🚀 go-pugleaf

RetroBBS NetNews Server

Inspired by RockSolid Light RIP Retro Guy

Article View: gnu.gcc.bug
Article #6068

Subtle gcc bug on alpha?

#6068
From: Linus Torvalds
Date: Sat, 14 Dec 1996 00:00
227 lines
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-mail

Show 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