https://gcc.gnu.org/bugzilla/show_bug.cgi?id=119830
Bug ID: 119830
Summary: RISC-V:Internal Compiler Error on RISC-V Windows
Toolchain (32-bit program) with -march=rv64gc_zbb_zbs
Product: gcc
Version: 14.2.1
Status: UNCONFIRMED
Severity: normal
Priority: P3
Component: c
Assignee: unassigned at gcc dot gnu.org
Reporter: bigmagicreadsun at gmail dot com
Target Milestone: ---
Description:
When compiling the following code using a RISC-V Windows toolchain (32-bit
program) with -march=rv64gc_zbb_zbs -mabi=lp64d -O3, an internal compiler error
occurs:
<C>
#include <stdint.h>
void test(int32_t N, int16_t* A, int16_t val) {
int32_t i, j;
for (i = 0; i < N; i++) {
for (j = 0; j < N; j++) {
A[i * N + j] += val;
}
}
}
Command & Error:
<BASH>
riscv64-unknown-elf-gcc.exe -Ofast -march=rv64gc_zbb_zbs -mabi=lp64d -c .\xxx.c
-fdump-rtl-all -freport-bug
.\xxx.c: In function 'test':
.\xxx.c:10:1: error: unrecognizable insn:
(insn 264 263 265 28 (set (reg:DI 419)
(and:DI (reg:DI 421)
(const_int 2147483647 [0x7fffffff]))) -1
(expr_list:REG_EQUAL (const_int -4294901761 [0xffffffff0000ffff])
(nil)))
during RTL pass: vregs
xxx.c.267r.vregs
internal compiler error: in extract_insn, at recog.cc:2812
Additional Context:
Comparing the RISC-V Linux toolchain’s RTL dump (Godbolt
link:https://godbolt.org/z/rcooKfc1n), the correct insn uses the bclridi
template:
<LISP>
(insn 329 328 330 28 (set (reg:DI 413)
(and:DI (reg:DI 415)
(const_int -2147483649 [0xffffffff7fffffff]))) 630 {*bclridi}
(expr_list:REG_EQUAL (const_int -4294901761 [0xffffffff0000ffff])...))
The Windows toolchain produces a mismatched insn:
<LISP>
(insn 264 [...] (const_int 2147483647 [0x7fffffff]))) ; Not matching bclridi
The discrepancy in the generated and constant (2147483647 vs. -2147483649)
causes failure to match the bclridi pattern, triggering the ICE.
Question: Why does the Windows toolchain generate inconsistent RTL patterns
compared to Linux for the bclridi instruction template?
Compiler Version: riscv64-unknown-elf-gcc 14.2.1
Reproduction Steps:
Compile the code with -march=rv64gc_zbb_zbs -mabi=lp64d -O3.
Observe RTL differences in the vregs pass.
This includes all critical details and allows GCC developers to investigate
architecture-specific code generation differences. Let me know if you need
further adjustments.