[Bug target/15286] ICE cause by reload
uweigand at gcc dot gnu dot org
gcc-bugzilla@gcc.gnu.org
Mon Oct 25 20:42:00 GMT 2004
------- Additional Comments From uweigand at gcc dot gnu dot org 2004-10-25 20:42 -------
(My last message got messed up somehow, I'm trying again.)
David Edelsohn wrote:
>Correction. While the reload changes fix the crash, it looks like there still
>is a bug because the resulting code does not access the correct SUBREG. It
>does not access the LSW.
That would be because alter_subreg doesn't handle paradoxical subregs
on big-endian machines correctly. Something like the following (untested)
should fix that one:
Index: gcc/final.c
===================================================================
RCS file: /cvs/gcc/gcc/gcc/final.c,v
retrieving revision 1.339
diff -c -p -r1.339 final.c
*** gcc/final.c 22 Oct 2004 17:05:05 -0000 1.339
--- gcc/final.c 25 Oct 2004 20:35:41 -0000
*************** alter_subreg (rtx *xp)
*** 2607,2613 ****
/* 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));
else
{
rtx new = simplify_subreg (GET_MODE (x), y, GET_MODE (y),
--- 2607,2628 ----
/* simplify_subreg does not remove subreg from volatile references.
We are required to. */
if (MEM_P (y))
! {
! 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 (y) < GET_MODE_SIZE (x))
! {
! int difference = GET_MODE_SIZE (y) - GET_MODE_SIZE (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),
--
http://gcc.gnu.org/bugzilla/show_bug.cgi?id=15286
More information about the Gcc-bugs
mailing list