[sanitizer] Improve FreeBSD ASLR detection
[llvm-project.git] / llvm / test / Transforms / InstCombine / icmp.ll
blob7d38013ee399199b2fad5f09f57d9ee20ed8178f
1 ; NOTE: Assertions have been autogenerated by utils/update_test_checks.py
2 ; RUN: opt < %s -instcombine -S | FileCheck %s
4 target datalayout = "e-p:64:64:64-p1:16:16:16-p2:32:32:32-p3:64:64:64-i1:8:8-i8:8:8-i16:16:16-i32:32:32-i64:64:64-f32:32:32-f64:64:64-v64:64:64-v128:128:128-a0:0:64-s0:64:64-f80:128:128-n8:16:32:64"
6 declare i8 @llvm.abs.i8(i8, i1)
8 define i32 @test1(i32 %X) {
9 ; CHECK-LABEL: @test1(
10 ; CHECK-NEXT:    [[X_LOBIT:%.*]] = lshr i32 [[X:%.*]], 31
11 ; CHECK-NEXT:    ret i32 [[X_LOBIT]]
13   %a = icmp slt i32 %X, 0
14   %b = zext i1 %a to i32
15   ret i32 %b
18 define <2 x i32> @test1vec(<2 x i32> %X) {
19 ; CHECK-LABEL: @test1vec(
20 ; CHECK-NEXT:    [[X_LOBIT:%.*]] = lshr <2 x i32> [[X:%.*]], <i32 31, i32 31>
21 ; CHECK-NEXT:    ret <2 x i32> [[X_LOBIT]]
23   %a = icmp slt <2 x i32> %X, zeroinitializer
24   %b = zext <2 x i1> %a to <2 x i32>
25   ret <2 x i32> %b
28 define i32 @test2(i32 %X) {
29 ; CHECK-LABEL: @test2(
30 ; CHECK-NEXT:    [[TMP1:%.*]] = xor i32 [[X:%.*]], -1
31 ; CHECK-NEXT:    [[X_LOBIT_NOT:%.*]] = lshr i32 [[TMP1]], 31
32 ; CHECK-NEXT:    ret i32 [[X_LOBIT_NOT]]
34   %a = icmp ult i32 %X, -2147483648
35   %b = zext i1 %a to i32
36   ret i32 %b
39 define <2 x i32> @test2vec(<2 x i32> %X) {
40 ; CHECK-LABEL: @test2vec(
41 ; CHECK-NEXT:    [[TMP1:%.*]] = xor <2 x i32> [[X:%.*]], <i32 -1, i32 -1>
42 ; CHECK-NEXT:    [[X_LOBIT_NOT:%.*]] = lshr <2 x i32> [[TMP1]], <i32 31, i32 31>
43 ; CHECK-NEXT:    ret <2 x i32> [[X_LOBIT_NOT]]
45   %a = icmp ult <2 x i32> %X, <i32 -2147483648, i32 -2147483648>
46   %b = zext <2 x i1> %a to <2 x i32>
47   ret <2 x i32> %b
50 define i32 @test3(i32 %X) {
51 ; CHECK-LABEL: @test3(
52 ; CHECK-NEXT:    [[X_LOBIT:%.*]] = ashr i32 [[X:%.*]], 31
53 ; CHECK-NEXT:    ret i32 [[X_LOBIT]]
55   %a = icmp slt i32 %X, 0
56   %b = sext i1 %a to i32
57   ret i32 %b
60 define i32 @test4(i32 %X) {
61 ; CHECK-LABEL: @test4(
62 ; CHECK-NEXT:    [[X_LOBIT:%.*]] = ashr i32 [[X:%.*]], 31
63 ; CHECK-NEXT:    [[X_LOBIT_NOT:%.*]] = xor i32 [[X_LOBIT]], -1
64 ; CHECK-NEXT:    ret i32 [[X_LOBIT_NOT]]
66   %a = icmp ult i32 %X, -2147483648
67   %b = sext i1 %a to i32
68   ret i32 %b
71 ; PR4837
72 define <2 x i1> @test5_eq(<2 x i64> %x) {
73 ; CHECK-LABEL: @test5_eq(
74 ; CHECK-NEXT:    ret <2 x i1> undef
76   %V = icmp eq <2 x i64> %x, undef
77   ret <2 x i1> %V
79 define <2 x i1> @test5_ne(<2 x i64> %x) {
80 ; CHECK-LABEL: @test5_ne(
81 ; CHECK-NEXT:    ret <2 x i1> undef
83   %V = icmp ne <2 x i64> %x, undef
84   ret <2 x i1> %V
86 define <2 x i1> @test5_ugt(<2 x i64> %x) {
87 ; CHECK-LABEL: @test5_ugt(
88 ; CHECK-NEXT:    ret <2 x i1> zeroinitializer
90   %V = icmp ugt <2 x i64> %x, undef
91   ret <2 x i1> %V
93 define <2 x i1> @test5_zero() {
94 ; CHECK-LABEL: @test5_zero(
95 ; CHECK-NEXT:    ret <2 x i1> undef
97   %V = icmp eq <2 x i64> zeroinitializer, undef
98   ret <2 x i1> %V
101 define i32 @test6(i32 %a, i32 %b) {
102 ; CHECK-LABEL: @test6(
103 ; CHECK-NEXT:    [[ISNEG:%.*]] = icmp slt i32 [[A:%.*]], 0
104 ; CHECK-NEXT:    [[F:%.*]] = select i1 [[ISNEG]], i32 [[B:%.*]], i32 0
105 ; CHECK-NEXT:    ret i32 [[F]]
107   %c = icmp sle i32 %a, -1
108   %d = zext i1 %c to i32
109   %e = sub i32 0, %d
110   %f = and i32 %e, %b
111   ret i32 %f
115 define i1 @test7(i32 %x) {
116 ; CHECK-LABEL: @test7(
117 ; CHECK-NEXT:    [[B:%.*]] = icmp ne i32 [[X:%.*]], 0
118 ; CHECK-NEXT:    ret i1 [[B]]
120   %a = add i32 %x, -1
121   %b = icmp ult i32 %a, %x
122   ret i1 %b
125 define <2 x i1> @test7_vec(<2 x i32> %x) {
126 ; CHECK-LABEL: @test7_vec(
127 ; CHECK-NEXT:    [[B:%.*]] = icmp ne <2 x i32> [[X:%.*]], zeroinitializer
128 ; CHECK-NEXT:    ret <2 x i1> [[B]]
130   %a = add <2 x i32> %x, <i32 -1, i32 -1>
131   %b = icmp ult <2 x i32> %a, %x
132   ret <2 x i1> %b
135 define i1 @test8(i32 %x) {
136 ; CHECK-LABEL: @test8(
137 ; CHECK-NEXT:    ret i1 false
139   %a = add i32 %x, -1
140   %b = icmp eq i32 %a, %x
141   ret i1 %b
144 define <2 x i1> @test8_vec(<2 x i32> %x) {
145 ; CHECK-LABEL: @test8_vec(
146 ; CHECK-NEXT:    ret <2 x i1> zeroinitializer
148   %a = add <2 x i32> %x, <i32 -1, i32 -1>
149   %b = icmp eq <2 x i32> %a, %x
150   ret <2 x i1> %b
153 define i1 @test9(i32 %x) {
154 ; CHECK-LABEL: @test9(
155 ; CHECK-NEXT:    [[B:%.*]] = icmp ugt i32 [[X:%.*]], 1
156 ; CHECK-NEXT:    ret i1 [[B]]
158   %a = add i32 %x, -2
159   %b = icmp ugt i32 %x, %a
160   ret i1 %b
163 define <2 x i1> @test9_vec(<2 x i32> %x) {
164 ; CHECK-LABEL: @test9_vec(
165 ; CHECK-NEXT:    [[B:%.*]] = icmp ugt <2 x i32> [[X:%.*]], <i32 1, i32 1>
166 ; CHECK-NEXT:    ret <2 x i1> [[B]]
168   %a = add <2 x i32> %x, <i32 -2, i32 -2>
169   %b = icmp ugt <2 x i32> %x, %a
170   ret <2 x i1> %b
173 define i1 @test9b(i32 %x) {
174 ; CHECK-LABEL: @test9b(
175 ; CHECK-NEXT:    [[B:%.*]] = icmp ult i32 [[X:%.*]], 2
176 ; CHECK-NEXT:    ret i1 [[B]]
178   %a = add i32 %x, -2
179   %b = icmp ugt i32 %a, %x
180   ret i1 %b
183 define <2 x i1> @test9b_vec(<2 x i32> %x) {
184 ; CHECK-LABEL: @test9b_vec(
185 ; CHECK-NEXT:    [[B:%.*]] = icmp ult <2 x i32> [[X:%.*]], <i32 2, i32 2>
186 ; CHECK-NEXT:    ret <2 x i1> [[B]]
188   %a = add <2 x i32> %x, <i32 -2, i32 -2>
189   %b = icmp ugt <2 x i32> %a, %x
190   ret <2 x i1> %b
193 define i1 @test10(i32 %x) {
194 ; CHECK-LABEL: @test10(
195 ; CHECK-NEXT:    [[B:%.*]] = icmp ne i32 [[X:%.*]], -2147483648
196 ; CHECK-NEXT:    ret i1 [[B]]
198   %a = add i32 %x, -1
199   %b = icmp slt i32 %a, %x
200   ret i1 %b
203 define <2 x i1> @test10_vec(<2 x i32> %x) {
204 ; CHECK-LABEL: @test10_vec(
205 ; CHECK-NEXT:    [[B:%.*]] = icmp ne <2 x i32> [[X:%.*]], <i32 -2147483648, i32 -2147483648>
206 ; CHECK-NEXT:    ret <2 x i1> [[B]]
208   %a = add <2 x i32> %x, <i32 -1, i32 -1>
209   %b = icmp slt <2 x i32> %a, %x
210   ret <2 x i1> %b
213 define i1 @test10b(i32 %x) {
214 ; CHECK-LABEL: @test10b(
215 ; CHECK-NEXT:    [[B:%.*]] = icmp eq i32 [[X:%.*]], -2147483648
216 ; CHECK-NEXT:    ret i1 [[B]]
218   %a = add i32 %x, -1
219   %b = icmp sgt i32 %a, %x
220   ret i1 %b
223 define <2 x i1> @test10b_vec(<2 x i32> %x) {
224 ; CHECK-LABEL: @test10b_vec(
225 ; CHECK-NEXT:    [[B:%.*]] = icmp eq <2 x i32> [[X:%.*]], <i32 -2147483648, i32 -2147483648>
226 ; CHECK-NEXT:    ret <2 x i1> [[B]]
228   %a = add <2 x i32> %x, <i32 -1, i32 -1>
229   %b = icmp sgt <2 x i32> %a, %x
230   ret <2 x i1> %b
233 define i1 @test11(i32 %x) {
234 ; CHECK-LABEL: @test11(
235 ; CHECK-NEXT:    ret i1 true
237   %a = add nsw i32 %x, 8
238   %b = icmp slt i32 %x, %a
239   ret i1 %b
242 define <2 x i1> @test11_vec(<2 x i32> %x) {
243 ; CHECK-LABEL: @test11_vec(
244 ; CHECK-NEXT:    ret <2 x i1> <i1 true, i1 true>
246   %a = add nsw <2 x i32> %x, <i32 8, i32 8>
247   %b = icmp slt <2 x i32> %x, %a
248   ret <2 x i1> %b
251 ; PR6195
252 define i1 @test12(i1 %A) {
253 ; CHECK-LABEL: @test12(
254 ; CHECK-NEXT:    [[NOT_A:%.*]] = xor i1 [[A:%.*]], true
255 ; CHECK-NEXT:    ret i1 [[NOT_A]]
257   %S = select i1 %A, i64 -4294967295, i64 8589934591
258   %B = icmp ne i64 bitcast (<2 x i32> <i32 1, i32 -1> to i64), %S
259   ret i1 %B
262 ; PR6481
263 define i1 @test13(i8 %X) {
264 ; CHECK-LABEL: @test13(
265 ; CHECK-NEXT:    ret i1 false
267   %cmp = icmp slt i8 undef, %X
268   ret i1 %cmp
271 define i1 @test14(i8 %X) {
272 ; CHECK-LABEL: @test14(
273 ; CHECK-NEXT:    ret i1 false
275   %cmp = icmp slt i8 undef, -128
276   ret i1 %cmp
279 define i1 @test15() {
280 ; CHECK-LABEL: @test15(
281 ; CHECK-NEXT:    ret i1 undef
283   %cmp = icmp eq i8 undef, -128
284   ret i1 %cmp
287 define i1 @test16() {
288 ; CHECK-LABEL: @test16(
289 ; CHECK-NEXT:    ret i1 undef
291   %cmp = icmp ne i8 undef, -128
292   ret i1 %cmp
295 define i1 @test17(i32 %x) {
296 ; CHECK-LABEL: @test17(
297 ; CHECK-NEXT:    [[CMP:%.*]] = icmp ne i32 [[X:%.*]], 3
298 ; CHECK-NEXT:    ret i1 [[CMP]]
300   %shl = shl i32 1, %x
301   %and = and i32 %shl, 8
302   %cmp = icmp eq i32 %and, 0
303   ret i1 %cmp
306 define <2 x i1> @test17vec(<2 x i32> %x) {
307 ; CHECK-LABEL: @test17vec(
308 ; CHECK-NEXT:    [[CMP:%.*]] = icmp ne <2 x i32> [[X:%.*]], <i32 3, i32 3>
309 ; CHECK-NEXT:    ret <2 x i1> [[CMP]]
311   %shl = shl <2 x i32> <i32 1, i32 1>, %x
312   %and = and <2 x i32> %shl, <i32 8, i32 8>
313   %cmp = icmp eq <2 x i32> %and, zeroinitializer
314   ret <2 x i1> %cmp
317 define i1 @test17a(i32 %x) {
318 ; CHECK-LABEL: @test17a(
319 ; CHECK-NEXT:    [[CMP:%.*]] = icmp ugt i32 [[X:%.*]], 2
320 ; CHECK-NEXT:    ret i1 [[CMP]]
322   %shl = shl i32 1, %x
323   %and = and i32 %shl, 7
324   %cmp = icmp eq i32 %and, 0
325   ret i1 %cmp
328 define <2 x i1> @test17a_vec(<2 x i32> %x) {
329 ; CHECK-LABEL: @test17a_vec(
330 ; CHECK-NEXT:    [[CMP:%.*]] = icmp ugt <2 x i32> [[X:%.*]], <i32 2, i32 2>
331 ; CHECK-NEXT:    ret <2 x i1> [[CMP]]
333   %shl = shl <2 x i32> <i32 1, i32 1>, %x
334   %and = and <2 x i32> %shl, <i32 7, i32 7>
335   %cmp = icmp eq <2 x i32> %and, zeroinitializer
336   ret <2 x i1> %cmp
339 define i1 @test18_eq(i32 %x) {
340 ; CHECK-LABEL: @test18_eq(
341 ; CHECK-NEXT:    [[CMP:%.*]] = icmp ne i32 [[X:%.*]], 3
342 ; CHECK-NEXT:    ret i1 [[CMP]]
344   %sh = lshr i32 8, %x
345   %and = and i32 %sh, 1
346   %cmp = icmp eq i32 %and, 0
347   ret i1 %cmp
350 define <2 x i1> @test18_eq_vec(<2 x i32> %x) {
351 ; CHECK-LABEL: @test18_eq_vec(
352 ; CHECK-NEXT:    [[CMP:%.*]] = icmp ne <2 x i32> [[X:%.*]], <i32 3, i32 3>
353 ; CHECK-NEXT:    ret <2 x i1> [[CMP]]
355   %sh = lshr <2 x i32> <i32 8, i32 8>, %x
356   %and = and <2 x i32> %sh, <i32 1, i32 1>
357   %cmp = icmp eq <2 x i32> %and, zeroinitializer
358   ret <2 x i1> %cmp
361 define i1 @test18_ne(i32 %x) {
362 ; CHECK-LABEL: @test18_ne(
363 ; CHECK-NEXT:    [[CMP:%.*]] = icmp eq i32 [[X:%.*]], 3
364 ; CHECK-NEXT:    ret i1 [[CMP]]
366   %sh = lshr i32 8, %x
367   %and = and i32 %sh, 1
368   %cmp = icmp ne i32 %and, 0
369   ret i1 %cmp
372 define <2 x i1> @test18_ne_vec(<2 x i32> %x) {
373 ; CHECK-LABEL: @test18_ne_vec(
374 ; CHECK-NEXT:    [[CMP:%.*]] = icmp eq <2 x i32> [[X:%.*]], <i32 3, i32 3>
375 ; CHECK-NEXT:    ret <2 x i1> [[CMP]]
377   %sh = lshr <2 x i32> <i32 8, i32 8>, %x
378   %and = and <2 x i32> %sh, <i32 1, i32 1>
379   %cmp = icmp ne <2 x i32> %and, zeroinitializer
380   ret <2 x i1> %cmp
383 define i1 @test19(i32 %x) {
384 ; CHECK-LABEL: @test19(
385 ; CHECK-NEXT:    [[CMP:%.*]] = icmp eq i32 [[X:%.*]], 3
386 ; CHECK-NEXT:    ret i1 [[CMP]]
388   %shl = shl i32 1, %x
389   %and = and i32 %shl, 8
390   %cmp = icmp eq i32 %and, 8
391   ret i1 %cmp
394 define <2 x i1> @test19vec(<2 x i32> %x) {
395 ; CHECK-LABEL: @test19vec(
396 ; CHECK-NEXT:    [[CMP:%.*]] = icmp eq <2 x i32> [[X:%.*]], <i32 3, i32 3>
397 ; CHECK-NEXT:    ret <2 x i1> [[CMP]]
399   %shl = shl <2 x i32> <i32 1, i32 1>, %x
400   %and = and <2 x i32> %shl, <i32 8, i32 8>
401   %cmp = icmp eq <2 x i32> %and, <i32 8, i32 8>
402   ret <2 x i1> %cmp
405 define <2 x i1> @cmp_and_signbit_vec(<2 x i3> %x) {
406 ; CHECK-LABEL: @cmp_and_signbit_vec(
407 ; CHECK-NEXT:    [[CMP:%.*]] = icmp slt <2 x i3> [[X:%.*]], zeroinitializer
408 ; CHECK-NEXT:    ret <2 x i1> [[CMP]]
410   %and = and <2 x i3> %x, <i3 4, i3 4>
411   %cmp = icmp ne <2 x i3> %and, zeroinitializer
412   ret <2 x i1> %cmp
415 define i1 @test20(i32 %x) {
416 ; CHECK-LABEL: @test20(
417 ; CHECK-NEXT:    [[CMP:%.*]] = icmp eq i32 [[X:%.*]], 3
418 ; CHECK-NEXT:    ret i1 [[CMP]]
420   %shl = shl i32 1, %x
421   %and = and i32 %shl, 8
422   %cmp = icmp ne i32 %and, 0
423   ret i1 %cmp
426 define <2 x i1> @test20vec(<2 x i32> %x) {
427 ; CHECK-LABEL: @test20vec(
428 ; CHECK-NEXT:    [[CMP:%.*]] = icmp eq <2 x i32> [[X:%.*]], <i32 3, i32 3>
429 ; CHECK-NEXT:    ret <2 x i1> [[CMP]]
431   %shl = shl <2 x i32> <i32 1, i32 1>, %x
432   %and = and <2 x i32> %shl, <i32 8, i32 8>
433   %cmp = icmp ne <2 x i32> %and, zeroinitializer
434   ret <2 x i1> %cmp
437 define i1 @test20a(i32 %x) {
438 ; CHECK-LABEL: @test20a(
439 ; CHECK-NEXT:    [[CMP:%.*]] = icmp ult i32 [[X:%.*]], 3
440 ; CHECK-NEXT:    ret i1 [[CMP]]
442   %shl = shl i32 1, %x
443   %and = and i32 %shl, 7
444   %cmp = icmp ne i32 %and, 0
445   ret i1 %cmp
448 define <2 x i1> @test20a_vec(<2 x i32> %x) {
449 ; CHECK-LABEL: @test20a_vec(
450 ; CHECK-NEXT:    [[CMP:%.*]] = icmp ult <2 x i32> [[X:%.*]], <i32 3, i32 3>
451 ; CHECK-NEXT:    ret <2 x i1> [[CMP]]
453   %shl = shl <2 x i32> <i32 1, i32 1>, %x
454   %and = and <2 x i32> %shl, <i32 7, i32 7>
455   %cmp = icmp ne <2 x i32> %and, zeroinitializer
456   ret <2 x i1> %cmp
459 define i1 @test21(i8 %x, i8 %y) {
460 ; CHECK-LABEL: @test21(
461 ; CHECK-NEXT:    [[B:%.*]] = icmp ugt i8 [[X:%.*]], 3
462 ; CHECK-NEXT:    ret i1 [[B]]
464   %A = or i8 %x, 1
465   %B = icmp ugt i8 %A, 3
466   ret i1 %B
469 define i1 @test22(i8 %x, i8 %y) {
470 ; CHECK-LABEL: @test22(
471 ; CHECK-NEXT:    [[B:%.*]] = icmp ult i8 [[X:%.*]], 4
472 ; CHECK-NEXT:    ret i1 [[B]]
474   %A = or i8 %x, 1
475   %B = icmp ult i8 %A, 4
476   ret i1 %B
479 ; PR2740
480 define i1 @test23(i32 %x) {
481 ; CHECK-LABEL: @test23(
482 ; CHECK-NEXT:    [[I4:%.*]] = icmp sgt i32 [[X:%.*]], 1328634634
483 ; CHECK-NEXT:    ret i1 [[I4]]
485   %i3 = sdiv i32 %x, -1328634635
486   %i4 = icmp eq i32 %i3, -1
487   ret i1 %i4
490 define <2 x i1> @test23vec(<2 x i32> %x) {
491 ; CHECK-LABEL: @test23vec(
492 ; CHECK-NEXT:    [[I4:%.*]] = icmp sgt <2 x i32> [[X:%.*]], <i32 1328634634, i32 1328634634>
493 ; CHECK-NEXT:    ret <2 x i1> [[I4]]
495   %i3 = sdiv <2 x i32> %x, <i32 -1328634635, i32 -1328634635>
496   %i4 = icmp eq <2 x i32> %i3, <i32 -1, i32 -1>
497   ret <2 x i1> %i4
500 ; Note: offs can be negative, LLVM used to make an incorrect assumption that
501 ; unsigned overflow does not happen during offset computation
502 define i1 @test24_neg_offs(i32* %p, i64 %offs) {
503 ; CHECK-LABEL: @test24_neg_offs(
504 ; CHECK-NEXT:    [[P1_IDX_NEG:%.*]] = mul i64 [[OFFS:%.*]], -4
505 ; CHECK-NEXT:    [[CMP:%.*]] = icmp eq i64 [[P1_IDX_NEG]], 8
506 ; CHECK-NEXT:    ret i1 [[CMP]]
508   %p1 = getelementptr inbounds i32, i32* %p, i64 %offs
509   %conv1 = ptrtoint i32* %p to i64
510   %conv2 = ptrtoint i32* %p1 to i64
511   %delta = sub i64 %conv1, %conv2
512   %cmp = icmp eq i64 %delta, 8
513   ret i1 %cmp
516 ; X - Z > Y - Z -> X > Y if there is no overflow.
517 define i1 @test27(i32 %x, i32 %y, i32 %z) {
518 ; CHECK-LABEL: @test27(
519 ; CHECK-NEXT:    [[C:%.*]] = icmp sgt i32 [[X:%.*]], [[Y:%.*]]
520 ; CHECK-NEXT:    ret i1 [[C]]
522   %lhs = sub nsw i32 %x, %z
523   %rhs = sub nsw i32 %y, %z
524   %c = icmp sgt i32 %lhs, %rhs
525   ret i1 %c
528 define i1 @test27_extra_uses(i32 %x, i32 %y, i32 %z) {
529 ; CHECK-LABEL: @test27_extra_uses(
530 ; CHECK-NEXT:    [[LHS:%.*]] = sub nsw i32 [[X:%.*]], [[Z:%.*]]
531 ; CHECK-NEXT:    call void @foo(i32 [[LHS]])
532 ; CHECK-NEXT:    [[RHS:%.*]] = sub nsw i32 [[Y:%.*]], [[Z]]
533 ; CHECK-NEXT:    call void @foo(i32 [[RHS]])
534 ; CHECK-NEXT:    [[C:%.*]] = icmp sgt i32 [[X]], [[Y]]
535 ; CHECK-NEXT:    ret i1 [[C]]
537   %lhs = sub nsw i32 %x, %z
538   call void @foo(i32 %lhs)
539   %rhs = sub nsw i32 %y, %z
540   call void @foo(i32 %rhs)
541   %c = icmp sgt i32 %lhs, %rhs
542   ret i1 %c
545 ; X - Z > Y - Z -> X > Y if there is no overflow.
546 define i1 @test28(i32 %x, i32 %y, i32 %z) {
547 ; CHECK-LABEL: @test28(
548 ; CHECK-NEXT:    [[C:%.*]] = icmp ugt i32 [[X:%.*]], [[Y:%.*]]
549 ; CHECK-NEXT:    ret i1 [[C]]
551   %lhs = sub nuw i32 %x, %z
552   %rhs = sub nuw i32 %y, %z
553   %c = icmp ugt i32 %lhs, %rhs
554   ret i1 %c
557 define i1 @test28_extra_uses(i32 %x, i32 %y, i32 %z) {
558 ; CHECK-LABEL: @test28_extra_uses(
559 ; CHECK-NEXT:    [[LHS:%.*]] = sub nuw i32 [[X:%.*]], [[Z:%.*]]
560 ; CHECK-NEXT:    call void @foo(i32 [[LHS]])
561 ; CHECK-NEXT:    [[RHS:%.*]] = sub nuw i32 [[Y:%.*]], [[Z]]
562 ; CHECK-NEXT:    call void @foo(i32 [[RHS]])
563 ; CHECK-NEXT:    [[C:%.*]] = icmp ugt i32 [[X]], [[Y]]
564 ; CHECK-NEXT:    ret i1 [[C]]
566   %lhs = sub nuw i32 %x, %z
567   call void @foo(i32 %lhs)
568   %rhs = sub nuw i32 %y, %z
569   call void @foo(i32 %rhs)
570   %c = icmp ugt i32 %lhs, %rhs
571   ret i1 %c
574 ; PR36969 - https://bugs.llvm.org/show_bug.cgi?id=36969
576 define i1 @ugt_sub(i32 %xsrc, i32 %y) {
577 ; CHECK-LABEL: @ugt_sub(
578 ; CHECK-NEXT:    [[X:%.*]] = udiv i32 [[XSRC:%.*]], 42
579 ; CHECK-NEXT:    [[CMP:%.*]] = icmp ult i32 [[X]], [[Y:%.*]]
580 ; CHECK-NEXT:    ret i1 [[CMP]]
582   %x = udiv i32 %xsrc, 42 ; thwart complexity-based canonicalization
583   %sub = sub i32 %x, %y
584   %cmp = icmp ugt i32 %sub, %x
585   ret i1 %cmp
588 ; Swap operands and predicate. Try a vector type to verify that works too.
590 define <2 x i1> @ult_sub(<2 x i8> %xsrc, <2 x i8> %y) {
591 ; CHECK-LABEL: @ult_sub(
592 ; CHECK-NEXT:    [[X:%.*]] = udiv <2 x i8> [[XSRC:%.*]], <i8 42, i8 -42>
593 ; CHECK-NEXT:    [[CMP:%.*]] = icmp ult <2 x i8> [[X]], [[Y:%.*]]
594 ; CHECK-NEXT:    ret <2 x i1> [[CMP]]
596   %x = udiv <2 x i8> %xsrc, <i8 42, i8 -42> ; thwart complexity-based canonicalization
597   %sub = sub <2 x i8> %x, %y
598   %cmp = icmp ult <2 x i8> %x, %sub
599   ret <2 x i1> %cmp
602 ; X - Y > X -> 0 > Y if there is no overflow.
603 define i1 @test33(i32 %x, i32 %y) {
604 ; CHECK-LABEL: @test33(
605 ; CHECK-NEXT:    [[C:%.*]] = icmp slt i32 [[Y:%.*]], 0
606 ; CHECK-NEXT:    ret i1 [[C]]
608   %lhs = sub nsw i32 %x, %y
609   %c = icmp sgt i32 %lhs, %x
610   ret i1 %c
613 ; X - Y > X -> 0 > Y if there is no overflow.
614 define i1 @test34(i32 %x, i32 %y) {
615 ; CHECK-LABEL: @test34(
616 ; CHECK-NEXT:    ret i1 false
618   %lhs = sub nuw i32 %x, %y
619   %c = icmp ugt i32 %lhs, %x
620   ret i1 %c
623 ; X > X - Y -> Y > 0 if there is no overflow.
624 define i1 @test35(i32 %x, i32 %y) {
625 ; CHECK-LABEL: @test35(
626 ; CHECK-NEXT:    [[C:%.*]] = icmp sgt i32 [[Y:%.*]], 0
627 ; CHECK-NEXT:    ret i1 [[C]]
629   %rhs = sub nsw i32 %x, %y
630   %c = icmp sgt i32 %x, %rhs
631   ret i1 %c
634 ; X > X - Y -> Y > 0 if there is no overflow.
635 define i1 @test36(i32 %x, i32 %y) {
636 ; CHECK-LABEL: @test36(
637 ; CHECK-NEXT:    [[C:%.*]] = icmp ne i32 [[Y:%.*]], 0
638 ; CHECK-NEXT:    ret i1 [[C]]
640   %rhs = sub nuw i32 %x, %y
641   %c = icmp ugt i32 %x, %rhs
642   ret i1 %c
645 ; X - Y > X - Z -> Z > Y if there is no overflow.
646 define i1 @test37(i32 %x, i32 %y, i32 %z) {
647 ; CHECK-LABEL: @test37(
648 ; CHECK-NEXT:    [[C:%.*]] = icmp sgt i32 [[Z:%.*]], [[Y:%.*]]
649 ; CHECK-NEXT:    ret i1 [[C]]
651   %lhs = sub nsw i32 %x, %y
652   %rhs = sub nsw i32 %x, %z
653   %c = icmp sgt i32 %lhs, %rhs
654   ret i1 %c
657 define i1 @test37_extra_uses(i32 %x, i32 %y, i32 %z) {
658 ; CHECK-LABEL: @test37_extra_uses(
659 ; CHECK-NEXT:    [[LHS:%.*]] = sub nsw i32 [[X:%.*]], [[Y:%.*]]
660 ; CHECK-NEXT:    call void @foo(i32 [[LHS]])
661 ; CHECK-NEXT:    [[RHS:%.*]] = sub nsw i32 [[X]], [[Z:%.*]]
662 ; CHECK-NEXT:    call void @foo(i32 [[RHS]])
663 ; CHECK-NEXT:    [[C:%.*]] = icmp sgt i32 [[Z]], [[Y]]
664 ; CHECK-NEXT:    ret i1 [[C]]
666   %lhs = sub nsw i32 %x, %y
667   call void @foo(i32 %lhs)
668   %rhs = sub nsw i32 %x, %z
669   call void @foo(i32 %rhs)
670   %c = icmp sgt i32 %lhs, %rhs
671   ret i1 %c
674 ; TODO: Min/max pattern should not prevent the fold.
676 define i32 @neg_max_s32(i32 %x, i32 %y) {
677 ; CHECK-LABEL: @neg_max_s32(
678 ; CHECK-NEXT:    [[C:%.*]] = icmp slt i32 [[Y:%.*]], [[X:%.*]]
679 ; CHECK-NEXT:    [[S_NEG:%.*]] = select i1 [[C]], i32 [[Y]], i32 [[X]]
680 ; CHECK-NEXT:    ret i32 [[S_NEG]]
682   %nx = sub nsw i32 0, %x
683   %ny = sub nsw i32 0, %y
684   %c = icmp slt i32 %nx, %ny
685   %s = select i1 %c, i32 %ny, i32 %nx
686   %r = sub nsw i32 0, %s
687   ret i32 %r
690 define <4 x i32> @neg_max_v4s32(<4 x i32> %x, <4 x i32> %y) {
691 ; CHECK-LABEL: @neg_max_v4s32(
692 ; CHECK-NEXT:    [[C:%.*]] = icmp sgt <4 x i32> [[Y:%.*]], [[X:%.*]]
693 ; CHECK-NEXT:    [[S_NEG:%.*]] = select <4 x i1> [[C]], <4 x i32> [[X]], <4 x i32> [[Y]]
694 ; CHECK-NEXT:    ret <4 x i32> [[S_NEG]]
696   %nx = sub nsw <4 x i32> zeroinitializer, %x
697   %ny = sub nsw <4 x i32> zeroinitializer, %y
698   %c = icmp sgt <4 x i32> %nx, %ny
699   %s = select <4 x i1> %c, <4 x i32> %nx, <4 x i32> %ny
700   %r = sub <4 x i32> zeroinitializer, %s
701   ret <4 x i32> %r
704 ; X - Y > X - Z -> Z > Y if there is no overflow.
705 define i1 @test38(i32 %x, i32 %y, i32 %z) {
706 ; CHECK-LABEL: @test38(
707 ; CHECK-NEXT:    [[C:%.*]] = icmp ugt i32 [[Z:%.*]], [[Y:%.*]]
708 ; CHECK-NEXT:    ret i1 [[C]]
710   %lhs = sub nuw i32 %x, %y
711   %rhs = sub nuw i32 %x, %z
712   %c = icmp ugt i32 %lhs, %rhs
713   ret i1 %c
716 define i1 @test38_extra_uses(i32 %x, i32 %y, i32 %z) {
717 ; CHECK-LABEL: @test38_extra_uses(
718 ; CHECK-NEXT:    [[LHS:%.*]] = sub nuw i32 [[X:%.*]], [[Y:%.*]]
719 ; CHECK-NEXT:    call void @foo(i32 [[LHS]])
720 ; CHECK-NEXT:    [[RHS:%.*]] = sub nuw i32 [[X]], [[Z:%.*]]
721 ; CHECK-NEXT:    call void @foo(i32 [[RHS]])
722 ; CHECK-NEXT:    [[C:%.*]] = icmp ugt i32 [[Z]], [[Y]]
723 ; CHECK-NEXT:    ret i1 [[C]]
725   %lhs = sub nuw i32 %x, %y
726   call void @foo(i32 %lhs)
727   %rhs = sub nuw i32 %x, %z
728   call void @foo(i32 %rhs)
729   %c = icmp ugt i32 %lhs, %rhs
730   ret i1 %c
733 define i1 @shr_exact(i132 %x) {
734 ; CHECK-LABEL: @shr_exact(
735 ; CHECK-NEXT:    [[CMP:%.*]] = icmp eq i132 [[X:%.*]], 32
736 ; CHECK-NEXT:    ret i1 [[CMP]]
738   %sh = ashr exact i132 %x, 4
739   %cmp = icmp eq i132 %sh, 2
740   ret i1 %cmp
743 define <2 x i1> @shr_exact_vec(<2 x i132> %x) {
744 ; CHECK-LABEL: @shr_exact_vec(
745 ; CHECK-NEXT:    [[CMP:%.*]] = icmp ne <2 x i132> [[X:%.*]], <i132 32, i132 32>
746 ; CHECK-NEXT:    ret <2 x i1> [[CMP]]
748   %sh = lshr exact <2 x i132> %x, <i132 4, i132 4>
749   %cmp = icmp ne <2 x i132> %sh, <i132 2, i132 2>
750   ret <2 x i1> %cmp
753 ; PR9343 #3
754 define i1 @test41(i32 %X, i32 %Y) {
755 ; CHECK-LABEL: @test41(
756 ; CHECK-NEXT:    ret i1 true
758   %A = urem i32 %X, %Y
759   %B = icmp ugt i32 %Y, %A
760   ret i1 %B
763 define i1 @test42(i32 %X, i32 %Y) {
764 ; CHECK-LABEL: @test42(
765 ; CHECK-NEXT:    [[B:%.*]] = icmp sgt i32 [[Y:%.*]], -1
766 ; CHECK-NEXT:    ret i1 [[B]]
768   %A = srem i32 %X, %Y
769   %B = icmp slt i32 %A, %Y
770   ret i1 %B
773 define i1 @test43(i32 %X, i32 %Y) {
774 ; CHECK-LABEL: @test43(
775 ; CHECK-NEXT:    [[B:%.*]] = icmp slt i32 [[Y:%.*]], 0
776 ; CHECK-NEXT:    ret i1 [[B]]
778   %A = srem i32 %X, %Y
779   %B = icmp slt i32 %Y, %A
780   ret i1 %B
783 define i1 @test44(i32 %X, i32 %Y) {
784 ; CHECK-LABEL: @test44(
785 ; CHECK-NEXT:    [[B:%.*]] = icmp sgt i32 [[Y:%.*]], -1
786 ; CHECK-NEXT:    ret i1 [[B]]
788   %A = srem i32 %X, %Y
789   %B = icmp slt i32 %A, %Y
790   ret i1 %B
793 define i1 @test45(i32 %X, i32 %Y) {
794 ; CHECK-LABEL: @test45(
795 ; CHECK-NEXT:    [[B:%.*]] = icmp slt i32 [[Y:%.*]], 0
796 ; CHECK-NEXT:    ret i1 [[B]]
798   %A = srem i32 %X, %Y
799   %B = icmp slt i32 %Y, %A
800   ret i1 %B
803 ; PR9343 #4
804 define i1 @test46(i32 %X, i32 %Y, i32 %Z) {
805 ; CHECK-LABEL: @test46(
806 ; CHECK-NEXT:    [[C:%.*]] = icmp ult i32 [[X:%.*]], [[Y:%.*]]
807 ; CHECK-NEXT:    ret i1 [[C]]
809   %A = ashr exact i32 %X, %Z
810   %B = ashr exact i32 %Y, %Z
811   %C = icmp ult i32 %A, %B
812   ret i1 %C
815 ; PR9343 #5
816 define i1 @test47(i32 %X, i32 %Y, i32 %Z) {
817 ; CHECK-LABEL: @test47(
818 ; CHECK-NEXT:    [[C:%.*]] = icmp ugt i32 [[X:%.*]], [[Y:%.*]]
819 ; CHECK-NEXT:    ret i1 [[C]]
821   %A = ashr exact i32 %X, %Z
822   %B = ashr exact i32 %Y, %Z
823   %C = icmp ugt i32 %A, %B
824   ret i1 %C
827 ; PR9343 #8
828 define i1 @test48(i32 %X, i32 %Y, i32 %Z) {
829 ; CHECK-LABEL: @test48(
830 ; CHECK-NEXT:    [[C:%.*]] = icmp eq i32 [[X:%.*]], [[Y:%.*]]
831 ; CHECK-NEXT:    ret i1 [[C]]
833   %A = sdiv exact i32 %X, %Z
834   %B = sdiv exact i32 %Y, %Z
835   %C = icmp eq i32 %A, %B
836   ret i1 %C
839 ; The above transform only works for equality predicates.
841 define i1 @PR32949(i32 %X, i32 %Y, i32 %Z) {
842 ; CHECK-LABEL: @PR32949(
843 ; CHECK-NEXT:    [[A:%.*]] = sdiv exact i32 [[X:%.*]], [[Z:%.*]]
844 ; CHECK-NEXT:    [[B:%.*]] = sdiv exact i32 [[Y:%.*]], [[Z]]
845 ; CHECK-NEXT:    [[C:%.*]] = icmp sgt i32 [[A]], [[B]]
846 ; CHECK-NEXT:    ret i1 [[C]]
848   %A = sdiv exact i32 %X, %Z
849   %B = sdiv exact i32 %Y, %Z
850   %C = icmp sgt i32 %A, %B
851   ret i1 %C
854 ; PR8469
855 define <2 x i1> @test49(<2 x i32> %i3) {
856 ; CHECK-LABEL: @test49(
857 ; CHECK-NEXT:  entry:
858 ; CHECK-NEXT:    ret <2 x i1> <i1 true, i1 true>
860 entry:
861   %i11 = and <2 x i32> %i3, <i32 3, i32 3>
862   %cmp = icmp ult <2 x i32> %i11, <i32 4, i32 4>
863   ret <2 x i1> %cmp
866 ; PR9343 #7
867 define i1 @test50(i16 %X, i32 %Y) {
868 ; CHECK-LABEL: @test50(
869 ; CHECK-NEXT:    ret i1 true
871   %A = zext i16 %X to i32
872   %B = srem i32 %A, %Y
873   %C = icmp sgt i32 %B, -1
874   ret i1 %C
877 define i1 @test51(i32 %X, i32 %Y) {
878 ; CHECK-LABEL: @test51(
879 ; CHECK-NEXT:    [[A:%.*]] = and i32 [[X:%.*]], -2147483648
880 ; CHECK-NEXT:    [[B:%.*]] = srem i32 [[A]], [[Y:%.*]]
881 ; CHECK-NEXT:    [[C:%.*]] = icmp sgt i32 [[B]], -1
882 ; CHECK-NEXT:    ret i1 [[C]]
884   %A = and i32 %X, 2147483648
885   %B = srem i32 %A, %Y
886   %C = icmp sgt i32 %B, -1
887   ret i1 %C
890 define i1 @test52(i32 %x1) {
891 ; CHECK-LABEL: @test52(
892 ; CHECK-NEXT:    [[TMP1:%.*]] = and i32 [[X1:%.*]], 16711935
893 ; CHECK-NEXT:    [[TMP2:%.*]] = icmp eq i32 [[TMP1]], 4980863
894 ; CHECK-NEXT:    ret i1 [[TMP2]]
896   %conv = and i32 %x1, 255
897   %cmp = icmp eq i32 %conv, 127
898   %i2 = lshr i32 %x1, 16
899   %i3 = trunc i32 %i2 to i8
900   %cmp15 = icmp eq i8 %i3, 76
902   %A = and i1 %cmp, %cmp15
903   ret i1 %A
906 define i1 @test52_logical(i32 %x1) {
907 ; CHECK-LABEL: @test52_logical(
908 ; CHECK-NEXT:    [[TMP1:%.*]] = and i32 [[X1:%.*]], 16711935
909 ; CHECK-NEXT:    [[TMP2:%.*]] = icmp eq i32 [[TMP1]], 4980863
910 ; CHECK-NEXT:    ret i1 [[TMP2]]
912   %conv = and i32 %x1, 255
913   %cmp = icmp eq i32 %conv, 127
914   %i2 = lshr i32 %x1, 16
915   %i3 = trunc i32 %i2 to i8
916   %cmp15 = icmp eq i8 %i3, 76
918   %A = select i1 %cmp, i1 %cmp15, i1 false
919   ret i1 %A
922 define i1 @test52b(i128 %x1) {
923 ; CHECK-LABEL: @test52b(
924 ; CHECK-NEXT:    [[TMP1:%.*]] = and i128 [[X1:%.*]], 16711935
925 ; CHECK-NEXT:    [[TMP2:%.*]] = icmp eq i128 [[TMP1]], 4980863
926 ; CHECK-NEXT:    ret i1 [[TMP2]]
928   %conv = and i128 %x1, 255
929   %cmp = icmp eq i128 %conv, 127
930   %i2 = lshr i128 %x1, 16
931   %i3 = trunc i128 %i2 to i8
932   %cmp15 = icmp eq i8 %i3, 76
934   %A = and i1 %cmp, %cmp15
935   ret i1 %A
938 define i1 @test52b_logical(i128 %x1) {
939 ; CHECK-LABEL: @test52b_logical(
940 ; CHECK-NEXT:    [[TMP1:%.*]] = and i128 [[X1:%.*]], 16711935
941 ; CHECK-NEXT:    [[TMP2:%.*]] = icmp eq i128 [[TMP1]], 4980863
942 ; CHECK-NEXT:    ret i1 [[TMP2]]
944   %conv = and i128 %x1, 255
945   %cmp = icmp eq i128 %conv, 127
946   %i2 = lshr i128 %x1, 16
947   %i3 = trunc i128 %i2 to i8
948   %cmp15 = icmp eq i8 %i3, 76
950   %A = select i1 %cmp, i1 %cmp15, i1 false
951   ret i1 %A
954 ; PR9838
955 define i1 @test53(i32 %a, i32 %b) {
956 ; CHECK-LABEL: @test53(
957 ; CHECK-NEXT:    [[X:%.*]] = sdiv exact i32 [[A:%.*]], 30
958 ; CHECK-NEXT:    [[Y:%.*]] = sdiv i32 [[B:%.*]], 30
959 ; CHECK-NEXT:    [[Z:%.*]] = icmp eq i32 [[X]], [[Y]]
960 ; CHECK-NEXT:    ret i1 [[Z]]
962   %x = sdiv exact i32 %a, 30
963   %y = sdiv i32 %b, 30
964   %z = icmp eq i32 %x, %y
965   ret i1 %z
968 define i1 @test54(i8 %a) {
969 ; CHECK-LABEL: @test54(
970 ; CHECK-NEXT:    [[TMP1:%.*]] = and i8 [[A:%.*]], -64
971 ; CHECK-NEXT:    [[RET:%.*]] = icmp eq i8 [[TMP1]], -128
972 ; CHECK-NEXT:    ret i1 [[RET]]
974   %ext = zext i8 %a to i32
975   %and = and i32 %ext, 192
976   %ret = icmp eq i32 %and, 128
977   ret i1 %ret
980 define i1 @test55(i32 %a) {
981 ; CHECK-LABEL: @test55(
982 ; CHECK-NEXT:    [[CMP:%.*]] = icmp eq i32 [[A:%.*]], -123
983 ; CHECK-NEXT:    ret i1 [[CMP]]
985   %sub = sub i32 0, %a
986   %cmp = icmp eq i32 %sub, 123
987   ret i1 %cmp
990 define <2 x i1> @test55vec(<2 x i32> %a) {
991 ; CHECK-LABEL: @test55vec(
992 ; CHECK-NEXT:    [[CMP:%.*]] = icmp eq <2 x i32> [[A:%.*]], <i32 -123, i32 -123>
993 ; CHECK-NEXT:    ret <2 x i1> [[CMP]]
995   %sub = sub <2 x i32> zeroinitializer, %a
996   %cmp = icmp eq <2 x i32> %sub, <i32 123, i32 123>
997   ret <2 x i1> %cmp
1000 define i1 @test56(i32 %a) {
1001 ; CHECK-LABEL: @test56(
1002 ; CHECK-NEXT:    [[CMP:%.*]] = icmp eq i32 [[A:%.*]], -113
1003 ; CHECK-NEXT:    ret i1 [[CMP]]
1005   %sub = sub i32 10, %a
1006   %cmp = icmp eq i32 %sub, 123
1007   ret i1 %cmp
1010 define <2 x i1> @test56vec(<2 x i32> %a) {
1011 ; CHECK-LABEL: @test56vec(
1012 ; CHECK-NEXT:    [[CMP:%.*]] = icmp eq <2 x i32> [[A:%.*]], <i32 -113, i32 -113>
1013 ; CHECK-NEXT:    ret <2 x i1> [[CMP]]
1015   %sub = sub <2 x i32> <i32 10, i32 10>, %a
1016   %cmp = icmp eq <2 x i32> %sub, <i32 123, i32 123>
1017   ret <2 x i1> %cmp
1020 ; PR10267 Don't make icmps more expensive when no other inst is subsumed.
1021 declare void @foo(i32)
1022 define i1 @test57(i32 %a) {
1023 ; CHECK-LABEL: @test57(
1024 ; CHECK-NEXT:    [[AND:%.*]] = and i32 [[A:%.*]], -2
1025 ; CHECK-NEXT:    [[CMP:%.*]] = icmp ne i32 [[AND]], 0
1026 ; CHECK-NEXT:    call void @foo(i32 [[AND]])
1027 ; CHECK-NEXT:    ret i1 [[CMP]]
1029   %and = and i32 %a, -2
1030   %cmp = icmp ne i32 %and, 0
1031   call void @foo(i32 %and)
1032   ret i1 %cmp
1035 ; rdar://problem/10482509
1036 define zeroext i1 @cmpabs1(i64 %val) {
1037 ; CHECK-LABEL: @cmpabs1(
1038 ; CHECK-NEXT:    [[TOBOOL:%.*]] = icmp ne i64 [[VAL:%.*]], 0
1039 ; CHECK-NEXT:    ret i1 [[TOBOOL]]
1041   %sub = sub nsw i64 0, %val
1042   %cmp = icmp slt i64 %val, 0
1043   %sub.val = select i1 %cmp, i64 %sub, i64 %val
1044   %tobool = icmp ne i64 %sub.val, 0
1045   ret i1 %tobool
1048 define zeroext i1 @cmpabs2(i64 %val) {
1049 ; CHECK-LABEL: @cmpabs2(
1050 ; CHECK-NEXT:    [[TOBOOL:%.*]] = icmp ne i64 [[VAL:%.*]], 0
1051 ; CHECK-NEXT:    ret i1 [[TOBOOL]]
1053   %sub = sub nsw i64 0, %val
1054   %cmp = icmp slt i64 %val, 0
1055   %sub.val = select i1 %cmp, i64 %val, i64 %sub
1056   %tobool = icmp ne i64 %sub.val, 0
1057   ret i1 %tobool
1060 define i1 @abs_intrin_eq_zero(i8 %x) {
1061 ; CHECK-LABEL: @abs_intrin_eq_zero(
1062 ; CHECK-NEXT:    [[CMP:%.*]] = icmp eq i8 [[X:%.*]], 0
1063 ; CHECK-NEXT:    ret i1 [[CMP]]
1065   %abs = call i8 @llvm.abs.i8(i8 %x, i1 false)
1066   %cmp = icmp eq i8 %abs, 0
1067   ret i1 %cmp
1070 define i1 @abs_intrin_ne_zero(i8 %x) {
1071 ; CHECK-LABEL: @abs_intrin_ne_zero(
1072 ; CHECK-NEXT:    [[CMP:%.*]] = icmp ne i8 [[X:%.*]], 0
1073 ; CHECK-NEXT:    ret i1 [[CMP]]
1075   %abs = call i8 @llvm.abs.i8(i8 %x, i1 false)
1076   %cmp = icmp ne i8 %abs, 0
1077   ret i1 %cmp
1080 define void @test58() {
1081 ; CHECK-LABEL: @test58(
1082 ; CHECK-NEXT:    [[CALL:%.*]] = call i32 @test58_d(i64 36029346783166592)
1083 ; CHECK-NEXT:    ret void
1085   %cast = bitcast <1 x i64> <i64 36029346783166592> to i64
1086   %call = call i32 @test58_d( i64 %cast)
1087   ret void
1089 declare i32 @test58_d(i64)
1091 ; Negative test: GEP inbounds may cross sign boundary.
1092 define i1 @test62(i8* %a) {
1093 ; CHECK-LABEL: @test62(
1094 ; CHECK-NEXT:    [[ARRAYIDX1:%.*]] = getelementptr inbounds i8, i8* [[A:%.*]], i64 1
1095 ; CHECK-NEXT:    [[ARRAYIDX2:%.*]] = getelementptr inbounds i8, i8* [[A]], i64 10
1096 ; CHECK-NEXT:    [[CMP:%.*]] = icmp slt i8* [[ARRAYIDX1]], [[ARRAYIDX2]]
1097 ; CHECK-NEXT:    ret i1 [[CMP]]
1099   %arrayidx1 = getelementptr inbounds i8, i8* %a, i64 1
1100   %arrayidx2 = getelementptr inbounds i8, i8* %a, i64 10
1101   %cmp = icmp slt i8* %arrayidx1, %arrayidx2
1102   ret i1 %cmp
1105 define i1 @test62_as1(i8 addrspace(1)* %a) {
1106 ; CHECK-LABEL: @test62_as1(
1107 ; CHECK-NEXT:    [[ARRAYIDX1:%.*]] = getelementptr inbounds i8, i8 addrspace(1)* [[A:%.*]], i16 1
1108 ; CHECK-NEXT:    [[ARRAYIDX2:%.*]] = getelementptr inbounds i8, i8 addrspace(1)* [[A]], i16 10
1109 ; CHECK-NEXT:    [[CMP:%.*]] = icmp slt i8 addrspace(1)* [[ARRAYIDX1]], [[ARRAYIDX2]]
1110 ; CHECK-NEXT:    ret i1 [[CMP]]
1112   %arrayidx1 = getelementptr inbounds i8, i8 addrspace(1)* %a, i64 1
1113   %arrayidx2 = getelementptr inbounds i8, i8 addrspace(1)* %a, i64 10
1114   %cmp = icmp slt i8 addrspace(1)* %arrayidx1, %arrayidx2
1115   ret i1 %cmp
1118 define i1 @test63(i8 %a, i32 %b) {
1119 ; CHECK-LABEL: @test63(
1120 ; CHECK-NEXT:    [[TMP1:%.*]] = trunc i32 [[B:%.*]] to i8
1121 ; CHECK-NEXT:    [[C:%.*]] = icmp eq i8 [[TMP1]], [[A:%.*]]
1122 ; CHECK-NEXT:    ret i1 [[C]]
1124   %z = zext i8 %a to i32
1125   %t = and i32 %b, 255
1126   %c = icmp eq i32 %z, %t
1127   ret i1 %c
1130 define i1 @test64(i8 %a, i32 %b) {
1131 ; CHECK-LABEL: @test64(
1132 ; CHECK-NEXT:    [[TMP1:%.*]] = trunc i32 [[B:%.*]] to i8
1133 ; CHECK-NEXT:    [[C:%.*]] = icmp eq i8 [[TMP1]], [[A:%.*]]
1134 ; CHECK-NEXT:    ret i1 [[C]]
1136   %t = and i32 %b, 255
1137   %z = zext i8 %a to i32
1138   %c = icmp eq i32 %t, %z
1139   ret i1 %c
1142 define i1 @test65(i64 %A, i64 %B) {
1143 ; CHECK-LABEL: @test65(
1144 ; CHECK-NEXT:    ret i1 true
1146   %s1 = add i64 %A, %B
1147   %s2 = add i64 %A, %B
1148   %cmp = icmp eq i64 %s1, %s2
1149   ret i1 %cmp
1152 define i1 @test66(i64 %A, i64 %B) {
1153 ; CHECK-LABEL: @test66(
1154 ; CHECK-NEXT:    ret i1 true
1156   %s1 = add i64 %A, %B
1157   %s2 = add i64 %B, %A
1158   %cmp = icmp eq i64 %s1, %s2
1159   ret i1 %cmp
1162 define i1 @test67(i32 %x) {
1163 ; CHECK-LABEL: @test67(
1164 ; CHECK-NEXT:    [[AND:%.*]] = and i32 [[X:%.*]], 96
1165 ; CHECK-NEXT:    [[CMP:%.*]] = icmp ne i32 [[AND]], 0
1166 ; CHECK-NEXT:    ret i1 [[CMP]]
1168   %and = and i32 %x, 127
1169   %cmp = icmp sgt i32 %and, 31
1170   ret i1 %cmp
1173 define i1 @test67inverse(i32 %x) {
1174 ; CHECK-LABEL: @test67inverse(
1175 ; CHECK-NEXT:    [[AND:%.*]] = and i32 [[X:%.*]], 96
1176 ; CHECK-NEXT:    [[CMP:%.*]] = icmp eq i32 [[AND]], 0
1177 ; CHECK-NEXT:    ret i1 [[CMP]]
1179   %and = and i32 %x, 127
1180   %cmp = icmp sle i32 %and, 31
1181   ret i1 %cmp
1184 ; The test above relies on 3 different folds.
1185 ; This test only checks the last of those (icmp ugt -> icmp ne).
1187 define <2 x i1> @test67vec(<2 x i32> %x) {
1188 ; CHECK-LABEL: @test67vec(
1189 ; CHECK-NEXT:    [[AND:%.*]] = and <2 x i32> [[X:%.*]], <i32 96, i32 96>
1190 ; CHECK-NEXT:    [[CMP:%.*]] = icmp ne <2 x i32> [[AND]], zeroinitializer
1191 ; CHECK-NEXT:    ret <2 x i1> [[CMP]]
1193   %and = and <2 x i32> %x, <i32 96, i32 96>
1194   %cmp = icmp ugt <2 x i32> %and, <i32 31, i32 31>
1195   ret <2 x i1> %cmp
1198 define <2 x i1> @test67vec2(<2 x i32> %x) {
1199 ; CHECK-LABEL: @test67vec2(
1200 ; CHECK-NEXT:    [[AND:%.*]] = and <2 x i32> [[X:%.*]], <i32 96, i32 96>
1201 ; CHECK-NEXT:    [[CMP:%.*]] = icmp ne <2 x i32> [[AND]], zeroinitializer
1202 ; CHECK-NEXT:    ret <2 x i1> [[CMP]]
1204   %and = and <2 x i32> %x, <i32 127, i32 127>
1205   %cmp = icmp ugt <2 x i32> %and, <i32 31, i32 31>
1206   ret <2 x i1> %cmp
1209 define <2 x i1> @test67vecinverse(<2 x i32> %x) {
1210 ; CHECK-LABEL: @test67vecinverse(
1211 ; CHECK-NEXT:    [[AND:%.*]] = and <2 x i32> [[X:%.*]], <i32 96, i32 96>
1212 ; CHECK-NEXT:    [[CMP:%.*]] = icmp eq <2 x i32> [[AND]], zeroinitializer
1213 ; CHECK-NEXT:    ret <2 x i1> [[CMP]]
1215   %and = and <2 x i32> %x, <i32 96, i32 96>
1216   %cmp = icmp sle <2 x i32> %and, <i32 31, i32 31>
1217   ret <2 x i1> %cmp
1220 define i1 @test68(i32 %x) {
1221 ; CHECK-LABEL: @test68(
1222 ; CHECK-NEXT:    [[AND:%.*]] = and i32 [[X:%.*]], 127
1223 ; CHECK-NEXT:    [[CMP:%.*]] = icmp ugt i32 [[AND]], 30
1224 ; CHECK-NEXT:    ret i1 [[CMP]]
1226   %and = and i32 %x, 127
1227   %cmp = icmp sgt i32 %and, 30
1228   ret i1 %cmp
1231 ; PR15940
1232 define i1 @test70(i32 %X) {
1233 ; CHECK-LABEL: @test70(
1234 ; CHECK-NEXT:    [[A:%.*]] = srem i32 5, [[X:%.*]]
1235 ; CHECK-NEXT:    [[C:%.*]] = icmp ne i32 [[A]], 2
1236 ; CHECK-NEXT:    ret i1 [[C]]
1238   %A = srem i32 5, %X
1239   %B = add i32 %A, 2
1240   %C = icmp ne i32 %B, 4
1241   ret i1 %C
1244 define <2 x i1> @test70vec(<2 x i32> %X) {
1245 ; CHECK-LABEL: @test70vec(
1246 ; CHECK-NEXT:    [[C:%.*]] = icmp ne <2 x i32> [[X:%.*]], <i32 2, i32 2>
1247 ; CHECK-NEXT:    ret <2 x i1> [[C]]
1249   %B = add <2 x i32> %X, <i32 2, i32 2>
1250   %C = icmp ne <2 x i32> %B, <i32 4, i32 4>
1251   ret <2 x i1> %C
1254 define i1 @icmp_sext16trunc(i32 %x) {
1255 ; CHECK-LABEL: @icmp_sext16trunc(
1256 ; CHECK-NEXT:    [[TMP1:%.*]] = trunc i32 [[X:%.*]] to i16
1257 ; CHECK-NEXT:    [[CMP:%.*]] = icmp slt i16 [[TMP1]], 36
1258 ; CHECK-NEXT:    ret i1 [[CMP]]
1260   %trunc = trunc i32 %x to i16
1261   %sext = sext i16 %trunc to i32
1262   %cmp = icmp slt i32 %sext, 36
1263   ret i1 %cmp
1266 define i1 @icmp_sext8trunc(i32 %x) {
1267 ; CHECK-LABEL: @icmp_sext8trunc(
1268 ; CHECK-NEXT:    [[TMP1:%.*]] = trunc i32 [[X:%.*]] to i8
1269 ; CHECK-NEXT:    [[CMP:%.*]] = icmp slt i8 [[TMP1]], 36
1270 ; CHECK-NEXT:    ret i1 [[CMP]]
1272   %trunc = trunc i32 %x to i8
1273   %sext = sext i8 %trunc to i32
1274   %cmp = icmp slt i32 %sext, 36
1275   ret i1 %cmp
1278 ; Vectors should fold the same way.
1279 define <2 x i1> @icmp_sext8trunc_vec(<2 x i32> %x) {
1280 ; CHECK-LABEL: @icmp_sext8trunc_vec(
1281 ; CHECK-NEXT:    [[TMP1:%.*]] = trunc <2 x i32> [[X:%.*]] to <2 x i8>
1282 ; CHECK-NEXT:    [[CMP:%.*]] = icmp slt <2 x i8> [[TMP1]], <i8 36, i8 36>
1283 ; CHECK-NEXT:    ret <2 x i1> [[CMP]]
1285   %trunc = trunc <2 x i32> %x to <2 x i8>
1286   %sext = sext <2 x i8> %trunc to <2 x i32>
1287   %cmp = icmp slt <2 x i32> %sext, <i32 36, i32 36>
1288   ret <2 x i1> %cmp
1291 define i1 @icmp_shl16(i32 %x) {
1292 ; CHECK-LABEL: @icmp_shl16(
1293 ; CHECK-NEXT:    [[TMP1:%.*]] = trunc i32 [[X:%.*]] to i16
1294 ; CHECK-NEXT:    [[CMP:%.*]] = icmp slt i16 [[TMP1]], 36
1295 ; CHECK-NEXT:    ret i1 [[CMP]]
1297   %shl = shl i32 %x, 16
1298   %cmp = icmp slt i32 %shl, 2359296
1299   ret i1 %cmp
1302 ; D25952: Don't create illegal types like i15 in InstCombine
1304 define i1 @icmp_shl17(i32 %x) {
1305 ; CHECK-LABEL: @icmp_shl17(
1306 ; CHECK-NEXT:    [[SHL:%.*]] = shl i32 [[X:%.*]], 17
1307 ; CHECK-NEXT:    [[CMP:%.*]] = icmp slt i32 [[SHL]], 2359296
1308 ; CHECK-NEXT:    ret i1 [[CMP]]
1310   %shl = shl i32 %x, 17
1311   %cmp = icmp slt i32 %shl, 2359296
1312   ret i1 %cmp
1315 define <2 x i1> @icmp_shl16_vec(<2 x i32> %x) {
1316 ; CHECK-LABEL: @icmp_shl16_vec(
1317 ; CHECK-NEXT:    [[TMP1:%.*]] = trunc <2 x i32> [[X:%.*]] to <2 x i16>
1318 ; CHECK-NEXT:    [[CMP:%.*]] = icmp slt <2 x i16> [[TMP1]], <i16 36, i16 36>
1319 ; CHECK-NEXT:    ret <2 x i1> [[CMP]]
1321   %shl = shl <2 x i32> %x, <i32 16, i32 16>
1322   %cmp = icmp slt <2 x i32> %shl, <i32 2359296, i32 2359296>
1323   ret <2 x i1> %cmp
1326 define i1 @icmp_shl24(i32 %x) {
1327 ; CHECK-LABEL: @icmp_shl24(
1328 ; CHECK-NEXT:    [[TMP1:%.*]] = trunc i32 [[X:%.*]] to i8
1329 ; CHECK-NEXT:    [[CMP:%.*]] = icmp slt i8 [[TMP1]], 36
1330 ; CHECK-NEXT:    ret i1 [[CMP]]
1332   %shl = shl i32 %x, 24
1333   %cmp = icmp slt i32 %shl, 603979776
1334   ret i1 %cmp
1337 define i1 @icmp_shl_eq(i32 %x) {
1338 ; CHECK-LABEL: @icmp_shl_eq(
1339 ; CHECK-NEXT:    [[MUL_MASK:%.*]] = and i32 [[X:%.*]], 134217727
1340 ; CHECK-NEXT:    [[CMP:%.*]] = icmp eq i32 [[MUL_MASK]], 0
1341 ; CHECK-NEXT:    ret i1 [[CMP]]
1343   %mul = shl i32 %x, 5
1344   %cmp = icmp eq i32 %mul, 0
1345   ret i1 %cmp
1348 define <2 x i1> @icmp_shl_eq_vec(<2 x i32> %x) {
1349 ; CHECK-LABEL: @icmp_shl_eq_vec(
1350 ; CHECK-NEXT:    [[MUL_MASK:%.*]] = and <2 x i32> [[X:%.*]], <i32 134217727, i32 134217727>
1351 ; CHECK-NEXT:    [[CMP:%.*]] = icmp eq <2 x i32> [[MUL_MASK]], zeroinitializer
1352 ; CHECK-NEXT:    ret <2 x i1> [[CMP]]
1354   %mul = shl <2 x i32> %x, <i32 5, i32 5>
1355   %cmp = icmp eq <2 x i32> %mul, zeroinitializer
1356   ret <2 x i1> %cmp
1359 define i1 @icmp_shl_nsw_ne(i32 %x) {
1360 ; CHECK-LABEL: @icmp_shl_nsw_ne(
1361 ; CHECK-NEXT:    [[CMP:%.*]] = icmp ne i32 [[X:%.*]], 0
1362 ; CHECK-NEXT:    ret i1 [[CMP]]
1364   %mul = shl nsw i32 %x, 7
1365   %cmp = icmp ne i32 %mul, 0
1366   ret i1 %cmp
1369 define <2 x i1> @icmp_shl_nsw_ne_vec(<2 x i32> %x) {
1370 ; CHECK-LABEL: @icmp_shl_nsw_ne_vec(
1371 ; CHECK-NEXT:    [[CMP:%.*]] = icmp ne <2 x i32> [[X:%.*]], zeroinitializer
1372 ; CHECK-NEXT:    ret <2 x i1> [[CMP]]
1374   %mul = shl nsw <2 x i32> %x, <i32 7, i32 7>
1375   %cmp = icmp ne <2 x i32> %mul, zeroinitializer
1376   ret <2 x i1> %cmp
1379 define i1 @icmp_shl_ne(i32 %x) {
1380 ; CHECK-LABEL: @icmp_shl_ne(
1381 ; CHECK-NEXT:    [[MUL_MASK:%.*]] = and i32 [[X:%.*]], 33554431
1382 ; CHECK-NEXT:    [[CMP:%.*]] = icmp ne i32 [[MUL_MASK]], 0
1383 ; CHECK-NEXT:    ret i1 [[CMP]]
1385   %mul = shl i32 %x, 7
1386   %cmp = icmp ne i32 %mul, 0
1387   ret i1 %cmp
1390 define <2 x i1> @icmp_shl_ne_vec(<2 x i32> %x) {
1391 ; CHECK-LABEL: @icmp_shl_ne_vec(
1392 ; CHECK-NEXT:    [[MUL_MASK:%.*]] = and <2 x i32> [[X:%.*]], <i32 33554431, i32 33554431>
1393 ; CHECK-NEXT:    [[CMP:%.*]] = icmp ne <2 x i32> [[MUL_MASK]], zeroinitializer
1394 ; CHECK-NEXT:    ret <2 x i1> [[CMP]]
1396   %mul = shl <2 x i32> %x, <i32 7, i32 7>
1397   %cmp = icmp ne <2 x i32> %mul, zeroinitializer
1398   ret <2 x i1> %cmp
1401 define <2 x i1> @icmp_shl_nuw_ne_vec(<2 x i32> %x) {
1402 ; CHECK-LABEL: @icmp_shl_nuw_ne_vec(
1403 ; CHECK-NEXT:    [[CMP:%.*]] = icmp ne <2 x i32> [[X:%.*]], <i32 2, i32 2>
1404 ; CHECK-NEXT:    ret <2 x i1> [[CMP]]
1406   %shl = shl nuw <2 x i32> %x, <i32 7, i32 7>
1407   %cmp = icmp ne <2 x i32> %shl, <i32 256, i32 256>
1408   ret <2 x i1> %cmp
1411 ; If the (mul x, C) preserved the sign and this is sign test,
1412 ; compare the LHS operand instead
1413 define i1 @icmp_mul_nsw(i32 %x) {
1414 ; CHECK-LABEL: @icmp_mul_nsw(
1415 ; CHECK-NEXT:    [[CMP:%.*]] = icmp sgt i32 [[X:%.*]], 0
1416 ; CHECK-NEXT:    ret i1 [[CMP]]
1418   %mul = mul nsw i32 %x, 12
1419   %cmp = icmp sgt i32 %mul, 0
1420   ret i1 %cmp
1423 define i1 @icmp_mul_nsw1(i32 %x) {
1424 ; CHECK-LABEL: @icmp_mul_nsw1(
1425 ; CHECK-NEXT:    [[CMP:%.*]] = icmp slt i32 [[X:%.*]], 0
1426 ; CHECK-NEXT:    ret i1 [[CMP]]
1428   %mul = mul nsw i32 %x, 12
1429   %cmp = icmp sle i32 %mul, -1
1430   ret i1 %cmp
1433 define i1 @icmp_mul_nsw_neg(i32 %x) {
1434 ; CHECK-LABEL: @icmp_mul_nsw_neg(
1435 ; CHECK-NEXT:    [[CMP:%.*]] = icmp slt i32 [[X:%.*]], 1
1436 ; CHECK-NEXT:    ret i1 [[CMP]]
1438   %mul = mul nsw i32 %x, -12
1439   %cmp = icmp sge i32 %mul, 0
1440   ret i1 %cmp
1443 define i1 @icmp_mul_nsw_neg1(i32 %x) {
1444 ; CHECK-LABEL: @icmp_mul_nsw_neg1(
1445 ; CHECK-NEXT:    [[CMP:%.*]] = icmp slt i32 [[X:%.*]], 0
1446 ; CHECK-NEXT:    ret i1 [[CMP]]
1448   %mul = mul nsw i32 %x, -12
1449   %cmp = icmp sge i32 %mul, 1
1450   ret i1 %cmp
1453 define <2 x i1> @icmp_mul_nsw_neg1_vec(<2 x i32> %x) {
1454 ; CHECK-LABEL: @icmp_mul_nsw_neg1_vec(
1455 ; CHECK-NEXT:    [[CMP:%.*]] = icmp slt <2 x i32> [[X:%.*]], zeroinitializer
1456 ; CHECK-NEXT:    ret <2 x i1> [[CMP]]
1458   %mul = mul nsw <2 x i32> %x, <i32 -12, i32 -12>
1459   %cmp = icmp sge <2 x i32> %mul, <i32 1, i32 1>
1460   ret <2 x i1> %cmp
1463 define i1 @icmp_mul_nsw_0(i32 %x) {
1464 ; CHECK-LABEL: @icmp_mul_nsw_0(
1465 ; CHECK-NEXT:    ret i1 false
1467   %mul = mul nsw i32 %x, 0
1468   %cmp = icmp sgt i32 %mul, 0
1469   ret i1 %cmp
1472 define i1 @icmp_mul(i32 %x) {
1473 ; CHECK-LABEL: @icmp_mul(
1474 ; CHECK-NEXT:    [[MUL:%.*]] = mul i32 [[X:%.*]], -12
1475 ; CHECK-NEXT:    [[CMP:%.*]] = icmp sgt i32 [[MUL]], -1
1476 ; CHECK-NEXT:    ret i1 [[CMP]]
1478   %mul = mul i32 %x, -12
1479   %cmp = icmp sge i32 %mul, 0
1480   ret i1 %cmp
1483 ; Checks for icmp (eq|ne) (mul x, C), 0
1484 define i1 @icmp_mul_neq0(i32 %x) {
1485 ; CHECK-LABEL: @icmp_mul_neq0(
1486 ; CHECK-NEXT:    [[CMP:%.*]] = icmp ne i32 [[X:%.*]], 0
1487 ; CHECK-NEXT:    ret i1 [[CMP]]
1489   %mul = mul nsw i32 %x, -12
1490   %cmp = icmp ne i32 %mul, 0
1491   ret i1 %cmp
1494 define <2 x i1> @icmp_mul_neq0_vec(<2 x i32> %x) {
1495 ; CHECK-LABEL: @icmp_mul_neq0_vec(
1496 ; CHECK-NEXT:    [[CMP:%.*]] = icmp ne <2 x i32> [[X:%.*]], zeroinitializer
1497 ; CHECK-NEXT:    ret <2 x i1> [[CMP]]
1499   %mul = mul nsw <2 x i32> %x, <i32 -12, i32 -12>
1500   %cmp = icmp ne <2 x i32> %mul, zeroinitializer
1501   ret <2 x i1> %cmp
1504 define i1 @icmp_mul_eq0(i32 %x) {
1505 ; CHECK-LABEL: @icmp_mul_eq0(
1506 ; CHECK-NEXT:    [[CMP:%.*]] = icmp eq i32 [[X:%.*]], 0
1507 ; CHECK-NEXT:    ret i1 [[CMP]]
1509   %mul = mul nsw i32 %x, 12
1510   %cmp = icmp eq i32 %mul, 0
1511   ret i1 %cmp
1514 define i1 @icmp_mul0_eq0(i32 %x) {
1515 ; CHECK-LABEL: @icmp_mul0_eq0(
1516 ; CHECK-NEXT:    ret i1 true
1518   %mul = mul i32 %x, 0
1519   %cmp = icmp eq i32 %mul, 0
1520   ret i1 %cmp
1523 define i1 @icmp_mul0_ne0(i32 %x) {
1524 ; CHECK-LABEL: @icmp_mul0_ne0(
1525 ; CHECK-NEXT:    ret i1 false
1527   %mul = mul i32 %x, 0
1528   %cmp = icmp ne i32 %mul, 0
1529   ret i1 %cmp
1532 define i1 @icmp_sub1_sge(i32 %x, i32 %y) {
1533 ; CHECK-LABEL: @icmp_sub1_sge(
1534 ; CHECK-NEXT:    [[CMP:%.*]] = icmp sgt i32 [[X:%.*]], [[Y:%.*]]
1535 ; CHECK-NEXT:    ret i1 [[CMP]]
1537   %sub = add nsw i32 %x, -1
1538   %cmp = icmp sge i32 %sub, %y
1539   ret i1 %cmp
1542 define i1 @icmp_add1_sgt(i32 %x, i32 %y) {
1543 ; CHECK-LABEL: @icmp_add1_sgt(
1544 ; CHECK-NEXT:    [[CMP:%.*]] = icmp sge i32 [[X:%.*]], [[Y:%.*]]
1545 ; CHECK-NEXT:    ret i1 [[CMP]]
1547   %add = add nsw i32 %x, 1
1548   %cmp = icmp sgt i32 %add, %y
1549   ret i1 %cmp
1552 define i1 @icmp_sub1_slt(i32 %x, i32 %y) {
1553 ; CHECK-LABEL: @icmp_sub1_slt(
1554 ; CHECK-NEXT:    [[CMP:%.*]] = icmp sle i32 [[X:%.*]], [[Y:%.*]]
1555 ; CHECK-NEXT:    ret i1 [[CMP]]
1557   %sub = add nsw i32 %x, -1
1558   %cmp = icmp slt i32 %sub, %y
1559   ret i1 %cmp
1562 define i1 @icmp_add1_sle(i32 %x, i32 %y) {
1563 ; CHECK-LABEL: @icmp_add1_sle(
1564 ; CHECK-NEXT:    [[CMP:%.*]] = icmp slt i32 [[X:%.*]], [[Y:%.*]]
1565 ; CHECK-NEXT:    ret i1 [[CMP]]
1567   %add = add nsw i32 %x, 1
1568   %cmp = icmp sle i32 %add, %y
1569   ret i1 %cmp
1572 define i1 @icmp_add20_sge_add57(i32 %x, i32 %y) {
1573 ; CHECK-LABEL: @icmp_add20_sge_add57(
1574 ; CHECK-NEXT:    [[TMP1:%.*]] = add nsw i32 [[Y:%.*]], 37
1575 ; CHECK-NEXT:    [[CMP:%.*]] = icmp sle i32 [[TMP1]], [[X:%.*]]
1576 ; CHECK-NEXT:    ret i1 [[CMP]]
1578   %1 = add nsw i32 %x, 20
1579   %2 = add nsw i32 %y, 57
1580   %cmp = icmp sge i32 %1, %2
1581   ret i1 %cmp
1584 define i1 @icmp_sub57_sge_sub20(i32 %x, i32 %y) {
1585 ; CHECK-LABEL: @icmp_sub57_sge_sub20(
1586 ; CHECK-NEXT:    [[TMP1:%.*]] = add nsw i32 [[X:%.*]], -37
1587 ; CHECK-NEXT:    [[CMP:%.*]] = icmp sge i32 [[TMP1]], [[Y:%.*]]
1588 ; CHECK-NEXT:    ret i1 [[CMP]]
1590   %1 = add nsw i32 %x, -57
1591   %2 = add nsw i32 %y, -20
1592   %cmp = icmp sge i32 %1, %2
1593   ret i1 %cmp
1596 define i1 @icmp_and_shl_neg_ne_0(i32 %A, i32 %B) {
1597 ; CHECK-LABEL: @icmp_and_shl_neg_ne_0(
1598 ; CHECK-NEXT:    [[SHL:%.*]] = shl i32 1, [[B:%.*]]
1599 ; CHECK-NEXT:    [[TMP1:%.*]] = and i32 [[SHL]], [[A:%.*]]
1600 ; CHECK-NEXT:    [[CMP:%.*]] = icmp eq i32 [[TMP1]], 0
1601 ; CHECK-NEXT:    ret i1 [[CMP]]
1603   %neg = xor i32 %A, -1
1604   %shl = shl i32 1, %B
1605   %and = and i32 %shl, %neg
1606   %cmp = icmp ne i32 %and, 0
1607   ret i1 %cmp
1610 define i1 @icmp_and_shl_neg_eq_0(i32 %A, i32 %B) {
1611 ; CHECK-LABEL: @icmp_and_shl_neg_eq_0(
1612 ; CHECK-NEXT:    [[SHL:%.*]] = shl i32 1, [[B:%.*]]
1613 ; CHECK-NEXT:    [[TMP1:%.*]] = and i32 [[SHL]], [[A:%.*]]
1614 ; CHECK-NEXT:    [[CMP:%.*]] = icmp ne i32 [[TMP1]], 0
1615 ; CHECK-NEXT:    ret i1 [[CMP]]
1617   %neg = xor i32 %A, -1
1618   %shl = shl i32 1, %B
1619   %and = and i32 %shl, %neg
1620   %cmp = icmp eq i32 %and, 0
1621   ret i1 %cmp
1624 define i1 @icmp_add_and_shr_ne_0(i32 %X) {
1625 ; CHECK-LABEL: @icmp_add_and_shr_ne_0(
1626 ; CHECK-NEXT:    [[TMP1:%.*]] = and i32 [[X:%.*]], 240
1627 ; CHECK-NEXT:    [[TOBOOL:%.*]] = icmp ne i32 [[TMP1]], 224
1628 ; CHECK-NEXT:    ret i1 [[TOBOOL]]
1630   %shr = lshr i32 %X, 4
1631   %and = and i32 %shr, 15
1632   %add = add i32 %and, -14
1633   %tobool = icmp ne i32 %add, 0
1634   ret i1 %tobool
1637 define <2 x i1> @icmp_add_and_shr_ne_0_vec(<2 x i32> %X) {
1638 ; CHECK-LABEL: @icmp_add_and_shr_ne_0_vec(
1639 ; CHECK-NEXT:    [[TMP1:%.*]] = and <2 x i32> [[X:%.*]], <i32 240, i32 240>
1640 ; CHECK-NEXT:    [[TOBOOL:%.*]] = icmp ne <2 x i32> [[TMP1]], <i32 224, i32 224>
1641 ; CHECK-NEXT:    ret <2 x i1> [[TOBOOL]]
1643   %shr = lshr <2 x i32> %X, <i32 4, i32 4>
1644   %and = and <2 x i32> %shr, <i32 15, i32 15>
1645   %add = add <2 x i32> %and, <i32 -14, i32 -14>
1646   %tobool = icmp ne <2 x i32> %add, zeroinitializer
1647   ret <2 x i1> %tobool
1650 ; Variation of the above with an extra use of the shift
1651 define i1 @icmp_and_shr_multiuse(i32 %X) {
1652 ; CHECK-LABEL: @icmp_and_shr_multiuse(
1653 ; CHECK-NEXT:    [[TMP1:%.*]] = and i32 [[X:%.*]], 240
1654 ; CHECK-NEXT:    [[TOBOOL:%.*]] = icmp ne i32 [[TMP1]], 224
1655 ; CHECK-NEXT:    [[TMP2:%.*]] = and i32 [[X]], 496
1656 ; CHECK-NEXT:    [[TOBOOL2:%.*]] = icmp ne i32 [[TMP2]], 432
1657 ; CHECK-NEXT:    [[AND3:%.*]] = and i1 [[TOBOOL]], [[TOBOOL2]]
1658 ; CHECK-NEXT:    ret i1 [[AND3]]
1660   %shr = lshr i32 %X, 4
1661   %and = and i32 %shr, 15
1662   %and2 = and i32 %shr, 31 ; second use of the shift
1663   %tobool = icmp ne i32 %and, 14
1664   %tobool2 = icmp ne i32 %and2, 27
1665   %and3 = and i1 %tobool, %tobool2
1666   ret i1 %and3
1669 define i1 @icmp_and_shr_multiuse_logical(i32 %X) {
1670 ; CHECK-LABEL: @icmp_and_shr_multiuse_logical(
1671 ; CHECK-NEXT:    [[TMP1:%.*]] = and i32 [[X:%.*]], 240
1672 ; CHECK-NEXT:    [[TOBOOL:%.*]] = icmp ne i32 [[TMP1]], 224
1673 ; CHECK-NEXT:    [[TMP2:%.*]] = and i32 [[X]], 496
1674 ; CHECK-NEXT:    [[TOBOOL2:%.*]] = icmp ne i32 [[TMP2]], 432
1675 ; CHECK-NEXT:    [[AND3:%.*]] = and i1 [[TOBOOL]], [[TOBOOL2]]
1676 ; CHECK-NEXT:    ret i1 [[AND3]]
1678   %shr = lshr i32 %X, 4
1679   %and = and i32 %shr, 15
1680   %and2 = and i32 %shr, 31 ; second use of the shift
1681   %tobool = icmp ne i32 %and, 14
1682   %tobool2 = icmp ne i32 %and2, 27
1683   %and3 = select i1 %tobool, i1 %tobool2, i1 false
1684   ret i1 %and3
1687 ; Variation of the above with an ashr
1688 define i1 @icmp_and_ashr_multiuse(i32 %X) {
1689 ; CHECK-LABEL: @icmp_and_ashr_multiuse(
1690 ; CHECK-NEXT:    [[TMP1:%.*]] = and i32 [[X:%.*]], 240
1691 ; CHECK-NEXT:    [[TOBOOL:%.*]] = icmp ne i32 [[TMP1]], 224
1692 ; CHECK-NEXT:    [[TMP2:%.*]] = and i32 [[X]], 496
1693 ; CHECK-NEXT:    [[TOBOOL2:%.*]] = icmp ne i32 [[TMP2]], 432
1694 ; CHECK-NEXT:    [[AND3:%.*]] = and i1 [[TOBOOL]], [[TOBOOL2]]
1695 ; CHECK-NEXT:    ret i1 [[AND3]]
1697   %shr = ashr i32 %X, 4
1698   %and = and i32 %shr, 15
1699   %and2 = and i32 %shr, 31 ; second use of the shift
1700   %tobool = icmp ne i32 %and, 14
1701   %tobool2 = icmp ne i32 %and2, 27
1702   %and3 = and i1 %tobool, %tobool2
1703   ret i1 %and3
1706 define i1 @icmp_and_ashr_multiuse_logical(i32 %X) {
1707 ; CHECK-LABEL: @icmp_and_ashr_multiuse_logical(
1708 ; CHECK-NEXT:    [[TMP1:%.*]] = and i32 [[X:%.*]], 240
1709 ; CHECK-NEXT:    [[TOBOOL:%.*]] = icmp ne i32 [[TMP1]], 224
1710 ; CHECK-NEXT:    [[TMP2:%.*]] = and i32 [[X]], 496
1711 ; CHECK-NEXT:    [[TOBOOL2:%.*]] = icmp ne i32 [[TMP2]], 432
1712 ; CHECK-NEXT:    [[AND3:%.*]] = and i1 [[TOBOOL]], [[TOBOOL2]]
1713 ; CHECK-NEXT:    ret i1 [[AND3]]
1715   %shr = ashr i32 %X, 4
1716   %and = and i32 %shr, 15
1717   %and2 = and i32 %shr, 31 ; second use of the shift
1718   %tobool = icmp ne i32 %and, 14
1719   %tobool2 = icmp ne i32 %and2, 27
1720   %and3 = select i1 %tobool, i1 %tobool2, i1 false
1721   ret i1 %and3
1724 define i1 @icmp_lshr_and_overshift(i8 %X) {
1725 ; CHECK-LABEL: @icmp_lshr_and_overshift(
1726 ; CHECK-NEXT:    [[TOBOOL:%.*]] = icmp ugt i8 [[X:%.*]], 31
1727 ; CHECK-NEXT:    ret i1 [[TOBOOL]]
1729   %shr = lshr i8 %X, 5
1730   %and = and i8 %shr, 15
1731   %tobool = icmp ne i8 %and, 0
1732   ret i1 %tobool
1735 ; We shouldn't simplify this because the and uses bits that are shifted in.
1736 define i1 @icmp_ashr_and_overshift(i8 %X) {
1737 ; CHECK-LABEL: @icmp_ashr_and_overshift(
1738 ; CHECK-NEXT:    [[SHR:%.*]] = ashr i8 [[X:%.*]], 5
1739 ; CHECK-NEXT:    [[AND:%.*]] = and i8 [[SHR]], 15
1740 ; CHECK-NEXT:    [[TOBOOL:%.*]] = icmp ne i8 [[AND]], 0
1741 ; CHECK-NEXT:    ret i1 [[TOBOOL]]
1743   %shr = ashr i8 %X, 5
1744   %and = and i8 %shr, 15
1745   %tobool = icmp ne i8 %and, 0
1746   ret i1 %tobool
1749 define i1 @icmp_and_ashr_neg_and_legal(i8 %x) {
1750 ; CHECK-LABEL: @icmp_and_ashr_neg_and_legal(
1751 ; CHECK-NEXT:    [[TMP1:%.*]] = and i8 [[X:%.*]], -32
1752 ; CHECK-NEXT:    [[CMP:%.*]] = icmp slt i8 [[TMP1]], 16
1753 ; CHECK-NEXT:    ret i1 [[CMP]]
1755   %ashr = ashr i8 %x, 4
1756   %and = and i8 %ashr, -2
1757   %cmp = icmp slt i8 %and, 1
1758   ret i1 %cmp
1761 ; Negative test.
1762 define i1 @icmp_and_ashr_mixed_and_shiftout(i8 %x) {
1763 ; CHECK-LABEL: @icmp_and_ashr_mixed_and_shiftout(
1764 ; CHECK-NEXT:    [[ASHR:%.*]] = ashr i8 [[X:%.*]], 4
1765 ; CHECK-NEXT:    [[AND:%.*]] = and i8 [[ASHR]], 31
1766 ; CHECK-NEXT:    [[CMP:%.*]] = icmp ugt i8 [[AND]], 8
1767 ; CHECK-NEXT:    ret i1 [[CMP]]
1769   %ashr = ashr i8 %x, 4
1770   %and = and i8 %ashr, 31
1771   %cmp = icmp ugt i8 %and, 8
1772   ret i1 %cmp
1775 define i1 @icmp_and_ashr_neg_cmp_slt_legal(i8 %x) {
1776 ; CHECK-LABEL: @icmp_and_ashr_neg_cmp_slt_legal(
1777 ; CHECK-NEXT:    [[TMP1:%.*]] = and i8 [[X:%.*]], -32
1778 ; CHECK-NEXT:    [[CMP:%.*]] = icmp slt i8 [[TMP1]], -64
1779 ; CHECK-NEXT:    ret i1 [[CMP]]
1781   %ashr = ashr i8 %x, 4
1782   %and = and i8 %ashr, -2
1783   %cmp = icmp slt i8 %and, -4
1784   ret i1 %cmp
1787 ; Negative test.
1788 define i1 @icmp_and_ashr_neg_cmp_slt_shiftout(i8 %x) {
1789 ; CHECK-LABEL: @icmp_and_ashr_neg_cmp_slt_shiftout(
1790 ; CHECK-NEXT:    [[ASHR:%.*]] = ashr i8 [[X:%.*]], 4
1791 ; CHECK-NEXT:    [[AND:%.*]] = and i8 [[ASHR]], -2
1792 ; CHECK-NEXT:    [[CMP:%.*]] = icmp slt i8 [[AND]], -68
1793 ; CHECK-NEXT:    ret i1 [[CMP]]
1795   %ashr = ashr i8 %x, 4
1796   %and = and i8 %ashr, -2
1797   %cmp = icmp slt i8 %and, -68
1798   ret i1 %cmp
1801 define i1 @icmp_and_ashr_neg_cmp_eq_legal(i8 %x) {
1802 ; CHECK-LABEL: @icmp_and_ashr_neg_cmp_eq_legal(
1803 ; CHECK-NEXT:    [[TMP1:%.*]] = and i8 [[X:%.*]], -32
1804 ; CHECK-NEXT:    [[CMP:%.*]] = icmp eq i8 [[TMP1]], -64
1805 ; CHECK-NEXT:    ret i1 [[CMP]]
1807   %ashr = ashr i8 %x, 4
1808   %and = and i8 %ashr, -2
1809   %cmp = icmp eq i8 %and, -4
1810   ret i1 %cmp
1813 define i1 @icmp_and_ashr_neg_cmp_eq_shiftout(i8 %x) {
1814 ; CHECK-LABEL: @icmp_and_ashr_neg_cmp_eq_shiftout(
1815 ; CHECK-NEXT:    ret i1 false
1817   %ashr = ashr i8 %x, 4
1818   %and = and i8 %ashr, -2
1819   %cmp = icmp eq i8 %and, -68
1820   ret i1 %cmp
1823 define i1 @icmp_and_ashr_neg_cmp_ne_shiftout(i8 %x) {
1824 ; CHECK-LABEL: @icmp_and_ashr_neg_cmp_ne_shiftout(
1825 ; CHECK-NEXT:    ret i1 true
1827   %ashr = ashr i8 %x, 4
1828   %and = and i8 %ashr, -2
1829   %cmp = icmp ne i8 %and, -68
1830   ret i1 %cmp
1833 define i1 @icmp_shl_1_V_ult_32(i32 %V) {
1834 ; CHECK-LABEL: @icmp_shl_1_V_ult_32(
1835 ; CHECK-NEXT:    [[CMP:%.*]] = icmp ult i32 [[V:%.*]], 5
1836 ; CHECK-NEXT:    ret i1 [[CMP]]
1838   %shl = shl i32 1, %V
1839   %cmp = icmp ult i32 %shl, 32
1840   ret i1 %cmp
1843 define <2 x i1> @icmp_shl_1_V_ult_32_vec(<2 x i32> %V) {
1844 ; CHECK-LABEL: @icmp_shl_1_V_ult_32_vec(
1845 ; CHECK-NEXT:    [[CMP:%.*]] = icmp ult <2 x i32> [[V:%.*]], <i32 5, i32 5>
1846 ; CHECK-NEXT:    ret <2 x i1> [[CMP]]
1848   %shl = shl <2 x i32> <i32 1, i32 1>, %V
1849   %cmp = icmp ult <2 x i32> %shl, <i32 32, i32 32>
1850   ret <2 x i1> %cmp
1853 define i1 @icmp_shl_1_V_eq_32(i32 %V) {
1854 ; CHECK-LABEL: @icmp_shl_1_V_eq_32(
1855 ; CHECK-NEXT:    [[CMP:%.*]] = icmp eq i32 [[V:%.*]], 5
1856 ; CHECK-NEXT:    ret i1 [[CMP]]
1858   %shl = shl i32 1, %V
1859   %cmp = icmp eq i32 %shl, 32
1860   ret i1 %cmp
1863 define <2 x i1> @icmp_shl_1_V_eq_32_vec(<2 x i32> %V) {
1864 ; CHECK-LABEL: @icmp_shl_1_V_eq_32_vec(
1865 ; CHECK-NEXT:    [[CMP:%.*]] = icmp eq <2 x i32> [[V:%.*]], <i32 5, i32 5>
1866 ; CHECK-NEXT:    ret <2 x i1> [[CMP]]
1868   %shl = shl <2 x i32> <i32 1, i32 1>, %V
1869   %cmp = icmp eq <2 x i32> %shl, <i32 32, i32 32>
1870   ret <2 x i1> %cmp
1873 define i1 @icmp_shl_1_V_ult_30(i32 %V) {
1874 ; CHECK-LABEL: @icmp_shl_1_V_ult_30(
1875 ; CHECK-NEXT:    [[CMP:%.*]] = icmp ult i32 [[V:%.*]], 5
1876 ; CHECK-NEXT:    ret i1 [[CMP]]
1878   %shl = shl i32 1, %V
1879   %cmp = icmp ult i32 %shl, 30
1880   ret i1 %cmp
1883 define <2 x i1> @icmp_shl_1_V_ult_30_vec(<2 x i32> %V) {
1884 ; CHECK-LABEL: @icmp_shl_1_V_ult_30_vec(
1885 ; CHECK-NEXT:    [[CMP:%.*]] = icmp ult <2 x i32> [[V:%.*]], <i32 5, i32 5>
1886 ; CHECK-NEXT:    ret <2 x i1> [[CMP]]
1888   %shl = shl <2 x i32> <i32 1, i32 1>, %V
1889   %cmp = icmp ult <2 x i32> %shl, <i32 30, i32 30>
1890   ret <2 x i1> %cmp
1893 define i1 @icmp_shl_1_V_ugt_30(i32 %V) {
1894 ; CHECK-LABEL: @icmp_shl_1_V_ugt_30(
1895 ; CHECK-NEXT:    [[CMP:%.*]] = icmp ugt i32 [[V:%.*]], 4
1896 ; CHECK-NEXT:    ret i1 [[CMP]]
1898   %shl = shl i32 1, %V
1899   %cmp = icmp ugt i32 %shl, 30
1900   ret i1 %cmp
1903 define <2 x i1> @icmp_shl_1_V_ugt_30_vec(<2 x i32> %V) {
1904 ; CHECK-LABEL: @icmp_shl_1_V_ugt_30_vec(
1905 ; CHECK-NEXT:    [[CMP:%.*]] = icmp ugt <2 x i32> [[V:%.*]], <i32 4, i32 4>
1906 ; CHECK-NEXT:    ret <2 x i1> [[CMP]]
1908   %shl = shl <2 x i32> <i32 1, i32 1>, %V
1909   %cmp = icmp ugt <2 x i32> %shl, <i32 30, i32 30>
1910   ret <2 x i1> %cmp
1913 define i1 @icmp_shl_1_V_ule_30(i32 %V) {
1914 ; CHECK-LABEL: @icmp_shl_1_V_ule_30(
1915 ; CHECK-NEXT:    [[CMP:%.*]] = icmp ult i32 [[V:%.*]], 5
1916 ; CHECK-NEXT:    ret i1 [[CMP]]
1918   %shl = shl i32 1, %V
1919   %cmp = icmp ule i32 %shl, 30
1920   ret i1 %cmp
1923 define <2 x i1> @icmp_shl_1_V_ule_30_vec(<2 x i32> %V) {
1924 ; CHECK-LABEL: @icmp_shl_1_V_ule_30_vec(
1925 ; CHECK-NEXT:    [[CMP:%.*]] = icmp ult <2 x i32> [[V:%.*]], <i32 5, i32 5>
1926 ; CHECK-NEXT:    ret <2 x i1> [[CMP]]
1928   %shl = shl <2 x i32> <i32 1, i32 1>, %V
1929   %cmp = icmp ule <2 x i32> %shl, <i32 30, i32 30>
1930   ret <2 x i1> %cmp
1933 define i1 @icmp_shl_1_V_uge_30(i32 %V) {
1934 ; CHECK-LABEL: @icmp_shl_1_V_uge_30(
1935 ; CHECK-NEXT:    [[CMP:%.*]] = icmp ugt i32 [[V:%.*]], 4
1936 ; CHECK-NEXT:    ret i1 [[CMP]]
1938   %shl = shl i32 1, %V
1939   %cmp = icmp uge i32 %shl, 30
1940   ret i1 %cmp
1943 define <2 x i1> @icmp_shl_1_V_uge_30_vec(<2 x i32> %V) {
1944 ; CHECK-LABEL: @icmp_shl_1_V_uge_30_vec(
1945 ; CHECK-NEXT:    [[CMP:%.*]] = icmp ugt <2 x i32> [[V:%.*]], <i32 4, i32 4>
1946 ; CHECK-NEXT:    ret <2 x i1> [[CMP]]
1948   %shl = shl <2 x i32> <i32 1, i32 1>, %V
1949   %cmp = icmp uge <2 x i32> %shl, <i32 30, i32 30>
1950   ret <2 x i1> %cmp
1953 define i1 @icmp_shl_1_V_uge_2147483648(i32 %V) {
1954 ; CHECK-LABEL: @icmp_shl_1_V_uge_2147483648(
1955 ; CHECK-NEXT:    [[CMP:%.*]] = icmp eq i32 [[V:%.*]], 31
1956 ; CHECK-NEXT:    ret i1 [[CMP]]
1958   %shl = shl i32 1, %V
1959   %cmp = icmp uge i32 %shl, 2147483648
1960   ret i1 %cmp
1963 define <2 x i1> @icmp_shl_1_V_uge_2147483648_vec(<2 x i32> %V) {
1964 ; CHECK-LABEL: @icmp_shl_1_V_uge_2147483648_vec(
1965 ; CHECK-NEXT:    [[CMP:%.*]] = icmp eq <2 x i32> [[V:%.*]], <i32 31, i32 31>
1966 ; CHECK-NEXT:    ret <2 x i1> [[CMP]]
1968   %shl = shl <2 x i32> <i32 1, i32 1>, %V
1969   %cmp = icmp uge <2 x i32> %shl, <i32 2147483648, i32 2147483648>
1970   ret <2 x i1> %cmp
1973 define i1 @icmp_shl_1_V_ult_2147483648(i32 %V) {
1974 ; CHECK-LABEL: @icmp_shl_1_V_ult_2147483648(
1975 ; CHECK-NEXT:    [[CMP:%.*]] = icmp ne i32 [[V:%.*]], 31
1976 ; CHECK-NEXT:    ret i1 [[CMP]]
1978   %shl = shl i32 1, %V
1979   %cmp = icmp ult i32 %shl, 2147483648
1980   ret i1 %cmp
1983 define <2 x i1> @icmp_shl_1_V_ult_2147483648_vec(<2 x i32> %V) {
1984 ; CHECK-LABEL: @icmp_shl_1_V_ult_2147483648_vec(
1985 ; CHECK-NEXT:    [[CMP:%.*]] = icmp ne <2 x i32> [[V:%.*]], <i32 31, i32 31>
1986 ; CHECK-NEXT:    ret <2 x i1> [[CMP]]
1988   %shl = shl <2 x i32> <i32 1, i32 1>, %V
1989   %cmp = icmp ult <2 x i32> %shl, <i32 2147483648, i32 2147483648>
1990   ret <2 x i1> %cmp
1993 define i1 @or_icmp_eq_B_0_icmp_ult_A_B(i64 %a, i64 %b) {
1994 ; CHECK-LABEL: @or_icmp_eq_B_0_icmp_ult_A_B(
1995 ; CHECK-NEXT:    [[TMP1:%.*]] = add i64 [[B:%.*]], -1
1996 ; CHECK-NEXT:    [[TMP2:%.*]] = icmp uge i64 [[TMP1]], [[A:%.*]]
1997 ; CHECK-NEXT:    ret i1 [[TMP2]]
1999   %1 = icmp eq i64 %b, 0
2000   %2 = icmp ult i64 %a, %b
2001   %3 = or i1 %1, %2
2002   ret i1 %3
2005 define i1 @or_icmp_eq_B_0_icmp_ult_A_B_logical(i64 %a, i64 %b) {
2006 ; CHECK-LABEL: @or_icmp_eq_B_0_icmp_ult_A_B_logical(
2007 ; CHECK-NEXT:    [[TMP1:%.*]] = icmp eq i64 [[B:%.*]], 0
2008 ; CHECK-NEXT:    [[TMP2:%.*]] = icmp ult i64 [[A:%.*]], [[B]]
2009 ; CHECK-NEXT:    [[TMP3:%.*]] = select i1 [[TMP1]], i1 true, i1 [[TMP2]]
2010 ; CHECK-NEXT:    ret i1 [[TMP3]]
2012   %1 = icmp eq i64 %b, 0
2013   %2 = icmp ult i64 %a, %b
2014   %3 = select i1 %1, i1 true, i1 %2
2015   ret i1 %3
2018 define <2 x i1> @or_icmp_eq_B_0_icmp_ult_A_B_uniform(<2 x i64> %a, <2 x i64> %b) {
2019 ; CHECK-LABEL: @or_icmp_eq_B_0_icmp_ult_A_B_uniform(
2020 ; CHECK-NEXT:    [[TMP1:%.*]] = add <2 x i64> [[B:%.*]], <i64 -1, i64 -1>
2021 ; CHECK-NEXT:    [[TMP2:%.*]] = icmp uge <2 x i64> [[TMP1]], [[A:%.*]]
2022 ; CHECK-NEXT:    ret <2 x i1> [[TMP2]]
2024   %1 = icmp eq <2 x i64> %b, zeroinitializer
2025   %2 = icmp ult <2 x i64> %a, %b
2026   %3 = or <2 x i1> %1, %2
2027   ret <2 x i1> %3
2030 define <2 x i1> @or_icmp_eq_B_0_icmp_ult_A_B_undef(<2 x i64> %a, <2 x i64> %b) {
2031 ; CHECK-LABEL: @or_icmp_eq_B_0_icmp_ult_A_B_undef(
2032 ; CHECK-NEXT:    [[TMP1:%.*]] = add <2 x i64> [[B:%.*]], <i64 -1, i64 -1>
2033 ; CHECK-NEXT:    [[TMP2:%.*]] = icmp uge <2 x i64> [[TMP1]], [[A:%.*]]
2034 ; CHECK-NEXT:    ret <2 x i1> [[TMP2]]
2036   %1 = icmp eq <2 x i64> %b, <i64 0, i64 undef>
2037   %2 = icmp ult <2 x i64> %a, %b
2038   %3 = or <2 x i1> %1, %2
2039   ret <2 x i1> %3
2042 define i1 @or_icmp_ne_A_0_icmp_ne_B_0(i64 %a, i64 %b) {
2043 ; CHECK-LABEL: @or_icmp_ne_A_0_icmp_ne_B_0(
2044 ; CHECK-NEXT:    [[TMP1:%.*]] = or i64 [[A:%.*]], [[B:%.*]]
2045 ; CHECK-NEXT:    [[TMP2:%.*]] = icmp ne i64 [[TMP1]], 0
2046 ; CHECK-NEXT:    ret i1 [[TMP2]]
2048   %1 = icmp ne i64 %a, 0
2049   %2 = icmp ne i64 %b, 0
2050   %3 = or i1 %1, %2
2051   ret i1 %3
2054 define i1 @or_icmp_ne_A_0_icmp_ne_B_0_logical(i64 %a, i64 %b) {
2055 ; CHECK-LABEL: @or_icmp_ne_A_0_icmp_ne_B_0_logical(
2056 ; CHECK-NEXT:    [[TMP1:%.*]] = icmp ne i64 [[A:%.*]], 0
2057 ; CHECK-NEXT:    [[TMP2:%.*]] = icmp ne i64 [[B:%.*]], 0
2058 ; CHECK-NEXT:    [[TMP3:%.*]] = select i1 [[TMP1]], i1 true, i1 [[TMP2]]
2059 ; CHECK-NEXT:    ret i1 [[TMP3]]
2061   %1 = icmp ne i64 %a, 0
2062   %2 = icmp ne i64 %b, 0
2063   %3 = select i1 %1, i1 true, i1 %2
2064   ret i1 %3
2067 define <2 x i1> @or_icmp_ne_A_0_icmp_ne_B_0_uniform(<2 x i64> %a, <2 x i64> %b) {
2068 ; CHECK-LABEL: @or_icmp_ne_A_0_icmp_ne_B_0_uniform(
2069 ; CHECK-NEXT:    [[TMP1:%.*]] = or <2 x i64> [[A:%.*]], [[B:%.*]]
2070 ; CHECK-NEXT:    [[TMP2:%.*]] = icmp ne <2 x i64> [[TMP1]], zeroinitializer
2071 ; CHECK-NEXT:    ret <2 x i1> [[TMP2]]
2073   %1 = icmp ne <2 x i64> %a, zeroinitializer
2074   %2 = icmp ne <2 x i64> %b, zeroinitializer
2075   %3 = or <2 x i1> %1, %2
2076   ret <2 x i1> %3
2079 define <2 x i1> @or_icmp_ne_A_0_icmp_ne_B_0_undef(<2 x i64> %a, <2 x i64> %b) {
2080 ; CHECK-LABEL: @or_icmp_ne_A_0_icmp_ne_B_0_undef(
2081 ; CHECK-NEXT:    [[TMP1:%.*]] = or <2 x i64> [[A:%.*]], [[B:%.*]]
2082 ; CHECK-NEXT:    [[TMP2:%.*]] = icmp ne <2 x i64> [[TMP1]], zeroinitializer
2083 ; CHECK-NEXT:    ret <2 x i1> [[TMP2]]
2085   %1 = icmp ne <2 x i64> %a, <i64 0, i64 undef>
2086   %2 = icmp ne <2 x i64> %b, <i64 0, i64 undef>
2087   %3 = or <2 x i1> %1, %2
2088   ret <2 x i1> %3
2091 define i1 @icmp_add_ult_2(i32 %X) {
2092 ; CHECK-LABEL: @icmp_add_ult_2(
2093 ; CHECK-NEXT:    [[TMP1:%.*]] = and i32 [[X:%.*]], -2
2094 ; CHECK-NEXT:    [[CMP:%.*]] = icmp eq i32 [[TMP1]], 14
2095 ; CHECK-NEXT:    ret i1 [[CMP]]
2097   %add = add i32 %X, -14
2098   %cmp = icmp ult i32 %add, 2
2099   ret i1 %cmp
2102 define <2 x i1> @icmp_add_X_-14_ult_2_vec(<2 x i32> %X) {
2103 ; CHECK-LABEL: @icmp_add_X_-14_ult_2_vec(
2104 ; CHECK-NEXT:    [[TMP1:%.*]] = and <2 x i32> [[X:%.*]], <i32 -2, i32 -2>
2105 ; CHECK-NEXT:    [[CMP:%.*]] = icmp eq <2 x i32> [[TMP1]], <i32 14, i32 14>
2106 ; CHECK-NEXT:    ret <2 x i1> [[CMP]]
2108   %add = add <2 x i32> %X, <i32 -14, i32 -14>
2109   %cmp = icmp ult <2 x i32> %add, <i32 2, i32 2>
2110   ret <2 x i1> %cmp
2113 define i1 @icmp_sub_3_X_ult_2(i32 %X) {
2114 ; CHECK-LABEL: @icmp_sub_3_X_ult_2(
2115 ; CHECK-NEXT:    [[TMP1:%.*]] = and i32 [[X:%.*]], -2
2116 ; CHECK-NEXT:    [[CMP:%.*]] = icmp eq i32 [[TMP1]], 2
2117 ; CHECK-NEXT:    ret i1 [[CMP]]
2119   %add = sub i32 3, %X
2120   %cmp = icmp ult i32 %add, 2
2121   ret i1 %cmp
2124 define <2 x i1> @icmp_sub_3_X_ult_2_vec(<2 x i32> %X) {
2125 ; CHECK-LABEL: @icmp_sub_3_X_ult_2_vec(
2126 ; CHECK-NEXT:    [[TMP1:%.*]] = and <2 x i32> [[X:%.*]], <i32 -2, i32 -2>
2127 ; CHECK-NEXT:    [[CMP:%.*]] = icmp eq <2 x i32> [[TMP1]], <i32 2, i32 2>
2128 ; CHECK-NEXT:    ret <2 x i1> [[CMP]]
2130   %add = sub <2 x i32> <i32 3, i32 3>, %X
2131   %cmp = icmp ult <2 x i32> %add, <i32 2, i32 2>
2132   ret <2 x i1> %cmp
2135 define i1 @icmp_add_X_-14_uge_2(i32 %X) {
2136 ; CHECK-LABEL: @icmp_add_X_-14_uge_2(
2137 ; CHECK-NEXT:    [[TMP1:%.*]] = and i32 [[X:%.*]], -2
2138 ; CHECK-NEXT:    [[CMP:%.*]] = icmp ne i32 [[TMP1]], 14
2139 ; CHECK-NEXT:    ret i1 [[CMP]]
2141   %add = add i32 %X, -14
2142   %cmp = icmp uge i32 %add, 2
2143   ret i1 %cmp
2146 define <2 x i1> @icmp_add_X_-14_uge_2_vec(<2 x i32> %X) {
2147 ; CHECK-LABEL: @icmp_add_X_-14_uge_2_vec(
2148 ; CHECK-NEXT:    [[TMP1:%.*]] = and <2 x i32> [[X:%.*]], <i32 -2, i32 -2>
2149 ; CHECK-NEXT:    [[CMP:%.*]] = icmp ne <2 x i32> [[TMP1]], <i32 14, i32 14>
2150 ; CHECK-NEXT:    ret <2 x i1> [[CMP]]
2152   %add = add <2 x i32> %X, <i32 -14, i32 -14>
2153   %cmp = icmp uge <2 x i32> %add, <i32 2, i32 2>
2154   ret <2 x i1> %cmp
2157 define i1 @icmp_sub_3_X_uge_2(i32 %X) {
2158 ; CHECK-LABEL: @icmp_sub_3_X_uge_2(
2159 ; CHECK-NEXT:    [[TMP1:%.*]] = and i32 [[X:%.*]], -2
2160 ; CHECK-NEXT:    [[CMP:%.*]] = icmp ne i32 [[TMP1]], 2
2161 ; CHECK-NEXT:    ret i1 [[CMP]]
2163   %add = sub i32 3, %X
2164   %cmp = icmp uge i32 %add, 2
2165   ret i1 %cmp
2168 define <2 x i1> @icmp_sub_3_X_uge_2_vec(<2 x i32> %X) {
2169 ; CHECK-LABEL: @icmp_sub_3_X_uge_2_vec(
2170 ; CHECK-NEXT:    [[TMP1:%.*]] = and <2 x i32> [[X:%.*]], <i32 -2, i32 -2>
2171 ; CHECK-NEXT:    [[CMP:%.*]] = icmp ne <2 x i32> [[TMP1]], <i32 2, i32 2>
2172 ; CHECK-NEXT:    ret <2 x i1> [[CMP]]
2174   %add = sub <2 x i32> <i32 3, i32 3>, %X
2175   %cmp = icmp uge <2 x i32> %add, <i32 2, i32 2>
2176   ret <2 x i1> %cmp
2179 define i1 @icmp_and_X_-16_eq-16(i32 %X) {
2180 ; CHECK-LABEL: @icmp_and_X_-16_eq-16(
2181 ; CHECK-NEXT:    [[CMP:%.*]] = icmp ugt i32 [[X:%.*]], -17
2182 ; CHECK-NEXT:    ret i1 [[CMP]]
2184   %and = and i32 %X, -16
2185   %cmp = icmp eq i32 %and, -16
2186   ret i1 %cmp
2189 define <2 x i1> @icmp_and_X_-16_eq-16_vec(<2 x i32> %X) {
2190 ; CHECK-LABEL: @icmp_and_X_-16_eq-16_vec(
2191 ; CHECK-NEXT:    [[CMP:%.*]] = icmp ugt <2 x i32> [[X:%.*]], <i32 -17, i32 -17>
2192 ; CHECK-NEXT:    ret <2 x i1> [[CMP]]
2194   %and = and <2 x i32> %X, <i32 -16, i32 -16>
2195   %cmp = icmp eq <2 x i32> %and, <i32 -16, i32 -16>
2196   ret <2 x i1> %cmp
2199 define i1 @icmp_and_X_-16_ne-16(i32 %X) {
2200 ; CHECK-LABEL: @icmp_and_X_-16_ne-16(
2201 ; CHECK-NEXT:    [[CMP:%.*]] = icmp ult i32 [[X:%.*]], -16
2202 ; CHECK-NEXT:    ret i1 [[CMP]]
2204   %and = and i32 %X, -16
2205   %cmp = icmp ne i32 %and, -16
2206   ret i1 %cmp
2209 define <2 x i1> @icmp_and_X_-16_ne-16_vec(<2 x i32> %X) {
2210 ; CHECK-LABEL: @icmp_and_X_-16_ne-16_vec(
2211 ; CHECK-NEXT:    [[CMP:%.*]] = icmp ult <2 x i32> [[X:%.*]], <i32 -16, i32 -16>
2212 ; CHECK-NEXT:    ret <2 x i1> [[CMP]]
2214   %and = and <2 x i32> %X, <i32 -16, i32 -16>
2215   %cmp = icmp ne <2 x i32> %and, <i32 -16, i32 -16>
2216   ret <2 x i1> %cmp
2219 ; PR32524: https://bugs.llvm.org/show_bug.cgi?id=32524
2220 ; X | C == C --> X <=u C (when C+1 is PowerOf2).
2222 define i1 @or1_eq1(i32 %x) {
2223 ; CHECK-LABEL: @or1_eq1(
2224 ; CHECK-NEXT:    [[T1:%.*]] = icmp ult i32 [[X:%.*]], 2
2225 ; CHECK-NEXT:    ret i1 [[T1]]
2227   %t0 = or i32 %x, 1
2228   %t1 = icmp eq i32 %t0, 1
2229   ret i1 %t1
2232 ; X | C == C --> X <=u C (when C+1 is PowerOf2).
2234 define <2 x i1> @or3_eq3_vec(<2 x i8> %x) {
2235 ; CHECK-LABEL: @or3_eq3_vec(
2236 ; CHECK-NEXT:    [[T1:%.*]] = icmp ult <2 x i8> [[X:%.*]], <i8 4, i8 4>
2237 ; CHECK-NEXT:    ret <2 x i1> [[T1]]
2239   %t0 = or <2 x i8> %x, <i8 3, i8 3>
2240   %t1 = icmp eq <2 x i8> %t0, <i8 3, i8 3>
2241   ret <2 x i1> %t1
2244 ; X | C != C --> X >u C (when C+1 is PowerOf2).
2246 define i1 @or7_ne7(i32 %x) {
2247 ; CHECK-LABEL: @or7_ne7(
2248 ; CHECK-NEXT:    [[T1:%.*]] = icmp ugt i32 [[X:%.*]], 7
2249 ; CHECK-NEXT:    ret i1 [[T1]]
2251   %t0 = or i32 %x, 7
2252   %t1 = icmp ne i32 %t0, 7
2253   ret i1 %t1
2256 ; X | C != C --> X >u C (when C+1 is PowerOf2).
2258 define <2 x i1> @or63_ne63_vec(<2 x i8> %x) {
2259 ; CHECK-LABEL: @or63_ne63_vec(
2260 ; CHECK-NEXT:    [[T1:%.*]] = icmp ugt <2 x i8> [[X:%.*]], <i8 63, i8 63>
2261 ; CHECK-NEXT:    ret <2 x i1> [[T1]]
2263   %t0 = or <2 x i8> %x, <i8 63, i8 63>
2264   %t1 = icmp ne <2 x i8> %t0, <i8 63, i8 63>
2265   ret <2 x i1> %t1
2268 ; PR40611: https://bugs.llvm.org/show_bug.cgi?id=40611
2269 ; X | C == C --> (X & ~C) == 0
2271 define i1 @orC_eqC(i32 %x) {
2272 ; CHECK-LABEL: @orC_eqC(
2273 ; CHECK-NEXT:    [[TMP1:%.*]] = and i32 [[X:%.*]], -43
2274 ; CHECK-NEXT:    [[T1:%.*]] = icmp eq i32 [[TMP1]], 0
2275 ; CHECK-NEXT:    ret i1 [[T1]]
2277   %t0 = or i32 %x, 42
2278   %t1 = icmp eq i32 %t0, 42
2279   ret i1 %t1
2282 ; X | C == C --> (X & ~C) == 0
2284 define <2 x i1> @orC_eqC_vec(<2 x i8> %x) {
2285 ; CHECK-LABEL: @orC_eqC_vec(
2286 ; CHECK-NEXT:    [[TMP1:%.*]] = and <2 x i8> [[X:%.*]], <i8 -44, i8 -44>
2287 ; CHECK-NEXT:    [[T1:%.*]] = icmp eq <2 x i8> [[TMP1]], zeroinitializer
2288 ; CHECK-NEXT:    ret <2 x i1> [[T1]]
2290   %t0 = or <2 x i8> %x, <i8 43, i8 43>
2291   %t1 = icmp eq <2 x i8> %t0, <i8 43, i8 43>
2292   ret <2 x i1> %t1
2295 ; X | C != C --> (X & ~C) != 0
2297 define i1 @orC_neC(i32 %x) {
2298 ; CHECK-LABEL: @orC_neC(
2299 ; CHECK-NEXT:    [[TMP1:%.*]] = and i32 [[X:%.*]], 41
2300 ; CHECK-NEXT:    [[T1:%.*]] = icmp ne i32 [[TMP1]], 0
2301 ; CHECK-NEXT:    ret i1 [[T1]]
2303   %t0 = or i32 %x, -42
2304   %t1 = icmp ne i32 %t0, -42
2305   ret i1 %t1
2308 ; X | C != C --> (X & ~C) != 0
2310 define <2 x i1> @orC_neC_vec(<2 x i8> %x) {
2311 ; CHECK-LABEL: @orC_neC_vec(
2312 ; CHECK-NEXT:    [[TMP1:%.*]] = and <2 x i8> [[X:%.*]], <i8 42, i8 42>
2313 ; CHECK-NEXT:    [[T1:%.*]] = icmp ne <2 x i8> [[TMP1]], zeroinitializer
2314 ; CHECK-NEXT:    ret <2 x i1> [[T1]]
2316   %t0 = or <2 x i8> %x, <i8 -43, i8 -43>
2317   %t1 = icmp ne <2 x i8> %t0, <i8 -43, i8 -43>
2318   ret <2 x i1> %t1
2321 define i1 @shrink_constant(i32 %X) {
2322 ; CHECK-LABEL: @shrink_constant(
2323 ; CHECK-NEXT:    [[XOR:%.*]] = xor i32 [[X:%.*]], -12
2324 ; CHECK-NEXT:    [[CMP:%.*]] = icmp ult i32 [[XOR]], 4
2325 ; CHECK-NEXT:    ret i1 [[CMP]]
2327   %xor = xor i32 %X, -9
2328   %cmp = icmp ult i32 %xor, 4
2329   ret i1 %cmp
2332 define <2 x i1> @shrink_constant_vec(<2 x i32> %X) {
2333 ; CHECK-LABEL: @shrink_constant_vec(
2334 ; CHECK-NEXT:    [[XOR:%.*]] = xor <2 x i32> [[X:%.*]], <i32 -12, i32 -12>
2335 ; CHECK-NEXT:    [[CMP:%.*]] = icmp ult <2 x i32> [[XOR]], <i32 4, i32 4>
2336 ; CHECK-NEXT:    ret <2 x i1> [[CMP]]
2338   %xor = xor <2 x i32> %X, <i32 -9, i32 -9>
2339   %cmp = icmp ult <2 x i32> %xor, <i32 4, i32 4>
2340   ret <2 x i1> %cmp
2343 ; This test requires 3 different transforms to get to the result.
2344 define i1 @icmp_sub_-1_X_ult_4(i32 %X) {
2345 ; CHECK-LABEL: @icmp_sub_-1_X_ult_4(
2346 ; CHECK-NEXT:    [[CMP:%.*]] = icmp ugt i32 [[X:%.*]], -5
2347 ; CHECK-NEXT:    ret i1 [[CMP]]
2349   %sub = sub i32 -1, %X
2350   %cmp = icmp ult i32 %sub, 4
2351   ret i1 %cmp
2354 define <2 x i1> @icmp_xor_neg4_X_ult_4_vec(<2 x i32> %X) {
2355 ; CHECK-LABEL: @icmp_xor_neg4_X_ult_4_vec(
2356 ; CHECK-NEXT:    [[CMP:%.*]] = icmp ugt <2 x i32> [[X:%.*]], <i32 -5, i32 -5>
2357 ; CHECK-NEXT:    ret <2 x i1> [[CMP]]
2359   %xor = xor <2 x i32> %X, <i32 -4, i32 -4>
2360   %cmp = icmp ult <2 x i32> %xor, <i32 4, i32 4>
2361   ret <2 x i1> %cmp
2364 define i1 @icmp_sub_-1_X_uge_4(i32 %X) {
2365 ; CHECK-LABEL: @icmp_sub_-1_X_uge_4(
2366 ; CHECK-NEXT:    [[CMP:%.*]] = icmp ult i32 [[X:%.*]], -4
2367 ; CHECK-NEXT:    ret i1 [[CMP]]
2369   %sub = sub i32 -1, %X
2370   %cmp = icmp uge i32 %sub, 4
2371   ret i1 %cmp
2374 define <2 x i1> @icmp_xor_neg4_X_uge_4_vec(<2 x i32> %X) {
2375 ; CHECK-LABEL: @icmp_xor_neg4_X_uge_4_vec(
2376 ; CHECK-NEXT:    [[CMP:%.*]] = icmp ult <2 x i32> [[X:%.*]], <i32 -4, i32 -4>
2377 ; CHECK-NEXT:    ret <2 x i1> [[CMP]]
2379   %xor = xor <2 x i32> %X, <i32 -4, i32 -4>
2380   %cmp = icmp uge <2 x i32> %xor, <i32 4, i32 4>
2381   ret <2 x i1> %cmp
2384 define <2 x i1> @xor_ult(<2 x i8> %x) {
2385 ; CHECK-LABEL: @xor_ult(
2386 ; CHECK-NEXT:    [[R:%.*]] = icmp ugt <2 x i8> [[X:%.*]], <i8 3, i8 3>
2387 ; CHECK-NEXT:    ret <2 x i1> [[R]]
2389   %xor = xor <2 x i8> %x, <i8 -4, i8 -4>
2390   %r = icmp ult <2 x i8> %xor, <i8 -4, i8 -4>
2391   ret <2 x i1> %r
2394 define i1 @xor_ult_extra_use(i8 %x, i8* %p) {
2395 ; CHECK-LABEL: @xor_ult_extra_use(
2396 ; CHECK-NEXT:    [[XOR:%.*]] = xor i8 [[X:%.*]], -32
2397 ; CHECK-NEXT:    store i8 [[XOR]], i8* [[P:%.*]], align 1
2398 ; CHECK-NEXT:    [[R:%.*]] = icmp ugt i8 [[X]], 31
2399 ; CHECK-NEXT:    ret i1 [[R]]
2401   %xor = xor i8 %x, -32
2402   store i8 %xor, i8* %p
2403   %r = icmp ult i8 %xor, -32
2404   ret i1 %r
2407 define <2 x i1> @xor_ugt(<2 x i8> %x) {
2408 ; CHECK-LABEL: @xor_ugt(
2409 ; CHECK-NEXT:    [[R:%.*]] = icmp ugt <2 x i8> [[X:%.*]], <i8 7, i8 7>
2410 ; CHECK-NEXT:    ret <2 x i1> [[R]]
2412   %xor = xor <2 x i8> %x, <i8 7, i8 7>
2413   %r = icmp ugt <2 x i8> %xor, <i8 7, i8 7>
2414   ret <2 x i1> %r
2417 define i1 @xor_ugt_extra_use(i8 %x, i8* %p) {
2418 ; CHECK-LABEL: @xor_ugt_extra_use(
2419 ; CHECK-NEXT:    [[XOR:%.*]] = xor i8 [[X:%.*]], 63
2420 ; CHECK-NEXT:    store i8 [[XOR]], i8* [[P:%.*]], align 1
2421 ; CHECK-NEXT:    [[R:%.*]] = icmp ugt i8 [[X]], 63
2422 ; CHECK-NEXT:    ret i1 [[R]]
2424   %xor = xor i8 %x, 63
2425   store i8 %xor, i8* %p
2426   %r = icmp ugt i8 %xor, 63
2427   ret i1 %r
2430 define i1 @icmp_swap_operands_for_cse(i32 %X, i32 %Y) {
2431 ; CHECK-LABEL: @icmp_swap_operands_for_cse(
2432 ; CHECK-NEXT:  entry:
2433 ; CHECK-NEXT:    [[SUB:%.*]] = sub i32 [[X:%.*]], [[Y:%.*]]
2434 ; CHECK-NEXT:    [[CMP:%.*]] = icmp ult i32 [[X]], [[Y]]
2435 ; CHECK-NEXT:    br i1 [[CMP]], label [[TRUE:%.*]], label [[FALSE:%.*]]
2436 ; CHECK:       true:
2437 ; CHECK-NEXT:    [[TMP0:%.*]] = and i32 [[SUB]], 1
2438 ; CHECK-NEXT:    br label [[END:%.*]]
2439 ; CHECK:       false:
2440 ; CHECK-NEXT:    [[TMP1:%.*]] = and i32 [[SUB]], 16
2441 ; CHECK-NEXT:    br label [[END]]
2442 ; CHECK:       end:
2443 ; CHECK-NEXT:    [[RES_IN:%.*]] = phi i32 [ [[TMP0]], [[TRUE]] ], [ [[TMP1]], [[FALSE]] ]
2444 ; CHECK-NEXT:    [[RES:%.*]] = icmp ne i32 [[RES_IN]], 0
2445 ; CHECK-NEXT:    ret i1 [[RES]]
2447 entry:
2448   %sub = sub i32 %X, %Y
2449   %cmp = icmp ugt i32 %Y, %X
2450   br i1 %cmp, label %true, label %false
2451 true:
2452   %restrue = trunc i32 %sub to i1
2453   br label %end
2454 false:
2455   %shift = lshr i32 %sub, 4
2456   %resfalse = trunc i32 %shift to i1
2457   br label %end
2458 end:
2459   %res = phi i1 [%restrue, %true], [%resfalse, %false]
2460   ret i1 %res
2463 define i1 @icmp_swap_operands_for_cse2(i32 %X, i32 %Y) {
2464 ; CHECK-LABEL: @icmp_swap_operands_for_cse2(
2465 ; CHECK-NEXT:  entry:
2466 ; CHECK-NEXT:    [[CMP:%.*]] = icmp ult i32 [[X:%.*]], [[Y:%.*]]
2467 ; CHECK-NEXT:    br i1 [[CMP]], label [[TRUE:%.*]], label [[FALSE:%.*]]
2468 ; CHECK:       true:
2469 ; CHECK-NEXT:    [[SUB:%.*]] = sub i32 [[X]], [[Y]]
2470 ; CHECK-NEXT:    [[SUB1:%.*]] = sub i32 [[X]], [[Y]]
2471 ; CHECK-NEXT:    [[ADD:%.*]] = add i32 [[SUB]], [[SUB1]]
2472 ; CHECK-NEXT:    br label [[END:%.*]]
2473 ; CHECK:       false:
2474 ; CHECK-NEXT:    [[SUB2:%.*]] = sub i32 [[Y]], [[X]]
2475 ; CHECK-NEXT:    br label [[END]]
2476 ; CHECK:       end:
2477 ; CHECK-NEXT:    [[RES_IN_IN:%.*]] = phi i32 [ [[ADD]], [[TRUE]] ], [ [[SUB2]], [[FALSE]] ]
2478 ; CHECK-NEXT:    [[RES_IN:%.*]] = and i32 [[RES_IN_IN]], 1
2479 ; CHECK-NEXT:    [[RES:%.*]] = icmp ne i32 [[RES_IN]], 0
2480 ; CHECK-NEXT:    ret i1 [[RES]]
2482 entry:
2483   %cmp = icmp ugt i32 %Y, %X
2484   br i1 %cmp, label %true, label %false
2485 true:
2486   %sub = sub i32 %X, %Y
2487   %sub1 = sub i32 %X, %Y
2488   %add = add i32 %sub, %sub1
2489   %restrue = trunc i32 %add to i1
2490   br label %end
2491 false:
2492   %sub2 = sub i32 %Y, %X
2493   %resfalse = trunc i32 %sub2 to i1
2494   br label %end
2495 end:
2496   %res = phi i1 [%restrue, %true], [%resfalse, %false]
2497   ret i1 %res
2500 define i1 @icmp_do_not_swap_operands_for_cse(i32 %X, i32 %Y) {
2501 ; CHECK-LABEL: @icmp_do_not_swap_operands_for_cse(
2502 ; CHECK-NEXT:  entry:
2503 ; CHECK-NEXT:    [[CMP:%.*]] = icmp ugt i32 [[Y:%.*]], [[X:%.*]]
2504 ; CHECK-NEXT:    br i1 [[CMP]], label [[TRUE:%.*]], label [[FALSE:%.*]]
2505 ; CHECK:       true:
2506 ; CHECK-NEXT:    [[SUB:%.*]] = sub i32 [[X]], [[Y]]
2507 ; CHECK-NEXT:    br label [[END:%.*]]
2508 ; CHECK:       false:
2509 ; CHECK-NEXT:    [[SUB2:%.*]] = sub i32 [[Y]], [[X]]
2510 ; CHECK-NEXT:    br label [[END]]
2511 ; CHECK:       end:
2512 ; CHECK-NEXT:    [[RES_IN_IN:%.*]] = phi i32 [ [[SUB]], [[TRUE]] ], [ [[SUB2]], [[FALSE]] ]
2513 ; CHECK-NEXT:    [[RES_IN:%.*]] = and i32 [[RES_IN_IN]], 1
2514 ; CHECK-NEXT:    [[RES:%.*]] = icmp ne i32 [[RES_IN]], 0
2515 ; CHECK-NEXT:    ret i1 [[RES]]
2517 entry:
2518   %cmp = icmp ugt i32 %Y, %X
2519   br i1 %cmp, label %true, label %false
2520 true:
2521   %sub = sub i32 %X, %Y
2522   %restrue = trunc i32 %sub to i1
2523   br label %end
2524 false:
2525   %sub2 = sub i32 %Y, %X
2526   %resfalse = trunc i32 %sub2 to i1
2527   br label %end
2528 end:
2529   %res = phi i1 [%restrue, %true], [%resfalse, %false]
2530   ret i1 %res
2533 define i1 @icmp_lshr_lshr_eq(i32 %a, i32 %b) {
2534 ; CHECK-LABEL: @icmp_lshr_lshr_eq(
2535 ; CHECK-NEXT:    [[Z_UNSHIFTED:%.*]] = xor i32 [[A:%.*]], [[B:%.*]]
2536 ; CHECK-NEXT:    [[Z:%.*]] = icmp ult i32 [[Z_UNSHIFTED]], 1073741824
2537 ; CHECK-NEXT:    ret i1 [[Z]]
2539   %x = lshr i32 %a, 30
2540   %y = lshr i32 %b, 30
2541   %z = icmp eq i32 %x, %y
2542   ret i1 %z
2545 define i1 @icmp_ashr_ashr_ne(i32 %a, i32 %b) {
2546 ; CHECK-LABEL: @icmp_ashr_ashr_ne(
2547 ; CHECK-NEXT:    [[Z_UNSHIFTED:%.*]] = xor i32 [[A:%.*]], [[B:%.*]]
2548 ; CHECK-NEXT:    [[Z:%.*]] = icmp ugt i32 [[Z_UNSHIFTED]], 255
2549 ; CHECK-NEXT:    ret i1 [[Z]]
2551   %x = ashr i32 %a, 8
2552   %y = ashr i32 %b, 8
2553   %z = icmp ne i32 %x, %y
2554   ret i1 %z
2557 define i1 @icmp_neg_cst_slt(i32 %a) {
2558 ; CHECK-LABEL: @icmp_neg_cst_slt(
2559 ; CHECK-NEXT:    [[TMP1:%.*]] = icmp sgt i32 [[A:%.*]], 10
2560 ; CHECK-NEXT:    ret i1 [[TMP1]]
2562   %1 = sub nsw i32 0, %a
2563   %2 = icmp slt i32 %1, -10
2564   ret i1 %2
2567 define i1 @icmp_and_or_lshr(i32 %x, i32 %y) {
2568 ; CHECK-LABEL: @icmp_and_or_lshr(
2569 ; CHECK-NEXT:    [[SHF1:%.*]] = shl nuw i32 1, [[Y:%.*]]
2570 ; CHECK-NEXT:    [[OR2:%.*]] = or i32 [[SHF1]], 1
2571 ; CHECK-NEXT:    [[AND3:%.*]] = and i32 [[OR2]], [[X:%.*]]
2572 ; CHECK-NEXT:    [[RET:%.*]] = icmp ne i32 [[AND3]], 0
2573 ; CHECK-NEXT:    ret i1 [[RET]]
2575   %shf = lshr i32 %x, %y
2576   %or = or i32 %shf, %x
2577   %and = and i32 %or, 1
2578   %ret = icmp ne i32 %and, 0
2579   ret i1 %ret
2582 define <2 x i1> @icmp_and_or_lshr_vec(<2 x i32> %x, <2 x i32> %y) {
2583 ; CHECK-LABEL: @icmp_and_or_lshr_vec(
2584 ; CHECK-NEXT:    [[SHF:%.*]] = lshr <2 x i32> [[X:%.*]], [[Y:%.*]]
2585 ; CHECK-NEXT:    [[OR:%.*]] = or <2 x i32> [[SHF]], [[X]]
2586 ; CHECK-NEXT:    [[RET:%.*]] = trunc <2 x i32> [[OR]] to <2 x i1>
2587 ; CHECK-NEXT:    ret <2 x i1> [[RET]]
2589   %shf = lshr <2 x i32> %x, %y
2590   %or = or <2 x i32> %shf, %x
2591   %and = and <2 x i32> %or, <i32 1, i32 1>
2592   %ret = icmp ne <2 x i32> %and, zeroinitializer
2593   ret <2 x i1> %ret
2596 define <2 x i1> @icmp_and_or_lshr_vec_commute(<2 x i32> %xp, <2 x i32> %y) {
2597 ; CHECK-LABEL: @icmp_and_or_lshr_vec_commute(
2598 ; CHECK-NEXT:    [[X:%.*]] = srem <2 x i32> [[XP:%.*]], <i32 42, i32 42>
2599 ; CHECK-NEXT:    [[SHF:%.*]] = lshr <2 x i32> [[X]], [[Y:%.*]]
2600 ; CHECK-NEXT:    [[OR:%.*]] = or <2 x i32> [[X]], [[SHF]]
2601 ; CHECK-NEXT:    [[RET:%.*]] = trunc <2 x i32> [[OR]] to <2 x i1>
2602 ; CHECK-NEXT:    ret <2 x i1> [[RET]]
2604   %x = srem <2 x i32> %xp, <i32 42, i32 -42> ; prevent complexity-based canonicalization
2605   %shf = lshr <2 x i32> %x, %y
2606   %or = or <2 x i32> %x, %shf
2607   %and = and <2 x i32> %or, <i32 1, i32 1>
2608   %ret = icmp ne <2 x i32> %and, zeroinitializer
2609   ret <2 x i1> %ret
2612 define i1 @icmp_and_or_lshr_cst(i32 %x) {
2613 ; CHECK-LABEL: @icmp_and_or_lshr_cst(
2614 ; CHECK-NEXT:    [[AND1:%.*]] = and i32 [[X:%.*]], 3
2615 ; CHECK-NEXT:    [[RET:%.*]] = icmp ne i32 [[AND1]], 0
2616 ; CHECK-NEXT:    ret i1 [[RET]]
2618   %shf = lshr i32 %x, 1
2619   %or = or i32 %shf, %x
2620   %and = and i32 %or, 1
2621   %ret = icmp ne i32 %and, 0
2622   ret i1 %ret
2625 define <2 x i1> @icmp_and_or_lshr_cst_vec(<2 x i32> %x) {
2626 ; CHECK-LABEL: @icmp_and_or_lshr_cst_vec(
2627 ; CHECK-NEXT:    [[TMP1:%.*]] = and <2 x i32> [[X:%.*]], <i32 3, i32 3>
2628 ; CHECK-NEXT:    [[RET:%.*]] = icmp ne <2 x i32> [[TMP1]], zeroinitializer
2629 ; CHECK-NEXT:    ret <2 x i1> [[RET]]
2631   %shf = lshr <2 x i32> %x, <i32 1, i32 1>
2632   %or = or <2 x i32> %shf, %x
2633   %and = and <2 x i32> %or, <i32 1, i32 1>
2634   %ret = icmp ne <2 x i32> %and, zeroinitializer
2635   ret <2 x i1> %ret
2638 define <2 x i1> @icmp_and_or_lshr_cst_vec_nonuniform(<2 x i32> %x) {
2639 ; CHECK-LABEL: @icmp_and_or_lshr_cst_vec_nonuniform(
2640 ; CHECK-NEXT:    [[TMP1:%.*]] = and <2 x i32> [[X:%.*]], <i32 3, i32 5>
2641 ; CHECK-NEXT:    [[RET:%.*]] = icmp ne <2 x i32> [[TMP1]], zeroinitializer
2642 ; CHECK-NEXT:    ret <2 x i1> [[RET]]
2644   %shf = lshr <2 x i32> %x, <i32 1, i32 2>
2645   %or = or <2 x i32> %shf, %x
2646   %and = and <2 x i32> %or, <i32 1, i32 1>
2647   %ret = icmp ne <2 x i32> %and, zeroinitializer
2648   ret <2 x i1> %ret
2651 define <2 x i1> @icmp_and_or_lshr_cst_vec_undef(<2 x i32> %x) {
2652 ; CHECK-LABEL: @icmp_and_or_lshr_cst_vec_undef(
2653 ; CHECK-NEXT:    [[TMP1:%.*]] = and <2 x i32> [[X:%.*]], <i32 3, i32 poison>
2654 ; CHECK-NEXT:    [[RET:%.*]] = icmp ne <2 x i32> [[TMP1]], zeroinitializer
2655 ; CHECK-NEXT:    ret <2 x i1> [[RET]]
2657   %shf = lshr <2 x i32> %x, <i32 1, i32 undef>
2658   %or = or <2 x i32> %shf, %x
2659   %and = and <2 x i32> %or, <i32 1, i32 1>
2660   %ret = icmp ne <2 x i32> %and, zeroinitializer
2661   ret <2 x i1> %ret
2664 define <2 x i1> @icmp_and_or_lshr_cst_vec_commute(<2 x i32> %xp) {
2665 ; CHECK-LABEL: @icmp_and_or_lshr_cst_vec_commute(
2666 ; CHECK-NEXT:    [[X:%.*]] = srem <2 x i32> [[XP:%.*]], <i32 42, i32 42>
2667 ; CHECK-NEXT:    [[TMP1:%.*]] = and <2 x i32> [[X]], <i32 3, i32 3>
2668 ; CHECK-NEXT:    [[RET:%.*]] = icmp ne <2 x i32> [[TMP1]], zeroinitializer
2669 ; CHECK-NEXT:    ret <2 x i1> [[RET]]
2671   %x = srem <2 x i32> %xp, <i32 42, i32 -42> ; prevent complexity-based canonicalization
2672   %shf = lshr <2 x i32> %x, <i32 1, i32 1>
2673   %or = or <2 x i32> %x, %shf
2674   %and = and <2 x i32> %or, <i32 1, i32 1>
2675   %ret = icmp ne <2 x i32> %and, zeroinitializer
2676   ret <2 x i1> %ret
2679 define <2 x i1> @icmp_and_or_lshr_cst_vec_nonuniform_commute(<2 x i32> %xp) {
2680 ; CHECK-LABEL: @icmp_and_or_lshr_cst_vec_nonuniform_commute(
2681 ; CHECK-NEXT:    [[X:%.*]] = srem <2 x i32> [[XP:%.*]], <i32 42, i32 42>
2682 ; CHECK-NEXT:    [[TMP1:%.*]] = and <2 x i32> [[X]], <i32 3, i32 5>
2683 ; CHECK-NEXT:    [[RET:%.*]] = icmp ne <2 x i32> [[TMP1]], zeroinitializer
2684 ; CHECK-NEXT:    ret <2 x i1> [[RET]]
2686   %x = srem <2 x i32> %xp, <i32 42, i32 -42> ; prevent complexity-based canonicalization
2687   %shf = lshr <2 x i32> %x, <i32 1, i32 2>
2688   %or = or <2 x i32> %x, %shf
2689   %and = and <2 x i32> %or, <i32 1, i32 1>
2690   %ret = icmp ne <2 x i32> %and, zeroinitializer
2691   ret <2 x i1> %ret
2694 define <2 x i1> @icmp_and_or_lshr_cst_vec_undef_commute(<2 x i32> %xp) {
2695 ; CHECK-LABEL: @icmp_and_or_lshr_cst_vec_undef_commute(
2696 ; CHECK-NEXT:    [[X:%.*]] = srem <2 x i32> [[XP:%.*]], <i32 42, i32 42>
2697 ; CHECK-NEXT:    [[TMP1:%.*]] = and <2 x i32> [[X]], <i32 3, i32 poison>
2698 ; CHECK-NEXT:    [[RET:%.*]] = icmp ne <2 x i32> [[TMP1]], zeroinitializer
2699 ; CHECK-NEXT:    ret <2 x i1> [[RET]]
2701   %x = srem <2 x i32> %xp, <i32 42, i32 -42> ; prevent complexity-based canonicalization
2702   %shf = lshr <2 x i32> %x, <i32 1, i32 undef>
2703   %or = or <2 x i32> %x, %shf
2704   %and = and <2 x i32> %or, <i32 1, i32 1>
2705   %ret = icmp ne <2 x i32> %and, zeroinitializer
2706   ret <2 x i1> %ret
2709 define i1 @shl_ap1_zero_ap2_non_zero_2(i32 %a) {
2710 ; CHECK-LABEL: @shl_ap1_zero_ap2_non_zero_2(
2711 ; CHECK-NEXT:    [[CMP:%.*]] = icmp ugt i32 [[A:%.*]], 29
2712 ; CHECK-NEXT:    ret i1 [[CMP]]
2714   %shl = shl i32 4, %a
2715   %cmp = icmp eq i32 %shl, 0
2716   ret i1 %cmp
2719 define <2 x i1> @shl_ap1_zero_ap2_non_zero_2_vec(<2 x i32> %a) {
2720 ; CHECK-LABEL: @shl_ap1_zero_ap2_non_zero_2_vec(
2721 ; CHECK-NEXT:    [[CMP:%.*]] = icmp ugt <2 x i32> [[A:%.*]], <i32 29, i32 29>
2722 ; CHECK-NEXT:    ret <2 x i1> [[CMP]]
2724   %shl = shl <2 x i32> <i32 4, i32 4>, %a
2725   %cmp = icmp eq <2 x i32> %shl, zeroinitializer
2726   ret <2 x i1> %cmp
2729 define <2 x i1> @shl_ap1_zero_ap2_non_zero_2_vec_nonuniform(<2 x i32> %a) {
2730 ; CHECK-LABEL: @shl_ap1_zero_ap2_non_zero_2_vec_nonuniform(
2731 ; CHECK-NEXT:    [[SHL:%.*]] = shl <2 x i32> <i32 4, i32 5>, [[A:%.*]]
2732 ; CHECK-NEXT:    [[CMP:%.*]] = icmp eq <2 x i32> [[SHL]], zeroinitializer
2733 ; CHECK-NEXT:    ret <2 x i1> [[CMP]]
2735   %shl = shl <2 x i32> <i32 4, i32 5>, %a
2736   %cmp = icmp eq <2 x i32> %shl, zeroinitializer
2737   ret <2 x i1> %cmp
2740 define i1 @shl_ap1_zero_ap2_non_zero_4(i32 %a) {
2741 ; CHECK-LABEL: @shl_ap1_zero_ap2_non_zero_4(
2742 ; CHECK-NEXT:    [[CMP:%.*]] = icmp ugt i32 [[A:%.*]], 30
2743 ; CHECK-NEXT:    ret i1 [[CMP]]
2745   %shl = shl i32 -2, %a
2746   %cmp = icmp eq i32 %shl, 0
2747   ret i1 %cmp
2750 define i1 @shl_ap1_non_zero_ap2_non_zero_both_positive(i32 %a) {
2751 ; CHECK-LABEL: @shl_ap1_non_zero_ap2_non_zero_both_positive(
2752 ; CHECK-NEXT:    [[CMP:%.*]] = icmp eq i32 [[A:%.*]], 0
2753 ; CHECK-NEXT:    ret i1 [[CMP]]
2755   %shl = shl i32 50, %a
2756   %cmp = icmp eq i32 %shl, 50
2757   ret i1 %cmp
2760 define i1 @shl_ap1_non_zero_ap2_non_zero_both_negative(i32 %a) {
2761 ; CHECK-LABEL: @shl_ap1_non_zero_ap2_non_zero_both_negative(
2762 ; CHECK-NEXT:    [[CMP:%.*]] = icmp eq i32 [[A:%.*]], 0
2763 ; CHECK-NEXT:    ret i1 [[CMP]]
2765   %shl = shl i32 -50, %a
2766   %cmp = icmp eq i32 %shl, -50
2767   ret i1 %cmp
2770 define i1 @shl_ap1_non_zero_ap2_non_zero_ap1_1(i32 %a) {
2771 ; CHECK-LABEL: @shl_ap1_non_zero_ap2_non_zero_ap1_1(
2772 ; CHECK-NEXT:    ret i1 false
2774   %shl = shl i32 50, %a
2775   %cmp = icmp eq i32 %shl, 25
2776   ret i1 %cmp
2779 define i1 @shl_ap1_non_zero_ap2_non_zero_ap1_2(i32 %a) {
2780 ; CHECK-LABEL: @shl_ap1_non_zero_ap2_non_zero_ap1_2(
2781 ; CHECK-NEXT:    [[CMP:%.*]] = icmp eq i32 [[A:%.*]], 1
2782 ; CHECK-NEXT:    ret i1 [[CMP]]
2784   %shl = shl i32 25, %a
2785   %cmp = icmp eq i32 %shl, 50
2786   ret i1 %cmp
2789 define i1 @shl_ap1_non_zero_ap2_non_zero_ap1_3(i32 %a) {
2790 ; CHECK-LABEL: @shl_ap1_non_zero_ap2_non_zero_ap1_3(
2791 ; CHECK-NEXT:    ret i1 false
2793   %shl = shl i32 26, %a
2794   %cmp = icmp eq i32 %shl, 50
2795   ret i1 %cmp
2798 define i1 @icmp_sgt_zero_add_nsw(i32 %a) {
2799 ; CHECK-LABEL: @icmp_sgt_zero_add_nsw(
2800 ; CHECK-NEXT:    [[CMP:%.*]] = icmp sgt i32 [[A:%.*]], -1
2801 ; CHECK-NEXT:    ret i1 [[CMP]]
2803   %add = add nsw i32 %a, 1
2804   %cmp = icmp sgt i32 %add, 0
2805   ret i1 %cmp
2808 define i1 @icmp_sge_zero_add_nsw(i32 %a) {
2809 ; CHECK-LABEL: @icmp_sge_zero_add_nsw(
2810 ; CHECK-NEXT:    [[CMP:%.*]] = icmp sgt i32 [[A:%.*]], -2
2811 ; CHECK-NEXT:    ret i1 [[CMP]]
2813   %add = add nsw i32 %a, 1
2814   %cmp = icmp sge i32 %add, 0
2815   ret i1 %cmp
2818 define i1 @icmp_sle_zero_add_nsw(i32 %a) {
2819 ; CHECK-LABEL: @icmp_sle_zero_add_nsw(
2820 ; CHECK-NEXT:    [[CMP:%.*]] = icmp slt i32 [[A:%.*]], 0
2821 ; CHECK-NEXT:    ret i1 [[CMP]]
2823   %add = add nsw i32 %a, 1
2824   %cmp = icmp sle i32 %add, 0
2825   ret i1 %cmp
2828 define zeroext i1 @icmp_cmpxchg_strong(i32* %sc, i32 %old_val, i32 %new_val) {
2829 ; CHECK-LABEL: @icmp_cmpxchg_strong(
2830 ; CHECK-NEXT:    [[XCHG:%.*]] = cmpxchg i32* [[SC:%.*]], i32 [[OLD_VAL:%.*]], i32 [[NEW_VAL:%.*]] seq_cst seq_cst, align 4
2831 ; CHECK-NEXT:    [[ICMP:%.*]] = extractvalue { i32, i1 } [[XCHG]], 1
2832 ; CHECK-NEXT:    ret i1 [[ICMP]]
2834   %xchg = cmpxchg i32* %sc, i32 %old_val, i32 %new_val seq_cst seq_cst
2835   %xtrc = extractvalue { i32, i1 } %xchg, 0
2836   %icmp = icmp eq i32 %xtrc, %old_val
2837   ret i1 %icmp
2840 define i1 @f1(i64 %a, i64 %b) {
2841 ; CHECK-LABEL: @f1(
2842 ; CHECK-NEXT:    [[V:%.*]] = icmp sge i64 [[A:%.*]], [[B:%.*]]
2843 ; CHECK-NEXT:    ret i1 [[V]]
2845   %t = sub nsw i64 %a, %b
2846   %v = icmp sge i64 %t, 0
2847   ret i1 %v
2850 define <2 x i1> @f1_vec(<2 x i64> %a, <2 x i64> %b) {
2851 ; CHECK-LABEL: @f1_vec(
2852 ; CHECK-NEXT:    [[V:%.*]] = icmp sge <2 x i64> [[A:%.*]], [[B:%.*]]
2853 ; CHECK-NEXT:    ret <2 x i1> [[V]]
2855   %t = sub nsw <2 x i64> %a, %b
2856   %v = icmp sgt <2 x i64> %t, <i64 -1, i64 -1>
2857   ret <2 x i1> %v
2860 define i1 @f2(i64 %a, i64 %b) {
2861 ; CHECK-LABEL: @f2(
2862 ; CHECK-NEXT:    [[V:%.*]] = icmp sgt i64 [[A:%.*]], [[B:%.*]]
2863 ; CHECK-NEXT:    ret i1 [[V]]
2865   %t = sub nsw i64 %a, %b
2866   %v = icmp sgt i64 %t, 0
2867   ret i1 %v
2870 define <2 x i1> @f2_vec(<2 x i64> %a, <2 x i64> %b) {
2871 ; CHECK-LABEL: @f2_vec(
2872 ; CHECK-NEXT:    [[V:%.*]] = icmp sgt <2 x i64> [[A:%.*]], [[B:%.*]]
2873 ; CHECK-NEXT:    ret <2 x i1> [[V]]
2875   %t = sub nsw <2 x i64> %a, %b
2876   %v = icmp sgt <2 x i64> %t, zeroinitializer
2877   ret <2 x i1> %v
2880 define i1 @f3(i64 %a, i64 %b) {
2881 ; CHECK-LABEL: @f3(
2882 ; CHECK-NEXT:    [[V:%.*]] = icmp slt i64 [[A:%.*]], [[B:%.*]]
2883 ; CHECK-NEXT:    ret i1 [[V]]
2885   %t = sub nsw i64 %a, %b
2886   %v = icmp slt i64 %t, 0
2887   ret i1 %v
2890 define <2 x i1> @f3_vec(<2 x i64> %a, <2 x i64> %b) {
2891 ; CHECK-LABEL: @f3_vec(
2892 ; CHECK-NEXT:    [[V:%.*]] = icmp slt <2 x i64> [[A:%.*]], [[B:%.*]]
2893 ; CHECK-NEXT:    ret <2 x i1> [[V]]
2895   %t = sub nsw <2 x i64> %a, %b
2896   %v = icmp slt <2 x i64> %t, zeroinitializer
2897   ret <2 x i1> %v
2900 define i1 @f4(i64 %a, i64 %b) {
2901 ; CHECK-LABEL: @f4(
2902 ; CHECK-NEXT:    [[V:%.*]] = icmp sle i64 [[A:%.*]], [[B:%.*]]
2903 ; CHECK-NEXT:    ret i1 [[V]]
2905   %t = sub nsw i64 %a, %b
2906   %v = icmp sle i64 %t, 0
2907   ret i1 %v
2910 define <2 x i1> @f4_vec(<2 x i64> %a, <2 x i64> %b) {
2911 ; CHECK-LABEL: @f4_vec(
2912 ; CHECK-NEXT:    [[V:%.*]] = icmp sle <2 x i64> [[A:%.*]], [[B:%.*]]
2913 ; CHECK-NEXT:    ret <2 x i1> [[V]]
2915   %t = sub nsw <2 x i64> %a, %b
2916   %v = icmp slt <2 x i64> %t, <i64 1, i64 1>
2917   ret <2 x i1> %v
2920 define i32 @f5(i8 %a, i8 %b) {
2921 ; CHECK-LABEL: @f5(
2922 ; CHECK-NEXT:    [[CONV:%.*]] = zext i8 [[A:%.*]] to i32
2923 ; CHECK-NEXT:    [[CONV3:%.*]] = zext i8 [[B:%.*]] to i32
2924 ; CHECK-NEXT:    [[SUB:%.*]] = sub nsw i32 [[CONV]], [[CONV3]]
2925 ; CHECK-NEXT:    [[TMP1:%.*]] = call i32 @llvm.abs.i32(i32 [[SUB]], i1 true)
2926 ; CHECK-NEXT:    ret i32 [[TMP1]]
2928   %conv = zext i8 %a to i32
2929   %conv3 = zext i8 %b to i32
2930   %sub = sub nsw i32 %conv, %conv3
2931   %cmp4 = icmp slt i32 %sub, 0
2932   %sub7 = sub nsw i32 0, %sub
2933   %sub7.sub = select i1 %cmp4, i32 %sub7, i32 %sub
2934   ret i32 %sub7.sub
2937 define i32 @f6(i32 %a, i32 %b) {
2938 ; CHECK-LABEL: @f6(
2939 ; CHECK-NEXT:    [[CMP_UNSHIFTED:%.*]] = xor i32 [[A:%.*]], [[B:%.*]]
2940 ; CHECK-NEXT:    [[CMP_MASK:%.*]] = and i32 [[CMP_UNSHIFTED]], 255
2941 ; CHECK-NEXT:    [[CMP:%.*]] = icmp eq i32 [[CMP_MASK]], 0
2942 ; CHECK-NEXT:    [[S:%.*]] = select i1 [[CMP]], i32 10000, i32 0
2943 ; CHECK-NEXT:    ret i32 [[S]]
2945   %sext = shl i32 %a, 24
2946   %conv = ashr i32 %sext, 24
2947   %sext6 = shl i32 %b, 24
2948   %conv4 = ashr i32 %sext6, 24
2949   %cmp = icmp eq i32 %conv, %conv4
2950   %s = select i1 %cmp, i32 10000, i32 0
2951   ret i32 %s
2954 define i32 @f7(i32 %a, i32 %b) {
2955 ; CHECK-LABEL: @f7(
2956 ; CHECK-NEXT:    [[CMP_NOT_UNSHIFTED:%.*]] = xor i32 [[A:%.*]], [[B:%.*]]
2957 ; CHECK-NEXT:    [[CMP_NOT_MASK:%.*]] = and i32 [[CMP_NOT_UNSHIFTED]], 511
2958 ; CHECK-NEXT:    [[CMP_NOT:%.*]] = icmp eq i32 [[CMP_NOT_MASK]], 0
2959 ; CHECK-NEXT:    [[S:%.*]] = select i1 [[CMP_NOT]], i32 0, i32 10000
2960 ; CHECK-NEXT:    ret i32 [[S]]
2962   %sext = shl i32 %a, 23
2963   %sext6 = shl i32 %b, 23
2964   %cmp = icmp ne i32 %sext, %sext6
2965   %s = select i1 %cmp, i32 10000, i32 0
2966   ret i32 %s
2969 define i1 @f8(i32 %val, i32 %lim) {
2970 ; CHECK-LABEL: @f8(
2971 ; CHECK-NEXT:    [[R:%.*]] = icmp ne i32 [[LIM:%.*]], 0
2972 ; CHECK-NEXT:    ret i1 [[R]]
2974   %lim.sub = add i32 %lim, -1
2975   %val.and = and i32 %val, %lim.sub
2976   %r = icmp ult i32 %val.and, %lim
2977   ret i1 %r
2980 define i1 @f9(i32 %val, i32 %lim) {
2981 ; CHECK-LABEL: @f9(
2982 ; CHECK-NEXT:    [[R:%.*]] = icmp ne i32 [[LIM:%.*]], 0
2983 ; CHECK-NEXT:    ret i1 [[R]]
2985   %lim.sub = sub i32 %lim, 1
2986   %val.and = and i32 %val, %lim.sub
2987   %r = icmp ult i32 %val.and, %lim
2988   ret i1 %r
2991 define i1 @f10(i16 %p) {
2992 ; CHECK-LABEL: @f10(
2993 ; CHECK-NEXT:    [[CMP580:%.*]] = icmp uge i16 [[P:%.*]], mul (i16 zext (i8 ptrtoint (i1 (i16)* @f10 to i8) to i16), i16 zext (i8 ptrtoint (i1 (i16)* @f10 to i8) to i16))
2994 ; CHECK-NEXT:    ret i1 [[CMP580]]
2996   %cmp580 = icmp ule i16 mul (i16 zext (i8 ptrtoint (i1 (i16)* @f10 to i8) to i16), i16 zext (i8 ptrtoint (i1 (i16)* @f10 to i8) to i16)), %p
2997   ret i1 %cmp580
3000 ; Note: fptosi is used in various tests below to ensure that operand complexity
3001 ; canonicalization does not kick in, which would make some of the tests
3002 ; equivalent to one another.
3004 define i1 @cmp_sgt_rhs_dec(float %x, i32 %i) {
3005 ; CHECK-LABEL: @cmp_sgt_rhs_dec(
3006 ; CHECK-NEXT:    [[CONV:%.*]] = fptosi float [[X:%.*]] to i32
3007 ; CHECK-NEXT:    [[CMP:%.*]] = icmp sge i32 [[CONV]], [[I:%.*]]
3008 ; CHECK-NEXT:    ret i1 [[CMP]]
3010   %conv = fptosi float %x to i32
3011   %dec = sub nsw i32 %i, 1
3012   %cmp = icmp sgt i32 %conv, %dec
3013   ret i1 %cmp
3016 define i1 @cmp_sle_rhs_dec(float %x, i32 %i) {
3017 ; CHECK-LABEL: @cmp_sle_rhs_dec(
3018 ; CHECK-NEXT:    [[CONV:%.*]] = fptosi float [[X:%.*]] to i32
3019 ; CHECK-NEXT:    [[CMP:%.*]] = icmp slt i32 [[CONV]], [[I:%.*]]
3020 ; CHECK-NEXT:    ret i1 [[CMP]]
3022   %conv = fptosi float %x to i32
3023   %dec = sub nsw i32 %i, 1
3024   %cmp = icmp sle i32 %conv, %dec
3025   ret i1 %cmp
3028 define i1 @cmp_sge_rhs_inc(float %x, i32 %i) {
3029 ; CHECK-LABEL: @cmp_sge_rhs_inc(
3030 ; CHECK-NEXT:    [[CONV:%.*]] = fptosi float [[X:%.*]] to i32
3031 ; CHECK-NEXT:    [[CMP:%.*]] = icmp sgt i32 [[CONV]], [[I:%.*]]
3032 ; CHECK-NEXT:    ret i1 [[CMP]]
3034   %conv = fptosi float %x to i32
3035   %inc = add nsw i32 %i, 1
3036   %cmp = icmp sge i32 %conv, %inc
3037   ret i1 %cmp
3040 define i1 @cmp_slt_rhs_inc(float %x, i32 %i) {
3041 ; CHECK-LABEL: @cmp_slt_rhs_inc(
3042 ; CHECK-NEXT:    [[CONV:%.*]] = fptosi float [[X:%.*]] to i32
3043 ; CHECK-NEXT:    [[CMP:%.*]] = icmp sle i32 [[CONV]], [[I:%.*]]
3044 ; CHECK-NEXT:    ret i1 [[CMP]]
3046   %conv = fptosi float %x to i32
3047   %inc = add nsw i32 %i, 1
3048   %cmp = icmp slt i32 %conv, %inc
3049   ret i1 %cmp
3052 define i1 @PR26407(i32 %x, i32 %y) {
3053 ; CHECK-LABEL: @PR26407(
3054 ; CHECK-NEXT:    [[ADDX:%.*]] = add i32 [[X:%.*]], 2147483647
3055 ; CHECK-NEXT:    [[ADDY:%.*]] = add i32 [[Y:%.*]], 2147483647
3056 ; CHECK-NEXT:    [[CMP:%.*]] = icmp uge i32 [[ADDX]], [[ADDY]]
3057 ; CHECK-NEXT:    ret i1 [[CMP]]
3059   %addx = add i32 %x, 2147483647
3060   %addy = add i32 %y, 2147483647
3061   %cmp = icmp uge i32 %addx, %addy
3062   ret i1 %cmp
3065 define i1 @cmp_inverse_mask_bits_set_eq(i32 %x) {
3066 ; CHECK-LABEL: @cmp_inverse_mask_bits_set_eq(
3067 ; CHECK-NEXT:    [[TMP1:%.*]] = and i32 [[X:%.*]], -43
3068 ; CHECK-NEXT:    [[CMP:%.*]] = icmp eq i32 [[TMP1]], -43
3069 ; CHECK-NEXT:    ret i1 [[CMP]]
3071   %or = or i32 %x, 42
3072   %cmp = icmp eq i32 %or, -1
3073   ret i1 %cmp
3076 define <2 x i1> @cmp_inverse_mask_bits_set_eq_vec(<2 x i32> %x) {
3077 ; CHECK-LABEL: @cmp_inverse_mask_bits_set_eq_vec(
3078 ; CHECK-NEXT:    [[TMP1:%.*]] = and <2 x i32> [[X:%.*]], <i32 -43, i32 -43>
3079 ; CHECK-NEXT:    [[CMP:%.*]] = icmp eq <2 x i32> [[TMP1]], <i32 -43, i32 -43>
3080 ; CHECK-NEXT:    ret <2 x i1> [[CMP]]
3082   %or = or <2 x i32> %x, <i32 42, i32 42>
3083   %cmp = icmp eq <2 x i32> %or, <i32 -1, i32 -1>
3084   ret <2 x i1> %cmp
3087 define i1 @cmp_inverse_mask_bits_set_ne(i32 %x) {
3088 ; CHECK-LABEL: @cmp_inverse_mask_bits_set_ne(
3089 ; CHECK-NEXT:    [[TMP1:%.*]] = and i32 [[X:%.*]], -43
3090 ; CHECK-NEXT:    [[CMP:%.*]] = icmp ne i32 [[TMP1]], -43
3091 ; CHECK-NEXT:    ret i1 [[CMP]]
3093   %or = or i32 %x, 42
3094   %cmp = icmp ne i32 %or, -1
3095   ret i1 %cmp
3098 ; When canonicalizing to 'gt/lt', make sure the constant is correct.
3100 define i1 @PR27792(i128 %a) {
3101 ; CHECK-LABEL: @PR27792(
3102 ; CHECK-NEXT:    [[CMP:%.*]] = icmp sgt i128 [[A:%.*]], -1
3103 ; CHECK-NEXT:    ret i1 [[CMP]]
3105   %cmp = icmp sge i128 %a, 0
3106   ret i1 %cmp
3109 define i1 @PR27792_2(i128 %a) {
3110 ; CHECK-LABEL: @PR27792_2(
3111 ; CHECK-NEXT:    [[B:%.*]] = icmp ne i128 [[A:%.*]], 0
3112 ; CHECK-NEXT:    ret i1 [[B]]
3114   %b = icmp uge i128 %a, 1
3115   ret i1 %b
3118 define i1 @ugtMaxSignedVal(i8 %a) {
3119 ; CHECK-LABEL: @ugtMaxSignedVal(
3120 ; CHECK-NEXT:    [[CMP:%.*]] = icmp slt i8 [[A:%.*]], 0
3121 ; CHECK-NEXT:    ret i1 [[CMP]]
3123   %cmp = icmp ugt i8 %a, 127
3124   ret i1 %cmp
3127 define <2 x i1> @ugtMaxSignedValVec(<2 x i8> %a) {
3128 ; CHECK-LABEL: @ugtMaxSignedValVec(
3129 ; CHECK-NEXT:    [[CMP:%.*]] = icmp slt <2 x i8> [[A:%.*]], zeroinitializer
3130 ; CHECK-NEXT:    ret <2 x i1> [[CMP]]
3132   %cmp = icmp ugt <2 x i8> %a, <i8 127, i8 127>
3133   ret <2 x i1> %cmp
3136 define i1 @ugtKnownBits(i8 %a) {
3137 ; CHECK-LABEL: @ugtKnownBits(
3138 ; CHECK-NEXT:    [[B:%.*]] = and i8 [[A:%.*]], 17
3139 ; CHECK-NEXT:    [[CMP:%.*]] = icmp eq i8 [[B]], 17
3140 ; CHECK-NEXT:    ret i1 [[CMP]]
3142   %b = and i8 %a, 17
3143   %cmp = icmp ugt i8 %b, 16
3144   ret i1 %cmp
3147 define <2 x i1> @ugtKnownBitsVec(<2 x i8> %a) {
3148 ; CHECK-LABEL: @ugtKnownBitsVec(
3149 ; CHECK-NEXT:    [[B:%.*]] = and <2 x i8> [[A:%.*]], <i8 17, i8 17>
3150 ; CHECK-NEXT:    [[CMP:%.*]] = icmp eq <2 x i8> [[B]], <i8 17, i8 17>
3151 ; CHECK-NEXT:    ret <2 x i1> [[CMP]]
3153   %b = and <2 x i8> %a, <i8 17, i8 17>
3154   %cmp = icmp ugt <2 x i8> %b, <i8 16, i8 16>
3155   ret <2 x i1> %cmp
3158 define i1 @or_ptrtoint_mismatch(i8* %p, i32* %q) {
3159 ; CHECK-LABEL: @or_ptrtoint_mismatch(
3160 ; CHECK-NEXT:    [[TMP1:%.*]] = icmp eq i8* [[P:%.*]], null
3161 ; CHECK-NEXT:    [[TMP2:%.*]] = icmp eq i32* [[Q:%.*]], null
3162 ; CHECK-NEXT:    [[B:%.*]] = and i1 [[TMP1]], [[TMP2]]
3163 ; CHECK-NEXT:    ret i1 [[B]]
3166   %pp = ptrtoint i8* %p to i64
3167   %qq = ptrtoint i32* %q to i64
3168   %o = or i64 %pp, %qq
3169   %b = icmp eq i64 %o, 0
3170   ret i1 %b
3173 define i1 @icmp_add1_ugt(i32 %x, i32 %y) {
3174 ; CHECK-LABEL: @icmp_add1_ugt(
3175 ; CHECK-NEXT:    [[CMP:%.*]] = icmp uge i32 [[X:%.*]], [[Y:%.*]]
3176 ; CHECK-NEXT:    ret i1 [[CMP]]
3178   %add = add nuw i32 %x, 1
3179   %cmp = icmp ugt i32 %add, %y
3180   ret i1 %cmp
3183 define i1 @icmp_add1_ule(i32 %x, i32 %y) {
3184 ; CHECK-LABEL: @icmp_add1_ule(
3185 ; CHECK-NEXT:    [[CMP:%.*]] = icmp ult i32 [[X:%.*]], [[Y:%.*]]
3186 ; CHECK-NEXT:    ret i1 [[CMP]]
3188   %add = add nuw i32 %x, 1
3189   %cmp = icmp ule i32 %add, %y
3190   ret i1 %cmp
3193 define i1 @cmp_uge_rhs_inc(float %x, i32 %i) {
3194 ; CHECK-LABEL: @cmp_uge_rhs_inc(
3195 ; CHECK-NEXT:    [[CONV:%.*]] = fptosi float [[X:%.*]] to i32
3196 ; CHECK-NEXT:    [[CMP:%.*]] = icmp ugt i32 [[CONV]], [[I:%.*]]
3197 ; CHECK-NEXT:    ret i1 [[CMP]]
3199   %conv = fptosi float %x to i32
3200   %inc = add nuw i32 %i, 1
3201   %cmp = icmp uge i32 %conv, %inc
3202   ret i1 %cmp
3205 define i1 @cmp_ult_rhs_inc(float %x, i32 %i) {
3206 ; CHECK-LABEL: @cmp_ult_rhs_inc(
3207 ; CHECK-NEXT:    [[CONV:%.*]] = fptosi float [[X:%.*]] to i32
3208 ; CHECK-NEXT:    [[CMP:%.*]] = icmp ule i32 [[CONV]], [[I:%.*]]
3209 ; CHECK-NEXT:    ret i1 [[CMP]]
3211   %conv = fptosi float %x to i32
3212   %inc = add nuw i32 %i, 1
3213   %cmp = icmp ult i32 %conv, %inc
3214   ret i1 %cmp
3217 define i1 @cmp_sge_lhs_inc(i32 %x, i32 %y) {
3218 ; CHECK-LABEL: @cmp_sge_lhs_inc(
3219 ; CHECK-NEXT:    [[INC:%.*]] = add nsw i32 [[X:%.*]], 1
3220 ; CHECK-NEXT:    [[CMP:%.*]] = icmp sge i32 [[INC]], [[Y:%.*]]
3221 ; CHECK-NEXT:    ret i1 [[CMP]]
3223   %inc = add nsw i32 %x, 1
3224   %cmp = icmp sge i32 %inc, %y
3225   ret i1 %cmp
3228 define i1 @cmp_uge_lhs_inc(i32 %x, i32 %y) {
3229 ; CHECK-LABEL: @cmp_uge_lhs_inc(
3230 ; CHECK-NEXT:    [[INC:%.*]] = add nuw i32 [[X:%.*]], 1
3231 ; CHECK-NEXT:    [[CMP:%.*]] = icmp uge i32 [[INC]], [[Y:%.*]]
3232 ; CHECK-NEXT:    ret i1 [[CMP]]
3234   %inc = add nuw i32 %x, 1
3235   %cmp = icmp uge i32 %inc, %y
3236   ret i1 %cmp
3239 define i1 @cmp_sgt_lhs_dec(i32 %x, i32 %y) {
3240 ; CHECK-LABEL: @cmp_sgt_lhs_dec(
3241 ; CHECK-NEXT:    [[DEC:%.*]] = add nsw i32 [[X:%.*]], -1
3242 ; CHECK-NEXT:    [[CMP:%.*]] = icmp sgt i32 [[DEC]], [[Y:%.*]]
3243 ; CHECK-NEXT:    ret i1 [[CMP]]
3245   %dec = sub nsw i32 %x, 1
3246   %cmp = icmp sgt i32 %dec, %y
3247   ret i1 %cmp
3250 define i1 @cmp_ugt_lhs_dec(i32 %x, i32 %y) {
3251 ; CHECK-LABEL: @cmp_ugt_lhs_dec(
3252 ; CHECK-NEXT:    [[DEC:%.*]] = add i32 [[X:%.*]], -1
3253 ; CHECK-NEXT:    [[CMP:%.*]] = icmp ugt i32 [[DEC]], [[Y:%.*]]
3254 ; CHECK-NEXT:    ret i1 [[CMP]]
3256   %dec = sub nuw i32 %x, 1
3257   %cmp = icmp ugt i32 %dec, %y
3258   ret i1 %cmp
3261 define i1 @cmp_sle_rhs_inc(float %x, i32 %y) {
3262 ; CHECK-LABEL: @cmp_sle_rhs_inc(
3263 ; CHECK-NEXT:    [[CONV:%.*]] = fptosi float [[X:%.*]] to i32
3264 ; CHECK-NEXT:    [[INC:%.*]] = add nsw i32 [[Y:%.*]], 1
3265 ; CHECK-NEXT:    [[CMP:%.*]] = icmp sge i32 [[INC]], [[CONV]]
3266 ; CHECK-NEXT:    ret i1 [[CMP]]
3268   %conv = fptosi float %x to i32
3269   %inc = add nsw i32 %y, 1
3270   %cmp = icmp sle i32 %conv, %inc
3271   ret i1 %cmp
3274 define i1 @cmp_ule_rhs_inc(float %x, i32 %y) {
3275 ; CHECK-LABEL: @cmp_ule_rhs_inc(
3276 ; CHECK-NEXT:    [[CONV:%.*]] = fptosi float [[X:%.*]] to i32
3277 ; CHECK-NEXT:    [[INC:%.*]] = add nuw i32 [[Y:%.*]], 1
3278 ; CHECK-NEXT:    [[CMP:%.*]] = icmp uge i32 [[INC]], [[CONV]]
3279 ; CHECK-NEXT:    ret i1 [[CMP]]
3281   %conv = fptosi float %x to i32
3282   %inc = add nuw i32 %y, 1
3283   %cmp = icmp ule i32 %conv, %inc
3284   ret i1 %cmp
3287 define i1 @cmp_slt_rhs_dec(float %x, i32 %y) {
3288 ; CHECK-LABEL: @cmp_slt_rhs_dec(
3289 ; CHECK-NEXT:    [[CONV:%.*]] = fptosi float [[X:%.*]] to i32
3290 ; CHECK-NEXT:    [[DEC:%.*]] = add nsw i32 [[Y:%.*]], -1
3291 ; CHECK-NEXT:    [[CMP:%.*]] = icmp sgt i32 [[DEC]], [[CONV]]
3292 ; CHECK-NEXT:    ret i1 [[CMP]]
3294   %conv = fptosi float %x to i32
3295   %dec = sub nsw i32 %y, 1
3296   %cmp = icmp slt i32 %conv, %dec
3297   ret i1 %cmp
3300 define i1 @cmp_ult_rhs_dec(float %x, i32 %y) {
3301 ; CHECK-LABEL: @cmp_ult_rhs_dec(
3302 ; CHECK-NEXT:    [[CONV:%.*]] = fptosi float [[X:%.*]] to i32
3303 ; CHECK-NEXT:    [[DEC:%.*]] = add i32 [[Y:%.*]], -1
3304 ; CHECK-NEXT:    [[CMP:%.*]] = icmp ugt i32 [[DEC]], [[CONV]]
3305 ; CHECK-NEXT:    ret i1 [[CMP]]
3307   %conv = fptosi float %x to i32
3308   %dec = sub nuw i32 %y, 1
3309   %cmp = icmp ult i32 %conv, %dec
3310   ret i1 %cmp
3313 define i1 @eq_add_constants(i32 %x, i32 %y) {
3314 ; CHECK-LABEL: @eq_add_constants(
3315 ; CHECK-NEXT:    [[C:%.*]] = icmp eq i32 [[X:%.*]], [[Y:%.*]]
3316 ; CHECK-NEXT:    ret i1 [[C]]
3318   %A = add i32 %x, 5
3319   %B = add i32 %y, 5
3320   %C = icmp eq i32 %A, %B
3321   ret i1 %C
3324 declare i32 @llvm.bswap.i32(i32)
3326 define i1 @bswap_ne(i32 %x, i32 %y) {
3327 ; CHECK-LABEL: @bswap_ne(
3328 ; CHECK-NEXT:    [[CMP:%.*]] = icmp ne i32 [[X:%.*]], [[Y:%.*]]
3329 ; CHECK-NEXT:    ret i1 [[CMP]]
3331   %swapx = call i32 @llvm.bswap.i32(i32 %x)
3332   %swapy = call i32 @llvm.bswap.i32(i32 %y)
3333   %cmp = icmp ne i32 %swapx, %swapy
3334   ret i1 %cmp
3337 declare <8 x i16> @llvm.bswap.v8i16(<8 x i16>)
3339 define <8 x i1> @bswap_vec_eq(<8 x i16> %x, <8 x i16> %y) {
3340 ; CHECK-LABEL: @bswap_vec_eq(
3341 ; CHECK-NEXT:    [[CMP:%.*]] = icmp eq <8 x i16> [[X:%.*]], [[Y:%.*]]
3342 ; CHECK-NEXT:    ret <8 x i1> [[CMP]]
3344   %swapx = call <8 x i16> @llvm.bswap.v8i16(<8 x i16> %x)
3345   %swapy = call <8 x i16> @llvm.bswap.v8i16(<8 x i16> %y)
3346   %cmp = icmp eq <8 x i16> %swapx, %swapy
3347   ret <8 x i1> %cmp
3350 declare i64 @llvm.bitreverse.i64(i64)
3352 define i1 @bitreverse_eq(i64 %x, i64 %y) {
3353 ; CHECK-LABEL: @bitreverse_eq(
3354 ; CHECK-NEXT:    [[CMP:%.*]] = icmp eq i64 [[X:%.*]], [[Y:%.*]]
3355 ; CHECK-NEXT:    ret i1 [[CMP]]
3357   %revx = call i64 @llvm.bitreverse.i64(i64 %x)
3358   %revy = call i64 @llvm.bitreverse.i64(i64 %y)
3359   %cmp = icmp eq i64 %revx, %revy
3360   ret i1 %cmp
3363 declare <8 x i16> @llvm.bitreverse.v8i16(<8 x i16>)
3365 define <8 x i1> @bitreverse_vec_ne(<8 x i16> %x, <8 x i16> %y) {
3366 ; CHECK-LABEL: @bitreverse_vec_ne(
3367 ; CHECK-NEXT:    [[CMP:%.*]] = icmp ne <8 x i16> [[X:%.*]], [[Y:%.*]]
3368 ; CHECK-NEXT:    ret <8 x i1> [[CMP]]
3370   %revx = call <8 x i16> @llvm.bitreverse.v8i16(<8 x i16> %x)
3371   %revy = call <8 x i16> @llvm.bitreverse.v8i16(<8 x i16> %y)
3372   %cmp = icmp ne <8 x i16> %revx, %revy
3373   ret <8 x i1> %cmp
3376 ; These perform a comparison of a value known to be between 4 and 5 with a value between 5 and 7.
3377 ; They should all simplify to equality compares.
3378 define i1 @knownbits1(i8 %a, i8 %b) {
3379 ; CHECK-LABEL: @knownbits1(
3380 ; CHECK-NEXT:    [[A1:%.*]] = and i8 [[A:%.*]], 1
3381 ; CHECK-NEXT:    [[A2:%.*]] = or i8 [[A1]], 4
3382 ; CHECK-NEXT:    [[B1:%.*]] = and i8 [[B:%.*]], 2
3383 ; CHECK-NEXT:    [[B2:%.*]] = or i8 [[B1]], 5
3384 ; CHECK-NEXT:    [[C:%.*]] = icmp eq i8 [[A2]], [[B2]]
3385 ; CHECK-NEXT:    ret i1 [[C]]
3387   %a1 = and i8 %a, 5
3388   %a2 = or i8 %a1, 4
3389   %b1 = and i8 %b, 7
3390   %b2 = or i8 %b1, 5
3391   %c = icmp uge i8 %a2, %b2
3392   ret i1 %c
3395 define i1 @knownbits2(i8 %a, i8 %b) {
3396 ; CHECK-LABEL: @knownbits2(
3397 ; CHECK-NEXT:    [[A1:%.*]] = and i8 [[A:%.*]], 1
3398 ; CHECK-NEXT:    [[A2:%.*]] = or i8 [[A1]], 4
3399 ; CHECK-NEXT:    [[B1:%.*]] = and i8 [[B:%.*]], 2
3400 ; CHECK-NEXT:    [[B2:%.*]] = or i8 [[B1]], 5
3401 ; CHECK-NEXT:    [[C:%.*]] = icmp ne i8 [[A2]], [[B2]]
3402 ; CHECK-NEXT:    ret i1 [[C]]
3404   %a1 = and i8 %a, 5
3405   %a2 = or i8 %a1, 4
3406   %b1 = and i8 %b, 7
3407   %b2 = or i8 %b1, 5
3408   %c = icmp ult i8 %a2, %b2
3409   ret i1 %c
3412 define i1 @knownbits3(i8 %a, i8 %b) {
3413 ; CHECK-LABEL: @knownbits3(
3414 ; CHECK-NEXT:    [[A1:%.*]] = and i8 [[A:%.*]], 1
3415 ; CHECK-NEXT:    [[A2:%.*]] = or i8 [[A1]], 4
3416 ; CHECK-NEXT:    [[B1:%.*]] = and i8 [[B:%.*]], 2
3417 ; CHECK-NEXT:    [[B2:%.*]] = or i8 [[B1]], 5
3418 ; CHECK-NEXT:    [[C:%.*]] = icmp eq i8 [[B2]], [[A2]]
3419 ; CHECK-NEXT:    ret i1 [[C]]
3421   %a1 = and i8 %a, 5
3422   %a2 = or i8 %a1, 4
3423   %b1 = and i8 %b, 7
3424   %b2 = or i8 %b1, 5
3425   %c = icmp ule i8 %b2, %a2
3426   ret i1 %c
3429 define <2 x i1> @knownbits4(<2 x i8> %a, <2 x i8> %b) {
3430 ; CHECK-LABEL: @knownbits4(
3431 ; CHECK-NEXT:    [[A1:%.*]] = and <2 x i8> [[A:%.*]], <i8 1, i8 1>
3432 ; CHECK-NEXT:    [[A2:%.*]] = or <2 x i8> [[A1]], <i8 4, i8 4>
3433 ; CHECK-NEXT:    [[B1:%.*]] = and <2 x i8> [[B:%.*]], <i8 2, i8 2>
3434 ; CHECK-NEXT:    [[B2:%.*]] = or <2 x i8> [[B1]], <i8 5, i8 5>
3435 ; CHECK-NEXT:    [[C:%.*]] = icmp ne <2 x i8> [[B2]], [[A2]]
3436 ; CHECK-NEXT:    ret <2 x i1> [[C]]
3438   %a1 = and <2 x i8> %a, <i8 5, i8 5>
3439   %a2 = or <2 x i8> %a1, <i8 4, i8 4>
3440   %b1 = and <2 x i8> %b, <i8 7, i8 7>
3441   %b2 = or <2 x i8> %b1, <i8 5, i8 5>
3442   %c = icmp ugt <2 x i8> %b2, %a2
3443   ret <2 x i1> %c
3446 ; These are the signed versions of the above. One value is less than or equal to 5, but maybe negative.
3447 ; The other is known to be a value 5-7. These should simplify to equality comparisons.
3448 define i1 @knownbits5(i8 %a, i8 %b) {
3449 ; CHECK-LABEL: @knownbits5(
3450 ; CHECK-NEXT:    [[A1:%.*]] = and i8 [[A:%.*]], -127
3451 ; CHECK-NEXT:    [[A2:%.*]] = or i8 [[A1]], 4
3452 ; CHECK-NEXT:    [[B1:%.*]] = and i8 [[B:%.*]], 2
3453 ; CHECK-NEXT:    [[B2:%.*]] = or i8 [[B1]], 5
3454 ; CHECK-NEXT:    [[C:%.*]] = icmp eq i8 [[A2]], [[B2]]
3455 ; CHECK-NEXT:    ret i1 [[C]]
3457   %a1 = and i8 %a, 133
3458   %a2 = or i8 %a1, 4
3459   %b1 = and i8 %b, 7
3460   %b2 = or i8 %b1, 5
3461   %c = icmp sge i8 %a2, %b2
3462   ret i1 %c
3465 define i1 @knownbits6(i8 %a, i8 %b) {
3466 ; CHECK-LABEL: @knownbits6(
3467 ; CHECK-NEXT:    [[A1:%.*]] = and i8 [[A:%.*]], -127
3468 ; CHECK-NEXT:    [[A2:%.*]] = or i8 [[A1]], 4
3469 ; CHECK-NEXT:    [[B1:%.*]] = and i8 [[B:%.*]], 2
3470 ; CHECK-NEXT:    [[B2:%.*]] = or i8 [[B1]], 5
3471 ; CHECK-NEXT:    [[C:%.*]] = icmp ne i8 [[A2]], [[B2]]
3472 ; CHECK-NEXT:    ret i1 [[C]]
3474   %a1 = and i8 %a, 133
3475   %a2 = or i8 %a1, 4
3476   %b1 = and i8 %b, 7
3477   %b2 = or i8 %b1, 5
3478   %c = icmp slt i8 %a2, %b2
3479   ret i1 %c
3482 define <2 x i1> @knownbits7(<2 x i8> %a, <2 x i8> %b) {
3483 ; CHECK-LABEL: @knownbits7(
3484 ; CHECK-NEXT:    [[A1:%.*]] = and <2 x i8> [[A:%.*]], <i8 -127, i8 -127>
3485 ; CHECK-NEXT:    [[A2:%.*]] = or <2 x i8> [[A1]], <i8 4, i8 4>
3486 ; CHECK-NEXT:    [[B1:%.*]] = and <2 x i8> [[B:%.*]], <i8 2, i8 2>
3487 ; CHECK-NEXT:    [[B2:%.*]] = or <2 x i8> [[B1]], <i8 5, i8 5>
3488 ; CHECK-NEXT:    [[C:%.*]] = icmp eq <2 x i8> [[B2]], [[A2]]
3489 ; CHECK-NEXT:    ret <2 x i1> [[C]]
3491   %a1 = and <2 x i8> %a, <i8 133, i8 133>
3492   %a2 = or <2 x i8> %a1, <i8 4, i8 4>
3493   %b1 = and <2 x i8> %b, <i8 7, i8 7>
3494   %b2 = or <2 x i8> %b1, <i8 5, i8 5>
3495   %c = icmp sle <2 x i8> %b2, %a2
3496   ret <2 x i1> %c
3499 define i1 @knownbits8(i8 %a, i8 %b) {
3500 ; CHECK-LABEL: @knownbits8(
3501 ; CHECK-NEXT:    [[A1:%.*]] = and i8 [[A:%.*]], -127
3502 ; CHECK-NEXT:    [[A2:%.*]] = or i8 [[A1]], 4
3503 ; CHECK-NEXT:    [[B1:%.*]] = and i8 [[B:%.*]], 2
3504 ; CHECK-NEXT:    [[B2:%.*]] = or i8 [[B1]], 5
3505 ; CHECK-NEXT:    [[C:%.*]] = icmp ne i8 [[B2]], [[A2]]
3506 ; CHECK-NEXT:    ret i1 [[C]]
3508   %a1 = and i8 %a, 133
3509   %a2 = or i8 %a1, 4
3510   %b1 = and i8 %b, 7
3511   %b2 = or i8 %b1, 5
3512   %c = icmp sgt i8 %b2, %a2
3513   ret i1 %c
3516 ; Make sure InstCombine doesn't try too hard to simplify the icmp and break the abs idiom
3517 define i32 @abs_preserve(i32 %x) {
3518 ; CHECK-LABEL: @abs_preserve(
3519 ; CHECK-NEXT:    [[A:%.*]] = shl nsw i32 [[X:%.*]], 1
3520 ; CHECK-NEXT:    [[TMP1:%.*]] = call i32 @llvm.abs.i32(i32 [[A]], i1 false)
3521 ; CHECK-NEXT:    ret i32 [[TMP1]]
3523   %a = mul nsw i32 %x, 2
3524   %c = icmp sge i32 %a, 0
3525   %nega = sub i32 0, %a
3526   %abs = select i1 %c, i32 %a, i32 %nega
3527   ret i32 %abs
3530 ; Don't crash by assuming the compared values are integers.
3532 declare void @llvm.assume(i1)
3533 define i1 @PR35794(i32* %a) {
3534 ; CHECK-LABEL: @PR35794(
3535 ; CHECK-NEXT:    [[MASKCOND:%.*]] = icmp eq i32* [[A:%.*]], null
3536 ; CHECK-NEXT:    tail call void @llvm.assume(i1 [[MASKCOND]])
3537 ; CHECK-NEXT:    ret i1 true
3539   %cmp = icmp sgt i32* %a, inttoptr (i64 -1 to i32*)
3540   %maskcond = icmp eq i32* %a, null
3541   tail call void @llvm.assume(i1 %maskcond)
3542   ret i1 %cmp
3545 ; Don't crash by assuming the compared values are integers.
3546 define <2 x i1> @PR36583(<2 x i8*>)  {
3547 ; CHECK-LABEL: @PR36583(
3548 ; CHECK-NEXT:    [[RES:%.*]] = icmp eq <2 x i8*> [[TMP0:%.*]], zeroinitializer
3549 ; CHECK-NEXT:    ret <2 x i1> [[RES]]
3551   %cast = ptrtoint <2 x i8*> %0 to <2 x i64>
3552   %res = icmp eq <2 x i64> %cast, zeroinitializer
3553   ret <2 x i1> %res
3556 ; fold (icmp pred (sub (0, X)) C1) for vec type
3557 define <2 x i32> @Op1Negated_Vec(<2 x i32> %x) {
3558 ; CHECK-LABEL: @Op1Negated_Vec(
3559 ; CHECK-NEXT:    [[TMP1:%.*]] = call <2 x i32> @llvm.abs.v2i32(<2 x i32> [[X:%.*]], i1 true)
3560 ; CHECK-NEXT:    ret <2 x i32> [[TMP1]]
3562   %sub = sub nsw <2 x i32> zeroinitializer, %x
3563   %cmp = icmp sgt <2 x i32> %sub, <i32 -1, i32 -1>
3564   %cond = select <2 x i1> %cmp, <2 x i32> %sub, <2 x i32> %x
3565   ret <2 x i32> %cond
3568 define i1 @signbit_bitcast_fpext(float %x) {
3569 ; CHECK-LABEL: @signbit_bitcast_fpext(
3570 ; CHECK-NEXT:    [[TMP1:%.*]] = bitcast float [[X:%.*]] to i32
3571 ; CHECK-NEXT:    [[R:%.*]] = icmp slt i32 [[TMP1]], 0
3572 ; CHECK-NEXT:    ret i1 [[R]]
3574   %f = fpext float %x to double
3575   %b = bitcast double %f to i64
3576   %r = icmp slt i64 %b, 0
3577   ret i1 %r
3580 define <2 x i1> @signbit_bitcast_fpext_vec(<2 x half> %x) {
3581 ; CHECK-LABEL: @signbit_bitcast_fpext_vec(
3582 ; CHECK-NEXT:    [[TMP1:%.*]] = bitcast <2 x half> [[X:%.*]] to <2 x i16>
3583 ; CHECK-NEXT:    [[R:%.*]] = icmp slt <2 x i16> [[TMP1]], zeroinitializer
3584 ; CHECK-NEXT:    ret <2 x i1> [[R]]
3586   %f = fpext <2 x half> %x to <2 x float>
3587   %b = bitcast <2 x float> %f to <2 x i32>
3588   %r = icmp ugt <2 x i32> %b, <i32 2147483647, i32 2147483647>
3589   ret <2 x i1> %r
3592 define i1 @signbit_bitcast_fptrunc(float %x) {
3593 ; CHECK-LABEL: @signbit_bitcast_fptrunc(
3594 ; CHECK-NEXT:    [[TMP1:%.*]] = bitcast float [[X:%.*]] to i32
3595 ; CHECK-NEXT:    [[R:%.*]] = icmp sgt i32 [[TMP1]], -1
3596 ; CHECK-NEXT:    ret i1 [[R]]
3598   %f = fptrunc float %x to half
3599   %b = bitcast half %f to i16
3600   %r = icmp ult i16 %b, 32768
3601   ret i1 %r
3604 define <2 x i1> @signbit_bitcast_fptrunc_vec(<2 x double> %x) {
3605 ; CHECK-LABEL: @signbit_bitcast_fptrunc_vec(
3606 ; CHECK-NEXT:    [[TMP1:%.*]] = bitcast <2 x double> [[X:%.*]] to <2 x i64>
3607 ; CHECK-NEXT:    [[R:%.*]] = icmp sgt <2 x i64> [[TMP1]], <i64 -1, i64 -1>
3608 ; CHECK-NEXT:    ret <2 x i1> [[R]]
3610   %f = fptrunc <2 x double> %x to <2 x half>
3611   %b = bitcast <2 x half> %f to <2 x i16>
3612   %r = icmp sge <2 x i16> %b, zeroinitializer
3613   ret <2 x i1> %r
3616 define i1 @signbit_bitcast_fpext_wrong_cmp(float %x) {
3617 ; CHECK-LABEL: @signbit_bitcast_fpext_wrong_cmp(
3618 ; CHECK-NEXT:    [[F:%.*]] = fpext float [[X:%.*]] to double
3619 ; CHECK-NEXT:    [[B:%.*]] = bitcast double [[F]] to i64
3620 ; CHECK-NEXT:    [[R:%.*]] = icmp slt i64 [[B]], 1
3621 ; CHECK-NEXT:    ret i1 [[R]]
3623   %f = fpext float %x to double
3624   %b = bitcast double %f to i64
3625   %r = icmp slt i64 %b, 1
3626   ret i1 %r
3629 define <4 x i1> @signbit_bitcast_fpext_vec_wrong_bitcast(<2 x half> %x) {
3630 ; CHECK-LABEL: @signbit_bitcast_fpext_vec_wrong_bitcast(
3631 ; CHECK-NEXT:    [[F:%.*]] = fpext <2 x half> [[X:%.*]] to <2 x float>
3632 ; CHECK-NEXT:    [[B:%.*]] = bitcast <2 x float> [[F]] to <4 x i16>
3633 ; CHECK-NEXT:    [[R:%.*]] = icmp sgt <4 x i16> [[B]], <i16 -1, i16 -1, i16 -1, i16 -1>
3634 ; CHECK-NEXT:    ret <4 x i1> [[R]]
3636   %f = fpext <2 x half> %x to <2 x float>
3637   %b = bitcast <2 x float> %f to <4 x i16>
3638   %r = icmp sgt <4 x i16> %b, <i16 -1, i16 -1, i16 -1, i16 -1>
3639   ret <4 x i1> %r
3642 declare void @use_i64(i64)
3644 define i1 @signbit_bitcast_fpext_extra_use(float %x, i64* %p) {
3645 ; CHECK-LABEL: @signbit_bitcast_fpext_extra_use(
3646 ; CHECK-NEXT:    [[F:%.*]] = fpext float [[X:%.*]] to double
3647 ; CHECK-NEXT:    [[B:%.*]] = bitcast double [[F]] to i64
3648 ; CHECK-NEXT:    call void @use_i64(i64 [[B]])
3649 ; CHECK-NEXT:    [[R:%.*]] = icmp slt i64 [[B]], 0
3650 ; CHECK-NEXT:    ret i1 [[R]]
3652   %f = fpext float %x to double
3653   %b = bitcast double %f to i64
3654   call void @use_i64(i64 %b)
3655   %r = icmp slt i64 %b, 0
3656   ret i1 %r
3659 define i1 @signbit_bitcast_fpext_ppc_fp128(float %x) {
3660 ; CHECK-LABEL: @signbit_bitcast_fpext_ppc_fp128(
3661 ; CHECK-NEXT:    [[S2:%.*]] = fpext float [[X:%.*]] to ppc_fp128
3662 ; CHECK-NEXT:    [[S3:%.*]] = bitcast ppc_fp128 [[S2]] to i128
3663 ; CHECK-NEXT:    [[S4:%.*]] = icmp slt i128 [[S3]], 0
3664 ; CHECK-NEXT:    ret i1 [[S4]]
3666   %s2 = fpext float %x to ppc_fp128
3667   %s3 = bitcast ppc_fp128 %s2 to i128
3668   %s4 = icmp slt i128 %s3, 0
3669   ret i1 %s4
3672 define i1 @signbit_bitcast_fptrunc_ppc_fp128(ppc_fp128 %x) {
3673 ; CHECK-LABEL: @signbit_bitcast_fptrunc_ppc_fp128(
3674 ; CHECK-NEXT:    [[S2:%.*]] = fptrunc ppc_fp128 [[X:%.*]] to float
3675 ; CHECK-NEXT:    [[S3:%.*]] = bitcast float [[S2]] to i32
3676 ; CHECK-NEXT:    [[S4:%.*]] = icmp slt i32 [[S3]], 0
3677 ; CHECK-NEXT:    ret i1 [[S4]]
3679   %s2 = fptrunc ppc_fp128 %x to float
3680   %s3 = bitcast float %s2 to i32
3681   %s4 = icmp slt i32 %s3, 0
3682   ret i1 %s4
3685 @x = external dso_local local_unnamed_addr global i32, align 4
3686 @y = external dso_local local_unnamed_addr global i32, align 4
3687 define i1 @pr47997(i32 %arg) {
3688 ; CHECK-LABEL: @pr47997(
3689 ; CHECK-NEXT:  bb:
3690 ; CHECK-NEXT:    [[I:%.*]] = add nsw i32 [[ARG:%.*]], -1
3691 ; CHECK-NEXT:    store i32 [[I]], i32* @x, align 4
3692 ; CHECK-NEXT:    [[I1:%.*]] = sub nsw i32 1, [[ARG]]
3693 ; CHECK-NEXT:    store i32 [[I1]], i32* @y, align 4
3694 ; CHECK-NEXT:    ret i1 true
3697   %i = add nsw i32 %arg, -1
3698   store i32 %i, i32* @x
3699   %i1 = sub nsw i32 1, %arg
3700   store i32 %i1, i32* @y
3701   %i2 = sub nsw i32 0, %i1
3702   %i3 = icmp eq i32 %i, %i2
3703   ret i1 %i3
3706 ; PR50944
3708 define i1 @thread_cmp_over_select_with_poison_trueval(i1 %b) {
3709 ; CHECK-LABEL: @thread_cmp_over_select_with_poison_trueval(
3710 ; CHECK-NEXT:    ret i1 false
3712   %s = select i1 %b, i32 poison, i32 0
3713   %tobool = icmp ne i32 %s, 0
3714   ret i1 %tobool
3717 define i1 @thread_cmp_over_select_with_poison_falseval(i1 %b) {
3718 ; CHECK-LABEL: @thread_cmp_over_select_with_poison_falseval(
3719 ; CHECK-NEXT:    ret i1 true
3721   %s = select i1 %b, i32 1, i32 poison
3722   %tobool = icmp ne i32 %s, 0
3723   ret i1 %tobool
3726 define i1 @signbit_true_logic(i8 %x) {
3727 ; CHECK-LABEL: @signbit_true_logic(
3728 ; CHECK-NEXT:    [[R:%.*]] = icmp eq i8 [[X:%.*]], 0
3729 ; CHECK-NEXT:    ret i1 [[R]]
3731   %dec = add i8 %x, -1
3732   %not = xor i8 %x, -1
3733   %and = and i8 %dec, %not
3734   %r = icmp slt i8 %and, 0
3735   ret i1 %r
3738 define <2 x i1> @signbit_false_logic(<2 x i5> %x) {
3739 ; CHECK-LABEL: @signbit_false_logic(
3740 ; CHECK-NEXT:    [[R:%.*]] = icmp ne <2 x i5> [[X:%.*]], zeroinitializer
3741 ; CHECK-NEXT:    ret <2 x i1> [[R]]
3743   %dec = add <2 x i5> %x,  <i5 -1, i5 undef>
3744   %not = xor <2 x i5> %x,  <i5 -1, i5 -1>
3745   %and = and <2 x i5> %dec, %not
3746   %r = icmp sgt <2 x i5> %and, <i5 -1, i5 -1>
3747   ret <2 x i1> %r
3750 ; Confirm that complexity canonicalization works for commuted pattern.
3752 define i1 @signbit_true_logic_uses_commute(i64 %x) {
3753 ; CHECK-LABEL: @signbit_true_logic_uses_commute(
3754 ; CHECK-NEXT:    [[DEC:%.*]] = add i64 [[X:%.*]], -1
3755 ; CHECK-NEXT:    call void @use_i64(i64 [[DEC]])
3756 ; CHECK-NEXT:    [[NOT:%.*]] = xor i64 [[X]], -1
3757 ; CHECK-NEXT:    call void @use_i64(i64 [[NOT]])
3758 ; CHECK-NEXT:    [[AND:%.*]] = and i64 [[DEC]], [[NOT]]
3759 ; CHECK-NEXT:    call void @use_i64(i64 [[AND]])
3760 ; CHECK-NEXT:    [[R:%.*]] = icmp eq i64 [[X]], 0
3761 ; CHECK-NEXT:    ret i1 [[R]]
3763   %dec = add i64 %x, -1
3764   call void @use_i64(i64 %dec)
3765   %not = xor i64 %x, -1
3766   call void @use_i64(i64 %not)
3767   %and = and i64 %not, %dec
3768   call void @use_i64(i64 %and)
3769   %r = icmp slt i64 %and, 0
3770   ret i1 %r