[mlir][scf]: Add value bound between scf for loop yield and result (#123200)
[llvm-project.git] / llvm / test / Transforms / InstCombine / icmp.ll
blob6e1486660b24d79ec22d73aba12a160c5fa1d5da
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
20   ret i32 %b
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>
30   ret <2 x i32> %b
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
41   ret i32 %b
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>
52   ret <2 x i32> %b
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
62   ret i32 %b
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
73   ret i32 %b
76 ; PR4837
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
82   ret <2 x i1> %V
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
89   ret <2 x i1> %V
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
96   ret <2 x i1> %V
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
103   ret <2 x i1> %V
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
114   %e = sub i32 0, %d
115   %f = and i32 %e, %b
116   ret i32 %f
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]]
125   %a = add i32 %x, -1
126   %b = icmp ult i32 %a, %x
127   ret i1 %b
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
137   ret <2 x i1> %b
140 define i1 @test8(i32 %x) {
141 ; CHECK-LABEL: @test8(
142 ; CHECK-NEXT:    ret i1 false
144   %a = add i32 %x, -1
145   %b = icmp eq i32 %a, %x
146   ret i1 %b
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
155   ret <2 x i1> %b
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]]
163   %a = add i32 %x, -2
164   %b = icmp ugt i32 %x, %a
165   ret i1 %b
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
175   ret <2 x i1> %b
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]]
183   %a = add i32 %x, -2
184   %b = icmp ugt i32 %a, %x
185   ret i1 %b
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
195   ret <2 x i1> %b
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]]
203   %a = add i32 %x, -1
204   %b = icmp slt i32 %a, %x
205   ret i1 %b
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
215   ret <2 x i1> %b
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]]
223   %a = add i32 %x, -1
224   %b = icmp sgt i32 %a, %x
225   ret i1 %b
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
235   ret <2 x i1> %b
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
244   ret i1 %b
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
253   ret <2 x i1> %b
256 ; PR6195
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
264   ret i1 %B
267 ; PR6481
268 define i1 @test13(i8 %X) {
269 ; CHECK-LABEL: @test13(
270 ; CHECK-NEXT:    ret i1 false
272   %cmp = icmp slt i8 undef, %X
273   ret i1 %cmp
276 define i1 @test14(i8 %X) {
277 ; CHECK-LABEL: @test14(
278 ; CHECK-NEXT:    ret i1 false
280   %cmp = icmp slt i8 undef, -128
281   ret i1 %cmp
284 define i1 @test15() {
285 ; CHECK-LABEL: @test15(
286 ; CHECK-NEXT:    ret i1 undef
288   %cmp = icmp eq i8 undef, -128
289   ret i1 %cmp
292 define i1 @test16() {
293 ; CHECK-LABEL: @test16(
294 ; CHECK-NEXT:    ret i1 undef
296   %cmp = icmp ne i8 undef, -128
297   ret i1 %cmp
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]]
305   %shl = shl i32 1, %x
306   %and = and i32 %shl, 8
307   %cmp = icmp eq i32 %and, 0
308   ret i1 %cmp
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
319   ret <2 x i1> %cmp
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]]
327   %shl = shl i32 1, %x
328   %and = and i32 %shl, 7
329   %cmp = icmp eq i32 %and, 0
330   ret i1 %cmp
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
341   ret <2 x i1> %cmp
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]]
349   %sh = lshr i32 8, %x
350   %and = and i32 %sh, 1
351   %cmp = icmp eq i32 %and, 0
352   ret i1 %cmp
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
363   ret <2 x i1> %cmp
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]]
371   %sh = lshr i32 8, %x
372   %and = and i32 %sh, 1
373   %cmp = icmp ne i32 %and, 0
374   ret i1 %cmp
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
385   ret <2 x i1> %cmp
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]]
393   %shl = shl i32 1, %x
394   %and = and i32 %shl, 8
395   %cmp = icmp eq i32 %and, 8
396   ret i1 %cmp
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>
407   ret <2 x i1> %cmp
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
417   ret <2 x i1> %cmp
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]]
425   %shl = shl i32 1, %x
426   %and = and i32 %shl, 8
427   %cmp = icmp ne i32 %and, 0
428   ret i1 %cmp
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
439   ret <2 x i1> %cmp
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]]
447   %shl = shl i32 1, %x
448   %and = and i32 %shl, 7
449   %cmp = icmp ne i32 %and, 0
450   ret i1 %cmp
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
461   ret <2 x i1> %cmp
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]]
469   %A = or i8 %x, 1
470   %B = icmp ugt i8 %A, 3
471   ret i1 %B
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]]
479   %A = or i8 %x, 1
480   %B = icmp ult i8 %A, 4
481   ret i1 %B
484 ; PR2740
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
492   ret i1 %i4
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>
502   ret <2 x i1> %i4
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
518   ret i1 %cmp
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
530   ret i1 %c
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
547   ret i1 %c
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
559   ret i1 %c
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
576   ret i1 %c
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
590   ret i1 %cmp
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
604   ret <2 x i1> %cmp
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
615   ret i1 %c
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
625   ret i1 %c
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
636   ret i1 %c
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
647   ret i1 %c
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
659   ret i1 %c
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
676   ret i1 %c
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
691   ret i32 %r
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
704   ret <4 x i32> %r
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
716   ret i1 %c
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
733   ret i1 %c
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
743   ret i1 %cmp
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>
753   ret <2 x i1> %cmp
756 ; PR9343 #3
757 define i1 @test41(i32 %X, i32 %Y) {
758 ; CHECK-LABEL: @test41(
759 ; CHECK-NEXT:    ret i1 true
761   %A = urem i32 %X, %Y
762   %B = icmp ugt i32 %Y, %A
763   ret i1 %B
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]]
771   %A = srem i32 %X, %Y
772   %B = icmp slt i32 %A, %Y
773   ret i1 %B
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]]
781   %A = srem i32 %X, %Y
782   %B = icmp slt i32 %Y, %A
783   ret i1 %B
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]]
791   %A = srem i32 %X, %Y
792   %B = icmp slt i32 %A, %Y
793   ret i1 %B
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]]
801   %A = srem i32 %X, %Y
802   %B = icmp slt i32 %Y, %A
803   ret i1 %B
806 ; PR9343 #4
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
815   ret i1 %C
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
829   ret i1 %C
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
843   ret i1 %C
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
860   ret i1 %C
863 ; PR9343 #5
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
872   ret i1 %C
875 ; PR9343 #8
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
884   ret i1 %C
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
899   ret i1 %C
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
910   ret i1 %cmp
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
921   ret i1 %cmp
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
932   ret i1 %cmp
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
943   ret i1 %cmp
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
954   ret i1 %cmp
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
965   ret i1 %cmp
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
976   ret i1 %cmp
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
987   ret i1 %cmp
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
1000   ret i1 %cmp
1003 ; PR8469
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)
1009 entry:
1010   %i11 = and <2 x i32> %i3, <i32 3, i32 3>
1011   %cmp = icmp ult <2 x i32> %i11, <i32 4, i32 4>
1012   ret <2 x i1> %cmp
1015 ; PR9343 #7
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
1023   ret i1 %C
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
1036   ret i1 %C
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
1052   ret i1 %A
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
1068   ret i1 %A
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
1084   ret i1 %A
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
1100   ret i1 %A
1103 ; PR9838
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
1114   ret i1 %z
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
1125   ret i1 %ret
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
1135   ret i1 %cmp
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>
1145   ret <2 x i1> %cmp
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
1155   ret i1 %cmp
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>
1165   ret <2 x i1> %cmp
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)
1179   ret i1 %cmp
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
1192   ret i1 %tobool
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
1204   ret i1 %tobool
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
1214   ret i1 %cmp
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
1224   ret i1 %cmp
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)
1234   ret void
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
1249   ret i1 %cmp
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
1262   ret i1 %cmp
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
1274   ret i1 %c
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
1286   ret i1 %c
1289 ; negative test
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
1301   ret i1 %c
1304 ; negative test
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
1316   ret i1 %c
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
1331   ret i1 %c
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
1346   ret i1 %c
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
1363   ret i1 %c
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
1375   ret <2 x i1> %c
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
1385   ret i1 %cmp
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
1395   ret i1 %cmp
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
1406   ret i1 %cmp
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
1417   ret i1 %cmp
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>
1431   ret <2 x i1> %cmp
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>
1442   ret <2 x i1> %cmp
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>
1453   ret <2 x i1> %cmp
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
1464   ret i1 %cmp
1467 ; PR15940
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]]
1474   %A = srem i32 5, %X
1475   %B = add i32 %A, 2
1476   %C = icmp ne i32 %B, 4
1477   ret i1 %C
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>
1487   ret <2 x i1> %C
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
1499   ret i1 %cmp
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
1511   ret i1 %cmp
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>
1524   ret <2 x i1> %cmp
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
1535   ret i1 %cmp
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
1548   ret i1 %cmp
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>
1559   ret <2 x i1> %cmp
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
1570   ret i1 %cmp
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
1581   ret i1 %cmp
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
1592   ret <2 x i1> %cmp
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
1602   ret i1 %cmp
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
1612   ret <2 x i1> %cmp
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
1623   ret i1 %cmp
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
1634   ret <2 x i1> %cmp
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>
1644   ret <2 x i1> %cmp
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
1656   ret i1 %cmp
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
1666   ret i1 %cmp
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
1676   ret i1 %cmp
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
1686   ret i1 %cmp
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>
1696   ret <2 x i1> %cmp
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
1705   ret i1 %cmp
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
1716   ret i1 %cmp
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
1727   ret i1 %cmp
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
1737   ret <2 x i1> %cmp
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
1747   ret i1 %cmp
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
1756   ret i1 %cmp
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
1765   ret i1 %cmp
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]]
1774   %1 = add i32 %x, 20
1775   %2 = add i32 %y, 57
1776   %cmp = icmp eq i32 %1, %2
1777   ret i1 %cmp
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
1789   ret <2 x i1> %cmp
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
1801   ret <2 x i1> %cmp
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
1813   ret <2 x i1> %cmp
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
1825   ret i1 %cmp
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
1837   ret <2 x i1> %cmp
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
1849   ret <2 x i1> %cmp
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
1861   ret <2 x i1> %cmp
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
1871   ret i1 %cmp
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
1881   ret i1 %cmp
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
1891   ret i1 %cmp
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
1901   ret i1 %cmp
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
1913   ret i1 %cmp
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
1925   ret <2 x i1> %cmp
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
1937   ret <2 x i1> %cmp
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
1950   ret <2 x i1> %cmp
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
1962   ret i1 %cmp
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
1974   ret <2 x i1> %cmp
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
1986   ret <2 x i1> %cmp
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
1999   ret <2 x i1> %cmp
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
2013   ret i1 %cmp
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
2028   ret i1 %cmp
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
2042   ret i1 %cmp
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
2056   ret i1 %cmp
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
2070   ret i1 %cmp
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
2083   ret i1 %tobool
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
2115   ret i1 %and3
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
2133   ret i1 %and3
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
2152   ret i1 %and3
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
2170   ret i1 %and3
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
2181   ret i1 %tobool
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
2195   ret i1 %tobool
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
2206   ret i1 %cmp
2209 ; Negative test.
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
2220   ret i1 %cmp
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
2232   ret i1 %cmp
2235 ; Negative test.
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
2246   ret i1 %cmp
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
2258   ret i1 %cmp
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
2268   ret i1 %cmp
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
2278   ret i1 %cmp
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
2288   ret i1 %cmp
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>
2298   ret <2 x i1> %cmp
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
2308   ret i1 %cmp
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>
2318   ret <2 x i1> %cmp
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
2328   ret i1 %cmp
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>
2338   ret <2 x i1> %cmp
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
2348   ret i1 %cmp
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>
2358   ret <2 x i1> %cmp
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
2368   ret i1 %cmp
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>
2378   ret <2 x i1> %cmp
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
2388   ret i1 %cmp
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>
2398   ret <2 x i1> %cmp
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
2408   ret i1 %cmp
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>
2418   ret <2 x i1> %cmp
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
2428   ret i1 %cmp
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>
2438   ret <2 x i1> %cmp
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
2448   ret i1 %cmp
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>
2458   ret <2 x i1> %cmp
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
2468   ret i1 %cmp
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>
2478   ret <2 x i1> %cmp
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
2488   ret i1 %cmp
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>
2498   ret <2 x i1> %cmp
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
2508   ret i1 %cmp
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>
2518   ret <2 x i1> %cmp
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
2529   %3 = or i1 %1, %2
2530   ret i1 %3
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
2543   ret i1 %3
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
2555   ret <2 x i1> %3
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
2567   ret <2 x i1> %3
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
2578   %3 = or i1 %1, %2
2579   ret i1 %3
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
2592   ret i1 %3
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
2604   ret <2 x i1> %3
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
2616   ret <2 x i1> %3
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
2627   %3 = and i1 %1, %2
2628   ret i1 %3
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
2639   %3 = and i1 %1, %2
2640   ret i1 %3
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
2651   %3 = and i1 %1, %2
2652   ret i1 %3
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
2664   ret i1 %3
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
2677   ret i1 %3
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
2691   %3 = and i1 %1, %2
2692   ret i1 %3
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)
2706   %3 = and i1 %1, %2
2707   ret i1 %3
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)
2723   %3 = and i1 %1, %2
2724   ret i1 %3
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
2736   %3 = and i1 %1, %2
2737   ret i1 %3
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
2749   %3 = and i1 %1, %2
2750   ret i1 %3
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
2762   %3 = and i1 %1, %2
2763   ret i1 %3
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
2775   %3 = and i1 %1, %2
2776   ret i1 %3
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
2789   ret i1 %3
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
2801   ret <2 x i1> %3
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
2813   ret <2 x i1> %3
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
2824   ret i1 %cmp
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>
2835   ret <2 x i1> %cmp
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
2846   ret i1 %cmp
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>
2857   ret <2 x i1> %cmp
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
2868   ret i1 %cmp
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>
2879   ret <2 x i1> %cmp
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
2890   ret i1 %cmp
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>
2901   ret <2 x i1> %cmp
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
2911   ret i1 %cmp
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>
2921   ret <2 x i1> %cmp
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
2931   ret i1 %cmp
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>
2941   ret <2 x i1> %cmp
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]]
2952   %t0 = or i32 %x, 1
2953   %t1 = icmp eq i32 %t0, 1
2954   ret i1 %t1
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>
2966   ret <2 x i1> %t1
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]]
2976   %t0 = or i32 %x, 7
2977   %t1 = icmp ne i32 %t0, 7
2978   ret i1 %t1
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>
2990   ret <2 x i1> %t1
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]]
3002   %t0 = or i32 %x, 42
3003   %t1 = icmp eq i32 %t0, 42
3004   ret i1 %t1
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>
3017   ret <2 x i1> %t1
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
3030   ret i1 %t1
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>
3043   ret <2 x i1> %t1
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
3054   ret i1 %cmp
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>
3065   ret <2 x i1> %cmp
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
3076   ret i1 %cmp
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>
3086   ret <2 x i1> %cmp
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
3096   ret i1 %cmp
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>
3106   ret <2 x i1> %cmp
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>
3116   ret <2 x i1> %r
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
3129   ret i1 %r
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>
3139   ret <2 x i1> %r
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
3152   ret i1 %r
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
3164   ret i1 %z
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]]
3173   %x = ashr i32 %a, 8
3174   %y = ashr i32 %b, 8
3175   %z = icmp ne i32 %x, %y
3176   ret i1 %z
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
3186   ret i1 %2
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
3201   ret i1 %ret
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
3216   ret i1 %ret
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
3230   ret <2 x i1> %ret
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
3246   ret <2 x i1> %ret
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
3259   ret i1 %ret
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
3272   ret <2 x i1> %ret
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
3285   ret <2 x i1> %ret
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
3298   ret <2 x i1> %ret
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
3313   ret <2 x i1> %ret
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
3328   ret <2 x i1> %ret
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
3343   ret <2 x i1> %ret
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
3353   ret i1 %cmp
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
3363   ret <2 x i1> %cmp
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
3374   ret <2 x i1> %cmp
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
3384   ret i1 %cmp
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
3394   ret i1 %cmp
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
3404   ret i1 %cmp
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
3413   ret i1 %cmp
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
3423   ret i1 %cmp
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
3432   ret i1 %cmp
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
3442   ret i1 %cmp
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
3452   ret i1 %cmp
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
3462   ret i1 %cmp
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
3474   ret i1 %icmp
3477 define i1 @f1(i64 %a, i64 %b) {
3478 ; CHECK-LABEL: @f1(
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
3484   ret i1 %v
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>
3494   ret <2 x i1> %v
3497 define i1 @f2(i64 %a, i64 %b) {
3498 ; CHECK-LABEL: @f2(
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
3504   ret i1 %v
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
3514   ret <2 x i1> %v
3517 define i1 @f3(i64 %a, i64 %b) {
3518 ; CHECK-LABEL: @f3(
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
3524   ret i1 %v
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
3534   ret <2 x i1> %v
3537 define i1 @f4(i64 %a, i64 %b) {
3538 ; CHECK-LABEL: @f4(
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
3544   ret i1 %v
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>
3554   ret <2 x i1> %v
3557 define i32 @f5(i8 %a, i8 %b) {
3558 ; CHECK-LABEL: @f5(
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
3571   ret i32 %sub7.sub
3574 define i32 @f6(i32 %a, i32 %b) {
3575 ; CHECK-LABEL: @f6(
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
3588   ret i32 %s
3591 define i32 @f7(i32 %a, i32 %b) {
3592 ; CHECK-LABEL: @f7(
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
3603   ret i32 %s
3606 define i1 @f8(i32 %val, i32 %lim) {
3607 ; CHECK-LABEL: @f8(
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
3614   ret i1 %r
3617 define i1 @f9(i32 %val, i32 %lim) {
3618 ; CHECK-LABEL: @f9(
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
3625   ret i1 %r
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
3640   ret i1 %cmp580
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
3656   ret i1 %cmp
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
3668   ret i1 %cmp
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
3680   ret i1 %cmp
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
3692   ret i1 %cmp
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
3705   ret i1 %cmp
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]]
3714   %or = or i32 %x, 42
3715   %cmp = icmp eq i32 %or, -1
3716   ret i1 %cmp
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>
3727   ret <2 x i1> %cmp
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]]
3736   %or = or i32 %x, 42
3737   %cmp = icmp ne i32 %or, -1
3738   ret i1 %cmp
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
3749   ret i1 %cmp
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
3758   ret i1 %b
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
3767   ret i1 %cmp
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>
3776   ret <2 x i1> %cmp
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]]
3785   %b = and i8 %a, 17
3786   %cmp = icmp ugt i8 %b, 16
3787   ret i1 %cmp
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>
3798   ret <2 x i1> %cmp
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
3813   ret i1 %b
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
3823   ret i1 %cmp
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
3833   ret i1 %cmp
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
3845   ret i1 %cmp
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
3857   ret i1 %cmp
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
3868   ret i1 %cmp
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
3879   ret i1 %cmp
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
3890   ret i1 %cmp
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
3901   ret i1 %cmp
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
3914   ret i1 %cmp
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
3927   ret i1 %cmp
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
3940   ret i1 %cmp
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
3953   ret i1 %cmp
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]]
3961   %A = add i32 %x, 5
3962   %B = add i32 %y, 5
3963   %C = icmp eq i32 %A, %B
3964   ret i1 %C
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
3977   ret i1 %cmp
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
3990   ret <8 x i1> %cmp
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
4003   ret i1 %cmp
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
4016   ret <8 x i1> %cmp
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]]
4029   %a1 = and i8 %a, 5
4030   %a2 = or i8 %a1, 4
4031   %b1 = and i8 %b, 7
4032   %b2 = or i8 %b1, 5
4033   %c = icmp uge i8 %a2, %b2
4034   ret i1 %c
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]]
4045   %a1 = and i8 %a, 5
4046   %a2 = or i8 %a1, 4
4047   %b1 = and i8 %b, 7
4048   %b2 = or i8 %b1, 5
4049   %c = icmp ult i8 %a2, %b2
4050   ret i1 %c
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]]
4061   %a1 = and i8 %a, 5
4062   %a2 = or i8 %a1, 4
4063   %b1 = and i8 %b, 7
4064   %b2 = or i8 %b1, 5
4065   %c = icmp ule i8 %b2, %a2
4066   ret i1 %c
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
4082   ret <2 x i1> %c
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
4096   %a2 = or i8 %a1, 4
4097   %b1 = and i8 %b, 7
4098   %b2 = or i8 %b1, 5
4099   %c = icmp sge i8 %a2, %b2
4100   ret i1 %c
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
4112   %a2 = or i8 %a1, 4
4113   %b1 = and i8 %b, 7
4114   %b2 = or i8 %b1, 5
4115   %c = icmp slt i8 %a2, %b2
4116   ret i1 %c
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
4132   ret <2 x i1> %c
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
4144   %a2 = or i8 %a1, 4
4145   %b1 = and i8 %b, 7
4146   %b2 = or i8 %b1, 5
4147   %c = icmp sgt i8 %b2, %a2
4148   ret i1 %c
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
4162   ret i32 %abs
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)
4177   ret i1 %cmp
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
4188   ret <2 x i1> %res
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
4200   ret <2 x i32> %cond
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
4212   ret i1 %r
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>
4224   ret <2 x i1> %r
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
4236   ret i1 %r
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
4248   ret <2 x i1> %r
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
4261   ret i1 %r
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>
4274   ret <4 x i1> %r
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
4289   ret i1 %r
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
4302   ret i1 %s4
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
4315   ret i1 %s4
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(
4322 ; CHECK-NEXT:  bb:
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
4336   ret i1 %i3
4339 ; PR50944
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
4347   ret i1 %tobool
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
4356   ret i1 %tobool
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
4368   ret i1 %r
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>
4380   ret <2 x i1> %r
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
4403   ret i1 %r
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]]
4412   %y = ashr i32 %x, 1
4413   %z = xor i32 %y, %x
4414   %c = icmp ult i32 %z, 4
4415   ret i1 %c
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]]
4424   %y = ashr i32 %x, 1
4425   %z = xor i32 %y, %x
4426   %c = icmp ult i32 %z, 1073741824
4427   ret i1 %c
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
4437   %z = xor i32 %y, %x
4438   %c = icmp ult i32 %z, 4
4439   ret i1 %c
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
4449   %z = xor i32 %y, %x
4450   %c = icmp ult i32 %z, 1073741824
4451   ret i1 %c
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)
4464   %z = xor i32 %y, %x
4465   %c = icmp ult i32 %z, 1073741824
4466   ret i1 %c
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
4478   %z = xor i32 %y, %x
4479   call void @use_i32(i32 %z)
4480   %c = icmp ult i32 %z, 1073741824
4481   ret i1 %c
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
4492   %z = xor i32 %y, %w
4493   %c = icmp ult i32 %z, 1073741824
4494   ret i1 %c
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]]
4504   %y = lshr i8 %x, 5
4505   %z = xor i8 %y, %x
4506   %c = icmp ult i8 %z, 2
4507   ret i1 %c
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
4519   %z = xor i32 %x, %y
4520   %c = icmp ult i32 %z, 1073741824
4521   ret i1 %c
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]]
4530   %y = ashr i8 %x, 5
4531   %z = xor i8 %y, %x
4532   %c = icmp ult i8 %z, 2
4533   ret i1 %c
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>
4547   ret <2 x i1> %c
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]]
4556   %y = ashr i32 %x, 1
4557   %z = xor i32 %y, %x
4558   %c = icmp ugt i32 %z, 3
4559   ret i1 %c
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]]
4568   %y = ashr i32 %x, 1
4569   %z = xor i32 %y, %x
4570   %c = icmp ugt i32 %z, 1073741823
4571   ret i1 %c
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
4581   %z = xor i32 %y, %x
4582   %c = icmp ugt i32 %z, 3
4583   ret i1 %c
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
4593   %z = xor i32 %y, %x
4594   %c = icmp ugt i32 %z, 1073741823
4595   ret i1 %c
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
4607   %a = and i8 %zx, %y
4608   %r = icmp eq i8 %a, 0
4609   ret i1 %r
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
4624   ret <2 x i1> %r
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
4635   %a = and i8 %zx, %y
4636   %r = icmp ne i8 %a, 0
4637   ret i1 %r
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
4649   %a = and i8 %zx, %y
4650   %r = icmp ne i8 %a, 1
4651   ret i1 %r
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>
4663   ret <2 x i1> %r
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
4676   %a = or i8 %zx, %y
4677   %r = icmp eq i8 %a, 0
4678   ret i1 %r
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
4695   ret i1 %r
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
4712   ret i1 %r
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
4725   %a = and i8 %zx, %y
4726   %r = icmp ne i8 %a, 0
4727   ret i1 %r
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]]
4737   %b = or i8 %a, 24
4738   %cmp = icmp sgt i8 %b, 0
4739   ret i1 %cmp
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>
4750   ret <2 x i1> %cmp
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>
4760   ret <2 x i1> %cmp
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]]
4768   %b = or i8 %a, 24
4769   %cmp = icmp sge i8 %b, 0
4770   ret i1 %cmp
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>
4781   ret <2 x i1> %cmp
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>
4791   ret <2 x i1> %cmp
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]]
4799   %b = or i8 %a, 24
4800   %cmp = icmp sge i8 %b, 24
4801   ret i1 %cmp
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>
4812   ret <2 x i1> %cmp
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>
4822   ret <2 x i1> %cmp
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]]
4830   %b = or i8 %a, 24
4831   %cmp = icmp sle i8 %b, 0
4832   ret i1 %cmp
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>
4843   ret <2 x i1> %cmp
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>
4853   ret <2 x i1> %cmp
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]]
4861   %b = or i8 %a, 24
4862   %cmp = icmp slt i8 %b, 0
4863   ret i1 %cmp
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>
4874   ret <2 x i1> %cmp
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>
4884   ret <2 x i1> %cmp
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]]
4892   %b = or i8 %a, 24
4893   %cmp = icmp slt i8 %b, 24
4894   ret i1 %cmp
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>
4905   ret <2 x i1> %cmp
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>
4915   ret <2 x i1> %cmp
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]]
4925   %b = or i8 %a, 24
4926   %cmp = icmp sgt i8 %b, -1
4927   ret i1 %cmp
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>
4938   ret <2 x i1> %cmp
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]]
4947   %b = or i8 %a, 24
4948   %cmp = icmp sge i8 %b, -1
4949   ret i1 %cmp
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>
4961   ret <2 x i1> %cmp
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]]
4970   %b = or i8 %a, 24
4971   %cmp = icmp sge i8 %b, 25
4972   ret i1 %cmp
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>
4984   ret <2 x i1> %cmp
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]]
4992   %b = or i8 %a, 24
4993   %cmp = icmp sle i8 %b, -1
4994   ret i1 %cmp
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>
5005   ret <2 x i1> %cmp
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]]
5014   %b = or i8 %a, 24
5015   %cmp = icmp slt i8 %b, -1
5016   ret i1 %cmp
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>
5028   ret <2 x i1> %cmp
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]]
5037   %b = or i8 %a, 24
5038   %cmp = icmp slt i8 %b, 25
5039   ret i1 %cmp
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>
5051   ret <2 x i1> %cmp
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]]
5061   %b = or i8 %a, 24
5062   call void @use_i8(i8 %b)
5063   %cmp = icmp sgt i8 %b, 0
5064   ret i1 %cmp
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
5077   ret i1 %icmp_
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
5088   %b1 = add i8 %b, 1
5089   %icmp_ = icmp sgt i8 %a1, %b1
5090   ret i1 %icmp_
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
5103   ret i1 %icmp_
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
5115   ret i1 %icmp_
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
5126   %b1 = add i8 %b, 1
5127   %icmp_ = icmp ugt i8 %a1, %b1
5128   ret i1 %icmp_
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
5141   ret i1 %icmp_
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]]
5151 entry:
5152   %add1 = add nuw i8 %b, 2
5153   %add2 = add i8 %a, 1
5154   %cmp = icmp eq i8 %add1, %add2
5155   ret i1 %cmp
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]]
5165 entry:
5166   %add1 = add nuw i8 %b, 2
5167   %add2 = add i8 %a, 1
5168   %cmp = icmp eq i8 %add2, %add1
5169   ret i1 %cmp
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]]
5179 entry:
5180   %add1 = add nuw i8 %b, -2
5181   %add2 = add i8 %a, -1
5182   %cmp = icmp eq i8 %add1, %add2
5183   ret i1 %cmp
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]]
5193 entry:
5194   %add1 = add nuw i8 %b, -2
5195   %add2 = add i8 %a, -1
5196   %cmp = icmp eq i8 %add2, %add1
5197   ret i1 %cmp
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
5212   ret i1 %cmp2
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
5223   ret i1 %cmp
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
5236   ret i1 %cmp
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
5247   ret i1 %cmp
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
5258   ret i1 %cmp
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
5268   ret i1 %cmp
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
5278   ret i1 %cmp
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
5288   ret i1 %cmp
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
5299   ret i1 %cmp
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)
5310   ret <2 x i1> %cmp
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
5319   ret i1 %cmp
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
5330   ret i1 %cmp
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
5340   ret i1 %cmp
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
5359   ret i1 %cmp
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
5379   ret i1 %cmp
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
5390   ret i1 %V
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
5401   ret i1 %V