https://gcc.gnu.org/g:66309452125f8f2c68cd3662dc709041b57073f3

commit r16-3584-g66309452125f8f2c68cd3662dc709041b57073f3
Author: Pan Li <pan2...@intel.com>
Date:   Tue Sep 2 12:30:16 2025 +0800

    RISC-V: Combine vec_duplicate + vmadd.vv to vmadd.vx on GR2VR cost
    
    This patch would like to combine the vec_duplicate + vmadd.vv to the
    vmadd.vx.  From example as below code.  The related pattern will depend
    on the cost of vec_duplicate from GR2VR.  Then the late-combine will
    take action if the cost of GR2VR is zero, and reject the combination
    if the GR2VR cost is greater than zero.
    
    Assume we have example code like below, GR2VR cost is 0.
    
    Before this patch:
      11   │     beq a3,zero,.L8
      12   │     vsetvli a5,zero,e32,m1,ta,ma
      13   │     vmv.v.x v2,a2
      ...
      16   │ .L3:
      17   │     vsetvli a5,a3,e32,m1,ta,ma
      ...
      22   │     vmadd.vv v1,v2,v3
      ...
      25   │     bne a3,zero,.L3
    
    After this patch:
      11   │     beq a3,zero,.L8
      ...
      14   │ .L3:
      15   │     vsetvli a5,a3,e32,m1,ta,ma
      ...
      20   │     vmadd.vx v1,a2,v3
      ...
      23   │     bne a3,zero,.L3
    
    gcc/ChangeLog:
    
            * config/riscv/autovec-opt.md (*vmacc_vx_<mode>): Rename to
            handle both the macc and madd.
            (*mul_plus_vx_<mode>): Add madd pattern.
            * config/riscv/vector.md (@pred_mul_plus_vx_<mode>): Rename to
            handle both the macc and madd.
            (*pred_macc_<mode>_scalar_undef): Remove.
            (*pred_nmsac_<mode>_scalar_undef): Remove.
            (*pred_mul_plus_vx<mode>_undef): Add new pattern to handle
            both the vmacc and vmadd.
            (@pred_mul_plus_vx<mode>): Ditto.
    
    Signed-off-by: Pan Li <pan2...@intel.com>

Diff:
---
 gcc/config/riscv/autovec-opt.md |   6 +-
 gcc/config/riscv/vector.md      | 172 ++++++++++++++++++++--------------------
 2 files changed, 91 insertions(+), 87 deletions(-)

diff --git a/gcc/config/riscv/autovec-opt.md b/gcc/config/riscv/autovec-opt.md
index 80b3b78d53b2..331d08c2e420 100644
--- a/gcc/config/riscv/autovec-opt.md
+++ b/gcc/config/riscv/autovec-opt.md
@@ -1824,7 +1824,7 @@
   }
   [(set_attr "type" "vimerge")])
 
