1 ! RUN: bbc -emit-fir -fopenmp %s -o - | FileCheck %s
2 ! RUN: %flang_fc1 -emit-fir -fopenmp %s -o - | FileCheck %s
4 !CHECK-LABEL: omp.reduction.declare
5 !CHECK-SAME: @[[RED_F64_NAME:.*]] : f64 init {
6 !CHECK: ^bb0(%{{.*}}: f64):
7 !CHECK: %[[C0_1:.*]] = arith.constant 0.000000e+00 : f64
8 !CHECK: omp.yield(%[[C0_1]] : f64)
10 !CHECK: ^bb0(%[[ARG0:.*]]: f64, %[[ARG1:.*]]: f64):
11 !CHECK: %[[RES:.*]] = arith.addf %[[ARG0]], %[[ARG1]] {{.*}}: f64
12 !CHECK: omp.yield(%[[RES]] : f64)
15 !CHECK-LABEL: omp.reduction.declare
16 !CHECK-SAME: @[[RED_I64_NAME:.*]] : i64 init {
17 !CHECK: ^bb0(%{{.*}}: i64):
18 !CHECK: %[[C0_1:.*]] = arith.constant 0 : i64
19 !CHECK: omp.yield(%[[C0_1]] : i64)
21 !CHECK: ^bb0(%[[ARG0:.*]]: i64, %[[ARG1:.*]]: i64):
22 !CHECK: %[[RES:.*]] = arith.addi %[[ARG0]], %[[ARG1]] : i64
23 !CHECK: omp.yield(%[[RES]] : i64)
26 !CHECK-LABEL: omp.reduction.declare
27 !CHECK-SAME: @[[RED_F32_NAME:.*]] : f32 init {
28 !CHECK: ^bb0(%{{.*}}: f32):
29 !CHECK: %[[C0_1:.*]] = arith.constant 0.000000e+00 : f32
30 !CHECK: omp.yield(%[[C0_1]] : f32)
32 !CHECK: ^bb0(%[[ARG0:.*]]: f32, %[[ARG1:.*]]: f32):
33 !CHECK: %[[RES:.*]] = arith.addf %[[ARG0]], %[[ARG1]] {{.*}}: f32
34 !CHECK: omp.yield(%[[RES]] : f32)
37 !CHECK-LABEL: omp.reduction.declare
38 !CHECK-SAME: @[[RED_I32_NAME:.*]] : i32 init {
39 !CHECK: ^bb0(%{{.*}}: i32):
40 !CHECK: %[[C0_1:.*]] = arith.constant 0 : i32
41 !CHECK: omp.yield(%[[C0_1]] : i32)
43 !CHECK: ^bb0(%[[ARG0:.*]]: i32, %[[ARG1:.*]]: i32):
44 !CHECK: %[[RES:.*]] = arith.addi %[[ARG0]], %[[ARG1]] : i32
45 !CHECK: omp.yield(%[[RES]] : i32)
48 !CHECK-LABEL: func.func @_QPsimple_int_reduction
49 !CHECK: %[[XREF:.*]] = fir.alloca i32 {bindc_name = "x", uniq_name = "_QFsimple_int_reductionEx"}
50 !CHECK: %[[C0_2:.*]] = arith.constant 0 : i32
51 !CHECK: fir.store %[[C0_2]] to %[[XREF]] : !fir.ref<i32>
53 !CHECK: %[[I_PVT_REF:.*]] = fir.alloca i32 {adapt.valuebyref, pinned}
54 !CHECK: %[[C1_1:.*]] = arith.constant 1 : i32
55 !CHECK: %[[C100:.*]] = arith.constant 100 : i32
56 !CHECK: %[[C1_2:.*]] = arith.constant 1 : i32
57 !CHECK: omp.wsloop reduction(@[[RED_I32_NAME]] -> %[[XREF]] : !fir.ref<i32>) for (%[[IVAL:.*]]) : i32 = (%[[C1_1]]) to (%[[C100]]) inclusive step (%[[C1_2]])
58 !CHECK: fir.store %[[IVAL]] to %[[I_PVT_REF]] : !fir.ref<i32>
59 !CHECK: %[[I_PVT_VAL:.*]] = fir.load %[[I_PVT_REF]] : !fir.ref<i32>
60 !CHECK: omp.reduction %[[I_PVT_VAL]], %[[XREF]] : i32, !fir.ref<i32>
62 !CHECK: omp.terminator
64 subroutine simple_int_reduction
68 !$omp do reduction(+:x)
76 !CHECK-LABEL: func.func @_QPsimple_real_reduction
77 !CHECK: %[[XREF:.*]] = fir.alloca f32 {bindc_name = "x", uniq_name = "_QFsimple_real_reductionEx"}
78 !CHECK: %[[C0_2:.*]] = arith.constant 0.000000e+00 : f32
79 !CHECK: fir.store %[[C0_2]] to %[[XREF]] : !fir.ref<f32>
81 !CHECK: %[[I_PVT_REF:.*]] = fir.alloca i32 {adapt.valuebyref, pinned}
82 !CHECK: %[[C1_1:.*]] = arith.constant 1 : i32
83 !CHECK: %[[C100:.*]] = arith.constant 100 : i32
84 !CHECK: %[[C1_2:.*]] = arith.constant 1 : i32
85 !CHECK: omp.wsloop reduction(@[[RED_F32_NAME]] -> %[[XREF]] : !fir.ref<f32>) for (%[[IVAL:.*]]) : i32 = (%[[C1_1]]) to (%[[C100]]) inclusive step (%[[C1_2]])
86 !CHECK: fir.store %[[IVAL]] to %[[I_PVT_REF]] : !fir.ref<i32>
87 !CHECK: %[[I_PVT_VAL_i32:.*]] = fir.load %[[I_PVT_REF]] : !fir.ref<i32>
88 !CHECK: %[[I_PVT_VAL_f32:.*]] = fir.convert %[[I_PVT_VAL_i32]] : (i32) -> f32
89 !CHECK: omp.reduction %[[I_PVT_VAL_f32]], %[[XREF]] : f32, !fir.ref<f32>
91 !CHECK: omp.terminator
93 subroutine simple_real_reduction
97 !$omp do reduction(+:x)
105 !CHECK-LABEL: func.func @_QPsimple_int_reduction_switch_order
106 !CHECK: %[[XREF:.*]] = fir.alloca i32 {bindc_name = "x", uniq_name = "_QFsimple_int_reduction_switch_orderEx"}
107 !CHECK: %[[C0_2:.*]] = arith.constant 0 : i32
108 !CHECK: fir.store %[[C0_2]] to %[[XREF]] : !fir.ref<i32>
110 !CHECK: %[[I_PVT_REF:.*]] = fir.alloca i32 {adapt.valuebyref, pinned}
111 !CHECK: %[[C1_1:.*]] = arith.constant 1 : i32
112 !CHECK: %[[C100:.*]] = arith.constant 100 : i32
113 !CHECK: %[[C1_2:.*]] = arith.constant 1 : i32
114 !CHECK: omp.wsloop reduction(@[[RED_I32_NAME]] -> %[[XREF]] : !fir.ref<i32>) for (%[[IVAL:.*]]) : i32 = (%[[C1_1]]) to (%[[C100]]) inclusive step (%[[C1_2]])
115 !CHECK: fir.store %[[IVAL]] to %[[I_PVT_REF]] : !fir.ref<i32>
116 !CHECK: %[[I_PVT_VAL:.*]] = fir.load %[[I_PVT_REF]] : !fir.ref<i32>
117 !CHECK: omp.reduction %[[I_PVT_VAL]], %[[XREF]] : i32, !fir.ref<i32>
119 !CHECK: omp.terminator
121 subroutine simple_int_reduction_switch_order
125 !$omp do reduction(+:x)
133 !CHECK-LABEL: func.func @_QPsimple_real_reduction_switch_order
134 !CHECK: %[[XREF:.*]] = fir.alloca f32 {bindc_name = "x", uniq_name = "_QFsimple_real_reduction_switch_orderEx"}
135 !CHECK: %[[C0_2:.*]] = arith.constant 0.000000e+00 : f32
136 !CHECK: fir.store %[[C0_2]] to %[[XREF]] : !fir.ref<f32>
138 !CHECK: %[[I_PVT_REF:.*]] = fir.alloca i32 {adapt.valuebyref, pinned}
139 !CHECK: %[[C1_1:.*]] = arith.constant 1 : i32
140 !CHECK: %[[C100:.*]] = arith.constant 100 : i32
141 !CHECK: %[[C1_2:.*]] = arith.constant 1 : i32
142 !CHECK: omp.wsloop reduction(@[[RED_F32_NAME]] -> %[[XREF]] : !fir.ref<f32>) for (%[[IVAL:.*]]) : i32 = (%[[C1_1]]) to (%[[C100]]) inclusive step (%[[C1_2]])
143 !CHECK: fir.store %[[IVAL]] to %[[I_PVT_REF]] : !fir.ref<i32>
144 !CHECK: %[[I_PVT_VAL_i32:.*]] = fir.load %[[I_PVT_REF]] : !fir.ref<i32>
145 !CHECK: %[[I_PVT_VAL_f32:.*]] = fir.convert %[[I_PVT_VAL_i32]] : (i32) -> f32
146 !CHECK: omp.reduction %[[I_PVT_VAL_f32]], %[[XREF]] : f32, !fir.ref<f32>
148 !CHECK: omp.terminator
150 subroutine simple_real_reduction_switch_order
154 !$omp do reduction(+:x)
162 !CHECK-LABEL: func.func @_QPmultiple_int_reductions_same_type
163 !CHECK: %[[XREF:.*]] = fir.alloca i32 {bindc_name = "x", uniq_name = "_QFmultiple_int_reductions_same_typeEx"}
164 !CHECK: %[[YREF:.*]] = fir.alloca i32 {bindc_name = "y", uniq_name = "_QFmultiple_int_reductions_same_typeEy"}
165 !CHECK: %[[ZREF:.*]] = fir.alloca i32 {bindc_name = "z", uniq_name = "_QFmultiple_int_reductions_same_typeEz"}
167 !CHECK: %[[I_PVT_REF:.*]] = fir.alloca i32 {adapt.valuebyref, pinned}
168 !CHECK: omp.wsloop reduction(@[[RED_I32_NAME]] -> %[[XREF]] : !fir.ref<i32>, @[[RED_I32_NAME]] -> %[[YREF]] : !fir.ref<i32>, @[[RED_I32_NAME]] -> %[[ZREF]] : !fir.ref<i32>) for (%[[IVAL]]) : i32
169 !CHECK: fir.store %[[IVAL]] to %[[I_PVT_REF]] : !fir.ref<i32>
170 !CHECK: %[[I_PVT_VAL1:.*]] = fir.load %[[I_PVT_REF]] : !fir.ref<i32>
171 !CHECK: omp.reduction %[[I_PVT_VAL1]], %[[XREF]] : i32, !fir.ref<i32>
172 !CHECK: %[[I_PVT_VAL2:.*]] = fir.load %[[I_PVT_REF]] : !fir.ref<i32>
173 !CHECK: omp.reduction %[[I_PVT_VAL2]], %[[YREF]] : i32, !fir.ref<i32>
174 !CHECK: %[[I_PVT_VAL3:.*]] = fir.load %[[I_PVT_REF]] : !fir.ref<i32>
175 !CHECK: omp.reduction %[[I_PVT_VAL3]], %[[ZREF]] : i32, !fir.ref<i32>
177 !CHECK: omp.terminator
179 subroutine multiple_int_reductions_same_type
185 !$omp do reduction(+:x,y,z)
195 !CHECK-LABEL: func.func @_QPmultiple_real_reductions_same_type
196 !CHECK: %[[XREF:.*]] = fir.alloca f32 {bindc_name = "x", uniq_name = "_QFmultiple_real_reductions_same_typeEx"}
197 !CHECK: %[[YREF:.*]] = fir.alloca f32 {bindc_name = "y", uniq_name = "_QFmultiple_real_reductions_same_typeEy"}
198 !CHECK: %[[ZREF:.*]] = fir.alloca f32 {bindc_name = "z", uniq_name = "_QFmultiple_real_reductions_same_typeEz"}
200 !CHECK: %[[I_PVT_REF:.*]] = fir.alloca i32 {adapt.valuebyref, pinned}
201 !CHECK: omp.wsloop reduction(@[[RED_F32_NAME]] -> %[[XREF]] : !fir.ref<f32>, @[[RED_F32_NAME]] -> %[[YREF]] : !fir.ref<f32>, @[[RED_F32_NAME]] -> %[[ZREF]] : !fir.ref<f32>) for (%[[IVAL]]) : i32
202 !CHECK: fir.store %[[IVAL]] to %[[I_PVT_REF]] : !fir.ref<i32>
203 !CHECK: %[[I_PVT_VAL1_I32:.*]] = fir.load %[[I_PVT_REF]] : !fir.ref<i32>
204 !CHECK: %[[I_PVT_VAL1_F32:.*]] = fir.convert %[[I_PVT_VAL1_I32]] : (i32) -> f32
205 !CHECK: omp.reduction %[[I_PVT_VAL1_F32]], %[[XREF]] : f32, !fir.ref<f32>
206 !CHECK: %[[I_PVT_VAL2_I32:.*]] = fir.load %[[I_PVT_REF]] : !fir.ref<i32>
207 !CHECK: %[[I_PVT_VAL2_F32:.*]] = fir.convert %[[I_PVT_VAL2_I32]] : (i32) -> f32
208 !CHECK: omp.reduction %[[I_PVT_VAL2_F32]], %[[YREF]] : f32, !fir.ref<f32>
209 !CHECK: %[[I_PVT_VAL3_I32:.*]] = fir.load %[[I_PVT_REF]] : !fir.ref<i32>
210 !CHECK: %[[I_PVT_VAL3_F32:.*]] = fir.convert %[[I_PVT_VAL3_I32]] : (i32) -> f32
211 !CHECK: omp.reduction %[[I_PVT_VAL3_F32]], %[[ZREF]] : f32, !fir.ref<f32>
213 !CHECK: omp.terminator
215 subroutine multiple_real_reductions_same_type
221 !$omp do reduction(+:x,y,z)
231 !CHECK-LABEL: func.func @_QPmultiple_reductions_different_type
232 !CHECK: %[[WREF:.*]] = fir.alloca f64 {bindc_name = "w", uniq_name = "_QFmultiple_reductions_different_typeEw"}
233 !CHECK: %[[XREF:.*]] = fir.alloca i32 {bindc_name = "x", uniq_name = "_QFmultiple_reductions_different_typeEx"}
234 !CHECK: %[[YREF:.*]] = fir.alloca i64 {bindc_name = "y", uniq_name = "_QFmultiple_reductions_different_typeEy"}
235 !CHECK: %[[ZREF:.*]] = fir.alloca f32 {bindc_name = "z", uniq_name = "_QFmultiple_reductions_different_typeEz"}
237 !CHECK: %[[I_PVT_REF:.*]] = fir.alloca i32 {adapt.valuebyref, pinned}
238 !CHECK: omp.wsloop reduction(@[[RED_I32_NAME]] -> %[[XREF]] : !fir.ref<i32>, @[[RED_I64_NAME]] -> %[[YREF]] : !fir.ref<i64>, @[[RED_F32_NAME]] -> %[[ZREF]] : !fir.ref<f32>, @[[RED_F64_NAME]] -> %[[WREF]] : !fir.ref<f64>) for (%[[IVAL:.*]]) : i32
239 !CHECK: fir.store %[[IVAL]] to %[[I_PVT_REF]] : !fir.ref<i32>
240 !CHECK: %[[I_PVT_VAL1_I32:.*]] = fir.load %[[I_PVT_REF]] : !fir.ref<i32>
241 !CHECK: omp.reduction %[[I_PVT_VAL1_I32]], %[[XREF]] : i32, !fir.ref<i32>
242 !CHECK: %[[I_PVT_VAL2_I32:.*]] = fir.load %[[I_PVT_REF]] : !fir.ref<i32>
243 !CHECK: %[[I_PVT_VAL2_I64:.*]] = fir.convert %[[I_PVT_VAL2_I32]] : (i32) -> i64
244 !CHECK: omp.reduction %[[I_PVT_VAL2_I64]], %[[YREF]] : i64, !fir.ref<i64>
245 !CHECK: %[[I_PVT_VAL3_I32:.*]] = fir.load %[[I_PVT_REF]] : !fir.ref<i32>
246 !CHECK: %[[I_PVT_VAL3_F32:.*]] = fir.convert %[[I_PVT_VAL3_I32]] : (i32) -> f32
247 !CHECK: omp.reduction %[[I_PVT_VAL3_F32]], %[[ZREF]] : f32, !fir.ref<f32>
248 !CHECK: %[[I_PVT_VAL4_I32:.*]] = fir.load %[[I_PVT_REF]] : !fir.ref<i32>
249 !CHECK: %[[I_PVT_VAL4_F64:.*]] = fir.convert %[[I_PVT_VAL4_I32]] : (i32) -> f64
250 !CHECK: omp.reduction %[[I_PVT_VAL4_F64]], %[[WREF]] : f64, !fir.ref<f64>
252 !CHECK: omp.terminator
254 subroutine multiple_reductions_different_type
264 !$omp do reduction(+:x,y,z,w)