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 i1 @test_assume_cmp_with_offset_or(i64 %idx, i1 %other) {
591 ; CHECK-LABEL: @test_assume_cmp_with_offset_or(
592 ; CHECK-NEXT: [[IDX_OFF1:%.*]] = or disjoint i64 [[IDX:%.*]], 5
593 ; CHECK-NEXT: [[CMP1:%.*]] = icmp ugt i64 [[IDX_OFF1]], 10
594 ; CHECK-NEXT: br i1 [[CMP1]], label [[T:%.*]], label [[F:%.*]]
596 ; CHECK-NEXT: ret i1 true
598 ; CHECK-NEXT: ret i1 [[OTHER:%.*]]
600 %idx.off1 = or disjoint i64 %idx, 5
601 %cmp1 = icmp ugt i64 %idx.off1, 10
602 br i1 %cmp1, label %T, label %F
604 %cmp2 = icmp ugt i64 %idx, 2
610 define void @test_cmp_phi(i8 %a) {
611 ; CHECK-LABEL: @test_cmp_phi(
613 ; CHECK-NEXT: [[C0:%.*]] = icmp ult i8 [[A:%.*]], 2
614 ; CHECK-NEXT: br i1 [[C0]], label [[LOOP:%.*]], label [[EXIT:%.*]]
616 ; CHECK-NEXT: [[P:%.*]] = phi i8 [ [[A]], [[ENTRY:%.*]] ], [ [[B:%.*]], [[LOOP]] ]
617 ; CHECK-NEXT: [[C1:%.*]] = icmp ne i8 [[P]], 0
618 ; CHECK-NEXT: [[C4:%.*]] = call i1 @get_bool()
619 ; CHECK-NEXT: [[B]] = zext i1 [[C4]] to i8
620 ; CHECK-NEXT: br i1 [[C1]], label [[LOOP]], label [[EXIT]]
622 ; CHECK-NEXT: ret void
625 %c0 = icmp ult i8 %a, 2
626 br i1 %c0, label %loop, label %exit
629 %p = phi i8 [ %a, %entry ], [ %b, %loop ]
630 %c1 = icmp ne i8 %p, 0
631 %c2 = icmp ne i8 %p, 2
632 %c3 = and i1 %c1, %c2
633 %c4 = call i1 @get_bool()
634 %b = zext i1 %c4 to i8
635 br i1 %c3, label %loop, label %exit
641 declare i1 @get_bool()
643 define void @test_icmp_or_ult(i32 %a, i32 %b) {
644 ; CHECK-LABEL: @test_icmp_or_ult(
646 ; CHECK-NEXT: [[OR:%.*]] = or i32 [[A:%.*]], [[B:%.*]]
647 ; CHECK-NEXT: [[CMP:%.*]] = icmp ult i32 [[OR]], 42
648 ; CHECK-NEXT: br i1 [[CMP]], label [[IF_TRUE:%.*]], label [[IF_FALSE:%.*]]
650 ; CHECK-NEXT: call void @check1(i1 true)
651 ; CHECK-NEXT: call void @check1(i1 true)
652 ; CHECK-NEXT: ret void
654 ; CHECK-NEXT: [[CMP4:%.*]] = icmp uge i32 [[A]], 42
655 ; CHECK-NEXT: call void @check1(i1 [[CMP4]])
656 ; CHECK-NEXT: [[CMP5:%.*]] = icmp uge i32 [[B]], 42
657 ; CHECK-NEXT: call void @check1(i1 [[CMP5]])
658 ; CHECK-NEXT: ret void
662 %cmp = icmp ult i32 %or, 42
663 br i1 %cmp, label %if.true, label %if.false
666 %cmp2 = icmp ult i32 %a, 42
667 call void @check1(i1 %cmp2)
668 %cmp3 = icmp ult i32 %b, 42
669 call void @check1(i1 %cmp3)
673 %cmp4 = icmp uge i32 %a, 42
674 call void @check1(i1 %cmp4)
675 %cmp5 = icmp uge i32 %b, 42
676 call void @check1(i1 %cmp5)
680 define void @test_icmp_or_ule(i32 %a, i32 %b) {
681 ; CHECK-LABEL: @test_icmp_or_ule(
683 ; CHECK-NEXT: [[OR:%.*]] = or i32 [[A:%.*]], [[B:%.*]]
684 ; CHECK-NEXT: [[CMP:%.*]] = icmp ule i32 [[OR]], 42
685 ; CHECK-NEXT: br i1 [[CMP]], label [[IF_TRUE:%.*]], label [[IF_FALSE:%.*]]
687 ; CHECK-NEXT: call void @check1(i1 true)
688 ; CHECK-NEXT: call void @check1(i1 true)
689 ; CHECK-NEXT: ret void
691 ; CHECK-NEXT: [[CMP4:%.*]] = icmp ugt i32 [[A]], 42
692 ; CHECK-NEXT: call void @check1(i1 [[CMP4]])
693 ; CHECK-NEXT: [[CMP5:%.*]] = icmp ugt i32 [[B]], 42
694 ; CHECK-NEXT: call void @check1(i1 [[CMP5]])
695 ; CHECK-NEXT: ret void
699 %cmp = icmp ule i32 %or, 42
700 br i1 %cmp, label %if.true, label %if.false
703 %cmp2 = icmp ule i32 %a, 42
704 call void @check1(i1 %cmp2)
705 %cmp3 = icmp ule i32 %b, 42
706 call void @check1(i1 %cmp3)
710 %cmp4 = icmp ugt i32 %a, 42
711 call void @check1(i1 %cmp4)
712 %cmp5 = icmp ugt i32 %b, 42
713 call void @check1(i1 %cmp5)
717 define void @test_icmp_or_ugt(i32 %a, i32 %b) {
718 ; CHECK-LABEL: @test_icmp_or_ugt(
720 ; CHECK-NEXT: [[OR:%.*]] = or i32 [[A:%.*]], [[B:%.*]]
721 ; CHECK-NEXT: [[CMP:%.*]] = icmp ugt i32 [[OR]], 42
722 ; CHECK-NEXT: br i1 [[CMP]], label [[IF_TRUE:%.*]], label [[IF_FALSE:%.*]]
724 ; CHECK-NEXT: [[CMP2:%.*]] = icmp ugt i32 [[A]], 42
725 ; CHECK-NEXT: call void @check1(i1 [[CMP2]])
726 ; CHECK-NEXT: [[CMP3:%.*]] = icmp ugt i32 [[B]], 42
727 ; CHECK-NEXT: call void @check1(i1 [[CMP3]])
728 ; CHECK-NEXT: ret void
730 ; CHECK-NEXT: call void @check1(i1 true)
731 ; CHECK-NEXT: call void @check1(i1 true)
732 ; CHECK-NEXT: ret void
736 %cmp = icmp ugt i32 %or, 42
737 br i1 %cmp, label %if.true, label %if.false
740 %cmp2 = icmp ugt i32 %a, 42
741 call void @check1(i1 %cmp2)
742 %cmp3 = icmp ugt i32 %b, 42
743 call void @check1(i1 %cmp3)
747 %cmp4 = icmp ule i32 %a, 42
748 call void @check1(i1 %cmp4)
749 %cmp5 = icmp ule i32 %b, 42
750 call void @check1(i1 %cmp5)
754 define void @test_icmp_or_uge(i32 %a, i32 %b) {
755 ; CHECK-LABEL: @test_icmp_or_uge(
757 ; CHECK-NEXT: [[OR:%.*]] = or i32 [[A:%.*]], [[B:%.*]]
758 ; CHECK-NEXT: [[CMP:%.*]] = icmp uge i32 [[OR]], 42
759 ; CHECK-NEXT: br i1 [[CMP]], label [[IF_TRUE:%.*]], label [[IF_FALSE:%.*]]
761 ; CHECK-NEXT: [[CMP2:%.*]] = icmp uge i32 [[A]], 42
762 ; CHECK-NEXT: call void @check1(i1 [[CMP2]])
763 ; CHECK-NEXT: [[CMP3:%.*]] = icmp uge i32 [[B]], 42
764 ; CHECK-NEXT: call void @check1(i1 [[CMP3]])
765 ; CHECK-NEXT: ret void
767 ; CHECK-NEXT: call void @check1(i1 true)
768 ; CHECK-NEXT: call void @check1(i1 true)
769 ; CHECK-NEXT: ret void
773 %cmp = icmp uge i32 %or, 42
774 br i1 %cmp, label %if.true, label %if.false
777 %cmp2 = icmp uge i32 %a, 42
778 call void @check1(i1 %cmp2)
779 %cmp3 = icmp uge i32 %b, 42
780 call void @check1(i1 %cmp3)
784 %cmp4 = icmp ult i32 %a, 42
785 call void @check1(i1 %cmp4)
786 %cmp5 = icmp ult i32 %b, 42
787 call void @check1(i1 %cmp5)
791 define void @test_icmp_or_slt(i32 %a, i32 %b) {
792 ; CHECK-LABEL: @test_icmp_or_slt(
794 ; CHECK-NEXT: [[OR:%.*]] = or i32 [[A:%.*]], [[B:%.*]]
795 ; CHECK-NEXT: [[CMP:%.*]] = icmp slt i32 [[OR]], 42
796 ; CHECK-NEXT: br i1 [[CMP]], label [[IF_TRUE:%.*]], label [[IF_FALSE:%.*]]
798 ; CHECK-NEXT: [[CMP2:%.*]] = icmp slt i32 [[A]], 42
799 ; CHECK-NEXT: call void @check1(i1 [[CMP2]])
800 ; CHECK-NEXT: [[CMP3:%.*]] = icmp slt i32 [[B]], 42
801 ; CHECK-NEXT: call void @check1(i1 [[CMP3]])
802 ; CHECK-NEXT: ret void
804 ; CHECK-NEXT: [[CMP4:%.*]] = icmp sge i32 [[A]], 42
805 ; CHECK-NEXT: call void @check1(i1 [[CMP4]])
806 ; CHECK-NEXT: [[CMP5:%.*]] = icmp sge i32 [[B]], 42
807 ; CHECK-NEXT: call void @check1(i1 [[CMP5]])
808 ; CHECK-NEXT: ret void
812 %cmp = icmp slt i32 %or, 42
813 br i1 %cmp, label %if.true, label %if.false
816 %cmp2 = icmp slt i32 %a, 42
817 call void @check1(i1 %cmp2)
818 %cmp3 = icmp slt i32 %b, 42
819 call void @check1(i1 %cmp3)
823 %cmp4 = icmp sge i32 %a, 42
824 call void @check1(i1 %cmp4)
825 %cmp5 = icmp sge i32 %b, 42
826 call void @check1(i1 %cmp5)
830 define void @test_icmp_and_ugt(i32 %a, i32 %b) {
831 ; CHECK-LABEL: @test_icmp_and_ugt(
833 ; CHECK-NEXT: [[AND:%.*]] = and i32 [[A:%.*]], [[B:%.*]]
834 ; CHECK-NEXT: [[CMP:%.*]] = icmp ugt i32 [[AND]], 42
835 ; CHECK-NEXT: br i1 [[CMP]], label [[IF_TRUE:%.*]], label [[IF_FALSE:%.*]]
837 ; CHECK-NEXT: call void @check1(i1 true)
838 ; CHECK-NEXT: call void @check1(i1 true)
839 ; CHECK-NEXT: ret void
841 ; CHECK-NEXT: [[CMP4:%.*]] = icmp ule i32 [[A]], 42
842 ; CHECK-NEXT: call void @check1(i1 [[CMP4]])
843 ; CHECK-NEXT: [[CMP5:%.*]] = icmp ule i32 [[B]], 42
844 ; CHECK-NEXT: call void @check1(i1 [[CMP5]])
845 ; CHECK-NEXT: ret void
848 %and = and i32 %a, %b
849 %cmp = icmp ugt i32 %and, 42
850 br i1 %cmp, label %if.true, label %if.false
853 %cmp2 = icmp ugt i32 %a, 42
854 call void @check1(i1 %cmp2)
855 %cmp3 = icmp ugt i32 %b, 42
856 call void @check1(i1 %cmp3)
860 %cmp4 = icmp ule i32 %a, 42
861 call void @check1(i1 %cmp4)
862 %cmp5 = icmp ule i32 %b, 42
863 call void @check1(i1 %cmp5)
867 define void @test_icmp_and_uge(i32 %a, i32 %b) {
868 ; CHECK-LABEL: @test_icmp_and_uge(
870 ; CHECK-NEXT: [[AND:%.*]] = and i32 [[A:%.*]], [[B:%.*]]
871 ; CHECK-NEXT: [[CMP:%.*]] = icmp uge i32 [[AND]], 42
872 ; CHECK-NEXT: br i1 [[CMP]], label [[IF_TRUE:%.*]], label [[IF_FALSE:%.*]]
874 ; CHECK-NEXT: call void @check1(i1 true)
875 ; CHECK-NEXT: call void @check1(i1 true)
876 ; CHECK-NEXT: ret void
878 ; CHECK-NEXT: [[CMP4:%.*]] = icmp ult i32 [[A]], 42
879 ; CHECK-NEXT: call void @check1(i1 [[CMP4]])
880 ; CHECK-NEXT: [[CMP5:%.*]] = icmp ult i32 [[B]], 42
881 ; CHECK-NEXT: call void @check1(i1 [[CMP5]])
882 ; CHECK-NEXT: ret void
885 %and = and i32 %a, %b
886 %cmp = icmp uge i32 %and, 42
887 br i1 %cmp, label %if.true, label %if.false
890 %cmp2 = icmp uge i32 %a, 42
891 call void @check1(i1 %cmp2)
892 %cmp3 = icmp uge i32 %b, 42
893 call void @check1(i1 %cmp3)
897 %cmp4 = icmp ult i32 %a, 42
898 call void @check1(i1 %cmp4)
899 %cmp5 = icmp ult i32 %b, 42
900 call void @check1(i1 %cmp5)
904 define void @test_icmp_and_ult(i32 %a, i32 %b) {
905 ; CHECK-LABEL: @test_icmp_and_ult(
907 ; CHECK-NEXT: [[AND:%.*]] = and i32 [[A:%.*]], [[B:%.*]]
908 ; CHECK-NEXT: [[CMP:%.*]] = icmp ult i32 [[AND]], 42
909 ; CHECK-NEXT: br i1 [[CMP]], label [[IF_TRUE:%.*]], label [[IF_FALSE:%.*]]
911 ; CHECK-NEXT: [[CMP2:%.*]] = icmp ult i32 [[A]], 42
912 ; CHECK-NEXT: call void @check1(i1 [[CMP2]])
913 ; CHECK-NEXT: [[CMP3:%.*]] = icmp ult i32 [[B]], 42
914 ; CHECK-NEXT: call void @check1(i1 [[CMP3]])
915 ; CHECK-NEXT: ret void
917 ; CHECK-NEXT: call void @check1(i1 true)
918 ; CHECK-NEXT: call void @check1(i1 true)
919 ; CHECK-NEXT: ret void
922 %and = and i32 %a, %b
923 %cmp = icmp ult i32 %and, 42
924 br i1 %cmp, label %if.true, label %if.false
927 %cmp2 = icmp ult i32 %a, 42
928 call void @check1(i1 %cmp2)
929 %cmp3 = icmp ult i32 %b, 42
930 call void @check1(i1 %cmp3)
934 %cmp4 = icmp uge i32 %a, 42
935 call void @check1(i1 %cmp4)
936 %cmp5 = icmp uge i32 %b, 42
937 call void @check1(i1 %cmp5)
941 define void @test_icmp_and_sgt(i32 %a, i32 %b) {
942 ; CHECK-LABEL: @test_icmp_and_sgt(
944 ; CHECK-NEXT: [[AND:%.*]] = and i32 [[A:%.*]], [[B:%.*]]
945 ; CHECK-NEXT: [[CMP:%.*]] = icmp sgt i32 [[AND]], 42
946 ; CHECK-NEXT: br i1 [[CMP]], label [[IF_TRUE:%.*]], label [[IF_FALSE:%.*]]
948 ; CHECK-NEXT: [[CMP2:%.*]] = icmp sgt i32 [[A]], 42
949 ; CHECK-NEXT: call void @check1(i1 [[CMP2]])
950 ; CHECK-NEXT: [[CMP3:%.*]] = icmp sgt i32 [[B]], 42
951 ; CHECK-NEXT: call void @check1(i1 [[CMP3]])
952 ; CHECK-NEXT: ret void
954 ; CHECK-NEXT: [[CMP4:%.*]] = icmp sle i32 [[A]], 42
955 ; CHECK-NEXT: call void @check1(i1 [[CMP4]])
956 ; CHECK-NEXT: [[CMP5:%.*]] = icmp sle i32 [[B]], 42
957 ; CHECK-NEXT: call void @check1(i1 [[CMP5]])
958 ; CHECK-NEXT: ret void
961 %and = and i32 %a, %b
962 %cmp = icmp sgt i32 %and, 42
963 br i1 %cmp, label %if.true, label %if.false
966 %cmp2 = icmp sgt i32 %a, 42
967 call void @check1(i1 %cmp2)
968 %cmp3 = icmp sgt i32 %b, 42
969 call void @check1(i1 %cmp3)
973 %cmp4 = icmp sle i32 %a, 42
974 call void @check1(i1 %cmp4)
975 %cmp5 = icmp sle i32 %b, 42
976 call void @check1(i1 %cmp5)
980 define void @test_icmp_mask_eq_two_values(i32 %a) {
981 ; CHECK-LABEL: @test_icmp_mask_eq_two_values(
982 ; CHECK-NEXT: [[AND:%.*]] = and i32 [[A:%.*]], -2
983 ; CHECK-NEXT: [[CMP:%.*]] = icmp eq i32 [[AND]], 10
984 ; CHECK-NEXT: br i1 [[CMP]], label [[IF_TRUE:%.*]], label [[IF_FALSE:%.*]]
986 ; CHECK-NEXT: call void @check1(i1 true)
987 ; CHECK-NEXT: call void @check1(i1 true)
988 ; CHECK-NEXT: call void @check1(i1 false)
989 ; CHECK-NEXT: call void @check1(i1 false)
990 ; CHECK-NEXT: ret void
992 ; CHECK-NEXT: ret void
994 %and = and i32 %a, -2
995 %cmp = icmp eq i32 %and, 10
996 br i1 %cmp, label %if.true, label %if.false
999 %cmp2 = icmp uge i32 %a, 10
1000 call void @check1(i1 %cmp2)
1001 %cmp3 = icmp ule i32 %a, 11
1002 call void @check1(i1 %cmp3)
1003 %cmp4 = icmp ult i32 %a, 10
1004 call void @check1(i1 %cmp4)
1005 %cmp5 = icmp ugt i32 %a, 11
1006 call void @check1(i1 %cmp5)
1013 define void @test_icmp_mask_eq_bit_set(i32 %a) {
1014 ; CHECK-LABEL: @test_icmp_mask_eq_bit_set(
1015 ; CHECK-NEXT: [[AND:%.*]] = and i32 [[A:%.*]], 32
1016 ; CHECK-NEXT: [[CMP:%.*]] = icmp eq i32 [[AND]], 32
1017 ; CHECK-NEXT: br i1 [[CMP]], label [[IF_TRUE:%.*]], label [[IF_FALSE:%.*]]
1019 ; CHECK-NEXT: call void @check1(i1 true)
1020 ; CHECK-NEXT: [[CMP3:%.*]] = icmp uge i32 [[A]], 33
1021 ; CHECK-NEXT: call void @check1(i1 [[CMP3]])
1022 ; CHECK-NEXT: ret void
1024 ; CHECK-NEXT: ret void
1026 %and = and i32 %a, 32
1027 %cmp = icmp eq i32 %and, 32
1028 br i1 %cmp, label %if.true, label %if.false
1031 %cmp2 = icmp uge i32 %a, 32
1032 call void @check1(i1 %cmp2)
1033 %cmp3 = icmp uge i32 %a, 33
1034 call void @check1(i1 %cmp3)
1041 define void @test_icmp_mask_eq_bit_unset(i32 %a) {
1042 ; CHECK-LABEL: @test_icmp_mask_eq_bit_unset(
1043 ; CHECK-NEXT: [[AND:%.*]] = and i32 [[A:%.*]], 32
1044 ; CHECK-NEXT: [[CMP:%.*]] = icmp eq i32 [[AND]], 0
1045 ; CHECK-NEXT: br i1 [[CMP]], label [[IF_TRUE:%.*]], label [[IF_FALSE:%.*]]
1047 ; CHECK-NEXT: call void @check1(i1 true)
1048 ; CHECK-NEXT: [[CMP3:%.*]] = icmp ule i32 [[A]], -34
1049 ; CHECK-NEXT: call void @check1(i1 [[CMP3]])
1050 ; CHECK-NEXT: ret void
1052 ; CHECK-NEXT: ret void
1054 %and = and i32 %a, 32
1055 %cmp = icmp eq i32 %and, 0
1056 br i1 %cmp, label %if.true, label %if.false
1059 %cmp2 = icmp ule i32 %a, -33
1060 call void @check1(i1 %cmp2)
1061 %cmp3 = icmp ule i32 %a, -34
1062 call void @check1(i1 %cmp3)
1069 define void @test_icmp_mask_eq_wrong_predicate(i32 %a) {
1070 ; CHECK-LABEL: @test_icmp_mask_eq_wrong_predicate(
1071 ; CHECK-NEXT: [[AND:%.*]] = and i32 [[A:%.*]], -2
1072 ; CHECK-NEXT: [[CMP:%.*]] = icmp ne i32 [[AND]], 10
1073 ; CHECK-NEXT: br i1 [[CMP]], label [[IF_TRUE:%.*]], label [[IF_FALSE:%.*]]
1075 ; CHECK-NEXT: [[CMP2:%.*]] = icmp uge i32 [[A]], 10
1076 ; CHECK-NEXT: call void @check1(i1 [[CMP2]])
1077 ; CHECK-NEXT: [[CMP3:%.*]] = icmp ule i32 [[A]], 11
1078 ; CHECK-NEXT: call void @check1(i1 [[CMP3]])
1079 ; CHECK-NEXT: [[CMP4:%.*]] = icmp ult i32 [[A]], 10
1080 ; CHECK-NEXT: call void @check1(i1 [[CMP4]])
1081 ; CHECK-NEXT: [[CMP5:%.*]] = icmp ugt i32 [[A]], 11
1082 ; CHECK-NEXT: call void @check1(i1 [[CMP5]])
1083 ; CHECK-NEXT: ret void
1085 ; CHECK-NEXT: ret void
1087 %and = and i32 %a, -2
1088 %cmp = icmp ne i32 %and, 10
1089 br i1 %cmp, label %if.true, label %if.false
1092 %cmp2 = icmp uge i32 %a, 10
1093 call void @check1(i1 %cmp2)
1094 %cmp3 = icmp ule i32 %a, 11
1095 call void @check1(i1 %cmp3)
1096 %cmp4 = icmp ult i32 %a, 10
1097 call void @check1(i1 %cmp4)
1098 %cmp5 = icmp ugt i32 %a, 11
1099 call void @check1(i1 %cmp5)
1106 define void @test_icmp_mask_ne(i32 %a) {
1107 ; CHECK-LABEL: @test_icmp_mask_ne(
1108 ; CHECK-NEXT: [[AND:%.*]] = and i32 [[A:%.*]], 6
1109 ; CHECK-NEXT: [[CMP:%.*]] = icmp ne i32 [[AND]], 0
1110 ; CHECK-NEXT: br i1 [[CMP]], label [[IF_TRUE:%.*]], label [[IF_FALSE:%.*]]
1112 ; CHECK-NEXT: call void @check1(i1 true)
1113 ; CHECK-NEXT: [[CMP3:%.*]] = icmp ugt i32 [[A]], 2
1114 ; CHECK-NEXT: call void @check1(i1 [[CMP3]])
1115 ; CHECK-NEXT: [[CMP4:%.*]] = icmp ult i32 [[A]], -1
1116 ; CHECK-NEXT: call void @check1(i1 [[CMP4]])
1117 ; CHECK-NEXT: ret void
1119 ; CHECK-NEXT: ret void
1121 %and = and i32 %a, 6
1122 %cmp = icmp ne i32 %and, 0
1123 br i1 %cmp, label %if.true, label %if.false
1126 %cmp2 = icmp uge i32 %a, 2
1127 call void @check1(i1 %cmp2)
1128 %cmp3 = icmp ugt i32 %a, 2
1129 call void @check1(i1 %cmp3)
1130 %cmp4 = icmp ult i32 %a, -1
1131 call void @check1(i1 %cmp4)
1138 define void @test_icmp_mask_ne_nonzero_cmp(i32 %a) {
1139 ; CHECK-LABEL: @test_icmp_mask_ne_nonzero_cmp(
1140 ; CHECK-NEXT: [[AND:%.*]] = and i32 [[A:%.*]], 6
1141 ; CHECK-NEXT: [[CMP:%.*]] = icmp ne i32 [[AND]], 6
1142 ; CHECK-NEXT: br i1 [[CMP]], label [[IF_TRUE:%.*]], label [[IF_FALSE:%.*]]
1144 ; CHECK-NEXT: [[CMP2:%.*]] = icmp uge i32 [[A]], 2
1145 ; CHECK-NEXT: call void @check1(i1 [[CMP2]])
1146 ; CHECK-NEXT: [[CMP3:%.*]] = icmp ugt i32 [[A]], 2
1147 ; CHECK-NEXT: call void @check1(i1 [[CMP3]])
1148 ; CHECK-NEXT: [[CMP4:%.*]] = icmp ult i32 [[A]], -1
1149 ; CHECK-NEXT: call void @check1(i1 [[CMP4]])
1150 ; CHECK-NEXT: ret void
1152 ; CHECK-NEXT: ret void
1154 %and = and i32 %a, 6
1155 %cmp = icmp ne i32 %and, 6
1156 br i1 %cmp, label %if.true, label %if.false
1159 %cmp2 = icmp uge i32 %a, 2
1160 call void @check1(i1 %cmp2)
1161 %cmp3 = icmp ugt i32 %a, 2
1162 call void @check1(i1 %cmp3)
1163 %cmp4 = icmp ult i32 %a, -1
1164 call void @check1(i1 %cmp4)
1171 define void @test_icmp_mask_ne_zero_mask(i32 %a) {
1172 ; CHECK-LABEL: @test_icmp_mask_ne_zero_mask(
1173 ; CHECK-NEXT: [[AND:%.*]] = and i32 [[A:%.*]], 0
1174 ; CHECK-NEXT: br i1 false, label [[IF_TRUE:%.*]], label [[IF_FALSE:%.*]]
1176 ; CHECK-NEXT: [[CMP2:%.*]] = icmp ne i32 [[A]], 0
1177 ; CHECK-NEXT: call void @check1(i1 [[CMP2]])
1178 ; CHECK-NEXT: ret void
1180 ; CHECK-NEXT: ret void
1182 %and = and i32 %a, 0
1183 %cmp = icmp ne i32 %and, 0
1184 br i1 %cmp, label %if.true, label %if.false
1187 %cmp2 = icmp ne i32 %a, 0
1188 call void @check1(i1 %cmp2)
1195 define void @non_const_range(i32 %a, i32 %b) {
1196 ; CHECK-LABEL: @non_const_range(
1197 ; CHECK-NEXT: [[CMP1:%.*]] = icmp ult i32 [[A:%.*]], 11
1198 ; CHECK-NEXT: [[CMP2:%.*]] = icmp ult i32 [[B:%.*]], 21
1199 ; CHECK-NEXT: [[AND:%.*]] = select i1 [[CMP1]], i1 [[CMP2]], i1 false
1200 ; CHECK-NEXT: br i1 [[AND]], label [[IF:%.*]], label [[ELSE:%.*]]
1202 ; CHECK-NEXT: [[A_100:%.*]] = add nuw nsw i32 [[A]], 100
1203 ; CHECK-NEXT: call void @check1(i1 true)
1204 ; CHECK-NEXT: call void @check1(i1 false)
1205 ; CHECK-NEXT: [[A_10:%.*]] = add nuw nsw i32 [[A]], 10
1206 ; CHECK-NEXT: [[CMP5:%.*]] = icmp ne i32 [[A_10]], [[B]]
1207 ; CHECK-NEXT: call void @check1(i1 [[CMP5]])
1208 ; CHECK-NEXT: [[CMP6:%.*]] = icmp eq i32 [[A_10]], [[B]]
1209 ; CHECK-NEXT: call void @check1(i1 [[CMP6]])
1210 ; CHECK-NEXT: ret void
1212 ; CHECK-NEXT: ret void
1214 %cmp1 = icmp ult i32 %a, 11
1215 %cmp2 = icmp ult i32 %b, 21
1216 %and = select i1 %cmp1, i1 %cmp2, i1 false
1217 br i1 %and, label %if, label %else
1220 %a.100 = add nuw nsw i32 %a, 100
1221 %cmp3 = icmp ne i32 %a.100, %b
1222 call void @check1(i1 %cmp3)
1223 %cmp4 = icmp eq i32 %a.100, %b
1224 call void @check1(i1 %cmp4)
1226 %a.10 = add nuw nsw i32 %a, 10
1227 %cmp5 = icmp ne i32 %a.10, %b
1228 call void @check1(i1 %cmp5)
1229 %cmp6 = icmp eq i32 %a.10, %b
1230 call void @check1(i1 %cmp6)
1237 define i1 @non_const_range_minmax(i8 %a, i8 %b) {
1238 ; CHECK-LABEL: @non_const_range_minmax(
1239 ; CHECK-NEXT: [[A2:%.*]] = call i8 @llvm.umin.i8(i8 [[A:%.*]], i8 10)
1240 ; CHECK-NEXT: [[B2:%.*]] = call i8 @llvm.umax.i8(i8 [[B:%.*]], i8 11)
1241 ; CHECK-NEXT: ret i1 true
1243 %a2 = call i8 @llvm.umin.i8(i8 %a, i8 10)
1244 %b2 = call i8 @llvm.umax.i8(i8 %b, i8 11)
1245 %cmp1 = icmp ult i8 %a2, %b2
1249 define <2 x i1> @non_const_range_minmax_vec(<2 x i8> %a, <2 x i8> %b) {
1250 ; CHECK-LABEL: @non_const_range_minmax_vec(
1251 ; CHECK-NEXT: [[A2:%.*]] = call <2 x i8> @llvm.umin.v2i8(<2 x i8> [[A:%.*]], <2 x i8> <i8 10, i8 10>)
1252 ; CHECK-NEXT: [[B2:%.*]] = call <2 x i8> @llvm.umax.v2i8(<2 x i8> [[B:%.*]], <2 x i8> <i8 11, i8 11>)
1253 ; CHECK-NEXT: ret <2 x i1> <i1 true, i1 true>
1255 %a2 = call <2 x i8> @llvm.umin.v2i8(<2 x i8> %a, <2 x i8> <i8 10, i8 10>)
1256 %b2 = call <2 x i8> @llvm.umax.v2i8(<2 x i8> %b, <2 x i8> <i8 11, i8 11>)
1257 %cmp1 = icmp ult <2 x i8> %a2, %b2
1261 define void @ashr_sgt(i8 %x) {
1262 ; CHECK-LABEL: @ashr_sgt(
1263 ; CHECK-NEXT: [[S:%.*]] = ashr i8 [[X:%.*]], 2
1264 ; CHECK-NEXT: [[C:%.*]] = icmp sgt i8 [[S]], 1
1265 ; CHECK-NEXT: br i1 [[C]], label [[IF:%.*]], label [[ELSE:%.*]]
1267 ; CHECK-NEXT: call void @check1(i1 true)
1268 ; CHECK-NEXT: [[C3:%.*]] = icmp ugt i8 [[X]], 8
1269 ; CHECK-NEXT: call void @check1(i1 [[C3]])
1270 ; CHECK-NEXT: ret void
1272 ; CHECK-NEXT: ret void
1275 %c = icmp sgt i8 %s, 1
1276 br i1 %c, label %if, label %else
1278 %c2 = icmp sgt i8 %x, 7
1279 call void @check1(i1 %c2)
1280 %c3 = icmp sgt i8 %x, 8
1281 call void @check1(i1 %c3)
1287 define void @ashr_sge(i8 %x) {
1288 ; CHECK-LABEL: @ashr_sge(
1289 ; CHECK-NEXT: [[S:%.*]] = ashr i8 [[X:%.*]], 2
1290 ; CHECK-NEXT: [[C:%.*]] = icmp sge i8 [[S]], 1
1291 ; CHECK-NEXT: br i1 [[C]], label [[IF:%.*]], label [[ELSE:%.*]]
1293 ; CHECK-NEXT: call void @check1(i1 true)
1294 ; CHECK-NEXT: [[C3:%.*]] = icmp uge i8 [[X]], 5
1295 ; CHECK-NEXT: call void @check1(i1 [[C3]])
1296 ; CHECK-NEXT: ret void
1298 ; CHECK-NEXT: ret void
1301 %c = icmp sge i8 %s, 1
1302 br i1 %c, label %if, label %else
1304 %c2 = icmp sge i8 %x, 4
1305 call void @check1(i1 %c2)
1306 %c3 = icmp sge i8 %x, 5
1307 call void @check1(i1 %c3)
1313 define void @ashr_slt(i8 %x) {
1314 ; CHECK-LABEL: @ashr_slt(
1315 ; CHECK-NEXT: [[S:%.*]] = ashr i8 [[X:%.*]], 2
1316 ; CHECK-NEXT: [[C:%.*]] = icmp slt i8 [[S]], 1
1317 ; CHECK-NEXT: br i1 [[C]], label [[IF:%.*]], label [[ELSE:%.*]]
1319 ; CHECK-NEXT: call void @check1(i1 true)
1320 ; CHECK-NEXT: [[C3:%.*]] = icmp slt i8 [[X]], 3
1321 ; CHECK-NEXT: call void @check1(i1 [[C3]])
1322 ; CHECK-NEXT: ret void
1324 ; CHECK-NEXT: ret void
1327 %c = icmp slt i8 %s, 1
1328 br i1 %c, label %if, label %else
1330 %c2 = icmp slt i8 %x, 4
1331 call void @check1(i1 %c2)
1332 %c3 = icmp slt i8 %x, 3
1333 call void @check1(i1 %c3)
1339 define void @ashr_sle(i8 %x) {
1340 ; CHECK-LABEL: @ashr_sle(
1341 ; CHECK-NEXT: [[S:%.*]] = ashr i8 [[X:%.*]], 2
1342 ; CHECK-NEXT: [[C:%.*]] = icmp sle i8 [[S]], 1
1343 ; CHECK-NEXT: br i1 [[C]], label [[IF:%.*]], label [[ELSE:%.*]]
1345 ; CHECK-NEXT: call void @check1(i1 true)
1346 ; CHECK-NEXT: [[C3:%.*]] = icmp sle i8 [[X]], 6
1347 ; CHECK-NEXT: call void @check1(i1 [[C3]])
1348 ; CHECK-NEXT: ret void
1350 ; CHECK-NEXT: ret void
1353 %c = icmp sle i8 %s, 1
1354 br i1 %c, label %if, label %else
1356 %c2 = icmp sle i8 %x, 7
1357 call void @check1(i1 %c2)
1358 %c3 = icmp sle i8 %x, 6
1359 call void @check1(i1 %c3)
1365 declare i8 @llvm.umin.i8(i8, i8)
1366 declare i8 @llvm.umax.i8(i8, i8)
1367 declare <2 x i8> @llvm.umin.v2i8(<2 x i8>, <2 x i8>)
1368 declare <2 x i8> @llvm.umax.v2i8(<2 x i8>, <2 x i8>)
1370 attributes #4 = { noreturn }
1372 define i1 @pr69928(i64 noundef %arg, i64 noundef %arg1) {
1373 ; CHECK-LABEL: @pr69928(
1374 ; CHECK-NEXT: entry:
1375 ; CHECK-NEXT: [[CMP1:%.*]] = icmp ult i64 [[ARG:%.*]], 64424509440
1376 ; CHECK-NEXT: [[AND:%.*]] = and i64 [[ARG1:%.*]], 4294967295
1377 ; CHECK-NEXT: [[CMP2:%.*]] = icmp ult i64 [[ARG]], [[AND]]
1378 ; CHECK-NEXT: [[SELECT:%.*]] = select i1 [[CMP1]], i1 [[CMP2]], i1 false
1379 ; CHECK-NEXT: ret i1 [[SELECT]]
1382 %cmp1 = icmp ult i64 %arg, 64424509440
1383 %and = and i64 %arg1, 4294967295
1384 %cmp2 = icmp slt i64 %arg, %and
1385 %select = select i1 %cmp1, i1 %cmp2, i1 false
1389 define i1 @test_select_flip(i64 noundef %arg) {
1390 ; CHECK-LABEL: @test_select_flip(
1391 ; CHECK-NEXT: entry:
1392 ; CHECK-NEXT: [[CMP1:%.*]] = icmp ult i64 [[ARG:%.*]], 1000
1393 ; CHECK-NEXT: [[CMP2:%.*]] = icmp ult i64 [[ARG]], 100
1394 ; CHECK-NEXT: [[SELECT:%.*]] = select i1 [[CMP1]], i1 [[CMP2]], i1 false
1395 ; CHECK-NEXT: ret i1 [[SELECT]]
1398 %cmp1 = icmp ult i64 %arg, 1000
1399 %cmp2 = icmp slt i64 %arg, 100
1400 %select = select i1 %cmp1, i1 %cmp2, i1 false
1404 define i1 @test_select_flip_fail1(i64 noundef %arg) {
1405 ; CHECK-LABEL: @test_select_flip_fail1(
1406 ; CHECK-NEXT: entry:
1407 ; CHECK-NEXT: [[CMP1:%.*]] = icmp slt i64 [[ARG:%.*]], 1000
1408 ; CHECK-NEXT: [[CMP2:%.*]] = icmp slt i64 [[ARG]], 100
1409 ; CHECK-NEXT: [[SELECT:%.*]] = select i1 [[CMP1]], i1 [[CMP2]], i1 false
1410 ; CHECK-NEXT: ret i1 [[SELECT]]
1413 %cmp1 = icmp slt i64 %arg, 1000
1414 %cmp2 = icmp slt i64 %arg, 100
1415 %select = select i1 %cmp1, i1 %cmp2, i1 false
1419 define i1 @test_select_flip_fail2(i64 noundef %arg) {
1420 ; CHECK-LABEL: @test_select_flip_fail2(
1421 ; CHECK-NEXT: entry:
1422 ; CHECK-NEXT: [[CMP1:%.*]] = icmp ult i64 [[ARG:%.*]], 1000
1423 ; CHECK-NEXT: [[CMP2:%.*]] = icmp slt i64 [[ARG]], 100
1424 ; CHECK-NEXT: [[SELECT:%.*]] = select i1 [[CMP1]], i1 false, i1 [[CMP2]]
1425 ; CHECK-NEXT: ret i1 [[SELECT]]
1428 %cmp1 = icmp ult i64 %arg, 1000
1429 %cmp2 = icmp slt i64 %arg, 100
1430 %select = select i1 %cmp1, i1 false, i1 %cmp2
1434 define i1 @test_select_flip_fail3(i64 noundef %arg, i64 noundef %arg1) {
1435 ; CHECK-LABEL: @test_select_flip_fail3(
1436 ; CHECK-NEXT: entry:
1437 ; CHECK-NEXT: [[CMP1:%.*]] = icmp ult i64 [[ARG1:%.*]], 1000
1438 ; CHECK-NEXT: [[CMP2:%.*]] = icmp slt i64 [[ARG:%.*]], 100
1439 ; CHECK-NEXT: [[SELECT:%.*]] = select i1 [[CMP1]], i1 [[CMP2]], i1 false
1440 ; CHECK-NEXT: ret i1 [[SELECT]]
1443 %cmp1 = icmp ult i64 %arg1, 1000
1444 %cmp2 = icmp slt i64 %arg, 100
1445 %select = select i1 %cmp1, i1 %cmp2, i1 false
1449 define i1 @test_select_flip_fail4(i64 noundef %arg) {
1450 ; CHECK-LABEL: @test_select_flip_fail4(
1451 ; CHECK-NEXT: entry:
1452 ; CHECK-NEXT: [[CMP2:%.*]] = icmp slt i64 [[ARG:%.*]], 100
1453 ; CHECK-NEXT: [[SELECT:%.*]] = select i1 true, i1 [[CMP2]], i1 false
1454 ; CHECK-NEXT: ret i1 [[SELECT]]
1457 %cmp2 = icmp slt i64 %arg, 100
1458 %select = select i1 true, i1 %cmp2, i1 false
1462 define i1 @test_select_flip_fail5(i64 noundef %arg, i64 noundef %arg1) {
1463 ; CHECK-LABEL: @test_select_flip_fail5(
1464 ; CHECK-NEXT: entry:
1465 ; CHECK-NEXT: [[CMP1:%.*]] = icmp ult i64 [[ARG:%.*]], 1000
1466 ; CHECK-NEXT: [[CMP2:%.*]] = icmp slt i64 [[ARG]], [[ARG1:%.*]]
1467 ; CHECK-NEXT: [[SELECT:%.*]] = select i1 [[CMP1]], i1 [[CMP2]], i1 false
1468 ; CHECK-NEXT: ret i1 [[SELECT]]
1471 %cmp1 = icmp ult i64 %arg, 1000
1472 %cmp2 = icmp slt i64 %arg, %arg1
1473 %select = select i1 %cmp1, i1 %cmp2, i1 false
1477 declare void @opaque()
1479 define void @test_icmp_ne_from_implied_range(i32 noundef %arg) {
1480 ; CHECK-LABEL: @test_icmp_ne_from_implied_range(
1481 ; CHECK-NEXT: [[AND_MASK:%.*]] = and i32 [[ARG:%.*]], -8
1482 ; CHECK-NEXT: [[CMP:%.*]] = icmp eq i32 [[AND_MASK]], -16
1483 ; CHECK-NEXT: br i1 [[CMP]], label [[END:%.*]], label [[ELSE:%.*]]
1485 ; CHECK-NEXT: br label [[END]]
1487 ; CHECK-NEXT: call void @opaque()
1488 ; CHECK-NEXT: br label [[END]]
1490 ; CHECK-NEXT: ret void
1492 %and.mask = and i32 %arg, -8
1493 %cmp = icmp eq i32 %and.mask, -16
1494 br i1 %cmp, label %end, label %else
1497 ; %arg is within [-8, -16).
1498 switch i32 %arg, label %end [
1499 i32 -16, label %sw.case
1500 i32 -12, label %sw.case
1501 i32 -9, label %sw.case
1509 ; %arg is within [-16, -8).