]> git.ipfire.org Git - thirdparty/gcc.git/commitdiff
re PR rtl-optimization/54290 (wrong code at -O2 with large offset)
authorEric Botcazou <ebotcazou@adacore.com>
Wed, 19 Sep 2012 15:38:16 +0000 (15:38 +0000)
committerEric Botcazou <ebotcazou@gcc.gnu.org>
Wed, 19 Sep 2012 15:38:16 +0000 (15:38 +0000)
PR rtl-optimization/54290
* reload1.c (choose_reload_regs): Also take into account secondary MEMs
to remove address replacements for inherited reloads.
(replaced_subreg): Move around.

From-SVN: r191484

gcc/ChangeLog
gcc/reload1.c
gcc/testsuite/ChangeLog
gcc/testsuite/gcc.c-torture/execute/20120919-1.c [new file with mode: 0644]

index e7f798049af33361b4bbab4a6458a869a032dcf6..48884d8ed62339361e9181dc35ce5b88d8029467 100644 (file)
@@ -1,3 +1,10 @@
+2012-09-19  Eric Botcazou  <ebotcazou@adacore.com>
+
+       PR rtl-optimization/54290
+       * reload1.c (choose_reload_regs): Also take into account secondary MEMs
+       to remove address replacements for inherited reloads.
+       (replaced_subreg): Move around.
+
 2012-09-19  David Edelsohn  <dje.gcc@gmail.com>
 
        * config/rs6000/aix61.h (TARGET_DEFAULT): Add MASK_PPC_GPOPT,
index 1bcdfad9377e6bb0602b9cac5953c75938628d75..4487ea83fa9ee8272523b539edc0e2215d5ba1ed 100644 (file)
@@ -6352,6 +6352,20 @@ choose_reload_regs_init (struct insn_chain *chain, rtx *save_reload_reg_rtx)
                              rld[i].when_needed, rld[i].mode);
 }
 
+#ifdef SECONDARY_MEMORY_NEEDED
+/* If X is not a subreg, return it unmodified.  If it is a subreg,
+   look up whether we made a replacement for the SUBREG_REG.  Return
+   either the replacement or the SUBREG_REG.  */
+
+static rtx
+replaced_subreg (rtx x)
+{
+  if (GET_CODE (x) == SUBREG)
+    return find_replacement (&SUBREG_REG (x));
+  return x;
+}
+#endif
+
 /* Assign hard reg targets for the pseudo-registers we must reload
    into hard regs for this insn.
    Also output the instructions to copy them in and out of the hard regs.
@@ -6942,7 +6956,7 @@ choose_reload_regs (struct insn_chain *chain)
       for (j = 0; j < n_reloads; j++)
        {
          int r = reload_order[j];
-         rtx check_reg;
+         rtx check_reg, tem;
          if (reload_inherited[r] && rld[r].reg_rtx)
            check_reg = rld[r].reg_rtx;
          else if (reload_override_in[r]
@@ -6974,10 +6988,26 @@ choose_reload_regs (struct insn_chain *chain)
             If we succeeded removing some reload and we are doing a preliminary
             pass just to remove such reloads, make another pass, since the
             removal of one reload might allow us to inherit another one.  */
-         else if (rld[r].in
+         else if (pass
+                  && rld[r].in
+                  && rld[r].out != rld[r].in
+                  && remove_address_replacements (rld[r].in))
+           pass = 2;
+#ifdef SECONDARY_MEMORY_NEEDED
+         /* If we needed a memory location for the reload, we also have to
+            remove its related reloads.  */
+         else if (pass
+                  && rld[r].in
                   && rld[r].out != rld[r].in
-                  && remove_address_replacements (rld[r].in) && pass)
+                  && (tem = replaced_subreg (rld[r].in), REG_P (tem))             
+                  && REGNO (tem) < FIRST_PSEUDO_REGISTER
+                  && SECONDARY_MEMORY_NEEDED (REGNO_REG_CLASS (REGNO (tem)),
+                                              rld[r].rclass, rld[r].inmode)
+                  && remove_address_replacements
+                     (get_secondary_mem (tem, rld[r].inmode, rld[r].opnum,
+                                         rld[r].when_needed)))
            pass = 2;
+#endif
        }
     }
 
@@ -8458,20 +8488,6 @@ emit_insn_if_valid_for_reload (rtx insn)
   return NULL;
 }
 
-#ifdef SECONDARY_MEMORY_NEEDED
-/* If X is not a subreg, return it unmodified.  If it is a subreg,
-   look up whether we made a replacement for the SUBREG_REG.  Return
-   either the replacement or the SUBREG_REG.  */
-
-static rtx
-replaced_subreg (rtx x)
-{
-  if (GET_CODE (x) == SUBREG)
-    return find_replacement (&SUBREG_REG (x));
-  return x;
-}
-#endif
-
 /* Emit code to perform a reload from IN (which may be a reload register) to
    OUT (which may also be a reload register).  IN or OUT is from operand
    OPNUM with reload type TYPE.
index 31069a0a212232d3081cceaa4d1d9b9c79f574b4..6c6fdf374122a774d5e7cf65f80893e9c82b1d9a 100644 (file)
@@ -1,3 +1,7 @@
+2012-09-19  Eric Botcazou  <ebotcazou@adacore.com>
+
+       * gcc.c-torture/execute/20120919-1.c: New test.
+
 2012-09-19  Richard Guenther  <rguenther@suse.de>
 
        * lib/c-torture.exp (TORTURE_OPTIONS): Add -Og -g.
diff --git a/gcc/testsuite/gcc.c-torture/execute/20120919-1.c b/gcc/testsuite/gcc.c-torture/execute/20120919-1.c
new file mode 100644 (file)
index 0000000..e7f3295
--- /dev/null
@@ -0,0 +1,37 @@
+/* PR rtl-optimization/54290 */
+/* Testcase by Eric Volk <eriksnga@gmail.com> */
+
+double vd[2] = {1., 0.};
+int vi[2] = {1234567890, 0};
+double *pd = vd;
+int *pi = vi;
+
+extern void abort(void);
+
+void init (int *n, int *dummy) __attribute__ ((noinline,noclone));
+
+void init (int *n, int *dummy)
+{
+  if(0 == n) dummy[0] = 0;
+}
+
+int main (void)
+{
+  int dummy[1532];
+  int i = -1, n = 1, s = 0;
+  init (&n, dummy);
+  while (i < n) {
+    if (i == 0) {
+      if (pd[i] > 0) {
+        if (pi[i] > 0) {
+          s += pi[i];
+        }
+      }
+      pd[i] = pi[i];
+    }
+    ++i;
+  }
+  if (s != 1234567890)
+    abort ();
+  return 0;
+}