re PR rtl-optimization/88845 (ICE in lra_set_insn_recog_data, at lra.c:1010)
authorPeter Bergner <bergner@linux.ibm.com>
Wed, 6 Mar 2019 15:36:43 +0000 (15:36 +0000)
committerPeter Bergner <bergner@gcc.gnu.org>
Wed, 6 Mar 2019 15:36:43 +0000 (09:36 -0600)
gcc/
PR rtl-optimization/88845
* config/rs6000/rs6000.c (rs6000_emit_move_si_sf_subreg): Enable during
LRA.
* lra.c (remove_scratches_1): New function.
(remove_scratches): Use it.
(lra_emit_move): Likewise.

gcc/testsuite/
PR rtl-optimization/88845
* gcc.target/powerpc/pr88845.c: New test.

From-SVN: r269428

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

index 3408e67b2c53488134bb2112826f5d5a9167baaf..8a10820be2b6c244dd6cd81cbd6c9616a5ffcafe 100644 (file)
@@ -1,3 +1,12 @@
+2019-03-06  Peter Bergner  <bergner@linux.ibm.com>
+
+       PR rtl-optimization/88845
+       * config/rs6000/rs6000.c (rs6000_emit_move_si_sf_subreg): Enable during
+       LRA.
+       * lra.c (remove_scratches_1): New function.
+       (remove_scratches): Use it.
+       (lra_emit_move): Likewise.
+
 2019-03-06  Claudiu Zissulescu  <claziss@synopsys.com>
 
        * config/arc/arc-c.def (__ARC_UNALIGNED__): Set it on
