The following patch fixes

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

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

  Committed as rev. 193712.

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

        PR rtl-optimization/55414
        * lra-constraints.c (Index): New function.
        (lra_constraints): Check dead equiv init insns.



Index: lra-constraints.c
===================================================================
--- lra-constraints.c   (revision 193702)
+++ lra-constraints.c   (working copy)
@@ -3215,6 +3215,17 @@ multi_block_pseudo_p (int regno)
     return false;
 }
 
+/* Return true if LIST contains a deleted insn.  */
+static bool
+contains_deleted_insn_p (rtx list)
+{
+  for (; list != NULL_RTX; list = XEXP (list, 1))
+    if (NOTE_P (XEXP (list, 0))
+       && NOTE_KIND (XEXP (list, 0)) == NOTE_INSN_DELETED)
+      return true;
+  return false;
+}
+
 /* Return true if X contains a pseudo dying in INSN.  */
 static bool
 dead_pseudo_p (rtx x, rtx insn)
@@ -3317,10 +3328,29 @@ lra_constraints (bool first_p)
            bool pseudo_p = contains_reg_p (x, false, false);
            rtx set, insn;
 
-           /* We don't use DF for compilation speed sake.  So it is
-              problematic to update live info when we use an
-              equivalence containing pseudos in more than one BB.  */
-           if ((pseudo_p && multi_block_pseudo_p (i))
+           /* After RTL transformation, we can not guarantee that
+              pseudo in the substitution was not reloaded which might
+              make equivalence invalid.  For example, in reverse
+              equiv of p0
+
+              p0 <- ...
+              ...
+              equiv_mem <- p0
+
+              the memory address register was reloaded before the 2nd
+              insn.  */
+           if ((! first_p && pseudo_p)
+               /* We don't use DF for compilation speed sake.  So it
+                  is problematic to update live info when we use an
+                  equivalence containing pseudos in more than one
+                  BB.  */
+               || (pseudo_p && multi_block_pseudo_p (i))
+               /* If an init insn was deleted for some reason, cancel
+                  the equiv.  We could update the equiv insns after
+                  transformations including an equiv insn deletion
+                  but it is not worthy as such cases are extremely
+                  rare.  */ 
+               || contains_deleted_insn_p (ira_reg_equiv[i].init_insns)
                /* If it is not a reverse equivalence, we check that a
                   pseudo in rhs of the init insn is not dying in the
                   insn.  Otherwise, the live info at the beginning of
@@ -3335,19 +3365,6 @@ lra_constraints (bool first_p)
                       && (int) REGNO (SET_DEST (set)) == i)
                    && init_insn_rhs_dead_pseudo_p (i)))
              ira_reg_equiv[i].defined_p = false;
-           else if (! first_p && pseudo_p)
-             /* After RTL transformation, we can not guarantee that
-                pseudo in the substitution was not reloaded which
-                might make equivalence invalid.  For example, in
-                reverse equiv of p0
-
-                p0 <- ...
-                ...
-                equiv_mem <- p0
-
-                the memory address register was reloaded before the
-                2nd insn.  */
-             ira_reg_equiv[i].defined_p = false;
            if (contains_reg_p (x, false, true))
              ira_reg_equiv[i].profitable_p = false;
            if (get_equiv_substitution (reg) != reg)

Reply via email to