https://gcc.gnu.org/bugzilla/show_bug.cgi?id=87627
Bug ID: 87627 Summary: GCC generates rube-goldberg machine for trivial tail call on 32-bit x86 Product: gcc Version: unknown Status: UNCONFIRMED Severity: normal Priority: P3 Component: target Assignee: unassigned at gcc dot gnu.org Reporter: bugdal at aerifal dot cx Target Milestone: --- Simple test case: extern void bar(); extern void bah(int, int, int); void foo(int a, int b, int c) { bar(); bah(a, b, c); } Expected output: subl $12, %esp call bar addl $12, %esp jmp bah Actual: pushl %edi pushl %esi pushl %ebx movl 16(%esp), %ebx movl 20(%esp), %esi movl 24(%esp), %edi call bar movl %edi, 24(%esp) movl %esi, 20(%esp) movl %ebx, 16(%esp) popl %ebx popl %esi popl %edi jmp bah I'm not clear on whether GCC is unaware that the argument space belongs to the callee and is preserved across calls, or whether it somehow thinks using call-saved registers is more optimal in typical cases and is missing the trivial reason why it's not here.