1 ! This test checks the lowering of OpenMP sections construct with several clauses present
3 ! RUN: %flang_fc1 -flang-experimental-hlfir -emit-hlfir -fopenmp %s -o - | FileCheck %s
4 ! RUN: bbc -hlfir -emit-hlfir -fopenmp %s -o - | FileCheck %s
6 !CHECK: func @_QQmain() attributes {fir.bindc_name = "sample"} {
7 !CHECK: %[[COUNT:.*]] = fir.address_of(@_QFEcount) : !fir.ref<i32>
8 !CHECK: %[[COUNT_DECL:.*]]:2 = hlfir.declare %[[COUNT]] {uniq_name = "_QFEcount"} : (!fir.ref<i32>) -> (!fir.ref<i32>, !fir.ref<i32>)
9 !CHECK: %[[ETA:.*]] = fir.alloca f32 {bindc_name = "eta", uniq_name = "_QFEeta"}
10 !CHECK: %[[CONST_1:.*]] = arith.constant 1 : i32
11 !CHECK: omp.sections allocate(%[[CONST_1]] : i32 -> %[[COUNT_DECL]]#1 : !fir.ref<i32>) {
13 !CHECK: %[[PRIVATE_ETA:.*]] = fir.alloca f32 {bindc_name = "eta", pinned, uniq_name = "_QFEeta"}
14 !CHECK: %[[PRIVATE_ETA_DECL:.*]]:2 = hlfir.declare %[[PRIVATE_ETA]] {uniq_name = "_QFEeta"} : (!fir.ref<f32>) -> (!fir.ref<f32>, !fir.ref<f32>)
15 !CHECK: %[[PRIVATE_DOUBLE_COUNT:.*]] = fir.alloca i32 {bindc_name = "double_count", pinned, uniq_name = "_QFEdouble_count"}
16 !CHECK: %[[PRIVATE_DOUBLE_COUNT_DECL:.*]]:2 = hlfir.declare %[[PRIVATE_DOUBLE_COUNT]] {uniq_name = "_QFEdouble_count"} : (!fir.ref<i32>) -> (!fir.ref<i32>, !fir.ref<i32>)
17 !CHECK: %[[CONST5:.*]] = arith.constant 5 : i32
18 !CHECK: hlfir.assign %[[CONST5]] to %[[COUNT_DECL]]#0 : i32, !fir.ref<i32>
19 !CHECK: %[[TEMP_COUNT:.*]] = fir.load %[[COUNT_DECL]]#0 : !fir.ref<i32>
20 !CHECK: %[[TEMP_DOUBLE_COUNT:.*]] = fir.load %[[PRIVATE_DOUBLE_COUNT_DECL]]#0 : !fir.ref<i32>
21 !CHECK: %[[RESULT:.*]] = arith.muli %[[TEMP_COUNT]], %[[TEMP_DOUBLE_COUNT]] : i32
22 !CHECK: %[[RESULT_CONVERT:.*]] = fir.convert %[[RESULT]] : (i32) -> f32
23 !CHECK: hlfir.assign %[[RESULT_CONVERT]] to %[[PRIVATE_ETA_DECL]]#0 : f32, !fir.ref<f32>
24 !CHECK: omp.terminator
27 !CHECK: %[[PRIVATE_ETA:.*]] = fir.alloca f32 {bindc_name = "eta", pinned, uniq_name = "_QFEeta"}
28 !CHECK: %[[PRIVATE_ETA_DECL:.*]]:2 = hlfir.declare %[[PRIVATE_ETA]] {uniq_name = "_QFEeta"} : (!fir.ref<f32>) -> (!fir.ref<f32>, !fir.ref<f32>)
29 !CHECK: %[[PRIVATE_DOUBLE_COUNT:.*]] = fir.alloca i32 {bindc_name = "double_count", pinned, uniq_name = "_QFEdouble_count"}
30 !CHECK: %[[PRIVATE_DOUBLE_COUNT_DECL:.*]]:2 = hlfir.declare %[[PRIVATE_DOUBLE_COUNT]] {uniq_name = "_QFEdouble_count"} : (!fir.ref<i32>) -> (!fir.ref<i32>, !fir.ref<i32>)
31 !CHECK: %[[TEMP:.*]] = fir.load %[[PRIVATE_DOUBLE_COUNT_DECL]]#0 : !fir.ref<i32>
32 !CHECK: %[[CONST:.*]] = arith.constant 1 : i32
33 !CHECK: %[[RESULT:.*]] = arith.addi %[[TEMP]], %[[CONST]] : i32
34 !CHECK: hlfir.assign %[[RESULT]] to %[[PRIVATE_DOUBLE_COUNT_DECL]]#0 : i32, !fir.ref<i32>
35 !CHECK: omp.terminator
38 !CHECK: %[[PRIVATE_ETA:.*]] = fir.alloca f32 {bindc_name = "eta", pinned, uniq_name = "_QFEeta"}
39 !CHECK: %[[PRIVATE_ETA_DECL:.*]]:2 = hlfir.declare %[[PRIVATE_ETA]] {uniq_name = "_QFEeta"} : (!fir.ref<f32>) -> (!fir.ref<f32>, !fir.ref<f32>)
40 !CHECK: %[[PRIVATE_DOUBLE_COUNT:.*]] = fir.alloca i32 {bindc_name = "double_count", pinned, uniq_name = "_QFEdouble_count"}
41 !CHECK: %[[PRIVATE_DOUBLE_COUNT_DECL:.*]]:2 = hlfir.declare %[[PRIVATE_DOUBLE_COUNT]] {uniq_name = "_QFEdouble_count"} : (!fir.ref<i32>) -> (!fir.ref<i32>, !fir.ref<i32>)
42 !CHECK: %[[TEMP:.*]] = fir.load %[[PRIVATE_ETA_DECL]]#0 : !fir.ref<f32>
43 !CHECK: %[[CONST:.*]] = arith.constant 7.000000e+00 : f32
44 !CHECK: %[[RESULT:.*]] = arith.subf %[[TEMP]], %[[CONST]] {{.*}}: f32
45 !CHECK: hlfir.assign %[[RESULT]] to %[[PRIVATE_ETA_DECL]]#0 : f32, !fir.ref<f32>
46 !CHECK: %[[TEMP_COUNT1:.*]] = fir.load %[[COUNT_DECL]]#0 : !fir.ref<i32>
47 !CHECK: %[[TEMP_COUNT:.*]] = fir.convert %[[TEMP_COUNT1]] : (i32) -> f32
48 !CHECK: %[[TEMP_ETA:.*]] = fir.load %[[PRIVATE_ETA_DECL]]#0 : !fir.ref<f32>
49 !CHECK: %[[TEMP_COUNT2:.*]] = arith.mulf %[[TEMP_COUNT]], %[[TEMP_ETA]] {{.*}}: f32
50 !CHECK: %[[RESULT:.*]] = fir.convert %[[TEMP_COUNT2]] : (f32) -> i32
51 !CHECK: hlfir.assign %[[RESULT]] to %[[COUNT_DECL]]#0 : i32, !fir.ref<i32>
52 !CHECK: %[[TEMP_COUNT3:.*]] = fir.load %[[COUNT_DECL]]#0 : !fir.ref<i32>
53 !CHECK: %[[TEMP_COUNT4:.*]] = fir.convert %[[TEMP_COUNT3]] : (i32) -> f32
54 !CHECK: %[[TEMP_ETA:.*]] = fir.load %[[PRIVATE_ETA_DECL]]#0 : !fir.ref<f32>
55 !CHECK: %[[TEMP_COUNT5:.*]] = arith.subf %[[TEMP_COUNT4]], %[[TEMP_ETA]] {{.*}}: f32
56 !CHECK: %[[RESULT2:.*]] = fir.convert %[[TEMP_COUNT5]] : (f32) -> i32
57 !CHECK: hlfir.assign %[[RESULT2]] to %[[PRIVATE_DOUBLE_COUNT_DECL]]#0 : i32, !fir.ref<i32>
58 !CHECK: omp.terminator
60 !CHECK: omp.terminator
62 !CHECK: omp.sections nowait {
63 !CHECK: omp.terminator
70 integer :: count
= 0, double_count
= 1
71 !$omp sections private (eta, double_count) allocate(omp_high_bw_mem_alloc: count)
74 eta
= count
* double_count
76 double_count
= double_count
+ 1
80 double_count
= count
- eta
84 !$omp end sections nowait
87 !CHECK: func @_QPfirstprivate(%[[ARG:.*]]: !fir.ref<f32> {fir.bindc_name = "alpha"}) {
88 !CHECK: %[[ARG_DECL:.*]]:2 = hlfir.declare %[[ARG]] {uniq_name = "_QFfirstprivateEalpha"} : (!fir.ref<f32>) -> (!fir.ref<f32>, !fir.ref<f32>)
89 !CHECK: omp.sections {
91 !CHECK: %[[PRIVATE_ALPHA:.*]] = fir.alloca f32 {bindc_name = "alpha", pinned, uniq_name = "_QFfirstprivateEalpha"}
92 !CHECK: %[[PRIVATE_ALPHA_DECL:.*]]:2 = hlfir.declare %[[PRIVATE_ALPHA]] {uniq_name = "_QFfirstprivateEalpha"} : (!fir.ref<f32>) -> (!fir.ref<f32>, !fir.ref<f32>)
93 !CHECK: %[[TEMP:.*]] = fir.load %[[ARG_DECL]]#1 : !fir.ref<f32>
94 !CHECK: fir.store %[[TEMP]] to %[[PRIVATE_ALPHA_DECL]]#1 : !fir.ref<f32>
95 !CHECK: omp.terminator
97 !CHECK: omp.terminator
99 !CHECK: omp.sections {
100 !CHECK: omp.section {
101 !CHECK: %[[PRIVATE_VAR:.*]] = fir.load %[[ARG_DECL]]#0 : !fir.ref<f32>
102 !CHECK: %[[CONSTANT:.*]] = arith.constant 5.000000e+00 : f32
103 !CHECK: %[[PRIVATE_VAR_2:.*]] = arith.mulf %[[PRIVATE_VAR]], %[[CONSTANT]] {{.*}}: f32
104 !CHECK: hlfir.assign %[[PRIVATE_VAR_2]] to %[[ARG_DECL]]#0 : f32, !fir.ref<f32>
105 !CHECK: omp.terminator
107 !CHECK: omp.terminator
112 subroutine firstprivate(alpha
)
114 !$omp sections firstprivate(alpha)
122 !CHECK-LABEL: func @_QPlastprivate
123 subroutine lastprivate()
125 !CHECK: %[[X:.*]] = fir.alloca i32 {bindc_name = "x", uniq_name = "_QFlastprivateEx"}
126 !CHECK: %[[X_DECL:.*]]:2 = hlfir.declare %[[X]] {uniq_name = "_QFlastprivateEx"} : (!fir.ref<i32>) -> (!fir.ref<i32>, !fir.ref<i32>)
127 !CHECK: omp.sections {
128 !$omp sections lastprivate(x)
129 !CHECK: omp.section {
130 !CHECK: %[[PRIVATE_X:.*]] = fir.alloca i32 {bindc_name = "x", pinned, uniq_name = "_QFlastprivateEx"}
131 !CHECK: %[[PRIVATE_X_DECL:.*]]:2 = hlfir.declare %[[PRIVATE_X]] {uniq_name = "_QFlastprivateEx"} : (!fir.ref<i32>) -> (!fir.ref<i32>, !fir.ref<i32>)
132 !CHECK: %[[CONST10:.*]] = arith.constant 10 : i32
133 !CHECK: %[[TEMP:.*]] = fir.load %[[PRIVATE_X_DECL]]#0 : !fir.ref<i32>
134 !CHECK: %[[RESULT:.*]] = arith.muli %[[CONST10]], %[[TEMP]] : i32
135 !CHECK: hlfir.assign %[[RESULT]] to %[[PRIVATE_X_DECL]]#0 : i32, !fir.ref<i32>
136 !CHECK: omp.terminator
141 !CHECK: omp.section {
142 !CHECK: %[[PRIVATE_X:.*]] = fir.alloca i32 {bindc_name = "x", pinned, uniq_name = "_QFlastprivateEx"}
143 !CHECK: %[[PRIVATE_X_DECL:.*]]:2 = hlfir.declare %[[PRIVATE_X]] {uniq_name = "_QFlastprivateEx"} : (!fir.ref<i32>) -> (!fir.ref<i32>, !fir.ref<i32>)
144 !CHECK: %[[TRUE:.*]] = arith.constant true
145 !CHECK: %[[TEMP:.*]] = fir.load %[[PRIVATE_X_DECL]]#0 : !fir.ref<i32>
146 !CHECK: %[[CONST:.*]] = arith.constant 1 : i32
147 !CHECK: %[[RESULT:.*]] = arith.addi %[[TEMP]], %[[CONST]] : i32
148 !CHECK: hlfir.assign %[[RESULT]] to %[[PRIVATE_X_DECL]]#0 : i32, !fir.ref<i32>
149 !CHECK: fir.if %[[TRUE]] {
150 !CHECK: %[[TEMP1:.*]] = fir.load %[[PRIVATE_X_DECL]]#1 : !fir.ref<i32>
151 !CHECK: fir.store %[[TEMP1]] to %[[X_DECL]]#1 : !fir.ref<i32>
153 !CHECK: omp.terminator
157 !CHECK: omp.terminator
161 !CHECK: omp.sections {
162 !$omp sections firstprivate(x) lastprivate(x)
163 !CHECK: omp.section {
164 !CHECK: %[[PRIVATE_X:.*]] = fir.alloca i32 {bindc_name = "x", pinned, uniq_name = "_QFlastprivateEx"}
165 !CHECK: %[[PRIVATE_X_DECL:.*]]:2 = hlfir.declare %[[PRIVATE_X]] {uniq_name = "_QFlastprivateEx"} : (!fir.ref<i32>) -> (!fir.ref<i32>, !fir.ref<i32>)
166 !CHECK: %[[TEMP:.*]] = fir.load %[[X_DECL]]#1 : !fir.ref<i32>
167 !CHECK: fir.store %[[TEMP]] to %[[PRIVATE_X_DECL]]#1 : !fir.ref<i32>
169 !CHECK: %[[CONST:.*]] = arith.constant 10 : i32
170 !CHECK: %[[TEMP:.*]] = fir.load %[[PRIVATE_X_DECL]]#0 : !fir.ref<i32>
171 !CHECK: %[[RESULT:.*]] = arith.muli %[[CONST]], %[[TEMP]] : i32
172 !CHECK: hlfir.assign %[[RESULT]] to %[[PRIVATE_X_DECL]]#0 : i32, !fir.ref<i32>
173 !CHECK: omp.terminator
177 !CHECK: omp.section {
178 !CHECK: %[[PRIVATE_X:.*]] = fir.alloca i32 {bindc_name = "x", pinned, uniq_name = "_QFlastprivateEx"}
179 !CHECK: %[[PRIVATE_X_DECL:.*]]:2 = hlfir.declare %[[PRIVATE_X]] {uniq_name = "_QFlastprivateEx"} : (!fir.ref<i32>) -> (!fir.ref<i32>, !fir.ref<i32>)
180 !CHECK: %[[TEMP:.*]] = fir.load %[[X_DECL]]#1 : !fir.ref<i32>
181 !CHECK: fir.store %[[TEMP]] to %[[PRIVATE_X_DECL]]#1 : !fir.ref<i32>
183 !CHECK: %[[TRUE:.*]] = arith.constant true
184 !CHECK: %[[TEMP:.*]] = fir.load %[[PRIVATE_X_DECL]]#0 : !fir.ref<i32>
185 !CHECK: %[[CONST:.*]] = arith.constant 1 : i32
186 !CHECK: %[[RESULT:.*]] = arith.addi %[[TEMP]], %[[CONST]] : i32
187 !CHECK: hlfir.assign %[[RESULT]] to %[[PRIVATE_X_DECL]]#0 : i32, !fir.ref<i32>
188 !CHECK: fir.if %[[TRUE]] {
189 !CHECK: %[[TEMP:.*]] = fir.load %[[PRIVATE_X_DECL]]#1 : !fir.ref<i32>
190 !CHECK: fir.store %[[TEMP]] to %[[X_DECL]]#1 : !fir.ref<i32>
192 !CHECK: omp.terminator
196 !CHECK: omp.terminator
200 !CHECK: omp.sections nowait {
201 !$omp sections firstprivate(x) lastprivate(x)
202 !CHECK: omp.section {
203 !CHECK: %[[PRIVATE_X:.*]] = fir.alloca i32 {bindc_name = "x", pinned, uniq_name = "_QFlastprivateEx"}
204 !CHECK: %[[PRIVATE_X_DECL:.*]]:2 = hlfir.declare %[[PRIVATE_X]] {uniq_name = "_QFlastprivateEx"} : (!fir.ref<i32>) -> (!fir.ref<i32>, !fir.ref<i32>)
205 !CHECK: %[[TEMP:.*]] = fir.load %[[X_DECL]]#1 : !fir.ref<i32>
206 !CHECK: fir.store %[[TEMP]] to %[[PRIVATE_X_DECL]]#1 : !fir.ref<i32>
208 !CHECK: %[[CONST:.*]] = arith.constant 10 : i32
209 !CHECK: %[[TEMP:.*]] = fir.load %[[PRIVATE_X_DECL]]#0 : !fir.ref<i32>
210 !CHECK: %[[RESULT:.*]] = arith.muli %[[CONST]], %[[TEMP]] : i32
211 !CHECK: hlfir.assign %[[RESULT]] to %[[PRIVATE_X_DECL]]#0 : i32, !fir.ref<i32>
212 !CHECK: omp.terminator
216 !CHECK: omp.section {
217 !CHECK: %[[PRIVATE_X:.*]] = fir.alloca i32 {bindc_name = "x", pinned, uniq_name = "_QFlastprivateEx"}
218 !CHECK: %[[PRIVATE_X_DECL:.*]]:2 = hlfir.declare %[[PRIVATE_X]] {uniq_name = "_QFlastprivateEx"} : (!fir.ref<i32>) -> (!fir.ref<i32>, !fir.ref<i32>)
219 !CHECK: %[[TEMP:.*]] = fir.load %[[X_DECL]]#1 : !fir.ref<i32>
220 !CHECK: fir.store %[[TEMP]] to %[[PRIVATE_X_DECL]]#1 : !fir.ref<i32>
222 !CHECK: %[[TRUE:.*]] = arith.constant true
223 !CHECK: %[[TEMP:.*]] = fir.load %[[PRIVATE_X_DECL]]#0 : !fir.ref<i32>
224 !CHECK: %[[CONST:.*]] = arith.constant 1 : i32
225 !CHECK: %[[RESULT:.*]] = arith.addi %[[TEMP]], %[[CONST]] : i32
226 !CHECK: hlfir.assign %[[RESULT]] to %[[PRIVATE_X_DECL]]#0 : i32, !fir.ref<i32>
227 !CHECK: fir.if %[[TRUE]] {
228 !CHECK: %[[TEMP:.*]] = fir.load %[[PRIVATE_X_DECL]]#1 : !fir.ref<i32>
229 !CHECK: fir.store %[[TEMP]] to %[[X_DECL]]#1 : !fir.ref<i32>
232 !CHECK: omp.terminator
236 !CHECK: omp.terminator
238 !$omp end sections nowait
240 !CHECK: omp.sections {
241 !CHECK: omp.section {
242 !CHECK: %[[PRIVATE_X:.*]] = fir.alloca i32 {bindc_name = "x", pinned, uniq_name = "_QFlastprivateEx"}
243 !CHECK: %[[PRIVATE_X_DECL:.*]]:2 = hlfir.declare %[[PRIVATE_X]] {uniq_name = "_QFlastprivateEx"} : (!fir.ref<i32>) -> (!fir.ref<i32>, !fir.ref<i32>)
245 !CHECK: ^bb1: // pred: ^bb0
246 !CHECK: %[[INNER_PRIVATE_X:.*]] = fir.load %[[PRIVATE_X_DECL]]#0 : !fir.ref<i32>
247 !CHECK: %[[CONST:.*]] = arith.constant 1 : i32
248 !CHECK: %[[RESULT:.*]] = arith.addi %[[INNER_PRIVATE_X]], %[[CONST]] : i32
249 !CHECK: hlfir.assign %[[RESULT]] to %[[PRIVATE_X_DECL]]#0 : i32, !fir.ref<i32>
250 !CHECK: %[[LOADED_VALUE:.*]] = fir.load %[[PRIVATE_X_DECL]]#1 : !fir.ref<i32>
251 !CHECK: fir.store %[[LOADED_VALUE]] to %[[X_DECL]]#1 : !fir.ref<i32>
252 !CHECK: omp.terminator
254 !CHECK: omp.terminator
259 !$omp sections lastprivate(x)
266 !CHECK-LABEL: func @_QPunstructured_sections_privatization
267 subroutine unstructured_sections_privatization()
268 !CHECK: %[[X:.*]] = fir.alloca f32 {bindc_name = "x", uniq_name = "_QFunstructured_sections_privatizationEx"}
269 !CHECK: %[[X_DECL:.*]]:2 = hlfir.declare %[[X]] {uniq_name = "_QFunstructured_sections_privatizationEx"} : (!fir.ref<f32>) -> (!fir.ref<f32>, !fir.ref<f32>)
270 !CHECK: omp.sections {
271 !CHECK: omp.section {
272 !CHECK: %[[PRIVATE_X:.*]] = fir.alloca f32 {bindc_name = "x", pinned, uniq_name = "_QFunstructured_sections_privatizationEx"}
273 !CHECK: %[[PRIVATE_X_DECL:.*]]:2 = hlfir.declare %[[PRIVATE_X]] {uniq_name = "_QFunstructured_sections_privatizationEx"} : (!fir.ref<f32>) -> (!fir.ref<f32>, !fir.ref<f32>)
275 !CHECK: ^bb1: // pred: ^bb0
276 !CHECK: %[[INNER_PRIVATE_X:.*]] = fir.load %[[PRIVATE_X_DECL]]#0 : !fir.ref<f32>
277 !CHECK: %[[CONSTANT:.*]] = arith.constant 1.000000e+00 : f32
278 !CHECK: %[[RESULT:.*]] = arith.addf %[[INNER_PRIVATE_X]], %[[CONSTANT]] fastmath<contract> : f32
279 !CHECK: hlfir.assign %[[RESULT]] to %[[PRIVATE_X_DECL]]#0 : f32, !fir.ref<f32>
280 !CHECK: omp.terminator
282 !CHECK: omp.terminator
284 !$omp sections private(x)
289 !CHECK: omp.sections {
290 !CHECK: omp.section {
291 !CHECK: %[[PRIVATE_X:.*]] = fir.alloca f32 {bindc_name = "x", pinned, uniq_name = "_QFunstructured_sections_privatizationEx"}
292 !CHECK: %[[PRIVATE_X_DECL:.*]]:2 = hlfir.declare %[[PRIVATE_X]] {uniq_name = "_QFunstructured_sections_privatizationEx"} : (!fir.ref<f32>) -> (!fir.ref<f32>, !fir.ref<f32>)
293 !CHECK: %[[TEMP:.*]] = fir.load %[[X_DECL]]#1 : !fir.ref<f32>
294 !CHECK: fir.store %[[TEMP]] to %[[PRIVATE_X_DECL]]#1 : !fir.ref<f32>
297 !CHECK: %[[INNER_PRIVATE_X:.*]] = fir.load %[[PRIVATE_X_DECL]]#0 : !fir.ref<f32>
298 !CHECK: %[[CONSTANT:.*]] = arith.constant 1.000000e+00 : f32
299 !CHECK: %[[RESULT:.*]] = arith.addf %[[INNER_PRIVATE_X]], %[[CONSTANT]] fastmath<contract> : f32
300 !CHECK: hlfir.assign %[[RESULT]] to %[[PRIVATE_X_DECL]]#0 : f32, !fir.ref<f32>
301 !CHECK: omp.terminator
303 !CHECK: omp.terminator
305 !$omp sections firstprivate(x)