https://github.com/TIFitis updated 
https://github.com/llvm/llvm-project/pull/169367

>From c6440f42e19a54bfce0d7f55ca40b5a28b30f7bc Mon Sep 17 00:00:00 2001
From: Akash Banerjee <[email protected]>
Date: Mon, 24 Nov 2025 17:05:29 +0000
Subject: [PATCH 1/4] [MLIR][OpenMP] Add OpenMPToLLVMIRTranslation support for
 is_device_ptr

---
 .../OpenMP/map-types-and-sizes.f90            |  9 +++
 .../OpenMP/OpenMPToLLVMIRTranslation.cpp      | 18 +++--
 mlir/test/Target/LLVMIR/openmp-todo.mlir      | 11 ---
 .../fortran/target-is-device-ptr.f90          | 79 +++++++++++++++++++
 4 files changed, 100 insertions(+), 17 deletions(-)
 create mode 100644 offload/test/offloading/fortran/target-is-device-ptr.f90

diff --git a/flang/test/Integration/OpenMP/map-types-and-sizes.f90 
b/flang/test/Integration/OpenMP/map-types-and-sizes.f90
index 44a049f5ac510..85434460bbea6 100644
--- a/flang/test/Integration/OpenMP/map-types-and-sizes.f90
+++ b/flang/test/Integration/OpenMP/map-types-and-sizes.f90
@@ -33,6 +33,15 @@ subroutine mapType_array
   !$omp end target
 end subroutine mapType_array
 
+!CHECK: @.offload_sizes{{.*}} = private unnamed_addr constant [1 x i64] [i64 8]
+!CHECK: @.offload_maptypes{{.*}} = private unnamed_addr constant [1 x i64] 
[i64 288]
+subroutine mapType_is_device_ptr
+  use iso_c_binding, only : c_ptr
+  type(c_ptr) :: p
+  !$omp target is_device_ptr(p)
+  !$omp end target
+end subroutine mapType_is_device_ptr
+
 !CHECK: @.offload_sizes{{.*}} = private unnamed_addr constant [4 x i64] [i64 
0, i64 24, i64 8, i64 0]
 !CHECK: @.offload_maptypes{{.*}} = private unnamed_addr constant [4 x i64] 
[i64 32, i64 281474976711169, i64 281474976711171, i64 281474976711187]
 subroutine mapType_ptr
diff --git 
a/mlir/lib/Target/LLVMIR/Dialect/OpenMP/OpenMPToLLVMIRTranslation.cpp 
b/mlir/lib/Target/LLVMIR/Dialect/OpenMP/OpenMPToLLVMIRTranslation.cpp
index f28454075f1d3..9fa0e659320d6 100644
--- a/mlir/lib/Target/LLVMIR/Dialect/OpenMP/OpenMPToLLVMIRTranslation.cpp
+++ b/mlir/lib/Target/LLVMIR/Dialect/OpenMP/OpenMPToLLVMIRTranslation.cpp
@@ -332,10 +332,7 @@ static LogicalResult checkImplementationStatus(Operation 
&op) {
         op.getInReductionSyms())
       result = todo("in_reduction");
   };
