This is the mail archive of the gcc-patches@gcc.gnu.org mailing list for the GCC project.


Index Nav: [Date Index] [Subject Index] [Author Index] [Thread Index]
Message Nav: [Date Prev] [Date Next] [Thread Prev] [Thread Next]
Other format: [Raw text]

[PATCH, IRA] Fix ALLOCNO_MODE in the case of paradoxical subreg.


Hi,

This patch is to address the problem described here:
http://gcc.gnu.org/ml/gcc/2013-09/msg00187.html

The patch changes ALLOCNO_MODE of a pseudo reg to be outermode if the
pseudo reg is used in a paradoxical subreg, so IRA will not mistakenly
assign an operand with a bigger mode to a smaller hardreg which
couldn't find a pair register.

No test is added because I cannot create a small testcase to reproduce
the problem on trunk, the difficulty of which was described in the
above post.

bootstrap and regression pass. ok for trunk?

Thanks,
Wei Mi.

2013-09-24  Wei Mi  <wmi@google.com>

        * ira-build.c (create_insn_allocnos): Fix ALLOCNO_MODE
        in the case of paradoxical subreg.

Index: ira-build.c
===================================================================
--- ira-build.c (revision 201963)
+++ ira-build.c (working copy)
@@ -1688,6 +1688,30 @@ create_insn_allocnos (rtx x, bool output
        }
       return;
     }
+  else if (code == SUBREG)
+    {
+      int regno;
+      rtx subreg_reg = SUBREG_REG (x);
+      enum machine_mode outermode, innermode;
+
+      create_insn_allocnos (subreg_reg, output_p);
+      /* For paradoxical subreg, set allocno's mode to be
+        the outermode.  */
+      outermode = GET_MODE (x);
+      innermode = GET_MODE (subreg_reg);
+      if (REG_P (subreg_reg)
+         && (GET_MODE_SIZE (outermode) > GET_MODE_SIZE (innermode)))
+       {
+         regno = REGNO (subreg_reg);
+         if (regno >= FIRST_PSEUDO_REGISTER)
+           {
+             ira_allocno_t a = ira_curr_regno_allocno_map[regno];
+             ira_assert (a != NULL);
+             ALLOCNO_MODE (a) = outermode;
+           }
+       }
+      return;
+    }
   else if (code == SET)
     {
       create_insn_allocnos (SET_DEST (x), true);


Index Nav: [Date Index] [Subject Index] [Author Index] [Thread Index]
Message Nav: [Date Prev] [Date Next] [Thread Prev] [Thread Next]