1 ! Test unstructured code adjacent to and inside OpenMP constructs.
3 ! RUN: bbc %s -fopenmp -emit-hlfir -o "-" \
6 ! CHECK-LABEL: func @_QPss1{{.*}} {
8 ! CHECK: ^bb1: // 2 preds: ^bb0, ^bb4
9 ! CHECK: cond_br %{{[0-9]*}}, ^bb2, ^bb5
10 ! CHECK: ^bb2: // pred: ^bb1
11 ! CHECK: cond_br %{{[0-9]*}}, ^bb3, ^bb4
12 ! CHECK: ^bb4: // pred: ^bb2
13 ! CHECK: fir.call @_FortranAioBeginExternalListOutput
15 ! CHECK: ^bb5: // 2 preds: ^bb1, ^bb3
17 ! CHECK: @_FortranAioBeginExternalListOutput
18 ! CHECK: omp.terminator
20 ! CHECK: @_FortranAioBeginExternalListOutput
22 subroutine ss1(n
) ! unstructured code followed by a structured OpenMP construct
33 ! CHECK-LABEL: func @_QPss2{{.*}} {
35 ! CHECK: @_FortranAioBeginExternalListOutput
37 ! CHECK: ^bb1: // 2 preds: ^bb0, ^bb4
38 ! CHECK: cond_br %{{[0-9]*}}, ^bb2, ^bb5
39 ! CHECK: ^bb2: // pred: ^bb1
40 ! CHECK: cond_br %{{[0-9]*}}, ^bb3, ^bb4
41 ! CHECK: ^bb3: // pred: ^bb2
42 ! CHECK: @_FortranAioBeginExternalListOutput
44 ! CHECK: ^bb5: // 2 preds: ^bb1, ^bb3
45 ! CHECK: omp.terminator
47 ! CHECK: @_FortranAioBeginExternalListOutput
48 ! CHECK: @_FortranAioBeginExternalListOutput
50 subroutine ss2(n
) ! unstructured OpenMP construct; loop exit inside construct
62 ! CHECK-LABEL: func @_QPss3{{.*}} {
63 ! CHECK: omp.parallel private(@{{.*}} %{{.*}}#0 -> %{{.*}} : {{.*}}) {
64 ! CHECK: %[[ALLOCA_K:.*]] = fir.alloca i32 {bindc_name = "k", pinned}
65 ! CHECK: %[[K_DECL:.*]]:2 = hlfir.declare %[[ALLOCA_K]] {uniq_name = "_QFss3Ek"} : (!fir.ref<i32>) -> (!fir.ref<i32>, !fir.ref<i32>)
68 ! CHECK: ^bb1: // 2 preds: ^bb0, ^bb3
69 ! CHECK: cond_br %{{[0-9]*}}, ^bb2, ^bb4
70 ! CHECK: ^bb2: // pred: ^bb1
72 ! CHECK: %[[ALLOCA_2:.*]] = fir.alloca i32 {{{.*}}, pinned, {{.*}}}
73 ! CHECK: %[[OMP_LOOP_K_DECL:.*]]:2 = hlfir.declare %[[ALLOCA_2]] {uniq_name = "_QFss3Ek"} : (!fir.ref<i32>) -> (!fir.ref<i32>, !fir.ref<i32>)
75 ! CHECK: omp.loop_nest (%[[ARG1:.*]]) : {{.*}} {
76 ! CHECK: fir.store %[[ARG1]] to %[[OMP_LOOP_K_DECL]]#1 : !fir.ref<i32>
77 ! CHECK: @_FortranAioBeginExternalListOutput
78 ! CHECK: %[[LOAD_1:.*]] = fir.load %[[OMP_LOOP_K_DECL]]#0 : !fir.ref<i32>
79 ! CHECK: @_FortranAioOutputInteger32(%{{.*}}, %[[LOAD_1]])
84 ! CHECK: %[[ALLOCA_1:.*]] = fir.alloca i32 {{{.*}}, pinned, {{.*}}}
85 ! CHECK: %[[OMP_LOOP_J_DECL:.*]]:2 = hlfir.declare %[[ALLOCA_1]] {uniq_name = "_QFss3Ej"} : (!fir.ref<i32>) -> (!fir.ref<i32>, !fir.ref<i32>)
88 ! CHECK: omp.loop_nest (%[[ARG2:.*]]) : {{.*}} {
89 ! CHECK: fir.store %[[ARG2]] to %[[OMP_LOOP_J_DECL]]#1 : !fir.ref<i32>
91 ! CHECK: ^bb2: // 2 preds: ^bb1, ^bb5
92 ! CHECK: cond_br %{{[0-9]*}}, ^bb3, ^bb6
93 ! CHECK: ^bb3: // pred: ^bb2
94 ! CHECK: cond_br %{{[0-9]*}}, ^bb4, ^bb5
95 ! CHECK: ^bb4: // pred: ^bb3
96 ! CHECK: @_FortranAioBeginExternalListOutput
97 ! CHECK: %[[LOAD_2:.*]] = fir.load %[[K_DECL]]#0 : !fir.ref<i32>
98 ! CHECK: @_FortranAioOutputInteger32(%{{.*}}, %[[LOAD_2]])
100 ! CHECK: ^bb6: // 2 preds: ^bb2, ^bb4
105 ! CHECK: ^bb4: // pred: ^bb1
106 ! CHECK: omp.terminator
109 subroutine ss3(n
) ! nested unstructured OpenMP constructs
129 ! CHECK-LABEL: func @_QPss4{{.*}} {
130 ! CHECK: omp.parallel private(@{{.*}} %{{.*}}#0 -> %{{.*}} : {{.*}}) {
131 ! CHECK: %[[ALLOCA:.*]] = fir.alloca i32 {{{.*}}, pinned, uniq_name = "_QFss4Ej"}
132 ! CHECK: %[[OMP_LOOP_J_DECL:.*]]:2 = hlfir.declare %[[ALLOCA]] {uniq_name = "_QFss4Ej"} : (!fir.ref<i32>) -> (!fir.ref<i32>, !fir.ref<i32>)
133 ! CHECK: omp.wsloop {
134 ! CHECK-NEXT: omp.loop_nest (%[[ARG:.*]]) : {{.*}} {
135 ! CHECK: fir.store %[[ARG]] to %[[OMP_LOOP_J_DECL]]#1 : !fir.ref<i32>
136 ! CHECK: %[[COND:.*]] = arith.cmpi eq, %{{.*}}, %{{.*}}
137 ! CHECK: %[[COND_XOR:.*]] = arith.xori %[[COND]], %{{.*}}
138 ! CHECK: fir.if %[[COND_XOR]] {
139 ! CHECK: @_FortranAioBeginExternalListOutput
140 ! CHECK: %[[LOAD:.*]] = fir.load %[[OMP_LOOP_J_DECL]]#0 : !fir.ref<i32>
141 ! CHECK: @_FortranAioOutputInteger32(%{{.*}}, %[[LOAD]])
143 ! CHECK-NEXT: omp.yield
146 ! CHECK: omp.terminator
148 subroutine ss4(n
) ! CYCLE in OpenMP wsloop constructs
161 ! CHECK-LABEL: func @_QPss5() {
162 ! CHECK: omp.parallel private(@{{.*}} %{{.*}}#0 -> %{{.*}} : {{.*}}) {
163 ! CHECK: omp.wsloop {
164 ! CHECK: omp.loop_nest {{.*}} {
165 ! CHECK: br ^[[BB1:.*]]
167 ! CHECK: br ^[[BB2:.*]]
169 ! CHECK: cond_br %{{.*}}, ^[[BB3:.*]], ^[[BB6:.*]]
171 ! CHECK: cond_br %{{.*}}, ^[[BB4:.*]], ^[[BB3:.*]]
180 ! CHECK: omp.terminator
182 subroutine ss5() ! EXIT inside OpenMP wsloop (inside parallel)
184 !$omp parallel private(x)
199 ! CHECK-LABEL: func @_QPss6() {
200 ! CHECK: omp.parallel private(@{{.*}} %{{.*}}#0 -> %{{.*}} : {{.*}}) {
201 ! CHECK: br ^[[BB1_OUTER:.*]]
202 ! CHECK: ^[[BB1_OUTER]]:
203 ! CHECK: cond_br %{{.*}}, ^[[BB2_OUTER:.*]], ^[[BB3_OUTER:.*]]
204 ! CHECK: ^[[BB2_OUTER]]:
205 ! CHECK: omp.wsloop {
206 ! CHECK: omp.loop_nest {{.*}} {
207 ! CHECK: br ^[[BB1:.*]]
209 ! CHECK: br ^[[BB2:.*]]
211 ! CHECK: cond_br %{{.*}}, ^[[BB3:.*]], ^[[BB6:.*]]
213 ! CHECK: cond_br %{{.*}}, ^[[BB4:.*]], ^[[BB5:.*]]
222 ! CHECK: br ^[[BB1_OUTER]]
223 ! CHECK: ^[[BB3_OUTER]]:
224 ! CHECK: omp.terminator
226 subroutine ss6() ! EXIT inside OpenMP wsloop in a do loop (inside parallel)
228 !$omp parallel private(x)
245 ! CHECK-LABEL: func @_QPss7() {
246 ! CHECK: br ^[[BB1_OUTER:.*]]
247 ! CHECK: ^[[BB1_OUTER]]:
248 ! CHECK: cond_br %{{.*}}, ^[[BB2_OUTER:.*]], ^[[BB3_OUTER:.*]]
249 ! CHECK-NEXT: ^[[BB2_OUTER:.*]]:
250 ! CHECK: omp.parallel {
251 ! CHECK: omp.wsloop {
252 ! CHECK: omp.loop_nest {{.*}} {
253 ! CHECK: br ^[[BB1:.*]]
254 ! CHECK-NEXT: ^[[BB1]]:
255 ! CHECK: br ^[[BB2:.*]]
256 ! CHECK-NEXT: ^[[BB2]]:
257 ! CHECK: cond_br %{{.*}}, ^[[BB3:.*]], ^[[BB6:.*]]
258 ! CHECK-NEXT: ^[[BB3]]:
259 ! CHECK: cond_br %{{.*}}, ^[[BB4:.*]], ^[[BB5:.*]]
260 ! CHECK-NEXT: ^[[BB4]]:
262 ! CHECK-NEXT: ^[[BB5]]:
264 ! CHECK-NEXT: ^[[BB6]]:
268 ! CHECK: omp.terminator
270 ! CHECK: br ^[[BB1_OUTER]]
271 ! CHECK-NEXT: ^[[BB3_OUTER]]:
273 subroutine ss7() ! EXIT inside OpenMP parallel do (inside do loop)
276 !$omp parallel do private(x)
285 !$omp end parallel do
289 ! CHECK-LABEL: func @_QPss8() {
290 ! CHECK: omp.parallel {
291 ! CHECK: omp.wsloop {
292 ! CHECK: omp.loop_nest {{.*}} {
293 ! CHECK: br ^[[BB1:.*]]
294 ! CHECK-NEXT: ^[[BB1]]:
295 ! CHECK: br ^[[BB2:.*]]
297 ! CHECK: cond_br %{{.*}}, ^[[BB3:.*]], ^[[BB6:.*]]
299 ! CHECK: cond_br %{{.*}}, ^[[BB4:.*]], ^[[BB5:.*]]
301 ! CHECK-NEXT: br ^[[BB6]]
304 ! CHECK-NEXT: ^[[BB6]]:
308 ! CHECK: omp.terminator
310 subroutine ss8() ! EXIT inside OpenMP parallel do
312 !$omp parallel do private(x)
321 !$omp end parallel do
324 ! CHECK-LABEL: func @_QPss9() {
325 ! CHECK: omp.parallel {
326 ! CHECK-NEXT: omp.parallel private(@{{.*}} %{{.*}}#0 -> %{{.*}}, @{{.*}} %{{.*}}#0 -> %{{.*}} : {{.*}}) {
327 ! CHECK: br ^[[BB1:.*]]
329 ! CHECK: cond_br %{{.*}}, ^[[BB2:.*]], ^[[BB5:.*]]
330 ! CHECK-NEXT: ^[[BB2]]:
331 ! CHECK: cond_br %{{.*}}, ^[[BB3:.*]], ^[[BB4:.*]]
332 ! CHECK-NEXT: ^[[BB3]]:
333 ! CHECK-NEXT: br ^[[BB5]]
334 ! CHECK-NEXT: ^[[BB4]]:
336 ! CHECK-NEXT: ^[[BB5]]:
337 ! CHECK: omp.terminator
339 ! CHECK: omp.terminator
342 subroutine ss9() ! EXIT inside OpenMP parallel (inside parallel)
345 !$omp parallel private(x)
355 ! CHECK-LABEL: func @_QQmain