[V3] RISC-V: Support RVV floating-point auto-vectorization

Message ID 20230621155314.183370-1-juzhe.zhong@rivai.ai
State Unresolved
Headers
Series [V3] RISC-V: Support RVV floating-point auto-vectorization |

Checks

Context Check Description
snail/gcc-patch-check warning Git am fail log

Commit Message

juzhe.zhong@rivai.ai June 21, 2023, 3:53 p.m. UTC
  This patch adds RVV floating-point auto-vectorization.
Also, fix attribute bug of floating-point ternary operations in vector.md.

gcc/ChangeLog:

        * config/riscv/autovec.md (fma<mode>4): New pattern.
        (*fma<mode>): Ditto.
        (fnma<mode>4): Ditto.
        (*fnma<mode>): Ditto.
        (fms<mode>4): Ditto.
        (*fms<mode>): Ditto.
        (fnms<mode>4): Ditto.
        (*fnms<mode>): Ditto.
        * config/riscv/riscv-protos.h (emit_vlmax_fp_ternary_insn): New function.
        * config/riscv/riscv-v.cc (emit_vlmax_fp_ternary_insn): Ditto.
        * config/riscv/vector.md: Fix attribute bug.

---
 gcc/config/riscv/autovec.md                   | 184 ++++++++++++++++++
 gcc/config/riscv/riscv-protos.h               |   1 +
 gcc/config/riscv/riscv-v.cc                   |  49 +++--
 gcc/config/riscv/vector.md                    |   4 +-
 .../riscv/rvv/autovec/ternop/ternop-1.c       |   8 +-
 .../riscv/rvv/autovec/ternop/ternop-10.c      |  23 +++
 .../riscv/rvv/autovec/ternop/ternop-11.c      |  29 +++
 .../riscv/rvv/autovec/ternop/ternop-12.c      |  28 +++
 .../riscv/rvv/autovec/ternop/ternop-2.c       |   8 +-
 .../riscv/rvv/autovec/ternop/ternop-3.c       |   9 +-
 .../riscv/rvv/autovec/ternop/ternop-4.c       |   8 +-
 .../riscv/rvv/autovec/ternop/ternop-5.c       |   8 +-
 .../riscv/rvv/autovec/ternop/ternop-6.c       |   9 +-
 .../riscv/rvv/autovec/ternop/ternop-7.c       |  23 +++
 .../riscv/rvv/autovec/ternop/ternop-8.c       |  29 +++
 .../riscv/rvv/autovec/ternop/ternop-9.c       |  28 +++
 .../riscv/rvv/autovec/ternop/ternop_run-1.c   |  12 +-
 .../riscv/rvv/autovec/ternop/ternop_run-10.c  |  40 ++++
 .../riscv/rvv/autovec/ternop/ternop_run-11.c  |  60 ++++++
 .../riscv/rvv/autovec/ternop/ternop_run-12.c  |  60 ++++++
 .../riscv/rvv/autovec/ternop/ternop_run-2.c   |  12 +-
 .../riscv/rvv/autovec/ternop/ternop_run-3.c   |  12 +-
 .../riscv/rvv/autovec/ternop/ternop_run-4.c   |  12 +-
 .../riscv/rvv/autovec/ternop/ternop_run-5.c   |  12 +-
 .../riscv/rvv/autovec/ternop/ternop_run-6.c   |  12 +-
 .../riscv/rvv/autovec/ternop/ternop_run-7.c   |  40 ++++
 .../riscv/rvv/autovec/ternop/ternop_run-8.c   |  60 ++++++
 .../riscv/rvv/autovec/ternop/ternop_run-9.c   |  60 ++++++
 .../rvv/autovec/ternop/ternop_run_zvfh-1.c    |  35 ++++
 .../rvv/autovec/ternop/ternop_run_zvfh-10.c   |  35 ++++
 .../rvv/autovec/ternop/ternop_run_zvfh-11.c   |  55 ++++++
 .../rvv/autovec/ternop/ternop_run_zvfh-12.c   |  55 ++++++
 .../rvv/autovec/ternop/ternop_run_zvfh-2.c    |  55 ++++++
 .../rvv/autovec/ternop/ternop_run_zvfh-3.c    |  55 ++++++
 .../rvv/autovec/ternop/ternop_run_zvfh-4.c    |  35 ++++
 .../rvv/autovec/ternop/ternop_run_zvfh-5.c    |  55 ++++++
 .../rvv/autovec/ternop/ternop_run_zvfh-6.c    |  55 ++++++
 .../rvv/autovec/ternop/ternop_run_zvfh-7.c    |  35 ++++
 .../rvv/autovec/ternop/ternop_run_zvfh-8.c    |  55 ++++++
 .../rvv/autovec/ternop/ternop_run_zvfh-9.c    |  55 ++++++
 40 files changed, 1386 insertions(+), 34 deletions(-)
 create mode 100644 gcc/testsuite/gcc.target/riscv/rvv/autovec/ternop/ternop-10.c
 create mode 100644 gcc/testsuite/gcc.target/riscv/rvv/autovec/ternop/ternop-11.c
 create mode 100644 gcc/testsuite/gcc.target/riscv/rvv/autovec/ternop/ternop-12.c
 create mode 100644 gcc/testsuite/gcc.target/riscv/rvv/autovec/ternop/ternop-7.c
 create mode 100644 gcc/testsuite/gcc.target/riscv/rvv/autovec/ternop/ternop-8.c
 create mode 100644 gcc/testsuite/gcc.target/riscv/rvv/autovec/ternop/ternop-9.c
 create mode 100644 gcc/testsuite/gcc.target/riscv/rvv/autovec/ternop/ternop_run-10.c
 create mode 100644 gcc/testsuite/gcc.target/riscv/rvv/autovec/ternop/ternop_run-11.c
 create mode 100644 gcc/testsuite/gcc.target/riscv/rvv/autovec/ternop/ternop_run-12.c
 create mode 100644 gcc/testsuite/gcc.target/riscv/rvv/autovec/ternop/ternop_run-7.c
 create mode 100644 gcc/testsuite/gcc.target/riscv/rvv/autovec/ternop/ternop_run-8.c
 create mode 100644 gcc/testsuite/gcc.target/riscv/rvv/autovec/ternop/ternop_run-9.c
 create mode 100644 gcc/testsuite/gcc.target/riscv/rvv/autovec/ternop/ternop_run_zvfh-1.c
 create mode 100644 gcc/testsuite/gcc.target/riscv/rvv/autovec/ternop/ternop_run_zvfh-10.c
 create mode 100644 gcc/testsuite/gcc.target/riscv/rvv/autovec/ternop/ternop_run_zvfh-11.c
 create mode 100644 gcc/testsuite/gcc.target/riscv/rvv/autovec/ternop/ternop_run_zvfh-12.c
 create mode 100644 gcc/testsuite/gcc.target/riscv/rvv/autovec/ternop/ternop_run_zvfh-2.c
 create mode 100644 gcc/testsuite/gcc.target/riscv/rvv/autovec/ternop/ternop_run_zvfh-3.c
 create mode 100644 gcc/testsuite/gcc.target/riscv/rvv/autovec/ternop/ternop_run_zvfh-4.c
 create mode 100644 gcc/testsuite/gcc.target/riscv/rvv/autovec/ternop/ternop_run_zvfh-5.c
 create mode 100644 gcc/testsuite/gcc.target/riscv/rvv/autovec/ternop/ternop_run_zvfh-6.c
 create mode 100644 gcc/testsuite/gcc.target/riscv/rvv/autovec/ternop/ternop_run_zvfh-7.c
 create mode 100644 gcc/testsuite/gcc.target/riscv/rvv/autovec/ternop/ternop_run_zvfh-8.c
 create mode 100644 gcc/testsuite/gcc.target/riscv/rvv/autovec/ternop/ternop_run_zvfh-9.c
  

Comments

Jeff Law June 24, 2023, 2:05 p.m. UTC | #1
On 6/21/23 09:53, Juzhe-Zhong wrote:
> This patch adds RVV floating-point auto-vectorization.
> Also, fix attribute bug of floating-point ternary operations in vector.md.
> 
> gcc/ChangeLog:
> 
>          * config/riscv/autovec.md (fma<mode>4): New pattern.
>          (*fma<mode>): Ditto.
>          (fnma<mode>4): Ditto.
>          (*fnma<mode>): Ditto.
>          (fms<mode>4): Ditto.
>          (*fms<mode>): Ditto.
>          (fnms<mode>4): Ditto.
>          (*fnms<mode>): Ditto.
>          * config/riscv/riscv-protos.h (emit_vlmax_fp_ternary_insn): New function.
>          * config/riscv/riscv-v.cc (emit_vlmax_fp_ternary_insn): Ditto.
>          * config/riscv/vector.md: Fix attribute bug.
OK.  Thanks for digging into that clobber issue.

Jeff
  
Li, Pan2 via Gcc-patches June 24, 2023, 2:42 p.m. UTC | #2
Committed, thanks Jeff.

Pan

-----Original Message-----
From: Gcc-patches <gcc-patches-bounces+pan2.li=intel.com@gcc.gnu.org> On Behalf Of Jeff Law via Gcc-patches
Sent: Saturday, June 24, 2023 10:06 PM
To: Juzhe-Zhong <juzhe.zhong@rivai.ai>; gcc-patches@gcc.gnu.org
Cc: kito.cheng@sifive.com; palmer@rivosinc.com; rdapp.gcc@gmail.com
Subject: Re: [PATCH V3] RISC-V: Support RVV floating-point auto-vectorization



On 6/21/23 09:53, Juzhe-Zhong wrote:
> This patch adds RVV floating-point auto-vectorization.
> Also, fix attribute bug of floating-point ternary operations in vector.md.
> 
> gcc/ChangeLog:
> 
>          * config/riscv/autovec.md (fma<mode>4): New pattern.
>          (*fma<mode>): Ditto.
>          (fnma<mode>4): Ditto.
>          (*fnma<mode>): Ditto.
>          (fms<mode>4): Ditto.
>          (*fms<mode>): Ditto.
>          (fnms<mode>4): Ditto.
>          (*fnms<mode>): Ditto.
>          * config/riscv/riscv-protos.h (emit_vlmax_fp_ternary_insn): New function.
>          * config/riscv/riscv-v.cc (emit_vlmax_fp_ternary_insn): Ditto.
>          * config/riscv/vector.md: Fix attribute bug.
OK.  Thanks for digging into that clobber issue.

Jeff
  

Patch

diff --git a/gcc/config/riscv/autovec.md b/gcc/config/riscv/autovec.md
index f1641d7e1ea..cf154b3737a 100644
--- a/gcc/config/riscv/autovec.md
+++ b/gcc/config/riscv/autovec.md
@@ -676,6 +676,190 @@ 
   [(set_attr "type" "vimuladd")
    (set_attr "mode" "<MODE>")])
 
