This is the mail archive of the
gcc-bugs@gcc.gnu.org
mailing list for the GCC project.
[Bug target/35271] Stack not aligned at mod 16 byte boundary in x86_64 code
- From: "matz at gcc dot gnu dot org" <gcc-bugzilla at gcc dot gnu dot org>
- To: gcc-bugs at gcc dot gnu dot org
- Date: 22 Feb 2008 23:40:46 -0000
- Subject: [Bug target/35271] Stack not aligned at mod 16 byte boundary in x86_64 code
- References: <bug-35271-9218@http.gcc.gnu.org/bugzilla/>
- Reply-to: gcc-bugzilla at gcc dot gnu dot org
------- Comment #8 from matz at gcc dot gnu dot org 2008-02-22 23:40 -------
I can confirm this, the code in foo is definitely wrong. When I compile
the (standard compliant, unlike the example from comment #4) with 4.2 or
4.3 on x86-64, with -O or -O2 it breaks:
% cat foo.c
long align;
int foo (int flag)
{
int variable;
if (flag == 0)
return 42;
align = (long)&variable;
return foo (flag - 1);
}
The asm code for foo():
foo:
subq $16, %rsp
testl %edi, %edi
movl $42, %eax
je .L4
leaq 12(%rsp), %rax
subl $1, %edi
movq %rax, align(%rip)
call foo
.L4:
addq $16, %rsp
ret
It's clear that this misaligns the stack for the next calls. On entry it's
8 mod 16, after the rsp adjustment it's still 8 mod 16, so in front of the
call it's also 8 mod 16, and boom. Just before calls %rsp needs to be
0 mod 16.
It seems to be important that this is a recursive call. This body does a
'sub $24', i.e. is correct:
int bar(int);
int foo (int flag)
{
int variable;
if (flag == 0)
return 42;
align = (long)&variable;
return bar (flag - 1);
}
The same is true, when I instead add a second call in the body (to bar()),
then the incoming argument is stored in %rbx, which needs saving, so there's
a push, and still a 'sub $16', i.e. again adjusting correctly.
--
matz at gcc dot gnu dot org changed:
What |Removed |Added
----------------------------------------------------------------------------
CC| |jh at suse dot cz, matz at
| |gcc dot gnu dot org
GCC target triplet|i386-apple-darwin8.11.1 |x86_64
http://gcc.gnu.org/bugzilla/show_bug.cgi?id=35271