[DAGCombiner] Add target hook function to decide folding (mul (add x, c1), c2)
[llvm-project.git] / llvm / test / Transforms / InstCombine / icmp.ll
blob3d254ef1da16d80ee0c17df4e4cd496e0c5bbb22
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:    [[A_LOBIT_NEG:%.*]] = ashr i32 [[A:%.*]], 31
104 ; CHECK-NEXT:    [[F:%.*]] = and i32 [[A_LOBIT_NEG]], [[B:%.*]]
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 @X = global [1000 x i32] zeroinitializer
502 ; PR8882
503 define i1 @test24(i64 %i) {
504 ; CHECK-LABEL: @test24(
505 ; CHECK-NEXT:    [[CMP:%.*]] = icmp eq i64 [[I:%.*]], 1000
506 ; CHECK-NEXT:    ret i1 [[CMP]]
508   %p1 = getelementptr inbounds i32, i32* getelementptr inbounds ([1000 x i32], [1000 x i32]* @X, i64 0, i64 0), i64 %i
509   %cmp = icmp eq i32* %p1, getelementptr inbounds ([1000 x i32], [1000 x i32]* @X, i64 1, i64 0)
510   ret i1 %cmp
513 ; Note: offs can be negative, LLVM used to make an incorrect assumption that
514 ; unsigned overflow does not happen during offset computation
515 define i1 @test24_neg_offs(i32* %p, i64 %offs) {
516 ; CHECK-LABEL: @test24_neg_offs(
517 ; CHECK-NEXT:    [[P1_IDX_NEG:%.*]] = mul i64 [[OFFS:%.*]], -4
518 ; CHECK-NEXT:    [[CMP:%.*]] = icmp eq i64 [[P1_IDX_NEG]], 8
519 ; CHECK-NEXT:    ret i1 [[CMP]]
521   %p1 = getelementptr inbounds i32, i32* %p, i64 %offs
522   %conv1 = ptrtoint i32* %p to i64
523   %conv2 = ptrtoint i32* %p1 to i64
524   %delta = sub i64 %conv1, %conv2
525   %cmp = icmp eq i64 %delta, 8
526   ret i1 %cmp
529 @X_as1 = addrspace(1) global [1000 x i32] zeroinitializer
531 define i1 @test24_as1(i64 %i) {
532 ; CHECK-LABEL: @test24_as1(
533 ; CHECK-NEXT:    [[TMP1:%.*]] = trunc i64 [[I:%.*]] to i16
534 ; CHECK-NEXT:    [[CMP:%.*]] = icmp eq i16 [[TMP1]], 1000
535 ; CHECK-NEXT:    ret i1 [[CMP]]
537   %p1 = getelementptr inbounds i32, i32 addrspace(1)* getelementptr inbounds ([1000 x i32], [1000 x i32] addrspace(1)* @X_as1, i64 0, i64 0), i64 %i
538   %cmp = icmp eq i32 addrspace(1)* %p1, getelementptr inbounds ([1000 x i32], [1000 x i32] addrspace(1)* @X_as1, i64 1, i64 0)
539   ret i1 %cmp
542 ; X - Z > Y - Z -> X > Y if there is no overflow.
543 define i1 @test27(i32 %x, i32 %y, i32 %z) {
544 ; CHECK-LABEL: @test27(
545 ; CHECK-NEXT:    [[C:%.*]] = icmp sgt i32 [[X:%.*]], [[Y:%.*]]
546 ; CHECK-NEXT:    ret i1 [[C]]
548   %lhs = sub nsw i32 %x, %z
549   %rhs = sub nsw i32 %y, %z
550   %c = icmp sgt i32 %lhs, %rhs
551   ret i1 %c
554 define i1 @test27_extra_uses(i32 %x, i32 %y, i32 %z) {
555 ; CHECK-LABEL: @test27_extra_uses(
556 ; CHECK-NEXT:    [[LHS:%.*]] = sub nsw i32 [[X:%.*]], [[Z:%.*]]
557 ; CHECK-NEXT:    call void @foo(i32 [[LHS]])
558 ; CHECK-NEXT:    [[RHS:%.*]] = sub nsw i32 [[Y:%.*]], [[Z]]
559 ; CHECK-NEXT:    call void @foo(i32 [[RHS]])
560 ; CHECK-NEXT:    [[C:%.*]] = icmp sgt i32 [[X]], [[Y]]
561 ; CHECK-NEXT:    ret i1 [[C]]
563   %lhs = sub nsw i32 %x, %z
564   call void @foo(i32 %lhs)
565   %rhs = sub nsw i32 %y, %z
566   call void @foo(i32 %rhs)
567   %c = icmp sgt i32 %lhs, %rhs
568   ret i1 %c
571 ; X - Z > Y - Z -> X > Y if there is no overflow.
572 define i1 @test28(i32 %x, i32 %y, i32 %z) {
573 ; CHECK-LABEL: @test28(
574 ; CHECK-NEXT:    [[C:%.*]] = icmp ugt i32 [[X:%.*]], [[Y:%.*]]
575 ; CHECK-NEXT:    ret i1 [[C]]
577   %lhs = sub nuw i32 %x, %z
578   %rhs = sub nuw i32 %y, %z
579   %c = icmp ugt i32 %lhs, %rhs
580   ret i1 %c
583 define i1 @test28_extra_uses(i32 %x, i32 %y, i32 %z) {
584 ; CHECK-LABEL: @test28_extra_uses(
585 ; CHECK-NEXT:    [[LHS:%.*]] = sub nuw i32 [[X:%.*]], [[Z:%.*]]
586 ; CHECK-NEXT:    call void @foo(i32 [[LHS]])
587 ; CHECK-NEXT:    [[RHS:%.*]] = sub nuw i32 [[Y:%.*]], [[Z]]
588 ; CHECK-NEXT:    call void @foo(i32 [[RHS]])
589 ; CHECK-NEXT:    [[C:%.*]] = icmp ugt i32 [[X]], [[Y]]
590 ; CHECK-NEXT:    ret i1 [[C]]
592   %lhs = sub nuw i32 %x, %z
593   call void @foo(i32 %lhs)
594   %rhs = sub nuw i32 %y, %z
595   call void @foo(i32 %rhs)
596   %c = icmp ugt i32 %lhs, %rhs
597   ret i1 %c
600 ; PR36969 - https://bugs.llvm.org/show_bug.cgi?id=36969
602 define i1 @ugt_sub(i32 %xsrc, i32 %y) {
603 ; CHECK-LABEL: @ugt_sub(
604 ; CHECK-NEXT:    [[X:%.*]] = udiv i32 [[XSRC:%.*]], 42
605 ; CHECK-NEXT:    [[CMP:%.*]] = icmp ult i32 [[X]], [[Y:%.*]]
606 ; CHECK-NEXT:    ret i1 [[CMP]]
608   %x = udiv i32 %xsrc, 42 ; thwart complexity-based canonicalization
609   %sub = sub i32 %x, %y
610   %cmp = icmp ugt i32 %sub, %x
611   ret i1 %cmp
614 ; Swap operands and predicate. Try a vector type to verify that works too.
616 define <2 x i1> @ult_sub(<2 x i8> %xsrc, <2 x i8> %y) {
617 ; CHECK-LABEL: @ult_sub(
618 ; CHECK-NEXT:    [[X:%.*]] = udiv <2 x i8> [[XSRC:%.*]], <i8 42, i8 -42>
619 ; CHECK-NEXT:    [[CMP:%.*]] = icmp ult <2 x i8> [[X]], [[Y:%.*]]
620 ; CHECK-NEXT:    ret <2 x i1> [[CMP]]
622   %x = udiv <2 x i8> %xsrc, <i8 42, i8 -42> ; thwart complexity-based canonicalization
623   %sub = sub <2 x i8> %x, %y
624   %cmp = icmp ult <2 x i8> %x, %sub
625   ret <2 x i1> %cmp
628 ; X - Y > X -> 0 > Y if there is no overflow.
629 define i1 @test33(i32 %x, i32 %y) {
630 ; CHECK-LABEL: @test33(
631 ; CHECK-NEXT:    [[C:%.*]] = icmp slt i32 [[Y:%.*]], 0
632 ; CHECK-NEXT:    ret i1 [[C]]
634   %lhs = sub nsw i32 %x, %y
635   %c = icmp sgt i32 %lhs, %x
636   ret i1 %c
639 ; X - Y > X -> 0 > Y if there is no overflow.
640 define i1 @test34(i32 %x, i32 %y) {
641 ; CHECK-LABEL: @test34(
642 ; CHECK-NEXT:    ret i1 false
644   %lhs = sub nuw i32 %x, %y
645   %c = icmp ugt i32 %lhs, %x
646   ret i1 %c
649 ; X > X - Y -> Y > 0 if there is no overflow.
650 define i1 @test35(i32 %x, i32 %y) {
651 ; CHECK-LABEL: @test35(
652 ; CHECK-NEXT:    [[C:%.*]] = icmp sgt i32 [[Y:%.*]], 0
653 ; CHECK-NEXT:    ret i1 [[C]]
655   %rhs = sub nsw i32 %x, %y
656   %c = icmp sgt i32 %x, %rhs
657   ret i1 %c
660 ; X > X - Y -> Y > 0 if there is no overflow.
661 define i1 @test36(i32 %x, i32 %y) {
662 ; CHECK-LABEL: @test36(
663 ; CHECK-NEXT:    [[C:%.*]] = icmp ne i32 [[Y:%.*]], 0
664 ; CHECK-NEXT:    ret i1 [[C]]
666   %rhs = sub nuw i32 %x, %y
667   %c = icmp ugt i32 %x, %rhs
668   ret i1 %c
671 ; X - Y > X - Z -> Z > Y if there is no overflow.
672 define i1 @test37(i32 %x, i32 %y, i32 %z) {
673 ; CHECK-LABEL: @test37(
674 ; CHECK-NEXT:    [[C:%.*]] = icmp sgt i32 [[Z:%.*]], [[Y:%.*]]
675 ; CHECK-NEXT:    ret i1 [[C]]
677   %lhs = sub nsw i32 %x, %y
678   %rhs = sub nsw i32 %x, %z
679   %c = icmp sgt i32 %lhs, %rhs
680   ret i1 %c
683 define i1 @test37_extra_uses(i32 %x, i32 %y, i32 %z) {
684 ; CHECK-LABEL: @test37_extra_uses(
685 ; CHECK-NEXT:    [[LHS:%.*]] = sub nsw i32 [[X:%.*]], [[Y:%.*]]
686 ; CHECK-NEXT:    call void @foo(i32 [[LHS]])
687 ; CHECK-NEXT:    [[RHS:%.*]] = sub nsw i32 [[X]], [[Z:%.*]]
688 ; CHECK-NEXT:    call void @foo(i32 [[RHS]])
689 ; CHECK-NEXT:    [[C:%.*]] = icmp sgt i32 [[Z]], [[Y]]
690 ; CHECK-NEXT:    ret i1 [[C]]
692   %lhs = sub nsw i32 %x, %y
693   call void @foo(i32 %lhs)
694   %rhs = sub nsw i32 %x, %z
695   call void @foo(i32 %rhs)
696   %c = icmp sgt i32 %lhs, %rhs
697   ret i1 %c
700 ; TODO: Min/max pattern should not prevent the fold.
702 define i32 @neg_max_s32(i32 %x, i32 %y) {
703 ; CHECK-LABEL: @neg_max_s32(
704 ; CHECK-NEXT:    [[C:%.*]] = icmp slt i32 [[Y:%.*]], [[X:%.*]]
705 ; CHECK-NEXT:    [[S_V:%.*]] = select i1 [[C]], i32 [[Y]], i32 [[X]]
706 ; CHECK-NEXT:    ret i32 [[S_V]]
708   %nx = sub nsw i32 0, %x
709   %ny = sub nsw i32 0, %y
710   %c = icmp slt i32 %nx, %ny
711   %s = select i1 %c, i32 %ny, i32 %nx
712   %r = sub nsw i32 0, %s
713   ret i32 %r
716 define <4 x i32> @neg_max_v4s32(<4 x i32> %x, <4 x i32> %y) {
717 ; CHECK-LABEL: @neg_max_v4s32(
718 ; CHECK-NEXT:    [[C:%.*]] = icmp sgt <4 x i32> [[Y:%.*]], [[X:%.*]]
719 ; CHECK-NEXT:    [[S_V:%.*]] = select <4 x i1> [[C]], <4 x i32> [[X]], <4 x i32> [[Y]]
720 ; CHECK-NEXT:    ret <4 x i32> [[S_V]]
722   %nx = sub nsw <4 x i32> zeroinitializer, %x
723   %ny = sub nsw <4 x i32> zeroinitializer, %y
724   %c = icmp sgt <4 x i32> %nx, %ny
725   %s = select <4 x i1> %c, <4 x i32> %nx, <4 x i32> %ny
726   %r = sub <4 x i32> zeroinitializer, %s
727   ret <4 x i32> %r
730 ; X - Y > X - Z -> Z > Y if there is no overflow.
731 define i1 @test38(i32 %x, i32 %y, i32 %z) {
732 ; CHECK-LABEL: @test38(
733 ; CHECK-NEXT:    [[C:%.*]] = icmp ugt i32 [[Z:%.*]], [[Y:%.*]]
734 ; CHECK-NEXT:    ret i1 [[C]]
736   %lhs = sub nuw i32 %x, %y
737   %rhs = sub nuw i32 %x, %z
738   %c = icmp ugt i32 %lhs, %rhs
739   ret i1 %c
742 define i1 @test38_extra_uses(i32 %x, i32 %y, i32 %z) {
743 ; CHECK-LABEL: @test38_extra_uses(
744 ; CHECK-NEXT:    [[LHS:%.*]] = sub nuw i32 [[X:%.*]], [[Y:%.*]]
745 ; CHECK-NEXT:    call void @foo(i32 [[LHS]])
746 ; CHECK-NEXT:    [[RHS:%.*]] = sub nuw i32 [[X]], [[Z:%.*]]
747 ; CHECK-NEXT:    call void @foo(i32 [[RHS]])
748 ; CHECK-NEXT:    [[C:%.*]] = icmp ugt i32 [[Z]], [[Y]]
749 ; CHECK-NEXT:    ret i1 [[C]]
751   %lhs = sub nuw i32 %x, %y
752   call void @foo(i32 %lhs)
753   %rhs = sub nuw i32 %x, %z
754   call void @foo(i32 %rhs)
755   %c = icmp ugt i32 %lhs, %rhs
756   ret i1 %c
759 ; PR9343 #1
760 define i1 @test39(i32 %X, i32 %Y) {
761 ; CHECK-LABEL: @test39(
762 ; CHECK-NEXT:    [[B:%.*]] = icmp eq i32 [[X:%.*]], 0
763 ; CHECK-NEXT:    ret i1 [[B]]
765   %A = ashr exact i32 %X, %Y
766   %B = icmp eq i32 %A, 0
767   ret i1 %B
770 define <2 x i1> @test39vec(<2 x i32> %X, <2 x i32> %Y) {
771 ; CHECK-LABEL: @test39vec(
772 ; CHECK-NEXT:    [[B:%.*]] = icmp eq <2 x i32> [[X:%.*]], zeroinitializer
773 ; CHECK-NEXT:    ret <2 x i1> [[B]]
775   %A = ashr exact <2 x i32> %X, %Y
776   %B = icmp eq <2 x i32> %A, zeroinitializer
777   ret <2 x i1> %B
780 define i1 @test40(i32 %X, i32 %Y) {
781 ; CHECK-LABEL: @test40(
782 ; CHECK-NEXT:    [[B:%.*]] = icmp ne i32 [[X:%.*]], 0
783 ; CHECK-NEXT:    ret i1 [[B]]
785   %A = lshr exact i32 %X, %Y
786   %B = icmp ne i32 %A, 0
787   ret i1 %B
790 define <2 x i1> @test40vec(<2 x i32> %X, <2 x i32> %Y) {
791 ; CHECK-LABEL: @test40vec(
792 ; CHECK-NEXT:    [[B:%.*]] = icmp ne <2 x i32> [[X:%.*]], zeroinitializer
793 ; CHECK-NEXT:    ret <2 x i1> [[B]]
795   %A = lshr exact <2 x i32> %X, %Y
796   %B = icmp ne <2 x i32> %A, zeroinitializer
797   ret <2 x i1> %B
800 define i1 @shr_exact(i132 %x) {
801 ; CHECK-LABEL: @shr_exact(
802 ; CHECK-NEXT:    [[CMP:%.*]] = icmp eq i132 [[X:%.*]], 32
803 ; CHECK-NEXT:    ret i1 [[CMP]]
805   %sh = ashr exact i132 %x, 4
806   %cmp = icmp eq i132 %sh, 2
807   ret i1 %cmp
810 define <2 x i1> @shr_exact_vec(<2 x i132> %x) {
811 ; CHECK-LABEL: @shr_exact_vec(
812 ; CHECK-NEXT:    [[CMP:%.*]] = icmp ne <2 x i132> [[X:%.*]], <i132 32, i132 32>
813 ; CHECK-NEXT:    ret <2 x i1> [[CMP]]
815   %sh = lshr exact <2 x i132> %x, <i132 4, i132 4>
816   %cmp = icmp ne <2 x i132> %sh, <i132 2, i132 2>
817   ret <2 x i1> %cmp
820 ; PR9343 #3
821 define i1 @test41(i32 %X, i32 %Y) {
822 ; CHECK-LABEL: @test41(
823 ; CHECK-NEXT:    ret i1 true
825   %A = urem i32 %X, %Y
826   %B = icmp ugt i32 %Y, %A
827   ret i1 %B
830 define i1 @test42(i32 %X, i32 %Y) {
831 ; CHECK-LABEL: @test42(
832 ; CHECK-NEXT:    [[B:%.*]] = icmp sgt i32 [[Y:%.*]], -1
833 ; CHECK-NEXT:    ret i1 [[B]]
835   %A = srem i32 %X, %Y
836   %B = icmp slt i32 %A, %Y
837   ret i1 %B
840 define i1 @test43(i32 %X, i32 %Y) {
841 ; CHECK-LABEL: @test43(
842 ; CHECK-NEXT:    [[B:%.*]] = icmp slt i32 [[Y:%.*]], 0
843 ; CHECK-NEXT:    ret i1 [[B]]
845   %A = srem i32 %X, %Y
846   %B = icmp slt i32 %Y, %A
847   ret i1 %B
850 define i1 @test44(i32 %X, i32 %Y) {
851 ; CHECK-LABEL: @test44(
852 ; CHECK-NEXT:    [[B:%.*]] = icmp sgt i32 [[Y:%.*]], -1
853 ; CHECK-NEXT:    ret i1 [[B]]
855   %A = srem i32 %X, %Y
856   %B = icmp slt i32 %A, %Y
857   ret i1 %B
860 define i1 @test45(i32 %X, i32 %Y) {
861 ; CHECK-LABEL: @test45(
862 ; CHECK-NEXT:    [[B:%.*]] = icmp slt i32 [[Y:%.*]], 0
863 ; CHECK-NEXT:    ret i1 [[B]]
865   %A = srem i32 %X, %Y
866   %B = icmp slt i32 %Y, %A
867   ret i1 %B
870 ; PR9343 #4
871 define i1 @test46(i32 %X, i32 %Y, i32 %Z) {
872 ; CHECK-LABEL: @test46(
873 ; CHECK-NEXT:    [[C:%.*]] = icmp ult i32 [[X:%.*]], [[Y:%.*]]
874 ; CHECK-NEXT:    ret i1 [[C]]
876   %A = ashr exact i32 %X, %Z
877   %B = ashr exact i32 %Y, %Z
878   %C = icmp ult i32 %A, %B
879   ret i1 %C
882 ; PR9343 #5
883 define i1 @test47(i32 %X, i32 %Y, i32 %Z) {
884 ; CHECK-LABEL: @test47(
885 ; CHECK-NEXT:    [[C:%.*]] = icmp ugt i32 [[X:%.*]], [[Y:%.*]]
886 ; CHECK-NEXT:    ret i1 [[C]]
888   %A = ashr exact i32 %X, %Z
889   %B = ashr exact i32 %Y, %Z
890   %C = icmp ugt i32 %A, %B
891   ret i1 %C
894 ; PR9343 #8
895 define i1 @test48(i32 %X, i32 %Y, i32 %Z) {
896 ; CHECK-LABEL: @test48(
897 ; CHECK-NEXT:    [[C:%.*]] = icmp eq i32 [[X:%.*]], [[Y:%.*]]
898 ; CHECK-NEXT:    ret i1 [[C]]
900   %A = sdiv exact i32 %X, %Z
901   %B = sdiv exact i32 %Y, %Z
902   %C = icmp eq i32 %A, %B
903   ret i1 %C
906 ; The above transform only works for equality predicates.
908 define i1 @PR32949(i32 %X, i32 %Y, i32 %Z) {
909 ; CHECK-LABEL: @PR32949(
910 ; CHECK-NEXT:    [[A:%.*]] = sdiv exact i32 [[X:%.*]], [[Z:%.*]]
911 ; CHECK-NEXT:    [[B:%.*]] = sdiv exact i32 [[Y:%.*]], [[Z]]
912 ; CHECK-NEXT:    [[C:%.*]] = icmp sgt i32 [[A]], [[B]]
913 ; CHECK-NEXT:    ret i1 [[C]]
915   %A = sdiv exact i32 %X, %Z
916   %B = sdiv exact i32 %Y, %Z
917   %C = icmp sgt i32 %A, %B
918   ret i1 %C
921 ; PR8469
922 define <2 x i1> @test49(<2 x i32> %i3) {
923 ; CHECK-LABEL: @test49(
924 ; CHECK-NEXT:  entry:
925 ; CHECK-NEXT:    ret <2 x i1> <i1 true, i1 true>
927 entry:
928   %i11 = and <2 x i32> %i3, <i32 3, i32 3>
929   %cmp = icmp ult <2 x i32> %i11, <i32 4, i32 4>
930   ret <2 x i1> %cmp
933 ; PR9343 #7
934 define i1 @test50(i16 %X, i32 %Y) {
935 ; CHECK-LABEL: @test50(
936 ; CHECK-NEXT:    ret i1 true
938   %A = zext i16 %X to i32
939   %B = srem i32 %A, %Y
940   %C = icmp sgt i32 %B, -1
941   ret i1 %C
944 define i1 @test51(i32 %X, i32 %Y) {
945 ; CHECK-LABEL: @test51(
946 ; CHECK-NEXT:    [[A:%.*]] = and i32 [[X:%.*]], -2147483648
947 ; CHECK-NEXT:    [[B:%.*]] = srem i32 [[A]], [[Y:%.*]]
948 ; CHECK-NEXT:    [[C:%.*]] = icmp sgt i32 [[B]], -1
949 ; CHECK-NEXT:    ret i1 [[C]]
951   %A = and i32 %X, 2147483648
952   %B = srem i32 %A, %Y
953   %C = icmp sgt i32 %B, -1
954   ret i1 %C
957 define i1 @test52(i32 %x1) {
958 ; CHECK-LABEL: @test52(
959 ; CHECK-NEXT:    [[TMP1:%.*]] = and i32 [[X1:%.*]], 16711935
960 ; CHECK-NEXT:    [[TMP2:%.*]] = icmp eq i32 [[TMP1]], 4980863
961 ; CHECK-NEXT:    ret i1 [[TMP2]]
963   %conv = and i32 %x1, 255
964   %cmp = icmp eq i32 %conv, 127
965   %i2 = lshr i32 %x1, 16
966   %i3 = trunc i32 %i2 to i8
967   %cmp15 = icmp eq i8 %i3, 76
969   %A = and i1 %cmp, %cmp15
970   ret i1 %A
973 define i1 @test52_logical(i32 %x1) {
974 ; CHECK-LABEL: @test52_logical(
975 ; CHECK-NEXT:    [[TMP1:%.*]] = and i32 [[X1:%.*]], 16711935
976 ; CHECK-NEXT:    [[TMP2:%.*]] = icmp eq i32 [[TMP1]], 4980863
977 ; CHECK-NEXT:    ret i1 [[TMP2]]
979   %conv = and i32 %x1, 255
980   %cmp = icmp eq i32 %conv, 127
981   %i2 = lshr i32 %x1, 16
982   %i3 = trunc i32 %i2 to i8
983   %cmp15 = icmp eq i8 %i3, 76
985   %A = select i1 %cmp, i1 %cmp15, i1 false
986   ret i1 %A
989 define i1 @test52b(i128 %x1) {
990 ; CHECK-LABEL: @test52b(
991 ; CHECK-NEXT:    [[TMP1:%.*]] = and i128 [[X1:%.*]], 16711935
992 ; CHECK-NEXT:    [[TMP2:%.*]] = icmp eq i128 [[TMP1]], 4980863
993 ; CHECK-NEXT:    ret i1 [[TMP2]]
995   %conv = and i128 %x1, 255
996   %cmp = icmp eq i128 %conv, 127
997   %i2 = lshr i128 %x1, 16
998   %i3 = trunc i128 %i2 to i8
999   %cmp15 = icmp eq i8 %i3, 76
1001   %A = and i1 %cmp, %cmp15
1002   ret i1 %A
1005 define i1 @test52b_logical(i128 %x1) {
1006 ; CHECK-LABEL: @test52b_logical(
1007 ; CHECK-NEXT:    [[TMP1:%.*]] = and i128 [[X1:%.*]], 16711935
1008 ; CHECK-NEXT:    [[TMP2:%.*]] = icmp eq i128 [[TMP1]], 4980863
1009 ; CHECK-NEXT:    ret i1 [[TMP2]]
1011   %conv = and i128 %x1, 255
1012   %cmp = icmp eq i128 %conv, 127
1013   %i2 = lshr i128 %x1, 16
1014   %i3 = trunc i128 %i2 to i8
1015   %cmp15 = icmp eq i8 %i3, 76
1017   %A = select i1 %cmp, i1 %cmp15, i1 false
1018   ret i1 %A
1021 ; PR9838
1022 define i1 @test53(i32 %a, i32 %b) {
1023 ; CHECK-LABEL: @test53(
1024 ; CHECK-NEXT:    [[X:%.*]] = sdiv exact i32 [[A:%.*]], 30
1025 ; CHECK-NEXT:    [[Y:%.*]] = sdiv i32 [[B:%.*]], 30
1026 ; CHECK-NEXT:    [[Z:%.*]] = icmp eq i32 [[X]], [[Y]]
1027 ; CHECK-NEXT:    ret i1 [[Z]]
1029   %x = sdiv exact i32 %a, 30
1030   %y = sdiv i32 %b, 30
1031   %z = icmp eq i32 %x, %y
1032   ret i1 %z
1035 define i1 @test54(i8 %a) {
1036 ; CHECK-LABEL: @test54(
1037 ; CHECK-NEXT:    [[TMP1:%.*]] = and i8 [[A:%.*]], -64
1038 ; CHECK-NEXT:    [[RET:%.*]] = icmp eq i8 [[TMP1]], -128
1039 ; CHECK-NEXT:    ret i1 [[RET]]
1041   %ext = zext i8 %a to i32
1042   %and = and i32 %ext, 192
1043   %ret = icmp eq i32 %and, 128
1044   ret i1 %ret
1047 define i1 @test55(i32 %a) {
1048 ; CHECK-LABEL: @test55(
1049 ; CHECK-NEXT:    [[CMP:%.*]] = icmp eq i32 [[A:%.*]], -123
1050 ; CHECK-NEXT:    ret i1 [[CMP]]
1052   %sub = sub i32 0, %a
1053   %cmp = icmp eq i32 %sub, 123
1054   ret i1 %cmp
1057 define <2 x i1> @test55vec(<2 x i32> %a) {
1058 ; CHECK-LABEL: @test55vec(
1059 ; CHECK-NEXT:    [[CMP:%.*]] = icmp eq <2 x i32> [[A:%.*]], <i32 -123, i32 -123>
1060 ; CHECK-NEXT:    ret <2 x i1> [[CMP]]
1062   %sub = sub <2 x i32> zeroinitializer, %a
1063   %cmp = icmp eq <2 x i32> %sub, <i32 123, i32 123>
1064   ret <2 x i1> %cmp
1067 define i1 @test56(i32 %a) {
1068 ; CHECK-LABEL: @test56(
1069 ; CHECK-NEXT:    [[CMP:%.*]] = icmp eq i32 [[A:%.*]], -113
1070 ; CHECK-NEXT:    ret i1 [[CMP]]
1072   %sub = sub i32 10, %a
1073   %cmp = icmp eq i32 %sub, 123
1074   ret i1 %cmp
1077 define <2 x i1> @test56vec(<2 x i32> %a) {
1078 ; CHECK-LABEL: @test56vec(
1079 ; CHECK-NEXT:    [[CMP:%.*]] = icmp eq <2 x i32> [[A:%.*]], <i32 -113, i32 -113>
1080 ; CHECK-NEXT:    ret <2 x i1> [[CMP]]
1082   %sub = sub <2 x i32> <i32 10, i32 10>, %a
1083   %cmp = icmp eq <2 x i32> %sub, <i32 123, i32 123>
1084   ret <2 x i1> %cmp
1087 ; PR10267 Don't make icmps more expensive when no other inst is subsumed.
1088 declare void @foo(i32)
1089 define i1 @test57(i32 %a) {
1090 ; CHECK-LABEL: @test57(
1091 ; CHECK-NEXT:    [[AND:%.*]] = and i32 [[A:%.*]], -2
1092 ; CHECK-NEXT:    [[CMP:%.*]] = icmp ne i32 [[AND]], 0
1093 ; CHECK-NEXT:    call void @foo(i32 [[AND]])
1094 ; CHECK-NEXT:    ret i1 [[CMP]]
1096   %and = and i32 %a, -2
1097   %cmp = icmp ne i32 %and, 0
1098   call void @foo(i32 %and)
1099   ret i1 %cmp
1102 ; rdar://problem/10482509
1103 define zeroext i1 @cmpabs1(i64 %val) {
1104 ; CHECK-LABEL: @cmpabs1(
1105 ; CHECK-NEXT:    [[TOBOOL:%.*]] = icmp ne i64 [[VAL:%.*]], 0
1106 ; CHECK-NEXT:    ret i1 [[TOBOOL]]
1108   %sub = sub nsw i64 0, %val
1109   %cmp = icmp slt i64 %val, 0
1110   %sub.val = select i1 %cmp, i64 %sub, i64 %val
1111   %tobool = icmp ne i64 %sub.val, 0
1112   ret i1 %tobool
1115 define zeroext i1 @cmpabs2(i64 %val) {
1116 ; CHECK-LABEL: @cmpabs2(
1117 ; CHECK-NEXT:    [[TOBOOL:%.*]] = icmp ne i64 [[VAL:%.*]], 0
1118 ; CHECK-NEXT:    ret i1 [[TOBOOL]]
1120   %sub = sub nsw i64 0, %val
1121   %cmp = icmp slt i64 %val, 0
1122   %sub.val = select i1 %cmp, i64 %val, i64 %sub
1123   %tobool = icmp ne i64 %sub.val, 0
1124   ret i1 %tobool
1127 define i1 @abs_intrin_eq_zero(i8 %x) {
1128 ; CHECK-LABEL: @abs_intrin_eq_zero(
1129 ; CHECK-NEXT:    [[CMP:%.*]] = icmp eq i8 [[X:%.*]], 0
1130 ; CHECK-NEXT:    ret i1 [[CMP]]
1132   %abs = call i8 @llvm.abs.i8(i8 %x, i1 false)
1133   %cmp = icmp eq i8 %abs, 0
1134   ret i1 %cmp
1137 define i1 @abs_intrin_ne_zero(i8 %x) {
1138 ; CHECK-LABEL: @abs_intrin_ne_zero(
1139 ; CHECK-NEXT:    [[CMP:%.*]] = icmp ne i8 [[X:%.*]], 0
1140 ; CHECK-NEXT:    ret i1 [[CMP]]
1142   %abs = call i8 @llvm.abs.i8(i8 %x, i1 false)
1143   %cmp = icmp ne i8 %abs, 0
1144   ret i1 %cmp
1147 define void @test58() {
1148 ; CHECK-LABEL: @test58(
1149 ; CHECK-NEXT:    [[CALL:%.*]] = call i32 @test58_d(i64 36029346783166592)
1150 ; CHECK-NEXT:    ret void
1152   %cast = bitcast <1 x i64> <i64 36029346783166592> to i64
1153   %call = call i32 @test58_d( i64 %cast)
1154   ret void
1156 declare i32 @test58_d(i64)
1158 define i1 @test59(i8* %foo) {
1159 ; CHECK-LABEL: @test59(
1160 ; CHECK-NEXT:    [[GEP1:%.*]] = getelementptr inbounds i8, i8* [[FOO:%.*]], i64 8
1161 ; CHECK-NEXT:    [[USE:%.*]] = ptrtoint i8* [[GEP1]] to i64
1162 ; CHECK-NEXT:    [[CALL:%.*]] = call i32 @test58_d(i64 [[USE]])
1163 ; CHECK-NEXT:    ret i1 true
1165   %bit = bitcast i8* %foo to i32*
1166   %gep1 = getelementptr inbounds i32, i32* %bit, i64 2
1167   %gep2 = getelementptr inbounds i8, i8* %foo, i64 10
1168   %cast1 = bitcast i32* %gep1 to i8*
1169   %cmp = icmp ult i8* %cast1, %gep2
1170   %use = ptrtoint i8* %cast1 to i64
1171   %call = call i32 @test58_d(i64 %use)
1172   ret i1 %cmp
1175 define i1 @test59_as1(i8 addrspace(1)* %foo) {
1176 ; CHECK-LABEL: @test59_as1(
1177 ; CHECK-NEXT:    [[GEP1:%.*]] = getelementptr inbounds i8, i8 addrspace(1)* [[FOO:%.*]], i16 8
1178 ; CHECK-NEXT:    [[TMP1:%.*]] = ptrtoint i8 addrspace(1)* [[GEP1]] to i16
1179 ; CHECK-NEXT:    [[USE:%.*]] = zext i16 [[TMP1]] to i64
1180 ; CHECK-NEXT:    [[CALL:%.*]] = call i32 @test58_d(i64 [[USE]])
1181 ; CHECK-NEXT:    ret i1 true
1183   %bit = bitcast i8 addrspace(1)* %foo to i32 addrspace(1)*
1184   %gep1 = getelementptr inbounds i32, i32 addrspace(1)* %bit, i64 2
1185   %gep2 = getelementptr inbounds i8, i8 addrspace(1)* %foo, i64 10
1186   %cast1 = bitcast i32 addrspace(1)* %gep1 to i8 addrspace(1)*
1187   %cmp = icmp ult i8 addrspace(1)* %cast1, %gep2
1188   %use = ptrtoint i8 addrspace(1)* %cast1 to i64
1189   %call = call i32 @test58_d(i64 %use)
1190   ret i1 %cmp
1193 define i1 @test60(i8* %foo, i64 %i, i64 %j) {
1194 ; CHECK-LABEL: @test60(
1195 ; CHECK-NEXT:    [[GEP1_IDX:%.*]] = shl nsw i64 [[I:%.*]], 2
1196 ; CHECK-NEXT:    [[TMP1:%.*]] = icmp slt i64 [[GEP1_IDX]], [[J:%.*]]
1197 ; CHECK-NEXT:    ret i1 [[TMP1]]
1199   %bit = bitcast i8* %foo to i32*
1200   %gep1 = getelementptr inbounds i32, i32* %bit, i64 %i
1201   %gep2 = getelementptr inbounds i8, i8* %foo, i64 %j
1202   %cast1 = bitcast i32* %gep1 to i8*
1203   %cmp = icmp ult i8* %cast1, %gep2
1204   ret i1 %cmp
1207 define i1 @test60_as1(i8 addrspace(1)* %foo, i64 %i, i64 %j) {
1208 ; CHECK-LABEL: @test60_as1(
1209 ; CHECK-NEXT:    [[TMP1:%.*]] = trunc i64 [[I:%.*]] to i16
1210 ; CHECK-NEXT:    [[TMP2:%.*]] = trunc i64 [[J:%.*]] to i16
1211 ; CHECK-NEXT:    [[GEP1_IDX:%.*]] = shl nsw i16 [[TMP1]], 2
1212 ; CHECK-NEXT:    [[TMP3:%.*]] = icmp slt i16 [[GEP1_IDX]], [[TMP2]]
1213 ; CHECK-NEXT:    ret i1 [[TMP3]]
1215   %bit = bitcast i8 addrspace(1)* %foo to i32 addrspace(1)*
1216   %gep1 = getelementptr inbounds i32, i32 addrspace(1)* %bit, i64 %i
1217   %gep2 = getelementptr inbounds i8, i8 addrspace(1)* %foo, i64 %j
1218   %cast1 = bitcast i32 addrspace(1)* %gep1 to i8 addrspace(1)*
1219   %cmp = icmp ult i8 addrspace(1)* %cast1, %gep2
1220   ret i1 %cmp
1223 ; Same as test60, but look through an addrspacecast instead of a
1224 ; bitcast. This uses the same sized addrspace.
1225 define i1 @test60_addrspacecast(i8* %foo, i64 %i, i64 %j) {
1226 ; CHECK-LABEL: @test60_addrspacecast(
1227 ; CHECK-NEXT:    [[GEP1_IDX:%.*]] = shl nsw i64 [[I:%.*]], 2
1228 ; CHECK-NEXT:    [[TMP1:%.*]] = icmp slt i64 [[GEP1_IDX]], [[J:%.*]]
1229 ; CHECK-NEXT:    ret i1 [[TMP1]]
1231   %bit = addrspacecast i8* %foo to i32 addrspace(3)*
1232   %gep1 = getelementptr inbounds i32, i32 addrspace(3)* %bit, i64 %i
1233   %gep2 = getelementptr inbounds i8, i8* %foo, i64 %j
1234   %cast1 = addrspacecast i32 addrspace(3)* %gep1 to i8*
1235   %cmp = icmp ult i8* %cast1, %gep2
1236   ret i1 %cmp
1239 define i1 @test60_addrspacecast_smaller(i8* %foo, i16 %i, i64 %j) {
1240 ; CHECK-LABEL: @test60_addrspacecast_smaller(
1241 ; CHECK-NEXT:    [[GEP1_IDX:%.*]] = shl nsw i16 [[I:%.*]], 2
1242 ; CHECK-NEXT:    [[TMP1:%.*]] = trunc i64 [[J:%.*]] to i16
1243 ; CHECK-NEXT:    [[TMP2:%.*]] = icmp slt i16 [[GEP1_IDX]], [[TMP1]]
1244 ; CHECK-NEXT:    ret i1 [[TMP2]]
1246   %bit = addrspacecast i8* %foo to i32 addrspace(1)*
1247   %gep1 = getelementptr inbounds i32, i32 addrspace(1)* %bit, i16 %i
1248   %gep2 = getelementptr inbounds i8, i8* %foo, i64 %j
1249   %cast1 = addrspacecast i32 addrspace(1)* %gep1 to i8*
1250   %cmp = icmp ult i8* %cast1, %gep2
1251   ret i1 %cmp
1254 define i1 @test60_addrspacecast_larger(i8 addrspace(1)* %foo, i32 %i, i16 %j) {
1255 ; CHECK-LABEL: @test60_addrspacecast_larger(
1256 ; CHECK-NEXT:    [[I_TR:%.*]] = trunc i32 [[I:%.*]] to i16
1257 ; CHECK-NEXT:    [[TMP1:%.*]] = shl i16 [[I_TR]], 2
1258 ; CHECK-NEXT:    [[TMP2:%.*]] = icmp slt i16 [[TMP1]], [[J:%.*]]
1259 ; CHECK-NEXT:    ret i1 [[TMP2]]
1261   %bit = addrspacecast i8 addrspace(1)* %foo to i32 addrspace(2)*
1262   %gep1 = getelementptr inbounds i32, i32 addrspace(2)* %bit, i32 %i
1263   %gep2 = getelementptr inbounds i8, i8 addrspace(1)* %foo, i16 %j
1264   %cast1 = addrspacecast i32 addrspace(2)* %gep1 to i8 addrspace(1)*
1265   %cmp = icmp ult i8 addrspace(1)* %cast1, %gep2
1266   ret i1 %cmp
1269 define i1 @test61(i8* %foo, i64 %i, i64 %j) {
1270 ; CHECK-LABEL: @test61(
1271 ; CHECK-NEXT:    [[BIT:%.*]] = bitcast i8* [[FOO:%.*]] to i32*
1272 ; CHECK-NEXT:    [[GEP1:%.*]] = getelementptr i32, i32* [[BIT]], i64 [[I:%.*]]
1273 ; CHECK-NEXT:    [[GEP2:%.*]] = getelementptr i8, i8* [[FOO]], i64 [[J:%.*]]
1274 ; CHECK-NEXT:    [[CAST1:%.*]] = bitcast i32* [[GEP1]] to i8*
1275 ; CHECK-NEXT:    [[CMP:%.*]] = icmp ugt i8* [[GEP2]], [[CAST1]]
1276 ; CHECK-NEXT:    ret i1 [[CMP]]
1278   %bit = bitcast i8* %foo to i32*
1279   %gep1 = getelementptr i32, i32* %bit, i64 %i
1280   %gep2 = getelementptr  i8,  i8* %foo, i64 %j
1281   %cast1 = bitcast i32* %gep1 to i8*
1282   %cmp = icmp ult i8* %cast1, %gep2
1283   ret i1 %cmp
1284 ; Don't transform non-inbounds GEPs.
1287 define i1 @test61_as1(i8 addrspace(1)* %foo, i16 %i, i16 %j) {
1288 ; CHECK-LABEL: @test61_as1(
1289 ; CHECK-NEXT:    [[BIT:%.*]] = bitcast i8 addrspace(1)* [[FOO:%.*]] to i32 addrspace(1)*
1290 ; CHECK-NEXT:    [[GEP1:%.*]] = getelementptr i32, i32 addrspace(1)* [[BIT]], i16 [[I:%.*]]
1291 ; CHECK-NEXT:    [[GEP2:%.*]] = getelementptr i8, i8 addrspace(1)* [[FOO]], i16 [[J:%.*]]
1292 ; CHECK-NEXT:    [[CAST1:%.*]] = bitcast i32 addrspace(1)* [[GEP1]] to i8 addrspace(1)*
1293 ; CHECK-NEXT:    [[CMP:%.*]] = icmp ugt i8 addrspace(1)* [[GEP2]], [[CAST1]]
1294 ; CHECK-NEXT:    ret i1 [[CMP]]
1296   %bit = bitcast i8 addrspace(1)* %foo to i32 addrspace(1)*
1297   %gep1 = getelementptr i32, i32 addrspace(1)* %bit, i16 %i
1298   %gep2 = getelementptr i8, i8 addrspace(1)* %foo, i16 %j
1299   %cast1 = bitcast i32 addrspace(1)* %gep1 to i8 addrspace(1)*
1300   %cmp = icmp ult i8 addrspace(1)* %cast1, %gep2
1301   ret i1 %cmp
1302 ; Don't transform non-inbounds GEPs.
1305 define i1 @test62(i8* %a) {
1306 ; CHECK-LABEL: @test62(
1307 ; CHECK-NEXT:    ret i1 true
1309   %arrayidx1 = getelementptr inbounds i8, i8* %a, i64 1
1310   %arrayidx2 = getelementptr inbounds i8, i8* %a, i64 10
1311   %cmp = icmp slt i8* %arrayidx1, %arrayidx2
1312   ret i1 %cmp
1315 define i1 @test62_as1(i8 addrspace(1)* %a) {
1316 ; CHECK-LABEL: @test62_as1(
1317 ; CHECK-NEXT:    ret i1 true
1319   %arrayidx1 = getelementptr inbounds i8, i8 addrspace(1)* %a, i64 1
1320   %arrayidx2 = getelementptr inbounds i8, i8 addrspace(1)* %a, i64 10
1321   %cmp = icmp slt i8 addrspace(1)* %arrayidx1, %arrayidx2
1322   ret i1 %cmp
1325 define i1 @test63(i8 %a, i32 %b) {
1326 ; CHECK-LABEL: @test63(
1327 ; CHECK-NEXT:    [[TMP1:%.*]] = trunc i32 [[B:%.*]] to i8
1328 ; CHECK-NEXT:    [[C:%.*]] = icmp eq i8 [[TMP1]], [[A:%.*]]
1329 ; CHECK-NEXT:    ret i1 [[C]]
1331   %z = zext i8 %a to i32
1332   %t = and i32 %b, 255
1333   %c = icmp eq i32 %z, %t
1334   ret i1 %c
1337 define i1 @test64(i8 %a, i32 %b) {
1338 ; CHECK-LABEL: @test64(
1339 ; CHECK-NEXT:    [[TMP1:%.*]] = trunc i32 [[B:%.*]] to i8
1340 ; CHECK-NEXT:    [[C:%.*]] = icmp eq i8 [[TMP1]], [[A:%.*]]
1341 ; CHECK-NEXT:    ret i1 [[C]]
1343   %t = and i32 %b, 255
1344   %z = zext i8 %a to i32
1345   %c = icmp eq i32 %t, %z
1346   ret i1 %c
1349 define i1 @test65(i64 %A, i64 %B) {
1350 ; CHECK-LABEL: @test65(
1351 ; CHECK-NEXT:    ret i1 true
1353   %s1 = add i64 %A, %B
1354   %s2 = add i64 %A, %B
1355   %cmp = icmp eq i64 %s1, %s2
1356   ret i1 %cmp
1359 define i1 @test66(i64 %A, i64 %B) {
1360 ; CHECK-LABEL: @test66(
1361 ; CHECK-NEXT:    ret i1 true
1363   %s1 = add i64 %A, %B
1364   %s2 = add i64 %B, %A
1365   %cmp = icmp eq i64 %s1, %s2
1366   ret i1 %cmp
1369 define i1 @test67(i32 %x) {
1370 ; CHECK-LABEL: @test67(
1371 ; CHECK-NEXT:    [[AND:%.*]] = and i32 [[X:%.*]], 96
1372 ; CHECK-NEXT:    [[CMP:%.*]] = icmp ne i32 [[AND]], 0
1373 ; CHECK-NEXT:    ret i1 [[CMP]]
1375   %and = and i32 %x, 127
1376   %cmp = icmp sgt i32 %and, 31
1377   ret i1 %cmp
1380 define i1 @test67inverse(i32 %x) {
1381 ; CHECK-LABEL: @test67inverse(
1382 ; CHECK-NEXT:    [[AND:%.*]] = and i32 [[X:%.*]], 96
1383 ; CHECK-NEXT:    [[CMP:%.*]] = icmp eq i32 [[AND]], 0
1384 ; CHECK-NEXT:    ret i1 [[CMP]]
1386   %and = and i32 %x, 127
1387   %cmp = icmp sle i32 %and, 31
1388   ret i1 %cmp
1391 ; The test above relies on 3 different folds.
1392 ; This test only checks the last of those (icmp ugt -> icmp ne).
1394 define <2 x i1> @test67vec(<2 x i32> %x) {
1395 ; CHECK-LABEL: @test67vec(
1396 ; CHECK-NEXT:    [[AND:%.*]] = and <2 x i32> [[X:%.*]], <i32 96, i32 96>
1397 ; CHECK-NEXT:    [[CMP:%.*]] = icmp ne <2 x i32> [[AND]], zeroinitializer
1398 ; CHECK-NEXT:    ret <2 x i1> [[CMP]]
1400   %and = and <2 x i32> %x, <i32 96, i32 96>
1401   %cmp = icmp ugt <2 x i32> %and, <i32 31, i32 31>
1402   ret <2 x i1> %cmp
1405 define <2 x i1> @test67vec2(<2 x i32> %x) {
1406 ; CHECK-LABEL: @test67vec2(
1407 ; CHECK-NEXT:    [[AND:%.*]] = and <2 x i32> [[X:%.*]], <i32 96, i32 96>
1408 ; CHECK-NEXT:    [[CMP:%.*]] = icmp ne <2 x i32> [[AND]], zeroinitializer
1409 ; CHECK-NEXT:    ret <2 x i1> [[CMP]]
1411   %and = and <2 x i32> %x, <i32 127, i32 127>
1412   %cmp = icmp ugt <2 x i32> %and, <i32 31, i32 31>
1413   ret <2 x i1> %cmp
1416 define <2 x i1> @test67vecinverse(<2 x i32> %x) {
1417 ; CHECK-LABEL: @test67vecinverse(
1418 ; CHECK-NEXT:    [[AND:%.*]] = and <2 x i32> [[X:%.*]], <i32 96, i32 96>
1419 ; CHECK-NEXT:    [[CMP:%.*]] = icmp eq <2 x i32> [[AND]], zeroinitializer
1420 ; CHECK-NEXT:    ret <2 x i1> [[CMP]]
1422   %and = and <2 x i32> %x, <i32 96, i32 96>
1423   %cmp = icmp sle <2 x i32> %and, <i32 31, i32 31>
1424   ret <2 x i1> %cmp
1427 define i1 @test68(i32 %x) {
1428 ; CHECK-LABEL: @test68(
1429 ; CHECK-NEXT:    [[AND:%.*]] = and i32 [[X:%.*]], 127
1430 ; CHECK-NEXT:    [[CMP:%.*]] = icmp ugt i32 [[AND]], 30
1431 ; CHECK-NEXT:    ret i1 [[CMP]]
1433   %and = and i32 %x, 127
1434   %cmp = icmp sgt i32 %and, 30
1435   ret i1 %cmp
1438 ; PR15940
1439 define i1 @test70(i32 %X) {
1440 ; CHECK-LABEL: @test70(
1441 ; CHECK-NEXT:    [[A:%.*]] = srem i32 5, [[X:%.*]]
1442 ; CHECK-NEXT:    [[C:%.*]] = icmp ne i32 [[A]], 2
1443 ; CHECK-NEXT:    ret i1 [[C]]
1445   %A = srem i32 5, %X
1446   %B = add i32 %A, 2
1447   %C = icmp ne i32 %B, 4
1448   ret i1 %C
1451 define <2 x i1> @test70vec(<2 x i32> %X) {
1452 ; CHECK-LABEL: @test70vec(
1453 ; CHECK-NEXT:    [[C:%.*]] = icmp ne <2 x i32> [[X:%.*]], <i32 2, i32 2>
1454 ; CHECK-NEXT:    ret <2 x i1> [[C]]
1456   %B = add <2 x i32> %X, <i32 2, i32 2>
1457   %C = icmp ne <2 x i32> %B, <i32 4, i32 4>
1458   ret <2 x i1> %C
1461 define i1 @icmp_sext16trunc(i32 %x) {
1462 ; CHECK-LABEL: @icmp_sext16trunc(
1463 ; CHECK-NEXT:    [[TMP1:%.*]] = trunc i32 [[X:%.*]] to i16
1464 ; CHECK-NEXT:    [[CMP:%.*]] = icmp slt i16 [[TMP1]], 36
1465 ; CHECK-NEXT:    ret i1 [[CMP]]
1467   %trunc = trunc i32 %x to i16
1468   %sext = sext i16 %trunc to i32
1469   %cmp = icmp slt i32 %sext, 36
1470   ret i1 %cmp
1473 define i1 @icmp_sext8trunc(i32 %x) {
1474 ; CHECK-LABEL: @icmp_sext8trunc(
1475 ; CHECK-NEXT:    [[TMP1:%.*]] = trunc i32 [[X:%.*]] to i8
1476 ; CHECK-NEXT:    [[CMP:%.*]] = icmp slt i8 [[TMP1]], 36
1477 ; CHECK-NEXT:    ret i1 [[CMP]]
1479   %trunc = trunc i32 %x to i8
1480   %sext = sext i8 %trunc to i32
1481   %cmp = icmp slt i32 %sext, 36
1482   ret i1 %cmp
1485 ; Vectors should fold the same way.
1486 define <2 x i1> @icmp_sext8trunc_vec(<2 x i32> %x) {
1487 ; CHECK-LABEL: @icmp_sext8trunc_vec(
1488 ; CHECK-NEXT:    [[TMP1:%.*]] = trunc <2 x i32> [[X:%.*]] to <2 x i8>
1489 ; CHECK-NEXT:    [[CMP:%.*]] = icmp slt <2 x i8> [[TMP1]], <i8 36, i8 36>
1490 ; CHECK-NEXT:    ret <2 x i1> [[CMP]]
1492   %trunc = trunc <2 x i32> %x to <2 x i8>
1493   %sext = sext <2 x i8> %trunc to <2 x i32>
1494   %cmp = icmp slt <2 x i32> %sext, <i32 36, i32 36>
1495   ret <2 x i1> %cmp
1498 define i1 @icmp_shl16(i32 %x) {
1499 ; CHECK-LABEL: @icmp_shl16(
1500 ; CHECK-NEXT:    [[TMP1:%.*]] = trunc i32 [[X:%.*]] to i16
1501 ; CHECK-NEXT:    [[CMP:%.*]] = icmp slt i16 [[TMP1]], 36
1502 ; CHECK-NEXT:    ret i1 [[CMP]]
1504   %shl = shl i32 %x, 16
1505   %cmp = icmp slt i32 %shl, 2359296
1506   ret i1 %cmp
1509 ; D25952: Don't create illegal types like i15 in InstCombine
1511 define i1 @icmp_shl17(i32 %x) {
1512 ; CHECK-LABEL: @icmp_shl17(
1513 ; CHECK-NEXT:    [[SHL:%.*]] = shl i32 [[X:%.*]], 17
1514 ; CHECK-NEXT:    [[CMP:%.*]] = icmp slt i32 [[SHL]], 2359296
1515 ; CHECK-NEXT:    ret i1 [[CMP]]
1517   %shl = shl i32 %x, 17
1518   %cmp = icmp slt i32 %shl, 2359296
1519   ret i1 %cmp
1522 define <2 x i1> @icmp_shl16_vec(<2 x i32> %x) {
1523 ; CHECK-LABEL: @icmp_shl16_vec(
1524 ; CHECK-NEXT:    [[TMP1:%.*]] = trunc <2 x i32> [[X:%.*]] to <2 x i16>
1525 ; CHECK-NEXT:    [[CMP:%.*]] = icmp slt <2 x i16> [[TMP1]], <i16 36, i16 36>
1526 ; CHECK-NEXT:    ret <2 x i1> [[CMP]]
1528   %shl = shl <2 x i32> %x, <i32 16, i32 16>
1529   %cmp = icmp slt <2 x i32> %shl, <i32 2359296, i32 2359296>
1530   ret <2 x i1> %cmp
1533 define i1 @icmp_shl24(i32 %x) {
1534 ; CHECK-LABEL: @icmp_shl24(
1535 ; CHECK-NEXT:    [[TMP1:%.*]] = trunc i32 [[X:%.*]] to i8
1536 ; CHECK-NEXT:    [[CMP:%.*]] = icmp slt i8 [[TMP1]], 36
1537 ; CHECK-NEXT:    ret i1 [[CMP]]
1539   %shl = shl i32 %x, 24
1540   %cmp = icmp slt i32 %shl, 603979776
1541   ret i1 %cmp
1544 define i1 @icmp_shl_eq(i32 %x) {
1545 ; CHECK-LABEL: @icmp_shl_eq(
1546 ; CHECK-NEXT:    [[MUL_MASK:%.*]] = and i32 [[X:%.*]], 134217727
1547 ; CHECK-NEXT:    [[CMP:%.*]] = icmp eq i32 [[MUL_MASK]], 0
1548 ; CHECK-NEXT:    ret i1 [[CMP]]
1550   %mul = shl i32 %x, 5
1551   %cmp = icmp eq i32 %mul, 0
1552   ret i1 %cmp
1555 define <2 x i1> @icmp_shl_eq_vec(<2 x i32> %x) {
1556 ; CHECK-LABEL: @icmp_shl_eq_vec(
1557 ; CHECK-NEXT:    [[MUL_MASK:%.*]] = and <2 x i32> [[X:%.*]], <i32 134217727, i32 134217727>
1558 ; CHECK-NEXT:    [[CMP:%.*]] = icmp eq <2 x i32> [[MUL_MASK]], zeroinitializer
1559 ; CHECK-NEXT:    ret <2 x i1> [[CMP]]
1561   %mul = shl <2 x i32> %x, <i32 5, i32 5>
1562   %cmp = icmp eq <2 x i32> %mul, zeroinitializer
1563   ret <2 x i1> %cmp
1566 define i1 @icmp_shl_nsw_ne(i32 %x) {
1567 ; CHECK-LABEL: @icmp_shl_nsw_ne(
1568 ; CHECK-NEXT:    [[CMP:%.*]] = icmp ne i32 [[X:%.*]], 0
1569 ; CHECK-NEXT:    ret i1 [[CMP]]
1571   %mul = shl nsw i32 %x, 7
1572   %cmp = icmp ne i32 %mul, 0
1573   ret i1 %cmp
1576 define <2 x i1> @icmp_shl_nsw_ne_vec(<2 x i32> %x) {
1577 ; CHECK-LABEL: @icmp_shl_nsw_ne_vec(
1578 ; CHECK-NEXT:    [[CMP:%.*]] = icmp ne <2 x i32> [[X:%.*]], zeroinitializer
1579 ; CHECK-NEXT:    ret <2 x i1> [[CMP]]
1581   %mul = shl nsw <2 x i32> %x, <i32 7, i32 7>
1582   %cmp = icmp ne <2 x i32> %mul, zeroinitializer
1583   ret <2 x i1> %cmp
1586 define i1 @icmp_shl_ne(i32 %x) {
1587 ; CHECK-LABEL: @icmp_shl_ne(
1588 ; CHECK-NEXT:    [[MUL_MASK:%.*]] = and i32 [[X:%.*]], 33554431
1589 ; CHECK-NEXT:    [[CMP:%.*]] = icmp ne i32 [[MUL_MASK]], 0
1590 ; CHECK-NEXT:    ret i1 [[CMP]]
1592   %mul = shl i32 %x, 7
1593   %cmp = icmp ne i32 %mul, 0
1594   ret i1 %cmp
1597 define <2 x i1> @icmp_shl_ne_vec(<2 x i32> %x) {
1598 ; CHECK-LABEL: @icmp_shl_ne_vec(
1599 ; CHECK-NEXT:    [[MUL_MASK:%.*]] = and <2 x i32> [[X:%.*]], <i32 33554431, i32 33554431>
1600 ; CHECK-NEXT:    [[CMP:%.*]] = icmp ne <2 x i32> [[MUL_MASK]], zeroinitializer
1601 ; CHECK-NEXT:    ret <2 x i1> [[CMP]]
1603   %mul = shl <2 x i32> %x, <i32 7, i32 7>
1604   %cmp = icmp ne <2 x i32> %mul, zeroinitializer
1605   ret <2 x i1> %cmp
1608 define <2 x i1> @icmp_shl_nuw_ne_vec(<2 x i32> %x) {
1609 ; CHECK-LABEL: @icmp_shl_nuw_ne_vec(
1610 ; CHECK-NEXT:    [[CMP:%.*]] = icmp ne <2 x i32> [[X:%.*]], <i32 2, i32 2>
1611 ; CHECK-NEXT:    ret <2 x i1> [[CMP]]
1613   %shl = shl nuw <2 x i32> %x, <i32 7, i32 7>
1614   %cmp = icmp ne <2 x i32> %shl, <i32 256, i32 256>
1615   ret <2 x i1> %cmp
1618 ; If the (mul x, C) preserved the sign and this is sign test,
1619 ; compare the LHS operand instead
1620 define i1 @icmp_mul_nsw(i32 %x) {
1621 ; CHECK-LABEL: @icmp_mul_nsw(
1622 ; CHECK-NEXT:    [[CMP:%.*]] = icmp sgt i32 [[X:%.*]], 0
1623 ; CHECK-NEXT:    ret i1 [[CMP]]
1625   %mul = mul nsw i32 %x, 12
1626   %cmp = icmp sgt i32 %mul, 0
1627   ret i1 %cmp
1630 define i1 @icmp_mul_nsw1(i32 %x) {
1631 ; CHECK-LABEL: @icmp_mul_nsw1(
1632 ; CHECK-NEXT:    [[CMP:%.*]] = icmp slt i32 [[X:%.*]], 0
1633 ; CHECK-NEXT:    ret i1 [[CMP]]
1635   %mul = mul nsw i32 %x, 12
1636   %cmp = icmp sle i32 %mul, -1
1637   ret i1 %cmp
1640 define i1 @icmp_mul_nsw_neg(i32 %x) {
1641 ; CHECK-LABEL: @icmp_mul_nsw_neg(
1642 ; CHECK-NEXT:    [[CMP:%.*]] = icmp slt i32 [[X:%.*]], 1
1643 ; CHECK-NEXT:    ret i1 [[CMP]]
1645   %mul = mul nsw i32 %x, -12
1646   %cmp = icmp sge i32 %mul, 0
1647   ret i1 %cmp
1650 define i1 @icmp_mul_nsw_neg1(i32 %x) {
1651 ; CHECK-LABEL: @icmp_mul_nsw_neg1(
1652 ; CHECK-NEXT:    [[CMP:%.*]] = icmp slt i32 [[X:%.*]], 0
1653 ; CHECK-NEXT:    ret i1 [[CMP]]
1655   %mul = mul nsw i32 %x, -12
1656   %cmp = icmp sge i32 %mul, 1
1657   ret i1 %cmp
1660 define <2 x i1> @icmp_mul_nsw_neg1_vec(<2 x i32> %x) {
1661 ; CHECK-LABEL: @icmp_mul_nsw_neg1_vec(
1662 ; CHECK-NEXT:    [[CMP:%.*]] = icmp slt <2 x i32> [[X:%.*]], zeroinitializer
1663 ; CHECK-NEXT:    ret <2 x i1> [[CMP]]
1665   %mul = mul nsw <2 x i32> %x, <i32 -12, i32 -12>
1666   %cmp = icmp sge <2 x i32> %mul, <i32 1, i32 1>
1667   ret <2 x i1> %cmp
1670 define i1 @icmp_mul_nsw_0(i32 %x) {
1671 ; CHECK-LABEL: @icmp_mul_nsw_0(
1672 ; CHECK-NEXT:    ret i1 false
1674   %mul = mul nsw i32 %x, 0
1675   %cmp = icmp sgt i32 %mul, 0
1676   ret i1 %cmp
1679 define i1 @icmp_mul(i32 %x) {
1680 ; CHECK-LABEL: @icmp_mul(
1681 ; CHECK-NEXT:    [[MUL:%.*]] = mul i32 [[X:%.*]], -12
1682 ; CHECK-NEXT:    [[CMP:%.*]] = icmp sgt i32 [[MUL]], -1
1683 ; CHECK-NEXT:    ret i1 [[CMP]]
1685   %mul = mul i32 %x, -12
1686   %cmp = icmp sge i32 %mul, 0
1687   ret i1 %cmp
1690 ; Checks for icmp (eq|ne) (mul x, C), 0
1691 define i1 @icmp_mul_neq0(i32 %x) {
1692 ; CHECK-LABEL: @icmp_mul_neq0(
1693 ; CHECK-NEXT:    [[CMP:%.*]] = icmp ne i32 [[X:%.*]], 0
1694 ; CHECK-NEXT:    ret i1 [[CMP]]
1696   %mul = mul nsw i32 %x, -12
1697   %cmp = icmp ne i32 %mul, 0
1698   ret i1 %cmp
1701 define <2 x i1> @icmp_mul_neq0_vec(<2 x i32> %x) {
1702 ; CHECK-LABEL: @icmp_mul_neq0_vec(
1703 ; CHECK-NEXT:    [[CMP:%.*]] = icmp ne <2 x i32> [[X:%.*]], zeroinitializer
1704 ; CHECK-NEXT:    ret <2 x i1> [[CMP]]
1706   %mul = mul nsw <2 x i32> %x, <i32 -12, i32 -12>
1707   %cmp = icmp ne <2 x i32> %mul, zeroinitializer
1708   ret <2 x i1> %cmp
1711 define i1 @icmp_mul_eq0(i32 %x) {
1712 ; CHECK-LABEL: @icmp_mul_eq0(
1713 ; CHECK-NEXT:    [[CMP:%.*]] = icmp eq i32 [[X:%.*]], 0
1714 ; CHECK-NEXT:    ret i1 [[CMP]]
1716   %mul = mul nsw i32 %x, 12
1717   %cmp = icmp eq i32 %mul, 0
1718   ret i1 %cmp
1721 define i1 @icmp_mul0_eq0(i32 %x) {
1722 ; CHECK-LABEL: @icmp_mul0_eq0(
1723 ; CHECK-NEXT:    ret i1 true
1725   %mul = mul i32 %x, 0
1726   %cmp = icmp eq i32 %mul, 0
1727   ret i1 %cmp
1730 define i1 @icmp_mul0_ne0(i32 %x) {
1731 ; CHECK-LABEL: @icmp_mul0_ne0(
1732 ; CHECK-NEXT:    ret i1 false
1734   %mul = mul i32 %x, 0
1735   %cmp = icmp ne i32 %mul, 0
1736   ret i1 %cmp
1739 define i1 @icmp_sub1_sge(i32 %x, i32 %y) {
1740 ; CHECK-LABEL: @icmp_sub1_sge(
1741 ; CHECK-NEXT:    [[CMP:%.*]] = icmp sgt i32 [[X:%.*]], [[Y:%.*]]
1742 ; CHECK-NEXT:    ret i1 [[CMP]]
1744   %sub = add nsw i32 %x, -1
1745   %cmp = icmp sge i32 %sub, %y
1746   ret i1 %cmp
1749 define i1 @icmp_add1_sgt(i32 %x, i32 %y) {
1750 ; CHECK-LABEL: @icmp_add1_sgt(
1751 ; CHECK-NEXT:    [[CMP:%.*]] = icmp sge i32 [[X:%.*]], [[Y:%.*]]
1752 ; CHECK-NEXT:    ret i1 [[CMP]]
1754   %add = add nsw i32 %x, 1
1755   %cmp = icmp sgt i32 %add, %y
1756   ret i1 %cmp
1759 define i1 @icmp_sub1_slt(i32 %x, i32 %y) {
1760 ; CHECK-LABEL: @icmp_sub1_slt(
1761 ; CHECK-NEXT:    [[CMP:%.*]] = icmp sle i32 [[X:%.*]], [[Y:%.*]]
1762 ; CHECK-NEXT:    ret i1 [[CMP]]
1764   %sub = add nsw i32 %x, -1
1765   %cmp = icmp slt i32 %sub, %y
1766   ret i1 %cmp
1769 define i1 @icmp_add1_sle(i32 %x, i32 %y) {
1770 ; CHECK-LABEL: @icmp_add1_sle(
1771 ; CHECK-NEXT:    [[CMP:%.*]] = icmp slt i32 [[X:%.*]], [[Y:%.*]]
1772 ; CHECK-NEXT:    ret i1 [[CMP]]
1774   %add = add nsw i32 %x, 1
1775   %cmp = icmp sle i32 %add, %y
1776   ret i1 %cmp
1779 define i1 @icmp_add20_sge_add57(i32 %x, i32 %y) {
1780 ; CHECK-LABEL: @icmp_add20_sge_add57(
1781 ; CHECK-NEXT:    [[TMP1:%.*]] = add nsw i32 [[Y:%.*]], 37
1782 ; CHECK-NEXT:    [[CMP:%.*]] = icmp sle i32 [[TMP1]], [[X:%.*]]
1783 ; CHECK-NEXT:    ret i1 [[CMP]]
1785   %1 = add nsw i32 %x, 20
1786   %2 = add nsw i32 %y, 57
1787   %cmp = icmp sge i32 %1, %2
1788   ret i1 %cmp
1791 define i1 @icmp_sub57_sge_sub20(i32 %x, i32 %y) {
1792 ; CHECK-LABEL: @icmp_sub57_sge_sub20(
1793 ; CHECK-NEXT:    [[TMP1:%.*]] = add nsw i32 [[X:%.*]], -37
1794 ; CHECK-NEXT:    [[CMP:%.*]] = icmp sge i32 [[TMP1]], [[Y:%.*]]
1795 ; CHECK-NEXT:    ret i1 [[CMP]]
1797   %1 = add nsw i32 %x, -57
1798   %2 = add nsw i32 %y, -20
1799   %cmp = icmp sge i32 %1, %2
1800   ret i1 %cmp
1803 define i1 @icmp_and_shl_neg_ne_0(i32 %A, i32 %B) {
1804 ; CHECK-LABEL: @icmp_and_shl_neg_ne_0(
1805 ; CHECK-NEXT:    [[SHL:%.*]] = shl i32 1, [[B:%.*]]
1806 ; CHECK-NEXT:    [[TMP1:%.*]] = and i32 [[SHL]], [[A:%.*]]
1807 ; CHECK-NEXT:    [[CMP:%.*]] = icmp eq i32 [[TMP1]], 0
1808 ; CHECK-NEXT:    ret i1 [[CMP]]
1810   %neg = xor i32 %A, -1
1811   %shl = shl i32 1, %B
1812   %and = and i32 %shl, %neg
1813   %cmp = icmp ne i32 %and, 0
1814   ret i1 %cmp
1817 define i1 @icmp_and_shl_neg_eq_0(i32 %A, i32 %B) {
1818 ; CHECK-LABEL: @icmp_and_shl_neg_eq_0(
1819 ; CHECK-NEXT:    [[SHL:%.*]] = shl i32 1, [[B:%.*]]
1820 ; CHECK-NEXT:    [[TMP1:%.*]] = and i32 [[SHL]], [[A:%.*]]
1821 ; CHECK-NEXT:    [[CMP:%.*]] = icmp ne i32 [[TMP1]], 0
1822 ; CHECK-NEXT:    ret i1 [[CMP]]
1824   %neg = xor i32 %A, -1
1825   %shl = shl i32 1, %B
1826   %and = and i32 %shl, %neg
1827   %cmp = icmp eq i32 %and, 0
1828   ret i1 %cmp
1831 define i1 @icmp_add_and_shr_ne_0(i32 %X) {
1832 ; CHECK-LABEL: @icmp_add_and_shr_ne_0(
1833 ; CHECK-NEXT:    [[TMP1:%.*]] = and i32 [[X:%.*]], 240
1834 ; CHECK-NEXT:    [[TOBOOL:%.*]] = icmp ne i32 [[TMP1]], 224
1835 ; CHECK-NEXT:    ret i1 [[TOBOOL]]
1837   %shr = lshr i32 %X, 4
1838   %and = and i32 %shr, 15
1839   %add = add i32 %and, -14
1840   %tobool = icmp ne i32 %add, 0
1841   ret i1 %tobool
1844 define <2 x i1> @icmp_add_and_shr_ne_0_vec(<2 x i32> %X) {
1845 ; CHECK-LABEL: @icmp_add_and_shr_ne_0_vec(
1846 ; CHECK-NEXT:    [[TMP1:%.*]] = and <2 x i32> [[X:%.*]], <i32 240, i32 240>
1847 ; CHECK-NEXT:    [[TOBOOL:%.*]] = icmp ne <2 x i32> [[TMP1]], <i32 224, i32 224>
1848 ; CHECK-NEXT:    ret <2 x i1> [[TOBOOL]]
1850   %shr = lshr <2 x i32> %X, <i32 4, i32 4>
1851   %and = and <2 x i32> %shr, <i32 15, i32 15>
1852   %add = add <2 x i32> %and, <i32 -14, i32 -14>
1853   %tobool = icmp ne <2 x i32> %add, zeroinitializer
1854   ret <2 x i1> %tobool
1857 ; Variation of the above with an extra use of the shift
1858 define i1 @icmp_and_shr_multiuse(i32 %X) {
1859 ; CHECK-LABEL: @icmp_and_shr_multiuse(
1860 ; CHECK-NEXT:    [[TMP1:%.*]] = and i32 [[X:%.*]], 240
1861 ; CHECK-NEXT:    [[TOBOOL:%.*]] = icmp ne i32 [[TMP1]], 224
1862 ; CHECK-NEXT:    [[TMP2:%.*]] = and i32 [[X]], 496
1863 ; CHECK-NEXT:    [[TOBOOL2:%.*]] = icmp ne i32 [[TMP2]], 432
1864 ; CHECK-NEXT:    [[AND3:%.*]] = and i1 [[TOBOOL]], [[TOBOOL2]]
1865 ; CHECK-NEXT:    ret i1 [[AND3]]
1867   %shr = lshr i32 %X, 4
1868   %and = and i32 %shr, 15
1869   %and2 = and i32 %shr, 31 ; second use of the shift
1870   %tobool = icmp ne i32 %and, 14
1871   %tobool2 = icmp ne i32 %and2, 27
1872   %and3 = and i1 %tobool, %tobool2
1873   ret i1 %and3
1876 define i1 @icmp_and_shr_multiuse_logical(i32 %X) {
1877 ; CHECK-LABEL: @icmp_and_shr_multiuse_logical(
1878 ; CHECK-NEXT:    [[TMP1:%.*]] = and i32 [[X:%.*]], 240
1879 ; CHECK-NEXT:    [[TOBOOL:%.*]] = icmp ne i32 [[TMP1]], 224
1880 ; CHECK-NEXT:    [[TMP2:%.*]] = and i32 [[X]], 496
1881 ; CHECK-NEXT:    [[TOBOOL2:%.*]] = icmp ne i32 [[TMP2]], 432
1882 ; CHECK-NEXT:    [[AND3:%.*]] = and i1 [[TOBOOL]], [[TOBOOL2]]
1883 ; CHECK-NEXT:    ret i1 [[AND3]]
1885   %shr = lshr i32 %X, 4
1886   %and = and i32 %shr, 15
1887   %and2 = and i32 %shr, 31 ; second use of the shift
1888   %tobool = icmp ne i32 %and, 14
1889   %tobool2 = icmp ne i32 %and2, 27
1890   %and3 = select i1 %tobool, i1 %tobool2, i1 false
1891   ret i1 %and3
1894 ; Variation of the above with an ashr
1895 define i1 @icmp_and_ashr_multiuse(i32 %X) {
1896 ; CHECK-LABEL: @icmp_and_ashr_multiuse(
1897 ; CHECK-NEXT:    [[TMP1:%.*]] = and i32 [[X:%.*]], 240
1898 ; CHECK-NEXT:    [[TOBOOL:%.*]] = icmp ne i32 [[TMP1]], 224
1899 ; CHECK-NEXT:    [[TMP2:%.*]] = and i32 [[X]], 496
1900 ; CHECK-NEXT:    [[TOBOOL2:%.*]] = icmp ne i32 [[TMP2]], 432
1901 ; CHECK-NEXT:    [[AND3:%.*]] = and i1 [[TOBOOL]], [[TOBOOL2]]
1902 ; CHECK-NEXT:    ret i1 [[AND3]]
1904   %shr = ashr i32 %X, 4
1905   %and = and i32 %shr, 15
1906   %and2 = and i32 %shr, 31 ; second use of the shift
1907   %tobool = icmp ne i32 %and, 14
1908   %tobool2 = icmp ne i32 %and2, 27
1909   %and3 = and i1 %tobool, %tobool2
1910   ret i1 %and3
1913 define i1 @icmp_and_ashr_multiuse_logical(i32 %X) {
1914 ; CHECK-LABEL: @icmp_and_ashr_multiuse_logical(
1915 ; CHECK-NEXT:    [[TMP1:%.*]] = and i32 [[X:%.*]], 240
1916 ; CHECK-NEXT:    [[TOBOOL:%.*]] = icmp ne i32 [[TMP1]], 224
1917 ; CHECK-NEXT:    [[TMP2:%.*]] = and i32 [[X]], 496
1918 ; CHECK-NEXT:    [[TOBOOL2:%.*]] = icmp ne i32 [[TMP2]], 432
1919 ; CHECK-NEXT:    [[AND3:%.*]] = and i1 [[TOBOOL]], [[TOBOOL2]]
1920 ; CHECK-NEXT:    ret i1 [[AND3]]
1922   %shr = ashr i32 %X, 4
1923   %and = and i32 %shr, 15
1924   %and2 = and i32 %shr, 31 ; second use of the shift
1925   %tobool = icmp ne i32 %and, 14
1926   %tobool2 = icmp ne i32 %and2, 27
1927   %and3 = select i1 %tobool, i1 %tobool2, i1 false
1928   ret i1 %and3
1931 define i1 @icmp_lshr_and_overshift(i8 %X) {
1932 ; CHECK-LABEL: @icmp_lshr_and_overshift(
1933 ; CHECK-NEXT:    [[TOBOOL:%.*]] = icmp ugt i8 [[X:%.*]], 31
1934 ; CHECK-NEXT:    ret i1 [[TOBOOL]]
1936   %shr = lshr i8 %X, 5
1937   %and = and i8 %shr, 15
1938   %tobool = icmp ne i8 %and, 0
1939   ret i1 %tobool
1942 ; We shouldn't simplify this because the and uses bits that are shifted in.
1943 define i1 @icmp_ashr_and_overshift(i8 %X) {
1944 ; CHECK-LABEL: @icmp_ashr_and_overshift(
1945 ; CHECK-NEXT:    [[SHR:%.*]] = ashr i8 [[X:%.*]], 5
1946 ; CHECK-NEXT:    [[AND:%.*]] = and i8 [[SHR]], 15
1947 ; CHECK-NEXT:    [[TOBOOL:%.*]] = icmp ne i8 [[AND]], 0
1948 ; CHECK-NEXT:    ret i1 [[TOBOOL]]
1950   %shr = ashr i8 %X, 5
1951   %and = and i8 %shr, 15
1952   %tobool = icmp ne i8 %and, 0
1953   ret i1 %tobool
1956 define i1 @icmp_and_ashr_neg_and_legal(i8 %x) {
1957 ; CHECK-LABEL: @icmp_and_ashr_neg_and_legal(
1958 ; CHECK-NEXT:    [[TMP1:%.*]] = and i8 [[X:%.*]], -32
1959 ; CHECK-NEXT:    [[CMP:%.*]] = icmp slt i8 [[TMP1]], 16
1960 ; CHECK-NEXT:    ret i1 [[CMP]]
1962   %ashr = ashr i8 %x, 4
1963   %and = and i8 %ashr, -2
1964   %cmp = icmp slt i8 %and, 1
1965   ret i1 %cmp
1968 ; Negative test.
1969 define i1 @icmp_and_ashr_mixed_and_shiftout(i8 %x) {
1970 ; CHECK-LABEL: @icmp_and_ashr_mixed_and_shiftout(
1971 ; CHECK-NEXT:    [[ASHR:%.*]] = ashr i8 [[X:%.*]], 4
1972 ; CHECK-NEXT:    [[AND:%.*]] = and i8 [[ASHR]], 31
1973 ; CHECK-NEXT:    [[CMP:%.*]] = icmp ugt i8 [[AND]], 8
1974 ; CHECK-NEXT:    ret i1 [[CMP]]
1976   %ashr = ashr i8 %x, 4
1977   %and = and i8 %ashr, 31
1978   %cmp = icmp ugt i8 %and, 8
1979   ret i1 %cmp
1982 define i1 @icmp_and_ashr_neg_cmp_slt_legal(i8 %x) {
1983 ; CHECK-LABEL: @icmp_and_ashr_neg_cmp_slt_legal(
1984 ; CHECK-NEXT:    [[TMP1:%.*]] = and i8 [[X:%.*]], -32
1985 ; CHECK-NEXT:    [[CMP:%.*]] = icmp slt i8 [[TMP1]], -64
1986 ; CHECK-NEXT:    ret i1 [[CMP]]
1988   %ashr = ashr i8 %x, 4
1989   %and = and i8 %ashr, -2
1990   %cmp = icmp slt i8 %and, -4
1991   ret i1 %cmp
1994 ; Negative test.
1995 define i1 @icmp_and_ashr_neg_cmp_slt_shiftout(i8 %x) {
1996 ; CHECK-LABEL: @icmp_and_ashr_neg_cmp_slt_shiftout(
1997 ; CHECK-NEXT:    [[ASHR:%.*]] = ashr i8 [[X:%.*]], 4
1998 ; CHECK-NEXT:    [[AND:%.*]] = and i8 [[ASHR]], -2
1999 ; CHECK-NEXT:    [[CMP:%.*]] = icmp slt i8 [[AND]], -68
2000 ; CHECK-NEXT:    ret i1 [[CMP]]
2002   %ashr = ashr i8 %x, 4
2003   %and = and i8 %ashr, -2
2004   %cmp = icmp slt i8 %and, -68
2005   ret i1 %cmp
2008 define i1 @icmp_and_ashr_neg_cmp_eq_legal(i8 %x) {
2009 ; CHECK-LABEL: @icmp_and_ashr_neg_cmp_eq_legal(
2010 ; CHECK-NEXT:    [[TMP1:%.*]] = and i8 [[X:%.*]], -32
2011 ; CHECK-NEXT:    [[CMP:%.*]] = icmp eq i8 [[TMP1]], -64
2012 ; CHECK-NEXT:    ret i1 [[CMP]]
2014   %ashr = ashr i8 %x, 4
2015   %and = and i8 %ashr, -2
2016   %cmp = icmp eq i8 %and, -4
2017   ret i1 %cmp
2020 define i1 @icmp_and_ashr_neg_cmp_eq_shiftout(i8 %x) {
2021 ; CHECK-LABEL: @icmp_and_ashr_neg_cmp_eq_shiftout(
2022 ; CHECK-NEXT:    ret i1 false
2024   %ashr = ashr i8 %x, 4
2025   %and = and i8 %ashr, -2
2026   %cmp = icmp eq i8 %and, -68
2027   ret i1 %cmp
2030 define i1 @icmp_and_ashr_neg_cmp_ne_shiftout(i8 %x) {
2031 ; CHECK-LABEL: @icmp_and_ashr_neg_cmp_ne_shiftout(
2032 ; CHECK-NEXT:    ret i1 true
2034   %ashr = ashr i8 %x, 4
2035   %and = and i8 %ashr, -2
2036   %cmp = icmp ne i8 %and, -68
2037   ret i1 %cmp
2040 ; PR16244
2041 define i1 @test71(i8* %x) {
2042 ; CHECK-LABEL: @test71(
2043 ; CHECK-NEXT:    ret i1 false
2045   %a = getelementptr i8, i8* %x, i64 8
2046   %b = getelementptr inbounds i8, i8* %x, i64 8
2047   %c = icmp ugt i8* %a, %b
2048   ret i1 %c
2051 define i1 @test71_as1(i8 addrspace(1)* %x) {
2052 ; CHECK-LABEL: @test71_as1(
2053 ; CHECK-NEXT:    ret i1 false
2055   %a = getelementptr i8, i8 addrspace(1)* %x, i64 8
2056   %b = getelementptr inbounds i8, i8 addrspace(1)* %x, i64 8
2057   %c = icmp ugt i8 addrspace(1)* %a, %b
2058   ret i1 %c
2061 define i1 @icmp_shl_1_V_ult_32(i32 %V) {
2062 ; CHECK-LABEL: @icmp_shl_1_V_ult_32(
2063 ; CHECK-NEXT:    [[CMP:%.*]] = icmp ult i32 [[V:%.*]], 5
2064 ; CHECK-NEXT:    ret i1 [[CMP]]
2066   %shl = shl i32 1, %V
2067   %cmp = icmp ult i32 %shl, 32
2068   ret i1 %cmp
2071 define <2 x i1> @icmp_shl_1_V_ult_32_vec(<2 x i32> %V) {
2072 ; CHECK-LABEL: @icmp_shl_1_V_ult_32_vec(
2073 ; CHECK-NEXT:    [[CMP:%.*]] = icmp ult <2 x i32> [[V:%.*]], <i32 5, i32 5>
2074 ; CHECK-NEXT:    ret <2 x i1> [[CMP]]
2076   %shl = shl <2 x i32> <i32 1, i32 1>, %V
2077   %cmp = icmp ult <2 x i32> %shl, <i32 32, i32 32>
2078   ret <2 x i1> %cmp
2081 define i1 @icmp_shl_1_V_eq_32(i32 %V) {
2082 ; CHECK-LABEL: @icmp_shl_1_V_eq_32(
2083 ; CHECK-NEXT:    [[CMP:%.*]] = icmp eq i32 [[V:%.*]], 5
2084 ; CHECK-NEXT:    ret i1 [[CMP]]
2086   %shl = shl i32 1, %V
2087   %cmp = icmp eq i32 %shl, 32
2088   ret i1 %cmp
2091 define <2 x i1> @icmp_shl_1_V_eq_32_vec(<2 x i32> %V) {
2092 ; CHECK-LABEL: @icmp_shl_1_V_eq_32_vec(
2093 ; CHECK-NEXT:    [[CMP:%.*]] = icmp eq <2 x i32> [[V:%.*]], <i32 5, i32 5>
2094 ; CHECK-NEXT:    ret <2 x i1> [[CMP]]
2096   %shl = shl <2 x i32> <i32 1, i32 1>, %V
2097   %cmp = icmp eq <2 x i32> %shl, <i32 32, i32 32>
2098   ret <2 x i1> %cmp
2101 define i1 @icmp_shl_1_V_ult_30(i32 %V) {
2102 ; CHECK-LABEL: @icmp_shl_1_V_ult_30(
2103 ; CHECK-NEXT:    [[CMP:%.*]] = icmp ult i32 [[V:%.*]], 5
2104 ; CHECK-NEXT:    ret i1 [[CMP]]
2106   %shl = shl i32 1, %V
2107   %cmp = icmp ult i32 %shl, 30
2108   ret i1 %cmp
2111 define <2 x i1> @icmp_shl_1_V_ult_30_vec(<2 x i32> %V) {
2112 ; CHECK-LABEL: @icmp_shl_1_V_ult_30_vec(
2113 ; CHECK-NEXT:    [[CMP:%.*]] = icmp ult <2 x i32> [[V:%.*]], <i32 5, i32 5>
2114 ; CHECK-NEXT:    ret <2 x i1> [[CMP]]
2116   %shl = shl <2 x i32> <i32 1, i32 1>, %V
2117   %cmp = icmp ult <2 x i32> %shl, <i32 30, i32 30>
2118   ret <2 x i1> %cmp
2121 define i1 @icmp_shl_1_V_ugt_30(i32 %V) {
2122 ; CHECK-LABEL: @icmp_shl_1_V_ugt_30(
2123 ; CHECK-NEXT:    [[CMP:%.*]] = icmp ugt i32 [[V:%.*]], 4
2124 ; CHECK-NEXT:    ret i1 [[CMP]]
2126   %shl = shl i32 1, %V
2127   %cmp = icmp ugt i32 %shl, 30
2128   ret i1 %cmp
2131 define <2 x i1> @icmp_shl_1_V_ugt_30_vec(<2 x i32> %V) {
2132 ; CHECK-LABEL: @icmp_shl_1_V_ugt_30_vec(
2133 ; CHECK-NEXT:    [[CMP:%.*]] = icmp ugt <2 x i32> [[V:%.*]], <i32 4, i32 4>
2134 ; CHECK-NEXT:    ret <2 x i1> [[CMP]]
2136   %shl = shl <2 x i32> <i32 1, i32 1>, %V
2137   %cmp = icmp ugt <2 x i32> %shl, <i32 30, i32 30>
2138   ret <2 x i1> %cmp
2141 define i1 @icmp_shl_1_V_ule_30(i32 %V) {
2142 ; CHECK-LABEL: @icmp_shl_1_V_ule_30(
2143 ; CHECK-NEXT:    [[CMP:%.*]] = icmp ult i32 [[V:%.*]], 5
2144 ; CHECK-NEXT:    ret i1 [[CMP]]
2146   %shl = shl i32 1, %V
2147   %cmp = icmp ule i32 %shl, 30
2148   ret i1 %cmp
2151 define <2 x i1> @icmp_shl_1_V_ule_30_vec(<2 x i32> %V) {
2152 ; CHECK-LABEL: @icmp_shl_1_V_ule_30_vec(
2153 ; CHECK-NEXT:    [[CMP:%.*]] = icmp ult <2 x i32> [[V:%.*]], <i32 5, i32 5>
2154 ; CHECK-NEXT:    ret <2 x i1> [[CMP]]
2156   %shl = shl <2 x i32> <i32 1, i32 1>, %V
2157   %cmp = icmp ule <2 x i32> %shl, <i32 30, i32 30>
2158   ret <2 x i1> %cmp
2161 define i1 @icmp_shl_1_V_uge_30(i32 %V) {
2162 ; CHECK-LABEL: @icmp_shl_1_V_uge_30(
2163 ; CHECK-NEXT:    [[CMP:%.*]] = icmp ugt i32 [[V:%.*]], 4
2164 ; CHECK-NEXT:    ret i1 [[CMP]]
2166   %shl = shl i32 1, %V
2167   %cmp = icmp uge i32 %shl, 30
2168   ret i1 %cmp
2171 define <2 x i1> @icmp_shl_1_V_uge_30_vec(<2 x i32> %V) {
2172 ; CHECK-LABEL: @icmp_shl_1_V_uge_30_vec(
2173 ; CHECK-NEXT:    [[CMP:%.*]] = icmp ugt <2 x i32> [[V:%.*]], <i32 4, i32 4>
2174 ; CHECK-NEXT:    ret <2 x i1> [[CMP]]
2176   %shl = shl <2 x i32> <i32 1, i32 1>, %V
2177   %cmp = icmp uge <2 x i32> %shl, <i32 30, i32 30>
2178   ret <2 x i1> %cmp
2181 define i1 @icmp_shl_1_V_uge_2147483648(i32 %V) {
2182 ; CHECK-LABEL: @icmp_shl_1_V_uge_2147483648(
2183 ; CHECK-NEXT:    [[CMP:%.*]] = icmp eq i32 [[V:%.*]], 31
2184 ; CHECK-NEXT:    ret i1 [[CMP]]
2186   %shl = shl i32 1, %V
2187   %cmp = icmp uge i32 %shl, 2147483648
2188   ret i1 %cmp
2191 define <2 x i1> @icmp_shl_1_V_uge_2147483648_vec(<2 x i32> %V) {
2192 ; CHECK-LABEL: @icmp_shl_1_V_uge_2147483648_vec(
2193 ; CHECK-NEXT:    [[CMP:%.*]] = icmp eq <2 x i32> [[V:%.*]], <i32 31, i32 31>
2194 ; CHECK-NEXT:    ret <2 x i1> [[CMP]]
2196   %shl = shl <2 x i32> <i32 1, i32 1>, %V
2197   %cmp = icmp uge <2 x i32> %shl, <i32 2147483648, i32 2147483648>
2198   ret <2 x i1> %cmp
2201 define i1 @icmp_shl_1_V_ult_2147483648(i32 %V) {
2202 ; CHECK-LABEL: @icmp_shl_1_V_ult_2147483648(
2203 ; CHECK-NEXT:    [[CMP:%.*]] = icmp ne i32 [[V:%.*]], 31
2204 ; CHECK-NEXT:    ret i1 [[CMP]]
2206   %shl = shl i32 1, %V
2207   %cmp = icmp ult i32 %shl, 2147483648
2208   ret i1 %cmp
2211 define <2 x i1> @icmp_shl_1_V_ult_2147483648_vec(<2 x i32> %V) {
2212 ; CHECK-LABEL: @icmp_shl_1_V_ult_2147483648_vec(
2213 ; CHECK-NEXT:    [[CMP:%.*]] = icmp ne <2 x i32> [[V:%.*]], <i32 31, i32 31>
2214 ; CHECK-NEXT:    ret <2 x i1> [[CMP]]
2216   %shl = shl <2 x i32> <i32 1, i32 1>, %V
2217   %cmp = icmp ult <2 x i32> %shl, <i32 2147483648, i32 2147483648>
2218   ret <2 x i1> %cmp
2221 define i1 @or_icmp_eq_B_0_icmp_ult_A_B(i64 %a, i64 %b) {
2222 ; CHECK-LABEL: @or_icmp_eq_B_0_icmp_ult_A_B(
2223 ; CHECK-NEXT:    [[TMP1:%.*]] = add i64 [[B:%.*]], -1
2224 ; CHECK-NEXT:    [[TMP2:%.*]] = icmp uge i64 [[TMP1]], [[A:%.*]]
2225 ; CHECK-NEXT:    ret i1 [[TMP2]]
2227   %1 = icmp eq i64 %b, 0
2228   %2 = icmp ult i64 %a, %b
2229   %3 = or i1 %1, %2
2230   ret i1 %3
2233 define i1 @or_icmp_eq_B_0_icmp_ult_A_B_logical(i64 %a, i64 %b) {
2234 ; CHECK-LABEL: @or_icmp_eq_B_0_icmp_ult_A_B_logical(
2235 ; CHECK-NEXT:    [[TMP1:%.*]] = icmp eq i64 [[B:%.*]], 0
2236 ; CHECK-NEXT:    [[TMP2:%.*]] = icmp ult i64 [[A:%.*]], [[B]]
2237 ; CHECK-NEXT:    [[TMP3:%.*]] = select i1 [[TMP1]], i1 true, i1 [[TMP2]]
2238 ; CHECK-NEXT:    ret i1 [[TMP3]]
2240   %1 = icmp eq i64 %b, 0
2241   %2 = icmp ult i64 %a, %b
2242   %3 = select i1 %1, i1 true, i1 %2
2243   ret i1 %3
2246 define <2 x i1> @or_icmp_eq_B_0_icmp_ult_A_B_uniform(<2 x i64> %a, <2 x i64> %b) {
2247 ; CHECK-LABEL: @or_icmp_eq_B_0_icmp_ult_A_B_uniform(
2248 ; CHECK-NEXT:    [[TMP1:%.*]] = add <2 x i64> [[B:%.*]], <i64 -1, i64 -1>
2249 ; CHECK-NEXT:    [[TMP2:%.*]] = icmp uge <2 x i64> [[TMP1]], [[A:%.*]]
2250 ; CHECK-NEXT:    ret <2 x i1> [[TMP2]]
2252   %1 = icmp eq <2 x i64> %b, zeroinitializer
2253   %2 = icmp ult <2 x i64> %a, %b
2254   %3 = or <2 x i1> %1, %2
2255   ret <2 x i1> %3
2258 define <2 x i1> @or_icmp_eq_B_0_icmp_ult_A_B_undef(<2 x i64> %a, <2 x i64> %b) {
2259 ; CHECK-LABEL: @or_icmp_eq_B_0_icmp_ult_A_B_undef(
2260 ; CHECK-NEXT:    [[TMP1:%.*]] = add <2 x i64> [[B:%.*]], <i64 -1, i64 -1>
2261 ; CHECK-NEXT:    [[TMP2:%.*]] = icmp uge <2 x i64> [[TMP1]], [[A:%.*]]
2262 ; CHECK-NEXT:    ret <2 x i1> [[TMP2]]
2264   %1 = icmp eq <2 x i64> %b, <i64 0, i64 undef>
2265   %2 = icmp ult <2 x i64> %a, %b
2266   %3 = or <2 x i1> %1, %2
2267   ret <2 x i1> %3
2270 define i1 @or_icmp_ne_A_0_icmp_ne_B_0(i64 %a, i64 %b) {
2271 ; CHECK-LABEL: @or_icmp_ne_A_0_icmp_ne_B_0(
2272 ; CHECK-NEXT:    [[TMP1:%.*]] = or i64 [[A:%.*]], [[B:%.*]]
2273 ; CHECK-NEXT:    [[TMP2:%.*]] = icmp ne i64 [[TMP1]], 0
2274 ; CHECK-NEXT:    ret i1 [[TMP2]]
2276   %1 = icmp ne i64 %a, 0
2277   %2 = icmp ne i64 %b, 0
2278   %3 = or i1 %1, %2
2279   ret i1 %3
2282 define i1 @or_icmp_ne_A_0_icmp_ne_B_0_logical(i64 %a, i64 %b) {
2283 ; CHECK-LABEL: @or_icmp_ne_A_0_icmp_ne_B_0_logical(
2284 ; CHECK-NEXT:    [[TMP1:%.*]] = icmp ne i64 [[A:%.*]], 0
2285 ; CHECK-NEXT:    [[TMP2:%.*]] = icmp ne i64 [[B:%.*]], 0
2286 ; CHECK-NEXT:    [[TMP3:%.*]] = select i1 [[TMP1]], i1 true, i1 [[TMP2]]
2287 ; CHECK-NEXT:    ret i1 [[TMP3]]
2289   %1 = icmp ne i64 %a, 0
2290   %2 = icmp ne i64 %b, 0
2291   %3 = select i1 %1, i1 true, i1 %2
2292   ret i1 %3
2295 define <2 x i1> @or_icmp_ne_A_0_icmp_ne_B_0_uniform(<2 x i64> %a, <2 x i64> %b) {
2296 ; CHECK-LABEL: @or_icmp_ne_A_0_icmp_ne_B_0_uniform(
2297 ; CHECK-NEXT:    [[TMP1:%.*]] = or <2 x i64> [[A:%.*]], [[B:%.*]]
2298 ; CHECK-NEXT:    [[TMP2:%.*]] = icmp ne <2 x i64> [[TMP1]], zeroinitializer
2299 ; CHECK-NEXT:    ret <2 x i1> [[TMP2]]
2301   %1 = icmp ne <2 x i64> %a, zeroinitializer
2302   %2 = icmp ne <2 x i64> %b, zeroinitializer
2303   %3 = or <2 x i1> %1, %2
2304   ret <2 x i1> %3
2307 define <2 x i1> @or_icmp_ne_A_0_icmp_ne_B_0_undef(<2 x i64> %a, <2 x i64> %b) {
2308 ; CHECK-LABEL: @or_icmp_ne_A_0_icmp_ne_B_0_undef(
2309 ; CHECK-NEXT:    [[TMP1:%.*]] = or <2 x i64> [[A:%.*]], [[B:%.*]]
2310 ; CHECK-NEXT:    [[TMP2:%.*]] = icmp ne <2 x i64> [[TMP1]], zeroinitializer
2311 ; CHECK-NEXT:    ret <2 x i1> [[TMP2]]
2313   %1 = icmp ne <2 x i64> %a, <i64 0, i64 undef>
2314   %2 = icmp ne <2 x i64> %b, <i64 0, i64 undef>
2315   %3 = or <2 x i1> %1, %2
2316   ret <2 x i1> %3
2319 define i1 @icmp_add_ult_2(i32 %X) {
2320 ; CHECK-LABEL: @icmp_add_ult_2(
2321 ; CHECK-NEXT:    [[TMP1:%.*]] = and i32 [[X:%.*]], -2
2322 ; CHECK-NEXT:    [[CMP:%.*]] = icmp eq i32 [[TMP1]], 14
2323 ; CHECK-NEXT:    ret i1 [[CMP]]
2325   %add = add i32 %X, -14
2326   %cmp = icmp ult i32 %add, 2
2327   ret i1 %cmp
2330 define <2 x i1> @icmp_add_X_-14_ult_2_vec(<2 x i32> %X) {
2331 ; CHECK-LABEL: @icmp_add_X_-14_ult_2_vec(
2332 ; CHECK-NEXT:    [[TMP1:%.*]] = and <2 x i32> [[X:%.*]], <i32 -2, i32 -2>
2333 ; CHECK-NEXT:    [[CMP:%.*]] = icmp eq <2 x i32> [[TMP1]], <i32 14, i32 14>
2334 ; CHECK-NEXT:    ret <2 x i1> [[CMP]]
2336   %add = add <2 x i32> %X, <i32 -14, i32 -14>
2337   %cmp = icmp ult <2 x i32> %add, <i32 2, i32 2>
2338   ret <2 x i1> %cmp
2341 define i1 @icmp_sub_3_X_ult_2(i32 %X) {
2342 ; CHECK-LABEL: @icmp_sub_3_X_ult_2(
2343 ; CHECK-NEXT:    [[TMP1:%.*]] = and i32 [[X:%.*]], -2
2344 ; CHECK-NEXT:    [[CMP:%.*]] = icmp eq i32 [[TMP1]], 2
2345 ; CHECK-NEXT:    ret i1 [[CMP]]
2347   %add = sub i32 3, %X
2348   %cmp = icmp ult i32 %add, 2
2349   ret i1 %cmp
2352 define <2 x i1> @icmp_sub_3_X_ult_2_vec(<2 x i32> %X) {
2353 ; CHECK-LABEL: @icmp_sub_3_X_ult_2_vec(
2354 ; CHECK-NEXT:    [[TMP1:%.*]] = and <2 x i32> [[X:%.*]], <i32 -2, i32 -2>
2355 ; CHECK-NEXT:    [[CMP:%.*]] = icmp eq <2 x i32> [[TMP1]], <i32 2, i32 2>
2356 ; CHECK-NEXT:    ret <2 x i1> [[CMP]]
2358   %add = sub <2 x i32> <i32 3, i32 3>, %X
2359   %cmp = icmp ult <2 x i32> %add, <i32 2, i32 2>
2360   ret <2 x i1> %cmp
2363 define i1 @icmp_add_X_-14_uge_2(i32 %X) {
2364 ; CHECK-LABEL: @icmp_add_X_-14_uge_2(
2365 ; CHECK-NEXT:    [[TMP1:%.*]] = and i32 [[X:%.*]], -2
2366 ; CHECK-NEXT:    [[CMP:%.*]] = icmp ne i32 [[TMP1]], 14
2367 ; CHECK-NEXT:    ret i1 [[CMP]]
2369   %add = add i32 %X, -14
2370   %cmp = icmp uge i32 %add, 2
2371   ret i1 %cmp
2374 define <2 x i1> @icmp_add_X_-14_uge_2_vec(<2 x i32> %X) {
2375 ; CHECK-LABEL: @icmp_add_X_-14_uge_2_vec(
2376 ; CHECK-NEXT:    [[TMP1:%.*]] = and <2 x i32> [[X:%.*]], <i32 -2, i32 -2>
2377 ; CHECK-NEXT:    [[CMP:%.*]] = icmp ne <2 x i32> [[TMP1]], <i32 14, i32 14>
2378 ; CHECK-NEXT:    ret <2 x i1> [[CMP]]
2380   %add = add <2 x i32> %X, <i32 -14, i32 -14>
2381   %cmp = icmp uge <2 x i32> %add, <i32 2, i32 2>
2382   ret <2 x i1> %cmp
2385 define i1 @icmp_sub_3_X_uge_2(i32 %X) {
2386 ; CHECK-LABEL: @icmp_sub_3_X_uge_2(
2387 ; CHECK-NEXT:    [[TMP1:%.*]] = and i32 [[X:%.*]], -2
2388 ; CHECK-NEXT:    [[CMP:%.*]] = icmp ne i32 [[TMP1]], 2
2389 ; CHECK-NEXT:    ret i1 [[CMP]]
2391   %add = sub i32 3, %X
2392   %cmp = icmp uge i32 %add, 2
2393   ret i1 %cmp
2396 define <2 x i1> @icmp_sub_3_X_uge_2_vec(<2 x i32> %X) {
2397 ; CHECK-LABEL: @icmp_sub_3_X_uge_2_vec(
2398 ; CHECK-NEXT:    [[TMP1:%.*]] = and <2 x i32> [[X:%.*]], <i32 -2, i32 -2>
2399 ; CHECK-NEXT:    [[CMP:%.*]] = icmp ne <2 x i32> [[TMP1]], <i32 2, i32 2>
2400 ; CHECK-NEXT:    ret <2 x i1> [[CMP]]
2402   %add = sub <2 x i32> <i32 3, i32 3>, %X
2403   %cmp = icmp uge <2 x i32> %add, <i32 2, i32 2>
2404   ret <2 x i1> %cmp
2407 define i1 @icmp_and_X_-16_eq-16(i32 %X) {
2408 ; CHECK-LABEL: @icmp_and_X_-16_eq-16(
2409 ; CHECK-NEXT:    [[CMP:%.*]] = icmp ugt i32 [[X:%.*]], -17
2410 ; CHECK-NEXT:    ret i1 [[CMP]]
2412   %and = and i32 %X, -16
2413   %cmp = icmp eq i32 %and, -16
2414   ret i1 %cmp
2417 define <2 x i1> @icmp_and_X_-16_eq-16_vec(<2 x i32> %X) {
2418 ; CHECK-LABEL: @icmp_and_X_-16_eq-16_vec(
2419 ; CHECK-NEXT:    [[CMP:%.*]] = icmp ugt <2 x i32> [[X:%.*]], <i32 -17, i32 -17>
2420 ; CHECK-NEXT:    ret <2 x i1> [[CMP]]
2422   %and = and <2 x i32> %X, <i32 -16, i32 -16>
2423   %cmp = icmp eq <2 x i32> %and, <i32 -16, i32 -16>
2424   ret <2 x i1> %cmp
2427 define i1 @icmp_and_X_-16_ne-16(i32 %X) {
2428 ; CHECK-LABEL: @icmp_and_X_-16_ne-16(
2429 ; CHECK-NEXT:    [[CMP:%.*]] = icmp ult i32 [[X:%.*]], -16
2430 ; CHECK-NEXT:    ret i1 [[CMP]]
2432   %and = and i32 %X, -16
2433   %cmp = icmp ne i32 %and, -16
2434   ret i1 %cmp
2437 define <2 x i1> @icmp_and_X_-16_ne-16_vec(<2 x i32> %X) {
2438 ; CHECK-LABEL: @icmp_and_X_-16_ne-16_vec(
2439 ; CHECK-NEXT:    [[CMP:%.*]] = icmp ult <2 x i32> [[X:%.*]], <i32 -16, i32 -16>
2440 ; CHECK-NEXT:    ret <2 x i1> [[CMP]]
2442   %and = and <2 x i32> %X, <i32 -16, i32 -16>
2443   %cmp = icmp ne <2 x i32> %and, <i32 -16, i32 -16>
2444   ret <2 x i1> %cmp
2447 ; PR32524: https://bugs.llvm.org/show_bug.cgi?id=32524
2448 ; X | C == C --> X <=u C (when C+1 is PowerOf2).
2450 define i1 @or1_eq1(i32 %x) {
2451 ; CHECK-LABEL: @or1_eq1(
2452 ; CHECK-NEXT:    [[T1:%.*]] = icmp ult i32 [[X:%.*]], 2
2453 ; CHECK-NEXT:    ret i1 [[T1]]
2455   %t0 = or i32 %x, 1
2456   %t1 = icmp eq i32 %t0, 1
2457   ret i1 %t1
2460 ; X | C == C --> X <=u C (when C+1 is PowerOf2).
2462 define <2 x i1> @or3_eq3_vec(<2 x i8> %x) {
2463 ; CHECK-LABEL: @or3_eq3_vec(
2464 ; CHECK-NEXT:    [[T1:%.*]] = icmp ult <2 x i8> [[X:%.*]], <i8 4, i8 4>
2465 ; CHECK-NEXT:    ret <2 x i1> [[T1]]
2467   %t0 = or <2 x i8> %x, <i8 3, i8 3>
2468   %t1 = icmp eq <2 x i8> %t0, <i8 3, i8 3>
2469   ret <2 x i1> %t1
2472 ; X | C != C --> X >u C (when C+1 is PowerOf2).
2474 define i1 @or7_ne7(i32 %x) {
2475 ; CHECK-LABEL: @or7_ne7(
2476 ; CHECK-NEXT:    [[T1:%.*]] = icmp ugt i32 [[X:%.*]], 7
2477 ; CHECK-NEXT:    ret i1 [[T1]]
2479   %t0 = or i32 %x, 7
2480   %t1 = icmp ne i32 %t0, 7
2481   ret i1 %t1
2484 ; X | C != C --> X >u C (when C+1 is PowerOf2).
2486 define <2 x i1> @or63_ne63_vec(<2 x i8> %x) {
2487 ; CHECK-LABEL: @or63_ne63_vec(
2488 ; CHECK-NEXT:    [[T1:%.*]] = icmp ugt <2 x i8> [[X:%.*]], <i8 63, i8 63>
2489 ; CHECK-NEXT:    ret <2 x i1> [[T1]]
2491   %t0 = or <2 x i8> %x, <i8 63, i8 63>
2492   %t1 = icmp ne <2 x i8> %t0, <i8 63, i8 63>
2493   ret <2 x i1> %t1
2496 ; PR40611: https://bugs.llvm.org/show_bug.cgi?id=40611
2497 ; X | C == C --> (X & ~C) == 0
2499 define i1 @orC_eqC(i32 %x) {
2500 ; CHECK-LABEL: @orC_eqC(
2501 ; CHECK-NEXT:    [[TMP1:%.*]] = and i32 [[X:%.*]], -43
2502 ; CHECK-NEXT:    [[T1:%.*]] = icmp eq i32 [[TMP1]], 0
2503 ; CHECK-NEXT:    ret i1 [[T1]]
2505   %t0 = or i32 %x, 42
2506   %t1 = icmp eq i32 %t0, 42
2507   ret i1 %t1
2510 ; X | C == C --> (X & ~C) == 0
2512 define <2 x i1> @orC_eqC_vec(<2 x i8> %x) {
2513 ; CHECK-LABEL: @orC_eqC_vec(
2514 ; CHECK-NEXT:    [[TMP1:%.*]] = and <2 x i8> [[X:%.*]], <i8 -44, i8 -44>
2515 ; CHECK-NEXT:    [[T1:%.*]] = icmp eq <2 x i8> [[TMP1]], zeroinitializer
2516 ; CHECK-NEXT:    ret <2 x i1> [[T1]]
2518   %t0 = or <2 x i8> %x, <i8 43, i8 43>
2519   %t1 = icmp eq <2 x i8> %t0, <i8 43, i8 43>
2520   ret <2 x i1> %t1
2523 ; X | C != C --> (X & ~C) != 0
2525 define i1 @orC_neC(i32 %x) {
2526 ; CHECK-LABEL: @orC_neC(
2527 ; CHECK-NEXT:    [[TMP1:%.*]] = and i32 [[X:%.*]], 41
2528 ; CHECK-NEXT:    [[T1:%.*]] = icmp ne i32 [[TMP1]], 0
2529 ; CHECK-NEXT:    ret i1 [[T1]]
2531   %t0 = or i32 %x, -42
2532   %t1 = icmp ne i32 %t0, -42
2533   ret i1 %t1
2536 ; X | C != C --> (X & ~C) != 0
2538 define <2 x i1> @orC_neC_vec(<2 x i8> %x) {
2539 ; CHECK-LABEL: @orC_neC_vec(
2540 ; CHECK-NEXT:    [[TMP1:%.*]] = and <2 x i8> [[X:%.*]], <i8 42, i8 42>
2541 ; CHECK-NEXT:    [[T1:%.*]] = icmp ne <2 x i8> [[TMP1]], zeroinitializer
2542 ; CHECK-NEXT:    ret <2 x i1> [[T1]]
2544   %t0 = or <2 x i8> %x, <i8 -43, i8 -43>
2545   %t1 = icmp ne <2 x i8> %t0, <i8 -43, i8 -43>
2546   ret <2 x i1> %t1
2549 define i1 @shrink_constant(i32 %X) {
2550 ; CHECK-LABEL: @shrink_constant(
2551 ; CHECK-NEXT:    [[XOR:%.*]] = xor i32 [[X:%.*]], -12
2552 ; CHECK-NEXT:    [[CMP:%.*]] = icmp ult i32 [[XOR]], 4
2553 ; CHECK-NEXT:    ret i1 [[CMP]]
2555   %xor = xor i32 %X, -9
2556   %cmp = icmp ult i32 %xor, 4
2557   ret i1 %cmp
2560 define <2 x i1> @shrink_constant_vec(<2 x i32> %X) {
2561 ; CHECK-LABEL: @shrink_constant_vec(
2562 ; CHECK-NEXT:    [[XOR:%.*]] = xor <2 x i32> [[X:%.*]], <i32 -12, i32 -12>
2563 ; CHECK-NEXT:    [[CMP:%.*]] = icmp ult <2 x i32> [[XOR]], <i32 4, i32 4>
2564 ; CHECK-NEXT:    ret <2 x i1> [[CMP]]
2566   %xor = xor <2 x i32> %X, <i32 -9, i32 -9>
2567   %cmp = icmp ult <2 x i32> %xor, <i32 4, i32 4>
2568   ret <2 x i1> %cmp
2571 ; This test requires 3 different transforms to get to the result.
2572 define i1 @icmp_sub_-1_X_ult_4(i32 %X) {
2573 ; CHECK-LABEL: @icmp_sub_-1_X_ult_4(
2574 ; CHECK-NEXT:    [[CMP:%.*]] = icmp ugt i32 [[X:%.*]], -5
2575 ; CHECK-NEXT:    ret i1 [[CMP]]
2577   %sub = sub i32 -1, %X
2578   %cmp = icmp ult i32 %sub, 4
2579   ret i1 %cmp
2582 define <2 x i1> @icmp_xor_neg4_X_ult_4_vec(<2 x i32> %X) {
2583 ; CHECK-LABEL: @icmp_xor_neg4_X_ult_4_vec(
2584 ; CHECK-NEXT:    [[CMP:%.*]] = icmp ugt <2 x i32> [[X:%.*]], <i32 -5, i32 -5>
2585 ; CHECK-NEXT:    ret <2 x i1> [[CMP]]
2587   %xor = xor <2 x i32> %X, <i32 -4, i32 -4>
2588   %cmp = icmp ult <2 x i32> %xor, <i32 4, i32 4>
2589   ret <2 x i1> %cmp
2592 define i1 @icmp_sub_-1_X_uge_4(i32 %X) {
2593 ; CHECK-LABEL: @icmp_sub_-1_X_uge_4(
2594 ; CHECK-NEXT:    [[CMP:%.*]] = icmp ult i32 [[X:%.*]], -4
2595 ; CHECK-NEXT:    ret i1 [[CMP]]
2597   %sub = sub i32 -1, %X
2598   %cmp = icmp uge i32 %sub, 4
2599   ret i1 %cmp
2602 define <2 x i1> @icmp_xor_neg4_X_uge_4_vec(<2 x i32> %X) {
2603 ; CHECK-LABEL: @icmp_xor_neg4_X_uge_4_vec(
2604 ; CHECK-NEXT:    [[CMP:%.*]] = icmp ult <2 x i32> [[X:%.*]], <i32 -4, i32 -4>
2605 ; CHECK-NEXT:    ret <2 x i1> [[CMP]]
2607   %xor = xor <2 x i32> %X, <i32 -4, i32 -4>
2608   %cmp = icmp uge <2 x i32> %xor, <i32 4, i32 4>
2609   ret <2 x i1> %cmp
2612 define <2 x i1> @xor_ult(<2 x i8> %x) {
2613 ; CHECK-LABEL: @xor_ult(
2614 ; CHECK-NEXT:    [[R:%.*]] = icmp ugt <2 x i8> [[X:%.*]], <i8 3, i8 3>
2615 ; CHECK-NEXT:    ret <2 x i1> [[R]]
2617   %xor = xor <2 x i8> %x, <i8 -4, i8 -4>
2618   %r = icmp ult <2 x i8> %xor, <i8 -4, i8 -4>
2619   ret <2 x i1> %r
2622 define i1 @xor_ult_extra_use(i8 %x, i8* %p) {
2623 ; CHECK-LABEL: @xor_ult_extra_use(
2624 ; CHECK-NEXT:    [[XOR:%.*]] = xor i8 [[X:%.*]], -32
2625 ; CHECK-NEXT:    store i8 [[XOR]], i8* [[P:%.*]], align 1
2626 ; CHECK-NEXT:    [[R:%.*]] = icmp ugt i8 [[X]], 31
2627 ; CHECK-NEXT:    ret i1 [[R]]
2629   %xor = xor i8 %x, -32
2630   store i8 %xor, i8* %p
2631   %r = icmp ult i8 %xor, -32
2632   ret i1 %r
2635 define <2 x i1> @xor_ugt(<2 x i8> %x) {
2636 ; CHECK-LABEL: @xor_ugt(
2637 ; CHECK-NEXT:    [[R:%.*]] = icmp ugt <2 x i8> [[X:%.*]], <i8 7, i8 7>
2638 ; CHECK-NEXT:    ret <2 x i1> [[R]]
2640   %xor = xor <2 x i8> %x, <i8 7, i8 7>
2641   %r = icmp ugt <2 x i8> %xor, <i8 7, i8 7>
2642   ret <2 x i1> %r
2645 define i1 @xor_ugt_extra_use(i8 %x, i8* %p) {
2646 ; CHECK-LABEL: @xor_ugt_extra_use(
2647 ; CHECK-NEXT:    [[XOR:%.*]] = xor i8 [[X:%.*]], 63
2648 ; CHECK-NEXT:    store i8 [[XOR]], i8* [[P:%.*]], align 1
2649 ; CHECK-NEXT:    [[R:%.*]] = icmp ugt i8 [[X]], 63
2650 ; CHECK-NEXT:    ret i1 [[R]]
2652   %xor = xor i8 %x, 63
2653   store i8 %xor, i8* %p
2654   %r = icmp ugt i8 %xor, 63
2655   ret i1 %r
2658 define i1 @icmp_swap_operands_for_cse(i32 %X, i32 %Y) {
2659 ; CHECK-LABEL: @icmp_swap_operands_for_cse(
2660 ; CHECK-NEXT:  entry:
2661 ; CHECK-NEXT:    [[SUB:%.*]] = sub i32 [[X:%.*]], [[Y:%.*]]
2662 ; CHECK-NEXT:    [[CMP:%.*]] = icmp ult i32 [[X]], [[Y]]
2663 ; CHECK-NEXT:    br i1 [[CMP]], label [[TRUE:%.*]], label [[FALSE:%.*]]
2664 ; CHECK:       true:
2665 ; CHECK-NEXT:    [[TMP0:%.*]] = and i32 [[SUB]], 1
2666 ; CHECK-NEXT:    br label [[END:%.*]]
2667 ; CHECK:       false:
2668 ; CHECK-NEXT:    [[TMP1:%.*]] = and i32 [[SUB]], 16
2669 ; CHECK-NEXT:    br label [[END]]
2670 ; CHECK:       end:
2671 ; CHECK-NEXT:    [[RES_IN:%.*]] = phi i32 [ [[TMP0]], [[TRUE]] ], [ [[TMP1]], [[FALSE]] ]
2672 ; CHECK-NEXT:    [[RES:%.*]] = icmp ne i32 [[RES_IN]], 0
2673 ; CHECK-NEXT:    ret i1 [[RES]]
2675 entry:
2676   %sub = sub i32 %X, %Y
2677   %cmp = icmp ugt i32 %Y, %X
2678   br i1 %cmp, label %true, label %false
2679 true:
2680   %restrue = trunc i32 %sub to i1
2681   br label %end
2682 false:
2683   %shift = lshr i32 %sub, 4
2684   %resfalse = trunc i32 %shift to i1
2685   br label %end
2686 end:
2687   %res = phi i1 [%restrue, %true], [%resfalse, %false]
2688   ret i1 %res
2691 define i1 @icmp_swap_operands_for_cse2(i32 %X, i32 %Y) {
2692 ; CHECK-LABEL: @icmp_swap_operands_for_cse2(
2693 ; CHECK-NEXT:  entry:
2694 ; CHECK-NEXT:    [[CMP:%.*]] = icmp ult i32 [[X:%.*]], [[Y:%.*]]
2695 ; CHECK-NEXT:    br i1 [[CMP]], label [[TRUE:%.*]], label [[FALSE:%.*]]
2696 ; CHECK:       true:
2697 ; CHECK-NEXT:    [[SUB:%.*]] = sub i32 [[X]], [[Y]]
2698 ; CHECK-NEXT:    [[SUB1:%.*]] = sub i32 [[X]], [[Y]]
2699 ; CHECK-NEXT:    [[ADD:%.*]] = add i32 [[SUB]], [[SUB1]]
2700 ; CHECK-NEXT:    br label [[END:%.*]]
2701 ; CHECK:       false:
2702 ; CHECK-NEXT:    [[SUB2:%.*]] = sub i32 [[Y]], [[X]]
2703 ; CHECK-NEXT:    br label [[END]]
2704 ; CHECK:       end:
2705 ; CHECK-NEXT:    [[RES_IN_IN:%.*]] = phi i32 [ [[ADD]], [[TRUE]] ], [ [[SUB2]], [[FALSE]] ]
2706 ; CHECK-NEXT:    [[RES_IN:%.*]] = and i32 [[RES_IN_IN]], 1
2707 ; CHECK-NEXT:    [[RES:%.*]] = icmp ne i32 [[RES_IN]], 0
2708 ; CHECK-NEXT:    ret i1 [[RES]]
2710 entry:
2711   %cmp = icmp ugt i32 %Y, %X
2712   br i1 %cmp, label %true, label %false
2713 true:
2714   %sub = sub i32 %X, %Y
2715   %sub1 = sub i32 %X, %Y
2716   %add = add i32 %sub, %sub1
2717   %restrue = trunc i32 %add to i1
2718   br label %end
2719 false:
2720   %sub2 = sub i32 %Y, %X
2721   %resfalse = trunc i32 %sub2 to i1
2722   br label %end
2723 end:
2724   %res = phi i1 [%restrue, %true], [%resfalse, %false]
2725   ret i1 %res
2728 define i1 @icmp_do_not_swap_operands_for_cse(i32 %X, i32 %Y) {
2729 ; CHECK-LABEL: @icmp_do_not_swap_operands_for_cse(
2730 ; CHECK-NEXT:  entry:
2731 ; CHECK-NEXT:    [[CMP:%.*]] = icmp ugt i32 [[Y:%.*]], [[X:%.*]]
2732 ; CHECK-NEXT:    br i1 [[CMP]], label [[TRUE:%.*]], label [[FALSE:%.*]]
2733 ; CHECK:       true:
2734 ; CHECK-NEXT:    [[SUB:%.*]] = sub i32 [[X]], [[Y]]
2735 ; CHECK-NEXT:    br label [[END:%.*]]
2736 ; CHECK:       false:
2737 ; CHECK-NEXT:    [[SUB2:%.*]] = sub i32 [[Y]], [[X]]
2738 ; CHECK-NEXT:    br label [[END]]
2739 ; CHECK:       end:
2740 ; CHECK-NEXT:    [[RES_IN_IN:%.*]] = phi i32 [ [[SUB]], [[TRUE]] ], [ [[SUB2]], [[FALSE]] ]
2741 ; CHECK-NEXT:    [[RES_IN:%.*]] = and i32 [[RES_IN_IN]], 1
2742 ; CHECK-NEXT:    [[RES:%.*]] = icmp ne i32 [[RES_IN]], 0
2743 ; CHECK-NEXT:    ret i1 [[RES]]
2745 entry:
2746   %cmp = icmp ugt i32 %Y, %X
2747   br i1 %cmp, label %true, label %false
2748 true:
2749   %sub = sub i32 %X, %Y
2750   %restrue = trunc i32 %sub to i1
2751   br label %end
2752 false:
2753   %sub2 = sub i32 %Y, %X
2754   %resfalse = trunc i32 %sub2 to i1
2755   br label %end
2756 end:
2757   %res = phi i1 [%restrue, %true], [%resfalse, %false]
2758   ret i1 %res
2761 define i1 @icmp_lshr_lshr_eq(i32 %a, i32 %b) {
2762 ; CHECK-LABEL: @icmp_lshr_lshr_eq(
2763 ; CHECK-NEXT:    [[Z_UNSHIFTED:%.*]] = xor i32 [[A:%.*]], [[B:%.*]]
2764 ; CHECK-NEXT:    [[Z:%.*]] = icmp ult i32 [[Z_UNSHIFTED]], 1073741824
2765 ; CHECK-NEXT:    ret i1 [[Z]]
2767   %x = lshr i32 %a, 30
2768   %y = lshr i32 %b, 30
2769   %z = icmp eq i32 %x, %y
2770   ret i1 %z
2773 define i1 @icmp_ashr_ashr_ne(i32 %a, i32 %b) {
2774 ; CHECK-LABEL: @icmp_ashr_ashr_ne(
2775 ; CHECK-NEXT:    [[Z_UNSHIFTED:%.*]] = xor i32 [[A:%.*]], [[B:%.*]]
2776 ; CHECK-NEXT:    [[Z:%.*]] = icmp ugt i32 [[Z_UNSHIFTED]], 255
2777 ; CHECK-NEXT:    ret i1 [[Z]]
2779   %x = ashr i32 %a, 8
2780   %y = ashr i32 %b, 8
2781   %z = icmp ne i32 %x, %y
2782   ret i1 %z
2785 define i1 @icmp_neg_cst_slt(i32 %a) {
2786 ; CHECK-LABEL: @icmp_neg_cst_slt(
2787 ; CHECK-NEXT:    [[TMP1:%.*]] = icmp sgt i32 [[A:%.*]], 10
2788 ; CHECK-NEXT:    ret i1 [[TMP1]]
2790   %1 = sub nsw i32 0, %a
2791   %2 = icmp slt i32 %1, -10
2792   ret i1 %2
2795 define i1 @icmp_and_or_lshr(i32 %x, i32 %y) {
2796 ; CHECK-LABEL: @icmp_and_or_lshr(
2797 ; CHECK-NEXT:    [[SHF1:%.*]] = shl nuw i32 1, [[Y:%.*]]
2798 ; CHECK-NEXT:    [[OR2:%.*]] = or i32 [[SHF1]], 1
2799 ; CHECK-NEXT:    [[AND3:%.*]] = and i32 [[OR2]], [[X:%.*]]
2800 ; CHECK-NEXT:    [[RET:%.*]] = icmp ne i32 [[AND3]], 0
2801 ; CHECK-NEXT:    ret i1 [[RET]]
2803   %shf = lshr i32 %x, %y
2804   %or = or i32 %shf, %x
2805   %and = and i32 %or, 1
2806   %ret = icmp ne i32 %and, 0
2807   ret i1 %ret
2810 define <2 x i1> @icmp_and_or_lshr_vec(<2 x i32> %x, <2 x i32> %y) {
2811 ; CHECK-LABEL: @icmp_and_or_lshr_vec(
2812 ; CHECK-NEXT:    [[SHF:%.*]] = lshr <2 x i32> [[X:%.*]], [[Y:%.*]]
2813 ; CHECK-NEXT:    [[OR:%.*]] = or <2 x i32> [[SHF]], [[X]]
2814 ; CHECK-NEXT:    [[RET:%.*]] = trunc <2 x i32> [[OR]] to <2 x i1>
2815 ; CHECK-NEXT:    ret <2 x i1> [[RET]]
2817   %shf = lshr <2 x i32> %x, %y
2818   %or = or <2 x i32> %shf, %x
2819   %and = and <2 x i32> %or, <i32 1, i32 1>
2820   %ret = icmp ne <2 x i32> %and, zeroinitializer
2821   ret <2 x i1> %ret
2824 define <2 x i1> @icmp_and_or_lshr_vec_commute(<2 x i32> %xp, <2 x i32> %y) {
2825 ; CHECK-LABEL: @icmp_and_or_lshr_vec_commute(
2826 ; CHECK-NEXT:    [[X:%.*]] = srem <2 x i32> [[XP:%.*]], <i32 42, i32 42>
2827 ; CHECK-NEXT:    [[SHF:%.*]] = lshr <2 x i32> [[X]], [[Y:%.*]]
2828 ; CHECK-NEXT:    [[OR:%.*]] = or <2 x i32> [[X]], [[SHF]]
2829 ; CHECK-NEXT:    [[RET:%.*]] = trunc <2 x i32> [[OR]] to <2 x i1>
2830 ; CHECK-NEXT:    ret <2 x i1> [[RET]]
2832   %x = srem <2 x i32> %xp, <i32 42, i32 -42> ; prevent complexity-based canonicalization
2833   %shf = lshr <2 x i32> %x, %y
2834   %or = or <2 x i32> %x, %shf
2835   %and = and <2 x i32> %or, <i32 1, i32 1>
2836   %ret = icmp ne <2 x i32> %and, zeroinitializer
2837   ret <2 x i1> %ret
2840 define i1 @icmp_and_or_lshr_cst(i32 %x) {
2841 ; CHECK-LABEL: @icmp_and_or_lshr_cst(
2842 ; CHECK-NEXT:    [[AND1:%.*]] = and i32 [[X:%.*]], 3
2843 ; CHECK-NEXT:    [[RET:%.*]] = icmp ne i32 [[AND1]], 0
2844 ; CHECK-NEXT:    ret i1 [[RET]]
2846   %shf = lshr i32 %x, 1
2847   %or = or i32 %shf, %x
2848   %and = and i32 %or, 1
2849   %ret = icmp ne i32 %and, 0
2850   ret i1 %ret
2853 define <2 x i1> @icmp_and_or_lshr_cst_vec(<2 x i32> %x) {
2854 ; CHECK-LABEL: @icmp_and_or_lshr_cst_vec(
2855 ; CHECK-NEXT:    [[TMP1:%.*]] = and <2 x i32> [[X:%.*]], <i32 3, i32 3>
2856 ; CHECK-NEXT:    [[RET:%.*]] = icmp ne <2 x i32> [[TMP1]], zeroinitializer
2857 ; CHECK-NEXT:    ret <2 x i1> [[RET]]
2859   %shf = lshr <2 x i32> %x, <i32 1, i32 1>
2860   %or = or <2 x i32> %shf, %x
2861   %and = and <2 x i32> %or, <i32 1, i32 1>
2862   %ret = icmp ne <2 x i32> %and, zeroinitializer
2863   ret <2 x i1> %ret
2866 define <2 x i1> @icmp_and_or_lshr_cst_vec_nonuniform(<2 x i32> %x) {
2867 ; CHECK-LABEL: @icmp_and_or_lshr_cst_vec_nonuniform(
2868 ; CHECK-NEXT:    [[TMP1:%.*]] = and <2 x i32> [[X:%.*]], <i32 3, i32 5>
2869 ; CHECK-NEXT:    [[RET:%.*]] = icmp ne <2 x i32> [[TMP1]], zeroinitializer
2870 ; CHECK-NEXT:    ret <2 x i1> [[RET]]
2872   %shf = lshr <2 x i32> %x, <i32 1, i32 2>
2873   %or = or <2 x i32> %shf, %x
2874   %and = and <2 x i32> %or, <i32 1, i32 1>
2875   %ret = icmp ne <2 x i32> %and, zeroinitializer
2876   ret <2 x i1> %ret
2879 define <2 x i1> @icmp_and_or_lshr_cst_vec_undef(<2 x i32> %x) {
2880 ; CHECK-LABEL: @icmp_and_or_lshr_cst_vec_undef(
2881 ; CHECK-NEXT:    [[TMP1:%.*]] = and <2 x i32> [[X:%.*]], <i32 3, i32 poison>
2882 ; CHECK-NEXT:    [[RET:%.*]] = icmp ne <2 x i32> [[TMP1]], zeroinitializer
2883 ; CHECK-NEXT:    ret <2 x i1> [[RET]]
2885   %shf = lshr <2 x i32> %x, <i32 1, i32 undef>
2886   %or = or <2 x i32> %shf, %x
2887   %and = and <2 x i32> %or, <i32 1, i32 1>
2888   %ret = icmp ne <2 x i32> %and, zeroinitializer
2889   ret <2 x i1> %ret
2892 define <2 x i1> @icmp_and_or_lshr_cst_vec_commute(<2 x i32> %xp) {
2893 ; CHECK-LABEL: @icmp_and_or_lshr_cst_vec_commute(
2894 ; CHECK-NEXT:    [[X:%.*]] = srem <2 x i32> [[XP:%.*]], <i32 42, i32 42>
2895 ; CHECK-NEXT:    [[TMP1:%.*]] = and <2 x i32> [[X]], <i32 3, i32 3>
2896 ; CHECK-NEXT:    [[RET:%.*]] = icmp ne <2 x i32> [[TMP1]], zeroinitializer
2897 ; CHECK-NEXT:    ret <2 x i1> [[RET]]
2899   %x = srem <2 x i32> %xp, <i32 42, i32 -42> ; prevent complexity-based canonicalization
2900   %shf = lshr <2 x i32> %x, <i32 1, i32 1>
2901   %or = or <2 x i32> %x, %shf
2902   %and = and <2 x i32> %or, <i32 1, i32 1>
2903   %ret = icmp ne <2 x i32> %and, zeroinitializer
2904   ret <2 x i1> %ret
2907 define <2 x i1> @icmp_and_or_lshr_cst_vec_nonuniform_commute(<2 x i32> %xp) {
2908 ; CHECK-LABEL: @icmp_and_or_lshr_cst_vec_nonuniform_commute(
2909 ; CHECK-NEXT:    [[X:%.*]] = srem <2 x i32> [[XP:%.*]], <i32 42, i32 42>
2910 ; CHECK-NEXT:    [[TMP1:%.*]] = and <2 x i32> [[X]], <i32 3, i32 5>
2911 ; CHECK-NEXT:    [[RET:%.*]] = icmp ne <2 x i32> [[TMP1]], zeroinitializer
2912 ; CHECK-NEXT:    ret <2 x i1> [[RET]]
2914   %x = srem <2 x i32> %xp, <i32 42, i32 -42> ; prevent complexity-based canonicalization
2915   %shf = lshr <2 x i32> %x, <i32 1, i32 2>
2916   %or = or <2 x i32> %x, %shf
2917   %and = and <2 x i32> %or, <i32 1, i32 1>
2918   %ret = icmp ne <2 x i32> %and, zeroinitializer
2919   ret <2 x i1> %ret
2922 define <2 x i1> @icmp_and_or_lshr_cst_vec_undef_commute(<2 x i32> %xp) {
2923 ; CHECK-LABEL: @icmp_and_or_lshr_cst_vec_undef_commute(
2924 ; CHECK-NEXT:    [[X:%.*]] = srem <2 x i32> [[XP:%.*]], <i32 42, i32 42>
2925 ; CHECK-NEXT:    [[TMP1:%.*]] = and <2 x i32> [[X]], <i32 3, i32 poison>
2926 ; CHECK-NEXT:    [[RET:%.*]] = icmp ne <2 x i32> [[TMP1]], zeroinitializer
2927 ; CHECK-NEXT:    ret <2 x i1> [[RET]]
2929   %x = srem <2 x i32> %xp, <i32 42, i32 -42> ; prevent complexity-based canonicalization
2930   %shf = lshr <2 x i32> %x, <i32 1, i32 undef>
2931   %or = or <2 x i32> %x, %shf
2932   %and = and <2 x i32> %or, <i32 1, i32 1>
2933   %ret = icmp ne <2 x i32> %and, zeroinitializer
2934   ret <2 x i1> %ret
2937 define i1 @shl_ap1_zero_ap2_non_zero_2(i32 %a) {
2938 ; CHECK-LABEL: @shl_ap1_zero_ap2_non_zero_2(
2939 ; CHECK-NEXT:    [[CMP:%.*]] = icmp ugt i32 [[A:%.*]], 29
2940 ; CHECK-NEXT:    ret i1 [[CMP]]
2942   %shl = shl i32 4, %a
2943   %cmp = icmp eq i32 %shl, 0
2944   ret i1 %cmp
2947 define <2 x i1> @shl_ap1_zero_ap2_non_zero_2_vec(<2 x i32> %a) {
2948 ; CHECK-LABEL: @shl_ap1_zero_ap2_non_zero_2_vec(
2949 ; CHECK-NEXT:    [[CMP:%.*]] = icmp ugt <2 x i32> [[A:%.*]], <i32 29, i32 29>
2950 ; CHECK-NEXT:    ret <2 x i1> [[CMP]]
2952   %shl = shl <2 x i32> <i32 4, i32 4>, %a
2953   %cmp = icmp eq <2 x i32> %shl, zeroinitializer
2954   ret <2 x i1> %cmp
2957 define <2 x i1> @shl_ap1_zero_ap2_non_zero_2_vec_nonuniform(<2 x i32> %a) {
2958 ; CHECK-LABEL: @shl_ap1_zero_ap2_non_zero_2_vec_nonuniform(
2959 ; CHECK-NEXT:    [[SHL:%.*]] = shl <2 x i32> <i32 4, i32 5>, [[A:%.*]]
2960 ; CHECK-NEXT:    [[CMP:%.*]] = icmp eq <2 x i32> [[SHL]], zeroinitializer
2961 ; CHECK-NEXT:    ret <2 x i1> [[CMP]]
2963   %shl = shl <2 x i32> <i32 4, i32 5>, %a
2964   %cmp = icmp eq <2 x i32> %shl, zeroinitializer
2965   ret <2 x i1> %cmp
2968 define i1 @shl_ap1_zero_ap2_non_zero_4(i32 %a) {
2969 ; CHECK-LABEL: @shl_ap1_zero_ap2_non_zero_4(
2970 ; CHECK-NEXT:    [[CMP:%.*]] = icmp ugt i32 [[A:%.*]], 30
2971 ; CHECK-NEXT:    ret i1 [[CMP]]
2973   %shl = shl i32 -2, %a
2974   %cmp = icmp eq i32 %shl, 0
2975   ret i1 %cmp
2978 define i1 @shl_ap1_non_zero_ap2_non_zero_both_positive(i32 %a) {
2979 ; CHECK-LABEL: @shl_ap1_non_zero_ap2_non_zero_both_positive(
2980 ; CHECK-NEXT:    [[CMP:%.*]] = icmp eq i32 [[A:%.*]], 0
2981 ; CHECK-NEXT:    ret i1 [[CMP]]
2983   %shl = shl i32 50, %a
2984   %cmp = icmp eq i32 %shl, 50
2985   ret i1 %cmp
2988 define i1 @shl_ap1_non_zero_ap2_non_zero_both_negative(i32 %a) {
2989 ; CHECK-LABEL: @shl_ap1_non_zero_ap2_non_zero_both_negative(
2990 ; CHECK-NEXT:    [[CMP:%.*]] = icmp eq i32 [[A:%.*]], 0
2991 ; CHECK-NEXT:    ret i1 [[CMP]]
2993   %shl = shl i32 -50, %a
2994   %cmp = icmp eq i32 %shl, -50
2995   ret i1 %cmp
2998 define i1 @shl_ap1_non_zero_ap2_non_zero_ap1_1(i32 %a) {
2999 ; CHECK-LABEL: @shl_ap1_non_zero_ap2_non_zero_ap1_1(
3000 ; CHECK-NEXT:    ret i1 false
3002   %shl = shl i32 50, %a
3003   %cmp = icmp eq i32 %shl, 25
3004   ret i1 %cmp
3007 define i1 @shl_ap1_non_zero_ap2_non_zero_ap1_2(i32 %a) {
3008 ; CHECK-LABEL: @shl_ap1_non_zero_ap2_non_zero_ap1_2(
3009 ; CHECK-NEXT:    [[CMP:%.*]] = icmp eq i32 [[A:%.*]], 1
3010 ; CHECK-NEXT:    ret i1 [[CMP]]
3012   %shl = shl i32 25, %a
3013   %cmp = icmp eq i32 %shl, 50
3014   ret i1 %cmp
3017 define i1 @shl_ap1_non_zero_ap2_non_zero_ap1_3(i32 %a) {
3018 ; CHECK-LABEL: @shl_ap1_non_zero_ap2_non_zero_ap1_3(
3019 ; CHECK-NEXT:    ret i1 false
3021   %shl = shl i32 26, %a
3022   %cmp = icmp eq i32 %shl, 50
3023   ret i1 %cmp
3026 define i1 @icmp_sgt_zero_add_nsw(i32 %a) {
3027 ; CHECK-LABEL: @icmp_sgt_zero_add_nsw(
3028 ; CHECK-NEXT:    [[CMP:%.*]] = icmp sgt i32 [[A:%.*]], -1
3029 ; CHECK-NEXT:    ret i1 [[CMP]]
3031   %add = add nsw i32 %a, 1
3032   %cmp = icmp sgt i32 %add, 0
3033   ret i1 %cmp
3036 define i1 @icmp_sge_zero_add_nsw(i32 %a) {
3037 ; CHECK-LABEL: @icmp_sge_zero_add_nsw(
3038 ; CHECK-NEXT:    [[CMP:%.*]] = icmp sgt i32 [[A:%.*]], -2
3039 ; CHECK-NEXT:    ret i1 [[CMP]]
3041   %add = add nsw i32 %a, 1
3042   %cmp = icmp sge i32 %add, 0
3043   ret i1 %cmp
3046 define i1 @icmp_sle_zero_add_nsw(i32 %a) {
3047 ; CHECK-LABEL: @icmp_sle_zero_add_nsw(
3048 ; CHECK-NEXT:    [[CMP:%.*]] = icmp slt i32 [[A:%.*]], 0
3049 ; CHECK-NEXT:    ret i1 [[CMP]]
3051   %add = add nsw i32 %a, 1
3052   %cmp = icmp sle i32 %add, 0
3053   ret i1 %cmp
3056 define zeroext i1 @icmp_cmpxchg_strong(i32* %sc, i32 %old_val, i32 %new_val) {
3057 ; CHECK-LABEL: @icmp_cmpxchg_strong(
3058 ; CHECK-NEXT:    [[XCHG:%.*]] = cmpxchg i32* [[SC:%.*]], i32 [[OLD_VAL:%.*]], i32 [[NEW_VAL:%.*]] seq_cst seq_cst, align 4
3059 ; CHECK-NEXT:    [[ICMP:%.*]] = extractvalue { i32, i1 } [[XCHG]], 1
3060 ; CHECK-NEXT:    ret i1 [[ICMP]]
3062   %xchg = cmpxchg i32* %sc, i32 %old_val, i32 %new_val seq_cst seq_cst
3063   %xtrc = extractvalue { i32, i1 } %xchg, 0
3064   %icmp = icmp eq i32 %xtrc, %old_val
3065   ret i1 %icmp
3068 define i1 @f1(i64 %a, i64 %b) {
3069 ; CHECK-LABEL: @f1(
3070 ; CHECK-NEXT:    [[V:%.*]] = icmp sge i64 [[A:%.*]], [[B:%.*]]
3071 ; CHECK-NEXT:    ret i1 [[V]]
3073   %t = sub nsw i64 %a, %b
3074   %v = icmp sge i64 %t, 0
3075   ret i1 %v
3078 define <2 x i1> @f1_vec(<2 x i64> %a, <2 x i64> %b) {
3079 ; CHECK-LABEL: @f1_vec(
3080 ; CHECK-NEXT:    [[V:%.*]] = icmp sge <2 x i64> [[A:%.*]], [[B:%.*]]
3081 ; CHECK-NEXT:    ret <2 x i1> [[V]]
3083   %t = sub nsw <2 x i64> %a, %b
3084   %v = icmp sgt <2 x i64> %t, <i64 -1, i64 -1>
3085   ret <2 x i1> %v
3088 define i1 @f2(i64 %a, i64 %b) {
3089 ; CHECK-LABEL: @f2(
3090 ; CHECK-NEXT:    [[V:%.*]] = icmp sgt i64 [[A:%.*]], [[B:%.*]]
3091 ; CHECK-NEXT:    ret i1 [[V]]
3093   %t = sub nsw i64 %a, %b
3094   %v = icmp sgt i64 %t, 0
3095   ret i1 %v
3098 define <2 x i1> @f2_vec(<2 x i64> %a, <2 x i64> %b) {
3099 ; CHECK-LABEL: @f2_vec(
3100 ; CHECK-NEXT:    [[V:%.*]] = icmp sgt <2 x i64> [[A:%.*]], [[B:%.*]]
3101 ; CHECK-NEXT:    ret <2 x i1> [[V]]
3103   %t = sub nsw <2 x i64> %a, %b
3104   %v = icmp sgt <2 x i64> %t, zeroinitializer
3105   ret <2 x i1> %v
3108 define i1 @f3(i64 %a, i64 %b) {
3109 ; CHECK-LABEL: @f3(
3110 ; CHECK-NEXT:    [[V:%.*]] = icmp slt i64 [[A:%.*]], [[B:%.*]]
3111 ; CHECK-NEXT:    ret i1 [[V]]
3113   %t = sub nsw i64 %a, %b
3114   %v = icmp slt i64 %t, 0
3115   ret i1 %v
3118 define <2 x i1> @f3_vec(<2 x i64> %a, <2 x i64> %b) {
3119 ; CHECK-LABEL: @f3_vec(
3120 ; CHECK-NEXT:    [[V:%.*]] = icmp slt <2 x i64> [[A:%.*]], [[B:%.*]]
3121 ; CHECK-NEXT:    ret <2 x i1> [[V]]
3123   %t = sub nsw <2 x i64> %a, %b
3124   %v = icmp slt <2 x i64> %t, zeroinitializer
3125   ret <2 x i1> %v
3128 define i1 @f4(i64 %a, i64 %b) {
3129 ; CHECK-LABEL: @f4(
3130 ; CHECK-NEXT:    [[V:%.*]] = icmp sle i64 [[A:%.*]], [[B:%.*]]
3131 ; CHECK-NEXT:    ret i1 [[V]]
3133   %t = sub nsw i64 %a, %b
3134   %v = icmp sle i64 %t, 0
3135   ret i1 %v
3138 define <2 x i1> @f4_vec(<2 x i64> %a, <2 x i64> %b) {
3139 ; CHECK-LABEL: @f4_vec(
3140 ; CHECK-NEXT:    [[V:%.*]] = icmp sle <2 x i64> [[A:%.*]], [[B:%.*]]
3141 ; CHECK-NEXT:    ret <2 x i1> [[V]]
3143   %t = sub nsw <2 x i64> %a, %b
3144   %v = icmp slt <2 x i64> %t, <i64 1, i64 1>
3145   ret <2 x i1> %v
3148 define i32 @f5(i8 %a, i8 %b) {
3149 ; CHECK-LABEL: @f5(
3150 ; CHECK-NEXT:    [[CONV:%.*]] = zext i8 [[A:%.*]] to i32
3151 ; CHECK-NEXT:    [[CONV3:%.*]] = zext i8 [[B:%.*]] to i32
3152 ; CHECK-NEXT:    [[SUB:%.*]] = sub nsw i32 [[CONV]], [[CONV3]]
3153 ; CHECK-NEXT:    [[TMP1:%.*]] = call i32 @llvm.abs.i32(i32 [[SUB]], i1 true)
3154 ; CHECK-NEXT:    ret i32 [[TMP1]]
3156   %conv = zext i8 %a to i32
3157   %conv3 = zext i8 %b to i32
3158   %sub = sub nsw i32 %conv, %conv3
3159   %cmp4 = icmp slt i32 %sub, 0
3160   %sub7 = sub nsw i32 0, %sub
3161   %sub7.sub = select i1 %cmp4, i32 %sub7, i32 %sub
3162   ret i32 %sub7.sub
3165 define i32 @f6(i32 %a, i32 %b) {
3166 ; CHECK-LABEL: @f6(
3167 ; CHECK-NEXT:    [[CMP_UNSHIFTED:%.*]] = xor i32 [[A:%.*]], [[B:%.*]]
3168 ; CHECK-NEXT:    [[CMP_MASK:%.*]] = and i32 [[CMP_UNSHIFTED]], 255
3169 ; CHECK-NEXT:    [[CMP:%.*]] = icmp eq i32 [[CMP_MASK]], 0
3170 ; CHECK-NEXT:    [[S:%.*]] = select i1 [[CMP]], i32 10000, i32 0
3171 ; CHECK-NEXT:    ret i32 [[S]]
3173   %sext = shl i32 %a, 24
3174   %conv = ashr i32 %sext, 24
3175   %sext6 = shl i32 %b, 24
3176   %conv4 = ashr i32 %sext6, 24
3177   %cmp = icmp eq i32 %conv, %conv4
3178   %s = select i1 %cmp, i32 10000, i32 0
3179   ret i32 %s
3182 define i32 @f7(i32 %a, i32 %b) {
3183 ; CHECK-LABEL: @f7(
3184 ; CHECK-NEXT:    [[CMP_NOT_UNSHIFTED:%.*]] = xor i32 [[A:%.*]], [[B:%.*]]
3185 ; CHECK-NEXT:    [[CMP_NOT_MASK:%.*]] = and i32 [[CMP_NOT_UNSHIFTED]], 511
3186 ; CHECK-NEXT:    [[CMP_NOT:%.*]] = icmp eq i32 [[CMP_NOT_MASK]], 0
3187 ; CHECK-NEXT:    [[S:%.*]] = select i1 [[CMP_NOT]], i32 0, i32 10000
3188 ; CHECK-NEXT:    ret i32 [[S]]
3190   %sext = shl i32 %a, 23
3191   %sext6 = shl i32 %b, 23
3192   %cmp = icmp ne i32 %sext, %sext6
3193   %s = select i1 %cmp, i32 10000, i32 0
3194   ret i32 %s
3197 define i1 @f8(i32 %val, i32 %lim) {
3198 ; CHECK-LABEL: @f8(
3199 ; CHECK-NEXT:    [[R:%.*]] = icmp ne i32 [[LIM:%.*]], 0
3200 ; CHECK-NEXT:    ret i1 [[R]]
3202   %lim.sub = add i32 %lim, -1
3203   %val.and = and i32 %val, %lim.sub
3204   %r = icmp ult i32 %val.and, %lim
3205   ret i1 %r
3208 define i1 @f9(i32 %val, i32 %lim) {
3209 ; CHECK-LABEL: @f9(
3210 ; CHECK-NEXT:    [[R:%.*]] = icmp ne i32 [[LIM:%.*]], 0
3211 ; CHECK-NEXT:    ret i1 [[R]]
3213   %lim.sub = sub i32 %lim, 1
3214   %val.and = and i32 %val, %lim.sub
3215   %r = icmp ult i32 %val.and, %lim
3216   ret i1 %r
3219 define i1 @f10(i16 %p) {
3220 ; CHECK-LABEL: @f10(
3221 ; 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))
3222 ; CHECK-NEXT:    ret i1 [[CMP580]]
3224   %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
3225   ret i1 %cmp580
3228 ; Note: fptosi is used in various tests below to ensure that operand complexity
3229 ; canonicalization does not kick in, which would make some of the tests
3230 ; equivalent to one another.
3232 define i1 @cmp_sgt_rhs_dec(float %x, i32 %i) {
3233 ; CHECK-LABEL: @cmp_sgt_rhs_dec(
3234 ; CHECK-NEXT:    [[CONV:%.*]] = fptosi float [[X:%.*]] to i32
3235 ; CHECK-NEXT:    [[CMP:%.*]] = icmp sge i32 [[CONV]], [[I:%.*]]
3236 ; CHECK-NEXT:    ret i1 [[CMP]]
3238   %conv = fptosi float %x to i32
3239   %dec = sub nsw i32 %i, 1
3240   %cmp = icmp sgt i32 %conv, %dec
3241   ret i1 %cmp
3244 define i1 @cmp_sle_rhs_dec(float %x, i32 %i) {
3245 ; CHECK-LABEL: @cmp_sle_rhs_dec(
3246 ; CHECK-NEXT:    [[CONV:%.*]] = fptosi float [[X:%.*]] to i32
3247 ; CHECK-NEXT:    [[CMP:%.*]] = icmp slt i32 [[CONV]], [[I:%.*]]
3248 ; CHECK-NEXT:    ret i1 [[CMP]]
3250   %conv = fptosi float %x to i32
3251   %dec = sub nsw i32 %i, 1
3252   %cmp = icmp sle i32 %conv, %dec
3253   ret i1 %cmp
3256 define i1 @cmp_sge_rhs_inc(float %x, i32 %i) {
3257 ; CHECK-LABEL: @cmp_sge_rhs_inc(
3258 ; CHECK-NEXT:    [[CONV:%.*]] = fptosi float [[X:%.*]] to i32
3259 ; CHECK-NEXT:    [[CMP:%.*]] = icmp sgt i32 [[CONV]], [[I:%.*]]
3260 ; CHECK-NEXT:    ret i1 [[CMP]]
3262   %conv = fptosi float %x to i32
3263   %inc = add nsw i32 %i, 1
3264   %cmp = icmp sge i32 %conv, %inc
3265   ret i1 %cmp
3268 define i1 @cmp_slt_rhs_inc(float %x, i32 %i) {
3269 ; CHECK-LABEL: @cmp_slt_rhs_inc(
3270 ; CHECK-NEXT:    [[CONV:%.*]] = fptosi float [[X:%.*]] to i32
3271 ; CHECK-NEXT:    [[CMP:%.*]] = icmp sle i32 [[CONV]], [[I:%.*]]
3272 ; CHECK-NEXT:    ret i1 [[CMP]]
3274   %conv = fptosi float %x to i32
3275   %inc = add nsw i32 %i, 1
3276   %cmp = icmp slt i32 %conv, %inc
3277   ret i1 %cmp
3280 define i1 @PR26407(i32 %x, i32 %y) {
3281 ; CHECK-LABEL: @PR26407(
3282 ; CHECK-NEXT:    [[ADDX:%.*]] = add i32 [[X:%.*]], 2147483647
3283 ; CHECK-NEXT:    [[ADDY:%.*]] = add i32 [[Y:%.*]], 2147483647
3284 ; CHECK-NEXT:    [[CMP:%.*]] = icmp uge i32 [[ADDX]], [[ADDY]]
3285 ; CHECK-NEXT:    ret i1 [[CMP]]
3287   %addx = add i32 %x, 2147483647
3288   %addy = add i32 %y, 2147483647
3289   %cmp = icmp uge i32 %addx, %addy
3290   ret i1 %cmp
3293 define i1 @cmp_inverse_mask_bits_set_eq(i32 %x) {
3294 ; CHECK-LABEL: @cmp_inverse_mask_bits_set_eq(
3295 ; CHECK-NEXT:    [[TMP1:%.*]] = and i32 [[X:%.*]], -43
3296 ; CHECK-NEXT:    [[CMP:%.*]] = icmp eq i32 [[TMP1]], -43
3297 ; CHECK-NEXT:    ret i1 [[CMP]]
3299   %or = or i32 %x, 42
3300   %cmp = icmp eq i32 %or, -1
3301   ret i1 %cmp
3304 define <2 x i1> @cmp_inverse_mask_bits_set_eq_vec(<2 x i32> %x) {
3305 ; CHECK-LABEL: @cmp_inverse_mask_bits_set_eq_vec(
3306 ; CHECK-NEXT:    [[TMP1:%.*]] = and <2 x i32> [[X:%.*]], <i32 -43, i32 -43>
3307 ; CHECK-NEXT:    [[CMP:%.*]] = icmp eq <2 x i32> [[TMP1]], <i32 -43, i32 -43>
3308 ; CHECK-NEXT:    ret <2 x i1> [[CMP]]
3310   %or = or <2 x i32> %x, <i32 42, i32 42>
3311   %cmp = icmp eq <2 x i32> %or, <i32 -1, i32 -1>
3312   ret <2 x i1> %cmp
3315 define i1 @cmp_inverse_mask_bits_set_ne(i32 %x) {
3316 ; CHECK-LABEL: @cmp_inverse_mask_bits_set_ne(
3317 ; CHECK-NEXT:    [[TMP1:%.*]] = and i32 [[X:%.*]], -43
3318 ; CHECK-NEXT:    [[CMP:%.*]] = icmp ne i32 [[TMP1]], -43
3319 ; CHECK-NEXT:    ret i1 [[CMP]]
3321   %or = or i32 %x, 42
3322   %cmp = icmp ne i32 %or, -1
3323   ret i1 %cmp
3326 ; When canonicalizing to 'gt/lt', make sure the constant is correct.
3328 define i1 @PR27792(i128 %a) {
3329 ; CHECK-LABEL: @PR27792(
3330 ; CHECK-NEXT:    [[CMP:%.*]] = icmp sgt i128 [[A:%.*]], -1
3331 ; CHECK-NEXT:    ret i1 [[CMP]]
3333   %cmp = icmp sge i128 %a, 0
3334   ret i1 %cmp
3337 define i1 @PR27792_2(i128 %a) {
3338 ; CHECK-LABEL: @PR27792_2(
3339 ; CHECK-NEXT:    [[B:%.*]] = icmp ne i128 [[A:%.*]], 0
3340 ; CHECK-NEXT:    ret i1 [[B]]
3342   %b = icmp uge i128 %a, 1
3343   ret i1 %b
3346 define i1 @ugtMaxSignedVal(i8 %a) {
3347 ; CHECK-LABEL: @ugtMaxSignedVal(
3348 ; CHECK-NEXT:    [[CMP:%.*]] = icmp slt i8 [[A:%.*]], 0
3349 ; CHECK-NEXT:    ret i1 [[CMP]]
3351   %cmp = icmp ugt i8 %a, 127
3352   ret i1 %cmp
3355 define <2 x i1> @ugtMaxSignedValVec(<2 x i8> %a) {
3356 ; CHECK-LABEL: @ugtMaxSignedValVec(
3357 ; CHECK-NEXT:    [[CMP:%.*]] = icmp slt <2 x i8> [[A:%.*]], zeroinitializer
3358 ; CHECK-NEXT:    ret <2 x i1> [[CMP]]
3360   %cmp = icmp ugt <2 x i8> %a, <i8 127, i8 127>
3361   ret <2 x i1> %cmp
3364 define i1 @ugtKnownBits(i8 %a) {
3365 ; CHECK-LABEL: @ugtKnownBits(
3366 ; CHECK-NEXT:    [[B:%.*]] = and i8 [[A:%.*]], 17
3367 ; CHECK-NEXT:    [[CMP:%.*]] = icmp eq i8 [[B]], 17
3368 ; CHECK-NEXT:    ret i1 [[CMP]]
3370   %b = and i8 %a, 17
3371   %cmp = icmp ugt i8 %b, 16
3372   ret i1 %cmp
3375 define <2 x i1> @ugtKnownBitsVec(<2 x i8> %a) {
3376 ; CHECK-LABEL: @ugtKnownBitsVec(
3377 ; CHECK-NEXT:    [[B:%.*]] = and <2 x i8> [[A:%.*]], <i8 17, i8 17>
3378 ; CHECK-NEXT:    [[CMP:%.*]] = icmp eq <2 x i8> [[B]], <i8 17, i8 17>
3379 ; CHECK-NEXT:    ret <2 x i1> [[CMP]]
3381   %b = and <2 x i8> %a, <i8 17, i8 17>
3382   %cmp = icmp ugt <2 x i8> %b, <i8 16, i8 16>
3383   ret <2 x i1> %cmp
3386 define i1 @or_ptrtoint_mismatch(i8* %p, i32* %q) {
3387 ; CHECK-LABEL: @or_ptrtoint_mismatch(
3388 ; CHECK-NEXT:    [[TMP1:%.*]] = icmp eq i8* [[P:%.*]], null
3389 ; CHECK-NEXT:    [[TMP2:%.*]] = icmp eq i32* [[Q:%.*]], null
3390 ; CHECK-NEXT:    [[B:%.*]] = and i1 [[TMP1]], [[TMP2]]
3391 ; CHECK-NEXT:    ret i1 [[B]]
3394   %pp = ptrtoint i8* %p to i64
3395   %qq = ptrtoint i32* %q to i64
3396   %o = or i64 %pp, %qq
3397   %b = icmp eq i64 %o, 0
3398   ret i1 %b
3401 define i1 @icmp_add1_ugt(i32 %x, i32 %y) {
3402 ; CHECK-LABEL: @icmp_add1_ugt(
3403 ; CHECK-NEXT:    [[CMP:%.*]] = icmp uge i32 [[X:%.*]], [[Y:%.*]]
3404 ; CHECK-NEXT:    ret i1 [[CMP]]
3406   %add = add nuw i32 %x, 1
3407   %cmp = icmp ugt i32 %add, %y
3408   ret i1 %cmp
3411 define i1 @icmp_add1_ule(i32 %x, i32 %y) {
3412 ; CHECK-LABEL: @icmp_add1_ule(
3413 ; CHECK-NEXT:    [[CMP:%.*]] = icmp ult i32 [[X:%.*]], [[Y:%.*]]
3414 ; CHECK-NEXT:    ret i1 [[CMP]]
3416   %add = add nuw i32 %x, 1
3417   %cmp = icmp ule i32 %add, %y
3418   ret i1 %cmp
3421 define i1 @cmp_uge_rhs_inc(float %x, i32 %i) {
3422 ; CHECK-LABEL: @cmp_uge_rhs_inc(
3423 ; CHECK-NEXT:    [[CONV:%.*]] = fptosi float [[X:%.*]] to i32
3424 ; CHECK-NEXT:    [[CMP:%.*]] = icmp ugt i32 [[CONV]], [[I:%.*]]
3425 ; CHECK-NEXT:    ret i1 [[CMP]]
3427   %conv = fptosi float %x to i32
3428   %inc = add nuw i32 %i, 1
3429   %cmp = icmp uge i32 %conv, %inc
3430   ret i1 %cmp
3433 define i1 @cmp_ult_rhs_inc(float %x, i32 %i) {
3434 ; CHECK-LABEL: @cmp_ult_rhs_inc(
3435 ; CHECK-NEXT:    [[CONV:%.*]] = fptosi float [[X:%.*]] to i32
3436 ; CHECK-NEXT:    [[CMP:%.*]] = icmp ule i32 [[CONV]], [[I:%.*]]
3437 ; CHECK-NEXT:    ret i1 [[CMP]]
3439   %conv = fptosi float %x to i32
3440   %inc = add nuw i32 %i, 1
3441   %cmp = icmp ult i32 %conv, %inc
3442   ret i1 %cmp
3445 define i1 @cmp_sge_lhs_inc(i32 %x, i32 %y) {
3446 ; CHECK-LABEL: @cmp_sge_lhs_inc(
3447 ; CHECK-NEXT:    [[INC:%.*]] = add nsw i32 [[X:%.*]], 1
3448 ; CHECK-NEXT:    [[CMP:%.*]] = icmp sge i32 [[INC]], [[Y:%.*]]
3449 ; CHECK-NEXT:    ret i1 [[CMP]]
3451   %inc = add nsw i32 %x, 1
3452   %cmp = icmp sge i32 %inc, %y
3453   ret i1 %cmp
3456 define i1 @cmp_uge_lhs_inc(i32 %x, i32 %y) {
3457 ; CHECK-LABEL: @cmp_uge_lhs_inc(
3458 ; CHECK-NEXT:    [[INC:%.*]] = add nuw i32 [[X:%.*]], 1
3459 ; CHECK-NEXT:    [[CMP:%.*]] = icmp uge i32 [[INC]], [[Y:%.*]]
3460 ; CHECK-NEXT:    ret i1 [[CMP]]
3462   %inc = add nuw i32 %x, 1
3463   %cmp = icmp uge i32 %inc, %y
3464   ret i1 %cmp
3467 define i1 @cmp_sgt_lhs_dec(i32 %x, i32 %y) {
3468 ; CHECK-LABEL: @cmp_sgt_lhs_dec(
3469 ; CHECK-NEXT:    [[DEC:%.*]] = add nsw i32 [[X:%.*]], -1
3470 ; CHECK-NEXT:    [[CMP:%.*]] = icmp sgt i32 [[DEC]], [[Y:%.*]]
3471 ; CHECK-NEXT:    ret i1 [[CMP]]
3473   %dec = sub nsw i32 %x, 1
3474   %cmp = icmp sgt i32 %dec, %y
3475   ret i1 %cmp
3478 define i1 @cmp_ugt_lhs_dec(i32 %x, i32 %y) {
3479 ; CHECK-LABEL: @cmp_ugt_lhs_dec(
3480 ; CHECK-NEXT:    [[DEC:%.*]] = add i32 [[X:%.*]], -1
3481 ; CHECK-NEXT:    [[CMP:%.*]] = icmp ugt i32 [[DEC]], [[Y:%.*]]
3482 ; CHECK-NEXT:    ret i1 [[CMP]]
3484   %dec = sub nuw i32 %x, 1
3485   %cmp = icmp ugt i32 %dec, %y
3486   ret i1 %cmp
3489 define i1 @cmp_sle_rhs_inc(float %x, i32 %y) {
3490 ; CHECK-LABEL: @cmp_sle_rhs_inc(
3491 ; CHECK-NEXT:    [[CONV:%.*]] = fptosi float [[X:%.*]] to i32
3492 ; CHECK-NEXT:    [[INC:%.*]] = add nsw i32 [[Y:%.*]], 1
3493 ; CHECK-NEXT:    [[CMP:%.*]] = icmp sge i32 [[INC]], [[CONV]]
3494 ; CHECK-NEXT:    ret i1 [[CMP]]
3496   %conv = fptosi float %x to i32
3497   %inc = add nsw i32 %y, 1
3498   %cmp = icmp sle i32 %conv, %inc
3499   ret i1 %cmp
3502 define i1 @cmp_ule_rhs_inc(float %x, i32 %y) {
3503 ; CHECK-LABEL: @cmp_ule_rhs_inc(
3504 ; CHECK-NEXT:    [[CONV:%.*]] = fptosi float [[X:%.*]] to i32
3505 ; CHECK-NEXT:    [[INC:%.*]] = add nuw i32 [[Y:%.*]], 1
3506 ; CHECK-NEXT:    [[CMP:%.*]] = icmp uge i32 [[INC]], [[CONV]]
3507 ; CHECK-NEXT:    ret i1 [[CMP]]
3509   %conv = fptosi float %x to i32
3510   %inc = add nuw i32 %y, 1
3511   %cmp = icmp ule i32 %conv, %inc
3512   ret i1 %cmp
3515 define i1 @cmp_slt_rhs_dec(float %x, i32 %y) {
3516 ; CHECK-LABEL: @cmp_slt_rhs_dec(
3517 ; CHECK-NEXT:    [[CONV:%.*]] = fptosi float [[X:%.*]] to i32
3518 ; CHECK-NEXT:    [[DEC:%.*]] = add nsw i32 [[Y:%.*]], -1
3519 ; CHECK-NEXT:    [[CMP:%.*]] = icmp sgt i32 [[DEC]], [[CONV]]
3520 ; CHECK-NEXT:    ret i1 [[CMP]]
3522   %conv = fptosi float %x to i32
3523   %dec = sub nsw i32 %y, 1
3524   %cmp = icmp slt i32 %conv, %dec
3525   ret i1 %cmp
3528 define i1 @cmp_ult_rhs_dec(float %x, i32 %y) {
3529 ; CHECK-LABEL: @cmp_ult_rhs_dec(
3530 ; CHECK-NEXT:    [[CONV:%.*]] = fptosi float [[X:%.*]] to i32
3531 ; CHECK-NEXT:    [[DEC:%.*]] = add i32 [[Y:%.*]], -1
3532 ; CHECK-NEXT:    [[CMP:%.*]] = icmp ugt i32 [[DEC]], [[CONV]]
3533 ; CHECK-NEXT:    ret i1 [[CMP]]
3535   %conv = fptosi float %x to i32
3536   %dec = sub nuw i32 %y, 1
3537   %cmp = icmp ult i32 %conv, %dec
3538   ret i1 %cmp
3541 define i1 @eq_add_constants(i32 %x, i32 %y) {
3542 ; CHECK-LABEL: @eq_add_constants(
3543 ; CHECK-NEXT:    [[C:%.*]] = icmp eq i32 [[X:%.*]], [[Y:%.*]]
3544 ; CHECK-NEXT:    ret i1 [[C]]
3546   %A = add i32 %x, 5
3547   %B = add i32 %y, 5
3548   %C = icmp eq i32 %A, %B
3549   ret i1 %C
3552 declare i32 @llvm.bswap.i32(i32)
3554 define i1 @bswap_ne(i32 %x, i32 %y) {
3555 ; CHECK-LABEL: @bswap_ne(
3556 ; CHECK-NEXT:    [[CMP:%.*]] = icmp ne i32 [[X:%.*]], [[Y:%.*]]
3557 ; CHECK-NEXT:    ret i1 [[CMP]]
3559   %swapx = call i32 @llvm.bswap.i32(i32 %x)
3560   %swapy = call i32 @llvm.bswap.i32(i32 %y)
3561   %cmp = icmp ne i32 %swapx, %swapy
3562   ret i1 %cmp
3565 declare <8 x i16> @llvm.bswap.v8i16(<8 x i16>)
3567 define <8 x i1> @bswap_vec_eq(<8 x i16> %x, <8 x i16> %y) {
3568 ; CHECK-LABEL: @bswap_vec_eq(
3569 ; CHECK-NEXT:    [[CMP:%.*]] = icmp eq <8 x i16> [[X:%.*]], [[Y:%.*]]
3570 ; CHECK-NEXT:    ret <8 x i1> [[CMP]]
3572   %swapx = call <8 x i16> @llvm.bswap.v8i16(<8 x i16> %x)
3573   %swapy = call <8 x i16> @llvm.bswap.v8i16(<8 x i16> %y)
3574   %cmp = icmp eq <8 x i16> %swapx, %swapy
3575   ret <8 x i1> %cmp
3578 declare i64 @llvm.bitreverse.i64(i64)
3580 define i1 @bitreverse_eq(i64 %x, i64 %y) {
3581 ; CHECK-LABEL: @bitreverse_eq(
3582 ; CHECK-NEXT:    [[CMP:%.*]] = icmp eq i64 [[X:%.*]], [[Y:%.*]]
3583 ; CHECK-NEXT:    ret i1 [[CMP]]
3585   %revx = call i64 @llvm.bitreverse.i64(i64 %x)
3586   %revy = call i64 @llvm.bitreverse.i64(i64 %y)
3587   %cmp = icmp eq i64 %revx, %revy
3588   ret i1 %cmp
3591 declare <8 x i16> @llvm.bitreverse.v8i16(<8 x i16>)
3593 define <8 x i1> @bitreverse_vec_ne(<8 x i16> %x, <8 x i16> %y) {
3594 ; CHECK-LABEL: @bitreverse_vec_ne(
3595 ; CHECK-NEXT:    [[CMP:%.*]] = icmp ne <8 x i16> [[X:%.*]], [[Y:%.*]]
3596 ; CHECK-NEXT:    ret <8 x i1> [[CMP]]
3598   %revx = call <8 x i16> @llvm.bitreverse.v8i16(<8 x i16> %x)
3599   %revy = call <8 x i16> @llvm.bitreverse.v8i16(<8 x i16> %y)
3600   %cmp = icmp ne <8 x i16> %revx, %revy
3601   ret <8 x i1> %cmp
3604 ; These perform a comparison of a value known to be between 4 and 5 with a value between 5 and 7.
3605 ; They should all simplify to equality compares.
3606 define i1 @knownbits1(i8 %a, i8 %b) {
3607 ; CHECK-LABEL: @knownbits1(
3608 ; CHECK-NEXT:    [[A1:%.*]] = and i8 [[A:%.*]], 1
3609 ; CHECK-NEXT:    [[A2:%.*]] = or i8 [[A1]], 4
3610 ; CHECK-NEXT:    [[B1:%.*]] = and i8 [[B:%.*]], 2
3611 ; CHECK-NEXT:    [[B2:%.*]] = or i8 [[B1]], 5
3612 ; CHECK-NEXT:    [[C:%.*]] = icmp eq i8 [[A2]], [[B2]]
3613 ; CHECK-NEXT:    ret i1 [[C]]
3615   %a1 = and i8 %a, 5
3616   %a2 = or i8 %a1, 4
3617   %b1 = and i8 %b, 7
3618   %b2 = or i8 %b1, 5
3619   %c = icmp uge i8 %a2, %b2
3620   ret i1 %c
3623 define i1 @knownbits2(i8 %a, i8 %b) {
3624 ; CHECK-LABEL: @knownbits2(
3625 ; CHECK-NEXT:    [[A1:%.*]] = and i8 [[A:%.*]], 1
3626 ; CHECK-NEXT:    [[A2:%.*]] = or i8 [[A1]], 4
3627 ; CHECK-NEXT:    [[B1:%.*]] = and i8 [[B:%.*]], 2
3628 ; CHECK-NEXT:    [[B2:%.*]] = or i8 [[B1]], 5
3629 ; CHECK-NEXT:    [[C:%.*]] = icmp ne i8 [[A2]], [[B2]]
3630 ; CHECK-NEXT:    ret i1 [[C]]
3632   %a1 = and i8 %a, 5
3633   %a2 = or i8 %a1, 4
3634   %b1 = and i8 %b, 7
3635   %b2 = or i8 %b1, 5
3636   %c = icmp ult i8 %a2, %b2
3637   ret i1 %c
3640 define i1 @knownbits3(i8 %a, i8 %b) {
3641 ; CHECK-LABEL: @knownbits3(
3642 ; CHECK-NEXT:    [[A1:%.*]] = and i8 [[A:%.*]], 1
3643 ; CHECK-NEXT:    [[A2:%.*]] = or i8 [[A1]], 4
3644 ; CHECK-NEXT:    [[B1:%.*]] = and i8 [[B:%.*]], 2
3645 ; CHECK-NEXT:    [[B2:%.*]] = or i8 [[B1]], 5
3646 ; CHECK-NEXT:    [[C:%.*]] = icmp eq i8 [[B2]], [[A2]]
3647 ; CHECK-NEXT:    ret i1 [[C]]
3649   %a1 = and i8 %a, 5
3650   %a2 = or i8 %a1, 4
3651   %b1 = and i8 %b, 7
3652   %b2 = or i8 %b1, 5
3653   %c = icmp ule i8 %b2, %a2
3654   ret i1 %c
3657 define <2 x i1> @knownbits4(<2 x i8> %a, <2 x i8> %b) {
3658 ; CHECK-LABEL: @knownbits4(
3659 ; CHECK-NEXT:    [[A1:%.*]] = and <2 x i8> [[A:%.*]], <i8 1, i8 1>
3660 ; CHECK-NEXT:    [[A2:%.*]] = or <2 x i8> [[A1]], <i8 4, i8 4>
3661 ; CHECK-NEXT:    [[B1:%.*]] = and <2 x i8> [[B:%.*]], <i8 2, i8 2>
3662 ; CHECK-NEXT:    [[B2:%.*]] = or <2 x i8> [[B1]], <i8 5, i8 5>
3663 ; CHECK-NEXT:    [[C:%.*]] = icmp ne <2 x i8> [[B2]], [[A2]]
3664 ; CHECK-NEXT:    ret <2 x i1> [[C]]
3666   %a1 = and <2 x i8> %a, <i8 5, i8 5>
3667   %a2 = or <2 x i8> %a1, <i8 4, i8 4>
3668   %b1 = and <2 x i8> %b, <i8 7, i8 7>
3669   %b2 = or <2 x i8> %b1, <i8 5, i8 5>
3670   %c = icmp ugt <2 x i8> %b2, %a2
3671   ret <2 x i1> %c
3674 ; These are the signed versions of the above. One value is less than or equal to 5, but maybe negative.
3675 ; The other is known to be a value 5-7. These should simplify to equality comparisons.
3676 define i1 @knownbits5(i8 %a, i8 %b) {
3677 ; CHECK-LABEL: @knownbits5(
3678 ; CHECK-NEXT:    [[A1:%.*]] = and i8 [[A:%.*]], -127
3679 ; CHECK-NEXT:    [[A2:%.*]] = or i8 [[A1]], 4
3680 ; CHECK-NEXT:    [[B1:%.*]] = and i8 [[B:%.*]], 2
3681 ; CHECK-NEXT:    [[B2:%.*]] = or i8 [[B1]], 5
3682 ; CHECK-NEXT:    [[C:%.*]] = icmp eq i8 [[A2]], [[B2]]
3683 ; CHECK-NEXT:    ret i1 [[C]]
3685   %a1 = and i8 %a, 133
3686   %a2 = or i8 %a1, 4
3687   %b1 = and i8 %b, 7
3688   %b2 = or i8 %b1, 5
3689   %c = icmp sge i8 %a2, %b2
3690   ret i1 %c
3693 define i1 @knownbits6(i8 %a, i8 %b) {
3694 ; CHECK-LABEL: @knownbits6(
3695 ; CHECK-NEXT:    [[A1:%.*]] = and i8 [[A:%.*]], -127
3696 ; CHECK-NEXT:    [[A2:%.*]] = or i8 [[A1]], 4
3697 ; CHECK-NEXT:    [[B1:%.*]] = and i8 [[B:%.*]], 2
3698 ; CHECK-NEXT:    [[B2:%.*]] = or i8 [[B1]], 5
3699 ; CHECK-NEXT:    [[C:%.*]] = icmp ne i8 [[A2]], [[B2]]
3700 ; CHECK-NEXT:    ret i1 [[C]]
3702   %a1 = and i8 %a, 133
3703   %a2 = or i8 %a1, 4
3704   %b1 = and i8 %b, 7
3705   %b2 = or i8 %b1, 5
3706   %c = icmp slt i8 %a2, %b2
3707   ret i1 %c
3710 define <2 x i1> @knownbits7(<2 x i8> %a, <2 x i8> %b) {
3711 ; CHECK-LABEL: @knownbits7(
3712 ; CHECK-NEXT:    [[A1:%.*]] = and <2 x i8> [[A:%.*]], <i8 -127, i8 -127>
3713 ; CHECK-NEXT:    [[A2:%.*]] = or <2 x i8> [[A1]], <i8 4, i8 4>
3714 ; CHECK-NEXT:    [[B1:%.*]] = and <2 x i8> [[B:%.*]], <i8 2, i8 2>
3715 ; CHECK-NEXT:    [[B2:%.*]] = or <2 x i8> [[B1]], <i8 5, i8 5>
3716 ; CHECK-NEXT:    [[C:%.*]] = icmp eq <2 x i8> [[B2]], [[A2]]
3717 ; CHECK-NEXT:    ret <2 x i1> [[C]]
3719   %a1 = and <2 x i8> %a, <i8 133, i8 133>
3720   %a2 = or <2 x i8> %a1, <i8 4, i8 4>
3721   %b1 = and <2 x i8> %b, <i8 7, i8 7>
3722   %b2 = or <2 x i8> %b1, <i8 5, i8 5>
3723   %c = icmp sle <2 x i8> %b2, %a2
3724   ret <2 x i1> %c
3727 define i1 @knownbits8(i8 %a, i8 %b) {
3728 ; CHECK-LABEL: @knownbits8(
3729 ; CHECK-NEXT:    [[A1:%.*]] = and i8 [[A:%.*]], -127
3730 ; CHECK-NEXT:    [[A2:%.*]] = or i8 [[A1]], 4
3731 ; CHECK-NEXT:    [[B1:%.*]] = and i8 [[B:%.*]], 2
3732 ; CHECK-NEXT:    [[B2:%.*]] = or i8 [[B1]], 5
3733 ; CHECK-NEXT:    [[C:%.*]] = icmp ne i8 [[B2]], [[A2]]
3734 ; CHECK-NEXT:    ret i1 [[C]]
3736   %a1 = and i8 %a, 133
3737   %a2 = or i8 %a1, 4
3738   %b1 = and i8 %b, 7
3739   %b2 = or i8 %b1, 5
3740   %c = icmp sgt i8 %b2, %a2
3741   ret i1 %c
3744 ; Make sure InstCombine doesn't try too hard to simplify the icmp and break the abs idiom
3745 define i32 @abs_preserve(i32 %x) {
3746 ; CHECK-LABEL: @abs_preserve(
3747 ; CHECK-NEXT:    [[A:%.*]] = shl nsw i32 [[X:%.*]], 1
3748 ; CHECK-NEXT:    [[TMP1:%.*]] = call i32 @llvm.abs.i32(i32 [[A]], i1 false)
3749 ; CHECK-NEXT:    ret i32 [[TMP1]]
3751   %a = mul nsw i32 %x, 2
3752   %c = icmp sge i32 %a, 0
3753   %nega = sub i32 0, %a
3754   %abs = select i1 %c, i32 %a, i32 %nega
3755   ret i32 %abs
3758 ; Don't crash by assuming the compared values are integers.
3760 declare void @llvm.assume(i1)
3761 define i1 @PR35794(i32* %a) {
3762 ; CHECK-LABEL: @PR35794(
3763 ; CHECK-NEXT:    [[MASKCOND:%.*]] = icmp eq i32* [[A:%.*]], null
3764 ; CHECK-NEXT:    tail call void @llvm.assume(i1 [[MASKCOND]])
3765 ; CHECK-NEXT:    ret i1 true
3767   %cmp = icmp sgt i32* %a, inttoptr (i64 -1 to i32*)
3768   %maskcond = icmp eq i32* %a, null
3769   tail call void @llvm.assume(i1 %maskcond)
3770   ret i1 %cmp
3773 ; Don't crash by assuming the compared values are integers.
3774 define <2 x i1> @PR36583(<2 x i8*>)  {
3775 ; CHECK-LABEL: @PR36583(
3776 ; CHECK-NEXT:    [[RES:%.*]] = icmp eq <2 x i8*> [[TMP0:%.*]], zeroinitializer
3777 ; CHECK-NEXT:    ret <2 x i1> [[RES]]
3779   %cast = ptrtoint <2 x i8*> %0 to <2 x i64>
3780   %res = icmp eq <2 x i64> %cast, zeroinitializer
3781   ret <2 x i1> %res
3784 ; fold (icmp pred (sub (0, X)) C1) for vec type
3785 define <2 x i32> @Op1Negated_Vec(<2 x i32> %x) {
3786 ; CHECK-LABEL: @Op1Negated_Vec(
3787 ; CHECK-NEXT:    [[TMP1:%.*]] = call <2 x i32> @llvm.abs.v2i32(<2 x i32> [[X:%.*]], i1 true)
3788 ; CHECK-NEXT:    ret <2 x i32> [[TMP1]]
3790   %sub = sub nsw <2 x i32> zeroinitializer, %x
3791   %cmp = icmp sgt <2 x i32> %sub, <i32 -1, i32 -1>
3792   %cond = select <2 x i1> %cmp, <2 x i32> %sub, <2 x i32> %x
3793   ret <2 x i32> %cond
3796 define i1 @signbit_bitcast_fpext(float %x) {
3797 ; CHECK-LABEL: @signbit_bitcast_fpext(
3798 ; CHECK-NEXT:    [[TMP1:%.*]] = bitcast float [[X:%.*]] to i32
3799 ; CHECK-NEXT:    [[R:%.*]] = icmp slt i32 [[TMP1]], 0
3800 ; CHECK-NEXT:    ret i1 [[R]]
3802   %f = fpext float %x to double
3803   %b = bitcast double %f to i64
3804   %r = icmp slt i64 %b, 0
3805   ret i1 %r
3808 define <2 x i1> @signbit_bitcast_fpext_vec(<2 x half> %x) {
3809 ; CHECK-LABEL: @signbit_bitcast_fpext_vec(
3810 ; CHECK-NEXT:    [[TMP1:%.*]] = bitcast <2 x half> [[X:%.*]] to <2 x i16>
3811 ; CHECK-NEXT:    [[R:%.*]] = icmp slt <2 x i16> [[TMP1]], zeroinitializer
3812 ; CHECK-NEXT:    ret <2 x i1> [[R]]
3814   %f = fpext <2 x half> %x to <2 x float>
3815   %b = bitcast <2 x float> %f to <2 x i32>
3816   %r = icmp ugt <2 x i32> %b, <i32 2147483647, i32 2147483647>
3817   ret <2 x i1> %r
3820 define i1 @signbit_bitcast_fptrunc(float %x) {
3821 ; CHECK-LABEL: @signbit_bitcast_fptrunc(
3822 ; CHECK-NEXT:    [[TMP1:%.*]] = bitcast float [[X:%.*]] to i32
3823 ; CHECK-NEXT:    [[R:%.*]] = icmp sgt i32 [[TMP1]], -1
3824 ; CHECK-NEXT:    ret i1 [[R]]
3826   %f = fptrunc float %x to half
3827   %b = bitcast half %f to i16
3828   %r = icmp ult i16 %b, 32768
3829   ret i1 %r
3832 define <2 x i1> @signbit_bitcast_fptrunc_vec(<2 x double> %x) {
3833 ; CHECK-LABEL: @signbit_bitcast_fptrunc_vec(
3834 ; CHECK-NEXT:    [[TMP1:%.*]] = bitcast <2 x double> [[X:%.*]] to <2 x i64>
3835 ; CHECK-NEXT:    [[R:%.*]] = icmp sgt <2 x i64> [[TMP1]], <i64 -1, i64 -1>
3836 ; CHECK-NEXT:    ret <2 x i1> [[R]]
3838   %f = fptrunc <2 x double> %x to <2 x half>
3839   %b = bitcast <2 x half> %f to <2 x i16>
3840   %r = icmp sge <2 x i16> %b, zeroinitializer
3841   ret <2 x i1> %r
3844 define i1 @signbit_bitcast_fpext_wrong_cmp(float %x) {
3845 ; CHECK-LABEL: @signbit_bitcast_fpext_wrong_cmp(
3846 ; CHECK-NEXT:    [[F:%.*]] = fpext float [[X:%.*]] to double
3847 ; CHECK-NEXT:    [[B:%.*]] = bitcast double [[F]] to i64
3848 ; CHECK-NEXT:    [[R:%.*]] = icmp slt i64 [[B]], 1
3849 ; CHECK-NEXT:    ret i1 [[R]]
3851   %f = fpext float %x to double
3852   %b = bitcast double %f to i64
3853   %r = icmp slt i64 %b, 1
3854   ret i1 %r
3857 define <4 x i1> @signbit_bitcast_fpext_vec_wrong_bitcast(<2 x half> %x) {
3858 ; CHECK-LABEL: @signbit_bitcast_fpext_vec_wrong_bitcast(
3859 ; CHECK-NEXT:    [[F:%.*]] = fpext <2 x half> [[X:%.*]] to <2 x float>
3860 ; CHECK-NEXT:    [[B:%.*]] = bitcast <2 x float> [[F]] to <4 x i16>
3861 ; CHECK-NEXT:    [[R:%.*]] = icmp sgt <4 x i16> [[B]], <i16 -1, i16 -1, i16 -1, i16 -1>
3862 ; CHECK-NEXT:    ret <4 x i1> [[R]]
3864   %f = fpext <2 x half> %x to <2 x float>
3865   %b = bitcast <2 x float> %f to <4 x i16>
3866   %r = icmp sgt <4 x i16> %b, <i16 -1, i16 -1, i16 -1, i16 -1>
3867   ret <4 x i1> %r
3870 declare void @use_i64(i64)
3872 define i1 @signbit_bitcast_fpext_extra_use(float %x, i64* %p) {
3873 ; CHECK-LABEL: @signbit_bitcast_fpext_extra_use(
3874 ; CHECK-NEXT:    [[F:%.*]] = fpext float [[X:%.*]] to double
3875 ; CHECK-NEXT:    [[B:%.*]] = bitcast double [[F]] to i64
3876 ; CHECK-NEXT:    call void @use_i64(i64 [[B]])
3877 ; CHECK-NEXT:    [[R:%.*]] = icmp slt i64 [[B]], 0
3878 ; CHECK-NEXT:    ret i1 [[R]]
3880   %f = fpext float %x to double
3881   %b = bitcast double %f to i64
3882   call void @use_i64(i64 %b)
3883   %r = icmp slt i64 %b, 0
3884   ret i1 %r
3887 define i1 @signbit_bitcast_fpext_ppc_fp128(float %x) {
3888 ; CHECK-LABEL: @signbit_bitcast_fpext_ppc_fp128(
3889 ; CHECK-NEXT:    [[S2:%.*]] = fpext float [[X:%.*]] to ppc_fp128
3890 ; CHECK-NEXT:    [[S3:%.*]] = bitcast ppc_fp128 [[S2]] to i128
3891 ; CHECK-NEXT:    [[S4:%.*]] = icmp slt i128 [[S3]], 0
3892 ; CHECK-NEXT:    ret i1 [[S4]]
3894   %s2 = fpext float %x to ppc_fp128
3895   %s3 = bitcast ppc_fp128 %s2 to i128
3896   %s4 = icmp slt i128 %s3, 0
3897   ret i1 %s4
3900 define i1 @signbit_bitcast_fptrunc_ppc_fp128(ppc_fp128 %x) {
3901 ; CHECK-LABEL: @signbit_bitcast_fptrunc_ppc_fp128(
3902 ; CHECK-NEXT:    [[S2:%.*]] = fptrunc ppc_fp128 [[X:%.*]] to float
3903 ; CHECK-NEXT:    [[S3:%.*]] = bitcast float [[S2]] to i32
3904 ; CHECK-NEXT:    [[S4:%.*]] = icmp slt i32 [[S3]], 0
3905 ; CHECK-NEXT:    ret i1 [[S4]]
3907   %s2 = fptrunc ppc_fp128 %x to float
3908   %s3 = bitcast float %s2 to i32
3909   %s4 = icmp slt i32 %s3, 0
3910   ret i1 %s4
3913 @x = external dso_local local_unnamed_addr global i32, align 4
3914 @y = external dso_local local_unnamed_addr global i32, align 4
3915 define i1 @pr47997(i32 %arg) {
3916 ; CHECK-LABEL: @pr47997(
3917 ; CHECK-NEXT:  bb:
3918 ; CHECK-NEXT:    [[I:%.*]] = add nsw i32 [[ARG:%.*]], -1
3919 ; CHECK-NEXT:    store i32 [[I]], i32* @x, align 4
3920 ; CHECK-NEXT:    [[I1:%.*]] = sub nsw i32 1, [[ARG]]
3921 ; CHECK-NEXT:    store i32 [[I1]], i32* @y, align 4
3922 ; CHECK-NEXT:    ret i1 true
3925   %i = add nsw i32 %arg, -1
3926   store i32 %i, i32* @x
3927   %i1 = sub nsw i32 1, %arg
3928   store i32 %i1, i32* @y
3929   %i2 = sub nsw i32 0, %i1
3930   %i3 = icmp eq i32 %i, %i2
3931   ret i1 %i3
3934 ; PR50944
3936 define i1 @thread_cmp_over_select_with_poison_trueval(i1 %b) {
3937 ; CHECK-LABEL: @thread_cmp_over_select_with_poison_trueval(
3938 ; CHECK-NEXT:    ret i1 false
3940   %s = select i1 %b, i32 poison, i32 0
3941   %tobool = icmp ne i32 %s, 0
3942   ret i1 %tobool
3945 define i1 @thread_cmp_over_select_with_poison_falseval(i1 %b) {
3946 ; CHECK-LABEL: @thread_cmp_over_select_with_poison_falseval(
3947 ; CHECK-NEXT:    ret i1 true
3949   %s = select i1 %b, i32 1, i32 poison
3950   %tobool = icmp ne i32 %s, 0
3951   ret i1 %tobool
3954 define i1 @signbit_true_logic(i8 %x) {
3955 ; CHECK-LABEL: @signbit_true_logic(
3956 ; CHECK-NEXT:    [[R:%.*]] = icmp eq i8 [[X:%.*]], 0
3957 ; CHECK-NEXT:    ret i1 [[R]]
3959   %dec = add i8 %x, -1
3960   %not = xor i8 %x, -1
3961   %and = and i8 %dec, %not
3962   %r = icmp slt i8 %and, 0
3963   ret i1 %r
3966 define <2 x i1> @signbit_false_logic(<2 x i5> %x) {
3967 ; CHECK-LABEL: @signbit_false_logic(
3968 ; CHECK-NEXT:    [[R:%.*]] = icmp ne <2 x i5> [[X:%.*]], zeroinitializer
3969 ; CHECK-NEXT:    ret <2 x i1> [[R]]
3971   %dec = add <2 x i5> %x,  <i5 -1, i5 undef>
3972   %not = xor <2 x i5> %x,  <i5 -1, i5 -1>
3973   %and = and <2 x i5> %dec, %not
3974   %r = icmp sgt <2 x i5> %and, <i5 -1, i5 -1>
3975   ret <2 x i1> %r
3978 ; Confirm that complexity canonicalization works for commuted pattern.
3980 define i1 @signbit_true_logic_uses_commute(i64 %x) {
3981 ; CHECK-LABEL: @signbit_true_logic_uses_commute(
3982 ; CHECK-NEXT:    [[DEC:%.*]] = add i64 [[X:%.*]], -1
3983 ; CHECK-NEXT:    call void @use_i64(i64 [[DEC]])
3984 ; CHECK-NEXT:    [[NOT:%.*]] = xor i64 [[X]], -1
3985 ; CHECK-NEXT:    call void @use_i64(i64 [[NOT]])
3986 ; CHECK-NEXT:    [[AND:%.*]] = and i64 [[DEC]], [[NOT]]
3987 ; CHECK-NEXT:    call void @use_i64(i64 [[AND]])
3988 ; CHECK-NEXT:    [[R:%.*]] = icmp eq i64 [[X]], 0
3989 ; CHECK-NEXT:    ret i1 [[R]]
3991   %dec = add i64 %x, -1
3992   call void @use_i64(i64 %dec)
3993   %not = xor i64 %x, -1
3994   call void @use_i64(i64 %not)
3995   %and = and i64 %not, %dec
3996   call void @use_i64(i64 %and)
3997   %r = icmp slt i64 %and, 0
3998   ret i1 %r