https://gcc.gnu.org/bugzilla/show_bug.cgi?id=106786
Bug ID: 106786 Summary: Regression in cmp+sbb Product: gcc Version: 12.2.0 Status: UNCONFIRMED Severity: normal Priority: P3 Component: tree-optimization Assignee: unassigned at gcc dot gnu.org Reporter: chfast at gmail dot com Target Milestone: --- I noticed a regression when using the builtin for sbb instruction (__builtin_ia32_sbb_u64). typedef unsigned long long u64; struct R { u64 value; bool carry; }; inline R subc(u64 x, u64 y, bool carry) noexcept { u64 d; const u64 carryout = __builtin_ia32_sbb_u64(carry, x, y, &d); return {d, carryout != 0}; } bool bad(u64 x, u64 y) { const R z = subc(x, y, false); R a = subc(x, y, z.carry); return a.carry; } https://godbolt.org/z/f41KKe19q The expected assembly is cmp rdi, rsi sbb rdi, rsi But GCC 12.2.0 and trunk produces cmp rdi, rsi setb al movzx eax, al add al, -1 sbb rdi, rsi The regression is in 12.2.0, the 11.3.0 optimizes properly. There are simple changes which will bring back the expected optimization: - change `const R z` to `R z`, - change `bool carry` to `u64 carry`. This may be related to calling convention / ABI because I noticed in one of the tree optimization outputs for 12.2.0 that the `bool carry` is forced to be in memory: `MEM <unsigned char> [(struct R *)&z + 8B]`. https://godbolt.org/z/7zh7GxraK