xref: /llvm-project/flang/test/Lower/OpenMP/wsloop-reduction-multi.f90 (revision 937cbce14c9aa956342a9c818c26a8a557802843)
1! RUN: bbc -emit-hlfir -fopenmp -o - %s 2>&1 | FileCheck %s
2! RUN: %flang_fc1 -emit-hlfir -fopenmp -o - %s 2>&1 | FileCheck %s
3
4!CHECK-LABEL: omp.declare_reduction
5!CHECK-SAME: @[[MIN_RED_I32_NAME:.*]] : i32 init {
6!CHECK: ^bb0(%{{.*}}: i32):
7!CHECK:  %[[C0_1:.*]] = arith.constant 2147483647 : i32
8!CHECK:  omp.yield(%[[C0_1]] : i32)
9!CHECK: } combiner {
10!CHECK: ^bb0(%[[ARG0:.*]]: i32, %[[ARG1:.*]]: i32):
11!CHECK:  %[[RES:.*]] = arith.minsi %[[ARG0]], %[[ARG1]] : i32
12!CHECK:  omp.yield(%[[RES]] : i32)
13!CHECK: }
14
15!CHECK-LABEL: omp.declare_reduction
16!CHECK-SAME: @[[ADD_RED_F32_NAME:.*]] : f32 init {
17!CHECK: ^bb0(%{{.*}}: f32):
18!CHECK:   %[[C0_1:.*]] = arith.constant 0.000000e+00 : f32
19!CHECK:   omp.yield(%[[C0_1]] : f32)
20!CHECK: } combiner {
21!CHECK: ^bb0(%[[ARG0:.*]]: f32, %[[ARG1:.*]]: f32):
22!CHECK:   %[[RES:.*]] = arith.addf %[[ARG0]], %[[ARG1]] {{.*}} : f32
23!CHECK:   omp.yield(%[[RES]] : f32)
24!CHECK: }
25
26!CHECK-LABEL: omp.declare_reduction
27!CHECK-SAME: @[[ADD_RED_I32_NAME:.*]] : i32 init {
28!CHECK: ^bb0(%{{.*}}: i32):
29!CHECK:  %[[C0_1:.*]] = arith.constant 0 : i32
30!CHECK:  omp.yield(%[[C0_1]] : i32)
31!CHECK: } combiner {
32!CHECK: ^bb0(%[[ARG0:.*]]: i32, %[[ARG1:.*]]: i32):
33!CHECK:  %[[RES:.*]] = arith.addi %[[ARG0]], %[[ARG1]] : i32
34!CHECK:  omp.yield(%[[RES]] : i32)
35!CHECK: }
36
37!CHECK-LABEL: func.func @_QPmultiple_reduction
38!CHECK:      %[[X_REF:.*]] = fir.alloca i32 {bindc_name = "x", uniq_name = "_QFmultiple_reductionEx"}
39!CHECK:      %[[X_DECL:.*]]:2 = hlfir.declare %[[X_REF]] {uniq_name = "_QFmultiple_reductionEx"} : (!fir.ref<i32>) -> (!fir.ref<i32>, !fir.ref<i32>)
40!CHECK:      %[[Y_REF:.*]] = fir.alloca f32 {bindc_name = "y", uniq_name = "_QFmultiple_reductionEy"}
41!CHECK:      %[[Y_DECL:.*]]:2 = hlfir.declare %[[Y_REF]] {uniq_name = "_QFmultiple_reductionEy"} : (!fir.ref<f32>) -> (!fir.ref<f32>, !fir.ref<f32>)
42!CHECK:      %[[Z_REF:.*]] = fir.alloca i32 {bindc_name = "z", uniq_name = "_QFmultiple_reductionEz"}
43!CHECK:      %[[Z_DECL:.*]]:2 = hlfir.declare %[[Z_REF]] {uniq_name = "_QFmultiple_reductionEz"} : (!fir.ref<i32>) -> (!fir.ref<i32>, !fir.ref<i32>)
44!CHECK:      omp.wsloop reduction(
45!CHECK-SAME: @[[ADD_RED_I32_NAME]] %[[X_DECL]]#0 -> %[[PRV_X:[^,]+]],
46!CHECK-SAME: @[[ADD_RED_F32_NAME]] %[[Y_DECL]]#0 -> %[[PRV_Y:[^,]+]],
47!CHECK-SAME: @[[MIN_RED_I32_NAME]] %[[Z_DECL]]#0 -> %[[PRV_Z:.+]] :
48!CHECK-SAME: !fir.ref<i32>, !fir.ref<f32>, !fir.ref<i32>) {
49!CHECK-NEXT:   omp.loop_nest {{.*}} {
50!CHECK:          %[[PRV_X_DECL:.+]]:2 = hlfir.declare %[[PRV_X]] {{.*}} : (!fir.ref<i32>) -> (!fir.ref<i32>, !fir.ref<i32>)
51!CHECK:          %[[PRV_Y_DECL:.+]]:2 = hlfir.declare %[[PRV_Y]] {{.*}} : (!fir.ref<f32>) -> (!fir.ref<f32>, !fir.ref<f32>)
52!CHECK:          %[[PRV_Z_DECL:.+]]:2 = hlfir.declare %[[PRV_Z]] {{.*}} : (!fir.ref<i32>) -> (!fir.ref<i32>, !fir.ref<i32>)
53!CHECK:          %[[LPRV_X:.+]] = fir.load %[[PRV_X_DECL]]#0 : !fir.ref<i32>
54!CHECK:          %[[RES_X:.+]] = arith.addi %[[LPRV_X]], %{{.+}} : i32
55!CHECK:          hlfir.assign %[[RES_X]] to %[[PRV_X_DECL]]#0 : i32, !fir.ref<i32>
56!CHECK:          %[[LPRV_Y:.+]] = fir.load %[[PRV_Y_DECL]]#0 : !fir.ref<f32>
57!CHECK:          %[[RES_Y:.+]] = arith.addf %[[LPRV_Y]], %{{.+}} : f32
58!CHECK:          hlfir.assign %[[RES_Y]] to %[[PRV_Y_DECL]]#0 : f32, !fir.ref<f32>
59!CHECK:          %[[LPRV_Z:.+]] = fir.load %[[PRV_Z_DECL]]#0 : !fir.ref<i32>
60!CHECK:          %[[RES_Z:.+]] = arith.select %{{.+}}, %[[LPRV_Z]], %{{.+}} : i32
61!CHECK:          hlfir.assign %[[RES_Z]] to %[[PRV_Z_DECL]]#0 : i32, !fir.ref<i32>
62!CHECK:          omp.yield
63!CHECK:        }
64!CHECK:      }
65!CHECK:      return
66subroutine multiple_reduction(v)
67  implicit none
68  integer, intent(in) :: v(:)
69  integer :: i
70  integer :: x
71  real :: y
72  integer:: z
73  x = 0
74  y = 0.0
75  z = 10
76
77  !$omp do reduction(+:x,y) reduction(min:z)
78  do i=1, 100
79    x = x + v(i)
80    y = y + 1.5 * v(i)
81    z = min(z, v(i))
82  end do
83  !$omp end do
84end subroutine
85