Compiling this code: int f(); void g(); void t() { if (f()) g(); } with gcc -Os -fomit-frame-pointer -S t.c produces: .file "t.c" .text .globl t .type t, @function t: subl $12, %esp call f testl %eax, %eax je .L4 addl $12, %esp jmp g .L4: addl $12, %esp ret .size t, .-t .ident "GCC: (GNU) 4.2.1" .section .note.GNU-stack,"",@progbits subl/addl $12, %esp seem to be completely pointless to me here.
>subl/addl $12, %esp seem to be completely pointless to me here. It is needed to call f.
Well, gcc 3.4.3 disagrees with you: # gcc -Os -fomit-frame-pointer -S t.c # cat t.s .file "t.c" .text .globl t .type t, @function t: call f testl %eax, %eax je .L1 jmp g .L1: ret .size t, .-t .section .note.GNU-stack,"",@progbits .ident "GCC: (GNU) 3.4.3"
That is a known bug in GCC 3.4.3, causing the SSE code in f() to segfault.
I am confused... How does reserving 12 bytes on stack can help to prevent a segfault? I can imagine how aligning the stack can help, but here gcc 4.2.1 does something diffrent. Maybe just throw an URL to more info about segfault of gcc 3.4.3-produced code at me.
The point is exactly to align the stack. The call instruction decrements %esp by 4 bytes, so GCC has to decrement %esp by another 12 bytes to keep the stack aligned. See also bug target/13685.
Oh *shit*. I see. Why, oh why you didn't go for aligning stack in fuctions which decided they need to use instructions which require alignment? And ONLY that functions? Why everyone needs to pay this tax now? Oh well...
I want to apologise. Apparently this behavior (16-byte stack alignment) can be turned off with an option => I can still have just word-aligned stack. As long as that still works, I am a more-or-less happy camper. Sorry guys.
You can use -mpreferred-stack-boundary=2 to disable this feature if you know you're never going to need the additional stack alignment. The compiler has know way of knowing whet the rest of your application does, so has to make conservative assumptions. If 16-byte alignment is needed anywhere then all functions must preserve that alignment. Dynamic stack realignment is sufficiently expensive that it's much better to not allow the stack to get misaligned in the first place.