
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.
68 lines
1.3 KiB
C
68 lines
1.3 KiB
C
#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;
|
|
}
|