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):
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:
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.