re PR target/15286 (ICE cause by reload)

PR target/15286
	* final.c (alter_subreg): Compute correct offset to use with
	paradoxical SUBREGs of memory operands.
	* recog.c (general_operand): Allow paradoxical SUBREGs of
	memory operands after reload.
	* simplify-rtx.c (simplify_gen_subreg): Fail if simplify_subreg
	has failed when passed a hard register.

From-SVN: r89752
This commit is contained in:
Ulrich Weigand 2004-10-28 12:47:21 +00:00 committed by Ulrich Weigand
parent 4af46a327e
commit fd326ba823
4 changed files with 34 additions and 4 deletions

View File

@ -1,3 +1,13 @@
2004-10-28 Ulrich Weigand <uweigand@de.ibm.com>
PR target/15286
* final.c (alter_subreg): Compute correct offset to use with
paradoxical SUBREGs of memory operands.
* recog.c (general_operand): Allow paradoxical SUBREGs of
memory operands after reload.
* simplify-rtx.c (simplify_gen_subreg): Fail if simplify_subreg
has failed when passed a hard register.
2004-10-28 Aldy Hernandez <aldyh@redhat.com>
* function.c (assign_parm_setup_block): Handle parallels correctly.

View File

@ -2608,7 +2608,24 @@ alter_subreg (rtx *xp)
/* simplify_subreg does not remove subreg from volatile references.
We are required to. */
if (MEM_P (y))
*xp = adjust_address (y, GET_MODE (x), SUBREG_BYTE (x));
{
int offset = SUBREG_BYTE (x);
/* For paradoxical subregs on big-endian machines, SUBREG_BYTE
contains 0 instead of the proper offset. See simplify_subreg. */
if (offset == 0
&& GET_MODE_SIZE (GET_MODE (y)) < GET_MODE_SIZE (GET_MODE (x)))
{
int difference = GET_MODE_SIZE (GET_MODE (y))
- GET_MODE_SIZE (GET_MODE (x));
if (WORDS_BIG_ENDIAN)
offset += (difference / UNITS_PER_WORD) * UNITS_PER_WORD;
if (BYTES_BIG_ENDIAN)
offset += difference % UNITS_PER_WORD;
}
*xp = adjust_address (y, GET_MODE (x), offset);
}
else
{
rtx new = simplify_subreg (GET_MODE (x), y, GET_MODE (y),

View File

@ -936,8 +936,10 @@ general_operand (rtx op, enum machine_mode mode)
#ifdef INSN_SCHEDULING
/* On machines that have insn scheduling, we want all memory
reference to be explicit, so outlaw paradoxical SUBREGs. */
if (MEM_P (sub)
reference to be explicit, so outlaw paradoxical SUBREGs.
However, we must allow them after reload so that they can
get cleaned up by cleanup_subreg_operands. */
if (!reload_completed && MEM_P (sub)
&& GET_MODE_SIZE (mode) > GET_MODE_SIZE (GET_MODE (sub)))
return 0;
#endif

View File

@ -3789,7 +3789,8 @@ simplify_gen_subreg (enum machine_mode outermode, rtx op,
if (newx)
return newx;
if (GET_CODE (op) == SUBREG || GET_MODE (op) == VOIDmode)
if (GET_CODE (op) == SUBREG || GET_MODE (op) == VOIDmode
|| (REG_P (op) && REGNO (op) < FIRST_PSEUDO_REGISTER))
return NULL_RTX;
return gen_rtx_SUBREG (outermode, op, byte);