[flang-commits] [flang] [flang][OpenMP] Lower DO and SIMD variants in metadirectives (PR #210810)

via flang-commits flang-commits at lists.llvm.org
Mon Jul 27 22:07:26 PDT 2026


================
@@ -753,11 +754,53 @@ void OmpStructureChecker::Leave(const parser::OmpDirectiveSpecification &x) {
   }
 }
 
+void OmpStructureChecker::BeginMetadirectiveSelection() {
+  metadirectiveSelectionStarts_.push_back(metadirectiveLoopVariants_.size());
+}
+
+void OmpStructureChecker::EndMetadirectiveSelection(
+    const parser::OmpClauseList &clauses) {
+  CHECK(!metadirectiveSelectionStarts_.empty());
+  std::size_t firstVariant{metadirectiveSelectionStarts_.back()};
+  metadirectiveSelectionStarts_.pop_back();
+  if (firstVariant == metadirectiveLoopVariants_.size()) {
+    return;
+  }
+
+  llvm::SmallVector<llvm::omp::TraitProperty, 8> constructTraits;
+  for (const LoopOrConstruct &item : constructStack_) {
+    if (const auto *construct{
+            std::get_if<const parser::OpenMPConstruct *>(&item)}) {
+      AppendConstructTraitsForDirective(
+          parser::omp::GetOmpDirectiveName(**construct).v, constructTraits);
+    }
+  }
+  OmpVariantMatchContext matchContext{context_, constructTraits};
+  std::optional<MetadirectiveCandidateSet> candidateSet{
+      BuildMetadirectiveCandidateSet(clauses, context_, matchContext)};
+  if (!candidateSet) {
+    // Keep every variant when selection cannot yet model a selector.
+    return;
+  }
+
+  llvm::SmallVector<const parser::OmpDirectiveSpecification *, 4> reachable{
+      GetReachableMetadirectiveVariants(*candidateSet, matchContext)};
+  auto first{metadirectiveLoopVariants_.begin() + firstVariant};
+  metadirectiveLoopVariants_.erase(
----------------
MattPD wrote:

This erase drops variants that `GetReachableMetadirectiveVariants` reports unreachable, but the match context built during semantics comes from the parse-tree ancestry, so it cannot include a construct an enclosing metadirective selected, whereas lowering's `collectEnclosingConstructTraits` does see it.

For an inner `when(construct={parallel}: do)` over a `real` iteration variable, the type error fires when the enclosing `parallel` is written directly and is silent when an outer metadirective selects it, although lowering still selects the inner variant and reaches the enclosing-data-environment TODO. As far as I can tell the risk is one-directional: the erase can skip a diagnostic, but it will not produce a false error.

That TODO masks the consequence today, since every trait-bearing op is also in the data-environment set. It is also the TODO this work is heading toward removing. Would you prefer a conservative erase, such as skipping it when the metadirective has an enclosing OpenMP construct?

https://github.com/llvm/llvm-project/pull/210810


More information about the flang-commits mailing list