diff options
author | Eric Botcazou <ebotcazou@adacore.com> | 2012-09-19 15:38:16 +0000 |
---|---|---|
committer | Eric Botcazou <ebotcazou@gcc.gnu.org> | 2012-09-19 15:38:16 +0000 |
commit | 17fff17b06f8a9fe4aad1e117cce060be0c6ef61 (patch) | |
tree | 517a7be095a7ea671516cbc69701962ee2aface4 | |
parent | 5b156feaf87dac1a14203b280f19c1d645994211 (diff) | |
download | gcc-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/ChangeLog | 7 | ||||
-rw-r--r-- | gcc/reload1.c | 50 | ||||
-rw-r--r-- | gcc/testsuite/ChangeLog | 4 | ||||
-rw-r--r-- | gcc/testsuite/gcc.c-torture/execute/20120919-1.c | 37 |
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; +} |