[llvm-branch-commits] [flang] [flang][OpenMP] Use different ids for block and s/a ORDERED directive (PR #214727)

Krzysztof Parzyszek via llvm-branch-commits llvm-branch-commits at lists.llvm.org
Fri Aug 7 06:33:19 PDT 2026


https://github.com/kparzysz created https://github.com/llvm/llvm-project/pull/214727

Use OMPD_ordered_blockassoc for the block-associated ORDERED directive,
and OMPD_ordered_standalone for the standalone variant.

---

<sub>Stack created with <a href="https://github.com/github/gh-stack">GitHub Stacks CLI</a> • <a href="https://gh.io/stacks-feedback">Give Feedback 💬</a></sub>

>From 7113bf88322a09d4b905590549ed108dcb32309a Mon Sep 17 00:00:00 2001
From: Krzysztof Parzyszek <Krzysztof.Parzyszek at amd.com>
Date: Thu, 6 Aug 2026 07:45:21 -0500
Subject: [PATCH] [flang][OpenMP] Use different ids for block and s/a ORDERED
 directive

Use OMPD_ordered_blockassoc for the block-associated ORDERED directive,
and OMPD_ordered_standalone for the standalone variant.
---
 .../flang/Semantics/openmp-directive-sets.h   | 10 +++---
 flang/lib/Lower/OpenMP/OpenMP.cpp             | 15 ++++----
 flang/lib/Parser/openmp-parsers.cpp           | 35 ++++++++++++++++---
 flang/lib/Semantics/check-omp-loop.cpp        |  5 +--
 flang/lib/Semantics/check-omp-structure.cpp   | 14 +++++---
 flang/lib/Semantics/openmp-utils.cpp          |  2 +-
 .../test/Lower/OpenMP/Todo/ordered-depend.f90 |  2 +-
 flang/test/Lower/OpenMP/Todo/ordered.f90      |  2 +-
 8 files changed, 59 insertions(+), 26 deletions(-)

diff --git a/flang/include/flang/Semantics/openmp-directive-sets.h b/flang/include/flang/Semantics/openmp-directive-sets.h
index 99fab5a9fb040..c6966a8d836b0 100644
--- a/flang/include/flang/Semantics/openmp-directive-sets.h
+++ b/flang/include/flang/Semantics/openmp-directive-sets.h
@@ -217,7 +217,7 @@ static const llvm::omp::DirectiveSet compositeConstructSet{
 static const llvm::omp::DirectiveSet blockConstructSet{
     Directive::OMPD_masked,
     Directive::OMPD_master,
-    Directive::OMPD_ordered,
+    Directive::OMPD_ordered_blockassoc,
     Directive::OMPD_parallel,
     Directive::OMPD_parallel_masked,
     Directive::OMPD_parallel_master,
@@ -327,7 +327,7 @@ static const llvm::omp::DirectiveSet nestedBarrierErrSet{
         Directive::OMPD_atomic,
         Directive::OMPD_critical,
         Directive::OMPD_master,
-        Directive::OMPD_ordered,
+        Directive::OMPD_ordered_blockassoc,
     } | taskGeneratingSet |
         workShareSet,
 };
@@ -372,7 +372,7 @@ static const llvm::omp::DirectiveSet nestedOrderedDoAllowedSet{
 static const llvm::omp::DirectiveSet nestedOrderedErrSet{
     Directive::OMPD_atomic,
     Directive::OMPD_critical,
-    Directive::OMPD_ordered,
+    Directive::OMPD_ordered_blockassoc,
     Directive::OMPD_task,
     Directive::OMPD_taskloop,
 };
@@ -413,7 +413,7 @@ static const llvm::omp::DirectiveSet nestedWorkshareErrSet{
         Directive::OMPD_atomic,
         Directive::OMPD_critical,
         Directive::OMPD_master,
-        Directive::OMPD_ordered,
+        Directive::OMPD_ordered_blockassoc,
         Directive::OMPD_task,
         Directive::OMPD_taskloop,
     } | workShareSet,
@@ -427,7 +427,7 @@ static const llvm::omp::DirectiveSet nestedWorkshareErrSet{
 static const llvm::omp::DirectiveSet simpleStandaloneNonSimdOnlySet{
     Directive::OMPD_taskyield,
     Directive::OMPD_barrier,
-    Directive::OMPD_ordered,
+    Directive::OMPD_ordered_standalone,
     Directive::OMPD_target_enter_data,
     Directive::OMPD_target_exit_data,
     Directive::OMPD_target_update,
diff --git a/flang/lib/Lower/OpenMP/OpenMP.cpp b/flang/lib/Lower/OpenMP/OpenMP.cpp
index 3876799b3a081..7d45d17f65bb5 100644
--- a/flang/lib/Lower/OpenMP/OpenMP.cpp
+++ b/flang/lib/Lower/OpenMP/OpenMP.cpp
@@ -3475,7 +3475,7 @@ genOrderedOp(lower::AbstractConverter &converter, lower::SymMap &symTable,
              mlir::Location loc, const ConstructQueue &queue,
              ConstructQueue::const_iterator item) {
   if (!semaCtx.langOptions().OpenMPSimd)
-    TODO(loc, "OMPD_ordered");
+    TODO(loc, "OMPD_ordered_standalone");
   return nullptr;
 }
 
@@ -3490,7 +3490,7 @@ genOrderedRegionOp(lower::AbstractConverter &converter, lower::SymMap &symTable,
 
   return genOpWithBody<mlir::omp::OrderedRegionOp>(
       OpWithBodyGenInfo(converter, symTable, semaCtx, loc, eval,
-                        llvm::omp::Directive::OMPD_ordered),
+                        llvm::omp::Directive::OMPD_ordered_blockassoc),
       queue, item, clauseOps);
 }
 
@@ -4983,7 +4983,7 @@ static void genOMPDispatch(lower::AbstractConverter &converter,
   case llvm::omp::Directive::OMPD_master:
     newOp = genMasterOp(converter, symTable, semaCtx, eval, loc, queue, item);
     break;
-  case llvm::omp::Directive::OMPD_ordered:
+  case llvm::omp::Directive::OMPD_ordered_blockassoc:
     // Block-associated "ordered" construct.
     newOp = genOrderedRegionOp(converter, symTable, semaCtx, eval, loc, queue,
                                item);
@@ -5109,9 +5109,10 @@ static void genOMPDispatch(lower::AbstractConverter &converter,
       // leafs and loop transformation constructs.
       llvm::omp::DirectiveSet combinableDirs =
           (llvm::omp::blockConstructSet &
-           ~llvm::omp::DirectiveSet{llvm::omp::Directive::OMPD_ordered,
-                                    llvm::omp::Directive::OMPD_scope,
-                                    llvm::omp::Directive::OMPD_taskgroup}) |
+           ~llvm::omp::DirectiveSet{
+               llvm::omp::Directive::OMPD_ordered_blockassoc,
+               llvm::omp::Directive::OMPD_scope,
+               llvm::omp::Directive::OMPD_taskgroup}) |
           (llvm::omp::loopConstructSet & ~llvm::omp::loopTransformationSet);
       const auto &ompEval = nestedEval->get<parser::OpenMPConstruct>();
       llvm::omp::Directive nestedDir =
@@ -6283,7 +6284,7 @@ static void genOMP(lower::AbstractConverter &converter, lower::SymMap &symTable,
   ConstructQueue queue{
       buildConstructQueue(converter.getFirOpBuilder().getModule(), semaCtx,
                           eval, directive.source, directive.v, clauses)};
-  if (directive.v == llvm::omp::Directive::OMPD_ordered) {
+  if (directive.v == llvm::omp::Directive::OMPD_ordered_standalone) {
     // Standalone "ordered" directive.
     genOrderedOp(converter, symTable, semaCtx, eval, currentLocation, queue,
                  queue.begin());
diff --git a/flang/lib/Parser/openmp-parsers.cpp b/flang/lib/Parser/openmp-parsers.cpp
index 7c4e49a673bb0..f5ab5380754c8 100644
--- a/flang/lib/Parser/openmp-parsers.cpp
+++ b/flang/lib/Parser/openmp-parsers.cpp
@@ -209,7 +209,14 @@ struct OmpDirectiveNameParser {
     for (const NameWithId &nid : directives_starting_with(next)) {
       if (attempt(Token(nid.first.data())).Parse(state)) {
         OmpDirectiveName n;
-        n.v = nid.second;
+        // We can't tell which one "ordered" corresponds to here,
+        // so normalize it to OMPD_ordered_standalone.
+        if (nid.second == llvm::omp::Directive::OMPD_ordered ||
+            nid.second == llvm::omp::Directive::OMPD_ordered_blockassoc) {
+          n.v = llvm::omp::Directive::OMPD_ordered_standalone;
+        } else {
+          n.v = nid.second;
+        }
         n.source = parser::CharBlock(begin, state.GetLocation());
         return n;
       }
@@ -1903,8 +1910,10 @@ auto OmpDirectiveSpecificationParser::Parse(ParseState &state) const
 }
 
 static bool IsStandaloneOrdered(const OmpDirectiveSpecification &spec) {
-  // An ORDERED construct is standalone if it has DOACROSS or DEPEND clause.
-  return spec.DirId() == llvm::omp::Directive::OMPD_ordered &&
+  // An ORDERED directive is standalone if it has DOACROSS or DEPEND clause.
+  // The directive name parser will always use OMPD_ordered_standalone
+  // for "ORDEED".
+  return spec.DirId() == llvm::omp::Directive::OMPD_ordered_standalone &&
       llvm::any_of(spec.Clauses().v, [](const OmpClause &clause) {
         llvm::omp::Clause id{clause.Id()};
         return id == llvm::omp::Clause::OMPC_depend ||
@@ -2184,6 +2193,7 @@ struct OmpBlockConstructParser {
       if (auto &&body{attempt(StrictlyStructuredBlockParser{}).Parse(state)}) {
         // Try strictly-structured block with an optional end-directive
         auto end{maybe(OmpEndDirectiveParser{dir_}).Parse(state)};
+        SwitchToBlockOrdered(*begin, *end);
         return OmpBlockConstruct{OmpBeginDirective(std::move(*begin)),
             std::move(*body),
             llvm::transformOptional(std::move(*end),
@@ -2194,6 +2204,7 @@ struct OmpBlockConstructParser {
         auto end{maybe(OmpEndDirectiveParser{dir_}).Parse(state)};
         // Delay the error for a missing end-directive until semantics so that
         // we have better control over the output.
+        SwitchToBlockOrdered(*begin, *end);
         return OmpBlockConstruct{OmpBeginDirective(std::move(*begin)),
             std::move(*body),
             llvm::transformOptional(std::move(*end),
@@ -2204,6 +2215,22 @@ struct OmpBlockConstructParser {
   }
 
 private:
+  // There are two directive ids corresponding to "ORDERED", and the
+  // directive name parser will always use OMPD_ordered_standalone.
+  // Change it to OMPD_ordered_blockassoc once we've confirmed that
+  // this is the block-associated variant.
+  void SwitchToBlockOrdered(const OmpDirectiveSpecification &begin,
+      const std::optional<OmpDirectiveSpecification> &end) const {
+    if (begin.DirId() == llvm::omp::Directive::OMPD_ordered_standalone) {
+      const_cast<OmpDirectiveName &>(begin.DirName()).v =
+          llvm::omp::Directive::OMPD_ordered_blockassoc;
+      if (end) {
+        const_cast<OmpDirectiveName &>(end->DirName()).v =
+            llvm::omp::Directive::OMPD_ordered_blockassoc;
+      }
+    }
+  }
+
   llvm::omp::Directive dir_;
   bool implicit_;
 };
@@ -2614,7 +2641,7 @@ TYPE_PARSER(sourced(construct<OmpAssumeDirective>(
 TYPE_PARSER( //
     MakeBlockConstruct(llvm::omp::Directive::OMPD_masked) ||
     MakeBlockConstruct(llvm::omp::Directive::OMPD_master) ||
-    MakeBlockConstruct(llvm::omp::Directive::OMPD_ordered) ||
+    MakeBlockConstruct(llvm::omp::Directive::OMPD_ordered_standalone) ||
     MakeBlockConstruct(llvm::omp::Directive::OMPD_parallel_masked) ||
     MakeBlockConstruct(llvm::omp::Directive::OMPD_parallel_master) ||
     MakeBlockConstruct(llvm::omp::Directive::OMPD_parallel_workshare) ||
diff --git a/flang/lib/Semantics/check-omp-loop.cpp b/flang/lib/Semantics/check-omp-loop.cpp
index 65d097b5a31f7..3c9cdfac450dc 100644
--- a/flang/lib/Semantics/check-omp-loop.cpp
+++ b/flang/lib/Semantics/check-omp-loop.cpp
@@ -186,7 +186,8 @@ void OmpStructureChecker::CheckSIMDNest(const parser::OpenMPConstruct &c) {
           // Allow `!$OMP ORDERED SIMD`
           [&](const parser::OmpBlockConstruct &c) {
             const parser::OmpDirectiveSpecification &beginSpec{c.BeginDir()};
-            if (beginSpec.DirId() == llvm::omp::Directive::OMPD_ordered) {
+            if (beginSpec.DirId() ==
+                llvm::omp::Directive::OMPD_ordered_blockassoc) {
               if (parser::omp::FindClause(
                       beginSpec, llvm::omp::Clause::OMPC_simd)) {
                 eligibleSIMD = true;
@@ -197,7 +198,7 @@ void OmpStructureChecker::CheckSIMDNest(const parser::OpenMPConstruct &c) {
             if (auto *ssc{std::get_if<parser::OpenMPSimpleStandaloneConstruct>(
                     &c.u)}) {
               llvm::omp::Directive dirId{ssc->v.DirId()};
-              if (dirId == llvm::omp::Directive::OMPD_ordered) {
+              if (dirId == llvm::omp::Directive::OMPD_ordered_standalone) {
                 if (parser::omp::FindClause(
                         ssc->v, llvm::omp::Clause::OMPC_simd)) {
                   eligibleSIMD = true;
diff --git a/flang/lib/Semantics/check-omp-structure.cpp b/flang/lib/Semantics/check-omp-structure.cpp
index 7bd5f1720fb3c..db61bd636e675 100644
--- a/flang/lib/Semantics/check-omp-structure.cpp
+++ b/flang/lib/Semantics/check-omp-structure.cpp
@@ -903,7 +903,11 @@ void OmpStructureChecker::CheckDirectiveSpelling(
     }
     llvm::StringRef name{llvm::omp::getOpenMPDirectiveName(id, v)};
     auto [kind, versions]{llvm::omp::getOpenMPDirectiveKindAndVersions(name)};
-    assert(kind == id && "Directive kind mismatch");
+    if (kind != llvm::omp::Directive::OMPD_ordered &&
+        kind != llvm::omp::Directive::OMPD_ordered_blockassoc &&
+        kind != llvm::omp::Directive::OMPD_ordered_standalone) {
+      assert(kind == id && "Directive kind mismatch");
+    }
 
     if (static_cast<int>(version) >= versions.Min) {
       continue;
@@ -1497,7 +1501,7 @@ void OmpStructureChecker::Enter(const parser::OmpBlockConstruct &x) {
         parser::omp::GetUpperName(dirId, version))};
     // ORDERED has two variants, so be explicit about which variant we think
     // this is.
-    if (dirId == llvm::omp::Directive::OMPD_ordered) {
+    if (dirId == llvm::omp::Directive::OMPD_ordered_blockassoc) {
       msg.Attach(
           beginSpec.source, "The ORDERED directive is block-associated"_en_US);
     }
@@ -1775,7 +1779,7 @@ void OmpStructureChecker::Enter(const parser::OmpBeginDirective &x) {
 
 void OmpStructureChecker::Leave(const parser::OmpBeginDirective &x) {
   switch (x.DirId()) {
-  case llvm::omp::Directive::OMPD_ordered:
+  case llvm::omp::Directive::OMPD_ordered_blockassoc:
     // [5.1] 2.19.9 Ordered Construct Restriction
     ChecksOnOrderedAsBlock();
     break;
@@ -3275,7 +3279,7 @@ void OmpStructureChecker::Enter(
 void OmpStructureChecker::Leave(
     const parser::OpenMPSimpleStandaloneConstruct &x) {
   switch (GetContext().directive) {
-  case llvm::omp::Directive::OMPD_ordered:
+  case llvm::omp::Directive::OMPD_ordered_standalone:
     // [5.1] 2.19.9 Ordered Construct Restriction
     ChecksOnOrderedAsStandalone();
     break;
@@ -5072,7 +5076,7 @@ void OmpStructureChecker::Enter(const parser::OmpClause::Depend &x) {
             version == 50 ? "SINK, SOURCE or DEPOBJ" : "SINK or SOURCE");
       }
     }
-  } else if (dir != llvm::omp::OMPD_ordered) {
+  } else if (dir != llvm::omp::OMPD_ordered_standalone) {
     if (doaDep) {
       context_.Say(GetContext().clauseSource,
           "The SINK and SOURCE dependence types can only be used with the ORDERED directive, used here in the %s construct"_err_en_US,
diff --git a/flang/lib/Semantics/openmp-utils.cpp b/flang/lib/Semantics/openmp-utils.cpp
index 731d98f1103a5..dc3d5a302e841 100644
--- a/flang/lib/Semantics/openmp-utils.cpp
+++ b/flang/lib/Semantics/openmp-utils.cpp
@@ -1586,7 +1586,7 @@ struct DoacrossFinder {
   }
 
   bool Pre(const parser::OpenMPSimpleStandaloneConstruct &x) {
-    inOrdered = x.v.DirId() == llvm::omp::Directive::OMPD_ordered;
+    inOrdered = x.v.DirId() == llvm::omp::Directive::OMPD_ordered_standalone;
     return !found;
   }
   void Post(const parser::OpenMPSimpleStandaloneConstruct &) {
diff --git a/flang/test/Lower/OpenMP/Todo/ordered-depend.f90 b/flang/test/Lower/OpenMP/Todo/ordered-depend.f90
index 9706d2be0c665..f3b787f0b3e02 100644
--- a/flang/test/Lower/OpenMP/Todo/ordered-depend.f90
+++ b/flang/test/Lower/OpenMP/Todo/ordered-depend.f90
@@ -7,7 +7,7 @@
 ! clause, which decomposition only accepts from OpenMP 5.2, while the construct
 ! itself is valid (using this spelling) since OpenMP 4.5.
 
-!CHECK: not yet implemented: OMPD_ordered
+!CHECK: not yet implemented: OMPD_ordered_standalone
 subroutine f00
   integer :: i
   !$omp do ordered(1)
diff --git a/flang/test/Lower/OpenMP/Todo/ordered.f90 b/flang/test/Lower/OpenMP/Todo/ordered.f90
index 2f91e5ed28a1a..1b4f33a490de5 100644
--- a/flang/test/Lower/OpenMP/Todo/ordered.f90
+++ b/flang/test/Lower/OpenMP/Todo/ordered.f90
@@ -1,7 +1,7 @@
 !RUN: %not_todo_cmd bbc -emit-hlfir -fopenmp -fopenmp-version=52 -o - %s 2>&1 | FileCheck %s
 !RUN: %not_todo_cmd %flang_fc1 -emit-hlfir -fopenmp -fopenmp-version=52 -o - %s 2>&1 | FileCheck %s
 
-!CHECK: not yet implemented: OMPD_ordered
+!CHECK: not yet implemented: OMPD_ordered_standalone
 subroutine f00(x)
   integer :: a(10)
 



More information about the llvm-branch-commits mailing list