[flang-commits] [flang] [llvm] [mlir] [Flang][OpenMP] Support 'nowait' clause on taskwait (PR #219247)

Phoebe Linck via flang-commits flang-commits at lists.llvm.org
Sun Sep 27 20:50:14 PDT 2026


https://github.com/phi-bee updated https://github.com/llvm/llvm-project/pull/219247

>From 56d533c47aafa6d5a5fd040c258a3fbda325b91a Mon Sep 17 00:00:00 2001
From: Phoebe Linck <phoebe.linck at hpe.com>
Date: Thu, 27 Aug 2026 11:12:51 -0500
Subject: [PATCH] [Flang][OpenMP] Support 'nowait' clause on taskwait

---
 flang/lib/Lower/OpenMP/OpenMP.cpp                     |  2 +-
 flang/lib/Semantics/check-omp-structure.cpp           | 10 ++++++++++
 flang/test/Lower/OpenMP/Todo/taskwait-nowait.f90      |  8 --------
 flang/test/Semantics/OpenMP/taskwait-nowait.f90       |  8 ++++++++
 llvm/include/llvm/Frontend/OpenMP/OMPIRBuilder.h      |  4 +++-
 llvm/lib/Frontend/OpenMP/OMPIRBuilder.cpp             |  5 +++--
 mlir/lib/Dialect/OpenMP/IR/OpenMPDialect.cpp          |  2 +-
 .../Dialect/OpenMP/OpenMPToLLVMIRTranslation.cpp      |  4 ++--
 mlir/test/Target/LLVMIR/openmp-taskwait-depend.mlir   |  7 +++++++
 mlir/test/Target/LLVMIR/openmp-todo.mlir              | 11 -----------
 10 files changed, 35 insertions(+), 26 deletions(-)
 delete mode 100644 flang/test/Lower/OpenMP/Todo/taskwait-nowait.f90
 create mode 100644 flang/test/Semantics/OpenMP/taskwait-nowait.f90

diff --git a/flang/lib/Lower/OpenMP/OpenMP.cpp b/flang/lib/Lower/OpenMP/OpenMP.cpp
index df14d13b76a4b..c22bd51238e2f 100644
--- a/flang/lib/Lower/OpenMP/OpenMP.cpp
+++ b/flang/lib/Lower/OpenMP/OpenMP.cpp
@@ -2785,7 +2785,7 @@ static void genTaskwaitClauses(lower::AbstractConverter &converter,
   lower::StatementContext stmtCtx;
   lower::SymMap &symTable = converter.getSymbolMap();
   cp.processDepend(symTable, stmtCtx, clauseOps);
-  cp.processTODO<clause::Nowait>(loc, llvm::omp::Directive::OMPD_taskwait);
+  cp.processNowait(clauseOps);
 }
 
 static void genWorkshareClauses(lower::AbstractConverter &converter,
diff --git a/flang/lib/Semantics/check-omp-structure.cpp b/flang/lib/Semantics/check-omp-structure.cpp
index edcd5f9ede237..cc80bcb8ca570 100644
--- a/flang/lib/Semantics/check-omp-structure.cpp
+++ b/flang/lib/Semantics/check-omp-structure.cpp
@@ -4017,6 +4017,16 @@ void OmpStructureChecker::Leave(const parser::OmpClauseList &x) {
       firstClause = clause;
     }
   }
+
+  // [5.2:308] The nowait clause may only appear on a taskwait directive if the
+  // depend clause is present.
+  if (GetContext().directive == llvm::omp::OMPD_taskwait) {
+    if (FindClause(llvm::omp::Clause::OMPC_nowait) &&
+        !FindClause(llvm::omp::Clause::OMPC_depend)) {
+      context_.Say(GetContext().clauseSource,
+          "A NOWAIT clause may only appear on TASKWAIT if a DEPEND clause is present"_err_en_US);
+    }
+  }
 }
 
 void OmpStructureChecker::Enter(const parser::OmpClause &x) {
diff --git a/flang/test/Lower/OpenMP/Todo/taskwait-nowait.f90 b/flang/test/Lower/OpenMP/Todo/taskwait-nowait.f90
deleted file mode 100644
index 21e8609b08ba3..0000000000000
--- a/flang/test/Lower/OpenMP/Todo/taskwait-nowait.f90
+++ /dev/null
@@ -1,8 +0,0 @@
-! RUN: %not_todo_cmd bbc -emit-fir -fopenmp -o - %s -fopenmp-version=51 2>&1 | FileCheck %s
-! RUN: %not_todo_cmd %flang_fc1 -emit-fir -fopenmp -o - %s -fopenmp-version=51 2>&1 | FileCheck %s
-
-! CHECK: not yet implemented: Unhandled clause NOWAIT in TASKWAIT construct
-subroutine omp_tw_nowait
-  !$omp taskwait nowait
-end subroutine omp_tw_nowait
-
diff --git a/flang/test/Semantics/OpenMP/taskwait-nowait.f90 b/flang/test/Semantics/OpenMP/taskwait-nowait.f90
new file mode 100644
index 0000000000000..544a87db56a7f
--- /dev/null
+++ b/flang/test/Semantics/OpenMP/taskwait-nowait.f90
@@ -0,0 +1,8 @@
+! RUN: %python %S/../test_errors.py %s %flang -fopenmp -fopenmp-version=51
+subroutine sub
+  integer :: x
+  !$omp taskwait depend(in: x) nowait
+  !ERROR: A NOWAIT clause may only appear on TASKWAIT if a DEPEND clause is present
+  !$omp taskwait nowait
+end subroutine sub
+
diff --git a/llvm/include/llvm/Frontend/OpenMP/OMPIRBuilder.h b/llvm/include/llvm/Frontend/OpenMP/OMPIRBuilder.h
index b87f051c6e6a4..0114be5f194b1 100644
--- a/llvm/include/llvm/Frontend/OpenMP/OMPIRBuilder.h
+++ b/llvm/include/llvm/Frontend/OpenMP/OMPIRBuilder.h
@@ -1576,8 +1576,10 @@ class OpenMPIRBuilder {
   ///
   /// \param Loc The location where the taskwait directive was encountered.
   /// \param Dependencies dependencies as specified by the 'depend' clause.
+  /// \param IsNowait True when a 'nowait' clause is present
   LLVM_ABI void createTaskwait(const LocationDescription &Loc,
-                               DependenciesInfo Dependencies = {});
+                               DependenciesInfo Dependencies = {},
+                               bool IsNowait = false);
 
   ///  Return the LLVM struct type matching runtime `kmp_task_affinity_info_t`.
   /// `{ kmp_intptr_t base_addr; size_t len; flags (bitfield storage as i32) }`
diff --git a/llvm/lib/Frontend/OpenMP/OMPIRBuilder.cpp b/llvm/lib/Frontend/OpenMP/OMPIRBuilder.cpp
index 3173fecc5d526..be466e6d0d14b 100644
--- a/llvm/lib/Frontend/OpenMP/OMPIRBuilder.cpp
+++ b/llvm/lib/Frontend/OpenMP/OMPIRBuilder.cpp
@@ -2443,7 +2443,8 @@ void OpenMPIRBuilder::emitTaskwaitImpl(const LocationDescription &Loc) {
 }
 
 void OpenMPIRBuilder::createTaskwait(const LocationDescription &Loc,
-                                     DependenciesInfo Dependencies) {
+                                     DependenciesInfo Dependencies,
+                                     bool IsNowait) {
   if (!updateToLocation(Loc))
     return;
 
@@ -2482,7 +2483,7 @@ void OpenMPIRBuilder::createTaskwait(const LocationDescription &Loc,
         DepArray,
         ConstantInt::get(Builder.getInt32Ty(), 0),
         ConstantPointerNull::get(PointerType::getUnqual(M.getContext())),
-        ConstantInt::get(Builder.getInt32Ty(), false)};
+        ConstantInt::get(Builder.getInt32Ty(), IsNowait)};
     createRuntimeFunctionCall(
         getOrCreateRuntimeFunctionPtr(
             omp::RuntimeFunction::OMPRTL___kmpc_omp_taskwait_deps_51),
diff --git a/mlir/lib/Dialect/OpenMP/IR/OpenMPDialect.cpp b/mlir/lib/Dialect/OpenMP/IR/OpenMPDialect.cpp
index ed144f7b28983..3029c9c56f408 100644
--- a/mlir/lib/Dialect/OpenMP/IR/OpenMPDialect.cpp
+++ b/mlir/lib/Dialect/OpenMP/IR/OpenMPDialect.cpp
@@ -5009,7 +5009,7 @@ void TaskwaitOp::build(OpBuilder &builder, OperationState &state,
       /*depend_vars=*/clauses.dependVars,
       /*depend_iterated_kinds=*/makeArrayAttr(ctx, clauses.dependIteratedKinds),
       /*depend_iterated=*/ValueRange(clauses.dependIterated),
-      /*nowait=*/false);
+      /*nowait=*/clauses.nowait);
 }
 
 //===----------------------------------------------------------------------===//
