https://gcc.gnu.org/bugzilla/show_bug.cgi?id=112600
Bug ID: 112600 Summary: Failed to optimize saturating addition using __builtin_add_overflow Product: gcc Version: 14.0 Status: UNCONFIRMED Keywords: missed-optimization Severity: normal Priority: P3 Component: middle-end Assignee: unassigned at gcc dot gnu.org Reporter: redi at gcc dot gnu.org Target Milestone: --- These two implementations of C++26 saturating addition (std::add_sat<unsigned>) have equivalent behaviour: unsigned add_sat(unsigned x, unsigned y) noexcept { unsigned z; if (!__builtin_add_overflow(x, y, &z)) return z; return -1u; } unsigned add_sat2(unsigned x, unsigned y) noexcept { unsigned res; res = x + y; res |= -(res < x); return res; } For -O3 on x86_64 GCC uses a branch for the first one: add_sat(unsigned int, unsigned int): add edi, esi jc .L3 mov eax, edi ret .L3: or eax, -1 ret For the second one we get better code: add_sat2(unsigned int, unsigned int): add edi, esi sbb eax, eax or eax, edi ret Clang compiles them both to the same code: add_sat(unsigned int, unsigned int): add edi, esi mov eax, -1 cmovae eax, edi ret