aboutsummaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorRobin Dapp <rdapp@linux.ibm.com>2022-08-22 11:05:39 +0200
committerRobin Dapp <rdapp@linux.ibm.com>2023-03-02 15:34:23 +0100
commitda19e37cedc2acd1c560012dc41a57b7145dc181 (patch)
tree869ce374c83db14908f6632d13aa04617945c53d
parent61407e018940633a9ca997bf3773f794faa25e23 (diff)
downloadgcc-da19e37cedc2acd1c560012dc41a57b7145dc181.zip
gcc-da19e37cedc2acd1c560012dc41a57b7145dc181.tar.gz
gcc-da19e37cedc2acd1c560012dc41a57b7145dc181.tar.bz2
s390: Add LEN_LOAD/LEN_STORE support.
This patch adds LEN_LOAD/LEN_STORE support for z13 and newer. It defines a bias value of -1 and implements the LEN_LOAD and LEN_STORE optabs. Add vll/vstl testcases adapted from Power. Also change expectations for SLP testcases with more than one rgroup. gcc/ChangeLog: * config/s390/predicates.md (vll_bias_operand): Add -1 bias. * config/s390/s390.cc (s390_option_override_internal): Make partial vector usage the default from z13 on. * config/s390/vector.md (len_load_v16qi): Add. (len_store_v16qi): Add. gcc/testsuite/ChangeLog: * gcc.target/s390/s390.exp: Add partial subdirectory. * gcc.target/s390/vector/vec-nopeel-2.c: Change test expectation. * lib/target-supports.exp: Add s390. * gcc.target/s390/vector/partial/s390-vec-length-1.h: New test. * gcc.target/s390/vector/partial/s390-vec-length-2.h: New test. * gcc.target/s390/vector/partial/s390-vec-length-3.h: New test. * gcc.target/s390/vector/partial/s390-vec-length-7.h: New test. * gcc.target/s390/vector/partial/s390-vec-length-epil-1.c: New test. * gcc.target/s390/vector/partial/s390-vec-length-epil-2.c: New test. * gcc.target/s390/vector/partial/s390-vec-length-epil-3.c: New test. * gcc.target/s390/vector/partial/s390-vec-length-epil-7.c: New test. * gcc.target/s390/vector/partial/s390-vec-length-epil-run-1.c: New test. * gcc.target/s390/vector/partial/s390-vec-length-epil-run-2.c: New test. * gcc.target/s390/vector/partial/s390-vec-length-epil-run-3.c: New test. * gcc.target/s390/vector/partial/s390-vec-length-epil-run-7.c: New test. * gcc.target/s390/vector/partial/s390-vec-length-full-1.c: New test. * gcc.target/s390/vector/partial/s390-vec-length-full-2.c: New test. * gcc.target/s390/vector/partial/s390-vec-length-full-3.c: New test. * gcc.target/s390/vector/partial/s390-vec-length-full-7.c: New test. * gcc.target/s390/vector/partial/s390-vec-length-full-run-1.c: New test. * gcc.target/s390/vector/partial/s390-vec-length-full-run-2.c: New test. * gcc.target/s390/vector/partial/s390-vec-length-full-run-3.c: New test. * gcc.target/s390/vector/partial/s390-vec-length-full-run-7.c: New test. * gcc.target/s390/vector/partial/s390-vec-length-run-1.h: New test. * gcc.target/s390/vector/partial/s390-vec-length-run-2.h: New test. * gcc.target/s390/vector/partial/s390-vec-length-run-3.h: New test. * gcc.target/s390/vector/partial/s390-vec-length-run-7.h: New test. * gcc.target/s390/vector/partial/s390-vec-length-small.c: New test. * gcc.target/s390/vector/partial/s390-vec-length.h: New test.
-rw-r--r--gcc/config/s390/predicates.md8
-rw-r--r--gcc/config/s390/s390.cc9
-rw-r--r--gcc/config/s390/vector.md35
-rw-r--r--gcc/testsuite/gcc.target/s390/s390.exp3
-rw-r--r--gcc/testsuite/gcc.target/s390/vector/partial/s390-vec-length-1.h18
-rw-r--r--gcc/testsuite/gcc.target/s390/vector/partial/s390-vec-length-2.h18
-rw-r--r--gcc/testsuite/gcc.target/s390/vector/partial/s390-vec-length-3.h31
-rw-r--r--gcc/testsuite/gcc.target/s390/vector/partial/s390-vec-length-7.h17
-rw-r--r--gcc/testsuite/gcc.target/s390/vector/partial/s390-vec-length-epil-1.c13
-rw-r--r--gcc/testsuite/gcc.target/s390/vector/partial/s390-vec-length-epil-2.c13
-rw-r--r--gcc/testsuite/gcc.target/s390/vector/partial/s390-vec-length-epil-3.c16
-rw-r--r--gcc/testsuite/gcc.target/s390/vector/partial/s390-vec-length-epil-7.c11
-rw-r--r--gcc/testsuite/gcc.target/s390/vector/partial/s390-vec-length-epil-run-1.c7
-rw-r--r--gcc/testsuite/gcc.target/s390/vector/partial/s390-vec-length-epil-run-2.c7
-rw-r--r--gcc/testsuite/gcc.target/s390/vector/partial/s390-vec-length-epil-run-3.c7
-rw-r--r--gcc/testsuite/gcc.target/s390/vector/partial/s390-vec-length-epil-run-7.c7
-rw-r--r--gcc/testsuite/gcc.target/s390/vector/partial/s390-vec-length-full-1.c12
-rw-r--r--gcc/testsuite/gcc.target/s390/vector/partial/s390-vec-length-full-2.c12
-rw-r--r--gcc/testsuite/gcc.target/s390/vector/partial/s390-vec-length-full-3.c13
-rw-r--r--gcc/testsuite/gcc.target/s390/vector/partial/s390-vec-length-full-7.c14
-rw-r--r--gcc/testsuite/gcc.target/s390/vector/partial/s390-vec-length-full-run-1.c7
-rw-r--r--gcc/testsuite/gcc.target/s390/vector/partial/s390-vec-length-full-run-2.c7
-rw-r--r--gcc/testsuite/gcc.target/s390/vector/partial/s390-vec-length-full-run-3.c7
-rw-r--r--gcc/testsuite/gcc.target/s390/vector/partial/s390-vec-length-full-run-7.c7
-rw-r--r--gcc/testsuite/gcc.target/s390/vector/partial/s390-vec-length-run-1.h34
-rw-r--r--gcc/testsuite/gcc.target/s390/vector/partial/s390-vec-length-run-2.h36
-rw-r--r--gcc/testsuite/gcc.target/s390/vector/partial/s390-vec-length-run-3.h34
-rw-r--r--gcc/testsuite/gcc.target/s390/vector/partial/s390-vec-length-run-7.h16
-rw-r--r--gcc/testsuite/gcc.target/s390/vector/partial/s390-vec-length-small.c15
-rw-r--r--gcc/testsuite/gcc.target/s390/vector/partial/s390-vec-length.h14
-rw-r--r--gcc/testsuite/gcc.target/s390/vector/vec-nopeel-2.c2
-rw-r--r--gcc/testsuite/lib/target-supports.exp3
32 files changed, 450 insertions, 3 deletions
diff --git a/gcc/config/s390/predicates.md b/gcc/config/s390/predicates.md
index d5d5a7c..0c36919 100644
--- a/gcc/config/s390/predicates.md
+++ b/gcc/config/s390/predicates.md
@@ -606,3 +606,11 @@
(and (match_code "reg")
(match_test "reload_completed || reload_in_progress")
(match_test "register_operand (op, GET_MODE (op))"))))
+
+; Bias value for LEN_LOAD and LEN_STORE. The bias will be added to the
+; length (in bytes for s390) to be loaded. vll/vstl expect the lowest byte
+; to load while LEN_LOAD/LEN_STORE use the actual length in bytes. This implies
+; that we cannot load a length of 0.
+(define_predicate "vll_bias_operand"
+ (and (match_code "const_int")
+ (match_test "op == CONSTM1_RTX (QImode)")))
diff --git a/gcc/config/s390/s390.cc b/gcc/config/s390/s390.cc
index b66edf0..505de99 100644
--- a/gcc/config/s390/s390.cc
+++ b/gcc/config/s390/s390.cc
@@ -15857,6 +15857,14 @@ s390_option_override_internal (struct gcc_options *opts,
/* Use the alternative scheduling-pressure algorithm by default. */
SET_OPTION_IF_UNSET (opts, opts_set, param_sched_pressure_algorithm, 2);
+
+ /* Allow simple vector masking using vll/vstl for epilogues. */
+ if (TARGET_Z13)
+ SET_OPTION_IF_UNSET (opts, opts_set, param_vect_partial_vector_usage, 1);
+ else
+ SET_OPTION_IF_UNSET (opts, opts_set, param_vect_partial_vector_usage, 0);
+
+ /* Do not vectorize loops with a low trip count for now. */
SET_OPTION_IF_UNSET (opts, opts_set, param_min_vect_loop_bound, 2);
/* Set the default alignment. */
@@ -17825,7 +17833,6 @@ s390_vectorize_vec_perm_const (machine_mode vmode, machine_mode op_mode,
#undef TARGET_VECTORIZE_VEC_PERM_CONST
#define TARGET_VECTORIZE_VEC_PERM_CONST s390_vectorize_vec_perm_const
-
struct gcc_target targetm = TARGET_INITIALIZER;
#include "gt-s390.h"
diff --git a/gcc/config/s390/vector.md b/gcc/config/s390/vector.md
index 08e0b68..21bec729 100644
--- a/gcc/config/s390/vector.md
+++ b/gcc/config/s390/vector.md
@@ -2947,6 +2947,41 @@
""
[(set_attr "op_type" "*,VRX,VRX")])
+;
+; Implement len_load/len_store optabs with vll/vstl.
+(define_expand "len_load_v16qi"
+ [(match_operand:V16QI 0 "register_operand")
+ (match_operand:V16QI 1 "memory_operand")
+ (match_operand:QI 2 "register_operand")
+ (match_operand:QI 3 "vll_bias_operand")
+ ]
+ "TARGET_VX && TARGET_64BIT"
+{
+ rtx mem = adjust_address (operands[1], BLKmode, 0);
+
+ rtx len = gen_reg_rtx (SImode);
+ emit_move_insn (len, gen_rtx_ZERO_EXTEND (SImode, operands[2]));
+ emit_insn (gen_vllv16qi (operands[0], len, mem));
+ DONE;
+})
+
+(define_expand "len_store_v16qi"
+ [(match_operand:V16QI 0 "memory_operand")
+ (match_operand:V16QI 1 "register_operand")
+ (match_operand:QI 2 "register_operand")
+ (match_operand:QI 3 "vll_bias_operand")
+ ]
+ "TARGET_VX && TARGET_64BIT"
+{
+ rtx mem = adjust_address (operands[0], BLKmode, 0);
+
+ rtx len = gen_reg_rtx (SImode);
+ emit_move_insn (len, gen_rtx_ZERO_EXTEND (SImode, operands[2]));
+ emit_insn (gen_vstlv16qi (operands[1], len, mem));
+ DONE;
+});;
+
+
; reduc_smin
; reduc_smax
; reduc_umin
diff --git a/gcc/testsuite/gcc.target/s390/s390.exp b/gcc/testsuite/gcc.target/s390/s390.exp
index 5045b48..5825849 100644
--- a/gcc/testsuite/gcc.target/s390/s390.exp
+++ b/gcc/testsuite/gcc.target/s390/s390.exp
@@ -236,6 +236,9 @@ dg-runtest [lsort [prune [glob -nocomplain $srcdir/$subdir/*.{c,S}] \
dg-runtest [lsort [glob -nocomplain $srcdir/$subdir/*vector*/*.{c,S}]] \
"" $DEFAULT_CFLAGS
+dg-runtest [lsort [glob -nocomplain $srcdir/$subdir/*vector*/partial/*.{c,S}]] \
+ "" $DEFAULT_CFLAGS
+
gfortran-dg-runtest [lsort [glob -nocomplain $srcdir/$subdir/*vector*/*.F90]] \
"" $DEFAULT_FFLAGS
diff --git a/gcc/testsuite/gcc.target/s390/vector/partial/s390-vec-length-1.h b/gcc/testsuite/gcc.target/s390/vector/partial/s390-vec-length-1.h
new file mode 100644
index 0000000..5a27c32
--- /dev/null
+++ b/gcc/testsuite/gcc.target/s390/vector/partial/s390-vec-length-1.h
@@ -0,0 +1,18 @@
+#include "s390-vec-length.h"
+
+/* Test the case loop iteration is known. */
+
+#define N 127
+
+#define test(TYPE) \
+ extern TYPE a_##TYPE[N]; \
+ extern TYPE b_##TYPE[N]; \
+ extern TYPE c_##TYPE[N]; \
+ void __attribute__ ((noinline, noclone)) test##TYPE () \
+ { \
+ unsigned int i = 0; \
+ for (i = 0; i < N; i++) \
+ c_##TYPE[i] = a_##TYPE[i] + b_##TYPE[i]; \
+ }
+
+TEST_ALL (test)
diff --git a/gcc/testsuite/gcc.target/s390/vector/partial/s390-vec-length-2.h b/gcc/testsuite/gcc.target/s390/vector/partial/s390-vec-length-2.h
new file mode 100644
index 0000000..a9a188c
--- /dev/null
+++ b/gcc/testsuite/gcc.target/s390/vector/partial/s390-vec-length-2.h
@@ -0,0 +1,18 @@
+#include "s390-vec-length.h"
+
+/* Test the case loop iteration is unknown. */
+
+#define N 255
+
+#define test(TYPE) \
+ extern TYPE a_##TYPE[N]; \
+ extern TYPE b_##TYPE[N]; \
+ extern TYPE c_##TYPE[N]; \
+ void __attribute__ ((noinline, noclone)) test##TYPE (unsigned int n) \
+ { \
+ unsigned int i = 0; \
+ for (i = 0; i < n; i++) \
+ c_##TYPE[i] = a_##TYPE[i] + b_##TYPE[i]; \
+ }
+
+TEST_ALL (test)
diff --git a/gcc/testsuite/gcc.target/s390/vector/partial/s390-vec-length-3.h b/gcc/testsuite/gcc.target/s390/vector/partial/s390-vec-length-3.h
new file mode 100644
index 0000000..30d7c38
--- /dev/null
+++ b/gcc/testsuite/gcc.target/s390/vector/partial/s390-vec-length-3.h
@@ -0,0 +1,31 @@
+#include "s390-vec-length.h"
+
+/* Test the case loop iteration less than VF. */
+
+/* For char. */
+#define N_uint8_t 15
+#define N_int8_t 15
+/* For short. */
+#define N_uint16_t 6
+#define N_int16_t 6
+/* For int/float. */
+#define N_uint32_t 3
+#define N_int32_t 3
+#define N_float 3
+/* For long/double. */
+#define N_uint64_t 1
+#define N_int64_t 1
+#define N_double 1
+
+#define test(TYPE) \
+ extern TYPE a_##TYPE[N_##TYPE]; \
+ extern TYPE b_##TYPE[N_##TYPE]; \
+ extern TYPE c_##TYPE[N_##TYPE]; \
+ void __attribute__ ((noinline, noclone)) test##TYPE () \
+ { \
+ unsigned int i = 0; \
+ for (i = 0; i < N_##TYPE; i++) \
+ c_##TYPE[i] = a_##TYPE[i] + b_##TYPE[i]; \
+ }
+
+TEST_ALL (test)
diff --git a/gcc/testsuite/gcc.target/s390/vector/partial/s390-vec-length-7.h b/gcc/testsuite/gcc.target/s390/vector/partial/s390-vec-length-7.h
new file mode 100644
index 0000000..e441bf6
--- /dev/null
+++ b/gcc/testsuite/gcc.target/s390/vector/partial/s390-vec-length-7.h
@@ -0,0 +1,17 @@
+#include "s390-vec-length.h"
+
+#define N 64
+#define START 1
+#define END 59
+
+#define test(TYPE) \
+ TYPE x_##TYPE[N] __attribute__((aligned(16))); \
+ void __attribute__((noinline, noclone)) test_npeel_##TYPE() { \
+ TYPE v = 0; \
+ for (unsigned int i = START; i < END; i++) { \
+ x_##TYPE[i] = v; \
+ v += 1; \
+ } \
+ }
+
+TEST_ALL (test)
diff --git a/gcc/testsuite/gcc.target/s390/vector/partial/s390-vec-length-epil-1.c b/gcc/testsuite/gcc.target/s390/vector/partial/s390-vec-length-epil-1.c
new file mode 100644
index 0000000..ca844f7
--- /dev/null
+++ b/gcc/testsuite/gcc.target/s390/vector/partial/s390-vec-length-epil-1.c
@@ -0,0 +1,13 @@
+/* { dg-do compile { target { lp64 && s390_vx } } } */
+/* { dg-options "-march=native -O2 -ftree-vectorize -fno-vect-cost-model -fno-unroll-loops -fno-trapping-math" } */
+
+/* { dg-additional-options "--param=vect-partial-vector-usage=1 --param=min-vect-loop-bound=0" } */
+
+/* Test that we only vectorize the epilogue with vector load/store with length,
+ the main body still uses normal vector load/store. */
+
+#include "s390-vec-length-1.h"
+
+/* { dg-final { scan-assembler-times {\mvll\M} 14 } } */
+/* { dg-final { scan-assembler-times {\mvstl\M} 7 } } */
+
diff --git a/gcc/testsuite/gcc.target/s390/vector/partial/s390-vec-length-epil-2.c b/gcc/testsuite/gcc.target/s390/vector/partial/s390-vec-length-epil-2.c
new file mode 100644
index 0000000..31850f8
--- /dev/null
+++ b/gcc/testsuite/gcc.target/s390/vector/partial/s390-vec-length-epil-2.c
@@ -0,0 +1,13 @@
+/* { dg-do compile { target { lp64 && s390_vx } } } */
+/* { dg-options "-march=native -O2 -ftree-vectorize -fno-vect-cost-model -fno-unroll-loops -fno-trapping-math" } */
+
+/* { dg-additional-options "--param=vect-partial-vector-usage=1 --param=min-vect-loop-bound=0" } */
+
+/* Test that we only vectorize the epilogue with vector load/store with length,
+ the main body still uses normal vector load/store. */
+
+#include "s390-vec-length-2.h"
+
+/* { dg-final { scan-assembler-times {\mvll\M} 20 } } */
+/* { dg-final { scan-assembler-times {\mvstl\M} 10 } } */
+
diff --git a/gcc/testsuite/gcc.target/s390/vector/partial/s390-vec-length-epil-3.c b/gcc/testsuite/gcc.target/s390/vector/partial/s390-vec-length-epil-3.c
new file mode 100644
index 0000000..4e342de
--- /dev/null
+++ b/gcc/testsuite/gcc.target/s390/vector/partial/s390-vec-length-epil-3.c
@@ -0,0 +1,16 @@
+/* { dg-do compile { target { lp64 && s390_vx } } } */
+/* { dg-options "-march=native -O2 -ftree-vectorize -fno-vect-cost-model -fno-unroll-loops -fno-trapping-math" } */
+
+/* { dg-additional-options "--param=vect-partial-vector-usage=1 --param=min-vect-loop-bound=0" } */
+
+/* Test that we only vectorize the epilogue with vector load/store with length,
+ the main body still uses normal vector load/store. */
+
+#include "s390-vec-length-3.h"
+
+/* { dg-final { scan-assembler-not {\mvl\M} } } */
+/* { dg-final { scan-assembler-not {\mvst\M} } } */
+/* 64bit types get completely unrolled, so only check the others. */
+/* { dg-final { scan-assembler-times {\mvll\M} 14 } } */
+/* { dg-final { scan-assembler-times {\mvstl\M} 7 } } */
+
diff --git a/gcc/testsuite/gcc.target/s390/vector/partial/s390-vec-length-epil-7.c b/gcc/testsuite/gcc.target/s390/vector/partial/s390-vec-length-epil-7.c
new file mode 100644
index 0000000..c85c93e
--- /dev/null
+++ b/gcc/testsuite/gcc.target/s390/vector/partial/s390-vec-length-epil-7.c
@@ -0,0 +1,11 @@
+/* { dg-do compile { target { lp64 && s390_vx } } } */
+/* { dg-options "-march=native -O2 -ftree-vectorize -fno-vect-cost-model -fno-unroll-loops -ffast-math -fno-trapping-math" } */
+
+/* { dg-additional-options "--param=vect-partial-vector-usage=1 --param=min-vect-loop-bound=0" } */
+
+/* Test that we only vectorize the epilogue with vector load/store with length,
+ the main body still uses normal vector load/store. */
+
+#include "s390-vec-length-7.h"
+
+/* { dg-final { scan-assembler-times {\mvstl\M} 4 } } */
diff --git a/gcc/testsuite/gcc.target/s390/vector/partial/s390-vec-length-epil-run-1.c b/gcc/testsuite/gcc.target/s390/vector/partial/s390-vec-length-epil-run-1.c
new file mode 100644
index 0000000..83d9864
--- /dev/null
+++ b/gcc/testsuite/gcc.target/s390/vector/partial/s390-vec-length-epil-run-1.c
@@ -0,0 +1,7 @@
+/* { dg-do run { target { lp64 && s390_vx } } } */
+/* { dg-options "-march=native -O2 -ftree-vectorize -fno-vect-cost-model -fno-trapping-math" } */
+
+/* { dg-additional-options "--param=vect-partial-vector-usage=1" } */
+
+#include "s390-vec-length-run-1.h"
+
diff --git a/gcc/testsuite/gcc.target/s390/vector/partial/s390-vec-length-epil-run-2.c b/gcc/testsuite/gcc.target/s390/vector/partial/s390-vec-length-epil-run-2.c
new file mode 100644
index 0000000..8b3b195
--- /dev/null
+++ b/gcc/testsuite/gcc.target/s390/vector/partial/s390-vec-length-epil-run-2.c
@@ -0,0 +1,7 @@
+/* { dg-do run { target { lp64 && s390_vx } } } */
+/* { dg-options "-march=native -O2 -ftree-vectorize -fno-vect-cost-model -fno-trapping-math" } */
+
+/* { dg-additional-options "--param=vect-partial-vector-usage=1" } */
+
+#include "s390-vec-length-run-2.h"
+
diff --git a/gcc/testsuite/gcc.target/s390/vector/partial/s390-vec-length-epil-run-3.c b/gcc/testsuite/gcc.target/s390/vector/partial/s390-vec-length-epil-run-3.c
new file mode 100644
index 0000000..f2f94ef
--- /dev/null
+++ b/gcc/testsuite/gcc.target/s390/vector/partial/s390-vec-length-epil-run-3.c
@@ -0,0 +1,7 @@
+/* { dg-do run { target { lp64 && s390_vx } } } */
+/* { dg-options "-march=native -O2 -ftree-vectorize -fno-vect-cost-model -fno-trapping-math" } */
+
+/* { dg-additional-options "--param=vect-partial-vector-usage=1" } */
+
+#include "s390-vec-length-run-3.h"
+
diff --git a/gcc/testsuite/gcc.target/s390/vector/partial/s390-vec-length-epil-run-7.c b/gcc/testsuite/gcc.target/s390/vector/partial/s390-vec-length-epil-run-7.c
new file mode 100644
index 0000000..c1f58c3
--- /dev/null
+++ b/gcc/testsuite/gcc.target/s390/vector/partial/s390-vec-length-epil-run-7.c
@@ -0,0 +1,7 @@
+/* { dg-do run { target { lp64 && s390_vx } } } */
+/* { dg-options "-march=native -O2 -ftree-vectorize -fno-vect-cost-model -ffast-math -fno-trapping-math" } */
+
+/* { dg-additional-options "--param=vect-partial-vector-usage=1" } */
+
+#include "s390-vec-length-run-7.h"
+
diff --git a/gcc/testsuite/gcc.target/s390/vector/partial/s390-vec-length-full-1.c b/gcc/testsuite/gcc.target/s390/vector/partial/s390-vec-length-full-1.c
new file mode 100644
index 0000000..0ff86e7
--- /dev/null
+++ b/gcc/testsuite/gcc.target/s390/vector/partial/s390-vec-length-full-1.c
@@ -0,0 +1,12 @@
+/* { dg-do compile { target { lp64 && s390_vx } } } */
+/* { dg-options "-march=native -O2 -ftree-vectorize -fno-vect-cost-model -fno-unroll-loops -fno-trapping-math" } */
+
+/* { dg-additional-options "--param=vect-partial-vector-usage=2" } */
+
+/* Test that the loop body uses vector load/store with length,
+ there should not be any epilogues. */
+
+#include "s390-vec-length-1.h"
+
+/* { dg-final { scan-assembler-times {\mvll\M} 20 } } */
+/* { dg-final { scan-assembler-times {\mvstl\M} 10 } } */
diff --git a/gcc/testsuite/gcc.target/s390/vector/partial/s390-vec-length-full-2.c b/gcc/testsuite/gcc.target/s390/vector/partial/s390-vec-length-full-2.c
new file mode 100644
index 0000000..f47fb89
--- /dev/null
+++ b/gcc/testsuite/gcc.target/s390/vector/partial/s390-vec-length-full-2.c
@@ -0,0 +1,12 @@
+/* { dg-do compile { target { lp64 && s390_vx } } } */
+/* { dg-options "-march=native -O2 -ftree-vectorize -fno-vect-cost-model -fno-unroll-loops -fno-trapping-math" } */
+
+/* { dg-additional-options "--param=vect-partial-vector-usage=2" } */
+
+/* Test that the loop body uses vector load/store with length,
+ there should not be any epilogues. */
+
+#include "s390-vec-length-2.h"
+
+/* { dg-final { scan-assembler-times {\mvll\M} 20 } } */
+/* { dg-final { scan-assembler-times {\mvstl\M} 10 } } */
diff --git a/gcc/testsuite/gcc.target/s390/vector/partial/s390-vec-length-full-3.c b/gcc/testsuite/gcc.target/s390/vector/partial/s390-vec-length-full-3.c
new file mode 100644
index 0000000..086185f
--- /dev/null
+++ b/gcc/testsuite/gcc.target/s390/vector/partial/s390-vec-length-full-3.c
@@ -0,0 +1,13 @@
+/* { dg-do compile { target { lp64 && s390_vx } } } */
+/* { dg-options "-march=native -O2 -ftree-vectorize -fno-vect-cost-model -fno-unroll-loops -fno-trapping-math" } */
+
+/* { dg-additional-options "--param=vect-partial-vector-usage=2 --param=min-vect-loop-bound=0" } */
+
+/* Test that the loop body uses vector load/store with length,
+ there should not be any epilogues. */
+
+#include "s390-vec-length-3.h"
+
+/* 64bit types get completely unrolled, so only check the others. */
+/* { dg-final { scan-assembler-times {\mvll\M} 14 } } */
+/* { dg-final { scan-assembler-times {\mvstl\M} 7 } } */
diff --git a/gcc/testsuite/gcc.target/s390/vector/partial/s390-vec-length-full-7.c b/gcc/testsuite/gcc.target/s390/vector/partial/s390-vec-length-full-7.c
new file mode 100644
index 0000000..23856e1
--- /dev/null
+++ b/gcc/testsuite/gcc.target/s390/vector/partial/s390-vec-length-full-7.c
@@ -0,0 +1,14 @@
+/* { dg-do compile { target { lp64 && s390_vx } } } */
+/* { dg-options "-march=native -O2 -ftree-vectorize -fno-vect-cost-model -fno-unroll-loops -fno-trapping-math" } */
+
+/* { dg-additional-options "--param=vect-partial-vector-usage=2" } */
+
+/* Test that the loop body uses vector load/store with length,
+ there should not be any epilogues. */
+
+#include "s390-vec-length-7.h"
+
+/* Each type should have one vstl but we do not currently vectorize the
+ float and double variants and the [u]int64_t ones which do not require
+ partial vectors. */
+/* { dg-final { scan-assembler-times {\mvstl\M} 6 } } */
diff --git a/gcc/testsuite/gcc.target/s390/vector/partial/s390-vec-length-full-run-1.c b/gcc/testsuite/gcc.target/s390/vector/partial/s390-vec-length-full-run-1.c
new file mode 100644
index 0000000..b064706
--- /dev/null
+++ b/gcc/testsuite/gcc.target/s390/vector/partial/s390-vec-length-full-run-1.c
@@ -0,0 +1,7 @@
+/* { dg-do run { target { lp64 && s390_vx } } } */
+/* { dg-options "-march=native -O2 -ftree-vectorize -fno-vect-cost-model -fno-trapping-math" } */
+
+/* { dg-additional-options "--param=vect-partial-vector-usage=2" } */
+
+#include "s390-vec-length-run-1.h"
+
diff --git a/gcc/testsuite/gcc.target/s390/vector/partial/s390-vec-length-full-run-2.c b/gcc/testsuite/gcc.target/s390/vector/partial/s390-vec-length-full-run-2.c
new file mode 100644
index 0000000..c9a4ae8
--- /dev/null
+++ b/gcc/testsuite/gcc.target/s390/vector/partial/s390-vec-length-full-run-2.c
@@ -0,0 +1,7 @@
+/* { dg-do run { target { lp64 && s390_vx } } } */
+/* { dg-options "-march=native -O2 -ftree-vectorize -fno-vect-cost-model -fno-trapping-math" } */
+
+/* { dg-additional-options "--param=vect-partial-vector-usage=2" } */
+
+#include "s390-vec-length-run-2.h"
+
diff --git a/gcc/testsuite/gcc.target/s390/vector/partial/s390-vec-length-full-run-3.c b/gcc/testsuite/gcc.target/s390/vector/partial/s390-vec-length-full-run-3.c
new file mode 100644
index 0000000..b422119
--- /dev/null
+++ b/gcc/testsuite/gcc.target/s390/vector/partial/s390-vec-length-full-run-3.c
@@ -0,0 +1,7 @@
+/* { dg-do run { target { lp64 && s390_vx } } } */
+/* { dg-options "-march=native -O2 -ftree-vectorize -fno-vect-cost-model -fno-trapping-math" } */
+
+/* { dg-additional-options "--param=vect-partial-vector-usage=2" } */
+
+#include "s390-vec-length-run-3.h"
+
diff --git a/gcc/testsuite/gcc.target/s390/vector/partial/s390-vec-length-full-run-7.c b/gcc/testsuite/gcc.target/s390/vector/partial/s390-vec-length-full-run-7.c
new file mode 100644
index 0000000..dea7a0a
--- /dev/null
+++ b/gcc/testsuite/gcc.target/s390/vector/partial/s390-vec-length-full-run-7.c
@@ -0,0 +1,7 @@
+/* { dg-do run { target { lp64 && s390_vx } } } */
+/* { dg-options "-march=native -O2 -ftree-vectorize -fno-vect-cost-model -ffast-math -fno-trapping-math" } */
+
+/* { dg-additional-options "--param=vect-partial-vector-usage=2" } */
+
+#include "s390-vec-length-run-7.h"
+
diff --git a/gcc/testsuite/gcc.target/s390/vector/partial/s390-vec-length-run-1.h b/gcc/testsuite/gcc.target/s390/vector/partial/s390-vec-length-run-1.h
new file mode 100644
index 0000000..ba9e113
--- /dev/null
+++ b/gcc/testsuite/gcc.target/s390/vector/partial/s390-vec-length-run-1.h
@@ -0,0 +1,34 @@
+#include "s390-vec-length-1.h"
+
+#define decl(TYPE) \
+ TYPE a_##TYPE[N]; \
+ TYPE b_##TYPE[N]; \
+ TYPE c_##TYPE[N];
+
+#define run(TYPE) \
+ { \
+ unsigned int i = 0; \
+ for (i = 0; i < N; i++) \
+ { \
+ a_##TYPE[i] = i * 2 + 1; \
+ b_##TYPE[i] = i % 2 - 2; \
+ } \
+ test##TYPE (); \
+ for (i = 0; i < N; i++) \
+ { \
+ TYPE a1 = i * 2 + 1; \
+ TYPE b1 = i % 2 - 2; \
+ TYPE exp_c = a1 + b1; \
+ if (c_##TYPE[i] != exp_c) \
+ __builtin_abort (); \
+ } \
+ }
+
+TEST_ALL (decl)
+
+int
+main (void)
+{
+ TEST_ALL (run)
+ return 0;
+}
diff --git a/gcc/testsuite/gcc.target/s390/vector/partial/s390-vec-length-run-2.h b/gcc/testsuite/gcc.target/s390/vector/partial/s390-vec-length-run-2.h
new file mode 100644
index 0000000..87582ce
--- /dev/null
+++ b/gcc/testsuite/gcc.target/s390/vector/partial/s390-vec-length-run-2.h
@@ -0,0 +1,36 @@
+#include "s390-vec-length-2.h"
+
+#define decl(TYPE) \
+ TYPE a_##TYPE[N]; \
+ TYPE b_##TYPE[N]; \
+ TYPE c_##TYPE[N];
+
+#define N1 195
+
+#define run(TYPE) \
+ { \
+ unsigned int i = 0; \
+ for (i = 0; i < N; i++) \
+ { \
+ a_##TYPE[i] = i * 2 + 1; \
+ b_##TYPE[i] = i % 2 - 2; \
+ } \
+ test##TYPE (N1); \
+ for (i = 0; i < N1; i++) \
+ { \
+ TYPE a1 = i * 2 + 1; \
+ TYPE b1 = i % 2 - 2; \
+ TYPE exp_c = a1 + b1; \
+ if (c_##TYPE[i] != exp_c) \
+ __builtin_abort (); \
+ } \
+ }
+
+TEST_ALL (decl)
+
+int
+main (void)
+{
+ TEST_ALL (run)
+ return 0;
+}
diff --git a/gcc/testsuite/gcc.target/s390/vector/partial/s390-vec-length-run-3.h b/gcc/testsuite/gcc.target/s390/vector/partial/s390-vec-length-run-3.h
new file mode 100644
index 0000000..eef57f4
--- /dev/null
+++ b/gcc/testsuite/gcc.target/s390/vector/partial/s390-vec-length-run-3.h
@@ -0,0 +1,34 @@
+#include "s390-vec-length-3.h"
+
+#define decl(TYPE) \
+ TYPE a_##TYPE[N_##TYPE]; \
+ TYPE b_##TYPE[N_##TYPE]; \
+ TYPE c_##TYPE[N_##TYPE];
+
+#define run(TYPE) \
+ { \
+ unsigned int i = 0; \
+ for (i = 0; i < N_##TYPE; i++) \
+ { \
+ a_##TYPE[i] = i * 2 + 1; \
+ b_##TYPE[i] = i % 2 - 2; \
+ } \
+ test##TYPE (); \
+ for (i = 0; i < N_##TYPE; i++) \
+ { \
+ TYPE a1 = i * 2 + 1; \
+ TYPE b1 = i % 2 - 2; \
+ TYPE exp_c = a1 + b1; \
+ if (c_##TYPE[i] != exp_c) \
+ __builtin_abort (); \
+ } \
+ }
+
+TEST_ALL (decl)
+
+int
+main (void)
+{
+ TEST_ALL (run)
+ return 0;
+}
diff --git a/gcc/testsuite/gcc.target/s390/vector/partial/s390-vec-length-run-7.h b/gcc/testsuite/gcc.target/s390/vector/partial/s390-vec-length-run-7.h
new file mode 100644
index 0000000..39af9a6
--- /dev/null
+++ b/gcc/testsuite/gcc.target/s390/vector/partial/s390-vec-length-run-7.h
@@ -0,0 +1,16 @@
+#include "s390-vec-length-7.h"
+
+#define run(TYPE) \
+ { \
+ unsigned int i = 0; \
+ test_npeel_##TYPE(); \
+ for (int i = 0; i < N; ++i) { \
+ if (x_##TYPE[i] != (i < START || i >= END ? 0 : (i - START))) \
+ __builtin_abort(); \
+ } \
+ }
+
+int main() {
+ TEST_ALL(run)
+ return 0;
+}
diff --git a/gcc/testsuite/gcc.target/s390/vector/partial/s390-vec-length-small.c b/gcc/testsuite/gcc.target/s390/vector/partial/s390-vec-length-small.c
new file mode 100644
index 0000000..ed953c8
--- /dev/null
+++ b/gcc/testsuite/gcc.target/s390/vector/partial/s390-vec-length-small.c
@@ -0,0 +1,15 @@
+/* { dg-do compile { target { lp64 && s390_vx } } } */
+/* { dg-options "-mzarch -march=native -O2 -ftree-vectorize -fno-vect-cost-model -fno-unroll-loops" } */
+
+/* { dg-additional-options "--param=min-vect-loop-bound=0 --param=vect-partial-vector-usage=2 -fno-trapping-math" } */
+
+#define SZ 333
+
+void foo (char *restrict a, char *restrict b, char *restrict c, int n)
+{
+#pragma gcc unroll 0
+ for (int i = 0; i < 17; i++)
+ c[i] = a[i] + b[i];
+/* { dg-final { scan-assembler-times "lhi\t%r\[0-9\]*,0\n" 1 } } */
+}
+
diff --git a/gcc/testsuite/gcc.target/s390/vector/partial/s390-vec-length.h b/gcc/testsuite/gcc.target/s390/vector/partial/s390-vec-length.h
new file mode 100644
index 0000000..83418b0
--- /dev/null
+++ b/gcc/testsuite/gcc.target/s390/vector/partial/s390-vec-length.h
@@ -0,0 +1,14 @@
+#include <stdint.h>
+
+#define TEST_ALL(T) \
+ T (int8_t) \
+ T (uint8_t) \
+ T (int16_t) \
+ T (uint16_t) \
+ T (int32_t) \
+ T (uint32_t) \
+ T (int64_t) \
+ T (uint64_t) \
+ T (float) \
+ T (double)
+
diff --git a/gcc/testsuite/gcc.target/s390/vector/vec-nopeel-2.c b/gcc/testsuite/gcc.target/s390/vector/vec-nopeel-2.c
index 9b67793..03bf5ee 100644
--- a/gcc/testsuite/gcc.target/s390/vector/vec-nopeel-2.c
+++ b/gcc/testsuite/gcc.target/s390/vector/vec-nopeel-2.c
@@ -9,4 +9,4 @@ void foo(int *restrict a, int *restrict b, unsigned int n)
}
/* { dg-final { scan-tree-dump-times "vectorized 1 loops" 1 "vect" } } */
-/* { dg-final { scan-tree-dump-times "Vectorizing an unaligned access" 2 "vect" } } */
+/* { dg-final { scan-tree-dump "Vectorizing an unaligned access" "vect" } } */
diff --git a/gcc/testsuite/lib/target-supports.exp b/gcc/testsuite/lib/target-supports.exp
index 839e5a6..4236c92 100644
--- a/gcc/testsuite/lib/target-supports.exp
+++ b/gcc/testsuite/lib/target-supports.exp
@@ -7778,7 +7778,8 @@ proc check_effective_target_vect_fully_masked { } {
# @code{len_store} optabs.
proc check_effective_target_vect_len_load_store { } {
- return [check_effective_target_has_arch_pwr9]
+ return [expr { [check_effective_target_has_arch_pwr9]
+ || [check_effective_target_s390_vx] }]
}
# Return the value of parameter vect-partial-vector-usage specified for