1// RUN: mlir-opt -test-int-range-inference -canonicalize %s | FileCheck %s
2
3// CHECK-LABEL: func @add_min_max
4// CHECK: %[[c3:.*]] = arith.constant 3 : index
5// CHECK: return %[[c3]]
6func.func @add_min_max(%a: index, %b: index) -> index {
7    %c1 = arith.constant 1 : index
8    %c2 = arith.constant 2 : index
9    %0 = arith.minsi %a, %c1 : index
10    %1 = arith.maxsi %0, %c1 : index
11    %2 = arith.minui %b, %c2 : index
12    %3 = arith.maxui %2, %c2 : index
13    %4 = arith.addi %1, %3 : index
14    func.return %4 : index
15}
16
17// CHECK-LABEL: func @add_lower_bound
18// CHECK: %[[sge:.*]] = arith.cmpi sge
19// CHECK: return %[[sge]]
20func.func @add_lower_bound(%a : i32, %b : i32) -> i1 {
21    %c1 = arith.constant 1 : i32
22    %c2 = arith.constant 2 : i32
23    %0 = arith.maxsi %a, %c1 : i32
24    %1 = arith.maxsi %b, %c1 : i32
25    %2 = arith.addi %0, %1 : i32
26    %3 = arith.cmpi sge, %2, %c2 : i32
27    %4 = arith.cmpi uge, %2, %c2 : i32
28    %5 = arith.andi %3, %4 : i1
29    func.return %5 : i1
30}
31
32// CHECK-LABEL: func @sub_signed_vs_unsigned
33// CHECK-NOT: arith.cmpi sle
34// CHECK: %[[unsigned:.*]] = arith.cmpi ule
35// CHECK: return %[[unsigned]] : i1
36func.func @sub_signed_vs_unsigned(%v : i64) -> i1 {
37    %c0 = arith.constant 0 : i64
38    %c2 = arith.constant 2 : i64
39    %c-5 = arith.constant -5 : i64
40    %0 = arith.minsi %v, %c2 : i64
41    %1 = arith.maxsi %0, %c-5 : i64
42    %2 = arith.subi %1, %c2 : i64
43    %3 = arith.cmpi sle, %2, %c0 : i64
44    %4 = arith.cmpi ule, %2, %c0 : i64
45    %5 = arith.andi %3, %4 : i1
46    func.return %5 : i1
47}
48
49// CHECK-LABEL: func @multiply_negatives
50// CHECK: %[[false:.*]] = arith.constant false
51// CHECK: return %[[false]]
52func.func @multiply_negatives(%a : index, %b : index) -> i1 {
53    %c2 = arith.constant 2 : index
54    %c3 = arith.constant 3 : index
55    %c_1 = arith.constant -1 : index
56    %c_2 = arith.constant -2 : index
57    %c_4 = arith.constant -4 : index
58    %c_12 = arith.constant -12 : index
59    %0 = arith.maxsi %a, %c2 : index
60    %1 = arith.minsi %0, %c3 : index
61    %2 = arith.minsi %b, %c_1 : index
62    %3 = arith.maxsi %2, %c_4 : index
63    %4 = arith.muli %1, %3 : index
64    %5 = arith.cmpi slt, %4, %c_12 : index
65    %6 = arith.cmpi slt, %c_1, %4 : index
66    %7 = arith.ori %5, %6 : i1
67    func.return %7 : i1
68}
69
70// CHECK-LABEL: func @multiply_unsigned_bounds
71// CHECK: %[[true:.*]] = arith.constant true
72// CHECK: return %[[true]]
73func.func @multiply_unsigned_bounds(%a : i16, %b : i16) -> i1 {
74    %c0 = arith.constant 0 : i16
75    %c4 = arith.constant 4 : i16
76    %c_mask = arith.constant 0x3fff : i16
77    %c_bound = arith.constant 0xfffc : i16
78    %0 = arith.andi %a, %c_mask : i16
79    %1 = arith.minui %b, %c4 : i16
80    %2 = arith.muli %0, %1 : i16
81    %3 = arith.cmpi uge, %2, %c0 : i16
82    %4 = arith.cmpi ule, %2, %c_bound : i16
83    %5 = arith.andi %3, %4 : i1
84    func.return %5 : i1
85}
86
87// CHECK-LABEL: @for_loop_with_increasing_arg
88// CHECK: %[[ret:.*]] = arith.cmpi ule
89// CHECK: return %[[ret]]
90func.func @for_loop_with_increasing_arg() -> i1 {
91    %c0 = arith.constant 0 : index
92    %c1 = arith.constant 1 : index
93    %c4 = arith.constant 4 : index
94    %c16 = arith.constant 16 : index
95    %0 = scf.for %arg0 = %c0 to %c4 step %c1 iter_args(%arg1 = %c0) -> index {
96        %10 = arith.addi %arg0, %arg1 : index
97        scf.yield %10 : index
98    }
99    %1 = arith.cmpi ule, %0, %c16 : index
100    func.return %1 : i1
101}
102
103// CHECK-LABEL: @for_loop_with_constant_result
104// CHECK: %[[true:.*]] = arith.constant true
105// CHECK: return %[[true]]
106func.func @for_loop_with_constant_result() -> i1 {
107    %c0 = arith.constant 0 : index
108    %c1 = arith.constant 1 : index
109    %c4 = arith.constant 4 : index
110    %true = arith.constant true
111    %0 = scf.for %arg0 = %c0 to %c4 step %c1 iter_args(%arg1 = %true) -> i1 {
112        %10 = arith.cmpi ule, %arg0, %c4 : index
113        %11 = arith.andi %10, %arg1 : i1
114        scf.yield %11 : i1
115    }
116    func.return %0 : i1
117}
118
119// Test to catch a bug present in some versions of the data flow analysis
120// CHECK-LABEL: func @while_false
121// CHECK: %[[false:.*]] = arith.constant false
122// CHECK: scf.condition(%[[false]])
123func.func @while_false(%arg0 : index) -> index {
124    %c0 = arith.constant 0 : index
125    %c1 = arith.constant 1 : index
126    %c2 = arith.constant 2 : index
127    %0 = arith.divui %arg0, %c2 : index
128    %1 = scf.while (%arg1 = %0) : (index) -> index {
129        %2 = arith.cmpi slt, %arg1, %c0 : index
130        scf.condition(%2) %arg1 : index
131    } do {
132    ^bb0(%arg2 : index):
133        scf.yield %c2 : index
134    }
135    func.return %1 : index
136}
137
138// CHECK-LABEL: func @div_bounds_positive
139// CHECK: %[[true:.*]] = arith.constant true
140// CHECK: return %[[true]]
141func.func @div_bounds_positive(%arg0 : index) -> i1 {
142    %c0 = arith.constant 0 : index
143    %c2 = arith.constant 2 : index
144    %c4 = arith.constant 4 : index
145    %0 = arith.maxsi %arg0, %c2 : index
146    %1 = arith.divsi %c4, %0 : index
147    %2 = arith.divui %c4, %0 : index
148
149    %3 = arith.cmpi sge, %1, %c0 : index
150    %4 = arith.cmpi sle, %1, %c2 : index
151    %5 = arith.cmpi sge, %2, %c0 : index
152    %6 = arith.cmpi sle, %1, %c2 : index
153
154    %7 = arith.andi %3, %4 : i1
155    %8 = arith.andi %7, %5 : i1
156    %9 = arith.andi %8, %6 : i1
157    func.return %9 : i1
158}
159
160// CHECK-LABEL: func @div_bounds_negative
161// CHECK: %[[true:.*]] = arith.constant true
162// CHECK: return %[[true]]
163func.func @div_bounds_negative(%arg0 : index) -> i1 {
164    %c0 = arith.constant 0 : index
165    %c_2 = arith.constant -2 : index
166    %c4 = arith.constant 4 : index
167    %0 = arith.minsi %arg0, %c_2 : index
168    %1 = arith.divsi %c4, %0 : index
169    %2 = arith.divui %c4, %0 : index
170
171    %3 = arith.cmpi sle, %1, %c0 : index
172    %4 = arith.cmpi sge, %1, %c_2 : index
173    %5 = arith.cmpi eq, %2, %c0 : index
174
175    %7 = arith.andi %3, %4 : i1
176    %8 = arith.andi %7, %5 : i1
177    func.return %8 : i1
178}
179
180// CHECK-LABEL: func @div_zero_undefined
181// CHECK: %[[ret:.*]] = arith.cmpi ule
182// CHECK: return %[[ret]]
183func.func @div_zero_undefined(%arg0 : index) -> i1 {
184    %c0 = arith.constant 0 : index
185    %c1 = arith.constant 1 : index
186    %c4 = arith.constant 4 : index
187    %0 = arith.andi %arg0, %c1 : index
188    %1 = arith.divui %c4, %0 : index
189    %2 = arith.cmpi ule, %1, %c4 : index
190    func.return %2 : i1
191}
192
193// CHECK-LABEL: func @ceil_divui
194// CHECK: %[[ret:.*]] = arith.cmpi eq
195// CHECK: return %[[ret]]
196func.func @ceil_divui(%arg0 : index) -> i1 {
197    %c0 = arith.constant 0 : index
198    %c1 = arith.constant 1 : index
199    %c3 = arith.constant 3 : index
200    %c4 = arith.constant 4 : index
201
202    %0 = arith.minui %arg0, %c3 : index
203    %1 = arith.maxui %0, %c1 : index
204    %2 = arith.ceildivui %1, %c4 : index
205    %3 = arith.cmpi eq, %2, %c1 : index
206
207    %4 = arith.maxui %0, %c0 : index
208    %5 = arith.ceildivui %4, %c4 : index
209    %6 = arith.cmpi eq, %5, %c1 : index
210    %7 = arith.andi %3, %6 : i1
211    func.return %7 : i1
212}
213
214// CHECK-LABEL: func @ceil_divsi
215// CHECK: %[[ret:.*]] = arith.cmpi eq
216// CHECK: return %[[ret]]
217func.func @ceil_divsi(%arg0 : index) -> i1 {
218    %c0 = arith.constant 0 : index
219    %c1 = arith.constant 1 : index
220    %c3 = arith.constant 3 : index
221    %c4 = arith.constant 4 : index
222    %c-4 = arith.constant -4 : index
223
224    %0 = arith.minsi %arg0, %c3 : index
225    %1 = arith.maxsi %0, %c1 : index
226    %2 = arith.ceildivsi %1, %c4 : index
227    %3 = arith.cmpi eq, %2, %c1 : index
228    %4 = arith.ceildivsi %1, %c-4 : index
229    %5 = arith.cmpi eq, %4, %c0 : index
230    %6 = arith.andi %3, %5 : i1
231
232    %7 = arith.maxsi %0, %c0 : index
233    %8 = arith.ceildivsi %7, %c4 : index
234    %9 = arith.cmpi eq, %8, %c1 : index
235    %10 = arith.andi %6, %9 : i1
236    func.return %10 : i1
237}
238
239// CHECK-LABEL: func @floor_divsi
240// CHECK: %[[true:.*]] = arith.constant true
241// CHECK: return %[[true]]
242func.func @floor_divsi(%arg0 : index) -> i1 {
243    %c4 = arith.constant 4 : index
244    %c-1 = arith.constant -1 : index
245    %c-3 = arith.constant -3 : index
246    %c-4 = arith.constant -4 : index
247
248    %0 = arith.minsi %arg0, %c-1 : index
249    %1 = arith.maxsi %0, %c-4 : index
250    %2 = arith.floordivsi %1, %c4 : index
251    %3 = arith.cmpi eq, %2, %c-1 : index
252    func.return %3 : i1
253}
254
255// CHECK-LABEL: func @remui_base
256// CHECK: %[[true:.*]] = arith.constant true
257// CHECK: return %[[true]]
258func.func @remui_base(%arg0 : index, %arg1 : index ) -> i1 {
259    %c2 = arith.constant 2 : index
260    %c4 = arith.constant 4 : index
261
262    %0 = arith.minui %arg1, %c4 : index
263    %1 = arith.maxui %0, %c2 : index
264    %2 = arith.remui %arg0, %1 : index
265    %3 = arith.cmpi ult, %2, %c4 : index
266    func.return %3 : i1
267}
268
269// CHECK-LABEL: func @remsi_base
270// CHECK: %[[ret:.*]] = arith.cmpi sge
271// CHECK: return %[[ret]]
272func.func @remsi_base(%arg0 : index, %arg1 : index ) -> i1 {
273    %c0 = arith.constant 0 : index
274    %c2 = arith.constant 2 : index
275    %c4 = arith.constant 4 : index
276    %c-4 = arith.constant -4 : index
277    %true = arith.constant true
278
279    %0 = arith.minsi %arg1, %c4 : index
280    %1 = arith.maxsi %0, %c2 : index
281    %2 = arith.remsi %arg0, %1 : index
282    %3 = arith.cmpi sgt, %2, %c-4 : index
283    %4 = arith.cmpi slt, %2, %c4 : index
284    %5 = arith.cmpi sge, %2, %c0 : index
285    %6 = arith.andi %3, %4 : i1
286    %7 = arith.andi %5, %6 : i1
287    func.return %7 : i1
288}
289
290// CHECK-LABEL: func @remsi_positive
291// CHECK: %[[true:.*]] = arith.constant true
292// CHECK: return %[[true]]
293func.func @remsi_positive(%arg0 : index, %arg1 : index ) -> i1 {
294    %c0 = arith.constant 0 : index
295    %c2 = arith.constant 2 : index
296    %c4 = arith.constant 4 : index
297    %true = arith.constant true
298
299    %0 = arith.minsi %arg1, %c4 : index
300    %1 = arith.maxsi %0, %c2 : index
301    %2 = arith.maxsi %arg0, %c0 : index
302    %3 = arith.remsi %2, %1 : index
303    %4 = arith.cmpi sge, %3, %c0 : index
304    %5 = arith.cmpi slt, %3, %c4 : index
305    %6 = arith.andi %4, %5 : i1
306    func.return %6 : i1
307}
308
309// CHECK-LABEL: func @remui_restricted
310// CHECK: %[[true:.*]] = arith.constant true
311// CHECK: return %[[true]]
312func.func @remui_restricted(%arg0 : index) -> i1 {
313    %c2 = arith.constant 2 : index
314    %c3 = arith.constant 3 : index
315    %c4 = arith.constant 4 : index
316
317    %0 = arith.minui %arg0, %c3 : index
318    %1 = arith.maxui %0, %c2 : index
319    %2 = arith.remui %1, %c4 : index
320    %3 = arith.cmpi ule, %2, %c3 : index
321    %4 = arith.cmpi uge, %2, %c2 : index
322    %5 = arith.andi %3, %4 : i1
323    func.return %5 : i1
324}
325
326// CHECK-LABEL: func @remsi_restricted
327// CHECK: %[[true:.*]] = arith.constant true
328// CHECK: return %[[true]]
329func.func @remsi_restricted(%arg0 : index) -> i1 {
330    %c2 = arith.constant 2 : index
331    %c3 = arith.constant 3 : index
332    %c-4 = arith.constant -4 : index
333
334    %0 = arith.minsi %arg0, %c3 : index
335    %1 = arith.maxsi %0, %c2 : index
336    %2 = arith.remsi %1, %c-4 : index
337    %3 = arith.cmpi ule, %2, %c3 : index
338    %4 = arith.cmpi uge, %2, %c2 : index
339    %5 = arith.andi %3, %4 : i1
340    func.return %5 : i1
341}
342
343// CHECK-LABEL: func @remui_restricted_fails
344// CHECK: %[[ret:.*]] = arith.cmpi ne
345// CHECK: return %[[ret]]
346func.func @remui_restricted_fails(%arg0 : index) -> i1 {
347    %c2 = arith.constant 2 : index
348    %c3 = arith.constant 3 : index
349    %c4 = arith.constant 4 : index
350    %c5 = arith.constant 5 : index
351
352    %0 = arith.minui %arg0, %c5 : index
353    %1 = arith.maxui %0, %c3 : index
354    %2 = arith.remui %1, %c4 : index
355    %3 = arith.cmpi ne, %2, %c2 : index
356    func.return %3 : i1
357}
358
359// CHECK-LABEL: func @remsi_restricted_fails
360// CHECK: %[[ret:.*]] = arith.cmpi ne
361// CHECK: return %[[ret]]
362func.func @remsi_restricted_fails(%arg0 : index) -> i1 {
363    %c2 = arith.constant 2 : index
364    %c3 = arith.constant 3 : index
365    %c5 = arith.constant 5 : index
366    %c-4 = arith.constant -4 : index
367
368    %0 = arith.minsi %arg0, %c5 : index
369    %1 = arith.maxsi %0, %c3 : index
370    %2 = arith.remsi %1, %c-4 : index
371    %3 = arith.cmpi ne, %2, %c2 : index
372    func.return %3 : i1
373}
374
375// CHECK-LABEL: func @andi
376// CHECK: %[[ret:.*]] = arith.cmpi ugt
377// CHECK: return %[[ret]]
378func.func @andi(%arg0 : index) -> i1 {
379    %c2 = arith.constant 2 : index
380    %c5 = arith.constant 5 : index
381    %c7 = arith.constant 7 : index
382
383    %0 = arith.minsi %arg0, %c5 : index
384    %1 = arith.maxsi %0, %c2 : index
385    %2 = arith.andi %1, %c7 : index
386    %3 = arith.cmpi ugt, %2, %c5 : index
387    %4 = arith.cmpi ule, %2, %c7 : index
388    %5 = arith.andi %3, %4 : i1
389    func.return %5 : i1
390}
391
392// CHECK-LABEL: func @andi_doesnt_make_nonnegative
393// CHECK: %[[ret:.*]] = arith.cmpi sge
394// CHECK: return %[[ret]]
395func.func @andi_doesnt_make_nonnegative(%arg0 : index) -> i1 {
396    %c0 = arith.constant 0 : index
397    %c1 = arith.constant 1 : index
398    %0 = arith.addi %arg0, %c1 : index
399    %1 = arith.andi %arg0, %0 : index
400    %2 = arith.cmpi sge, %1, %c0 : index
401    func.return %2 : i1
402}
403
404
405// CHECK-LABEL: func @ori
406// CHECK: %[[true:.*]] = arith.constant true
407// CHECK: return %[[true]]
408func.func @ori(%arg0 : i128, %arg1 : i128) -> i1 {
409    %c-1 = arith.constant -1 : i128
410    %c0 = arith.constant 0 : i128
411
412    %0 = arith.minsi %arg1, %c-1 : i128
413    %1 = arith.ori %arg0, %0 : i128
414    %2 = arith.cmpi slt, %1, %c0 : i128
415    func.return %2 : i1
416}
417
418// CHECK-LABEL: func @xori
419// CHECK: %[[false:.*]] = arith.constant false
420// CHECK: return %[[false]]
421func.func @xori(%arg0 : i64, %arg1 : i64) -> i1 {
422    %c0 = arith.constant 0 : i64
423    %c7 = arith.constant 7 : i64
424    %c15 = arith.constant 15 : i64
425    %true = arith.constant true
426
427    %0 = arith.minui %arg0, %c7 : i64
428    %1 = arith.minui %arg1, %c15 : i64
429    %2 = arith.xori %0, %1 : i64
430    %3 = arith.cmpi sle, %2, %c15 : i64
431    %4 = arith.xori %3, %true : i1
432    func.return %4 : i1
433}
434
435// CHECK-LABEL: func @extui
436// CHECK: %[[true:.*]] = arith.constant true
437// CHECK: return %[[true]]
438func.func @extui(%arg0 : i16) -> i1 {
439    %ci16_max = arith.constant 0xffff : i32
440    %0 = arith.extui %arg0 : i16 to i32
441    %1 = arith.cmpi ule, %0, %ci16_max : i32
442    func.return %1 : i1
443}
444
445// CHECK-LABEL: func @extsi
446// CHECK: %[[true:.*]] = arith.constant true
447// CHECK: return %[[true]]
448func.func @extsi(%arg0 : i16) -> i1 {
449    %ci16_smax = arith.constant 0x7fff : i32
450    %ci16_smin = arith.constant 0xffff8000 : i32
451    %0 = arith.extsi %arg0 : i16 to i32
452    %1 = arith.cmpi sle, %0, %ci16_smax : i32
453    %2 = arith.cmpi sge, %0, %ci16_smin : i32
454    %3 = arith.andi %1, %2 : i1
455    func.return %3 : i1
456}
457
458// CHECK-LABEL: func @trunci
459// CHECK: %[[true:.*]] = arith.constant true
460// CHECK: return %[[true]]
461func.func @trunci(%arg0 : i32) -> i1 {
462    %c-14_i32 = arith.constant -14 : i32
463    %c-14_i16 = arith.constant -14 : i16
464    %ci16_smin = arith.constant 0xffff8000 : i32
465    %0 = arith.minsi %arg0, %c-14_i32 : i32
466    %1 = arith.trunci %0 : i32 to i16
467    %2 = arith.cmpi sle, %1, %c-14_i16 : i16
468    %3 = arith.extsi %1 : i16 to i32
469    %4 = arith.cmpi sle, %3, %c-14_i32 : i32
470    %5 = arith.cmpi sge, %3, %ci16_smin : i32
471    %6 = arith.andi %2, %4 : i1
472    %7 = arith.andi %6, %5 : i1
473    func.return %7 : i1
474}
475
476// CHECK-LABEL: func @index_cast
477// CHECK: %[[true:.*]] = arith.constant true
478// CHECK: return %[[true]]
479func.func @index_cast(%arg0 : index) -> i1 {
480    %ci32_smin = arith.constant 0xffffffff80000000 : i64
481    %0 = arith.index_cast %arg0 : index to i32
482    %1 = arith.index_cast %0 : i32 to index
483    %2 = arith.index_cast %ci32_smin : i64 to index
484    %3 = arith.cmpi sge, %1, %2 : index
485    func.return %3 : i1
486}
487
488// CHECK-LABEL: func @shli
489// CHECK: %[[ret:.*]] = arith.cmpi sgt
490// CHECK: return %[[ret]]
491func.func @shli(%arg0 : i32, %arg1 : i1) -> i1 {
492    %c2 = arith.constant 2 : i32
493    %c4 = arith.constant 4 : i32
494    %c8 = arith.constant 8 : i32
495    %c32 = arith.constant 32 : i32
496    %c-1 = arith.constant -1 : i32
497    %c-16 = arith.constant -16 : i32
498    %0 = arith.maxsi %arg0, %c-1 : i32
499    %1 = arith.minsi %0, %c2 : i32
500    %2 = arith.select %arg1, %c2, %c4 : i32
501    %3 = arith.shli %1, %2 : i32
502    %4 = arith.cmpi sge, %3, %c-16 : i32
503    %5 = arith.cmpi sle, %3, %c32 : i32
504    %6 = arith.cmpi sgt, %3, %c8 : i32
505    %7 = arith.andi %4, %5 : i1
506    %8 = arith.andi %7, %6 : i1
507    func.return %8 : i1
508}
509
510// CHECK-LABEL: func @shrui
511// CHECK: %[[ret:.*]] = arith.cmpi uge
512// CHECK: return %[[ret]]
513func.func @shrui(%arg0 : i1) -> i1 {
514    %c2 = arith.constant 2 : i32
515    %c4 = arith.constant 4 : i32
516    %c8 = arith.constant 8 : i32
517    %c32 = arith.constant 32 : i32
518    %0 = arith.select %arg0, %c2, %c4 : i32
519    %1 = arith.shrui %c32, %0 : i32
520    %2 = arith.cmpi ule, %1, %c8 : i32
521    %3 = arith.cmpi uge, %1, %c2 : i32
522    %4 = arith.cmpi uge, %1, %c8 : i32
523    %5 = arith.andi %2, %3 : i1
524    %6 = arith.andi %5, %4 : i1
525    func.return %6 : i1
526}
527
528// CHECK-LABEL: func @shrsi
529// CHECK: %[[ret:.*]] = arith.cmpi slt
530// CHECK: return %[[ret]]
531func.func @shrsi(%arg0 : i32, %arg1 : i1) -> i1 {
532    %c2 = arith.constant 2 : i32
533    %c4 = arith.constant 4 : i32
534    %c8 = arith.constant 8 : i32
535    %c32 = arith.constant 32 : i32
536    %c-8 = arith.constant -8 : i32
537    %c-32 = arith.constant -32 : i32
538    %0 = arith.maxsi %arg0, %c-32 : i32
539    %1 = arith.minsi %0, %c32 : i32
540    %2 = arith.select %arg1, %c2, %c4 : i32
541    %3 = arith.shrsi %1, %2 : i32
542    %4 = arith.cmpi sge, %3, %c-8 : i32
543    %5 = arith.cmpi sle, %3, %c8 : i32
544    %6 = arith.cmpi slt, %3, %c2 : i32
545    %7 = arith.andi %4, %5 : i1
546    %8 = arith.andi %7, %6 : i1
547    func.return %8 : i1
548}
549
550// CHECK-LABEL: func @no_aggressive_eq
551// CHECK: %[[ret:.*]] = arith.cmpi eq
552// CHECK: return %[[ret]]
553func.func @no_aggressive_eq(%arg0 : index) -> i1 {
554    %c1 = arith.constant 1 : index
555    %0 = arith.andi %arg0, %c1 : index
556    %1 = arith.minui %arg0, %c1 : index
557    %2 = arith.cmpi eq, %0, %1 : index
558    func.return %2 : i1
559}
560
561// CHECK-LABEL: func @select_union
562// CHECK: %[[ret:.*]] = arith.cmpi ne
563// CHECK: return %[[ret]]
564
565func.func @select_union(%arg0 : index, %arg1 : i1) -> i1 {
566    %c64 = arith.constant 64 : index
567    %c100 = arith.constant 100 : index
568    %c128 = arith.constant 128 : index
569    %c192 = arith.constant 192 : index
570    %0 = arith.remui %arg0, %c64 : index
571    %1 = arith.addi %0, %c128 : index
572    %2 = arith.select %arg1, %0, %1 : index
573    %3 = arith.cmpi slt, %2, %c192 : index
574    %4 = arith.cmpi ne, %c100, %2 : index
575    %5 = arith.andi %3, %4 : i1
576    func.return %5 : i1
577}
578
579// CHECK-LABEL: func @if_union
580// CHECK: %[[true:.*]] = arith.constant true
581// CHECK: return %[[true]]
582func.func @if_union(%arg0 : index, %arg1 : i1) -> i1 {
583    %c4 = arith.constant 4 : index
584    %c16 = arith.constant 16 : index
585    %c-1 = arith.constant -1 : index
586    %c-4 = arith.constant -4 : index
587    %0 = arith.minui %arg0, %c4 : index
588    %1 = scf.if %arg1 -> index {
589        %10 = arith.muli %0, %0 : index
590        scf.yield %10 : index
591    } else {
592        %20 = arith.muli %0, %c-1 : index
593        scf.yield %20 : index
594    }
595    %2 = arith.cmpi sle, %1, %c16 : index
596    %3 = arith.cmpi sge, %1, %c-4 : index
597    %4 = arith.andi %2, %3 : i1
598    func.return %4 : i1
599}
600
601// CHECK-LABEL: func @branch_union
602// CHECK: %[[true:.*]] = arith.constant true
603// CHECK: return %[[true]]
604func.func @branch_union(%arg0 : index, %arg1 : i1) -> i1 {
605    %c4 = arith.constant 4 : index
606    %c16 = arith.constant 16 : index
607    %c-1 = arith.constant -1 : index
608    %c-4 = arith.constant -4 : index
609    %0 = arith.minui %arg0, %c4 : index
610    cf.cond_br %arg1, ^bb1, ^bb2
611^bb1 :
612    %1 = arith.muli %0, %0 : index
613    cf.br ^bb3(%1 : index)
614^bb2 :
615    %2 = arith.muli %0, %c-1 : index
616    cf.br ^bb3(%2 : index)
617^bb3(%3 : index) :
618    %4 = arith.cmpi sle, %3, %c16 : index
619    %5 = arith.cmpi sge, %3, %c-4 : index
620    %6 = arith.andi %4, %5 : i1
621    func.return %6 : i1
622}
623
624// CHECK-LABEL: func @loop_bound_not_inferred_with_branch
625// CHECK-DAG: %[[min:.*]] = arith.cmpi sge
626// CHECK-DAG: %[[max:.*]] = arith.cmpi slt
627// CHECK-DAG: %[[ret:.*]] = arith.andi %[[min]], %[[max]]
628// CHECK: return %[[ret]]
629func.func @loop_bound_not_inferred_with_branch(%arg0 : index, %arg1 : i1) -> i1 {
630    %c0 = arith.constant 0 : index
631    %c1 = arith.constant 1 : index
632    %c4 = arith.constant 4 : index
633    %0 = arith.minui %arg0, %c4 : index
634    cf.br ^bb2(%c0 : index)
635^bb1(%1 : index) :
636    %2 = arith.addi %1, %c1 : index
637    cf.br ^bb2(%2 : index)
638^bb2(%3 : index):
639    %4 = arith.cmpi ult, %3, %c4 : index
640    cf.cond_br %4, ^bb1(%3 : index), ^bb3(%3 : index)
641^bb3(%5 : index) :
642    %6 = arith.cmpi sge, %5, %c0 : index
643    %7 = arith.cmpi slt, %5, %c4 : index
644    %8 = arith.andi %6, %7 : i1
645    func.return %8 : i1
646}
647
648