This is part of my vector-scalar FMA series. See:
https://gcc.gnu.org/pipermail/gcc-patches/2025-March/679513.html
https://gcc.gnu.org/pipermail/gcc-patches/2025-June/685624.html

The attached patch handles vfmacc and vfmsac. However I ran into an issue while writing testcases. Since the add and acc variants share the same RTL patterns, the only difference being operand constraints, RA is free to pick either of the two, which makes it difficult to test in a straightforward and reliable way. I managed to get appropriate testcases in vf-3-* and vf-4-* by making the loop body longer and register pressure higher. Now I haven't found a simple equivalent either for vf-1-* and vf-2-* or for the run tests.

The attempt shown in the current patch (e.g. vf-1-f64) exercises the right pattern (*pred_mul_addrvvm4df_scalar_undef) but the wrong alternative (got 2 while wanting to test 3).

Any suggestion would be appreciated!

Thanks,
--
PA
commit 03fe5570ae7f9dfa354a9a6fc4afd1cb6f28e1f1
Author: Paul-Antoine Arras <par...@baylibre.com>
Date:   Thu Jun 12 11:30:20 2025 +0200

    RISC-V: Add patterns for vector-scalar multiply-(subtract-)accumulate [PR119100]
    
    This pattern enables the combine pass (or late-combine, depending on the case)
    to merge a vec_duplicate into a plus-mult or minus-mult RTL instruction.
    
    Before this patch, we have two instructions, e.g.:
      vfmv.v.f       v6,fa0
      vfmacc.vv      v2,v6,v4
    
    After, we get only one:
      vfmacc.vf      v2,fa0,v4
    
    gcc/ChangeLog:
    
            * config/riscv/autovec-opt.md (*<optab>_vf_<mode>): Handle both add and
            acc FMA variants.
            * config/riscv/vector.md (*pred_mul_<optab><mode>_scalar_undef): New.
    
    gcc/testsuite/ChangeLog:
    
            * gcc.target/riscv/rvv/autovec/vx_vf/vf-1-f16.c: Add vfmacc and vfmsac.
            * gcc.target/riscv/rvv/autovec/vx_vf/vf-1-f32.c: Likewise.
            * gcc.target/riscv/rvv/autovec/vx_vf/vf-1-f64.c: Likewise.
            * gcc.target/riscv/rvv/autovec/vx_vf/vf-2-f16.c: Likewise.
            * gcc.target/riscv/rvv/autovec/vx_vf/vf-2-f32.c: Likewise.
            * gcc.target/riscv/rvv/autovec/vx_vf/vf-2-f64.c: Likewise.
            * gcc.target/riscv/rvv/autovec/vx_vf/vf-3-f16.c: Likewise.
            * gcc.target/riscv/rvv/autovec/vx_vf/vf-3-f32.c: Likewise.
            * gcc.target/riscv/rvv/autovec/vx_vf/vf-3-f64.c: Likewise.
            * gcc.target/riscv/rvv/autovec/vx_vf/vf-4-f16.c: Likewise.
            * gcc.target/riscv/rvv/autovec/vx_vf/vf-4-f32.c: Likewise.
            * gcc.target/riscv/rvv/autovec/vx_vf/vf-4-f64.c: Likewise.
            * gcc.target/riscv/rvv/autovec/vx_vf/vf_mulop.h: Add support for acc
            variants.

