https://gcc.gnu.org/bugzilla/show_bug.cgi?id=123381
--- Comment #3 from Robin Dapp <rdapp at gcc dot gnu.org> ---
To me what we're doing looks superficially reasonable. As we cannot directly
vector sign-extend the DImode reg, we spill it and should vector load it from
memory.
This will get us to this pattern:
(define_insn_and_split "*mov<V_FRACT:mode><P:mode>_lra"
[(set (match_operand:V_FRACT 0 "reg_or_mem_operand" "=vr, m,vr")
(match_operand:V_FRACT 1 "reg_or_mem_operand" " m,vr,vr"))
(clobber (match_scratch:P 2 "=&r,&r,X"))]
One complication is that the mode RVVMF4HI happens to have a constant number of
units, so is actually a V2HImode. Not ideal but manageable.
In the real VLS case, instead of the pattern above we just use movv2hi
(define_insn_and_split "*mov<mode>"
[(set (match_operand:VLS_AVL_IMM 0 "reg_or_mem_operand" "=vr, m, vr")
(match_operand:VLS_AVL_IMM 1 "reg_or_mem_operand" " m,vr, vr"))]
The difference is that this has just two operands and LRA does the cycle-danger
check:
Cycle danger: overall += LRA_MAX_REJECT
This makes us use the first alternative (mem->reg) which just works.
The _lra pattern above has three operands, the scratch included. LRA doesn't
check for cycle danger and happily creates a cycle :)
Not sure yet how to proceed. Naively I'd have said scratch registers shouldn't
count and we should still do the cycle check.