1 ; NOTE: Assertions have been autogenerated by utils/update_test_checks.py
2 ; RUN: opt -passes=correlated-propagation -S %s | FileCheck %s
4 target datalayout = "e-m:o-i64:64-f80:128-n8:16:32:64-S128"
5 target triple = "x86_64-apple-macosx10.10.0"
7 declare void @check1(i1) #1
8 declare void @check2(i1) #1
9 declare void @llvm.assume(i1)
11 ; Make sure we propagate the value of %tmp35 to the true/false cases
13 define void @test1(i64 %tmp35) {
14 ; CHECK-LABEL: @test1(
16 ; CHECK-NEXT: [[TMP36:%.*]] = icmp sgt i64 [[TMP35:%.*]], 0
17 ; CHECK-NEXT: br i1 [[TMP36]], label [[BB_TRUE:%.*]], label [[BB_FALSE:%.*]]
19 ; CHECK-NEXT: tail call void @check1(i1 false) #[[ATTR2:[0-9]+]]
20 ; CHECK-NEXT: unreachable
22 ; CHECK-NEXT: tail call void @check2(i1 true) #[[ATTR2]]
23 ; CHECK-NEXT: unreachable
26 %tmp36 = icmp sgt i64 %tmp35, 0
27 br i1 %tmp36, label %bb_true, label %bb_false
30 %tmp47 = icmp slt i64 %tmp35, 0
31 tail call void @check1(i1 %tmp47) #4
35 %tmp48 = icmp sle i64 %tmp35, 0
36 tail call void @check2(i1 %tmp48) #4
40 ; This is the same as test1 but with a diamond to ensure we
41 ; get %tmp36 from both true and false BBs.
43 define void @test2(i64 %tmp35, i1 %inner_cmp) {
44 ; CHECK-LABEL: @test2(
46 ; CHECK-NEXT: [[TMP36:%.*]] = icmp sgt i64 [[TMP35:%.*]], 0
47 ; CHECK-NEXT: br i1 [[TMP36]], label [[BB_TRUE:%.*]], label [[BB_FALSE:%.*]]
49 ; CHECK-NEXT: br i1 [[INNER_CMP:%.*]], label [[INNER_TRUE:%.*]], label [[INNER_FALSE:%.*]]
51 ; CHECK-NEXT: br label [[MERGE:%.*]]
53 ; CHECK-NEXT: br label [[MERGE]]
55 ; CHECK-NEXT: tail call void @check1(i1 false)
56 ; CHECK-NEXT: unreachable
58 ; CHECK-NEXT: tail call void @check2(i1 true) #[[ATTR2]]
59 ; CHECK-NEXT: unreachable
62 %tmp36 = icmp sgt i64 %tmp35, 0
63 br i1 %tmp36, label %bb_true, label %bb_false
66 br i1 %inner_cmp, label %inner_true, label %inner_false
75 %tmp47 = icmp slt i64 %tmp35, 0
76 tail call void @check1(i1 %tmp47) #0
80 %tmp48 = icmp sle i64 %tmp35, 0
81 tail call void @check2(i1 %tmp48) #4
85 ; Make sure binary operator transfer functions are run when RHS is non-constant
87 define i1 @test3(i32 %x, i32 %y) #0 {
88 ; CHECK-LABEL: @test3(
90 ; CHECK-NEXT: [[CMP1:%.*]] = icmp ult i32 [[X:%.*]], 10
91 ; CHECK-NEXT: br i1 [[CMP1]], label [[CONT1:%.*]], label [[OUT:%.*]]
93 ; CHECK-NEXT: [[CMP2:%.*]] = icmp ult i32 [[Y:%.*]], 10
94 ; CHECK-NEXT: br i1 [[CMP2]], label [[CONT2:%.*]], label [[OUT]]
96 ; CHECK-NEXT: [[ADD:%.*]] = add nuw nsw i32 [[X]], [[Y]]
97 ; CHECK-NEXT: br label [[OUT]]
99 ; CHECK-NEXT: ret i1 true
102 %cmp1 = icmp ult i32 %x, 10
103 br i1 %cmp1, label %cont1, label %out
106 %cmp2 = icmp ult i32 %y, 10
107 br i1 %cmp2, label %cont2, label %out
110 %add = add i32 %x, %y
111 %cmp3 = icmp ult i32 %add, 25
115 %ret = phi i1 [ true, %entry], [ true, %cont1 ], [ %cmp3, %cont2 ]
119 ; Same as previous but make sure nobody gets over-zealous
121 define i1 @test4(i32 %x, i32 %y) #0 {
122 ; CHECK-LABEL: @test4(
124 ; CHECK-NEXT: [[CMP1:%.*]] = icmp ult i32 [[X:%.*]], 10
125 ; CHECK-NEXT: br i1 [[CMP1]], label [[CONT1:%.*]], label [[OUT:%.*]]
127 ; CHECK-NEXT: [[CMP2:%.*]] = icmp ult i32 [[Y:%.*]], 10
128 ; CHECK-NEXT: br i1 [[CMP2]], label [[CONT2:%.*]], label [[OUT]]
130 ; CHECK-NEXT: [[ADD:%.*]] = add nuw nsw i32 [[X]], [[Y]]
131 ; CHECK-NEXT: [[CMP3:%.*]] = icmp ult i32 [[ADD]], 15
132 ; CHECK-NEXT: br label [[OUT]]
134 ; CHECK-NEXT: [[RET:%.*]] = phi i1 [ true, [[ENTRY:%.*]] ], [ true, [[CONT1]] ], [ [[CMP3]], [[CONT2]] ]
135 ; CHECK-NEXT: ret i1 [[RET]]
138 %cmp1 = icmp ult i32 %x, 10
139 br i1 %cmp1, label %cont1, label %out
142 %cmp2 = icmp ult i32 %y, 10
143 br i1 %cmp2, label %cont2, label %out
146 %add = add i32 %x, %y
147 %cmp3 = icmp ult i32 %add, 15
151 %ret = phi i1 [ true, %entry], [ true, %cont1 ], [ %cmp3, %cont2 ]
155 ; Make sure binary operator transfer functions are run when RHS is non-constant
157 define i1 @test5(i32 %x, i32 %y) #0 {
158 ; CHECK-LABEL: @test5(
160 ; CHECK-NEXT: [[CMP1:%.*]] = icmp ult i32 [[X:%.*]], 5
161 ; CHECK-NEXT: br i1 [[CMP1]], label [[CONT1:%.*]], label [[OUT:%.*]]
163 ; CHECK-NEXT: [[CMP2:%.*]] = icmp ult i32 [[Y:%.*]], 5
164 ; CHECK-NEXT: br i1 [[CMP2]], label [[CONT2:%.*]], label [[OUT]]
166 ; CHECK-NEXT: [[SHIFTED:%.*]] = shl nuw nsw i32 [[X]], [[Y]]
167 ; CHECK-NEXT: br label [[OUT]]
169 ; CHECK-NEXT: ret i1 true
172 %cmp1 = icmp ult i32 %x, 5
173 br i1 %cmp1, label %cont1, label %out
176 %cmp2 = icmp ult i32 %y, 5
177 br i1 %cmp2, label %cont2, label %out
180 %shifted = shl i32 %x, %y
181 %cmp3 = icmp ult i32 %shifted, 65536
185 %ret = phi i1 [ true, %entry], [ true, %cont1 ], [ %cmp3, %cont2 ]
189 ; Same as previous but make sure nobody gets over-zealous
191 define i1 @test6(i32 %x, i32 %y) #0 {
192 ; CHECK-LABEL: @test6(
194 ; CHECK-NEXT: [[CMP1:%.*]] = icmp ult i32 [[X:%.*]], 5
195 ; CHECK-NEXT: br i1 [[CMP1]], label [[CONT1:%.*]], label [[OUT:%.*]]
197 ; CHECK-NEXT: [[CMP2:%.*]] = icmp ult i32 [[Y:%.*]], 15
198 ; CHECK-NEXT: br i1 [[CMP2]], label [[CONT2:%.*]], label [[OUT]]
200 ; CHECK-NEXT: [[SHIFTED:%.*]] = shl nuw nsw i32 [[X]], [[Y]]
201 ; CHECK-NEXT: [[CMP3:%.*]] = icmp ult i32 [[SHIFTED]], 65536
202 ; CHECK-NEXT: br label [[OUT]]
204 ; CHECK-NEXT: [[RET:%.*]] = phi i1 [ true, [[ENTRY:%.*]] ], [ true, [[CONT1]] ], [ [[CMP3]], [[CONT2]] ]
205 ; CHECK-NEXT: ret i1 [[RET]]
208 %cmp1 = icmp ult i32 %x, 5
209 br i1 %cmp1, label %cont1, label %out
212 %cmp2 = icmp ult i32 %y, 15
213 br i1 %cmp2, label %cont2, label %out
216 %shifted = shl i32 %x, %y
217 %cmp3 = icmp ult i32 %shifted, 65536
221 %ret = phi i1 [ true, %entry], [ true, %cont1 ], [ %cmp3, %cont2 ]
225 define i1 @test7(i32 %a, i32 %b) {
226 ; CHECK-LABEL: @test7(
228 ; CHECK-NEXT: [[CMP0:%.*]] = icmp sge i32 [[A:%.*]], 0
229 ; CHECK-NEXT: [[CMP1:%.*]] = icmp sge i32 [[B:%.*]], 0
230 ; CHECK-NEXT: [[BR:%.*]] = and i1 [[CMP0]], [[CMP1]]
231 ; CHECK-NEXT: br i1 [[BR]], label [[BB:%.*]], label [[EXIT:%.*]]
233 ; CHECK-NEXT: [[ADD:%.*]] = add nuw i32 [[A]], [[B]]
234 ; CHECK-NEXT: [[RES:%.*]] = icmp sge i32 [[ADD]], 0
235 ; CHECK-NEXT: br label [[EXIT]]
237 ; CHECK-NEXT: [[IV:%.*]] = phi i1 [ true, [[BEGIN:%.*]] ], [ [[RES]], [[BB]] ]
238 ; CHECK-NEXT: ret i1 [[IV]]
241 %cmp0 = icmp sge i32 %a, 0
242 %cmp1 = icmp sge i32 %b, 0
243 %br = and i1 %cmp0, %cmp1
244 br i1 %br, label %bb, label %exit
247 %add = add i32 %a, %b
248 %res = icmp sge i32 %add, 0
252 %iv = phi i1 [ true, %begin ], [ %res, %bb ]
256 define i1 @test8(i32 %a, i32 %b) {
257 ; CHECK-LABEL: @test8(
259 ; CHECK-NEXT: [[CMP0:%.*]] = icmp sge i32 [[A:%.*]], 0
260 ; CHECK-NEXT: [[CMP1:%.*]] = icmp sge i32 [[B:%.*]], 0
261 ; CHECK-NEXT: [[BR:%.*]] = and i1 [[CMP0]], [[CMP1]]
262 ; CHECK-NEXT: br i1 [[BR]], label [[BB:%.*]], label [[EXIT:%.*]]
264 ; CHECK-NEXT: [[ADD:%.*]] = add nuw nsw i32 [[A]], [[B]]
265 ; CHECK-NEXT: br label [[EXIT]]
267 ; CHECK-NEXT: ret i1 true
270 %cmp0 = icmp sge i32 %a, 0
271 %cmp1 = icmp sge i32 %b, 0
272 %br = and i1 %cmp0, %cmp1
273 br i1 %br, label %bb, label %exit
276 %add = add nsw i32 %a, %b
277 %res = icmp sge i32 %add, 0
281 %iv = phi i1 [ true, %begin ], [ %res, %bb ]
285 define i1 @test10(i32 %a, i32 %b) {
286 ; CHECK-LABEL: @test10(
288 ; CHECK-NEXT: [[CMP:%.*]] = icmp uge i32 [[A:%.*]], -256
289 ; CHECK-NEXT: br i1 [[CMP]], label [[BB:%.*]], label [[EXIT:%.*]]
291 ; CHECK-NEXT: [[ADD:%.*]] = add i32 [[A]], [[B:%.*]]
292 ; CHECK-NEXT: [[RES:%.*]] = icmp uge i32 [[ADD]], -256
293 ; CHECK-NEXT: br label [[EXIT]]
295 ; CHECK-NEXT: [[IV:%.*]] = phi i1 [ true, [[BEGIN:%.*]] ], [ [[RES]], [[BB]] ]
296 ; CHECK-NEXT: ret i1 [[IV]]
299 %cmp = icmp uge i32 %a, 4294967040
300 br i1 %cmp, label %bb, label %exit
303 %add = add i32 %a, %b
304 %res = icmp uge i32 %add, 4294967040
308 %iv = phi i1 [ true, %begin ], [ %res, %bb ]
312 define i1 @test11(i32 %a, i32 %b) {
313 ; CHECK-LABEL: @test11(
315 ; CHECK-NEXT: [[CMP:%.*]] = icmp uge i32 [[A:%.*]], -256
316 ; CHECK-NEXT: br i1 [[CMP]], label [[BB:%.*]], label [[EXIT:%.*]]
318 ; CHECK-NEXT: [[ADD:%.*]] = add nuw i32 [[A]], [[B:%.*]]
319 ; CHECK-NEXT: br label [[EXIT]]
321 ; CHECK-NEXT: ret i1 true
324 %cmp = icmp uge i32 %a, 4294967040
325 br i1 %cmp, label %bb, label %exit
328 %add = add nuw i32 %a, %b
329 %res = icmp uge i32 %add, 4294967040
333 %iv = phi i1 [ true, %begin ], [ %res, %bb ]
337 define i1 @test12(i32 %x) {
338 ; CHECK-LABEL: @test12(
339 ; CHECK-NEXT: [[ZEXT:%.*]] = zext i32 [[X:%.*]] to i64
340 ; CHECK-NEXT: [[MUL:%.*]] = mul nuw nsw i64 [[ZEXT]], 7
341 ; CHECK-NEXT: [[SHR:%.*]] = lshr i64 [[MUL]], 32
342 ; CHECK-NEXT: [[TRUNC:%.*]] = trunc i64 [[SHR]] to i32
343 ; CHECK-NEXT: ret i1 true
345 %zext = zext i32 %x to i64
346 %mul = mul nuw i64 %zext, 7
347 %shr = lshr i64 %mul, 32
348 %trunc = trunc i64 %shr to i32
349 %cmp = icmp ult i32 %trunc, 7
353 define i1 @test13(i8 %x, ptr %p) {
354 ; CHECK-LABEL: @test13(
355 ; CHECK-NEXT: [[ZEXT:%.*]] = zext i8 [[X:%.*]] to i64
356 ; CHECK-NEXT: [[ADD:%.*]] = add nuw nsw i64 [[ZEXT]], 128
357 ; CHECK-NEXT: store i64 [[ADD]], ptr [[P:%.*]], align 8
358 ; CHECK-NEXT: ret i1 true
360 %zext = zext i8 %x to i64
361 %add = add nuw nsw i64 %zext, 128
362 %cmp = icmp ult i64 %add, 384
363 ; Without this extra use, InstSimplify could handle this
364 store i64 %add, ptr %p
368 define i1 @test14(i32 %a, i32 %b) {
369 ; CHECK-LABEL: @test14(
371 ; CHECK-NEXT: [[CMP0:%.*]] = icmp sge i32 [[A:%.*]], 0
372 ; CHECK-NEXT: [[CMP1:%.*]] = icmp sge i32 [[B:%.*]], 0
373 ; CHECK-NEXT: [[BR:%.*]] = and i1 [[CMP0]], [[CMP1]]
374 ; CHECK-NEXT: br i1 [[BR]], label [[BB:%.*]], label [[EXIT:%.*]]
376 ; CHECK-NEXT: [[SUB:%.*]] = sub nsw i32 [[A]], [[B]]
377 ; CHECK-NEXT: [[RES:%.*]] = icmp sge i32 [[SUB]], 0
378 ; CHECK-NEXT: br label [[EXIT]]
380 ; CHECK-NEXT: [[IV:%.*]] = phi i1 [ true, [[BEGIN:%.*]] ], [ [[RES]], [[BB]] ]
381 ; CHECK-NEXT: ret i1 [[IV]]
384 %cmp0 = icmp sge i32 %a, 0
385 %cmp1 = icmp sge i32 %b, 0
386 %br = and i1 %cmp0, %cmp1
387 br i1 %br, label %bb, label %exit
390 %sub = sub i32 %a, %b
391 %res = icmp sge i32 %sub, 0
395 %iv = phi i1 [ true, %begin ], [ %res, %bb ]
399 define i1 @test15(i32 %a, i32 %b) {
400 ; CHECK-LABEL: @test15(
402 ; CHECK-NEXT: [[CMP0:%.*]] = icmp sge i32 [[A:%.*]], 0
403 ; CHECK-NEXT: [[CMP1:%.*]] = icmp sge i32 [[B:%.*]], 0
404 ; CHECK-NEXT: [[BR:%.*]] = and i1 [[CMP0]], [[CMP1]]
405 ; CHECK-NEXT: br i1 [[BR]], label [[BB:%.*]], label [[EXIT:%.*]]
407 ; CHECK-NEXT: [[SUB:%.*]] = sub nsw i32 [[A]], [[B]]
408 ; CHECK-NEXT: [[RES:%.*]] = icmp sge i32 [[SUB]], 0
409 ; CHECK-NEXT: br label [[EXIT]]
411 ; CHECK-NEXT: [[IV:%.*]] = phi i1 [ true, [[BEGIN:%.*]] ], [ [[RES]], [[BB]] ]
412 ; CHECK-NEXT: ret i1 [[IV]]
415 %cmp0 = icmp sge i32 %a, 0
416 %cmp1 = icmp sge i32 %b, 0
417 %br = and i1 %cmp0, %cmp1
418 br i1 %br, label %bb, label %exit
421 %sub = sub nsw i32 %a, %b
422 %res = icmp sge i32 %sub, 0
426 %iv = phi i1 [ true, %begin ], [ %res, %bb ]
430 define i1 @test16(i32 %a, i32 %b) {
431 ; CHECK-LABEL: @test16(
433 ; CHECK-NEXT: [[CMP0:%.*]] = icmp sge i32 [[A:%.*]], 0
434 ; CHECK-NEXT: [[CMP1:%.*]] = icmp sge i32 [[B:%.*]], 0
435 ; CHECK-NEXT: [[BR:%.*]] = and i1 [[CMP0]], [[CMP1]]
436 ; CHECK-NEXT: br i1 [[BR]], label [[BB:%.*]], label [[EXIT:%.*]]
438 ; CHECK-NEXT: [[SUB:%.*]] = sub nuw nsw i32 [[A]], [[B]]
439 ; CHECK-NEXT: br label [[EXIT]]
441 ; CHECK-NEXT: ret i1 true
444 %cmp0 = icmp sge i32 %a, 0
445 %cmp1 = icmp sge i32 %b, 0
446 %br = and i1 %cmp0, %cmp1
447 br i1 %br, label %bb, label %exit
450 %sub = sub nuw i32 %a, %b
451 %res = icmp sge i32 %sub, 0
455 %iv = phi i1 [ true, %begin ], [ %res, %bb ]
459 define i1 @test17(i32 %a, i32 %b) {
460 ; CHECK-LABEL: @test17(
462 ; CHECK-NEXT: [[CMP0:%.*]] = icmp sle i32 [[A:%.*]], 0
463 ; CHECK-NEXT: [[CMP1:%.*]] = icmp sge i32 [[B:%.*]], 0
464 ; CHECK-NEXT: [[BR:%.*]] = and i1 [[CMP0]], [[CMP1]]
465 ; CHECK-NEXT: br i1 [[BR]], label [[BB:%.*]], label [[EXIT:%.*]]
467 ; CHECK-NEXT: [[SUB:%.*]] = sub i32 [[A]], [[B]]
468 ; CHECK-NEXT: [[RES:%.*]] = icmp sle i32 [[SUB]], 0
469 ; CHECK-NEXT: br label [[EXIT]]
471 ; CHECK-NEXT: [[IV:%.*]] = phi i1 [ true, [[BEGIN:%.*]] ], [ [[RES]], [[BB]] ]
472 ; CHECK-NEXT: ret i1 [[IV]]
475 %cmp0 = icmp sle i32 %a, 0
476 %cmp1 = icmp sge i32 %b, 0
477 %br = and i1 %cmp0, %cmp1
478 br i1 %br, label %bb, label %exit
481 %sub = sub i32 %a, %b
482 %res = icmp sle i32 %sub, 0
486 %iv = phi i1 [ true, %begin ], [ %res, %bb ]
490 define i1 @test18(i32 %a, i32 %b) {
491 ; CHECK-LABEL: @test18(
493 ; CHECK-NEXT: [[CMP0:%.*]] = icmp sle i32 [[A:%.*]], 0
494 ; CHECK-NEXT: [[CMP1:%.*]] = icmp sge i32 [[B:%.*]], 0
495 ; CHECK-NEXT: [[BR:%.*]] = and i1 [[CMP0]], [[CMP1]]
496 ; CHECK-NEXT: br i1 [[BR]], label [[BB:%.*]], label [[EXIT:%.*]]
498 ; CHECK-NEXT: [[SUB:%.*]] = sub nuw i32 [[A]], [[B]]
499 ; CHECK-NEXT: [[RES:%.*]] = icmp sle i32 [[SUB]], 0
500 ; CHECK-NEXT: br label [[EXIT]]
502 ; CHECK-NEXT: [[IV:%.*]] = phi i1 [ true, [[BEGIN:%.*]] ], [ [[RES]], [[BB]] ]
503 ; CHECK-NEXT: ret i1 [[IV]]
506 %cmp0 = icmp sle i32 %a, 0
507 %cmp1 = icmp sge i32 %b, 0
508 %br = and i1 %cmp0, %cmp1
509 br i1 %br, label %bb, label %exit
512 %sub = sub nuw i32 %a, %b
513 %res = icmp sle i32 %sub, 0
517 %iv = phi i1 [ true, %begin ], [ %res, %bb ]
521 define i1 @test19(i32 %a, i32 %b) {
522 ; CHECK-LABEL: @test19(
524 ; CHECK-NEXT: [[CMP0:%.*]] = icmp sle i32 [[A:%.*]], 0
525 ; CHECK-NEXT: [[CMP1:%.*]] = icmp sge i32 [[B:%.*]], 0
526 ; CHECK-NEXT: [[BR:%.*]] = and i1 [[CMP0]], [[CMP1]]
527 ; CHECK-NEXT: br i1 [[BR]], label [[BB:%.*]], label [[EXIT:%.*]]
529 ; CHECK-NEXT: [[SUB:%.*]] = sub nsw i32 [[A]], [[B]]
530 ; CHECK-NEXT: br label [[EXIT]]
532 ; CHECK-NEXT: ret i1 true
535 %cmp0 = icmp sle i32 %a, 0
536 %cmp1 = icmp sge i32 %b, 0
537 %br = and i1 %cmp0, %cmp1
538 br i1 %br, label %bb, label %exit
541 %sub = sub nsw i32 %a, %b
542 %res = icmp sle i32 %sub, 0
546 %iv = phi i1 [ true, %begin ], [ %res, %bb ]
550 define i1 @test_br_cmp_with_offset(i64 %idx) {
551 ; CHECK-LABEL: @test_br_cmp_with_offset(
552 ; CHECK-NEXT: [[IDX_OFF1:%.*]] = add i64 [[IDX:%.*]], -5
553 ; CHECK-NEXT: [[CMP1:%.*]] = icmp ult i64 [[IDX_OFF1]], 3
554 ; CHECK-NEXT: br i1 [[CMP1]], label [[IF_TRUE:%.*]], label [[IF_FALSE:%.*]]
556 ; CHECK-NEXT: [[IDX_OFF2:%.*]] = add nsw i64 [[IDX]], -1
557 ; CHECK-NEXT: ret i1 true
559 ; CHECK-NEXT: ret i1 undef
561 %idx.off1 = add i64 %idx, -5
562 %cmp1 = icmp ult i64 %idx.off1, 3
563 br i1 %cmp1, label %if.true, label %if.false
566 %idx.off2 = add i64 %idx, -1
567 %cmp2 = icmp ult i64 %idx.off2, 10
574 define i1 @test_assume_cmp_with_offset(i64 %idx) {
575 ; CHECK-LABEL: @test_assume_cmp_with_offset(
576 ; CHECK-NEXT: [[IDX_OFF1:%.*]] = add i64 [[IDX:%.*]], -5
577 ; CHECK-NEXT: [[CMP1:%.*]] = icmp ult i64 [[IDX_OFF1]], 3
578 ; CHECK-NEXT: tail call void @llvm.assume(i1 [[CMP1]])
579 ; CHECK-NEXT: [[IDX_OFF2:%.*]] = add nsw i64 [[IDX]], -1
580 ; CHECK-NEXT: ret i1 true
582 %idx.off1 = add i64 %idx, -5
583 %cmp1 = icmp ult i64 %idx.off1, 3
584 tail call void @llvm.assume(i1 %cmp1)
585 %idx.off2 = add i64 %idx, -1
586 %cmp2 = icmp ult i64 %idx.off2, 10
590 define void @test_cmp_phi(i8 %a) {
591 ; CHECK-LABEL: @test_cmp_phi(
593 ; CHECK-NEXT: [[C0:%.*]] = icmp ult i8 [[A:%.*]], 2
594 ; CHECK-NEXT: br i1 [[C0]], label [[LOOP:%.*]], label [[EXIT:%.*]]
596 ; CHECK-NEXT: [[P:%.*]] = phi i8 [ [[A]], [[ENTRY:%.*]] ], [ [[B:%.*]], [[LOOP]] ]
597 ; CHECK-NEXT: [[C1:%.*]] = icmp ne i8 [[P]], 0
598 ; CHECK-NEXT: [[C4:%.*]] = call i1 @get_bool()
599 ; CHECK-NEXT: [[B]] = zext i1 [[C4]] to i8
600 ; CHECK-NEXT: br i1 [[C1]], label [[LOOP]], label [[EXIT]]
602 ; CHECK-NEXT: ret void
605 %c0 = icmp ult i8 %a, 2
606 br i1 %c0, label %loop, label %exit
609 %p = phi i8 [ %a, %entry ], [ %b, %loop ]
610 %c1 = icmp ne i8 %p, 0
611 %c2 = icmp ne i8 %p, 2
612 %c3 = and i1 %c1, %c2
613 %c4 = call i1 @get_bool()
614 %b = zext i1 %c4 to i8
615 br i1 %c3, label %loop, label %exit
621 declare i1 @get_bool()
623 define void @test_icmp_or_ult(i32 %a, i32 %b) {
624 ; CHECK-LABEL: @test_icmp_or_ult(
626 ; CHECK-NEXT: [[OR:%.*]] = or i32 [[A:%.*]], [[B:%.*]]
627 ; CHECK-NEXT: [[CMP:%.*]] = icmp ult i32 [[OR]], 42
628 ; CHECK-NEXT: br i1 [[CMP]], label [[IF_TRUE:%.*]], label [[IF_FALSE:%.*]]
630 ; CHECK-NEXT: call void @check1(i1 true)
631 ; CHECK-NEXT: call void @check1(i1 true)
632 ; CHECK-NEXT: ret void
634 ; CHECK-NEXT: [[CMP4:%.*]] = icmp uge i32 [[A]], 42
635 ; CHECK-NEXT: call void @check1(i1 [[CMP4]])
636 ; CHECK-NEXT: [[CMP5:%.*]] = icmp uge i32 [[B]], 42
637 ; CHECK-NEXT: call void @check1(i1 [[CMP5]])
638 ; CHECK-NEXT: ret void
642 %cmp = icmp ult i32 %or, 42
643 br i1 %cmp, label %if.true, label %if.false
646 %cmp2 = icmp ult i32 %a, 42
647 call void @check1(i1 %cmp2)
648 %cmp3 = icmp ult i32 %b, 42
649 call void @check1(i1 %cmp3)
653 %cmp4 = icmp uge i32 %a, 42
654 call void @check1(i1 %cmp4)
655 %cmp5 = icmp uge i32 %b, 42
656 call void @check1(i1 %cmp5)
660 define void @test_icmp_or_ule(i32 %a, i32 %b) {
661 ; CHECK-LABEL: @test_icmp_or_ule(
663 ; CHECK-NEXT: [[OR:%.*]] = or i32 [[A:%.*]], [[B:%.*]]
664 ; CHECK-NEXT: [[CMP:%.*]] = icmp ule i32 [[OR]], 42
665 ; CHECK-NEXT: br i1 [[CMP]], label [[IF_TRUE:%.*]], label [[IF_FALSE:%.*]]
667 ; CHECK-NEXT: call void @check1(i1 true)
668 ; CHECK-NEXT: call void @check1(i1 true)
669 ; CHECK-NEXT: ret void
671 ; CHECK-NEXT: [[CMP4:%.*]] = icmp ugt i32 [[A]], 42
672 ; CHECK-NEXT: call void @check1(i1 [[CMP4]])
673 ; CHECK-NEXT: [[CMP5:%.*]] = icmp ugt i32 [[B]], 42
674 ; CHECK-NEXT: call void @check1(i1 [[CMP5]])
675 ; CHECK-NEXT: ret void
679 %cmp = icmp ule i32 %or, 42
680 br i1 %cmp, label %if.true, label %if.false
683 %cmp2 = icmp ule i32 %a, 42
684 call void @check1(i1 %cmp2)
685 %cmp3 = icmp ule i32 %b, 42
686 call void @check1(i1 %cmp3)
690 %cmp4 = icmp ugt i32 %a, 42
691 call void @check1(i1 %cmp4)
692 %cmp5 = icmp ugt i32 %b, 42
693 call void @check1(i1 %cmp5)
697 define void @test_icmp_or_ugt(i32 %a, i32 %b) {
698 ; CHECK-LABEL: @test_icmp_or_ugt(
700 ; CHECK-NEXT: [[OR:%.*]] = or i32 [[A:%.*]], [[B:%.*]]
701 ; CHECK-NEXT: [[CMP:%.*]] = icmp ugt i32 [[OR]], 42
702 ; CHECK-NEXT: br i1 [[CMP]], label [[IF_TRUE:%.*]], label [[IF_FALSE:%.*]]
704 ; CHECK-NEXT: [[CMP2:%.*]] = icmp ugt i32 [[A]], 42
705 ; CHECK-NEXT: call void @check1(i1 [[CMP2]])
706 ; CHECK-NEXT: [[CMP3:%.*]] = icmp ugt i32 [[B]], 42
707 ; CHECK-NEXT: call void @check1(i1 [[CMP3]])
708 ; CHECK-NEXT: ret void
710 ; CHECK-NEXT: call void @check1(i1 true)
711 ; CHECK-NEXT: call void @check1(i1 true)
712 ; CHECK-NEXT: ret void
716 %cmp = icmp ugt i32 %or, 42
717 br i1 %cmp, label %if.true, label %if.false
720 %cmp2 = icmp ugt i32 %a, 42
721 call void @check1(i1 %cmp2)
722 %cmp3 = icmp ugt i32 %b, 42
723 call void @check1(i1 %cmp3)
727 %cmp4 = icmp ule i32 %a, 42
728 call void @check1(i1 %cmp4)
729 %cmp5 = icmp ule i32 %b, 42
730 call void @check1(i1 %cmp5)
734 define void @test_icmp_or_uge(i32 %a, i32 %b) {
735 ; CHECK-LABEL: @test_icmp_or_uge(
737 ; CHECK-NEXT: [[OR:%.*]] = or i32 [[A:%.*]], [[B:%.*]]
738 ; CHECK-NEXT: [[CMP:%.*]] = icmp uge i32 [[OR]], 42
739 ; CHECK-NEXT: br i1 [[CMP]], label [[IF_TRUE:%.*]], label [[IF_FALSE:%.*]]
741 ; CHECK-NEXT: [[CMP2:%.*]] = icmp uge i32 [[A]], 42
742 ; CHECK-NEXT: call void @check1(i1 [[CMP2]])
743 ; CHECK-NEXT: [[CMP3:%.*]] = icmp uge i32 [[B]], 42
744 ; CHECK-NEXT: call void @check1(i1 [[CMP3]])
745 ; CHECK-NEXT: ret void
747 ; CHECK-NEXT: call void @check1(i1 true)
748 ; CHECK-NEXT: call void @check1(i1 true)
749 ; CHECK-NEXT: ret void
753 %cmp = icmp uge i32 %or, 42
754 br i1 %cmp, label %if.true, label %if.false
757 %cmp2 = icmp uge i32 %a, 42
758 call void @check1(i1 %cmp2)
759 %cmp3 = icmp uge i32 %b, 42
760 call void @check1(i1 %cmp3)
764 %cmp4 = icmp ult i32 %a, 42
765 call void @check1(i1 %cmp4)
766 %cmp5 = icmp ult i32 %b, 42
767 call void @check1(i1 %cmp5)
771 define void @test_icmp_or_slt(i32 %a, i32 %b) {
772 ; CHECK-LABEL: @test_icmp_or_slt(
774 ; CHECK-NEXT: [[OR:%.*]] = or i32 [[A:%.*]], [[B:%.*]]
775 ; CHECK-NEXT: [[CMP:%.*]] = icmp slt i32 [[OR]], 42
776 ; CHECK-NEXT: br i1 [[CMP]], label [[IF_TRUE:%.*]], label [[IF_FALSE:%.*]]
778 ; CHECK-NEXT: [[CMP2:%.*]] = icmp slt i32 [[A]], 42
779 ; CHECK-NEXT: call void @check1(i1 [[CMP2]])
780 ; CHECK-NEXT: [[CMP3:%.*]] = icmp slt i32 [[B]], 42
781 ; CHECK-NEXT: call void @check1(i1 [[CMP3]])
782 ; CHECK-NEXT: ret void
784 ; CHECK-NEXT: [[CMP4:%.*]] = icmp sge i32 [[A]], 42
785 ; CHECK-NEXT: call void @check1(i1 [[CMP4]])
786 ; CHECK-NEXT: [[CMP5:%.*]] = icmp sge i32 [[B]], 42
787 ; CHECK-NEXT: call void @check1(i1 [[CMP5]])
788 ; CHECK-NEXT: ret void
792 %cmp = icmp slt i32 %or, 42
793 br i1 %cmp, label %if.true, label %if.false
796 %cmp2 = icmp slt i32 %a, 42
797 call void @check1(i1 %cmp2)
798 %cmp3 = icmp slt i32 %b, 42
799 call void @check1(i1 %cmp3)
803 %cmp4 = icmp sge i32 %a, 42
804 call void @check1(i1 %cmp4)
805 %cmp5 = icmp sge i32 %b, 42
806 call void @check1(i1 %cmp5)
810 define void @test_icmp_and_ugt(i32 %a, i32 %b) {
811 ; CHECK-LABEL: @test_icmp_and_ugt(
813 ; CHECK-NEXT: [[AND:%.*]] = and i32 [[A:%.*]], [[B:%.*]]
814 ; CHECK-NEXT: [[CMP:%.*]] = icmp ugt i32 [[AND]], 42
815 ; CHECK-NEXT: br i1 [[CMP]], label [[IF_TRUE:%.*]], label [[IF_FALSE:%.*]]
817 ; CHECK-NEXT: call void @check1(i1 true)
818 ; CHECK-NEXT: call void @check1(i1 true)
819 ; CHECK-NEXT: ret void
821 ; CHECK-NEXT: [[CMP4:%.*]] = icmp ule i32 [[A]], 42
822 ; CHECK-NEXT: call void @check1(i1 [[CMP4]])
823 ; CHECK-NEXT: [[CMP5:%.*]] = icmp ule i32 [[B]], 42
824 ; CHECK-NEXT: call void @check1(i1 [[CMP5]])
825 ; CHECK-NEXT: ret void
828 %and = and i32 %a, %b
829 %cmp = icmp ugt i32 %and, 42
830 br i1 %cmp, label %if.true, label %if.false
833 %cmp2 = icmp ugt i32 %a, 42
834 call void @check1(i1 %cmp2)
835 %cmp3 = icmp ugt i32 %b, 42
836 call void @check1(i1 %cmp3)
840 %cmp4 = icmp ule i32 %a, 42
841 call void @check1(i1 %cmp4)
842 %cmp5 = icmp ule i32 %b, 42
843 call void @check1(i1 %cmp5)
847 define void @test_icmp_and_uge(i32 %a, i32 %b) {
848 ; CHECK-LABEL: @test_icmp_and_uge(
850 ; CHECK-NEXT: [[AND:%.*]] = and i32 [[A:%.*]], [[B:%.*]]
851 ; CHECK-NEXT: [[CMP:%.*]] = icmp uge i32 [[AND]], 42
852 ; CHECK-NEXT: br i1 [[CMP]], label [[IF_TRUE:%.*]], label [[IF_FALSE:%.*]]
854 ; CHECK-NEXT: call void @check1(i1 true)
855 ; CHECK-NEXT: call void @check1(i1 true)
856 ; CHECK-NEXT: ret void
858 ; CHECK-NEXT: [[CMP4:%.*]] = icmp ult i32 [[A]], 42
859 ; CHECK-NEXT: call void @check1(i1 [[CMP4]])
860 ; CHECK-NEXT: [[CMP5:%.*]] = icmp ult i32 [[B]], 42
861 ; CHECK-NEXT: call void @check1(i1 [[CMP5]])
862 ; CHECK-NEXT: ret void
865 %and = and i32 %a, %b
866 %cmp = icmp uge i32 %and, 42
867 br i1 %cmp, label %if.true, label %if.false
870 %cmp2 = icmp uge i32 %a, 42
871 call void @check1(i1 %cmp2)
872 %cmp3 = icmp uge i32 %b, 42
873 call void @check1(i1 %cmp3)
877 %cmp4 = icmp ult i32 %a, 42
878 call void @check1(i1 %cmp4)
879 %cmp5 = icmp ult i32 %b, 42
880 call void @check1(i1 %cmp5)
884 define void @test_icmp_and_ult(i32 %a, i32 %b) {
885 ; CHECK-LABEL: @test_icmp_and_ult(
887 ; CHECK-NEXT: [[AND:%.*]] = and i32 [[A:%.*]], [[B:%.*]]
888 ; CHECK-NEXT: [[CMP:%.*]] = icmp ult i32 [[AND]], 42
889 ; CHECK-NEXT: br i1 [[CMP]], label [[IF_TRUE:%.*]], label [[IF_FALSE:%.*]]
891 ; CHECK-NEXT: [[CMP2:%.*]] = icmp ult i32 [[A]], 42
892 ; CHECK-NEXT: call void @check1(i1 [[CMP2]])
893 ; CHECK-NEXT: [[CMP3:%.*]] = icmp ult i32 [[B]], 42
894 ; CHECK-NEXT: call void @check1(i1 [[CMP3]])
895 ; CHECK-NEXT: ret void
897 ; CHECK-NEXT: call void @check1(i1 true)
898 ; CHECK-NEXT: call void @check1(i1 true)
899 ; CHECK-NEXT: ret void
902 %and = and i32 %a, %b
903 %cmp = icmp ult i32 %and, 42
904 br i1 %cmp, label %if.true, label %if.false
907 %cmp2 = icmp ult i32 %a, 42
908 call void @check1(i1 %cmp2)
909 %cmp3 = icmp ult i32 %b, 42
910 call void @check1(i1 %cmp3)
914 %cmp4 = icmp uge i32 %a, 42
915 call void @check1(i1 %cmp4)
916 %cmp5 = icmp uge i32 %b, 42
917 call void @check1(i1 %cmp5)
921 define void @test_icmp_and_sgt(i32 %a, i32 %b) {
922 ; CHECK-LABEL: @test_icmp_and_sgt(
924 ; CHECK-NEXT: [[AND:%.*]] = and i32 [[A:%.*]], [[B:%.*]]
925 ; CHECK-NEXT: [[CMP:%.*]] = icmp sgt i32 [[AND]], 42
926 ; CHECK-NEXT: br i1 [[CMP]], label [[IF_TRUE:%.*]], label [[IF_FALSE:%.*]]
928 ; CHECK-NEXT: [[CMP2:%.*]] = icmp sgt i32 [[A]], 42
929 ; CHECK-NEXT: call void @check1(i1 [[CMP2]])
930 ; CHECK-NEXT: [[CMP3:%.*]] = icmp sgt i32 [[B]], 42
931 ; CHECK-NEXT: call void @check1(i1 [[CMP3]])
932 ; CHECK-NEXT: ret void
934 ; CHECK-NEXT: [[CMP4:%.*]] = icmp sle i32 [[A]], 42
935 ; CHECK-NEXT: call void @check1(i1 [[CMP4]])
936 ; CHECK-NEXT: [[CMP5:%.*]] = icmp sle i32 [[B]], 42
937 ; CHECK-NEXT: call void @check1(i1 [[CMP5]])
938 ; CHECK-NEXT: ret void
941 %and = and i32 %a, %b
942 %cmp = icmp sgt i32 %and, 42
943 br i1 %cmp, label %if.true, label %if.false
946 %cmp2 = icmp sgt i32 %a, 42
947 call void @check1(i1 %cmp2)
948 %cmp3 = icmp sgt i32 %b, 42
949 call void @check1(i1 %cmp3)
953 %cmp4 = icmp sle i32 %a, 42
954 call void @check1(i1 %cmp4)
955 %cmp5 = icmp sle i32 %b, 42
956 call void @check1(i1 %cmp5)
960 define void @test_icmp_mask_eq_two_values(i32 %a) {
961 ; CHECK-LABEL: @test_icmp_mask_eq_two_values(
962 ; CHECK-NEXT: [[AND:%.*]] = and i32 [[A:%.*]], -2
963 ; CHECK-NEXT: [[CMP:%.*]] = icmp eq i32 [[AND]], 10
964 ; CHECK-NEXT: br i1 [[CMP]], label [[IF_TRUE:%.*]], label [[IF_FALSE:%.*]]
966 ; CHECK-NEXT: call void @check1(i1 true)
967 ; CHECK-NEXT: call void @check1(i1 true)
968 ; CHECK-NEXT: call void @check1(i1 false)
969 ; CHECK-NEXT: call void @check1(i1 false)
970 ; CHECK-NEXT: ret void
972 ; CHECK-NEXT: ret void
974 %and = and i32 %a, -2
975 %cmp = icmp eq i32 %and, 10
976 br i1 %cmp, label %if.true, label %if.false
979 %cmp2 = icmp uge i32 %a, 10
980 call void @check1(i1 %cmp2)
981 %cmp3 = icmp ule i32 %a, 11
982 call void @check1(i1 %cmp3)
983 %cmp4 = icmp ult i32 %a, 10
984 call void @check1(i1 %cmp4)
985 %cmp5 = icmp ugt i32 %a, 11
986 call void @check1(i1 %cmp5)
993 define void @test_icmp_mask_eq_bit_set(i32 %a) {
994 ; CHECK-LABEL: @test_icmp_mask_eq_bit_set(
995 ; CHECK-NEXT: [[AND:%.*]] = and i32 [[A:%.*]], 32
996 ; CHECK-NEXT: [[CMP:%.*]] = icmp eq i32 [[AND]], 32
997 ; CHECK-NEXT: br i1 [[CMP]], label [[IF_TRUE:%.*]], label [[IF_FALSE:%.*]]
999 ; CHECK-NEXT: call void @check1(i1 true)
1000 ; CHECK-NEXT: [[CMP3:%.*]] = icmp uge i32 [[A]], 33
1001 ; CHECK-NEXT: call void @check1(i1 [[CMP3]])
1002 ; CHECK-NEXT: ret void
1004 ; CHECK-NEXT: ret void
1006 %and = and i32 %a, 32
1007 %cmp = icmp eq i32 %and, 32
1008 br i1 %cmp, label %if.true, label %if.false
1011 %cmp2 = icmp uge i32 %a, 32
1012 call void @check1(i1 %cmp2)
1013 %cmp3 = icmp uge i32 %a, 33
1014 call void @check1(i1 %cmp3)
1021 define void @test_icmp_mask_eq_bit_unset(i32 %a) {
1022 ; CHECK-LABEL: @test_icmp_mask_eq_bit_unset(
1023 ; CHECK-NEXT: [[AND:%.*]] = and i32 [[A:%.*]], 32
1024 ; CHECK-NEXT: [[CMP:%.*]] = icmp eq i32 [[AND]], 0
1025 ; CHECK-NEXT: br i1 [[CMP]], label [[IF_TRUE:%.*]], label [[IF_FALSE:%.*]]
1027 ; CHECK-NEXT: call void @check1(i1 true)
1028 ; CHECK-NEXT: [[CMP3:%.*]] = icmp ule i32 [[A]], -34
1029 ; CHECK-NEXT: call void @check1(i1 [[CMP3]])
1030 ; CHECK-NEXT: ret void
1032 ; CHECK-NEXT: ret void
1034 %and = and i32 %a, 32
1035 %cmp = icmp eq i32 %and, 0
1036 br i1 %cmp, label %if.true, label %if.false
1039 %cmp2 = icmp ule i32 %a, -33
1040 call void @check1(i1 %cmp2)
1041 %cmp3 = icmp ule i32 %a, -34
1042 call void @check1(i1 %cmp3)
1049 define void @test_icmp_mask_eq_wrong_predicate(i32 %a) {
1050 ; CHECK-LABEL: @test_icmp_mask_eq_wrong_predicate(
1051 ; CHECK-NEXT: [[AND:%.*]] = and i32 [[A:%.*]], -2
1052 ; CHECK-NEXT: [[CMP:%.*]] = icmp ne i32 [[AND]], 10
1053 ; CHECK-NEXT: br i1 [[CMP]], label [[IF_TRUE:%.*]], label [[IF_FALSE:%.*]]
1055 ; CHECK-NEXT: [[CMP2:%.*]] = icmp uge i32 [[A]], 10
1056 ; CHECK-NEXT: call void @check1(i1 [[CMP2]])
1057 ; CHECK-NEXT: [[CMP3:%.*]] = icmp ule i32 [[A]], 11
1058 ; CHECK-NEXT: call void @check1(i1 [[CMP3]])
1059 ; CHECK-NEXT: [[CMP4:%.*]] = icmp ult i32 [[A]], 10
1060 ; CHECK-NEXT: call void @check1(i1 [[CMP4]])
1061 ; CHECK-NEXT: [[CMP5:%.*]] = icmp ugt i32 [[A]], 11
1062 ; CHECK-NEXT: call void @check1(i1 [[CMP5]])
1063 ; CHECK-NEXT: ret void
1065 ; CHECK-NEXT: ret void
1067 %and = and i32 %a, -2
1068 %cmp = icmp ne i32 %and, 10
1069 br i1 %cmp, label %if.true, label %if.false
1072 %cmp2 = icmp uge i32 %a, 10
1073 call void @check1(i1 %cmp2)
1074 %cmp3 = icmp ule i32 %a, 11
1075 call void @check1(i1 %cmp3)
1076 %cmp4 = icmp ult i32 %a, 10
1077 call void @check1(i1 %cmp4)
1078 %cmp5 = icmp ugt i32 %a, 11
1079 call void @check1(i1 %cmp5)
1086 define void @test_icmp_mask_ne(i32 %a) {
1087 ; CHECK-LABEL: @test_icmp_mask_ne(
1088 ; CHECK-NEXT: [[AND:%.*]] = and i32 [[A:%.*]], 6
1089 ; CHECK-NEXT: [[CMP:%.*]] = icmp ne i32 [[AND]], 0
1090 ; CHECK-NEXT: br i1 [[CMP]], label [[IF_TRUE:%.*]], label [[IF_FALSE:%.*]]
1092 ; CHECK-NEXT: call void @check1(i1 true)
1093 ; CHECK-NEXT: [[CMP3:%.*]] = icmp ugt i32 [[A]], 2
1094 ; CHECK-NEXT: call void @check1(i1 [[CMP3]])
1095 ; CHECK-NEXT: [[CMP4:%.*]] = icmp ult i32 [[A]], -1
1096 ; CHECK-NEXT: call void @check1(i1 [[CMP4]])
1097 ; CHECK-NEXT: ret void
1099 ; CHECK-NEXT: ret void
1101 %and = and i32 %a, 6
1102 %cmp = icmp ne i32 %and, 0
1103 br i1 %cmp, label %if.true, label %if.false
1106 %cmp2 = icmp uge i32 %a, 2
1107 call void @check1(i1 %cmp2)
1108 %cmp3 = icmp ugt i32 %a, 2
1109 call void @check1(i1 %cmp3)
1110 %cmp4 = icmp ult i32 %a, -1
1111 call void @check1(i1 %cmp4)
1118 define void @test_icmp_mask_ne_nonzero_cmp(i32 %a) {
1119 ; CHECK-LABEL: @test_icmp_mask_ne_nonzero_cmp(
1120 ; CHECK-NEXT: [[AND:%.*]] = and i32 [[A:%.*]], 6
1121 ; CHECK-NEXT: [[CMP:%.*]] = icmp ne i32 [[AND]], 6
1122 ; CHECK-NEXT: br i1 [[CMP]], label [[IF_TRUE:%.*]], label [[IF_FALSE:%.*]]
1124 ; CHECK-NEXT: [[CMP2:%.*]] = icmp uge i32 [[A]], 2
1125 ; CHECK-NEXT: call void @check1(i1 [[CMP2]])
1126 ; CHECK-NEXT: [[CMP3:%.*]] = icmp ugt i32 [[A]], 2
1127 ; CHECK-NEXT: call void @check1(i1 [[CMP3]])
1128 ; CHECK-NEXT: [[CMP4:%.*]] = icmp ult i32 [[A]], -1
1129 ; CHECK-NEXT: call void @check1(i1 [[CMP4]])
1130 ; CHECK-NEXT: ret void
1132 ; CHECK-NEXT: ret void
1134 %and = and i32 %a, 6
1135 %cmp = icmp ne i32 %and, 6
1136 br i1 %cmp, label %if.true, label %if.false
1139 %cmp2 = icmp uge i32 %a, 2
1140 call void @check1(i1 %cmp2)
1141 %cmp3 = icmp ugt i32 %a, 2
1142 call void @check1(i1 %cmp3)
1143 %cmp4 = icmp ult i32 %a, -1
1144 call void @check1(i1 %cmp4)
1151 define void @test_icmp_mask_ne_zero_mask(i32 %a) {
1152 ; CHECK-LABEL: @test_icmp_mask_ne_zero_mask(
1153 ; CHECK-NEXT: [[AND:%.*]] = and i32 [[A:%.*]], 0
1154 ; CHECK-NEXT: br i1 false, label [[IF_TRUE:%.*]], label [[IF_FALSE:%.*]]
1156 ; CHECK-NEXT: [[CMP2:%.*]] = icmp ne i32 [[A]], 0
1157 ; CHECK-NEXT: call void @check1(i1 [[CMP2]])
1158 ; CHECK-NEXT: ret void
1160 ; CHECK-NEXT: ret void
1162 %and = and i32 %a, 0
1163 %cmp = icmp ne i32 %and, 0
1164 br i1 %cmp, label %if.true, label %if.false
1167 %cmp2 = icmp ne i32 %a, 0
1168 call void @check1(i1 %cmp2)
1175 define void @non_const_range(i32 %a, i32 %b) {
1176 ; CHECK-LABEL: @non_const_range(
1177 ; CHECK-NEXT: [[CMP1:%.*]] = icmp ult i32 [[A:%.*]], 11
1178 ; CHECK-NEXT: [[CMP2:%.*]] = icmp ult i32 [[B:%.*]], 21
1179 ; CHECK-NEXT: [[AND:%.*]] = select i1 [[CMP1]], i1 [[CMP2]], i1 false
1180 ; CHECK-NEXT: br i1 [[AND]], label [[IF:%.*]], label [[ELSE:%.*]]
1182 ; CHECK-NEXT: [[A_100:%.*]] = add nuw nsw i32 [[A]], 100
1183 ; CHECK-NEXT: call void @check1(i1 true)
1184 ; CHECK-NEXT: call void @check1(i1 false)
1185 ; CHECK-NEXT: [[A_10:%.*]] = add nuw nsw i32 [[A]], 10
1186 ; CHECK-NEXT: [[CMP5:%.*]] = icmp ne i32 [[A_10]], [[B]]
1187 ; CHECK-NEXT: call void @check1(i1 [[CMP5]])
1188 ; CHECK-NEXT: [[CMP6:%.*]] = icmp eq i32 [[A_10]], [[B]]
1189 ; CHECK-NEXT: call void @check1(i1 [[CMP6]])
1190 ; CHECK-NEXT: ret void
1192 ; CHECK-NEXT: ret void
1194 %cmp1 = icmp ult i32 %a, 11
1195 %cmp2 = icmp ult i32 %b, 21
1196 %and = select i1 %cmp1, i1 %cmp2, i1 false
1197 br i1 %and, label %if, label %else
1200 %a.100 = add nuw nsw i32 %a, 100
1201 %cmp3 = icmp ne i32 %a.100, %b
1202 call void @check1(i1 %cmp3)
1203 %cmp4 = icmp eq i32 %a.100, %b
1204 call void @check1(i1 %cmp4)
1206 %a.10 = add nuw nsw i32 %a, 10
1207 %cmp5 = icmp ne i32 %a.10, %b
1208 call void @check1(i1 %cmp5)
1209 %cmp6 = icmp eq i32 %a.10, %b
1210 call void @check1(i1 %cmp6)
1217 define i1 @non_const_range_minmax(i8 %a, i8 %b) {
1218 ; CHECK-LABEL: @non_const_range_minmax(
1219 ; CHECK-NEXT: [[A2:%.*]] = call i8 @llvm.umin.i8(i8 [[A:%.*]], i8 10)
1220 ; CHECK-NEXT: [[B2:%.*]] = call i8 @llvm.umax.i8(i8 [[B:%.*]], i8 11)
1221 ; CHECK-NEXT: ret i1 true
1223 %a2 = call i8 @llvm.umin.i8(i8 %a, i8 10)
1224 %b2 = call i8 @llvm.umax.i8(i8 %b, i8 11)
1225 %cmp1 = icmp ult i8 %a2, %b2
1229 ; FIXME: Also support vectors.
1230 define <2 x i1> @non_const_range_minmax_vec(<2 x i8> %a, <2 x i8> %b) {
1231 ; CHECK-LABEL: @non_const_range_minmax_vec(
1232 ; CHECK-NEXT: [[A2:%.*]] = call <2 x i8> @llvm.umin.v2i8(<2 x i8> [[A:%.*]], <2 x i8> <i8 10, i8 10>)
1233 ; CHECK-NEXT: [[B2:%.*]] = call <2 x i8> @llvm.umax.v2i8(<2 x i8> [[B:%.*]], <2 x i8> <i8 11, i8 11>)
1234 ; CHECK-NEXT: [[CMP1:%.*]] = icmp ult <2 x i8> [[A2]], [[B2]]
1235 ; CHECK-NEXT: ret <2 x i1> [[CMP1]]
1237 %a2 = call <2 x i8> @llvm.umin.v2i8(<2 x i8> %a, <2 x i8> <i8 10, i8 10>)
1238 %b2 = call <2 x i8> @llvm.umax.v2i8(<2 x i8> %b, <2 x i8> <i8 11, i8 11>)
1239 %cmp1 = icmp ult <2 x i8> %a2, %b2
1243 define void @ashr_sgt(i8 %x) {
1244 ; CHECK-LABEL: @ashr_sgt(
1245 ; CHECK-NEXT: [[S:%.*]] = ashr i8 [[X:%.*]], 2
1246 ; CHECK-NEXT: [[C:%.*]] = icmp sgt i8 [[S]], 1
1247 ; CHECK-NEXT: br i1 [[C]], label [[IF:%.*]], label [[ELSE:%.*]]
1249 ; CHECK-NEXT: call void @check1(i1 true)
1250 ; CHECK-NEXT: [[C3:%.*]] = icmp ugt i8 [[X]], 8
1251 ; CHECK-NEXT: call void @check1(i1 [[C3]])
1252 ; CHECK-NEXT: ret void
1254 ; CHECK-NEXT: ret void
1257 %c = icmp sgt i8 %s, 1
1258 br i1 %c, label %if, label %else
1260 %c2 = icmp sgt i8 %x, 7
1261 call void @check1(i1 %c2)
1262 %c3 = icmp sgt i8 %x, 8
1263 call void @check1(i1 %c3)
1269 define void @ashr_sge(i8 %x) {
1270 ; CHECK-LABEL: @ashr_sge(
1271 ; CHECK-NEXT: [[S:%.*]] = ashr i8 [[X:%.*]], 2
1272 ; CHECK-NEXT: [[C:%.*]] = icmp sge i8 [[S]], 1
1273 ; CHECK-NEXT: br i1 [[C]], label [[IF:%.*]], label [[ELSE:%.*]]
1275 ; CHECK-NEXT: call void @check1(i1 true)
1276 ; CHECK-NEXT: [[C3:%.*]] = icmp uge i8 [[X]], 5
1277 ; CHECK-NEXT: call void @check1(i1 [[C3]])
1278 ; CHECK-NEXT: ret void
1280 ; CHECK-NEXT: ret void
1283 %c = icmp sge i8 %s, 1
1284 br i1 %c, label %if, label %else
1286 %c2 = icmp sge i8 %x, 4
1287 call void @check1(i1 %c2)
1288 %c3 = icmp sge i8 %x, 5
1289 call void @check1(i1 %c3)
1295 define void @ashr_slt(i8 %x) {
1296 ; CHECK-LABEL: @ashr_slt(
1297 ; CHECK-NEXT: [[S:%.*]] = ashr i8 [[X:%.*]], 2
1298 ; CHECK-NEXT: [[C:%.*]] = icmp slt i8 [[S]], 1
1299 ; CHECK-NEXT: br i1 [[C]], label [[IF:%.*]], label [[ELSE:%.*]]
1301 ; CHECK-NEXT: call void @check1(i1 true)
1302 ; CHECK-NEXT: [[C3:%.*]] = icmp slt i8 [[X]], 3
1303 ; CHECK-NEXT: call void @check1(i1 [[C3]])
1304 ; CHECK-NEXT: ret void
1306 ; CHECK-NEXT: ret void
1309 %c = icmp slt i8 %s, 1
1310 br i1 %c, label %if, label %else
1312 %c2 = icmp slt i8 %x, 4
1313 call void @check1(i1 %c2)
1314 %c3 = icmp slt i8 %x, 3
1315 call void @check1(i1 %c3)
1321 define void @ashr_sle(i8 %x) {
1322 ; CHECK-LABEL: @ashr_sle(
1323 ; CHECK-NEXT: [[S:%.*]] = ashr i8 [[X:%.*]], 2
1324 ; CHECK-NEXT: [[C:%.*]] = icmp sle i8 [[S]], 1
1325 ; CHECK-NEXT: br i1 [[C]], label [[IF:%.*]], label [[ELSE:%.*]]
1327 ; CHECK-NEXT: call void @check1(i1 true)
1328 ; CHECK-NEXT: [[C3:%.*]] = icmp sle i8 [[X]], 6
1329 ; CHECK-NEXT: call void @check1(i1 [[C3]])
1330 ; CHECK-NEXT: ret void
1332 ; CHECK-NEXT: ret void
1335 %c = icmp sle i8 %s, 1
1336 br i1 %c, label %if, label %else
1338 %c2 = icmp sle i8 %x, 7
1339 call void @check1(i1 %c2)
1340 %c3 = icmp sle i8 %x, 6
1341 call void @check1(i1 %c3)
1347 declare i8 @llvm.umin.i8(i8, i8)
1348 declare i8 @llvm.umax.i8(i8, i8)
1349 declare <2 x i8> @llvm.umin.v2i8(<2 x i8>, <2 x i8>)
1350 declare <2 x i8> @llvm.umax.v2i8(<2 x i8>, <2 x i8>)
1352 attributes #4 = { noreturn }
1354 define i1 @pr69928(i64 noundef %arg, i64 noundef %arg1) {
1355 ; CHECK-LABEL: @pr69928(
1356 ; CHECK-NEXT: entry:
1357 ; CHECK-NEXT: [[CMP1:%.*]] = icmp ult i64 [[ARG:%.*]], 64424509440
1358 ; CHECK-NEXT: [[AND:%.*]] = and i64 [[ARG1:%.*]], 4294967295
1359 ; CHECK-NEXT: [[CMP2:%.*]] = icmp ult i64 [[ARG]], [[AND]]
1360 ; CHECK-NEXT: [[SELECT:%.*]] = select i1 [[CMP1]], i1 [[CMP2]], i1 false
1361 ; CHECK-NEXT: ret i1 [[SELECT]]
1364 %cmp1 = icmp ult i64 %arg, 64424509440
1365 %and = and i64 %arg1, 4294967295
1366 %cmp2 = icmp slt i64 %arg, %and
1367 %select = select i1 %cmp1, i1 %cmp2, i1 false
1371 define i1 @test_select_flip(i64 noundef %arg) {
1372 ; CHECK-LABEL: @test_select_flip(
1373 ; CHECK-NEXT: entry:
1374 ; CHECK-NEXT: [[CMP1:%.*]] = icmp ult i64 [[ARG:%.*]], 1000
1375 ; CHECK-NEXT: [[CMP2:%.*]] = icmp ult i64 [[ARG]], 100
1376 ; CHECK-NEXT: [[SELECT:%.*]] = select i1 [[CMP1]], i1 [[CMP2]], i1 false
1377 ; CHECK-NEXT: ret i1 [[SELECT]]
1380 %cmp1 = icmp ult i64 %arg, 1000
1381 %cmp2 = icmp slt i64 %arg, 100
1382 %select = select i1 %cmp1, i1 %cmp2, i1 false
1386 define i1 @test_select_flip_fail1(i64 noundef %arg) {
1387 ; CHECK-LABEL: @test_select_flip_fail1(
1388 ; CHECK-NEXT: entry:
1389 ; CHECK-NEXT: [[CMP1:%.*]] = icmp slt i64 [[ARG:%.*]], 1000
1390 ; CHECK-NEXT: [[CMP2:%.*]] = icmp slt i64 [[ARG]], 100
1391 ; CHECK-NEXT: [[SELECT:%.*]] = select i1 [[CMP1]], i1 [[CMP2]], i1 false
1392 ; CHECK-NEXT: ret i1 [[SELECT]]
1395 %cmp1 = icmp slt i64 %arg, 1000
1396 %cmp2 = icmp slt i64 %arg, 100
1397 %select = select i1 %cmp1, i1 %cmp2, i1 false
1401 define i1 @test_select_flip_fail2(i64 noundef %arg) {
1402 ; CHECK-LABEL: @test_select_flip_fail2(
1403 ; CHECK-NEXT: entry:
1404 ; CHECK-NEXT: [[CMP1:%.*]] = icmp ult i64 [[ARG:%.*]], 1000
1405 ; CHECK-NEXT: [[CMP2:%.*]] = icmp slt i64 [[ARG]], 100
1406 ; CHECK-NEXT: [[SELECT:%.*]] = select i1 [[CMP1]], i1 false, i1 [[CMP2]]
1407 ; CHECK-NEXT: ret i1 [[SELECT]]
1410 %cmp1 = icmp ult i64 %arg, 1000
1411 %cmp2 = icmp slt i64 %arg, 100
1412 %select = select i1 %cmp1, i1 false, i1 %cmp2
1416 define i1 @test_select_flip_fail3(i64 noundef %arg, i64 noundef %arg1) {
1417 ; CHECK-LABEL: @test_select_flip_fail3(
1418 ; CHECK-NEXT: entry:
1419 ; CHECK-NEXT: [[CMP1:%.*]] = icmp ult i64 [[ARG1:%.*]], 1000
1420 ; CHECK-NEXT: [[CMP2:%.*]] = icmp slt i64 [[ARG:%.*]], 100
1421 ; CHECK-NEXT: [[SELECT:%.*]] = select i1 [[CMP1]], i1 [[CMP2]], i1 false
1422 ; CHECK-NEXT: ret i1 [[SELECT]]
1425 %cmp1 = icmp ult i64 %arg1, 1000
1426 %cmp2 = icmp slt i64 %arg, 100
1427 %select = select i1 %cmp1, i1 %cmp2, i1 false
1431 define i1 @test_select_flip_fail4(i64 noundef %arg) {
1432 ; CHECK-LABEL: @test_select_flip_fail4(
1433 ; CHECK-NEXT: entry:
1434 ; CHECK-NEXT: [[CMP2:%.*]] = icmp slt i64 [[ARG:%.*]], 100
1435 ; CHECK-NEXT: [[SELECT:%.*]] = select i1 true, i1 [[CMP2]], i1 false
1436 ; CHECK-NEXT: ret i1 [[SELECT]]
1439 %cmp2 = icmp slt i64 %arg, 100
1440 %select = select i1 true, i1 %cmp2, i1 false
1444 define i1 @test_select_flip_fail5(i64 noundef %arg, i64 noundef %arg1) {
1445 ; CHECK-LABEL: @test_select_flip_fail5(
1446 ; CHECK-NEXT: entry:
1447 ; CHECK-NEXT: [[CMP1:%.*]] = icmp ult i64 [[ARG:%.*]], 1000
1448 ; CHECK-NEXT: [[CMP2:%.*]] = icmp slt i64 [[ARG]], [[ARG1:%.*]]
1449 ; CHECK-NEXT: [[SELECT:%.*]] = select i1 [[CMP1]], i1 [[CMP2]], i1 false
1450 ; CHECK-NEXT: ret i1 [[SELECT]]
1453 %cmp1 = icmp ult i64 %arg, 1000
1454 %cmp2 = icmp slt i64 %arg, %arg1
1455 %select = select i1 %cmp1, i1 %cmp2, i1 false