[Mlir-commits] [flang] [mlir] [flang][OpenMP] Support for "omp assumes absent" (PR #236693)
llvmlistbot at llvm.org
llvmlistbot at llvm.org
Thu Oct 29 01:47:21 PDT 2026
llvmorg-github-actions[bot] wrote:
<!--LLVM PR SUMMARY COMMENT-->
@llvm/pr-subscribers-mlir
@llvm/pr-subscribers-flang-openmp
Author: SunilKuravinakop
<details>
<summary>Changes</summary>
Support for "absent" clause in "assumes" directive.
---
Patch is 28.45 KiB, truncated to 20.00 KiB below, full version: https://github.com/llvm/llvm-project/pull/236693.diff
14 Files Affected:
- (modified) flang/docs/OpenMPSupport.md (+1-1)
- (modified) flang/include/flang/Semantics/scope.h (+9)
- (modified) flang/lib/Lower/Bridge.cpp (+29-12)
- (modified) flang/lib/Lower/OpenMP/OpenMP.cpp (+2-1)
- (modified) flang/lib/Semantics/mod-file.cpp (+9)
- (modified) flang/lib/Semantics/resolve-directives.cpp (+12-5)
- (modified) flang/lib/Semantics/resolve-names.cpp (+8)
- (modified) flang/test/Lower/OpenMP/Todo/assumes.f90 (+13-7)
- (renamed) flang/test/Lower/OpenMP/assumption-submodule.f90 (+11-1)
- (modified) flang/test/Lower/OpenMP/assumption.f90 (+150-10)
- (modified) flang/test/Parser/OpenMP/assumption.f90 (+21)
- (modified) flang/test/Semantics/OpenMP/declarative-directive01.f90 (+31)
- (modified) mlir/test/Conversion/FuncToLLVM/convert-funcs.mlir (+2-2)
- (modified) mlir/test/Target/LLVMIR/llvmir.mlir (+2-2)
``````````diff
diff --git a/flang/docs/OpenMPSupport.md b/flang/docs/OpenMPSupport.md
index 63c1c3b66ad0a2..fee2b324f51d3c 100644
--- a/flang/docs/OpenMPSupport.md
+++ b/flang/docs/OpenMPSupport.md
@@ -197,7 +197,7 @@ Parser/Semantics, MLIR, Lowering, or the OpenMPIRBuilder.
| nothing directive | <span class="good">done</span> | | Parser and lowering coverage exists for standalone and metadirective-selected forms (`flang/test/Parser/OpenMP/nothing.f90`, `flang/test/Lower/OpenMP/nothing.f90`, `flang/test/Lower/OpenMP/metadirective-nothing.f90`). | [llvm/llvm-project#193664](https://github.com/llvm/llvm-project/pull/193664), [llvm/llvm-project#202679](https://github.com/llvm/llvm-project/pull/202679) |
| tile and unroll constructs | <span class="part">partial</span> | | Semantics coverage exists across tile/unroll and loop-transformation tests (`flang/test/Semantics/OpenMP/tile01.f90`, `flang/test/Semantics/OpenMP/tile09.f90`, `flang/test/Semantics/OpenMP/loop-transformation-construct01.f90`), with additional lowering/transform completeness work ongoing. The `full` and `partial` clauses on `unroll` are lowered (`flang/test/Lower/OpenMP/unroll-full01.f90`, `flang/test/Lower/OpenMP/unroll-partial01.f90`). | [llvm/llvm-project#160298](https://github.com/llvm/llvm-project/pull/160298), [llvm/llvm-project#185296](https://github.com/llvm/llvm-project/pull/185296), [llvm/llvm-project#188025](https://github.com/llvm/llvm-project/pull/188025) |
| scope construct | <span class="part">partial</span> | | Scope construct support is available, with follow-on completeness work still in progress for some combinations (see also OpenMP 5.2 scope-related rows). | [llvm/llvm-project#113700](https://github.com/llvm/llvm-project/pull/113700), [llvm/llvm-project#193098](https://github.com/llvm/llvm-project/pull/193098) |
-| assumes directives | <span class="part">partial</span> | | `no_openmp` is supported. For OpenMP 5.2 and earlier, module-level assumptions are preserved in module files for separately compiled submodules. Other clauses remain TODO-tracked (`flang/test/Lower/OpenMP/assumption.f90`, `flang/test/Lower/OpenMP/Todo/assumes.f90`). | [llvm/llvm-project#102008](https://github.com/llvm/llvm-project/pull/102008) |
+| assumes directives | <span class="part">partial</span> | | `no_openmp` and `absent` are supported. Other clauses remain TODO-tracked (`flang/test/Lower/OpenMP/assumption.f90`, `flang/test/Lower/OpenMP/Todo/assumes.f90`). | [llvm/llvm-project#102008](https://github.com/llvm/llvm-project/pull/102008) |
| assume directive | <span class="none">unclaimed</span> | | Lowering still has explicit TODO (`flang/lib/Lower/OpenMP/OpenMP.cpp` TODO: `OpenMP ASSUME construct`; `flang/test/Lower/OpenMP/Todo/assume.f90`). | [llvm/llvm-project#102008](https://github.com/llvm/llvm-project/pull/102008) |
| default(firstprivate) | <span class="good">done</span> | | Supported for `default(firstprivate)` clause forms, with semantics and lowering coverage (`flang/test/Semantics/OpenMP/default-clause.f90`, `flang/test/Lower/OpenMP/default-clause.f90`, `flang/test/Lower/OpenMP/default-clause-byref.f90`). | [D123930](https://reviews.llvm.org/D123930) |
| default(private) | <span class="part">partial</span> | | Semantics/default-clause coverage exists (`flang/test/Semantics/OpenMP/default.f90`, `flang/test/Semantics/OpenMP/default02.f90`) with ongoing lowering completeness checks. | [llvm/llvm-project#107586](https://github.com/llvm/llvm-project/pull/107586) |
diff --git a/flang/include/flang/Semantics/scope.h b/flang/include/flang/Semantics/scope.h
index c3cb663dea2366..0536ec028dd81e 100644
--- a/flang/include/flang/Semantics/scope.h
+++ b/flang/include/flang/Semantics/scope.h
@@ -16,6 +16,7 @@
#include "flang/Parser/message.h"
#include "flang/Parser/provenance.h"
#include "flang/Support/Fortran.h"
+#include "llvm/Frontend/OpenMP/OMP.h"
#include <list>
#include <map>
#include <optional>
@@ -275,6 +276,13 @@ class Scope {
bool hasSAVE() const { return hasSAVE_; }
void set_hasSAVE(bool yes = true) { hasSAVE_ = yes; }
+ const std::set<llvm::omp::Directive> &ompAssumesAbsent() const {
+ return ompAssumesAbsent_;
+ }
+ void add_ompAssumesAbsent(llvm::omp::Directive directive) {
+ ompAssumesAbsent_.insert(directive);
+ }
+
// The range of the source of this and nested scopes.
const parser::CharBlock &sourceRange() const { return sourceRange_; }
void AddSourceRange(parser::CharBlock);
@@ -327,6 +335,7 @@ class Scope {
std::optional<ImportKind> importKind_;
std::set<SourceName> importNames_;
UnorderedSymbolSet openACCMappedSymbols_;
+ std::set<llvm::omp::Directive> ompAssumesAbsent_;
DerivedTypeSpec *derivedTypeSpec_{nullptr}; // dTS->scope() == this
parser::Message::Reference instantiationContext_;
bool hasSAVE_{false}; // scope has a bare SAVE statement
diff --git a/flang/lib/Lower/Bridge.cpp b/flang/lib/Lower/Bridge.cpp
index f7c3796c266d9a..05601f87449701 100644
--- a/flang/lib/Lower/Bridge.cpp
+++ b/flang/lib/Lower/Bridge.cpp
@@ -86,6 +86,7 @@
#include "llvm/Support/Path.h"
#include "llvm/Target/TargetMachine.h"
#include <optional>
+#include <set>
#define DEBUG_TYPE "flang-lower-bridge"
@@ -6508,26 +6509,42 @@ class FirConverter : public Fortran::lower::AbstractConverter {
void setOpenMPAssumptionAttributes(mlir::func::FuncOp func,
const Fortran::semantics::Scope &scope) {
- if (bridge.getSemanticsContext().langOptions().OpenMPSimd)
+ const auto &langOptions = bridge.getSemanticsContext().langOptions();
+ if (langOptions.OpenMPSimd)
return;
const auto *assumptionScopeEnd =
&Fortran::semantics::omp::GetProgramUnit(scope).parent();
+ bool noOpenmp = false;
+ std::set<llvm::omp::Directive> absent;
for (const auto *assumptionScope = &scope;
!assumptionScope->IsGlobal() && assumptionScope != assumptionScopeEnd;
assumptionScope = &assumptionScope->parent()) {
if (const auto *symbol = assumptionScope->symbol();
- !symbol ||
- !symbol->test(Fortran::semantics::Symbol::Flag::OmpAssumesNoOpenmp))
- continue;
- llvm::SmallVector<mlir::Attribute> llvmAttrs;
- if (auto existing =
- func->getAttrOfType<mlir::ArrayAttr>("llvm.passthrough"))
- llvm::append_range(llvmAttrs, existing);
- llvmAttrs.push_back(
- builder->getStrArrayAttr({llvm::AssumptionAttrKey, "omp_no_openmp"}));
- func->setAttr("llvm.passthrough", builder->getArrayAttr(llvmAttrs));
- break;
+ symbol &&
+ symbol->test(Fortran::semantics::Symbol::Flag::OmpAssumesNoOpenmp))
+ noOpenmp = true;
+ const auto &directives = assumptionScope->ompAssumesAbsent();
+ absent.insert(directives.begin(), directives.end());
}
+ if (!noOpenmp && absent.empty())
+ return;
+ std::string assumptions = noOpenmp ? "omp_no_openmp" : "";
+ for (llvm::omp::Directive directive : absent) {
+ if (!assumptions.empty())
+ assumptions += ',';
+ assumptions += "absent(";
+ assumptions += llvm::omp::getOpenMPDirectiveName(
+ directive, langOptions.getOpenMPVersion())
+ .str();
+ assumptions += ')';
+ }
+ llvm::SmallVector<mlir::Attribute> llvmAttrs;
+ if (auto existing =
+ func->getAttrOfType<mlir::ArrayAttr>("llvm.passthrough"))
+ llvm::append_range(llvmAttrs, existing);
+ llvmAttrs.push_back(
+ builder->getStrArrayAttr({llvm::AssumptionAttrKey, assumptions}));
+ func->setAttr("llvm.passthrough", builder->getArrayAttr(llvmAttrs));
}
/// Start translation of a function.
diff --git a/flang/lib/Lower/OpenMP/OpenMP.cpp b/flang/lib/Lower/OpenMP/OpenMP.cpp
index 3ce793989dee30..004f68418fd66a 100644
--- a/flang/lib/Lower/OpenMP/OpenMP.cpp
+++ b/flang/lib/Lower/OpenMP/OpenMP.cpp
@@ -5951,7 +5951,8 @@ static void genOMP(lower::AbstractConverter &converter, lower::SymMap &symTable,
return;
for (const parser::OmpClause &clause : assumesConstruct.v.Clauses().v) {
- if (!std::holds_alternative<parser::OmpClause::NoOpenmp>(clause.u))
+ if (!std::holds_alternative<parser::OmpClause::NoOpenmp>(clause.u) &&
+ !std::holds_alternative<parser::OmpClause::Absent>(clause.u))
TODO(converter.genLocation(clause.source),
"assumption clauses on the assumes directive");
}
diff --git a/flang/lib/Semantics/mod-file.cpp b/flang/lib/Semantics/mod-file.cpp
index dae665eb67500e..b90a8f16bec535 100644
--- a/flang/lib/Semantics/mod-file.cpp
+++ b/flang/lib/Semantics/mod-file.cpp
@@ -473,6 +473,15 @@ void ModFileWriter::PutSymbols(
if (scope.symbol()->test(Symbol::Flag::OmpAssumesNoOpenmp)) {
decls_ << "!$omp assumes no_openmp\n";
}
+ if (!scope.ompAssumesAbsent().empty()) {
+ decls_ << "!$omp assumes absent(";
+ llvm::interleaveComma(
+ scope.ompAssumesAbsent(), decls_, [&](llvm::omp::Directive directive) {
+ decls_ << llvm::omp::getOpenMPDirectiveName(
+ directive, context_.langOptions().getOpenMPVersion());
+ });
+ decls_ << ")\n";
+ }
PutOpenMPDeclarativeDirectives(decls_, sorted, context_);
for (const auto &set : scope.equivalenceSets()) {
diff --git a/flang/lib/Semantics/resolve-directives.cpp b/flang/lib/Semantics/resolve-directives.cpp
index 9b15b979c0d1ae..6d90816c244585 100644
--- a/flang/lib/Semantics/resolve-directives.cpp
+++ b/flang/lib/Semantics/resolve-directives.cpp
@@ -501,11 +501,18 @@ class OmpAttributeVisitor : DirectiveAttributeVisitor<llvm::omp::Directive> {
if (x.moduleName.symbol) {
Scope &thisScope{context_.FindScope(x.moduleName.source)};
const auto version{context_.langOptions().getOpenMPVersion()};
- if ((version == 51 || version == 52) &&
- x.moduleName.symbol->test(Symbol::Flag::OmpAssumesNoOpenmp)) {
- if (auto *symbol{const_cast<Symbol *>(
- omp::GetProgramUnit(thisScope).symbol())}) {
- symbol->set(Symbol::Flag::OmpAssumesNoOpenmp);
+ if (version == 51 || version == 52) {
+ Scope &programUnit{const_cast<Scope &>(omp::GetProgramUnit(thisScope))};
+ if (x.moduleName.symbol->test(Symbol::Flag::OmpAssumesNoOpenmp)) {
+ if (auto *symbol{const_cast<Symbol *>(programUnit.symbol())}) {
+ symbol->set(Symbol::Flag::OmpAssumesNoOpenmp);
+ }
+ }
+ if (const auto *moduleScope{x.moduleName.symbol->scope()}) {
+ for (llvm::omp::Directive directive :
+ moduleScope->ompAssumesAbsent()) {
+ programUnit.add_ompAssumesAbsent(directive);
+ }
}
}
common::visit(
diff --git a/flang/lib/Semantics/resolve-names.cpp b/flang/lib/Semantics/resolve-names.cpp
index 6dd69a7d210dbd..a0c1ebf4349eac 100644
--- a/flang/lib/Semantics/resolve-names.cpp
+++ b/flang/lib/Semantics/resolve-names.cpp
@@ -1859,6 +1859,14 @@ class OmpVisitor : public virtual DeclarationVisitor {
symbol->set(Symbol::Flag::OmpAssumesNoOpenmp);
}
}
+ for (const parser::OmpClause &clause : x.v.Clauses().v) {
+ if (const auto *absent{
+ std::get_if<parser::OmpClause::Absent>(&clause.u)}) {
+ for (llvm::omp::Directive directive : absent->v.v) {
+ currScope().add_ompAssumesAbsent(directive);
+ }
+ }
+ }
}
// Make sure that the following code is properly handled:
diff --git a/flang/test/Lower/OpenMP/Todo/assumes.f90 b/flang/test/Lower/OpenMP/Todo/assumes.f90
index 256307bb737f70..ff535cfe4177e5 100644
--- a/flang/test/Lower/OpenMP/Todo/assumes.f90
+++ b/flang/test/Lower/OpenMP/Todo/assumes.f90
@@ -3,7 +3,8 @@
! RUN: %not_todo_cmd %flang_fc1 -emit-hlfir -fopenmp -fopenmp-version=52 -o - %t/no-openmp-first.f90 2>&1 | FileCheck %s
! RUN: %not_todo_cmd %flang_fc1 -emit-hlfir -fopenmp -fopenmp-version=52 -o - %t/no-openmp-last.f90 2>&1 | FileCheck %s
! RUN: %not_todo_cmd %flang_fc1 -emit-hlfir -fopenmp -fopenmp-version=52 -o - %t/no-openmp-routines.f90 2>&1 | FileCheck %s
-! RUN: %not_todo_cmd %flang_fc1 -emit-hlfir -fopenmp -fopenmp-version=52 -o - %t/absent.f90 2>&1 | FileCheck %s
+! RUN: %not_todo_cmd %flang_fc1 -emit-hlfir -fopenmp -fopenmp-version=52 -o - %t/absent-first.f90 2>&1 | FileCheck %s
+! RUN: %not_todo_cmd %flang_fc1 -emit-hlfir -fopenmp -fopenmp-version=52 -o - %t/absent-last.f90 2>&1 | FileCheck %s
! RUN: %not_todo_cmd %flang_fc1 -emit-hlfir -fopenmp -fopenmp-version=52 -o - %t/contains.f90 2>&1 | FileCheck %s
! RUN: %not_todo_cmd %flang_fc1 -emit-hlfir -fopenmp -fopenmp-version=52 -o - %t/holds.f90 2>&1 | FileCheck %s
@@ -24,22 +25,27 @@ subroutine p
!$omp assumes no_parallelism no_openmp
end subroutine p
-!--- no-openmp-routines.f90
+!--- absent-first.f90
subroutine p
- !$omp assumes no_openmp no_openmp_routines
+ !$omp assumes absent(parallel) no_parallelism
end subroutine p
-!--- absent.f90
+!--- absent-last.f90
+subroutine p
+ !$omp assumes no_parallelism absent(parallel)
+end subroutine p
+
+!--- no-openmp-routines.f90
subroutine p
- !$omp assumes no_openmp absent(parallel)
+ !$omp assumes no_openmp absent(parallel) no_openmp_routines
end subroutine p
!--- contains.f90
subroutine p
- !$omp assumes no_openmp contains(parallel)
+ !$omp assumes no_openmp absent(parallel) contains(task)
end subroutine p
!--- holds.f90
subroutine p
- !$omp assumes no_openmp holds(.true.)
+ !$omp assumes no_openmp absent(parallel) holds(.true.)
end subroutine p
diff --git a/flang/test/Lower/OpenMP/assumption-noopenmp-submodule.f90 b/flang/test/Lower/OpenMP/assumption-submodule.f90
similarity index 68%
rename from flang/test/Lower/OpenMP/assumption-noopenmp-submodule.f90
rename to flang/test/Lower/OpenMP/assumption-submodule.f90
index 2d57eb312e9658..cdf810f028d050 100644
--- a/flang/test/Lower/OpenMP/assumption-noopenmp-submodule.f90
+++ b/flang/test/Lower/OpenMP/assumption-submodule.f90
@@ -17,8 +17,18 @@
implicit none
contains
! CHECK-LABEL: func.func @_QMuse_parentPimported_work()
- ! CHECK5X-SAME: llvm.passthrough = {{\[\[}}"llvm.assume", "omp_no_openmp"]]
+ ! CHECK5X-SAME: llvm.passthrough = {{\[\[}}"llvm.assume", "omp_no_openmp,absent(barrier),absent(parallel)"]]
! CHECK60-NOT: "omp_no_openmp"
module procedure imported_work
end procedure imported_work
end submodule use_child_reload
+
+submodule (use_parent) absent_use_child_reload
+ use absent_reexport, only:
+contains
+ ! CHECK-LABEL: func.func @_QMuse_parentPabsent_imported_work()
+ ! CHECK5X-SAME: llvm.passthrough = {{\[\[}}"llvm.assume", "absent(barrier),absent(parallel),absent(target)"]]
+ ! CHECK60-NOT: llvm.passthrough
+ module procedure absent_imported_work
+ end procedure absent_imported_work
+end submodule absent_use_child_reload
diff --git a/flang/test/Lower/OpenMP/assumption.f90 b/flang/test/Lower/OpenMP/assumption.f90
index ca2e522a0b790d..b43022c6c983ff 100644
--- a/flang/test/Lower/OpenMP/assumption.f90
+++ b/flang/test/Lower/OpenMP/assumption.f90
@@ -1,13 +1,12 @@
! RUN: mkdir -p %t
-! RUN: %flang_fc1 -emit-hlfir -fopenmp -fopenmp-version=51 -module-dir %t -o - %s 2>&1 | FileCheck %s --check-prefixes=CHECK,CHECK5X,SCOPE,SCOPE5X
+! RUN: %flang_fc1 -emit-hlfir -fopenmp -fopenmp-version=51 -module-dir %t -o - %s 2>&1 | FileCheck %s --check-prefixes=CHECK,CHECK5X,SUBMODULE,SCOPE,SCOPE5X,ABSENT,ABSENT5X,RELOAD,RELOAD5X
! RUN: FileCheck %s --check-prefix=MODFILE --input-file=%t/assumes_module.mod
-! RUN: FileCheck %s --check-prefix=USE-MODFILE --input-file=%t/use_parent-use_child.mod
-! RUN: %flang_fc1 -emit-hlfir -fopenmp -fopenmp-version=60 -module-dir %t -o - %s 2>&1 | FileCheck %s --check-prefixes=CHECK,CHECK60,SCOPE,SCOPE60
+! RUN: %flang_fc1 -emit-hlfir -fopenmp -fopenmp-version=60 -module-dir %t -o - %s 2>&1 | FileCheck %s --check-prefixes=CHECK,CHECK60,SUBMODULE,SCOPE,SCOPE60,ABSENT,ABSENT60,RELOAD,RELOAD60
! RUN: %flang_fc1 -emit-hlfir -fopenmp-simd -fopenmp-version=51 -module-dir %t -o - %s | FileCheck %s --check-prefix=SIMD
! RUN: %flang_fc1 -fdebug-dump-symbols -fopenmp -fopenmp-version=51 -module-dir %t %s | FileCheck %s --check-prefix=SYMBOLS
! SIMD: module
-! SIMD-NOT: "omp_no_openmp"
+! SIMD-NOT: "llvm.assume"
! SYMBOLS-DAG: assume_block (Subroutine): Subprogram
! SYMBOLS-DAG: assumes_module (OmpAssumesNoOpenmp): Module
@@ -21,7 +20,7 @@
! always lowered.
! CHECK-LABEL: func.func @_QPassume_block
-! CHECK-NOT: "omp_no_openmp"
+! CHECK-NOT: llvm.passthrough
subroutine assume_block(x)
integer :: x
! CHECK: %[[DECL:.*]]:2 = hlfir.declare
@@ -126,19 +125,29 @@ subroutine assumes_no_openmp_local
call set_value(x)
end subroutine assumes_no_openmp_local
+submodule (assumes_module) assumes_implementation
+contains
+ module procedure separate_work
+ end procedure separate_work
+end submodule assumes_implementation
+
! MODFILE: module assumes_module
! MODFILE: !$omp assumes no_openmp
+! SUBMODULE-LABEL: func.func @_QMassumes_modulePseparate_work()
+! SUBMODULE-NOT: "omp_no_openmp"
+! SUBMODULE: return
+
module scoped_assumes
implicit none
- !$omp assumes no_openmp
+ !$omp assumes no_openmp absent(parallel, barrier)
interface
module subroutine independent_work() bind(C, name="independent_work")
end subroutine independent_work
end interface
contains
! SCOPE-LABEL: func.func @_QMscoped_assumesPmodule_work()
- ! SCOPE-SAME: llvm.passthrough = {{\[\[}}"llvm.assume", "omp_no_openmp"]]
+ ! SCOPE-SAME: llvm.passthrough = {{\[\[}}"llvm.assume", "omp_no_openmp,absent(barrier),absent(parallel)"]]
subroutine module_work()
end subroutine module_work
end module scoped_assumes
@@ -146,7 +155,7 @@ end module scoped_assumes
submodule (scoped_assumes) scoped_implementation
contains
! SCOPE-LABEL: func.func @independent_work()
- ! SCOPE-NOT: "omp_no_openmp"
+ ! SCOPE-NOT: llvm.passthrough
module procedure independent_work
! SCOPE: omp.parallel {
!$omp parallel
@@ -167,17 +176,148 @@ module use_parent
interface
module subroutine imported_work()
end subroutine imported_work
+ module subroutine absent_imported_work()
+ end subroutine absent_imported_work
end interface
end module use_parent
-! USE-MODFILE: !$omp assumes no_openmp
submodule (use_parent) use_child
use scoped_assumes, only:
implicit none
contains
! SCOPE-LABEL: func.func @_QMuse_parentPimported_work()
- ! SCOPE5X-SAME: llvm.passthrough = {{\[\[}}"llvm.assume", "omp_no_openmp"]]
+ ! SCOPE5X-SAME: llvm.passthrough = {{\[\[}}"llvm.assume", "omp_no_openmp,absent(barrier),absent(parallel)"]]
! SCOPE60-NOT: "omp_no_openmp"
module procedure imported_work
end procedure imported_work
end submodule use_child
+
+! ABSENT-LABEL: func.func @_QPassumes_absent
+! ABSENT-SAME: llvm.passthrough = {{\[\[}}"llvm.assume", "absent(barrier),absent(parallel)"]]
+subroutine assumes_absent(x)
+ implicit none
+ !$omp assumes absent(parallel, barrier)
+ integer :: x
+ ! ABSENT: hlfir.assign
+ x = 7
+end subroutine assumes_absent
+
+module absent_module
+ implicit none
+ !$omp assumes no_openmp absent(parallel, barrier)
+ interface
+ module subroutine separate_absent_work() bind(C, name="separate_absent_work")
+ end subroutine separate_absent_work
+ end interface
+contains
+ ! ABSENT-LABEL: func.func @_QMabsent_modulePmodule_work()
+ ! ABSENT-SAME: llvm.passthrough = {{\[\[}}"llvm.assume", "omp_no_openmp,absent(barrier),absent(parallel)"]]
+ subroutine module_work()
+ end subroutine module_work
+
+ ! ABSENT-LABEL: func.func @_QMabsent_modulePlocal_work()
+ ! ABSENT-SAME: llvm.passthrough = {{\[\[}}"llvm.assume", "omp_no_openmp,absent(barrier),absent(critical),absent(parallel)"]]
+ subroutine local_work()
+ !$omp assumes absent(critical)
+ end subroutine local_work
+end module absent_module
+
+! ABSENT-LABEL: func.func @_QPassumes_host()
+! ABSENT-SAME: llvm.passthrough = {{\[\[}}"llvm.assume", "absent(parallel)"]]
+subroutine assumes_host()
+ !$omp assumes absent(parallel)
+ call internal_work()
+contains
+ ! ABSENT-LABEL: func.func {{.*}}@_QFassumes_hostPinternal_work()
+ ! ABSENT-SAME: llvm.passthrough = {{\[\[}}"llvm.assume", "omp_no_openmp,absent(barrier),absent(parallel)"]]
+ subroutine internal_work()
+ !$omp assumes absent(parallel, barrier) no_openmp
+ !$omp assumes absent(barrier)
+ end subroutine internal_work
+end subroutine assumes_host
+
+! ABSENT-LABEL: func....
[truncated]
``````````
</details>
https://github.com/llvm/llvm-project/pull/236693
More information about the Mlir-commits
mailing list