[Flang][MLIR][OpenMP] Fix declare_target globals visibility#208188
Open
skatrak wants to merge 1 commit into
Open
[Flang][MLIR][OpenMP] Fix declare_target globals visibility#208188skatrak wants to merge 1 commit into
skatrak wants to merge 1 commit into
Conversation
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.
Member
Author
|
@llvm/pr-subscribers-flang-fir-hlfir @llvm/pr-subscribers-mlir Author: Sergio Afonso (skatrak) ChangesThis patch introduces various changes to the handling of
Fixes #195188, fixes #195468. Assisted-by: Claude Opus 4.8. Patch is 23.43 KiB, truncated to 20.00 KiB below, full version: https://github.com/llvm/llvm-project/pull/208188.diff 5 Files Affected:
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...
[truncated]
|
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment
Add this suggestion to a batch that can be applied as a single commit.This suggestion is invalid because no changes were made to the code.Suggestions cannot be applied while the pull request is closed.Suggestions cannot be applied while viewing a subset of changes.Only one suggestion per line can be applied in a batch.Add this suggestion to a batch that can be applied as a single commit.Applying suggestions on deleted lines is not supported.You must change the existing code in this line in order to create a valid suggestion.Outdated suggestions cannot be applied.This suggestion has been applied or marked resolved.Suggestions cannot be applied from pending reviews.Suggestions cannot be applied on multi-line comments.Suggestions cannot be applied while the pull request is queued to merge.Suggestion cannot be applied right now. Please check back later.
This patch introduces various changes to the handling of
declare_targetglobal variables in Flang:declare_targetglobals 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.declare_target enter(...).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.