GCC 2.95.1 AMD K6 -O2 Problem
David King
david.king@lmco.com
Mon Oct 18 09:49:00 GMT 1999
Problem environment: Homebuilt system based on AMD K6/233 on Shuttle
HOT-595 mainboard, 64MB SDRAM. Linux kernel 2.2.12, glibc 2.1.1,
gcc 2.95.1 configured with --prefix=/usr --enable-shared
--enable-threads
--enable-haifa, no modifications to 2.95.1 source.
The following source demonstrates a problem in K6 optimization in
gcc 2.95.1:
---------------------------------------------------------------------
int
sub2(x, y)
int x, y;
{
printf("sub2 %d %d\n", x, y);
return x+y;
}
typedef int (*sub2_t) (int, int);
sub2_t jumptable[] = {sub2};
int
sub1(i, j)
int i, j;
{
return ((*jumptable[0])(i, j));
}
main()
{
int i = 3, j = 6, k;
printf("main calling sub1 %d %d\n", i, j);
k = sub1(i, j);
printf ("sub1 returned %d\n",k);
}
---------------------------------------------------------------------
When this program is compiled with any of these sets of options
cc -o test4 test4.c
cc -o test4 -O1 test4.c
cc -o test4 -O2 test4.c
cc -o test4 -O3 test4.c
cc -o test4 -m386 -O2 test4.c
cc -o test4 -mpentium -O2 test4.c
cc -o test4 -mpentium -O3 test4.c
cc -o test4 -mcpu=k6 -O1 test4.c
cc -o test4 -mcpu=k6 -O3 test4.c
and run, it produces the expected output
main calling sub1 3 6
sub2 3 6
sub1 returned 9
However, if it is compiled with this set of options
cc -o test4 -mcpu=k6 -O2 test4.c
and run, it produces this unexpected output on my system:
main calling sub1 3 6
sub2 134513731 3
sub1 returned 134513734
Examining the assembler produced for function sub1 in the -O1 and -O2
cases of -mcpu=k6 reveals the incorrect code produced. Under -O1
the code is:
pushl %ebp
movl %esp,%ebp
subl $8,%esp
addl $-8,%esp
pushl 12(%ebp)
pushl 8(%ebp)
movl jumptable,%eax
call *%eax
leave
ret
whereas under -O2 the code is:
pushl %ebp
movl %esp,%ebp
subl $8,%esp
addl $-8,%esp
pushl 12(%ebp)
pushl 8(%ebp)
movl jumptable,%eax
leave
call *%eax
ret
The optimization of the leave instruction from after to before the call
instruction ruins the stack frame.
In the case of -mcpu=k6 -O3, the same erroneous code exists for function
sub1, but the optimization of the main function results in sub1 never
being called.
I am not especially troubled by this, and have no need of a fix sent to
me. I turned on -mcpu=k6 optimization since I found it a new feature of
gcc 2.95.1, and found no problems with it when rebuilding such things as
linux kernel 2.2.12, XFree86 3.3.5, and various other products. This
particular problem appeared when attempting to install glibc 2.1.2; the
test example is derived from the relevant portion of
glibc-2.1.2/libio/genops.c, function __overflow. I have gone back to
using -mpentium for now, which is quite sufficient for me.
For reference, as requested by the gcc FAQ, here is the test4.s file
produced by gcc -g -o test4 -save-temps -mcpu=k6 -O2 test4.c:
---------------------------------------------------------------------
.file "test4.c"
.version "01.01"
.stabs "/home/djk/test/",100,0,0,.Ltext0
.stabs "test4.c",100,0,0,.Ltext0
.text
.Ltext0:
.stabs "gcc2_compiled.", 0x3c, 0, 0, 0
.stabs "int:t(0,1)=r(0,1);0020000000000;0017777777777;",128,0,0,0
.stabs "char:t(0,2)=r(0,2);0;127;",128,0,0,0
.stabs "long int:t(0,3)=r(0,1);0020000000000;0017777777777;",128,0,0,0
.stabs "unsigned
int:t(0,4)=r(0,1);0000000000000;0037777777777;",128,0,0,0
.stabs "long unsigned
int:t(0,5)=r(0,1);0000000000000;0037777777777;",128,0,0,0
.stabs "long long
int:t(0,6)=r(0,1);01000000000000000000000;0777777777777777777777;",128,0,0,0
.stabs "long long unsigned
int:t(0,7)=r(0,1);0000000000000;01777777777777777777777;",128,0,0,0
.stabs "short int:t(0,8)=r(0,8);-32768;32767;",128,0,0,0
.stabs "short unsigned int:t(0,9)=r(0,9);0;65535;",128,0,0,0
.stabs "signed char:t(0,10)=r(0,10);-128;127;",128,0,0,0
.stabs "unsigned char:t(0,11)=r(0,11);0;255;",128,0,0,0
.stabs "float:t(0,12)=r(0,1);4;0;",128,0,0,0
.stabs "double:t(0,13)=r(0,1);8;0;",128,0,0,0
.stabs "long double:t(0,14)=r(0,1);12;0;",128,0,0,0
.stabs "complex
int:t(0,15)=s8real:(0,1),0,32;imag:(0,1),32,32;;",128,0,0,0
.stabs "complex float:t(0,16)=r(0,16);4;0;",128,0,0,0
.stabs "complex double:t(0,17)=r(0,17);8;0;",128,0,0,0
.stabs "complex long double:t(0,18)=r(0,18);12;0;",128,0,0,0
.stabs "void:t(0,19)=(0,19)",128,0,0,0
.section .rodata
.LC0:
.string "sub2 %d %d\n"
.text
.align 4
.stabs "sub2:F(0,1)",36,0,3,sub2
.stabs "x:p(0,1)",160,0,3,8
.stabs "y:p(0,1)",160,0,3,12
.globl sub2
.type sub2,@function
sub2:
.stabn 68,0,4,.LM1-sub2
.LM1:
.LBB2:
pushl %ebp
movl %esp,%ebp
subl $16,%esp
pushl %esi
pushl %ebx
movl 8(%ebp),%esi
.stabn 68,0,5,.LM2-sub2
.LM2:
addl $-4,%esp
.stabn 68,0,4,.LM3-sub2
.LM3:
movl 12(%ebp),%ebx
.stabn 68,0,5,.LM4-sub2
.LM4:
pushl %ebx
pushl %esi
pushl $.LC0
call printf
.stabn 68,0,6,.LM5-sub2
.LM5:
leal (%ebx,%esi),%eax
leal -24(%ebp),%esp
popl %ebx
popl %esi
leave
ret
.stabn 68,0,7,.LM6-sub2
.LM6:
.LBE2:
.Lfe1:
.size sub2,.Lfe1-sub2
.stabs "x:r(0,1)",64,0,3,6
.stabs "y:r(0,1)",64,0,3,3
.stabn 192,0,0,.LBB2-sub2
.stabn 224,0,0,.LBE2-sub2
.Lscope0:
.stabs "",36,0,0,.Lscope0-sub2
.stabs "sub2_t:t(0,20)=(0,21)=*(0,22)=f(0,1)",128,0,8,0
.globl jumptable
.data
.stabs "jumptable:G(0,23)=ar(0,1);0;-1;(0,20)",32,0,9,0
.align 4
.type jumptable,@object
jumptable:
.long sub2
.size jumptable,4
.text
.align 4
.stabs "sub1:F(0,1)",36,0,12,sub1
.stabs "i:p(0,1)",160,0,12,8
.stabs "j:p(0,1)",160,0,12,12
.globl sub1
.type sub1,@function
sub1:
.stabn 68,0,13,.LM7-sub1
.LM7:
.stabn 68,0,14,.LM8-sub1
.LM8:
pushl %ebp
movl %esp,%ebp
subl $8,%esp
addl $-8,%esp
pushl 12(%ebp)
pushl 8(%ebp)
movl jumptable,%eax
leave
call *%eax
ret
.Lfe2:
.size sub1,.Lfe2-sub1
.Lscope1:
.stabs "",36,0,0,.Lscope1-sub1
.section .rodata
.LC1:
.string "main calling sub1 %d %d\n"
.LC2:
.string "sub1 returned %d\n"
.text
.align 4
.stabs "main:F(0,1)",36,0,17,main
.globl main
.type main,@function
main:
.stabn 68,0,17,.LM9-main
.LM9:
.stabn 68,0,18,.LM10-main
.LM10:
.LBB3:
.stabn 68,0,19,.LM11-main
.LM11:
pushl %ebp
movl %esp,%ebp
subl $8,%esp
addl $-4,%esp
pushl $6
pushl $3
pushl $.LC1
call printf
.stabn 68,0,20,.LM12-main
.LM12:
addl $-8,%esp
pushl $6
pushl $3
call sub1
.stabn 68,0,21,.LM13-main
.LM13:
addl $32,%esp
addl $-8,%esp
pushl %eax
pushl $.LC2
call printf
leave
ret
.stabn 68,0,22,.LM14-main
.LM14:
.LBE3:
.Lfe3:
.size main,.Lfe3-main
.stabs "k:r(0,1)",64,0,18,0
.stabn 192,0,0,.LBB3-main
.stabn 224,0,0,.LBE3-main
.Lscope2:
.stabs "",36,0,0,.Lscope2-main
.text
.stabs "",100,0,0,Letext
Letext:
.ident "GCC: (GNU) 2.95.1 19990816 (release)"
---------------------------------------------------------------------
David King
david.king@lmco.com
More information about the Gcc-bugs
mailing list