aboutsummaryrefslogtreecommitdiff
path: root/libgomp
diff options
context:
space:
mode:
authorTobias Burnus <tobias@codesourcery.com>2023-04-25 16:29:14 +0200
committerTobias Burnus <tobias@codesourcery.com>2023-04-25 16:29:14 +0200
commit1c101fcfaac8f609d618f83b124bd50aea012132 (patch)
treedd1ac83cab1561d60c15f2083fcc243b452636a8 /libgomp
parent78aaaf862e70cea45f3a2be7cb855cfe1a4ead21 (diff)
downloadgcc-1c101fcfaac8f609d618f83b124bd50aea012132.zip
gcc-1c101fcfaac8f609d618f83b124bd50aea012132.tar.gz
gcc-1c101fcfaac8f609d618f83b124bd50aea012132.tar.bz2
'omp scan' struct block seq update for OpenMP 5.x
While OpenMP 5.0 required a single structured block before and after the 'omp scan' directive, OpenMP 5.1 changed this to a 'structured block sequence, denoting 2 or more executable statements in OpenMP 5.1 (whoops!) and zero or more in OpenMP 5.2. This commit updates C/C++ to accept zero statements (but till requires the '{' ... '}' for the final-loop-body) and updates Fortran to accept zero or more than one statements. If there is no preceeding or succeeding executable statement, a warning is shown. gcc/c/ChangeLog: * c-parser.cc (c_parser_omp_scan_loop_body): Handle zero exec statements before/after 'omp scan'. gcc/cp/ChangeLog: * parser.cc (cp_parser_omp_scan_loop_body): Handle zero exec statements before/after 'omp scan'. gcc/fortran/ChangeLog: * openmp.cc (gfc_resolve_omp_do_blocks): Handle zero or more than one exec statements before/after 'omp scan'. * trans-openmp.cc (gfc_trans_omp_do): Likewise. libgomp/ChangeLog: * testsuite/libgomp.c-c++-common/scan-1.c: New test. * testsuite/libgomp.c/scan-23.c: New test. * testsuite/libgomp.fortran/scan-2.f90: New test. gcc/testsuite/ChangeLog: * g++.dg/gomp/attrs-7.C: Update dg-error/dg-warning. * gfortran.dg/gomp/loop-2.f90: Likewise. * gfortran.dg/gomp/reduction5.f90: Likewise. * gfortran.dg/gomp/reduction6.f90: Likewise. * gfortran.dg/gomp/scan-1.f90: Likewise. * gfortran.dg/gomp/taskloop-2.f90: Likewise. * c-c++-common/gomp/scan-6.c: New test. * gfortran.dg/gomp/scan-8.f90: New test.
Diffstat (limited to 'libgomp')
-rw-r--r--libgomp/testsuite/libgomp.c-c++-common/scan-1.c68
-rw-r--r--libgomp/testsuite/libgomp.c/scan-23.c121
-rw-r--r--libgomp/testsuite/libgomp.fortran/scan-2.f9059
3 files changed, 248 insertions, 0 deletions
diff --git a/libgomp/testsuite/libgomp.c-c++-common/scan-1.c b/libgomp/testsuite/libgomp.c-c++-common/scan-1.c
new file mode 100644
index 0000000..d1951a3
--- /dev/null
+++ b/libgomp/testsuite/libgomp.c-c++-common/scan-1.c
@@ -0,0 +1,68 @@
+#define N 30
+#define M 3
+
+int a[N][M], b[N][M], c[N][M];
+
+int
+main()
+{
+ int x, y, shift;
+ int j = 0;
+ for (int i = 0; i < N; i++)
+ {
+ a[i][0] = (i+1)*32;
+ a[i][1] = (i+1)*17;
+ a[i][2] = (i+1)*11;
+ b[i][0] = (i+1)*7;
+ b[i][1] = (i+1)*5;
+ b[i][2] = (i+1)*3;
+ }
+
+ x = 0;
+ #pragma omp parallel for simd collapse(2) reduction(inscan,+: x) private(shift)
+ for (int i = 0; i < N; i++)
+ for (int j = 0; j < M; j++)
+ {
+ x += a[i][j];
+ x += b[i][j];
+ #pragma omp scan inclusive(x)
+ shift = i + 29*j;
+ c[i][j] = x + shift;
+ }
+
+ y = 0;
+ for (int i = 0; i < N; i++)
+ for (int j = 0; j < M; j++)
+ {
+ y += a[i][j] + b[i][j];
+ if (c[i][j] != y + i + 29*j)
+ __builtin_abort ();
+ }
+ if (x != y)
+ __builtin_abort ();
+
+ x = 0;
+ #pragma omp parallel for simd collapse(2) reduction(inscan,+: x) private(shift)
+ for (int i = 0; i < N; i++)
+ for (int j = 0; j < M; j++)
+ {
+ shift = i + 29*j;
+ c[i][j] = x + shift;
+ #pragma omp scan exclusive(x)
+ x += a[i][j];
+ x += b[i][j];
+ }
+
+ y = 0;
+ for (int i = 0; i < N; i++)
+ for (int j = 0; j < M; j++)
+ {
+ if (c[i][j] != y + i + 29*j)
+ __builtin_abort ();
+ y += a[i][j] + b[i][j];
+ }
+ if (x != y)
+ __builtin_abort ();
+
+ return 0;
+}
diff --git a/libgomp/testsuite/libgomp.c/scan-23.c b/libgomp/testsuite/libgomp.c/scan-23.c
new file mode 100644
index 0000000..e7681ad
--- /dev/null
+++ b/libgomp/testsuite/libgomp.c/scan-23.c
@@ -0,0 +1,121 @@
+/* { dg-require-effective-target size32plus } */
+/* Same as scan-9.c, instead of using { ... } it simply uses multiple
+ executable stmt before 'omp scan'. */
+
+extern void abort (void);
+int r, a[1024], b[1024], x, y, z;
+
+__attribute__((noipa)) void
+foo (int *a, int *b)
+{
+ #pragma omp for reduction (inscan, +:r) lastprivate (conditional: z) firstprivate (x) private (y)
+ for (int i = 0; i < 1024; i++)
+ {
+ y = a[i];
+ r += y + x + 12;
+ #pragma omp scan inclusive(r)
+ b[i] = r;
+ if ((i & 1) == 0 && i < 937)
+ z = r;
+ }
+}
+
+__attribute__((noipa)) int
+bar (void)
+{
+ int s = 0;
+ #pragma omp parallel
+ #pragma omp for reduction (inscan, +:s) firstprivate (x) private (y) lastprivate (z)
+ for (int i = 0; i < 1024; i++)
+ {
+ y = 2 * a[i]; s += y; z = y;
+ #pragma omp scan inclusive(s)
+ y = s; b[i] = y + x + 12;
+ }
+ return s;
+}
+
+__attribute__((noipa)) void
+baz (int *a, int *b)
+{
+ #pragma omp parallel for reduction (inscan, +:r) firstprivate (x) lastprivate (x)
+ for (int i = 0; i < 1024; i++)
+ {
+ r += a[i] + x + 12; if (i == 1023) x = 29;
+ #pragma omp scan inclusive(r)
+ b[i] = r;
+ }
+}
+
+__attribute__((noipa)) int
+qux (void)
+{
+ int s = 0;
+ #pragma omp parallel for reduction (inscan, +:s) lastprivate (conditional: x, y)
+ for (int i = 0; i < 1024; i++)
+ {
+ s += 2 * a[i]; if ((a[i] & 1) == 1 && i < 825) x = a[i];
+ #pragma omp scan inclusive(s)
+ b[i] = s; if ((a[i] & 1) == 0 && i < 829) y = a[i];
+ }
+ return s;
+}
+
+int
+main ()
+{
+ int s = 0;
+ x = -12;
+ for (int i = 0; i < 1024; ++i)
+ {
+ a[i] = i;
+ b[i] = -1;
+ asm ("" : "+g" (i));
+ }
+ #pragma omp parallel
+ foo (a, b);
+ if (r != 1024 * 1023 / 2 || x != -12 || z != b[936])
+ abort ();
+ for (int i = 0; i < 1024; ++i)
+ {
+ s += i;
+ if (b[i] != s)
+ abort ();
+ else
+ b[i] = 25;
+ }
+ if (bar () != 1024 * 1023 || x != -12 || z != 2 * 1023)
+ abort ();
+ s = 0;
+ for (int i = 0; i < 1024; ++i)
+ {
+ s += 2 * i;
+ if (b[i] != s)
+ abort ();
+ else
+ b[i] = -1;
+ }
+ r = 0;
+ baz (a, b);
+ if (r != 1024 * 1023 / 2 || x != 29)
+ abort ();
+ s = 0;
+ for (int i = 0; i < 1024; ++i)
+ {
+ s += i;
+ if (b[i] != s)
+ abort ();
+ else
+ b[i] = -25;
+ }
+ if (qux () != 1024 * 1023 || x != 823 || y != 828)
+ abort ();
+ s = 0;
+ for (int i = 0; i < 1024; ++i)
+ {
+ s += 2 * i;
+ if (b[i] != s)
+ abort ();
+ }
+ return 0;
+}
diff --git a/libgomp/testsuite/libgomp.fortran/scan-2.f90 b/libgomp/testsuite/libgomp.fortran/scan-2.f90
new file mode 100644
index 0000000..2815ec7
--- /dev/null
+++ b/libgomp/testsuite/libgomp.fortran/scan-2.f90
@@ -0,0 +1,59 @@
+implicit none
+integer, parameter :: N = 30
+integer, parameter :: M = 3
+
+integer :: a(M,N), b(M,N), c(M,N)
+integer :: x, y, shift
+integer :: i, j
+
+do i = 1, N
+ a(1,i) = i*32
+ a(2,i) = i*17
+ a(3,i) = i*11
+ b(1,i) = i*7
+ b(2,i) = i*5
+ b(3,i) = i*3
+end do
+
+x = 0
+!$omp parallel do simd collapse(2) reduction(inscan,+: x) private(shift)
+do i = 1, N
+ do j = 1, M
+ x = x + a(j,i)
+ x = x + b(j,i)
+ !$omp scan inclusive(x)
+ shift = i + 29*j
+ c(j,i) = x + shift;
+ end do
+end do
+
+y = 0
+do i = 1, N
+ do j = 1, M
+ y = y + a(j,i) + b(j,i)
+ if (c(j,i) /= y + i + 29*j) error stop 1
+ end do
+end do
+if (x /= y) error stop 2
+
+x = 0
+!$omp parallel do simd collapse(2) reduction(inscan,+: x) private(shift)
+do i = 1, N
+ do j = 1, M
+ shift = i + 29*j
+ c(j,i) = x + shift;
+ !$omp scan exclusive(x)
+ x = x + a(j,i)
+ x = x + b(j,i)
+ end do
+end do
+
+y = 0
+do i = 1, N
+ do j = 1, M
+ if (c(j,i) /= y + i + 29*j) error stop 1
+ y = y + a(j,i) + b(j,i)
+ end do
+end do
+if (x /= y) error stop 2
+end