[flang] [llvm] [mlir] [flang][mlir][OpenMP] Report Fortran names for privatized target maps (PR #228195)

Jason Van Beusekom via llvm-commits llvm-commits at lists.llvm.org
Thu Oct 1 11:51:56 PDT 2026


https://github.com/Jason-Van-Beusekom created https://github.com/llvm/llvm-project/pull/228195

Privatized, firstprivate and implicitly captured variables offloaded to a target device were reported as "unknown" in LIBOMPTARGET_INFO debug output. This PR addresses this by adding the variable names to the offload mapping information:
 
- `MapsForPrivatizedSymbols` now sets the name on the omp.map.info it creates,
   recovering it from the hlfir.declare uniq name or, for anonymously boxed
   values (e.g. a firstprivate array), from a NameLoc on the descriptor's
   alloca.
 - `privatizeSymbol` tags that alloca with a NameLoc carrying the symbol name
   so the pass can recover it when there is no hlfir.declare.
 - `createMappingInformation` gains an optional map name and prefers it over the
   location-derived name; the OpenMP translation forwards each map's name
   attribute for both parent and member entries.
   
   
  Repro: 
 ``` fortran
 program f2_var_names
  implicit none
  integer :: factor, base, res
  integer :: arr(4)
  factor = 7
  base = 5
  res = 0
  arr = (/1, 2, 3, 4/)

  ! explicit firstprivate scalar (factor) + implicit scalar capture (base)
  !$omp target map(tofrom: res) firstprivate(factor)
    res = factor + base
  !$omp end target
  print *, "res1 =", res   ! expect 12

  ! array firstprivate is boxed for privatization; the descriptor maps must
  ! still report the source name.
  !$omp target map(tofrom: res) firstprivate(arr)
    res = arr(1) + arr(4)
  !$omp end target
  print *, "res2 =", res   ! expect 5
end program f2_var_names 
 ```
 Output:
 ``` bash
 # Patched Flang
 omptarget device 0 info: Entering OpenMP kernel at f2_var_names.f90:22:9 with 3 arguments:
omptarget device 0 info: tofrom(res)[4] 
omptarget device 0 info: firstprivate(base)[4] (implicit)
omptarget device 0 info: to(factor)[4] 
omptarget device 0 info: Entering OpenMP kernel at f2_var_names.f90:29:9 with 5 arguments:
omptarget device 0 info: tofrom(res)[4] 
omptarget device 0 info: to(arr)[48] 
omptarget device 0 info: to(arr)[48] 
omptarget device 0 info: tofrom(unknown)[16] 
omptarget device 0 info: attach(arr)[48] 
 res1 = 12
 res2 = 5
 # Base Flang
 omptarget device 0 info: Entering OpenMP kernel at f2_var_names.f90:22:9 with 3 arguments:
omptarget device 0 info: tofrom(res)[4] 
omptarget device 0 info: firstprivate(unknown)[4] (implicit)
omptarget device 0 info: to(unknown)[4] 
omptarget device 0 info: Entering OpenMP kernel at f2_var_names.f90:29:9 with 5 arguments:
omptarget device 0 info: tofrom(res)[4] 
omptarget device 0 info: to(unknown)[48] 
omptarget device 0 info: to(unknown)[48] 
omptarget device 0 info: tofrom(unknown)[16] 
omptarget device 0 info: attach(unknown)[48] 
 res1 = 12
 res2 = 5
 ```
 
 Assisted-by: Opus 4.8

>From 538473afad186e0adb07a64b247613a65d057181 Mon Sep 17 00:00:00 2001
From: Jason Van Beusekom <jason.van-beusekom at hpe.com>
Date: Thu, 1 Oct 2026 13:42:35 -0500
Subject: [PATCH] [flang][mlir][OpenMP] Report Fortran names for privatized
 target maps

---
 flang/lib/Lower/Support/Utils.cpp             |  5 +-
 .../OpenMP/MapsForPrivatizedSymbols.cpp       | 17 +++-
 .../target-private-allocatable.f90            |  4 +-
 .../target-private-implicit-scalar-map-2.f90  |  4 +-
 .../target-private-implicit-scalar-map.f90    |  4 +-
 ...rget-teams-private-implicit-scalar-map.f90 |  4 +-
 flang/test/Lower/OpenMP/defaultmap.f90        |  2 +-
 .../Lower/OpenMP/optional-argument-map-2.f90  |  4 +-
 flang/test/Lower/OpenMP/target.f90            |  4 +-
 .../omp-maps-for-privatized-symbols.fir       |  8 +-
 .../mlir/Target/LLVMIR/Dialect/OpenMPCommon.h |  3 +-
 .../OpenMP/OpenMPToLLVMIRTranslation.cpp      | 30 +++++--
 .../Target/LLVMIR/Dialect/OpenMPCommon.cpp    | 15 ++--
 .../fortran/target-firstprivate-info.f90      | 82 +++++++++++++++++++
 14 files changed, 153 insertions(+), 33 deletions(-)
 create mode 100644 offload/test/offloading/fortran/target-firstprivate-info.f90

diff --git a/flang/lib/Lower/Support/Utils.cpp b/flang/lib/Lower/Support/Utils.cpp
index e6b6e923308af..ca131529158d3 100644
--- a/flang/lib/Lower/Support/Utils.cpp
+++ b/flang/lib/Lower/Support/Utils.cpp
@@ -749,8 +749,11 @@ void privatizeSymbol(
     // Boxes should be passed by reference into nested regions:
     auto oldIP = firOpBuilder.saveInsertionPoint();
     firOpBuilder.setInsertionPointToStart(firOpBuilder.getAllocaBlock());
+    // Get name so later passes (e.g. MapsForPrivatizedSymbols) can report it in offload info.
+    mlir::Location boxLoc = mlir::NameLoc::get(
+        firOpBuilder.getStringAttr(sym->name().ToString()), symLoc);
     auto alloca =
-        fir::AllocaOp::create(firOpBuilder, symLoc, privVal.getType());
+        fir::AllocaOp::create(firOpBuilder, boxLoc, privVal.getType());
     firOpBuilder.restoreInsertionPoint(oldIP);
     fir::StoreOp::create(firOpBuilder, symLoc, privVal, alloca);
     privVal = alloca;
diff --git a/flang/lib/Optimizer/OpenMP/MapsForPrivatizedSymbols.cpp b/flang/lib/Optimizer/OpenMP/MapsForPrivatizedSymbols.cpp
index de3dd8d352b3b..a831e6abaaa2d 100644
--- a/flang/lib/Optimizer/OpenMP/MapsForPrivatizedSymbols.cpp
+++ b/flang/lib/Optimizer/OpenMP/MapsForPrivatizedSymbols.cpp
@@ -29,6 +29,7 @@
 #include "flang/Optimizer/Dialect/Support/KindMapping.h"
 #include "flang/Optimizer/HLFIR/HLFIROps.h"
 #include "flang/Optimizer/OpenMP/Passes.h"
+#include "flang/Optimizer/Support/InternalNames.h"
 #include "flang/Utils/OpenMP.h"
 
 #include "mlir/Dialect/Func/IR/FuncOps.h"
@@ -73,6 +74,7 @@ class MapsForPrivatizedSymbolsPass
     Operation *definingOp = var.getDefiningOp();
 
     Value varPtr = var;
+    mlir::StringAttr mapName;
     // We want the first result of the hlfir.declare op because our goal
     // is to map the descriptor (fir.box or fir.boxchar) and the first
     // result for hlfir.declare is the descriptor if a the symbol being
@@ -80,8 +82,19 @@ class MapsForPrivatizedSymbolsPass
     // Some types are boxed immediately before privatization. These have other
     // operations in between the privatization and the declaration. It is safe
     // to use var directly here because they will be boxed anyway.
-    if (auto declOp = llvm::dyn_cast_if_present<hlfir::DeclareOp>(definingOp))
+    if (auto declOp = llvm::dyn_cast_if_present<hlfir::DeclareOp>(definingOp)) {
       varPtr = declOp.getBase();
+      std::string sourceName =
+          fir::NameUniquer::deconstruct(declOp.getUniqName()).second.name;
+      if (!sourceName.empty())
+        mapName = builder.getStringAttr(sourceName);
+    }
+    // Boxed values map an anonymous descriptor with no declare
+    // so recover it from the value's location.
+    if (!mapName) {
+      if (auto nameLoc = llvm::dyn_cast<mlir::NameLoc>(var.getLoc()))
+        mapName = nameLoc.getName();
+    }
 
     // If we do not have a reference to a descriptor but the descriptor itself,
     // then we need to store that on the stack so that we can map the
@@ -156,7 +169,7 @@ class MapsForPrivatizedSymbolsPass
         /*members=*/SmallVector<Value>{},
         /*member_index=*/mlir::ArrayAttr{},
         /*bounds=*/boundsOps,
-        /*mapperId=*/mapperId, /*name=*/StringAttr(),
+        /*mapperId=*/mapperId, /*name=*/mapName,
         builder.getBoolAttr(false));
   }
   void addMapInfoOp(omp::TargetOp targetOp, omp::MapInfoOp mapInfoOp) {
diff --git a/flang/test/Lower/OpenMP/DelayedPrivatization/target-private-allocatable.f90 b/flang/test/Lower/OpenMP/DelayedPrivatization/target-private-allocatable.f90
index 8c5ee99b26fd5..0a1e26c814974 100644
--- a/flang/test/Lower/OpenMP/DelayedPrivatization/target-private-allocatable.f90
+++ b/flang/test/Lower/OpenMP/DelayedPrivatization/target-private-allocatable.f90
@@ -70,8 +70,8 @@ end subroutine target_allocatable
 ! CPU:  %[[VAR_DECL:.*]]:2 = hlfir.declare %[[VAR_ALLOC]]
 ! CPU:  %[[BASE_ADDR:.*]] = fir.box_offset %[[VAR_DECL]]#0 base_addr : (!fir.ref<!fir.box<!fir.heap<i32>>>) -> [[MEMBER_TYPE:.*]]
 ! CPU:  %[[MEMBER:.*]] = omp.map.info var_ptr(%[[VAR_DECL]]#0 : [[TYPE]], [[DESC_TYPE]]) map_clauses(tofrom) capture(ByRef) var_ptr_ptr(%[[BASE_ADDR]] : [[MEMBER_TYPE:.*]], i32) name("") -> {{.*}}
-! CPU:  %[[MAP_VAR:.*]] = omp.map.info var_ptr(%[[VAR_DECL]]#0 : [[TYPE]], [[DESC_TYPE]]) map_clauses({{.*}}to{{.*}}) capture(ByRef) members(%[[MEMBER]] : [0] : [[MEMBER_TYPE]]) -> !fir.ref<!fir.box<!fir.heap<i32>>>
-! CPU:  %[[ATTACH:.*]] = omp.map.info var_ptr(%[[VAR_DECL]]#0 : [[TYPE]], [[DESC_TYPE]]) map_clauses(attach, ref_ptr, ref_ptee) capture(ByRef) var_ptr_ptr(%[[BASE_ADDR]] : [[MEMBER_TYPE]], i32) -> !fir.ref<!fir.box<!fir.heap<i32>>>
+! CPU:  %[[MAP_VAR:.*]] = omp.map.info var_ptr(%[[VAR_DECL]]#0 : [[TYPE]], [[DESC_TYPE]]) map_clauses({{.*}}to{{.*}}) capture(ByRef) members(%[[MEMBER]] : [0] : [[MEMBER_TYPE]]) name("alloc_var") -> !fir.ref<!fir.box<!fir.heap<i32>>>
+! CPU:  %[[ATTACH:.*]] = omp.map.info var_ptr(%[[VAR_DECL]]#0 : [[TYPE]], [[DESC_TYPE]]) map_clauses(attach, ref_ptr, ref_ptee) capture(ByRef) var_ptr_ptr(%[[BASE_ADDR]] : [[MEMBER_TYPE]], i32) name("alloc_var") -> !fir.ref<!fir.box<!fir.heap<i32>>>
 
 ! CPU:  omp.target kernel_type(generic) map_entries(%[[MAP_VAR]] -> %arg0, %[[ATTACH]] -> %arg1, %[[MEMBER]] -> %arg2 : [[TYPE]], [[TYPE]], [[MEMBER_TYPE]]) private(
 ! CPU-SAME: @[[VAR_PRIVATIZER_SYM]] %[[VAR_DECL]]#0 -> %{{.*}} [map_idx=0] : [[TYPE]]) {
diff --git a/flang/test/Lower/OpenMP/DelayedPrivatization/target-private-implicit-scalar-map-2.f90 b/flang/test/Lower/OpenMP/DelayedPrivatization/target-private-implicit-scalar-map-2.f90
index dd7bd0a60f8c4..fe647147c28e1 100644
--- a/flang/test/Lower/OpenMP/DelayedPrivatization/target-private-implicit-scalar-map-2.f90
+++ b/flang/test/Lower/OpenMP/DelayedPrivatization/target-private-implicit-scalar-map-2.f90
@@ -35,6 +35,6 @@ end subroutine target_imp_capture
 ! CHECK-PROG:           %[[VAL_1:.*]] = omp.map.info var_ptr({{.*}} : !fir.ref<!fir.array<10x10xf32>>, !fir.array<10x10xf32>) map_clauses(implicit, tofrom) capture(ByRef) bounds({{.*}}) name("i") -> !fir.ref<!fir.array<10x10xf32>>
 ! CHECK-PROG:           %[[VAL_2:.*]] = omp.map.info var_ptr(%{{.*}} : !fir.ptr<!fir.array<5x5x2xf32>>, !fir.array<5x5x2xf32>) map_clauses(implicit, tofrom) capture(ByRef) bounds({{.*}}) name("j") -> !fir.ptr<!fir.array<5x5x2xf32>>
 ! CHECK-PROG:           %[[VAL_3:.*]] = omp.map.info var_ptr(%{{.*}} : !fir.ptr<!fir.array<25x2xf32>>, !fir.array<25x2xf32>) map_clauses(implicit, tofrom) capture(ByRef) bounds({{.*}}) name("k") -> !fir.ptr<!fir.array<25x2xf32>>
-! CHECK-PROG:           %[[VAL_4:.*]] = omp.map.info var_ptr(%{{.*}} : !fir.ref<i32>, i32) map_clauses(to) capture(ByCopy) -> !fir.ref<i32>
-! CHECK-PROG:           %[[VAL_5:.*]] = omp.map.info var_ptr(%{{.*}} : !fir.ref<i32>, i32) map_clauses(to) capture(ByCopy) -> !fir.ref<i32>
+! CHECK-PROG:           %[[VAL_4:.*]] = omp.map.info var_ptr(%{{.*}} : !fir.ref<i32>, i32) map_clauses(to) capture(ByCopy) name("y") -> !fir.ref<i32>
+! CHECK-PROG:           %[[VAL_5:.*]] = omp.map.info var_ptr(%{{.*}} : !fir.ref<i32>, i32) map_clauses(to) capture(ByCopy) name("z") -> !fir.ref<i32>
 ! CHECK-PROG:           omp.target kernel_type(generic) map_entries(%[[VAL_0]] -> %[[VAL_6:.*]], %[[VAL_1]] -> %[[VAL_7:.*]], %[[VAL_2]] -> %[[VAL_8:.*]], %[[VAL_3]] -> %[[VAL_9:.*]], %[[VAL_4]] -> %[[VAL_10:.*]], %[[VAL_5]] -> %[[VAL_11:.*]] : !fir.ref<i32>, !fir.ref<!fir.array<10x10xf32>>, !fir.ptr<!fir.array<5x5x2xf32>>, !fir.ptr<!fir.array<25x2xf32>>, !fir.ref<i32>, !fir.ref<i32>) private(@_QFtarget_imp_captureEy_firstprivate_i32 %{{.*}}#0 -> %[[VAL_12:.*]] [map_idx=4], @_QMtest_dataEz_firstprivate_i32 %{{.*}}#0 -> %[[VAL_13:.*]] [map_idx=5] : !fir.ref<i32>, !fir.ref<i32>) {
diff --git a/flang/test/Lower/OpenMP/DelayedPrivatization/target-private-implicit-scalar-map.f90 b/flang/test/Lower/OpenMP/DelayedPrivatization/target-private-implicit-scalar-map.f90
index 4ddd88b852f9c..a952ac79a1542 100644
--- a/flang/test/Lower/OpenMP/DelayedPrivatization/target-private-implicit-scalar-map.f90
+++ b/flang/test/Lower/OpenMP/DelayedPrivatization/target-private-implicit-scalar-map.f90
@@ -22,8 +22,8 @@
 ! CHECK:  %[[VAL_1:.*]] = fir.declare %[[VAL_0]] {uniq_name = "_QFExdgfx"} : (!fir.ref<i32>) -> !fir.ref<i32>
 ! CHECK:  %[[VAL_2:.*]] = fir.alloca i32 <{bindc_name = "xfpvx", uniq_name = "_QFExfpvx"}>
 ! CHECK:  %[[VAL_3:.*]] = fir.declare %[[VAL_2]] {uniq_name = "_QFExfpvx"} : (!fir.ref<i32>) -> !fir.ref<i32>
-! CHECK:  %[[VAL_4:.*]] = omp.map.info var_ptr(%[[VAL_3]] : !fir.ref<i32>, i32) map_clauses(to) capture(ByCopy) -> !fir.ref<i32>
-! CHECK:  %[[VAL_5:.*]] = omp.map.info var_ptr(%[[VAL_1]] : !fir.ref<i32>, i32) map_clauses(to) capture(ByCopy) -> !fir.ref<i32>
+! CHECK:  %[[VAL_4:.*]] = omp.map.info var_ptr(%[[VAL_3]] : !fir.ref<i32>, i32) map_clauses(to) capture(ByCopy) name("xfpvx") -> !fir.ref<i32>
+! CHECK:  %[[VAL_5:.*]] = omp.map.info var_ptr(%[[VAL_1]] : !fir.ref<i32>, i32) map_clauses(to) capture(ByCopy) name("xdgfx") -> !fir.ref<i32>
 
 ! CHECK:  omp.target kernel_type(generic) map_entries(%[[VAL_4]] -> %{{.*}}, %[[VAL_5]] -> %{{.*}} : !fir.ref<i32>, !fir.ref<i32>) private(@_QFExfpvx_firstprivate_i32 %[[VAL_3]] -> %[[VAL_6:.*]] [map_idx=0], @_QFExdgfx_firstprivate_i32 %[[VAL_1]] -> %[[VAL_7:.*]] [map_idx=1] : !fir.ref<i32>, !fir.ref<i32>) {
 ! CHECK:  %{{.*}} = fir.declare %[[VAL_6]] {uniq_name = "_QFExfpvx"} : (!fir.ref<i32>) -> !fir.ref<i32>
diff --git a/flang/test/Lower/OpenMP/DelayedPrivatization/target-teams-private-implicit-scalar-map.f90 b/flang/test/Lower/OpenMP/DelayedPrivatization/target-teams-private-implicit-scalar-map.f90
index 5ef94b394daba..e918c213e0df6 100644
--- a/flang/test/Lower/OpenMP/DelayedPrivatization/target-teams-private-implicit-scalar-map.f90
+++ b/flang/test/Lower/OpenMP/DelayedPrivatization/target-teams-private-implicit-scalar-map.f90
@@ -30,8 +30,8 @@ program test_default_implicit_firstprivate
 !CHECK:           %[[VAL_11:.*]] = omp.map.info var_ptr(%[[VAL_0]] : !fir.ref<!fir.box<!fir.heap<!fir.array<?x?x?xi32>>>>, !fir.box<!fir.heap<!fir.array<?x?x?xi32>>>) map_clauses(implicit, tofrom) capture(ByRef) var_ptr_ptr(%[[VAL_10]] : !fir.llvm_ptr<!fir.ref<!fir.array<?x?x?xi32>>>, i32) bounds({{.*}}) name("") -> !fir.llvm_ptr<!fir.ref<!fir.array<?x?x?xi32>>>
 !CHECK:           %[[VAL_12:.*]] = omp.map.info var_ptr(%[[VAL_0]] : !fir.ref<!fir.box<!fir.heap<!fir.array<?x?x?xi32>>>>, !fir.box<!fir.heap<!fir.array<?x?x?xi32>>>) map_clauses(always, implicit, to) capture(ByRef) members(%[[VAL_11]] : [0] : !fir.llvm_ptr<!fir.ref<!fir.array<?x?x?xi32>>>) name("allocarr") -> !fir.ref<!fir.box<!fir.heap<!fir.array<?x?x?xi32>>>>
 !CHECK:           %[[VAL_13:.*]] = omp.map.info var_ptr(%[[VAL_1]] : !fir.ref<!fir.array<10x10x10xi32>>, !fir.array<10x10x10xi32>) map_clauses(implicit, tofrom) capture(ByRef) bounds({{.*}}) name("arr") -> !fir.ref<!fir.array<10x10x10xi32>>
-!CHECK:           %[[VAL_14:.*]] = omp.map.info var_ptr(%[[VAL_6]] : !fir.ref<i32>, i32) map_clauses(to) capture(ByCopy) -> !fir.ref<i32>
-!CHECK:           %[[VAL_15:.*]] = omp.map.info var_ptr(%[[VAL_5]] : !fir.ref<i32>, i32) map_clauses(to) capture(ByCopy) -> !fir.ref<i32>
+!CHECK:           %[[VAL_14:.*]] = omp.map.info var_ptr(%[[VAL_6]] : !fir.ref<i32>, i32) map_clauses(to) capture(ByCopy) name("xfpvx") -> !fir.ref<i32>
+!CHECK:           %[[VAL_15:.*]] = omp.map.info var_ptr(%[[VAL_5]] : !fir.ref<i32>, i32) map_clauses(to) capture(ByCopy) name("xdgfx") -> !fir.ref<i32>
 !CHECK:           omp.target kernel_type(spmd) host_eval({{.*}}) map_entries(%[[VAL_7]] -> %{{.*}}, %[[VAL_8]] -> %{{.*}}, %[[VAL_9]] -> %{{.*}}, %[[VAL_12]] -> %{{.*}}, %[[VAL_13]] -> %{{.*}}, %[[VAL_14]] -> %{{.*}}, %[[VAL_15]] -> %{{.*}}, %[[VAL_11]] -> %{{.*}} : {{.*}}) private(@[[SYM_XFPVX]] %[[VAL_6]] -> %{{.*}} [map_idx=5], @[[SYM_XDGFX]] %[[VAL_5]] -> %{{.*}} [map_idx=6] : {{.*}}) {
 !CHECK              omp.parallel private(@[[SYM_XFPVX]] %{{.*}} -> %{{.*}}, @[[SYM_XDGFX]] %{{.*}} -> %{{.*}}, @[[SYM_I]] %{{.*}} -> %{{.*}}, @[[SYM_J]] %{{.*}} -> %{{.*}}, @[[SYM_K]] %{{.*}} -> %{{.*}} : {{.*}}) {
   !$omp target teams distribute parallel do collapse(3) firstprivate(xfpvx)
diff --git a/flang/test/Lower/OpenMP/defaultmap.f90 b/flang/test/Lower/OpenMP/defaultmap.f90
index 6dca29434c34d..3f7c85f2c128a 100644
--- a/flang/test/Lower/OpenMP/defaultmap.f90
+++ b/flang/test/Lower/OpenMP/defaultmap.f90
@@ -56,7 +56,7 @@ subroutine defaultmap_pointer_to()
 ! CHECK-NO-FPRIV: %[[MAP_1:.*]] = omp.map.info var_ptr({{.*}} : !fir.ref<!fir.box<!fir.ptr<!fir.array<?xi32>>>>, !fir.box<!fir.ptr<!fir.array<?xi32>>>) map_clauses(implicit, to) capture(ByRef) var_ptr_ptr({{.*}}) bounds({{.*}}) name("") -> !fir.llvm_ptr<!fir.ref<!fir.array<?xi32>>>
 ! CHECK-FPRIV: %[[MAP_1:.*]] = omp.map.info var_ptr({{.*}} : !fir.ref<!fir.box<!fir.ptr<!fir.array<?xi32>>>>, !fir.box<!fir.ptr<!fir.array<?xi32>>>) map_clauses(implicit, to) capture(ByRef) var_ptr_ptr({{.*}}) bounds({{.*}}) name("") -> !fir.llvm_ptr<!fir.ref<!fir.array<?xi32>>>
 ! CHECK: %[[MAP_2:.*]] = omp.map.info var_ptr({{.*}} : !fir.ref<!fir.box<!fir.ptr<!fir.array<?xi32>>>>, !fir.box<!fir.ptr<!fir.array<?xi32>>>) map_clauses(always, implicit, to) capture(ByRef) members({{.*}}) name("arr_ptr") -> !fir.ref<!fir.box<!fir.ptr<!fir.array<?xi32>>>>
-! CHECK-FPRIV: %[[MAP_3:.*]] = omp.map.info var_ptr({{.*}} : !fir.ref<i32>, i32) map_clauses(to) capture(ByCopy) -> !fir.ref<i32>
+! CHECK-FPRIV: %[[MAP_3:.*]] = omp.map.info var_ptr({{.*}} : !fir.ref<i32>, i32) map_clauses(to) capture(ByCopy) name("scalar_int") -> !fir.ref<i32>
 ! CHECK-NO-FPRIV: %[[MAP_3:.*]] = omp.map.info var_ptr({{.*}} : !fir.ref<i32>, i32) map_clauses(implicit) capture(ByCopy) name("scalar_int") -> !fir.ref<i32>
     !$omp target defaultmap(to: pointer)
         arr_ptr(1) = scalar_int + 20
diff --git a/flang/test/Lower/OpenMP/optional-argument-map-2.f90 b/flang/test/Lower/OpenMP/optional-argument-map-2.f90
index ea49dd3a1ffe5..0c14fbc4f52aa 100644
--- a/flang/test/Lower/OpenMP/optional-argument-map-2.f90
+++ b/flang/test/Lower/OpenMP/optional-argument-map-2.f90
@@ -73,8 +73,8 @@ end module mod
 ! CHECK-FPRIV:     %[[VAL_14:.*]] = omp.map.bounds lower_bound(%[[VAL_10]] : index) upper_bound(%[[VAL_13]] : index) extent(%[[VAL_12]]#1 : index) stride(%[[VAL_11]] : index) start_idx(%[[VAL_10]] : index) stride_in_bytes(true)
 ! CHECK-FPRIV:     %[[VAL_16:.*]] = fir.box_offset %[[VAL_0]] base_addr : (!fir.ref<!fir.boxchar<1>>) -> !fir.llvm_ptr<!fir.ref<!fir.char<1,?>>>
 ! CHECK-FPRIV:     %[[VAL_17:.*]] = omp.map.info var_ptr(%[[VAL_0]] : !fir.ref<!fir.boxchar<1>>, !fir.boxchar<1>) map_clauses(tofrom) capture(ByRef) var_ptr_ptr(%[[VAL_16]] : !fir.llvm_ptr<!fir.ref<!fir.char<1,?>>>, !fir.char<1,?>) bounds(%[[VAL_14]]) name("") -> !fir.llvm_ptr<!fir.ref<!fir.char<1,?>>>
-! CHECK-FPRIV:     %[[VAL_18:.*]] = omp.map.info var_ptr(%[[VAL_0]] : !fir.ref<!fir.boxchar<1>>, !fir.boxchar<1>) map_clauses(always, to) capture(ByRef) members(%[[VAL_17]] : [0] : !fir.llvm_ptr<!fir.ref<!fir.char<1,?>>>) -> !fir.ref<!fir.boxchar<1>>
-! CHECK-FPRIV:     %[[VAL_20:.*]] = omp.map.info var_ptr(%[[VAL_0]] : !fir.ref<!fir.boxchar<1>>, !fir.boxchar<1>) map_clauses(attach, ref_ptr, ref_ptee) capture(ByRef) var_ptr_ptr(%[[VAL_16]] : !fir.llvm_ptr<!fir.ref<!fir.char<1,?>>>, !fir.char<1,?>) bounds(%[[VAL_14]]) -> !fir.ref<!fir.boxchar<1>>
+! CHECK-FPRIV:     %[[VAL_18:.*]] = omp.map.info var_ptr(%[[VAL_0]] : !fir.ref<!fir.boxchar<1>>, !fir.boxchar<1>) map_clauses(always, to) capture(ByRef) members(%[[VAL_17]] : [0] : !fir.llvm_ptr<!fir.ref<!fir.char<1,?>>>) name("a") -> !fir.ref<!fir.boxchar<1>>
+! CHECK-FPRIV:     %[[VAL_20:.*]] = omp.map.info var_ptr(%[[VAL_0]] : !fir.ref<!fir.boxchar<1>>, !fir.boxchar<1>) map_clauses(attach, ref_ptr, ref_ptee) capture(ByRef) var_ptr_ptr(%[[VAL_16]] : !fir.llvm_ptr<!fir.ref<!fir.char<1,?>>>, !fir.char<1,?>) bounds(%[[VAL_14]]) name("a") -> !fir.ref<!fir.boxchar<1>>
 ! CHECK-FPRIV:     omp.target kernel_type(generic) map_entries(%[[VAL_7]] -> %[[VAL_21:.*]], %[[VAL_18]] -> %[[VAL_22:.*]], [[VAL_20:.*]] -> %{{.*}}, %[[VAL_17]] -> %[[VAL_23:.*]] : !fir.ref<!fir.char<1,4>>, !fir.ref<!fir.boxchar<1>>, !fir.ref<!fir.boxchar<1>>, !fir.llvm_ptr<!fir.ref<!fir.char<1,?>>>) private(@_QMmodFroutine_boxcharEa_firstprivate_boxchar_c8xU %[[VAL_3]]#0 -> %[[VAL_24:.*]] [map_idx=1] : !fir.boxchar<1>) {
 ! CHECK-FPRIV:         %[[VAL_25:.*]] = arith.constant 4 : index
 ! CHECK-FPRIV:         %[[VAL_26:.*]]:2 = hlfir.declare %[[VAL_21]] typeparams %[[VAL_25]] {uniq_name = "_QMmodFroutine_boxcharEb"} : (!fir.ref<!fir.char<1,4>>, index) -> (!fir.ref<!fir.char<1,4>>, !fir.ref<!fir.char<1,4>>)
diff --git a/flang/test/Lower/OpenMP/target.f90 b/flang/test/Lower/OpenMP/target.f90
index 0dc8e4b9c885a..a79fdc6c74344 100644
--- a/flang/test/Lower/OpenMP/target.f90
+++ b/flang/test/Lower/OpenMP/target.f90
@@ -677,8 +677,8 @@ subroutine target_unstructured
    !CHECK-NO-FPRIV: %[[VAL_4:.*]] = omp.map.info var_ptr(%[[VAL_1]]#1 : !fir.ref<i32>, i32) map_clauses(implicit) capture(ByCopy) name("i") -> !fir.ref<i32>
    !CHECK-NO-FPRIV: %[[VAL_5:.*]] = omp.map.info var_ptr(%[[VAL_3]]#1 : !fir.ref<i32>, i32) map_clauses(implicit) capture(ByCopy) name("j") -> !fir.ref<i32>
    !CHECK-NO-FPRIV: omp.target kernel_type(generic) map_entries(%[[VAL_4]] -> %[[VAL_6:.*]], %[[VAL_5]] -> %[[VAL_7:.*]] : !fir.ref<i32>, !fir.ref<i32>) {
-   !CHECK-FPRIV: %[[VAL_4:.*]] = omp.map.info var_ptr(%[[VAL_1]]#0 : !fir.ref<i32>, i32) map_clauses(to) capture(ByCopy) -> !fir.ref<i32>
-   !CHECK-FPRIV: %[[VAL_5:.*]] = omp.map.info var_ptr(%[[VAL_3]]#0 : !fir.ref<i32>, i32) map_clauses(to) capture(ByCopy) -> !fir.ref<i32>
+   !CHECK-FPRIV: %[[VAL_4:.*]] = omp.map.info var_ptr(%[[VAL_1]]#0 : !fir.ref<i32>, i32) map_clauses(to) capture(ByCopy) name("i") -> !fir.ref<i32>
+   !CHECK-FPRIV: %[[VAL_5:.*]] = omp.map.info var_ptr(%[[VAL_3]]#0 : !fir.ref<i32>, i32) map_clauses(to) capture(ByCopy) name("j") -> !fir.ref<i32>
    !CHECK-FPRIV: omp.target kernel_type(generic) map_entries(%[[VAL_4]] -> %[[ARG_0:.*]], %[[VAL_5]] -> %[[ARG_1:.*]] : !fir.ref<i32>, !fir.ref<i32>) private(@{{.*}} %[[VAL_1]]#0 -> %[[ARG_2:.*]] [map_idx=0], @{{.*}} %[[VAL_3]]#0 -> %[[ARG_3:.*]] [map_idx=1] : !fir.ref<i32>, !fir.ref<i32>) {
    !$omp target
       !CHECK-FPRIV: %[[VAL_8:.*]]:2 = hlfir.declare %[[ARG_2]] {uniq_name = "_QFtarget_unstructuredEi"} : (!fir.ref<i32>) -> (!fir.ref<i32>, !fir.ref<i32>)
diff --git a/flang/test/Transforms/omp-maps-for-privatized-symbols.fir b/flang/test/Transforms/omp-maps-for-privatized-symbols.fir
index b780babd8ece6..6fdf1c783127a 100644
--- a/flang/test/Transforms/omp-maps-for-privatized-symbols.fir
+++ b/flang/test/Transforms/omp-maps-for-privatized-symbols.fir
@@ -32,8 +32,8 @@ module attributes {omp.is_target_device = false} {
   }
 }
 // CHECK: %[[MAP0:.*]] = omp.map.info var_ptr({{.*}} : !fir.ref<i32>, i32) map_clauses(to) capture(ByRef) name("a") -> !fir.ref<i32>
-// CHECK: %[[MAP1:.*]] = omp.map.info var_ptr({{.*}} : !fir.ref<!fir.box<!fir.heap<i32>>>, !fir.box<!fir.heap<i32>>) map_clauses(tofrom) capture(ByRef) -> !fir.ref<!fir.box<!fir.heap<i32>>>
-// CHECK: %[[MAP2:.*]] = omp.map.info var_ptr({{.*}} : !fir.ref<i32>, i32) map_clauses(to) capture(ByCopy) -> !fir.ref<i32>
+// CHECK: %[[MAP1:.*]] = omp.map.info var_ptr({{.*}} : !fir.ref<!fir.box<!fir.heap<i32>>>, !fir.box<!fir.heap<i32>>) map_clauses(tofrom) capture(ByRef) name("simple_var") -> !fir.ref<!fir.box<!fir.heap<i32>>>
+// CHECK: %[[MAP2:.*]] = omp.map.info var_ptr({{.*}} : !fir.ref<i32>, i32) map_clauses(to) capture(ByCopy) name("fp_int") -> !fir.ref<i32>
 // CHECK:  omp.target kernel_type(generic) map_entries(%[[MAP0]] -> %arg0, %[[MAP1]] -> %arg1, %[[MAP2]] -> %arg2 : !fir.ref<i32>, !fir.ref<!fir.box<!fir.heap<i32>>>, !fir.ref<i32>)
 
 // -----
@@ -54,7 +54,7 @@ module attributes {omp.is_target_device = false} {
   }
 }
 // CHECK: omp.declare_mapper @[[GEN_MAPPER:_QFTgen_t_omp_default_mapper]]
-// CHECK: %[[GEN_MAP:.*]] = omp.map.info var_ptr({{.*}} : !fir.ref<!fir.type<_QFTgen_t{{.*}}>>, !fir.type<_QFTgen_t{{.*}}>) map_clauses(tofrom) capture(ByRef) mapper(@[[GEN_MAPPER]]) -> !fir.ref<!fir.type<_QFTgen_t{{.*}}>>
+// CHECK: %[[GEN_MAP:.*]] = omp.map.info var_ptr({{.*}} : !fir.ref<!fir.type<_QFTgen_t{{.*}}>>, !fir.type<_QFTgen_t{{.*}}>) map_clauses(tofrom) capture(ByRef) mapper(@[[GEN_MAPPER]]) name("dt") -> !fir.ref<!fir.type<_QFTgen_t{{.*}}>>
 // CHECK: omp.target kernel_type(generic) map_entries(%[[GEN_MAP]] -> %arg0 : !fir.ref<!fir.type<_QFTgen_t{{.*}}>>)
 
 // -----
@@ -76,5 +76,5 @@ module attributes {omp.is_target_device = false} {
 }
 
 // CHECK-NOT: omp.declare_mapper @_QFTplain_t_omp_default_mapper
-// CHECK: %[[PLAIN_MAP:.*]] = omp.map.info var_ptr({{.*}} : !fir.ref<!fir.type<_QFTplain_t{{.*}}>>, !fir.type<_QFTplain_t{{.*}}>) map_clauses(tofrom) capture(ByRef) -> !fir.ref<!fir.type<_QFTplain_t{{.*}}>>
+// CHECK: %[[PLAIN_MAP:.*]] = omp.map.info var_ptr({{.*}} : !fir.ref<!fir.type<_QFTplain_t{{.*}}>>, !fir.type<_QFTplain_t{{.*}}>) map_clauses(tofrom) capture(ByRef) name("dt") -> !fir.ref<!fir.type<_QFTplain_t{{.*}}>>
 // CHECK-NOT: mapper(
diff --git a/mlir/include/mlir/Target/LLVMIR/Dialect/OpenMPCommon.h b/mlir/include/mlir/Target/LLVMIR/Dialect/OpenMPCommon.h
index 914c79c35cd59..7a957b45adc68 100644
--- a/mlir/include/mlir/Target/LLVMIR/Dialect/OpenMPCommon.h
+++ b/mlir/include/mlir/Target/LLVMIR/Dialect/OpenMPCommon.h
@@ -36,7 +36,8 @@ llvm::Constant *createSourceLocStrFromLocation(Location loc,
 /// Create a constant string representing the mapping information extracted from
 /// the MLIR location information.
 llvm::Constant *createMappingInformation(Location loc,
-                                         llvm::OpenMPIRBuilder &builder);
+                                         llvm::OpenMPIRBuilder &builder,
+                                         StringRef mapName = {});
 
 } // namespace LLVM
 } // namespace mlir
diff --git a/mlir/lib/Target/LLVMIR/Dialect/OpenMP/OpenMPToLLVMIRTranslation.cpp b/mlir/lib/Target/LLVMIR/Dialect/OpenMP/OpenMPToLLVMIRTranslation.cpp
index 530c1a260ddcc..92db96d2d5955 100644
--- a/mlir/lib/Target/LLVMIR/Dialect/OpenMP/OpenMPToLLVMIRTranslation.cpp
+++ b/mlir/lib/Target/LLVMIR/Dialect/OpenMP/OpenMPToLLVMIRTranslation.cpp
@@ -7406,6 +7406,12 @@ convertClauseMapFlags(omp::ClauseMapFlags mlirFlags) {
   return mapType;
 }
 
+static StringRef getMapClauseName(omp::MapInfoOp mapOp) {
+  if (StringAttr name = mapOp.getNameAttr())
+    return name.getValue();
+  return {};
+}
+
 static void collectMapDataFromMapOperands(
     MapInfoData &mapData, SmallVectorImpl<Value> &mapVars,
     LLVM::ModuleTranslation &moduleTranslation, DataLayout &dl,
@@ -7488,7 +7494,8 @@ static void collectMapDataFromMapOperands(
     // TODO: set HasAttachPtr from Flang for pointee-storage entries.
     mapData.HasAttachPtr.push_back(false);
     mapData.Names.push_back(LLVM::createMappingInformation(
-        mapOp.getLoc(), *moduleTranslation.getOpenMPBuilder()));
+        mapOp.getLoc(), *moduleTranslation.getOpenMPBuilder(),
+        getMapClauseName(mapOp)));
     mapData.DevicePointers.push_back(llvm::OpenMPIRBuilder::DeviceInfoTy::None);
     if (mapOp.getMapperId())
       mapData.Mappers.push_back(
@@ -7558,7 +7565,8 @@ static void collectMapDataFromMapOperands(
         // TODO: set HasAttachPtr from Flang for pointee-storage entries.
         mapData.HasAttachPtr.push_back(false);
         mapData.Names.push_back(LLVM::createMappingInformation(
-            mapOp.getLoc(), *moduleTranslation.getOpenMPBuilder()));
+            mapOp.getLoc(), *moduleTranslation.getOpenMPBuilder(),
+            getMapClauseName(mapOp)));
         mapData.DevicePointers.push_back(devInfoTy);
         mapData.Mappers.push_back(nullptr);
         mapData.IsAMapping.push_back(false);
@@ -7620,7 +7628,8 @@ static void collectMapDataFromMapOperands(
       mapData.Mappers.push_back(nullptr);
     }
     mapData.Names.push_back(LLVM::createMappingInformation(
-        mapOp.getLoc(), *moduleTranslation.getOpenMPBuilder()));
+        mapOp.getLoc(), *moduleTranslation.getOpenMPBuilder(),
+        getMapClauseName(mapOp)));
     mapData.DevicePointers.push_back(
         isDevicePtr ? llvm::OpenMPIRBuilder::DeviceInfoTy::Pointer
                     : llvm::OpenMPIRBuilder::DeviceInfoTy::Address);
@@ -8003,7 +8012,8 @@ static void mapParentWithMembers(
   combinedInfo.Mappers.emplace_back(
       parentMapper && !parentClause.getPartialMap() ? parentMapper : nullptr);
   combinedInfo.Names.emplace_back(LLVM::createMappingInformation(
-      mapData.MapClause[mapDataIndex]->getLoc(), ompBuilder));
+      mapData.MapClause[mapDataIndex]->getLoc(), ompBuilder,
+      getMapClauseName(cast<omp::MapInfoOp>(mapData.MapClause[mapDataIndex]))));
   combinedInfo.BasePointers.emplace_back(mapData.BasePointers[mapDataIndex]);
 
   // Calculate size of the parent object being mapped based on the
@@ -8100,7 +8110,9 @@ static void mapParentWithMembers(
       combinedInfo.DevicePointers.emplace_back(
           mapData.DevicePointers[mapDataIndex]);
       combinedInfo.Names.emplace_back(LLVM::createMappingInformation(
-          mapData.MapClause[mapDataIndex]->getLoc(), ompBuilder));
+          mapData.MapClause[mapDataIndex]->getLoc(), ompBuilder,
+          getMapClauseName(
+              cast<omp::MapInfoOp>(mapData.MapClause[mapDataIndex]))));
       combinedInfo.BasePointers.emplace_back(
           mapData.BasePointers[mapDataIndex]);
       combinedInfo.Pointers.emplace_back(mapData.Pointers[mapDataIndex]);
@@ -8142,7 +8154,9 @@ static void mapParentWithMembers(
         combinedInfo.DevicePointers.emplace_back(
             llvm::OpenMPIRBuilder::DeviceInfoTy::None);
         combinedInfo.Names.emplace_back(LLVM::createMappingInformation(
-            mapData.MapClause[mapDataIndex]->getLoc(), ompBuilder));
+            mapData.MapClause[mapDataIndex]->getLoc(), ompBuilder,
+            getMapClauseName(
+                cast<omp::MapInfoOp>(mapData.MapClause[mapDataIndex]))));
         combinedInfo.BasePointers.emplace_back(
             mapData.BasePointers[mapDataIndex]);
         combinedInfo.Mappers.emplace_back(nullptr);
@@ -8173,7 +8187,9 @@ static void mapParentWithMembers(
       combinedInfo.DevicePointers.emplace_back(
           llvm::OpenMPIRBuilder::DeviceInfoTy::None);
       combinedInfo.Names.emplace_back(LLVM::createMappingInformation(
-          mapData.MapClause[mapDataIndex]->getLoc(), ompBuilder));
+          mapData.MapClause[mapDataIndex]->getLoc(), ompBuilder,
+          getMapClauseName(
+              cast<omp::MapInfoOp>(mapData.MapClause[mapDataIndex]))));
       combinedInfo.BasePointers.emplace_back(
           mapData.BasePointers[mapDataIndex]);
       combinedInfo.Mappers.emplace_back(nullptr);
diff --git a/mlir/lib/Target/LLVMIR/Dialect/OpenMPCommon.cpp b/mlir/lib/Target/LLVMIR/Dialect/OpenMPCommon.cpp
index 586b74751c3b7..f25793907aba1 100644
--- a/mlir/lib/Target/LLVMIR/Dialect/OpenMPCommon.cpp
+++ b/mlir/lib/Target/LLVMIR/Dialect/OpenMPCommon.cpp
@@ -32,13 +32,18 @@ llvm::Constant *mlir::LLVM::createSourceLocStrFromLocation(
 
 llvm::Constant *
 mlir::LLVM::createMappingInformation(Location loc,
-                                     llvm::OpenMPIRBuilder &builder) {
+                                     llvm::OpenMPIRBuilder &builder,
+                                     StringRef mapName) {
   uint32_t strLen;
+  Location childLoc = loc;
+  StringRef name = mapName;
   if (auto nameLoc = dyn_cast<NameLoc>(loc)) {
-    StringRef name = nameLoc.getName();
-    return createSourceLocStrFromLocation(nameLoc.getChildLoc(), builder, name,
-                                          strLen, /*forOffloadMap=*/true);
+    childLoc = nameLoc.getChildLoc();
+    if (name.empty())
+      name = nameLoc.getName();
   }
-  return createSourceLocStrFromLocation(loc, builder, "unknown", strLen,
+  if (name.empty())
+    name = "unknown";
+  return createSourceLocStrFromLocation(childLoc, builder, name, strLen,
                                         /*forOffloadMap=*/true);
 }
diff --git a/offload/test/offloading/fortran/target-firstprivate-info.f90 b/offload/test/offloading/fortran/target-firstprivate-info.f90
new file mode 100644
index 0000000000000..c10274efcf9cc
--- /dev/null
+++ b/offload/test/offloading/fortran/target-firstprivate-info.f90
@@ -0,0 +1,82 @@
+! REQUIRES: flang, amdgpu
+
+! RUN: %libomptarget-compile-fortran-generic
+! RUN: env LIBOMPTARGET_INFO=1 %libomptarget-run-generic 2>&1 | %fcheck-generic
+! RUN: %libomptarget-run-generic 2>&1 | %fcheck-generic --check-prefix=VALUE
+
+module fp_info_mod
+  type :: point
+    integer :: x
+    integer :: y
+  end type
+end module
+
+program target_firstprivate_info
+  use fp_info_mod
+  implicit none
+  integer :: factor, base, res
+  integer :: arr(4)
+  integer, allocatable :: pa(:)
+  character(len=4) :: cstr
+  type(point) :: p
+  factor = 7; base = 5; res = 0
+  arr = (/1, 2, 3, 4/)
+  p%x = 3; p%y = 4
+  allocate(pa(4)); pa = 1
+  cstr = "abcd"
+
+  ! 'factor' is explicitly privatized, 'base' is an implicit scalar capture.
+  !$omp target map(tofrom: res) firstprivate(factor)
+    res = factor + base
+  !$omp end target
+  print *, "res1 =", res
+
+  ! array firstprivate is boxed for privatization; its descriptor maps must
+  ! still report the source name.
+  !$omp target map(tofrom: res) firstprivate(arr)
+    res = arr(1) + arr(4)
+  !$omp end target
+  print *, "res2 =", res
+
+  ! derived-type firstprivate
+  !$omp target map(tofrom: res) firstprivate(p)
+    res = p%x + p%y
+  !$omp end target
+  print *, "res3 =", res
+
+  ! a fixed-size private array is not mapped, but a private allocatable maps its
+  ! descriptor (copy left unallocated/unused here) and must report its name.
+  !$omp target map(tofrom: res) private(pa)
+    res = 99
+  !$omp end target
+  print *, "res4 =", res
+
+  ! character firstprivate.
+  !$omp target map(tofrom: res) firstprivate(cstr)
+    res = ichar(cstr(1:1))
+  !$omp end target
+  print *, "res5 =", res
+  deallocate(pa)
+end program target_firstprivate_info
+
+! CHECK: Entering OpenMP kernel {{.*}} with 3 arguments:
+! CHECK-DAG: tofrom(res)[4]
+! CHECK-DAG: firstprivate(base)[4] (implicit)
+! CHECK-DAG: to(factor)[4]
+! Array firstprivate is boxed; the descriptor maps still name the variable.
+! CHECK: Entering OpenMP kernel {{.*}} with 5 arguments:
+! CHECK-DAG: to(arr)[48]
+! CHECK-DAG: attach(arr)[48]
+! CHECK: Entering OpenMP kernel {{.*}} with 2 arguments:
+! CHECK-DAG: tofrom(p)[8]
+! A private allocatable and a character firstprivate are named too.
+! CHECK: Entering OpenMP kernel {{.*}} with 5 arguments:
+! CHECK-DAG: to(pa)[48]
+! CHECK-DAG: attach(pa)[48]
+! CHECK: Entering OpenMP kernel {{.*}} with 2 arguments:
+! CHECK-DAG: to(cstr)[4]
+! VALUE: res1 = 12
+! VALUE: res2 = 5
+! VALUE: res3 = 7
+! VALUE: res4 = 99
+! VALUE: res5 = 97



More information about the llvm-commits mailing list