1 ; NOTE: Assertions have been autogenerated by utils/update_test_checks.py
2 ; RUN: opt < %s -passes=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 declare i8 @llvm.abs.i8(i8, i1)
8 declare void @use_i1(i1)
9 declare void @use_i8(i8)
10 declare void @use_i32(i32)
11 declare void @use_i64(i64)
13 define i32 @test1(i32 %X) {
14 ; CHECK-LABEL: @test1(
15 ; CHECK-NEXT: [[X_LOBIT:%.*]] = lshr i32 [[X:%.*]], 31
16 ; CHECK-NEXT: ret i32 [[X_LOBIT]]
18 %a = icmp slt i32 %X, 0
19 %b = zext i1 %a to i32
23 define <2 x i32> @test1vec(<2 x i32> %X) {
24 ; CHECK-LABEL: @test1vec(
25 ; CHECK-NEXT: [[X_LOBIT:%.*]] = lshr <2 x i32> [[X:%.*]], splat (i32 31)
26 ; CHECK-NEXT: ret <2 x i32> [[X_LOBIT]]
28 %a = icmp slt <2 x i32> %X, zeroinitializer
29 %b = zext <2 x i1> %a to <2 x i32>
33 define i32 @test2(i32 %X) {
34 ; CHECK-LABEL: @test2(
35 ; CHECK-NEXT: [[A:%.*]] = icmp sgt i32 [[X:%.*]], -1
36 ; CHECK-NEXT: [[B:%.*]] = zext i1 [[A]] to i32
37 ; CHECK-NEXT: ret i32 [[B]]
39 %a = icmp ult i32 %X, -2147483648
40 %b = zext i1 %a to i32
44 define <2 x i32> @test2vec(<2 x i32> %X) {
45 ; CHECK-LABEL: @test2vec(
46 ; CHECK-NEXT: [[A:%.*]] = icmp sgt <2 x i32> [[X:%.*]], splat (i32 -1)
47 ; CHECK-NEXT: [[B:%.*]] = zext <2 x i1> [[A]] to <2 x i32>
48 ; CHECK-NEXT: ret <2 x i32> [[B]]
50 %a = icmp ult <2 x i32> %X, <i32 -2147483648, i32 -2147483648>
51 %b = zext <2 x i1> %a to <2 x i32>
55 define i32 @test3(i32 %X) {
56 ; CHECK-LABEL: @test3(
57 ; CHECK-NEXT: [[X_LOBIT:%.*]] = ashr i32 [[X:%.*]], 31
58 ; CHECK-NEXT: ret i32 [[X_LOBIT]]
60 %a = icmp slt i32 %X, 0
61 %b = sext i1 %a to i32
65 define i32 @test4(i32 %X) {
66 ; CHECK-LABEL: @test4(
67 ; CHECK-NEXT: [[A:%.*]] = icmp sgt i32 [[X:%.*]], -1
68 ; CHECK-NEXT: [[B:%.*]] = sext i1 [[A]] to i32
69 ; CHECK-NEXT: ret i32 [[B]]
71 %a = icmp ult i32 %X, -2147483648
72 %b = sext i1 %a to i32
77 define <2 x i1> @test5_eq(<2 x i64> %x) {
78 ; CHECK-LABEL: @test5_eq(
79 ; CHECK-NEXT: ret <2 x i1> undef
81 %V = icmp eq <2 x i64> %x, undef
84 define <2 x i1> @test5_ne(<2 x i64> %x) {
85 ; CHECK-LABEL: @test5_ne(
86 ; CHECK-NEXT: ret <2 x i1> undef
88 %V = icmp ne <2 x i64> %x, undef
91 define <2 x i1> @test5_ugt(<2 x i64> %x) {
92 ; CHECK-LABEL: @test5_ugt(
93 ; CHECK-NEXT: ret <2 x i1> zeroinitializer
95 %V = icmp ugt <2 x i64> %x, undef
98 define <2 x i1> @test5_zero() {
99 ; CHECK-LABEL: @test5_zero(
100 ; CHECK-NEXT: ret <2 x i1> undef
102 %V = icmp eq <2 x i64> zeroinitializer, undef
106 define i32 @test6(i32 %a, i32 %b) {
107 ; CHECK-LABEL: @test6(
108 ; CHECK-NEXT: [[ISNEG:%.*]] = icmp slt i32 [[A:%.*]], 0
109 ; CHECK-NEXT: [[F:%.*]] = select i1 [[ISNEG]], i32 [[B:%.*]], i32 0
110 ; CHECK-NEXT: ret i32 [[F]]
112 %c = icmp sle i32 %a, -1
113 %d = zext i1 %c to i32
120 define i1 @test7(i32 %x) {
121 ; CHECK-LABEL: @test7(
122 ; CHECK-NEXT: [[B:%.*]] = icmp ne i32 [[X:%.*]], 0
123 ; CHECK-NEXT: ret i1 [[B]]
126 %b = icmp ult i32 %a, %x
130 define <2 x i1> @test7_vec(<2 x i32> %x) {
131 ; CHECK-LABEL: @test7_vec(
132 ; CHECK-NEXT: [[B:%.*]] = icmp ne <2 x i32> [[X:%.*]], zeroinitializer
133 ; CHECK-NEXT: ret <2 x i1> [[B]]
135 %a = add <2 x i32> %x, <i32 -1, i32 -1>
136 %b = icmp ult <2 x i32> %a, %x
140 define i1 @test8(i32 %x) {
141 ; CHECK-LABEL: @test8(
142 ; CHECK-NEXT: ret i1 false
145 %b = icmp eq i32 %a, %x
149 define <2 x i1> @test8_vec(<2 x i32> %x) {
150 ; CHECK-LABEL: @test8_vec(
151 ; CHECK-NEXT: ret <2 x i1> zeroinitializer
153 %a = add <2 x i32> %x, <i32 -1, i32 -1>
154 %b = icmp eq <2 x i32> %a, %x
158 define i1 @test9(i32 %x) {
159 ; CHECK-LABEL: @test9(
160 ; CHECK-NEXT: [[B:%.*]] = icmp ugt i32 [[X:%.*]], 1
161 ; CHECK-NEXT: ret i1 [[B]]
164 %b = icmp ugt i32 %x, %a
168 define <2 x i1> @test9_vec(<2 x i32> %x) {
169 ; CHECK-LABEL: @test9_vec(
170 ; CHECK-NEXT: [[B:%.*]] = icmp ugt <2 x i32> [[X:%.*]], splat (i32 1)
171 ; CHECK-NEXT: ret <2 x i1> [[B]]
173 %a = add <2 x i32> %x, <i32 -2, i32 -2>
174 %b = icmp ugt <2 x i32> %x, %a
178 define i1 @test9b(i32 %x) {
179 ; CHECK-LABEL: @test9b(
180 ; CHECK-NEXT: [[B:%.*]] = icmp ult i32 [[X:%.*]], 2
181 ; CHECK-NEXT: ret i1 [[B]]
184 %b = icmp ugt i32 %a, %x
188 define <2 x i1> @test9b_vec(<2 x i32> %x) {
189 ; CHECK-LABEL: @test9b_vec(
190 ; CHECK-NEXT: [[B:%.*]] = icmp ult <2 x i32> [[X:%.*]], splat (i32 2)
191 ; CHECK-NEXT: ret <2 x i1> [[B]]
193 %a = add <2 x i32> %x, <i32 -2, i32 -2>
194 %b = icmp ugt <2 x i32> %a, %x
198 define i1 @test10(i32 %x) {
199 ; CHECK-LABEL: @test10(
200 ; CHECK-NEXT: [[B:%.*]] = icmp ne i32 [[X:%.*]], -2147483648
201 ; CHECK-NEXT: ret i1 [[B]]
204 %b = icmp slt i32 %a, %x
208 define <2 x i1> @test10_vec(<2 x i32> %x) {
209 ; CHECK-LABEL: @test10_vec(
210 ; CHECK-NEXT: [[B:%.*]] = icmp ne <2 x i32> [[X:%.*]], splat (i32 -2147483648)
211 ; CHECK-NEXT: ret <2 x i1> [[B]]
213 %a = add <2 x i32> %x, <i32 -1, i32 -1>
214 %b = icmp slt <2 x i32> %a, %x
218 define i1 @test10b(i32 %x) {
219 ; CHECK-LABEL: @test10b(
220 ; CHECK-NEXT: [[B:%.*]] = icmp eq i32 [[X:%.*]], -2147483648
221 ; CHECK-NEXT: ret i1 [[B]]
224 %b = icmp sgt i32 %a, %x
228 define <2 x i1> @test10b_vec(<2 x i32> %x) {
229 ; CHECK-LABEL: @test10b_vec(
230 ; CHECK-NEXT: [[B:%.*]] = icmp eq <2 x i32> [[X:%.*]], splat (i32 -2147483648)
231 ; CHECK-NEXT: ret <2 x i1> [[B]]
233 %a = add <2 x i32> %x, <i32 -1, i32 -1>
234 %b = icmp sgt <2 x i32> %a, %x
238 define i1 @test11(i32 %x) {
239 ; CHECK-LABEL: @test11(
240 ; CHECK-NEXT: ret i1 true
242 %a = add nsw i32 %x, 8
243 %b = icmp slt i32 %x, %a
247 define <2 x i1> @test11_vec(<2 x i32> %x) {
248 ; CHECK-LABEL: @test11_vec(
249 ; CHECK-NEXT: ret <2 x i1> splat (i1 true)
251 %a = add nsw <2 x i32> %x, <i32 8, i32 8>
252 %b = icmp slt <2 x i32> %x, %a
257 define i1 @test12(i1 %A) {
258 ; CHECK-LABEL: @test12(
259 ; CHECK-NEXT: [[NOT_A:%.*]] = xor i1 [[A:%.*]], true
260 ; CHECK-NEXT: ret i1 [[NOT_A]]
262 %S = select i1 %A, i64 -4294967295, i64 8589934591
263 %B = icmp ne i64 bitcast (<2 x i32> <i32 1, i32 -1> to i64), %S
268 define i1 @test13(i8 %X) {
269 ; CHECK-LABEL: @test13(
270 ; CHECK-NEXT: ret i1 false
272 %cmp = icmp slt i8 undef, %X
276 define i1 @test14(i8 %X) {
277 ; CHECK-LABEL: @test14(
278 ; CHECK-NEXT: ret i1 false
280 %cmp = icmp slt i8 undef, -128
284 define i1 @test15() {
285 ; CHECK-LABEL: @test15(
286 ; CHECK-NEXT: ret i1 undef
288 %cmp = icmp eq i8 undef, -128
292 define i1 @test16() {
293 ; CHECK-LABEL: @test16(
294 ; CHECK-NEXT: ret i1 undef
296 %cmp = icmp ne i8 undef, -128
300 define i1 @test17(i32 %x) {
301 ; CHECK-LABEL: @test17(
302 ; CHECK-NEXT: [[TMP1:%.*]] = icmp ne i32 [[X:%.*]], 3
303 ; CHECK-NEXT: ret i1 [[TMP1]]
306 %and = and i32 %shl, 8
307 %cmp = icmp eq i32 %and, 0
311 define <2 x i1> @test17vec(<2 x i32> %x) {
312 ; CHECK-LABEL: @test17vec(
313 ; CHECK-NEXT: [[TMP1:%.*]] = icmp ne <2 x i32> [[X:%.*]], splat (i32 3)
314 ; CHECK-NEXT: ret <2 x i1> [[TMP1]]
316 %shl = shl <2 x i32> <i32 1, i32 1>, %x
317 %and = and <2 x i32> %shl, <i32 8, i32 8>
318 %cmp = icmp eq <2 x i32> %and, zeroinitializer
322 define i1 @test17a(i32 %x) {
323 ; CHECK-LABEL: @test17a(
324 ; CHECK-NEXT: [[CMP:%.*]] = icmp ugt i32 [[X:%.*]], 2
325 ; CHECK-NEXT: ret i1 [[CMP]]
328 %and = and i32 %shl, 7
329 %cmp = icmp eq i32 %and, 0
333 define <2 x i1> @test17a_vec(<2 x i32> %x) {
334 ; CHECK-LABEL: @test17a_vec(
335 ; CHECK-NEXT: [[CMP:%.*]] = icmp ugt <2 x i32> [[X:%.*]], splat (i32 2)
336 ; CHECK-NEXT: ret <2 x i1> [[CMP]]
338 %shl = shl <2 x i32> <i32 1, i32 1>, %x
339 %and = and <2 x i32> %shl, <i32 7, i32 7>
340 %cmp = icmp eq <2 x i32> %and, zeroinitializer
344 define i1 @test18_eq(i32 %x) {
345 ; CHECK-LABEL: @test18_eq(
346 ; CHECK-NEXT: [[TMP1:%.*]] = icmp ne i32 [[X:%.*]], 3
347 ; CHECK-NEXT: ret i1 [[TMP1]]
350 %and = and i32 %sh, 1
351 %cmp = icmp eq i32 %and, 0
355 define <2 x i1> @test18_eq_vec(<2 x i32> %x) {
356 ; CHECK-LABEL: @test18_eq_vec(
357 ; CHECK-NEXT: [[TMP1:%.*]] = icmp ne <2 x i32> [[X:%.*]], splat (i32 3)
358 ; CHECK-NEXT: ret <2 x i1> [[TMP1]]
360 %sh = lshr <2 x i32> <i32 8, i32 8>, %x
361 %and = and <2 x i32> %sh, <i32 1, i32 1>
362 %cmp = icmp eq <2 x i32> %and, zeroinitializer
366 define i1 @test18_ne(i32 %x) {
367 ; CHECK-LABEL: @test18_ne(
368 ; CHECK-NEXT: [[TMP1:%.*]] = icmp eq i32 [[X:%.*]], 3
369 ; CHECK-NEXT: ret i1 [[TMP1]]
372 %and = and i32 %sh, 1
373 %cmp = icmp ne i32 %and, 0
377 define <2 x i1> @test18_ne_vec(<2 x i32> %x) {
378 ; CHECK-LABEL: @test18_ne_vec(
379 ; CHECK-NEXT: [[TMP1:%.*]] = icmp eq <2 x i32> [[X:%.*]], splat (i32 3)
380 ; CHECK-NEXT: ret <2 x i1> [[TMP1]]
382 %sh = lshr <2 x i32> <i32 8, i32 8>, %x
383 %and = and <2 x i32> %sh, <i32 1, i32 1>
384 %cmp = icmp ne <2 x i32> %and, zeroinitializer
388 define i1 @test19(i32 %x) {
389 ; CHECK-LABEL: @test19(
390 ; CHECK-NEXT: [[TMP1:%.*]] = icmp eq i32 [[X:%.*]], 3
391 ; CHECK-NEXT: ret i1 [[TMP1]]
394 %and = and i32 %shl, 8
395 %cmp = icmp eq i32 %and, 8
399 define <2 x i1> @test19vec(<2 x i32> %x) {
400 ; CHECK-LABEL: @test19vec(
401 ; CHECK-NEXT: [[TMP1:%.*]] = icmp eq <2 x i32> [[X:%.*]], splat (i32 3)
402 ; CHECK-NEXT: ret <2 x i1> [[TMP1]]
404 %shl = shl <2 x i32> <i32 1, i32 1>, %x
405 %and = and <2 x i32> %shl, <i32 8, i32 8>
406 %cmp = icmp eq <2 x i32> %and, <i32 8, i32 8>
410 define <2 x i1> @cmp_and_signbit_vec(<2 x i3> %x) {
411 ; CHECK-LABEL: @cmp_and_signbit_vec(
412 ; CHECK-NEXT: [[CMP:%.*]] = icmp slt <2 x i3> [[X:%.*]], zeroinitializer
413 ; CHECK-NEXT: ret <2 x i1> [[CMP]]
415 %and = and <2 x i3> %x, <i3 4, i3 4>
416 %cmp = icmp ne <2 x i3> %and, zeroinitializer
420 define i1 @test20(i32 %x) {
421 ; CHECK-LABEL: @test20(
422 ; CHECK-NEXT: [[TMP1:%.*]] = icmp eq i32 [[X:%.*]], 3
423 ; CHECK-NEXT: ret i1 [[TMP1]]
426 %and = and i32 %shl, 8
427 %cmp = icmp ne i32 %and, 0
431 define <2 x i1> @test20vec(<2 x i32> %x) {
432 ; CHECK-LABEL: @test20vec(
433 ; CHECK-NEXT: [[TMP1:%.*]] = icmp eq <2 x i32> [[X:%.*]], splat (i32 3)
434 ; CHECK-NEXT: ret <2 x i1> [[TMP1]]
436 %shl = shl <2 x i32> <i32 1, i32 1>, %x
437 %and = and <2 x i32> %shl, <i32 8, i32 8>
438 %cmp = icmp ne <2 x i32> %and, zeroinitializer
442 define i1 @test20a(i32 %x) {
443 ; CHECK-LABEL: @test20a(
444 ; CHECK-NEXT: [[CMP:%.*]] = icmp ult i32 [[X:%.*]], 3
445 ; CHECK-NEXT: ret i1 [[CMP]]
448 %and = and i32 %shl, 7
449 %cmp = icmp ne i32 %and, 0
453 define <2 x i1> @test20a_vec(<2 x i32> %x) {
454 ; CHECK-LABEL: @test20a_vec(
455 ; CHECK-NEXT: [[CMP:%.*]] = icmp ult <2 x i32> [[X:%.*]], splat (i32 3)
456 ; CHECK-NEXT: ret <2 x i1> [[CMP]]
458 %shl = shl <2 x i32> <i32 1, i32 1>, %x
459 %and = and <2 x i32> %shl, <i32 7, i32 7>
460 %cmp = icmp ne <2 x i32> %and, zeroinitializer
464 define i1 @test21(i8 %x, i8 %y) {
465 ; CHECK-LABEL: @test21(
466 ; CHECK-NEXT: [[B:%.*]] = icmp ugt i8 [[X:%.*]], 3
467 ; CHECK-NEXT: ret i1 [[B]]
470 %B = icmp ugt i8 %A, 3
474 define i1 @test22(i8 %x, i8 %y) {
475 ; CHECK-LABEL: @test22(
476 ; CHECK-NEXT: [[B:%.*]] = icmp ult i8 [[X:%.*]], 4
477 ; CHECK-NEXT: ret i1 [[B]]
480 %B = icmp ult i8 %A, 4
485 define i1 @test23(i32 %x) {
486 ; CHECK-LABEL: @test23(
487 ; CHECK-NEXT: [[I4:%.*]] = icmp sgt i32 [[X:%.*]], 1328634634
488 ; CHECK-NEXT: ret i1 [[I4]]
490 %i3 = sdiv i32 %x, -1328634635
491 %i4 = icmp eq i32 %i3, -1
495 define <2 x i1> @test23vec(<2 x i32> %x) {
496 ; CHECK-LABEL: @test23vec(
497 ; CHECK-NEXT: [[I4:%.*]] = icmp sgt <2 x i32> [[X:%.*]], splat (i32 1328634634)
498 ; CHECK-NEXT: ret <2 x i1> [[I4]]
500 %i3 = sdiv <2 x i32> %x, <i32 -1328634635, i32 -1328634635>
501 %i4 = icmp eq <2 x i32> %i3, <i32 -1, i32 -1>
505 ; Note: offs can be negative, LLVM used to make an incorrect assumption that
506 ; unsigned overflow does not happen during offset computation
507 define i1 @test24_neg_offs(ptr %p, i64 %offs) {
508 ; CHECK-LABEL: @test24_neg_offs(
509 ; CHECK-NEXT: [[P1_IDX_NEG:%.*]] = mul i64 [[OFFS:%.*]], -4
510 ; CHECK-NEXT: [[CMP:%.*]] = icmp eq i64 [[P1_IDX_NEG]], 8
511 ; CHECK-NEXT: ret i1 [[CMP]]
513 %p1 = getelementptr inbounds i32, ptr %p, i64 %offs
514 %conv1 = ptrtoint ptr %p to i64
515 %conv2 = ptrtoint ptr %p1 to i64
516 %delta = sub i64 %conv1, %conv2
517 %cmp = icmp eq i64 %delta, 8
521 ; X - Z > Y - Z -> X > Y if there is no overflow.
522 define i1 @test27(i32 %x, i32 %y, i32 %z) {
523 ; CHECK-LABEL: @test27(
524 ; CHECK-NEXT: [[C:%.*]] = icmp sgt i32 [[X:%.*]], [[Y:%.*]]
525 ; CHECK-NEXT: ret i1 [[C]]
527 %lhs = sub nsw i32 %x, %z
528 %rhs = sub nsw i32 %y, %z
529 %c = icmp sgt i32 %lhs, %rhs
533 define i1 @test27_extra_uses(i32 %x, i32 %y, i32 %z) {
534 ; CHECK-LABEL: @test27_extra_uses(
535 ; CHECK-NEXT: [[LHS:%.*]] = sub nsw i32 [[X:%.*]], [[Z:%.*]]
536 ; CHECK-NEXT: call void @use_i32(i32 [[LHS]])
537 ; CHECK-NEXT: [[RHS:%.*]] = sub nsw i32 [[Y:%.*]], [[Z]]
538 ; CHECK-NEXT: call void @use_i32(i32 [[RHS]])
539 ; CHECK-NEXT: [[C:%.*]] = icmp sgt i32 [[X]], [[Y]]
540 ; CHECK-NEXT: ret i1 [[C]]
542 %lhs = sub nsw i32 %x, %z
543 call void @use_i32(i32 %lhs)
544 %rhs = sub nsw i32 %y, %z
545 call void @use_i32(i32 %rhs)
546 %c = icmp sgt i32 %lhs, %rhs
550 ; X - Z > Y - Z -> X > Y if there is no overflow.
551 define i1 @test28(i32 %x, i32 %y, i32 %z) {
552 ; CHECK-LABEL: @test28(
553 ; CHECK-NEXT: [[C:%.*]] = icmp ugt i32 [[X:%.*]], [[Y:%.*]]
554 ; CHECK-NEXT: ret i1 [[C]]
556 %lhs = sub nuw i32 %x, %z
557 %rhs = sub nuw i32 %y, %z
558 %c = icmp ugt i32 %lhs, %rhs
562 define i1 @test28_extra_uses(i32 %x, i32 %y, i32 %z) {
563 ; CHECK-LABEL: @test28_extra_uses(
564 ; CHECK-NEXT: [[LHS:%.*]] = sub nuw i32 [[X:%.*]], [[Z:%.*]]
565 ; CHECK-NEXT: call void @use_i32(i32 [[LHS]])
566 ; CHECK-NEXT: [[RHS:%.*]] = sub nuw i32 [[Y:%.*]], [[Z]]
567 ; CHECK-NEXT: call void @use_i32(i32 [[RHS]])
568 ; CHECK-NEXT: [[C:%.*]] = icmp ugt i32 [[X]], [[Y]]
569 ; CHECK-NEXT: ret i1 [[C]]
571 %lhs = sub nuw i32 %x, %z
572 call void @use_i32(i32 %lhs)
573 %rhs = sub nuw i32 %y, %z
574 call void @use_i32(i32 %rhs)
575 %c = icmp ugt i32 %lhs, %rhs
579 ; PR36969 - https://bugs.llvm.org/show_bug.cgi?id=36969
581 define i1 @ugt_sub(i32 %xsrc, i32 %y) {
582 ; CHECK-LABEL: @ugt_sub(
583 ; CHECK-NEXT: [[X:%.*]] = udiv i32 [[XSRC:%.*]], 42
584 ; CHECK-NEXT: [[CMP:%.*]] = icmp ugt i32 [[Y:%.*]], [[X]]
585 ; CHECK-NEXT: ret i1 [[CMP]]
587 %x = udiv i32 %xsrc, 42 ; thwart complexity-based canonicalization
588 %sub = sub i32 %x, %y
589 %cmp = icmp ugt i32 %sub, %x
593 ; Swap operands and predicate. Try a vector type to verify that works too.
595 define <2 x i1> @ult_sub(<2 x i8> %xsrc, <2 x i8> %y) {
596 ; CHECK-LABEL: @ult_sub(
597 ; CHECK-NEXT: [[X:%.*]] = udiv <2 x i8> [[XSRC:%.*]], <i8 42, i8 -42>
598 ; CHECK-NEXT: [[CMP:%.*]] = icmp ult <2 x i8> [[X]], [[Y:%.*]]
599 ; CHECK-NEXT: ret <2 x i1> [[CMP]]
601 %x = udiv <2 x i8> %xsrc, <i8 42, i8 -42> ; thwart complexity-based canonicalization
602 %sub = sub <2 x i8> %x, %y
603 %cmp = icmp ult <2 x i8> %x, %sub
607 ; X - Y > X -> 0 > Y if there is no overflow.
608 define i1 @test33(i32 %x, i32 %y) {
609 ; CHECK-LABEL: @test33(
610 ; CHECK-NEXT: [[C:%.*]] = icmp slt i32 [[Y:%.*]], 0
611 ; CHECK-NEXT: ret i1 [[C]]
613 %lhs = sub nsw i32 %x, %y
614 %c = icmp sgt i32 %lhs, %x
618 ; X - Y > X -> 0 > Y if there is no overflow.
619 define i1 @test34(i32 %x, i32 %y) {
620 ; CHECK-LABEL: @test34(
621 ; CHECK-NEXT: ret i1 false
623 %lhs = sub nuw i32 %x, %y
624 %c = icmp ugt i32 %lhs, %x
628 ; X > X - Y -> Y > 0 if there is no overflow.
629 define i1 @test35(i32 %x, i32 %y) {
630 ; CHECK-LABEL: @test35(
631 ; CHECK-NEXT: [[C:%.*]] = icmp sgt i32 [[Y:%.*]], 0
632 ; CHECK-NEXT: ret i1 [[C]]
634 %rhs = sub nsw i32 %x, %y
635 %c = icmp sgt i32 %x, %rhs
639 ; X > X - Y -> Y > 0 if there is no overflow.
640 define i1 @test36(i32 %x, i32 %y) {
641 ; CHECK-LABEL: @test36(
642 ; CHECK-NEXT: [[C:%.*]] = icmp ne i32 [[Y:%.*]], 0
643 ; CHECK-NEXT: ret i1 [[C]]
645 %rhs = sub nuw i32 %x, %y
646 %c = icmp ugt i32 %x, %rhs
650 ; X - Y > X - Z -> Z > Y if there is no overflow.
651 define i1 @test37(i32 %x, i32 %y, i32 %z) {
652 ; CHECK-LABEL: @test37(
653 ; CHECK-NEXT: [[C:%.*]] = icmp sgt i32 [[Z:%.*]], [[Y:%.*]]
654 ; CHECK-NEXT: ret i1 [[C]]
656 %lhs = sub nsw i32 %x, %y
657 %rhs = sub nsw i32 %x, %z
658 %c = icmp sgt i32 %lhs, %rhs
662 define i1 @test37_extra_uses(i32 %x, i32 %y, i32 %z) {
663 ; CHECK-LABEL: @test37_extra_uses(
664 ; CHECK-NEXT: [[LHS:%.*]] = sub nsw i32 [[X:%.*]], [[Y:%.*]]
665 ; CHECK-NEXT: call void @use_i32(i32 [[LHS]])
666 ; CHECK-NEXT: [[RHS:%.*]] = sub nsw i32 [[X]], [[Z:%.*]]
667 ; CHECK-NEXT: call void @use_i32(i32 [[RHS]])
668 ; CHECK-NEXT: [[C:%.*]] = icmp sgt i32 [[Z]], [[Y]]
669 ; CHECK-NEXT: ret i1 [[C]]
671 %lhs = sub nsw i32 %x, %y
672 call void @use_i32(i32 %lhs)
673 %rhs = sub nsw i32 %x, %z
674 call void @use_i32(i32 %rhs)
675 %c = icmp sgt i32 %lhs, %rhs
679 ; TODO: Min/max pattern should not prevent the fold.
681 define i32 @neg_max_s32(i32 %x, i32 %y) {
682 ; CHECK-LABEL: @neg_max_s32(
683 ; CHECK-NEXT: [[TMP1:%.*]] = call i32 @llvm.smin.i32(i32 [[X:%.*]], i32 [[Y:%.*]])
684 ; CHECK-NEXT: ret i32 [[TMP1]]
686 %nx = sub nsw i32 0, %x
687 %ny = sub nsw i32 0, %y
688 %c = icmp slt i32 %nx, %ny
689 %s = select i1 %c, i32 %ny, i32 %nx
690 %r = sub nsw i32 0, %s
694 define <4 x i32> @neg_max_v4s32(<4 x i32> %x, <4 x i32> %y) {
695 ; CHECK-LABEL: @neg_max_v4s32(
696 ; CHECK-NEXT: [[TMP1:%.*]] = call <4 x i32> @llvm.smin.v4i32(<4 x i32> [[X:%.*]], <4 x i32> [[Y:%.*]])
697 ; CHECK-NEXT: ret <4 x i32> [[TMP1]]
699 %nx = sub nsw <4 x i32> zeroinitializer, %x
700 %ny = sub nsw <4 x i32> zeroinitializer, %y
701 %c = icmp sgt <4 x i32> %nx, %ny
702 %s = select <4 x i1> %c, <4 x i32> %nx, <4 x i32> %ny
703 %r = sub <4 x i32> zeroinitializer, %s
707 ; X - Y > X - Z -> Z > Y if there is no overflow.
708 define i1 @test38(i32 %x, i32 %y, i32 %z) {
709 ; CHECK-LABEL: @test38(
710 ; CHECK-NEXT: [[C:%.*]] = icmp ugt i32 [[Z:%.*]], [[Y:%.*]]
711 ; CHECK-NEXT: ret i1 [[C]]
713 %lhs = sub nuw i32 %x, %y
714 %rhs = sub nuw i32 %x, %z
715 %c = icmp ugt i32 %lhs, %rhs
719 define i1 @test38_extra_uses(i32 %x, i32 %y, i32 %z) {
720 ; CHECK-LABEL: @test38_extra_uses(
721 ; CHECK-NEXT: [[LHS:%.*]] = sub nuw i32 [[X:%.*]], [[Y:%.*]]
722 ; CHECK-NEXT: call void @use_i32(i32 [[LHS]])
723 ; CHECK-NEXT: [[RHS:%.*]] = sub nuw i32 [[X]], [[Z:%.*]]
724 ; CHECK-NEXT: call void @use_i32(i32 [[RHS]])
725 ; CHECK-NEXT: [[C:%.*]] = icmp ugt i32 [[Z]], [[Y]]
726 ; CHECK-NEXT: ret i1 [[C]]
728 %lhs = sub nuw i32 %x, %y
729 call void @use_i32(i32 %lhs)
730 %rhs = sub nuw i32 %x, %z
731 call void @use_i32(i32 %rhs)
732 %c = icmp ugt i32 %lhs, %rhs
736 define i1 @shr_exact(i132 %x) {
737 ; CHECK-LABEL: @shr_exact(
738 ; CHECK-NEXT: [[CMP:%.*]] = icmp eq i132 [[X:%.*]], 32
739 ; CHECK-NEXT: ret i1 [[CMP]]
741 %sh = ashr exact i132 %x, 4
742 %cmp = icmp eq i132 %sh, 2
746 define <2 x i1> @shr_exact_vec(<2 x i132> %x) {
747 ; CHECK-LABEL: @shr_exact_vec(
748 ; CHECK-NEXT: [[CMP:%.*]] = icmp ne <2 x i132> [[X:%.*]], splat (i132 32)
749 ; CHECK-NEXT: ret <2 x i1> [[CMP]]
751 %sh = lshr exact <2 x i132> %x, <i132 4, i132 4>
752 %cmp = icmp ne <2 x i132> %sh, <i132 2, i132 2>
757 define i1 @test41(i32 %X, i32 %Y) {
758 ; CHECK-LABEL: @test41(
759 ; CHECK-NEXT: ret i1 true
762 %B = icmp ugt i32 %Y, %A
766 define i1 @test42(i32 %X, i32 %Y) {
767 ; CHECK-LABEL: @test42(
768 ; CHECK-NEXT: [[B:%.*]] = icmp sgt i32 [[Y:%.*]], -1
769 ; CHECK-NEXT: ret i1 [[B]]
772 %B = icmp slt i32 %A, %Y
776 define i1 @test43(i32 %X, i32 %Y) {
777 ; CHECK-LABEL: @test43(
778 ; CHECK-NEXT: [[B:%.*]] = icmp slt i32 [[Y:%.*]], 0
779 ; CHECK-NEXT: ret i1 [[B]]
782 %B = icmp slt i32 %Y, %A
786 define i1 @test44(i32 %X, i32 %Y) {
787 ; CHECK-LABEL: @test44(
788 ; CHECK-NEXT: [[B:%.*]] = icmp sgt i32 [[Y:%.*]], -1
789 ; CHECK-NEXT: ret i1 [[B]]
792 %B = icmp slt i32 %A, %Y
796 define i1 @test45(i32 %X, i32 %Y) {
797 ; CHECK-LABEL: @test45(
798 ; CHECK-NEXT: [[B:%.*]] = icmp slt i32 [[Y:%.*]], 0
799 ; CHECK-NEXT: ret i1 [[B]]
802 %B = icmp slt i32 %Y, %A
807 define i1 @test46(i32 %X, i32 %Y, i32 %Z) {
808 ; CHECK-LABEL: @test46(
809 ; CHECK-NEXT: [[C:%.*]] = icmp ult i32 [[X:%.*]], [[Y:%.*]]
810 ; CHECK-NEXT: ret i1 [[C]]
812 %A = ashr exact i32 %X, %Z
813 %B = ashr exact i32 %Y, %Z
814 %C = icmp ult i32 %A, %B
818 define i1 @test46_multiuse1(i32 %X, i32 %Y, i32 %Z) {
819 ; CHECK-LABEL: @test46_multiuse1(
820 ; CHECK-NEXT: [[A:%.*]] = ashr exact i32 [[X:%.*]], [[Z:%.*]]
821 ; CHECK-NEXT: call void @use_i32(i32 [[A]])
822 ; CHECK-NEXT: [[C:%.*]] = icmp ult i32 [[X]], [[Y:%.*]]
823 ; CHECK-NEXT: ret i1 [[C]]
825 %A = ashr exact i32 %X, %Z
826 call void @use_i32(i32 %A)
827 %B = ashr exact i32 %Y, %Z
828 %C = icmp ult i32 %A, %B
832 define i1 @test46_multiuse2(i32 %X, i32 %Y, i32 %Z) {
833 ; CHECK-LABEL: @test46_multiuse2(
834 ; CHECK-NEXT: [[B:%.*]] = ashr exact i32 [[Y:%.*]], [[Z:%.*]]
835 ; CHECK-NEXT: call void @use_i32(i32 [[B]])
836 ; CHECK-NEXT: [[C:%.*]] = icmp ult i32 [[X:%.*]], [[Y]]
837 ; CHECK-NEXT: ret i1 [[C]]
839 %A = ashr exact i32 %X, %Z
840 %B = ashr exact i32 %Y, %Z
841 call void @use_i32(i32 %B)
842 %C = icmp ult i32 %A, %B
846 define i1 @test46_multiuse3(i32 %X, i32 %Y, i32 %Z) {
847 ; CHECK-LABEL: @test46_multiuse3(
848 ; CHECK-NEXT: [[A:%.*]] = ashr exact i32 [[X:%.*]], [[Z:%.*]]
849 ; CHECK-NEXT: call void @use_i32(i32 [[A]])
850 ; CHECK-NEXT: [[B:%.*]] = ashr exact i32 [[Y:%.*]], [[Z]]
851 ; CHECK-NEXT: call void @use_i32(i32 [[B]])
852 ; CHECK-NEXT: [[C:%.*]] = icmp ult i32 [[A]], [[B]]
853 ; CHECK-NEXT: ret i1 [[C]]
855 %A = ashr exact i32 %X, %Z
856 call void @use_i32(i32 %A)
857 %B = ashr exact i32 %Y, %Z
858 call void @use_i32(i32 %B)
859 %C = icmp ult i32 %A, %B
864 define i1 @test47(i32 %X, i32 %Y, i32 %Z) {
865 ; CHECK-LABEL: @test47(
866 ; CHECK-NEXT: [[C:%.*]] = icmp ugt i32 [[X:%.*]], [[Y:%.*]]
867 ; CHECK-NEXT: ret i1 [[C]]
869 %A = ashr exact i32 %X, %Z
870 %B = ashr exact i32 %Y, %Z
871 %C = icmp ugt i32 %A, %B
876 define i1 @test48(i32 %X, i32 %Y, i32 %Z) {
877 ; CHECK-LABEL: @test48(
878 ; CHECK-NEXT: [[C:%.*]] = icmp eq i32 [[X:%.*]], [[Y:%.*]]
879 ; CHECK-NEXT: ret i1 [[C]]
881 %A = sdiv exact i32 %X, %Z
882 %B = sdiv exact i32 %Y, %Z
883 %C = icmp eq i32 %A, %B
887 ; The above transform only works for equality predicates.
889 define i1 @PR32949(i32 %X, i32 %Y, i32 %Z) {
890 ; CHECK-LABEL: @PR32949(
891 ; CHECK-NEXT: [[A:%.*]] = sdiv exact i32 [[X:%.*]], [[Z:%.*]]
892 ; CHECK-NEXT: [[B:%.*]] = sdiv exact i32 [[Y:%.*]], [[Z]]
893 ; CHECK-NEXT: [[C:%.*]] = icmp sgt i32 [[A]], [[B]]
894 ; CHECK-NEXT: ret i1 [[C]]
896 %A = sdiv exact i32 %X, %Z
897 %B = sdiv exact i32 %Y, %Z
898 %C = icmp sgt i32 %A, %B
902 define i1 @test_sdiv_pos_slt(i32 %x, i32 %y) {
903 ; CHECK-LABEL: @test_sdiv_pos_slt(
904 ; CHECK-NEXT: [[CMP:%.*]] = icmp slt i32 [[X:%.*]], [[Y:%.*]]
905 ; CHECK-NEXT: ret i1 [[CMP]]
907 %divx = sdiv exact i32 %x, 40
908 %divy = sdiv exact i32 %y, 40
909 %cmp = icmp slt i32 %divx, %divy
913 define i1 @test_sdiv_pos_sle(i32 %x, i32 %y) {
914 ; CHECK-LABEL: @test_sdiv_pos_sle(
915 ; CHECK-NEXT: [[CMP:%.*]] = icmp sle i32 [[X:%.*]], [[Y:%.*]]
916 ; CHECK-NEXT: ret i1 [[CMP]]
918 %divx = sdiv exact i32 %x, 40
919 %divy = sdiv exact i32 %y, 40
920 %cmp = icmp sle i32 %divx, %divy
924 define i1 @test_sdiv_pos_sgt(i32 %x, i32 %y) {
925 ; CHECK-LABEL: @test_sdiv_pos_sgt(
926 ; CHECK-NEXT: [[CMP:%.*]] = icmp sgt i32 [[X:%.*]], [[Y:%.*]]
927 ; CHECK-NEXT: ret i1 [[CMP]]
929 %divx = sdiv exact i32 %x, 40
930 %divy = sdiv exact i32 %y, 40
931 %cmp = icmp sgt i32 %divx, %divy
935 define i1 @test_sdiv_pos_sge(i32 %x, i32 %y) {
936 ; CHECK-LABEL: @test_sdiv_pos_sge(
937 ; CHECK-NEXT: [[CMP:%.*]] = icmp sge i32 [[X:%.*]], [[Y:%.*]]
938 ; CHECK-NEXT: ret i1 [[CMP]]
940 %divx = sdiv exact i32 %x, 40
941 %divy = sdiv exact i32 %y, 40
942 %cmp = icmp sge i32 %divx, %divy
946 define i1 @test_sdiv_pos_ult(i32 %x, i32 %y) {
947 ; CHECK-LABEL: @test_sdiv_pos_ult(
948 ; CHECK-NEXT: [[CMP:%.*]] = icmp ult i32 [[X:%.*]], [[Y:%.*]]
949 ; CHECK-NEXT: ret i1 [[CMP]]
951 %divx = sdiv exact i32 %x, 40
952 %divy = sdiv exact i32 %y, 40
953 %cmp = icmp ult i32 %divx, %divy
957 define i1 @test_sdiv_pos_ule(i32 %x, i32 %y) {
958 ; CHECK-LABEL: @test_sdiv_pos_ule(
959 ; CHECK-NEXT: [[CMP:%.*]] = icmp ule i32 [[X:%.*]], [[Y:%.*]]
960 ; CHECK-NEXT: ret i1 [[CMP]]
962 %divx = sdiv exact i32 %x, 40
963 %divy = sdiv exact i32 %y, 40
964 %cmp = icmp ule i32 %divx, %divy
968 define i1 @test_sdiv_pos_ugt(i32 %x, i32 %y) {
969 ; CHECK-LABEL: @test_sdiv_pos_ugt(
970 ; CHECK-NEXT: [[CMP:%.*]] = icmp ugt i32 [[X:%.*]], [[Y:%.*]]
971 ; CHECK-NEXT: ret i1 [[CMP]]
973 %divx = sdiv exact i32 %x, 40
974 %divy = sdiv exact i32 %y, 40
975 %cmp = icmp ugt i32 %divx, %divy
979 define i1 @test_sdiv_pos_uge(i32 %x, i32 %y) {
980 ; CHECK-LABEL: @test_sdiv_pos_uge(
981 ; CHECK-NEXT: [[CMP:%.*]] = icmp uge i32 [[X:%.*]], [[Y:%.*]]
982 ; CHECK-NEXT: ret i1 [[CMP]]
984 %divx = sdiv exact i32 %x, 40
985 %divy = sdiv exact i32 %y, 40
986 %cmp = icmp uge i32 %divx, %divy
990 define i1 @test_sdiv_neg_slt(i32 %x, i32 %y) {
991 ; CHECK-LABEL: @test_sdiv_neg_slt(
992 ; CHECK-NEXT: [[DIVX:%.*]] = sdiv exact i32 [[X:%.*]], -40
993 ; CHECK-NEXT: [[DIVY:%.*]] = sdiv exact i32 [[Y:%.*]], -40
994 ; CHECK-NEXT: [[CMP:%.*]] = icmp slt i32 [[DIVX]], [[DIVY]]
995 ; CHECK-NEXT: ret i1 [[CMP]]
997 %divx = sdiv exact i32 %x, -40
998 %divy = sdiv exact i32 %y, -40
999 %cmp = icmp slt i32 %divx, %divy
1004 define <2 x i1> @test49(<2 x i32> %i3) {
1005 ; CHECK-LABEL: @test49(
1006 ; CHECK-NEXT: entry:
1007 ; CHECK-NEXT: ret <2 x i1> splat (i1 true)
1010 %i11 = and <2 x i32> %i3, <i32 3, i32 3>
1011 %cmp = icmp ult <2 x i32> %i11, <i32 4, i32 4>
1016 define i1 @test50(i16 %X, i32 %Y) {
1017 ; CHECK-LABEL: @test50(
1018 ; CHECK-NEXT: ret i1 true
1020 %A = zext i16 %X to i32
1021 %B = srem i32 %A, %Y
1022 %C = icmp sgt i32 %B, -1
1026 define i1 @test51(i32 %X, i32 %Y) {
1027 ; CHECK-LABEL: @test51(
1028 ; CHECK-NEXT: [[A:%.*]] = and i32 [[X:%.*]], -2147483648
1029 ; CHECK-NEXT: [[B:%.*]] = srem i32 [[A]], [[Y:%.*]]
1030 ; CHECK-NEXT: [[C:%.*]] = icmp sgt i32 [[B]], -1
1031 ; CHECK-NEXT: ret i1 [[C]]
1033 %A = and i32 %X, 2147483648
1034 %B = srem i32 %A, %Y
1035 %C = icmp sgt i32 %B, -1
1039 define i1 @test52(i32 %x1) {
1040 ; CHECK-LABEL: @test52(
1041 ; CHECK-NEXT: [[TMP1:%.*]] = and i32 [[X1:%.*]], 16711935
1042 ; CHECK-NEXT: [[A:%.*]] = icmp eq i32 [[TMP1]], 4980863
1043 ; CHECK-NEXT: ret i1 [[A]]
1045 %conv = and i32 %x1, 255
1046 %cmp = icmp eq i32 %conv, 127
1047 %i2 = lshr i32 %x1, 16
1048 %i3 = trunc i32 %i2 to i8
1049 %cmp15 = icmp eq i8 %i3, 76
1051 %A = and i1 %cmp, %cmp15
1055 define i1 @test52_logical(i32 %x1) {
1056 ; CHECK-LABEL: @test52_logical(
1057 ; CHECK-NEXT: [[TMP1:%.*]] = and i32 [[X1:%.*]], 16711935
1058 ; CHECK-NEXT: [[A:%.*]] = icmp eq i32 [[TMP1]], 4980863
1059 ; CHECK-NEXT: ret i1 [[A]]
1061 %conv = and i32 %x1, 255
1062 %cmp = icmp eq i32 %conv, 127
1063 %i2 = lshr i32 %x1, 16
1064 %i3 = trunc i32 %i2 to i8
1065 %cmp15 = icmp eq i8 %i3, 76
1067 %A = select i1 %cmp, i1 %cmp15, i1 false
1071 define i1 @test52b(i128 %x1) {
1072 ; CHECK-LABEL: @test52b(
1073 ; CHECK-NEXT: [[TMP1:%.*]] = and i128 [[X1:%.*]], 16711935
1074 ; CHECK-NEXT: [[A:%.*]] = icmp eq i128 [[TMP1]], 4980863
1075 ; CHECK-NEXT: ret i1 [[A]]
1077 %conv = and i128 %x1, 255
1078 %cmp = icmp eq i128 %conv, 127
1079 %i2 = lshr i128 %x1, 16
1080 %i3 = trunc i128 %i2 to i8
1081 %cmp15 = icmp eq i8 %i3, 76
1083 %A = and i1 %cmp, %cmp15
1087 define i1 @test52b_logical(i128 %x1) {
1088 ; CHECK-LABEL: @test52b_logical(
1089 ; CHECK-NEXT: [[TMP1:%.*]] = and i128 [[X1:%.*]], 16711935
1090 ; CHECK-NEXT: [[A:%.*]] = icmp eq i128 [[TMP1]], 4980863
1091 ; CHECK-NEXT: ret i1 [[A]]
1093 %conv = and i128 %x1, 255
1094 %cmp = icmp eq i128 %conv, 127
1095 %i2 = lshr i128 %x1, 16
1096 %i3 = trunc i128 %i2 to i8
1097 %cmp15 = icmp eq i8 %i3, 76
1099 %A = select i1 %cmp, i1 %cmp15, i1 false
1104 define i1 @test53(i32 %a, i32 %b) {
1105 ; CHECK-LABEL: @test53(
1106 ; CHECK-NEXT: [[X:%.*]] = sdiv exact i32 [[A:%.*]], 30
1107 ; CHECK-NEXT: [[Y:%.*]] = sdiv i32 [[B:%.*]], 30
1108 ; CHECK-NEXT: [[Z:%.*]] = icmp eq i32 [[X]], [[Y]]
1109 ; CHECK-NEXT: ret i1 [[Z]]
1111 %x = sdiv exact i32 %a, 30
1112 %y = sdiv i32 %b, 30
1113 %z = icmp eq i32 %x, %y
1117 define i1 @test54(i8 %a) {
1118 ; CHECK-LABEL: @test54(
1119 ; CHECK-NEXT: [[RET:%.*]] = icmp slt i8 [[A:%.*]], -64
1120 ; CHECK-NEXT: ret i1 [[RET]]
1122 %ext = zext i8 %a to i32
1123 %and = and i32 %ext, 192
1124 %ret = icmp eq i32 %and, 128
1128 define i1 @test55(i32 %a) {
1129 ; CHECK-LABEL: @test55(
1130 ; CHECK-NEXT: [[CMP:%.*]] = icmp eq i32 [[A:%.*]], -123
1131 ; CHECK-NEXT: ret i1 [[CMP]]
1133 %sub = sub i32 0, %a
1134 %cmp = icmp eq i32 %sub, 123
1138 define <2 x i1> @test55vec(<2 x i32> %a) {
1139 ; CHECK-LABEL: @test55vec(
1140 ; CHECK-NEXT: [[CMP:%.*]] = icmp eq <2 x i32> [[A:%.*]], splat (i32 -123)
1141 ; CHECK-NEXT: ret <2 x i1> [[CMP]]
1143 %sub = sub <2 x i32> zeroinitializer, %a
1144 %cmp = icmp eq <2 x i32> %sub, <i32 123, i32 123>
1148 define i1 @test56(i32 %a) {
1149 ; CHECK-LABEL: @test56(
1150 ; CHECK-NEXT: [[CMP:%.*]] = icmp eq i32 [[A:%.*]], -113
1151 ; CHECK-NEXT: ret i1 [[CMP]]
1153 %sub = sub i32 10, %a
1154 %cmp = icmp eq i32 %sub, 123
1158 define <2 x i1> @test56vec(<2 x i32> %a) {
1159 ; CHECK-LABEL: @test56vec(
1160 ; CHECK-NEXT: [[CMP:%.*]] = icmp eq <2 x i32> [[A:%.*]], splat (i32 -113)
1161 ; CHECK-NEXT: ret <2 x i1> [[CMP]]
1163 %sub = sub <2 x i32> <i32 10, i32 10>, %a
1164 %cmp = icmp eq <2 x i32> %sub, <i32 123, i32 123>
1168 ; PR10267 Don't make icmps more expensive when no other inst is subsumed.
1169 define i1 @test57(i32 %a) {
1170 ; CHECK-LABEL: @test57(
1171 ; CHECK-NEXT: [[AND:%.*]] = and i32 [[A:%.*]], -2
1172 ; CHECK-NEXT: [[CMP:%.*]] = icmp ne i32 [[AND]], 0
1173 ; CHECK-NEXT: call void @use_i32(i32 [[AND]])
1174 ; CHECK-NEXT: ret i1 [[CMP]]
1176 %and = and i32 %a, -2
1177 %cmp = icmp ne i32 %and, 0
1178 call void @use_i32(i32 %and)
1182 ; rdar://problem/10482509
1183 define zeroext i1 @cmpabs1(i64 %val) {
1184 ; CHECK-LABEL: @cmpabs1(
1185 ; CHECK-NEXT: [[TOBOOL:%.*]] = icmp ne i64 [[VAL:%.*]], 0
1186 ; CHECK-NEXT: ret i1 [[TOBOOL]]
1188 %sub = sub nsw i64 0, %val
1189 %cmp = icmp slt i64 %val, 0
1190 %sub.val = select i1 %cmp, i64 %sub, i64 %val
1191 %tobool = icmp ne i64 %sub.val, 0
1195 define zeroext i1 @cmpabs2(i64 %val) {
1196 ; CHECK-LABEL: @cmpabs2(
1197 ; CHECK-NEXT: [[TOBOOL:%.*]] = icmp ne i64 [[VAL:%.*]], 0
1198 ; CHECK-NEXT: ret i1 [[TOBOOL]]
1200 %sub = sub nsw i64 0, %val
1201 %cmp = icmp slt i64 %val, 0
1202 %sub.val = select i1 %cmp, i64 %val, i64 %sub
1203 %tobool = icmp ne i64 %sub.val, 0
1207 define i1 @abs_intrin_eq_zero(i8 %x) {
1208 ; CHECK-LABEL: @abs_intrin_eq_zero(
1209 ; CHECK-NEXT: [[CMP:%.*]] = icmp eq i8 [[X:%.*]], 0
1210 ; CHECK-NEXT: ret i1 [[CMP]]
1212 %abs = call i8 @llvm.abs.i8(i8 %x, i1 false)
1213 %cmp = icmp eq i8 %abs, 0
1217 define i1 @abs_intrin_ne_zero(i8 %x) {
1218 ; CHECK-LABEL: @abs_intrin_ne_zero(
1219 ; CHECK-NEXT: [[CMP:%.*]] = icmp ne i8 [[X:%.*]], 0
1220 ; CHECK-NEXT: ret i1 [[CMP]]
1222 %abs = call i8 @llvm.abs.i8(i8 %x, i1 false)
1223 %cmp = icmp ne i8 %abs, 0
1227 define void @test58() {
1228 ; CHECK-LABEL: @test58(
1229 ; CHECK-NEXT: [[CALL:%.*]] = call i32 @test58_d(i64 36029346783166592)
1230 ; CHECK-NEXT: ret void
1232 %cast = bitcast <1 x i64> <i64 36029346783166592> to i64
1233 %call = call i32 @test58_d( i64 %cast)
1236 declare i32 @test58_d(i64)
1238 ; Negative test: GEP inbounds may cross sign boundary.
1239 define i1 @test62(ptr %a) {
1240 ; CHECK-LABEL: @test62(
1241 ; CHECK-NEXT: [[ARRAYIDX1:%.*]] = getelementptr inbounds nuw i8, ptr [[A:%.*]], i64 1
1242 ; CHECK-NEXT: [[ARRAYIDX2:%.*]] = getelementptr inbounds nuw i8, ptr [[A]], i64 10
1243 ; CHECK-NEXT: [[CMP:%.*]] = icmp slt ptr [[ARRAYIDX1]], [[ARRAYIDX2]]
1244 ; CHECK-NEXT: ret i1 [[CMP]]
1246 %arrayidx1 = getelementptr inbounds i8, ptr %a, i64 1
1247 %arrayidx2 = getelementptr inbounds i8, ptr %a, i64 10
1248 %cmp = icmp slt ptr %arrayidx1, %arrayidx2
1252 define i1 @test62_as1(ptr addrspace(1) %a) {
1253 ; CHECK-LABEL: @test62_as1(
1254 ; CHECK-NEXT: [[ARRAYIDX1:%.*]] = getelementptr inbounds nuw i8, ptr addrspace(1) [[A:%.*]], i16 1
1255 ; CHECK-NEXT: [[ARRAYIDX2:%.*]] = getelementptr inbounds nuw i8, ptr addrspace(1) [[A]], i16 10
1256 ; CHECK-NEXT: [[CMP:%.*]] = icmp slt ptr addrspace(1) [[ARRAYIDX1]], [[ARRAYIDX2]]
1257 ; CHECK-NEXT: ret i1 [[CMP]]
1259 %arrayidx1 = getelementptr inbounds i8, ptr addrspace(1) %a, i64 1
1260 %arrayidx2 = getelementptr inbounds i8, ptr addrspace(1) %a, i64 10
1261 %cmp = icmp slt ptr addrspace(1) %arrayidx1, %arrayidx2
1265 define i1 @low_mask_eq_zext(i8 %a, i32 %b) {
1266 ; CHECK-LABEL: @low_mask_eq_zext(
1267 ; CHECK-NEXT: [[TMP1:%.*]] = trunc i32 [[B:%.*]] to i8
1268 ; CHECK-NEXT: [[C:%.*]] = icmp eq i8 [[A:%.*]], [[TMP1]]
1269 ; CHECK-NEXT: ret i1 [[C]]
1271 %z = zext i8 %a to i32
1272 %t = and i32 %b, 255
1273 %c = icmp eq i32 %z, %t
1277 define i1 @low_mask_eq_zext_commute(i8 %a, i32 %b) {
1278 ; CHECK-LABEL: @low_mask_eq_zext_commute(
1279 ; CHECK-NEXT: [[TMP1:%.*]] = trunc i32 [[B:%.*]] to i8
1280 ; CHECK-NEXT: [[C:%.*]] = icmp eq i8 [[A:%.*]], [[TMP1]]
1281 ; CHECK-NEXT: ret i1 [[C]]
1283 %t = and i32 %b, 255
1284 %z = zext i8 %a to i32
1285 %c = icmp eq i32 %t, %z
1291 define i1 @wrong_low_mask_eq_zext(i8 %a, i32 %b) {
1292 ; CHECK-LABEL: @wrong_low_mask_eq_zext(
1293 ; CHECK-NEXT: [[T:%.*]] = and i32 [[B:%.*]], 127
1294 ; CHECK-NEXT: [[Z:%.*]] = zext i8 [[A:%.*]] to i32
1295 ; CHECK-NEXT: [[C:%.*]] = icmp eq i32 [[T]], [[Z]]
1296 ; CHECK-NEXT: ret i1 [[C]]
1298 %t = and i32 %b, 127
1299 %z = zext i8 %a to i32
1300 %c = icmp eq i32 %t, %z
1306 define i1 @wrong_low_mask_eq_zext2(i8 %a, i32 %b) {
1307 ; CHECK-LABEL: @wrong_low_mask_eq_zext2(
1308 ; CHECK-NEXT: [[T:%.*]] = and i32 [[B:%.*]], 254
1309 ; CHECK-NEXT: [[Z:%.*]] = zext i8 [[A:%.*]] to i32
1310 ; CHECK-NEXT: [[C:%.*]] = icmp eq i32 [[T]], [[Z]]
1311 ; CHECK-NEXT: ret i1 [[C]]
1313 %t = and i32 %b, 254
1314 %z = zext i8 %a to i32
1315 %c = icmp eq i32 %t, %z
1319 define i1 @low_mask_eq_zext_use1(i8 %a, i32 %b) {
1320 ; CHECK-LABEL: @low_mask_eq_zext_use1(
1321 ; CHECK-NEXT: [[T:%.*]] = and i32 [[B:%.*]], 255
1322 ; CHECK-NEXT: call void @use_i32(i32 [[T]])
1323 ; CHECK-NEXT: [[TMP1:%.*]] = trunc i32 [[B]] to i8
1324 ; CHECK-NEXT: [[C:%.*]] = icmp eq i8 [[A:%.*]], [[TMP1]]
1325 ; CHECK-NEXT: ret i1 [[C]]
1327 %t = and i32 %b, 255
1328 call void @use_i32(i32 %t)
1329 %z = zext i8 %a to i32
1330 %c = icmp eq i32 %t, %z
1334 define i1 @low_mask_eq_zext_use2(i8 %a, i32 %b) {
1335 ; CHECK-LABEL: @low_mask_eq_zext_use2(
1336 ; CHECK-NEXT: [[Z:%.*]] = zext i8 [[A:%.*]] to i32
1337 ; CHECK-NEXT: call void @use_i32(i32 [[Z]])
1338 ; CHECK-NEXT: [[TMP1:%.*]] = trunc i32 [[B:%.*]] to i8
1339 ; CHECK-NEXT: [[C:%.*]] = icmp eq i8 [[A]], [[TMP1]]
1340 ; CHECK-NEXT: ret i1 [[C]]
1342 %t = and i32 %b, 255
1343 %z = zext i8 %a to i32
1344 call void @use_i32(i32 %z)
1345 %c = icmp eq i32 %t, %z
1349 define i1 @low_mask_eq_zext_use3(i8 %a, i32 %b) {
1350 ; CHECK-LABEL: @low_mask_eq_zext_use3(
1351 ; CHECK-NEXT: [[T:%.*]] = and i32 [[B:%.*]], 255
1352 ; CHECK-NEXT: call void @use_i32(i32 [[T]])
1353 ; CHECK-NEXT: [[Z:%.*]] = zext i8 [[A:%.*]] to i32
1354 ; CHECK-NEXT: call void @use_i32(i32 [[Z]])
1355 ; CHECK-NEXT: [[C:%.*]] = icmp eq i32 [[T]], [[Z]]
1356 ; CHECK-NEXT: ret i1 [[C]]
1358 %t = and i32 %b, 255
1359 call void @use_i32(i32 %t)
1360 %z = zext i8 %a to i32
1361 call void @use_i32(i32 %z)
1362 %c = icmp eq i32 %t, %z
1366 define <2 x i1> @low_mask_eq_zext_vec_splat(<2 x i8> %a, <2 x i32> %b) {
1367 ; CHECK-LABEL: @low_mask_eq_zext_vec_splat(
1368 ; CHECK-NEXT: [[TMP1:%.*]] = trunc <2 x i32> [[B:%.*]] to <2 x i8>
1369 ; CHECK-NEXT: [[C:%.*]] = icmp eq <2 x i8> [[A:%.*]], [[TMP1]]
1370 ; CHECK-NEXT: ret <2 x i1> [[C]]
1372 %t = and <2 x i32> %b, <i32 255, i32 255>
1373 %z = zext <2 x i8> %a to <2 x i32>
1374 %c = icmp eq <2 x i32> %t, %z
1378 define i1 @test65(i64 %A, i64 %B) {
1379 ; CHECK-LABEL: @test65(
1380 ; CHECK-NEXT: ret i1 true
1382 %s1 = add i64 %A, %B
1383 %s2 = add i64 %A, %B
1384 %cmp = icmp eq i64 %s1, %s2
1388 define i1 @test66(i64 %A, i64 %B) {
1389 ; CHECK-LABEL: @test66(
1390 ; CHECK-NEXT: ret i1 true
1392 %s1 = add i64 %A, %B
1393 %s2 = add i64 %B, %A
1394 %cmp = icmp eq i64 %s1, %s2
1398 define i1 @test67(i32 %x) {
1399 ; CHECK-LABEL: @test67(
1400 ; CHECK-NEXT: [[AND:%.*]] = and i32 [[X:%.*]], 96
1401 ; CHECK-NEXT: [[CMP:%.*]] = icmp ne i32 [[AND]], 0
1402 ; CHECK-NEXT: ret i1 [[CMP]]
1404 %and = and i32 %x, 127
1405 %cmp = icmp sgt i32 %and, 31
1409 define i1 @test67inverse(i32 %x) {
1410 ; CHECK-LABEL: @test67inverse(
1411 ; CHECK-NEXT: [[AND:%.*]] = and i32 [[X:%.*]], 96
1412 ; CHECK-NEXT: [[CMP:%.*]] = icmp eq i32 [[AND]], 0
1413 ; CHECK-NEXT: ret i1 [[CMP]]
1415 %and = and i32 %x, 127
1416 %cmp = icmp sle i32 %and, 31
1420 ; The test above relies on 3 different folds.
1421 ; This test only checks the last of those (icmp ugt -> icmp ne).
1423 define <2 x i1> @test67vec(<2 x i32> %x) {
1424 ; CHECK-LABEL: @test67vec(
1425 ; CHECK-NEXT: [[AND:%.*]] = and <2 x i32> [[X:%.*]], splat (i32 96)
1426 ; CHECK-NEXT: [[CMP:%.*]] = icmp ne <2 x i32> [[AND]], zeroinitializer
1427 ; CHECK-NEXT: ret <2 x i1> [[CMP]]
1429 %and = and <2 x i32> %x, <i32 96, i32 96>
1430 %cmp = icmp ugt <2 x i32> %and, <i32 31, i32 31>
1434 define <2 x i1> @test67vec2(<2 x i32> %x) {
1435 ; CHECK-LABEL: @test67vec2(
1436 ; CHECK-NEXT: [[AND:%.*]] = and <2 x i32> [[X:%.*]], splat (i32 96)
1437 ; CHECK-NEXT: [[CMP:%.*]] = icmp ne <2 x i32> [[AND]], zeroinitializer
1438 ; CHECK-NEXT: ret <2 x i1> [[CMP]]
1440 %and = and <2 x i32> %x, <i32 127, i32 127>
1441 %cmp = icmp ugt <2 x i32> %and, <i32 31, i32 31>
1445 define <2 x i1> @test67vecinverse(<2 x i32> %x) {
1446 ; CHECK-LABEL: @test67vecinverse(
1447 ; CHECK-NEXT: [[AND:%.*]] = and <2 x i32> [[X:%.*]], splat (i32 96)
1448 ; CHECK-NEXT: [[CMP:%.*]] = icmp eq <2 x i32> [[AND]], zeroinitializer
1449 ; CHECK-NEXT: ret <2 x i1> [[CMP]]
1451 %and = and <2 x i32> %x, <i32 96, i32 96>
1452 %cmp = icmp sle <2 x i32> %and, <i32 31, i32 31>
1456 define i1 @test68(i32 %x) {
1457 ; CHECK-LABEL: @test68(
1458 ; CHECK-NEXT: [[AND:%.*]] = and i32 [[X:%.*]], 127
1459 ; CHECK-NEXT: [[CMP:%.*]] = icmp samesign ugt i32 [[AND]], 30
1460 ; CHECK-NEXT: ret i1 [[CMP]]
1462 %and = and i32 %x, 127
1463 %cmp = icmp sgt i32 %and, 30
1468 define i1 @test70(i32 %X) {
1469 ; CHECK-LABEL: @test70(
1470 ; CHECK-NEXT: [[A:%.*]] = srem i32 5, [[X:%.*]]
1471 ; CHECK-NEXT: [[C:%.*]] = icmp ne i32 [[A]], 2
1472 ; CHECK-NEXT: ret i1 [[C]]
1476 %C = icmp ne i32 %B, 4
1480 define <2 x i1> @test70vec(<2 x i32> %X) {
1481 ; CHECK-LABEL: @test70vec(
1482 ; CHECK-NEXT: [[C:%.*]] = icmp ne <2 x i32> [[X:%.*]], splat (i32 2)
1483 ; CHECK-NEXT: ret <2 x i1> [[C]]
1485 %B = add <2 x i32> %X, <i32 2, i32 2>
1486 %C = icmp ne <2 x i32> %B, <i32 4, i32 4>
1490 define i1 @icmp_sext16trunc(i32 %x) {
1491 ; CHECK-LABEL: @icmp_sext16trunc(
1492 ; CHECK-NEXT: [[TMP1:%.*]] = trunc i32 [[X:%.*]] to i16
1493 ; CHECK-NEXT: [[CMP:%.*]] = icmp slt i16 [[TMP1]], 36
1494 ; CHECK-NEXT: ret i1 [[CMP]]
1496 %trunc = trunc i32 %x to i16
1497 %sext = sext i16 %trunc to i32
1498 %cmp = icmp slt i32 %sext, 36
1502 define i1 @icmp_sext8trunc(i32 %x) {
1503 ; CHECK-LABEL: @icmp_sext8trunc(
1504 ; CHECK-NEXT: [[TMP1:%.*]] = trunc i32 [[X:%.*]] to i8
1505 ; CHECK-NEXT: [[CMP:%.*]] = icmp slt i8 [[TMP1]], 36
1506 ; CHECK-NEXT: ret i1 [[CMP]]
1508 %trunc = trunc i32 %x to i8
1509 %sext = sext i8 %trunc to i32
1510 %cmp = icmp slt i32 %sext, 36
1514 ; Vectors should fold the same way.
1515 define <2 x i1> @icmp_sext8trunc_vec(<2 x i32> %x) {
1516 ; CHECK-LABEL: @icmp_sext8trunc_vec(
1517 ; CHECK-NEXT: [[TMP1:%.*]] = trunc <2 x i32> [[X:%.*]] to <2 x i8>
1518 ; CHECK-NEXT: [[CMP:%.*]] = icmp slt <2 x i8> [[TMP1]], splat (i8 36)
1519 ; CHECK-NEXT: ret <2 x i1> [[CMP]]
1521 %trunc = trunc <2 x i32> %x to <2 x i8>
1522 %sext = sext <2 x i8> %trunc to <2 x i32>
1523 %cmp = icmp slt <2 x i32> %sext, <i32 36, i32 36>
1527 define i1 @icmp_shl16(i32 %x) {
1528 ; CHECK-LABEL: @icmp_shl16(
1529 ; CHECK-NEXT: [[TMP1:%.*]] = trunc i32 [[X:%.*]] to i16
1530 ; CHECK-NEXT: [[CMP:%.*]] = icmp slt i16 [[TMP1]], 36
1531 ; CHECK-NEXT: ret i1 [[CMP]]
1533 %shl = shl i32 %x, 16
1534 %cmp = icmp slt i32 %shl, 2359296
1538 ; D25952: Don't create illegal types like i15 in InstCombine
1540 define i1 @icmp_shl17(i32 %x) {
1541 ; CHECK-LABEL: @icmp_shl17(
1542 ; CHECK-NEXT: [[SHL:%.*]] = shl i32 [[X:%.*]], 17
1543 ; CHECK-NEXT: [[CMP:%.*]] = icmp slt i32 [[SHL]], 2359296
1544 ; CHECK-NEXT: ret i1 [[CMP]]
1546 %shl = shl i32 %x, 17
1547 %cmp = icmp slt i32 %shl, 2359296
1551 define <2 x i1> @icmp_shl16_vec(<2 x i32> %x) {
1552 ; CHECK-LABEL: @icmp_shl16_vec(
1553 ; CHECK-NEXT: [[TMP1:%.*]] = trunc <2 x i32> [[X:%.*]] to <2 x i16>
1554 ; CHECK-NEXT: [[CMP:%.*]] = icmp slt <2 x i16> [[TMP1]], splat (i16 36)
1555 ; CHECK-NEXT: ret <2 x i1> [[CMP]]
1557 %shl = shl <2 x i32> %x, <i32 16, i32 16>
1558 %cmp = icmp slt <2 x i32> %shl, <i32 2359296, i32 2359296>
1562 define i1 @icmp_shl24(i32 %x) {
1563 ; CHECK-LABEL: @icmp_shl24(
1564 ; CHECK-NEXT: [[TMP1:%.*]] = trunc i32 [[X:%.*]] to i8
1565 ; CHECK-NEXT: [[CMP:%.*]] = icmp slt i8 [[TMP1]], 36
1566 ; CHECK-NEXT: ret i1 [[CMP]]
1568 %shl = shl i32 %x, 24
1569 %cmp = icmp slt i32 %shl, 603979776
1573 define i1 @icmp_shl_eq(i32 %x) {
1574 ; CHECK-LABEL: @icmp_shl_eq(
1575 ; CHECK-NEXT: [[MUL_MASK:%.*]] = and i32 [[X:%.*]], 134217727
1576 ; CHECK-NEXT: [[CMP:%.*]] = icmp eq i32 [[MUL_MASK]], 0
1577 ; CHECK-NEXT: ret i1 [[CMP]]
1579 %mul = shl i32 %x, 5
1580 %cmp = icmp eq i32 %mul, 0
1584 define <2 x i1> @icmp_shl_eq_vec(<2 x i32> %x) {
1585 ; CHECK-LABEL: @icmp_shl_eq_vec(
1586 ; CHECK-NEXT: [[MUL_MASK:%.*]] = and <2 x i32> [[X:%.*]], splat (i32 134217727)
1587 ; CHECK-NEXT: [[CMP:%.*]] = icmp eq <2 x i32> [[MUL_MASK]], zeroinitializer
1588 ; CHECK-NEXT: ret <2 x i1> [[CMP]]
1590 %mul = shl <2 x i32> %x, <i32 5, i32 5>
1591 %cmp = icmp eq <2 x i32> %mul, zeroinitializer
1595 define i1 @icmp_shl_nsw_ne(i32 %x) {
1596 ; CHECK-LABEL: @icmp_shl_nsw_ne(
1597 ; CHECK-NEXT: [[CMP:%.*]] = icmp ne i32 [[X:%.*]], 0
1598 ; CHECK-NEXT: ret i1 [[CMP]]
1600 %mul = shl nsw i32 %x, 7
1601 %cmp = icmp ne i32 %mul, 0
1605 define <2 x i1> @icmp_shl_nsw_ne_vec(<2 x i32> %x) {
1606 ; CHECK-LABEL: @icmp_shl_nsw_ne_vec(
1607 ; CHECK-NEXT: [[CMP:%.*]] = icmp ne <2 x i32> [[X:%.*]], zeroinitializer
1608 ; CHECK-NEXT: ret <2 x i1> [[CMP]]
1610 %mul = shl nsw <2 x i32> %x, <i32 7, i32 7>
1611 %cmp = icmp ne <2 x i32> %mul, zeroinitializer
1615 define i1 @icmp_shl_ne(i32 %x) {
1616 ; CHECK-LABEL: @icmp_shl_ne(
1617 ; CHECK-NEXT: [[MUL_MASK:%.*]] = and i32 [[X:%.*]], 33554431
1618 ; CHECK-NEXT: [[CMP:%.*]] = icmp ne i32 [[MUL_MASK]], 0
1619 ; CHECK-NEXT: ret i1 [[CMP]]
1621 %mul = shl i32 %x, 7
1622 %cmp = icmp ne i32 %mul, 0
1626 define <2 x i1> @icmp_shl_ne_vec(<2 x i32> %x) {
1627 ; CHECK-LABEL: @icmp_shl_ne_vec(
1628 ; CHECK-NEXT: [[MUL_MASK:%.*]] = and <2 x i32> [[X:%.*]], splat (i32 33554431)
1629 ; CHECK-NEXT: [[CMP:%.*]] = icmp ne <2 x i32> [[MUL_MASK]], zeroinitializer
1630 ; CHECK-NEXT: ret <2 x i1> [[CMP]]
1632 %mul = shl <2 x i32> %x, <i32 7, i32 7>
1633 %cmp = icmp ne <2 x i32> %mul, zeroinitializer
1637 define <2 x i1> @icmp_shl_nuw_ne_vec(<2 x i32> %x) {
1638 ; CHECK-LABEL: @icmp_shl_nuw_ne_vec(
1639 ; CHECK-NEXT: [[CMP:%.*]] = icmp ne <2 x i32> [[X:%.*]], splat (i32 2)
1640 ; CHECK-NEXT: ret <2 x i1> [[CMP]]
1642 %shl = shl nuw <2 x i32> %x, <i32 7, i32 7>
1643 %cmp = icmp ne <2 x i32> %shl, <i32 256, i32 256>
1647 ; If the (mul x, C) preserved the sign and this is sign test,
1648 ; compare the LHS operand instead
1649 define i1 @icmp_mul_nsw(i32 %x) {
1650 ; CHECK-LABEL: @icmp_mul_nsw(
1651 ; CHECK-NEXT: [[CMP:%.*]] = icmp sgt i32 [[X:%.*]], 0
1652 ; CHECK-NEXT: ret i1 [[CMP]]
1654 %mul = mul nsw i32 %x, 12
1655 %cmp = icmp sgt i32 %mul, 0
1659 define i1 @icmp_mul_nsw1(i32 %x) {
1660 ; CHECK-LABEL: @icmp_mul_nsw1(
1661 ; CHECK-NEXT: [[CMP:%.*]] = icmp slt i32 [[X:%.*]], 0
1662 ; CHECK-NEXT: ret i1 [[CMP]]
1664 %mul = mul nsw i32 %x, 12
1665 %cmp = icmp sle i32 %mul, -1
1669 define i1 @icmp_mul_nsw_neg(i32 %x) {
1670 ; CHECK-LABEL: @icmp_mul_nsw_neg(
1671 ; CHECK-NEXT: [[CMP:%.*]] = icmp slt i32 [[X:%.*]], 1
1672 ; CHECK-NEXT: ret i1 [[CMP]]
1674 %mul = mul nsw i32 %x, -12
1675 %cmp = icmp sge i32 %mul, 0
1679 define i1 @icmp_mul_nsw_neg1(i32 %x) {
1680 ; CHECK-LABEL: @icmp_mul_nsw_neg1(
1681 ; CHECK-NEXT: [[CMP:%.*]] = icmp slt i32 [[X:%.*]], 0
1682 ; CHECK-NEXT: ret i1 [[CMP]]
1684 %mul = mul nsw i32 %x, -12
1685 %cmp = icmp sge i32 %mul, 1
1689 define <2 x i1> @icmp_mul_nsw_neg1_vec(<2 x i32> %x) {
1690 ; CHECK-LABEL: @icmp_mul_nsw_neg1_vec(
1691 ; CHECK-NEXT: [[CMP:%.*]] = icmp slt <2 x i32> [[X:%.*]], zeroinitializer
1692 ; CHECK-NEXT: ret <2 x i1> [[CMP]]
1694 %mul = mul nsw <2 x i32> %x, <i32 -12, i32 -12>
1695 %cmp = icmp sge <2 x i32> %mul, <i32 1, i32 1>
1699 define i1 @icmp_mul_nsw_0(i32 %x) {
1700 ; CHECK-LABEL: @icmp_mul_nsw_0(
1701 ; CHECK-NEXT: ret i1 false
1703 %mul = mul nsw i32 %x, 0
1704 %cmp = icmp sgt i32 %mul, 0
1708 define i1 @icmp_mul(i32 %x) {
1709 ; CHECK-LABEL: @icmp_mul(
1710 ; CHECK-NEXT: [[MUL:%.*]] = mul i32 [[X:%.*]], -12
1711 ; CHECK-NEXT: [[CMP:%.*]] = icmp sgt i32 [[MUL]], -1
1712 ; CHECK-NEXT: ret i1 [[CMP]]
1714 %mul = mul i32 %x, -12
1715 %cmp = icmp sge i32 %mul, 0
1719 ; Checks for icmp (eq|ne) (mul x, C), 0
1720 define i1 @icmp_mul_neq0(i32 %x) {
1721 ; CHECK-LABEL: @icmp_mul_neq0(
1722 ; CHECK-NEXT: [[CMP:%.*]] = icmp ne i32 [[X:%.*]], 0
1723 ; CHECK-NEXT: ret i1 [[CMP]]
1725 %mul = mul nsw i32 %x, -12
1726 %cmp = icmp ne i32 %mul, 0
1730 define <2 x i1> @icmp_mul_neq0_vec(<2 x i32> %x) {
1731 ; CHECK-LABEL: @icmp_mul_neq0_vec(
1732 ; CHECK-NEXT: [[CMP:%.*]] = icmp ne <2 x i32> [[X:%.*]], zeroinitializer
1733 ; CHECK-NEXT: ret <2 x i1> [[CMP]]
1735 %mul = mul nsw <2 x i32> %x, <i32 -12, i32 -12>
1736 %cmp = icmp ne <2 x i32> %mul, zeroinitializer
1740 define i1 @icmp_mul_eq0(i32 %x) {
1741 ; CHECK-LABEL: @icmp_mul_eq0(
1742 ; CHECK-NEXT: [[CMP:%.*]] = icmp eq i32 [[X:%.*]], 0
1743 ; CHECK-NEXT: ret i1 [[CMP]]
1745 %mul = mul nsw i32 %x, 12
1746 %cmp = icmp eq i32 %mul, 0
1750 define i1 @icmp_mul0_eq0(i32 %x) {
1751 ; CHECK-LABEL: @icmp_mul0_eq0(
1752 ; CHECK-NEXT: ret i1 true
1754 %mul = mul i32 %x, 0
1755 %cmp = icmp eq i32 %mul, 0
1759 define i1 @icmp_mul0_ne0(i32 %x) {
1760 ; CHECK-LABEL: @icmp_mul0_ne0(
1761 ; CHECK-NEXT: ret i1 false
1763 %mul = mul i32 %x, 0
1764 %cmp = icmp ne i32 %mul, 0
1768 define i1 @icmp_add20_eq_add57(i32 %x, i32 %y) {
1769 ; CHECK-LABEL: @icmp_add20_eq_add57(
1770 ; CHECK-NEXT: [[TMP1:%.*]] = add i32 [[Y:%.*]], 37
1771 ; CHECK-NEXT: [[CMP:%.*]] = icmp eq i32 [[X:%.*]], [[TMP1]]
1772 ; CHECK-NEXT: ret i1 [[CMP]]
1776 %cmp = icmp eq i32 %1, %2
1780 define <2 x i1> @icmp_add20_eq_add57_splat(<2 x i32> %x, <2 x i32> %y) {
1781 ; CHECK-LABEL: @icmp_add20_eq_add57_splat(
1782 ; CHECK-NEXT: [[TMP1:%.*]] = add <2 x i32> [[Y:%.*]], splat (i32 37)
1783 ; CHECK-NEXT: [[CMP:%.*]] = icmp eq <2 x i32> [[X:%.*]], [[TMP1]]
1784 ; CHECK-NEXT: ret <2 x i1> [[CMP]]
1786 %1 = add <2 x i32> %x, <i32 20, i32 20>
1787 %2 = add <2 x i32> %y, <i32 57, i32 57>
1788 %cmp = icmp eq <2 x i32> %1, %2
1792 define <2 x i1> @icmp_add20_eq_add57_poison(<2 x i32> %x, <2 x i32> %y) {
1793 ; CHECK-LABEL: @icmp_add20_eq_add57_poison(
1794 ; CHECK-NEXT: [[TMP1:%.*]] = add <2 x i32> [[Y:%.*]], splat (i32 37)
1795 ; CHECK-NEXT: [[CMP:%.*]] = icmp eq <2 x i32> [[X:%.*]], [[TMP1]]
1796 ; CHECK-NEXT: ret <2 x i1> [[CMP]]
1798 %1 = add <2 x i32> %x, <i32 20, i32 20>
1799 %2 = add <2 x i32> %y, <i32 57, i32 poison>
1800 %cmp = icmp eq <2 x i32> %1, %2
1804 define <2 x i1> @icmp_add20_eq_add57_vec_nonsplat(<2 x i32> %x, <2 x i32> %y) {
1805 ; CHECK-LABEL: @icmp_add20_eq_add57_vec_nonsplat(
1806 ; CHECK-NEXT: [[TMP1:%.*]] = add <2 x i32> [[Y:%.*]], <i32 37, i32 39>
1807 ; CHECK-NEXT: [[CMP:%.*]] = icmp eq <2 x i32> [[X:%.*]], [[TMP1]]
1808 ; CHECK-NEXT: ret <2 x i1> [[CMP]]
1810 %1 = add <2 x i32> %x, <i32 20, i32 19>
1811 %2 = add <2 x i32> %y, <i32 57, i32 58>
1812 %cmp = icmp eq <2 x i32> %1, %2
1816 define i1 @icmp_sub57_ne_sub20(i32 %x, i32 %y) {
1817 ; CHECK-LABEL: @icmp_sub57_ne_sub20(
1818 ; CHECK-NEXT: [[TMP1:%.*]] = add i32 [[X:%.*]], -37
1819 ; CHECK-NEXT: [[CMP:%.*]] = icmp ne i32 [[TMP1]], [[Y:%.*]]
1820 ; CHECK-NEXT: ret i1 [[CMP]]
1822 %1 = add i32 %x, -57
1823 %2 = add i32 %y, -20
1824 %cmp = icmp ne i32 %1, %2
1828 define <2 x i1> @icmp_sub57_ne_sub20_splat(<2 x i32> %x, <2 x i32> %y) {
1829 ; CHECK-LABEL: @icmp_sub57_ne_sub20_splat(
1830 ; CHECK-NEXT: [[TMP1:%.*]] = add <2 x i32> [[X:%.*]], splat (i32 -37)
1831 ; CHECK-NEXT: [[CMP:%.*]] = icmp ne <2 x i32> [[TMP1]], [[Y:%.*]]
1832 ; CHECK-NEXT: ret <2 x i1> [[CMP]]
1834 %1 = add <2 x i32> %x, <i32 -57, i32 -57>
1835 %2 = add <2 x i32> %y, <i32 -20, i32 -20>
1836 %cmp = icmp ne <2 x i32> %1, %2
1840 define <2 x i1> @icmp_sub57_ne_sub20_vec_poison(<2 x i32> %x, <2 x i32> %y) {
1841 ; CHECK-LABEL: @icmp_sub57_ne_sub20_vec_poison(
1842 ; CHECK-NEXT: [[TMP1:%.*]] = add <2 x i32> [[X:%.*]], splat (i32 -37)
1843 ; CHECK-NEXT: [[CMP:%.*]] = icmp ne <2 x i32> [[TMP1]], [[Y:%.*]]
1844 ; CHECK-NEXT: ret <2 x i1> [[CMP]]
1846 %1 = add <2 x i32> %x, <i32 -57, i32 poison>
1847 %2 = add <2 x i32> %y, <i32 -20, i32 poison>
1848 %cmp = icmp ne <2 x i32> %1, %2
1852 define <2 x i1> @icmp_sub57_ne_sub20_vec_nonsplat(<2 x i32> %x, <2 x i32> %y) {
1853 ; CHECK-LABEL: @icmp_sub57_ne_sub20_vec_nonsplat(
1854 ; CHECK-NEXT: [[TMP1:%.*]] = add <2 x i32> [[Y:%.*]], splat (i32 37)
1855 ; CHECK-NEXT: [[CMP:%.*]] = icmp ne <2 x i32> [[X:%.*]], [[TMP1]]
1856 ; CHECK-NEXT: ret <2 x i1> [[CMP]]
1858 %1 = add <2 x i32> %x, <i32 -57, i32 -58>
1859 %2 = add <2 x i32> %y, <i32 -20, i32 -21>
1860 %cmp = icmp ne <2 x i32> %1, %2
1864 define i1 @icmp_sub1_sge(i32 %x, i32 %y) {
1865 ; CHECK-LABEL: @icmp_sub1_sge(
1866 ; CHECK-NEXT: [[CMP:%.*]] = icmp sgt i32 [[X:%.*]], [[Y:%.*]]
1867 ; CHECK-NEXT: ret i1 [[CMP]]
1869 %sub = add nsw i32 %x, -1
1870 %cmp = icmp sge i32 %sub, %y
1874 define i1 @icmp_add1_sgt(i32 %x, i32 %y) {
1875 ; CHECK-LABEL: @icmp_add1_sgt(
1876 ; CHECK-NEXT: [[CMP:%.*]] = icmp sge i32 [[X:%.*]], [[Y:%.*]]
1877 ; CHECK-NEXT: ret i1 [[CMP]]
1879 %add = add nsw i32 %x, 1
1880 %cmp = icmp sgt i32 %add, %y
1884 define i1 @icmp_sub1_slt(i32 %x, i32 %y) {
1885 ; CHECK-LABEL: @icmp_sub1_slt(
1886 ; CHECK-NEXT: [[CMP:%.*]] = icmp sle i32 [[X:%.*]], [[Y:%.*]]
1887 ; CHECK-NEXT: ret i1 [[CMP]]
1889 %sub = add nsw i32 %x, -1
1890 %cmp = icmp slt i32 %sub, %y
1894 define i1 @icmp_add1_sle(i32 %x, i32 %y) {
1895 ; CHECK-LABEL: @icmp_add1_sle(
1896 ; CHECK-NEXT: [[CMP:%.*]] = icmp slt i32 [[X:%.*]], [[Y:%.*]]
1897 ; CHECK-NEXT: ret i1 [[CMP]]
1899 %add = add nsw i32 %x, 1
1900 %cmp = icmp sle i32 %add, %y
1904 define i1 @icmp_add20_sge_add57(i32 %x, i32 %y) {
1905 ; CHECK-LABEL: @icmp_add20_sge_add57(
1906 ; CHECK-NEXT: [[TMP1:%.*]] = add nsw i32 [[Y:%.*]], 37
1907 ; CHECK-NEXT: [[CMP:%.*]] = icmp sge i32 [[X:%.*]], [[TMP1]]
1908 ; CHECK-NEXT: ret i1 [[CMP]]
1910 %1 = add nsw i32 %x, 20
1911 %2 = add nsw i32 %y, 57
1912 %cmp = icmp sge i32 %1, %2
1916 define <2 x i1> @icmp_add20_sge_add57_splat(<2 x i32> %x, <2 x i32> %y) {
1917 ; CHECK-LABEL: @icmp_add20_sge_add57_splat(
1918 ; CHECK-NEXT: [[TMP1:%.*]] = add nsw <2 x i32> [[Y:%.*]], splat (i32 37)
1919 ; CHECK-NEXT: [[CMP:%.*]] = icmp sge <2 x i32> [[X:%.*]], [[TMP1]]
1920 ; CHECK-NEXT: ret <2 x i1> [[CMP]]
1922 %1 = add nsw <2 x i32> %x, <i32 20, i32 20>
1923 %2 = add nsw <2 x i32> %y, <i32 57, i32 57>
1924 %cmp = icmp sge <2 x i32> %1, %2
1928 define <2 x i1> @icmp_add20_sge_add57_poison(<2 x i32> %x, <2 x i32> %y) {
1929 ; CHECK-LABEL: @icmp_add20_sge_add57_poison(
1930 ; CHECK-NEXT: [[TMP1:%.*]] = add nsw <2 x i32> [[Y:%.*]], splat (i32 37)
1931 ; CHECK-NEXT: [[CMP:%.*]] = icmp sge <2 x i32> [[X:%.*]], [[TMP1]]
1932 ; CHECK-NEXT: ret <2 x i1> [[CMP]]
1934 %1 = add nsw <2 x i32> %x, <i32 20, i32 20>
1935 %2 = add nsw <2 x i32> %y, <i32 57, i32 poison>
1936 %cmp = icmp sge <2 x i32> %1, %2
1940 define <2 x i1> @icmp_add20_sge_add57_vec_nonsplat(<2 x i32> %x, <2 x i32> %y) {
1941 ; CHECK-LABEL: @icmp_add20_sge_add57_vec_nonsplat(
1942 ; CHECK-NEXT: [[TMP1:%.*]] = add nsw <2 x i32> [[X:%.*]], <i32 20, i32 19>
1943 ; CHECK-NEXT: [[TMP2:%.*]] = add nsw <2 x i32> [[Y:%.*]], <i32 57, i32 58>
1944 ; CHECK-NEXT: [[CMP:%.*]] = icmp sge <2 x i32> [[TMP1]], [[TMP2]]
1945 ; CHECK-NEXT: ret <2 x i1> [[CMP]]
1947 %1 = add nsw <2 x i32> %x, <i32 20, i32 19>
1948 %2 = add nsw <2 x i32> %y, <i32 57, i32 58>
1949 %cmp = icmp sge <2 x i32> %1, %2
1953 define i1 @icmp_sub57_sge_sub20(i32 %x, i32 %y) {
1954 ; CHECK-LABEL: @icmp_sub57_sge_sub20(
1955 ; CHECK-NEXT: [[TMP1:%.*]] = add nsw i32 [[X:%.*]], -37
1956 ; CHECK-NEXT: [[CMP:%.*]] = icmp sge i32 [[TMP1]], [[Y:%.*]]
1957 ; CHECK-NEXT: ret i1 [[CMP]]
1959 %1 = add nsw i32 %x, -57
1960 %2 = add nsw i32 %y, -20
1961 %cmp = icmp sge i32 %1, %2
1965 define <2 x i1> @icmp_sub57_sge_sub20_splat(<2 x i32> %x, <2 x i32> %y) {
1966 ; CHECK-LABEL: @icmp_sub57_sge_sub20_splat(
1967 ; CHECK-NEXT: [[TMP1:%.*]] = add nsw <2 x i32> [[X:%.*]], splat (i32 -37)
1968 ; CHECK-NEXT: [[CMP:%.*]] = icmp sge <2 x i32> [[TMP1]], [[Y:%.*]]
1969 ; CHECK-NEXT: ret <2 x i1> [[CMP]]
1971 %1 = add nsw <2 x i32> %x, <i32 -57, i32 -57>
1972 %2 = add nsw <2 x i32> %y, <i32 -20, i32 -20>
1973 %cmp = icmp sge <2 x i32> %1, %2
1977 define <2 x i1> @icmp_sub57_sge_sub20_vec_poison(<2 x i32> %x, <2 x i32> %y) {
1978 ; CHECK-LABEL: @icmp_sub57_sge_sub20_vec_poison(
1979 ; CHECK-NEXT: [[TMP1:%.*]] = add nsw <2 x i32> [[X:%.*]], splat (i32 -37)
1980 ; CHECK-NEXT: [[CMP:%.*]] = icmp sge <2 x i32> [[TMP1]], [[Y:%.*]]
1981 ; CHECK-NEXT: ret <2 x i1> [[CMP]]
1983 %1 = add nsw <2 x i32> %x, <i32 -57, i32 poison>
1984 %2 = add nsw <2 x i32> %y, <i32 -20, i32 poison>
1985 %cmp = icmp sge <2 x i32> %1, %2
1989 define <2 x i1> @icmp_sub57_sge_sub20_vec_nonsplat(<2 x i32> %x, <2 x i32> %y) {
1990 ; CHECK-LABEL: @icmp_sub57_sge_sub20_vec_nonsplat(
1991 ; CHECK-NEXT: [[TMP1:%.*]] = add nsw <2 x i32> [[X:%.*]], <i32 -57, i32 -58>
1992 ; CHECK-NEXT: [[TMP2:%.*]] = add nsw <2 x i32> [[Y:%.*]], <i32 -20, i32 -21>
1993 ; CHECK-NEXT: [[CMP:%.*]] = icmp sge <2 x i32> [[TMP1]], [[TMP2]]
1994 ; CHECK-NEXT: ret <2 x i1> [[CMP]]
1996 %1 = add nsw <2 x i32> %x, <i32 -57, i32 -58>
1997 %2 = add nsw <2 x i32> %y, <i32 -20, i32 -21>
1998 %cmp = icmp sge <2 x i32> %1, %2
2002 define i1 @icmp_and_shl_neg_ne_0(i32 %A, i32 %B) {
2003 ; CHECK-LABEL: @icmp_and_shl_neg_ne_0(
2004 ; CHECK-NEXT: [[SHL:%.*]] = shl nuw i32 1, [[B:%.*]]
2005 ; CHECK-NEXT: [[TMP1:%.*]] = and i32 [[SHL]], [[A:%.*]]
2006 ; CHECK-NEXT: [[CMP:%.*]] = icmp eq i32 [[TMP1]], 0
2007 ; CHECK-NEXT: ret i1 [[CMP]]
2009 %neg = xor i32 %A, -1
2010 %shl = shl i32 1, %B
2011 %and = and i32 %shl, %neg
2012 %cmp = icmp ne i32 %and, 0
2016 define i1 @icmp_and_shl_neg_ne_0_shl2_no_flags(i32 %A, i32 %B) {
2017 ; CHECK-LABEL: @icmp_and_shl_neg_ne_0_shl2_no_flags(
2018 ; CHECK-NEXT: [[NEG:%.*]] = xor i32 [[A:%.*]], -1
2019 ; CHECK-NEXT: [[SHL:%.*]] = shl i32 2, [[B:%.*]]
2020 ; CHECK-NEXT: [[AND:%.*]] = and i32 [[SHL]], [[NEG]]
2021 ; CHECK-NEXT: [[CMP:%.*]] = icmp ne i32 [[AND]], 0
2022 ; CHECK-NEXT: ret i1 [[CMP]]
2024 %neg = xor i32 %A, -1
2025 %shl = shl i32 2, %B
2026 %and = and i32 %shl, %neg
2027 %cmp = icmp ne i32 %and, 0
2031 define i1 @icmp_and_shl_neg_ne_0_shl2_nuw(i32 %A, i32 %B) {
2032 ; CHECK-LABEL: @icmp_and_shl_neg_ne_0_shl2_nuw(
2033 ; CHECK-NEXT: [[SHL:%.*]] = shl nuw i32 2, [[B:%.*]]
2034 ; CHECK-NEXT: [[TMP1:%.*]] = and i32 [[SHL]], [[A:%.*]]
2035 ; CHECK-NEXT: [[CMP:%.*]] = icmp eq i32 [[TMP1]], 0
2036 ; CHECK-NEXT: ret i1 [[CMP]]
2038 %neg = xor i32 %A, -1
2039 %shl = shl nuw i32 2, %B
2040 %and = and i32 %shl, %neg
2041 %cmp = icmp ne i32 %and, 0
2045 define i1 @icmp_and_shl_neg_ne_0_shl2_nsw(i32 %A, i32 %B) {
2046 ; CHECK-LABEL: @icmp_and_shl_neg_ne_0_shl2_nsw(
2047 ; CHECK-NEXT: [[SHL:%.*]] = shl nsw i32 2, [[B:%.*]]
2048 ; CHECK-NEXT: [[TMP1:%.*]] = and i32 [[SHL]], [[A:%.*]]
2049 ; CHECK-NEXT: [[CMP:%.*]] = icmp eq i32 [[TMP1]], 0
2050 ; CHECK-NEXT: ret i1 [[CMP]]
2052 %neg = xor i32 %A, -1
2053 %shl = shl nsw i32 2, %B
2054 %and = and i32 %shl, %neg
2055 %cmp = icmp ne i32 %and, 0
2059 define i1 @icmp_and_shl_neg_eq_0(i32 %A, i32 %B) {
2060 ; CHECK-LABEL: @icmp_and_shl_neg_eq_0(
2061 ; CHECK-NEXT: [[SHL:%.*]] = shl nuw i32 1, [[B:%.*]]
2062 ; CHECK-NEXT: [[TMP1:%.*]] = and i32 [[SHL]], [[A:%.*]]
2063 ; CHECK-NEXT: [[CMP:%.*]] = icmp ne i32 [[TMP1]], 0
2064 ; CHECK-NEXT: ret i1 [[CMP]]
2066 %neg = xor i32 %A, -1
2067 %shl = shl i32 1, %B
2068 %and = and i32 %shl, %neg
2069 %cmp = icmp eq i32 %and, 0
2073 define i1 @icmp_add_and_shr_ne_0(i32 %X) {
2074 ; CHECK-LABEL: @icmp_add_and_shr_ne_0(
2075 ; CHECK-NEXT: [[TMP1:%.*]] = and i32 [[X:%.*]], 240
2076 ; CHECK-NEXT: [[TOBOOL:%.*]] = icmp ne i32 [[TMP1]], 224
2077 ; CHECK-NEXT: ret i1 [[TOBOOL]]
2079 %shr = lshr i32 %X, 4
2080 %and = and i32 %shr, 15
2081 %add = add i32 %and, -14
2082 %tobool = icmp ne i32 %add, 0
2086 define <2 x i1> @icmp_add_and_shr_ne_0_vec(<2 x i32> %X) {
2087 ; CHECK-LABEL: @icmp_add_and_shr_ne_0_vec(
2088 ; CHECK-NEXT: [[TMP1:%.*]] = and <2 x i32> [[X:%.*]], splat (i32 240)
2089 ; CHECK-NEXT: [[TOBOOL:%.*]] = icmp ne <2 x i32> [[TMP1]], splat (i32 224)
2090 ; CHECK-NEXT: ret <2 x i1> [[TOBOOL]]
2092 %shr = lshr <2 x i32> %X, <i32 4, i32 4>
2093 %and = and <2 x i32> %shr, <i32 15, i32 15>
2094 %add = add <2 x i32> %and, <i32 -14, i32 -14>
2095 %tobool = icmp ne <2 x i32> %add, zeroinitializer
2096 ret <2 x i1> %tobool
2099 ; Variation of the above with an extra use of the shift
2100 define i1 @icmp_and_shr_multiuse(i32 %X) {
2101 ; CHECK-LABEL: @icmp_and_shr_multiuse(
2102 ; CHECK-NEXT: [[TMP1:%.*]] = and i32 [[X:%.*]], 240
2103 ; CHECK-NEXT: [[TOBOOL:%.*]] = icmp ne i32 [[TMP1]], 224
2104 ; CHECK-NEXT: [[TMP2:%.*]] = and i32 [[X]], 496
2105 ; CHECK-NEXT: [[TOBOOL2:%.*]] = icmp ne i32 [[TMP2]], 432
2106 ; CHECK-NEXT: [[AND3:%.*]] = and i1 [[TOBOOL]], [[TOBOOL2]]
2107 ; CHECK-NEXT: ret i1 [[AND3]]
2109 %shr = lshr i32 %X, 4
2110 %and = and i32 %shr, 15
2111 %and2 = and i32 %shr, 31 ; second use of the shift
2112 %tobool = icmp ne i32 %and, 14
2113 %tobool2 = icmp ne i32 %and2, 27
2114 %and3 = and i1 %tobool, %tobool2
2118 define i1 @icmp_and_shr_multiuse_logical(i32 %X) {
2119 ; CHECK-LABEL: @icmp_and_shr_multiuse_logical(
2120 ; CHECK-NEXT: [[TMP1:%.*]] = and i32 [[X:%.*]], 240
2121 ; CHECK-NEXT: [[TOBOOL:%.*]] = icmp ne i32 [[TMP1]], 224
2122 ; CHECK-NEXT: [[TMP2:%.*]] = and i32 [[X]], 496
2123 ; CHECK-NEXT: [[TOBOOL2:%.*]] = icmp ne i32 [[TMP2]], 432
2124 ; CHECK-NEXT: [[AND3:%.*]] = and i1 [[TOBOOL]], [[TOBOOL2]]
2125 ; CHECK-NEXT: ret i1 [[AND3]]
2127 %shr = lshr i32 %X, 4
2128 %and = and i32 %shr, 15
2129 %and2 = and i32 %shr, 31 ; second use of the shift
2130 %tobool = icmp ne i32 %and, 14
2131 %tobool2 = icmp ne i32 %and2, 27
2132 %and3 = select i1 %tobool, i1 %tobool2, i1 false
2136 ; Variation of the above with an ashr
2137 define i1 @icmp_and_ashr_multiuse(i32 %X) {
2138 ; CHECK-LABEL: @icmp_and_ashr_multiuse(
2139 ; CHECK-NEXT: [[TMP1:%.*]] = and i32 [[X:%.*]], 240
2140 ; CHECK-NEXT: [[TOBOOL:%.*]] = icmp ne i32 [[TMP1]], 224
2141 ; CHECK-NEXT: [[TMP2:%.*]] = and i32 [[X]], 496
2142 ; CHECK-NEXT: [[TOBOOL2:%.*]] = icmp ne i32 [[TMP2]], 432
2143 ; CHECK-NEXT: [[AND3:%.*]] = and i1 [[TOBOOL]], [[TOBOOL2]]
2144 ; CHECK-NEXT: ret i1 [[AND3]]
2146 %shr = ashr i32 %X, 4
2147 %and = and i32 %shr, 15
2148 %and2 = and i32 %shr, 31 ; second use of the shift
2149 %tobool = icmp ne i32 %and, 14
2150 %tobool2 = icmp ne i32 %and2, 27
2151 %and3 = and i1 %tobool, %tobool2
2155 define i1 @icmp_and_ashr_multiuse_logical(i32 %X) {
2156 ; CHECK-LABEL: @icmp_and_ashr_multiuse_logical(
2157 ; CHECK-NEXT: [[TMP1:%.*]] = and i32 [[X:%.*]], 240
2158 ; CHECK-NEXT: [[TOBOOL:%.*]] = icmp ne i32 [[TMP1]], 224
2159 ; CHECK-NEXT: [[TMP2:%.*]] = and i32 [[X]], 496
2160 ; CHECK-NEXT: [[TOBOOL2:%.*]] = icmp ne i32 [[TMP2]], 432
2161 ; CHECK-NEXT: [[AND3:%.*]] = and i1 [[TOBOOL]], [[TOBOOL2]]
2162 ; CHECK-NEXT: ret i1 [[AND3]]
2164 %shr = ashr i32 %X, 4
2165 %and = and i32 %shr, 15
2166 %and2 = and i32 %shr, 31 ; second use of the shift
2167 %tobool = icmp ne i32 %and, 14
2168 %tobool2 = icmp ne i32 %and2, 27
2169 %and3 = select i1 %tobool, i1 %tobool2, i1 false
2173 define i1 @icmp_lshr_and_overshift(i8 %X) {
2174 ; CHECK-LABEL: @icmp_lshr_and_overshift(
2175 ; CHECK-NEXT: [[TOBOOL:%.*]] = icmp ugt i8 [[X:%.*]], 31
2176 ; CHECK-NEXT: ret i1 [[TOBOOL]]
2178 %shr = lshr i8 %X, 5
2179 %and = and i8 %shr, 15
2180 %tobool = icmp ne i8 %and, 0
2184 ; We shouldn't simplify this because the and uses bits that are shifted in.
2185 define i1 @icmp_ashr_and_overshift(i8 %X) {
2186 ; CHECK-LABEL: @icmp_ashr_and_overshift(
2187 ; CHECK-NEXT: [[SHR:%.*]] = ashr i8 [[X:%.*]], 5
2188 ; CHECK-NEXT: [[AND:%.*]] = and i8 [[SHR]], 15
2189 ; CHECK-NEXT: [[TOBOOL:%.*]] = icmp ne i8 [[AND]], 0
2190 ; CHECK-NEXT: ret i1 [[TOBOOL]]
2192 %shr = ashr i8 %X, 5
2193 %and = and i8 %shr, 15
2194 %tobool = icmp ne i8 %and, 0
2198 define i1 @icmp_and_ashr_neg_and_legal(i8 %x) {
2199 ; CHECK-LABEL: @icmp_and_ashr_neg_and_legal(
2200 ; CHECK-NEXT: [[CMP:%.*]] = icmp slt i8 [[X:%.*]], 32
2201 ; CHECK-NEXT: ret i1 [[CMP]]
2203 %ashr = ashr i8 %x, 4
2204 %and = and i8 %ashr, -2
2205 %cmp = icmp slt i8 %and, 1
2210 define i1 @icmp_and_ashr_mixed_and_shiftout(i8 %x) {
2211 ; CHECK-LABEL: @icmp_and_ashr_mixed_and_shiftout(
2212 ; CHECK-NEXT: [[ASHR:%.*]] = ashr i8 [[X:%.*]], 4
2213 ; CHECK-NEXT: [[AND:%.*]] = and i8 [[ASHR]], 31
2214 ; CHECK-NEXT: [[CMP:%.*]] = icmp samesign ugt i8 [[AND]], 8
2215 ; CHECK-NEXT: ret i1 [[CMP]]
2217 %ashr = ashr i8 %x, 4
2218 %and = and i8 %ashr, 31
2219 %cmp = icmp ugt i8 %and, 8
2223 define i1 @icmp_and_ashr_neg_cmp_slt_legal(i8 %x) {
2224 ; CHECK-LABEL: @icmp_and_ashr_neg_cmp_slt_legal(
2225 ; CHECK-NEXT: [[TMP1:%.*]] = and i8 [[X:%.*]], -32
2226 ; CHECK-NEXT: [[CMP:%.*]] = icmp slt i8 [[TMP1]], -64
2227 ; CHECK-NEXT: ret i1 [[CMP]]
2229 %ashr = ashr i8 %x, 4
2230 %and = and i8 %ashr, -2
2231 %cmp = icmp slt i8 %and, -4
2236 define i1 @icmp_and_ashr_neg_cmp_slt_shiftout(i8 %x) {
2237 ; CHECK-LABEL: @icmp_and_ashr_neg_cmp_slt_shiftout(
2238 ; CHECK-NEXT: [[ASHR:%.*]] = ashr i8 [[X:%.*]], 4
2239 ; CHECK-NEXT: [[AND:%.*]] = and i8 [[ASHR]], -2
2240 ; CHECK-NEXT: [[CMP:%.*]] = icmp slt i8 [[AND]], -68
2241 ; CHECK-NEXT: ret i1 [[CMP]]
2243 %ashr = ashr i8 %x, 4
2244 %and = and i8 %ashr, -2
2245 %cmp = icmp slt i8 %and, -68
2249 define i1 @icmp_and_ashr_neg_cmp_eq_legal(i8 %x) {
2250 ; CHECK-LABEL: @icmp_and_ashr_neg_cmp_eq_legal(
2251 ; CHECK-NEXT: [[TMP1:%.*]] = and i8 [[X:%.*]], -32
2252 ; CHECK-NEXT: [[CMP:%.*]] = icmp eq i8 [[TMP1]], -64
2253 ; CHECK-NEXT: ret i1 [[CMP]]
2255 %ashr = ashr i8 %x, 4
2256 %and = and i8 %ashr, -2
2257 %cmp = icmp eq i8 %and, -4
2261 define i1 @icmp_and_ashr_neg_cmp_eq_shiftout(i8 %x) {
2262 ; CHECK-LABEL: @icmp_and_ashr_neg_cmp_eq_shiftout(
2263 ; CHECK-NEXT: ret i1 false
2265 %ashr = ashr i8 %x, 4
2266 %and = and i8 %ashr, -2
2267 %cmp = icmp eq i8 %and, -68
2271 define i1 @icmp_and_ashr_neg_cmp_ne_shiftout(i8 %x) {
2272 ; CHECK-LABEL: @icmp_and_ashr_neg_cmp_ne_shiftout(
2273 ; CHECK-NEXT: ret i1 true
2275 %ashr = ashr i8 %x, 4
2276 %and = and i8 %ashr, -2
2277 %cmp = icmp ne i8 %and, -68
2281 define i1 @icmp_shl_1_V_ult_32(i32 %V) {
2282 ; CHECK-LABEL: @icmp_shl_1_V_ult_32(
2283 ; CHECK-NEXT: [[CMP:%.*]] = icmp ult i32 [[V:%.*]], 5
2284 ; CHECK-NEXT: ret i1 [[CMP]]
2286 %shl = shl i32 1, %V
2287 %cmp = icmp ult i32 %shl, 32
2291 define <2 x i1> @icmp_shl_1_V_ult_32_vec(<2 x i32> %V) {
2292 ; CHECK-LABEL: @icmp_shl_1_V_ult_32_vec(
2293 ; CHECK-NEXT: [[CMP:%.*]] = icmp ult <2 x i32> [[V:%.*]], splat (i32 5)
2294 ; CHECK-NEXT: ret <2 x i1> [[CMP]]
2296 %shl = shl <2 x i32> <i32 1, i32 1>, %V
2297 %cmp = icmp ult <2 x i32> %shl, <i32 32, i32 32>
2301 define i1 @icmp_shl_1_V_eq_32(i32 %V) {
2302 ; CHECK-LABEL: @icmp_shl_1_V_eq_32(
2303 ; CHECK-NEXT: [[CMP:%.*]] = icmp eq i32 [[V:%.*]], 5
2304 ; CHECK-NEXT: ret i1 [[CMP]]
2306 %shl = shl i32 1, %V
2307 %cmp = icmp eq i32 %shl, 32
2311 define <2 x i1> @icmp_shl_1_V_eq_32_vec(<2 x i32> %V) {
2312 ; CHECK-LABEL: @icmp_shl_1_V_eq_32_vec(
2313 ; CHECK-NEXT: [[CMP:%.*]] = icmp eq <2 x i32> [[V:%.*]], splat (i32 5)
2314 ; CHECK-NEXT: ret <2 x i1> [[CMP]]
2316 %shl = shl <2 x i32> <i32 1, i32 1>, %V
2317 %cmp = icmp eq <2 x i32> %shl, <i32 32, i32 32>
2321 define i1 @icmp_shl_1_V_ult_30(i32 %V) {
2322 ; CHECK-LABEL: @icmp_shl_1_V_ult_30(
2323 ; CHECK-NEXT: [[CMP:%.*]] = icmp ult i32 [[V:%.*]], 5
2324 ; CHECK-NEXT: ret i1 [[CMP]]
2326 %shl = shl i32 1, %V
2327 %cmp = icmp ult i32 %shl, 30
2331 define <2 x i1> @icmp_shl_1_V_ult_30_vec(<2 x i32> %V) {
2332 ; CHECK-LABEL: @icmp_shl_1_V_ult_30_vec(
2333 ; CHECK-NEXT: [[CMP:%.*]] = icmp ult <2 x i32> [[V:%.*]], splat (i32 5)
2334 ; CHECK-NEXT: ret <2 x i1> [[CMP]]
2336 %shl = shl <2 x i32> <i32 1, i32 1>, %V
2337 %cmp = icmp ult <2 x i32> %shl, <i32 30, i32 30>
2341 define i1 @icmp_shl_1_V_ugt_30(i32 %V) {
2342 ; CHECK-LABEL: @icmp_shl_1_V_ugt_30(
2343 ; CHECK-NEXT: [[CMP:%.*]] = icmp ugt i32 [[V:%.*]], 4
2344 ; CHECK-NEXT: ret i1 [[CMP]]
2346 %shl = shl i32 1, %V
2347 %cmp = icmp ugt i32 %shl, 30
2351 define <2 x i1> @icmp_shl_1_V_ugt_30_vec(<2 x i32> %V) {
2352 ; CHECK-LABEL: @icmp_shl_1_V_ugt_30_vec(
2353 ; CHECK-NEXT: [[CMP:%.*]] = icmp ugt <2 x i32> [[V:%.*]], splat (i32 4)
2354 ; CHECK-NEXT: ret <2 x i1> [[CMP]]
2356 %shl = shl <2 x i32> <i32 1, i32 1>, %V
2357 %cmp = icmp ugt <2 x i32> %shl, <i32 30, i32 30>
2361 define i1 @icmp_shl_1_V_ule_30(i32 %V) {
2362 ; CHECK-LABEL: @icmp_shl_1_V_ule_30(
2363 ; CHECK-NEXT: [[CMP:%.*]] = icmp ult i32 [[V:%.*]], 5
2364 ; CHECK-NEXT: ret i1 [[CMP]]
2366 %shl = shl i32 1, %V
2367 %cmp = icmp ule i32 %shl, 30
2371 define <2 x i1> @icmp_shl_1_V_ule_30_vec(<2 x i32> %V) {
2372 ; CHECK-LABEL: @icmp_shl_1_V_ule_30_vec(
2373 ; CHECK-NEXT: [[CMP:%.*]] = icmp ult <2 x i32> [[V:%.*]], splat (i32 5)
2374 ; CHECK-NEXT: ret <2 x i1> [[CMP]]
2376 %shl = shl <2 x i32> <i32 1, i32 1>, %V
2377 %cmp = icmp ule <2 x i32> %shl, <i32 30, i32 30>
2381 define i1 @icmp_shl_1_V_uge_30(i32 %V) {
2382 ; CHECK-LABEL: @icmp_shl_1_V_uge_30(
2383 ; CHECK-NEXT: [[CMP:%.*]] = icmp ugt i32 [[V:%.*]], 4
2384 ; CHECK-NEXT: ret i1 [[CMP]]
2386 %shl = shl i32 1, %V
2387 %cmp = icmp uge i32 %shl, 30
2391 define <2 x i1> @icmp_shl_1_V_uge_30_vec(<2 x i32> %V) {
2392 ; CHECK-LABEL: @icmp_shl_1_V_uge_30_vec(
2393 ; CHECK-NEXT: [[CMP:%.*]] = icmp ugt <2 x i32> [[V:%.*]], splat (i32 4)
2394 ; CHECK-NEXT: ret <2 x i1> [[CMP]]
2396 %shl = shl <2 x i32> <i32 1, i32 1>, %V
2397 %cmp = icmp uge <2 x i32> %shl, <i32 30, i32 30>
2401 define i1 @icmp_shl_1_V_uge_2147483648(i32 %V) {
2402 ; CHECK-LABEL: @icmp_shl_1_V_uge_2147483648(
2403 ; CHECK-NEXT: [[CMP:%.*]] = icmp eq i32 [[V:%.*]], 31
2404 ; CHECK-NEXT: ret i1 [[CMP]]
2406 %shl = shl i32 1, %V
2407 %cmp = icmp uge i32 %shl, 2147483648
2411 define <2 x i1> @icmp_shl_1_V_uge_2147483648_vec(<2 x i32> %V) {
2412 ; CHECK-LABEL: @icmp_shl_1_V_uge_2147483648_vec(
2413 ; CHECK-NEXT: [[CMP:%.*]] = icmp eq <2 x i32> [[V:%.*]], splat (i32 31)
2414 ; CHECK-NEXT: ret <2 x i1> [[CMP]]
2416 %shl = shl <2 x i32> <i32 1, i32 1>, %V
2417 %cmp = icmp uge <2 x i32> %shl, <i32 2147483648, i32 2147483648>
2421 define i1 @icmp_shl_1_V_ult_2147483648(i32 %V) {
2422 ; CHECK-LABEL: @icmp_shl_1_V_ult_2147483648(
2423 ; CHECK-NEXT: [[CMP:%.*]] = icmp ne i32 [[V:%.*]], 31
2424 ; CHECK-NEXT: ret i1 [[CMP]]
2426 %shl = shl i32 1, %V
2427 %cmp = icmp ult i32 %shl, 2147483648
2431 define <2 x i1> @icmp_shl_1_V_ult_2147483648_vec(<2 x i32> %V) {
2432 ; CHECK-LABEL: @icmp_shl_1_V_ult_2147483648_vec(
2433 ; CHECK-NEXT: [[CMP:%.*]] = icmp ne <2 x i32> [[V:%.*]], splat (i32 31)
2434 ; CHECK-NEXT: ret <2 x i1> [[CMP]]
2436 %shl = shl <2 x i32> <i32 1, i32 1>, %V
2437 %cmp = icmp ult <2 x i32> %shl, <i32 2147483648, i32 2147483648>
2441 define i1 @icmp_shl_1_V_sle_0(i32 %V) {
2442 ; CHECK-LABEL: @icmp_shl_1_V_sle_0(
2443 ; CHECK-NEXT: [[CMP:%.*]] = icmp eq i32 [[V:%.*]], 31
2444 ; CHECK-NEXT: ret i1 [[CMP]]
2446 %shl = shl i32 1, %V
2447 %cmp = icmp sle i32 %shl, 0
2451 define <2 x i1> @icmp_shl_1_V_sle_0_vec(<2 x i32> %V) {
2452 ; CHECK-LABEL: @icmp_shl_1_V_sle_0_vec(
2453 ; CHECK-NEXT: [[CMP:%.*]] = icmp eq <2 x i32> [[V:%.*]], splat (i32 31)
2454 ; CHECK-NEXT: ret <2 x i1> [[CMP]]
2456 %shl = shl <2 x i32> <i32 1, i32 1>, %V
2457 %cmp = icmp sle <2 x i32> %shl, <i32 0, i32 0>
2461 define i1 @icmp_shl_1_V_sle_negative(i32 %V) {
2462 ; CHECK-LABEL: @icmp_shl_1_V_sle_negative(
2463 ; CHECK-NEXT: [[CMP:%.*]] = icmp eq i32 [[V:%.*]], 31
2464 ; CHECK-NEXT: ret i1 [[CMP]]
2466 %shl = shl i32 1, %V
2467 %cmp = icmp sle i32 %shl, -42
2471 define <2 x i1> @icmp_shl_1_V_sle_0_negative(<2 x i32> %V) {
2472 ; CHECK-LABEL: @icmp_shl_1_V_sle_0_negative(
2473 ; CHECK-NEXT: [[CMP:%.*]] = icmp eq <2 x i32> [[V:%.*]], splat (i32 31)
2474 ; CHECK-NEXT: ret <2 x i1> [[CMP]]
2476 %shl = shl <2 x i32> <i32 1, i32 1>, %V
2477 %cmp = icmp sle <2 x i32> %shl, <i32 -2147483647, i32 -2147483647>
2481 define i1 @icmp_shl_1_V_sgt_0(i32 %V) {
2482 ; CHECK-LABEL: @icmp_shl_1_V_sgt_0(
2483 ; CHECK-NEXT: [[CMP:%.*]] = icmp ne i32 [[V:%.*]], 31
2484 ; CHECK-NEXT: ret i1 [[CMP]]
2486 %shl = shl i32 1, %V
2487 %cmp = icmp sgt i32 %shl, 0
2491 define <2 x i1> @icmp_shl_1_V_sgt_0_vec(<2 x i32> %V) {
2492 ; CHECK-LABEL: @icmp_shl_1_V_sgt_0_vec(
2493 ; CHECK-NEXT: [[CMP:%.*]] = icmp ne <2 x i32> [[V:%.*]], splat (i32 31)
2494 ; CHECK-NEXT: ret <2 x i1> [[CMP]]
2496 %shl = shl <2 x i32> <i32 1, i32 1>, %V
2497 %cmp = icmp sgt <2 x i32> %shl, <i32 0, i32 0>
2501 define i1 @icmp_shl_1_V_sgt_negative(i32 %V) {
2502 ; CHECK-LABEL: @icmp_shl_1_V_sgt_negative(
2503 ; CHECK-NEXT: [[CMP:%.*]] = icmp ne i32 [[V:%.*]], 31
2504 ; CHECK-NEXT: ret i1 [[CMP]]
2506 %shl = shl i32 1, %V
2507 %cmp = icmp sgt i32 %shl, -12345
2511 define <2 x i1> @icmp_shl_1_V_sgt_negative_vec(<2 x i32> %V) {
2512 ; CHECK-LABEL: @icmp_shl_1_V_sgt_negative_vec(
2513 ; CHECK-NEXT: [[CMP:%.*]] = icmp ne <2 x i32> [[V:%.*]], splat (i32 31)
2514 ; CHECK-NEXT: ret <2 x i1> [[CMP]]
2516 %shl = shl <2 x i32> <i32 1, i32 1>, %V
2517 %cmp = icmp sgt <2 x i32> %shl, <i32 -2, i32 -2>
2521 define i1 @or_icmp_eq_B_0_icmp_ult_A_B(i64 %a, i64 %b) {
2522 ; CHECK-LABEL: @or_icmp_eq_B_0_icmp_ult_A_B(
2523 ; CHECK-NEXT: [[TMP1:%.*]] = add i64 [[B:%.*]], -1
2524 ; CHECK-NEXT: [[TMP2:%.*]] = icmp uge i64 [[TMP1]], [[A:%.*]]
2525 ; CHECK-NEXT: ret i1 [[TMP2]]
2527 %1 = icmp eq i64 %b, 0
2528 %2 = icmp ult i64 %a, %b
2533 define i1 @or_icmp_eq_B_0_icmp_ult_A_B_logical(i64 %a, i64 %b) {
2534 ; CHECK-LABEL: @or_icmp_eq_B_0_icmp_ult_A_B_logical(
2535 ; CHECK-NEXT: [[TMP1:%.*]] = freeze i64 [[A:%.*]]
2536 ; CHECK-NEXT: [[TMP2:%.*]] = add i64 [[B:%.*]], -1
2537 ; CHECK-NEXT: [[TMP3:%.*]] = icmp uge i64 [[TMP2]], [[TMP1]]
2538 ; CHECK-NEXT: ret i1 [[TMP3]]
2540 %1 = icmp eq i64 %b, 0
2541 %2 = icmp ult i64 %a, %b
2542 %3 = select i1 %1, i1 true, i1 %2
2546 define <2 x i1> @or_icmp_eq_B_0_icmp_ult_A_B_uniform(<2 x i64> %a, <2 x i64> %b) {
2547 ; CHECK-LABEL: @or_icmp_eq_B_0_icmp_ult_A_B_uniform(
2548 ; CHECK-NEXT: [[TMP1:%.*]] = add <2 x i64> [[B:%.*]], splat (i64 -1)
2549 ; CHECK-NEXT: [[TMP2:%.*]] = icmp uge <2 x i64> [[TMP1]], [[A:%.*]]
2550 ; CHECK-NEXT: ret <2 x i1> [[TMP2]]
2552 %1 = icmp eq <2 x i64> %b, zeroinitializer
2553 %2 = icmp ult <2 x i64> %a, %b
2554 %3 = or <2 x i1> %1, %2
2558 define <2 x i1> @or_icmp_eq_B_0_icmp_ult_A_B_poison(<2 x i64> %a, <2 x i64> %b) {
2559 ; CHECK-LABEL: @or_icmp_eq_B_0_icmp_ult_A_B_poison(
2560 ; CHECK-NEXT: [[TMP1:%.*]] = add <2 x i64> [[B:%.*]], splat (i64 -1)
2561 ; CHECK-NEXT: [[TMP2:%.*]] = icmp uge <2 x i64> [[TMP1]], [[A:%.*]]
2562 ; CHECK-NEXT: ret <2 x i1> [[TMP2]]
2564 %1 = icmp eq <2 x i64> %b, <i64 0, i64 poison>
2565 %2 = icmp ult <2 x i64> %a, %b
2566 %3 = or <2 x i1> %1, %2
2570 define i1 @or_icmp_ne_A_0_icmp_ne_B_0(i64 %a, i64 %b) {
2571 ; CHECK-LABEL: @or_icmp_ne_A_0_icmp_ne_B_0(
2572 ; CHECK-NEXT: [[TMP1:%.*]] = or i64 [[A:%.*]], [[B:%.*]]
2573 ; CHECK-NEXT: [[TMP2:%.*]] = icmp ne i64 [[TMP1]], 0
2574 ; CHECK-NEXT: ret i1 [[TMP2]]
2576 %1 = icmp ne i64 %a, 0
2577 %2 = icmp ne i64 %b, 0
2582 define i1 @or_icmp_ne_A_0_icmp_ne_B_0_logical(i64 %a, i64 %b) {
2583 ; CHECK-LABEL: @or_icmp_ne_A_0_icmp_ne_B_0_logical(
2584 ; CHECK-NEXT: [[TMP1:%.*]] = icmp ne i64 [[A:%.*]], 0
2585 ; CHECK-NEXT: [[TMP2:%.*]] = icmp ne i64 [[B:%.*]], 0
2586 ; CHECK-NEXT: [[TMP3:%.*]] = select i1 [[TMP1]], i1 true, i1 [[TMP2]]
2587 ; CHECK-NEXT: ret i1 [[TMP3]]
2589 %1 = icmp ne i64 %a, 0
2590 %2 = icmp ne i64 %b, 0
2591 %3 = select i1 %1, i1 true, i1 %2
2595 define <2 x i1> @or_icmp_ne_A_0_icmp_ne_B_0_uniform(<2 x i64> %a, <2 x i64> %b) {
2596 ; CHECK-LABEL: @or_icmp_ne_A_0_icmp_ne_B_0_uniform(
2597 ; CHECK-NEXT: [[TMP1:%.*]] = or <2 x i64> [[A:%.*]], [[B:%.*]]
2598 ; CHECK-NEXT: [[TMP2:%.*]] = icmp ne <2 x i64> [[TMP1]], zeroinitializer
2599 ; CHECK-NEXT: ret <2 x i1> [[TMP2]]
2601 %1 = icmp ne <2 x i64> %a, zeroinitializer
2602 %2 = icmp ne <2 x i64> %b, zeroinitializer
2603 %3 = or <2 x i1> %1, %2
2607 define <2 x i1> @or_icmp_ne_A_0_icmp_ne_B_0_poison(<2 x i64> %a, <2 x i64> %b) {
2608 ; CHECK-LABEL: @or_icmp_ne_A_0_icmp_ne_B_0_poison(
2609 ; CHECK-NEXT: [[TMP1:%.*]] = or <2 x i64> [[A:%.*]], [[B:%.*]]
2610 ; CHECK-NEXT: [[TMP2:%.*]] = icmp ne <2 x i64> [[TMP1]], zeroinitializer
2611 ; CHECK-NEXT: ret <2 x i1> [[TMP2]]
2613 %1 = icmp ne <2 x i64> %a, <i64 0, i64 poison>
2614 %2 = icmp ne <2 x i64> %b, <i64 0, i64 poison>
2615 %3 = or <2 x i1> %1, %2
2619 define i1 @and_icmp_ne_B_0_icmp_uge_A_B(i64 %a, i64 %b) {
2620 ; CHECK-LABEL: @and_icmp_ne_B_0_icmp_uge_A_B(
2621 ; CHECK-NEXT: [[TMP1:%.*]] = add i64 [[B:%.*]], -1
2622 ; CHECK-NEXT: [[TMP2:%.*]] = icmp ult i64 [[TMP1]], [[A:%.*]]
2623 ; CHECK-NEXT: ret i1 [[TMP2]]
2625 %1 = icmp ne i64 %b, 0
2626 %2 = icmp uge i64 %a, %b
2631 define i1 @and_icmp_ne_B_0_icmp_uge_A_B_commuted1(i64 %a, i64 %b) {
2632 ; CHECK-LABEL: @and_icmp_ne_B_0_icmp_uge_A_B_commuted1(
2633 ; CHECK-NEXT: [[TMP1:%.*]] = add i64 [[B:%.*]], -1
2634 ; CHECK-NEXT: [[TMP2:%.*]] = icmp ult i64 [[TMP1]], [[A:%.*]]
2635 ; CHECK-NEXT: ret i1 [[TMP2]]
2637 %1 = icmp uge i64 %a, %b
2638 %2 = icmp ne i64 %b, 0
2643 define i1 @and_icmp_ne_B_0_icmp_uge_A_B_commuted2(i64 %a, i64 %b) {
2644 ; CHECK-LABEL: @and_icmp_ne_B_0_icmp_uge_A_B_commuted2(
2645 ; CHECK-NEXT: [[TMP1:%.*]] = add i64 [[B:%.*]], -1
2646 ; CHECK-NEXT: [[TMP2:%.*]] = icmp ult i64 [[TMP1]], [[A:%.*]]
2647 ; CHECK-NEXT: ret i1 [[TMP2]]
2649 %1 = icmp ne i64 %b, 0
2650 %2 = icmp ule i64 %b, %a
2655 define i1 @and_icmp_ne_B_0_icmp_uge_A_B_commuted1_logical(i64 %a, i64 %b) {
2656 ; CHECK-LABEL: @and_icmp_ne_B_0_icmp_uge_A_B_commuted1_logical(
2657 ; CHECK-NEXT: [[TMP1:%.*]] = add i64 [[B:%.*]], -1
2658 ; CHECK-NEXT: [[TMP2:%.*]] = icmp ult i64 [[TMP1]], [[A:%.*]]
2659 ; CHECK-NEXT: ret i1 [[TMP2]]
2661 %1 = icmp uge i64 %a, %b
2662 %2 = icmp ne i64 %b, 0
2663 %3 = select i1 %1, i1 %2, i1 false
2667 define i1 @and_icmp_ne_B_0_icmp_uge_A_B_commuted2_logical(i64 %a, i64 %b) {
2668 ; CHECK-LABEL: @and_icmp_ne_B_0_icmp_uge_A_B_commuted2_logical(
2669 ; CHECK-NEXT: [[TMP1:%.*]] = freeze i64 [[A:%.*]]
2670 ; CHECK-NEXT: [[TMP2:%.*]] = add i64 [[B:%.*]], -1
2671 ; CHECK-NEXT: [[TMP3:%.*]] = icmp ult i64 [[TMP2]], [[TMP1]]
2672 ; CHECK-NEXT: ret i1 [[TMP3]]
2674 %1 = icmp ne i64 %b, 0
2675 %2 = icmp ule i64 %b, %a
2676 %3 = select i1 %1, i1 %2, i1 false
2680 define i1 @and_icmp_ne_B_0_icmp_uge_A_B_extra_use1(i64 %a, i64 %b) {
2681 ; CHECK-LABEL: @and_icmp_ne_B_0_icmp_uge_A_B_extra_use1(
2682 ; CHECK-NEXT: [[TMP1:%.*]] = icmp ne i64 [[B:%.*]], 0
2683 ; CHECK-NEXT: call void @use_i1(i1 [[TMP1]])
2684 ; CHECK-NEXT: [[TMP2:%.*]] = add i64 [[B]], -1
2685 ; CHECK-NEXT: [[TMP3:%.*]] = icmp ult i64 [[TMP2]], [[A:%.*]]
2686 ; CHECK-NEXT: ret i1 [[TMP3]]
2688 %1 = icmp ne i64 %b, 0
2689 call void @use_i1(i1 %1)
2690 %2 = icmp uge i64 %a, %b
2695 define i1 @and_icmp_ne_B_0_icmp_uge_A_B_extra_use2(i64 %a, i64 %b) {
2696 ; CHECK-LABEL: @and_icmp_ne_B_0_icmp_uge_A_B_extra_use2(
2697 ; CHECK-NEXT: [[TMP1:%.*]] = icmp uge i64 [[A:%.*]], [[B:%.*]]
2698 ; CHECK-NEXT: call void @use_i1(i1 [[TMP1]])
2699 ; CHECK-NEXT: [[TMP2:%.*]] = add i64 [[B]], -1
2700 ; CHECK-NEXT: [[TMP3:%.*]] = icmp ult i64 [[TMP2]], [[A]]
2701 ; CHECK-NEXT: ret i1 [[TMP3]]
2703 %1 = icmp ne i64 %b, 0
2704 %2 = icmp uge i64 %a, %b
2705 call void @use_i1(i1 %2)
2710 define i1 @and_icmp_ne_B_0_icmp_uge_A_B_extra_use3(i64 %a, i64 %b) {
2711 ; CHECK-LABEL: @and_icmp_ne_B_0_icmp_uge_A_B_extra_use3(
2712 ; CHECK-NEXT: [[TMP1:%.*]] = icmp ne i64 [[B:%.*]], 0
2713 ; CHECK-NEXT: call void @use_i1(i1 [[TMP1]])
2714 ; CHECK-NEXT: [[TMP2:%.*]] = icmp uge i64 [[A:%.*]], [[B]]
2715 ; CHECK-NEXT: call void @use_i1(i1 [[TMP2]])
2716 ; CHECK-NEXT: [[TMP3:%.*]] = and i1 [[TMP1]], [[TMP2]]
2717 ; CHECK-NEXT: ret i1 [[TMP3]]
2719 %1 = icmp ne i64 %b, 0
2720 call void @use_i1(i1 %1)
2721 %2 = icmp uge i64 %a, %b
2722 call void @use_i1(i1 %2)
2727 define i1 @and_icmp_ne_B_0_icmp_uge_A_B_wrong_pred1(i64 %a, i64 %b) {
2728 ; CHECK-LABEL: @and_icmp_ne_B_0_icmp_uge_A_B_wrong_pred1(
2729 ; CHECK-NEXT: [[TMP1:%.*]] = icmp sgt i64 [[B:%.*]], 0
2730 ; CHECK-NEXT: [[TMP2:%.*]] = icmp uge i64 [[A:%.*]], [[B]]
2731 ; CHECK-NEXT: [[TMP3:%.*]] = and i1 [[TMP1]], [[TMP2]]
2732 ; CHECK-NEXT: ret i1 [[TMP3]]
2734 %1 = icmp sgt i64 %b, 0
2735 %2 = icmp uge i64 %a, %b
2740 define i1 @and_icmp_ne_B_0_icmp_uge_A_B_wrong_pred2(i64 %a, i64 %b) {
2741 ; CHECK-LABEL: @and_icmp_ne_B_0_icmp_uge_A_B_wrong_pred2(
2742 ; CHECK-NEXT: [[TMP1:%.*]] = icmp ne i64 [[B:%.*]], 0
2743 ; CHECK-NEXT: [[TMP2:%.*]] = icmp ugt i64 [[A:%.*]], [[B]]
2744 ; CHECK-NEXT: [[TMP3:%.*]] = and i1 [[TMP1]], [[TMP2]]
2745 ; CHECK-NEXT: ret i1 [[TMP3]]
2747 %1 = icmp ne i64 %b, 0
2748 %2 = icmp ugt i64 %a, %b
2753 define i1 @and_icmp_ne_B_0_icmp_uge_A_B_wrong_op1(i64 %a, i64 %b) {
2754 ; CHECK-LABEL: @and_icmp_ne_B_0_icmp_uge_A_B_wrong_op1(
2755 ; CHECK-NEXT: [[TMP1:%.*]] = icmp ne i64 [[B:%.*]], 1
2756 ; CHECK-NEXT: [[TMP2:%.*]] = icmp uge i64 [[A:%.*]], [[B]]
2757 ; CHECK-NEXT: [[TMP3:%.*]] = and i1 [[TMP1]], [[TMP2]]
2758 ; CHECK-NEXT: ret i1 [[TMP3]]
2760 %1 = icmp ne i64 %b, 1
2761 %2 = icmp uge i64 %a, %b
2766 define i1 @and_icmp_ne_B_0_icmp_uge_A_B_wrong_op2(i64 %a, i64 %b, i64 %c) {
2767 ; CHECK-LABEL: @and_icmp_ne_B_0_icmp_uge_A_B_wrong_op2(
2768 ; CHECK-NEXT: [[TMP1:%.*]] = icmp ne i64 [[B:%.*]], 0
2769 ; CHECK-NEXT: [[TMP2:%.*]] = icmp uge i64 [[A:%.*]], [[C:%.*]]
2770 ; CHECK-NEXT: [[TMP3:%.*]] = and i1 [[TMP1]], [[TMP2]]
2771 ; CHECK-NEXT: ret i1 [[TMP3]]
2773 %1 = icmp ne i64 %b, 0
2774 %2 = icmp uge i64 %a, %c
2779 define i1 @and_icmp_ne_B_0_icmp_uge_A_B_logical(i64 %a, i64 %b) {
2780 ; CHECK-LABEL: @and_icmp_ne_B_0_icmp_uge_A_B_logical(
2781 ; CHECK-NEXT: [[TMP1:%.*]] = freeze i64 [[A:%.*]]
2782 ; CHECK-NEXT: [[TMP2:%.*]] = add i64 [[B:%.*]], -1
2783 ; CHECK-NEXT: [[TMP3:%.*]] = icmp ult i64 [[TMP2]], [[TMP1]]
2784 ; CHECK-NEXT: ret i1 [[TMP3]]
2786 %1 = icmp ne i64 %b, 0
2787 %2 = icmp uge i64 %a, %b
2788 %3 = select i1 %1, i1 %2, i1 false
2792 define <2 x i1> @and_icmp_ne_B_0_icmp_uge_A_B_uniform(<2 x i64> %a, <2 x i64> %b) {
2793 ; CHECK-LABEL: @and_icmp_ne_B_0_icmp_uge_A_B_uniform(
2794 ; CHECK-NEXT: [[TMP1:%.*]] = add <2 x i64> [[B:%.*]], splat (i64 -1)
2795 ; CHECK-NEXT: [[TMP2:%.*]] = icmp ult <2 x i64> [[TMP1]], [[A:%.*]]
2796 ; CHECK-NEXT: ret <2 x i1> [[TMP2]]
2798 %1 = icmp ne <2 x i64> %b, zeroinitializer
2799 %2 = icmp uge <2 x i64> %a, %b
2800 %3 = and <2 x i1> %1, %2
2804 define <2 x i1> @and_icmp_ne_B_0_icmp_uge_A_B_poison(<2 x i64> %a, <2 x i64> %b) {
2805 ; CHECK-LABEL: @and_icmp_ne_B_0_icmp_uge_A_B_poison(
2806 ; CHECK-NEXT: [[TMP1:%.*]] = add <2 x i64> [[B:%.*]], splat (i64 -1)
2807 ; CHECK-NEXT: [[TMP2:%.*]] = icmp ult <2 x i64> [[TMP1]], [[A:%.*]]
2808 ; CHECK-NEXT: ret <2 x i1> [[TMP2]]
2810 %1 = icmp ne <2 x i64> %b, <i64 0, i64 poison>
2811 %2 = icmp uge <2 x i64> %a, %b
2812 %3 = and <2 x i1> %1, %2
2816 define i1 @icmp_add_ult_2(i32 %X) {
2817 ; CHECK-LABEL: @icmp_add_ult_2(
2818 ; CHECK-NEXT: [[TMP1:%.*]] = and i32 [[X:%.*]], -2
2819 ; CHECK-NEXT: [[CMP:%.*]] = icmp eq i32 [[TMP1]], 14
2820 ; CHECK-NEXT: ret i1 [[CMP]]
2822 %add = add i32 %X, -14
2823 %cmp = icmp ult i32 %add, 2
2827 define <2 x i1> @icmp_add_X_-14_ult_2_vec(<2 x i32> %X) {
2828 ; CHECK-LABEL: @icmp_add_X_-14_ult_2_vec(
2829 ; CHECK-NEXT: [[TMP1:%.*]] = and <2 x i32> [[X:%.*]], splat (i32 -2)
2830 ; CHECK-NEXT: [[CMP:%.*]] = icmp eq <2 x i32> [[TMP1]], splat (i32 14)
2831 ; CHECK-NEXT: ret <2 x i1> [[CMP]]
2833 %add = add <2 x i32> %X, <i32 -14, i32 -14>
2834 %cmp = icmp ult <2 x i32> %add, <i32 2, i32 2>
2838 define i1 @icmp_sub_3_X_ult_2(i32 %X) {
2839 ; CHECK-LABEL: @icmp_sub_3_X_ult_2(
2840 ; CHECK-NEXT: [[TMP1:%.*]] = and i32 [[X:%.*]], -2
2841 ; CHECK-NEXT: [[CMP:%.*]] = icmp eq i32 [[TMP1]], 2
2842 ; CHECK-NEXT: ret i1 [[CMP]]
2844 %add = sub i32 3, %X
2845 %cmp = icmp ult i32 %add, 2
2849 define <2 x i1> @icmp_sub_3_X_ult_2_vec(<2 x i32> %X) {
2850 ; CHECK-LABEL: @icmp_sub_3_X_ult_2_vec(
2851 ; CHECK-NEXT: [[TMP1:%.*]] = and <2 x i32> [[X:%.*]], splat (i32 -2)
2852 ; CHECK-NEXT: [[CMP:%.*]] = icmp eq <2 x i32> [[TMP1]], splat (i32 2)
2853 ; CHECK-NEXT: ret <2 x i1> [[CMP]]
2855 %add = sub <2 x i32> <i32 3, i32 3>, %X
2856 %cmp = icmp ult <2 x i32> %add, <i32 2, i32 2>
2860 define i1 @icmp_add_X_-14_uge_2(i32 %X) {
2861 ; CHECK-LABEL: @icmp_add_X_-14_uge_2(
2862 ; CHECK-NEXT: [[TMP1:%.*]] = and i32 [[X:%.*]], -2
2863 ; CHECK-NEXT: [[CMP:%.*]] = icmp ne i32 [[TMP1]], 14
2864 ; CHECK-NEXT: ret i1 [[CMP]]
2866 %add = add i32 %X, -14
2867 %cmp = icmp uge i32 %add, 2
2871 define <2 x i1> @icmp_add_X_-14_uge_2_vec(<2 x i32> %X) {
2872 ; CHECK-LABEL: @icmp_add_X_-14_uge_2_vec(
2873 ; CHECK-NEXT: [[TMP1:%.*]] = and <2 x i32> [[X:%.*]], splat (i32 -2)
2874 ; CHECK-NEXT: [[CMP:%.*]] = icmp ne <2 x i32> [[TMP1]], splat (i32 14)
2875 ; CHECK-NEXT: ret <2 x i1> [[CMP]]
2877 %add = add <2 x i32> %X, <i32 -14, i32 -14>
2878 %cmp = icmp uge <2 x i32> %add, <i32 2, i32 2>
2882 define i1 @icmp_sub_3_X_uge_2(i32 %X) {
2883 ; CHECK-LABEL: @icmp_sub_3_X_uge_2(
2884 ; CHECK-NEXT: [[TMP1:%.*]] = and i32 [[X:%.*]], -2
2885 ; CHECK-NEXT: [[CMP:%.*]] = icmp ne i32 [[TMP1]], 2
2886 ; CHECK-NEXT: ret i1 [[CMP]]
2888 %add = sub i32 3, %X
2889 %cmp = icmp uge i32 %add, 2
2893 define <2 x i1> @icmp_sub_3_X_uge_2_vec(<2 x i32> %X) {
2894 ; CHECK-LABEL: @icmp_sub_3_X_uge_2_vec(
2895 ; CHECK-NEXT: [[TMP1:%.*]] = and <2 x i32> [[X:%.*]], splat (i32 -2)
2896 ; CHECK-NEXT: [[CMP:%.*]] = icmp ne <2 x i32> [[TMP1]], splat (i32 2)
2897 ; CHECK-NEXT: ret <2 x i1> [[CMP]]
2899 %add = sub <2 x i32> <i32 3, i32 3>, %X
2900 %cmp = icmp uge <2 x i32> %add, <i32 2, i32 2>
2904 define i1 @icmp_and_X_-16_eq-16(i32 %X) {
2905 ; CHECK-LABEL: @icmp_and_X_-16_eq-16(
2906 ; CHECK-NEXT: [[CMP:%.*]] = icmp ugt i32 [[X:%.*]], -17
2907 ; CHECK-NEXT: ret i1 [[CMP]]
2909 %and = and i32 %X, -16
2910 %cmp = icmp eq i32 %and, -16
2914 define <2 x i1> @icmp_and_X_-16_eq-16_vec(<2 x i32> %X) {
2915 ; CHECK-LABEL: @icmp_and_X_-16_eq-16_vec(
2916 ; CHECK-NEXT: [[CMP:%.*]] = icmp ugt <2 x i32> [[X:%.*]], splat (i32 -17)
2917 ; CHECK-NEXT: ret <2 x i1> [[CMP]]
2919 %and = and <2 x i32> %X, <i32 -16, i32 -16>
2920 %cmp = icmp eq <2 x i32> %and, <i32 -16, i32 -16>
2924 define i1 @icmp_and_X_-16_ne-16(i32 %X) {
2925 ; CHECK-LABEL: @icmp_and_X_-16_ne-16(
2926 ; CHECK-NEXT: [[CMP:%.*]] = icmp ult i32 [[X:%.*]], -16
2927 ; CHECK-NEXT: ret i1 [[CMP]]
2929 %and = and i32 %X, -16
2930 %cmp = icmp ne i32 %and, -16
2934 define <2 x i1> @icmp_and_X_-16_ne-16_vec(<2 x i32> %X) {
2935 ; CHECK-LABEL: @icmp_and_X_-16_ne-16_vec(
2936 ; CHECK-NEXT: [[CMP:%.*]] = icmp ult <2 x i32> [[X:%.*]], splat (i32 -16)
2937 ; CHECK-NEXT: ret <2 x i1> [[CMP]]
2939 %and = and <2 x i32> %X, <i32 -16, i32 -16>
2940 %cmp = icmp ne <2 x i32> %and, <i32 -16, i32 -16>
2944 ; PR32524: https://bugs.llvm.org/show_bug.cgi?id=32524
2945 ; X | C == C --> X <=u C (when C+1 is PowerOf2).
2947 define i1 @or1_eq1(i32 %x) {
2948 ; CHECK-LABEL: @or1_eq1(
2949 ; CHECK-NEXT: [[T1:%.*]] = icmp ult i32 [[X:%.*]], 2
2950 ; CHECK-NEXT: ret i1 [[T1]]
2953 %t1 = icmp eq i32 %t0, 1
2957 ; X | C == C --> X <=u C (when C+1 is PowerOf2).
2959 define <2 x i1> @or3_eq3_vec(<2 x i8> %x) {
2960 ; CHECK-LABEL: @or3_eq3_vec(
2961 ; CHECK-NEXT: [[T1:%.*]] = icmp ult <2 x i8> [[X:%.*]], splat (i8 4)
2962 ; CHECK-NEXT: ret <2 x i1> [[T1]]
2964 %t0 = or <2 x i8> %x, <i8 3, i8 3>
2965 %t1 = icmp eq <2 x i8> %t0, <i8 3, i8 3>
2969 ; X | C != C --> X >u C (when C+1 is PowerOf2).
2971 define i1 @or7_ne7(i32 %x) {
2972 ; CHECK-LABEL: @or7_ne7(
2973 ; CHECK-NEXT: [[T1:%.*]] = icmp ugt i32 [[X:%.*]], 7
2974 ; CHECK-NEXT: ret i1 [[T1]]
2977 %t1 = icmp ne i32 %t0, 7
2981 ; X | C != C --> X >u C (when C+1 is PowerOf2).
2983 define <2 x i1> @or63_ne63_vec(<2 x i8> %x) {
2984 ; CHECK-LABEL: @or63_ne63_vec(
2985 ; CHECK-NEXT: [[T1:%.*]] = icmp ugt <2 x i8> [[X:%.*]], splat (i8 63)
2986 ; CHECK-NEXT: ret <2 x i1> [[T1]]
2988 %t0 = or <2 x i8> %x, <i8 63, i8 63>
2989 %t1 = icmp ne <2 x i8> %t0, <i8 63, i8 63>
2993 ; PR40611: https://bugs.llvm.org/show_bug.cgi?id=40611
2994 ; X | C == C --> (X & ~C) == 0
2996 define i1 @orC_eqC(i32 %x) {
2997 ; CHECK-LABEL: @orC_eqC(
2998 ; CHECK-NEXT: [[TMP1:%.*]] = and i32 [[X:%.*]], -43
2999 ; CHECK-NEXT: [[T1:%.*]] = icmp eq i32 [[TMP1]], 0
3000 ; CHECK-NEXT: ret i1 [[T1]]
3003 %t1 = icmp eq i32 %t0, 42
3007 ; X | C == C --> (X & ~C) == 0
3009 define <2 x i1> @orC_eqC_vec(<2 x i8> %x) {
3010 ; CHECK-LABEL: @orC_eqC_vec(
3011 ; CHECK-NEXT: [[TMP1:%.*]] = and <2 x i8> [[X:%.*]], splat (i8 -44)
3012 ; CHECK-NEXT: [[T1:%.*]] = icmp eq <2 x i8> [[TMP1]], zeroinitializer
3013 ; CHECK-NEXT: ret <2 x i1> [[T1]]
3015 %t0 = or <2 x i8> %x, <i8 43, i8 43>
3016 %t1 = icmp eq <2 x i8> %t0, <i8 43, i8 43>
3020 ; X | C != C --> (X & ~C) != 0
3022 define i1 @orC_neC(i32 %x) {
3023 ; CHECK-LABEL: @orC_neC(
3024 ; CHECK-NEXT: [[TMP1:%.*]] = and i32 [[X:%.*]], 41
3025 ; CHECK-NEXT: [[T1:%.*]] = icmp ne i32 [[TMP1]], 0
3026 ; CHECK-NEXT: ret i1 [[T1]]
3028 %t0 = or i32 %x, -42
3029 %t1 = icmp ne i32 %t0, -42
3033 ; X | C != C --> (X & ~C) != 0
3035 define <2 x i1> @orC_neC_vec(<2 x i8> %x) {
3036 ; CHECK-LABEL: @orC_neC_vec(
3037 ; CHECK-NEXT: [[TMP1:%.*]] = and <2 x i8> [[X:%.*]], splat (i8 42)
3038 ; CHECK-NEXT: [[T1:%.*]] = icmp ne <2 x i8> [[TMP1]], zeroinitializer
3039 ; CHECK-NEXT: ret <2 x i1> [[T1]]
3041 %t0 = or <2 x i8> %x, <i8 -43, i8 -43>
3042 %t1 = icmp ne <2 x i8> %t0, <i8 -43, i8 -43>
3046 define i1 @shrink_constant(i32 %X) {
3047 ; CHECK-LABEL: @shrink_constant(
3048 ; CHECK-NEXT: [[XOR:%.*]] = xor i32 [[X:%.*]], -12
3049 ; CHECK-NEXT: [[CMP:%.*]] = icmp ult i32 [[XOR]], 4
3050 ; CHECK-NEXT: ret i1 [[CMP]]
3052 %xor = xor i32 %X, -9
3053 %cmp = icmp ult i32 %xor, 4
3057 define <2 x i1> @shrink_constant_vec(<2 x i32> %X) {
3058 ; CHECK-LABEL: @shrink_constant_vec(
3059 ; CHECK-NEXT: [[XOR:%.*]] = xor <2 x i32> [[X:%.*]], splat (i32 -12)
3060 ; CHECK-NEXT: [[CMP:%.*]] = icmp ult <2 x i32> [[XOR]], splat (i32 4)
3061 ; CHECK-NEXT: ret <2 x i1> [[CMP]]
3063 %xor = xor <2 x i32> %X, <i32 -9, i32 -9>
3064 %cmp = icmp ult <2 x i32> %xor, <i32 4, i32 4>
3068 ; This test requires 3 different transforms to get to the result.
3069 define i1 @icmp_sub_-1_X_ult_4(i32 %X) {
3070 ; CHECK-LABEL: @icmp_sub_-1_X_ult_4(
3071 ; CHECK-NEXT: [[CMP:%.*]] = icmp ugt i32 [[X:%.*]], -5
3072 ; CHECK-NEXT: ret i1 [[CMP]]
3074 %sub = sub i32 -1, %X
3075 %cmp = icmp ult i32 %sub, 4
3079 define <2 x i1> @icmp_xor_neg4_X_ult_4_vec(<2 x i32> %X) {
3080 ; CHECK-LABEL: @icmp_xor_neg4_X_ult_4_vec(
3081 ; CHECK-NEXT: [[CMP:%.*]] = icmp ugt <2 x i32> [[X:%.*]], splat (i32 -5)
3082 ; CHECK-NEXT: ret <2 x i1> [[CMP]]
3084 %xor = xor <2 x i32> %X, <i32 -4, i32 -4>
3085 %cmp = icmp ult <2 x i32> %xor, <i32 4, i32 4>
3089 define i1 @icmp_sub_-1_X_uge_4(i32 %X) {
3090 ; CHECK-LABEL: @icmp_sub_-1_X_uge_4(
3091 ; CHECK-NEXT: [[CMP:%.*]] = icmp ult i32 [[X:%.*]], -4
3092 ; CHECK-NEXT: ret i1 [[CMP]]
3094 %sub = sub i32 -1, %X
3095 %cmp = icmp uge i32 %sub, 4
3099 define <2 x i1> @icmp_xor_neg4_X_uge_4_vec(<2 x i32> %X) {
3100 ; CHECK-LABEL: @icmp_xor_neg4_X_uge_4_vec(
3101 ; CHECK-NEXT: [[CMP:%.*]] = icmp ult <2 x i32> [[X:%.*]], splat (i32 -4)
3102 ; CHECK-NEXT: ret <2 x i1> [[CMP]]
3104 %xor = xor <2 x i32> %X, <i32 -4, i32 -4>
3105 %cmp = icmp uge <2 x i32> %xor, <i32 4, i32 4>
3109 define <2 x i1> @xor_ult(<2 x i8> %x) {
3110 ; CHECK-LABEL: @xor_ult(
3111 ; CHECK-NEXT: [[R:%.*]] = icmp ugt <2 x i8> [[X:%.*]], splat (i8 3)
3112 ; CHECK-NEXT: ret <2 x i1> [[R]]
3114 %xor = xor <2 x i8> %x, <i8 -4, i8 -4>
3115 %r = icmp ult <2 x i8> %xor, <i8 -4, i8 -4>
3119 define i1 @xor_ult_extra_use(i8 %x, ptr %p) {
3120 ; CHECK-LABEL: @xor_ult_extra_use(
3121 ; CHECK-NEXT: [[XOR:%.*]] = xor i8 [[X:%.*]], -32
3122 ; CHECK-NEXT: store i8 [[XOR]], ptr [[P:%.*]], align 1
3123 ; CHECK-NEXT: [[R:%.*]] = icmp ugt i8 [[X]], 31
3124 ; CHECK-NEXT: ret i1 [[R]]
3126 %xor = xor i8 %x, -32
3127 store i8 %xor, ptr %p
3128 %r = icmp ult i8 %xor, -32
3132 define <2 x i1> @xor_ugt(<2 x i8> %x) {
3133 ; CHECK-LABEL: @xor_ugt(
3134 ; CHECK-NEXT: [[R:%.*]] = icmp ugt <2 x i8> [[X:%.*]], splat (i8 7)
3135 ; CHECK-NEXT: ret <2 x i1> [[R]]
3137 %xor = xor <2 x i8> %x, <i8 7, i8 7>
3138 %r = icmp ugt <2 x i8> %xor, <i8 7, i8 7>
3142 define i1 @xor_ugt_extra_use(i8 %x, ptr %p) {
3143 ; CHECK-LABEL: @xor_ugt_extra_use(
3144 ; CHECK-NEXT: [[XOR:%.*]] = xor i8 [[X:%.*]], 63
3145 ; CHECK-NEXT: store i8 [[XOR]], ptr [[P:%.*]], align 1
3146 ; CHECK-NEXT: [[R:%.*]] = icmp ugt i8 [[X]], 63
3147 ; CHECK-NEXT: ret i1 [[R]]
3149 %xor = xor i8 %x, 63
3150 store i8 %xor, ptr %p
3151 %r = icmp ugt i8 %xor, 63
3155 define i1 @icmp_lshr_lshr_eq(i32 %a, i32 %b) {
3156 ; CHECK-LABEL: @icmp_lshr_lshr_eq(
3157 ; CHECK-NEXT: [[Z_UNSHIFTED:%.*]] = xor i32 [[A:%.*]], [[B:%.*]]
3158 ; CHECK-NEXT: [[Z:%.*]] = icmp ult i32 [[Z_UNSHIFTED]], 1073741824
3159 ; CHECK-NEXT: ret i1 [[Z]]
3161 %x = lshr i32 %a, 30
3162 %y = lshr i32 %b, 30
3163 %z = icmp eq i32 %x, %y
3167 define i1 @icmp_ashr_ashr_ne(i32 %a, i32 %b) {
3168 ; CHECK-LABEL: @icmp_ashr_ashr_ne(
3169 ; CHECK-NEXT: [[Z_UNSHIFTED:%.*]] = xor i32 [[A:%.*]], [[B:%.*]]
3170 ; CHECK-NEXT: [[Z:%.*]] = icmp ugt i32 [[Z_UNSHIFTED]], 255
3171 ; CHECK-NEXT: ret i1 [[Z]]
3175 %z = icmp ne i32 %x, %y
3179 define i1 @icmp_neg_cst_slt(i32 %a) {
3180 ; CHECK-LABEL: @icmp_neg_cst_slt(
3181 ; CHECK-NEXT: [[TMP1:%.*]] = icmp sgt i32 [[A:%.*]], 10
3182 ; CHECK-NEXT: ret i1 [[TMP1]]
3184 %1 = sub nsw i32 0, %a
3185 %2 = icmp slt i32 %1, -10
3189 define i1 @icmp_and_or_lshr(i32 %x, i32 %y) {
3190 ; CHECK-LABEL: @icmp_and_or_lshr(
3191 ; CHECK-NEXT: [[SHF1:%.*]] = shl nuw i32 1, [[Y:%.*]]
3192 ; CHECK-NEXT: [[OR2:%.*]] = or i32 [[SHF1]], 1
3193 ; CHECK-NEXT: [[AND3:%.*]] = and i32 [[X:%.*]], [[OR2]]
3194 ; CHECK-NEXT: [[RET:%.*]] = icmp ne i32 [[AND3]], 0
3195 ; CHECK-NEXT: ret i1 [[RET]]
3197 %shf = lshr i32 %x, %y
3198 %or = or i32 %shf, %x
3199 %and = and i32 %or, 1
3200 %ret = icmp ne i32 %and, 0
3204 define i1 @icmp_and_or_lshr_samesign(i32 %x, i32 %y) {
3205 ; CHECK-LABEL: @icmp_and_or_lshr_samesign(
3206 ; CHECK-NEXT: [[SHF1:%.*]] = shl nuw i32 1, [[Y:%.*]]
3207 ; CHECK-NEXT: [[OR2:%.*]] = or i32 [[SHF1]], 1
3208 ; CHECK-NEXT: [[AND3:%.*]] = and i32 [[X:%.*]], [[OR2]]
3209 ; CHECK-NEXT: [[RET:%.*]] = icmp ne i32 [[AND3]], 0
3210 ; CHECK-NEXT: ret i1 [[RET]]
3212 %shf = lshr i32 %x, %y
3213 %or = or i32 %shf, %x
3214 %and = and i32 %or, 1
3215 %ret = icmp samesign ne i32 %and, 0
3219 define <2 x i1> @icmp_and_or_lshr_vec(<2 x i32> %x, <2 x i32> %y) {
3220 ; CHECK-LABEL: @icmp_and_or_lshr_vec(
3221 ; CHECK-NEXT: [[SHF:%.*]] = lshr <2 x i32> [[X:%.*]], [[Y:%.*]]
3222 ; CHECK-NEXT: [[OR:%.*]] = or <2 x i32> [[SHF]], [[X]]
3223 ; CHECK-NEXT: [[RET:%.*]] = trunc <2 x i32> [[OR]] to <2 x i1>
3224 ; CHECK-NEXT: ret <2 x i1> [[RET]]
3226 %shf = lshr <2 x i32> %x, %y
3227 %or = or <2 x i32> %shf, %x
3228 %and = and <2 x i32> %or, <i32 1, i32 1>
3229 %ret = icmp ne <2 x i32> %and, zeroinitializer
3233 define <2 x i1> @icmp_and_or_lshr_vec_commute(<2 x i32> %xp, <2 x i32> %y) {
3234 ; CHECK-LABEL: @icmp_and_or_lshr_vec_commute(
3235 ; CHECK-NEXT: [[X:%.*]] = srem <2 x i32> [[XP:%.*]], splat (i32 42)
3236 ; CHECK-NEXT: [[SHF:%.*]] = lshr <2 x i32> [[X]], [[Y:%.*]]
3237 ; CHECK-NEXT: [[OR:%.*]] = or <2 x i32> [[X]], [[SHF]]
3238 ; CHECK-NEXT: [[RET:%.*]] = trunc <2 x i32> [[OR]] to <2 x i1>
3239 ; CHECK-NEXT: ret <2 x i1> [[RET]]
3241 %x = srem <2 x i32> %xp, <i32 42, i32 -42> ; prevent complexity-based canonicalization
3242 %shf = lshr <2 x i32> %x, %y
3243 %or = or <2 x i32> %x, %shf
3244 %and = and <2 x i32> %or, <i32 1, i32 1>
3245 %ret = icmp ne <2 x i32> %and, zeroinitializer
3249 define i1 @icmp_and_or_lshr_cst(i32 %x) {
3250 ; CHECK-LABEL: @icmp_and_or_lshr_cst(
3251 ; CHECK-NEXT: [[AND1:%.*]] = and i32 [[X:%.*]], 3
3252 ; CHECK-NEXT: [[RET:%.*]] = icmp ne i32 [[AND1]], 0
3253 ; CHECK-NEXT: ret i1 [[RET]]
3255 %shf = lshr i32 %x, 1
3256 %or = or i32 %shf, %x
3257 %and = and i32 %or, 1
3258 %ret = icmp ne i32 %and, 0
3262 define <2 x i1> @icmp_and_or_lshr_cst_vec(<2 x i32> %x) {
3263 ; CHECK-LABEL: @icmp_and_or_lshr_cst_vec(
3264 ; CHECK-NEXT: [[TMP1:%.*]] = and <2 x i32> [[X:%.*]], splat (i32 3)
3265 ; CHECK-NEXT: [[RET:%.*]] = icmp ne <2 x i32> [[TMP1]], zeroinitializer
3266 ; CHECK-NEXT: ret <2 x i1> [[RET]]
3268 %shf = lshr <2 x i32> %x, <i32 1, i32 1>
3269 %or = or <2 x i32> %shf, %x
3270 %and = and <2 x i32> %or, <i32 1, i32 1>
3271 %ret = icmp ne <2 x i32> %and, zeroinitializer
3275 define <2 x i1> @icmp_and_or_lshr_cst_vec_nonuniform(<2 x i32> %x) {
3276 ; CHECK-LABEL: @icmp_and_or_lshr_cst_vec_nonuniform(
3277 ; CHECK-NEXT: [[TMP1:%.*]] = and <2 x i32> [[X:%.*]], <i32 3, i32 5>
3278 ; CHECK-NEXT: [[RET:%.*]] = icmp ne <2 x i32> [[TMP1]], zeroinitializer
3279 ; CHECK-NEXT: ret <2 x i1> [[RET]]
3281 %shf = lshr <2 x i32> %x, <i32 1, i32 2>
3282 %or = or <2 x i32> %shf, %x
3283 %and = and <2 x i32> %or, <i32 1, i32 1>
3284 %ret = icmp ne <2 x i32> %and, zeroinitializer
3288 define <2 x i1> @icmp_and_or_lshr_cst_vec_poison(<2 x i32> %x) {
3289 ; CHECK-LABEL: @icmp_and_or_lshr_cst_vec_poison(
3290 ; CHECK-NEXT: [[TMP1:%.*]] = and <2 x i32> [[X:%.*]], <i32 3, i32 poison>
3291 ; CHECK-NEXT: [[RET:%.*]] = icmp ne <2 x i32> [[TMP1]], zeroinitializer
3292 ; CHECK-NEXT: ret <2 x i1> [[RET]]
3294 %shf = lshr <2 x i32> %x, <i32 1, i32 poison>
3295 %or = or <2 x i32> %shf, %x
3296 %and = and <2 x i32> %or, <i32 1, i32 1>
3297 %ret = icmp ne <2 x i32> %and, zeroinitializer
3301 define <2 x i1> @icmp_and_or_lshr_cst_vec_commute(<2 x i32> %xp) {
3302 ; CHECK-LABEL: @icmp_and_or_lshr_cst_vec_commute(
3303 ; CHECK-NEXT: [[X:%.*]] = srem <2 x i32> [[XP:%.*]], splat (i32 42)
3304 ; CHECK-NEXT: [[TMP1:%.*]] = and <2 x i32> [[X]], splat (i32 3)
3305 ; CHECK-NEXT: [[RET:%.*]] = icmp ne <2 x i32> [[TMP1]], zeroinitializer
3306 ; CHECK-NEXT: ret <2 x i1> [[RET]]
3308 %x = srem <2 x i32> %xp, <i32 42, i32 -42> ; prevent complexity-based canonicalization
3309 %shf = lshr <2 x i32> %x, <i32 1, i32 1>
3310 %or = or <2 x i32> %x, %shf
3311 %and = and <2 x i32> %or, <i32 1, i32 1>
3312 %ret = icmp ne <2 x i32> %and, zeroinitializer
3316 define <2 x i1> @icmp_and_or_lshr_cst_vec_nonuniform_commute(<2 x i32> %xp) {
3317 ; CHECK-LABEL: @icmp_and_or_lshr_cst_vec_nonuniform_commute(
3318 ; CHECK-NEXT: [[X:%.*]] = srem <2 x i32> [[XP:%.*]], splat (i32 42)
3319 ; CHECK-NEXT: [[TMP1:%.*]] = and <2 x i32> [[X]], <i32 3, i32 5>
3320 ; CHECK-NEXT: [[RET:%.*]] = icmp ne <2 x i32> [[TMP1]], zeroinitializer
3321 ; CHECK-NEXT: ret <2 x i1> [[RET]]
3323 %x = srem <2 x i32> %xp, <i32 42, i32 -42> ; prevent complexity-based canonicalization
3324 %shf = lshr <2 x i32> %x, <i32 1, i32 2>
3325 %or = or <2 x i32> %x, %shf
3326 %and = and <2 x i32> %or, <i32 1, i32 1>
3327 %ret = icmp ne <2 x i32> %and, zeroinitializer
3331 define <2 x i1> @icmp_and_or_lshr_cst_vec_poison_commute(<2 x i32> %xp) {
3332 ; CHECK-LABEL: @icmp_and_or_lshr_cst_vec_poison_commute(
3333 ; CHECK-NEXT: [[X:%.*]] = srem <2 x i32> [[XP:%.*]], splat (i32 42)
3334 ; CHECK-NEXT: [[TMP1:%.*]] = and <2 x i32> [[X]], <i32 3, i32 poison>
3335 ; CHECK-NEXT: [[RET:%.*]] = icmp ne <2 x i32> [[TMP1]], zeroinitializer
3336 ; CHECK-NEXT: ret <2 x i1> [[RET]]
3338 %x = srem <2 x i32> %xp, <i32 42, i32 -42> ; prevent complexity-based canonicalization
3339 %shf = lshr <2 x i32> %x, <i32 1, i32 poison>
3340 %or = or <2 x i32> %x, %shf
3341 %and = and <2 x i32> %or, <i32 1, i32 1>
3342 %ret = icmp ne <2 x i32> %and, zeroinitializer
3346 define i1 @shl_ap1_zero_ap2_non_zero_2(i32 %a) {
3347 ; CHECK-LABEL: @shl_ap1_zero_ap2_non_zero_2(
3348 ; CHECK-NEXT: [[CMP:%.*]] = icmp ugt i32 [[A:%.*]], 29
3349 ; CHECK-NEXT: ret i1 [[CMP]]
3351 %shl = shl i32 4, %a
3352 %cmp = icmp eq i32 %shl, 0
3356 define <2 x i1> @shl_ap1_zero_ap2_non_zero_2_vec(<2 x i32> %a) {
3357 ; CHECK-LABEL: @shl_ap1_zero_ap2_non_zero_2_vec(
3358 ; CHECK-NEXT: [[CMP:%.*]] = icmp ugt <2 x i32> [[A:%.*]], splat (i32 29)
3359 ; CHECK-NEXT: ret <2 x i1> [[CMP]]
3361 %shl = shl <2 x i32> <i32 4, i32 4>, %a
3362 %cmp = icmp eq <2 x i32> %shl, zeroinitializer
3366 define <2 x i1> @shl_ap1_zero_ap2_non_zero_2_vec_nonuniform(<2 x i32> %a) {
3367 ; CHECK-LABEL: @shl_ap1_zero_ap2_non_zero_2_vec_nonuniform(
3368 ; CHECK-NEXT: [[SHL:%.*]] = shl <2 x i32> <i32 4, i32 5>, [[A:%.*]]
3369 ; CHECK-NEXT: [[CMP:%.*]] = icmp eq <2 x i32> [[SHL]], zeroinitializer
3370 ; CHECK-NEXT: ret <2 x i1> [[CMP]]
3372 %shl = shl <2 x i32> <i32 4, i32 5>, %a
3373 %cmp = icmp eq <2 x i32> %shl, zeroinitializer
3377 define i1 @shl_ap1_zero_ap2_non_zero_4(i32 %a) {
3378 ; CHECK-LABEL: @shl_ap1_zero_ap2_non_zero_4(
3379 ; CHECK-NEXT: [[CMP:%.*]] = icmp ugt i32 [[A:%.*]], 30
3380 ; CHECK-NEXT: ret i1 [[CMP]]
3382 %shl = shl i32 -2, %a
3383 %cmp = icmp eq i32 %shl, 0
3387 define i1 @shl_ap1_non_zero_ap2_non_zero_both_positive(i32 %a) {
3388 ; CHECK-LABEL: @shl_ap1_non_zero_ap2_non_zero_both_positive(
3389 ; CHECK-NEXT: [[CMP:%.*]] = icmp eq i32 [[A:%.*]], 0
3390 ; CHECK-NEXT: ret i1 [[CMP]]
3392 %shl = shl i32 50, %a
3393 %cmp = icmp eq i32 %shl, 50
3397 define i1 @shl_ap1_non_zero_ap2_non_zero_both_negative(i32 %a) {
3398 ; CHECK-LABEL: @shl_ap1_non_zero_ap2_non_zero_both_negative(
3399 ; CHECK-NEXT: [[CMP:%.*]] = icmp eq i32 [[A:%.*]], 0
3400 ; CHECK-NEXT: ret i1 [[CMP]]
3402 %shl = shl i32 -50, %a
3403 %cmp = icmp eq i32 %shl, -50
3407 define i1 @shl_ap1_non_zero_ap2_non_zero_ap1_1(i32 %a) {
3408 ; CHECK-LABEL: @shl_ap1_non_zero_ap2_non_zero_ap1_1(
3409 ; CHECK-NEXT: ret i1 false
3411 %shl = shl i32 50, %a
3412 %cmp = icmp eq i32 %shl, 25
3416 define i1 @shl_ap1_non_zero_ap2_non_zero_ap1_2(i32 %a) {
3417 ; CHECK-LABEL: @shl_ap1_non_zero_ap2_non_zero_ap1_2(
3418 ; CHECK-NEXT: [[CMP:%.*]] = icmp eq i32 [[A:%.*]], 1
3419 ; CHECK-NEXT: ret i1 [[CMP]]
3421 %shl = shl i32 25, %a
3422 %cmp = icmp eq i32 %shl, 50
3426 define i1 @shl_ap1_non_zero_ap2_non_zero_ap1_3(i32 %a) {
3427 ; CHECK-LABEL: @shl_ap1_non_zero_ap2_non_zero_ap1_3(
3428 ; CHECK-NEXT: ret i1 false
3430 %shl = shl i32 26, %a
3431 %cmp = icmp eq i32 %shl, 50
3435 define i1 @icmp_sgt_zero_add_nsw(i32 %a) {
3436 ; CHECK-LABEL: @icmp_sgt_zero_add_nsw(
3437 ; CHECK-NEXT: [[CMP:%.*]] = icmp sgt i32 [[A:%.*]], -1
3438 ; CHECK-NEXT: ret i1 [[CMP]]
3440 %add = add nsw i32 %a, 1
3441 %cmp = icmp sgt i32 %add, 0
3445 define i1 @icmp_sge_zero_add_nsw(i32 %a) {
3446 ; CHECK-LABEL: @icmp_sge_zero_add_nsw(
3447 ; CHECK-NEXT: [[CMP:%.*]] = icmp sgt i32 [[A:%.*]], -2
3448 ; CHECK-NEXT: ret i1 [[CMP]]
3450 %add = add nsw i32 %a, 1
3451 %cmp = icmp sge i32 %add, 0
3455 define i1 @icmp_sle_zero_add_nsw(i32 %a) {
3456 ; CHECK-LABEL: @icmp_sle_zero_add_nsw(
3457 ; CHECK-NEXT: [[CMP:%.*]] = icmp slt i32 [[A:%.*]], 0
3458 ; CHECK-NEXT: ret i1 [[CMP]]
3460 %add = add nsw i32 %a, 1
3461 %cmp = icmp sle i32 %add, 0
3465 define zeroext i1 @icmp_cmpxchg_strong(ptr %sc, i32 %old_val, i32 %new_val) {
3466 ; CHECK-LABEL: @icmp_cmpxchg_strong(
3467 ; CHECK-NEXT: [[XCHG:%.*]] = cmpxchg ptr [[SC:%.*]], i32 [[OLD_VAL:%.*]], i32 [[NEW_VAL:%.*]] seq_cst seq_cst, align 4
3468 ; CHECK-NEXT: [[ICMP:%.*]] = extractvalue { i32, i1 } [[XCHG]], 1
3469 ; CHECK-NEXT: ret i1 [[ICMP]]
3471 %xchg = cmpxchg ptr %sc, i32 %old_val, i32 %new_val seq_cst seq_cst
3472 %xtrc = extractvalue { i32, i1 } %xchg, 0
3473 %icmp = icmp eq i32 %xtrc, %old_val
3477 define i1 @f1(i64 %a, i64 %b) {
3479 ; CHECK-NEXT: [[V:%.*]] = icmp sge i64 [[A:%.*]], [[B:%.*]]
3480 ; CHECK-NEXT: ret i1 [[V]]
3482 %t = sub nsw i64 %a, %b
3483 %v = icmp sge i64 %t, 0
3487 define <2 x i1> @f1_vec(<2 x i64> %a, <2 x i64> %b) {
3488 ; CHECK-LABEL: @f1_vec(
3489 ; CHECK-NEXT: [[V:%.*]] = icmp sge <2 x i64> [[A:%.*]], [[B:%.*]]
3490 ; CHECK-NEXT: ret <2 x i1> [[V]]
3492 %t = sub nsw <2 x i64> %a, %b
3493 %v = icmp sgt <2 x i64> %t, <i64 -1, i64 -1>
3497 define i1 @f2(i64 %a, i64 %b) {
3499 ; CHECK-NEXT: [[V:%.*]] = icmp sgt i64 [[A:%.*]], [[B:%.*]]
3500 ; CHECK-NEXT: ret i1 [[V]]
3502 %t = sub nsw i64 %a, %b
3503 %v = icmp sgt i64 %t, 0
3507 define <2 x i1> @f2_vec(<2 x i64> %a, <2 x i64> %b) {
3508 ; CHECK-LABEL: @f2_vec(
3509 ; CHECK-NEXT: [[V:%.*]] = icmp sgt <2 x i64> [[A:%.*]], [[B:%.*]]
3510 ; CHECK-NEXT: ret <2 x i1> [[V]]
3512 %t = sub nsw <2 x i64> %a, %b
3513 %v = icmp sgt <2 x i64> %t, zeroinitializer
3517 define i1 @f3(i64 %a, i64 %b) {
3519 ; CHECK-NEXT: [[V:%.*]] = icmp slt i64 [[A:%.*]], [[B:%.*]]
3520 ; CHECK-NEXT: ret i1 [[V]]
3522 %t = sub nsw i64 %a, %b
3523 %v = icmp slt i64 %t, 0
3527 define <2 x i1> @f3_vec(<2 x i64> %a, <2 x i64> %b) {
3528 ; CHECK-LABEL: @f3_vec(
3529 ; CHECK-NEXT: [[V:%.*]] = icmp slt <2 x i64> [[A:%.*]], [[B:%.*]]
3530 ; CHECK-NEXT: ret <2 x i1> [[V]]
3532 %t = sub nsw <2 x i64> %a, %b
3533 %v = icmp slt <2 x i64> %t, zeroinitializer
3537 define i1 @f4(i64 %a, i64 %b) {
3539 ; CHECK-NEXT: [[V:%.*]] = icmp sle i64 [[A:%.*]], [[B:%.*]]
3540 ; CHECK-NEXT: ret i1 [[V]]
3542 %t = sub nsw i64 %a, %b
3543 %v = icmp sle i64 %t, 0
3547 define <2 x i1> @f4_vec(<2 x i64> %a, <2 x i64> %b) {
3548 ; CHECK-LABEL: @f4_vec(
3549 ; CHECK-NEXT: [[V:%.*]] = icmp sle <2 x i64> [[A:%.*]], [[B:%.*]]
3550 ; CHECK-NEXT: ret <2 x i1> [[V]]
3552 %t = sub nsw <2 x i64> %a, %b
3553 %v = icmp slt <2 x i64> %t, <i64 1, i64 1>
3557 define i32 @f5(i8 %a, i8 %b) {
3559 ; CHECK-NEXT: [[CONV:%.*]] = zext i8 [[A:%.*]] to i32
3560 ; CHECK-NEXT: [[CONV3:%.*]] = zext i8 [[B:%.*]] to i32
3561 ; CHECK-NEXT: [[SUB:%.*]] = sub nsw i32 [[CONV]], [[CONV3]]
3562 ; CHECK-NEXT: [[SUB7_SUB:%.*]] = call i32 @llvm.abs.i32(i32 [[SUB]], i1 true)
3563 ; CHECK-NEXT: ret i32 [[SUB7_SUB]]
3565 %conv = zext i8 %a to i32
3566 %conv3 = zext i8 %b to i32
3567 %sub = sub nsw i32 %conv, %conv3
3568 %cmp4 = icmp slt i32 %sub, 0
3569 %sub7 = sub nsw i32 0, %sub
3570 %sub7.sub = select i1 %cmp4, i32 %sub7, i32 %sub
3574 define i32 @f6(i32 %a, i32 %b) {
3576 ; CHECK-NEXT: [[CMP_UNSHIFTED:%.*]] = xor i32 [[A:%.*]], [[B:%.*]]
3577 ; CHECK-NEXT: [[CMP_MASK:%.*]] = and i32 [[CMP_UNSHIFTED]], 255
3578 ; CHECK-NEXT: [[CMP:%.*]] = icmp eq i32 [[CMP_MASK]], 0
3579 ; CHECK-NEXT: [[S:%.*]] = select i1 [[CMP]], i32 10000, i32 0
3580 ; CHECK-NEXT: ret i32 [[S]]
3582 %sext = shl i32 %a, 24
3583 %conv = ashr i32 %sext, 24
3584 %sext6 = shl i32 %b, 24
3585 %conv4 = ashr i32 %sext6, 24
3586 %cmp = icmp eq i32 %conv, %conv4
3587 %s = select i1 %cmp, i32 10000, i32 0
3591 define i32 @f7(i32 %a, i32 %b) {
3593 ; CHECK-NEXT: [[CMP_NOT_UNSHIFTED:%.*]] = xor i32 [[A:%.*]], [[B:%.*]]
3594 ; CHECK-NEXT: [[CMP_NOT_MASK:%.*]] = and i32 [[CMP_NOT_UNSHIFTED]], 511
3595 ; CHECK-NEXT: [[CMP_NOT:%.*]] = icmp eq i32 [[CMP_NOT_MASK]], 0
3596 ; CHECK-NEXT: [[S:%.*]] = select i1 [[CMP_NOT]], i32 0, i32 10000
3597 ; CHECK-NEXT: ret i32 [[S]]
3599 %sext = shl i32 %a, 23
3600 %sext6 = shl i32 %b, 23
3601 %cmp = icmp ne i32 %sext, %sext6
3602 %s = select i1 %cmp, i32 10000, i32 0
3606 define i1 @f8(i32 %val, i32 %lim) {
3608 ; CHECK-NEXT: [[R:%.*]] = icmp ne i32 [[LIM:%.*]], 0
3609 ; CHECK-NEXT: ret i1 [[R]]
3611 %lim.sub = add i32 %lim, -1
3612 %val.and = and i32 %val, %lim.sub
3613 %r = icmp ult i32 %val.and, %lim
3617 define i1 @f9(i32 %val, i32 %lim) {
3619 ; CHECK-NEXT: [[R:%.*]] = icmp ne i32 [[LIM:%.*]], 0
3620 ; CHECK-NEXT: ret i1 [[R]]
3622 %lim.sub = sub i32 %lim, 1
3623 %val.and = and i32 %val, %lim.sub
3624 %r = icmp ult i32 %val.and, %lim
3628 define i1 @f10(i16 %p) {
3629 ; CHECK-LABEL: @f10(
3630 ; CHECK-NEXT: [[EXT1:%.*]] = zext i8 ptrtoint (ptr @f10 to i8) to i16
3631 ; CHECK-NEXT: [[EXT2:%.*]] = zext i8 ptrtoint (ptr @f10 to i8) to i16
3632 ; CHECK-NEXT: [[MUL:%.*]] = mul nuw i16 [[EXT1]], [[EXT2]]
3633 ; CHECK-NEXT: [[CMP580:%.*]] = icmp ule i16 [[MUL]], [[P:%.*]]
3634 ; CHECK-NEXT: ret i1 [[CMP580]]
3636 %ext1 = zext i8 ptrtoint (ptr @f10 to i8) to i16
3637 %ext2 = zext i8 ptrtoint (ptr @f10 to i8) to i16
3638 %mul = mul i16 %ext1, %ext2
3639 %cmp580 = icmp ule i16 %mul, %p
3643 ; Note: fptosi is used in various tests below to ensure that operand complexity
3644 ; canonicalization does not kick in, which would make some of the tests
3645 ; equivalent to one another.
3647 define i1 @cmp_sgt_rhs_dec(float %x, i32 %i) {
3648 ; CHECK-LABEL: @cmp_sgt_rhs_dec(
3649 ; CHECK-NEXT: [[CONV:%.*]] = fptosi float [[X:%.*]] to i32
3650 ; CHECK-NEXT: [[CMP:%.*]] = icmp sle i32 [[I:%.*]], [[CONV]]
3651 ; CHECK-NEXT: ret i1 [[CMP]]
3653 %conv = fptosi float %x to i32
3654 %dec = sub nsw i32 %i, 1
3655 %cmp = icmp sgt i32 %conv, %dec
3659 define i1 @cmp_sle_rhs_dec(float %x, i32 %i) {
3660 ; CHECK-LABEL: @cmp_sle_rhs_dec(
3661 ; CHECK-NEXT: [[CONV:%.*]] = fptosi float [[X:%.*]] to i32
3662 ; CHECK-NEXT: [[CMP:%.*]] = icmp sgt i32 [[I:%.*]], [[CONV]]
3663 ; CHECK-NEXT: ret i1 [[CMP]]
3665 %conv = fptosi float %x to i32
3666 %dec = sub nsw i32 %i, 1
3667 %cmp = icmp sle i32 %conv, %dec
3671 define i1 @cmp_sge_rhs_inc(float %x, i32 %i) {
3672 ; CHECK-LABEL: @cmp_sge_rhs_inc(
3673 ; CHECK-NEXT: [[CONV:%.*]] = fptosi float [[X:%.*]] to i32
3674 ; CHECK-NEXT: [[CMP:%.*]] = icmp slt i32 [[I:%.*]], [[CONV]]
3675 ; CHECK-NEXT: ret i1 [[CMP]]
3677 %conv = fptosi float %x to i32
3678 %inc = add nsw i32 %i, 1
3679 %cmp = icmp sge i32 %conv, %inc
3683 define i1 @cmp_slt_rhs_inc(float %x, i32 %i) {
3684 ; CHECK-LABEL: @cmp_slt_rhs_inc(
3685 ; CHECK-NEXT: [[CONV:%.*]] = fptosi float [[X:%.*]] to i32
3686 ; CHECK-NEXT: [[CMP:%.*]] = icmp sge i32 [[I:%.*]], [[CONV]]
3687 ; CHECK-NEXT: ret i1 [[CMP]]
3689 %conv = fptosi float %x to i32
3690 %inc = add nsw i32 %i, 1
3691 %cmp = icmp slt i32 %conv, %inc
3695 define i1 @PR26407(i32 %x, i32 %y) {
3696 ; CHECK-LABEL: @PR26407(
3697 ; CHECK-NEXT: [[ADDX:%.*]] = add i32 [[X:%.*]], 2147483647
3698 ; CHECK-NEXT: [[ADDY:%.*]] = add i32 [[Y:%.*]], 2147483647
3699 ; CHECK-NEXT: [[CMP:%.*]] = icmp uge i32 [[ADDX]], [[ADDY]]
3700 ; CHECK-NEXT: ret i1 [[CMP]]
3702 %addx = add i32 %x, 2147483647
3703 %addy = add i32 %y, 2147483647
3704 %cmp = icmp uge i32 %addx, %addy
3708 define i1 @cmp_inverse_mask_bits_set_eq(i32 %x) {
3709 ; CHECK-LABEL: @cmp_inverse_mask_bits_set_eq(
3710 ; CHECK-NEXT: [[TMP1:%.*]] = and i32 [[X:%.*]], -43
3711 ; CHECK-NEXT: [[CMP:%.*]] = icmp eq i32 [[TMP1]], -43
3712 ; CHECK-NEXT: ret i1 [[CMP]]
3715 %cmp = icmp eq i32 %or, -1
3719 define <2 x i1> @cmp_inverse_mask_bits_set_eq_vec(<2 x i32> %x) {
3720 ; CHECK-LABEL: @cmp_inverse_mask_bits_set_eq_vec(
3721 ; CHECK-NEXT: [[TMP1:%.*]] = and <2 x i32> [[X:%.*]], splat (i32 -43)
3722 ; CHECK-NEXT: [[CMP:%.*]] = icmp eq <2 x i32> [[TMP1]], splat (i32 -43)
3723 ; CHECK-NEXT: ret <2 x i1> [[CMP]]
3725 %or = or <2 x i32> %x, <i32 42, i32 42>
3726 %cmp = icmp eq <2 x i32> %or, <i32 -1, i32 -1>
3730 define i1 @cmp_inverse_mask_bits_set_ne(i32 %x) {
3731 ; CHECK-LABEL: @cmp_inverse_mask_bits_set_ne(
3732 ; CHECK-NEXT: [[TMP1:%.*]] = and i32 [[X:%.*]], -43
3733 ; CHECK-NEXT: [[CMP:%.*]] = icmp ne i32 [[TMP1]], -43
3734 ; CHECK-NEXT: ret i1 [[CMP]]
3737 %cmp = icmp ne i32 %or, -1
3741 ; When canonicalizing to 'gt/lt', make sure the constant is correct.
3743 define i1 @PR27792(i128 %a) {
3744 ; CHECK-LABEL: @PR27792(
3745 ; CHECK-NEXT: [[CMP:%.*]] = icmp sgt i128 [[A:%.*]], -1
3746 ; CHECK-NEXT: ret i1 [[CMP]]
3748 %cmp = icmp sge i128 %a, 0
3752 define i1 @PR27792_2(i128 %a) {
3753 ; CHECK-LABEL: @PR27792_2(
3754 ; CHECK-NEXT: [[B:%.*]] = icmp ne i128 [[A:%.*]], 0
3755 ; CHECK-NEXT: ret i1 [[B]]
3757 %b = icmp uge i128 %a, 1
3761 define i1 @ugtMaxSignedVal(i8 %a) {
3762 ; CHECK-LABEL: @ugtMaxSignedVal(
3763 ; CHECK-NEXT: [[CMP:%.*]] = icmp slt i8 [[A:%.*]], 0
3764 ; CHECK-NEXT: ret i1 [[CMP]]
3766 %cmp = icmp ugt i8 %a, 127
3770 define <2 x i1> @ugtMaxSignedValVec(<2 x i8> %a) {
3771 ; CHECK-LABEL: @ugtMaxSignedValVec(
3772 ; CHECK-NEXT: [[CMP:%.*]] = icmp slt <2 x i8> [[A:%.*]], zeroinitializer
3773 ; CHECK-NEXT: ret <2 x i1> [[CMP]]
3775 %cmp = icmp ugt <2 x i8> %a, <i8 127, i8 127>
3779 define i1 @ugtKnownBits(i8 %a) {
3780 ; CHECK-LABEL: @ugtKnownBits(
3781 ; CHECK-NEXT: [[B:%.*]] = and i8 [[A:%.*]], 17
3782 ; CHECK-NEXT: [[CMP:%.*]] = icmp eq i8 [[B]], 17
3783 ; CHECK-NEXT: ret i1 [[CMP]]
3786 %cmp = icmp ugt i8 %b, 16
3790 define <2 x i1> @ugtKnownBitsVec(<2 x i8> %a) {
3791 ; CHECK-LABEL: @ugtKnownBitsVec(
3792 ; CHECK-NEXT: [[B:%.*]] = and <2 x i8> [[A:%.*]], splat (i8 17)
3793 ; CHECK-NEXT: [[CMP:%.*]] = icmp eq <2 x i8> [[B]], splat (i8 17)
3794 ; CHECK-NEXT: ret <2 x i1> [[CMP]]
3796 %b = and <2 x i8> %a, <i8 17, i8 17>
3797 %cmp = icmp ugt <2 x i8> %b, <i8 16, i8 16>
3801 define i1 @or_ptrtoint_mismatch(ptr %p, ptr %q) {
3802 ; CHECK-LABEL: @or_ptrtoint_mismatch(
3803 ; CHECK-NEXT: [[TMP1:%.*]] = icmp eq ptr [[P:%.*]], null
3804 ; CHECK-NEXT: [[TMP2:%.*]] = icmp eq ptr [[Q:%.*]], null
3805 ; CHECK-NEXT: [[B:%.*]] = and i1 [[TMP1]], [[TMP2]]
3806 ; CHECK-NEXT: ret i1 [[B]]
3809 %pp = ptrtoint ptr %p to i64
3810 %qq = ptrtoint ptr %q to i64
3811 %o = or i64 %pp, %qq
3812 %b = icmp eq i64 %o, 0
3816 define i1 @icmp_add1_ugt(i32 %x, i32 %y) {
3817 ; CHECK-LABEL: @icmp_add1_ugt(
3818 ; CHECK-NEXT: [[CMP:%.*]] = icmp uge i32 [[X:%.*]], [[Y:%.*]]
3819 ; CHECK-NEXT: ret i1 [[CMP]]
3821 %add = add nuw i32 %x, 1
3822 %cmp = icmp ugt i32 %add, %y
3826 define i1 @icmp_add1_ule(i32 %x, i32 %y) {
3827 ; CHECK-LABEL: @icmp_add1_ule(
3828 ; CHECK-NEXT: [[CMP:%.*]] = icmp ult i32 [[X:%.*]], [[Y:%.*]]
3829 ; CHECK-NEXT: ret i1 [[CMP]]
3831 %add = add nuw i32 %x, 1
3832 %cmp = icmp ule i32 %add, %y
3836 define i1 @cmp_uge_rhs_inc(float %x, i32 %i) {
3837 ; CHECK-LABEL: @cmp_uge_rhs_inc(
3838 ; CHECK-NEXT: [[CONV:%.*]] = fptosi float [[X:%.*]] to i32
3839 ; CHECK-NEXT: [[CMP:%.*]] = icmp ult i32 [[I:%.*]], [[CONV]]
3840 ; CHECK-NEXT: ret i1 [[CMP]]
3842 %conv = fptosi float %x to i32
3843 %inc = add nuw i32 %i, 1
3844 %cmp = icmp uge i32 %conv, %inc
3848 define i1 @cmp_ult_rhs_inc(float %x, i32 %i) {
3849 ; CHECK-LABEL: @cmp_ult_rhs_inc(
3850 ; CHECK-NEXT: [[CONV:%.*]] = fptosi float [[X:%.*]] to i32
3851 ; CHECK-NEXT: [[CMP:%.*]] = icmp uge i32 [[I:%.*]], [[CONV]]
3852 ; CHECK-NEXT: ret i1 [[CMP]]
3854 %conv = fptosi float %x to i32
3855 %inc = add nuw i32 %i, 1
3856 %cmp = icmp ult i32 %conv, %inc
3860 define i1 @cmp_sge_lhs_inc(i32 %x, i32 %y) {
3861 ; CHECK-LABEL: @cmp_sge_lhs_inc(
3862 ; CHECK-NEXT: [[INC:%.*]] = add nsw i32 [[X:%.*]], 1
3863 ; CHECK-NEXT: [[CMP:%.*]] = icmp sge i32 [[INC]], [[Y:%.*]]
3864 ; CHECK-NEXT: ret i1 [[CMP]]
3866 %inc = add nsw i32 %x, 1
3867 %cmp = icmp sge i32 %inc, %y
3871 define i1 @cmp_uge_lhs_inc(i32 %x, i32 %y) {
3872 ; CHECK-LABEL: @cmp_uge_lhs_inc(
3873 ; CHECK-NEXT: [[INC:%.*]] = add nuw i32 [[X:%.*]], 1
3874 ; CHECK-NEXT: [[CMP:%.*]] = icmp uge i32 [[INC]], [[Y:%.*]]
3875 ; CHECK-NEXT: ret i1 [[CMP]]
3877 %inc = add nuw i32 %x, 1
3878 %cmp = icmp uge i32 %inc, %y
3882 define i1 @cmp_sgt_lhs_dec(i32 %x, i32 %y) {
3883 ; CHECK-LABEL: @cmp_sgt_lhs_dec(
3884 ; CHECK-NEXT: [[DEC:%.*]] = add nsw i32 [[X:%.*]], -1
3885 ; CHECK-NEXT: [[CMP:%.*]] = icmp sgt i32 [[DEC]], [[Y:%.*]]
3886 ; CHECK-NEXT: ret i1 [[CMP]]
3888 %dec = sub nsw i32 %x, 1
3889 %cmp = icmp sgt i32 %dec, %y
3893 define i1 @cmp_ugt_lhs_dec(i32 %x, i32 %y) {
3894 ; CHECK-LABEL: @cmp_ugt_lhs_dec(
3895 ; CHECK-NEXT: [[DEC:%.*]] = add i32 [[X:%.*]], -1
3896 ; CHECK-NEXT: [[CMP:%.*]] = icmp ugt i32 [[DEC]], [[Y:%.*]]
3897 ; CHECK-NEXT: ret i1 [[CMP]]
3899 %dec = sub nuw i32 %x, 1
3900 %cmp = icmp ugt i32 %dec, %y
3904 define i1 @cmp_sle_rhs_inc(float %x, i32 %y) {
3905 ; CHECK-LABEL: @cmp_sle_rhs_inc(
3906 ; CHECK-NEXT: [[CONV:%.*]] = fptosi float [[X:%.*]] to i32
3907 ; CHECK-NEXT: [[INC:%.*]] = add nsw i32 [[Y:%.*]], 1
3908 ; CHECK-NEXT: [[CMP:%.*]] = icmp sge i32 [[INC]], [[CONV]]
3909 ; CHECK-NEXT: ret i1 [[CMP]]
3911 %conv = fptosi float %x to i32
3912 %inc = add nsw i32 %y, 1
3913 %cmp = icmp sle i32 %conv, %inc
3917 define i1 @cmp_ule_rhs_inc(float %x, i32 %y) {
3918 ; CHECK-LABEL: @cmp_ule_rhs_inc(
3919 ; CHECK-NEXT: [[CONV:%.*]] = fptosi float [[X:%.*]] to i32
3920 ; CHECK-NEXT: [[INC:%.*]] = add nuw i32 [[Y:%.*]], 1
3921 ; CHECK-NEXT: [[CMP:%.*]] = icmp uge i32 [[INC]], [[CONV]]
3922 ; CHECK-NEXT: ret i1 [[CMP]]
3924 %conv = fptosi float %x to i32
3925 %inc = add nuw i32 %y, 1
3926 %cmp = icmp ule i32 %conv, %inc
3930 define i1 @cmp_slt_rhs_dec(float %x, i32 %y) {
3931 ; CHECK-LABEL: @cmp_slt_rhs_dec(
3932 ; CHECK-NEXT: [[CONV:%.*]] = fptosi float [[X:%.*]] to i32
3933 ; CHECK-NEXT: [[DEC:%.*]] = add nsw i32 [[Y:%.*]], -1
3934 ; CHECK-NEXT: [[CMP:%.*]] = icmp sgt i32 [[DEC]], [[CONV]]
3935 ; CHECK-NEXT: ret i1 [[CMP]]
3937 %conv = fptosi float %x to i32
3938 %dec = sub nsw i32 %y, 1
3939 %cmp = icmp slt i32 %conv, %dec
3943 define i1 @cmp_ult_rhs_dec(float %x, i32 %y) {
3944 ; CHECK-LABEL: @cmp_ult_rhs_dec(
3945 ; CHECK-NEXT: [[CONV:%.*]] = fptosi float [[X:%.*]] to i32
3946 ; CHECK-NEXT: [[DEC:%.*]] = add i32 [[Y:%.*]], -1
3947 ; CHECK-NEXT: [[CMP:%.*]] = icmp ugt i32 [[DEC]], [[CONV]]
3948 ; CHECK-NEXT: ret i1 [[CMP]]
3950 %conv = fptosi float %x to i32
3951 %dec = sub nuw i32 %y, 1
3952 %cmp = icmp ult i32 %conv, %dec
3956 define i1 @eq_add_constants(i32 %x, i32 %y) {
3957 ; CHECK-LABEL: @eq_add_constants(
3958 ; CHECK-NEXT: [[C:%.*]] = icmp eq i32 [[X:%.*]], [[Y:%.*]]
3959 ; CHECK-NEXT: ret i1 [[C]]
3963 %C = icmp eq i32 %A, %B
3967 declare i32 @llvm.bswap.i32(i32)
3969 define i1 @bswap_ne(i32 %x, i32 %y) {
3970 ; CHECK-LABEL: @bswap_ne(
3971 ; CHECK-NEXT: [[CMP:%.*]] = icmp ne i32 [[X:%.*]], [[Y:%.*]]
3972 ; CHECK-NEXT: ret i1 [[CMP]]
3974 %swapx = call i32 @llvm.bswap.i32(i32 %x)
3975 %swapy = call i32 @llvm.bswap.i32(i32 %y)
3976 %cmp = icmp ne i32 %swapx, %swapy
3980 declare <8 x i16> @llvm.bswap.v8i16(<8 x i16>)
3982 define <8 x i1> @bswap_vec_eq(<8 x i16> %x, <8 x i16> %y) {
3983 ; CHECK-LABEL: @bswap_vec_eq(
3984 ; CHECK-NEXT: [[CMP:%.*]] = icmp eq <8 x i16> [[X:%.*]], [[Y:%.*]]
3985 ; CHECK-NEXT: ret <8 x i1> [[CMP]]
3987 %swapx = call <8 x i16> @llvm.bswap.v8i16(<8 x i16> %x)
3988 %swapy = call <8 x i16> @llvm.bswap.v8i16(<8 x i16> %y)
3989 %cmp = icmp eq <8 x i16> %swapx, %swapy
3993 declare i64 @llvm.bitreverse.i64(i64)
3995 define i1 @bitreverse_eq(i64 %x, i64 %y) {
3996 ; CHECK-LABEL: @bitreverse_eq(
3997 ; CHECK-NEXT: [[CMP:%.*]] = icmp eq i64 [[X:%.*]], [[Y:%.*]]
3998 ; CHECK-NEXT: ret i1 [[CMP]]
4000 %revx = call i64 @llvm.bitreverse.i64(i64 %x)
4001 %revy = call i64 @llvm.bitreverse.i64(i64 %y)
4002 %cmp = icmp eq i64 %revx, %revy
4006 declare <8 x i16> @llvm.bitreverse.v8i16(<8 x i16>)
4008 define <8 x i1> @bitreverse_vec_ne(<8 x i16> %x, <8 x i16> %y) {
4009 ; CHECK-LABEL: @bitreverse_vec_ne(
4010 ; CHECK-NEXT: [[CMP:%.*]] = icmp ne <8 x i16> [[X:%.*]], [[Y:%.*]]
4011 ; CHECK-NEXT: ret <8 x i1> [[CMP]]
4013 %revx = call <8 x i16> @llvm.bitreverse.v8i16(<8 x i16> %x)
4014 %revy = call <8 x i16> @llvm.bitreverse.v8i16(<8 x i16> %y)
4015 %cmp = icmp ne <8 x i16> %revx, %revy
4019 ; These perform a comparison of a value known to be between 4 and 5 with a value between 5 and 7.
4020 ; They should all simplify to equality compares.
4021 define i1 @knownbits1(i8 %a, i8 %b) {
4022 ; CHECK-LABEL: @knownbits1(
4023 ; CHECK-NEXT: [[A1:%.*]] = and i8 [[A:%.*]], 1
4024 ; CHECK-NEXT: [[B1:%.*]] = and i8 [[B:%.*]], 2
4025 ; CHECK-NEXT: [[TMP1:%.*]] = or disjoint i8 [[B1]], 1
4026 ; CHECK-NEXT: [[C:%.*]] = icmp eq i8 [[A1]], [[TMP1]]
4027 ; CHECK-NEXT: ret i1 [[C]]
4033 %c = icmp uge i8 %a2, %b2
4037 define i1 @knownbits2(i8 %a, i8 %b) {
4038 ; CHECK-LABEL: @knownbits2(
4039 ; CHECK-NEXT: [[A1:%.*]] = and i8 [[A:%.*]], 1
4040 ; CHECK-NEXT: [[B1:%.*]] = and i8 [[B:%.*]], 2
4041 ; CHECK-NEXT: [[TMP1:%.*]] = or disjoint i8 [[B1]], 1
4042 ; CHECK-NEXT: [[C:%.*]] = icmp ne i8 [[A1]], [[TMP1]]
4043 ; CHECK-NEXT: ret i1 [[C]]
4049 %c = icmp ult i8 %a2, %b2
4053 define i1 @knownbits3(i8 %a, i8 %b) {
4054 ; CHECK-LABEL: @knownbits3(
4055 ; CHECK-NEXT: [[A1:%.*]] = and i8 [[A:%.*]], 1
4056 ; CHECK-NEXT: [[B1:%.*]] = and i8 [[B:%.*]], 2
4057 ; CHECK-NEXT: [[TMP1:%.*]] = or disjoint i8 [[B1]], 1
4058 ; CHECK-NEXT: [[C:%.*]] = icmp eq i8 [[TMP1]], [[A1]]
4059 ; CHECK-NEXT: ret i1 [[C]]
4065 %c = icmp ule i8 %b2, %a2
4069 define <2 x i1> @knownbits4(<2 x i8> %a, <2 x i8> %b) {
4070 ; CHECK-LABEL: @knownbits4(
4071 ; CHECK-NEXT: [[A1:%.*]] = and <2 x i8> [[A:%.*]], splat (i8 1)
4072 ; CHECK-NEXT: [[B1:%.*]] = and <2 x i8> [[B:%.*]], splat (i8 2)
4073 ; CHECK-NEXT: [[TMP1:%.*]] = or disjoint <2 x i8> [[B1]], splat (i8 1)
4074 ; CHECK-NEXT: [[C:%.*]] = icmp ne <2 x i8> [[TMP1]], [[A1]]
4075 ; CHECK-NEXT: ret <2 x i1> [[C]]
4077 %a1 = and <2 x i8> %a, <i8 5, i8 5>
4078 %a2 = or <2 x i8> %a1, <i8 4, i8 4>
4079 %b1 = and <2 x i8> %b, <i8 7, i8 7>
4080 %b2 = or <2 x i8> %b1, <i8 5, i8 5>
4081 %c = icmp ugt <2 x i8> %b2, %a2
4085 ; These are the signed versions of the above. One value is less than or equal to 5, but maybe negative.
4086 ; The other is known to be a value 5-7. These should simplify to equality comparisons.
4087 define i1 @knownbits5(i8 %a, i8 %b) {
4088 ; CHECK-LABEL: @knownbits5(
4089 ; CHECK-NEXT: [[A1:%.*]] = and i8 [[A:%.*]], -127
4090 ; CHECK-NEXT: [[B1:%.*]] = and i8 [[B:%.*]], 2
4091 ; CHECK-NEXT: [[TMP1:%.*]] = or disjoint i8 [[B1]], 1
4092 ; CHECK-NEXT: [[C:%.*]] = icmp eq i8 [[A1]], [[TMP1]]
4093 ; CHECK-NEXT: ret i1 [[C]]
4095 %a1 = and i8 %a, 133
4099 %c = icmp sge i8 %a2, %b2
4103 define i1 @knownbits6(i8 %a, i8 %b) {
4104 ; CHECK-LABEL: @knownbits6(
4105 ; CHECK-NEXT: [[A1:%.*]] = and i8 [[A:%.*]], -127
4106 ; CHECK-NEXT: [[B1:%.*]] = and i8 [[B:%.*]], 2
4107 ; CHECK-NEXT: [[TMP1:%.*]] = or disjoint i8 [[B1]], 1
4108 ; CHECK-NEXT: [[C:%.*]] = icmp ne i8 [[A1]], [[TMP1]]
4109 ; CHECK-NEXT: ret i1 [[C]]
4111 %a1 = and i8 %a, 133
4115 %c = icmp slt i8 %a2, %b2
4119 define <2 x i1> @knownbits7(<2 x i8> %a, <2 x i8> %b) {
4120 ; CHECK-LABEL: @knownbits7(
4121 ; CHECK-NEXT: [[A1:%.*]] = and <2 x i8> [[A:%.*]], splat (i8 -127)
4122 ; CHECK-NEXT: [[B1:%.*]] = and <2 x i8> [[B:%.*]], splat (i8 2)
4123 ; CHECK-NEXT: [[TMP1:%.*]] = or disjoint <2 x i8> [[B1]], splat (i8 1)
4124 ; CHECK-NEXT: [[C:%.*]] = icmp eq <2 x i8> [[TMP1]], [[A1]]
4125 ; CHECK-NEXT: ret <2 x i1> [[C]]
4127 %a1 = and <2 x i8> %a, <i8 133, i8 133>
4128 %a2 = or <2 x i8> %a1, <i8 4, i8 4>
4129 %b1 = and <2 x i8> %b, <i8 7, i8 7>
4130 %b2 = or <2 x i8> %b1, <i8 5, i8 5>
4131 %c = icmp sle <2 x i8> %b2, %a2
4135 define i1 @knownbits8(i8 %a, i8 %b) {
4136 ; CHECK-LABEL: @knownbits8(
4137 ; CHECK-NEXT: [[A1:%.*]] = and i8 [[A:%.*]], -127
4138 ; CHECK-NEXT: [[B1:%.*]] = and i8 [[B:%.*]], 2
4139 ; CHECK-NEXT: [[TMP1:%.*]] = or disjoint i8 [[B1]], 1
4140 ; CHECK-NEXT: [[C:%.*]] = icmp ne i8 [[TMP1]], [[A1]]
4141 ; CHECK-NEXT: ret i1 [[C]]
4143 %a1 = and i8 %a, 133
4147 %c = icmp sgt i8 %b2, %a2
4151 ; Make sure InstCombine doesn't try too hard to simplify the icmp and break the abs idiom
4152 define i32 @abs_preserve(i32 %x) {
4153 ; CHECK-LABEL: @abs_preserve(
4154 ; CHECK-NEXT: [[A:%.*]] = shl nsw i32 [[X:%.*]], 1
4155 ; CHECK-NEXT: [[ABS:%.*]] = call i32 @llvm.abs.i32(i32 [[A]], i1 false)
4156 ; CHECK-NEXT: ret i32 [[ABS]]
4158 %a = mul nsw i32 %x, 2
4159 %c = icmp sge i32 %a, 0
4160 %nega = sub i32 0, %a
4161 %abs = select i1 %c, i32 %a, i32 %nega
4165 ; Don't crash by assuming the compared values are integers.
4167 declare void @llvm.assume(i1)
4168 define i1 @PR35794(ptr %a) {
4169 ; CHECK-LABEL: @PR35794(
4170 ; CHECK-NEXT: [[MASKCOND:%.*]] = icmp eq ptr [[A:%.*]], null
4171 ; CHECK-NEXT: tail call void @llvm.assume(i1 [[MASKCOND]])
4172 ; CHECK-NEXT: ret i1 true
4174 %cmp = icmp sgt ptr %a, inttoptr (i64 -1 to ptr)
4175 %maskcond = icmp eq ptr %a, null
4176 tail call void @llvm.assume(i1 %maskcond)
4180 ; Don't crash by assuming the compared values are integers.
4181 define <2 x i1> @PR36583(<2 x ptr>) {
4182 ; CHECK-LABEL: @PR36583(
4183 ; CHECK-NEXT: [[RES:%.*]] = icmp eq <2 x ptr> [[TMP0:%.*]], zeroinitializer
4184 ; CHECK-NEXT: ret <2 x i1> [[RES]]
4186 %cast = ptrtoint <2 x ptr> %0 to <2 x i64>
4187 %res = icmp eq <2 x i64> %cast, zeroinitializer
4191 ; fold (icmp pred (sub (0, X)) C1) for vec type
4192 define <2 x i32> @Op1Negated_Vec(<2 x i32> %x) {
4193 ; CHECK-LABEL: @Op1Negated_Vec(
4194 ; CHECK-NEXT: [[COND:%.*]] = call <2 x i32> @llvm.abs.v2i32(<2 x i32> [[X:%.*]], i1 true)
4195 ; CHECK-NEXT: ret <2 x i32> [[COND]]
4197 %sub = sub nsw <2 x i32> zeroinitializer, %x
4198 %cmp = icmp sgt <2 x i32> %sub, <i32 -1, i32 -1>
4199 %cond = select <2 x i1> %cmp, <2 x i32> %sub, <2 x i32> %x
4203 define i1 @signbit_bitcast_fpext(float %x) {
4204 ; CHECK-LABEL: @signbit_bitcast_fpext(
4205 ; CHECK-NEXT: [[TMP1:%.*]] = bitcast float [[X:%.*]] to i32
4206 ; CHECK-NEXT: [[R:%.*]] = icmp slt i32 [[TMP1]], 0
4207 ; CHECK-NEXT: ret i1 [[R]]
4209 %f = fpext float %x to double
4210 %b = bitcast double %f to i64
4211 %r = icmp slt i64 %b, 0
4215 define <2 x i1> @signbit_bitcast_fpext_vec(<2 x half> %x) {
4216 ; CHECK-LABEL: @signbit_bitcast_fpext_vec(
4217 ; CHECK-NEXT: [[TMP1:%.*]] = bitcast <2 x half> [[X:%.*]] to <2 x i16>
4218 ; CHECK-NEXT: [[R:%.*]] = icmp slt <2 x i16> [[TMP1]], zeroinitializer
4219 ; CHECK-NEXT: ret <2 x i1> [[R]]
4221 %f = fpext <2 x half> %x to <2 x float>
4222 %b = bitcast <2 x float> %f to <2 x i32>
4223 %r = icmp ugt <2 x i32> %b, <i32 2147483647, i32 2147483647>
4227 define i1 @signbit_bitcast_fptrunc(float %x) {
4228 ; CHECK-LABEL: @signbit_bitcast_fptrunc(
4229 ; CHECK-NEXT: [[TMP1:%.*]] = bitcast float [[X:%.*]] to i32
4230 ; CHECK-NEXT: [[R:%.*]] = icmp sgt i32 [[TMP1]], -1
4231 ; CHECK-NEXT: ret i1 [[R]]
4233 %f = fptrunc float %x to half
4234 %b = bitcast half %f to i16
4235 %r = icmp ult i16 %b, 32768
4239 define <2 x i1> @signbit_bitcast_fptrunc_vec(<2 x double> %x) {
4240 ; CHECK-LABEL: @signbit_bitcast_fptrunc_vec(
4241 ; CHECK-NEXT: [[TMP1:%.*]] = bitcast <2 x double> [[X:%.*]] to <2 x i64>
4242 ; CHECK-NEXT: [[R:%.*]] = icmp sgt <2 x i64> [[TMP1]], splat (i64 -1)
4243 ; CHECK-NEXT: ret <2 x i1> [[R]]
4245 %f = fptrunc <2 x double> %x to <2 x half>
4246 %b = bitcast <2 x half> %f to <2 x i16>
4247 %r = icmp sge <2 x i16> %b, zeroinitializer
4251 define i1 @signbit_bitcast_fpext_wrong_cmp(float %x) {
4252 ; CHECK-LABEL: @signbit_bitcast_fpext_wrong_cmp(
4253 ; CHECK-NEXT: [[F:%.*]] = fpext float [[X:%.*]] to double
4254 ; CHECK-NEXT: [[B:%.*]] = bitcast double [[F]] to i64
4255 ; CHECK-NEXT: [[R:%.*]] = icmp slt i64 [[B]], 1
4256 ; CHECK-NEXT: ret i1 [[R]]
4258 %f = fpext float %x to double
4259 %b = bitcast double %f to i64
4260 %r = icmp slt i64 %b, 1
4264 define <4 x i1> @signbit_bitcast_fpext_vec_wrong_bitcast(<2 x half> %x) {
4265 ; CHECK-LABEL: @signbit_bitcast_fpext_vec_wrong_bitcast(
4266 ; CHECK-NEXT: [[F:%.*]] = fpext <2 x half> [[X:%.*]] to <2 x float>
4267 ; CHECK-NEXT: [[B:%.*]] = bitcast <2 x float> [[F]] to <4 x i16>
4268 ; CHECK-NEXT: [[R:%.*]] = icmp sgt <4 x i16> [[B]], splat (i16 -1)
4269 ; CHECK-NEXT: ret <4 x i1> [[R]]
4271 %f = fpext <2 x half> %x to <2 x float>
4272 %b = bitcast <2 x float> %f to <4 x i16>
4273 %r = icmp sgt <4 x i16> %b, <i16 -1, i16 -1, i16 -1, i16 -1>
4277 define i1 @signbit_bitcast_fpext_extra_use(float %x, ptr %p) {
4278 ; CHECK-LABEL: @signbit_bitcast_fpext_extra_use(
4279 ; CHECK-NEXT: [[F:%.*]] = fpext float [[X:%.*]] to double
4280 ; CHECK-NEXT: [[B:%.*]] = bitcast double [[F]] to i64
4281 ; CHECK-NEXT: call void @use_i64(i64 [[B]])
4282 ; CHECK-NEXT: [[R:%.*]] = icmp slt i64 [[B]], 0
4283 ; CHECK-NEXT: ret i1 [[R]]
4285 %f = fpext float %x to double
4286 %b = bitcast double %f to i64
4287 call void @use_i64(i64 %b)
4288 %r = icmp slt i64 %b, 0
4292 define i1 @signbit_bitcast_fpext_ppc_fp128(float %x) {
4293 ; CHECK-LABEL: @signbit_bitcast_fpext_ppc_fp128(
4294 ; CHECK-NEXT: [[S2:%.*]] = fpext float [[X:%.*]] to ppc_fp128
4295 ; CHECK-NEXT: [[S3:%.*]] = bitcast ppc_fp128 [[S2]] to i128
4296 ; CHECK-NEXT: [[S4:%.*]] = icmp slt i128 [[S3]], 0
4297 ; CHECK-NEXT: ret i1 [[S4]]
4299 %s2 = fpext float %x to ppc_fp128
4300 %s3 = bitcast ppc_fp128 %s2 to i128
4301 %s4 = icmp slt i128 %s3, 0
4305 define i1 @signbit_bitcast_fptrunc_ppc_fp128(ppc_fp128 %x) {
4306 ; CHECK-LABEL: @signbit_bitcast_fptrunc_ppc_fp128(
4307 ; CHECK-NEXT: [[S2:%.*]] = fptrunc ppc_fp128 [[X:%.*]] to float
4308 ; CHECK-NEXT: [[S3:%.*]] = bitcast float [[S2]] to i32
4309 ; CHECK-NEXT: [[S4:%.*]] = icmp slt i32 [[S3]], 0
4310 ; CHECK-NEXT: ret i1 [[S4]]
4312 %s2 = fptrunc ppc_fp128 %x to float
4313 %s3 = bitcast float %s2 to i32
4314 %s4 = icmp slt i32 %s3, 0
4318 @x = external dso_local local_unnamed_addr global i32, align 4
4319 @y = external dso_local local_unnamed_addr global i32, align 4
4320 define i1 @pr47997(i32 %arg) {
4321 ; CHECK-LABEL: @pr47997(
4323 ; CHECK-NEXT: [[I:%.*]] = add nsw i32 [[ARG:%.*]], -1
4324 ; CHECK-NEXT: store i32 [[I]], ptr @x, align 4
4325 ; CHECK-NEXT: [[I1:%.*]] = sub nsw i32 1, [[ARG]]
4326 ; CHECK-NEXT: store i32 [[I1]], ptr @y, align 4
4327 ; CHECK-NEXT: ret i1 true
4330 %i = add nsw i32 %arg, -1
4331 store i32 %i, ptr @x
4332 %i1 = sub nsw i32 1, %arg
4333 store i32 %i1, ptr @y
4334 %i2 = sub nsw i32 0, %i1
4335 %i3 = icmp eq i32 %i, %i2
4341 define i1 @thread_cmp_over_select_with_poison_trueval(i1 %b) {
4342 ; CHECK-LABEL: @thread_cmp_over_select_with_poison_trueval(
4343 ; CHECK-NEXT: ret i1 false
4345 %s = select i1 %b, i32 poison, i32 0
4346 %tobool = icmp ne i32 %s, 0
4350 define i1 @thread_cmp_over_select_with_poison_falseval(i1 %b) {
4351 ; CHECK-LABEL: @thread_cmp_over_select_with_poison_falseval(
4352 ; CHECK-NEXT: ret i1 true
4354 %s = select i1 %b, i32 1, i32 poison
4355 %tobool = icmp ne i32 %s, 0
4359 define i1 @signbit_true_logic(i8 %x) {
4360 ; CHECK-LABEL: @signbit_true_logic(
4361 ; CHECK-NEXT: [[R:%.*]] = icmp eq i8 [[X:%.*]], 0
4362 ; CHECK-NEXT: ret i1 [[R]]
4364 %dec = add i8 %x, -1
4365 %not = xor i8 %x, -1
4366 %and = and i8 %dec, %not
4367 %r = icmp slt i8 %and, 0
4371 define <2 x i1> @signbit_false_logic(<2 x i5> %x) {
4372 ; CHECK-LABEL: @signbit_false_logic(
4373 ; CHECK-NEXT: [[R:%.*]] = icmp ne <2 x i5> [[X:%.*]], zeroinitializer
4374 ; CHECK-NEXT: ret <2 x i1> [[R]]
4376 %dec = add <2 x i5> %x, <i5 -1, i5 poison>
4377 %not = xor <2 x i5> %x, <i5 -1, i5 -1>
4378 %and = and <2 x i5> %dec, %not
4379 %r = icmp sgt <2 x i5> %and, <i5 -1, i5 -1>
4383 ; Confirm that complexity canonicalization works for commuted pattern.
4385 define i1 @signbit_true_logic_uses_commute(i64 %x) {
4386 ; CHECK-LABEL: @signbit_true_logic_uses_commute(
4387 ; CHECK-NEXT: [[DEC:%.*]] = add i64 [[X:%.*]], -1
4388 ; CHECK-NEXT: call void @use_i64(i64 [[DEC]])
4389 ; CHECK-NEXT: [[NOT:%.*]] = xor i64 [[X]], -1
4390 ; CHECK-NEXT: call void @use_i64(i64 [[NOT]])
4391 ; CHECK-NEXT: [[AND:%.*]] = and i64 [[DEC]], [[NOT]]
4392 ; CHECK-NEXT: call void @use_i64(i64 [[AND]])
4393 ; CHECK-NEXT: [[R:%.*]] = icmp eq i64 [[X]], 0
4394 ; CHECK-NEXT: ret i1 [[R]]
4396 %dec = add i64 %x, -1
4397 call void @use_i64(i64 %dec)
4398 %not = xor i64 %x, -1
4399 call void @use_i64(i64 %not)
4400 %and = and i64 %not, %dec
4401 call void @use_i64(i64 %and)
4402 %r = icmp slt i64 %and, 0
4406 define i1 @redundant_sign_bit_count_ult_1_2(i32 %x) {
4407 ; CHECK-LABEL: @redundant_sign_bit_count_ult_1_2(
4408 ; CHECK-NEXT: [[TMP1:%.*]] = add i32 [[X:%.*]], 4
4409 ; CHECK-NEXT: [[C:%.*]] = icmp ult i32 [[TMP1]], 8
4410 ; CHECK-NEXT: ret i1 [[C]]
4414 %c = icmp ult i32 %z, 4
4418 define i1 @redundant_sign_bit_count_ult_1_30(i32 %x) {
4419 ; CHECK-LABEL: @redundant_sign_bit_count_ult_1_30(
4420 ; CHECK-NEXT: [[TMP1:%.*]] = add i32 [[X:%.*]], 1073741824
4421 ; CHECK-NEXT: [[C:%.*]] = icmp sgt i32 [[TMP1]], -1
4422 ; CHECK-NEXT: ret i1 [[C]]
4426 %c = icmp ult i32 %z, 1073741824
4430 define i1 @redundant_sign_bit_count_ult_31_2(i32 %x) {
4431 ; CHECK-LABEL: @redundant_sign_bit_count_ult_31_2(
4432 ; CHECK-NEXT: [[TMP1:%.*]] = add i32 [[X:%.*]], 4
4433 ; CHECK-NEXT: [[C:%.*]] = icmp ult i32 [[TMP1]], 8
4434 ; CHECK-NEXT: ret i1 [[C]]
4436 %y = ashr i32 %x, 31
4438 %c = icmp ult i32 %z, 4
4442 define i1 @redundant_sign_bit_count_ult_31_30(i32 %x) {
4443 ; CHECK-LABEL: @redundant_sign_bit_count_ult_31_30(
4444 ; CHECK-NEXT: [[TMP1:%.*]] = add i32 [[X:%.*]], 1073741824
4445 ; CHECK-NEXT: [[C:%.*]] = icmp sgt i32 [[TMP1]], -1
4446 ; CHECK-NEXT: ret i1 [[C]]
4448 %y = ashr i32 %x, 31
4450 %c = icmp ult i32 %z, 1073741824
4454 define i1 @redundant_sign_bit_count_ult_31_30_extra_use_ashr(i32 %x) {
4455 ; CHECK-LABEL: @redundant_sign_bit_count_ult_31_30_extra_use_ashr(
4456 ; CHECK-NEXT: [[Y:%.*]] = ashr i32 [[X:%.*]], 31
4457 ; CHECK-NEXT: call void @use_i32(i32 [[Y]])
4458 ; CHECK-NEXT: [[TMP1:%.*]] = add i32 [[X]], 1073741824
4459 ; CHECK-NEXT: [[C:%.*]] = icmp sgt i32 [[TMP1]], -1
4460 ; CHECK-NEXT: ret i1 [[C]]
4462 %y = ashr i32 %x, 31
4463 call void @use_i32(i32 %y)
4465 %c = icmp ult i32 %z, 1073741824
4469 define i1 @redundant_sign_bit_count_ult_31_30_extra_use_xor(i32 %x) {
4470 ; CHECK-LABEL: @redundant_sign_bit_count_ult_31_30_extra_use_xor(
4471 ; CHECK-NEXT: [[Y:%.*]] = ashr i32 [[X:%.*]], 31
4472 ; CHECK-NEXT: [[Z:%.*]] = xor i32 [[Y]], [[X]]
4473 ; CHECK-NEXT: call void @use_i32(i32 [[Z]])
4474 ; CHECK-NEXT: [[C:%.*]] = icmp ult i32 [[Z]], 1073741824
4475 ; CHECK-NEXT: ret i1 [[C]]
4477 %y = ashr i32 %x, 31
4479 call void @use_i32(i32 %z)
4480 %c = icmp ult i32 %z, 1073741824
4484 define i1 @not_redundant_sign_bit_count_ult(i32 %w, i32 %x) {
4485 ; CHECK-LABEL: @not_redundant_sign_bit_count_ult(
4486 ; CHECK-NEXT: [[Y:%.*]] = ashr i32 [[X:%.*]], 31
4487 ; CHECK-NEXT: [[Z:%.*]] = xor i32 [[Y]], [[W:%.*]]
4488 ; CHECK-NEXT: [[C:%.*]] = icmp ult i32 [[Z]], 1073741824
4489 ; CHECK-NEXT: ret i1 [[C]]
4491 %y = ashr i32 %x, 31
4493 %c = icmp ult i32 %z, 1073741824
4497 define i1 @wrong_shift_opcode_i8(i8 %x) {
4498 ; CHECK-LABEL: @wrong_shift_opcode_i8(
4499 ; CHECK-NEXT: [[Y:%.*]] = lshr i8 [[X:%.*]], 5
4500 ; CHECK-NEXT: [[Z:%.*]] = xor i8 [[Y]], [[X]]
4501 ; CHECK-NEXT: [[C:%.*]] = icmp ult i8 [[Z]], 2
4502 ; CHECK-NEXT: ret i1 [[C]]
4506 %c = icmp ult i8 %z, 2
4510 define i1 @redundant_sign_bit_count_ult_31_30_commute(i32 %xsrc) {
4511 ; CHECK-LABEL: @redundant_sign_bit_count_ult_31_30_commute(
4512 ; CHECK-NEXT: [[X:%.*]] = mul i32 [[XSRC:%.*]], 13
4513 ; CHECK-NEXT: [[TMP1:%.*]] = add i32 [[X]], 1073741824
4514 ; CHECK-NEXT: [[C:%.*]] = icmp sgt i32 [[TMP1]], -1
4515 ; CHECK-NEXT: ret i1 [[C]]
4517 %x = mul i32 %xsrc, 13 ; thwart complexity-based canonicalization
4518 %y = ashr i32 %x, 31
4520 %c = icmp ult i32 %z, 1073741824
4524 define i1 @redundant_sign_bit_count_i8(i8 %x) {
4525 ; CHECK-LABEL: @redundant_sign_bit_count_i8(
4526 ; CHECK-NEXT: [[TMP1:%.*]] = add i8 [[X:%.*]], 2
4527 ; CHECK-NEXT: [[C:%.*]] = icmp ult i8 [[TMP1]], 4
4528 ; CHECK-NEXT: ret i1 [[C]]
4532 %c = icmp ult i8 %z, 2
4536 define <2 x i1> @redundant_sign_bit_count_ult_31_30_vector(<2 x i32> %xsrc) {
4537 ; CHECK-LABEL: @redundant_sign_bit_count_ult_31_30_vector(
4538 ; CHECK-NEXT: [[X:%.*]] = mul <2 x i32> [[XSRC:%.*]], splat (i32 13)
4539 ; CHECK-NEXT: [[TMP1:%.*]] = add <2 x i32> [[X]], splat (i32 1073741824)
4540 ; CHECK-NEXT: [[C:%.*]] = icmp sgt <2 x i32> [[TMP1]], splat (i32 -1)
4541 ; CHECK-NEXT: ret <2 x i1> [[C]]
4543 %x = mul <2 x i32> %xsrc, <i32 13, i32 13> ; thwart complexity-based canonicalization
4544 %y = ashr <2 x i32> %x, <i32 31, i32 31>
4545 %z = xor <2 x i32> %x, %y
4546 %c = icmp ult <2 x i32> %z, <i32 1073741824, i32 1073741824>
4550 define i1 @redundant_sign_bit_count_ugt_1_2(i32 %x) {
4551 ; CHECK-LABEL: @redundant_sign_bit_count_ugt_1_2(
4552 ; CHECK-NEXT: [[TMP1:%.*]] = add i32 [[X:%.*]], -4
4553 ; CHECK-NEXT: [[C:%.*]] = icmp ult i32 [[TMP1]], -8
4554 ; CHECK-NEXT: ret i1 [[C]]
4558 %c = icmp ugt i32 %z, 3
4562 define i1 @redundant_sign_bit_count_ugt_1_30(i32 %x) {
4563 ; CHECK-LABEL: @redundant_sign_bit_count_ugt_1_30(
4564 ; CHECK-NEXT: [[TMP1:%.*]] = add i32 [[X:%.*]], 1073741824
4565 ; CHECK-NEXT: [[C:%.*]] = icmp slt i32 [[TMP1]], 0
4566 ; CHECK-NEXT: ret i1 [[C]]
4570 %c = icmp ugt i32 %z, 1073741823
4574 define i1 @redundant_sign_bit_count_ugt_31_2(i32 %x) {
4575 ; CHECK-LABEL: @redundant_sign_bit_count_ugt_31_2(
4576 ; CHECK-NEXT: [[TMP1:%.*]] = add i32 [[X:%.*]], -4
4577 ; CHECK-NEXT: [[C:%.*]] = icmp ult i32 [[TMP1]], -8
4578 ; CHECK-NEXT: ret i1 [[C]]
4580 %y = ashr i32 %x, 31
4582 %c = icmp ugt i32 %z, 3
4586 define i1 @redundant_sign_bit_count_ugt_31_30(i32 %x) {
4587 ; CHECK-LABEL: @redundant_sign_bit_count_ugt_31_30(
4588 ; CHECK-NEXT: [[TMP1:%.*]] = add i32 [[X:%.*]], 1073741824
4589 ; CHECK-NEXT: [[C:%.*]] = icmp slt i32 [[TMP1]], 0
4590 ; CHECK-NEXT: ret i1 [[C]]
4592 %y = ashr i32 %x, 31
4594 %c = icmp ugt i32 %z, 1073741823
4598 define i1 @zext_bool_and_eq0(i1 %x, i8 %y) {
4599 ; CHECK-LABEL: @zext_bool_and_eq0(
4600 ; CHECK-NEXT: [[TMP1:%.*]] = and i8 [[Y:%.*]], 1
4601 ; CHECK-NEXT: [[R1:%.*]] = icmp eq i8 [[TMP1]], 0
4602 ; CHECK-NEXT: [[NOT_X:%.*]] = xor i1 [[X:%.*]], true
4603 ; CHECK-NEXT: [[R:%.*]] = select i1 [[NOT_X]], i1 true, i1 [[R1]]
4604 ; CHECK-NEXT: ret i1 [[R]]
4606 %zx = zext i1 %x to i8
4608 %r = icmp eq i8 %a, 0
4612 define <2 x i1> @zext_bool_and_eq0_commute(<2 x i1> %x, <2 x i8> %p) {
4613 ; CHECK-LABEL: @zext_bool_and_eq0_commute(
4614 ; CHECK-NEXT: [[TMP1:%.*]] = and <2 x i8> [[P:%.*]], splat (i8 1)
4615 ; CHECK-NEXT: [[R1:%.*]] = icmp eq <2 x i8> [[TMP1]], zeroinitializer
4616 ; CHECK-NEXT: [[NOT_X:%.*]] = xor <2 x i1> [[X:%.*]], splat (i1 true)
4617 ; CHECK-NEXT: [[R:%.*]] = select <2 x i1> [[NOT_X]], <2 x i1> splat (i1 true), <2 x i1> [[R1]]
4618 ; CHECK-NEXT: ret <2 x i1> [[R]]
4620 %y = mul <2 x i8> %p, %p ; thwart complexity-based canonicalization
4621 %zx = zext <2 x i1> %x to <2 x i8>
4622 %a = and <2 x i8> %y, %zx
4623 %r = icmp eq <2 x i8> %a, zeroinitializer
4627 define i1 @zext_bool_and_ne0(i1 %x, i8 %y) {
4628 ; CHECK-LABEL: @zext_bool_and_ne0(
4629 ; CHECK-NEXT: [[TMP1:%.*]] = and i8 [[Y:%.*]], 1
4630 ; CHECK-NEXT: [[R1:%.*]] = icmp ne i8 [[TMP1]], 0
4631 ; CHECK-NEXT: [[R:%.*]] = select i1 [[X:%.*]], i1 [[R1]], i1 false
4632 ; CHECK-NEXT: ret i1 [[R]]
4634 %zx = zext i1 %x to i8
4636 %r = icmp ne i8 %a, 0
4640 define i1 @zext_bool_and_ne1(i1 %x, i8 %y) {
4641 ; CHECK-LABEL: @zext_bool_and_ne1(
4642 ; CHECK-NEXT: [[TMP1:%.*]] = and i8 [[Y:%.*]], 1
4643 ; CHECK-NEXT: [[R1:%.*]] = icmp eq i8 [[TMP1]], 0
4644 ; CHECK-NEXT: [[NOT_X:%.*]] = xor i1 [[X:%.*]], true
4645 ; CHECK-NEXT: [[R:%.*]] = select i1 [[NOT_X]], i1 true, i1 [[R1]]
4646 ; CHECK-NEXT: ret i1 [[R]]
4648 %zx = zext i1 %x to i8
4650 %r = icmp ne i8 %a, 1
4654 define <2 x i1> @zext_bool_and_eq1(<2 x i1> %x, <2 x i8> %y) {
4655 ; CHECK-LABEL: @zext_bool_and_eq1(
4656 ; CHECK-NEXT: [[R1:%.*]] = trunc <2 x i8> [[Y:%.*]] to <2 x i1>
4657 ; CHECK-NEXT: [[R:%.*]] = select <2 x i1> [[X:%.*]], <2 x i1> [[R1]], <2 x i1> zeroinitializer
4658 ; CHECK-NEXT: ret <2 x i1> [[R]]
4660 %zx = zext <2 x i1> %x to <2 x i8>
4661 %a = and <2 x i8> %zx, %y
4662 %r = icmp eq <2 x i8> %a, <i8 1, i8 1>
4666 ; negative test - wrong logic op
4668 define i1 @zext_bool_or_eq0(i1 %x, i8 %y) {
4669 ; CHECK-LABEL: @zext_bool_or_eq0(
4670 ; CHECK-NEXT: [[ZX:%.*]] = zext i1 [[X:%.*]] to i8
4671 ; CHECK-NEXT: [[A:%.*]] = or i8 [[Y:%.*]], [[ZX]]
4672 ; CHECK-NEXT: [[R:%.*]] = icmp eq i8 [[A]], 0
4673 ; CHECK-NEXT: ret i1 [[R]]
4675 %zx = zext i1 %x to i8
4677 %r = icmp eq i8 %a, 0
4681 ; negative test - extra use
4683 define i1 @zext_bool_and_eq0_use(i1 %x, i64 %y) {
4684 ; CHECK-LABEL: @zext_bool_and_eq0_use(
4685 ; CHECK-NEXT: [[ZX:%.*]] = zext i1 [[X:%.*]] to i64
4686 ; CHECK-NEXT: call void @use_i64(i64 [[ZX]])
4687 ; CHECK-NEXT: [[A:%.*]] = and i64 [[Y:%.*]], [[ZX]]
4688 ; CHECK-NEXT: [[R:%.*]] = icmp eq i64 [[A]], 0
4689 ; CHECK-NEXT: ret i1 [[R]]
4691 %zx = zext i1 %x to i64
4692 call void @use_i64(i64 %zx)
4693 %a = and i64 %zx, %y
4694 %r = icmp eq i64 %a, 0
4698 ; negative test - extra use
4700 define i1 @zext_bool_and_ne0_use(i1 %x, i64 %y) {
4701 ; CHECK-LABEL: @zext_bool_and_ne0_use(
4702 ; CHECK-NEXT: [[TMP1:%.*]] = and i64 [[Y:%.*]], 1
4703 ; CHECK-NEXT: [[A:%.*]] = select i1 [[X:%.*]], i64 [[TMP1]], i64 0
4704 ; CHECK-NEXT: call void @use_i64(i64 [[A]])
4705 ; CHECK-NEXT: [[R:%.*]] = icmp ne i64 [[A]], 0
4706 ; CHECK-NEXT: ret i1 [[R]]
4708 %zx = zext i1 %x to i64
4709 %a = and i64 %zx, %y
4710 call void @use_i64(i64 %a)
4711 %r = icmp ne i64 %a, 0
4715 ; negative test - must zext from i1
4717 define i1 @zext_notbool_and_ne0(i2 %x, i8 %y) {
4718 ; CHECK-LABEL: @zext_notbool_and_ne0(
4719 ; CHECK-NEXT: [[ZX:%.*]] = zext i2 [[X:%.*]] to i8
4720 ; CHECK-NEXT: [[A:%.*]] = and i8 [[Y:%.*]], [[ZX]]
4721 ; CHECK-NEXT: [[R:%.*]] = icmp ne i8 [[A]], 0
4722 ; CHECK-NEXT: ret i1 [[R]]
4724 %zx = zext i2 %x to i8
4726 %r = icmp ne i8 %a, 0
4730 ; fold icmp(X | OrC, C) --> icmp(X, 0)
4732 define i1 @or_positive_sgt_zero(i8 %a) {
4733 ; CHECK-LABEL: @or_positive_sgt_zero(
4734 ; CHECK-NEXT: [[CMP:%.*]] = icmp sgt i8 [[A:%.*]], -1
4735 ; CHECK-NEXT: ret i1 [[CMP]]
4738 %cmp = icmp sgt i8 %b, 0
4742 define <2 x i1> @or_postive_sgt_zero_vec(<2 x i8> %a) {
4743 ; CHECK-LABEL: @or_postive_sgt_zero_vec(
4744 ; CHECK-NEXT: [[CMP:%.*]] = icmp sgt <2 x i8> [[A:%.*]], splat (i8 -1)
4745 ; CHECK-NEXT: ret <2 x i1> [[CMP]]
4748 %b = or <2 x i8> %a, <i8 24, i8 24>
4749 %cmp = icmp sgt <2 x i8> %b, <i8 0, i8 0>
4753 define <2 x i1> @or_poison_vec_sgt_zero_vec(<2 x i8> %a) {
4754 ; CHECK-LABEL: @or_poison_vec_sgt_zero_vec(
4755 ; CHECK-NEXT: ret <2 x i1> poison
4758 %b = or <2 x i8> %a, <i8 poison, i8 poison>
4759 %cmp = icmp sgt <2 x i8> %b, <i8 0, i8 0>
4763 define i1 @or_positive_sge_zero(i8 %a) {
4764 ; CHECK-LABEL: @or_positive_sge_zero(
4765 ; CHECK-NEXT: [[CMP:%.*]] = icmp sgt i8 [[A:%.*]], -1
4766 ; CHECK-NEXT: ret i1 [[CMP]]
4769 %cmp = icmp sge i8 %b, 0
4773 define <2 x i1> @or_postive_sge_zero_vec(<2 x i8> %a) {
4774 ; CHECK-LABEL: @or_postive_sge_zero_vec(
4775 ; CHECK-NEXT: [[CMP:%.*]] = icmp sgt <2 x i8> [[A:%.*]], splat (i8 -1)
4776 ; CHECK-NEXT: ret <2 x i1> [[CMP]]
4779 %b = or <2 x i8> %a, <i8 24, i8 24>
4780 %cmp = icmp sge <2 x i8> %b, <i8 0, i8 0>
4784 define <2 x i1> @or_poison_vec_sge_zero_vec(<2 x i8> %a) {
4785 ; CHECK-LABEL: @or_poison_vec_sge_zero_vec(
4786 ; CHECK-NEXT: ret <2 x i1> poison
4789 %b = or <2 x i8> %a, <i8 poison, i8 poison>
4790 %cmp = icmp sge <2 x i8> %b, <i8 0, i8 0>
4794 define i1 @or_positive_sge_postive(i8 %a) {
4795 ; CHECK-LABEL: @or_positive_sge_postive(
4796 ; CHECK-NEXT: [[CMP:%.*]] = icmp sgt i8 [[A:%.*]], -1
4797 ; CHECK-NEXT: ret i1 [[CMP]]
4800 %cmp = icmp sge i8 %b, 24
4804 define <2 x i1> @or_postive_sge_positive_vec(<2 x i8> %a) {
4805 ; CHECK-LABEL: @or_postive_sge_positive_vec(
4806 ; CHECK-NEXT: [[CMP:%.*]] = icmp sgt <2 x i8> [[A:%.*]], splat (i8 -1)
4807 ; CHECK-NEXT: ret <2 x i1> [[CMP]]
4810 %b = or <2 x i8> %a, <i8 24, i8 24>
4811 %cmp = icmp sge <2 x i8> %b, <i8 24, i8 24>
4815 define <2 x i1> @or_poison_vec_sge_positive_vec(<2 x i8> %a) {
4816 ; CHECK-LABEL: @or_poison_vec_sge_positive_vec(
4817 ; CHECK-NEXT: ret <2 x i1> poison
4820 %b = or <2 x i8> %a, <i8 poison, i8 poison>
4821 %cmp = icmp sge <2 x i8> %b, <i8 24, i8 24>
4825 define i1 @or_positive_sle_zero(i8 %a) {
4826 ; CHECK-LABEL: @or_positive_sle_zero(
4827 ; CHECK-NEXT: [[CMP:%.*]] = icmp slt i8 [[A:%.*]], 0
4828 ; CHECK-NEXT: ret i1 [[CMP]]
4831 %cmp = icmp sle i8 %b, 0
4835 define <2 x i1> @or_postive_sle_zero_vec(<2 x i8> %a) {
4836 ; CHECK-LABEL: @or_postive_sle_zero_vec(
4837 ; CHECK-NEXT: [[CMP:%.*]] = icmp slt <2 x i8> [[A:%.*]], zeroinitializer
4838 ; CHECK-NEXT: ret <2 x i1> [[CMP]]
4841 %b = or <2 x i8> %a, <i8 24, i8 24>
4842 %cmp = icmp sle <2 x i8> %b, <i8 0, i8 0>
4846 define <2 x i1> @or_poison_vec_sle_zero_vec(<2 x i8> %a) {
4847 ; CHECK-LABEL: @or_poison_vec_sle_zero_vec(
4848 ; CHECK-NEXT: ret <2 x i1> poison
4851 %b = or <2 x i8> %a, <i8 poison, i8 poison>
4852 %cmp = icmp sle <2 x i8> %b, <i8 0, i8 0>
4856 define i1 @or_positive_slt_zero(i8 %a) {
4857 ; CHECK-LABEL: @or_positive_slt_zero(
4858 ; CHECK-NEXT: [[CMP:%.*]] = icmp slt i8 [[A:%.*]], 0
4859 ; CHECK-NEXT: ret i1 [[CMP]]
4862 %cmp = icmp slt i8 %b, 0
4866 define <2 x i1> @or_postive_slt_zero_vec(<2 x i8> %a) {
4867 ; CHECK-LABEL: @or_postive_slt_zero_vec(
4868 ; CHECK-NEXT: [[CMP:%.*]] = icmp slt <2 x i8> [[A:%.*]], zeroinitializer
4869 ; CHECK-NEXT: ret <2 x i1> [[CMP]]
4872 %b = or <2 x i8> %a, <i8 24, i8 24>
4873 %cmp = icmp slt <2 x i8> %b, <i8 0, i8 0>
4877 define <2 x i1> @or_poison_vec_slt_zero_vec(<2 x i8> %a) {
4878 ; CHECK-LABEL: @or_poison_vec_slt_zero_vec(
4879 ; CHECK-NEXT: ret <2 x i1> poison
4882 %b = or <2 x i8> %a, <i8 poison, i8 poison>
4883 %cmp = icmp slt <2 x i8> %b, <i8 0, i8 0>
4887 define i1 @or_positive_slt_postive(i8 %a) {
4888 ; CHECK-LABEL: @or_positive_slt_postive(
4889 ; CHECK-NEXT: [[CMP:%.*]] = icmp slt i8 [[A:%.*]], 0
4890 ; CHECK-NEXT: ret i1 [[CMP]]
4893 %cmp = icmp slt i8 %b, 24
4897 define <2 x i1> @or_postive_slt_positive_vec(<2 x i8> %a) {
4898 ; CHECK-LABEL: @or_postive_slt_positive_vec(
4899 ; CHECK-NEXT: [[CMP:%.*]] = icmp slt <2 x i8> [[A:%.*]], zeroinitializer
4900 ; CHECK-NEXT: ret <2 x i1> [[CMP]]
4903 %b = or <2 x i8> %a, <i8 24, i8 24>
4904 %cmp = icmp slt <2 x i8> %b, <i8 24, i8 24>
4908 define <2 x i1> @or_poison_vec_slt_positive_vec(<2 x i8> %a) {
4909 ; CHECK-LABEL: @or_poison_vec_slt_positive_vec(
4910 ; CHECK-NEXT: ret <2 x i1> poison
4913 %b = or <2 x i8> %a, <i8 poison, i8 poison>
4914 %cmp = icmp slt <2 x i8> %b, <i8 24, i8 24>
4918 ; negative tests for icmp(X | OrC, C) --> icmp(X, 0)
4920 define i1 @or_positive_sgt_neg(i8 %a) {
4921 ; CHECK-LABEL: @or_positive_sgt_neg(
4922 ; CHECK-NEXT: [[CMP:%.*]] = icmp sgt i8 [[A:%.*]], -1
4923 ; CHECK-NEXT: ret i1 [[CMP]]
4926 %cmp = icmp sgt i8 %b, -1
4930 define <2 x i1> @or_postive_sgt_neg_vec(<2 x i8> %a) {
4931 ; CHECK-LABEL: @or_postive_sgt_neg_vec(
4932 ; CHECK-NEXT: [[CMP:%.*]] = icmp sgt <2 x i8> [[A:%.*]], splat (i8 -1)
4933 ; CHECK-NEXT: ret <2 x i1> [[CMP]]
4936 %b = or <2 x i8> %a, <i8 24, i8 24>
4937 %cmp = icmp sgt <2 x i8> %b, <i8 -1, i8 -1>
4941 define i1 @mul_or_positive_sge_neg(i8 %a) {
4942 ; CHECK-LABEL: @mul_or_positive_sge_neg(
4943 ; CHECK-NEXT: [[B:%.*]] = or i8 [[A:%.*]], 24
4944 ; CHECK-NEXT: [[CMP:%.*]] = icmp sgt i8 [[B]], -2
4945 ; CHECK-NEXT: ret i1 [[CMP]]
4948 %cmp = icmp sge i8 %b, -1
4952 define <2 x i1> @or_postive_sge_neg_vec(<2 x i8> %a) {
4953 ; CHECK-LABEL: @or_postive_sge_neg_vec(
4954 ; CHECK-NEXT: [[B:%.*]] = or <2 x i8> [[A:%.*]], splat (i8 24)
4955 ; CHECK-NEXT: [[CMP:%.*]] = icmp sgt <2 x i8> [[B]], splat (i8 -2)
4956 ; CHECK-NEXT: ret <2 x i1> [[CMP]]
4959 %b = or <2 x i8> %a, <i8 24, i8 24>
4960 %cmp = icmp sge <2 x i8> %b, <i8 -1, i8 -1>
4964 define i1 @mul_or_small_sge_large(i8 %a) {
4965 ; CHECK-LABEL: @mul_or_small_sge_large(
4966 ; CHECK-NEXT: [[B:%.*]] = or i8 [[A:%.*]], 24
4967 ; CHECK-NEXT: [[CMP:%.*]] = icmp sgt i8 [[B]], 24
4968 ; CHECK-NEXT: ret i1 [[CMP]]
4971 %cmp = icmp sge i8 %b, 25
4975 define <2 x i1> @or_small_sge_large_vec(<2 x i8> %a) {
4976 ; CHECK-LABEL: @or_small_sge_large_vec(
4977 ; CHECK-NEXT: [[B:%.*]] = or <2 x i8> [[A:%.*]], splat (i8 24)
4978 ; CHECK-NEXT: [[CMP:%.*]] = icmp sgt <2 x i8> [[B]], splat (i8 24)
4979 ; CHECK-NEXT: ret <2 x i1> [[CMP]]
4982 %b = or <2 x i8> %a, <i8 24, i8 24>
4983 %cmp = icmp sge <2 x i8> %b, <i8 25, i8 25>
4987 define i1 @or_positive_sle_neg(i8 %a) {
4988 ; CHECK-LABEL: @or_positive_sle_neg(
4989 ; CHECK-NEXT: [[CMP:%.*]] = icmp slt i8 [[A:%.*]], 0
4990 ; CHECK-NEXT: ret i1 [[CMP]]
4993 %cmp = icmp sle i8 %b, -1
4997 define <2 x i1> @or_sle_neg_vec(<2 x i8> %a) {
4998 ; CHECK-LABEL: @or_sle_neg_vec(
4999 ; CHECK-NEXT: [[CMP:%.*]] = icmp slt <2 x i8> [[A:%.*]], zeroinitializer
5000 ; CHECK-NEXT: ret <2 x i1> [[CMP]]
5003 %b = or <2 x i8> %a, <i8 24, i8 24>
5004 %cmp = icmp sle <2 x i8> %b, <i8 -1, i8 -1>
5008 define i1 @or_positive_slt_neg(i8 %a) {
5009 ; CHECK-LABEL: @or_positive_slt_neg(
5010 ; CHECK-NEXT: [[B:%.*]] = or i8 [[A:%.*]], 24
5011 ; CHECK-NEXT: [[CMP:%.*]] = icmp slt i8 [[B]], -1
5012 ; CHECK-NEXT: ret i1 [[CMP]]
5015 %cmp = icmp slt i8 %b, -1
5019 define <2 x i1> @or_postive_slt_neg_vec(<2 x i8> %a) {
5020 ; CHECK-LABEL: @or_postive_slt_neg_vec(
5021 ; CHECK-NEXT: [[B:%.*]] = or <2 x i8> [[A:%.*]], splat (i8 24)
5022 ; CHECK-NEXT: [[CMP:%.*]] = icmp slt <2 x i8> [[B]], splat (i8 -1)
5023 ; CHECK-NEXT: ret <2 x i1> [[CMP]]
5026 %b = or <2 x i8> %a, <i8 24, i8 24>
5027 %cmp = icmp slt <2 x i8> %b, <i8 -1, i8 -1>
5031 define i1 @or_small_slt_large(i8 %a) {
5032 ; CHECK-LABEL: @or_small_slt_large(
5033 ; CHECK-NEXT: [[B:%.*]] = or i8 [[A:%.*]], 24
5034 ; CHECK-NEXT: [[CMP:%.*]] = icmp slt i8 [[B]], 25
5035 ; CHECK-NEXT: ret i1 [[CMP]]
5038 %cmp = icmp slt i8 %b, 25
5042 define <2 x i1> @or_small_slt_large_vec(<2 x i8> %a) {
5043 ; CHECK-LABEL: @or_small_slt_large_vec(
5044 ; CHECK-NEXT: [[B:%.*]] = or <2 x i8> [[A:%.*]], splat (i8 24)
5045 ; CHECK-NEXT: [[CMP:%.*]] = icmp slt <2 x i8> [[B]], splat (i8 25)
5046 ; CHECK-NEXT: ret <2 x i1> [[CMP]]
5049 %b = or <2 x i8> %a, <i8 24, i8 24>
5050 %cmp = icmp slt <2 x i8> %b, <i8 25, i8 25>
5054 define i1 @or_positive_sgt_zero_multi_use(i8 %a) {
5055 ; CHECK-LABEL: @or_positive_sgt_zero_multi_use(
5056 ; CHECK-NEXT: [[B:%.*]] = or i8 [[A:%.*]], 24
5057 ; CHECK-NEXT: call void @use_i8(i8 [[B]])
5058 ; CHECK-NEXT: [[CMP:%.*]] = icmp sgt i8 [[A]], -1
5059 ; CHECK-NEXT: ret i1 [[CMP]]
5062 call void @use_i8(i8 %b)
5063 %cmp = icmp sgt i8 %b, 0
5068 define i1 @disjoint_or_sgt_1(i8 %a, i8 %b) {
5069 ; CHECK-LABEL: @disjoint_or_sgt_1(
5070 ; CHECK-NEXT: [[B1:%.*]] = add nsw i8 [[B:%.*]], 2
5071 ; CHECK-NEXT: [[ICMP_:%.*]] = icmp sge i8 [[A:%.*]], [[B1]]
5072 ; CHECK-NEXT: ret i1 [[ICMP_]]
5074 %a1 = or disjoint i8 %a, 1
5075 %b1 = add nsw i8 %b, 2
5076 %icmp_ = icmp sgt i8 %a1, %b1
5080 define i1 @disjoint_or_sgt_2(i8 %a, i8 %b) {
5081 ; CHECK-LABEL: @disjoint_or_sgt_2(
5082 ; CHECK-NEXT: [[A1:%.*]] = or disjoint i8 [[A:%.*]], 2
5083 ; CHECK-NEXT: [[B1:%.*]] = add i8 [[B:%.*]], 1
5084 ; CHECK-NEXT: [[ICMP_:%.*]] = icmp sgt i8 [[A1]], [[B1]]
5085 ; CHECK-NEXT: ret i1 [[ICMP_]]
5087 %a1 = or disjoint i8 %a, 2
5089 %icmp_ = icmp sgt i8 %a1, %b1
5093 define i1 @disjoint_or_sgt_3(i8 %a, i8 %b) {
5094 ; CHECK-LABEL: @disjoint_or_sgt_3(
5095 ; CHECK-NEXT: [[A1:%.*]] = or disjoint i8 [[A:%.*]], 2
5096 ; CHECK-NEXT: [[B1:%.*]] = add nuw i8 [[B:%.*]], 1
5097 ; CHECK-NEXT: [[ICMP_:%.*]] = icmp sgt i8 [[A1]], [[B1]]
5098 ; CHECK-NEXT: ret i1 [[ICMP_]]
5100 %a1 = or disjoint i8 %a, 2
5101 %b1 = add nuw i8 %b, 1
5102 %icmp_ = icmp sgt i8 %a1, %b1
5106 define i1 @disjoint_or_ugt_1(i8 %a, i8 %b) {
5107 ; CHECK-LABEL: @disjoint_or_ugt_1(
5108 ; CHECK-NEXT: [[B1:%.*]] = add nsw i8 [[B:%.*]], 2
5109 ; CHECK-NEXT: [[ICMP_:%.*]] = icmp uge i8 [[A:%.*]], [[B1]]
5110 ; CHECK-NEXT: ret i1 [[ICMP_]]
5112 %a1 = or disjoint i8 %a, 1
5113 %b1 = add nsw i8 %b, 2
5114 %icmp_ = icmp ugt i8 %a1, %b1
5118 define i1 @disjoint_or_ugt_2(i8 %a, i8 %b) {
5119 ; CHECK-LABEL: @disjoint_or_ugt_2(
5120 ; CHECK-NEXT: [[A1:%.*]] = or disjoint i8 [[A:%.*]], 2
5121 ; CHECK-NEXT: [[B1:%.*]] = add i8 [[B:%.*]], 1
5122 ; CHECK-NEXT: [[ICMP_:%.*]] = icmp ugt i8 [[A1]], [[B1]]
5123 ; CHECK-NEXT: ret i1 [[ICMP_]]
5125 %a1 = or disjoint i8 %a, 2
5127 %icmp_ = icmp ugt i8 %a1, %b1
5131 define i1 @disjoint_or_ugt_3(i8 %a, i8 %b) {
5132 ; CHECK-LABEL: @disjoint_or_ugt_3(
5133 ; CHECK-NEXT: [[A1:%.*]] = or disjoint i8 [[A:%.*]], 2
5134 ; CHECK-NEXT: [[B1:%.*]] = add nuw i8 [[B:%.*]], 1
5135 ; CHECK-NEXT: [[ICMP_:%.*]] = icmp ugt i8 [[A1]], [[B1]]
5136 ; CHECK-NEXT: ret i1 [[ICMP_]]
5138 %a1 = or disjoint i8 %a, 2
5139 %b1 = add nuw i8 %b, 1
5140 %icmp_ = icmp ugt i8 %a1, %b1
5144 define i1 @deduce_nuw_flag_1(i8 %a, i8 %b) {
5145 ; CHECK-LABEL: @deduce_nuw_flag_1(
5146 ; CHECK-NEXT: entry:
5147 ; CHECK-NEXT: [[TMP0:%.*]] = add nuw i8 [[B:%.*]], 1
5148 ; CHECK-NEXT: [[CMP:%.*]] = icmp eq i8 [[TMP0]], [[A:%.*]]
5149 ; CHECK-NEXT: ret i1 [[CMP]]
5152 %add1 = add nuw i8 %b, 2
5153 %add2 = add i8 %a, 1
5154 %cmp = icmp eq i8 %add1, %add2
5158 define i1 @deduce_nuw_flag_2(i8 %a, i8 %b) {
5159 ; CHECK-LABEL: @deduce_nuw_flag_2(
5160 ; CHECK-NEXT: entry:
5161 ; CHECK-NEXT: [[TMP0:%.*]] = add nuw i8 [[B:%.*]], 1
5162 ; CHECK-NEXT: [[CMP:%.*]] = icmp eq i8 [[A:%.*]], [[TMP0]]
5163 ; CHECK-NEXT: ret i1 [[CMP]]
5166 %add1 = add nuw i8 %b, 2
5167 %add2 = add i8 %a, 1
5168 %cmp = icmp eq i8 %add2, %add1
5172 define i1 @dont_deduce_nuw_flag_1(i8 %a, i8 %b) {
5173 ; CHECK-LABEL: @dont_deduce_nuw_flag_1(
5174 ; CHECK-NEXT: entry:
5175 ; CHECK-NEXT: [[TMP0:%.*]] = add i8 [[B:%.*]], -1
5176 ; CHECK-NEXT: [[CMP:%.*]] = icmp eq i8 [[TMP0]], [[A:%.*]]
5177 ; CHECK-NEXT: ret i1 [[CMP]]
5180 %add1 = add nuw i8 %b, -2
5181 %add2 = add i8 %a, -1
5182 %cmp = icmp eq i8 %add1, %add2
5186 define i1 @dont_deduce_nuw_flag_2(i8 %a, i8 %b) {
5187 ; CHECK-LABEL: @dont_deduce_nuw_flag_2(
5188 ; CHECK-NEXT: entry:
5189 ; CHECK-NEXT: [[TMP0:%.*]] = add i8 [[B:%.*]], -1
5190 ; CHECK-NEXT: [[CMP:%.*]] = icmp eq i8 [[A:%.*]], [[TMP0]]
5191 ; CHECK-NEXT: ret i1 [[CMP]]
5194 %add1 = add nuw i8 %b, -2
5195 %add2 = add i8 %a, -1
5196 %cmp = icmp eq i8 %add2, %add1
5200 define i1 @icmp_freeze_sext(i16 %x, i16 %y) {
5201 ; CHECK-LABEL: @icmp_freeze_sext(
5202 ; CHECK-NEXT: [[CMP1:%.*]] = icmp uge i16 [[X:%.*]], [[Y:%.*]]
5203 ; CHECK-NEXT: [[CMP1_FR:%.*]] = freeze i1 [[CMP1]]
5204 ; CHECK-NEXT: [[TMP1:%.*]] = icmp eq i16 [[Y]], 0
5205 ; CHECK-NEXT: [[CMP2:%.*]] = or i1 [[TMP1]], [[CMP1_FR]]
5206 ; CHECK-NEXT: ret i1 [[CMP2]]
5208 %cmp1 = icmp uge i16 %x, %y
5209 %ext = sext i1 %cmp1 to i16
5210 %ext.fr = freeze i16 %ext
5211 %cmp2 = icmp uge i16 %ext.fr, %y
5215 define i1 @test_icmp_shl(i64 %x) {
5216 ; CHECK-LABEL: @test_icmp_shl(
5217 ; CHECK-NEXT: [[TMP1:%.*]] = trunc i64 [[X:%.*]] to i32
5218 ; CHECK-NEXT: [[CMP:%.*]] = icmp ult i32 [[TMP1]], 3
5219 ; CHECK-NEXT: ret i1 [[CMP]]
5221 %shl = shl i64 %x, 32
5222 %cmp = icmp ult i64 %shl, 8589934593
5226 define i1 @test_icmp_shl_multiuse(i64 %x) {
5227 ; CHECK-LABEL: @test_icmp_shl_multiuse(
5228 ; CHECK-NEXT: [[SHL:%.*]] = shl i64 [[X:%.*]], 32
5229 ; CHECK-NEXT: call void @use_i64(i64 [[SHL]])
5230 ; CHECK-NEXT: [[CMP:%.*]] = icmp ult i64 [[SHL]], 8589934593
5231 ; CHECK-NEXT: ret i1 [[CMP]]
5233 %shl = shl i64 %x, 32
5234 call void @use_i64(i64 %shl)
5235 %cmp = icmp ult i64 %shl, 8589934593
5239 define i1 @test_icmp_shl_illegal_length(i64 %x) {
5240 ; CHECK-LABEL: @test_icmp_shl_illegal_length(
5241 ; CHECK-NEXT: [[SHL:%.*]] = shl i64 [[X:%.*]], 31
5242 ; CHECK-NEXT: [[CMP:%.*]] = icmp ult i64 [[SHL]], 8589934593
5243 ; CHECK-NEXT: ret i1 [[CMP]]
5245 %shl = shl i64 %x, 31
5246 %cmp = icmp ult i64 %shl, 8589934593
5250 define i1 @test_icmp_shl_invalid_rhsc(i64 %x) {
5251 ; CHECK-LABEL: @test_icmp_shl_invalid_rhsc(
5252 ; CHECK-NEXT: [[SHL:%.*]] = shl i64 [[X:%.*]], 32
5253 ; CHECK-NEXT: [[CMP:%.*]] = icmp ult i64 [[SHL]], 8589934595
5254 ; CHECK-NEXT: ret i1 [[CMP]]
5256 %shl = shl i64 %x, 32
5257 %cmp = icmp ult i64 %shl, 8589934595
5261 define i1 @test_icmp_shl_nuw(i64 %x) {
5262 ; CHECK-LABEL: @test_icmp_shl_nuw(
5263 ; CHECK-NEXT: [[CMP:%.*]] = icmp ult i64 [[X:%.*]], 3
5264 ; CHECK-NEXT: ret i1 [[CMP]]
5266 %shl = shl nuw i64 %x, 32
5267 %cmp = icmp ult i64 %shl, 8589934593
5271 define i1 @test_icmp_shl_nuw_i31(i31 %x) {
5272 ; CHECK-LABEL: @test_icmp_shl_nuw_i31(
5273 ; CHECK-NEXT: [[CMP:%.*]] = icmp ugt i31 [[X:%.*]], 250
5274 ; CHECK-NEXT: ret i1 [[CMP]]
5276 %shl = shl nuw i31 %x, 23
5277 %cmp = icmp ugt i31 %shl, -50331648
5281 define i1 @test_icmp_shl_nsw(i64 %x) {
5282 ; CHECK-LABEL: @test_icmp_shl_nsw(
5283 ; CHECK-NEXT: [[CMP:%.*]] = icmp ult i64 [[X:%.*]], 3
5284 ; CHECK-NEXT: ret i1 [[CMP]]
5286 %shl = shl nsw i64 %x, 32
5287 %cmp = icmp ult i64 %shl, 8589934593
5291 define i1 @test_icmp_shl_nsw_i31(i31 %x) {
5292 ; CHECK-LABEL: @test_icmp_shl_nsw_i31(
5293 ; CHECK-NEXT: [[TMP1:%.*]] = trunc nsw i31 [[X:%.*]] to i8
5294 ; CHECK-NEXT: [[CMP:%.*]] = icmp ugt i8 [[TMP1]], -6
5295 ; CHECK-NEXT: ret i1 [[CMP]]
5297 %shl = shl nsw i31 %x, 23
5298 %cmp = icmp ugt i31 %shl, -50331648
5302 define <2 x i1> @test_icmp_shl_vec(<2 x i64> %x) {
5303 ; CHECK-LABEL: @test_icmp_shl_vec(
5304 ; CHECK-NEXT: [[TMP1:%.*]] = trunc <2 x i64> [[X:%.*]] to <2 x i32>
5305 ; CHECK-NEXT: [[CMP:%.*]] = icmp ult <2 x i32> [[TMP1]], splat (i32 3)
5306 ; CHECK-NEXT: ret <2 x i1> [[CMP]]
5308 %shl = shl <2 x i64> %x, splat(i64 32)
5309 %cmp = icmp ult <2 x i64> %shl, splat(i64 8589934593)
5313 define i1 @test_icmp_shl_eq(i64 %x) {
5314 ; CHECK-LABEL: @test_icmp_shl_eq(
5315 ; CHECK-NEXT: ret i1 false
5317 %shl = shl i64 %x, 32
5318 %cmp = icmp eq i64 %shl, 8589934593
5322 define i1 @test_icmp_shl_sgt(i64 %x) {
5323 ; CHECK-LABEL: @test_icmp_shl_sgt(
5324 ; CHECK-NEXT: [[TMP1:%.*]] = trunc i64 [[X:%.*]] to i32
5325 ; CHECK-NEXT: [[CMP:%.*]] = icmp sgt i32 [[TMP1]], 1
5326 ; CHECK-NEXT: ret i1 [[CMP]]
5328 %shl = shl i64 %x, 32
5329 %cmp = icmp sgt i64 %shl, 8589934591
5333 define i1 @pr94897(i32 range(i32 -2147483648, 0) %x) {
5334 ; CHECK-LABEL: @pr94897(
5335 ; CHECK-NEXT: [[CMP:%.*]] = icmp samesign ugt i32 [[X:%.*]], -3
5336 ; CHECK-NEXT: ret i1 [[CMP]]
5338 %shl = shl nsw i32 %x, 24
5339 %cmp = icmp ugt i32 %shl, -50331648
5343 define i1 @icmp_and_inv_pow2_ne_0(i32 %A, i32 %B) {
5344 ; CHECK-LABEL: @icmp_and_inv_pow2_ne_0(
5345 ; CHECK-NEXT: [[POPCNT:%.*]] = tail call range(i32 0, 33) i32 @llvm.ctpop.i32(i32 [[A:%.*]])
5346 ; CHECK-NEXT: [[COND:%.*]] = icmp eq i32 [[POPCNT]], 1
5347 ; CHECK-NEXT: call void @llvm.assume(i1 [[COND]])
5348 ; CHECK-NEXT: [[TMP1:%.*]] = and i32 [[A]], [[B:%.*]]
5349 ; CHECK-NEXT: [[CMP:%.*]] = icmp eq i32 [[TMP1]], 0
5350 ; CHECK-NEXT: ret i1 [[CMP]]
5352 %popcnt = tail call i32 @llvm.ctpop.i32(i32 %A)
5353 %cond = icmp eq i32 %popcnt, 1
5354 call void @llvm.assume(i1 %cond)
5356 %inv = xor i32 %B, -1
5357 %and = and i32 %A, %inv
5358 %cmp = icmp ne i32 %and, 0
5362 define i1 @icmp_and_inv_pow2_or_zero_ne_0(i32 %A, i32 %B) {
5363 ; CHECK-LABEL: @icmp_and_inv_pow2_or_zero_ne_0(
5364 ; CHECK-NEXT: [[POPCNT:%.*]] = tail call range(i32 0, 33) i32 @llvm.ctpop.i32(i32 [[A:%.*]])
5365 ; CHECK-NEXT: [[COND:%.*]] = icmp samesign ult i32 [[POPCNT]], 2
5366 ; CHECK-NEXT: call void @llvm.assume(i1 [[COND]])
5367 ; CHECK-NEXT: [[INV:%.*]] = xor i32 [[B:%.*]], -1
5368 ; CHECK-NEXT: [[AND:%.*]] = and i32 [[A]], [[INV]]
5369 ; CHECK-NEXT: [[CMP:%.*]] = icmp ne i32 [[AND]], 0
5370 ; CHECK-NEXT: ret i1 [[CMP]]
5372 %popcnt = tail call i32 @llvm.ctpop.i32(i32 %A)
5373 %cond = icmp ult i32 %popcnt, 2
5374 call void @llvm.assume(i1 %cond)
5376 %inv = xor i32 %B, -1
5377 %and = and i32 %A, %inv
5378 %cmp = icmp ne i32 %and, 0
5382 define i1 @icmp_samesign_logical_and(i32 %In) {
5383 ; CHECK-LABEL: @icmp_samesign_logical_and(
5384 ; CHECK-NEXT: [[C2:%.*]] = icmp eq i32 [[IN:%.*]], 1
5385 ; CHECK-NEXT: ret i1 [[C2]]
5387 %c1 = icmp samesign sgt i32 %In, -1
5388 %c2 = icmp samesign eq i32 %In, 1
5389 %V = select i1 %c1, i1 %c2, i1 false
5393 define i1 @icmp_samesign_logical_or(i32 %In) {
5394 ; CHECK-LABEL: @icmp_samesign_logical_or(
5395 ; CHECK-NEXT: [[V:%.*]] = icmp ne i32 [[IN:%.*]], 1
5396 ; CHECK-NEXT: ret i1 [[V]]
5398 %c1 = icmp samesign slt i32 %In, 0
5399 %c2 = icmp samesign ne i32 %In, 1
5400 %V = select i1 %c1, i1 true, i1 %c2