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.

Reply via email to