1 ; NOTE: Assertions have been autogenerated by utils/update_test_checks.py
2 ; RUN: opt < %s -instcombine -S | FileCheck %s
4 target datalayout = "e-p:64:64:64-p1:16:16:16-p2:32:32:32-p3:64:64:64-i1:8:8-i8:8:8-i16:16:16-i32:32:32-i64:64:64-f32:32:32-f64:64:64-v64:64:64-v128:128:128-a0:0:64-s0:64:64-f80:128:128-n8:16:32:64"
6 define i32 @test1(i32 %X) {
8 ; CHECK-NEXT: [[X_LOBIT:%.*]] = lshr i32 [[X:%.*]], 31
9 ; CHECK-NEXT: ret i32 [[X_LOBIT]]
11 %a = icmp slt i32 %X, 0
12 %b = zext i1 %a to i32
16 define <2 x i32> @test1vec(<2 x i32> %X) {
17 ; CHECK-LABEL: @test1vec(
18 ; CHECK-NEXT: [[X_LOBIT:%.*]] = lshr <2 x i32> [[X:%.*]], <i32 31, i32 31>
19 ; CHECK-NEXT: ret <2 x i32> [[X_LOBIT]]
21 %a = icmp slt <2 x i32> %X, zeroinitializer
22 %b = zext <2 x i1> %a to <2 x i32>
26 define i32 @test2(i32 %X) {
27 ; CHECK-LABEL: @test2(
28 ; CHECK-NEXT: [[X_LOBIT:%.*]] = lshr i32 [[X:%.*]], 31
29 ; CHECK-NEXT: [[X_LOBIT_NOT:%.*]] = xor i32 [[X_LOBIT]], 1
30 ; CHECK-NEXT: ret i32 [[X_LOBIT_NOT]]
32 %a = icmp ult i32 %X, -2147483648
33 %b = zext i1 %a to i32
37 define <2 x i32> @test2vec(<2 x i32> %X) {
38 ; CHECK-LABEL: @test2vec(
39 ; CHECK-NEXT: [[X_LOBIT:%.*]] = lshr <2 x i32> [[X:%.*]], <i32 31, i32 31>
40 ; CHECK-NEXT: [[X_LOBIT_NOT:%.*]] = xor <2 x i32> [[X_LOBIT]], <i32 1, i32 1>
41 ; CHECK-NEXT: ret <2 x i32> [[X_LOBIT_NOT]]
43 %a = icmp ult <2 x i32> %X, <i32 -2147483648, i32 -2147483648>
44 %b = zext <2 x i1> %a to <2 x i32>
48 define i32 @test3(i32 %X) {
49 ; CHECK-LABEL: @test3(
50 ; CHECK-NEXT: [[X_LOBIT:%.*]] = ashr i32 [[X:%.*]], 31
51 ; CHECK-NEXT: ret i32 [[X_LOBIT]]
53 %a = icmp slt i32 %X, 0
54 %b = sext i1 %a to i32
58 define i32 @test4(i32 %X) {
59 ; CHECK-LABEL: @test4(
60 ; CHECK-NEXT: [[X_LOBIT:%.*]] = ashr i32 [[X:%.*]], 31
61 ; CHECK-NEXT: [[X_LOBIT_NOT:%.*]] = xor i32 [[X_LOBIT]], -1
62 ; CHECK-NEXT: ret i32 [[X_LOBIT_NOT]]
64 %a = icmp ult i32 %X, -2147483648
65 %b = sext i1 %a to i32
70 define <2 x i1> @test5_eq(<2 x i64> %x) {
71 ; CHECK-LABEL: @test5_eq(
72 ; CHECK-NEXT: ret <2 x i1> undef
74 %V = icmp eq <2 x i64> %x, undef
77 define <2 x i1> @test5_ne(<2 x i64> %x) {
78 ; CHECK-LABEL: @test5_ne(
79 ; CHECK-NEXT: ret <2 x i1> undef
81 %V = icmp ne <2 x i64> %x, undef
84 define <2 x i1> @test5_ugt(<2 x i64> %x) {
85 ; CHECK-LABEL: @test5_ugt(
86 ; CHECK-NEXT: ret <2 x i1> zeroinitializer
88 %V = icmp ugt <2 x i64> %x, undef
91 define <2 x i1> @test5_zero() {
92 ; CHECK-LABEL: @test5_zero(
93 ; CHECK-NEXT: ret <2 x i1> undef
95 %V = icmp eq <2 x i64> zeroinitializer, undef
99 define i32 @test6(i32 %a, i32 %b) {
100 ; CHECK-LABEL: @test6(
101 ; CHECK-NEXT: [[E:%.*]] = ashr i32 [[A:%.*]], 31
102 ; CHECK-NEXT: [[F:%.*]] = and i32 [[E]], [[B:%.*]]
103 ; CHECK-NEXT: ret i32 [[F]]
105 %c = icmp sle i32 %a, -1
106 %d = zext i1 %c to i32
113 define i1 @test7(i32 %x) {
114 ; CHECK-LABEL: @test7(
115 ; CHECK-NEXT: [[B:%.*]] = icmp ne i32 [[X:%.*]], 0
116 ; CHECK-NEXT: ret i1 [[B]]
119 %b = icmp ult i32 %a, %x
123 define <2 x i1> @test7_vec(<2 x i32> %x) {
124 ; CHECK-LABEL: @test7_vec(
125 ; CHECK-NEXT: [[B:%.*]] = icmp ne <2 x i32> [[X:%.*]], zeroinitializer
126 ; CHECK-NEXT: ret <2 x i1> [[B]]
128 %a = add <2 x i32> %x, <i32 -1, i32 -1>
129 %b = icmp ult <2 x i32> %a, %x
133 define i1 @test8(i32 %x) {
134 ; CHECK-LABEL: @test8(
135 ; CHECK-NEXT: ret i1 false
138 %b = icmp eq i32 %a, %x
142 define <2 x i1> @test8_vec(<2 x i32> %x) {
143 ; CHECK-LABEL: @test8_vec(
144 ; CHECK-NEXT: ret <2 x i1> zeroinitializer
146 %a = add <2 x i32> %x, <i32 -1, i32 -1>
147 %b = icmp eq <2 x i32> %a, %x
151 define i1 @test9(i32 %x) {
152 ; CHECK-LABEL: @test9(
153 ; CHECK-NEXT: [[B:%.*]] = icmp ugt i32 [[X:%.*]], 1
154 ; CHECK-NEXT: ret i1 [[B]]
157 %b = icmp ugt i32 %x, %a
161 define <2 x i1> @test9_vec(<2 x i32> %x) {
162 ; CHECK-LABEL: @test9_vec(
163 ; CHECK-NEXT: [[B:%.*]] = icmp ugt <2 x i32> [[X:%.*]], <i32 1, i32 1>
164 ; CHECK-NEXT: ret <2 x i1> [[B]]
166 %a = add <2 x i32> %x, <i32 -2, i32 -2>
167 %b = icmp ugt <2 x i32> %x, %a
171 define i1 @test9b(i32 %x) {
172 ; CHECK-LABEL: @test9b(
173 ; CHECK-NEXT: [[B:%.*]] = icmp ult i32 [[X:%.*]], 2
174 ; CHECK-NEXT: ret i1 [[B]]
177 %b = icmp ugt i32 %a, %x
181 define <2 x i1> @test9b_vec(<2 x i32> %x) {
182 ; CHECK-LABEL: @test9b_vec(
183 ; CHECK-NEXT: [[B:%.*]] = icmp ult <2 x i32> [[X:%.*]], <i32 2, i32 2>
184 ; CHECK-NEXT: ret <2 x i1> [[B]]
186 %a = add <2 x i32> %x, <i32 -2, i32 -2>
187 %b = icmp ugt <2 x i32> %a, %x
191 define i1 @test10(i32 %x) {
192 ; CHECK-LABEL: @test10(
193 ; CHECK-NEXT: [[B:%.*]] = icmp ne i32 [[X:%.*]], -2147483648
194 ; CHECK-NEXT: ret i1 [[B]]
197 %b = icmp slt i32 %a, %x
201 define <2 x i1> @test10_vec(<2 x i32> %x) {
202 ; CHECK-LABEL: @test10_vec(
203 ; CHECK-NEXT: [[B:%.*]] = icmp ne <2 x i32> [[X:%.*]], <i32 -2147483648, i32 -2147483648>
204 ; CHECK-NEXT: ret <2 x i1> [[B]]
206 %a = add <2 x i32> %x, <i32 -1, i32 -1>
207 %b = icmp slt <2 x i32> %a, %x
211 define i1 @test10b(i32 %x) {
212 ; CHECK-LABEL: @test10b(
213 ; CHECK-NEXT: [[B:%.*]] = icmp eq i32 [[X:%.*]], -2147483648
214 ; CHECK-NEXT: ret i1 [[B]]
217 %b = icmp sgt i32 %a, %x
221 define <2 x i1> @test10b_vec(<2 x i32> %x) {
222 ; CHECK-LABEL: @test10b_vec(
223 ; CHECK-NEXT: [[B:%.*]] = icmp eq <2 x i32> [[X:%.*]], <i32 -2147483648, i32 -2147483648>
224 ; CHECK-NEXT: ret <2 x i1> [[B]]
226 %a = add <2 x i32> %x, <i32 -1, i32 -1>
227 %b = icmp sgt <2 x i32> %a, %x
231 define i1 @test11(i32 %x) {
232 ; CHECK-LABEL: @test11(
233 ; CHECK-NEXT: ret i1 true
235 %a = add nsw i32 %x, 8
236 %b = icmp slt i32 %x, %a
240 define <2 x i1> @test11_vec(<2 x i32> %x) {
241 ; CHECK-LABEL: @test11_vec(
242 ; CHECK-NEXT: ret <2 x i1> <i1 true, i1 true>
244 %a = add nsw <2 x i32> %x, <i32 8, i32 8>
245 %b = icmp slt <2 x i32> %x, %a
250 define i1 @test12(i1 %A) {
251 ; CHECK-LABEL: @test12(
252 ; CHECK-NEXT: [[NOT_A:%.*]] = xor i1 [[A:%.*]], true
253 ; CHECK-NEXT: ret i1 [[NOT_A]]
255 %S = select i1 %A, i64 -4294967295, i64 8589934591
256 %B = icmp ne i64 bitcast (<2 x i32> <i32 1, i32 -1> to i64), %S
261 define i1 @test13(i8 %X) {
262 ; CHECK-LABEL: @test13(
263 ; CHECK-NEXT: ret i1 false
265 %cmp = icmp slt i8 undef, %X
269 define i1 @test14(i8 %X) {
270 ; CHECK-LABEL: @test14(
271 ; CHECK-NEXT: ret i1 false
273 %cmp = icmp slt i8 undef, -128
277 define i1 @test15() {
278 ; CHECK-LABEL: @test15(
279 ; CHECK-NEXT: ret i1 undef
281 %cmp = icmp eq i8 undef, -128
285 define i1 @test16() {
286 ; CHECK-LABEL: @test16(
287 ; CHECK-NEXT: ret i1 undef
289 %cmp = icmp ne i8 undef, -128
293 define i1 @test17(i32 %x) {
294 ; CHECK-LABEL: @test17(
295 ; CHECK-NEXT: [[CMP:%.*]] = icmp ne i32 [[X:%.*]], 3
296 ; CHECK-NEXT: ret i1 [[CMP]]
299 %and = and i32 %shl, 8
300 %cmp = icmp eq i32 %and, 0
304 define <2 x i1> @test17vec(<2 x i32> %x) {
305 ; CHECK-LABEL: @test17vec(
306 ; CHECK-NEXT: [[CMP:%.*]] = icmp ne <2 x i32> [[X:%.*]], <i32 3, i32 3>
307 ; CHECK-NEXT: ret <2 x i1> [[CMP]]
309 %shl = shl <2 x i32> <i32 1, i32 1>, %x
310 %and = and <2 x i32> %shl, <i32 8, i32 8>
311 %cmp = icmp eq <2 x i32> %and, zeroinitializer
315 define i1 @test17a(i32 %x) {
316 ; CHECK-LABEL: @test17a(
317 ; CHECK-NEXT: [[CMP:%.*]] = icmp ugt i32 [[X:%.*]], 2
318 ; CHECK-NEXT: ret i1 [[CMP]]
321 %and = and i32 %shl, 7
322 %cmp = icmp eq i32 %and, 0
326 define <2 x i1> @test17a_vec(<2 x i32> %x) {
327 ; CHECK-LABEL: @test17a_vec(
328 ; CHECK-NEXT: [[CMP:%.*]] = icmp ugt <2 x i32> [[X:%.*]], <i32 2, i32 2>
329 ; CHECK-NEXT: ret <2 x i1> [[CMP]]
331 %shl = shl <2 x i32> <i32 1, i32 1>, %x
332 %and = and <2 x i32> %shl, <i32 7, i32 7>
333 %cmp = icmp eq <2 x i32> %and, zeroinitializer
337 define i1 @test18_eq(i32 %x) {
338 ; CHECK-LABEL: @test18_eq(
339 ; CHECK-NEXT: [[CMP:%.*]] = icmp ne i32 [[X:%.*]], 3
340 ; CHECK-NEXT: ret i1 [[CMP]]
343 %and = and i32 %sh, 1
344 %cmp = icmp eq i32 %and, 0
348 define <2 x i1> @test18_eq_vec(<2 x i32> %x) {
349 ; CHECK-LABEL: @test18_eq_vec(
350 ; CHECK-NEXT: [[CMP:%.*]] = icmp ne <2 x i32> [[X:%.*]], <i32 3, i32 3>
351 ; CHECK-NEXT: ret <2 x i1> [[CMP]]
353 %sh = lshr <2 x i32> <i32 8, i32 8>, %x
354 %and = and <2 x i32> %sh, <i32 1, i32 1>
355 %cmp = icmp eq <2 x i32> %and, zeroinitializer
359 define i1 @test18_ne(i32 %x) {
360 ; CHECK-LABEL: @test18_ne(
361 ; CHECK-NEXT: [[CMP:%.*]] = icmp eq i32 [[X:%.*]], 3
362 ; CHECK-NEXT: ret i1 [[CMP]]
365 %and = and i32 %sh, 1
366 %cmp = icmp ne i32 %and, 0
370 define <2 x i1> @test18_ne_vec(<2 x i32> %x) {
371 ; CHECK-LABEL: @test18_ne_vec(
372 ; CHECK-NEXT: [[CMP:%.*]] = icmp eq <2 x i32> [[X:%.*]], <i32 3, i32 3>
373 ; CHECK-NEXT: ret <2 x i1> [[CMP]]
375 %sh = lshr <2 x i32> <i32 8, i32 8>, %x
376 %and = and <2 x i32> %sh, <i32 1, i32 1>
377 %cmp = icmp ne <2 x i32> %and, zeroinitializer
381 define i1 @test19(i32 %x) {
382 ; CHECK-LABEL: @test19(
383 ; CHECK-NEXT: [[CMP:%.*]] = icmp eq i32 [[X:%.*]], 3
384 ; CHECK-NEXT: ret i1 [[CMP]]
387 %and = and i32 %shl, 8
388 %cmp = icmp eq i32 %and, 8
392 define <2 x i1> @test19vec(<2 x i32> %x) {
393 ; CHECK-LABEL: @test19vec(
394 ; CHECK-NEXT: [[CMP:%.*]] = icmp eq <2 x i32> [[X:%.*]], <i32 3, i32 3>
395 ; CHECK-NEXT: ret <2 x i1> [[CMP]]
397 %shl = shl <2 x i32> <i32 1, i32 1>, %x
398 %and = and <2 x i32> %shl, <i32 8, i32 8>
399 %cmp = icmp eq <2 x i32> %and, <i32 8, i32 8>
403 define <2 x i1> @cmp_and_signbit_vec(<2 x i3> %x) {
404 ; CHECK-LABEL: @cmp_and_signbit_vec(
405 ; CHECK-NEXT: [[CMP:%.*]] = icmp slt <2 x i3> [[X:%.*]], zeroinitializer
406 ; CHECK-NEXT: ret <2 x i1> [[CMP]]
408 %and = and <2 x i3> %x, <i3 4, i3 4>
409 %cmp = icmp ne <2 x i3> %and, zeroinitializer
413 define i1 @test20(i32 %x) {
414 ; CHECK-LABEL: @test20(
415 ; CHECK-NEXT: [[CMP:%.*]] = icmp eq i32 [[X:%.*]], 3
416 ; CHECK-NEXT: ret i1 [[CMP]]
419 %and = and i32 %shl, 8
420 %cmp = icmp ne i32 %and, 0
424 define <2 x i1> @test20vec(<2 x i32> %x) {
425 ; CHECK-LABEL: @test20vec(
426 ; CHECK-NEXT: [[CMP:%.*]] = icmp eq <2 x i32> [[X:%.*]], <i32 3, i32 3>
427 ; CHECK-NEXT: ret <2 x i1> [[CMP]]
429 %shl = shl <2 x i32> <i32 1, i32 1>, %x
430 %and = and <2 x i32> %shl, <i32 8, i32 8>
431 %cmp = icmp ne <2 x i32> %and, zeroinitializer
435 define i1 @test20a(i32 %x) {
436 ; CHECK-LABEL: @test20a(
437 ; CHECK-NEXT: [[CMP:%.*]] = icmp ult i32 [[X:%.*]], 3
438 ; CHECK-NEXT: ret i1 [[CMP]]
441 %and = and i32 %shl, 7
442 %cmp = icmp ne i32 %and, 0
446 define <2 x i1> @test20a_vec(<2 x i32> %x) {
447 ; CHECK-LABEL: @test20a_vec(
448 ; CHECK-NEXT: [[CMP:%.*]] = icmp ult <2 x i32> [[X:%.*]], <i32 3, i32 3>
449 ; CHECK-NEXT: ret <2 x i1> [[CMP]]
451 %shl = shl <2 x i32> <i32 1, i32 1>, %x
452 %and = and <2 x i32> %shl, <i32 7, i32 7>
453 %cmp = icmp ne <2 x i32> %and, zeroinitializer
457 define i1 @test21(i8 %x, i8 %y) {
458 ; CHECK-LABEL: @test21(
459 ; CHECK-NEXT: [[B:%.*]] = icmp ugt i8 [[X:%.*]], 3
460 ; CHECK-NEXT: ret i1 [[B]]
463 %B = icmp ugt i8 %A, 3
467 define i1 @test22(i8 %x, i8 %y) {
468 ; CHECK-LABEL: @test22(
469 ; CHECK-NEXT: [[B:%.*]] = icmp ult i8 [[X:%.*]], 4
470 ; CHECK-NEXT: ret i1 [[B]]
473 %B = icmp ult i8 %A, 4
478 define i1 @test23(i32 %x) {
479 ; CHECK-LABEL: @test23(
480 ; CHECK-NEXT: [[I4:%.*]] = icmp sgt i32 [[X:%.*]], 1328634634
481 ; CHECK-NEXT: ret i1 [[I4]]
483 %i3 = sdiv i32 %x, -1328634635
484 %i4 = icmp eq i32 %i3, -1
488 define <2 x i1> @test23vec(<2 x i32> %x) {
489 ; CHECK-LABEL: @test23vec(
490 ; CHECK-NEXT: [[I4:%.*]] = icmp sgt <2 x i32> [[X:%.*]], <i32 1328634634, i32 1328634634>
491 ; CHECK-NEXT: ret <2 x i1> [[I4]]
493 %i3 = sdiv <2 x i32> %x, <i32 -1328634635, i32 -1328634635>
494 %i4 = icmp eq <2 x i32> %i3, <i32 -1, i32 -1>
498 @X = global [1000 x i32] zeroinitializer
501 define i1 @test24(i64 %i) {
502 ; CHECK-LABEL: @test24(
503 ; CHECK-NEXT: [[CMP:%.*]] = icmp eq i64 [[I:%.*]], 1000
504 ; CHECK-NEXT: ret i1 [[CMP]]
506 %p1 = getelementptr inbounds i32, i32* getelementptr inbounds ([1000 x i32], [1000 x i32]* @X, i64 0, i64 0), i64 %i
507 %cmp = icmp eq i32* %p1, getelementptr inbounds ([1000 x i32], [1000 x i32]* @X, i64 1, i64 0)
511 @X_as1 = addrspace(1) global [1000 x i32] zeroinitializer
513 define i1 @test24_as1(i64 %i) {
514 ; CHECK-LABEL: @test24_as1(
515 ; CHECK-NEXT: [[TMP1:%.*]] = trunc i64 [[I:%.*]] to i16
516 ; CHECK-NEXT: [[CMP:%.*]] = icmp eq i16 [[TMP1]], 1000
517 ; CHECK-NEXT: ret i1 [[CMP]]
519 %p1 = getelementptr inbounds i32, i32 addrspace(1)* getelementptr inbounds ([1000 x i32], [1000 x i32] addrspace(1)* @X_as1, i64 0, i64 0), i64 %i
520 %cmp = icmp eq i32 addrspace(1)* %p1, getelementptr inbounds ([1000 x i32], [1000 x i32] addrspace(1)* @X_as1, i64 1, i64 0)
524 ; X - Z > Y - Z -> X > Y if there is no overflow.
525 define i1 @test27(i32 %x, i32 %y, i32 %z) {
526 ; CHECK-LABEL: @test27(
527 ; CHECK-NEXT: [[C:%.*]] = icmp sgt i32 [[X:%.*]], [[Y:%.*]]
528 ; CHECK-NEXT: ret i1 [[C]]
530 %lhs = sub nsw i32 %x, %z
531 %rhs = sub nsw i32 %y, %z
532 %c = icmp sgt i32 %lhs, %rhs
536 define i1 @test27_extra_uses(i32 %x, i32 %y, i32 %z) {
537 ; CHECK-LABEL: @test27_extra_uses(
538 ; CHECK-NEXT: [[LHS:%.*]] = sub nsw i32 [[X:%.*]], [[Z:%.*]]
539 ; CHECK-NEXT: call void @foo(i32 [[LHS]])
540 ; CHECK-NEXT: [[RHS:%.*]] = sub nsw i32 [[Y:%.*]], [[Z]]
541 ; CHECK-NEXT: call void @foo(i32 [[RHS]])
542 ; CHECK-NEXT: [[C:%.*]] = icmp sgt i32 [[X]], [[Y]]
543 ; CHECK-NEXT: ret i1 [[C]]
545 %lhs = sub nsw i32 %x, %z
546 call void @foo(i32 %lhs)
547 %rhs = sub nsw i32 %y, %z
548 call void @foo(i32 %rhs)
549 %c = icmp sgt i32 %lhs, %rhs
553 ; X - Z > Y - Z -> X > Y if there is no overflow.
554 define i1 @test28(i32 %x, i32 %y, i32 %z) {
555 ; CHECK-LABEL: @test28(
556 ; CHECK-NEXT: [[C:%.*]] = icmp ugt i32 [[X:%.*]], [[Y:%.*]]
557 ; CHECK-NEXT: ret i1 [[C]]
559 %lhs = sub nuw i32 %x, %z
560 %rhs = sub nuw i32 %y, %z
561 %c = icmp ugt i32 %lhs, %rhs
565 define i1 @test28_extra_uses(i32 %x, i32 %y, i32 %z) {
566 ; CHECK-LABEL: @test28_extra_uses(
567 ; CHECK-NEXT: [[LHS:%.*]] = sub nuw i32 [[X:%.*]], [[Z:%.*]]
568 ; CHECK-NEXT: call void @foo(i32 [[LHS]])
569 ; CHECK-NEXT: [[RHS:%.*]] = sub nuw i32 [[Y:%.*]], [[Z]]
570 ; CHECK-NEXT: call void @foo(i32 [[RHS]])
571 ; CHECK-NEXT: [[C:%.*]] = icmp ugt i32 [[X]], [[Y]]
572 ; CHECK-NEXT: ret i1 [[C]]
574 %lhs = sub nuw i32 %x, %z
575 call void @foo(i32 %lhs)
576 %rhs = sub nuw i32 %y, %z
577 call void @foo(i32 %rhs)
578 %c = icmp ugt i32 %lhs, %rhs
582 ; PR36969 - https://bugs.llvm.org/show_bug.cgi?id=36969
584 define i1 @ugt_sub(i32 %xsrc, i32 %y) {
585 ; CHECK-LABEL: @ugt_sub(
586 ; CHECK-NEXT: [[X:%.*]] = udiv i32 [[XSRC:%.*]], 42
587 ; CHECK-NEXT: [[CMP:%.*]] = icmp ult i32 [[X]], [[Y:%.*]]
588 ; CHECK-NEXT: ret i1 [[CMP]]
590 %x = udiv i32 %xsrc, 42 ; thwart complexity-based canonicalization
591 %sub = sub i32 %x, %y
592 %cmp = icmp ugt i32 %sub, %x
596 ; Swap operands and predicate. Try a vector type to verify that works too.
598 define <2 x i1> @ult_sub(<2 x i8> %xsrc, <2 x i8> %y) {
599 ; CHECK-LABEL: @ult_sub(
600 ; CHECK-NEXT: [[X:%.*]] = udiv <2 x i8> [[XSRC:%.*]], <i8 42, i8 -42>
601 ; CHECK-NEXT: [[CMP:%.*]] = icmp ult <2 x i8> [[X]], [[Y:%.*]]
602 ; CHECK-NEXT: ret <2 x i1> [[CMP]]
604 %x = udiv <2 x i8> %xsrc, <i8 42, i8 -42> ; thwart complexity-based canonicalization
605 %sub = sub <2 x i8> %x, %y
606 %cmp = icmp ult <2 x i8> %x, %sub
610 ; X - Y > X -> 0 > Y if there is no overflow.
611 define i1 @test33(i32 %x, i32 %y) {
612 ; CHECK-LABEL: @test33(
613 ; CHECK-NEXT: [[C:%.*]] = icmp slt i32 [[Y:%.*]], 0
614 ; CHECK-NEXT: ret i1 [[C]]
616 %lhs = sub nsw i32 %x, %y
617 %c = icmp sgt i32 %lhs, %x
621 ; X - Y > X -> 0 > Y if there is no overflow.
622 define i1 @test34(i32 %x, i32 %y) {
623 ; CHECK-LABEL: @test34(
624 ; CHECK-NEXT: ret i1 false
626 %lhs = sub nuw i32 %x, %y
627 %c = icmp ugt i32 %lhs, %x
631 ; X > X - Y -> Y > 0 if there is no overflow.
632 define i1 @test35(i32 %x, i32 %y) {
633 ; CHECK-LABEL: @test35(
634 ; CHECK-NEXT: [[C:%.*]] = icmp sgt i32 [[Y:%.*]], 0
635 ; CHECK-NEXT: ret i1 [[C]]
637 %rhs = sub nsw i32 %x, %y
638 %c = icmp sgt i32 %x, %rhs
642 ; X > X - Y -> Y > 0 if there is no overflow.
643 define i1 @test36(i32 %x, i32 %y) {
644 ; CHECK-LABEL: @test36(
645 ; CHECK-NEXT: [[C:%.*]] = icmp ne i32 [[Y:%.*]], 0
646 ; CHECK-NEXT: ret i1 [[C]]
648 %rhs = sub nuw i32 %x, %y
649 %c = icmp ugt i32 %x, %rhs
653 ; X - Y > X - Z -> Z > Y if there is no overflow.
654 define i1 @test37(i32 %x, i32 %y, i32 %z) {
655 ; CHECK-LABEL: @test37(
656 ; CHECK-NEXT: [[C:%.*]] = icmp sgt i32 [[Z:%.*]], [[Y:%.*]]
657 ; CHECK-NEXT: ret i1 [[C]]
659 %lhs = sub nsw i32 %x, %y
660 %rhs = sub nsw i32 %x, %z
661 %c = icmp sgt i32 %lhs, %rhs
665 define i1 @test37_extra_uses(i32 %x, i32 %y, i32 %z) {
666 ; CHECK-LABEL: @test37_extra_uses(
667 ; CHECK-NEXT: [[LHS:%.*]] = sub nsw i32 [[X:%.*]], [[Y:%.*]]
668 ; CHECK-NEXT: call void @foo(i32 [[LHS]])
669 ; CHECK-NEXT: [[RHS:%.*]] = sub nsw i32 [[X]], [[Z:%.*]]
670 ; CHECK-NEXT: call void @foo(i32 [[RHS]])
671 ; CHECK-NEXT: [[C:%.*]] = icmp sgt i32 [[Z]], [[Y]]
672 ; CHECK-NEXT: ret i1 [[C]]
674 %lhs = sub nsw i32 %x, %y
675 call void @foo(i32 %lhs)
676 %rhs = sub nsw i32 %x, %z
677 call void @foo(i32 %rhs)
678 %c = icmp sgt i32 %lhs, %rhs
682 ; TODO: Min/max pattern should not prevent the fold.
684 define i32 @neg_max_s32(i32 %x, i32 %y) {
685 ; CHECK-LABEL: @neg_max_s32(
686 ; CHECK-NEXT: [[C:%.*]] = icmp slt i32 [[Y:%.*]], [[X:%.*]]
687 ; CHECK-NEXT: [[S_V:%.*]] = select i1 [[C]], i32 [[Y]], i32 [[X]]
688 ; CHECK-NEXT: ret i32 [[S_V]]
690 %nx = sub nsw i32 0, %x
691 %ny = sub nsw i32 0, %y
692 %c = icmp slt i32 %nx, %ny
693 %s = select i1 %c, i32 %ny, i32 %nx
694 %r = sub nsw i32 0, %s
698 define <4 x i32> @neg_max_v4s32(<4 x i32> %x, <4 x i32> %y) {
699 ; CHECK-LABEL: @neg_max_v4s32(
700 ; CHECK-NEXT: [[C:%.*]] = icmp sgt <4 x i32> [[Y:%.*]], [[X:%.*]]
701 ; CHECK-NEXT: [[S_V:%.*]] = select <4 x i1> [[C]], <4 x i32> [[X]], <4 x i32> [[Y]]
702 ; CHECK-NEXT: ret <4 x i32> [[S_V]]
704 %nx = sub nsw <4 x i32> zeroinitializer, %x
705 %ny = sub nsw <4 x i32> zeroinitializer, %y
706 %c = icmp sgt <4 x i32> %nx, %ny
707 %s = select <4 x i1> %c, <4 x i32> %nx, <4 x i32> %ny
708 %r = sub <4 x i32> zeroinitializer, %s
712 ; X - Y > X - Z -> Z > Y if there is no overflow.
713 define i1 @test38(i32 %x, i32 %y, i32 %z) {
714 ; CHECK-LABEL: @test38(
715 ; CHECK-NEXT: [[C:%.*]] = icmp ugt i32 [[Z:%.*]], [[Y:%.*]]
716 ; CHECK-NEXT: ret i1 [[C]]
718 %lhs = sub nuw i32 %x, %y
719 %rhs = sub nuw i32 %x, %z
720 %c = icmp ugt i32 %lhs, %rhs
724 define i1 @test38_extra_uses(i32 %x, i32 %y, i32 %z) {
725 ; CHECK-LABEL: @test38_extra_uses(
726 ; CHECK-NEXT: [[LHS:%.*]] = sub nuw i32 [[X:%.*]], [[Y:%.*]]
727 ; CHECK-NEXT: call void @foo(i32 [[LHS]])
728 ; CHECK-NEXT: [[RHS:%.*]] = sub nuw i32 [[X]], [[Z:%.*]]
729 ; CHECK-NEXT: call void @foo(i32 [[RHS]])
730 ; CHECK-NEXT: [[C:%.*]] = icmp ugt i32 [[Z]], [[Y]]
731 ; CHECK-NEXT: ret i1 [[C]]
733 %lhs = sub nuw i32 %x, %y
734 call void @foo(i32 %lhs)
735 %rhs = sub nuw i32 %x, %z
736 call void @foo(i32 %rhs)
737 %c = icmp ugt i32 %lhs, %rhs
742 define i1 @test39(i32 %X, i32 %Y) {
743 ; CHECK-LABEL: @test39(
744 ; CHECK-NEXT: [[B:%.*]] = icmp eq i32 [[X:%.*]], 0
745 ; CHECK-NEXT: ret i1 [[B]]
747 %A = ashr exact i32 %X, %Y
748 %B = icmp eq i32 %A, 0
752 define <2 x i1> @test39vec(<2 x i32> %X, <2 x i32> %Y) {
753 ; CHECK-LABEL: @test39vec(
754 ; CHECK-NEXT: [[B:%.*]] = icmp eq <2 x i32> [[X:%.*]], zeroinitializer
755 ; CHECK-NEXT: ret <2 x i1> [[B]]
757 %A = ashr exact <2 x i32> %X, %Y
758 %B = icmp eq <2 x i32> %A, zeroinitializer
762 define i1 @test40(i32 %X, i32 %Y) {
763 ; CHECK-LABEL: @test40(
764 ; CHECK-NEXT: [[B:%.*]] = icmp ne i32 [[X:%.*]], 0
765 ; CHECK-NEXT: ret i1 [[B]]
767 %A = lshr exact i32 %X, %Y
768 %B = icmp ne i32 %A, 0
772 define <2 x i1> @test40vec(<2 x i32> %X, <2 x i32> %Y) {
773 ; CHECK-LABEL: @test40vec(
774 ; CHECK-NEXT: [[B:%.*]] = icmp ne <2 x i32> [[X:%.*]], zeroinitializer
775 ; CHECK-NEXT: ret <2 x i1> [[B]]
777 %A = lshr exact <2 x i32> %X, %Y
778 %B = icmp ne <2 x i32> %A, zeroinitializer
782 define i1 @shr_exact(i132 %x) {
783 ; CHECK-LABEL: @shr_exact(
784 ; CHECK-NEXT: [[CMP:%.*]] = icmp eq i132 [[X:%.*]], 32
785 ; CHECK-NEXT: ret i1 [[CMP]]
787 %sh = ashr exact i132 %x, 4
788 %cmp = icmp eq i132 %sh, 2
792 define <2 x i1> @shr_exact_vec(<2 x i132> %x) {
793 ; CHECK-LABEL: @shr_exact_vec(
794 ; CHECK-NEXT: [[CMP:%.*]] = icmp ne <2 x i132> [[X:%.*]], <i132 32, i132 32>
795 ; CHECK-NEXT: ret <2 x i1> [[CMP]]
797 %sh = lshr exact <2 x i132> %x, <i132 4, i132 4>
798 %cmp = icmp ne <2 x i132> %sh, <i132 2, i132 2>
803 define i1 @test41(i32 %X, i32 %Y) {
804 ; CHECK-LABEL: @test41(
805 ; CHECK-NEXT: ret i1 true
808 %B = icmp ugt i32 %Y, %A
812 define i1 @test42(i32 %X, i32 %Y) {
813 ; CHECK-LABEL: @test42(
814 ; CHECK-NEXT: [[B:%.*]] = icmp sgt i32 [[Y:%.*]], -1
815 ; CHECK-NEXT: ret i1 [[B]]
818 %B = icmp slt i32 %A, %Y
822 define i1 @test43(i32 %X, i32 %Y) {
823 ; CHECK-LABEL: @test43(
824 ; CHECK-NEXT: [[B:%.*]] = icmp slt i32 [[Y:%.*]], 0
825 ; CHECK-NEXT: ret i1 [[B]]
828 %B = icmp slt i32 %Y, %A
832 define i1 @test44(i32 %X, i32 %Y) {
833 ; CHECK-LABEL: @test44(
834 ; CHECK-NEXT: [[B:%.*]] = icmp sgt i32 [[Y:%.*]], -1
835 ; CHECK-NEXT: ret i1 [[B]]
838 %B = icmp slt i32 %A, %Y
842 define i1 @test45(i32 %X, i32 %Y) {
843 ; CHECK-LABEL: @test45(
844 ; CHECK-NEXT: [[B:%.*]] = icmp slt i32 [[Y:%.*]], 0
845 ; CHECK-NEXT: ret i1 [[B]]
848 %B = icmp slt i32 %Y, %A
853 define i1 @test46(i32 %X, i32 %Y, i32 %Z) {
854 ; CHECK-LABEL: @test46(
855 ; CHECK-NEXT: [[C:%.*]] = icmp ult i32 [[X:%.*]], [[Y:%.*]]
856 ; CHECK-NEXT: ret i1 [[C]]
858 %A = ashr exact i32 %X, %Z
859 %B = ashr exact i32 %Y, %Z
860 %C = icmp ult i32 %A, %B
865 define i1 @test47(i32 %X, i32 %Y, i32 %Z) {
866 ; CHECK-LABEL: @test47(
867 ; CHECK-NEXT: [[C:%.*]] = icmp ugt i32 [[X:%.*]], [[Y:%.*]]
868 ; CHECK-NEXT: ret i1 [[C]]
870 %A = ashr exact i32 %X, %Z
871 %B = ashr exact i32 %Y, %Z
872 %C = icmp ugt i32 %A, %B
877 define i1 @test48(i32 %X, i32 %Y, i32 %Z) {
878 ; CHECK-LABEL: @test48(
879 ; CHECK-NEXT: [[C:%.*]] = icmp eq i32 [[X:%.*]], [[Y:%.*]]
880 ; CHECK-NEXT: ret i1 [[C]]
882 %A = sdiv exact i32 %X, %Z
883 %B = sdiv exact i32 %Y, %Z
884 %C = icmp eq i32 %A, %B
888 ; The above transform only works for equality predicates.
890 define i1 @PR32949(i32 %X, i32 %Y, i32 %Z) {
891 ; CHECK-LABEL: @PR32949(
892 ; CHECK-NEXT: [[A:%.*]] = sdiv exact i32 [[X:%.*]], [[Z:%.*]]
893 ; CHECK-NEXT: [[B:%.*]] = sdiv exact i32 [[Y:%.*]], [[Z]]
894 ; CHECK-NEXT: [[C:%.*]] = icmp sgt i32 [[A]], [[B]]
895 ; CHECK-NEXT: ret i1 [[C]]
897 %A = sdiv exact i32 %X, %Z
898 %B = sdiv exact i32 %Y, %Z
899 %C = icmp sgt i32 %A, %B
904 define <2 x i1> @test49(<2 x i32> %tmp3) {
905 ; CHECK-LABEL: @test49(
907 ; CHECK-NEXT: ret <2 x i1> <i1 true, i1 true>
910 %tmp11 = and <2 x i32> %tmp3, <i32 3, i32 3>
911 %cmp = icmp ult <2 x i32> %tmp11, <i32 4, i32 4>
916 define i1 @test50(i16 %X, i32 %Y) {
917 ; CHECK-LABEL: @test50(
918 ; CHECK-NEXT: ret i1 true
920 %A = zext i16 %X to i32
922 %C = icmp sgt i32 %B, -1
926 define i1 @test51(i32 %X, i32 %Y) {
927 ; CHECK-LABEL: @test51(
928 ; CHECK-NEXT: [[A:%.*]] = and i32 [[X:%.*]], -2147483648
929 ; CHECK-NEXT: [[B:%.*]] = srem i32 [[A]], [[Y:%.*]]
930 ; CHECK-NEXT: [[C:%.*]] = icmp sgt i32 [[B]], -1
931 ; CHECK-NEXT: ret i1 [[C]]
933 %A = and i32 %X, 2147483648
935 %C = icmp sgt i32 %B, -1
939 define i1 @test52(i32 %x1) {
940 ; CHECK-LABEL: @test52(
941 ; CHECK-NEXT: [[TMP1:%.*]] = and i32 [[X1:%.*]], 16711935
942 ; CHECK-NEXT: [[TMP2:%.*]] = icmp eq i32 [[TMP1]], 4980863
943 ; CHECK-NEXT: ret i1 [[TMP2]]
945 %conv = and i32 %x1, 255
946 %cmp = icmp eq i32 %conv, 127
947 %tmp2 = lshr i32 %x1, 16
948 %tmp3 = trunc i32 %tmp2 to i8
949 %cmp15 = icmp eq i8 %tmp3, 76
951 %A = and i1 %cmp, %cmp15
955 define i1 @test52b(i128 %x1) {
956 ; CHECK-LABEL: @test52b(
957 ; CHECK-NEXT: [[TMP1:%.*]] = and i128 [[X1:%.*]], 16711935
958 ; CHECK-NEXT: [[TMP2:%.*]] = icmp eq i128 [[TMP1]], 4980863
959 ; CHECK-NEXT: ret i1 [[TMP2]]
961 %conv = and i128 %x1, 255
962 %cmp = icmp eq i128 %conv, 127
963 %tmp2 = lshr i128 %x1, 16
964 %tmp3 = trunc i128 %tmp2 to i8
965 %cmp15 = icmp eq i8 %tmp3, 76
967 %A = and i1 %cmp, %cmp15
972 define i1 @test53(i32 %a, i32 %b) {
973 ; CHECK-LABEL: @test53(
974 ; CHECK-NEXT: [[X:%.*]] = sdiv exact i32 [[A:%.*]], 30
975 ; CHECK-NEXT: [[Y:%.*]] = sdiv i32 [[B:%.*]], 30
976 ; CHECK-NEXT: [[Z:%.*]] = icmp eq i32 [[X]], [[Y]]
977 ; CHECK-NEXT: ret i1 [[Z]]
979 %x = sdiv exact i32 %a, 30
981 %z = icmp eq i32 %x, %y
985 define i1 @test54(i8 %a) {
986 ; CHECK-LABEL: @test54(
987 ; CHECK-NEXT: [[TMP1:%.*]] = and i8 [[A:%.*]], -64
988 ; CHECK-NEXT: [[RET:%.*]] = icmp eq i8 [[TMP1]], -128
989 ; CHECK-NEXT: ret i1 [[RET]]
991 %ext = zext i8 %a to i32
992 %and = and i32 %ext, 192
993 %ret = icmp eq i32 %and, 128
997 define i1 @test55(i32 %a) {
998 ; CHECK-LABEL: @test55(
999 ; CHECK-NEXT: [[CMP:%.*]] = icmp eq i32 [[A:%.*]], -123
1000 ; CHECK-NEXT: ret i1 [[CMP]]
1002 %sub = sub i32 0, %a
1003 %cmp = icmp eq i32 %sub, 123
1007 define <2 x i1> @test55vec(<2 x i32> %a) {
1008 ; CHECK-LABEL: @test55vec(
1009 ; CHECK-NEXT: [[CMP:%.*]] = icmp eq <2 x i32> [[A:%.*]], <i32 -123, i32 -123>
1010 ; CHECK-NEXT: ret <2 x i1> [[CMP]]
1012 %sub = sub <2 x i32> zeroinitializer, %a
1013 %cmp = icmp eq <2 x i32> %sub, <i32 123, i32 123>
1017 define i1 @test56(i32 %a) {
1018 ; CHECK-LABEL: @test56(
1019 ; CHECK-NEXT: [[CMP:%.*]] = icmp eq i32 [[A:%.*]], -113
1020 ; CHECK-NEXT: ret i1 [[CMP]]
1022 %sub = sub i32 10, %a
1023 %cmp = icmp eq i32 %sub, 123
1027 define <2 x i1> @test56vec(<2 x i32> %a) {
1028 ; CHECK-LABEL: @test56vec(
1029 ; CHECK-NEXT: [[CMP:%.*]] = icmp eq <2 x i32> [[A:%.*]], <i32 -113, i32 -113>
1030 ; CHECK-NEXT: ret <2 x i1> [[CMP]]
1032 %sub = sub <2 x i32> <i32 10, i32 10>, %a
1033 %cmp = icmp eq <2 x i32> %sub, <i32 123, i32 123>
1037 ; PR10267 Don't make icmps more expensive when no other inst is subsumed.
1038 declare void @foo(i32)
1039 define i1 @test57(i32 %a) {
1040 ; CHECK-LABEL: @test57(
1041 ; CHECK-NEXT: [[AND:%.*]] = and i32 [[A:%.*]], -2
1042 ; CHECK-NEXT: [[CMP:%.*]] = icmp ne i32 [[AND]], 0
1043 ; CHECK-NEXT: call void @foo(i32 [[AND]])
1044 ; CHECK-NEXT: ret i1 [[CMP]]
1046 %and = and i32 %a, -2
1047 %cmp = icmp ne i32 %and, 0
1048 call void @foo(i32 %and)
1052 ; rdar://problem/10482509
1053 define zeroext i1 @cmpabs1(i64 %val) {
1054 ; CHECK-LABEL: @cmpabs1(
1055 ; CHECK-NEXT: [[TOBOOL:%.*]] = icmp ne i64 [[VAL:%.*]], 0
1056 ; CHECK-NEXT: ret i1 [[TOBOOL]]
1058 %sub = sub nsw i64 0, %val
1059 %cmp = icmp slt i64 %val, 0
1060 %sub.val = select i1 %cmp, i64 %sub, i64 %val
1061 %tobool = icmp ne i64 %sub.val, 0
1065 define zeroext i1 @cmpabs2(i64 %val) {
1066 ; CHECK-LABEL: @cmpabs2(
1067 ; CHECK-NEXT: [[TOBOOL:%.*]] = icmp ne i64 [[VAL:%.*]], 0
1068 ; CHECK-NEXT: ret i1 [[TOBOOL]]
1070 %sub = sub nsw i64 0, %val
1071 %cmp = icmp slt i64 %val, 0
1072 %sub.val = select i1 %cmp, i64 %val, i64 %sub
1073 %tobool = icmp ne i64 %sub.val, 0
1077 define void @test58() {
1078 ; CHECK-LABEL: @test58(
1079 ; CHECK-NEXT: [[CALL:%.*]] = call i32 @test58_d(i64 36029346783166592)
1080 ; CHECK-NEXT: ret void
1082 %cast = bitcast <1 x i64> <i64 36029346783166592> to i64
1083 %call = call i32 @test58_d( i64 %cast)
1086 declare i32 @test58_d(i64)
1088 define i1 @test59(i8* %foo) {
1089 ; CHECK-LABEL: @test59(
1090 ; CHECK-NEXT: [[GEP1:%.*]] = getelementptr inbounds i8, i8* [[FOO:%.*]], i64 8
1091 ; CHECK-NEXT: [[USE:%.*]] = ptrtoint i8* [[GEP1]] to i64
1092 ; CHECK-NEXT: [[CALL:%.*]] = call i32 @test58_d(i64 [[USE]])
1093 ; CHECK-NEXT: ret i1 true
1095 %bit = bitcast i8* %foo to i32*
1096 %gep1 = getelementptr inbounds i32, i32* %bit, i64 2
1097 %gep2 = getelementptr inbounds i8, i8* %foo, i64 10
1098 %cast1 = bitcast i32* %gep1 to i8*
1099 %cmp = icmp ult i8* %cast1, %gep2
1100 %use = ptrtoint i8* %cast1 to i64
1101 %call = call i32 @test58_d(i64 %use)
1105 define i1 @test59_as1(i8 addrspace(1)* %foo) {
1106 ; CHECK-LABEL: @test59_as1(
1107 ; CHECK-NEXT: [[GEP1:%.*]] = getelementptr inbounds i8, i8 addrspace(1)* [[FOO:%.*]], i16 8
1108 ; CHECK-NEXT: [[TMP1:%.*]] = ptrtoint i8 addrspace(1)* [[GEP1]] to i16
1109 ; CHECK-NEXT: [[USE:%.*]] = zext i16 [[TMP1]] to i64
1110 ; CHECK-NEXT: [[CALL:%.*]] = call i32 @test58_d(i64 [[USE]])
1111 ; CHECK-NEXT: ret i1 true
1113 %bit = bitcast i8 addrspace(1)* %foo to i32 addrspace(1)*
1114 %gep1 = getelementptr inbounds i32, i32 addrspace(1)* %bit, i64 2
1115 %gep2 = getelementptr inbounds i8, i8 addrspace(1)* %foo, i64 10
1116 %cast1 = bitcast i32 addrspace(1)* %gep1 to i8 addrspace(1)*
1117 %cmp = icmp ult i8 addrspace(1)* %cast1, %gep2
1118 %use = ptrtoint i8 addrspace(1)* %cast1 to i64
1119 %call = call i32 @test58_d(i64 %use)
1123 define i1 @test60(i8* %foo, i64 %i, i64 %j) {
1124 ; CHECK-LABEL: @test60(
1125 ; CHECK-NEXT: [[GEP1_IDX:%.*]] = shl nuw i64 [[I:%.*]], 2
1126 ; CHECK-NEXT: [[TMP1:%.*]] = icmp slt i64 [[GEP1_IDX]], [[J:%.*]]
1127 ; CHECK-NEXT: ret i1 [[TMP1]]
1129 %bit = bitcast i8* %foo to i32*
1130 %gep1 = getelementptr inbounds i32, i32* %bit, i64 %i
1131 %gep2 = getelementptr inbounds i8, i8* %foo, i64 %j
1132 %cast1 = bitcast i32* %gep1 to i8*
1133 %cmp = icmp ult i8* %cast1, %gep2
1137 define i1 @test60_as1(i8 addrspace(1)* %foo, i64 %i, i64 %j) {
1138 ; CHECK-LABEL: @test60_as1(
1139 ; CHECK-NEXT: [[TMP1:%.*]] = trunc i64 [[I:%.*]] to i16
1140 ; CHECK-NEXT: [[TMP2:%.*]] = trunc i64 [[J:%.*]] to i16
1141 ; CHECK-NEXT: [[GEP1_IDX:%.*]] = shl nuw i16 [[TMP1]], 2
1142 ; CHECK-NEXT: [[TMP3:%.*]] = icmp slt i16 [[GEP1_IDX]], [[TMP2]]
1143 ; CHECK-NEXT: ret i1 [[TMP3]]
1145 %bit = bitcast i8 addrspace(1)* %foo to i32 addrspace(1)*
1146 %gep1 = getelementptr inbounds i32, i32 addrspace(1)* %bit, i64 %i
1147 %gep2 = getelementptr inbounds i8, i8 addrspace(1)* %foo, i64 %j
1148 %cast1 = bitcast i32 addrspace(1)* %gep1 to i8 addrspace(1)*
1149 %cmp = icmp ult i8 addrspace(1)* %cast1, %gep2
1153 ; Same as test60, but look through an addrspacecast instead of a
1154 ; bitcast. This uses the same sized addrspace.
1155 define i1 @test60_addrspacecast(i8* %foo, i64 %i, i64 %j) {
1156 ; CHECK-LABEL: @test60_addrspacecast(
1157 ; CHECK-NEXT: [[GEP1_IDX:%.*]] = shl nuw i64 [[I:%.*]], 2
1158 ; CHECK-NEXT: [[TMP1:%.*]] = icmp slt i64 [[GEP1_IDX]], [[J:%.*]]
1159 ; CHECK-NEXT: ret i1 [[TMP1]]
1161 %bit = addrspacecast i8* %foo to i32 addrspace(3)*
1162 %gep1 = getelementptr inbounds i32, i32 addrspace(3)* %bit, i64 %i
1163 %gep2 = getelementptr inbounds i8, i8* %foo, i64 %j
1164 %cast1 = addrspacecast i32 addrspace(3)* %gep1 to i8*
1165 %cmp = icmp ult i8* %cast1, %gep2
1169 define i1 @test60_addrspacecast_smaller(i8* %foo, i16 %i, i64 %j) {
1170 ; CHECK-LABEL: @test60_addrspacecast_smaller(
1171 ; CHECK-NEXT: [[GEP1_IDX:%.*]] = shl nuw i16 [[I:%.*]], 2
1172 ; CHECK-NEXT: [[TMP1:%.*]] = trunc i64 [[J:%.*]] to i16
1173 ; CHECK-NEXT: [[TMP2:%.*]] = icmp slt i16 [[GEP1_IDX]], [[TMP1]]
1174 ; CHECK-NEXT: ret i1 [[TMP2]]
1176 %bit = addrspacecast i8* %foo to i32 addrspace(1)*
1177 %gep1 = getelementptr inbounds i32, i32 addrspace(1)* %bit, i16 %i
1178 %gep2 = getelementptr inbounds i8, i8* %foo, i64 %j
1179 %cast1 = addrspacecast i32 addrspace(1)* %gep1 to i8*
1180 %cmp = icmp ult i8* %cast1, %gep2
1184 define i1 @test60_addrspacecast_larger(i8 addrspace(1)* %foo, i32 %i, i16 %j) {
1185 ; CHECK-LABEL: @test60_addrspacecast_larger(
1186 ; CHECK-NEXT: [[I_TR:%.*]] = trunc i32 [[I:%.*]] to i16
1187 ; CHECK-NEXT: [[TMP1:%.*]] = shl i16 [[I_TR]], 2
1188 ; CHECK-NEXT: [[TMP2:%.*]] = icmp slt i16 [[TMP1]], [[J:%.*]]
1189 ; CHECK-NEXT: ret i1 [[TMP2]]
1191 %bit = addrspacecast i8 addrspace(1)* %foo to i32 addrspace(2)*
1192 %gep1 = getelementptr inbounds i32, i32 addrspace(2)* %bit, i32 %i
1193 %gep2 = getelementptr inbounds i8, i8 addrspace(1)* %foo, i16 %j
1194 %cast1 = addrspacecast i32 addrspace(2)* %gep1 to i8 addrspace(1)*
1195 %cmp = icmp ult i8 addrspace(1)* %cast1, %gep2
1199 define i1 @test61(i8* %foo, i64 %i, i64 %j) {
1200 ; CHECK-LABEL: @test61(
1201 ; CHECK-NEXT: [[BIT:%.*]] = bitcast i8* [[FOO:%.*]] to i32*
1202 ; CHECK-NEXT: [[GEP1:%.*]] = getelementptr i32, i32* [[BIT]], i64 [[I:%.*]]
1203 ; CHECK-NEXT: [[GEP2:%.*]] = getelementptr i8, i8* [[FOO]], i64 [[J:%.*]]
1204 ; CHECK-NEXT: [[CAST1:%.*]] = bitcast i32* [[GEP1]] to i8*
1205 ; CHECK-NEXT: [[CMP:%.*]] = icmp ugt i8* [[GEP2]], [[CAST1]]
1206 ; CHECK-NEXT: ret i1 [[CMP]]
1208 %bit = bitcast i8* %foo to i32*
1209 %gep1 = getelementptr i32, i32* %bit, i64 %i
1210 %gep2 = getelementptr i8, i8* %foo, i64 %j
1211 %cast1 = bitcast i32* %gep1 to i8*
1212 %cmp = icmp ult i8* %cast1, %gep2
1214 ; Don't transform non-inbounds GEPs.
1217 define i1 @test61_as1(i8 addrspace(1)* %foo, i16 %i, i16 %j) {
1218 ; CHECK-LABEL: @test61_as1(
1219 ; CHECK-NEXT: [[BIT:%.*]] = bitcast i8 addrspace(1)* [[FOO:%.*]] to i32 addrspace(1)*
1220 ; CHECK-NEXT: [[GEP1:%.*]] = getelementptr i32, i32 addrspace(1)* [[BIT]], i16 [[I:%.*]]
1221 ; CHECK-NEXT: [[GEP2:%.*]] = getelementptr i8, i8 addrspace(1)* [[FOO]], i16 [[J:%.*]]
1222 ; CHECK-NEXT: [[CAST1:%.*]] = bitcast i32 addrspace(1)* [[GEP1]] to i8 addrspace(1)*
1223 ; CHECK-NEXT: [[CMP:%.*]] = icmp ugt i8 addrspace(1)* [[GEP2]], [[CAST1]]
1224 ; CHECK-NEXT: ret i1 [[CMP]]
1226 %bit = bitcast i8 addrspace(1)* %foo to i32 addrspace(1)*
1227 %gep1 = getelementptr i32, i32 addrspace(1)* %bit, i16 %i
1228 %gep2 = getelementptr i8, i8 addrspace(1)* %foo, i16 %j
1229 %cast1 = bitcast i32 addrspace(1)* %gep1 to i8 addrspace(1)*
1230 %cmp = icmp ult i8 addrspace(1)* %cast1, %gep2
1232 ; Don't transform non-inbounds GEPs.
1235 define i1 @test62(i8* %a) {
1236 ; CHECK-LABEL: @test62(
1237 ; CHECK-NEXT: ret i1 true
1239 %arrayidx1 = getelementptr inbounds i8, i8* %a, i64 1
1240 %arrayidx2 = getelementptr inbounds i8, i8* %a, i64 10
1241 %cmp = icmp slt i8* %arrayidx1, %arrayidx2
1245 define i1 @test62_as1(i8 addrspace(1)* %a) {
1246 ; CHECK-LABEL: @test62_as1(
1247 ; CHECK-NEXT: ret i1 true
1249 %arrayidx1 = getelementptr inbounds i8, i8 addrspace(1)* %a, i64 1
1250 %arrayidx2 = getelementptr inbounds i8, i8 addrspace(1)* %a, i64 10
1251 %cmp = icmp slt i8 addrspace(1)* %arrayidx1, %arrayidx2
1255 define i1 @test63(i8 %a, i32 %b) {
1256 ; CHECK-LABEL: @test63(
1257 ; CHECK-NEXT: [[TMP1:%.*]] = trunc i32 [[B:%.*]] to i8
1258 ; CHECK-NEXT: [[C:%.*]] = icmp eq i8 [[TMP1]], [[A:%.*]]
1259 ; CHECK-NEXT: ret i1 [[C]]
1261 %z = zext i8 %a to i32
1262 %t = and i32 %b, 255
1263 %c = icmp eq i32 %z, %t
1267 define i1 @test64(i8 %a, i32 %b) {
1268 ; CHECK-LABEL: @test64(
1269 ; CHECK-NEXT: [[TMP1:%.*]] = trunc i32 [[B:%.*]] to i8
1270 ; CHECK-NEXT: [[C:%.*]] = icmp eq i8 [[TMP1]], [[A:%.*]]
1271 ; CHECK-NEXT: ret i1 [[C]]
1273 %t = and i32 %b, 255
1274 %z = zext i8 %a to i32
1275 %c = icmp eq i32 %t, %z
1279 define i1 @test65(i64 %A, i64 %B) {
1280 ; CHECK-LABEL: @test65(
1281 ; CHECK-NEXT: ret i1 true
1283 %s1 = add i64 %A, %B
1284 %s2 = add i64 %A, %B
1285 %cmp = icmp eq i64 %s1, %s2
1289 define i1 @test66(i64 %A, i64 %B) {
1290 ; CHECK-LABEL: @test66(
1291 ; CHECK-NEXT: ret i1 true
1293 %s1 = add i64 %A, %B
1294 %s2 = add i64 %B, %A
1295 %cmp = icmp eq i64 %s1, %s2
1299 define i1 @test67(i32 %x) {
1300 ; CHECK-LABEL: @test67(
1301 ; CHECK-NEXT: [[AND:%.*]] = and i32 [[X:%.*]], 96
1302 ; CHECK-NEXT: [[CMP:%.*]] = icmp ne i32 [[AND]], 0
1303 ; CHECK-NEXT: ret i1 [[CMP]]
1305 %and = and i32 %x, 127
1306 %cmp = icmp sgt i32 %and, 31
1310 define i1 @test67inverse(i32 %x) {
1311 ; CHECK-LABEL: @test67inverse(
1312 ; CHECK-NEXT: [[AND:%.*]] = and i32 [[X:%.*]], 96
1313 ; CHECK-NEXT: [[CMP:%.*]] = icmp eq i32 [[AND]], 0
1314 ; CHECK-NEXT: ret i1 [[CMP]]
1316 %and = and i32 %x, 127
1317 %cmp = icmp sle i32 %and, 31
1321 ; The test above relies on 3 different folds.
1322 ; This test only checks the last of those (icmp ugt -> icmp ne).
1324 define <2 x i1> @test67vec(<2 x i32> %x) {
1325 ; CHECK-LABEL: @test67vec(
1326 ; CHECK-NEXT: [[AND:%.*]] = and <2 x i32> [[X:%.*]], <i32 96, i32 96>
1327 ; CHECK-NEXT: [[CMP:%.*]] = icmp ne <2 x i32> [[AND]], zeroinitializer
1328 ; CHECK-NEXT: ret <2 x i1> [[CMP]]
1330 %and = and <2 x i32> %x, <i32 96, i32 96>
1331 %cmp = icmp ugt <2 x i32> %and, <i32 31, i32 31>
1335 define <2 x i1> @test67vec2(<2 x i32> %x) {
1336 ; CHECK-LABEL: @test67vec2(
1337 ; CHECK-NEXT: [[AND:%.*]] = and <2 x i32> [[X:%.*]], <i32 96, i32 96>
1338 ; CHECK-NEXT: [[CMP:%.*]] = icmp ne <2 x i32> [[AND]], zeroinitializer
1339 ; CHECK-NEXT: ret <2 x i1> [[CMP]]
1341 %and = and <2 x i32> %x, <i32 127, i32 127>
1342 %cmp = icmp ugt <2 x i32> %and, <i32 31, i32 31>
1346 define <2 x i1> @test67vecinverse(<2 x i32> %x) {
1347 ; CHECK-LABEL: @test67vecinverse(
1348 ; CHECK-NEXT: [[AND:%.*]] = and <2 x i32> [[X:%.*]], <i32 96, i32 96>
1349 ; CHECK-NEXT: [[CMP:%.*]] = icmp eq <2 x i32> [[AND]], zeroinitializer
1350 ; CHECK-NEXT: ret <2 x i1> [[CMP]]
1352 %and = and <2 x i32> %x, <i32 96, i32 96>
1353 %cmp = icmp sle <2 x i32> %and, <i32 31, i32 31>
1357 define i1 @test68(i32 %x) {
1358 ; CHECK-LABEL: @test68(
1359 ; CHECK-NEXT: [[AND:%.*]] = and i32 [[X:%.*]], 127
1360 ; CHECK-NEXT: [[CMP:%.*]] = icmp ugt i32 [[AND]], 30
1361 ; CHECK-NEXT: ret i1 [[CMP]]
1363 %and = and i32 %x, 127
1364 %cmp = icmp sgt i32 %and, 30
1369 define i1 @test70(i32 %X) {
1370 ; CHECK-LABEL: @test70(
1371 ; CHECK-NEXT: [[A:%.*]] = srem i32 5, [[X:%.*]]
1372 ; CHECK-NEXT: [[C:%.*]] = icmp ne i32 [[A]], 2
1373 ; CHECK-NEXT: ret i1 [[C]]
1377 %C = icmp ne i32 %B, 4
1381 define <2 x i1> @test70vec(<2 x i32> %X) {
1382 ; CHECK-LABEL: @test70vec(
1383 ; CHECK-NEXT: [[C:%.*]] = icmp ne <2 x i32> [[X:%.*]], <i32 2, i32 2>
1384 ; CHECK-NEXT: ret <2 x i1> [[C]]
1386 %B = add <2 x i32> %X, <i32 2, i32 2>
1387 %C = icmp ne <2 x i32> %B, <i32 4, i32 4>
1391 define i1 @icmp_sext16trunc(i32 %x) {
1392 ; CHECK-LABEL: @icmp_sext16trunc(
1393 ; CHECK-NEXT: [[TMP1:%.*]] = trunc i32 [[X:%.*]] to i16
1394 ; CHECK-NEXT: [[CMP:%.*]] = icmp slt i16 [[TMP1]], 36
1395 ; CHECK-NEXT: ret i1 [[CMP]]
1397 %trunc = trunc i32 %x to i16
1398 %sext = sext i16 %trunc to i32
1399 %cmp = icmp slt i32 %sext, 36
1403 define i1 @icmp_sext8trunc(i32 %x) {
1404 ; CHECK-LABEL: @icmp_sext8trunc(
1405 ; CHECK-NEXT: [[TMP1:%.*]] = trunc i32 [[X:%.*]] to i8
1406 ; CHECK-NEXT: [[CMP:%.*]] = icmp slt i8 [[TMP1]], 36
1407 ; CHECK-NEXT: ret i1 [[CMP]]
1409 %trunc = trunc i32 %x to i8
1410 %sext = sext i8 %trunc to i32
1411 %cmp = icmp slt i32 %sext, 36
1415 ; Vectors should fold the same way.
1416 define <2 x i1> @icmp_sext8trunc_vec(<2 x i32> %x) {
1417 ; CHECK-LABEL: @icmp_sext8trunc_vec(
1418 ; CHECK-NEXT: [[TMP1:%.*]] = trunc <2 x i32> [[X:%.*]] to <2 x i8>
1419 ; CHECK-NEXT: [[CMP:%.*]] = icmp slt <2 x i8> [[TMP1]], <i8 36, i8 36>
1420 ; CHECK-NEXT: ret <2 x i1> [[CMP]]
1422 %trunc = trunc <2 x i32> %x to <2 x i8>
1423 %sext = sext <2 x i8> %trunc to <2 x i32>
1424 %cmp = icmp slt <2 x i32> %sext, <i32 36, i32 36>
1428 define i1 @icmp_shl16(i32 %x) {
1429 ; CHECK-LABEL: @icmp_shl16(
1430 ; CHECK-NEXT: [[TMP1:%.*]] = trunc i32 [[X:%.*]] to i16
1431 ; CHECK-NEXT: [[CMP:%.*]] = icmp slt i16 [[TMP1]], 36
1432 ; CHECK-NEXT: ret i1 [[CMP]]
1434 %shl = shl i32 %x, 16
1435 %cmp = icmp slt i32 %shl, 2359296
1439 ; D25952: Don't create illegal types like i15 in InstCombine
1441 define i1 @icmp_shl17(i32 %x) {
1442 ; CHECK-LABEL: @icmp_shl17(
1443 ; CHECK-NEXT: [[SHL:%.*]] = shl i32 [[X:%.*]], 17
1444 ; CHECK-NEXT: [[CMP:%.*]] = icmp slt i32 [[SHL]], 2359296
1445 ; CHECK-NEXT: ret i1 [[CMP]]
1447 %shl = shl i32 %x, 17
1448 %cmp = icmp slt i32 %shl, 2359296
1452 define <2 x i1> @icmp_shl16_vec(<2 x i32> %x) {
1453 ; CHECK-LABEL: @icmp_shl16_vec(
1454 ; CHECK-NEXT: [[TMP1:%.*]] = trunc <2 x i32> [[X:%.*]] to <2 x i16>
1455 ; CHECK-NEXT: [[CMP:%.*]] = icmp slt <2 x i16> [[TMP1]], <i16 36, i16 36>
1456 ; CHECK-NEXT: ret <2 x i1> [[CMP]]
1458 %shl = shl <2 x i32> %x, <i32 16, i32 16>
1459 %cmp = icmp slt <2 x i32> %shl, <i32 2359296, i32 2359296>
1463 define i1 @icmp_shl24(i32 %x) {
1464 ; CHECK-LABEL: @icmp_shl24(
1465 ; CHECK-NEXT: [[TMP1:%.*]] = trunc i32 [[X:%.*]] to i8
1466 ; CHECK-NEXT: [[CMP:%.*]] = icmp slt i8 [[TMP1]], 36
1467 ; CHECK-NEXT: ret i1 [[CMP]]
1469 %shl = shl i32 %x, 24
1470 %cmp = icmp slt i32 %shl, 603979776
1474 define i1 @icmp_shl_eq(i32 %x) {
1475 ; CHECK-LABEL: @icmp_shl_eq(
1476 ; CHECK-NEXT: [[MUL_MASK:%.*]] = and i32 [[X:%.*]], 134217727
1477 ; CHECK-NEXT: [[CMP:%.*]] = icmp eq i32 [[MUL_MASK]], 0
1478 ; CHECK-NEXT: ret i1 [[CMP]]
1480 %mul = shl i32 %x, 5
1481 %cmp = icmp eq i32 %mul, 0
1485 define <2 x i1> @icmp_shl_eq_vec(<2 x i32> %x) {
1486 ; CHECK-LABEL: @icmp_shl_eq_vec(
1487 ; CHECK-NEXT: [[MUL_MASK:%.*]] = and <2 x i32> [[X:%.*]], <i32 134217727, i32 134217727>
1488 ; CHECK-NEXT: [[CMP:%.*]] = icmp eq <2 x i32> [[MUL_MASK]], zeroinitializer
1489 ; CHECK-NEXT: ret <2 x i1> [[CMP]]
1491 %mul = shl <2 x i32> %x, <i32 5, i32 5>
1492 %cmp = icmp eq <2 x i32> %mul, zeroinitializer
1496 define i1 @icmp_shl_nsw_ne(i32 %x) {
1497 ; CHECK-LABEL: @icmp_shl_nsw_ne(
1498 ; CHECK-NEXT: [[CMP:%.*]] = icmp ne i32 [[X:%.*]], 0
1499 ; CHECK-NEXT: ret i1 [[CMP]]
1501 %mul = shl nsw i32 %x, 7
1502 %cmp = icmp ne i32 %mul, 0
1506 define <2 x i1> @icmp_shl_nsw_ne_vec(<2 x i32> %x) {
1507 ; CHECK-LABEL: @icmp_shl_nsw_ne_vec(
1508 ; CHECK-NEXT: [[CMP:%.*]] = icmp ne <2 x i32> [[X:%.*]], zeroinitializer
1509 ; CHECK-NEXT: ret <2 x i1> [[CMP]]
1511 %mul = shl nsw <2 x i32> %x, <i32 7, i32 7>
1512 %cmp = icmp ne <2 x i32> %mul, zeroinitializer
1516 define i1 @icmp_shl_ne(i32 %x) {
1517 ; CHECK-LABEL: @icmp_shl_ne(
1518 ; CHECK-NEXT: [[MUL_MASK:%.*]] = and i32 [[X:%.*]], 33554431
1519 ; CHECK-NEXT: [[CMP:%.*]] = icmp ne i32 [[MUL_MASK]], 0
1520 ; CHECK-NEXT: ret i1 [[CMP]]
1522 %mul = shl i32 %x, 7
1523 %cmp = icmp ne i32 %mul, 0
1527 define <2 x i1> @icmp_shl_ne_vec(<2 x i32> %x) {
1528 ; CHECK-LABEL: @icmp_shl_ne_vec(
1529 ; CHECK-NEXT: [[MUL_MASK:%.*]] = and <2 x i32> [[X:%.*]], <i32 33554431, i32 33554431>
1530 ; CHECK-NEXT: [[CMP:%.*]] = icmp ne <2 x i32> [[MUL_MASK]], zeroinitializer
1531 ; CHECK-NEXT: ret <2 x i1> [[CMP]]
1533 %mul = shl <2 x i32> %x, <i32 7, i32 7>
1534 %cmp = icmp ne <2 x i32> %mul, zeroinitializer
1538 define <2 x i1> @icmp_shl_nuw_ne_vec(<2 x i32> %x) {
1539 ; CHECK-LABEL: @icmp_shl_nuw_ne_vec(
1540 ; CHECK-NEXT: [[CMP:%.*]] = icmp ne <2 x i32> [[X:%.*]], <i32 2, i32 2>
1541 ; CHECK-NEXT: ret <2 x i1> [[CMP]]
1543 %shl = shl nuw <2 x i32> %x, <i32 7, i32 7>
1544 %cmp = icmp ne <2 x i32> %shl, <i32 256, i32 256>
1548 ; If the (mul x, C) preserved the sign and this is sign test,
1549 ; compare the LHS operand instead
1550 define i1 @icmp_mul_nsw(i32 %x) {
1551 ; CHECK-LABEL: @icmp_mul_nsw(
1552 ; CHECK-NEXT: [[CMP:%.*]] = icmp sgt i32 [[X:%.*]], 0
1553 ; CHECK-NEXT: ret i1 [[CMP]]
1555 %mul = mul nsw i32 %x, 12
1556 %cmp = icmp sgt i32 %mul, 0
1560 define i1 @icmp_mul_nsw1(i32 %x) {
1561 ; CHECK-LABEL: @icmp_mul_nsw1(
1562 ; CHECK-NEXT: [[CMP:%.*]] = icmp slt i32 [[X:%.*]], 0
1563 ; CHECK-NEXT: ret i1 [[CMP]]
1565 %mul = mul nsw i32 %x, 12
1566 %cmp = icmp sle i32 %mul, -1
1570 define i1 @icmp_mul_nsw_neg(i32 %x) {
1571 ; CHECK-LABEL: @icmp_mul_nsw_neg(
1572 ; CHECK-NEXT: [[CMP:%.*]] = icmp slt i32 [[X:%.*]], 1
1573 ; CHECK-NEXT: ret i1 [[CMP]]
1575 %mul = mul nsw i32 %x, -12
1576 %cmp = icmp sge i32 %mul, 0
1580 define i1 @icmp_mul_nsw_neg1(i32 %x) {
1581 ; CHECK-LABEL: @icmp_mul_nsw_neg1(
1582 ; CHECK-NEXT: [[CMP:%.*]] = icmp slt i32 [[X:%.*]], 0
1583 ; CHECK-NEXT: ret i1 [[CMP]]
1585 %mul = mul nsw i32 %x, -12
1586 %cmp = icmp sge i32 %mul, 1
1590 define <2 x i1> @icmp_mul_nsw_neg1_vec(<2 x i32> %x) {
1591 ; CHECK-LABEL: @icmp_mul_nsw_neg1_vec(
1592 ; CHECK-NEXT: [[CMP:%.*]] = icmp slt <2 x i32> [[X:%.*]], zeroinitializer
1593 ; CHECK-NEXT: ret <2 x i1> [[CMP]]
1595 %mul = mul nsw <2 x i32> %x, <i32 -12, i32 -12>
1596 %cmp = icmp sge <2 x i32> %mul, <i32 1, i32 1>
1600 define i1 @icmp_mul_nsw_0(i32 %x) {
1601 ; CHECK-LABEL: @icmp_mul_nsw_0(
1602 ; CHECK-NEXT: ret i1 false
1604 %mul = mul nsw i32 %x, 0
1605 %cmp = icmp sgt i32 %mul, 0
1609 define i1 @icmp_mul(i32 %x) {
1610 ; CHECK-LABEL: @icmp_mul(
1611 ; CHECK-NEXT: [[MUL:%.*]] = mul i32 [[X:%.*]], -12
1612 ; CHECK-NEXT: [[CMP:%.*]] = icmp sgt i32 [[MUL]], -1
1613 ; CHECK-NEXT: ret i1 [[CMP]]
1615 %mul = mul i32 %x, -12
1616 %cmp = icmp sge i32 %mul, 0
1620 ; Checks for icmp (eq|ne) (mul x, C), 0
1621 define i1 @icmp_mul_neq0(i32 %x) {
1622 ; CHECK-LABEL: @icmp_mul_neq0(
1623 ; CHECK-NEXT: [[CMP:%.*]] = icmp ne i32 [[X:%.*]], 0
1624 ; CHECK-NEXT: ret i1 [[CMP]]
1626 %mul = mul nsw i32 %x, -12
1627 %cmp = icmp ne i32 %mul, 0
1631 define <2 x i1> @icmp_mul_neq0_vec(<2 x i32> %x) {
1632 ; CHECK-LABEL: @icmp_mul_neq0_vec(
1633 ; CHECK-NEXT: [[CMP:%.*]] = icmp ne <2 x i32> [[X:%.*]], zeroinitializer
1634 ; CHECK-NEXT: ret <2 x i1> [[CMP]]
1636 %mul = mul nsw <2 x i32> %x, <i32 -12, i32 -12>
1637 %cmp = icmp ne <2 x i32> %mul, zeroinitializer
1641 define i1 @icmp_mul_eq0(i32 %x) {
1642 ; CHECK-LABEL: @icmp_mul_eq0(
1643 ; CHECK-NEXT: [[CMP:%.*]] = icmp eq i32 [[X:%.*]], 0
1644 ; CHECK-NEXT: ret i1 [[CMP]]
1646 %mul = mul nsw i32 %x, 12
1647 %cmp = icmp eq i32 %mul, 0
1651 define i1 @icmp_mul0_eq0(i32 %x) {
1652 ; CHECK-LABEL: @icmp_mul0_eq0(
1653 ; CHECK-NEXT: ret i1 true
1655 %mul = mul i32 %x, 0
1656 %cmp = icmp eq i32 %mul, 0
1660 define i1 @icmp_mul0_ne0(i32 %x) {
1661 ; CHECK-LABEL: @icmp_mul0_ne0(
1662 ; CHECK-NEXT: ret i1 false
1664 %mul = mul i32 %x, 0
1665 %cmp = icmp ne i32 %mul, 0
1669 define i1 @icmp_sub1_sge(i32 %x, i32 %y) {
1670 ; CHECK-LABEL: @icmp_sub1_sge(
1671 ; CHECK-NEXT: [[CMP:%.*]] = icmp sgt i32 [[X:%.*]], [[Y:%.*]]
1672 ; CHECK-NEXT: ret i1 [[CMP]]
1674 %sub = add nsw i32 %x, -1
1675 %cmp = icmp sge i32 %sub, %y
1679 define i1 @icmp_add1_sgt(i32 %x, i32 %y) {
1680 ; CHECK-LABEL: @icmp_add1_sgt(
1681 ; CHECK-NEXT: [[CMP:%.*]] = icmp sge i32 [[X:%.*]], [[Y:%.*]]
1682 ; CHECK-NEXT: ret i1 [[CMP]]
1684 %add = add nsw i32 %x, 1
1685 %cmp = icmp sgt i32 %add, %y
1689 define i1 @icmp_sub1_slt(i32 %x, i32 %y) {
1690 ; CHECK-LABEL: @icmp_sub1_slt(
1691 ; CHECK-NEXT: [[CMP:%.*]] = icmp sle i32 [[X:%.*]], [[Y:%.*]]
1692 ; CHECK-NEXT: ret i1 [[CMP]]
1694 %sub = add nsw i32 %x, -1
1695 %cmp = icmp slt i32 %sub, %y
1699 define i1 @icmp_add1_sle(i32 %x, i32 %y) {
1700 ; CHECK-LABEL: @icmp_add1_sle(
1701 ; CHECK-NEXT: [[CMP:%.*]] = icmp slt i32 [[X:%.*]], [[Y:%.*]]
1702 ; CHECK-NEXT: ret i1 [[CMP]]
1704 %add = add nsw i32 %x, 1
1705 %cmp = icmp sle i32 %add, %y
1709 define i1 @icmp_add20_sge_add57(i32 %x, i32 %y) {
1710 ; CHECK-LABEL: @icmp_add20_sge_add57(
1711 ; CHECK-NEXT: [[TMP1:%.*]] = add nsw i32 [[Y:%.*]], 37
1712 ; CHECK-NEXT: [[CMP:%.*]] = icmp sle i32 [[TMP1]], [[X:%.*]]
1713 ; CHECK-NEXT: ret i1 [[CMP]]
1715 %1 = add nsw i32 %x, 20
1716 %2 = add nsw i32 %y, 57
1717 %cmp = icmp sge i32 %1, %2
1721 define i1 @icmp_sub57_sge_sub20(i32 %x, i32 %y) {
1722 ; CHECK-LABEL: @icmp_sub57_sge_sub20(
1723 ; CHECK-NEXT: [[TMP1:%.*]] = add nsw i32 [[X:%.*]], -37
1724 ; CHECK-NEXT: [[CMP:%.*]] = icmp sge i32 [[TMP1]], [[Y:%.*]]
1725 ; CHECK-NEXT: ret i1 [[CMP]]
1727 %1 = add nsw i32 %x, -57
1728 %2 = add nsw i32 %y, -20
1729 %cmp = icmp sge i32 %1, %2
1733 define i1 @icmp_and_shl_neg_ne_0(i32 %A, i32 %B) {
1734 ; CHECK-LABEL: @icmp_and_shl_neg_ne_0(
1735 ; CHECK-NEXT: [[SHL:%.*]] = shl i32 1, [[B:%.*]]
1736 ; CHECK-NEXT: [[TMP1:%.*]] = and i32 [[SHL]], [[A:%.*]]
1737 ; CHECK-NEXT: [[CMP:%.*]] = icmp eq i32 [[TMP1]], 0
1738 ; CHECK-NEXT: ret i1 [[CMP]]
1740 %neg = xor i32 %A, -1
1741 %shl = shl i32 1, %B
1742 %and = and i32 %shl, %neg
1743 %cmp = icmp ne i32 %and, 0
1747 define i1 @icmp_and_shl_neg_eq_0(i32 %A, i32 %B) {
1748 ; CHECK-LABEL: @icmp_and_shl_neg_eq_0(
1749 ; CHECK-NEXT: [[SHL:%.*]] = shl i32 1, [[B:%.*]]
1750 ; CHECK-NEXT: [[TMP1:%.*]] = and i32 [[SHL]], [[A:%.*]]
1751 ; CHECK-NEXT: [[CMP:%.*]] = icmp ne i32 [[TMP1]], 0
1752 ; CHECK-NEXT: ret i1 [[CMP]]
1754 %neg = xor i32 %A, -1
1755 %shl = shl i32 1, %B
1756 %and = and i32 %shl, %neg
1757 %cmp = icmp eq i32 %and, 0
1761 define i1 @icmp_add_and_shr_ne_0(i32 %X) {
1762 ; CHECK-LABEL: @icmp_add_and_shr_ne_0(
1763 ; CHECK-NEXT: [[AND:%.*]] = and i32 [[X:%.*]], 240
1764 ; CHECK-NEXT: [[TOBOOL:%.*]] = icmp ne i32 [[AND]], 224
1765 ; CHECK-NEXT: ret i1 [[TOBOOL]]
1767 %shr = lshr i32 %X, 4
1768 %and = and i32 %shr, 15
1769 %add = add i32 %and, -14
1770 %tobool = icmp ne i32 %add, 0
1774 define <2 x i1> @icmp_add_and_shr_ne_0_vec(<2 x i32> %X) {
1775 ; CHECK-LABEL: @icmp_add_and_shr_ne_0_vec(
1776 ; CHECK-NEXT: [[AND:%.*]] = and <2 x i32> [[X:%.*]], <i32 240, i32 240>
1777 ; CHECK-NEXT: [[TOBOOL:%.*]] = icmp ne <2 x i32> [[AND]], <i32 224, i32 224>
1778 ; CHECK-NEXT: ret <2 x i1> [[TOBOOL]]
1780 %shr = lshr <2 x i32> %X, <i32 4, i32 4>
1781 %and = and <2 x i32> %shr, <i32 15, i32 15>
1782 %add = add <2 x i32> %and, <i32 -14, i32 -14>
1783 %tobool = icmp ne <2 x i32> %add, zeroinitializer
1784 ret <2 x i1> %tobool
1787 ; Variation of the above with an extra use of the shift
1788 define i1 @icmp_and_shr_multiuse(i32 %X) {
1789 ; CHECK-LABEL: @icmp_and_shr_multiuse(
1790 ; CHECK-NEXT: [[AND:%.*]] = and i32 [[X:%.*]], 240
1791 ; CHECK-NEXT: [[AND2:%.*]] = and i32 [[X]], 496
1792 ; CHECK-NEXT: [[TOBOOL:%.*]] = icmp ne i32 [[AND]], 224
1793 ; CHECK-NEXT: [[TOBOOL2:%.*]] = icmp ne i32 [[AND2]], 432
1794 ; CHECK-NEXT: [[AND3:%.*]] = and i1 [[TOBOOL]], [[TOBOOL2]]
1795 ; CHECK-NEXT: ret i1 [[AND3]]
1797 %shr = lshr i32 %X, 4
1798 %and = and i32 %shr, 15
1799 %and2 = and i32 %shr, 31 ; second use of the shift
1800 %tobool = icmp ne i32 %and, 14
1801 %tobool2 = icmp ne i32 %and2, 27
1802 %and3 = and i1 %tobool, %tobool2
1806 ; Variation of the above with an ashr
1807 define i1 @icmp_and_ashr_multiuse(i32 %X) {
1808 ; CHECK-LABEL: @icmp_and_ashr_multiuse(
1809 ; CHECK-NEXT: [[AND:%.*]] = and i32 [[X:%.*]], 240
1810 ; CHECK-NEXT: [[AND2:%.*]] = and i32 [[X]], 496
1811 ; CHECK-NEXT: [[TOBOOL:%.*]] = icmp ne i32 [[AND]], 224
1812 ; CHECK-NEXT: [[TOBOOL2:%.*]] = icmp ne i32 [[AND2]], 432
1813 ; CHECK-NEXT: [[AND3:%.*]] = and i1 [[TOBOOL]], [[TOBOOL2]]
1814 ; CHECK-NEXT: ret i1 [[AND3]]
1816 %shr = ashr i32 %X, 4
1817 %and = and i32 %shr, 15
1818 %and2 = and i32 %shr, 31 ; second use of the shift
1819 %tobool = icmp ne i32 %and, 14
1820 %tobool2 = icmp ne i32 %and2, 27
1821 %and3 = and i1 %tobool, %tobool2
1825 define i1 @icmp_lshr_and_overshift(i8 %X) {
1826 ; CHECK-LABEL: @icmp_lshr_and_overshift(
1827 ; CHECK-NEXT: [[TOBOOL:%.*]] = icmp ugt i8 [[X:%.*]], 31
1828 ; CHECK-NEXT: ret i1 [[TOBOOL]]
1830 %shr = lshr i8 %X, 5
1831 %and = and i8 %shr, 15
1832 %tobool = icmp ne i8 %and, 0
1836 ; We shouldn't simplify this because the and uses bits that are shifted in.
1837 define i1 @icmp_ashr_and_overshift(i8 %X) {
1838 ; CHECK-LABEL: @icmp_ashr_and_overshift(
1839 ; CHECK-NEXT: [[SHR:%.*]] = ashr i8 [[X:%.*]], 5
1840 ; CHECK-NEXT: [[AND:%.*]] = and i8 [[SHR]], 15
1841 ; CHECK-NEXT: [[TOBOOL:%.*]] = icmp ne i8 [[AND]], 0
1842 ; CHECK-NEXT: ret i1 [[TOBOOL]]
1844 %shr = ashr i8 %X, 5
1845 %and = and i8 %shr, 15
1846 %tobool = icmp ne i8 %and, 0
1851 define i1 @test71(i8* %x) {
1852 ; CHECK-LABEL: @test71(
1853 ; CHECK-NEXT: ret i1 false
1855 %a = getelementptr i8, i8* %x, i64 8
1856 %b = getelementptr inbounds i8, i8* %x, i64 8
1857 %c = icmp ugt i8* %a, %b
1861 define i1 @test71_as1(i8 addrspace(1)* %x) {
1862 ; CHECK-LABEL: @test71_as1(
1863 ; CHECK-NEXT: ret i1 false
1865 %a = getelementptr i8, i8 addrspace(1)* %x, i64 8
1866 %b = getelementptr inbounds i8, i8 addrspace(1)* %x, i64 8
1867 %c = icmp ugt i8 addrspace(1)* %a, %b
1871 define i1 @icmp_shl_1_V_ult_32(i32 %V) {
1872 ; CHECK-LABEL: @icmp_shl_1_V_ult_32(
1873 ; CHECK-NEXT: [[CMP:%.*]] = icmp ult i32 [[V:%.*]], 5
1874 ; CHECK-NEXT: ret i1 [[CMP]]
1876 %shl = shl i32 1, %V
1877 %cmp = icmp ult i32 %shl, 32
1881 define <2 x i1> @icmp_shl_1_V_ult_32_vec(<2 x i32> %V) {
1882 ; CHECK-LABEL: @icmp_shl_1_V_ult_32_vec(
1883 ; CHECK-NEXT: [[CMP:%.*]] = icmp ult <2 x i32> [[V:%.*]], <i32 5, i32 5>
1884 ; CHECK-NEXT: ret <2 x i1> [[CMP]]
1886 %shl = shl <2 x i32> <i32 1, i32 1>, %V
1887 %cmp = icmp ult <2 x i32> %shl, <i32 32, i32 32>
1891 define i1 @icmp_shl_1_V_eq_32(i32 %V) {
1892 ; CHECK-LABEL: @icmp_shl_1_V_eq_32(
1893 ; CHECK-NEXT: [[CMP:%.*]] = icmp eq i32 [[V:%.*]], 5
1894 ; CHECK-NEXT: ret i1 [[CMP]]
1896 %shl = shl i32 1, %V
1897 %cmp = icmp eq i32 %shl, 32
1901 define <2 x i1> @icmp_shl_1_V_eq_32_vec(<2 x i32> %V) {
1902 ; CHECK-LABEL: @icmp_shl_1_V_eq_32_vec(
1903 ; CHECK-NEXT: [[CMP:%.*]] = icmp eq <2 x i32> [[V:%.*]], <i32 5, i32 5>
1904 ; CHECK-NEXT: ret <2 x i1> [[CMP]]
1906 %shl = shl <2 x i32> <i32 1, i32 1>, %V
1907 %cmp = icmp eq <2 x i32> %shl, <i32 32, i32 32>
1911 define i1 @icmp_shl_1_V_ult_30(i32 %V) {
1912 ; CHECK-LABEL: @icmp_shl_1_V_ult_30(
1913 ; CHECK-NEXT: [[CMP:%.*]] = icmp ult i32 [[V:%.*]], 5
1914 ; CHECK-NEXT: ret i1 [[CMP]]
1916 %shl = shl i32 1, %V
1917 %cmp = icmp ult i32 %shl, 30
1921 define <2 x i1> @icmp_shl_1_V_ult_30_vec(<2 x i32> %V) {
1922 ; CHECK-LABEL: @icmp_shl_1_V_ult_30_vec(
1923 ; CHECK-NEXT: [[CMP:%.*]] = icmp ult <2 x i32> [[V:%.*]], <i32 5, i32 5>
1924 ; CHECK-NEXT: ret <2 x i1> [[CMP]]
1926 %shl = shl <2 x i32> <i32 1, i32 1>, %V
1927 %cmp = icmp ult <2 x i32> %shl, <i32 30, i32 30>
1931 define i1 @icmp_shl_1_V_ugt_30(i32 %V) {
1932 ; CHECK-LABEL: @icmp_shl_1_V_ugt_30(
1933 ; CHECK-NEXT: [[CMP:%.*]] = icmp ugt i32 [[V:%.*]], 4
1934 ; CHECK-NEXT: ret i1 [[CMP]]
1936 %shl = shl i32 1, %V
1937 %cmp = icmp ugt i32 %shl, 30
1941 define <2 x i1> @icmp_shl_1_V_ugt_30_vec(<2 x i32> %V) {
1942 ; CHECK-LABEL: @icmp_shl_1_V_ugt_30_vec(
1943 ; CHECK-NEXT: [[CMP:%.*]] = icmp ugt <2 x i32> [[V:%.*]], <i32 4, i32 4>
1944 ; CHECK-NEXT: ret <2 x i1> [[CMP]]
1946 %shl = shl <2 x i32> <i32 1, i32 1>, %V
1947 %cmp = icmp ugt <2 x i32> %shl, <i32 30, i32 30>
1951 define i1 @icmp_shl_1_V_ule_30(i32 %V) {
1952 ; CHECK-LABEL: @icmp_shl_1_V_ule_30(
1953 ; CHECK-NEXT: [[CMP:%.*]] = icmp ult i32 [[V:%.*]], 5
1954 ; CHECK-NEXT: ret i1 [[CMP]]
1956 %shl = shl i32 1, %V
1957 %cmp = icmp ule i32 %shl, 30
1961 define <2 x i1> @icmp_shl_1_V_ule_30_vec(<2 x i32> %V) {
1962 ; CHECK-LABEL: @icmp_shl_1_V_ule_30_vec(
1963 ; CHECK-NEXT: [[CMP:%.*]] = icmp ult <2 x i32> [[V:%.*]], <i32 5, i32 5>
1964 ; CHECK-NEXT: ret <2 x i1> [[CMP]]
1966 %shl = shl <2 x i32> <i32 1, i32 1>, %V
1967 %cmp = icmp ule <2 x i32> %shl, <i32 30, i32 30>
1971 define i1 @icmp_shl_1_V_uge_30(i32 %V) {
1972 ; CHECK-LABEL: @icmp_shl_1_V_uge_30(
1973 ; CHECK-NEXT: [[CMP:%.*]] = icmp ugt i32 [[V:%.*]], 4
1974 ; CHECK-NEXT: ret i1 [[CMP]]
1976 %shl = shl i32 1, %V
1977 %cmp = icmp uge i32 %shl, 30
1981 define <2 x i1> @icmp_shl_1_V_uge_30_vec(<2 x i32> %V) {
1982 ; CHECK-LABEL: @icmp_shl_1_V_uge_30_vec(
1983 ; CHECK-NEXT: [[CMP:%.*]] = icmp ugt <2 x i32> [[V:%.*]], <i32 4, i32 4>
1984 ; CHECK-NEXT: ret <2 x i1> [[CMP]]
1986 %shl = shl <2 x i32> <i32 1, i32 1>, %V
1987 %cmp = icmp uge <2 x i32> %shl, <i32 30, i32 30>
1991 define i1 @icmp_shl_1_V_uge_2147483648(i32 %V) {
1992 ; CHECK-LABEL: @icmp_shl_1_V_uge_2147483648(
1993 ; CHECK-NEXT: [[CMP:%.*]] = icmp eq i32 [[V:%.*]], 31
1994 ; CHECK-NEXT: ret i1 [[CMP]]
1996 %shl = shl i32 1, %V
1997 %cmp = icmp uge i32 %shl, 2147483648
2001 define <2 x i1> @icmp_shl_1_V_uge_2147483648_vec(<2 x i32> %V) {
2002 ; CHECK-LABEL: @icmp_shl_1_V_uge_2147483648_vec(
2003 ; CHECK-NEXT: [[CMP:%.*]] = icmp eq <2 x i32> [[V:%.*]], <i32 31, i32 31>
2004 ; CHECK-NEXT: ret <2 x i1> [[CMP]]
2006 %shl = shl <2 x i32> <i32 1, i32 1>, %V
2007 %cmp = icmp uge <2 x i32> %shl, <i32 2147483648, i32 2147483648>
2011 define i1 @icmp_shl_1_V_ult_2147483648(i32 %V) {
2012 ; CHECK-LABEL: @icmp_shl_1_V_ult_2147483648(
2013 ; CHECK-NEXT: [[CMP:%.*]] = icmp ne i32 [[V:%.*]], 31
2014 ; CHECK-NEXT: ret i1 [[CMP]]
2016 %shl = shl i32 1, %V
2017 %cmp = icmp ult i32 %shl, 2147483648
2021 define <2 x i1> @icmp_shl_1_V_ult_2147483648_vec(<2 x i32> %V) {
2022 ; CHECK-LABEL: @icmp_shl_1_V_ult_2147483648_vec(
2023 ; CHECK-NEXT: [[CMP:%.*]] = icmp ne <2 x i32> [[V:%.*]], <i32 31, i32 31>
2024 ; CHECK-NEXT: ret <2 x i1> [[CMP]]
2026 %shl = shl <2 x i32> <i32 1, i32 1>, %V
2027 %cmp = icmp ult <2 x i32> %shl, <i32 2147483648, i32 2147483648>
2031 define i1 @or_icmp_eq_B_0_icmp_ult_A_B(i64 %a, i64 %b) {
2032 ; CHECK-LABEL: @or_icmp_eq_B_0_icmp_ult_A_B(
2033 ; CHECK-NEXT: [[TMP1:%.*]] = add i64 [[B:%.*]], -1
2034 ; CHECK-NEXT: [[TMP2:%.*]] = icmp uge i64 [[TMP1]], [[A:%.*]]
2035 ; CHECK-NEXT: ret i1 [[TMP2]]
2037 %1 = icmp eq i64 %b, 0
2038 %2 = icmp ult i64 %a, %b
2043 define i1 @icmp_add_ult_2(i32 %X) {
2044 ; CHECK-LABEL: @icmp_add_ult_2(
2045 ; CHECK-NEXT: [[TMP1:%.*]] = and i32 [[X:%.*]], -2
2046 ; CHECK-NEXT: [[CMP:%.*]] = icmp eq i32 [[TMP1]], 14
2047 ; CHECK-NEXT: ret i1 [[CMP]]
2049 %add = add i32 %X, -14
2050 %cmp = icmp ult i32 %add, 2
2054 define <2 x i1> @icmp_add_X_-14_ult_2_vec(<2 x i32> %X) {
2055 ; CHECK-LABEL: @icmp_add_X_-14_ult_2_vec(
2056 ; CHECK-NEXT: [[TMP1:%.*]] = and <2 x i32> [[X:%.*]], <i32 -2, i32 -2>
2057 ; CHECK-NEXT: [[CMP:%.*]] = icmp eq <2 x i32> [[TMP1]], <i32 14, i32 14>
2058 ; CHECK-NEXT: ret <2 x i1> [[CMP]]
2060 %add = add <2 x i32> %X, <i32 -14, i32 -14>
2061 %cmp = icmp ult <2 x i32> %add, <i32 2, i32 2>
2065 define i1 @icmp_sub_3_X_ult_2(i32 %X) {
2066 ; CHECK-LABEL: @icmp_sub_3_X_ult_2(
2067 ; CHECK-NEXT: [[TMP1:%.*]] = or i32 [[X:%.*]], 1
2068 ; CHECK-NEXT: [[CMP:%.*]] = icmp eq i32 [[TMP1]], 3
2069 ; CHECK-NEXT: ret i1 [[CMP]]
2071 %add = sub i32 3, %X
2072 %cmp = icmp ult i32 %add, 2
2076 define <2 x i1> @icmp_sub_3_X_ult_2_vec(<2 x i32> %X) {
2077 ; CHECK-LABEL: @icmp_sub_3_X_ult_2_vec(
2078 ; CHECK-NEXT: [[TMP1:%.*]] = or <2 x i32> [[X:%.*]], <i32 1, i32 1>
2079 ; CHECK-NEXT: [[CMP:%.*]] = icmp eq <2 x i32> [[TMP1]], <i32 3, i32 3>
2080 ; CHECK-NEXT: ret <2 x i1> [[CMP]]
2082 %add = sub <2 x i32> <i32 3, i32 3>, %X
2083 %cmp = icmp ult <2 x i32> %add, <i32 2, i32 2>
2087 define i1 @icmp_add_X_-14_uge_2(i32 %X) {
2088 ; CHECK-LABEL: @icmp_add_X_-14_uge_2(
2089 ; CHECK-NEXT: [[TMP1:%.*]] = and i32 [[X:%.*]], -2
2090 ; CHECK-NEXT: [[CMP:%.*]] = icmp ne i32 [[TMP1]], 14
2091 ; CHECK-NEXT: ret i1 [[CMP]]
2093 %add = add i32 %X, -14
2094 %cmp = icmp uge i32 %add, 2
2098 define <2 x i1> @icmp_add_X_-14_uge_2_vec(<2 x i32> %X) {
2099 ; CHECK-LABEL: @icmp_add_X_-14_uge_2_vec(
2100 ; CHECK-NEXT: [[TMP1:%.*]] = and <2 x i32> [[X:%.*]], <i32 -2, i32 -2>
2101 ; CHECK-NEXT: [[CMP:%.*]] = icmp ne <2 x i32> [[TMP1]], <i32 14, i32 14>
2102 ; CHECK-NEXT: ret <2 x i1> [[CMP]]
2104 %add = add <2 x i32> %X, <i32 -14, i32 -14>
2105 %cmp = icmp uge <2 x i32> %add, <i32 2, i32 2>
2109 define i1 @icmp_sub_3_X_uge_2(i32 %X) {
2110 ; CHECK-LABEL: @icmp_sub_3_X_uge_2(
2111 ; CHECK-NEXT: [[TMP1:%.*]] = or i32 [[X:%.*]], 1
2112 ; CHECK-NEXT: [[CMP:%.*]] = icmp ne i32 [[TMP1]], 3
2113 ; CHECK-NEXT: ret i1 [[CMP]]
2115 %add = sub i32 3, %X
2116 %cmp = icmp uge i32 %add, 2
2120 define <2 x i1> @icmp_sub_3_X_uge_2_vec(<2 x i32> %X) {
2121 ; CHECK-LABEL: @icmp_sub_3_X_uge_2_vec(
2122 ; CHECK-NEXT: [[TMP1:%.*]] = or <2 x i32> [[X:%.*]], <i32 1, i32 1>
2123 ; CHECK-NEXT: [[CMP:%.*]] = icmp ne <2 x i32> [[TMP1]], <i32 3, i32 3>
2124 ; CHECK-NEXT: ret <2 x i1> [[CMP]]
2126 %add = sub <2 x i32> <i32 3, i32 3>, %X
2127 %cmp = icmp uge <2 x i32> %add, <i32 2, i32 2>
2131 define i1 @icmp_and_X_-16_eq-16(i32 %X) {
2132 ; CHECK-LABEL: @icmp_and_X_-16_eq-16(
2133 ; CHECK-NEXT: [[CMP:%.*]] = icmp ugt i32 [[X:%.*]], -17
2134 ; CHECK-NEXT: ret i1 [[CMP]]
2136 %and = and i32 %X, -16
2137 %cmp = icmp eq i32 %and, -16
2141 define <2 x i1> @icmp_and_X_-16_eq-16_vec(<2 x i32> %X) {
2142 ; CHECK-LABEL: @icmp_and_X_-16_eq-16_vec(
2143 ; CHECK-NEXT: [[CMP:%.*]] = icmp ugt <2 x i32> [[X:%.*]], <i32 -17, i32 -17>
2144 ; CHECK-NEXT: ret <2 x i1> [[CMP]]
2146 %and = and <2 x i32> %X, <i32 -16, i32 -16>
2147 %cmp = icmp eq <2 x i32> %and, <i32 -16, i32 -16>
2151 define i1 @icmp_and_X_-16_ne-16(i32 %X) {
2152 ; CHECK-LABEL: @icmp_and_X_-16_ne-16(
2153 ; CHECK-NEXT: [[CMP:%.*]] = icmp ult i32 [[X:%.*]], -16
2154 ; CHECK-NEXT: ret i1 [[CMP]]
2156 %and = and i32 %X, -16
2157 %cmp = icmp ne i32 %and, -16
2161 define <2 x i1> @icmp_and_X_-16_ne-16_vec(<2 x i32> %X) {
2162 ; CHECK-LABEL: @icmp_and_X_-16_ne-16_vec(
2163 ; CHECK-NEXT: [[CMP:%.*]] = icmp ult <2 x i32> [[X:%.*]], <i32 -16, i32 -16>
2164 ; CHECK-NEXT: ret <2 x i1> [[CMP]]
2166 %and = and <2 x i32> %X, <i32 -16, i32 -16>
2167 %cmp = icmp ne <2 x i32> %and, <i32 -16, i32 -16>
2171 ; PR32524: https://bugs.llvm.org/show_bug.cgi?id=32524
2172 ; X | C == C --> X <=u C (when C+1 is PowerOf2).
2174 define i1 @or1_eq1(i32 %x) {
2175 ; CHECK-LABEL: @or1_eq1(
2176 ; CHECK-NEXT: [[T1:%.*]] = icmp ult i32 [[X:%.*]], 2
2177 ; CHECK-NEXT: ret i1 [[T1]]
2180 %t1 = icmp eq i32 %t0, 1
2184 ; X | C == C --> X <=u C (when C+1 is PowerOf2).
2186 define <2 x i1> @or3_eq3_vec(<2 x i8> %x) {
2187 ; CHECK-LABEL: @or3_eq3_vec(
2188 ; CHECK-NEXT: [[T1:%.*]] = icmp ult <2 x i8> [[X:%.*]], <i8 4, i8 4>
2189 ; CHECK-NEXT: ret <2 x i1> [[T1]]
2191 %t0 = or <2 x i8> %x, <i8 3, i8 3>
2192 %t1 = icmp eq <2 x i8> %t0, <i8 3, i8 3>
2196 ; X | C != C --> X >u C (when C+1 is PowerOf2).
2198 define i1 @or7_ne7(i32 %x) {
2199 ; CHECK-LABEL: @or7_ne7(
2200 ; CHECK-NEXT: [[T1:%.*]] = icmp ugt i32 [[X:%.*]], 7
2201 ; CHECK-NEXT: ret i1 [[T1]]
2204 %t1 = icmp ne i32 %t0, 7
2208 ; X | C != C --> X >u C (when C+1 is PowerOf2).
2210 define <2 x i1> @or63_ne63_vec(<2 x i8> %x) {
2211 ; CHECK-LABEL: @or63_ne63_vec(
2212 ; CHECK-NEXT: [[T1:%.*]] = icmp ugt <2 x i8> [[X:%.*]], <i8 63, i8 63>
2213 ; CHECK-NEXT: ret <2 x i1> [[T1]]
2215 %t0 = or <2 x i8> %x, <i8 63, i8 63>
2216 %t1 = icmp ne <2 x i8> %t0, <i8 63, i8 63>
2220 ; PR40611: https://bugs.llvm.org/show_bug.cgi?id=40611
2221 ; X | C == C --> (X & ~C) == 0
2223 define i1 @orC_eqC(i32 %x) {
2224 ; CHECK-LABEL: @orC_eqC(
2225 ; CHECK-NEXT: [[TMP1:%.*]] = and i32 [[X:%.*]], -43
2226 ; CHECK-NEXT: [[T1:%.*]] = icmp eq i32 [[TMP1]], 0
2227 ; CHECK-NEXT: ret i1 [[T1]]
2230 %t1 = icmp eq i32 %t0, 42
2234 ; X | C == C --> (X & ~C) == 0
2236 define <2 x i1> @orC_eqC_vec(<2 x i8> %x) {
2237 ; CHECK-LABEL: @orC_eqC_vec(
2238 ; CHECK-NEXT: [[TMP1:%.*]] = and <2 x i8> [[X:%.*]], <i8 -44, i8 -44>
2239 ; CHECK-NEXT: [[T1:%.*]] = icmp eq <2 x i8> [[TMP1]], zeroinitializer
2240 ; CHECK-NEXT: ret <2 x i1> [[T1]]
2242 %t0 = or <2 x i8> %x, <i8 43, i8 43>
2243 %t1 = icmp eq <2 x i8> %t0, <i8 43, i8 43>
2247 ; X | C != C --> (X & ~C) != 0
2249 define i1 @orC_neC(i32 %x) {
2250 ; CHECK-LABEL: @orC_neC(
2251 ; CHECK-NEXT: [[TMP1:%.*]] = and i32 [[X:%.*]], 41
2252 ; CHECK-NEXT: [[T1:%.*]] = icmp ne i32 [[TMP1]], 0
2253 ; CHECK-NEXT: ret i1 [[T1]]
2255 %t0 = or i32 %x, -42
2256 %t1 = icmp ne i32 %t0, -42
2260 ; X | C != C --> (X & ~C) != 0
2262 define <2 x i1> @orC_neC_vec(<2 x i8> %x) {
2263 ; CHECK-LABEL: @orC_neC_vec(
2264 ; CHECK-NEXT: [[TMP1:%.*]] = and <2 x i8> [[X:%.*]], <i8 42, i8 42>
2265 ; CHECK-NEXT: [[T1:%.*]] = icmp ne <2 x i8> [[TMP1]], zeroinitializer
2266 ; CHECK-NEXT: ret <2 x i1> [[T1]]
2268 %t0 = or <2 x i8> %x, <i8 -43, i8 -43>
2269 %t1 = icmp ne <2 x i8> %t0, <i8 -43, i8 -43>
2273 define i1 @shrink_constant(i32 %X) {
2274 ; CHECK-LABEL: @shrink_constant(
2275 ; CHECK-NEXT: [[XOR:%.*]] = xor i32 [[X:%.*]], -12
2276 ; CHECK-NEXT: [[CMP:%.*]] = icmp ult i32 [[XOR]], 4
2277 ; CHECK-NEXT: ret i1 [[CMP]]
2279 %xor = xor i32 %X, -9
2280 %cmp = icmp ult i32 %xor, 4
2284 define <2 x i1> @shrink_constant_vec(<2 x i32> %X) {
2285 ; CHECK-LABEL: @shrink_constant_vec(
2286 ; CHECK-NEXT: [[XOR:%.*]] = xor <2 x i32> [[X:%.*]], <i32 -12, i32 -12>
2287 ; CHECK-NEXT: [[CMP:%.*]] = icmp ult <2 x i32> [[XOR]], <i32 4, i32 4>
2288 ; CHECK-NEXT: ret <2 x i1> [[CMP]]
2290 %xor = xor <2 x i32> %X, <i32 -9, i32 -9>
2291 %cmp = icmp ult <2 x i32> %xor, <i32 4, i32 4>
2295 ; This test requires 3 different transforms to get to the result.
2296 define i1 @icmp_sub_-1_X_ult_4(i32 %X) {
2297 ; CHECK-LABEL: @icmp_sub_-1_X_ult_4(
2298 ; CHECK-NEXT: [[CMP:%.*]] = icmp ugt i32 [[X:%.*]], -5
2299 ; CHECK-NEXT: ret i1 [[CMP]]
2301 %sub = sub i32 -1, %X
2302 %cmp = icmp ult i32 %sub, 4
2306 define <2 x i1> @icmp_xor_neg4_X_ult_4_vec(<2 x i32> %X) {
2307 ; CHECK-LABEL: @icmp_xor_neg4_X_ult_4_vec(
2308 ; CHECK-NEXT: [[CMP:%.*]] = icmp ugt <2 x i32> [[X:%.*]], <i32 -5, i32 -5>
2309 ; CHECK-NEXT: ret <2 x i1> [[CMP]]
2311 %xor = xor <2 x i32> %X, <i32 -4, i32 -4>
2312 %cmp = icmp ult <2 x i32> %xor, <i32 4, i32 4>
2316 define i1 @icmp_sub_-1_X_uge_4(i32 %X) {
2317 ; CHECK-LABEL: @icmp_sub_-1_X_uge_4(
2318 ; CHECK-NEXT: [[CMP:%.*]] = icmp ult i32 [[X:%.*]], -4
2319 ; CHECK-NEXT: ret i1 [[CMP]]
2321 %sub = sub i32 -1, %X
2322 %cmp = icmp uge i32 %sub, 4
2326 define <2 x i1> @icmp_xor_neg4_X_uge_4_vec(<2 x i32> %X) {
2327 ; CHECK-LABEL: @icmp_xor_neg4_X_uge_4_vec(
2328 ; CHECK-NEXT: [[CMP:%.*]] = icmp ult <2 x i32> [[X:%.*]], <i32 -4, i32 -4>
2329 ; CHECK-NEXT: ret <2 x i1> [[CMP]]
2331 %xor = xor <2 x i32> %X, <i32 -4, i32 -4>
2332 %cmp = icmp uge <2 x i32> %xor, <i32 4, i32 4>
2336 define <2 x i1> @xor_ult(<2 x i8> %x) {
2337 ; CHECK-LABEL: @xor_ult(
2338 ; CHECK-NEXT: [[R:%.*]] = icmp ugt <2 x i8> [[X:%.*]], <i8 3, i8 3>
2339 ; CHECK-NEXT: ret <2 x i1> [[R]]
2341 %xor = xor <2 x i8> %x, <i8 -4, i8 -4>
2342 %r = icmp ult <2 x i8> %xor, <i8 -4, i8 -4>
2346 define i1 @xor_ult_extra_use(i8 %x, i8* %p) {
2347 ; CHECK-LABEL: @xor_ult_extra_use(
2348 ; CHECK-NEXT: [[XOR:%.*]] = xor i8 [[X:%.*]], -32
2349 ; CHECK-NEXT: store i8 [[XOR]], i8* [[P:%.*]], align 1
2350 ; CHECK-NEXT: [[R:%.*]] = icmp ugt i8 [[X]], 31
2351 ; CHECK-NEXT: ret i1 [[R]]
2353 %xor = xor i8 %x, -32
2354 store i8 %xor, i8* %p
2355 %r = icmp ult i8 %xor, -32
2359 define <2 x i1> @xor_ugt(<2 x i8> %x) {
2360 ; CHECK-LABEL: @xor_ugt(
2361 ; CHECK-NEXT: [[R:%.*]] = icmp ugt <2 x i8> [[X:%.*]], <i8 7, i8 7>
2362 ; CHECK-NEXT: ret <2 x i1> [[R]]
2364 %xor = xor <2 x i8> %x, <i8 7, i8 7>
2365 %r = icmp ugt <2 x i8> %xor, <i8 7, i8 7>
2369 define i1 @xor_ugt_extra_use(i8 %x, i8* %p) {
2370 ; CHECK-LABEL: @xor_ugt_extra_use(
2371 ; CHECK-NEXT: [[XOR:%.*]] = xor i8 [[X:%.*]], 63
2372 ; CHECK-NEXT: store i8 [[XOR]], i8* [[P:%.*]], align 1
2373 ; CHECK-NEXT: [[R:%.*]] = icmp ugt i8 [[X]], 63
2374 ; CHECK-NEXT: ret i1 [[R]]
2376 %xor = xor i8 %x, 63
2377 store i8 %xor, i8* %p
2378 %r = icmp ugt i8 %xor, 63
2382 define i1 @icmp_swap_operands_for_cse(i32 %X, i32 %Y) {
2383 ; CHECK-LABEL: @icmp_swap_operands_for_cse(
2384 ; CHECK-NEXT: entry:
2385 ; CHECK-NEXT: [[SUB:%.*]] = sub i32 [[X:%.*]], [[Y:%.*]]
2386 ; CHECK-NEXT: [[CMP:%.*]] = icmp ult i32 [[X]], [[Y]]
2387 ; CHECK-NEXT: br i1 [[CMP]], label [[TRUE:%.*]], label [[FALSE:%.*]]
2389 ; CHECK-NEXT: [[TMP0:%.*]] = and i32 [[SUB]], 1
2390 ; CHECK-NEXT: br label [[END:%.*]]
2392 ; CHECK-NEXT: [[TMP1:%.*]] = and i32 [[SUB]], 16
2393 ; CHECK-NEXT: br label [[END]]
2395 ; CHECK-NEXT: [[RES_IN:%.*]] = phi i32 [ [[TMP0]], [[TRUE]] ], [ [[TMP1]], [[FALSE]] ]
2396 ; CHECK-NEXT: [[RES:%.*]] = icmp ne i32 [[RES_IN]], 0
2397 ; CHECK-NEXT: ret i1 [[RES]]
2400 %sub = sub i32 %X, %Y
2401 %cmp = icmp ugt i32 %Y, %X
2402 br i1 %cmp, label %true, label %false
2404 %restrue = trunc i32 %sub to i1
2407 %shift = lshr i32 %sub, 4
2408 %resfalse = trunc i32 %shift to i1
2411 %res = phi i1 [%restrue, %true], [%resfalse, %false]
2415 define i1 @icmp_swap_operands_for_cse2(i32 %X, i32 %Y) {
2416 ; CHECK-LABEL: @icmp_swap_operands_for_cse2(
2417 ; CHECK-NEXT: entry:
2418 ; CHECK-NEXT: [[CMP:%.*]] = icmp ult i32 [[X:%.*]], [[Y:%.*]]
2419 ; CHECK-NEXT: br i1 [[CMP]], label [[TRUE:%.*]], label [[FALSE:%.*]]
2421 ; CHECK-NEXT: [[SUB:%.*]] = sub i32 [[X]], [[Y]]
2422 ; CHECK-NEXT: [[SUB1:%.*]] = sub i32 [[X]], [[Y]]
2423 ; CHECK-NEXT: [[ADD:%.*]] = add i32 [[SUB]], [[SUB1]]
2424 ; CHECK-NEXT: br label [[END:%.*]]
2426 ; CHECK-NEXT: [[SUB2:%.*]] = sub i32 [[Y]], [[X]]
2427 ; CHECK-NEXT: br label [[END]]
2429 ; CHECK-NEXT: [[RES_IN_IN:%.*]] = phi i32 [ [[ADD]], [[TRUE]] ], [ [[SUB2]], [[FALSE]] ]
2430 ; CHECK-NEXT: [[RES_IN:%.*]] = and i32 [[RES_IN_IN]], 1
2431 ; CHECK-NEXT: [[RES:%.*]] = icmp ne i32 [[RES_IN]], 0
2432 ; CHECK-NEXT: ret i1 [[RES]]
2435 %cmp = icmp ugt i32 %Y, %X
2436 br i1 %cmp, label %true, label %false
2438 %sub = sub i32 %X, %Y
2439 %sub1 = sub i32 %X, %Y
2440 %add = add i32 %sub, %sub1
2441 %restrue = trunc i32 %add to i1
2444 %sub2 = sub i32 %Y, %X
2445 %resfalse = trunc i32 %sub2 to i1
2448 %res = phi i1 [%restrue, %true], [%resfalse, %false]
2452 define i1 @icmp_do_not_swap_operands_for_cse(i32 %X, i32 %Y) {
2453 ; CHECK-LABEL: @icmp_do_not_swap_operands_for_cse(
2454 ; CHECK-NEXT: entry:
2455 ; CHECK-NEXT: [[CMP:%.*]] = icmp ugt i32 [[Y:%.*]], [[X:%.*]]
2456 ; CHECK-NEXT: br i1 [[CMP]], label [[TRUE:%.*]], label [[FALSE:%.*]]
2458 ; CHECK-NEXT: [[SUB:%.*]] = sub i32 [[X]], [[Y]]
2459 ; CHECK-NEXT: br label [[END:%.*]]
2461 ; CHECK-NEXT: [[SUB2:%.*]] = sub i32 [[Y]], [[X]]
2462 ; CHECK-NEXT: br label [[END]]
2464 ; CHECK-NEXT: [[RES_IN_IN:%.*]] = phi i32 [ [[SUB]], [[TRUE]] ], [ [[SUB2]], [[FALSE]] ]
2465 ; CHECK-NEXT: [[RES_IN:%.*]] = and i32 [[RES_IN_IN]], 1
2466 ; CHECK-NEXT: [[RES:%.*]] = icmp ne i32 [[RES_IN]], 0
2467 ; CHECK-NEXT: ret i1 [[RES]]
2470 %cmp = icmp ugt i32 %Y, %X
2471 br i1 %cmp, label %true, label %false
2473 %sub = sub i32 %X, %Y
2474 %restrue = trunc i32 %sub to i1
2477 %sub2 = sub i32 %Y, %X
2478 %resfalse = trunc i32 %sub2 to i1
2481 %res = phi i1 [%restrue, %true], [%resfalse, %false]
2485 define i1 @icmp_lshr_lshr_eq(i32 %a, i32 %b) {
2486 ; CHECK-LABEL: @icmp_lshr_lshr_eq(
2487 ; CHECK-NEXT: [[Z_UNSHIFTED:%.*]] = xor i32 [[A:%.*]], [[B:%.*]]
2488 ; CHECK-NEXT: [[Z:%.*]] = icmp ult i32 [[Z_UNSHIFTED]], 1073741824
2489 ; CHECK-NEXT: ret i1 [[Z]]
2491 %x = lshr i32 %a, 30
2492 %y = lshr i32 %b, 30
2493 %z = icmp eq i32 %x, %y
2497 define i1 @icmp_ashr_ashr_ne(i32 %a, i32 %b) {
2498 ; CHECK-LABEL: @icmp_ashr_ashr_ne(
2499 ; CHECK-NEXT: [[Z_UNSHIFTED:%.*]] = xor i32 [[A:%.*]], [[B:%.*]]
2500 ; CHECK-NEXT: [[Z:%.*]] = icmp ugt i32 [[Z_UNSHIFTED]], 255
2501 ; CHECK-NEXT: ret i1 [[Z]]
2505 %z = icmp ne i32 %x, %y
2509 define i1 @icmp_neg_cst_slt(i32 %a) {
2510 ; CHECK-LABEL: @icmp_neg_cst_slt(
2511 ; CHECK-NEXT: [[TMP1:%.*]] = icmp sgt i32 [[A:%.*]], 10
2512 ; CHECK-NEXT: ret i1 [[TMP1]]
2514 %1 = sub nsw i32 0, %a
2515 %2 = icmp slt i32 %1, -10
2519 define i1 @icmp_and_or_lshr(i32 %x, i32 %y) {
2520 ; CHECK-LABEL: @icmp_and_or_lshr(
2521 ; CHECK-NEXT: [[SHF1:%.*]] = shl nuw i32 1, [[Y:%.*]]
2522 ; CHECK-NEXT: [[OR2:%.*]] = or i32 [[SHF1]], 1
2523 ; CHECK-NEXT: [[AND3:%.*]] = and i32 [[OR2]], [[X:%.*]]
2524 ; CHECK-NEXT: [[RET:%.*]] = icmp ne i32 [[AND3]], 0
2525 ; CHECK-NEXT: ret i1 [[RET]]
2527 %shf = lshr i32 %x, %y
2528 %or = or i32 %shf, %x
2529 %and = and i32 %or, 1
2530 %ret = icmp ne i32 %and, 0
2534 define <2 x i1> @icmp_and_or_lshr_vec(<2 x i32> %x, <2 x i32> %y) {
2535 ; CHECK-LABEL: @icmp_and_or_lshr_vec(
2536 ; CHECK-NEXT: [[SHF:%.*]] = lshr <2 x i32> [[X:%.*]], [[Y:%.*]]
2537 ; CHECK-NEXT: [[OR:%.*]] = or <2 x i32> [[SHF]], [[X]]
2538 ; CHECK-NEXT: [[RET:%.*]] = trunc <2 x i32> [[OR]] to <2 x i1>
2539 ; CHECK-NEXT: ret <2 x i1> [[RET]]
2541 %shf = lshr <2 x i32> %x, %y
2542 %or = or <2 x i32> %shf, %x
2543 %and = and <2 x i32> %or, <i32 1, i32 1>
2544 %ret = icmp ne <2 x i32> %and, zeroinitializer
2548 define <2 x i1> @icmp_and_or_lshr_vec_commute(<2 x i32> %xp, <2 x i32> %y) {
2549 ; CHECK-LABEL: @icmp_and_or_lshr_vec_commute(
2550 ; CHECK-NEXT: [[X:%.*]] = srem <2 x i32> [[XP:%.*]], <i32 42, i32 42>
2551 ; CHECK-NEXT: [[SHF:%.*]] = lshr <2 x i32> [[X]], [[Y:%.*]]
2552 ; CHECK-NEXT: [[OR:%.*]] = or <2 x i32> [[X]], [[SHF]]
2553 ; CHECK-NEXT: [[RET:%.*]] = trunc <2 x i32> [[OR]] to <2 x i1>
2554 ; CHECK-NEXT: ret <2 x i1> [[RET]]
2556 %x = srem <2 x i32> %xp, <i32 42, i32 -42> ; prevent complexity-based canonicalization
2557 %shf = lshr <2 x i32> %x, %y
2558 %or = or <2 x i32> %x, %shf
2559 %and = and <2 x i32> %or, <i32 1, i32 1>
2560 %ret = icmp ne <2 x i32> %and, zeroinitializer
2564 define i1 @icmp_and_or_lshr_cst(i32 %x) {
2565 ; CHECK-LABEL: @icmp_and_or_lshr_cst(
2566 ; CHECK-NEXT: [[AND1:%.*]] = and i32 [[X:%.*]], 3
2567 ; CHECK-NEXT: [[RET:%.*]] = icmp ne i32 [[AND1]], 0
2568 ; CHECK-NEXT: ret i1 [[RET]]
2570 %shf = lshr i32 %x, 1
2571 %or = or i32 %shf, %x
2572 %and = and i32 %or, 1
2573 %ret = icmp ne i32 %and, 0
2577 define <2 x i1> @icmp_and_or_lshr_cst_vec(<2 x i32> %x) {
2578 ; CHECK-LABEL: @icmp_and_or_lshr_cst_vec(
2579 ; CHECK-NEXT: [[TMP1:%.*]] = and <2 x i32> [[X:%.*]], <i32 3, i32 3>
2580 ; CHECK-NEXT: [[RET:%.*]] = icmp ne <2 x i32> [[TMP1]], zeroinitializer
2581 ; CHECK-NEXT: ret <2 x i1> [[RET]]
2583 %shf = lshr <2 x i32> %x, <i32 1, i32 1>
2584 %or = or <2 x i32> %shf, %x
2585 %and = and <2 x i32> %or, <i32 1, i32 1>
2586 %ret = icmp ne <2 x i32> %and, zeroinitializer
2590 define <2 x i1> @icmp_and_or_lshr_cst_vec_commute(<2 x i32> %xp) {
2591 ; CHECK-LABEL: @icmp_and_or_lshr_cst_vec_commute(
2592 ; CHECK-NEXT: [[X:%.*]] = srem <2 x i32> [[XP:%.*]], <i32 42, i32 42>
2593 ; CHECK-NEXT: [[TMP1:%.*]] = and <2 x i32> [[X]], <i32 3, i32 3>
2594 ; CHECK-NEXT: [[RET:%.*]] = icmp ne <2 x i32> [[TMP1]], zeroinitializer
2595 ; CHECK-NEXT: ret <2 x i1> [[RET]]
2597 %x = srem <2 x i32> %xp, <i32 42, i32 -42> ; prevent complexity-based canonicalization
2598 %shf = lshr <2 x i32> %x, <i32 1, i32 1>
2599 %or = or <2 x i32> %x, %shf
2600 %and = and <2 x i32> %or, <i32 1, i32 1>
2601 %ret = icmp ne <2 x i32> %and, zeroinitializer
2605 define i1 @shl_ap1_zero_ap2_non_zero_2(i32 %a) {
2606 ; CHECK-LABEL: @shl_ap1_zero_ap2_non_zero_2(
2607 ; CHECK-NEXT: [[CMP:%.*]] = icmp ugt i32 [[A:%.*]], 29
2608 ; CHECK-NEXT: ret i1 [[CMP]]
2610 %shl = shl i32 4, %a
2611 %cmp = icmp eq i32 %shl, 0
2615 define <2 x i1> @shl_ap1_zero_ap2_non_zero_2_vec(<2 x i32> %a) {
2616 ; CHECK-LABEL: @shl_ap1_zero_ap2_non_zero_2_vec(
2617 ; CHECK-NEXT: [[CMP:%.*]] = icmp ugt <2 x i32> [[A:%.*]], <i32 29, i32 29>
2618 ; CHECK-NEXT: ret <2 x i1> [[CMP]]
2620 %shl = shl <2 x i32> <i32 4, i32 4>, %a
2621 %cmp = icmp eq <2 x i32> %shl, zeroinitializer
2625 define i1 @shl_ap1_zero_ap2_non_zero_4(i32 %a) {
2626 ; CHECK-LABEL: @shl_ap1_zero_ap2_non_zero_4(
2627 ; CHECK-NEXT: [[CMP:%.*]] = icmp ugt i32 [[A:%.*]], 30
2628 ; CHECK-NEXT: ret i1 [[CMP]]
2630 %shl = shl i32 -2, %a
2631 %cmp = icmp eq i32 %shl, 0
2635 define i1 @shl_ap1_non_zero_ap2_non_zero_both_positive(i32 %a) {
2636 ; CHECK-LABEL: @shl_ap1_non_zero_ap2_non_zero_both_positive(
2637 ; CHECK-NEXT: [[CMP:%.*]] = icmp eq i32 [[A:%.*]], 0
2638 ; CHECK-NEXT: ret i1 [[CMP]]
2640 %shl = shl i32 50, %a
2641 %cmp = icmp eq i32 %shl, 50
2645 define i1 @shl_ap1_non_zero_ap2_non_zero_both_negative(i32 %a) {
2646 ; CHECK-LABEL: @shl_ap1_non_zero_ap2_non_zero_both_negative(
2647 ; CHECK-NEXT: [[CMP:%.*]] = icmp eq i32 [[A:%.*]], 0
2648 ; CHECK-NEXT: ret i1 [[CMP]]
2650 %shl = shl i32 -50, %a
2651 %cmp = icmp eq i32 %shl, -50
2655 define i1 @shl_ap1_non_zero_ap2_non_zero_ap1_1(i32 %a) {
2656 ; CHECK-LABEL: @shl_ap1_non_zero_ap2_non_zero_ap1_1(
2657 ; CHECK-NEXT: ret i1 false
2659 %shl = shl i32 50, %a
2660 %cmp = icmp eq i32 %shl, 25
2664 define i1 @shl_ap1_non_zero_ap2_non_zero_ap1_2(i32 %a) {
2665 ; CHECK-LABEL: @shl_ap1_non_zero_ap2_non_zero_ap1_2(
2666 ; CHECK-NEXT: [[CMP:%.*]] = icmp eq i32 [[A:%.*]], 1
2667 ; CHECK-NEXT: ret i1 [[CMP]]
2669 %shl = shl i32 25, %a
2670 %cmp = icmp eq i32 %shl, 50
2674 define i1 @shl_ap1_non_zero_ap2_non_zero_ap1_3(i32 %a) {
2675 ; CHECK-LABEL: @shl_ap1_non_zero_ap2_non_zero_ap1_3(
2676 ; CHECK-NEXT: ret i1 false
2678 %shl = shl i32 26, %a
2679 %cmp = icmp eq i32 %shl, 50
2683 define i1 @icmp_sgt_zero_add_nsw(i32 %a) {
2684 ; CHECK-LABEL: @icmp_sgt_zero_add_nsw(
2685 ; CHECK-NEXT: [[CMP:%.*]] = icmp sgt i32 [[A:%.*]], -1
2686 ; CHECK-NEXT: ret i1 [[CMP]]
2688 %add = add nsw i32 %a, 1
2689 %cmp = icmp sgt i32 %add, 0
2693 define i1 @icmp_sge_zero_add_nsw(i32 %a) {
2694 ; CHECK-LABEL: @icmp_sge_zero_add_nsw(
2695 ; CHECK-NEXT: [[CMP:%.*]] = icmp sgt i32 [[A:%.*]], -2
2696 ; CHECK-NEXT: ret i1 [[CMP]]
2698 %add = add nsw i32 %a, 1
2699 %cmp = icmp sge i32 %add, 0
2703 define i1 @icmp_sle_zero_add_nsw(i32 %a) {
2704 ; CHECK-LABEL: @icmp_sle_zero_add_nsw(
2705 ; CHECK-NEXT: [[CMP:%.*]] = icmp slt i32 [[A:%.*]], 0
2706 ; CHECK-NEXT: ret i1 [[CMP]]
2708 %add = add nsw i32 %a, 1
2709 %cmp = icmp sle i32 %add, 0
2713 define zeroext i1 @icmp_cmpxchg_strong(i32* %sc, i32 %old_val, i32 %new_val) {
2714 ; CHECK-LABEL: @icmp_cmpxchg_strong(
2715 ; CHECK-NEXT: [[XCHG:%.*]] = cmpxchg i32* [[SC:%.*]], i32 [[OLD_VAL:%.*]], i32 [[NEW_VAL:%.*]] seq_cst seq_cst
2716 ; CHECK-NEXT: [[ICMP:%.*]] = extractvalue { i32, i1 } [[XCHG]], 1
2717 ; CHECK-NEXT: ret i1 [[ICMP]]
2719 %xchg = cmpxchg i32* %sc, i32 %old_val, i32 %new_val seq_cst seq_cst
2720 %xtrc = extractvalue { i32, i1 } %xchg, 0
2721 %icmp = icmp eq i32 %xtrc, %old_val
2725 define i1 @f1(i64 %a, i64 %b) {
2727 ; CHECK-NEXT: [[V:%.*]] = icmp sge i64 [[A:%.*]], [[B:%.*]]
2728 ; CHECK-NEXT: ret i1 [[V]]
2730 %t = sub nsw i64 %a, %b
2731 %v = icmp sge i64 %t, 0
2735 define <2 x i1> @f1_vec(<2 x i64> %a, <2 x i64> %b) {
2736 ; CHECK-LABEL: @f1_vec(
2737 ; CHECK-NEXT: [[V:%.*]] = icmp sge <2 x i64> [[A:%.*]], [[B:%.*]]
2738 ; CHECK-NEXT: ret <2 x i1> [[V]]
2740 %t = sub nsw <2 x i64> %a, %b
2741 %v = icmp sgt <2 x i64> %t, <i64 -1, i64 -1>
2745 define i1 @f2(i64 %a, i64 %b) {
2747 ; CHECK-NEXT: [[V:%.*]] = icmp sgt i64 [[A:%.*]], [[B:%.*]]
2748 ; CHECK-NEXT: ret i1 [[V]]
2750 %t = sub nsw i64 %a, %b
2751 %v = icmp sgt i64 %t, 0
2755 define <2 x i1> @f2_vec(<2 x i64> %a, <2 x i64> %b) {
2756 ; CHECK-LABEL: @f2_vec(
2757 ; CHECK-NEXT: [[V:%.*]] = icmp sgt <2 x i64> [[A:%.*]], [[B:%.*]]
2758 ; CHECK-NEXT: ret <2 x i1> [[V]]
2760 %t = sub nsw <2 x i64> %a, %b
2761 %v = icmp sgt <2 x i64> %t, zeroinitializer
2765 define i1 @f3(i64 %a, i64 %b) {
2767 ; CHECK-NEXT: [[V:%.*]] = icmp slt i64 [[A:%.*]], [[B:%.*]]
2768 ; CHECK-NEXT: ret i1 [[V]]
2770 %t = sub nsw i64 %a, %b
2771 %v = icmp slt i64 %t, 0
2775 define <2 x i1> @f3_vec(<2 x i64> %a, <2 x i64> %b) {
2776 ; CHECK-LABEL: @f3_vec(
2777 ; CHECK-NEXT: [[V:%.*]] = icmp slt <2 x i64> [[A:%.*]], [[B:%.*]]
2778 ; CHECK-NEXT: ret <2 x i1> [[V]]
2780 %t = sub nsw <2 x i64> %a, %b
2781 %v = icmp slt <2 x i64> %t, zeroinitializer
2785 define i1 @f4(i64 %a, i64 %b) {
2787 ; CHECK-NEXT: [[V:%.*]] = icmp sle i64 [[A:%.*]], [[B:%.*]]
2788 ; CHECK-NEXT: ret i1 [[V]]
2790 %t = sub nsw i64 %a, %b
2791 %v = icmp sle i64 %t, 0
2795 define <2 x i1> @f4_vec(<2 x i64> %a, <2 x i64> %b) {
2796 ; CHECK-LABEL: @f4_vec(
2797 ; CHECK-NEXT: [[V:%.*]] = icmp sle <2 x i64> [[A:%.*]], [[B:%.*]]
2798 ; CHECK-NEXT: ret <2 x i1> [[V]]
2800 %t = sub nsw <2 x i64> %a, %b
2801 %v = icmp slt <2 x i64> %t, <i64 1, i64 1>
2805 define i32 @f5(i8 %a, i8 %b) {
2807 ; CHECK-NEXT: [[CONV:%.*]] = zext i8 [[A:%.*]] to i32
2808 ; CHECK-NEXT: [[CONV3:%.*]] = zext i8 [[B:%.*]] to i32
2809 ; CHECK-NEXT: [[SUB:%.*]] = sub nsw i32 [[CONV]], [[CONV3]]
2810 ; CHECK-NEXT: [[CMP4:%.*]] = icmp slt i32 [[SUB]], 0
2811 ; CHECK-NEXT: [[SUB7:%.*]] = sub nsw i32 0, [[SUB]]
2812 ; CHECK-NEXT: [[SUB7_SUB:%.*]] = select i1 [[CMP4]], i32 [[SUB7]], i32 [[SUB]]
2813 ; CHECK-NEXT: ret i32 [[SUB7_SUB]]
2815 %conv = zext i8 %a to i32
2816 %conv3 = zext i8 %b to i32
2817 %sub = sub nsw i32 %conv, %conv3
2818 %cmp4 = icmp slt i32 %sub, 0
2819 %sub7 = sub nsw i32 0, %sub
2820 %sub7.sub = select i1 %cmp4, i32 %sub7, i32 %sub
2824 define i32 @f6(i32 %a, i32 %b) {
2826 ; CHECK-NEXT: [[CMP_UNSHIFTED:%.*]] = xor i32 [[A:%.*]], [[B:%.*]]
2827 ; CHECK-NEXT: [[CMP_MASK:%.*]] = and i32 [[CMP_UNSHIFTED]], 255
2828 ; CHECK-NEXT: [[CMP:%.*]] = icmp eq i32 [[CMP_MASK]], 0
2829 ; CHECK-NEXT: [[S:%.*]] = select i1 [[CMP]], i32 10000, i32 0
2830 ; CHECK-NEXT: ret i32 [[S]]
2832 %sext = shl i32 %a, 24
2833 %conv = ashr i32 %sext, 24
2834 %sext6 = shl i32 %b, 24
2835 %conv4 = ashr i32 %sext6, 24
2836 %cmp = icmp eq i32 %conv, %conv4
2837 %s = select i1 %cmp, i32 10000, i32 0
2841 define i32 @f7(i32 %a, i32 %b) {
2843 ; CHECK-NEXT: [[CMP_UNSHIFTED:%.*]] = xor i32 [[A:%.*]], [[B:%.*]]
2844 ; CHECK-NEXT: [[CMP_MASK:%.*]] = and i32 [[CMP_UNSHIFTED]], 511
2845 ; CHECK-NEXT: [[CMP:%.*]] = icmp eq i32 [[CMP_MASK]], 0
2846 ; CHECK-NEXT: [[S:%.*]] = select i1 [[CMP]], i32 0, i32 10000
2847 ; CHECK-NEXT: ret i32 [[S]]
2849 %sext = shl i32 %a, 23
2850 %sext6 = shl i32 %b, 23
2851 %cmp = icmp ne i32 %sext, %sext6
2852 %s = select i1 %cmp, i32 10000, i32 0
2856 define i1 @f8(i32 %val, i32 %lim) {
2858 ; CHECK-NEXT: [[R:%.*]] = icmp ne i32 [[LIM:%.*]], 0
2859 ; CHECK-NEXT: ret i1 [[R]]
2861 %lim.sub = add i32 %lim, -1
2862 %val.and = and i32 %val, %lim.sub
2863 %r = icmp ult i32 %val.and, %lim
2867 define i1 @f9(i32 %val, i32 %lim) {
2869 ; CHECK-NEXT: [[R:%.*]] = icmp ne i32 [[LIM:%.*]], 0
2870 ; CHECK-NEXT: ret i1 [[R]]
2872 %lim.sub = sub i32 %lim, 1
2873 %val.and = and i32 %val, %lim.sub
2874 %r = icmp ult i32 %val.and, %lim
2878 define i1 @f10(i16 %p) {
2879 ; CHECK-LABEL: @f10(
2880 ; CHECK-NEXT: [[CMP580:%.*]] = icmp uge i16 [[P:%.*]], mul (i16 zext (i8 ptrtoint (i1 (i16)* @f10 to i8) to i16), i16 zext (i8 ptrtoint (i1 (i16)* @f10 to i8) to i16))
2881 ; CHECK-NEXT: ret i1 [[CMP580]]
2883 %cmp580 = icmp ule i16 mul (i16 zext (i8 ptrtoint (i1 (i16)* @f10 to i8) to i16), i16 zext (i8 ptrtoint (i1 (i16)* @f10 to i8) to i16)), %p
2887 ; Note: fptosi is used in various tests below to ensure that operand complexity
2888 ; canonicalization does not kick in, which would make some of the tests
2889 ; equivalent to one another.
2891 define i1 @cmp_sgt_rhs_dec(float %x, i32 %i) {
2892 ; CHECK-LABEL: @cmp_sgt_rhs_dec(
2893 ; CHECK-NEXT: [[CONV:%.*]] = fptosi float [[X:%.*]] to i32
2894 ; CHECK-NEXT: [[CMP:%.*]] = icmp sge i32 [[CONV]], [[I:%.*]]
2895 ; CHECK-NEXT: ret i1 [[CMP]]
2897 %conv = fptosi float %x to i32
2898 %dec = sub nsw i32 %i, 1
2899 %cmp = icmp sgt i32 %conv, %dec
2903 define i1 @cmp_sle_rhs_dec(float %x, i32 %i) {
2904 ; CHECK-LABEL: @cmp_sle_rhs_dec(
2905 ; CHECK-NEXT: [[CONV:%.*]] = fptosi float [[X:%.*]] to i32
2906 ; CHECK-NEXT: [[CMP:%.*]] = icmp slt i32 [[CONV]], [[I:%.*]]
2907 ; CHECK-NEXT: ret i1 [[CMP]]
2909 %conv = fptosi float %x to i32
2910 %dec = sub nsw i32 %i, 1
2911 %cmp = icmp sle i32 %conv, %dec
2915 define i1 @cmp_sge_rhs_inc(float %x, i32 %i) {
2916 ; CHECK-LABEL: @cmp_sge_rhs_inc(
2917 ; CHECK-NEXT: [[CONV:%.*]] = fptosi float [[X:%.*]] to i32
2918 ; CHECK-NEXT: [[CMP:%.*]] = icmp sgt i32 [[CONV]], [[I:%.*]]
2919 ; CHECK-NEXT: ret i1 [[CMP]]
2921 %conv = fptosi float %x to i32
2922 %inc = add nsw i32 %i, 1
2923 %cmp = icmp sge i32 %conv, %inc
2927 define i1 @cmp_slt_rhs_inc(float %x, i32 %i) {
2928 ; CHECK-LABEL: @cmp_slt_rhs_inc(
2929 ; CHECK-NEXT: [[CONV:%.*]] = fptosi float [[X:%.*]] to i32
2930 ; CHECK-NEXT: [[CMP:%.*]] = icmp sle i32 [[CONV]], [[I:%.*]]
2931 ; CHECK-NEXT: ret i1 [[CMP]]
2933 %conv = fptosi float %x to i32
2934 %inc = add nsw i32 %i, 1
2935 %cmp = icmp slt i32 %conv, %inc
2939 define i1 @PR26407(i32 %x, i32 %y) {
2940 ; CHECK-LABEL: @PR26407(
2941 ; CHECK-NEXT: [[ADDX:%.*]] = add i32 [[X:%.*]], 2147483647
2942 ; CHECK-NEXT: [[ADDY:%.*]] = add i32 [[Y:%.*]], 2147483647
2943 ; CHECK-NEXT: [[CMP:%.*]] = icmp uge i32 [[ADDX]], [[ADDY]]
2944 ; CHECK-NEXT: ret i1 [[CMP]]
2946 %addx = add i32 %x, 2147483647
2947 %addy = add i32 %y, 2147483647
2948 %cmp = icmp uge i32 %addx, %addy
2952 define i1 @cmp_inverse_mask_bits_set_eq(i32 %x) {
2953 ; CHECK-LABEL: @cmp_inverse_mask_bits_set_eq(
2954 ; CHECK-NEXT: [[TMP1:%.*]] = and i32 [[X:%.*]], -43
2955 ; CHECK-NEXT: [[CMP:%.*]] = icmp eq i32 [[TMP1]], -43
2956 ; CHECK-NEXT: ret i1 [[CMP]]
2959 %cmp = icmp eq i32 %or, -1
2963 define <2 x i1> @cmp_inverse_mask_bits_set_eq_vec(<2 x i32> %x) {
2964 ; CHECK-LABEL: @cmp_inverse_mask_bits_set_eq_vec(
2965 ; CHECK-NEXT: [[TMP1:%.*]] = and <2 x i32> [[X:%.*]], <i32 -43, i32 -43>
2966 ; CHECK-NEXT: [[CMP:%.*]] = icmp eq <2 x i32> [[TMP1]], <i32 -43, i32 -43>
2967 ; CHECK-NEXT: ret <2 x i1> [[CMP]]
2969 %or = or <2 x i32> %x, <i32 42, i32 42>
2970 %cmp = icmp eq <2 x i32> %or, <i32 -1, i32 -1>
2974 define i1 @cmp_inverse_mask_bits_set_ne(i32 %x) {
2975 ; CHECK-LABEL: @cmp_inverse_mask_bits_set_ne(
2976 ; CHECK-NEXT: [[TMP1:%.*]] = and i32 [[X:%.*]], -43
2977 ; CHECK-NEXT: [[CMP:%.*]] = icmp ne i32 [[TMP1]], -43
2978 ; CHECK-NEXT: ret i1 [[CMP]]
2981 %cmp = icmp ne i32 %or, -1
2985 ; When canonicalizing to 'gt/lt', make sure the constant is correct.
2987 define i1 @PR27792(i128 %a) {
2988 ; CHECK-LABEL: @PR27792(
2989 ; CHECK-NEXT: [[CMP:%.*]] = icmp sgt i128 [[A:%.*]], -1
2990 ; CHECK-NEXT: ret i1 [[CMP]]
2992 %cmp = icmp sge i128 %a, 0
2996 define i1 @PR27792_2(i128 %a) {
2997 ; CHECK-LABEL: @PR27792_2(
2998 ; CHECK-NEXT: [[B:%.*]] = icmp ne i128 [[A:%.*]], 0
2999 ; CHECK-NEXT: ret i1 [[B]]
3001 %b = icmp uge i128 %a, 1
3005 define i1 @ugtMaxSignedVal(i8 %a) {
3006 ; CHECK-LABEL: @ugtMaxSignedVal(
3007 ; CHECK-NEXT: [[CMP:%.*]] = icmp slt i8 [[A:%.*]], 0
3008 ; CHECK-NEXT: ret i1 [[CMP]]
3010 %cmp = icmp ugt i8 %a, 127
3014 define <2 x i1> @ugtMaxSignedValVec(<2 x i8> %a) {
3015 ; CHECK-LABEL: @ugtMaxSignedValVec(
3016 ; CHECK-NEXT: [[CMP:%.*]] = icmp slt <2 x i8> [[A:%.*]], zeroinitializer
3017 ; CHECK-NEXT: ret <2 x i1> [[CMP]]
3019 %cmp = icmp ugt <2 x i8> %a, <i8 127, i8 127>
3023 define i1 @ugtKnownBits(i8 %a) {
3024 ; CHECK-LABEL: @ugtKnownBits(
3025 ; CHECK-NEXT: [[B:%.*]] = and i8 [[A:%.*]], 17
3026 ; CHECK-NEXT: [[CMP:%.*]] = icmp eq i8 [[B]], 17
3027 ; CHECK-NEXT: ret i1 [[CMP]]
3030 %cmp = icmp ugt i8 %b, 16
3034 define <2 x i1> @ugtKnownBitsVec(<2 x i8> %a) {
3035 ; CHECK-LABEL: @ugtKnownBitsVec(
3036 ; CHECK-NEXT: [[B:%.*]] = and <2 x i8> [[A:%.*]], <i8 17, i8 17>
3037 ; CHECK-NEXT: [[CMP:%.*]] = icmp eq <2 x i8> [[B]], <i8 17, i8 17>
3038 ; CHECK-NEXT: ret <2 x i1> [[CMP]]
3040 %b = and <2 x i8> %a, <i8 17, i8 17>
3041 %cmp = icmp ugt <2 x i8> %b, <i8 16, i8 16>
3045 define i1 @or_ptrtoint_mismatch(i8* %p, i32* %q) {
3046 ; CHECK-LABEL: @or_ptrtoint_mismatch(
3047 ; CHECK-NEXT: [[TMP1:%.*]] = icmp eq i8* [[P:%.*]], null
3048 ; CHECK-NEXT: [[TMP2:%.*]] = icmp eq i32* [[Q:%.*]], null
3049 ; CHECK-NEXT: [[B:%.*]] = and i1 [[TMP1]], [[TMP2]]
3050 ; CHECK-NEXT: ret i1 [[B]]
3053 %pp = ptrtoint i8* %p to i64
3054 %qq = ptrtoint i32* %q to i64
3055 %o = or i64 %pp, %qq
3056 %b = icmp eq i64 %o, 0
3060 define i1 @icmp_add1_ugt(i32 %x, i32 %y) {
3061 ; CHECK-LABEL: @icmp_add1_ugt(
3062 ; CHECK-NEXT: [[CMP:%.*]] = icmp uge i32 [[X:%.*]], [[Y:%.*]]
3063 ; CHECK-NEXT: ret i1 [[CMP]]
3065 %add = add nuw i32 %x, 1
3066 %cmp = icmp ugt i32 %add, %y
3070 define i1 @icmp_add1_ule(i32 %x, i32 %y) {
3071 ; CHECK-LABEL: @icmp_add1_ule(
3072 ; CHECK-NEXT: [[CMP:%.*]] = icmp ult i32 [[X:%.*]], [[Y:%.*]]
3073 ; CHECK-NEXT: ret i1 [[CMP]]
3075 %add = add nuw i32 %x, 1
3076 %cmp = icmp ule i32 %add, %y
3080 define i1 @cmp_uge_rhs_inc(float %x, i32 %i) {
3081 ; CHECK-LABEL: @cmp_uge_rhs_inc(
3082 ; CHECK-NEXT: [[CONV:%.*]] = fptosi float [[X:%.*]] to i32
3083 ; CHECK-NEXT: [[CMP:%.*]] = icmp ugt i32 [[CONV]], [[I:%.*]]
3084 ; CHECK-NEXT: ret i1 [[CMP]]
3086 %conv = fptosi float %x to i32
3087 %inc = add nuw i32 %i, 1
3088 %cmp = icmp uge i32 %conv, %inc
3092 define i1 @cmp_ult_rhs_inc(float %x, i32 %i) {
3093 ; CHECK-LABEL: @cmp_ult_rhs_inc(
3094 ; CHECK-NEXT: [[CONV:%.*]] = fptosi float [[X:%.*]] to i32
3095 ; CHECK-NEXT: [[CMP:%.*]] = icmp ule i32 [[CONV]], [[I:%.*]]
3096 ; CHECK-NEXT: ret i1 [[CMP]]
3098 %conv = fptosi float %x to i32
3099 %inc = add nuw i32 %i, 1
3100 %cmp = icmp ult i32 %conv, %inc
3104 define i1 @cmp_sge_lhs_inc(i32 %x, i32 %y) {
3105 ; CHECK-LABEL: @cmp_sge_lhs_inc(
3106 ; CHECK-NEXT: [[INC:%.*]] = add nsw i32 [[X:%.*]], 1
3107 ; CHECK-NEXT: [[CMP:%.*]] = icmp sge i32 [[INC]], [[Y:%.*]]
3108 ; CHECK-NEXT: ret i1 [[CMP]]
3110 %inc = add nsw i32 %x, 1
3111 %cmp = icmp sge i32 %inc, %y
3115 define i1 @cmp_uge_lhs_inc(i32 %x, i32 %y) {
3116 ; CHECK-LABEL: @cmp_uge_lhs_inc(
3117 ; CHECK-NEXT: [[INC:%.*]] = add nuw i32 [[X:%.*]], 1
3118 ; CHECK-NEXT: [[CMP:%.*]] = icmp uge i32 [[INC]], [[Y:%.*]]
3119 ; CHECK-NEXT: ret i1 [[CMP]]
3121 %inc = add nuw i32 %x, 1
3122 %cmp = icmp uge i32 %inc, %y
3126 define i1 @cmp_sgt_lhs_dec(i32 %x, i32 %y) {
3127 ; CHECK-LABEL: @cmp_sgt_lhs_dec(
3128 ; CHECK-NEXT: [[DEC:%.*]] = add nsw i32 [[X:%.*]], -1
3129 ; CHECK-NEXT: [[CMP:%.*]] = icmp sgt i32 [[DEC]], [[Y:%.*]]
3130 ; CHECK-NEXT: ret i1 [[CMP]]
3132 %dec = sub nsw i32 %x, 1
3133 %cmp = icmp sgt i32 %dec, %y
3137 define i1 @cmp_ugt_lhs_dec(i32 %x, i32 %y) {
3138 ; CHECK-LABEL: @cmp_ugt_lhs_dec(
3139 ; CHECK-NEXT: [[DEC:%.*]] = add i32 [[X:%.*]], -1
3140 ; CHECK-NEXT: [[CMP:%.*]] = icmp ugt i32 [[DEC]], [[Y:%.*]]
3141 ; CHECK-NEXT: ret i1 [[CMP]]
3143 %dec = sub nuw i32 %x, 1
3144 %cmp = icmp ugt i32 %dec, %y
3148 define i1 @cmp_sle_rhs_inc(float %x, i32 %y) {
3149 ; CHECK-LABEL: @cmp_sle_rhs_inc(
3150 ; CHECK-NEXT: [[CONV:%.*]] = fptosi float [[X:%.*]] to i32
3151 ; CHECK-NEXT: [[INC:%.*]] = add nsw i32 [[Y:%.*]], 1
3152 ; CHECK-NEXT: [[CMP:%.*]] = icmp sge i32 [[INC]], [[CONV]]
3153 ; CHECK-NEXT: ret i1 [[CMP]]
3155 %conv = fptosi float %x to i32
3156 %inc = add nsw i32 %y, 1
3157 %cmp = icmp sle i32 %conv, %inc
3161 define i1 @cmp_ule_rhs_inc(float %x, i32 %y) {
3162 ; CHECK-LABEL: @cmp_ule_rhs_inc(
3163 ; CHECK-NEXT: [[CONV:%.*]] = fptosi float [[X:%.*]] to i32
3164 ; CHECK-NEXT: [[INC:%.*]] = add nuw i32 [[Y:%.*]], 1
3165 ; CHECK-NEXT: [[CMP:%.*]] = icmp uge i32 [[INC]], [[CONV]]
3166 ; CHECK-NEXT: ret i1 [[CMP]]
3168 %conv = fptosi float %x to i32
3169 %inc = add nuw i32 %y, 1
3170 %cmp = icmp ule i32 %conv, %inc
3174 define i1 @cmp_slt_rhs_dec(float %x, i32 %y) {
3175 ; CHECK-LABEL: @cmp_slt_rhs_dec(
3176 ; CHECK-NEXT: [[CONV:%.*]] = fptosi float [[X:%.*]] to i32
3177 ; CHECK-NEXT: [[DEC:%.*]] = add nsw i32 [[Y:%.*]], -1
3178 ; CHECK-NEXT: [[CMP:%.*]] = icmp sgt i32 [[DEC]], [[CONV]]
3179 ; CHECK-NEXT: ret i1 [[CMP]]
3181 %conv = fptosi float %x to i32
3182 %dec = sub nsw i32 %y, 1
3183 %cmp = icmp slt i32 %conv, %dec
3187 define i1 @cmp_ult_rhs_dec(float %x, i32 %y) {
3188 ; CHECK-LABEL: @cmp_ult_rhs_dec(
3189 ; CHECK-NEXT: [[CONV:%.*]] = fptosi float [[X:%.*]] to i32
3190 ; CHECK-NEXT: [[DEC:%.*]] = add i32 [[Y:%.*]], -1
3191 ; CHECK-NEXT: [[CMP:%.*]] = icmp ugt i32 [[DEC]], [[CONV]]
3192 ; CHECK-NEXT: ret i1 [[CMP]]
3194 %conv = fptosi float %x to i32
3195 %dec = sub nuw i32 %y, 1
3196 %cmp = icmp ult i32 %conv, %dec
3200 define i1 @eq_add_constants(i32 %x, i32 %y) {
3201 ; CHECK-LABEL: @eq_add_constants(
3202 ; CHECK-NEXT: [[C:%.*]] = icmp eq i32 [[X:%.*]], [[Y:%.*]]
3203 ; CHECK-NEXT: ret i1 [[C]]
3207 %C = icmp eq i32 %A, %B
3211 define i1 @eq_mul_constants(i32 %x, i32 %y) {
3212 ; CHECK-LABEL: @eq_mul_constants(
3213 ; CHECK-NEXT: [[C:%.*]] = icmp eq i32 [[X:%.*]], [[Y:%.*]]
3214 ; CHECK-NEXT: ret i1 [[C]]
3218 %C = icmp eq i32 %A, %B
3222 define <2 x i1> @eq_mul_constants_splat(<2 x i32> %x, <2 x i32> %y) {
3223 ; CHECK-LABEL: @eq_mul_constants_splat(
3224 ; CHECK-NEXT: [[C:%.*]] = icmp ne <2 x i32> [[X:%.*]], [[Y:%.*]]
3225 ; CHECK-NEXT: ret <2 x i1> [[C]]
3227 %A = mul <2 x i32> %x, <i32 5, i32 5>
3228 %B = mul <2 x i32> %y, <i32 5, i32 5>
3229 %C = icmp ne <2 x i32> %A, %B
3233 ; If the multiply constant has any trailing zero bits, we get something completely different.
3234 ; We mask off the high bits of each input and then convert:
3235 ; (X&Z) == (Y&Z) -> (X^Y) & Z == 0
3237 define i1 @eq_mul_constants_with_tz(i32 %x, i32 %y) {
3238 ; CHECK-LABEL: @eq_mul_constants_with_tz(
3239 ; CHECK-NEXT: [[TMP1:%.*]] = xor i32 [[X:%.*]], [[Y:%.*]]
3240 ; CHECK-NEXT: [[TMP2:%.*]] = and i32 [[TMP1]], 1073741823
3241 ; CHECK-NEXT: [[C:%.*]] = icmp ne i32 [[TMP2]], 0
3242 ; CHECK-NEXT: ret i1 [[C]]
3246 %C = icmp ne i32 %A, %B
3250 define <2 x i1> @eq_mul_constants_with_tz_splat(<2 x i32> %x, <2 x i32> %y) {
3251 ; CHECK-LABEL: @eq_mul_constants_with_tz_splat(
3252 ; CHECK-NEXT: [[TMP1:%.*]] = xor <2 x i32> [[X:%.*]], [[Y:%.*]]
3253 ; CHECK-NEXT: [[TMP2:%.*]] = and <2 x i32> [[TMP1]], <i32 1073741823, i32 1073741823>
3254 ; CHECK-NEXT: [[C:%.*]] = icmp eq <2 x i32> [[TMP2]], zeroinitializer
3255 ; CHECK-NEXT: ret <2 x i1> [[C]]
3257 %A = mul <2 x i32> %x, <i32 12, i32 12>
3258 %B = mul <2 x i32> %y, <i32 12, i32 12>
3259 %C = icmp eq <2 x i32> %A, %B
3263 declare i32 @llvm.bswap.i32(i32)
3265 define i1 @bswap_ne(i32 %x, i32 %y) {
3266 ; CHECK-LABEL: @bswap_ne(
3267 ; CHECK-NEXT: [[CMP:%.*]] = icmp ne i32 [[X:%.*]], [[Y:%.*]]
3268 ; CHECK-NEXT: ret i1 [[CMP]]
3270 %swapx = call i32 @llvm.bswap.i32(i32 %x)
3271 %swapy = call i32 @llvm.bswap.i32(i32 %y)
3272 %cmp = icmp ne i32 %swapx, %swapy
3276 declare <8 x i16> @llvm.bswap.v8i16(<8 x i16>)
3278 define <8 x i1> @bswap_vec_eq(<8 x i16> %x, <8 x i16> %y) {
3279 ; CHECK-LABEL: @bswap_vec_eq(
3280 ; CHECK-NEXT: [[CMP:%.*]] = icmp eq <8 x i16> [[X:%.*]], [[Y:%.*]]
3281 ; CHECK-NEXT: ret <8 x i1> [[CMP]]
3283 %swapx = call <8 x i16> @llvm.bswap.v8i16(<8 x i16> %x)
3284 %swapy = call <8 x i16> @llvm.bswap.v8i16(<8 x i16> %y)
3285 %cmp = icmp eq <8 x i16> %swapx, %swapy
3289 declare i64 @llvm.bitreverse.i64(i64)
3291 define i1 @bitreverse_eq(i64 %x, i64 %y) {
3292 ; CHECK-LABEL: @bitreverse_eq(
3293 ; CHECK-NEXT: [[CMP:%.*]] = icmp eq i64 [[X:%.*]], [[Y:%.*]]
3294 ; CHECK-NEXT: ret i1 [[CMP]]
3296 %revx = call i64 @llvm.bitreverse.i64(i64 %x)
3297 %revy = call i64 @llvm.bitreverse.i64(i64 %y)
3298 %cmp = icmp eq i64 %revx, %revy
3302 declare <8 x i16> @llvm.bitreverse.v8i16(<8 x i16>)
3304 define <8 x i1> @bitreverse_vec_ne(<8 x i16> %x, <8 x i16> %y) {
3305 ; CHECK-LABEL: @bitreverse_vec_ne(
3306 ; CHECK-NEXT: [[CMP:%.*]] = icmp ne <8 x i16> [[X:%.*]], [[Y:%.*]]
3307 ; CHECK-NEXT: ret <8 x i1> [[CMP]]
3309 %revx = call <8 x i16> @llvm.bitreverse.v8i16(<8 x i16> %x)
3310 %revy = call <8 x i16> @llvm.bitreverse.v8i16(<8 x i16> %y)
3311 %cmp = icmp ne <8 x i16> %revx, %revy
3315 ; These perform a comparison of a value known to be between 4 and 5 with a value between 5 and 7.
3316 ; They should all simplify to equality compares.
3317 define i1 @knownbits1(i8 %a, i8 %b) {
3318 ; CHECK-LABEL: @knownbits1(
3319 ; CHECK-NEXT: [[A1:%.*]] = and i8 [[A:%.*]], 1
3320 ; CHECK-NEXT: [[A2:%.*]] = or i8 [[A1]], 4
3321 ; CHECK-NEXT: [[B1:%.*]] = and i8 [[B:%.*]], 2
3322 ; CHECK-NEXT: [[B2:%.*]] = or i8 [[B1]], 5
3323 ; CHECK-NEXT: [[C:%.*]] = icmp eq i8 [[A2]], [[B2]]
3324 ; CHECK-NEXT: ret i1 [[C]]
3330 %c = icmp uge i8 %a2, %b2
3334 define i1 @knownbits2(i8 %a, i8 %b) {
3335 ; CHECK-LABEL: @knownbits2(
3336 ; CHECK-NEXT: [[A1:%.*]] = and i8 [[A:%.*]], 1
3337 ; CHECK-NEXT: [[A2:%.*]] = or i8 [[A1]], 4
3338 ; CHECK-NEXT: [[B1:%.*]] = and i8 [[B:%.*]], 2
3339 ; CHECK-NEXT: [[B2:%.*]] = or i8 [[B1]], 5
3340 ; CHECK-NEXT: [[C:%.*]] = icmp ne i8 [[A2]], [[B2]]
3341 ; CHECK-NEXT: ret i1 [[C]]
3347 %c = icmp ult i8 %a2, %b2
3351 define i1 @knownbits3(i8 %a, i8 %b) {
3352 ; CHECK-LABEL: @knownbits3(
3353 ; CHECK-NEXT: [[A1:%.*]] = and i8 [[A:%.*]], 1
3354 ; CHECK-NEXT: [[A2:%.*]] = or i8 [[A1]], 4
3355 ; CHECK-NEXT: [[B1:%.*]] = and i8 [[B:%.*]], 2
3356 ; CHECK-NEXT: [[B2:%.*]] = or i8 [[B1]], 5
3357 ; CHECK-NEXT: [[C:%.*]] = icmp eq i8 [[B2]], [[A2]]
3358 ; CHECK-NEXT: ret i1 [[C]]
3364 %c = icmp ule i8 %b2, %a2
3368 define <2 x i1> @knownbits4(<2 x i8> %a, <2 x i8> %b) {
3369 ; CHECK-LABEL: @knownbits4(
3370 ; CHECK-NEXT: [[A1:%.*]] = and <2 x i8> [[A:%.*]], <i8 1, i8 1>
3371 ; CHECK-NEXT: [[A2:%.*]] = or <2 x i8> [[A1]], <i8 4, i8 4>
3372 ; CHECK-NEXT: [[B1:%.*]] = and <2 x i8> [[B:%.*]], <i8 2, i8 2>
3373 ; CHECK-NEXT: [[B2:%.*]] = or <2 x i8> [[B1]], <i8 5, i8 5>
3374 ; CHECK-NEXT: [[C:%.*]] = icmp ne <2 x i8> [[B2]], [[A2]]
3375 ; CHECK-NEXT: ret <2 x i1> [[C]]
3377 %a1 = and <2 x i8> %a, <i8 5, i8 5>
3378 %a2 = or <2 x i8> %a1, <i8 4, i8 4>
3379 %b1 = and <2 x i8> %b, <i8 7, i8 7>
3380 %b2 = or <2 x i8> %b1, <i8 5, i8 5>
3381 %c = icmp ugt <2 x i8> %b2, %a2
3385 ; These are the signed versions of the above. One value is less than or equal to 5, but maybe negative.
3386 ; The other is known to be a value 5-7. These should simplify to equality comparisons.
3387 define i1 @knownbits5(i8 %a, i8 %b) {
3388 ; CHECK-LABEL: @knownbits5(
3389 ; CHECK-NEXT: [[A1:%.*]] = and i8 [[A:%.*]], -127
3390 ; CHECK-NEXT: [[A2:%.*]] = or i8 [[A1]], 4
3391 ; CHECK-NEXT: [[B1:%.*]] = and i8 [[B:%.*]], 2
3392 ; CHECK-NEXT: [[B2:%.*]] = or i8 [[B1]], 5
3393 ; CHECK-NEXT: [[C:%.*]] = icmp eq i8 [[A2]], [[B2]]
3394 ; CHECK-NEXT: ret i1 [[C]]
3396 %a1 = and i8 %a, 133
3400 %c = icmp sge i8 %a2, %b2
3404 define i1 @knownbits6(i8 %a, i8 %b) {
3405 ; CHECK-LABEL: @knownbits6(
3406 ; CHECK-NEXT: [[A1:%.*]] = and i8 [[A:%.*]], -127
3407 ; CHECK-NEXT: [[A2:%.*]] = or i8 [[A1]], 4
3408 ; CHECK-NEXT: [[B1:%.*]] = and i8 [[B:%.*]], 2
3409 ; CHECK-NEXT: [[B2:%.*]] = or i8 [[B1]], 5
3410 ; CHECK-NEXT: [[C:%.*]] = icmp ne i8 [[A2]], [[B2]]
3411 ; CHECK-NEXT: ret i1 [[C]]
3413 %a1 = and i8 %a, 133
3417 %c = icmp slt i8 %a2, %b2
3421 define <2 x i1> @knownbits7(<2 x i8> %a, <2 x i8> %b) {
3422 ; CHECK-LABEL: @knownbits7(
3423 ; CHECK-NEXT: [[A1:%.*]] = and <2 x i8> [[A:%.*]], <i8 -127, i8 -127>
3424 ; CHECK-NEXT: [[A2:%.*]] = or <2 x i8> [[A1]], <i8 4, i8 4>
3425 ; CHECK-NEXT: [[B1:%.*]] = and <2 x i8> [[B:%.*]], <i8 2, i8 2>
3426 ; CHECK-NEXT: [[B2:%.*]] = or <2 x i8> [[B1]], <i8 5, i8 5>
3427 ; CHECK-NEXT: [[C:%.*]] = icmp eq <2 x i8> [[B2]], [[A2]]
3428 ; CHECK-NEXT: ret <2 x i1> [[C]]
3430 %a1 = and <2 x i8> %a, <i8 133, i8 133>
3431 %a2 = or <2 x i8> %a1, <i8 4, i8 4>
3432 %b1 = and <2 x i8> %b, <i8 7, i8 7>
3433 %b2 = or <2 x i8> %b1, <i8 5, i8 5>
3434 %c = icmp sle <2 x i8> %b2, %a2
3438 define i1 @knownbits8(i8 %a, i8 %b) {
3439 ; CHECK-LABEL: @knownbits8(
3440 ; CHECK-NEXT: [[A1:%.*]] = and i8 [[A:%.*]], -127
3441 ; CHECK-NEXT: [[A2:%.*]] = or i8 [[A1]], 4
3442 ; CHECK-NEXT: [[B1:%.*]] = and i8 [[B:%.*]], 2
3443 ; CHECK-NEXT: [[B2:%.*]] = or i8 [[B1]], 5
3444 ; CHECK-NEXT: [[C:%.*]] = icmp ne i8 [[B2]], [[A2]]
3445 ; CHECK-NEXT: ret i1 [[C]]
3447 %a1 = and i8 %a, 133
3451 %c = icmp sgt i8 %b2, %a2
3455 ; Make sure InstCombine doesn't try too hard to simplify the icmp and break the abs idiom
3456 define i32 @abs_preserve(i32 %x) {
3457 ; CHECK-LABEL: @abs_preserve(
3458 ; CHECK-NEXT: [[A:%.*]] = shl nsw i32 [[X:%.*]], 1
3459 ; CHECK-NEXT: [[C:%.*]] = icmp slt i32 [[A]], 0
3460 ; CHECK-NEXT: [[NEGA:%.*]] = sub i32 0, [[A]]
3461 ; CHECK-NEXT: [[ABS:%.*]] = select i1 [[C]], i32 [[NEGA]], i32 [[A]]
3462 ; CHECK-NEXT: ret i32 [[ABS]]
3464 %a = mul nsw i32 %x, 2
3465 %c = icmp sge i32 %a, 0
3466 %nega = sub i32 0, %a
3467 %abs = select i1 %c, i32 %a, i32 %nega
3471 ; Don't crash by assuming the compared values are integers.
3473 declare void @llvm.assume(i1)
3474 define i1 @PR35794(i32* %a) {
3475 ; CHECK-LABEL: @PR35794(
3476 ; CHECK-NEXT: [[MASKCOND:%.*]] = icmp eq i32* [[A:%.*]], null
3477 ; CHECK-NEXT: tail call void @llvm.assume(i1 [[MASKCOND]])
3478 ; CHECK-NEXT: ret i1 true
3480 %cmp = icmp sgt i32* %a, inttoptr (i64 -1 to i32*)
3481 %maskcond = icmp eq i32* %a, null
3482 tail call void @llvm.assume(i1 %maskcond)
3486 ; Don't crash by assuming the compared values are integers.
3487 define <2 x i1> @PR36583(<2 x i8*>) {
3488 ; CHECK-LABEL: @PR36583(
3489 ; CHECK-NEXT: [[RES:%.*]] = icmp eq <2 x i8*> [[TMP0:%.*]], zeroinitializer
3490 ; CHECK-NEXT: ret <2 x i1> [[RES]]
3492 %cast = ptrtoint <2 x i8*> %0 to <2 x i64>
3493 %res = icmp eq <2 x i64> %cast, zeroinitializer
3497 ; fold (icmp pred (sub (0, X)) C1) for vec type
3498 define <2 x i32> @Op1Negated_Vec(<2 x i32> %x) {
3499 ; CHECK-LABEL: @Op1Negated_Vec(
3500 ; CHECK-NEXT: [[SUB:%.*]] = sub nsw <2 x i32> zeroinitializer, [[X:%.*]]
3501 ; CHECK-NEXT: [[CMP:%.*]] = icmp slt <2 x i32> [[X]], zeroinitializer
3502 ; CHECK-NEXT: [[COND:%.*]] = select <2 x i1> [[CMP]], <2 x i32> [[SUB]], <2 x i32> [[X]]
3503 ; CHECK-NEXT: ret <2 x i32> [[COND]]
3505 %sub = sub nsw <2 x i32> zeroinitializer, %x
3506 %cmp = icmp sgt <2 x i32> %sub, <i32 -1, i32 -1>
3507 %cond = select <2 x i1> %cmp, <2 x i32> %sub, <2 x i32> %x