[gcc(refs/vendors/riscv/heads/gcc-15-with-riscv-opts)] RISC-V: Combine vec_duplicate + vmadd.vv to vmadd.vx on GR2VR cost

Jeff Law law@gcc.gnu.org
Sat Sep 13 16:30:36 GMT 2025


https://gcc.gnu.org/g:dfe99cc4ac3070b71866a5db035a707da5a86235

commit dfe99cc4ac3070b71866a5db035a707da5a86235
Author: Pan Li <pan2.li@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.li@intel.com>
    (cherry picked from commit 66309452125f8f2c68cd3662dc709041b57073f3)

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")


More information about the Gcc-cvs mailing list