[flang-commits] [flang] [flang][openmp] Support importing module declare target globals (PR #213930)

Ville-Markus Yli-Suutala via flang-commits flang-commits at lists.llvm.org
Sat Aug 8 10:22:28 PDT 2026


https://github.com/VeeEM updated https://github.com/llvm/llvm-project/pull/213930

>From 42601b434e87b4a12300e47ca4d583de51e95b0a Mon Sep 17 00:00:00 2001
From: Ville-Markus Yli-Suutala <ville-markus.yli-suutala at helsinki.fi>
Date: Mon, 3 Aug 2026 18:59:50 +0300
Subject: [PATCH 1/2] [flang][openmp] Write to clause symbols to modfile

Fix bug where the list of variables would be ignored when writing the to
clause of a declare target directive to a modfile.

to clauses are written into a modfile as enter clauses.
---
 flang/lib/Semantics/symbol.cpp                         | 9 +++++++--
 flang/test/Semantics/OpenMP/declare-target-modfile.f90 | 4 ++++
 2 files changed, 11 insertions(+), 2 deletions(-)

diff --git a/flang/lib/Semantics/symbol.cpp b/flang/lib/Semantics/symbol.cpp
index b802930326a6f..b3acd59b4a299 100644
--- a/flang/lib/Semantics/symbol.cpp
+++ b/flang/lib/Semantics/symbol.cpp
@@ -78,8 +78,13 @@ void WithOmpDeclarative::printClauseSet(llvm::raw_ostream &os,
   size_t idx{0}, size{clauses.count()};
 
   for (llvm::omp::Clause c : clauses) {
-    os << toLower(llvm::omp::getOpenMPClauseName(c, version_));
-    switch (c) {
+    llvm::omp::Clause clause = c;
+    // Write to as enter when writing a mod file
+    if (clause == llvm::omp::Clause::OMPC_to && !name.empty()) {
+      clause = llvm::omp::Clause::OMPC_enter;
+    }
+    os << toLower(llvm::omp::getOpenMPClauseName(clause, version_));
+    switch (clause) {
     case llvm::omp::Clause::OMPC_atomic_default_mem_order:
       os << '(' << toLower(EnumToString(*ompAtomicDefaultMemOrder())) << ')';
       break;
diff --git a/flang/test/Semantics/OpenMP/declare-target-modfile.f90 b/flang/test/Semantics/OpenMP/declare-target-modfile.f90
index 9a2f9a3026947..710c849ca61b4 100644
--- a/flang/test/Semantics/OpenMP/declare-target-modfile.f90
+++ b/flang/test/Semantics/OpenMP/declare-target-modfile.f90
@@ -3,6 +3,8 @@
 module m
 integer :: x
 !$omp declare_target link(x) device_type(nohost)
+integer :: y
+!$omp declare target to(y)
 real :: w(10), u(10)
 common /named_block/ w, u
 !$omp declare_target link(/named_block/)
@@ -28,6 +30,7 @@ subroutine h
 !Expect: m.mod
 !module m
 !integer(4)::x
+!integer(4)::y
 !real(4)::w(1_8:10_8)
 !real(4)::u(1_8:10_8)
 !interface
@@ -38,6 +41,7 @@ subroutine h
 !end interface
 !common/named_block/w,u
 !!$omp declare_target device_type(nohost) link(x)
+!!$omp declare_target enter(y)
 !!$omp declare_target enter(g)
 !!$omp declare_target enter(f)
 !!$omp declare_target enter(h)

>From 3b141686963701f1f9c626fb68db06c92896ec0c Mon Sep 17 00:00:00 2001
From: Ville-Markus Yli-Suutala <ville-markus.yli-suutala at helsinki.fi>
Date: Sat, 8 Aug 2026 20:21:24 +0300
Subject: [PATCH 2/2] [flang][openmp] Support importing module declare target
 globals

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
---
 flang/include/flang/Lower/OpenMP.h |  5 +++
 flang/lib/Lower/OpenMP/OpenMP.cpp  | 57 ++++++++++++++++++++++++------
 2 files changed, 52 insertions(+), 10 deletions(-)

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..b325493b73023 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,38 @@ 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::DeclareTargetDeviceType deviceType =
+                toMLIRDeclareTargetDeviceType(
+                    details.ompDeclTargetDeviceType().value_or(
+                        Fortran::common::OmpDeviceType::Any));
+
+            mlir::omp::DeclareTargetCaptureClause clause;
+            if (details.ompDeclTarget().test(llvm::omp::Clause::OMPC_link))
+              clause = mlir::omp::DeclareTargetCaptureClause::link;
+            else
+              clause = mlir::omp::DeclareTargetCaptureClause::enter;
+
+            declareTargetOp.setDeclareTarget(deviceType, clause,
+                                             /*automap=*/false);
+          }
+        },
+        ultimateSymbol.details());
+  }
+}



More information about the flang-commits mailing list