[Bug target/121937] [16 Regression] RISC-V rv64gcv: crash at -O3 during RTL pass: combine
cvs-commit at gcc dot gnu.org
gcc-bugzilla@gcc.gnu.org
Fri Oct 3 14:43:23 GMT 2025
https://gcc.gnu.org/bugzilla/show_bug.cgi?id=121937
--- Comment #3 from GCC Commits <cvs-commit at gcc dot gnu.org> ---
The master branch has been updated by Jeff Law <law@gcc.gnu.org>:
https://gcc.gnu.org/g:f864e4b54a13420f37dc3710aeb9f8a6f9e63b9c
commit r16-4207-gf864e4b54a13420f37dc3710aeb9f8a6f9e63b9c
Author: Jeff Law <jlaw@ventanamicro.com>
Date: Fri Oct 3 08:41:53 2025 -0600
[RISC-V][PR rtl-optimization/121937] Don't call neg_poly_int_rtx with a
vector mode
Fun little bug.
We're asked to simplify this:
(vec_select:HI (if_then_else:V2HI (unspec:V2BI [
(const_vector:V2BI [
(const_int 0 [0])
(const_int 1 [0x1])
])
(const_int 2 [0x2])
(const_int 0 [0]) repeated x3
(reg:SI 66 vl)
(reg:SI 67 vtype)
] UNSPEC_VPREDICATE)
(const_vector:V2HI [
(const_int 0 [0])
(const_int -1 [0xffffffffffffffff])
])
(const_vector:V2HI [
(const_int -1 [0xffffffffffffffff])
(const_int 0 [0])
]))
(parallel [
(const_int 0 [0])
]))
That triggers some fairly obscure code in combine which realizes the arms
are
STORE_FLAG_VALUE computabble. So we ask for a simplified conditional of
the
condition against (const_int 0):
3610 return simplify_context ().simplify_gen_relational (code, mode,
op_mode,
(gdb) p debug_rtx (op0)
(unspec:V2BI [
(const_vector:V2BI [
(const_int 0 [0])
(const_int 1 [0x1])
])
(const_int 2 [0x2])
(const_int 0 [0]) repeated x3
(reg:SI 66 vl)
(reg:SI 67 vtype)
] UNSPEC_VPREDICATE)
$50 = void
(gdb) p debug_rtx (op1)
(const_int 0 [0])
CODE will be EQ. So that eventually we'll try that as a simplification
using
MINUS with those two operands.
That ultimately lands us in simplify_binary_operation_1 which (of course)
tries
to simplify x - 0 to x. But that fails because we test (const_int 0)
against
CONST0_RTX (V2BI) which, of course, false.
We then stumble down into this code:
/* Don't let a relocatable value get a negative coeff. */
if (poly_int_rtx_p (op1) && GET_MODE (op0) != VOIDmode)
return simplify_gen_binary (PLUS, mode,
op0,
neg_poly_int_rtx (mode, op1));
Where MODE is V2BI. That's not a scalar mode and we try to get the
precision
of V2BI in the bowels of neg_poly_int_rtx, which looks like:
return GET_MODE_PRECISION (as_a <scalar_mode> (x.second));
Where x.second is the mode, V2BI. Since V2BI is not a scalar mode it blows
up
as seen in the BZ.
The immediate and direct fix is to guard that code with a check that we've
got
a scalar mode.
I looked at passing a more suitable zero node as well as improving the
checks
to simplify x - 0 -> x for this case. While the RTL does simplify in the
expected ways, nothing really comes out of the RTL simplification (ie, the
final assembly code is the same). So I decided against including those
hacks
(they really didn't feel all that clean to me). There's just not a
compelling
reason for them.
Anyway, bootstrapped and regression tested on x86_64. Verified it fixes
the
riscv fault and doesn't regress riscv64-elf and riscv32-elf. Bootstrap on
riscv
native targets will fire up overnight.
PR rtl-optimization/121937
gcc/
* simplify-rtx.cc (simplify_context::simplify_binary_operation_1):
Make
sure we've got a scalar_int_mode before calling neg_poly_int_rtx.
gcc/testsuite/
* gcc.target/riscv/pr121937.c: New test.
More information about the Gcc-bugs
mailing list