The following patch fixes compilation abort of SPECFP2000 mesa on ppc64.

The patch was successfully bootstrapped on x86-64, ppc64, and ia64.

 2011-06-24  Vladimir Makarov <vmaka...@redhat.com>

        * lra-constraints.c (lra_constraints): Check subreg for equiv init
        insn.


Index: lra-constraints.c
===================================================================
--- lra-constraints.c   (revision 175313)
+++ lra-constraints.c   (working copy)
@@ -3121,7 +3121,7 @@ lra_constraints (bool first_p)
   bool changed_p;
   int i, hard_regno, new_insns_num;
   unsigned int min_len;
-  rtx set, x;
+  rtx set, x, dest_reg;
   basic_block last_bb;
 
   lra_constraint_iter++;
@@ -3193,43 +3193,52 @@ lra_constraints (bool first_p)
       new_insns_num++;
       if (NONDEBUG_INSN_P (curr_insn))
        {
-         if ((set = single_set (curr_insn)) != NULL_RTX
-             && ((((x = get_equiv_substitution (SET_DEST (set)))
-                   != SET_DEST (set))
-                  /* Remove insns which set up a pseudo whose value
-                     can not be changed.  Such insns might be not in
-                     init_insns because we don't update equiv data
-                     during insn transformations.
-
-                     As an example, let suppose that a pseudo got
-                     hard register and on the 1st pass was not
-                     changed to equivalent constant.  We generate an
-                     additional insn setting up the pseudo because of
-                     secondary memory movement.  Then the pseudo is
-                     spilled and we use the equiv constant.  In this
-                     case we should remove the additional insn and
-                     this insn is not init_insns list.  */
-                  && (! MEM_P (x) || MEM_READONLY_P (x)
-                      || in_list_p (curr_insn,
-                                    ira_reg_equiv
-                                    [REGNO (SET_DEST (set))].init_insns)))
-                 || (SET_SRC (set) != get_equiv_substitution (SET_SRC (set))
-                     && in_list_p (curr_insn,
-                                   ira_reg_equiv
-                                   [REGNO (SET_SRC (set))].init_insns))))
+         if ((set = single_set (curr_insn)) != NULL_RTX)
            {
-             /* This is equiv init insn of pseudo which did not get a
-                hard register -- remove the insn.  */
-             if (lra_dump_file != NULL)
+             dest_reg = SET_DEST (set);
+             /* The equivalence pseudo could be set up as SUBREG in a
+                case when it is a call restore insn in a mode
+                different from the pseudo mode.  */
+             if (GET_CODE (dest_reg) == SUBREG)
+               dest_reg = SUBREG_REG (dest_reg);
+             if (REG_P (dest_reg)
+                 && ((((x = get_equiv_substitution (dest_reg)) != dest_reg)
+                      /* Remove insns which set up a pseudo whose
+                         value can not be changed.  Such insns might
+                         be not in init_insns because we don't update
+                         equiv data during insn transformations.
+                         
+                         As an example, let suppose that a pseudo got
+                         hard register and on the 1st pass was not
+                         changed to equivalent constant.  We generate
+                         an additional insn setting up the pseudo
+                         because of secondary memory movement.  Then
+                         the pseudo is spilled and we use the equiv
+                         constant.  In this case we should remove the
+                         additional insn and this insn is not
+                         init_insns list.  */
+                      && (! MEM_P (x) || MEM_READONLY_P (x)
+                          || in_list_p (curr_insn,
+                                        ira_reg_equiv
+                                        [REGNO (SET_DEST (set))].init_insns)))
+                     || (SET_SRC (set) != get_equiv_substitution (SET_SRC 
(set))
+                         && in_list_p (curr_insn,
+                                       ira_reg_equiv
+                                       [REGNO (SET_SRC (set))].init_insns))))
                {
-                 fprintf (lra_dump_file,
-                          "      Removing equiv init insn %i (freq=%d)\n",
-                          INSN_UID (curr_insn),
-                          BLOCK_FOR_INSN (curr_insn)->frequency);
-                 print_rtl_slim (lra_dump_file, curr_insn, curr_insn, -1, 0);
+                 /* This is equiv init insn of pseudo which did not get a
+                    hard register -- remove the insn.  */
+                 if (lra_dump_file != NULL)
+                   {
+                     fprintf (lra_dump_file,
+                              "      Removing equiv init insn %i (freq=%d)\n",
+                              INSN_UID (curr_insn),
+                              BLOCK_FOR_INSN (curr_insn)->frequency);
+                     print_rtl_slim (lra_dump_file, curr_insn, curr_insn, -1, 
0);
+                   }
+                 lra_set_insn_deleted (curr_insn);
+                 continue;
                }
-             lra_set_insn_deleted (curr_insn);
-             continue;
            }
          curr_id = lra_get_insn_recog_data (curr_insn);
          curr_static_id = curr_id->insn_static_data;

Reply via email to