re PR rtl-optimization/70263 (ICE at -O1 and above in both 32-bit and 64-bit modes...
authorJeff Law <law@redhat.com>
Fri, 18 Mar 2016 19:30:20 +0000 (13:30 -0600)
committerJeff Law <law@gcc.gnu.org>
Fri, 18 Mar 2016 19:30:20 +0000 (13:30 -0600)
PR rtl-optimization/70263
* ira.c (memref_used_between_p): Assert we found END in the insn chain.
(update_equiv_regs): When trying to move a store to after the insn
that sets the source of the store, make sure the store occurs after
the insn that sets the source of the store.  When successful note
the REG_EQUIV note created in the dump file.

PR rtl-optimization/70263
* gcc.c-torture/compile/pr70263-1.c: New test.
* gcc.target/i386/pr70263-2.c: New test.

From-SVN: r234344

gcc/ChangeLog
gcc/ira.c
gcc/testsuite/ChangeLog
gcc/testsuite/gcc.c-torture/compile/pr70263-1.c [new file with mode: 0644]
gcc/testsuite/gcc.target/i386/pr70263-2.c [new file with mode: 0644]

index 9aee1f0f834eac1dc5bddfd7d80817c0ad52a92d..6f52c2d2787d4972415c4060a3291db705bec15c 100644 (file)
@@ -1,3 +1,12 @@
+2016-03-18  Jeff Law  <law@redhat.com>
+
+       PR rtl-optimization/70263
+       * ira.c (memref_used_between_p): Assert we found END in the insn chain.
+       (update_equiv_regs): When trying to move a store to after the insn
+       that sets the source of the store, make sure the store occurs after
+       the insn that sets the source of the store.  When successful note
+       the REG_EQUIV note created in the dump file.
+
 2016-03-16  David Wohlferd  <dw@LimeGreenSocks.com>
             Bernd Schmidt  <bschmidt@redhat.com>
 
index 062b8a4d4b8ca177b592d3de119bce729cc295e5..c12318a6227ba25282a5cf59be7437df668b5622 100644 (file)
--- a/gcc/ira.c
+++ b/gcc/ira.c
@@ -3225,13 +3225,18 @@ memref_referenced_p (rtx memref, rtx x)
 }
 
 /* TRUE if some insn in the range (START, END] references a memory location
-   that would be affected by a store to MEMREF.  */
+   that would be affected by a store to MEMREF.
+
+   Callers should not call this routine if START is after END in the
+   RTL chain.  */
+
 static int
 memref_used_between_p (rtx memref, rtx_insn *start, rtx_insn *end)
 {
   rtx_insn *insn;
 
-  for (insn = NEXT_INSN (start); insn != NEXT_INSN (end);
+  for (insn = NEXT_INSN (start);
+       insn && insn != NEXT_INSN (end);
        insn = NEXT_INSN (insn))
     {
       if (!NONDEBUG_INSN_P (insn))
@@ -3245,6 +3250,7 @@ memref_used_between_p (rtx memref, rtx_insn *start, rtx_insn *end)
        return 1;
     }
 
+  gcc_assert (insn == NEXT_INSN (end));
   return 0;
 }
 
@@ -3337,6 +3343,7 @@ update_equiv_regs (void)
   int loop_depth;
   bitmap cleared_regs;
   bool *pdx_subregs;
+  bitmap_head seen_insns;
 
   /* Use pdx_subregs to show whether a reg is used in a paradoxical
      subreg.  */
@@ -3606,11 +3613,14 @@ update_equiv_regs (void)
   /* A second pass, to gather additional equivalences with memory.  This needs
      to be done after we know which registers we are going to replace.  */
 
+  bitmap_initialize (&seen_insns, NULL);
   for (insn = get_insns (); insn; insn = NEXT_INSN (insn))
     {
       rtx set, src, dest;
       unsigned regno;
 
+      bitmap_set_bit (&seen_insns, INSN_UID (insn));
+
       if (! INSN_P (insn))
        continue;
 
@@ -3651,6 +3661,7 @@ update_equiv_regs (void)
          rtx_insn *init_insn =
            as_a <rtx_insn *> (XEXP (reg_equiv[regno].init_insns, 0));
          if (validate_equiv_mem (init_insn, src, dest)
+             && bitmap_bit_p (&seen_insns, INSN_UID (init_insn))
              && ! memref_used_between_p (dest, init_insn, insn)
              /* Attaching a REG_EQUIV note will fail if INIT_INSN has
                 multiple sets.  */
@@ -3661,9 +3672,15 @@ update_equiv_regs (void)
              ira_reg_equiv[regno].init_insns
                = gen_rtx_INSN_LIST (VOIDmode, insn, NULL_RTX);
              df_notes_rescan (init_insn);
+             if (dump_file)
+               fprintf (dump_file,
+                        "Adding REG_EQUIV to insn %d for source of insn %d\n",
+                        INSN_UID (init_insn),
+                        INSN_UID (insn));
            }
        }
     }
+  bitmap_clear (&seen_insns);
 
   cleared_regs = BITMAP_ALLOC (NULL);
   /* Now scan all regs killed in an insn to see if any of them are
index 53994fe63ec36402fb0401e818ab849f4777e39a..c043b4b8ec3d394d45debe4687674ff69390395f 100644 (file)
@@ -1,3 +1,9 @@
+2016-03-18  Jeff Law  <law@redhat.com>
+
+       PR rtl-optimization/70263
+       * gcc.c-torture/compile/pr70263-1.c: New test.
+       * gcc.target/i386/pr70263-2.c: New test.
+
 2016-03-18  Bernd Schmidt  <bschmidt@redhat.com>
 
        PR rtl-optimization/70278
diff --git a/gcc/testsuite/gcc.c-torture/compile/pr70263-1.c b/gcc/testsuite/gcc.c-torture/compile/pr70263-1.c
new file mode 100644 (file)
index 0000000..d4bf280
--- /dev/null
@@ -0,0 +1,11 @@
+int a[91];
+int b, c;
+void fn1() {
+  int n, m;
+  do {
+    a[c--];
+    a[--c] = m;
+    a[--m] = b;
+  } while (n);
+}
+
diff --git a/gcc/testsuite/gcc.target/i386/pr70263-2.c b/gcc/testsuite/gcc.target/i386/pr70263-2.c
new file mode 100644 (file)
index 0000000..18ebbf0
--- /dev/null
@@ -0,0 +1,23 @@
+/* { dg-do compile } */
+/* { dg-options "-O2 -fdump-rtl-ira" } */
+
+/* { dg-final { scan-rtl-dump "Adding REG_EQUIV to insn \[0-9\]+ for source of insn \[0-9\]+" "ira" } } */
+
+typedef float XFtype __attribute__ ((mode (XF)));
+typedef _Complex float XCtype __attribute__ ((mode (XC)));
+XCtype
+__mulxc3 (XFtype a, XFtype b, XFtype c, XFtype d)
+{
+  XFtype ac, bd, ad, bc, x, y;
+  ac = a * c;
+__asm__ ("": "=m" (ac):"m" (ac));
+  if (x != x)
+    {
+      _Bool recalc = 0;
+      if (((!(!(((ac) - (ac)) != ((ac) - (ac)))))))
+       recalc = 1;
+      if (recalc)
+       x = __builtin_huge_vall () * (a * c - b * d);
+    }
+  return x;
+}