[flang-commits] [flang] 8163d62 - [flang][OpenMP] Don't drop NOTHING with clauses in METADIRECTIVE (#233981)

via flang-commits flang-commits at lists.llvm.org
Wed Oct 21 08:50:32 PDT 2026


Author: Chi-Chun, Chen
Date: 2026-10-21T10:46:43-05:00
New Revision: 8163d62ded778e9a78a9245bd8c556fbe677ecde

URL: https://github.com/llvm/llvm-project/commit/8163d62ded778e9a78a9245bd8c556fbe677ecde
DIFF: https://github.com/llvm/llvm-project/commit/8163d62ded778e9a78a9245bd8c556fbe677ecde.diff

LOG: [flang][OpenMP] Don't drop NOTHING with clauses in METADIRECTIVE (#233981)

A METADIRECTIVE replacement of NOTHING was treated as having no
directive, even when it had clauses. A selected `nothing apply(...)` was
therefore lowered as a no-op, silently dropping the loop transformation.

Keep NOTHING as a replacement when it has clauses, and report it as not
yet implemented in lowering.

Assisted-by: GitHub Copilot (Claude Opus 5.5)

Added: 
    flang/test/Lower/OpenMP/Todo/metadirective-nothing-apply.f90

Modified: 
    flang/include/flang/Semantics/openmp-utils.h
    flang/lib/Lower/OpenMP/OpenMP.cpp
    flang/lib/Semantics/openmp-utils.cpp

Removed: 
    


