Commit 17fff17b by Eric Botcazou Committed by Eric Botcazou

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
parent 5b156fea
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> 2012-09-19 David Edelsohn <dje.gcc@gmail.com>
* config/rs6000/aix61.h (TARGET_DEFAULT): Add MASK_PPC_GPOPT, * config/rs6000/aix61.h (TARGET_DEFAULT): Add MASK_PPC_GPOPT,
......
...@@ -6352,6 +6352,20 @@ choose_reload_regs_init (struct insn_chain *chain, rtx *save_reload_reg_rtx) ...@@ -6352,6 +6352,20 @@ choose_reload_regs_init (struct insn_chain *chain, rtx *save_reload_reg_rtx)
rld[i].when_needed, rld[i].mode); 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 /* Assign hard reg targets for the pseudo-registers we must reload
into hard regs for this insn. into hard regs for this insn.
Also output the instructions to copy them in and out of the hard regs. 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) ...@@ -6942,7 +6956,7 @@ choose_reload_regs (struct insn_chain *chain)
for (j = 0; j < n_reloads; j++) for (j = 0; j < n_reloads; j++)
{ {
int r = reload_order[j]; int r = reload_order[j];
rtx check_reg; rtx check_reg, tem;
if (reload_inherited[r] && rld[r].reg_rtx) if (reload_inherited[r] && rld[r].reg_rtx)
check_reg = rld[r].reg_rtx; check_reg = rld[r].reg_rtx;
else if (reload_override_in[r] else if (reload_override_in[r]
...@@ -6974,10 +6988,26 @@ choose_reload_regs (struct insn_chain *chain) ...@@ -6974,10 +6988,26 @@ choose_reload_regs (struct insn_chain *chain)
If we succeeded removing some reload and we are doing a preliminary If we succeeded removing some reload and we are doing a preliminary
pass just to remove such reloads, make another pass, since the pass just to remove such reloads, make another pass, since the
removal of one reload might allow us to inherit another one. */ 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 && 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; pass = 2;
#endif
} }
} }
...@@ -8458,20 +8488,6 @@ emit_insn_if_valid_for_reload (rtx insn) ...@@ -8458,20 +8488,6 @@ emit_insn_if_valid_for_reload (rtx insn)
return NULL; 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 /* 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 OUT (which may also be a reload register). IN or OUT is from operand
OPNUM with reload type TYPE. OPNUM with reload type TYPE.
......
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> 2012-09-19 Richard Guenther <rguenther@suse.de>
* lib/c-torture.exp (TORTURE_OPTIONS): Add -Og -g. * lib/c-torture.exp (TORTURE_OPTIONS): Add -Og -g.
......
/* 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;
}
Markdown is supported
0% or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment