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.
This commit is contained in:
Paul-Antoine Arras
2023-03-01 17:20:21 +01:00
parent 14e5b65fd9
commit 553ff2524f
50 changed files with 1381 additions and 2 deletions
+136 -1
View File
@@ -2358,6 +2358,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
@@ -2370,6 +2398,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
@@ -3468,7 +3561,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>"
+1 -1
View File
@@ -798,7 +798,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;
@@ -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_..} } } */
@@ -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;
}
@@ -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_..} } } */
@@ -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;
}
@@ -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_..} } } */
@@ -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;
}
@@ -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_..} } } */
@@ -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;
}
@@ -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_..} } } */
@@ -0,0 +1,4 @@
/* { dg-do run } */
/* { dg-options "-O2 -ftree-vectorize" } */
#include "cond_fmaxnm_1_run.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_..} } } */
@@ -0,0 +1,4 @@
/* { dg-do run } */
/* { dg-options "-O2 -ftree-vectorize" } */
#include "cond_fmaxnm_2_run.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_..} } } */
@@ -0,0 +1,4 @@
/* { dg-do run } */
/* { dg-options "-O2 -ftree-vectorize" } */
#include "cond_fmaxnm_3_run.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_..} } } */
@@ -0,0 +1,4 @@
/* { dg-do run } */
/* { dg-options "-O2 -ftree-vectorize" } */
#include "cond_fmaxnm_4_run.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_..} } } */
@@ -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"
@@ -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_..} } } */
@@ -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"
@@ -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_..} } } */
@@ -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"
@@ -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_..} } } */
@@ -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"
@@ -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_..} } } */
@@ -0,0 +1,4 @@
/* { dg-do run } */
/* { dg-options "-O2 -ftree-vectorize" } */
#include "cond_fminnm_1_run.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_..} } } */
@@ -0,0 +1,4 @@
/* { dg-do run } */
/* { dg-options "-O2 -ftree-vectorize" } */
#include "cond_fminnm_2_run.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_..} } } */
@@ -0,0 +1,4 @@
/* { dg-do run } */
/* { dg-options "-O2 -ftree-vectorize" } */
#include "cond_fminnm_3_run.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_..} } } */
@@ -0,0 +1,4 @@
/* { dg-do run } */
/* { dg-options "-O2 -ftree-vectorize" } */
#include "cond_fminnm_4_run.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 } } */
@@ -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;
}
@@ -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 } } */
@@ -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;
}
@@ -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 } } */
@@ -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;
}
@@ -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 } } */
@@ -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;
}
+47
View File
@@ -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 } } */
+48
View File
@@ -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;
}
+47
View File
@@ -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 } } */
+48
View File
@@ -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;
}
+45
View File
@@ -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 } } */
+48
View File
@@ -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;
}
+45
View File
@@ -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 } } */
+48
View File
@@ -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;
}