https://gcc.gnu.org/bugzilla/show_bug.cgi?id=112600
--- Comment #2 from Jonathan Wakely <redi at gcc dot gnu.org> --- For similar saturating subtraction functions: unsigned sub_sat(unsigned x, unsigned y) noexcept { unsigned z; if (!__builtin_sub_overflow(x, y, &z)) return z; return 0; } unsigned sub_sat2(unsigned x, unsigned y) noexcept { unsigned res; res = x - y; res &= -(res <= x);; return res; } GCC x86_64 gives: sub_sat(unsigned int, unsigned int): sub edi, esi jb .L3 mov eax, edi ret .L3: xor eax, eax ret sub_sat2(unsigned int, unsigned int): sub edi, esi mov eax, 0 cmovnb eax, edi ret GCC aarch64 gives: sub_sat(unsigned int, unsigned int): subs w2, w0, w1 mov w3, 0 cmp w0, w1 csel w0, w2, w3, cs ret sub_sat2(unsigned int, unsigned int): subs w0, w0, w1 csel w0, w0, wzr, cs ret Clang x86_64 gives: sub_sat(unsigned int, unsigned int): xor eax, eax sub edi, esi cmovae eax, edi ret sub_sat2(unsigned int, unsigned int): xor eax, eax sub edi, esi cmovae eax, edi ret