https://gcc.gnu.org/bugzilla/show_bug.cgi?id=95669
Bug ID: 95669
Summary: -O3 generates more complicated code to return 8-byte
struct of zeros, sometimes
Product: gcc
Version: 10.1.0
Status: UNCONFIRMED
Severity: normal
Priority: P3
Component: c++
Assignee: unassigned at gcc dot gnu.org
Reporter: jzwinck at gmail dot com
Target Milestone: ---
Consider this C++ code:
struct res
{
int val;
bool ok;
bool dummy;
};
res fun(int a, int b)
{
if (a < b)
return {0, false};
return {a * b, true};
}
10.1 (or 8.x) with -O2 or -O3 on x86_64 looks good:
cmp edi, esi ; a < b
jge .L2
xor eax, eax ; {0, false}
ret
.L2:
imul edi, esi ; a * b
mov rax, rdi
bts rax, 32 ; ok = true
ret
But if you remove "dummy" and compile with -O3, it looks worse:
cmp edi, esi ; a < b
jl .L3
imul edi, esi ; a * b
mov esi, 1 ; ok = true
sal rsi, 32
mov eax, edi
or rax, rsi
ret
.L3:
xor esi, esi
xor edi, edi
mov eax, edi
sal rsi, 32
or rax, rsi
ret
Both branch cases are longer, but especially strange is how .L3 uses five
instructions instead of "xor eax, eax".
Similar happens in every version I tried except for 4.5 and 4.6.
Live demo: https://godbolt.org/z/4Lisy6