https://gcc.gnu.org/bugzilla/show_bug.cgi?id=123905
Jeffrey A. Law <law at gcc dot gnu.org> changed:
What |Removed |Added
----------------------------------------------------------------------------
Keywords| |missed-optimization
Summary|Failure to optimize away |Failure to optimize away
|sign extension |sign extension on RISC-V
--- Comment #1 from Jeffrey A. Law <law at gcc dot gnu.org> ---
Ugh, think I hit a button too early. Compile these with -O2 -march=rv64gcbv
int foo1(unsigned a, unsigned b)
{
return __builtin_clz(a) & ~b;
}
int foo2(unsigned a, unsigned b)
{
return __builtin_ctz(a) & ~b;
}
int foo3(unsigned a, unsigned b)
{
return __builtin_popcount(a) & ~b;
}
You'll get something like:
foo1:
clzw a0,a0 # 8 [c=4 l=4] *clzsi2
andn a0,a0,a1 # 12 [c=4 l=4] and_notdi3
sext.w a0,a0 # 18 [c=4 l=4] *extendsidi2_internal/0
ret # 27 [c=0 l=4] simple_return
.size foo1, .-foo1
.align 1
.globl foo2
.type foo2, @function
foo2:
ctzw a0,a0 # 8 [c=4 l=4] *ctzsi2
andn a0,a0,a1 # 12 [c=4 l=4] and_notdi3
sext.w a0,a0 # 18 [c=4 l=4] *extendsidi2_internal/0
ret # 27 [c=0 l=4] simple_return
.size foo2, .-foo2
.align 1
.globl foo3
.type foo3, @function
foo3:
cpopw a0,a0 # 8 [c=4 l=4] *popcountsi2
andn a0,a0,a1 # 12 [c=4 l=4] and_notdi3
andi a0,a0,63 # 18 [c=4 l=4] *anddi3/1
ret # 27 [c=0 l=4] simple_return
Note the sext.w or trailing andi instruction. Those are all signs that we
failed to eliminate a zero/sign extension. I suspect this is opcodes not being
handled in num_sign_bit_copies, but I haven't verified that.