https://gcc.gnu.org/bugzilla/show_bug.cgi?id=105136
Bug ID: 105136
Summary: [11/12] Missed optimization regression with 32-bit
adds and shifts
Product: gcc
Version: 12.0
Status: UNCONFIRMED
Severity: normal
Priority: P3
Component: middle-end
Assignee: unassigned at gcc dot gnu.org
Reporter: andre.schackier at gmail dot com
Target Milestone: ---
Given the following source code [godbolt](https://godbolt.org/z/daTxMYWKo)
#include <stdint.h>
int32_t foo(int64_t a, int32_t b, int cond) {
if (cond) {
a += ((int64_t)b) << 32;
}
return a >> 32;
}
int32_t bar(int64_t a, int32_t b, int cond) {
int32_t r = a >> 32;
if (cond) {
r += b;
}
return r;
}
and compiling with "-O3" we get the following assembly:
foo:
sal rsi, 32
mov rax, rdi
add rax, rsi
test edx, edx
cmove rax, rdi
shr rax, 32
ret
bar:
sar rdi, 32
add esi, edi
test edx, edx
mov eax, esi
cmove eax, edi
ret
With gcc-10.3 we get for bar:
bar:
sar rdi, 32
test edx, edx
lea eax, [rsi+rdi]
cmove eax, edi
ret
Also note that neither versions recognize that foo does the same as bar.
Credits: This was entirely found by Trevor Spiteri reported at the llvm-project
here: https://github.com/llvm/llvm-project/issues/54718