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

Reply via email to