[flang-commits] [flang] 2dfa047 - [flang][OpenMP] Include check for fully unrolled loops into nest check, NFC (#181729)
via flang-commits
flang-commits at lists.llvm.org
Wed Feb 18 04:48:37 PST 2026
Author: Krzysztof Parzyszek
Date: 2026-02-18T06:48:33-06:00
New Revision: 2dfa047916c7603d1d0c67500cbd2d6cc707e653
URL: https://github.com/llvm/llvm-project/commit/2dfa047916c7603d1d0c67500cbd2d6cc707e653
DIFF: https://github.com/llvm/llvm-project/commit/2dfa047916c7603d1d0c67500cbd2d6cc707e653.diff
LOG: [flang][OpenMP] Include check for fully unrolled loops into nest check, NFC (#181729)
It's naturally a part of the verification of constructs nested in loop
constructs, so perform that check there instead of having it in a
separate function.
Added:
Modified:
flang/lib/Semantics/check-omp-loop.cpp
flang/lib/Semantics/check-omp-structure.h
Removed:
################################################################################
diff --git a/flang/lib/Semantics/check-omp-loop.cpp b/flang/lib/Semantics/check-omp-loop.cpp
index 80d2b90baf939..2f4b1ebecf579 100644
--- a/flang/lib/Semantics/check-omp-loop.cpp
+++ b/flang/lib/Semantics/check-omp-loop.cpp
@@ -270,6 +270,17 @@ static bool IsLoopTransforming(llvm::omp::Directive dir) {
}
}
+static bool IsFullUnroll(const parser::OpenMPLoopConstruct &x) {
+ const parser::OmpDirectiveSpecification &beginSpec{x.BeginDir()};
+
+ if (beginSpec.DirName().v == llvm::omp::Directive::OMPD_unroll) {
+ return llvm::none_of(beginSpec.Clauses().v, [](const parser::OmpClause &c) {
+ return c.Id() == llvm::omp::Clause::OMPC_partial;
+ });
+ }
+ return false;
+}
+
void OmpStructureChecker::CheckNestedBlock(
const parser::OpenMPLoopConstruct &x, const parser::Block &body) {
using BlockRange = parser::omp::BlockRange;
@@ -282,6 +293,10 @@ void OmpStructureChecker::CheckNestedBlock(
context_.Say(omp->source,
"Only loop-transforming OpenMP constructs are allowed inside OpenMP loop constructs"_err_en_US);
}
+ if (IsFullUnroll(*omp)) {
+ context_.Say(x.source,
+ "OpenMP loop construct cannot apply to a fully unrolled loop"_err_en_US);
+ }
} else if (!parser::Unwrap<parser::DoConstruct>(stmt)) {
parser::CharBlock source{parser::GetSource(stmt).value_or(x.source)};
context_.Say(source,
@@ -290,17 +305,6 @@ void OmpStructureChecker::CheckNestedBlock(
}
}
-static bool IsFullUnroll(const parser::OpenMPLoopConstruct &x) {
- const parser::OmpDirectiveSpecification &beginSpec{x.BeginDir()};
-
- if (beginSpec.DirName().v == llvm::omp::Directive::OMPD_unroll) {
- return llvm::none_of(beginSpec.Clauses().v, [](const parser::OmpClause &c) {
- return c.Id() == llvm::omp::Clause::OMPC_partial;
- });
- }
- return false;
-}
-
static std::optional<size_t> CountGeneratedNests(
const parser::ExecutionPartConstruct &epc) {
if (parser::Unwrap<parser::DoConstruct>(epc)) {
@@ -403,18 +407,6 @@ void OmpStructureChecker::CheckNestedConstruct(
}
}
-void OmpStructureChecker::CheckFullUnroll(
- const parser::OpenMPLoopConstruct &x) {
- // If the nested construct is a full unroll, then this construct is invalid
- // since it won't contain a loop.
- if (const parser::OpenMPLoopConstruct *nested{x.GetNestedConstruct()}) {
- if (IsFullUnroll(*nested)) {
- context_.Say(x.source,
- "OpenMP loop construct cannot apply to a fully unrolled loop"_err_en_US);
- }
- }
-}
-
void OmpStructureChecker::Enter(const parser::OpenMPLoopConstruct &x) {
loopStack_.push_back(&x);
@@ -471,7 +463,6 @@ void OmpStructureChecker::Enter(const parser::OpenMPLoopConstruct &x) {
}
CheckLoopItrVariableIsInt(x);
CheckNestedConstruct(x);
- CheckFullUnroll(x);
CheckAssociatedLoopConstraints(x);
HasInvalidDistributeNesting(x);
HasInvalidLoopBinding(x);
diff --git a/flang/lib/Semantics/check-omp-structure.h b/flang/lib/Semantics/check-omp-structure.h
index 3bbfd61ca4d2b..d6dc3e4080c87 100644
--- a/flang/lib/Semantics/check-omp-structure.h
+++ b/flang/lib/Semantics/check-omp-structure.h
@@ -332,7 +332,6 @@ class OmpStructureChecker : public OmpStructureCheckerBase {
void CheckNestedBlock(
const parser::OpenMPLoopConstruct &x, const parser::Block &body);
void CheckNestedConstruct(const parser::OpenMPLoopConstruct &x);
- void CheckFullUnroll(const parser::OpenMPLoopConstruct &x);
void CheckTargetNest(const parser::OpenMPConstruct &x);
void CheckTargetUpdate();
void CheckTaskgraph(const parser::OmpBlockConstruct &x);
More information about the flang-commits
mailing list