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



Reply via email to