re PR target/67808 (LRA ICEs on simple double to long double conversion test case)
authorMichael Meissner <meissner@linux.vnet.ibm.com>
Tue, 6 Oct 2015 17:20:49 +0000 (17:20 +0000)
committerMichael Meissner <meissner@gcc.gnu.org>
Tue, 6 Oct 2015 17:20:49 +0000 (17:20 +0000)
[gcc]
2015-10-05  Michael Meissner  <meissner@linux.vnet.ibm.com>
    Peter Bergner  <bergner@vnet.ibm.com>

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  <meissner@linux.vnet.ibm.com>
    Peter Bergner <bergner@vnet.ibm.com>

PR target/67808
* gcc.target/powerpc/pr67808.c: New test.

Co-Authored-By: Peter Bergner <bergner@vnet.ibm.com>
From-SVN: r228538

gcc/ChangeLog
gcc/config/rs6000/rs6000.md
gcc/testsuite/ChangeLog
gcc/testsuite/gcc.target/powerpc/pr67808.c [new file with mode: 0644]

index e960a5ec786e08c904c77b0c33453bc7dd69714c..429148f1e1f96445322f282604a1240520be094d 100644 (file)
@@ -1,3 +1,21 @@
+2015-10-05  Michael Meissner  <meissner@linux.vnet.ibm.com>
+           Peter Bergner  <bergner@vnet.ibm.com>
+
+       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  <ramana.radhakrishnan@arm.com>
 
        * varasm.c (default_elf_asm_named_section): Remove ATTRIBUTE_UNUSED
index cf40f10f83790532e24b54beca13787d91255c03..78e20f076320107b463e99380c75fef05171ff0b 100644 (file)
   [(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"
 {
     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)
index 0e06ee82cd2454d6121e38eae7853eb7eba1673f..1e1896398d42d3b5807fd1d0b76a97e742cadba2 100644 (file)
@@ -1,3 +1,9 @@
+2015-10-05  Michael Meissner  <meissner@linux.vnet.ibm.com>
+           Peter Bergner <bergner@vnet.ibm.com>
+
+       PR target/67808
+       * gcc.target/powerpc/pr67808.c: New test.
+
 2015-10-06  Nick Clifton  <nickc@redhat.com>
 
        * 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 (file)
index 0000000..266fd97
--- /dev/null
@@ -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" } } */