+;; -------------------------------------------------------------------------
+;; ---- [FP] VFMACC and VFMADD
+;; -------------------------------------------------------------------------
+;; Includes:
+;; - vfmacc
+;; - vfmadd
+;; -------------------------------------------------------------------------
+
+(define_expand "fma<mode>4"
+  [(parallel
+    [(set (match_operand:VF_AUTO 0 "register_operand")
+	  (fma:VF_AUTO
+	    (match_operand:VF_AUTO 1 "register_operand")
+	    (match_operand:VF_AUTO 2 "register_operand")
+	    (match_operand:VF_AUTO 3 "register_operand")))
+     (clobber (match_dup 4))])]
+  "TARGET_VECTOR"
+  {
+    operands[4] = gen_reg_rtx (Pmode);
+  })
+
+(define_insn_and_split "*fma<VF_AUTO:mode><P:mode>"
+  [(set (match_operand:VF_AUTO 0 "register_operand"   "=vr, vr, ?&vr")
+	(fma:VF_AUTO
+	  (match_operand:VF_AUTO 1 "register_operand" " %0, vr,   vr")
+	  (match_operand:VF_AUTO 2 "register_operand" " vr, vr,   vr")
+	  (match_operand:VF_AUTO 3 "register_operand" " vr,  0,   vr")))
+   (clobber (match_operand:P 4 "register_operand" "=r,r,r"))]
+  "TARGET_VECTOR"
+  "#"
+  "&& reload_completed"
+  [(const_int 0)]
+  {
+    riscv_vector::emit_vlmax_vsetvl (<VF_AUTO:MODE>mode, operands[4]);
+    if (which_alternative == 2)
+      emit_insn (gen_rtx_SET (operands[0], operands[3]));
+    rtx ops[] = {operands[0], operands[1], operands[2], operands[3], operands[0]};
+    riscv_vector::emit_vlmax_fp_ternary_insn (code_for_pred_mul (PLUS, <VF_AUTO:MODE>mode),
+					      riscv_vector::RVV_TERNOP, ops, operands[4]);
+    DONE;
+  }
+  [(set_attr "type" "vfmuladd")
+   (set_attr "mode" "<VF_AUTO:MODE>")])
+
+;; -------------------------------------------------------------------------
+;; ---- [FP] VFNMSAC and VFNMSUB
+;; -------------------------------------------------------------------------
+;; Includes:
+;; - vfnmsac
+;; - vfnmsub
+;; -------------------------------------------------------------------------
+
+(define_expand "fnma<mode>4"
+  [(parallel
+    [(set (match_operand:VF_AUTO 0 "register_operand")
+	  (fma:VF_AUTO
+	    (neg:VF_AUTO
+	      (match_operand:VF_AUTO 1 "register_operand"))
+	    (match_operand:VF_AUTO 2 "register_operand")
+	    (match_operand:VF_AUTO 3 "register_operand")))
+     (clobber (match_dup 4))])]
+  "TARGET_VECTOR"
+  {
+    operands[4] = gen_reg_rtx (Pmode);
+  })
+
+(define_insn_and_split "*fnma<VF_AUTO:mode><P:mode>"
+  [(set (match_operand:VF_AUTO 0 "register_operand"     "=vr, vr, ?&vr")
+	(fma:VF_AUTO
+	  (neg:VF_AUTO
+	    (match_operand:VF_AUTO 1 "register_operand" " %0, vr,   vr"))
+	  (match_operand:VF_AUTO 2 "register_operand"   " vr, vr,   vr")
+	  (match_operand:VF_AUTO 3 "register_operand"   " vr,  0,   vr")))
+   (clobber (match_operand:P 4 "register_operand" "=r,r,r"))]
+  "TARGET_VECTOR"
+  "#"
+  "&& reload_completed"
+  [(const_int 0)]
+  {
+    riscv_vector::emit_vlmax_vsetvl (<VF_AUTO:MODE>mode, operands[4]);
+    if (which_alternative == 2)
+      emit_insn (gen_rtx_SET (operands[0], operands[3]));
+    rtx ops[] = {operands[0], operands[1], operands[2], operands[3], operands[0]};
+    riscv_vector::emit_vlmax_fp_ternary_insn (code_for_pred_mul_neg (PLUS, <VF_AUTO:MODE>mode),
+					      riscv_vector::RVV_TERNOP, ops, operands[4]);
+    DONE;
+  }
+  [(set_attr "type" "vfmuladd")
+   (set_attr "mode" "<VF_AUTO:MODE>")])
+
+;; -------------------------------------------------------------------------
+;; ---- [FP] VFMSAC and VFMSUB
+;; -------------------------------------------------------------------------
+;; Includes:
+;; - vfmsac
+;; - vfmsub
+;; -------------------------------------------------------------------------
+
+(define_expand "fms<mode>4"
+  [(parallel
+    [(set (match_operand:VF_AUTO 0 "register_operand")
+	  (fma:VF_AUTO
+	    (match_operand:VF_AUTO 1 "register_operand")
+	    (match_operand:VF_AUTO 2 "register_operand")
+	    (neg:VF_AUTO
+	      (match_operand:VF_AUTO 3 "register_operand"))))
+     (clobber (match_dup 4))])]
+  "TARGET_VECTOR"
+  {
+    operands[4] = gen_reg_rtx (Pmode);
+  })
+
+(define_insn_and_split "*fms<VF_AUTO:mode><P:mode>"
+  [(set (match_operand:VF_AUTO 0 "register_operand"     "=vr, vr, ?&vr")
+	(fma:VF_AUTO
+	  (match_operand:VF_AUTO 1 "register_operand"   " %0, vr,   vr")
+	  (match_operand:VF_AUTO 2 "register_operand"   " vr, vr,   vr")
+	  (neg:VF_AUTO
+	    (match_operand:VF_AUTO 3 "register_operand" " vr,  0,   vr"))))
+   (clobber (match_operand:P 4 "register_operand" "=r,r,r"))]
+  "TARGET_VECTOR"
+  "#"
+  "&& reload_completed"
+  [(const_int 0)]
+  {
+    riscv_vector::emit_vlmax_vsetvl (<VF_AUTO:MODE>mode, operands[4]);
+    if (which_alternative == 2)
+      emit_insn (gen_rtx_SET (operands[0], operands[3]));
+    rtx ops[] = {operands[0], operands[1], operands[2], operands[3], operands[0]};
+    riscv_vector::emit_vlmax_fp_ternary_insn (code_for_pred_mul (MINUS, <VF_AUTO:MODE>mode),
+					      riscv_vector::RVV_TERNOP, ops, operands[4]);
+    DONE;
+  }
+  [(set_attr "type" "vfmuladd")
+   (set_attr "mode" "<VF_AUTO:MODE>")])
+
+;; -------------------------------------------------------------------------
+;; ---- [FP] VFMSAC and VFMSUB
+;; -------------------------------------------------------------------------
+;; Includes:
+;; - vfmsac
+;; - vfmsub
+;; -------------------------------------------------------------------------
+
+(define_expand "fnms<mode>4"
+  [(parallel
+    [(set (match_operand:VF_AUTO 0 "register_operand")
+	  (fma:VF_AUTO
+	    (neg:VF_AUTO
+	      (match_operand:VF_AUTO 1 "register_operand"))
+	    (match_operand:VF_AUTO 2 "register_operand")
+	    (neg:VF_AUTO
+	      (match_operand:VF_AUTO 3 "register_operand"))))
+     (clobber (match_dup 4))])]
+  "TARGET_VECTOR"
+  {
+    operands[4] = gen_reg_rtx (Pmode);
+  })
+
+(define_insn_and_split "*fnms<VF_AUTO:mode><P:mode>"
+  [(set (match_operand:VF_AUTO 0 "register_operand"     "=vr, vr, ?&vr")
+	(fma:VF_AUTO
+	  (neg:VF_AUTO
+	    (match_operand:VF_AUTO 1 "register_operand" " %0, vr,   vr"))
+	  (match_operand:VF_AUTO 2 "register_operand"   " vr, vr,   vr")
+	  (neg:VF_AUTO
+	    (match_operand:VF_AUTO 3 "register_operand" " vr,  0,   vr"))))
+   (clobber (match_operand:P 4 "register_operand" "=r,r,r"))]
+  "TARGET_VECTOR"
+  "#"
+  "&& reload_completed"
+  [(const_int 0)]
+  {
+    riscv_vector::emit_vlmax_vsetvl (<VF_AUTO:MODE>mode, operands[4]);
+    if (which_alternative == 2)
+      emit_insn (gen_rtx_SET (operands[0], operands[3]));
+    rtx ops[] = {operands[0], operands[1], operands[2], operands[3], operands[0]};
+    riscv_vector::emit_vlmax_fp_ternary_insn (code_for_pred_mul_neg (MINUS, <VF_AUTO:MODE>mode),
+					      riscv_vector::RVV_TERNOP, ops, operands[4]);
+    DONE;
+  }
+  [(set_attr "type" "vfmuladd")
+   (set_attr "mode" "<VF_AUTO:MODE>")])
+
 ;; =========================================================================
 ;; == SELECT_VL
 ;; =========================================================================
diff --git a/gcc/config/riscv/riscv-protos.h b/gcc/config/riscv/riscv-protos.h
index f052757cede..6d607dc61d1 100644
--- a/gcc/config/riscv/riscv-protos.h
+++ b/gcc/config/riscv/riscv-protos.h
@@ -187,6 +187,7 @@  void emit_hard_vlmax_vsetvl (machine_mode, rtx);
 void emit_vlmax_insn (unsigned, int, rtx *, rtx = 0);
 void emit_vlmax_fp_insn (unsigned, int, rtx *, rtx = 0);
 void emit_vlmax_ternary_insn (unsigned, int, rtx *, rtx = 0);
+void emit_vlmax_fp_ternary_insn (unsigned, int, rtx *, rtx = 0);
 void emit_nonvlmax_insn (unsigned, int, rtx *, rtx);
 void emit_vlmax_slide_insn (unsigned, rtx *);
 void emit_nonvlmax_slide_tu_insn (unsigned, rtx *, rtx);
diff --git a/gcc/config/riscv/riscv-v.cc b/gcc/config/riscv/riscv-v.cc
index 839a2c6ba71..52b9c202ec4 100644
--- a/gcc/config/riscv/riscv-v.cc
+++ b/gcc/config/riscv/riscv-v.cc
@@ -705,19 +705,42 @@  emit_vlmax_ternary_insn (unsigned icode, int op_num, rtx *ops, rtx vl)
 {
   machine_mode dest_mode = GET_MODE (ops[0]);
   machine_mode mask_mode = get_mask_mode (dest_mode).require ();
-  /* We have a maximum of 11 operands for RVV instruction patterns according to
-   * vector.md.  */
-  insn_expander<11> e (/*OP_NUM*/ op_num, /*HAS_DEST_P*/ true,
-		       /*FULLY_UNMASKED_P*/ true,
-		       /*USE_REAL_MERGE_P*/ true, /*HAS_AVL_P*/ true,
-		       /*VLMAX_P*/ true,
-		       /*DEST_MODE*/ dest_mode, /*MASK_MODE*/ mask_mode);
+  insn_expander<RVV_INSN_OPERANDS_MAX> e (/*OP_NUM*/ op_num,
+					  /*HAS_DEST_P*/ true,
+					  /*FULLY_UNMASKED_P*/ true,
+					  /*USE_REAL_MERGE_P*/ true,
+					  /*HAS_AVL_P*/ true,
+					  /*VLMAX_P*/ true,
+					  /*DEST_MODE*/ dest_mode,
+					  /*MASK_MODE*/ mask_mode);
   e.set_policy (TAIL_ANY);
   e.set_policy (MASK_ANY);
   e.set_vl (vl);
   e.emit_insn ((enum insn_code) icode, ops);
 }
 
+/* This function emits a {VLMAX, TAIL_ANY, MASK_ANY} vsetvli followed by the
+ * ternary operation which always has a real merge operand.  */
+void
+emit_vlmax_fp_ternary_insn (unsigned icode, int op_num, rtx *ops, rtx vl)
+{
+  machine_mode dest_mode = GET_MODE (ops[0]);
+  machine_mode mask_mode = get_mask_mode (dest_mode).require ();
+  insn_expander<RVV_INSN_OPERANDS_MAX> e (/*OP_NUM*/ op_num,
+					  /*HAS_DEST_P*/ true,
+					  /*FULLY_UNMASKED_P*/ true,
+					  /*USE_REAL_MERGE_P*/ true,
+					  /*HAS_AVL_P*/ true,
+					  /*VLMAX_P*/ true,
+					  /*DEST_MODE*/ dest_mode,
+					  /*MASK_MODE*/ mask_mode);
+  e.set_policy (TAIL_ANY);
+  e.set_policy (MASK_ANY);
+  e.set_rounding_mode (FRM_DYN);
+  e.set_vl (vl);
+  e.emit_insn ((enum insn_code) icode, ops);
+}
+
 /* This function emits a {NONVLMAX, TAIL_ANY, MASK_ANY} vsetvli followed by the
  * actual operation.  */
 void
