re PR rtl-optimization/60508 (internal compiler error: in lra_set_insn_recog_data...
authorVladimir Makarov <vmakarov@redhat.com>
Fri, 14 Mar 2014 16:34:57 +0000 (16:34 +0000)
committerVladimir Makarov <vmakarov@gcc.gnu.org>
Fri, 14 Mar 2014 16:34:57 +0000 (16:34 +0000)
2014-03-14  Vladimir Makarov  <vmakarov@redhat.com>

PR rtl-optimization/60508
* lra-constraints.c (get_reload_reg): Add new parameter
in_subreg_p.
(process_addr_reg, simplify_operand_subreg, curr_insn_transform):
Pass the new parameter values.

2014-03-14  Vladimir Makarov  <vmakarov@redhat.com>

PR rtl-optimization/60508
* gcc.target/i386/pr60508.c: New.

From-SVN: r208570

gcc/ChangeLog
gcc/lra-constraints.c
gcc/testsuite/ChangeLog
gcc/testsuite/gcc.target/i386/pr60508.c [new file with mode: 0644]

index 8a4ab7a0387152238bd83037d549061d4b1f9551..09b6e1f73656c0a3438100b7d4cade2dac556898 100644 (file)
@@ -1,3 +1,11 @@
+2014-03-14  Vladimir Makarov  <vmakarov@redhat.com>
+
+       PR rtl-optimization/60508
+       * lra-constraints.c (get_reload_reg): Add new parameter
+       in_subreg_p.
+       (process_addr_reg, simplify_operand_subreg, curr_insn_transform):
+       Pass the new parameter values.
+
 2014-03-14  Richard Biener  <rguenther@suse.de>
 
        * common.opt: Revert unintented changes from r205065.
index 288e24b4fe15df3b23923ccd76dccda8ca51a2a7..ba4d489e9e5e6d43ef609833cfbb9ecc6862a2c1 100644 (file)
@@ -439,14 +439,16 @@ init_curr_insn_input_reloads (void)
 }
 
 /* Create a new pseudo using MODE, RCLASS, ORIGINAL or reuse already
-   created input reload pseudo (only if TYPE is not OP_OUT).  The
-   result pseudo is returned through RESULT_REG.  Return TRUE if we
-   created a new pseudo, FALSE if we reused the already created input
-   reload pseudo.  Use TITLE to describe new registers for debug
-   purposes.  */
+   created input reload pseudo (only if TYPE is not OP_OUT).  Don't
+   reuse pseudo if IN_SUBREG_P is true and the reused pseudo should be
+   wrapped up in SUBREG.  The result pseudo is returned through
+   RESULT_REG.  Return TRUE if we created a new pseudo, FALSE if we
+   reused the already created input reload pseudo.  Use TITLE to
+   describe new registers for debug purposes.  */
 static bool
 get_reload_reg (enum op_type type, enum machine_mode mode, rtx original,
-               enum reg_class rclass, const char *title, rtx *result_reg)
+               enum reg_class rclass, bool in_subreg_p,
+               const char *title, rtx *result_reg)
 {
   int i, regno;
   enum reg_class new_class;
@@ -471,6 +473,8 @@ get_reload_reg (enum op_type type, enum machine_mode mode, rtx original,
             Ensure we don't return *result_reg with wrong mode.  */
          if (GET_MODE (reg) != mode)
            {
+             if (in_subreg_p)
+               continue;
              if (GET_MODE_SIZE (GET_MODE (reg)) < GET_MODE_SIZE (mode))
                continue;
              reg = lowpart_subreg (mode, reg, GET_MODE (reg));
@@ -1139,9 +1143,11 @@ process_addr_reg (rtx *loc, rtx *before, rtx *after, enum reg_class cl)
   rtx reg;
   rtx new_reg;
   enum machine_mode mode;
-  bool before_p = false;
+  bool subreg_p, before_p = false;
 
-  loc = strip_subreg (loc);
+  subreg_p = GET_CODE (*loc) == SUBREG;
+  if (subreg_p)
+    loc = &SUBREG_REG (*loc);
   reg = *loc;
   mode = GET_MODE (reg);
   if (! REG_P (reg))
@@ -1171,7 +1177,7 @@ process_addr_reg (rtx *loc, rtx *before, rtx *after, enum reg_class cl)
        {
          reg = *loc;
          if (get_reload_reg (after == NULL ? OP_IN : OP_INOUT,
-                             mode, reg, cl, "address", &new_reg))
+                             mode, reg, cl, subreg_p, "address", &new_reg))
            before_p = true;
        }
       else if (new_class != NO_REGS && rclass != new_class)
@@ -1304,7 +1310,7 @@ simplify_operand_subreg (int nop, enum machine_mode reg_mode)
          = (enum reg_class) targetm.preferred_reload_class (reg, ALL_REGS);
 
       if (get_reload_reg (curr_static_id->operand[nop].type, reg_mode, reg,
-                         rclass, "subreg reg", &new_reg))
+                         rclass, TRUE, "subreg reg", &new_reg))
        {
          bool insert_before, insert_after;
          bitmap_set_bit (&lra_subreg_reload_pseudos, REGNO (new_reg));
@@ -1365,7 +1371,7 @@ simplify_operand_subreg (int nop, enum machine_mode reg_mode)
        = (enum reg_class) targetm.preferred_reload_class (reg, ALL_REGS);
 
       if (get_reload_reg (curr_static_id->operand[nop].type, mode, reg,
-                          rclass, "paradoxical subreg", &new_reg))
+                          rclass, TRUE, "paradoxical subreg", &new_reg))
         {
          rtx subreg;
          bool insert_before, insert_after;
@@ -3573,7 +3579,7 @@ curr_insn_transform (void)
            new_reg = emit_inc (rclass, *loc, *loc,
                                /* This value does not matter for MODIFY.  */
                                GET_MODE_SIZE (GET_MODE (op)));
-         else if (get_reload_reg (OP_IN, Pmode, *loc, rclass,
+         else if (get_reload_reg (OP_IN, Pmode, *loc, rclass, FALSE,
                                   "offsetable address", &new_reg))
            lra_emit_move (new_reg, *loc);
          before = get_insns ();
@@ -3615,7 +3621,8 @@ curr_insn_transform (void)
                }
            }
          old = *loc;
-         if (get_reload_reg (type, mode, old, goal_alt[i], "", &new_reg)
+         if (get_reload_reg (type, mode, old, goal_alt[i],
+                             loc != curr_id->operand_loc[i], "", &new_reg)
              && type != OP_OUT)
            {
              push_to_sequence (before);
index 97e6bba73811a6b47e0679df5e14e7113d12d1c9..fa781bd1c7ac327f219b2cf48c6221c13d4ee98c 100644 (file)
@@ -1,3 +1,8 @@
+2014-03-14  Vladimir Makarov  <vmakarov@redhat.com>
+
+       PR rtl-optimization/60508
+       * gcc.target/i386/pr60508.c: New.
+
 2014-03-14  Richard Biener  <rguenther@suse.de>
 
        PR middle-end/60518
diff --git a/gcc/testsuite/gcc.target/i386/pr60508.c b/gcc/testsuite/gcc.target/i386/pr60508.c
new file mode 100644 (file)
index 0000000..78dfb78
--- /dev/null
@@ -0,0 +1,31 @@
+/* { dg-do compile } */
+/* { dg-options "-O -w" } */
+int a = 1, g, h = 1, d, e, *f;
+char b;
+static int c[] = { 0, 0 };
+void fn2 (void);
+
+void
+fn1 (short x, int l)
+{
+lab:
+  {
+    int k, m[0];
+    long j = h ? 0 : 0 / 0;
+    unsigned char n = j;
+    unsigned char i = x >= 0 ? n : n >> x;
+    g = i;
+    for (;;)
+      {
+        if (a)
+          goto lab;
+        while (d)
+          {
+            e = b = c[l];
+            fn2 ();
+          }
+        int o = m[0];
+        f = &k;
+      }
+  }
+}