lgm@ODDJOB.UCHICAGO.EDU (12/26/88)
The bug described below has been present for several GCC versions
now. I would emphasize again that although the example below is
rather contrived, the bug also manifests itself when compiling
"cccp.c" of GCC, if all optimizations - including '-fforce-addr'
and '-fforce-mem' - are requested.
Perhaps it helps if I mention that according to 'sdb', the
compiler is aborting in final() of "final.c" because
constrain_operands() is returning failure. One possible
interpretation is that GCC plans to generate an instruction like
cmp.b (%a0)+,(%a1)+
but is unable to fulfil the constraint on this instruction:
getting both operands into address registers.
SYNOPSIS:
GCC Version 1.32 dumps core in certain circumstances, when compiling
statements of the form
if ( *p++ != *q++ ) ...
In particular, core dumps seem to occur when p and q above
were originally meant to be in registers but ended up on the stack
(i.e., spilled).
The bug manifests itself when compiling "cccp.c" with '-O -fforce-addr
-fforce-mem -fcombine-regs -fomit-frame-pointer' - i.e., it blew up
my re-compilation of GCC itself. The example below is more contrived,
but also more illustrative; especially since in the example, a mere '-O'
brings out the bug.
MACHINE AND OS:
AT&T UNIX PC 3B1 (based on Motorola 68010 microprocessor) running
OS Version 3.5 (compatible with UNIX System V Release 2).
CONFIGURATION FILES:
'config.gcc 3b1'
TRANSCRIPT (INPUT FILE, COMMAND LINE, OUTPUT):
_______________________________________
$ cat ptrcmp.c
extern void g();
void
f( p, q, r, s, t, u, v )
register char *p, *q, *r, *s, *t, *u, *v;
{
*p++ = *q++ = *r++ = *s++ = *t++ = *u++ = *v++;
{
register char *w = p + ( q - r );
register char *x = s + ( t - u );
if ( *w++ != *x++ )
g( p, q, r, s, t, u, v, w, x );
}
}
$ ../final/gcc -B../final/ -S -O -v ptrcmp.c
gcc version 1.32
../final/cpp -v -undef -D__GNUC__ -Dmc68k -Dunix -Dunixpc -D__mc68k__ -D__unix__ -D__unixpc__ -D__OPTIMIZE__ ptrcmp.c /tmp/cca26753.cpp
GNU CPP version 1.32
../final/cc1 /tmp/cca26753.cpp -quiet -dumpbase ptrcmp.c -O -version -o ptrcmp.s
GNU C version 1.32 (68k, SGS/AT&T unixpc syntax) compiled by GNU C version 1.32.
../final/gcc: Program cc1 got fatal signal 6.
$ cat ptrcmp.s
file "ptrcmp.c"
text
even
global f
f:
link.w %a6,&-4
movm.l &0x303c,-(%sp)
mov.l 8(%fp),%d3
mov.l 12(%fp),%d2
mov.l 16(%fp),%d1
mov.l 20(%fp),%a5
mov.l 24(%fp),%a3
mov.l 28(%fp),%a2
mov.l 32(%fp),%a4
mov.b (%a4)+,%d0
mov.b %d0,(%a2)+
mov.b %d0,(%a3)+
mov.b %d0,(%a5)+
mov.l %d1,%a1
addq.l &1,%d1
mov.b %d0,(%a1)
mov.l %d2,%a1
addq.l &1,%d2
mov.b %d0,(%a1)
mov.l %d3,%a1
addq.l &1,%d3
mov.b %d0,(%a1)
mov.l %d2,%d0
sub.l %d1,%d0
add.l %d3,%d0
mov.l %d0,-4(%fp)
mov.l %a3,%d0
sub.l %a2,%d0
lea (%a5,%d0.l),%a0
mov.l -4(%fp),%a1
addq.w &1,%a1
mov.l %a1,-4(%fp)
sub.l &1,%a1
$
_______________________________________
EXPLANATION OF TRANSCRIPT:
Notice how the use of -4(%fp) indicates that w has been spilled.
Lawrence G. Mayka
Aurora, Illinois
lgm@lmayk.UUCP
chinet!lmayk!lgm