RISC-V: Fix Zbkb single-bit IOR/XOR synthesis [PR124818]

Message ID 20260408165426.4154722-1-christoph.muellner@vrull.eu
State New
Headers
Series RISC-V: Fix Zbkb single-bit IOR/XOR synthesis [PR124818] |

Checks

Context Check Description
linaro-tcwg-bot/tcwg_gcc_build--master-aarch64 fail Patch failed to apply
linaro-tcwg-bot/tcwg_gcc_build--master-arm fail Patch failed to apply
rivoscibot/toolchain-ci-rivos-apply-patch success Patch applied
rivoscibot/toolchain-ci-rivos-lint success Lint passed
rivoscibot/toolchain-ci-rivos-build--newlib-rv64gcv-lp64d-multilib success Build passed
rivoscibot/toolchain-ci-rivos-build--linux-rv64gcv-lp64d-multilib success Build passed
rivoscibot/toolchain-ci-rivos-build--linux-rv64gc_zba_zbb_zbc_zbs-lp64d-multilib success Build passed
rivoscibot/toolchain-ci-rivos-test success Testing passed

Commit Message

Christoph Müllner April 8, 2026, 4:54 p.m. UTC
  Only Zbs provides the bseti/binvi support that can directly handle a
large single-bit immediate in scalar IOR/XOR operations.  Zbkb alone
does not, but synthesize_ior_xor treated Zbkb as sufficient and
returned false for such constants.

On RV32 with -march=rv32gc_zbkb this leaves an unmatchable
(ior:SI reg (const_int 0x20000)) RTL insn, which later triggers an ICE
in extract_insn during virtual register instantiation.

Restrict the single-bit fast path to Zbs and add an RV32 Zbkb
regression test for the reduced reproducer.

	PR target/124818

gcc/ChangeLog:

	* config/riscv/riscv.cc (synthesize_ior_xor): Do not treat
	TARGET_ZBKB as sufficient for single-bit immediate IOR/XOR.

gcc/testsuite/ChangeLog:

	* gcc.target/riscv/pr124818.c: New test.

Signed-off-by: Christoph Müllner <christoph.muellner@vrull.eu>
---
 gcc/config/riscv/riscv.cc                 | 2 +-
 gcc/testsuite/gcc.target/riscv/pr124818.c | 9 +++++++++
 2 files changed, 10 insertions(+), 1 deletion(-)
 create mode 100644 gcc/testsuite/gcc.target/riscv/pr124818.c
  

Comments

Jeffrey Law April 9, 2026, 3:21 a.m. UTC | #1
On 4/8/2026 10:54 AM, Christoph Müllner wrote:
> Only Zbs provides the bseti/binvi support that can directly handle a
> large single-bit immediate in scalar IOR/XOR operations.  Zbkb alone
> does not, but synthesize_ior_xor treated Zbkb as sufficient and
> returned false for such constants.
>
> On RV32 with -march=rv32gc_zbkb this leaves an unmatchable
> (ior:SI reg (const_int 0x20000)) RTL insn, which later triggers an ICE
> in extract_insn during virtual register instantiation.
>
> Restrict the single-bit fast path to Zbs and add an RV32 Zbkb
> regression test for the reduced reproducer.
>
> 	PR target/124818
>
> gcc/ChangeLog:
>
> 	* config/riscv/riscv.cc (synthesize_ior_xor): Do not treat
> 	TARGET_ZBKB as sufficient for single-bit immediate IOR/XOR.
>
> gcc/testsuite/ChangeLog:
>
> 	* gcc.target/riscv/pr124818.c: New test.
This is almost certainly a 16 regression.  OK for the trunk.

Jeff
  

Patch

diff --git a/gcc/config/riscv/riscv.cc b/gcc/config/riscv/riscv.cc
index a6106547757..b743d3533f2 100644
--- a/gcc/config/riscv/riscv.cc
+++ b/gcc/config/riscv/riscv.cc
@@ -15919,7 +15919,7 @@  synthesize_ior_xor (rtx_code code, rtx operands[3])
 {
   /* Trivial cases that don't need synthesis.  */
   if (SMALL_OPERAND (INTVAL (operands[2]))
-     || ((TARGET_ZBS || TARGET_ZBKB)
+     || (TARGET_ZBS
 	 && single_bit_mask_operand (operands[2], word_mode)))
     return false;
 
diff --git a/gcc/testsuite/gcc.target/riscv/pr124818.c b/gcc/testsuite/gcc.target/riscv/pr124818.c
new file mode 100644
index 00000000000..a629e8e96a2
--- /dev/null
+++ b/gcc/testsuite/gcc.target/riscv/pr124818.c
@@ -0,0 +1,9 @@ 
+/* { dg-do compile { target { riscv32*-*-* } } } */
+/* { dg-options "-O2 -march=rv32gc_zbkb -mabi=ilp32" } */
+
+int
+f (unsigned int *flags)
+{
+  *flags |= 0x20000U;
+  return 1;
+}