]> git.ipfire.org Git - thirdparty/gcc.git/commit
[to-be-committed,v2,RISC-V] Use bclri in constant synthesis
authorJeff Law <jlaw@ventanamicro.com>
Fri, 24 May 2024 13:27:00 +0000 (07:27 -0600)
committerJeff Law <jlaw@ventanamicro.com>
Fri, 24 May 2024 13:27:00 +0000 (07:27 -0600)
commit401994d60ab38ffa9e63f368f0456eb7b08599be
tree9f738349a869c46181b0764b16b894f5c09c01a0
parenta0fe4fb1c8d7804515845dd5d2a814b3c7a1ccba
[to-be-committed,v2,RISC-V] Use bclri in constant synthesis

Testing with Zbs enabled by default showed a minor logic error.  After
the loop clearing things with bclri, we can only use the sequence if we
were able to clear all the necessary bits.  If any bits are still on,
then the bclr sequence turned out to not be profitable.

--

So this is conceptually similar to how we handled direct generation of
bseti for constant synthesis, but this time for bclr.

In the bclr case, we already have an expander for AND.  So we just
needed to adjust the predicate to accept another class of constant
operands (those with a single bit clear).

With that in place constant synthesis is adjusted so that it counts the
number of bits clear in the high 33 bits of a 64bit word.  If that
number is small relative to the current best cost, then we try to
generate the constant with a lui based sequence for the low half which
implicitly sets the upper 32 bits as well.  Then we bclri one or more of
those upper 33 bits.

So as an example, this code goes from 4 instructions down to 3:

 > unsigned long foo_0xfffffffbfffff7ff(void) { return
0xfffffffbfffff7ffUL; }

Note the use of 33 bits above.  That's meant to capture cases like this:

 > unsigned long foo_0xfffdffff7ffff7ff(void) { return
0xfffdffff7ffff7ffUL; }

We can use lui+addi+bclri+bclri to synthesize that in 4 instructions
instead of 5.

I'm including a handful of cases covering the two basic ideas above that
were found by the testing code.

And, no, we're not done yet.  I see at least one more notable idiom
missing before exploring zbkb's potential to improve things.

Tested in my tester and waiting on Rivos CI system before moving forward.
gcc/

* config/riscv/predicates.md (arith_operand_or_mode_mask): Renamed to..
(arith_or_mode_mask_or_zbs_operand): New predicate.
* config/riscv/riscv.md (and<mode>3): Update predicate for operand 2.
* config/riscv/riscv.cc (riscv_build_integer_1): Use bclri to clear
bits, particularly bits 31..63 when profitable to do so.

gcc/testsuite/

* gcc.target/riscv/synthesis-6.c: New test.
gcc/config/riscv/predicates.md
gcc/config/riscv/riscv.cc
gcc/config/riscv/riscv.md
gcc/testsuite/gcc.target/riscv/synthesis-6.c [new file with mode: 0644]