public inbox for gcc-cvs@sourceware.org
help / color / mirror / Atom feed
* [gcc/devel/omp/gcc-12] amdgcn: Add instruction patterns for conditional min/max operations
@ 2023-03-06 15:01 Paul-Antoine Arras
0 siblings, 0 replies; only message in thread
From: Paul-Antoine Arras @ 2023-03-06 15:01 UTC (permalink / raw)
To: gcc-cvs
https://gcc.gnu.org/g:745775eb2c47dad4f2ce30f5559ae39a9b73f184
commit 745775eb2c47dad4f2ce30f5559ae39a9b73f184
Author: Paul-Antoine Arras <pa@codesourcery.com>
Date: Wed Mar 1 17:20:21 2023 +0100
amdgcn: Add instruction patterns for conditional min/max operations
gcc/ChangeLog:
* config/gcn/gcn-valu.md (<expander><mode>3_exec): Add patterns for
{s|u}{max|min} in QI, HI and DI modes.
(<expander><mode>3): Add pattern for {s|u}{max|min} in DI mode.
(cond_<fexpander><mode>): Add pattern for cond_f{max|min}.
(cond_<expander><mode>): Add pattern for cond_{s|u}{max|min}.
* config/gcn/gcn.cc (gcn_spill_class): Allow the exec register to be
saved in SGPRs.
gcc/testsuite/ChangeLog:
* gcc.target/gcn/cond_fmaxnm_1.c: New test.
* gcc.target/gcn/cond_fmaxnm_1_run.c: New test.
* gcc.target/gcn/cond_fmaxnm_2.c: New test.
* gcc.target/gcn/cond_fmaxnm_2_run.c: New test.
* gcc.target/gcn/cond_fmaxnm_3.c: New test.
* gcc.target/gcn/cond_fmaxnm_3_run.c: New test.
* gcc.target/gcn/cond_fmaxnm_4.c: New test.
* gcc.target/gcn/cond_fmaxnm_4_run.c: New test.
* gcc.target/gcn/cond_fmaxnm_5.c: New test.
* gcc.target/gcn/cond_fmaxnm_5_run.c: New test.
* gcc.target/gcn/cond_fmaxnm_6.c: New test.
* gcc.target/gcn/cond_fmaxnm_6_run.c: New test.
* gcc.target/gcn/cond_fmaxnm_7.c: New test.
* gcc.target/gcn/cond_fmaxnm_7_run.c: New test.
* gcc.target/gcn/cond_fmaxnm_8.c: New test.
* gcc.target/gcn/cond_fmaxnm_8_run.c: New test.
* gcc.target/gcn/cond_fminnm_1.c: New test.
* gcc.target/gcn/cond_fminnm_1_run.c: New test.
* gcc.target/gcn/cond_fminnm_2.c: New test.
* gcc.target/gcn/cond_fminnm_2_run.c: New test.
* gcc.target/gcn/cond_fminnm_3.c: New test.
* gcc.target/gcn/cond_fminnm_3_run.c: New test.
* gcc.target/gcn/cond_fminnm_4.c: New test.
* gcc.target/gcn/cond_fminnm_4_run.c: New test.
* gcc.target/gcn/cond_fminnm_5.c: New test.
* gcc.target/gcn/cond_fminnm_5_run.c: New test.
* gcc.target/gcn/cond_fminnm_6.c: New test.
* gcc.target/gcn/cond_fminnm_6_run.c: New test.
* gcc.target/gcn/cond_fminnm_7.c: New test.
* gcc.target/gcn/cond_fminnm_7_run.c: New test.
* gcc.target/gcn/cond_fminnm_8.c: New test.
* gcc.target/gcn/cond_fminnm_8_run.c: New test.
* gcc.target/gcn/cond_smax_1.c: New test.
* gcc.target/gcn/cond_smax_1_run.c: New test.
* gcc.target/gcn/cond_smin_1.c: New test.
* gcc.target/gcn/cond_smin_1_run.c: New test.
* gcc.target/gcn/cond_umax_1.c: New test.
* gcc.target/gcn/cond_umax_1_run.c: New test.
* gcc.target/gcn/cond_umin_1.c: New test.
* gcc.target/gcn/cond_umin_1_run.c: New test.
* gcc.target/gcn/smax_1.c: New test.
* gcc.target/gcn/smax_1_run.c: New test.
* gcc.target/gcn/smin_1.c: New test.
* gcc.target/gcn/smin_1_run.c: New test.
* gcc.target/gcn/umax_1.c: New test.
* gcc.target/gcn/umax_1_run.c: New test.
* gcc.target/gcn/umin_1.c: New test.
* gcc.target/gcn/umin_1_run.c: New test.
(cherry picked from commit 553ff2524f412be4e02e2ffb1a0a3dc3e2280742)
Diff:
---
gcc/ChangeLog.omp | 13 +++
gcc/config/gcn/gcn-valu.md | 137 ++++++++++++++++++++++-
gcc/config/gcn/gcn.cc | 2 +-
gcc/testsuite/ChangeLog.omp | 54 +++++++++
gcc/testsuite/gcc.target/gcn/cond_fmaxnm_1.c | 33 ++++++
gcc/testsuite/gcc.target/gcn/cond_fmaxnm_1_run.c | 32 ++++++
gcc/testsuite/gcc.target/gcn/cond_fmaxnm_2.c | 33 ++++++
gcc/testsuite/gcc.target/gcn/cond_fmaxnm_2_run.c | 31 +++++
gcc/testsuite/gcc.target/gcn/cond_fmaxnm_3.c | 35 ++++++
gcc/testsuite/gcc.target/gcn/cond_fmaxnm_3_run.c | 32 ++++++
gcc/testsuite/gcc.target/gcn/cond_fmaxnm_4.c | 35 ++++++
gcc/testsuite/gcc.target/gcn/cond_fmaxnm_4_run.c | 32 ++++++
gcc/testsuite/gcc.target/gcn/cond_fmaxnm_5.c | 9 ++
gcc/testsuite/gcc.target/gcn/cond_fmaxnm_5_run.c | 4 +
gcc/testsuite/gcc.target/gcn/cond_fmaxnm_6.c | 9 ++
gcc/testsuite/gcc.target/gcn/cond_fmaxnm_6_run.c | 4 +
gcc/testsuite/gcc.target/gcn/cond_fmaxnm_7.c | 9 ++
gcc/testsuite/gcc.target/gcn/cond_fmaxnm_7_run.c | 4 +
gcc/testsuite/gcc.target/gcn/cond_fmaxnm_8.c | 9 ++
gcc/testsuite/gcc.target/gcn/cond_fmaxnm_8_run.c | 4 +
gcc/testsuite/gcc.target/gcn/cond_fminnm_1.c | 10 ++
gcc/testsuite/gcc.target/gcn/cond_fminnm_1_run.c | 5 +
gcc/testsuite/gcc.target/gcn/cond_fminnm_2.c | 10 ++
gcc/testsuite/gcc.target/gcn/cond_fminnm_2_run.c | 5 +
gcc/testsuite/gcc.target/gcn/cond_fminnm_3.c | 12 ++
gcc/testsuite/gcc.target/gcn/cond_fminnm_3_run.c | 5 +
gcc/testsuite/gcc.target/gcn/cond_fminnm_4.c | 12 ++
gcc/testsuite/gcc.target/gcn/cond_fminnm_4_run.c | 5 +
gcc/testsuite/gcc.target/gcn/cond_fminnm_5.c | 10 ++
gcc/testsuite/gcc.target/gcn/cond_fminnm_5_run.c | 4 +
gcc/testsuite/gcc.target/gcn/cond_fminnm_6.c | 10 ++
gcc/testsuite/gcc.target/gcn/cond_fminnm_6_run.c | 4 +
gcc/testsuite/gcc.target/gcn/cond_fminnm_7.c | 10 ++
gcc/testsuite/gcc.target/gcn/cond_fminnm_7_run.c | 4 +
gcc/testsuite/gcc.target/gcn/cond_fminnm_8.c | 10 ++
gcc/testsuite/gcc.target/gcn/cond_fminnm_8_run.c | 4 +
gcc/testsuite/gcc.target/gcn/cond_smax_1.c | 57 ++++++++++
gcc/testsuite/gcc.target/gcn/cond_smax_1_run.c | 53 +++++++++
gcc/testsuite/gcc.target/gcn/cond_smin_1.c | 57 ++++++++++
gcc/testsuite/gcc.target/gcn/cond_smin_1_run.c | 53 +++++++++
gcc/testsuite/gcc.target/gcn/cond_umax_1.c | 54 +++++++++
gcc/testsuite/gcc.target/gcn/cond_umax_1_run.c | 53 +++++++++
gcc/testsuite/gcc.target/gcn/cond_umin_1.c | 53 +++++++++
gcc/testsuite/gcc.target/gcn/cond_umin_1_run.c | 53 +++++++++
gcc/testsuite/gcc.target/gcn/smax_1.c | 47 ++++++++
gcc/testsuite/gcc.target/gcn/smax_1_run.c | 48 ++++++++
gcc/testsuite/gcc.target/gcn/smin_1.c | 47 ++++++++
gcc/testsuite/gcc.target/gcn/smin_1_run.c | 48 ++++++++
gcc/testsuite/gcc.target/gcn/umax_1.c | 45 ++++++++
gcc/testsuite/gcc.target/gcn/umax_1_run.c | 48 ++++++++
gcc/testsuite/gcc.target/gcn/umin_1.c | 45 ++++++++
gcc/testsuite/gcc.target/gcn/umin_1_run.c | 48 ++++++++
52 files changed, 1448 insertions(+), 2 deletions(-)
diff --git a/gcc/ChangeLog.omp b/gcc/ChangeLog.omp
index be8dfa8f1b9..832679887d0 100644
--- a/gcc/ChangeLog.omp
+++ b/gcc/ChangeLog.omp
@@ -1,3 +1,16 @@
+2023-03-06 Paul-Antoine Arras <pa@codesourcery.com>
+
+ Backported from master:
+ 2023-03-06 Paul-Antoine Arras <pa@codesourcery.com>
+
+ * config/gcn/gcn-valu.md (<expander><mode>3_exec): Add patterns for
+ {s|u}{max|min} in QI, HI and DI modes.
+ (<expander><mode>3): Add pattern for {s|u}{max|min} in DI mode.
+ (cond_<fexpander><mode>): Add pattern for cond_f{max|min}.
+ (cond_<expander><mode>): Add pattern for cond_{s|u}{max|min}.
+ * config/gcn/gcn.cc (gcn_spill_class): Allow the exec register to be
+ saved in SGPRs.
+
2023-03-01 Tobias Burnus <tobias@codesourcery.com>
Backported from master:
diff --git a/gcc/config/gcn/gcn-valu.md b/gcc/config/gcn/gcn-valu.md
index 079bb09bd68..35c108755cc 100644
--- a/gcc/config/gcn/gcn-valu.md
+++ b/gcc/config/gcn/gcn-valu.md
@@ -2361,6 +2361,34 @@
DONE;
})
+(define_expand "<expander><mode>3_exec"
+ [(set (match_operand:V_QIHI 0 "gcn_valu_dst_operand")
+ (vec_merge:V_QIHI
+ (minmaxop:V_QIHI
+ (match_operand:V_QIHI 1 "gcn_valu_src0_operand")
+ (match_operand:V_QIHI 2 "gcn_valu_src1com_operand"))
+ (match_operand:V_QIHI 3 "gcn_register_or_unspec_operand" "U0")
+ (match_operand:DI 4 "gcn_exec_reg_operand" "e")))]
+ ""
+ {
+ enum {smin, umin, smax, umax};
+ bool unsignedp = (<code> == umax || <code> == umin);
+ rtx insi1 = gen_reg_rtx (<VnSI>mode);
+ rtx insi2 = gen_reg_rtx (<VnSI>mode);
+ rtx outsi = gen_reg_rtx (<VnSI>mode);
+ rtx out = operands[0];
+ rtx exec = operands[4];
+ rtx tmp = gen_reg_rtx (<MODE>mode);
+
+ convert_move (insi1, operands[1], unsignedp);
+ convert_move (insi2, operands[2], unsignedp);
+ emit_insn (gen_<code><vnsi>3_exec (outsi, insi1, insi2,
+ gcn_gen_undef(<VnSI>mode), exec));
+ convert_move (tmp, outsi, unsignedp);
+ emit_insn (gen_mov<mode>_exec (out, tmp, operands[3], exec));
+ DONE;
+ })
+
(define_insn "<expander><vnsi>3<exec>"
[(set (match_operand:V_SI 0 "gcn_valu_dst_operand" "= v,RD")
(minmaxop:V_SI
@@ -2373,6 +2401,71 @@
[(set_attr "type" "vop2,ds")
(set_attr "length" "8,8")])
+(define_insn_and_split "<expander><mode>3"
+ [(set (match_operand:V_DI 0 "register_operand" "=v")
+ (minmaxop:V_DI
+ (match_operand:V_DI 1 "gcn_alu_operand" " v")
+ (match_operand:V_DI 2 "gcn_alu_operand" " v")))
+ (clobber (reg:DI VCC_REG))]
+ ""
+ "#"
+ "reload_completed"
+ [(const_int 0)]
+ {
+ rtx out = operands[0];
+ rtx vcc = gen_rtx_REG (DImode, VCC_REG);
+
+ enum {smin, smax, umin, umax};
+ bool minp = (<code> == smin || <code> == umin);
+ if (<code> == smin || <code> == smax)
+ emit_insn (gen_vec_cmp<mode>di (vcc, minp ? gen_rtx_LT (VOIDmode, 0, 0) :
+ gen_rtx_GT (VOIDmode, 0, 0), operands[1],
+ operands[2]));
+ else
+ emit_insn (gen_vec_cmp<mode>di (vcc, minp ? gen_rtx_LTU (VOIDmode, 0, 0) :
+ gen_rtx_GTU (VOIDmode, 0, 0), operands[1],
+ operands[2]));
+ emit_insn (gen_vcond_mask_<mode>di (out, operands[1], operands[2], vcc));
+ }
+ [(set_attr "type" "mult")])
+
+(define_insn_and_split "<expander><mode>3_exec"
+ [(set (match_operand:V_DI 0 "register_operand" "= v")
+ (vec_merge:V_DI
+ (minmaxop:V_DI
+ (match_operand:V_DI 1 "gcn_alu_operand" " v")
+ (match_operand:V_DI 2 "gcn_alu_operand" " v"))
+ (match_operand:V_DI 3 "gcn_register_or_unspec_operand" " U0")
+ (match_operand:DI 4 "gcn_exec_reg_operand" "+e")))
+ (clobber (match_scratch:<VnDI> 5 "= &v"))
+ (clobber (reg:DI VCC_REG))]
+ ""
+ "#"
+ "reload_completed"
+ [(const_int 0)]
+ {
+ rtx out = operands[0];
+ rtx vcc = gen_rtx_REG (DImode, VCC_REG);
+ rtx exec = operands[4];
+ rtx tmp = operands[5];
+
+ enum {smin, smax, umin, umax};
+ bool minp = (<code> == smin || <code> == umin);
+ if (<code> == smin || <code> == smax)
+ emit_insn (gen_vec_cmp<mode>di_exec (vcc,
+ minp ? gen_rtx_LT (VOIDmode, 0, 0) :
+ gen_rtx_GT (VOIDmode, 0, 0),
+ operands[1], operands[2], exec));
+ else
+ emit_insn (gen_vec_cmp<mode>di_exec (vcc,
+ minp ? gen_rtx_LTU (VOIDmode, 0, 0) :
+ gen_rtx_GTU (VOIDmode, 0, 0),
+ operands[1], operands[2], exec));
+ emit_insn (gen_vcond_mask_<mode>di (tmp, operands[1], operands[2], vcc));
+ emit_insn (gen_mov<mode>_exec (out, tmp, operands[3], exec));
+ }
+ [(set_attr "type" "mult")])
+
;; }}}
;; {{{ Int unops
@@ -3471,7 +3564,49 @@
DONE;
})
-;; TODO smin umin smax umax
+(define_code_iterator cond_fminmaxop [smin smax])
+
+(define_expand "cond_<fexpander><mode>"
+ [(match_operand:V_FP 0 "register_operand")
+ (match_operand:DI 1 "register_operand")
+ (cond_fminmaxop:V_FP
+ (match_operand:V_FP 2 "gcn_alu_operand")
+ (match_operand:V_FP 3 "gcn_alu_operand"))
+ (match_operand:V_FP 4 "register_operand")]
+ ""
+ {
+ operands[1] = force_reg (DImode, operands[1]);
+ operands[2] = force_reg (<MODE>mode, operands[2]);
+
+ emit_insn (gen_<fexpander><mode>3_exec (operands[0], operands[2],
+ operands[3], operands[4],
+ operands[1]));
+ DONE;
+ })
+
+(define_code_iterator cond_minmaxop [smin smax umin umax])
+
+(define_expand "cond_<expander><mode>"
+ [(match_operand:V_INT 0 "register_operand")
+ (match_operand:DI 1 "register_operand")
+ (cond_minmaxop:V_INT
+ (match_operand:V_INT 2 "gcn_alu_operand")
+ (match_operand:V_INT 3 "gcn_alu_operand"))
+ (match_operand:V_INT 4 "register_operand")]
+ ""
+ {
+ operands[1] = force_reg (DImode, operands[1]);
+ operands[2] = force_reg (<MODE>mode, operands[2]);
+ rtx tmp = gen_reg_rtx (<MODE>mode);
+
+ emit_insn (gen_<expander><mode>3_exec (tmp, operands[2], operands[3],
+ gcn_gen_undef(<MODE>mode),
+ operands[1]));
+ emit_insn (gen_vcond_mask_<mode>di (operands[0], tmp, operands[4],
+ operands[1]));
+ DONE;
+ })
+
(define_code_iterator cond_bitop [and ior xor])
(define_expand "cond_<expander><mode>"
diff --git a/gcc/config/gcn/gcn.cc b/gcc/config/gcn/gcn.cc
index 8e487b94e95..a0c55fb4d75 100644
--- a/gcc/config/gcn/gcn.cc
+++ b/gcc/config/gcn/gcn.cc
@@ -809,7 +809,7 @@ static reg_class_t
gcn_spill_class (reg_class_t c, machine_mode /*mode */ )
{
if (reg_classes_intersect_p (ALL_CONDITIONAL_REGS, c)
- || c == VCC_CONDITIONAL_REG)
+ || c == VCC_CONDITIONAL_REG || c == EXEC_MASK_REG)
return SGPR_REGS;
else
return NO_REGS;
diff --git a/gcc/testsuite/ChangeLog.omp b/gcc/testsuite/ChangeLog.omp
index d4217ccc71f..860ecdc780b 100644
--- a/gcc/testsuite/ChangeLog.omp
+++ b/gcc/testsuite/ChangeLog.omp
@@ -1,3 +1,57 @@
+2023-03-06 Paul-Antoine Arras <pa@codesourcery.com>
+
+ Backported from master:
+ 2023-03-06 Paul-Antoine Arras <pa@codesourcery.com>
+
+ * gcc.target/gcn/cond_fmaxnm_1.c: New test.
+ * gcc.target/gcn/cond_fmaxnm_1_run.c: New test.
+ * gcc.target/gcn/cond_fmaxnm_2.c: New test.
+ * gcc.target/gcn/cond_fmaxnm_2_run.c: New test.
+ * gcc.target/gcn/cond_fmaxnm_3.c: New test.
+ * gcc.target/gcn/cond_fmaxnm_3_run.c: New test.
+ * gcc.target/gcn/cond_fmaxnm_4.c: New test.
+ * gcc.target/gcn/cond_fmaxnm_4_run.c: New test.
+ * gcc.target/gcn/cond_fmaxnm_5.c: New test.
+ * gcc.target/gcn/cond_fmaxnm_5_run.c: New test.
+ * gcc.target/gcn/cond_fmaxnm_6.c: New test.
+ * gcc.target/gcn/cond_fmaxnm_6_run.c: New test.
+ * gcc.target/gcn/cond_fmaxnm_7.c: New test.
+ * gcc.target/gcn/cond_fmaxnm_7_run.c: New test.
+ * gcc.target/gcn/cond_fmaxnm_8.c: New test.
+ * gcc.target/gcn/cond_fmaxnm_8_run.c: New test.
+ * gcc.target/gcn/cond_fminnm_1.c: New test.
+ * gcc.target/gcn/cond_fminnm_1_run.c: New test.
+ * gcc.target/gcn/cond_fminnm_2.c: New test.
+ * gcc.target/gcn/cond_fminnm_2_run.c: New test.
+ * gcc.target/gcn/cond_fminnm_3.c: New test.
+ * gcc.target/gcn/cond_fminnm_3_run.c: New test.
+ * gcc.target/gcn/cond_fminnm_4.c: New test.
+ * gcc.target/gcn/cond_fminnm_4_run.c: New test.
+ * gcc.target/gcn/cond_fminnm_5.c: New test.
+ * gcc.target/gcn/cond_fminnm_5_run.c: New test.
+ * gcc.target/gcn/cond_fminnm_6.c: New test.
+ * gcc.target/gcn/cond_fminnm_6_run.c: New test.
+ * gcc.target/gcn/cond_fminnm_7.c: New test.
+ * gcc.target/gcn/cond_fminnm_7_run.c: New test.
+ * gcc.target/gcn/cond_fminnm_8.c: New test.
+ * gcc.target/gcn/cond_fminnm_8_run.c: New test.
+ * gcc.target/gcn/cond_smax_1.c: New test.
+ * gcc.target/gcn/cond_smax_1_run.c: New test.
+ * gcc.target/gcn/cond_smin_1.c: New test.
+ * gcc.target/gcn/cond_smin_1_run.c: New test.
+ * gcc.target/gcn/cond_umax_1.c: New test.
+ * gcc.target/gcn/cond_umax_1_run.c: New test.
+ * gcc.target/gcn/cond_umin_1.c: New test.
+ * gcc.target/gcn/cond_umin_1_run.c: New test.
+ * gcc.target/gcn/smax_1.c: New test.
+ * gcc.target/gcn/smax_1_run.c: New test.
+ * gcc.target/gcn/smin_1.c: New test.
+ * gcc.target/gcn/smin_1_run.c: New test.
+ * gcc.target/gcn/umax_1.c: New test.
+ * gcc.target/gcn/umax_1_run.c: New test.
+ * gcc.target/gcn/umin_1.c: New test.
+ * gcc.target/gcn/umin_1_run.c: New test.
+
2023-02-27 Tobias Burnus <tobias@codesourcery.com>
* gfortran.dg/goacc/finalize-1.f: Update scan-tree-dump-times for
diff --git a/gcc/testsuite/gcc.target/gcn/cond_fmaxnm_1.c b/gcc/testsuite/gcc.target/gcn/cond_fmaxnm_1.c
new file mode 100644
index 00000000000..17c49bdc518
--- /dev/null
+++ b/gcc/testsuite/gcc.target/gcn/cond_fmaxnm_1.c
@@ -0,0 +1,33 @@
+/* { dg-do compile } */
+/* { dg-options "-O2 -ftree-vectorize -ffast-math -dp" } */
+
+#include <stdint.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 (f32), float, int32_t) \
+ TEST_TYPE (T, FN (f64), double, int64_t)
+
+TEST_ALL (DEF_LOOP)
+
+/* { dg-final { scan-assembler-times {smaxv64sf3_exec} 3 } } */
+/* { dg-final { scan-assembler-times {smaxv64df3_exec} 3 } } */
+
+/* { dg-final { scan-assembler-not {\tv_writelane_b32\tv[0-9]+, vcc_..} } } */
\ No newline at end of file
diff --git a/gcc/testsuite/gcc.target/gcn/cond_fmaxnm_1_run.c b/gcc/testsuite/gcc.target/gcn/cond_fmaxnm_1_run.c
new file mode 100644
index 00000000000..1e4c81c17a9
--- /dev/null
+++ b/gcc/testsuite/gcc.target/gcn/cond_fmaxnm_1_run.c
@@ -0,0 +1,32 @@
+/* { dg-do run } */
+/* { dg-options "-O2 -ftree-vectorize -ffast-math" } */
+
+#include "cond_fmaxnm_1.c"
+
+#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/gcn/cond_fmaxnm_2.c b/gcc/testsuite/gcc.target/gcn/cond_fmaxnm_2.c
new file mode 100644
index 00000000000..406df48962a
--- /dev/null
+++ b/gcc/testsuite/gcc.target/gcn/cond_fmaxnm_2.c
@@ -0,0 +1,33 @@
+/* { dg-do compile } */
+/* { dg-options "-O2 -ftree-vectorize -ffast-math -dp" } */
+
+#include <stdint.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 (f32), float) \
+ TEST_TYPE (T, FN (f64), double)
+
+TEST_ALL (DEF_LOOP)
+
+/* { dg-final { scan-assembler-times {smaxv64sf3_exec} 3 } } */
+/* { dg-final { scan-assembler-times {smaxv64df3_exec} 3 } } */
+
+/* { dg-final { scan-assembler-not {\tv_writelane_b32\tv[0-9]+, vcc_..} } } */
diff --git a/gcc/testsuite/gcc.target/gcn/cond_fmaxnm_2_run.c b/gcc/testsuite/gcc.target/gcn/cond_fmaxnm_2_run.c
new file mode 100644
index 00000000000..05d18f41f06
--- /dev/null
+++ b/gcc/testsuite/gcc.target/gcn/cond_fmaxnm_2_run.c
@@ -0,0 +1,31 @@
+/* { dg-do run } */
+/* { dg-options "-O2 -ftree-vectorize -ffast-math" } */
+
+#include "cond_fmaxnm_2.c"
+
+#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/gcn/cond_fmaxnm_3.c b/gcc/testsuite/gcc.target/gcn/cond_fmaxnm_3.c
new file mode 100644
index 00000000000..45b8b7883ba
--- /dev/null
+++ b/gcc/testsuite/gcc.target/gcn/cond_fmaxnm_3.c
@@ -0,0 +1,35 @@
+/* { dg-do compile } */
+/* { dg-options "-O2 -ftree-vectorize -ffast-math -dp" } */
+
+#include <stdint.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 (f32), float, int32_t) \
+ TEST_TYPE (T, FN (f64), double, int64_t)
+
+TEST_ALL (DEF_LOOP)
+
+/* { dg-final { scan-assembler-times {smaxv64sf3} 3 } } */
+/* { dg-final { scan-assembler-times {movv64sf_exec} 3 } } */
+/* { dg-final { scan-assembler-times {smaxv64sf3} 3 } } */
+/* { dg-final { scan-assembler-times {movv64df_exec} 3 } } */
+
+/* { dg-final { scan-assembler-not {\tv_writelane_b32\tv[0-9]+, vcc_..} } } */
\ No newline at end of file
diff --git a/gcc/testsuite/gcc.target/gcn/cond_fmaxnm_3_run.c b/gcc/testsuite/gcc.target/gcn/cond_fmaxnm_3_run.c
new file mode 100644
index 00000000000..23dd00b0b13
--- /dev/null
+++ b/gcc/testsuite/gcc.target/gcn/cond_fmaxnm_3_run.c
@@ -0,0 +1,32 @@
+/* { dg-do run } */
+/* { dg-options "-O2 -ftree-vectorize -ffast-math" } */
+
+#include "cond_fmaxnm_3.c"
+
+#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/gcn/cond_fmaxnm_4.c b/gcc/testsuite/gcc.target/gcn/cond_fmaxnm_4.c
new file mode 100644
index 00000000000..416aea89e6e
--- /dev/null
+++ b/gcc/testsuite/gcc.target/gcn/cond_fmaxnm_4.c
@@ -0,0 +1,35 @@
+/* { dg-do compile } */
+/* { dg-options "-O2 -ftree-vectorize -ffast-math -dp" } */
+
+#include <stdint.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 (f32), float, int32_t) \
+ TEST_TYPE (T, FN (f64), double, int64_t)
+
+TEST_ALL (DEF_LOOP)
+
+/* { dg-final { scan-assembler-times {smaxv64sf3} 3 } } */
+/* { dg-final { scan-assembler-times {movv64sf_exec} 3 } } */
+/* { dg-final { scan-assembler-times {smaxv64sf3} 3 } } */
+/* { dg-final { scan-assembler-times {movv64df_exec} 3 } } */
+
+/* { dg-final { scan-assembler-not {\tv_writelane_b32\tv[0-9]+, vcc_..} } } */
\ No newline at end of file
diff --git a/gcc/testsuite/gcc.target/gcn/cond_fmaxnm_4_run.c b/gcc/testsuite/gcc.target/gcn/cond_fmaxnm_4_run.c
new file mode 100644
index 00000000000..1db583242ba
--- /dev/null
+++ b/gcc/testsuite/gcc.target/gcn/cond_fmaxnm_4_run.c
@@ -0,0 +1,32 @@
+/* { dg-do run } */
+/* { dg-options "-O2 -ftree-vectorize -ffast-math" } */
+
+#include "cond_fmaxnm_4.c"
+
+#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/gcn/cond_fmaxnm_5.c b/gcc/testsuite/gcc.target/gcn/cond_fmaxnm_5.c
new file mode 100644
index 00000000000..a4d7ab991de
--- /dev/null
+++ b/gcc/testsuite/gcc.target/gcn/cond_fmaxnm_5.c
@@ -0,0 +1,9 @@
+/* { dg-do compile } */
+/* { dg-options "-O2 -ftree-vectorize -dp" } */
+
+#include "cond_fmaxnm_1.c"
+
+/* { dg-final { scan-assembler-times {smaxv64sf3_exec} 3 } } */
+/* { dg-final { scan-assembler-times {smaxv64df3_exec} 3 } } */
+
+/* { dg-final { scan-assembler-not {\tv_writelane_b32\tv[0-9]+, vcc_..} } } */
\ No newline at end of file
diff --git a/gcc/testsuite/gcc.target/gcn/cond_fmaxnm_5_run.c b/gcc/testsuite/gcc.target/gcn/cond_fmaxnm_5_run.c
new file mode 100644
index 00000000000..8c0bc2ae876
--- /dev/null
+++ b/gcc/testsuite/gcc.target/gcn/cond_fmaxnm_5_run.c
@@ -0,0 +1,4 @@
+/* { dg-do run } */
+/* { dg-options "-O2 -ftree-vectorize" } */
+
+#include "cond_fmaxnm_1_run.c"
diff --git a/gcc/testsuite/gcc.target/gcn/cond_fmaxnm_6.c b/gcc/testsuite/gcc.target/gcn/cond_fmaxnm_6.c
new file mode 100644
index 00000000000..6c64a01bcbb
--- /dev/null
+++ b/gcc/testsuite/gcc.target/gcn/cond_fmaxnm_6.c
@@ -0,0 +1,9 @@
+/* { dg-do compile } */
+/* { dg-options "-O2 -ftree-vectorize -dp" } */
+
+#include "cond_fmaxnm_2.c"
+
+/* { dg-final { scan-assembler-times {smaxv64sf3_exec} 3 } } */
+/* { dg-final { scan-assembler-times {smaxv64df3_exec} 3 } } */
+
+/* { dg-final { scan-assembler-not {\tv_writelane_b32\tv[0-9]+, vcc_..} } } */
diff --git a/gcc/testsuite/gcc.target/gcn/cond_fmaxnm_6_run.c b/gcc/testsuite/gcc.target/gcn/cond_fmaxnm_6_run.c
new file mode 100644
index 00000000000..5c5db46b390
--- /dev/null
+++ b/gcc/testsuite/gcc.target/gcn/cond_fmaxnm_6_run.c
@@ -0,0 +1,4 @@
+/* { dg-do run } */
+/* { dg-options "-O2 -ftree-vectorize" } */
+
+#include "cond_fmaxnm_2_run.c"
diff --git a/gcc/testsuite/gcc.target/gcn/cond_fmaxnm_7.c b/gcc/testsuite/gcc.target/gcn/cond_fmaxnm_7.c
new file mode 100644
index 00000000000..bdb3f2f99ef
--- /dev/null
+++ b/gcc/testsuite/gcc.target/gcn/cond_fmaxnm_7.c
@@ -0,0 +1,9 @@
+/* { dg-do compile } */
+/* { dg-options "-O2 -ftree-vectorize -dp" } */
+
+#include "cond_fmaxnm_3.c"
+
+/* { dg-final { scan-assembler-times {smaxv64sf3_exec} 3 } } */
+/* { dg-final { scan-assembler-times {smaxv64df3_exec} 3 } } */
+
+/* { dg-final { scan-assembler-not {\tv_writelane_b32\tv[0-9]+, vcc_..} } } */
\ No newline at end of file
diff --git a/gcc/testsuite/gcc.target/gcn/cond_fmaxnm_7_run.c b/gcc/testsuite/gcc.target/gcn/cond_fmaxnm_7_run.c
new file mode 100644
index 00000000000..0abe626fdfb
--- /dev/null
+++ b/gcc/testsuite/gcc.target/gcn/cond_fmaxnm_7_run.c
@@ -0,0 +1,4 @@
+/* { dg-do run } */
+/* { dg-options "-O2 -ftree-vectorize" } */
+
+#include "cond_fmaxnm_3_run.c"
diff --git a/gcc/testsuite/gcc.target/gcn/cond_fmaxnm_8.c b/gcc/testsuite/gcc.target/gcn/cond_fmaxnm_8.c
new file mode 100644
index 00000000000..c11633b5236
--- /dev/null
+++ b/gcc/testsuite/gcc.target/gcn/cond_fmaxnm_8.c
@@ -0,0 +1,9 @@
+/* { dg-do compile } */
+/* { dg-options "-O2 -ftree-vectorize -dp" } */
+
+#include "cond_fmaxnm_4.c"
+
+/* { dg-final { scan-assembler-times {smaxv64sf3_exec} 3 } } */
+/* { dg-final { scan-assembler-times {smaxv64df3_exec} 3 } } */
+
+/* { dg-final { scan-assembler-not {\tv_writelane_b32\tv[0-9]+, vcc_..} } } */
\ No newline at end of file
diff --git a/gcc/testsuite/gcc.target/gcn/cond_fmaxnm_8_run.c b/gcc/testsuite/gcc.target/gcn/cond_fmaxnm_8_run.c
new file mode 100644
index 00000000000..43b892f922e
--- /dev/null
+++ b/gcc/testsuite/gcc.target/gcn/cond_fmaxnm_8_run.c
@@ -0,0 +1,4 @@
+/* { dg-do run } */
+/* { dg-options "-O2 -ftree-vectorize" } */
+
+#include "cond_fmaxnm_4_run.c"
diff --git a/gcc/testsuite/gcc.target/gcn/cond_fminnm_1.c b/gcc/testsuite/gcc.target/gcn/cond_fminnm_1.c
new file mode 100644
index 00000000000..bb456887568
--- /dev/null
+++ b/gcc/testsuite/gcc.target/gcn/cond_fminnm_1.c
@@ -0,0 +1,10 @@
+/* { dg-do compile } */
+/* { dg-options "-O2 -ftree-vectorize -ffast-math -dp" } */
+
+#define FN(X) __builtin_fmin##X
+#include "cond_fmaxnm_1.c"
+
+/* { dg-final { scan-assembler-times {sminv64sf3_exec} 3 } } */
+/* { dg-final { scan-assembler-times {sminv64df3_exec} 3 } } */
+
+/* { dg-final { scan-assembler-not {\tv_writelane_b32\tv[0-9]+, vcc_..} } } */
diff --git a/gcc/testsuite/gcc.target/gcn/cond_fminnm_1_run.c b/gcc/testsuite/gcc.target/gcn/cond_fminnm_1_run.c
new file mode 100644
index 00000000000..6dd9d499b35
--- /dev/null
+++ b/gcc/testsuite/gcc.target/gcn/cond_fminnm_1_run.c
@@ -0,0 +1,5 @@
+/* { dg-do run } */
+/* { dg-options "-O2 -ftree-vectorize -ffast-math" } */
+
+#define FN(X) __builtin_fmin##X
+#include "cond_fmaxnm_1_run.c"
diff --git a/gcc/testsuite/gcc.target/gcn/cond_fminnm_2.c b/gcc/testsuite/gcc.target/gcn/cond_fminnm_2.c
new file mode 100644
index 00000000000..502f8987494
--- /dev/null
+++ b/gcc/testsuite/gcc.target/gcn/cond_fminnm_2.c
@@ -0,0 +1,10 @@
+/* { dg-do compile } */
+/* { dg-options "-O2 -ftree-vectorize -ffast-math -dp" } */
+
+#define FN(X) __builtin_fmin##X
+#include "cond_fmaxnm_2.c"
+
+/* { dg-final { scan-assembler-times {sminv64sf3_exec} 3 } } */
+/* { dg-final { scan-assembler-times {sminv64df3_exec} 3 } } */
+
+/* { dg-final { scan-assembler-not {\tv_writelane_b32\tv[0-9]+, vcc_..} } } */
\ No newline at end of file
diff --git a/gcc/testsuite/gcc.target/gcn/cond_fminnm_2_run.c b/gcc/testsuite/gcc.target/gcn/cond_fminnm_2_run.c
new file mode 100644
index 00000000000..72784290113
--- /dev/null
+++ b/gcc/testsuite/gcc.target/gcn/cond_fminnm_2_run.c
@@ -0,0 +1,5 @@
+/* { dg-do run } */
+/* { dg-options "-O2 -ftree-vectorize -ffast-math" } */
+
+#define FN(X) __builtin_fmin##X
+#include "cond_fmaxnm_2_run.c"
diff --git a/gcc/testsuite/gcc.target/gcn/cond_fminnm_3.c b/gcc/testsuite/gcc.target/gcn/cond_fminnm_3.c
new file mode 100644
index 00000000000..2ea1eb2ec2c
--- /dev/null
+++ b/gcc/testsuite/gcc.target/gcn/cond_fminnm_3.c
@@ -0,0 +1,12 @@
+/* { dg-do compile } */
+/* { dg-options "-O2 -ftree-vectorize -ffast-math -dp" } */
+
+#define FN(X) __builtin_fmin##X
+#include "cond_fmaxnm_3.c"
+
+/* { dg-final { scan-assembler-times {sminv64sf3} 3 } } */
+/* { dg-final { scan-assembler-times {movv64sf_exec} 3 } } */
+/* { dg-final { scan-assembler-times {sminv64sf3} 3 } } */
+/* { dg-final { scan-assembler-times {movv64df_exec} 3 } } */
+
+/* { dg-final { scan-assembler-not {\tv_writelane_b32\tv[0-9]+, vcc_..} } } */
\ No newline at end of file
diff --git a/gcc/testsuite/gcc.target/gcn/cond_fminnm_3_run.c b/gcc/testsuite/gcc.target/gcn/cond_fminnm_3_run.c
new file mode 100644
index 00000000000..8c994cae202
--- /dev/null
+++ b/gcc/testsuite/gcc.target/gcn/cond_fminnm_3_run.c
@@ -0,0 +1,5 @@
+/* { dg-do run } */
+/* { dg-options "-O2 -ftree-vectorize -ffast-math" } */
+
+#define FN(X) __builtin_fmin##X
+#include "cond_fmaxnm_3_run.c"
diff --git a/gcc/testsuite/gcc.target/gcn/cond_fminnm_4.c b/gcc/testsuite/gcc.target/gcn/cond_fminnm_4.c
new file mode 100644
index 00000000000..3673ecafc2d
--- /dev/null
+++ b/gcc/testsuite/gcc.target/gcn/cond_fminnm_4.c
@@ -0,0 +1,12 @@
+/* { dg-do compile } */
+/* { dg-options "-O2 -ftree-vectorize -ffast-math -dp" } */
+
+#define FN(X) __builtin_fmin##X
+#include "cond_fmaxnm_4.c"
+
+/* { dg-final { scan-assembler-times {sminv64sf3} 3 } } */
+/* { dg-final { scan-assembler-times {movv64sf_exec} 3 } } */
+/* { dg-final { scan-assembler-times {sminv64sf3} 3 } } */
+/* { dg-final { scan-assembler-times {movv64df_exec} 3 } } */
+
+/* { dg-final { scan-assembler-not {\tv_writelane_b32\tv[0-9]+, vcc_..} } } */
\ No newline at end of file
diff --git a/gcc/testsuite/gcc.target/gcn/cond_fminnm_4_run.c b/gcc/testsuite/gcc.target/gcn/cond_fminnm_4_run.c
new file mode 100644
index 00000000000..728f4136015
--- /dev/null
+++ b/gcc/testsuite/gcc.target/gcn/cond_fminnm_4_run.c
@@ -0,0 +1,5 @@
+/* { dg-do run } */
+/* { dg-options "-O2 -ftree-vectorize -ffast-math" } */
+
+#define FN(X) __builtin_fmin##X
+#include "cond_fmaxnm_4_run.c"
diff --git a/gcc/testsuite/gcc.target/gcn/cond_fminnm_5.c b/gcc/testsuite/gcc.target/gcn/cond_fminnm_5.c
new file mode 100644
index 00000000000..ac98941a373
--- /dev/null
+++ b/gcc/testsuite/gcc.target/gcn/cond_fminnm_5.c
@@ -0,0 +1,10 @@
+/* { dg-do compile } */
+/* { dg-options "-O2 -ftree-vectorize -dp" } */
+
+#define FN(X) __builtin_fmin##X
+#include "cond_fmaxnm_1.c"
+
+/* { dg-final { scan-assembler-times {sminv64sf3_exec} 3 } } */
+/* { dg-final { scan-assembler-times {sminv64df3_exec} 3 } } */
+
+/* { dg-final { scan-assembler-not {\tv_writelane_b32\tv[0-9]+, vcc_..} } } */
\ No newline at end of file
diff --git a/gcc/testsuite/gcc.target/gcn/cond_fminnm_5_run.c b/gcc/testsuite/gcc.target/gcn/cond_fminnm_5_run.c
new file mode 100644
index 00000000000..9236ab5b211
--- /dev/null
+++ b/gcc/testsuite/gcc.target/gcn/cond_fminnm_5_run.c
@@ -0,0 +1,4 @@
+/* { dg-do run } */
+/* { dg-options "-O2 -ftree-vectorize" } */
+
+#include "cond_fminnm_1_run.c"
diff --git a/gcc/testsuite/gcc.target/gcn/cond_fminnm_6.c b/gcc/testsuite/gcc.target/gcn/cond_fminnm_6.c
new file mode 100644
index 00000000000..7f4dba0d314
--- /dev/null
+++ b/gcc/testsuite/gcc.target/gcn/cond_fminnm_6.c
@@ -0,0 +1,10 @@
+/* { dg-do compile } */
+/* { dg-options "-O2 -ftree-vectorize -dp" } */
+
+#define FN(X) __builtin_fmin##X
+#include "cond_fmaxnm_2.c"
+
+/* { dg-final { scan-assembler-times {sminv64sf3_exec} 3 } } */
+/* { dg-final { scan-assembler-times {sminv64df3_exec} 3 } } */
+
+/* { dg-final { scan-assembler-not {\tv_writelane_b32\tv[0-9]+, vcc_..} } } */
\ No newline at end of file
diff --git a/gcc/testsuite/gcc.target/gcn/cond_fminnm_6_run.c b/gcc/testsuite/gcc.target/gcn/cond_fminnm_6_run.c
new file mode 100644
index 00000000000..a5f90d9e76a
--- /dev/null
+++ b/gcc/testsuite/gcc.target/gcn/cond_fminnm_6_run.c
@@ -0,0 +1,4 @@
+/* { dg-do run } */
+/* { dg-options "-O2 -ftree-vectorize" } */
+
+#include "cond_fminnm_2_run.c"
diff --git a/gcc/testsuite/gcc.target/gcn/cond_fminnm_7.c b/gcc/testsuite/gcc.target/gcn/cond_fminnm_7.c
new file mode 100644
index 00000000000..5faf0c5cc59
--- /dev/null
+++ b/gcc/testsuite/gcc.target/gcn/cond_fminnm_7.c
@@ -0,0 +1,10 @@
+/* { dg-do compile } */
+/* { dg-options "-O2 -ftree-vectorize -dp" } */
+
+#define FN(X) __builtin_fmin##X
+#include "cond_fmaxnm_3.c"
+
+/* { dg-final { scan-assembler-times {sminv64sf3_exec} 3 } } */
+/* { dg-final { scan-assembler-times {sminv64df3_exec} 3 } } */
+
+/* { dg-final { scan-assembler-not {\tv_writelane_b32\tv[0-9]+, vcc_..} } } */
\ No newline at end of file
diff --git a/gcc/testsuite/gcc.target/gcn/cond_fminnm_7_run.c b/gcc/testsuite/gcc.target/gcn/cond_fminnm_7_run.c
new file mode 100644
index 00000000000..d7ad738db5c
--- /dev/null
+++ b/gcc/testsuite/gcc.target/gcn/cond_fminnm_7_run.c
@@ -0,0 +1,4 @@
+/* { dg-do run } */
+/* { dg-options "-O2 -ftree-vectorize" } */
+
+#include "cond_fminnm_3_run.c"
diff --git a/gcc/testsuite/gcc.target/gcn/cond_fminnm_8.c b/gcc/testsuite/gcc.target/gcn/cond_fminnm_8.c
new file mode 100644
index 00000000000..89d93ac596a
--- /dev/null
+++ b/gcc/testsuite/gcc.target/gcn/cond_fminnm_8.c
@@ -0,0 +1,10 @@
+/* { dg-do compile } */
+/* { dg-options "-O2 -ftree-vectorize -dp" } */
+
+#define FN(X) __builtin_fmin##X
+#include "cond_fmaxnm_4.c"
+
+/* { dg-final { scan-assembler-times {sminv64sf3_exec} 3 } } */
+/* { dg-final { scan-assembler-times {sminv64df3_exec} 3 } } */
+
+/* { dg-final { scan-assembler-not {\tv_writelane_b32\tv[0-9]+, vcc_..} } } */
\ No newline at end of file
diff --git a/gcc/testsuite/gcc.target/gcn/cond_fminnm_8_run.c b/gcc/testsuite/gcc.target/gcn/cond_fminnm_8_run.c
new file mode 100644
index 00000000000..3d92353ac55
--- /dev/null
+++ b/gcc/testsuite/gcc.target/gcn/cond_fminnm_8_run.c
@@ -0,0 +1,4 @@
+/* { dg-do run } */
+/* { dg-options "-O2 -ftree-vectorize" } */
+
+#include "cond_fminnm_4_run.c"
diff --git a/gcc/testsuite/gcc.target/gcn/cond_smax_1.c b/gcc/testsuite/gcc.target/gcn/cond_smax_1.c
new file mode 100644
index 00000000000..342b5e827d2
--- /dev/null
+++ b/gcc/testsuite/gcc.target/gcn/cond_smax_1.c
@@ -0,0 +1,57 @@
+/* { dg-do compile } */
+/* { dg-options "-O2 -ftree-vectorize -dp" } */
+
+#include <stdint.h>
+
+#define DO_REGREG_OPS(TYPE) \
+ void __attribute__ ((noclone)) \
+ varith_##TYPE##_reg (TYPE *__restrict x, TYPE *__restrict y, \
+ TYPE *__restrict pred, int count) \
+ { \
+ for (int i = 0; i < count; ++i) \
+ x[i] = (pred[i] != -1) ? (x[i] > y[i] ? x[i] : y[i]) : -4; \
+ }
+
+#define DO_IMMEDIATE_OPS(VALUE, TYPE, NAME) \
+ void __attribute__ ((noclone)) \
+ varithimm_##NAME##_##TYPE (TYPE *__restrict x, TYPE *__restrict pred, \
+ int count) \
+ { \
+ for (int i = 0; i < count; ++i) \
+ x[i] \
+ = (pred[i] != -1) ? (x[i] > (TYPE) VALUE ? x[i] : (TYPE) VALUE) : -4; \
+ }
+
+#define DO_ARITH_OPS(REG, IMM, TYPE) \
+ REG (TYPE); \
+ IMM (0, TYPE, 0); \
+ IMM (86, TYPE, 86); \
+ IMM (109, TYPE, 109); \
+ IMM (141, TYPE, 141); \
+ IMM (92137445376, TYPE, 92137445376); \
+ IMM (-1, TYPE, minus1); \
+ IMM (-110, TYPE, minus110); \
+ IMM (-141, TYPE, minus141); \
+ IMM (-92137445376, TYPE, minus92137445376);
+
+#define TEST_ALL(REG, IMM) \
+ DO_ARITH_OPS (REG, IMM, int8_t) \
+ DO_ARITH_OPS (REG, IMM, int16_t) \
+ DO_ARITH_OPS (REG, IMM, int32_t) \
+ DO_ARITH_OPS (REG, IMM, int64_t)
+
+TEST_ALL (DO_REGREG_OPS, DO_IMMEDIATE_OPS)
+
+/* One per test case < 64 bits */
+/* { dg-final { scan-assembler-times {smaxv64si3_exec} 30 } } */
+/* { dg-final { scan-assembler-not {smaxv64si3/0} } } */
+/* { dg-final { scan-assembler-not {\tv_writelane_b32\tv[0-9]+, vcc_??, 0} } } */
+
+/* Two per test case: */
+/* { dg-final { scan-assembler-times {\tv_cmp_gt_i32\tvcc, s[0-9]+, v[0-9]+} 80 } } */
+/* { dg-final { scan-assembler-not {\tv_cmpx_gt_i32\tvcc, s[0-9]+, v[0-9]+} } } */
+/* { dg-final { scan-assembler-not {\ts_cmpk_lg_u32\tvcc_lo, 0} } } */
+
+/* One per 64-bit test case: */
+/* { dg-final { scan-assembler-times {\tv_cmp_ne_u64\ts\[[0-9]+:[0-9]+\], v\[[0-9]+:[0-9]+\], -1} 10 } } */
+/* { dg-final { scan-assembler-times {\tv_cmp_gt_i64\tvcc, v[[0-9]+:[0-9]+], v[[0-9]+:[0-9]+]} 10 } } */
diff --git a/gcc/testsuite/gcc.target/gcn/cond_smax_1_run.c b/gcc/testsuite/gcc.target/gcn/cond_smax_1_run.c
new file mode 100644
index 00000000000..c951e614579
--- /dev/null
+++ b/gcc/testsuite/gcc.target/gcn/cond_smax_1_run.c
@@ -0,0 +1,53 @@
+/* { dg-do run } */
+/* { dg-options "-O2 -ftree-vectorize" } */
+
+#include "cond_smax_1.c"
+
+#define N 99
+
+#define TEST_REGREG_OPS(TYPE) \
+ { \
+ TYPE x[N], y[N]; \
+ TYPE pred[N]; \
+ for (int i = 0; i < N; ++i) \
+ { \
+ x[i] = i % 13; \
+ y[i] = i * i; \
+ pred[i] = i % 3; \
+ } \
+ varith_##TYPE##_reg (x, y, pred, N); \
+ for (int i = 0; i < N; ++i) \
+ { \
+ TYPE expected = i % 3 != -1 ? (x[i] > y[i] ? x[i] : y[i]) : -4; \
+ if (x[i] != expected) \
+ __builtin_abort (); \
+ asm volatile ("" ::: "memory"); \
+ } \
+ }
+
+#define TEST_IMMEDIATE_OPS(VALUE, TYPE, NAME) \
+ { \
+ TYPE x[N], y[N]; \
+ TYPE pred[N]; \
+ for (int i = 0; i < N; ++i) \
+ { \
+ x[i] = i * i; \
+ pred[i] = i % 3; \
+ } \
+ varithimm_##NAME##_##TYPE (x, pred, N); \
+ for (int i = 0; i < N; ++i) \
+ { \
+ TYPE expected \
+ = i % 3 != -1 ? (x[i] > (TYPE) VALUE ? x[i] : (TYPE) VALUE) : -4; \
+ if (x[i] != expected) \
+ __builtin_abort (); \
+ asm volatile ("" ::: "memory"); \
+ } \
+ }
+
+int
+main (void)
+{
+ TEST_ALL (TEST_REGREG_OPS, TEST_IMMEDIATE_OPS)
+ return 0;
+}
\ No newline at end of file
diff --git a/gcc/testsuite/gcc.target/gcn/cond_smin_1.c b/gcc/testsuite/gcc.target/gcn/cond_smin_1.c
new file mode 100644
index 00000000000..ad8b583448b
--- /dev/null
+++ b/gcc/testsuite/gcc.target/gcn/cond_smin_1.c
@@ -0,0 +1,57 @@
+/* { dg-do compile } */
+/* { dg-options "-O2 -ftree-vectorize -dp" } */
+
+#include <stdint.h>
+
+#define DO_REGREG_OPS(TYPE) \
+ void __attribute__ ((noclone)) \
+ varith_##TYPE##_reg (TYPE *__restrict x, TYPE *__restrict y, \
+ TYPE *__restrict pred, int count) \
+ { \
+ for (int i = 0; i < count; ++i) \
+ x[i] = (pred[i] != -1) ? (x[i] < y[i] ? x[i] : y[i]) : -4; \
+ }
+
+#define DO_IMMEDIATE_OPS(VALUE, TYPE, NAME) \
+ void __attribute__ ((noclone)) \
+ varithimm_##NAME##_##TYPE (TYPE *__restrict x, TYPE *__restrict pred, \
+ int count) \
+ { \
+ for (int i = 0; i < count; ++i) \
+ x[i] \
+ = (pred[i] != -1) ? (x[i] < (TYPE) VALUE ? x[i] : (TYPE) VALUE) : -4; \
+ }
+
+#define DO_ARITH_OPS(REG, IMM, TYPE) \
+ REG (TYPE); \
+ IMM (0, TYPE, 0); \
+ IMM (86, TYPE, 86); \
+ IMM (109, TYPE, 109); \
+ IMM (141, TYPE, 141); \
+ IMM (92137445376, TYPE, 92137445376); \
+ IMM (-1, TYPE, minus1); \
+ IMM (-110, TYPE, minus110); \
+ IMM (-141, TYPE, minus141); \
+ IMM (-92137445376, TYPE, minus92137445376);
+
+#define TEST_ALL(REG, IMM) \
+ DO_ARITH_OPS (REG, IMM, int8_t) \
+ DO_ARITH_OPS (REG, IMM, int16_t) \
+ DO_ARITH_OPS (REG, IMM, int32_t) \
+ DO_ARITH_OPS (REG, IMM, int64_t)
+
+TEST_ALL (DO_REGREG_OPS, DO_IMMEDIATE_OPS)
+
+/* One per test case < 64 bits */
+/* { dg-final { scan-assembler-times {sminv64si3_exec} 30 } } */
+/* { dg-final { scan-assembler-not {sminv64si3/0} } } */
+/* { dg-final { scan-assembler-not {\tv_writelane_b32\tv[0-9]+, vcc_??, 0} } } */
+
+/* Two per test case: */
+/* { dg-final { scan-assembler-times {\tv_cmp_gt_i32\tvcc, s[0-9]+, v[0-9]+} 80 } } */
+/* { dg-final { scan-assembler-not {\tv_cmpx_gt_i32\tvcc, s[0-9]+, v[0-9]+} } } */
+/* { dg-final { scan-assembler-not {\ts_cmpk_lg_u32\tvcc_lo, 0} } } */
+
+/* One per 64-bit test case: */
+/* { dg-final { scan-assembler-times {\tv_cmp_ne_u64\ts\[[0-9]+:[0-9]+\], v\[[0-9]+:[0-9]+\], -1} 10 } } */
+/* { dg-final { scan-assembler-times {\tv_cmp_lt_i64\tvcc, v[[0-9]+:[0-9]+], v[[0-9]+:[0-9]+]} 10 } } */
diff --git a/gcc/testsuite/gcc.target/gcn/cond_smin_1_run.c b/gcc/testsuite/gcc.target/gcn/cond_smin_1_run.c
new file mode 100644
index 00000000000..bfdb7d1b9e8
--- /dev/null
+++ b/gcc/testsuite/gcc.target/gcn/cond_smin_1_run.c
@@ -0,0 +1,53 @@
+/* { dg-do run } */
+/* { dg-options "-O2 -ftree-vectorize" } */
+
+#include "cond_smin_1.c"
+
+#define N 99
+
+#define TEST_REGREG_OPS(TYPE) \
+ { \
+ TYPE x[N], y[N]; \
+ TYPE pred[N]; \
+ for (int i = 0; i < N; ++i) \
+ { \
+ x[i] = i % 13; \
+ y[i] = i * i; \
+ pred[i] = i % 3; \
+ } \
+ varith_##TYPE##_reg (x, y, pred, N); \
+ for (int i = 0; i < N; ++i) \
+ { \
+ TYPE expected = i % 3 != -1 ? (x[i] < y[i] ? x[i] : y[i]) : -4; \
+ if (x[i] != expected) \
+ __builtin_abort (); \
+ asm volatile ("" ::: "memory"); \
+ } \
+ }
+
+#define TEST_IMMEDIATE_OPS(VALUE, TYPE, NAME) \
+ { \
+ TYPE x[N], y[N]; \
+ TYPE pred[N]; \
+ for (int i = 0; i < N; ++i) \
+ { \
+ x[i] = i * i; \
+ pred[i] = i % 3; \
+ } \
+ varithimm_##NAME##_##TYPE (x, pred, N); \
+ for (int i = 0; i < N; ++i) \
+ { \
+ TYPE expected \
+ = i % 3 != -1 ? (x[i] < (TYPE) VALUE ? x[i] : (TYPE) VALUE) : -4; \
+ if (x[i] != expected) \
+ __builtin_abort (); \
+ asm volatile ("" ::: "memory"); \
+ } \
+ }
+
+int
+main (void)
+{
+ TEST_ALL (TEST_REGREG_OPS, TEST_IMMEDIATE_OPS)
+ return 0;
+}
\ No newline at end of file
diff --git a/gcc/testsuite/gcc.target/gcn/cond_umax_1.c b/gcc/testsuite/gcc.target/gcn/cond_umax_1.c
new file mode 100644
index 00000000000..389228f9e4a
--- /dev/null
+++ b/gcc/testsuite/gcc.target/gcn/cond_umax_1.c
@@ -0,0 +1,54 @@
+/* { dg-do compile } */
+/* { dg-options "-O2 -ftree-vectorize -dp" } */
+
+#include <stdint.h>
+
+#define DO_REGREG_OPS(TYPE) \
+ void __attribute__ ((noclone)) \
+ varith_##TYPE##_reg (TYPE *__restrict x, TYPE *__restrict y, \
+ TYPE *__restrict pred, int count) \
+ { \
+ for (int i = 0; i < count; ++i) \
+ x[i] = (pred[i] != 1) ? (x[i] > y[i] ? x[i] : y[i]) : 4; \
+ }
+
+#define DO_IMMEDIATE_OPS(VALUE, TYPE) \
+ void __attribute__ ((noclone)) \
+ varithimm_##VALUE##_##TYPE (TYPE *__restrict x, TYPE *__restrict pred, \
+ int count) \
+ { \
+ for (int i = 0; i < count; ++i) \
+ x[i] = (pred[i] != 1) ? (x[i] > (TYPE) VALUE ? x[i] : (TYPE) VALUE) : 4; \
+ }
+
+#define DO_ARITH_OPS(REG, IMM, TYPE) \
+ REG (TYPE); \
+ IMM (2, TYPE); \
+ IMM (86, TYPE); \
+ IMM (109, TYPE); \
+ IMM (141, TYPE); \
+ IMM (229, TYPE); \
+ IMM (255, TYPE); \
+ IMM (992137445376, TYPE);
+
+#define TEST_ALL(REG, IMM) \
+ DO_ARITH_OPS (REG, IMM, uint8_t) \
+ DO_ARITH_OPS (REG, IMM, uint16_t) \
+ DO_ARITH_OPS (REG, IMM, uint32_t) \
+ DO_ARITH_OPS (REG, IMM, uint64_t)
+
+TEST_ALL (DO_REGREG_OPS, DO_IMMEDIATE_OPS)
+
+/* Two per test case < 64 bits with wide-enough type:*/
+/* { dg-final { scan-assembler-times {umaxv64si3_exec} 20 } } */
+/* { dg-final { scan-assembler-not {umaxv64si3/0} } } */
+/* { dg-final { scan-assembler-not {\tv_writelane_b32\tv[0-9]+, vcc_??, 0} } } */
+
+/* Two per test case with wide-enough type:*/
+/* { dg-final { scan-assembler-times {\tv_cmp_gt_i32\tvcc, s[0-9]+, v[0-9]+} 56 } } */
+/* { dg-final { scan-assembler-not {\ts_cmpk_lg_u32\tvcc_lo, 0} } } */
+
+/* One per 64-bit test case: */
+/* { dg-final { scan-assembler-times {\tv_cmp_ne_u64\ts\[[0-9]+:[0-9]+\], v\[[0-9]+:[0-9]+\], 1} 8 } } */
+/* { dg-final { scan-assembler-times {\tv_cmp_gt_u64\tvcc, v[[0-9]+:[0-9]+], v[[0-9]+:[0-9]+]} 8 } } */
+
diff --git a/gcc/testsuite/gcc.target/gcn/cond_umax_1_run.c b/gcc/testsuite/gcc.target/gcn/cond_umax_1_run.c
new file mode 100644
index 00000000000..2396c2452d7
--- /dev/null
+++ b/gcc/testsuite/gcc.target/gcn/cond_umax_1_run.c
@@ -0,0 +1,53 @@
+/* { dg-do run } */
+/* { dg-options "-O2 -ftree-vectorize" } */
+
+#include "cond_umax_1.c"
+
+#define N 99
+
+#define TEST_REGREG_OPS(TYPE) \
+ { \
+ TYPE x[N], y[N]; \
+ TYPE pred[N]; \
+ for (int i = 0; i < N; ++i) \
+ { \
+ x[i] = i % 13; \
+ y[i] = i * i; \
+ pred[i] = i % 3; \
+ } \
+ varith_##TYPE##_reg (x, y, pred, N); \
+ for (int i = 0; i < N; ++i) \
+ { \
+ TYPE expected = i % 3 != 1 ? (x[i] > y[i] ? x[i] : y[i]) : 4; \
+ if (x[i] != expected) \
+ __builtin_abort (); \
+ asm volatile ("" ::: "memory"); \
+ } \
+ }
+
+#define TEST_IMMEDIATE_OPS(VALUE, TYPE) \
+ { \
+ TYPE x[N], y[N]; \
+ TYPE pred[N]; \
+ for (int i = 0; i < N; ++i) \
+ { \
+ x[i] = i * i; \
+ pred[i] = i % 3; \
+ } \
+ varithimm_##VALUE##_##TYPE (x, pred, N); \
+ for (int i = 0; i < N; ++i) \
+ { \
+ TYPE expected \
+ = i % 3 != 1 ? (x[i] > (TYPE) VALUE ? x[i] : (TYPE) VALUE) : 4; \
+ if (x[i] != expected) \
+ __builtin_abort (); \
+ asm volatile ("" ::: "memory"); \
+ } \
+ }
+
+int
+main (void)
+{
+ TEST_ALL (TEST_REGREG_OPS, TEST_IMMEDIATE_OPS)
+ return 0;
+}
\ No newline at end of file
diff --git a/gcc/testsuite/gcc.target/gcn/cond_umin_1.c b/gcc/testsuite/gcc.target/gcn/cond_umin_1.c
new file mode 100644
index 00000000000..65759d695ad
--- /dev/null
+++ b/gcc/testsuite/gcc.target/gcn/cond_umin_1.c
@@ -0,0 +1,53 @@
+/* { dg-do compile } */
+/* { dg-options "-O2 -ftree-vectorize -dp" } */
+
+#include <stdint.h>
+
+#define DO_REGREG_OPS(TYPE) \
+ void __attribute__ ((noclone)) \
+ varith_##TYPE##_reg (TYPE *__restrict x, TYPE *__restrict y, \
+ TYPE *__restrict pred, int count) \
+ { \
+ for (int i = 0; i < count; ++i) \
+ x[i] = (pred[i] != 1) ? (x[i] < y[i] ? x[i] : y[i]) : 4; \
+ }
+
+#define DO_IMMEDIATE_OPS(VALUE, TYPE) \
+ void __attribute__ ((noclone)) \
+ varithimm_##VALUE##_##TYPE (TYPE *__restrict x, TYPE *__restrict pred, \
+ int count) \
+ { \
+ for (int i = 0; i < count; ++i) \
+ x[i] = (pred[i] != 1) ? (x[i] < (TYPE) VALUE ? x[i] : (TYPE) VALUE) : 4; \
+ }
+
+#define DO_ARITH_OPS(REG, IMM, TYPE) \
+ REG (TYPE); \
+ IMM (2, TYPE); \
+ IMM (86, TYPE); \
+ IMM (109, TYPE); \
+ IMM (141, TYPE); \
+ IMM (229, TYPE); \
+ IMM (255, TYPE); \
+ IMM (992137445376, TYPE);
+
+#define TEST_ALL(REG, IMM) \
+ DO_ARITH_OPS (REG, IMM, uint8_t) \
+ DO_ARITH_OPS (REG, IMM, uint16_t) \
+ DO_ARITH_OPS (REG, IMM, uint32_t) \
+ DO_ARITH_OPS (REG, IMM, uint64_t)
+
+TEST_ALL (DO_REGREG_OPS, DO_IMMEDIATE_OPS)
+
+/* Two per test case < 64 bits with wide-enough type:*/
+/* { dg-final { scan-assembler-times {uminv64si3_exec} 20 } } */
+/* { dg-final { scan-assembler-not {uminv64si3/0} } } */
+/* { dg-final { scan-assembler-not {\tv_writelane_b32\tv[0-9]+, vcc_??, 0} } } */
+
+/* Two per test case with wide-enough type:*/
+/* { dg-final { scan-assembler-times {\tv_cmp_gt_i32\tvcc, s[0-9]+, v[0-9]+} 56 } } */
+/* { dg-final { scan-assembler-not {\ts_cmpk_lg_u32\tvcc_lo, 0} } } */
+
+/* One per 64-bit test case: */
+/* { dg-final { scan-assembler-times {\tv_cmp_ne_u64\ts\[[0-9]+:[0-9]+\], v\[[0-9]+:[0-9]+\], 1} 8 } } */
+/* { dg-final { scan-assembler-times {\tv_cmp_lt_u64\tvcc, v[[0-9]+:[0-9]+], v[[0-9]+:[0-9]+]} 8 } } */
diff --git a/gcc/testsuite/gcc.target/gcn/cond_umin_1_run.c b/gcc/testsuite/gcc.target/gcn/cond_umin_1_run.c
new file mode 100644
index 00000000000..ef6f03948ea
--- /dev/null
+++ b/gcc/testsuite/gcc.target/gcn/cond_umin_1_run.c
@@ -0,0 +1,53 @@
+/* { dg-do run } */
+/* { dg-options "-O2 -ftree-vectorize" } */
+
+#include "cond_umin_1.c"
+
+#define N 99
+
+#define TEST_REGREG_OPS(TYPE) \
+ { \
+ TYPE x[N], y[N]; \
+ TYPE pred[N]; \
+ for (int i = 0; i < N; ++i) \
+ { \
+ x[i] = i % 13; \
+ y[i] = i * i; \
+ pred[i] = i % 3; \
+ } \
+ varith_##TYPE##_reg (x, y, pred, N); \
+ for (int i = 0; i < N; ++i) \
+ { \
+ TYPE expected = i % 3 != 1 ? (x[i] < y[i] ? x[i] : y[i]) : 4; \
+ if (x[i] != expected) \
+ __builtin_abort (); \
+ asm volatile ("" ::: "memory"); \
+ } \
+ }
+
+#define TEST_IMMEDIATE_OPS(VALUE, TYPE) \
+ { \
+ TYPE x[N], y[N]; \
+ TYPE pred[N]; \
+ for (int i = 0; i < N; ++i) \
+ { \
+ x[i] = i * i; \
+ pred[i] = i % 3; \
+ } \
+ varithimm_##VALUE##_##TYPE (x, pred, N); \
+ for (int i = 0; i < N; ++i) \
+ { \
+ TYPE expected \
+ = i % 3 != 1 ? (x[i] < (TYPE) VALUE ? x[i] : (TYPE) VALUE) : 4; \
+ if (x[i] != expected) \
+ __builtin_abort (); \
+ asm volatile ("" ::: "memory"); \
+ } \
+ }
+
+int
+main (void)
+{
+ TEST_ALL (TEST_REGREG_OPS, TEST_IMMEDIATE_OPS)
+ return 0;
+}
\ No newline at end of file
diff --git a/gcc/testsuite/gcc.target/gcn/smax_1.c b/gcc/testsuite/gcc.target/gcn/smax_1.c
new file mode 100644
index 00000000000..46c21f73132
--- /dev/null
+++ b/gcc/testsuite/gcc.target/gcn/smax_1.c
@@ -0,0 +1,47 @@
+/* { dg-do compile } */
+/* { dg-options "-O2 -ftree-vectorize -dp" } */
+
+#include <stdint.h>
+
+#define DO_REGREG_OPS(TYPE) \
+ void __attribute__ ((noclone)) \
+ varith_##TYPE##_reg (TYPE *__restrict x, TYPE *__restrict y, int count) \
+ { \
+ for (int i = 0; i < count; ++i) \
+ x[i] = x[i] > y[i] ? x[i] : y[i]; \
+ }
+
+#define DO_IMMEDIATE_OPS(VALUE, TYPE, NAME) \
+ void __attribute__ ((noclone)) \
+ varithimm_##NAME##_##TYPE (TYPE *__restrict x, int count) \
+ { \
+ for (int i = 0; i < count; ++i) \
+ x[i] = x[i] > (TYPE) VALUE ? x[i] : (TYPE) VALUE; \
+ }
+
+#define DO_ARITH_OPS(REG, IMM, TYPE) \
+ REG (TYPE); \
+ IMM (0, TYPE, 0); \
+ IMM (86, TYPE, 86); \
+ IMM (109, TYPE, 109); \
+ IMM (141, TYPE, 141); \
+ IMM (92137445376, TYPE, 92137445376); \
+ IMM (-1, TYPE, minus1); \
+ IMM (-110, TYPE, minus110); \
+ IMM (-141, TYPE, minus141); \
+ IMM (-92137445376, TYPE, minus92137445376);
+
+#define TEST_ALL(REG, IMM) \
+ DO_ARITH_OPS (REG, IMM, int8_t) \
+ DO_ARITH_OPS (REG, IMM, int16_t) \
+ DO_ARITH_OPS (REG, IMM, int32_t) \
+ DO_ARITH_OPS (REG, IMM, int64_t)
+
+TEST_ALL (DO_REGREG_OPS, DO_IMMEDIATE_OPS)
+
+/* One per 64-bit test case: */
+/* { dg-final { scan-assembler-times {vec_cmpv64didi} 10 } } */
+
+/* Two per test case: */
+/* { dg-final { scan-assembler-times {\tv_cmp_gt_i64\tvcc, v[[0-9]+:[0-9]+], v[[0-9]+:[0-9]+]} 10 } } */
+/* { dg-final { scan-assembler-times {\tv_cmpx_gt_i32\tvcc, s[0-9]+, v[0-9]+} 80 } } */
\ No newline at end of file
diff --git a/gcc/testsuite/gcc.target/gcn/smax_1_run.c b/gcc/testsuite/gcc.target/gcn/smax_1_run.c
new file mode 100644
index 00000000000..4f975916229
--- /dev/null
+++ b/gcc/testsuite/gcc.target/gcn/smax_1_run.c
@@ -0,0 +1,48 @@
+/* { dg-do run } */
+/* { dg-options "-O2 -ftree-vectorize" } */
+
+#include "smax_1.c"
+
+#define N 99
+
+#define TEST_REGREG_OPS(TYPE) \
+ { \
+ TYPE x[N], y[N]; \
+ for (int i = 0; i < N; ++i) \
+ { \
+ x[i] = i % 13; \
+ y[i] = i * i; \
+ } \
+ varith_##TYPE##_reg (x, y, N); \
+ for (int i = 0; i < N; ++i) \
+ { \
+ TYPE expected = x[i] > y[i] ? x[i] : y[i]; \
+ if (x[i] != expected) \
+ __builtin_abort (); \
+ asm volatile ("" ::: "memory"); \
+ } \
+ }
+
+#define TEST_IMMEDIATE_OPS(VALUE, TYPE, NAME) \
+ { \
+ TYPE x[N], y[N]; \
+ for (int i = 0; i < N; ++i) \
+ { \
+ x[i] = i * i; \
+ } \
+ varithimm_##NAME##_##TYPE (x, N); \
+ for (int i = 0; i < N; ++i) \
+ { \
+ TYPE expected = x[i] > (TYPE) VALUE ? x[i] : (TYPE) VALUE; \
+ if (x[i] != expected) \
+ __builtin_abort (); \
+ asm volatile ("" ::: "memory"); \
+ } \
+ }
+
+int
+main (void)
+{
+ TEST_ALL (TEST_REGREG_OPS, TEST_IMMEDIATE_OPS)
+ return 0;
+}
\ No newline at end of file
diff --git a/gcc/testsuite/gcc.target/gcn/smin_1.c b/gcc/testsuite/gcc.target/gcn/smin_1.c
new file mode 100644
index 00000000000..8d6edfaa3d1
--- /dev/null
+++ b/gcc/testsuite/gcc.target/gcn/smin_1.c
@@ -0,0 +1,47 @@
+/* { dg-do compile } */
+/* { dg-options "-O2 -ftree-vectorize -dp" } */
+
+#include <stdint.h>
+
+#define DO_REGREG_OPS(TYPE) \
+ void __attribute__ ((noclone)) \
+ varith_##TYPE##_reg (TYPE *__restrict x, TYPE *__restrict y, int count) \
+ { \
+ for (int i = 0; i < count; ++i) \
+ x[i] = x[i] < y[i] ? x[i] : y[i]; \
+ }
+
+#define DO_IMMEDIATE_OPS(VALUE, TYPE, NAME) \
+ void __attribute__ ((noclone)) \
+ varithimm_##NAME##_##TYPE (TYPE *__restrict x, int count) \
+ { \
+ for (int i = 0; i < count; ++i) \
+ x[i] = x[i] < (TYPE) VALUE ? x[i] : (TYPE) VALUE; \
+ }
+
+#define DO_ARITH_OPS(REG, IMM, TYPE) \
+ REG (TYPE); \
+ IMM (0, TYPE, 0); \
+ IMM (86, TYPE, 86); \
+ IMM (109, TYPE, 109); \
+ IMM (141, TYPE, 141); \
+ IMM (92137445376, TYPE, 92137445376); \
+ IMM (-1, TYPE, minus1); \
+ IMM (-110, TYPE, minus110); \
+ IMM (-141, TYPE, minus141); \
+ IMM (-92137445376, TYPE, minus92137445376);
+
+#define TEST_ALL(REG, IMM) \
+ DO_ARITH_OPS (REG, IMM, int8_t) \
+ DO_ARITH_OPS (REG, IMM, int16_t) \
+ DO_ARITH_OPS (REG, IMM, int32_t) \
+ DO_ARITH_OPS (REG, IMM, int64_t)
+
+TEST_ALL (DO_REGREG_OPS, DO_IMMEDIATE_OPS)
+
+/* One per 64-bit test case: */
+/* { dg-final { scan-assembler-times {vec_cmpv64didi} 10 } } */
+/* { dg-final { scan-assembler-times {\tv_cmp_lt_i64\tvcc, v[[0-9]+:[0-9]+], v[[0-9]+:[0-9]+]} 10 } } */
+
+/* Two per test case:*/
+/* { dg-final { scan-assembler-times {\tv_cmpx_gt_i32\tvcc, s[0-9]+, v[0-9]+} 80 } } */
\ No newline at end of file
diff --git a/gcc/testsuite/gcc.target/gcn/smin_1_run.c b/gcc/testsuite/gcc.target/gcn/smin_1_run.c
new file mode 100644
index 00000000000..6758d571fe2
--- /dev/null
+++ b/gcc/testsuite/gcc.target/gcn/smin_1_run.c
@@ -0,0 +1,48 @@
+/* { dg-do run } */
+/* { dg-options "-O2 -ftree-vectorize" } */
+
+#include "smin_1.c"
+
+#define N 99
+
+#define TEST_REGREG_OPS(TYPE) \
+ { \
+ TYPE x[N], y[N]; \
+ for (int i = 0; i < N; ++i) \
+ { \
+ x[i] = i % 13; \
+ y[i] = i * i; \
+ } \
+ varith_##TYPE##_reg (x, y, N); \
+ for (int i = 0; i < N; ++i) \
+ { \
+ TYPE expected = x[i] < y[i] ? x[i] : y[i]; \
+ if (x[i] != expected) \
+ __builtin_abort (); \
+ asm volatile ("" ::: "memory"); \
+ } \
+ }
+
+#define TEST_IMMEDIATE_OPS(VALUE, TYPE, NAME) \
+ { \
+ TYPE x[N], y[N]; \
+ for (int i = 0; i < N; ++i) \
+ { \
+ x[i] = i * i; \
+ } \
+ varithimm_##NAME##_##TYPE (x, N); \
+ for (int i = 0; i < N; ++i) \
+ { \
+ TYPE expected = x[i] < (TYPE) VALUE ? x[i] : (TYPE) VALUE; \
+ if (x[i] != expected) \
+ __builtin_abort (); \
+ asm volatile ("" ::: "memory"); \
+ } \
+ }
+
+int
+main (void)
+{
+ TEST_ALL (TEST_REGREG_OPS, TEST_IMMEDIATE_OPS)
+ return 0;
+}
\ No newline at end of file
diff --git a/gcc/testsuite/gcc.target/gcn/umax_1.c b/gcc/testsuite/gcc.target/gcn/umax_1.c
new file mode 100644
index 00000000000..dc4b9842d9a
--- /dev/null
+++ b/gcc/testsuite/gcc.target/gcn/umax_1.c
@@ -0,0 +1,45 @@
+/* { dg-do compile } */
+/* { dg-options "-O2 -ftree-vectorize -dp" } */
+
+#include <stdint.h>
+
+#define DO_REGREG_OPS(TYPE) \
+ void __attribute__ ((noclone)) \
+ varith_##TYPE##_reg (TYPE *__restrict x, TYPE *__restrict y, int count) \
+ { \
+ for (int i = 0; i < count; ++i) \
+ x[i] = x[i] > y[i] ? x[i] : y[i]; \
+ }
+
+#define DO_IMMEDIATE_OPS(VALUE, TYPE) \
+ void __attribute__ ((noclone)) \
+ varithimm_##VALUE##_##TYPE (TYPE *__restrict x, int count) \
+ { \
+ for (int i = 0; i < count; ++i) \
+ x[i] = x[i] > (TYPE) VALUE ? x[i] : (TYPE) VALUE; \
+ }
+
+#define DO_ARITH_OPS(REG, IMM, TYPE) \
+ REG (TYPE); \
+ IMM (2, TYPE); \
+ IMM (86, TYPE); \
+ IMM (109, TYPE); \
+ IMM (141, TYPE); \
+ IMM (229, TYPE); \
+ IMM (255, TYPE); \
+ IMM (992137445376, TYPE);
+
+#define TEST_ALL(REG, IMM) \
+ DO_ARITH_OPS (REG, IMM, uint8_t) \
+ DO_ARITH_OPS (REG, IMM, uint16_t) \
+ DO_ARITH_OPS (REG, IMM, uint32_t) \
+ DO_ARITH_OPS (REG, IMM, uint64_t)
+
+TEST_ALL (DO_REGREG_OPS, DO_IMMEDIATE_OPS)
+
+/* One per 64-bit test case: */
+/* { dg-final { scan-assembler-times {vec_cmpv64didi} 8 } } */
+
+/* Two per test case with wide-enough type:*/
+/* { dg-final { scan-assembler-times {\tv_cmp_gt_u64\tvcc, v[[0-9]+:[0-9]+], v[[0-9]+:[0-9]+]} 8 } } */
+/* { dg-final { scan-assembler-times {\tv_cmpx_gt_i32\tvcc, s[0-9]+, v[0-9]+} 56 } } */
diff --git a/gcc/testsuite/gcc.target/gcn/umax_1_run.c b/gcc/testsuite/gcc.target/gcn/umax_1_run.c
new file mode 100644
index 00000000000..b8ff54044fd
--- /dev/null
+++ b/gcc/testsuite/gcc.target/gcn/umax_1_run.c
@@ -0,0 +1,48 @@
+/* { dg-do run } */
+/* { dg-options "-O2 -ftree-vectorize" } */
+
+#include "umax_1.c"
+
+#define N 99
+
+#define TEST_REGREG_OPS(TYPE) \
+ { \
+ TYPE x[N], y[N]; \
+ for (int i = 0; i < N; ++i) \
+ { \
+ x[i] = i % 13; \
+ y[i] = i * i; \
+ } \
+ varith_##TYPE##_reg (x, y, N); \
+ for (int i = 0; i < N; ++i) \
+ { \
+ TYPE expected = x[i] > y[i] ? x[i] : y[i]; \
+ if (x[i] != expected) \
+ __builtin_abort (); \
+ asm volatile ("" ::: "memory"); \
+ } \
+ }
+
+#define TEST_IMMEDIATE_OPS(VALUE, TYPE) \
+ { \
+ TYPE x[N], y[N]; \
+ for (int i = 0; i < N; ++i) \
+ { \
+ x[i] = i * i; \
+ } \
+ varithimm_##VALUE##_##TYPE (x, N); \
+ for (int i = 0; i < N; ++i) \
+ { \
+ TYPE expected = x[i] > (TYPE) VALUE ? x[i] : (TYPE) VALUE; \
+ if (x[i] != expected) \
+ __builtin_abort (); \
+ asm volatile ("" ::: "memory"); \
+ } \
+ }
+
+int
+main (void)
+{
+ TEST_ALL (TEST_REGREG_OPS, TEST_IMMEDIATE_OPS)
+ return 0;
+}
\ No newline at end of file
diff --git a/gcc/testsuite/gcc.target/gcn/umin_1.c b/gcc/testsuite/gcc.target/gcn/umin_1.c
new file mode 100644
index 00000000000..d07f7ec083b
--- /dev/null
+++ b/gcc/testsuite/gcc.target/gcn/umin_1.c
@@ -0,0 +1,45 @@
+/* { dg-do compile } */
+/* { dg-options "-O2 -ftree-vectorize -dp" } */
+
+#include <stdint.h>
+
+#define DO_REGREG_OPS(TYPE) \
+ void __attribute__ ((noclone)) \
+ varith_##TYPE##_reg (TYPE *__restrict x, TYPE *__restrict y, int count) \
+ { \
+ for (int i = 0; i < count; ++i) \
+ x[i] = x[i] < y[i] ? x[i] : y[i]; \
+ }
+
+#define DO_IMMEDIATE_OPS(VALUE, TYPE) \
+ void __attribute__ ((noclone)) \
+ varithimm_##VALUE##_##TYPE (TYPE *__restrict x, int count) \
+ { \
+ for (int i = 0; i < count; ++i) \
+ x[i] = x[i] < (TYPE) VALUE ? x[i] : (TYPE) VALUE; \
+ }
+
+#define DO_ARITH_OPS(REG, IMM, TYPE) \
+ REG (TYPE); \
+ IMM (2, TYPE); \
+ IMM (86, TYPE); \
+ IMM (109, TYPE); \
+ IMM (141, TYPE); \
+ IMM (229, TYPE); \
+ IMM (255, TYPE); \
+ IMM (992137445376, TYPE);
+
+#define TEST_ALL(REG, IMM) \
+ DO_ARITH_OPS (REG, IMM, uint8_t) \
+ DO_ARITH_OPS (REG, IMM, uint16_t) \
+ DO_ARITH_OPS (REG, IMM, uint32_t) \
+ DO_ARITH_OPS (REG, IMM, uint64_t)
+
+TEST_ALL (DO_REGREG_OPS, DO_IMMEDIATE_OPS)
+
+/* One per 64-bit test case: */
+/* { dg-final { scan-assembler-times {vec_cmpv64didi} 8 } } */
+/* { dg-final { scan-assembler-times {\tv_cmp_lt_u64\tvcc, v[[0-9]+:[0-9]+], v[[0-9]+:[0-9]+]} 8 } } */
+
+/* Two per test case with wide-enough type:*/
+/* { dg-final { scan-assembler-times {\tv_cmpx_gt_i32\tvcc, s[0-9]+, v[0-9]+} 56 } } */
diff --git a/gcc/testsuite/gcc.target/gcn/umin_1_run.c b/gcc/testsuite/gcc.target/gcn/umin_1_run.c
new file mode 100644
index 00000000000..a15d7b3982a
--- /dev/null
+++ b/gcc/testsuite/gcc.target/gcn/umin_1_run.c
@@ -0,0 +1,48 @@
+/* { dg-do run } */
+/* { dg-options "-O2 -ftree-vectorize" } */
+
+#include "umin_1.c"
+
+#define N 99
+
+#define TEST_REGREG_OPS(TYPE) \
+ { \
+ TYPE x[N], y[N]; \
+ for (int i = 0; i < N; ++i) \
+ { \
+ x[i] = i % 13; \
+ y[i] = i * i; \
+ } \
+ varith_##TYPE##_reg (x, y, N); \
+ for (int i = 0; i < N; ++i) \
+ { \
+ TYPE expected = x[i] < y[i] ? x[i] : y[i]; \
+ if (x[i] != expected) \
+ __builtin_abort (); \
+ asm volatile ("" ::: "memory"); \
+ } \
+ }
+
+#define TEST_IMMEDIATE_OPS(VALUE, TYPE) \
+ { \
+ TYPE x[N], y[N]; \
+ for (int i = 0; i < N; ++i) \
+ { \
+ x[i] = i * i; \
+ } \
+ varithimm_##VALUE##_##TYPE (x, N); \
+ for (int i = 0; i < N; ++i) \
+ { \
+ TYPE expected = x[i] < (TYPE) VALUE ? x[i] : (TYPE) VALUE; \
+ if (x[i] != expected) \
+ __builtin_abort (); \
+ asm volatile ("" ::: "memory"); \
+ } \
+ }
+
+int
+main (void)
+{
+ TEST_ALL (TEST_REGREG_OPS, TEST_IMMEDIATE_OPS)
+ return 0;
+}
\ No newline at end of file
^ permalink raw reply [flat|nested] only message in thread
only message in thread, other threads:[~2023-03-06 15:01 UTC | newest]
Thread overview: (only message) (download: mbox.gz / follow: Atom feed)
-- links below jump to the message on this page --
2023-03-06 15:01 [gcc/devel/omp/gcc-12] amdgcn: Add instruction patterns for conditional min/max operations Paul-Antoine Arras
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).