Description
bool test1(unsigned n) {
__builtin_assume(n);
return __builtin_popcount(n) == 1;
}
bool test2(unsigned n) {
__builtin_assume(n);
return (n != 0) && ((n & (n-1u)) == 0);
}
Where test1
looks like libstdc++'s std::has_single_bit
and test2
looks like libc++'s std::has_single_bit
.
These are optimized differently with the non-zero assumption: https://godbolt.org/z/b8jTae91x
test1: # @test1
popcnt eax, edi
cmp eax, 1
sete al
ret
test2: # @test2
blsr eax, edi
sete al
ret
(without the assumption, they are both optimized to use popcnt
)
return __builtin_popcount(n) <= 1;
is optimized to blsr