From 561ffc69c504b2c897fc2991cf0bb99defa80efb Mon Sep 17 00:00:00 2001
From: tschwinge <tschwinge@138bc75d-0d04-0410-961f-82ee72b054a4>
Date: Tue, 18 Jun 2019 22:14:24 +0000
Subject: [PATCH] [PR90743] Fortran 'allocatable' with OpenACC data/OpenMP
 'target' 'map' clauses

Test what OpenMP 5.0 has to say on this topic.  And, do the same for OpenACC.

	libgomp/
	PR fortran/90743
	* oacc-parallel.c (GOACC_parallel_keyed): Handle NULL mapping
	case.
	* testsuite/libgomp.fortran/target-allocatable-1-1.f90: New file.
	* testsuite/libgomp.fortran/target-allocatable-1-2.f90: Likewise.
	* testsuite/libgomp.oacc-fortran/allocatable-1-1.f90: Likewise.
	* testsuite/libgomp.oacc-fortran/allocatable-1-2.f90: Likewise.

git-svn-id: svn+ssh://gcc.gnu.org/svn/gcc/trunk@272447 138bc75d-0d04-0410-961f-82ee72b054a4
---
 libgomp/ChangeLog                             |  8 ++
 libgomp/oacc-parallel.c                       |  9 +-
 .../target-allocatable-1-1.f90                | 69 ++++++++++++++++
 .../target-allocatable-1-2.f90                | 82 +++++++++++++++++++
 .../libgomp.oacc-fortran/allocatable-1-1.f90  | 68 +++++++++++++++
 .../libgomp.oacc-fortran/allocatable-1-2.f90  | 81 ++++++++++++++++++
 6 files changed, 314 insertions(+), 3 deletions(-)
 create mode 100644 libgomp/testsuite/libgomp.fortran/target-allocatable-1-1.f90
 create mode 100644 libgomp/testsuite/libgomp.fortran/target-allocatable-1-2.f90
 create mode 100644 libgomp/testsuite/libgomp.oacc-fortran/allocatable-1-1.f90
 create mode 100644 libgomp/testsuite/libgomp.oacc-fortran/allocatable-1-2.f90

diff --git a/libgomp/ChangeLog b/libgomp/ChangeLog
index 1a0d363e4ba2..62c45828a009 100644
--- a/libgomp/ChangeLog
+++ b/libgomp/ChangeLog
@@ -1,5 +1,13 @@
 2019-06-18  Thomas Schwinge  <thomas@codesourcery.com>
 
+	PR fortran/90743
+	* oacc-parallel.c (GOACC_parallel_keyed): Handle NULL mapping
+	case.
+	* testsuite/libgomp.fortran/target-allocatable-1-1.f90: New file.
+	* testsuite/libgomp.fortran/target-allocatable-1-2.f90: Likewise.
+	* testsuite/libgomp.oacc-fortran/allocatable-1-1.f90: Likewise.
+	* testsuite/libgomp.oacc-fortran/allocatable-1-2.f90: Likewise.
+
 	PR testsuite/90861
 	* testsuite/libgomp.oacc-c-c++-common/declare-vla.c: Update.
 
