[flang-commits] [flang] [flang][openmp] Support importing module declare target globals (PR #213930)
via flang-commits
flang-commits at lists.llvm.org
Tue Aug 4 06:10:27 PDT 2026
llvmorg-github-actions[bot] wrote:
<!--LLVM PR SUMMARY COMMENT-->
@llvm/pr-subscribers-flang-openmp
Author: Ville-Markus Yli-Suutala (VeeEM)
<details>
<summary>Changes</summary>
Attach device type and capture clause attributes to declare target globals that have been imported from a module file.
Fixes https://github.com/llvm/llvm-project/issues/212333
---
Full diff: https://github.com/llvm/llvm-project/pull/213930.diff
4 Files Affected:
- (modified) flang/include/flang/Lower/OpenMP.h (+5)
- (modified) flang/lib/Lower/OpenMP/OpenMP.cpp (+50-10)
- (added) flang/test/Lower/OpenMP/declare_target_module.f90 (+37)
- (added) flang/test/Lower/OpenMP/declare_target_module.mod (+11)
``````````diff
diff --git a/flang/include/flang/Lower/OpenMP.h b/flang/include/flang/Lower/OpenMP.h
index a3f35498b9180..47f27ceece165 100644
--- a/flang/include/flang/Lower/OpenMP.h
+++ b/flang/include/flang/Lower/OpenMP.h
@@ -106,6 +106,11 @@ void materializeOpenMPDeclareMappers(
Fortran::lower::AbstractConverter &, Fortran::semantics::SemanticsContext &,
const Fortran::semantics::Scope *scope = nullptr);
+// Attach declare target attributes to declare target global variables
+// imported from a module file.
+void attachOpenMPDeclareTargetAttributes(lower::AbstractConverter &converter,
+ const lower::pft::Variable &var);
+
namespace omp {
/// If \p base carries OpenMP DECLARE VARIANT entries, return the variant symbol
/// that best matches the enclosing OpenMP context, or nullptr if none matches.
diff --git a/flang/lib/Lower/OpenMP/OpenMP.cpp b/flang/lib/Lower/OpenMP/OpenMP.cpp
index ae1eb897c9348..9eab03e2a1884 100644
--- a/flang/lib/Lower/OpenMP/OpenMP.cpp
+++ b/flang/lib/Lower/OpenMP/OpenMP.cpp
@@ -6846,8 +6846,12 @@ void Fortran::lower::genOpenMPSymbolProperties(
if (sym.test(semantics::Symbol::Flag::OmpThreadprivate))
lower::genThreadprivateOp(converter, var);
- if (sym.test(semantics::Symbol::Flag::OmpDeclareTarget))
- lower::genDeclareTargetIntGlobal(converter, var);
+ if (sym.test(semantics::Symbol::Flag::OmpDeclareTarget)) {
+ if (var.isGlobal())
+ lower::attachOpenMPDeclareTargetAttributes(converter, var);
+ else
+ lower::genDeclareTargetIntGlobal(converter, var);
+ }
}
void Fortran::lower::genGroupprivateOp(lower::AbstractConverter &converter,
@@ -6947,14 +6951,12 @@ void Fortran::lower::genThreadprivateOp(lower::AbstractConverter &converter,
// generation.
void Fortran::lower::genDeclareTargetIntGlobal(
lower::AbstractConverter &converter, const lower::pft::Variable &var) {
- if (!var.isGlobal()) {
- // A non-global variable which can be in a declare target directive must
- // be a variable in the main program, and it has the implicit SAVE
- // attribute. We create a GlobalOp for it to simplify the translation to
- // LLVM IR.
- globalInitialization(converter, converter.getFirOpBuilder(),
- var.getSymbol(), var, converter.getCurrentLocation());
- }
+ // A non-global variable which can be in a declare target directive must
+ // be a variable in the main program, and it has the implicit SAVE
+ // attribute. We create a GlobalOp for it to simplify the translation to
+ // LLVM IR.
+ globalInitialization(converter, converter.getFirOpBuilder(), var.getSymbol(),
+ var, converter.getCurrentLocation());
}
bool Fortran::lower::isOpenMPTargetConstruct(
@@ -7109,3 +7111,41 @@ void Fortran::lower::materializeOpenMPDeclareMappers(
// Walk scopes and materialize omp.declare_reduction ops for user-defined
// operator reductions imported from modules (deleted: replaced by lazy,
// clause-driven materialization).
+
+void Fortran::lower::attachOpenMPDeclareTargetAttributes(
+ lower::AbstractConverter &converter, const lower::pft::Variable &var) {
+ auto module = converter.getModuleOp();
+
+ mlir::Operation *globalOp =
+ module.lookupSymbol(converter.mangleName(var.getSymbol()));
+
+ auto ultimateSymbol = var.getSymbol().GetUltimate();
+
+ if (globalOp && ultimateSymbol.IsFromModFile()) {
+ auto declareTargetOp =
+ llvm::dyn_cast<mlir::omp::DeclareTargetInterface>(globalOp);
+ Fortran::common::visit(
+ [&](const auto &details) {
+ if constexpr (std::is_base_of_v<semantics::WithOmpDeclarative,
+ std::decay_t<decltype(details)>>) {
+ mlir::omp::DeclareTargetCaptureClause clause;
+ mlir::omp::DeclareTargetDeviceType deviceType =
+ toMLIRDeclareTargetDeviceType(
+ details.ompDeclTargetDeviceType().value_or(
+ Fortran::common::OmpDeviceType::Any));
+
+ const llvm::omp::ClauseSet clauses = details.ompDeclTarget();
+
+ if (clauses.test(llvm::omp::Clause::OMPC_link))
+ clause = mlir::omp::DeclareTargetCaptureClause::link;
+ else if (clauses.test(llvm::omp::Clause::OMPC_to))
+ clause = mlir::omp::DeclareTargetCaptureClause::to;
+ else
+ clause = mlir::omp::DeclareTargetCaptureClause::enter;
+
+ declareTargetOp.setDeclareTarget(deviceType, clause, false);
+ }
+ },
+ ultimateSymbol.details());
+ }
+}
diff --git a/flang/test/Lower/OpenMP/declare_target_module.f90 b/flang/test/Lower/OpenMP/declare_target_module.f90
new file mode 100644
index 0000000000000..07a0b2d921e60
--- /dev/null
+++ b/flang/test/Lower/OpenMP/declare_target_module.f90
@@ -0,0 +1,37 @@
+!RUN: %flang_fc1 -emit-hlfir -fopenmp -fopenmp-version=52 -I%S %s -o - | FileCheck %s
+!RUN: rm use_declare_target_module.mod
+
+! declare_target_module source
+#if 0
+module declare_target_module
+ implicit none
+ integer, dimension(10) :: global_arr
+ !$omp declare target (global_arr)
+ real :: global_real
+ !$omp declare target link(global_real)
+ integer :: global_integer
+ !$omp declare target to(global_integer)
+ integer :: global_device_integer
+ !$omp declare target enter(global_device_integer) device_type(nohost)
+end module
+#endif
+
+module use_declare_target_module
+use declare_target_module
+implicit none
+contains
+subroutine s()
+ !$omp declare target
+ global_arr(1) = 1
+ global_real = 1.0
+ global_integer = 1
+end subroutine
+!CHECK-DAG: fir.global @_QMdeclare_target_moduleEglobal_arr {alignment = 64 : i64, omp.declare_target = #omp.declaretarget<device_type = (any), capture_clause = (enter), automap = false>} : !fir.array<10xi32>
+!CHECK-DAG: fir.global @_QMdeclare_target_moduleEglobal_real {omp.declare_target = #omp.declaretarget<device_type = (any), capture_clause = (link), automap = false>} : f32
+!CHECK-DAG: fir.global @_QMdeclare_target_moduleEglobal_integer {omp.declare_target = #omp.declaretarget<device_type = (any), capture_clause = (to), automap = false>} : i32
+subroutine device_s()
+ !$omp declare target enter(device_s) device_type(nohost)
+ global_device_integer = 1
+end subroutine
+!CHECK-DAG: fir.global @_QMdeclare_target_moduleEglobal_device_integer {omp.declare_target = #omp.declaretarget<device_type = (nohost), capture_clause = (enter), automap = false>} : i32
+end module
diff --git a/flang/test/Lower/OpenMP/declare_target_module.mod b/flang/test/Lower/OpenMP/declare_target_module.mod
new file mode 100644
index 0000000000000..eeb940ba425d0
--- /dev/null
+++ b/flang/test/Lower/OpenMP/declare_target_module.mod
@@ -0,0 +1,11 @@
+!mod$ v1 sum:24be1f891770838c
+module declare_target_module
+integer(4)::global_arr(1_8:10_8)
+real(4)::global_real
+integer(4)::global_integer
+integer(4)::global_device_integer
+!$omp declare target enter(global_arr)
+!$omp declare target link(global_real)
+!$omp declare target to(global_integer)
+!$omp declare target device_type(nohost) enter(global_device_integer)
+end
``````````
</details>
https://github.com/llvm/llvm-project/pull/213930
More information about the flang-commits
mailing list