olson@modular.UUCP (Jon Olson) (01/22/89)
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@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;
bowen@cs.Buffalo.EDU (Devon E Bowen) (01/23/89)
In article <642@modular.UUCP> olson@modular.UUCP (Jon Olson) writes: >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@prep.ai.mit.edu. Hopefully someone will see this >who knows to forward to its appropriate destination. We've been tracking the same bug. Thanks for the patches. I'll forward them on to gnu for you. Devon Bowen (KA2NRC) FAX: (716) 636-3464 University at Buffalo BITNET: bowen@sunybcs.BITNET Internet: bowen@cs.Buffalo.EDU UUCP: ...!{watmath,boulder,decvax,rutgers}!sunybcs!bowen