Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
Original file line number Diff line number Diff line change
Expand Up @@ -4089,11 +4089,30 @@ static llvm::omp::OpenMPOffloadMappingFlags mapParentWithMembers(
assert(!ompBuilder.Config.isTargetDevice() &&
"function only supported for host device codegen");

// Map the first segment of our structure
combinedInfo.Types.emplace_back(
// Map the first segment of the parent. If a user-defined mapper is attached,
// include the parent's to/from-style bits (and common modifiers) in this
// base entry so the mapper receives correct copy semantics via its 'type'
// parameter. Also keep TARGET_PARAM when required for kernel arguments.
llvm::omp::OpenMPOffloadMappingFlags baseFlag =
isTargetParams
? llvm::omp::OpenMPOffloadMappingFlags::OMP_MAP_TARGET_PARAM
: llvm::omp::OpenMPOffloadMappingFlags::OMP_MAP_NONE);
: llvm::omp::OpenMPOffloadMappingFlags::OMP_MAP_NONE;

// Detect if this mapping uses a user-defined mapper.
bool hasUserMapper = mapData.Mappers[mapDataIndex] != nullptr;
if (hasUserMapper) {
using mapFlags = llvm::omp::OpenMPOffloadMappingFlags;
// Preserve relevant map-type bits from the parent clause. These include
// the copy direction (TO/FROM), as well as commonly used modifiers that
// should be visible to the mapper for correct behaviour.
mapFlags parentFlags = mapData.Types[mapDataIndex];
mapFlags preserve = mapFlags::OMP_MAP_TO | mapFlags::OMP_MAP_FROM |
mapFlags::OMP_MAP_ALWAYS | mapFlags::OMP_MAP_CLOSE |
mapFlags::OMP_MAP_PRESENT | mapFlags::OMP_MAP_OMPX_HOLD;
baseFlag |= (parentFlags & preserve);
}

combinedInfo.Types.emplace_back(baseFlag);
combinedInfo.DevicePointers.emplace_back(
mapData.DevicePointers[mapDataIndex]);
combinedInfo.Mappers.emplace_back(mapData.Mappers[mapDataIndex]);
Expand Down
Original file line number Diff line number Diff line change
@@ -0,0 +1,48 @@
! This test validates that declare mapper for a derived type with an
! allocatable component preserves TO/FROM semantics for the component,
! ensuring the payload is copied back to the host on target exit.

! REQUIRES: flang, amdgpu

! RUN: %libomptarget-compile-fortran-run-and-check-generic

program target_declare_mapper_allocatable
implicit none

type :: real_t
real, allocatable :: real_arr(:)
end type real_t

! Map the allocatable array payload via a named mapper.
!$omp declare mapper (xyz : real_t :: t) map(tofrom: t%real_arr)

type(real_t) :: r
integer :: i
logical :: ok

allocate(r%real_arr(10))
r%real_arr = 1.0

!$omp target map(mapper(xyz), tofrom: r)
do i = 1, size(r%real_arr)
r%real_arr(i) = 3.0
end do
!$omp end target

ok = .true.
do i = 1, size(r%real_arr)
if (r%real_arr(i) /= 3.0) ok = .false.
end do
if (ok) then
print *, "Test passed!"
else
print *, "Test failed!"
do i = 1, size(r%real_arr)
print *, r%real_arr(i)
end do
end if

deallocate(r%real_arr)
end program target_declare_mapper_allocatable

! CHECK: Test passed!