[flang-commits] [flang] 015162d - [Flang][MLIR][OpenMP] Fix declare_target globals visibility (#208188)

via flang-commits flang-commits at lists.llvm.org
Thu Jul 9 03:55:09 PDT 2026


Author: Sergio Afonso
Date: 2026-07-09T11:55:03+01:00
New Revision: 015162dacdd5f0752cea50fc400d454a15b6afbe

URL: https://github.com/llvm/llvm-project/commit/015162dacdd5f0752cea50fc400d454a15b6afbe
DIFF: https://github.com/llvm/llvm-project/commit/015162dacdd5f0752cea50fc400d454a15b6afbe.diff

LOG: [Flang][MLIR][OpenMP] Fix declare_target globals visibility (#208188)

This patch introduces various changes to the handling of
`declare_target` global variables in Flang:
- Non-`declare_target` globals are unconditionally made "internal" when
compiling for an OpenMP offload target. This prevents potential symbol
redefinition issues related to globals that don't actually exist on the
device.
- Local SAVE variables handling for OpenMP offloading programs is fixed
to prevent their associated "internal" linkage from producing broken
device code for `declare_target enter(...)`.
- When globals are indirectly accessed from the target device (e.g.
`declare_target link(...)`), the associated and unused full-storage
global is marked with "internal" linkage to facilitate later removal.
- `declare_target device_type(host) enter(...)` variables are set to
external linkage when compiling for a target device, causing linker
errors if accessed. This mirrors Clang's behavior.

Fixes #195188, fixes #195468.

Assisted-by: Claude Opus 4.8.

Added: 
    mlir/test/Target/LLVMIR/omptarget-declare-target-all-device-types-device.mlir

Modified: 
    flang/lib/Optimizer/OpenMP/HostOpFiltering.cpp
    flang/test/Transforms/OpenMP/function-filtering-host-ops.mlir
    mlir/lib/Target/LLVMIR/Dialect/OpenMP/OpenMPToLLVMIRTranslation.cpp
    mlir/test/Target/LLVMIR/omptarget-declare-target-llvm-device.mlir

Removed: 
    


################################################################################
diff  --git a/flang/lib/Optimizer/OpenMP/HostOpFiltering.cpp b/flang/lib/Optimizer/OpenMP/HostOpFiltering.cpp
index e42e10a82e6c2..05ea0bc08c4ab 100644
--- a/flang/lib/Optimizer/OpenMP/HostOpFiltering.cpp
+++ b/flang/lib/Optimizer/OpenMP/HostOpFiltering.cpp
@@ -65,6 +65,15 @@ static void collectRewrite(Value value, llvm::SetVector<Value> &rewrites) {
   rewrites.insert(value);
 }
 
+/// Provide the `device_type` of an `omp.declare_target` attribute, if defined.
+static std::optional<omp::DeclareTargetDeviceType>
+getDeclareTargetDevice(Operation &op) {
+  auto declareTargetOp = dyn_cast<omp::DeclareTargetInterface>(op);
+  if (declareTargetOp && declareTargetOp.isDeclareTarget())
+    return declareTargetOp.getDeclareTargetDeviceType();
+  return std::nullopt;
+}
+
 namespace {
 class HostOpFilteringPass
     : public flangomp::impl::HostOpFilteringPassBase<HostOpFilteringPass> {
@@ -78,11 +87,8 @@ class HostOpFilteringPass
 
     op->walk<WalkOrder::PreOrder>([&](func::FuncOp funcOp) {
       omp::DeclareTargetDeviceType declareType =
-          omp::DeclareTargetDeviceType::host;
-      auto declareTargetOp =
-          dyn_cast<omp::DeclareTargetInterface>(funcOp.getOperation());
-      if (declareTargetOp && declareTargetOp.isDeclareTarget())
-        declareType = declareTargetOp.getDeclareTargetDeviceType();
+          getDeclareTargetDevice(*funcOp.getOperation())
+              .value_or(omp::DeclareTargetDeviceType::host);
 
       // Only process host function definitions.
       if (funcOp.isExternal() ||
@@ -95,6 +101,15 @@ class HostOpFilteringPass
       }
       return WalkResult::advance();
     });
+
+    // Make non-declare target globals internal for the device. They cannot be
+    // deleted, because they are needed in order to properly lower map clauses.
+    // However, no uses will remain in the device module, so we make them
+    // internal to prevent link time issues.
+    op->walk([&](fir::GlobalOp globalOp) {
+      if (!getDeclareTargetDevice(*globalOp.getOperation()).has_value())
+        globalOp.setLinkName("internal");
+    });
   }
 
 private:

diff  --git a/flang/test/Transforms/OpenMP/function-filtering-host-ops.mlir b/flang/test/Transforms/OpenMP/function-filtering-host-ops.mlir
index f3b15bd028bc4..3acdfda876812 100644
--- a/flang/test/Transforms/OpenMP/function-filtering-host-ops.mlir
+++ b/flang/test/Transforms/OpenMP/function-filtering-host-ops.mlir
@@ -523,10 +523,6 @@ module attributes {omp.is_target_device = true} {
   }
 
   func.func private @foo() -> () attributes {omp.declare_target = #omp.declaretarget<device_type = (any), capture_clause = (enter)>}
-  fir.global internal @global_scalar constant : i32 {
-    %0 = arith.constant 10 : i32
-    fir.has_value %0 : i32
-  }
   omp.private {type = firstprivate} @privatizer : i32 copy {
   ^bb0(%arg0: !fir.ref<i32>, %arg1: !fir.ref<i32>):
     %0 = fir.load %arg0 : !fir.ref<i32>
@@ -544,4 +540,21 @@ module attributes {omp.is_target_device = true} {
     %1 = arith.addi %arg0, %arg1 : i32
     omp.yield (%1 : i32)
   }
+
+  // CHECK: fir.global internal @global_scalar constant : i32
+  fir.global @global_scalar constant : i32
+
+  // CHECK: fir.global @declare_target_enter_any {omp.declare_target = #omp.declaretarget<device_type = (any), capture_clause = (enter), automap = false>} : i32
+  // CHECK: fir.global @declare_target_enter_host {omp.declare_target = #omp.declaretarget<device_type = (host), capture_clause = (enter), automap = false>} : i32
+  // CHECK: fir.global @declare_target_enter_nohost {omp.declare_target = #omp.declaretarget<device_type = (nohost), capture_clause = (enter), automap = false>} : i32
+  fir.global @declare_target_enter_any {omp.declare_target = #omp.declaretarget<device_type = (any), capture_clause = (enter), automap = false>} : i32
+  fir.global @declare_target_enter_host {omp.declare_target = #omp.declaretarget<device_type = (host), capture_clause = (enter), automap = false>} : i32
+  fir.global @declare_target_enter_nohost {omp.declare_target = #omp.declaretarget<device_type = (nohost), capture_clause = (enter), automap = false>} : i32
+
+  // CHECK: fir.global @declare_target_link_any {omp.declare_target = #omp.declaretarget<device_type = (any), capture_clause = (link), automap = false>} : i32
+  // CHECK: fir.global @declare_target_link_host {omp.declare_target = #omp.declaretarget<device_type = (host), capture_clause = (link), automap = false>} : i32
+  // CHECK: fir.global @declare_target_link_nohost {omp.declare_target = #omp.declaretarget<device_type = (nohost), capture_clause = (link), automap = false>} : i32
+  fir.global @declare_target_link_any {omp.declare_target = #omp.declaretarget<device_type = (any), capture_clause = (link), automap = false>} : i32
+  fir.global @declare_target_link_host {omp.declare_target = #omp.declaretarget<device_type = (host), capture_clause = (link), automap = false>} : i32
+  fir.global @declare_target_link_nohost {omp.declare_target = #omp.declaretarget<device_type = (nohost), capture_clause = (link), automap = false>} : i32
 }

diff  --git a/mlir/lib/Target/LLVMIR/Dialect/OpenMP/OpenMPToLLVMIRTranslation.cpp b/mlir/lib/Target/LLVMIR/Dialect/OpenMP/OpenMPToLLVMIRTranslation.cpp
index 4574b20ce27fd..b2d2ef6d8f770 100644
--- a/mlir/lib/Target/LLVMIR/Dialect/OpenMP/OpenMPToLLVMIRTranslation.cpp
+++ b/mlir/lib/Target/LLVMIR/Dialect/OpenMP/OpenMPToLLVMIRTranslation.cpp
@@ -8843,14 +8843,16 @@ convertDeclareTargetAttr(Operation *op, mlir::omp::DeclareTargetAttr attribute,
   if (LLVM::GlobalOp gOp = dyn_cast<LLVM::GlobalOp>(op)) {
     llvm::Module *llvmModule = moduleTranslation.getLLVMModule();
     if (auto *gVal = llvmModule->getNamedValue(gOp.getSymName())) {
+      auto *gVar = cast<llvm::GlobalVariable>(gVal);
       llvm::OpenMPIRBuilder *ompBuilder = moduleTranslation.getOpenMPBuilder();
       bool isDeclaration = gOp.isDeclaration();
       bool isExternallyVisible =
           gOp.getVisibility() != mlir::SymbolTable::Visibility::Private;
       auto loc = op->getLoc()->findInstanceOf<FileLineColLoc>();
       llvm::StringRef mangledName = gOp.getSymName();
-      auto captureClause =
-          convertToCaptureClauseKind(attribute.getCaptureClause().getValue());
+      mlir::omp::DeclareTargetCaptureClause captureClause =
+          attribute.getCaptureClause().getValue();
+      auto captureClauseKind = convertToCaptureClauseKind(captureClause);
       auto deviceClause =
           convertToDeviceClauseKind(attribute.getDeviceType().getValue());
       // unused for MLIR at the moment, required in Clang for book
@@ -8877,31 +8879,64 @@ convertDeclareTargetAttr(Operation *op, mlir::omp::DeclareTargetAttr attribute,
                                                      lineNo);
       };
 
-      llvm::vfs::FileSystem &vfs = moduleTranslation.getFileSystem();
+      bool requiresUSM = ompBuilder->Config.hasRequiresUnifiedSharedMemory();
+      bool isToOrEnter =
+          captureClause == omp::DeclareTargetCaptureClause::to ||
+          captureClause == omp::DeclareTargetCaptureClause::enter;
+      bool isHostOnly = attribute.getDeviceType().getValue() ==
+                        omp::DeclareTargetDeviceType::host;
+
+      // A to/enter declare-target variable needs a device-resident,
+      // name-resolvable copy and a host offloading entry. A local-linkage
+      // global provides neither, so we promote it to external.
+      if (isToOrEnter && !isHostOnly && !requiresUSM &&
+          gVar->hasLocalLinkage()) {
+        gVar->setLinkage(llvm::GlobalValue::ExternalLinkage);
+        isExternallyVisible = true;
+
+        // Clear the stale dso_local flag so it is referenced like a
+        // module-scope declare target global.
+        if (ompBuilder->Config.isTargetDevice())
+          gVar->setDSOLocal(false);
+      }
 
+      llvm::vfs::FileSystem &vfs = moduleTranslation.getFileSystem();
       ompBuilder->registerTargetGlobalVariable(
-          captureClause, deviceClause, isDeclaration, isExternallyVisible,
+          captureClauseKind, deviceClause, isDeclaration, isExternallyVisible,
           ompBuilder->getTargetEntryUniqueInfo(fileInfoCallBack, vfs),
           mangledName, generatedRefs, /*OpenMPSimd*/ false, targetTriple,
           /*GlobalInitializer*/ nullptr, /*VariableLinkage*/ nullptr,
           gVal->getType(), gVal);
 
-      bool requiresUSM = ompBuilder->Config.hasRequiresUnifiedSharedMemory();
       if (ompBuilder->Config.isTargetDevice() &&
-          (attribute.getCaptureClause().getValue() ==
-               mlir::omp::DeclareTargetCaptureClause::link ||
+          (captureClause == omp::DeclareTargetCaptureClause::link ||
            requiresUSM)) {
         llvm::Type *ptrTy = gVal->getType();
         // For USM the global type becomes a pointer handle, as opposed to the
         // globals original type.
         if (requiresUSM)
           ptrTy = llvm::PointerType::get(llvmModule->getContext(), 0);
-        ompBuilder->getAddrOfDeclareTargetVar(
-            captureClause, deviceClause, isDeclaration, isExternallyVisible,
+        bool addrGlobalCreated = ompBuilder->getAddrOfDeclareTargetVar(
+            captureClauseKind, deviceClause, isDeclaration, isExternallyVisible,
             ompBuilder->getTargetEntryUniqueInfo(fileInfoCallBack, vfs),
             mangledName, generatedRefs, /*OpenMPSimd*/ false, targetTriple,
             ptrTy, /*GlobalInitializer*/ nullptr,
             /*VariableLinkage*/ nullptr);
+
+        // For indirectly-accessed global pointers, we rely on "internal"
+        // linkage to optimize out the unneeded full-variable storage later,
+        // since we can't prevent the LLVM dialect from generating globals
+        // without also breaking target lowering.
+        if (addrGlobalCreated)
+          gVar->setLinkage(llvm::GlobalValue::InternalLinkage);
+      }
+
+      // Mark 'device_type(host) enter(...)' variables as external in the device
+      // since they're not supposed to have their own copy. This will cause
+      // linker errors if accesses are attempted from the target device.
+      if (ompBuilder->Config.isTargetDevice() && isHostOnly && isToOrEnter) {
+        gVar->setLinkage(llvm::GlobalValue::ExternalLinkage);
+        gVar->setInitializer(nullptr);
       }
     }
   }

diff  --git a/mlir/test/Target/LLVMIR/omptarget-declare-target-all-device-types-device.mlir b/mlir/test/Target/LLVMIR/omptarget-declare-target-all-device-types-device.mlir
new file mode 100644
index 0000000000000..2cd3fc3c44231
--- /dev/null
+++ b/mlir/test/Target/LLVMIR/omptarget-declare-target-all-device-types-device.mlir
@@ -0,0 +1,252 @@
+// RUN: mlir-translate -mlir-to-llvmir %s | FileCheck %s
+
+// Tests lowering to LLVM IR of all combinations of OpenMP declare target
+// device_type (any/host/nohost) and capture clause (link/enter) when compiling
+// for device, for both external and internal linkage global variables.
+
+module attributes {llvm.target_triple = "amdgcn-amd-amdhsa", omp.is_gpu = true, omp.is_target_device = true} {
+  // --- link any ---
+
+  // CHECK-DAG: @ial = internal global float 0.000000e+00
+  // CHECK-DAG: @ial_decl_tgt_ref_ptr = weak global ptr null, align 8
+  llvm.mlir.global internal @ial() {addr_space = 0 : i32, omp.declare_target = #omp.declaretarget<device_type = (any), capture_clause = (link)>} : f32 {
+    %0 = llvm.mlir.zero : f32
+    llvm.return %0 : f32
+  }
+
+  // CHECK-DAG: @eal = internal global float 0.000000e+00
+  // CHECK-DAG: @eal_decl_tgt_ref_ptr = weak global ptr null, align 8
+  llvm.mlir.global external @eal() {addr_space = 0 : i32, dso_local, omp.declare_target = #omp.declaretarget<device_type = (any), capture_clause = (link)>} : f32 {
+    %0 = llvm.mlir.zero : f32
+    llvm.return %0 : f32
+  }
+
+  // --- link host ---
+
+  // CHECK-DAG: @ihl = internal global float 0.000000e+00
+  // CHECK-DAG: @ihl_decl_tgt_ref_ptr = weak global ptr null, align 8
+  llvm.mlir.global internal @ihl() {addr_space = 0 : i32, omp.declare_target = #omp.declaretarget<device_type = (host), capture_clause = (link)>} : f32 {
+    %0 = llvm.mlir.zero : f32
+    llvm.return %0 : f32
+  }
+
+  // CHECK-DAG: @ehl = internal global float 0.000000e+00
+  // CHECK-DAG: @ehl_decl_tgt_ref_ptr = weak global ptr null, align 8
+  llvm.mlir.global external @ehl() {addr_space = 0 : i32, dso_local, omp.declare_target = #omp.declaretarget<device_type = (host), capture_clause = (link)>} : f32 {
+    %0 = llvm.mlir.zero : f32
+    llvm.return %0 : f32
+  }
+
+  // --- link nohost ---
+
+  // CHECK-DAG: @inl = internal global float 0.000000e+00
+  // CHECK-DAG: @inl_decl_tgt_ref_ptr = weak global ptr null, align 8
+  llvm.mlir.global internal @inl() {addr_space = 0 : i32, omp.declare_target = #omp.declaretarget<device_type = (nohost), capture_clause = (link)>} : f32 {
+    %0 = llvm.mlir.zero : f32
+    llvm.return %0 : f32
+  }
+
+  // CHECK-DAG: @enl = internal global float 0.000000e+00
+  // CHECK-DAG: @enl_decl_tgt_ref_ptr = weak global ptr null, align 8
+  llvm.mlir.global external @enl() {addr_space = 0 : i32, dso_local, omp.declare_target = #omp.declaretarget<device_type = (nohost), capture_clause = (link)>} : f32 {
+    %0 = llvm.mlir.zero : f32
+    llvm.return %0 : f32
+  }
+
+  // --- enter any ---
+
+  // CHECK-DAG: @iae = global float 0.000000e+00
+  llvm.mlir.global internal @iae() {addr_space = 0 : i32, omp.declare_target = #omp.declaretarget<device_type = (any), capture_clause = (enter)>} : f32 {
+    %0 = llvm.mlir.zero : f32
+    llvm.return %0 : f32
+  }
+
+  // CHECK-DAG: @eae = dso_local global float 0.000000e+00
+  llvm.mlir.global external @eae() {addr_space = 0 : i32, dso_local, omp.declare_target = #omp.declaretarget<device_type = (any), capture_clause = (enter)>} : f32 {
+    %0 = llvm.mlir.zero : f32
+    llvm.return %0 : f32
+  }
+
+  // --- enter host ---
+
+  // CHECK-DAG: @ihe = external dso_local global float
+  llvm.mlir.global internal @ihe() {addr_space = 0 : i32, omp.declare_target = #omp.declaretarget<device_type = (host), capture_clause = (enter)>} : f32 {
+    %0 = llvm.mlir.zero : f32
+    llvm.return %0 : f32
+  }
+
+  // CHECK-DAG: @ehe = external dso_local global float
+  llvm.mlir.global external @ehe() {addr_space = 0 : i32, dso_local, omp.declare_target = #omp.declaretarget<device_type = (host), capture_clause = (enter)>} : f32 {
+    %0 = llvm.mlir.zero : f32
+    llvm.return %0 : f32
+  }
+
+  // --- enter nohost ---
+
+  // CHECK-DAG: @ine = global float 0.000000e+00
+  llvm.mlir.global internal @ine() {addr_space = 0 : i32, omp.declare_target = #omp.declaretarget<device_type = (nohost), capture_clause = (enter)>} : f32 {
+    %0 = llvm.mlir.zero : f32
+    llvm.return %0 : f32
+  }
+
+  // CHECK-DAG: @ene = dso_local global float 0.000000e+00
+  llvm.mlir.global external @ene() {addr_space = 0 : i32, dso_local, omp.declare_target = #omp.declaretarget<device_type = (nohost), capture_clause = (enter)>} : f32 {
+    %0 = llvm.mlir.zero : f32
+    llvm.return %0 : f32
+  }
+
+  llvm.func @_QQmain() {
+    %0 = llvm.mlir.addressof @ial : !llvm.ptr
+    %1 = llvm.addrspacecast %0 : !llvm.ptr to !llvm.ptr
+    %2 = llvm.mlir.addressof @ihl : !llvm.ptr
+    %3 = llvm.addrspacecast %2 : !llvm.ptr to !llvm.ptr
+    %4 = llvm.mlir.addressof @inl : !llvm.ptr
+    %5 = llvm.addrspacecast %4 : !llvm.ptr to !llvm.ptr
+    %6 = llvm.mlir.addressof @iae : !llvm.ptr
+    %7 = llvm.addrspacecast %6 : !llvm.ptr to !llvm.ptr
+    %8 = llvm.mlir.addressof @ihe : !llvm.ptr
+    %9 = llvm.addrspacecast %8 : !llvm.ptr to !llvm.ptr
+    %10 = llvm.mlir.addressof @ine : !llvm.ptr
+    %11 = llvm.addrspacecast %10 : !llvm.ptr to !llvm.ptr
+    %12 = llvm.mlir.addressof @eal : !llvm.ptr
+    %13 = llvm.addrspacecast %12 : !llvm.ptr to !llvm.ptr
+    %14 = llvm.mlir.addressof @ehl : !llvm.ptr
+    %15 = llvm.addrspacecast %14 : !llvm.ptr to !llvm.ptr
+    %16 = llvm.mlir.addressof @enl : !llvm.ptr
+    %17 = llvm.addrspacecast %16 : !llvm.ptr to !llvm.ptr
+    %18 = llvm.mlir.addressof @eae : !llvm.ptr
+    %19 = llvm.addrspacecast %18 : !llvm.ptr to !llvm.ptr
+    %20 = llvm.mlir.addressof @ehe : !llvm.ptr
+    %21 = llvm.addrspacecast %20 : !llvm.ptr to !llvm.ptr
+    %22 = llvm.mlir.addressof @ene : !llvm.ptr
+    %23 = llvm.addrspacecast %22 : !llvm.ptr to !llvm.ptr
+
+    // CHECK-LABEL: define {{.*}} @__omp_offloading_{{.*}}_l{{[0-9]+}}(
+    // CHECK:         omp.target:
+    // CHECK:           %[[REF:.*]] = load ptr, ptr @ial_decl_tgt_ref_ptr, align 8
+    // CHECK:           store float 1.100000e+00, ptr %[[REF]], align 4
+    %map_ial = omp.map.info var_ptr(%1 : !llvm.ptr, f32) map_clauses(always, from) capture(ByRef) -> !llvm.ptr {name = "ial"}
+    omp.target kernel_type(generic) map_entries(%map_ial -> %arg0 : !llvm.ptr) {
+      %v = llvm.mlir.constant(1.100000e+00 : f32) : f32
+      llvm.store %v, %arg0 : f32, !llvm.ptr
+      omp.terminator
+    }
+
+    // CHECK-LABEL: define {{.*}} @__omp_offloading_{{.*}}_l{{[0-9]+}}(
+    // CHECK:         omp.target:
+    // CHECK:           %[[REF:.*]] = load ptr, ptr @eal_decl_tgt_ref_ptr, align 8
+    // CHECK:           store float 1.200000e+00, ptr %[[REF]], align 4
+    %map_eal = omp.map.info var_ptr(%13 : !llvm.ptr, f32) map_clauses(always, from) capture(ByRef) -> !llvm.ptr {name = "eal"}
+    omp.target kernel_type(generic) map_entries(%map_eal -> %arg0 : !llvm.ptr) {
+      %v = llvm.mlir.constant(1.200000e+00 : f32) : f32
+      llvm.store %v, %arg0 : f32, !llvm.ptr
+      omp.terminator
+    }
+
+    // CHECK-LABEL: define {{.*}} @__omp_offloading_{{.*}}_l{{[0-9]+}}(
+    // CHECK:         omp.target:
+    // CHECK:           %[[REF:.*]] = load ptr, ptr @ihl_decl_tgt_ref_ptr, align 8
+    // CHECK:           store float 2.100000e+00, ptr %[[REF]], align 4
+    %map_ihl = omp.map.info var_ptr(%3 : !llvm.ptr, f32) map_clauses(always, from) capture(ByRef) -> !llvm.ptr {name = "ihl"}
+    omp.target kernel_type(generic) map_entries(%map_ihl -> %arg0 : !llvm.ptr) {
+      %v = llvm.mlir.constant(2.100000e+00 : f32) : f32
+      llvm.store %v, %arg0 : f32, !llvm.ptr
+      omp.terminator
+    }
+
+    // CHECK-LABEL: define {{.*}} @__omp_offloading_{{.*}}_l{{[0-9]+}}(
+    // CHECK:         omp.target:
+    // CHECK:           %[[REF:.*]] = load ptr, ptr @ehl_decl_tgt_ref_ptr, align 8
+    // CHECK:           store float 2.200000e+00, ptr %[[REF]], align 4
+    %map_ehl = omp.map.info var_ptr(%15 : !llvm.ptr, f32) map_clauses(always, from) capture(ByRef) -> !llvm.ptr {name = "ehl"}
+    omp.target kernel_type(generic) map_entries(%map_ehl -> %arg0 : !llvm.ptr) {
+      %v = llvm.mlir.constant(2.200000e+00 : f32) : f32
+      llvm.store %v, %arg0 : f32, !llvm.ptr
+      omp.terminator
+    }
+
+    // CHECK-LABEL: define {{.*}} @__omp_offloading_{{.*}}_l{{[0-9]+}}(
+    // CHECK:         omp.target:
+    // CHECK:           %[[REF:.*]] = load ptr, ptr @inl_decl_tgt_ref_ptr, align 8
+    // CHECK:           store float 3.100000e+00, ptr %[[REF]], align 4
+    %map_inl = omp.map.info var_ptr(%5 : !llvm.ptr, f32) map_clauses(always, from) capture(ByRef) -> !llvm.ptr {name = "inl"}
+    omp.target kernel_type(generic) map_entries(%map_inl -> %arg0 : !llvm.ptr) {
+      %v = llvm.mlir.constant(3.100000e+00 : f32) : f32
+      llvm.store %v, %arg0 : f32, !llvm.ptr
+      omp.terminator
+    }
+
+    // CHECK-LABEL: define {{.*}} @__omp_offloading_{{.*}}_l{{[0-9]+}}(
+    // CHECK:         omp.target:
+    // CHECK:           %[[REF:.*]] = load ptr, ptr @enl_decl_tgt_ref_ptr, align 8
+    // CHECK:           store float 3.200000e+00, ptr %[[REF]], align 4
+    %map_enl = omp.map.info var_ptr(%17 : !llvm.ptr, f32) map_clauses(always, from) capture(ByRef) -> !llvm.ptr {name = "enl"}
+    omp.target kernel_type(generic) map_entries(%map_enl -> %arg0 : !llvm.ptr) {
+      %v = llvm.mlir.constant(3.200000e+00 : f32) : f32
+      llvm.store %v, %arg0 : f32, !llvm.ptr
+      omp.terminator
+    }
+
+    // CHECK-LABEL: define {{.*}} @__omp_offloading_{{.*}}_l{{[0-9]+}}(
+    // CHECK:         omp.target:
+    // CHECK:           store float 4.100000e+00, ptr @iae, align 4
+    %map_iae = omp.map.info var_ptr(%7 : !llvm.ptr, f32) map_clauses(always, from) capture(ByRef) -> !llvm.ptr {name = "iae"}
+    omp.target kernel_type(generic) map_entries(%map_iae -> %arg0 : !llvm.ptr) {
+      %v = llvm.mlir.constant(4.100000e+00 : f32) : f32
+      llvm.store %v, %arg0 : f32, !llvm.ptr
+      omp.terminator
+    }
+
+    // CHECK-LABEL: define {{.*}} @__omp_offloading_{{.*}}_l{{[0-9]+}}(
+    // CHECK:         omp.target:
+    // CHECK:           store float 4.200000e+00, ptr @eae, align 4
+    %map_eae = omp.map.info var_ptr(%19 : !llvm.ptr, f32) map_clauses(always, from) capture(ByRef) -> !llvm.ptr {name = "eae"}
+    omp.target kernel_type(generic) map_entries(%map_eae -> %arg0 : !llvm.ptr) {
+      %v = llvm.mlir.constant(4.200000e+00 : f32) : f32
+      llvm.store %v, %arg0 : f32, !llvm.ptr
+      omp.terminator
+    }
+
+    // CHECK-LABEL: define {{.*}} @__omp_offloading_{{.*}}_l{{[0-9]+}}(
+    // CHECK:         omp.target:
+    // CHECK:           store float 5.100000e+00, ptr @ihe, align 4
+    %map_ihe = omp.map.info var_ptr(%9 : !llvm.ptr, f32) map_clauses(always, from) capture(ByRef) -> !llvm.ptr {name = "ihe"}
+    omp.target kernel_type(generic) map_entries(%map_ihe -> %arg0 : !llvm.ptr) {
+      %v = llvm.mlir.constant(5.100000e+00 : f32) : f32
+      llvm.store %v, %arg0 : f32, !llvm.ptr
+      omp.terminator
+    }
+
+    // CHECK-LABEL: define {{.*}} @__omp_offloading_{{.*}}_l{{[0-9]+}}(
+    // CHECK:         omp.target:
+    // CHECK:           store float 5.200000e+00, ptr @ehe, align 4
+    %map_ehe = omp.map.info var_ptr(%21 : !llvm.ptr, f32) map_clauses(always, from) capture(ByRef) -> !llvm.ptr {name = "ehe"}
+    omp.target kernel_type(generic) map_entries(%map_ehe -> %arg0 : !llvm.ptr) {
+      %v = llvm.mlir.constant(5.200000e+00 : f32) : f32
+      llvm.store %v, %arg0 : f32, !llvm.ptr
+      omp.terminator
+    }
+
+    // CHECK-LABEL: define {{.*}} @__omp_offloading_{{.*}}_l{{[0-9]+}}(
+    // CHECK:         omp.target:
+    // CHECK:           store float 6.100000e+00, ptr @ine, align 4
+    %map_ine = omp.map.info var_ptr(%11 : !llvm.ptr, f32) map_clauses(always, from) capture(ByRef) -> !llvm.ptr {name = "ine"}
+    omp.target kernel_type(generic) map_entries(%map_ine -> %arg0 : !llvm.ptr) {
+      %v = llvm.mlir.constant(6.100000e+00 : f32) : f32
+      llvm.store %v, %arg0 : f32, !llvm.ptr
+      omp.terminator
+    }
+
+    // CHECK-LABEL: define {{.*}} @__omp_offloading_{{.*}}_l{{[0-9]+}}(
+    // CHECK:         omp.target:
+    // CHECK:           store float 6.210000e+00, ptr @ene, align 4
+    %map_ene = omp.map.info var_ptr(%23 : !llvm.ptr, f32) map_clauses(always, from) capture(ByRef) -> !llvm.ptr {name = "ene"}
+    omp.target kernel_type(generic) map_entries(%map_ene -> %arg0 : !llvm.ptr) {
+      %v = llvm.mlir.constant(6.210000e+00 : f32) : f32
+      llvm.store %v, %arg0 : f32, !llvm.ptr
+      omp.terminator
+    }
+
+    llvm.return
+  }
+}

diff  --git a/mlir/test/Target/LLVMIR/omptarget-declare-target-llvm-device.mlir b/mlir/test/Target/LLVMIR/omptarget-declare-target-llvm-device.mlir
index bc59fdda2cc25..745ab424fb5f8 100644
--- a/mlir/test/Target/LLVMIR/omptarget-declare-target-llvm-device.mlir
+++ b/mlir/test/Target/LLVMIR/omptarget-declare-target-llvm-device.mlir
@@ -8,6 +8,7 @@
 // file created by the host and appended as an attribute to the module.
 
 module attributes {llvm.target_triple = "amdgcn-amd-amdhsa", omp.is_target_device = true} {
+  // CHECK-DAG: @_QMtest_0Esp = internal global i32
   // CHECK-DAG: @_QMtest_0Esp_decl_tgt_ref_ptr = weak global ptr null, align 8
   llvm.mlir.global external @_QMtest_0Esp() {addr_space = 0 : i32, omp.declare_target = #omp.declaretarget<device_type = (any), capture_clause = (link)>} : i32 {
     %0 = llvm.mlir.constant(0 : i32) : i32


        


More information about the flang-commits mailing list