[Mlir-commits] [llvm] [mlir] [OpenMP][MLIR] Preserve to/from flags in mapper base entry for mappers (PR #159799)
Akash Banerjee
llvmlistbot at llvm.org
Fri Sep 19 08:44:10 PDT 2025
https://github.com/TIFitis created https://github.com/llvm/llvm-project/pull/159799
With declare mapper, the parent base entry was emitted as `TARGET_PARAM` only. The mapper received a map-type without `to/from`, causing components to degrade to `alloc`-only (no copies), breaking allocatable payload mapping. This PR preserves the map-type bits from the parent.
This fixes #156466.
>From 6b6c37ff81c0083590dc60164277535679fbeb63 Mon Sep 17 00:00:00 2001
From: Akash Banerjee <Akash.Banerjee at amd.com>
Date: Fri, 19 Sep 2025 16:40:17 +0100
Subject: [PATCH] [OpenMP][MLIR] Preserve to/from flags in mapper base entry
for mappers
With declare mapper, the parent base entry was emitted as TARGET_PARAM only.
The mapper received a map-type without to/from, causing components to degrade
to alloc-only (no copies), breaking allocatable payload mapping.
This PR preseves the map-type bits from the parent.
---
.../OpenMP/OpenMPToLLVMIRTranslation.cpp | 25 ++++++++--
.../target-declare-mapper-allocatable.f90 | 48 +++++++++++++++++++
2 files changed, 70 insertions(+), 3 deletions(-)
create mode 100644 offload/test/offloading/fortran/target-declare-mapper-allocatable.f90
diff --git a/mlir/lib/Target/LLVMIR/Dialect/OpenMP/OpenMPToLLVMIRTranslation.cpp b/mlir/lib/Target/LLVMIR/Dialect/OpenMP/OpenMPToLLVMIRTranslation.cpp
index 5e194dc715d59..4921a1990b6e8 100644
--- a/mlir/lib/Target/LLVMIR/Dialect/OpenMP/OpenMPToLLVMIRTranslation.cpp
+++ b/mlir/lib/Target/LLVMIR/Dialect/OpenMP/OpenMPToLLVMIRTranslation.cpp
@@ -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]);
diff --git a/offload/test/offloading/fortran/target-declare-mapper-allocatable.f90 b/offload/test/offloading/fortran/target-declare-mapper-allocatable.f90
new file mode 100644
index 0000000000000..d8d5e1b5631a5
--- /dev/null
+++ b/offload/test/offloading/fortran/target-declare-mapper-allocatable.f90
@@ -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!
More information about the Mlir-commits
mailing list