[llvm] [OpenMP] Allocatable explicit member mapping fortran offloading tests (PR #111190)

via llvm-commits llvm-commits at lists.llvm.org
Fri Oct 4 11:37:24 PDT 2024


https://github.com/agozillon created https://github.com/llvm/llvm-project/pull/111190

This PR is one in a series of 3 that aim to add support for explicit member mapping of
allocatable components in derived types within OpenMP+Fortran for Flang.

This PR provides all of the runtime tests that are currently upstreamable, unfortunately
some of the other tests would require linking of the fortran runtime for offload which
we currently do not do. But regardless, this is plenty to ensure that the mapping is
working in most cases.


>From 00df4378bb9f4595bc54779d78f2110c3888b5d5 Mon Sep 17 00:00:00 2001
From: agozillon <Andrew.Gozillon at amd.com>
Date: Fri, 4 Oct 2024 13:37:14 -0500
Subject: [PATCH] =?UTF-8?q?[=F0=9D=98=80=F0=9D=97=BD=F0=9D=97=BF]=20initia?=
 =?UTF-8?q?l=20version?=
MIME-Version: 1.0
Content-Type: text/plain; charset=UTF-8
Content-Transfer-Encoding: 8bit

Created using spr 1.3.4
---
 .../dtype-array-constant-index-map.f90        |   8 +-
 .../fortran/dtype-member-map-syntax-1.f90     | 110 +++++++++++
 .../fortran/dtype-member-map-syntax-2.f90     | 176 ++++++++++++++++++
 ...map-alloca-dtype-alloca-array-of-dtype.f90 |  36 ++++
 .../target-map-alloca-dtype-alloca-array.f90  |  30 +++
 ...t-map-alloca-dtype-and-alloca-array-v2.f90 |  35 ++++
 ...rget-map-alloca-dtype-and-alloca-array.f90 |  34 ++++
 ...rget-map-alloca-dtype-array-and-scalar.f90 |  40 ++++
 ...target-map-alloca-dtype-array-of-dtype.f90 |  36 ++++
 .../fortran/target-map-allocatable-dtype.f90  |  32 ++++
 ...t-map-double-nested-dtype-array-bounds.f90 |   2 +-
 ...-map-dtype-3d-alloca-array-with-bounds.f90 |  42 +++++
 ...-map-dtype-alloca-and-non-alloca-array.f90 |  36 ++++
 ...type-alloca-array-and-non-alloca-dtype.f90 |  45 +++++
 ...target-map-dtype-alloca-array-of-dtype.f90 |  35 ++++
 ...get-map-dtype-alloca-array-with-bounds.f90 |  30 +++
 .../target-map-dtype-allocatable-array.f90    |  28 +++
 ...map-dtype-allocatable-scalar-and-array.f90 |  34 ++++
 ...lloca-dtypes-with-multi-alloca-members.f90 |  90 +++++++++
 ...alloca-dtypes-with-multi-mixed-members.f90 |  82 ++++++++
 ...ed-alloca-dtype-3d-alloca-array-bounds.f90 |  51 +++++
 ...ested-alloca-dtype-alloca-array-bounds.f90 |  43 +++++
 ...sted-dtype-3d-alloca-array-with-bounds.f90 |  50 +++++
 ...sted-dtype-alloca-and-non-alloca-array.f90 |  47 +++++
 ...type-alloca-array-and-non-alloca-dtype.f90 |  51 +++++
 ...-nested-dtype-alloca-array-with-bounds.f90 |  43 +++++
 .../target-map-nested-dtype-alloca-array.f90  |  38 ++++
 ...ap-pointer-to-dtype-allocatable-member.f90 |  46 +++++
 28 files changed, 1322 insertions(+), 8 deletions(-)
 create mode 100644 offload/test/offloading/fortran/dtype-member-map-syntax-1.f90
 create mode 100644 offload/test/offloading/fortran/dtype-member-map-syntax-2.f90
 create mode 100644 offload/test/offloading/fortran/target-map-alloca-dtype-alloca-array-of-dtype.f90
 create mode 100644 offload/test/offloading/fortran/target-map-alloca-dtype-alloca-array.f90
 create mode 100644 offload/test/offloading/fortran/target-map-alloca-dtype-and-alloca-array-v2.f90
 create mode 100644 offload/test/offloading/fortran/target-map-alloca-dtype-and-alloca-array.f90
 create mode 100644 offload/test/offloading/fortran/target-map-alloca-dtype-array-and-scalar.f90
 create mode 100644 offload/test/offloading/fortran/target-map-alloca-dtype-array-of-dtype.f90
 create mode 100644 offload/test/offloading/fortran/target-map-allocatable-dtype.f90
 create mode 100644 offload/test/offloading/fortran/target-map-dtype-3d-alloca-array-with-bounds.f90
 create mode 100644 offload/test/offloading/fortran/target-map-dtype-alloca-and-non-alloca-array.f90
 create mode 100644 offload/test/offloading/fortran/target-map-dtype-alloca-array-and-non-alloca-dtype.f90
 create mode 100644 offload/test/offloading/fortran/target-map-dtype-alloca-array-of-dtype.f90
 create mode 100644 offload/test/offloading/fortran/target-map-dtype-alloca-array-with-bounds.f90
 create mode 100644 offload/test/offloading/fortran/target-map-dtype-allocatable-array.f90
 create mode 100644 offload/test/offloading/fortran/target-map-dtype-allocatable-scalar-and-array.f90
 create mode 100644 offload/test/offloading/fortran/target-map-multi-alloca-dtypes-with-multi-alloca-members.f90
 create mode 100644 offload/test/offloading/fortran/target-map-multi-alloca-dtypes-with-multi-mixed-members.f90
 create mode 100644 offload/test/offloading/fortran/target-map-nested-alloca-dtype-3d-alloca-array-bounds.f90
 create mode 100644 offload/test/offloading/fortran/target-map-nested-alloca-dtype-alloca-array-bounds.f90
 create mode 100644 offload/test/offloading/fortran/target-map-nested-dtype-3d-alloca-array-with-bounds.f90
 create mode 100644 offload/test/offloading/fortran/target-map-nested-dtype-alloca-and-non-alloca-array.f90
 create mode 100644 offload/test/offloading/fortran/target-map-nested-dtype-alloca-array-and-non-alloca-dtype.f90
 create mode 100644 offload/test/offloading/fortran/target-map-nested-dtype-alloca-array-with-bounds.f90
 create mode 100644 offload/test/offloading/fortran/target-map-nested-dtype-alloca-array.f90
 create mode 100644 offload/test/offloading/fortran/target-map-pointer-to-dtype-allocatable-member.f90

diff --git a/offload/test/offloading/fortran/dtype-array-constant-index-map.f90 b/offload/test/offloading/fortran/dtype-array-constant-index-map.f90
index 7e168b846f858c..ff6787012494c0 100644
--- a/offload/test/offloading/fortran/dtype-array-constant-index-map.f90
+++ b/offload/test/offloading/fortran/dtype-array-constant-index-map.f90
@@ -5,13 +5,7 @@
 ! test helps to check that we can replace the constants
 ! within the kernel with instructions and then replace
 ! these instructions with the kernel parameters.
-! REQUIRES: flang
-! UNSUPPORTED: nvptx64-nvidia-cuda
-! UNSUPPORTED: nvptx64-nvidia-cuda-LTO
-! UNSUPPORTED: aarch64-unknown-linux-gnu
-! UNSUPPORTED: aarch64-unknown-linux-gnu-LTO
-! UNSUPPORTED: x86_64-unknown-linux-gnu
-! UNSUPPORTED: x86_64-unknown-linux-gnu-LTO
+! REQUIRES: flang, amdgpu
 
 ! RUN: %libomptarget-compile-fortran-run-and-check-generic
 module test_0
diff --git a/offload/test/offloading/fortran/dtype-member-map-syntax-1.f90 b/offload/test/offloading/fortran/dtype-member-map-syntax-1.f90
new file mode 100644
index 00000000000000..e53049e7a0c027
--- /dev/null
+++ b/offload/test/offloading/fortran/dtype-member-map-syntax-1.f90
@@ -0,0 +1,110 @@
+! This test checks a number of more complex derived type
+! member mapping syntaxes utilising a non-allocatable parent
+! derived type.
+
+! REQUIRES: flang, amdgpu
+
+! RUN: %libomptarget-compile-fortran-run-and-check-generic
+program main
+    type dtype2
+    integer int
+    real float
+    real float_elements(10)
+    end type dtype2
+
+    type dtype1
+    character (LEN=30) characters
+    character (LEN=1) character
+    type(dtype2) number
+    end type dtype1
+
+    type nonallocatabledtype
+    integer elements(20)
+    type(dtype1) num_chars
+    integer value
+    type(dtype2) internal_dtypes(5)
+    end type nonallocatabledtype
+
+    type (nonallocatabledtype) array_dtype(5)
+
+  !$omp target map(tofrom: array_dtype(5))
+      do i = 1, 20
+        array_dtype(5)%elements(i) = 20 + i
+      end do
+
+      array_dtype(5)%num_chars%number%float_elements(5) = 10
+      array_dtype(5)%value = 40
+  !$omp end target
+
+    print *, array_dtype(5)%elements
+    print *, array_dtype(5)%num_chars%number%float_elements(5)
+    print *, array_dtype(5)%value
+
+  !$omp target map(tofrom: array_dtype(4)%elements(3))
+    array_dtype(4)%elements(3) = 74
+  !$omp end target
+
+   print *, array_dtype(4)%elements(3)
+
+  !$omp target map(tofrom: array_dtype(5)%elements(3:5))
+    do i = 3, 5
+       array_dtype(5)%elements(i) = i + 1
+    end do
+  !$omp end target
+
+   do i = 3, 5
+      print *, array_dtype(5)%elements(i)
+   end do
+
+  !$omp target map(tofrom: array_dtype(3:5))
+    do i = 3, 5
+      array_dtype(i)%value = i + 2
+    end do
+  !$omp end target
+
+    do i = 3, 5
+        print *, array_dtype(i)%value
+    end do
+
+  !$omp target map(tofrom: array_dtype(4)%num_chars%number%float_elements(8))
+    array_dtype(4)%num_chars%number%float_elements(8) = 250
+  !$omp end target
+
+  print *, array_dtype(4)%num_chars%number%float_elements(8)
+
+  !$omp target map(tofrom: array_dtype(4)%num_chars%number%float_elements(5:10))
+    do i = 5, 10
+      array_dtype(4)%num_chars%number%float_elements(i) = i + 3
+    end do
+  !$omp end target
+
+  do i = 5, 10
+    print *, array_dtype(4)%num_chars%number%float_elements(i)
+  end do
+
+  !$omp target map(tofrom: array_dtype(4)%internal_dtypes(3)%float_elements(4))
+    array_dtype(4)%internal_dtypes(3)%float_elements(4) = 200
+  !$omp end target
+
+  print *, array_dtype(4)%internal_dtypes(3)%float_elements(4)
+
+end program main
+
+! CHECK: 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40
+! CHECK: 10.
+! CHECK: 40
+! CHECK: 74
+! CHECK: 4
+! CHECK: 5
+! CHECK: 6
+! CHECK: 5
+! CHECK: 6
+! CHECK: 7
+! CHECK: 250.
+! CHECK: 8.
+! CHECK: 9.
+! CHECK: 10.
+! CHECK: 11.
+! CHECK: 12.
+! CHECK: 13.
+! CHECK: 200
diff --git a/offload/test/offloading/fortran/dtype-member-map-syntax-2.f90 b/offload/test/offloading/fortran/dtype-member-map-syntax-2.f90
new file mode 100644
index 00000000000000..0975794009ed24
--- /dev/null
+++ b/offload/test/offloading/fortran/dtype-member-map-syntax-2.f90
@@ -0,0 +1,176 @@
+! This test checks a number of more complex derived type
+! member mapping syntaxes utilising an allocatable parent
+! derived type and mixed allocatable members.
+
+! REQUIRES: flang, amdgpu
+
+! RUN: %libomptarget-compile-fortran-run-and-check-generic
+program main
+    implicit none
+
+    integer :: i
+    integer :: N1, N2
+
+    type :: vertexes
+        integer :: test
+        integer :: testarray(10)
+        integer(4), allocatable :: vertexx(:)
+        integer(4), allocatable :: vertexy(:)
+    end type vertexes
+
+    type testing_tile_type
+        TYPE(vertexes) :: field
+    end type testing_tile_type
+
+    type :: dtype
+        real(4) :: i
+        type(vertexes), allocatable :: vertexes(:)
+        TYPE(testing_tile_type), DIMENSION(:), allocatable :: test_tile
+        integer(4) :: array_i(10)
+        real(4) :: j
+        integer, allocatable :: array_j(:)
+        integer(4) :: k
+    end type dtype
+
+    type(dtype) :: alloca_dtype
+    type(dtype), DIMENSION(:), allocatable :: alloca_dtype_arr
+
+    allocate(alloca_dtype%vertexes(4))
+    allocate(alloca_dtype%vertexes(1)%vertexx(10))
+    allocate(alloca_dtype%vertexes(1)%vertexy(10))
+    allocate(alloca_dtype%vertexes(2)%vertexx(10))
+    allocate(alloca_dtype%vertexes(2)%vertexy(10))
+    allocate(alloca_dtype%vertexes(3)%vertexx(10))
+    allocate(alloca_dtype%vertexes(3)%vertexy(10))
+    allocate(alloca_dtype%vertexes(4)%vertexx(10))
+    allocate(alloca_dtype%vertexes(4)%vertexy(10))
+    allocate(alloca_dtype%test_tile(4))
+    allocate(alloca_dtype%test_tile(1)%field%vertexx(10))
+    allocate(alloca_dtype%test_tile(1)%field%vertexy(10))
+    allocate(alloca_dtype%test_tile(2)%field%vertexx(10))
+    allocate(alloca_dtype%test_tile(2)%field%vertexy(10))
+    allocate(alloca_dtype%test_tile(3)%field%vertexx(10))
+    allocate(alloca_dtype%test_tile(3)%field%vertexy(10))
+    allocate(alloca_dtype%test_tile(4)%field%vertexx(10))
+    allocate(alloca_dtype%test_tile(4)%field%vertexy(10))
+
+    allocate(alloca_dtype_arr(3))
+
+    N1 = 1
+    N2 = 2
+
+!$omp target map(tofrom: alloca_dtype%vertexes(N1)%test)
+        alloca_dtype%vertexes(N1)%test = 3
+!$omp end target
+
+print *, alloca_dtype%vertexes(N1)%test
+
+!$omp target map(tofrom: alloca_dtype%vertexes(N1)%test, alloca_dtype%vertexes(N2)%test)
+        alloca_dtype%vertexes(N1)%test = 5
+        alloca_dtype%vertexes(N2)%test = 10
+!$omp end target
+
+print *, alloca_dtype%vertexes(N1)%test
+print *, alloca_dtype%vertexes(N2)%test
+
+!$omp target map(tofrom: alloca_dtype%test_tile(N1)%field%vertexx, &
+!$omp                    alloca_dtype%test_tile(N1)%field%vertexy)
+    do i = 1, 10
+        alloca_dtype%test_tile(N1)%field%vertexx(i) = i + 4
+        alloca_dtype%test_tile(N1)%field%vertexy(i) = i + 4
+    end do
+!$omp end target
+
+print *, alloca_dtype%test_tile(N1)%field%vertexx
+print *, alloca_dtype%test_tile(N1)%field%vertexy
+
+!$omp target map(tofrom:  alloca_dtype%test_tile(N1)%field%test, &
+!$omp                     alloca_dtype%test_tile(N2)%field%test, &
+!$omp                     alloca_dtype%test_tile(N1)%field%vertexy, &
+!$omp                     alloca_dtype%test_tile(N2)%field%vertexy)
+    alloca_dtype%test_tile(N2)%field%test = 9999
+    alloca_dtype%test_tile(N2)%field%vertexy(2) = 9998
+    alloca_dtype%test_tile(N1)%field%test = 9997
+    alloca_dtype%test_tile(N1)%field%vertexy(2) = 9996
+!$omp end target
+
+print *, alloca_dtype%test_tile(N1)%field%test
+print *, alloca_dtype%test_tile(N2)%field%test
+print *, alloca_dtype%test_tile(N1)%field%vertexy(2)
+print *, alloca_dtype%test_tile(N2)%field%vertexy(2)
+
+!$omp target map(tofrom:  alloca_dtype%test_tile(N2)%field%vertexy)
+   alloca_dtype%test_tile(N2)%field%vertexy(2) = 2000
+!$omp end target
+
+!$omp target map(tofrom: alloca_dtype%vertexes(N1)%vertexx, &
+!$omp                    alloca_dtype%vertexes(N1)%vertexy, &
+!$omp                    alloca_dtype%vertexes(N2)%vertexx, &
+!$omp                    alloca_dtype%vertexes(N2)%vertexy)
+    do i = 1, 10
+        alloca_dtype%vertexes(N1)%vertexx(i) = i * 2
+        alloca_dtype%vertexes(N1)%vertexy(i) = i * 2
+        alloca_dtype%vertexes(N2)%vertexx(i) = i * 2
+        alloca_dtype%vertexes(N2)%vertexy(i) = i * 2
+    end do
+!$omp end target
+
+print *, alloca_dtype%vertexes(N1)%vertexx
+print *, alloca_dtype%vertexes(N1)%vertexy
+print *, alloca_dtype%vertexes(N2)%vertexx
+print *, alloca_dtype%vertexes(N2)%vertexy
+
+!$omp target map(tofrom: alloca_dtype%vertexes(N1)%vertexx, &
+!$omp                    alloca_dtype%vertexes(N1)%vertexy, &
+!$omp                    alloca_dtype%vertexes(4)%vertexy, &
+!$omp                    alloca_dtype%vertexes(4)%vertexx, &
+!$omp                    alloca_dtype%vertexes(N2)%vertexx, &
+!$omp                    alloca_dtype%vertexes(N2)%vertexy)
+    do i = 1, 10
+        alloca_dtype%vertexes(N1)%vertexx(i) = i * 3
+        alloca_dtype%vertexes(N1)%vertexy(i) = i * 3
+        alloca_dtype%vertexes(4)%vertexx(i) = i * 3
+        alloca_dtype%vertexes(4)%vertexy(i) = i * 3
+        alloca_dtype%vertexes(N2)%vertexx(i) = i * 3
+        alloca_dtype%vertexes(N2)%vertexy(i) = i * 3
+    end do
+!$omp end target
+
+
+    print *, alloca_dtype%vertexes(1)%vertexx
+    print *, alloca_dtype%vertexes(1)%vertexy
+    print *, alloca_dtype%vertexes(4)%vertexx
+    print *, alloca_dtype%vertexes(4)%vertexy
+    print *, alloca_dtype%vertexes(2)%vertexx
+    print *, alloca_dtype%vertexes(2)%vertexy
+
+!$omp target map(tofrom: alloca_dtype_arr(N2)%array_i)
+    do i = 1, 10
+        alloca_dtype_arr(N2)%array_i(i) = i + 2
+    end do
+!$omp end target
+
+print *, alloca_dtype_arr(N2)%array_i
+
+end program main
+
+! CHECK: 3
+! CHECK: 5
+! CHECK: 10
+! CHECK: 5 6 7 8 9 10 11 12 13 14
+! CHECK: 5 6 7 8 9 10 11 12 13 14
+! CHECK: 9997
+! CHECK: 9999
+! CHECK: 9996
+! CHECK: 9998
+! CHECK: 2 4 6 8 10 12 14 16 18 20
+! CHECK: 2 4 6 8 10 12 14 16 18 20
+! CHECK: 2 4 6 8 10 12 14 16 18 20
+! CHECK: 2 4 6 8 10 12 14 16 18 20
+! CHECK: 3 6 9 12 15 18 21 24 27 30
+! CHECK: 3 6 9 12 15 18 21 24 27 30
+! CHECK: 3 6 9 12 15 18 21 24 27 30
+! CHECK: 3 6 9 12 15 18 21 24 27 30
+! CHECK: 3 6 9 12 15 18 21 24 27 30
+! CHECK: 3 6 9 12 15 18 21 24 27 30
+! CHECK: 3 4 5 6 7 8 9 10 11 12
diff --git a/offload/test/offloading/fortran/target-map-alloca-dtype-alloca-array-of-dtype.f90 b/offload/test/offloading/fortran/target-map-alloca-dtype-alloca-array-of-dtype.f90
new file mode 100644
index 00000000000000..d0ad74d3812dc0
--- /dev/null
+++ b/offload/test/offloading/fortran/target-map-alloca-dtype-alloca-array-of-dtype.f90
@@ -0,0 +1,36 @@
+! Offloading test checking interaction of explicit
+! member mapping of an allocatable array of derived
+! types contained within an allocatable derived type
+! REQUIRES: flang, amdgpu
+
+! RUN: %libomptarget-compile-fortran-run-and-check-generic
+program main
+    type :: nested_dtype
+        real(4) :: i
+        real(4) :: j
+        integer(4) :: array_i(10)
+        integer(4) :: k
+    end type nested_dtype
+
+    type :: dtype
+        real(4) :: i
+        integer(4) :: array_i(10)
+        real(4) :: j
+        type(nested_dtype), allocatable :: array_dtype(:)
+        integer(4) :: k
+    end type dtype
+
+    type(dtype), allocatable :: dtyped
+    allocate(dtyped)
+    allocate(dtyped%array_dtype(10))
+
+!$omp target map(tofrom: dtyped%array_dtype)
+    do i = 1, 10
+        dtyped%array_dtype(i)%k = i
+    end do
+!$omp end target
+
+    print *, dtyped%array_dtype%k
+end program main
+
+!CHECK: 1 2 3 4 5 6 7 8 9 10
diff --git a/offload/test/offloading/fortran/target-map-alloca-dtype-alloca-array.f90 b/offload/test/offloading/fortran/target-map-alloca-dtype-alloca-array.f90
new file mode 100644
index 00000000000000..d48b7a10ada4c8
--- /dev/null
+++ b/offload/test/offloading/fortran/target-map-alloca-dtype-alloca-array.f90
@@ -0,0 +1,30 @@
+! Offload test that checks an allocatable array within an
+! allocatable derived type can be mapped explicitly using
+! member mapping.
+! REQUIRES: flang, amdgpu
+
+! RUN: %libomptarget-compile-fortran-run-and-check-generic
+program main
+    type :: dtype
+        real(4) :: i
+        integer(4) :: array_i(10)
+        real(4) :: j
+        integer, allocatable :: array_j(:)
+        integer(4) :: k
+    end type dtype
+
+    type(dtype), allocatable :: alloca_dtype
+    allocate(alloca_dtype)
+    allocate(alloca_dtype%array_j(10))
+
+!$omp target map(tofrom: alloca_dtype%array_j)
+    do i = 1, 10
+        alloca_dtype%array_j(i) = i
+    end do
+!$omp end target
+
+print *, alloca_dtype%array_j
+
+end program main
+
+!CHECK: 1 2 3 4 5 6 7 8 9 10
diff --git a/offload/test/offloading/fortran/target-map-alloca-dtype-and-alloca-array-v2.f90 b/offload/test/offloading/fortran/target-map-alloca-dtype-and-alloca-array-v2.f90
new file mode 100644
index 00000000000000..e54b64f074310d
--- /dev/null
+++ b/offload/test/offloading/fortran/target-map-alloca-dtype-and-alloca-array-v2.f90
@@ -0,0 +1,35 @@
+! Offload test that checks an allocatable derived type can be
+! mapped alongside one of its own allocatable components
+! without disrupting either mapping, different from original
+! as the argument ordering is reversed (similar to C++ mapping
+! of a struct and a pointer, in concept at least).
+! REQUIRES: flang, amdgpu
+
+! RUN: %libomptarget-compile-fortran-run-and-check-generic
+program main
+    type :: dtype
+        real(4) :: i
+        integer, allocatable :: scalar
+        integer(4) :: array_i(10)
+        real(4) :: j
+        integer, allocatable :: array_j(:)
+        integer(4) :: k
+    end type dtype
+
+    type(dtype), allocatable :: alloca_dtype
+    allocate(alloca_dtype)
+    allocate(alloca_dtype%array_j(10))
+
+!$omp target map(tofrom: alloca_dtype%array_j, alloca_dtype)
+    do i = 1, 10
+        alloca_dtype%array_j(i) = i
+    end do
+    alloca_dtype%k = 50
+!$omp end target
+
+print *, alloca_dtype%array_j
+print *, alloca_dtype%k
+end program main
+
+!CHECK: 1 2 3 4 5 6 7 8 9 10
+!CHECK: 50
diff --git a/offload/test/offloading/fortran/target-map-alloca-dtype-and-alloca-array.f90 b/offload/test/offloading/fortran/target-map-alloca-dtype-and-alloca-array.f90
new file mode 100644
index 00000000000000..1a147177afdd80
--- /dev/null
+++ b/offload/test/offloading/fortran/target-map-alloca-dtype-and-alloca-array.f90
@@ -0,0 +1,34 @@
+! Offload test that checks an allocatable derived type can be
+! mapped alongside one of its own allocatable components
+! without disrupting either mapping (similar to C++ mapping
+! of a struct and a pointer, in concept at least).
+! REQUIRES: flang, amdgpu
+
+! RUN: %libomptarget-compile-fortran-run-and-check-generic
+program main
+    type :: dtype
+        real(4) :: i
+        integer, allocatable :: scalar
+        integer(4) :: array_i(10)
+        real(4) :: j
+        integer, allocatable :: array_j(:)
+        integer(4) :: k
+    end type dtype
+
+    type(dtype), allocatable :: alloca_dtype
+    allocate(alloca_dtype)
+    allocate(alloca_dtype%array_j(10))
+
+!$omp target map(tofrom: alloca_dtype, alloca_dtype%array_j)
+    do i = 1, 10
+        alloca_dtype%array_j(i) = i
+    end do
+    alloca_dtype%k = 50
+!$omp end target
+
+print *, alloca_dtype%array_j
+print *, alloca_dtype%k
+end program main
+
+!CHECK: 1 2 3 4 5 6 7 8 9 10
+!CHECK: 50
diff --git a/offload/test/offloading/fortran/target-map-alloca-dtype-array-and-scalar.f90 b/offload/test/offloading/fortran/target-map-alloca-dtype-array-and-scalar.f90
new file mode 100644
index 00000000000000..63dd06f7093a7d
--- /dev/null
+++ b/offload/test/offloading/fortran/target-map-alloca-dtype-array-and-scalar.f90
@@ -0,0 +1,40 @@
+! Offloading test checking interaction of explicit
+! member mapping of non-allocatable members of an
+! allocatable derived type.
+! REQUIRES: flang, amdgpu
+
+! RUN: %libomptarget-compile-fortran-run-and-check-generic
+program main
+    type :: nested_dtype
+        real(4) :: i
+        real(4) :: j
+        integer(4) :: array_i(10)
+        integer(4) :: k
+    end type nested_dtype
+
+    type :: dtype
+        real(4) :: i
+        integer, allocatable :: scalar 
+        integer(4) :: array_i(10)
+        type(nested_dtype) :: nested_dtype
+        real(4) :: j
+        integer, allocatable :: array_j(:)
+        integer(4) :: k
+    end type dtype
+
+    type(dtype), allocatable :: alloca_dtype
+    allocate(alloca_dtype)
+
+!$omp target map(tofrom: alloca_dtype%nested_dtype%array_i, alloca_dtype%k)
+    do i = 1, 10
+        alloca_dtype%nested_dtype%array_i(i) = i
+    end do
+    alloca_dtype%k = 50
+!$omp end target
+
+print *, alloca_dtype%k
+print *, alloca_dtype%nested_dtype%array_i
+end program main
+
+!CHECK: 50
+!CHECK: 1 2 3 4 5 6 7 8 9 10
diff --git a/offload/test/offloading/fortran/target-map-alloca-dtype-array-of-dtype.f90 b/offload/test/offloading/fortran/target-map-alloca-dtype-array-of-dtype.f90
new file mode 100644
index 00000000000000..327fa3575d263b
--- /dev/null
+++ b/offload/test/offloading/fortran/target-map-alloca-dtype-array-of-dtype.f90
@@ -0,0 +1,36 @@
+! Offloading test checking interaction of explicit
+! member mapping of an array of derived types
+! contained within an allocatable derived type
+! REQUIRES: flang, amdgpu
+
+! RUN: %libomptarget-compile-fortran-run-and-check-generic
+program main
+    type :: nested_dtype
+        real(4) :: i
+        real(4) :: j
+        integer(4) :: array_i(10)
+        integer(4) :: k
+    end type nested_dtype
+
+    type :: dtype
+        real(4) :: i
+        integer(4) :: array_i(10)
+        real(4) :: j
+        type(nested_dtype) :: array_dtype(10)
+        integer(4) :: k
+    end type dtype
+
+    type(dtype), allocatable :: dtyped
+    allocate(dtyped)
+
+!$omp target map(tofrom: dtyped%array_dtype)
+    do i = 1, 10
+        dtyped%array_dtype(i)%k = i
+    end do
+!$omp end target
+
+print *, dtyped%array_dtype%k
+
+end program main
+
+!CHECK: 1 2 3 4 5 6 7 8 9 10
diff --git a/offload/test/offloading/fortran/target-map-allocatable-dtype.f90 b/offload/test/offloading/fortran/target-map-allocatable-dtype.f90
new file mode 100644
index 00000000000000..27559a6c98de96
--- /dev/null
+++ b/offload/test/offloading/fortran/target-map-allocatable-dtype.f90
@@ -0,0 +1,32 @@
+! Offload test that checks an allocatable derived type can be
+! mapped and at the least non-allocatable components can be
+! accessed.
+! REQUIRES: flang, amdgpu
+
+! RUN: %libomptarget-compile-fortran-run-and-check-generic
+program main
+    type :: dtype
+        real(4) :: i
+        integer, allocatable :: scalar
+        integer(4) :: array_i(10)
+        real(4) :: j
+        integer, allocatable :: array_j(:)
+        integer(4) :: k
+    end type dtype
+
+    type(dtype), allocatable :: alloca_dtype
+    allocate(alloca_dtype)
+
+!$omp target map(tofrom: alloca_dtype)
+    do i = 1, 10
+        alloca_dtype%array_i(i) = i
+    end do
+    alloca_dtype%k = 50
+!$omp end target
+
+print *, alloca_dtype%k
+print *, alloca_dtype%array_i
+end program main
+
+!CHECK: 50
+!CHECK: 1 2 3 4 5 6 7 8 9 10
diff --git a/offload/test/offloading/fortran/target-map-double-nested-dtype-array-bounds.f90 b/offload/test/offloading/fortran/target-map-double-nested-dtype-array-bounds.f90
index 7f260ac4cdc1ed..df1d8c8b9f9af3 100644
--- a/offload/test/offloading/fortran/target-map-double-nested-dtype-array-bounds.f90
+++ b/offload/test/offloading/fortran/target-map-double-nested-dtype-array-bounds.f90
@@ -1,5 +1,5 @@
 ! Offloading test checking interaction of two
-! explicit arrau member maps with bounds from
+! explicit array member maps with bounds from
 ! two nested derived types
 ! REQUIRES: flang, amdgpu
 
diff --git a/offload/test/offloading/fortran/target-map-dtype-3d-alloca-array-with-bounds.f90 b/offload/test/offloading/fortran/target-map-dtype-3d-alloca-array-with-bounds.f90
new file mode 100644
index 00000000000000..65fa788a2296dc
--- /dev/null
+++ b/offload/test/offloading/fortran/target-map-dtype-3d-alloca-array-with-bounds.f90
@@ -0,0 +1,42 @@
+! Offload test that checks an allocatable array can be mapped with
+! a specified 3-D bounds when contained within a derived type and
+! mapped via member mapping.
+! REQUIRES: flang, amdgpu
+
+! RUN: %libomptarget-compile-fortran-run-and-check-generic
+program main
+    type :: top_layer
+    real(4) :: i
+    integer, allocatable :: scalar
+    integer(4) :: array_i(10)
+    real(4) :: j
+    integer, allocatable :: array_j(:,:,:)
+    integer(4) :: k
+    end type top_layer
+
+    type(top_layer) :: one_l
+    integer :: inArray(3,3,3)
+
+    allocate(one_l%array_j(3,3,3))
+
+    do i = 1, 3
+        do j = 1, 3
+          do k = 1, 3
+              inArray(i, j, k) = 42
+              one_l%array_j(i, j, k) = 0
+          end do
+         end do
+      end do
+
+!$omp target map(tofrom: one_l%array_j(1:3, 1:3, 2:2)) map(to: inArray(1:3, 1:3, 1:3))
+    do j = 1, 3
+        do k = 1, 3
+            one_l%array_j(k, j, 2) = inArray(k, j, 2)
+        end do
+      end do
+!$omp end target
+
+    print *, one_l%array_j
+end program main
+
+!CHECK: 0 0 0 0 0 0 0 0 0 42 42 42 42 42 42 42 42 42 0 0 0 0 0 0 0 0 0
diff --git a/offload/test/offloading/fortran/target-map-dtype-alloca-and-non-alloca-array.f90 b/offload/test/offloading/fortran/target-map-dtype-alloca-and-non-alloca-array.f90
new file mode 100644
index 00000000000000..71cfc4462bd280
--- /dev/null
+++ b/offload/test/offloading/fortran/target-map-dtype-alloca-and-non-alloca-array.f90
@@ -0,0 +1,36 @@
+! Offload test that checks an allocatable array can be mapped alongside
+! a non-allocatable array when both are contained within a derived type
+! can be mapped correctly via member mapping and then written to.
+! REQUIRES: flang, amdgpu
+
+! RUN: %libomptarget-compile-fortran-run-and-check-generic
+program main
+    type :: one_layer
+    real(4) :: i
+    integer, allocatable :: scalar
+    integer(4) :: array_i(10)
+    real(4) :: j
+    integer, allocatable :: array_j(:)
+    integer(4) :: k
+    end type one_layer
+
+    type(one_layer) :: one_l
+
+    allocate(one_l%array_j(10))
+
+    do i = 1, 10
+        one_l%array_i(i) = i
+    end do
+
+!$omp target map(tofrom: one_l%array_i, one_l%array_j)
+    do i = 1, 10
+        one_l%array_j(i) = one_l%array_i(i) + i
+    end do
+!$omp end target
+
+    print *, one_l%array_i
+    print *, one_l%array_j
+end program main
+
+!CHECK: 1 2 3 4 5 6 7 8 9 10
+!CHECK: 2 4 6 8 10 12 14 16 18 20
diff --git a/offload/test/offloading/fortran/target-map-dtype-alloca-array-and-non-alloca-dtype.f90 b/offload/test/offloading/fortran/target-map-dtype-alloca-array-and-non-alloca-dtype.f90
new file mode 100644
index 00000000000000..bc38ecebd75618
--- /dev/null
+++ b/offload/test/offloading/fortran/target-map-dtype-alloca-array-and-non-alloca-dtype.f90
@@ -0,0 +1,45 @@
+! Offload test that checks an allocatable array can be mapped alongside
+! a non-allocatable derived type when both are contained within a
+! derived type can be mapped correctly via member mapping and then
+! written to.
+! REQUIRES: flang, amdgpu
+
+! RUN: %libomptarget-compile-fortran-run-and-check-generic
+program main
+    type :: bottom_layer
+    real(4) :: i
+    integer(4) :: array_i(10)
+    integer(4) :: k
+    end type bottom_layer
+
+    type :: top_layer
+    real(4) :: i
+    integer, allocatable :: scalar
+    integer(4) :: array_i(10)
+    real(4) :: j
+    integer, allocatable :: array_j(:)
+    integer(4) :: k
+    type(bottom_layer) :: nest
+    end type top_layer
+
+    type(top_layer) :: one_l
+
+    allocate(one_l%array_j(10))
+    allocate(one_l%scalar)
+
+    do i = 1, 10
+        one_l%nest%array_i(i) = i
+    end do
+
+!$omp target map(tofrom: one_l%nest, one_l%array_j)
+    do i = 1, 10
+        one_l%array_j(i) = one_l%nest%array_i(i) + i
+    end do
+!$omp end target
+
+    print *, one_l%nest%array_i
+    print *, one_l%array_j
+end program main
+
+!CHECK: 1 2 3 4 5 6 7 8 9 10
+!CHECK: 2 4 6 8 10 12 14 16 18 20
diff --git a/offload/test/offloading/fortran/target-map-dtype-alloca-array-of-dtype.f90 b/offload/test/offloading/fortran/target-map-dtype-alloca-array-of-dtype.f90
new file mode 100644
index 00000000000000..a3fc2616bfa587
--- /dev/null
+++ b/offload/test/offloading/fortran/target-map-dtype-alloca-array-of-dtype.f90
@@ -0,0 +1,35 @@
+! Offload test that checks it is possible to member map
+! an allocatable array of derived types nested within a
+! non-allocatable derived type.
+! REQUIRES: flang, amdgpu
+
+! RUN: %libomptarget-compile-fortran-run-and-check-generic
+program main
+    type :: nested_dtype
+        real(4) :: i
+        real(4) :: j
+        integer(4) :: array_i(10)
+        integer(4) :: k
+    end type nested_dtype
+
+    type :: dtype
+        real(4) :: i
+        integer(4) :: array_i(10)
+        real(4) :: j
+        type(nested_dtype), allocatable :: array_dtype(:)
+        integer(4) :: k
+    end type dtype
+
+    type(dtype) :: dtyped
+    allocate(dtyped%array_dtype(10))
+
+!$omp target map(tofrom: dtyped%array_dtype)
+    do i = 1, 10
+        dtyped%array_dtype(i)%k = i
+    end do
+!$omp end target
+
+print *, dtyped%array_dtype%k
+end program main
+
+!CHECK: 1 2 3 4 5 6 7 8 9 10
diff --git a/offload/test/offloading/fortran/target-map-dtype-alloca-array-with-bounds.f90 b/offload/test/offloading/fortran/target-map-dtype-alloca-array-with-bounds.f90
new file mode 100644
index 00000000000000..574a2dd3a21b6b
--- /dev/null
+++ b/offload/test/offloading/fortran/target-map-dtype-alloca-array-with-bounds.f90
@@ -0,0 +1,30 @@
+! Offload test that checks an allocatable array can be mapped with
+! a specified 1-D bounds when contained within a derived type and
+! mapped via member mapping.
+! REQUIRES: flang, amdgpu
+
+! RUN: %libomptarget-compile-fortran-run-and-check-generic
+program main
+    type :: top_layer
+    real(4) :: i
+    integer, allocatable :: scalar
+    integer(4) :: array_i(10)
+    real(4) :: j
+    integer, allocatable :: array_j(:)
+    integer(4) :: k
+    end type top_layer
+
+    type(top_layer) :: one_l
+
+    allocate(one_l%array_j(10))
+
+!$omp target map(tofrom: one_l%array_j(2:6))
+    do index = 1, 10
+        one_l%array_j(index) = index
+    end do
+!$omp end target
+
+    print *, one_l%array_j(2:6)
+end program main
+
+!CHECK: 2 3 4 5 6
diff --git a/offload/test/offloading/fortran/target-map-dtype-allocatable-array.f90 b/offload/test/offloading/fortran/target-map-dtype-allocatable-array.f90
new file mode 100644
index 00000000000000..dbd839637f280d
--- /dev/null
+++ b/offload/test/offloading/fortran/target-map-dtype-allocatable-array.f90
@@ -0,0 +1,28 @@
+! Offload test that checks an allocatable array contained within a derived type
+! can be mapped correctly via member mapping and then written to.
+! REQUIRES: flang, amdgpu
+
+! RUN: %libomptarget-compile-fortran-run-and-check-generic
+program main
+    type :: one_layer
+    real(4) :: i
+    integer, allocatable :: scalar
+    integer(4) :: array_i(10)
+    real(4) :: j
+    integer, allocatable :: array_j(:)
+    integer(4) :: k
+    end type one_layer
+
+    type(one_layer) :: one_l
+    allocate(one_l%array_j(10))
+
+    !$omp target map(tofrom: one_l%array_j)
+        do i = 1, 10
+            one_l%array_j(i) = i
+        end do
+    !$omp end target
+
+    print *, one_l%array_j
+end program main
+
+!CHECK: 1 2 3 4 5 6 7 8 9 10
diff --git a/offload/test/offloading/fortran/target-map-dtype-allocatable-scalar-and-array.f90 b/offload/test/offloading/fortran/target-map-dtype-allocatable-scalar-and-array.f90
new file mode 100644
index 00000000000000..e173c40eb322e4
--- /dev/null
+++ b/offload/test/offloading/fortran/target-map-dtype-allocatable-scalar-and-array.f90
@@ -0,0 +1,34 @@
+! Offload test that checks an allocatable array alongside an allocatable
+! sclar contained within a derived type can be mapped correctly via
+! member mapping and then written to.
+! REQUIRES: flang, amdgpu
+
+! RUN: %libomptarget-compile-fortran-run-and-check-generic
+program main
+    type :: one_layer
+    real(4) :: i
+    integer, allocatable :: scalar
+    integer(4) :: array_i(10)
+    real(4) :: j
+    integer, allocatable :: array_j(:)
+    integer(4) :: k
+    end type one_layer
+
+    type(one_layer) :: one_l
+
+    allocate(one_l%array_j(10))
+    allocate(one_l%scalar)
+
+    !$omp target map(tofrom: one_l%array_j, one_l%j)
+        do i = 1, 10
+            one_l%array_j(i) = i
+        end do
+        one_l%j = 50
+    !$omp end target
+
+    print *, one_l%j
+    print *, one_l%array_j
+end program main
+
+!CHECK: 50
+!CHECK: 1 2 3 4 5 6 7 8 9 10
diff --git a/offload/test/offloading/fortran/target-map-multi-alloca-dtypes-with-multi-alloca-members.f90 b/offload/test/offloading/fortran/target-map-multi-alloca-dtypes-with-multi-alloca-members.f90
new file mode 100644
index 00000000000000..7880069881acc1
--- /dev/null
+++ b/offload/test/offloading/fortran/target-map-multi-alloca-dtypes-with-multi-alloca-members.f90
@@ -0,0 +1,90 @@
+! Offloading test checking interaction of an explicit member map allocatable
+! components of two large nested derived types. NOTE: Unfortunately this test
+! loses a bit of its bite as we do not currently support linking against an
+! offload compiled fortran runtime library which means allocatable scalar
+! assignment isn't going to work in target regions.
+! REQUIRES: flang, amdgpu
+
+! RUN: %libomptarget-compile-fortran-run-and-check-generic
+program main
+    type :: bottom_layer1
+    real(4), allocatable :: i4
+    real(4), allocatable :: j4
+    integer, pointer :: array_ptr(:)
+    real(4), allocatable :: k4
+    end type bottom_layer1
+
+    type :: bottom_layer2
+      integer(4), allocatable :: i3
+      integer(4), allocatable :: j3
+      integer, allocatable :: scalar
+      real, allocatable :: array_j(:)
+      integer(4), allocatable :: k3
+    end type bottom_layer2
+
+    type :: middle_layer
+     real(4) :: array_i2(10)
+     real(4), allocatable :: i2
+     integer, pointer :: scalar_ptr
+     real(4) :: array_j2(10)
+     type(bottom_layer1), allocatable :: nest
+     type(bottom_layer2), allocatable :: nest2
+    end type middle_layer
+
+    type :: top_layer
+    real(4) :: i
+    integer(4), allocatable :: array_i(:)
+    real(4) :: j
+    integer(4) :: k
+    type(middle_layer), allocatable :: nested
+    end type top_layer
+
+    type(top_layer), allocatable :: top_dtype
+    type(top_layer), allocatable :: top_dtype2
+    integer, target :: array_target(10)
+    integer, target :: array_target2(10)
+
+    allocate(top_dtype)
+    allocate(top_dtype2)
+    allocate(top_dtype%nested)
+    allocate(top_dtype2%nested)
+    allocate(top_dtype%nested%nest)
+    allocate(top_dtype2%nested%nest)
+    allocate(top_dtype%nested%nest2)
+    allocate(top_dtype2%nested%nest2)
+    allocate(top_dtype%array_i(10))
+    allocate(top_dtype2%array_i(10))
+
+    top_dtype%nested%nest%array_ptr => array_target
+    allocate(top_dtype%nested%nest2%array_j(10))
+
+    top_dtype2%nested%nest%array_ptr => array_target2
+    allocate(top_dtype2%nested%nest2%array_j(10))
+
+!$omp target map(tofrom: top_dtype%array_i, top_dtype%nested%nest2%array_j, top_dtype%nested%nest%array_ptr) &
+!$omp map(tofrom: top_dtype2%array_i, top_dtype2%nested%nest2%array_j, top_dtype2%nested%nest%array_ptr)
+    do i = 1, 10
+      top_dtype%nested%nest%array_ptr(i) = i
+      top_dtype%nested%nest2%array_j(i) = i
+      top_dtype%array_i(i) = i
+      top_dtype2%nested%nest%array_ptr(i) = i
+      top_dtype2%nested%nest2%array_j(i) = i
+      top_dtype2%array_i(i) = i
+    end do
+!$omp end target
+
+  print *, top_dtype%nested%nest%array_ptr
+  print *, top_dtype%nested%nest2%array_j
+  print *, top_dtype%array_i
+
+  print *, top_dtype2%nested%nest%array_ptr
+  print *, top_dtype2%nested%nest2%array_j
+  print *, top_dtype2%array_i
+end program main
+
+!CHECK: 1 2 3 4 5 6 7 8 9 10
+!CHECK: 1. 2. 3. 4. 5. 6. 7. 8. 9. 10.
+!CHECK: 1 2 3 4 5 6 7 8 9 10
+!CHECK: 1 2 3 4 5 6 7 8 9 10
+!CHECK: 1. 2. 3. 4. 5. 6. 7. 8. 9. 10.
+!CHECK:  1 2 3 4 5 6 7 8 9 10
diff --git a/offload/test/offloading/fortran/target-map-multi-alloca-dtypes-with-multi-mixed-members.f90 b/offload/test/offloading/fortran/target-map-multi-alloca-dtypes-with-multi-mixed-members.f90
new file mode 100644
index 00000000000000..c0330b9c9e2a4e
--- /dev/null
+++ b/offload/test/offloading/fortran/target-map-multi-alloca-dtypes-with-multi-mixed-members.f90
@@ -0,0 +1,82 @@
+! Offloading test checking interaction of an explicit member map of mixed
+! allocatable and non-allocatable components of a nested derived types. 
+! NOTE: Unfortunately this test loses a bit of its bite as we do not 
+! currently support linking against an offload compiled fortran runtime 
+! library which means allocatable scalar assignment isn't going to work in 
+! target regions.
+! REQUIRES: flang, amdgpu
+
+! RUN: %libomptarget-compile-fortran-run-and-check-generic
+program main
+    type :: bottom_layer1
+    real(4) :: i4
+    real(4), allocatable :: j4
+    real(4) :: k4
+    end type bottom_layer1
+
+    type :: bottom_layer2
+      integer(4) :: i3
+      integer(4) :: j3
+      integer(4), allocatable :: k3
+    end type bottom_layer2
+
+    type :: middle_layer
+     real(4) :: array_i2(10)
+     real(4) :: i2
+     real(4), allocatable :: array_j2(:)
+     type(bottom_layer1) :: nest
+     type(bottom_layer2), allocatable :: nest2
+    end type middle_layer
+
+    type :: top_layer
+    real(4) :: i
+    integer(4) :: array_i(10)
+    real(4) :: j
+    integer, allocatable :: array_j(:)
+    integer(4) :: k
+    type(middle_layer) :: nested
+    end type top_layer
+
+    type(top_layer), allocatable :: top_dtype
+
+    allocate(top_dtype)
+    allocate(top_dtype%array_j(10))
+    allocate(top_dtype%nested%nest2)
+    allocate(top_dtype%nested%array_j2(10))
+
+!$omp target map(tofrom: top_dtype%nested%nest%i4, top_dtype%nested%array_j2) &
+!$omp map(tofrom: top_dtype%nested%nest%k4, top_dtype%array_i, top_dtype%nested%nest2%i3) &
+!$omp map(tofrom: top_dtype%nested%i2, top_dtype%nested%nest2%j3, top_dtype%array_j)
+    top_dtype%nested%nest%i4 = 10
+    top_dtype%nested%nest%k4 = 10
+    top_dtype%nested%nest2%i3 = 20
+    top_dtype%nested%nest2%j3 = 40
+
+    top_dtype%nested%i2 = 200
+
+    do i = 1, 10
+        top_dtype%array_j(i) = i
+        top_dtype%array_i(i) = i
+        top_dtype%nested%array_j2(i) = i
+    end do
+!$omp end target
+
+  print *, top_dtype%nested%nest%i4
+  print *, top_dtype%nested%nest%k4
+  print *, top_dtype%nested%nest2%i3
+  print *, top_dtype%nested%nest2%j3
+
+  print *, top_dtype%nested%i2
+  print *, top_dtype%array_i
+  print *, top_dtype%array_j
+  print *, top_dtype%nested%array_j2
+end program main
+
+!CHECK: 10.
+!CHECK: 10.
+!CHECK: 20
+!CHECK: 40
+!CHECK: 200.
+!CHECK: 1 2 3 4 5 6 7 8 9 10
+!CHECK: 1 2 3 4 5 6 7 8 9 10
+!CHECK: 1. 2. 3. 4. 5. 6. 7. 8. 9. 10.
diff --git a/offload/test/offloading/fortran/target-map-nested-alloca-dtype-3d-alloca-array-bounds.f90 b/offload/test/offloading/fortran/target-map-nested-alloca-dtype-3d-alloca-array-bounds.f90
new file mode 100644
index 00000000000000..caa06299b4314b
--- /dev/null
+++ b/offload/test/offloading/fortran/target-map-nested-alloca-dtype-3d-alloca-array-bounds.f90
@@ -0,0 +1,51 @@
+! Offloading test checking interaction of an explicit member map of
+! an allocatable 3d array within a nested allocatable derived type
+! with specified bounds
+! REQUIRES: flang, amdgpu
+
+! RUN: %libomptarget-compile-fortran-run-and-check-generic
+program main
+    type :: bottom_layer
+    real(4) :: i
+    integer(4) :: array_i(10)
+    integer, allocatable :: array_k(:,:,:)
+    integer(4) :: k
+    end type bottom_layer
+
+    type :: top_layer
+    real(4) :: i
+    integer, allocatable :: scalar
+    integer(4) :: array_i(10)
+    real(4) :: j
+    integer, allocatable :: array_j(:)
+    integer(4) :: k
+    type(bottom_layer), allocatable :: nest
+    end type top_layer
+
+    type(top_layer), allocatable :: one_l
+    integer :: inArray(3,3,3)
+    allocate(one_l)
+    allocate(one_l%nest)
+    allocate(one_l%nest%array_k(3,3,3))
+
+    do i = 1, 3
+        do j = 1, 3
+          do k = 1, 3
+              inArray(i, j, k) = 42
+              one_l%nest%array_k(i, j, k) = 0
+          end do
+         end do
+      end do
+
+!$omp target map(tofrom: one_l%nest%array_k(1:3, 1:3, 2:2)) map(to: inArray(1:3, 1:3, 1:3))
+    do j = 1, 3
+        do k = 1, 3
+            one_l%nest%array_k(k, j, 2) = inArray(k, j, 2)
+        end do
+      end do
+!$omp end target
+
+    print *, one_l%nest%array_k
+end program main
+
+!CHECK: 0 0 0 0 0 0 0 0 0 42 42 42 42 42 42 42 42 42 0 0 0 0 0 0 0 0 0
diff --git a/offload/test/offloading/fortran/target-map-nested-alloca-dtype-alloca-array-bounds.f90 b/offload/test/offloading/fortran/target-map-nested-alloca-dtype-alloca-array-bounds.f90
new file mode 100644
index 00000000000000..f106993e72a1b0
--- /dev/null
+++ b/offload/test/offloading/fortran/target-map-nested-alloca-dtype-alloca-array-bounds.f90
@@ -0,0 +1,43 @@
+! Offloading test checking interaction of an explicit member map of
+! an allocatable array within a nested allocatable derived type with
+! specified bounds
+! REQUIRES: flang, amdgpu
+
+! RUN: %libomptarget-compile-fortran-run-and-check-generic
+program main
+    type :: bottom_layer
+    real(4) :: i
+    integer(4) :: array_i(10)
+    integer, allocatable :: array_k(:)
+    integer(4) :: k
+    end type bottom_layer
+
+    type :: top_layer
+    real(4) :: i
+    integer, allocatable :: scalar
+    integer(4) :: array_i(10)
+    real(4) :: j
+    integer, allocatable :: array_j(:)
+    integer(4) :: k
+    type(bottom_layer), allocatable :: nest
+    end type top_layer
+
+    type(top_layer), allocatable :: one_l
+    allocate(one_l)
+    allocate(one_l%nest)
+    allocate(one_l%nest%array_k(10))
+
+    do index = 1, 10
+        one_l%nest%array_k(index) = 0
+    end do
+
+!$omp target map(tofrom: one_l%nest%array_k(2:6))
+    do index = 2, 6
+        one_l%nest%array_k(index) = index
+    end do
+!$omp end target
+
+    print *, one_l%nest%array_k
+end program main
+
+!CHECK: 0 2 3 4 5 6 0 0 0 0
diff --git a/offload/test/offloading/fortran/target-map-nested-dtype-3d-alloca-array-with-bounds.f90 b/offload/test/offloading/fortran/target-map-nested-dtype-3d-alloca-array-with-bounds.f90
new file mode 100644
index 00000000000000..496a0cad0bc7f7
--- /dev/null
+++ b/offload/test/offloading/fortran/target-map-nested-dtype-3d-alloca-array-with-bounds.f90
@@ -0,0 +1,50 @@
+! Offload test that checks an allocatable array can be mapped with
+! a specified 3-D bounds when contained within a nested derived type
+! and mapped via member mapping.
+! REQUIRES: flang, amdgpu
+
+! RUN: %libomptarget-compile-fortran-run-and-check-generic
+program main
+    type :: bottom_layer
+    real(4) :: i
+    integer(4) :: array_i(10)
+    integer, allocatable :: array_k(:,:,:)
+    integer(4) :: k
+    end type bottom_layer
+
+    type :: top_layer
+    real(4) :: i
+    integer, allocatable :: scalar
+    integer(4) :: array_i(10)
+    real(4) :: j
+    integer, allocatable :: array_j(:)
+    integer(4) :: k
+    type(bottom_layer) :: nest
+    end type top_layer
+
+    type(top_layer) :: one_l
+    integer :: inArray(3,3,3)
+
+    allocate(one_l%nest%array_k(3,3,3))
+
+    do i = 1, 3
+        do j = 1, 3
+          do k = 1, 3
+              inArray(i, j, k) = 42
+              one_l%nest%array_k(i, j, k) = 0
+          end do
+         end do
+      end do
+
+!$omp target map(tofrom: one_l%nest%array_k(1:3, 1:3, 2:2)) map(to: inArray(1:3, 1:3, 1:3))
+    do j = 1, 3
+        do k = 1, 3
+            one_l%nest%array_k(k, j, 2) = inArray(k, j, 2)
+        end do
+      end do
+!$omp end target
+
+    print *, one_l%nest%array_k
+end program main
+
+!CHECK: 0 0 0 0 0 0 0 0 0 42 42 42 42 42 42 42 42 42 0 0 0 0 0 0 0 0 0
diff --git a/offload/test/offloading/fortran/target-map-nested-dtype-alloca-and-non-alloca-array.f90 b/offload/test/offloading/fortran/target-map-nested-dtype-alloca-and-non-alloca-array.f90
new file mode 100644
index 00000000000000..01a9ce06782c33
--- /dev/null
+++ b/offload/test/offloading/fortran/target-map-nested-dtype-alloca-and-non-alloca-array.f90
@@ -0,0 +1,47 @@
+! Offload test that checks an allocatable array can be mapped via
+! member mapping alongside a non-allocatable array when both are
+! contained within a nested derived type.
+! REQUIRES: flang, amdgpu
+
+! RUN: %libomptarget-compile-fortran-run-and-check-generic
+program main
+    type :: bottom_layer
+    real(4) :: i
+    integer, allocatable :: scalar_i
+    integer(4) :: array_i(10)
+    integer, allocatable :: array_k(:)
+    integer(4) :: k
+    end type bottom_layer
+
+    type :: one_layer
+    real(4) :: i
+    integer, allocatable :: scalar
+    integer(4) :: array_i(10)
+    real(4) :: j
+    integer, allocatable :: array_j(:)
+    integer(4) :: k
+    type(bottom_layer) :: nest
+    end type one_layer
+
+    type(one_layer) :: one_l
+
+    allocate(one_l%nest%array_k(10))
+    allocate(one_l%nest%scalar_i)
+
+    do i = 1, 10
+        one_l%nest%array_i(i) = i
+    end do
+
+    !$omp target map(tofrom: one_l%nest%array_i, one_l%nest%array_k)
+    do i = 1, 10
+        one_l%nest%array_k(i) = one_l%nest%array_i(i) + i
+    end do
+    !$omp end target
+
+    print *, one_l%nest%array_k
+    print *, one_l%nest%array_i
+end program main
+
+!CHECK: 2 4 6 8 10 12 14 16 18 20
+!CHECK: 1 2 3 4 5 6 7 8 9 10
+
diff --git a/offload/test/offloading/fortran/target-map-nested-dtype-alloca-array-and-non-alloca-dtype.f90 b/offload/test/offloading/fortran/target-map-nested-dtype-alloca-array-and-non-alloca-dtype.f90
new file mode 100644
index 00000000000000..d00a31e8ff6541
--- /dev/null
+++ b/offload/test/offloading/fortran/target-map-nested-dtype-alloca-array-and-non-alloca-dtype.f90
@@ -0,0 +1,51 @@
+! Offload test that checks an allocatable array can be mapped alongside
+! a non-allocatable derived type when both are contained within a
+! nested derived type.
+! REQUIRES: flang, amdgpu
+
+! RUN: %libomptarget-compile-fortran-run-and-check-generic
+program main
+    type :: bottom_layer
+    real(4) :: i
+    integer(4) :: array_i(10)
+    integer(4) :: k
+    end type bottom_layer
+
+    type :: middle_layer
+    real(4) :: i
+    integer(4) :: array_i(10)
+    type(bottom_layer) :: nest2
+    integer, allocatable :: array_k(:)
+    integer(4) :: k
+    end type middle_layer
+
+    type :: top_layer
+    real(4) :: i
+    integer, allocatable :: scalar
+    integer(4) :: array_i(10)
+    real(4) :: j
+    integer, allocatable :: array_j(:)
+    integer(4) :: k
+    type(middle_layer) :: nest
+    end type top_layer
+
+    type(top_layer) :: one_l
+
+    allocate(one_l%nest%array_k(10))
+
+    do i = 1, 10
+        one_l%nest%nest2%array_i(i) = i
+    end do
+
+    !$omp target map(tofrom: one_l%nest%nest2, one_l%nest%array_k)
+        do i = 1, 10
+            one_l%nest%array_k(i) = one_l%nest%nest2%array_i(i) + i
+        end do
+    !$omp end target
+
+    print *, one_l%nest%nest2%array_i
+    print *, one_l%nest%array_k
+end program main
+
+!CHECK: 1 2 3 4 5 6 7 8 9 10
+!CHECK: 2 4 6 8 10 12 14 16 18 20
diff --git a/offload/test/offloading/fortran/target-map-nested-dtype-alloca-array-with-bounds.f90 b/offload/test/offloading/fortran/target-map-nested-dtype-alloca-array-with-bounds.f90
new file mode 100644
index 00000000000000..90873b94bb90f8
--- /dev/null
+++ b/offload/test/offloading/fortran/target-map-nested-dtype-alloca-array-with-bounds.f90
@@ -0,0 +1,43 @@
+! Offload test that checks an allocatable array can be mapped with
+! a specified 1-D bounds when contained within a nested derived
+! type and mapped via member mapping.
+! REQUIRES: flang, amdgpu
+
+! RUN: %libomptarget-compile-fortran-run-and-check-generic
+program main
+    type :: bottom_layer
+    real(4) :: i
+    integer(4) :: array_i(10)
+    integer, allocatable :: array_k(:)
+    integer(4) :: k
+    end type bottom_layer
+
+    type :: top_layer
+    real(4) :: i
+    integer, allocatable :: scalar
+    integer(4) :: array_i(10)
+    real(4) :: j
+    integer, allocatable :: array_j(:)
+    integer(4) :: k
+    type(bottom_layer) :: nest
+    end type top_layer
+
+    type(top_layer) :: one_l
+
+    allocate(one_l%nest%array_k(10))
+
+    do index = 1, 10
+        one_l%nest%array_k(index) = 0
+    end do
+
+!$omp target map(tofrom: one_l%nest%array_k(2:6))
+    do index = 2, 6
+        one_l%nest%array_k(index) = index
+    end do
+!$omp end target
+
+print *, one_l%nest%array_k
+
+end program main
+
+!CHECK: 0 2 3 4 5 6 0 0 0 0
diff --git a/offload/test/offloading/fortran/target-map-nested-dtype-alloca-array.f90 b/offload/test/offloading/fortran/target-map-nested-dtype-alloca-array.f90
new file mode 100644
index 00000000000000..fc9f40654a7e72
--- /dev/null
+++ b/offload/test/offloading/fortran/target-map-nested-dtype-alloca-array.f90
@@ -0,0 +1,38 @@
+! Offload test that checks an allocatable array contained within a nested
+! derived type can be mapped correctly via member mapping and then 
+! written to.
+! REQUIRES: flang, amdgpu
+
+! RUN: %libomptarget-compile-fortran-run-and-check-generic
+program main
+    type :: bottom_layer
+    real(4) :: i
+    integer(4) :: array_i(10)
+    integer, allocatable :: array_k(:)
+    integer(4) :: k
+    end type bottom_layer
+
+    type :: one_layer
+    real(4) :: i
+    integer, allocatable :: scalar
+    integer(4) :: array_i(10)
+    real(4) :: j
+    integer, allocatable :: array_j(:)
+    integer(4) :: k
+    type(bottom_layer) :: nest
+    end type one_layer
+
+    type(one_layer) :: one_l
+
+    allocate(one_l%nest%array_k(10))
+
+!$omp target map(tofrom: one_l%nest%array_k)
+    do i = 1, 10
+        one_l%nest%array_k(i) = i
+    end do
+!$omp end target
+
+    print *, one_l%nest%array_k
+end program main
+
+!CHECK: 1 2 3 4 5 6 7 8 9 10
diff --git a/offload/test/offloading/fortran/target-map-pointer-to-dtype-allocatable-member.f90 b/offload/test/offloading/fortran/target-map-pointer-to-dtype-allocatable-member.f90
new file mode 100644
index 00000000000000..26ddb349707ccb
--- /dev/null
+++ b/offload/test/offloading/fortran/target-map-pointer-to-dtype-allocatable-member.f90
@@ -0,0 +1,46 @@
+! Offloading test checking interaction of implicit 
+! captured of a pointer targetting an allocatable
+! member of a derived type, alongside the explicit
+! map of the derived type and allocatable data
+! via target enter and exit directives
+! REQUIRES: flang, amdgpu
+
+! RUN: %libomptarget-compile-fortran-run-and-check-generic
+module dtype
+    type :: my_dtype
+            integer :: s, e
+            integer,dimension(:),allocatable :: values
+    end type
+end module
+
+program offload_types
+    use dtype
+
+    type(my_dtype),target :: my_instance
+    integer,dimension(:),pointer :: values_ptr
+    integer :: i
+
+    allocate(my_instance%values(20))
+    my_instance%s=1
+    my_instance%e=20
+
+    values_ptr => my_instance%values
+
+    !$omp target enter data map(to:my_instance, my_instance%values)
+
+    !$omp target
+      do i = 1,20
+             values_ptr(i) = i
+      end do
+    !$omp end target
+
+    !$omp target exit data map(from:my_instance%values)
+
+    write(*,*) my_instance%values
+
+    !$omp target exit data map(release:my_instance)
+
+    deallocate(my_instance%values)
+end program
+
+!CHECK: 1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20



More information about the llvm-commits mailing list