-  auto checkIsDevicePtr = [&todo](auto op, LogicalResult &result) {
-    if (!op.getIsDevicePtrVars().empty())
-      result = todo("is_device_ptr");
-  };
+  auto checkIsDevicePtr = [](auto, LogicalResult &) {};
   auto checkLinear = [&todo](auto op, LogicalResult &result) {
     if (!op.getLinearVars().empty() || !op.getLinearStepVars().empty())
       result = todo("linear");
@@ -3996,6 +3993,9 @@ static void collectMapDataFromMapOperands(
     llvm::Value *origValue = moduleTranslation.lookupValue(offloadPtr);
     auto mapType = convertClauseMapFlags(mapOp.getMapType());
     auto mapTypeAlways = llvm::omp::OpenMPOffloadMappingFlags::OMP_MAP_ALWAYS;
+    bool isDevicePtr =
+        (mapOp.getMapType() & omp::ClauseMapFlags::storage) ==
+        omp::ClauseMapFlags::storage;
 
     mapData.OriginalValue.push_back(origValue);
     mapData.BasePointers.push_back(origValue);
@@ -4006,7 +4006,12 @@ static void collectMapDataFromMapOperands(
     mapData.Sizes.push_back(
         builder.getInt64(dl.getTypeSize(mapOp.getVarType())));
     mapData.MapClause.push_back(mapOp.getOperation());
-    if (llvm::to_underlying(mapType & mapTypeAlways)) {
+    if (isDevicePtr) {
+      mapType |= llvm::omp::OpenMPOffloadMappingFlags::OMP_MAP_TARGET_PARAM;
+      mapType |= llvm::omp::OpenMPOffloadMappingFlags::OMP_MAP_LITERAL;
+      mapData.Types.push_back(mapType);
+      mapData.Mappers.push_back(nullptr);
+    } else if (llvm::to_underlying(mapType & mapTypeAlways)) {
       // Descriptors are mapped with the ALWAYS flag, since they can get
       // rematerialized, so the address of the decriptor for a given object
       // may change from one place to another.
@@ -4029,7 +4034,8 @@ static void collectMapDataFromMapOperands(
     mapData.Names.push_back(LLVM::createMappingInformation(
         mapOp.getLoc(), *moduleTranslation.getOpenMPBuilder()));
     mapData.DevicePointers.push_back(
-        llvm::OpenMPIRBuilder::DeviceInfoTy::Address);
+        isDevicePtr ? llvm::OpenMPIRBuilder::DeviceInfoTy::Pointer
+                    : llvm::OpenMPIRBuilder::DeviceInfoTy::Address);
     mapData.IsAMapping.push_back(false);
     mapData.IsAMember.push_back(checkIsAMember(hasDevAddrOperands, mapOp));
   }
diff --git a/mlir/test/Target/LLVMIR/openmp-todo.mlir 
b/mlir/test/Target/LLVMIR/openmp-todo.mlir
index af6d254cfd3c3..0704008aa7135 100644
--- a/mlir/test/Target/LLVMIR/openmp-todo.mlir
+++ b/mlir/test/Target/LLVMIR/openmp-todo.mlir
@@ -238,17 +238,6 @@ llvm.func @target_in_reduction(%x : !llvm.ptr) {
 
 // -----
 
-llvm.func @target_is_device_ptr(%x : !llvm.ptr) {
-  // expected-error@below {{not yet implemented: Unhandled clause 
is_device_ptr in omp.target operation}}
-  // expected-error@below {{LLVM Translation failed for operation: omp.target}}
-  omp.target is_device_ptr(%x : !llvm.ptr) {
-    omp.terminator
-  }
-  llvm.return
-}
-
-// -----
-
 llvm.func @target_enter_data_depend(%x: !llvm.ptr) {
   // expected-error@below {{not yet implemented: Unhandled clause depend in 
omp.target_enter_data operation}}
   // expected-error@below {{LLVM Translation failed for operation: 
omp.target_enter_data}}
diff --git a/offload/test/offloading/fortran/target-is-device-ptr.f90 
b/offload/test/offloading/fortran/target-is-device-ptr.f90
new file mode 100644
index 0000000000000..6010d59113498
--- /dev/null
+++ b/offload/test/offloading/fortran/target-is-device-ptr.f90
@@ -0,0 +1,79 @@
+! Validate that a device pointer allocated via OpenMP runtime APIs can be
+! consumed by a TARGET region using the is_device_ptr clause.
+! REQUIRES: flang, amdgcn-amd-amdhsa
+! 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
+
+! RUN: %libomptarget-compile-fortran-run-and-check-generic
+
+program is_device_ptr_target
+  use omp_lib
+  use iso_c_binding
+  implicit none
+
+  integer, parameter :: n = 4
+  integer, target :: host(n)
+  type(c_ptr) :: device_ptr
+  integer(c_int) :: rc
+  integer :: i
+
+  do i = 1, n
+    host(i) = i
+  end do
+
+  device_ptr = omp_target_alloc(int(n, c_size_t) * int(c_sizeof(host(1)), 
c_size_t), &
+                                omp_get_default_device())
+  if (.not. c_associated(device_ptr)) then
+    print *, "device alloc failed"
+    stop 1
+  end if
+
+  rc = omp_target_memcpy(device_ptr, c_loc(host), &
+                         int(n, c_size_t) * int(c_sizeof(host(1)), c_size_t), &
+                         0_c_size_t, 0_c_size_t, &
+                         omp_get_default_device(), omp_get_initial_device())
+  if (rc .ne. 0) then
+    print *, "host->device memcpy failed"
+    call omp_target_free(device_ptr, omp_get_default_device())
+    stop 1
+  end if
+
+  call fill_on_device(device_ptr)
+
+  rc = omp_target_memcpy(c_loc(host), device_ptr, &
+                         int(n, c_size_t) * int(c_sizeof(host(1)), c_size_t), &
+                         0_c_size_t, 0_c_size_t, &
+                         omp_get_initial_device(), omp_get_default_device())
+  call omp_target_free(device_ptr, omp_get_default_device())
+
+  if (rc .ne. 0) then
+    print *, "device->host memcpy failed"
+    stop 1
+  end if
+
+  if (all(host == [2, 4, 6, 8])) then
+    print *, "PASS"
+  else
+    print *, "FAIL", host
+  end if
+
+contains
+  subroutine fill_on_device(ptr)
+    type(c_ptr) :: ptr
+    integer, pointer :: p(:)
+    call c_f_pointer(ptr, p, [n])
+
+    !$omp target is_device_ptr(ptr)
+      p(1) = 2
+      p(2) = 4
+      p(3) = 6
+      p(4) = 8
+    !$omp end target
+  end subroutine fill_on_device
+end program is_device_ptr_target
+
+!CHECK: PASS

