The following patch fixes PR55130

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

The reason for the crash was in missed processing clobber insn with pseudo changed on its equivalent memory. It resulted in presence of the pseudo and in trying to remove equiv initialization insn the second time.

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

  Committed as rev. 193096.

2012-11-02  Vladimir Makarov  <vmaka...@redhat.com>

        PR middle-end/55130
        * lra-constraints.c (debug_loc_equivalence_change_p): Rename to
        loc_equivalence_change_p.
        (lra_constraints): Check equiv_insn_bitmap for debug insn.  Call
        loc_equivalence_change_p for non-transformed insn.

2012-11-02  Vladimir Makarov  <vmaka...@redhat.com>

        PR middle-end/55150
        * gcc.target/i386/pr55130.c: New test.


Index: lra-constraints.c
===================================================================
--- lra-constraints.c   (revision 193065)
+++ lra-constraints.c   (working copy)
@@ -3095,10 +3095,10 @@ contains_reg_p (rtx x, bool hard_reg_p,
   return false;
 }
 
-/* Process all regs in debug location *LOC and change them on
-   equivalent substitution.  Return true if any change was done.  */
+/* Process all regs in location *LOC and change them on equivalent
+   substitution.  Return true if any change was done.  */
 static bool
-debug_loc_equivalence_change_p (rtx *loc)
+loc_equivalence_change_p (rtx *loc)
 {
   rtx subst, reg, x = *loc;
   bool result = false;
@@ -3130,11 +3130,11 @@ debug_loc_equivalence_change_p (rtx *loc
   for (i = GET_RTX_LENGTH (code) - 1; i >= 0; i--)
     {
       if (fmt[i] == 'e')
-       result = debug_loc_equivalence_change_p (&XEXP (x, i)) || result;
+       result = loc_equivalence_change_p (&XEXP (x, i)) || result;
       else if (fmt[i] == 'E')
        for (j = XVECLEN (x, i) - 1; j >= 0; j--)
          result
-           = debug_loc_equivalence_change_p (&XVECEXP (x, i, j)) || result;
+           = loc_equivalence_change_p (&XVECEXP (x, i, j)) || result;
     }
   return result;
 }
@@ -3322,7 +3322,6 @@ lra_constraints (bool first_p)
      substituted by their equivalences.  */
   EXECUTE_IF_SET_IN_BITMAP (&equiv_insn_bitmap, 0, uid, bi)
     lra_push_insn_by_uid (uid);
-  bitmap_clear (&equiv_insn_bitmap);
   lra_eliminate (false);
   min_len = lra_insn_stack_length ();
   new_insns_num = 0;
@@ -3353,7 +3352,8 @@ lra_constraints (bool first_p)
          /* We need to check equivalence in debug insn and change
             pseudo to the equivalent value if necessary.  */
          curr_id = lra_get_insn_recog_data (curr_insn);
-         if (debug_loc_equivalence_change_p (curr_id->operand_loc[0]))
+         if (bitmap_bit_p (&equiv_insn_bitmap, INSN_UID (curr_insn))
+             && loc_equivalence_change_p (curr_id->operand_loc[0]))
            {
              lra_update_insn_regno_info (curr_insn);
              changed_p = true;
@@ -3417,8 +3417,18 @@ lra_constraints (bool first_p)
          init_curr_operand_mode ();
          if (curr_insn_transform ())
            changed_p = true;
+         /* Check non-transformed insns too for equiv change as USE
+            or CLOBBER don't need reloads but can contain pseudos
+            being changed on their equivalences.  */
+         else if (bitmap_bit_p (&equiv_insn_bitmap, INSN_UID (curr_insn))
+                  && loc_equivalence_change_p (&PATTERN (curr_insn)))
+           {
+             lra_update_insn_regno_info (curr_insn);
+             changed_p = true;
+           }
        }
     }
+  bitmap_clear (&equiv_insn_bitmap);
   /* If we used a new hard regno, changed_p should be true because the
      hard reg is assigned to a new pseudo.  */
 #ifdef ENABLE_CHECKING
Index: testsuite/gcc.target/i386/pr55130.c
===================================================================
--- testsuite/gcc.target/i386/pr55130.c (revision 0)
+++ testsuite/gcc.target/i386/pr55130.c (working copy)
@@ -0,0 +1,15 @@
+/* PR middle-end/55130 */
+/* { dg-do compile { target ia32 } } */
+/* { dg-options "-O1 -mregparm=3 -mpreferred-stack-boundary=2" } */
+
+extern void bar(long long);
+
+int foo(long long a, char b, long long c, long long d)
+{
+  if (c == 0)
+    c = d;
+
+  bar(b + c);
+
+  return a == d;
+}

Reply via email to