[test] Update the name of the debug entry values option. NFC
[llvm-core.git] / test / Transforms / InstCombine / icmp.ll
blob3fecf97e89dbd340f3f1bb2ffaaafaf82f5605e1
1 ; NOTE: Assertions have been autogenerated by utils/update_test_checks.py
2 ; RUN: opt < %s -instcombine -S | FileCheck %s
4 target datalayout = "e-p:64:64:64-p1:16:16:16-p2:32:32:32-p3:64:64:64-i1:8:8-i8:8:8-i16:16:16-i32:32:32-i64:64:64-f32:32:32-f64:64:64-v64:64:64-v128:128:128-a0:0:64-s0:64:64-f80:128:128-n8:16:32:64"
6 define i32 @test1(i32 %X) {
7 ; CHECK-LABEL: @test1(
8 ; CHECK-NEXT:    [[X_LOBIT:%.*]] = lshr i32 [[X:%.*]], 31
9 ; CHECK-NEXT:    ret i32 [[X_LOBIT]]
11   %a = icmp slt i32 %X, 0
12   %b = zext i1 %a to i32
13   ret i32 %b
16 define <2 x i32> @test1vec(<2 x i32> %X) {
17 ; CHECK-LABEL: @test1vec(
18 ; CHECK-NEXT:    [[X_LOBIT:%.*]] = lshr <2 x i32> [[X:%.*]], <i32 31, i32 31>
19 ; CHECK-NEXT:    ret <2 x i32> [[X_LOBIT]]
21   %a = icmp slt <2 x i32> %X, zeroinitializer
22   %b = zext <2 x i1> %a to <2 x i32>
23   ret <2 x i32> %b
26 define i32 @test2(i32 %X) {
27 ; CHECK-LABEL: @test2(
28 ; CHECK-NEXT:    [[X_LOBIT:%.*]] = lshr i32 [[X:%.*]], 31
29 ; CHECK-NEXT:    [[X_LOBIT_NOT:%.*]] = xor i32 [[X_LOBIT]], 1
30 ; CHECK-NEXT:    ret i32 [[X_LOBIT_NOT]]
32   %a = icmp ult i32 %X, -2147483648
33   %b = zext i1 %a to i32
34   ret i32 %b
37 define <2 x i32> @test2vec(<2 x i32> %X) {
38 ; CHECK-LABEL: @test2vec(
39 ; CHECK-NEXT:    [[X_LOBIT:%.*]] = lshr <2 x i32> [[X:%.*]], <i32 31, i32 31>
40 ; CHECK-NEXT:    [[X_LOBIT_NOT:%.*]] = xor <2 x i32> [[X_LOBIT]], <i32 1, i32 1>
41 ; CHECK-NEXT:    ret <2 x i32> [[X_LOBIT_NOT]]
43   %a = icmp ult <2 x i32> %X, <i32 -2147483648, i32 -2147483648>
44   %b = zext <2 x i1> %a to <2 x i32>
45   ret <2 x i32> %b
48 define i32 @test3(i32 %X) {
49 ; CHECK-LABEL: @test3(
50 ; CHECK-NEXT:    [[X_LOBIT:%.*]] = ashr i32 [[X:%.*]], 31
51 ; CHECK-NEXT:    ret i32 [[X_LOBIT]]
53   %a = icmp slt i32 %X, 0
54   %b = sext i1 %a to i32
55   ret i32 %b
58 define i32 @test4(i32 %X) {
59 ; CHECK-LABEL: @test4(
60 ; CHECK-NEXT:    [[X_LOBIT:%.*]] = ashr i32 [[X:%.*]], 31
61 ; CHECK-NEXT:    [[X_LOBIT_NOT:%.*]] = xor i32 [[X_LOBIT]], -1
62 ; CHECK-NEXT:    ret i32 [[X_LOBIT_NOT]]
64   %a = icmp ult i32 %X, -2147483648
65   %b = sext i1 %a to i32
66   ret i32 %b
69 ; PR4837
70 define <2 x i1> @test5_eq(<2 x i64> %x) {
71 ; CHECK-LABEL: @test5_eq(
72 ; CHECK-NEXT:    ret <2 x i1> undef
74   %V = icmp eq <2 x i64> %x, undef
75   ret <2 x i1> %V
77 define <2 x i1> @test5_ne(<2 x i64> %x) {
78 ; CHECK-LABEL: @test5_ne(
79 ; CHECK-NEXT:    ret <2 x i1> undef
81   %V = icmp ne <2 x i64> %x, undef
82   ret <2 x i1> %V
84 define <2 x i1> @test5_ugt(<2 x i64> %x) {
85 ; CHECK-LABEL: @test5_ugt(
86 ; CHECK-NEXT:    ret <2 x i1> zeroinitializer
88   %V = icmp ugt <2 x i64> %x, undef
89   ret <2 x i1> %V
91 define <2 x i1> @test5_zero() {
92 ; CHECK-LABEL: @test5_zero(
93 ; CHECK-NEXT:    ret <2 x i1> undef
95   %V = icmp eq <2 x i64> zeroinitializer, undef
96   ret <2 x i1> %V
99 define i32 @test6(i32 %a, i32 %b) {
100 ; CHECK-LABEL: @test6(
101 ; CHECK-NEXT:    [[E:%.*]] = ashr i32 [[A:%.*]], 31
102 ; CHECK-NEXT:    [[F:%.*]] = and i32 [[E]], [[B:%.*]]
103 ; CHECK-NEXT:    ret i32 [[F]]
105   %c = icmp sle i32 %a, -1
106   %d = zext i1 %c to i32
107   %e = sub i32 0, %d
108   %f = and i32 %e, %b
109   ret i32 %f
113 define i1 @test7(i32 %x) {
114 ; CHECK-LABEL: @test7(
115 ; CHECK-NEXT:    [[B:%.*]] = icmp ne i32 [[X:%.*]], 0
116 ; CHECK-NEXT:    ret i1 [[B]]
118   %a = add i32 %x, -1
119   %b = icmp ult i32 %a, %x
120   ret i1 %b
123 define <2 x i1> @test7_vec(<2 x i32> %x) {
124 ; CHECK-LABEL: @test7_vec(
125 ; CHECK-NEXT:    [[B:%.*]] = icmp ne <2 x i32> [[X:%.*]], zeroinitializer
126 ; CHECK-NEXT:    ret <2 x i1> [[B]]
128   %a = add <2 x i32> %x, <i32 -1, i32 -1>
129   %b = icmp ult <2 x i32> %a, %x
130   ret <2 x i1> %b
133 define i1 @test8(i32 %x) {
134 ; CHECK-LABEL: @test8(
135 ; CHECK-NEXT:    ret i1 false
137   %a = add i32 %x, -1
138   %b = icmp eq i32 %a, %x
139   ret i1 %b
142 define <2 x i1> @test8_vec(<2 x i32> %x) {
143 ; CHECK-LABEL: @test8_vec(
144 ; CHECK-NEXT:    ret <2 x i1> zeroinitializer
146   %a = add <2 x i32> %x, <i32 -1, i32 -1>
147   %b = icmp eq <2 x i32> %a, %x
148   ret <2 x i1> %b
151 define i1 @test9(i32 %x) {
152 ; CHECK-LABEL: @test9(
153 ; CHECK-NEXT:    [[B:%.*]] = icmp ugt i32 [[X:%.*]], 1
154 ; CHECK-NEXT:    ret i1 [[B]]
156   %a = add i32 %x, -2
157   %b = icmp ugt i32 %x, %a
158   ret i1 %b
161 define <2 x i1> @test9_vec(<2 x i32> %x) {
162 ; CHECK-LABEL: @test9_vec(
163 ; CHECK-NEXT:    [[B:%.*]] = icmp ugt <2 x i32> [[X:%.*]], <i32 1, i32 1>
164 ; CHECK-NEXT:    ret <2 x i1> [[B]]
166   %a = add <2 x i32> %x, <i32 -2, i32 -2>
167   %b = icmp ugt <2 x i32> %x, %a
168   ret <2 x i1> %b
171 define i1 @test9b(i32 %x) {
172 ; CHECK-LABEL: @test9b(
173 ; CHECK-NEXT:    [[B:%.*]] = icmp ult i32 [[X:%.*]], 2
174 ; CHECK-NEXT:    ret i1 [[B]]
176   %a = add i32 %x, -2
177   %b = icmp ugt i32 %a, %x
178   ret i1 %b
181 define <2 x i1> @test9b_vec(<2 x i32> %x) {
182 ; CHECK-LABEL: @test9b_vec(
183 ; CHECK-NEXT:    [[B:%.*]] = icmp ult <2 x i32> [[X:%.*]], <i32 2, i32 2>
184 ; CHECK-NEXT:    ret <2 x i1> [[B]]
186   %a = add <2 x i32> %x, <i32 -2, i32 -2>
187   %b = icmp ugt <2 x i32> %a, %x
188   ret <2 x i1> %b
191 define i1 @test10(i32 %x) {
192 ; CHECK-LABEL: @test10(
193 ; CHECK-NEXT:    [[B:%.*]] = icmp ne i32 [[X:%.*]], -2147483648
194 ; CHECK-NEXT:    ret i1 [[B]]
196   %a = add i32 %x, -1
197   %b = icmp slt i32 %a, %x
198   ret i1 %b
201 define <2 x i1> @test10_vec(<2 x i32> %x) {
202 ; CHECK-LABEL: @test10_vec(
203 ; CHECK-NEXT:    [[B:%.*]] = icmp ne <2 x i32> [[X:%.*]], <i32 -2147483648, i32 -2147483648>
204 ; CHECK-NEXT:    ret <2 x i1> [[B]]
206   %a = add <2 x i32> %x, <i32 -1, i32 -1>
207   %b = icmp slt <2 x i32> %a, %x
208   ret <2 x i1> %b
211 define i1 @test10b(i32 %x) {
212 ; CHECK-LABEL: @test10b(
213 ; CHECK-NEXT:    [[B:%.*]] = icmp eq i32 [[X:%.*]], -2147483648
214 ; CHECK-NEXT:    ret i1 [[B]]
216   %a = add i32 %x, -1
217   %b = icmp sgt i32 %a, %x
218   ret i1 %b
221 define <2 x i1> @test10b_vec(<2 x i32> %x) {
222 ; CHECK-LABEL: @test10b_vec(
223 ; CHECK-NEXT:    [[B:%.*]] = icmp eq <2 x i32> [[X:%.*]], <i32 -2147483648, i32 -2147483648>
224 ; CHECK-NEXT:    ret <2 x i1> [[B]]
226   %a = add <2 x i32> %x, <i32 -1, i32 -1>
227   %b = icmp sgt <2 x i32> %a, %x
228   ret <2 x i1> %b
231 define i1 @test11(i32 %x) {
232 ; CHECK-LABEL: @test11(
233 ; CHECK-NEXT:    ret i1 true
235   %a = add nsw i32 %x, 8
236   %b = icmp slt i32 %x, %a
237   ret i1 %b
240 define <2 x i1> @test11_vec(<2 x i32> %x) {
241 ; CHECK-LABEL: @test11_vec(
242 ; CHECK-NEXT:    ret <2 x i1> <i1 true, i1 true>
244   %a = add nsw <2 x i32> %x, <i32 8, i32 8>
245   %b = icmp slt <2 x i32> %x, %a
246   ret <2 x i1> %b
249 ; PR6195
250 define i1 @test12(i1 %A) {
251 ; CHECK-LABEL: @test12(
252 ; CHECK-NEXT:    [[NOT_A:%.*]] = xor i1 [[A:%.*]], true
253 ; CHECK-NEXT:    ret i1 [[NOT_A]]
255   %S = select i1 %A, i64 -4294967295, i64 8589934591
256   %B = icmp ne i64 bitcast (<2 x i32> <i32 1, i32 -1> to i64), %S
257   ret i1 %B
260 ; PR6481
261 define i1 @test13(i8 %X) {
262 ; CHECK-LABEL: @test13(
263 ; CHECK-NEXT:    ret i1 false
265   %cmp = icmp slt i8 undef, %X
266   ret i1 %cmp
269 define i1 @test14(i8 %X) {
270 ; CHECK-LABEL: @test14(
271 ; CHECK-NEXT:    ret i1 false
273   %cmp = icmp slt i8 undef, -128
274   ret i1 %cmp
277 define i1 @test15() {
278 ; CHECK-LABEL: @test15(
279 ; CHECK-NEXT:    ret i1 undef
281   %cmp = icmp eq i8 undef, -128
282   ret i1 %cmp
285 define i1 @test16() {
286 ; CHECK-LABEL: @test16(
287 ; CHECK-NEXT:    ret i1 undef
289   %cmp = icmp ne i8 undef, -128
290   ret i1 %cmp
293 define i1 @test17(i32 %x) {
294 ; CHECK-LABEL: @test17(
295 ; CHECK-NEXT:    [[CMP:%.*]] = icmp ne i32 [[X:%.*]], 3
296 ; CHECK-NEXT:    ret i1 [[CMP]]
298   %shl = shl i32 1, %x
299   %and = and i32 %shl, 8
300   %cmp = icmp eq i32 %and, 0
301   ret i1 %cmp
304 define <2 x i1> @test17vec(<2 x i32> %x) {
305 ; CHECK-LABEL: @test17vec(
306 ; CHECK-NEXT:    [[CMP:%.*]] = icmp ne <2 x i32> [[X:%.*]], <i32 3, i32 3>
307 ; CHECK-NEXT:    ret <2 x i1> [[CMP]]
309   %shl = shl <2 x i32> <i32 1, i32 1>, %x
310   %and = and <2 x i32> %shl, <i32 8, i32 8>
311   %cmp = icmp eq <2 x i32> %and, zeroinitializer
312   ret <2 x i1> %cmp
315 define i1 @test17a(i32 %x) {
316 ; CHECK-LABEL: @test17a(
317 ; CHECK-NEXT:    [[CMP:%.*]] = icmp ugt i32 [[X:%.*]], 2
318 ; CHECK-NEXT:    ret i1 [[CMP]]
320   %shl = shl i32 1, %x
321   %and = and i32 %shl, 7
322   %cmp = icmp eq i32 %and, 0
323   ret i1 %cmp
326 define <2 x i1> @test17a_vec(<2 x i32> %x) {
327 ; CHECK-LABEL: @test17a_vec(
328 ; CHECK-NEXT:    [[CMP:%.*]] = icmp ugt <2 x i32> [[X:%.*]], <i32 2, i32 2>
329 ; CHECK-NEXT:    ret <2 x i1> [[CMP]]
331   %shl = shl <2 x i32> <i32 1, i32 1>, %x
332   %and = and <2 x i32> %shl, <i32 7, i32 7>
333   %cmp = icmp eq <2 x i32> %and, zeroinitializer
334   ret <2 x i1> %cmp
337 define i1 @test18_eq(i32 %x) {
338 ; CHECK-LABEL: @test18_eq(
339 ; CHECK-NEXT:    [[CMP:%.*]] = icmp ne i32 [[X:%.*]], 3
340 ; CHECK-NEXT:    ret i1 [[CMP]]
342   %sh = lshr i32 8, %x
343   %and = and i32 %sh, 1
344   %cmp = icmp eq i32 %and, 0
345   ret i1 %cmp
348 define <2 x i1> @test18_eq_vec(<2 x i32> %x) {
349 ; CHECK-LABEL: @test18_eq_vec(
350 ; CHECK-NEXT:    [[CMP:%.*]] = icmp ne <2 x i32> [[X:%.*]], <i32 3, i32 3>
351 ; CHECK-NEXT:    ret <2 x i1> [[CMP]]
353   %sh = lshr <2 x i32> <i32 8, i32 8>, %x
354   %and = and <2 x i32> %sh, <i32 1, i32 1>
355   %cmp = icmp eq <2 x i32> %and, zeroinitializer
356   ret <2 x i1> %cmp
359 define i1 @test18_ne(i32 %x) {
360 ; CHECK-LABEL: @test18_ne(
361 ; CHECK-NEXT:    [[CMP:%.*]] = icmp eq i32 [[X:%.*]], 3
362 ; CHECK-NEXT:    ret i1 [[CMP]]
364   %sh = lshr i32 8, %x
365   %and = and i32 %sh, 1
366   %cmp = icmp ne i32 %and, 0
367   ret i1 %cmp
370 define <2 x i1> @test18_ne_vec(<2 x i32> %x) {
371 ; CHECK-LABEL: @test18_ne_vec(
372 ; CHECK-NEXT:    [[CMP:%.*]] = icmp eq <2 x i32> [[X:%.*]], <i32 3, i32 3>
373 ; CHECK-NEXT:    ret <2 x i1> [[CMP]]
375   %sh = lshr <2 x i32> <i32 8, i32 8>, %x
376   %and = and <2 x i32> %sh, <i32 1, i32 1>
377   %cmp = icmp ne <2 x i32> %and, zeroinitializer
378   ret <2 x i1> %cmp
381 define i1 @test19(i32 %x) {
382 ; CHECK-LABEL: @test19(
383 ; CHECK-NEXT:    [[CMP:%.*]] = icmp eq i32 [[X:%.*]], 3
384 ; CHECK-NEXT:    ret i1 [[CMP]]
386   %shl = shl i32 1, %x
387   %and = and i32 %shl, 8
388   %cmp = icmp eq i32 %and, 8
389   ret i1 %cmp
392 define <2 x i1> @test19vec(<2 x i32> %x) {
393 ; CHECK-LABEL: @test19vec(
394 ; CHECK-NEXT:    [[CMP:%.*]] = icmp eq <2 x i32> [[X:%.*]], <i32 3, i32 3>
395 ; CHECK-NEXT:    ret <2 x i1> [[CMP]]
397   %shl = shl <2 x i32> <i32 1, i32 1>, %x
398   %and = and <2 x i32> %shl, <i32 8, i32 8>
399   %cmp = icmp eq <2 x i32> %and, <i32 8, i32 8>
400   ret <2 x i1> %cmp
403 define <2 x i1> @cmp_and_signbit_vec(<2 x i3> %x) {
404 ; CHECK-LABEL: @cmp_and_signbit_vec(
405 ; CHECK-NEXT:    [[CMP:%.*]] = icmp slt <2 x i3> [[X:%.*]], zeroinitializer
406 ; CHECK-NEXT:    ret <2 x i1> [[CMP]]
408   %and = and <2 x i3> %x, <i3 4, i3 4>
409   %cmp = icmp ne <2 x i3> %and, zeroinitializer
410   ret <2 x i1> %cmp
413 define i1 @test20(i32 %x) {
414 ; CHECK-LABEL: @test20(
415 ; CHECK-NEXT:    [[CMP:%.*]] = icmp eq i32 [[X:%.*]], 3
416 ; CHECK-NEXT:    ret i1 [[CMP]]
418   %shl = shl i32 1, %x
419   %and = and i32 %shl, 8
420   %cmp = icmp ne i32 %and, 0
421   ret i1 %cmp
424 define <2 x i1> @test20vec(<2 x i32> %x) {
425 ; CHECK-LABEL: @test20vec(
426 ; CHECK-NEXT:    [[CMP:%.*]] = icmp eq <2 x i32> [[X:%.*]], <i32 3, i32 3>
427 ; CHECK-NEXT:    ret <2 x i1> [[CMP]]
429   %shl = shl <2 x i32> <i32 1, i32 1>, %x
430   %and = and <2 x i32> %shl, <i32 8, i32 8>
431   %cmp = icmp ne <2 x i32> %and, zeroinitializer
432   ret <2 x i1> %cmp
435 define i1 @test20a(i32 %x) {
436 ; CHECK-LABEL: @test20a(
437 ; CHECK-NEXT:    [[CMP:%.*]] = icmp ult i32 [[X:%.*]], 3
438 ; CHECK-NEXT:    ret i1 [[CMP]]
440   %shl = shl i32 1, %x
441   %and = and i32 %shl, 7
442   %cmp = icmp ne i32 %and, 0
443   ret i1 %cmp
446 define <2 x i1> @test20a_vec(<2 x i32> %x) {
447 ; CHECK-LABEL: @test20a_vec(
448 ; CHECK-NEXT:    [[CMP:%.*]] = icmp ult <2 x i32> [[X:%.*]], <i32 3, i32 3>
449 ; CHECK-NEXT:    ret <2 x i1> [[CMP]]
451   %shl = shl <2 x i32> <i32 1, i32 1>, %x
452   %and = and <2 x i32> %shl, <i32 7, i32 7>
453   %cmp = icmp ne <2 x i32> %and, zeroinitializer
454   ret <2 x i1> %cmp
457 define i1 @test21(i8 %x, i8 %y) {
458 ; CHECK-LABEL: @test21(
459 ; CHECK-NEXT:    [[B:%.*]] = icmp ugt i8 [[X:%.*]], 3
460 ; CHECK-NEXT:    ret i1 [[B]]
462   %A = or i8 %x, 1
463   %B = icmp ugt i8 %A, 3
464   ret i1 %B
467 define i1 @test22(i8 %x, i8 %y) {
468 ; CHECK-LABEL: @test22(
469 ; CHECK-NEXT:    [[B:%.*]] = icmp ult i8 [[X:%.*]], 4
470 ; CHECK-NEXT:    ret i1 [[B]]
472   %A = or i8 %x, 1
473   %B = icmp ult i8 %A, 4
474   ret i1 %B
477 ; PR2740
478 define i1 @test23(i32 %x) {
479 ; CHECK-LABEL: @test23(
480 ; CHECK-NEXT:    [[I4:%.*]] = icmp sgt i32 [[X:%.*]], 1328634634
481 ; CHECK-NEXT:    ret i1 [[I4]]
483   %i3 = sdiv i32 %x, -1328634635
484   %i4 = icmp eq i32 %i3, -1
485   ret i1 %i4
488 define <2 x i1> @test23vec(<2 x i32> %x) {
489 ; CHECK-LABEL: @test23vec(
490 ; CHECK-NEXT:    [[I4:%.*]] = icmp sgt <2 x i32> [[X:%.*]], <i32 1328634634, i32 1328634634>
491 ; CHECK-NEXT:    ret <2 x i1> [[I4]]
493   %i3 = sdiv <2 x i32> %x, <i32 -1328634635, i32 -1328634635>
494   %i4 = icmp eq <2 x i32> %i3, <i32 -1, i32 -1>
495   ret <2 x i1> %i4
498 @X = global [1000 x i32] zeroinitializer
500 ; PR8882
501 define i1 @test24(i64 %i) {
502 ; CHECK-LABEL: @test24(
503 ; CHECK-NEXT:    [[CMP:%.*]] = icmp eq i64 [[I:%.*]], 1000
504 ; CHECK-NEXT:    ret i1 [[CMP]]
506   %p1 = getelementptr inbounds i32, i32* getelementptr inbounds ([1000 x i32], [1000 x i32]* @X, i64 0, i64 0), i64 %i
507   %cmp = icmp eq i32* %p1, getelementptr inbounds ([1000 x i32], [1000 x i32]* @X, i64 1, i64 0)
508   ret i1 %cmp
511 @X_as1 = addrspace(1) global [1000 x i32] zeroinitializer
513 define i1 @test24_as1(i64 %i) {
514 ; CHECK-LABEL: @test24_as1(
515 ; CHECK-NEXT:    [[TMP1:%.*]] = trunc i64 [[I:%.*]] to i16
516 ; CHECK-NEXT:    [[CMP:%.*]] = icmp eq i16 [[TMP1]], 1000
517 ; CHECK-NEXT:    ret i1 [[CMP]]
519   %p1 = getelementptr inbounds i32, i32 addrspace(1)* getelementptr inbounds ([1000 x i32], [1000 x i32] addrspace(1)* @X_as1, i64 0, i64 0), i64 %i
520   %cmp = icmp eq i32 addrspace(1)* %p1, getelementptr inbounds ([1000 x i32], [1000 x i32] addrspace(1)* @X_as1, i64 1, i64 0)
521   ret i1 %cmp
524 define i1 @test25(i32 %x, i32 %y, i32 %z) {
525 ; CHECK-LABEL: @test25(
526 ; CHECK-NEXT:    [[C:%.*]] = icmp sgt i32 [[X:%.*]], [[Y:%.*]]
527 ; CHECK-NEXT:    ret i1 [[C]]
529   %lhs = add nsw i32 %x, %z
530   %rhs = add nsw i32 %y, %z
531   %c = icmp sgt i32 %lhs, %rhs
532   ret i1 %c
535 ; X + Z > Y + Z -> X > Y if there is no overflow.
536 define i1 @test26(i32 %x, i32 %y, i32 %z) {
537 ; CHECK-LABEL: @test26(
538 ; CHECK-NEXT:    [[C:%.*]] = icmp ugt i32 [[X:%.*]], [[Y:%.*]]
539 ; CHECK-NEXT:    ret i1 [[C]]
541   %lhs = add nuw i32 %x, %z
542   %rhs = add nuw i32 %y, %z
543   %c = icmp ugt i32 %lhs, %rhs
544   ret i1 %c
547 ; X - Z > Y - Z -> X > Y if there is no overflow.
548 define i1 @test27(i32 %x, i32 %y, i32 %z) {
549 ; CHECK-LABEL: @test27(
550 ; CHECK-NEXT:    [[C:%.*]] = icmp sgt i32 [[X:%.*]], [[Y:%.*]]
551 ; CHECK-NEXT:    ret i1 [[C]]
553   %lhs = sub nsw i32 %x, %z
554   %rhs = sub nsw i32 %y, %z
555   %c = icmp sgt i32 %lhs, %rhs
556   ret i1 %c
559 ; X - Z > Y - Z -> X > Y if there is no overflow.
560 define i1 @test28(i32 %x, i32 %y, i32 %z) {
561 ; CHECK-LABEL: @test28(
562 ; CHECK-NEXT:    [[C:%.*]] = icmp ugt i32 [[X:%.*]], [[Y:%.*]]
563 ; CHECK-NEXT:    ret i1 [[C]]
565   %lhs = sub nuw i32 %x, %z
566   %rhs = sub nuw i32 %y, %z
567   %c = icmp ugt i32 %lhs, %rhs
568   ret i1 %c
571 ; X + Y > X -> Y > 0 if there is no overflow.
572 define i1 @test29(i32 %x, i32 %y) {
573 ; CHECK-LABEL: @test29(
574 ; CHECK-NEXT:    [[C:%.*]] = icmp sgt i32 [[Y:%.*]], 0
575 ; CHECK-NEXT:    ret i1 [[C]]
577   %lhs = add nsw i32 %x, %y
578   %c = icmp sgt i32 %lhs, %x
579   ret i1 %c
582 ; X + Y > X -> Y > 0 if there is no overflow.
583 define i1 @test30(i32 %x, i32 %y) {
584 ; CHECK-LABEL: @test30(
585 ; CHECK-NEXT:    [[C:%.*]] = icmp ne i32 [[Y:%.*]], 0
586 ; CHECK-NEXT:    ret i1 [[C]]
588   %lhs = add nuw i32 %x, %y
589   %c = icmp ugt i32 %lhs, %x
590   ret i1 %c
593 ; X > X + Y -> 0 > Y if there is no overflow.
594 define i1 @test31(i32 %x, i32 %y) {
595 ; CHECK-LABEL: @test31(
596 ; CHECK-NEXT:    [[C:%.*]] = icmp slt i32 [[Y:%.*]], 0
597 ; CHECK-NEXT:    ret i1 [[C]]
599   %rhs = add nsw i32 %x, %y
600   %c = icmp sgt i32 %x, %rhs
601   ret i1 %c
604 ; X > X + Y -> 0 > Y if there is no overflow.
605 define i1 @test32(i32 %x, i32 %y) {
606 ; CHECK-LABEL: @test32(
607 ; CHECK-NEXT:    ret i1 false
609   %rhs = add nuw i32 %x, %y
610   %c = icmp ugt i32 %x, %rhs
611   ret i1 %c
614 ; X - Y > X -> 0 > Y if there is no overflow.
615 define i1 @test33(i32 %x, i32 %y) {
616 ; CHECK-LABEL: @test33(
617 ; CHECK-NEXT:    [[C:%.*]] = icmp slt i32 [[Y:%.*]], 0
618 ; CHECK-NEXT:    ret i1 [[C]]
620   %lhs = sub nsw i32 %x, %y
621   %c = icmp sgt i32 %lhs, %x
622   ret i1 %c
625 ; X - Y > X -> 0 > Y if there is no overflow.
626 define i1 @test34(i32 %x, i32 %y) {
627 ; CHECK-LABEL: @test34(
628 ; CHECK-NEXT:    ret i1 false
630   %lhs = sub nuw i32 %x, %y
631   %c = icmp ugt i32 %lhs, %x
632   ret i1 %c
635 ; X > X - Y -> Y > 0 if there is no overflow.
636 define i1 @test35(i32 %x, i32 %y) {
637 ; CHECK-LABEL: @test35(
638 ; CHECK-NEXT:    [[C:%.*]] = icmp sgt i32 [[Y:%.*]], 0
639 ; CHECK-NEXT:    ret i1 [[C]]
641   %rhs = sub nsw i32 %x, %y
642   %c = icmp sgt i32 %x, %rhs
643   ret i1 %c
646 ; X > X - Y -> Y > 0 if there is no overflow.
647 define i1 @test36(i32 %x, i32 %y) {
648 ; CHECK-LABEL: @test36(
649 ; CHECK-NEXT:    [[C:%.*]] = icmp ne i32 [[Y:%.*]], 0
650 ; CHECK-NEXT:    ret i1 [[C]]
652   %rhs = sub nuw i32 %x, %y
653   %c = icmp ugt i32 %x, %rhs
654   ret i1 %c
657 ; PR36969 - https://bugs.llvm.org/show_bug.cgi?id=36969
659 define i1 @ugt_sub(i32 %xsrc, i32 %y) {
660 ; CHECK-LABEL: @ugt_sub(
661 ; CHECK-NEXT:    [[X:%.*]] = udiv i32 [[XSRC:%.*]], 42
662 ; CHECK-NEXT:    [[CMP:%.*]] = icmp ult i32 [[X]], [[Y:%.*]]
663 ; CHECK-NEXT:    ret i1 [[CMP]]
665   %x = udiv i32 %xsrc, 42 ; thwart complexity-based canonicalization
666   %sub = sub i32 %x, %y
667   %cmp = icmp ugt i32 %sub, %x
668   ret i1 %cmp
671 ; Swap operands and predicate. Try a vector type to verify that works too.
673 define <2 x i1> @ult_sub(<2 x i8> %xsrc, <2 x i8> %y) {
674 ; CHECK-LABEL: @ult_sub(
675 ; CHECK-NEXT:    [[X:%.*]] = udiv <2 x i8> [[XSRC:%.*]], <i8 42, i8 -42>
676 ; CHECK-NEXT:    [[CMP:%.*]] = icmp ult <2 x i8> [[X]], [[Y:%.*]]
677 ; CHECK-NEXT:    ret <2 x i1> [[CMP]]
679   %x = udiv <2 x i8> %xsrc, <i8 42, i8 -42> ; thwart complexity-based canonicalization
680   %sub = sub <2 x i8> %x, %y
681   %cmp = icmp ult <2 x i8> %x, %sub
682   ret <2 x i1> %cmp
685 ; X - Y > X - Z -> Z > Y if there is no overflow.
686 define i1 @test37(i32 %x, i32 %y, i32 %z) {
687 ; CHECK-LABEL: @test37(
688 ; CHECK-NEXT:    [[C:%.*]] = icmp sgt i32 [[Z:%.*]], [[Y:%.*]]
689 ; CHECK-NEXT:    ret i1 [[C]]
691   %lhs = sub nsw i32 %x, %y
692   %rhs = sub nsw i32 %x, %z
693   %c = icmp sgt i32 %lhs, %rhs
694   ret i1 %c
697 ; X - Y > X - Z -> Z > Y if there is no overflow.
698 define i1 @test38(i32 %x, i32 %y, i32 %z) {
699 ; CHECK-LABEL: @test38(
700 ; CHECK-NEXT:    [[C:%.*]] = icmp ugt i32 [[Z:%.*]], [[Y:%.*]]
701 ; CHECK-NEXT:    ret i1 [[C]]
703   %lhs = sub nuw i32 %x, %y
704   %rhs = sub nuw i32 %x, %z
705   %c = icmp ugt i32 %lhs, %rhs
706   ret i1 %c
709 ; PR9343 #1
710 define i1 @test39(i32 %X, i32 %Y) {
711 ; CHECK-LABEL: @test39(
712 ; CHECK-NEXT:    [[B:%.*]] = icmp eq i32 [[X:%.*]], 0
713 ; CHECK-NEXT:    ret i1 [[B]]
715   %A = ashr exact i32 %X, %Y
716   %B = icmp eq i32 %A, 0
717   ret i1 %B
720 define <2 x i1> @test39vec(<2 x i32> %X, <2 x i32> %Y) {
721 ; CHECK-LABEL: @test39vec(
722 ; CHECK-NEXT:    [[B:%.*]] = icmp eq <2 x i32> [[X:%.*]], zeroinitializer
723 ; CHECK-NEXT:    ret <2 x i1> [[B]]
725   %A = ashr exact <2 x i32> %X, %Y
726   %B = icmp eq <2 x i32> %A, zeroinitializer
727   ret <2 x i1> %B
730 define i1 @test40(i32 %X, i32 %Y) {
731 ; CHECK-LABEL: @test40(
732 ; CHECK-NEXT:    [[B:%.*]] = icmp ne i32 [[X:%.*]], 0
733 ; CHECK-NEXT:    ret i1 [[B]]
735   %A = lshr exact i32 %X, %Y
736   %B = icmp ne i32 %A, 0
737   ret i1 %B
740 define <2 x i1> @test40vec(<2 x i32> %X, <2 x i32> %Y) {
741 ; CHECK-LABEL: @test40vec(
742 ; CHECK-NEXT:    [[B:%.*]] = icmp ne <2 x i32> [[X:%.*]], zeroinitializer
743 ; CHECK-NEXT:    ret <2 x i1> [[B]]
745   %A = lshr exact <2 x i32> %X, %Y
746   %B = icmp ne <2 x i32> %A, zeroinitializer
747   ret <2 x i1> %B
750 define i1 @shr_exact(i132 %x) {
751 ; CHECK-LABEL: @shr_exact(
752 ; CHECK-NEXT:    [[CMP:%.*]] = icmp eq i132 [[X:%.*]], 32
753 ; CHECK-NEXT:    ret i1 [[CMP]]
755   %sh = ashr exact i132 %x, 4
756   %cmp = icmp eq i132 %sh, 2
757   ret i1 %cmp
760 define <2 x i1> @shr_exact_vec(<2 x i132> %x) {
761 ; CHECK-LABEL: @shr_exact_vec(
762 ; CHECK-NEXT:    [[CMP:%.*]] = icmp ne <2 x i132> [[X:%.*]], <i132 32, i132 32>
763 ; CHECK-NEXT:    ret <2 x i1> [[CMP]]
765   %sh = lshr exact <2 x i132> %x, <i132 4, i132 4>
766   %cmp = icmp ne <2 x i132> %sh, <i132 2, i132 2>
767   ret <2 x i1> %cmp
770 ; PR9343 #3
771 define i1 @test41(i32 %X, i32 %Y) {
772 ; CHECK-LABEL: @test41(
773 ; CHECK-NEXT:    ret i1 true
775   %A = urem i32 %X, %Y
776   %B = icmp ugt i32 %Y, %A
777   ret i1 %B
780 define i1 @test42(i32 %X, i32 %Y) {
781 ; CHECK-LABEL: @test42(
782 ; CHECK-NEXT:    [[B:%.*]] = icmp sgt i32 [[Y:%.*]], -1
783 ; CHECK-NEXT:    ret i1 [[B]]
785   %A = srem i32 %X, %Y
786   %B = icmp slt i32 %A, %Y
787   ret i1 %B
790 define i1 @test43(i32 %X, i32 %Y) {
791 ; CHECK-LABEL: @test43(
792 ; CHECK-NEXT:    [[B:%.*]] = icmp slt i32 [[Y:%.*]], 0
793 ; CHECK-NEXT:    ret i1 [[B]]
795   %A = srem i32 %X, %Y
796   %B = icmp slt i32 %Y, %A
797   ret i1 %B
800 define i1 @test44(i32 %X, i32 %Y) {
801 ; CHECK-LABEL: @test44(
802 ; CHECK-NEXT:    [[B:%.*]] = icmp sgt i32 [[Y:%.*]], -1
803 ; CHECK-NEXT:    ret i1 [[B]]
805   %A = srem i32 %X, %Y
806   %B = icmp slt i32 %A, %Y
807   ret i1 %B
810 define i1 @test45(i32 %X, i32 %Y) {
811 ; CHECK-LABEL: @test45(
812 ; CHECK-NEXT:    [[B:%.*]] = icmp slt i32 [[Y:%.*]], 0
813 ; CHECK-NEXT:    ret i1 [[B]]
815   %A = srem i32 %X, %Y
816   %B = icmp slt i32 %Y, %A
817   ret i1 %B
820 ; PR9343 #4
821 define i1 @test46(i32 %X, i32 %Y, i32 %Z) {
822 ; CHECK-LABEL: @test46(
823 ; CHECK-NEXT:    [[C:%.*]] = icmp ult i32 [[X:%.*]], [[Y:%.*]]
824 ; CHECK-NEXT:    ret i1 [[C]]
826   %A = ashr exact i32 %X, %Z
827   %B = ashr exact i32 %Y, %Z
828   %C = icmp ult i32 %A, %B
829   ret i1 %C
832 ; PR9343 #5
833 define i1 @test47(i32 %X, i32 %Y, i32 %Z) {
834 ; CHECK-LABEL: @test47(
835 ; CHECK-NEXT:    [[C:%.*]] = icmp ugt i32 [[X:%.*]], [[Y:%.*]]
836 ; CHECK-NEXT:    ret i1 [[C]]
838   %A = ashr exact i32 %X, %Z
839   %B = ashr exact i32 %Y, %Z
840   %C = icmp ugt i32 %A, %B
841   ret i1 %C
844 ; PR9343 #8
845 define i1 @test48(i32 %X, i32 %Y, i32 %Z) {
846 ; CHECK-LABEL: @test48(
847 ; CHECK-NEXT:    [[C:%.*]] = icmp eq i32 [[X:%.*]], [[Y:%.*]]
848 ; CHECK-NEXT:    ret i1 [[C]]
850   %A = sdiv exact i32 %X, %Z
851   %B = sdiv exact i32 %Y, %Z
852   %C = icmp eq i32 %A, %B
853   ret i1 %C
856 ; The above transform only works for equality predicates.
858 define i1 @PR32949(i32 %X, i32 %Y, i32 %Z) {
859 ; CHECK-LABEL: @PR32949(
860 ; CHECK-NEXT:    [[A:%.*]] = sdiv exact i32 [[X:%.*]], [[Z:%.*]]
861 ; CHECK-NEXT:    [[B:%.*]] = sdiv exact i32 [[Y:%.*]], [[Z]]
862 ; CHECK-NEXT:    [[C:%.*]] = icmp sgt i32 [[A]], [[B]]
863 ; CHECK-NEXT:    ret i1 [[C]]
865   %A = sdiv exact i32 %X, %Z
866   %B = sdiv exact i32 %Y, %Z
867   %C = icmp sgt i32 %A, %B
868   ret i1 %C
871 ; PR8469
872 define <2 x i1> @test49(<2 x i32> %tmp3) {
873 ; CHECK-LABEL: @test49(
874 ; CHECK-NEXT:  entry:
875 ; CHECK-NEXT:    ret <2 x i1> <i1 true, i1 true>
877 entry:
878   %tmp11 = and <2 x i32> %tmp3, <i32 3, i32 3>
879   %cmp = icmp ult <2 x i32> %tmp11, <i32 4, i32 4>
880   ret <2 x i1> %cmp
883 ; PR9343 #7
884 define i1 @test50(i16 %X, i32 %Y) {
885 ; CHECK-LABEL: @test50(
886 ; CHECK-NEXT:    ret i1 true
888   %A = zext i16 %X to i32
889   %B = srem i32 %A, %Y
890   %C = icmp sgt i32 %B, -1
891   ret i1 %C
894 define i1 @test51(i32 %X, i32 %Y) {
895 ; CHECK-LABEL: @test51(
896 ; CHECK-NEXT:    [[A:%.*]] = and i32 [[X:%.*]], -2147483648
897 ; CHECK-NEXT:    [[B:%.*]] = srem i32 [[A]], [[Y:%.*]]
898 ; CHECK-NEXT:    [[C:%.*]] = icmp sgt i32 [[B]], -1
899 ; CHECK-NEXT:    ret i1 [[C]]
901   %A = and i32 %X, 2147483648
902   %B = srem i32 %A, %Y
903   %C = icmp sgt i32 %B, -1
904   ret i1 %C
907 define i1 @test52(i32 %x1) {
908 ; CHECK-LABEL: @test52(
909 ; CHECK-NEXT:    [[TMP1:%.*]] = and i32 [[X1:%.*]], 16711935
910 ; CHECK-NEXT:    [[TMP2:%.*]] = icmp eq i32 [[TMP1]], 4980863
911 ; CHECK-NEXT:    ret i1 [[TMP2]]
913   %conv = and i32 %x1, 255
914   %cmp = icmp eq i32 %conv, 127
915   %tmp2 = lshr i32 %x1, 16
916   %tmp3 = trunc i32 %tmp2 to i8
917   %cmp15 = icmp eq i8 %tmp3, 76
919   %A = and i1 %cmp, %cmp15
920   ret i1 %A
923 define i1 @test52b(i128 %x1) {
924 ; CHECK-LABEL: @test52b(
925 ; CHECK-NEXT:    [[TMP1:%.*]] = and i128 [[X1:%.*]], 16711935
926 ; CHECK-NEXT:    [[TMP2:%.*]] = icmp eq i128 [[TMP1]], 4980863
927 ; CHECK-NEXT:    ret i1 [[TMP2]]
929   %conv = and i128 %x1, 255
930   %cmp = icmp eq i128 %conv, 127
931   %tmp2 = lshr i128 %x1, 16
932   %tmp3 = trunc i128 %tmp2 to i8
933   %cmp15 = icmp eq i8 %tmp3, 76
935   %A = and i1 %cmp, %cmp15
936   ret i1 %A
939 ; PR9838
940 define i1 @test53(i32 %a, i32 %b) {
941 ; CHECK-LABEL: @test53(
942 ; CHECK-NEXT:    [[X:%.*]] = sdiv exact i32 [[A:%.*]], 30
943 ; CHECK-NEXT:    [[Y:%.*]] = sdiv i32 [[B:%.*]], 30
944 ; CHECK-NEXT:    [[Z:%.*]] = icmp eq i32 [[X]], [[Y]]
945 ; CHECK-NEXT:    ret i1 [[Z]]
947   %x = sdiv exact i32 %a, 30
948   %y = sdiv i32 %b, 30
949   %z = icmp eq i32 %x, %y
950   ret i1 %z
953 define i1 @test54(i8 %a) {
954 ; CHECK-LABEL: @test54(
955 ; CHECK-NEXT:    [[TMP1:%.*]] = and i8 [[A:%.*]], -64
956 ; CHECK-NEXT:    [[RET:%.*]] = icmp eq i8 [[TMP1]], -128
957 ; CHECK-NEXT:    ret i1 [[RET]]
959   %ext = zext i8 %a to i32
960   %and = and i32 %ext, 192
961   %ret = icmp eq i32 %and, 128
962   ret i1 %ret
965 define i1 @test55(i32 %a) {
966 ; CHECK-LABEL: @test55(
967 ; CHECK-NEXT:    [[CMP:%.*]] = icmp eq i32 [[A:%.*]], -123
968 ; CHECK-NEXT:    ret i1 [[CMP]]
970   %sub = sub i32 0, %a
971   %cmp = icmp eq i32 %sub, 123
972   ret i1 %cmp
975 define <2 x i1> @test55vec(<2 x i32> %a) {
976 ; CHECK-LABEL: @test55vec(
977 ; CHECK-NEXT:    [[CMP:%.*]] = icmp eq <2 x i32> [[A:%.*]], <i32 -123, i32 -123>
978 ; CHECK-NEXT:    ret <2 x i1> [[CMP]]
980   %sub = sub <2 x i32> zeroinitializer, %a
981   %cmp = icmp eq <2 x i32> %sub, <i32 123, i32 123>
982   ret <2 x i1> %cmp
985 define i1 @test56(i32 %a) {
986 ; CHECK-LABEL: @test56(
987 ; CHECK-NEXT:    [[CMP:%.*]] = icmp eq i32 [[A:%.*]], -113
988 ; CHECK-NEXT:    ret i1 [[CMP]]
990   %sub = sub i32 10, %a
991   %cmp = icmp eq i32 %sub, 123
992   ret i1 %cmp
995 define <2 x i1> @test56vec(<2 x i32> %a) {
996 ; CHECK-LABEL: @test56vec(
997 ; CHECK-NEXT:    [[CMP:%.*]] = icmp eq <2 x i32> [[A:%.*]], <i32 -113, i32 -113>
998 ; CHECK-NEXT:    ret <2 x i1> [[CMP]]
1000   %sub = sub <2 x i32> <i32 10, i32 10>, %a
1001   %cmp = icmp eq <2 x i32> %sub, <i32 123, i32 123>
1002   ret <2 x i1> %cmp
1005 ; PR10267 Don't make icmps more expensive when no other inst is subsumed.
1006 declare void @foo(i32)
1007 define i1 @test57(i32 %a) {
1008 ; CHECK-LABEL: @test57(
1009 ; CHECK-NEXT:    [[AND:%.*]] = and i32 [[A:%.*]], -2
1010 ; CHECK-NEXT:    [[CMP:%.*]] = icmp ne i32 [[AND]], 0
1011 ; CHECK-NEXT:    call void @foo(i32 [[AND]])
1012 ; CHECK-NEXT:    ret i1 [[CMP]]
1014   %and = and i32 %a, -2
1015   %cmp = icmp ne i32 %and, 0
1016   call void @foo(i32 %and)
1017   ret i1 %cmp
1020 ; rdar://problem/10482509
1021 define zeroext i1 @cmpabs1(i64 %val) {
1022 ; CHECK-LABEL: @cmpabs1(
1023 ; CHECK-NEXT:    [[TOBOOL:%.*]] = icmp ne i64 [[VAL:%.*]], 0
1024 ; CHECK-NEXT:    ret i1 [[TOBOOL]]
1026   %sub = sub nsw i64 0, %val
1027   %cmp = icmp slt i64 %val, 0
1028   %sub.val = select i1 %cmp, i64 %sub, i64 %val
1029   %tobool = icmp ne i64 %sub.val, 0
1030   ret i1 %tobool
1033 define zeroext i1 @cmpabs2(i64 %val) {
1034 ; CHECK-LABEL: @cmpabs2(
1035 ; CHECK-NEXT:    [[TOBOOL:%.*]] = icmp ne i64 [[VAL:%.*]], 0
1036 ; CHECK-NEXT:    ret i1 [[TOBOOL]]
1038   %sub = sub nsw i64 0, %val
1039   %cmp = icmp slt i64 %val, 0
1040   %sub.val = select i1 %cmp, i64 %val, i64 %sub
1041   %tobool = icmp ne i64 %sub.val, 0
1042   ret i1 %tobool
1045 define void @test58() {
1046 ; CHECK-LABEL: @test58(
1047 ; CHECK-NEXT:    [[CALL:%.*]] = call i32 @test58_d(i64 36029346783166592)
1048 ; CHECK-NEXT:    ret void
1050   %cast = bitcast <1 x i64> <i64 36029346783166592> to i64
1051   %call = call i32 @test58_d( i64 %cast)
1052   ret void
1054 declare i32 @test58_d(i64)
1056 define i1 @test59(i8* %foo) {
1057 ; CHECK-LABEL: @test59(
1058 ; CHECK-NEXT:    [[GEP1:%.*]] = getelementptr inbounds i8, i8* [[FOO:%.*]], i64 8
1059 ; CHECK-NEXT:    [[USE:%.*]] = ptrtoint i8* [[GEP1]] to i64
1060 ; CHECK-NEXT:    [[CALL:%.*]] = call i32 @test58_d(i64 [[USE]])
1061 ; CHECK-NEXT:    ret i1 true
1063   %bit = bitcast i8* %foo to i32*
1064   %gep1 = getelementptr inbounds i32, i32* %bit, i64 2
1065   %gep2 = getelementptr inbounds i8, i8* %foo, i64 10
1066   %cast1 = bitcast i32* %gep1 to i8*
1067   %cmp = icmp ult i8* %cast1, %gep2
1068   %use = ptrtoint i8* %cast1 to i64
1069   %call = call i32 @test58_d(i64 %use)
1070   ret i1 %cmp
1073 define i1 @test59_as1(i8 addrspace(1)* %foo) {
1074 ; CHECK-LABEL: @test59_as1(
1075 ; CHECK-NEXT:    [[GEP1:%.*]] = getelementptr inbounds i8, i8 addrspace(1)* [[FOO:%.*]], i16 8
1076 ; CHECK-NEXT:    [[TMP1:%.*]] = ptrtoint i8 addrspace(1)* [[GEP1]] to i16
1077 ; CHECK-NEXT:    [[USE:%.*]] = zext i16 [[TMP1]] to i64
1078 ; CHECK-NEXT:    [[CALL:%.*]] = call i32 @test58_d(i64 [[USE]])
1079 ; CHECK-NEXT:    ret i1 true
1081   %bit = bitcast i8 addrspace(1)* %foo to i32 addrspace(1)*
1082   %gep1 = getelementptr inbounds i32, i32 addrspace(1)* %bit, i64 2
1083   %gep2 = getelementptr inbounds i8, i8 addrspace(1)* %foo, i64 10
1084   %cast1 = bitcast i32 addrspace(1)* %gep1 to i8 addrspace(1)*
1085   %cmp = icmp ult i8 addrspace(1)* %cast1, %gep2
1086   %use = ptrtoint i8 addrspace(1)* %cast1 to i64
1087   %call = call i32 @test58_d(i64 %use)
1088   ret i1 %cmp
1091 define i1 @test60(i8* %foo, i64 %i, i64 %j) {
1092 ; CHECK-LABEL: @test60(
1093 ; CHECK-NEXT:    [[GEP1_IDX:%.*]] = shl nuw i64 [[I:%.*]], 2
1094 ; CHECK-NEXT:    [[TMP1:%.*]] = icmp slt i64 [[GEP1_IDX]], [[J:%.*]]
1095 ; CHECK-NEXT:    ret i1 [[TMP1]]
1097   %bit = bitcast i8* %foo to i32*
1098   %gep1 = getelementptr inbounds i32, i32* %bit, i64 %i
1099   %gep2 = getelementptr inbounds i8, i8* %foo, i64 %j
1100   %cast1 = bitcast i32* %gep1 to i8*
1101   %cmp = icmp ult i8* %cast1, %gep2
1102   ret i1 %cmp
1105 define i1 @test60_as1(i8 addrspace(1)* %foo, i64 %i, i64 %j) {
1106 ; CHECK-LABEL: @test60_as1(
1107 ; CHECK-NEXT:    [[TMP1:%.*]] = trunc i64 [[I:%.*]] to i16
1108 ; CHECK-NEXT:    [[TMP2:%.*]] = trunc i64 [[J:%.*]] to i16
1109 ; CHECK-NEXT:    [[GEP1_IDX:%.*]] = shl nuw i16 [[TMP1]], 2
1110 ; CHECK-NEXT:    [[TMP3:%.*]] = icmp slt i16 [[GEP1_IDX]], [[TMP2]]
1111 ; CHECK-NEXT:    ret i1 [[TMP3]]
1113   %bit = bitcast i8 addrspace(1)* %foo to i32 addrspace(1)*
1114   %gep1 = getelementptr inbounds i32, i32 addrspace(1)* %bit, i64 %i
1115   %gep2 = getelementptr inbounds i8, i8 addrspace(1)* %foo, i64 %j
1116   %cast1 = bitcast i32 addrspace(1)* %gep1 to i8 addrspace(1)*
1117   %cmp = icmp ult i8 addrspace(1)* %cast1, %gep2
1118   ret i1 %cmp
1121 ; Same as test60, but look through an addrspacecast instead of a
1122 ; bitcast. This uses the same sized addrspace.
1123 define i1 @test60_addrspacecast(i8* %foo, i64 %i, i64 %j) {
1124 ; CHECK-LABEL: @test60_addrspacecast(
1125 ; CHECK-NEXT:    [[GEP1_IDX:%.*]] = shl nuw i64 [[I:%.*]], 2
1126 ; CHECK-NEXT:    [[TMP1:%.*]] = icmp slt i64 [[GEP1_IDX]], [[J:%.*]]
1127 ; CHECK-NEXT:    ret i1 [[TMP1]]
1129   %bit = addrspacecast i8* %foo to i32 addrspace(3)*
1130   %gep1 = getelementptr inbounds i32, i32 addrspace(3)* %bit, i64 %i
1131   %gep2 = getelementptr inbounds i8, i8* %foo, i64 %j
1132   %cast1 = addrspacecast i32 addrspace(3)* %gep1 to i8*
1133   %cmp = icmp ult i8* %cast1, %gep2
1134   ret i1 %cmp
1137 define i1 @test60_addrspacecast_smaller(i8* %foo, i16 %i, i64 %j) {
1138 ; CHECK-LABEL: @test60_addrspacecast_smaller(
1139 ; CHECK-NEXT:    [[GEP1_IDX:%.*]] = shl nuw i16 [[I:%.*]], 2
1140 ; CHECK-NEXT:    [[TMP1:%.*]] = trunc i64 [[J:%.*]] to i16
1141 ; CHECK-NEXT:    [[TMP2:%.*]] = icmp slt i16 [[GEP1_IDX]], [[TMP1]]
1142 ; CHECK-NEXT:    ret i1 [[TMP2]]
1144   %bit = addrspacecast i8* %foo to i32 addrspace(1)*
1145   %gep1 = getelementptr inbounds i32, i32 addrspace(1)* %bit, i16 %i
1146   %gep2 = getelementptr inbounds i8, i8* %foo, i64 %j
1147   %cast1 = addrspacecast i32 addrspace(1)* %gep1 to i8*
1148   %cmp = icmp ult i8* %cast1, %gep2
1149   ret i1 %cmp
1152 define i1 @test60_addrspacecast_larger(i8 addrspace(1)* %foo, i32 %i, i16 %j) {
1153 ; CHECK-LABEL: @test60_addrspacecast_larger(
1154 ; CHECK-NEXT:    [[I_TR:%.*]] = trunc i32 [[I:%.*]] to i16
1155 ; CHECK-NEXT:    [[TMP1:%.*]] = shl i16 [[I_TR]], 2
1156 ; CHECK-NEXT:    [[TMP2:%.*]] = icmp slt i16 [[TMP1]], [[J:%.*]]
1157 ; CHECK-NEXT:    ret i1 [[TMP2]]
1159   %bit = addrspacecast i8 addrspace(1)* %foo to i32 addrspace(2)*
1160   %gep1 = getelementptr inbounds i32, i32 addrspace(2)* %bit, i32 %i
1161   %gep2 = getelementptr inbounds i8, i8 addrspace(1)* %foo, i16 %j
1162   %cast1 = addrspacecast i32 addrspace(2)* %gep1 to i8 addrspace(1)*
1163   %cmp = icmp ult i8 addrspace(1)* %cast1, %gep2
1164   ret i1 %cmp
1167 define i1 @test61(i8* %foo, i64 %i, i64 %j) {
1168 ; CHECK-LABEL: @test61(
1169 ; CHECK-NEXT:    [[BIT:%.*]] = bitcast i8* [[FOO:%.*]] to i32*
1170 ; CHECK-NEXT:    [[GEP1:%.*]] = getelementptr i32, i32* [[BIT]], i64 [[I:%.*]]
1171 ; CHECK-NEXT:    [[GEP2:%.*]] = getelementptr i8, i8* [[FOO]], i64 [[J:%.*]]
1172 ; CHECK-NEXT:    [[CAST1:%.*]] = bitcast i32* [[GEP1]] to i8*
1173 ; CHECK-NEXT:    [[CMP:%.*]] = icmp ugt i8* [[GEP2]], [[CAST1]]
1174 ; CHECK-NEXT:    ret i1 [[CMP]]
1176   %bit = bitcast i8* %foo to i32*
1177   %gep1 = getelementptr i32, i32* %bit, i64 %i
1178   %gep2 = getelementptr  i8,  i8* %foo, i64 %j
1179   %cast1 = bitcast i32* %gep1 to i8*
1180   %cmp = icmp ult i8* %cast1, %gep2
1181   ret i1 %cmp
1182 ; Don't transform non-inbounds GEPs.
1185 define i1 @test61_as1(i8 addrspace(1)* %foo, i16 %i, i16 %j) {
1186 ; CHECK-LABEL: @test61_as1(
1187 ; CHECK-NEXT:    [[BIT:%.*]] = bitcast i8 addrspace(1)* [[FOO:%.*]] to i32 addrspace(1)*
1188 ; CHECK-NEXT:    [[GEP1:%.*]] = getelementptr i32, i32 addrspace(1)* [[BIT]], i16 [[I:%.*]]
1189 ; CHECK-NEXT:    [[GEP2:%.*]] = getelementptr i8, i8 addrspace(1)* [[FOO]], i16 [[J:%.*]]
1190 ; CHECK-NEXT:    [[CAST1:%.*]] = bitcast i32 addrspace(1)* [[GEP1]] to i8 addrspace(1)*
1191 ; CHECK-NEXT:    [[CMP:%.*]] = icmp ugt i8 addrspace(1)* [[GEP2]], [[CAST1]]
1192 ; CHECK-NEXT:    ret i1 [[CMP]]
1194   %bit = bitcast i8 addrspace(1)* %foo to i32 addrspace(1)*
1195   %gep1 = getelementptr i32, i32 addrspace(1)* %bit, i16 %i
1196   %gep2 = getelementptr i8, i8 addrspace(1)* %foo, i16 %j
1197   %cast1 = bitcast i32 addrspace(1)* %gep1 to i8 addrspace(1)*
1198   %cmp = icmp ult i8 addrspace(1)* %cast1, %gep2
1199   ret i1 %cmp
1200 ; Don't transform non-inbounds GEPs.
1203 define i1 @test62(i8* %a) {
1204 ; CHECK-LABEL: @test62(
1205 ; CHECK-NEXT:    ret i1 true
1207   %arrayidx1 = getelementptr inbounds i8, i8* %a, i64 1
1208   %arrayidx2 = getelementptr inbounds i8, i8* %a, i64 10
1209   %cmp = icmp slt i8* %arrayidx1, %arrayidx2
1210   ret i1 %cmp
1213 define i1 @test62_as1(i8 addrspace(1)* %a) {
1214 ; CHECK-LABEL: @test62_as1(
1215 ; CHECK-NEXT:    ret i1 true
1217   %arrayidx1 = getelementptr inbounds i8, i8 addrspace(1)* %a, i64 1
1218   %arrayidx2 = getelementptr inbounds i8, i8 addrspace(1)* %a, i64 10
1219   %cmp = icmp slt i8 addrspace(1)* %arrayidx1, %arrayidx2
1220   ret i1 %cmp
1223 define i1 @test63(i8 %a, i32 %b) {
1224 ; CHECK-LABEL: @test63(
1225 ; CHECK-NEXT:    [[TMP1:%.*]] = trunc i32 [[B:%.*]] to i8
1226 ; CHECK-NEXT:    [[C:%.*]] = icmp eq i8 [[TMP1]], [[A:%.*]]
1227 ; CHECK-NEXT:    ret i1 [[C]]
1229   %z = zext i8 %a to i32
1230   %t = and i32 %b, 255
1231   %c = icmp eq i32 %z, %t
1232   ret i1 %c
1235 define i1 @test64(i8 %a, i32 %b) {
1236 ; CHECK-LABEL: @test64(
1237 ; CHECK-NEXT:    [[TMP1:%.*]] = trunc i32 [[B:%.*]] to i8
1238 ; CHECK-NEXT:    [[C:%.*]] = icmp eq i8 [[TMP1]], [[A:%.*]]
1239 ; CHECK-NEXT:    ret i1 [[C]]
1241   %t = and i32 %b, 255
1242   %z = zext i8 %a to i32
1243   %c = icmp eq i32 %t, %z
1244   ret i1 %c
1247 define i1 @test65(i64 %A, i64 %B) {
1248 ; CHECK-LABEL: @test65(
1249 ; CHECK-NEXT:    ret i1 true
1251   %s1 = add i64 %A, %B
1252   %s2 = add i64 %A, %B
1253   %cmp = icmp eq i64 %s1, %s2
1254   ret i1 %cmp
1257 define i1 @test66(i64 %A, i64 %B) {
1258 ; CHECK-LABEL: @test66(
1259 ; CHECK-NEXT:    ret i1 true
1261   %s1 = add i64 %A, %B
1262   %s2 = add i64 %B, %A
1263   %cmp = icmp eq i64 %s1, %s2
1264   ret i1 %cmp
1267 define i1 @test67(i32 %x) {
1268 ; CHECK-LABEL: @test67(
1269 ; CHECK-NEXT:    [[AND:%.*]] = and i32 [[X:%.*]], 96
1270 ; CHECK-NEXT:    [[CMP:%.*]] = icmp ne i32 [[AND]], 0
1271 ; CHECK-NEXT:    ret i1 [[CMP]]
1273   %and = and i32 %x, 127
1274   %cmp = icmp sgt i32 %and, 31
1275   ret i1 %cmp
1278 define i1 @test67inverse(i32 %x) {
1279 ; CHECK-LABEL: @test67inverse(
1280 ; CHECK-NEXT:    [[AND:%.*]] = and i32 [[X:%.*]], 96
1281 ; CHECK-NEXT:    [[CMP:%.*]] = icmp eq i32 [[AND]], 0
1282 ; CHECK-NEXT:    ret i1 [[CMP]]
1284   %and = and i32 %x, 127
1285   %cmp = icmp sle i32 %and, 31
1286   ret i1 %cmp
1289 ; The test above relies on 3 different folds.
1290 ; This test only checks the last of those (icmp ugt -> icmp ne).
1292 define <2 x i1> @test67vec(<2 x i32> %x) {
1293 ; CHECK-LABEL: @test67vec(
1294 ; CHECK-NEXT:    [[AND:%.*]] = and <2 x i32> [[X:%.*]], <i32 96, i32 96>
1295 ; CHECK-NEXT:    [[CMP:%.*]] = icmp ne <2 x i32> [[AND]], zeroinitializer
1296 ; CHECK-NEXT:    ret <2 x i1> [[CMP]]
1298   %and = and <2 x i32> %x, <i32 96, i32 96>
1299   %cmp = icmp ugt <2 x i32> %and, <i32 31, i32 31>
1300   ret <2 x i1> %cmp
1303 define <2 x i1> @test67vec2(<2 x i32> %x) {
1304 ; CHECK-LABEL: @test67vec2(
1305 ; CHECK-NEXT:    [[AND:%.*]] = and <2 x i32> [[X:%.*]], <i32 96, i32 96>
1306 ; CHECK-NEXT:    [[CMP:%.*]] = icmp ne <2 x i32> [[AND]], zeroinitializer
1307 ; CHECK-NEXT:    ret <2 x i1> [[CMP]]
1309   %and = and <2 x i32> %x, <i32 127, i32 127>
1310   %cmp = icmp ugt <2 x i32> %and, <i32 31, i32 31>
1311   ret <2 x i1> %cmp
1314 define <2 x i1> @test67vecinverse(<2 x i32> %x) {
1315 ; CHECK-LABEL: @test67vecinverse(
1316 ; CHECK-NEXT:    [[AND:%.*]] = and <2 x i32> [[X:%.*]], <i32 96, i32 96>
1317 ; CHECK-NEXT:    [[CMP:%.*]] = icmp eq <2 x i32> [[AND]], zeroinitializer
1318 ; CHECK-NEXT:    ret <2 x i1> [[CMP]]
1320   %and = and <2 x i32> %x, <i32 96, i32 96>
1321   %cmp = icmp sle <2 x i32> %and, <i32 31, i32 31>
1322   ret <2 x i1> %cmp
1325 define i1 @test68(i32 %x) {
1326 ; CHECK-LABEL: @test68(
1327 ; CHECK-NEXT:    [[AND:%.*]] = and i32 [[X:%.*]], 127
1328 ; CHECK-NEXT:    [[CMP:%.*]] = icmp ugt i32 [[AND]], 30
1329 ; CHECK-NEXT:    ret i1 [[CMP]]
1331   %and = and i32 %x, 127
1332   %cmp = icmp sgt i32 %and, 30
1333   ret i1 %cmp
1336 ; PR15940
1337 define i1 @test70(i32 %X) {
1338 ; CHECK-LABEL: @test70(
1339 ; CHECK-NEXT:    [[A:%.*]] = srem i32 5, [[X:%.*]]
1340 ; CHECK-NEXT:    [[C:%.*]] = icmp ne i32 [[A]], 2
1341 ; CHECK-NEXT:    ret i1 [[C]]
1343   %A = srem i32 5, %X
1344   %B = add i32 %A, 2
1345   %C = icmp ne i32 %B, 4
1346   ret i1 %C
1349 define <2 x i1> @test70vec(<2 x i32> %X) {
1350 ; CHECK-LABEL: @test70vec(
1351 ; CHECK-NEXT:    [[C:%.*]] = icmp ne <2 x i32> [[X:%.*]], <i32 2, i32 2>
1352 ; CHECK-NEXT:    ret <2 x i1> [[C]]
1354   %B = add <2 x i32> %X, <i32 2, i32 2>
1355   %C = icmp ne <2 x i32> %B, <i32 4, i32 4>
1356   ret <2 x i1> %C
1359 define i1 @icmp_sext16trunc(i32 %x) {
1360 ; CHECK-LABEL: @icmp_sext16trunc(
1361 ; CHECK-NEXT:    [[TMP1:%.*]] = trunc i32 [[X:%.*]] to i16
1362 ; CHECK-NEXT:    [[CMP:%.*]] = icmp slt i16 [[TMP1]], 36
1363 ; CHECK-NEXT:    ret i1 [[CMP]]
1365   %trunc = trunc i32 %x to i16
1366   %sext = sext i16 %trunc to i32
1367   %cmp = icmp slt i32 %sext, 36
1368   ret i1 %cmp
1371 define i1 @icmp_sext8trunc(i32 %x) {
1372 ; CHECK-LABEL: @icmp_sext8trunc(
1373 ; CHECK-NEXT:    [[TMP1:%.*]] = trunc i32 [[X:%.*]] to i8
1374 ; CHECK-NEXT:    [[CMP:%.*]] = icmp slt i8 [[TMP1]], 36
1375 ; CHECK-NEXT:    ret i1 [[CMP]]
1377   %trunc = trunc i32 %x to i8
1378   %sext = sext i8 %trunc to i32
1379   %cmp = icmp slt i32 %sext, 36
1380   ret i1 %cmp
1383 ; Vectors should fold the same way.
1384 define <2 x i1> @icmp_sext8trunc_vec(<2 x i32> %x) {
1385 ; CHECK-LABEL: @icmp_sext8trunc_vec(
1386 ; CHECK-NEXT:    [[TMP1:%.*]] = trunc <2 x i32> [[X:%.*]] to <2 x i8>
1387 ; CHECK-NEXT:    [[CMP:%.*]] = icmp slt <2 x i8> [[TMP1]], <i8 36, i8 36>
1388 ; CHECK-NEXT:    ret <2 x i1> [[CMP]]
1390   %trunc = trunc <2 x i32> %x to <2 x i8>
1391   %sext = sext <2 x i8> %trunc to <2 x i32>
1392   %cmp = icmp slt <2 x i32> %sext, <i32 36, i32 36>
1393   ret <2 x i1> %cmp
1396 define i1 @icmp_shl16(i32 %x) {
1397 ; CHECK-LABEL: @icmp_shl16(
1398 ; CHECK-NEXT:    [[TMP1:%.*]] = trunc i32 [[X:%.*]] to i16
1399 ; CHECK-NEXT:    [[CMP:%.*]] = icmp slt i16 [[TMP1]], 36
1400 ; CHECK-NEXT:    ret i1 [[CMP]]
1402   %shl = shl i32 %x, 16
1403   %cmp = icmp slt i32 %shl, 2359296
1404   ret i1 %cmp
1407 ; D25952: Don't create illegal types like i15 in InstCombine
1409 define i1 @icmp_shl17(i32 %x) {
1410 ; CHECK-LABEL: @icmp_shl17(
1411 ; CHECK-NEXT:    [[SHL:%.*]] = shl i32 [[X:%.*]], 17
1412 ; CHECK-NEXT:    [[CMP:%.*]] = icmp slt i32 [[SHL]], 2359296
1413 ; CHECK-NEXT:    ret i1 [[CMP]]
1415   %shl = shl i32 %x, 17
1416   %cmp = icmp slt i32 %shl, 2359296
1417   ret i1 %cmp
1420 define <2 x i1> @icmp_shl16_vec(<2 x i32> %x) {
1421 ; CHECK-LABEL: @icmp_shl16_vec(
1422 ; CHECK-NEXT:    [[TMP1:%.*]] = trunc <2 x i32> [[X:%.*]] to <2 x i16>
1423 ; CHECK-NEXT:    [[CMP:%.*]] = icmp slt <2 x i16> [[TMP1]], <i16 36, i16 36>
1424 ; CHECK-NEXT:    ret <2 x i1> [[CMP]]
1426   %shl = shl <2 x i32> %x, <i32 16, i32 16>
1427   %cmp = icmp slt <2 x i32> %shl, <i32 2359296, i32 2359296>
1428   ret <2 x i1> %cmp
1431 define i1 @icmp_shl24(i32 %x) {
1432 ; CHECK-LABEL: @icmp_shl24(
1433 ; CHECK-NEXT:    [[TMP1:%.*]] = trunc i32 [[X:%.*]] to i8
1434 ; CHECK-NEXT:    [[CMP:%.*]] = icmp slt i8 [[TMP1]], 36
1435 ; CHECK-NEXT:    ret i1 [[CMP]]
1437   %shl = shl i32 %x, 24
1438   %cmp = icmp slt i32 %shl, 603979776
1439   ret i1 %cmp
1442 define i1 @icmp_shl_eq(i32 %x) {
1443 ; CHECK-LABEL: @icmp_shl_eq(
1444 ; CHECK-NEXT:    [[MUL_MASK:%.*]] = and i32 [[X:%.*]], 134217727
1445 ; CHECK-NEXT:    [[CMP:%.*]] = icmp eq i32 [[MUL_MASK]], 0
1446 ; CHECK-NEXT:    ret i1 [[CMP]]
1448   %mul = shl i32 %x, 5
1449   %cmp = icmp eq i32 %mul, 0
1450   ret i1 %cmp
1453 define <2 x i1> @icmp_shl_eq_vec(<2 x i32> %x) {
1454 ; CHECK-LABEL: @icmp_shl_eq_vec(
1455 ; CHECK-NEXT:    [[MUL_MASK:%.*]] = and <2 x i32> [[X:%.*]], <i32 134217727, i32 134217727>
1456 ; CHECK-NEXT:    [[CMP:%.*]] = icmp eq <2 x i32> [[MUL_MASK]], zeroinitializer
1457 ; CHECK-NEXT:    ret <2 x i1> [[CMP]]
1459   %mul = shl <2 x i32> %x, <i32 5, i32 5>
1460   %cmp = icmp eq <2 x i32> %mul, zeroinitializer
1461   ret <2 x i1> %cmp
1464 define i1 @icmp_shl_nsw_ne(i32 %x) {
1465 ; CHECK-LABEL: @icmp_shl_nsw_ne(
1466 ; CHECK-NEXT:    [[CMP:%.*]] = icmp ne i32 [[X:%.*]], 0
1467 ; CHECK-NEXT:    ret i1 [[CMP]]
1469   %mul = shl nsw i32 %x, 7
1470   %cmp = icmp ne i32 %mul, 0
1471   ret i1 %cmp
1474 define <2 x i1> @icmp_shl_nsw_ne_vec(<2 x i32> %x) {
1475 ; CHECK-LABEL: @icmp_shl_nsw_ne_vec(
1476 ; CHECK-NEXT:    [[CMP:%.*]] = icmp ne <2 x i32> [[X:%.*]], zeroinitializer
1477 ; CHECK-NEXT:    ret <2 x i1> [[CMP]]
1479   %mul = shl nsw <2 x i32> %x, <i32 7, i32 7>
1480   %cmp = icmp ne <2 x i32> %mul, zeroinitializer
1481   ret <2 x i1> %cmp
1484 define i1 @icmp_shl_ne(i32 %x) {
1485 ; CHECK-LABEL: @icmp_shl_ne(
1486 ; CHECK-NEXT:    [[MUL_MASK:%.*]] = and i32 [[X:%.*]], 33554431
1487 ; CHECK-NEXT:    [[CMP:%.*]] = icmp ne i32 [[MUL_MASK]], 0
1488 ; CHECK-NEXT:    ret i1 [[CMP]]
1490   %mul = shl i32 %x, 7
1491   %cmp = icmp ne i32 %mul, 0
1492   ret i1 %cmp
1495 define <2 x i1> @icmp_shl_ne_vec(<2 x i32> %x) {
1496 ; CHECK-LABEL: @icmp_shl_ne_vec(
1497 ; CHECK-NEXT:    [[MUL_MASK:%.*]] = and <2 x i32> [[X:%.*]], <i32 33554431, i32 33554431>
1498 ; CHECK-NEXT:    [[CMP:%.*]] = icmp ne <2 x i32> [[MUL_MASK]], zeroinitializer
1499 ; CHECK-NEXT:    ret <2 x i1> [[CMP]]
1501   %mul = shl <2 x i32> %x, <i32 7, i32 7>
1502   %cmp = icmp ne <2 x i32> %mul, zeroinitializer
1503   ret <2 x i1> %cmp
1506 define <2 x i1> @icmp_shl_nuw_ne_vec(<2 x i32> %x) {
1507 ; CHECK-LABEL: @icmp_shl_nuw_ne_vec(
1508 ; CHECK-NEXT:    [[CMP:%.*]] = icmp ne <2 x i32> [[X:%.*]], <i32 2, i32 2>
1509 ; CHECK-NEXT:    ret <2 x i1> [[CMP]]
1511   %shl = shl nuw <2 x i32> %x, <i32 7, i32 7>
1512   %cmp = icmp ne <2 x i32> %shl, <i32 256, i32 256>
1513   ret <2 x i1> %cmp
1516 ; If the (mul x, C) preserved the sign and this is sign test,
1517 ; compare the LHS operand instead
1518 define i1 @icmp_mul_nsw(i32 %x) {
1519 ; CHECK-LABEL: @icmp_mul_nsw(
1520 ; CHECK-NEXT:    [[CMP:%.*]] = icmp sgt i32 [[X:%.*]], 0
1521 ; CHECK-NEXT:    ret i1 [[CMP]]
1523   %mul = mul nsw i32 %x, 12
1524   %cmp = icmp sgt i32 %mul, 0
1525   ret i1 %cmp
1528 define i1 @icmp_mul_nsw1(i32 %x) {
1529 ; CHECK-LABEL: @icmp_mul_nsw1(
1530 ; CHECK-NEXT:    [[CMP:%.*]] = icmp slt i32 [[X:%.*]], 0
1531 ; CHECK-NEXT:    ret i1 [[CMP]]
1533   %mul = mul nsw i32 %x, 12
1534   %cmp = icmp sle i32 %mul, -1
1535   ret i1 %cmp
1538 define i1 @icmp_mul_nsw_neg(i32 %x) {
1539 ; CHECK-LABEL: @icmp_mul_nsw_neg(
1540 ; CHECK-NEXT:    [[CMP:%.*]] = icmp slt i32 [[X:%.*]], 1
1541 ; CHECK-NEXT:    ret i1 [[CMP]]
1543   %mul = mul nsw i32 %x, -12
1544   %cmp = icmp sge i32 %mul, 0
1545   ret i1 %cmp
1548 define i1 @icmp_mul_nsw_neg1(i32 %x) {
1549 ; CHECK-LABEL: @icmp_mul_nsw_neg1(
1550 ; CHECK-NEXT:    [[CMP:%.*]] = icmp slt i32 [[X:%.*]], 0
1551 ; CHECK-NEXT:    ret i1 [[CMP]]
1553   %mul = mul nsw i32 %x, -12
1554   %cmp = icmp sge i32 %mul, 1
1555   ret i1 %cmp
1558 define <2 x i1> @icmp_mul_nsw_neg1_vec(<2 x i32> %x) {
1559 ; CHECK-LABEL: @icmp_mul_nsw_neg1_vec(
1560 ; CHECK-NEXT:    [[CMP:%.*]] = icmp slt <2 x i32> [[X:%.*]], zeroinitializer
1561 ; CHECK-NEXT:    ret <2 x i1> [[CMP]]
1563   %mul = mul nsw <2 x i32> %x, <i32 -12, i32 -12>
1564   %cmp = icmp sge <2 x i32> %mul, <i32 1, i32 1>
1565   ret <2 x i1> %cmp
1568 define i1 @icmp_mul_nsw_0(i32 %x) {
1569 ; CHECK-LABEL: @icmp_mul_nsw_0(
1570 ; CHECK-NEXT:    ret i1 false
1572   %mul = mul nsw i32 %x, 0
1573   %cmp = icmp sgt i32 %mul, 0
1574   ret i1 %cmp
1577 define i1 @icmp_mul(i32 %x) {
1578 ; CHECK-LABEL: @icmp_mul(
1579 ; CHECK-NEXT:    [[MUL:%.*]] = mul i32 [[X:%.*]], -12
1580 ; CHECK-NEXT:    [[CMP:%.*]] = icmp sgt i32 [[MUL]], -1
1581 ; CHECK-NEXT:    ret i1 [[CMP]]
1583   %mul = mul i32 %x, -12
1584   %cmp = icmp sge i32 %mul, 0
1585   ret i1 %cmp
1588 ; Checks for icmp (eq|ne) (mul x, C), 0
1589 define i1 @icmp_mul_neq0(i32 %x) {
1590 ; CHECK-LABEL: @icmp_mul_neq0(
1591 ; CHECK-NEXT:    [[CMP:%.*]] = icmp ne i32 [[X:%.*]], 0
1592 ; CHECK-NEXT:    ret i1 [[CMP]]
1594   %mul = mul nsw i32 %x, -12
1595   %cmp = icmp ne i32 %mul, 0
1596   ret i1 %cmp
1599 define <2 x i1> @icmp_mul_neq0_vec(<2 x i32> %x) {
1600 ; CHECK-LABEL: @icmp_mul_neq0_vec(
1601 ; CHECK-NEXT:    [[CMP:%.*]] = icmp ne <2 x i32> [[X:%.*]], zeroinitializer
1602 ; CHECK-NEXT:    ret <2 x i1> [[CMP]]
1604   %mul = mul nsw <2 x i32> %x, <i32 -12, i32 -12>
1605   %cmp = icmp ne <2 x i32> %mul, zeroinitializer
1606   ret <2 x i1> %cmp
1609 define i1 @icmp_mul_eq0(i32 %x) {
1610 ; CHECK-LABEL: @icmp_mul_eq0(
1611 ; CHECK-NEXT:    [[CMP:%.*]] = icmp eq i32 [[X:%.*]], 0
1612 ; CHECK-NEXT:    ret i1 [[CMP]]
1614   %mul = mul nsw i32 %x, 12
1615   %cmp = icmp eq i32 %mul, 0
1616   ret i1 %cmp
1619 define i1 @icmp_mul0_eq0(i32 %x) {
1620 ; CHECK-LABEL: @icmp_mul0_eq0(
1621 ; CHECK-NEXT:    ret i1 true
1623   %mul = mul i32 %x, 0
1624   %cmp = icmp eq i32 %mul, 0
1625   ret i1 %cmp
1628 define i1 @icmp_mul0_ne0(i32 %x) {
1629 ; CHECK-LABEL: @icmp_mul0_ne0(
1630 ; CHECK-NEXT:    ret i1 false
1632   %mul = mul i32 %x, 0
1633   %cmp = icmp ne i32 %mul, 0
1634   ret i1 %cmp
1637 define i1 @icmp_sub1_sge(i32 %x, i32 %y) {
1638 ; CHECK-LABEL: @icmp_sub1_sge(
1639 ; CHECK-NEXT:    [[CMP:%.*]] = icmp sgt i32 [[X:%.*]], [[Y:%.*]]
1640 ; CHECK-NEXT:    ret i1 [[CMP]]
1642   %sub = add nsw i32 %x, -1
1643   %cmp = icmp sge i32 %sub, %y
1644   ret i1 %cmp
1647 define i1 @icmp_add1_sgt(i32 %x, i32 %y) {
1648 ; CHECK-LABEL: @icmp_add1_sgt(
1649 ; CHECK-NEXT:    [[CMP:%.*]] = icmp sge i32 [[X:%.*]], [[Y:%.*]]
1650 ; CHECK-NEXT:    ret i1 [[CMP]]
1652   %add = add nsw i32 %x, 1
1653   %cmp = icmp sgt i32 %add, %y
1654   ret i1 %cmp
1657 define i1 @icmp_sub1_slt(i32 %x, i32 %y) {
1658 ; CHECK-LABEL: @icmp_sub1_slt(
1659 ; CHECK-NEXT:    [[CMP:%.*]] = icmp sle i32 [[X:%.*]], [[Y:%.*]]
1660 ; CHECK-NEXT:    ret i1 [[CMP]]
1662   %sub = add nsw i32 %x, -1
1663   %cmp = icmp slt i32 %sub, %y
1664   ret i1 %cmp
1667 define i1 @icmp_add1_sle(i32 %x, i32 %y) {
1668 ; CHECK-LABEL: @icmp_add1_sle(
1669 ; CHECK-NEXT:    [[CMP:%.*]] = icmp slt i32 [[X:%.*]], [[Y:%.*]]
1670 ; CHECK-NEXT:    ret i1 [[CMP]]
1672   %add = add nsw i32 %x, 1
1673   %cmp = icmp sle i32 %add, %y
1674   ret i1 %cmp
1677 define i1 @icmp_add20_sge_add57(i32 %x, i32 %y) {
1678 ; CHECK-LABEL: @icmp_add20_sge_add57(
1679 ; CHECK-NEXT:    [[TMP1:%.*]] = add nsw i32 [[Y:%.*]], 37
1680 ; CHECK-NEXT:    [[CMP:%.*]] = icmp sle i32 [[TMP1]], [[X:%.*]]
1681 ; CHECK-NEXT:    ret i1 [[CMP]]
1683   %1 = add nsw i32 %x, 20
1684   %2 = add nsw i32 %y, 57
1685   %cmp = icmp sge i32 %1, %2
1686   ret i1 %cmp
1689 define i1 @icmp_sub57_sge_sub20(i32 %x, i32 %y) {
1690 ; CHECK-LABEL: @icmp_sub57_sge_sub20(
1691 ; CHECK-NEXT:    [[TMP1:%.*]] = add nsw i32 [[X:%.*]], -37
1692 ; CHECK-NEXT:    [[CMP:%.*]] = icmp sge i32 [[TMP1]], [[Y:%.*]]
1693 ; CHECK-NEXT:    ret i1 [[CMP]]
1695   %1 = add nsw i32 %x, -57
1696   %2 = add nsw i32 %y, -20
1697   %cmp = icmp sge i32 %1, %2
1698   ret i1 %cmp
1701 define i1 @icmp_and_shl_neg_ne_0(i32 %A, i32 %B) {
1702 ; CHECK-LABEL: @icmp_and_shl_neg_ne_0(
1703 ; CHECK-NEXT:    [[SHL:%.*]] = shl i32 1, [[B:%.*]]
1704 ; CHECK-NEXT:    [[TMP1:%.*]] = and i32 [[SHL]], [[A:%.*]]
1705 ; CHECK-NEXT:    [[CMP:%.*]] = icmp eq i32 [[TMP1]], 0
1706 ; CHECK-NEXT:    ret i1 [[CMP]]
1708   %neg = xor i32 %A, -1
1709   %shl = shl i32 1, %B
1710   %and = and i32 %shl, %neg
1711   %cmp = icmp ne i32 %and, 0
1712   ret i1 %cmp
1715 define i1 @icmp_and_shl_neg_eq_0(i32 %A, i32 %B) {
1716 ; CHECK-LABEL: @icmp_and_shl_neg_eq_0(
1717 ; CHECK-NEXT:    [[SHL:%.*]] = shl i32 1, [[B:%.*]]
1718 ; CHECK-NEXT:    [[TMP1:%.*]] = and i32 [[SHL]], [[A:%.*]]
1719 ; CHECK-NEXT:    [[CMP:%.*]] = icmp ne i32 [[TMP1]], 0
1720 ; CHECK-NEXT:    ret i1 [[CMP]]
1722   %neg = xor i32 %A, -1
1723   %shl = shl i32 1, %B
1724   %and = and i32 %shl, %neg
1725   %cmp = icmp eq i32 %and, 0
1726   ret i1 %cmp
1729 define i1 @icmp_add_and_shr_ne_0(i32 %X) {
1730 ; CHECK-LABEL: @icmp_add_and_shr_ne_0(
1731 ; CHECK-NEXT:    [[AND:%.*]] = and i32 [[X:%.*]], 240
1732 ; CHECK-NEXT:    [[TOBOOL:%.*]] = icmp ne i32 [[AND]], 224
1733 ; CHECK-NEXT:    ret i1 [[TOBOOL]]
1735   %shr = lshr i32 %X, 4
1736   %and = and i32 %shr, 15
1737   %add = add i32 %and, -14
1738   %tobool = icmp ne i32 %add, 0
1739   ret i1 %tobool
1742 define <2 x i1> @icmp_add_and_shr_ne_0_vec(<2 x i32> %X) {
1743 ; CHECK-LABEL: @icmp_add_and_shr_ne_0_vec(
1744 ; CHECK-NEXT:    [[AND:%.*]] = and <2 x i32> [[X:%.*]], <i32 240, i32 240>
1745 ; CHECK-NEXT:    [[TOBOOL:%.*]] = icmp ne <2 x i32> [[AND]], <i32 224, i32 224>
1746 ; CHECK-NEXT:    ret <2 x i1> [[TOBOOL]]
1748   %shr = lshr <2 x i32> %X, <i32 4, i32 4>
1749   %and = and <2 x i32> %shr, <i32 15, i32 15>
1750   %add = add <2 x i32> %and, <i32 -14, i32 -14>
1751   %tobool = icmp ne <2 x i32> %add, zeroinitializer
1752   ret <2 x i1> %tobool
1755 ; Variation of the above with an extra use of the shift
1756 define i1 @icmp_and_shr_multiuse(i32 %X) {
1757 ; CHECK-LABEL: @icmp_and_shr_multiuse(
1758 ; CHECK-NEXT:    [[AND:%.*]] = and i32 [[X:%.*]], 240
1759 ; CHECK-NEXT:    [[AND2:%.*]] = and i32 [[X]], 496
1760 ; CHECK-NEXT:    [[TOBOOL:%.*]] = icmp ne i32 [[AND]], 224
1761 ; CHECK-NEXT:    [[TOBOOL2:%.*]] = icmp ne i32 [[AND2]], 432
1762 ; CHECK-NEXT:    [[AND3:%.*]] = and i1 [[TOBOOL]], [[TOBOOL2]]
1763 ; CHECK-NEXT:    ret i1 [[AND3]]
1765   %shr = lshr i32 %X, 4
1766   %and = and i32 %shr, 15
1767   %and2 = and i32 %shr, 31 ; second use of the shift
1768   %tobool = icmp ne i32 %and, 14
1769   %tobool2 = icmp ne i32 %and2, 27
1770   %and3 = and i1 %tobool, %tobool2
1771   ret i1 %and3
1774 ; Variation of the above with an ashr
1775 define i1 @icmp_and_ashr_multiuse(i32 %X) {
1776 ; CHECK-LABEL: @icmp_and_ashr_multiuse(
1777 ; CHECK-NEXT:    [[AND:%.*]] = and i32 [[X:%.*]], 240
1778 ; CHECK-NEXT:    [[AND2:%.*]] = and i32 [[X]], 496
1779 ; CHECK-NEXT:    [[TOBOOL:%.*]] = icmp ne i32 [[AND]], 224
1780 ; CHECK-NEXT:    [[TOBOOL2:%.*]] = icmp ne i32 [[AND2]], 432
1781 ; CHECK-NEXT:    [[AND3:%.*]] = and i1 [[TOBOOL]], [[TOBOOL2]]
1782 ; CHECK-NEXT:    ret i1 [[AND3]]
1784   %shr = ashr i32 %X, 4
1785   %and = and i32 %shr, 15
1786   %and2 = and i32 %shr, 31 ; second use of the shift
1787   %tobool = icmp ne i32 %and, 14
1788   %tobool2 = icmp ne i32 %and2, 27
1789   %and3 = and i1 %tobool, %tobool2
1790   ret i1 %and3
1793 define i1 @icmp_lshr_and_overshift(i8 %X) {
1794 ; CHECK-LABEL: @icmp_lshr_and_overshift(
1795 ; CHECK-NEXT:    [[TOBOOL:%.*]] = icmp ugt i8 [[X:%.*]], 31
1796 ; CHECK-NEXT:    ret i1 [[TOBOOL]]
1798   %shr = lshr i8 %X, 5
1799   %and = and i8 %shr, 15
1800   %tobool = icmp ne i8 %and, 0
1801   ret i1 %tobool
1804 ; We shouldn't simplify this because the and uses bits that are shifted in.
1805 define i1 @icmp_ashr_and_overshift(i8 %X) {
1806 ; CHECK-LABEL: @icmp_ashr_and_overshift(
1807 ; CHECK-NEXT:    [[SHR:%.*]] = ashr i8 [[X:%.*]], 5
1808 ; CHECK-NEXT:    [[AND:%.*]] = and i8 [[SHR]], 15
1809 ; CHECK-NEXT:    [[TOBOOL:%.*]] = icmp ne i8 [[AND]], 0
1810 ; CHECK-NEXT:    ret i1 [[TOBOOL]]
1812   %shr = ashr i8 %X, 5
1813   %and = and i8 %shr, 15
1814   %tobool = icmp ne i8 %and, 0
1815   ret i1 %tobool
1818 ; PR16244
1819 define i1 @test71(i8* %x) {
1820 ; CHECK-LABEL: @test71(
1821 ; CHECK-NEXT:    ret i1 false
1823   %a = getelementptr i8, i8* %x, i64 8
1824   %b = getelementptr inbounds i8, i8* %x, i64 8
1825   %c = icmp ugt i8* %a, %b
1826   ret i1 %c
1829 define i1 @test71_as1(i8 addrspace(1)* %x) {
1830 ; CHECK-LABEL: @test71_as1(
1831 ; CHECK-NEXT:    ret i1 false
1833   %a = getelementptr i8, i8 addrspace(1)* %x, i64 8
1834   %b = getelementptr inbounds i8, i8 addrspace(1)* %x, i64 8
1835   %c = icmp ugt i8 addrspace(1)* %a, %b
1836   ret i1 %c
1839 define i1 @icmp_shl_1_V_ult_32(i32 %V) {
1840 ; CHECK-LABEL: @icmp_shl_1_V_ult_32(
1841 ; CHECK-NEXT:    [[CMP:%.*]] = icmp ult i32 [[V:%.*]], 5
1842 ; CHECK-NEXT:    ret i1 [[CMP]]
1844   %shl = shl i32 1, %V
1845   %cmp = icmp ult i32 %shl, 32
1846   ret i1 %cmp
1849 define <2 x i1> @icmp_shl_1_V_ult_32_vec(<2 x i32> %V) {
1850 ; CHECK-LABEL: @icmp_shl_1_V_ult_32_vec(
1851 ; CHECK-NEXT:    [[CMP:%.*]] = icmp ult <2 x i32> [[V:%.*]], <i32 5, i32 5>
1852 ; CHECK-NEXT:    ret <2 x i1> [[CMP]]
1854   %shl = shl <2 x i32> <i32 1, i32 1>, %V
1855   %cmp = icmp ult <2 x i32> %shl, <i32 32, i32 32>
1856   ret <2 x i1> %cmp
1859 define i1 @icmp_shl_1_V_eq_32(i32 %V) {
1860 ; CHECK-LABEL: @icmp_shl_1_V_eq_32(
1861 ; CHECK-NEXT:    [[CMP:%.*]] = icmp eq i32 [[V:%.*]], 5
1862 ; CHECK-NEXT:    ret i1 [[CMP]]
1864   %shl = shl i32 1, %V
1865   %cmp = icmp eq i32 %shl, 32
1866   ret i1 %cmp
1869 define <2 x i1> @icmp_shl_1_V_eq_32_vec(<2 x i32> %V) {
1870 ; CHECK-LABEL: @icmp_shl_1_V_eq_32_vec(
1871 ; CHECK-NEXT:    [[CMP:%.*]] = icmp eq <2 x i32> [[V:%.*]], <i32 5, i32 5>
1872 ; CHECK-NEXT:    ret <2 x i1> [[CMP]]
1874   %shl = shl <2 x i32> <i32 1, i32 1>, %V
1875   %cmp = icmp eq <2 x i32> %shl, <i32 32, i32 32>
1876   ret <2 x i1> %cmp
1879 define i1 @icmp_shl_1_V_ult_30(i32 %V) {
1880 ; CHECK-LABEL: @icmp_shl_1_V_ult_30(
1881 ; CHECK-NEXT:    [[CMP:%.*]] = icmp ult i32 [[V:%.*]], 5
1882 ; CHECK-NEXT:    ret i1 [[CMP]]
1884   %shl = shl i32 1, %V
1885   %cmp = icmp ult i32 %shl, 30
1886   ret i1 %cmp
1889 define <2 x i1> @icmp_shl_1_V_ult_30_vec(<2 x i32> %V) {
1890 ; CHECK-LABEL: @icmp_shl_1_V_ult_30_vec(
1891 ; CHECK-NEXT:    [[CMP:%.*]] = icmp ult <2 x i32> [[V:%.*]], <i32 5, i32 5>
1892 ; CHECK-NEXT:    ret <2 x i1> [[CMP]]
1894   %shl = shl <2 x i32> <i32 1, i32 1>, %V
1895   %cmp = icmp ult <2 x i32> %shl, <i32 30, i32 30>
1896   ret <2 x i1> %cmp
1899 define i1 @icmp_shl_1_V_ugt_30(i32 %V) {
1900 ; CHECK-LABEL: @icmp_shl_1_V_ugt_30(
1901 ; CHECK-NEXT:    [[CMP:%.*]] = icmp ugt i32 [[V:%.*]], 4
1902 ; CHECK-NEXT:    ret i1 [[CMP]]
1904   %shl = shl i32 1, %V
1905   %cmp = icmp ugt i32 %shl, 30
1906   ret i1 %cmp
1909 define <2 x i1> @icmp_shl_1_V_ugt_30_vec(<2 x i32> %V) {
1910 ; CHECK-LABEL: @icmp_shl_1_V_ugt_30_vec(
1911 ; CHECK-NEXT:    [[CMP:%.*]] = icmp ugt <2 x i32> [[V:%.*]], <i32 4, i32 4>
1912 ; CHECK-NEXT:    ret <2 x i1> [[CMP]]
1914   %shl = shl <2 x i32> <i32 1, i32 1>, %V
1915   %cmp = icmp ugt <2 x i32> %shl, <i32 30, i32 30>
1916   ret <2 x i1> %cmp
1919 define i1 @icmp_shl_1_V_ule_30(i32 %V) {
1920 ; CHECK-LABEL: @icmp_shl_1_V_ule_30(
1921 ; CHECK-NEXT:    [[CMP:%.*]] = icmp ult i32 [[V:%.*]], 5
1922 ; CHECK-NEXT:    ret i1 [[CMP]]
1924   %shl = shl i32 1, %V
1925   %cmp = icmp ule i32 %shl, 30
1926   ret i1 %cmp
1929 define <2 x i1> @icmp_shl_1_V_ule_30_vec(<2 x i32> %V) {
1930 ; CHECK-LABEL: @icmp_shl_1_V_ule_30_vec(
1931 ; CHECK-NEXT:    [[CMP:%.*]] = icmp ult <2 x i32> [[V:%.*]], <i32 5, i32 5>
1932 ; CHECK-NEXT:    ret <2 x i1> [[CMP]]
1934   %shl = shl <2 x i32> <i32 1, i32 1>, %V
1935   %cmp = icmp ule <2 x i32> %shl, <i32 30, i32 30>
1936   ret <2 x i1> %cmp
1939 define i1 @icmp_shl_1_V_uge_30(i32 %V) {
1940 ; CHECK-LABEL: @icmp_shl_1_V_uge_30(
1941 ; CHECK-NEXT:    [[CMP:%.*]] = icmp ugt i32 [[V:%.*]], 4
1942 ; CHECK-NEXT:    ret i1 [[CMP]]
1944   %shl = shl i32 1, %V
1945   %cmp = icmp uge i32 %shl, 30
1946   ret i1 %cmp
1949 define <2 x i1> @icmp_shl_1_V_uge_30_vec(<2 x i32> %V) {
1950 ; CHECK-LABEL: @icmp_shl_1_V_uge_30_vec(
1951 ; CHECK-NEXT:    [[CMP:%.*]] = icmp ugt <2 x i32> [[V:%.*]], <i32 4, i32 4>
1952 ; CHECK-NEXT:    ret <2 x i1> [[CMP]]
1954   %shl = shl <2 x i32> <i32 1, i32 1>, %V
1955   %cmp = icmp uge <2 x i32> %shl, <i32 30, i32 30>
1956   ret <2 x i1> %cmp
1959 define i1 @icmp_shl_1_V_uge_2147483648(i32 %V) {
1960 ; CHECK-LABEL: @icmp_shl_1_V_uge_2147483648(
1961 ; CHECK-NEXT:    [[CMP:%.*]] = icmp eq i32 [[V:%.*]], 31
1962 ; CHECK-NEXT:    ret i1 [[CMP]]
1964   %shl = shl i32 1, %V
1965   %cmp = icmp uge i32 %shl, 2147483648
1966   ret i1 %cmp
1969 define <2 x i1> @icmp_shl_1_V_uge_2147483648_vec(<2 x i32> %V) {
1970 ; CHECK-LABEL: @icmp_shl_1_V_uge_2147483648_vec(
1971 ; CHECK-NEXT:    [[CMP:%.*]] = icmp eq <2 x i32> [[V:%.*]], <i32 31, i32 31>
1972 ; CHECK-NEXT:    ret <2 x i1> [[CMP]]
1974   %shl = shl <2 x i32> <i32 1, i32 1>, %V
1975   %cmp = icmp uge <2 x i32> %shl, <i32 2147483648, i32 2147483648>
1976   ret <2 x i1> %cmp
1979 define i1 @icmp_shl_1_V_ult_2147483648(i32 %V) {
1980 ; CHECK-LABEL: @icmp_shl_1_V_ult_2147483648(
1981 ; CHECK-NEXT:    [[CMP:%.*]] = icmp ne i32 [[V:%.*]], 31
1982 ; CHECK-NEXT:    ret i1 [[CMP]]
1984   %shl = shl i32 1, %V
1985   %cmp = icmp ult i32 %shl, 2147483648
1986   ret i1 %cmp
1989 define <2 x i1> @icmp_shl_1_V_ult_2147483648_vec(<2 x i32> %V) {
1990 ; CHECK-LABEL: @icmp_shl_1_V_ult_2147483648_vec(
1991 ; CHECK-NEXT:    [[CMP:%.*]] = icmp ne <2 x i32> [[V:%.*]], <i32 31, i32 31>
1992 ; CHECK-NEXT:    ret <2 x i1> [[CMP]]
1994   %shl = shl <2 x i32> <i32 1, i32 1>, %V
1995   %cmp = icmp ult <2 x i32> %shl, <i32 2147483648, i32 2147483648>
1996   ret <2 x i1> %cmp
1999 define i1 @or_icmp_eq_B_0_icmp_ult_A_B(i64 %a, i64 %b) {
2000 ; CHECK-LABEL: @or_icmp_eq_B_0_icmp_ult_A_B(
2001 ; CHECK-NEXT:    [[TMP1:%.*]] = add i64 [[B:%.*]], -1
2002 ; CHECK-NEXT:    [[TMP2:%.*]] = icmp uge i64 [[TMP1]], [[A:%.*]]
2003 ; CHECK-NEXT:    ret i1 [[TMP2]]
2005   %1 = icmp eq i64 %b, 0
2006   %2 = icmp ult i64 %a, %b
2007   %3 = or i1 %1, %2
2008   ret i1 %3
2011 define i1 @icmp_add_ult_2(i32 %X) {
2012 ; CHECK-LABEL: @icmp_add_ult_2(
2013 ; CHECK-NEXT:    [[TMP1:%.*]] = and i32 [[X:%.*]], -2
2014 ; CHECK-NEXT:    [[CMP:%.*]] = icmp eq i32 [[TMP1]], 14
2015 ; CHECK-NEXT:    ret i1 [[CMP]]
2017   %add = add i32 %X, -14
2018   %cmp = icmp ult i32 %add, 2
2019   ret i1 %cmp
2022 define <2 x i1> @icmp_add_X_-14_ult_2_vec(<2 x i32> %X) {
2023 ; CHECK-LABEL: @icmp_add_X_-14_ult_2_vec(
2024 ; CHECK-NEXT:    [[TMP1:%.*]] = and <2 x i32> [[X:%.*]], <i32 -2, i32 -2>
2025 ; CHECK-NEXT:    [[CMP:%.*]] = icmp eq <2 x i32> [[TMP1]], <i32 14, i32 14>
2026 ; CHECK-NEXT:    ret <2 x i1> [[CMP]]
2028   %add = add <2 x i32> %X, <i32 -14, i32 -14>
2029   %cmp = icmp ult <2 x i32> %add, <i32 2, i32 2>
2030   ret <2 x i1> %cmp
2033 define i1 @icmp_sub_3_X_ult_2(i32 %X) {
2034 ; CHECK-LABEL: @icmp_sub_3_X_ult_2(
2035 ; CHECK-NEXT:    [[TMP1:%.*]] = or i32 [[X:%.*]], 1
2036 ; CHECK-NEXT:    [[CMP:%.*]] = icmp eq i32 [[TMP1]], 3
2037 ; CHECK-NEXT:    ret i1 [[CMP]]
2039   %add = sub i32 3, %X
2040   %cmp = icmp ult i32 %add, 2
2041   ret i1 %cmp
2044 define <2 x i1> @icmp_sub_3_X_ult_2_vec(<2 x i32> %X) {
2045 ; CHECK-LABEL: @icmp_sub_3_X_ult_2_vec(
2046 ; CHECK-NEXT:    [[TMP1:%.*]] = or <2 x i32> [[X:%.*]], <i32 1, i32 1>
2047 ; CHECK-NEXT:    [[CMP:%.*]] = icmp eq <2 x i32> [[TMP1]], <i32 3, i32 3>
2048 ; CHECK-NEXT:    ret <2 x i1> [[CMP]]
2050   %add = sub <2 x i32> <i32 3, i32 3>, %X
2051   %cmp = icmp ult <2 x i32> %add, <i32 2, i32 2>
2052   ret <2 x i1> %cmp
2055 define i1 @icmp_add_X_-14_uge_2(i32 %X) {
2056 ; CHECK-LABEL: @icmp_add_X_-14_uge_2(
2057 ; CHECK-NEXT:    [[TMP1:%.*]] = and i32 [[X:%.*]], -2
2058 ; CHECK-NEXT:    [[CMP:%.*]] = icmp ne i32 [[TMP1]], 14
2059 ; CHECK-NEXT:    ret i1 [[CMP]]
2061   %add = add i32 %X, -14
2062   %cmp = icmp uge i32 %add, 2
2063   ret i1 %cmp
2066 define <2 x i1> @icmp_add_X_-14_uge_2_vec(<2 x i32> %X) {
2067 ; CHECK-LABEL: @icmp_add_X_-14_uge_2_vec(
2068 ; CHECK-NEXT:    [[TMP1:%.*]] = and <2 x i32> [[X:%.*]], <i32 -2, i32 -2>
2069 ; CHECK-NEXT:    [[CMP:%.*]] = icmp ne <2 x i32> [[TMP1]], <i32 14, i32 14>
2070 ; CHECK-NEXT:    ret <2 x i1> [[CMP]]
2072   %add = add <2 x i32> %X, <i32 -14, i32 -14>
2073   %cmp = icmp uge <2 x i32> %add, <i32 2, i32 2>
2074   ret <2 x i1> %cmp
2077 define i1 @icmp_sub_3_X_uge_2(i32 %X) {
2078 ; CHECK-LABEL: @icmp_sub_3_X_uge_2(
2079 ; CHECK-NEXT:    [[TMP1:%.*]] = or i32 [[X:%.*]], 1
2080 ; CHECK-NEXT:    [[CMP:%.*]] = icmp ne i32 [[TMP1]], 3
2081 ; CHECK-NEXT:    ret i1 [[CMP]]
2083   %add = sub i32 3, %X
2084   %cmp = icmp uge i32 %add, 2
2085   ret i1 %cmp
2088 define <2 x i1> @icmp_sub_3_X_uge_2_vec(<2 x i32> %X) {
2089 ; CHECK-LABEL: @icmp_sub_3_X_uge_2_vec(
2090 ; CHECK-NEXT:    [[TMP1:%.*]] = or <2 x i32> [[X:%.*]], <i32 1, i32 1>
2091 ; CHECK-NEXT:    [[CMP:%.*]] = icmp ne <2 x i32> [[TMP1]], <i32 3, i32 3>
2092 ; CHECK-NEXT:    ret <2 x i1> [[CMP]]
2094   %add = sub <2 x i32> <i32 3, i32 3>, %X
2095   %cmp = icmp uge <2 x i32> %add, <i32 2, i32 2>
2096   ret <2 x i1> %cmp
2099 define i1 @icmp_and_X_-16_eq-16(i32 %X) {
2100 ; CHECK-LABEL: @icmp_and_X_-16_eq-16(
2101 ; CHECK-NEXT:    [[CMP:%.*]] = icmp ugt i32 [[X:%.*]], -17
2102 ; CHECK-NEXT:    ret i1 [[CMP]]
2104   %and = and i32 %X, -16
2105   %cmp = icmp eq i32 %and, -16
2106   ret i1 %cmp
2109 define <2 x i1> @icmp_and_X_-16_eq-16_vec(<2 x i32> %X) {
2110 ; CHECK-LABEL: @icmp_and_X_-16_eq-16_vec(
2111 ; CHECK-NEXT:    [[CMP:%.*]] = icmp ugt <2 x i32> [[X:%.*]], <i32 -17, i32 -17>
2112 ; CHECK-NEXT:    ret <2 x i1> [[CMP]]
2114   %and = and <2 x i32> %X, <i32 -16, i32 -16>
2115   %cmp = icmp eq <2 x i32> %and, <i32 -16, i32 -16>
2116   ret <2 x i1> %cmp
2119 define i1 @icmp_and_X_-16_ne-16(i32 %X) {
2120 ; CHECK-LABEL: @icmp_and_X_-16_ne-16(
2121 ; CHECK-NEXT:    [[CMP:%.*]] = icmp ult i32 [[X:%.*]], -16
2122 ; CHECK-NEXT:    ret i1 [[CMP]]
2124   %and = and i32 %X, -16
2125   %cmp = icmp ne i32 %and, -16
2126   ret i1 %cmp
2129 define <2 x i1> @icmp_and_X_-16_ne-16_vec(<2 x i32> %X) {
2130 ; CHECK-LABEL: @icmp_and_X_-16_ne-16_vec(
2131 ; CHECK-NEXT:    [[CMP:%.*]] = icmp ult <2 x i32> [[X:%.*]], <i32 -16, i32 -16>
2132 ; CHECK-NEXT:    ret <2 x i1> [[CMP]]
2134   %and = and <2 x i32> %X, <i32 -16, i32 -16>
2135   %cmp = icmp ne <2 x i32> %and, <i32 -16, i32 -16>
2136   ret <2 x i1> %cmp
2139 ; PR32524: https://bugs.llvm.org/show_bug.cgi?id=32524
2140 ; X | C == C --> X <=u C (when C+1 is PowerOf2).
2142 define i1 @or1_eq1(i32 %x) {
2143 ; CHECK-LABEL: @or1_eq1(
2144 ; CHECK-NEXT:    [[T1:%.*]] = icmp ult i32 [[X:%.*]], 2
2145 ; CHECK-NEXT:    ret i1 [[T1]]
2147   %t0 = or i32 %x, 1
2148   %t1 = icmp eq i32 %t0, 1
2149   ret i1 %t1
2152 ; X | C == C --> X <=u C (when C+1 is PowerOf2).
2154 define <2 x i1> @or3_eq3_vec(<2 x i8> %x) {
2155 ; CHECK-LABEL: @or3_eq3_vec(
2156 ; CHECK-NEXT:    [[T1:%.*]] = icmp ult <2 x i8> [[X:%.*]], <i8 4, i8 4>
2157 ; CHECK-NEXT:    ret <2 x i1> [[T1]]
2159   %t0 = or <2 x i8> %x, <i8 3, i8 3>
2160   %t1 = icmp eq <2 x i8> %t0, <i8 3, i8 3>
2161   ret <2 x i1> %t1
2164 ; X | C != C --> X >u C (when C+1 is PowerOf2).
2166 define i1 @or7_ne7(i32 %x) {
2167 ; CHECK-LABEL: @or7_ne7(
2168 ; CHECK-NEXT:    [[T1:%.*]] = icmp ugt i32 [[X:%.*]], 7
2169 ; CHECK-NEXT:    ret i1 [[T1]]
2171   %t0 = or i32 %x, 7
2172   %t1 = icmp ne i32 %t0, 7
2173   ret i1 %t1
2176 ; X | C != C --> X >u C (when C+1 is PowerOf2).
2178 define <2 x i1> @or63_ne63_vec(<2 x i8> %x) {
2179 ; CHECK-LABEL: @or63_ne63_vec(
2180 ; CHECK-NEXT:    [[T1:%.*]] = icmp ugt <2 x i8> [[X:%.*]], <i8 63, i8 63>
2181 ; CHECK-NEXT:    ret <2 x i1> [[T1]]
2183   %t0 = or <2 x i8> %x, <i8 63, i8 63>
2184   %t1 = icmp ne <2 x i8> %t0, <i8 63, i8 63>
2185   ret <2 x i1> %t1
2188 ; PR40611: https://bugs.llvm.org/show_bug.cgi?id=40611
2189 ; X | C == C --> (X & ~C) == 0
2191 define i1 @orC_eqC(i32 %x) {
2192 ; CHECK-LABEL: @orC_eqC(
2193 ; CHECK-NEXT:    [[TMP1:%.*]] = and i32 [[X:%.*]], -43
2194 ; CHECK-NEXT:    [[T1:%.*]] = icmp eq i32 [[TMP1]], 0
2195 ; CHECK-NEXT:    ret i1 [[T1]]
2197   %t0 = or i32 %x, 42
2198   %t1 = icmp eq i32 %t0, 42
2199   ret i1 %t1
2202 ; X | C == C --> (X & ~C) == 0
2204 define <2 x i1> @orC_eqC_vec(<2 x i8> %x) {
2205 ; CHECK-LABEL: @orC_eqC_vec(
2206 ; CHECK-NEXT:    [[TMP1:%.*]] = and <2 x i8> [[X:%.*]], <i8 -44, i8 -44>
2207 ; CHECK-NEXT:    [[T1:%.*]] = icmp eq <2 x i8> [[TMP1]], zeroinitializer
2208 ; CHECK-NEXT:    ret <2 x i1> [[T1]]
2210   %t0 = or <2 x i8> %x, <i8 43, i8 43>
2211   %t1 = icmp eq <2 x i8> %t0, <i8 43, i8 43>
2212   ret <2 x i1> %t1
2215 ; X | C != C --> (X & ~C) != 0
2217 define i1 @orC_neC(i32 %x) {
2218 ; CHECK-LABEL: @orC_neC(
2219 ; CHECK-NEXT:    [[TMP1:%.*]] = and i32 [[X:%.*]], 41
2220 ; CHECK-NEXT:    [[T1:%.*]] = icmp ne i32 [[TMP1]], 0
2221 ; CHECK-NEXT:    ret i1 [[T1]]
2223   %t0 = or i32 %x, -42
2224   %t1 = icmp ne i32 %t0, -42
2225   ret i1 %t1
2228 ; X | C != C --> (X & ~C) != 0
2230 define <2 x i1> @orC_neC_vec(<2 x i8> %x) {
2231 ; CHECK-LABEL: @orC_neC_vec(
2232 ; CHECK-NEXT:    [[TMP1:%.*]] = and <2 x i8> [[X:%.*]], <i8 42, i8 42>
2233 ; CHECK-NEXT:    [[T1:%.*]] = icmp ne <2 x i8> [[TMP1]], zeroinitializer
2234 ; CHECK-NEXT:    ret <2 x i1> [[T1]]
2236   %t0 = or <2 x i8> %x, <i8 -43, i8 -43>
2237   %t1 = icmp ne <2 x i8> %t0, <i8 -43, i8 -43>
2238   ret <2 x i1> %t1
2241 define i1 @shrink_constant(i32 %X) {
2242 ; CHECK-LABEL: @shrink_constant(
2243 ; CHECK-NEXT:    [[XOR:%.*]] = xor i32 [[X:%.*]], -12
2244 ; CHECK-NEXT:    [[CMP:%.*]] = icmp ult i32 [[XOR]], 4
2245 ; CHECK-NEXT:    ret i1 [[CMP]]
2247   %xor = xor i32 %X, -9
2248   %cmp = icmp ult i32 %xor, 4
2249   ret i1 %cmp
2252 define <2 x i1> @shrink_constant_vec(<2 x i32> %X) {
2253 ; CHECK-LABEL: @shrink_constant_vec(
2254 ; CHECK-NEXT:    [[XOR:%.*]] = xor <2 x i32> [[X:%.*]], <i32 -12, i32 -12>
2255 ; CHECK-NEXT:    [[CMP:%.*]] = icmp ult <2 x i32> [[XOR]], <i32 4, i32 4>
2256 ; CHECK-NEXT:    ret <2 x i1> [[CMP]]
2258   %xor = xor <2 x i32> %X, <i32 -9, i32 -9>
2259   %cmp = icmp ult <2 x i32> %xor, <i32 4, i32 4>
2260   ret <2 x i1> %cmp
2263 ; This test requires 3 different transforms to get to the result.
2264 define i1 @icmp_sub_-1_X_ult_4(i32 %X) {
2265 ; CHECK-LABEL: @icmp_sub_-1_X_ult_4(
2266 ; CHECK-NEXT:    [[CMP:%.*]] = icmp ugt i32 [[X:%.*]], -5
2267 ; CHECK-NEXT:    ret i1 [[CMP]]
2269   %sub = sub i32 -1, %X
2270   %cmp = icmp ult i32 %sub, 4
2271   ret i1 %cmp
2274 define <2 x i1> @icmp_xor_neg4_X_ult_4_vec(<2 x i32> %X) {
2275 ; CHECK-LABEL: @icmp_xor_neg4_X_ult_4_vec(
2276 ; CHECK-NEXT:    [[CMP:%.*]] = icmp ugt <2 x i32> [[X:%.*]], <i32 -5, i32 -5>
2277 ; CHECK-NEXT:    ret <2 x i1> [[CMP]]
2279   %xor = xor <2 x i32> %X, <i32 -4, i32 -4>
2280   %cmp = icmp ult <2 x i32> %xor, <i32 4, i32 4>
2281   ret <2 x i1> %cmp
2284 define i1 @icmp_sub_-1_X_uge_4(i32 %X) {
2285 ; CHECK-LABEL: @icmp_sub_-1_X_uge_4(
2286 ; CHECK-NEXT:    [[CMP:%.*]] = icmp ult i32 [[X:%.*]], -4
2287 ; CHECK-NEXT:    ret i1 [[CMP]]
2289   %sub = sub i32 -1, %X
2290   %cmp = icmp uge i32 %sub, 4
2291   ret i1 %cmp
2294 define <2 x i1> @icmp_xor_neg4_X_uge_4_vec(<2 x i32> %X) {
2295 ; CHECK-LABEL: @icmp_xor_neg4_X_uge_4_vec(
2296 ; CHECK-NEXT:    [[CMP:%.*]] = icmp ult <2 x i32> [[X:%.*]], <i32 -4, i32 -4>
2297 ; CHECK-NEXT:    ret <2 x i1> [[CMP]]
2299   %xor = xor <2 x i32> %X, <i32 -4, i32 -4>
2300   %cmp = icmp uge <2 x i32> %xor, <i32 4, i32 4>
2301   ret <2 x i1> %cmp
2304 define <2 x i1> @xor_ult(<2 x i8> %x) {
2305 ; CHECK-LABEL: @xor_ult(
2306 ; CHECK-NEXT:    [[R:%.*]] = icmp ugt <2 x i8> [[X:%.*]], <i8 3, i8 3>
2307 ; CHECK-NEXT:    ret <2 x i1> [[R]]
2309   %xor = xor <2 x i8> %x, <i8 -4, i8 -4>
2310   %r = icmp ult <2 x i8> %xor, <i8 -4, i8 -4>
2311   ret <2 x i1> %r
2314 define i1 @xor_ult_extra_use(i8 %x, i8* %p) {
2315 ; CHECK-LABEL: @xor_ult_extra_use(
2316 ; CHECK-NEXT:    [[XOR:%.*]] = xor i8 [[X:%.*]], -32
2317 ; CHECK-NEXT:    store i8 [[XOR]], i8* [[P:%.*]], align 1
2318 ; CHECK-NEXT:    [[R:%.*]] = icmp ugt i8 [[X]], 31
2319 ; CHECK-NEXT:    ret i1 [[R]]
2321   %xor = xor i8 %x, -32
2322   store i8 %xor, i8* %p
2323   %r = icmp ult i8 %xor, -32
2324   ret i1 %r
2327 define <2 x i1> @xor_ugt(<2 x i8> %x) {
2328 ; CHECK-LABEL: @xor_ugt(
2329 ; CHECK-NEXT:    [[R:%.*]] = icmp ugt <2 x i8> [[X:%.*]], <i8 7, i8 7>
2330 ; CHECK-NEXT:    ret <2 x i1> [[R]]
2332   %xor = xor <2 x i8> %x, <i8 7, i8 7>
2333   %r = icmp ugt <2 x i8> %xor, <i8 7, i8 7>
2334   ret <2 x i1> %r
2337 define i1 @xor_ugt_extra_use(i8 %x, i8* %p) {
2338 ; CHECK-LABEL: @xor_ugt_extra_use(
2339 ; CHECK-NEXT:    [[XOR:%.*]] = xor i8 [[X:%.*]], 63
2340 ; CHECK-NEXT:    store i8 [[XOR]], i8* [[P:%.*]], align 1
2341 ; CHECK-NEXT:    [[R:%.*]] = icmp ugt i8 [[X]], 63
2342 ; CHECK-NEXT:    ret i1 [[R]]
2344   %xor = xor i8 %x, 63
2345   store i8 %xor, i8* %p
2346   %r = icmp ugt i8 %xor, 63
2347   ret i1 %r
2350 define i1 @icmp_swap_operands_for_cse(i32 %X, i32 %Y) {
2351 ; CHECK-LABEL: @icmp_swap_operands_for_cse(
2352 ; CHECK-NEXT:  entry:
2353 ; CHECK-NEXT:    [[SUB:%.*]] = sub i32 [[X:%.*]], [[Y:%.*]]
2354 ; CHECK-NEXT:    [[CMP:%.*]] = icmp ult i32 [[X]], [[Y]]
2355 ; CHECK-NEXT:    br i1 [[CMP]], label [[TRUE:%.*]], label [[FALSE:%.*]]
2356 ; CHECK:       true:
2357 ; CHECK-NEXT:    [[TMP0:%.*]] = and i32 [[SUB]], 1
2358 ; CHECK-NEXT:    br label [[END:%.*]]
2359 ; CHECK:       false:
2360 ; CHECK-NEXT:    [[TMP1:%.*]] = and i32 [[SUB]], 16
2361 ; CHECK-NEXT:    br label [[END]]
2362 ; CHECK:       end:
2363 ; CHECK-NEXT:    [[RES_IN:%.*]] = phi i32 [ [[TMP0]], [[TRUE]] ], [ [[TMP1]], [[FALSE]] ]
2364 ; CHECK-NEXT:    [[RES:%.*]] = icmp ne i32 [[RES_IN]], 0
2365 ; CHECK-NEXT:    ret i1 [[RES]]
2367 entry:
2368   %sub = sub i32 %X, %Y
2369   %cmp = icmp ugt i32 %Y, %X
2370   br i1 %cmp, label %true, label %false
2371 true:
2372   %restrue = trunc i32 %sub to i1
2373   br label %end
2374 false:
2375   %shift = lshr i32 %sub, 4
2376   %resfalse = trunc i32 %shift to i1
2377   br label %end
2378 end:
2379   %res = phi i1 [%restrue, %true], [%resfalse, %false]
2380   ret i1 %res
2383 define i1 @icmp_swap_operands_for_cse2(i32 %X, i32 %Y) {
2384 ; CHECK-LABEL: @icmp_swap_operands_for_cse2(
2385 ; CHECK-NEXT:  entry:
2386 ; CHECK-NEXT:    [[CMP:%.*]] = icmp ult i32 [[X:%.*]], [[Y:%.*]]
2387 ; CHECK-NEXT:    br i1 [[CMP]], label [[TRUE:%.*]], label [[FALSE:%.*]]
2388 ; CHECK:       true:
2389 ; CHECK-NEXT:    [[SUB:%.*]] = sub i32 [[X]], [[Y]]
2390 ; CHECK-NEXT:    [[SUB1:%.*]] = sub i32 [[X]], [[Y]]
2391 ; CHECK-NEXT:    [[ADD:%.*]] = add i32 [[SUB]], [[SUB1]]
2392 ; CHECK-NEXT:    br label [[END:%.*]]
2393 ; CHECK:       false:
2394 ; CHECK-NEXT:    [[SUB2:%.*]] = sub i32 [[Y]], [[X]]
2395 ; CHECK-NEXT:    br label [[END]]
2396 ; CHECK:       end:
2397 ; CHECK-NEXT:    [[RES_IN_IN:%.*]] = phi i32 [ [[ADD]], [[TRUE]] ], [ [[SUB2]], [[FALSE]] ]
2398 ; CHECK-NEXT:    [[RES_IN:%.*]] = and i32 [[RES_IN_IN]], 1
2399 ; CHECK-NEXT:    [[RES:%.*]] = icmp ne i32 [[RES_IN]], 0
2400 ; CHECK-NEXT:    ret i1 [[RES]]
2402 entry:
2403   %cmp = icmp ugt i32 %Y, %X
2404   br i1 %cmp, label %true, label %false
2405 true:
2406   %sub = sub i32 %X, %Y
2407   %sub1 = sub i32 %X, %Y
2408   %add = add i32 %sub, %sub1
2409   %restrue = trunc i32 %add to i1
2410   br label %end
2411 false:
2412   %sub2 = sub i32 %Y, %X
2413   %resfalse = trunc i32 %sub2 to i1
2414   br label %end
2415 end:
2416   %res = phi i1 [%restrue, %true], [%resfalse, %false]
2417   ret i1 %res
2420 define i1 @icmp_do_not_swap_operands_for_cse(i32 %X, i32 %Y) {
2421 ; CHECK-LABEL: @icmp_do_not_swap_operands_for_cse(
2422 ; CHECK-NEXT:  entry:
2423 ; CHECK-NEXT:    [[CMP:%.*]] = icmp ugt i32 [[Y:%.*]], [[X:%.*]]
2424 ; CHECK-NEXT:    br i1 [[CMP]], label [[TRUE:%.*]], label [[FALSE:%.*]]
2425 ; CHECK:       true:
2426 ; CHECK-NEXT:    [[SUB:%.*]] = sub i32 [[X]], [[Y]]
2427 ; CHECK-NEXT:    br label [[END:%.*]]
2428 ; CHECK:       false:
2429 ; CHECK-NEXT:    [[SUB2:%.*]] = sub i32 [[Y]], [[X]]
2430 ; CHECK-NEXT:    br label [[END]]
2431 ; CHECK:       end:
2432 ; CHECK-NEXT:    [[RES_IN_IN:%.*]] = phi i32 [ [[SUB]], [[TRUE]] ], [ [[SUB2]], [[FALSE]] ]
2433 ; CHECK-NEXT:    [[RES_IN:%.*]] = and i32 [[RES_IN_IN]], 1
2434 ; CHECK-NEXT:    [[RES:%.*]] = icmp ne i32 [[RES_IN]], 0
2435 ; CHECK-NEXT:    ret i1 [[RES]]
2437 entry:
2438   %cmp = icmp ugt i32 %Y, %X
2439   br i1 %cmp, label %true, label %false
2440 true:
2441   %sub = sub i32 %X, %Y
2442   %restrue = trunc i32 %sub to i1
2443   br label %end
2444 false:
2445   %sub2 = sub i32 %Y, %X
2446   %resfalse = trunc i32 %sub2 to i1
2447   br label %end
2448 end:
2449   %res = phi i1 [%restrue, %true], [%resfalse, %false]
2450   ret i1 %res
2453 define i1 @icmp_lshr_lshr_eq(i32 %a, i32 %b) {
2454 ; CHECK-LABEL: @icmp_lshr_lshr_eq(
2455 ; CHECK-NEXT:    [[Z_UNSHIFTED:%.*]] = xor i32 [[A:%.*]], [[B:%.*]]
2456 ; CHECK-NEXT:    [[Z:%.*]] = icmp ult i32 [[Z_UNSHIFTED]], 1073741824
2457 ; CHECK-NEXT:    ret i1 [[Z]]
2459   %x = lshr i32 %a, 30
2460   %y = lshr i32 %b, 30
2461   %z = icmp eq i32 %x, %y
2462   ret i1 %z
2465 define i1 @icmp_ashr_ashr_ne(i32 %a, i32 %b) {
2466 ; CHECK-LABEL: @icmp_ashr_ashr_ne(
2467 ; CHECK-NEXT:    [[Z_UNSHIFTED:%.*]] = xor i32 [[A:%.*]], [[B:%.*]]
2468 ; CHECK-NEXT:    [[Z:%.*]] = icmp ugt i32 [[Z_UNSHIFTED]], 255
2469 ; CHECK-NEXT:    ret i1 [[Z]]
2471   %x = ashr i32 %a, 8
2472   %y = ashr i32 %b, 8
2473   %z = icmp ne i32 %x, %y
2474   ret i1 %z
2477 define i1 @icmp_neg_cst_slt(i32 %a) {
2478 ; CHECK-LABEL: @icmp_neg_cst_slt(
2479 ; CHECK-NEXT:    [[TMP1:%.*]] = icmp sgt i32 [[A:%.*]], 10
2480 ; CHECK-NEXT:    ret i1 [[TMP1]]
2482   %1 = sub nsw i32 0, %a
2483   %2 = icmp slt i32 %1, -10
2484   ret i1 %2
2487 define i1 @icmp_and_or_lshr(i32 %x, i32 %y) {
2488 ; CHECK-LABEL: @icmp_and_or_lshr(
2489 ; CHECK-NEXT:    [[SHF1:%.*]] = shl nuw i32 1, [[Y:%.*]]
2490 ; CHECK-NEXT:    [[OR2:%.*]] = or i32 [[SHF1]], 1
2491 ; CHECK-NEXT:    [[AND3:%.*]] = and i32 [[OR2]], [[X:%.*]]
2492 ; CHECK-NEXT:    [[RET:%.*]] = icmp ne i32 [[AND3]], 0
2493 ; CHECK-NEXT:    ret i1 [[RET]]
2495   %shf = lshr i32 %x, %y
2496   %or = or i32 %shf, %x
2497   %and = and i32 %or, 1
2498   %ret = icmp ne i32 %and, 0
2499   ret i1 %ret
2502 define <2 x i1> @icmp_and_or_lshr_vec(<2 x i32> %x, <2 x i32> %y) {
2503 ; CHECK-LABEL: @icmp_and_or_lshr_vec(
2504 ; CHECK-NEXT:    [[SHF:%.*]] = lshr <2 x i32> [[X:%.*]], [[Y:%.*]]
2505 ; CHECK-NEXT:    [[OR:%.*]] = or <2 x i32> [[SHF]], [[X]]
2506 ; CHECK-NEXT:    [[RET:%.*]] = trunc <2 x i32> [[OR]] to <2 x i1>
2507 ; CHECK-NEXT:    ret <2 x i1> [[RET]]
2509   %shf = lshr <2 x i32> %x, %y
2510   %or = or <2 x i32> %shf, %x
2511   %and = and <2 x i32> %or, <i32 1, i32 1>
2512   %ret = icmp ne <2 x i32> %and, zeroinitializer
2513   ret <2 x i1> %ret
2516 define <2 x i1> @icmp_and_or_lshr_vec_commute(<2 x i32> %xp, <2 x i32> %y) {
2517 ; CHECK-LABEL: @icmp_and_or_lshr_vec_commute(
2518 ; CHECK-NEXT:    [[X:%.*]] = srem <2 x i32> [[XP:%.*]], <i32 42, i32 42>
2519 ; CHECK-NEXT:    [[SHF:%.*]] = lshr <2 x i32> [[X]], [[Y:%.*]]
2520 ; CHECK-NEXT:    [[OR:%.*]] = or <2 x i32> [[X]], [[SHF]]
2521 ; CHECK-NEXT:    [[RET:%.*]] = trunc <2 x i32> [[OR]] to <2 x i1>
2522 ; CHECK-NEXT:    ret <2 x i1> [[RET]]
2524   %x = srem <2 x i32> %xp, <i32 42, i32 -42> ; prevent complexity-based canonicalization
2525   %shf = lshr <2 x i32> %x, %y
2526   %or = or <2 x i32> %x, %shf
2527   %and = and <2 x i32> %or, <i32 1, i32 1>
2528   %ret = icmp ne <2 x i32> %and, zeroinitializer
2529   ret <2 x i1> %ret
2532 define i1 @icmp_and_or_lshr_cst(i32 %x) {
2533 ; CHECK-LABEL: @icmp_and_or_lshr_cst(
2534 ; CHECK-NEXT:    [[AND1:%.*]] = and i32 [[X:%.*]], 3
2535 ; CHECK-NEXT:    [[RET:%.*]] = icmp ne i32 [[AND1]], 0
2536 ; CHECK-NEXT:    ret i1 [[RET]]
2538   %shf = lshr i32 %x, 1
2539   %or = or i32 %shf, %x
2540   %and = and i32 %or, 1
2541   %ret = icmp ne i32 %and, 0
2542   ret i1 %ret
2545 define <2 x i1> @icmp_and_or_lshr_cst_vec(<2 x i32> %x) {
2546 ; CHECK-LABEL: @icmp_and_or_lshr_cst_vec(
2547 ; CHECK-NEXT:    [[TMP1:%.*]] = and <2 x i32> [[X:%.*]], <i32 3, i32 3>
2548 ; CHECK-NEXT:    [[RET:%.*]] = icmp ne <2 x i32> [[TMP1]], zeroinitializer
2549 ; CHECK-NEXT:    ret <2 x i1> [[RET]]
2551   %shf = lshr <2 x i32> %x, <i32 1, i32 1>
2552   %or = or <2 x i32> %shf, %x
2553   %and = and <2 x i32> %or, <i32 1, i32 1>
2554   %ret = icmp ne <2 x i32> %and, zeroinitializer
2555   ret <2 x i1> %ret
2558 define <2 x i1> @icmp_and_or_lshr_cst_vec_commute(<2 x i32> %xp) {
2559 ; CHECK-LABEL: @icmp_and_or_lshr_cst_vec_commute(
2560 ; CHECK-NEXT:    [[X:%.*]] = srem <2 x i32> [[XP:%.*]], <i32 42, i32 42>
2561 ; CHECK-NEXT:    [[TMP1:%.*]] = and <2 x i32> [[X]], <i32 3, i32 3>
2562 ; CHECK-NEXT:    [[RET:%.*]] = icmp ne <2 x i32> [[TMP1]], zeroinitializer
2563 ; CHECK-NEXT:    ret <2 x i1> [[RET]]
2565   %x = srem <2 x i32> %xp, <i32 42, i32 -42> ; prevent complexity-based canonicalization
2566   %shf = lshr <2 x i32> %x, <i32 1, i32 1>
2567   %or = or <2 x i32> %x, %shf
2568   %and = and <2 x i32> %or, <i32 1, i32 1>
2569   %ret = icmp ne <2 x i32> %and, zeroinitializer
2570   ret <2 x i1> %ret
2573 define i1 @shl_ap1_zero_ap2_non_zero_2(i32 %a) {
2574 ; CHECK-LABEL: @shl_ap1_zero_ap2_non_zero_2(
2575 ; CHECK-NEXT:    [[CMP:%.*]] = icmp ugt i32 [[A:%.*]], 29
2576 ; CHECK-NEXT:    ret i1 [[CMP]]
2578   %shl = shl i32 4, %a
2579   %cmp = icmp eq i32 %shl, 0
2580   ret i1 %cmp
2583 define <2 x i1> @shl_ap1_zero_ap2_non_zero_2_vec(<2 x i32> %a) {
2584 ; CHECK-LABEL: @shl_ap1_zero_ap2_non_zero_2_vec(
2585 ; CHECK-NEXT:    [[CMP:%.*]] = icmp ugt <2 x i32> [[A:%.*]], <i32 29, i32 29>
2586 ; CHECK-NEXT:    ret <2 x i1> [[CMP]]
2588   %shl = shl <2 x i32> <i32 4, i32 4>, %a
2589   %cmp = icmp eq <2 x i32> %shl, zeroinitializer
2590   ret <2 x i1> %cmp
2593 define i1 @shl_ap1_zero_ap2_non_zero_4(i32 %a) {
2594 ; CHECK-LABEL: @shl_ap1_zero_ap2_non_zero_4(
2595 ; CHECK-NEXT:    [[CMP:%.*]] = icmp ugt i32 [[A:%.*]], 30
2596 ; CHECK-NEXT:    ret i1 [[CMP]]
2598   %shl = shl i32 -2, %a
2599   %cmp = icmp eq i32 %shl, 0
2600   ret i1 %cmp
2603 define i1 @shl_ap1_non_zero_ap2_non_zero_both_positive(i32 %a) {
2604 ; CHECK-LABEL: @shl_ap1_non_zero_ap2_non_zero_both_positive(
2605 ; CHECK-NEXT:    [[CMP:%.*]] = icmp eq i32 [[A:%.*]], 0
2606 ; CHECK-NEXT:    ret i1 [[CMP]]
2608   %shl = shl i32 50, %a
2609   %cmp = icmp eq i32 %shl, 50
2610   ret i1 %cmp
2613 define i1 @shl_ap1_non_zero_ap2_non_zero_both_negative(i32 %a) {
2614 ; CHECK-LABEL: @shl_ap1_non_zero_ap2_non_zero_both_negative(
2615 ; CHECK-NEXT:    [[CMP:%.*]] = icmp eq i32 [[A:%.*]], 0
2616 ; CHECK-NEXT:    ret i1 [[CMP]]
2618   %shl = shl i32 -50, %a
2619   %cmp = icmp eq i32 %shl, -50
2620   ret i1 %cmp
2623 define i1 @shl_ap1_non_zero_ap2_non_zero_ap1_1(i32 %a) {
2624 ; CHECK-LABEL: @shl_ap1_non_zero_ap2_non_zero_ap1_1(
2625 ; CHECK-NEXT:    ret i1 false
2627   %shl = shl i32 50, %a
2628   %cmp = icmp eq i32 %shl, 25
2629   ret i1 %cmp
2632 define i1 @shl_ap1_non_zero_ap2_non_zero_ap1_2(i32 %a) {
2633 ; CHECK-LABEL: @shl_ap1_non_zero_ap2_non_zero_ap1_2(
2634 ; CHECK-NEXT:    [[CMP:%.*]] = icmp eq i32 [[A:%.*]], 1
2635 ; CHECK-NEXT:    ret i1 [[CMP]]
2637   %shl = shl i32 25, %a
2638   %cmp = icmp eq i32 %shl, 50
2639   ret i1 %cmp
2642 define i1 @shl_ap1_non_zero_ap2_non_zero_ap1_3(i32 %a) {
2643 ; CHECK-LABEL: @shl_ap1_non_zero_ap2_non_zero_ap1_3(
2644 ; CHECK-NEXT:    ret i1 false
2646   %shl = shl i32 26, %a
2647   %cmp = icmp eq i32 %shl, 50
2648   ret i1 %cmp
2651 define i1 @icmp_sgt_zero_add_nsw(i32 %a) {
2652 ; CHECK-LABEL: @icmp_sgt_zero_add_nsw(
2653 ; CHECK-NEXT:    [[CMP:%.*]] = icmp sgt i32 [[A:%.*]], -1
2654 ; CHECK-NEXT:    ret i1 [[CMP]]
2656   %add = add nsw i32 %a, 1
2657   %cmp = icmp sgt i32 %add, 0
2658   ret i1 %cmp
2661 define i1 @icmp_sge_zero_add_nsw(i32 %a) {
2662 ; CHECK-LABEL: @icmp_sge_zero_add_nsw(
2663 ; CHECK-NEXT:    [[CMP:%.*]] = icmp sgt i32 [[A:%.*]], -2
2664 ; CHECK-NEXT:    ret i1 [[CMP]]
2666   %add = add nsw i32 %a, 1
2667   %cmp = icmp sge i32 %add, 0
2668   ret i1 %cmp
2671 define i1 @icmp_sle_zero_add_nsw(i32 %a) {
2672 ; CHECK-LABEL: @icmp_sle_zero_add_nsw(
2673 ; CHECK-NEXT:    [[CMP:%.*]] = icmp slt i32 [[A:%.*]], 0
2674 ; CHECK-NEXT:    ret i1 [[CMP]]
2676   %add = add nsw i32 %a, 1
2677   %cmp = icmp sle i32 %add, 0
2678   ret i1 %cmp
2681 define zeroext i1 @icmp_cmpxchg_strong(i32* %sc, i32 %old_val, i32 %new_val) {
2682 ; CHECK-LABEL: @icmp_cmpxchg_strong(
2683 ; CHECK-NEXT:    [[XCHG:%.*]] = cmpxchg i32* [[SC:%.*]], i32 [[OLD_VAL:%.*]], i32 [[NEW_VAL:%.*]] seq_cst seq_cst
2684 ; CHECK-NEXT:    [[ICMP:%.*]] = extractvalue { i32, i1 } [[XCHG]], 1
2685 ; CHECK-NEXT:    ret i1 [[ICMP]]
2687   %xchg = cmpxchg i32* %sc, i32 %old_val, i32 %new_val seq_cst seq_cst
2688   %xtrc = extractvalue { i32, i1 } %xchg, 0
2689   %icmp = icmp eq i32 %xtrc, %old_val
2690   ret i1 %icmp
2693 define i1 @f1(i64 %a, i64 %b) {
2694 ; CHECK-LABEL: @f1(
2695 ; CHECK-NEXT:    [[V:%.*]] = icmp sge i64 [[A:%.*]], [[B:%.*]]
2696 ; CHECK-NEXT:    ret i1 [[V]]
2698   %t = sub nsw i64 %a, %b
2699   %v = icmp sge i64 %t, 0
2700   ret i1 %v
2703 define <2 x i1> @f1_vec(<2 x i64> %a, <2 x i64> %b) {
2704 ; CHECK-LABEL: @f1_vec(
2705 ; CHECK-NEXT:    [[V:%.*]] = icmp sge <2 x i64> [[A:%.*]], [[B:%.*]]
2706 ; CHECK-NEXT:    ret <2 x i1> [[V]]
2708   %t = sub nsw <2 x i64> %a, %b
2709   %v = icmp sgt <2 x i64> %t, <i64 -1, i64 -1>
2710   ret <2 x i1> %v
2713 define i1 @f2(i64 %a, i64 %b) {
2714 ; CHECK-LABEL: @f2(
2715 ; CHECK-NEXT:    [[V:%.*]] = icmp sgt i64 [[A:%.*]], [[B:%.*]]
2716 ; CHECK-NEXT:    ret i1 [[V]]
2718   %t = sub nsw i64 %a, %b
2719   %v = icmp sgt i64 %t, 0
2720   ret i1 %v
2723 define <2 x i1> @f2_vec(<2 x i64> %a, <2 x i64> %b) {
2724 ; CHECK-LABEL: @f2_vec(
2725 ; CHECK-NEXT:    [[V:%.*]] = icmp sgt <2 x i64> [[A:%.*]], [[B:%.*]]
2726 ; CHECK-NEXT:    ret <2 x i1> [[V]]
2728   %t = sub nsw <2 x i64> %a, %b
2729   %v = icmp sgt <2 x i64> %t, zeroinitializer
2730   ret <2 x i1> %v
2733 define i1 @f3(i64 %a, i64 %b) {
2734 ; CHECK-LABEL: @f3(
2735 ; CHECK-NEXT:    [[V:%.*]] = icmp slt i64 [[A:%.*]], [[B:%.*]]
2736 ; CHECK-NEXT:    ret i1 [[V]]
2738   %t = sub nsw i64 %a, %b
2739   %v = icmp slt i64 %t, 0
2740   ret i1 %v
2743 define <2 x i1> @f3_vec(<2 x i64> %a, <2 x i64> %b) {
2744 ; CHECK-LABEL: @f3_vec(
2745 ; CHECK-NEXT:    [[V:%.*]] = icmp slt <2 x i64> [[A:%.*]], [[B:%.*]]
2746 ; CHECK-NEXT:    ret <2 x i1> [[V]]
2748   %t = sub nsw <2 x i64> %a, %b
2749   %v = icmp slt <2 x i64> %t, zeroinitializer
2750   ret <2 x i1> %v
2753 define i1 @f4(i64 %a, i64 %b) {
2754 ; CHECK-LABEL: @f4(
2755 ; CHECK-NEXT:    [[V:%.*]] = icmp sle i64 [[A:%.*]], [[B:%.*]]
2756 ; CHECK-NEXT:    ret i1 [[V]]
2758   %t = sub nsw i64 %a, %b
2759   %v = icmp sle i64 %t, 0
2760   ret i1 %v
2763 define <2 x i1> @f4_vec(<2 x i64> %a, <2 x i64> %b) {
2764 ; CHECK-LABEL: @f4_vec(
2765 ; CHECK-NEXT:    [[V:%.*]] = icmp sle <2 x i64> [[A:%.*]], [[B:%.*]]
2766 ; CHECK-NEXT:    ret <2 x i1> [[V]]
2768   %t = sub nsw <2 x i64> %a, %b
2769   %v = icmp slt <2 x i64> %t, <i64 1, i64 1>
2770   ret <2 x i1> %v
2773 define i32 @f5(i8 %a, i8 %b) {
2774 ; CHECK-LABEL: @f5(
2775 ; CHECK-NEXT:    [[CONV:%.*]] = zext i8 [[A:%.*]] to i32
2776 ; CHECK-NEXT:    [[CONV3:%.*]] = zext i8 [[B:%.*]] to i32
2777 ; CHECK-NEXT:    [[SUB:%.*]] = sub nsw i32 [[CONV]], [[CONV3]]
2778 ; CHECK-NEXT:    [[CMP4:%.*]] = icmp slt i32 [[SUB]], 0
2779 ; CHECK-NEXT:    [[SUB7:%.*]] = sub nsw i32 0, [[SUB]]
2780 ; CHECK-NEXT:    [[SUB7_SUB:%.*]] = select i1 [[CMP4]], i32 [[SUB7]], i32 [[SUB]]
2781 ; CHECK-NEXT:    ret i32 [[SUB7_SUB]]
2783   %conv = zext i8 %a to i32
2784   %conv3 = zext i8 %b to i32
2785   %sub = sub nsw i32 %conv, %conv3
2786   %cmp4 = icmp slt i32 %sub, 0
2787   %sub7 = sub nsw i32 0, %sub
2788   %sub7.sub = select i1 %cmp4, i32 %sub7, i32 %sub
2789   ret i32 %sub7.sub
2792 define i32 @f6(i32 %a, i32 %b) {
2793 ; CHECK-LABEL: @f6(
2794 ; CHECK-NEXT:    [[CMP_UNSHIFTED:%.*]] = xor i32 [[A:%.*]], [[B:%.*]]
2795 ; CHECK-NEXT:    [[CMP_MASK:%.*]] = and i32 [[CMP_UNSHIFTED]], 255
2796 ; CHECK-NEXT:    [[CMP:%.*]] = icmp eq i32 [[CMP_MASK]], 0
2797 ; CHECK-NEXT:    [[S:%.*]] = select i1 [[CMP]], i32 10000, i32 0
2798 ; CHECK-NEXT:    ret i32 [[S]]
2800   %sext = shl i32 %a, 24
2801   %conv = ashr i32 %sext, 24
2802   %sext6 = shl i32 %b, 24
2803   %conv4 = ashr i32 %sext6, 24
2804   %cmp = icmp eq i32 %conv, %conv4
2805   %s = select i1 %cmp, i32 10000, i32 0
2806   ret i32 %s
2809 define i32 @f7(i32 %a, i32 %b) {
2810 ; CHECK-LABEL: @f7(
2811 ; CHECK-NEXT:    [[CMP_UNSHIFTED:%.*]] = xor i32 [[A:%.*]], [[B:%.*]]
2812 ; CHECK-NEXT:    [[CMP_MASK:%.*]] = and i32 [[CMP_UNSHIFTED]], 511
2813 ; CHECK-NEXT:    [[CMP:%.*]] = icmp eq i32 [[CMP_MASK]], 0
2814 ; CHECK-NEXT:    [[S:%.*]] = select i1 [[CMP]], i32 0, i32 10000
2815 ; CHECK-NEXT:    ret i32 [[S]]
2817   %sext = shl i32 %a, 23
2818   %sext6 = shl i32 %b, 23
2819   %cmp = icmp ne i32 %sext, %sext6
2820   %s = select i1 %cmp, i32 10000, i32 0
2821   ret i32 %s
2824 define i1 @f8(i32 %val, i32 %lim) {
2825 ; CHECK-LABEL: @f8(
2826 ; CHECK-NEXT:    [[R:%.*]] = icmp ne i32 [[LIM:%.*]], 0
2827 ; CHECK-NEXT:    ret i1 [[R]]
2829   %lim.sub = add i32 %lim, -1
2830   %val.and = and i32 %val, %lim.sub
2831   %r = icmp ult i32 %val.and, %lim
2832   ret i1 %r
2835 define i1 @f9(i32 %val, i32 %lim) {
2836 ; CHECK-LABEL: @f9(
2837 ; CHECK-NEXT:    [[R:%.*]] = icmp ne i32 [[LIM:%.*]], 0
2838 ; CHECK-NEXT:    ret i1 [[R]]
2840   %lim.sub = sub i32 %lim, 1
2841   %val.and = and i32 %val, %lim.sub
2842   %r = icmp ult i32 %val.and, %lim
2843   ret i1 %r
2846 define i1 @f10(i16 %p) {
2847 ; CHECK-LABEL: @f10(
2848 ; 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))
2849 ; CHECK-NEXT:    ret i1 [[CMP580]]
2851   %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
2852   ret i1 %cmp580
2855 ; Note: fptosi is used in various tests below to ensure that operand complexity
2856 ; canonicalization does not kick in, which would make some of the tests
2857 ; equivalent to one another.
2859 define i1 @cmp_sgt_rhs_dec(float %x, i32 %i) {
2860 ; CHECK-LABEL: @cmp_sgt_rhs_dec(
2861 ; CHECK-NEXT:    [[CONV:%.*]] = fptosi float [[X:%.*]] to i32
2862 ; CHECK-NEXT:    [[CMP:%.*]] = icmp sge i32 [[CONV]], [[I:%.*]]
2863 ; CHECK-NEXT:    ret i1 [[CMP]]
2865   %conv = fptosi float %x to i32
2866   %dec = sub nsw i32 %i, 1
2867   %cmp = icmp sgt i32 %conv, %dec
2868   ret i1 %cmp
2871 define i1 @cmp_sle_rhs_dec(float %x, i32 %i) {
2872 ; CHECK-LABEL: @cmp_sle_rhs_dec(
2873 ; CHECK-NEXT:    [[CONV:%.*]] = fptosi float [[X:%.*]] to i32
2874 ; CHECK-NEXT:    [[CMP:%.*]] = icmp slt i32 [[CONV]], [[I:%.*]]
2875 ; CHECK-NEXT:    ret i1 [[CMP]]
2877   %conv = fptosi float %x to i32
2878   %dec = sub nsw i32 %i, 1
2879   %cmp = icmp sle i32 %conv, %dec
2880   ret i1 %cmp
2883 define i1 @cmp_sge_rhs_inc(float %x, i32 %i) {
2884 ; CHECK-LABEL: @cmp_sge_rhs_inc(
2885 ; CHECK-NEXT:    [[CONV:%.*]] = fptosi float [[X:%.*]] to i32
2886 ; CHECK-NEXT:    [[CMP:%.*]] = icmp sgt i32 [[CONV]], [[I:%.*]]
2887 ; CHECK-NEXT:    ret i1 [[CMP]]
2889   %conv = fptosi float %x to i32
2890   %inc = add nsw i32 %i, 1
2891   %cmp = icmp sge i32 %conv, %inc
2892   ret i1 %cmp
2895 define i1 @cmp_slt_rhs_inc(float %x, i32 %i) {
2896 ; CHECK-LABEL: @cmp_slt_rhs_inc(
2897 ; CHECK-NEXT:    [[CONV:%.*]] = fptosi float [[X:%.*]] to i32
2898 ; CHECK-NEXT:    [[CMP:%.*]] = icmp sle i32 [[CONV]], [[I:%.*]]
2899 ; CHECK-NEXT:    ret i1 [[CMP]]
2901   %conv = fptosi float %x to i32
2902   %inc = add nsw i32 %i, 1
2903   %cmp = icmp slt i32 %conv, %inc
2904   ret i1 %cmp
2907 define i1 @PR26407(i32 %x, i32 %y) {
2908 ; CHECK-LABEL: @PR26407(
2909 ; CHECK-NEXT:    [[ADDX:%.*]] = add i32 [[X:%.*]], 2147483647
2910 ; CHECK-NEXT:    [[ADDY:%.*]] = add i32 [[Y:%.*]], 2147483647
2911 ; CHECK-NEXT:    [[CMP:%.*]] = icmp uge i32 [[ADDX]], [[ADDY]]
2912 ; CHECK-NEXT:    ret i1 [[CMP]]
2914   %addx = add i32 %x, 2147483647
2915   %addy = add i32 %y, 2147483647
2916   %cmp = icmp uge i32 %addx, %addy
2917   ret i1 %cmp
2920 define i1 @cmp_inverse_mask_bits_set_eq(i32 %x) {
2921 ; CHECK-LABEL: @cmp_inverse_mask_bits_set_eq(
2922 ; CHECK-NEXT:    [[TMP1:%.*]] = and i32 [[X:%.*]], -43
2923 ; CHECK-NEXT:    [[CMP:%.*]] = icmp eq i32 [[TMP1]], -43
2924 ; CHECK-NEXT:    ret i1 [[CMP]]
2926   %or = or i32 %x, 42
2927   %cmp = icmp eq i32 %or, -1
2928   ret i1 %cmp
2931 define <2 x i1> @cmp_inverse_mask_bits_set_eq_vec(<2 x i32> %x) {
2932 ; CHECK-LABEL: @cmp_inverse_mask_bits_set_eq_vec(
2933 ; CHECK-NEXT:    [[TMP1:%.*]] = and <2 x i32> [[X:%.*]], <i32 -43, i32 -43>
2934 ; CHECK-NEXT:    [[CMP:%.*]] = icmp eq <2 x i32> [[TMP1]], <i32 -43, i32 -43>
2935 ; CHECK-NEXT:    ret <2 x i1> [[CMP]]
2937   %or = or <2 x i32> %x, <i32 42, i32 42>
2938   %cmp = icmp eq <2 x i32> %or, <i32 -1, i32 -1>
2939   ret <2 x i1> %cmp
2942 define i1 @cmp_inverse_mask_bits_set_ne(i32 %x) {
2943 ; CHECK-LABEL: @cmp_inverse_mask_bits_set_ne(
2944 ; CHECK-NEXT:    [[TMP1:%.*]] = and i32 [[X:%.*]], -43
2945 ; CHECK-NEXT:    [[CMP:%.*]] = icmp ne i32 [[TMP1]], -43
2946 ; CHECK-NEXT:    ret i1 [[CMP]]
2948   %or = or i32 %x, 42
2949   %cmp = icmp ne i32 %or, -1
2950   ret i1 %cmp
2953 ; When canonicalizing to 'gt/lt', make sure the constant is correct.
2955 define i1 @PR27792(i128 %a) {
2956 ; CHECK-LABEL: @PR27792(
2957 ; CHECK-NEXT:    [[CMP:%.*]] = icmp sgt i128 [[A:%.*]], -1
2958 ; CHECK-NEXT:    ret i1 [[CMP]]
2960   %cmp = icmp sge i128 %a, 0
2961   ret i1 %cmp
2964 define i1 @PR27792_2(i128 %a) {
2965 ; CHECK-LABEL: @PR27792_2(
2966 ; CHECK-NEXT:    [[B:%.*]] = icmp ne i128 [[A:%.*]], 0
2967 ; CHECK-NEXT:    ret i1 [[B]]
2969   %b = icmp uge i128 %a, 1
2970   ret i1 %b
2973 define i1 @ugtMaxSignedVal(i8 %a) {
2974 ; CHECK-LABEL: @ugtMaxSignedVal(
2975 ; CHECK-NEXT:    [[CMP:%.*]] = icmp slt i8 [[A:%.*]], 0
2976 ; CHECK-NEXT:    ret i1 [[CMP]]
2978   %cmp = icmp ugt i8 %a, 127
2979   ret i1 %cmp
2982 define <2 x i1> @ugtMaxSignedValVec(<2 x i8> %a) {
2983 ; CHECK-LABEL: @ugtMaxSignedValVec(
2984 ; CHECK-NEXT:    [[CMP:%.*]] = icmp slt <2 x i8> [[A:%.*]], zeroinitializer
2985 ; CHECK-NEXT:    ret <2 x i1> [[CMP]]
2987   %cmp = icmp ugt <2 x i8> %a, <i8 127, i8 127>
2988   ret <2 x i1> %cmp
2991 define i1 @ugtKnownBits(i8 %a) {
2992 ; CHECK-LABEL: @ugtKnownBits(
2993 ; CHECK-NEXT:    [[B:%.*]] = and i8 [[A:%.*]], 17
2994 ; CHECK-NEXT:    [[CMP:%.*]] = icmp eq i8 [[B]], 17
2995 ; CHECK-NEXT:    ret i1 [[CMP]]
2997   %b = and i8 %a, 17
2998   %cmp = icmp ugt i8 %b, 16
2999   ret i1 %cmp
3002 define <2 x i1> @ugtKnownBitsVec(<2 x i8> %a) {
3003 ; CHECK-LABEL: @ugtKnownBitsVec(
3004 ; CHECK-NEXT:    [[B:%.*]] = and <2 x i8> [[A:%.*]], <i8 17, i8 17>
3005 ; CHECK-NEXT:    [[CMP:%.*]] = icmp eq <2 x i8> [[B]], <i8 17, i8 17>
3006 ; CHECK-NEXT:    ret <2 x i1> [[CMP]]
3008   %b = and <2 x i8> %a, <i8 17, i8 17>
3009   %cmp = icmp ugt <2 x i8> %b, <i8 16, i8 16>
3010   ret <2 x i1> %cmp
3013 define i1 @or_ptrtoint_mismatch(i8* %p, i32* %q) {
3014 ; CHECK-LABEL: @or_ptrtoint_mismatch(
3015 ; CHECK-NEXT:    [[TMP1:%.*]] = icmp eq i8* [[P:%.*]], null
3016 ; CHECK-NEXT:    [[TMP2:%.*]] = icmp eq i32* [[Q:%.*]], null
3017 ; CHECK-NEXT:    [[B:%.*]] = and i1 [[TMP1]], [[TMP2]]
3018 ; CHECK-NEXT:    ret i1 [[B]]
3021   %pp = ptrtoint i8* %p to i64
3022   %qq = ptrtoint i32* %q to i64
3023   %o = or i64 %pp, %qq
3024   %b = icmp eq i64 %o, 0
3025   ret i1 %b
3028 define i1 @icmp_add1_ugt(i32 %x, i32 %y) {
3029 ; CHECK-LABEL: @icmp_add1_ugt(
3030 ; CHECK-NEXT:    [[CMP:%.*]] = icmp uge i32 [[X:%.*]], [[Y:%.*]]
3031 ; CHECK-NEXT:    ret i1 [[CMP]]
3033   %add = add nuw i32 %x, 1
3034   %cmp = icmp ugt i32 %add, %y
3035   ret i1 %cmp
3038 define i1 @icmp_add1_ule(i32 %x, i32 %y) {
3039 ; CHECK-LABEL: @icmp_add1_ule(
3040 ; CHECK-NEXT:    [[CMP:%.*]] = icmp ult i32 [[X:%.*]], [[Y:%.*]]
3041 ; CHECK-NEXT:    ret i1 [[CMP]]
3043   %add = add nuw i32 %x, 1
3044   %cmp = icmp ule i32 %add, %y
3045   ret i1 %cmp
3048 define i1 @cmp_uge_rhs_inc(float %x, i32 %i) {
3049 ; CHECK-LABEL: @cmp_uge_rhs_inc(
3050 ; CHECK-NEXT:    [[CONV:%.*]] = fptosi float [[X:%.*]] to i32
3051 ; CHECK-NEXT:    [[CMP:%.*]] = icmp ugt i32 [[CONV]], [[I:%.*]]
3052 ; CHECK-NEXT:    ret i1 [[CMP]]
3054   %conv = fptosi float %x to i32
3055   %inc = add nuw i32 %i, 1
3056   %cmp = icmp uge i32 %conv, %inc
3057   ret i1 %cmp
3060 define i1 @cmp_ult_rhs_inc(float %x, i32 %i) {
3061 ; CHECK-LABEL: @cmp_ult_rhs_inc(
3062 ; CHECK-NEXT:    [[CONV:%.*]] = fptosi float [[X:%.*]] to i32
3063 ; CHECK-NEXT:    [[CMP:%.*]] = icmp ule i32 [[CONV]], [[I:%.*]]
3064 ; CHECK-NEXT:    ret i1 [[CMP]]
3066   %conv = fptosi float %x to i32
3067   %inc = add nuw i32 %i, 1
3068   %cmp = icmp ult i32 %conv, %inc
3069   ret i1 %cmp
3072 define i1 @cmp_sge_lhs_inc(i32 %x, i32 %y) {
3073 ; CHECK-LABEL: @cmp_sge_lhs_inc(
3074 ; CHECK-NEXT:    [[INC:%.*]] = add nsw i32 [[X:%.*]], 1
3075 ; CHECK-NEXT:    [[CMP:%.*]] = icmp sge i32 [[INC]], [[Y:%.*]]
3076 ; CHECK-NEXT:    ret i1 [[CMP]]
3078   %inc = add nsw i32 %x, 1
3079   %cmp = icmp sge i32 %inc, %y
3080   ret i1 %cmp
3083 define i1 @cmp_uge_lhs_inc(i32 %x, i32 %y) {
3084 ; CHECK-LABEL: @cmp_uge_lhs_inc(
3085 ; CHECK-NEXT:    [[INC:%.*]] = add nuw i32 [[X:%.*]], 1
3086 ; CHECK-NEXT:    [[CMP:%.*]] = icmp uge i32 [[INC]], [[Y:%.*]]
3087 ; CHECK-NEXT:    ret i1 [[CMP]]
3089   %inc = add nuw i32 %x, 1
3090   %cmp = icmp uge i32 %inc, %y
3091   ret i1 %cmp
3094 define i1 @cmp_sgt_lhs_dec(i32 %x, i32 %y) {
3095 ; CHECK-LABEL: @cmp_sgt_lhs_dec(
3096 ; CHECK-NEXT:    [[DEC:%.*]] = add nsw i32 [[X:%.*]], -1
3097 ; CHECK-NEXT:    [[CMP:%.*]] = icmp sgt i32 [[DEC]], [[Y:%.*]]
3098 ; CHECK-NEXT:    ret i1 [[CMP]]
3100   %dec = sub nsw i32 %x, 1
3101   %cmp = icmp sgt i32 %dec, %y
3102   ret i1 %cmp
3105 define i1 @cmp_ugt_lhs_dec(i32 %x, i32 %y) {
3106 ; CHECK-LABEL: @cmp_ugt_lhs_dec(
3107 ; CHECK-NEXT:    [[DEC:%.*]] = add i32 [[X:%.*]], -1
3108 ; CHECK-NEXT:    [[CMP:%.*]] = icmp ugt i32 [[DEC]], [[Y:%.*]]
3109 ; CHECK-NEXT:    ret i1 [[CMP]]
3111   %dec = sub nuw i32 %x, 1
3112   %cmp = icmp ugt i32 %dec, %y
3113   ret i1 %cmp
3116 define i1 @cmp_sle_rhs_inc(float %x, i32 %y) {
3117 ; CHECK-LABEL: @cmp_sle_rhs_inc(
3118 ; CHECK-NEXT:    [[CONV:%.*]] = fptosi float [[X:%.*]] to i32
3119 ; CHECK-NEXT:    [[INC:%.*]] = add nsw i32 [[Y:%.*]], 1
3120 ; CHECK-NEXT:    [[CMP:%.*]] = icmp sge i32 [[INC]], [[CONV]]
3121 ; CHECK-NEXT:    ret i1 [[CMP]]
3123   %conv = fptosi float %x to i32
3124   %inc = add nsw i32 %y, 1
3125   %cmp = icmp sle i32 %conv, %inc
3126   ret i1 %cmp
3129 define i1 @cmp_ule_rhs_inc(float %x, i32 %y) {
3130 ; CHECK-LABEL: @cmp_ule_rhs_inc(
3131 ; CHECK-NEXT:    [[CONV:%.*]] = fptosi float [[X:%.*]] to i32
3132 ; CHECK-NEXT:    [[INC:%.*]] = add nuw i32 [[Y:%.*]], 1
3133 ; CHECK-NEXT:    [[CMP:%.*]] = icmp uge i32 [[INC]], [[CONV]]
3134 ; CHECK-NEXT:    ret i1 [[CMP]]
3136   %conv = fptosi float %x to i32
3137   %inc = add nuw i32 %y, 1
3138   %cmp = icmp ule i32 %conv, %inc
3139   ret i1 %cmp
3142 define i1 @cmp_slt_rhs_dec(float %x, i32 %y) {
3143 ; CHECK-LABEL: @cmp_slt_rhs_dec(
3144 ; CHECK-NEXT:    [[CONV:%.*]] = fptosi float [[X:%.*]] to i32
3145 ; CHECK-NEXT:    [[DEC:%.*]] = add nsw i32 [[Y:%.*]], -1
3146 ; CHECK-NEXT:    [[CMP:%.*]] = icmp sgt i32 [[DEC]], [[CONV]]
3147 ; CHECK-NEXT:    ret i1 [[CMP]]
3149   %conv = fptosi float %x to i32
3150   %dec = sub nsw i32 %y, 1
3151   %cmp = icmp slt i32 %conv, %dec
3152   ret i1 %cmp
3155 define i1 @cmp_ult_rhs_dec(float %x, i32 %y) {
3156 ; CHECK-LABEL: @cmp_ult_rhs_dec(
3157 ; CHECK-NEXT:    [[CONV:%.*]] = fptosi float [[X:%.*]] to i32
3158 ; CHECK-NEXT:    [[DEC:%.*]] = add i32 [[Y:%.*]], -1
3159 ; CHECK-NEXT:    [[CMP:%.*]] = icmp ugt i32 [[DEC]], [[CONV]]
3160 ; CHECK-NEXT:    ret i1 [[CMP]]
3162   %conv = fptosi float %x to i32
3163   %dec = sub nuw i32 %y, 1
3164   %cmp = icmp ult i32 %conv, %dec
3165   ret i1 %cmp
3168 define i1 @eq_add_constants(i32 %x, i32 %y) {
3169 ; CHECK-LABEL: @eq_add_constants(
3170 ; CHECK-NEXT:    [[C:%.*]] = icmp eq i32 [[X:%.*]], [[Y:%.*]]
3171 ; CHECK-NEXT:    ret i1 [[C]]
3173   %A = add i32 %x, 5
3174   %B = add i32 %y, 5
3175   %C = icmp eq i32 %A, %B
3176   ret i1 %C
3179 define i1 @eq_mul_constants(i32 %x, i32 %y) {
3180 ; CHECK-LABEL: @eq_mul_constants(
3181 ; CHECK-NEXT:    [[C:%.*]] = icmp eq i32 [[X:%.*]], [[Y:%.*]]
3182 ; CHECK-NEXT:    ret i1 [[C]]
3184   %A = mul i32 %x, 5
3185   %B = mul i32 %y, 5
3186   %C = icmp eq i32 %A, %B
3187   ret i1 %C
3190 define <2 x i1> @eq_mul_constants_splat(<2 x i32> %x, <2 x i32> %y) {
3191 ; CHECK-LABEL: @eq_mul_constants_splat(
3192 ; CHECK-NEXT:    [[C:%.*]] = icmp ne <2 x i32> [[X:%.*]], [[Y:%.*]]
3193 ; CHECK-NEXT:    ret <2 x i1> [[C]]
3195   %A = mul <2 x i32> %x, <i32 5, i32 5>
3196   %B = mul <2 x i32> %y, <i32 5, i32 5>
3197   %C = icmp ne <2 x i32> %A, %B
3198   ret <2 x i1> %C
3201 ; If the multiply constant has any trailing zero bits, we get something completely different.
3202 ; We mask off the high bits of each input and then convert:
3203 ; (X&Z) == (Y&Z) -> (X^Y) & Z == 0
3205 define i1 @eq_mul_constants_with_tz(i32 %x, i32 %y) {
3206 ; CHECK-LABEL: @eq_mul_constants_with_tz(
3207 ; CHECK-NEXT:    [[TMP1:%.*]] = xor i32 [[X:%.*]], [[Y:%.*]]
3208 ; CHECK-NEXT:    [[TMP2:%.*]] = and i32 [[TMP1]], 1073741823
3209 ; CHECK-NEXT:    [[C:%.*]] = icmp ne i32 [[TMP2]], 0
3210 ; CHECK-NEXT:    ret i1 [[C]]
3212   %A = mul i32 %x, 12
3213   %B = mul i32 %y, 12
3214   %C = icmp ne i32 %A, %B
3215   ret i1 %C
3218 define <2 x i1> @eq_mul_constants_with_tz_splat(<2 x i32> %x, <2 x i32> %y) {
3219 ; CHECK-LABEL: @eq_mul_constants_with_tz_splat(
3220 ; CHECK-NEXT:    [[TMP1:%.*]] = xor <2 x i32> [[X:%.*]], [[Y:%.*]]
3221 ; CHECK-NEXT:    [[TMP2:%.*]] = and <2 x i32> [[TMP1]], <i32 1073741823, i32 1073741823>
3222 ; CHECK-NEXT:    [[C:%.*]] = icmp eq <2 x i32> [[TMP2]], zeroinitializer
3223 ; CHECK-NEXT:    ret <2 x i1> [[C]]
3225   %A = mul <2 x i32> %x, <i32 12, i32 12>
3226   %B = mul <2 x i32> %y, <i32 12, i32 12>
3227   %C = icmp eq <2 x i32> %A, %B
3228   ret <2 x i1> %C
3231 declare i32 @llvm.bswap.i32(i32)
3233 define i1 @bswap_ne(i32 %x, i32 %y) {
3234 ; CHECK-LABEL: @bswap_ne(
3235 ; CHECK-NEXT:    [[CMP:%.*]] = icmp ne i32 [[X:%.*]], [[Y:%.*]]
3236 ; CHECK-NEXT:    ret i1 [[CMP]]
3238   %swapx = call i32 @llvm.bswap.i32(i32 %x)
3239   %swapy = call i32 @llvm.bswap.i32(i32 %y)
3240   %cmp = icmp ne i32 %swapx, %swapy
3241   ret i1 %cmp
3244 declare <8 x i16> @llvm.bswap.v8i16(<8 x i16>)
3246 define <8 x i1> @bswap_vec_eq(<8 x i16> %x, <8 x i16> %y) {
3247 ; CHECK-LABEL: @bswap_vec_eq(
3248 ; CHECK-NEXT:    [[CMP:%.*]] = icmp eq <8 x i16> [[X:%.*]], [[Y:%.*]]
3249 ; CHECK-NEXT:    ret <8 x i1> [[CMP]]
3251   %swapx = call <8 x i16> @llvm.bswap.v8i16(<8 x i16> %x)
3252   %swapy = call <8 x i16> @llvm.bswap.v8i16(<8 x i16> %y)
3253   %cmp = icmp eq <8 x i16> %swapx, %swapy
3254   ret <8 x i1> %cmp
3257 declare i64 @llvm.bitreverse.i64(i64)
3259 define i1 @bitreverse_eq(i64 %x, i64 %y) {
3260 ; CHECK-LABEL: @bitreverse_eq(
3261 ; CHECK-NEXT:    [[CMP:%.*]] = icmp eq i64 [[X:%.*]], [[Y:%.*]]
3262 ; CHECK-NEXT:    ret i1 [[CMP]]
3264   %revx = call i64 @llvm.bitreverse.i64(i64 %x)
3265   %revy = call i64 @llvm.bitreverse.i64(i64 %y)
3266   %cmp = icmp eq i64 %revx, %revy
3267   ret i1 %cmp
3270 declare <8 x i16> @llvm.bitreverse.v8i16(<8 x i16>)
3272 define <8 x i1> @bitreverse_vec_ne(<8 x i16> %x, <8 x i16> %y) {
3273 ; CHECK-LABEL: @bitreverse_vec_ne(
3274 ; CHECK-NEXT:    [[CMP:%.*]] = icmp ne <8 x i16> [[X:%.*]], [[Y:%.*]]
3275 ; CHECK-NEXT:    ret <8 x i1> [[CMP]]
3277   %revx = call <8 x i16> @llvm.bitreverse.v8i16(<8 x i16> %x)
3278   %revy = call <8 x i16> @llvm.bitreverse.v8i16(<8 x i16> %y)
3279   %cmp = icmp ne <8 x i16> %revx, %revy
3280   ret <8 x i1> %cmp
3283 ; These perform a comparison of a value known to be between 4 and 5 with a value between 5 and 7.
3284 ; They should all simplify to equality compares.
3285 define i1 @knownbits1(i8 %a, i8 %b) {
3286 ; CHECK-LABEL: @knownbits1(
3287 ; CHECK-NEXT:    [[A1:%.*]] = and i8 [[A:%.*]], 1
3288 ; CHECK-NEXT:    [[A2:%.*]] = or i8 [[A1]], 4
3289 ; CHECK-NEXT:    [[B1:%.*]] = and i8 [[B:%.*]], 2
3290 ; CHECK-NEXT:    [[B2:%.*]] = or i8 [[B1]], 5
3291 ; CHECK-NEXT:    [[C:%.*]] = icmp eq i8 [[A2]], [[B2]]
3292 ; CHECK-NEXT:    ret i1 [[C]]
3294   %a1 = and i8 %a, 5
3295   %a2 = or i8 %a1, 4
3296   %b1 = and i8 %b, 7
3297   %b2 = or i8 %b1, 5
3298   %c = icmp uge i8 %a2, %b2
3299   ret i1 %c
3302 define i1 @knownbits2(i8 %a, i8 %b) {
3303 ; CHECK-LABEL: @knownbits2(
3304 ; CHECK-NEXT:    [[A1:%.*]] = and i8 [[A:%.*]], 1
3305 ; CHECK-NEXT:    [[A2:%.*]] = or i8 [[A1]], 4
3306 ; CHECK-NEXT:    [[B1:%.*]] = and i8 [[B:%.*]], 2
3307 ; CHECK-NEXT:    [[B2:%.*]] = or i8 [[B1]], 5
3308 ; CHECK-NEXT:    [[C:%.*]] = icmp ne i8 [[A2]], [[B2]]
3309 ; CHECK-NEXT:    ret i1 [[C]]
3311   %a1 = and i8 %a, 5
3312   %a2 = or i8 %a1, 4
3313   %b1 = and i8 %b, 7
3314   %b2 = or i8 %b1, 5
3315   %c = icmp ult i8 %a2, %b2
3316   ret i1 %c
3319 define i1 @knownbits3(i8 %a, i8 %b) {
3320 ; CHECK-LABEL: @knownbits3(
3321 ; CHECK-NEXT:    [[A1:%.*]] = and i8 [[A:%.*]], 1
3322 ; CHECK-NEXT:    [[A2:%.*]] = or i8 [[A1]], 4
3323 ; CHECK-NEXT:    [[B1:%.*]] = and i8 [[B:%.*]], 2
3324 ; CHECK-NEXT:    [[B2:%.*]] = or i8 [[B1]], 5
3325 ; CHECK-NEXT:    [[C:%.*]] = icmp eq i8 [[B2]], [[A2]]
3326 ; CHECK-NEXT:    ret i1 [[C]]
3328   %a1 = and i8 %a, 5
3329   %a2 = or i8 %a1, 4
3330   %b1 = and i8 %b, 7
3331   %b2 = or i8 %b1, 5
3332   %c = icmp ule i8 %b2, %a2
3333   ret i1 %c
3336 define <2 x i1> @knownbits4(<2 x i8> %a, <2 x i8> %b) {
3337 ; CHECK-LABEL: @knownbits4(
3338 ; CHECK-NEXT:    [[A1:%.*]] = and <2 x i8> [[A:%.*]], <i8 1, i8 1>
3339 ; CHECK-NEXT:    [[A2:%.*]] = or <2 x i8> [[A1]], <i8 4, i8 4>
3340 ; CHECK-NEXT:    [[B1:%.*]] = and <2 x i8> [[B:%.*]], <i8 2, i8 2>
3341 ; CHECK-NEXT:    [[B2:%.*]] = or <2 x i8> [[B1]], <i8 5, i8 5>
3342 ; CHECK-NEXT:    [[C:%.*]] = icmp ne <2 x i8> [[B2]], [[A2]]
3343 ; CHECK-NEXT:    ret <2 x i1> [[C]]
3345   %a1 = and <2 x i8> %a, <i8 5, i8 5>
3346   %a2 = or <2 x i8> %a1, <i8 4, i8 4>
3347   %b1 = and <2 x i8> %b, <i8 7, i8 7>
3348   %b2 = or <2 x i8> %b1, <i8 5, i8 5>
3349   %c = icmp ugt <2 x i8> %b2, %a2
3350   ret <2 x i1> %c
3353 ; These are the signed versions of the above. One value is less than or equal to 5, but maybe negative.
3354 ; The other is known to be a value 5-7. These should simplify to equality comparisons.
3355 define i1 @knownbits5(i8 %a, i8 %b) {
3356 ; CHECK-LABEL: @knownbits5(
3357 ; CHECK-NEXT:    [[A1:%.*]] = and i8 [[A:%.*]], -127
3358 ; CHECK-NEXT:    [[A2:%.*]] = or i8 [[A1]], 4
3359 ; CHECK-NEXT:    [[B1:%.*]] = and i8 [[B:%.*]], 2
3360 ; CHECK-NEXT:    [[B2:%.*]] = or i8 [[B1]], 5
3361 ; CHECK-NEXT:    [[C:%.*]] = icmp eq i8 [[A2]], [[B2]]
3362 ; CHECK-NEXT:    ret i1 [[C]]
3364   %a1 = and i8 %a, 133
3365   %a2 = or i8 %a1, 4
3366   %b1 = and i8 %b, 7
3367   %b2 = or i8 %b1, 5
3368   %c = icmp sge i8 %a2, %b2
3369   ret i1 %c
3372 define i1 @knownbits6(i8 %a, i8 %b) {
3373 ; CHECK-LABEL: @knownbits6(
3374 ; CHECK-NEXT:    [[A1:%.*]] = and i8 [[A:%.*]], -127
3375 ; CHECK-NEXT:    [[A2:%.*]] = or i8 [[A1]], 4
3376 ; CHECK-NEXT:    [[B1:%.*]] = and i8 [[B:%.*]], 2
3377 ; CHECK-NEXT:    [[B2:%.*]] = or i8 [[B1]], 5
3378 ; CHECK-NEXT:    [[C:%.*]] = icmp ne i8 [[A2]], [[B2]]
3379 ; CHECK-NEXT:    ret i1 [[C]]
3381   %a1 = and i8 %a, 133
3382   %a2 = or i8 %a1, 4
3383   %b1 = and i8 %b, 7
3384   %b2 = or i8 %b1, 5
3385   %c = icmp slt i8 %a2, %b2
3386   ret i1 %c
3389 define <2 x i1> @knownbits7(<2 x i8> %a, <2 x i8> %b) {
3390 ; CHECK-LABEL: @knownbits7(
3391 ; CHECK-NEXT:    [[A1:%.*]] = and <2 x i8> [[A:%.*]], <i8 -127, i8 -127>
3392 ; CHECK-NEXT:    [[A2:%.*]] = or <2 x i8> [[A1]], <i8 4, i8 4>
3393 ; CHECK-NEXT:    [[B1:%.*]] = and <2 x i8> [[B:%.*]], <i8 2, i8 2>
3394 ; CHECK-NEXT:    [[B2:%.*]] = or <2 x i8> [[B1]], <i8 5, i8 5>
3395 ; CHECK-NEXT:    [[C:%.*]] = icmp eq <2 x i8> [[B2]], [[A2]]
3396 ; CHECK-NEXT:    ret <2 x i1> [[C]]
3398   %a1 = and <2 x i8> %a, <i8 133, i8 133>
3399   %a2 = or <2 x i8> %a1, <i8 4, i8 4>
3400   %b1 = and <2 x i8> %b, <i8 7, i8 7>
3401   %b2 = or <2 x i8> %b1, <i8 5, i8 5>
3402   %c = icmp sle <2 x i8> %b2, %a2
3403   ret <2 x i1> %c
3406 define i1 @knownbits8(i8 %a, i8 %b) {
3407 ; CHECK-LABEL: @knownbits8(
3408 ; CHECK-NEXT:    [[A1:%.*]] = and i8 [[A:%.*]], -127
3409 ; CHECK-NEXT:    [[A2:%.*]] = or i8 [[A1]], 4
3410 ; CHECK-NEXT:    [[B1:%.*]] = and i8 [[B:%.*]], 2
3411 ; CHECK-NEXT:    [[B2:%.*]] = or i8 [[B1]], 5
3412 ; CHECK-NEXT:    [[C:%.*]] = icmp ne i8 [[B2]], [[A2]]
3413 ; CHECK-NEXT:    ret i1 [[C]]
3415   %a1 = and i8 %a, 133
3416   %a2 = or i8 %a1, 4
3417   %b1 = and i8 %b, 7
3418   %b2 = or i8 %b1, 5
3419   %c = icmp sgt i8 %b2, %a2
3420   ret i1 %c
3423 ; Make sure InstCombine doesn't try too hard to simplify the icmp and break the abs idiom
3424 define i32 @abs_preserve(i32 %x) {
3425 ; CHECK-LABEL: @abs_preserve(
3426 ; CHECK-NEXT:    [[A:%.*]] = shl nsw i32 [[X:%.*]], 1
3427 ; CHECK-NEXT:    [[C:%.*]] = icmp slt i32 [[A]], 0
3428 ; CHECK-NEXT:    [[NEGA:%.*]] = sub i32 0, [[A]]
3429 ; CHECK-NEXT:    [[ABS:%.*]] = select i1 [[C]], i32 [[NEGA]], i32 [[A]]
3430 ; CHECK-NEXT:    ret i32 [[ABS]]
3432   %a = mul nsw i32 %x, 2
3433   %c = icmp sge i32 %a, 0
3434   %nega = sub i32 0, %a
3435   %abs = select i1 %c, i32 %a, i32 %nega
3436   ret i32 %abs
3439 ; Don't crash by assuming the compared values are integers.
3441 declare void @llvm.assume(i1)
3442 define i1 @PR35794(i32* %a) {
3443 ; CHECK-LABEL: @PR35794(
3444 ; CHECK-NEXT:    [[MASKCOND:%.*]] = icmp eq i32* [[A:%.*]], null
3445 ; CHECK-NEXT:    tail call void @llvm.assume(i1 [[MASKCOND]])
3446 ; CHECK-NEXT:    ret i1 true
3448   %cmp = icmp sgt i32* %a, inttoptr (i64 -1 to i32*)
3449   %maskcond = icmp eq i32* %a, null
3450   tail call void @llvm.assume(i1 %maskcond)
3451   ret i1 %cmp
3454 ; Don't crash by assuming the compared values are integers.
3455 define <2 x i1> @PR36583(<2 x i8*>)  {
3456 ; CHECK-LABEL: @PR36583(
3457 ; CHECK-NEXT:    [[RES:%.*]] = icmp eq <2 x i8*> [[TMP0:%.*]], zeroinitializer
3458 ; CHECK-NEXT:    ret <2 x i1> [[RES]]
3460   %cast = ptrtoint <2 x i8*> %0 to <2 x i64>
3461   %res = icmp eq <2 x i64> %cast, zeroinitializer
3462   ret <2 x i1> %res
3465 ; fold (icmp pred (sub (0, X)) C1) for vec type
3466 define <2 x i32> @Op1Negated_Vec(<2 x i32> %x) {
3467 ; CHECK-LABEL: @Op1Negated_Vec(
3468 ; CHECK-NEXT:    [[SUB:%.*]] = sub nsw <2 x i32> zeroinitializer, [[X:%.*]]
3469 ; CHECK-NEXT:    [[CMP:%.*]] = icmp slt <2 x i32> [[X]], zeroinitializer
3470 ; CHECK-NEXT:    [[COND:%.*]] = select <2 x i1> [[CMP]], <2 x i32> [[SUB]], <2 x i32> [[X]]
3471 ; CHECK-NEXT:    ret <2 x i32> [[COND]]
3473   %sub = sub nsw <2 x i32> zeroinitializer, %x
3474   %cmp = icmp sgt <2 x i32> %sub, <i32 -1, i32 -1>
3475   %cond = select <2 x i1> %cmp, <2 x i32> %sub, <2 x i32> %x
3476   ret <2 x i32> %cond