Issue 91205
Summary [flang][OpenMP] `barrier` inserted in wrong place for `copyin`
Labels flang
Assignees kparzysz
Reporter kparzysz
    Handling of the `parallel` directive with a `copyin` clause happens in three steps:
1. Insert `threadprivate` operations into the body of the `parallel` op
2. Insert copies from the outer threadprivate variables into their local counterparts in the parallel region
3. Insert a `barrier` operation after the copies (at least that's the intent).

The issue is that step 3 inserts the barrier after the most recently generated copy.  This does not have to be the after the last copy (in the execution order), since the order of insertions of the copies in step 2 is not necessarily the same as the order in which they will be executed.

Step 1 utilizes `converter.collectSymbolSet` to get the threadprivate variables.  The variables will be ordered with respect to their appearance order in the PFT. If `x1` is seen before `x2` in the PFT, then their `threadprivate` op order will follow that:
```
x1 = threadprivate
x2 = threadprivate
```
Then, the `copyin` clauses are processed in step 2. If they are ordered in such a way that `x2` appears before `x1`, then the first copy to insert will be that for `x2`:
```
x1 = threadprivate
x2 = threadprivate
assign
```
followed by
```
x1 = threadprivate
assign  (inserted second)
x2 = threadprivate
assign  (inserted first)
```
Now, the `barrier` op is inserted, and we end up with
```
x1 = threadprivate
assign (inserted second)
barrier
x2 = threadprivate
assign  (inserted first)
```

Below is an actual testcase that demonstrates the issue:
```
subroutine copyin_scalar_array()
  integer(kind=4), save :: x1
  integer(kind=8), save :: x2(10)
  !$omp threadprivate(x1, x2)

  !$omp parallel if (x1 .eq. x2(1)) copyin(x2, x1)
    call sub1(x1, x2)
  !$omp end parallel

end
```

`bbc -fopenmp -emit-hlfir copyin-order.f90 -o -`

```
[...]
 "omp.parallel"(%16) <{operandSegmentSizes = array<i32: 1, 0, 0, 0, 0, 0>}> ({
      %17 = "omp.threadprivate"(%1#1) : (!fir.ref<i32>) -> !fir.ref<i32>
      %18:2 = "hlfir.declare"(%17) <{operandSegmentSizes = array<i32: 1, 0, 0>, uniq_name = "_QFcopyin_scalar_arrayEx1"}> : (!fir.ref<i32>) -> (!fir.ref<i32>, !fir.ref<i32>)
      %19 = "fir.load"(%3#0) : (!fir.ref<i32>) -> i32
      "hlfir.assign"(%19, %18#0) <{temporary_lhs}> : (i32, !fir.ref<i32>) -> ()
==> "omp.barrier"() : () -> ()
      %20 = "omp.threadprivate"(%7#1) : (!fir.ref<!fir.array<10xi64>>) -> !fir.ref<!fir.array<10xi64>>
      %21 = "fir.shape"(%5) : (index) -> !fir.shape<1>
      %22:2 = "hlfir.declare"(%20, %21) <{operandSegmentSizes = array<i32: 1, 1, 0>, uniq_name = "_QFcopyin_scalar_arrayEx2"}> : (!fir.ref<!fir.array<10xi64>>, !fir.shape<1>) -> (!fir.ref<!fir.array<10xi64>>, !fir.ref<!fir.array<10xi64>>)
      "hlfir.assign"(%10#0, %22#0) <{temporary_lhs}> : (!fir.ref<!fir.array<10xi64>>, !fir.ref<!fir.array<10xi64>>) -> ()
      "fir.call"(%18#1, %22#1) <{callee = @_QPsub1, fastmath = #arith.fastmath<contract>}> : (!fir.ref<i32>, !fir.ref<!fir.array<10xi64>>) -> ()
      "omp.terminator"() : () -> ()
    }) : (i1) -> ()
[...]
```
_______________________________________________
llvm-bugs mailing list
llvm-bugs@lists.llvm.org
https://lists.llvm.org/cgi-bin/mailman/listinfo/llvm-bugs

Reply via email to