[InstCombine] Signed saturation patterns
[llvm-core.git] / test / Transforms / InstCombine / icmp.ll
blob4ee2d4ec1546d45e6ecd73b30f53a817bcec30b8
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 ; Note: offs can be negative, LLVM used to make an incorrect assumption that
512 ; unsigned overflow does not happen during offset computation
513 define i1 @test24_neg_offs(i32* %p, i64 %offs) {
514 ; CHECK-LABEL: @test24_neg_offs(
515 ; CHECK-NEXT:    [[CMP:%.*]] = icmp eq i64 [[OFFS:%.*]], -2
516 ; CHECK-NEXT:    ret i1 [[CMP]]
518   %p1 = getelementptr inbounds i32, i32* %p, i64 %offs
519   %conv1 = ptrtoint i32* %p to i64
520   %conv2 = ptrtoint i32* %p1 to i64
521   %delta = sub i64 %conv1, %conv2
522   %cmp = icmp eq i64 %delta, 8
523   ret i1 %cmp
526 @X_as1 = addrspace(1) global [1000 x i32] zeroinitializer
528 define i1 @test24_as1(i64 %i) {
529 ; CHECK-LABEL: @test24_as1(
530 ; CHECK-NEXT:    [[TMP1:%.*]] = trunc i64 [[I:%.*]] to i16
531 ; CHECK-NEXT:    [[CMP:%.*]] = icmp eq i16 [[TMP1]], 1000
532 ; CHECK-NEXT:    ret i1 [[CMP]]
534   %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
535   %cmp = icmp eq i32 addrspace(1)* %p1, getelementptr inbounds ([1000 x i32], [1000 x i32] addrspace(1)* @X_as1, i64 1, i64 0)
536   ret i1 %cmp
539 ; X - Z > Y - Z -> X > Y if there is no overflow.
540 define i1 @test27(i32 %x, i32 %y, i32 %z) {
541 ; CHECK-LABEL: @test27(
542 ; CHECK-NEXT:    [[C:%.*]] = icmp sgt i32 [[X:%.*]], [[Y:%.*]]
543 ; CHECK-NEXT:    ret i1 [[C]]
545   %lhs = sub nsw i32 %x, %z
546   %rhs = sub nsw i32 %y, %z
547   %c = icmp sgt i32 %lhs, %rhs
548   ret i1 %c
551 define i1 @test27_extra_uses(i32 %x, i32 %y, i32 %z) {
552 ; CHECK-LABEL: @test27_extra_uses(
553 ; CHECK-NEXT:    [[LHS:%.*]] = sub nsw i32 [[X:%.*]], [[Z:%.*]]
554 ; CHECK-NEXT:    call void @foo(i32 [[LHS]])
555 ; CHECK-NEXT:    [[RHS:%.*]] = sub nsw i32 [[Y:%.*]], [[Z]]
556 ; CHECK-NEXT:    call void @foo(i32 [[RHS]])
557 ; CHECK-NEXT:    [[C:%.*]] = icmp sgt i32 [[X]], [[Y]]
558 ; CHECK-NEXT:    ret i1 [[C]]
560   %lhs = sub nsw i32 %x, %z
561   call void @foo(i32 %lhs)
562   %rhs = sub nsw i32 %y, %z
563   call void @foo(i32 %rhs)
564   %c = icmp sgt i32 %lhs, %rhs
565   ret i1 %c
568 ; X - Z > Y - Z -> X > Y if there is no overflow.
569 define i1 @test28(i32 %x, i32 %y, i32 %z) {
570 ; CHECK-LABEL: @test28(
571 ; CHECK-NEXT:    [[C:%.*]] = icmp ugt i32 [[X:%.*]], [[Y:%.*]]
572 ; CHECK-NEXT:    ret i1 [[C]]
574   %lhs = sub nuw i32 %x, %z
575   %rhs = sub nuw i32 %y, %z
576   %c = icmp ugt i32 %lhs, %rhs
577   ret i1 %c
580 define i1 @test28_extra_uses(i32 %x, i32 %y, i32 %z) {
581 ; CHECK-LABEL: @test28_extra_uses(
582 ; CHECK-NEXT:    [[LHS:%.*]] = sub nuw i32 [[X:%.*]], [[Z:%.*]]
583 ; CHECK-NEXT:    call void @foo(i32 [[LHS]])
584 ; CHECK-NEXT:    [[RHS:%.*]] = sub nuw i32 [[Y:%.*]], [[Z]]
585 ; CHECK-NEXT:    call void @foo(i32 [[RHS]])
586 ; CHECK-NEXT:    [[C:%.*]] = icmp ugt i32 [[X]], [[Y]]
587 ; CHECK-NEXT:    ret i1 [[C]]
589   %lhs = sub nuw i32 %x, %z
590   call void @foo(i32 %lhs)
591   %rhs = sub nuw i32 %y, %z
592   call void @foo(i32 %rhs)
593   %c = icmp ugt i32 %lhs, %rhs
594   ret i1 %c
597 ; PR36969 - https://bugs.llvm.org/show_bug.cgi?id=36969
599 define i1 @ugt_sub(i32 %xsrc, i32 %y) {
600 ; CHECK-LABEL: @ugt_sub(
601 ; CHECK-NEXT:    [[X:%.*]] = udiv i32 [[XSRC:%.*]], 42
602 ; CHECK-NEXT:    [[CMP:%.*]] = icmp ult i32 [[X]], [[Y:%.*]]
603 ; CHECK-NEXT:    ret i1 [[CMP]]
605   %x = udiv i32 %xsrc, 42 ; thwart complexity-based canonicalization
606   %sub = sub i32 %x, %y
607   %cmp = icmp ugt i32 %sub, %x
608   ret i1 %cmp
611 ; Swap operands and predicate. Try a vector type to verify that works too.
613 define <2 x i1> @ult_sub(<2 x i8> %xsrc, <2 x i8> %y) {
614 ; CHECK-LABEL: @ult_sub(
615 ; CHECK-NEXT:    [[X:%.*]] = udiv <2 x i8> [[XSRC:%.*]], <i8 42, i8 -42>
616 ; CHECK-NEXT:    [[CMP:%.*]] = icmp ult <2 x i8> [[X]], [[Y:%.*]]
617 ; CHECK-NEXT:    ret <2 x i1> [[CMP]]
619   %x = udiv <2 x i8> %xsrc, <i8 42, i8 -42> ; thwart complexity-based canonicalization
620   %sub = sub <2 x i8> %x, %y
621   %cmp = icmp ult <2 x i8> %x, %sub
622   ret <2 x i1> %cmp
625 ; X - Y > X -> 0 > Y if there is no overflow.
626 define i1 @test33(i32 %x, i32 %y) {
627 ; CHECK-LABEL: @test33(
628 ; CHECK-NEXT:    [[C:%.*]] = icmp slt i32 [[Y:%.*]], 0
629 ; CHECK-NEXT:    ret i1 [[C]]
631   %lhs = sub nsw i32 %x, %y
632   %c = icmp sgt i32 %lhs, %x
633   ret i1 %c
636 ; X - Y > X -> 0 > Y if there is no overflow.
637 define i1 @test34(i32 %x, i32 %y) {
638 ; CHECK-LABEL: @test34(
639 ; CHECK-NEXT:    ret i1 false
641   %lhs = sub nuw i32 %x, %y
642   %c = icmp ugt i32 %lhs, %x
643   ret i1 %c
646 ; X > X - Y -> Y > 0 if there is no overflow.
647 define i1 @test35(i32 %x, i32 %y) {
648 ; CHECK-LABEL: @test35(
649 ; CHECK-NEXT:    [[C:%.*]] = icmp sgt i32 [[Y:%.*]], 0
650 ; CHECK-NEXT:    ret i1 [[C]]
652   %rhs = sub nsw i32 %x, %y
653   %c = icmp sgt i32 %x, %rhs
654   ret i1 %c
657 ; X > X - Y -> Y > 0 if there is no overflow.
658 define i1 @test36(i32 %x, i32 %y) {
659 ; CHECK-LABEL: @test36(
660 ; CHECK-NEXT:    [[C:%.*]] = icmp ne i32 [[Y:%.*]], 0
661 ; CHECK-NEXT:    ret i1 [[C]]
663   %rhs = sub nuw i32 %x, %y
664   %c = icmp ugt i32 %x, %rhs
665   ret i1 %c
668 ; X - Y > X - Z -> Z > Y if there is no overflow.
669 define i1 @test37(i32 %x, i32 %y, i32 %z) {
670 ; CHECK-LABEL: @test37(
671 ; CHECK-NEXT:    [[C:%.*]] = icmp sgt i32 [[Z:%.*]], [[Y:%.*]]
672 ; CHECK-NEXT:    ret i1 [[C]]
674   %lhs = sub nsw i32 %x, %y
675   %rhs = sub nsw i32 %x, %z
676   %c = icmp sgt i32 %lhs, %rhs
677   ret i1 %c
680 define i1 @test37_extra_uses(i32 %x, i32 %y, i32 %z) {
681 ; CHECK-LABEL: @test37_extra_uses(
682 ; CHECK-NEXT:    [[LHS:%.*]] = sub nsw i32 [[X:%.*]], [[Y:%.*]]
683 ; CHECK-NEXT:    call void @foo(i32 [[LHS]])
684 ; CHECK-NEXT:    [[RHS:%.*]] = sub nsw i32 [[X]], [[Z:%.*]]
685 ; CHECK-NEXT:    call void @foo(i32 [[RHS]])
686 ; CHECK-NEXT:    [[C:%.*]] = icmp sgt i32 [[Z]], [[Y]]
687 ; CHECK-NEXT:    ret i1 [[C]]
689   %lhs = sub nsw i32 %x, %y
690   call void @foo(i32 %lhs)
691   %rhs = sub nsw i32 %x, %z
692   call void @foo(i32 %rhs)
693   %c = icmp sgt i32 %lhs, %rhs
694   ret i1 %c
697 ; TODO: Min/max pattern should not prevent the fold.
699 define i32 @neg_max_s32(i32 %x, i32 %y) {
700 ; CHECK-LABEL: @neg_max_s32(
701 ; CHECK-NEXT:    [[C:%.*]] = icmp slt i32 [[Y:%.*]], [[X:%.*]]
702 ; CHECK-NEXT:    [[S_V:%.*]] = select i1 [[C]], i32 [[Y]], i32 [[X]]
703 ; CHECK-NEXT:    ret i32 [[S_V]]
705   %nx = sub nsw i32 0, %x
706   %ny = sub nsw i32 0, %y
707   %c = icmp slt i32 %nx, %ny
708   %s = select i1 %c, i32 %ny, i32 %nx
709   %r = sub nsw i32 0, %s
710   ret i32 %r
713 define <4 x i32> @neg_max_v4s32(<4 x i32> %x, <4 x i32> %y) {
714 ; CHECK-LABEL: @neg_max_v4s32(
715 ; CHECK-NEXT:    [[C:%.*]] = icmp sgt <4 x i32> [[Y:%.*]], [[X:%.*]]
716 ; CHECK-NEXT:    [[S_V:%.*]] = select <4 x i1> [[C]], <4 x i32> [[X]], <4 x i32> [[Y]]
717 ; CHECK-NEXT:    ret <4 x i32> [[S_V]]
719   %nx = sub nsw <4 x i32> zeroinitializer, %x
720   %ny = sub nsw <4 x i32> zeroinitializer, %y
721   %c = icmp sgt <4 x i32> %nx, %ny
722   %s = select <4 x i1> %c, <4 x i32> %nx, <4 x i32> %ny
723   %r = sub <4 x i32> zeroinitializer, %s
724   ret <4 x i32> %r
727 ; X - Y > X - Z -> Z > Y if there is no overflow.
728 define i1 @test38(i32 %x, i32 %y, i32 %z) {
729 ; CHECK-LABEL: @test38(
730 ; CHECK-NEXT:    [[C:%.*]] = icmp ugt i32 [[Z:%.*]], [[Y:%.*]]
731 ; CHECK-NEXT:    ret i1 [[C]]
733   %lhs = sub nuw i32 %x, %y
734   %rhs = sub nuw i32 %x, %z
735   %c = icmp ugt i32 %lhs, %rhs
736   ret i1 %c
739 define i1 @test38_extra_uses(i32 %x, i32 %y, i32 %z) {
740 ; CHECK-LABEL: @test38_extra_uses(
741 ; CHECK-NEXT:    [[LHS:%.*]] = sub nuw i32 [[X:%.*]], [[Y:%.*]]
742 ; CHECK-NEXT:    call void @foo(i32 [[LHS]])
743 ; CHECK-NEXT:    [[RHS:%.*]] = sub nuw i32 [[X]], [[Z:%.*]]
744 ; CHECK-NEXT:    call void @foo(i32 [[RHS]])
745 ; CHECK-NEXT:    [[C:%.*]] = icmp ugt i32 [[Z]], [[Y]]
746 ; CHECK-NEXT:    ret i1 [[C]]
748   %lhs = sub nuw i32 %x, %y
749   call void @foo(i32 %lhs)
750   %rhs = sub nuw i32 %x, %z
751   call void @foo(i32 %rhs)
752   %c = icmp ugt i32 %lhs, %rhs
753   ret i1 %c
756 ; PR9343 #1
757 define i1 @test39(i32 %X, i32 %Y) {
758 ; CHECK-LABEL: @test39(
759 ; CHECK-NEXT:    [[B:%.*]] = icmp eq i32 [[X:%.*]], 0
760 ; CHECK-NEXT:    ret i1 [[B]]
762   %A = ashr exact i32 %X, %Y
763   %B = icmp eq i32 %A, 0
764   ret i1 %B
767 define <2 x i1> @test39vec(<2 x i32> %X, <2 x i32> %Y) {
768 ; CHECK-LABEL: @test39vec(
769 ; CHECK-NEXT:    [[B:%.*]] = icmp eq <2 x i32> [[X:%.*]], zeroinitializer
770 ; CHECK-NEXT:    ret <2 x i1> [[B]]
772   %A = ashr exact <2 x i32> %X, %Y
773   %B = icmp eq <2 x i32> %A, zeroinitializer
774   ret <2 x i1> %B
777 define i1 @test40(i32 %X, i32 %Y) {
778 ; CHECK-LABEL: @test40(
779 ; CHECK-NEXT:    [[B:%.*]] = icmp ne i32 [[X:%.*]], 0
780 ; CHECK-NEXT:    ret i1 [[B]]
782   %A = lshr exact i32 %X, %Y
783   %B = icmp ne i32 %A, 0
784   ret i1 %B
787 define <2 x i1> @test40vec(<2 x i32> %X, <2 x i32> %Y) {
788 ; CHECK-LABEL: @test40vec(
789 ; CHECK-NEXT:    [[B:%.*]] = icmp ne <2 x i32> [[X:%.*]], zeroinitializer
790 ; CHECK-NEXT:    ret <2 x i1> [[B]]
792   %A = lshr exact <2 x i32> %X, %Y
793   %B = icmp ne <2 x i32> %A, zeroinitializer
794   ret <2 x i1> %B
797 define i1 @shr_exact(i132 %x) {
798 ; CHECK-LABEL: @shr_exact(
799 ; CHECK-NEXT:    [[CMP:%.*]] = icmp eq i132 [[X:%.*]], 32
800 ; CHECK-NEXT:    ret i1 [[CMP]]
802   %sh = ashr exact i132 %x, 4
803   %cmp = icmp eq i132 %sh, 2
804   ret i1 %cmp
807 define <2 x i1> @shr_exact_vec(<2 x i132> %x) {
808 ; CHECK-LABEL: @shr_exact_vec(
809 ; CHECK-NEXT:    [[CMP:%.*]] = icmp ne <2 x i132> [[X:%.*]], <i132 32, i132 32>
810 ; CHECK-NEXT:    ret <2 x i1> [[CMP]]
812   %sh = lshr exact <2 x i132> %x, <i132 4, i132 4>
813   %cmp = icmp ne <2 x i132> %sh, <i132 2, i132 2>
814   ret <2 x i1> %cmp
817 ; PR9343 #3
818 define i1 @test41(i32 %X, i32 %Y) {
819 ; CHECK-LABEL: @test41(
820 ; CHECK-NEXT:    ret i1 true
822   %A = urem i32 %X, %Y
823   %B = icmp ugt i32 %Y, %A
824   ret i1 %B
827 define i1 @test42(i32 %X, i32 %Y) {
828 ; CHECK-LABEL: @test42(
829 ; CHECK-NEXT:    [[B:%.*]] = icmp sgt i32 [[Y:%.*]], -1
830 ; CHECK-NEXT:    ret i1 [[B]]
832   %A = srem i32 %X, %Y
833   %B = icmp slt i32 %A, %Y
834   ret i1 %B
837 define i1 @test43(i32 %X, i32 %Y) {
838 ; CHECK-LABEL: @test43(
839 ; CHECK-NEXT:    [[B:%.*]] = icmp slt i32 [[Y:%.*]], 0
840 ; CHECK-NEXT:    ret i1 [[B]]
842   %A = srem i32 %X, %Y
843   %B = icmp slt i32 %Y, %A
844   ret i1 %B
847 define i1 @test44(i32 %X, i32 %Y) {
848 ; CHECK-LABEL: @test44(
849 ; CHECK-NEXT:    [[B:%.*]] = icmp sgt i32 [[Y:%.*]], -1
850 ; CHECK-NEXT:    ret i1 [[B]]
852   %A = srem i32 %X, %Y
853   %B = icmp slt i32 %A, %Y
854   ret i1 %B
857 define i1 @test45(i32 %X, i32 %Y) {
858 ; CHECK-LABEL: @test45(
859 ; CHECK-NEXT:    [[B:%.*]] = icmp slt i32 [[Y:%.*]], 0
860 ; CHECK-NEXT:    ret i1 [[B]]
862   %A = srem i32 %X, %Y
863   %B = icmp slt i32 %Y, %A
864   ret i1 %B
867 ; PR9343 #4
868 define i1 @test46(i32 %X, i32 %Y, i32 %Z) {
869 ; CHECK-LABEL: @test46(
870 ; CHECK-NEXT:    [[C:%.*]] = icmp ult i32 [[X:%.*]], [[Y:%.*]]
871 ; CHECK-NEXT:    ret i1 [[C]]
873   %A = ashr exact i32 %X, %Z
874   %B = ashr exact i32 %Y, %Z
875   %C = icmp ult i32 %A, %B
876   ret i1 %C
879 ; PR9343 #5
880 define i1 @test47(i32 %X, i32 %Y, i32 %Z) {
881 ; CHECK-LABEL: @test47(
882 ; CHECK-NEXT:    [[C:%.*]] = icmp ugt i32 [[X:%.*]], [[Y:%.*]]
883 ; CHECK-NEXT:    ret i1 [[C]]
885   %A = ashr exact i32 %X, %Z
886   %B = ashr exact i32 %Y, %Z
887   %C = icmp ugt i32 %A, %B
888   ret i1 %C
891 ; PR9343 #8
892 define i1 @test48(i32 %X, i32 %Y, i32 %Z) {
893 ; CHECK-LABEL: @test48(
894 ; CHECK-NEXT:    [[C:%.*]] = icmp eq i32 [[X:%.*]], [[Y:%.*]]
895 ; CHECK-NEXT:    ret i1 [[C]]
897   %A = sdiv exact i32 %X, %Z
898   %B = sdiv exact i32 %Y, %Z
899   %C = icmp eq i32 %A, %B
900   ret i1 %C
903 ; The above transform only works for equality predicates.
905 define i1 @PR32949(i32 %X, i32 %Y, i32 %Z) {
906 ; CHECK-LABEL: @PR32949(
907 ; CHECK-NEXT:    [[A:%.*]] = sdiv exact i32 [[X:%.*]], [[Z:%.*]]
908 ; CHECK-NEXT:    [[B:%.*]] = sdiv exact i32 [[Y:%.*]], [[Z]]
909 ; CHECK-NEXT:    [[C:%.*]] = icmp sgt i32 [[A]], [[B]]
910 ; CHECK-NEXT:    ret i1 [[C]]
912   %A = sdiv exact i32 %X, %Z
913   %B = sdiv exact i32 %Y, %Z
914   %C = icmp sgt i32 %A, %B
915   ret i1 %C
918 ; PR8469
919 define <2 x i1> @test49(<2 x i32> %tmp3) {
920 ; CHECK-LABEL: @test49(
921 ; CHECK-NEXT:  entry:
922 ; CHECK-NEXT:    ret <2 x i1> <i1 true, i1 true>
924 entry:
925   %tmp11 = and <2 x i32> %tmp3, <i32 3, i32 3>
926   %cmp = icmp ult <2 x i32> %tmp11, <i32 4, i32 4>
927   ret <2 x i1> %cmp
930 ; PR9343 #7
931 define i1 @test50(i16 %X, i32 %Y) {
932 ; CHECK-LABEL: @test50(
933 ; CHECK-NEXT:    ret i1 true
935   %A = zext i16 %X to i32
936   %B = srem i32 %A, %Y
937   %C = icmp sgt i32 %B, -1
938   ret i1 %C
941 define i1 @test51(i32 %X, i32 %Y) {
942 ; CHECK-LABEL: @test51(
943 ; CHECK-NEXT:    [[A:%.*]] = and i32 [[X:%.*]], -2147483648
944 ; CHECK-NEXT:    [[B:%.*]] = srem i32 [[A]], [[Y:%.*]]
945 ; CHECK-NEXT:    [[C:%.*]] = icmp sgt i32 [[B]], -1
946 ; CHECK-NEXT:    ret i1 [[C]]
948   %A = and i32 %X, 2147483648
949   %B = srem i32 %A, %Y
950   %C = icmp sgt i32 %B, -1
951   ret i1 %C
954 define i1 @test52(i32 %x1) {
955 ; CHECK-LABEL: @test52(
956 ; CHECK-NEXT:    [[TMP1:%.*]] = and i32 [[X1:%.*]], 16711935
957 ; CHECK-NEXT:    [[TMP2:%.*]] = icmp eq i32 [[TMP1]], 4980863
958 ; CHECK-NEXT:    ret i1 [[TMP2]]
960   %conv = and i32 %x1, 255
961   %cmp = icmp eq i32 %conv, 127
962   %tmp2 = lshr i32 %x1, 16
963   %tmp3 = trunc i32 %tmp2 to i8
964   %cmp15 = icmp eq i8 %tmp3, 76
966   %A = and i1 %cmp, %cmp15
967   ret i1 %A
970 define i1 @test52b(i128 %x1) {
971 ; CHECK-LABEL: @test52b(
972 ; CHECK-NEXT:    [[TMP1:%.*]] = and i128 [[X1:%.*]], 16711935
973 ; CHECK-NEXT:    [[TMP2:%.*]] = icmp eq i128 [[TMP1]], 4980863
974 ; CHECK-NEXT:    ret i1 [[TMP2]]
976   %conv = and i128 %x1, 255
977   %cmp = icmp eq i128 %conv, 127
978   %tmp2 = lshr i128 %x1, 16
979   %tmp3 = trunc i128 %tmp2 to i8
980   %cmp15 = icmp eq i8 %tmp3, 76
982   %A = and i1 %cmp, %cmp15
983   ret i1 %A
986 ; PR9838
987 define i1 @test53(i32 %a, i32 %b) {
988 ; CHECK-LABEL: @test53(
989 ; CHECK-NEXT:    [[X:%.*]] = sdiv exact i32 [[A:%.*]], 30
990 ; CHECK-NEXT:    [[Y:%.*]] = sdiv i32 [[B:%.*]], 30
991 ; CHECK-NEXT:    [[Z:%.*]] = icmp eq i32 [[X]], [[Y]]
992 ; CHECK-NEXT:    ret i1 [[Z]]
994   %x = sdiv exact i32 %a, 30
995   %y = sdiv i32 %b, 30
996   %z = icmp eq i32 %x, %y
997   ret i1 %z
1000 define i1 @test54(i8 %a) {
1001 ; CHECK-LABEL: @test54(
1002 ; CHECK-NEXT:    [[TMP1:%.*]] = and i8 [[A:%.*]], -64
1003 ; CHECK-NEXT:    [[RET:%.*]] = icmp eq i8 [[TMP1]], -128
1004 ; CHECK-NEXT:    ret i1 [[RET]]
1006   %ext = zext i8 %a to i32
1007   %and = and i32 %ext, 192
1008   %ret = icmp eq i32 %and, 128
1009   ret i1 %ret
1012 define i1 @test55(i32 %a) {
1013 ; CHECK-LABEL: @test55(
1014 ; CHECK-NEXT:    [[CMP:%.*]] = icmp eq i32 [[A:%.*]], -123
1015 ; CHECK-NEXT:    ret i1 [[CMP]]
1017   %sub = sub i32 0, %a
1018   %cmp = icmp eq i32 %sub, 123
1019   ret i1 %cmp
1022 define <2 x i1> @test55vec(<2 x i32> %a) {
1023 ; CHECK-LABEL: @test55vec(
1024 ; CHECK-NEXT:    [[CMP:%.*]] = icmp eq <2 x i32> [[A:%.*]], <i32 -123, i32 -123>
1025 ; CHECK-NEXT:    ret <2 x i1> [[CMP]]
1027   %sub = sub <2 x i32> zeroinitializer, %a
1028   %cmp = icmp eq <2 x i32> %sub, <i32 123, i32 123>
1029   ret <2 x i1> %cmp
1032 define i1 @test56(i32 %a) {
1033 ; CHECK-LABEL: @test56(
1034 ; CHECK-NEXT:    [[CMP:%.*]] = icmp eq i32 [[A:%.*]], -113
1035 ; CHECK-NEXT:    ret i1 [[CMP]]
1037   %sub = sub i32 10, %a
1038   %cmp = icmp eq i32 %sub, 123
1039   ret i1 %cmp
1042 define <2 x i1> @test56vec(<2 x i32> %a) {
1043 ; CHECK-LABEL: @test56vec(
1044 ; CHECK-NEXT:    [[CMP:%.*]] = icmp eq <2 x i32> [[A:%.*]], <i32 -113, i32 -113>
1045 ; CHECK-NEXT:    ret <2 x i1> [[CMP]]
1047   %sub = sub <2 x i32> <i32 10, i32 10>, %a
1048   %cmp = icmp eq <2 x i32> %sub, <i32 123, i32 123>
1049   ret <2 x i1> %cmp
1052 ; PR10267 Don't make icmps more expensive when no other inst is subsumed.
1053 declare void @foo(i32)
1054 define i1 @test57(i32 %a) {
1055 ; CHECK-LABEL: @test57(
1056 ; CHECK-NEXT:    [[AND:%.*]] = and i32 [[A:%.*]], -2
1057 ; CHECK-NEXT:    [[CMP:%.*]] = icmp ne i32 [[AND]], 0
1058 ; CHECK-NEXT:    call void @foo(i32 [[AND]])
1059 ; CHECK-NEXT:    ret i1 [[CMP]]
1061   %and = and i32 %a, -2
1062   %cmp = icmp ne i32 %and, 0
1063   call void @foo(i32 %and)
1064   ret i1 %cmp
1067 ; rdar://problem/10482509
1068 define zeroext i1 @cmpabs1(i64 %val) {
1069 ; CHECK-LABEL: @cmpabs1(
1070 ; CHECK-NEXT:    [[TOBOOL:%.*]] = icmp ne i64 [[VAL:%.*]], 0
1071 ; CHECK-NEXT:    ret i1 [[TOBOOL]]
1073   %sub = sub nsw i64 0, %val
1074   %cmp = icmp slt i64 %val, 0
1075   %sub.val = select i1 %cmp, i64 %sub, i64 %val
1076   %tobool = icmp ne i64 %sub.val, 0
1077   ret i1 %tobool
1080 define zeroext i1 @cmpabs2(i64 %val) {
1081 ; CHECK-LABEL: @cmpabs2(
1082 ; CHECK-NEXT:    [[TOBOOL:%.*]] = icmp ne i64 [[VAL:%.*]], 0
1083 ; CHECK-NEXT:    ret i1 [[TOBOOL]]
1085   %sub = sub nsw i64 0, %val
1086   %cmp = icmp slt i64 %val, 0
1087   %sub.val = select i1 %cmp, i64 %val, i64 %sub
1088   %tobool = icmp ne i64 %sub.val, 0
1089   ret i1 %tobool
1092 define void @test58() {
1093 ; CHECK-LABEL: @test58(
1094 ; CHECK-NEXT:    [[CALL:%.*]] = call i32 @test58_d(i64 36029346783166592)
1095 ; CHECK-NEXT:    ret void
1097   %cast = bitcast <1 x i64> <i64 36029346783166592> to i64
1098   %call = call i32 @test58_d( i64 %cast)
1099   ret void
1101 declare i32 @test58_d(i64)
1103 define i1 @test59(i8* %foo) {
1104 ; CHECK-LABEL: @test59(
1105 ; CHECK-NEXT:    [[GEP1:%.*]] = getelementptr inbounds i8, i8* [[FOO:%.*]], i64 8
1106 ; CHECK-NEXT:    [[USE:%.*]] = ptrtoint i8* [[GEP1]] to i64
1107 ; CHECK-NEXT:    [[CALL:%.*]] = call i32 @test58_d(i64 [[USE]])
1108 ; CHECK-NEXT:    ret i1 true
1110   %bit = bitcast i8* %foo to i32*
1111   %gep1 = getelementptr inbounds i32, i32* %bit, i64 2
1112   %gep2 = getelementptr inbounds i8, i8* %foo, i64 10
1113   %cast1 = bitcast i32* %gep1 to i8*
1114   %cmp = icmp ult i8* %cast1, %gep2
1115   %use = ptrtoint i8* %cast1 to i64
1116   %call = call i32 @test58_d(i64 %use)
1117   ret i1 %cmp
1120 define i1 @test59_as1(i8 addrspace(1)* %foo) {
1121 ; CHECK-LABEL: @test59_as1(
1122 ; CHECK-NEXT:    [[GEP1:%.*]] = getelementptr inbounds i8, i8 addrspace(1)* [[FOO:%.*]], i16 8
1123 ; CHECK-NEXT:    [[TMP1:%.*]] = ptrtoint i8 addrspace(1)* [[GEP1]] to i16
1124 ; CHECK-NEXT:    [[USE:%.*]] = zext i16 [[TMP1]] to i64
1125 ; CHECK-NEXT:    [[CALL:%.*]] = call i32 @test58_d(i64 [[USE]])
1126 ; CHECK-NEXT:    ret i1 true
1128   %bit = bitcast i8 addrspace(1)* %foo to i32 addrspace(1)*
1129   %gep1 = getelementptr inbounds i32, i32 addrspace(1)* %bit, i64 2
1130   %gep2 = getelementptr inbounds i8, i8 addrspace(1)* %foo, i64 10
1131   %cast1 = bitcast i32 addrspace(1)* %gep1 to i8 addrspace(1)*
1132   %cmp = icmp ult i8 addrspace(1)* %cast1, %gep2
1133   %use = ptrtoint i8 addrspace(1)* %cast1 to i64
1134   %call = call i32 @test58_d(i64 %use)
1135   ret i1 %cmp
1138 define i1 @test60(i8* %foo, i64 %i, i64 %j) {
1139 ; CHECK-LABEL: @test60(
1140 ; CHECK-NEXT:    [[GEP1_IDX:%.*]] = shl nsw i64 [[I:%.*]], 2
1141 ; CHECK-NEXT:    [[TMP1:%.*]] = icmp slt i64 [[GEP1_IDX]], [[J:%.*]]
1142 ; CHECK-NEXT:    ret i1 [[TMP1]]
1144   %bit = bitcast i8* %foo to i32*
1145   %gep1 = getelementptr inbounds i32, i32* %bit, i64 %i
1146   %gep2 = getelementptr inbounds i8, i8* %foo, i64 %j
1147   %cast1 = bitcast i32* %gep1 to i8*
1148   %cmp = icmp ult i8* %cast1, %gep2
1149   ret i1 %cmp
1152 define i1 @test60_as1(i8 addrspace(1)* %foo, i64 %i, i64 %j) {
1153 ; CHECK-LABEL: @test60_as1(
1154 ; CHECK-NEXT:    [[TMP1:%.*]] = trunc i64 [[I:%.*]] to i16
1155 ; CHECK-NEXT:    [[TMP2:%.*]] = trunc i64 [[J:%.*]] to i16
1156 ; CHECK-NEXT:    [[GEP1_IDX:%.*]] = shl nsw i16 [[TMP1]], 2
1157 ; CHECK-NEXT:    [[TMP3:%.*]] = icmp slt i16 [[GEP1_IDX]], [[TMP2]]
1158 ; CHECK-NEXT:    ret i1 [[TMP3]]
1160   %bit = bitcast i8 addrspace(1)* %foo to i32 addrspace(1)*
1161   %gep1 = getelementptr inbounds i32, i32 addrspace(1)* %bit, i64 %i
1162   %gep2 = getelementptr inbounds i8, i8 addrspace(1)* %foo, i64 %j
1163   %cast1 = bitcast i32 addrspace(1)* %gep1 to i8 addrspace(1)*
1164   %cmp = icmp ult i8 addrspace(1)* %cast1, %gep2
1165   ret i1 %cmp
1168 ; Same as test60, but look through an addrspacecast instead of a
1169 ; bitcast. This uses the same sized addrspace.
1170 define i1 @test60_addrspacecast(i8* %foo, i64 %i, i64 %j) {
1171 ; CHECK-LABEL: @test60_addrspacecast(
1172 ; CHECK-NEXT:    [[GEP1_IDX:%.*]] = shl nsw i64 [[I:%.*]], 2
1173 ; CHECK-NEXT:    [[TMP1:%.*]] = icmp slt i64 [[GEP1_IDX]], [[J:%.*]]
1174 ; CHECK-NEXT:    ret i1 [[TMP1]]
1176   %bit = addrspacecast i8* %foo to i32 addrspace(3)*
1177   %gep1 = getelementptr inbounds i32, i32 addrspace(3)* %bit, i64 %i
1178   %gep2 = getelementptr inbounds i8, i8* %foo, i64 %j
1179   %cast1 = addrspacecast i32 addrspace(3)* %gep1 to i8*
1180   %cmp = icmp ult i8* %cast1, %gep2
1181   ret i1 %cmp
1184 define i1 @test60_addrspacecast_smaller(i8* %foo, i16 %i, i64 %j) {
1185 ; CHECK-LABEL: @test60_addrspacecast_smaller(
1186 ; CHECK-NEXT:    [[GEP1_IDX:%.*]] = shl nsw i16 [[I:%.*]], 2
1187 ; CHECK-NEXT:    [[TMP1:%.*]] = trunc i64 [[J:%.*]] to i16
1188 ; CHECK-NEXT:    [[TMP2:%.*]] = icmp slt i16 [[GEP1_IDX]], [[TMP1]]
1189 ; CHECK-NEXT:    ret i1 [[TMP2]]
1191   %bit = addrspacecast i8* %foo to i32 addrspace(1)*
1192   %gep1 = getelementptr inbounds i32, i32 addrspace(1)* %bit, i16 %i
1193   %gep2 = getelementptr inbounds i8, i8* %foo, i64 %j
1194   %cast1 = addrspacecast i32 addrspace(1)* %gep1 to i8*
1195   %cmp = icmp ult i8* %cast1, %gep2
1196   ret i1 %cmp
1199 define i1 @test60_addrspacecast_larger(i8 addrspace(1)* %foo, i32 %i, i16 %j) {
1200 ; CHECK-LABEL: @test60_addrspacecast_larger(
1201 ; CHECK-NEXT:    [[I_TR:%.*]] = trunc i32 [[I:%.*]] to i16
1202 ; CHECK-NEXT:    [[TMP1:%.*]] = shl i16 [[I_TR]], 2
1203 ; CHECK-NEXT:    [[TMP2:%.*]] = icmp slt i16 [[TMP1]], [[J:%.*]]
1204 ; CHECK-NEXT:    ret i1 [[TMP2]]
1206   %bit = addrspacecast i8 addrspace(1)* %foo to i32 addrspace(2)*
1207   %gep1 = getelementptr inbounds i32, i32 addrspace(2)* %bit, i32 %i
1208   %gep2 = getelementptr inbounds i8, i8 addrspace(1)* %foo, i16 %j
1209   %cast1 = addrspacecast i32 addrspace(2)* %gep1 to i8 addrspace(1)*
1210   %cmp = icmp ult i8 addrspace(1)* %cast1, %gep2
1211   ret i1 %cmp
1214 define i1 @test61(i8* %foo, i64 %i, i64 %j) {
1215 ; CHECK-LABEL: @test61(
1216 ; CHECK-NEXT:    [[BIT:%.*]] = bitcast i8* [[FOO:%.*]] to i32*
1217 ; CHECK-NEXT:    [[GEP1:%.*]] = getelementptr i32, i32* [[BIT]], i64 [[I:%.*]]
1218 ; CHECK-NEXT:    [[GEP2:%.*]] = getelementptr i8, i8* [[FOO]], i64 [[J:%.*]]
1219 ; CHECK-NEXT:    [[CAST1:%.*]] = bitcast i32* [[GEP1]] to i8*
1220 ; CHECK-NEXT:    [[CMP:%.*]] = icmp ugt i8* [[GEP2]], [[CAST1]]
1221 ; CHECK-NEXT:    ret i1 [[CMP]]
1223   %bit = bitcast i8* %foo to i32*
1224   %gep1 = getelementptr i32, i32* %bit, i64 %i
1225   %gep2 = getelementptr  i8,  i8* %foo, i64 %j
1226   %cast1 = bitcast i32* %gep1 to i8*
1227   %cmp = icmp ult i8* %cast1, %gep2
1228   ret i1 %cmp
1229 ; Don't transform non-inbounds GEPs.
1232 define i1 @test61_as1(i8 addrspace(1)* %foo, i16 %i, i16 %j) {
1233 ; CHECK-LABEL: @test61_as1(
1234 ; CHECK-NEXT:    [[BIT:%.*]] = bitcast i8 addrspace(1)* [[FOO:%.*]] to i32 addrspace(1)*
1235 ; CHECK-NEXT:    [[GEP1:%.*]] = getelementptr i32, i32 addrspace(1)* [[BIT]], i16 [[I:%.*]]
1236 ; CHECK-NEXT:    [[GEP2:%.*]] = getelementptr i8, i8 addrspace(1)* [[FOO]], i16 [[J:%.*]]
1237 ; CHECK-NEXT:    [[CAST1:%.*]] = bitcast i32 addrspace(1)* [[GEP1]] to i8 addrspace(1)*
1238 ; CHECK-NEXT:    [[CMP:%.*]] = icmp ugt i8 addrspace(1)* [[GEP2]], [[CAST1]]
1239 ; CHECK-NEXT:    ret i1 [[CMP]]
1241   %bit = bitcast i8 addrspace(1)* %foo to i32 addrspace(1)*
1242   %gep1 = getelementptr i32, i32 addrspace(1)* %bit, i16 %i
1243   %gep2 = getelementptr i8, i8 addrspace(1)* %foo, i16 %j
1244   %cast1 = bitcast i32 addrspace(1)* %gep1 to i8 addrspace(1)*
1245   %cmp = icmp ult i8 addrspace(1)* %cast1, %gep2
1246   ret i1 %cmp
1247 ; Don't transform non-inbounds GEPs.
1250 define i1 @test62(i8* %a) {
1251 ; CHECK-LABEL: @test62(
1252 ; CHECK-NEXT:    ret i1 true
1254   %arrayidx1 = getelementptr inbounds i8, i8* %a, i64 1
1255   %arrayidx2 = getelementptr inbounds i8, i8* %a, i64 10
1256   %cmp = icmp slt i8* %arrayidx1, %arrayidx2
1257   ret i1 %cmp
1260 define i1 @test62_as1(i8 addrspace(1)* %a) {
1261 ; CHECK-LABEL: @test62_as1(
1262 ; CHECK-NEXT:    ret i1 true
1264   %arrayidx1 = getelementptr inbounds i8, i8 addrspace(1)* %a, i64 1
1265   %arrayidx2 = getelementptr inbounds i8, i8 addrspace(1)* %a, i64 10
1266   %cmp = icmp slt i8 addrspace(1)* %arrayidx1, %arrayidx2
1267   ret i1 %cmp
1270 define i1 @test63(i8 %a, i32 %b) {
1271 ; CHECK-LABEL: @test63(
1272 ; CHECK-NEXT:    [[TMP1:%.*]] = trunc i32 [[B:%.*]] to i8
1273 ; CHECK-NEXT:    [[C:%.*]] = icmp eq i8 [[TMP1]], [[A:%.*]]
1274 ; CHECK-NEXT:    ret i1 [[C]]
1276   %z = zext i8 %a to i32
1277   %t = and i32 %b, 255
1278   %c = icmp eq i32 %z, %t
1279   ret i1 %c
1282 define i1 @test64(i8 %a, i32 %b) {
1283 ; CHECK-LABEL: @test64(
1284 ; CHECK-NEXT:    [[TMP1:%.*]] = trunc i32 [[B:%.*]] to i8
1285 ; CHECK-NEXT:    [[C:%.*]] = icmp eq i8 [[TMP1]], [[A:%.*]]
1286 ; CHECK-NEXT:    ret i1 [[C]]
1288   %t = and i32 %b, 255
1289   %z = zext i8 %a to i32
1290   %c = icmp eq i32 %t, %z
1291   ret i1 %c
1294 define i1 @test65(i64 %A, i64 %B) {
1295 ; CHECK-LABEL: @test65(
1296 ; CHECK-NEXT:    ret i1 true
1298   %s1 = add i64 %A, %B
1299   %s2 = add i64 %A, %B
1300   %cmp = icmp eq i64 %s1, %s2
1301   ret i1 %cmp
1304 define i1 @test66(i64 %A, i64 %B) {
1305 ; CHECK-LABEL: @test66(
1306 ; CHECK-NEXT:    ret i1 true
1308   %s1 = add i64 %A, %B
1309   %s2 = add i64 %B, %A
1310   %cmp = icmp eq i64 %s1, %s2
1311   ret i1 %cmp
1314 define i1 @test67(i32 %x) {
1315 ; CHECK-LABEL: @test67(
1316 ; CHECK-NEXT:    [[AND:%.*]] = and i32 [[X:%.*]], 96
1317 ; CHECK-NEXT:    [[CMP:%.*]] = icmp ne i32 [[AND]], 0
1318 ; CHECK-NEXT:    ret i1 [[CMP]]
1320   %and = and i32 %x, 127
1321   %cmp = icmp sgt i32 %and, 31
1322   ret i1 %cmp
1325 define i1 @test67inverse(i32 %x) {
1326 ; CHECK-LABEL: @test67inverse(
1327 ; CHECK-NEXT:    [[AND:%.*]] = and i32 [[X:%.*]], 96
1328 ; CHECK-NEXT:    [[CMP:%.*]] = icmp eq i32 [[AND]], 0
1329 ; CHECK-NEXT:    ret i1 [[CMP]]
1331   %and = and i32 %x, 127
1332   %cmp = icmp sle i32 %and, 31
1333   ret i1 %cmp
1336 ; The test above relies on 3 different folds.
1337 ; This test only checks the last of those (icmp ugt -> icmp ne).
1339 define <2 x i1> @test67vec(<2 x i32> %x) {
1340 ; CHECK-LABEL: @test67vec(
1341 ; CHECK-NEXT:    [[AND:%.*]] = and <2 x i32> [[X:%.*]], <i32 96, i32 96>
1342 ; CHECK-NEXT:    [[CMP:%.*]] = icmp ne <2 x i32> [[AND]], zeroinitializer
1343 ; CHECK-NEXT:    ret <2 x i1> [[CMP]]
1345   %and = and <2 x i32> %x, <i32 96, i32 96>
1346   %cmp = icmp ugt <2 x i32> %and, <i32 31, i32 31>
1347   ret <2 x i1> %cmp
1350 define <2 x i1> @test67vec2(<2 x i32> %x) {
1351 ; CHECK-LABEL: @test67vec2(
1352 ; CHECK-NEXT:    [[AND:%.*]] = and <2 x i32> [[X:%.*]], <i32 96, i32 96>
1353 ; CHECK-NEXT:    [[CMP:%.*]] = icmp ne <2 x i32> [[AND]], zeroinitializer
1354 ; CHECK-NEXT:    ret <2 x i1> [[CMP]]
1356   %and = and <2 x i32> %x, <i32 127, i32 127>
1357   %cmp = icmp ugt <2 x i32> %and, <i32 31, i32 31>
1358   ret <2 x i1> %cmp
1361 define <2 x i1> @test67vecinverse(<2 x i32> %x) {
1362 ; CHECK-LABEL: @test67vecinverse(
1363 ; CHECK-NEXT:    [[AND:%.*]] = and <2 x i32> [[X:%.*]], <i32 96, i32 96>
1364 ; CHECK-NEXT:    [[CMP:%.*]] = icmp eq <2 x i32> [[AND]], zeroinitializer
1365 ; CHECK-NEXT:    ret <2 x i1> [[CMP]]
1367   %and = and <2 x i32> %x, <i32 96, i32 96>
1368   %cmp = icmp sle <2 x i32> %and, <i32 31, i32 31>
1369   ret <2 x i1> %cmp
1372 define i1 @test68(i32 %x) {
1373 ; CHECK-LABEL: @test68(
1374 ; CHECK-NEXT:    [[AND:%.*]] = and i32 [[X:%.*]], 127
1375 ; CHECK-NEXT:    [[CMP:%.*]] = icmp ugt i32 [[AND]], 30
1376 ; CHECK-NEXT:    ret i1 [[CMP]]
1378   %and = and i32 %x, 127
1379   %cmp = icmp sgt i32 %and, 30
1380   ret i1 %cmp
1383 ; PR15940
1384 define i1 @test70(i32 %X) {
1385 ; CHECK-LABEL: @test70(
1386 ; CHECK-NEXT:    [[A:%.*]] = srem i32 5, [[X:%.*]]
1387 ; CHECK-NEXT:    [[C:%.*]] = icmp ne i32 [[A]], 2
1388 ; CHECK-NEXT:    ret i1 [[C]]
1390   %A = srem i32 5, %X
1391   %B = add i32 %A, 2
1392   %C = icmp ne i32 %B, 4
1393   ret i1 %C
1396 define <2 x i1> @test70vec(<2 x i32> %X) {
1397 ; CHECK-LABEL: @test70vec(
1398 ; CHECK-NEXT:    [[C:%.*]] = icmp ne <2 x i32> [[X:%.*]], <i32 2, i32 2>
1399 ; CHECK-NEXT:    ret <2 x i1> [[C]]
1401   %B = add <2 x i32> %X, <i32 2, i32 2>
1402   %C = icmp ne <2 x i32> %B, <i32 4, i32 4>
1403   ret <2 x i1> %C
1406 define i1 @icmp_sext16trunc(i32 %x) {
1407 ; CHECK-LABEL: @icmp_sext16trunc(
1408 ; CHECK-NEXT:    [[TMP1:%.*]] = trunc i32 [[X:%.*]] to i16
1409 ; CHECK-NEXT:    [[CMP:%.*]] = icmp slt i16 [[TMP1]], 36
1410 ; CHECK-NEXT:    ret i1 [[CMP]]
1412   %trunc = trunc i32 %x to i16
1413   %sext = sext i16 %trunc to i32
1414   %cmp = icmp slt i32 %sext, 36
1415   ret i1 %cmp
1418 define i1 @icmp_sext8trunc(i32 %x) {
1419 ; CHECK-LABEL: @icmp_sext8trunc(
1420 ; CHECK-NEXT:    [[TMP1:%.*]] = trunc i32 [[X:%.*]] to i8
1421 ; CHECK-NEXT:    [[CMP:%.*]] = icmp slt i8 [[TMP1]], 36
1422 ; CHECK-NEXT:    ret i1 [[CMP]]
1424   %trunc = trunc i32 %x to i8
1425   %sext = sext i8 %trunc to i32
1426   %cmp = icmp slt i32 %sext, 36
1427   ret i1 %cmp
1430 ; Vectors should fold the same way.
1431 define <2 x i1> @icmp_sext8trunc_vec(<2 x i32> %x) {
1432 ; CHECK-LABEL: @icmp_sext8trunc_vec(
1433 ; CHECK-NEXT:    [[TMP1:%.*]] = trunc <2 x i32> [[X:%.*]] to <2 x i8>
1434 ; CHECK-NEXT:    [[CMP:%.*]] = icmp slt <2 x i8> [[TMP1]], <i8 36, i8 36>
1435 ; CHECK-NEXT:    ret <2 x i1> [[CMP]]
1437   %trunc = trunc <2 x i32> %x to <2 x i8>
1438   %sext = sext <2 x i8> %trunc to <2 x i32>
1439   %cmp = icmp slt <2 x i32> %sext, <i32 36, i32 36>
1440   ret <2 x i1> %cmp
1443 define i1 @icmp_shl16(i32 %x) {
1444 ; CHECK-LABEL: @icmp_shl16(
1445 ; CHECK-NEXT:    [[TMP1:%.*]] = trunc i32 [[X:%.*]] to i16
1446 ; CHECK-NEXT:    [[CMP:%.*]] = icmp slt i16 [[TMP1]], 36
1447 ; CHECK-NEXT:    ret i1 [[CMP]]
1449   %shl = shl i32 %x, 16
1450   %cmp = icmp slt i32 %shl, 2359296
1451   ret i1 %cmp
1454 ; D25952: Don't create illegal types like i15 in InstCombine
1456 define i1 @icmp_shl17(i32 %x) {
1457 ; CHECK-LABEL: @icmp_shl17(
1458 ; CHECK-NEXT:    [[SHL:%.*]] = shl i32 [[X:%.*]], 17
1459 ; CHECK-NEXT:    [[CMP:%.*]] = icmp slt i32 [[SHL]], 2359296
1460 ; CHECK-NEXT:    ret i1 [[CMP]]
1462   %shl = shl i32 %x, 17
1463   %cmp = icmp slt i32 %shl, 2359296
1464   ret i1 %cmp
1467 define <2 x i1> @icmp_shl16_vec(<2 x i32> %x) {
1468 ; CHECK-LABEL: @icmp_shl16_vec(
1469 ; CHECK-NEXT:    [[TMP1:%.*]] = trunc <2 x i32> [[X:%.*]] to <2 x i16>
1470 ; CHECK-NEXT:    [[CMP:%.*]] = icmp slt <2 x i16> [[TMP1]], <i16 36, i16 36>
1471 ; CHECK-NEXT:    ret <2 x i1> [[CMP]]
1473   %shl = shl <2 x i32> %x, <i32 16, i32 16>
1474   %cmp = icmp slt <2 x i32> %shl, <i32 2359296, i32 2359296>
1475   ret <2 x i1> %cmp
1478 define i1 @icmp_shl24(i32 %x) {
1479 ; CHECK-LABEL: @icmp_shl24(
1480 ; CHECK-NEXT:    [[TMP1:%.*]] = trunc i32 [[X:%.*]] to i8
1481 ; CHECK-NEXT:    [[CMP:%.*]] = icmp slt i8 [[TMP1]], 36
1482 ; CHECK-NEXT:    ret i1 [[CMP]]
1484   %shl = shl i32 %x, 24
1485   %cmp = icmp slt i32 %shl, 603979776
1486   ret i1 %cmp
1489 define i1 @icmp_shl_eq(i32 %x) {
1490 ; CHECK-LABEL: @icmp_shl_eq(
1491 ; CHECK-NEXT:    [[MUL_MASK:%.*]] = and i32 [[X:%.*]], 134217727
1492 ; CHECK-NEXT:    [[CMP:%.*]] = icmp eq i32 [[MUL_MASK]], 0
1493 ; CHECK-NEXT:    ret i1 [[CMP]]
1495   %mul = shl i32 %x, 5
1496   %cmp = icmp eq i32 %mul, 0
1497   ret i1 %cmp
1500 define <2 x i1> @icmp_shl_eq_vec(<2 x i32> %x) {
1501 ; CHECK-LABEL: @icmp_shl_eq_vec(
1502 ; CHECK-NEXT:    [[MUL_MASK:%.*]] = and <2 x i32> [[X:%.*]], <i32 134217727, i32 134217727>
1503 ; CHECK-NEXT:    [[CMP:%.*]] = icmp eq <2 x i32> [[MUL_MASK]], zeroinitializer
1504 ; CHECK-NEXT:    ret <2 x i1> [[CMP]]
1506   %mul = shl <2 x i32> %x, <i32 5, i32 5>
1507   %cmp = icmp eq <2 x i32> %mul, zeroinitializer
1508   ret <2 x i1> %cmp
1511 define i1 @icmp_shl_nsw_ne(i32 %x) {
1512 ; CHECK-LABEL: @icmp_shl_nsw_ne(
1513 ; CHECK-NEXT:    [[CMP:%.*]] = icmp ne i32 [[X:%.*]], 0
1514 ; CHECK-NEXT:    ret i1 [[CMP]]
1516   %mul = shl nsw i32 %x, 7
1517   %cmp = icmp ne i32 %mul, 0
1518   ret i1 %cmp
1521 define <2 x i1> @icmp_shl_nsw_ne_vec(<2 x i32> %x) {
1522 ; CHECK-LABEL: @icmp_shl_nsw_ne_vec(
1523 ; CHECK-NEXT:    [[CMP:%.*]] = icmp ne <2 x i32> [[X:%.*]], zeroinitializer
1524 ; CHECK-NEXT:    ret <2 x i1> [[CMP]]
1526   %mul = shl nsw <2 x i32> %x, <i32 7, i32 7>
1527   %cmp = icmp ne <2 x i32> %mul, zeroinitializer
1528   ret <2 x i1> %cmp
1531 define i1 @icmp_shl_ne(i32 %x) {
1532 ; CHECK-LABEL: @icmp_shl_ne(
1533 ; CHECK-NEXT:    [[MUL_MASK:%.*]] = and i32 [[X:%.*]], 33554431
1534 ; CHECK-NEXT:    [[CMP:%.*]] = icmp ne i32 [[MUL_MASK]], 0
1535 ; CHECK-NEXT:    ret i1 [[CMP]]
1537   %mul = shl i32 %x, 7
1538   %cmp = icmp ne i32 %mul, 0
1539   ret i1 %cmp
1542 define <2 x i1> @icmp_shl_ne_vec(<2 x i32> %x) {
1543 ; CHECK-LABEL: @icmp_shl_ne_vec(
1544 ; CHECK-NEXT:    [[MUL_MASK:%.*]] = and <2 x i32> [[X:%.*]], <i32 33554431, i32 33554431>
1545 ; CHECK-NEXT:    [[CMP:%.*]] = icmp ne <2 x i32> [[MUL_MASK]], zeroinitializer
1546 ; CHECK-NEXT:    ret <2 x i1> [[CMP]]
1548   %mul = shl <2 x i32> %x, <i32 7, i32 7>
1549   %cmp = icmp ne <2 x i32> %mul, zeroinitializer
1550   ret <2 x i1> %cmp
1553 define <2 x i1> @icmp_shl_nuw_ne_vec(<2 x i32> %x) {
1554 ; CHECK-LABEL: @icmp_shl_nuw_ne_vec(
1555 ; CHECK-NEXT:    [[CMP:%.*]] = icmp ne <2 x i32> [[X:%.*]], <i32 2, i32 2>
1556 ; CHECK-NEXT:    ret <2 x i1> [[CMP]]
1558   %shl = shl nuw <2 x i32> %x, <i32 7, i32 7>
1559   %cmp = icmp ne <2 x i32> %shl, <i32 256, i32 256>
1560   ret <2 x i1> %cmp
1563 ; If the (mul x, C) preserved the sign and this is sign test,
1564 ; compare the LHS operand instead
1565 define i1 @icmp_mul_nsw(i32 %x) {
1566 ; CHECK-LABEL: @icmp_mul_nsw(
1567 ; CHECK-NEXT:    [[CMP:%.*]] = icmp sgt i32 [[X:%.*]], 0
1568 ; CHECK-NEXT:    ret i1 [[CMP]]
1570   %mul = mul nsw i32 %x, 12
1571   %cmp = icmp sgt i32 %mul, 0
1572   ret i1 %cmp
1575 define i1 @icmp_mul_nsw1(i32 %x) {
1576 ; CHECK-LABEL: @icmp_mul_nsw1(
1577 ; CHECK-NEXT:    [[CMP:%.*]] = icmp slt i32 [[X:%.*]], 0
1578 ; CHECK-NEXT:    ret i1 [[CMP]]
1580   %mul = mul nsw i32 %x, 12
1581   %cmp = icmp sle i32 %mul, -1
1582   ret i1 %cmp
1585 define i1 @icmp_mul_nsw_neg(i32 %x) {
1586 ; CHECK-LABEL: @icmp_mul_nsw_neg(
1587 ; CHECK-NEXT:    [[CMP:%.*]] = icmp slt i32 [[X:%.*]], 1
1588 ; CHECK-NEXT:    ret i1 [[CMP]]
1590   %mul = mul nsw i32 %x, -12
1591   %cmp = icmp sge i32 %mul, 0
1592   ret i1 %cmp
1595 define i1 @icmp_mul_nsw_neg1(i32 %x) {
1596 ; CHECK-LABEL: @icmp_mul_nsw_neg1(
1597 ; CHECK-NEXT:    [[CMP:%.*]] = icmp slt i32 [[X:%.*]], 0
1598 ; CHECK-NEXT:    ret i1 [[CMP]]
1600   %mul = mul nsw i32 %x, -12
1601   %cmp = icmp sge i32 %mul, 1
1602   ret i1 %cmp
1605 define <2 x i1> @icmp_mul_nsw_neg1_vec(<2 x i32> %x) {
1606 ; CHECK-LABEL: @icmp_mul_nsw_neg1_vec(
1607 ; CHECK-NEXT:    [[CMP:%.*]] = icmp slt <2 x i32> [[X:%.*]], zeroinitializer
1608 ; CHECK-NEXT:    ret <2 x i1> [[CMP]]
1610   %mul = mul nsw <2 x i32> %x, <i32 -12, i32 -12>
1611   %cmp = icmp sge <2 x i32> %mul, <i32 1, i32 1>
1612   ret <2 x i1> %cmp
1615 define i1 @icmp_mul_nsw_0(i32 %x) {
1616 ; CHECK-LABEL: @icmp_mul_nsw_0(
1617 ; CHECK-NEXT:    ret i1 false
1619   %mul = mul nsw i32 %x, 0
1620   %cmp = icmp sgt i32 %mul, 0
1621   ret i1 %cmp
1624 define i1 @icmp_mul(i32 %x) {
1625 ; CHECK-LABEL: @icmp_mul(
1626 ; CHECK-NEXT:    [[MUL:%.*]] = mul i32 [[X:%.*]], -12
1627 ; CHECK-NEXT:    [[CMP:%.*]] = icmp sgt i32 [[MUL]], -1
1628 ; CHECK-NEXT:    ret i1 [[CMP]]
1630   %mul = mul i32 %x, -12
1631   %cmp = icmp sge i32 %mul, 0
1632   ret i1 %cmp
1635 ; Checks for icmp (eq|ne) (mul x, C), 0
1636 define i1 @icmp_mul_neq0(i32 %x) {
1637 ; CHECK-LABEL: @icmp_mul_neq0(
1638 ; CHECK-NEXT:    [[CMP:%.*]] = icmp ne i32 [[X:%.*]], 0
1639 ; CHECK-NEXT:    ret i1 [[CMP]]
1641   %mul = mul nsw i32 %x, -12
1642   %cmp = icmp ne i32 %mul, 0
1643   ret i1 %cmp
1646 define <2 x i1> @icmp_mul_neq0_vec(<2 x i32> %x) {
1647 ; CHECK-LABEL: @icmp_mul_neq0_vec(
1648 ; CHECK-NEXT:    [[CMP:%.*]] = icmp ne <2 x i32> [[X:%.*]], zeroinitializer
1649 ; CHECK-NEXT:    ret <2 x i1> [[CMP]]
1651   %mul = mul nsw <2 x i32> %x, <i32 -12, i32 -12>
1652   %cmp = icmp ne <2 x i32> %mul, zeroinitializer
1653   ret <2 x i1> %cmp
1656 define i1 @icmp_mul_eq0(i32 %x) {
1657 ; CHECK-LABEL: @icmp_mul_eq0(
1658 ; CHECK-NEXT:    [[CMP:%.*]] = icmp eq i32 [[X:%.*]], 0
1659 ; CHECK-NEXT:    ret i1 [[CMP]]
1661   %mul = mul nsw i32 %x, 12
1662   %cmp = icmp eq i32 %mul, 0
1663   ret i1 %cmp
1666 define i1 @icmp_mul0_eq0(i32 %x) {
1667 ; CHECK-LABEL: @icmp_mul0_eq0(
1668 ; CHECK-NEXT:    ret i1 true
1670   %mul = mul i32 %x, 0
1671   %cmp = icmp eq i32 %mul, 0
1672   ret i1 %cmp
1675 define i1 @icmp_mul0_ne0(i32 %x) {
1676 ; CHECK-LABEL: @icmp_mul0_ne0(
1677 ; CHECK-NEXT:    ret i1 false
1679   %mul = mul i32 %x, 0
1680   %cmp = icmp ne i32 %mul, 0
1681   ret i1 %cmp
1684 define i1 @icmp_sub1_sge(i32 %x, i32 %y) {
1685 ; CHECK-LABEL: @icmp_sub1_sge(
1686 ; CHECK-NEXT:    [[CMP:%.*]] = icmp sgt i32 [[X:%.*]], [[Y:%.*]]
1687 ; CHECK-NEXT:    ret i1 [[CMP]]
1689   %sub = add nsw i32 %x, -1
1690   %cmp = icmp sge i32 %sub, %y
1691   ret i1 %cmp
1694 define i1 @icmp_add1_sgt(i32 %x, i32 %y) {
1695 ; CHECK-LABEL: @icmp_add1_sgt(
1696 ; CHECK-NEXT:    [[CMP:%.*]] = icmp sge i32 [[X:%.*]], [[Y:%.*]]
1697 ; CHECK-NEXT:    ret i1 [[CMP]]
1699   %add = add nsw i32 %x, 1
1700   %cmp = icmp sgt i32 %add, %y
1701   ret i1 %cmp
1704 define i1 @icmp_sub1_slt(i32 %x, i32 %y) {
1705 ; CHECK-LABEL: @icmp_sub1_slt(
1706 ; CHECK-NEXT:    [[CMP:%.*]] = icmp sle i32 [[X:%.*]], [[Y:%.*]]
1707 ; CHECK-NEXT:    ret i1 [[CMP]]
1709   %sub = add nsw i32 %x, -1
1710   %cmp = icmp slt i32 %sub, %y
1711   ret i1 %cmp
1714 define i1 @icmp_add1_sle(i32 %x, i32 %y) {
1715 ; CHECK-LABEL: @icmp_add1_sle(
1716 ; CHECK-NEXT:    [[CMP:%.*]] = icmp slt i32 [[X:%.*]], [[Y:%.*]]
1717 ; CHECK-NEXT:    ret i1 [[CMP]]
1719   %add = add nsw i32 %x, 1
1720   %cmp = icmp sle i32 %add, %y
1721   ret i1 %cmp
1724 define i1 @icmp_add20_sge_add57(i32 %x, i32 %y) {
1725 ; CHECK-LABEL: @icmp_add20_sge_add57(
1726 ; CHECK-NEXT:    [[TMP1:%.*]] = add nsw i32 [[Y:%.*]], 37
1727 ; CHECK-NEXT:    [[CMP:%.*]] = icmp sle i32 [[TMP1]], [[X:%.*]]
1728 ; CHECK-NEXT:    ret i1 [[CMP]]
1730   %1 = add nsw i32 %x, 20
1731   %2 = add nsw i32 %y, 57
1732   %cmp = icmp sge i32 %1, %2
1733   ret i1 %cmp
1736 define i1 @icmp_sub57_sge_sub20(i32 %x, i32 %y) {
1737 ; CHECK-LABEL: @icmp_sub57_sge_sub20(
1738 ; CHECK-NEXT:    [[TMP1:%.*]] = add nsw i32 [[X:%.*]], -37
1739 ; CHECK-NEXT:    [[CMP:%.*]] = icmp sge i32 [[TMP1]], [[Y:%.*]]
1740 ; CHECK-NEXT:    ret i1 [[CMP]]
1742   %1 = add nsw i32 %x, -57
1743   %2 = add nsw i32 %y, -20
1744   %cmp = icmp sge i32 %1, %2
1745   ret i1 %cmp
1748 define i1 @icmp_and_shl_neg_ne_0(i32 %A, i32 %B) {
1749 ; CHECK-LABEL: @icmp_and_shl_neg_ne_0(
1750 ; CHECK-NEXT:    [[SHL:%.*]] = shl i32 1, [[B:%.*]]
1751 ; CHECK-NEXT:    [[TMP1:%.*]] = and i32 [[SHL]], [[A:%.*]]
1752 ; CHECK-NEXT:    [[CMP:%.*]] = icmp eq i32 [[TMP1]], 0
1753 ; CHECK-NEXT:    ret i1 [[CMP]]
1755   %neg = xor i32 %A, -1
1756   %shl = shl i32 1, %B
1757   %and = and i32 %shl, %neg
1758   %cmp = icmp ne i32 %and, 0
1759   ret i1 %cmp
1762 define i1 @icmp_and_shl_neg_eq_0(i32 %A, i32 %B) {
1763 ; CHECK-LABEL: @icmp_and_shl_neg_eq_0(
1764 ; CHECK-NEXT:    [[SHL:%.*]] = shl i32 1, [[B:%.*]]
1765 ; CHECK-NEXT:    [[TMP1:%.*]] = and i32 [[SHL]], [[A:%.*]]
1766 ; CHECK-NEXT:    [[CMP:%.*]] = icmp ne i32 [[TMP1]], 0
1767 ; CHECK-NEXT:    ret i1 [[CMP]]
1769   %neg = xor i32 %A, -1
1770   %shl = shl i32 1, %B
1771   %and = and i32 %shl, %neg
1772   %cmp = icmp eq i32 %and, 0
1773   ret i1 %cmp
1776 define i1 @icmp_add_and_shr_ne_0(i32 %X) {
1777 ; CHECK-LABEL: @icmp_add_and_shr_ne_0(
1778 ; CHECK-NEXT:    [[AND:%.*]] = and i32 [[X:%.*]], 240
1779 ; CHECK-NEXT:    [[TOBOOL:%.*]] = icmp ne i32 [[AND]], 224
1780 ; CHECK-NEXT:    ret i1 [[TOBOOL]]
1782   %shr = lshr i32 %X, 4
1783   %and = and i32 %shr, 15
1784   %add = add i32 %and, -14
1785   %tobool = icmp ne i32 %add, 0
1786   ret i1 %tobool
1789 define <2 x i1> @icmp_add_and_shr_ne_0_vec(<2 x i32> %X) {
1790 ; CHECK-LABEL: @icmp_add_and_shr_ne_0_vec(
1791 ; CHECK-NEXT:    [[AND:%.*]] = and <2 x i32> [[X:%.*]], <i32 240, i32 240>
1792 ; CHECK-NEXT:    [[TOBOOL:%.*]] = icmp ne <2 x i32> [[AND]], <i32 224, i32 224>
1793 ; CHECK-NEXT:    ret <2 x i1> [[TOBOOL]]
1795   %shr = lshr <2 x i32> %X, <i32 4, i32 4>
1796   %and = and <2 x i32> %shr, <i32 15, i32 15>
1797   %add = add <2 x i32> %and, <i32 -14, i32 -14>
1798   %tobool = icmp ne <2 x i32> %add, zeroinitializer
1799   ret <2 x i1> %tobool
1802 ; Variation of the above with an extra use of the shift
1803 define i1 @icmp_and_shr_multiuse(i32 %X) {
1804 ; CHECK-LABEL: @icmp_and_shr_multiuse(
1805 ; CHECK-NEXT:    [[AND:%.*]] = and i32 [[X:%.*]], 240
1806 ; CHECK-NEXT:    [[AND2:%.*]] = and i32 [[X]], 496
1807 ; CHECK-NEXT:    [[TOBOOL:%.*]] = icmp ne i32 [[AND]], 224
1808 ; CHECK-NEXT:    [[TOBOOL2:%.*]] = icmp ne i32 [[AND2]], 432
1809 ; CHECK-NEXT:    [[AND3:%.*]] = and i1 [[TOBOOL]], [[TOBOOL2]]
1810 ; CHECK-NEXT:    ret i1 [[AND3]]
1812   %shr = lshr i32 %X, 4
1813   %and = and i32 %shr, 15
1814   %and2 = and i32 %shr, 31 ; second use of the shift
1815   %tobool = icmp ne i32 %and, 14
1816   %tobool2 = icmp ne i32 %and2, 27
1817   %and3 = and i1 %tobool, %tobool2
1818   ret i1 %and3
1821 ; Variation of the above with an ashr
1822 define i1 @icmp_and_ashr_multiuse(i32 %X) {
1823 ; CHECK-LABEL: @icmp_and_ashr_multiuse(
1824 ; CHECK-NEXT:    [[AND:%.*]] = and i32 [[X:%.*]], 240
1825 ; CHECK-NEXT:    [[AND2:%.*]] = and i32 [[X]], 496
1826 ; CHECK-NEXT:    [[TOBOOL:%.*]] = icmp ne i32 [[AND]], 224
1827 ; CHECK-NEXT:    [[TOBOOL2:%.*]] = icmp ne i32 [[AND2]], 432
1828 ; CHECK-NEXT:    [[AND3:%.*]] = and i1 [[TOBOOL]], [[TOBOOL2]]
1829 ; CHECK-NEXT:    ret i1 [[AND3]]
1831   %shr = ashr i32 %X, 4
1832   %and = and i32 %shr, 15
1833   %and2 = and i32 %shr, 31 ; second use of the shift
1834   %tobool = icmp ne i32 %and, 14
1835   %tobool2 = icmp ne i32 %and2, 27
1836   %and3 = and i1 %tobool, %tobool2
1837   ret i1 %and3
1840 define i1 @icmp_lshr_and_overshift(i8 %X) {
1841 ; CHECK-LABEL: @icmp_lshr_and_overshift(
1842 ; CHECK-NEXT:    [[TOBOOL:%.*]] = icmp ugt i8 [[X:%.*]], 31
1843 ; CHECK-NEXT:    ret i1 [[TOBOOL]]
1845   %shr = lshr i8 %X, 5
1846   %and = and i8 %shr, 15
1847   %tobool = icmp ne i8 %and, 0
1848   ret i1 %tobool
1851 ; We shouldn't simplify this because the and uses bits that are shifted in.
1852 define i1 @icmp_ashr_and_overshift(i8 %X) {
1853 ; CHECK-LABEL: @icmp_ashr_and_overshift(
1854 ; CHECK-NEXT:    [[SHR:%.*]] = ashr i8 [[X:%.*]], 5
1855 ; CHECK-NEXT:    [[AND:%.*]] = and i8 [[SHR]], 15
1856 ; CHECK-NEXT:    [[TOBOOL:%.*]] = icmp ne i8 [[AND]], 0
1857 ; CHECK-NEXT:    ret i1 [[TOBOOL]]
1859   %shr = ashr i8 %X, 5
1860   %and = and i8 %shr, 15
1861   %tobool = icmp ne i8 %and, 0
1862   ret i1 %tobool
1865 ; PR16244
1866 define i1 @test71(i8* %x) {
1867 ; CHECK-LABEL: @test71(
1868 ; CHECK-NEXT:    ret i1 false
1870   %a = getelementptr i8, i8* %x, i64 8
1871   %b = getelementptr inbounds i8, i8* %x, i64 8
1872   %c = icmp ugt i8* %a, %b
1873   ret i1 %c
1876 define i1 @test71_as1(i8 addrspace(1)* %x) {
1877 ; CHECK-LABEL: @test71_as1(
1878 ; CHECK-NEXT:    ret i1 false
1880   %a = getelementptr i8, i8 addrspace(1)* %x, i64 8
1881   %b = getelementptr inbounds i8, i8 addrspace(1)* %x, i64 8
1882   %c = icmp ugt i8 addrspace(1)* %a, %b
1883   ret i1 %c
1886 define i1 @icmp_shl_1_V_ult_32(i32 %V) {
1887 ; CHECK-LABEL: @icmp_shl_1_V_ult_32(
1888 ; CHECK-NEXT:    [[CMP:%.*]] = icmp ult i32 [[V:%.*]], 5
1889 ; CHECK-NEXT:    ret i1 [[CMP]]
1891   %shl = shl i32 1, %V
1892   %cmp = icmp ult i32 %shl, 32
1893   ret i1 %cmp
1896 define <2 x i1> @icmp_shl_1_V_ult_32_vec(<2 x i32> %V) {
1897 ; CHECK-LABEL: @icmp_shl_1_V_ult_32_vec(
1898 ; CHECK-NEXT:    [[CMP:%.*]] = icmp ult <2 x i32> [[V:%.*]], <i32 5, i32 5>
1899 ; CHECK-NEXT:    ret <2 x i1> [[CMP]]
1901   %shl = shl <2 x i32> <i32 1, i32 1>, %V
1902   %cmp = icmp ult <2 x i32> %shl, <i32 32, i32 32>
1903   ret <2 x i1> %cmp
1906 define i1 @icmp_shl_1_V_eq_32(i32 %V) {
1907 ; CHECK-LABEL: @icmp_shl_1_V_eq_32(
1908 ; CHECK-NEXT:    [[CMP:%.*]] = icmp eq i32 [[V:%.*]], 5
1909 ; CHECK-NEXT:    ret i1 [[CMP]]
1911   %shl = shl i32 1, %V
1912   %cmp = icmp eq i32 %shl, 32
1913   ret i1 %cmp
1916 define <2 x i1> @icmp_shl_1_V_eq_32_vec(<2 x i32> %V) {
1917 ; CHECK-LABEL: @icmp_shl_1_V_eq_32_vec(
1918 ; CHECK-NEXT:    [[CMP:%.*]] = icmp eq <2 x i32> [[V:%.*]], <i32 5, i32 5>
1919 ; CHECK-NEXT:    ret <2 x i1> [[CMP]]
1921   %shl = shl <2 x i32> <i32 1, i32 1>, %V
1922   %cmp = icmp eq <2 x i32> %shl, <i32 32, i32 32>
1923   ret <2 x i1> %cmp
1926 define i1 @icmp_shl_1_V_ult_30(i32 %V) {
1927 ; CHECK-LABEL: @icmp_shl_1_V_ult_30(
1928 ; CHECK-NEXT:    [[CMP:%.*]] = icmp ult i32 [[V:%.*]], 5
1929 ; CHECK-NEXT:    ret i1 [[CMP]]
1931   %shl = shl i32 1, %V
1932   %cmp = icmp ult i32 %shl, 30
1933   ret i1 %cmp
1936 define <2 x i1> @icmp_shl_1_V_ult_30_vec(<2 x i32> %V) {
1937 ; CHECK-LABEL: @icmp_shl_1_V_ult_30_vec(
1938 ; CHECK-NEXT:    [[CMP:%.*]] = icmp ult <2 x i32> [[V:%.*]], <i32 5, i32 5>
1939 ; CHECK-NEXT:    ret <2 x i1> [[CMP]]
1941   %shl = shl <2 x i32> <i32 1, i32 1>, %V
1942   %cmp = icmp ult <2 x i32> %shl, <i32 30, i32 30>
1943   ret <2 x i1> %cmp
1946 define i1 @icmp_shl_1_V_ugt_30(i32 %V) {
1947 ; CHECK-LABEL: @icmp_shl_1_V_ugt_30(
1948 ; CHECK-NEXT:    [[CMP:%.*]] = icmp ugt i32 [[V:%.*]], 4
1949 ; CHECK-NEXT:    ret i1 [[CMP]]
1951   %shl = shl i32 1, %V
1952   %cmp = icmp ugt i32 %shl, 30
1953   ret i1 %cmp
1956 define <2 x i1> @icmp_shl_1_V_ugt_30_vec(<2 x i32> %V) {
1957 ; CHECK-LABEL: @icmp_shl_1_V_ugt_30_vec(
1958 ; CHECK-NEXT:    [[CMP:%.*]] = icmp ugt <2 x i32> [[V:%.*]], <i32 4, i32 4>
1959 ; CHECK-NEXT:    ret <2 x i1> [[CMP]]
1961   %shl = shl <2 x i32> <i32 1, i32 1>, %V
1962   %cmp = icmp ugt <2 x i32> %shl, <i32 30, i32 30>
1963   ret <2 x i1> %cmp
1966 define i1 @icmp_shl_1_V_ule_30(i32 %V) {
1967 ; CHECK-LABEL: @icmp_shl_1_V_ule_30(
1968 ; CHECK-NEXT:    [[CMP:%.*]] = icmp ult i32 [[V:%.*]], 5
1969 ; CHECK-NEXT:    ret i1 [[CMP]]
1971   %shl = shl i32 1, %V
1972   %cmp = icmp ule i32 %shl, 30
1973   ret i1 %cmp
1976 define <2 x i1> @icmp_shl_1_V_ule_30_vec(<2 x i32> %V) {
1977 ; CHECK-LABEL: @icmp_shl_1_V_ule_30_vec(
1978 ; CHECK-NEXT:    [[CMP:%.*]] = icmp ult <2 x i32> [[V:%.*]], <i32 5, i32 5>
1979 ; CHECK-NEXT:    ret <2 x i1> [[CMP]]
1981   %shl = shl <2 x i32> <i32 1, i32 1>, %V
1982   %cmp = icmp ule <2 x i32> %shl, <i32 30, i32 30>
1983   ret <2 x i1> %cmp
1986 define i1 @icmp_shl_1_V_uge_30(i32 %V) {
1987 ; CHECK-LABEL: @icmp_shl_1_V_uge_30(
1988 ; CHECK-NEXT:    [[CMP:%.*]] = icmp ugt i32 [[V:%.*]], 4
1989 ; CHECK-NEXT:    ret i1 [[CMP]]
1991   %shl = shl i32 1, %V
1992   %cmp = icmp uge i32 %shl, 30
1993   ret i1 %cmp
1996 define <2 x i1> @icmp_shl_1_V_uge_30_vec(<2 x i32> %V) {
1997 ; CHECK-LABEL: @icmp_shl_1_V_uge_30_vec(
1998 ; CHECK-NEXT:    [[CMP:%.*]] = icmp ugt <2 x i32> [[V:%.*]], <i32 4, i32 4>
1999 ; CHECK-NEXT:    ret <2 x i1> [[CMP]]
2001   %shl = shl <2 x i32> <i32 1, i32 1>, %V
2002   %cmp = icmp uge <2 x i32> %shl, <i32 30, i32 30>
2003   ret <2 x i1> %cmp
2006 define i1 @icmp_shl_1_V_uge_2147483648(i32 %V) {
2007 ; CHECK-LABEL: @icmp_shl_1_V_uge_2147483648(
2008 ; CHECK-NEXT:    [[CMP:%.*]] = icmp eq i32 [[V:%.*]], 31
2009 ; CHECK-NEXT:    ret i1 [[CMP]]
2011   %shl = shl i32 1, %V
2012   %cmp = icmp uge i32 %shl, 2147483648
2013   ret i1 %cmp
2016 define <2 x i1> @icmp_shl_1_V_uge_2147483648_vec(<2 x i32> %V) {
2017 ; CHECK-LABEL: @icmp_shl_1_V_uge_2147483648_vec(
2018 ; CHECK-NEXT:    [[CMP:%.*]] = icmp eq <2 x i32> [[V:%.*]], <i32 31, i32 31>
2019 ; CHECK-NEXT:    ret <2 x i1> [[CMP]]
2021   %shl = shl <2 x i32> <i32 1, i32 1>, %V
2022   %cmp = icmp uge <2 x i32> %shl, <i32 2147483648, i32 2147483648>
2023   ret <2 x i1> %cmp
2026 define i1 @icmp_shl_1_V_ult_2147483648(i32 %V) {
2027 ; CHECK-LABEL: @icmp_shl_1_V_ult_2147483648(
2028 ; CHECK-NEXT:    [[CMP:%.*]] = icmp ne i32 [[V:%.*]], 31
2029 ; CHECK-NEXT:    ret i1 [[CMP]]
2031   %shl = shl i32 1, %V
2032   %cmp = icmp ult i32 %shl, 2147483648
2033   ret i1 %cmp
2036 define <2 x i1> @icmp_shl_1_V_ult_2147483648_vec(<2 x i32> %V) {
2037 ; CHECK-LABEL: @icmp_shl_1_V_ult_2147483648_vec(
2038 ; CHECK-NEXT:    [[CMP:%.*]] = icmp ne <2 x i32> [[V:%.*]], <i32 31, i32 31>
2039 ; CHECK-NEXT:    ret <2 x i1> [[CMP]]
2041   %shl = shl <2 x i32> <i32 1, i32 1>, %V
2042   %cmp = icmp ult <2 x i32> %shl, <i32 2147483648, i32 2147483648>
2043   ret <2 x i1> %cmp
2046 define i1 @or_icmp_eq_B_0_icmp_ult_A_B(i64 %a, i64 %b) {
2047 ; CHECK-LABEL: @or_icmp_eq_B_0_icmp_ult_A_B(
2048 ; CHECK-NEXT:    [[TMP1:%.*]] = add i64 [[B:%.*]], -1
2049 ; CHECK-NEXT:    [[TMP2:%.*]] = icmp uge i64 [[TMP1]], [[A:%.*]]
2050 ; CHECK-NEXT:    ret i1 [[TMP2]]
2052   %1 = icmp eq i64 %b, 0
2053   %2 = icmp ult i64 %a, %b
2054   %3 = or i1 %1, %2
2055   ret i1 %3
2058 define i1 @icmp_add_ult_2(i32 %X) {
2059 ; CHECK-LABEL: @icmp_add_ult_2(
2060 ; CHECK-NEXT:    [[TMP1:%.*]] = and i32 [[X:%.*]], -2
2061 ; CHECK-NEXT:    [[CMP:%.*]] = icmp eq i32 [[TMP1]], 14
2062 ; CHECK-NEXT:    ret i1 [[CMP]]
2064   %add = add i32 %X, -14
2065   %cmp = icmp ult i32 %add, 2
2066   ret i1 %cmp
2069 define <2 x i1> @icmp_add_X_-14_ult_2_vec(<2 x i32> %X) {
2070 ; CHECK-LABEL: @icmp_add_X_-14_ult_2_vec(
2071 ; CHECK-NEXT:    [[TMP1:%.*]] = and <2 x i32> [[X:%.*]], <i32 -2, i32 -2>
2072 ; CHECK-NEXT:    [[CMP:%.*]] = icmp eq <2 x i32> [[TMP1]], <i32 14, i32 14>
2073 ; CHECK-NEXT:    ret <2 x i1> [[CMP]]
2075   %add = add <2 x i32> %X, <i32 -14, i32 -14>
2076   %cmp = icmp ult <2 x i32> %add, <i32 2, i32 2>
2077   ret <2 x i1> %cmp
2080 define i1 @icmp_sub_3_X_ult_2(i32 %X) {
2081 ; CHECK-LABEL: @icmp_sub_3_X_ult_2(
2082 ; CHECK-NEXT:    [[TMP1:%.*]] = or i32 [[X:%.*]], 1
2083 ; CHECK-NEXT:    [[CMP:%.*]] = icmp eq i32 [[TMP1]], 3
2084 ; CHECK-NEXT:    ret i1 [[CMP]]
2086   %add = sub i32 3, %X
2087   %cmp = icmp ult i32 %add, 2
2088   ret i1 %cmp
2091 define <2 x i1> @icmp_sub_3_X_ult_2_vec(<2 x i32> %X) {
2092 ; CHECK-LABEL: @icmp_sub_3_X_ult_2_vec(
2093 ; CHECK-NEXT:    [[TMP1:%.*]] = or <2 x i32> [[X:%.*]], <i32 1, i32 1>
2094 ; CHECK-NEXT:    [[CMP:%.*]] = icmp eq <2 x i32> [[TMP1]], <i32 3, i32 3>
2095 ; CHECK-NEXT:    ret <2 x i1> [[CMP]]
2097   %add = sub <2 x i32> <i32 3, i32 3>, %X
2098   %cmp = icmp ult <2 x i32> %add, <i32 2, i32 2>
2099   ret <2 x i1> %cmp
2102 define i1 @icmp_add_X_-14_uge_2(i32 %X) {
2103 ; CHECK-LABEL: @icmp_add_X_-14_uge_2(
2104 ; CHECK-NEXT:    [[TMP1:%.*]] = and i32 [[X:%.*]], -2
2105 ; CHECK-NEXT:    [[CMP:%.*]] = icmp ne i32 [[TMP1]], 14
2106 ; CHECK-NEXT:    ret i1 [[CMP]]
2108   %add = add i32 %X, -14
2109   %cmp = icmp uge i32 %add, 2
2110   ret i1 %cmp
2113 define <2 x i1> @icmp_add_X_-14_uge_2_vec(<2 x i32> %X) {
2114 ; CHECK-LABEL: @icmp_add_X_-14_uge_2_vec(
2115 ; CHECK-NEXT:    [[TMP1:%.*]] = and <2 x i32> [[X:%.*]], <i32 -2, i32 -2>
2116 ; CHECK-NEXT:    [[CMP:%.*]] = icmp ne <2 x i32> [[TMP1]], <i32 14, i32 14>
2117 ; CHECK-NEXT:    ret <2 x i1> [[CMP]]
2119   %add = add <2 x i32> %X, <i32 -14, i32 -14>
2120   %cmp = icmp uge <2 x i32> %add, <i32 2, i32 2>
2121   ret <2 x i1> %cmp
2124 define i1 @icmp_sub_3_X_uge_2(i32 %X) {
2125 ; CHECK-LABEL: @icmp_sub_3_X_uge_2(
2126 ; CHECK-NEXT:    [[TMP1:%.*]] = or i32 [[X:%.*]], 1
2127 ; CHECK-NEXT:    [[CMP:%.*]] = icmp ne i32 [[TMP1]], 3
2128 ; CHECK-NEXT:    ret i1 [[CMP]]
2130   %add = sub i32 3, %X
2131   %cmp = icmp uge i32 %add, 2
2132   ret i1 %cmp
2135 define <2 x i1> @icmp_sub_3_X_uge_2_vec(<2 x i32> %X) {
2136 ; CHECK-LABEL: @icmp_sub_3_X_uge_2_vec(
2137 ; CHECK-NEXT:    [[TMP1:%.*]] = or <2 x i32> [[X:%.*]], <i32 1, i32 1>
2138 ; CHECK-NEXT:    [[CMP:%.*]] = icmp ne <2 x i32> [[TMP1]], <i32 3, i32 3>
2139 ; CHECK-NEXT:    ret <2 x i1> [[CMP]]
2141   %add = sub <2 x i32> <i32 3, i32 3>, %X
2142   %cmp = icmp uge <2 x i32> %add, <i32 2, i32 2>
2143   ret <2 x i1> %cmp
2146 define i1 @icmp_and_X_-16_eq-16(i32 %X) {
2147 ; CHECK-LABEL: @icmp_and_X_-16_eq-16(
2148 ; CHECK-NEXT:    [[CMP:%.*]] = icmp ugt i32 [[X:%.*]], -17
2149 ; CHECK-NEXT:    ret i1 [[CMP]]
2151   %and = and i32 %X, -16
2152   %cmp = icmp eq i32 %and, -16
2153   ret i1 %cmp
2156 define <2 x i1> @icmp_and_X_-16_eq-16_vec(<2 x i32> %X) {
2157 ; CHECK-LABEL: @icmp_and_X_-16_eq-16_vec(
2158 ; CHECK-NEXT:    [[CMP:%.*]] = icmp ugt <2 x i32> [[X:%.*]], <i32 -17, i32 -17>
2159 ; CHECK-NEXT:    ret <2 x i1> [[CMP]]
2161   %and = and <2 x i32> %X, <i32 -16, i32 -16>
2162   %cmp = icmp eq <2 x i32> %and, <i32 -16, i32 -16>
2163   ret <2 x i1> %cmp
2166 define i1 @icmp_and_X_-16_ne-16(i32 %X) {
2167 ; CHECK-LABEL: @icmp_and_X_-16_ne-16(
2168 ; CHECK-NEXT:    [[CMP:%.*]] = icmp ult i32 [[X:%.*]], -16
2169 ; CHECK-NEXT:    ret i1 [[CMP]]
2171   %and = and i32 %X, -16
2172   %cmp = icmp ne i32 %and, -16
2173   ret i1 %cmp
2176 define <2 x i1> @icmp_and_X_-16_ne-16_vec(<2 x i32> %X) {
2177 ; CHECK-LABEL: @icmp_and_X_-16_ne-16_vec(
2178 ; CHECK-NEXT:    [[CMP:%.*]] = icmp ult <2 x i32> [[X:%.*]], <i32 -16, i32 -16>
2179 ; CHECK-NEXT:    ret <2 x i1> [[CMP]]
2181   %and = and <2 x i32> %X, <i32 -16, i32 -16>
2182   %cmp = icmp ne <2 x i32> %and, <i32 -16, i32 -16>
2183   ret <2 x i1> %cmp
2186 ; PR32524: https://bugs.llvm.org/show_bug.cgi?id=32524
2187 ; X | C == C --> X <=u C (when C+1 is PowerOf2).
2189 define i1 @or1_eq1(i32 %x) {
2190 ; CHECK-LABEL: @or1_eq1(
2191 ; CHECK-NEXT:    [[T1:%.*]] = icmp ult i32 [[X:%.*]], 2
2192 ; CHECK-NEXT:    ret i1 [[T1]]
2194   %t0 = or i32 %x, 1
2195   %t1 = icmp eq i32 %t0, 1
2196   ret i1 %t1
2199 ; X | C == C --> X <=u C (when C+1 is PowerOf2).
2201 define <2 x i1> @or3_eq3_vec(<2 x i8> %x) {
2202 ; CHECK-LABEL: @or3_eq3_vec(
2203 ; CHECK-NEXT:    [[T1:%.*]] = icmp ult <2 x i8> [[X:%.*]], <i8 4, i8 4>
2204 ; CHECK-NEXT:    ret <2 x i1> [[T1]]
2206   %t0 = or <2 x i8> %x, <i8 3, i8 3>
2207   %t1 = icmp eq <2 x i8> %t0, <i8 3, i8 3>
2208   ret <2 x i1> %t1
2211 ; X | C != C --> X >u C (when C+1 is PowerOf2).
2213 define i1 @or7_ne7(i32 %x) {
2214 ; CHECK-LABEL: @or7_ne7(
2215 ; CHECK-NEXT:    [[T1:%.*]] = icmp ugt i32 [[X:%.*]], 7
2216 ; CHECK-NEXT:    ret i1 [[T1]]
2218   %t0 = or i32 %x, 7
2219   %t1 = icmp ne i32 %t0, 7
2220   ret i1 %t1
2223 ; X | C != C --> X >u C (when C+1 is PowerOf2).
2225 define <2 x i1> @or63_ne63_vec(<2 x i8> %x) {
2226 ; CHECK-LABEL: @or63_ne63_vec(
2227 ; CHECK-NEXT:    [[T1:%.*]] = icmp ugt <2 x i8> [[X:%.*]], <i8 63, i8 63>
2228 ; CHECK-NEXT:    ret <2 x i1> [[T1]]
2230   %t0 = or <2 x i8> %x, <i8 63, i8 63>
2231   %t1 = icmp ne <2 x i8> %t0, <i8 63, i8 63>
2232   ret <2 x i1> %t1
2235 ; PR40611: https://bugs.llvm.org/show_bug.cgi?id=40611
2236 ; X | C == C --> (X & ~C) == 0
2238 define i1 @orC_eqC(i32 %x) {
2239 ; CHECK-LABEL: @orC_eqC(
2240 ; CHECK-NEXT:    [[TMP1:%.*]] = and i32 [[X:%.*]], -43
2241 ; CHECK-NEXT:    [[T1:%.*]] = icmp eq i32 [[TMP1]], 0
2242 ; CHECK-NEXT:    ret i1 [[T1]]
2244   %t0 = or i32 %x, 42
2245   %t1 = icmp eq i32 %t0, 42
2246   ret i1 %t1
2249 ; X | C == C --> (X & ~C) == 0
2251 define <2 x i1> @orC_eqC_vec(<2 x i8> %x) {
2252 ; CHECK-LABEL: @orC_eqC_vec(
2253 ; CHECK-NEXT:    [[TMP1:%.*]] = and <2 x i8> [[X:%.*]], <i8 -44, i8 -44>
2254 ; CHECK-NEXT:    [[T1:%.*]] = icmp eq <2 x i8> [[TMP1]], zeroinitializer
2255 ; CHECK-NEXT:    ret <2 x i1> [[T1]]
2257   %t0 = or <2 x i8> %x, <i8 43, i8 43>
2258   %t1 = icmp eq <2 x i8> %t0, <i8 43, i8 43>
2259   ret <2 x i1> %t1
2262 ; X | C != C --> (X & ~C) != 0
2264 define i1 @orC_neC(i32 %x) {
2265 ; CHECK-LABEL: @orC_neC(
2266 ; CHECK-NEXT:    [[TMP1:%.*]] = and i32 [[X:%.*]], 41
2267 ; CHECK-NEXT:    [[T1:%.*]] = icmp ne i32 [[TMP1]], 0
2268 ; CHECK-NEXT:    ret i1 [[T1]]
2270   %t0 = or i32 %x, -42
2271   %t1 = icmp ne i32 %t0, -42
2272   ret i1 %t1
2275 ; X | C != C --> (X & ~C) != 0
2277 define <2 x i1> @orC_neC_vec(<2 x i8> %x) {
2278 ; CHECK-LABEL: @orC_neC_vec(
2279 ; CHECK-NEXT:    [[TMP1:%.*]] = and <2 x i8> [[X:%.*]], <i8 42, i8 42>
2280 ; CHECK-NEXT:    [[T1:%.*]] = icmp ne <2 x i8> [[TMP1]], zeroinitializer
2281 ; CHECK-NEXT:    ret <2 x i1> [[T1]]
2283   %t0 = or <2 x i8> %x, <i8 -43, i8 -43>
2284   %t1 = icmp ne <2 x i8> %t0, <i8 -43, i8 -43>
2285   ret <2 x i1> %t1
2288 define i1 @shrink_constant(i32 %X) {
2289 ; CHECK-LABEL: @shrink_constant(
2290 ; CHECK-NEXT:    [[XOR:%.*]] = xor i32 [[X:%.*]], -12
2291 ; CHECK-NEXT:    [[CMP:%.*]] = icmp ult i32 [[XOR]], 4
2292 ; CHECK-NEXT:    ret i1 [[CMP]]
2294   %xor = xor i32 %X, -9
2295   %cmp = icmp ult i32 %xor, 4
2296   ret i1 %cmp
2299 define <2 x i1> @shrink_constant_vec(<2 x i32> %X) {
2300 ; CHECK-LABEL: @shrink_constant_vec(
2301 ; CHECK-NEXT:    [[XOR:%.*]] = xor <2 x i32> [[X:%.*]], <i32 -12, i32 -12>
2302 ; CHECK-NEXT:    [[CMP:%.*]] = icmp ult <2 x i32> [[XOR]], <i32 4, i32 4>
2303 ; CHECK-NEXT:    ret <2 x i1> [[CMP]]
2305   %xor = xor <2 x i32> %X, <i32 -9, i32 -9>
2306   %cmp = icmp ult <2 x i32> %xor, <i32 4, i32 4>
2307   ret <2 x i1> %cmp
2310 ; This test requires 3 different transforms to get to the result.
2311 define i1 @icmp_sub_-1_X_ult_4(i32 %X) {
2312 ; CHECK-LABEL: @icmp_sub_-1_X_ult_4(
2313 ; CHECK-NEXT:    [[CMP:%.*]] = icmp ugt i32 [[X:%.*]], -5
2314 ; CHECK-NEXT:    ret i1 [[CMP]]
2316   %sub = sub i32 -1, %X
2317   %cmp = icmp ult i32 %sub, 4
2318   ret i1 %cmp
2321 define <2 x i1> @icmp_xor_neg4_X_ult_4_vec(<2 x i32> %X) {
2322 ; CHECK-LABEL: @icmp_xor_neg4_X_ult_4_vec(
2323 ; CHECK-NEXT:    [[CMP:%.*]] = icmp ugt <2 x i32> [[X:%.*]], <i32 -5, i32 -5>
2324 ; CHECK-NEXT:    ret <2 x i1> [[CMP]]
2326   %xor = xor <2 x i32> %X, <i32 -4, i32 -4>
2327   %cmp = icmp ult <2 x i32> %xor, <i32 4, i32 4>
2328   ret <2 x i1> %cmp
2331 define i1 @icmp_sub_-1_X_uge_4(i32 %X) {
2332 ; CHECK-LABEL: @icmp_sub_-1_X_uge_4(
2333 ; CHECK-NEXT:    [[CMP:%.*]] = icmp ult i32 [[X:%.*]], -4
2334 ; CHECK-NEXT:    ret i1 [[CMP]]
2336   %sub = sub i32 -1, %X
2337   %cmp = icmp uge i32 %sub, 4
2338   ret i1 %cmp
2341 define <2 x i1> @icmp_xor_neg4_X_uge_4_vec(<2 x i32> %X) {
2342 ; CHECK-LABEL: @icmp_xor_neg4_X_uge_4_vec(
2343 ; CHECK-NEXT:    [[CMP:%.*]] = icmp ult <2 x i32> [[X:%.*]], <i32 -4, i32 -4>
2344 ; CHECK-NEXT:    ret <2 x i1> [[CMP]]
2346   %xor = xor <2 x i32> %X, <i32 -4, i32 -4>
2347   %cmp = icmp uge <2 x i32> %xor, <i32 4, i32 4>
2348   ret <2 x i1> %cmp
2351 define <2 x i1> @xor_ult(<2 x i8> %x) {
2352 ; CHECK-LABEL: @xor_ult(
2353 ; CHECK-NEXT:    [[R:%.*]] = icmp ugt <2 x i8> [[X:%.*]], <i8 3, i8 3>
2354 ; CHECK-NEXT:    ret <2 x i1> [[R]]
2356   %xor = xor <2 x i8> %x, <i8 -4, i8 -4>
2357   %r = icmp ult <2 x i8> %xor, <i8 -4, i8 -4>
2358   ret <2 x i1> %r
2361 define i1 @xor_ult_extra_use(i8 %x, i8* %p) {
2362 ; CHECK-LABEL: @xor_ult_extra_use(
2363 ; CHECK-NEXT:    [[XOR:%.*]] = xor i8 [[X:%.*]], -32
2364 ; CHECK-NEXT:    store i8 [[XOR]], i8* [[P:%.*]], align 1
2365 ; CHECK-NEXT:    [[R:%.*]] = icmp ugt i8 [[X]], 31
2366 ; CHECK-NEXT:    ret i1 [[R]]
2368   %xor = xor i8 %x, -32
2369   store i8 %xor, i8* %p
2370   %r = icmp ult i8 %xor, -32
2371   ret i1 %r
2374 define <2 x i1> @xor_ugt(<2 x i8> %x) {
2375 ; CHECK-LABEL: @xor_ugt(
2376 ; CHECK-NEXT:    [[R:%.*]] = icmp ugt <2 x i8> [[X:%.*]], <i8 7, i8 7>
2377 ; CHECK-NEXT:    ret <2 x i1> [[R]]
2379   %xor = xor <2 x i8> %x, <i8 7, i8 7>
2380   %r = icmp ugt <2 x i8> %xor, <i8 7, i8 7>
2381   ret <2 x i1> %r
2384 define i1 @xor_ugt_extra_use(i8 %x, i8* %p) {
2385 ; CHECK-LABEL: @xor_ugt_extra_use(
2386 ; CHECK-NEXT:    [[XOR:%.*]] = xor i8 [[X:%.*]], 63
2387 ; CHECK-NEXT:    store i8 [[XOR]], i8* [[P:%.*]], align 1
2388 ; CHECK-NEXT:    [[R:%.*]] = icmp ugt i8 [[X]], 63
2389 ; CHECK-NEXT:    ret i1 [[R]]
2391   %xor = xor i8 %x, 63
2392   store i8 %xor, i8* %p
2393   %r = icmp ugt i8 %xor, 63
2394   ret i1 %r
2397 define i1 @icmp_swap_operands_for_cse(i32 %X, i32 %Y) {
2398 ; CHECK-LABEL: @icmp_swap_operands_for_cse(
2399 ; CHECK-NEXT:  entry:
2400 ; CHECK-NEXT:    [[SUB:%.*]] = sub i32 [[X:%.*]], [[Y:%.*]]
2401 ; CHECK-NEXT:    [[CMP:%.*]] = icmp ult i32 [[X]], [[Y]]
2402 ; CHECK-NEXT:    br i1 [[CMP]], label [[TRUE:%.*]], label [[FALSE:%.*]]
2403 ; CHECK:       true:
2404 ; CHECK-NEXT:    [[TMP0:%.*]] = and i32 [[SUB]], 1
2405 ; CHECK-NEXT:    br label [[END:%.*]]
2406 ; CHECK:       false:
2407 ; CHECK-NEXT:    [[TMP1:%.*]] = and i32 [[SUB]], 16
2408 ; CHECK-NEXT:    br label [[END]]
2409 ; CHECK:       end:
2410 ; CHECK-NEXT:    [[RES_IN:%.*]] = phi i32 [ [[TMP0]], [[TRUE]] ], [ [[TMP1]], [[FALSE]] ]
2411 ; CHECK-NEXT:    [[RES:%.*]] = icmp ne i32 [[RES_IN]], 0
2412 ; CHECK-NEXT:    ret i1 [[RES]]
2414 entry:
2415   %sub = sub i32 %X, %Y
2416   %cmp = icmp ugt i32 %Y, %X
2417   br i1 %cmp, label %true, label %false
2418 true:
2419   %restrue = trunc i32 %sub to i1
2420   br label %end
2421 false:
2422   %shift = lshr i32 %sub, 4
2423   %resfalse = trunc i32 %shift to i1
2424   br label %end
2425 end:
2426   %res = phi i1 [%restrue, %true], [%resfalse, %false]
2427   ret i1 %res
2430 define i1 @icmp_swap_operands_for_cse2(i32 %X, i32 %Y) {
2431 ; CHECK-LABEL: @icmp_swap_operands_for_cse2(
2432 ; CHECK-NEXT:  entry:
2433 ; CHECK-NEXT:    [[CMP:%.*]] = icmp ult i32 [[X:%.*]], [[Y:%.*]]
2434 ; CHECK-NEXT:    br i1 [[CMP]], label [[TRUE:%.*]], label [[FALSE:%.*]]
2435 ; CHECK:       true:
2436 ; CHECK-NEXT:    [[SUB:%.*]] = sub i32 [[X]], [[Y]]
2437 ; CHECK-NEXT:    [[SUB1:%.*]] = sub i32 [[X]], [[Y]]
2438 ; CHECK-NEXT:    [[ADD:%.*]] = add i32 [[SUB]], [[SUB1]]
2439 ; CHECK-NEXT:    br label [[END:%.*]]
2440 ; CHECK:       false:
2441 ; CHECK-NEXT:    [[SUB2:%.*]] = sub i32 [[Y]], [[X]]
2442 ; CHECK-NEXT:    br label [[END]]
2443 ; CHECK:       end:
2444 ; CHECK-NEXT:    [[RES_IN_IN:%.*]] = phi i32 [ [[ADD]], [[TRUE]] ], [ [[SUB2]], [[FALSE]] ]
2445 ; CHECK-NEXT:    [[RES_IN:%.*]] = and i32 [[RES_IN_IN]], 1
2446 ; CHECK-NEXT:    [[RES:%.*]] = icmp ne i32 [[RES_IN]], 0
2447 ; CHECK-NEXT:    ret i1 [[RES]]
2449 entry:
2450   %cmp = icmp ugt i32 %Y, %X
2451   br i1 %cmp, label %true, label %false
2452 true:
2453   %sub = sub i32 %X, %Y
2454   %sub1 = sub i32 %X, %Y
2455   %add = add i32 %sub, %sub1
2456   %restrue = trunc i32 %add to i1
2457   br label %end
2458 false:
2459   %sub2 = sub i32 %Y, %X
2460   %resfalse = trunc i32 %sub2 to i1
2461   br label %end
2462 end:
2463   %res = phi i1 [%restrue, %true], [%resfalse, %false]
2464   ret i1 %res
2467 define i1 @icmp_do_not_swap_operands_for_cse(i32 %X, i32 %Y) {
2468 ; CHECK-LABEL: @icmp_do_not_swap_operands_for_cse(
2469 ; CHECK-NEXT:  entry:
2470 ; CHECK-NEXT:    [[CMP:%.*]] = icmp ugt i32 [[Y:%.*]], [[X:%.*]]
2471 ; CHECK-NEXT:    br i1 [[CMP]], label [[TRUE:%.*]], label [[FALSE:%.*]]
2472 ; CHECK:       true:
2473 ; CHECK-NEXT:    [[SUB:%.*]] = sub i32 [[X]], [[Y]]
2474 ; CHECK-NEXT:    br label [[END:%.*]]
2475 ; CHECK:       false:
2476 ; CHECK-NEXT:    [[SUB2:%.*]] = sub i32 [[Y]], [[X]]
2477 ; CHECK-NEXT:    br label [[END]]
2478 ; CHECK:       end:
2479 ; CHECK-NEXT:    [[RES_IN_IN:%.*]] = phi i32 [ [[SUB]], [[TRUE]] ], [ [[SUB2]], [[FALSE]] ]
2480 ; CHECK-NEXT:    [[RES_IN:%.*]] = and i32 [[RES_IN_IN]], 1
2481 ; CHECK-NEXT:    [[RES:%.*]] = icmp ne i32 [[RES_IN]], 0
2482 ; CHECK-NEXT:    ret i1 [[RES]]
2484 entry:
2485   %cmp = icmp ugt i32 %Y, %X
2486   br i1 %cmp, label %true, label %false
2487 true:
2488   %sub = sub i32 %X, %Y
2489   %restrue = trunc i32 %sub to i1
2490   br label %end
2491 false:
2492   %sub2 = sub i32 %Y, %X
2493   %resfalse = trunc i32 %sub2 to i1
2494   br label %end
2495 end:
2496   %res = phi i1 [%restrue, %true], [%resfalse, %false]
2497   ret i1 %res
2500 define i1 @icmp_lshr_lshr_eq(i32 %a, i32 %b) {
2501 ; CHECK-LABEL: @icmp_lshr_lshr_eq(
2502 ; CHECK-NEXT:    [[Z_UNSHIFTED:%.*]] = xor i32 [[A:%.*]], [[B:%.*]]
2503 ; CHECK-NEXT:    [[Z:%.*]] = icmp ult i32 [[Z_UNSHIFTED]], 1073741824
2504 ; CHECK-NEXT:    ret i1 [[Z]]
2506   %x = lshr i32 %a, 30
2507   %y = lshr i32 %b, 30
2508   %z = icmp eq i32 %x, %y
2509   ret i1 %z
2512 define i1 @icmp_ashr_ashr_ne(i32 %a, i32 %b) {
2513 ; CHECK-LABEL: @icmp_ashr_ashr_ne(
2514 ; CHECK-NEXT:    [[Z_UNSHIFTED:%.*]] = xor i32 [[A:%.*]], [[B:%.*]]
2515 ; CHECK-NEXT:    [[Z:%.*]] = icmp ugt i32 [[Z_UNSHIFTED]], 255
2516 ; CHECK-NEXT:    ret i1 [[Z]]
2518   %x = ashr i32 %a, 8
2519   %y = ashr i32 %b, 8
2520   %z = icmp ne i32 %x, %y
2521   ret i1 %z
2524 define i1 @icmp_neg_cst_slt(i32 %a) {
2525 ; CHECK-LABEL: @icmp_neg_cst_slt(
2526 ; CHECK-NEXT:    [[TMP1:%.*]] = icmp sgt i32 [[A:%.*]], 10
2527 ; CHECK-NEXT:    ret i1 [[TMP1]]
2529   %1 = sub nsw i32 0, %a
2530   %2 = icmp slt i32 %1, -10
2531   ret i1 %2
2534 define i1 @icmp_and_or_lshr(i32 %x, i32 %y) {
2535 ; CHECK-LABEL: @icmp_and_or_lshr(
2536 ; CHECK-NEXT:    [[SHF1:%.*]] = shl nuw i32 1, [[Y:%.*]]
2537 ; CHECK-NEXT:    [[OR2:%.*]] = or i32 [[SHF1]], 1
2538 ; CHECK-NEXT:    [[AND3:%.*]] = and i32 [[OR2]], [[X:%.*]]
2539 ; CHECK-NEXT:    [[RET:%.*]] = icmp ne i32 [[AND3]], 0
2540 ; CHECK-NEXT:    ret i1 [[RET]]
2542   %shf = lshr i32 %x, %y
2543   %or = or i32 %shf, %x
2544   %and = and i32 %or, 1
2545   %ret = icmp ne i32 %and, 0
2546   ret i1 %ret
2549 define <2 x i1> @icmp_and_or_lshr_vec(<2 x i32> %x, <2 x i32> %y) {
2550 ; CHECK-LABEL: @icmp_and_or_lshr_vec(
2551 ; CHECK-NEXT:    [[SHF:%.*]] = lshr <2 x i32> [[X:%.*]], [[Y:%.*]]
2552 ; CHECK-NEXT:    [[OR:%.*]] = or <2 x i32> [[SHF]], [[X]]
2553 ; CHECK-NEXT:    [[RET:%.*]] = trunc <2 x i32> [[OR]] to <2 x i1>
2554 ; CHECK-NEXT:    ret <2 x i1> [[RET]]
2556   %shf = lshr <2 x i32> %x, %y
2557   %or = or <2 x i32> %shf, %x
2558   %and = and <2 x i32> %or, <i32 1, i32 1>
2559   %ret = icmp ne <2 x i32> %and, zeroinitializer
2560   ret <2 x i1> %ret
2563 define <2 x i1> @icmp_and_or_lshr_vec_commute(<2 x i32> %xp, <2 x i32> %y) {
2564 ; CHECK-LABEL: @icmp_and_or_lshr_vec_commute(
2565 ; CHECK-NEXT:    [[X:%.*]] = srem <2 x i32> [[XP:%.*]], <i32 42, i32 42>
2566 ; CHECK-NEXT:    [[SHF:%.*]] = lshr <2 x i32> [[X]], [[Y:%.*]]
2567 ; CHECK-NEXT:    [[OR:%.*]] = or <2 x i32> [[X]], [[SHF]]
2568 ; CHECK-NEXT:    [[RET:%.*]] = trunc <2 x i32> [[OR]] to <2 x i1>
2569 ; CHECK-NEXT:    ret <2 x i1> [[RET]]
2571   %x = srem <2 x i32> %xp, <i32 42, i32 -42> ; prevent complexity-based canonicalization
2572   %shf = lshr <2 x i32> %x, %y
2573   %or = or <2 x i32> %x, %shf
2574   %and = and <2 x i32> %or, <i32 1, i32 1>
2575   %ret = icmp ne <2 x i32> %and, zeroinitializer
2576   ret <2 x i1> %ret
2579 define i1 @icmp_and_or_lshr_cst(i32 %x) {
2580 ; CHECK-LABEL: @icmp_and_or_lshr_cst(
2581 ; CHECK-NEXT:    [[AND1:%.*]] = and i32 [[X:%.*]], 3
2582 ; CHECK-NEXT:    [[RET:%.*]] = icmp ne i32 [[AND1]], 0
2583 ; CHECK-NEXT:    ret i1 [[RET]]
2585   %shf = lshr i32 %x, 1
2586   %or = or i32 %shf, %x
2587   %and = and i32 %or, 1
2588   %ret = icmp ne i32 %and, 0
2589   ret i1 %ret
2592 define <2 x i1> @icmp_and_or_lshr_cst_vec(<2 x i32> %x) {
2593 ; CHECK-LABEL: @icmp_and_or_lshr_cst_vec(
2594 ; CHECK-NEXT:    [[TMP1:%.*]] = and <2 x i32> [[X:%.*]], <i32 3, i32 3>
2595 ; CHECK-NEXT:    [[RET:%.*]] = icmp ne <2 x i32> [[TMP1]], zeroinitializer
2596 ; CHECK-NEXT:    ret <2 x i1> [[RET]]
2598   %shf = lshr <2 x i32> %x, <i32 1, i32 1>
2599   %or = or <2 x i32> %shf, %x
2600   %and = and <2 x i32> %or, <i32 1, i32 1>
2601   %ret = icmp ne <2 x i32> %and, zeroinitializer
2602   ret <2 x i1> %ret
2605 define <2 x i1> @icmp_and_or_lshr_cst_vec_commute(<2 x i32> %xp) {
2606 ; CHECK-LABEL: @icmp_and_or_lshr_cst_vec_commute(
2607 ; CHECK-NEXT:    [[X:%.*]] = srem <2 x i32> [[XP:%.*]], <i32 42, i32 42>
2608 ; CHECK-NEXT:    [[TMP1:%.*]] = and <2 x i32> [[X]], <i32 3, i32 3>
2609 ; CHECK-NEXT:    [[RET:%.*]] = icmp ne <2 x i32> [[TMP1]], zeroinitializer
2610 ; CHECK-NEXT:    ret <2 x i1> [[RET]]
2612   %x = srem <2 x i32> %xp, <i32 42, i32 -42> ; prevent complexity-based canonicalization
2613   %shf = lshr <2 x i32> %x, <i32 1, i32 1>
2614   %or = or <2 x i32> %x, %shf
2615   %and = and <2 x i32> %or, <i32 1, i32 1>
2616   %ret = icmp ne <2 x i32> %and, zeroinitializer
2617   ret <2 x i1> %ret
2620 define i1 @shl_ap1_zero_ap2_non_zero_2(i32 %a) {
2621 ; CHECK-LABEL: @shl_ap1_zero_ap2_non_zero_2(
2622 ; CHECK-NEXT:    [[CMP:%.*]] = icmp ugt i32 [[A:%.*]], 29
2623 ; CHECK-NEXT:    ret i1 [[CMP]]
2625   %shl = shl i32 4, %a
2626   %cmp = icmp eq i32 %shl, 0
2627   ret i1 %cmp
2630 define <2 x i1> @shl_ap1_zero_ap2_non_zero_2_vec(<2 x i32> %a) {
2631 ; CHECK-LABEL: @shl_ap1_zero_ap2_non_zero_2_vec(
2632 ; CHECK-NEXT:    [[CMP:%.*]] = icmp ugt <2 x i32> [[A:%.*]], <i32 29, i32 29>
2633 ; CHECK-NEXT:    ret <2 x i1> [[CMP]]
2635   %shl = shl <2 x i32> <i32 4, i32 4>, %a
2636   %cmp = icmp eq <2 x i32> %shl, zeroinitializer
2637   ret <2 x i1> %cmp
2640 define i1 @shl_ap1_zero_ap2_non_zero_4(i32 %a) {
2641 ; CHECK-LABEL: @shl_ap1_zero_ap2_non_zero_4(
2642 ; CHECK-NEXT:    [[CMP:%.*]] = icmp ugt i32 [[A:%.*]], 30
2643 ; CHECK-NEXT:    ret i1 [[CMP]]
2645   %shl = shl i32 -2, %a
2646   %cmp = icmp eq i32 %shl, 0
2647   ret i1 %cmp
2650 define i1 @shl_ap1_non_zero_ap2_non_zero_both_positive(i32 %a) {
2651 ; CHECK-LABEL: @shl_ap1_non_zero_ap2_non_zero_both_positive(
2652 ; CHECK-NEXT:    [[CMP:%.*]] = icmp eq i32 [[A:%.*]], 0
2653 ; CHECK-NEXT:    ret i1 [[CMP]]
2655   %shl = shl i32 50, %a
2656   %cmp = icmp eq i32 %shl, 50
2657   ret i1 %cmp
2660 define i1 @shl_ap1_non_zero_ap2_non_zero_both_negative(i32 %a) {
2661 ; CHECK-LABEL: @shl_ap1_non_zero_ap2_non_zero_both_negative(
2662 ; CHECK-NEXT:    [[CMP:%.*]] = icmp eq i32 [[A:%.*]], 0
2663 ; CHECK-NEXT:    ret i1 [[CMP]]
2665   %shl = shl i32 -50, %a
2666   %cmp = icmp eq i32 %shl, -50
2667   ret i1 %cmp
2670 define i1 @shl_ap1_non_zero_ap2_non_zero_ap1_1(i32 %a) {
2671 ; CHECK-LABEL: @shl_ap1_non_zero_ap2_non_zero_ap1_1(
2672 ; CHECK-NEXT:    ret i1 false
2674   %shl = shl i32 50, %a
2675   %cmp = icmp eq i32 %shl, 25
2676   ret i1 %cmp
2679 define i1 @shl_ap1_non_zero_ap2_non_zero_ap1_2(i32 %a) {
2680 ; CHECK-LABEL: @shl_ap1_non_zero_ap2_non_zero_ap1_2(
2681 ; CHECK-NEXT:    [[CMP:%.*]] = icmp eq i32 [[A:%.*]], 1
2682 ; CHECK-NEXT:    ret i1 [[CMP]]
2684   %shl = shl i32 25, %a
2685   %cmp = icmp eq i32 %shl, 50
2686   ret i1 %cmp
2689 define i1 @shl_ap1_non_zero_ap2_non_zero_ap1_3(i32 %a) {
2690 ; CHECK-LABEL: @shl_ap1_non_zero_ap2_non_zero_ap1_3(
2691 ; CHECK-NEXT:    ret i1 false
2693   %shl = shl i32 26, %a
2694   %cmp = icmp eq i32 %shl, 50
2695   ret i1 %cmp
2698 define i1 @icmp_sgt_zero_add_nsw(i32 %a) {
2699 ; CHECK-LABEL: @icmp_sgt_zero_add_nsw(
2700 ; CHECK-NEXT:    [[CMP:%.*]] = icmp sgt i32 [[A:%.*]], -1
2701 ; CHECK-NEXT:    ret i1 [[CMP]]
2703   %add = add nsw i32 %a, 1
2704   %cmp = icmp sgt i32 %add, 0
2705   ret i1 %cmp
2708 define i1 @icmp_sge_zero_add_nsw(i32 %a) {
2709 ; CHECK-LABEL: @icmp_sge_zero_add_nsw(
2710 ; CHECK-NEXT:    [[CMP:%.*]] = icmp sgt i32 [[A:%.*]], -2
2711 ; CHECK-NEXT:    ret i1 [[CMP]]
2713   %add = add nsw i32 %a, 1
2714   %cmp = icmp sge i32 %add, 0
2715   ret i1 %cmp
2718 define i1 @icmp_sle_zero_add_nsw(i32 %a) {
2719 ; CHECK-LABEL: @icmp_sle_zero_add_nsw(
2720 ; CHECK-NEXT:    [[CMP:%.*]] = icmp slt i32 [[A:%.*]], 0
2721 ; CHECK-NEXT:    ret i1 [[CMP]]
2723   %add = add nsw i32 %a, 1
2724   %cmp = icmp sle i32 %add, 0
2725   ret i1 %cmp
2728 define zeroext i1 @icmp_cmpxchg_strong(i32* %sc, i32 %old_val, i32 %new_val) {
2729 ; CHECK-LABEL: @icmp_cmpxchg_strong(
2730 ; CHECK-NEXT:    [[XCHG:%.*]] = cmpxchg i32* [[SC:%.*]], i32 [[OLD_VAL:%.*]], i32 [[NEW_VAL:%.*]] seq_cst seq_cst
2731 ; CHECK-NEXT:    [[ICMP:%.*]] = extractvalue { i32, i1 } [[XCHG]], 1
2732 ; CHECK-NEXT:    ret i1 [[ICMP]]
2734   %xchg = cmpxchg i32* %sc, i32 %old_val, i32 %new_val seq_cst seq_cst
2735   %xtrc = extractvalue { i32, i1 } %xchg, 0
2736   %icmp = icmp eq i32 %xtrc, %old_val
2737   ret i1 %icmp
2740 define i1 @f1(i64 %a, i64 %b) {
2741 ; CHECK-LABEL: @f1(
2742 ; CHECK-NEXT:    [[V:%.*]] = icmp sge i64 [[A:%.*]], [[B:%.*]]
2743 ; CHECK-NEXT:    ret i1 [[V]]
2745   %t = sub nsw i64 %a, %b
2746   %v = icmp sge i64 %t, 0
2747   ret i1 %v
2750 define <2 x i1> @f1_vec(<2 x i64> %a, <2 x i64> %b) {
2751 ; CHECK-LABEL: @f1_vec(
2752 ; CHECK-NEXT:    [[V:%.*]] = icmp sge <2 x i64> [[A:%.*]], [[B:%.*]]
2753 ; CHECK-NEXT:    ret <2 x i1> [[V]]
2755   %t = sub nsw <2 x i64> %a, %b
2756   %v = icmp sgt <2 x i64> %t, <i64 -1, i64 -1>
2757   ret <2 x i1> %v
2760 define i1 @f2(i64 %a, i64 %b) {
2761 ; CHECK-LABEL: @f2(
2762 ; CHECK-NEXT:    [[V:%.*]] = icmp sgt i64 [[A:%.*]], [[B:%.*]]
2763 ; CHECK-NEXT:    ret i1 [[V]]
2765   %t = sub nsw i64 %a, %b
2766   %v = icmp sgt i64 %t, 0
2767   ret i1 %v
2770 define <2 x i1> @f2_vec(<2 x i64> %a, <2 x i64> %b) {
2771 ; CHECK-LABEL: @f2_vec(
2772 ; CHECK-NEXT:    [[V:%.*]] = icmp sgt <2 x i64> [[A:%.*]], [[B:%.*]]
2773 ; CHECK-NEXT:    ret <2 x i1> [[V]]
2775   %t = sub nsw <2 x i64> %a, %b
2776   %v = icmp sgt <2 x i64> %t, zeroinitializer
2777   ret <2 x i1> %v
2780 define i1 @f3(i64 %a, i64 %b) {
2781 ; CHECK-LABEL: @f3(
2782 ; CHECK-NEXT:    [[V:%.*]] = icmp slt i64 [[A:%.*]], [[B:%.*]]
2783 ; CHECK-NEXT:    ret i1 [[V]]
2785   %t = sub nsw i64 %a, %b
2786   %v = icmp slt i64 %t, 0
2787   ret i1 %v
2790 define <2 x i1> @f3_vec(<2 x i64> %a, <2 x i64> %b) {
2791 ; CHECK-LABEL: @f3_vec(
2792 ; CHECK-NEXT:    [[V:%.*]] = icmp slt <2 x i64> [[A:%.*]], [[B:%.*]]
2793 ; CHECK-NEXT:    ret <2 x i1> [[V]]
2795   %t = sub nsw <2 x i64> %a, %b
2796   %v = icmp slt <2 x i64> %t, zeroinitializer
2797   ret <2 x i1> %v
2800 define i1 @f4(i64 %a, i64 %b) {
2801 ; CHECK-LABEL: @f4(
2802 ; CHECK-NEXT:    [[V:%.*]] = icmp sle i64 [[A:%.*]], [[B:%.*]]
2803 ; CHECK-NEXT:    ret i1 [[V]]
2805   %t = sub nsw i64 %a, %b
2806   %v = icmp sle i64 %t, 0
2807   ret i1 %v
2810 define <2 x i1> @f4_vec(<2 x i64> %a, <2 x i64> %b) {
2811 ; CHECK-LABEL: @f4_vec(
2812 ; CHECK-NEXT:    [[V:%.*]] = icmp sle <2 x i64> [[A:%.*]], [[B:%.*]]
2813 ; CHECK-NEXT:    ret <2 x i1> [[V]]
2815   %t = sub nsw <2 x i64> %a, %b
2816   %v = icmp slt <2 x i64> %t, <i64 1, i64 1>
2817   ret <2 x i1> %v
2820 define i32 @f5(i8 %a, i8 %b) {
2821 ; CHECK-LABEL: @f5(
2822 ; CHECK-NEXT:    [[CONV:%.*]] = zext i8 [[A:%.*]] to i32
2823 ; CHECK-NEXT:    [[CONV3:%.*]] = zext i8 [[B:%.*]] to i32
2824 ; CHECK-NEXT:    [[SUB:%.*]] = sub nsw i32 [[CONV]], [[CONV3]]
2825 ; CHECK-NEXT:    [[CMP4:%.*]] = icmp slt i32 [[SUB]], 0
2826 ; CHECK-NEXT:    [[SUB7:%.*]] = sub nsw i32 0, [[SUB]]
2827 ; CHECK-NEXT:    [[SUB7_SUB:%.*]] = select i1 [[CMP4]], i32 [[SUB7]], i32 [[SUB]]
2828 ; CHECK-NEXT:    ret i32 [[SUB7_SUB]]
2830   %conv = zext i8 %a to i32
2831   %conv3 = zext i8 %b to i32
2832   %sub = sub nsw i32 %conv, %conv3
2833   %cmp4 = icmp slt i32 %sub, 0
2834   %sub7 = sub nsw i32 0, %sub
2835   %sub7.sub = select i1 %cmp4, i32 %sub7, i32 %sub
2836   ret i32 %sub7.sub
2839 define i32 @f6(i32 %a, i32 %b) {
2840 ; CHECK-LABEL: @f6(
2841 ; CHECK-NEXT:    [[CMP_UNSHIFTED:%.*]] = xor i32 [[A:%.*]], [[B:%.*]]
2842 ; CHECK-NEXT:    [[CMP_MASK:%.*]] = and i32 [[CMP_UNSHIFTED]], 255
2843 ; CHECK-NEXT:    [[CMP:%.*]] = icmp eq i32 [[CMP_MASK]], 0
2844 ; CHECK-NEXT:    [[S:%.*]] = select i1 [[CMP]], i32 10000, i32 0
2845 ; CHECK-NEXT:    ret i32 [[S]]
2847   %sext = shl i32 %a, 24
2848   %conv = ashr i32 %sext, 24
2849   %sext6 = shl i32 %b, 24
2850   %conv4 = ashr i32 %sext6, 24
2851   %cmp = icmp eq i32 %conv, %conv4
2852   %s = select i1 %cmp, i32 10000, i32 0
2853   ret i32 %s
2856 define i32 @f7(i32 %a, i32 %b) {
2857 ; CHECK-LABEL: @f7(
2858 ; CHECK-NEXT:    [[CMP_UNSHIFTED:%.*]] = xor i32 [[A:%.*]], [[B:%.*]]
2859 ; CHECK-NEXT:    [[CMP_MASK:%.*]] = and i32 [[CMP_UNSHIFTED]], 511
2860 ; CHECK-NEXT:    [[CMP:%.*]] = icmp eq i32 [[CMP_MASK]], 0
2861 ; CHECK-NEXT:    [[S:%.*]] = select i1 [[CMP]], i32 0, i32 10000
2862 ; CHECK-NEXT:    ret i32 [[S]]
2864   %sext = shl i32 %a, 23
2865   %sext6 = shl i32 %b, 23
2866   %cmp = icmp ne i32 %sext, %sext6
2867   %s = select i1 %cmp, i32 10000, i32 0
2868   ret i32 %s
2871 define i1 @f8(i32 %val, i32 %lim) {
2872 ; CHECK-LABEL: @f8(
2873 ; CHECK-NEXT:    [[R:%.*]] = icmp ne i32 [[LIM:%.*]], 0
2874 ; CHECK-NEXT:    ret i1 [[R]]
2876   %lim.sub = add i32 %lim, -1
2877   %val.and = and i32 %val, %lim.sub
2878   %r = icmp ult i32 %val.and, %lim
2879   ret i1 %r
2882 define i1 @f9(i32 %val, i32 %lim) {
2883 ; CHECK-LABEL: @f9(
2884 ; CHECK-NEXT:    [[R:%.*]] = icmp ne i32 [[LIM:%.*]], 0
2885 ; CHECK-NEXT:    ret i1 [[R]]
2887   %lim.sub = sub i32 %lim, 1
2888   %val.and = and i32 %val, %lim.sub
2889   %r = icmp ult i32 %val.and, %lim
2890   ret i1 %r
2893 define i1 @f10(i16 %p) {
2894 ; CHECK-LABEL: @f10(
2895 ; 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))
2896 ; CHECK-NEXT:    ret i1 [[CMP580]]
2898   %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
2899   ret i1 %cmp580
2902 ; Note: fptosi is used in various tests below to ensure that operand complexity
2903 ; canonicalization does not kick in, which would make some of the tests
2904 ; equivalent to one another.
2906 define i1 @cmp_sgt_rhs_dec(float %x, i32 %i) {
2907 ; CHECK-LABEL: @cmp_sgt_rhs_dec(
2908 ; CHECK-NEXT:    [[CONV:%.*]] = fptosi float [[X:%.*]] to i32
2909 ; CHECK-NEXT:    [[CMP:%.*]] = icmp sge i32 [[CONV]], [[I:%.*]]
2910 ; CHECK-NEXT:    ret i1 [[CMP]]
2912   %conv = fptosi float %x to i32
2913   %dec = sub nsw i32 %i, 1
2914   %cmp = icmp sgt i32 %conv, %dec
2915   ret i1 %cmp
2918 define i1 @cmp_sle_rhs_dec(float %x, i32 %i) {
2919 ; CHECK-LABEL: @cmp_sle_rhs_dec(
2920 ; CHECK-NEXT:    [[CONV:%.*]] = fptosi float [[X:%.*]] to i32
2921 ; CHECK-NEXT:    [[CMP:%.*]] = icmp slt i32 [[CONV]], [[I:%.*]]
2922 ; CHECK-NEXT:    ret i1 [[CMP]]
2924   %conv = fptosi float %x to i32
2925   %dec = sub nsw i32 %i, 1
2926   %cmp = icmp sle i32 %conv, %dec
2927   ret i1 %cmp
2930 define i1 @cmp_sge_rhs_inc(float %x, i32 %i) {
2931 ; CHECK-LABEL: @cmp_sge_rhs_inc(
2932 ; CHECK-NEXT:    [[CONV:%.*]] = fptosi float [[X:%.*]] to i32
2933 ; CHECK-NEXT:    [[CMP:%.*]] = icmp sgt i32 [[CONV]], [[I:%.*]]
2934 ; CHECK-NEXT:    ret i1 [[CMP]]
2936   %conv = fptosi float %x to i32
2937   %inc = add nsw i32 %i, 1
2938   %cmp = icmp sge i32 %conv, %inc
2939   ret i1 %cmp
2942 define i1 @cmp_slt_rhs_inc(float %x, i32 %i) {
2943 ; CHECK-LABEL: @cmp_slt_rhs_inc(
2944 ; CHECK-NEXT:    [[CONV:%.*]] = fptosi float [[X:%.*]] to i32
2945 ; CHECK-NEXT:    [[CMP:%.*]] = icmp sle i32 [[CONV]], [[I:%.*]]
2946 ; CHECK-NEXT:    ret i1 [[CMP]]
2948   %conv = fptosi float %x to i32
2949   %inc = add nsw i32 %i, 1
2950   %cmp = icmp slt i32 %conv, %inc
2951   ret i1 %cmp
2954 define i1 @PR26407(i32 %x, i32 %y) {
2955 ; CHECK-LABEL: @PR26407(
2956 ; CHECK-NEXT:    [[ADDX:%.*]] = add i32 [[X:%.*]], 2147483647
2957 ; CHECK-NEXT:    [[ADDY:%.*]] = add i32 [[Y:%.*]], 2147483647
2958 ; CHECK-NEXT:    [[CMP:%.*]] = icmp uge i32 [[ADDX]], [[ADDY]]
2959 ; CHECK-NEXT:    ret i1 [[CMP]]
2961   %addx = add i32 %x, 2147483647
2962   %addy = add i32 %y, 2147483647
2963   %cmp = icmp uge i32 %addx, %addy
2964   ret i1 %cmp
2967 define i1 @cmp_inverse_mask_bits_set_eq(i32 %x) {
2968 ; CHECK-LABEL: @cmp_inverse_mask_bits_set_eq(
2969 ; CHECK-NEXT:    [[TMP1:%.*]] = and i32 [[X:%.*]], -43
2970 ; CHECK-NEXT:    [[CMP:%.*]] = icmp eq i32 [[TMP1]], -43
2971 ; CHECK-NEXT:    ret i1 [[CMP]]
2973   %or = or i32 %x, 42
2974   %cmp = icmp eq i32 %or, -1
2975   ret i1 %cmp
2978 define <2 x i1> @cmp_inverse_mask_bits_set_eq_vec(<2 x i32> %x) {
2979 ; CHECK-LABEL: @cmp_inverse_mask_bits_set_eq_vec(
2980 ; CHECK-NEXT:    [[TMP1:%.*]] = and <2 x i32> [[X:%.*]], <i32 -43, i32 -43>
2981 ; CHECK-NEXT:    [[CMP:%.*]] = icmp eq <2 x i32> [[TMP1]], <i32 -43, i32 -43>
2982 ; CHECK-NEXT:    ret <2 x i1> [[CMP]]
2984   %or = or <2 x i32> %x, <i32 42, i32 42>
2985   %cmp = icmp eq <2 x i32> %or, <i32 -1, i32 -1>
2986   ret <2 x i1> %cmp
2989 define i1 @cmp_inverse_mask_bits_set_ne(i32 %x) {
2990 ; CHECK-LABEL: @cmp_inverse_mask_bits_set_ne(
2991 ; CHECK-NEXT:    [[TMP1:%.*]] = and i32 [[X:%.*]], -43
2992 ; CHECK-NEXT:    [[CMP:%.*]] = icmp ne i32 [[TMP1]], -43
2993 ; CHECK-NEXT:    ret i1 [[CMP]]
2995   %or = or i32 %x, 42
2996   %cmp = icmp ne i32 %or, -1
2997   ret i1 %cmp
3000 ; When canonicalizing to 'gt/lt', make sure the constant is correct.
3002 define i1 @PR27792(i128 %a) {
3003 ; CHECK-LABEL: @PR27792(
3004 ; CHECK-NEXT:    [[CMP:%.*]] = icmp sgt i128 [[A:%.*]], -1
3005 ; CHECK-NEXT:    ret i1 [[CMP]]
3007   %cmp = icmp sge i128 %a, 0
3008   ret i1 %cmp
3011 define i1 @PR27792_2(i128 %a) {
3012 ; CHECK-LABEL: @PR27792_2(
3013 ; CHECK-NEXT:    [[B:%.*]] = icmp ne i128 [[A:%.*]], 0
3014 ; CHECK-NEXT:    ret i1 [[B]]
3016   %b = icmp uge i128 %a, 1
3017   ret i1 %b
3020 define i1 @ugtMaxSignedVal(i8 %a) {
3021 ; CHECK-LABEL: @ugtMaxSignedVal(
3022 ; CHECK-NEXT:    [[CMP:%.*]] = icmp slt i8 [[A:%.*]], 0
3023 ; CHECK-NEXT:    ret i1 [[CMP]]
3025   %cmp = icmp ugt i8 %a, 127
3026   ret i1 %cmp
3029 define <2 x i1> @ugtMaxSignedValVec(<2 x i8> %a) {
3030 ; CHECK-LABEL: @ugtMaxSignedValVec(
3031 ; CHECK-NEXT:    [[CMP:%.*]] = icmp slt <2 x i8> [[A:%.*]], zeroinitializer
3032 ; CHECK-NEXT:    ret <2 x i1> [[CMP]]
3034   %cmp = icmp ugt <2 x i8> %a, <i8 127, i8 127>
3035   ret <2 x i1> %cmp
3038 define i1 @ugtKnownBits(i8 %a) {
3039 ; CHECK-LABEL: @ugtKnownBits(
3040 ; CHECK-NEXT:    [[B:%.*]] = and i8 [[A:%.*]], 17
3041 ; CHECK-NEXT:    [[CMP:%.*]] = icmp eq i8 [[B]], 17
3042 ; CHECK-NEXT:    ret i1 [[CMP]]
3044   %b = and i8 %a, 17
3045   %cmp = icmp ugt i8 %b, 16
3046   ret i1 %cmp
3049 define <2 x i1> @ugtKnownBitsVec(<2 x i8> %a) {
3050 ; CHECK-LABEL: @ugtKnownBitsVec(
3051 ; CHECK-NEXT:    [[B:%.*]] = and <2 x i8> [[A:%.*]], <i8 17, i8 17>
3052 ; CHECK-NEXT:    [[CMP:%.*]] = icmp eq <2 x i8> [[B]], <i8 17, i8 17>
3053 ; CHECK-NEXT:    ret <2 x i1> [[CMP]]
3055   %b = and <2 x i8> %a, <i8 17, i8 17>
3056   %cmp = icmp ugt <2 x i8> %b, <i8 16, i8 16>
3057   ret <2 x i1> %cmp
3060 define i1 @or_ptrtoint_mismatch(i8* %p, i32* %q) {
3061 ; CHECK-LABEL: @or_ptrtoint_mismatch(
3062 ; CHECK-NEXT:    [[TMP1:%.*]] = icmp eq i8* [[P:%.*]], null
3063 ; CHECK-NEXT:    [[TMP2:%.*]] = icmp eq i32* [[Q:%.*]], null
3064 ; CHECK-NEXT:    [[B:%.*]] = and i1 [[TMP1]], [[TMP2]]
3065 ; CHECK-NEXT:    ret i1 [[B]]
3068   %pp = ptrtoint i8* %p to i64
3069   %qq = ptrtoint i32* %q to i64
3070   %o = or i64 %pp, %qq
3071   %b = icmp eq i64 %o, 0
3072   ret i1 %b
3075 define i1 @icmp_add1_ugt(i32 %x, i32 %y) {
3076 ; CHECK-LABEL: @icmp_add1_ugt(
3077 ; CHECK-NEXT:    [[CMP:%.*]] = icmp uge i32 [[X:%.*]], [[Y:%.*]]
3078 ; CHECK-NEXT:    ret i1 [[CMP]]
3080   %add = add nuw i32 %x, 1
3081   %cmp = icmp ugt i32 %add, %y
3082   ret i1 %cmp
3085 define i1 @icmp_add1_ule(i32 %x, i32 %y) {
3086 ; CHECK-LABEL: @icmp_add1_ule(
3087 ; CHECK-NEXT:    [[CMP:%.*]] = icmp ult i32 [[X:%.*]], [[Y:%.*]]
3088 ; CHECK-NEXT:    ret i1 [[CMP]]
3090   %add = add nuw i32 %x, 1
3091   %cmp = icmp ule i32 %add, %y
3092   ret i1 %cmp
3095 define i1 @cmp_uge_rhs_inc(float %x, i32 %i) {
3096 ; CHECK-LABEL: @cmp_uge_rhs_inc(
3097 ; CHECK-NEXT:    [[CONV:%.*]] = fptosi float [[X:%.*]] to i32
3098 ; CHECK-NEXT:    [[CMP:%.*]] = icmp ugt i32 [[CONV]], [[I:%.*]]
3099 ; CHECK-NEXT:    ret i1 [[CMP]]
3101   %conv = fptosi float %x to i32
3102   %inc = add nuw i32 %i, 1
3103   %cmp = icmp uge i32 %conv, %inc
3104   ret i1 %cmp
3107 define i1 @cmp_ult_rhs_inc(float %x, i32 %i) {
3108 ; CHECK-LABEL: @cmp_ult_rhs_inc(
3109 ; CHECK-NEXT:    [[CONV:%.*]] = fptosi float [[X:%.*]] to i32
3110 ; CHECK-NEXT:    [[CMP:%.*]] = icmp ule i32 [[CONV]], [[I:%.*]]
3111 ; CHECK-NEXT:    ret i1 [[CMP]]
3113   %conv = fptosi float %x to i32
3114   %inc = add nuw i32 %i, 1
3115   %cmp = icmp ult i32 %conv, %inc
3116   ret i1 %cmp
3119 define i1 @cmp_sge_lhs_inc(i32 %x, i32 %y) {
3120 ; CHECK-LABEL: @cmp_sge_lhs_inc(
3121 ; CHECK-NEXT:    [[INC:%.*]] = add nsw i32 [[X:%.*]], 1
3122 ; CHECK-NEXT:    [[CMP:%.*]] = icmp sge i32 [[INC]], [[Y:%.*]]
3123 ; CHECK-NEXT:    ret i1 [[CMP]]
3125   %inc = add nsw i32 %x, 1
3126   %cmp = icmp sge i32 %inc, %y
3127   ret i1 %cmp
3130 define i1 @cmp_uge_lhs_inc(i32 %x, i32 %y) {
3131 ; CHECK-LABEL: @cmp_uge_lhs_inc(
3132 ; CHECK-NEXT:    [[INC:%.*]] = add nuw i32 [[X:%.*]], 1
3133 ; CHECK-NEXT:    [[CMP:%.*]] = icmp uge i32 [[INC]], [[Y:%.*]]
3134 ; CHECK-NEXT:    ret i1 [[CMP]]
3136   %inc = add nuw i32 %x, 1
3137   %cmp = icmp uge i32 %inc, %y
3138   ret i1 %cmp
3141 define i1 @cmp_sgt_lhs_dec(i32 %x, i32 %y) {
3142 ; CHECK-LABEL: @cmp_sgt_lhs_dec(
3143 ; CHECK-NEXT:    [[DEC:%.*]] = add nsw i32 [[X:%.*]], -1
3144 ; CHECK-NEXT:    [[CMP:%.*]] = icmp sgt i32 [[DEC]], [[Y:%.*]]
3145 ; CHECK-NEXT:    ret i1 [[CMP]]
3147   %dec = sub nsw i32 %x, 1
3148   %cmp = icmp sgt i32 %dec, %y
3149   ret i1 %cmp
3152 define i1 @cmp_ugt_lhs_dec(i32 %x, i32 %y) {
3153 ; CHECK-LABEL: @cmp_ugt_lhs_dec(
3154 ; CHECK-NEXT:    [[DEC:%.*]] = add i32 [[X:%.*]], -1
3155 ; CHECK-NEXT:    [[CMP:%.*]] = icmp ugt i32 [[DEC]], [[Y:%.*]]
3156 ; CHECK-NEXT:    ret i1 [[CMP]]
3158   %dec = sub nuw i32 %x, 1
3159   %cmp = icmp ugt i32 %dec, %y
3160   ret i1 %cmp
3163 define i1 @cmp_sle_rhs_inc(float %x, i32 %y) {
3164 ; CHECK-LABEL: @cmp_sle_rhs_inc(
3165 ; CHECK-NEXT:    [[CONV:%.*]] = fptosi float [[X:%.*]] to i32
3166 ; CHECK-NEXT:    [[INC:%.*]] = add nsw i32 [[Y:%.*]], 1
3167 ; CHECK-NEXT:    [[CMP:%.*]] = icmp sge i32 [[INC]], [[CONV]]
3168 ; CHECK-NEXT:    ret i1 [[CMP]]
3170   %conv = fptosi float %x to i32
3171   %inc = add nsw i32 %y, 1
3172   %cmp = icmp sle i32 %conv, %inc
3173   ret i1 %cmp
3176 define i1 @cmp_ule_rhs_inc(float %x, i32 %y) {
3177 ; CHECK-LABEL: @cmp_ule_rhs_inc(
3178 ; CHECK-NEXT:    [[CONV:%.*]] = fptosi float [[X:%.*]] to i32
3179 ; CHECK-NEXT:    [[INC:%.*]] = add nuw i32 [[Y:%.*]], 1
3180 ; CHECK-NEXT:    [[CMP:%.*]] = icmp uge i32 [[INC]], [[CONV]]
3181 ; CHECK-NEXT:    ret i1 [[CMP]]
3183   %conv = fptosi float %x to i32
3184   %inc = add nuw i32 %y, 1
3185   %cmp = icmp ule i32 %conv, %inc
3186   ret i1 %cmp
3189 define i1 @cmp_slt_rhs_dec(float %x, i32 %y) {
3190 ; CHECK-LABEL: @cmp_slt_rhs_dec(
3191 ; CHECK-NEXT:    [[CONV:%.*]] = fptosi float [[X:%.*]] to i32
3192 ; CHECK-NEXT:    [[DEC:%.*]] = add nsw i32 [[Y:%.*]], -1
3193 ; CHECK-NEXT:    [[CMP:%.*]] = icmp sgt i32 [[DEC]], [[CONV]]
3194 ; CHECK-NEXT:    ret i1 [[CMP]]
3196   %conv = fptosi float %x to i32
3197   %dec = sub nsw i32 %y, 1
3198   %cmp = icmp slt i32 %conv, %dec
3199   ret i1 %cmp
3202 define i1 @cmp_ult_rhs_dec(float %x, i32 %y) {
3203 ; CHECK-LABEL: @cmp_ult_rhs_dec(
3204 ; CHECK-NEXT:    [[CONV:%.*]] = fptosi float [[X:%.*]] to i32
3205 ; CHECK-NEXT:    [[DEC:%.*]] = add i32 [[Y:%.*]], -1
3206 ; CHECK-NEXT:    [[CMP:%.*]] = icmp ugt i32 [[DEC]], [[CONV]]
3207 ; CHECK-NEXT:    ret i1 [[CMP]]
3209   %conv = fptosi float %x to i32
3210   %dec = sub nuw i32 %y, 1
3211   %cmp = icmp ult i32 %conv, %dec
3212   ret i1 %cmp
3215 define i1 @eq_add_constants(i32 %x, i32 %y) {
3216 ; CHECK-LABEL: @eq_add_constants(
3217 ; CHECK-NEXT:    [[C:%.*]] = icmp eq i32 [[X:%.*]], [[Y:%.*]]
3218 ; CHECK-NEXT:    ret i1 [[C]]
3220   %A = add i32 %x, 5
3221   %B = add i32 %y, 5
3222   %C = icmp eq i32 %A, %B
3223   ret i1 %C
3226 define i1 @eq_mul_constants(i32 %x, i32 %y) {
3227 ; CHECK-LABEL: @eq_mul_constants(
3228 ; CHECK-NEXT:    [[C:%.*]] = icmp eq i32 [[X:%.*]], [[Y:%.*]]
3229 ; CHECK-NEXT:    ret i1 [[C]]
3231   %A = mul i32 %x, 5
3232   %B = mul i32 %y, 5
3233   %C = icmp eq i32 %A, %B
3234   ret i1 %C
3237 define <2 x i1> @eq_mul_constants_splat(<2 x i32> %x, <2 x i32> %y) {
3238 ; CHECK-LABEL: @eq_mul_constants_splat(
3239 ; CHECK-NEXT:    [[C:%.*]] = icmp ne <2 x i32> [[X:%.*]], [[Y:%.*]]
3240 ; CHECK-NEXT:    ret <2 x i1> [[C]]
3242   %A = mul <2 x i32> %x, <i32 5, i32 5>
3243   %B = mul <2 x i32> %y, <i32 5, i32 5>
3244   %C = icmp ne <2 x i32> %A, %B
3245   ret <2 x i1> %C
3248 ; If the multiply constant has any trailing zero bits, we get something completely different.
3249 ; We mask off the high bits of each input and then convert:
3250 ; (X&Z) == (Y&Z) -> (X^Y) & Z == 0
3252 define i1 @eq_mul_constants_with_tz(i32 %x, i32 %y) {
3253 ; CHECK-LABEL: @eq_mul_constants_with_tz(
3254 ; CHECK-NEXT:    [[TMP1:%.*]] = xor i32 [[X:%.*]], [[Y:%.*]]
3255 ; CHECK-NEXT:    [[TMP2:%.*]] = and i32 [[TMP1]], 1073741823
3256 ; CHECK-NEXT:    [[C:%.*]] = icmp ne i32 [[TMP2]], 0
3257 ; CHECK-NEXT:    ret i1 [[C]]
3259   %A = mul i32 %x, 12
3260   %B = mul i32 %y, 12
3261   %C = icmp ne i32 %A, %B
3262   ret i1 %C
3265 define <2 x i1> @eq_mul_constants_with_tz_splat(<2 x i32> %x, <2 x i32> %y) {
3266 ; CHECK-LABEL: @eq_mul_constants_with_tz_splat(
3267 ; CHECK-NEXT:    [[TMP1:%.*]] = xor <2 x i32> [[X:%.*]], [[Y:%.*]]
3268 ; CHECK-NEXT:    [[TMP2:%.*]] = and <2 x i32> [[TMP1]], <i32 1073741823, i32 1073741823>
3269 ; CHECK-NEXT:    [[C:%.*]] = icmp eq <2 x i32> [[TMP2]], zeroinitializer
3270 ; CHECK-NEXT:    ret <2 x i1> [[C]]
3272   %A = mul <2 x i32> %x, <i32 12, i32 12>
3273   %B = mul <2 x i32> %y, <i32 12, i32 12>
3274   %C = icmp eq <2 x i32> %A, %B
3275   ret <2 x i1> %C
3278 declare i32 @llvm.bswap.i32(i32)
3280 define i1 @bswap_ne(i32 %x, i32 %y) {
3281 ; CHECK-LABEL: @bswap_ne(
3282 ; CHECK-NEXT:    [[CMP:%.*]] = icmp ne i32 [[X:%.*]], [[Y:%.*]]
3283 ; CHECK-NEXT:    ret i1 [[CMP]]
3285   %swapx = call i32 @llvm.bswap.i32(i32 %x)
3286   %swapy = call i32 @llvm.bswap.i32(i32 %y)
3287   %cmp = icmp ne i32 %swapx, %swapy
3288   ret i1 %cmp
3291 declare <8 x i16> @llvm.bswap.v8i16(<8 x i16>)
3293 define <8 x i1> @bswap_vec_eq(<8 x i16> %x, <8 x i16> %y) {
3294 ; CHECK-LABEL: @bswap_vec_eq(
3295 ; CHECK-NEXT:    [[CMP:%.*]] = icmp eq <8 x i16> [[X:%.*]], [[Y:%.*]]
3296 ; CHECK-NEXT:    ret <8 x i1> [[CMP]]
3298   %swapx = call <8 x i16> @llvm.bswap.v8i16(<8 x i16> %x)
3299   %swapy = call <8 x i16> @llvm.bswap.v8i16(<8 x i16> %y)
3300   %cmp = icmp eq <8 x i16> %swapx, %swapy
3301   ret <8 x i1> %cmp
3304 declare i64 @llvm.bitreverse.i64(i64)
3306 define i1 @bitreverse_eq(i64 %x, i64 %y) {
3307 ; CHECK-LABEL: @bitreverse_eq(
3308 ; CHECK-NEXT:    [[CMP:%.*]] = icmp eq i64 [[X:%.*]], [[Y:%.*]]
3309 ; CHECK-NEXT:    ret i1 [[CMP]]
3311   %revx = call i64 @llvm.bitreverse.i64(i64 %x)
3312   %revy = call i64 @llvm.bitreverse.i64(i64 %y)
3313   %cmp = icmp eq i64 %revx, %revy
3314   ret i1 %cmp
3317 declare <8 x i16> @llvm.bitreverse.v8i16(<8 x i16>)
3319 define <8 x i1> @bitreverse_vec_ne(<8 x i16> %x, <8 x i16> %y) {
3320 ; CHECK-LABEL: @bitreverse_vec_ne(
3321 ; CHECK-NEXT:    [[CMP:%.*]] = icmp ne <8 x i16> [[X:%.*]], [[Y:%.*]]
3322 ; CHECK-NEXT:    ret <8 x i1> [[CMP]]
3324   %revx = call <8 x i16> @llvm.bitreverse.v8i16(<8 x i16> %x)
3325   %revy = call <8 x i16> @llvm.bitreverse.v8i16(<8 x i16> %y)
3326   %cmp = icmp ne <8 x i16> %revx, %revy
3327   ret <8 x i1> %cmp
3330 ; These perform a comparison of a value known to be between 4 and 5 with a value between 5 and 7.
3331 ; They should all simplify to equality compares.
3332 define i1 @knownbits1(i8 %a, i8 %b) {
3333 ; CHECK-LABEL: @knownbits1(
3334 ; CHECK-NEXT:    [[A1:%.*]] = and i8 [[A:%.*]], 1
3335 ; CHECK-NEXT:    [[A2:%.*]] = or i8 [[A1]], 4
3336 ; CHECK-NEXT:    [[B1:%.*]] = and i8 [[B:%.*]], 2
3337 ; CHECK-NEXT:    [[B2:%.*]] = or i8 [[B1]], 5
3338 ; CHECK-NEXT:    [[C:%.*]] = icmp eq i8 [[A2]], [[B2]]
3339 ; CHECK-NEXT:    ret i1 [[C]]
3341   %a1 = and i8 %a, 5
3342   %a2 = or i8 %a1, 4
3343   %b1 = and i8 %b, 7
3344   %b2 = or i8 %b1, 5
3345   %c = icmp uge i8 %a2, %b2
3346   ret i1 %c
3349 define i1 @knownbits2(i8 %a, i8 %b) {
3350 ; CHECK-LABEL: @knownbits2(
3351 ; CHECK-NEXT:    [[A1:%.*]] = and i8 [[A:%.*]], 1
3352 ; CHECK-NEXT:    [[A2:%.*]] = or i8 [[A1]], 4
3353 ; CHECK-NEXT:    [[B1:%.*]] = and i8 [[B:%.*]], 2
3354 ; CHECK-NEXT:    [[B2:%.*]] = or i8 [[B1]], 5
3355 ; CHECK-NEXT:    [[C:%.*]] = icmp ne i8 [[A2]], [[B2]]
3356 ; CHECK-NEXT:    ret i1 [[C]]
3358   %a1 = and i8 %a, 5
3359   %a2 = or i8 %a1, 4
3360   %b1 = and i8 %b, 7
3361   %b2 = or i8 %b1, 5
3362   %c = icmp ult i8 %a2, %b2
3363   ret i1 %c
3366 define i1 @knownbits3(i8 %a, i8 %b) {
3367 ; CHECK-LABEL: @knownbits3(
3368 ; CHECK-NEXT:    [[A1:%.*]] = and i8 [[A:%.*]], 1
3369 ; CHECK-NEXT:    [[A2:%.*]] = or i8 [[A1]], 4
3370 ; CHECK-NEXT:    [[B1:%.*]] = and i8 [[B:%.*]], 2
3371 ; CHECK-NEXT:    [[B2:%.*]] = or i8 [[B1]], 5
3372 ; CHECK-NEXT:    [[C:%.*]] = icmp eq i8 [[B2]], [[A2]]
3373 ; CHECK-NEXT:    ret i1 [[C]]
3375   %a1 = and i8 %a, 5
3376   %a2 = or i8 %a1, 4
3377   %b1 = and i8 %b, 7
3378   %b2 = or i8 %b1, 5
3379   %c = icmp ule i8 %b2, %a2
3380   ret i1 %c
3383 define <2 x i1> @knownbits4(<2 x i8> %a, <2 x i8> %b) {
3384 ; CHECK-LABEL: @knownbits4(
3385 ; CHECK-NEXT:    [[A1:%.*]] = and <2 x i8> [[A:%.*]], <i8 1, i8 1>
3386 ; CHECK-NEXT:    [[A2:%.*]] = or <2 x i8> [[A1]], <i8 4, i8 4>
3387 ; CHECK-NEXT:    [[B1:%.*]] = and <2 x i8> [[B:%.*]], <i8 2, i8 2>
3388 ; CHECK-NEXT:    [[B2:%.*]] = or <2 x i8> [[B1]], <i8 5, i8 5>
3389 ; CHECK-NEXT:    [[C:%.*]] = icmp ne <2 x i8> [[B2]], [[A2]]
3390 ; CHECK-NEXT:    ret <2 x i1> [[C]]
3392   %a1 = and <2 x i8> %a, <i8 5, i8 5>
3393   %a2 = or <2 x i8> %a1, <i8 4, i8 4>
3394   %b1 = and <2 x i8> %b, <i8 7, i8 7>
3395   %b2 = or <2 x i8> %b1, <i8 5, i8 5>
3396   %c = icmp ugt <2 x i8> %b2, %a2
3397   ret <2 x i1> %c
3400 ; These are the signed versions of the above. One value is less than or equal to 5, but maybe negative.
3401 ; The other is known to be a value 5-7. These should simplify to equality comparisons.
3402 define i1 @knownbits5(i8 %a, i8 %b) {
3403 ; CHECK-LABEL: @knownbits5(
3404 ; CHECK-NEXT:    [[A1:%.*]] = and i8 [[A:%.*]], -127
3405 ; CHECK-NEXT:    [[A2:%.*]] = or i8 [[A1]], 4
3406 ; CHECK-NEXT:    [[B1:%.*]] = and i8 [[B:%.*]], 2
3407 ; CHECK-NEXT:    [[B2:%.*]] = or i8 [[B1]], 5
3408 ; CHECK-NEXT:    [[C:%.*]] = icmp eq i8 [[A2]], [[B2]]
3409 ; CHECK-NEXT:    ret i1 [[C]]
3411   %a1 = and i8 %a, 133
3412   %a2 = or i8 %a1, 4
3413   %b1 = and i8 %b, 7
3414   %b2 = or i8 %b1, 5
3415   %c = icmp sge i8 %a2, %b2
3416   ret i1 %c
3419 define i1 @knownbits6(i8 %a, i8 %b) {
3420 ; CHECK-LABEL: @knownbits6(
3421 ; CHECK-NEXT:    [[A1:%.*]] = and i8 [[A:%.*]], -127
3422 ; CHECK-NEXT:    [[A2:%.*]] = or i8 [[A1]], 4
3423 ; CHECK-NEXT:    [[B1:%.*]] = and i8 [[B:%.*]], 2
3424 ; CHECK-NEXT:    [[B2:%.*]] = or i8 [[B1]], 5
3425 ; CHECK-NEXT:    [[C:%.*]] = icmp ne i8 [[A2]], [[B2]]
3426 ; CHECK-NEXT:    ret i1 [[C]]
3428   %a1 = and i8 %a, 133
3429   %a2 = or i8 %a1, 4
3430   %b1 = and i8 %b, 7
3431   %b2 = or i8 %b1, 5
3432   %c = icmp slt i8 %a2, %b2
3433   ret i1 %c
3436 define <2 x i1> @knownbits7(<2 x i8> %a, <2 x i8> %b) {
3437 ; CHECK-LABEL: @knownbits7(
3438 ; CHECK-NEXT:    [[A1:%.*]] = and <2 x i8> [[A:%.*]], <i8 -127, i8 -127>
3439 ; CHECK-NEXT:    [[A2:%.*]] = or <2 x i8> [[A1]], <i8 4, i8 4>
3440 ; CHECK-NEXT:    [[B1:%.*]] = and <2 x i8> [[B:%.*]], <i8 2, i8 2>
3441 ; CHECK-NEXT:    [[B2:%.*]] = or <2 x i8> [[B1]], <i8 5, i8 5>
3442 ; CHECK-NEXT:    [[C:%.*]] = icmp eq <2 x i8> [[B2]], [[A2]]
3443 ; CHECK-NEXT:    ret <2 x i1> [[C]]
3445   %a1 = and <2 x i8> %a, <i8 133, i8 133>
3446   %a2 = or <2 x i8> %a1, <i8 4, i8 4>
3447   %b1 = and <2 x i8> %b, <i8 7, i8 7>
3448   %b2 = or <2 x i8> %b1, <i8 5, i8 5>
3449   %c = icmp sle <2 x i8> %b2, %a2
3450   ret <2 x i1> %c
3453 define i1 @knownbits8(i8 %a, i8 %b) {
3454 ; CHECK-LABEL: @knownbits8(
3455 ; CHECK-NEXT:    [[A1:%.*]] = and i8 [[A:%.*]], -127
3456 ; CHECK-NEXT:    [[A2:%.*]] = or i8 [[A1]], 4
3457 ; CHECK-NEXT:    [[B1:%.*]] = and i8 [[B:%.*]], 2
3458 ; CHECK-NEXT:    [[B2:%.*]] = or i8 [[B1]], 5
3459 ; CHECK-NEXT:    [[C:%.*]] = icmp ne i8 [[B2]], [[A2]]
3460 ; CHECK-NEXT:    ret i1 [[C]]
3462   %a1 = and i8 %a, 133
3463   %a2 = or i8 %a1, 4
3464   %b1 = and i8 %b, 7
3465   %b2 = or i8 %b1, 5
3466   %c = icmp sgt i8 %b2, %a2
3467   ret i1 %c
3470 ; Make sure InstCombine doesn't try too hard to simplify the icmp and break the abs idiom
3471 define i32 @abs_preserve(i32 %x) {
3472 ; CHECK-LABEL: @abs_preserve(
3473 ; CHECK-NEXT:    [[A:%.*]] = shl nsw i32 [[X:%.*]], 1
3474 ; CHECK-NEXT:    [[C:%.*]] = icmp slt i32 [[A]], 0
3475 ; CHECK-NEXT:    [[NEGA:%.*]] = sub i32 0, [[A]]
3476 ; CHECK-NEXT:    [[ABS:%.*]] = select i1 [[C]], i32 [[NEGA]], i32 [[A]]
3477 ; CHECK-NEXT:    ret i32 [[ABS]]
3479   %a = mul nsw i32 %x, 2
3480   %c = icmp sge i32 %a, 0
3481   %nega = sub i32 0, %a
3482   %abs = select i1 %c, i32 %a, i32 %nega
3483   ret i32 %abs
3486 ; Don't crash by assuming the compared values are integers.
3488 declare void @llvm.assume(i1)
3489 define i1 @PR35794(i32* %a) {
3490 ; CHECK-LABEL: @PR35794(
3491 ; CHECK-NEXT:    [[MASKCOND:%.*]] = icmp eq i32* [[A:%.*]], null
3492 ; CHECK-NEXT:    tail call void @llvm.assume(i1 [[MASKCOND]])
3493 ; CHECK-NEXT:    ret i1 true
3495   %cmp = icmp sgt i32* %a, inttoptr (i64 -1 to i32*)
3496   %maskcond = icmp eq i32* %a, null
3497   tail call void @llvm.assume(i1 %maskcond)
3498   ret i1 %cmp
3501 ; Don't crash by assuming the compared values are integers.
3502 define <2 x i1> @PR36583(<2 x i8*>)  {
3503 ; CHECK-LABEL: @PR36583(
3504 ; CHECK-NEXT:    [[RES:%.*]] = icmp eq <2 x i8*> [[TMP0:%.*]], zeroinitializer
3505 ; CHECK-NEXT:    ret <2 x i1> [[RES]]
3507   %cast = ptrtoint <2 x i8*> %0 to <2 x i64>
3508   %res = icmp eq <2 x i64> %cast, zeroinitializer
3509   ret <2 x i1> %res
3512 ; fold (icmp pred (sub (0, X)) C1) for vec type
3513 define <2 x i32> @Op1Negated_Vec(<2 x i32> %x) {
3514 ; CHECK-LABEL: @Op1Negated_Vec(
3515 ; CHECK-NEXT:    [[SUB:%.*]] = sub nsw <2 x i32> zeroinitializer, [[X:%.*]]
3516 ; CHECK-NEXT:    [[CMP:%.*]] = icmp slt <2 x i32> [[X]], zeroinitializer
3517 ; CHECK-NEXT:    [[COND:%.*]] = select <2 x i1> [[CMP]], <2 x i32> [[SUB]], <2 x i32> [[X]]
3518 ; CHECK-NEXT:    ret <2 x i32> [[COND]]
3520   %sub = sub nsw <2 x i32> zeroinitializer, %x
3521   %cmp = icmp sgt <2 x i32> %sub, <i32 -1, i32 -1>
3522   %cond = select <2 x i1> %cmp, <2 x i32> %sub, <2 x i32> %x
3523   ret <2 x i32> %cond