Hi Victor,
> -----Original Message-----
> From: Victor Do Nascimento <[email protected]>
> Sent: 03 December 2025 17:22
> To: [email protected]
> Cc: Tamar Christina <[email protected]>; [email protected]; Victor
> Do Nascimento <[email protected]>
> Subject: [PATCH v3] vect: Add uncounted loop unit tests
>
> New in this revision:
>
> - Cleanup previously proposed tests
> - Add new tests
>
> ------------
> gcc/testsuite/ChangeLog:
>
> * gcc.dg/vect/vect-early-break_40.c: Fix.
> * gcc.dg/gomp/static-chunk-size-one.c: Likewise.
> * gcc.dg/vect/vect-uncounted-1.c: New.
> * gcc.dg/vect/vect-uncounted-2.c: Likewise.
> * gcc.dg/vect/vect-uncounted-3.c: Likewise.
> * gcc.dg/vect/vect-uncounted-4.c: Likewise.
> * gcc.dg/vect/vect-uncounted-5.c: Likewise.
> * gcc.dg/vect/vect-uncounted-6.c: Likewise.
> * gcc.dg/vect/vect-uncounted-7.c: Likewise.
> * gcc.dg/vect/vect-uncounted-run-1.c: Likewise.
> * gcc.dg/vect/vect-uncounted-run-2.c: Likewise.
> * gcc.dg/vect/vect-uncounted-run-3.c: Likewise.
> * gcc.dg/vect/vect-uncounted-prolog-peel-1.c: Likewise.
> ---
> .../gcc.dg/gomp/static-chunk-size-one.c | 2 +-
> .../gcc.dg/vect/vect-early-break_40.c | 3 +-
> gcc/testsuite/gcc.dg/vect/vect-uncounted-1.c | 24 ++++++++
> gcc/testsuite/gcc.dg/vect/vect-uncounted-2.c | 21 +++++++
> gcc/testsuite/gcc.dg/vect/vect-uncounted-3.c | 27 +++++++++
> gcc/testsuite/gcc.dg/vect/vect-uncounted-4.c | 22 ++++++++
> gcc/testsuite/gcc.dg/vect/vect-uncounted-5.c | 20 +++++++
> gcc/testsuite/gcc.dg/vect/vect-uncounted-6.c | 24 ++++++++
> gcc/testsuite/gcc.dg/vect/vect-uncounted-7.c | 24 ++++++++
> .../vect/vect-uncounted-prolog-peel-1.c | 23 ++++++++
> .../gcc.dg/vect/vect-uncounted-run-1.c | 55 +++++++++++++++++++
> .../gcc.dg/vect/vect-uncounted-run-2.c | 38 +++++++++++++
> .../gcc.dg/vect/vect-uncounted-run-3.c | 40 ++++++++++++++
> 13 files changed, 320 insertions(+), 3 deletions(-)
> create mode 100644 gcc/testsuite/gcc.dg/vect/vect-uncounted-1.c
> create mode 100644 gcc/testsuite/gcc.dg/vect/vect-uncounted-2.c
> create mode 100644 gcc/testsuite/gcc.dg/vect/vect-uncounted-3.c
> create mode 100644 gcc/testsuite/gcc.dg/vect/vect-uncounted-4.c
> create mode 100644 gcc/testsuite/gcc.dg/vect/vect-uncounted-5.c
> create mode 100644 gcc/testsuite/gcc.dg/vect/vect-uncounted-6.c
> create mode 100644 gcc/testsuite/gcc.dg/vect/vect-uncounted-7.c
> create mode 100644 gcc/testsuite/gcc.dg/vect/vect-uncounted-prolog-peel-
> 1.c
> create mode 100644 gcc/testsuite/gcc.dg/vect/vect-uncounted-run-1.c
> create mode 100644 gcc/testsuite/gcc.dg/vect/vect-uncounted-run-2.c
> create mode 100644 gcc/testsuite/gcc.dg/vect/vect-uncounted-run-3.c
>
> diff --git a/gcc/testsuite/gcc.dg/gomp/static-chunk-size-one.c
> b/gcc/testsuite/gcc.dg/gomp/static-chunk-size-one.c
> index e82de772deb..12b508657fa 100644
> --- a/gcc/testsuite/gcc.dg/gomp/static-chunk-size-one.c
> +++ b/gcc/testsuite/gcc.dg/gomp/static-chunk-size-one.c
> @@ -1,5 +1,5 @@
> /* { dg-do compile } */
> -/* { dg-options "-fopenmp -O2 -fdump-tree-optimized -fno-tree-pre" } */
> +/* { dg-options "-fopenmp -O2 -fdump-tree-optimized -fno-tree-pre -fno-
> tree-vectorize" } */
This one seems weird, how come you're turning off the vectorizer in OMP test?
>
> int
> bar ()
> diff --git a/gcc/testsuite/gcc.dg/vect/vect-early-break_40.c
> b/gcc/testsuite/gcc.dg/vect/vect-early-break_40.c
> index 428f6249fa6..9c0e1fb1264 100644
> --- a/gcc/testsuite/gcc.dg/vect/vect-early-break_40.c
> +++ b/gcc/testsuite/gcc.dg/vect/vect-early-break_40.c
> @@ -23,5 +23,4 @@ unsigned test4(unsigned x)
> return ret;
> }
>
> -/* SCEV can't currently analyze this loop bounds. */
> -/* { dg-final { scan-tree-dump "vectorized 1 loops in function" "vect" {
> xfail *-
> *-* } } } */
> \ No newline at end of file
> +/* { dg-final { scan-tree-dump "vectorized 1 loops in function" "vect" } } */
> diff --git a/gcc/testsuite/gcc.dg/vect/vect-uncounted-1.c
> b/gcc/testsuite/gcc.dg/vect/vect-uncounted-1.c
> new file mode 100644
> index 00000000000..e5bfbc64527
> --- /dev/null
> +++ b/gcc/testsuite/gcc.dg/vect/vect-uncounted-1.c
> @@ -0,0 +1,24 @@
> +/* Check we can derive scalar IV return value from vectorized IV value,
> + resetting it on entry into the scalar epilogue loop via BIT_FIELD_REF. */
> +/* { dg-add-options vect_early_break } */
> +/* { dg-do compile } */
Tests in the vect/ directory don't specify the action, they're detected
automatically
so drop this and the run from the tests
> +/* { dg-require-effective-target vect_early_break } */
> +/* { dg-require-effective-target vect_int } */
> +
> +int
> +foo (int *haystack, int needle)
> +{
> + int i = 0;
> + while (1)
> + {
> + if (haystack[i] == needle)
> + return i;
> + i++;
> + }
> +}
> +
> +/* { dg-final { scan-tree-dump "Loop being analyzed as uncounted." "vect" } }
> */
> +/* { dg-final { scan-tree-dump "vectorized 1 loops in function" "vect" } } */
> +/* Ensure we reset our scalar IV so as to repeat the last vector iteration.
> */
> +/* { dg-final { scan-tree-dump {_[0-9_]+ = BIT_FIELD_REF <vect_i_[0-9_.]+,
> [0-9]+, 0>} "vect" } } */
> +
> diff --git a/gcc/testsuite/gcc.dg/vect/vect-uncounted-2.c
> b/gcc/testsuite/gcc.dg/vect/vect-uncounted-2.c
> new file mode 100644
> index 00000000000..33fb0ce1f0d
> --- /dev/null
> +++ b/gcc/testsuite/gcc.dg/vect/vect-uncounted-2.c
> @@ -0,0 +1,21 @@
> +/* { dg-add-options vect_early_break } */
> +/* { dg-do compile } */
> +/* { dg-require-effective-target vect_early_break } */
> +/* { dg-require-effective-target vect_int } */
> +
> +int
> +foo (int *a0, int *aN, int *b0, int *bN)
> +{
> + int *a = a0;
> + int *b = b0;
> +
> + for (;a != aN && b != bN; a++, b++)
> + *a += *b;
> +}
> +
> +/* { dg-final { scan-tree-dump "Loop being analyzed as uncounted." "vect" } }
> */
> +/* { dg-final { scan-tree-dump "vectorized 1 loops in function" "vect" } } */
> +/* Make sure the values used in peeled epilog loop effectively reset the last
> vectorized iteration. */
> +/* { dg-final { scan-tree-dump {<bb ([0-9]+)>[^\n\r]*:.+# (a_[0-9]+) = PHI
> <a_[0-9]+\([0-9]+\).+<bb [0-9]+>[^\n\r]*:.+# a_[0-9]+ = PHI <\2\(\1\)>}
> "vect" } } */
> +/* { dg-final { scan-tree-dump {<bb ([0-9]+)>[^\n\r]*:.+# (b_[0-9]+) = PHI
> <b_[0-9]+\([0-9]+\).+<bb [0-9]+>[^\n\r]*:.+# b_[0-9]+ = PHI <\2\(\1\)>}
> "vect" } } */
> +
> diff --git a/gcc/testsuite/gcc.dg/vect/vect-uncounted-3.c
> b/gcc/testsuite/gcc.dg/vect/vect-uncounted-3.c
> new file mode 100644
> index 00000000000..ace20240663
> --- /dev/null
> +++ b/gcc/testsuite/gcc.dg/vect/vect-uncounted-3.c
> @@ -0,0 +1,27 @@
> +/* Test the correct resetting of live out values on epilog loop entry for IV
> + when it's incremented prior to exit taken. */
> +/* { dg-add-options vect_early_break } */
> +/* { dg-do compile } */
> +/* { dg-require-effective-target vect_early_break } */
> +/* { dg-require-effective-target vect_int } */
> +
> +extern int N;
> +
> +int
> +foo (int c[N], int d[N], int a)
> +{
> + int i = 0;
> + while(c[i] != 0)
> + {
> + i += 1;
> + if (d[i] == a)
> + break;
> + if (d[i] == 7)
> + break;
> + }
> + return i;
> +}
> +
> +/* { dg-final { scan-tree-dump "Loop being analyzed as uncounted." "vect" } }
> */
> +/* { dg-final { scan-tree-dump "BIT_FIELD_REF <vect_vec_iv_.\[0-9_\]+, \[0-
> 9\]+, 0>" "vect" } } */
> +/* { dg-final { scan-tree-dump "vectorized 1 loops in function" "vect" } } */
> diff --git a/gcc/testsuite/gcc.dg/vect/vect-uncounted-4.c
> b/gcc/testsuite/gcc.dg/vect/vect-uncounted-4.c
> new file mode 100644
> index 00000000000..0544e321233
> --- /dev/null
> +++ b/gcc/testsuite/gcc.dg/vect/vect-uncounted-4.c
> @@ -0,0 +1,22 @@
> +/* Check vectorization of uncounted reductions. */
> +/* { dg-add-options vect_early_break } */
> +/* { dg-do compile } */
> +/* { dg-require-effective-target vect_early_break } */
> +/* { dg-require-effective-target vect_int } */
> +
> +int
> +foo (int *a0, int *aN, int accum)
> +{
> + int i = 0;
> + while (1)
> + {
> + if (a0[i++] == *aN)
> + return accum;
> + accum += a0[i];
> + }
> +}
> +
> +/* { dg-final { scan-tree-dump "Loop being analyzed as uncounted." "vect" } }
> */
> +/* { dg-final { scan-tree-dump "Detected reduction." "vect" } } */
> +/* { dg-final { scan-tree-dump "vectorized 1 loops in function" "vect" } } */
> +/* { dg-final { scan-tree-dump {vect_accum_([0-9_.]+) = PHI <vect_accum_[0-
> 9_.]+\([0-9]+\), { 0, 0, 0, 0 }\([0-9]+\)>.*# vect_accum_[0-9_.]+ = PHI
> <vect_accum_\1\([0-9]+\)>} "vect" } } */
> diff --git a/gcc/testsuite/gcc.dg/vect/vect-uncounted-5.c
> b/gcc/testsuite/gcc.dg/vect/vect-uncounted-5.c
> new file mode 100644
> index 00000000000..6b572b812e0
> --- /dev/null
> +++ b/gcc/testsuite/gcc.dg/vect/vect-uncounted-5.c
> @@ -0,0 +1,20 @@
> +/* Loop with undetermined increment at compile-time is treated as
> uncounted. */
> +/* Adapted from pr102572.cc */
> +/* { dg-add-options vect_early_break } */
> +/* { dg-do compile } */
> +/* { dg-require-effective-target vect_early_break } */
> +/* { dg-require-effective-target vect_int } */
> +
> +int a, b, c, f;
> +void g(bool h, int d[][5])
> +{
> + int k = 0;
> + for (short i = f; i; i += 1)
> + {
> + a = h && d[0][i];
> + for (int j = 0; j < 4; j += c)
> + b++;
> + }
> +}
> +/* { dg-final { scan-tree-dump "Loop being analyzed as uncounted." "vect" } }
> */
> +/* { dg-final { scan-tree-dump "vectorized 1 loops in function" "vect" } } */
> diff --git a/gcc/testsuite/gcc.dg/vect/vect-uncounted-6.c
> b/gcc/testsuite/gcc.dg/vect/vect-uncounted-6.c
> new file mode 100644
> index 00000000000..a7776da24c5
> --- /dev/null
> +++ b/gcc/testsuite/gcc.dg/vect/vect-uncounted-6.c
> @@ -0,0 +1,24 @@
> +/* Check the vectorization of existing testsuite examples */
> +/* Taken from pr109331.c */
> +/* { dg-add-options vect_early_break } */
> +/* { dg-do compile } */
> +/* { dg-require-effective-target vect_early_break } */
> +/* { dg-require-effective-target vect_int } */
> +
> +char *ustol_dpp;
> +void ustol(int flags)
> +{
> + char *s;
> + if (s)
> + flags |= 3;
> + switch (flags & 3)
> + case 3:
> + while (*s)
> + case '+':
> + ++s;
> + if (flags)
> + ustol_dpp = s;
> +}
> +
> +/* { dg-final { scan-tree-dump "Loop being analyzed as uncounted." "vect" } }
> */
> +/* { dg-final { scan-tree-dump "vectorized 1 loops in function" "vect" } } */
> diff --git a/gcc/testsuite/gcc.dg/vect/vect-uncounted-7.c
> b/gcc/testsuite/gcc.dg/vect/vect-uncounted-7.c
> new file mode 100644
> index 00000000000..83aa3085ce7
> --- /dev/null
> +++ b/gcc/testsuite/gcc.dg/vect/vect-uncounted-7.c
> @@ -0,0 +1,24 @@
> +/* Check the vectorization of existing testsuite examples */
> +/* Taken from pr54824.c */
> +/* { dg-additional-options "-w" } */
> +/* { dg-add-options vect_early_break } */
> +/* { dg-do compile } */
> +/* { dg-require-effective-target vect_early_break } */
> +/* { dg-require-effective-target vect_int } */
> +
> +void __attribute__((noreturn)) bar(void)
> +{
> +}
> +
> +void foo(int i, char *p, char *q)
> +{
> + while (*p++) {
> + if (i)
> + p++;
> + if (!*q++)
> + bar();
> + }
> +}
> +
> +/* { dg-final { scan-tree-dump "Loop being analyzed as uncounted." "vect" } }
> */
> +/* { dg-final { scan-tree-dump "vectorized 1 loops in function" "vect" } } */
> diff --git a/gcc/testsuite/gcc.dg/vect/vect-uncounted-prolog-peel-1.c
> b/gcc/testsuite/gcc.dg/vect/vect-uncounted-prolog-peel-1.c
> new file mode 100644
> index 00000000000..fab4ed0f569
> --- /dev/null
> +++ b/gcc/testsuite/gcc.dg/vect/vect-uncounted-prolog-peel-1.c
> @@ -0,0 +1,23 @@
> +/* { dg-add-options vect_early_break } */
> +/* { dg-do compile } */
> +/* { dg-require-effective-target vect_early_break } */
> +/* { dg-require-effective-target vect_int } */
> +
> +int
> +foo (int *haystack, int needle)
> +{
> + int i = 0;
> + while (1)
> + {
> + if (haystack[i] == needle)
> + return i;
> + i++;
> + }
> +}
> +
> +/* { dg-final { scan-tree-dump {note:\s*Alignment of access forced using
> peeling.} "vect" } } */
> +/* { dg-final { scan-tree-dump {if \(prolog_loop_niters.[0-9_]+ ==
> 0\)\n\s*goto} "vect" } } */
> +/* { dg-final { scan-tree-dump {ivtmp_[0-9_]+ = PHI <ivtmp_[0-9_]+\([0-
> 9_]+\), 0\([0-9_]+\)>} "vect" } } */
> +/* { dg-final { scan-tree-dump {ivtmp_[0-9_]+ = ivtmp_[0-9_]+ \+ 1;} "vect" }
> } */
> +/* { dg-final { scan-tree-dump {if \(ivtmp_[0-9_]+ >= prolog_loop_niters.[0-
> 9_]+\)\n\s*goto} "vect" } } */
> +/* { dg-final { scan-tree-dump {vectorized 1 loops in function} "vect" } } */
> diff --git a/gcc/testsuite/gcc.dg/vect/vect-uncounted-run-1.c
> b/gcc/testsuite/gcc.dg/vect/vect-uncounted-run-1.c
> new file mode 100644
> index 00000000000..ff09d955d34
> --- /dev/null
> +++ b/gcc/testsuite/gcc.dg/vect/vect-uncounted-run-1.c
> @@ -0,0 +1,55 @@
> +/* Check we can derive scalar IV return value from vectorized IV value,
> + resetting it on entry into the scalar epilogue loop via BIT_FIELD_REF. */
> +/* { dg-add-options vect_early_break } */
> +/* { dg-do run } */
> +/* { dg-require-effective-target vect_early_break } */
Run tests need to check vect_early_break_hw instead.
Also include `tree-vect.h`
> +/* { dg-require-effective-target vect_int } */
> +
> +#include <assert.h>
> +
> +#define N 128
> +#define VAL 13
> +
> +int
It's also useful to add __attribute__((nopia)) to these
So that there's no possibility of them being inlined and
optimized away.
> +foo (int *haystack, int needle)
> +{
> + int i = 0;
> + while (1)
> + {
> + if (haystack[i] == needle)
> + return i;
> + i++;
> + }
> +}
> +
> +#define CHECK_MATCH(POS) \
> + void \
> + check_match_ ## POS (void) \
> + { \
> + int input[N] = {[0 ... N-1] = 0}; \
> + input[POS] = VAL; \
> + int res = foo (input, VAL); \
> + assert (res == POS); \
> + }
> +
> +CHECK_MATCH (0)
> +CHECK_MATCH (3)
> +CHECK_MATCH (127)
> +
> +#undef CHECK_MATCH
> +#define CHECK_MATCH(POS) check_match_ ## POS ()
> +
> +int
> +main ()
> +{
And call check_vect () in main to initialize things.
Thanks,
Tamar
> + CHECK_MATCH (0);
> + CHECK_MATCH (3);
> + CHECK_MATCH (127);
> + return 0;
> +}
> +
> +/* { dg-final { scan-tree-dump "Loop being analyzed as uncounted." "vect" } }
> */
> +/* { dg-final { scan-tree-dump "vectorized 1 loops in function" "vect" } } */
> +/* Ensure we reset our scalar IV so as to repeat the last vector iteration.
> */
> +/* { dg-final { scan-tree-dump {_[0-9_]+ = BIT_FIELD_REF <vect_i_[0-9_.]+,
> [0-9]+, 0>} "vect" } } */
> +
> diff --git a/gcc/testsuite/gcc.dg/vect/vect-uncounted-run-2.c
> b/gcc/testsuite/gcc.dg/vect/vect-uncounted-run-2.c
> new file mode 100644
> index 00000000000..7e38b7c6701
> --- /dev/null
> +++ b/gcc/testsuite/gcc.dg/vect/vect-uncounted-run-2.c
> @@ -0,0 +1,38 @@
> +/* execution test for the correct resetting of live out values on epilog loop
> + entry. */
> +/* { dg-add-options vect_early_break } */
> +/* { dg-do run } */
> +/* { dg-require-effective-target vect_early_break } */
> +/* { dg-require-effective-target vect_int } */
> +
> +#include <assert.h>
> +#define N 9
> +void
> +test01 ()
> +{
> + {
> + int x[N] = {2, 4, 6, 8, 10, 12, 14, 16, 18};
> + const int y[N] = {3, 5, 7, 9, 11, 13, 15, 17, 19};
> + int z[N] = {5, 9, 13, 17, 21, 25, 29, 33, 37};
> +
> + int *x0 = x;
> + int *xN = x+N;
> + const int *y0 = y;
> + const int *yN = y+N;
> +
> + int *res = x;
> +
> + for (; x0 != xN && y0 != yN; ++x0, (void)++y0, ++res)
> + *res = *x0 + *y0;
> + assert (x0 == x+N && y0 == y+N && res == x+N);
> + assert (x[0] == z[0] && x[1] == z[1]);
> + }
> +}
> +
> +int
> +main ()
> +{
> + test01 ();
> +}
> +
> +/* { dg-final { scan-tree-dump "vectorized 1 loops in function" "vect" } } */
> diff --git a/gcc/testsuite/gcc.dg/vect/vect-uncounted-run-3.c
> b/gcc/testsuite/gcc.dg/vect/vect-uncounted-run-3.c
> new file mode 100644
> index 00000000000..45fcda39854
> --- /dev/null
> +++ b/gcc/testsuite/gcc.dg/vect/vect-uncounted-run-3.c
> @@ -0,0 +1,40 @@
> +/* Check vectorization of uncounted reductions. */
> +/* { dg-add-options vect_early_break } */
> +/* { dg-do run } */
> +/* { dg-require-effective-target vect_early_break } */
> +/* { dg-require-effective-target vect_int } */
> +#include <assert.h>
> +
> +int
> +foo (int *a0, int *aN, int accum)
> +{
> + int i = 0;
> + while (1)
> + {
> + if (a0[i++] == *aN)
> + return accum;
> + accum += a0[i];
> + }
> +}
> +
> +void
> +accum_check (int *a0, int len, int accum, int result)
> +{
> + int retval = foo (a0, a0+len, accum);
> + assert (retval == result);
> +}
> +
> +int
> +main (void)
> +{
> + int a[] = {0,1,2,3,4,5,6,10,11,12};
> + accum_check (a, 5, 0, 15);
> + accum_check (a, 9, 0, 54);
> + accum_check (a, 6, 0, 21);
> + accum_check (a, 6, 5, 26);
> + return 0;
> +}
> +
> +/* { dg-final { scan-tree-dump "Loop being analyzed as uncounted." "vect" } }
> */
> +/* { dg-final { scan-tree-dump "Detected reduction." "vect" } } */
> +/* { dg-final { scan-tree-dump "vectorized 1 loops in function" "vect" } } */
> --
> 2.43.0