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

Reply via email to