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

Akash Banerjee via flang-commits flang-commits at lists.llvm.org
Thu Jun 18 07:57:17 PDT 2026


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

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

>From 3d273241433ed9e3966b043f99597a4ec9706e9d Mon Sep 17 00:00:00 2001
From: Akash Banerjee <Akash.Banerjee at amd.com>
Date: Thu, 18 Jun 2026 15:40:22 +0100
Subject: [PATCH] [Flang][OpenMP] Fix Fortran pointer map(present) null
 handling

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

Co-authored-by: Codex <codex at openai.com>
---
 .../test/Lower/OpenMP/map-present-pointer.f90 | 16 +++++++++
 offload/include/OpenMP/Mapping.h              |  4 +++
 offload/libomptarget/OpenMP/Mapping.cpp       |  2 +-
 offload/libomptarget/omptarget.cpp            |  6 ++--
 .../fortran/target_map_present_pointer.f90    | 34 +++++++++++++++++++
 5 files changed, 59 insertions(+), 3 deletions(-)
 create mode 100644 flang/test/Lower/OpenMP/map-present-pointer.f90
 create mode 100644 offload/test/offloading/fortran/target_map_present_pointer.f90

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



More information about the flang-commits mailing list