1 ; NOTE: Assertions have been autogenerated by utils/update_test_checks.py
2 ; RUN: opt < %s -passes=instsimplify -S | FileCheck %s
3 target datalayout = "p:32:32-p1:64:64"
5 declare void @llvm.assume(i1)
7 define i1 @ptrtoint() {
8 ; CHECK-LABEL: @ptrtoint(
9 ; CHECK-NEXT: ret i1 false
12 %tmp = ptrtoint ptr %a to i32
13 %r = icmp eq i32 %tmp, 0
17 define i1 @bitcast() {
18 ; CHECK-LABEL: @bitcast(
19 ; CHECK-NEXT: ret i1 false
23 %cmp = icmp eq ptr %a, %b
29 ; CHECK-NEXT: ret i1 false
31 %a = alloca [3 x i8], align 8
32 %cmp = icmp eq ptr %a, null
38 ; CHECK-NEXT: ret i1 true
40 %a = alloca [3 x i8], align 8
41 %cmp = icmp eq ptr %a, %a
46 %gept = type { i32, i32 }
47 @gepy = global %gept zeroinitializer, align 8
48 @gepz = extern_weak global %gept
52 ; CHECK-NEXT: ret i1 false
54 %x = alloca %gept, align 8
55 %b = getelementptr %gept, ptr %x, i64 0, i32 1
56 %equal = icmp eq ptr %x, %b
62 ; CHECK-NEXT: ret i1 false
64 %x = alloca %gept, align 8
65 %b = getelementptr %gept, ptr @gepy, i64 0, i32 1
66 %equal = icmp eq ptr @gepy, %b
70 @a = common global [1 x i32] zeroinitializer, align 4
72 define i1 @PR31262() {
73 ; CHECK-LABEL: @PR31262(
74 ; CHECK-NEXT: ret i1 true
76 %idx = getelementptr inbounds [1 x i32], ptr @a, i64 0, i64 undef
77 %cmp = icmp uge ptr %idx, @a
83 ; CHECK-NEXT: ret i1 false
85 %x = alloca %gept, align 8
86 %a = getelementptr inbounds %gept, ptr %x, i64 0, i32 1
87 %equal = icmp eq ptr %a, @gepy
91 define i1 @gep6(ptr %x) {
92 ; Same as @gep3 but potentially null.
94 ; CHECK-NEXT: ret i1 false
96 %b = getelementptr %gept, ptr %x, i64 0, i32 1
97 %equal = icmp eq ptr %x, %b
101 define i1 @gep7(ptr %x) {
102 ; CHECK-LABEL: @gep7(
103 ; CHECK-NEXT: [[EQUAL:%.*]] = icmp eq ptr [[X:%.*]], @gepz
104 ; CHECK-NEXT: ret i1 [[EQUAL]]
106 %equal = icmp eq ptr %x, @gepz
110 define i1 @gep8(ptr %x) {
111 ; CHECK-LABEL: @gep8(
112 ; CHECK-NEXT: [[A:%.*]] = getelementptr [[GEPT:%.*]], ptr [[X:%.*]], i32 1
113 ; CHECK-NEXT: [[B:%.*]] = getelementptr [[GEPT]], ptr [[X]], i32 -1
114 ; CHECK-NEXT: [[EQUAL:%.*]] = icmp ugt ptr [[A]], [[B]]
115 ; CHECK-NEXT: ret i1 [[EQUAL]]
117 %a = getelementptr %gept, ptr %x, i32 1
118 %b = getelementptr %gept, ptr %x, i32 -1
119 %equal = icmp ugt ptr %a, %b
123 define i1 @gep9(ptr %ptr) {
124 ; CHECK-LABEL: @gep9(
126 ; CHECK-NEXT: ret i1 true
129 %first2 = getelementptr inbounds i8, ptr %ptr, i32 1
130 %first3 = getelementptr inbounds i8, ptr %first2, i32 2
131 %first4 = getelementptr inbounds i8, ptr %first3, i32 4
132 %last1 = getelementptr inbounds i8, ptr %first2, i32 48
133 %last2 = getelementptr inbounds i8, ptr %last1, i32 8
134 %last3 = getelementptr inbounds i8, ptr %last2, i32 -4
135 %last4 = getelementptr inbounds i8, ptr %last3, i32 -4
136 %first.int = ptrtoint ptr %first4 to i32
137 %last.int = ptrtoint ptr %last4 to i32
138 %cmp = icmp ne i32 %last.int, %first.int
142 define i1 @gep10(ptr %ptr) {
143 ; CHECK-LABEL: @gep10(
145 ; CHECK-NEXT: ret i1 true
148 %first1 = getelementptr inbounds i8, ptr %ptr, i32 -2
149 %first2 = getelementptr inbounds i8, ptr %first1, i32 44
150 %last1 = getelementptr inbounds i8, ptr %ptr, i32 48
151 %last2 = getelementptr inbounds i8, ptr %last1, i32 -6
152 %first.int = ptrtoint ptr %first2 to i32
153 %last.int = ptrtoint ptr %last2 to i32
154 %cmp = icmp eq i32 %last.int, %first.int
158 define i1 @gep11(ptr %ptr) {
159 ; CHECK-LABEL: @gep11(
161 ; CHECK-NEXT: ret i1 true
164 %first1 = getelementptr inbounds i8, ptr %ptr, i32 -2
165 %last1 = getelementptr inbounds i8, ptr %ptr, i32 48
166 %last2 = getelementptr inbounds i8, ptr %last1, i32 -6
167 %cmp = icmp ult ptr %first1, %last2
171 define i1 @gep12(ptr %ptr) {
172 ; CHECK-LABEL: @gep12(
174 ; CHECK-NEXT: [[FIRST1:%.*]] = getelementptr inbounds i8, ptr [[PTR:%.*]], i32 -2
175 ; CHECK-NEXT: [[LAST1:%.*]] = getelementptr inbounds i8, ptr [[PTR]], i32 48
176 ; CHECK-NEXT: [[LAST2:%.*]] = getelementptr inbounds i8, ptr [[LAST1]], i32 -6
177 ; CHECK-NEXT: [[CMP:%.*]] = icmp slt ptr [[FIRST1]], [[LAST2]]
178 ; CHECK-NEXT: ret i1 [[CMP]]
181 %first1 = getelementptr inbounds i8, ptr %ptr, i32 -2
182 %last1 = getelementptr inbounds i8, ptr %ptr, i32 48
183 %last2 = getelementptr inbounds i8, ptr %last1, i32 -6
184 %cmp = icmp slt ptr %first1, %last2
188 define i1 @gep13(ptr %ptr) {
189 ; CHECK-LABEL: @gep13(
190 ; CHECK-NEXT: ret i1 false
192 ; We can prove this GEP is non-null because it is inbounds.
193 %x = getelementptr inbounds i8, ptr %ptr, i32 1
194 %cmp = icmp eq ptr %x, null
198 define i1 @gep13_no_null_opt(ptr %ptr) #0 {
199 ; We can't prove this GEP is non-null.
200 ; CHECK-LABEL: @gep13_no_null_opt(
201 ; CHECK-NEXT: [[X:%.*]] = getelementptr inbounds i8, ptr [[PTR:%.*]], i32 1
202 ; CHECK-NEXT: [[CMP:%.*]] = icmp eq ptr [[X]], null
203 ; CHECK-NEXT: ret i1 [[CMP]]
205 %x = getelementptr inbounds i8, ptr %ptr, i32 1
206 %cmp = icmp eq ptr %x, null
210 ; We can prove this GEP is non-null because it is nuw.
211 define i1 @gep_nuw_not_null(ptr %ptr) {
212 ; CHECK-LABEL: @gep_nuw_not_null(
213 ; CHECK-NEXT: ret i1 false
215 %x = getelementptr nuw i8, ptr %ptr, i32 1
216 %cmp = icmp eq ptr %x, null
220 ; Unlike the inbounds case, this holds even if the null pointer is valid.
221 define i1 @gep_nuw_null_pointer_valid(ptr %ptr) null_pointer_is_valid {
222 ; CHECK-LABEL: @gep_nuw_null_pointer_valid(
223 ; CHECK-NEXT: ret i1 false
225 %x = getelementptr nuw i8, ptr %ptr, i32 1
226 %cmp = icmp eq ptr %x, null
230 ; If the base pointer is non-null, the offset doesn't matter.
231 define i1 @gep_nuw_maybe_zero_offset(ptr nonnull %ptr, i32 %offset) {
232 ; CHECK-LABEL: @gep_nuw_maybe_zero_offset(
233 ; CHECK-NEXT: ret i1 false
235 %x = getelementptr nuw i8, ptr %ptr, i32 %offset
236 %cmp = icmp eq ptr %x, null
240 ; We can not prove non-null if both the base pointer may be null and the
242 define i1 @gep13_nuw_maybe_zero_offset(ptr %ptr, i32 %offset) {
243 ; CHECK-LABEL: @gep13_nuw_maybe_zero_offset(
244 ; CHECK-NEXT: [[X:%.*]] = getelementptr nuw i8, ptr [[PTR:%.*]], i32 [[OFFSET:%.*]]
245 ; CHECK-NEXT: [[CMP:%.*]] = icmp eq ptr [[X]], null
246 ; CHECK-NEXT: ret i1 [[CMP]]
248 %x = getelementptr nuw i8, ptr %ptr, i32 %offset
249 %cmp = icmp eq ptr %x, null
253 ; For gep nusw we don't have any non-null information.
254 define i1 @gep_nusw_may_be_null(ptr %ptr) {
255 ; CHECK-LABEL: @gep_nusw_may_be_null(
256 ; CHECK-NEXT: [[X:%.*]] = getelementptr nusw i8, ptr [[PTR:%.*]], i32 1
257 ; CHECK-NEXT: [[CMP:%.*]] = icmp eq ptr [[X]], null
258 ; CHECK-NEXT: ret i1 [[CMP]]
260 %x = getelementptr nusw i8, ptr %ptr, i32 1
261 %cmp = icmp eq ptr %x, null
265 define i1 @gep14(ptr %ptr) {
266 ; CHECK-LABEL: @gep14(
267 ; CHECK-NEXT: [[X:%.*]] = getelementptr inbounds { {}, i8 }, ptr [[PTR:%.*]], i32 0, i32 1
268 ; CHECK-NEXT: [[CMP:%.*]] = icmp eq ptr [[X]], null
269 ; CHECK-NEXT: ret i1 [[CMP]]
271 ; We can't simplify this because the offset of one in the GEP actually doesn't
273 %x = getelementptr inbounds { {}, i8 }, ptr %ptr, i32 0, i32 1
274 %cmp = icmp eq ptr %x, null
278 define i1 @gep15(ptr %ptr, i32 %y) {
279 ; CHECK-LABEL: @gep15(
280 ; CHECK-NEXT: ret i1 false
282 ; We can prove this GEP is non-null even though there is a user value, as we
283 ; would necessarily violate inbounds on one side or the other.
284 %x = getelementptr inbounds { {}, [4 x {i8, i8}]}, ptr %ptr, i32 0, i32 1, i32 %y, i32 1
285 %cmp = icmp eq ptr %x, null
289 define i1 @gep15_no_null_opt(ptr %ptr, i32 %y) #0 {
290 ; We can't prove this GEP is non-null.
291 ; CHECK-LABEL: @gep15_no_null_opt(
292 ; CHECK-NEXT: [[X:%.*]] = getelementptr inbounds { {}, [4 x { i8, i8 }] }, ptr [[PTR:%.*]], i32 0, i32 1, i32 [[Y:%.*]], i32 1
293 ; CHECK-NEXT: [[CMP:%.*]] = icmp eq ptr [[X]], null
294 ; CHECK-NEXT: ret i1 [[CMP]]
296 %x = getelementptr inbounds { {}, [4 x {i8, i8}]}, ptr %ptr, i32 0, i32 1, i32 %y, i32 1
297 %cmp = icmp eq ptr %x, null
301 define i1 @gep16(ptr %ptr, i32 %a) {
302 ; CHECK-LABEL: @gep16(
303 ; CHECK-NEXT: ret i1 false
305 ; We can prove this GEP is non-null because it is inbounds and because we know
306 ; %b is non-zero even though we don't know its value.
308 %x = getelementptr inbounds i8, ptr %ptr, i32 %b
309 %cmp = icmp eq ptr %x, null
313 define i1 @gep16_no_null_opt(ptr %ptr, i32 %a) #0 {
314 ; We can't prove this GEP is non-null.
315 ; CHECK-LABEL: @gep16_no_null_opt(
316 ; CHECK-NEXT: [[B:%.*]] = or i32 [[A:%.*]], 1
317 ; CHECK-NEXT: [[X:%.*]] = getelementptr inbounds i8, ptr [[PTR:%.*]], i32 [[B]]
318 ; CHECK-NEXT: [[CMP:%.*]] = icmp eq ptr [[X]], null
319 ; CHECK-NEXT: ret i1 [[CMP]]
322 %x = getelementptr inbounds i8, ptr %ptr, i32 %b
323 %cmp = icmp eq ptr %x, null
328 ; CHECK-LABEL: @gep17(
329 ; CHECK-NEXT: ret i1 true
331 %alloca = alloca i32, align 4
332 %gep1 = getelementptr inbounds i32, ptr %alloca, i32 1
333 %pti1 = ptrtoint ptr %gep1 to i32
334 %gep2 = getelementptr inbounds [4 x i8], ptr %alloca, i32 0, i32 1
335 %pti2 = ptrtoint ptr %gep2 to i32
336 %cmp = icmp ugt i32 %pti1, %pti2
340 @extern_weak = extern_weak global i8
342 define i1 @extern_weak_may_be_null() {
343 ; CHECK-LABEL: @extern_weak_may_be_null(
344 ; CHECK-NEXT: [[CMP:%.*]] = icmp ne ptr @extern_weak, null
345 ; CHECK-NEXT: ret i1 [[CMP]]
347 %cmp = icmp ne ptr @extern_weak, null
351 ; Don't fold this. @A might really be allocated next to @B, in which case the
352 ; icmp should return true. It's not valid to *dereference* in @B from a pointer
353 ; based on @A, but icmp isn't a dereference.
354 define i1 @globals_might_be_adjacent() {
355 ; CHECK-LABEL: @globals_might_be_adjacent(
356 ; CHECK-NEXT: [[CMP:%.*]] = icmp eq ptr getelementptr inbounds (i32, ptr @A, i64 1), @B
357 ; CHECK-NEXT: ret i1 [[CMP]]
359 %cmp = icmp eq ptr getelementptr inbounds (i32, ptr @A, i64 1), @B
363 define i1 @globals_might_be_adjacent2() {
364 ; CHECK-LABEL: @globals_might_be_adjacent2(
365 ; CHECK-NEXT: [[CMP:%.*]] = icmp eq ptr getelementptr inbounds (i64, ptr @A, i64 1), getelementptr inbounds (i64, ptr @B, i64 2)
366 ; CHECK-NEXT: ret i1 [[CMP]]
368 %cmp = icmp eq ptr getelementptr inbounds (i64, ptr @A, i64 1), getelementptr inbounds (i64, ptr @B, i64 2)
372 @weak = weak global i32 0
374 ; An object with weak linkage cannot have it's identity determined at compile time.
375 define i1 @weak_comparison() {
376 ; CHECK-LABEL: @weak_comparison(
377 ; CHECK-NEXT: [[CMP:%.*]] = icmp eq ptr @weak, @A
378 ; CHECK-NEXT: ret i1 [[CMP]]
380 %cmp = icmp eq ptr @weak, @A
384 @empty.1 = external global [0 x i8], align 1
385 @empty.2 = external global [0 x i8], align 1
387 ; Empty globals might end up anywhere, even on top of another global.
388 define i1 @empty_global_comparison() {
389 ; CHECK-LABEL: @empty_global_comparison(
390 ; CHECK-NEXT: [[CMP:%.*]] = icmp eq ptr @empty.1, @empty.2
391 ; CHECK-NEXT: ret i1 [[CMP]]
393 %cmp = icmp eq ptr @empty.1, @empty.2
397 @unnamed.1 = unnamed_addr constant [5 x i8] c"asdf\00"
398 @unnamed.2 = unnamed_addr constant [5 x i8] c"asdf\00"
400 ; Two unnamed_addr globals can share an address
401 define i1 @unnamed_addr_comparison() {
402 ; CHECK-LABEL: @unnamed_addr_comparison(
403 ; CHECK-NEXT: [[CMP:%.*]] = icmp eq ptr @unnamed.1, @unnamed.2
404 ; CHECK-NEXT: ret i1 [[CMP]]
406 %cmp = icmp eq ptr @unnamed.1, @unnamed.2
410 @addrspace3 = internal addrspace(3) global i32 undef
412 define i1 @no.fold.addrspace.icmp.eq.gv.null() {
413 ; CHECK-LABEL: @no.fold.addrspace.icmp.eq.gv.null(
414 ; CHECK-NEXT: [[CMP:%.*]] = icmp eq ptr addrspace(3) @addrspace3, null
415 ; CHECK-NEXT: ret i1 [[CMP]]
417 %cmp = icmp eq ptr addrspace(3) @addrspace3, null
421 define i1 @no.fold.addrspace.icmp.eq.null.gv() {
422 ; CHECK-LABEL: @no.fold.addrspace.icmp.eq.null.gv(
423 ; CHECK-NEXT: [[CMP:%.*]] = icmp eq ptr addrspace(3) null, @addrspace3
424 ; CHECK-NEXT: ret i1 [[CMP]]
426 %cmp = icmp eq ptr addrspace(3) null, @addrspace3
430 define i1 @no.fold.addrspace.icmp.ne.gv.null() {
431 ; CHECK-LABEL: @no.fold.addrspace.icmp.ne.gv.null(
432 ; CHECK-NEXT: [[CMP:%.*]] = icmp ne ptr addrspace(3) @addrspace3, null
433 ; CHECK-NEXT: ret i1 [[CMP]]
435 %cmp = icmp ne ptr addrspace(3) @addrspace3, null
439 define i1 @no.fold.addrspace.icmp.ne.null.gv() {
440 ; CHECK-LABEL: @no.fold.addrspace.icmp.ne.null.gv(
441 ; CHECK-NEXT: [[CMP:%.*]] = icmp ne ptr addrspace(3) null, @addrspace3
442 ; CHECK-NEXT: ret i1 [[CMP]]
444 %cmp = icmp ne ptr addrspace(3) null, @addrspace3
448 ; Negative test: GEP inbounds may cross sign boundary.
449 define i1 @gep_same_base_constant_indices(ptr %a) {
450 ; CHECK-LABEL: @gep_same_base_constant_indices(
451 ; CHECK-NEXT: [[ARRAYIDX1:%.*]] = getelementptr inbounds i8, ptr [[A:%.*]], i64 1
452 ; CHECK-NEXT: [[ARRAYIDX2:%.*]] = getelementptr inbounds i8, ptr [[A]], i64 10
453 ; CHECK-NEXT: [[CMP:%.*]] = icmp slt ptr [[ARRAYIDX1]], [[ARRAYIDX2]]
454 ; CHECK-NEXT: ret i1 [[CMP]]
456 %arrayidx1 = getelementptr inbounds i8, ptr %a, i64 1
457 %arrayidx2 = getelementptr inbounds i8, ptr %a, i64 10
458 %cmp = icmp slt ptr %arrayidx1, %arrayidx2
462 define i1 @zext(i32 %x) {
463 ; CHECK-LABEL: @zext(
464 ; CHECK-NEXT: ret i1 true
466 %e1 = zext i32 %x to i64
467 %e2 = zext i32 %x to i64
468 %r = icmp eq i64 %e1, %e2
472 define i1 @zext2(i1 %x) {
473 ; CHECK-LABEL: @zext2(
474 ; CHECK-NEXT: ret i1 [[X:%.*]]
476 %e = zext i1 %x to i32
477 %c = icmp ne i32 %e, 0
482 ; CHECK-LABEL: @zext3(
483 ; CHECK-NEXT: ret i1 true
485 %e = zext i1 1 to i32
486 %c = icmp ne i32 %e, 0
490 define i1 @sext(i32 %x) {
491 ; CHECK-LABEL: @sext(
492 ; CHECK-NEXT: ret i1 true
494 %e1 = sext i32 %x to i64
495 %e2 = sext i32 %x to i64
496 %r = icmp eq i64 %e1, %e2
500 define i1 @sext2(i1 %x) {
501 ; CHECK-LABEL: @sext2(
502 ; CHECK-NEXT: ret i1 [[X:%.*]]
504 %e = sext i1 %x to i32
505 %c = icmp ne i32 %e, 0
510 ; CHECK-LABEL: @sext3(
511 ; CHECK-NEXT: ret i1 true
513 %e = sext i1 1 to i32
514 %c = icmp ne i32 %e, 0
518 define i1 @add(i32 %x, i32 %y) {
520 ; CHECK-NEXT: ret i1 false
526 %c = icmp eq i32 %s, 0
530 define i1 @addv(<2 x i32> %x, <2 x i32> %y) {
531 ; CHECK-LABEL: @addv(
532 ; CHECK-NEXT: ret i1 false
534 %l = lshr <2 x i32> %x, <i32 1, i32 0>
535 %q = lshr <2 x i32> %y, <i32 1, i32 0>
536 %r = or <2 x i32> %q, <i32 1, i32 0>
537 %s = add <2 x i32> %l, %r
538 %e = extractelement <2 x i32> %s, i32 0
539 %c = icmp eq i32 %e, 0
543 define i1 @add2(i8 %x, i8 %y) {
544 ; CHECK-LABEL: @add2(
545 ; CHECK-NEXT: ret i1 false
550 %c = icmp eq i8 %s, 0
554 define i1 @add2v(<2 x i8> %x, <2 x i8> %y) {
555 ; CHECK-LABEL: @add2v(
556 ; CHECK-NEXT: ret i1 false
558 %l = or <2 x i8> %x, <i8 0, i8 128>
559 %r = or <2 x i8> %y, <i8 0, i8 129>
560 %s = add <2 x i8> %l, %r
561 %e = extractelement <2 x i8> %s, i32 1
562 %c = icmp eq i8 %e, 0
566 define i1 @add3(i8 %x, i8 %y) {
567 ; CHECK-LABEL: @add3(
568 ; CHECK-NEXT: [[L:%.*]] = zext i8 [[X:%.*]] to i32
569 ; CHECK-NEXT: [[R:%.*]] = zext i8 [[Y:%.*]] to i32
570 ; CHECK-NEXT: [[S:%.*]] = add i32 [[L]], [[R]]
571 ; CHECK-NEXT: [[C:%.*]] = icmp eq i32 [[S]], 0
572 ; CHECK-NEXT: ret i1 [[C]]
574 %l = zext i8 %x to i32
575 %r = zext i8 %y to i32
577 %c = icmp eq i32 %s, 0
581 define i1 @add4(i32 %x, i32 %y) {
582 ; CHECK-LABEL: @add4(
583 ; CHECK-NEXT: ret i1 true
585 %z = add nsw i32 %y, 1
586 %s1 = add nsw i32 %x, %y
587 %s2 = add nsw i32 %x, %z
588 %c = icmp slt i32 %s1, %s2
592 define i1 @add5(i32 %x, i32 %y) {
593 ; CHECK-LABEL: @add5(
594 ; CHECK-NEXT: ret i1 true
596 %z = add nuw i32 %y, 1
597 %s1 = add nuw i32 %x, %z
598 %s2 = add nuw i32 %x, %y
599 %c = icmp ugt i32 %s1, %s2
603 define i1 @add6(i64 %A, i64 %B) {
604 ; CHECK-LABEL: @add6(
605 ; CHECK-NEXT: ret i1 true
609 %cmp = icmp eq i64 %s1, %s2
613 define i1 @addpowtwo(i32 %x, i32 %y) {
614 ; CHECK-LABEL: @addpowtwo(
615 ; CHECK-NEXT: ret i1 false
620 %c = icmp eq i32 %s, 0
624 define i1 @addpowtwov(<2 x i32> %x, <2 x i32> %y) {
625 ; CHECK-LABEL: @addpowtwov(
626 ; CHECK-NEXT: [[L:%.*]] = lshr <2 x i32> [[X:%.*]], <i32 1, i32 0>
627 ; CHECK-NEXT: [[R:%.*]] = shl <2 x i32> <i32 1, i32 0>, [[Y:%.*]]
628 ; CHECK-NEXT: [[S:%.*]] = add <2 x i32> [[L]], [[R]]
629 ; CHECK-NEXT: [[E:%.*]] = extractelement <2 x i32> [[S]], i32 0
630 ; CHECK-NEXT: [[C:%.*]] = icmp eq i32 [[E]], 0
631 ; CHECK-NEXT: ret i1 [[C]]
633 %l = lshr <2 x i32> %x, <i32 1, i32 0>
634 %r = shl <2 x i32> <i32 1, i32 0>, %y
635 %s = add <2 x i32> %l, %r
636 %e = extractelement <2 x i32> %s, i32 0
637 %c = icmp eq i32 %e, 0
641 define i1 @or(i32 %x) {
643 ; CHECK-NEXT: ret i1 false
646 %c = icmp eq i32 %o, 0
650 ; Do not simplify if we cannot guarantee that the ConstantExpr is a non-zero
652 @GV = common global ptr null
653 define i1 @or_constexp(i32 %x) {
654 ; CHECK-LABEL: @or_constexp(
656 ; CHECK-NEXT: [[TMP0:%.*]] = and i32 ptrtoint (ptr @GV to i32), 32
657 ; CHECK-NEXT: [[O:%.*]] = or i32 [[X:%.*]], [[TMP0]]
658 ; CHECK-NEXT: [[C:%.*]] = icmp eq i32 [[O]], 0
659 ; CHECK-NEXT: ret i1 [[C]]
662 %0 = and i32 ptrtoint (ptr @GV to i32), 32
664 %c = icmp eq i32 %o, 0
668 define i1 @shl1(i32 %x) {
669 ; CHECK-LABEL: @shl1(
670 ; CHECK-NEXT: ret i1 false
673 %c = icmp eq i32 %s, 0
677 define i1 @lshr1(i32 %x) {
678 ; CHECK-LABEL: @lshr1(
679 ; CHECK-NEXT: ret i1 false
682 %c = icmp eq i32 %s, 0
686 define i1 @lshr3(i32 %x) {
687 ; CHECK-LABEL: @lshr3(
688 ; CHECK-NEXT: ret i1 true
691 %c = icmp eq i32 %s, 0
695 define i1 @lshr4(i32 %X, i32 %Y) {
696 ; CHECK-LABEL: @lshr4(
697 ; CHECK-NEXT: ret i1 true
700 %C = icmp ule i32 %A, %X
704 define i1 @lshr5(i32 %X, i32 %Y) {
705 ; CHECK-LABEL: @lshr5(
706 ; CHECK-NEXT: ret i1 false
709 %C = icmp ugt i32 %A, %X
713 define i1 @lshr6(i32 %X, i32 %Y) {
714 ; CHECK-LABEL: @lshr6(
715 ; CHECK-NEXT: ret i1 false
718 %C = icmp ult i32 %X, %A
722 define i1 @lshr7(i32 %X, i32 %Y) {
723 ; CHECK-LABEL: @lshr7(
724 ; CHECK-NEXT: ret i1 true
727 %C = icmp uge i32 %X, %A
731 define i1 @lshr_nonzero_eq(i32 %x) {
732 ; CHECK-LABEL: @lshr_nonzero_eq(
733 ; CHECK-NEXT: [[X_NE_0:%.*]] = icmp ne i32 [[X:%.*]], 0
734 ; CHECK-NEXT: call void @llvm.assume(i1 [[X_NE_0]])
735 ; CHECK-NEXT: ret i1 false
737 %x_ne_0 = icmp ne i32 %x, 0
738 call void @llvm.assume(i1 %x_ne_0)
739 %lhs = lshr i32 %x, 1
740 %cmp = icmp eq i32 %lhs, %x
744 define i1 @lshr_nonzero_uge(i32 %x) {
745 ; CHECK-LABEL: @lshr_nonzero_uge(
746 ; CHECK-NEXT: [[X_NE_0:%.*]] = icmp ne i32 [[X:%.*]], 0
747 ; CHECK-NEXT: call void @llvm.assume(i1 [[X_NE_0]])
748 ; CHECK-NEXT: ret i1 false
750 %x_ne_0 = icmp ne i32 %x, 0
751 call void @llvm.assume(i1 %x_ne_0)
752 %lhs = lshr i32 %x, 1
753 %cmp = icmp uge i32 %lhs, %x
757 define i1 @lshr_nonzero_ne(i32 %x) {
758 ; CHECK-LABEL: @lshr_nonzero_ne(
759 ; CHECK-NEXT: [[X_NE_0:%.*]] = icmp ne i32 [[X:%.*]], 0
760 ; CHECK-NEXT: call void @llvm.assume(i1 [[X_NE_0]])
761 ; CHECK-NEXT: ret i1 true
763 %x_ne_0 = icmp ne i32 %x, 0
764 call void @llvm.assume(i1 %x_ne_0)
765 %lhs = lshr i32 %x, 1
766 %cmp = icmp ne i32 %lhs, %x
770 define i1 @lshr_nonzero_ult(i32 %x) {
771 ; CHECK-LABEL: @lshr_nonzero_ult(
772 ; CHECK-NEXT: [[X_NE_0:%.*]] = icmp ne i32 [[X:%.*]], 0
773 ; CHECK-NEXT: call void @llvm.assume(i1 [[X_NE_0]])
774 ; CHECK-NEXT: ret i1 true
776 %x_ne_0 = icmp ne i32 %x, 0
777 call void @llvm.assume(i1 %x_ne_0)
778 %lhs = lshr i32 %x, 1
779 %cmp = icmp ult i32 %lhs, %x
783 ; Negative test - unknown shift amount
784 define i1 @lshr_nonzero_neg_unknown(i32 %x, i32 %c) {
785 ; CHECK-LABEL: @lshr_nonzero_neg_unknown(
786 ; CHECK-NEXT: [[X_NE_0:%.*]] = icmp ne i32 [[X:%.*]], 0
787 ; CHECK-NEXT: call void @llvm.assume(i1 [[X_NE_0]])
788 ; CHECK-NEXT: [[LHS:%.*]] = lshr i32 [[X]], [[C:%.*]]
789 ; CHECK-NEXT: [[CMP:%.*]] = icmp ult i32 [[LHS]], [[X]]
790 ; CHECK-NEXT: ret i1 [[CMP]]
792 %x_ne_0 = icmp ne i32 %x, 0
793 call void @llvm.assume(i1 %x_ne_0)
794 %lhs = lshr i32 %x, %c
795 %cmp = icmp ult i32 %lhs, %x
799 ; Negative test - x may be zero
800 define i1 @lshr_nonzero_neg_maybe_zero(i32 %x) {
801 ; CHECK-LABEL: @lshr_nonzero_neg_maybe_zero(
802 ; CHECK-NEXT: [[LHS:%.*]] = lshr i32 [[X:%.*]], 1
803 ; CHECK-NEXT: [[CMP:%.*]] = icmp ult i32 [[LHS]], [[X]]
804 ; CHECK-NEXT: ret i1 [[CMP]]
806 %lhs = lshr i32 %x, 1
807 %cmp = icmp ult i32 %lhs, %x
811 ; Negative test - signed pred
812 define i1 @lshr_nonzero_neg_signed(i32 %x, i32 %c) {
813 ; CHECK-LABEL: @lshr_nonzero_neg_signed(
814 ; CHECK-NEXT: [[X_NE_0:%.*]] = icmp ne i32 [[X:%.*]], 0
815 ; CHECK-NEXT: call void @llvm.assume(i1 [[X_NE_0]])
816 ; CHECK-NEXT: [[LHS:%.*]] = lshr i32 [[X]], 1
817 ; CHECK-NEXT: [[CMP:%.*]] = icmp slt i32 [[LHS]], [[X]]
818 ; CHECK-NEXT: ret i1 [[CMP]]
820 %x_ne_0 = icmp ne i32 %x, 0
821 call void @llvm.assume(i1 %x_ne_0)
822 %lhs = lshr i32 %x, 1
823 %cmp = icmp slt i32 %lhs, %x
827 define i1 @ashr1(i32 %x) {
828 ; CHECK-LABEL: @ashr1(
829 ; CHECK-NEXT: ret i1 false
832 %c = icmp eq i32 %s, 0
836 define i1 @ashr3(i32 %x) {
837 ; CHECK-LABEL: @ashr3(
838 ; CHECK-NEXT: ret i1 true
841 %c = icmp eq i32 %s, 0
845 define i1 @select1(i1 %cond) {
846 ; CHECK-LABEL: @select1(
847 ; CHECK-NEXT: ret i1 [[COND:%.*]]
849 %s = select i1 %cond, i32 1, i32 0
850 %c = icmp eq i32 %s, 1
854 define i1 @select2(i1 %cond) {
855 ; CHECK-LABEL: @select2(
856 ; CHECK-NEXT: ret i1 [[COND:%.*]]
858 %x = zext i1 %cond to i32
859 %s = select i1 %cond, i32 %x, i32 0
860 %c = icmp ne i32 %s, 0
864 define i1 @select3(i1 %cond) {
865 ; CHECK-LABEL: @select3(
866 ; CHECK-NEXT: ret i1 [[COND:%.*]]
868 %x = zext i1 %cond to i32
869 %s = select i1 %cond, i32 1, i32 %x
870 %c = icmp ne i32 %s, 0
874 define i1 @select4(i1 %cond) {
875 ; CHECK-LABEL: @select4(
876 ; CHECK-NEXT: ret i1 [[COND:%.*]]
878 %invert = xor i1 %cond, 1
879 %s = select i1 %invert, i32 0, i32 1
880 %c = icmp ne i32 %s, 0
884 define i1 @select5(i32 %x) {
885 ; CHECK-LABEL: @select5(
886 ; CHECK-NEXT: ret i1 false
888 %c = icmp eq i32 %x, 0
889 %s = select i1 %c, i32 1, i32 %x
890 %c2 = icmp eq i32 %s, 0
894 define i1 @select6(i32 %x) {
895 ; CHECK-LABEL: @select6(
896 ; CHECK-NEXT: ret i1 false
898 %c = icmp sgt i32 %x, 0
899 %s = select i1 %c, i32 %x, i32 4
900 %c2 = icmp eq i32 %s, 0
904 define i1 @urem1(i32 %X, i32 %Y) {
905 ; CHECK-LABEL: @urem1(
906 ; CHECK-NEXT: ret i1 true
909 %B = icmp ult i32 %A, %Y
913 define i1 @urem2(i32 %X, i32 %Y) {
914 ; CHECK-LABEL: @urem2(
915 ; CHECK-NEXT: ret i1 false
918 %B = icmp eq i32 %A, %Y
922 define i1 @urem4(i32 %X) {
923 ; CHECK-LABEL: @urem4(
924 ; CHECK-NEXT: [[A:%.*]] = urem i32 [[X:%.*]], 15
925 ; CHECK-NEXT: [[B:%.*]] = icmp ult i32 [[A]], 10
926 ; CHECK-NEXT: ret i1 [[B]]
929 %B = icmp ult i32 %A, 10
933 define i1 @urem5(i16 %X, i32 %Y) {
934 ; CHECK-LABEL: @urem5(
935 ; CHECK-NEXT: [[A:%.*]] = zext i16 [[X:%.*]] to i32
936 ; CHECK-NEXT: [[B:%.*]] = urem i32 [[A]], [[Y:%.*]]
937 ; CHECK-NEXT: [[C:%.*]] = icmp slt i32 [[B]], [[Y]]
938 ; CHECK-NEXT: ret i1 [[C]]
940 %A = zext i16 %X to i32
942 %C = icmp slt i32 %B, %Y
946 define i1 @urem6(i32 %X, i32 %Y) {
947 ; CHECK-LABEL: @urem6(
948 ; CHECK-NEXT: ret i1 true
951 %B = icmp ugt i32 %Y, %A
955 define i1 @urem7(i32 %X) {
956 ; CHECK-LABEL: @urem7(
957 ; CHECK-NEXT: [[A:%.*]] = urem i32 1, [[X:%.*]]
958 ; CHECK-NEXT: [[B:%.*]] = icmp sgt i32 [[A]], [[X]]
959 ; CHECK-NEXT: ret i1 [[B]]
962 %B = icmp sgt i32 %A, %X
966 define i1 @urem8(i8 %X, i8 %Y) {
967 ; CHECK-LABEL: @urem8(
968 ; CHECK-NEXT: ret i1 true
971 %B = icmp ule i8 %A, %X
975 define i1 @urem9(i8 %X, i8 %Y) {
976 ; CHECK-LABEL: @urem9(
977 ; CHECK-NEXT: ret i1 false
980 %B = icmp ugt i8 %A, %X
984 define i1 @urem10(i8 %X, i8 %Y) {
985 ; CHECK-LABEL: @urem10(
986 ; CHECK-NEXT: ret i1 true
989 %B = icmp uge i8 %X, %A
993 define i1 @urem11(i8 %X, i8 %Y) {
994 ; CHECK-LABEL: @urem11(
995 ; CHECK-NEXT: ret i1 false
998 %B = icmp ult i8 %X, %A
1003 define i1 @srem2(i16 %X, i32 %Y) {
1004 ; CHECK-LABEL: @srem2(
1005 ; CHECK-NEXT: ret i1 false
1007 %A = zext i16 %X to i32
1008 %B = add nsw i32 %A, 1
1009 %C = srem i32 %B, %Y
1010 %D = icmp slt i32 %C, 0
1014 define i1 @srem2v(<2 x i16> %X, <2 x i32> %Y) {
1015 ; CHECK-LABEL: @srem2v(
1016 ; CHECK-NEXT: ret i1 false
1018 %A = zext <2 x i16> %X to <2 x i32>
1019 %B = add nsw <2 x i32> %A, <i32 1, i32 0>
1020 %C = srem <2 x i32> %B, %Y
1021 %D = extractelement <2 x i32> %C, i32 0
1022 %E = icmp slt i32 %D, 0
1026 define i1 @srem3(i16 %X, i32 %Y) {
1027 ; CHECK-LABEL: @srem3(
1028 ; CHECK-NEXT: ret i1 false
1030 %A = zext i16 %X to i32
1031 %B = or i32 2147483648, %A
1032 %C = sub nsw i32 1, %B
1033 %D = srem i32 %C, %Y
1034 %E = icmp slt i32 %D, 0
1038 define i1 @srem3v(<2 x i16> %X, <2 x i32> %Y) {
1039 ; CHECK-LABEL: @srem3v(
1040 ; CHECK-NEXT: ret i1 false
1042 %A = zext <2 x i16> %X to <2 x i32>
1043 %B = or <2 x i32> <i32 1, i32 2147483648>, %A
1044 %C = sub nsw <2 x i32> <i32 0, i32 1>, %B
1045 %D = srem <2 x i32> %C, %Y
1046 %E = extractelement <2 x i32> %C, i32 1
1047 %F = icmp slt i32 %E, 0
1051 define i1 @udiv2(i32 %Z) {
1052 ; CHECK-LABEL: @udiv2(
1053 ; CHECK-NEXT: ret i1 true
1055 %A = udiv exact i32 10, %Z
1056 %B = udiv exact i32 20, %Z
1057 %C = icmp ult i32 %A, %B
1061 ; Exact sdiv and equality preds can simplify.
1063 define i1 @sdiv_exact_equality(i32 %Z) {
1064 ; CHECK-LABEL: @sdiv_exact_equality(
1065 ; CHECK-NEXT: ret i1 false
1067 %A = sdiv exact i32 10, %Z
1068 %B = sdiv exact i32 20, %Z
1069 %C = icmp eq i32 %A, %B
1073 ; But not other preds: PR32949 - https://bugs.llvm.org/show_bug.cgi?id=32949
1075 define i1 @sdiv_exact_not_equality(i32 %Z) {
1076 ; CHECK-LABEL: @sdiv_exact_not_equality(
1077 ; CHECK-NEXT: [[A:%.*]] = sdiv exact i32 10, [[Z:%.*]]
1078 ; CHECK-NEXT: [[B:%.*]] = sdiv exact i32 20, [[Z]]
1079 ; CHECK-NEXT: [[C:%.*]] = icmp ult i32 [[A]], [[B]]
1080 ; CHECK-NEXT: ret i1 [[C]]
1082 %A = sdiv exact i32 10, %Z
1083 %B = sdiv exact i32 20, %Z
1084 %C = icmp ult i32 %A, %B
1088 define i1 @udiv3(i32 %X, i32 %Y) {
1089 ; CHECK-LABEL: @udiv3(
1090 ; CHECK-NEXT: ret i1 false
1092 %A = udiv i32 %X, %Y
1093 %C = icmp ugt i32 %A, %X
1097 define i1 @udiv4(i32 %X, i32 %Y) {
1098 ; CHECK-LABEL: @udiv4(
1099 ; CHECK-NEXT: ret i1 true
1101 %A = udiv i32 %X, %Y
1102 %C = icmp ule i32 %A, %X
1107 define i1 @udiv6(i32 %X) nounwind {
1108 ; CHECK-LABEL: @udiv6(
1109 ; CHECK-NEXT: [[A:%.*]] = udiv i32 1, [[X:%.*]]
1110 ; CHECK-NEXT: [[C:%.*]] = icmp eq i32 [[A]], 0
1111 ; CHECK-NEXT: ret i1 [[C]]
1114 %C = icmp eq i32 %A, 0
1118 define i1 @udiv7(i32 %X, i32 %Y) {
1119 ; CHECK-LABEL: @udiv7(
1120 ; CHECK-NEXT: ret i1 false
1122 %A = udiv i32 %X, %Y
1123 %C = icmp ult i32 %X, %A
1127 define i1 @udiv8(i32 %X, i32 %Y) {
1128 ; CHECK-LABEL: @udiv8(
1129 ; CHECK-NEXT: ret i1 true
1131 %A = udiv i32 %X, %Y
1132 %C = icmp uge i32 %X, %A
1136 define i1 @udiv_nonzero_eq(i32 %x) {
1137 ; CHECK-LABEL: @udiv_nonzero_eq(
1138 ; CHECK-NEXT: [[X_NE_0:%.*]] = icmp ne i32 [[X:%.*]], 0
1139 ; CHECK-NEXT: call void @llvm.assume(i1 [[X_NE_0]])
1140 ; CHECK-NEXT: ret i1 false
1142 %x_ne_0 = icmp ne i32 %x, 0
1143 call void @llvm.assume(i1 %x_ne_0)
1144 %lhs = udiv i32 %x, 3
1145 %cmp = icmp eq i32 %lhs, %x
1149 define i1 @udiv_nonzero_uge(i32 %x) {
1150 ; CHECK-LABEL: @udiv_nonzero_uge(
1151 ; CHECK-NEXT: [[X_NE_0:%.*]] = icmp ne i32 [[X:%.*]], 0
1152 ; CHECK-NEXT: call void @llvm.assume(i1 [[X_NE_0]])
1153 ; CHECK-NEXT: ret i1 false
1155 %x_ne_0 = icmp ne i32 %x, 0
1156 call void @llvm.assume(i1 %x_ne_0)
1157 %lhs = udiv i32 %x, 3
1158 %cmp = icmp uge i32 %lhs, %x
1162 define i1 @udiv_nonzero_ne(i32 %x) {
1163 ; CHECK-LABEL: @udiv_nonzero_ne(
1164 ; CHECK-NEXT: [[X_NE_0:%.*]] = icmp ne i32 [[X:%.*]], 0
1165 ; CHECK-NEXT: call void @llvm.assume(i1 [[X_NE_0]])
1166 ; CHECK-NEXT: ret i1 true
1168 %x_ne_0 = icmp ne i32 %x, 0
1169 call void @llvm.assume(i1 %x_ne_0)
1170 %lhs = udiv i32 %x, 3
1171 %cmp = icmp ne i32 %lhs, %x
1175 define i1 @udiv_nonzero_ult(i32 %x) {
1176 ; CHECK-LABEL: @udiv_nonzero_ult(
1177 ; CHECK-NEXT: [[X_NE_0:%.*]] = icmp ne i32 [[X:%.*]], 0
1178 ; CHECK-NEXT: call void @llvm.assume(i1 [[X_NE_0]])
1179 ; CHECK-NEXT: ret i1 true
1181 %x_ne_0 = icmp ne i32 %x, 0
1182 call void @llvm.assume(i1 %x_ne_0)
1183 %lhs = udiv i32 %x, 3
1184 %cmp = icmp ult i32 %lhs, %x
1188 ; Negative test - unknown divisor
1189 define i1 @udiv_nonzero_neg_unknown(i32 %x, i32 %c) {
1190 ; CHECK-LABEL: @udiv_nonzero_neg_unknown(
1191 ; CHECK-NEXT: [[X_NE_0:%.*]] = icmp ne i32 [[X:%.*]], 0
1192 ; CHECK-NEXT: call void @llvm.assume(i1 [[X_NE_0]])
1193 ; CHECK-NEXT: [[LHS:%.*]] = udiv i32 [[X]], [[C:%.*]]
1194 ; CHECK-NEXT: [[CMP:%.*]] = icmp ult i32 [[LHS]], [[X]]
1195 ; CHECK-NEXT: ret i1 [[CMP]]
1197 %x_ne_0 = icmp ne i32 %x, 0
1198 call void @llvm.assume(i1 %x_ne_0)
1199 %lhs = udiv i32 %x, %c
1200 %cmp = icmp ult i32 %lhs, %x
1204 ; Negative test - x may be zero
1205 define i1 @udiv_nonzero_neg_maybe_zero(i32 %x) {
1206 ; CHECK-LABEL: @udiv_nonzero_neg_maybe_zero(
1207 ; CHECK-NEXT: [[LHS:%.*]] = udiv i32 [[X:%.*]], 3
1208 ; CHECK-NEXT: [[CMP:%.*]] = icmp ult i32 [[LHS]], [[X]]
1209 ; CHECK-NEXT: ret i1 [[CMP]]
1211 %lhs = udiv i32 %x, 3
1212 %cmp = icmp ult i32 %lhs, %x
1216 ; Negative test - signed pred
1217 define i1 @udiv_nonzero_neg_signed(i32 %x) {
1218 ; CHECK-LABEL: @udiv_nonzero_neg_signed(
1219 ; CHECK-NEXT: [[X_NE_0:%.*]] = icmp ne i32 [[X:%.*]], 0
1220 ; CHECK-NEXT: call void @llvm.assume(i1 [[X_NE_0]])
1221 ; CHECK-NEXT: [[LHS:%.*]] = udiv i32 [[X]], 3
1222 ; CHECK-NEXT: [[CMP:%.*]] = icmp slt i32 [[LHS]], [[X]]
1223 ; CHECK-NEXT: ret i1 [[CMP]]
1225 %x_ne_0 = icmp ne i32 %x, 0
1226 call void @llvm.assume(i1 %x_ne_0)
1227 %lhs = udiv i32 %x, 3
1228 %cmp = icmp slt i32 %lhs, %x
1232 ; Square of a non-zero number is non-zero if there is no overflow.
1233 define i1 @mul1(i32 %X) {
1234 ; CHECK-LABEL: @mul1(
1235 ; CHECK-NEXT: ret i1 false
1238 %M = mul nuw i32 %Y, %Y
1239 %C = icmp eq i32 %M, 0
1243 define i1 @mul1v(<2 x i32> %X) {
1244 ; CHECK-LABEL: @mul1v(
1245 ; CHECK-NEXT: ret i1 false
1247 %Y = or <2 x i32> %X, <i32 1, i32 0>
1248 %M = mul nuw <2 x i32> %Y, %Y
1249 %E = extractelement <2 x i32> %M, i32 0
1250 %C = icmp eq i32 %E, 0
1254 ; Square of a non-zero number is positive if there is no signed overflow.
1255 define i1 @mul2(i32 %X) {
1256 ; CHECK-LABEL: @mul2(
1257 ; CHECK-NEXT: ret i1 true
1260 %M = mul nsw i32 %Y, %Y
1261 %C = icmp sgt i32 %M, 0
1265 define i1 @mul2v(<2 x i32> %X) {
1266 ; CHECK-LABEL: @mul2v(
1267 ; CHECK-NEXT: ret i1 true
1269 %Y = or <2 x i32> %X, <i32 0, i32 1>
1270 %M = mul nsw <2 x i32> %Y, %Y
1271 %E = extractelement <2 x i32> %M, i32 1
1272 %C = icmp sgt i32 %E, 0
1276 ; Product of non-negative numbers is non-negative if there is no signed overflow.
1277 define i1 @mul3(i32 %X, i32 %Y) {
1278 ; CHECK-LABEL: @mul3(
1279 ; CHECK-NEXT: ret i1 true
1281 %XX = mul nsw i32 %X, %X
1282 %YY = mul nsw i32 %Y, %Y
1283 %M = mul nsw i32 %XX, %YY
1284 %C = icmp sge i32 %M, 0
1288 define <2 x i1> @mul3v(<2 x i32> %X, <2 x i32> %Y) {
1289 ; CHECK-LABEL: @mul3v(
1290 ; CHECK-NEXT: ret <2 x i1> <i1 true, i1 true>
1292 %XX = mul nsw <2 x i32> %X, %X
1293 %YY = mul nsw <2 x i32> %Y, %Y
1294 %M = mul nsw <2 x i32> %XX, %YY
1295 %C = icmp sge <2 x i32> %M, zeroinitializer
1299 define <2 x i1> @vectorselect1(<2 x i1> %cond) {
1300 ; CHECK-LABEL: @vectorselect1(
1301 ; CHECK-NEXT: ret <2 x i1> [[COND:%.*]]
1303 %invert = xor <2 x i1> %cond, <i1 1, i1 1>
1304 %s = select <2 x i1> %invert, <2 x i32> <i32 0, i32 0>, <2 x i32> <i32 1, i32 1>
1305 %c = icmp ne <2 x i32> %s, <i32 0, i32 0>
1310 define <2 x i1> @vectorselectcrash(i32 %arg1) {
1311 ; CHECK-LABEL: @vectorselectcrash(
1312 ; CHECK-NEXT: [[TOBOOL40:%.*]] = icmp ne i32 [[ARG1:%.*]], 0
1313 ; CHECK-NEXT: [[COND43:%.*]] = select i1 [[TOBOOL40]], <2 x i16> <i16 -5, i16 66>, <2 x i16> <i16 46, i16 1>
1314 ; CHECK-NEXT: [[CMP45:%.*]] = icmp ugt <2 x i16> [[COND43]], <i16 73, i16 21>
1315 ; CHECK-NEXT: ret <2 x i1> [[CMP45]]
1317 %tobool40 = icmp ne i32 %arg1, 0
1318 %cond43 = select i1 %tobool40, <2 x i16> <i16 -5, i16 66>, <2 x i16> <i16 46, i16 1>
1319 %cmp45 = icmp ugt <2 x i16> %cond43, <i16 73, i16 21>
1324 define i1 @alloca_compare(i64 %idx) {
1325 ; CHECK-LABEL: @alloca_compare(
1326 ; CHECK-NEXT: ret i1 false
1328 %sv = alloca { i32, i32, [124 x i32] }
1329 %1 = getelementptr inbounds { i32, i32, [124 x i32] }, ptr %sv, i32 0, i32 2, i64 %idx
1330 %2 = icmp eq ptr %1, null
1334 define i1 @alloca_compare_no_null_opt(i64 %idx) #0 {
1335 ; CHECK-LABEL: @alloca_compare_no_null_opt(
1336 ; CHECK-NEXT: [[SV:%.*]] = alloca { i32, i32, [124 x i32] }, align 8
1337 ; CHECK-NEXT: [[CMP:%.*]] = getelementptr inbounds { i32, i32, [124 x i32] }, ptr [[SV]], i32 0, i32 2, i64 [[IDX:%.*]]
1338 ; CHECK-NEXT: [[X:%.*]] = icmp eq ptr [[CMP]], null
1339 ; CHECK-NEXT: ret i1 [[X]]
1341 %sv = alloca { i32, i32, [124 x i32] }
1342 %cmp = getelementptr inbounds { i32, i32, [124 x i32] }, ptr %sv, i32 0, i32 2, i64 %idx
1343 %X = icmp eq ptr %cmp, null
1347 define i1 @infinite_gep() {
1348 ; CHECK-LABEL: @infinite_gep(
1349 ; CHECK-NEXT: ret i1 true
1350 ; CHECK: unreachableblock:
1351 ; CHECK-NEXT: [[X:%.*]] = getelementptr i32, ptr [[X]], i32 1
1352 ; CHECK-NEXT: [[Y:%.*]] = icmp eq ptr [[X]], null
1353 ; CHECK-NEXT: ret i1 [[Y]]
1358 %X = getelementptr i32, ptr%X, i32 1
1359 %Y = icmp eq ptr %X, null
1363 ; It's not valid to fold a comparison of an argument with an alloca, even though
1364 ; that's tempting. An argument can't *alias* an alloca, however the aliasing rule
1365 ; relies on restrictions against guessing an object's address and dereferencing.
1366 ; There are no restrictions against guessing an object's address and comparing.
1368 define i1 @alloca_argument_compare(ptr %arg) {
1369 ; CHECK-LABEL: @alloca_argument_compare(
1370 ; CHECK-NEXT: [[ALLOC:%.*]] = alloca i64, align 8
1371 ; CHECK-NEXT: [[CMP:%.*]] = icmp eq ptr [[ARG:%.*]], [[ALLOC]]
1372 ; CHECK-NEXT: ret i1 [[CMP]]
1375 %cmp = icmp eq ptr %arg, %alloc
1379 ; As above, but with the operands reversed.
1381 define i1 @alloca_argument_compare_swapped(ptr %arg) {
1382 ; CHECK-LABEL: @alloca_argument_compare_swapped(
1383 ; CHECK-NEXT: [[ALLOC:%.*]] = alloca i64, align 8
1384 ; CHECK-NEXT: [[CMP:%.*]] = icmp eq ptr [[ALLOC]], [[ARG:%.*]]
1385 ; CHECK-NEXT: ret i1 [[CMP]]
1388 %cmp = icmp eq ptr %alloc, %arg
1392 ; Don't assume that a noalias argument isn't equal to a global variable's
1393 ; address. This is an example where AliasAnalysis' NoAlias concept is
1394 ; different from actual pointer inequality.
1396 @y = external global i32
1397 define zeroext i1 @external_compare(ptr noalias %x) {
1398 ; CHECK-LABEL: @external_compare(
1399 ; CHECK-NEXT: [[CMP:%.*]] = icmp eq ptr [[X:%.*]], @y
1400 ; CHECK-NEXT: ret i1 [[CMP]]
1402 %cmp = icmp eq ptr %x, @y
1406 define i1 @alloca_gep(i64 %a, i64 %b) {
1407 ; CHECK-LABEL: @alloca_gep(
1408 ; CHECK-NEXT: ret i1 false
1410 ; We can prove this GEP is non-null because it is inbounds and the pointer
1412 %strs = alloca [1000 x [1001 x i8]], align 16
1413 %x = getelementptr inbounds [1000 x [1001 x i8]], ptr %strs, i64 0, i64 %a, i64 %b
1414 %cmp = icmp eq ptr %x, null
1418 define i1 @alloca_gep_no_null_opt(i64 %a, i64 %b) #0 {
1419 ; CHECK-LABEL: @alloca_gep_no_null_opt(
1420 ; CHECK-NEXT: [[STRS:%.*]] = alloca [1000 x [1001 x i8]], align 16
1421 ; CHECK-NEXT: [[X:%.*]] = getelementptr inbounds [1000 x [1001 x i8]], ptr [[STRS]], i64 0, i64 [[A:%.*]], i64 [[B:%.*]]
1422 ; CHECK-NEXT: [[CMP:%.*]] = icmp eq ptr [[X]], null
1423 ; CHECK-NEXT: ret i1 [[CMP]]
1425 ; We can't prove this GEP is non-null.
1426 %strs = alloca [1000 x [1001 x i8]], align 16
1427 %x = getelementptr inbounds [1000 x [1001 x i8]], ptr %strs, i64 0, i64 %a, i64 %b
1428 %cmp = icmp eq ptr %x, null
1432 define i1 @non_inbounds_gep_compare(ptr %a) {
1433 ; CHECK-LABEL: @non_inbounds_gep_compare(
1434 ; CHECK-NEXT: ret i1 true
1436 ; Equality compares with non-inbounds GEPs can be folded.
1437 %x = getelementptr i64, ptr %a, i64 42
1438 %y = getelementptr inbounds i64, ptr %x, i64 -42
1439 %z = getelementptr i64, ptr %a, i64 -42
1440 %w = getelementptr inbounds i64, ptr %z, i64 42
1441 %cmp = icmp eq ptr %y, %w
1445 define i1 @non_inbounds_gep_compare2(ptr %a) {
1446 ; CHECK-LABEL: @non_inbounds_gep_compare2(
1447 ; CHECK-NEXT: ret i1 true
1449 ; Equality compares with non-inbounds GEPs can be folded.
1450 %x = getelementptr i64, ptr %a, i64 4294967297
1451 %y = getelementptr i64, ptr %a, i64 1
1452 %cmp = icmp eq ptr %y, %y
1456 define i1 @compare_always_true_slt(i16 %a) {
1457 ; CHECK-LABEL: @compare_always_true_slt(
1458 ; CHECK-NEXT: ret i1 true
1460 %t1 = zext i16 %a to i32
1461 %t2 = sub i32 0, %t1
1462 %t3 = icmp slt i32 %t2, 1
1466 define <2 x i1> @compare_always_true_slt_splat(<2 x i16> %a) {
1467 ; CHECK-LABEL: @compare_always_true_slt_splat(
1468 ; CHECK-NEXT: ret <2 x i1> <i1 true, i1 true>
1470 %t1 = zext <2 x i16> %a to <2 x i32>
1471 %t2 = sub <2 x i32> zeroinitializer, %t1
1472 %t3 = icmp slt <2 x i32> %t2, <i32 1, i32 1>
1476 define i1 @compare_always_true_sle(i16 %a) {
1477 ; CHECK-LABEL: @compare_always_true_sle(
1478 ; CHECK-NEXT: ret i1 true
1480 %t1 = zext i16 %a to i32
1481 %t2 = sub i32 0, %t1
1482 %t3 = icmp sle i32 %t2, 0
1486 define <2 x i1> @compare_always_true_sle_splat(<2 x i16> %a) {
1487 ; CHECK-LABEL: @compare_always_true_sle_splat(
1488 ; CHECK-NEXT: ret <2 x i1> <i1 true, i1 true>
1490 %t1 = zext <2 x i16> %a to <2 x i32>
1491 %t2 = sub <2 x i32> zeroinitializer, %t1
1492 %t3 = icmp sle <2 x i32> %t2, zeroinitializer
1496 define i1 @compare_always_false_sgt(i16 %a) {
1497 ; CHECK-LABEL: @compare_always_false_sgt(
1498 ; CHECK-NEXT: ret i1 false
1500 %t1 = zext i16 %a to i32
1501 %t2 = sub i32 0, %t1
1502 %t3 = icmp sgt i32 %t2, 0
1506 define <2 x i1> @compare_always_false_sgt_splat(<2 x i16> %a) {
1507 ; CHECK-LABEL: @compare_always_false_sgt_splat(
1508 ; CHECK-NEXT: ret <2 x i1> zeroinitializer
1510 %t1 = zext <2 x i16> %a to <2 x i32>
1511 %t2 = sub <2 x i32> zeroinitializer, %t1
1512 %t3 = icmp sgt <2 x i32> %t2, zeroinitializer
1516 define i1 @compare_always_false_sge(i16 %a) {
1517 ; CHECK-LABEL: @compare_always_false_sge(
1518 ; CHECK-NEXT: ret i1 false
1520 %t1 = zext i16 %a to i32
1521 %t2 = sub i32 0, %t1
1522 %t3 = icmp sge i32 %t2, 1
1526 define <2 x i1> @compare_always_false_sge_splat(<2 x i16> %a) {
1527 ; CHECK-LABEL: @compare_always_false_sge_splat(
1528 ; CHECK-NEXT: ret <2 x i1> zeroinitializer
1530 %t1 = zext <2 x i16> %a to <2 x i32>
1531 %t2 = sub <2 x i32> zeroinitializer, %t1
1532 %t3 = icmp sge <2 x i32> %t2, <i32 1, i32 1>
1536 define i1 @compare_always_false_eq(i16 %a) {
1537 ; CHECK-LABEL: @compare_always_false_eq(
1538 ; CHECK-NEXT: ret i1 false
1540 %t1 = zext i16 %a to i32
1541 %t2 = sub i32 0, %t1
1542 %t3 = icmp eq i32 %t2, 1
1546 define <2 x i1> @compare_always_false_eq_splat(<2 x i16> %a) {
1547 ; CHECK-LABEL: @compare_always_false_eq_splat(
1548 ; CHECK-NEXT: ret <2 x i1> zeroinitializer
1550 %t1 = zext <2 x i16> %a to <2 x i32>
1551 %t2 = sub <2 x i32> zeroinitializer, %t1
1552 %t3 = icmp eq <2 x i32> %t2, <i32 1, i32 1>
1556 define i1 @compare_always_true_ne(i16 %a) {
1557 ; CHECK-LABEL: @compare_always_true_ne(
1558 ; CHECK-NEXT: ret i1 true
1560 %t1 = zext i16 %a to i32
1561 %t2 = sub i32 0, %t1
1562 %t3 = icmp ne i32 %t2, 1
1566 define <2 x i1> @compare_always_true_ne_splat(<2 x i16> %a) {
1567 ; CHECK-LABEL: @compare_always_true_ne_splat(
1568 ; CHECK-NEXT: ret <2 x i1> <i1 true, i1 true>
1570 %t1 = zext <2 x i16> %a to <2 x i32>
1571 %t2 = sub <2 x i32> zeroinitializer, %t1
1572 %t3 = icmp ne <2 x i32> %t2, <i32 1, i32 1>
1576 define i1 @lshr_ugt_false(i32 %a) {
1577 ; CHECK-LABEL: @lshr_ugt_false(
1578 ; CHECK-NEXT: ret i1 false
1580 %shr = lshr i32 1, %a
1581 %cmp = icmp ugt i32 %shr, 1
1585 define i1 @nonnull_arg(ptr nonnull %i) {
1586 ; CHECK-LABEL: @nonnull_arg(
1587 ; CHECK-NEXT: ret i1 false
1589 %cmp = icmp eq ptr %i, null
1593 define i1 @nonnull_arg_no_null_opt(ptr nonnull %i) #0 {
1594 ; CHECK-LABEL: @nonnull_arg_no_null_opt(
1595 ; CHECK-NEXT: ret i1 false
1597 %cmp = icmp eq ptr %i, null
1601 define i1 @nonnull_deref_arg(ptr dereferenceable(4) %i) {
1602 ; CHECK-LABEL: @nonnull_deref_arg(
1603 ; CHECK-NEXT: ret i1 false
1605 %cmp = icmp eq ptr %i, null
1609 define i1 @nonnull_deref_arg_no_null_opt(ptr dereferenceable(4) %i) #0 {
1610 ; CHECK-LABEL: @nonnull_deref_arg_no_null_opt(
1611 ; CHECK-NEXT: [[CMP:%.*]] = icmp eq ptr [[I:%.*]], null
1612 ; CHECK-NEXT: ret i1 [[CMP]]
1614 %cmp = icmp eq ptr %i, null
1617 define i1 @nonnull_deref_as_arg(ptr addrspace(1) dereferenceable(4) %i) {
1618 ; CHECK-LABEL: @nonnull_deref_as_arg(
1619 ; CHECK-NEXT: [[CMP:%.*]] = icmp eq ptr addrspace(1) [[I:%.*]], null
1620 ; CHECK-NEXT: ret i1 [[CMP]]
1622 %cmp = icmp eq ptr addrspace(1) %i, null
1626 declare nonnull ptr @returns_nonnull_helper()
1627 define i1 @returns_nonnull() {
1628 ; CHECK-LABEL: @returns_nonnull(
1629 ; CHECK-NEXT: [[CALL:%.*]] = call nonnull ptr @returns_nonnull_helper()
1630 ; CHECK-NEXT: ret i1 false
1632 %call = call nonnull ptr @returns_nonnull_helper()
1633 %cmp = icmp eq ptr %call, null
1637 declare dereferenceable(4) ptr @returns_nonnull_deref_helper()
1638 define i1 @returns_nonnull_deref() {
1639 ; CHECK-LABEL: @returns_nonnull_deref(
1640 ; CHECK-NEXT: [[CALL:%.*]] = call dereferenceable(4) ptr @returns_nonnull_deref_helper()
1641 ; CHECK-NEXT: ret i1 false
1643 %call = call dereferenceable(4) ptr @returns_nonnull_deref_helper()
1644 %cmp = icmp eq ptr %call, null
1648 define i1 @returns_nonnull_deref_no_null_opt () #0 {
1649 ; CHECK-LABEL: @returns_nonnull_deref_no_null_opt(
1650 ; CHECK-NEXT: [[CALL:%.*]] = call dereferenceable(4) ptr @returns_nonnull_deref_helper()
1651 ; CHECK-NEXT: [[CMP:%.*]] = icmp eq ptr [[CALL]], null
1652 ; CHECK-NEXT: ret i1 [[CMP]]
1654 %call = call dereferenceable(4) ptr @returns_nonnull_deref_helper()
1655 %cmp = icmp eq ptr %call, null
1659 declare dereferenceable(4) ptr addrspace(1) @returns_nonnull_deref_as_helper()
1660 define i1 @returns_nonnull_as_deref() {
1661 ; CHECK-LABEL: @returns_nonnull_as_deref(
1662 ; CHECK-NEXT: [[CALL:%.*]] = call dereferenceable(4) ptr addrspace(1) @returns_nonnull_deref_as_helper()
1663 ; CHECK-NEXT: [[CMP:%.*]] = icmp eq ptr addrspace(1) [[CALL]], null
1664 ; CHECK-NEXT: ret i1 [[CMP]]
1666 %call = call dereferenceable(4) ptr addrspace(1) @returns_nonnull_deref_as_helper()
1667 %cmp = icmp eq ptr addrspace(1) %call, null
1671 define i1 @nonnull_load(ptr %addr) {
1672 ; CHECK-LABEL: @nonnull_load(
1673 ; CHECK-NEXT: ret i1 false
1675 %ptr = load ptr, ptr %addr, !nonnull !{}
1676 %cmp = icmp eq ptr %ptr, null
1680 define i1 @nonnull_load_as_outer(ptr addrspace(1) %addr) {
1681 ; CHECK-LABEL: @nonnull_load_as_outer(
1682 ; CHECK-NEXT: ret i1 false
1684 %ptr = load ptr, ptr addrspace(1) %addr, !nonnull !{}
1685 %cmp = icmp eq ptr %ptr, null
1688 define i1 @nonnull_load_as_inner(ptr %addr) {
1689 ; CHECK-LABEL: @nonnull_load_as_inner(
1690 ; CHECK-NEXT: ret i1 false
1692 %ptr = load ptr addrspace(1), ptr %addr, !nonnull !{}
1693 %cmp = icmp eq ptr addrspace(1) %ptr, null
1697 ; If a bit is known to be zero for A and known to be one for B,
1698 ; then A and B cannot be equal.
1699 define i1 @icmp_eq_const(i32 %a) {
1700 ; CHECK-LABEL: @icmp_eq_const(
1701 ; CHECK-NEXT: ret i1 false
1703 %b = mul nsw i32 %a, -2
1704 %c = icmp eq i32 %b, 1
1708 define <2 x i1> @icmp_eq_const_vec(<2 x i32> %a) {
1709 ; CHECK-LABEL: @icmp_eq_const_vec(
1710 ; CHECK-NEXT: ret <2 x i1> zeroinitializer
1712 %b = mul nsw <2 x i32> %a, <i32 -2, i32 -2>
1713 %c = icmp eq <2 x i32> %b, <i32 1, i32 1>
1717 define i1 @icmp_ne_const(i32 %a) {
1718 ; CHECK-LABEL: @icmp_ne_const(
1719 ; CHECK-NEXT: ret i1 true
1721 %b = mul nsw i32 %a, -2
1722 %c = icmp ne i32 %b, 1
1726 define <2 x i1> @icmp_ne_const_vec(<2 x i32> %a) {
1727 ; CHECK-LABEL: @icmp_ne_const_vec(
1728 ; CHECK-NEXT: ret <2 x i1> <i1 true, i1 true>
1730 %b = mul nsw <2 x i32> %a, <i32 -2, i32 -2>
1731 %c = icmp ne <2 x i32> %b, <i32 1, i32 1>
1735 define i1 @icmp_sdiv_int_min(i32 %a) {
1736 ; CHECK-LABEL: @icmp_sdiv_int_min(
1737 ; CHECK-NEXT: [[DIV:%.*]] = sdiv i32 -2147483648, [[A:%.*]]
1738 ; CHECK-NEXT: [[CMP:%.*]] = icmp ne i32 [[DIV]], -1073741824
1739 ; CHECK-NEXT: ret i1 [[CMP]]
1741 %div = sdiv i32 -2147483648, %a
1742 %cmp = icmp ne i32 %div, -1073741824
1747 define i1 @icmp_sdiv_pr20288(i64 %a) {
1748 ; CHECK-LABEL: @icmp_sdiv_pr20288(
1749 ; CHECK-NEXT: [[DIV:%.*]] = sdiv i64 [[A:%.*]], -8589934592
1750 ; CHECK-NEXT: [[CMP:%.*]] = icmp ne i64 [[DIV]], 1073741824
1751 ; CHECK-NEXT: ret i1 [[CMP]]
1753 %div = sdiv i64 %a, -8589934592
1754 %cmp = icmp ne i64 %div, 1073741824
1759 define i1 @icmp_sdiv_neg1(i64 %a) {
1760 ; CHECK-LABEL: @icmp_sdiv_neg1(
1761 ; CHECK-NEXT: [[DIV:%.*]] = sdiv i64 [[A:%.*]], -1
1762 ; CHECK-NEXT: [[CMP:%.*]] = icmp ne i64 [[DIV]], 1073741824
1763 ; CHECK-NEXT: ret i1 [[CMP]]
1765 %div = sdiv i64 %a, -1
1766 %cmp = icmp ne i64 %div, 1073741824
1771 define i1 @icmp_known_bits(i4 %x, i4 %y) {
1772 ; CHECK-LABEL: @icmp_known_bits(
1773 ; CHECK-NEXT: ret i1 false
1775 %and1 = and i4 %y, -7
1776 %and2 = and i4 %x, -7
1777 %or1 = or i4 %and1, 2
1778 %or2 = or i4 %and2, 2
1779 %add = add i4 %or1, %or2
1780 %cmp = icmp eq i4 %add, 0
1784 define i1 @icmp_known_bits_vec(<2 x i4> %x, <2 x i4> %y) {
1785 ; CHECK-LABEL: @icmp_known_bits_vec(
1786 ; CHECK-NEXT: ret i1 false
1788 %and1 = and <2 x i4> %y, <i4 -7, i4 -1>
1789 %and2 = and <2 x i4> %x, <i4 -7, i4 -1>
1790 %or1 = or <2 x i4> %and1, <i4 2, i4 2>
1791 %or2 = or <2 x i4> %and2, <i4 2, i4 2>
1792 %add = add <2 x i4> %or1, %or2
1793 %ext = extractelement <2 x i4> %add,i32 0
1794 %cmp = icmp eq i4 %ext, 0
1798 define i1 @icmp_shl_nuw_1(i64 %a) {
1799 ; CHECK-LABEL: @icmp_shl_nuw_1(
1800 ; CHECK-NEXT: ret i1 true
1802 %shl = shl nuw i64 1, %a
1803 %cmp = icmp ne i64 %shl, 0
1807 define i1 @icmp_shl_1_V_ugt_2147483648(i32 %V) {
1808 ; CHECK-LABEL: @icmp_shl_1_V_ugt_2147483648(
1809 ; CHECK-NEXT: ret i1 false
1811 %shl = shl i32 1, %V
1812 %cmp = icmp ugt i32 %shl, 2147483648
1816 define <2 x i1> @icmp_shl_1_ugt_signmask(<2 x i8> %V) {
1817 ; CHECK-LABEL: @icmp_shl_1_ugt_signmask(
1818 ; CHECK-NEXT: ret <2 x i1> zeroinitializer
1820 %shl = shl <2 x i8> <i8 1, i8 1>, %V
1821 %cmp = icmp ugt <2 x i8> %shl, <i8 128, i8 128>
1825 define <2 x i1> @icmp_shl_1_ugt_signmask_poison(<2 x i8> %V) {
1826 ; CHECK-LABEL: @icmp_shl_1_ugt_signmask_poison(
1827 ; CHECK-NEXT: ret <2 x i1> zeroinitializer
1829 %shl = shl <2 x i8> <i8 1, i8 1>, %V
1830 %cmp = icmp ugt <2 x i8> %shl, <i8 128, i8 poison>
1834 define <2 x i1> @icmp_shl_1_ugt_signmask_poison2(<2 x i8> %V) {
1835 ; CHECK-LABEL: @icmp_shl_1_ugt_signmask_poison2(
1836 ; CHECK-NEXT: ret <2 x i1> zeroinitializer
1838 %shl = shl <2 x i8> <i8 1, i8 poison>, %V
1839 %cmp = icmp ugt <2 x i8> %shl, <i8 poison, i8 128>
1843 define i1 @icmp_shl_1_V_ule_2147483648(i32 %V) {
1844 ; CHECK-LABEL: @icmp_shl_1_V_ule_2147483648(
1845 ; CHECK-NEXT: ret i1 true
1847 %shl = shl i32 1, %V
1848 %cmp = icmp ule i32 %shl, 2147483648
1852 define <2 x i1> @icmp_shl_1_ule_signmask(<2 x i8> %V) {
1853 ; CHECK-LABEL: @icmp_shl_1_ule_signmask(
1854 ; CHECK-NEXT: ret <2 x i1> <i1 true, i1 true>
1856 %shl = shl <2 x i8> <i8 1, i8 1>, %V
1857 %cmp = icmp ule <2 x i8> %shl, <i8 128, i8 128>
1861 define <2 x i1> @icmp_shl_1_ule_signmask_poison(<2 x i8> %V) {
1862 ; CHECK-LABEL: @icmp_shl_1_ule_signmask_poison(
1863 ; CHECK-NEXT: ret <2 x i1> <i1 true, i1 true>
1865 %shl = shl <2 x i8> <i8 1, i8 1>, %V
1866 %cmp = icmp ule <2 x i8> %shl, <i8 128, i8 poison>
1870 define <2 x i1> @icmp_shl_1_ule_signmask_poison2(<2 x i8> %V) {
1871 ; CHECK-LABEL: @icmp_shl_1_ule_signmask_poison2(
1872 ; CHECK-NEXT: ret <2 x i1> <i1 true, i1 true>
1874 %shl = shl <2 x i8> <i8 1, i8 poison>, %V
1875 %cmp = icmp ule <2 x i8> %shl, <i8 poison, i8 128>
1879 define i1 @shl_1_cmp_eq_nonpow2(i32 %x) {
1880 ; CHECK-LABEL: @shl_1_cmp_eq_nonpow2(
1881 ; CHECK-NEXT: ret i1 false
1884 %c = icmp eq i32 %s, 31
1888 define <2 x i1> @shl_1_cmp_eq_nonpow2_splat(<2 x i32> %x) {
1889 ; CHECK-LABEL: @shl_1_cmp_eq_nonpow2_splat(
1890 ; CHECK-NEXT: ret <2 x i1> zeroinitializer
1892 %s = shl <2 x i32> <i32 1, i32 1>, %x
1893 %c = icmp eq <2 x i32> %s, <i32 31, i32 31>
1897 define <2 x i1> @shl_1_cmp_eq_nonpow2_splat_poison(<2 x i32> %x) {
1898 ; CHECK-LABEL: @shl_1_cmp_eq_nonpow2_splat_poison(
1899 ; CHECK-NEXT: ret <2 x i1> zeroinitializer
1901 %s = shl <2 x i32> <i32 1, i32 1>, %x
1902 %c = icmp eq <2 x i32> %s, <i32 31, i32 poison>
1906 define i1 @shl_1_cmp_ne_nonpow2(i32 %x) {
1907 ; CHECK-LABEL: @shl_1_cmp_ne_nonpow2(
1908 ; CHECK-NEXT: ret i1 true
1911 %c = icmp ne i32 %s, 42
1915 define <2 x i1> @shl_1_cmp_ne_nonpow2_splat(<2 x i32> %x) {
1916 ; CHECK-LABEL: @shl_1_cmp_ne_nonpow2_splat(
1917 ; CHECK-NEXT: ret <2 x i1> <i1 true, i1 true>
1919 %s = shl <2 x i32> <i32 1, i32 1>, %x
1920 %c = icmp ne <2 x i32> %s, <i32 42, i32 42>
1924 define <2 x i1> @shl_1_cmp_ne_nonpow2_splat_poison(<2 x i32> %x) {
1925 ; CHECK-LABEL: @shl_1_cmp_ne_nonpow2_splat_poison(
1926 ; CHECK-NEXT: ret <2 x i1> <i1 true, i1 true>
1928 %s = shl <2 x i32> <i32 poison, i32 1>, %x
1929 %c = icmp ne <2 x i32> %s, <i32 42, i32 poison>
1933 define i1 @shl_pow2_cmp_eq_nonpow2(i32 %x) {
1934 ; CHECK-LABEL: @shl_pow2_cmp_eq_nonpow2(
1935 ; CHECK-NEXT: ret i1 false
1938 %c = icmp eq i32 %s, 31
1942 define <2 x i1> @shl_pow21_cmp_ne_nonpow2_splat_poison(<2 x i32> %x) {
1943 ; CHECK-LABEL: @shl_pow21_cmp_ne_nonpow2_splat_poison(
1944 ; CHECK-NEXT: ret <2 x i1> <i1 true, i1 true>
1946 %s = shl <2 x i32> <i32 poison, i32 4>, %x
1947 %c = icmp ne <2 x i32> %s, <i32 31, i32 poison>
1951 ; Negative test - overflowing shift could be zero.
1953 define i1 @shl_pow2_cmp_ne_zero(i32 %x) {
1954 ; CHECK-LABEL: @shl_pow2_cmp_ne_zero(
1955 ; CHECK-NEXT: [[S:%.*]] = shl i32 16, [[X:%.*]]
1956 ; CHECK-NEXT: [[C:%.*]] = icmp ne i32 [[S]], 0
1957 ; CHECK-NEXT: ret i1 [[C]]
1960 %c = icmp ne i32 %s, 0
1964 ; Negative test - overflowing shift could be zero.
1966 define <2 x i1> @shl_pow2_cmp_ne_zero_splat(<2 x i32> %x) {
1967 ; CHECK-LABEL: @shl_pow2_cmp_ne_zero_splat(
1968 ; CHECK-NEXT: [[S:%.*]] = shl <2 x i32> <i32 16, i32 16>, [[X:%.*]]
1969 ; CHECK-NEXT: [[C:%.*]] = icmp ne <2 x i32> [[S]], zeroinitializer
1970 ; CHECK-NEXT: ret <2 x i1> [[C]]
1972 %s = shl <2 x i32> <i32 16, i32 16>, %x
1973 %c = icmp ne <2 x i32> %s, zeroinitializer
1977 define i1 @shl_pow2_cmp_eq_zero_nuw(i32 %x) {
1978 ; CHECK-LABEL: @shl_pow2_cmp_eq_zero_nuw(
1979 ; CHECK-NEXT: ret i1 false
1981 %s = shl nuw i32 16, %x
1982 %c = icmp eq i32 %s, 0
1986 define <2 x i1> @shl_pow2_cmp_ne_zero_nuw_splat_poison(<2 x i32> %x) {
1987 ; CHECK-LABEL: @shl_pow2_cmp_ne_zero_nuw_splat_poison(
1988 ; CHECK-NEXT: ret <2 x i1> <i1 true, i1 true>
1990 %s = shl nuw <2 x i32> <i32 16, i32 poison>, %x
1991 %c = icmp ne <2 x i32> %s, <i32 poison, i32 0>
1995 define i1 @shl_pow2_cmp_ne_zero_nsw(i32 %x) {
1996 ; CHECK-LABEL: @shl_pow2_cmp_ne_zero_nsw(
1997 ; CHECK-NEXT: ret i1 true
1999 %s = shl nsw i32 16, %x
2000 %c = icmp ne i32 %s, 0
2004 define <2 x i1> @shl_pow2_cmp_eq_zero_nsw_splat_poison(<2 x i32> %x) {
2005 ; CHECK-LABEL: @shl_pow2_cmp_eq_zero_nsw_splat_poison(
2006 ; CHECK-NEXT: ret <2 x i1> zeroinitializer
2008 %s = shl nsw <2 x i32> <i32 poison, i32 16>, %x
2009 %c = icmp eq <2 x i32> %s, <i32 0, i32 poison>
2013 define i1 @tautological1(i32 %A, i32 %B) {
2014 ; CHECK-LABEL: @tautological1(
2015 ; CHECK-NEXT: ret i1 false
2018 %D = icmp ugt i32 %C, %A
2022 define i1 @tautological2(i32 %A, i32 %B) {
2023 ; CHECK-LABEL: @tautological2(
2024 ; CHECK-NEXT: ret i1 true
2027 %D = icmp ule i32 %C, %A
2031 define i1 @tautological3(i32 %A, i32 %B) {
2032 ; CHECK-LABEL: @tautological3(
2033 ; CHECK-NEXT: ret i1 true
2036 %D = icmp ule i32 %A, %C
2040 define i1 @tautological4(i32 %A, i32 %B) {
2041 ; CHECK-LABEL: @tautological4(
2042 ; CHECK-NEXT: ret i1 false
2045 %D = icmp ugt i32 %A, %C
2049 define i1 @tautological5(i32 %A, i32 %B) {
2050 ; CHECK-LABEL: @tautological5(
2051 ; CHECK-NEXT: ret i1 false
2054 %D = icmp ult i32 %C, %A
2058 define i1 @tautological6(i32 %A, i32 %B) {
2059 ; CHECK-LABEL: @tautological6(
2060 ; CHECK-NEXT: ret i1 true
2063 %D = icmp uge i32 %C, %A
2067 define i1 @tautological7(i32 %A, i32 %B) {
2068 ; CHECK-LABEL: @tautological7(
2069 ; CHECK-NEXT: ret i1 true
2072 %D = icmp uge i32 %A, %C
2076 define i1 @tautological8(i32 %A, i32 %B) {
2077 ; CHECK-LABEL: @tautological8(
2078 ; CHECK-NEXT: ret i1 false
2081 %D = icmp ult i32 %A, %C
2085 define i1 @tautological9(i32 %A) {
2086 ; CHECK-LABEL: @tautological9(
2087 ; CHECK-NEXT: ret i1 false
2091 %D = icmp ugt i32 %C1, %C2
2095 define <2 x i1> @tautological9_vec(<2 x i32> %A) {
2096 ; CHECK-LABEL: @tautological9_vec(
2097 ; CHECK-NEXT: ret <2 x i1> zeroinitializer
2099 %C1 = and <2 x i32> %A, <i32 1, i32 1>
2100 %C2 = and <2 x i32> %A, <i32 3, i32 3>
2101 %D = icmp ugt <2 x i32> %C1, %C2
2105 define i1 @tautological10(i32 %A) {
2106 ; CHECK-LABEL: @tautological10(
2107 ; CHECK-NEXT: ret i1 true
2111 %D = icmp ule i32 %C1, %C2
2115 define i1 @tautological11(i32 %A) {
2116 ; CHECK-LABEL: @tautological11(
2117 ; CHECK-NEXT: ret i1 true
2121 %D = icmp ule i32 %C1, %C2
2125 define i1 @tautological12(i32 %A) {
2126 ; CHECK-LABEL: @tautological12(
2127 ; CHECK-NEXT: ret i1 false
2131 %D = icmp ugt i32 %C1, %C2
2135 define i1 @tautological13(i32 %A) {
2136 ; CHECK-LABEL: @tautological13(
2137 ; CHECK-NEXT: ret i1 false
2141 %D = icmp ult i32 %C2, %C1
2145 define i1 @tautological14(i32 %A) {
2146 ; CHECK-LABEL: @tautological14(
2147 ; CHECK-NEXT: ret i1 true
2151 %D = icmp uge i32 %C2, %C1
2155 define i1 @tautological15(i32 %A) {
2156 ; CHECK-LABEL: @tautological15(
2157 ; CHECK-NEXT: ret i1 true
2161 %D = icmp uge i32 %C2, %C1
2165 define i1 @tautological16(i32 %A) {
2166 ; CHECK-LABEL: @tautological16(
2167 ; CHECK-NEXT: ret i1 false
2171 %D = icmp ult i32 %C2, %C1
2175 define i1 @tautological9_negative(i32 %A) {
2176 ; CHECK-LABEL: @tautological9_negative(
2177 ; CHECK-NEXT: [[C1:%.*]] = and i32 [[A:%.*]], 1
2178 ; CHECK-NEXT: [[C2:%.*]] = and i32 [[A]], 2
2179 ; CHECK-NEXT: [[D:%.*]] = icmp ugt i32 [[C1]], [[C2]]
2180 ; CHECK-NEXT: ret i1 [[D]]
2184 %D = icmp ugt i32 %C1, %C2
2188 define i1 @tautological10_negative(i32 %A) {
2189 ; CHECK-LABEL: @tautological10_negative(
2190 ; CHECK-NEXT: [[C1:%.*]] = and i32 [[A:%.*]], 1
2191 ; CHECK-NEXT: [[C2:%.*]] = and i32 [[A]], 2
2192 ; CHECK-NEXT: [[D:%.*]] = icmp ule i32 [[C1]], [[C2]]
2193 ; CHECK-NEXT: ret i1 [[D]]
2197 %D = icmp ule i32 %C1, %C2
2201 define i1 @tautological11_negative(i32 %A) {
2202 ; CHECK-LABEL: @tautological11_negative(
2203 ; CHECK-NEXT: [[C1:%.*]] = or i32 [[A:%.*]], 1
2204 ; CHECK-NEXT: [[C2:%.*]] = or i32 [[A]], 2
2205 ; CHECK-NEXT: [[D:%.*]] = icmp ule i32 [[C1]], [[C2]]
2206 ; CHECK-NEXT: ret i1 [[D]]
2210 %D = icmp ule i32 %C1, %C2
2214 define i1 @tautological12_negative(i32 %A) {
2215 ; CHECK-LABEL: @tautological12_negative(
2216 ; CHECK-NEXT: [[C1:%.*]] = or i32 [[A:%.*]], 1
2217 ; CHECK-NEXT: [[C2:%.*]] = or i32 [[A]], 2
2218 ; CHECK-NEXT: [[D:%.*]] = icmp ugt i32 [[C1]], [[C2]]
2219 ; CHECK-NEXT: ret i1 [[D]]
2223 %D = icmp ugt i32 %C1, %C2
2227 define i1 @tautological13_negative(i32 %A) {
2228 ; CHECK-LABEL: @tautological13_negative(
2229 ; CHECK-NEXT: [[C1:%.*]] = or i32 [[A:%.*]], 1
2230 ; CHECK-NEXT: [[C2:%.*]] = or i32 [[A]], 2
2231 ; CHECK-NEXT: [[D:%.*]] = icmp ult i32 [[C2]], [[C1]]
2232 ; CHECK-NEXT: ret i1 [[D]]
2236 %D = icmp ult i32 %C2, %C1
2240 define i1 @tautological14_negative(i32 %A) {
2241 ; CHECK-LABEL: @tautological14_negative(
2242 ; CHECK-NEXT: [[C1:%.*]] = or i32 [[A:%.*]], 1
2243 ; CHECK-NEXT: [[C2:%.*]] = or i32 [[A]], 2
2244 ; CHECK-NEXT: [[D:%.*]] = icmp uge i32 [[C2]], [[C1]]
2245 ; CHECK-NEXT: ret i1 [[D]]
2249 %D = icmp uge i32 %C2, %C1
2253 define i1 @tautological15_negative(i32 %A) {
2254 ; CHECK-LABEL: @tautological15_negative(
2255 ; CHECK-NEXT: [[C1:%.*]] = and i32 [[A:%.*]], 1
2256 ; CHECK-NEXT: [[C2:%.*]] = and i32 [[A]], 2
2257 ; CHECK-NEXT: [[D:%.*]] = icmp uge i32 [[C2]], [[C1]]
2258 ; CHECK-NEXT: ret i1 [[D]]
2262 %D = icmp uge i32 %C2, %C1
2266 define i1 @tautological16_negative(i32 %A) {
2267 ; CHECK-LABEL: @tautological16_negative(
2268 ; CHECK-NEXT: [[C1:%.*]] = and i32 [[A:%.*]], 1
2269 ; CHECK-NEXT: [[C2:%.*]] = and i32 [[A]], 2
2270 ; CHECK-NEXT: [[D:%.*]] = icmp ult i32 [[C2]], [[C1]]
2271 ; CHECK-NEXT: ret i1 [[D]]
2275 %D = icmp ult i32 %C2, %C1
2279 define i1 @tautological17_subset1(i32 %A) {
2280 ; CHECK-LABEL: @tautological17_subset1(
2281 ; CHECK-NEXT: ret i1 false
2285 %D = icmp sgt i32 %C1, %C2
2289 define i1 @tautological17_subset2(i32 %A) {
2290 ; CHECK-LABEL: @tautological17_subset2(
2291 ; CHECK-NEXT: ret i1 false
2293 %C1 = and i32 %A, -4
2294 %C2 = and i32 %A, -3
2295 %D = icmp sgt i32 %C1, %C2
2299 define i1 @tautological17_negative(i32 %A) {
2300 ; CHECK-LABEL: @tautological17_negative(
2301 ; CHECK-NEXT: [[C1:%.*]] = and i32 [[A:%.*]], 1
2302 ; CHECK-NEXT: [[C2:%.*]] = and i32 [[A]], -3
2303 ; CHECK-NEXT: [[D:%.*]] = icmp sgt i32 [[C1]], [[C2]]
2304 ; CHECK-NEXT: ret i1 [[D]]
2307 %C2 = and i32 %A, -3
2308 %D = icmp sgt i32 %C1, %C2
2312 define i1 @tautological18_subset1(i32 %A) {
2313 ; CHECK-LABEL: @tautological18_subset1(
2314 ; CHECK-NEXT: ret i1 true
2318 %D = icmp sle i32 %C1, %C2
2322 define i1 @tautological18_subset2(i32 %A) {
2323 ; CHECK-LABEL: @tautological18_subset2(
2324 ; CHECK-NEXT: ret i1 true
2326 %C1 = and i32 %A, -4
2327 %C2 = and i32 %A, -3
2328 %D = icmp sle i32 %C1, %C2
2332 define i1 @tautological18_negative(i32 %A) {
2333 ; CHECK-LABEL: @tautological18_negative(
2334 ; CHECK-NEXT: [[C1:%.*]] = and i32 [[A:%.*]], 1
2335 ; CHECK-NEXT: [[C2:%.*]] = and i32 [[A]], -3
2336 ; CHECK-NEXT: [[D:%.*]] = icmp sle i32 [[C1]], [[C2]]
2337 ; CHECK-NEXT: ret i1 [[D]]
2340 %C2 = and i32 %A, -3
2341 %D = icmp sle i32 %C1, %C2
2345 define i1 @tautological19_subset1(i32 %A) {
2346 ; CHECK-LABEL: @tautological19_subset1(
2347 ; CHECK-NEXT: ret i1 false
2351 %D = icmp sgt i32 %C1, %C2
2355 define i1 @tautological19_subset2(i32 %A) {
2356 ; CHECK-LABEL: @tautological19_subset2(
2357 ; CHECK-NEXT: ret i1 false
2359 %C1 = and i32 %A, -4
2360 %C2 = and i32 %A, -3
2361 %D = icmp sgt i32 %C1, %C2
2365 define i1 @tautological19_negative(i32 %A) {
2366 ; CHECK-LABEL: @tautological19_negative(
2367 ; CHECK-NEXT: [[C1:%.*]] = and i32 [[A:%.*]], 1
2368 ; CHECK-NEXT: [[C2:%.*]] = and i32 [[A]], -3
2369 ; CHECK-NEXT: [[D:%.*]] = icmp sgt i32 [[C1]], [[C2]]
2370 ; CHECK-NEXT: ret i1 [[D]]
2373 %C2 = and i32 %A, -3
2374 %D = icmp sgt i32 %C1, %C2
2378 define i1 @tautological20_subset1(i32 %A) {
2379 ; CHECK-LABEL: @tautological20_subset1(
2380 ; CHECK-NEXT: ret i1 true
2384 %D = icmp sle i32 %C1, %C2
2388 define i1 @tautological20_subset2(i32 %A) {
2389 ; CHECK-LABEL: @tautological20_subset2(
2390 ; CHECK-NEXT: ret i1 true
2392 %C1 = and i32 %A, -4
2393 %C2 = and i32 %A, -3
2394 %D = icmp sle i32 %C1, %C2
2398 define i1 @tautological20_negative(i32 %A) {
2399 ; CHECK-LABEL: @tautological20_negative(
2400 ; CHECK-NEXT: [[C1:%.*]] = and i32 [[A:%.*]], 1
2401 ; CHECK-NEXT: [[C2:%.*]] = and i32 [[A]], -3
2402 ; CHECK-NEXT: [[D:%.*]] = icmp sle i32 [[C1]], [[C2]]
2403 ; CHECK-NEXT: ret i1 [[D]]
2406 %C2 = and i32 %A, -3
2407 %D = icmp sle i32 %C1, %C2
2411 declare void @helper_i1(i1)
2412 ; Series of tests for icmp s[lt|ge] (or A, B), A and icmp s[gt|le] A, (or A, B)
2413 define void @icmp_slt_sge_or(i32 %Ax, i32 %Bx) {
2414 ; 'p' for positive, 'n' for negative, 'x' for potentially either.
2415 ; %D is 'icmp slt (or A, B), A'
2416 ; %E is 'icmp sge (or A, B), A' making it the not of %D
2417 ; %F is 'icmp sgt A, (or A, B)' making it the same as %D
2418 ; %G is 'icmp sle A, (or A, B)' making it the not of %D
2419 ; CHECK-LABEL: @icmp_slt_sge_or(
2420 ; CHECK-NEXT: [[APOS:%.*]] = and i32 [[AX:%.*]], 2147483647
2421 ; CHECK-NEXT: [[BNEG:%.*]] = or i32 [[BX:%.*]], -2147483648
2422 ; CHECK-NEXT: [[CPX:%.*]] = or i32 [[APOS]], [[BX]]
2423 ; CHECK-NEXT: [[DPX:%.*]] = icmp slt i32 [[CPX]], [[APOS]]
2424 ; CHECK-NEXT: [[EPX:%.*]] = icmp sge i32 [[CPX]], [[APOS]]
2425 ; CHECK-NEXT: [[FPX:%.*]] = icmp sgt i32 [[APOS]], [[CPX]]
2426 ; CHECK-NEXT: [[GPX:%.*]] = icmp sle i32 [[APOS]], [[CPX]]
2427 ; CHECK-NEXT: [[CXX:%.*]] = or i32 [[AX]], [[BX]]
2428 ; CHECK-NEXT: [[DXX:%.*]] = icmp slt i32 [[CXX]], [[AX]]
2429 ; CHECK-NEXT: [[EXX:%.*]] = icmp sge i32 [[CXX]], [[AX]]
2430 ; CHECK-NEXT: [[FXX:%.*]] = icmp sgt i32 [[AX]], [[CXX]]
2431 ; CHECK-NEXT: [[GXX:%.*]] = icmp sle i32 [[AX]], [[CXX]]
2432 ; CHECK-NEXT: [[CXN:%.*]] = or i32 [[AX]], [[BNEG]]
2433 ; CHECK-NEXT: [[DXN:%.*]] = icmp slt i32 [[CXN]], [[AX]]
2434 ; CHECK-NEXT: [[EXN:%.*]] = icmp sge i32 [[CXN]], [[AX]]
2435 ; CHECK-NEXT: [[FXN:%.*]] = icmp sgt i32 [[AX]], [[CXN]]
2436 ; CHECK-NEXT: [[GXN:%.*]] = icmp sle i32 [[AX]], [[CXN]]
2437 ; CHECK-NEXT: call void @helper_i1(i1 false)
2438 ; CHECK-NEXT: call void @helper_i1(i1 true)
2439 ; CHECK-NEXT: call void @helper_i1(i1 false)
2440 ; CHECK-NEXT: call void @helper_i1(i1 true)
2441 ; CHECK-NEXT: call void @helper_i1(i1 [[DPX]])
2442 ; CHECK-NEXT: call void @helper_i1(i1 [[EPX]])
2443 ; CHECK-NEXT: call void @helper_i1(i1 [[FPX]])
2444 ; CHECK-NEXT: call void @helper_i1(i1 [[GPX]])
2445 ; CHECK-NEXT: call void @helper_i1(i1 true)
2446 ; CHECK-NEXT: call void @helper_i1(i1 false)
2447 ; CHECK-NEXT: call void @helper_i1(i1 true)
2448 ; CHECK-NEXT: call void @helper_i1(i1 false)
2449 ; CHECK-NEXT: call void @helper_i1(i1 false)
2450 ; CHECK-NEXT: call void @helper_i1(i1 true)
2451 ; CHECK-NEXT: call void @helper_i1(i1 false)
2452 ; CHECK-NEXT: call void @helper_i1(i1 true)
2453 ; CHECK-NEXT: call void @helper_i1(i1 [[DXX]])
2454 ; CHECK-NEXT: call void @helper_i1(i1 [[EXX]])
2455 ; CHECK-NEXT: call void @helper_i1(i1 [[FXX]])
2456 ; CHECK-NEXT: call void @helper_i1(i1 [[GXX]])
2457 ; CHECK-NEXT: call void @helper_i1(i1 [[DXN]])
2458 ; CHECK-NEXT: call void @helper_i1(i1 [[EXN]])
2459 ; CHECK-NEXT: call void @helper_i1(i1 [[FXN]])
2460 ; CHECK-NEXT: call void @helper_i1(i1 [[GXN]])
2461 ; CHECK-NEXT: call void @helper_i1(i1 false)
2462 ; CHECK-NEXT: call void @helper_i1(i1 true)
2463 ; CHECK-NEXT: call void @helper_i1(i1 false)
2464 ; CHECK-NEXT: call void @helper_i1(i1 true)
2465 ; CHECK-NEXT: call void @helper_i1(i1 false)
2466 ; CHECK-NEXT: call void @helper_i1(i1 true)
2467 ; CHECK-NEXT: call void @helper_i1(i1 false)
2468 ; CHECK-NEXT: call void @helper_i1(i1 true)
2469 ; CHECK-NEXT: call void @helper_i1(i1 false)
2470 ; CHECK-NEXT: call void @helper_i1(i1 true)
2471 ; CHECK-NEXT: call void @helper_i1(i1 false)
2472 ; CHECK-NEXT: call void @helper_i1(i1 true)
2473 ; CHECK-NEXT: ret void
2475 %Aneg = or i32 %Ax, 2147483648
2476 %Apos = and i32 %Ax, 2147483647
2477 %Bneg = or i32 %Bx, 2147483648
2478 %Bpos = and i32 %Bx, 2147483647
2480 %Cpp = or i32 %Apos, %Bpos
2481 %Dpp = icmp slt i32 %Cpp, %Apos
2482 %Epp = icmp sge i32 %Cpp, %Apos
2483 %Fpp = icmp sgt i32 %Apos, %Cpp
2484 %Gpp = icmp sle i32 %Apos, %Cpp
2485 %Cpx = or i32 %Apos, %Bx
2486 %Dpx = icmp slt i32 %Cpx, %Apos
2487 %Epx = icmp sge i32 %Cpx, %Apos
2488 %Fpx = icmp sgt i32 %Apos, %Cpx
2489 %Gpx = icmp sle i32 %Apos, %Cpx
2490 %Cpn = or i32 %Apos, %Bneg
2491 %Dpn = icmp slt i32 %Cpn, %Apos
2492 %Epn = icmp sge i32 %Cpn, %Apos
2493 %Fpn = icmp sgt i32 %Apos, %Cpn
2494 %Gpn = icmp sle i32 %Apos, %Cpn
2496 %Cxp = or i32 %Ax, %Bpos
2497 %Dxp = icmp slt i32 %Cxp, %Ax
2498 %Exp = icmp sge i32 %Cxp, %Ax
2499 %Fxp = icmp sgt i32 %Ax, %Cxp
2500 %Gxp = icmp sle i32 %Ax, %Cxp
2501 %Cxx = or i32 %Ax, %Bx
2502 %Dxx = icmp slt i32 %Cxx, %Ax
2503 %Exx = icmp sge i32 %Cxx, %Ax
2504 %Fxx = icmp sgt i32 %Ax, %Cxx
2505 %Gxx = icmp sle i32 %Ax, %Cxx
2506 %Cxn = or i32 %Ax, %Bneg
2507 %Dxn = icmp slt i32 %Cxn, %Ax
2508 %Exn = icmp sge i32 %Cxn, %Ax
2509 %Fxn = icmp sgt i32 %Ax, %Cxn
2510 %Gxn = icmp sle i32 %Ax, %Cxn
2512 %Cnp = or i32 %Aneg, %Bpos
2513 %Dnp = icmp slt i32 %Cnp, %Aneg
2514 %Enp = icmp sge i32 %Cnp, %Aneg
2515 %Fnp = icmp sgt i32 %Aneg, %Cnp
2516 %Gnp = icmp sle i32 %Aneg, %Cnp
2517 %Cnx = or i32 %Aneg, %Bx
2518 %Dnx = icmp slt i32 %Cnx, %Aneg
2519 %Enx = icmp sge i32 %Cnx, %Aneg
2520 %Fnx = icmp sgt i32 %Aneg, %Cnx
2521 %Gnx = icmp sle i32 %Aneg, %Cnx
2522 %Cnn = or i32 %Aneg, %Bneg
2523 %Dnn = icmp slt i32 %Cnn, %Aneg
2524 %Enn = icmp sge i32 %Cnn, %Aneg
2525 %Fnn = icmp sgt i32 %Aneg, %Cnn
2526 %Gnn = icmp sle i32 %Aneg, %Cnn
2528 call void @helper_i1(i1 %Dpp)
2529 call void @helper_i1(i1 %Epp)
2530 call void @helper_i1(i1 %Fpp)
2531 call void @helper_i1(i1 %Gpp)
2532 call void @helper_i1(i1 %Dpx)
2533 call void @helper_i1(i1 %Epx)
2534 call void @helper_i1(i1 %Fpx)
2535 call void @helper_i1(i1 %Gpx)
2536 call void @helper_i1(i1 %Dpn)
2537 call void @helper_i1(i1 %Epn)
2538 call void @helper_i1(i1 %Fpn)
2539 call void @helper_i1(i1 %Gpn)
2540 call void @helper_i1(i1 %Dxp)
2541 call void @helper_i1(i1 %Exp)
2542 call void @helper_i1(i1 %Fxp)
2543 call void @helper_i1(i1 %Gxp)
2544 call void @helper_i1(i1 %Dxx)
2545 call void @helper_i1(i1 %Exx)
2546 call void @helper_i1(i1 %Fxx)
2547 call void @helper_i1(i1 %Gxx)
2548 call void @helper_i1(i1 %Dxn)
2549 call void @helper_i1(i1 %Exn)
2550 call void @helper_i1(i1 %Fxn)
2551 call void @helper_i1(i1 %Gxn)
2552 call void @helper_i1(i1 %Dnp)
2553 call void @helper_i1(i1 %Enp)
2554 call void @helper_i1(i1 %Fnp)
2555 call void @helper_i1(i1 %Gnp)
2556 call void @helper_i1(i1 %Dnx)
2557 call void @helper_i1(i1 %Enx)
2558 call void @helper_i1(i1 %Fnx)
2559 call void @helper_i1(i1 %Gnx)
2560 call void @helper_i1(i1 %Dnn)
2561 call void @helper_i1(i1 %Enn)
2562 call void @helper_i1(i1 %Fnn)
2563 call void @helper_i1(i1 %Gnn)
2567 define i1 @constant_fold_inttoptr_null() {
2568 ; CHECK-LABEL: @constant_fold_inttoptr_null(
2569 ; CHECK-NEXT: ret i1 false
2571 %x = icmp eq ptr inttoptr (i64 32 to ptr), null
2575 define i1 @constant_fold_null_inttoptr() {
2576 ; CHECK-LABEL: @constant_fold_null_inttoptr(
2577 ; CHECK-NEXT: ret i1 false
2579 %x = icmp eq ptr null, inttoptr (i64 32 to ptr)
2583 define i1 @cmp_through_addrspacecast(ptr addrspace(1) %p1) {
2584 ; CHECK-LABEL: @cmp_through_addrspacecast(
2585 ; CHECK-NEXT: ret i1 true
2587 %p0 = addrspacecast ptr addrspace(1) %p1 to ptr
2588 %p0.1 = getelementptr inbounds i32, ptr %p0, i64 1
2589 %cmp = icmp ne ptr %p0, %p0.1
2593 ; Test simplifications for: icmp (X+Y), (X+Z) -> icmp Y,Z
2594 ; Test the overflow check when the RHS has NSW set and constant Z is greater
2595 ; than Y, then we know X+Y also can't overflow.
2597 define i1 @icmp_nsw_1(i32 %V) {
2598 ; CHECK-LABEL: @icmp_nsw_1(
2599 ; CHECK-NEXT: ret i1 true
2601 %add5 = add i32 %V, 5
2602 %add6 = add nsw i32 %V, 6
2603 %s1 = sext i32 %add5 to i64
2604 %s2 = sext i32 %add6 to i64
2605 %cmp = icmp slt i64 %s1, %s2
2609 define i1 @icmp_nsw_2(i32 %V) {
2610 ; CHECK-LABEL: @icmp_nsw_2(
2611 ; CHECK-NEXT: ret i1 true
2613 %add5 = add i32 %V, 5
2614 %add6 = add nsw i32 %V, 6
2615 %cmp = icmp slt i32 %add5, %add6
2619 define i1 @icmp_nsw_22(i32 %V) {
2620 ; CHECK-LABEL: @icmp_nsw_22(
2621 ; CHECK-NEXT: ret i1 true
2623 %add5 = add nsw i32 %V, 5
2624 %add6 = add nsw i32 %V, 6
2625 %cmp = icmp slt i32 %add5, %add6
2629 define i1 @icmp_nsw_23(i32 %V) {
2630 ; CHECK-LABEL: @icmp_nsw_23(
2631 ; CHECK-NEXT: [[ADD5:%.*]] = add nsw i32 [[V:%.*]], 5
2632 ; CHECK-NEXT: [[ADD6:%.*]] = add i32 [[V]], 6
2633 ; CHECK-NEXT: [[CMP:%.*]] = icmp slt i32 [[ADD5]], [[ADD6]]
2634 ; CHECK-NEXT: ret i1 [[CMP]]
2636 %add5 = add nsw i32 %V, 5
2637 %add6 = add i32 %V, 6
2638 %cmp = icmp slt i32 %add5, %add6
2642 define i1 @icmp_nsw_false(i32 %V) {
2643 ; CHECK-LABEL: @icmp_nsw_false(
2644 ; CHECK-NEXT: ret i1 false
2646 %add5 = add nsw i32 %V, 6
2647 %add6 = add i32 %V, 5
2648 %cmp = icmp slt i32 %add5, %add6
2652 define i1 @icmp_nsw_false_2(i32 %V) {
2653 ; CHECK-LABEL: @icmp_nsw_false_2(
2654 ; CHECK-NEXT: ret i1 false
2656 %add5 = add nsw i32 %V, 6
2657 %add6 = add nsw i32 %V, 5
2658 %cmp = icmp slt i32 %add5, %add6
2662 define i1 @icmp_nsw_false_3(i32 %V) {
2663 ; CHECK-LABEL: @icmp_nsw_false_3(
2664 ; CHECK-NEXT: [[ADD5:%.*]] = add nsw i32 [[V:%.*]], 5
2665 ; CHECK-NEXT: [[ADD6:%.*]] = add i32 [[V]], 5
2666 ; CHECK-NEXT: [[CMP:%.*]] = icmp slt i32 [[ADD5]], [[ADD6]]
2667 ; CHECK-NEXT: ret i1 [[CMP]]
2669 %add5 = add nsw i32 %V, 5
2670 %add6 = add i32 %V, 5
2671 %cmp = icmp slt i32 %add5, %add6
2675 define i1 @icmp_nsw_false_4(i32 %V) {
2676 ; CHECK-LABEL: @icmp_nsw_false_4(
2677 ; CHECK-NEXT: [[ADD5:%.*]] = add i32 [[V:%.*]], 6
2678 ; CHECK-NEXT: [[ADD6:%.*]] = add nsw i32 [[V]], 5
2679 ; CHECK-NEXT: [[CMP:%.*]] = icmp slt i32 [[ADD5]], [[ADD6]]
2680 ; CHECK-NEXT: ret i1 [[CMP]]
2682 %add5 = add i32 %V, 6
2683 %add6 = add nsw i32 %V, 5
2684 %cmp = icmp slt i32 %add5, %add6
2688 define i1 @icmp_nsw_false_5(i8 %V) {
2689 ; CHECK-LABEL: @icmp_nsw_false_5(
2690 ; CHECK-NEXT: [[ADD:%.*]] = add i8 [[V:%.*]], 121
2691 ; CHECK-NEXT: [[ADDNSW:%.*]] = add nsw i8 [[V]], -104
2692 ; CHECK-NEXT: [[CMP:%.*]] = icmp slt i8 [[ADD]], [[ADDNSW]]
2693 ; CHECK-NEXT: ret i1 [[CMP]]
2695 %add = add i8 %V, 121
2696 %addnsw = add nsw i8 %V, -104
2697 %cmp = icmp slt i8 %add, %addnsw
2701 define i1 @icmp_nsw_i8(i8 %V) {
2702 ; CHECK-LABEL: @icmp_nsw_i8(
2703 ; CHECK-NEXT: ret i1 true
2705 %add5 = add i8 %V, 5
2706 %add6 = add nsw i8 %V, 6
2707 %cmp = icmp slt i8 %add5, %add6
2711 define i1 @icmp_nsw_i16(i16 %V) {
2712 ; CHECK-LABEL: @icmp_nsw_i16(
2713 ; CHECK-NEXT: ret i1 true
2715 %add5 = add i16 %V, 0
2716 %add6 = add nsw i16 %V, 1
2717 %cmp = icmp slt i16 %add5, %add6
2721 define i1 @icmp_nsw_i64(i64 %V) {
2722 ; CHECK-LABEL: @icmp_nsw_i64(
2723 ; CHECK-NEXT: ret i1 true
2725 %add5 = add i64 %V, 5
2726 %add6 = add nsw i64 %V, 6
2727 %cmp = icmp slt i64 %add5, %add6
2731 define <4 x i1> @icmp_nsw_vec(<4 x i32> %V) {
2732 ; CHECK-LABEL: @icmp_nsw_vec(
2733 ; CHECK-NEXT: ret <4 x i1> <i1 true, i1 true, i1 true, i1 true>
2735 %add5 = add <4 x i32> %V, <i32 5, i32 5, i32 5, i32 5>
2736 %add6 = add nsw <4 x i32> %V, <i32 6, i32 6, i32 6, i32 6>
2737 %cmp = icmp slt <4 x i32> %add5, %add6
2741 define i1 @icmp_nsw_3(i32 %V) {
2742 ; CHECK-LABEL: @icmp_nsw_3(
2743 ; CHECK-NEXT: [[ADD5:%.*]] = add i32 [[V:%.*]], 5
2744 ; CHECK-NEXT: [[ADD5_2:%.*]] = add nsw i32 [[V]], 5
2745 ; CHECK-NEXT: [[CMP:%.*]] = icmp slt i32 [[ADD5]], [[ADD5_2]]
2746 ; CHECK-NEXT: ret i1 [[CMP]]
2748 %add5 = add i32 %V, 5
2749 %add5_2 = add nsw i32 %V, 5
2750 %cmp = icmp slt i32 %add5, %add5_2
2754 define i1 @icmp_nsw_4(i32 %V) {
2755 ; CHECK-LABEL: @icmp_nsw_4(
2756 ; CHECK-NEXT: [[ADD5:%.*]] = add i32 [[V:%.*]], 5
2757 ; CHECK-NEXT: [[ADD4:%.*]] = add nsw i32 [[V]], 4
2758 ; CHECK-NEXT: [[CMP:%.*]] = icmp slt i32 [[ADD5]], [[ADD4]]
2759 ; CHECK-NEXT: ret i1 [[CMP]]
2761 %add5 = add i32 %V, 5
2762 %add4 = add nsw i32 %V, 4
2763 %cmp = icmp slt i32 %add5, %add4
2767 define i1 @icmp_nsw_5(i32 %V) {
2768 ; CHECK-LABEL: @icmp_nsw_5(
2769 ; CHECK-NEXT: [[ADD5:%.*]] = add nsw i32 [[V:%.*]], 5
2770 ; CHECK-NEXT: [[ADD6:%.*]] = add i32 [[V]], 6
2771 ; CHECK-NEXT: [[CMP:%.*]] = icmp slt i32 [[ADD5]], [[ADD6]]
2772 ; CHECK-NEXT: ret i1 [[CMP]]
2774 %add5 = add nsw i32 %V, 5
2775 %add6 = add i32 %V, 6
2776 %cmp = icmp slt i32 %add5, %add6
2780 define i1 @icmp_nsw_7(i32 %V, i32 %arg) {
2781 ; CHECK-LABEL: @icmp_nsw_7(
2782 ; CHECK-NEXT: [[ADD5:%.*]] = add i32 [[V:%.*]], 5
2783 ; CHECK-NEXT: [[ADDARG:%.*]] = add nsw i32 [[V]], [[ARG:%.*]]
2784 ; CHECK-NEXT: [[CMP:%.*]] = icmp slt i32 [[ADD5]], [[ADDARG]]
2785 ; CHECK-NEXT: ret i1 [[CMP]]
2787 %add5 = add i32 %V, 5
2788 %addarg = add nsw i32 %V, %arg
2789 %cmp = icmp slt i32 %add5, %addarg
2793 define i1 @icmp_nsw_8(i32 %V, i32 %arg) {
2794 ; CHECK-LABEL: @icmp_nsw_8(
2795 ; CHECK-NEXT: [[ADDARG:%.*]] = add i32 [[V:%.*]], [[ARG:%.*]]
2796 ; CHECK-NEXT: [[ADD6:%.*]] = add nsw i32 [[V]], 5
2797 ; CHECK-NEXT: [[CMP:%.*]] = icmp slt i32 [[ADDARG]], [[ADD6]]
2798 ; CHECK-NEXT: ret i1 [[CMP]]
2800 %addarg = add i32 %V, %arg
2801 %add6 = add nsw i32 %V, 5
2802 %cmp = icmp slt i32 %addarg, %add6
2806 define i1 @icmp_nsw_9(i32 %V1, i32 %V2) {
2807 ; CHECK-LABEL: @icmp_nsw_9(
2808 ; CHECK-NEXT: [[ADD_V1:%.*]] = add i32 [[V1:%.*]], 5
2809 ; CHECK-NEXT: [[ADD_V2:%.*]] = add nsw i32 [[V2:%.*]], 6
2810 ; CHECK-NEXT: [[CMP:%.*]] = icmp slt i32 [[ADD_V1]], [[ADD_V2]]
2811 ; CHECK-NEXT: ret i1 [[CMP]]
2813 %add_V1 = add i32 %V1, 5
2814 %add_V2 = add nsw i32 %V2, 6
2815 %cmp = icmp slt i32 %add_V1, %add_V2
2819 define i1 @icmp_nsw_10(i32 %V) {
2820 ; CHECK-LABEL: @icmp_nsw_10(
2821 ; CHECK-NEXT: [[ADD5:%.*]] = add i32 [[V:%.*]], 5
2822 ; CHECK-NEXT: [[ADD6:%.*]] = add nsw i32 [[V]], 6
2823 ; CHECK-NEXT: [[CMP:%.*]] = icmp sgt i32 [[ADD6]], [[ADD5]]
2824 ; CHECK-NEXT: ret i1 [[CMP]]
2826 %add5 = add i32 %V, 5
2827 %add6 = add nsw i32 %V, 6
2828 %cmp = icmp sgt i32 %add6, %add5
2832 define i1 @icmp_nsw_11(i32 %V) {
2833 ; CHECK-LABEL: @icmp_nsw_11(
2834 ; CHECK-NEXT: [[ADD5:%.*]] = add i32 [[V:%.*]], -125
2835 ; CHECK-NEXT: [[ADD6:%.*]] = add nsw i32 [[V]], -99
2836 ; CHECK-NEXT: [[CMP:%.*]] = icmp slt i32 [[ADD5]], [[ADD6]]
2837 ; CHECK-NEXT: ret i1 [[CMP]]
2839 %add5 = add i32 %V, -125
2840 %add6 = add nsw i32 %V, -99
2841 %cmp = icmp slt i32 %add5, %add6
2845 define i1 @icmp_nsw_nonpos(i32 %V) {
2846 ; CHECK-LABEL: @icmp_nsw_nonpos(
2847 ; CHECK-NEXT: ret i1 false
2849 %add5 = add i32 %V, 0
2850 %add6 = add nsw i32 %V, -1
2851 %cmp = icmp slt i32 %add5, %add6
2855 define i1 @icmp_nsw_nonpos2(i32 %V) {
2856 ; CHECK-LABEL: @icmp_nsw_nonpos2(
2857 ; CHECK-NEXT: [[ADD5:%.*]] = add i32 [[V:%.*]], 1
2858 ; CHECK-NEXT: [[CMP:%.*]] = icmp slt i32 [[ADD5]], [[V]]
2859 ; CHECK-NEXT: ret i1 [[CMP]]
2861 %add5 = add i32 %V, 1
2862 %add6 = add nsw i32 %V, 0
2863 %cmp = icmp slt i32 %add5, %add6
2867 declare i11 @llvm.ctpop.i11(i11)
2868 declare i73 @llvm.ctpop.i73(i73)
2869 declare <2 x i13> @llvm.ctpop.v2i13(<2 x i13>)
2871 define i1 @ctpop_sgt_bitwidth(i11 %x) {
2872 ; CHECK-LABEL: @ctpop_sgt_bitwidth(
2873 ; CHECK-NEXT: ret i1 false
2875 %pop = call i11 @llvm.ctpop.i11(i11 %x)
2876 %cmp = icmp sgt i11 %pop, 11
2880 define i1 @ctpop_sle_minus1(i11 %x) {
2881 ; CHECK-LABEL: @ctpop_sle_minus1(
2882 ; CHECK-NEXT: ret i1 false
2884 %pop = call i11 @llvm.ctpop.i11(i11 %x)
2885 %cmp = icmp sle i11 %pop, -1
2889 define i1 @ctpop_ugt_bitwidth(i73 %x) {
2890 ; CHECK-LABEL: @ctpop_ugt_bitwidth(
2891 ; CHECK-NEXT: ret i1 false
2893 %pop = call i73 @llvm.ctpop.i73(i73 %x)
2894 %cmp = icmp ugt i73 %pop, 73
2898 ; Negative test - does not simplify, but instcombine could reduce this.
2900 define i1 @ctpop_ugt_bitwidth_minus1(i73 %x) {
2901 ; CHECK-LABEL: @ctpop_ugt_bitwidth_minus1(
2902 ; CHECK-NEXT: [[POP:%.*]] = call i73 @llvm.ctpop.i73(i73 [[X:%.*]])
2903 ; CHECK-NEXT: [[CMP:%.*]] = icmp ugt i73 [[POP]], 72
2904 ; CHECK-NEXT: ret i1 [[CMP]]
2906 %pop = call i73 @llvm.ctpop.i73(i73 %x)
2907 %cmp = icmp ugt i73 %pop, 72
2911 define <2 x i1> @ctpop_sgt_bitwidth_splat(<2 x i13> %x) {
2912 ; CHECK-LABEL: @ctpop_sgt_bitwidth_splat(
2913 ; CHECK-NEXT: ret <2 x i1> zeroinitializer
2915 %pop = call <2 x i13> @llvm.ctpop.v2i13(<2 x i13> %x)
2916 %cmp = icmp sgt <2 x i13> %pop, <i13 13, i13 13>
2920 define i1 @ctpop_ult_plus1_bitwidth(i11 %x) {
2921 ; CHECK-LABEL: @ctpop_ult_plus1_bitwidth(
2922 ; CHECK-NEXT: ret i1 true
2924 %pop = call i11 @llvm.ctpop.i11(i11 %x)
2925 %cmp = icmp ult i11 %pop, 12
2929 define i1 @ctpop_ne_big_bitwidth(i73 %x) {
2930 ; CHECK-LABEL: @ctpop_ne_big_bitwidth(
2931 ; CHECK-NEXT: ret i1 true
2933 %pop = call i73 @llvm.ctpop.i73(i73 %x)
2934 %cmp = icmp ne i73 %pop, 75
2938 define <2 x i1> @ctpop_slt_bitwidth_plus1_splat(<2 x i13> %x) {
2939 ; CHECK-LABEL: @ctpop_slt_bitwidth_plus1_splat(
2940 ; CHECK-NEXT: ret <2 x i1> <i1 true, i1 true>
2942 %pop = call <2 x i13> @llvm.ctpop.v2i13(<2 x i13> %x)
2943 %cmp = icmp slt <2 x i13> %pop, <i13 14, i13 14>
2947 ; Negative test - does not simplify, but instcombine could reduce this.
2949 define <2 x i1> @ctpop_slt_bitwidth_splat(<2 x i13> %x) {
2950 ; CHECK-LABEL: @ctpop_slt_bitwidth_splat(
2951 ; CHECK-NEXT: [[POP:%.*]] = call <2 x i13> @llvm.ctpop.v2i13(<2 x i13> [[X:%.*]])
2952 ; CHECK-NEXT: [[CMP:%.*]] = icmp slt <2 x i13> [[POP]], <i13 13, i13 13>
2953 ; CHECK-NEXT: ret <2 x i1> [[CMP]]
2955 %pop = call <2 x i13> @llvm.ctpop.v2i13(<2 x i13> %x)
2956 %cmp = icmp slt <2 x i13> %pop, <i13 13, i13 13>
2960 declare i11 @llvm.ctlz.i11(i11)
2961 declare i73 @llvm.ctlz.i73(i73)
2962 declare <2 x i13> @llvm.ctlz.v2i13(<2 x i13>)
2964 define i1 @ctlz_sgt_bitwidth(i11 %x) {
2965 ; CHECK-LABEL: @ctlz_sgt_bitwidth(
2966 ; CHECK-NEXT: ret i1 false
2968 %pop = call i11 @llvm.ctlz.i11(i11 %x)
2969 %cmp = icmp sgt i11 %pop, 11
2973 define i1 @ctlz_sle_minus1(i11 %x) {
2974 ; CHECK-LABEL: @ctlz_sle_minus1(
2975 ; CHECK-NEXT: ret i1 false
2977 %pop = call i11 @llvm.ctlz.i11(i11 %x)
2978 %cmp = icmp sle i11 %pop, -1
2982 define i1 @ctlz_ugt_bitwidth(i73 %x) {
2983 ; CHECK-LABEL: @ctlz_ugt_bitwidth(
2984 ; CHECK-NEXT: ret i1 false
2986 %pop = call i73 @llvm.ctlz.i73(i73 %x)
2987 %cmp = icmp ugt i73 %pop, 73
2991 ; Negative test - does not simplify, but instcombine could reduce this.
2993 define i1 @ctlz_ugt_bitwidth_minus1(i73 %x) {
2994 ; CHECK-LABEL: @ctlz_ugt_bitwidth_minus1(
2995 ; CHECK-NEXT: [[POP:%.*]] = call i73 @llvm.ctlz.i73(i73 [[X:%.*]], i1 false)
2996 ; CHECK-NEXT: [[CMP:%.*]] = icmp ugt i73 [[POP]], 72
2997 ; CHECK-NEXT: ret i1 [[CMP]]
2999 %pop = call i73 @llvm.ctlz.i73(i73 %x)
3000 %cmp = icmp ugt i73 %pop, 72
3004 define <2 x i1> @ctlz_sgt_bitwidth_splat(<2 x i13> %x) {
3005 ; CHECK-LABEL: @ctlz_sgt_bitwidth_splat(
3006 ; CHECK-NEXT: ret <2 x i1> zeroinitializer
3008 %pop = call <2 x i13> @llvm.ctlz.v2i13(<2 x i13> %x)
3009 %cmp = icmp sgt <2 x i13> %pop, <i13 13, i13 13>
3013 define i1 @ctlz_ult_plus1_bitwidth(i11 %x) {
3014 ; CHECK-LABEL: @ctlz_ult_plus1_bitwidth(
3015 ; CHECK-NEXT: ret i1 true
3017 %pop = call i11 @llvm.ctlz.i11(i11 %x)
3018 %cmp = icmp ult i11 %pop, 12
3022 define i1 @ctlz_ne_big_bitwidth(i73 %x) {
3023 ; CHECK-LABEL: @ctlz_ne_big_bitwidth(
3024 ; CHECK-NEXT: ret i1 true
3026 %pop = call i73 @llvm.ctlz.i73(i73 %x)
3027 %cmp = icmp ne i73 %pop, 75
3031 define <2 x i1> @ctlz_slt_bitwidth_plus1_splat(<2 x i13> %x) {
3032 ; CHECK-LABEL: @ctlz_slt_bitwidth_plus1_splat(
3033 ; CHECK-NEXT: ret <2 x i1> <i1 true, i1 true>
3035 %pop = call <2 x i13> @llvm.ctlz.v2i13(<2 x i13> %x)
3036 %cmp = icmp slt <2 x i13> %pop, <i13 14, i13 14>
3040 ; Negative test - does not simplify, but instcombine could reduce this.
3042 define <2 x i1> @ctlz_slt_bitwidth_splat(<2 x i13> %x) {
3043 ; CHECK-LABEL: @ctlz_slt_bitwidth_splat(
3044 ; CHECK-NEXT: [[POP:%.*]] = call <2 x i13> @llvm.ctlz.v2i13(<2 x i13> [[X:%.*]], i1 false)
3045 ; CHECK-NEXT: [[CMP:%.*]] = icmp slt <2 x i13> [[POP]], <i13 13, i13 13>
3046 ; CHECK-NEXT: ret <2 x i1> [[CMP]]
3048 %pop = call <2 x i13> @llvm.ctlz.v2i13(<2 x i13> %x)
3049 %cmp = icmp slt <2 x i13> %pop, <i13 13, i13 13>
3053 declare i11 @llvm.cttz.i11(i11)
3054 declare i73 @llvm.cttz.i73(i73)
3055 declare <2 x i13> @llvm.cttz.v2i13(<2 x i13>)
3057 define i1 @cttz_sgt_bitwidth(i11 %x) {
3058 ; CHECK-LABEL: @cttz_sgt_bitwidth(
3059 ; CHECK-NEXT: ret i1 false
3061 %pop = call i11 @llvm.cttz.i11(i11 %x)
3062 %cmp = icmp sgt i11 %pop, 11
3066 define i1 @cttz_sle_minus1(i11 %x) {
3067 ; CHECK-LABEL: @cttz_sle_minus1(
3068 ; CHECK-NEXT: ret i1 false
3070 %pop = call i11 @llvm.cttz.i11(i11 %x)
3071 %cmp = icmp sle i11 %pop, -1
3075 define i1 @cttz_ugt_bitwidth(i73 %x) {
3076 ; CHECK-LABEL: @cttz_ugt_bitwidth(
3077 ; CHECK-NEXT: ret i1 false
3079 %pop = call i73 @llvm.cttz.i73(i73 %x)
3080 %cmp = icmp ugt i73 %pop, 73
3084 ; Negative test - does not simplify, but instcombine could reduce this.
3086 define i1 @cttz_ugt_bitwidth_minus1(i73 %x) {
3087 ; CHECK-LABEL: @cttz_ugt_bitwidth_minus1(
3088 ; CHECK-NEXT: [[POP:%.*]] = call i73 @llvm.cttz.i73(i73 [[X:%.*]], i1 false)
3089 ; CHECK-NEXT: [[CMP:%.*]] = icmp ugt i73 [[POP]], 72
3090 ; CHECK-NEXT: ret i1 [[CMP]]
3092 %pop = call i73 @llvm.cttz.i73(i73 %x)
3093 %cmp = icmp ugt i73 %pop, 72
3097 define <2 x i1> @cttz_sgt_bitwidth_splat(<2 x i13> %x) {
3098 ; CHECK-LABEL: @cttz_sgt_bitwidth_splat(
3099 ; CHECK-NEXT: ret <2 x i1> zeroinitializer
3101 %pop = call <2 x i13> @llvm.cttz.v2i13(<2 x i13> %x)
3102 %cmp = icmp sgt <2 x i13> %pop, <i13 13, i13 13>
3106 define i1 @cttz_ult_plus1_bitwidth(i11 %x) {
3107 ; CHECK-LABEL: @cttz_ult_plus1_bitwidth(
3108 ; CHECK-NEXT: ret i1 true
3110 %pop = call i11 @llvm.cttz.i11(i11 %x)
3111 %cmp = icmp ult i11 %pop, 12
3115 define i1 @cttz_ne_big_bitwidth(i73 %x) {
3116 ; CHECK-LABEL: @cttz_ne_big_bitwidth(
3117 ; CHECK-NEXT: ret i1 true
3119 %pop = call i73 @llvm.cttz.i73(i73 %x)
3120 %cmp = icmp ne i73 %pop, 75
3124 define <2 x i1> @cttz_slt_bitwidth_plus1_splat(<2 x i13> %x) {
3125 ; CHECK-LABEL: @cttz_slt_bitwidth_plus1_splat(
3126 ; CHECK-NEXT: ret <2 x i1> <i1 true, i1 true>
3128 %pop = call <2 x i13> @llvm.cttz.v2i13(<2 x i13> %x)
3129 %cmp = icmp slt <2 x i13> %pop, <i13 14, i13 14>
3133 ; Negative test - does not simplify, but instcombine could reduce this.
3135 define <2 x i1> @cttz_slt_bitwidth_splat(<2 x i13> %x) {
3136 ; CHECK-LABEL: @cttz_slt_bitwidth_splat(
3137 ; CHECK-NEXT: [[POP:%.*]] = call <2 x i13> @llvm.cttz.v2i13(<2 x i13> [[X:%.*]], i1 false)
3138 ; CHECK-NEXT: [[CMP:%.*]] = icmp slt <2 x i13> [[POP]], <i13 13, i13 13>
3139 ; CHECK-NEXT: ret <2 x i1> [[CMP]]
3141 %pop = call <2 x i13> @llvm.cttz.v2i13(<2 x i13> %x)
3142 %cmp = icmp slt <2 x i13> %pop, <i13 13, i13 13>
3146 ; A zero sized alloca *can* be equal to another alloca
3147 define i1 @zero_sized_alloca1() {
3148 ; CHECK-LABEL: @zero_sized_alloca1(
3149 ; CHECK-NEXT: [[A:%.*]] = alloca i32, i32 0, align 4
3150 ; CHECK-NEXT: [[B:%.*]] = alloca i32, i32 0, align 4
3151 ; CHECK-NEXT: [[RES:%.*]] = icmp ne ptr [[A]], [[B]]
3152 ; CHECK-NEXT: ret i1 [[RES]]
3154 %a = alloca i32, i32 0
3155 %b = alloca i32, i32 0
3156 %res = icmp ne ptr %a, %b
3160 define i1 @zero_sized_alloca2() {
3161 ; CHECK-LABEL: @zero_sized_alloca2(
3162 ; CHECK-NEXT: [[A:%.*]] = alloca i32, i32 0, align 4
3163 ; CHECK-NEXT: [[B:%.*]] = alloca i32, align 4
3164 ; CHECK-NEXT: [[RES:%.*]] = icmp ne ptr [[A]], [[B]]
3165 ; CHECK-NEXT: ret i1 [[RES]]
3167 %a = alloca i32, i32 0
3169 %res = icmp ne ptr %a, %b
3173 define i1 @scalar_vectors_are_non_empty() {
3174 ; CHECK-LABEL: @scalar_vectors_are_non_empty(
3175 ; CHECK-NEXT: ret i1 true
3177 %a = alloca <vscale x 2 x i32>
3178 %b = alloca <vscale x 2 x i32>
3179 %res = icmp ne ptr %a, %b
3184 define i1 @byval_args_inequal(ptr byval(i32) %a, ptr byval(i32) %b) {
3185 ; CHECK-LABEL: @byval_args_inequal(
3186 ; CHECK-NEXT: ret i1 true
3188 %res = icmp ne ptr %a, %b
3192 ; Arguments can be adjacent on the stack
3193 define i1 @neg_args_adjacent(ptr byval(i32) %a, ptr byval(i32) %b) {
3194 ; CHECK-LABEL: @neg_args_adjacent(
3195 ; CHECK-NEXT: [[A_OFF:%.*]] = getelementptr i32, ptr [[A:%.*]], i32 1
3196 ; CHECK-NEXT: [[RES:%.*]] = icmp ne ptr [[A_OFF]], [[B:%.*]]
3197 ; CHECK-NEXT: ret i1 [[RES]]
3199 %a.off = getelementptr i32, ptr %a, i32 1
3200 %res = icmp ne ptr %a.off, %b
3205 define i1 @test_byval_alloca_inequal(ptr byval(i32) %a) {
3206 ; CHECK-LABEL: @test_byval_alloca_inequal(
3207 ; CHECK-NEXT: ret i1 true
3210 %res = icmp ne ptr %a, %b
3214 ; Byval argument can be immediately before alloca, and crossing
3216 define i1 @neg_byval_alloca_adjacent(ptr byval(i32) %a) {
3217 ; CHECK-LABEL: @neg_byval_alloca_adjacent(
3218 ; CHECK-NEXT: [[B:%.*]] = alloca i32, align 4
3219 ; CHECK-NEXT: [[A_OFF:%.*]] = getelementptr i32, ptr [[A:%.*]], i32 1
3220 ; CHECK-NEXT: [[RES:%.*]] = icmp ne ptr [[A_OFF]], [[B]]
3221 ; CHECK-NEXT: ret i1 [[RES]]
3224 %a.off = getelementptr i32, ptr %a, i32 1
3225 %res = icmp ne ptr %a.off, %b
3231 @A.alias = alias i32, ptr @A
3233 define i1 @globals_inequal() {
3234 ; CHECK-LABEL: @globals_inequal(
3235 ; CHECK-NEXT: ret i1 true
3237 %res = icmp ne ptr @A, @B
3242 define i1 @globals_offset_inequal() {
3243 ; CHECK-LABEL: @globals_offset_inequal(
3244 ; CHECK-NEXT: [[RES:%.*]] = icmp ne ptr getelementptr inbounds (i8, ptr @A, i32 1), getelementptr inbounds (i8, ptr @B, i32 1)
3245 ; CHECK-NEXT: ret i1 [[RES]]
3247 %a.off = getelementptr i8, ptr @A, i32 1
3248 %b.off = getelementptr i8, ptr @B, i32 1
3249 %res = icmp ne ptr %a.off, %b.off
3255 define i1 @test_byval_global_inequal(ptr byval(i32) %a) {
3256 ; CHECK-LABEL: @test_byval_global_inequal(
3257 ; CHECK-NEXT: ret i1 true
3260 %res = icmp ne ptr %a, @B
3265 define i1 @neg_global_alias() {
3266 ; CHECK-LABEL: @neg_global_alias(
3267 ; CHECK-NEXT: [[RES:%.*]] = icmp ne ptr @A, @A.alias
3268 ; CHECK-NEXT: ret i1 [[RES]]
3270 %res = icmp ne ptr @A, @A.alias
3275 define i1 @icmp_lshr_known_non_zero_ult_true(i8 %x) {
3276 ; CHECK-LABEL: @icmp_lshr_known_non_zero_ult_true(
3277 ; CHECK-NEXT: ret i1 true
3280 %x1 = shl nuw i8 %or, 1
3281 %x2 = shl nuw i8 %or, 2
3282 %cmp = icmp ult i8 %x1, %x2
3286 define i1 @icmp_lshr_known_non_zero_ult_false(i8 %x) {
3287 ; CHECK-LABEL: @icmp_lshr_known_non_zero_ult_false(
3288 ; CHECK-NEXT: ret i1 false
3291 %x1 = shl nuw i8 %or, 1
3292 %x2 = shl nuw i8 %or, 2
3293 %cmp = icmp ugt i8 %x1, %x2
3297 define i1 @icmp_lshr_known_non_zero_slt_true(i8 %x) {
3298 ; CHECK-LABEL: @icmp_lshr_known_non_zero_slt_true(
3299 ; CHECK-NEXT: ret i1 true
3302 %x1 = shl nuw nsw i8 %or, 1
3303 %x2 = shl nuw nsw i8 %or, 2
3304 %cmp = icmp slt i8 %x1, %x2
3308 define i1 @icmp_lshr_known_non_zero_slt_false(i8 %x) {
3309 ; CHECK-LABEL: @icmp_lshr_known_non_zero_slt_false(
3310 ; CHECK-NEXT: ret i1 false
3313 %x1 = shl nuw nsw i8 %or, 2
3314 %x2 = shl nuw nsw i8 %or, 1
3315 %cmp = icmp slt i8 %x1, %x2
3319 define i1 @neg_icmp_lshr_known_non_zero_slt_no_nsw(i8 %x) {
3320 ; CHECK-LABEL: @neg_icmp_lshr_known_non_zero_slt_no_nsw(
3321 ; CHECK-NEXT: [[OR:%.*]] = or i8 [[X:%.*]], 1
3322 ; CHECK-NEXT: [[X1:%.*]] = shl nuw i8 [[OR]], 1
3323 ; CHECK-NEXT: [[X2:%.*]] = shl nuw i8 [[OR]], 2
3324 ; CHECK-NEXT: [[CMP:%.*]] = icmp slt i8 [[X1]], [[X2]]
3325 ; CHECK-NEXT: ret i1 [[CMP]]
3328 %x1 = shl nuw i8 %or, 1
3329 %x2 = shl nuw i8 %or, 2
3330 %cmp = icmp slt i8 %x1, %x2
3334 define i1 @neg_icmp_lshr_known_non_zero_ult_no_nuw(i8 %x) {
3335 ; CHECK-LABEL: @neg_icmp_lshr_known_non_zero_ult_no_nuw(
3336 ; CHECK-NEXT: [[OR:%.*]] = or i8 [[X:%.*]], 1
3337 ; CHECK-NEXT: [[X1:%.*]] = shl i8 [[OR]], 1
3338 ; CHECK-NEXT: [[X2:%.*]] = shl i8 [[OR]], 2
3339 ; CHECK-NEXT: [[CMP:%.*]] = icmp ult i8 [[X1]], [[X2]]
3340 ; CHECK-NEXT: ret i1 [[CMP]]
3345 %cmp = icmp ult i8 %x1, %x2
3349 define i1 @neg_icmp_lshr_known_non_zero_slt_no_nuw(i8 %x) {
3350 ; CHECK-LABEL: @neg_icmp_lshr_known_non_zero_slt_no_nuw(
3351 ; CHECK-NEXT: [[OR:%.*]] = or i8 [[X:%.*]], 1
3352 ; CHECK-NEXT: [[X1:%.*]] = shl nsw i8 [[OR]], 1
3353 ; CHECK-NEXT: [[X2:%.*]] = shl nsw i8 [[OR]], 2
3354 ; CHECK-NEXT: [[CMP:%.*]] = icmp slt i8 [[X1]], [[X2]]
3355 ; CHECK-NEXT: ret i1 [[CMP]]
3358 %x1 = shl nsw i8 %or, 1
3359 %x2 = shl nsw i8 %or, 2
3360 %cmp = icmp slt i8 %x1, %x2
3364 define i1 @neg_icmp_lshr_unknown_value(i8 %x) {
3365 ; CHECK-LABEL: @neg_icmp_lshr_unknown_value(
3366 ; CHECK-NEXT: [[X1:%.*]] = shl nuw i8 [[X:%.*]], 2
3367 ; CHECK-NEXT: [[X2:%.*]] = shl nuw i8 [[X]], 1
3368 ; CHECK-NEXT: [[CMP:%.*]] = icmp ugt i8 [[X1]], [[X2]]
3369 ; CHECK-NEXT: ret i1 [[CMP]]
3371 %x1 = shl nuw i8 %x, 2
3372 %x2 = shl nuw i8 %x, 1
3373 %cmp = icmp ugt i8 %x1, %x2
3377 define i1 @neg_icmp_lshr_unknown_shift(i8 %x, i8 %C1) {
3378 ; CHECK-LABEL: @neg_icmp_lshr_unknown_shift(
3379 ; CHECK-NEXT: [[OR:%.*]] = or i8 [[X:%.*]], 1
3380 ; CHECK-NEXT: [[X1:%.*]] = shl nuw i8 [[OR]], 2
3381 ; CHECK-NEXT: [[X2:%.*]] = shl nuw i8 [[OR]], [[C1:%.*]]
3382 ; CHECK-NEXT: [[CMP:%.*]] = icmp ugt i8 [[X1]], [[X2]]
3383 ; CHECK-NEXT: ret i1 [[CMP]]
3386 %x1 = shl nuw i8 %or, 2
3387 %x2 = shl nuw i8 %or, %C1
3388 %cmp = icmp ugt i8 %x1, %x2
3392 define i1 @neg_icmp_lshr_different_shift_values(i8 %x, i8 %y) {
3393 ; CHECK-LABEL: @neg_icmp_lshr_different_shift_values(
3394 ; CHECK-NEXT: [[X1:%.*]] = shl nuw nsw i8 [[X:%.*]], 1
3395 ; CHECK-NEXT: [[X2:%.*]] = shl nuw nsw i8 [[Y:%.*]], 2
3396 ; CHECK-NEXT: [[CMP:%.*]] = icmp ult i8 [[X1]], [[X2]]
3397 ; CHECK-NEXT: ret i1 [[CMP]]
3399 %x1 = shl nuw nsw i8 %x, 1
3400 %x2 = shl nuw nsw i8 %y, 2
3401 %cmp = icmp ult i8 %x1, %x2
3405 define i1 @icmp_ult_vscale_true(i8 %x, i8 %y) {
3406 ; CHECK-LABEL: @icmp_ult_vscale_true(
3407 ; CHECK-NEXT: ret i1 true
3409 %vscale = call i64 @llvm.vscale.i64()
3410 %x1 = shl nuw nsw i64 %vscale, 1
3411 %x2 = shl nuw nsw i64 %vscale, 2
3412 %cmp = icmp ult i64 %x1, %x2
3416 define i1 @icmp_ult_vscale_false(i8 %x, i8 %y) {
3417 ; CHECK-LABEL: @icmp_ult_vscale_false(
3418 ; CHECK-NEXT: ret i1 false
3420 %vscale = call i64 @llvm.vscale.i64()
3421 %x1 = shl nuw nsw i64 %vscale, 1
3422 %x2 = shl nuw nsw i64 %vscale, 2
3423 %cmp = icmp ugt i64 %x1, %x2
3427 declare i64 @llvm.vscale.i64()
3429 ; TODO: Add coverage for global aliases, link once, etc..
3432 attributes #0 = { null_pointer_is_valid }