From: Victor Do Nascimento Date: Mon, 1 Dec 2025 17:23:53 +0000 (+0000) Subject: vect: Add uncounted loop unit tests X-Git-Url: http://git.ipfire.org/cgi-bin/gitweb.cgi?a=commitdiff_plain;h=66724bf714e73c1714ee97aeddeb0b469d674cc4;p=thirdparty%2Fgcc.git vect: Add uncounted loop unit 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. --- 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" } */ 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-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 } "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..75a8ed1372f --- /dev/null +++ b/gcc/testsuite/gcc.dg/vect/vect-uncounted-run_1.c @@ -0,0 +1,56 @@ +/* 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-require-effective-target vect_early_break_hw } */ +/* { dg-require-effective-target vect_int } */ + +#include +#include "tree-vect.h" + +#define N 128 +#define VAL 13 + +__attribute__((noipa, noinline)) +int +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 () +{ + 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" } } */ + 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..c5019de250d --- /dev/null +++ b/gcc/testsuite/gcc.dg/vect/vect-uncounted-run_2.c @@ -0,0 +1,41 @@ +/* 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_hw } */ +/* { dg-require-effective-target vect_int } */ + +#include +#include "tree-vect.h" +#define N 9 + +__attribute__((noipa, noinline)) +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..26fcb06fab9 --- /dev/null +++ b/gcc/testsuite/gcc.dg/vect/vect-uncounted-run_3.c @@ -0,0 +1,42 @@ +/* Check vectorization of uncounted reductions. */ +/* { dg-add-options vect_early_break } */ +/* { dg-do run } */ +/* { dg-require-effective-target vect_early_break_hw } */ +/* { dg-require-effective-target vect_int } */ +#include +#include "tree-vect.h" + +__attribute__((noipa, noinline)) +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" } } */ 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 } */ +/* { 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" } } */ + 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 {[^\n\r]*:.+# (a_[0-9]+) = PHI [^\n\r]*:.+# a_[0-9]+ = PHI <\2\(\1\)>} "vect" } } */ +/* { dg-final { scan-tree-dump {[^\n\r]*:.+# (b_[0-9]+) = PHI [^\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" } } */ +/* { 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..328dbb6ca6d --- /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_.]+ = PHI } "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" } } */