Issue |
90869
|
Summary |
[mlir][openmp] - LLVM IR codegen for `omp.task` in MLIR does not honor dependencies on a task in the presence of the `if` clause
|
Labels |
openmp,
mlir,
llvm:openmpirbuilder
|
Assignees |
|
Reporter |
bhandarkar-pranav
|
In the following piece of MLIR code, the if condition in the `if` clause on the `omp.task` operation is a compile time constant. Therefore, the else path willl be taken. If the `if` clause in an OpenMP task evaluates to false, then per the OpenMP spec an undeferred task is generated. This undeferred task should still honor all dependencies specified by the `depend` clause (if present).
```
module attributes {dlti.dl_spec = #dlti.dl_spec<#dlti.dl_entry<!llvm.ptr<270>, dense<32> : vector<4xi64>>, #dlti.dl_entry<i64, dense<64> : vector<2xi64>>, #dlti.dl_entry<i32, dense<32> : vector<2xi64>>, #dlti.dl_entry<!llvm.ptr<27\
2>, dense<64> : vector<4xi64>>, #dlti.dl_entry<!llvm.ptr<271>, dense<32> : vector<4xi64>>, #dlti.dl_entry<f16, dense<16> : vector<2xi64>>, #dlti.dl_entry<f64, dense<64> : vector<2xi64>>, #dlti.dl_entry<f128, dense<128> : vector<2x\
i64>>, #dlti.dl_entry<f80, dense<128> : vector<2xi64>>, #dlti.dl_entry<i128, dense<128> : vector<2xi64>>, #dlti.dl_entry<i16, dense<16> : vector<2xi64>>, #dlti.dl_entry<i8, dense<8> : vector<2xi64>>, #dlti.dl_entry<i1, dense<8> : \
vector<2xi64>>, #dlti.dl_entry<!llvm.ptr, dense<64> : vector<4xi64>>, #dlti.dl_entry<"dlti.endianness", "little">, #dlti.dl_entry<"dlti.stack_alignment", 128 : i64>>, fir.defaultkind = "a1c4d8i4l4r4", fir.kindmap = "", llvm.data_l\
ayout = "e-m:e-p270:32:32-p271:32:32-p272:64:64-i64:64-i128:128-f80:128-n8:16:32:64-S128", llvm.target_triple = "x86_64-unknown-linux-gnu", omp.is_gpu = false, omp.is_target_device = false, omp.version = #omp.version<version = 11>\
} {
llvm.func @foo_(%arg0: !llvm.ptr {fir.bindc_name = "n"}, %arg1: !llvm.ptr {fir.bindc_name = "r"}) attributes {fir.internal_name = "_QPfoo"} {
%0 = llvm.mlir.constant(false) : i1
omp.task if(%0) depend(taskdependin -> %arg0 : !llvm.ptr) {
%1 = llvm.load %arg0 : !llvm.ptr -> i32
llvm.store %1, %arg1 : i32, !llvm.ptr
omp.terminator
}
llvm.return
}
llvm.func @llvm.stacksave.p0() -> !llvm.ptr attributes {sym_visibility = "private"}
llvm.func @llvm.stackrestore.p0(!llvm.ptr) attributes {sym_visibility = "private"}
}
```
However, when the LLVM IR is generated, I see this
```
%8 = call ptr @__kmpc_omp_task_alloc(ptr @1, i32 %omp_global_thread_num, i32 1, i64 40, i64 16, ptr @foo_..omp_par)
%9 = load ptr, ptr %8, align 8
call void @llvm.memcpy.p0.p0.i64(ptr align 1 %9, ptr align 1 %structArg, i64 16, i1 false)
br i1 false, label %10, label %12
10: ; preds = %codeRepl
%11 = call i32 @__kmpc_omp_task_with_deps(ptr @1, i32 %omp_global_thread_num, ptr %8, i32 1, ptr %.dep.arr.addr, i32 0, ptr null)
br label %13
12: ; preds = %codeRepl
call void @__kmpc_omp_task_begin_if0(ptr @1, i32 %omp_global_thread_num, ptr %8)
call void @foo_..omp_par(i32 %omp_global_thread_num, ptr %8)
call void @__kmpc_omp_task_complete_if0(ptr @1, i32 %omp_global_thread_num, ptr %8)
br label %13
```
In the else case (Basic block `12`), there is **no call made to the OpenMP runtime to make the task wait until dependencies are resolved.**
To reproduce this, save the above code in test.mlir and then use the following command
```
mlir-translate -mlir-to-llvmir test.mlir -o test.ll
```
Here is the equivalent code generated by clang, which IMO is correct (Showing only the else codegen)
```
call void @__kmpc_omp_taskwait_deps_51(ptr @1, i32 %0, i32 1, ptr %8, i32 0, ptr null, i32 0)
call void @__kmpc_omp_task_begin_if0(ptr @1, i32 %0, ptr %1)
%14 = call i32 @.omp_task_entry.(i32 %0, ptr %1) #3
call void @__kmpc_omp_task_complete_if0(ptr @1, i32 %0, ptr %1)
%15 = load i32, ptr %a, align 4
ret i32 %15
```
_______________________________________________
llvm-bugs mailing list
llvm-bugs@lists.llvm.org
https://lists.llvm.org/cgi-bin/mailman/listinfo/llvm-bugs