diff --git a/mlir/lib/Target/LLVMIR/Dialect/OpenMP/OpenMPToLLVMIRTranslation.cpp b/mlir/lib/Target/LLVMIR/Dialect/OpenMP/OpenMPToLLVMIRTranslation.cpp
index d8b596ad9c83e..2812feb5d8bb2 100644
--- a/mlir/lib/Target/LLVMIR/Dialect/OpenMP/OpenMPToLLVMIRTranslation.cpp
+++ b/mlir/lib/Target/LLVMIR/Dialect/OpenMP/OpenMPToLLVMIRTranslation.cpp
@@ -571,7 +571,6 @@ static LogicalResult checkImplementationStatus(Operation &op) {
         checkAllocate(op, result);
         checkTaskReductionByref(op, result);
       })
-      .Case([&](omp::TaskwaitOp op) { checkNowait(op, result); })
       .Case([&](omp::DispatchOp op) {
         // OpenMP 5.1 dispatch creates an explicit task; nowait controls whether
         // it is included. Diagnose unsupported asynchronous tasking before 5.2,
@@ -4652,7 +4651,8 @@ convertOmpTaskwaitOp(omp::TaskwaitOp twOp, llvm::IRBuilderBase &builder,
     return failure();
   }
 
-  moduleTranslation.getOpenMPBuilder()->createTaskwait(builder, dds);
+  moduleTranslation.getOpenMPBuilder()->createTaskwait(builder, dds,
+                                                       twOp.getNowait());
   if (dds.DepArray) {
     builder.CreateFree(dds.DepArray);
   }
diff --git a/mlir/test/Target/LLVMIR/openmp-taskwait-depend.mlir b/mlir/test/Target/LLVMIR/openmp-taskwait-depend.mlir
index fd29efeca3b9f..305cbf9c27518 100644
--- a/mlir/test/Target/LLVMIR/openmp-taskwait-depend.mlir
+++ b/mlir/test/Target/LLVMIR/openmp-taskwait-depend.mlir
@@ -51,3 +51,10 @@ llvm.func @taskwait_depend_iterator(%x: !llvm.ptr) {
 // CHECK: %[[omp_global_thread_num:.+]] = call i32 @__kmpc_global_thread_num({{.+}})
 // CHECK: call void @__kmpc_omp_taskwait_deps_51(ptr @{{.+}}, i32 %[[omp_global_thread_num]], i32 10, ptr %[[dep_arr_addr]], i32 0, ptr null, i32 0)
 // CHECK: tail call void @free(ptr %[[dep_arr_addr:.+]])
+
+llvm.func @taskwait_depend_nowait(%x: !llvm.ptr) {
+  omp.taskwait depend(taskdependout -> %x : !llvm.ptr) nowait
+  llvm.return
+}
+// CHECK-LABEL: define void @taskwait_depend_nowait
+// CHECK: call void @__kmpc_omp_taskwait_deps_51(ptr @{{.+}}, i32 %{{.+}}, i32 1, ptr %{{.+}}, i32 0, ptr null, i32 1)
diff --git a/mlir/test/Target/LLVMIR/openmp-todo.mlir b/mlir/test/Target/LLVMIR/openmp-todo.mlir
index 43063cdf1c82d..ebc66e4a7e765 100644
--- a/mlir/test/Target/LLVMIR/openmp-todo.mlir
+++ b/mlir/test/Target/LLVMIR/openmp-todo.mlir
@@ -627,17 +627,6 @@ llvm.func @taskloop_reduction_two_arg_init(%lb : i32, %ub : i32, %step : i32, %x
 
 // -----
 
-llvm.func @taskwait_nowait() {
-  // expected-error at below {{not yet implemented: Unhandled clause nowait in omp.taskwait operation}}
-  // expected-error at below {{LLVM Translation failed for operation: omp.taskwait}}
-  omp.taskwait nowait {
-    omp.terminator
-  }
-  llvm.return
-}
-
-// -----
-
 // `nowait` on dispatch is unimplemented for OpenMP <= 5.1; from 5.2 it has no
 // effect and is accepted (see openmp-dispatch.mlir).
 module attributes {omp.version = #omp.version<version = 51>} {



More information about the flang-commits mailing list