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