@@ -847,11 +870,13 @@  emit_vlmax_masked_mu_insn (unsigned icode, int op_num, rtx *ops)
 {
   machine_mode dest_mode = GET_MODE (ops[0]);
   machine_mode mask_mode = get_mask_mode (dest_mode).require ();
-  insn_expander<11> e (/*OP_NUM*/ op_num, /*HAS_DEST_P*/ true,
-		       /*FULLY_UNMASKED_P*/ false,
-		       /*USE_REAL_MERGE_P*/ true,
-		       /*HAS_AVL_P*/ true,
-		       /*VLMAX_P*/ true, dest_mode, mask_mode);
+  insn_expander<RVV_INSN_OPERANDS_MAX> e (/*OP_NUM*/ op_num,
+					  /*HAS_DEST_P*/ true,
+					  /*FULLY_UNMASKED_P*/ false,
+					  /*USE_REAL_MERGE_P*/ true,
+					  /*HAS_AVL_P*/ true,
+					  /*VLMAX_P*/ true, dest_mode,
+					  mask_mode);
   e.set_policy (TAIL_ANY);
   e.set_policy (MASK_UNDISTURBED);
   e.emit_insn ((enum insn_code) icode, ops);
diff --git a/gcc/config/riscv/vector.md b/gcc/config/riscv/vector.md
index 884e7435cc2..858abdc684c 100644
--- a/gcc/config/riscv/vector.md
+++ b/gcc/config/riscv/vector.md
@@ -425,14 +425,14 @@ 
 	 (eq_attr "type" "vldux,vldox,vialu,vshift,viminmax,vimul,vidiv,vsalu,\
 			  viwalu,viwmul,vnshift,vaalu,vsmul,vsshift,\
 			  vnclip,vicmp,vfalu,vfmul,vfminmax,vfdiv,vfwalu,vfwmul,\
-			  vfsgnj,vfcmp,vfmuladd,vslideup,vslidedown,vislide1up,\
+			  vfsgnj,vfcmp,vslideup,vslidedown,vislide1up,\
 			  vislide1down,vfslide1up,vfslide1down,vgather,viwmuladd,vfwmuladd,\
 			  vlsegds,vlsegdux,vlsegdox")
 	   (symbol_ref "INTVAL (operands[8])")
 	 (eq_attr "type" "vstux,vstox,vssegts,vssegtux,vssegtox")
 	   (symbol_ref "INTVAL (operands[5])")
 
-	 (eq_attr "type" "vimuladd")
+	 (eq_attr "type" "vimuladd,vfmuladd")
 	   (symbol_ref "INTVAL (operands[9])")
 
 	 (eq_attr "type" "vmsfs,vmidx,vcompress")
diff --git a/gcc/testsuite/gcc.target/riscv/rvv/autovec/ternop/ternop-1.c b/gcc/testsuite/gcc.target/riscv/rvv/autovec/ternop/ternop-1.c
index 1996ca65108..442000117b1 100644
--- a/gcc/testsuite/gcc.target/riscv/rvv/autovec/ternop/ternop-1.c
+++ b/gcc/testsuite/gcc.target/riscv/rvv/autovec/ternop/ternop-1.c
@@ -1,5 +1,5 @@ 
 /* { dg-do compile } */
-/* { dg-additional-options "-march=rv32gcv -mabi=ilp32d --param=riscv-autovec-preference=scalable" } */
+/* { dg-additional-options "-march=rv32gcv_zvfh -mabi=ilp32d --param=riscv-autovec-preference=scalable -ffast-math" } */
 
 #include <stdint-gcc.h>
 
@@ -20,9 +20,13 @@ 
   TEST_TYPE (int32_t)                                                          \
   TEST_TYPE (uint32_t)                                                         \
   TEST_TYPE (int64_t)                                                          \
-  TEST_TYPE (uint64_t)
+  TEST_TYPE (uint64_t)                                                         \
+  TEST_TYPE (_Float16)                                                         \
+  TEST_TYPE (float)                                                            \
+  TEST_TYPE (double)
 
 TEST_ALL ()
 
 /* { dg-final { scan-assembler-times {\tvmadd\.vv} 8 } } */
+/* { dg-final { scan-assembler-times {\tvfmadd\.vv} 3 } } */
 /* { dg-final { scan-assembler-not {\tvmv} } } */
diff --git a/gcc/testsuite/gcc.target/riscv/rvv/autovec/ternop/ternop-10.c b/gcc/testsuite/gcc.target/riscv/rvv/autovec/ternop/ternop-10.c
new file mode 100644
index 00000000000..fc66def0577
--- /dev/null
+++ b/gcc/testsuite/gcc.target/riscv/rvv/autovec/ternop/ternop-10.c
@@ -0,0 +1,23 @@ 
+/* { dg-do compile } */
+/* { dg-additional-options "-march=rv32gcv_zvfh -mabi=ilp32d --param=riscv-autovec-preference=scalable -ffast-math" } */
+
+#include <stdint-gcc.h>
+
+#define TEST_TYPE(TYPE)                                                        \
+  __attribute__ ((noipa)) void ternop_##TYPE (TYPE *__restrict dst,            \
+					      TYPE *__restrict a,              \
+					      TYPE *__restrict b, int n)       \
+  {                                                                            \
+    for (int i = 0; i < n; i++)                                                \
+      dst[i] = -(a[i] * b[i]) - dst[i];                                        \
+  }
+
+#define TEST_ALL()                                                             \
+  TEST_TYPE (_Float16)                                                         \
+  TEST_TYPE (float)                                                            \
+  TEST_TYPE (double)
+
+TEST_ALL ()
+
+/* { dg-final { scan-assembler-times {\tvfnmadd\.vv} 3 } } */
+/* { dg-final { scan-assembler-not {\tvmv} } } */
diff --git a/gcc/testsuite/gcc.target/riscv/rvv/autovec/ternop/ternop-11.c b/gcc/testsuite/gcc.target/riscv/rvv/autovec/ternop/ternop-11.c
new file mode 100644
index 00000000000..23c542f9f27
--- /dev/null
+++ b/gcc/testsuite/gcc.target/riscv/rvv/autovec/ternop/ternop-11.c
@@ -0,0 +1,29 @@ 
+/* { dg-do compile } */
+/* { dg-additional-options "-march=rv32gcv_zvfh -mabi=ilp32d --param=riscv-autovec-preference=scalable -fno-schedule-insns -ffast-math" } */
+
+#include <stdint-gcc.h>
+
+#define TEST_TYPE(TYPE)                                                        \
+  __attribute__ ((noipa)) void ternop_##TYPE (TYPE *__restrict dest1,          \
+					      TYPE *__restrict dest2,          \
+					      TYPE *__restrict dest3,          \
+					      TYPE *__restrict src1,           \
+					      TYPE *__restrict src2, int n)    \
+  {                                                                            \
+    for (int i = 0; i < n; ++i)                                                \
+      {                                                                        \
+	dest1[i] = -(src1[i] * src2[i]) - dest1[i];                            \
+	dest2[i] = src1[i] * dest1[i] - dest2[i];                              \
+	dest3[i] = src2[i] * dest2[i] - dest3[i];                              \
+      }                                                                        \
+  }
+
+#define TEST_ALL()                                                             \
+  TEST_TYPE (_Float16)                                                         \
+  TEST_TYPE (float)                                                            \
+  TEST_TYPE (double)
+
+TEST_ALL ()
+
+/* { dg-final { scan-assembler-times {\tvfnmacc\.vv} 3 } } */
+/* { dg-final { scan-assembler-not {\tvmv} } } */
diff --git a/gcc/testsuite/gcc.target/riscv/rvv/autovec/ternop/ternop-12.c b/gcc/testsuite/gcc.target/riscv/rvv/autovec/ternop/ternop-12.c
new file mode 100644
index 00000000000..8ec261b799a
--- /dev/null
+++ b/gcc/testsuite/gcc.target/riscv/rvv/autovec/ternop/ternop-12.c
@@ -0,0 +1,28 @@ 
+/* { dg-do compile } */
+/* { dg-additional-options "-march=rv32gcv_zvfh -mabi=ilp32d --param=riscv-autovec-preference=scalable -ffast-math" } */
+
+#include <stdint-gcc.h>
+
+#define TEST_TYPE(TYPE)                                                        \
+  __attribute__ ((noipa)) void ternop_##TYPE (TYPE *__restrict dest1,          \
+					      TYPE *__restrict dest2,          \
+					      TYPE *__restrict dest3,          \
+					      TYPE *__restrict src1,           \
+					      TYPE *__restrict src2, int n)    \
+  {                                                                            \
+    for (int i = 0; i < n; ++i)                                                \
+      {                                                                        \
+	dest1[i] = -(src1[i] * src2[i]) - dest2[i];                            \
+	dest2[i] = src1[i] * dest1[i] - dest2[i];                              \
+	dest3[i] = src2[i] * dest2[i] - dest3[i];                              \
+      }                                                                        \
+  }
+
+#define TEST_ALL()                                                             \
+  TEST_TYPE (_Float16)                                                         \
+  TEST_TYPE (float)                                                            \
+  TEST_TYPE (double)
+
+TEST_ALL ()
+
+/* { dg-final { scan-assembler-times {\tvmv} 3 } } */
diff --git a/gcc/testsuite/gcc.target/riscv/rvv/autovec/ternop/ternop-2.c b/gcc/testsuite/gcc.target/riscv/rvv/autovec/ternop/ternop-2.c
index e52e07ddd09..ad2673a05bc 100644
--- a/gcc/testsuite/gcc.target/riscv/rvv/autovec/ternop/ternop-2.c
+++ b/gcc/testsuite/gcc.target/riscv/rvv/autovec/ternop/ternop-2.c
@@ -1,5 +1,5 @@ 
 /* { dg-do compile } */
-/* { dg-additional-options "-march=rv32gcv -mabi=ilp32d --param=riscv-autovec-preference=scalable -fno-schedule-insns" } */
+/* { dg-additional-options "-march=rv32gcv_zvfh -mabi=ilp32d --param=riscv-autovec-preference=scalable -fno-schedule-insns -ffast-math" } */
 
 #include <stdint-gcc.h>
 
@@ -26,9 +26,13 @@ 
   TEST_TYPE (int32_t)                                                          \
   TEST_TYPE (uint32_t)                                                         \
   TEST_TYPE (int64_t)                                                          \
-  TEST_TYPE (uint64_t)
+  TEST_TYPE (uint64_t)                                                         \
+  TEST_TYPE (_Float16)                                                         \
+  TEST_TYPE (float)                                                            \
+  TEST_TYPE (double)
 
 TEST_ALL ()
 
 /* { dg-final { scan-assembler-times {\tvmacc\.vv} 8 } } */
+/* { dg-final { scan-assembler-times {\tvfmacc\.vv} 3 } } */
 /* { dg-final { scan-assembler-not {\tvmv} } } */
diff --git a/gcc/testsuite/gcc.target/riscv/rvv/autovec/ternop/ternop-3.c b/gcc/testsuite/gcc.target/riscv/rvv/autovec/ternop/ternop-3.c
index 127e701b187..cd97f4d980e 100644
--- a/gcc/testsuite/gcc.target/riscv/rvv/autovec/ternop/ternop-3.c
+++ b/gcc/testsuite/gcc.target/riscv/rvv/autovec/ternop/ternop-3.c
@@ -1,5 +1,5 @@ 
 /* { dg-do compile } */
-/* { dg-additional-options "-march=rv32gcv -mabi=ilp32d --param=riscv-autovec-preference=scalable" } */
+/* { dg-additional-options "-march=rv32gcv_zvfh -mabi=ilp32d --param=riscv-autovec-preference=scalable -ffast-math" } */
 
 #include <stdint-gcc.h>
 
@@ -26,8 +26,11 @@ 
   TEST_TYPE (int32_t)                                                          \
   TEST_TYPE (uint32_t)                                                         \
   TEST_TYPE (int64_t)                                                          \
-  TEST_TYPE (uint64_t)
+  TEST_TYPE (uint64_t)                                                         \
+  TEST_TYPE (_Float16)                                                         \
+  TEST_TYPE (float)                                                            \
+  TEST_TYPE (double)
 
 TEST_ALL ()
 
-/* { dg-final { scan-assembler-times {\tvmv} 8 } } */
+/* { dg-final { scan-assembler-times {\tvmv} 11 } } */
diff --git a/gcc/testsuite/gcc.target/riscv/rvv/autovec/ternop/ternop-4.c b/gcc/testsuite/gcc.target/riscv/rvv/autovec/ternop/ternop-4.c
index 1b8b934149e..a225ea0757b 100644
--- a/gcc/testsuite/gcc.target/riscv/rvv/autovec/ternop/ternop-4.c
+++ b/gcc/testsuite/gcc.target/riscv/rvv/autovec/ternop/ternop-4.c
@@ -1,5 +1,5 @@ 
 /* { dg-do compile } */
-/* { dg-additional-options "-march=rv32gcv -mabi=ilp32d --param=riscv-autovec-preference=scalable" } */
+/* { dg-additional-options "-march=rv32gcv_zvfh -mabi=ilp32d --param=riscv-autovec-preference=scalable -ffast-math" } */
 
 #include <stdint-gcc.h>
 
@@ -20,9 +20,13 @@ 
   TEST_TYPE (int32_t)                                                          \
   TEST_TYPE (uint32_t)                                                         \
   TEST_TYPE (int64_t)                                                          \
-  TEST_TYPE (uint64_t)
+  TEST_TYPE (uint64_t)                                                         \
+  TEST_TYPE (_Float16)                                                         \
+  TEST_TYPE (float)                                                            \
+  TEST_TYPE (double)
 
 TEST_ALL ()
 
 /* { dg-final { scan-assembler-times {\tvnmsub\.vv} 8 } } */
+/* { dg-final { scan-assembler-times {\tvfnmsub\.vv} 3 } } */
 /* { dg-final { scan-assembler-not {\tvmv} } } */
diff --git a/gcc/testsuite/gcc.target/riscv/rvv/autovec/ternop/ternop-5.c b/gcc/testsuite/gcc.target/riscv/rvv/autovec/ternop/ternop-5.c
index 49c85efbf3a..12dfa0ac21d 100644
--- a/gcc/testsuite/gcc.target/riscv/rvv/autovec/ternop/ternop-5.c
+++ b/gcc/testsuite/gcc.target/riscv/rvv/autovec/ternop/ternop-5.c
@@ -1,5 +1,5 @@ 
 /* { dg-do compile } */
-/* { dg-additional-options "-march=rv32gcv -mabi=ilp32d --param=riscv-autovec-preference=scalable -fno-schedule-insns" } */
+/* { dg-additional-options "-march=rv32gcv_zvfh -mabi=ilp32d --param=riscv-autovec-preference=scalable -fno-schedule-insns -ffast-math" } */
 
 #include <stdint-gcc.h>
 
@@ -26,9 +26,13 @@ 
   TEST_TYPE (int32_t)                                                          \
   TEST_TYPE (uint32_t)                                                         \
   TEST_TYPE (int64_t)                                                          \
-  TEST_TYPE (uint64_t)
+  TEST_TYPE (uint64_t)                                                         \
+  TEST_TYPE (_Float16)                                                         \
+  TEST_TYPE (float)                                                            \
+  TEST_TYPE (double)
 
 TEST_ALL ()
 
 /* { dg-final { scan-assembler-times {\tvnmsac\.vv} 8 } } */
+/* { dg-final { scan-assembler-times {\tvfnmsac\.vv} 3 } } */
 /* { dg-final { scan-assembler-not {\tvmv} } } */
diff --git a/gcc/testsuite/gcc.target/riscv/rvv/autovec/ternop/ternop-6.c b/gcc/testsuite/gcc.target/riscv/rvv/autovec/ternop/ternop-6.c
index f38f303574f..b83590f1a46 100644
--- a/gcc/testsuite/gcc.target/riscv/rvv/autovec/ternop/ternop-6.c
+++ b/gcc/testsuite/gcc.target/riscv/rvv/autovec/ternop/ternop-6.c
@@ -1,5 +1,5 @@ 
 /* { dg-do compile } */
-/* { dg-additional-options "-march=rv32gcv -mabi=ilp32d --param=riscv-autovec-preference=scalable" } */
+/* { dg-additional-options "-march=rv32gcv_zvfh -mabi=ilp32d --param=riscv-autovec-preference=scalable -ffast-math" } */
 
 #include <stdint-gcc.h>
 
@@ -26,8 +26,11 @@ 
   TEST_TYPE (int32_t)                                                          \
   TEST_TYPE (uint32_t)                                                         \
   TEST_TYPE (int64_t)                                                          \
-  TEST_TYPE (uint64_t)
+  TEST_TYPE (uint64_t)                                                         \
+  TEST_TYPE (_Float16)                                                         \
+  TEST_TYPE (float)                                                            \
+  TEST_TYPE (double)
 
 TEST_ALL ()
 