-(define_insn_and_split "*vmacc_vx_<mode>"
+(define_insn_and_split "*mul_plus_vx_<mode>"
  [(set (match_operand:V_VLSI 0 "register_operand")
    (plus:V_VLSI
     (mult:V_VLSI
@@ -1838,8 +1838,8 @@
   [(const_int 0)]
   {
     insn_code icode = code_for_pred_mul_plus_vx (<MODE>mode);
-    rtx ops[] = {operands[0], operands[1], operands[2], operands[3],
-                RVV_VUNDEF(<MODE>mode)};
+    rtx v_undef = RVV_VUNDEF(<MODE>mode);
+    rtx ops[] = {operands[0], operands[1], operands[2], operands[3], v_undef};
     riscv_vector::emit_vlmax_insn (icode, riscv_vector::TERNARY_OP, ops);
 
     DONE;
diff --git a/gcc/config/riscv/vector.md b/gcc/config/riscv/vector.md
index 2b35d66b6114..2e7e77315a78 100644
--- a/gcc/config/riscv/vector.md
+++ b/gcc/config/riscv/vector.md
@@ -5493,52 +5493,6 @@
   "TARGET_VECTOR"
 {})
 
-(define_expand "@pred_mul_plus_vx_<mode>"
-  [(set (match_operand:V_VLSI_QHS       0 "register_operand")
-       (if_then_else:V_VLSI_QHS
-         (unspec:<VM>
-           [(match_operand:<VM>        1 "vector_mask_operand")
-            (match_operand             6 "vector_length_operand")
-            (match_operand             7 "const_int_operand")
-            (match_operand             8 "const_int_operand")
-            (match_operand             9 "const_int_operand")
-            (reg:SI VL_REGNUM)
-            (reg:SI VTYPE_REGNUM)] UNSPEC_VPREDICATE)
-         (plus:V_VLSI_QHS
-           (mult:V_VLSI_QHS
-             (vec_duplicate:V_VLSI_QHS
-               (match_operand:<VEL>    2 "register_operand"))
-             (match_operand:V_VLSI_QHS 3 "register_operand"))
-           (match_operand:V_VLSI_QHS   4 "register_operand"))
-         (match_operand:V_VLSI_QHS     5 "vector_merge_operand")))]
-  "TARGET_VECTOR"
-{
-  riscv_vector::prepare_ternary_operands (operands);
-})
-
-(define_expand "@pred_mul_plus_vx_<mode>"
-  [(set (match_operand:V_VLSI_D       0 "register_operand")
-       (if_then_else:V_VLSI_D
-         (unspec:<VM>
-           [(match_operand:<VM>      1 "vector_mask_operand")
-            (match_operand           6 "vector_length_operand")
-            (match_operand           7 "const_int_operand")
-            (match_operand           8 "const_int_operand")
-            (match_operand           9 "const_int_operand")
-            (reg:SI VL_REGNUM)
-            (reg:SI VTYPE_REGNUM)] UNSPEC_VPREDICATE)
-         (plus:V_VLSI_D
-           (mult:V_VLSI_D
-             (vec_duplicate:V_VLSI_D
-               (match_operand:<VEL>  2 "register_operand"))
-             (match_operand:V_VLSI_D 3 "register_operand"))
-           (match_operand:V_VLSI_D   4 "register_operand"))
-         (match_operand:V_VLSI_D     5 "vector_merge_operand")))]
-  "TARGET_VECTOR && TARGET_64BIT"
-{
-  riscv_vector::prepare_ternary_operands (operands);
-})
-
 (define_expand "@pred_vnmsac_vx_<mode>"
   [(set (match_operand:V_VLSI_QHS       0 "register_operand")
        (if_then_else:V_VLSI_QHS
@@ -8934,7 +8888,7 @@
   [(set_attr "type" "vssegt<order>x")
    (set_attr "mode" "<V32T:MODE>")])
 
-(define_insn "*pred_macc_<mode>_scalar_undef"
+(define_insn "*pred_nmsac_<mode>_scalar_undef"
   [(set (match_operand:V_VLSI_QHS       0 "register_operand"      "=vd,  vr")
        (if_then_else:V_VLSI_QHS
          (unspec:<VM>
@@ -8945,21 +8899,21 @@
             (match_operand             9 "const_int_operand"     "  i,   i")
             (reg:SI VL_REGNUM)
             (reg:SI VTYPE_REGNUM)] UNSPEC_VPREDICATE)
-         (plus:V_VLSI_QHS
+         (minus:V_VLSI_QHS
+           (match_operand:V_VLSI_QHS   5 "register_operand"     "   0,   0")
            (mult:V_VLSI_QHS
              (vec_duplicate:V_VLSI_QHS
                (match_operand:<VEL>    3 "reg_or_0_operand"     "  rJ,  rJ"))
-             (match_operand:V_VLSI_QHS 4 "register_operand"     "  vr,  vr"))
-           (match_operand:V_VLSI_QHS   5 "register_operand"     "   0,   0"))
+             (match_operand:V_VLSI_QHS 4 "register_operand"     "  vr,  vr")))
          (match_operand:V_VLSI_QHS     2 "vector_undef_operand")))]
   "TARGET_VECTOR"
   "@
-   vmacc.vx\t%0,%z3,%4%p1
-   vmacc.vx\t%0,%z3,%4%p1"
+   vnmsac.vx\t%0,%z3,%4%p1
+   vnmsac.vx\t%0,%z3,%4%p1"
   [(set_attr "type" "vimuladd")
    (set_attr "mode" "<MODE>")])
 
-(define_insn "*pred_macc_<mode>_scalar_undef"
+(define_insn "*pred_nmsac_<mode>_scalar_undef"
   [(set (match_operand:V_VLSI_D       0 "register_operand"      "=vd,  vr")
        (if_then_else:V_VLSI_D
          (unspec:<VM>
@@ -8970,70 +8924,120 @@
             (match_operand           9 "const_int_operand"     "  i,   i")
             (reg:SI VL_REGNUM)
             (reg:SI VTYPE_REGNUM)] UNSPEC_VPREDICATE)
-         (plus:V_VLSI_D
+         (minus:V_VLSI_D
+           (match_operand:V_VLSI_D   5 "register_operand"     "   0,   0")
            (mult:V_VLSI_D
              (vec_duplicate:V_VLSI_D
                (match_operand:<VEL>  3 "reg_or_0_operand"     "  rJ,  rJ"))
-             (match_operand:V_VLSI_D 4 "register_operand"     "  vr,  vr"))
-           (match_operand:V_VLSI_D   5 "register_operand"     "   0,   0"))
+             (match_operand:V_VLSI_D 4 "register_operand"     "  vr,  vr")))
          (match_operand:V_VLSI_D     2 "vector_undef_operand")))]
   "TARGET_VECTOR && TARGET_64BIT"
   "@
-   vmacc.vx\t%0,%z3,%4%p1
-   vmacc.vx\t%0,%z3,%4%p1"
+   vnmsac.vx\t%0,%z3,%4%p1
+   vnmsac.vx\t%0,%z3,%4%p1"
   [(set_attr "type" "vimuladd")
    (set_attr "mode" "<MODE>")])
 
-(define_insn "*pred_nmsac_<mode>_scalar_undef"
-  [(set (match_operand:V_VLSI_QHS       0 "register_operand"      "=vd,  vr")
+(define_insn "*pred_mul_plus_vx<mode>_undef"
+  [(set (match_operand:V_VLSI_QHS       0 "register_operand"      "=vd,  vd, 
vr,  vr")
        (if_then_else:V_VLSI_QHS
          (unspec:<VM>
-           [(match_operand:<VM>        1 "vector_mask_operand"   " vm, Wc1")
-            (match_operand             6 "vector_length_operand" "rvl, rvl")
-            (match_operand             7 "const_int_operand"     "  i,   i")
-            (match_operand             8 "const_int_operand"     "  i,   i")
-            (match_operand             9 "const_int_operand"     "  i,   i")
+           [(match_operand:<VM>        1 "vector_mask_operand"   " vm,  vm, 
Wc1, Wc1")
+            (match_operand             6 "vector_length_operand" "rvl, rvl, 
rvl, rvl")
+            (match_operand             7 "const_int_operand"     "  i,   i,   
i,   i")
+            (match_operand             8 "const_int_operand"     "  i,   i,   
i,   i")
+            (match_operand             9 "const_int_operand"     "  i,   i,   
i,   i")
             (reg:SI VL_REGNUM)
             (reg:SI VTYPE_REGNUM)] UNSPEC_VPREDICATE)
-         (minus:V_VLSI_QHS
-           (match_operand:V_VLSI_QHS   5 "register_operand"     "   0,   0")
+         (plus:V_VLSI_QHS
            (mult:V_VLSI_QHS
              (vec_duplicate:V_VLSI_QHS
-               (match_operand:<VEL>    3 "reg_or_0_operand"     "  rJ,  rJ"))
-             (match_operand:V_VLSI_QHS 4 "register_operand"     "  vr,  vr")))
+               (match_operand:<VEL>    3 "reg_or_0_operand"      " rJ,  rJ,  
rJ,  rJ"))
+             (match_operand:V_VLSI_QHS 4 "register_operand"      "  0,  vr,   
0,  vr"))
+           (match_operand:V_VLSI_QHS   5 "register_operand"      " vr,   0,  
vr,   0"))
          (match_operand:V_VLSI_QHS     2 "vector_undef_operand")))]
   "TARGET_VECTOR"
   "@
-   vnmsac.vx\t%0,%z3,%4%p1
-   vnmsac.vx\t%0,%z3,%4%p1"
+   vmadd.vx\t%0,%z3,%5%p1
+   vmacc.vx\t%0,%z3,%4%p1
+   vmadd.vx\t%0,%z3,%5%p1
+   vmacc.vx\t%0,%z3,%4%p1"
   [(set_attr "type" "vimuladd")
    (set_attr "mode" "<MODE>")])
 
-(define_insn "*pred_nmsac_<mode>_scalar_undef"
-  [(set (match_operand:V_VLSI_D       0 "register_operand"      "=vd,  vr")
+(define_insn "*pred_mul_plus_vx<mode>_undef"
+  [(set (match_operand:V_VLSI_D       0 "register_operand"      "=vd,  vd, vr, 
 vr")
        (if_then_else:V_VLSI_D
          (unspec:<VM>
-           [(match_operand:<VM>      1 "vector_mask_operand"   " vm, Wc1")
-            (match_operand           6 "vector_length_operand" "rvl, rvl")
-            (match_operand           7 "const_int_operand"     "  i,   i")
-            (match_operand           8 "const_int_operand"     "  i,   i")
-            (match_operand           9 "const_int_operand"     "  i,   i")
+           [(match_operand:<VM>      1 "vector_mask_operand"   " vm,  vm, Wc1, 
Wc1")
+            (match_operand           6 "vector_length_operand" "rvl, rvl, rvl, 
rvl")
+            (match_operand           7 "const_int_operand"     "  i,   i,   i, 
  i")
+            (match_operand           8 "const_int_operand"     "  i,   i,   i, 
  i")
+            (match_operand           9 "const_int_operand"     "  i,   i,   i, 
  i")
             (reg:SI VL_REGNUM)
             (reg:SI VTYPE_REGNUM)] UNSPEC_VPREDICATE)
-         (minus:V_VLSI_D
-           (match_operand:V_VLSI_D   5 "register_operand"     "   0,   0")
+         (plus:V_VLSI_D
            (mult:V_VLSI_D
              (vec_duplicate:V_VLSI_D
-               (match_operand:<VEL>  3 "reg_or_0_operand"     "  rJ,  rJ"))
-             (match_operand:V_VLSI_D 4 "register_operand"     "  vr,  vr")))
+               (match_operand:<VEL>  3 "reg_or_0_operand"      " rJ,  rJ,  rJ, 
 rJ"))
+             (match_operand:V_VLSI_D 4 "register_operand"      "  0,  vr,   0, 
 vr"))
+           (match_operand:V_VLSI_D   5 "register_operand"      " vr,   0,  vr, 
  0"))
          (match_operand:V_VLSI_D     2 "vector_undef_operand")))]
   "TARGET_VECTOR && TARGET_64BIT"
   "@
-   vnmsac.vx\t%0,%z3,%4%p1
-   vnmsac.vx\t%0,%z3,%4%p1"
+   vmadd.vx\t%0,%z3,%5%p1
+   vmacc.vx\t%0,%z3,%4%p1
+   vmadd.vx\t%0,%z3,%5%p1
+   vmacc.vx\t%0,%z3,%4%p1"
   [(set_attr "type" "vimuladd")
    (set_attr "mode" "<MODE>")])
 
+(define_expand "@pred_mul_plus_vx<mode>"
+  [(set (match_operand:V_VLSI_QHS       0 "register_operand")
+       (if_then_else:V_VLSI_QHS
+         (unspec:<VM>
+           [(match_operand:<VM>        1 "vector_mask_operand")
+            (match_operand             6 "vector_length_operand")
+            (match_operand             7 "const_int_operand")
+            (match_operand             8 "const_int_operand")
+            (match_operand             9 "const_int_operand")
+            (reg:SI VL_REGNUM)
+            (reg:SI VTYPE_REGNUM)] UNSPEC_VPREDICATE)
+         (plus:V_VLSI_QHS
+           (mult:V_VLSI_QHS
+             (vec_duplicate:V_VLSI_QHS
+               (match_operand:<VEL>    2 "reg_or_0_operand"))
+             (match_operand:V_VLSI_QHS 3 "register_operand"))
+           (match_operand:V_VLSI_QHS   4 "register_operand"))
+         (match_operand:V_VLSI_QHS     5 "vector_merge_operand")))]
+  "TARGET_VECTOR"
+  {
+    riscv_vector::prepare_ternary_operands (operands);
+  })
+
+(define_expand "@pred_mul_plus_vx<mode>"
+  [(set (match_operand:V_VLSI_D       0 "register_operand")
+       (if_then_else:V_VLSI_D
+         (unspec:<VM>
+           [(match_operand:<VM>      1 "vector_mask_operand")
+            (match_operand           6 "vector_length_operand")
+            (match_operand           7 "const_int_operand")
+            (match_operand           8 "const_int_operand")
+            (match_operand           9 "const_int_operand")
+            (reg:SI VL_REGNUM)
+            (reg:SI VTYPE_REGNUM)] UNSPEC_VPREDICATE)
+         (plus:V_VLSI_D
+           (mult:V_VLSI_D
+             (vec_duplicate:V_VLSI_D
+               (match_operand:<VEL>  2 "reg_or_0_operand"))
+             (match_operand:V_VLSI_D 3 "register_operand"))
+           (match_operand:V_VLSI_D   4 "register_operand"))
+         (match_operand:V_VLSI_D     5 "vector_merge_operand")))]
+  "TARGET_VECTOR && TARGET_64BIT"
+  {
+    riscv_vector::prepare_ternary_operands (operands);
+  })
+
 (include "autovec.md")
 (include "autovec-opt.md")
 (include "sifive-vector.md")

Reply via email to