reload.c (find_reloads): Force constants into literal pool also if they are wrapped in a SUBREG.

2008-08-06  Andreas Krebbel  <krebbel1@de.ibm.com>

	* reload.c (find_reloads): Force constants into literal pool
	also if they are wrapped in a SUBREG.

2008-08-06  Andreas Krebbel  <krebbel1@de.ibm.com>

 	* gcc.c-torture/compile/20080806-1.c: New testcase.

From-SVN: r138763
This commit is contained in:
Andreas Krebbel 2008-08-06 06:51:11 +00:00 committed by Andreas Krebbel
parent c275297bdd
commit e0a1795933
4 changed files with 93 additions and 39 deletions

View File

@ -1,3 +1,8 @@
2008-08-06 Andreas Krebbel <krebbel1@de.ibm.com>
* reload.c (find_reloads): Force constants into literal pool
also if they are wrapped in a SUBREG.
2008-08-06 Maxim Kuvyrkov <maxim@codesourcery.com>
PR target/35659

View File

@ -3843,49 +3843,61 @@ find_reloads (rtx insn, int replace, int ind_levels, int live_known,
/* Any constants that aren't allowed and can't be reloaded
into registers are here changed into memory references. */
for (i = 0; i < noperands; i++)
if (! goal_alternative_win[i]
&& CONST_POOL_OK_P (recog_data.operand[i])
&& ((PREFERRED_RELOAD_CLASS (recog_data.operand[i],
(enum reg_class) goal_alternative[i])
== NO_REGS)
|| no_input_reloads)
&& operand_mode[i] != VOIDmode)
if (! goal_alternative_win[i])
{
int this_address_reloaded;
rtx op = recog_data.operand[i];
rtx subreg = NULL_RTX;
rtx plus = NULL_RTX;
enum machine_mode mode = operand_mode[i];
this_address_reloaded = 0;
substed_operand[i] = recog_data.operand[i]
= find_reloads_toplev (force_const_mem (operand_mode[i],
recog_data.operand[i]),
i, address_type[i], ind_levels, 0, insn,
&this_address_reloaded);
if (alternative_allows_const_pool_ref (this_address_reloaded == 0
? substed_operand[i]
: NULL,
recog_data.constraints[i],
goal_alternative_number))
goal_alternative_win[i] = 1;
}
/* Reloads of SUBREGs of CONSTANT RTXs are handled later in
push_reload so we have to let them pass here. */
if (GET_CODE (op) == SUBREG)
{
subreg = op;
op = SUBREG_REG (op);
mode = GET_MODE (op);
}
/* Likewise any invalid constants appearing as operand of a PLUS
that is to be reloaded. */
for (i = 0; i < noperands; i++)
if (! goal_alternative_win[i]
&& GET_CODE (recog_data.operand[i]) == PLUS
&& CONST_POOL_OK_P (XEXP (recog_data.operand[i], 1))
&& (PREFERRED_RELOAD_CLASS (XEXP (recog_data.operand[i], 1),
(enum reg_class) goal_alternative[i])
== NO_REGS)
&& operand_mode[i] != VOIDmode)
{
rtx tem = force_const_mem (operand_mode[i],
XEXP (recog_data.operand[i], 1));
tem = gen_rtx_PLUS (operand_mode[i],
XEXP (recog_data.operand[i], 0), tem);
if (GET_CODE (op) == PLUS)
{
plus = op;
op = XEXP (op, 1);
}
substed_operand[i] = recog_data.operand[i]
= find_reloads_toplev (tem, i, address_type[i],
ind_levels, 0, insn, NULL);
if (CONST_POOL_OK_P (op)
&& ((PREFERRED_RELOAD_CLASS (op,
(enum reg_class) goal_alternative[i])
== NO_REGS)
|| no_input_reloads)
&& mode != VOIDmode)
{
int this_address_reloaded;
rtx tem = force_const_mem (mode, op);
/* If we stripped a SUBREG or a PLUS above add it back. */
if (plus != NULL_RTX)
tem = gen_rtx_PLUS (mode, XEXP (plus, 0), tem);
if (subreg != NULL_RTX)
tem = gen_rtx_SUBREG (operand_mode[i], tem, SUBREG_BYTE (subreg));
this_address_reloaded = 0;
substed_operand[i] = recog_data.operand[i]
= find_reloads_toplev (tem, i, address_type[i], ind_levels,
0, insn, &this_address_reloaded);
/* If the alternative accepts constant pool refs directly
there will be no reload needed at all. */
if (plus == NULL_RTX
&& subreg == NULL_RTX
&& alternative_allows_const_pool_ref (this_address_reloaded == 0
? substed_operand[i]
: NULL,
recog_data.constraints[i],
goal_alternative_number))
goal_alternative_win[i] = 1;
}
}
/* Record the values of the earlyclobber operands for the caller. */

View File

@ -1,3 +1,7 @@
2008-08-06 Andreas Krebbel <krebbel1@de.ibm.com>
* gcc.c-torture/compile/20080806-1.c: New testcase.
2008-08-06 Maxim Kuvyrkov <maxim@codesourcery.com>
* gcc.target/ia64/20080802-1.c: New test.

View File

@ -0,0 +1,33 @@
int gl2;
typedef __SIZE_TYPE__ size_t;
extern void *memcpy (void *dest, const void *src, size_t n);
void
f1 ()
{
int i2;
unsigned char bf[64 * 1024 + 4];
for (i2 = 0; i2 < 3; i2++)
{
unsigned char *p2 = bf;
unsigned char *p3 = ((void *) 0);
unsigned short ctf2;
p2 += sizeof (short);
for (ctf2 = 0; ctf2 < 3; ctf2++)
{
if (ctf2 == 1)
{
unsigned short of = p2 - bf - 6;
unsigned short *ofp = (unsigned short *) &of;
memcpy (p3, ofp, sizeof (short));
}
if (gl2 == 1)
p2 += 3;
}
}
}