[flang-commits] [flang] [Flang][OpenMP]Support for lowering task_reduction and in_reduction to MLIR (PR #111155)

Kaviya Rajendiran via flang-commits flang-commits at lists.llvm.org
Mon May 5 01:51:36 PDT 2025


kaviya2510 wrote:

`According to the OpenMP specification, the rules for variables with implicitly determined data-sharing attributes are:
* In a _parallel_ construct, if no _default_ clause is present, these variables are **shared**
* In a task generating construct, if no _default_ clause is present, a variable for which the data-sharing attribute is not determined by the rules aboveand that in the enclosing context is determined to be shared by all implicit tasks bound to the current team is **shared**
* In an orphaned task generating construct, if no _default_ clause is present, dummy arguments are **firstprivate**
* In a task generating construct, if no _default_ clause is present, a variable for which the data-sharing attribute is not determined by the rules above is **firstprivate**`

```fortran
subroutine omp_task_in_reduction()
   integer i
   i = 0
   !$omp task in_reduction(+:i)
   i = i + 1
   !$omp end task
end subroutine omp_task_in_reduction
```
In the above example, without any explicit data sharing attribute the variable `i` would normally considered as `firstprivate` in task construct. However, since the variable`i` appears in the `in_reduction` clause, its data-sharing attribute should not be firstprivate.

With the current flow, the compiler incorrectly marks the data-sharing attribute of `i` as `firstprivate`, based on the implicit rule for task constructs and as a result it generate the below mlir during lowering.
```mlir
 omp.private {type = firstprivate} @_QFomp_task_in_reductionEi_firstprivate_ref_i32 : !fir.ref<i32> alloc {
  ^bb0(%arg0: !fir.ref<i32>):
    %0 = fir.alloca i32 {bindc_name = "i", pinned, uniq_name = "_QFomp_task_in_reductionEi"}
    %1:2 = hlfir.declare %0 {uniq_name = "_QFomp_task_in_reductionEi"} : (!fir.ref<i32>) -> (!fir.ref<i32>, !fir.ref<i32>)
    omp.yield(%1#0 : !fir.ref<i32>)
  } copy {
  ^bb0(%arg0: !fir.ref<i32>, %arg1: !fir.ref<i32>):
    %0 = fir.load %arg0 : !fir.ref<i32>
    hlfir.assign %0 to %arg1 : i32, !fir.ref<i32>
    omp.yield(%arg1 : !fir.ref<i32>)
  }
```
I am felling that my earlier fix in DataSharingProcessor.cpp is not correct. Instead of skipping collecting symbols in DataSharingProcessor.cpp, I added a new change which detects the dsa of variable `i` as in_reduction and skip marking it as  firstprivate.

@tblah , could you please take a look at it and review my changes?

https://github.com/llvm/llvm-project/pull/111155


More information about the flang-commits mailing list