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.

Reply via email to