diff --git a/gcc/omp-low.cc b/gcc/omp-low.cc index d36756e33a5..6fd685cdecd 100644 --- a/gcc/omp-low.cc +++ b/gcc/omp-low.cc @@ -13240,7 +13240,20 @@ lower_omp_target (gimple_stmt_iterator *gsi_p, omp_context *ctx) unsigned HOST_WIDE_INT tkind2; switch (OMP_CLAUSE_CODE (c)) { - case OMP_CLAUSE_MAP: tkind2 = OMP_CLAUSE_MAP_KIND (c); break; + case OMP_CLAUSE_MAP: + tkind2 = OMP_CLAUSE_MAP_KIND (c); + if (OMP_CLAUSE_MAP_RUNTIME_IMPLICIT_P (c) + && (((tkind2 & GOMP_MAP_FLAG_SPECIAL_BITS) + & ~GOMP_MAP_IMPLICIT) + == 0)) + { + /* If this is an implicit map, and the GOMP_MAP_IMPLICIT + bits are not interfered by other special bit + encodings, then turn the GOMP_IMPLICIT_BIT flag on + for the runtime to see. */ + tkind2 |= GOMP_MAP_IMPLICIT; + } + break; case OMP_CLAUSE_FIRSTPRIVATE: tkind2 = GOMP_MAP_TO; break; case OMP_CLAUSE_TO: tkind2 = GOMP_MAP_TO; break; case OMP_CLAUSE_FROM: tkind2 = GOMP_MAP_FROM; break; diff --git a/libgomp/target.c b/libgomp/target.c index 49d4218b1f7..af7c702d439 100644 --- a/libgomp/target.c +++ b/libgomp/target.c @@ -1665,14 +1665,14 @@ gomp_map_vars_internal (struct gomp_device_descr *devicep, case GOMP_MAP_STRUCT_UNORD: if (sizes[i] > 1) { - void *first = hostaddrs[i + 1]; for (size_t j = i + 1; j < i + sizes[i]; j++) - if (hostaddrs[j + 1] != first) + if (hostaddrs[j + 1] < hostaddrs[j]) { gomp_mutex_unlock (&devicep->lock); - gomp_fatal ("Mapped array elements must be the " - "same (%p vs %p)", first, - hostaddrs[j + 1]); + gomp_fatal ( + "Mapped array elements must be the same or in " + "increasing address order (got %p > %p)", + hostaddrs[j], hostaddrs[j + 1]); } } /* Fallthrough. */ diff --git a/libgomp/testsuite/libgomp.c-c++-common/map-arrayofstruct-2.c b/libgomp/testsuite/libgomp.c-c++-common/map-arrayofstruct-2.c index ff7ce0eb162..55bd60772a0 100644 --- a/libgomp/testsuite/libgomp.c-c++-common/map-arrayofstruct-2.c +++ b/libgomp/testsuite/libgomp.c-c++-common/map-arrayofstruct-2.c @@ -54,5 +54,5 @@ int main (void) } /* { dg-output "(\n|\r|\r\n)" { target offload_device_nonshared_as } } */ -/* { dg-output "libgomp: Mapped array elements must be the same .*(\n|\r|\r\n)+" { target offload_device_nonshared_as } } */ +/* { dg-output "libgomp: Mapped array elements must be the same or in increasing address order .*(\n|\r|\r\n)+" { target offload_device_nonshared_as } } */ /* { dg-shouldfail "" { offload_device_nonshared_as } } */ diff --git a/libgomp/testsuite/libgomp.c-c++-common/map-arrayofstruct-3.c b/libgomp/testsuite/libgomp.c-c++-common/map-arrayofstruct-3.c index 770ac2ae1aa..0352682d042 100644 --- a/libgomp/testsuite/libgomp.c-c++-common/map-arrayofstruct-3.c +++ b/libgomp/testsuite/libgomp.c-c++-common/map-arrayofstruct-3.c @@ -64,5 +64,5 @@ int main (void) } /* { dg-output "(\n|\r|\r\n)" { target offload_device_nonshared_as } } */ -/* { dg-output "libgomp: Mapped array elements must be the same .*(\n|\r|\r\n)+" { target offload_device_nonshared_as } } */ +/* { dg-output "libgomp: Mapped array elements must be the same or in increasing address order .*(\n|\r|\r\n)+" { target offload_device_nonshared_as } } */ /* { dg-shouldfail "" { offload_device_nonshared_as } } */ diff --git a/libgomp/testsuite/libgomp.fortran/map-subarray-10.f90 b/libgomp/testsuite/libgomp.fortran/map-subarray-10.f90 new file mode 100644 index 00000000000..9afb8458849 --- /dev/null +++ b/libgomp/testsuite/libgomp.fortran/map-subarray-10.f90 @@ -0,0 +1,40 @@ +! { dg-do run } + +! PR fortran/120505 + +! This test case checks that explicit mapping of allocatable DT components from +! different containing array elements followed by implicit deep mapping works. + +module m +type t + integer, allocatable :: den1(:,:), den2(:,:) +end type t + +type t2 + type(t), allocatable :: tiles(:) +end type t2 + +type(t2) :: var +end + +use m + +allocate(var%tiles(2)) +var%tiles(1)%den1 = reshape([1,2,3,4],[2,2]) +var%tiles(2)%den2 = reshape([11,22,33,44],[2,2]) + +!$omp target enter data map(var%tiles(1)%den1, var%tiles(2)%den2) + +!$omp target + if (any (var%tiles(1)%den1 /= reshape([1,2,3,4],[2,2]))) stop 1 + if (any (var%tiles(2)%den2 /= reshape([11,22,33,44],[2,2]))) stop 1 + var%tiles(1)%den1 = var%tiles(1)%den1 + 5 + var%tiles(2)%den2 = var%tiles(2)%den2 + 7 +!$omp end target + +!$omp target exit data map(var%tiles(1)%den1, var%tiles(2)%den2) + +if (any (var%tiles(1)%den1 /= 5 + reshape([1,2,3,4],[2,2]))) stop 1 +if (any (var%tiles(2)%den2 /= 7 + reshape([11,22,33,44],[2,2]))) stop 1 + +end diff --git a/libgomp/testsuite/libgomp.fortran/map-subarray-5.f90 b/libgomp/testsuite/libgomp.fortran/map-subarray-5.f90 index 59ad01ab76b..7bf3102018e 100644 --- a/libgomp/testsuite/libgomp.fortran/map-subarray-5.f90 +++ b/libgomp/testsuite/libgomp.fortran/map-subarray-5.f90 @@ -50,5 +50,5 @@ end do end ! { dg-output "(\n|\r|\r\n)" { target offload_device_nonshared_as } } -! { dg-output "libgomp: Mapped array elements must be the same .*(\n|\r|\r\n)+" { target offload_device_nonshared_as } } +! { dg-output "libgomp: Mapped array elements must be the same or in increasing address order .*(\n|\r|\r\n)+" { target offload_device_nonshared_as } } ! { dg-shouldfail "" { offload_device_nonshared_as } } diff --git a/libgomp/testsuite/libgomp.fortran/map-subarray-9.f90 b/libgomp/testsuite/libgomp.fortran/map-subarray-9.f90 new file mode 100644 index 00000000000..f3101559903 --- /dev/null +++ b/libgomp/testsuite/libgomp.fortran/map-subarray-9.f90 @@ -0,0 +1,40 @@ +! { dg-do run } + +! PR fortran/120505 + +! This test case checks that explicit mapping of allocatable DT components +! followed by implicit deep mapping works. + +module m +type t + integer, allocatable :: den1(:,:), den2(:,:) +end type t + +type t2 + type(t), allocatable :: tiles(:) +end type t2 + +type(t2) :: var +end + +use m + +allocate(var%tiles(1)) +var%tiles(1)%den1 = reshape([1,2,3,4],[2,2]) +var%tiles(1)%den2 = reshape([11,22,33,44],[2,2]) + +!$omp target enter data map(var%tiles(1)%den1, var%tiles(1)%den2) + +!$omp target + if (any (var%tiles(1)%den1 /= reshape([1,2,3,4],[2,2]))) stop 1 + if (any (var%tiles(1)%den2 /= reshape([11,22,33,44],[2,2]))) stop 1 + var%tiles(1)%den1 = var%tiles(1)%den1 + 5 + var%tiles(1)%den2 = var%tiles(1)%den2 + 7 +!$omp end target + +!$omp target exit data map(var%tiles(1)%den1, var%tiles(1)%den2) + +if (any (var%tiles(1)%den1 /= 5 + reshape([1,2,3,4],[2,2]))) stop 1 +if (any (var%tiles(1)%den2 /= 7 + reshape([11,22,33,44],[2,2]))) stop 1 + +end