unsigned long f1(unsigned long num) {
if (num % 5L == 0 && num % 3L == 0) { return 1000; }
return 0;
}
unsigned long f2(unsigned long num) {
if (num % 15L == 0) { return 1000; }
return 0;
}
Compiler result:
f1(unsigned long):
movabs rdx, -3689348814741910323
mov rax, rdi
mov rcx, rdi
mul rdx
mov rax, rdx
and rdx, -4
shr rax, 2
add rdx, rax
mov rax, rdi
sub rcx, rdx
movabs rdx, -6148914691236517205
mul rdx
mov rax, rdx
and rdx, -2
shr rax
add rdx, rax
sub rdi, rdx
or rdi, rcx
cmp rdi, 1
sbb rax, rax
and eax, 1000
ret
f2(unsigned long):
movabs rax, -1229782938247303441
imul rdi, rax
movabs rax, 1229782938247303441
cmp rax, rdi
sbb rax, rax
not rax
and eax, 1000
ret
tried GCC, msvc, clang, Java C2, C# JIT
I think num % 5 == 0 && num % 3 == 0 can be optimized into num % 15 == 0, but most compilers won't do it.
Is there any situations that will make these compare different or just no one just think about it?
by icebp: godbolt link