Break circular dependency between FIR dialect and utilities
[llvm-project.git] / flang / test / Fir / loop01.fir
blob72ca1c3989e453d41f3605c14cb48bc657f8e654
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
6     fir.if %b {
7       fir.store %iv to %addr : !fir.ref<index>
8     } else {
9       %zero = arith.constant 0 : index
10       fir.store %zero to %addr : !fir.ref<index>
11     }
12   }
13   return
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
27 // CHECK:     ^bb2:
28 // CHECK:       cond_br %[[VAL_3]], ^bb3, ^bb4
29 // CHECK:     ^bb3:
30 // CHECK:       fir.store %[[VAL_8]] to %[[VAL_4]] : !fir.ref<index>
31 // CHECK:       br ^bb5
32 // CHECK:     ^bb4:
33 // CHECK:       %[[VAL_12:.*]] = arith.constant 0 : index
34 // CHECK:       fir.store %[[VAL_12]] to %[[VAL_4]] : !fir.ref<index>
35 // CHECK:       br ^bb5
36 // CHECK:     ^bb5:
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)
41 // CHECK:     ^bb6:
42 // CHECK:       return
43 // CHECK:     }
44 // CHECK:     func private @f2() -> i1
46 // -----
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
52     fir.result %ok2 : i1
53   }
54   return
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
73 // CHECK:   ^bb2:
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)
77 // CHECK:   ^bb3:
78 // CHECK:     return
79 // CHECK:   }
80 // CHECK:   func private @f3(i16)
82 // -----
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
90     fir.result %ok : i1
91   }
92   return %ok2 : 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
108 // CHECK:         ^bb2:
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)
114 // CHECK:         ^bb3:
115 // CHECK:           return %[[VAL_8]] : i1
116 // CHECK:         }
118 // -----
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
128   }
129   %andok = arith.andi %ok2#0, %ok2#1 : i1
130   return %andok : 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
153 // CHECK:         ^bb2:
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)
157 // CHECK:         ^bb3:
158 // CHECK:           %[[VAL_19:.*]] = arith.andi %[[VAL_6]], %[[VAL_7]] : i1
159 // CHECK:           return %[[VAL_19]] : i1
160 // CHECK:         }
161 // CHECK:         func private @f4(i32) -> i1
163 // -----
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
172   }
173   return %v : 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
188 // CHECK:         ^bb2:
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)
195 // CHECK:         ^bb3:
196 // CHECK:           return %[[VAL_6]] : index
197 // CHECK:         }
199 // -----
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
209   }
210   return %v#0 : index
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
230 // CHECK:         ^bb2:
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)
235 // CHECK:         ^bb3:
236 // CHECK:           return %[[VAL_4]] : index
237 // CHECK:         }
239 // -----
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
250   }
251   fir.call @f3(%v#1) : (i16) -> ()
252   return %v#0 : index
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
268 // CHECK:         ^bb2:
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)
275 // CHECK:         ^bb3:
276 // CHECK:           fir.call @f3(%[[VAL_8]]) : (i16) -> ()
277 // CHECK:           return %[[VAL_7]] : index
278 // CHECK:         }
280 // -----
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
292   }
293   fir.if %v#1 {
294     %arg = arith.constant 0 : i32
295     %ok4 = fir.call @f4(%arg) : (i32) -> i1
296   }
297   fir.call @f3(%v#2) : (i16) -> ()
298   return %v#0 : index
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
319 // CHECK:         ^bb2:
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)
324 // CHECK:         ^bb3:
325 // CHECK:           cond_br %[[VAL_6]], ^bb4, ^bb5
326 // CHECK:         ^bb4:
327 // CHECK:           %[[VAL_20:.*]] = arith.constant 0 : i32
328 // CHECK:           %[[VAL_21:.*]] = fir.call @f4(%[[VAL_20]]) : (i32) -> i1
329 // CHECK:           br ^bb5
330 // CHECK:         ^bb5:
331 // CHECK:           fir.call @f3(%[[VAL_7]]) : (i16) -> ()
332 // CHECK:           return %[[VAL_5]] : index
333 // CHECK:         }