[flang-commits] [flang] e55c853 - [Flang][OpenMP] Extend omp requires detection in Bridge.cpp (#188106)
via flang-commits
flang-commits at lists.llvm.org
Wed Apr 1 10:48:13 PDT 2026
Author: agozillon
Date: 2026-04-01T19:48:07+02:00
New Revision: e55c85341d9f757021b4f31b910d2ad2175f7e6c
URL: https://github.com/llvm/llvm-project/commit/e55c85341d9f757021b4f31b910d2ad2175f7e6c
DIFF: https://github.com/llvm/llvm-project/commit/e55c85341d9f757021b4f31b910d2ad2175f7e6c.diff
LOG: [Flang][OpenMP] Extend omp requires detection in Bridge.cpp (#188106)
Currently, we do not check the module for requires directives, which
means we'll miss these and not set them on the OpenMP module.
Otherwise, due to the first come first serve method we currently check
the symbols, there is certain formats that would mean the compiler would
miss that a user had specified requires somewhere in the module. This is
partially but not fully avoided by the Semantics layer pushing the
requires on to the top most PFT symbol, as it is entirely possible to
create a legal Fortran program where you could have two or more of these
(e.g. module and main program in one file, standalone funcitons
intermixed with modules or main program). Some examples of this are
shown in the added Fortran test. This PR opts to resolve it by gathering
all of the relevant symbols and processing them.
Also removed gathering from BlockDataUnit as I don't think these symbols
ever get the requires applied.
Added:
flang/test/Lower/OpenMP/requires-usm.f90
Modified:
flang/lib/Lower/Bridge.cpp
Removed:
################################################################################
diff --git a/flang/lib/Lower/Bridge.cpp b/flang/lib/Lower/Bridge.cpp
index 5251e85d56c86..63867fab57678 100644
--- a/flang/lib/Lower/Bridge.cpp
+++ b/flang/lib/Lower/Bridge.cpp
@@ -494,7 +494,8 @@ class FirConverter : public Fortran::lower::AbstractConverter {
// - Define module variables and OpenMP/OpenACC declarative constructs so
// they are available before lowering any function that may use them.
bool hasMainProgram = false;
- const Fortran::semantics::Symbol *globalOmpRequiresSymbol = nullptr;
+ llvm::SmallVector<const Fortran::semantics::Symbol *>
+ globalOmpRequiresSymbols;
createBuilderOutsideOfFuncOpAndDo([&]() {
for (Fortran::lower::pft::Program::Units &u : pft.getUnits()) {
Fortran::common::visit(
@@ -503,8 +504,7 @@ class FirConverter : public Fortran::lower::AbstractConverter {
if (f.isMainProgram())
hasMainProgram = true;
declareFunction(f);
- if (!globalOmpRequiresSymbol)
- globalOmpRequiresSymbol = f.getScope().symbol();
+ globalOmpRequiresSymbols.push_back(f.getScope().symbol());
},
[&](Fortran::lower::pft::ModuleLikeUnit &m) {
lowerModuleDeclScope(m);
@@ -512,12 +512,15 @@ class FirConverter : public Fortran::lower::AbstractConverter {
m.containedUnitList)
if (auto *f =
std::get_if<Fortran::lower::pft::FunctionLikeUnit>(
- &unit))
+ &unit)) {
declareFunction(*f);
+ globalOmpRequiresSymbols.push_back(
+ f->getScope().symbol());
+ }
+ globalOmpRequiresSymbols.push_back(m.getScope().symbol());
},
[&](Fortran::lower::pft::BlockDataUnit &b) {
- if (!globalOmpRequiresSymbol)
- globalOmpRequiresSymbol = b.symTab.symbol();
+ globalOmpRequiresSymbols.push_back(b.symTab.symbol());
},
[&](Fortran::lower::pft::CompilerDirectiveUnit &d) {},
[&](Fortran::lower::pft::OpenACCDirectiveUnit &d) {},
@@ -567,7 +570,7 @@ class FirConverter : public Fortran::lower::AbstractConverter {
Fortran::common::LanguageFeature::Coarray));
});
- finalizeOpenMPLowering(globalOmpRequiresSymbol);
+ finalizeOpenMPLowering(globalOmpRequiresSymbols);
}
/// Declare a function.
@@ -7201,7 +7204,8 @@ class FirConverter : public Fortran::lower::AbstractConverter {
/// Performing OpenMP lowering actions that were deferred to the end of
/// lowering.
void finalizeOpenMPLowering(
- const Fortran::semantics::Symbol *globalOmpRequiresSymbol) {
+ llvm::SmallVectorImpl<const Fortran::semantics::Symbol *>
+ &globalOmpRequiresSymbol) {
if (!ompDeferredDeclareTarget.empty()) {
bool deferredDeviceFuncFound =
Fortran::lower::markOpenMPDeferredDeclareTargetFunctions(
@@ -7210,9 +7214,10 @@ class FirConverter : public Fortran::lower::AbstractConverter {
}
// Set the module attribute related to OpenMP requires directives
- if (ompDeviceCodeFound)
- Fortran::lower::genOpenMPRequires(getModuleOp().getOperation(),
- globalOmpRequiresSymbol);
+ if (ompDeviceCodeFound) {
+ for (const Fortran::semantics::Symbol *sym : globalOmpRequiresSymbol)
+ Fortran::lower::genOpenMPRequires(getModuleOp().getOperation(), sym);
+ }
}
/// Record fir.dummy_scope operation for this function.
diff --git a/flang/test/Lower/OpenMP/requires-usm.f90 b/flang/test/Lower/OpenMP/requires-usm.f90
new file mode 100644
index 0000000000000..eb5b84cdba78c
--- /dev/null
+++ b/flang/test/Lower/OpenMP/requires-usm.f90
@@ -0,0 +1,56 @@
+! RUN: split-file %s %t
+
+! Verify that we pick up requires USM and apply it correctly when it is specified
+! outside of the program.
+
+! RUN: %flang_fc1 -emit-hlfir -fopenmp %t/requires-usm.f90 -o - | FileCheck %s
+! RUN: %flang_fc1 -emit-hlfir -fopenmp -fopenmp-is-target-device %t/requires-usm.f90 -o - | FileCheck %s
+! RUN: bbc -fopenmp -emit-hlfir %t/requires-usm.f90 -o - | FileCheck %s
+! RUN: bbc -fopenmp -fopenmp-is-target-device -emit-hlfir %t/requires-usm.f90 -o - | FileCheck %s
+! RUN: %flang_fc1 -emit-hlfir -fopenmp %t/requires-usm-subroutine-after.f90 -o - | FileCheck %s
+! RUN: %flang_fc1 -emit-hlfir -fopenmp -fopenmp-is-target-device %t/requires-usm-subroutine-after.f90 -o - | FileCheck %s
+! RUN: bbc -fopenmp -emit-hlfir %t/requires-usm-subroutine-after.f90 -o - | FileCheck %s
+! RUN: bbc -fopenmp -fopenmp-is-target-device -emit-hlfir %t/requires-usm-subroutine-after.f90 -o - | FileCheck %s
+! RUN: %flang_fc1 -emit-hlfir -fopenmp %t/requires-usm-program-after.f90 -o - | FileCheck %s
+! RUN: %flang_fc1 -emit-hlfir -fopenmp -fopenmp-is-target-device %t/requires-usm-program-after.f90 -o - | FileCheck %s
+! RUN: bbc -fopenmp -emit-hlfir %t/requires-usm-program-after.f90 -o - | FileCheck %s
+! RUN: bbc -fopenmp -fopenmp-is-target-device -emit-hlfir %t/requires-usm-program-after.f90 -o - | FileCheck %s
+
+! CHECK: module attributes {
+! CHECK-SAME: omp.requires = #omp<clause_requires unified_shared_memory>
+
+!--- requires-usm.f90
+module declare_mod
+ implicit none
+!$omp requires unified_shared_memory
+ contains
+end module
+
+program main
+ use declare_mod
+ implicit none
+!$omp target
+!$omp end target
+end program
+
+!--- requires-usm-subroutine-after.f90
+program main
+ implicit none
+end program main
+
+subroutine test
+ !$omp requires unified_shared_memory
+!$omp target
+!$omp end target
+end subroutine
+
+!--- requires-usm-program-after.f90
+subroutine test
+end subroutine
+
+program main
+ implicit none
+!$omp requires unified_shared_memory
+!$omp target
+!$omp end target
+end program main
More information about the flang-commits
mailing list