* GCC plays "Shell Game", but looses track of the shell covering the nought
@ 2023-05-27 16:23 Stefan Kanthak
[not found] ` <20230527113728.26edde9fb121c8c310413fbb@killthe.net>
0 siblings, 1 reply; 2+ messages in thread
From: Stefan Kanthak @ 2023-05-27 16:23 UTC (permalink / raw)
To: gcc
--- demo.c ---
int ispowerof2(unsigned long long argument) {
return (argument != 0) && ((argument & argument - 1) == 0);
}
--- EOF ---
GCC 12.2 gcc -m32 -O3
https://gcc.godbolt.org/z/YWP4zb8jd
ispowerof2(unsigned long long):
push edi # three registers clobbered
push esi # without need, and three
push ebx # superfluous memory writes
mov edi, DWORD PTR [esp+20] -> mov ecx, [esp+4]
mov esi, DWORD PTR [esp+16] -> mov edx, [esp+8]
mov eax, edi -> mov eax, ecx
or eax, esi -> or eax, edx
je .L5 -> jz .L0
mov eax, esi # superfluous
mov edx, edi # superfluous
add eax, -1 -> add ecx, -1
adc edx, -1 -> adc edx, -1
mov ecx, eax # shell game
mov eax, esi # shell game
mov ebx, edx # shell game
mov edx, edi # shell game
and eax, ecx -> and ecx, [esp+4]
xor ecx, ecx -> xor eax, eax
and edx, ebx -> and edx, [esp+8]
pop ebx # superfluous
pop esi # superfluous
or eax, edx -> or ecx, edx
pop edi # superfluous
sete cl -> setz al
mov eax, ecx # shell game
ret .L0: -> ret
.L5: # eax is 0 here!
xor ecx, ecx # superfluous
pop ebx # superfluous
pop esi # superfluous
mov eax, ecx # superfluous
pop edi # superfluous
ret # superfluous
OUCH: 19 (in words: NINETEEN) superfluous instructions out of 32, despite -O3,
3 registers clobbered without need and reason, resulting in
3 superfluous memory writes
GCC 12.3 generates the same BRAINDEAD code!
GCC 13.3 gcc -m32 -O3
https://gcc.godbolt.org/z/Ge7q4Tv9M
ispowerof2(unsigned long long):
push esi # two registers clobbered without need,
push ebx # two superfluous memory writes
mov ecx, DWORD PTR [esp+12] -> mov ecx, [esp+4]
mov ebx, DWORD PTR [esp+16] -> mov edx, [esp+8]
mov eax, ecx -> mov eax, ecx
or eax, ebx -> or eax, edx
je .L5 -> jz .L0
xor eax, eax
mov eax, ecx # superfluous
mov edx, ebx # superfluous
add eax, -1 -> add ecx, -1
adc edx, -1 -> adc edx, -1
and eax, ecx -> and ecx, [esp+4]
and edx, ebx -> and edx, [esp+8]
pop ebx # superfluous
or eax, edx -> or ecx, edx
sete al -> setz al
movzx eax, al # superfluous: see xor added above
mov esi, eax # shell game
mov eax, esi # shell game
pop esi # superfluous
ret .L0: -> ret
.L5: # eax is 0 here!
xor esi, esi # superfluous
pop ebx # superfluous
mov eax, esi # superfluous
pop esi # superfluous
ret # superfluous
OUCH: 13 (in words: THIRTEEN) superfluous instructions out of 26, despite -O3,
2 registers clobbered without need and reason, resulting in
2 superfluous memory writes
It's e REAL shame how bad GCC's code generator is!
Stefan
^ permalink raw reply [flat|nested] 2+ messages in thread
* Re: GCC plays "Shell Game", but looses track of the shell covering the nought
[not found] ` <20230527113728.26edde9fb121c8c310413fbb@killthe.net>
@ 2023-05-27 17:00 ` Stefan Kanthak
0 siblings, 0 replies; 2+ messages in thread
From: Stefan Kanthak @ 2023-05-27 17:00 UTC (permalink / raw)
To: Dave Blanchard; +Cc: gcc
"Dave Blanchard" <dave@killthe.net> wrote:
> Hi Stefan, thanks for sharing this information.
> I was wondering if the code generators in earlier GCC
> versions were any better?
Just open one of the URLs I included, select another GCC version
and see the resulting code.
> Is this a problem in GCC 12+ only?
NO! GCC's code generator REALLY sucks, especially when "double word"
operations are involved.
GCC 6.* generates the following "gem":
.L5: # eax is already 0 here!
xor eax, eax
movzx eax, al
pop ebx
pop esi
ret
GCC 7.* is even worse, it clobbers FOUR registers.
GCC 8.* and 9.* uses/clobbers just one additional register.
GCC 10.* generates the same code as GCC 13.1 with "only" 13 superfluous
instructions (from a total of 26).
GCC 11.* shows the same behaviour with 19 superfluous instructions as 12.*
Also note the difference to yesterdays demo.c: "thanks" to the added
| (argument != 0)
GCC does NOT generate SSE2 instructions any more.
I don't know yet whether this change is a quirk or WTF,
Stefan
> Dave
>
>
> On Sat, 27 May 2023 18:23:12 +0200
> "Stefan Kanthak" <stefan.kanthak@nexgo.de> wrote:
>
>> [...]
>> It's a REAL shame how bad GCC's code generator is!
>>
>> Stefan
^ permalink raw reply [flat|nested] 2+ messages in thread
end of thread, other threads:[~2023-05-27 17:08 UTC | newest]
Thread overview: 2+ messages (download: mbox.gz / follow: Atom feed)
-- links below jump to the message on this page --
2023-05-27 16:23 GCC plays "Shell Game", but looses track of the shell covering the nought Stefan Kanthak
[not found] ` <20230527113728.26edde9fb121c8c310413fbb@killthe.net>
2023-05-27 17:00 ` Stefan Kanthak
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).