1 // RUN: fir-opt --split-input-file --cfg-conversion %s | FileCheck %s
3 func.func @x(%lb : index, %ub : index, %step : index, %b : i1, %addr : !fir.ref<index>) {
4 fir.do_loop %iv = %lb to %ub step %step unordered {
5 // expect following conditional blocks to get fused
7 fir.store %iv to %addr : !fir.ref<index>
9 %zero = arith.constant 0 : index
10 fir.store %zero to %addr : !fir.ref<index>
16 func.func private @f2() -> i1
18 // CHECK: func @x(%[[VAL_0:.*]]: index, %[[VAL_1:.*]]: index, %[[VAL_2:.*]]: index, %[[VAL_3:.*]]: i1, %[[VAL_4:.*]]: !fir.ref<index>) {
19 // CHECK: %[[VAL_5:.*]] = arith.subi %[[VAL_1]], %[[VAL_0]] : index
20 // CHECK: %[[VAL_6:.*]] = arith.addi %[[VAL_5]], %[[VAL_2]] : index
21 // CHECK: %[[VAL_7:.*]] = arith.divsi %[[VAL_6]], %[[VAL_2]] : index
22 // CHECK: br ^bb1(%[[VAL_0]], %[[VAL_7]] : index, index)
23 // CHECK: ^bb1(%[[VAL_8:.*]]: index, %[[VAL_9:.*]]: index):
24 // CHECK: %[[VAL_10:.*]] = arith.constant 0 : index
25 // CHECK: %[[VAL_11:.*]] = arith.cmpi sgt, %[[VAL_9]], %[[VAL_10]] : index
26 // CHECK: cond_br %[[VAL_11]], ^bb2, ^bb6
28 // CHECK: cond_br %[[VAL_3]], ^bb3, ^bb4
30 // CHECK: fir.store %[[VAL_8]] to %[[VAL_4]] : !fir.ref<index>
33 // CHECK: %[[VAL_12:.*]] = arith.constant 0 : index
34 // CHECK: fir.store %[[VAL_12]] to %[[VAL_4]] : !fir.ref<index>
37 // CHECK: %[[VAL_13:.*]] = arith.addi %[[VAL_8]], %[[VAL_2]] : index
38 // CHECK: %[[VAL_14:.*]] = arith.constant 1 : index
39 // CHECK: %[[VAL_15:.*]] = arith.subi %[[VAL_9]], %[[VAL_14]] : index
40 // CHECK: br ^bb1(%[[VAL_13]], %[[VAL_15]] : index, index)
44 // CHECK: func private @f2() -> i1
48 func.func @x2(%lo : index, %up : index, %ok : i1) {
49 %c1 = arith.constant 1 : index
50 %unused = fir.iterate_while (%i = %lo to %up step %c1) and (%ok1 = %ok) {
51 %ok2 = fir.call @f2() : () -> i1
57 func.func private @f3(i16)
59 // CHECK: func @x2(%[[VAL_0:.*]]: index, %[[VAL_1:.*]]: index, %[[VAL_2:.*]]: i1) {
60 // CHECK: %[[VAL_3:.*]] = arith.constant 1 : index
61 // CHECK: br ^bb1(%[[VAL_0]], %[[VAL_2]] : index, i1)
62 // CHECK: ^bb1(%[[VAL_4:.*]]: index, %[[VAL_5:.*]]: i1):
63 // CHECK: %[[VAL_6:.*]] = arith.constant 0 : index
64 // CHECK: %[[VAL_7:.*]] = arith.cmpi slt, %[[VAL_6]], %[[VAL_3]] : index
65 // CHECK: %[[VAL_8:.*]] = arith.cmpi sle, %[[VAL_4]], %[[VAL_1]] : index
66 // CHECK: %[[VAL_9:.*]] = arith.cmpi slt, %[[VAL_3]], %[[VAL_6]] : index
67 // CHECK: %[[VAL_10:.*]] = arith.cmpi sle, %[[VAL_1]], %[[VAL_4]] : index
68 // CHECK: %[[VAL_11:.*]] = arith.andi %[[VAL_7]], %[[VAL_8]] : i1
69 // CHECK: %[[VAL_12:.*]] = arith.andi %[[VAL_9]], %[[VAL_10]] : i1
70 // CHECK: %[[VAL_13:.*]] = arith.ori %[[VAL_11]], %[[VAL_12]] : i1
71 // CHECK: %[[VAL_14:.*]] = arith.andi %[[VAL_5]], %[[VAL_13]] : i1
72 // CHECK: cond_br %[[VAL_14]], ^bb2, ^bb3
74 // CHECK: %[[VAL_15:.*]] = fir.call @f2() : () -> i1
75 // CHECK: %[[VAL_16:.*]] = arith.addi %[[VAL_4]], %[[VAL_3]] : index
76 // CHECK: br ^bb1(%[[VAL_16]], %[[VAL_15]] : index, i1)
80 // CHECK: func private @f3(i16)
84 // do_loop with an extra loop-carried value
85 func.func @x3(%lo : index, %up : index) -> i1 {
86 %c1 = arith.constant 1 : index
87 %ok1 = arith.constant true
88 %ok2 = fir.do_loop %i = %lo to %up step %c1 iter_args(%j = %ok1) -> i1 {
89 %ok = fir.call @f2() : () -> i1
95 // CHECK-LABEL: func @x3(
96 // CHECK-SAME: %[[VAL_0:.*]]: index,
97 // CHECK-SAME: %[[VAL_1:.*]]: index) -> i1 {
98 // CHECK: %[[VAL_2:.*]] = arith.constant 1 : index
99 // CHECK: %[[VAL_3:.*]] = arith.constant true
100 // CHECK: %[[VAL_4:.*]] = arith.subi %[[VAL_1]], %[[VAL_0]] : index
101 // CHECK: %[[VAL_5:.*]] = arith.addi %[[VAL_4]], %[[VAL_2]] : index
102 // CHECK: %[[VAL_6:.*]] = arith.divsi %[[VAL_5]], %[[VAL_2]] : index
103 // CHECK: br ^bb1(%[[VAL_0]], %[[VAL_3]], %[[VAL_6]] : index, i1, index)
104 // CHECK: ^bb1(%[[VAL_7:.*]]: index, %[[VAL_8:.*]]: i1, %[[VAL_9:.*]]: index):
105 // CHECK: %[[VAL_10:.*]] = arith.constant 0 : index
106 // CHECK: %[[VAL_11:.*]] = arith.cmpi sgt, %[[VAL_9]], %[[VAL_10]] : index
107 // CHECK: cond_br %[[VAL_11]], ^bb2, ^bb3
109 // CHECK: %[[VAL_12:.*]] = fir.call @f2() : () -> i1
110 // CHECK: %[[VAL_13:.*]] = arith.addi %[[VAL_7]], %[[VAL_2]] : index
111 // CHECK: %[[VAL_14:.*]] = arith.constant 1 : index
112 // CHECK: %[[VAL_15:.*]] = arith.subi %[[VAL_9]], %[[VAL_14]] : index
113 // CHECK: br ^bb1(%[[VAL_13]], %[[VAL_12]], %[[VAL_15]] : index, i1, index)
115 // CHECK: return %[[VAL_8]] : i1
120 // iterate_while with an extra loop-carried value
121 func.func @y3(%lo : index, %up : index) -> i1 {
122 %c1 = arith.constant 1 : index
123 %ok1 = arith.constant true
124 %ok4 = fir.call @f2() : () -> i1
125 %ok2:2 = fir.iterate_while (%i = %lo to %up step %c1) and (%ok3 = %ok1) iter_args(%j = %ok4) -> i1 {
126 %ok = fir.call @f2() : () -> i1
127 fir.result %ok3, %ok : i1, i1
129 %andok = arith.andi %ok2#0, %ok2#1 : i1
133 func.func private @f4(i32) -> i1
135 // CHECK-LABEL: func @y3(
136 // CHECK-SAME: %[[VAL_0:.*]]: index,
137 // CHECK-SAME: %[[VAL_1:.*]]: index) -> i1 {
138 // CHECK: %[[VAL_2:.*]] = arith.constant 1 : index
139 // CHECK: %[[VAL_3:.*]] = arith.constant true
140 // CHECK: %[[VAL_4:.*]] = fir.call @f2() : () -> i1
141 // CHECK: br ^bb1(%[[VAL_0]], %[[VAL_3]], %[[VAL_4]] : index, i1, i1)
142 // CHECK: ^bb1(%[[VAL_5:.*]]: index, %[[VAL_6:.*]]: i1, %[[VAL_7:.*]]: i1):
143 // CHECK: %[[VAL_8:.*]] = arith.constant 0 : index
144 // CHECK: %[[VAL_9:.*]] = arith.cmpi slt, %[[VAL_8]], %[[VAL_2]] : index
145 // CHECK: %[[VAL_10:.*]] = arith.cmpi sle, %[[VAL_5]], %[[VAL_1]] : index
146 // CHECK: %[[VAL_11:.*]] = arith.cmpi slt, %[[VAL_2]], %[[VAL_8]] : index
147 // CHECK: %[[VAL_12:.*]] = arith.cmpi sle, %[[VAL_1]], %[[VAL_5]] : index
148 // CHECK: %[[VAL_13:.*]] = arith.andi %[[VAL_9]], %[[VAL_10]] : i1
149 // CHECK: %[[VAL_14:.*]] = arith.andi %[[VAL_11]], %[[VAL_12]] : i1
150 // CHECK: %[[VAL_15:.*]] = arith.ori %[[VAL_13]], %[[VAL_14]] : i1
151 // CHECK: %[[VAL_16:.*]] = arith.andi %[[VAL_6]], %[[VAL_15]] : i1
152 // CHECK: cond_br %[[VAL_16]], ^bb2, ^bb3
154 // CHECK: %[[VAL_17:.*]] = fir.call @f2() : () -> i1
155 // CHECK: %[[VAL_18:.*]] = arith.addi %[[VAL_5]], %[[VAL_2]] : index
156 // CHECK: br ^bb1(%[[VAL_18]], %[[VAL_6]], %[[VAL_17]] : index, i1, i1)
158 // CHECK: %[[VAL_19:.*]] = arith.andi %[[VAL_6]], %[[VAL_7]] : i1
159 // CHECK: return %[[VAL_19]] : i1
161 // CHECK: func private @f4(i32) -> i1
165 // do_loop that returns the final value of the induction
166 func.func @x4(%lo : index, %up : index) -> index {
167 %c1 = arith.constant 1 : index
168 %v = fir.do_loop %i = %lo to %up step %c1 -> index {
169 %i1 = fir.convert %i : (index) -> i32
170 %ok = fir.call @f4(%i1) : (i32) -> i1
171 fir.result %i : index
176 // CHECK-LABEL: func @x4(
177 // CHECK-SAME: %[[VAL_0:.*]]: index,
178 // CHECK-SAME: %[[VAL_1:.*]]: index) -> index {
179 // CHECK: %[[VAL_2:.*]] = arith.constant 1 : index
180 // CHECK: %[[VAL_3:.*]] = arith.subi %[[VAL_1]], %[[VAL_0]] : index
181 // CHECK: %[[VAL_4:.*]] = arith.addi %[[VAL_3]], %[[VAL_2]] : index
182 // CHECK: %[[VAL_5:.*]] = arith.divsi %[[VAL_4]], %[[VAL_2]] : index
183 // CHECK: br ^bb1(%[[VAL_0]], %[[VAL_5]] : index, index)
184 // CHECK: ^bb1(%[[VAL_6:.*]]: index, %[[VAL_7:.*]]: index):
185 // CHECK: %[[VAL_8:.*]] = arith.constant 0 : index
186 // CHECK: %[[VAL_9:.*]] = arith.cmpi sgt, %[[VAL_7]], %[[VAL_8]] : index
187 // CHECK: cond_br %[[VAL_9]], ^bb2, ^bb3
189 // CHECK: %[[VAL_10:.*]] = fir.convert %[[VAL_6]] : (index) -> i32
190 // CHECK: %[[VAL_11:.*]] = fir.call @f4(%[[VAL_10]]) : (i32) -> i1
191 // CHECK: %[[VAL_12:.*]] = arith.addi %[[VAL_6]], %[[VAL_2]] : index
192 // CHECK: %[[VAL_13:.*]] = arith.constant 1 : index
193 // CHECK: %[[VAL_14:.*]] = arith.subi %[[VAL_7]], %[[VAL_13]] : index
194 // CHECK: br ^bb1(%[[VAL_12]], %[[VAL_14]] : index, index)
196 // CHECK: return %[[VAL_6]] : index
201 // iterate_while that returns the final value of both inductions
202 func.func @y4(%lo : index, %up : index) -> index {
203 %c1 = arith.constant 1 : index
204 %ok1 = arith.constant true
205 %v:2 = fir.iterate_while (%i = %lo to %up step %c1) and (%ok2 = %ok1) -> (index, i1) {
206 %i1 = fir.convert %i : (index) -> i32
207 %ok = fir.call @f4(%i1) : (i32) -> i1
208 fir.result %i, %ok : index, i1
213 // CHECK-LABEL: func @y4(
214 // CHECK-SAME: %[[VAL_0:.*]]: index,
215 // CHECK-SAME: %[[VAL_1:.*]]: index) -> index {
216 // CHECK: %[[VAL_2:.*]] = arith.constant 1 : index
217 // CHECK: %[[VAL_3:.*]] = arith.constant true
218 // CHECK: br ^bb1(%[[VAL_0]], %[[VAL_3]] : index, i1)
219 // CHECK: ^bb1(%[[VAL_4:.*]]: index, %[[VAL_5:.*]]: i1):
220 // CHECK: %[[VAL_6:.*]] = arith.constant 0 : index
221 // CHECK: %[[VAL_7:.*]] = arith.cmpi slt, %[[VAL_6]], %[[VAL_2]] : index
222 // CHECK: %[[VAL_8:.*]] = arith.cmpi sle, %[[VAL_4]], %[[VAL_1]] : index
223 // CHECK: %[[VAL_9:.*]] = arith.cmpi slt, %[[VAL_2]], %[[VAL_6]] : index
224 // CHECK: %[[VAL_10:.*]] = arith.cmpi sle, %[[VAL_1]], %[[VAL_4]] : index
225 // CHECK: %[[VAL_11:.*]] = arith.andi %[[VAL_7]], %[[VAL_8]] : i1
226 // CHECK: %[[VAL_12:.*]] = arith.andi %[[VAL_9]], %[[VAL_10]] : i1
227 // CHECK: %[[VAL_13:.*]] = arith.ori %[[VAL_11]], %[[VAL_12]] : i1
228 // CHECK: %[[VAL_14:.*]] = arith.andi %[[VAL_5]], %[[VAL_13]] : i1
229 // CHECK: cond_br %[[VAL_14]], ^bb2, ^bb3
231 // CHECK: %[[VAL_15:.*]] = fir.convert %[[VAL_4]] : (index) -> i32
232 // CHECK: %[[VAL_16:.*]] = fir.call @f4(%[[VAL_15]]) : (i32) -> i1
233 // CHECK: %[[VAL_17:.*]] = arith.addi %[[VAL_4]], %[[VAL_2]] : index
234 // CHECK: br ^bb1(%[[VAL_17]], %[[VAL_16]] : index, i1)
236 // CHECK: return %[[VAL_4]] : index
241 // do_loop that returns the final induction value
242 // and an extra loop-carried value
243 func.func @x5(%lo : index, %up : index) -> index {
244 %c1 = arith.constant 1 : index
245 %s1 = arith.constant 42 : i16
246 %v:2 = fir.do_loop %i = %lo to %up step %c1 iter_args(%s = %s1) -> (index, i16) {
247 %ok = fir.call @f2() : () -> i1
248 %s2 = fir.convert %ok : (i1) -> i16
249 fir.result %i, %s2 : index, i16
251 fir.call @f3(%v#1) : (i16) -> ()
255 // CHECK-LABEL: func @x5(
256 // CHECK-SAME: %[[VAL_0:.*]]: index,
257 // CHECK-SAME: %[[VAL_1:.*]]: index) -> index {
258 // CHECK: %[[VAL_2:.*]] = arith.constant 1 : index
259 // CHECK: %[[VAL_3:.*]] = arith.constant 42 : i16
260 // CHECK: %[[VAL_4:.*]] = arith.subi %[[VAL_1]], %[[VAL_0]] : index
261 // CHECK: %[[VAL_5:.*]] = arith.addi %[[VAL_4]], %[[VAL_2]] : index
262 // CHECK: %[[VAL_6:.*]] = arith.divsi %[[VAL_5]], %[[VAL_2]] : index
263 // CHECK: br ^bb1(%[[VAL_0]], %[[VAL_3]], %[[VAL_6]] : index, i16, index)
264 // CHECK: ^bb1(%[[VAL_7:.*]]: index, %[[VAL_8:.*]]: i16, %[[VAL_9:.*]]: index):
265 // CHECK: %[[VAL_10:.*]] = arith.constant 0 : index
266 // CHECK: %[[VAL_11:.*]] = arith.cmpi sgt, %[[VAL_9]], %[[VAL_10]] : index
267 // CHECK: cond_br %[[VAL_11]], ^bb2, ^bb3
269 // CHECK: %[[VAL_12:.*]] = fir.call @f2() : () -> i1
270 // CHECK: %[[VAL_13:.*]] = fir.convert %[[VAL_12]] : (i1) -> i16
271 // CHECK: %[[VAL_14:.*]] = arith.addi %[[VAL_7]], %[[VAL_2]] : index
272 // CHECK: %[[VAL_15:.*]] = arith.constant 1 : index
273 // CHECK: %[[VAL_16:.*]] = arith.subi %[[VAL_9]], %[[VAL_15]] : index
274 // CHECK: br ^bb1(%[[VAL_14]], %[[VAL_13]], %[[VAL_16]] : index, i16, index)
276 // CHECK: fir.call @f3(%[[VAL_8]]) : (i16) -> ()
277 // CHECK: return %[[VAL_7]] : index
282 // iterate_while that returns the both induction values
283 // and an extra loop-carried value
284 func.func @y5(%lo : index, %up : index) -> index {
285 %c1 = arith.constant 1 : index
286 %s1 = arith.constant 42 : i16
287 %ok1 = arith.constant true
288 %v:3 = fir.iterate_while (%i = %lo to %up step %c1) and (%ok2 = %ok1) iter_args(%s = %s1) -> (index, i1, i16) {
289 %ok = fir.call @f2() : () -> i1
290 %s2 = fir.convert %ok : (i1) -> i16
291 fir.result %i, %ok, %s2 : index, i1, i16
294 %arg = arith.constant 0 : i32
295 %ok4 = fir.call @f4(%arg) : (i32) -> i1
297 fir.call @f3(%v#2) : (i16) -> ()
301 // CHECK-LABEL: func @y5(
302 // CHECK-SAME: %[[VAL_0:.*]]: index,
303 // CHECK-SAME: %[[VAL_1:.*]]: index) -> index {
304 // CHECK: %[[VAL_2:.*]] = arith.constant 1 : index
305 // CHECK: %[[VAL_3:.*]] = arith.constant 42 : i16
306 // CHECK: %[[VAL_4:.*]] = arith.constant true
307 // CHECK: br ^bb1(%[[VAL_0]], %[[VAL_4]], %[[VAL_3]] : index, i1, i16)
308 // CHECK: ^bb1(%[[VAL_5:.*]]: index, %[[VAL_6:.*]]: i1, %[[VAL_7:.*]]: i16):
309 // CHECK: %[[VAL_8:.*]] = arith.constant 0 : index
310 // CHECK: %[[VAL_9:.*]] = arith.cmpi slt, %[[VAL_8]], %[[VAL_2]] : index
311 // CHECK: %[[VAL_10:.*]] = arith.cmpi sle, %[[VAL_5]], %[[VAL_1]] : index
312 // CHECK: %[[VAL_11:.*]] = arith.cmpi slt, %[[VAL_2]], %[[VAL_8]] : index
313 // CHECK: %[[VAL_12:.*]] = arith.cmpi sle, %[[VAL_1]], %[[VAL_5]] : index
314 // CHECK: %[[VAL_13:.*]] = arith.andi %[[VAL_9]], %[[VAL_10]] : i1
315 // CHECK: %[[VAL_14:.*]] = arith.andi %[[VAL_11]], %[[VAL_12]] : i1
316 // CHECK: %[[VAL_15:.*]] = arith.ori %[[VAL_13]], %[[VAL_14]] : i1
317 // CHECK: %[[VAL_16:.*]] = arith.andi %[[VAL_6]], %[[VAL_15]] : i1
318 // CHECK: cond_br %[[VAL_16]], ^bb2, ^bb3
320 // CHECK: %[[VAL_17:.*]] = fir.call @f2() : () -> i1
321 // CHECK: %[[VAL_18:.*]] = fir.convert %[[VAL_17]] : (i1) -> i16
322 // CHECK: %[[VAL_19:.*]] = arith.addi %[[VAL_5]], %[[VAL_2]] : index
323 // CHECK: br ^bb1(%[[VAL_19]], %[[VAL_17]], %[[VAL_18]] : index, i1, i16)
325 // CHECK: cond_br %[[VAL_6]], ^bb4, ^bb5
327 // CHECK: %[[VAL_20:.*]] = arith.constant 0 : i32
328 // CHECK: %[[VAL_21:.*]] = fir.call @f4(%[[VAL_20]]) : (i32) -> i1
331 // CHECK: fir.call @f3(%[[VAL_7]]) : (i16) -> ()
332 // CHECK: return %[[VAL_5]] : index