https://gcc.gnu.org/bugzilla/show_bug.cgi?id=91213
Bug ID: 91213
Summary: Missed optimization: (sub X Y) -> (xor X Y) when Y <=
X and isPowerOf2(X + 1)
Product: gcc
Version: 10.0
Status: UNCONFIRMED
Severity: normal
Priority: P3
Component: tree-optimization
Assignee: unassigned at gcc dot gnu.org
Reporter: nok.raven at gmail dot com
Target Milestone: ---
Proof https://rise4fun.com/Alive/Xr3
unsigned foo(unsigned x)
{
if (x > 31) __builtin_unreachable();
return 31 - x;
}
unsigned bar(unsigned x)
{
if (x > 63) __builtin_unreachable();
return 63 - x;
}
The optimization seems to be manually applied to __builtin_clz, and because
GCC cannot reverse it or apply again the:
unsigned bsrl(unsigned x)
{
return 31 - __builtin_clz(x);
}
becomes (sub 31 (xor 31 (bsr x))):
bsrl(unsigned int):
bsrl %edi, %edi
movl $31, %eax
xorl $31, %edi
subl %edi, %eax
ret
https://godbolt.org/z/3nzi0z