diff --git a/libgomp/oacc-parallel.c b/libgomp/oacc-parallel.c
index e56330f6226b..0c2cfa05a438 100644
--- a/libgomp/oacc-parallel.c
+++ b/libgomp/oacc-parallel.c
@@ -325,9 +325,12 @@ GOACC_parallel_keyed (int flags_m, void (*fn) (void *),
   
   devaddrs = gomp_alloca (sizeof (void *) * mapnum);
   for (i = 0; i < mapnum; i++)
-    devaddrs[i] = (void *) (tgt->list[i].key->tgt->tgt_start
-			    + tgt->list[i].key->tgt_offset
-			    + tgt->list[i].offset);
+    if (tgt->list[i].key != NULL)
+      devaddrs[i] = (void *) (tgt->list[i].key->tgt->tgt_start
+			      + tgt->list[i].key->tgt_offset
+			      + tgt->list[i].offset);
+    else
+      devaddrs[i] = NULL;
   if (aq == NULL)
     acc_dev->openacc.exec_func (tgt_fn, mapnum, hostaddrs, devaddrs, dims,
 				tgt);
diff --git a/libgomp/testsuite/libgomp.fortran/target-allocatable-1-1.f90 b/libgomp/testsuite/libgomp.fortran/target-allocatable-1-1.f90
new file mode 100644
index 000000000000..429a855a20b2
--- /dev/null
+++ b/libgomp/testsuite/libgomp.fortran/target-allocatable-1-1.f90
@@ -0,0 +1,69 @@
+! Test 'allocatable' with OpenMP 'target' 'map' clauses.
+
+! See also '../libgomp.oacc-fortran/allocatable-1-1.f90'.
+
+! { dg-do run }
+! { dg-additional-options "-cpp" }
+! { dg-additional-options "-DMEM_SHARED" { target offload_device_shared_as } }
+
+program main
+  implicit none
+  integer, allocatable :: a, b, c, d, e
+
+  allocate (a)
+  a = 11
+
+  b = 25 ! Implicit allocation.
+
+  c = 52 ! Implicit allocation.
+
+  !No 'allocate (d)' here.
+
+  !No 'allocate (e)' here.
+
+  !$omp target map(to: a) map(tofrom: b, c, d) map(from: e)
+
+  if (.not. allocated (a)) stop 1
+  if (a .ne. 11) stop 2
+  a = 33
+
+  if (.not. allocated (b)) stop 3
+  if (b .ne. 25) stop 4
+
+  if (.not. allocated (c)) stop 5
+  if (c .ne. 52) stop 6
+  c = 10
+
+  if (allocated (d)) stop 7
+  d = 42 ! Implicit allocation, but on device only.
+  if (.not. allocated (d)) stop 8
+  deallocate (d) ! OpenMP requires must be "unallocated upon exit from the region".
+
+  if (allocated (e)) stop 9
+  e = 24 ! Implicit allocation, but on device only.
+  if (.not. allocated (e)) stop 10
+  deallocate (e) ! OpenMP requires must be "unallocated upon exit from the region".
+
+  !$omp end target
+
+  if (.not. allocated (a)) stop 20
+#ifdef MEM_SHARED
+  if (a .ne. 33) stop 21
+#else
+  if (a .ne. 11) stop 22
+#endif
+  deallocate (a)
+
+  if (.not. allocated (b)) stop 23
+  if (b .ne. 25) stop 24
+  deallocate (b)
+
+  if (.not. allocated (c)) stop 25
+  if (c .ne. 10) stop 26
+  deallocate (c)
+
+  if (allocated (d)) stop 27
+
+  if (allocated (e)) stop 28
+
+end program main
diff --git a/libgomp/testsuite/libgomp.fortran/target-allocatable-1-2.f90 b/libgomp/testsuite/libgomp.fortran/target-allocatable-1-2.f90
new file mode 100644
index 000000000000..5301c8eeffbd
--- /dev/null
+++ b/libgomp/testsuite/libgomp.fortran/target-allocatable-1-2.f90
@@ -0,0 +1,82 @@
+! Test 'allocatable' with OpenMP 'target' 'map' clauses, subroutine in module,
+! pass by reference.
+
+! See also '../libgomp.oacc-fortran/allocatable-1-2.f90'.
+
+! { dg-do run }
+! { dg-additional-options "-cpp" }
+! { dg-additional-options "-DMEM_SHARED" { target offload_device_shared_as } }
+
+module m
+contains
+  subroutine r (a, b, c, d, e)
+    implicit none
+    integer, allocatable :: a, b, c, d, e
+
+    !$omp target map(to: a) map(tofrom: b, c, d) map(from: e)
+
+    if (.not. allocated (a)) stop 1
+    if (a .ne. 11) stop 2
+    a = 33
+
+    if (.not. allocated (b)) stop 3
+    if (b .ne. 25) stop 4
+
+    if (.not. allocated (c)) stop 5
+    if (c .ne. 52) stop 6
+    c = 10
+
+    if (allocated (d)) stop 7
+    d = 42 ! Implicit allocation, but on device only.
+    if (.not. allocated (d)) stop 8
+    deallocate (d) ! OpenMP requires must be "unallocated upon exit from the region".
+
+    if (allocated (e)) stop 9
+    e = 24 ! Implicit allocation, but on device only.
+    if (.not. allocated (e)) stop 10
+    deallocate (e) ! OpenMP requires must be "unallocated upon exit from the region".
+
+    !$omp end target
+
+  end subroutine r
+end module m
+
+program main
+  use m
+  implicit none
+  integer, allocatable :: a, b, c, d, e
+
+  allocate (a)
+  a = 11
+
+  b = 25 ! Implicit allocation.
+
+  c = 52 ! Implicit allocation.
+
+  !No 'allocate (d)' here.
+
+  !No 'allocate (e)' here.
+
+  call r(a, b, c, d, e)
+
+  if (.not. allocated (a)) stop 20
+#ifdef MEM_SHARED
+  if (a .ne. 33) stop 21
+#else
+  if (a .ne. 11) stop 22
+#endif
+  deallocate (a)
+
+  if (.not. allocated (b)) stop 23
+  if (b .ne. 25) stop 24
+  deallocate (b)
+
+  if (.not. allocated (c)) stop 25
+  if (c .ne. 10) stop 26
+  deallocate (c)
+
+  if (allocated (d)) stop 27
+
+  if (allocated (e)) stop 28
+
+end program main
diff --git a/libgomp/testsuite/libgomp.oacc-fortran/allocatable-1-1.f90 b/libgomp/testsuite/libgomp.oacc-fortran/allocatable-1-1.f90
new file mode 100644
index 000000000000..e5981312f148
--- /dev/null
+++ b/libgomp/testsuite/libgomp.oacc-fortran/allocatable-1-1.f90
@@ -0,0 +1,68 @@
+! Test 'allocatable' with OpenACC data clauses.
+
+! See also '../libgomp.fortran/target-allocatable-1-1.f90'.
+
+! { dg-do run }
+! { dg-additional-options "-cpp" }
+
+program main
+  implicit none
+  integer, allocatable :: a, b, c, d, e
+
+  allocate (a)
+  a = 11
+
+  b = 25 ! Implicit allocation.
+
+  c = 52 ! Implicit allocation.
+
+  !No 'allocate (d)' here.
+
+  !No 'allocate (e)' here.
+
+  !$acc parallel copyin(a) copy(b, c, d) copyout(e)
+
+  if (.not. allocated (a)) stop 1
+  if (a .ne. 11) stop 2
+  a = 33
+
+  if (.not. allocated (b)) stop 3
+  if (b .ne. 25) stop 4
+
+  if (.not. allocated (c)) stop 5
+  if (c .ne. 52) stop 6
+  c = 10
+
+  if (allocated (d)) stop 7
+  d = 42 ! Implicit allocation, but on device only.
+  if (.not. allocated (d)) stop 8
+  deallocate (d) ! OpenMP requires must be "unallocated upon exit from the region".
+
+  if (allocated (e)) stop 9
+  e = 24 ! Implicit allocation, but on device only.
+  if (.not. allocated (e)) stop 10
+  deallocate (e) ! OpenMP requires must be "unallocated upon exit from the region".
+
+  !$acc end parallel
+
+  if (.not. allocated (a)) stop 20
+#if ACC_MEM_SHARED
+  if (a .ne. 33) stop 21
+#else
+  if (a .ne. 11) stop 22
+#endif
+  deallocate (a)
+
+  if (.not. allocated (b)) stop 23
+  if (b .ne. 25) stop 24
+  deallocate (b)
+
+  if (.not. allocated (c)) stop 25
+  if (c .ne. 10) stop 26
+  deallocate (c)
+
+  if (allocated (d)) stop 27
+
+  if (allocated (e)) stop 28
+
+end program main
diff --git a/libgomp/testsuite/libgomp.oacc-fortran/allocatable-1-2.f90 b/libgomp/testsuite/libgomp.oacc-fortran/allocatable-1-2.f90
new file mode 100644
index 000000000000..2faf0f8078f0
--- /dev/null
+++ b/libgomp/testsuite/libgomp.oacc-fortran/allocatable-1-2.f90
@@ -0,0 +1,81 @@
+! Test 'allocatable' with OpenACC data clauses, subroutine in module, pass by
+! reference.
+
+! See also '../libgomp.fortran/target-allocatable-1-2.f90'.
+
+! { dg-do run }
+! { dg-additional-options "-cpp" }
+
+module m
+contains
+  subroutine r (a, b, c, d, e)
+    implicit none
+    integer, allocatable :: a, b, c, d, e
+
+    !$acc parallel copyin(a) copy(b, c, d) copyout(e)
+
+    if (.not. allocated (a)) stop 1
+    if (a .ne. 11) stop 2
+    a = 33
+
+    if (.not. allocated (b)) stop 3
+    if (b .ne. 25) stop 4
+
+    if (.not. allocated (c)) stop 5
+    if (c .ne. 52) stop 6
+    c = 10
+
+    if (allocated (d)) stop 7
+    d = 42 ! Implicit allocation, but on device only.
+    if (.not. allocated (d)) stop 8
+    deallocate (d) ! OpenMP requires must be "unallocated upon exit from the region".
+
+    if (allocated (e)) stop 9
+    e = 24 ! Implicit allocation, but on device only.
+    if (.not. allocated (e)) stop 10
+    deallocate (e) ! OpenMP requires must be "unallocated upon exit from the region".
+
+    !$acc end parallel
+
+  end subroutine r
+end module m
+
+program main
+  use m
+  implicit none
+  integer, allocatable :: a, b, c, d, e
+
+  allocate (a)
+  a = 11
+
+  b = 25 ! Implicit allocation.
+
+  c = 52 ! Implicit allocation.
+
+  !No 'allocate (d)' here.
+
+  !No 'allocate (e)' here.
+
+  call r(a, b, c, d, e)
+
+  if (.not. allocated (a)) stop 20
+#if ACC_MEM_SHARED
+  if (a .ne. 33) stop 21
+#else
+  if (a .ne. 11) stop 22
+#endif
+  deallocate (a)
+
+  if (.not. allocated (b)) stop 23
+  if (b .ne. 25) stop 24
+  deallocate (b)
+
+  if (.not. allocated (c)) stop 25
+  if (c .ne. 10) stop 26
+  deallocate (c)
+
+  if (allocated (d)) stop 27
+
+  if (allocated (e)) stop 28
+
+end program main
-- 
2.20.1

