> This expression comes from store_bit_field_1. For the equal-sized > mode > pun here, store_bit_field_1 calls force_subreg (V2SImode, > symbol_ref:DI, DImode, 0). force_subreg first tries > simplify_gen_subreg. The latter allows SYMBOL_REF, CONST, and LABEL_REF > inside a SUBREG. validate_subreg also accepts the equal-sized modes > and zero offset in this case. Therefore, force_subreg returns the > SUBREG directly instead of materializing the inner constant in a > register. > > emit_move_insn then invokes the movV2SI expander directly through > mov_optab. The operand is not checked against general_operand before > the expander is called, so it reaches riscv_vector::legitimize_move. > The same approach is used by ix86_expand_vector_move > (see > https://gcc.gnu.org/git/?p=gcc.git;a=commit;h=6a20b538f2a02e01b311af1dade9cea6a58d815e > , > PR middle-end/71626): materialize SUBREG_REG first and then rebuild the > SUBREG.
Even if x86 has a target workaround, I'm not convinced that's the way to go. If it was, we'd need to add it to every target exposed to it because the issue is surely latent on most vector targets then? Ad 71626 looks like a different signature, initially, so the attack surface is even larger. > More precisely, the expression can be constructed by the current > validate_subreg and simplify_gen_subreg and used as a temporary input to > a move expander. However, it is not a general_operand and cannot remain > in a final move insn. legitimize_move legalizes it before emitting the > final move. Then we rather shouldn't have done that in the first place, I'd say. -- Regards Robin