-/* { dg-final { scan-assembler-times {\tvmv} 8 } } */
+/* { dg-final { scan-assembler-times {\tvmv} 11 } } */
diff --git a/gcc/testsuite/gcc.target/riscv/rvv/autovec/ternop/ternop-7.c b/gcc/testsuite/gcc.target/riscv/rvv/autovec/ternop/ternop-7.c
new file mode 100644
index 00000000000..0f80da4a69d
--- /dev/null
+++ b/gcc/testsuite/gcc.target/riscv/rvv/autovec/ternop/ternop-7.c
@@ -0,0 +1,23 @@ 
+/* { dg-do compile } */
+/* { dg-additional-options "-march=rv32gcv_zvfh -mabi=ilp32d --param=riscv-autovec-preference=scalable -ffast-math" } */
+
+#include <stdint-gcc.h>
+
+#define TEST_TYPE(TYPE)                                                        \
+  __attribute__ ((noipa)) void ternop_##TYPE (TYPE *__restrict dst,            \
+					      TYPE *__restrict a,              \
+					      TYPE *__restrict b, int n)       \
+  {                                                                            \
+    for (int i = 0; i < n; i++)                                                \
+      dst[i] = a[i] * b[i] - dst[i];                                           \
+  }
+
+#define TEST_ALL()                                                             \
+  TEST_TYPE (_Float16)                                                         \
+  TEST_TYPE (float)                                                            \
+  TEST_TYPE (double)
+
+TEST_ALL ()
+
+/* { dg-final { scan-assembler-times {\tvfmsub\.vv} 3 } } */
+/* { dg-final { scan-assembler-not {\tvmv} } } */
diff --git a/gcc/testsuite/gcc.target/riscv/rvv/autovec/ternop/ternop-8.c b/gcc/testsuite/gcc.target/riscv/rvv/autovec/ternop/ternop-8.c
new file mode 100644
index 00000000000..ae65298f06a
--- /dev/null
+++ b/gcc/testsuite/gcc.target/riscv/rvv/autovec/ternop/ternop-8.c
@@ -0,0 +1,29 @@ 
+/* { dg-do compile } */
+/* { dg-additional-options "-march=rv32gcv_zvfh -mabi=ilp32d --param=riscv-autovec-preference=scalable -fno-schedule-insns -ffast-math" } */
+
+#include <stdint-gcc.h>
+
+#define TEST_TYPE(TYPE)                                                        \
+  __attribute__ ((noipa)) void ternop_##TYPE (TYPE *__restrict dest1,          \
+					      TYPE *__restrict dest2,          \
+					      TYPE *__restrict dest3,          \
+					      TYPE *__restrict src1,           \
+					      TYPE *__restrict src2, int n)    \
+  {                                                                            \
+    for (int i = 0; i < n; ++i)                                                \
+      {                                                                        \
+	dest1[i] = src1[i] * src2[i] - dest1[i];                               \
+	dest2[i] = src1[i] * dest1[i] - dest2[i];                              \
+	dest3[i] = src2[i] * dest2[i] - dest3[i];                              \
+      }                                                                        \
+  }
+
+#define TEST_ALL()                                                             \
+  TEST_TYPE (_Float16)                                                         \
+  TEST_TYPE (float)                                                            \
+  TEST_TYPE (double)
+
+TEST_ALL ()
+
+/* { dg-final { scan-assembler-times {\tvfmsac\.vv} 3 } } */
+/* { dg-final { scan-assembler-not {\tvmv} } } */
diff --git a/gcc/testsuite/gcc.target/riscv/rvv/autovec/ternop/ternop-9.c b/gcc/testsuite/gcc.target/riscv/rvv/autovec/ternop/ternop-9.c
new file mode 100644
index 00000000000..299bd2dbcec
--- /dev/null
+++ b/gcc/testsuite/gcc.target/riscv/rvv/autovec/ternop/ternop-9.c
@@ -0,0 +1,28 @@ 
+/* { dg-do compile } */
+/* { dg-additional-options "-march=rv32gcv_zvfh -mabi=ilp32d --param=riscv-autovec-preference=scalable -ffast-math" } */
+
+#include <stdint-gcc.h>
+
+#define TEST_TYPE(TYPE)                                                        \
+  __attribute__ ((noipa)) void ternop_##TYPE (TYPE *__restrict dest1,          \
+					      TYPE *__restrict dest2,          \
+					      TYPE *__restrict dest3,          \
+					      TYPE *__restrict src1,           \
+					      TYPE *__restrict src2, int n)    \
+  {                                                                            \
+    for (int i = 0; i < n; ++i)                                                \
+      {                                                                        \
+	dest1[i] = src1[i] * src2[i] - dest2[i];                               \
+	dest2[i] = src1[i] * dest1[i] - dest2[i];                              \
+	dest3[i] = src2[i] * dest2[i] - dest3[i];                              \
+      }                                                                        \
+  }
+
+#define TEST_ALL()                                                             \
+  TEST_TYPE (_Float16)                                                         \
+  TEST_TYPE (float)                                                            \
+  TEST_TYPE (double)
+
+TEST_ALL ()
+
+/* { dg-final { scan-assembler-times {\tvmv} 3 } } */
diff --git a/gcc/testsuite/gcc.target/riscv/rvv/autovec/ternop/ternop_run-1.c b/gcc/testsuite/gcc.target/riscv/rvv/autovec/ternop/ternop_run-1.c
index 1f69b694818..e0ec9ed48dd 100644
--- a/gcc/testsuite/gcc.target/riscv/rvv/autovec/ternop/ternop_run-1.c
+++ b/gcc/testsuite/gcc.target/riscv/rvv/autovec/ternop/ternop_run-1.c
@@ -1,5 +1,5 @@ 
 /* { dg-do run { target { riscv_vector } } } */
-/* { dg-additional-options "--param=riscv-autovec-preference=scalable" } */
+/* { dg-additional-options "--param=riscv-autovec-preference=scalable -ffast-math" } */
 
 #include "ternop-1.c"
 
@@ -80,5 +80,15 @@  int __attribute__ ((optimize (0))) main ()
   TEST_LOOP (int64_t, 795)
   TEST_LOOP (uint64_t, 795)
 
+  TEST_LOOP (float, 7)
+  TEST_LOOP (double, 7)
+  TEST_LOOP (float, 16)
+  TEST_LOOP (double, 16)
+  TEST_LOOP (float, 77)
+  TEST_LOOP (double, 77)
+  TEST_LOOP (float, 128)
+  TEST_LOOP (double, 128)
+  TEST_LOOP (float, 795)
+  TEST_LOOP (double, 795)
   return 0;
 }
