* [PATCH] RISC-V: Support RVV floating-point ternary auto-vectorization
@ 2023-06-21 11:12 Juzhe-Zhong
2023-06-21 12:54 ` Robin Dapp
2023-06-21 15:15 ` Jeff Law
0 siblings, 2 replies; 8+ messages in thread
From: Juzhe-Zhong @ 2023-06-21 11:12 UTC (permalink / raw)
To: gcc-patches
Cc: kito.cheng, kito.cheng, palmer, palmer, jeffreyalaw, rdapp.gcc,
Juzhe-Zhong
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/testsuite/ChangeLog:
* gcc.target/riscv/rvv/autovec/ternop/ternop-1.c: Add floating-point teranary tests.
* gcc.target/riscv/rvv/autovec/ternop/ternop-2.c: Ditto.
* gcc.target/riscv/rvv/autovec/ternop/ternop-3.c: Ditto.
* gcc.target/riscv/rvv/autovec/ternop/ternop-4.c: Ditto.
* gcc.target/riscv/rvv/autovec/ternop/ternop-5.c: Ditto.
* gcc.target/riscv/rvv/autovec/ternop/ternop-6.c: Ditto.
* gcc.target/riscv/rvv/autovec/ternop/ternop_run-1.c: Ditto.
* gcc.target/riscv/rvv/autovec/ternop/ternop_run-2.c: Ditto.
* gcc.target/riscv/rvv/autovec/ternop/ternop_run-3.c: Ditto.
* gcc.target/riscv/rvv/autovec/ternop/ternop_run-4.c: Ditto.
* gcc.target/riscv/rvv/autovec/ternop/ternop_run-5.c: Ditto.
* gcc.target/riscv/rvv/autovec/ternop/ternop_run-6.c: Ditto.
* gcc.target/riscv/rvv/autovec/ternop/ternop-10.c: New test.
* gcc.target/riscv/rvv/autovec/ternop/ternop-11.c: New test.
* gcc.target/riscv/rvv/autovec/ternop/ternop-12.c: New test.
* gcc.target/riscv/rvv/autovec/ternop/ternop-7.c: New test.
* gcc.target/riscv/rvv/autovec/ternop/ternop-8.c: New test.
* gcc.target/riscv/rvv/autovec/ternop/ternop-9.c: New test.
* gcc.target/riscv/rvv/autovec/ternop/ternop_run-10.c: New test.
* gcc.target/riscv/rvv/autovec/ternop/ternop_run-11.c: New test.
* gcc.target/riscv/rvv/autovec/ternop/ternop_run-12.c: New test.
* gcc.target/riscv/rvv/autovec/ternop/ternop_run-7.c: New test.
* gcc.target/riscv/rvv/autovec/ternop/ternop_run-8.c: New test.
* gcc.target/riscv/rvv/autovec/ternop/ternop_run-9.c: New test.
* gcc.target/riscv/rvv/autovec/ternop/ternop_run_zvfh-1.c: New test.
* gcc.target/riscv/rvv/autovec/ternop/ternop_run_zvfh-10.c: New test.
* gcc.target/riscv/rvv/autovec/ternop/ternop_run_zvfh-11.c: New test.
* gcc.target/riscv/rvv/autovec/ternop/ternop_run_zvfh-12.c: New test.
* gcc.target/riscv/rvv/autovec/ternop/ternop_run_zvfh-2.c: New test.
* gcc.target/riscv/rvv/autovec/ternop/ternop_run_zvfh-3.c: New test.
* gcc.target/riscv/rvv/autovec/ternop/ternop_run_zvfh-4.c: New test.
* gcc.target/riscv/rvv/autovec/ternop/ternop_run_zvfh-5.c: New test.
* gcc.target/riscv/rvv/autovec/ternop/ternop_run_zvfh-6.c: New test.
* gcc.target/riscv/rvv/autovec/ternop/ternop_run_zvfh-7.c: New test.
* gcc.target/riscv/rvv/autovec/ternop/ternop_run_zvfh-8.c: New test.
* gcc.target/riscv/rvv/autovec/ternop/ternop_run_zvfh-9.c: New test.
---
gcc/config/riscv/autovec.md | 180 ++++++++++++++++++
gcc/config/riscv/riscv-protos.h | 1 +
gcc/config/riscv/riscv-v.cc | 21 ++
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, 1366 insertions(+), 22 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
diff --git a/gcc/config/riscv/autovec.md b/gcc/config/riscv/autovec.md
index f1641d7e1ea..ddee6171acb 100644
--- a/gcc/config/riscv/autovec.md
+++ b/gcc/config/riscv/autovec.md
@@ -676,6 +676,186 @@
[(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_scratch:SI 4))])]
+ "TARGET_VECTOR"
+ {})
+
+(define_insn_and_split "*fma<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_scratch:SI 4 "=r,r,r"))]
+ "TARGET_VECTOR"
+ "#"
+ "&& reload_completed"
+ [(const_int 0)]
+ {
+ PUT_MODE (operands[4], Pmode);
+ riscv_vector::emit_vlmax_vsetvl (<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, <MODE>mode),
+ riscv_vector::RVV_TERNOP, ops, operands[4]);
+ DONE;
+ }
+ [(set_attr "type" "vfmuladd")
+ (set_attr "mode" "<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_scratch:SI 4))])]
+ "TARGET_VECTOR"
+ {})
+
+(define_insn_and_split "*fnma<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_scratch:SI 4 "=r,r,r"))]
+ "TARGET_VECTOR"
+ "#"
+ "&& reload_completed"
+ [(const_int 0)]
+ {
+ PUT_MODE (operands[4], Pmode);
+ riscv_vector::emit_vlmax_vsetvl (<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, <MODE>mode),
+ riscv_vector::RVV_TERNOP, ops, operands[4]);
+ DONE;
+ }
+ [(set_attr "type" "vfmuladd")
+ (set_attr "mode" "<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_scratch:SI 4))])]
+ "TARGET_VECTOR"
+ {})
+
+(define_insn_and_split "*fms<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_scratch:SI 4 "=r,r,r"))]
+ "TARGET_VECTOR"
+ "#"
+ "&& reload_completed"
+ [(const_int 0)]
+ {
+ PUT_MODE (operands[4], Pmode);
+ riscv_vector::emit_vlmax_vsetvl (<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, <MODE>mode),
+ riscv_vector::RVV_TERNOP, ops, operands[4]);
+ DONE;
+ }
+ [(set_attr "type" "vfmuladd")
+ (set_attr "mode" "<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_scratch:SI 4))])]
+ "TARGET_VECTOR"
+ {})
+
+(define_insn_and_split "*fnms<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_scratch:SI 4 "=r,r,r"))]
+ "TARGET_VECTOR"
+ "#"
+ "&& reload_completed"
+ [(const_int 0)]
+ {
+ PUT_MODE (operands[4], Pmode);
+ riscv_vector::emit_vlmax_vsetvl (<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, <MODE>mode),
+ riscv_vector::RVV_TERNOP, ops, operands[4]);
+ DONE;
+ }
+ [(set_attr "type" "vfmuladd")
+ (set_attr "mode" "<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..87c537b9e61 100644
--- a/gcc/config/riscv/riscv-v.cc
+++ b/gcc/config/riscv/riscv-v.cc
@@ -718,6 +718,27 @@ emit_vlmax_ternary_insn (unsigned icode, int op_num, rtx *ops, rtx 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 ();
+ /* 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);
+ 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
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;
+}
--
2.36.1
^ permalink raw reply [flat|nested] 8+ messages in thread
* Re: [PATCH] RISC-V: Support RVV floating-point ternary auto-vectorization
2023-06-21 11:12 [PATCH] RISC-V: Support RVV floating-point ternary auto-vectorization Juzhe-Zhong
@ 2023-06-21 12:54 ` Robin Dapp
2023-06-21 15:15 ` Jeff Law
1 sibling, 0 replies; 8+ messages in thread
From: Robin Dapp @ 2023-06-21 12:54 UTC (permalink / raw)
To: Juzhe-Zhong, gcc-patches
Cc: rdapp.gcc, kito.cheng, kito.cheng, palmer, palmer, jeffreyalaw
Hi Juzhe,
LGTM apart from a tiny nit:
> + /* 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,
Seems like you copied this from the non-fp ternary part but the
rest of the file uses RVV_INSN_OPERANDS_MAX already. Could you adjust this
as well as emit_vlmax_ternary_insn?
Thanks.
Regards
Robin
^ permalink raw reply [flat|nested] 8+ messages in thread
* Re: [PATCH] RISC-V: Support RVV floating-point ternary auto-vectorization
2023-06-21 11:12 [PATCH] RISC-V: Support RVV floating-point ternary auto-vectorization Juzhe-Zhong
2023-06-21 12:54 ` Robin Dapp
@ 2023-06-21 15:15 ` Jeff Law
2023-06-21 15:20 ` 钟居哲
1 sibling, 1 reply; 8+ messages in thread
From: Jeff Law @ 2023-06-21 15:15 UTC (permalink / raw)
To: Juzhe-Zhong, gcc-patches
Cc: kito.cheng, kito.cheng, palmer, palmer, rdapp.gcc
On 6/21/23 05:12, 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.
>
> gcc/testsuite/ChangeLog:
>
> * gcc.target/riscv/rvv/autovec/ternop/ternop-1.c: Add floating-point teranary tests.
> * gcc.target/riscv/rvv/autovec/ternop/ternop-2.c: Ditto.
> * gcc.target/riscv/rvv/autovec/ternop/ternop-3.c: Ditto.
> * gcc.target/riscv/rvv/autovec/ternop/ternop-4.c: Ditto.
> * gcc.target/riscv/rvv/autovec/ternop/ternop-5.c: Ditto.
> * gcc.target/riscv/rvv/autovec/ternop/ternop-6.c: Ditto.
> * gcc.target/riscv/rvv/autovec/ternop/ternop_run-1.c: Ditto.
> * gcc.target/riscv/rvv/autovec/ternop/ternop_run-2.c: Ditto.
> * gcc.target/riscv/rvv/autovec/ternop/ternop_run-3.c: Ditto.
> * gcc.target/riscv/rvv/autovec/ternop/ternop_run-4.c: Ditto.
> * gcc.target/riscv/rvv/autovec/ternop/ternop_run-5.c: Ditto.
> * gcc.target/riscv/rvv/autovec/ternop/ternop_run-6.c: Ditto.
> * gcc.target/riscv/rvv/autovec/ternop/ternop-10.c: New test.
> * gcc.target/riscv/rvv/autovec/ternop/ternop-11.c: New test.
> * gcc.target/riscv/rvv/autovec/ternop/ternop-12.c: New test.
> * gcc.target/riscv/rvv/autovec/ternop/ternop-7.c: New test.
> * gcc.target/riscv/rvv/autovec/ternop/ternop-8.c: New test.
> * gcc.target/riscv/rvv/autovec/ternop/ternop-9.c: New test.
> * gcc.target/riscv/rvv/autovec/ternop/ternop_run-10.c: New test.
> * gcc.target/riscv/rvv/autovec/ternop/ternop_run-11.c: New test.
> * gcc.target/riscv/rvv/autovec/ternop/ternop_run-12.c: New test.
> * gcc.target/riscv/rvv/autovec/ternop/ternop_run-7.c: New test.
> * gcc.target/riscv/rvv/autovec/ternop/ternop_run-8.c: New test.
> * gcc.target/riscv/rvv/autovec/ternop/ternop_run-9.c: New test.
> * gcc.target/riscv/rvv/autovec/ternop/ternop_run_zvfh-1.c: New test.
> * gcc.target/riscv/rvv/autovec/ternop/ternop_run_zvfh-10.c: New test.
> * gcc.target/riscv/rvv/autovec/ternop/ternop_run_zvfh-11.c: New test.
> * gcc.target/riscv/rvv/autovec/ternop/ternop_run_zvfh-12.c: New test.
> * gcc.target/riscv/rvv/autovec/ternop/ternop_run_zvfh-2.c: New test.
> * gcc.target/riscv/rvv/autovec/ternop/ternop_run_zvfh-3.c: New test.
> * gcc.target/riscv/rvv/autovec/ternop/ternop_run_zvfh-4.c: New test.
> * gcc.target/riscv/rvv/autovec/ternop/ternop_run_zvfh-5.c: New test.
> * gcc.target/riscv/rvv/autovec/ternop/ternop_run_zvfh-6.c: New test.
> * gcc.target/riscv/rvv/autovec/ternop/ternop_run_zvfh-7.c: New test.
> * gcc.target/riscv/rvv/autovec/ternop/ternop_run_zvfh-8.c: New test.
> * gcc.target/riscv/rvv/autovec/ternop/ternop_run_zvfh-9.c: New test.
>
> ---
> +
> +(define_insn_and_split "*fma<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_scratch:SI 4 "=r,r,r"))]
> + "TARGET_VECTOR"
> + "#"
> + "&& reload_completed"
> + [(const_int 0)]
> + {
> + PUT_MODE (operands[4], Pmode);
Maybe this has already been answered, but why not get the mode right in
the expander & pattern as opposed to blindly changing it in the C fragment?
It's probably technically safe to do what you've done, mostly because by
the time the C code runs, we've turned the scratch into a hard register
and I suspect the code to allocate scratches probably constructs a new
hard reg for each scratch rather than using a shared object.
But if we can, let's get the mode right from the beginning.
I'll note the existing define_insn_and_splits for integer FMAs have this
same wart.
jeff
^ permalink raw reply [flat|nested] 8+ messages in thread
* Re: Re: [PATCH] RISC-V: Support RVV floating-point ternary auto-vectorization
2023-06-21 15:15 ` Jeff Law
@ 2023-06-21 15:20 ` 钟居哲
2023-06-21 15:21 ` Jeff Law
0 siblings, 1 reply; 8+ messages in thread
From: 钟居哲 @ 2023-06-21 15:20 UTC (permalink / raw)
To: Jeff Law, gcc-patches; +Cc: kito.cheng, kito.cheng, palmer, palmer, rdapp.gcc
[-- Attachment #1: Type: text/plain, Size: 5085 bytes --]
I failed to make Pmode of the of operand.
I have tried the following
clobber (match_dup_4)
But it causes to many issues. I do many tries turns out only the current solution can work.
juzhe.zhong@rivai.ai
From: Jeff Law
Date: 2023-06-21 23:15
To: Juzhe-Zhong; gcc-patches
CC: kito.cheng; kito.cheng; palmer; palmer; rdapp.gcc
Subject: Re: [PATCH] RISC-V: Support RVV floating-point ternary auto-vectorization
On 6/21/23 05:12, 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.
>
> gcc/testsuite/ChangeLog:
>
> * gcc.target/riscv/rvv/autovec/ternop/ternop-1.c: Add floating-point teranary tests.
> * gcc.target/riscv/rvv/autovec/ternop/ternop-2.c: Ditto.
> * gcc.target/riscv/rvv/autovec/ternop/ternop-3.c: Ditto.
> * gcc.target/riscv/rvv/autovec/ternop/ternop-4.c: Ditto.
> * gcc.target/riscv/rvv/autovec/ternop/ternop-5.c: Ditto.
> * gcc.target/riscv/rvv/autovec/ternop/ternop-6.c: Ditto.
> * gcc.target/riscv/rvv/autovec/ternop/ternop_run-1.c: Ditto.
> * gcc.target/riscv/rvv/autovec/ternop/ternop_run-2.c: Ditto.
> * gcc.target/riscv/rvv/autovec/ternop/ternop_run-3.c: Ditto.
> * gcc.target/riscv/rvv/autovec/ternop/ternop_run-4.c: Ditto.
> * gcc.target/riscv/rvv/autovec/ternop/ternop_run-5.c: Ditto.
> * gcc.target/riscv/rvv/autovec/ternop/ternop_run-6.c: Ditto.
> * gcc.target/riscv/rvv/autovec/ternop/ternop-10.c: New test.
> * gcc.target/riscv/rvv/autovec/ternop/ternop-11.c: New test.
> * gcc.target/riscv/rvv/autovec/ternop/ternop-12.c: New test.
> * gcc.target/riscv/rvv/autovec/ternop/ternop-7.c: New test.
> * gcc.target/riscv/rvv/autovec/ternop/ternop-8.c: New test.
> * gcc.target/riscv/rvv/autovec/ternop/ternop-9.c: New test.
> * gcc.target/riscv/rvv/autovec/ternop/ternop_run-10.c: New test.
> * gcc.target/riscv/rvv/autovec/ternop/ternop_run-11.c: New test.
> * gcc.target/riscv/rvv/autovec/ternop/ternop_run-12.c: New test.
> * gcc.target/riscv/rvv/autovec/ternop/ternop_run-7.c: New test.
> * gcc.target/riscv/rvv/autovec/ternop/ternop_run-8.c: New test.
> * gcc.target/riscv/rvv/autovec/ternop/ternop_run-9.c: New test.
> * gcc.target/riscv/rvv/autovec/ternop/ternop_run_zvfh-1.c: New test.
> * gcc.target/riscv/rvv/autovec/ternop/ternop_run_zvfh-10.c: New test.
> * gcc.target/riscv/rvv/autovec/ternop/ternop_run_zvfh-11.c: New test.
> * gcc.target/riscv/rvv/autovec/ternop/ternop_run_zvfh-12.c: New test.
> * gcc.target/riscv/rvv/autovec/ternop/ternop_run_zvfh-2.c: New test.
> * gcc.target/riscv/rvv/autovec/ternop/ternop_run_zvfh-3.c: New test.
> * gcc.target/riscv/rvv/autovec/ternop/ternop_run_zvfh-4.c: New test.
> * gcc.target/riscv/rvv/autovec/ternop/ternop_run_zvfh-5.c: New test.
> * gcc.target/riscv/rvv/autovec/ternop/ternop_run_zvfh-6.c: New test.
> * gcc.target/riscv/rvv/autovec/ternop/ternop_run_zvfh-7.c: New test.
> * gcc.target/riscv/rvv/autovec/ternop/ternop_run_zvfh-8.c: New test.
> * gcc.target/riscv/rvv/autovec/ternop/ternop_run_zvfh-9.c: New test.
>
> ---
> +
> +(define_insn_and_split "*fma<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_scratch:SI 4 "=r,r,r"))]
> + "TARGET_VECTOR"
> + "#"
> + "&& reload_completed"
> + [(const_int 0)]
> + {
> + PUT_MODE (operands[4], Pmode);
Maybe this has already been answered, but why not get the mode right in
the expander & pattern as opposed to blindly changing it in the C fragment?
It's probably technically safe to do what you've done, mostly because by
the time the C code runs, we've turned the scratch into a hard register
and I suspect the code to allocate scratches probably constructs a new
hard reg for each scratch rather than using a shared object.
But if we can, let's get the mode right from the beginning.
I'll note the existing define_insn_and_splits for integer FMAs have this
same wart.
jeff
^ permalink raw reply [flat|nested] 8+ messages in thread
* Re: [PATCH] RISC-V: Support RVV floating-point ternary auto-vectorization
2023-06-21 15:20 ` 钟居哲
@ 2023-06-21 15:21 ` Jeff Law
2023-06-21 15:28 ` 钟居哲
0 siblings, 1 reply; 8+ messages in thread
From: Jeff Law @ 2023-06-21 15:21 UTC (permalink / raw)
To: 钟居哲, gcc-patches
Cc: kito.cheng, kito.cheng, palmer, palmer, rdapp.gcc
On 6/21/23 09:20, 钟居哲 wrote:
> I failed to make Pmode of the of operand.
>
> I have tried the following
>
> clobber (match_dup_4)
> But it causes to many issues. I do many tries turns out only the current
> solution can work.
Can you describe more concretely what failed?
Offhand I can't think of a reason why this shouldn't work and what
you're doing seems long term fragile/wrong.
jeff
^ permalink raw reply [flat|nested] 8+ messages in thread
* Re: Re: [PATCH] RISC-V: Support RVV floating-point ternary auto-vectorization
2023-06-21 15:21 ` Jeff Law
@ 2023-06-21 15:28 ` 钟居哲
2023-06-21 15:32 ` Jeff Law
0 siblings, 1 reply; 8+ messages in thread
From: 钟居哲 @ 2023-06-21 15:28 UTC (permalink / raw)
To: Jeff Law, gcc-patches; +Cc: kito.cheng, kito.cheng, palmer, palmer, rdapp.gcc
[-- Attachment #1: Type: text/plain, Size: 2058 bytes --]
I have tried:
(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 "=r,r,r"))]
"TARGET_VECTOR"
"#"
"&& reload_completed"
[(const_int 0)]
{
riscv_vector::emit_vlmax_vsetvl (<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, <MODE>mode),
riscv_vector::RVV_TERNOP, ops, operands[4]);
DONE;
}
[(set_attr "type" "vfmuladd")
(set_attr "mode" "<MODE>")])
It fails and create ICE.
juzhe.zhong@rivai.ai
From: Jeff Law
Date: 2023-06-21 23:21
To: 钟居哲; gcc-patches
CC: kito.cheng; kito.cheng; palmer; palmer; rdapp.gcc
Subject: Re: [PATCH] RISC-V: Support RVV floating-point ternary auto-vectorization
On 6/21/23 09:20, 钟居哲 wrote:
> I failed to make Pmode of the of operand.
>
> I have tried the following
>
> clobber (match_dup_4)
> But it causes to many issues. I do many tries turns out only the current
> solution can work.
Can you describe more concretely what failed?
Offhand I can't think of a reason why this shouldn't work and what
you're doing seems long term fragile/wrong.
jeff
^ permalink raw reply [flat|nested] 8+ messages in thread
* Re: [PATCH] RISC-V: Support RVV floating-point ternary auto-vectorization
2023-06-21 15:28 ` 钟居哲
@ 2023-06-21 15:32 ` Jeff Law
2023-06-21 15:55 ` 钟居哲
0 siblings, 1 reply; 8+ messages in thread
From: Jeff Law @ 2023-06-21 15:32 UTC (permalink / raw)
To: 钟居哲, gcc-patches
Cc: kito.cheng, kito.cheng, palmer, palmer, rdapp.gcc
On 6/21/23 09:28, 钟居哲 wrote:
> I have tried:
> (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_dup4))])]
> "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 "=r,r,r"))]
> "TARGET_VECTOR"
> "#"
> "&& reload_completed"
> [(const_int 0)]
> {
> riscv_vector::emit_vlmax_vsetvl (<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,
> <MODE>mode),
> riscv_vector::RVV_TERNOP, ops, operands[4]);
> DONE;
> }
> [(set_attr "type" "vfmuladd")
> (set_attr "mode" "<MODE>")])
>
> It fails and create ICE.
But where did ICE and *why*? That's really the question. Changing the
mode just looks like papering over a more serious issue.
jeff
^ permalink raw reply [flat|nested] 8+ messages in thread
* Re: Re: [PATCH] RISC-V: Support RVV floating-point ternary auto-vectorization
2023-06-21 15:32 ` Jeff Law
@ 2023-06-21 15:55 ` 钟居哲
0 siblings, 0 replies; 8+ messages in thread
From: 钟居哲 @ 2023-06-21 15:55 UTC (permalink / raw)
To: Jeff Law, gcc-patches; +Cc: kito.cheng, kito.cheng, palmer, palmer, rdapp.gcc
[-- Attachment #1: Type: text/plain, Size: 3566 bytes --]
Hi, Jeff.
I tried again:
+(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>")])
It seems to work and all test have passed.
Thanks for pointing this out.
I have sent V3:
https://gcc.gnu.org/pipermail/gcc-patches/2023-June/622481.html
If this implementation is more reasonable, I will send a separate patch to adjust integer ternary autovec patterns.
juzhe.zhong@rivai.ai
From: Jeff Law
Date: 2023-06-21 23:32
To: 钟居哲; gcc-patches
CC: kito.cheng; kito.cheng; palmer; palmer; rdapp.gcc
Subject: Re: [PATCH] RISC-V: Support RVV floating-point ternary auto-vectorization
On 6/21/23 09:28, 钟居哲 wrote:
> I have tried:
> (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_dup4))])]
> "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 "=r,r,r"))]
> "TARGET_VECTOR"
> "#"
> "&& reload_completed"
> [(const_int 0)]
> {
> riscv_vector::emit_vlmax_vsetvl (<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,
> <MODE>mode),
> riscv_vector::RVV_TERNOP, ops, operands[4]);
> DONE;
> }
> [(set_attr "type" "vfmuladd")
> (set_attr "mode" "<MODE>")])
>
> It fails and create ICE.
But where did ICE and *why*? That's really the question. Changing the
mode just looks like papering over a more serious issue.
jeff
^ permalink raw reply [flat|nested] 8+ messages in thread
end of thread, other threads:[~2023-06-21 15:55 UTC | newest]
Thread overview: 8+ messages (download: mbox.gz / follow: Atom feed)
-- links below jump to the message on this page --
2023-06-21 11:12 [PATCH] RISC-V: Support RVV floating-point ternary auto-vectorization Juzhe-Zhong
2023-06-21 12:54 ` Robin Dapp
2023-06-21 15:15 ` Jeff Law
2023-06-21 15:20 ` 钟居哲
2023-06-21 15:21 ` Jeff Law
2023-06-21 15:28 ` 钟居哲
2023-06-21 15:32 ` Jeff Law
2023-06-21 15:55 ` 钟居哲
This is a public inbox, see mirroring instructions
for how to clone and mirror all data and code used for this inbox;
as well as URLs for read-only IMAP folder(s) and NNTP newsgroup(s).