################################################################################
diff  --git a/flang/include/flang/Semantics/openmp-utils.h b/flang/include/flang/Semantics/openmp-utils.h
index c31459f256f622..a20af4f546d7bf 100644
--- a/flang/include/flang/Semantics/openmp-utils.h
+++ b/flang/include/flang/Semantics/openmp-utils.h
@@ -279,7 +279,7 @@ struct MetadirectiveCandidate {
 
 struct MetadirectiveCandidateSet {
   llvm::SmallVector<MetadirectiveCandidate, 4> candidates;
-  /// Null represents either an explicit NOTHING fallback or no fallback.
+  /// Null represents either a clause-free NOTHING fallback or no fallback.
   const parser::OmpDirectiveSpecification *fallback{nullptr};
 };
 
@@ -313,7 +313,7 @@ llvm::SmallVector<unsigned, 4> GetMetadirectiveElsePathCandidates(
     const OmpVariantMatchContext &matchContext, SemanticsContext &context);
 
 /// Return every replacement that can be selected, retaining lower-ranked
-/// candidates after a dynamic condition. Null represents NOTHING.
+/// candidates after a dynamic condition. Null represents clause-free NOTHING.
 llvm::SmallVector<const parser::OmpDirectiveSpecification *, 4>
 GetReachableMetadirectiveVariants(const MetadirectiveCandidateSet &candidateSet,
     const OmpVariantMatchContext &matchContext, SemanticsContext &context);

diff  --git a/flang/lib/Lower/OpenMP/OpenMP.cpp b/flang/lib/Lower/OpenMP/OpenMP.cpp
index abe1df79f6aef2..26f83938207655 100644
--- a/flang/lib/Lower/OpenMP/OpenMP.cpp
+++ b/flang/lib/Lower/OpenMP/OpenMP.cpp
@@ -7652,6 +7652,8 @@ static void genMetadirective(lower::AbstractConverter &converter,
       return;
     }
     mlir::Location variantLoc = converter.genLocation(spec->source);
+    if (spec->DirId() == llvm::omp::Directive::OMPD_nothing)
+      TODO(variantLoc, "NOTHING with clauses in METADIRECTIVE");
     List<Clause> variantClauses = makeClauses(spec->Clauses(), semaCtx);
     ConstructQueue queue{
         buildConstructQueue(converter.getFirOpBuilder().getModule(), semaCtx,

diff  --git a/flang/lib/Semantics/openmp-utils.cpp b/flang/lib/Semantics/openmp-utils.cpp
index 0c86239136553c..4004c1897f56f3 100644
--- a/flang/lib/Semantics/openmp-utils.cpp
+++ b/flang/lib/Semantics/openmp-utils.cpp
@@ -2563,20 +2563,21 @@ std::optional<MetadirectiveCandidateSet> BuildMetadirectiveCandidateSet(
         &modifiers->front().u);
   };
 
-  auto getDirectiveVariant = [](const parser::OmpClause::When &whenClause)
+  auto getVariant = [](const parser::OmpDirectiveSpecification &spec) {
+    // Keep NOTHING with clauses, e.g. APPLY, so they are not silently dropped.
+    return spec.DirId() == llvm::omp::Directive::OMPD_nothing &&
+            spec.Clauses().v.empty()
+        ? nullptr
+        : &spec;
+  };
+
+  auto getDirectiveVariant = [&](const parser::OmpClause::When &whenClause)
       -> std::pair<const parser::OmpDirectiveSpecification *, bool> {
     const auto &optionalSpec{std::get<1>(whenClause.v.t)};
     if (!optionalSpec) {
       return {nullptr, false};
     }
-    if (optionalSpec->value().DirId() == llvm::omp::Directive::OMPD_nothing) {
-      return {nullptr, true};
-    }
-    return {&optionalSpec->value(), true};
-  };
-
-  auto getFallbackVariant = [](const parser::OmpDirectiveSpecification &spec) {
-    return spec.DirId() == llvm::omp::Directive::OMPD_nothing ? nullptr : &spec;
+    return {getVariant(optionalSpec->value()), true};
   };
 
   for (const parser::OmpClause &clause : clauses.v) {
@@ -2688,11 +2689,11 @@ std::optional<MetadirectiveCandidateSet> BuildMetadirectiveCandidateSet(
     } else if (const auto *otherwiseClause{
                    std::get_if<parser::OmpClause::Otherwise>(&clause.u)}) {
       if (otherwiseClause->v && otherwiseClause->v->v) {
-        result.fallback = getFallbackVariant(otherwiseClause->v->v->value());
+        result.fallback = getVariant(otherwiseClause->v->v->value());
       }
     } else if (const auto *defaultVariantClause{
                    std::get_if<parser::OmpClause::DefaultVariant>(&clause.u)}) {
-      result.fallback = getFallbackVariant(defaultVariantClause->v.v.value());
+      result.fallback = getVariant(defaultVariantClause->v.v.value());
     }
   }
   return result;

diff  --git a/flang/test/Lower/OpenMP/Todo/metadirective-nothing-apply.f90 b/flang/test/Lower/OpenMP/Todo/metadirective-nothing-apply.f90
new file mode 100644
index 00000000000000..0bc0caa49c95b8
--- /dev/null
+++ b/flang/test/Lower/OpenMP/Todo/metadirective-nothing-apply.f90
@@ -0,0 +1,23 @@
+! RUN: %not_todo_cmd %flang_fc1 -cpp -emit-hlfir -fopenmp \
+! RUN:   -fopenmp-version=60 -o - %s 2>&1 | FileCheck %s
+! RUN: %not_todo_cmd %flang_fc1 -cpp -DFALLBACK -emit-hlfir -fopenmp \
+! RUN:   -fopenmp-version=60 -o - %s 2>&1 | FileCheck %s
+
+! NOTHING with APPLY must not be silently lowered as a no-op, whether it is
+! selected by a WHEN clause or as the fallback.
+! CHECK: not yet implemented: NOTHING with clauses in METADIRECTIVE
+
+subroutine nothing_apply(n, a)
+  integer :: n, a(n), i
+#ifdef FALLBACK
+  !$omp metadirective when(user={condition(.false.)}: nothing) &
+  !$omp& otherwise(nothing apply(reverse))
+#else
+  !$omp metadirective &
+  !$omp& when(user={condition(.true.)}: nothing apply(reverse)) &
+  !$omp& otherwise(nothing)
+#endif
+  do i = 1, n
+    a(i) = i
+  end do
+end subroutine


        


More information about the flang-commits mailing list