I have recently begun working on adding OpenMP reductions to Flang. I’ve come across a peculiar problem while trying to implement subtraction.
For a loop such as:
!$omp parallel
!$omp do reduction(-:x)
do i = 1, 100
x = x - i
end do
!$omp end do
!$omp end parallel
The correct output here would be -5050, however when I attempt to run it, x instead prints as 0. This same loop reduces perfectly fine for addition and multiplication.
I’ve been trying to debug the issue, but can’t seem to find the problem.
This is the MLIR emitted:
module attributes {fir.defaultkind = "a1c4d8i4l4r4", fir.kindmap = "", llvm.target_triple = "aarch64-unknown-linux-gnu"} {
omp.reduction.declare @subtract_reduction_i_32 : i32 init {
^bb0(%arg0: i32):
%c0_i32 = arith.constant 0 : i32
omp.yield(%c0_i32 : i32)
} combiner {
^bb0(%arg0: i32, %arg1: i32):
%0 = arith.subi %arg0, %arg1 : i32
omp.yield(%0 : i32)
}
func.func @_QPreduction_subtract() {
%0 = fir.alloca i32 {bindc_name = "i", uniq_name = "_QFreduction_subtractEi"}
%1 = fir.alloca i32 {bindc_name = "x", uniq_name = "_QFreduction_subtractEx"}
%c0_i32 = arith.constant 0 : i32
fir.store %c0_i32 to %1 : !fir.ref<i32>
omp.parallel {
%2 = fir.alloca i32 {adapt.valuebyref, pinned}
%c1_i32 = arith.constant 1 : i32
%c100_i32 = arith.constant 100 : i32
%c1_i32_0 = arith.constant 1 : i32
omp.wsloop reduction(@subtract_reduction_i_32 -> %1 : !fir.ref<i32>) for (%arg0) : i32 = (%c1_i32) to (%c100_i32) inclusive step (%c1_i32_0) {
fir.store %arg0 to %2 : !fir.ref<i32>
%3 = fir.load %2 : !fir.ref<i32>
omp.reduction %3, %1 : !fir.ref<i32>
omp.yield
}
omp.terminator
}
return
}
}
The only difference between the MLIR here and for addition is the subi in omp.reduction.declare. I’m unsure if I’m overlooking something here and would appreciate any help/suggestions.
I’ve created a WIP patch on phabricator containing the changes, here:
D131679 [WIP][Flang][OpenMP] Add support for integer subtraction reduction in worksharing-loop