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.