This is the mail archive of the
gcc-bugs@gcc.gnu.org
mailing list for the GCC project.
Optimization bug on i386, stack fiddling
- To: gcc-bugs at gcc dot gnu dot org
- Subject: Optimization bug on i386, stack fiddling
- From: Lars Balker Rasmussen <lbr at mjolner dot dk>
- Date: 06 Jan 2000 16:53:35 +0100
Hi,
We found that gcc (2.7.2.3, 2.8.1 and 2.95.2) generates wrong code with
-O1 on the following code snippet (tested on Solaris 7 i386):
int printf(const char *, ...);
int main()
{
asm ("pushl %ebp");
printf("Hello world\n");
asm ("popl %ebp");
return 0;
}
While the pushl/popl may seem pathological, we merely wanted an example
we knew would crash'n'burn. In the real program, the call is to a
library function that is not too register friendly, so we padded its
call with
asm ("pushl %edi");
asm ("pushl %esi");
asm ("pushl %eax");
asm ("pushl %ebx");
asm ("pushl %ecx");
asm ("pushl %edx");
foo();
asm ("popl %edx");
asm ("popl %ecx");
asm ("popl %ebx");
asm ("popl %eax");
asm ("popl %esi");
asm ("popl %edi");
assuming that it couldn't hurt to do a bit more stack-operating than is
really necessary...
"gcc -V 2.95.2 -S -O0" generates the following code for the main() above:
main:
pushl %ebp
movl %esp,%ebp
subl $8,%esp
/APP
pushl %ebp
/NO_APP
addl $-12,%esp
pushl $.LC0
call printf
addl $16,%esp
/APP
popl %ebp
/NO_APP
xorl %eax,%eax
jmp .L2
.align 4
.L2:
leave
ret
And "gcc -V 2.95.2 -S -O1" generates:
main:
pushl %ebp
movl %esp,%ebp
subl $8,%esp
/APP
pushl %ebp
/NO_APP
addl $-12,%esp
pushl $.LC0
call printf
/APP
popl %ebp
/NO_APP
xorl %eax,%eax
leave
ret
As can be seen, the main difference is that gcc -O1 wrongly(?) assumes
it can safely leave the stack-cleanup to "leave", instead of actually
doing if after the call, screwing up any use of the stack after the
fact.
Now, is this an actual bug with gcc, or is it us who do not understand
how to communicate to gcc the fact that the asm() calls rely on the
stack?
Sincerely,
--
Lars Balker Rasmussen, Software Engineer, Mjolner Informatics ApS
lbr@mjolner.dk