re PR rtl-optimization/56195 (Error: incorrect register `%rdi' used with `l' suffix...
authorJakub Jelinek <jakub@redhat.com>
Fri, 8 Feb 2013 15:19:02 +0000 (16:19 +0100)
committerJakub Jelinek <jakub@gcc.gnu.org>
Fri, 8 Feb 2013 15:19:02 +0000 (16:19 +0100)
PR rtl-optimization/56195
* lra-constraints.c (get_reload_reg): Don't reuse regs
if they have smaller mode than requested, if they have
wider mode than requested, try to return a SUBREG.

* gcc.dg/torture/pr56195.c: New test.

From-SVN: r195891

gcc/ChangeLog
gcc/lra-constraints.c
gcc/testsuite/ChangeLog
gcc/testsuite/gcc.dg/torture/pr56195.c [new file with mode: 0644]

index 4c6bfba83213f9e4f7f9ca5d9214beb73c237b65..420f95d1e10086d225cae106bd232d360149e23c 100644 (file)
@@ -1,5 +1,10 @@
 2013-02-08  Jakub Jelinek  <jakub@redhat.com>
 
+       PR rtl-optimization/56195
+       * lra-constraints.c (get_reload_reg): Don't reuse regs
+       if they have smaller mode than requested, if they have
+       wider mode than requested, try to return a SUBREG.
+
        PR tree-optimization/56250
        * fold-const.c (extract_muldiv_1) <case NEGATE_EXPR>: Don't optimize
        if type is unsigned and code isn't MULT_EXPR.
index af68c3aee4c35180b3df67c65b655db33fa02d95..13420ebfbd84bc7a4eaee97bc5c4b8f0b85dc732 100644 (file)
@@ -421,8 +421,20 @@ get_reload_reg (enum op_type type, enum machine_mode mode, rtx original,
       if (rtx_equal_p (curr_insn_input_reloads[i].input, original)
          && in_class_p (curr_insn_input_reloads[i].reg, rclass, &new_class))
        {
-         *result_reg = curr_insn_input_reloads[i].reg;
-         regno = REGNO (*result_reg);
+         rtx reg = curr_insn_input_reloads[i].reg;
+         regno = REGNO (reg);
+         /* If input is equal to original and both are VOIDmode,
+            GET_MODE (reg) might be still different from mode.
+            Ensure we don't return *result_reg with wrong mode.  */
+         if (GET_MODE (reg) != mode)
+           {
+             if (GET_MODE_SIZE (GET_MODE (reg)) < GET_MODE_SIZE (mode))
+               continue;
+             reg = lowpart_subreg (mode, reg, GET_MODE (reg));
+             if (reg == NULL_RTX || GET_CODE (reg) != SUBREG)
+               continue;
+           }
+         *result_reg = reg;
          if (lra_dump_file != NULL)
            {
              fprintf (lra_dump_file, "  Reuse r%d for reload ", regno);
index 60fc9289f2bbdd32ad5ad45ff929e2c95c091b4e..5872f3685076d4a717446b4391678e4f478c837a 100644 (file)
@@ -1,3 +1,8 @@
+2013-02-08  Jakub Jelinek  <jakub@redhat.com>
+
+       PR rtl-optimization/56195
+       * gcc.dg/torture/pr56195.c: New test.
+
 2013-02-08  Mikael Morin  <mikael@gcc.gnu.org>
 
        PR fortran/54107
diff --git a/gcc/testsuite/gcc.dg/torture/pr56195.c b/gcc/testsuite/gcc.dg/torture/pr56195.c
new file mode 100644 (file)
index 0000000..d1949fd
--- /dev/null
@@ -0,0 +1,31 @@
+/* PR rtl-optimization/56195 */
+/* { dg-do assemble } */
+
+int i, a, t, b, c, d, e, f, j, *h;
+
+void
+fn (void)
+{
+  if (b)
+    {
+      int *p, *q;
+      char g;
+
+      if (f++)
+       for (;; e++);
+    lbl:
+      for (b = 0; b < 2; b++)
+       t /= d + 1 ? : i || a < c < (d = f) ? : 1 | (j = 2);
+
+      *p = g >= *q ^ c != a ^ *p;
+
+      if (!e)
+       {
+         q = p;
+         goto lbl;
+       }
+    }
+
+  if (h++)
+    goto lbl;
+}