Next try – with the proper patch instead of a full test case.
On 4/17/20 5:54 PM, Tobias Burnus wrote:
It turned out that doing
omp enter data map(alloc:FortranArray)
omp exit data map(delete:FortranArray)
left the array descriptor (fortranarray [as opposed to
fortranarray.data])
on the device. (cf. -fdump-tree-omplower in the PR.)
Mapping FortranArray again (e.g. "map(tofrom:FortranArray)")
then failed by returning garbage.
This patch now removes the descriptor with 'data exit',
which was passed as MAP_TO_PSET clause to the middle end,
but got removed. Instead, the clause is now turned into MAP_DELETE.
Build on x86-64-gnu-linux and tested without and with AMDGCN
as offloading device. OK for the trunk?
Tobias
-----------------
Mentor Graphics (Deutschland) GmbH, Arnulfstraße 201, 80634 München / Germany
Registergericht München HRB 106955, Geschäftsführer: Thomas Heurung, Alexander
Walter
[OpenMP] Fix 'omp exit data' for Fortran arrays (PR 94635)
PR middle-end/94635
* gimplify.c (gimplify_scan_omp_clauses): Turn MAP_TO_PSET to
MAP_DELETE.
PR middle-end/94635
* testsuite/libgomp.fortran/target-enter-data-2.F90: New.
gcc/gimplify.c | 14 +++++---
.../libgomp.fortran/target-enter-data-2.F90 | 40 ++++++++++++++++++++++
2 files changed, 49 insertions(+), 5 deletions(-)
diff --git a/gcc/gimplify.c b/gcc/gimplify.c
index 8cdfae26510..6fd8196f01c 100644
--- a/gcc/gimplify.c
+++ b/gcc/gimplify.c
@@ -8785,11 +8785,15 @@ gimplify_scan_omp_clauses (tree *list_p, gimple_seq *pre_p,
'exit data' - and in particular for 'delete:' - having an 'alloc:'
does not make sense. Likewise, for 'update' only transferring the
data itself is needed as the rest has been handled in previous
- directives. */
- if ((code == OMP_TARGET_EXIT_DATA || code == OMP_TARGET_UPDATE)
- && (OMP_CLAUSE_MAP_KIND (c) == GOMP_MAP_POINTER
- || OMP_CLAUSE_MAP_KIND (c) == GOMP_MAP_TO_PSET))
- remove = true;
+ directives. However, for 'exit data', the array descriptor needs
+ to be delete; hence, we turn the MAP_TO_PSET into a MAP_DELETE. */
+ if (code == OMP_TARGET_EXIT_DATA
+ && OMP_CLAUSE_MAP_KIND (c) == GOMP_MAP_TO_PSET)
+ OMP_CLAUSE_SET_MAP_KIND (c, GOMP_MAP_DELETE);
+ else if ((code == OMP_TARGET_EXIT_DATA || code == OMP_TARGET_UPDATE)
+ && (OMP_CLAUSE_MAP_KIND (c) == GOMP_MAP_POINTER
+ || OMP_CLAUSE_MAP_KIND (c) == GOMP_MAP_TO_PSET))
+ remove = true;
if (remove)
break;
diff --git a/libgomp/testsuite/libgomp.fortran/target-enter-data-2.F90 b/libgomp/testsuite/libgomp.fortran/target-enter-data-2.F90
new file mode 100644
index 00000000000..320d8bf419f
--- /dev/null
+++ b/libgomp/testsuite/libgomp.fortran/target-enter-data-2.F90
@@ -0,0 +1,40 @@
+! { dg-additional-options "-DMEM_SHARED" { target offload_device_shared_as } }
+!
+! PR middle-end/94635
+ implicit none
+ integer, parameter :: N = 20
+ integer, allocatable, dimension(:) :: my1DPtr
+ integer, dimension(N) :: my1DArr
+ integer :: i
+
+ allocate(my1DPtr(N))
+ my1DPtr = 43
+
+ !$omp target enter data map(alloc: my1DPtr)
+ !$omp target
+ my1DPtr = [(i , i = 1, N)]
+ !$omp end target
+
+ !$omp target map(from: my1DArr)
+ my1DArr = my1DPtr
+ !$omp end target
+ !$omp target exit data map(delete: my1DPtr)
+
+ if (any (my1DArr /= [(i, i = 1, N)])) stop 1
+#if MEM_SHARED
+ if (any (my1DArr /= my1DPtr)) stop 2
+#else
+ if (any (43 /= my1DPtr)) stop 3
+#endif
+
+ my1DPtr = [(2*N-i, i = 1, N)]
+ my1DArr = 42
+
+ !$omp target map(tofrom: my1DArr) map(tofrom: my1DPtr(:))
+ my1DArr = my1DPtr
+ my1DPtr = 20
+ !$omp end target
+
+ if (any (my1DArr /= [(2*N-i, i = 1, N)])) stop 4
+ if (any (20 /= my1DPtr)) stop 6
+end