[flang-commits] [flang] [llvm] [Flang][OpenMP] Fix Fortran pointer map(present) null handling (PR #204615)

via flang-commits flang-commits at lists.llvm.org
Thu Jun 18 07:58:07 PDT 2026


llvmorg-github-actions[bot] wrote:


<!--LLVM PR SUMMARY COMMENT-->

@llvm/pr-subscribers-flang-fir-hlfir

Author: Akash Banerjee (TIFitis)

<details>
<summary>Changes</summary>

Allow map(present, to: ...) on a Fortran pointer with a null, zero-length pointee map without aborting the target region.

---
Full diff: https://github.com/llvm/llvm-project/pull/204615.diff


5 Files Affected:

- (added) flang/test/Lower/OpenMP/map-present-pointer.f90 (+16) 
- (modified) offload/include/OpenMP/Mapping.h (+4) 
- (modified) offload/libomptarget/OpenMP/Mapping.cpp (+1-1) 
- (modified) offload/libomptarget/omptarget.cpp (+4-2) 
- (added) offload/test/offloading/fortran/target_map_present_pointer.f90 (+34) 


``````````diff
diff --git a/flang/test/Lower/OpenMP/map-present-pointer.f90 b/flang/test/Lower/OpenMP/map-present-pointer.f90
new file mode 100644
index 0000000000000..8363606be9d99
--- /dev/null
+++ b/flang/test/Lower/OpenMP/map-present-pointer.f90
@@ -0,0 +1,16 @@
+! RUN: %flang_fc1 -emit-hlfir -fopenmp %s -o - | FileCheck %s
+
+subroutine map_present_pointer(p)
+  integer, pointer :: p(:)
+
+! CHECK-LABEL: func.func @_QPmap_present_pointer
+! CHECK: %[[DECL:.*]]:2 = hlfir.declare %{{.*}} {fortran_attrs = #fir.var_attrs<pointer>
+! CHECK: %[[BASE:.*]] = fir.box_offset %[[DECL]]#1 base_addr
+! CHECK: %[[PTEE_MAP:.*]] = omp.map.info var_ptr(%[[DECL]]#1 : {{.*}}) map_clauses(present, to) capture(ByRef) var_ptr_ptr(%[[BASE]] : {{.*}}) {{.*}} -> !fir.llvm_ptr
+! CHECK: %[[DESC_MAP:.*]] = omp.map.info var_ptr(%[[DECL]]#1 : {{.*}}) map_clauses(always, to) capture(ByRef) members(%[[PTEE_MAP]] : [0] : {{.*}}) -> {{.*}} {name = "p"}
+! CHECK: %[[ATTACH_MAP:.*]] = omp.map.info var_ptr(%[[DECL]]#1 : {{.*}}) map_clauses(attach, ref_ptr, ref_ptee) capture(ByRef) var_ptr_ptr(%[[BASE]] : {{.*}})
+! CHECK: omp.target map_entries(%[[DESC_MAP]] -> {{.*}}, %[[ATTACH_MAP]] -> {{.*}}, %[[PTEE_MAP]] -> {{.*}}
+!$omp target map(present, to: p)
+  if (associated(p)) p(1) = p(1)
+!$omp end target
+end subroutine
diff --git a/offload/include/OpenMP/Mapping.h b/offload/include/OpenMP/Mapping.h
index e4024abf26690..f76363af5091c 100644
--- a/offload/include/OpenMP/Mapping.h
+++ b/offload/include/OpenMP/Mapping.h
@@ -28,6 +28,10 @@ class AsyncInfoTy;
 
 using map_var_info_t = void *;
 
+inline bool isNullMap(const void *HstPtrBegin, int64_t Size) {
+  return HstPtrBegin == nullptr && Size == 0;
+}
+
 class MappingConfig {
 
   MappingConfig() {
diff --git a/offload/libomptarget/OpenMP/Mapping.cpp b/offload/libomptarget/OpenMP/Mapping.cpp
index 1bb2e424bd083..3639fb160181a 100644
--- a/offload/libomptarget/OpenMP/Mapping.cpp
+++ b/offload/libomptarget/OpenMP/Mapping.cpp
@@ -283,7 +283,7 @@ TargetPointerResultTy MappingInfoTy::getTargetPointer(
       LR.TPR.Flags.IsHostPointer = true;
       LR.TPR.TargetPointer = HstPtrBegin;
     }
-  } else if (HasPresentModifier) {
+  } else if (HasPresentModifier && !isNullMap(HstPtrBegin, Size)) {
     ODBG(ODT_Mapping) << "Mapping required by 'present' map type modifier does "
                       << "not exist for HstPtrBegin=" << HstPtrBegin
                       << ", Size=" << Size;
diff --git a/offload/libomptarget/omptarget.cpp b/offload/libomptarget/omptarget.cpp
index 17b215732d51b..91489f9c03a9b 100644
--- a/offload/libomptarget/omptarget.cpp
+++ b/offload/libomptarget/omptarget.cpp
@@ -665,7 +665,8 @@ int targetDataBegin(ident_t *Loc, DeviceTy &Device, int32_t ArgNum,
     IsHostPtr = TPR.Flags.IsHostPointer;
     // If data_size==0, then the argument could be a zero-length pointer to
     // NULL, so getOrAlloc() returning NULL is not an error.
-    if (!TgtPtrBegin && (DataSize || HasPresentModifier)) {
+    if (!TgtPtrBegin && (DataSize || (HasPresentModifier &&
+                                      !isNullMap(HstPtrBegin, DataSize)))) {
       REPORT() << "Call to getTargetPointer returned null pointer ("
                << (HasPresentModifier ? "'present' map type modifier"
                                       : "device failure or illegal mapping")
@@ -1132,7 +1133,8 @@ int targetDataEnd(ident_t *Loc, DeviceTy &Device, int32_t ArgNum,
         ForceDelete, /*FromDataEnd=*/true);
     void *TgtPtrBegin = TPR.TargetPointer;
     if (!TPR.isPresent() && !TPR.isHostPointer() &&
-        (DataSize || HasPresentModifier)) {
+        (DataSize ||
+         (HasPresentModifier && !isNullMap(HstPtrBegin, DataSize)))) {
       ODBG(ODT_Mapping) << "Mapping does not exist ("
                         << (HasPresentModifier ? "'present' map type modifier"
                                                : "ignored")
diff --git a/offload/test/offloading/fortran/target_map_present_pointer.f90 b/offload/test/offloading/fortran/target_map_present_pointer.f90
new file mode 100644
index 0000000000000..07d2176b3e312
--- /dev/null
+++ b/offload/test/offloading/fortran/target_map_present_pointer.f90
@@ -0,0 +1,34 @@
+! REQUIRES: flang, amdgpu
+! RUN: %libomptarget-compile-fortran-generic
+! RUN: %libomptarget-run-generic 2>&1 | %fcheck-generic
+
+program map_present_pointer
+  implicit none
+  integer, target :: src(4) = [10, 20, 30, 40]
+  integer, pointer :: p(:) => null()
+  integer :: out
+
+  out = -1
+!$omp target map(present, to: p) map(tofrom: out)
+  if (associated(p)) out = p(1)
+!$omp end target
+
+  if (out /= -1) stop 1
+  print *, "null pointer ok"
+
+  p => src
+  out = -1
+
+!$omp target enter data map(to: src)
+!$omp target map(present, to: p) map(from: out)
+  out = p(2)
+!$omp end target
+!$omp target exit data map(delete: src)
+
+  if (out /= 20) stop 2
+  print *, "associated pointer ok"
+end program
+
+! CHECK-NOT: omptarget
+! CHECK: null pointer ok
+! CHECK: associated pointer ok

``````````

</details>


https://github.com/llvm/llvm-project/pull/204615


More information about the flang-commits mailing list