The following patch fixes

http://gcc.gnu.org/bugzilla/show_bug.cgi?id=58418

The patch also fixes a duplicated bug PR58419.

The patch was successfully tested and bootstrapped on x86/x86-64.

Committed as rev. 202630.

2013-09-16  Vladimir Makarov  <vmaka...@redhat.com>

        PR middle-end/58418
        * lra-constraints.c (undo_optional_reloads): Consider all optional
        reload even if it did not get a hard reg.

2013-09-16  Vladimir Makarov  <vmaka...@redhat.com>

        * gcc.target/i386/pr58418.c: New.

Index: lra-constraints.c
===================================================================
--- lra-constraints.c   (revision 202626)
+++ lra-constraints.c   (working copy)
@@ -5454,43 +5454,42 @@ undo_optional_reloads (void)
   bitmap_initialize (&removed_optional_reload_pseudos, &reg_obstack);
   bitmap_copy (&removed_optional_reload_pseudos, &lra_optional_reload_pseudos);
   EXECUTE_IF_SET_IN_BITMAP (&lra_optional_reload_pseudos, 0, regno, bi)
-    if (reg_renumber[regno] >= 0)
-      {
-       keep_p = false;
-       if (reg_renumber[lra_reg_info[regno].restore_regno] >= 0)
-         /* If the original pseudo changed its allocation, just
-            removing the optional pseudo is dangerous as the original
-            pseudo will have longer live range.  */
-         keep_p = true;
-       else
-         EXECUTE_IF_SET_IN_BITMAP (&lra_reg_info[regno].insn_bitmap, 0, uid, 
bi2)
-           {
-             insn = lra_insn_recog_data[uid]->insn;
-             if ((set = single_set (insn)) == NULL_RTX)
-               continue;
-             src = SET_SRC (set);
-             dest = SET_DEST (set);
-             if (! REG_P (src) || ! REG_P (dest))
-               continue;
-             if (REGNO (dest) == regno
-                 /* Ignore insn for optional reloads itself.  */
-                 && lra_reg_info[regno].restore_regno != (int) REGNO (src)
-                 /* Check only inheritance on last inheritance pass.  */
-                 && (int) REGNO (src) >= new_regno_start
-                 /* Check that the optional reload was inherited.  */
-                 && bitmap_bit_p (&lra_inheritance_pseudos, REGNO (src)))
-               {
-                 keep_p = true;
-                 break;
-               }
-           }
-       if (keep_p)
+    {
+      keep_p = false;
+      if (reg_renumber[lra_reg_info[regno].restore_regno] >= 0)
+       /* If the original pseudo changed its allocation, just
+          removing the optional pseudo is dangerous as the original
+          pseudo will have longer live range.  */
+       keep_p = true;
+      else if (reg_renumber[regno] >= 0)
+       EXECUTE_IF_SET_IN_BITMAP (&lra_reg_info[regno].insn_bitmap, 0, uid, bi2)
          {
-           bitmap_clear_bit (&removed_optional_reload_pseudos, regno);
-           if (lra_dump_file != NULL)
-             fprintf (lra_dump_file, "Keep optional reload reg %d\n", regno);
+           insn = lra_insn_recog_data[uid]->insn;
+           if ((set = single_set (insn)) == NULL_RTX)
+             continue;
+           src = SET_SRC (set);
+           dest = SET_DEST (set);
+           if (! REG_P (src) || ! REG_P (dest))
+             continue;
+           if (REGNO (dest) == regno
+               /* Ignore insn for optional reloads itself.  */
+               && lra_reg_info[regno].restore_regno != (int) REGNO (src)
+               /* Check only inheritance on last inheritance pass.  */
+               && (int) REGNO (src) >= new_regno_start
+               /* Check that the optional reload was inherited.  */
+               && bitmap_bit_p (&lra_inheritance_pseudos, REGNO (src)))
+             {
+               keep_p = true;
+               break;
+             }
          }
-      }
+      if (keep_p)
+       {
+         bitmap_clear_bit (&removed_optional_reload_pseudos, regno);
+         if (lra_dump_file != NULL)
+           fprintf (lra_dump_file, "Keep optional reload reg %d\n", regno);
+       }
+    }
   change_p = ! bitmap_empty_p (&removed_optional_reload_pseudos);
   bitmap_initialize (&insn_bitmap, &reg_obstack);
   EXECUTE_IF_SET_IN_BITMAP (&removed_optional_reload_pseudos, 0, regno, bi)
Index: testsuite/gcc.target/i386/pr58418.c
===================================================================
--- testsuite/gcc.target/i386/pr58418.c (revision 0)
+++ testsuite/gcc.target/i386/pr58418.c (working copy)
@@ -0,0 +1,32 @@
+/* { dg-do run } */
+/* { dg-options "-O2" } */
+
+extern void abort (void);
+int a, b, *c = &b, d = -1, e, f, *g, *h = &f, **i = &g, j;
+
+unsigned int
+foo (unsigned int p)
+{
+  return p == 0 ? 0 : 1 / p;
+}
+
+static int *
+bar ()
+{
+  *c = *h = foo (d) & (-9 < d);
+  for (e = 0; e; e++)
+    ;
+  return 0;
+}
+
+int
+main ()
+{
+  for (; j; j++)
+    for (;; a--)
+      ;
+  *i = bar ();
+  if (f != 0)
+    abort ();
+  return 0;
+}

Reply via email to