The following patch fixes PR54991.

Committed as rev. 192645.

2012-10-20  Vladimir Makarov  <vmaka...@redhat.com>

    PR rtl-optimization/54991
    * lra-constraints.c (lra_constraints): Change equiv memory check
    on reverse equivalence check.
    (inherit_in_ebb): Invalidate usage insns for multi-word hard regs.

Index: lra-constraints.c
===================================================================
--- lra-constraints.c   (revision 192637)
+++ lra-constraints.c   (working copy)
@@ -3552,18 +3552,24 @@ lra_constraints (bool first_p)
        else if ((x = get_equiv_substitution (regno_reg_rtx[i])) != NULL_RTX)
          {
            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))
-               /* 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 the corresponding BB might be
-                  wrong after we removed the insn.  When the equiv can
-                  be a constant, the right hand side of the init insn
-                  can be a pseudo.  */
-               || (ira_reg_equiv[i].memory == NULL_RTX
+               /* 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
+                  the corresponding BB might be wrong after we
+                  removed the insn.  When the equiv can be a
+                  constant, the right hand side of the init insn can
+                  be a pseudo.  */
+               || (! ((insn = ira_reg_equiv[i].init_insns) != NULL_RTX
+                      && INSN_P (insn)
+                      && (set = single_set (insn)) != NULL_RTX
+                      && REG_P (SET_DEST (set))
+                      && (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)
@@ -4444,7 +4450,7 @@ static bitmap_head temp_bitmap;
 static bool
 inherit_in_ebb (rtx head, rtx tail)
 {
-  int i, src_regno, dst_regno;
+  int i, src_regno, dst_regno, nregs;
   bool change_p, succ_p;
   rtx prev_insn, next_usage_insns, set, last_insn;
   enum reg_class cl;
@@ -4607,13 +4613,26 @@ inherit_in_ebb (rtx head, rtx tail)
                                           reg_renumber[dst_regno]);
                    AND_COMPL_HARD_REG_SET (live_hard_regs, s);
                  }
-               /* We should invalidate potential inheritance for the
-                  current insn usages to the next usage insns (see
-                  code below) as the output pseudo prevents this.  */
-               if (reg_renumber[dst_regno] < 0
-                   || (reg->type == OP_OUT && ! reg->subreg_p))
-                 /* Invalidate.  */
-                 usage_insns[dst_regno].check = 0;
+               /* We should invalidate potential inheritance or
+                  splitting for the current insn usages to the next
+                  usage insns (see code below) as the output pseudo
+                  prevents this.  */
+               if ((dst_regno >= FIRST_PSEUDO_REGISTER
+                    && reg_renumber[dst_regno] < 0)
+                   || (reg->type == OP_OUT && ! reg->subreg_p
+                       && (dst_regno < FIRST_PSEUDO_REGISTER
+                           || reg_renumber[dst_regno] >= 0)))
+                 {
+                   /* Invalidate.  */
+                   if (dst_regno >= FIRST_PSEUDO_REGISTER)
+                     usage_insns[dst_regno].check = 0;
+                   else
+                     {
+                       nregs = hard_regno_nregs[dst_regno][reg->biggest_mode];
+                       for (i = 0; i < nregs; i++)
+                         usage_insns[dst_regno + i].check = 0;
+                     }
+                 }
              }
          if (! JUMP_P (curr_insn))
            for (i = 0; i < to_inherit_num; i++)

Reply via email to