diff --git gcc/config/riscv/autovec-opt.md gcc/config/riscv/autovec-opt.md
index e8293135af3..bb15d14b4e6 100644
--- gcc/config/riscv/autovec-opt.md
+++ gcc/config/riscv/autovec-opt.md
@@ -1721,24 +1721,26 @@ (define_insn_and_split "*<optab>_vx_<mode>"
 ;; - vfmsub.vf
 ;; - vfnmadd.vf
 ;; - vfnmsub.vf
+;; - vfmacc.vf
+;; - vfmsac.vf
 ;; =============================================================================
 
-;; vfmadd.vf, vfmsub.vf
+;; vfmadd.vf, vfmsub.vf, vfmacc.vf, vfmsac.vf
 (define_insn_and_split "*<optab>_vf_<mode>"
-  [(set (match_operand:V_VLSF 0 "register_operand"		"=vd")
+  [(set (match_operand:V_VLSF 0 "register_operand")
     (plus_minus:V_VLSF
 	    (mult:V_VLSF
 	      (vec_duplicate:V_VLSF
-		(match_operand:<VEL> 1 "register_operand"	"  f"))
-	      (match_operand:V_VLSF 2 "register_operand"	"  0"))
-	    (match_operand:V_VLSF 3 "register_operand"		" vr")))]
+		(match_operand:<VEL> 1 "register_operand"))
+	      (match_operand:V_VLSF 2 "register_operand"))
+	    (match_operand:V_VLSF 3 "register_operand")))]
   "TARGET_VECTOR && can_create_pseudo_p ()"
   "#"
   "&& 1"
   [(const_int 0)]
   {
     rtx ops[] = {operands[0], operands[1], operands[2], operands[3],
-		 operands[2]};
+		 RVV_VUNDEF(<MODE>mode)};
     riscv_vector::emit_vlmax_insn (code_for_pred_mul_scalar (<CODE>, <MODE>mode),
 				   riscv_vector::TERNARY_OP_FRM_DYN, ops);
     DONE;
diff --git gcc/config/riscv/vector.md gcc/config/riscv/vector.md
index 851ba4a9490..aaea1153393 100644
--- gcc/config/riscv/vector.md
+++ gcc/config/riscv/vector.md
@@ -6599,9 +6599,42 @@ (define_expand "@pred_mul_<optab><mode>_scalar"
 	        (match_operand:<VEL> 2 "register_operand"))
 	      (match_operand:V_VLSF 3 "register_operand"))
 	    (match_operand:V_VLSF 4 "register_operand"))
-	  (match_operand:V_VLSF 5 "register_operand")))]
+	  (match_operand:V_VLSF 5 "vector_merge_operand")))]
   "TARGET_VECTOR"