>From a88f1712d23a53f10dc6eb553efdd7a8b55ea794 Mon Sep 17 00:00:00 2001
From: Akash Banerjee <[email protected]>
Date: Mon, 24 Nov 2025 17:09:45 +0000
Subject: [PATCH 2/4] Fix clang-format.

---
 .../LLVMIR/Dialect/OpenMP/OpenMPToLLVMIRTranslation.cpp      | 5 ++---
 1 file changed, 2 insertions(+), 3 deletions(-)

diff --git 
a/mlir/lib/Target/LLVMIR/Dialect/OpenMP/OpenMPToLLVMIRTranslation.cpp 
b/mlir/lib/Target/LLVMIR/Dialect/OpenMP/OpenMPToLLVMIRTranslation.cpp
index 9fa0e659320d6..00c4c351caa4e 100644
--- a/mlir/lib/Target/LLVMIR/Dialect/OpenMP/OpenMPToLLVMIRTranslation.cpp
+++ b/mlir/lib/Target/LLVMIR/Dialect/OpenMP/OpenMPToLLVMIRTranslation.cpp
@@ -3993,9 +3993,8 @@ static void collectMapDataFromMapOperands(
     llvm::Value *origValue = moduleTranslation.lookupValue(offloadPtr);
     auto mapType = convertClauseMapFlags(mapOp.getMapType());
     auto mapTypeAlways = llvm::omp::OpenMPOffloadMappingFlags::OMP_MAP_ALWAYS;
-    bool isDevicePtr =
-        (mapOp.getMapType() & omp::ClauseMapFlags::storage) ==
-        omp::ClauseMapFlags::storage;
+    bool isDevicePtr = (mapOp.getMapType() & omp::ClauseMapFlags::storage) ==
+                       omp::ClauseMapFlags::storage;
 
     mapData.OriginalValue.push_back(origValue);
     mapData.BasePointers.push_back(origValue);

>From f4ff68bf9f61d0da012ea4a85682ba91d45d0777 Mon Sep 17 00:00:00 2001
From: Akash Banerjee <[email protected]>
Date: Tue, 25 Nov 2025 16:35:56 +0000
Subject: [PATCH 3/4] Add is_device_ptr to mlir map flag.

---
 flang/lib/Lower/OpenMP/ClauseProcessor.cpp            |  3 ++-
 mlir/include/mlir/Dialect/OpenMP/OpenMPEnums.td       |  4 +++-
 .../Dialect/OpenMP/OpenMPToLLVMIRTranslation.cpp      | 11 +++++++----
 3 files changed, 12 insertions(+), 6 deletions(-)

diff --git a/flang/lib/Lower/OpenMP/ClauseProcessor.cpp 
b/flang/lib/Lower/OpenMP/ClauseProcessor.cpp
index 81a47e20b2a88..d8d9b51b23804 100644
--- a/flang/lib/Lower/OpenMP/ClauseProcessor.cpp
+++ b/flang/lib/Lower/OpenMP/ClauseProcessor.cpp
@@ -1146,7 +1146,8 @@ bool ClauseProcessor::processIsDevicePtr(
           const parser::CharBlock &source) {
         mlir::Location location = converter.genLocation(source);
         mlir::omp::ClauseMapFlags mapTypeBits =
-            mlir::omp::ClauseMapFlags::storage;
+            mlir::omp::ClauseMapFlags::return_param |
+            mlir::omp::ClauseMapFlags::is_device_ptr;
         processMapObjects(stmtCtx, location, clause.v, mapTypeBits,
                           parentMemberIndices, result.isDevicePtrVars,
                           isDeviceSyms);
diff --git a/mlir/include/mlir/Dialect/OpenMP/OpenMPEnums.td 
b/mlir/include/mlir/Dialect/OpenMP/OpenMPEnums.td
index d9882cbcb5977..8a7680bf6385e 100644
--- a/mlir/include/mlir/Dialect/OpenMP/OpenMPEnums.td
+++ b/mlir/include/mlir/Dialect/OpenMP/OpenMPEnums.td
@@ -126,6 +126,7 @@ def ClauseMapFlagsAttachAuto : 
I32BitEnumAttrCaseBit<"attach_auto", 15>;
 def ClauseMapFlagsRefPtr : I32BitEnumAttrCaseBit<"ref_ptr", 16>;
 def ClauseMapFlagsRefPtee : I32BitEnumAttrCaseBit<"ref_ptee", 17>;
 def ClauseMapFlagsRefPtrPtee : I32BitEnumAttrCaseBit<"ref_ptr_ptee", 18>;
+def ClauseMapFlagsIsDevicePtr : I32BitEnumAttrCaseBit<"is_device_ptr", 19>;
 
 def ClauseMapFlags : OpenMP_BitEnumAttr<
     "ClauseMapFlags",
@@ -149,7 +150,8 @@ def ClauseMapFlags : OpenMP_BitEnumAttr<
       ClauseMapFlagsAttachAuto,
       ClauseMapFlagsRefPtr,
       ClauseMapFlagsRefPtee,
-      ClauseMapFlagsRefPtrPtee
+      ClauseMapFlagsRefPtrPtee,
+      ClauseMapFlagsIsDevicePtr
     ]>;
 
 def ClauseMapFlagsAttr : OpenMP_EnumAttr<ClauseMapFlags,
diff --git 
a/mlir/lib/Target/LLVMIR/Dialect/OpenMP/OpenMPToLLVMIRTranslation.cpp 
b/mlir/lib/Target/LLVMIR/Dialect/OpenMP/OpenMPToLLVMIRTranslation.cpp
index 00c4c351caa4e..1519fee6ea302 100644
--- a/mlir/lib/Target/LLVMIR/Dialect/OpenMP/OpenMPToLLVMIRTranslation.cpp
+++ b/mlir/lib/Target/LLVMIR/Dialect/OpenMP/OpenMPToLLVMIRTranslation.cpp
@@ -332,7 +332,6 @@ static LogicalResult checkImplementationStatus(Operation 
&op) {
         op.getInReductionSyms())
       result = todo("in_reduction");
   };
