aboutsummaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorEric Botcazou <ebotcazou@adacore.com>2012-09-19 15:38:16 +0000
committerEric Botcazou <ebotcazou@gcc.gnu.org>2012-09-19 15:38:16 +0000
commit17fff17b06f8a9fe4aad1e117cce060be0c6ef61 (patch)
tree517a7be095a7ea671516cbc69701962ee2aface4
parent5b156feaf87dac1a14203b280f19c1d645994211 (diff)
downloadgcc-17fff17b06f8a9fe4aad1e117cce060be0c6ef61.zip
gcc-17fff17b06f8a9fe4aad1e117cce060be0c6ef61.tar.gz
gcc-17fff17b06f8a9fe4aad1e117cce060be0c6ef61.tar.bz2
re PR rtl-optimization/54290 (wrong code at -O2 with large offset)
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
-rw-r--r--gcc/ChangeLog7
-rw-r--r--gcc/reload1.c50
-rw-r--r--gcc/testsuite/ChangeLog4
-rw-r--r--gcc/testsuite/gcc.c-torture/execute/20120919-1.c37
4 files changed, 81 insertions, 17 deletions
diff --git a/gcc/ChangeLog b/gcc/ChangeLog
index e7f7980..48884d8 100644
--- a/gcc/ChangeLog
+++ b/gcc/ChangeLog
@@ -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,
diff --git a/gcc/reload1.c b/gcc/reload1.c
index 1bcdfad..4487ea8 100644
--- a/gcc/reload1.c
+++ b/gcc/reload1.c
@@ -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.
diff --git a/gcc/testsuite/ChangeLog b/gcc/testsuite/ChangeLog
index 31069a0..6c6fdf3 100644
--- a/gcc/testsuite/ChangeLog
+++ b/gcc/testsuite/ChangeLog
@@ -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
index 0000000..e7f3295
--- /dev/null
+++ b/gcc/testsuite/gcc.c-torture/execute/20120919-1.c
@@ -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;
+}