https://gcc.gnu.org/bugzilla/show_bug.cgi?id=85527
Bug ID: 85527 Summary: [openacc] atomic_capture-1.{c,f90} undefined behaviour Product: gcc Version: unknown Status: UNCONFIRMED Severity: normal Priority: P3 Component: testsuite Assignee: unassigned at gcc dot gnu.org Reporter: vries at gcc dot gnu.org Target Milestone: --- I. Consider this test-case, minimized from atomic_capture-1.f90: ... program main real fgot, fexp, ftmp integer, parameter :: N = 32 fgot = 1234.0 fexp = 1266.0 !$acc parallel loop copy (fgot, ftmp) do i = 1, N !$acc atomic capture ftmp = fgot fgot = fgot + 1.0 !$acc end atomic end do !$acc end parallel loop if (ftmp /= fexp - 1.0) call abort end program main ... We write different values to the scalar ftmp in a parallel loop. So, roughtly equivalent to: ... !$acc parallel loop copy (fgot, ftmp) do i = 1, N ftmp = i end do !$acc end parallel loop ... This is undefined behaviour. If we look in atomic_capture-1.c, the equivalent loop looks like this: ... #pragma acc data copy (fgot, fdata[0:N]) { #pragma acc parallel loop for (i = 0; i < N; i++) { #pragma acc atomic capture fdata[i] = fgot++; } } if (fexp != fgot) abort (); ... So, the solution here is to write to different entries in an array. II. atomic_capture-1.c contains only a single case of checking the contents of fdata/ldata/idata: ... fgot = 1.0; fexp = 0.0; #pragma acc data copy (fgot, fdata[0:N]) { #pragma acc parallel loop for (i = 0; i < N; i++) { float expr = 32.0; #pragma acc atomic capture fdata[i] = fgot = expr - fgot; } } for (i = 0; i < N; i++) if (i % 2 == 0) { if (fdata[i] != 31.0) abort (); } else { if (fdata[i] != 1.0) abort (); } ... That was already observed to be causing problem here (https://gcc.gnu.org/ml/gcc-patches/2016-05/msg00173.html ), and was removed in this patch: ... commit 39be832ac8fb62836b54b98c118ce713a323bb2e Author: nathan <nathan@138bc75d-0d04-0410-961f-82ee72b054a4> Date: Fri Jan 22 22:01:33 2016 +0000 * testsuite/libgomp.oacc-c-c++-common/atomic_capture-1.c: Don't assume atomic op ordering. * testsuite/libgomp.oacc-fortran/atomic_capture-1.f90: Likewise. git-svn-id: svn+ssh://gcc.gnu.org/svn/gcc/branches/gomp-4_0-branch@232749 138bc75d-0d04-0410-961f-82ee72b054a4 ... but that's still missing on trunk. That patch also removes some of the ftmp/itmp/ltmp checks in atomic_capture-1.f90, but not the one mentioned in I. III. It may still be a good idea to check the result of fdata/idata/ldata array, but not in the order-dependent fashion that's used in the example listed at II.