Break circular dependency between FIR dialect and utilities
[llvm-project.git] / flang / test / Lower / OpenMP / unstructured.f90
blobe7d48bb2693499400b770c5e68dffa0cb4263dc0
1 ! Test unstructured code adjacent to and inside OpenMP constructs.
3 ! RUN: bbc %s -fopenmp -emit-fir -o "-" | FileCheck %s
5 ! CHECK-LABEL: func @_QPss1{{.*}} {
6 ! CHECK: br ^bb1
7 ! CHECK: ^bb1: // 2 preds: ^bb0, ^bb4
8 ! CHECK: cond_br %{{[0-9]*}}, ^bb2, ^bb5
9 ! CHECK: ^bb2: // pred: ^bb1
10 ! CHECK: cond_br %{{[0-9]*}}, ^bb3, ^bb4
11 ! CHECK: ^bb4: // pred: ^bb2
12 ! CHECK: fir.call @_FortranAioBeginExternalListOutput
13 ! CHECK: br ^bb1
14 ! CHECK: ^bb5: // 2 preds: ^bb1, ^bb3
15 ! CHECK: omp.master {
16 ! CHECK: @_FortranAioBeginExternalListOutput
17 ! CHECK: omp.terminator
18 ! CHECK: }
19 ! CHECK: @_FortranAioBeginExternalListOutput
20 ! CHECK: }
21 subroutine ss1(n) ! unstructured code followed by a structured OpenMP construct
22 do i = 1, 3
23 if (i .eq. n) exit
24 print*, 'ss1-A', i
25 enddo
26 !$omp master
27 print*, 'ss1-B', i
28 !$omp end master
29 print*
30 end
32 ! CHECK-LABEL: func @_QPss2{{.*}} {
33 ! CHECK: omp.master {
34 ! CHECK: @_FortranAioBeginExternalListOutput
35 ! CHECK: br ^bb1
36 ! CHECK: ^bb1: // 2 preds: ^bb0, ^bb4
37 ! CHECK: cond_br %{{[0-9]*}}, ^bb2, ^bb5
38 ! CHECK: ^bb2: // pred: ^bb1
39 ! CHECK: cond_br %{{[0-9]*}}, ^bb3, ^bb4
40 ! CHECK: ^bb3: // pred: ^bb2
41 ! CHECK: @_FortranAioBeginExternalListOutput
42 ! CHECK: br ^bb1
43 ! CHECK: ^bb5: // 2 preds: ^bb1, ^bb3
44 ! CHECK: omp.terminator
45 ! CHECK: }
46 ! CHECK: @_FortranAioBeginExternalListOutput
47 ! CHECK: @_FortranAioBeginExternalListOutput
48 ! CHECK: }
49 subroutine ss2(n) ! unstructured OpenMP construct; loop exit inside construct
50 !$omp master
51 print*, 'ss2-A', n
52 do i = 1, 3
53 if (i .eq. n) exit
54 print*, 'ss2-B', i
55 enddo
56 !$omp end master
57 print*, 'ss2-C', i
58 print*
59 end
61 ! CHECK-LABEL: func @_QPss3{{.*}} {
62 ! CHECK: omp.parallel {
63 ! CHECK: %[[ALLOCA_K:.*]] = fir.alloca i32 {bindc_name = "k", pinned}
64 ! CHECK: %[[ALLOCA_1:.*]] = fir.alloca i32 {{{.*}}, pinned}
65 ! CHECK: %[[ALLOCA_2:.*]] = fir.alloca i32 {{{.*}}, pinned}
66 ! CHECK: br ^bb1
67 ! CHECK: ^bb1: // 2 preds: ^bb0, ^bb3
68 ! CHECK: cond_br %{{[0-9]*}}, ^bb2, ^bb4
69 ! CHECK: ^bb2: // pred: ^bb1
70 ! CHECK: omp.wsloop for (%[[ARG1:.*]]) : {{.*}} {
71 ! CHECK: fir.store %[[ARG1]] to %[[ALLOCA_2]] : !fir.ref<i32>
72 ! CHECK: @_FortranAioBeginExternalListOutput
73 ! CHECK: %[[LOAD_1:.*]] = fir.load %[[ALLOCA_2]] : !fir.ref<i32>
74 ! CHECK: @_FortranAioOutputInteger32(%{{.*}}, %[[LOAD_1]])
75 ! CHECK: omp.yield
76 ! CHECK: }
77 ! CHECK: omp.wsloop for (%[[ARG2:.*]]) : {{.*}} {
78 ! CHECK: fir.store %[[ARG2]] to %[[ALLOCA_1]] : !fir.ref<i32>
79 ! CHECK: br ^bb1
80 ! CHECK: ^bb2: // 2 preds: ^bb1, ^bb5
81 ! CHECK: cond_br %{{[0-9]*}}, ^bb3, ^bb6
82 ! CHECK: ^bb3: // pred: ^bb2
83 ! CHECK: cond_br %{{[0-9]*}}, ^bb4, ^bb5
84 ! CHECK: ^bb4: // pred: ^bb3
85 ! CHECK: @_FortranAioBeginExternalListOutput
86 ! CHECK: %[[LOAD_2:.*]] = fir.load %[[ALLOCA_K]] : !fir.ref<i32>
87 ! CHECK: @_FortranAioOutputInteger32(%{{.*}}, %[[LOAD_2]])
88 ! CHECK: br ^bb2
89 ! CHECK: ^bb6: // 2 preds: ^bb2, ^bb4
90 ! CHECK: omp.yield
91 ! CHECK: }
92 ! CHECK: br ^bb1
93 ! CHECK: ^bb4: // pred: ^bb1
94 ! CHECK: omp.terminator
95 ! CHECK: }
96 ! CHECK: }
97 subroutine ss3(n) ! nested unstructured OpenMP constructs
98 !$omp parallel
99 do i = 1, 3
100 !$omp do
101 do k = 1, 3
102 print*, 'ss3-A', k
103 enddo
104 !$omp end do
105 !$omp do
106 do j = 1, 3
107 do k = 1, 3
108 if (k .eq. n) exit
109 print*, 'ss3-B', k
110 enddo
111 enddo
112 !$omp end do
113 enddo
114 !$omp end parallel
117 ! CHECK-LABEL: func @_QPss4{{.*}} {
118 ! CHECK: omp.parallel {
119 ! CHECK: %[[ALLOCA:.*]] = fir.alloca i32 {{{.*}}, pinned}
120 ! CHECK: omp.wsloop for (%[[ARG:.*]]) : {{.*}} {
121 ! CHECK: fir.store %[[ARG]] to %[[ALLOCA]] : !fir.ref<i32>
122 ! CHECK: %[[COND:.*]] = arith.cmpi eq, %{{.*}}, %{{.*}}
123 ! CHECK: %[[COND_XOR:.*]] = arith.xori %[[COND]], %{{.*}}
124 ! CHECK: fir.if %[[COND_XOR]] {
125 ! CHECK: @_FortranAioBeginExternalListOutput
126 ! CHECK: %[[LOAD:.*]] = fir.load %[[ALLOCA]] : !fir.ref<i32>
127 ! CHECK: @_FortranAioOutputInteger32(%{{.*}}, %[[LOAD]])
128 ! CHECK: } else {
129 ! CHECK: }
130 ! CHECK-NEXT: omp.yield
131 ! CHECK-NEXT: }
132 ! CHECK: omp.terminator
133 ! CHECK-NEXT:}
134 subroutine ss4(n) ! CYCLE in OpenMP wsloop constructs
135 !$omp parallel
136 do i = 1, 3
137 !$omp do
138 do j = 1, 3
139 if (j .eq. n) cycle
140 print*, 'ss4', j
141 enddo
142 !$omp end do
143 enddo
144 !$omp end parallel
147 ! CHECK-LABEL: func @_QPss5() {
148 ! CHECK: omp.parallel {
149 ! CHECK: omp.wsloop {{.*}} {
150 ! CHECK: br ^[[BB1:.*]]
151 ! CHECK: ^[[BB1]]:
152 ! CHECK: br ^[[BB2:.*]]
153 ! CHECK: ^[[BB2]]:
154 ! CHECK: cond_br %{{.*}}, ^[[BB3:.*]], ^[[BB6:.*]]
155 ! CHECK: ^[[BB3]]:
156 ! CHECK: cond_br %{{.*}}, ^[[BB4:.*]], ^[[BB3:.*]]
157 ! CHECK: ^[[BB4]]:
158 ! CHECK: br ^[[BB6]]
159 ! CHECK: ^[[BB3]]:
160 ! CHECK: br ^[[BB2]]
161 ! CHECK: ^[[BB6]]:
162 ! CHECK: omp.yield
163 ! CHECK: }
164 ! CHECK: omp.terminator
165 ! CHECK: }
166 subroutine ss5() ! EXIT inside OpenMP wsloop (inside parallel)
167 integer :: x
168 !$omp parallel private(x)
169 !$omp do
170 do j = 1, 3
171 x = j * i
172 do k = 1, 3
173 if (k .eq. n) exit
174 x = k
175 x = x + k
176 enddo
177 x = j - 222
178 enddo
179 !$omp end do
180 !$omp end parallel
183 ! CHECK-LABEL: func @_QPss6() {
184 ! CHECK: omp.parallel {
185 ! CHECK: br ^[[BB1_OUTER:.*]]
186 ! CHECK: ^[[BB1_OUTER]]:
187 ! CHECK: cond_br %{{.*}}, ^[[BB2_OUTER:.*]], ^[[BB3_OUTER:.*]]
188 ! CHECK: ^[[BB2_OUTER]]:
189 ! CHECK: omp.wsloop {{.*}} {
190 ! CHECK: br ^[[BB1:.*]]
191 ! CHECK: ^[[BB1]]:
192 ! CHECK: br ^[[BB2:.*]]
193 ! CHECK: ^[[BB2]]:
194 ! CHECK: cond_br %{{.*}}, ^[[BB3:.*]], ^[[BB6:.*]]
195 ! CHECK: ^[[BB3]]:
196 ! CHECK: cond_br %{{.*}}, ^[[BB4:.*]], ^[[BB5:.*]]
197 ! CHECK: ^[[BB4]]:
198 ! CHECK: br ^[[BB6]]
199 ! CHECK: ^[[BB5]]
200 ! CHECK: br ^[[BB2]]
201 ! CHECK: ^[[BB6]]:
202 ! CHECK: omp.yield
203 ! CHECK: }
204 ! CHECK: br ^[[BB1_OUTER]]
205 ! CHECK: ^[[BB3_OUTER]]:
206 ! CHECK: omp.terminator
207 ! CHECK: }
208 subroutine ss6() ! EXIT inside OpenMP wsloop in a do loop (inside parallel)
209 integer :: x
210 !$omp parallel private(x)
211 do i = 1, 3
212 !$omp do
213 do j = 1, 3
214 x = j * i
215 do k = 1, 3
216 if (k .eq. n) exit
217 x = k
218 x = x + k
219 enddo
220 x = j - 222
221 enddo
222 !$omp end do
223 enddo
224 !$omp end parallel
227 ! CHECK-LABEL: func @_QPss7() {
228 ! CHECK: br ^[[BB1_OUTER:.*]]
229 ! CHECK: ^[[BB1_OUTER]]:
230 ! CHECK: cond_br %{{.*}}, ^[[BB2_OUTER:.*]], ^[[BB3_OUTER:.*]]
231 ! CHECK-NEXT: ^[[BB2_OUTER:.*]]:
232 ! CHECK: omp.parallel {
233 ! CHECK: omp.wsloop {{.*}} {
234 ! CHECK: br ^[[BB1:.*]]
235 ! CHECK-NEXT: ^[[BB1]]:
236 ! CHECK: br ^[[BB2:.*]]
237 ! CHECK-NEXT: ^[[BB2]]:
238 ! CHECK: cond_br %{{.*}}, ^[[BB3:.*]], ^[[BB6:.*]]
239 ! CHECK-NEXT: ^[[BB3]]:
240 ! CHECK: cond_br %{{.*}}, ^[[BB4:.*]], ^[[BB5:.*]]
241 ! CHECK-NEXT: ^[[BB4]]:
242 ! CHECK: br ^[[BB6]]
243 ! CHECK-NEXT: ^[[BB5]]:
244 ! CHECK: br ^[[BB2]]
245 ! CHECK-NEXT: ^[[BB6]]:
246 ! CHECK: omp.yield
247 ! CHECK: }
248 ! CHECK: omp.terminator
249 ! CHECK: }
250 ! CHECK: br ^[[BB1_OUTER]]
251 ! CHECK-NEXT: ^[[BB3_OUTER]]:
252 ! CHECK-NEXT: return
253 subroutine ss7() ! EXIT inside OpenMP parallel do (inside do loop)
254 integer :: x
255 do i = 1, 3
256 !$omp parallel do private(x)
257 do j = 1, 3
258 x = j * i
259 do k = 1, 3
260 if (k .eq. n) exit
261 x = k
262 x = x + k
263 enddo
264 enddo
265 !$omp end parallel do
266 enddo
269 ! CHECK-LABEL: func @_QPss8() {
270 ! CHECK: omp.parallel {
271 ! CHECK: omp.wsloop {{.*}} {
272 ! CHECK: br ^[[BB1:.*]]
273 ! CHECK-NEXT: ^[[BB1]]:
274 ! CHECK: br ^[[BB2:.*]]
275 ! CHECK: ^[[BB2]]:
276 ! CHECK: cond_br %{{.*}}, ^[[BB3:.*]], ^[[BB6:.*]]
277 ! CHECK: ^[[BB3]]:
278 ! CHECK: cond_br %{{.*}}, ^[[BB4:.*]], ^[[BB5:.*]]
279 ! CHECK: ^[[BB4]]:
280 ! CHECK-NEXT: br ^[[BB6]]
281 ! CHECK: ^[[BB5]]:
282 ! CHECK: br ^[[BB2]]
283 ! CHECK-NEXT: ^[[BB6]]:
284 ! CHECK: omp.yield
285 ! CHECK: }
286 ! CHECK: omp.terminator
287 ! CHECK: }
288 subroutine ss8() ! EXIT inside OpenMP parallel do
289 integer :: x
290 !$omp parallel do private(x)
291 do j = 1, 3
292 x = j * i
293 do k = 1, 3
294 if (k .eq. n) exit
295 x = k
296 x = x + k
297 enddo
298 enddo
299 !$omp end parallel do
302 ! CHECK-LABEL: func @_QPss9() {
303 ! CHECK: omp.parallel {
304 ! CHECK-NEXT: omp.parallel {
305 ! CHECK: br ^[[BB1:.*]]
306 ! CHECK: ^[[BB1]]:
307 ! CHECK: cond_br %{{.*}}, ^[[BB2:.*]], ^[[BB5:.*]]
308 ! CHECK-NEXT: ^[[BB2]]:
309 ! CHECK: cond_br %{{.*}}, ^[[BB3:.*]], ^[[BB4:.*]]
310 ! CHECK-NEXT: ^[[BB3]]:
311 ! CHECK-NEXT: br ^[[BB5]]
312 ! CHECK-NEXT: ^[[BB4]]:
313 ! CHECK: br ^[[BB1]]
314 ! CHECK-NEXT: ^[[BB5]]:
315 ! CHECK: omp.terminator
316 ! CHECK-NEXT: }
317 ! CHECK: omp.terminator
318 ! CHECK-NEXT }
319 ! CHECK: }
320 subroutine ss9() ! EXIT inside OpenMP parallel (inside parallel)
321 integer :: x
322 !$omp parallel
323 !$omp parallel private(x)
324 do k = 1, 3
325 if (k .eq. n) exit
326 x = k
327 x = x + k
328 end do
329 !$omp end parallel
330 !$omp end parallel
333 ! CHECK-LABEL: func @_QQmain
334 program p
335 call ss1(2)
336 call ss2(2)
337 call ss3(2)
338 call ss4(2)
339 call ss5()
340 call ss6()
341 call ss7()
342 call ss8()
343 call ss9()