https://gcc.gnu.org/bugzilla/show_bug.cgi?id=101175

            Bug ID: 101175
           Summary: builtin_clz generates wrong bsr instruction
           Product: gcc
           Version: 11.1.0
            Status: UNCONFIRMED
          Severity: normal
          Priority: P3
         Component: target
          Assignee: unassigned at gcc dot gnu.org
          Reporter: mytbk920423 at gmail dot com
  Target Milestone: ---

Built with '-march=x86-64-v3 -O1', the following code generates a bsr
instruction, which has undefined behavior when the source operand is zero, thus
gives wrong result (code also in https://gcc.godbolt.org/z/zzT7x57MT):

static inline int test_clz32(uint32_t value)
{
        if (value != 0) {
                return __builtin_clz(value);
        } else {
                return 32;
        }
}

/* returns -1 if x == 0 */
int firstone(uint32_t x)
{
        return 31 - test_clz32(x);
}

The result assembly:

firstone:
        bsr     eax, edi
        ret

Note that the lzcnt instruction has a defined behavior to return the operand
size when operand is zero.

Reply via email to