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 <[email protected]>: https://gcc.gnu.org/g:f864e4b54a13420f37dc3710aeb9f8a6f9e63b9c commit r16-4207-gf864e4b54a13420f37dc3710aeb9f8a6f9e63b9c Author: Jeff Law <[email protected]> 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.
