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.