Hi! On Sun, Feb 14, 2021 at 12:38:26PM +0100, Stefan Ring via Gcc-help wrote: > I recently noticed that gcc 9 introduced a strange push/pop pair in a > function that does nothing other than shift all arguments by one > position and transfer control to another function: > > int func(int, int, int, int, int, int); > int caller(int a, int b, int c, int d, int e) { return func(0, a, b, c, d, e); } > > pushq %r12 > movl %r8d, %r9d > popq %r12 > movl %ecx, %r8d > movl %edx, %ecx > movl %esi, %edx > movl %edi, %esi > xorl %edi, %edi > jmp func > > Obviously, pushing and popping r12 serves no useful purpose, and gcc 8 > does not produce it. It also disappears when a is used instead of the > constant 0 as the first argument. Where does this come from? The pop was emitted right before the jump, but it was moved to earlier by the instruction scheduled (sched2). The prologue/epilogue push and pop r12 because that is a non-volatile ("callee-saved") register. At the point the prologue and expilogue code is generated r12 is used in the code, to shuffle these registers through. It is essentially r10 := edi r11 := esi r12 := edx r9 := r8 r8 := ecx ecx := r12 edx := r11 esi := r10 edi := 0 which then by cprop_hardreg is simplified to r9 := r8 r8 := ecx ecx := edx edx := esi esi := edi edi := 0 but by then it is too late to omit the push and pop. Please open a PR (see https://gcc.gnu.org/bugs.html for how). Thanks! Segher