[ORC] Add std::tuple support to SimplePackedSerialization.
[llvm-project.git] / llvm / test / Transforms / CorrelatedValuePropagation / icmp.ll
blobc195dc10dc6b9624f7df7f77d1eaf2d97fad3ca8
1 ; NOTE: Assertions have been autogenerated by utils/update_test_checks.py
2 ; RUN: opt -correlated-propagation -S %s | FileCheck %s
3 ; RUN: opt -passes=correlated-propagation -S %s | FileCheck %s
5 target datalayout = "e-m:o-i64:64-f80:128-n8:16:32:64-S128"
6 target triple = "x86_64-apple-macosx10.10.0"
8 declare void @check1(i1) #1
9 declare void @check2(i1) #1
10 declare void @llvm.assume(i1)
12 ; Make sure we propagate the value of %tmp35 to the true/false cases
14 define void @test1(i64 %tmp35) {
15 ; CHECK-LABEL: @test1(
16 ; CHECK-NEXT:  bb:
17 ; CHECK-NEXT:    [[TMP36:%.*]] = icmp sgt i64 [[TMP35:%.*]], 0
18 ; CHECK-NEXT:    br i1 [[TMP36]], label [[BB_TRUE:%.*]], label [[BB_FALSE:%.*]]
19 ; CHECK:       bb_true:
20 ; CHECK-NEXT:    tail call void @check1(i1 false) #[[ATTR1:[0-9]+]]
21 ; CHECK-NEXT:    unreachable
22 ; CHECK:       bb_false:
23 ; CHECK-NEXT:    tail call void @check2(i1 true) #[[ATTR1]]
24 ; CHECK-NEXT:    unreachable
26 bb:
27   %tmp36 = icmp sgt i64 %tmp35, 0
28   br i1 %tmp36, label %bb_true, label %bb_false
30 bb_true:
31   %tmp47 = icmp slt i64 %tmp35, 0
32   tail call void @check1(i1 %tmp47) #4
33   unreachable
35 bb_false:
36   %tmp48 = icmp sle i64 %tmp35, 0
37   tail call void @check2(i1 %tmp48) #4
38   unreachable
41 ; This is the same as test1 but with a diamond to ensure we
42 ; get %tmp36 from both true and false BBs.
44 define void @test2(i64 %tmp35, i1 %inner_cmp) {
45 ; CHECK-LABEL: @test2(
46 ; CHECK-NEXT:  bb:
47 ; CHECK-NEXT:    [[TMP36:%.*]] = icmp sgt i64 [[TMP35:%.*]], 0
48 ; CHECK-NEXT:    br i1 [[TMP36]], label [[BB_TRUE:%.*]], label [[BB_FALSE:%.*]]
49 ; CHECK:       bb_true:
50 ; CHECK-NEXT:    br i1 [[INNER_CMP:%.*]], label [[INNER_TRUE:%.*]], label [[INNER_FALSE:%.*]]
51 ; CHECK:       inner_true:
52 ; CHECK-NEXT:    br label [[MERGE:%.*]]
53 ; CHECK:       inner_false:
54 ; CHECK-NEXT:    br label [[MERGE]]
55 ; CHECK:       merge:
56 ; CHECK-NEXT:    tail call void @check1(i1 false)
57 ; CHECK-NEXT:    unreachable
58 ; CHECK:       bb_false:
59 ; CHECK-NEXT:    tail call void @check2(i1 true) #[[ATTR1]]
60 ; CHECK-NEXT:    unreachable
62 bb:
63   %tmp36 = icmp sgt i64 %tmp35, 0
64   br i1 %tmp36, label %bb_true, label %bb_false
66 bb_true:
67   br i1 %inner_cmp, label %inner_true, label %inner_false
69 inner_true:
70   br label %merge
72 inner_false:
73   br label %merge
75 merge:
76   %tmp47 = icmp slt i64 %tmp35, 0
77   tail call void @check1(i1 %tmp47) #0
78   unreachable
80 bb_false:
81   %tmp48 = icmp sle i64 %tmp35, 0
82   tail call void @check2(i1 %tmp48) #4
83   unreachable
86 ; Make sure binary operator transfer functions are run when RHS is non-constant
88 define i1 @test3(i32 %x, i32 %y) #0 {
89 ; CHECK-LABEL: @test3(
90 ; CHECK-NEXT:  entry:
91 ; CHECK-NEXT:    [[CMP1:%.*]] = icmp ult i32 [[X:%.*]], 10
92 ; CHECK-NEXT:    br i1 [[CMP1]], label [[CONT1:%.*]], label [[OUT:%.*]]
93 ; CHECK:       cont1:
94 ; CHECK-NEXT:    [[CMP2:%.*]] = icmp ult i32 [[Y:%.*]], 10
95 ; CHECK-NEXT:    br i1 [[CMP2]], label [[CONT2:%.*]], label [[OUT]]
96 ; CHECK:       cont2:
97 ; CHECK-NEXT:    [[ADD:%.*]] = add nuw nsw i32 [[X]], [[Y]]
98 ; CHECK-NEXT:    br label [[OUT]]
99 ; CHECK:       out:
100 ; CHECK-NEXT:    ret i1 true
102 entry:
103   %cmp1 = icmp ult i32 %x, 10
104   br i1 %cmp1, label %cont1, label %out
106 cont1:
107   %cmp2 = icmp ult i32 %y, 10
108   br i1 %cmp2, label %cont2, label %out
110 cont2:
111   %add = add i32 %x, %y
112   %cmp3 = icmp ult i32 %add, 25
113   br label %out
115 out:
116   %ret = phi i1 [ true, %entry], [ true, %cont1 ], [ %cmp3, %cont2 ]
117   ret i1 %ret
120 ; Same as previous but make sure nobody gets over-zealous
122 define i1 @test4(i32 %x, i32 %y) #0 {
123 ; CHECK-LABEL: @test4(
124 ; CHECK-NEXT:  entry:
125 ; CHECK-NEXT:    [[CMP1:%.*]] = icmp ult i32 [[X:%.*]], 10
126 ; CHECK-NEXT:    br i1 [[CMP1]], label [[CONT1:%.*]], label [[OUT:%.*]]
127 ; CHECK:       cont1:
128 ; CHECK-NEXT:    [[CMP2:%.*]] = icmp ult i32 [[Y:%.*]], 10
129 ; CHECK-NEXT:    br i1 [[CMP2]], label [[CONT2:%.*]], label [[OUT]]
130 ; CHECK:       cont2:
131 ; CHECK-NEXT:    [[ADD:%.*]] = add nuw nsw i32 [[X]], [[Y]]
132 ; CHECK-NEXT:    [[CMP3:%.*]] = icmp ult i32 [[ADD]], 15
133 ; CHECK-NEXT:    br label [[OUT]]
134 ; CHECK:       out:
135 ; CHECK-NEXT:    [[RET:%.*]] = phi i1 [ true, [[ENTRY:%.*]] ], [ true, [[CONT1]] ], [ [[CMP3]], [[CONT2]] ]
136 ; CHECK-NEXT:    ret i1 [[RET]]
138 entry:
139   %cmp1 = icmp ult i32 %x, 10
140   br i1 %cmp1, label %cont1, label %out
142 cont1:
143   %cmp2 = icmp ult i32 %y, 10
144   br i1 %cmp2, label %cont2, label %out
146 cont2:
147   %add = add i32 %x, %y
148   %cmp3 = icmp ult i32 %add, 15
149   br label %out
151 out:
152   %ret = phi i1 [ true, %entry], [ true, %cont1 ], [ %cmp3, %cont2 ]
153   ret i1 %ret
156 ; Make sure binary operator transfer functions are run when RHS is non-constant
158 define i1 @test5(i32 %x, i32 %y) #0 {
159 ; CHECK-LABEL: @test5(
160 ; CHECK-NEXT:  entry:
161 ; CHECK-NEXT:    [[CMP1:%.*]] = icmp ult i32 [[X:%.*]], 5
162 ; CHECK-NEXT:    br i1 [[CMP1]], label [[CONT1:%.*]], label [[OUT:%.*]]
163 ; CHECK:       cont1:
164 ; CHECK-NEXT:    [[CMP2:%.*]] = icmp ult i32 [[Y:%.*]], 5
165 ; CHECK-NEXT:    br i1 [[CMP2]], label [[CONT2:%.*]], label [[OUT]]
166 ; CHECK:       cont2:
167 ; CHECK-NEXT:    [[SHIFTED:%.*]] = shl nuw nsw i32 [[X]], [[Y]]
168 ; CHECK-NEXT:    br label [[OUT]]
169 ; CHECK:       out:
170 ; CHECK-NEXT:    ret i1 true
172 entry:
173   %cmp1 = icmp ult i32 %x, 5
174   br i1 %cmp1, label %cont1, label %out
176 cont1:
177   %cmp2 = icmp ult i32 %y, 5
178   br i1 %cmp2, label %cont2, label %out
180 cont2:
181   %shifted = shl i32 %x, %y
182   %cmp3 = icmp ult i32 %shifted, 65536
183   br label %out
185 out:
186   %ret = phi i1 [ true, %entry], [ true, %cont1 ], [ %cmp3, %cont2 ]
187   ret i1 %ret
190 ; Same as previous but make sure nobody gets over-zealous
192 define i1 @test6(i32 %x, i32 %y) #0 {
193 ; CHECK-LABEL: @test6(
194 ; CHECK-NEXT:  entry:
195 ; CHECK-NEXT:    [[CMP1:%.*]] = icmp ult i32 [[X:%.*]], 5
196 ; CHECK-NEXT:    br i1 [[CMP1]], label [[CONT1:%.*]], label [[OUT:%.*]]
197 ; CHECK:       cont1:
198 ; CHECK-NEXT:    [[CMP2:%.*]] = icmp ult i32 [[Y:%.*]], 15
199 ; CHECK-NEXT:    br i1 [[CMP2]], label [[CONT2:%.*]], label [[OUT]]
200 ; CHECK:       cont2:
201 ; CHECK-NEXT:    [[SHIFTED:%.*]] = shl nuw nsw i32 [[X]], [[Y]]
202 ; CHECK-NEXT:    [[CMP3:%.*]] = icmp ult i32 [[SHIFTED]], 65536
203 ; CHECK-NEXT:    br label [[OUT]]
204 ; CHECK:       out:
205 ; CHECK-NEXT:    [[RET:%.*]] = phi i1 [ true, [[ENTRY:%.*]] ], [ true, [[CONT1]] ], [ [[CMP3]], [[CONT2]] ]
206 ; CHECK-NEXT:    ret i1 [[RET]]
208 entry:
209   %cmp1 = icmp ult i32 %x, 5
210   br i1 %cmp1, label %cont1, label %out
212 cont1:
213   %cmp2 = icmp ult i32 %y, 15
214   br i1 %cmp2, label %cont2, label %out
216 cont2:
217   %shifted = shl i32 %x, %y
218   %cmp3 = icmp ult i32 %shifted, 65536
219   br label %out
221 out:
222   %ret = phi i1 [ true, %entry], [ true, %cont1 ], [ %cmp3, %cont2 ]
223   ret i1 %ret
226 define i1 @test7(i32 %a, i32 %b) {
227 ; CHECK-LABEL: @test7(
228 ; CHECK-NEXT:  begin:
229 ; CHECK-NEXT:    [[CMP0:%.*]] = icmp sge i32 [[A:%.*]], 0
230 ; CHECK-NEXT:    [[CMP1:%.*]] = icmp sge i32 [[B:%.*]], 0
231 ; CHECK-NEXT:    [[BR:%.*]] = and i1 [[CMP0]], [[CMP1]]
232 ; CHECK-NEXT:    br i1 [[BR]], label [[BB:%.*]], label [[EXIT:%.*]]
233 ; CHECK:       bb:
234 ; CHECK-NEXT:    [[ADD:%.*]] = add nuw i32 [[A]], [[B]]
235 ; CHECK-NEXT:    [[RES:%.*]] = icmp sge i32 [[ADD]], 0
236 ; CHECK-NEXT:    br label [[EXIT]]
237 ; CHECK:       exit:
238 ; CHECK-NEXT:    [[IV:%.*]] = phi i1 [ true, [[BEGIN:%.*]] ], [ [[RES]], [[BB]] ]
239 ; CHECK-NEXT:    ret i1 [[IV]]
241 begin:
242   %cmp0 = icmp sge i32 %a, 0
243   %cmp1 = icmp sge i32 %b, 0
244   %br = and i1 %cmp0, %cmp1
245   br i1 %br, label %bb, label %exit
248   %add = add i32 %a, %b
249   %res = icmp sge i32 %add, 0
250   br label %exit
252 exit:
253   %iv = phi i1 [ true, %begin ], [ %res, %bb ]
254   ret i1 %iv
257 define i1 @test8(i32 %a, i32 %b) {
258 ; CHECK-LABEL: @test8(
259 ; CHECK-NEXT:  begin:
260 ; CHECK-NEXT:    [[CMP0:%.*]] = icmp sge i32 [[A:%.*]], 0
261 ; CHECK-NEXT:    [[CMP1:%.*]] = icmp sge i32 [[B:%.*]], 0
262 ; CHECK-NEXT:    [[BR:%.*]] = and i1 [[CMP0]], [[CMP1]]
263 ; CHECK-NEXT:    br i1 [[BR]], label [[BB:%.*]], label [[EXIT:%.*]]
264 ; CHECK:       bb:
265 ; CHECK-NEXT:    [[ADD:%.*]] = add nuw nsw i32 [[A]], [[B]]
266 ; CHECK-NEXT:    br label [[EXIT]]
267 ; CHECK:       exit:
268 ; CHECK-NEXT:    ret i1 true
270 begin:
271   %cmp0 = icmp sge i32 %a, 0
272   %cmp1 = icmp sge i32 %b, 0
273   %br = and i1 %cmp0, %cmp1
274   br i1 %br, label %bb, label %exit
277   %add = add nsw i32 %a, %b
278   %res = icmp sge i32 %add, 0
279   br label %exit
281 exit:
282   %iv = phi i1 [ true, %begin ], [ %res, %bb ]
283   ret i1 %iv
286 define i1 @test10(i32 %a, i32 %b) {
287 ; CHECK-LABEL: @test10(
288 ; CHECK-NEXT:  begin:
289 ; CHECK-NEXT:    [[CMP:%.*]] = icmp uge i32 [[A:%.*]], -256
290 ; CHECK-NEXT:    br i1 [[CMP]], label [[BB:%.*]], label [[EXIT:%.*]]
291 ; CHECK:       bb:
292 ; CHECK-NEXT:    [[ADD:%.*]] = add i32 [[A]], [[B:%.*]]
293 ; CHECK-NEXT:    [[RES:%.*]] = icmp uge i32 [[ADD]], -256
294 ; CHECK-NEXT:    br label [[EXIT]]
295 ; CHECK:       exit:
296 ; CHECK-NEXT:    [[IV:%.*]] = phi i1 [ true, [[BEGIN:%.*]] ], [ [[RES]], [[BB]] ]
297 ; CHECK-NEXT:    ret i1 [[IV]]
299 begin:
300   %cmp = icmp uge i32 %a, 4294967040
301   br i1 %cmp, label %bb, label %exit
304   %add = add i32 %a, %b
305   %res = icmp uge i32 %add, 4294967040
306   br label %exit
308 exit:
309   %iv = phi i1 [ true, %begin ], [ %res, %bb ]
310   ret i1 %iv
313 define i1 @test11(i32 %a, i32 %b) {
314 ; CHECK-LABEL: @test11(
315 ; CHECK-NEXT:  begin:
316 ; CHECK-NEXT:    [[CMP:%.*]] = icmp uge i32 [[A:%.*]], -256
317 ; CHECK-NEXT:    br i1 [[CMP]], label [[BB:%.*]], label [[EXIT:%.*]]
318 ; CHECK:       bb:
319 ; CHECK-NEXT:    [[ADD:%.*]] = add nuw i32 [[A]], [[B:%.*]]
320 ; CHECK-NEXT:    br label [[EXIT]]
321 ; CHECK:       exit:
322 ; CHECK-NEXT:    ret i1 true
324 begin:
325   %cmp = icmp uge i32 %a, 4294967040
326   br i1 %cmp, label %bb, label %exit
329   %add = add nuw i32 %a, %b
330   %res = icmp uge i32 %add, 4294967040
331   br label %exit
333 exit:
334   %iv = phi i1 [ true, %begin ], [ %res, %bb ]
335   ret i1 %iv
338 define i1 @test12(i32 %x) {
339 ; CHECK-LABEL: @test12(
340 ; CHECK-NEXT:    [[ZEXT:%.*]] = zext i32 [[X:%.*]] to i64
341 ; CHECK-NEXT:    [[MUL:%.*]] = mul nuw nsw i64 [[ZEXT]], 7
342 ; CHECK-NEXT:    [[SHR:%.*]] = lshr i64 [[MUL]], 32
343 ; CHECK-NEXT:    [[TRUNC:%.*]] = trunc i64 [[SHR]] to i32
344 ; CHECK-NEXT:    ret i1 true
346   %zext = zext i32 %x to i64
347   %mul = mul nuw i64 %zext, 7
348   %shr = lshr i64 %mul, 32
349   %trunc = trunc i64 %shr to i32
350   %cmp = icmp ult i32 %trunc, 7
351   ret i1 %cmp
354 define i1 @test13(i8 %x, i64* %p) {
355 ; CHECK-LABEL: @test13(
356 ; CHECK-NEXT:    [[ZEXT:%.*]] = zext i8 [[X:%.*]] to i64
357 ; CHECK-NEXT:    [[ADD:%.*]] = add nuw nsw i64 [[ZEXT]], 128
358 ; CHECK-NEXT:    store i64 [[ADD]], i64* [[P:%.*]], align 8
359 ; CHECK-NEXT:    ret i1 true
361   %zext = zext i8 %x to i64
362   %add = add nuw nsw i64 %zext, 128
363   %cmp = icmp ult i64 %add, 384
364   ; Without this extra use, InstSimplify could handle this
365   store i64 %add, i64* %p
366   ret i1 %cmp
369 define i1 @test14(i32 %a, i32 %b) {
370 ; CHECK-LABEL: @test14(
371 ; CHECK-NEXT:  begin:
372 ; CHECK-NEXT:    [[CMP0:%.*]] = icmp sge i32 [[A:%.*]], 0
373 ; CHECK-NEXT:    [[CMP1:%.*]] = icmp sge i32 [[B:%.*]], 0
374 ; CHECK-NEXT:    [[BR:%.*]] = and i1 [[CMP0]], [[CMP1]]
375 ; CHECK-NEXT:    br i1 [[BR]], label [[BB:%.*]], label [[EXIT:%.*]]
376 ; CHECK:       bb:
377 ; CHECK-NEXT:    [[SUB:%.*]] = sub nsw i32 [[A]], [[B]]
378 ; CHECK-NEXT:    [[RES:%.*]] = icmp sge i32 [[SUB]], 0
379 ; CHECK-NEXT:    br label [[EXIT]]
380 ; CHECK:       exit:
381 ; CHECK-NEXT:    [[IV:%.*]] = phi i1 [ true, [[BEGIN:%.*]] ], [ [[RES]], [[BB]] ]
382 ; CHECK-NEXT:    ret i1 [[IV]]
384 begin:
385   %cmp0 = icmp sge i32 %a, 0
386   %cmp1 = icmp sge i32 %b, 0
387   %br = and i1 %cmp0, %cmp1
388   br i1 %br, label %bb, label %exit
391   %sub = sub i32 %a, %b
392   %res = icmp sge i32 %sub, 0
393   br label %exit
395 exit:
396   %iv = phi i1 [ true, %begin ], [ %res, %bb ]
397   ret i1 %iv
400 define i1 @test15(i32 %a, i32 %b) {
401 ; CHECK-LABEL: @test15(
402 ; CHECK-NEXT:  begin:
403 ; CHECK-NEXT:    [[CMP0:%.*]] = icmp sge i32 [[A:%.*]], 0
404 ; CHECK-NEXT:    [[CMP1:%.*]] = icmp sge i32 [[B:%.*]], 0
405 ; CHECK-NEXT:    [[BR:%.*]] = and i1 [[CMP0]], [[CMP1]]
406 ; CHECK-NEXT:    br i1 [[BR]], label [[BB:%.*]], label [[EXIT:%.*]]
407 ; CHECK:       bb:
408 ; CHECK-NEXT:    [[SUB:%.*]] = sub nsw i32 [[A]], [[B]]
409 ; CHECK-NEXT:    [[RES:%.*]] = icmp sge i32 [[SUB]], 0
410 ; CHECK-NEXT:    br label [[EXIT]]
411 ; CHECK:       exit:
412 ; CHECK-NEXT:    [[IV:%.*]] = phi i1 [ true, [[BEGIN:%.*]] ], [ [[RES]], [[BB]] ]
413 ; CHECK-NEXT:    ret i1 [[IV]]
415 begin:
416   %cmp0 = icmp sge i32 %a, 0
417   %cmp1 = icmp sge i32 %b, 0
418   %br = and i1 %cmp0, %cmp1
419   br i1 %br, label %bb, label %exit
422   %sub = sub nsw i32 %a, %b
423   %res = icmp sge i32 %sub, 0
424   br label %exit
426 exit:
427   %iv = phi i1 [ true, %begin ], [ %res, %bb ]
428   ret i1 %iv
431 define i1 @test16(i32 %a, i32 %b) {
432 ; CHECK-LABEL: @test16(
433 ; CHECK-NEXT:  begin:
434 ; CHECK-NEXT:    [[CMP0:%.*]] = icmp sge i32 [[A:%.*]], 0
435 ; CHECK-NEXT:    [[CMP1:%.*]] = icmp sge i32 [[B:%.*]], 0
436 ; CHECK-NEXT:    [[BR:%.*]] = and i1 [[CMP0]], [[CMP1]]
437 ; CHECK-NEXT:    br i1 [[BR]], label [[BB:%.*]], label [[EXIT:%.*]]
438 ; CHECK:       bb:
439 ; CHECK-NEXT:    [[SUB:%.*]] = sub nuw nsw i32 [[A]], [[B]]
440 ; CHECK-NEXT:    br label [[EXIT]]
441 ; CHECK:       exit:
442 ; CHECK-NEXT:    ret i1 true
444 begin:
445   %cmp0 = icmp sge i32 %a, 0
446   %cmp1 = icmp sge i32 %b, 0
447   %br = and i1 %cmp0, %cmp1
448   br i1 %br, label %bb, label %exit
451   %sub = sub nuw i32 %a, %b
452   %res = icmp sge i32 %sub, 0
453   br label %exit
455 exit:
456   %iv = phi i1 [ true, %begin ], [ %res, %bb ]
457   ret i1 %iv
460 define i1 @test17(i32 %a, i32 %b) {
461 ; CHECK-LABEL: @test17(
462 ; CHECK-NEXT:  begin:
463 ; CHECK-NEXT:    [[CMP0:%.*]] = icmp sle i32 [[A:%.*]], 0
464 ; CHECK-NEXT:    [[CMP1:%.*]] = icmp sge i32 [[B:%.*]], 0
465 ; CHECK-NEXT:    [[BR:%.*]] = and i1 [[CMP0]], [[CMP1]]
466 ; CHECK-NEXT:    br i1 [[BR]], label [[BB:%.*]], label [[EXIT:%.*]]
467 ; CHECK:       bb:
468 ; CHECK-NEXT:    [[SUB:%.*]] = sub i32 [[A]], [[B]]
469 ; CHECK-NEXT:    [[RES:%.*]] = icmp sle i32 [[SUB]], 0
470 ; CHECK-NEXT:    br label [[EXIT]]
471 ; CHECK:       exit:
472 ; CHECK-NEXT:    [[IV:%.*]] = phi i1 [ true, [[BEGIN:%.*]] ], [ [[RES]], [[BB]] ]
473 ; CHECK-NEXT:    ret i1 [[IV]]
475 begin:
476   %cmp0 = icmp sle i32 %a, 0
477   %cmp1 = icmp sge i32 %b, 0
478   %br = and i1 %cmp0, %cmp1
479   br i1 %br, label %bb, label %exit
482   %sub = sub i32 %a, %b
483   %res = icmp sle i32 %sub, 0
484   br label %exit
486 exit:
487   %iv = phi i1 [ true, %begin ], [ %res, %bb ]
488   ret i1 %iv
491 define i1 @test18(i32 %a, i32 %b) {
492 ; CHECK-LABEL: @test18(
493 ; CHECK-NEXT:  begin:
494 ; CHECK-NEXT:    [[CMP0:%.*]] = icmp sle i32 [[A:%.*]], 0
495 ; CHECK-NEXT:    [[CMP1:%.*]] = icmp sge i32 [[B:%.*]], 0
496 ; CHECK-NEXT:    [[BR:%.*]] = and i1 [[CMP0]], [[CMP1]]
497 ; CHECK-NEXT:    br i1 [[BR]], label [[BB:%.*]], label [[EXIT:%.*]]
498 ; CHECK:       bb:
499 ; CHECK-NEXT:    [[SUB:%.*]] = sub nuw i32 [[A]], [[B]]
500 ; CHECK-NEXT:    [[RES:%.*]] = icmp sle i32 [[SUB]], 0
501 ; CHECK-NEXT:    br label [[EXIT]]
502 ; CHECK:       exit:
503 ; CHECK-NEXT:    [[IV:%.*]] = phi i1 [ true, [[BEGIN:%.*]] ], [ [[RES]], [[BB]] ]
504 ; CHECK-NEXT:    ret i1 [[IV]]
506 begin:
507   %cmp0 = icmp sle i32 %a, 0
508   %cmp1 = icmp sge i32 %b, 0
509   %br = and i1 %cmp0, %cmp1
510   br i1 %br, label %bb, label %exit
513   %sub = sub nuw i32 %a, %b
514   %res = icmp sle i32 %sub, 0
515   br label %exit
517 exit:
518   %iv = phi i1 [ true, %begin ], [ %res, %bb ]
519   ret i1 %iv
522 define i1 @test19(i32 %a, i32 %b) {
523 ; CHECK-LABEL: @test19(
524 ; CHECK-NEXT:  begin:
525 ; CHECK-NEXT:    [[CMP0:%.*]] = icmp sle i32 [[A:%.*]], 0
526 ; CHECK-NEXT:    [[CMP1:%.*]] = icmp sge i32 [[B:%.*]], 0
527 ; CHECK-NEXT:    [[BR:%.*]] = and i1 [[CMP0]], [[CMP1]]
528 ; CHECK-NEXT:    br i1 [[BR]], label [[BB:%.*]], label [[EXIT:%.*]]
529 ; CHECK:       bb:
530 ; CHECK-NEXT:    [[SUB:%.*]] = sub nsw i32 [[A]], [[B]]
531 ; CHECK-NEXT:    br label [[EXIT]]
532 ; CHECK:       exit:
533 ; CHECK-NEXT:    ret i1 true
535 begin:
536   %cmp0 = icmp sle i32 %a, 0
537   %cmp1 = icmp sge i32 %b, 0
538   %br = and i1 %cmp0, %cmp1
539   br i1 %br, label %bb, label %exit
542   %sub = sub nsw i32 %a, %b
543   %res = icmp sle i32 %sub, 0
544   br label %exit
546 exit:
547   %iv = phi i1 [ true, %begin ], [ %res, %bb ]
548   ret i1 %iv
551 define i1 @test_br_cmp_with_offset(i64 %idx) {
552 ; CHECK-LABEL: @test_br_cmp_with_offset(
553 ; CHECK-NEXT:    [[IDX_OFF1:%.*]] = add i64 [[IDX:%.*]], -5
554 ; CHECK-NEXT:    [[CMP1:%.*]] = icmp ult i64 [[IDX_OFF1]], 3
555 ; CHECK-NEXT:    br i1 [[CMP1]], label [[IF_TRUE:%.*]], label [[IF_FALSE:%.*]]
556 ; CHECK:       if.true:
557 ; CHECK-NEXT:    [[IDX_OFF2:%.*]] = add nsw i64 [[IDX]], -1
558 ; CHECK-NEXT:    ret i1 true
559 ; CHECK:       if.false:
560 ; CHECK-NEXT:    ret i1 undef
562   %idx.off1 = add i64 %idx, -5
563   %cmp1 = icmp ult i64 %idx.off1, 3
564   br i1 %cmp1, label %if.true, label %if.false
566 if.true:
567   %idx.off2 = add i64 %idx, -1
568   %cmp2 = icmp ult i64 %idx.off2, 10
569   ret i1 %cmp2
571 if.false:
572   ret i1 undef
575 define i1 @test_assume_cmp_with_offset(i64 %idx) {
576 ; CHECK-LABEL: @test_assume_cmp_with_offset(
577 ; CHECK-NEXT:    [[IDX_OFF1:%.*]] = add i64 [[IDX:%.*]], -5
578 ; CHECK-NEXT:    [[CMP1:%.*]] = icmp ult i64 [[IDX_OFF1]], 3
579 ; CHECK-NEXT:    tail call void @llvm.assume(i1 [[CMP1]])
580 ; CHECK-NEXT:    [[IDX_OFF2:%.*]] = add nsw i64 [[IDX]], -1
581 ; CHECK-NEXT:    ret i1 true
583   %idx.off1 = add i64 %idx, -5
584   %cmp1 = icmp ult i64 %idx.off1, 3
585   tail call void @llvm.assume(i1 %cmp1)
586   %idx.off2 = add i64 %idx, -1
587   %cmp2 = icmp ult i64 %idx.off2, 10
588   ret i1 %cmp2
591 define void @test_cmp_phi(i8 %a) {
592 ; CHECK-LABEL: @test_cmp_phi(
593 ; CHECK-NEXT:  entry:
594 ; CHECK-NEXT:    [[C0:%.*]] = icmp ult i8 [[A:%.*]], 2
595 ; CHECK-NEXT:    br i1 [[C0]], label [[LOOP:%.*]], label [[EXIT:%.*]]
596 ; CHECK:       loop:
597 ; CHECK-NEXT:    [[P:%.*]] = phi i8 [ [[A]], [[ENTRY:%.*]] ], [ [[B:%.*]], [[LOOP]] ]
598 ; CHECK-NEXT:    [[C1:%.*]] = icmp ne i8 [[P]], 0
599 ; CHECK-NEXT:    [[C4:%.*]] = call i1 @get_bool()
600 ; CHECK-NEXT:    [[B]] = zext i1 [[C4]] to i8
601 ; CHECK-NEXT:    br i1 [[C1]], label [[LOOP]], label [[EXIT]]
602 ; CHECK:       exit:
603 ; CHECK-NEXT:    ret void
605 entry:
606   %c0 = icmp ult i8 %a, 2
607   br i1 %c0, label %loop, label %exit
609 loop:
610   %p = phi i8 [ %a, %entry ], [ %b, %loop ]
611   %c1 = icmp ne i8 %p, 0
612   %c2 = icmp ne i8 %p, 2
613   %c3 = and i1 %c1, %c2
614   %c4 = call i1 @get_bool()
615   %b = zext i1 %c4 to i8
616   br i1 %c3, label %loop, label %exit
618 exit:
619   ret void
622 declare i1 @get_bool()
624 define void @test_icmp_or_ult(i32 %a, i32 %b) {
625 ; CHECK-LABEL: @test_icmp_or_ult(
626 ; CHECK-NEXT:  entry:
627 ; CHECK-NEXT:    [[OR:%.*]] = or i32 [[A:%.*]], [[B:%.*]]
628 ; CHECK-NEXT:    [[CMP:%.*]] = icmp ult i32 [[OR]], 42
629 ; CHECK-NEXT:    br i1 [[CMP]], label [[IF_TRUE:%.*]], label [[IF_FALSE:%.*]]
630 ; CHECK:       if.true:
631 ; CHECK-NEXT:    call void @check1(i1 true)
632 ; CHECK-NEXT:    call void @check1(i1 true)
633 ; CHECK-NEXT:    ret void
634 ; CHECK:       if.false:
635 ; CHECK-NEXT:    [[CMP4:%.*]] = icmp uge i32 [[A]], 42
636 ; CHECK-NEXT:    call void @check1(i1 [[CMP4]])
637 ; CHECK-NEXT:    [[CMP5:%.*]] = icmp uge i32 [[B]], 42
638 ; CHECK-NEXT:    call void @check1(i1 [[CMP5]])
639 ; CHECK-NEXT:    ret void
641 entry:
642   %or = or i32 %a, %b
643   %cmp = icmp ult i32 %or, 42
644   br i1 %cmp, label %if.true, label %if.false
646 if.true:
647   %cmp2 = icmp ult i32 %a, 42
648   call void @check1(i1 %cmp2)
649   %cmp3 = icmp ult i32 %b, 42
650   call void @check1(i1 %cmp3)
651   ret void
653 if.false:
654   %cmp4 = icmp uge i32 %a, 42
655   call void @check1(i1 %cmp4)
656   %cmp5 = icmp uge i32 %b, 42
657   call void @check1(i1 %cmp5)
658   ret void
661 define void @test_icmp_or_ule(i32 %a, i32 %b) {
662 ; CHECK-LABEL: @test_icmp_or_ule(
663 ; CHECK-NEXT:  entry:
664 ; CHECK-NEXT:    [[OR:%.*]] = or i32 [[A:%.*]], [[B:%.*]]
665 ; CHECK-NEXT:    [[CMP:%.*]] = icmp ule i32 [[OR]], 42
666 ; CHECK-NEXT:    br i1 [[CMP]], label [[IF_TRUE:%.*]], label [[IF_FALSE:%.*]]
667 ; CHECK:       if.true:
668 ; CHECK-NEXT:    call void @check1(i1 true)
669 ; CHECK-NEXT:    call void @check1(i1 true)
670 ; CHECK-NEXT:    ret void
671 ; CHECK:       if.false:
672 ; CHECK-NEXT:    [[CMP4:%.*]] = icmp ugt i32 [[A]], 42
673 ; CHECK-NEXT:    call void @check1(i1 [[CMP4]])
674 ; CHECK-NEXT:    [[CMP5:%.*]] = icmp ugt i32 [[B]], 42
675 ; CHECK-NEXT:    call void @check1(i1 [[CMP5]])
676 ; CHECK-NEXT:    ret void
678 entry:
679   %or = or i32 %a, %b
680   %cmp = icmp ule i32 %or, 42
681   br i1 %cmp, label %if.true, label %if.false
683 if.true:
684   %cmp2 = icmp ule i32 %a, 42
685   call void @check1(i1 %cmp2)
686   %cmp3 = icmp ule i32 %b, 42
687   call void @check1(i1 %cmp3)
688   ret void
690 if.false:
691   %cmp4 = icmp ugt i32 %a, 42
692   call void @check1(i1 %cmp4)
693   %cmp5 = icmp ugt i32 %b, 42
694   call void @check1(i1 %cmp5)
695   ret void
698 define void @test_icmp_or_ugt(i32 %a, i32 %b) {
699 ; CHECK-LABEL: @test_icmp_or_ugt(
700 ; CHECK-NEXT:  entry:
701 ; CHECK-NEXT:    [[OR:%.*]] = or i32 [[A:%.*]], [[B:%.*]]
702 ; CHECK-NEXT:    [[CMP:%.*]] = icmp ugt i32 [[OR]], 42
703 ; CHECK-NEXT:    br i1 [[CMP]], label [[IF_TRUE:%.*]], label [[IF_FALSE:%.*]]
704 ; CHECK:       if.true:
705 ; CHECK-NEXT:    [[CMP2:%.*]] = icmp ugt i32 [[A]], 42
706 ; CHECK-NEXT:    call void @check1(i1 [[CMP2]])
707 ; CHECK-NEXT:    [[CMP3:%.*]] = icmp ugt i32 [[B]], 42
708 ; CHECK-NEXT:    call void @check1(i1 [[CMP3]])
709 ; CHECK-NEXT:    ret void
710 ; CHECK:       if.false:
711 ; CHECK-NEXT:    call void @check1(i1 true)
712 ; CHECK-NEXT:    call void @check1(i1 true)
713 ; CHECK-NEXT:    ret void
715 entry:
716   %or = or i32 %a, %b
717   %cmp = icmp ugt i32 %or, 42
718   br i1 %cmp, label %if.true, label %if.false
720 if.true:
721   %cmp2 = icmp ugt i32 %a, 42
722   call void @check1(i1 %cmp2)
723   %cmp3 = icmp ugt i32 %b, 42
724   call void @check1(i1 %cmp3)
725   ret void
727 if.false:
728   %cmp4 = icmp ule i32 %a, 42
729   call void @check1(i1 %cmp4)
730   %cmp5 = icmp ule i32 %b, 42
731   call void @check1(i1 %cmp5)
732   ret void
735 define void @test_icmp_or_uge(i32 %a, i32 %b) {
736 ; CHECK-LABEL: @test_icmp_or_uge(
737 ; CHECK-NEXT:  entry:
738 ; CHECK-NEXT:    [[OR:%.*]] = or i32 [[A:%.*]], [[B:%.*]]
739 ; CHECK-NEXT:    [[CMP:%.*]] = icmp uge i32 [[OR]], 42
740 ; CHECK-NEXT:    br i1 [[CMP]], label [[IF_TRUE:%.*]], label [[IF_FALSE:%.*]]
741 ; CHECK:       if.true:
742 ; CHECK-NEXT:    [[CMP2:%.*]] = icmp uge i32 [[A]], 42
743 ; CHECK-NEXT:    call void @check1(i1 [[CMP2]])
744 ; CHECK-NEXT:    [[CMP3:%.*]] = icmp uge i32 [[B]], 42
745 ; CHECK-NEXT:    call void @check1(i1 [[CMP3]])
746 ; CHECK-NEXT:    ret void
747 ; CHECK:       if.false:
748 ; CHECK-NEXT:    call void @check1(i1 true)
749 ; CHECK-NEXT:    call void @check1(i1 true)
750 ; CHECK-NEXT:    ret void
752 entry:
753   %or = or i32 %a, %b
754   %cmp = icmp uge i32 %or, 42
755   br i1 %cmp, label %if.true, label %if.false
757 if.true:
758   %cmp2 = icmp uge i32 %a, 42
759   call void @check1(i1 %cmp2)
760   %cmp3 = icmp uge i32 %b, 42
761   call void @check1(i1 %cmp3)
762   ret void
764 if.false:
765   %cmp4 = icmp ult i32 %a, 42
766   call void @check1(i1 %cmp4)
767   %cmp5 = icmp ult i32 %b, 42
768   call void @check1(i1 %cmp5)
769   ret void
772 define void @test_icmp_or_slt(i32 %a, i32 %b) {
773 ; CHECK-LABEL: @test_icmp_or_slt(
774 ; CHECK-NEXT:  entry:
775 ; CHECK-NEXT:    [[OR:%.*]] = or i32 [[A:%.*]], [[B:%.*]]
776 ; CHECK-NEXT:    [[CMP:%.*]] = icmp slt i32 [[OR]], 42
777 ; CHECK-NEXT:    br i1 [[CMP]], label [[IF_TRUE:%.*]], label [[IF_FALSE:%.*]]
778 ; CHECK:       if.true:
779 ; CHECK-NEXT:    [[CMP2:%.*]] = icmp slt i32 [[A]], 42
780 ; CHECK-NEXT:    call void @check1(i1 [[CMP2]])
781 ; CHECK-NEXT:    [[CMP3:%.*]] = icmp slt i32 [[B]], 42
782 ; CHECK-NEXT:    call void @check1(i1 [[CMP3]])
783 ; CHECK-NEXT:    ret void
784 ; CHECK:       if.false:
785 ; CHECK-NEXT:    [[CMP4:%.*]] = icmp sge i32 [[A]], 42
786 ; CHECK-NEXT:    call void @check1(i1 [[CMP4]])
787 ; CHECK-NEXT:    [[CMP5:%.*]] = icmp sge i32 [[B]], 42
788 ; CHECK-NEXT:    call void @check1(i1 [[CMP5]])
789 ; CHECK-NEXT:    ret void
791 entry:
792   %or = or i32 %a, %b
793   %cmp = icmp slt i32 %or, 42
794   br i1 %cmp, label %if.true, label %if.false
796 if.true:
797   %cmp2 = icmp slt i32 %a, 42
798   call void @check1(i1 %cmp2)
799   %cmp3 = icmp slt i32 %b, 42
800   call void @check1(i1 %cmp3)
801   ret void
803 if.false:
804   %cmp4 = icmp sge i32 %a, 42
805   call void @check1(i1 %cmp4)
806   %cmp5 = icmp sge i32 %b, 42
807   call void @check1(i1 %cmp5)
808   ret void
811 define void @test_icmp_and_ugt(i32 %a, i32 %b) {
812 ; CHECK-LABEL: @test_icmp_and_ugt(
813 ; CHECK-NEXT:  entry:
814 ; CHECK-NEXT:    [[AND:%.*]] = and i32 [[A:%.*]], [[B:%.*]]
815 ; CHECK-NEXT:    [[CMP:%.*]] = icmp ugt i32 [[AND]], 42
816 ; CHECK-NEXT:    br i1 [[CMP]], label [[IF_TRUE:%.*]], label [[IF_FALSE:%.*]]
817 ; CHECK:       if.true:
818 ; CHECK-NEXT:    call void @check1(i1 true)
819 ; CHECK-NEXT:    call void @check1(i1 true)
820 ; CHECK-NEXT:    ret void
821 ; CHECK:       if.false:
822 ; CHECK-NEXT:    [[CMP4:%.*]] = icmp ule i32 [[A]], 42
823 ; CHECK-NEXT:    call void @check1(i1 [[CMP4]])
824 ; CHECK-NEXT:    [[CMP5:%.*]] = icmp ule i32 [[B]], 42
825 ; CHECK-NEXT:    call void @check1(i1 [[CMP5]])
826 ; CHECK-NEXT:    ret void
828 entry:
829   %and = and i32 %a, %b
830   %cmp = icmp ugt i32 %and, 42
831   br i1 %cmp, label %if.true, label %if.false
833 if.true:
834   %cmp2 = icmp ugt i32 %a, 42
835   call void @check1(i1 %cmp2)
836   %cmp3 = icmp ugt i32 %b, 42
837   call void @check1(i1 %cmp3)
838   ret void
840 if.false:
841   %cmp4 = icmp ule i32 %a, 42
842   call void @check1(i1 %cmp4)
843   %cmp5 = icmp ule i32 %b, 42
844   call void @check1(i1 %cmp5)
845   ret void
848 define void @test_icmp_and_uge(i32 %a, i32 %b) {
849 ; CHECK-LABEL: @test_icmp_and_uge(
850 ; CHECK-NEXT:  entry:
851 ; CHECK-NEXT:    [[AND:%.*]] = and i32 [[A:%.*]], [[B:%.*]]
852 ; CHECK-NEXT:    [[CMP:%.*]] = icmp uge i32 [[AND]], 42
853 ; CHECK-NEXT:    br i1 [[CMP]], label [[IF_TRUE:%.*]], label [[IF_FALSE:%.*]]
854 ; CHECK:       if.true:
855 ; CHECK-NEXT:    call void @check1(i1 true)
856 ; CHECK-NEXT:    call void @check1(i1 true)
857 ; CHECK-NEXT:    ret void
858 ; CHECK:       if.false:
859 ; CHECK-NEXT:    [[CMP4:%.*]] = icmp ult i32 [[A]], 42
860 ; CHECK-NEXT:    call void @check1(i1 [[CMP4]])
861 ; CHECK-NEXT:    [[CMP5:%.*]] = icmp ult i32 [[B]], 42
862 ; CHECK-NEXT:    call void @check1(i1 [[CMP5]])
863 ; CHECK-NEXT:    ret void
865 entry:
866   %and = and i32 %a, %b
867   %cmp = icmp uge i32 %and, 42
868   br i1 %cmp, label %if.true, label %if.false
870 if.true:
871   %cmp2 = icmp uge i32 %a, 42
872   call void @check1(i1 %cmp2)
873   %cmp3 = icmp uge i32 %b, 42
874   call void @check1(i1 %cmp3)
875   ret void
877 if.false:
878   %cmp4 = icmp ult i32 %a, 42
879   call void @check1(i1 %cmp4)
880   %cmp5 = icmp ult i32 %b, 42
881   call void @check1(i1 %cmp5)
882   ret void
885 define void @test_icmp_and_ult(i32 %a, i32 %b) {
886 ; CHECK-LABEL: @test_icmp_and_ult(
887 ; CHECK-NEXT:  entry:
888 ; CHECK-NEXT:    [[AND:%.*]] = and i32 [[A:%.*]], [[B:%.*]]
889 ; CHECK-NEXT:    [[CMP:%.*]] = icmp ult i32 [[AND]], 42
890 ; CHECK-NEXT:    br i1 [[CMP]], label [[IF_TRUE:%.*]], label [[IF_FALSE:%.*]]
891 ; CHECK:       if.true:
892 ; CHECK-NEXT:    [[CMP2:%.*]] = icmp ult i32 [[A]], 42
893 ; CHECK-NEXT:    call void @check1(i1 [[CMP2]])
894 ; CHECK-NEXT:    [[CMP3:%.*]] = icmp ult i32 [[B]], 42
895 ; CHECK-NEXT:    call void @check1(i1 [[CMP3]])
896 ; CHECK-NEXT:    ret void
897 ; CHECK:       if.false:
898 ; CHECK-NEXT:    call void @check1(i1 true)
899 ; CHECK-NEXT:    call void @check1(i1 true)
900 ; CHECK-NEXT:    ret void
902 entry:
903   %and = and i32 %a, %b
904   %cmp = icmp ult i32 %and, 42
905   br i1 %cmp, label %if.true, label %if.false
907 if.true:
908   %cmp2 = icmp ult i32 %a, 42
909   call void @check1(i1 %cmp2)
910   %cmp3 = icmp ult i32 %b, 42
911   call void @check1(i1 %cmp3)
912   ret void
914 if.false:
915   %cmp4 = icmp uge i32 %a, 42
916   call void @check1(i1 %cmp4)
917   %cmp5 = icmp uge i32 %b, 42
918   call void @check1(i1 %cmp5)
919   ret void
922 define void @test_icmp_and_sgt(i32 %a, i32 %b) {
923 ; CHECK-LABEL: @test_icmp_and_sgt(
924 ; CHECK-NEXT:  entry:
925 ; CHECK-NEXT:    [[AND:%.*]] = and i32 [[A:%.*]], [[B:%.*]]
926 ; CHECK-NEXT:    [[CMP:%.*]] = icmp sgt i32 [[AND]], 42
927 ; CHECK-NEXT:    br i1 [[CMP]], label [[IF_TRUE:%.*]], label [[IF_FALSE:%.*]]
928 ; CHECK:       if.true:
929 ; CHECK-NEXT:    [[CMP2:%.*]] = icmp sgt i32 [[A]], 42
930 ; CHECK-NEXT:    call void @check1(i1 [[CMP2]])
931 ; CHECK-NEXT:    [[CMP3:%.*]] = icmp sgt i32 [[B]], 42
932 ; CHECK-NEXT:    call void @check1(i1 [[CMP3]])
933 ; CHECK-NEXT:    ret void
934 ; CHECK:       if.false:
935 ; CHECK-NEXT:    [[CMP4:%.*]] = icmp sle i32 [[A]], 42
936 ; CHECK-NEXT:    call void @check1(i1 [[CMP4]])
937 ; CHECK-NEXT:    [[CMP5:%.*]] = icmp sle i32 [[B]], 42
938 ; CHECK-NEXT:    call void @check1(i1 [[CMP5]])
939 ; CHECK-NEXT:    ret void
941 entry:
942   %and = and i32 %a, %b
943   %cmp = icmp sgt i32 %and, 42
944   br i1 %cmp, label %if.true, label %if.false
946 if.true:
947   %cmp2 = icmp sgt i32 %a, 42
948   call void @check1(i1 %cmp2)
949   %cmp3 = icmp sgt i32 %b, 42
950   call void @check1(i1 %cmp3)
951   ret void
953 if.false:
954   %cmp4 = icmp sle i32 %a, 42
955   call void @check1(i1 %cmp4)
956   %cmp5 = icmp sle i32 %b, 42
957   call void @check1(i1 %cmp5)
958   ret void
961 define void @test_icmp_mask_eq_two_values(i32 %a) {
962 ; CHECK-LABEL: @test_icmp_mask_eq_two_values(
963 ; CHECK-NEXT:    [[AND:%.*]] = and i32 [[A:%.*]], -2
964 ; CHECK-NEXT:    [[CMP:%.*]] = icmp eq i32 [[AND]], 10
965 ; CHECK-NEXT:    br i1 [[CMP]], label [[IF_TRUE:%.*]], label [[IF_FALSE:%.*]]
966 ; CHECK:       if.true:
967 ; CHECK-NEXT:    call void @check1(i1 true)
968 ; CHECK-NEXT:    call void @check1(i1 true)
969 ; CHECK-NEXT:    call void @check1(i1 false)
970 ; CHECK-NEXT:    call void @check1(i1 false)
971 ; CHECK-NEXT:    ret void
972 ; CHECK:       if.false:
973 ; CHECK-NEXT:    ret void
975   %and = and i32 %a, -2
976   %cmp = icmp eq i32 %and, 10
977   br i1 %cmp, label %if.true, label %if.false
979 if.true:
980   %cmp2 = icmp uge i32 %a, 10
981   call void @check1(i1 %cmp2)
982   %cmp3 = icmp ule i32 %a, 11
983   call void @check1(i1 %cmp3)
984   %cmp4 = icmp ult i32 %a, 10
985   call void @check1(i1 %cmp4)
986   %cmp5 = icmp ugt i32 %a, 11
987   call void @check1(i1 %cmp5)
988   ret void
990 if.false:
991   ret void
994 define void @test_icmp_mask_eq_bit_set(i32 %a) {
995 ; CHECK-LABEL: @test_icmp_mask_eq_bit_set(
996 ; CHECK-NEXT:    [[AND:%.*]] = and i32 [[A:%.*]], 32
997 ; CHECK-NEXT:    [[CMP:%.*]] = icmp eq i32 [[AND]], 32
998 ; CHECK-NEXT:    br i1 [[CMP]], label [[IF_TRUE:%.*]], label [[IF_FALSE:%.*]]
999 ; CHECK:       if.true:
1000 ; CHECK-NEXT:    call void @check1(i1 true)
1001 ; CHECK-NEXT:    [[CMP3:%.*]] = icmp uge i32 [[A]], 33
1002 ; CHECK-NEXT:    call void @check1(i1 [[CMP3]])
1003 ; CHECK-NEXT:    ret void
1004 ; CHECK:       if.false:
1005 ; CHECK-NEXT:    ret void
1007   %and = and i32 %a, 32
1008   %cmp = icmp eq i32 %and, 32
1009   br i1 %cmp, label %if.true, label %if.false
1011 if.true:
1012   %cmp2 = icmp uge i32 %a, 32
1013   call void @check1(i1 %cmp2)
1014   %cmp3 = icmp uge i32 %a, 33
1015   call void @check1(i1 %cmp3)
1016   ret void
1018 if.false:
1019   ret void
1022 define void @test_icmp_mask_eq_bit_unset(i32 %a) {
1023 ; CHECK-LABEL: @test_icmp_mask_eq_bit_unset(
1024 ; CHECK-NEXT:    [[AND:%.*]] = and i32 [[A:%.*]], 32
1025 ; CHECK-NEXT:    [[CMP:%.*]] = icmp eq i32 [[AND]], 0
1026 ; CHECK-NEXT:    br i1 [[CMP]], label [[IF_TRUE:%.*]], label [[IF_FALSE:%.*]]
1027 ; CHECK:       if.true:
1028 ; CHECK-NEXT:    call void @check1(i1 true)
1029 ; CHECK-NEXT:    [[CMP3:%.*]] = icmp ule i32 [[A]], -34
1030 ; CHECK-NEXT:    call void @check1(i1 [[CMP3]])
1031 ; CHECK-NEXT:    ret void
1032 ; CHECK:       if.false:
1033 ; CHECK-NEXT:    ret void
1035   %and = and i32 %a, 32
1036   %cmp = icmp eq i32 %and, 0
1037   br i1 %cmp, label %if.true, label %if.false
1039 if.true:
1040   %cmp2 = icmp ule i32 %a, -33
1041   call void @check1(i1 %cmp2)
1042   %cmp3 = icmp ule i32 %a, -34
1043   call void @check1(i1 %cmp3)
1044   ret void
1046 if.false:
1047   ret void
1050 define void @test_icmp_mask_eq_wrong_predicate(i32 %a) {
1051 ; CHECK-LABEL: @test_icmp_mask_eq_wrong_predicate(
1052 ; CHECK-NEXT:    [[AND:%.*]] = and i32 [[A:%.*]], -2
1053 ; CHECK-NEXT:    [[CMP:%.*]] = icmp ne i32 [[AND]], 10
1054 ; CHECK-NEXT:    br i1 [[CMP]], label [[IF_TRUE:%.*]], label [[IF_FALSE:%.*]]
1055 ; CHECK:       if.true:
1056 ; CHECK-NEXT:    [[CMP2:%.*]] = icmp uge i32 [[A]], 10
1057 ; CHECK-NEXT:    call void @check1(i1 [[CMP2]])
1058 ; CHECK-NEXT:    [[CMP3:%.*]] = icmp ule i32 [[A]], 11
1059 ; CHECK-NEXT:    call void @check1(i1 [[CMP3]])
1060 ; CHECK-NEXT:    [[CMP4:%.*]] = icmp ult i32 [[A]], 10
1061 ; CHECK-NEXT:    call void @check1(i1 [[CMP4]])
1062 ; CHECK-NEXT:    [[CMP5:%.*]] = icmp ugt i32 [[A]], 11
1063 ; CHECK-NEXT:    call void @check1(i1 [[CMP5]])
1064 ; CHECK-NEXT:    ret void
1065 ; CHECK:       if.false:
1066 ; CHECK-NEXT:    ret void
1068   %and = and i32 %a, -2
1069   %cmp = icmp ne i32 %and, 10
1070   br i1 %cmp, label %if.true, label %if.false
1072 if.true:
1073   %cmp2 = icmp uge i32 %a, 10
1074   call void @check1(i1 %cmp2)
1075   %cmp3 = icmp ule i32 %a, 11
1076   call void @check1(i1 %cmp3)
1077   %cmp4 = icmp ult i32 %a, 10
1078   call void @check1(i1 %cmp4)
1079   %cmp5 = icmp ugt i32 %a, 11
1080   call void @check1(i1 %cmp5)
1081   ret void
1083 if.false:
1084   ret void
1087 define void @test_icmp_mask_ne(i32 %a) {
1088 ; CHECK-LABEL: @test_icmp_mask_ne(
1089 ; CHECK-NEXT:    [[AND:%.*]] = and i32 [[A:%.*]], 6
1090 ; CHECK-NEXT:    [[CMP:%.*]] = icmp ne i32 [[AND]], 0
1091 ; CHECK-NEXT:    br i1 [[CMP]], label [[IF_TRUE:%.*]], label [[IF_FALSE:%.*]]
1092 ; CHECK:       if.true:
1093 ; CHECK-NEXT:    call void @check1(i1 true)
1094 ; CHECK-NEXT:    [[CMP3:%.*]] = icmp ugt i32 [[A]], 2
1095 ; CHECK-NEXT:    call void @check1(i1 [[CMP3]])
1096 ; CHECK-NEXT:    [[CMP4:%.*]] = icmp ult i32 [[A]], -1
1097 ; CHECK-NEXT:    call void @check1(i1 [[CMP4]])
1098 ; CHECK-NEXT:    ret void
1099 ; CHECK:       if.false:
1100 ; CHECK-NEXT:    ret void
1102   %and = and i32 %a, 6
1103   %cmp = icmp ne i32 %and, 0
1104   br i1 %cmp, label %if.true, label %if.false
1106 if.true:
1107   %cmp2 = icmp uge i32 %a, 2
1108   call void @check1(i1 %cmp2)
1109   %cmp3 = icmp ugt i32 %a, 2
1110   call void @check1(i1 %cmp3)
1111   %cmp4 = icmp ult i32 %a, -1
1112   call void @check1(i1 %cmp4)
1113   ret void
1115 if.false:
1116   ret void
1119 define void @test_icmp_mask_ne_nonzero_cmp(i32 %a) {
1120 ; CHECK-LABEL: @test_icmp_mask_ne_nonzero_cmp(
1121 ; CHECK-NEXT:    [[AND:%.*]] = and i32 [[A:%.*]], 6
1122 ; CHECK-NEXT:    [[CMP:%.*]] = icmp ne i32 [[AND]], 6
1123 ; CHECK-NEXT:    br i1 [[CMP]], label [[IF_TRUE:%.*]], label [[IF_FALSE:%.*]]
1124 ; CHECK:       if.true:
1125 ; CHECK-NEXT:    [[CMP2:%.*]] = icmp uge i32 [[A]], 2
1126 ; CHECK-NEXT:    call void @check1(i1 [[CMP2]])
1127 ; CHECK-NEXT:    [[CMP3:%.*]] = icmp ugt i32 [[A]], 2
1128 ; CHECK-NEXT:    call void @check1(i1 [[CMP3]])
1129 ; CHECK-NEXT:    [[CMP4:%.*]] = icmp ult i32 [[A]], -1
1130 ; CHECK-NEXT:    call void @check1(i1 [[CMP4]])
1131 ; CHECK-NEXT:    ret void
1132 ; CHECK:       if.false:
1133 ; CHECK-NEXT:    ret void
1135   %and = and i32 %a, 6
1136   %cmp = icmp ne i32 %and, 6
1137   br i1 %cmp, label %if.true, label %if.false
1139 if.true:
1140   %cmp2 = icmp uge i32 %a, 2
1141   call void @check1(i1 %cmp2)
1142   %cmp3 = icmp ugt i32 %a, 2
1143   call void @check1(i1 %cmp3)
1144   %cmp4 = icmp ult i32 %a, -1
1145   call void @check1(i1 %cmp4)
1146   ret void
1148 if.false:
1149   ret void
1152 define void @test_icmp_mask_ne_zero_mask(i32 %a) {
1153 ; CHECK-LABEL: @test_icmp_mask_ne_zero_mask(
1154 ; CHECK-NEXT:    [[AND:%.*]] = and i32 [[A:%.*]], 0
1155 ; CHECK-NEXT:    br i1 false, label [[IF_TRUE:%.*]], label [[IF_FALSE:%.*]]
1156 ; CHECK:       if.true:
1157 ; CHECK-NEXT:    [[CMP2:%.*]] = icmp ne i32 [[A]], 0
1158 ; CHECK-NEXT:    call void @check1(i1 [[CMP2]])
1159 ; CHECK-NEXT:    ret void
1160 ; CHECK:       if.false:
1161 ; CHECK-NEXT:    ret void
1163   %and = and i32 %a, 0
1164   %cmp = icmp ne i32 %and, 0
1165   br i1 %cmp, label %if.true, label %if.false
1167 if.true:
1168   %cmp2 = icmp ne i32 %a, 0
1169   call void @check1(i1 %cmp2)
1170   ret void
1172 if.false:
1173   ret void
1176 attributes #4 = { noreturn }