https://gcc.gnu.org/g:0926932e390e8317354acc564dc5e16c9e861418
commit r16-8544-g0926932e390e8317354acc564dc5e16c9e861418 Author: Christoph Müllner <[email protected]> Date: Wed Apr 8 18:21:04 2026 +0200 RISC-V: Fix Zbkb single-bit IOR/XOR synthesis [PR124818] 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 <[email protected]> Diff: --- gcc/config/riscv/riscv.cc | 2 +- gcc/testsuite/gcc.target/riscv/pr124818.c | 9 +++++++++ 2 files changed, 10 insertions(+), 1 deletion(-) diff --git a/gcc/config/riscv/riscv.cc b/gcc/config/riscv/riscv.cc index 61d950055804..1ee1cf60407f 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 000000000000..a629e8e96a2d --- /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; +}
