[Mlir-commits] [flang] [llvm] [mlir] [Flang][OpenMP] Fix Flang crash and incorrect ordering with OpenMP detached task (PR #194840)
Urvi Rav
llvmlistbot at llvm.org
Wed Apr 29 23:39:21 PDT 2026
https://github.com/ravurvi20 updated https://github.com/llvm/llvm-project/pull/194840
>From 1af3a3eda354ec29ed111f2edfcd6df234865e5f Mon Sep 17 00:00:00 2001
From: Urvi Rav <urvi.rav20 at gmail.com>
Date: Wed, 29 Apr 2026 07:23:20 -0500
Subject: [PATCH 1/2] Fix detach task if(false) lowering and semantics
---
.../flang/Semantics/openmp-directive-sets.h | 1 +
flang/lib/Semantics/resolve-directives.cpp | 11 +++++++++
llvm/lib/Frontend/OpenMP/OMPIRBuilder.cpp | 15 ++++++++----
mlir/test/Target/LLVMIR/omptask_if_false.mlir | 24 +++++++++++++++----
4 files changed, 43 insertions(+), 8 deletions(-)
diff --git a/flang/include/flang/Semantics/openmp-directive-sets.h b/flang/include/flang/Semantics/openmp-directive-sets.h
index 5e9979d032028..99aed83c654de 100644
--- a/flang/include/flang/Semantics/openmp-directive-sets.h
+++ b/flang/include/flang/Semantics/openmp-directive-sets.h
@@ -85,6 +85,7 @@ static const OmpDirectiveSet topParallelSet{
Directive::OMPD_parallel_loop,
Directive::OMPD_parallel_masked_taskloop,
Directive::OMPD_parallel_masked_taskloop_simd,
+ Directive::OMPD_parallel_master,
Directive::OMPD_parallel_master_taskloop,
Directive::OMPD_parallel_master_taskloop_simd,
Directive::OMPD_parallel_sections,
diff --git a/flang/lib/Semantics/resolve-directives.cpp b/flang/lib/Semantics/resolve-directives.cpp
index 8712c361965cb..fae47a829b140 100644
--- a/flang/lib/Semantics/resolve-directives.cpp
+++ b/flang/lib/Semantics/resolve-directives.cpp
@@ -766,6 +766,17 @@ class OmpAttributeVisitor : DirectiveAttributeVisitor<llvm::omp::Directive> {
*parser::omp::GetOmpObjectList(x), Symbol::Flag::OmpLastPrivate);
return false;
}
+ bool Pre(const parser::OmpClause::Detach &x) {
+ // OpenMP 5.0: Variables in detach clause have predetermined shared
+ // data-sharing attribute
+ if (const auto *name{parser::Unwrap<parser::Name>(x.v.v)}) {
+ if (auto *symbol{name->symbol})
+ SetSymbolDSA(*symbol,
+ Symbol::Flags{
+ Symbol::Flag::OmpShared, Symbol::Flag::OmpPreDetermined});
+ }
+ return false;
+ }
bool Pre(const parser::OmpClause::Copyin &x) {
ResolveOmpObjectList(x.v, Symbol::Flag::OmpCopyIn);
return false;
diff --git a/llvm/lib/Frontend/OpenMP/OMPIRBuilder.cpp b/llvm/lib/Frontend/OpenMP/OMPIRBuilder.cpp
index 5a4f12d91d540..dfd1621617bec 100644
--- a/llvm/lib/Frontend/OpenMP/OMPIRBuilder.cpp
+++ b/llvm/lib/Frontend/OpenMP/OMPIRBuilder.cpp
@@ -2730,20 +2730,27 @@ OpenMPIRBuilder::InsertPointOrErrorTy OpenMPIRBuilder::createTask(
// Task is untied iff (Flags & 1) == 0.
// Task is final iff (Flags & 2) == 2.
// Task is not final iff (Flags & 2) == 0.
- // Task is mergeable iff (Flags & 4) == 4.
- // Task is not mergeable iff (Flags & 4) == 0.
+ // Tasks lowered from a constant false `if` clause use the merged-if0
+ // runtime path and must execute immediately while still going through the
+ // normal task scheduling entrypoints.
+ // Task is detachable iff (Flags & 64) == 64.
+ // Task is not detachable iff (Flags & 64) == 0.
// Task is priority iff (Flags & 32) == 32.
// Task is not priority iff (Flags & 32) == 0.
// TODO: Handle the other flags.
Value *Flags = Builder.getInt32(Tied);
+ auto *ConstIfCondition = dyn_cast_or_null<ConstantInt>(IfCondition);
+ bool UseMergedIf0Path = ConstIfCondition && ConstIfCondition->isZero();
if (Final) {
Value *FinalFlag =
Builder.CreateSelect(Final, Builder.getInt32(2), Builder.getInt32(0));
Flags = Builder.CreateOr(FinalFlag, Flags);
}
- if (Mergeable)
+ if (Mergeable || UseMergedIf0Path)
Flags = Builder.CreateOr(Builder.getInt32(4), Flags);
+ if (EventHandle)
+ Flags = Builder.CreateOr(Builder.getInt32(64), Flags);
if (Priority)
Flags = Builder.CreateOr(Builder.getInt32(32), Flags);
@@ -2863,7 +2870,7 @@ OpenMPIRBuilder::InsertPointOrErrorTy OpenMPIRBuilder::createTask(
// br label %exit
// exit:
// ...
- if (IfCondition) {
+ if (IfCondition && !UseMergedIf0Path) {
// `SplitBlockAndInsertIfThenElse` requires the block to have a
// terminator.
splitBB(Builder, /*CreateBranch=*/true, "if.end");
diff --git a/mlir/test/Target/LLVMIR/omptask_if_false.mlir b/mlir/test/Target/LLVMIR/omptask_if_false.mlir
index c6014a76add6d..7f71496b9a605 100644
--- a/mlir/test/Target/LLVMIR/omptask_if_false.mlir
+++ b/mlir/test/Target/LLVMIR/omptask_if_false.mlir
@@ -10,8 +10,24 @@ llvm.func @foo_(%arg0: !llvm.ptr {fir.bindc_name = "n"}, %arg1: !llvm.ptr {fir.b
llvm.return
}
-// CHECK: call void @__kmpc_omp_wait_deps
-// CHECK-NEXT: call void @__kmpc_omp_task_begin_if0
-// CHECK-NEXT: call void @foo_..omp_par
-// CHECK-NEXT: call void @__kmpc_omp_task_complete_if0
+// CHECK: call ptr @__kmpc_omp_task_alloc(ptr @{{.+}}, i32 %{{.+}}, i32 5, i64 40, i64 16, ptr @foo_..omp_par)
+// CHECK: call i32 @__kmpc_omp_task_with_deps(ptr @{{.+}}, i32 %{{.+}}, ptr %{{.+}}, i32 1, ptr %{{.+}}, i32 0, ptr null)
+
+// CHECK-LABEL: define void @foo_detach_if_false
+llvm.func @foo_detach_if_false(%arg0: !llvm.ptr {fir.bindc_name = "n"}, %arg1: !llvm.ptr {fir.bindc_name = "ev"}) {
+ %0 = llvm.mlir.constant(false) : i1
+ omp.task if(%0) depend(taskdependin -> %arg0 : !llvm.ptr) detach(%arg1 : !llvm.ptr) {
+ omp.terminator
+ }
+ llvm.return
+}
+
+// CHECK: %[[TID:.+]] = call i32 @__kmpc_global_thread_num(ptr @{{.+}})
+// CHECK: %[[TASK:.+]] = call ptr @__kmpc_omp_task_alloc(ptr @{{.+}}, i32 %[[TID]], i32 69, i64 40, i64 0, ptr @foo_detach_if_false..omp_par)
+// CHECK: %[[EVENT:.+]] = call ptr @__kmpc_task_allow_completion_event(ptr @{{.+}}, i32 %[[TID]], ptr %[[TASK]])
+// CHECK: %[[INT_EVENT:.+]] = ptrtoint ptr %[[EVENT]] to i64
+// CHECK: store i64 %[[INT_EVENT]], ptr %{{.+}}, align 4
+// CHECK: call i32 @__kmpc_omp_task_with_deps(ptr @{{.+}}, i32 %[[TID]], ptr %[[TASK]], i32 1, ptr %{{.+}}, i32 0, ptr null)
+// CHECK-NOT: @__kmpc_omp_task_begin_if0
+// CHECK-NOT: @__kmpc_omp_task_complete_if0
>From 18f110c9c9ccecf3fbcb198d7142f7033f256cf9 Mon Sep 17 00:00:00 2001
From: Urvi Rav <urvi.rav20 at gmail.com>
Date: Thu, 30 Apr 2026 01:38:38 -0500
Subject: [PATCH 2/2] added OMPD_parallel_masked
---
flang/include/flang/Semantics/openmp-directive-sets.h | 1 +
1 file changed, 1 insertion(+)
diff --git a/flang/include/flang/Semantics/openmp-directive-sets.h b/flang/include/flang/Semantics/openmp-directive-sets.h
index 99aed83c654de..b99dd8fe07204 100644
--- a/flang/include/flang/Semantics/openmp-directive-sets.h
+++ b/flang/include/flang/Semantics/openmp-directive-sets.h
@@ -83,6 +83,7 @@ static const OmpDirectiveSet topParallelSet{
Directive::OMPD_parallel_do,
Directive::OMPD_parallel_do_simd,
Directive::OMPD_parallel_loop,
+ Directive::OMPD_parallel_masked,
Directive::OMPD_parallel_masked_taskloop,
Directive::OMPD_parallel_masked_taskloop_simd,
Directive::OMPD_parallel_master,
More information about the Mlir-commits
mailing list