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

Reply via email to