https://gcc.gnu.org/bugzilla/show_bug.cgi?id=100573
--- Comment #3 from Tom de Vries <vries at gcc dot gnu.org> --- Hmm, I reproduced the problem on the original test-case: libgomp.c-c++-common/for-3.c, and minimized from there: ... $ cat libgomp/testsuite/libgomp.c-c++-common/for-3.c /* { dg-additional-options "-std=gnu99" { target c } } */ #include <stdio.h> extern void abort (); #define N 1500 int a[N]; int main (void) { int err = 0; #pragma omp target map(tofrom: err) map (tofrom: a) #pragma omp teams num_teams (15) reduction(|:err) { int i; for (i = 0; i < N; i++) a[i] = 0; do {} while (0); #pragma omp distribute for (i = 0; i < N; i++) a[i] += 2; do {} while (0); for (i = 0; i < N; i++) if (a[i] != 2) err |= 1; } int i; for (i = 0; i < N; i++) if (a[i] != 2) printf ("a[%d]: %d\n", i, a[i]); if (err) abort (); return 0; } ... Again, I think there's a problem with the test-case. There's no implicit barrier at the end of a distribute construct, so we can have: - team 0 updates part of array - team 0 checks entire array, finds that only it's part is done, sets error flag - team 1 updates part of array ... I wonder whether there's an implicit barrier at the start of the distribute construct. If not, then the same problem exists for the initialization.