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

Reply via email to