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

Jeffrey A. Law <law at gcc dot gnu.org> changed:

           What    |Removed                     |Added
----------------------------------------------------------------------------
         Resolution|---                         |FIXED
             Status|UNCONFIRMED                 |RESOLVED

--- Comment #4 from Jeffrey A. Law <law at gcc dot gnu.org> ---
So we've been keeping this open due to the interactions of andn with
mvconst_internal.  Essentially mvconst_internal makes it difficult to generate
andn consistently when there's a constant argument involved.

The recent changes to AND synthesis have helped in two meaningful ways.  First
and most important the undesirable value clamping from  riscv_const_insns is
has been avoided by using riscv_integer_cost instead.  Meaning we can reliably
compare constant synthesis costs and select between an AND vs ANDN sequence
reliably.

Second, the rotation patches help indirectly.  There were cases where we could
instead synthesize ~C and use ANDN, but synthesizing the operation through a
rotate+mask+rotate sequence is better.

I missed adding this PR to the commit.

commit af13bb056c65532fc4b3cecd06f51f82a7c70149
Author: Jeff Law <[email protected]>
Date:   Fri Jul 3 07:47:09 2026 -0600

    [RISC-V] Improve AND synthesis
    So a couple changes to AND synthesis.

    First much like the ADD, IOR/XOR cases we should be using
riscv_integer_cost
    rather than riscv_const_insns.  This results in improvement for the exact
same
    constants in the IOR/XOR case. This also introduces the ability to use
rotation
    to help AND synthesis.

    Let's consider x & 0xff000000000000ff.  It currently generates this:

            li      a5,-1
            slli    a5,a5,56
            addi    a5,a5,255
            and     a0,a0,a5

    The trick here is to realize we only have 16 bits that are relevant and the
can
    be clustered together.  So we rotate x right by 56 bit positions, then turn
off
    the high bits using zext.h then rotate 8 more positions to put the bits
back
    into the proper position.  That looks like this:

            rori    a0,a0,56
            zext.h  a0,a0
            rori    a0,a0,8

    We can also use zext.w and andi for the bit clearing step.

    Built and tested on riscv32-elf and riscv64-elf and bootstrapped +
regression
    tested on the c920 and k3.  Waiting on pre-commit CI before moving forward.

    gcc/
            * config/riscv/riscv.cc (and_synthesis): Use riscv_integer_cost
rather
            than riscv_const_insns.  Use rotate+clear_bits+rotate when useful.

    gcc/testsuite/
            * gcc.target/riscv/and-synthesis-3.c: New test.

Reply via email to