------- Additional Comments From uweigand at gcc dot gnu dot org 2004-10-25 20:38 ------- 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