https://gcc.gnu.org/bugzilla/show_bug.cgi?id=124630
Bug ID: 124630
Summary: popcnt (a ^ (a - 1)) -1 is ctz when a is known
non-zero
Product: gcc
Version: 16.0
Status: UNCONFIRMED
Severity: normal
Priority: P3
Component: middle-end
Assignee: unassigned at gcc dot gnu.org
Reporter: liuhongt at gcc dot gnu.org
Target Milestone: ---
unsigned foo (unsigned a)
{
if (a != 0)
return __builtin_popcount (a ^ (a - 1)) - 1;
else
return 32;
}
it can be optimized to tzcnt for x86.
foo:
.LFB0:
.cfi_startproc
tzcntl %edi, %eax
ret
Currently, it generates blsmsk + popnct + sub with -march=x86-64-v3 -O2
foo(unsigned int):
blsmsk %edi, %eax
movl $32, %edx
popcntl %eax, %eax
subl $1, %eax
testl %edi, %edi
cmove %edx, %eax
ret