Article View: gnu.gcc.bug
Article #6068Subtle gcc bug on alpha?
From: Linus Torvalds
Date: Sat, 14 Dec 1996 00:00
Date: Sat, 14 Dec 1996 00:00
227 lines
5439 bytes
5439 bytes
Richard (and bug mailing list),
I've been trying to hunt down a kernel problem that occurs only on an
alpha, and it looks like it's actually due to a compiler bug related to
some kind of register re-loading issues.
The behaviour I see comes from something like this:
int logmask = 32 - r->rtmsg_prefixlen;
... lots of other variables, quite some code in between ...
fz = class->fib_zones[logmask];
Now, what happens is that due to register pressures, the "logmask"
variable is written onto the stack, and then re-loaded later when it's
needed for the array indexing. What I see is that gcc writes it as a
32-bit value, but when it re-loads it it loads it as a 64-bit value, so
that the upper 32 bits are random crap.
The generated code looks like this (edited out the stuff that isn't
relevant):
ldq_u $4,38($9)
addq $9,38,$1
extbl $4,$1,$4 /* r->rtmsg_prefixlen */
bis $31,32,$2
subl $2,$4,$2
stl $2,88($30)
...
ldq $7,88($30) /* Wheee!!! */
ldq $8,72($30)
s8addq $7,$8,$1
Note that either the "stl" should be a "stq" (it is certainly correct at
that point, because the subl will have made sure the high bits are
sign-extended correctly), or the "ldq" should be a "ldl". But this
combination results in garbage (whetever happened to be on the stack
before in the high 32 bits).
Have you seen or heard of anything like this?
Oh, I succeeded in creating a reasonably minimal test case, appended below
(it doesn't do anything, but compile it with "gcc -O2 -S" on an alpha and
you'll see what I mean). It seems to break with both 2.7.2 and a snapshot
from early November for me - can you confirm?
Linus
-----
/*
* Stupid program, compile into assembly on an alpha with "-O2 -S"
* to see register reloading problem
*/
int main(int argc, unsigned char **argv)
{
int bug = 32-**argv;
int a,b,c,d,e,f,g,h,i,j;
int a1,b1,c1,d1,e1,f1,g1,h1,i1,j1;
argc>>=1;
a = argc+1;
b = argc+2;
c = argc+3;
d = argc+4;
e = argc+5;
f = argc+6;
g = argc+7;
h = argc+8;
i = argc+9;
j = argc+10;
argc>>=1;
a1 = argc+1;
b1 = argc+2;
c1 = argc+3;
d1 = argc+4;
e1 = argc+5;
f1 = argc+6;
g1 = argc+7;
h1 = argc+8;
i1 = argc+9;
j1 = argc+10;
test(a,b,c,d,e,f,g,h,i,j);
test(a1,b1,c1,d1,e1,f1,g1,h1,i1,j1);
j = a+b+c+d+e+f+g+h+i+j;
printf("%p %p\n", argv, argv+bug);
return j;
}
-------
.file 1 "t.c"
.version "01.01"
.set noat
gcc2_compiled.:
__gnu_compiled_c:
.section .rodata
.align 3
$C32:
.ascii "%p %p\12\0"
.text
.align 3
.globl main
.ent main
main:
ldgp $29,0($27)
main..ng:
lda $30,-224($30)
.frame $30,224,$26,0
stq $26,32($30)
stq $9,40($30)
stq $10,48($30)
stq $11,56($30)
stq $12,64($30)
stq $13,72($30)
stq $14,80($30)
stq $15,88($30)
.mask 0x400fe00,-192
.prologue 1
sra $16,1,$11
stq $17,96($30)
addl $11,2,$3
stq $3,120($30)
addl $11,3,$3
stq $3,128($30)
addl $11,4,$3
stq $3,136($30)
ldq $3,96($30)
ldq $2,0($3)
addl $11,5,$3
stq $3,144($30)
ldq_u $1,0($2)
sra $11,1,$9
addl $11,6,$3
extbl $1,$2,$1
stq $3,152($30)
bis $31,32,$3
subl $3,$1,$1
ldq $17,120($30)
addl $11,7,$3
stq $3,160($30)
addl $11,8,$3
stq $3,168($30)
addl $11,9,$3
stq $3,176($30)
addl $9,2,$3
stq $3,184($30)
addl $9,3,$3
stq $3,192($30)
addl $9,4,$3
stq $3,200($30)
addl $9,5,$3
stq $3,208($30)
addl $9,6,$3
stq $3,216($30)
ldq $3,160($30)
ldq $18,128($30)
ldq $19,136($30)
stq $3,0($30)
addl $11,1,$10
ldq $3,168($30)
bis $10,$10,$16
ldq $20,144($30)
addl $9,1,$12
ldq $21,152($30)
addl $9,7,$13
stq $3,8($30)
addl $9,8,$14
ldq $3,176($30)
addl $9,9,$15
stl $1,112($30) ******** HERE - save 32 bits *********
addl $11,10,$11
stq $11,24($30)
addl $9,10,$9
stq $3,16($30)
jsr $26,test
ldgp $29,0($26)
ldq $17,184($30)
ldq $18,192($30)
stq $13,0($30)
ldq $19,200($30)
ldq $20,208($30)
ldq $21,216($30)
stq $14,8($30)
stq $15,16($30)
bis $12,$12,$16
stq $9,24($30)
jsr $26,test
ldgp $29,0($26)
ldq $3,120($30)
ldq $17,96($30)
addq $10,$3,$10
ldq $3,112($30) ******** HERE - load 64 bits *******
s8addq $3,$17,$18 *** random high 32 bits used here **
ldq $3,128($30)
addq $10,$3,$10
ldq $3,136($30)
addq $10,$3,$10
ldq $3,144($30)
addq $10,$3,$10
ldq $3,152($30)
addq $10,$3,$10
ldq $3,160($30)
addq $10,$3,$10
ldq $3,168($30)
addq $10,$3,$10
ldq $3,176($30)
lda $16,$C32
addq $10,$3,$10
addl $11,$10,$11
jsr $26,printf
ldgp $29,0($26)
bis $11,$11,$0
ldq $26,32($30)
ldq $9,40($30)
ldq $10,48($30)
ldq $11,56($30)
ldq $12,64($30)
ldq $13,72($30)
ldq $14,80($30)
ldq $15,88($30)
addq $30,224,$30
ret $31,($26),1
.end main
.ident "GCC: (GNU) 2.7.2"
Technical Details
Message-ID:
<Pine.LNX.3.95.961214192233.17988A-100000@linux.cs.Helsinki.FI>Path:
arc1-ca.pugleaf.net!unknown!not-for-mailShow Full Headers
Complete Article Headers
X-Google-Language: ENGLISH,ASCII-7-bit X-Google-Thread: 113d02,a327271f3bb2a594,start X-Google-Attributes: gid113d02,public From: torvalds@cs.Helsinki.FI (Linus Torvalds) Subject: Subtle gcc bug on alpha? Date: 1996/12/14 Message-ID: <Pine.LNX.3.95.961214192233.17988A-100000@linux.cs.Helsinki.FI> X-Deja-AN: 204123463 sender: bug-gcc-request@prep.ai.mit.edu x-gateway: relay6.UU.NET from bug-gcc to gnu.gcc.bug; Sat, 14 Dec 1996 12:54:08 EST content-type: TEXT/PLAIN; charset=US-ASCII mime-version: 1.0 newsgroups: gnu.gcc.bug