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.

Reply via email to