[llvm-branch-commits] [flang] [flang][OpenMP] Check if loop nest/sequence is well-formed (PR #188025)

2026-03-25 Thread Krzysztof Parzyszek via llvm-branch-commits


@@ -1326,4 +1334,64 @@ LoopSequence::Depth LoopSequence::getNestedDepths() 
const {
   }
   return children_.front().depth_;
 }
+
+static bool IsDoConcurrent(const parser::ExecutionPartConstruct &x) {
+  if (auto *loop{parser::Unwrap(x)}) {
+return loop->IsDoConcurrent();
+  }
+  return false;
+}
+
+static Reason whyNotWellFormed(

kparzysz wrote:

Done

https://github.com/llvm/llvm-project/pull/188025
___
llvm-branch-commits mailing list
[email protected]
https://lists.llvm.org/cgi-bin/mailman/listinfo/llvm-branch-commits


[llvm-branch-commits] [flang] [flang][OpenMP] Check if loop nest/sequence is well-formed (PR #188025)

2026-03-25 Thread Krzysztof Parzyszek via llvm-branch-commits

https://github.com/kparzysz updated 
https://github.com/llvm/llvm-project/pull/188025

>From fba1271b9b74d00f153d5f1eaa0887e61c64e02d Mon Sep 17 00:00:00 2001
From: Krzysztof Parzyszek 
Date: Fri, 20 Mar 2026 11:33:45 -0500
Subject: [PATCH 1/3] [flang][OpenM] Check if loop nest/sequence is well-formed

Check if the code associated with a nest or sequence construct is well
formed. Emit diagnostic messages if not.

Make a clearer separation for checks of loop-nest-associated and loop-
sequence-associated constructs.

Unify structure of some of the more common messages.

Issue: https://github.com/llvm/llvm-project/issues/185287
---
 flang/include/flang/Semantics/openmp-utils.h  |   3 +
 flang/lib/Semantics/check-omp-loop.cpp| 126 ++
 flang/lib/Semantics/openmp-utils.cpp  | 162 +-
 flang/lib/Semantics/resolve-directives.cpp|   5 -
 flang/test/Parser/OpenMP/interchange-fail.f90 |  31 
 flang/test/Parser/OpenMP/tile-fail.f90|  31 
 flang/test/Semantics/OpenMP/do-collapse.f90   |   3 +-
 .../OpenMP/do-concurrent-collapse.f90 |  11 +-
 flang/test/Semantics/OpenMP/do09.f90  |   6 +-
 flang/test/Semantics/OpenMP/do13.f90  |  10 +-
 flang/test/Semantics/OpenMP/do21.f90  |  10 +-
 flang/test/Semantics/OpenMP/fuse1.f90 |   2 +-
 .../Semantics/OpenMP/interchange-fail.f90 |  18 ++
 flang/test/Semantics/OpenMP/interchange01.f90 |   8 +-
 .../Semantics/OpenMP/loop-association.f90 |  15 +-
 .../loop-transformation-construct01.f90   |  17 +-
 .../loop-transformation-construct02.f90   |  11 +-
 .../loop-transformation-construct04.f90   |   4 +-
 flang/test/Semantics/OpenMP/tile-fail.f90 |  18 ++
 flang/test/Semantics/OpenMP/tile02.f90|   3 +-
 flang/test/Semantics/OpenMP/tile03.f90|   3 +-
 flang/test/Semantics/OpenMP/tile08.f90|   4 +-
 flang/test/Semantics/OpenMP/tile09.f90|   3 +-
 23 files changed, 269 insertions(+), 235 deletions(-)
 delete mode 100644 flang/test/Parser/OpenMP/interchange-fail.f90
 delete mode 100644 flang/test/Parser/OpenMP/tile-fail.f90
 create mode 100644 flang/test/Semantics/OpenMP/interchange-fail.f90
 create mode 100644 flang/test/Semantics/OpenMP/tile-fail.f90

diff --git a/flang/include/flang/Semantics/openmp-utils.h 
b/flang/include/flang/Semantics/openmp-utils.h
index 7c95edf81ada2..bf35598177e17 100644
--- a/flang/include/flang/Semantics/openmp-utils.h
+++ b/flang/include/flang/Semantics/openmp-utils.h
@@ -202,6 +202,9 @@ struct LoopSequence {
   const Depth &depth() const { return depth_; }
   const std::vector &children() const { return children_; }
 
+  WithReason isWellFormedSequence() const;
+  WithReason isWellFormedNest() const;
+
 private:
   using Construct = ExecutionPartIterator::Construct;
 
diff --git a/flang/lib/Semantics/check-omp-loop.cpp 
b/flang/lib/Semantics/check-omp-loop.cpp
index df9797ac8e56a..962537496e580 100644
--- a/flang/lib/Semantics/check-omp-loop.cpp
+++ b/flang/lib/Semantics/check-omp-loop.cpp
@@ -61,16 +61,6 @@ class AssociatedLoopChecker {
   constructNamesAndLevels_.emplace(
   constructName.value().ToString(), level_);
 }
-if (level_ >= 0) {
-  if (dc.IsDoWhile()) {
-context_.Say(doStmt.source,
-"The associated loop of a loop-associated directive cannot be a DO 
WHILE."_err_en_US);
-  }
-  if (!dc.GetLoopControl()) {
-context_.Say(doStmt.source,
-"The associated loop of a loop-associated directive cannot be a DO 
without control."_err_en_US);
-  }
-}
 return true;
   }
 
@@ -268,93 +258,83 @@ void OmpStructureChecker::CheckNestedConstruct(
 
   // Check constructs contained in the body of the loop construct.
   auto &body{std::get(x.t)};
+
   for (auto &stmt : BlockRange(body, BlockRange::Step::Over)) {
 if (auto *d{parser::Unwrap(stmt)}) {
   context_.Say(d->source,
   "Compiler directives are not allowed inside OpenMP loop 
constructs"_warn_en_US);
-} else if (auto *omp{parser::Unwrap(stmt)}) {
-  if (!IsLoopTransforming(omp->BeginDir().DirId())) {
-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(stmt)) {
-  parser::CharBlock source{parser::GetSource(stmt).value_or(x.source)};
-  context_.Say(source,
-  "OpenMP loop construct can only contain DO loops or 
loop-nest-generating OpenMP constructs"_err_en_US);
 }
   }
 
   LoopSequence sequence(body, version, true);
 
-  // Check if a loop-nest-associated construct has only one top-level loop
-  // in it.
+  auto assoc{llvm::omp::getDirectiveAssociation(dir)};
   auto needRange{GetAffectedLoopRangeWithReason(beginSpec, version)};
+ 

[llvm-branch-commits] [flang] [flang][OpenMP] Check if loop nest/sequence is well-formed (PR #188025)

2026-03-25 Thread Michael Kruse via llvm-branch-commits

https://github.com/Meinersbur edited 
https://github.com/llvm/llvm-project/pull/188025
___
llvm-branch-commits mailing list
[email protected]
https://lists.llvm.org/cgi-bin/mailman/listinfo/llvm-branch-commits


[llvm-branch-commits] [flang] [flang][OpenMP] Check if loop nest/sequence is well-formed (PR #188025)

2026-03-25 Thread Michael Kruse via llvm-branch-commits


@@ -1326,4 +1334,64 @@ LoopSequence::Depth LoopSequence::getNestedDepths() 
const {
   }
   return children_.front().depth_;
 }
+
+static bool IsDoConcurrent(const parser::ExecutionPartConstruct &x) {
+  if (auto *loop{parser::Unwrap(x)}) {
+return loop->IsDoConcurrent();
+  }
+  return false;
+}
+
+static Reason whyNotWellFormed(

Meinersbur wrote:

`IsDoConcurrent`, `whyNotWellFormed`: Two static function, one starting with a 
capital letter, the other with lower case. 

I do not quite get https://flang.llvm.org/docs/C++style.html#naming, but at 
least one of them is wrong

https://github.com/llvm/llvm-project/pull/188025
___
llvm-branch-commits mailing list
[email protected]
https://lists.llvm.org/cgi-bin/mailman/listinfo/llvm-branch-commits


[llvm-branch-commits] [flang] [flang][OpenMP] Check if loop nest/sequence is well-formed (PR #188025)

2026-03-25 Thread Michael Kruse via llvm-branch-commits

https://github.com/Meinersbur approved this pull request.

LGTM

https://github.com/llvm/llvm-project/pull/188025
___
llvm-branch-commits mailing list
[email protected]
https://lists.llvm.org/cgi-bin/mailman/listinfo/llvm-branch-commits


[llvm-branch-commits] [flang] [flang][OpenMP] Check if loop nest/sequence is well-formed (PR #188025)

2026-03-24 Thread Jack Styles via llvm-branch-commits

https://github.com/Stylie777 approved this pull request.

LGTM, thanks @kparzysz these are some nice improvements.

https://github.com/llvm/llvm-project/pull/188025
___
llvm-branch-commits mailing list
[email protected]
https://lists.llvm.org/cgi-bin/mailman/listinfo/llvm-branch-commits