Re: Interesting regression in parameter passing (x86_64)

[Date Prev][Date Next][Thread Prev][Thread Next][Date Index][Thread Index]

 



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



[Index of Archives]     [Linux C Programming]     [Linux Kernel]     [eCos]     [Fedora Development]     [Fedora Announce]     [Autoconf]     [The DWARVES Debugging Tools]     [Yosemite Campsites]     [Yosemite News]     [Linux GCC]

  Powered by Linux