I introduced a subtle bug in my fix for pr70828. That PR involved implicit data mappings of subarrays which the user had explicitly mapped inside an enclosing acc data region. E.g.
#pragma acc data copy(a[5:10]) { #pragma acc parallel loop for (...) a[i] = ... My fix for the PR was to duplicate the associated GOMP_MAP_POINTER clause for that subarray in the enclosing data region in the parallel region. However, the code inside gomp_needs_present_data doesn't check whether the decl in the GOMP_MAP_POINTER clause matches the incoming decl supplied to this function, which leads to bogus data clauses and failures at run time. I've applied this patch to gomp-4_0-branch to fix that. Cesar
2017-05-11 Cesar Philippidis <ce...@codesourcery.com> gcc/ * gimplify.c (gomp_needs_data_present): Ensure that the correct decl is matched when scanning clauses in the enclosing acc data constructs. libgomp/ * testsuite/libgomp.oacc-fortran/implicit_copy.f90: New test. diff --git a/gcc/gimplify.c b/gcc/gimplify.c index 47fe9ee..5a25dcf 100644 --- a/gcc/gimplify.c +++ b/gcc/gimplify.c @@ -7885,10 +7885,15 @@ gomp_needs_data_present (tree decl) break; for (c = ctx->clauses; c; c = OMP_CLAUSE_CHAIN (c)) - if (OMP_CLAUSE_CODE (c) == OMP_CLAUSE_MAP - && (omp_clause_matching_array_ref (c, decl) - || OMP_CLAUSE_MAP_KIND (c) == GOMP_MAP_POINTER)) + { + if (OMP_CLAUSE_CODE (c) != OMP_CLAUSE_MAP) + continue; + if (omp_clause_matching_array_ref (c, decl)) + return c; + else if (OMP_CLAUSE_DECL (c) == decl + && OMP_CLAUSE_MAP_KIND (c) == GOMP_MAP_POINTER) return c; + } } return NULL_TREE; diff --git a/libgomp/testsuite/libgomp.oacc-fortran/implicit_copy.f90 b/libgomp/testsuite/libgomp.oacc-fortran/implicit_copy.f90 new file mode 100644 index 0000000..f0d4064 --- /dev/null +++ b/libgomp/testsuite/libgomp.oacc-fortran/implicit_copy.f90 @@ -0,0 +1,29 @@ +integer function test() + implicit none + integer, parameter :: n = 10 + real(8), dimension(n) :: a, b, c + integer i + + do i = 1, n + a(i) = i + b(i) = 1 + end do + + !$acc data copyin(a(1:n), b(1:n)) + !$acc parallel loop + do i = 1, n + c(i) = a(i) * b(i) + end do + !$acc end data + + do i = 1, n + if (c(i) /= a(i) * b(i)) call abort + end do +end function test + +program main + implicit none + integer i, test + i = test() +end program main +