diff mbox

patch to fix PR55414

Message ID 50AD5430.5070204@redhat.com
State New
Headers show

Commit Message

Vladimir Makarov Nov. 21, 2012, 10:22 p.m. UTC
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  <vmakarov@redhat.com>

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

Patch

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)