index b489bef45017b6ba2b530edcf4d5af4bee4e763c..d72a51a01bfaa056a300b57121fce78c919c26ca 100644 (file)
@@ -9890,7 +9890,7 @@ valid_sf_si_move (rtx dest, rtx src, machine_mode mode)
 static bool
 rs6000_emit_move_si_sf_subreg (rtx dest, rtx source, machine_mode mode)
 {
-  if (TARGET_DIRECT_MOVE_64BIT && !lra_in_progress && !reload_completed
+  if (TARGET_DIRECT_MOVE_64BIT && !reload_completed
       && (!SUBREG_P (dest) || !sf_subreg_operand (dest, mode))
       && SUBREG_P (source) && sf_subreg_operand (source, mode))
     {
index f1300652889ffcc9b67f9d0f7954e93f7ef3b178..bef2f676a78cf539594b6da79c5242d2d56e8a43 100644 (file)
--- a/gcc/lra.c
+++ b/gcc/lra.c
@@ -159,6 +159,7 @@ static void invalidate_insn_recog_data (int);
 static int get_insn_freq (rtx_insn *);
 static void invalidate_insn_data_regno_info (lra_insn_recog_data_t,
                                             rtx_insn *, int);
+static void remove_scratches_1 (rtx_insn *);
 
 /* Expand all regno related info needed for LRA.  */
 static void
@@ -494,7 +495,11 @@ lra_emit_move (rtx x, rtx y)
       if (rtx_equal_p (x, y))
        return;
       old = max_reg_num ();
-      emit_move_insn (x, y);
+      rtx_insn *insn = emit_move_insn (x, y);
+      /* The move pattern may require scratch registers, so convert them
+        into real registers now.  */
+      if (insn != NULL_RTX)
+       remove_scratches_1 (insn);
       if (REG_P (x))
        lra_reg_info[ORIGINAL_REGNO (x)].last_reload = ++lra_curr_reload_num;
       /* Function emit_move can create pseudos -- so expand the pseudo
@@ -2077,47 +2082,53 @@ lra_register_new_scratch_op (rtx_insn *insn, int nop, int icode)
   add_reg_note (insn, REG_UNUSED, op);
 }
 
-/* Change scratches onto pseudos and save their location.  */
+/* Change INSN's scratches into pseudos and save their location.  */
 static void
-remove_scratches (void)
+remove_scratches_1 (rtx_insn *insn)
 {
   int i;
   bool insn_changed_p;
-  basic_block bb;
-  rtx_insn *insn;
   rtx reg;
   lra_insn_recog_data_t id;
   struct lra_static_insn_data *static_id;
 
+  id = lra_get_insn_recog_data (insn);
+  static_id = id->insn_static_data;
+  insn_changed_p = false;
+  for (i = 0; i < static_id->n_operands; i++)
+    if (GET_CODE (*id->operand_loc[i]) == SCRATCH
+       && GET_MODE (*id->operand_loc[i]) != VOIDmode)
+      {
+       insn_changed_p = true;
+       *id->operand_loc[i] = reg
+         = lra_create_new_reg (static_id->operand[i].mode,
+                               *id->operand_loc[i], ALL_REGS, NULL);
+       lra_register_new_scratch_op (insn, i, id->icode);
+       if (lra_dump_file != NULL)
+         fprintf (lra_dump_file,
+                  "Removing SCRATCH in insn #%u (nop %d)\n",
+                  INSN_UID (insn), i);
+      }
+  if (insn_changed_p)
+    /* Because we might use DF right after caller-saves sub-pass
+       we need to keep DF info up to date.  */
+    df_insn_rescan (insn);
+}
+
+/* Change scratches into pseudos and save their location.  */
+static void
+remove_scratches (void)
+{
+  basic_block bb;
+  rtx_insn *insn;
+
   scratches.create (get_max_uid ());
   bitmap_initialize (&scratch_bitmap, &reg_obstack);
   bitmap_initialize (&scratch_operand_bitmap, &reg_obstack);
   FOR_EACH_BB_FN (bb, cfun)
     FOR_BB_INSNS (bb, insn)
     if (INSN_P (insn))
-      {
-       id = lra_get_insn_recog_data (insn);
-       static_id = id->insn_static_data;
-       insn_changed_p = false;
-       for (i = 0; i < static_id->n_operands; i++)
-         if (GET_CODE (*id->operand_loc[i]) == SCRATCH
-             && GET_MODE (*id->operand_loc[i]) != VOIDmode)
-           {
-             insn_changed_p = true;
-             *id->operand_loc[i] = reg
-               = lra_create_new_reg (static_id->operand[i].mode,
-                                     *id->operand_loc[i], ALL_REGS, NULL);
-             lra_register_new_scratch_op (insn, i, id->icode);
-             if (lra_dump_file != NULL)
-               fprintf (lra_dump_file,
-                        "Removing SCRATCH in insn #%u (nop %d)\n",
-                        INSN_UID (insn), i);
-           }
-       if (insn_changed_p)
-         /* Because we might use DF right after caller-saves sub-pass
-            we need to keep DF info up to date.  */
-         df_insn_rescan (insn);
-      }
+      remove_scratches_1 (insn);
 }
 
 /* Changes pseudos created by function remove_scratches onto scratches.         */
index 9b2951f631fb194ca79679aa83567cfd4abcfff2..9a65e3a81470b2d48ae609d2f96de12ef32cf91f 100644 (file)
@@ -1,3 +1,8 @@
+2019-03-06  Peter Bergner  <bergner@linux.ibm.com>
+
+       PR rtl-optimization/88845
+       * gcc.target/powerpc/pr88845.c: New test.
+
 2019-03-06  Marek Polacek  <polacek@redhat.com>
 
        PR c++/87378 - bogus -Wredundant-move warning.
diff --git a/gcc/testsuite/gcc.target/powerpc/pr88845.c b/gcc/testsuite/gcc.target/powerpc/pr88845.c
new file mode 100644 (file)
index 0000000..a939fa9
--- /dev/null
@@ -0,0 +1,24 @@
+/* { dg-do compile { target powerpc*-*-linux* } } */
+/* { dg-skip-if "" { powerpc*-*-darwin* } } */
+/* { dg-skip-if "" { powerpc*-*-*spe* } } */
+/* { dg-require-effective-target powerpc_p8vector_ok } */
+/* { dg-options "-mdejagnu-cpu=power8 -O2" } */
+/* { dg-final { scan-assembler {\mmtvsrd\M} { target { lp64 } } } } */
+/* { dg-final { scan-assembler {\mxscvspdpn\M} { target { lp64 } } } } */
+
+/* Verify that we do not ICE and that we generate a direct move
+   for float types when compiling for 64-bit.  */
+
+struct a {
+  unsigned ui;
+  float f;
+};
+
+void
+foo (void)
+{
+  float e;
+  struct a s;
+  e = s.f;
+  __asm__("" : : "d" (e));
+}