Sorry, please ignore this, sent by mistake. Pan
________________________________________ From: Li, Pan2 <[email protected]> Sent: Monday, June 29, 2026 10:14 AM To: [email protected] <[email protected]> Cc: [email protected] <[email protected]>; Li, Pan2 <[email protected]> Subject: [PATCH WIP] RISC-V: Allow RVV register overlap for v[sz]ext.vf2 From: Pan Li <[email protected]> According to the RVV 1.0 spec, the widening ops like vzext.vf2 could have the source registers overlap on constraint, aka: ` The destination EEW is greater than the source EEW, the source EMUL is at least 1, and the overlap is in the highest- numbered part of the destination register group. ` This PATCH could like to re-enable it start from vzext.vf2 for lmul m2. gcc/ChangeLog: * config/riscv/constraints.md: Add more comments for the v[sz]ext.vf2 reg overlap. * config/riscv/riscv.cc (riscv_widen_overlap_ok): Take care of the reg overlap. * config/riscv/vector.md: Add low priority constraint. Signed-off-by: Pan Li <[email protected]> --- gcc/config/riscv/constraints.md | 31 ++++++++++++++++++++++++++++--- gcc/config/riscv/riscv.cc | 30 +++++++++++++++++++++--------- gcc/config/riscv/vector.md | 16 ++++++++-------- 3 files changed, 57 insertions(+), 20 deletions(-) diff --git a/gcc/config/riscv/constraints.md b/gcc/config/riscv/constraints.md index 81d14df17ab..cca4ea4279b 100644 --- a/gcc/config/riscv/constraints.md +++ b/gcc/config/riscv/constraints.md @@ -184,9 +184,34 @@ (define_register_constraint "vd" "TARGET_VECTOR ? VD_REGS : NO_REGS" (define_register_constraint "vm" "TARGET_VECTOR ? VM_REGS : NO_REGS" "A vector mask register (if available).") -;; Dependent (dynamic) constraint: -;; "The source group must overlap the highest-numbered part of the -;; "destination group", i.e. this operand depends on operand 0. +;; Dependent (dynamic) constraint for widening overlap: +;; The RVV widening constraints for register overlap, aka dest EEW > src EEW. +;; Quote from RVV spec 1.0: +;; +;; The destination EEW is greater than the source EEW, the source EMUL is at +;; least 1, and the overlap is in the highest-numbered part of the destination +;; register group (e.g., when LMUL=8, vzext.vf4 v0, v6 is legal, but a source +;; of v0, v2, or v4 is not). +;; +;; Take vzext.vfN for example, only below cases are valid. +;; Source EMUL = LMUL * (Source EEW / SEW) = LMUL * SEW / (N * SEW) = LMUL / N +;; +;; +-----------+------------+------------+----------+ +;; | | LMUL = 8 | LMUL = 4 | LMUL = 2 | +;; +-----------+------------+------------+----------+ +;; | vzext.vf2 | EMUL = 4 | EMUL = 2 | EMUL = 1 | +;; +-----------+------------+------------+----------+ +;; | | v0-7, v4-7 | v0-3, v2-3 | v0-1, v1 | +;; +-----------+------------+------------+----------+ +;; | vzext.vf4 | EMUL = 2 | EMUL = 1 | | +;; +-----------+------------+------------+----------+ +;; | | v0-7, v6-7 | v0-3, v3 | | +;; +-----------+------------+------------+----------+ +;; | vzext.vf8 | EMUL = 1 | | | +;; +-----------+------------+------------+----------+ +;; | | v0-7, v7 | | | +;; +-----------+------------+------------+----------+ +;; (define_register_constraint "Wtt" "TARGET_VECTOR ? V_REGS : NO_REGS" "Vector widening overlap" "riscv_widen_overlap_ok (regno, mode, ref_regno, ref_mode)" diff --git a/gcc/config/riscv/riscv.cc b/gcc/config/riscv/riscv.cc index cc1b8cd16a9..46cab20e664 100644 --- a/gcc/config/riscv/riscv.cc +++ b/gcc/config/riscv/riscv.cc @@ -11236,22 +11236,34 @@ riscv_widen_overlap_ok (unsigned int regno, machine_mode mode, gcc_checking_assert (riscv_vector_mode_p (mode) && riscv_vector_mode_p (wide_mode)); + if (regno == wide_regno) + return false; + unsigned int wide_nregs = riscv_hard_regno_nregs (wide_regno, wide_mode); unsigned int nregs = riscv_hard_regno_nregs (regno, mode); - /* Overlap is only allowed in the highest-numbered part of the wider - destination. */ - if (regno == wide_regno) + /* Reg num alignment. */ + if (wide_nregs < nregs) return false; - if (regno >= wide_regno + (wide_nregs - nregs)) - return true; + if (wide_nregs == nregs) { /* Source LMUL < 1, and vd is not equal to vs. */ + gcc_checking_assert (nregs == 1); + gcc_checking_assert (regno != wide_regno); - /* No overlap is OK. */ - if (regno < wide_regno) - return true; + return true; + } - return false; + gcc_checking_assert (wide_nregs > nregs); + gcc_checking_assert ((wide_nregs % nregs) == 0); + + /* No overlap, leave it to low priority alternative(s). This could allow + the lra overlap registers as much as possible. */ + if (regno + nregs <= wide_regno || wide_regno + wide_nregs <= regno) + return false + + unsigned int highest_num = wide_nregs - nregs; + + return (regno % wide_nregs) == highest_num; } /* Implement TARGET_HARD_REGNO_MODE_OK. */ diff --git a/gcc/config/riscv/vector.md b/gcc/config/riscv/vector.md index 2b6888fc679..2be3357b0bd 100644 --- a/gcc/config/riscv/vector.md +++ b/gcc/config/riscv/vector.md @@ -4090,19 +4090,19 @@ (define_insn "@pred_<optab><mode>" ;; Vector Double-Widening Sign-extend and Zero-extend. (define_insn "@pred_<optab><mode>_vf2" - [(set (match_operand:VWEXTI 0 "register_operand" "=vr, vr, vd, vd") + [(set (match_operand:VWEXTI 0 "register_operand" "=vr, vr, vd, vd, ?&vr, ?&vr, ?&vd, ?&vd") (if_then_else:VWEXTI (unspec:<VM> - [(match_operand:<VM> 1 "vector_mask_operand" "Wc1,Wc1, vm, vm") - (match_operand 4 "vector_length_operand" "rvl,rvl,rvl,rvl") - (match_operand 5 "const_int_operand" " i, i, i, i") - (match_operand 6 "const_int_operand" " i, i, i, i") - (match_operand 7 "const_int_operand" " i, i, i, i") + [(match_operand:<VM> 1 "vector_mask_operand" "Wc1,Wc1, vm, vm, Wc1, Wc1, vm, vm") + (match_operand 4 "vector_length_operand" "rvl,rvl,rvl,rvl, rvl, rvl, rvl, rvl") + (match_operand 5 "const_int_operand" " i, i, i, i, i, i, i, i") + (match_operand 6 "const_int_operand" " i, i, i, i, i, i, i, i") + (match_operand 7 "const_int_operand" " i, i, i, i, i, i, i, i") (reg:SI VL_REGNUM) (reg:SI VTYPE_REGNUM)] UNSPEC_VPREDICATE) (any_extend:VWEXTI - (match_operand:<V_DOUBLE_TRUNC> 3 "register_operand" "Wtt,Wtt,Wtt,Wtt")) - (match_operand:VWEXTI 2 "vector_merge_operand" " vu, 0, vu, 0")))] + (match_operand:<V_DOUBLE_TRUNC> 3 "register_operand" "Wtt,Wtt,Wtt,Wtt, vr, vr, vd, vd")) + (match_operand:VWEXTI 2 "vector_merge_operand" " vu, 0, vu, 0, vu, 0, vu, 0")))] "TARGET_VECTOR && !TARGET_XTHEADVECTOR" "v<sz>ext.vf2\t%0,%3%p1" [(set_attr "type" "vext") -- 2.43.0