diff --git a/gcc/testsuite/gcc.target/riscv/rvv/autovec/ternop/ternop_run-10.c b/gcc/testsuite/gcc.target/riscv/rvv/autovec/ternop/ternop_run-10.c
new file mode 100644
index 00000000000..854827fd465
--- /dev/null
+++ b/gcc/testsuite/gcc.target/riscv/rvv/autovec/ternop/ternop_run-10.c
@@ -0,0 +1,40 @@ 
+/* { dg-do run { target { riscv_vector } } } */
+/* { dg-additional-options "--param=riscv-autovec-preference=scalable -ffast-math" } */
+
+#include "ternop-10.c"
+
+#define TEST_LOOP(TYPE, NUM)                                                   \
+  {                                                                            \
+    TYPE array1_##NUM[NUM] = {};                                               \
+    TYPE array2_##NUM[NUM] = {};                                               \
+    TYPE array3_##NUM[NUM] = {};                                               \
+    TYPE array4_##NUM[NUM] = {};                                               \
+    for (int i = 0; i < NUM; ++i)                                              \
+      {                                                                        \
+ array1_##NUM[i] = (i & 1) + 5;                                         \
+ array2_##NUM[i] = i - NUM / 3;                                         \
+ array3_##NUM[i] = NUM - NUM / 3 - i;                                   \
+ array4_##NUM[i] = NUM - NUM / 3 - i;                                   \
+ asm volatile("" ::: "memory");                                         \
+      }                                                                        \
+    ternop_##TYPE (array3_##NUM, array1_##NUM, array2_##NUM, NUM);             \
+    for (int i = 0; i < NUM; i++)                                              \
+      if (array3_##NUM[i]                                                      \
+   != (TYPE) (-(array1_##NUM[i] * array2_##NUM[i]) - array4_##NUM[i]))  \
+ __builtin_abort ();                                                    \
+  }
+
+int __attribute__ ((optimize (0))) main ()
+{
+  TEST_LOOP (float, 7)
+  TEST_LOOP (double, 7)
+  TEST_LOOP (float, 16)
+  TEST_LOOP (double, 16)
+  TEST_LOOP (float, 77)
+  TEST_LOOP (double, 77)
+  TEST_LOOP (float, 128)
+  TEST_LOOP (double, 128)
+  TEST_LOOP (float, 795)
+  TEST_LOOP (double, 795)
+  return 0;
+}
diff --git a/gcc/testsuite/gcc.target/riscv/rvv/autovec/ternop/ternop_run-11.c b/gcc/testsuite/gcc.target/riscv/rvv/autovec/ternop/ternop_run-11.c
new file mode 100644
index 00000000000..b5a0845026b
--- /dev/null
+++ b/gcc/testsuite/gcc.target/riscv/rvv/autovec/ternop/ternop_run-11.c
@@ -0,0 +1,60 @@ 
+/* { dg-do run { target { riscv_vector } } } */
+/* { dg-additional-options "--param=riscv-autovec-preference=scalable -ffast-math" } */
+
+#include "ternop-11.c"
+
+#define TEST_LOOP(TYPE, NUM)                                                   \
+  {                                                                            \
+    TYPE array1_##NUM[NUM] = {};                                               \
+    TYPE array2_##NUM[NUM] = {};                                               \
+    TYPE array3_##NUM[NUM] = {};                                               \
+    TYPE array4_##NUM[NUM] = {};                                               \
+    TYPE array5_##NUM[NUM] = {};                                               \
+    TYPE array6_##NUM[NUM] = {};                                               \
+    TYPE array7_##NUM[NUM] = {};                                               \
+    TYPE array8_##NUM[NUM] = {};                                               \
+    for (int i = 0; i < NUM; ++i)                                              \
+      {                                                                        \
+ array1_##NUM[i] = (i & 1) + 5;                                         \
+ array2_##NUM[i] = i - NUM / 3;                                         \
+ array3_##NUM[i] = NUM - NUM / 3 - i;                                   \
+ array6_##NUM[i] = NUM - NUM / 3 - i;                                   \
+ array4_##NUM[i] = NUM - NUM / 2 + i;                                   \
+ array7_##NUM[i] = NUM - NUM / 2 + i;                                   \
+ array5_##NUM[i] = NUM + i * 7;                                         \
+ array8_##NUM[i] = NUM + i * 7;                                         \
+ asm volatile("" ::: "memory");                                         \
+      }                                                                        \
+    ternop_##TYPE (array3_##NUM, array4_##NUM, array5_##NUM, array1_##NUM,     \
+    array2_##NUM, NUM);                                         \
+    for (int i = 0; i < NUM; i++)                                              \
+      {                                                                        \
+ array6_##NUM[i]                                                        \
+   = (TYPE) (-(array1_##NUM[i] * array2_##NUM[i]) - array6_##NUM[i]);   \
+ if (array3_##NUM[i] != array6_##NUM[i])                                \
+   __builtin_abort ();                                                  \
+ array7_##NUM[i]                                                        \
+   = (TYPE) (array1_##NUM[i] * array6_##NUM[i] - array7_##NUM[i]);      \
+ if (array4_##NUM[i] != array7_##NUM[i])                                \
+   __builtin_abort ();                                                  \
+ array8_##NUM[i]                                                        \
+   = (TYPE) (array2_##NUM[i] * array7_##NUM[i] - array8_##NUM[i]);      \
+ if (array5_##NUM[i] != array8_##NUM[i])                                \
+   __builtin_abort ();                                                  \
+      }                                                                        \
+  }
+
+int __attribute__ ((optimize (0))) main ()
+{
+  TEST_LOOP (float, 7)
+  TEST_LOOP (double, 7)
+  TEST_LOOP (float, 16)
+  TEST_LOOP (double, 16)
+  TEST_LOOP (float, 77)
+  TEST_LOOP (double, 77)
+  TEST_LOOP (float, 128)
+  TEST_LOOP (double, 128)
+  TEST_LOOP (float, 795)
+  TEST_LOOP (double, 795)
+  return 0;
+}
diff --git a/gcc/testsuite/gcc.target/riscv/rvv/autovec/ternop/ternop_run-12.c b/gcc/testsuite/gcc.target/riscv/rvv/autovec/ternop/ternop_run-12.c
new file mode 100644
index 00000000000..c7c4b4b50f0
--- /dev/null
+++ b/gcc/testsuite/gcc.target/riscv/rvv/autovec/ternop/ternop_run-12.c
@@ -0,0 +1,60 @@ 
+/* { dg-do run { target { riscv_vector } } } */
+/* { dg-additional-options "--param=riscv-autovec-preference=scalable -ffast-math" } */
+
+#include "ternop-12.c"
+
+#define TEST_LOOP(TYPE, NUM)                                                   \
+  {                                                                            \
+    TYPE array1_##NUM[NUM] = {};                                               \
+    TYPE array2_##NUM[NUM] = {};                                               \
+    TYPE array3_##NUM[NUM] = {};                                               \
+    TYPE array4_##NUM[NUM] = {};                                               \
+    TYPE array5_##NUM[NUM] = {};                                               \
+    TYPE array6_##NUM[NUM] = {};                                               \
+    TYPE array7_##NUM[NUM] = {};                                               \
+    TYPE array8_##NUM[NUM] = {};                                               \
+    for (int i = 0; i < NUM; ++i)                                              \
+      {                                                                        \
+ array1_##NUM[i] = (i & 1) + 5;                                         \
+ array2_##NUM[i] = i - NUM / 3;                                         \
+ array3_##NUM[i] = NUM - NUM / 3 - i;                                   \
+ array6_##NUM[i] = NUM - NUM / 3 - i;                                   \
+ array4_##NUM[i] = NUM - NUM / 2 + i;                                   \
+ array7_##NUM[i] = NUM - NUM / 2 + i;                                   \
+ array5_##NUM[i] = NUM + i * 7;                                         \
+ array8_##NUM[i] = NUM + i * 7;                                         \
+ asm volatile("" ::: "memory");                                         \
+      }                                                                        \
+    ternop_##TYPE (array3_##NUM, array4_##NUM, array5_##NUM, array1_##NUM,     \
+    array2_##NUM, NUM);                                         \
+    for (int i = 0; i < NUM; i++)                                              \
+      {                                                                        \
+ array6_##NUM[i]                                                        \
+   = (TYPE) (-(array1_##NUM[i] * array2_##NUM[i]) - array7_##NUM[i]);   \
+ if (array3_##NUM[i] != array6_##NUM[i])                                \
+   __builtin_abort ();                                                  \
+ array7_##NUM[i]                                                        \
+   = (TYPE) (array1_##NUM[i] * array6_##NUM[i] - array7_##NUM[i]);      \
+ if (array4_##NUM[i] != array7_##NUM[i])                                \
+   __builtin_abort ();                                                  \
+ array8_##NUM[i]                                                        \
+   = (TYPE) (array2_##NUM[i] * array7_##NUM[i] - array8_##NUM[i]);      \
+ if (array5_##NUM[i] != array8_##NUM[i])                                \
+   __builtin_abort ();                                                  \
+      }                                                                        \
+  }
+
+int __attribute__ ((optimize (0))) main ()
+{
+  TEST_LOOP (float, 7)
+  TEST_LOOP (double, 7)
+  TEST_LOOP (float, 16)
+  TEST_LOOP (double, 16)
+  TEST_LOOP (float, 77)
+  TEST_LOOP (double, 77)
+  TEST_LOOP (float, 128)
+  TEST_LOOP (double, 128)
+  TEST_LOOP (float, 795)
+  TEST_LOOP (double, 795)
+  return 0;
+}
diff --git a/gcc/testsuite/gcc.target/riscv/rvv/autovec/ternop/ternop_run-2.c b/gcc/testsuite/gcc.target/riscv/rvv/autovec/ternop/ternop_run-2.c
index 103b98acdf0..ee7c7251698 100644
--- a/gcc/testsuite/gcc.target/riscv/rvv/autovec/ternop/ternop_run-2.c
+++ b/gcc/testsuite/gcc.target/riscv/rvv/autovec/ternop/ternop_run-2.c
@@ -1,5 +1,5 @@ 
 /* { dg-do run { target { riscv_vector } } } */
-/* { dg-additional-options "--param=riscv-autovec-preference=scalable" } */
+/* { dg-additional-options "--param=riscv-autovec-preference=scalable -ffast-math" } */
 
 #include "ternop-2.c"
 
@@ -100,5 +100,15 @@  int __attribute__ ((optimize (0))) main ()
   TEST_LOOP (int64_t, 795)
   TEST_LOOP (uint64_t, 795)
 
+  TEST_LOOP (float, 7)
+  TEST_LOOP (double, 7)
+  TEST_LOOP (float, 16)
+  TEST_LOOP (double, 16)
+  TEST_LOOP (float, 77)
+  TEST_LOOP (double, 77)
+  TEST_LOOP (float, 128)
+  TEST_LOOP (double, 128)
+  TEST_LOOP (float, 795)
+  TEST_LOOP (double, 795)
   return 0;
 }
diff --git a/gcc/testsuite/gcc.target/riscv/rvv/autovec/ternop/ternop_run-3.c b/gcc/testsuite/gcc.target/riscv/rvv/autovec/ternop/ternop_run-3.c
index eac5408ce6f..6c4f28e8c02 100644
--- a/gcc/testsuite/gcc.target/riscv/rvv/autovec/ternop/ternop_run-3.c
+++ b/gcc/testsuite/gcc.target/riscv/rvv/autovec/ternop/ternop_run-3.c
@@ -1,5 +1,5 @@ 
 /* { dg-do run { target { riscv_vector } } } */
-/* { dg-additional-options "--param=riscv-autovec-preference=scalable" } */
+/* { dg-additional-options "--param=riscv-autovec-preference=scalable -ffast-math" } */
 
 #include "ternop-3.c"
 
@@ -100,5 +100,15 @@  int __attribute__ ((optimize (0))) main ()
   TEST_LOOP (int64_t, 795)
   TEST_LOOP (uint64_t, 795)
 
+  TEST_LOOP (float, 7)
+  TEST_LOOP (double, 7)
+  TEST_LOOP (float, 16)
+  TEST_LOOP (double, 16)
+  TEST_LOOP (float, 77)
+  TEST_LOOP (double, 77)
+  TEST_LOOP (float, 128)
+  TEST_LOOP (double, 128)
+  TEST_LOOP (float, 795)
+  TEST_LOOP (double, 795)
   return 0;
 }
diff --git a/gcc/testsuite/gcc.target/riscv/rvv/autovec/ternop/ternop_run-4.c b/gcc/testsuite/gcc.target/riscv/rvv/autovec/ternop/ternop_run-4.c
index c6f1fe591f3..44a4771cb84 100644
--- a/gcc/testsuite/gcc.target/riscv/rvv/autovec/ternop/ternop_run-4.c
+++ b/gcc/testsuite/gcc.target/riscv/rvv/autovec/ternop/ternop_run-4.c
@@ -1,5 +1,5 @@ 
 /* { dg-do run { target { riscv_vector } } } */
-/* { dg-additional-options "--param=riscv-autovec-preference=scalable" } */
+/* { dg-additional-options "--param=riscv-autovec-preference=scalable -ffast-math" } */
 
 #include "ternop-4.c"
 
@@ -80,5 +80,15 @@  int __attribute__ ((optimize (0))) main ()
   TEST_LOOP (int64_t, 795)
   TEST_LOOP (uint64_t, 795)
 
+  TEST_LOOP (float, 7)
+  TEST_LOOP (double, 7)
+  TEST_LOOP (float, 16)
+  TEST_LOOP (double, 16)
+  TEST_LOOP (float, 77)
+  TEST_LOOP (double, 77)
+  TEST_LOOP (float, 128)
+  TEST_LOOP (double, 128)
+  TEST_LOOP (float, 795)
+  TEST_LOOP (double, 795)
   return 0;
 }
diff --git a/gcc/testsuite/gcc.target/riscv/rvv/autovec/ternop/ternop_run-5.c b/gcc/testsuite/gcc.target/riscv/rvv/autovec/ternop/ternop_run-5.c
index 81af4b672a5..efe2f362189 100644
--- a/gcc/testsuite/gcc.target/riscv/rvv/autovec/ternop/ternop_run-5.c
+++ b/gcc/testsuite/gcc.target/riscv/rvv/autovec/ternop/ternop_run-5.c
@@ -1,5 +1,5 @@ 
 /* { dg-do run { target { riscv_vector } } } */
-/* { dg-additional-options "--param=riscv-autovec-preference=scalable" } */
+/* { dg-additional-options "--param=riscv-autovec-preference=scalable -ffast-math" } */
 
 #include "ternop-5.c"
 
@@ -100,5 +100,15 @@  int __attribute__ ((optimize (0))) main ()
   TEST_LOOP (int64_t, 795)
   TEST_LOOP (uint64_t, 795)
 
+  TEST_LOOP (float, 7)
+  TEST_LOOP (double, 7)
+  TEST_LOOP (float, 16)
+  TEST_LOOP (double, 16)
+  TEST_LOOP (float, 77)
+  TEST_LOOP (double, 77)
+  TEST_LOOP (float, 128)
+  TEST_LOOP (double, 128)
+  TEST_LOOP (float, 795)
+  TEST_LOOP (double, 795)
   return 0;
 }
diff --git a/gcc/testsuite/gcc.target/riscv/rvv/autovec/ternop/ternop_run-6.c b/gcc/testsuite/gcc.target/riscv/rvv/autovec/ternop/ternop_run-6.c
index b5e579ef55a..f1ce6a756ac 100644
--- a/gcc/testsuite/gcc.target/riscv/rvv/autovec/ternop/ternop_run-6.c
+++ b/gcc/testsuite/gcc.target/riscv/rvv/autovec/ternop/ternop_run-6.c
@@ -1,5 +1,5 @@ 
 /* { dg-do run { target { riscv_vector } } } */
-/* { dg-additional-options "--param=riscv-autovec-preference=scalable" } */
+/* { dg-additional-options "--param=riscv-autovec-preference=scalable -ffast-math" } */
 
 #include "ternop-6.c"
 
@@ -100,5 +100,15 @@  int __attribute__ ((optimize (0))) main ()
   TEST_LOOP (int64_t, 795)
   TEST_LOOP (uint64_t, 795)
 
+  TEST_LOOP (float, 7)
+  TEST_LOOP (double, 7)
+  TEST_LOOP (float, 16)
+  TEST_LOOP (double, 16)
+  TEST_LOOP (float, 77)
+  TEST_LOOP (double, 77)
+  TEST_LOOP (float, 128)
+  TEST_LOOP (double, 128)
+  TEST_LOOP (float, 795)
+  TEST_LOOP (double, 795)
   return 0;
 }
diff --git a/gcc/testsuite/gcc.target/riscv/rvv/autovec/ternop/ternop_run-7.c b/gcc/testsuite/gcc.target/riscv/rvv/autovec/ternop/ternop_run-7.c
new file mode 100644
index 00000000000..1809b237467
--- /dev/null
+++ b/gcc/testsuite/gcc.target/riscv/rvv/autovec/ternop/ternop_run-7.c
@@ -0,0 +1,40 @@ 
+/* { dg-do run { target { riscv_vector } } } */
+/* { dg-additional-options "--param=riscv-autovec-preference=scalable -ffast-math" } */
+
+#include "ternop-7.c"
+
+#define TEST_LOOP(TYPE, NUM)                                                   \
+  {                                                                            \
+    TYPE array1_##NUM[NUM] = {};                                               \
+    TYPE array2_##NUM[NUM] = {};                                               \
+    TYPE array3_##NUM[NUM] = {};                                               \
+    TYPE array4_##NUM[NUM] = {};                                               \
+    for (int i = 0; i < NUM; ++i)                                              \
+      {                                                                        \
+	array1_##NUM[i] = (i & 1) + 5;                                         \
+	array2_##NUM[i] = i - NUM / 3;                                         \
+	array3_##NUM[i] = NUM - NUM / 3 - i;                                   \
+	array4_##NUM[i] = NUM - NUM / 3 - i;                                   \
+	asm volatile("" ::: "memory");                                         \
+      }                                                                        \
+    ternop_##TYPE (array3_##NUM, array1_##NUM, array2_##NUM, NUM);             \
+    for (int i = 0; i < NUM; i++)                                              \
+      if (array3_##NUM[i]                                                      \
+	  != (TYPE) (array1_##NUM[i] * array2_##NUM[i] - array4_##NUM[i]))     \
+	__builtin_abort ();                                                    \
+  }
+
+int __attribute__ ((optimize (0))) main ()
+{
+  TEST_LOOP (float, 7)
+  TEST_LOOP (double, 7)
+  TEST_LOOP (float, 16)
+  TEST_LOOP (double, 16)
+  TEST_LOOP (float, 77)
+  TEST_LOOP (double, 77)
+  TEST_LOOP (float, 128)
+  TEST_LOOP (double, 128)
+  TEST_LOOP (float, 795)
+  TEST_LOOP (double, 795)
+  return 0;
+}
diff --git a/gcc/testsuite/gcc.target/riscv/rvv/autovec/ternop/ternop_run-8.c b/gcc/testsuite/gcc.target/riscv/rvv/autovec/ternop/ternop_run-8.c
new file mode 100644
index 00000000000..f048652f433
--- /dev/null
+++ b/gcc/testsuite/gcc.target/riscv/rvv/autovec/ternop/ternop_run-8.c
@@ -0,0 +1,60 @@ 
+/* { dg-do run { target { riscv_vector } } } */
+/* { dg-additional-options "--param=riscv-autovec-preference=scalable -ffast-math" } */
+
+#include "ternop-8.c"
+
+#define TEST_LOOP(TYPE, NUM)                                                   \
+  {                                                                            \
+    TYPE array1_##NUM[NUM] = {};                                               \
+    TYPE array2_##NUM[NUM] = {};                                               \
+    TYPE array3_##NUM[NUM] = {};                                               \
+    TYPE array4_##NUM[NUM] = {};                                               \
+    TYPE array5_##NUM[NUM] = {};                                               \
+    TYPE array6_##NUM[NUM] = {};                                               \
+    TYPE array7_##NUM[NUM] = {};                                               \
+    TYPE array8_##NUM[NUM] = {};                                               \
+    for (int i = 0; i < NUM; ++i)                                              \
+      {                                                                        \
+	array1_##NUM[i] = (i & 1) + 5;                                         \
+	array2_##NUM[i] = i - NUM / 3;                                         \
+	array3_##NUM[i] = NUM - NUM / 3 - i;                                   \
+	array6_##NUM[i] = NUM - NUM / 3 - i;                                   \
+	array4_##NUM[i] = NUM - NUM / 2 + i;                                   \
+	array7_##NUM[i] = NUM - NUM / 2 + i;                                   \
+	array5_##NUM[i] = NUM + i * 7;                                         \
+	array8_##NUM[i] = NUM + i * 7;                                         \
+	asm volatile("" ::: "memory");                                         \
+      }                                                                        \
+    ternop_##TYPE (array3_##NUM, array4_##NUM, array5_##NUM, array1_##NUM,     \
+		   array2_##NUM, NUM);                                         \
+    for (int i = 0; i < NUM; i++)                                              \
+      {                                                                        \
+	array6_##NUM[i]                                                        \
+	  = (TYPE) (array1_##NUM[i] * array2_##NUM[i] - array6_##NUM[i]);      \
+	if (array3_##NUM[i] != array6_##NUM[i])                                \
+	  __builtin_abort ();                                                  \
+	array7_##NUM[i]                                                        \
+	  = (TYPE) (array1_##NUM[i] * array6_##NUM[i] - array7_##NUM[i]);      \
+	if (array4_##NUM[i] != array7_##NUM[i])                                \
+	  __builtin_abort ();                                                  \
+	array8_##NUM[i]                                                        \
+	  = (TYPE) (array2_##NUM[i] * array7_##NUM[i] - array8_##NUM[i]);      \
+	if (array5_##NUM[i] != array8_##NUM[i])                                \
+	  __builtin_abort ();                                                  \
+      }                                                                        \
+  }
+
+int __attribute__ ((optimize (0))) main ()
+{
+  TEST_LOOP (float, 7)
+  TEST_LOOP (double, 7)
+  TEST_LOOP (float, 16)
+  TEST_LOOP (double, 16)
+  TEST_LOOP (float, 77)
+  TEST_LOOP (double, 77)
+  TEST_LOOP (float, 128)
+  TEST_LOOP (double, 128)
+  TEST_LOOP (float, 795)
+  TEST_LOOP (double, 795)
+  return 0;
+}
diff --git a/gcc/testsuite/gcc.target/riscv/rvv/autovec/ternop/ternop_run-9.c b/gcc/testsuite/gcc.target/riscv/rvv/autovec/ternop/ternop_run-9.c
new file mode 100644
index 00000000000..dcf87f67452
--- /dev/null
+++ b/gcc/testsuite/gcc.target/riscv/rvv/autovec/ternop/ternop_run-9.c
@@ -0,0 +1,60 @@ 
+/* { dg-do run { target { riscv_vector } } } */
+/* { dg-additional-options "--param=riscv-autovec-preference=scalable -ffast-math" } */
+
+#include "ternop-9.c"
+
+#define TEST_LOOP(TYPE, NUM)                                                   \
+  {                                                                            \
+    TYPE array1_##NUM[NUM] = {};                                               \
+    TYPE array2_##NUM[NUM] = {};                                               \
+    TYPE array3_##NUM[NUM] = {};                                               \
+    TYPE array4_##NUM[NUM] = {};                                               \
+    TYPE array5_##NUM[NUM] = {};                                               \
+    TYPE array6_##NUM[NUM] = {};                                               \
+    TYPE array7_##NUM[NUM] = {};                                               \
+    TYPE array8_##NUM[NUM] = {};                                               \
+    for (int i = 0; i < NUM; ++i)                                              \
+      {                                                                        \
+	array1_##NUM[i] = (i & 1) + 5;                                         \
+	array2_##NUM[i] = i - NUM / 3;                                         \
+	array3_##NUM[i] = NUM - NUM / 3 - i;                                   \
+	array6_##NUM[i] = NUM - NUM / 3 - i;                                   \
+	array4_##NUM[i] = NUM - NUM / 2 + i;                                   \
+	array7_##NUM[i] = NUM - NUM / 2 + i;                                   \
+	array5_##NUM[i] = NUM + i * 7;                                         \
+	array8_##NUM[i] = NUM + i * 7;                                         \
+	asm volatile("" ::: "memory");                                         \
+      }                                                                        \
+    ternop_##TYPE (array3_##NUM, array4_##NUM, array5_##NUM, array1_##NUM,     \
+		   array2_##NUM, NUM);                                         \
+    for (int i = 0; i < NUM; i++)                                              \
+      {                                                                        \
+	array6_##NUM[i]                                                        \
+	  = (TYPE) (array1_##NUM[i] * array2_##NUM[i] - array7_##NUM[i]);      \
+	if (array3_##NUM[i] != array6_##NUM[i])                                \
+	  __builtin_abort ();                                                  \
+	array7_##NUM[i]                                                        \
+	  = (TYPE) (array1_##NUM[i] * array6_##NUM[i] - array7_##NUM[i]);      \
+	if (array4_##NUM[i] != array7_##NUM[i])                                \
+	  __builtin_abort ();                                                  \
+	array8_##NUM[i]                                                        \
+	  = (TYPE) (array2_##NUM[i] * array7_##NUM[i] - array8_##NUM[i]);      \
+	if (array5_##NUM[i] != array8_##NUM[i])                                \
+	  __builtin_abort ();                                                  \
+      }                                                                        \
+  }
+
+int __attribute__ ((optimize (0))) main ()
+{
+  TEST_LOOP (float, 7)
+  TEST_LOOP (double, 7)
+  TEST_LOOP (float, 16)
+  TEST_LOOP (double, 16)
+  TEST_LOOP (float, 77)
+  TEST_LOOP (double, 77)
+  TEST_LOOP (float, 128)
+  TEST_LOOP (double, 128)
+  TEST_LOOP (float, 795)
+  TEST_LOOP (double, 795)
+  return 0;
+}
diff --git a/gcc/testsuite/gcc.target/riscv/rvv/autovec/ternop/ternop_run_zvfh-1.c b/gcc/testsuite/gcc.target/riscv/rvv/autovec/ternop/ternop_run_zvfh-1.c
new file mode 100644
index 00000000000..84fcb683341
--- /dev/null
+++ b/gcc/testsuite/gcc.target/riscv/rvv/autovec/ternop/ternop_run_zvfh-1.c
@@ -0,0 +1,35 @@ 
+/* { dg-do run { target { riscv_vector && riscv_zvfh_hw } } } */
+/* { dg-additional-options "--param=riscv-autovec-preference=scalable -ffast-math" } */
+
+#include "ternop-1.c"
+
+#define TEST_LOOP(TYPE, NUM)                                                   \
+  {                                                                            \
+    TYPE array1_##NUM[NUM] = {};                                               \
+    TYPE array2_##NUM[NUM] = {};                                               \
+    TYPE array3_##NUM[NUM] = {};                                               \
+    TYPE array4_##NUM[NUM] = {};                                               \
+    for (int i = 0; i < NUM; ++i)                                              \
+      {                                                                        \
+	array1_##NUM[i] = (i & 1) + 5;                                         \
+	array2_##NUM[i] = i - NUM / 3;                                         \
+	array3_##NUM[i] = NUM - NUM / 3 - i;                                   \
+	array4_##NUM[i] = NUM - NUM / 3 - i;                                   \
+	asm volatile("" ::: "memory");                                         \
+      }                                                                        \
+    ternop_##TYPE (array3_##NUM, array1_##NUM, array2_##NUM, NUM);             \
+    for (int i = 0; i < NUM; i++)                                              \
+      if (array3_##NUM[i]                                                      \
+	  != (TYPE) (array1_##NUM[i] * array2_##NUM[i] + array4_##NUM[i]))     \
+	__builtin_abort ();                                                    \
+  }
+
+int __attribute__ ((optimize (0))) main ()
+{
+  TEST_LOOP (_Float16, 7)
+  TEST_LOOP (_Float16, 16)
+  TEST_LOOP (_Float16, 77)
+  TEST_LOOP (_Float16, 128)
+  TEST_LOOP (_Float16, 795)
+  return 0;
+}
diff --git a/gcc/testsuite/gcc.target/riscv/rvv/autovec/ternop/ternop_run_zvfh-10.c b/gcc/testsuite/gcc.target/riscv/rvv/autovec/ternop/ternop_run_zvfh-10.c
new file mode 100644
index 00000000000..d669cd4f2c9
--- /dev/null
+++ b/gcc/testsuite/gcc.target/riscv/rvv/autovec/ternop/ternop_run_zvfh-10.c
@@ -0,0 +1,35 @@ 
+/* { dg-do run { target { riscv_vector && riscv_zvfh_hw } } } */
+/* { dg-additional-options "--param=riscv-autovec-preference=scalable -ffast-math" } */
+
+#include "ternop-10.c"
+
+#define TEST_LOOP(TYPE, NUM)                                                   \
+  {                                                                            \
+    TYPE array1_##NUM[NUM] = {};                                               \
+    TYPE array2_##NUM[NUM] = {};                                               \
+    TYPE array3_##NUM[NUM] = {};                                               \
+    TYPE array4_##NUM[NUM] = {};                                               \
+    for (int i = 0; i < NUM; ++i)                                              \
+      {                                                                        \
+ array1_##NUM[i] = (i & 1) + 5;                                         \
+ array2_##NUM[i] = i - NUM / 3;                                         \
+ array3_##NUM[i] = NUM - NUM / 3 - i;                                   \
+ array4_##NUM[i] = NUM - NUM / 3 - i;                                   \
+ asm volatile("" ::: "memory");                                         \
+      }                                                                        \
+    ternop_##TYPE (array3_##NUM, array1_##NUM, array2_##NUM, NUM);             \
+    for (int i = 0; i < NUM; i++)                                              \
+      if (array3_##NUM[i]                                                      \
+   != (TYPE) (-(array1_##NUM[i] * array2_##NUM[i]) - array4_##NUM[i]))  \
+ __builtin_abort ();                                                    \
+  }
+
+int __attribute__ ((optimize (0))) main ()
+{
+  TEST_LOOP (_Float16, 7)
+  TEST_LOOP (_Float16, 16)
+  TEST_LOOP (_Float16, 77)
+  TEST_LOOP (_Float16, 128)
+  TEST_LOOP (_Float16, 795)
+  return 0;
+}
diff --git a/gcc/testsuite/gcc.target/riscv/rvv/autovec/ternop/ternop_run_zvfh-11.c b/gcc/testsuite/gcc.target/riscv/rvv/autovec/ternop/ternop_run_zvfh-11.c
new file mode 100644
index 00000000000..fac17b62c59
--- /dev/null
+++ b/gcc/testsuite/gcc.target/riscv/rvv/autovec/ternop/ternop_run_zvfh-11.c
@@ -0,0 +1,55 @@ 
+/* { dg-do run { target { riscv_vector && riscv_zvfh_hw } } } */
+/* { dg-additional-options "--param=riscv-autovec-preference=scalable -ffast-math" } */
+
+#include "ternop-11.c"
+
+#define TEST_LOOP(TYPE, NUM)                                                   \
+  {                                                                            \
+    TYPE array1_##NUM[NUM] = {};                                               \
+    TYPE array2_##NUM[NUM] = {};                                               \
+    TYPE array3_##NUM[NUM] = {};                                               \
+    TYPE array4_##NUM[NUM] = {};                                               \
+    TYPE array5_##NUM[NUM] = {};                                               \
+    TYPE array6_##NUM[NUM] = {};                                               \
+    TYPE array7_##NUM[NUM] = {};                                               \
+    TYPE array8_##NUM[NUM] = {};                                               \
+    for (int i = 0; i < NUM; ++i)                                              \
+      {                                                                        \
+ array1_##NUM[i] = (i & 1) + 5;                                         \
+ array2_##NUM[i] = i - NUM / 3;                                         \
+ array3_##NUM[i] = NUM - NUM / 3 - i;                                   \
+ array6_##NUM[i] = NUM - NUM / 3 - i;                                   \
+ array4_##NUM[i] = NUM - NUM / 2 + i;                                   \
+ array7_##NUM[i] = NUM - NUM / 2 + i;                                   \
+ array5_##NUM[i] = NUM + i * 7;                                         \
+ array8_##NUM[i] = NUM + i * 7;                                         \
+ asm volatile("" ::: "memory");                                         \
+      }                                                                        \
+    ternop_##TYPE (array3_##NUM, array4_##NUM, array5_##NUM, array1_##NUM,     \
+    array2_##NUM, NUM);                                         \
+    for (int i = 0; i < NUM; i++)                                              \
+      {                                                                        \
+ array6_##NUM[i]                                                        \
+   = (TYPE) (-(array1_##NUM[i] * array2_##NUM[i]) - array6_##NUM[i]);   \
+ if (array3_##NUM[i] != array6_##NUM[i])                                \
+   __builtin_abort ();                                                  \
+ array7_##NUM[i]                                                        \
+   = (TYPE) (array1_##NUM[i] * array6_##NUM[i] - array7_##NUM[i]);      \
+ if (array4_##NUM[i] != array7_##NUM[i])                                \
+   __builtin_abort ();                                                  \
+ array8_##NUM[i]                                                        \
+   = (TYPE) (array2_##NUM[i] * array7_##NUM[i] - array8_##NUM[i]);      \
+ if (array5_##NUM[i] != array8_##NUM[i])                                \
+   __builtin_abort ();                                                  \
+      }                                                                        \
+  }
+
+int __attribute__ ((optimize (0))) main ()
+{
+  TEST_LOOP (_Float16, 7)
+  TEST_LOOP (_Float16, 16)
+  TEST_LOOP (_Float16, 77)
+  TEST_LOOP (_Float16, 128)
+  TEST_LOOP (_Float16, 795)
+  return 0;
+}
diff --git a/gcc/testsuite/gcc.target/riscv/rvv/autovec/ternop/ternop_run_zvfh-12.c b/gcc/testsuite/gcc.target/riscv/rvv/autovec/ternop/ternop_run_zvfh-12.c
new file mode 100644
index 00000000000..a51b926d036
--- /dev/null
+++ b/gcc/testsuite/gcc.target/riscv/rvv/autovec/ternop/ternop_run_zvfh-12.c
@@ -0,0 +1,55 @@ 
+/* { dg-do run { target { riscv_vector && riscv_zvfh_hw } } } */
+/* { dg-additional-options "--param=riscv-autovec-preference=scalable -ffast-math" } */
+
+#include "ternop-12.c"
+
+#define TEST_LOOP(TYPE, NUM)                                                   \
+  {                                                                            \
+    TYPE array1_##NUM[NUM] = {};                                               \
+    TYPE array2_##NUM[NUM] = {};                                               \
+    TYPE array3_##NUM[NUM] = {};                                               \
+    TYPE array4_##NUM[NUM] = {};                                               \
+    TYPE array5_##NUM[NUM] = {};                                               \
+    TYPE array6_##NUM[NUM] = {};                                               \
+    TYPE array7_##NUM[NUM] = {};                                               \
+    TYPE array8_##NUM[NUM] = {};                                               \
+    for (int i = 0; i < NUM; ++i)                                              \
+      {                                                                        \
+ array1_##NUM[i] = (i & 1) + 5;                                         \
+ array2_##NUM[i] = i - NUM / 3;                                         \
+ array3_##NUM[i] = NUM - NUM / 3 - i;                                   \
+ array6_##NUM[i] = NUM - NUM / 3 - i;                                   \
+ array4_##NUM[i] = NUM - NUM / 2 + i;                                   \
+ array7_##NUM[i] = NUM - NUM / 2 + i;                                   \
+ array5_##NUM[i] = NUM + i * 7;                                         \
+ array8_##NUM[i] = NUM + i * 7;                                         \
+ asm volatile("" ::: "memory");                                         \
+      }                                                                        \
+    ternop_##TYPE (array3_##NUM, array4_##NUM, array5_##NUM, array1_##NUM,     \
+    array2_##NUM, NUM);                                         \
+    for (int i = 0; i < NUM; i++)                                              \
+      {                                                                        \
+ array6_##NUM[i]                                                        \
+   = (TYPE) (-(array1_##NUM[i] * array2_##NUM[i]) - array7_##NUM[i]);   \
+ if (array3_##NUM[i] != array6_##NUM[i])                                \
+   __builtin_abort ();                                                  \
+ array7_##NUM[i]                                                        \
+   = (TYPE) (array1_##NUM[i] * array6_##NUM[i] - array7_##NUM[i]);      \
+ if (array4_##NUM[i] != array7_##NUM[i])                                \
+   __builtin_abort ();                                                  \
+ array8_##NUM[i]                                                        \
+   = (TYPE) (array2_##NUM[i] * array7_##NUM[i] - array8_##NUM[i]);      \
+ if (array5_##NUM[i] != array8_##NUM[i])                                \
+   __builtin_abort ();                                                  \
+      }                                                                        \
+  }
+
+int __attribute__ ((optimize (0))) main ()
+{
+  TEST_LOOP (_Float16, 7)
+  TEST_LOOP (_Float16, 16)
+  TEST_LOOP (_Float16, 77)
+  TEST_LOOP (_Float16, 128)
+  TEST_LOOP (_Float16, 795)
+  return 0;
+}
diff --git a/gcc/testsuite/gcc.target/riscv/rvv/autovec/ternop/ternop_run_zvfh-2.c b/gcc/testsuite/gcc.target/riscv/rvv/autovec/ternop/ternop_run_zvfh-2.c
new file mode 100644
index 00000000000..8fc6a1b33d1
--- /dev/null
+++ b/gcc/testsuite/gcc.target/riscv/rvv/autovec/ternop/ternop_run_zvfh-2.c
@@ -0,0 +1,55 @@ 
+/* { dg-do run { target { riscv_vector && riscv_zvfh_hw } } } */
+/* { dg-additional-options "--param=riscv-autovec-preference=scalable -ffast-math" } */
+
+#include "ternop-2.c"
+
+#define TEST_LOOP(TYPE, NUM)                                                   \
+  {                                                                            \
+    TYPE array1_##NUM[NUM] = {};                                               \
+    TYPE array2_##NUM[NUM] = {};                                               \
+    TYPE array3_##NUM[NUM] = {};                                               \
+    TYPE array4_##NUM[NUM] = {};                                               \
+    TYPE array5_##NUM[NUM] = {};                                               \
+    TYPE array6_##NUM[NUM] = {};                                               \
+    TYPE array7_##NUM[NUM] = {};                                               \
+    TYPE array8_##NUM[NUM] = {};                                               \
+    for (int i = 0; i < NUM; ++i)                                              \
+      {                                                                        \
+	array1_##NUM[i] = (i & 1) + 5;                                         \
+	array2_##NUM[i] = i - NUM / 3;                                         \
+	array3_##NUM[i] = NUM - NUM / 3 - i;                                   \
+	array6_##NUM[i] = NUM - NUM / 3 - i;                                   \
+	array4_##NUM[i] = NUM - NUM / 2 + i;                                   \
+	array7_##NUM[i] = NUM - NUM / 2 + i;                                   \
+	array5_##NUM[i] = NUM + i * 7;                                         \
+	array8_##NUM[i] = NUM + i * 7;                                         \
+	asm volatile("" ::: "memory");                                         \
+      }                                                                        \
+    ternop_##TYPE (array3_##NUM, array4_##NUM, array5_##NUM, array1_##NUM,     \
+		   array2_##NUM, NUM);                                         \
+    for (int i = 0; i < NUM; i++)                                              \
+      {                                                                        \
+	array6_##NUM[i]                                                        \
+	  = (TYPE) (array1_##NUM[i] * array2_##NUM[i] + array6_##NUM[i]);      \
+	if (array3_##NUM[i] != array6_##NUM[i])                                \
+	  __builtin_abort ();                                                  \
+	array7_##NUM[i]                                                        \
+	  = (TYPE) (array1_##NUM[i] * array6_##NUM[i] + array7_##NUM[i]);      \
+	if (array4_##NUM[i] != array7_##NUM[i])                                \
+	  __builtin_abort ();                                                  \
+	array8_##NUM[i]                                                        \
+	  = (TYPE) (array2_##NUM[i] * array7_##NUM[i] + array8_##NUM[i]);      \
+	if (array5_##NUM[i] != array8_##NUM[i])                                \
+	  __builtin_abort ();                                                  \
+      }                                                                        \
+  }
+
+int __attribute__ ((optimize (0))) main ()
+{
+  TEST_LOOP (_Float16, 7)
+  TEST_LOOP (_Float16, 16)
+  TEST_LOOP (_Float16, 77)
+  TEST_LOOP (_Float16, 128)
+  TEST_LOOP (_Float16, 795)
+  return 0;
+}
diff --git a/gcc/testsuite/gcc.target/riscv/rvv/autovec/ternop/ternop_run_zvfh-3.c b/gcc/testsuite/gcc.target/riscv/rvv/autovec/ternop/ternop_run_zvfh-3.c
new file mode 100644
index 00000000000..36013072415
--- /dev/null
+++ b/gcc/testsuite/gcc.target/riscv/rvv/autovec/ternop/ternop_run_zvfh-3.c
@@ -0,0 +1,55 @@ 
+/* { dg-do run { target { riscv_vector && riscv_zvfh_hw } } } */
+/* { dg-additional-options "--param=riscv-autovec-preference=scalable -ffast-math" } */
+
+#include "ternop-3.c"
+
+#define TEST_LOOP(TYPE, NUM)                                                   \
+  {                                                                            \
+    TYPE array1_##NUM[NUM] = {};                                               \
+    TYPE array2_##NUM[NUM] = {};                                               \
+    TYPE array3_##NUM[NUM] = {};                                               \
+    TYPE array4_##NUM[NUM] = {};                                               \
+    TYPE array5_##NUM[NUM] = {};                                               \
+    TYPE array6_##NUM[NUM] = {};                                               \
+    TYPE array7_##NUM[NUM] = {};                                               \
+    TYPE array8_##NUM[NUM] = {};                                               \
+    for (int i = 0; i < NUM; ++i)                                              \
+      {                                                                        \
+	array1_##NUM[i] = (i & 1) + 5;                                         \
+	array2_##NUM[i] = i - NUM / 3;                                         \
+	array3_##NUM[i] = NUM - NUM / 3 - i;                                   \
+	array6_##NUM[i] = NUM - NUM / 3 - i;                                   \
+	array4_##NUM[i] = NUM - NUM / 2 + i;                                   \
+	array7_##NUM[i] = NUM - NUM / 2 + i;                                   \
+	array5_##NUM[i] = NUM + i * 7;                                         \
+	array8_##NUM[i] = NUM + i * 7;                                         \
+	asm volatile("" ::: "memory");                                         \
+      }                                                                        \
+    ternop_##TYPE (array3_##NUM, array4_##NUM, array5_##NUM, array1_##NUM,     \
+		   array2_##NUM, NUM);                                         \
+    for (int i = 0; i < NUM; i++)                                              \
+      {                                                                        \
+	array6_##NUM[i]                                                        \
+	  = (TYPE) (array1_##NUM[i] * array2_##NUM[i] + array7_##NUM[i]);      \
+	if (array3_##NUM[i] != array6_##NUM[i])                                \
+	  __builtin_abort ();                                                  \
+	array7_##NUM[i]                                                        \
+	  = (TYPE) (array1_##NUM[i] * array6_##NUM[i] + array7_##NUM[i]);      \
+	if (array4_##NUM[i] != array7_##NUM[i])                                \
+	  __builtin_abort ();                                                  \
+	array8_##NUM[i]                                                        \
+	  = (TYPE) (array2_##NUM[i] * array7_##NUM[i] + array8_##NUM[i]);      \
+	if (array5_##NUM[i] != array8_##NUM[i])                                \
+	  __builtin_abort ();                                                  \
+      }                                                                        \
+  }
+
+int __attribute__ ((optimize (0))) main ()
+{
+  TEST_LOOP (_Float16, 7)
+  TEST_LOOP (_Float16, 16)
+  TEST_LOOP (_Float16, 77)
+  TEST_LOOP (_Float16, 128)
+  TEST_LOOP (_Float16, 795)
+  return 0;
+}
diff --git a/gcc/testsuite/gcc.target/riscv/rvv/autovec/ternop/ternop_run_zvfh-4.c b/gcc/testsuite/gcc.target/riscv/rvv/autovec/ternop/ternop_run_zvfh-4.c
new file mode 100644
index 00000000000..a26bcaa6017
--- /dev/null
+++ b/gcc/testsuite/gcc.target/riscv/rvv/autovec/ternop/ternop_run_zvfh-4.c
@@ -0,0 +1,35 @@ 
+/* { dg-do run { target { riscv_vector && riscv_zvfh_hw } } } */
+/* { dg-additional-options "--param=riscv-autovec-preference=scalable -ffast-math" } */
+
+#include "ternop-4.c"
+
+#define TEST_LOOP(TYPE, NUM)                                                   \
+  {                                                                            \
+    TYPE array1_##NUM[NUM] = {};                                               \
+    TYPE array2_##NUM[NUM] = {};                                               \
+    TYPE array3_##NUM[NUM] = {};                                               \
+    TYPE array4_##NUM[NUM] = {};                                               \
+    for (int i = 0; i < NUM; ++i)                                              \
+      {                                                                        \
+ array1_##NUM[i] = (i & 1) + 5;                                         \
+ array2_##NUM[i] = i - NUM / 3;                                         \
+ array3_##NUM[i] = NUM - NUM / 3 - i;                                   \
+ array4_##NUM[i] = NUM - NUM / 3 - i;                                   \
+ asm volatile("" ::: "memory");                                         \
+      }                                                                        \
+    ternop_##TYPE (array3_##NUM, array1_##NUM, array2_##NUM, NUM);             \
+    for (int i = 0; i < NUM; i++)                                              \
+      if (array3_##NUM[i]                                                      \
+   != (TYPE) (-(array1_##NUM[i] * array2_##NUM[i]) + array4_##NUM[i]))  \
+ __builtin_abort ();                                                    \
+  }
+
+int __attribute__ ((optimize (0))) main ()
+{
+  TEST_LOOP (_Float16, 7)
+  TEST_LOOP (_Float16, 16)
+  TEST_LOOP (_Float16, 77)
+  TEST_LOOP (_Float16, 128)
+  TEST_LOOP (_Float16, 795)
+  return 0;
+}
diff --git a/gcc/testsuite/gcc.target/riscv/rvv/autovec/ternop/ternop_run_zvfh-5.c b/gcc/testsuite/gcc.target/riscv/rvv/autovec/ternop/ternop_run_zvfh-5.c
new file mode 100644
index 00000000000..6dee6ba7c99
--- /dev/null
+++ b/gcc/testsuite/gcc.target/riscv/rvv/autovec/ternop/ternop_run_zvfh-5.c
@@ -0,0 +1,55 @@ 
+/* { dg-do run { target { riscv_vector && riscv_zvfh_hw } } } */
+/* { dg-additional-options "--param=riscv-autovec-preference=scalable -ffast-math" } */
+
+#include "ternop-5.c"
+
+#define TEST_LOOP(TYPE, NUM)                                                   \
+  {                                                                            \
+    TYPE array1_##NUM[NUM] = {};                                               \
+    TYPE array2_##NUM[NUM] = {};                                               \
+    TYPE array3_##NUM[NUM] = {};                                               \
+    TYPE array4_##NUM[NUM] = {};                                               \
+    TYPE array5_##NUM[NUM] = {};                                               \
+    TYPE array6_##NUM[NUM] = {};                                               \
+    TYPE array7_##NUM[NUM] = {};                                               \
+    TYPE array8_##NUM[NUM] = {};                                               \
+    for (int i = 0; i < NUM; ++i)                                              \
+      {                                                                        \
+ array1_##NUM[i] = (i & 1) + 5;                                         \
+ array2_##NUM[i] = i - NUM / 3;                                         \
+ array3_##NUM[i] = NUM - NUM / 3 - i;                                   \
+ array6_##NUM[i] = NUM - NUM / 3 - i;                                   \
+ array4_##NUM[i] = NUM - NUM / 2 + i;                                   \
+ array7_##NUM[i] = NUM - NUM / 2 + i;                                   \
+ array5_##NUM[i] = NUM + i * 7;                                         \
+ array8_##NUM[i] = NUM + i * 7;                                         \
+ asm volatile("" ::: "memory");                                         \
+      }                                                                        \
+    ternop_##TYPE (array3_##NUM, array4_##NUM, array5_##NUM, array1_##NUM,     \
+    array2_##NUM, NUM);                                         \
+    for (int i = 0; i < NUM; i++)                                              \
+      {                                                                        \
+ array6_##NUM[i]                                                        \
+   = (TYPE) (-(array1_##NUM[i] * array2_##NUM[i]) + array6_##NUM[i]);   \
+ if (array3_##NUM[i] != array6_##NUM[i])                                \
+   __builtin_abort ();                                                  \
+ array7_##NUM[i]                                                        \
+   = (TYPE) (array1_##NUM[i] * array6_##NUM[i] + array7_##NUM[i]);      \
+ if (array4_##NUM[i] != array7_##NUM[i])                                \
+   __builtin_abort ();                                                  \
+ array8_##NUM[i]                                                        \
+   = (TYPE) (array2_##NUM[i] * array7_##NUM[i] + array8_##NUM[i]);      \
+ if (array5_##NUM[i] != array8_##NUM[i])                                \
+   __builtin_abort ();                                                  \
+      }                                                                        \
+  }
+
+int __attribute__ ((optimize (0))) main ()
+{
+  TEST_LOOP (_Float16, 7)
+  TEST_LOOP (_Float16, 16)
+  TEST_LOOP (_Float16, 77)
+  TEST_LOOP (_Float16, 128)
+  TEST_LOOP (_Float16, 795)
+  return 0;
+}
diff --git a/gcc/testsuite/gcc.target/riscv/rvv/autovec/ternop/ternop_run_zvfh-6.c b/gcc/testsuite/gcc.target/riscv/rvv/autovec/ternop/ternop_run_zvfh-6.c
new file mode 100644
index 00000000000..3fdf2d30df9
--- /dev/null
+++ b/gcc/testsuite/gcc.target/riscv/rvv/autovec/ternop/ternop_run_zvfh-6.c
@@ -0,0 +1,55 @@ 
+/* { dg-do run { target { riscv_vector && riscv_zvfh_hw } } } */
+/* { dg-additional-options "--param=riscv-autovec-preference=scalable -ffast-math" } */
+
+#include "ternop-6.c"
+
+#define TEST_LOOP(TYPE, NUM)                                                   \
+  {                                                                            \
+    TYPE array1_##NUM[NUM] = {};                                               \
+    TYPE array2_##NUM[NUM] = {};                                               \
+    TYPE array3_##NUM[NUM] = {};                                               \
+    TYPE array4_##NUM[NUM] = {};                                               \
+    TYPE array5_##NUM[NUM] = {};                                               \
+    TYPE array6_##NUM[NUM] = {};                                               \
+    TYPE array7_##NUM[NUM] = {};                                               \
+    TYPE array8_##NUM[NUM] = {};                                               \
+    for (int i = 0; i < NUM; ++i)                                              \
+      {                                                                        \
+ array1_##NUM[i] = (i & 1) + 5;                                         \
+ array2_##NUM[i] = i - NUM / 3;                                         \
+ array3_##NUM[i] = NUM - NUM / 3 - i;                                   \
+ array6_##NUM[i] = NUM - NUM / 3 - i;                                   \
+ array4_##NUM[i] = NUM - NUM / 2 + i;                                   \
+ array7_##NUM[i] = NUM - NUM / 2 + i;                                   \
+ array5_##NUM[i] = NUM + i * 7;                                         \
+ array8_##NUM[i] = NUM + i * 7;                                         \
+ asm volatile("" ::: "memory");                                         \
+      }                                                                        \
+    ternop_##TYPE (array3_##NUM, array4_##NUM, array5_##NUM, array1_##NUM,     \
+    array2_##NUM, NUM);                                         \
+    for (int i = 0; i < NUM; i++)                                              \
+      {                                                                        \
+ array6_##NUM[i]                                                        \
+   = (TYPE) (-(array1_##NUM[i] * array2_##NUM[i]) + array7_##NUM[i]);   \
+ if (array3_##NUM[i] != array6_##NUM[i])                                \
+   __builtin_abort ();                                                  \
+ array7_##NUM[i]                                                        \
+   = (TYPE) (array1_##NUM[i] * array6_##NUM[i] + array7_##NUM[i]);      \
+ if (array4_##NUM[i] != array7_##NUM[i])                                \
+   __builtin_abort ();                                                  \
+ array8_##NUM[i]                                                        \
+   = (TYPE) (array2_##NUM[i] * array7_##NUM[i] + array8_##NUM[i]);      \
+ if (array5_##NUM[i] != array8_##NUM[i])                                \
+   __builtin_abort ();                                                  \
+      }                                                                        \
+  }
+
+int __attribute__ ((optimize (0))) main ()
+{
+  TEST_LOOP (_Float16, 7)
+  TEST_LOOP (_Float16, 16)
+  TEST_LOOP (_Float16, 77)
+  TEST_LOOP (_Float16, 128)
+  TEST_LOOP (_Float16, 795)
+  return 0;
+}
diff --git a/gcc/testsuite/gcc.target/riscv/rvv/autovec/ternop/ternop_run_zvfh-7.c b/gcc/testsuite/gcc.target/riscv/rvv/autovec/ternop/ternop_run_zvfh-7.c
new file mode 100644
index 00000000000..a25a6f7f188
--- /dev/null
+++ b/gcc/testsuite/gcc.target/riscv/rvv/autovec/ternop/ternop_run_zvfh-7.c
@@ -0,0 +1,35 @@ 
+/* { dg-do run { target { riscv_vector && riscv_zvfh_hw } } } */
+/* { dg-additional-options "--param=riscv-autovec-preference=scalable -ffast-math" } */
+
+#include "ternop-7.c"
+
+#define TEST_LOOP(TYPE, NUM)                                                   \
+  {                                                                            \
+    TYPE array1_##NUM[NUM] = {};                                               \
+    TYPE array2_##NUM[NUM] = {};                                               \
+    TYPE array3_##NUM[NUM] = {};                                               \
+    TYPE array4_##NUM[NUM] = {};                                               \
+    for (int i = 0; i < NUM; ++i)                                              \
+      {                                                                        \
+	array1_##NUM[i] = (i & 1) + 5;                                         \
+	array2_##NUM[i] = i - NUM / 3;                                         \
+	array3_##NUM[i] = NUM - NUM / 3 - i;                                   \
+	array4_##NUM[i] = NUM - NUM / 3 - i;                                   \
+	asm volatile("" ::: "memory");                                         \
+      }                                                                        \
+    ternop_##TYPE (array3_##NUM, array1_##NUM, array2_##NUM, NUM);             \
+    for (int i = 0; i < NUM; i++)                                              \
+      if (array3_##NUM[i]                                                      \
+	  != (TYPE) (array1_##NUM[i] * array2_##NUM[i] - array4_##NUM[i]))     \
+	__builtin_abort ();                                                    \
+  }
+
+int __attribute__ ((optimize (0))) main ()
+{
+  TEST_LOOP (_Float16, 7)
+  TEST_LOOP (_Float16, 16)
+  TEST_LOOP (_Float16, 77)
+  TEST_LOOP (_Float16, 128)
+  TEST_LOOP (_Float16, 795)
+  return 0;
+}
diff --git a/gcc/testsuite/gcc.target/riscv/rvv/autovec/ternop/ternop_run_zvfh-8.c b/gcc/testsuite/gcc.target/riscv/rvv/autovec/ternop/ternop_run_zvfh-8.c
new file mode 100644
index 00000000000..1d90bee1623
--- /dev/null
+++ b/gcc/testsuite/gcc.target/riscv/rvv/autovec/ternop/ternop_run_zvfh-8.c
@@ -0,0 +1,55 @@ 
+/* { dg-do run { target { riscv_vector && riscv_zvfh_hw } } } */
+/* { dg-additional-options "--param=riscv-autovec-preference=scalable -ffast-math" } */
+
+#include "ternop-8.c"
+
+#define TEST_LOOP(TYPE, NUM)                                                   \
+  {                                                                            \
+    TYPE array1_##NUM[NUM] = {};                                               \
+    TYPE array2_##NUM[NUM] = {};                                               \
+    TYPE array3_##NUM[NUM] = {};                                               \
+    TYPE array4_##NUM[NUM] = {};                                               \
+    TYPE array5_##NUM[NUM] = {};                                               \
+    TYPE array6_##NUM[NUM] = {};                                               \
+    TYPE array7_##NUM[NUM] = {};                                               \
+    TYPE array8_##NUM[NUM] = {};                                               \
+    for (int i = 0; i < NUM; ++i)                                              \
+      {                                                                        \
+	array1_##NUM[i] = (i & 1) + 5;                                         \
+	array2_##NUM[i] = i - NUM / 3;                                         \
+	array3_##NUM[i] = NUM - NUM / 3 - i;                                   \
+	array6_##NUM[i] = NUM - NUM / 3 - i;                                   \
+	array4_##NUM[i] = NUM - NUM / 2 + i;                                   \
+	array7_##NUM[i] = NUM - NUM / 2 + i;                                   \
+	array5_##NUM[i] = NUM + i * 7;                                         \
+	array8_##NUM[i] = NUM + i * 7;                                         \
+	asm volatile("" ::: "memory");                                         \
+      }                                                                        \
+    ternop_##TYPE (array3_##NUM, array4_##NUM, array5_##NUM, array1_##NUM,     \
+		   array2_##NUM, NUM);                                         \
+    for (int i = 0; i < NUM; i++)                                              \
+      {                                                                        \
+	array6_##NUM[i]                                                        \
+	  = (TYPE) (array1_##NUM[i] * array2_##NUM[i] - array6_##NUM[i]);      \
+	if (array3_##NUM[i] != array6_##NUM[i])                                \
+	  __builtin_abort ();                                                  \
+	array7_##NUM[i]                                                        \
+	  = (TYPE) (array1_##NUM[i] * array6_##NUM[i] - array7_##NUM[i]);      \
+	if (array4_##NUM[i] != array7_##NUM[i])                                \
+	  __builtin_abort ();                                                  \
+	array8_##NUM[i]                                                        \
+	  = (TYPE) (array2_##NUM[i] * array7_##NUM[i] - array8_##NUM[i]);      \
+	if (array5_##NUM[i] != array8_##NUM[i])                                \
+	  __builtin_abort ();                                                  \
+      }                                                                        \
+  }
+
+int __attribute__ ((optimize (0))) main ()
+{
+  TEST_LOOP (_Float16, 7)
+  TEST_LOOP (_Float16, 16)
+  TEST_LOOP (_Float16, 77)
+  TEST_LOOP (_Float16, 128)
+  TEST_LOOP (_Float16, 795)
+  return 0;
+}
diff --git a/gcc/testsuite/gcc.target/riscv/rvv/autovec/ternop/ternop_run_zvfh-9.c b/gcc/testsuite/gcc.target/riscv/rvv/autovec/ternop/ternop_run_zvfh-9.c
new file mode 100644
index 00000000000..c633f545349
--- /dev/null
+++ b/gcc/testsuite/gcc.target/riscv/rvv/autovec/ternop/ternop_run_zvfh-9.c
@@ -0,0 +1,55 @@ 
+/* { dg-do run { target { riscv_vector && riscv_zvfh_hw } } } */
+/* { dg-additional-options "--param=riscv-autovec-preference=scalable -ffast-math" } */
+
+#include "ternop-9.c"
+
+#define TEST_LOOP(TYPE, NUM)                                                   \
+  {                                                                            \
+    TYPE array1_##NUM[NUM] = {};                                               \
+    TYPE array2_##NUM[NUM] = {};                                               \
+    TYPE array3_##NUM[NUM] = {};                                               \
+    TYPE array4_##NUM[NUM] = {};                                               \
+    TYPE array5_##NUM[NUM] = {};                                               \
+    TYPE array6_##NUM[NUM] = {};                                               \
+    TYPE array7_##NUM[NUM] = {};                                               \
+    TYPE array8_##NUM[NUM] = {};                                               \
+    for (int i = 0; i < NUM; ++i)                                              \
+      {                                                                        \
+	array1_##NUM[i] = (i & 1) + 5;                                         \
+	array2_##NUM[i] = i - NUM / 3;                                         \
+	array3_##NUM[i] = NUM - NUM / 3 - i;                                   \
+	array6_##NUM[i] = NUM - NUM / 3 - i;                                   \
+	array4_##NUM[i] = NUM - NUM / 2 + i;                                   \
+	array7_##NUM[i] = NUM - NUM / 2 + i;                                   \
+	array5_##NUM[i] = NUM + i * 7;                                         \
+	array8_##NUM[i] = NUM + i * 7;                                         \
+	asm volatile("" ::: "memory");                                         \
+      }                                                                        \
+    ternop_##TYPE (array3_##NUM, array4_##NUM, array5_##NUM, array1_##NUM,     \
+		   array2_##NUM, NUM);                                         \
+    for (int i = 0; i < NUM; i++)                                              \
+      {                                                                        \
+	array6_##NUM[i]                                                        \
+	  = (TYPE) (array1_##NUM[i] * array2_##NUM[i] - array7_##NUM[i]);      \
+	if (array3_##NUM[i] != array6_##NUM[i])                                \
+	  __builtin_abort ();                                                  \
+	array7_##NUM[i]                                                        \
+	  = (TYPE) (array1_##NUM[i] * array6_##NUM[i] - array7_##NUM[i]);      \
+	if (array4_##NUM[i] != array7_##NUM[i])                                \
+	  __builtin_abort ();                                                  \
+	array8_##NUM[i]                                                        \
+	  = (TYPE) (array2_##NUM[i] * array7_##NUM[i] - array8_##NUM[i]);      \
+	if (array5_##NUM[i] != array8_##NUM[i])                                \
+	  __builtin_abort ();                                                  \
+      }                                                                        \
+  }
+
+int __attribute__ ((optimize (0))) main ()
+{
+  TEST_LOOP (_Float16, 7)
+  TEST_LOOP (_Float16, 16)
+  TEST_LOOP (_Float16, 77)
+  TEST_LOOP (_Float16, 128)
+  TEST_LOOP (_Float16, 795)
+  return 0;
+}