-{})
+{
+  riscv_vector::prepare_ternary_operands (operands);
+})
+
+(define_insn "*pred_mul_<optab><mode>_scalar_undef"
+  [(set (match_operand:V_VLSF 0 "register_operand"           "=vd,vd, vr, vr")
+	(if_then_else:V_VLSF
+	  (unspec:<VM>
+	    [(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")
+	     (match_operand 10 "const_int_operand"       "  i,  i,  i,  i")
+	     (reg:SI VL_REGNUM)
+	     (reg:SI VTYPE_REGNUM)
+	     (reg:SI FRM_REGNUM)] UNSPEC_VPREDICATE)
+	  (plus_minus:V_VLSF
+	    (mult:V_VLSF
+	      (vec_duplicate:V_VLSF
+	        (match_operand:<VEL> 3 "register_operand"    "  f,  f,  f,  f"))
+	      (match_operand:V_VLSF 4 "register_operand"     "  0, vr,  0, vr"))
+	    (match_operand:V_VLSF 5 "register_operand"       " vr,  0, vr,  0"))
+	  (match_operand:V_VLSF 2 "vector_undef_operand")))]
+  "TARGET_VECTOR"
+  "@
+   vf<madd_msub>.vf\t%0,%3,%5%p1
+   vf<macc_msac>.vf\t%0,%3,%4%p1
+   vf<madd_msub>.vf\t%0,%3,%5%p1
+   vf<macc_msac>.vf\t%0,%3,%4%p1"
+  [(set_attr "type" "vfmuladd")
+   (set_attr "mode" "<MODE>")
+   (set (attr "frm_mode")
+	(symbol_ref "riscv_vector::get_frm_mode (operands[10])"))])
 
 (define_insn "*pred_<madd_msub><mode>_scalar"
   [(set (match_operand:V_VLSF 0 "register_operand"            "=vd, vr")
diff --git gcc/testsuite/gcc.target/riscv/rvv/autovec/vx_vf/vf-1-f16.c gcc/testsuite/gcc.target/riscv/rvv/autovec/vx_vf/vf-1-f16.c
index 09f4b71f30d..10ee2d82597 100644
--- gcc/testsuite/gcc.target/riscv/rvv/autovec/vx_vf/vf-1-f16.c
+++ gcc/testsuite/gcc.target/riscv/rvv/autovec/vx_vf/vf-1-f16.c
@@ -7,8 +7,12 @@ DEF_VF_MULOP_CASE_0 (_Float16, +, +, add)
 DEF_VF_MULOP_CASE_0 (_Float16, -, +, sub)
 DEF_VF_MULOP_CASE_0 (_Float16, +, -, nadd)
 DEF_VF_MULOP_CASE_0 (_Float16, -, -, nsub)
+DEF_VF_MULOP_ACC_CASE_0 (_Float16, +, +, acc)
+DEF_VF_MULOP_ACC_CASE_0 (_Float16, -, +, sac)
 
 /* { dg-final { scan-assembler-times {vfmadd.vf} 1 } } */
 /* { dg-final { scan-assembler-times {vfmsub.vf} 1 } } */
 /* { dg-final { scan-assembler-times {vfnmadd.vf} 1 } } */
 /* { dg-final { scan-assembler-times {vfnmsub.vf} 1 } } */
+/* { dg-final { scan-assembler-times {vfmacc.vf} 1 } } */
+/* { dg-final { scan-assembler-times {vfmsac.vf} 1 } } */
diff --git gcc/testsuite/gcc.target/riscv/rvv/autovec/vx_vf/vf-1-f32.c gcc/testsuite/gcc.target/riscv/rvv/autovec/vx_vf/vf-1-f32.c
index b21ae49bd5f..3492c7f1ff8 100644
--- gcc/testsuite/gcc.target/riscv/rvv/autovec/vx_vf/vf-1-f32.c
+++ gcc/testsuite/gcc.target/riscv/rvv/autovec/vx_vf/vf-1-f32.c
@@ -7,8 +7,12 @@ DEF_VF_MULOP_CASE_0 (float, +, +, add)
 DEF_VF_MULOP_CASE_0 (float, -, +, sub)
 DEF_VF_MULOP_CASE_0 (float, +, -, nadd)
 DEF_VF_MULOP_CASE_0 (float, -, -, nsub)
+DEF_VF_MULOP_ACC_CASE_0 (float, +, +, acc)
+DEF_VF_MULOP_ACC_CASE_0 (float, -, +, sac)
 
 /* { dg-final { scan-assembler-times {vfmadd.vf} 1 } } */
 /* { dg-final { scan-assembler-times {vfmsub.vf} 1 } } */
 /* { dg-final { scan-assembler-times {vfnmadd.vf} 1 } } */
 /* { dg-final { scan-assembler-times {vfnmsub.vf} 1 } } */
+/* { dg-final { scan-assembler-times {vfmacc.vf} 1 } } */
+/* { dg-final { scan-assembler-times {vfmsac.vf} 1 } } */
diff --git gcc/testsuite/gcc.target/riscv/rvv/autovec/vx_vf/vf-1-f64.c gcc/testsuite/gcc.target/riscv/rvv/autovec/vx_vf/vf-1-f64.c
index 56a44dd065d..3ee2fbb9cd5 100644
--- gcc/testsuite/gcc.target/riscv/rvv/autovec/vx_vf/vf-1-f64.c
+++ gcc/testsuite/gcc.target/riscv/rvv/autovec/vx_vf/vf-1-f64.c
@@ -7,8 +7,12 @@ DEF_VF_MULOP_CASE_0 (double, +, +, add)
 DEF_VF_MULOP_CASE_0 (double, -, +, sub)
 DEF_VF_MULOP_CASE_0 (double, +, -, nadd)
 DEF_VF_MULOP_CASE_0 (double, -, -, nsub)
+DEF_VF_MULOP_ACC_CASE_0 (double, +, +, acc)
+DEF_VF_MULOP_ACC_CASE_0 (double, -, +, sac)
 
 /* { dg-final { scan-assembler-times {vfmadd.vf} 1 } } */
 /* { dg-final { scan-assembler-times {vfmsub.vf} 1 } } */
 /* { dg-final { scan-assembler-times {vfnmadd.vf} 1 } } */
 /* { dg-final { scan-assembler-times {vfnmsub.vf} 1 } } */
+/* { dg-final { scan-assembler-times {vfmacc.vf} 1 } } */
+/* { dg-final { scan-assembler-times {vfmsac.vf} 1 } } */
diff --git gcc/testsuite/gcc.target/riscv/rvv/autovec/vx_vf/vf-2-f16.c gcc/testsuite/gcc.target/riscv/rvv/autovec/vx_vf/vf-2-f16.c
index 22180cb53cd..1e4b8064228 100644
--- gcc/testsuite/gcc.target/riscv/rvv/autovec/vx_vf/vf-2-f16.c
+++ gcc/testsuite/gcc.target/riscv/rvv/autovec/vx_vf/vf-2-f16.c
@@ -1,14 +1,11 @@
 /* { dg-do compile } */
 /* { dg-options "-march=rv64gcv_zvfh -mabi=lp64d --param=fpr2vr-cost=1" } */
 
-#include "vf_mulop.h"
-
-DEF_VF_MULOP_CASE_0 (_Float16, +, +, add)
-DEF_VF_MULOP_CASE_0 (_Float16, -, +, sub)
-DEF_VF_MULOP_CASE_0 (_Float16, +, -, nadd)
-DEF_VF_MULOP_CASE_0 (_Float16, -, -, nsub)
+#include "vf-1-f16.c"
 
 /* { dg-final { scan-assembler-not {vfmadd.vf} } } */
 /* { dg-final { scan-assembler-not {vfmsub.vf} } } */
 /* { dg-final { scan-assembler-not {vfnmadd.vf} } } */
 /* { dg-final { scan-assembler-not {vfnmsub.vf} } } */
+/* { dg-final { scan-assembler-not {vfmacc.vf} } } */
+/* { dg-final { scan-assembler-not {vfmsac.vf} } } */
diff --git gcc/testsuite/gcc.target/riscv/rvv/autovec/vx_vf/vf-2-f32.c gcc/testsuite/gcc.target/riscv/rvv/autovec/vx_vf/vf-2-f32.c
index 318c281d0c1..1f4f5e7d361 100644
--- gcc/testsuite/gcc.target/riscv/rvv/autovec/vx_vf/vf-2-f32.c
+++ gcc/testsuite/gcc.target/riscv/rvv/autovec/vx_vf/vf-2-f32.c
@@ -1,12 +1,7 @@
 /* { dg-do compile } */
 /* { dg-options "-march=rv64gcv -mabi=lp64d --param=fpr2vr-cost=1" } */
 
-#include "vf_mulop.h"
-
-DEF_VF_MULOP_CASE_0 (float, +, +, add)
-DEF_VF_MULOP_CASE_0 (float, -, +, sub)
-DEF_VF_MULOP_CASE_0 (float, +, -, nadd)
-DEF_VF_MULOP_CASE_0 (float, -, -, nsub)
+#include "vf-1-f32.c"
 
 /* { dg-final { scan-assembler-not {vfmadd.vf} } } */
 /* { dg-final { scan-assembler-not {vfmsub.vf} } } */
diff --git gcc/testsuite/gcc.target/riscv/rvv/autovec/vx_vf/vf-2-f64.c gcc/testsuite/gcc.target/riscv/rvv/autovec/vx_vf/vf-2-f64.c
index 318c281d0c1..5030ea8f654 100644
--- gcc/testsuite/gcc.target/riscv/rvv/autovec/vx_vf/vf-2-f64.c
+++ gcc/testsuite/gcc.target/riscv/rvv/autovec/vx_vf/vf-2-f64.c
@@ -1,12 +1,7 @@
 /* { dg-do compile } */
 /* { dg-options "-march=rv64gcv -mabi=lp64d --param=fpr2vr-cost=1" } */
 
-#include "vf_mulop.h"
-
-DEF_VF_MULOP_CASE_0 (float, +, +, add)
-DEF_VF_MULOP_CASE_0 (float, -, +, sub)
-DEF_VF_MULOP_CASE_0 (float, +, -, nadd)
-DEF_VF_MULOP_CASE_0 (float, -, -, nsub)
+#include "vf-1-f64.c"
 
 /* { dg-final { scan-assembler-not {vfmadd.vf} } } */
 /* { dg-final { scan-assembler-not {vfmsub.vf} } } */
diff --git gcc/testsuite/gcc.target/riscv/rvv/autovec/vx_vf/vf-3-f16.c gcc/testsuite/gcc.target/riscv/rvv/autovec/vx_vf/vf-3-f16.c
index 382f7ef50a9..144214102c0 100644
--- gcc/testsuite/gcc.target/riscv/rvv/autovec/vx_vf/vf-3-f16.c
+++ gcc/testsuite/gcc.target/riscv/rvv/autovec/vx_vf/vf-3-f16.c
@@ -1,5 +1,5 @@
 /* { dg-do compile } */
-/* { dg-options "-march=rv64gcv_zvfh -mabi=lp64d --param=fpr2vr-cost=0" } */
+/* { dg-options "-march=rv64gcv_zvfh -mabi=lp64d -fno-schedule-insns -fno-schedule-insns2 --param=fpr2vr-cost=0" } */
 
 #include "vf_mulop.h"
 
@@ -7,8 +7,12 @@ DEF_VF_MULOP_CASE_1 (_Float16, +, +, add, VF_MULOP_BODY_X16)
 DEF_VF_MULOP_CASE_1 (_Float16, -, +, sub, VF_MULOP_BODY_X16)
 DEF_VF_MULOP_CASE_1 (_Float16, +, -, nadd, VF_MULOP_BODY_X16)
 DEF_VF_MULOP_CASE_1 (_Float16, -, -, nsub, VF_MULOP_BODY_X16)
+DEF_VF_MULOP_ACC_CASE_1 (_Float16, +, +, acc, VF_MULOP_ACC_BODY_X256)
+DEF_VF_MULOP_ACC_CASE_1 (_Float16, -, +, sac, VF_MULOP_ACC_BODY_X256)
 
 /* { dg-final { scan-assembler {vfmadd.vf} } } */
 /* { dg-final { scan-assembler {vfmsub.vf} } } */
 /* { dg-final { scan-assembler {vfnmadd.vf} } } */
 /* { dg-final { scan-assembler {vfnmsub.vf} } } */
+/* { dg-final { scan-assembler {vfmacc.vf} } } */
+/* { dg-final { scan-assembler {vfmsac.vf} } } */
diff --git gcc/testsuite/gcc.target/riscv/rvv/autovec/vx_vf/vf-3-f32.c gcc/testsuite/gcc.target/riscv/rvv/autovec/vx_vf/vf-3-f32.c
index db2cd2eaabf..b5daba65fb4 100644
--- gcc/testsuite/gcc.target/riscv/rvv/autovec/vx_vf/vf-3-f32.c
+++ gcc/testsuite/gcc.target/riscv/rvv/autovec/vx_vf/vf-3-f32.c
@@ -1,5 +1,5 @@
 /* { dg-do compile } */
-/* { dg-options "-march=rv64gcv -mabi=lp64d --param=fpr2vr-cost=0" } */
+/* { dg-options "-march=rv64gcv -mabi=lp64d -fno-schedule-insns -fno-schedule-insns2 --param=fpr2vr-cost=0" } */
 
 #include "vf_mulop.h"
 
@@ -7,8 +7,12 @@ DEF_VF_MULOP_CASE_1 (float, +, +, add, VF_MULOP_BODY_X16)
 DEF_VF_MULOP_CASE_1 (float, -, +, sub, VF_MULOP_BODY_X16)
 DEF_VF_MULOP_CASE_1 (float, +, -, nadd, VF_MULOP_BODY_X16)
 DEF_VF_MULOP_CASE_1 (float, -, -, nsub, VF_MULOP_BODY_X16)
+DEF_VF_MULOP_ACC_CASE_1 (float, +, +, acc, VF_MULOP_ACC_BODY_X128)
+DEF_VF_MULOP_ACC_CASE_1 (float, -, +, sac, VF_MULOP_ACC_BODY_X128)
 
 /* { dg-final { scan-assembler {vfmadd.vf} } } */
 /* { dg-final { scan-assembler {vfmsub.vf} } } */
 /* { dg-final { scan-assembler {vfnmadd.vf} } } */
 /* { dg-final { scan-assembler {vfnmsub.vf} } } */
+/* { dg-final { scan-assembler {vfmacc.vf} } } */
+/* { dg-final { scan-assembler {vfmsac.vf} } } */
diff --git gcc/testsuite/gcc.target/riscv/rvv/autovec/vx_vf/vf-3-f64.c gcc/testsuite/gcc.target/riscv/rvv/autovec/vx_vf/vf-3-f64.c
index 423b4db3966..c9a7eecf216 100644
--- gcc/testsuite/gcc.target/riscv/rvv/autovec/vx_vf/vf-3-f64.c
+++ gcc/testsuite/gcc.target/riscv/rvv/autovec/vx_vf/vf-3-f64.c
@@ -1,5 +1,5 @@
 /* { dg-do compile } */
-/* { dg-options "-march=rv64gcv -mabi=lp64d --param=fpr2vr-cost=0" } */
+/* { dg-options "-march=rv64gcv -mabi=lp64d -fno-schedule-insns -fno-schedule-insns2 --param=fpr2vr-cost=0" } */
 
 #include "vf_mulop.h"
 
@@ -7,8 +7,12 @@ DEF_VF_MULOP_CASE_1 (double, +, +, add, VF_MULOP_BODY_X16)
 DEF_VF_MULOP_CASE_1 (double, -, +, sub, VF_MULOP_BODY_X16)
 DEF_VF_MULOP_CASE_1 (double, +, -, nadd, VF_MULOP_BODY_X16)
 DEF_VF_MULOP_CASE_1 (double, -, -, nsub, VF_MULOP_BODY_X16)
+DEF_VF_MULOP_ACC_CASE_1 (double, +, +, acc, VF_MULOP_ACC_BODY_X128)
+DEF_VF_MULOP_ACC_CASE_1 (double, -, +, sac, VF_MULOP_ACC_BODY_X128)
 
 /* { dg-final { scan-assembler {vfmadd.vf} } } */
 /* { dg-final { scan-assembler {vfmsub.vf} } } */
 /* { dg-final { scan-assembler {vfnmadd.vf} } } */
 /* { dg-final { scan-assembler {vfnmsub.vf} } } */
+/* { dg-final { scan-assembler {vfmacc.vf} } } */
+/* { dg-final { scan-assembler {vfmsac.vf} } } */
diff --git gcc/testsuite/gcc.target/riscv/rvv/autovec/vx_vf/vf-4-f16.c gcc/testsuite/gcc.target/riscv/rvv/autovec/vx_vf/vf-4-f16.c
index 1482ff0fdf8..7f35144b8d5 100644
--- gcc/testsuite/gcc.target/riscv/rvv/autovec/vx_vf/vf-4-f16.c
+++ gcc/testsuite/gcc.target/riscv/rvv/autovec/vx_vf/vf-4-f16.c
@@ -1,14 +1,11 @@
 /* { dg-do compile } */
-/* { dg-options "-march=rv64gcv_zvfh -mabi=lp64d --param=fpr2vr-cost=4" } */
+/* { dg-options "-march=rv64gcv_zvfh -mabi=lp64d -fno-schedule-insns -fno-schedule-insns2 --param=fpr2vr-cost=4" } */
 
-#include "vf_mulop.h"
-
-DEF_VF_MULOP_CASE_1 (_Float16, +, +, add, VF_MULOP_BODY_X16)
-DEF_VF_MULOP_CASE_1 (_Float16, -, +, sub, VF_MULOP_BODY_X16)
-DEF_VF_MULOP_CASE_1 (_Float16, +, -, nadd, VF_MULOP_BODY_X16)
-DEF_VF_MULOP_CASE_1 (_Float16, -, -, nsub, VF_MULOP_BODY_X16)
+#include "vf-3-f16.c"
 
 /* { dg-final { scan-assembler-not {vfmadd.vf} } } */
 /* { dg-final { scan-assembler-not {vfmsub.vf} } } */
 /* { dg-final { scan-assembler-not {vfnmadd.vf} } } */
 /* { dg-final { scan-assembler-not {vfnmsub.vf} } } */
+/* { dg-final { scan-assembler-not {vfmacc.vf} } } */
+/* { dg-final { scan-assembler-not {vfmsac.vf} } } */
diff --git gcc/testsuite/gcc.target/riscv/rvv/autovec/vx_vf/vf-4-f32.c gcc/testsuite/gcc.target/riscv/rvv/autovec/vx_vf/vf-4-f32.c
index d1368e773d8..161791aef23 100644
--- gcc/testsuite/gcc.target/riscv/rvv/autovec/vx_vf/vf-4-f32.c
+++ gcc/testsuite/gcc.target/riscv/rvv/autovec/vx_vf/vf-4-f32.c
@@ -1,14 +1,11 @@
 /* { dg-do compile } */
-/* { dg-options "-march=rv64gcv -mabi=lp64d --param=fpr2vr-cost=4" } */
+/* { dg-options "-march=rv64gcv -mabi=lp64d -fno-schedule-insns -fno-schedule-insns2 --param=fpr2vr-cost=4" } */
 
-#include "vf_mulop.h"
-
-DEF_VF_MULOP_CASE_1 (float, +, +, add, VF_MULOP_BODY_X16)
-DEF_VF_MULOP_CASE_1 (float, -, +, sub, VF_MULOP_BODY_X16)
-DEF_VF_MULOP_CASE_1 (float, +, -, nadd, VF_MULOP_BODY_X16)
-DEF_VF_MULOP_CASE_1 (float, -, -, nsub, VF_MULOP_BODY_X16)
+#include "vf-3-f32.c"
 
 /* { dg-final { scan-assembler-not {vfmadd.vf} } } */
 /* { dg-final { scan-assembler-not {vfmsub.vf} } } */
 /* { dg-final { scan-assembler-not {vfnmadd.vf} } } */
 /* { dg-final { scan-assembler-not {vfnmsub.vf} } } */
+/* { dg-final { scan-assembler-not {vfmacc.vf} } } */
+/* { dg-final { scan-assembler-not {vfmsac.vf} } } */
diff --git gcc/testsuite/gcc.target/riscv/rvv/autovec/vx_vf/vf-4-f64.c gcc/testsuite/gcc.target/riscv/rvv/autovec/vx_vf/vf-4-f64.c
index 8e4bdd4b15a..e388c0fcd50 100644
--- gcc/testsuite/gcc.target/riscv/rvv/autovec/vx_vf/vf-4-f64.c
+++ gcc/testsuite/gcc.target/riscv/rvv/autovec/vx_vf/vf-4-f64.c
@@ -1,14 +1,11 @@
 /* { dg-do compile } */
-/* { dg-options "-march=rv64gcv -mabi=lp64d --param=fpr2vr-cost=4" } */
+/* { dg-options "-march=rv64gcv -mabi=lp64d -fno-schedule-insns -fno-schedule-insns2 --param=fpr2vr-cost=4" } */
 
-#include "vf_mulop.h"
-
-DEF_VF_MULOP_CASE_1 (double, +, +, add, VF_MULOP_BODY_X16)
-DEF_VF_MULOP_CASE_1 (double, -, +, sub, VF_MULOP_BODY_X16)
-DEF_VF_MULOP_CASE_1 (double, +, -, nadd, VF_MULOP_BODY_X16)
-DEF_VF_MULOP_CASE_1 (double, -, -, nsub, VF_MULOP_BODY_X16)
+#include "vf-3-f64.c"
 
 /* { dg-final { scan-assembler-not {vfmadd.vf} } } */
 /* { dg-final { scan-assembler-not {vfmsub.vf} } } */
 /* { dg-final { scan-assembler-not {vfnmadd.vf} } } */
 /* { dg-final { scan-assembler-not {vfnmsub.vf} } } */
+/* { dg-final { scan-assembler-not {vfmacc.vf} } } */
+/* { dg-final { scan-assembler-not {vfmsac.vf} } } */
diff --git gcc/testsuite/gcc.target/riscv/rvv/autovec/vx_vf/vf_mulop.h gcc/testsuite/gcc.target/riscv/rvv/autovec/vx_vf/vf_mulop.h
index 433a16e4eec..51252482937 100644
--- gcc/testsuite/gcc.target/riscv/rvv/autovec/vx_vf/vf_mulop.h
+++ gcc/testsuite/gcc.target/riscv/rvv/autovec/vx_vf/vf_mulop.h
@@ -17,6 +17,20 @@
 #define RUN_VF_MULOP_CASE_0_WRAP(T, NAME, out, in, x, n)                       \
   RUN_VF_MULOP_CASE_0(T, NAME, out, in, x, n)
 
+#define DEF_VF_MULOP_ACC_CASE_0(T, OP, NEG, NAME)                              \
+  T test_vf_mulop_##NAME##_##T##_case_0 (T *restrict out, T *restrict in, T f, \
+					 unsigned n)                           \
+  {                                                                            \
+    for (unsigned i = 0; i < n; i++)                                           \
+      out[i] = NEG (f * in[i] OP out[i]);                                      \
+  }
+#define DEF_VF_MULOP_ACC_CASE_0_WRAP(T, OP, NEG, NAME)                         \
+  DEF_VF_MULOP_ACC_CASE_0 (T, OP, NEG, NAME)
+#define RUN_VF_MULOP_ACC_CASE_0(T, NAME, out, in, x, n)                        \
+  test_vf_mulop_acc_##NAME##_##T##_case_0 (out, in, x, n)
+#define RUN_VF_MULOP_ACC_CASE_0_WRAP(T, NAME, out, in, x, n)                   \
+  RUN_VF_MULOP_ACC_CASE_0 (T, NAME, out, in, x, n)
+
 #define VF_MULOP_BODY(op, neg)                                                 \
   out[k + 0] = neg (tmp * out[k + 0] op in[k + 0]);                            \
   out[k + 1] = neg (tmp * out[k + 1] op in[k + 1]);                            \
@@ -62,4 +76,54 @@
 #define DEF_VF_MULOP_CASE_1_WRAP(T, OP, NEG, NAME, BODY)                       \
   DEF_VF_MULOP_CASE_1 (T, OP, NEG, NAME, BODY)
 
+#define VF_MULOP_ACC_BODY(op, neg)                                             \
+  out[k + 0] = neg (tmp * in[k + 0] op out[k + 0]);                            \
+  out[k + 1] = neg (tmp * in[k + 1] op out[k + 1]);                            \
+  k += 2;
+
+#define VF_MULOP_ACC_BODY_X4(op, neg)                                          \
+  VF_MULOP_ACC_BODY (op, neg)                                                  \
+  VF_MULOP_ACC_BODY (op, neg)
+
+#define VF_MULOP_ACC_BODY_X8(op, neg)                                          \
+  VF_MULOP_ACC_BODY_X4 (op, neg)                                               \
+  VF_MULOP_ACC_BODY_X4 (op, neg)
+
+#define VF_MULOP_ACC_BODY_X16(op, neg)                                         \
+  VF_MULOP_ACC_BODY_X8 (op, neg)                                               \
+  VF_MULOP_ACC_BODY_X8 (op, neg)
+
+#define VF_MULOP_ACC_BODY_X32(op, neg)                                         \
+  VF_MULOP_ACC_BODY_X16 (op, neg)                                              \
+  VF_MULOP_ACC_BODY_X16 (op, neg)
+
+#define VF_MULOP_ACC_BODY_X64(op, neg)                                         \
+  VF_MULOP_ACC_BODY_X32 (op, neg)                                              \
+  VF_MULOP_ACC_BODY_X32 (op, neg)
+
+#define VF_MULOP_ACC_BODY_X128(op, neg)                                        \
+  VF_MULOP_ACC_BODY_X64 (op, neg)                                              \
+  VF_MULOP_ACC_BODY_X64 (op, neg)
+
+#define VF_MULOP_ACC_BODY_X256(op, neg)                                        \
+  VF_MULOP_ACC_BODY_X128 (op, neg)                                             \
+  VF_MULOP_ACC_BODY_X128 (op, neg)
+
+#define DEF_VF_MULOP_ACC_CASE_1(T, OP, NEG, NAME, BODY)                        \
+  void test_vf_mulop_acc_##NAME##_##T##_case_1 (T *restrict out,               \
+						T *restrict in, T x,           \
+						unsigned n)                    \
+  {                                                                            \
+    unsigned k = 0;                                                            \
+    T tmp = x + 3;                                                             \
+                                                                               \
+    while (k < n)                                                              \
+      {                                                                        \
+	tmp = tmp * 0x3f;                                                      \
+	BODY (OP, NEG)                                                         \
+      }                                                                        \
+  }
+#define DEF_VF_MULOP_ACC_CASE_1_WRAP(T, OP, NEG, NAME, BODY)                   \
+  DEF_VF_MULOP_ACC_CASE_1 (T, OP, NEG, NAME, BODY)
+
 #endif

Reply via email to