gcc/testsuite/ChangeLog:
* gcc.dg/vect/hssr-1.c: New test.
* gcc.dg/vect/hssr-2.c: New test.
* gcc.dg/vect/hssr-3.c: New test.
* gcc.dg/vect/hssr-4.c: New test.
* gcc.dg/vect/hssr-5.c: New test.
* gcc.dg/vect/hssr-6.c: New test.
* gcc.dg/vect/hssr-ice-1.c: New test.
* gcc.dg/vect/hssr-ice-2.c: New test.
* gcc.dg/vect/hssr-ice-3.c: New test.
* gcc.dg/vect/hssr-ice-4.c: New test.
---
gcc/testsuite/gcc.dg/vect/hssr-1.c | 124 +++++++++++++++++++++++++
gcc/testsuite/gcc.dg/vect/hssr-2.c | 34 +++++++
gcc/testsuite/gcc.dg/vect/hssr-3.c | 25 +++++
gcc/testsuite/gcc.dg/vect/hssr-4.c | 25 +++++
gcc/testsuite/gcc.dg/vect/hssr-5.c | 19 ++++
gcc/testsuite/gcc.dg/vect/hssr-6.c | 17 ++++
gcc/testsuite/gcc.dg/vect/hssr-ice-1.c | 12 +++
gcc/testsuite/gcc.dg/vect/hssr-ice-2.c | 16 ++++
gcc/testsuite/gcc.dg/vect/hssr-ice-3.c | 14 +++
gcc/testsuite/gcc.dg/vect/hssr-ice-4.c | 17 ++++
10 files changed, 303 insertions(+)
create mode 100644 gcc/testsuite/gcc.dg/vect/hssr-1.c
create mode 100644 gcc/testsuite/gcc.dg/vect/hssr-2.c
create mode 100644 gcc/testsuite/gcc.dg/vect/hssr-3.c
create mode 100644 gcc/testsuite/gcc.dg/vect/hssr-4.c
create mode 100644 gcc/testsuite/gcc.dg/vect/hssr-5.c
create mode 100644 gcc/testsuite/gcc.dg/vect/hssr-6.c
create mode 100644 gcc/testsuite/gcc.dg/vect/hssr-ice-1.c
create mode 100644 gcc/testsuite/gcc.dg/vect/hssr-ice-2.c
create mode 100644 gcc/testsuite/gcc.dg/vect/hssr-ice-3.c
create mode 100644 gcc/testsuite/gcc.dg/vect/hssr-ice-4.c
diff --git a/gcc/testsuite/gcc.dg/vect/hssr-1.c
b/gcc/testsuite/gcc.dg/vect/hssr-1.c
new file mode 100644
index 00000000000..be9144ea591
--- /dev/null
+++ b/gcc/testsuite/gcc.dg/vect/hssr-1.c
@@ -0,0 +1,124 @@
+#include "tree-vect.h"
+
+#include <stdint.h>
+#include <stdlib.h>
+#include <assert.h>
+
+
+__attribute__ ((noipa))
+int
+hssr_loop (uint16_t *const restrict out,
+ uint16_t *const restrict src1,
+ uint16_t *const restrict src2,
+ unsigned int n)
+{
+ for (int i = 0; i < n; i++)
+ {
+ uint16_t v1 = src1[i];
+ uint16_t v2 = src2[i];
+ *out += (v1 == v2) + (v1 == i % 10);
+ if (v1 == 0 || v2 == 0)
+ return 1;
+ }
+ return 0;
+}
+
+__attribute__ ((noipa))
+int
+no_hssr_loop (uint16_t *const restrict out,
+ uint16_t *const restrict src1,
+ uint16_t *const restrict src2,
+ unsigned int n)
+{
+ #pragma GCC novector
+ for (int i = 0; i < n; i++)
+ {
+ uint16_t v1 = src1[i];
+ uint16_t v2 = src2[i];
+ *out += (v1 == v2) + (v1 == i % 10);
+ if (v1 == 0 || v2 == 0)
+ return 1;
+ }
+ return 0;
+}
+
+#define N 10000
+int main () {
+ check_vect ();
+
+ uint16_t *b1 = malloc (sizeof(uint16_t) * N);
+ uint16_t *b2 = malloc (sizeof(uint16_t) * N);
+
+ #pragma GCC novector
+ for (int i = 0; i < N; i++) {
+ b1[i] = 1 + (i % 3) * 3;
+ b2[i] = 1 + (i % 11) * 11;
+ /* These should only intersect when i % 7 = 0 and i % 11 = 0 */
+ }
+
+ uint16_t vect_out;
+ uint16_t no_vect_out;
+ int res_vect;
+ int res_no_vect;
+
+ /* Check while aligned */
+ vect_out = 0;
+ no_vect_out = 0;
+ res_vect = hssr_loop(&vect_out, b1, b2, N);
+ res_no_vect = no_hssr_loop(&no_vect_out, b1, b2, N);
+
+ assert (res_vect == res_no_vect);
+ assert (vect_out == no_vect_out);
+
+ /* Check while mutually misaligned */
+ vect_out = 0;
+ no_vect_out = 0;
+ res_vect = hssr_loop(&vect_out, b1+5, b2+5, N-5);
+ res_no_vect = no_hssr_loop(&no_vect_out, b1+5, b2+5, N-5);
+
+ assert (res_vect == res_no_vect);
+ assert (vect_out == no_vect_out);
+
+ /* Check while independently misaligned */
+ vect_out = 0;
+ no_vect_out = 0;
+ res_vect = hssr_loop(&vect_out, b1+9, b2+25, N-25);
+ res_no_vect = no_hssr_loop(&no_vect_out, b1+9, b2+25, N-25);
+
+ assert (res_vect == res_no_vect);
+ assert (vect_out == no_vect_out);
+
+ /* insert an early break and check it still works */
+
+ b1[N/2+75] = 0;
+
+ /* Check while aligned */
+ vect_out = 0;
+ no_vect_out = 0;
+ res_vect = hssr_loop(&vect_out, b1, b2, N);
+ res_no_vect = no_hssr_loop(&no_vect_out, b1, b2, N);
+
+ assert (res_vect == res_no_vect);
+ assert (vect_out == no_vect_out);
+
+ /* Check while mutually misaligned */
+ vect_out = 0;
+ no_vect_out = 0;
+ res_vect = hssr_loop(&vect_out, b1+5, b2+5, N-5);
+ res_no_vect = no_hssr_loop(&no_vect_out, b1+5, b2+5, N-5);
+
+ assert (res_vect == res_no_vect);
+ assert (vect_out == no_vect_out);
+
+ /* Check while independently misaligned */
+ vect_out = 0;
+ no_vect_out = 0;
+ res_vect = hssr_loop(&vect_out, b1+9, b2+25, N-25);
+ res_no_vect = no_hssr_loop(&no_vect_out, b1+9, b2+25, N-25);
+
+ assert (res_vect == res_no_vect);
+ assert (vect_out == no_vect_out);
+}
+
+/* { dg-final { scan-tree-dump "MASK_FF_HSSR_LOAD" "vect" { target { vect_hssr
} } } } */
+
diff --git a/gcc/testsuite/gcc.dg/vect/hssr-2.c
b/gcc/testsuite/gcc.dg/vect/hssr-2.c
new file mode 100644
index 00000000000..debfd60cf72
--- /dev/null
+++ b/gcc/testsuite/gcc.dg/vect/hssr-2.c
@@ -0,0 +1,34 @@
+/* { dg-do compile } */
+/* { dg-additional-options "--param=vect-hssr-usage=3
-fdump-tree-vect-details" } */
+/* { dg-require-effective-target vect_hssr } */
+
+#include <stdint.h>
+
+#define type uint16_t
+
+void foo(
+ type * const restrict dst1,
+ type * const restrict dst2,
+ type * const restrict src1,
+ type * const restrict src1b,
+ type * const restrict src2,
+ type * const restrict src3,
+ unsigned int n)
+{
+
+ for (int i = 0; i < n; i++) {
+ type v1 = src1[i];
+ type v1b = src1b[i];
+ if (v1 == v1b) {break;}
+ type v2 = src2[i];
+ dst1[i] = v1 + v2;
+ if (v2 == 1) {break;}
+ type v3 = src3[i];
+ dst2[i] = v1 + v2 + v3;
+ }
+}
+
+/* { dg-final { scan-tree-dump "Will use HSSR" "vect" } } */
+// We need two hssr regions here so there should be 2 reads
+/* { dg-final { scan-tree-dump-times {add new stmt for
region[^\n]*READ_HSSR_STATE} 2 "vect" } } */
+/* { dg-final { scan-tree-dump-times {add new stmt[^\n]*MASK_FF_HSSR_LOAD} 3
"vect" } } */
diff --git a/gcc/testsuite/gcc.dg/vect/hssr-3.c
b/gcc/testsuite/gcc.dg/vect/hssr-3.c
new file mode 100644
index 00000000000..e491332023d
--- /dev/null
+++ b/gcc/testsuite/gcc.dg/vect/hssr-3.c
@@ -0,0 +1,25 @@
+/* { dg-do compile } */
+/* { dg-additional-options "-fdump-tree-vect-details
--param=vect-hssr-usage=3" } */
+
+#include <stdint.h>
+
+#define type uint16_t
+
+ #include <stdint.h>
+void
+foo (uint16_t *const restrict dst1,
+ uint8_t *const restrict src1,
+ uint16_t *const restrict src2, unsigned int n)
+{
+ for (int i = 0; i < n && src1[2 * i] + src1[2 * i + 1] != 5; i++)
+ {
+ uint8_t v1 = src1[2 * i];
+ uint8_t v1a = src1[2 * i + 1];
+ uint16_t v2 = src2[i];
+ dst1[i] = v1 + v1a + v2;
+ }
+}
+
+/* This should not be vectorized with HSSR as we can't handle multiple lanes.
*/
+/* { dg-final { scan-tree-dump-not "Will use HSSR" "vect" } } */
+/* { dg-final { scan-tree-dump-not {add new stmt[^\n]*MASK_FF_HSSR_LOAD}
"vect" } } */
diff --git a/gcc/testsuite/gcc.dg/vect/hssr-4.c
b/gcc/testsuite/gcc.dg/vect/hssr-4.c
new file mode 100644
index 00000000000..13c2cb4a359
--- /dev/null
+++ b/gcc/testsuite/gcc.dg/vect/hssr-4.c
@@ -0,0 +1,25 @@
+/* { dg-do compile } */
+/* { dg-additional-options "-fdump-tree-vect-details --save-temps
--param=vect-hssr-usage=3" } */
+
+#include <stdint.h>
+
+#define type uint16_t
+
+void
+foo (uint16_t *const restrict dst1,
+ uint16_t *const restrict src1,
+ uint16_t *const restrict src2,
+ unsigned int n)
+{
+ for (int i = 0; i < n; i++)
+ {
+ uint16_t v1 = src1[i];
+ uint16_t v2 = src1[i] == 0 ? 0 : src2[i];
+ if (v1 + v2 == 100) break;
+ dst1[i] = v1 + v2;
+ }
+}
+
+/* This should not be vectorized with HSSR as can not mask HSSR reads. */
+/* { dg-final { scan-tree-dump-not "Will use HSSR" "vect" } } */
+/* { dg-final { scan-tree-dump-not {add new stmt[^\n]*MASK_FF_HSSR_LOAD}
"vect" } } */
diff --git a/gcc/testsuite/gcc.dg/vect/hssr-5.c
b/gcc/testsuite/gcc.dg/vect/hssr-5.c
new file mode 100644
index 00000000000..f2f18925e2c
--- /dev/null
+++ b/gcc/testsuite/gcc.dg/vect/hssr-5.c
@@ -0,0 +1,19 @@
+/* { dg-do compile } */
+/* { dg-additional-options "-O2" } */
+/* { dg-require-effective-target vect_hssr } */
+
+/* Check we use HSSR at O2. */
+
+#include <stdint.h>
+
+int foo (int *restrict a, int *restrict b, int N) {
+ for (int i = 0; i < N; i++)
+ {
+ if (a[i] == b[i])
+ return 1;
+ }
+ return 0;
+}
+
+/* { dg-final { scan-tree-dump "Will use HSSR" "vect" } } */
+/* { dg-final { scan-tree-dump {add new stmt[^\n]*MASK_FF_HSSR_LOAD} "vect" }
} */
diff --git a/gcc/testsuite/gcc.dg/vect/hssr-6.c
b/gcc/testsuite/gcc.dg/vect/hssr-6.c
new file mode 100644
index 00000000000..da850c12d4a
--- /dev/null
+++ b/gcc/testsuite/gcc.dg/vect/hssr-6.c
@@ -0,0 +1,17 @@
+/* { dg-do compile } */
+/* { dg-require-effective-target vect_hssr } */
+
+/* Check we reject HSSR with a negative step, as this cannot be supported. */
+
+#include <stdint.h>
+
+int foo (int *restrict a, int *restrict b, int n) {
+ for (int i = n-1; i >= 0; i--)
+ {
+ if (a[i] == b[i])
+ return 1;
+ }
+ return 0;
+}
+
+/* { dg-final { scan-tree-dump-not "Can use HSSR" "vect" } } */
diff --git a/gcc/testsuite/gcc.dg/vect/hssr-ice-1.c
b/gcc/testsuite/gcc.dg/vect/hssr-ice-1.c
new file mode 100644
index 00000000000..ee01089fb05
--- /dev/null
+++ b/gcc/testsuite/gcc.dg/vect/hssr-ice-1.c
@@ -0,0 +1,12 @@
+/* { dg-do compile } */
+
+// Check this doesnt ICE
+
+int a;
+char b[8];
+int c() {
+ unsigned d = 0;
+ for (; d < a; ++d)
+ if (b[d + 1])
+ return 0;
+}
diff --git a/gcc/testsuite/gcc.dg/vect/hssr-ice-2.c
b/gcc/testsuite/gcc.dg/vect/hssr-ice-2.c
new file mode 100644
index 00000000000..3f5362bfda2
--- /dev/null
+++ b/gcc/testsuite/gcc.dg/vect/hssr-ice-2.c
@@ -0,0 +1,16 @@
+/* { dg-do compile } */
+
+// Check this doesnt ICE
+
+char a;
+int b, d;
+char *c;
+void
+e ()
+{
+ int f;
+ while (f < d && c + f && (&a)[f] == c[f])
+ f++;
+ if (f)
+ b = d;
+}
diff --git a/gcc/testsuite/gcc.dg/vect/hssr-ice-3.c
b/gcc/testsuite/gcc.dg/vect/hssr-ice-3.c
new file mode 100644
index 00000000000..1d75a5e94bd
--- /dev/null
+++ b/gcc/testsuite/gcc.dg/vect/hssr-ice-3.c
@@ -0,0 +1,14 @@
+/* { dg-do compile } */
+
+// Check this doesn't ICE
+
+int c[3];
+long *d;
+int e, f, g;
+void h() {
+ for (;;) {
+ for (int i = 0; i < g; i++)
+ if (c[f + i] || d[e])
+ break;
+ }
+}
diff --git a/gcc/testsuite/gcc.dg/vect/hssr-ice-4.c
b/gcc/testsuite/gcc.dg/vect/hssr-ice-4.c
new file mode 100644
index 00000000000..9b4626ed931
--- /dev/null
+++ b/gcc/testsuite/gcc.dg/vect/hssr-ice-4.c
@@ -0,0 +1,17 @@
+/* { dg-do compile } */
+
+// Check this doesn't ICE
+
+int a, d, e, f, g;
+int *b, *c;
+void h() {
+ int i, j = 0;
+ for (; a; j++) {
+ for (; g; g++)
+ f = b[j];
+ for (; i < e; i++)
+ if (c[i])
+ break;
+ d = i;
+ }
+}
--
2.43.0