Skip to content

Commit 8fe4c60

Browse files
authored
[OpenMP][MLIR] Preserve to/from flags in mapper base entry for mappers (llvm#159799) (llvm#4159)
2 parents d89b973 + f6fc6a2 commit 8fe4c60

File tree

2 files changed

+71
-4
lines changed

2 files changed

+71
-4
lines changed

mlir/lib/Target/LLVMIR/Dialect/OpenMP/OpenMPToLLVMIRTranslation.cpp

Lines changed: 23 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -4298,14 +4298,33 @@ mapParentWithMembers(LLVM::ModuleTranslation &moduleTranslation,
42984298
uint64_t mapDataIndex, TargetDirective targetDirective) {
42994299
assert(!ompBuilder.Config.isTargetDevice() &&
43004300
"function only supported for host device codegen");
4301-
4302-
// Map the first segment of our structure
43034301
const size_t parentIndex = combinedInfo.Types.size();
4304-
combinedInfo.Types.emplace_back(
4302+
4303+
// Map the first segment of the parent. If a user-defined mapper is attached,
4304+
// include the parent's to/from-style bits (and common modifiers) in this
4305+
// base entry so the mapper receives correct copy semantics via its 'type'
4306+
// parameter. Also keep TARGET_PARAM when required for kernel arguments.
4307+
llvm::omp::OpenMPOffloadMappingFlags baseFlag =
43054308
(targetDirective == TargetDirective::Target &&
43064309
!mapData.IsDeclareTarget[mapDataIndex])
43074310
? llvm::omp::OpenMPOffloadMappingFlags::OMP_MAP_TARGET_PARAM
4308-
: llvm::omp::OpenMPOffloadMappingFlags::OMP_MAP_NONE);
4311+
: llvm::omp::OpenMPOffloadMappingFlags::OMP_MAP_NONE;
4312+
4313+
// Detect if this mapping uses a user-defined mapper.
4314+
bool hasUserMapper = mapData.Mappers[mapDataIndex] != nullptr;
4315+
if (hasUserMapper) {
4316+
using mapFlags = llvm::omp::OpenMPOffloadMappingFlags;
4317+
// Preserve relevant map-type bits from the parent clause. These include
4318+
// the copy direction (TO/FROM), as well as commonly used modifiers that
4319+
// should be visible to the mapper for correct behaviour.
4320+
mapFlags parentFlags = mapData.Types[mapDataIndex];
4321+
mapFlags preserve = mapFlags::OMP_MAP_TO | mapFlags::OMP_MAP_FROM |
4322+
mapFlags::OMP_MAP_ALWAYS | mapFlags::OMP_MAP_CLOSE |
4323+
mapFlags::OMP_MAP_PRESENT | mapFlags::OMP_MAP_OMPX_HOLD;
4324+
baseFlag |= (parentFlags & preserve);
4325+
}
4326+
4327+
combinedInfo.Types.emplace_back(baseFlag);
43094328
combinedInfo.DevicePointers.emplace_back(
43104329
mapData.DevicePointers[mapDataIndex]);
43114330
combinedInfo.Mappers.emplace_back(mapData.Mappers[mapDataIndex]);
Lines changed: 48 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,48 @@
1+
! This test validates that declare mapper for a derived type with an
2+
! allocatable component preserves TO/FROM semantics for the component,
3+
! ensuring the payload is copied back to the host on target exit.
4+
5+
! REQUIRES: flang, amdgpu
6+
7+
! RUN: %libomptarget-compile-fortran-run-and-check-generic
8+
9+
program target_declare_mapper_allocatable
10+
implicit none
11+
12+
type :: real_t
13+
real, allocatable :: real_arr(:)
14+
end type real_t
15+
16+
! Map the allocatable array payload via a named mapper.
17+
!$omp declare mapper (xyz : real_t :: t) map(tofrom: t%real_arr)
18+
19+
type(real_t) :: r
20+
integer :: i
21+
logical :: ok
22+
23+
allocate(r%real_arr(10))
24+
r%real_arr = 1.0
25+
26+
!$omp target map(mapper(xyz), tofrom: r)
27+
do i = 1, size(r%real_arr)
28+
r%real_arr(i) = 3.0
29+
end do
30+
!$omp end target
31+
32+
ok = .true.
33+
do i = 1, size(r%real_arr)
34+
if (r%real_arr(i) /= 3.0) ok = .false.
35+
end do
36+
if (ok) then
37+
print *, "Test passed!"
38+
else
39+
print *, "Test failed!"
40+
do i = 1, size(r%real_arr)
41+
print *, r%real_arr(i)
42+
end do
43+
end if
44+
45+
deallocate(r%real_arr)
46+
end program target_declare_mapper_allocatable
47+
48+
! CHECK: Test passed!

0 commit comments

Comments
 (0)