-  auto checkIsDevicePtr = [](auto, LogicalResult &) {};
   auto checkLinear = [&todo](auto op, LogicalResult &result) {
     if (!op.getLinearVars().empty() || !op.getLinearStepVars().empty())
       result = todo("linear");
@@ -441,7 +440,6 @@ static LogicalResult checkImplementationStatus(Operation 
&op) {
         checkBare(op, result);
         checkDevice(op, result);
         checkInReduction(op, result);
-        checkIsDevicePtr(op, result);
       })
       .Default([](Operation &) {
         // Assume all clauses for an operation can be translated unless they 
are
@@ -3872,6 +3870,10 @@ convertClauseMapFlags(omp::ClauseMapFlags mlirFlags) {
   if (mapTypeToBool(omp::ClauseMapFlags::attach))
     mapType |= llvm::omp::OpenMPOffloadMappingFlags::OMP_MAP_ATTACH;
 
+  // No dedicated LLVM runtime flag for is_device_ptr; handled separately.
+  if (mapTypeToBool(omp::ClauseMapFlags::is_device_ptr))
+    mapType |= llvm::omp::OpenMPOffloadMappingFlags::OMP_MAP_RETURN_PARAM;
+
   return mapType;
 }
 
@@ -3993,8 +3995,9 @@ static void collectMapDataFromMapOperands(
     llvm::Value *origValue = moduleTranslation.lookupValue(offloadPtr);
     auto mapType = convertClauseMapFlags(mapOp.getMapType());
     auto mapTypeAlways = llvm::omp::OpenMPOffloadMappingFlags::OMP_MAP_ALWAYS;
-    bool isDevicePtr = (mapOp.getMapType() & omp::ClauseMapFlags::storage) ==
-                       omp::ClauseMapFlags::storage;
+    bool isDevicePtr =
+        (mapOp.getMapType() & omp::ClauseMapFlags::is_device_ptr) !=
+        omp::ClauseMapFlags::none;
 
     mapData.OriginalValue.push_back(origValue);
     mapData.BasePointers.push_back(origValue);

>From ec3c5626ff4ae6a9481cc7f771f72a784fa59336 Mon Sep 17 00:00:00 2001
From: Akash Banerjee <[email protected]>
Date: Wed, 26 Nov 2025 16:54:20 +0000
Subject: [PATCH 4/4] Update tests.

---
 .../OpenMP/map-types-and-sizes.f90            |  2 +-
 .../fortran/target-is-device-ptr.f90          | 87 ++++++-------------
 2 files changed, 28 insertions(+), 61 deletions(-)

diff --git a/flang/test/Integration/OpenMP/map-types-and-sizes.f90 
b/flang/test/Integration/OpenMP/map-types-and-sizes.f90
index 85434460bbea6..ddb943c95fba2 100644
--- a/flang/test/Integration/OpenMP/map-types-and-sizes.f90
+++ b/flang/test/Integration/OpenMP/map-types-and-sizes.f90
@@ -34,7 +34,7 @@ subroutine mapType_array
 end subroutine mapType_array
 
 !CHECK: @.offload_sizes{{.*}} = private unnamed_addr constant [1 x i64] [i64 8]
-!CHECK: @.offload_maptypes{{.*}} = private unnamed_addr constant [1 x i64] 
[i64 288]
+!CHECK: @.offload_maptypes{{.*}} = private unnamed_addr constant [1 x i64] 
[i64 352]
 subroutine mapType_is_device_ptr
   use iso_c_binding, only : c_ptr
   type(c_ptr) :: p
diff --git a/offload/test/offloading/fortran/target-is-device-ptr.f90 
b/offload/test/offloading/fortran/target-is-device-ptr.f90
index 6010d59113498..b2da1ad23d093 100644
--- a/offload/test/offloading/fortran/target-is-device-ptr.f90
+++ b/offload/test/offloading/fortran/target-is-device-ptr.f90
@@ -1,79 +1,46 @@
-! Validate that a device pointer allocated via OpenMP runtime APIs can be
-! consumed by a TARGET region using the is_device_ptr clause.
+! Validate that a device pointer obtained via omp_get_mapped_ptr can be used
+! inside a TARGET region with the is_device_ptr clause.
 ! REQUIRES: flang, amdgcn-amd-amdhsa
-! 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
 
 ! RUN: %libomptarget-compile-fortran-run-and-check-generic
 
 program is_device_ptr_target
-  use omp_lib
-  use iso_c_binding
+  use iso_c_binding, only : c_ptr, c_loc
   implicit none
 
-  integer, parameter :: n = 4
-  integer, target :: host(n)
-  type(c_ptr) :: device_ptr
-  integer(c_int) :: rc
-  integer :: i
-
-  do i = 1, n
-    host(i) = i
-  end do
+  interface
+    function omp_get_mapped_ptr(host_ptr, device_num)                       &
+        bind(C, name="omp_get_mapped_ptr")
+      use iso_c_binding, only : c_ptr, c_int
+      type(c_ptr) :: omp_get_mapped_ptr
+      type(c_ptr), value :: host_ptr
+      integer(c_int), value :: device_num
+    end function omp_get_mapped_ptr
+  end interface
 
-  device_ptr = omp_target_alloc(int(n, c_size_t) * int(c_sizeof(host(1)), 
c_size_t), &
-                                omp_get_default_device())
-  if (.not. c_associated(device_ptr)) then
-    print *, "device alloc failed"
-    stop 1
-  end if
-
-  rc = omp_target_memcpy(device_ptr, c_loc(host), &
-                         int(n, c_size_t) * int(c_sizeof(host(1)), c_size_t), &
-                         0_c_size_t, 0_c_size_t, &
-                         omp_get_default_device(), omp_get_initial_device())
-  if (rc .ne. 0) then
-    print *, "host->device memcpy failed"
-    call omp_target_free(device_ptr, omp_get_default_device())
-    stop 1
-  end if
+  integer, parameter :: n = 4
+  integer, parameter :: dev = 0
+  integer, target :: a(n)
+  type(c_ptr) :: dptr
+  integer :: flag
 
-  call fill_on_device(device_ptr)
+  a = [2, 4, 6, 8]
+  flag = 0
 
-  rc = omp_target_memcpy(c_loc(host), device_ptr, &
-                         int(n, c_size_t) * int(c_sizeof(host(1)), c_size_t), &
-                         0_c_size_t, 0_c_size_t, &
-                         omp_get_initial_device(), omp_get_default_device())
-  call omp_target_free(device_ptr, omp_get_default_device())
+  !$omp target data map(tofrom: a, flag)
+    dptr = omp_get_mapped_ptr(c_loc(a), dev)
 
-  if (rc .ne. 0) then
-    print *, "device->host memcpy failed"
-    stop 1
-  end if
+    !$omp target is_device_ptr(dptr) map(tofrom: flag)
+      flag = flag + 1
+    !$omp end target
+  !$omp end target data
 
-  if (all(host == [2, 4, 6, 8])) then
+  if (flag .eq. 1 .and. all(a == [2, 4, 6, 8])) then
     print *, "PASS"
   else
-    print *, "FAIL", host
+    print *, "FAIL", a
   end if
 
-contains
-  subroutine fill_on_device(ptr)
-    type(c_ptr) :: ptr
-    integer, pointer :: p(:)
-    call c_f_pointer(ptr, p, [n])
-
-    !$omp target is_device_ptr(ptr)
-      p(1) = 2
-      p(2) = 4
-      p(3) = 6
-      p(4) = 8
-    !$omp end target
-  end subroutine fill_on_device
 end program is_device_ptr_target
 
 !CHECK: PASS

_______________________________________________
llvm-branch-commits mailing list
[email protected]
https://lists.llvm.org/cgi-bin/mailman/listinfo/llvm-branch-commits

Reply via email to