Optimization bug in GCC V1.32 on BIG_ENDIAN machines
Jon Olson
olson at modular.UUCP
Sun Jan 22 14:36:26 AEST 1989
I am sending out this GCC bug-report out to a couple likely
newsgroups since I have no luck reaching the gcc-bug account
of gcc-bug at prep.ai.mit.edu. Hopefully someone will see this
who knows to forward to its appropriate destination.
I tracked down a rather annoying bug in GCC V1.32 on SUNOS 4.0
the other day. The small test program below demonstrates this
bug:
struct TEST
{
unsigned char c;
unsigned short s;
int i;
} r1, r2, r3;
main()
{
foo( &r1, 1, 2, 3 );
printf( "c = %d, s = %d, i = %d\n", r1.c, r1.s, r1.i );
}
foo( p, i1, i2, i3 )
struct TEST *p;
int i1, i2, i3;
{
p->c = i1; /* Here, GCC generates moveb a6@(12),a0@ */
p->s = i2;
p->i = i3;
}
After a bit of digging I found the problem lied in some missing
logic in `combine.c' with respect to big-endian machines. During
optimization, this code forgot to add in the extra 3-bytes required
to extract the low byte of `i1' instead of the high byte. Below
are the context diffs for the change I made to fix the bug. Maybe
somebody should go through GCC carefully to make sure that there
are no other such big-endian machine problems???
*** combine.c.save Sat Jan 21 20:45:51 1989
--- combine.c Sat Jan 21 21:02:39 1989
***************
*** 878,891 ****
paradoxical case where gen_lowpart_for_combine makes them. */
if (SUBREG_REG (x) == to
&& GET_CODE (to) == MEM)
! {
if (!undobuf.storage)
undobuf.storage = (char *) oballoc (0);
/* Note if the plus_constant doesn't make a valid address
then this combination won't be accepted. */
return gen_rtx (MEM, GET_MODE (x),
! plus_constant (XEXP (to, 0),
! SUBREG_WORD (x) * UNITS_PER_WORD));
}
break;
--- 878,895 ----
paradoxical case where gen_lowpart_for_combine makes them. */
if (SUBREG_REG (x) == to
&& GET_CODE (to) == MEM)
! {/****** JPO: Fixed this for BIG-ENDIAN machines*****/
! register int offset = SUBREG_WORD (x) * UNITS_PER_WORD;
! #ifdef BYTES_BIG_ENDIAN
! offset -= (min (UNITS_PER_WORD, GET_MODE_SIZE (GET_MODE (x)))
! - min (UNITS_PER_WORD, GET_MODE_SIZE (GET_MODE (to))));
! #endif
if (!undobuf.storage)
undobuf.storage = (char *) oballoc (0);
/* Note if the plus_constant doesn't make a valid address
then this combination won't be accepted. */
return gen_rtx (MEM, GET_MODE (x),
! plus_constant (XEXP (to, 0), offset));
}
break;
More information about the Comp.lang.c
mailing list