gomp_map_vars_internal contains:

          if ((kind & typemask) == GOMP_MAP_TO_PSET)
            {
              size_t j;
              for (j = i + 1; j < mapnum; j++)
                if (!GOMP_MAP_POINTER_P (get_kind (short_mapkind, kinds, j)

where one accesses not only the i-th hostaddr but items following it.

On the other hand, in GOMP_target_enter_exit_data one currently has:

    for (i = 0; i < mapnum; i++)
      if ((kinds[i] & 0xff) == GOMP_MAP_STRUCT) …
      else
        gomp_map_vars (devicep, 1, &hostaddrs[i], NULL, &sizes[i], &kinds[i],
                       true, GOMP_MAP_VARS_ENTER_DATA);
passing the argument one by one.

I first thought to pass all non MAP_STRUCT items as block before the
MAP_STRUCT, then a MAP_STRUCT and then try to group the next items.

However, I could not find a difference between MAP_STRUCT and not,
hence, I now decided to simply pass the data on "as is".

OK for mainline? (What about older versions?)

Cheers,

Tobias

-----------------
Mentor Graphics (Deutschland) GmbH, Arnulfstraße 201, 80634 München / Germany
Registergericht München HRB 106955, Geschäftsführer: Thomas Heurung, Alexander 
Walter
libgomp – fix handling of 'target enter data'

	* target.c (GOMP_target_enter_exit_data): Call gomp_map_vars with
	multiples args at once.
	* testsuite/libgomp.fortran/target-enter-data-1.f90: New.

 libgomp/target.c                                   | 13 ++------
 .../libgomp.fortran/target-enter-data-1.f90        | 36 ++++++++++++++++++++++
 2 files changed, 38 insertions(+), 11 deletions(-)

diff --git a/libgomp/target.c b/libgomp/target.c
index c99dd5196fa..3de85434f5d 100644
--- a/libgomp/target.c
+++ b/libgomp/target.c
@@ -2480,18 +2480,9 @@ GOMP_target_enter_exit_data (int device, size_t mapnum, void **hostaddrs,
 	}
     }
 
-  size_t i;
   if ((flags & GOMP_TARGET_FLAG_EXIT_DATA) == 0)
-    for (i = 0; i < mapnum; i++)
-      if ((kinds[i] & 0xff) == GOMP_MAP_STRUCT)
-	{
-	  gomp_map_vars (devicep, sizes[i] + 1, &hostaddrs[i], NULL, &sizes[i],
-			 &kinds[i], true, GOMP_MAP_VARS_ENTER_DATA);
-	  i += sizes[i];
-	}
-      else
-	gomp_map_vars (devicep, 1, &hostaddrs[i], NULL, &sizes[i], &kinds[i],
-		       true, GOMP_MAP_VARS_ENTER_DATA);
+    gomp_map_vars (devicep, mapnum, hostaddrs, NULL, sizes, kinds,
+		   true, GOMP_MAP_VARS_ENTER_DATA);
   else
     gomp_exit_data (devicep, mapnum, hostaddrs, sizes, kinds);
 }
diff --git a/libgomp/testsuite/libgomp.fortran/target-enter-data-1.f90 b/libgomp/testsuite/libgomp.fortran/target-enter-data-1.f90
new file mode 100644
index 00000000000..91dedebf0a0
--- /dev/null
+++ b/libgomp/testsuite/libgomp.fortran/target-enter-data-1.f90
@@ -0,0 +1,36 @@
+program main
+  implicit none
+  integer, allocatable, dimension(:) :: AA, BB, CC, DD
+  integer :: i, N = 20
+
+  allocate(BB(N))
+  AA = [(i, i=1,N)]
+
+  !$omp target enter data map(alloc: BB)
+  !$omp target enter data map(to: AA)
+
+  !$omp target
+    BB = 3 * AA
+  !$omp end target
+
+  !$omp target exit data map(delete: AA)
+  !$omp target exit data map(from: BB)
+
+  if (any (BB /= [(3*i, i=1,N)])) stop 1
+  if (any (AA /= [(i, i=1,N)])) stop 2
+
+
+  CC = 31 * BB
+  DD = [(-i, i=1,N)]
+
+  !$omp target enter data map(to: CC) map(alloc: DD)
+
+  !$omp target
+    DD = 5 * CC
+  !$omp end target
+
+  !$omp target exit data map(delete: CC) map(from: DD)
+
+  if (any (CC /= [(31*3*i, i=1,N)])) stop 3
+  if (any (DD /= [(31*3*5*i, i=1,N)])) stop 4
+end

Reply via email to