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.