* Interesting regression in parameter passing (x86_64)
@ 2021-02-14 11:38 Stefan Ring
2021-02-15 22:43 ` Segher Boessenkool
0 siblings, 1 reply; 3+ messages in thread
From: Stefan Ring @ 2021-02-14 11:38 UTC (permalink / raw)
To: gcc-help
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?
^ permalink raw reply [flat|nested] 3+ messages in thread
* Re: Interesting regression in parameter passing (x86_64)
2021-02-14 11:38 Interesting regression in parameter passing (x86_64) Stefan Ring
@ 2021-02-15 22:43 ` Segher Boessenkool
2021-03-10 22:38 ` Stefan Ring
0 siblings, 1 reply; 3+ messages in thread
From: Segher Boessenkool @ 2021-02-15 22:43 UTC (permalink / raw)
To: Stefan Ring; +Cc: gcc-help
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
^ permalink raw reply [flat|nested] 3+ messages in thread
end of thread, other threads:[~2021-03-10 22:39 UTC | newest]
Thread overview: 3+ messages (download: mbox.gz / follow: Atom feed)
-- links below jump to the message on this page --
2021-02-14 11:38 Interesting regression in parameter passing (x86_64) Stefan Ring
2021-02-15 22:43 ` Segher Boessenkool
2021-03-10 22:38 ` Stefan Ring
This is a public inbox, see mirroring instructions
for how to clone and mirror all data and code used for this inbox;
as well as URLs for read-only IMAP folder(s) and NNTP newsgroup(s).