https://gcc.gnu.org/bugzilla/show_bug.cgi?id=88916

--- Comment #3 from Wojciech Mula <wojciech_mula at poczta dot onet.pl> ---
A similar case:

---sign.c---
int different_sign(long a, long b) {
    return (a >= 0 && b < 0) || (a < 0 && b >= 0);
}
---eof--

This is compiled into:

different_sign:
        notq    %rdi
        movq    %rdi, %rax
        notq    %rsi
        shrq    $63, %rax
        shrq    $63, %rsi
        xorl    %esi, %eax
        movzbl  %al, %eax
        ret

When expressed as difference of the sign bits

    ((unsigned long)a ^ (unsigned long)b) >> 63

the code is way shorter:

different_sign:
    xorq        %rsi, %rdi
    movq        %rdi, %rax
    shrq        $63, %rax

BTW, I looked at ARM assembly, and GCC also emits
two shifts, so the observed behaviour is not limited
by a target.

Reply via email to