[to-be-committed][RISC-V] Generate nearby constant, then adjust to our final desired constant
Next step in constant synthesis work.
For some cases it can be advantageous to generate a constant near our target,
then do a final addi to fully synthesize C.
The idea is that while our target C may require N instructions to synthesize,
C' may only require N-2 (or fewer) instructions. Thus there's budget to adjust
C' into C ending up with a better sequence than if we tried to generate C
directly.
So as an example:
> unsigned long foo_0xfffff7fe7ffff7ff(void) { return 0xfffff7fe7ffff7ffUL; }
This is currently 5 instructions on the trunk:
> li a0,-4096
> addi a0,a0,2047
> bclri a0,a0,31
> bclri a0,a0,32
> bclri a0,a0,43
But we can do better by first synthesizing 0xfffff7fe7ffff800 which is just 3
instructions. Then we can subtract 1 from the result. That gives us this
sequence:
> li a0,-
16789504
> slli a0,a0,19
> addi a0,a0,-2048
> addi a0,a0,-1
These cases are relatively easy to find once you know what you're looking for.
I kept the full set found by the testing code yesterday, mostly because some of
them show different patterns for generating C', thus showing generality in the
overall synthesis implementation. While all these tests have 0x7ff in their
low bits. That's just an artifact to the test script. The methodology will
work for a variety of other cases.
gcc/
* config/riscv/riscv.cc (riscv_build_integer_1): Try generating
a nearby simpler constant, then using a final addi to set low
bits properly.
gcc/testsuite
* gcc.target/riscv/synthesis-7.c: New test.