* [PATCH] RISC-V: Add vector fmin/fmax expanders.
@ 2023-10-30 16:08 Robin Dapp
2023-10-30 18:31 ` Joseph Myers
0 siblings, 1 reply; 5+ messages in thread
From: Robin Dapp @ 2023-10-30 16:08 UTC (permalink / raw)
To: gcc-patches, palmer, Kito Cheng, jeffreyalaw, juzhe.zhong; +Cc: rdapp.gcc
Hi,
this patch adds expanders for fmin and fmax and the associated
cond and reduc ones. As per RISC-V V spec 1.0 vfmin/vfmax are
IEEE 754-2008 compliant so that should be ok.
Regards
Robin
gcc/ChangeLog:
* config/riscv/autovec.md (<ieee_fmaxmin_op><mode>3): fmax/fmin
expanders.
(cond_<ieee_fmaxmin_op><mode>): Ditto.
(cond_len_<ieee_fmaxmin_op><mode>): Ditto.
(reduc_fmax_scal_<mode>): Ditto.
(reduc_fmin_scal_<mode>): Ditto.
* config/riscv/riscv-v.cc (needs_fp_rounding): Add fmin/fmax.
* config/riscv/vector-iterators.md (fmin): New UNSPEC.
(UNSPEC_VFMIN): Ditto.
* config/riscv/vector.md (@pred_<ieee_fmaxmin_op><mode>): Add
UNSPEC insn patterns.
(@pred_<ieee_fmaxmin_op><mode>_scalar): Ditto.
gcc/testsuite/ChangeLog:
* gcc.target/riscv/rvv/autovec/cond/cond_fmax-1.c: Remove
-ffast-math.
* gcc.target/riscv/rvv/autovec/cond/cond_fmax-2.c: Ditto.
* gcc.target/riscv/rvv/autovec/cond/cond_fmax-3.c: Ditto.
* gcc.target/riscv/rvv/autovec/cond/cond_fmax-4.c: Ditto.
* gcc.target/riscv/rvv/autovec/cond/cond_fmax_run-1.c: Ditto.
* gcc.target/riscv/rvv/autovec/cond/cond_fmax_run-2.c: Ditto.
* gcc.target/riscv/rvv/autovec/cond/cond_fmax_run-3.c: Ditto.
* gcc.target/riscv/rvv/autovec/cond/cond_fmax_run-4.c: Ditto.
* gcc.target/riscv/rvv/autovec/cond/cond_fmin-1.c: Ditto.
* gcc.target/riscv/rvv/autovec/cond/cond_fmin-2.c: Ditto.
* gcc.target/riscv/rvv/autovec/cond/cond_fmin-3.c: Ditto.
* gcc.target/riscv/rvv/autovec/cond/cond_fmin-4.c: Ditto.
* gcc.target/riscv/rvv/autovec/cond/cond_fmin_run-1.c: Ditto.
* gcc.target/riscv/rvv/autovec/cond/cond_fmin_run-2.c: Ditto.
* gcc.target/riscv/rvv/autovec/cond/cond_fmin_run-3.c: Ditto.
* gcc.target/riscv/rvv/autovec/cond/cond_fmin_run-4.c: Ditto.
* gcc.target/riscv/rvv/autovec/binop/fmax-1.c: New test.
* gcc.target/riscv/rvv/autovec/binop/fmax_run-1.c: New test.
* gcc.target/riscv/rvv/autovec/binop/fmax_zvfh-1.c: New test.
* gcc.target/riscv/rvv/autovec/binop/fmax_zvfh_run-1.c: New test.
* gcc.target/riscv/rvv/autovec/binop/fmin-1.c: New test.
* gcc.target/riscv/rvv/autovec/binop/fmin_run-1.c: New test.
* gcc.target/riscv/rvv/autovec/binop/fmin_zvfh-1.c: New test.
* gcc.target/riscv/rvv/autovec/binop/fmin_zvfh_run-1.c: New test.
* gcc.target/riscv/rvv/autovec/cond/cond_fmax_zvfh-1.c: New test.
* gcc.target/riscv/rvv/autovec/cond/cond_fmax_zvfh-2.c: New test.
* gcc.target/riscv/rvv/autovec/cond/cond_fmax_zvfh-3.c: New test.
* gcc.target/riscv/rvv/autovec/cond/cond_fmax_zvfh-4.c: New test.
* gcc.target/riscv/rvv/autovec/cond/cond_fmax_zvfh_run-1.c: New test.
* gcc.target/riscv/rvv/autovec/cond/cond_fmax_zvfh_run-2.c: New test.
* gcc.target/riscv/rvv/autovec/cond/cond_fmax_zvfh_run-3.c: New test.
* gcc.target/riscv/rvv/autovec/cond/cond_fmax_zvfh_run-4.c: New test.
* gcc.target/riscv/rvv/autovec/cond/cond_fmin_zvfh-1.c: New test.
* gcc.target/riscv/rvv/autovec/cond/cond_fmin_zvfh-2.c: New test.
* gcc.target/riscv/rvv/autovec/cond/cond_fmin_zvfh-3.c: New test.
* gcc.target/riscv/rvv/autovec/cond/cond_fmin_zvfh-4.c: New test.
* gcc.target/riscv/rvv/autovec/cond/cond_fmin_zvfh_run-1.c: New test.
* gcc.target/riscv/rvv/autovec/cond/cond_fmin_zvfh_run-2.c: New test.
* gcc.target/riscv/rvv/autovec/cond/cond_fmin_zvfh_run-3.c: New test.
* gcc.target/riscv/rvv/autovec/cond/cond_fmin_zvfh_run-4.c: New test.
* gcc.target/riscv/rvv/autovec/reduc/reduc-10.c: New test.
* gcc.target/riscv/rvv/autovec/reduc/reduc_run-10.c: New test.
* gcc.target/riscv/rvv/autovec/reduc/reduc_run_zvfh-10.c: New test.
* gcc.target/riscv/rvv/autovec/reduc/reduc_zvfh-10.c: New test.
---
gcc/config/riscv/autovec.md | 72 +++++++++++++++++++
gcc/config/riscv/riscv-v.cc | 2 +
gcc/config/riscv/vector-iterators.md | 8 +++
gcc/config/riscv/vector.md | 43 +++++++++++
.../riscv/rvv/autovec/binop/fmax-1.c | 24 +++++++
.../riscv/rvv/autovec/binop/fmax_run-1.c | 47 ++++++++++++
.../riscv/rvv/autovec/binop/fmax_zvfh-1.c | 23 ++++++
.../riscv/rvv/autovec/binop/fmax_zvfh_run-1.c | 48 +++++++++++++
.../riscv/rvv/autovec/binop/fmin-1.c | 10 +++
.../riscv/rvv/autovec/binop/fmin_run-1.c | 5 ++
.../riscv/rvv/autovec/binop/fmin_zvfh-1.c | 10 +++
.../riscv/rvv/autovec/binop/fmin_zvfh_run-1.c | 5 ++
.../riscv/rvv/autovec/cond/cond_fmax-1.c | 6 +-
.../riscv/rvv/autovec/cond/cond_fmax-2.c | 3 +-
.../riscv/rvv/autovec/cond/cond_fmax-3.c | 6 +-
.../riscv/rvv/autovec/cond/cond_fmax-4.c | 6 +-
.../riscv/rvv/autovec/cond/cond_fmax_run-1.c | 3 +-
.../riscv/rvv/autovec/cond/cond_fmax_run-2.c | 3 +-
.../riscv/rvv/autovec/cond/cond_fmax_run-3.c | 3 +-
.../riscv/rvv/autovec/cond/cond_fmax_run-4.c | 3 +-
.../riscv/rvv/autovec/cond/cond_fmax_zvfh-1.c | 32 +++++++++
.../riscv/rvv/autovec/cond/cond_fmax_zvfh-2.c | 32 +++++++++
.../riscv/rvv/autovec/cond/cond_fmax_zvfh-3.c | 32 +++++++++
.../riscv/rvv/autovec/cond/cond_fmax_zvfh-4.c | 32 +++++++++
.../rvv/autovec/cond/cond_fmax_zvfh_run-1.c | 33 +++++++++
.../rvv/autovec/cond/cond_fmax_zvfh_run-2.c | 32 +++++++++
.../rvv/autovec/cond/cond_fmax_zvfh_run-3.c | 33 +++++++++
.../rvv/autovec/cond/cond_fmax_zvfh_run-4.c | 33 +++++++++
.../riscv/rvv/autovec/cond/cond_fmin-1.c | 5 +-
.../riscv/rvv/autovec/cond/cond_fmin-2.c | 3 +-
.../riscv/rvv/autovec/cond/cond_fmin-3.c | 5 +-
.../riscv/rvv/autovec/cond/cond_fmin-4.c | 5 +-
.../riscv/rvv/autovec/cond/cond_fmin_run-1.c | 2 +-
.../riscv/rvv/autovec/cond/cond_fmin_run-2.c | 2 +-
.../riscv/rvv/autovec/cond/cond_fmin_run-3.c | 2 +-
.../riscv/rvv/autovec/cond/cond_fmin_run-4.c | 2 +-
.../riscv/rvv/autovec/cond/cond_fmin_zvfh-1.c | 11 +++
.../riscv/rvv/autovec/cond/cond_fmin_zvfh-2.c | 10 +++
.../riscv/rvv/autovec/cond/cond_fmin_zvfh-3.c | 10 +++
.../riscv/rvv/autovec/cond/cond_fmin_zvfh-4.c | 10 +++
.../rvv/autovec/cond/cond_fmin_zvfh_run-1.c | 5 ++
.../rvv/autovec/cond/cond_fmin_zvfh_run-2.c | 5 ++
.../rvv/autovec/cond/cond_fmin_zvfh_run-3.c | 5 ++
.../rvv/autovec/cond/cond_fmin_zvfh_run-4.c | 5 ++
.../riscv/rvv/autovec/reduc/reduc-10.c | 26 +++++++
.../riscv/rvv/autovec/reduc/reduc_run-10.c | 41 +++++++++++
.../rvv/autovec/reduc/reduc_run_zvfh-10.c | 41 +++++++++++
.../riscv/rvv/autovec/reduc/reduc_zvfh-10.c | 24 +++++++
48 files changed, 783 insertions(+), 25 deletions(-)
create mode 100644 gcc/testsuite/gcc.target/riscv/rvv/autovec/binop/fmax-1.c
create mode 100644 gcc/testsuite/gcc.target/riscv/rvv/autovec/binop/fmax_run-1.c
create mode 100644 gcc/testsuite/gcc.target/riscv/rvv/autovec/binop/fmax_zvfh-1.c
create mode 100644 gcc/testsuite/gcc.target/riscv/rvv/autovec/binop/fmax_zvfh_run-1.c
create mode 100644 gcc/testsuite/gcc.target/riscv/rvv/autovec/binop/fmin-1.c
create mode 100644 gcc/testsuite/gcc.target/riscv/rvv/autovec/binop/fmin_run-1.c
create mode 100644 gcc/testsuite/gcc.target/riscv/rvv/autovec/binop/fmin_zvfh-1.c
create mode 100644 gcc/testsuite/gcc.target/riscv/rvv/autovec/binop/fmin_zvfh_run-1.c
create mode 100644 gcc/testsuite/gcc.target/riscv/rvv/autovec/cond/cond_fmax_zvfh-1.c
create mode 100644 gcc/testsuite/gcc.target/riscv/rvv/autovec/cond/cond_fmax_zvfh-2.c
create mode 100644 gcc/testsuite/gcc.target/riscv/rvv/autovec/cond/cond_fmax_zvfh-3.c
create mode 100644 gcc/testsuite/gcc.target/riscv/rvv/autovec/cond/cond_fmax_zvfh-4.c
create mode 100644 gcc/testsuite/gcc.target/riscv/rvv/autovec/cond/cond_fmax_zvfh_run-1.c
create mode 100644 gcc/testsuite/gcc.target/riscv/rvv/autovec/cond/cond_fmax_zvfh_run-2.c
create mode 100644 gcc/testsuite/gcc.target/riscv/rvv/autovec/cond/cond_fmax_zvfh_run-3.c
create mode 100644 gcc/testsuite/gcc.target/riscv/rvv/autovec/cond/cond_fmax_zvfh_run-4.c
create mode 100644 gcc/testsuite/gcc.target/riscv/rvv/autovec/cond/cond_fmin_zvfh-1.c
create mode 100644 gcc/testsuite/gcc.target/riscv/rvv/autovec/cond/cond_fmin_zvfh-2.c
create mode 100644 gcc/testsuite/gcc.target/riscv/rvv/autovec/cond/cond_fmin_zvfh-3.c
create mode 100644 gcc/testsuite/gcc.target/riscv/rvv/autovec/cond/cond_fmin_zvfh-4.c
create mode 100644 gcc/testsuite/gcc.target/riscv/rvv/autovec/cond/cond_fmin_zvfh_run-1.c
create mode 100644 gcc/testsuite/gcc.target/riscv/rvv/autovec/cond/cond_fmin_zvfh_run-2.c
create mode 100644 gcc/testsuite/gcc.target/riscv/rvv/autovec/cond/cond_fmin_zvfh_run-3.c
create mode 100644 gcc/testsuite/gcc.target/riscv/rvv/autovec/cond/cond_fmin_zvfh_run-4.c
create mode 100644 gcc/testsuite/gcc.target/riscv/rvv/autovec/reduc/reduc-10.c
create mode 100644 gcc/testsuite/gcc.target/riscv/rvv/autovec/reduc/reduc_run-10.c
create mode 100644 gcc/testsuite/gcc.target/riscv/rvv/autovec/reduc/reduc_run_zvfh-10.c
create mode 100644 gcc/testsuite/gcc.target/riscv/rvv/autovec/reduc/reduc_zvfh-10.c
diff --git a/gcc/config/riscv/autovec.md b/gcc/config/riscv/autovec.md
index 5f49d73be44..ea7373304d4 100644
--- a/gcc/config/riscv/autovec.md
+++ b/gcc/config/riscv/autovec.md
@@ -1441,6 +1441,22 @@ (define_insn_and_split "<optab><mode>3"
}
[(set_attr "type" "vfminmax")])
+(define_insn_and_split "<ieee_fmaxmin_op><mode>3"
+ [(set (match_operand:V_VLSF 0 "register_operand")
+ (unspec:V_VLSF
+ [(match_operand:V_VLSF 1 "register_operand")
+ (match_operand:V_VLSF 2 "register_operand")] UNSPEC_VFMAXMIN))]
+ "TARGET_VECTOR && can_create_pseudo_p ()"
+ "#"
+ "&& 1"
+ [(const_int 0)]
+{
+ riscv_vector::emit_vlmax_insn (code_for_pred (<IEEE_FMAXMIN_OP>, <MODE>mode),
+ riscv_vector::BINARY_OP, operands);
+ DONE;
+}
+[(set_attr "type" "vfminmax")])
+
;; -------------------------------------------------------------------------------
;; ---- [FP] Sign copying
;; -------------------------------------------------------------------------------
@@ -1741,6 +1757,36 @@ (define_expand "cond_len_<optab><mode>"
DONE;
})
+(define_expand "cond_<ieee_fmaxmin_op><mode>"
+ [(match_operand:V_VLSF 0 "register_operand")
+ (match_operand:<VM> 1 "vector_mask_operand")
+ (unspec:V_VLSF
+ [(match_operand:V_VLSF 2 "register_operand")
+ (match_operand:V_VLSF 3 "register_operand")] UNSPEC_VFMAXMIN)
+ (match_operand:V_VLSF 4 "autovec_else_operand")]
+ "TARGET_VECTOR"
+{
+ insn_code icode = code_for_pred (<IEEE_FMAXMIN_OP>, <MODE>mode);
+ riscv_vector::expand_cond_binop (icode, operands);
+ DONE;
+})
+
+(define_expand "cond_len_<ieee_fmaxmin_op><mode>"
+ [(match_operand:VF 0 "register_operand")
+ (match_operand:<VM> 1 "vector_mask_operand")
+ (unspec:VF
+ [(match_operand:VF 2 "register_operand")
+ (match_operand:VF 3 "register_operand")] UNSPEC_VFMAXMIN)
+ (match_operand:VF 4 "autovec_else_operand")
+ (match_operand 5 "autovec_length_operand")
+ (match_operand 6 "const_0_operand")]
+ "TARGET_VECTOR"
+{
+ insn_code icode = code_for_pred (<IEEE_FMAXMIN_OP>, <MODE>mode);
+ riscv_vector::expand_cond_len_binop (icode, operands);
+ DONE;
+})
+
;; -------------------------------------------------------------------------
;; ---- [INT] Conditional ternary operations
;; -------------------------------------------------------------------------
@@ -2097,6 +2143,32 @@ (define_expand "reduc_smin_scal_<mode>"
DONE;
})
+(define_expand "reduc_fmax_scal_<mode>"
+ [(match_operand:<VEL> 0 "register_operand")
+ (match_operand:V_VLSF 1 "register_operand")]
+ "TARGET_VECTOR"
+{
+ REAL_VALUE_TYPE rv;
+ real_inf (&rv, true);
+ rtx f = const_double_from_real_value (rv, <VEL>mode);
+ riscv_vector::expand_reduction (UNSPEC_REDUC_MAX, riscv_vector::REDUCE_OP,
+ operands, f);
+ DONE;
+})
+
+(define_expand "reduc_fmin_scal_<mode>"
+ [(match_operand:<VEL> 0 "register_operand")
+ (match_operand:V_VLSF 1 "register_operand")]
+ "TARGET_VECTOR"
+{
+ REAL_VALUE_TYPE rv;
+ real_inf (&rv, false);
+ rtx f = const_double_from_real_value (rv, <VEL>mode);
+ riscv_vector::expand_reduction (UNSPEC_REDUC_MIN, riscv_vector::REDUCE_OP,
+ operands, f);
+ DONE;
+})
+
;; -------------------------------------------------------------------------
;; ---- [FP] Left-to-right reductions
;; -------------------------------------------------------------------------
diff --git a/gcc/config/riscv/riscv-v.cc b/gcc/config/riscv/riscv-v.cc
index 53991cc1090..ba403f9cff4 100644
--- a/gcc/config/riscv/riscv-v.cc
+++ b/gcc/config/riscv/riscv-v.cc
@@ -3207,7 +3207,9 @@ needs_fp_rounding (unsigned icode, machine_mode mode)
return false;
return icode != maybe_code_for_pred (SMIN, mode)
+ && icode != maybe_code_for_pred (UNSPEC_VFMIN, mode)
&& icode != maybe_code_for_pred (SMAX, mode)
+ && icode != maybe_code_for_pred (UNSPEC_VFMAX, mode)
&& icode != maybe_code_for_pred (NEG, mode)
&& icode != maybe_code_for_pred (ABS, mode)
/* narrower-FP -> FP */
diff --git a/gcc/config/riscv/vector-iterators.md b/gcc/config/riscv/vector-iterators.md
index e80a20dcfba..d9b5dec5edb 100644
--- a/gcc/config/riscv/vector-iterators.md
+++ b/gcc/config/riscv/vector-iterators.md
@@ -82,6 +82,9 @@ (define_c_enum "unspec" [
UNSPEC_VFFMA
+ UNSPEC_VFMAX
+ UNSPEC_VFMIN
+
;; Integer and Float Reduction
UNSPEC_REDUC
UNSPEC_REDUC_SUM
@@ -3479,6 +3482,11 @@ (define_int_attr ud_constraint [(UNSPEC_VSLIDEUP "=&vr,&vr,&vr,&vr") (UNSPEC_VSL
(define_int_attr UNSPEC [(UNSPEC_VSLIDE1UP "UNSPEC_VSLIDE1UP")
(UNSPEC_VSLIDE1DOWN "UNSPEC_VSLIDE1DOWN")])
+(define_int_iterator UNSPEC_VFMAXMIN [UNSPEC_VFMAX UNSPEC_VFMIN])
+
+(define_int_attr ieee_fmaxmin_op [(UNSPEC_VFMAX "fmax") (UNSPEC_VFMIN "fmin")])
+(define_int_attr IEEE_FMAXMIN_OP [(UNSPEC_VFMAX "UNSPEC_VFMAX") (UNSPEC_VFMIN "UNSPEC_VFMIN")])
+
(define_code_iterator any_int_binop [plus minus and ior xor ashift ashiftrt lshiftrt
smax umax smin umin mult div udiv mod umod
])
diff --git a/gcc/config/riscv/vector.md b/gcc/config/riscv/vector.md
index cea3dbf37a6..a4c09ff467e 100644
--- a/gcc/config/riscv/vector.md
+++ b/gcc/config/riscv/vector.md
@@ -6085,6 +6085,27 @@ (define_insn "@pred_<optab><mode>"
[(set_attr "type" "<float_insn_type>")
(set_attr "mode" "<MODE>")])
+(define_insn "@pred_<ieee_fmaxmin_op><mode>"
+ [(set (match_operand:V_VLSF 0 "register_operand" "=vd, vd, vr, vr")
+ (if_then_else:V_VLSF
+ (unspec:<VM>
+ [(match_operand:<VM> 1 "vector_mask_operand" " vm, vm,Wc1,Wc1")
+ (match_operand 5 "vector_length_operand" " rK, rK, rK, rK")
+ (match_operand 6 "const_int_operand" " i, i, i, i")
+ (match_operand 7 "const_int_operand" " i, i, i, i")
+ (match_operand 8 "const_int_operand" " i, i, i, i")
+ (reg:SI VL_REGNUM)
+ (reg:SI VTYPE_REGNUM)] UNSPEC_VPREDICATE)
+ (unspec:V_VLSF
+ [(match_operand:V_VLSF 3 "register_operand" " vr, vr, vr, vr")
+ (match_operand:V_VLSF 4 "register_operand" " vr, vr, vr, vr")]
+ UNSPEC_VFMAXMIN)
+ (match_operand:V_VLSF 2 "vector_merge_operand" " vu, 0, vu, 0")))]
+ "TARGET_VECTOR"
+ "v<ieee_fmaxmin_op>.vv\t%0,%3,%4%p1"
+ [(set_attr "type" "vfminmax")
+ (set_attr "mode" "<MODE>")])
+
(define_insn "@pred_<optab><mode>_scalar"
[(set (match_operand:VF 0 "register_operand" "=vd, vd, vr, vr")
(if_then_else:VF
@@ -6131,6 +6152,28 @@ (define_insn "@pred_<optab><mode>_scalar"
[(set_attr "type" "<float_insn_type>")
(set_attr "mode" "<MODE>")])
+(define_insn "@pred_<ieee_fmaxmin_op><mode>_scalar"
+ [(set (match_operand:VF 0 "register_operand" "=vd, vd, vr, vr")
+ (if_then_else:VF
+ (unspec:<VM>
+ [(match_operand:<VM> 1 "vector_mask_operand" " vm, vm,Wc1,Wc1")
+ (match_operand 5 "vector_length_operand" " rK, rK, rK, rK")
+ (match_operand 6 "const_int_operand" " i, i, i, i")
+ (match_operand 7 "const_int_operand" " i, i, i, i")
+ (match_operand 8 "const_int_operand" " i, i, i, i")
+ (reg:SI VL_REGNUM)
+ (reg:SI VTYPE_REGNUM)] UNSPEC_VPREDICATE)
+ (unspec:VF
+ [(match_operand:VF 3 "register_operand" " vr, vr, vr, vr")
+ (vec_duplicate:VF
+ (match_operand:<VEL> 4 "register_operand" " f, f, f, f"))]
+ UNSPEC_VFMAXMIN)
+ (match_operand:VF 2 "vector_merge_operand" " vu, 0, vu, 0")))]
+ "TARGET_VECTOR"
+ "v<ieee_fmaxmin_op>.vf\t%0,%3,%4%p1"
+ [(set_attr "type" "vfminmax")
+ (set_attr "mode" "<MODE>")])
+
(define_insn "@pred_<optab><mode>_scalar"
[(set (match_operand:VF 0 "register_operand" "=vd, vd, vr, vr")
(if_then_else:VF
diff --git a/gcc/testsuite/gcc.target/riscv/rvv/autovec/binop/fmax-1.c b/gcc/testsuite/gcc.target/riscv/rvv/autovec/binop/fmax-1.c
new file mode 100644
index 00000000000..6141ef12ac8
--- /dev/null
+++ b/gcc/testsuite/gcc.target/riscv/rvv/autovec/binop/fmax-1.c
@@ -0,0 +1,24 @@
+/* { dg-do compile } */
+/* { dg-additional-options "-march=rv32gcv -mabi=ilp32d --param=riscv-autovec-preference=scalable --param vect-epilogues-nomask=0" } */
+
+#include <stdint-gcc.h>
+
+#ifndef FN
+#define FN(X) __builtin_fmax##X
+#endif
+
+#define DEF_LOOP(FN, SUFFIX, TYPE) \
+ void __attribute__ ((noipa)) \
+ test_##TYPE (TYPE *__restrict x, TYPE *__restrict y, int n) \
+ { \
+ for (int i = 0; i < n; ++i) \
+ x[i] = FN (SUFFIX) (x[i], y[i]); \
+ }
+
+#define TEST_ALL(T) \
+ T (FN, f, float) \
+ T (FN, , double)
+
+TEST_ALL (DEF_LOOP)
+
+/* { dg-final { scan-assembler-times {vfmax\.vv\s+v[0-9]+,v[0-9]+,v[0-9]+} 2 } } */
diff --git a/gcc/testsuite/gcc.target/riscv/rvv/autovec/binop/fmax_run-1.c b/gcc/testsuite/gcc.target/riscv/rvv/autovec/binop/fmax_run-1.c
new file mode 100644
index 00000000000..3a68ad01999
--- /dev/null
+++ b/gcc/testsuite/gcc.target/riscv/rvv/autovec/binop/fmax_run-1.c
@@ -0,0 +1,47 @@
+/* { dg-do run { target { riscv_v } } } */
+/* { dg-additional-options "--param=riscv-autovec-preference=scalable" } */
+
+#include <math.h>
+#include "fmax-1.c"
+
+#define N 99
+
+#define TEST_LOOP(FN, SUFFIX, TYPE) \
+ { \
+ TYPE dst[N], x[N], y[N]; \
+ for (int i = 0; i < N; ++i) \
+ { \
+ x[i] = i; \
+ dst[i] = i; \
+ y[i] = ((i & 1) - 1) * i * i; \
+ } \
+ y[0] = -0.0; \
+ y[1] = 0.0; \
+ y[2] = nan ("0.0"); \
+ y[3] = INFINITY; \
+ y[4] = -INFINITY; \
+ x[5] = -0.0; \
+ x[6] = 0.0; \
+ x[7] = nan ("0.0"); \
+ x[8] = INFINITY; \
+ x[9] = -INFINITY; \
+ dst[5] = -0.0; \
+ dst[6] = 0.0; \
+ dst[7] = nan ("0.0"); \
+ dst[8] = INFINITY; \
+ dst[9] = -INFINITY; \
+ test_##TYPE (dst, y, N); \
+ for (int i = 0; i < N; ++i) \
+ { \
+ double ref = FN (SUFFIX) (x[i], y[i]); \
+ if (dst[i] != ref) \
+ __builtin_abort (); \
+ asm volatile ("" ::: "memory"); \
+ } \
+ }
+
+int __attribute__ ((optimize ("1"))) main (void)
+{
+ TEST_ALL (TEST_LOOP)
+ return 0;
+}
diff --git a/gcc/testsuite/gcc.target/riscv/rvv/autovec/binop/fmax_zvfh-1.c b/gcc/testsuite/gcc.target/riscv/rvv/autovec/binop/fmax_zvfh-1.c
new file mode 100644
index 00000000000..084c3a79d9e
--- /dev/null
+++ b/gcc/testsuite/gcc.target/riscv/rvv/autovec/binop/fmax_zvfh-1.c
@@ -0,0 +1,23 @@
+/* { dg-do compile } */
+/* { dg-additional-options "-march=rv32gcv_zvfh -mabi=ilp32d --param=riscv-autovec-preference=scalable --param vect-epilogues-nomask=0" } */
+
+#include <stdint-gcc.h>
+
+#ifndef FN
+#define FN(X) __builtin_fmax##X
+#endif
+
+#define DEF_LOOP(FN, SUFFIX, TYPE) \
+ void __attribute__ ((noipa)) \
+ test_##TYPE (TYPE *__restrict x, TYPE *__restrict y, int n) \
+ { \
+ for (int i = 0; i < n; ++i) \
+ x[i] = FN (SUFFIX) (x[i], y[i]); \
+ }
+
+#define TEST_ALL(T) \
+ T (FN, f16, _Float16) \
+
+TEST_ALL (DEF_LOOP)
+
+/* { dg-final { scan-assembler-times {vfmax\.vv\s+v[0-9]+,v[0-9]+,v[0-9]+} 1 } } */
diff --git a/gcc/testsuite/gcc.target/riscv/rvv/autovec/binop/fmax_zvfh_run-1.c b/gcc/testsuite/gcc.target/riscv/rvv/autovec/binop/fmax_zvfh_run-1.c
new file mode 100644
index 00000000000..bf388b4c726
--- /dev/null
+++ b/gcc/testsuite/gcc.target/riscv/rvv/autovec/binop/fmax_zvfh_run-1.c
@@ -0,0 +1,48 @@
+/* { dg-do run { target { riscv_zvfh } } } */
+/* { dg-additional-options "--param=riscv-autovec-preference=scalable" } */
+
+#include <math.h>
+#include "fmax_zvfh-1.c"
+
+#define N 99
+
+#define TEST_LOOP(FN, SUFFIX, TYPE) \
+ { \
+ TYPE dst[N], x[N], y[N]; \
+ for (int i = 0; i < N; ++i) \
+ { \
+ x[i] = i; \
+ dst[i] = i; \
+ y[i] = ((i & 1) - 1) * i * i; \
+ } \
+ y[0] = -0.0; \
+ y[1] = 0.0; \
+ y[2] = nan ("0.0"); \
+ y[3] = INFINITY; \
+ y[4] = -INFINITY; \
+ x[5] = -0.0; \
+ x[6] = 0.0; \
+ x[7] = nan ("0.0"); \
+ x[8] = INFINITY; \
+ x[9] = -INFINITY; \
+ dst[5] = -0.0; \
+ dst[6] = 0.0; \
+ dst[7] = nan ("0.0"); \
+ dst[8] = INFINITY; \
+ dst[9] = -INFINITY; \
+ kest_##TYPE (dst, y, N); \
+ for (int i = 0; i < N; ++i) \
+ { \
+ double ref = FN (SUFFIX) (x[i], y[i]); \
+ if (dst[i] != ref) \
+ __builtin_abort (); \
+ asm volatile ("" ::: "memory"); \
+ } \
+ }
+
+
+int __attribute__ ((optimize ("1"))) main (void)
+{
+ TEST_ALL (TEST_LOOP)
+ return 0;
+}
diff --git a/gcc/testsuite/gcc.target/riscv/rvv/autovec/binop/fmin-1.c b/gcc/testsuite/gcc.target/riscv/rvv/autovec/binop/fmin-1.c
new file mode 100644
index 00000000000..c388ddbc063
--- /dev/null
+++ b/gcc/testsuite/gcc.target/riscv/rvv/autovec/binop/fmin-1.c
@@ -0,0 +1,10 @@
+/* { dg-do compile } */
+/* { dg-additional-options "-march=rv32gcv -mabi=ilp32d --param=riscv-autovec-preference=scalable --param vect-epilogues-nomask=0" } */
+
+#include <stdint-gcc.h>
+
+#define FN(X) __builtin_fmin##X
+#include "fmax-1.c"
+
+/* { dg-final { scan-assembler-times {vfmin\.vv\s+v[0-9]+,v[0-9]+,v[0-9]+} 2 } } */
+
diff --git a/gcc/testsuite/gcc.target/riscv/rvv/autovec/binop/fmin_run-1.c b/gcc/testsuite/gcc.target/riscv/rvv/autovec/binop/fmin_run-1.c
new file mode 100644
index 00000000000..8ffb48aec5c
--- /dev/null
+++ b/gcc/testsuite/gcc.target/riscv/rvv/autovec/binop/fmin_run-1.c
@@ -0,0 +1,5 @@
+/* { dg-do run { target { riscv_v } } } */
+/* { dg-additional-options "--param=riscv-autovec-preference=scalable -fno-vect-cost-model" } */
+
+#define FN(X) __builtin_fmin##X
+#include "fmax_run-1.c"
diff --git a/gcc/testsuite/gcc.target/riscv/rvv/autovec/binop/fmin_zvfh-1.c b/gcc/testsuite/gcc.target/riscv/rvv/autovec/binop/fmin_zvfh-1.c
new file mode 100644
index 00000000000..fa9f2f95db9
--- /dev/null
+++ b/gcc/testsuite/gcc.target/riscv/rvv/autovec/binop/fmin_zvfh-1.c
@@ -0,0 +1,10 @@
+/* { dg-do compile } */
+/* { dg-additional-options "-march=rv32gcv_zvfh -mabi=ilp32d --param=riscv-autovec-preference=scalable --param vect-epilogues-nomask=0" } */
+
+#include <stdint-gcc.h>
+
+#define FN(X) __builtin_fmin##X
+#include "fmax_zvfh-1.c"
+
+/* { dg-final { scan-assembler-times {vfmin\.vv\s+v[0-9]+,v[0-9]+,v[0-9]+} 1 } } */
+
diff --git a/gcc/testsuite/gcc.target/riscv/rvv/autovec/binop/fmin_zvfh_run-1.c b/gcc/testsuite/gcc.target/riscv/rvv/autovec/binop/fmin_zvfh_run-1.c
new file mode 100644
index 00000000000..d914e6cabe9
--- /dev/null
+++ b/gcc/testsuite/gcc.target/riscv/rvv/autovec/binop/fmin_zvfh_run-1.c
@@ -0,0 +1,5 @@
+/* { dg-do run { target { riscv_zvfh } } } */
+/* { dg-additional-options "--param=riscv-autovec-preference=scalable" } */
+
+#define FN(X) __builtin_fmin##X
+#include "fmax_zvfh_run-1.c"
diff --git a/gcc/testsuite/gcc.target/riscv/rvv/autovec/cond/cond_fmax-1.c b/gcc/testsuite/gcc.target/riscv/rvv/autovec/cond/cond_fmax-1.c
index fe37794afeb..448e0def3a5 100644
--- a/gcc/testsuite/gcc.target/riscv/rvv/autovec/cond/cond_fmax-1.c
+++ b/gcc/testsuite/gcc.target/riscv/rvv/autovec/cond/cond_fmax-1.c
@@ -1,7 +1,8 @@
/* { dg-do compile } */
-/* { dg-additional-options "-march=rv32gcv_zvfh -mabi=ilp32d --param=riscv-autovec-preference=scalable -fno-vect-cost-model -ffast-math" } */
+/* { dg-additional-options "-march=rv32gcv_zvfh -mabi=ilp32d --param=riscv-autovec-preference=scalable -fno-vect-cost-model" } */
#include <stdint-gcc.h>
+#include <math.h>
#ifndef FN
#define FN(X) __builtin_fmax##X
@@ -24,10 +25,9 @@
T (FN, TYPE, PRED_TYPE, two, 2)
#define TEST_ALL(T) \
- TEST_TYPE (T, FN (f16), _Float16, int16_t) \
TEST_TYPE (T, FN (f32), float, int32_t) \
TEST_TYPE (T, FN (f64), double, int64_t)
TEST_ALL (DEF_LOOP)
-/* { dg-final { scan-assembler-times {vfmax\.vv\s+v[0-9]+,v[0-9]+,v[0-9]+,v0.t} 9 } } */
+/* { dg-final { scan-assembler-times {vfmax\.vv\s+v[0-9]+,v[0-9]+,v[0-9]+,v0.t} 6 } } */
diff --git a/gcc/testsuite/gcc.target/riscv/rvv/autovec/cond/cond_fmax-2.c b/gcc/testsuite/gcc.target/riscv/rvv/autovec/cond/cond_fmax-2.c
index f25562b22dd..63888e6ab98 100644
--- a/gcc/testsuite/gcc.target/riscv/rvv/autovec/cond/cond_fmax-2.c
+++ b/gcc/testsuite/gcc.target/riscv/rvv/autovec/cond/cond_fmax-2.c
@@ -1,7 +1,8 @@
/* { dg-do compile } */
-/* { dg-additional-options "-march=rv32gcv_zvfh -mabi=ilp32d --param=riscv-autovec-preference=scalable -fno-vect-cost-model -ffast-math" } */
+/* { dg-additional-options "-march=rv32gcv_zvfh -mabi=ilp32d --param=riscv-autovec-preference=scalable -fno-vect-cost-model" } */
#include <stdint-gcc.h>
+#include <math.h>
#ifndef FN
#define FN(X) __builtin_fmax##X
diff --git a/gcc/testsuite/gcc.target/riscv/rvv/autovec/cond/cond_fmax-3.c b/gcc/testsuite/gcc.target/riscv/rvv/autovec/cond/cond_fmax-3.c
index a23f4916caa..9e1c210538d 100644
--- a/gcc/testsuite/gcc.target/riscv/rvv/autovec/cond/cond_fmax-3.c
+++ b/gcc/testsuite/gcc.target/riscv/rvv/autovec/cond/cond_fmax-3.c
@@ -1,7 +1,8 @@
/* { dg-do compile } */
-/* { dg-additional-options "-march=rv32gcv_zvfh -mabi=ilp32d --param=riscv-autovec-preference=scalable -fno-vect-cost-model -ffast-math" } */
+/* { dg-additional-options "-march=rv32gcv_zvfh -mabi=ilp32d --param=riscv-autovec-preference=scalable -fno-vect-cost-model" } */
#include <stdint-gcc.h>
+#include <math.h>
#ifndef FN
#define FN(X) __builtin_fmax##X
@@ -24,10 +25,9 @@
T (FN, TYPE, PRED_TYPE, two, 2)
#define TEST_ALL(T) \
- TEST_TYPE (T, FN (f16), _Float16, int16_t) \
TEST_TYPE (T, FN (f32), float, int32_t) \
TEST_TYPE (T, FN (f64), double, int64_t)
TEST_ALL (DEF_LOOP)
-/* { dg-final { scan-assembler-times {vfmax\.vv\s+v[0-9]+,v[0-9]+,v[0-9]+,v0.t} 9 } } */
+/* { dg-final { scan-assembler-times {vfmax\.vv\s+v[0-9]+,v[0-9]+,v[0-9]+,v0.t} 6 } } */
diff --git a/gcc/testsuite/gcc.target/riscv/rvv/autovec/cond/cond_fmax-4.c b/gcc/testsuite/gcc.target/riscv/rvv/autovec/cond/cond_fmax-4.c
index 79e4771eaf3..d49b1722bbd 100644
--- a/gcc/testsuite/gcc.target/riscv/rvv/autovec/cond/cond_fmax-4.c
+++ b/gcc/testsuite/gcc.target/riscv/rvv/autovec/cond/cond_fmax-4.c
@@ -1,7 +1,8 @@
/* { dg-do compile } */
-/* { dg-additional-options "-march=rv32gcv_zvfh -mabi=ilp32d --param=riscv-autovec-preference=scalable -fno-vect-cost-model -ffast-math" } */
+/* { dg-additional-options "-march=rv32gcv_zvfh -mabi=ilp32d --param=riscv-autovec-preference=scalable -fno-vect-cost-model" } */
#include <stdint-gcc.h>
+#include <math.h>
#ifndef FN
#define FN(X) __builtin_fmax##X
@@ -24,10 +25,9 @@
T (FN, TYPE, PRED_TYPE, two, 2)
#define TEST_ALL(T) \
- TEST_TYPE (T, FN (f16), _Float16, int16_t) \
TEST_TYPE (T, FN (f32), float, int32_t) \
TEST_TYPE (T, FN (f64), double, int64_t)
TEST_ALL (DEF_LOOP)
-/* { dg-final { scan-assembler-times {vfmax\.vv\s+v[0-9]+,v[0-9]+,v[0-9]+,v0.t} 9 } } */
+/* { dg-final { scan-assembler-times {vfmax\.vv\s+v[0-9]+,v[0-9]+,v[0-9]+,v0.t} 6 } } */
diff --git a/gcc/testsuite/gcc.target/riscv/rvv/autovec/cond/cond_fmax_run-1.c b/gcc/testsuite/gcc.target/riscv/rvv/autovec/cond/cond_fmax_run-1.c
index e136f98002e..d8f9c000428 100644
--- a/gcc/testsuite/gcc.target/riscv/rvv/autovec/cond/cond_fmax_run-1.c
+++ b/gcc/testsuite/gcc.target/riscv/rvv/autovec/cond/cond_fmax_run-1.c
@@ -1,7 +1,8 @@
/* { dg-do run { target { riscv_v } } } */
-/* { dg-additional-options "--param=riscv-autovec-preference=scalable -fno-vect-cost-model -ffast-math" } */
+/* { dg-additional-options "--param=riscv-autovec-preference=scalable -fno-vect-cost-model" } */
#include "cond_fmax-1.c"
+#include <math.h>
#define N 99
diff --git a/gcc/testsuite/gcc.target/riscv/rvv/autovec/cond/cond_fmax_run-2.c b/gcc/testsuite/gcc.target/riscv/rvv/autovec/cond/cond_fmax_run-2.c
index 291cfca14ef..d6d39217a70 100644
--- a/gcc/testsuite/gcc.target/riscv/rvv/autovec/cond/cond_fmax_run-2.c
+++ b/gcc/testsuite/gcc.target/riscv/rvv/autovec/cond/cond_fmax_run-2.c
@@ -1,7 +1,8 @@
/* { dg-do run { target { riscv_v } } } */
-/* { dg-additional-options "--param=riscv-autovec-preference=scalable -fno-vect-cost-model -ffast-math" } */
+/* { dg-additional-options "--param=riscv-autovec-preference=scalable -fno-vect-cost-model" } */
#include "cond_fmax-2.c"
+#include <math.h>
#define N 99
diff --git a/gcc/testsuite/gcc.target/riscv/rvv/autovec/cond/cond_fmax_run-3.c b/gcc/testsuite/gcc.target/riscv/rvv/autovec/cond/cond_fmax_run-3.c
index 34f011dadee..a91b52f7e43 100644
--- a/gcc/testsuite/gcc.target/riscv/rvv/autovec/cond/cond_fmax_run-3.c
+++ b/gcc/testsuite/gcc.target/riscv/rvv/autovec/cond/cond_fmax_run-3.c
@@ -1,7 +1,8 @@
/* { dg-do run { target { riscv_v } } } */
-/* { dg-additional-options "--param=riscv-autovec-preference=scalable -fno-vect-cost-model -ffast-math" } */
+/* { dg-additional-options "--param=riscv-autovec-preference=scalable -fno-vect-cost-model" } */
#include "cond_fmax-3.c"
+#include <math.h>
#define N 99
diff --git a/gcc/testsuite/gcc.target/riscv/rvv/autovec/cond/cond_fmax_run-4.c b/gcc/testsuite/gcc.target/riscv/rvv/autovec/cond/cond_fmax_run-4.c
index 9986f8d24fe..414f4e4128c 100644
--- a/gcc/testsuite/gcc.target/riscv/rvv/autovec/cond/cond_fmax_run-4.c
+++ b/gcc/testsuite/gcc.target/riscv/rvv/autovec/cond/cond_fmax_run-4.c
@@ -1,7 +1,8 @@
/* { dg-do run { target { riscv_v } } } */
-/* { dg-additional-options "--param=riscv-autovec-preference=scalable -fno-vect-cost-model -ffast-math" } */
+/* { dg-additional-options "--param=riscv-autovec-preference=scalable -fno-vect-cost-model" } */
#include "cond_fmax-4.c"
+#include <math.h>
#define N 99
diff --git a/gcc/testsuite/gcc.target/riscv/rvv/autovec/cond/cond_fmax_zvfh-1.c b/gcc/testsuite/gcc.target/riscv/rvv/autovec/cond/cond_fmax_zvfh-1.c
new file mode 100644
index 00000000000..6c211328643
--- /dev/null
+++ b/gcc/testsuite/gcc.target/riscv/rvv/autovec/cond/cond_fmax_zvfh-1.c
@@ -0,0 +1,32 @@
+/* { dg-do compile } */
+/* { dg-additional-options "-march=rv32gcv_zvfh -mabi=ilp32d --param=riscv-autovec-preference=scalable -fno-vect-cost-model" } */
+
+#include <stdint-gcc.h>
+#include <math.h>
+
+#ifndef FN
+#define FN(X) __builtin_fmax##X
+#endif
+
+#define DEF_LOOP(FN, TYPE, PRED_TYPE, NAME, CONST) \
+ void __attribute__ ((noipa)) \
+ test_##TYPE##_##NAME (TYPE *__restrict x, \
+ TYPE *__restrict y, \
+ PRED_TYPE *__restrict pred, \
+ int n) \
+ { \
+ for (int i = 0; i < n; ++i) \
+ x[i] = pred[i] != 1 ? FN (y[i], CONST) : y[i]; \
+ }
+
+#define TEST_TYPE(T, FN, TYPE, PRED_TYPE) \
+ T (FN, TYPE, PRED_TYPE, zero, 0) \
+ T (FN, TYPE, PRED_TYPE, one, 1) \
+ T (FN, TYPE, PRED_TYPE, two, 2)
+
+#define TEST_ALL(T) \
+ TEST_TYPE (T, FN (f16), _Float16, int16_t)
+
+TEST_ALL (DEF_LOOP)
+
+/* { dg-final { scan-assembler-times {vfmax\.vv\s+v[0-9]+,v[0-9]+,v[0-9]+,v0.t} 3 } } */
diff --git a/gcc/testsuite/gcc.target/riscv/rvv/autovec/cond/cond_fmax_zvfh-2.c b/gcc/testsuite/gcc.target/riscv/rvv/autovec/cond/cond_fmax_zvfh-2.c
new file mode 100644
index 00000000000..0c211416d18
--- /dev/null
+++ b/gcc/testsuite/gcc.target/riscv/rvv/autovec/cond/cond_fmax_zvfh-2.c
@@ -0,0 +1,32 @@
+/* { dg-do compile } */
+/* { dg-additional-options "-march=rv32gcv_zvfh -mabi=ilp32d --param=riscv-autovec-preference=scalable -fno-vect-cost-model" } */
+
+#include <stdint-gcc.h>
+#include <math.h>
+
+#ifndef FN
+#define FN(X) __builtin_fmax##X
+#endif
+
+#define DEF_LOOP(FN, TYPE, NAME, CONST) \
+ void __attribute__ ((noipa)) \
+ test_##TYPE##_##NAME (TYPE *__restrict x, \
+ TYPE *__restrict y, \
+ TYPE *__restrict z, \
+ int n) \
+ { \
+ for (int i = 0; i < n; ++i) \
+ x[i] = y[i] < 8 ? FN (z[i], CONST) : y[i]; \
+ }
+
+#define TEST_TYPE(T, FN, TYPE) \
+ T (FN, TYPE, zero, 0) \
+ T (FN, TYPE, one, 1) \
+ T (FN, TYPE, two, 2)
+
+#define TEST_ALL(T) \
+ TEST_TYPE (T, FN (f16), _Float16)
+
+TEST_ALL (DEF_LOOP)
+
+/* { dg-final { scan-assembler-times {vfmax\.vv\s+v[0-9]+,v[0-9]+,v[0-9]+,v0.t} 3 } } */
diff --git a/gcc/testsuite/gcc.target/riscv/rvv/autovec/cond/cond_fmax_zvfh-3.c b/gcc/testsuite/gcc.target/riscv/rvv/autovec/cond/cond_fmax_zvfh-3.c
new file mode 100644
index 00000000000..44731c384af
--- /dev/null
+++ b/gcc/testsuite/gcc.target/riscv/rvv/autovec/cond/cond_fmax_zvfh-3.c
@@ -0,0 +1,32 @@
+/* { dg-do compile } */
+/* { dg-additional-options "-march=rv32gcv_zvfh -mabi=ilp32d --param=riscv-autovec-preference=scalable -fno-vect-cost-model" } */
+
+#include <stdint-gcc.h>
+#include <math.h>
+
+#ifndef FN
+#define FN(X) __builtin_fmax##X
+#endif
+
+#define DEF_LOOP(FN, TYPE, PRED_TYPE, NAME, CONST) \
+ void __attribute__ ((noipa)) \
+ test_##TYPE##_##NAME (TYPE *__restrict x, \
+ TYPE *__restrict y, \
+ PRED_TYPE *__restrict pred, \
+ int n) \
+ { \
+ for (int i = 0; i < n; ++i) \
+ x[i] = pred[i] != 1 ? FN (y[i], CONST) : 4; \
+ }
+
+#define TEST_TYPE(T, FN, TYPE, PRED_TYPE) \
+ T (FN, TYPE, PRED_TYPE, zero, 0) \
+ T (FN, TYPE, PRED_TYPE, one, 1) \
+ T (FN, TYPE, PRED_TYPE, two, 2)
+
+#define TEST_ALL(T) \
+ TEST_TYPE (T, FN (f16), _Float16, int16_t)
+
+TEST_ALL (DEF_LOOP)
+
+/* { dg-final { scan-assembler-times {vfmax\.vv\s+v[0-9]+,v[0-9]+,v[0-9]+,v0.t} 3 } } */
diff --git a/gcc/testsuite/gcc.target/riscv/rvv/autovec/cond/cond_fmax_zvfh-4.c b/gcc/testsuite/gcc.target/riscv/rvv/autovec/cond/cond_fmax_zvfh-4.c
new file mode 100644
index 00000000000..72a63a79893
--- /dev/null
+++ b/gcc/testsuite/gcc.target/riscv/rvv/autovec/cond/cond_fmax_zvfh-4.c
@@ -0,0 +1,32 @@
+/* { dg-do compile } */
+/* { dg-additional-options "-march=rv32gcv_zvfh -mabi=ilp32d --param=riscv-autovec-preference=scalable -fno-vect-cost-model" } */
+
+#include <stdint-gcc.h>
+#include <math.h>
+
+#ifndef FN
+#define FN(X) __builtin_fmax##X
+#endif
+
+#define DEF_LOOP(FN, TYPE, PRED_TYPE, NAME, CONST) \
+ void __attribute__ ((noipa)) \
+ test_##TYPE##_##NAME (TYPE *__restrict x, \
+ TYPE *__restrict y, \
+ PRED_TYPE *__restrict pred, \
+ int n) \
+ { \
+ for (int i = 0; i < n; ++i) \
+ x[i] = pred[i] != 1 ? FN (y[i], CONST) : 0; \
+ }
+
+#define TEST_TYPE(T, FN, TYPE, PRED_TYPE) \
+ T (FN, TYPE, PRED_TYPE, zero, 0) \
+ T (FN, TYPE, PRED_TYPE, one, 1) \
+ T (FN, TYPE, PRED_TYPE, two, 2)
+
+#define TEST_ALL(T) \
+ TEST_TYPE (T, FN (f16), _Float16, int16_t)
+
+TEST_ALL (DEF_LOOP)
+
+/* { dg-final { scan-assembler-times {vfmax\.vv\s+v[0-9]+,v[0-9]+,v[0-9]+,v0.t} 3 } } */
diff --git a/gcc/testsuite/gcc.target/riscv/rvv/autovec/cond/cond_fmax_zvfh_run-1.c b/gcc/testsuite/gcc.target/riscv/rvv/autovec/cond/cond_fmax_zvfh_run-1.c
new file mode 100644
index 00000000000..a2afe970bc1
--- /dev/null
+++ b/gcc/testsuite/gcc.target/riscv/rvv/autovec/cond/cond_fmax_zvfh_run-1.c
@@ -0,0 +1,33 @@
+/* { dg-do run { target { riscv_zvfh } } } */
+/* { dg-additional-options "--param=riscv-autovec-preference=scalable -fno-vect-cost-model" } */
+
+#include "cond_fmax_zvfh-1.c"
+#include <math.h>
+
+#define N 99
+
+#define TEST_LOOP(FN, TYPE, PRED_TYPE, NAME, CONST) \
+ { \
+ TYPE x[N], y[N]; \
+ PRED_TYPE pred[N]; \
+ for (int i = 0; i < N; ++i) \
+ { \
+ y[i] = i * i; \
+ pred[i] = i % 3; \
+ } \
+ test_##TYPE##_##NAME (x, y, pred, N); \
+ for (int i = 0; i < N; ++i) \
+ { \
+ TYPE expected = i % 3 != 1 ? FN (y[i], CONST) : y[i]; \
+ if (x[i] != expected) \
+ __builtin_abort (); \
+ asm volatile ("" ::: "memory"); \
+ } \
+ }
+
+int
+main (void)
+{
+ TEST_ALL (TEST_LOOP)
+ return 0;
+}
diff --git a/gcc/testsuite/gcc.target/riscv/rvv/autovec/cond/cond_fmax_zvfh_run-2.c b/gcc/testsuite/gcc.target/riscv/rvv/autovec/cond/cond_fmax_zvfh_run-2.c
new file mode 100644
index 00000000000..13e5a44ca66
--- /dev/null
+++ b/gcc/testsuite/gcc.target/riscv/rvv/autovec/cond/cond_fmax_zvfh_run-2.c
@@ -0,0 +1,32 @@
+/* { dg-do run { target { riscv_zvfh } } } */
+/* { dg-additional-options "--param=riscv-autovec-preference=scalable -fno-vect-cost-model" } */
+
+#include "cond_fmax_zvfh-2.c"
+#include <math.h>
+
+#define N 99
+
+#define TEST_LOOP(FN, TYPE, NAME, CONST) \
+ { \
+ TYPE x[N], y[N], z[N]; \
+ for (int i = 0; i < N; ++i) \
+ { \
+ y[i] = i % 13; \
+ z[i] = i * i; \
+ } \
+ test_##TYPE##_##NAME (x, y, z, N); \
+ for (int i = 0; i < N; ++i) \
+ { \
+ TYPE expected = y[i] < 8 ? FN (z[i], CONST) : y[i]; \
+ if (x[i] != expected) \
+ __builtin_abort (); \
+ asm volatile ("" ::: "memory"); \
+ } \
+ }
+
+int
+main (void)
+{
+ TEST_ALL (TEST_LOOP)
+ return 0;
+}
diff --git a/gcc/testsuite/gcc.target/riscv/rvv/autovec/cond/cond_fmax_zvfh_run-3.c b/gcc/testsuite/gcc.target/riscv/rvv/autovec/cond/cond_fmax_zvfh_run-3.c
new file mode 100644
index 00000000000..90f98e7a35c
--- /dev/null
+++ b/gcc/testsuite/gcc.target/riscv/rvv/autovec/cond/cond_fmax_zvfh_run-3.c
@@ -0,0 +1,33 @@
+/* { dg-do run { target { riscv_zvfh } } } */
+/* { dg-additional-options "--param=riscv-autovec-preference=scalable -fno-vect-cost-model" } */
+
+#include "cond_fmax_zvfh-3.c"
+#include <math.h>
+
+#define N 99
+
+#define TEST_LOOP(FN, TYPE, PRED_TYPE, NAME, CONST) \
+ { \
+ TYPE x[N], y[N]; \
+ PRED_TYPE pred[N]; \
+ for (int i = 0; i < N; ++i) \
+ { \
+ y[i] = i * i; \
+ pred[i] = i % 3; \
+ } \
+ test_##TYPE##_##NAME (x, y, pred, N); \
+ for (int i = 0; i < N; ++i) \
+ { \
+ TYPE expected = i % 3 != 1 ? FN (y[i], CONST) : 4; \
+ if (x[i] != expected) \
+ __builtin_abort (); \
+ asm volatile ("" ::: "memory"); \
+ } \
+ }
+
+int
+main (void)
+{
+ TEST_ALL (TEST_LOOP)
+ return 0;
+}
diff --git a/gcc/testsuite/gcc.target/riscv/rvv/autovec/cond/cond_fmax_zvfh_run-4.c b/gcc/testsuite/gcc.target/riscv/rvv/autovec/cond/cond_fmax_zvfh_run-4.c
new file mode 100644
index 00000000000..30914e13bcd
--- /dev/null
+++ b/gcc/testsuite/gcc.target/riscv/rvv/autovec/cond/cond_fmax_zvfh_run-4.c
@@ -0,0 +1,33 @@
+/* { dg-do run { target { riscv_zvfh } } } */
+/* { dg-additional-options "--param=riscv-autovec-preference=scalable -fno-vect-cost-model" } */
+
+#include "cond_fmax_zvfh-4.c"
+#include <math.h>
+
+#define N 99
+
+#define TEST_LOOP(FN, TYPE, PRED_TYPE, NAME, CONST) \
+ { \
+ TYPE x[N], y[N]; \
+ PRED_TYPE pred[N]; \
+ for (int i = 0; i < N; ++i) \
+ { \
+ y[i] = i * i; \
+ pred[i] = i % 3; \
+ } \
+ test_##TYPE##_##NAME (x, y, pred, N); \
+ for (int i = 0; i < N; ++i) \
+ { \
+ TYPE expected = i % 3 != 1 ? FN (y[i], CONST) : 0; \
+ if (x[i] != expected) \
+ __builtin_abort (); \
+ asm volatile ("" ::: "memory"); \
+ } \
+ }
+
+int
+main (void)
+{
+ TEST_ALL (TEST_LOOP)
+ return 0;
+}
diff --git a/gcc/testsuite/gcc.target/riscv/rvv/autovec/cond/cond_fmin-1.c b/gcc/testsuite/gcc.target/riscv/rvv/autovec/cond/cond_fmin-1.c
index f1596409312..b6a265e642f 100644
--- a/gcc/testsuite/gcc.target/riscv/rvv/autovec/cond/cond_fmin-1.c
+++ b/gcc/testsuite/gcc.target/riscv/rvv/autovec/cond/cond_fmin-1.c
@@ -1,10 +1,11 @@
/* { dg-do compile } */
-/* { dg-additional-options "-march=rv32gcv_zvfh -mabi=ilp32d --param=riscv-autovec-preference=scalable -fno-vect-cost-model -ffast-math" } */
+/* { dg-additional-options "-march=rv32gcv_zvfh -mabi=ilp32d --param=riscv-autovec-preference=scalable -fno-vect-cost-model" } */
#include <stdint-gcc.h>
+#include <math.h>
#define FN(X) __builtin_fmin##X
#include "cond_fmax-1.c"
-/* { dg-final { scan-assembler-times {vfmin\.vv\s+v[0-9]+,v[0-9]+,v[0-9]+,v0.t} 9 } } */
+/* { dg-final { scan-assembler-times {vfmin\.vv\s+v[0-9]+,v[0-9]+,v[0-9]+,v0.t} 6 } } */
diff --git a/gcc/testsuite/gcc.target/riscv/rvv/autovec/cond/cond_fmin-2.c b/gcc/testsuite/gcc.target/riscv/rvv/autovec/cond/cond_fmin-2.c
index 7c8c79ee251..fb32c2fe316 100644
--- a/gcc/testsuite/gcc.target/riscv/rvv/autovec/cond/cond_fmin-2.c
+++ b/gcc/testsuite/gcc.target/riscv/rvv/autovec/cond/cond_fmin-2.c
@@ -1,7 +1,8 @@
/* { dg-do compile } */
-/* { dg-additional-options "-march=rv32gcv_zvfh -mabi=ilp32d --param=riscv-autovec-preference=scalable -fno-vect-cost-model -ffast-math" } */
+/* { dg-additional-options "-march=rv32gcv_zvfh -mabi=ilp32d --param=riscv-autovec-preference=scalable -fno-vect-cost-model" } */
#include <stdint-gcc.h>
+#include <math.h>
#define FN(X) __builtin_fmin##X
#include "cond_fmax-2.c"
diff --git a/gcc/testsuite/gcc.target/riscv/rvv/autovec/cond/cond_fmin-3.c b/gcc/testsuite/gcc.target/riscv/rvv/autovec/cond/cond_fmin-3.c
index aee0e3572b0..29b9dbc4cdc 100644
--- a/gcc/testsuite/gcc.target/riscv/rvv/autovec/cond/cond_fmin-3.c
+++ b/gcc/testsuite/gcc.target/riscv/rvv/autovec/cond/cond_fmin-3.c
@@ -1,9 +1,10 @@
/* { dg-do compile } */
-/* { dg-additional-options "-march=rv32gcv_zvfh -mabi=ilp32d --param=riscv-autovec-preference=scalable -fno-vect-cost-model -ffast-math" } */
+/* { dg-additional-options "-march=rv32gcv_zvfh -mabi=ilp32d --param=riscv-autovec-preference=scalable -fno-vect-cost-model" } */
#include <stdint-gcc.h>
+#include <math.h>
#define FN(X) __builtin_fmin##X
#include "cond_fmax-3.c"
-/* { dg-final { scan-assembler-times {vfmin\.vv\s+v[0-9]+,v[0-9]+,v[0-9]+,v0.t} 9 } } */
+/* { dg-final { scan-assembler-times {vfmin\.vv\s+v[0-9]+,v[0-9]+,v[0-9]+,v0.t} 6 } } */
diff --git a/gcc/testsuite/gcc.target/riscv/rvv/autovec/cond/cond_fmin-4.c b/gcc/testsuite/gcc.target/riscv/rvv/autovec/cond/cond_fmin-4.c
index 223c8a6938b..db098c7e5fd 100644
--- a/gcc/testsuite/gcc.target/riscv/rvv/autovec/cond/cond_fmin-4.c
+++ b/gcc/testsuite/gcc.target/riscv/rvv/autovec/cond/cond_fmin-4.c
@@ -1,9 +1,10 @@
/* { dg-do compile } */
-/* { dg-additional-options "-march=rv32gcv_zvfh -mabi=ilp32d --param=riscv-autovec-preference=scalable -fno-vect-cost-model -ffast-math" } */
+/* { dg-additional-options "-march=rv32gcv_zvfh -mabi=ilp32d --param=riscv-autovec-preference=scalable -fno-vect-cost-model" } */
#include <stdint-gcc.h>
+#include <math.h>
#define FN(X) __builtin_fmin##X
#include "cond_fmax-4.c"
-/* { dg-final { scan-assembler-times {vfmin\.vv\s+v[0-9]+,v[0-9]+,v[0-9]+,v0.t} 9 } } */
+/* { dg-final { scan-assembler-times {vfmin\.vv\s+v[0-9]+,v[0-9]+,v[0-9]+,v0.t} 6 } } */
diff --git a/gcc/testsuite/gcc.target/riscv/rvv/autovec/cond/cond_fmin_run-1.c b/gcc/testsuite/gcc.target/riscv/rvv/autovec/cond/cond_fmin_run-1.c
index 293e1d93307..6700738fe8c 100644
--- a/gcc/testsuite/gcc.target/riscv/rvv/autovec/cond/cond_fmin_run-1.c
+++ b/gcc/testsuite/gcc.target/riscv/rvv/autovec/cond/cond_fmin_run-1.c
@@ -1,5 +1,5 @@
/* { dg-do run { target { riscv_v } } } */
-/* { dg-additional-options "--param=riscv-autovec-preference=scalable -fno-vect-cost-model -ffast-math" } */
+/* { dg-additional-options "--param=riscv-autovec-preference=scalable -fno-vect-cost-model" } */
#define FN(X) __builtin_fmin##X
#include "cond_fmax_run-1.c"
diff --git a/gcc/testsuite/gcc.target/riscv/rvv/autovec/cond/cond_fmin_run-2.c b/gcc/testsuite/gcc.target/riscv/rvv/autovec/cond/cond_fmin_run-2.c
index 3310bb7989f..015d283c6ff 100644
--- a/gcc/testsuite/gcc.target/riscv/rvv/autovec/cond/cond_fmin_run-2.c
+++ b/gcc/testsuite/gcc.target/riscv/rvv/autovec/cond/cond_fmin_run-2.c
@@ -1,5 +1,5 @@
/* { dg-do run { target { riscv_v } } } */
-/* { dg-additional-options "--param=riscv-autovec-preference=scalable -fno-vect-cost-model -ffast-math" } */
+/* { dg-additional-options "--param=riscv-autovec-preference=scalable -fno-vect-cost-model" } */
#define FN(X) __builtin_fmin##X
#include "cond_fmax_run-2.c"
diff --git a/gcc/testsuite/gcc.target/riscv/rvv/autovec/cond/cond_fmin_run-3.c b/gcc/testsuite/gcc.target/riscv/rvv/autovec/cond/cond_fmin_run-3.c
index 6bed341ac87..61d1685ed28 100644
--- a/gcc/testsuite/gcc.target/riscv/rvv/autovec/cond/cond_fmin_run-3.c
+++ b/gcc/testsuite/gcc.target/riscv/rvv/autovec/cond/cond_fmin_run-3.c
@@ -1,5 +1,5 @@
/* { dg-do run { target { riscv_v } } } */
-/* { dg-additional-options "--param=riscv-autovec-preference=scalable -fno-vect-cost-model -ffast-math" } */
+/* { dg-additional-options "--param=riscv-autovec-preference=scalable -fno-vect-cost-model" } */
#define FN(X) __builtin_fmin##X
#include "cond_fmax_run-3.c"
diff --git a/gcc/testsuite/gcc.target/riscv/rvv/autovec/cond/cond_fmin_run-4.c b/gcc/testsuite/gcc.target/riscv/rvv/autovec/cond/cond_fmin_run-4.c
index 4af0322e73f..36fb2e05845 100644
--- a/gcc/testsuite/gcc.target/riscv/rvv/autovec/cond/cond_fmin_run-4.c
+++ b/gcc/testsuite/gcc.target/riscv/rvv/autovec/cond/cond_fmin_run-4.c
@@ -1,5 +1,5 @@
/* { dg-do run { target { riscv_v } } } */
-/* { dg-additional-options "--param=riscv-autovec-preference=scalable -fno-vect-cost-model -ffast-math" } */
+/* { dg-additional-options "--param=riscv-autovec-preference=scalable -fno-vect-cost-model" } */
#define FN(X) __builtin_fmin##X
#include "cond_fmax_run-4.c"
diff --git a/gcc/testsuite/gcc.target/riscv/rvv/autovec/cond/cond_fmin_zvfh-1.c b/gcc/testsuite/gcc.target/riscv/rvv/autovec/cond/cond_fmin_zvfh-1.c
new file mode 100644
index 00000000000..f763f6369f5
--- /dev/null
+++ b/gcc/testsuite/gcc.target/riscv/rvv/autovec/cond/cond_fmin_zvfh-1.c
@@ -0,0 +1,11 @@
+/* { dg-do compile } */
+/* { dg-additional-options "-march=rv32gcv_zvfh -mabi=ilp32d --param=riscv-autovec-preference=scalable -fno-vect-cost-model" } */
+
+#include <stdint-gcc.h>
+#include <math.h>
+
+#define FN(X) __builtin_fmin##X
+#include "cond_fmax_zvfh-1.c"
+
+/* { dg-final { scan-assembler-times {vfmin\.vv\s+v[0-9]+,v[0-9]+,v[0-9]+,v0.t} 3 } } */
+
diff --git a/gcc/testsuite/gcc.target/riscv/rvv/autovec/cond/cond_fmin_zvfh-2.c b/gcc/testsuite/gcc.target/riscv/rvv/autovec/cond/cond_fmin_zvfh-2.c
new file mode 100644
index 00000000000..afe6d4ea54b
--- /dev/null
+++ b/gcc/testsuite/gcc.target/riscv/rvv/autovec/cond/cond_fmin_zvfh-2.c
@@ -0,0 +1,10 @@
+/* { dg-do compile } */
+/* { dg-additional-options "-march=rv32gcv_zvfh -mabi=ilp32d --param=riscv-autovec-preference=scalable -fno-vect-cost-model" } */
+
+#include <stdint-gcc.h>
+#include <math.h>
+
+#define FN(X) __builtin_fmin##X
+#include "cond_fmax_zvfh-2.c"
+
+/* { dg-final { scan-assembler-times {vfmin\.vv\s+v[0-9]+,v[0-9]+,v[0-9]+,v0.t} 3 } } */
diff --git a/gcc/testsuite/gcc.target/riscv/rvv/autovec/cond/cond_fmin_zvfh-3.c b/gcc/testsuite/gcc.target/riscv/rvv/autovec/cond/cond_fmin_zvfh-3.c
new file mode 100644
index 00000000000..f771a835ec9
--- /dev/null
+++ b/gcc/testsuite/gcc.target/riscv/rvv/autovec/cond/cond_fmin_zvfh-3.c
@@ -0,0 +1,10 @@
+/* { dg-do compile } */
+/* { dg-additional-options "-march=rv32gcv_zvfh -mabi=ilp32d --param=riscv-autovec-preference=scalable -fno-vect-cost-model" } */
+
+#include <stdint-gcc.h>
+#include <math.h>
+
+#define FN(X) __builtin_fmin##X
+#include "cond_fmax_zvfh-3.c"
+
+/* { dg-final { scan-assembler-times {vfmin\.vv\s+v[0-9]+,v[0-9]+,v[0-9]+,v0.t} 3 } } */
diff --git a/gcc/testsuite/gcc.target/riscv/rvv/autovec/cond/cond_fmin_zvfh-4.c b/gcc/testsuite/gcc.target/riscv/rvv/autovec/cond/cond_fmin_zvfh-4.c
new file mode 100644
index 00000000000..65598fefec1
--- /dev/null
+++ b/gcc/testsuite/gcc.target/riscv/rvv/autovec/cond/cond_fmin_zvfh-4.c
@@ -0,0 +1,10 @@
+/* { dg-do compile } */
+/* { dg-additional-options "-march=rv32gcv_zvfh -mabi=ilp32d --param=riscv-autovec-preference=scalable -fno-vect-cost-model" } */
+
+#include <stdint-gcc.h>
+#include <math.h>
+
+#define FN(X) __builtin_fmin##X
+#include "cond_fmax_zvfh-4.c"
+
+/* { dg-final { scan-assembler-times {vfmin\.vv\s+v[0-9]+,v[0-9]+,v[0-9]+,v0.t} 3 } } */
diff --git a/gcc/testsuite/gcc.target/riscv/rvv/autovec/cond/cond_fmin_zvfh_run-1.c b/gcc/testsuite/gcc.target/riscv/rvv/autovec/cond/cond_fmin_zvfh_run-1.c
new file mode 100644
index 00000000000..536b8f2762c
--- /dev/null
+++ b/gcc/testsuite/gcc.target/riscv/rvv/autovec/cond/cond_fmin_zvfh_run-1.c
@@ -0,0 +1,5 @@
+/* { dg-do run { target { riscv_zvfh } } } */
+/* { dg-additional-options "--param=riscv-autovec-preference=scalable -fno-vect-cost-model" } */
+
+#define FN(X) __builtin_fmin##X
+#include "cond_fmax_zvfh_run-1.c"
diff --git a/gcc/testsuite/gcc.target/riscv/rvv/autovec/cond/cond_fmin_zvfh_run-2.c b/gcc/testsuite/gcc.target/riscv/rvv/autovec/cond/cond_fmin_zvfh_run-2.c
new file mode 100644
index 00000000000..e6c5f625535
--- /dev/null
+++ b/gcc/testsuite/gcc.target/riscv/rvv/autovec/cond/cond_fmin_zvfh_run-2.c
@@ -0,0 +1,5 @@
+/* { dg-do run { target { riscv_zvfh } } } */
+/* { dg-additional-options "--param=riscv-autovec-preference=scalable -fno-vect-cost-model" } */
+
+#define FN(X) __builtin_fmin##X
+#include "cond_fmax_zvfh_run-2.c"
diff --git a/gcc/testsuite/gcc.target/riscv/rvv/autovec/cond/cond_fmin_zvfh_run-3.c b/gcc/testsuite/gcc.target/riscv/rvv/autovec/cond/cond_fmin_zvfh_run-3.c
new file mode 100644
index 00000000000..858588c822e
--- /dev/null
+++ b/gcc/testsuite/gcc.target/riscv/rvv/autovec/cond/cond_fmin_zvfh_run-3.c
@@ -0,0 +1,5 @@
+/* { dg-do run { target { riscv_zvfh } } } */
+/* { dg-additional-options "--param=riscv-autovec-preference=scalable -fno-vect-cost-model" } */
+
+#define FN(X) __builtin_fmin##X
+#include "cond_fmax_zvfh_run-3.c"
diff --git a/gcc/testsuite/gcc.target/riscv/rvv/autovec/cond/cond_fmin_zvfh_run-4.c b/gcc/testsuite/gcc.target/riscv/rvv/autovec/cond/cond_fmin_zvfh_run-4.c
new file mode 100644
index 00000000000..ece623e4cbb
--- /dev/null
+++ b/gcc/testsuite/gcc.target/riscv/rvv/autovec/cond/cond_fmin_zvfh_run-4.c
@@ -0,0 +1,5 @@
+/* { dg-do run { target { riscv_zvfh } } } */
+/* { dg-additional-options "--param=riscv-autovec-preference=scalable -fno-vect-cost-model" } */
+
+#define FN(X) __builtin_fmin##X
+#include "cond_fmax_zvfh_run-4.c"
diff --git a/gcc/testsuite/gcc.target/riscv/rvv/autovec/reduc/reduc-10.c b/gcc/testsuite/gcc.target/riscv/rvv/autovec/reduc/reduc-10.c
new file mode 100644
index 00000000000..a749756fde8
--- /dev/null
+++ b/gcc/testsuite/gcc.target/riscv/rvv/autovec/reduc/reduc-10.c
@@ -0,0 +1,26 @@
+/* { dg-do compile } */
+/* { dg-additional-options "-march=rv32gcv_zvfh -mabi=ilp32d --param=riscv-autovec-preference=scalable --param vect-epilogues-nomask=0" } */
+
+#include <stdint-gcc.h>
+
+#define DEF_REDUC_FMAXMIN(TYPE, NAME, MAXMIN_OP) \
+ TYPE __attribute__ ((noinline, noclone)) \
+ reduc_##NAME##_##TYPE (TYPE *a, int n) \
+ { \
+ TYPE r = -0.0; \
+ for (int i = 0; i < n; ++i) \
+ r = MAXMIN_OP (r, a[i]); \
+ return r; \
+ }
+
+#define TEST_FMAXMIN(T) \
+ T (float, max, __builtin_fmaxf) \
+ T (double, max, __builtin_fmax) \
+ T (float, min, __builtin_fminf) \
+ T (double, min, __builtin_fmin)
+
+
+TEST_FMAXMIN (DEF_REDUC_FMAXMIN)
+
+/* { dg-final { scan-assembler-times {vfredmax\.vs\s+v[0-9]+,\s*v[0-9]+,\s*v[0-9]+} 2 } } */
+/* { dg-final { scan-assembler-times {vfredmin\.vs\s+v[0-9]+,\s*v[0-9]+,\s*v[0-9]+} 2 } } */
diff --git a/gcc/testsuite/gcc.target/riscv/rvv/autovec/reduc/reduc_run-10.c b/gcc/testsuite/gcc.target/riscv/rvv/autovec/reduc/reduc_run-10.c
new file mode 100644
index 00000000000..a7c6d4fa59e
--- /dev/null
+++ b/gcc/testsuite/gcc.target/riscv/rvv/autovec/reduc/reduc_run-10.c
@@ -0,0 +1,41 @@
+/* { dg-do run { target { riscv_v } } } */
+/* { dg-additional-options "--param=riscv-autovec-preference=scalable" } */
+
+#include <math.h>
+
+#include "reduc-10.c"
+
+#define NUM_ELEMS(TYPE) (73 + sizeof (TYPE))
+
+#define INIT_VECTOR(TYPE) \
+ TYPE a[NUM_ELEMS (TYPE) + 1]; \
+ for (int i = 0; i < NUM_ELEMS (TYPE) + 1; i++) \
+ { \
+ a[i] = ((i * 2) * (i & 1 ? 1 : -1) | 3); \
+ asm volatile ("" ::: "memory"); \
+ } \
+ a[0] = -0.0; \
+ a[1] = nan ("0.0"); \
+ a[2] = nan ("1.0"); \
+ a[3] = 0.0; \
+ a[4] = -INFINITY; \
+ a[5] = INFINITY; \
+
+#define TEST_REDUC_FMAXMIN(TYPE, NAME, MAXMIN_OP) \
+ { \
+ INIT_VECTOR (TYPE); \
+ TYPE r1 = reduc_##NAME##_##TYPE (a, NUM_ELEMS (TYPE)); \
+ volatile TYPE r2 = -0.0; \
+ for (int i = 0; i < NUM_ELEMS (TYPE); ++i) \
+ r2 = MAXMIN_OP (r2, a[i]); \
+ if (r1 != r2) \
+ __builtin_abort (); \
+ }
+
+__attribute__ ((optimize ("1")))
+int main ()
+{
+ TEST_FMAXMIN (TEST_REDUC_FMAXMIN)
+
+ return 0;
+}
diff --git a/gcc/testsuite/gcc.target/riscv/rvv/autovec/reduc/reduc_run_zvfh-10.c b/gcc/testsuite/gcc.target/riscv/rvv/autovec/reduc/reduc_run_zvfh-10.c
new file mode 100644
index 00000000000..37288ba642a
--- /dev/null
+++ b/gcc/testsuite/gcc.target/riscv/rvv/autovec/reduc/reduc_run_zvfh-10.c
@@ -0,0 +1,41 @@
+/* { dg-do run { target { riscv_zvfh } } } */
+/* { dg-additional-options "--param=riscv-autovec-preference=scalable" } */
+
+#include <math.h>
+
+#include "reduc_zvfh-10.c"
+
+#define NUM_ELEMS(TYPE) (73 + sizeof (TYPE))
+
+#define INIT_VECTOR(TYPE) \
+ TYPE a[NUM_ELEMS (TYPE) + 1]; \
+ for (int i = 0; i < NUM_ELEMS (TYPE) + 1; i++) \
+ { \
+ a[i] = ((i * 2) * (i & 1 ? 1 : -1) | 3); \
+ asm volatile ("" ::: "memory"); \
+ } \
+ a[0] = -0.0; \
+ a[1] = nan ("0.0"); \
+ a[2] = nan ("1.0"); \
+ a[3] = 0.0; \
+ a[4] = -INFINITY; \
+ a[5] = INFINITY; \
+
+#define TEST_REDUC_FMAXMIN(TYPE, NAME, MAXMIN_OP) \
+ { \
+ INIT_VECTOR (TYPE); \
+ TYPE r1 = reduc_##NAME##_##TYPE (a, NUM_ELEMS (TYPE)); \
+ volatile TYPE r2 = -0.0; \
+ for (int i = 0; i < NUM_ELEMS (TYPE); ++i) \
+ r2 = MAXMIN_OP (r2, a[i]); \
+ if (r1 != r2) \
+ __builtin_abort (); \
+ }
+
+__attribute__ ((optimize ("1")))
+int main ()
+{
+ TEST_FMAXMIN (TEST_REDUC_FMAXMIN)
+
+ return 0;
+}
diff --git a/gcc/testsuite/gcc.target/riscv/rvv/autovec/reduc/reduc_zvfh-10.c b/gcc/testsuite/gcc.target/riscv/rvv/autovec/reduc/reduc_zvfh-10.c
new file mode 100644
index 00000000000..bb32cae83a4
--- /dev/null
+++ b/gcc/testsuite/gcc.target/riscv/rvv/autovec/reduc/reduc_zvfh-10.c
@@ -0,0 +1,24 @@
+/* { dg-do compile } */
+/* { dg-additional-options "-march=rv32gcv_zvfh -mabi=ilp32d --param=riscv-autovec-preference=scalable --param vect-epilogues-nomask=0" } */
+
+#include <stdint-gcc.h>
+
+#define DEF_REDUC_FMAXMIN(TYPE, NAME, MAXMIN_OP) \
+ TYPE __attribute__ ((noinline, noclone)) \
+ reduc_##NAME##_##TYPE (TYPE *a, int n) \
+ { \
+ TYPE r = -0.0; \
+ for (int i = 0; i < n; ++i) \
+ r = MAXMIN_OP (r, a[i]); \
+ return r; \
+ }
+
+#define TEST_FMAXMIN(T) \
+ T (_Float16, max, __builtin_fmaxf16) \
+ T (_Float16, min, __builtin_fminf16) \
+
+
+TEST_FMAXMIN (DEF_REDUC_FMAXMIN)
+
+/* { dg-final { scan-assembler-times {vfredmax\.vs\s+v[0-9]+,\s*v[0-9]+,\s*v[0-9]+} 1 } } */
+/* { dg-final { scan-assembler-times {vfredmin\.vs\s+v[0-9]+,\s*v[0-9]+,\s*v[0-9]+} 1 } } */
--
2.41.0
^ permalink raw reply [flat|nested] 5+ messages in thread
* Re: [PATCH] RISC-V: Add vector fmin/fmax expanders.
2023-10-30 16:08 [PATCH] RISC-V: Add vector fmin/fmax expanders Robin Dapp
@ 2023-10-30 18:31 ` Joseph Myers
2023-10-30 19:26 ` Robin Dapp
0 siblings, 1 reply; 5+ messages in thread
From: Joseph Myers @ 2023-10-30 18:31 UTC (permalink / raw)
To: Robin Dapp; +Cc: gcc-patches, palmer, Kito Cheng, jeffreyalaw, juzhe.zhong
On Mon, 30 Oct 2023, Robin Dapp wrote:
> Hi,
>
> this patch adds expanders for fmin and fmax and the associated
> cond and reduc ones. As per RISC-V V spec 1.0 vfmin/vfmax are
> IEEE 754-2008 compliant so that should be ok.
Aren't they actually the IEEE 754-2019 operations (with different
signaling NaN semantics; C functions such as fmaximum in C23), not the
IEEE 754-2008 operations (C functions such as fmax)? V spec 1.0 says "The
vector floating-point vfmin and vfmax instructions have the same behavior
as the corresponding scalar floating-point instructions in version 2.2 of
the RISC-V F/D/Q extension.". And version 2.2 of F/D/Q (which is *not*
version 2.2 of the instruction set, it's later than that) changed the
scalar instructions to be the IEEE 754-2019 operations (thus, the
!HONOR_SNANS checks in the back end).
--
Joseph S. Myers
joseph@codesourcery.com
^ permalink raw reply [flat|nested] 5+ messages in thread
* Re: [PATCH] RISC-V: Add vector fmin/fmax expanders.
2023-10-30 18:31 ` Joseph Myers
@ 2023-10-30 19:26 ` Robin Dapp
2023-10-31 1:19 ` juzhe.zhong
0 siblings, 1 reply; 5+ messages in thread
From: Robin Dapp @ 2023-10-30 19:26 UTC (permalink / raw)
To: Joseph Myers
Cc: rdapp.gcc, gcc-patches, palmer, Kito Cheng, jeffreyalaw, juzhe.zhong
> Aren't they actually the IEEE 754-2019 operations (with different
> signaling NaN semantics; C functions such as fmaximum in C23), not the
> IEEE 754-2008 operations (C functions such as fmax)? V spec 1.0 says "The
> vector floating-point vfmin and vfmax instructions have the same behavior
> as the corresponding scalar floating-point instructions in version 2.2 of
> the RISC-V F/D/Q extension.". And version 2.2 of F/D/Q (which is *not*
> version 2.2 of the instruction set, it's later than that) changed the
Oh, thanks for catching this - I indeed incorrectly assumed this refers to
version 2.2 of the RISC-V spec (which contains F/D, .. of version 2.0).
Too bad, it appeared too convenient. Then I need to add the same
!HONOR_SNANS to all the expanders as well as the tests.
Regards
Robin
^ permalink raw reply [flat|nested] 5+ messages in thread
* Re: Re: [PATCH] RISC-V: Add vector fmin/fmax expanders.
2023-10-30 19:26 ` Robin Dapp
@ 2023-10-31 1:19 ` juzhe.zhong
2023-10-31 11:51 ` Robin Dapp
0 siblings, 1 reply; 5+ messages in thread
From: juzhe.zhong @ 2023-10-31 1:19 UTC (permalink / raw)
To: Robin Dapp, joseph
Cc: Robin Dapp, gcc-patches, palmer, kito.cheng, jeffreyalaw
[-- Attachment #1: Type: text/plain, Size: 1103 bytes --]
LGTM as long as you add HONOR_SNANS
juzhe.zhong@rivai.ai
From: Robin Dapp
Date: 2023-10-31 03:26
To: Joseph Myers
CC: rdapp.gcc; gcc-patches; palmer; Kito Cheng; jeffreyalaw; juzhe.zhong@rivai.ai
Subject: Re: [PATCH] RISC-V: Add vector fmin/fmax expanders.
> Aren't they actually the IEEE 754-2019 operations (with different
> signaling NaN semantics; C functions such as fmaximum in C23), not the
> IEEE 754-2008 operations (C functions such as fmax)? V spec 1.0 says "The
> vector floating-point vfmin and vfmax instructions have the same behavior
> as the corresponding scalar floating-point instructions in version 2.2 of
> the RISC-V F/D/Q extension.". And version 2.2 of F/D/Q (which is *not*
> version 2.2 of the instruction set, it's later than that) changed the
Oh, thanks for catching this - I indeed incorrectly assumed this refers to
version 2.2 of the RISC-V spec (which contains F/D, .. of version 2.0).
Too bad, it appeared too convenient. Then I need to add the same
!HONOR_SNANS to all the expanders as well as the tests.
Regards
Robin
^ permalink raw reply [flat|nested] 5+ messages in thread
* Re: [PATCH] RISC-V: Add vector fmin/fmax expanders.
2023-10-31 1:19 ` juzhe.zhong
@ 2023-10-31 11:51 ` Robin Dapp
0 siblings, 0 replies; 5+ messages in thread
From: Robin Dapp @ 2023-10-31 11:51 UTC (permalink / raw)
To: juzhe.zhong, joseph
Cc: rdapp.gcc, gcc-patches, palmer, kito.cheng, jeffreyalaw
Thanks, going to commit the attached.
Regards
Robin
This patch adds expanders for fmin and fmax. As per RISC-V V Spec 1.0
vfmin/vfmax are IEEE 754-2019 compliant which differs from IEEE 754-2008
that fmin/fmax require (particularly in the signaling-NaN handling).
Therefore the pattern conditions include a !HONOR_SNANS.
gcc/ChangeLog:
* config/riscv/autovec.md (<ieee_fmaxmin_op><mode>3): fmax/fmin
expanders.
(cond_<ieee_fmaxmin_op><mode>): Ditto.
(cond_len_<ieee_fmaxmin_op><mode>): Ditto.
(reduc_fmax_scal_<mode>): Ditto.
(reduc_fmin_scal_<mode>): Ditto.
* config/riscv/riscv-v.cc (needs_fp_rounding): Add fmin/fmax.
* config/riscv/vector-iterators.md (fmin): New UNSPEC.
(UNSPEC_VFMIN): Ditto.
* config/riscv/vector.md (@pred_<ieee_fmaxmin_op><mode>): Add
UNSPEC insn patterns.
(@pred_<ieee_fmaxmin_op><mode>_scalar): Ditto.
gcc/testsuite/ChangeLog:
* gcc.target/riscv/rvv/autovec/cond/cond_fmax-1.c: Remove
-ffast-math.
* gcc.target/riscv/rvv/autovec/cond/cond_fmax-2.c: Ditto.
* gcc.target/riscv/rvv/autovec/cond/cond_fmax-3.c: Ditto.
* gcc.target/riscv/rvv/autovec/cond/cond_fmax-4.c: Ditto.
* gcc.target/riscv/rvv/autovec/cond/cond_fmax_run-1.c: Ditto.
* gcc.target/riscv/rvv/autovec/cond/cond_fmax_run-2.c: Ditto.
* gcc.target/riscv/rvv/autovec/cond/cond_fmax_run-3.c: Ditto.
* gcc.target/riscv/rvv/autovec/cond/cond_fmax_run-4.c: Ditto.
* gcc.target/riscv/rvv/autovec/cond/cond_fmin-1.c: Ditto.
* gcc.target/riscv/rvv/autovec/cond/cond_fmin-2.c: Ditto.
* gcc.target/riscv/rvv/autovec/cond/cond_fmin-3.c: Ditto.
* gcc.target/riscv/rvv/autovec/cond/cond_fmin-4.c: Ditto.
* gcc.target/riscv/rvv/autovec/cond/cond_fmin_run-1.c: Ditto.
* gcc.target/riscv/rvv/autovec/cond/cond_fmin_run-2.c: Ditto.
* gcc.target/riscv/rvv/autovec/cond/cond_fmin_run-3.c: Ditto.
* gcc.target/riscv/rvv/autovec/cond/cond_fmin_run-4.c: Ditto.
* gcc.target/riscv/rvv/autovec/binop/fmax-1.c: New test.
* gcc.target/riscv/rvv/autovec/binop/fmax_run-1.c: New test.
* gcc.target/riscv/rvv/autovec/binop/fmax_zvfh-1.c: New test.
* gcc.target/riscv/rvv/autovec/binop/fmax_zvfh_run-1.c: New test.
* gcc.target/riscv/rvv/autovec/binop/fmin-1.c: New test.
* gcc.target/riscv/rvv/autovec/binop/fmin_run-1.c: New test.
* gcc.target/riscv/rvv/autovec/binop/fmin_zvfh-1.c: New test.
* gcc.target/riscv/rvv/autovec/binop/fmin_zvfh_run-1.c: New test.
* gcc.target/riscv/rvv/autovec/cond/cond_fmax_zvfh-1.c: New test.
* gcc.target/riscv/rvv/autovec/cond/cond_fmax_zvfh-2.c: New test.
* gcc.target/riscv/rvv/autovec/cond/cond_fmax_zvfh-3.c: New test.
* gcc.target/riscv/rvv/autovec/cond/cond_fmax_zvfh-4.c: New test.
* gcc.target/riscv/rvv/autovec/cond/cond_fmax_zvfh_run-1.c: New test.
* gcc.target/riscv/rvv/autovec/cond/cond_fmax_zvfh_run-2.c: New test.
* gcc.target/riscv/rvv/autovec/cond/cond_fmax_zvfh_run-3.c: New test.
* gcc.target/riscv/rvv/autovec/cond/cond_fmax_zvfh_run-4.c: New test.
* gcc.target/riscv/rvv/autovec/cond/cond_fmin_zvfh-1.c: New test.
* gcc.target/riscv/rvv/autovec/cond/cond_fmin_zvfh-2.c: New test.
* gcc.target/riscv/rvv/autovec/cond/cond_fmin_zvfh-3.c: New test.
* gcc.target/riscv/rvv/autovec/cond/cond_fmin_zvfh-4.c: New test.
* gcc.target/riscv/rvv/autovec/cond/cond_fmin_zvfh_run-1.c: New test.
* gcc.target/riscv/rvv/autovec/cond/cond_fmin_zvfh_run-2.c: New test.
* gcc.target/riscv/rvv/autovec/cond/cond_fmin_zvfh_run-3.c: New test.
* gcc.target/riscv/rvv/autovec/cond/cond_fmin_zvfh_run-4.c: New test.
* gcc.target/riscv/rvv/autovec/reduc/reduc-10.c: New test.
* gcc.target/riscv/rvv/autovec/reduc/reduc_run-10.c: New test.
* gcc.target/riscv/rvv/autovec/reduc/reduc_run_zvfh-10.c: New test.
* gcc.target/riscv/rvv/autovec/reduc/reduc_zvfh-10.c: New test.
---
gcc/config/riscv/autovec.md | 72 +++++++++++++++++++
gcc/config/riscv/riscv-v.cc | 2 +
gcc/config/riscv/vector-iterators.md | 8 +++
gcc/config/riscv/vector.md | 43 +++++++++++
.../riscv/rvv/autovec/binop/fmax-1.c | 24 +++++++
.../riscv/rvv/autovec/binop/fmax_run-1.c | 47 ++++++++++++
.../riscv/rvv/autovec/binop/fmax_zvfh-1.c | 23 ++++++
.../riscv/rvv/autovec/binop/fmax_zvfh_run-1.c | 48 +++++++++++++
.../riscv/rvv/autovec/binop/fmin-1.c | 10 +++
.../riscv/rvv/autovec/binop/fmin_run-1.c | 5 ++
.../riscv/rvv/autovec/binop/fmin_zvfh-1.c | 10 +++
.../riscv/rvv/autovec/binop/fmin_zvfh_run-1.c | 5 ++
.../riscv/rvv/autovec/cond/cond_fmax-1.c | 6 +-
.../riscv/rvv/autovec/cond/cond_fmax-2.c | 3 +-
.../riscv/rvv/autovec/cond/cond_fmax-3.c | 6 +-
.../riscv/rvv/autovec/cond/cond_fmax-4.c | 6 +-
.../riscv/rvv/autovec/cond/cond_fmax_run-1.c | 3 +-
.../riscv/rvv/autovec/cond/cond_fmax_run-2.c | 3 +-
.../riscv/rvv/autovec/cond/cond_fmax_run-3.c | 3 +-
.../riscv/rvv/autovec/cond/cond_fmax_run-4.c | 3 +-
.../riscv/rvv/autovec/cond/cond_fmax_zvfh-1.c | 33 +++++++++
.../riscv/rvv/autovec/cond/cond_fmax_zvfh-2.c | 33 +++++++++
.../riscv/rvv/autovec/cond/cond_fmax_zvfh-3.c | 33 +++++++++
.../riscv/rvv/autovec/cond/cond_fmax_zvfh-4.c | 33 +++++++++
.../rvv/autovec/cond/cond_fmax_zvfh_run-1.c | 33 +++++++++
.../rvv/autovec/cond/cond_fmax_zvfh_run-2.c | 32 +++++++++
.../rvv/autovec/cond/cond_fmax_zvfh_run-3.c | 33 +++++++++
.../rvv/autovec/cond/cond_fmax_zvfh_run-4.c | 33 +++++++++
.../riscv/rvv/autovec/cond/cond_fmin-1.c | 5 +-
.../riscv/rvv/autovec/cond/cond_fmin-2.c | 3 +-
.../riscv/rvv/autovec/cond/cond_fmin-3.c | 5 +-
.../riscv/rvv/autovec/cond/cond_fmin-4.c | 5 +-
.../riscv/rvv/autovec/cond/cond_fmin_run-1.c | 2 +-
.../riscv/rvv/autovec/cond/cond_fmin_run-2.c | 2 +-
.../riscv/rvv/autovec/cond/cond_fmin_run-3.c | 2 +-
.../riscv/rvv/autovec/cond/cond_fmin_run-4.c | 2 +-
.../riscv/rvv/autovec/cond/cond_fmin_zvfh-1.c | 11 +++
.../riscv/rvv/autovec/cond/cond_fmin_zvfh-2.c | 11 +++
.../riscv/rvv/autovec/cond/cond_fmin_zvfh-3.c | 11 +++
.../riscv/rvv/autovec/cond/cond_fmin_zvfh-4.c | 11 +++
.../rvv/autovec/cond/cond_fmin_zvfh_run-1.c | 5 ++
.../rvv/autovec/cond/cond_fmin_zvfh_run-2.c | 5 ++
.../rvv/autovec/cond/cond_fmin_zvfh_run-3.c | 5 ++
.../rvv/autovec/cond/cond_fmin_zvfh_run-4.c | 5 ++
.../riscv/rvv/autovec/reduc/reduc-10.c | 26 +++++++
.../riscv/rvv/autovec/reduc/reduc_run-10.c | 41 +++++++++++
.../riscv/rvv/autovec/reduc/reduc_zvfh-10.c | 24 +++++++
.../rvv/autovec/reduc/reduc_zvfh_run-10.c | 41 +++++++++++
48 files changed, 790 insertions(+), 25 deletions(-)
create mode 100644 gcc/testsuite/gcc.target/riscv/rvv/autovec/binop/fmax-1.c
create mode 100644 gcc/testsuite/gcc.target/riscv/rvv/autovec/binop/fmax_run-1.c
create mode 100644 gcc/testsuite/gcc.target/riscv/rvv/autovec/binop/fmax_zvfh-1.c
create mode 100644 gcc/testsuite/gcc.target/riscv/rvv/autovec/binop/fmax_zvfh_run-1.c
create mode 100644 gcc/testsuite/gcc.target/riscv/rvv/autovec/binop/fmin-1.c
create mode 100644 gcc/testsuite/gcc.target/riscv/rvv/autovec/binop/fmin_run-1.c
create mode 100644 gcc/testsuite/gcc.target/riscv/rvv/autovec/binop/fmin_zvfh-1.c
create mode 100644 gcc/testsuite/gcc.target/riscv/rvv/autovec/binop/fmin_zvfh_run-1.c
create mode 100644 gcc/testsuite/gcc.target/riscv/rvv/autovec/cond/cond_fmax_zvfh-1.c
create mode 100644 gcc/testsuite/gcc.target/riscv/rvv/autovec/cond/cond_fmax_zvfh-2.c
create mode 100644 gcc/testsuite/gcc.target/riscv/rvv/autovec/cond/cond_fmax_zvfh-3.c
create mode 100644 gcc/testsuite/gcc.target/riscv/rvv/autovec/cond/cond_fmax_zvfh-4.c
create mode 100644 gcc/testsuite/gcc.target/riscv/rvv/autovec/cond/cond_fmax_zvfh_run-1.c
create mode 100644 gcc/testsuite/gcc.target/riscv/rvv/autovec/cond/cond_fmax_zvfh_run-2.c
create mode 100644 gcc/testsuite/gcc.target/riscv/rvv/autovec/cond/cond_fmax_zvfh_run-3.c
create mode 100644 gcc/testsuite/gcc.target/riscv/rvv/autovec/cond/cond_fmax_zvfh_run-4.c
create mode 100644 gcc/testsuite/gcc.target/riscv/rvv/autovec/cond/cond_fmin_zvfh-1.c
create mode 100644 gcc/testsuite/gcc.target/riscv/rvv/autovec/cond/cond_fmin_zvfh-2.c
create mode 100644 gcc/testsuite/gcc.target/riscv/rvv/autovec/cond/cond_fmin_zvfh-3.c
create mode 100644 gcc/testsuite/gcc.target/riscv/rvv/autovec/cond/cond_fmin_zvfh-4.c
create mode 100644 gcc/testsuite/gcc.target/riscv/rvv/autovec/cond/cond_fmin_zvfh_run-1.c
create mode 100644 gcc/testsuite/gcc.target/riscv/rvv/autovec/cond/cond_fmin_zvfh_run-2.c
create mode 100644 gcc/testsuite/gcc.target/riscv/rvv/autovec/cond/cond_fmin_zvfh_run-3.c
create mode 100644 gcc/testsuite/gcc.target/riscv/rvv/autovec/cond/cond_fmin_zvfh_run-4.c
create mode 100644 gcc/testsuite/gcc.target/riscv/rvv/autovec/reduc/reduc-10.c
create mode 100644 gcc/testsuite/gcc.target/riscv/rvv/autovec/reduc/reduc_run-10.c
create mode 100644 gcc/testsuite/gcc.target/riscv/rvv/autovec/reduc/reduc_zvfh-10.c
create mode 100644 gcc/testsuite/gcc.target/riscv/rvv/autovec/reduc/reduc_zvfh_run-10.c
diff --git a/gcc/config/riscv/autovec.md b/gcc/config/riscv/autovec.md
index 9803f7524d7..f5e3e347ace 100644
--- a/gcc/config/riscv/autovec.md
+++ b/gcc/config/riscv/autovec.md
@@ -1436,6 +1436,22 @@ (define_insn_and_split "<optab><mode>3"
}
[(set_attr "type" "vfminmax")])
+(define_insn_and_split "<ieee_fmaxmin_op><mode>3"
+ [(set (match_operand:V_VLSF 0 "register_operand")
+ (unspec:V_VLSF
+ [(match_operand:V_VLSF 1 "register_operand")
+ (match_operand:V_VLSF 2 "register_operand")] UNSPEC_VFMAXMIN))]
+ "TARGET_VECTOR && !HONOR_SNANS (<MODE>mode) && can_create_pseudo_p ()"
+ "#"
+ "&& 1"
+ [(const_int 0)]
+{
+ riscv_vector::emit_vlmax_insn (code_for_pred (<IEEE_FMAXMIN_OP>, <MODE>mode),
+ riscv_vector::BINARY_OP, operands);
+ DONE;
+}
+[(set_attr "type" "vfminmax")])
+
;; -------------------------------------------------------------------------------
;; ---- [FP] Sign copying
;; -------------------------------------------------------------------------------
@@ -1736,6 +1752,36 @@ (define_expand "cond_len_<optab><mode>"
DONE;
})
+(define_expand "cond_<ieee_fmaxmin_op><mode>"
+ [(match_operand:V_VLSF 0 "register_operand")
+ (match_operand:<VM> 1 "vector_mask_operand")
+ (unspec:V_VLSF
+ [(match_operand:V_VLSF 2 "register_operand")
+ (match_operand:V_VLSF 3 "register_operand")] UNSPEC_VFMAXMIN)
+ (match_operand:V_VLSF 4 "autovec_else_operand")]
+ "TARGET_VECTOR && !HONOR_SNANS (<MODE>mode)"
+{
+ insn_code icode = code_for_pred (<IEEE_FMAXMIN_OP>, <MODE>mode);
+ riscv_vector::expand_cond_binop (icode, operands);
+ DONE;
+})
+
+(define_expand "cond_len_<ieee_fmaxmin_op><mode>"
+ [(match_operand:VF 0 "register_operand")
+ (match_operand:<VM> 1 "vector_mask_operand")
+ (unspec:VF
+ [(match_operand:VF 2 "register_operand")
+ (match_operand:VF 3 "register_operand")] UNSPEC_VFMAXMIN)
+ (match_operand:VF 4 "autovec_else_operand")
+ (match_operand 5 "autovec_length_operand")
+ (match_operand 6 "const_0_operand")]
+ "TARGET_VECTOR && !HONOR_SNANS (<MODE>mode)"
+{
+ insn_code icode = code_for_pred (<IEEE_FMAXMIN_OP>, <MODE>mode);
+ riscv_vector::expand_cond_len_binop (icode, operands);
+ DONE;
+})
+
;; -------------------------------------------------------------------------
;; ---- [INT] Conditional ternary operations
;; -------------------------------------------------------------------------
@@ -2092,6 +2138,32 @@ (define_expand "reduc_smin_scal_<mode>"
DONE;
})
+(define_expand "reduc_fmax_scal_<mode>"
+ [(match_operand:<VEL> 0 "register_operand")
+ (match_operand:V_VLSF 1 "register_operand")]
+ "TARGET_VECTOR && !HONOR_SNANS (<MODE>mode)"
+{
+ REAL_VALUE_TYPE rv;
+ real_inf (&rv, true);
+ rtx f = const_double_from_real_value (rv, <VEL>mode);
+ riscv_vector::expand_reduction (UNSPEC_REDUC_MAX, riscv_vector::REDUCE_OP,
+ operands, f);
+ DONE;
+})
+
+(define_expand "reduc_fmin_scal_<mode>"
+ [(match_operand:<VEL> 0 "register_operand")
+ (match_operand:V_VLSF 1 "register_operand")]
+ "TARGET_VECTOR && !HONOR_SNANS (<MODE>mode)"
+{
+ REAL_VALUE_TYPE rv;
+ real_inf (&rv, false);
+ rtx f = const_double_from_real_value (rv, <VEL>mode);
+ riscv_vector::expand_reduction (UNSPEC_REDUC_MIN, riscv_vector::REDUCE_OP,
+ operands, f);
+ DONE;
+})
+
;; -------------------------------------------------------------------------
;; ---- [FP] Left-to-right reductions
;; -------------------------------------------------------------------------
diff --git a/gcc/config/riscv/riscv-v.cc b/gcc/config/riscv/riscv-v.cc
index ee631404b44..3a49ae76426 100644
--- a/gcc/config/riscv/riscv-v.cc
+++ b/gcc/config/riscv/riscv-v.cc
@@ -3211,7 +3211,9 @@ needs_fp_rounding (unsigned icode, machine_mode mode)
return false;
return icode != maybe_code_for_pred (SMIN, mode)
+ && icode != maybe_code_for_pred (UNSPEC_VFMIN, mode)
&& icode != maybe_code_for_pred (SMAX, mode)
+ && icode != maybe_code_for_pred (UNSPEC_VFMAX, mode)
&& icode != maybe_code_for_pred (NEG, mode)
&& icode != maybe_code_for_pred (ABS, mode)
/* narrower-FP -> FP */
diff --git a/gcc/config/riscv/vector-iterators.md b/gcc/config/riscv/vector-iterators.md
index e80a20dcfba..d9b5dec5edb 100644
--- a/gcc/config/riscv/vector-iterators.md
+++ b/gcc/config/riscv/vector-iterators.md
@@ -82,6 +82,9 @@ (define_c_enum "unspec" [
UNSPEC_VFFMA
+ UNSPEC_VFMAX
+ UNSPEC_VFMIN
+
;; Integer and Float Reduction
UNSPEC_REDUC
UNSPEC_REDUC_SUM
@@ -3479,6 +3482,11 @@ (define_int_attr ud_constraint [(UNSPEC_VSLIDEUP "=&vr,&vr,&vr,&vr") (UNSPEC_VSL
(define_int_attr UNSPEC [(UNSPEC_VSLIDE1UP "UNSPEC_VSLIDE1UP")
(UNSPEC_VSLIDE1DOWN "UNSPEC_VSLIDE1DOWN")])
+(define_int_iterator UNSPEC_VFMAXMIN [UNSPEC_VFMAX UNSPEC_VFMIN])
+
+(define_int_attr ieee_fmaxmin_op [(UNSPEC_VFMAX "fmax") (UNSPEC_VFMIN "fmin")])
+(define_int_attr IEEE_FMAXMIN_OP [(UNSPEC_VFMAX "UNSPEC_VFMAX") (UNSPEC_VFMIN "UNSPEC_VFMIN")])
+
(define_code_iterator any_int_binop [plus minus and ior xor ashift ashiftrt lshiftrt
smax umax smin umin mult div udiv mod umod
])
diff --git a/gcc/config/riscv/vector.md b/gcc/config/riscv/vector.md
index c4c136cb5d2..0297e4f0227 100644
--- a/gcc/config/riscv/vector.md
+++ b/gcc/config/riscv/vector.md
@@ -6103,6 +6103,27 @@ (define_insn "@pred_<optab><mode>"
[(set_attr "type" "<float_insn_type>")
(set_attr "mode" "<MODE>")])
+(define_insn "@pred_<ieee_fmaxmin_op><mode>"
+ [(set (match_operand:V_VLSF 0 "register_operand" "=vd, vd, vr, vr")
+ (if_then_else:V_VLSF
+ (unspec:<VM>
+ [(match_operand:<VM> 1 "vector_mask_operand" " vm, vm,Wc1,Wc1")
+ (match_operand 5 "vector_length_operand" " rK, rK, rK, rK")
+ (match_operand 6 "const_int_operand" " i, i, i, i")
+ (match_operand 7 "const_int_operand" " i, i, i, i")
+ (match_operand 8 "const_int_operand" " i, i, i, i")
+ (reg:SI VL_REGNUM)
+ (reg:SI VTYPE_REGNUM)] UNSPEC_VPREDICATE)
+ (unspec:V_VLSF
+ [(match_operand:V_VLSF 3 "register_operand" " vr, vr, vr, vr")
+ (match_operand:V_VLSF 4 "register_operand" " vr, vr, vr, vr")]
+ UNSPEC_VFMAXMIN)
+ (match_operand:V_VLSF 2 "vector_merge_operand" " vu, 0, vu, 0")))]
+ "TARGET_VECTOR"
+ "v<ieee_fmaxmin_op>.vv\t%0,%3,%4%p1"
+ [(set_attr "type" "vfminmax")
+ (set_attr "mode" "<MODE>")])
+
(define_insn "@pred_<optab><mode>_scalar"
[(set (match_operand:VF 0 "register_operand" "=vd, vd, vr, vr")
(if_then_else:VF
@@ -6149,6 +6170,28 @@ (define_insn "@pred_<optab><mode>_scalar"
[(set_attr "type" "<float_insn_type>")
(set_attr "mode" "<MODE>")])
+(define_insn "@pred_<ieee_fmaxmin_op><mode>_scalar"
+ [(set (match_operand:VF 0 "register_operand" "=vd, vd, vr, vr")
+ (if_then_else:VF
+ (unspec:<VM>
+ [(match_operand:<VM> 1 "vector_mask_operand" " vm, vm,Wc1,Wc1")
+ (match_operand 5 "vector_length_operand" " rK, rK, rK, rK")
+ (match_operand 6 "const_int_operand" " i, i, i, i")
+ (match_operand 7 "const_int_operand" " i, i, i, i")
+ (match_operand 8 "const_int_operand" " i, i, i, i")
+ (reg:SI VL_REGNUM)
+ (reg:SI VTYPE_REGNUM)] UNSPEC_VPREDICATE)
+ (unspec:VF
+ [(match_operand:VF 3 "register_operand" " vr, vr, vr, vr")
+ (vec_duplicate:VF
+ (match_operand:<VEL> 4 "register_operand" " f, f, f, f"))]
+ UNSPEC_VFMAXMIN)
+ (match_operand:VF 2 "vector_merge_operand" " vu, 0, vu, 0")))]
+ "TARGET_VECTOR"
+ "v<ieee_fmaxmin_op>.vf\t%0,%3,%4%p1"
+ [(set_attr "type" "vfminmax")
+ (set_attr "mode" "<MODE>")])
+
(define_insn "@pred_<optab><mode>_scalar"
[(set (match_operand:VF 0 "register_operand" "=vd, vd, vr, vr")
(if_then_else:VF
diff --git a/gcc/testsuite/gcc.target/riscv/rvv/autovec/binop/fmax-1.c b/gcc/testsuite/gcc.target/riscv/rvv/autovec/binop/fmax-1.c
new file mode 100644
index 00000000000..d635499c017
--- /dev/null
+++ b/gcc/testsuite/gcc.target/riscv/rvv/autovec/binop/fmax-1.c
@@ -0,0 +1,24 @@
+/* { dg-do compile } */
+/* { dg-additional-options "-march=rv32gcv -mabi=ilp32d --param=riscv-autovec-preference=scalable --param vect-epilogues-nomask=0 -fno-signaling-nans" } */
+
+#include <stdint-gcc.h>
+
+#ifndef FN
+#define FN(X) __builtin_fmax##X
+#endif
+
+#define DEF_LOOP(FN, SUFFIX, TYPE) \
+ void __attribute__ ((noipa)) \
+ test_##TYPE (TYPE *__restrict x, TYPE *__restrict y, int n) \
+ { \
+ for (int i = 0; i < n; ++i) \
+ x[i] = FN (SUFFIX) (x[i], y[i]); \
+ }
+
+#define TEST_ALL(T) \
+ T (FN, f, float) \
+ T (FN, , double)
+
+TEST_ALL (DEF_LOOP)
+
+/* { dg-final { scan-assembler-times {vfmax\.vv\s+v[0-9]+,v[0-9]+,v[0-9]+} 2 } } */
diff --git a/gcc/testsuite/gcc.target/riscv/rvv/autovec/binop/fmax_run-1.c b/gcc/testsuite/gcc.target/riscv/rvv/autovec/binop/fmax_run-1.c
new file mode 100644
index 00000000000..31661ee8900
--- /dev/null
+++ b/gcc/testsuite/gcc.target/riscv/rvv/autovec/binop/fmax_run-1.c
@@ -0,0 +1,47 @@
+/* { dg-do run { target { riscv_v } } } */
+/* { dg-additional-options "--param=riscv-autovec-preference=scalable -fno-signaling-nans" } */
+
+#include <math.h>
+#include "fmax-1.c"
+
+#define N 99
+
+#define TEST_LOOP(FN, SUFFIX, TYPE) \
+ { \
+ TYPE dst[N], x[N], y[N]; \
+ for (int i = 0; i < N; ++i) \
+ { \
+ x[i] = i; \
+ dst[i] = i; \
+ y[i] = ((i & 1) - 1) * i * i; \
+ } \
+ y[0] = -0.0; \
+ y[1] = 0.0; \
+ y[2] = nan ("0.0"); \
+ y[3] = INFINITY; \
+ y[4] = -INFINITY; \
+ x[5] = -0.0; \
+ x[6] = 0.0; \
+ x[7] = nan ("0.0"); \
+ x[8] = INFINITY; \
+ x[9] = -INFINITY; \
+ dst[5] = -0.0; \
+ dst[6] = 0.0; \
+ dst[7] = nan ("0.0"); \
+ dst[8] = INFINITY; \
+ dst[9] = -INFINITY; \
+ test_##TYPE (dst, y, N); \
+ for (int i = 0; i < N; ++i) \
+ { \
+ double ref = FN (SUFFIX) (x[i], y[i]); \
+ if (dst[i] != ref) \
+ __builtin_abort (); \
+ asm volatile ("" ::: "memory"); \
+ } \
+ }
+
+int __attribute__ ((optimize ("1"))) main (void)
+{
+ TEST_ALL (TEST_LOOP)
+ return 0;
+}
diff --git a/gcc/testsuite/gcc.target/riscv/rvv/autovec/binop/fmax_zvfh-1.c b/gcc/testsuite/gcc.target/riscv/rvv/autovec/binop/fmax_zvfh-1.c
new file mode 100644
index 00000000000..c137955619f
--- /dev/null
+++ b/gcc/testsuite/gcc.target/riscv/rvv/autovec/binop/fmax_zvfh-1.c
@@ -0,0 +1,23 @@
+/* { dg-do run { target { riscv_zvfh } } } */
+/* { dg-additional-options "--param=riscv-autovec-preference=scalable -fno-signaling-nans" } */
+
+#include <stdint-gcc.h>
+
+#ifndef FN
+#define FN(X) __builtin_fmax##X
+#endif
+
+#define DEF_LOOP(FN, SUFFIX, TYPE) \
+ void __attribute__ ((noipa)) \
+ test_##TYPE (TYPE *__restrict x, TYPE *__restrict y, int n) \
+ { \
+ for (int i = 0; i < n; ++i) \
+ x[i] = FN (SUFFIX) (x[i], y[i]); \
+ }
+
+#define TEST_ALL(T) \
+ T (FN, f16, _Float16) \
+
+TEST_ALL (DEF_LOOP)
+
+/* { dg-final { scan-assembler-times {vfmax\.vv\s+v[0-9]+,v[0-9]+,v[0-9]+} 1 } } */
diff --git a/gcc/testsuite/gcc.target/riscv/rvv/autovec/binop/fmax_zvfh_run-1.c b/gcc/testsuite/gcc.target/riscv/rvv/autovec/binop/fmax_zvfh_run-1.c
new file mode 100644
index 00000000000..4a248c28e0a
--- /dev/null
+++ b/gcc/testsuite/gcc.target/riscv/rvv/autovec/binop/fmax_zvfh_run-1.c
@@ -0,0 +1,48 @@
+/* { dg-do run { target { riscv_zvfh } } } */
+/* { dg-additional-options "--param=riscv-autovec-preference=scalable -fno-signaling-nans" } */
+
+#include <math.h>
+#include "fmax_zvfh-1.c"
+
+#define N 99
+
+#define TEST_LOOP(FN, SUFFIX, TYPE) \
+ { \
+ TYPE dst[N], x[N], y[N]; \
+ for (int i = 0; i < N; ++i) \
+ { \
+ x[i] = i; \
+ dst[i] = i; \
+ y[i] = ((i & 1) - 1) * i * i; \
+ } \
+ y[0] = -0.0; \
+ y[1] = 0.0; \
+ y[2] = nan ("0.0"); \
+ y[3] = INFINITY; \
+ y[4] = -INFINITY; \
+ x[5] = -0.0; \
+ x[6] = 0.0; \
+ x[7] = nan ("0.0"); \
+ x[8] = INFINITY; \
+ x[9] = -INFINITY; \
+ dst[5] = -0.0; \
+ dst[6] = 0.0; \
+ dst[7] = nan ("0.0"); \
+ dst[8] = INFINITY; \
+ dst[9] = -INFINITY; \
+ kest_##TYPE (dst, y, N); \
+ for (int i = 0; i < N; ++i) \
+ { \
+ double ref = FN (SUFFIX) (x[i], y[i]); \
+ if (dst[i] != ref) \
+ __builtin_abort (); \
+ asm volatile ("" ::: "memory"); \
+ } \
+ }
+
+
+int __attribute__ ((optimize ("1"))) main (void)
+{
+ TEST_ALL (TEST_LOOP)
+ return 0;
+}
diff --git a/gcc/testsuite/gcc.target/riscv/rvv/autovec/binop/fmin-1.c b/gcc/testsuite/gcc.target/riscv/rvv/autovec/binop/fmin-1.c
new file mode 100644
index 00000000000..0d2b53e21dc
--- /dev/null
+++ b/gcc/testsuite/gcc.target/riscv/rvv/autovec/binop/fmin-1.c
@@ -0,0 +1,10 @@
+/* { dg-do compile } */
+/* { dg-additional-options "-march=rv32gcv -mabi=ilp32d --param=riscv-autovec-preference=scalable --param vect-epilogues-nomask=0 -fno-signaling-nans" } */
+
+#include <stdint-gcc.h>
+
+#define FN(X) __builtin_fmin##X
+#include "fmax-1.c"
+
+/* { dg-final { scan-assembler-times {vfmin\.vv\s+v[0-9]+,v[0-9]+,v[0-9]+} 2 } } */
+
diff --git a/gcc/testsuite/gcc.target/riscv/rvv/autovec/binop/fmin_run-1.c b/gcc/testsuite/gcc.target/riscv/rvv/autovec/binop/fmin_run-1.c
new file mode 100644
index 00000000000..1964137347f
--- /dev/null
+++ b/gcc/testsuite/gcc.target/riscv/rvv/autovec/binop/fmin_run-1.c
@@ -0,0 +1,5 @@
+/* { dg-do run { target { riscv_v } } } */
+/* { dg-additional-options "--param=riscv-autovec-preference=scalable -fno-vect-cost-model -fno-signaling-nans" } */
+
+#define FN(X) __builtin_fmin##X
+#include "fmax_run-1.c"
diff --git a/gcc/testsuite/gcc.target/riscv/rvv/autovec/binop/fmin_zvfh-1.c b/gcc/testsuite/gcc.target/riscv/rvv/autovec/binop/fmin_zvfh-1.c
new file mode 100644
index 00000000000..39643a71f25
--- /dev/null
+++ b/gcc/testsuite/gcc.target/riscv/rvv/autovec/binop/fmin_zvfh-1.c
@@ -0,0 +1,10 @@
+/* { dg-do compile } */
+/* { dg-additional-options "-march=rv32gcv_zvfh -mabi=ilp32d --param=riscv-autovec-preference=scalable --param vect-epilogues-nomask=0 -fno-signaling-nans" } */
+
+#include <stdint-gcc.h>
+
+#define FN(X) __builtin_fmin##X
+#include "fmax_zvfh-1.c"
+
+/* { dg-final { scan-assembler-times {vfmin\.vv\s+v[0-9]+,v[0-9]+,v[0-9]+} 1 } } */
+
diff --git a/gcc/testsuite/gcc.target/riscv/rvv/autovec/binop/fmin_zvfh_run-1.c b/gcc/testsuite/gcc.target/riscv/rvv/autovec/binop/fmin_zvfh_run-1.c
new file mode 100644
index 00000000000..05bfce42e9a
--- /dev/null
+++ b/gcc/testsuite/gcc.target/riscv/rvv/autovec/binop/fmin_zvfh_run-1.c
@@ -0,0 +1,5 @@
+/* { dg-do run { target { riscv_zvfh } } } */
+/* { dg-additional-options "--param=riscv-autovec-preference=scalable -fno-signaling-nans" } */
+
+#define FN(X) __builtin_fmin##X
+#include "fmax_zvfh_run-1.c"
diff --git a/gcc/testsuite/gcc.target/riscv/rvv/autovec/cond/cond_fmax-1.c b/gcc/testsuite/gcc.target/riscv/rvv/autovec/cond/cond_fmax-1.c
index c5167b54fb3..25c35cf0607 100644
--- a/gcc/testsuite/gcc.target/riscv/rvv/autovec/cond/cond_fmax-1.c
+++ b/gcc/testsuite/gcc.target/riscv/rvv/autovec/cond/cond_fmax-1.c
@@ -1,7 +1,8 @@
/* { dg-do compile } */
-/* { dg-additional-options "-march=rv32gcv_zvfh -mabi=ilp32d --param=riscv-autovec-preference=scalable -fno-vect-cost-model -ffast-math" } */
+/* { dg-additional-options "-march=rv32gcv_zvfh -mabi=ilp32d --param=riscv-autovec-preference=scalable -fno-vect-cost-model -fno-signaling-nans" } */
#include <stdint-gcc.h>
+#include <math.h>
#ifndef FN
#define FN(X) __builtin_fmax##X
@@ -24,11 +25,10 @@
T (FN, TYPE, PRED_TYPE, two, 2)
#define TEST_ALL(T) \
- TEST_TYPE (T, FN (f16), _Float16, int16_t) \
TEST_TYPE (T, FN (f32), float, int32_t) \
TEST_TYPE (T, FN (f64), double, int64_t)
TEST_ALL (DEF_LOOP)
-/* { dg-final { scan-assembler-times {vfmax\.vv\s+v[0-9]+,v[0-9]+,v[0-9]+,v0.t} 9 } } */
+/* { dg-final { scan-assembler-times {vfmax\.vv\s+v[0-9]+,v[0-9]+,v[0-9]+,v0.t} 6 } } */
/* { dg-final { scan-assembler-not {\tvf?merge\.v[vxi]m\t} } } */
diff --git a/gcc/testsuite/gcc.target/riscv/rvv/autovec/cond/cond_fmax-2.c b/gcc/testsuite/gcc.target/riscv/rvv/autovec/cond/cond_fmax-2.c
index 30b6ae62777..17f86238b0f 100644
--- a/gcc/testsuite/gcc.target/riscv/rvv/autovec/cond/cond_fmax-2.c
+++ b/gcc/testsuite/gcc.target/riscv/rvv/autovec/cond/cond_fmax-2.c
@@ -1,7 +1,8 @@
/* { dg-do compile } */
-/* { dg-additional-options "-march=rv32gcv_zvfh -mabi=ilp32d --param=riscv-autovec-preference=scalable -fno-vect-cost-model -ffast-math" } */
+/* { dg-additional-options "-march=rv32gcv_zvfh -mabi=ilp32d --param=riscv-autovec-preference=scalable -fno-vect-cost-model -fno-signaling-nans" } */
#include <stdint-gcc.h>
+#include <math.h>
#ifndef FN
#define FN(X) __builtin_fmax##X
diff --git a/gcc/testsuite/gcc.target/riscv/rvv/autovec/cond/cond_fmax-3.c b/gcc/testsuite/gcc.target/riscv/rvv/autovec/cond/cond_fmax-3.c
index 4521f588f1c..9a29b52de3d 100644
--- a/gcc/testsuite/gcc.target/riscv/rvv/autovec/cond/cond_fmax-3.c
+++ b/gcc/testsuite/gcc.target/riscv/rvv/autovec/cond/cond_fmax-3.c
@@ -1,7 +1,8 @@
/* { dg-do compile } */
-/* { dg-additional-options "-march=rv32gcv_zvfh -mabi=ilp32d --param=riscv-autovec-preference=scalable -fno-vect-cost-model -ffast-math" } */
+/* { dg-additional-options "-march=rv32gcv_zvfh -mabi=ilp32d --param=riscv-autovec-preference=scalable -fno-vect-cost-model -fno-signaling-nans" } */
#include <stdint-gcc.h>
+#include <math.h>
#ifndef FN
#define FN(X) __builtin_fmax##X
@@ -24,11 +25,10 @@
T (FN, TYPE, PRED_TYPE, two, 2)
#define TEST_ALL(T) \
- TEST_TYPE (T, FN (f16), _Float16, int16_t) \
TEST_TYPE (T, FN (f32), float, int32_t) \
TEST_TYPE (T, FN (f64), double, int64_t)
TEST_ALL (DEF_LOOP)
-/* { dg-final { scan-assembler-times {vfmax\.vv\s+v[0-9]+,v[0-9]+,v[0-9]+,v0.t} 9 } } */
+/* { dg-final { scan-assembler-times {vfmax\.vv\s+v[0-9]+,v[0-9]+,v[0-9]+,v0.t} 6 } } */
/* { dg-final { scan-assembler-not {\tvf?merge\.v[vxi]m\t} } } */
diff --git a/gcc/testsuite/gcc.target/riscv/rvv/autovec/cond/cond_fmax-4.c b/gcc/testsuite/gcc.target/riscv/rvv/autovec/cond/cond_fmax-4.c
index 251066e4884..cba6cdf2a0f 100644
--- a/gcc/testsuite/gcc.target/riscv/rvv/autovec/cond/cond_fmax-4.c
+++ b/gcc/testsuite/gcc.target/riscv/rvv/autovec/cond/cond_fmax-4.c
@@ -1,7 +1,8 @@
/* { dg-do compile } */
-/* { dg-additional-options "-march=rv32gcv_zvfh -mabi=ilp32d --param=riscv-autovec-preference=scalable -fno-vect-cost-model -ffast-math" } */
+/* { dg-additional-options "-march=rv32gcv_zvfh -mabi=ilp32d --param=riscv-autovec-preference=scalable -fno-vect-cost-model -fno-signaling-nans" } */
#include <stdint-gcc.h>
+#include <math.h>
#ifndef FN
#define FN(X) __builtin_fmax##X
@@ -24,11 +25,10 @@
T (FN, TYPE, PRED_TYPE, two, 2)
#define TEST_ALL(T) \
- TEST_TYPE (T, FN (f16), _Float16, int16_t) \
TEST_TYPE (T, FN (f32), float, int32_t) \
TEST_TYPE (T, FN (f64), double, int64_t)
TEST_ALL (DEF_LOOP)
-/* { dg-final { scan-assembler-times {vfmax\.vv\s+v[0-9]+,v[0-9]+,v[0-9]+,v0.t} 9 } } */
+/* { dg-final { scan-assembler-times {vfmax\.vv\s+v[0-9]+,v[0-9]+,v[0-9]+,v0.t} 6 } } */
/* { dg-final { scan-assembler-not {\tvf?merge\.v[vxi]m\t} } } */
diff --git a/gcc/testsuite/gcc.target/riscv/rvv/autovec/cond/cond_fmax_run-1.c b/gcc/testsuite/gcc.target/riscv/rvv/autovec/cond/cond_fmax_run-1.c
index e136f98002e..3dc1fb8bd46 100644
--- a/gcc/testsuite/gcc.target/riscv/rvv/autovec/cond/cond_fmax_run-1.c
+++ b/gcc/testsuite/gcc.target/riscv/rvv/autovec/cond/cond_fmax_run-1.c
@@ -1,7 +1,8 @@
/* { dg-do run { target { riscv_v } } } */
-/* { dg-additional-options "--param=riscv-autovec-preference=scalable -fno-vect-cost-model -ffast-math" } */
+/* { dg-additional-options "--param=riscv-autovec-preference=scalable -fno-vect-cost-model -fno-signaling-nans" } */
#include "cond_fmax-1.c"
+#include <math.h>
#define N 99
diff --git a/gcc/testsuite/gcc.target/riscv/rvv/autovec/cond/cond_fmax_run-2.c b/gcc/testsuite/gcc.target/riscv/rvv/autovec/cond/cond_fmax_run-2.c
index 291cfca14ef..0cf67561c4d 100644
--- a/gcc/testsuite/gcc.target/riscv/rvv/autovec/cond/cond_fmax_run-2.c
+++ b/gcc/testsuite/gcc.target/riscv/rvv/autovec/cond/cond_fmax_run-2.c
@@ -1,7 +1,8 @@
/* { dg-do run { target { riscv_v } } } */
-/* { dg-additional-options "--param=riscv-autovec-preference=scalable -fno-vect-cost-model -ffast-math" } */
+/* { dg-additional-options "--param=riscv-autovec-preference=scalable -fno-vect-cost-model -fno-signaling-nans" } */
#include "cond_fmax-2.c"
+#include <math.h>
#define N 99
diff --git a/gcc/testsuite/gcc.target/riscv/rvv/autovec/cond/cond_fmax_run-3.c b/gcc/testsuite/gcc.target/riscv/rvv/autovec/cond/cond_fmax_run-3.c
index 34f011dadee..df4a5ded974 100644
--- a/gcc/testsuite/gcc.target/riscv/rvv/autovec/cond/cond_fmax_run-3.c
+++ b/gcc/testsuite/gcc.target/riscv/rvv/autovec/cond/cond_fmax_run-3.c
@@ -1,7 +1,8 @@
/* { dg-do run { target { riscv_v } } } */
-/* { dg-additional-options "--param=riscv-autovec-preference=scalable -fno-vect-cost-model -ffast-math" } */
+/* { dg-additional-options "--param=riscv-autovec-preference=scalable -fno-vect-cost-model -fno-signaling-nans" } */
#include "cond_fmax-3.c"
+#include <math.h>
#define N 99
diff --git a/gcc/testsuite/gcc.target/riscv/rvv/autovec/cond/cond_fmax_run-4.c b/gcc/testsuite/gcc.target/riscv/rvv/autovec/cond/cond_fmax_run-4.c
index 9986f8d24fe..1b949517637 100644
--- a/gcc/testsuite/gcc.target/riscv/rvv/autovec/cond/cond_fmax_run-4.c
+++ b/gcc/testsuite/gcc.target/riscv/rvv/autovec/cond/cond_fmax_run-4.c
@@ -1,7 +1,8 @@
/* { dg-do run { target { riscv_v } } } */
-/* { dg-additional-options "--param=riscv-autovec-preference=scalable -fno-vect-cost-model -ffast-math" } */
+/* { dg-additional-options "--param=riscv-autovec-preference=scalable -fno-vect-cost-model -fno-signaling-nans" } */
#include "cond_fmax-4.c"
+#include <math.h>
#define N 99
diff --git a/gcc/testsuite/gcc.target/riscv/rvv/autovec/cond/cond_fmax_zvfh-1.c b/gcc/testsuite/gcc.target/riscv/rvv/autovec/cond/cond_fmax_zvfh-1.c
new file mode 100644
index 00000000000..c6929a7c101
--- /dev/null
+++ b/gcc/testsuite/gcc.target/riscv/rvv/autovec/cond/cond_fmax_zvfh-1.c
@@ -0,0 +1,33 @@
+/* { dg-do compile } */
+/* { dg-additional-options "-march=rv32gcv_zvfh -mabi=ilp32d --param=riscv-autovec-preference=scalable -fno-vect-cost-model -fno-signaling-nans" } */
+
+#include <stdint-gcc.h>
+#include <math.h>
+
+#ifndef FN
+#define FN(X) __builtin_fmax##X
+#endif
+
+#define DEF_LOOP(FN, TYPE, PRED_TYPE, NAME, CONST) \
+ void __attribute__ ((noipa)) \
+ test_##TYPE##_##NAME (TYPE *__restrict x, \
+ TYPE *__restrict y, \
+ PRED_TYPE *__restrict pred, \
+ int n) \
+ { \
+ for (int i = 0; i < n; ++i) \
+ x[i] = pred[i] != 1 ? FN (y[i], CONST) : y[i]; \
+ }
+
+#define TEST_TYPE(T, FN, TYPE, PRED_TYPE) \
+ T (FN, TYPE, PRED_TYPE, zero, 0) \
+ T (FN, TYPE, PRED_TYPE, one, 1) \
+ T (FN, TYPE, PRED_TYPE, two, 2)
+
+#define TEST_ALL(T) \
+ TEST_TYPE (T, FN (f16), _Float16, int16_t)
+
+TEST_ALL (DEF_LOOP)
+
+/* { dg-final { scan-assembler-times {vfmax\.vv\s+v[0-9]+,v[0-9]+,v[0-9]+,v0.t} 3 } } */
+/* { dg-final { scan-assembler-not {\tvf?merge\.v[vxi]m\t} } } */
diff --git a/gcc/testsuite/gcc.target/riscv/rvv/autovec/cond/cond_fmax_zvfh-2.c b/gcc/testsuite/gcc.target/riscv/rvv/autovec/cond/cond_fmax_zvfh-2.c
new file mode 100644
index 00000000000..b8a184161f9
--- /dev/null
+++ b/gcc/testsuite/gcc.target/riscv/rvv/autovec/cond/cond_fmax_zvfh-2.c
@@ -0,0 +1,33 @@
+/* { dg-do compile } */
+/* { dg-additional-options "-march=rv32gcv_zvfh -mabi=ilp32d --param=riscv-autovec-preference=scalable -fno-vect-cost-model -fno-signaling-nans" } */
+
+#include <stdint-gcc.h>
+#include <math.h>
+
+#ifndef FN
+#define FN(X) __builtin_fmax##X
+#endif
+
+#define DEF_LOOP(FN, TYPE, NAME, CONST) \
+ void __attribute__ ((noipa)) \
+ test_##TYPE##_##NAME (TYPE *__restrict x, \
+ TYPE *__restrict y, \
+ TYPE *__restrict z, \
+ int n) \
+ { \
+ for (int i = 0; i < n; ++i) \
+ x[i] = y[i] < 8 ? FN (z[i], CONST) : y[i]; \
+ }
+
+#define TEST_TYPE(T, FN, TYPE) \
+ T (FN, TYPE, zero, 0) \
+ T (FN, TYPE, one, 1) \
+ T (FN, TYPE, two, 2)
+
+#define TEST_ALL(T) \
+ TEST_TYPE (T, FN (f16), _Float16)
+
+TEST_ALL (DEF_LOOP)
+
+/* { dg-final { scan-assembler-times {vfmax\.vv\s+v[0-9]+,v[0-9]+,v[0-9]+,v0.t} 3 } } */
+/* { dg-final { scan-assembler-not {\tvf?merge\.v[vxi]m\t} } } */
diff --git a/gcc/testsuite/gcc.target/riscv/rvv/autovec/cond/cond_fmax_zvfh-3.c b/gcc/testsuite/gcc.target/riscv/rvv/autovec/cond/cond_fmax_zvfh-3.c
new file mode 100644
index 00000000000..af06f11b99d
--- /dev/null
+++ b/gcc/testsuite/gcc.target/riscv/rvv/autovec/cond/cond_fmax_zvfh-3.c
@@ -0,0 +1,33 @@
+/* { dg-do compile } */
+/* { dg-additional-options "-march=rv32gcv_zvfh -mabi=ilp32d --param=riscv-autovec-preference=scalable -fno-vect-cost-model -fno-signaling-nans" } */
+
+#include <stdint-gcc.h>
+#include <math.h>
+
+#ifndef FN
+#define FN(X) __builtin_fmax##X
+#endif
+
+#define DEF_LOOP(FN, TYPE, PRED_TYPE, NAME, CONST) \
+ void __attribute__ ((noipa)) \
+ test_##TYPE##_##NAME (TYPE *__restrict x, \
+ TYPE *__restrict y, \
+ PRED_TYPE *__restrict pred, \
+ int n) \
+ { \
+ for (int i = 0; i < n; ++i) \
+ x[i] = pred[i] != 1 ? FN (y[i], CONST) : 4; \
+ }
+
+#define TEST_TYPE(T, FN, TYPE, PRED_TYPE) \
+ T (FN, TYPE, PRED_TYPE, zero, 0) \
+ T (FN, TYPE, PRED_TYPE, one, 1) \
+ T (FN, TYPE, PRED_TYPE, two, 2)
+
+#define TEST_ALL(T) \
+ TEST_TYPE (T, FN (f16), _Float16, int16_t)
+
+TEST_ALL (DEF_LOOP)
+
+/* { dg-final { scan-assembler-times {vfmax\.vv\s+v[0-9]+,v[0-9]+,v[0-9]+,v0.t} 3 } } */
+/* { dg-final { scan-assembler-not {\tvf?merge\.v[vxi]m\t} } } */
diff --git a/gcc/testsuite/gcc.target/riscv/rvv/autovec/cond/cond_fmax_zvfh-4.c b/gcc/testsuite/gcc.target/riscv/rvv/autovec/cond/cond_fmax_zvfh-4.c
new file mode 100644
index 00000000000..e6a5a76ca46
--- /dev/null
+++ b/gcc/testsuite/gcc.target/riscv/rvv/autovec/cond/cond_fmax_zvfh-4.c
@@ -0,0 +1,33 @@
+/* { dg-do compile } */
+/* { dg-additional-options "-march=rv32gcv_zvfh -mabi=ilp32d --param=riscv-autovec-preference=scalable -fno-vect-cost-model -fno-signaling-nans" } */
+
+#include <stdint-gcc.h>
+#include <math.h>
+
+#ifndef FN
+#define FN(X) __builtin_fmax##X
+#endif
+
+#define DEF_LOOP(FN, TYPE, PRED_TYPE, NAME, CONST) \
+ void __attribute__ ((noipa)) \
+ test_##TYPE##_##NAME (TYPE *__restrict x, \
+ TYPE *__restrict y, \
+ PRED_TYPE *__restrict pred, \
+ int n) \
+ { \
+ for (int i = 0; i < n; ++i) \
+ x[i] = pred[i] != 1 ? FN (y[i], CONST) : 0; \
+ }
+
+#define TEST_TYPE(T, FN, TYPE, PRED_TYPE) \
+ T (FN, TYPE, PRED_TYPE, zero, 0) \
+ T (FN, TYPE, PRED_TYPE, one, 1) \
+ T (FN, TYPE, PRED_TYPE, two, 2)
+
+#define TEST_ALL(T) \
+ TEST_TYPE (T, FN (f16), _Float16, int16_t)
+
+TEST_ALL (DEF_LOOP)
+
+/* { dg-final { scan-assembler-times {vfmax\.vv\s+v[0-9]+,v[0-9]+,v[0-9]+,v0.t} 3 } } */
+/* { dg-final { scan-assembler-not {\tvf?merge\.v[vxi]m\t} } } */
diff --git a/gcc/testsuite/gcc.target/riscv/rvv/autovec/cond/cond_fmax_zvfh_run-1.c b/gcc/testsuite/gcc.target/riscv/rvv/autovec/cond/cond_fmax_zvfh_run-1.c
new file mode 100644
index 00000000000..1609d2ced7b
--- /dev/null
+++ b/gcc/testsuite/gcc.target/riscv/rvv/autovec/cond/cond_fmax_zvfh_run-1.c
@@ -0,0 +1,33 @@
+/* { dg-do run { target { riscv_zvfh } } } */
+/* { dg-additional-options "--param=riscv-autovec-preference=scalable -fno-vect-cost-model -fno-signaling-nans" } */
+
+#include "cond_fmax_zvfh-1.c"
+#include <math.h>
+
+#define N 99
+
+#define TEST_LOOP(FN, TYPE, PRED_TYPE, NAME, CONST) \
+ { \
+ TYPE x[N], y[N]; \
+ PRED_TYPE pred[N]; \
+ for (int i = 0; i < N; ++i) \
+ { \
+ y[i] = i * i; \
+ pred[i] = i % 3; \
+ } \
+ test_##TYPE##_##NAME (x, y, pred, N); \
+ for (int i = 0; i < N; ++i) \
+ { \
+ TYPE expected = i % 3 != 1 ? FN (y[i], CONST) : y[i]; \
+ if (x[i] != expected) \
+ __builtin_abort (); \
+ asm volatile ("" ::: "memory"); \
+ } \
+ }
+
+int
+main (void)
+{
+ TEST_ALL (TEST_LOOP)
+ return 0;
+}
diff --git a/gcc/testsuite/gcc.target/riscv/rvv/autovec/cond/cond_fmax_zvfh_run-2.c b/gcc/testsuite/gcc.target/riscv/rvv/autovec/cond/cond_fmax_zvfh_run-2.c
new file mode 100644
index 00000000000..6c33858cc40
--- /dev/null
+++ b/gcc/testsuite/gcc.target/riscv/rvv/autovec/cond/cond_fmax_zvfh_run-2.c
@@ -0,0 +1,32 @@
+/* { dg-do run { target { riscv_zvfh } } } */
+/* { dg-additional-options "--param=riscv-autovec-preference=scalable -fno-vect-cost-model -fno-signaling-nans" } */
+
+#include "cond_fmax_zvfh-2.c"
+#include <math.h>
+
+#define N 99
+
+#define TEST_LOOP(FN, TYPE, NAME, CONST) \
+ { \
+ TYPE x[N], y[N], z[N]; \
+ for (int i = 0; i < N; ++i) \
+ { \
+ y[i] = i % 13; \
+ z[i] = i * i; \
+ } \
+ test_##TYPE##_##NAME (x, y, z, N); \
+ for (int i = 0; i < N; ++i) \
+ { \
+ TYPE expected = y[i] < 8 ? FN (z[i], CONST) : y[i]; \
+ if (x[i] != expected) \
+ __builtin_abort (); \
+ asm volatile ("" ::: "memory"); \
+ } \
+ }
+
+int
+main (void)
+{
+ TEST_ALL (TEST_LOOP)
+ return 0;
+}
diff --git a/gcc/testsuite/gcc.target/riscv/rvv/autovec/cond/cond_fmax_zvfh_run-3.c b/gcc/testsuite/gcc.target/riscv/rvv/autovec/cond/cond_fmax_zvfh_run-3.c
new file mode 100644
index 00000000000..6df48c220f3
--- /dev/null
+++ b/gcc/testsuite/gcc.target/riscv/rvv/autovec/cond/cond_fmax_zvfh_run-3.c
@@ -0,0 +1,33 @@
+/* { dg-do run { target { riscv_zvfh } } } */
+/* { dg-additional-options "--param=riscv-autovec-preference=scalable -fno-vect-cost-model -fno-signaling-nans" } */
+
+#include "cond_fmax_zvfh-3.c"
+#include <math.h>
+
+#define N 99
+
+#define TEST_LOOP(FN, TYPE, PRED_TYPE, NAME, CONST) \
+ { \
+ TYPE x[N], y[N]; \
+ PRED_TYPE pred[N]; \
+ for (int i = 0; i < N; ++i) \
+ { \
+ y[i] = i * i; \
+ pred[i] = i % 3; \
+ } \
+ test_##TYPE##_##NAME (x, y, pred, N); \
+ for (int i = 0; i < N; ++i) \
+ { \
+ TYPE expected = i % 3 != 1 ? FN (y[i], CONST) : 4; \
+ if (x[i] != expected) \
+ __builtin_abort (); \
+ asm volatile ("" ::: "memory"); \
+ } \
+ }
+
+int
+main (void)
+{
+ TEST_ALL (TEST_LOOP)
+ return 0;
+}
diff --git a/gcc/testsuite/gcc.target/riscv/rvv/autovec/cond/cond_fmax_zvfh_run-4.c b/gcc/testsuite/gcc.target/riscv/rvv/autovec/cond/cond_fmax_zvfh_run-4.c
new file mode 100644
index 00000000000..9bb1beb1418
--- /dev/null
+++ b/gcc/testsuite/gcc.target/riscv/rvv/autovec/cond/cond_fmax_zvfh_run-4.c
@@ -0,0 +1,33 @@
+/* { dg-do run { target { riscv_zvfh } } } */
+/* { dg-additional-options "--param=riscv-autovec-preference=scalable -fno-vect-cost-model -fno-signaling-nans" } */
+
+#include "cond_fmax_zvfh-4.c"
+#include <math.h>
+
+#define N 99
+
+#define TEST_LOOP(FN, TYPE, PRED_TYPE, NAME, CONST) \
+ { \
+ TYPE x[N], y[N]; \
+ PRED_TYPE pred[N]; \
+ for (int i = 0; i < N; ++i) \
+ { \
+ y[i] = i * i; \
+ pred[i] = i % 3; \
+ } \
+ test_##TYPE##_##NAME (x, y, pred, N); \
+ for (int i = 0; i < N; ++i) \
+ { \
+ TYPE expected = i % 3 != 1 ? FN (y[i], CONST) : 0; \
+ if (x[i] != expected) \
+ __builtin_abort (); \
+ asm volatile ("" ::: "memory"); \
+ } \
+ }
+
+int
+main (void)
+{
+ TEST_ALL (TEST_LOOP)
+ return 0;
+}
diff --git a/gcc/testsuite/gcc.target/riscv/rvv/autovec/cond/cond_fmin-1.c b/gcc/testsuite/gcc.target/riscv/rvv/autovec/cond/cond_fmin-1.c
index 9e3fd290474..2c8fbfb0c9e 100644
--- a/gcc/testsuite/gcc.target/riscv/rvv/autovec/cond/cond_fmin-1.c
+++ b/gcc/testsuite/gcc.target/riscv/rvv/autovec/cond/cond_fmin-1.c
@@ -1,10 +1,11 @@
/* { dg-do compile } */
-/* { dg-additional-options "-march=rv32gcv_zvfh -mabi=ilp32d --param=riscv-autovec-preference=scalable -fno-vect-cost-model -ffast-math" } */
+/* { dg-additional-options "-march=rv32gcv_zvfh -mabi=ilp32d --param=riscv-autovec-preference=scalable -fno-vect-cost-model -fno-signaling-nans" } */
#include <stdint-gcc.h>
+#include <math.h>
#define FN(X) __builtin_fmin##X
#include "cond_fmax-1.c"
-/* { dg-final { scan-assembler-times {vfmin\.vv\s+v[0-9]+,v[0-9]+,v[0-9]+,v0.t} 9 } } */
+/* { dg-final { scan-assembler-times {vfmin\.vv\s+v[0-9]+,v[0-9]+,v[0-9]+,v0.t} 6 } } */
/* { dg-final { scan-assembler-not {\tvf?merge\.v[vxi]m\t} } } */
diff --git a/gcc/testsuite/gcc.target/riscv/rvv/autovec/cond/cond_fmin-2.c b/gcc/testsuite/gcc.target/riscv/rvv/autovec/cond/cond_fmin-2.c
index c48fab461ff..fe0455412ba 100644
--- a/gcc/testsuite/gcc.target/riscv/rvv/autovec/cond/cond_fmin-2.c
+++ b/gcc/testsuite/gcc.target/riscv/rvv/autovec/cond/cond_fmin-2.c
@@ -1,7 +1,8 @@
/* { dg-do compile } */
-/* { dg-additional-options "-march=rv32gcv_zvfh -mabi=ilp32d --param=riscv-autovec-preference=scalable -fno-vect-cost-model -ffast-math" } */
+/* { dg-additional-options "-march=rv32gcv_zvfh -mabi=ilp32d --param=riscv-autovec-preference=scalable -fno-vect-cost-model -fno-signaling-nans" } */
#include <stdint-gcc.h>
+#include <math.h>
#define FN(X) __builtin_fmin##X
#include "cond_fmax-2.c"
diff --git a/gcc/testsuite/gcc.target/riscv/rvv/autovec/cond/cond_fmin-3.c b/gcc/testsuite/gcc.target/riscv/rvv/autovec/cond/cond_fmin-3.c
index e916008ebf0..e76361c94ba 100644
--- a/gcc/testsuite/gcc.target/riscv/rvv/autovec/cond/cond_fmin-3.c
+++ b/gcc/testsuite/gcc.target/riscv/rvv/autovec/cond/cond_fmin-3.c
@@ -1,10 +1,11 @@
/* { dg-do compile } */
-/* { dg-additional-options "-march=rv32gcv_zvfh -mabi=ilp32d --param=riscv-autovec-preference=scalable -fno-vect-cost-model -ffast-math" } */
+/* { dg-additional-options "-march=rv32gcv_zvfh -mabi=ilp32d --param=riscv-autovec-preference=scalable -fno-vect-cost-model -fno-signaling-nans" } */
#include <stdint-gcc.h>
+#include <math.h>
#define FN(X) __builtin_fmin##X
#include "cond_fmax-3.c"
-/* { dg-final { scan-assembler-times {vfmin\.vv\s+v[0-9]+,v[0-9]+,v[0-9]+,v0.t} 9 } } */
+/* { dg-final { scan-assembler-times {vfmin\.vv\s+v[0-9]+,v[0-9]+,v[0-9]+,v0.t} 6 } } */
/* { dg-final { scan-assembler-not {\tvf?merge\.v[vxi]m\t} } } */
diff --git a/gcc/testsuite/gcc.target/riscv/rvv/autovec/cond/cond_fmin-4.c b/gcc/testsuite/gcc.target/riscv/rvv/autovec/cond/cond_fmin-4.c
index 2c2edc2933b..9399a4027ff 100644
--- a/gcc/testsuite/gcc.target/riscv/rvv/autovec/cond/cond_fmin-4.c
+++ b/gcc/testsuite/gcc.target/riscv/rvv/autovec/cond/cond_fmin-4.c
@@ -1,10 +1,11 @@
/* { dg-do compile } */
-/* { dg-additional-options "-march=rv32gcv_zvfh -mabi=ilp32d --param=riscv-autovec-preference=scalable -fno-vect-cost-model -ffast-math" } */
+/* { dg-additional-options "-march=rv32gcv_zvfh -mabi=ilp32d --param=riscv-autovec-preference=scalable -fno-vect-cost-model -fno-signaling-nans" } */
#include <stdint-gcc.h>
+#include <math.h>
#define FN(X) __builtin_fmin##X
#include "cond_fmax-4.c"
-/* { dg-final { scan-assembler-times {vfmin\.vv\s+v[0-9]+,v[0-9]+,v[0-9]+,v0.t} 9 } } */
+/* { dg-final { scan-assembler-times {vfmin\.vv\s+v[0-9]+,v[0-9]+,v[0-9]+,v0.t} 6 } } */
/* { dg-final { scan-assembler-not {\tvf?merge\.v[vxi]m\t} } } */
diff --git a/gcc/testsuite/gcc.target/riscv/rvv/autovec/cond/cond_fmin_run-1.c b/gcc/testsuite/gcc.target/riscv/rvv/autovec/cond/cond_fmin_run-1.c
index 293e1d93307..139f9f77b34 100644
--- a/gcc/testsuite/gcc.target/riscv/rvv/autovec/cond/cond_fmin_run-1.c
+++ b/gcc/testsuite/gcc.target/riscv/rvv/autovec/cond/cond_fmin_run-1.c
@@ -1,5 +1,5 @@
/* { dg-do run { target { riscv_v } } } */
-/* { dg-additional-options "--param=riscv-autovec-preference=scalable -fno-vect-cost-model -ffast-math" } */
+/* { dg-additional-options "--param=riscv-autovec-preference=scalable -fno-vect-cost-model -fno-signaling-nans" } */
#define FN(X) __builtin_fmin##X
#include "cond_fmax_run-1.c"
diff --git a/gcc/testsuite/gcc.target/riscv/rvv/autovec/cond/cond_fmin_run-2.c b/gcc/testsuite/gcc.target/riscv/rvv/autovec/cond/cond_fmin_run-2.c
index 3310bb7989f..e9449b8adcb 100644
--- a/gcc/testsuite/gcc.target/riscv/rvv/autovec/cond/cond_fmin_run-2.c
+++ b/gcc/testsuite/gcc.target/riscv/rvv/autovec/cond/cond_fmin_run-2.c
@@ -1,5 +1,5 @@
/* { dg-do run { target { riscv_v } } } */
-/* { dg-additional-options "--param=riscv-autovec-preference=scalable -fno-vect-cost-model -ffast-math" } */
+/* { dg-additional-options "--param=riscv-autovec-preference=scalable -fno-vect-cost-model -fno-signaling-nans" } */
#define FN(X) __builtin_fmin##X
#include "cond_fmax_run-2.c"
diff --git a/gcc/testsuite/gcc.target/riscv/rvv/autovec/cond/cond_fmin_run-3.c b/gcc/testsuite/gcc.target/riscv/rvv/autovec/cond/cond_fmin_run-3.c
index 6bed341ac87..f70c3440a21 100644
--- a/gcc/testsuite/gcc.target/riscv/rvv/autovec/cond/cond_fmin_run-3.c
+++ b/gcc/testsuite/gcc.target/riscv/rvv/autovec/cond/cond_fmin_run-3.c
@@ -1,5 +1,5 @@
/* { dg-do run { target { riscv_v } } } */
-/* { dg-additional-options "--param=riscv-autovec-preference=scalable -fno-vect-cost-model -ffast-math" } */
+/* { dg-additional-options "--param=riscv-autovec-preference=scalable -fno-vect-cost-model -fno-signaling-nans" } */
#define FN(X) __builtin_fmin##X
#include "cond_fmax_run-3.c"
diff --git a/gcc/testsuite/gcc.target/riscv/rvv/autovec/cond/cond_fmin_run-4.c b/gcc/testsuite/gcc.target/riscv/rvv/autovec/cond/cond_fmin_run-4.c
index 4af0322e73f..fe700a2d5f6 100644
--- a/gcc/testsuite/gcc.target/riscv/rvv/autovec/cond/cond_fmin_run-4.c
+++ b/gcc/testsuite/gcc.target/riscv/rvv/autovec/cond/cond_fmin_run-4.c
@@ -1,5 +1,5 @@
/* { dg-do run { target { riscv_v } } } */
-/* { dg-additional-options "--param=riscv-autovec-preference=scalable -fno-vect-cost-model -ffast-math" } */
+/* { dg-additional-options "--param=riscv-autovec-preference=scalable -fno-vect-cost-model -fno-signaling-nans" } */
#define FN(X) __builtin_fmin##X
#include "cond_fmax_run-4.c"
diff --git a/gcc/testsuite/gcc.target/riscv/rvv/autovec/cond/cond_fmin_zvfh-1.c b/gcc/testsuite/gcc.target/riscv/rvv/autovec/cond/cond_fmin_zvfh-1.c
new file mode 100644
index 00000000000..77bc6e7a77e
--- /dev/null
+++ b/gcc/testsuite/gcc.target/riscv/rvv/autovec/cond/cond_fmin_zvfh-1.c
@@ -0,0 +1,11 @@
+/* { dg-do compile } */
+/* { dg-additional-options "-march=rv32gcv_zvfh -mabi=ilp32d --param=riscv-autovec-preference=scalable -fno-vect-cost-model -fno-signaling-nans" } */
+
+#include <stdint-gcc.h>
+#include <math.h>
+
+#define FN(X) __builtin_fmin##X
+#include "cond_fmax_zvfh-1.c"
+
+/* { dg-final { scan-assembler-times {vfmin\.vv\s+v[0-9]+,v[0-9]+,v[0-9]+,v0.t} 3 } } */
+/* { dg-final { scan-assembler-not {\tvf?merge\.v[vxi]m\t} } } */
diff --git a/gcc/testsuite/gcc.target/riscv/rvv/autovec/cond/cond_fmin_zvfh-2.c b/gcc/testsuite/gcc.target/riscv/rvv/autovec/cond/cond_fmin_zvfh-2.c
new file mode 100644
index 00000000000..8e330afac83
--- /dev/null
+++ b/gcc/testsuite/gcc.target/riscv/rvv/autovec/cond/cond_fmin_zvfh-2.c
@@ -0,0 +1,11 @@
+/* { dg-do compile } */
+/* { dg-additional-options "-march=rv32gcv_zvfh -mabi=ilp32d --param=riscv-autovec-preference=scalable -fno-vect-cost-model -fno-signaling-nans" } */
+
+#include <stdint-gcc.h>
+#include <math.h>
+
+#define FN(X) __builtin_fmin##X
+#include "cond_fmax_zvfh-2.c"
+
+/* { dg-final { scan-assembler-times {vfmin\.vv\s+v[0-9]+,v[0-9]+,v[0-9]+,v0.t} 3 } } */
+/* { dg-final { scan-assembler-not {\tvf?merge\.v[vxi]m\t} } } */
diff --git a/gcc/testsuite/gcc.target/riscv/rvv/autovec/cond/cond_fmin_zvfh-3.c b/gcc/testsuite/gcc.target/riscv/rvv/autovec/cond/cond_fmin_zvfh-3.c
new file mode 100644
index 00000000000..5caeac9b4e1
--- /dev/null
+++ b/gcc/testsuite/gcc.target/riscv/rvv/autovec/cond/cond_fmin_zvfh-3.c
@@ -0,0 +1,11 @@
+/* { dg-do compile } */
+/* { dg-additional-options "-march=rv32gcv_zvfh -mabi=ilp32d --param=riscv-autovec-preference=scalable -fno-vect-cost-model -fno-signaling-nans" } */
+
+#include <stdint-gcc.h>
+#include <math.h>
+
+#define FN(X) __builtin_fmin##X
+#include "cond_fmax_zvfh-3.c"
+
+/* { dg-final { scan-assembler-times {vfmin\.vv\s+v[0-9]+,v[0-9]+,v[0-9]+,v0.t} 3 } } */
+/* { dg-final { scan-assembler-not {\tvf?merge\.v[vxi]m\t} } } */
diff --git a/gcc/testsuite/gcc.target/riscv/rvv/autovec/cond/cond_fmin_zvfh-4.c b/gcc/testsuite/gcc.target/riscv/rvv/autovec/cond/cond_fmin_zvfh-4.c
new file mode 100644
index 00000000000..8281dc688e7
--- /dev/null
+++ b/gcc/testsuite/gcc.target/riscv/rvv/autovec/cond/cond_fmin_zvfh-4.c
@@ -0,0 +1,11 @@
+/* { dg-do compile } */
+/* { dg-additional-options "-march=rv32gcv_zvfh -mabi=ilp32d --param=riscv-autovec-preference=scalable -fno-vect-cost-model -fno-signaling-nans" } */
+
+#include <stdint-gcc.h>
+#include <math.h>
+
+#define FN(X) __builtin_fmin##X
+#include "cond_fmax_zvfh-4.c"
+
+/* { dg-final { scan-assembler-times {vfmin\.vv\s+v[0-9]+,v[0-9]+,v[0-9]+,v0.t} 3 } } */
+/* { dg-final { scan-assembler-not {\tvf?merge\.v[vxi]m\t} } } */
diff --git a/gcc/testsuite/gcc.target/riscv/rvv/autovec/cond/cond_fmin_zvfh_run-1.c b/gcc/testsuite/gcc.target/riscv/rvv/autovec/cond/cond_fmin_zvfh_run-1.c
new file mode 100644
index 00000000000..b334f4d6bea
--- /dev/null
+++ b/gcc/testsuite/gcc.target/riscv/rvv/autovec/cond/cond_fmin_zvfh_run-1.c
@@ -0,0 +1,5 @@
+/* { dg-do run { target { riscv_zvfh } } } */
+/* { dg-additional-options "--param=riscv-autovec-preference=scalable -fno-vect-cost-model -fno-signaling-nans" } */
+
+#define FN(X) __builtin_fmin##X
+#include "cond_fmax_zvfh_run-1.c"
diff --git a/gcc/testsuite/gcc.target/riscv/rvv/autovec/cond/cond_fmin_zvfh_run-2.c b/gcc/testsuite/gcc.target/riscv/rvv/autovec/cond/cond_fmin_zvfh_run-2.c
new file mode 100644
index 00000000000..873f413c6b7
--- /dev/null
+++ b/gcc/testsuite/gcc.target/riscv/rvv/autovec/cond/cond_fmin_zvfh_run-2.c
@@ -0,0 +1,5 @@
+/* { dg-do run { target { riscv_zvfh } } } */
+/* { dg-additional-options "--param=riscv-autovec-preference=scalable -fno-vect-cost-model -fno-signaling-nans" } */
+
+#define FN(X) __builtin_fmin##X
+#include "cond_fmax_zvfh_run-2.c"
diff --git a/gcc/testsuite/gcc.target/riscv/rvv/autovec/cond/cond_fmin_zvfh_run-3.c b/gcc/testsuite/gcc.target/riscv/rvv/autovec/cond/cond_fmin_zvfh_run-3.c
new file mode 100644
index 00000000000..94be087fb6e
--- /dev/null
+++ b/gcc/testsuite/gcc.target/riscv/rvv/autovec/cond/cond_fmin_zvfh_run-3.c
@@ -0,0 +1,5 @@
+/* { dg-do run { target { riscv_zvfh } } } */
+/* { dg-additional-options "--param=riscv-autovec-preference=scalable -fno-vect-cost-model -fno-signaling-nans" } */
+
+#define FN(X) __builtin_fmin##X
+#include "cond_fmax_zvfh_run-3.c"
diff --git a/gcc/testsuite/gcc.target/riscv/rvv/autovec/cond/cond_fmin_zvfh_run-4.c b/gcc/testsuite/gcc.target/riscv/rvv/autovec/cond/cond_fmin_zvfh_run-4.c
new file mode 100644
index 00000000000..8a144e85afa
--- /dev/null
+++ b/gcc/testsuite/gcc.target/riscv/rvv/autovec/cond/cond_fmin_zvfh_run-4.c
@@ -0,0 +1,5 @@
+/* { dg-do run { target { riscv_zvfh } } } */
+/* { dg-additional-options "--param=riscv-autovec-preference=scalable -fno-vect-cost-model -fno-signaling-nans" } */
+
+#define FN(X) __builtin_fmin##X
+#include "cond_fmax_zvfh_run-4.c"
diff --git a/gcc/testsuite/gcc.target/riscv/rvv/autovec/reduc/reduc-10.c b/gcc/testsuite/gcc.target/riscv/rvv/autovec/reduc/reduc-10.c
new file mode 100644
index 00000000000..be339bdd550
--- /dev/null
+++ b/gcc/testsuite/gcc.target/riscv/rvv/autovec/reduc/reduc-10.c
@@ -0,0 +1,26 @@
+/* { dg-do compile } */
+/* { dg-additional-options "-march=rv32gcv_zvfh -mabi=ilp32d --param=riscv-autovec-preference=scalable --param vect-epilogues-nomask=0 -fno-signaling-nans" } */
+
+#include <stdint-gcc.h>
+
+#define DEF_REDUC_FMAXMIN(TYPE, NAME, MAXMIN_OP) \
+ TYPE __attribute__ ((noinline, noclone)) \
+ reduc_##NAME##_##TYPE (TYPE *a, int n) \
+ { \
+ TYPE r = -0.0; \
+ for (int i = 0; i < n; ++i) \
+ r = MAXMIN_OP (r, a[i]); \
+ return r; \
+ }
+
+#define TEST_FMAXMIN(T) \
+ T (float, max, __builtin_fmaxf) \
+ T (double, max, __builtin_fmax) \
+ T (float, min, __builtin_fminf) \
+ T (double, min, __builtin_fmin)
+
+
+TEST_FMAXMIN (DEF_REDUC_FMAXMIN)
+
+/* { dg-final { scan-assembler-times {vfredmax\.vs\s+v[0-9]+,\s*v[0-9]+,\s*v[0-9]+} 2 } } */
+/* { dg-final { scan-assembler-times {vfredmin\.vs\s+v[0-9]+,\s*v[0-9]+,\s*v[0-9]+} 2 } } */
diff --git a/gcc/testsuite/gcc.target/riscv/rvv/autovec/reduc/reduc_run-10.c b/gcc/testsuite/gcc.target/riscv/rvv/autovec/reduc/reduc_run-10.c
new file mode 100644
index 00000000000..6dc372f5fb6
--- /dev/null
+++ b/gcc/testsuite/gcc.target/riscv/rvv/autovec/reduc/reduc_run-10.c
@@ -0,0 +1,41 @@
+/* { dg-do run { target { riscv_v } } } */
+/* { dg-additional-options "--param=riscv-autovec-preference=scalable -fno-signaling-nans" } */
+
+#include <math.h>
+
+#include "reduc-10.c"
+
+#define NUM_ELEMS(TYPE) (73 + sizeof (TYPE))
+
+#define INIT_VECTOR(TYPE) \
+ TYPE a[NUM_ELEMS (TYPE) + 1]; \
+ for (int i = 0; i < NUM_ELEMS (TYPE) + 1; i++) \
+ { \
+ a[i] = ((i * 2) * (i & 1 ? 1 : -1) | 3); \
+ asm volatile ("" ::: "memory"); \
+ } \
+ a[0] = -0.0; \
+ a[1] = nan ("0.0"); \
+ a[2] = nan ("1.0"); \
+ a[3] = 0.0; \
+ a[4] = -INFINITY; \
+ a[5] = INFINITY; \
+
+#define TEST_REDUC_FMAXMIN(TYPE, NAME, MAXMIN_OP) \
+ { \
+ INIT_VECTOR (TYPE); \
+ TYPE r1 = reduc_##NAME##_##TYPE (a, NUM_ELEMS (TYPE)); \
+ volatile TYPE r2 = -0.0; \
+ for (int i = 0; i < NUM_ELEMS (TYPE); ++i) \
+ r2 = MAXMIN_OP (r2, a[i]); \
+ if (r1 != r2) \
+ __builtin_abort (); \
+ }
+
+__attribute__ ((optimize ("1")))
+int main ()
+{
+ TEST_FMAXMIN (TEST_REDUC_FMAXMIN)
+
+ return 0;
+}
diff --git a/gcc/testsuite/gcc.target/riscv/rvv/autovec/reduc/reduc_zvfh-10.c b/gcc/testsuite/gcc.target/riscv/rvv/autovec/reduc/reduc_zvfh-10.c
new file mode 100644
index 00000000000..0651e3177b7
--- /dev/null
+++ b/gcc/testsuite/gcc.target/riscv/rvv/autovec/reduc/reduc_zvfh-10.c
@@ -0,0 +1,24 @@
+/* { dg-do compile } */
+/* { dg-additional-options "-march=rv32gcv_zvfh -mabi=ilp32d --param=riscv-autovec-preference=scalable --param vect-epilogues-nomask=0 -fno-signaling-nans" } */
+
+#include <stdint-gcc.h>
+
+#define DEF_REDUC_FMAXMIN(TYPE, NAME, MAXMIN_OP) \
+ TYPE __attribute__ ((noinline, noclone)) \
+ reduc_##NAME##_##TYPE (TYPE *a, int n) \
+ { \
+ TYPE r = -0.0; \
+ for (int i = 0; i < n; ++i) \
+ r = MAXMIN_OP (r, a[i]); \
+ return r; \
+ }
+
+#define TEST_FMAXMIN(T) \
+ T (_Float16, max, __builtin_fmaxf16) \
+ T (_Float16, min, __builtin_fminf16) \
+
+
+TEST_FMAXMIN (DEF_REDUC_FMAXMIN)
+
+/* { dg-final { scan-assembler-times {vfredmax\.vs\s+v[0-9]+,\s*v[0-9]+,\s*v[0-9]+} 1 } } */
+/* { dg-final { scan-assembler-times {vfredmin\.vs\s+v[0-9]+,\s*v[0-9]+,\s*v[0-9]+} 1 } } */
diff --git a/gcc/testsuite/gcc.target/riscv/rvv/autovec/reduc/reduc_zvfh_run-10.c b/gcc/testsuite/gcc.target/riscv/rvv/autovec/reduc/reduc_zvfh_run-10.c
new file mode 100644
index 00000000000..2b8bcdfe8fa
--- /dev/null
+++ b/gcc/testsuite/gcc.target/riscv/rvv/autovec/reduc/reduc_zvfh_run-10.c
@@ -0,0 +1,41 @@
+/* { dg-do run { target { riscv_zvfh } } } */
+/* { dg-additional-options "--param=riscv-autovec-preference=scalable -fno-signaling-nans" } */
+
+#include <math.h>
+
+#include "reduc_zvfh-10.c"
+
+#define NUM_ELEMS(TYPE) (73 + sizeof (TYPE))
+
+#define INIT_VECTOR(TYPE) \
+ TYPE a[NUM_ELEMS (TYPE) + 1]; \
+ for (int i = 0; i < NUM_ELEMS (TYPE) + 1; i++) \
+ { \
+ a[i] = ((i * 2) * (i & 1 ? 1 : -1) | 3); \
+ asm volatile ("" ::: "memory"); \
+ } \
+ a[0] = -0.0; \
+ a[1] = nan ("0.0"); \
+ a[2] = nan ("1.0"); \
+ a[3] = 0.0; \
+ a[4] = -INFINITY; \
+ a[5] = INFINITY; \
+
+#define TEST_REDUC_FMAXMIN(TYPE, NAME, MAXMIN_OP) \
+ { \
+ INIT_VECTOR (TYPE); \
+ TYPE r1 = reduc_##NAME##_##TYPE (a, NUM_ELEMS (TYPE)); \
+ volatile TYPE r2 = -0.0; \
+ for (int i = 0; i < NUM_ELEMS (TYPE); ++i) \
+ r2 = MAXMIN_OP (r2, a[i]); \
+ if (r1 != r2) \
+ __builtin_abort (); \
+ }
+
+__attribute__ ((optimize ("1")))
+int main ()
+{
+ TEST_FMAXMIN (TEST_REDUC_FMAXMIN)
+
+ return 0;
+}
--
2.41.0
^ permalink raw reply [flat|nested] 5+ messages in thread
end of thread, other threads:[~2023-10-31 11:51 UTC | newest]
Thread overview: 5+ messages (download: mbox.gz / follow: Atom feed)
-- links below jump to the message on this page --
2023-10-30 16:08 [PATCH] RISC-V: Add vector fmin/fmax expanders Robin Dapp
2023-10-30 18:31 ` Joseph Myers
2023-10-30 19:26 ` Robin Dapp
2023-10-31 1:19 ` juzhe.zhong
2023-10-31 11:51 ` Robin Dapp
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).