Test code: #include <stdint.h>
struct u64x2_t { uint64_t u64a; uint64_t u64b; }; union u64_u { uint64_t u64; uint64_t *ptr_u64; }; struct u64x2_t multiple_stack_stores(struct u64x2_t in) { struct u64x2_t out; out.u64a=in.u64a+1; out.u64b=in.u64b; if ((out.u64a & 63)==0) { union u64_u u; u.u64=(out.u64a >> 6) << 3; out.u64b=u.ptr_u64[0]; } return out; } struct u64x2_t no_stack_stores(uint64_t u64a, uint64_t u64b) { struct u64x2_t out; out.u64a=u64a+1; out.u64b=u64b; if ((out.u64a & 63)==0) { union u64_u u; u.u64=(out.u64a >> 6) << 3; out.u64b=u.ptr_u64[0]; } return out; } int main() { return 0; } $ gcc-4.3 -O3 gcc-stack-stores-bug.c && objdump -d -m i386:x86-64:intel a.out generates in part: 0000000000400480 <multiple_stack_stores>: 400480: 48 8d 4f 01 lea rcx,[rdi+0x1] 400484: 48 89 7c 24 d8 mov QWORD PTR [rsp-0x28],rdi 400489: 48 89 74 24 e0 mov QWORD PTR [rsp-0x20],rsi 40048e: f6 c1 3f test cl,0x3f 400491: 75 0f jne 4004a2 <multiple_stack_stores+0x22> 400493: 48 89 c8 mov rax,rcx 400496: 48 c1 e8 06 shr rax,0x6 40049a: 48 8b 34 c5 00 00 00 mov rsi,QWORD PTR [rax*8+0x0] 4004a1: 00 4004a2: 48 89 f2 mov rdx,rsi 4004a5: 48 89 c8 mov rax,rcx 4004a8: c3 ret 4004a9: 0f 1f 80 00 00 00 00 nop DWORD PTR [rax+0x0] 00000000004004b0 <no_stack_stores>: 4004b0: 48 8d 4f 01 lea rcx,[rdi+0x1] 4004b4: f6 c1 3f test cl,0x3f 4004b7: 75 0f jne 4004c8 <no_stack_stores+0x18> 4004b9: 48 89 c8 mov rax,rcx 4004bc: 48 c1 e8 06 shr rax,0x6 4004c0: 48 8b 34 c5 00 00 00 mov rsi,QWORD PTR [rax*8+0x0] 4004c7: 00 4004c8: 48 89 f2 mov rdx,rsi 4004cb: 48 89 c8 mov rax,rcx 4004ce: c3 ret 4004cf: 90 nop With the better-designed x86-64 ABI this struct is passed and returned in registers. So why is gcc generating this code: 400484: 48 89 7c 24 d8 mov QWORD PTR [rsp-0x28],rdi 400489: 48 89 74 24 e0 mov QWORD PTR [rsp-0x20],rsi Similar output is observed with gcc-4.1, gcc-4.2 and gcc-snapshot (Debian 20090129-1) 4.4.0 20090129 (experimental) [trunk revision 143770] -- Summary: gcc generating multiple stack stores in optimised code Product: gcc Version: 4.3.3 Status: UNCONFIRMED Severity: normal Priority: P3 Component: c AssignedTo: unassigned at gcc dot gnu dot org ReportedBy: adam at consulting dot net dot nz GCC host triplet: Debian Linux GCC target triplet: x86-84 core2 http://gcc.gnu.org/bugzilla/show_bug.cgi?id=39102