https://gcc.gnu.org/bugzilla/show_bug.cgi?id=118832
--- Comment #3 from Robin Dapp <rdapp at gcc dot gnu.org> --- The mechanism that introduces those unsplit instructions always seems to be via reload. At some point we see a REG_EQUAL note with a const_vector. As we, generally, can rematerialize constants we try to do that. And I don't think we can ever prevent moving constants to a register. Those VLA const_vectors aren't easily synthesized, though, and almost always require a few instructions. So just making everything unsplittable from LRA on is not going to help us directly, it would just break in a different way. Therefore I'm afraid we just need to make sure we don't use or rely on unsplit instructions in the const-move expander. For the case here the following helps: diff --git a/gcc/config/riscv/riscv-v.cc b/gcc/config/riscv/riscv-v.cc index 9847439ca77..a7559d11e19 100644 --- a/gcc/config/riscv/riscv-v.cc +++ b/gcc/config/riscv/riscv-v.cc @@ -1265,7 +1265,16 @@ expand_const_vector (rtx target, rtx src) element. Use element width = 64 and broadcast a vector with all element equal to 0x0706050403020100. */ rtx ele = builder.get_merged_repeating_sequence (); - rtx dup = expand_vector_broadcast (builder.new_mode (), ele); + rtx dup; + if (lra_in_progress) + { + dup = gen_reg_rtx (builder.new_mode ()); + rtx ops[] = {dup, ele}; + emit_vlmax_insn (code_for_pred_broadcast + (builder.new_mode ()), UNARY_OP, ops); + } + else + dup = expand_vector_broadcast (builder.new_mode (), ele); emit_move_insn (result, gen_lowpart (mode, dup)); } else But we'd need to audit the other cases still.