From bd4b39f249f92ed81a56e80b2afdc0783b7c1e23 Mon Sep 17 00:00:00 2001 From: Michael Meissner Date: Tue, 6 Oct 2015 17:20:49 +0000 Subject: [PATCH] re PR target/67808 (LRA ICEs on simple double to long double conversion test case) [gcc] 2015-10-05 Michael Meissner Peter Bergner PR target/67808 * config/rs6000/rs6000.md (extenddftf2): In the expander, only allow registers, but provide insns for the combiner to create for loads from memory. Separate VSX code from non-VSX code. For non-VSX code, combine extenddftf2_fprs into extenddftf2 and rename externaldftf2_internal to externaldftf2_fprs. Reorder constraints so that registers come before memory operations. Drop support from converting DFmode to TFmode, if the DFmode value is in a GPR register. (extenddftf2_fprs): Likewise. (extenddftf2_internal): Likewise. (extenddftf2_vsx): Likewise. (extendsftf2): In the expander, only allow registers, but provide insns for the combiner to create for stores and loads. [gcc/testsuite] 2015-10-05 Michael Meissner Peter Bergner PR target/67808 * gcc.target/powerpc/pr67808.c: New test. Co-Authored-By: Peter Bergner From-SVN: r228538 --- gcc/ChangeLog | 18 ++++++ gcc/config/rs6000/rs6000.md | 69 +++++++++++----------- gcc/testsuite/ChangeLog | 6 ++ gcc/testsuite/gcc.target/powerpc/pr67808.c | 46 +++++++++++++++ 4 files changed, 106 insertions(+), 33 deletions(-) create mode 100644 gcc/testsuite/gcc.target/powerpc/pr67808.c diff --git a/gcc/ChangeLog b/gcc/ChangeLog index e960a5ec786..429148f1e1f 100644 --- a/gcc/ChangeLog +++ b/gcc/ChangeLog @@ -1,3 +1,21 @@ +2015-10-05 Michael Meissner + Peter Bergner + + PR target/67808 + * config/rs6000/rs6000.md (extenddftf2): In the expander, only + allow registers, but provide insns for the combiner to create for + loads from memory. Separate VSX code from non-VSX code. For + non-VSX code, combine extenddftf2_fprs into extenddftf2 and rename + externaldftf2_internal to externaldftf2_fprs. Reorder constraints + so that registers come before memory operations. Drop support from + converting DFmode to TFmode, if the DFmode value is in a GPR + register. + (extenddftf2_fprs): Likewise. + (extenddftf2_internal): Likewise. + (extenddftf2_vsx): Likewise. + (extendsftf2): In the expander, only allow registers, but provide + insns for the combiner to create for stores and loads. + 2015-10-06 Ramana Radhakrishnan * varasm.c (default_elf_asm_named_section): Remove ATTRIBUTE_UNUSED diff --git a/gcc/config/rs6000/rs6000.md b/gcc/config/rs6000/rs6000.md index cf40f10f837..78e20f07632 100644 --- a/gcc/config/rs6000/rs6000.md +++ b/gcc/config/rs6000/rs6000.md @@ -6471,8 +6471,8 @@ [(set_attr "length" "20,20,16")]) (define_expand "extenddftf2" - [(set (match_operand:TF 0 "nonimmediate_operand" "") - (float_extend:TF (match_operand:DF 1 "input_operand" "")))] + [(set (match_operand:TF 0 "gpc_reg_operand" "") + (float_extend:TF (match_operand:DF 1 "gpc_reg_operand" "")))] "TARGET_HARD_FLOAT && (TARGET_FPRS || TARGET_E500_DOUBLE) && TARGET_LONG_DOUBLE_128" { @@ -6480,52 +6480,55 @@ rs6000_expand_float128_convert (operands[0], operands[1], false); else if (TARGET_E500_DOUBLE) emit_insn (gen_spe_extenddftf2 (operands[0], operands[1])); + else if (TARGET_VSX) + emit_insn (gen_extenddftf2_vsx (operands[0], operands[1])); else - emit_insn (gen_extenddftf2_fprs (operands[0], operands[1])); + { + rtx zero = gen_reg_rtx (DFmode); + rs6000_emit_move (zero, CONST0_RTX (DFmode), DFmode); + emit_insn (gen_extenddftf2_fprs (operands[0], operands[1], zero)); + } DONE; }) -(define_expand "extenddftf2_fprs" - [(parallel [(set (match_operand:TF 0 "nonimmediate_operand" "") - (float_extend:TF (match_operand:DF 1 "input_operand" ""))) - (use (match_dup 2))])] - "!TARGET_IEEEQUAD - && TARGET_HARD_FLOAT && TARGET_FPRS && TARGET_DOUBLE_FLOAT - && TARGET_LONG_DOUBLE_128" +;; Allow memory operands for the source to be created by the combiner. +(define_insn_and_split "extenddftf2_fprs" + [(set (match_operand:TF 0 "gpc_reg_operand" "=d,d,&d") + (float_extend:TF (match_operand:DF 1 "nonimmediate_operand" "d,m,d"))) + (use (match_operand:DF 2 "nonimmediate_operand" "m,m,d"))] + "!TARGET_VSX && TARGET_HARD_FLOAT && TARGET_FPRS && TARGET_DOUBLE_FLOAT + && TARGET_LONG_DOUBLE_128 && !TARGET_IEEEQUAD" + "#" + "&& reload_completed" + [(set (match_dup 3) (match_dup 1)) + (set (match_dup 4) (match_dup 2))] { - /* VSX can create 0.0 directly, otherwise let rs6000_emit_move create - the proper constant. */ - if (TARGET_VSX) - operands[2] = CONST0_RTX (DFmode); - else - { - operands[2] = gen_reg_rtx (DFmode); - rs6000_emit_move (operands[2], CONST0_RTX (DFmode), DFmode); - } + const int lo_word = LONG_DOUBLE_LARGE_FIRST ? GET_MODE_SIZE (DFmode) : 0; + const int hi_word = LONG_DOUBLE_LARGE_FIRST ? 0 : GET_MODE_SIZE (DFmode); + + operands[3] = simplify_gen_subreg (DFmode, operands[0], TFmode, hi_word); + operands[4] = simplify_gen_subreg (DFmode, operands[0], TFmode, lo_word); }) -(define_insn_and_split "*extenddftf2_internal" - [(set (match_operand:TF 0 "nonimmediate_operand" "=m,Y,ws,d,&d") - (float_extend:TF (match_operand:DF 1 "input_operand" "d,r,md,md,md"))) - (use (match_operand:DF 2 "zero_reg_mem_operand" "d,r,j,m,d"))] - "!TARGET_IEEEQUAD - && TARGET_HARD_FLOAT && TARGET_FPRS && TARGET_DOUBLE_FLOAT - && TARGET_LONG_DOUBLE_128" +(define_insn_and_split "extenddftf2_vsx" + [(set (match_operand:TF 0 "gpc_reg_operand" "=d,d") + (float_extend:TF (match_operand:DF 1 "nonimmediate_operand" "ws,m")))] + "TARGET_LONG_DOUBLE_128 && TARGET_VSX && !TARGET_IEEEQUAD" "#" "&& reload_completed" - [(pc)] + [(set (match_dup 2) (match_dup 1)) + (set (match_dup 3) (match_dup 4))] { const int lo_word = LONG_DOUBLE_LARGE_FIRST ? GET_MODE_SIZE (DFmode) : 0; const int hi_word = LONG_DOUBLE_LARGE_FIRST ? 0 : GET_MODE_SIZE (DFmode); - emit_move_insn (simplify_gen_subreg (DFmode, operands[0], TFmode, hi_word), - operands[1]); - emit_move_insn (simplify_gen_subreg (DFmode, operands[0], TFmode, lo_word), - operands[2]); - DONE; + + operands[2] = simplify_gen_subreg (DFmode, operands[0], TFmode, hi_word); + operands[3] = simplify_gen_subreg (DFmode, operands[0], TFmode, lo_word); + operands[4] = CONST0_RTX (DFmode); }) (define_expand "extendsftf2" - [(set (match_operand:TF 0 "nonimmediate_operand" "") + [(set (match_operand:TF 0 "gpc_reg_operand" "") (float_extend:TF (match_operand:SF 1 "gpc_reg_operand" "")))] "TARGET_HARD_FLOAT && (TARGET_FPRS || TARGET_E500_DOUBLE) diff --git a/gcc/testsuite/ChangeLog b/gcc/testsuite/ChangeLog index 0e06ee82cd2..1e1896398d4 100644 --- a/gcc/testsuite/ChangeLog +++ b/gcc/testsuite/ChangeLog @@ -1,3 +1,9 @@ +2015-10-05 Michael Meissner + Peter Bergner + + PR target/67808 + * gcc.target/powerpc/pr67808.c: New test. + 2015-10-06 Nick Clifton * gcc.target/msp430: New directory. diff --git a/gcc/testsuite/gcc.target/powerpc/pr67808.c b/gcc/testsuite/gcc.target/powerpc/pr67808.c new file mode 100644 index 00000000000..266fd97d663 --- /dev/null +++ b/gcc/testsuite/gcc.target/powerpc/pr67808.c @@ -0,0 +1,46 @@ +/* { dg-do compile { target { powerpc*-*-* } } } */ +/* { dg-skip-if "" { powerpc*-*-darwin* } { "*" } { "" } } */ +/* { dg-require-effective-target powerpc_vsx_ok } */ +/* { dg-require-effective-target powerpc_vsx_ok } */ +/* { dg-skip-if "do not override -mcpu" { powerpc*-*-* } { "-mcpu=*" } { "-mcpu=power7" } } */ +/* { dg-options "-O1 -mvsx -mlra -mcpu=power7" } */ + +/* PR 67808: LRA ICEs on simple double to long double conversion test case */ + +void +dfoo (long double *ldb1, double *db1) +{ + *ldb1 = *db1; +} + +long double +dfoo2 (double *db1) +{ + return *db1; +} + +long double +dfoo3 (double x) +{ + return x; +} + +void +ffoo (long double *ldb1, float *db1) +{ + *ldb1 = *db1; +} + +long double +ffoo2 (float *db1) +{ + return *db1; +} + +long double +ffoo3 (float x) +{ + return x; +} + +/* { dg-final { scan-assembler "xxlxor" } } */ -- 2.30.2