RISC-V: Split "(a & (1UL << bitno)) ? 0 : -1" to bext + addi
authorPhilipp Tomsich <philipp.tomsich@vrull.eu>
Wed, 11 May 2022 11:50:11 +0000 (13:50 +0200)
committerPhilipp Tomsich <philipp.tomsich@vrull.eu>
Wed, 16 Nov 2022 19:31:17 +0000 (20:31 +0100)
commit32462550f2803aafb726b5ae20d4d95ce36dcd9c
treef687f33888770a4ec5c9144ae43d899b9e56fe98
parente91d51457532da6c2179b23359435f06d89488e7
RISC-V: Split "(a & (1UL << bitno)) ? 0 : -1" to bext + addi

For a straightforward application of bext for the following function
  long bext64(long a, char bitno)
  {
    return (a & (1UL << bitno)) ? 0 : -1;
  }
we generate
srl a0,a0,a1 # 7 [c=4 l=4]  lshrdi3
andi a0,a0,1 # 8 [c=4 l=4]  anddi3/1
addi a0,a0,-1 # 14 [c=4 l=4]  adddi3/1
due to the following failed match at combine time:
  (set (reg:DI 82)
       (zero_extract:DI (reg:DI 83)
            (const_int 1 [0x1])
            (reg:DI 84)))

The existing pattern for bext requires the 3rd argument to
zero_extract to be a QImode register wrapped in a zero_extension.
This adds an additional pattern that allows an Xmode argument.

With this change, the testcase compiles to
bext a0,a0,a1 # 8 [c=4 l=4]  *bextdi
addi a0,a0,-1 # 14 [c=4 l=4]  adddi3/1

gcc/ChangeLog:

* config/riscv/bitmanip.md (*bext<mode>): Add an additional
pattern that allows the 3rd argument to zero_extract to be
an Xmode register operand.

gcc/testsuite/ChangeLog:

* gcc.target/riscv/zbs-bext.c: Add testcases.
* gcc.target/riscv/zbs-bexti.c: Add testcases.
gcc/config/riscv/bitmanip.md
gcc/testsuite/gcc.target/riscv/zbs-bext.c
gcc/testsuite/gcc.target/riscv/zbs-bexti.c [new file with mode: 0644]