Revert "[InstCombine] Support gep nuw in icmp folds" (#118698)
[llvm-project.git] / llvm / test / Transforms / InstCombine / icmp-dom.ll
blob3cf3a7af77041c644973be2fe4dc3dd5d75483db
1 ; NOTE: Assertions have been autogenerated by utils/update_test_checks.py
2 ; RUN: opt < %s -passes=instcombine -S | FileCheck %s
4 define void @idom_sign_bit_check_edge_dominates(i64 %a) {
5 ; CHECK-LABEL: @idom_sign_bit_check_edge_dominates(
6 ; CHECK-NEXT:  entry:
7 ; CHECK-NEXT:    [[CMP:%.*]] = icmp slt i64 [[A:%.*]], 0
8 ; CHECK-NEXT:    br i1 [[CMP]], label [[LAND_LHS_TRUE:%.*]], label [[LOR_RHS:%.*]]
9 ; CHECK:       land.lhs.true:
10 ; CHECK-NEXT:    br label [[LOR_END:%.*]]
11 ; CHECK:       lor.rhs:
12 ; CHECK-NEXT:    [[CMP2_NOT:%.*]] = icmp eq i64 [[A]], 0
13 ; CHECK-NEXT:    br i1 [[CMP2_NOT]], label [[LOR_END]], label [[LAND_RHS:%.*]]
14 ; CHECK:       land.rhs:
15 ; CHECK-NEXT:    br label [[LOR_END]]
16 ; CHECK:       lor.end:
17 ; CHECK-NEXT:    ret void
19 entry:
20   %cmp = icmp slt i64 %a, 0
21   br i1 %cmp, label %land.lhs.true, label %lor.rhs
23 land.lhs.true:
24   br label %lor.end
26 lor.rhs:
27   %cmp2 = icmp sgt i64 %a, 0
28   br i1 %cmp2, label %land.rhs, label %lor.end
30 land.rhs:
31   br label %lor.end
33 lor.end:
34   ret void
37 define void @idom_sign_bit_check_edge_not_dominates(i64 %a, i1 %c1) {
38 ; CHECK-LABEL: @idom_sign_bit_check_edge_not_dominates(
39 ; CHECK-NEXT:  entry:
40 ; CHECK-NEXT:    [[CMP:%.*]] = icmp slt i64 [[A:%.*]], 0
41 ; CHECK-NEXT:    br i1 [[CMP]], label [[LAND_LHS_TRUE:%.*]], label [[LOR_RHS:%.*]]
42 ; CHECK:       land.lhs.true:
43 ; CHECK-NEXT:    br i1 [[C1:%.*]], label [[LOR_END:%.*]], label [[LOR_RHS]]
44 ; CHECK:       lor.rhs:
45 ; CHECK-NEXT:    [[CMP2:%.*]] = icmp sgt i64 [[A]], 0
46 ; CHECK-NEXT:    br i1 [[CMP2]], label [[LAND_RHS:%.*]], label [[LOR_END]]
47 ; CHECK:       land.rhs:
48 ; CHECK-NEXT:    br label [[LOR_END]]
49 ; CHECK:       lor.end:
50 ; CHECK-NEXT:    ret void
52 entry:
53   %cmp = icmp slt i64 %a, 0
54   br i1 %cmp, label %land.lhs.true, label %lor.rhs
56 land.lhs.true:
57   br i1 %c1, label %lor.end, label %lor.rhs
59 lor.rhs:
60   %cmp2 = icmp sgt i64 %a, 0
61   br i1 %cmp2, label %land.rhs, label %lor.end
63 land.rhs:
64   br label %lor.end
66 lor.end:
67   ret void
70 define void @idom_sign_bit_check_edge_dominates_select(i64 %a, i64 %b) {
71 ; CHECK-LABEL: @idom_sign_bit_check_edge_dominates_select(
72 ; CHECK-NEXT:  entry:
73 ; CHECK-NEXT:    [[CMP:%.*]] = icmp slt i64 [[A:%.*]], 5
74 ; CHECK-NEXT:    br i1 [[CMP]], label [[LAND_LHS_TRUE:%.*]], label [[LOR_RHS:%.*]]
75 ; CHECK:       land.lhs.true:
76 ; CHECK-NEXT:    br label [[LOR_END:%.*]]
77 ; CHECK:       lor.rhs:
78 ; CHECK-NEXT:    [[CMP3_NOT:%.*]] = icmp eq i64 [[A]], [[B:%.*]]
79 ; CHECK-NEXT:    br i1 [[CMP3_NOT]], label [[LOR_END]], label [[LAND_RHS:%.*]]
80 ; CHECK:       land.rhs:
81 ; CHECK-NEXT:    br label [[LOR_END]]
82 ; CHECK:       lor.end:
83 ; CHECK-NEXT:    ret void
85 entry:
86   %cmp = icmp slt i64 %a, 5
87   br i1 %cmp, label %land.lhs.true, label %lor.rhs
89 land.lhs.true:
90   br label %lor.end
92 lor.rhs:
93   %cmp2 = icmp sgt i64 %a, 5
94   %select = select i1 %cmp2, i64 %a, i64 5
95   %cmp3 = icmp ne i64 %select, %b
96   br i1 %cmp3, label %land.rhs, label %lor.end
98 land.rhs:
99   br label %lor.end
101 lor.end:
102   ret void
105 define void @idom_zbranch(i64 %a) {
106 ; CHECK-LABEL: @idom_zbranch(
107 ; CHECK-NEXT:  entry:
108 ; CHECK-NEXT:    [[CMP:%.*]] = icmp sgt i64 [[A:%.*]], 0
109 ; CHECK-NEXT:    br i1 [[CMP]], label [[LOR_END:%.*]], label [[LOR_RHS:%.*]]
110 ; CHECK:       lor.rhs:
111 ; CHECK-NEXT:    [[CMP2:%.*]] = icmp slt i64 [[A]], 0
112 ; CHECK-NEXT:    br i1 [[CMP2]], label [[LAND_RHS:%.*]], label [[LOR_END]]
113 ; CHECK:       land.rhs:
114 ; CHECK-NEXT:    br label [[LOR_END]]
115 ; CHECK:       lor.end:
116 ; CHECK-NEXT:    ret void
118 entry:
119   %cmp = icmp sgt i64 %a, 0
120   br i1 %cmp, label %lor.end, label %lor.rhs
122 lor.rhs:
123   %cmp2 = icmp slt i64 %a, 0
124   br i1 %cmp2, label %land.rhs, label %lor.end
126 land.rhs:
127   br label %lor.end
129 lor.end:
130   ret void
133 define void @idom_not_zbranch(i32 %a, i32 %b) {
134 ; CHECK-LABEL: @idom_not_zbranch(
135 ; CHECK-NEXT:  entry:
136 ; CHECK-NEXT:    [[CMP:%.*]] = icmp sgt i32 [[A:%.*]], 0
137 ; CHECK-NEXT:    br i1 [[CMP]], label [[RETURN:%.*]], label [[IF_END:%.*]]
138 ; CHECK:       if.end:
139 ; CHECK-NEXT:    [[CMP2_NOT:%.*]] = icmp eq i32 [[A]], [[B:%.*]]
140 ; CHECK-NEXT:    br i1 [[CMP2_NOT]], label [[RETURN]], label [[IF_THEN3:%.*]]
141 ; CHECK:       if.then3:
142 ; CHECK-NEXT:    br label [[RETURN]]
143 ; CHECK:       return:
144 ; CHECK-NEXT:    ret void
146 entry:
147   %cmp = icmp sgt i32 %a, 0
148   br i1 %cmp, label %return, label %if.end
150 if.end:
151   %cmp1 = icmp slt i32 %a, 0
152   %a. = select i1 %cmp1, i32 %a, i32 0
153   %cmp2 = icmp ne i32 %a., %b
154   br i1 %cmp2, label %if.then3, label %return
156 if.then3:
157   br label %return
159 return:
160   ret void
163 define void @trueblock_cmp_eq(i32 %a, i32 %b) {
164 ; CHECK-LABEL: @trueblock_cmp_eq(
165 ; CHECK-NEXT:  entry:
166 ; CHECK-NEXT:    [[CMP:%.*]] = icmp sgt i32 [[A:%.*]], 0
167 ; CHECK-NEXT:    br i1 [[CMP]], label [[IF_END:%.*]], label [[RETURN:%.*]]
168 ; CHECK:       if.end:
169 ; CHECK-NEXT:    [[CMP1:%.*]] = icmp eq i32 [[A]], 1
170 ; CHECK-NEXT:    br i1 [[CMP1]], label [[IF_THEN3:%.*]], label [[RETURN]]
171 ; CHECK:       if.then3:
172 ; CHECK-NEXT:    br label [[RETURN]]
173 ; CHECK:       return:
174 ; CHECK-NEXT:    ret void
176 entry:
177   %cmp = icmp sgt i32 %a, 0
178   br i1 %cmp, label %if.end, label %return
180 if.end:
181   %cmp1 = icmp slt i32 %a, 2
182   br i1 %cmp1, label %if.then3, label %return
184 if.then3:
185   br label %return
187 return:
188   ret void
191 define i1 @trueblock_cmp_is_false(i32 %x, i32 %y) {
192 ; CHECK-LABEL: @trueblock_cmp_is_false(
193 ; CHECK-NEXT:  entry:
194 ; CHECK-NEXT:    [[CMP:%.*]] = icmp sgt i32 [[X:%.*]], [[Y:%.*]]
195 ; CHECK-NEXT:    br i1 [[CMP]], label [[T:%.*]], label [[F:%.*]]
196 ; CHECK:       t:
197 ; CHECK-NEXT:    ret i1 false
198 ; CHECK:       f:
199 ; CHECK-NEXT:    ret i1 false
201 entry:
202   %cmp = icmp sgt i32 %x, %y
203   br i1 %cmp, label %t, label %f
205   %cmp2 = icmp slt i32 %x, %y
206   ret i1 %cmp2
208   ret i1 %cmp
211 define i1 @trueblock_cmp_is_false_commute(i32 %x, i32 %y) {
212 ; CHECK-LABEL: @trueblock_cmp_is_false_commute(
213 ; CHECK-NEXT:  entry:
214 ; CHECK-NEXT:    [[CMP:%.*]] = icmp eq i32 [[X:%.*]], [[Y:%.*]]
215 ; CHECK-NEXT:    br i1 [[CMP]], label [[T:%.*]], label [[F:%.*]]
216 ; CHECK:       t:
217 ; CHECK-NEXT:    ret i1 false
218 ; CHECK:       f:
219 ; CHECK-NEXT:    ret i1 false
221 entry:
222   %cmp = icmp eq i32 %x, %y
223   br i1 %cmp, label %t, label %f
225   %cmp2 = icmp sgt i32 %y, %x
226   ret i1 %cmp2
228   ret i1 %cmp
231 define i1 @trueblock_cmp_is_true(i32 %x, i32 %y) {
232 ; CHECK-LABEL: @trueblock_cmp_is_true(
233 ; CHECK-NEXT:  entry:
234 ; CHECK-NEXT:    [[CMP:%.*]] = icmp ult i32 [[X:%.*]], [[Y:%.*]]
235 ; CHECK-NEXT:    br i1 [[CMP]], label [[T:%.*]], label [[F:%.*]]
236 ; CHECK:       t:
237 ; CHECK-NEXT:    ret i1 true
238 ; CHECK:       f:
239 ; CHECK-NEXT:    ret i1 false
241 entry:
242   %cmp = icmp ult i32 %x, %y
243   br i1 %cmp, label %t, label %f
245   %cmp2 = icmp ne i32 %x, %y
246   ret i1 %cmp2
248   ret i1 %cmp
251 define i1 @trueblock_cmp_is_true_commute(i32 %x, i32 %y) {
252 ; CHECK-LABEL: @trueblock_cmp_is_true_commute(
253 ; CHECK-NEXT:  entry:
254 ; CHECK-NEXT:    [[CMP:%.*]] = icmp ugt i32 [[X:%.*]], [[Y:%.*]]
255 ; CHECK-NEXT:    br i1 [[CMP]], label [[T:%.*]], label [[F:%.*]]
256 ; CHECK:       t:
257 ; CHECK-NEXT:    ret i1 true
258 ; CHECK:       f:
259 ; CHECK-NEXT:    ret i1 false
261 entry:
262   %cmp = icmp ugt i32 %x, %y
263   br i1 %cmp, label %t, label %f
265   %cmp2 = icmp ne i32 %y, %x
266   ret i1 %cmp2
268   ret i1 %cmp
271 define i1 @falseblock_cmp_is_false(i32 %x, i32 %y) {
272 ; CHECK-LABEL: @falseblock_cmp_is_false(
273 ; CHECK-NEXT:  entry:
274 ; CHECK-NEXT:    [[CMP_NOT:%.*]] = icmp sgt i32 [[X:%.*]], [[Y:%.*]]
275 ; CHECK-NEXT:    br i1 [[CMP_NOT]], label [[F:%.*]], label [[T:%.*]]
276 ; CHECK:       t:
277 ; CHECK-NEXT:    ret i1 true
278 ; CHECK:       f:
279 ; CHECK-NEXT:    ret i1 false
281 entry:
282   %cmp = icmp sle i32 %x, %y
283   br i1 %cmp, label %t, label %f
285   ret i1 %cmp
287   %cmp2 = icmp slt i32 %x, %y
288   ret i1 %cmp2
291 define i1 @falseblock_cmp_is_false_commute(i32 %x, i32 %y) {
292 ; CHECK-LABEL: @falseblock_cmp_is_false_commute(
293 ; CHECK-NEXT:  entry:
294 ; CHECK-NEXT:    [[CMP:%.*]] = icmp eq i32 [[X:%.*]], [[Y:%.*]]
295 ; CHECK-NEXT:    br i1 [[CMP]], label [[T:%.*]], label [[F:%.*]]
296 ; CHECK:       t:
297 ; CHECK-NEXT:    ret i1 true
298 ; CHECK:       f:
299 ; CHECK-NEXT:    ret i1 false
301 entry:
302   %cmp = icmp eq i32 %x, %y
303   br i1 %cmp, label %t, label %f
305   ret i1 %cmp
307   %cmp2 = icmp eq i32 %y, %x
308   ret i1 %cmp2
311 define i1 @falseblock_cmp_is_true(i32 %x, i32 %y) {
312 ; CHECK-LABEL: @falseblock_cmp_is_true(
313 ; CHECK-NEXT:  entry:
314 ; CHECK-NEXT:    [[CMP:%.*]] = icmp ult i32 [[X:%.*]], [[Y:%.*]]
315 ; CHECK-NEXT:    br i1 [[CMP]], label [[T:%.*]], label [[F:%.*]]
316 ; CHECK:       t:
317 ; CHECK-NEXT:    ret i1 true
318 ; CHECK:       f:
319 ; CHECK-NEXT:    ret i1 true
321 entry:
322   %cmp = icmp ult i32 %x, %y
323   br i1 %cmp, label %t, label %f
325   ret i1 %cmp
327   %cmp2 = icmp uge i32 %x, %y
328   ret i1 %cmp2
331 define i1 @falseblock_cmp_is_true_commute(i32 %x, i32 %y) {
332 ; CHECK-LABEL: @falseblock_cmp_is_true_commute(
333 ; CHECK-NEXT:  entry:
334 ; CHECK-NEXT:    [[CMP:%.*]] = icmp sgt i32 [[X:%.*]], [[Y:%.*]]
335 ; CHECK-NEXT:    br i1 [[CMP]], label [[T:%.*]], label [[F:%.*]]
336 ; CHECK:       t:
337 ; CHECK-NEXT:    ret i1 true
338 ; CHECK:       f:
339 ; CHECK-NEXT:    ret i1 true
341 entry:
342   %cmp = icmp sgt i32 %x, %y
343   br i1 %cmp, label %t, label %f
345   ret i1 %cmp
347   %cmp2 = icmp sge i32 %y, %x
348   ret i1 %cmp2
351 ; This used to infinite loop because of a conflict
352 ; with min/max canonicalization.
354 define i32 @PR48900(i32 %i, ptr %p) {
355 ; CHECK-LABEL: @PR48900(
356 ; CHECK-NEXT:    [[UMAX:%.*]] = call i32 @llvm.umax.i32(i32 [[I:%.*]], i32 1)
357 ; CHECK-NEXT:    [[I4:%.*]] = icmp sgt i32 [[UMAX]], 0
358 ; CHECK-NEXT:    br i1 [[I4]], label [[TRUELABEL:%.*]], label [[FALSELABEL:%.*]]
359 ; CHECK:       truelabel:
360 ; CHECK-NEXT:    [[SMIN:%.*]] = call i32 @llvm.umin.i32(i32 [[UMAX]], i32 2)
361 ; CHECK-NEXT:    ret i32 [[SMIN]]
362 ; CHECK:       falselabel:
363 ; CHECK-NEXT:    ret i32 0
365   %maxcmp = icmp ugt i32 %i, 1
366   %umax = select i1 %maxcmp, i32 %i, i32 1
367   %i4 = icmp sgt i32 %umax, 0
368   br i1 %i4, label %truelabel, label %falselabel
370 truelabel:
371   %mincmp = icmp ult i32 %umax, 2
372   %smin = select i1 %mincmp, i32 %umax, i32 2
373   ret i32 %smin
375 falselabel:
376   ret i32 0
379 ; This used to infinite loop because of a conflict
380 ; with min/max canonicalization.
382 define i8 @PR48900_alt(i8 %i, ptr %p) {
383 ; CHECK-LABEL: @PR48900_alt(
384 ; CHECK-NEXT:    [[SMAX:%.*]] = call i8 @llvm.smax.i8(i8 [[I:%.*]], i8 -127)
385 ; CHECK-NEXT:    [[I4:%.*]] = icmp ugt i8 [[SMAX]], -128
386 ; CHECK-NEXT:    br i1 [[I4]], label [[TRUELABEL:%.*]], label [[FALSELABEL:%.*]]
387 ; CHECK:       truelabel:
388 ; CHECK-NEXT:    [[UMIN:%.*]] = call i8 @llvm.smin.i8(i8 [[SMAX]], i8 -126)
389 ; CHECK-NEXT:    ret i8 [[UMIN]]
390 ; CHECK:       falselabel:
391 ; CHECK-NEXT:    ret i8 0
393   %maxcmp = icmp sgt i8 %i, -127
394   %smax = select i1 %maxcmp, i8 %i, i8 -127
395   %i4 = icmp ugt i8 %smax, 128
396   br i1 %i4, label %truelabel, label %falselabel
398 truelabel:
399   %mincmp = icmp slt i8 %smax, -126
400   %umin = select i1 %mincmp, i8 %smax, i8 -126
401   ret i8 %umin
403 falselabel:
404   ret i8 0
407 define i1 @and_mask1_eq(i32 %conv) {
408 ; CHECK-LABEL: @and_mask1_eq(
409 ; CHECK-NEXT:  entry:
410 ; CHECK-NEXT:    [[AND:%.*]] = and i32 [[CONV:%.*]], 1
411 ; CHECK-NEXT:    [[CMP:%.*]] = icmp eq i32 [[AND]], 0
412 ; CHECK-NEXT:    br i1 [[CMP]], label [[THEN:%.*]], label [[ELSE:%.*]]
413 ; CHECK:       then:
414 ; CHECK-NEXT:    ret i1 false
415 ; CHECK:       else:
416 ; CHECK-NEXT:    ret i1 false
418 entry:
419   %and = and i32 %conv, 1
420   %cmp = icmp eq i32 %and, 0
421   br i1 %cmp, label %then, label %else
423 then:
424   ret i1 0
426 else:
427   %and1 = and i32 %conv, 3
428   %cmp1 = icmp eq i32 %and1, 0
429   ret i1 %cmp1
432 define i1 @and_mask1_ne(i32 %conv) {
433 ; CHECK-LABEL: @and_mask1_ne(
434 ; CHECK-NEXT:  entry:
435 ; CHECK-NEXT:    [[AND:%.*]] = and i32 [[CONV:%.*]], 1
436 ; CHECK-NEXT:    [[CMP:%.*]] = icmp eq i32 [[AND]], 0
437 ; CHECK-NEXT:    br i1 [[CMP]], label [[THEN:%.*]], label [[ELSE:%.*]]
438 ; CHECK:       then:
439 ; CHECK-NEXT:    ret i1 false
440 ; CHECK:       else:
441 ; CHECK-NEXT:    ret i1 true
443 entry:
444   %and = and i32 %conv, 1
445   %cmp = icmp eq i32 %and, 0
446   br i1 %cmp, label %then, label %else
448 then:
449   ret i1 0
451 else:
452   %and1 = and i32 %conv, 3
453   %cmp1 = icmp ne i32 %and1, 0
454   ret i1 %cmp1
457 define i1 @and_mask2(i32 %conv) {
458 ; CHECK-LABEL: @and_mask2(
459 ; CHECK-NEXT:  entry:
460 ; CHECK-NEXT:    [[AND:%.*]] = and i32 [[CONV:%.*]], 4
461 ; CHECK-NEXT:    [[CMP:%.*]] = icmp eq i32 [[AND]], 0
462 ; CHECK-NEXT:    br i1 [[CMP]], label [[THEN:%.*]], label [[ELSE:%.*]]
463 ; CHECK:       then:
464 ; CHECK-NEXT:    ret i1 false
465 ; CHECK:       else:
466 ; CHECK-NEXT:    [[AND1:%.*]] = and i32 [[CONV]], 3
467 ; CHECK-NEXT:    [[CMP1:%.*]] = icmp eq i32 [[AND1]], 0
468 ; CHECK-NEXT:    ret i1 [[CMP1]]
470 entry:
471   %and = and i32 %conv, 4
472   %cmp = icmp eq i32 %and, 0
473   br i1 %cmp, label %then, label %else
475 then:
476   ret i1 0
478 else:
479   %and1 = and i32 %conv, 3
480   %cmp1 = icmp eq i32 %and1, 0
481   ret i1 %cmp1
484 ; TODO: %cmp1 can be folded into false.
486 define i1 @and_mask3(i32 %conv) {
487 ; CHECK-LABEL: @and_mask3(
488 ; CHECK-NEXT:  entry:
489 ; CHECK-NEXT:    [[AND:%.*]] = and i32 [[CONV:%.*]], 3
490 ; CHECK-NEXT:    [[CMP:%.*]] = icmp eq i32 [[AND]], 0
491 ; CHECK-NEXT:    br i1 [[CMP]], label [[THEN:%.*]], label [[ELSE:%.*]]
492 ; CHECK:       then:
493 ; CHECK-NEXT:    ret i1 false
494 ; CHECK:       else:
495 ; CHECK-NEXT:    [[AND1:%.*]] = and i32 [[CONV]], 7
496 ; CHECK-NEXT:    [[CMP1:%.*]] = icmp eq i32 [[AND1]], 0
497 ; CHECK-NEXT:    ret i1 [[CMP1]]
499 entry:
500   %and = and i32 %conv, 3
501   %cmp = icmp eq i32 %and, 0
502   br i1 %cmp, label %then, label %else
504 then:
505   ret i1 0
507 else:
508   %and1 = and i32 %conv, 7
509   %cmp1 = icmp eq i32 %and1, 0
510   ret i1 %cmp1
513 define i1 @and_mask4(i32 %conv) {
514 ; CHECK-LABEL: @and_mask4(
515 ; CHECK-NEXT:  entry:
516 ; CHECK-NEXT:    [[AND:%.*]] = and i32 [[CONV:%.*]], 4
517 ; CHECK-NEXT:    [[CMP:%.*]] = icmp eq i32 [[AND]], 0
518 ; CHECK-NEXT:    br i1 [[CMP]], label [[THEN:%.*]], label [[ELSE:%.*]]
519 ; CHECK:       then:
520 ; CHECK-NEXT:    ret i1 false
521 ; CHECK:       else:
522 ; CHECK-NEXT:    ret i1 false
524 entry:
525   %and = and i32 %conv, 4
526   %cmp = icmp eq i32 %and, 0
527   br i1 %cmp, label %then, label %else
529 then:
530   ret i1 0
532 else:
533   %and1 = and i32 %conv, 7
534   %cmp1 = icmp eq i32 %and1, 0
535   ret i1 %cmp1