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

Reply via email to