xref: /llvm-project/llvm/test/Transforms/InstCombine/icmp.ll (revision 462cb3cd6cecd0511ecaf0e3ebcaba455ece587d)
1; NOTE: Assertions have been autogenerated by utils/update_test_checks.py
2; RUN: opt < %s -passes=instcombine -S | FileCheck %s
3
4target 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"
5
6declare i8 @llvm.abs.i8(i8, i1)
7
8declare void @use_i1(i1)
9declare void @use_i8(i8)
10declare void @use_i32(i32)
11declare void @use_i64(i64)
12
13define i32 @test1(i32 %X) {
14; CHECK-LABEL: @test1(
15; CHECK-NEXT:    [[X_LOBIT:%.*]] = lshr i32 [[X:%.*]], 31
16; CHECK-NEXT:    ret i32 [[X_LOBIT]]
17;
18  %a = icmp slt i32 %X, 0
19  %b = zext i1 %a to i32
20  ret i32 %b
21}
22
23define <2 x i32> @test1vec(<2 x i32> %X) {
24; CHECK-LABEL: @test1vec(
25; CHECK-NEXT:    [[X_LOBIT:%.*]] = lshr <2 x i32> [[X:%.*]], splat (i32 31)
26; CHECK-NEXT:    ret <2 x i32> [[X_LOBIT]]
27;
28  %a = icmp slt <2 x i32> %X, zeroinitializer
29  %b = zext <2 x i1> %a to <2 x i32>
30  ret <2 x i32> %b
31}
32
33define i32 @test2(i32 %X) {
34; CHECK-LABEL: @test2(
35; CHECK-NEXT:    [[A:%.*]] = icmp sgt i32 [[X:%.*]], -1
36; CHECK-NEXT:    [[B:%.*]] = zext i1 [[A]] to i32
37; CHECK-NEXT:    ret i32 [[B]]
38;
39  %a = icmp ult i32 %X, -2147483648
40  %b = zext i1 %a to i32
41  ret i32 %b
42}
43
44define <2 x i32> @test2vec(<2 x i32> %X) {
45; CHECK-LABEL: @test2vec(
46; CHECK-NEXT:    [[A:%.*]] = icmp sgt <2 x i32> [[X:%.*]], splat (i32 -1)
47; CHECK-NEXT:    [[B:%.*]] = zext <2 x i1> [[A]] to <2 x i32>
48; CHECK-NEXT:    ret <2 x i32> [[B]]
49;
50  %a = icmp ult <2 x i32> %X, <i32 -2147483648, i32 -2147483648>
51  %b = zext <2 x i1> %a to <2 x i32>
52  ret <2 x i32> %b
53}
54
55define i32 @test3(i32 %X) {
56; CHECK-LABEL: @test3(
57; CHECK-NEXT:    [[X_LOBIT:%.*]] = ashr i32 [[X:%.*]], 31
58; CHECK-NEXT:    ret i32 [[X_LOBIT]]
59;
60  %a = icmp slt i32 %X, 0
61  %b = sext i1 %a to i32
62  ret i32 %b
63}
64
65define i32 @test4(i32 %X) {
66; CHECK-LABEL: @test4(
67; CHECK-NEXT:    [[A:%.*]] = icmp sgt i32 [[X:%.*]], -1
68; CHECK-NEXT:    [[B:%.*]] = sext i1 [[A]] to i32
69; CHECK-NEXT:    ret i32 [[B]]
70;
71  %a = icmp ult i32 %X, -2147483648
72  %b = sext i1 %a to i32
73  ret i32 %b
74}
75
76; PR4837
77define <2 x i1> @test5_eq(<2 x i64> %x) {
78; CHECK-LABEL: @test5_eq(
79; CHECK-NEXT:    ret <2 x i1> undef
80;
81  %V = icmp eq <2 x i64> %x, undef
82  ret <2 x i1> %V
83}
84define <2 x i1> @test5_ne(<2 x i64> %x) {
85; CHECK-LABEL: @test5_ne(
86; CHECK-NEXT:    ret <2 x i1> undef
87;
88  %V = icmp ne <2 x i64> %x, undef
89  ret <2 x i1> %V
90}
91define <2 x i1> @test5_ugt(<2 x i64> %x) {
92; CHECK-LABEL: @test5_ugt(
93; CHECK-NEXT:    ret <2 x i1> zeroinitializer
94;
95  %V = icmp ugt <2 x i64> %x, undef
96  ret <2 x i1> %V
97}
98define <2 x i1> @test5_zero() {
99; CHECK-LABEL: @test5_zero(
100; CHECK-NEXT:    ret <2 x i1> undef
101;
102  %V = icmp eq <2 x i64> zeroinitializer, undef
103  ret <2 x i1> %V
104}
105
106define i32 @test6(i32 %a, i32 %b) {
107; CHECK-LABEL: @test6(
108; CHECK-NEXT:    [[ISNEG:%.*]] = icmp slt i32 [[A:%.*]], 0
109; CHECK-NEXT:    [[F:%.*]] = select i1 [[ISNEG]], i32 [[B:%.*]], i32 0
110; CHECK-NEXT:    ret i32 [[F]]
111;
112  %c = icmp sle i32 %a, -1
113  %d = zext i1 %c to i32
114  %e = sub i32 0, %d
115  %f = and i32 %e, %b
116  ret i32 %f
117}
118
119
120define i1 @test7(i32 %x) {
121; CHECK-LABEL: @test7(
122; CHECK-NEXT:    [[B:%.*]] = icmp ne i32 [[X:%.*]], 0
123; CHECK-NEXT:    ret i1 [[B]]
124;
125  %a = add i32 %x, -1
126  %b = icmp ult i32 %a, %x
127  ret i1 %b
128}
129
130define <2 x i1> @test7_vec(<2 x i32> %x) {
131; CHECK-LABEL: @test7_vec(
132; CHECK-NEXT:    [[B:%.*]] = icmp ne <2 x i32> [[X:%.*]], zeroinitializer
133; CHECK-NEXT:    ret <2 x i1> [[B]]
134;
135  %a = add <2 x i32> %x, <i32 -1, i32 -1>
136  %b = icmp ult <2 x i32> %a, %x
137  ret <2 x i1> %b
138}
139
140define i1 @test8(i32 %x) {
141; CHECK-LABEL: @test8(
142; CHECK-NEXT:    ret i1 false
143;
144  %a = add i32 %x, -1
145  %b = icmp eq i32 %a, %x
146  ret i1 %b
147}
148
149define <2 x i1> @test8_vec(<2 x i32> %x) {
150; CHECK-LABEL: @test8_vec(
151; CHECK-NEXT:    ret <2 x i1> zeroinitializer
152;
153  %a = add <2 x i32> %x, <i32 -1, i32 -1>
154  %b = icmp eq <2 x i32> %a, %x
155  ret <2 x i1> %b
156}
157
158define i1 @test9(i32 %x) {
159; CHECK-LABEL: @test9(
160; CHECK-NEXT:    [[B:%.*]] = icmp ugt i32 [[X:%.*]], 1
161; CHECK-NEXT:    ret i1 [[B]]
162;
163  %a = add i32 %x, -2
164  %b = icmp ugt i32 %x, %a
165  ret i1 %b
166}
167
168define <2 x i1> @test9_vec(<2 x i32> %x) {
169; CHECK-LABEL: @test9_vec(
170; CHECK-NEXT:    [[B:%.*]] = icmp ugt <2 x i32> [[X:%.*]], splat (i32 1)
171; CHECK-NEXT:    ret <2 x i1> [[B]]
172;
173  %a = add <2 x i32> %x, <i32 -2, i32 -2>
174  %b = icmp ugt <2 x i32> %x, %a
175  ret <2 x i1> %b
176}
177
178define i1 @test9b(i32 %x) {
179; CHECK-LABEL: @test9b(
180; CHECK-NEXT:    [[B:%.*]] = icmp ult i32 [[X:%.*]], 2
181; CHECK-NEXT:    ret i1 [[B]]
182;
183  %a = add i32 %x, -2
184  %b = icmp ugt i32 %a, %x
185  ret i1 %b
186}
187
188define <2 x i1> @test9b_vec(<2 x i32> %x) {
189; CHECK-LABEL: @test9b_vec(
190; CHECK-NEXT:    [[B:%.*]] = icmp ult <2 x i32> [[X:%.*]], splat (i32 2)
191; CHECK-NEXT:    ret <2 x i1> [[B]]
192;
193  %a = add <2 x i32> %x, <i32 -2, i32 -2>
194  %b = icmp ugt <2 x i32> %a, %x
195  ret <2 x i1> %b
196}
197
198define i1 @test10(i32 %x) {
199; CHECK-LABEL: @test10(
200; CHECK-NEXT:    [[B:%.*]] = icmp ne i32 [[X:%.*]], -2147483648
201; CHECK-NEXT:    ret i1 [[B]]
202;
203  %a = add i32 %x, -1
204  %b = icmp slt i32 %a, %x
205  ret i1 %b
206}
207
208define <2 x i1> @test10_vec(<2 x i32> %x) {
209; CHECK-LABEL: @test10_vec(
210; CHECK-NEXT:    [[B:%.*]] = icmp ne <2 x i32> [[X:%.*]], splat (i32 -2147483648)
211; CHECK-NEXT:    ret <2 x i1> [[B]]
212;
213  %a = add <2 x i32> %x, <i32 -1, i32 -1>
214  %b = icmp slt <2 x i32> %a, %x
215  ret <2 x i1> %b
216}
217
218define i1 @test10b(i32 %x) {
219; CHECK-LABEL: @test10b(
220; CHECK-NEXT:    [[B:%.*]] = icmp eq i32 [[X:%.*]], -2147483648
221; CHECK-NEXT:    ret i1 [[B]]
222;
223  %a = add i32 %x, -1
224  %b = icmp sgt i32 %a, %x
225  ret i1 %b
226}
227
228define <2 x i1> @test10b_vec(<2 x i32> %x) {
229; CHECK-LABEL: @test10b_vec(
230; CHECK-NEXT:    [[B:%.*]] = icmp eq <2 x i32> [[X:%.*]], splat (i32 -2147483648)
231; CHECK-NEXT:    ret <2 x i1> [[B]]
232;
233  %a = add <2 x i32> %x, <i32 -1, i32 -1>
234  %b = icmp sgt <2 x i32> %a, %x
235  ret <2 x i1> %b
236}
237
238define i1 @test11(i32 %x) {
239; CHECK-LABEL: @test11(
240; CHECK-NEXT:    ret i1 true
241;
242  %a = add nsw i32 %x, 8
243  %b = icmp slt i32 %x, %a
244  ret i1 %b
245}
246
247define <2 x i1> @test11_vec(<2 x i32> %x) {
248; CHECK-LABEL: @test11_vec(
249; CHECK-NEXT:    ret <2 x i1> splat (i1 true)
250;
251  %a = add nsw <2 x i32> %x, <i32 8, i32 8>
252  %b = icmp slt <2 x i32> %x, %a
253  ret <2 x i1> %b
254}
255
256; PR6195
257define i1 @test12(i1 %A) {
258; CHECK-LABEL: @test12(
259; CHECK-NEXT:    [[NOT_A:%.*]] = xor i1 [[A:%.*]], true
260; CHECK-NEXT:    ret i1 [[NOT_A]]
261;
262  %S = select i1 %A, i64 -4294967295, i64 8589934591
263  %B = icmp ne i64 bitcast (<2 x i32> <i32 1, i32 -1> to i64), %S
264  ret i1 %B
265}
266
267; PR6481
268define i1 @test13(i8 %X) {
269; CHECK-LABEL: @test13(
270; CHECK-NEXT:    ret i1 false
271;
272  %cmp = icmp slt i8 undef, %X
273  ret i1 %cmp
274}
275
276define i1 @test14(i8 %X) {
277; CHECK-LABEL: @test14(
278; CHECK-NEXT:    ret i1 false
279;
280  %cmp = icmp slt i8 undef, -128
281  ret i1 %cmp
282}
283
284define i1 @test15() {
285; CHECK-LABEL: @test15(
286; CHECK-NEXT:    ret i1 undef
287;
288  %cmp = icmp eq i8 undef, -128
289  ret i1 %cmp
290}
291
292define i1 @test16() {
293; CHECK-LABEL: @test16(
294; CHECK-NEXT:    ret i1 undef
295;
296  %cmp = icmp ne i8 undef, -128
297  ret i1 %cmp
298}
299
300define i1 @test17(i32 %x) {
301; CHECK-LABEL: @test17(
302; CHECK-NEXT:    [[TMP1:%.*]] = icmp ne i32 [[X:%.*]], 3
303; CHECK-NEXT:    ret i1 [[TMP1]]
304;
305  %shl = shl i32 1, %x
306  %and = and i32 %shl, 8
307  %cmp = icmp eq i32 %and, 0
308  ret i1 %cmp
309}
310
311define <2 x i1> @test17vec(<2 x i32> %x) {
312; CHECK-LABEL: @test17vec(
313; CHECK-NEXT:    [[TMP1:%.*]] = icmp ne <2 x i32> [[X:%.*]], splat (i32 3)
314; CHECK-NEXT:    ret <2 x i1> [[TMP1]]
315;
316  %shl = shl <2 x i32> <i32 1, i32 1>, %x
317  %and = and <2 x i32> %shl, <i32 8, i32 8>
318  %cmp = icmp eq <2 x i32> %and, zeroinitializer
319  ret <2 x i1> %cmp
320}
321
322define i1 @test17a(i32 %x) {
323; CHECK-LABEL: @test17a(
324; CHECK-NEXT:    [[CMP:%.*]] = icmp ugt i32 [[X:%.*]], 2
325; CHECK-NEXT:    ret i1 [[CMP]]
326;
327  %shl = shl i32 1, %x
328  %and = and i32 %shl, 7
329  %cmp = icmp eq i32 %and, 0
330  ret i1 %cmp
331}
332
333define <2 x i1> @test17a_vec(<2 x i32> %x) {
334; CHECK-LABEL: @test17a_vec(
335; CHECK-NEXT:    [[CMP:%.*]] = icmp ugt <2 x i32> [[X:%.*]], splat (i32 2)
336; CHECK-NEXT:    ret <2 x i1> [[CMP]]
337;
338  %shl = shl <2 x i32> <i32 1, i32 1>, %x
339  %and = and <2 x i32> %shl, <i32 7, i32 7>
340  %cmp = icmp eq <2 x i32> %and, zeroinitializer
341  ret <2 x i1> %cmp
342}
343
344define i1 @test18_eq(i32 %x) {
345; CHECK-LABEL: @test18_eq(
346; CHECK-NEXT:    [[TMP1:%.*]] = icmp ne i32 [[X:%.*]], 3
347; CHECK-NEXT:    ret i1 [[TMP1]]
348;
349  %sh = lshr i32 8, %x
350  %and = and i32 %sh, 1
351  %cmp = icmp eq i32 %and, 0
352  ret i1 %cmp
353}
354
355define <2 x i1> @test18_eq_vec(<2 x i32> %x) {
356; CHECK-LABEL: @test18_eq_vec(
357; CHECK-NEXT:    [[TMP1:%.*]] = icmp ne <2 x i32> [[X:%.*]], splat (i32 3)
358; CHECK-NEXT:    ret <2 x i1> [[TMP1]]
359;
360  %sh = lshr <2 x i32> <i32 8, i32 8>, %x
361  %and = and <2 x i32> %sh, <i32 1, i32 1>
362  %cmp = icmp eq <2 x i32> %and, zeroinitializer
363  ret <2 x i1> %cmp
364}
365
366define i1 @test18_ne(i32 %x) {
367; CHECK-LABEL: @test18_ne(
368; CHECK-NEXT:    [[TMP1:%.*]] = icmp eq i32 [[X:%.*]], 3
369; CHECK-NEXT:    ret i1 [[TMP1]]
370;
371  %sh = lshr i32 8, %x
372  %and = and i32 %sh, 1
373  %cmp = icmp ne i32 %and, 0
374  ret i1 %cmp
375}
376
377define <2 x i1> @test18_ne_vec(<2 x i32> %x) {
378; CHECK-LABEL: @test18_ne_vec(
379; CHECK-NEXT:    [[TMP1:%.*]] = icmp eq <2 x i32> [[X:%.*]], splat (i32 3)
380; CHECK-NEXT:    ret <2 x i1> [[TMP1]]
381;
382  %sh = lshr <2 x i32> <i32 8, i32 8>, %x
383  %and = and <2 x i32> %sh, <i32 1, i32 1>
384  %cmp = icmp ne <2 x i32> %and, zeroinitializer
385  ret <2 x i1> %cmp
386}
387
388define i1 @test19(i32 %x) {
389; CHECK-LABEL: @test19(
390; CHECK-NEXT:    [[TMP1:%.*]] = icmp eq i32 [[X:%.*]], 3
391; CHECK-NEXT:    ret i1 [[TMP1]]
392;
393  %shl = shl i32 1, %x
394  %and = and i32 %shl, 8
395  %cmp = icmp eq i32 %and, 8
396  ret i1 %cmp
397}
398
399define <2 x i1> @test19vec(<2 x i32> %x) {
400; CHECK-LABEL: @test19vec(
401; CHECK-NEXT:    [[TMP1:%.*]] = icmp eq <2 x i32> [[X:%.*]], splat (i32 3)
402; CHECK-NEXT:    ret <2 x i1> [[TMP1]]
403;
404  %shl = shl <2 x i32> <i32 1, i32 1>, %x
405  %and = and <2 x i32> %shl, <i32 8, i32 8>
406  %cmp = icmp eq <2 x i32> %and, <i32 8, i32 8>
407  ret <2 x i1> %cmp
408}
409
410define <2 x i1> @cmp_and_signbit_vec(<2 x i3> %x) {
411; CHECK-LABEL: @cmp_and_signbit_vec(
412; CHECK-NEXT:    [[CMP:%.*]] = icmp slt <2 x i3> [[X:%.*]], zeroinitializer
413; CHECK-NEXT:    ret <2 x i1> [[CMP]]
414;
415  %and = and <2 x i3> %x, <i3 4, i3 4>
416  %cmp = icmp ne <2 x i3> %and, zeroinitializer
417  ret <2 x i1> %cmp
418}
419
420define i1 @test20(i32 %x) {
421; CHECK-LABEL: @test20(
422; CHECK-NEXT:    [[TMP1:%.*]] = icmp eq i32 [[X:%.*]], 3
423; CHECK-NEXT:    ret i1 [[TMP1]]
424;
425  %shl = shl i32 1, %x
426  %and = and i32 %shl, 8
427  %cmp = icmp ne i32 %and, 0
428  ret i1 %cmp
429}
430
431define <2 x i1> @test20vec(<2 x i32> %x) {
432; CHECK-LABEL: @test20vec(
433; CHECK-NEXT:    [[TMP1:%.*]] = icmp eq <2 x i32> [[X:%.*]], splat (i32 3)
434; CHECK-NEXT:    ret <2 x i1> [[TMP1]]
435;
436  %shl = shl <2 x i32> <i32 1, i32 1>, %x
437  %and = and <2 x i32> %shl, <i32 8, i32 8>
438  %cmp = icmp ne <2 x i32> %and, zeroinitializer
439  ret <2 x i1> %cmp
440}
441
442define i1 @test20a(i32 %x) {
443; CHECK-LABEL: @test20a(
444; CHECK-NEXT:    [[CMP:%.*]] = icmp ult i32 [[X:%.*]], 3
445; CHECK-NEXT:    ret i1 [[CMP]]
446;
447  %shl = shl i32 1, %x
448  %and = and i32 %shl, 7
449  %cmp = icmp ne i32 %and, 0
450  ret i1 %cmp
451}
452
453define <2 x i1> @test20a_vec(<2 x i32> %x) {
454; CHECK-LABEL: @test20a_vec(
455; CHECK-NEXT:    [[CMP:%.*]] = icmp ult <2 x i32> [[X:%.*]], splat (i32 3)
456; CHECK-NEXT:    ret <2 x i1> [[CMP]]
457;
458  %shl = shl <2 x i32> <i32 1, i32 1>, %x
459  %and = and <2 x i32> %shl, <i32 7, i32 7>
460  %cmp = icmp ne <2 x i32> %and, zeroinitializer
461  ret <2 x i1> %cmp
462}
463
464define i1 @test21(i8 %x, i8 %y) {
465; CHECK-LABEL: @test21(
466; CHECK-NEXT:    [[B:%.*]] = icmp ugt i8 [[X:%.*]], 3
467; CHECK-NEXT:    ret i1 [[B]]
468;
469  %A = or i8 %x, 1
470  %B = icmp ugt i8 %A, 3
471  ret i1 %B
472}
473
474define i1 @test22(i8 %x, i8 %y) {
475; CHECK-LABEL: @test22(
476; CHECK-NEXT:    [[B:%.*]] = icmp ult i8 [[X:%.*]], 4
477; CHECK-NEXT:    ret i1 [[B]]
478;
479  %A = or i8 %x, 1
480  %B = icmp ult i8 %A, 4
481  ret i1 %B
482}
483
484; PR2740
485define i1 @test23(i32 %x) {
486; CHECK-LABEL: @test23(
487; CHECK-NEXT:    [[I4:%.*]] = icmp sgt i32 [[X:%.*]], 1328634634
488; CHECK-NEXT:    ret i1 [[I4]]
489;
490  %i3 = sdiv i32 %x, -1328634635
491  %i4 = icmp eq i32 %i3, -1
492  ret i1 %i4
493}
494
495define <2 x i1> @test23vec(<2 x i32> %x) {
496; CHECK-LABEL: @test23vec(
497; CHECK-NEXT:    [[I4:%.*]] = icmp sgt <2 x i32> [[X:%.*]], splat (i32 1328634634)
498; CHECK-NEXT:    ret <2 x i1> [[I4]]
499;
500  %i3 = sdiv <2 x i32> %x, <i32 -1328634635, i32 -1328634635>
501  %i4 = icmp eq <2 x i32> %i3, <i32 -1, i32 -1>
502  ret <2 x i1> %i4
503}
504
505; Note: offs can be negative, LLVM used to make an incorrect assumption that
506; unsigned overflow does not happen during offset computation
507define i1 @test24_neg_offs(ptr %p, i64 %offs) {
508; CHECK-LABEL: @test24_neg_offs(
509; CHECK-NEXT:    [[P1_IDX_NEG:%.*]] = mul i64 [[OFFS:%.*]], -4
510; CHECK-NEXT:    [[CMP:%.*]] = icmp eq i64 [[P1_IDX_NEG]], 8
511; CHECK-NEXT:    ret i1 [[CMP]]
512;
513  %p1 = getelementptr inbounds i32, ptr %p, i64 %offs
514  %conv1 = ptrtoint ptr %p to i64
515  %conv2 = ptrtoint ptr %p1 to i64
516  %delta = sub i64 %conv1, %conv2
517  %cmp = icmp eq i64 %delta, 8
518  ret i1 %cmp
519}
520
521; X - Z > Y - Z -> X > Y if there is no overflow.
522define i1 @test27(i32 %x, i32 %y, i32 %z) {
523; CHECK-LABEL: @test27(
524; CHECK-NEXT:    [[C:%.*]] = icmp sgt i32 [[X:%.*]], [[Y:%.*]]
525; CHECK-NEXT:    ret i1 [[C]]
526;
527  %lhs = sub nsw i32 %x, %z
528  %rhs = sub nsw i32 %y, %z
529  %c = icmp sgt i32 %lhs, %rhs
530  ret i1 %c
531}
532
533define i1 @test27_extra_uses(i32 %x, i32 %y, i32 %z) {
534; CHECK-LABEL: @test27_extra_uses(
535; CHECK-NEXT:    [[LHS:%.*]] = sub nsw i32 [[X:%.*]], [[Z:%.*]]
536; CHECK-NEXT:    call void @use_i32(i32 [[LHS]])
537; CHECK-NEXT:    [[RHS:%.*]] = sub nsw i32 [[Y:%.*]], [[Z]]
538; CHECK-NEXT:    call void @use_i32(i32 [[RHS]])
539; CHECK-NEXT:    [[C:%.*]] = icmp sgt i32 [[X]], [[Y]]
540; CHECK-NEXT:    ret i1 [[C]]
541;
542  %lhs = sub nsw i32 %x, %z
543  call void @use_i32(i32 %lhs)
544  %rhs = sub nsw i32 %y, %z
545  call void @use_i32(i32 %rhs)
546  %c = icmp sgt i32 %lhs, %rhs
547  ret i1 %c
548}
549
550; X - Z > Y - Z -> X > Y if there is no overflow.
551define i1 @test28(i32 %x, i32 %y, i32 %z) {
552; CHECK-LABEL: @test28(
553; CHECK-NEXT:    [[C:%.*]] = icmp ugt i32 [[X:%.*]], [[Y:%.*]]
554; CHECK-NEXT:    ret i1 [[C]]
555;
556  %lhs = sub nuw i32 %x, %z
557  %rhs = sub nuw i32 %y, %z
558  %c = icmp ugt i32 %lhs, %rhs
559  ret i1 %c
560}
561
562define i1 @test28_extra_uses(i32 %x, i32 %y, i32 %z) {
563; CHECK-LABEL: @test28_extra_uses(
564; CHECK-NEXT:    [[LHS:%.*]] = sub nuw i32 [[X:%.*]], [[Z:%.*]]
565; CHECK-NEXT:    call void @use_i32(i32 [[LHS]])
566; CHECK-NEXT:    [[RHS:%.*]] = sub nuw i32 [[Y:%.*]], [[Z]]
567; CHECK-NEXT:    call void @use_i32(i32 [[RHS]])
568; CHECK-NEXT:    [[C:%.*]] = icmp ugt i32 [[X]], [[Y]]
569; CHECK-NEXT:    ret i1 [[C]]
570;
571  %lhs = sub nuw i32 %x, %z
572  call void @use_i32(i32 %lhs)
573  %rhs = sub nuw i32 %y, %z
574  call void @use_i32(i32 %rhs)
575  %c = icmp ugt i32 %lhs, %rhs
576  ret i1 %c
577}
578
579; PR36969 - https://bugs.llvm.org/show_bug.cgi?id=36969
580
581define i1 @ugt_sub(i32 %xsrc, i32 %y) {
582; CHECK-LABEL: @ugt_sub(
583; CHECK-NEXT:    [[X:%.*]] = udiv i32 [[XSRC:%.*]], 42
584; CHECK-NEXT:    [[CMP:%.*]] = icmp ugt i32 [[Y:%.*]], [[X]]
585; CHECK-NEXT:    ret i1 [[CMP]]
586;
587  %x = udiv i32 %xsrc, 42 ; thwart complexity-based canonicalization
588  %sub = sub i32 %x, %y
589  %cmp = icmp ugt i32 %sub, %x
590  ret i1 %cmp
591}
592
593; Swap operands and predicate. Try a vector type to verify that works too.
594
595define <2 x i1> @ult_sub(<2 x i8> %xsrc, <2 x i8> %y) {
596; CHECK-LABEL: @ult_sub(
597; CHECK-NEXT:    [[X:%.*]] = udiv <2 x i8> [[XSRC:%.*]], <i8 42, i8 -42>
598; CHECK-NEXT:    [[CMP:%.*]] = icmp ult <2 x i8> [[X]], [[Y:%.*]]
599; CHECK-NEXT:    ret <2 x i1> [[CMP]]
600;
601  %x = udiv <2 x i8> %xsrc, <i8 42, i8 -42> ; thwart complexity-based canonicalization
602  %sub = sub <2 x i8> %x, %y
603  %cmp = icmp ult <2 x i8> %x, %sub
604  ret <2 x i1> %cmp
605}
606
607; X - Y > X -> 0 > Y if there is no overflow.
608define i1 @test33(i32 %x, i32 %y) {
609; CHECK-LABEL: @test33(
610; CHECK-NEXT:    [[C:%.*]] = icmp slt i32 [[Y:%.*]], 0
611; CHECK-NEXT:    ret i1 [[C]]
612;
613  %lhs = sub nsw i32 %x, %y
614  %c = icmp sgt i32 %lhs, %x
615  ret i1 %c
616}
617
618; X - Y > X -> 0 > Y if there is no overflow.
619define i1 @test34(i32 %x, i32 %y) {
620; CHECK-LABEL: @test34(
621; CHECK-NEXT:    ret i1 false
622;
623  %lhs = sub nuw i32 %x, %y
624  %c = icmp ugt i32 %lhs, %x
625  ret i1 %c
626}
627
628; X > X - Y -> Y > 0 if there is no overflow.
629define i1 @test35(i32 %x, i32 %y) {
630; CHECK-LABEL: @test35(
631; CHECK-NEXT:    [[C:%.*]] = icmp sgt i32 [[Y:%.*]], 0
632; CHECK-NEXT:    ret i1 [[C]]
633;
634  %rhs = sub nsw i32 %x, %y
635  %c = icmp sgt i32 %x, %rhs
636  ret i1 %c
637}
638
639; X > X - Y -> Y > 0 if there is no overflow.
640define i1 @test36(i32 %x, i32 %y) {
641; CHECK-LABEL: @test36(
642; CHECK-NEXT:    [[C:%.*]] = icmp ne i32 [[Y:%.*]], 0
643; CHECK-NEXT:    ret i1 [[C]]
644;
645  %rhs = sub nuw i32 %x, %y
646  %c = icmp ugt i32 %x, %rhs
647  ret i1 %c
648}
649
650; X - Y > X - Z -> Z > Y if there is no overflow.
651define i1 @test37(i32 %x, i32 %y, i32 %z) {
652; CHECK-LABEL: @test37(
653; CHECK-NEXT:    [[C:%.*]] = icmp sgt i32 [[Z:%.*]], [[Y:%.*]]
654; CHECK-NEXT:    ret i1 [[C]]
655;
656  %lhs = sub nsw i32 %x, %y
657  %rhs = sub nsw i32 %x, %z
658  %c = icmp sgt i32 %lhs, %rhs
659  ret i1 %c
660}
661
662define i1 @test37_extra_uses(i32 %x, i32 %y, i32 %z) {
663; CHECK-LABEL: @test37_extra_uses(
664; CHECK-NEXT:    [[LHS:%.*]] = sub nsw i32 [[X:%.*]], [[Y:%.*]]
665; CHECK-NEXT:    call void @use_i32(i32 [[LHS]])
666; CHECK-NEXT:    [[RHS:%.*]] = sub nsw i32 [[X]], [[Z:%.*]]
667; CHECK-NEXT:    call void @use_i32(i32 [[RHS]])
668; CHECK-NEXT:    [[C:%.*]] = icmp sgt i32 [[Z]], [[Y]]
669; CHECK-NEXT:    ret i1 [[C]]
670;
671  %lhs = sub nsw i32 %x, %y
672  call void @use_i32(i32 %lhs)
673  %rhs = sub nsw i32 %x, %z
674  call void @use_i32(i32 %rhs)
675  %c = icmp sgt i32 %lhs, %rhs
676  ret i1 %c
677}
678
679; TODO: Min/max pattern should not prevent the fold.
680
681define i32 @neg_max_s32(i32 %x, i32 %y) {
682; CHECK-LABEL: @neg_max_s32(
683; CHECK-NEXT:    [[TMP1:%.*]] = call i32 @llvm.smin.i32(i32 [[X:%.*]], i32 [[Y:%.*]])
684; CHECK-NEXT:    ret i32 [[TMP1]]
685;
686  %nx = sub nsw i32 0, %x
687  %ny = sub nsw i32 0, %y
688  %c = icmp slt i32 %nx, %ny
689  %s = select i1 %c, i32 %ny, i32 %nx
690  %r = sub nsw i32 0, %s
691  ret i32 %r
692}
693
694define <4 x i32> @neg_max_v4s32(<4 x i32> %x, <4 x i32> %y) {
695; CHECK-LABEL: @neg_max_v4s32(
696; CHECK-NEXT:    [[TMP1:%.*]] = call <4 x i32> @llvm.smin.v4i32(<4 x i32> [[X:%.*]], <4 x i32> [[Y:%.*]])
697; CHECK-NEXT:    ret <4 x i32> [[TMP1]]
698;
699  %nx = sub nsw <4 x i32> zeroinitializer, %x
700  %ny = sub nsw <4 x i32> zeroinitializer, %y
701  %c = icmp sgt <4 x i32> %nx, %ny
702  %s = select <4 x i1> %c, <4 x i32> %nx, <4 x i32> %ny
703  %r = sub <4 x i32> zeroinitializer, %s
704  ret <4 x i32> %r
705}
706
707; X - Y > X - Z -> Z > Y if there is no overflow.
708define i1 @test38(i32 %x, i32 %y, i32 %z) {
709; CHECK-LABEL: @test38(
710; CHECK-NEXT:    [[C:%.*]] = icmp ugt i32 [[Z:%.*]], [[Y:%.*]]
711; CHECK-NEXT:    ret i1 [[C]]
712;
713  %lhs = sub nuw i32 %x, %y
714  %rhs = sub nuw i32 %x, %z
715  %c = icmp ugt i32 %lhs, %rhs
716  ret i1 %c
717}
718
719define i1 @test38_extra_uses(i32 %x, i32 %y, i32 %z) {
720; CHECK-LABEL: @test38_extra_uses(
721; CHECK-NEXT:    [[LHS:%.*]] = sub nuw i32 [[X:%.*]], [[Y:%.*]]
722; CHECK-NEXT:    call void @use_i32(i32 [[LHS]])
723; CHECK-NEXT:    [[RHS:%.*]] = sub nuw i32 [[X]], [[Z:%.*]]
724; CHECK-NEXT:    call void @use_i32(i32 [[RHS]])
725; CHECK-NEXT:    [[C:%.*]] = icmp ugt i32 [[Z]], [[Y]]
726; CHECK-NEXT:    ret i1 [[C]]
727;
728  %lhs = sub nuw i32 %x, %y
729  call void @use_i32(i32 %lhs)
730  %rhs = sub nuw i32 %x, %z
731  call void @use_i32(i32 %rhs)
732  %c = icmp ugt i32 %lhs, %rhs
733  ret i1 %c
734}
735
736define i1 @shr_exact(i132 %x) {
737; CHECK-LABEL: @shr_exact(
738; CHECK-NEXT:    [[CMP:%.*]] = icmp eq i132 [[X:%.*]], 32
739; CHECK-NEXT:    ret i1 [[CMP]]
740;
741  %sh = ashr exact i132 %x, 4
742  %cmp = icmp eq i132 %sh, 2
743  ret i1 %cmp
744}
745
746define <2 x i1> @shr_exact_vec(<2 x i132> %x) {
747; CHECK-LABEL: @shr_exact_vec(
748; CHECK-NEXT:    [[CMP:%.*]] = icmp ne <2 x i132> [[X:%.*]], splat (i132 32)
749; CHECK-NEXT:    ret <2 x i1> [[CMP]]
750;
751  %sh = lshr exact <2 x i132> %x, <i132 4, i132 4>
752  %cmp = icmp ne <2 x i132> %sh, <i132 2, i132 2>
753  ret <2 x i1> %cmp
754}
755
756; PR9343 #3
757define i1 @test41(i32 %X, i32 %Y) {
758; CHECK-LABEL: @test41(
759; CHECK-NEXT:    ret i1 true
760;
761  %A = urem i32 %X, %Y
762  %B = icmp ugt i32 %Y, %A
763  ret i1 %B
764}
765
766define i1 @test42(i32 %X, i32 %Y) {
767; CHECK-LABEL: @test42(
768; CHECK-NEXT:    [[B:%.*]] = icmp sgt i32 [[Y:%.*]], -1
769; CHECK-NEXT:    ret i1 [[B]]
770;
771  %A = srem i32 %X, %Y
772  %B = icmp slt i32 %A, %Y
773  ret i1 %B
774}
775
776define i1 @test43(i32 %X, i32 %Y) {
777; CHECK-LABEL: @test43(
778; CHECK-NEXT:    [[B:%.*]] = icmp slt i32 [[Y:%.*]], 0
779; CHECK-NEXT:    ret i1 [[B]]
780;
781  %A = srem i32 %X, %Y
782  %B = icmp slt i32 %Y, %A
783  ret i1 %B
784}
785
786define i1 @test44(i32 %X, i32 %Y) {
787; CHECK-LABEL: @test44(
788; CHECK-NEXT:    [[B:%.*]] = icmp sgt i32 [[Y:%.*]], -1
789; CHECK-NEXT:    ret i1 [[B]]
790;
791  %A = srem i32 %X, %Y
792  %B = icmp slt i32 %A, %Y
793  ret i1 %B
794}
795
796define i1 @test45(i32 %X, i32 %Y) {
797; CHECK-LABEL: @test45(
798; CHECK-NEXT:    [[B:%.*]] = icmp slt i32 [[Y:%.*]], 0
799; CHECK-NEXT:    ret i1 [[B]]
800;
801  %A = srem i32 %X, %Y
802  %B = icmp slt i32 %Y, %A
803  ret i1 %B
804}
805
806; PR9343 #4
807define i1 @test46(i32 %X, i32 %Y, i32 %Z) {
808; CHECK-LABEL: @test46(
809; CHECK-NEXT:    [[C:%.*]] = icmp ult i32 [[X:%.*]], [[Y:%.*]]
810; CHECK-NEXT:    ret i1 [[C]]
811;
812  %A = ashr exact i32 %X, %Z
813  %B = ashr exact i32 %Y, %Z
814  %C = icmp ult i32 %A, %B
815  ret i1 %C
816}
817
818define i1 @test46_multiuse1(i32 %X, i32 %Y, i32 %Z) {
819; CHECK-LABEL: @test46_multiuse1(
820; CHECK-NEXT:    [[A:%.*]] = ashr exact i32 [[X:%.*]], [[Z:%.*]]
821; CHECK-NEXT:    call void @use_i32(i32 [[A]])
822; CHECK-NEXT:    [[C:%.*]] = icmp ult i32 [[X]], [[Y:%.*]]
823; CHECK-NEXT:    ret i1 [[C]]
824;
825  %A = ashr exact i32 %X, %Z
826  call void @use_i32(i32 %A)
827  %B = ashr exact i32 %Y, %Z
828  %C = icmp ult i32 %A, %B
829  ret i1 %C
830}
831
832define i1 @test46_multiuse2(i32 %X, i32 %Y, i32 %Z) {
833; CHECK-LABEL: @test46_multiuse2(
834; CHECK-NEXT:    [[B:%.*]] = ashr exact i32 [[Y:%.*]], [[Z:%.*]]
835; CHECK-NEXT:    call void @use_i32(i32 [[B]])
836; CHECK-NEXT:    [[C:%.*]] = icmp ult i32 [[X:%.*]], [[Y]]
837; CHECK-NEXT:    ret i1 [[C]]
838;
839  %A = ashr exact i32 %X, %Z
840  %B = ashr exact i32 %Y, %Z
841  call void @use_i32(i32 %B)
842  %C = icmp ult i32 %A, %B
843  ret i1 %C
844}
845
846define i1 @test46_multiuse3(i32 %X, i32 %Y, i32 %Z) {
847; CHECK-LABEL: @test46_multiuse3(
848; CHECK-NEXT:    [[A:%.*]] = ashr exact i32 [[X:%.*]], [[Z:%.*]]
849; CHECK-NEXT:    call void @use_i32(i32 [[A]])
850; CHECK-NEXT:    [[B:%.*]] = ashr exact i32 [[Y:%.*]], [[Z]]
851; CHECK-NEXT:    call void @use_i32(i32 [[B]])
852; CHECK-NEXT:    [[C:%.*]] = icmp ult i32 [[A]], [[B]]
853; CHECK-NEXT:    ret i1 [[C]]
854;
855  %A = ashr exact i32 %X, %Z
856  call void @use_i32(i32 %A)
857  %B = ashr exact i32 %Y, %Z
858  call void @use_i32(i32 %B)
859  %C = icmp ult i32 %A, %B
860  ret i1 %C
861}
862
863; PR9343 #5
864define i1 @test47(i32 %X, i32 %Y, i32 %Z) {
865; CHECK-LABEL: @test47(
866; CHECK-NEXT:    [[C:%.*]] = icmp ugt i32 [[X:%.*]], [[Y:%.*]]
867; CHECK-NEXT:    ret i1 [[C]]
868;
869  %A = ashr exact i32 %X, %Z
870  %B = ashr exact i32 %Y, %Z
871  %C = icmp ugt i32 %A, %B
872  ret i1 %C
873}
874
875; PR9343 #8
876define i1 @test48(i32 %X, i32 %Y, i32 %Z) {
877; CHECK-LABEL: @test48(
878; CHECK-NEXT:    [[C:%.*]] = icmp eq i32 [[X:%.*]], [[Y:%.*]]
879; CHECK-NEXT:    ret i1 [[C]]
880;
881  %A = sdiv exact i32 %X, %Z
882  %B = sdiv exact i32 %Y, %Z
883  %C = icmp eq i32 %A, %B
884  ret i1 %C
885}
886
887; The above transform only works for equality predicates.
888
889define i1 @PR32949(i32 %X, i32 %Y, i32 %Z) {
890; CHECK-LABEL: @PR32949(
891; CHECK-NEXT:    [[A:%.*]] = sdiv exact i32 [[X:%.*]], [[Z:%.*]]
892; CHECK-NEXT:    [[B:%.*]] = sdiv exact i32 [[Y:%.*]], [[Z]]
893; CHECK-NEXT:    [[C:%.*]] = icmp sgt i32 [[A]], [[B]]
894; CHECK-NEXT:    ret i1 [[C]]
895;
896  %A = sdiv exact i32 %X, %Z
897  %B = sdiv exact i32 %Y, %Z
898  %C = icmp sgt i32 %A, %B
899  ret i1 %C
900}
901
902define i1 @test_sdiv_pos_slt(i32 %x, i32 %y) {
903; CHECK-LABEL: @test_sdiv_pos_slt(
904; CHECK-NEXT:    [[CMP:%.*]] = icmp slt i32 [[X:%.*]], [[Y:%.*]]
905; CHECK-NEXT:    ret i1 [[CMP]]
906;
907  %divx = sdiv exact i32 %x, 40
908  %divy = sdiv exact i32 %y, 40
909  %cmp = icmp slt i32 %divx, %divy
910  ret i1 %cmp
911}
912
913define i1 @test_sdiv_pos_sle(i32 %x, i32 %y) {
914; CHECK-LABEL: @test_sdiv_pos_sle(
915; CHECK-NEXT:    [[CMP:%.*]] = icmp sle i32 [[X:%.*]], [[Y:%.*]]
916; CHECK-NEXT:    ret i1 [[CMP]]
917;
918  %divx = sdiv exact i32 %x, 40
919  %divy = sdiv exact i32 %y, 40
920  %cmp = icmp sle i32 %divx, %divy
921  ret i1 %cmp
922}
923
924define i1 @test_sdiv_pos_sgt(i32 %x, i32 %y) {
925; CHECK-LABEL: @test_sdiv_pos_sgt(
926; CHECK-NEXT:    [[CMP:%.*]] = icmp sgt i32 [[X:%.*]], [[Y:%.*]]
927; CHECK-NEXT:    ret i1 [[CMP]]
928;
929  %divx = sdiv exact i32 %x, 40
930  %divy = sdiv exact i32 %y, 40
931  %cmp = icmp sgt i32 %divx, %divy
932  ret i1 %cmp
933}
934
935define i1 @test_sdiv_pos_sge(i32 %x, i32 %y) {
936; CHECK-LABEL: @test_sdiv_pos_sge(
937; CHECK-NEXT:    [[CMP:%.*]] = icmp sge i32 [[X:%.*]], [[Y:%.*]]
938; CHECK-NEXT:    ret i1 [[CMP]]
939;
940  %divx = sdiv exact i32 %x, 40
941  %divy = sdiv exact i32 %y, 40
942  %cmp = icmp sge i32 %divx, %divy
943  ret i1 %cmp
944}
945
946define i1 @test_sdiv_pos_ult(i32 %x, i32 %y) {
947; CHECK-LABEL: @test_sdiv_pos_ult(
948; CHECK-NEXT:    [[CMP:%.*]] = icmp ult i32 [[X:%.*]], [[Y:%.*]]
949; CHECK-NEXT:    ret i1 [[CMP]]
950;
951  %divx = sdiv exact i32 %x, 40
952  %divy = sdiv exact i32 %y, 40
953  %cmp = icmp ult i32 %divx, %divy
954  ret i1 %cmp
955}
956
957define i1 @test_sdiv_pos_ule(i32 %x, i32 %y) {
958; CHECK-LABEL: @test_sdiv_pos_ule(
959; CHECK-NEXT:    [[CMP:%.*]] = icmp ule i32 [[X:%.*]], [[Y:%.*]]
960; CHECK-NEXT:    ret i1 [[CMP]]
961;
962  %divx = sdiv exact i32 %x, 40
963  %divy = sdiv exact i32 %y, 40
964  %cmp = icmp ule i32 %divx, %divy
965  ret i1 %cmp
966}
967
968define i1 @test_sdiv_pos_ugt(i32 %x, i32 %y) {
969; CHECK-LABEL: @test_sdiv_pos_ugt(
970; CHECK-NEXT:    [[CMP:%.*]] = icmp ugt i32 [[X:%.*]], [[Y:%.*]]
971; CHECK-NEXT:    ret i1 [[CMP]]
972;
973  %divx = sdiv exact i32 %x, 40
974  %divy = sdiv exact i32 %y, 40
975  %cmp = icmp ugt i32 %divx, %divy
976  ret i1 %cmp
977}
978
979define i1 @test_sdiv_pos_uge(i32 %x, i32 %y) {
980; CHECK-LABEL: @test_sdiv_pos_uge(
981; CHECK-NEXT:    [[CMP:%.*]] = icmp uge i32 [[X:%.*]], [[Y:%.*]]
982; CHECK-NEXT:    ret i1 [[CMP]]
983;
984  %divx = sdiv exact i32 %x, 40
985  %divy = sdiv exact i32 %y, 40
986  %cmp = icmp uge i32 %divx, %divy
987  ret i1 %cmp
988}
989
990define i1 @test_sdiv_neg_slt(i32 %x, i32 %y) {
991; CHECK-LABEL: @test_sdiv_neg_slt(
992; CHECK-NEXT:    [[DIVX:%.*]] = sdiv exact i32 [[X:%.*]], -40
993; CHECK-NEXT:    [[DIVY:%.*]] = sdiv exact i32 [[Y:%.*]], -40
994; CHECK-NEXT:    [[CMP:%.*]] = icmp slt i32 [[DIVX]], [[DIVY]]
995; CHECK-NEXT:    ret i1 [[CMP]]
996;
997  %divx = sdiv exact i32 %x, -40
998  %divy = sdiv exact i32 %y, -40
999  %cmp = icmp slt i32 %divx, %divy
1000  ret i1 %cmp
1001}
1002
1003; PR8469
1004define <2 x i1> @test49(<2 x i32> %i3) {
1005; CHECK-LABEL: @test49(
1006; CHECK-NEXT:  entry:
1007; CHECK-NEXT:    ret <2 x i1> splat (i1 true)
1008;
1009entry:
1010  %i11 = and <2 x i32> %i3, <i32 3, i32 3>
1011  %cmp = icmp ult <2 x i32> %i11, <i32 4, i32 4>
1012  ret <2 x i1> %cmp
1013}
1014
1015; PR9343 #7
1016define i1 @test50(i16 %X, i32 %Y) {
1017; CHECK-LABEL: @test50(
1018; CHECK-NEXT:    ret i1 true
1019;
1020  %A = zext i16 %X to i32
1021  %B = srem i32 %A, %Y
1022  %C = icmp sgt i32 %B, -1
1023  ret i1 %C
1024}
1025
1026define i1 @test51(i32 %X, i32 %Y) {
1027; CHECK-LABEL: @test51(
1028; CHECK-NEXT:    [[A:%.*]] = and i32 [[X:%.*]], -2147483648
1029; CHECK-NEXT:    [[B:%.*]] = srem i32 [[A]], [[Y:%.*]]
1030; CHECK-NEXT:    [[C:%.*]] = icmp sgt i32 [[B]], -1
1031; CHECK-NEXT:    ret i1 [[C]]
1032;
1033  %A = and i32 %X, 2147483648
1034  %B = srem i32 %A, %Y
1035  %C = icmp sgt i32 %B, -1
1036  ret i1 %C
1037}
1038
1039define i1 @test52(i32 %x1) {
1040; CHECK-LABEL: @test52(
1041; CHECK-NEXT:    [[TMP1:%.*]] = and i32 [[X1:%.*]], 16711935
1042; CHECK-NEXT:    [[A:%.*]] = icmp eq i32 [[TMP1]], 4980863
1043; CHECK-NEXT:    ret i1 [[A]]
1044;
1045  %conv = and i32 %x1, 255
1046  %cmp = icmp eq i32 %conv, 127
1047  %i2 = lshr i32 %x1, 16
1048  %i3 = trunc i32 %i2 to i8
1049  %cmp15 = icmp eq i8 %i3, 76
1050
1051  %A = and i1 %cmp, %cmp15
1052  ret i1 %A
1053}
1054
1055define i1 @test52_logical(i32 %x1) {
1056; CHECK-LABEL: @test52_logical(
1057; CHECK-NEXT:    [[TMP1:%.*]] = and i32 [[X1:%.*]], 16711935
1058; CHECK-NEXT:    [[A:%.*]] = icmp eq i32 [[TMP1]], 4980863
1059; CHECK-NEXT:    ret i1 [[A]]
1060;
1061  %conv = and i32 %x1, 255
1062  %cmp = icmp eq i32 %conv, 127
1063  %i2 = lshr i32 %x1, 16
1064  %i3 = trunc i32 %i2 to i8
1065  %cmp15 = icmp eq i8 %i3, 76
1066
1067  %A = select i1 %cmp, i1 %cmp15, i1 false
1068  ret i1 %A
1069}
1070
1071define i1 @test52b(i128 %x1) {
1072; CHECK-LABEL: @test52b(
1073; CHECK-NEXT:    [[TMP1:%.*]] = and i128 [[X1:%.*]], 16711935
1074; CHECK-NEXT:    [[A:%.*]] = icmp eq i128 [[TMP1]], 4980863
1075; CHECK-NEXT:    ret i1 [[A]]
1076;
1077  %conv = and i128 %x1, 255
1078  %cmp = icmp eq i128 %conv, 127
1079  %i2 = lshr i128 %x1, 16
1080  %i3 = trunc i128 %i2 to i8
1081  %cmp15 = icmp eq i8 %i3, 76
1082
1083  %A = and i1 %cmp, %cmp15
1084  ret i1 %A
1085}
1086
1087define i1 @test52b_logical(i128 %x1) {
1088; CHECK-LABEL: @test52b_logical(
1089; CHECK-NEXT:    [[TMP1:%.*]] = and i128 [[X1:%.*]], 16711935
1090; CHECK-NEXT:    [[A:%.*]] = icmp eq i128 [[TMP1]], 4980863
1091; CHECK-NEXT:    ret i1 [[A]]
1092;
1093  %conv = and i128 %x1, 255
1094  %cmp = icmp eq i128 %conv, 127
1095  %i2 = lshr i128 %x1, 16
1096  %i3 = trunc i128 %i2 to i8
1097  %cmp15 = icmp eq i8 %i3, 76
1098
1099  %A = select i1 %cmp, i1 %cmp15, i1 false
1100  ret i1 %A
1101}
1102
1103; PR9838
1104define i1 @test53(i32 %a, i32 %b) {
1105; CHECK-LABEL: @test53(
1106; CHECK-NEXT:    [[X:%.*]] = sdiv exact i32 [[A:%.*]], 30
1107; CHECK-NEXT:    [[Y:%.*]] = sdiv i32 [[B:%.*]], 30
1108; CHECK-NEXT:    [[Z:%.*]] = icmp eq i32 [[X]], [[Y]]
1109; CHECK-NEXT:    ret i1 [[Z]]
1110;
1111  %x = sdiv exact i32 %a, 30
1112  %y = sdiv i32 %b, 30
1113  %z = icmp eq i32 %x, %y
1114  ret i1 %z
1115}
1116
1117define i1 @test54(i8 %a) {
1118; CHECK-LABEL: @test54(
1119; CHECK-NEXT:    [[RET:%.*]] = icmp slt i8 [[A:%.*]], -64
1120; CHECK-NEXT:    ret i1 [[RET]]
1121;
1122  %ext = zext i8 %a to i32
1123  %and = and i32 %ext, 192
1124  %ret = icmp eq i32 %and, 128
1125  ret i1 %ret
1126}
1127
1128define i1 @test55(i32 %a) {
1129; CHECK-LABEL: @test55(
1130; CHECK-NEXT:    [[CMP:%.*]] = icmp eq i32 [[A:%.*]], -123
1131; CHECK-NEXT:    ret i1 [[CMP]]
1132;
1133  %sub = sub i32 0, %a
1134  %cmp = icmp eq i32 %sub, 123
1135  ret i1 %cmp
1136}
1137
1138define <2 x i1> @test55vec(<2 x i32> %a) {
1139; CHECK-LABEL: @test55vec(
1140; CHECK-NEXT:    [[CMP:%.*]] = icmp eq <2 x i32> [[A:%.*]], splat (i32 -123)
1141; CHECK-NEXT:    ret <2 x i1> [[CMP]]
1142;
1143  %sub = sub <2 x i32> zeroinitializer, %a
1144  %cmp = icmp eq <2 x i32> %sub, <i32 123, i32 123>
1145  ret <2 x i1> %cmp
1146}
1147
1148define i1 @test56(i32 %a) {
1149; CHECK-LABEL: @test56(
1150; CHECK-NEXT:    [[CMP:%.*]] = icmp eq i32 [[A:%.*]], -113
1151; CHECK-NEXT:    ret i1 [[CMP]]
1152;
1153  %sub = sub i32 10, %a
1154  %cmp = icmp eq i32 %sub, 123
1155  ret i1 %cmp
1156}
1157
1158define <2 x i1> @test56vec(<2 x i32> %a) {
1159; CHECK-LABEL: @test56vec(
1160; CHECK-NEXT:    [[CMP:%.*]] = icmp eq <2 x i32> [[A:%.*]], splat (i32 -113)
1161; CHECK-NEXT:    ret <2 x i1> [[CMP]]
1162;
1163  %sub = sub <2 x i32> <i32 10, i32 10>, %a
1164  %cmp = icmp eq <2 x i32> %sub, <i32 123, i32 123>
1165  ret <2 x i1> %cmp
1166}
1167
1168; PR10267 Don't make icmps more expensive when no other inst is subsumed.
1169define i1 @test57(i32 %a) {
1170; CHECK-LABEL: @test57(
1171; CHECK-NEXT:    [[AND:%.*]] = and i32 [[A:%.*]], -2
1172; CHECK-NEXT:    [[CMP:%.*]] = icmp ne i32 [[AND]], 0
1173; CHECK-NEXT:    call void @use_i32(i32 [[AND]])
1174; CHECK-NEXT:    ret i1 [[CMP]]
1175;
1176  %and = and i32 %a, -2
1177  %cmp = icmp ne i32 %and, 0
1178  call void @use_i32(i32 %and)
1179  ret i1 %cmp
1180}
1181
1182; rdar://problem/10482509
1183define zeroext i1 @cmpabs1(i64 %val) {
1184; CHECK-LABEL: @cmpabs1(
1185; CHECK-NEXT:    [[TOBOOL:%.*]] = icmp ne i64 [[VAL:%.*]], 0
1186; CHECK-NEXT:    ret i1 [[TOBOOL]]
1187;
1188  %sub = sub nsw i64 0, %val
1189  %cmp = icmp slt i64 %val, 0
1190  %sub.val = select i1 %cmp, i64 %sub, i64 %val
1191  %tobool = icmp ne i64 %sub.val, 0
1192  ret i1 %tobool
1193}
1194
1195define zeroext i1 @cmpabs2(i64 %val) {
1196; CHECK-LABEL: @cmpabs2(
1197; CHECK-NEXT:    [[TOBOOL:%.*]] = icmp ne i64 [[VAL:%.*]], 0
1198; CHECK-NEXT:    ret i1 [[TOBOOL]]
1199;
1200  %sub = sub nsw i64 0, %val
1201  %cmp = icmp slt i64 %val, 0
1202  %sub.val = select i1 %cmp, i64 %val, i64 %sub
1203  %tobool = icmp ne i64 %sub.val, 0
1204  ret i1 %tobool
1205}
1206
1207define i1 @abs_intrin_eq_zero(i8 %x) {
1208; CHECK-LABEL: @abs_intrin_eq_zero(
1209; CHECK-NEXT:    [[CMP:%.*]] = icmp eq i8 [[X:%.*]], 0
1210; CHECK-NEXT:    ret i1 [[CMP]]
1211;
1212  %abs = call i8 @llvm.abs.i8(i8 %x, i1 false)
1213  %cmp = icmp eq i8 %abs, 0
1214  ret i1 %cmp
1215}
1216
1217define i1 @abs_intrin_ne_zero(i8 %x) {
1218; CHECK-LABEL: @abs_intrin_ne_zero(
1219; CHECK-NEXT:    [[CMP:%.*]] = icmp ne i8 [[X:%.*]], 0
1220; CHECK-NEXT:    ret i1 [[CMP]]
1221;
1222  %abs = call i8 @llvm.abs.i8(i8 %x, i1 false)
1223  %cmp = icmp ne i8 %abs, 0
1224  ret i1 %cmp
1225}
1226
1227define void @test58() {
1228; CHECK-LABEL: @test58(
1229; CHECK-NEXT:    [[CALL:%.*]] = call i32 @test58_d(i64 36029346783166592)
1230; CHECK-NEXT:    ret void
1231;
1232  %cast = bitcast <1 x i64> <i64 36029346783166592> to i64
1233  %call = call i32 @test58_d( i64 %cast)
1234  ret void
1235}
1236declare i32 @test58_d(i64)
1237
1238; Negative test: GEP inbounds may cross sign boundary.
1239define i1 @test62(ptr %a) {
1240; CHECK-LABEL: @test62(
1241; CHECK-NEXT:    [[ARRAYIDX1:%.*]] = getelementptr inbounds nuw i8, ptr [[A:%.*]], i64 1
1242; CHECK-NEXT:    [[ARRAYIDX2:%.*]] = getelementptr inbounds nuw i8, ptr [[A]], i64 10
1243; CHECK-NEXT:    [[CMP:%.*]] = icmp slt ptr [[ARRAYIDX1]], [[ARRAYIDX2]]
1244; CHECK-NEXT:    ret i1 [[CMP]]
1245;
1246  %arrayidx1 = getelementptr inbounds i8, ptr %a, i64 1
1247  %arrayidx2 = getelementptr inbounds i8, ptr %a, i64 10
1248  %cmp = icmp slt ptr %arrayidx1, %arrayidx2
1249  ret i1 %cmp
1250}
1251
1252define i1 @test62_as1(ptr addrspace(1) %a) {
1253; CHECK-LABEL: @test62_as1(
1254; CHECK-NEXT:    [[ARRAYIDX1:%.*]] = getelementptr inbounds nuw i8, ptr addrspace(1) [[A:%.*]], i16 1
1255; CHECK-NEXT:    [[ARRAYIDX2:%.*]] = getelementptr inbounds nuw i8, ptr addrspace(1) [[A]], i16 10
1256; CHECK-NEXT:    [[CMP:%.*]] = icmp slt ptr addrspace(1) [[ARRAYIDX1]], [[ARRAYIDX2]]
1257; CHECK-NEXT:    ret i1 [[CMP]]
1258;
1259  %arrayidx1 = getelementptr inbounds i8, ptr addrspace(1) %a, i64 1
1260  %arrayidx2 = getelementptr inbounds i8, ptr addrspace(1) %a, i64 10
1261  %cmp = icmp slt ptr addrspace(1) %arrayidx1, %arrayidx2
1262  ret i1 %cmp
1263}
1264
1265define i1 @low_mask_eq_zext(i8 %a, i32 %b) {
1266; CHECK-LABEL: @low_mask_eq_zext(
1267; CHECK-NEXT:    [[TMP1:%.*]] = trunc i32 [[B:%.*]] to i8
1268; CHECK-NEXT:    [[C:%.*]] = icmp eq i8 [[A:%.*]], [[TMP1]]
1269; CHECK-NEXT:    ret i1 [[C]]
1270;
1271  %z = zext i8 %a to i32
1272  %t = and i32 %b, 255
1273  %c = icmp eq i32 %z, %t
1274  ret i1 %c
1275}
1276
1277define i1 @low_mask_eq_zext_commute(i8 %a, i32 %b) {
1278; CHECK-LABEL: @low_mask_eq_zext_commute(
1279; CHECK-NEXT:    [[TMP1:%.*]] = trunc i32 [[B:%.*]] to i8
1280; CHECK-NEXT:    [[C:%.*]] = icmp eq i8 [[A:%.*]], [[TMP1]]
1281; CHECK-NEXT:    ret i1 [[C]]
1282;
1283  %t = and i32 %b, 255
1284  %z = zext i8 %a to i32
1285  %c = icmp eq i32 %t, %z
1286  ret i1 %c
1287}
1288
1289; negative test
1290
1291define i1 @wrong_low_mask_eq_zext(i8 %a, i32 %b) {
1292; CHECK-LABEL: @wrong_low_mask_eq_zext(
1293; CHECK-NEXT:    [[T:%.*]] = and i32 [[B:%.*]], 127
1294; CHECK-NEXT:    [[Z:%.*]] = zext i8 [[A:%.*]] to i32
1295; CHECK-NEXT:    [[C:%.*]] = icmp eq i32 [[T]], [[Z]]
1296; CHECK-NEXT:    ret i1 [[C]]
1297;
1298  %t = and i32 %b, 127
1299  %z = zext i8 %a to i32
1300  %c = icmp eq i32 %t, %z
1301  ret i1 %c
1302}
1303
1304; negative test
1305
1306define i1 @wrong_low_mask_eq_zext2(i8 %a, i32 %b) {
1307; CHECK-LABEL: @wrong_low_mask_eq_zext2(
1308; CHECK-NEXT:    [[T:%.*]] = and i32 [[B:%.*]], 254
1309; CHECK-NEXT:    [[Z:%.*]] = zext i8 [[A:%.*]] to i32
1310; CHECK-NEXT:    [[C:%.*]] = icmp eq i32 [[T]], [[Z]]
1311; CHECK-NEXT:    ret i1 [[C]]
1312;
1313  %t = and i32 %b, 254
1314  %z = zext i8 %a to i32
1315  %c = icmp eq i32 %t, %z
1316  ret i1 %c
1317}
1318
1319define i1 @low_mask_eq_zext_use1(i8 %a, i32 %b) {
1320; CHECK-LABEL: @low_mask_eq_zext_use1(
1321; CHECK-NEXT:    [[T:%.*]] = and i32 [[B:%.*]], 255
1322; CHECK-NEXT:    call void @use_i32(i32 [[T]])
1323; CHECK-NEXT:    [[TMP1:%.*]] = trunc i32 [[B]] to i8
1324; CHECK-NEXT:    [[C:%.*]] = icmp eq i8 [[A:%.*]], [[TMP1]]
1325; CHECK-NEXT:    ret i1 [[C]]
1326;
1327  %t = and i32 %b, 255
1328  call void @use_i32(i32 %t)
1329  %z = zext i8 %a to i32
1330  %c = icmp eq i32 %t, %z
1331  ret i1 %c
1332}
1333
1334define i1 @low_mask_eq_zext_use2(i8 %a, i32 %b) {
1335; CHECK-LABEL: @low_mask_eq_zext_use2(
1336; CHECK-NEXT:    [[Z:%.*]] = zext i8 [[A:%.*]] to i32
1337; CHECK-NEXT:    call void @use_i32(i32 [[Z]])
1338; CHECK-NEXT:    [[TMP1:%.*]] = trunc i32 [[B:%.*]] to i8
1339; CHECK-NEXT:    [[C:%.*]] = icmp eq i8 [[A]], [[TMP1]]
1340; CHECK-NEXT:    ret i1 [[C]]
1341;
1342  %t = and i32 %b, 255
1343  %z = zext i8 %a to i32
1344  call void @use_i32(i32 %z)
1345  %c = icmp eq i32 %t, %z
1346  ret i1 %c
1347}
1348
1349define i1 @low_mask_eq_zext_use3(i8 %a, i32 %b) {
1350; CHECK-LABEL: @low_mask_eq_zext_use3(
1351; CHECK-NEXT:    [[T:%.*]] = and i32 [[B:%.*]], 255
1352; CHECK-NEXT:    call void @use_i32(i32 [[T]])
1353; CHECK-NEXT:    [[Z:%.*]] = zext i8 [[A:%.*]] to i32
1354; CHECK-NEXT:    call void @use_i32(i32 [[Z]])
1355; CHECK-NEXT:    [[C:%.*]] = icmp eq i32 [[T]], [[Z]]
1356; CHECK-NEXT:    ret i1 [[C]]
1357;
1358  %t = and i32 %b, 255
1359  call void @use_i32(i32 %t)
1360  %z = zext i8 %a to i32
1361  call void @use_i32(i32 %z)
1362  %c = icmp eq i32 %t, %z
1363  ret i1 %c
1364}
1365
1366define <2 x i1> @low_mask_eq_zext_vec_splat(<2 x i8> %a, <2 x i32> %b) {
1367; CHECK-LABEL: @low_mask_eq_zext_vec_splat(
1368; CHECK-NEXT:    [[TMP1:%.*]] = trunc <2 x i32> [[B:%.*]] to <2 x i8>
1369; CHECK-NEXT:    [[C:%.*]] = icmp eq <2 x i8> [[A:%.*]], [[TMP1]]
1370; CHECK-NEXT:    ret <2 x i1> [[C]]
1371;
1372  %t = and <2 x i32> %b, <i32 255, i32 255>
1373  %z = zext <2 x i8> %a to <2 x i32>
1374  %c = icmp eq <2 x i32> %t, %z
1375  ret <2 x i1> %c
1376}
1377
1378define i1 @test65(i64 %A, i64 %B) {
1379; CHECK-LABEL: @test65(
1380; CHECK-NEXT:    ret i1 true
1381;
1382  %s1 = add i64 %A, %B
1383  %s2 = add i64 %A, %B
1384  %cmp = icmp eq i64 %s1, %s2
1385  ret i1 %cmp
1386}
1387
1388define i1 @test66(i64 %A, i64 %B) {
1389; CHECK-LABEL: @test66(
1390; CHECK-NEXT:    ret i1 true
1391;
1392  %s1 = add i64 %A, %B
1393  %s2 = add i64 %B, %A
1394  %cmp = icmp eq i64 %s1, %s2
1395  ret i1 %cmp
1396}
1397
1398define i1 @test67(i32 %x) {
1399; CHECK-LABEL: @test67(
1400; CHECK-NEXT:    [[AND:%.*]] = and i32 [[X:%.*]], 96
1401; CHECK-NEXT:    [[CMP:%.*]] = icmp ne i32 [[AND]], 0
1402; CHECK-NEXT:    ret i1 [[CMP]]
1403;
1404  %and = and i32 %x, 127
1405  %cmp = icmp sgt i32 %and, 31
1406  ret i1 %cmp
1407}
1408
1409define i1 @test67inverse(i32 %x) {
1410; CHECK-LABEL: @test67inverse(
1411; CHECK-NEXT:    [[AND:%.*]] = and i32 [[X:%.*]], 96
1412; CHECK-NEXT:    [[CMP:%.*]] = icmp eq i32 [[AND]], 0
1413; CHECK-NEXT:    ret i1 [[CMP]]
1414;
1415  %and = and i32 %x, 127
1416  %cmp = icmp sle i32 %and, 31
1417  ret i1 %cmp
1418}
1419
1420; The test above relies on 3 different folds.
1421; This test only checks the last of those (icmp ugt -> icmp ne).
1422
1423define <2 x i1> @test67vec(<2 x i32> %x) {
1424; CHECK-LABEL: @test67vec(
1425; CHECK-NEXT:    [[AND:%.*]] = and <2 x i32> [[X:%.*]], splat (i32 96)
1426; CHECK-NEXT:    [[CMP:%.*]] = icmp ne <2 x i32> [[AND]], zeroinitializer
1427; CHECK-NEXT:    ret <2 x i1> [[CMP]]
1428;
1429  %and = and <2 x i32> %x, <i32 96, i32 96>
1430  %cmp = icmp ugt <2 x i32> %and, <i32 31, i32 31>
1431  ret <2 x i1> %cmp
1432}
1433
1434define <2 x i1> @test67vec2(<2 x i32> %x) {
1435; CHECK-LABEL: @test67vec2(
1436; CHECK-NEXT:    [[AND:%.*]] = and <2 x i32> [[X:%.*]], splat (i32 96)
1437; CHECK-NEXT:    [[CMP:%.*]] = icmp ne <2 x i32> [[AND]], zeroinitializer
1438; CHECK-NEXT:    ret <2 x i1> [[CMP]]
1439;
1440  %and = and <2 x i32> %x, <i32 127, i32 127>
1441  %cmp = icmp ugt <2 x i32> %and, <i32 31, i32 31>
1442  ret <2 x i1> %cmp
1443}
1444
1445define <2 x i1> @test67vecinverse(<2 x i32> %x) {
1446; CHECK-LABEL: @test67vecinverse(
1447; CHECK-NEXT:    [[AND:%.*]] = and <2 x i32> [[X:%.*]], splat (i32 96)
1448; CHECK-NEXT:    [[CMP:%.*]] = icmp eq <2 x i32> [[AND]], zeroinitializer
1449; CHECK-NEXT:    ret <2 x i1> [[CMP]]
1450;
1451  %and = and <2 x i32> %x, <i32 96, i32 96>
1452  %cmp = icmp sle <2 x i32> %and, <i32 31, i32 31>
1453  ret <2 x i1> %cmp
1454}
1455
1456define i1 @test68(i32 %x) {
1457; CHECK-LABEL: @test68(
1458; CHECK-NEXT:    [[AND:%.*]] = and i32 [[X:%.*]], 127
1459; CHECK-NEXT:    [[CMP:%.*]] = icmp samesign ugt i32 [[AND]], 30
1460; CHECK-NEXT:    ret i1 [[CMP]]
1461;
1462  %and = and i32 %x, 127
1463  %cmp = icmp sgt i32 %and, 30
1464  ret i1 %cmp
1465}
1466
1467; PR15940
1468define i1 @test70(i32 %X) {
1469; CHECK-LABEL: @test70(
1470; CHECK-NEXT:    [[A:%.*]] = srem i32 5, [[X:%.*]]
1471; CHECK-NEXT:    [[C:%.*]] = icmp ne i32 [[A]], 2
1472; CHECK-NEXT:    ret i1 [[C]]
1473;
1474  %A = srem i32 5, %X
1475  %B = add i32 %A, 2
1476  %C = icmp ne i32 %B, 4
1477  ret i1 %C
1478}
1479
1480define <2 x i1> @test70vec(<2 x i32> %X) {
1481; CHECK-LABEL: @test70vec(
1482; CHECK-NEXT:    [[C:%.*]] = icmp ne <2 x i32> [[X:%.*]], splat (i32 2)
1483; CHECK-NEXT:    ret <2 x i1> [[C]]
1484;
1485  %B = add <2 x i32> %X, <i32 2, i32 2>
1486  %C = icmp ne <2 x i32> %B, <i32 4, i32 4>
1487  ret <2 x i1> %C
1488}
1489
1490define i1 @icmp_sext16trunc(i32 %x) {
1491; CHECK-LABEL: @icmp_sext16trunc(
1492; CHECK-NEXT:    [[TMP1:%.*]] = trunc i32 [[X:%.*]] to i16
1493; CHECK-NEXT:    [[CMP:%.*]] = icmp slt i16 [[TMP1]], 36
1494; CHECK-NEXT:    ret i1 [[CMP]]
1495;
1496  %trunc = trunc i32 %x to i16
1497  %sext = sext i16 %trunc to i32
1498  %cmp = icmp slt i32 %sext, 36
1499  ret i1 %cmp
1500}
1501
1502define i1 @icmp_sext8trunc(i32 %x) {
1503; CHECK-LABEL: @icmp_sext8trunc(
1504; CHECK-NEXT:    [[TMP1:%.*]] = trunc i32 [[X:%.*]] to i8
1505; CHECK-NEXT:    [[CMP:%.*]] = icmp slt i8 [[TMP1]], 36
1506; CHECK-NEXT:    ret i1 [[CMP]]
1507;
1508  %trunc = trunc i32 %x to i8
1509  %sext = sext i8 %trunc to i32
1510  %cmp = icmp slt i32 %sext, 36
1511  ret i1 %cmp
1512}
1513
1514; Vectors should fold the same way.
1515define <2 x i1> @icmp_sext8trunc_vec(<2 x i32> %x) {
1516; CHECK-LABEL: @icmp_sext8trunc_vec(
1517; CHECK-NEXT:    [[TMP1:%.*]] = trunc <2 x i32> [[X:%.*]] to <2 x i8>
1518; CHECK-NEXT:    [[CMP:%.*]] = icmp slt <2 x i8> [[TMP1]], splat (i8 36)
1519; CHECK-NEXT:    ret <2 x i1> [[CMP]]
1520;
1521  %trunc = trunc <2 x i32> %x to <2 x i8>
1522  %sext = sext <2 x i8> %trunc to <2 x i32>
1523  %cmp = icmp slt <2 x i32> %sext, <i32 36, i32 36>
1524  ret <2 x i1> %cmp
1525}
1526
1527define i1 @icmp_shl16(i32 %x) {
1528; CHECK-LABEL: @icmp_shl16(
1529; CHECK-NEXT:    [[TMP1:%.*]] = trunc i32 [[X:%.*]] to i16
1530; CHECK-NEXT:    [[CMP:%.*]] = icmp slt i16 [[TMP1]], 36
1531; CHECK-NEXT:    ret i1 [[CMP]]
1532;
1533  %shl = shl i32 %x, 16
1534  %cmp = icmp slt i32 %shl, 2359296
1535  ret i1 %cmp
1536}
1537
1538; D25952: Don't create illegal types like i15 in InstCombine
1539
1540define i1 @icmp_shl17(i32 %x) {
1541; CHECK-LABEL: @icmp_shl17(
1542; CHECK-NEXT:    [[SHL:%.*]] = shl i32 [[X:%.*]], 17
1543; CHECK-NEXT:    [[CMP:%.*]] = icmp slt i32 [[SHL]], 2359296
1544; CHECK-NEXT:    ret i1 [[CMP]]
1545;
1546  %shl = shl i32 %x, 17
1547  %cmp = icmp slt i32 %shl, 2359296
1548  ret i1 %cmp
1549}
1550
1551define <2 x i1> @icmp_shl16_vec(<2 x i32> %x) {
1552; CHECK-LABEL: @icmp_shl16_vec(
1553; CHECK-NEXT:    [[TMP1:%.*]] = trunc <2 x i32> [[X:%.*]] to <2 x i16>
1554; CHECK-NEXT:    [[CMP:%.*]] = icmp slt <2 x i16> [[TMP1]], splat (i16 36)
1555; CHECK-NEXT:    ret <2 x i1> [[CMP]]
1556;
1557  %shl = shl <2 x i32> %x, <i32 16, i32 16>
1558  %cmp = icmp slt <2 x i32> %shl, <i32 2359296, i32 2359296>
1559  ret <2 x i1> %cmp
1560}
1561
1562define i1 @icmp_shl24(i32 %x) {
1563; CHECK-LABEL: @icmp_shl24(
1564; CHECK-NEXT:    [[TMP1:%.*]] = trunc i32 [[X:%.*]] to i8
1565; CHECK-NEXT:    [[CMP:%.*]] = icmp slt i8 [[TMP1]], 36
1566; CHECK-NEXT:    ret i1 [[CMP]]
1567;
1568  %shl = shl i32 %x, 24
1569  %cmp = icmp slt i32 %shl, 603979776
1570  ret i1 %cmp
1571}
1572
1573define i1 @icmp_shl_eq(i32 %x) {
1574; CHECK-LABEL: @icmp_shl_eq(
1575; CHECK-NEXT:    [[MUL_MASK:%.*]] = and i32 [[X:%.*]], 134217727
1576; CHECK-NEXT:    [[CMP:%.*]] = icmp eq i32 [[MUL_MASK]], 0
1577; CHECK-NEXT:    ret i1 [[CMP]]
1578;
1579  %mul = shl i32 %x, 5
1580  %cmp = icmp eq i32 %mul, 0
1581  ret i1 %cmp
1582}
1583
1584define <2 x i1> @icmp_shl_eq_vec(<2 x i32> %x) {
1585; CHECK-LABEL: @icmp_shl_eq_vec(
1586; CHECK-NEXT:    [[MUL_MASK:%.*]] = and <2 x i32> [[X:%.*]], splat (i32 134217727)
1587; CHECK-NEXT:    [[CMP:%.*]] = icmp eq <2 x i32> [[MUL_MASK]], zeroinitializer
1588; CHECK-NEXT:    ret <2 x i1> [[CMP]]
1589;
1590  %mul = shl <2 x i32> %x, <i32 5, i32 5>
1591  %cmp = icmp eq <2 x i32> %mul, zeroinitializer
1592  ret <2 x i1> %cmp
1593}
1594
1595define i1 @icmp_shl_nsw_ne(i32 %x) {
1596; CHECK-LABEL: @icmp_shl_nsw_ne(
1597; CHECK-NEXT:    [[CMP:%.*]] = icmp ne i32 [[X:%.*]], 0
1598; CHECK-NEXT:    ret i1 [[CMP]]
1599;
1600  %mul = shl nsw i32 %x, 7
1601  %cmp = icmp ne i32 %mul, 0
1602  ret i1 %cmp
1603}
1604
1605define <2 x i1> @icmp_shl_nsw_ne_vec(<2 x i32> %x) {
1606; CHECK-LABEL: @icmp_shl_nsw_ne_vec(
1607; CHECK-NEXT:    [[CMP:%.*]] = icmp ne <2 x i32> [[X:%.*]], zeroinitializer
1608; CHECK-NEXT:    ret <2 x i1> [[CMP]]
1609;
1610  %mul = shl nsw <2 x i32> %x, <i32 7, i32 7>
1611  %cmp = icmp ne <2 x i32> %mul, zeroinitializer
1612  ret <2 x i1> %cmp
1613}
1614
1615define i1 @icmp_shl_ne(i32 %x) {
1616; CHECK-LABEL: @icmp_shl_ne(
1617; CHECK-NEXT:    [[MUL_MASK:%.*]] = and i32 [[X:%.*]], 33554431
1618; CHECK-NEXT:    [[CMP:%.*]] = icmp ne i32 [[MUL_MASK]], 0
1619; CHECK-NEXT:    ret i1 [[CMP]]
1620;
1621  %mul = shl i32 %x, 7
1622  %cmp = icmp ne i32 %mul, 0
1623  ret i1 %cmp
1624}
1625
1626define <2 x i1> @icmp_shl_ne_vec(<2 x i32> %x) {
1627; CHECK-LABEL: @icmp_shl_ne_vec(
1628; CHECK-NEXT:    [[MUL_MASK:%.*]] = and <2 x i32> [[X:%.*]], splat (i32 33554431)
1629; CHECK-NEXT:    [[CMP:%.*]] = icmp ne <2 x i32> [[MUL_MASK]], zeroinitializer
1630; CHECK-NEXT:    ret <2 x i1> [[CMP]]
1631;
1632  %mul = shl <2 x i32> %x, <i32 7, i32 7>
1633  %cmp = icmp ne <2 x i32> %mul, zeroinitializer
1634  ret <2 x i1> %cmp
1635}
1636
1637define <2 x i1> @icmp_shl_nuw_ne_vec(<2 x i32> %x) {
1638; CHECK-LABEL: @icmp_shl_nuw_ne_vec(
1639; CHECK-NEXT:    [[CMP:%.*]] = icmp ne <2 x i32> [[X:%.*]], splat (i32 2)
1640; CHECK-NEXT:    ret <2 x i1> [[CMP]]
1641;
1642  %shl = shl nuw <2 x i32> %x, <i32 7, i32 7>
1643  %cmp = icmp ne <2 x i32> %shl, <i32 256, i32 256>
1644  ret <2 x i1> %cmp
1645}
1646
1647; If the (mul x, C) preserved the sign and this is sign test,
1648; compare the LHS operand instead
1649define i1 @icmp_mul_nsw(i32 %x) {
1650; CHECK-LABEL: @icmp_mul_nsw(
1651; CHECK-NEXT:    [[CMP:%.*]] = icmp sgt i32 [[X:%.*]], 0
1652; CHECK-NEXT:    ret i1 [[CMP]]
1653;
1654  %mul = mul nsw i32 %x, 12
1655  %cmp = icmp sgt i32 %mul, 0
1656  ret i1 %cmp
1657}
1658
1659define i1 @icmp_mul_nsw1(i32 %x) {
1660; CHECK-LABEL: @icmp_mul_nsw1(
1661; CHECK-NEXT:    [[CMP:%.*]] = icmp slt i32 [[X:%.*]], 0
1662; CHECK-NEXT:    ret i1 [[CMP]]
1663;
1664  %mul = mul nsw i32 %x, 12
1665  %cmp = icmp sle i32 %mul, -1
1666  ret i1 %cmp
1667}
1668
1669define i1 @icmp_mul_nsw_neg(i32 %x) {
1670; CHECK-LABEL: @icmp_mul_nsw_neg(
1671; CHECK-NEXT:    [[CMP:%.*]] = icmp slt i32 [[X:%.*]], 1
1672; CHECK-NEXT:    ret i1 [[CMP]]
1673;
1674  %mul = mul nsw i32 %x, -12
1675  %cmp = icmp sge i32 %mul, 0
1676  ret i1 %cmp
1677}
1678
1679define i1 @icmp_mul_nsw_neg1(i32 %x) {
1680; CHECK-LABEL: @icmp_mul_nsw_neg1(
1681; CHECK-NEXT:    [[CMP:%.*]] = icmp slt i32 [[X:%.*]], 0
1682; CHECK-NEXT:    ret i1 [[CMP]]
1683;
1684  %mul = mul nsw i32 %x, -12
1685  %cmp = icmp sge i32 %mul, 1
1686  ret i1 %cmp
1687}
1688
1689define <2 x i1> @icmp_mul_nsw_neg1_vec(<2 x i32> %x) {
1690; CHECK-LABEL: @icmp_mul_nsw_neg1_vec(
1691; CHECK-NEXT:    [[CMP:%.*]] = icmp slt <2 x i32> [[X:%.*]], zeroinitializer
1692; CHECK-NEXT:    ret <2 x i1> [[CMP]]
1693;
1694  %mul = mul nsw <2 x i32> %x, <i32 -12, i32 -12>
1695  %cmp = icmp sge <2 x i32> %mul, <i32 1, i32 1>
1696  ret <2 x i1> %cmp
1697}
1698
1699define i1 @icmp_mul_nsw_0(i32 %x) {
1700; CHECK-LABEL: @icmp_mul_nsw_0(
1701; CHECK-NEXT:    ret i1 false
1702;
1703  %mul = mul nsw i32 %x, 0
1704  %cmp = icmp sgt i32 %mul, 0
1705  ret i1 %cmp
1706}
1707
1708define i1 @icmp_mul(i32 %x) {
1709; CHECK-LABEL: @icmp_mul(
1710; CHECK-NEXT:    [[MUL:%.*]] = mul i32 [[X:%.*]], -12
1711; CHECK-NEXT:    [[CMP:%.*]] = icmp sgt i32 [[MUL]], -1
1712; CHECK-NEXT:    ret i1 [[CMP]]
1713;
1714  %mul = mul i32 %x, -12
1715  %cmp = icmp sge i32 %mul, 0
1716  ret i1 %cmp
1717}
1718
1719; Checks for icmp (eq|ne) (mul x, C), 0
1720define i1 @icmp_mul_neq0(i32 %x) {
1721; CHECK-LABEL: @icmp_mul_neq0(
1722; CHECK-NEXT:    [[CMP:%.*]] = icmp ne i32 [[X:%.*]], 0
1723; CHECK-NEXT:    ret i1 [[CMP]]
1724;
1725  %mul = mul nsw i32 %x, -12
1726  %cmp = icmp ne i32 %mul, 0
1727  ret i1 %cmp
1728}
1729
1730define <2 x i1> @icmp_mul_neq0_vec(<2 x i32> %x) {
1731; CHECK-LABEL: @icmp_mul_neq0_vec(
1732; CHECK-NEXT:    [[CMP:%.*]] = icmp ne <2 x i32> [[X:%.*]], zeroinitializer
1733; CHECK-NEXT:    ret <2 x i1> [[CMP]]
1734;
1735  %mul = mul nsw <2 x i32> %x, <i32 -12, i32 -12>
1736  %cmp = icmp ne <2 x i32> %mul, zeroinitializer
1737  ret <2 x i1> %cmp
1738}
1739
1740define i1 @icmp_mul_eq0(i32 %x) {
1741; CHECK-LABEL: @icmp_mul_eq0(
1742; CHECK-NEXT:    [[CMP:%.*]] = icmp eq i32 [[X:%.*]], 0
1743; CHECK-NEXT:    ret i1 [[CMP]]
1744;
1745  %mul = mul nsw i32 %x, 12
1746  %cmp = icmp eq i32 %mul, 0
1747  ret i1 %cmp
1748}
1749
1750define i1 @icmp_mul0_eq0(i32 %x) {
1751; CHECK-LABEL: @icmp_mul0_eq0(
1752; CHECK-NEXT:    ret i1 true
1753;
1754  %mul = mul i32 %x, 0
1755  %cmp = icmp eq i32 %mul, 0
1756  ret i1 %cmp
1757}
1758
1759define i1 @icmp_mul0_ne0(i32 %x) {
1760; CHECK-LABEL: @icmp_mul0_ne0(
1761; CHECK-NEXT:    ret i1 false
1762;
1763  %mul = mul i32 %x, 0
1764  %cmp = icmp ne i32 %mul, 0
1765  ret i1 %cmp
1766}
1767
1768define i1 @icmp_add20_eq_add57(i32 %x, i32 %y) {
1769; CHECK-LABEL: @icmp_add20_eq_add57(
1770; CHECK-NEXT:    [[TMP1:%.*]] = add i32 [[Y:%.*]], 37
1771; CHECK-NEXT:    [[CMP:%.*]] = icmp eq i32 [[X:%.*]], [[TMP1]]
1772; CHECK-NEXT:    ret i1 [[CMP]]
1773;
1774  %1 = add i32 %x, 20
1775  %2 = add i32 %y, 57
1776  %cmp = icmp eq i32 %1, %2
1777  ret i1 %cmp
1778}
1779
1780define <2 x i1> @icmp_add20_eq_add57_splat(<2 x i32> %x, <2 x i32> %y) {
1781; CHECK-LABEL: @icmp_add20_eq_add57_splat(
1782; CHECK-NEXT:    [[TMP1:%.*]] = add <2 x i32> [[Y:%.*]], splat (i32 37)
1783; CHECK-NEXT:    [[CMP:%.*]] = icmp eq <2 x i32> [[X:%.*]], [[TMP1]]
1784; CHECK-NEXT:    ret <2 x i1> [[CMP]]
1785;
1786  %1 = add <2 x i32> %x, <i32 20, i32 20>
1787  %2 = add <2 x i32> %y, <i32 57, i32 57>
1788  %cmp = icmp eq <2 x i32> %1, %2
1789  ret <2 x i1> %cmp
1790}
1791
1792define <2 x i1> @icmp_add20_eq_add57_poison(<2 x i32> %x, <2 x i32> %y) {
1793; CHECK-LABEL: @icmp_add20_eq_add57_poison(
1794; CHECK-NEXT:    [[TMP1:%.*]] = add <2 x i32> [[Y:%.*]], splat (i32 37)
1795; CHECK-NEXT:    [[CMP:%.*]] = icmp eq <2 x i32> [[X:%.*]], [[TMP1]]
1796; CHECK-NEXT:    ret <2 x i1> [[CMP]]
1797;
1798  %1 = add <2 x i32> %x, <i32 20, i32 20>
1799  %2 = add <2 x i32> %y, <i32 57, i32 poison>
1800  %cmp = icmp eq <2 x i32> %1, %2
1801  ret <2 x i1> %cmp
1802}
1803
1804define <2 x i1> @icmp_add20_eq_add57_vec_nonsplat(<2 x i32> %x, <2 x i32> %y) {
1805; CHECK-LABEL: @icmp_add20_eq_add57_vec_nonsplat(
1806; CHECK-NEXT:    [[TMP1:%.*]] = add <2 x i32> [[Y:%.*]], <i32 37, i32 39>
1807; CHECK-NEXT:    [[CMP:%.*]] = icmp eq <2 x i32> [[X:%.*]], [[TMP1]]
1808; CHECK-NEXT:    ret <2 x i1> [[CMP]]
1809;
1810  %1 = add <2 x i32> %x, <i32 20, i32 19>
1811  %2 = add <2 x i32> %y, <i32 57, i32 58>
1812  %cmp = icmp eq <2 x i32> %1, %2
1813  ret <2 x i1> %cmp
1814}
1815
1816define i1 @icmp_sub57_ne_sub20(i32 %x, i32 %y) {
1817; CHECK-LABEL: @icmp_sub57_ne_sub20(
1818; CHECK-NEXT:    [[TMP1:%.*]] = add i32 [[X:%.*]], -37
1819; CHECK-NEXT:    [[CMP:%.*]] = icmp ne i32 [[TMP1]], [[Y:%.*]]
1820; CHECK-NEXT:    ret i1 [[CMP]]
1821;
1822  %1 = add i32 %x, -57
1823  %2 = add i32 %y, -20
1824  %cmp = icmp ne i32 %1, %2
1825  ret i1 %cmp
1826}
1827
1828define <2 x i1> @icmp_sub57_ne_sub20_splat(<2 x i32> %x, <2 x i32> %y) {
1829; CHECK-LABEL: @icmp_sub57_ne_sub20_splat(
1830; CHECK-NEXT:    [[TMP1:%.*]] = add <2 x i32> [[X:%.*]], splat (i32 -37)
1831; CHECK-NEXT:    [[CMP:%.*]] = icmp ne <2 x i32> [[TMP1]], [[Y:%.*]]
1832; CHECK-NEXT:    ret <2 x i1> [[CMP]]
1833;
1834  %1 = add <2 x i32> %x, <i32 -57, i32 -57>
1835  %2 = add <2 x i32> %y, <i32 -20, i32 -20>
1836  %cmp = icmp ne <2 x i32> %1, %2
1837  ret <2 x i1> %cmp
1838}
1839
1840define <2 x i1> @icmp_sub57_ne_sub20_vec_poison(<2 x i32> %x, <2 x i32> %y) {
1841; CHECK-LABEL: @icmp_sub57_ne_sub20_vec_poison(
1842; CHECK-NEXT:    [[TMP1:%.*]] = add <2 x i32> [[X:%.*]], splat (i32 -37)
1843; CHECK-NEXT:    [[CMP:%.*]] = icmp ne <2 x i32> [[TMP1]], [[Y:%.*]]
1844; CHECK-NEXT:    ret <2 x i1> [[CMP]]
1845;
1846  %1 = add <2 x i32> %x, <i32 -57, i32 poison>
1847  %2 = add <2 x i32> %y, <i32 -20, i32 poison>
1848  %cmp = icmp ne <2 x i32> %1, %2
1849  ret <2 x i1> %cmp
1850}
1851
1852define <2 x i1> @icmp_sub57_ne_sub20_vec_nonsplat(<2 x i32> %x, <2 x i32> %y) {
1853; CHECK-LABEL: @icmp_sub57_ne_sub20_vec_nonsplat(
1854; CHECK-NEXT:    [[TMP1:%.*]] = add <2 x i32> [[Y:%.*]], splat (i32 37)
1855; CHECK-NEXT:    [[CMP:%.*]] = icmp ne <2 x i32> [[X:%.*]], [[TMP1]]
1856; CHECK-NEXT:    ret <2 x i1> [[CMP]]
1857;
1858  %1 = add <2 x i32> %x, <i32 -57, i32 -58>
1859  %2 = add <2 x i32> %y, <i32 -20, i32 -21>
1860  %cmp = icmp ne <2 x i32> %1, %2
1861  ret <2 x i1> %cmp
1862}
1863
1864define i1 @icmp_sub1_sge(i32 %x, i32 %y) {
1865; CHECK-LABEL: @icmp_sub1_sge(
1866; CHECK-NEXT:    [[CMP:%.*]] = icmp sgt i32 [[X:%.*]], [[Y:%.*]]
1867; CHECK-NEXT:    ret i1 [[CMP]]
1868;
1869  %sub = add nsw i32 %x, -1
1870  %cmp = icmp sge i32 %sub, %y
1871  ret i1 %cmp
1872}
1873
1874define i1 @icmp_add1_sgt(i32 %x, i32 %y) {
1875; CHECK-LABEL: @icmp_add1_sgt(
1876; CHECK-NEXT:    [[CMP:%.*]] = icmp sge i32 [[X:%.*]], [[Y:%.*]]
1877; CHECK-NEXT:    ret i1 [[CMP]]
1878;
1879  %add = add nsw i32 %x, 1
1880  %cmp = icmp sgt i32 %add, %y
1881  ret i1 %cmp
1882}
1883
1884define i1 @icmp_sub1_slt(i32 %x, i32 %y) {
1885; CHECK-LABEL: @icmp_sub1_slt(
1886; CHECK-NEXT:    [[CMP:%.*]] = icmp sle i32 [[X:%.*]], [[Y:%.*]]
1887; CHECK-NEXT:    ret i1 [[CMP]]
1888;
1889  %sub = add nsw i32 %x, -1
1890  %cmp = icmp slt i32 %sub, %y
1891  ret i1 %cmp
1892}
1893
1894define i1 @icmp_add1_sle(i32 %x, i32 %y) {
1895; CHECK-LABEL: @icmp_add1_sle(
1896; CHECK-NEXT:    [[CMP:%.*]] = icmp slt i32 [[X:%.*]], [[Y:%.*]]
1897; CHECK-NEXT:    ret i1 [[CMP]]
1898;
1899  %add = add nsw i32 %x, 1
1900  %cmp = icmp sle i32 %add, %y
1901  ret i1 %cmp
1902}
1903
1904define i1 @icmp_add20_sge_add57(i32 %x, i32 %y) {
1905; CHECK-LABEL: @icmp_add20_sge_add57(
1906; CHECK-NEXT:    [[TMP1:%.*]] = add nsw i32 [[Y:%.*]], 37
1907; CHECK-NEXT:    [[CMP:%.*]] = icmp sge i32 [[X:%.*]], [[TMP1]]
1908; CHECK-NEXT:    ret i1 [[CMP]]
1909;
1910  %1 = add nsw i32 %x, 20
1911  %2 = add nsw i32 %y, 57
1912  %cmp = icmp sge i32 %1, %2
1913  ret i1 %cmp
1914}
1915
1916define <2 x i1> @icmp_add20_sge_add57_splat(<2 x i32> %x, <2 x i32> %y) {
1917; CHECK-LABEL: @icmp_add20_sge_add57_splat(
1918; CHECK-NEXT:    [[TMP1:%.*]] = add nsw <2 x i32> [[Y:%.*]], splat (i32 37)
1919; CHECK-NEXT:    [[CMP:%.*]] = icmp sge <2 x i32> [[X:%.*]], [[TMP1]]
1920; CHECK-NEXT:    ret <2 x i1> [[CMP]]
1921;
1922  %1 = add nsw <2 x i32> %x, <i32 20, i32 20>
1923  %2 = add nsw <2 x i32> %y, <i32 57, i32 57>
1924  %cmp = icmp sge <2 x i32> %1, %2
1925  ret <2 x i1> %cmp
1926}
1927
1928define <2 x i1> @icmp_add20_sge_add57_poison(<2 x i32> %x, <2 x i32> %y) {
1929; CHECK-LABEL: @icmp_add20_sge_add57_poison(
1930; CHECK-NEXT:    [[TMP1:%.*]] = add nsw <2 x i32> [[Y:%.*]], splat (i32 37)
1931; CHECK-NEXT:    [[CMP:%.*]] = icmp sge <2 x i32> [[X:%.*]], [[TMP1]]
1932; CHECK-NEXT:    ret <2 x i1> [[CMP]]
1933;
1934  %1 = add nsw <2 x i32> %x, <i32 20, i32 20>
1935  %2 = add nsw <2 x i32> %y, <i32 57, i32 poison>
1936  %cmp = icmp sge <2 x i32> %1, %2
1937  ret <2 x i1> %cmp
1938}
1939
1940define <2 x i1> @icmp_add20_sge_add57_vec_nonsplat(<2 x i32> %x, <2 x i32> %y) {
1941; CHECK-LABEL: @icmp_add20_sge_add57_vec_nonsplat(
1942; CHECK-NEXT:    [[TMP1:%.*]] = add nsw <2 x i32> [[X:%.*]], <i32 20, i32 19>
1943; CHECK-NEXT:    [[TMP2:%.*]] = add nsw <2 x i32> [[Y:%.*]], <i32 57, i32 58>
1944; CHECK-NEXT:    [[CMP:%.*]] = icmp sge <2 x i32> [[TMP1]], [[TMP2]]
1945; CHECK-NEXT:    ret <2 x i1> [[CMP]]
1946;
1947  %1 = add nsw <2 x i32> %x, <i32 20, i32 19>
1948  %2 = add nsw <2 x i32> %y, <i32 57, i32 58>
1949  %cmp = icmp sge <2 x i32> %1, %2
1950  ret <2 x i1> %cmp
1951}
1952
1953define i1 @icmp_sub57_sge_sub20(i32 %x, i32 %y) {
1954; CHECK-LABEL: @icmp_sub57_sge_sub20(
1955; CHECK-NEXT:    [[TMP1:%.*]] = add nsw i32 [[X:%.*]], -37
1956; CHECK-NEXT:    [[CMP:%.*]] = icmp sge i32 [[TMP1]], [[Y:%.*]]
1957; CHECK-NEXT:    ret i1 [[CMP]]
1958;
1959  %1 = add nsw i32 %x, -57
1960  %2 = add nsw i32 %y, -20
1961  %cmp = icmp sge i32 %1, %2
1962  ret i1 %cmp
1963}
1964
1965define <2 x i1> @icmp_sub57_sge_sub20_splat(<2 x i32> %x, <2 x i32> %y) {
1966; CHECK-LABEL: @icmp_sub57_sge_sub20_splat(
1967; CHECK-NEXT:    [[TMP1:%.*]] = add nsw <2 x i32> [[X:%.*]], splat (i32 -37)
1968; CHECK-NEXT:    [[CMP:%.*]] = icmp sge <2 x i32> [[TMP1]], [[Y:%.*]]
1969; CHECK-NEXT:    ret <2 x i1> [[CMP]]
1970;
1971  %1 = add nsw <2 x i32> %x, <i32 -57, i32 -57>
1972  %2 = add nsw <2 x i32> %y, <i32 -20, i32 -20>
1973  %cmp = icmp sge <2 x i32> %1, %2
1974  ret <2 x i1> %cmp
1975}
1976
1977define <2 x i1> @icmp_sub57_sge_sub20_vec_poison(<2 x i32> %x, <2 x i32> %y) {
1978; CHECK-LABEL: @icmp_sub57_sge_sub20_vec_poison(
1979; CHECK-NEXT:    [[TMP1:%.*]] = add nsw <2 x i32> [[X:%.*]], splat (i32 -37)
1980; CHECK-NEXT:    [[CMP:%.*]] = icmp sge <2 x i32> [[TMP1]], [[Y:%.*]]
1981; CHECK-NEXT:    ret <2 x i1> [[CMP]]
1982;
1983  %1 = add nsw <2 x i32> %x, <i32 -57, i32 poison>
1984  %2 = add nsw <2 x i32> %y, <i32 -20, i32 poison>
1985  %cmp = icmp sge <2 x i32> %1, %2
1986  ret <2 x i1> %cmp
1987}
1988
1989define <2 x i1> @icmp_sub57_sge_sub20_vec_nonsplat(<2 x i32> %x, <2 x i32> %y) {
1990; CHECK-LABEL: @icmp_sub57_sge_sub20_vec_nonsplat(
1991; CHECK-NEXT:    [[TMP1:%.*]] = add nsw <2 x i32> [[X:%.*]], <i32 -57, i32 -58>
1992; CHECK-NEXT:    [[TMP2:%.*]] = add nsw <2 x i32> [[Y:%.*]], <i32 -20, i32 -21>
1993; CHECK-NEXT:    [[CMP:%.*]] = icmp sge <2 x i32> [[TMP1]], [[TMP2]]
1994; CHECK-NEXT:    ret <2 x i1> [[CMP]]
1995;
1996  %1 = add nsw <2 x i32> %x, <i32 -57, i32 -58>
1997  %2 = add nsw <2 x i32> %y, <i32 -20, i32 -21>
1998  %cmp = icmp sge <2 x i32> %1, %2
1999  ret <2 x i1> %cmp
2000}
2001
2002define i1 @icmp_and_shl_neg_ne_0(i32 %A, i32 %B) {
2003; CHECK-LABEL: @icmp_and_shl_neg_ne_0(
2004; CHECK-NEXT:    [[SHL:%.*]] = shl nuw i32 1, [[B:%.*]]
2005; CHECK-NEXT:    [[TMP1:%.*]] = and i32 [[SHL]], [[A:%.*]]
2006; CHECK-NEXT:    [[CMP:%.*]] = icmp eq i32 [[TMP1]], 0
2007; CHECK-NEXT:    ret i1 [[CMP]]
2008;
2009  %neg = xor i32 %A, -1
2010  %shl = shl i32 1, %B
2011  %and = and i32 %shl, %neg
2012  %cmp = icmp ne i32 %and, 0
2013  ret i1 %cmp
2014}
2015
2016define i1 @icmp_and_shl_neg_ne_0_shl2_no_flags(i32 %A, i32 %B) {
2017; CHECK-LABEL: @icmp_and_shl_neg_ne_0_shl2_no_flags(
2018; CHECK-NEXT:    [[NEG:%.*]] = xor i32 [[A:%.*]], -1
2019; CHECK-NEXT:    [[SHL:%.*]] = shl i32 2, [[B:%.*]]
2020; CHECK-NEXT:    [[AND:%.*]] = and i32 [[SHL]], [[NEG]]
2021; CHECK-NEXT:    [[CMP:%.*]] = icmp ne i32 [[AND]], 0
2022; CHECK-NEXT:    ret i1 [[CMP]]
2023;
2024  %neg = xor i32 %A, -1
2025  %shl = shl i32 2, %B
2026  %and = and i32 %shl, %neg
2027  %cmp = icmp ne i32 %and, 0
2028  ret i1 %cmp
2029}
2030
2031define i1 @icmp_and_shl_neg_ne_0_shl2_nuw(i32 %A, i32 %B) {
2032; CHECK-LABEL: @icmp_and_shl_neg_ne_0_shl2_nuw(
2033; CHECK-NEXT:    [[SHL:%.*]] = shl nuw i32 2, [[B:%.*]]
2034; CHECK-NEXT:    [[TMP1:%.*]] = and i32 [[SHL]], [[A:%.*]]
2035; CHECK-NEXT:    [[CMP:%.*]] = icmp eq i32 [[TMP1]], 0
2036; CHECK-NEXT:    ret i1 [[CMP]]
2037;
2038  %neg = xor i32 %A, -1
2039  %shl = shl nuw i32 2, %B
2040  %and = and i32 %shl, %neg
2041  %cmp = icmp ne i32 %and, 0
2042  ret i1 %cmp
2043}
2044
2045define i1 @icmp_and_shl_neg_ne_0_shl2_nsw(i32 %A, i32 %B) {
2046; CHECK-LABEL: @icmp_and_shl_neg_ne_0_shl2_nsw(
2047; CHECK-NEXT:    [[SHL:%.*]] = shl nsw i32 2, [[B:%.*]]
2048; CHECK-NEXT:    [[TMP1:%.*]] = and i32 [[SHL]], [[A:%.*]]
2049; CHECK-NEXT:    [[CMP:%.*]] = icmp eq i32 [[TMP1]], 0
2050; CHECK-NEXT:    ret i1 [[CMP]]
2051;
2052  %neg = xor i32 %A, -1
2053  %shl = shl nsw i32 2, %B
2054  %and = and i32 %shl, %neg
2055  %cmp = icmp ne i32 %and, 0
2056  ret i1 %cmp
2057}
2058
2059define i1 @icmp_and_shl_neg_eq_0(i32 %A, i32 %B) {
2060; CHECK-LABEL: @icmp_and_shl_neg_eq_0(
2061; CHECK-NEXT:    [[SHL:%.*]] = shl nuw i32 1, [[B:%.*]]
2062; CHECK-NEXT:    [[TMP1:%.*]] = and i32 [[SHL]], [[A:%.*]]
2063; CHECK-NEXT:    [[CMP:%.*]] = icmp ne i32 [[TMP1]], 0
2064; CHECK-NEXT:    ret i1 [[CMP]]
2065;
2066  %neg = xor i32 %A, -1
2067  %shl = shl i32 1, %B
2068  %and = and i32 %shl, %neg
2069  %cmp = icmp eq i32 %and, 0
2070  ret i1 %cmp
2071}
2072
2073define i1 @icmp_add_and_shr_ne_0(i32 %X) {
2074; CHECK-LABEL: @icmp_add_and_shr_ne_0(
2075; CHECK-NEXT:    [[TMP1:%.*]] = and i32 [[X:%.*]], 240
2076; CHECK-NEXT:    [[TOBOOL:%.*]] = icmp ne i32 [[TMP1]], 224
2077; CHECK-NEXT:    ret i1 [[TOBOOL]]
2078;
2079  %shr = lshr i32 %X, 4
2080  %and = and i32 %shr, 15
2081  %add = add i32 %and, -14
2082  %tobool = icmp ne i32 %add, 0
2083  ret i1 %tobool
2084}
2085
2086define <2 x i1> @icmp_add_and_shr_ne_0_vec(<2 x i32> %X) {
2087; CHECK-LABEL: @icmp_add_and_shr_ne_0_vec(
2088; CHECK-NEXT:    [[TMP1:%.*]] = and <2 x i32> [[X:%.*]], splat (i32 240)
2089; CHECK-NEXT:    [[TOBOOL:%.*]] = icmp ne <2 x i32> [[TMP1]], splat (i32 224)
2090; CHECK-NEXT:    ret <2 x i1> [[TOBOOL]]
2091;
2092  %shr = lshr <2 x i32> %X, <i32 4, i32 4>
2093  %and = and <2 x i32> %shr, <i32 15, i32 15>
2094  %add = add <2 x i32> %and, <i32 -14, i32 -14>
2095  %tobool = icmp ne <2 x i32> %add, zeroinitializer
2096  ret <2 x i1> %tobool
2097}
2098
2099; Variation of the above with an extra use of the shift
2100define i1 @icmp_and_shr_multiuse(i32 %X) {
2101; CHECK-LABEL: @icmp_and_shr_multiuse(
2102; CHECK-NEXT:    [[TMP1:%.*]] = and i32 [[X:%.*]], 240
2103; CHECK-NEXT:    [[TOBOOL:%.*]] = icmp ne i32 [[TMP1]], 224
2104; CHECK-NEXT:    [[TMP2:%.*]] = and i32 [[X]], 496
2105; CHECK-NEXT:    [[TOBOOL2:%.*]] = icmp ne i32 [[TMP2]], 432
2106; CHECK-NEXT:    [[AND3:%.*]] = and i1 [[TOBOOL]], [[TOBOOL2]]
2107; CHECK-NEXT:    ret i1 [[AND3]]
2108;
2109  %shr = lshr i32 %X, 4
2110  %and = and i32 %shr, 15
2111  %and2 = and i32 %shr, 31 ; second use of the shift
2112  %tobool = icmp ne i32 %and, 14
2113  %tobool2 = icmp ne i32 %and2, 27
2114  %and3 = and i1 %tobool, %tobool2
2115  ret i1 %and3
2116}
2117
2118define i1 @icmp_and_shr_multiuse_logical(i32 %X) {
2119; CHECK-LABEL: @icmp_and_shr_multiuse_logical(
2120; CHECK-NEXT:    [[TMP1:%.*]] = and i32 [[X:%.*]], 240
2121; CHECK-NEXT:    [[TOBOOL:%.*]] = icmp ne i32 [[TMP1]], 224
2122; CHECK-NEXT:    [[TMP2:%.*]] = and i32 [[X]], 496
2123; CHECK-NEXT:    [[TOBOOL2:%.*]] = icmp ne i32 [[TMP2]], 432
2124; CHECK-NEXT:    [[AND3:%.*]] = and i1 [[TOBOOL]], [[TOBOOL2]]
2125; CHECK-NEXT:    ret i1 [[AND3]]
2126;
2127  %shr = lshr i32 %X, 4
2128  %and = and i32 %shr, 15
2129  %and2 = and i32 %shr, 31 ; second use of the shift
2130  %tobool = icmp ne i32 %and, 14
2131  %tobool2 = icmp ne i32 %and2, 27
2132  %and3 = select i1 %tobool, i1 %tobool2, i1 false
2133  ret i1 %and3
2134}
2135
2136; Variation of the above with an ashr
2137define i1 @icmp_and_ashr_multiuse(i32 %X) {
2138; CHECK-LABEL: @icmp_and_ashr_multiuse(
2139; CHECK-NEXT:    [[TMP1:%.*]] = and i32 [[X:%.*]], 240
2140; CHECK-NEXT:    [[TOBOOL:%.*]] = icmp ne i32 [[TMP1]], 224
2141; CHECK-NEXT:    [[TMP2:%.*]] = and i32 [[X]], 496
2142; CHECK-NEXT:    [[TOBOOL2:%.*]] = icmp ne i32 [[TMP2]], 432
2143; CHECK-NEXT:    [[AND3:%.*]] = and i1 [[TOBOOL]], [[TOBOOL2]]
2144; CHECK-NEXT:    ret i1 [[AND3]]
2145;
2146  %shr = ashr i32 %X, 4
2147  %and = and i32 %shr, 15
2148  %and2 = and i32 %shr, 31 ; second use of the shift
2149  %tobool = icmp ne i32 %and, 14
2150  %tobool2 = icmp ne i32 %and2, 27
2151  %and3 = and i1 %tobool, %tobool2
2152  ret i1 %and3
2153}
2154
2155define i1 @icmp_and_ashr_multiuse_logical(i32 %X) {
2156; CHECK-LABEL: @icmp_and_ashr_multiuse_logical(
2157; CHECK-NEXT:    [[TMP1:%.*]] = and i32 [[X:%.*]], 240
2158; CHECK-NEXT:    [[TOBOOL:%.*]] = icmp ne i32 [[TMP1]], 224
2159; CHECK-NEXT:    [[TMP2:%.*]] = and i32 [[X]], 496
2160; CHECK-NEXT:    [[TOBOOL2:%.*]] = icmp ne i32 [[TMP2]], 432
2161; CHECK-NEXT:    [[AND3:%.*]] = and i1 [[TOBOOL]], [[TOBOOL2]]
2162; CHECK-NEXT:    ret i1 [[AND3]]
2163;
2164  %shr = ashr i32 %X, 4
2165  %and = and i32 %shr, 15
2166  %and2 = and i32 %shr, 31 ; second use of the shift
2167  %tobool = icmp ne i32 %and, 14
2168  %tobool2 = icmp ne i32 %and2, 27
2169  %and3 = select i1 %tobool, i1 %tobool2, i1 false
2170  ret i1 %and3
2171}
2172
2173define i1 @icmp_lshr_and_overshift(i8 %X) {
2174; CHECK-LABEL: @icmp_lshr_and_overshift(
2175; CHECK-NEXT:    [[TOBOOL:%.*]] = icmp ugt i8 [[X:%.*]], 31
2176; CHECK-NEXT:    ret i1 [[TOBOOL]]
2177;
2178  %shr = lshr i8 %X, 5
2179  %and = and i8 %shr, 15
2180  %tobool = icmp ne i8 %and, 0
2181  ret i1 %tobool
2182}
2183
2184; We shouldn't simplify this because the and uses bits that are shifted in.
2185define i1 @icmp_ashr_and_overshift(i8 %X) {
2186; CHECK-LABEL: @icmp_ashr_and_overshift(
2187; CHECK-NEXT:    [[SHR:%.*]] = ashr i8 [[X:%.*]], 5
2188; CHECK-NEXT:    [[AND:%.*]] = and i8 [[SHR]], 15
2189; CHECK-NEXT:    [[TOBOOL:%.*]] = icmp ne i8 [[AND]], 0
2190; CHECK-NEXT:    ret i1 [[TOBOOL]]
2191;
2192  %shr = ashr i8 %X, 5
2193  %and = and i8 %shr, 15
2194  %tobool = icmp ne i8 %and, 0
2195  ret i1 %tobool
2196}
2197
2198define i1 @icmp_and_ashr_neg_and_legal(i8 %x) {
2199; CHECK-LABEL: @icmp_and_ashr_neg_and_legal(
2200; CHECK-NEXT:    [[CMP:%.*]] = icmp slt i8 [[X:%.*]], 32
2201; CHECK-NEXT:    ret i1 [[CMP]]
2202;
2203  %ashr = ashr i8 %x, 4
2204  %and = and i8 %ashr, -2
2205  %cmp = icmp slt i8 %and, 1
2206  ret i1 %cmp
2207}
2208
2209; Negative test.
2210define i1 @icmp_and_ashr_mixed_and_shiftout(i8 %x) {
2211; CHECK-LABEL: @icmp_and_ashr_mixed_and_shiftout(
2212; CHECK-NEXT:    [[ASHR:%.*]] = ashr i8 [[X:%.*]], 4
2213; CHECK-NEXT:    [[AND:%.*]] = and i8 [[ASHR]], 31
2214; CHECK-NEXT:    [[CMP:%.*]] = icmp samesign ugt i8 [[AND]], 8
2215; CHECK-NEXT:    ret i1 [[CMP]]
2216;
2217  %ashr = ashr i8 %x, 4
2218  %and = and i8 %ashr, 31
2219  %cmp = icmp ugt i8 %and, 8
2220  ret i1 %cmp
2221}
2222
2223define i1 @icmp_and_ashr_neg_cmp_slt_legal(i8 %x) {
2224; CHECK-LABEL: @icmp_and_ashr_neg_cmp_slt_legal(
2225; CHECK-NEXT:    [[TMP1:%.*]] = and i8 [[X:%.*]], -32
2226; CHECK-NEXT:    [[CMP:%.*]] = icmp slt i8 [[TMP1]], -64
2227; CHECK-NEXT:    ret i1 [[CMP]]
2228;
2229  %ashr = ashr i8 %x, 4
2230  %and = and i8 %ashr, -2
2231  %cmp = icmp slt i8 %and, -4
2232  ret i1 %cmp
2233}
2234
2235; Negative test.
2236define i1 @icmp_and_ashr_neg_cmp_slt_shiftout(i8 %x) {
2237; CHECK-LABEL: @icmp_and_ashr_neg_cmp_slt_shiftout(
2238; CHECK-NEXT:    [[ASHR:%.*]] = ashr i8 [[X:%.*]], 4
2239; CHECK-NEXT:    [[AND:%.*]] = and i8 [[ASHR]], -2
2240; CHECK-NEXT:    [[CMP:%.*]] = icmp slt i8 [[AND]], -68
2241; CHECK-NEXT:    ret i1 [[CMP]]
2242;
2243  %ashr = ashr i8 %x, 4
2244  %and = and i8 %ashr, -2
2245  %cmp = icmp slt i8 %and, -68
2246  ret i1 %cmp
2247}
2248
2249define i1 @icmp_and_ashr_neg_cmp_eq_legal(i8 %x) {
2250; CHECK-LABEL: @icmp_and_ashr_neg_cmp_eq_legal(
2251; CHECK-NEXT:    [[TMP1:%.*]] = and i8 [[X:%.*]], -32
2252; CHECK-NEXT:    [[CMP:%.*]] = icmp eq i8 [[TMP1]], -64
2253; CHECK-NEXT:    ret i1 [[CMP]]
2254;
2255  %ashr = ashr i8 %x, 4
2256  %and = and i8 %ashr, -2
2257  %cmp = icmp eq i8 %and, -4
2258  ret i1 %cmp
2259}
2260
2261define i1 @icmp_and_ashr_neg_cmp_eq_shiftout(i8 %x) {
2262; CHECK-LABEL: @icmp_and_ashr_neg_cmp_eq_shiftout(
2263; CHECK-NEXT:    ret i1 false
2264;
2265  %ashr = ashr i8 %x, 4
2266  %and = and i8 %ashr, -2
2267  %cmp = icmp eq i8 %and, -68
2268  ret i1 %cmp
2269}
2270
2271define i1 @icmp_and_ashr_neg_cmp_ne_shiftout(i8 %x) {
2272; CHECK-LABEL: @icmp_and_ashr_neg_cmp_ne_shiftout(
2273; CHECK-NEXT:    ret i1 true
2274;
2275  %ashr = ashr i8 %x, 4
2276  %and = and i8 %ashr, -2
2277  %cmp = icmp ne i8 %and, -68
2278  ret i1 %cmp
2279}
2280
2281define i1 @icmp_shl_1_V_ult_32(i32 %V) {
2282; CHECK-LABEL: @icmp_shl_1_V_ult_32(
2283; CHECK-NEXT:    [[CMP:%.*]] = icmp ult i32 [[V:%.*]], 5
2284; CHECK-NEXT:    ret i1 [[CMP]]
2285;
2286  %shl = shl i32 1, %V
2287  %cmp = icmp ult i32 %shl, 32
2288  ret i1 %cmp
2289}
2290
2291define <2 x i1> @icmp_shl_1_V_ult_32_vec(<2 x i32> %V) {
2292; CHECK-LABEL: @icmp_shl_1_V_ult_32_vec(
2293; CHECK-NEXT:    [[CMP:%.*]] = icmp ult <2 x i32> [[V:%.*]], splat (i32 5)
2294; CHECK-NEXT:    ret <2 x i1> [[CMP]]
2295;
2296  %shl = shl <2 x i32> <i32 1, i32 1>, %V
2297  %cmp = icmp ult <2 x i32> %shl, <i32 32, i32 32>
2298  ret <2 x i1> %cmp
2299}
2300
2301define i1 @icmp_shl_1_V_eq_32(i32 %V) {
2302; CHECK-LABEL: @icmp_shl_1_V_eq_32(
2303; CHECK-NEXT:    [[CMP:%.*]] = icmp eq i32 [[V:%.*]], 5
2304; CHECK-NEXT:    ret i1 [[CMP]]
2305;
2306  %shl = shl i32 1, %V
2307  %cmp = icmp eq i32 %shl, 32
2308  ret i1 %cmp
2309}
2310
2311define <2 x i1> @icmp_shl_1_V_eq_32_vec(<2 x i32> %V) {
2312; CHECK-LABEL: @icmp_shl_1_V_eq_32_vec(
2313; CHECK-NEXT:    [[CMP:%.*]] = icmp eq <2 x i32> [[V:%.*]], splat (i32 5)
2314; CHECK-NEXT:    ret <2 x i1> [[CMP]]
2315;
2316  %shl = shl <2 x i32> <i32 1, i32 1>, %V
2317  %cmp = icmp eq <2 x i32> %shl, <i32 32, i32 32>
2318  ret <2 x i1> %cmp
2319}
2320
2321define i1 @icmp_shl_1_V_ult_30(i32 %V) {
2322; CHECK-LABEL: @icmp_shl_1_V_ult_30(
2323; CHECK-NEXT:    [[CMP:%.*]] = icmp ult i32 [[V:%.*]], 5
2324; CHECK-NEXT:    ret i1 [[CMP]]
2325;
2326  %shl = shl i32 1, %V
2327  %cmp = icmp ult i32 %shl, 30
2328  ret i1 %cmp
2329}
2330
2331define <2 x i1> @icmp_shl_1_V_ult_30_vec(<2 x i32> %V) {
2332; CHECK-LABEL: @icmp_shl_1_V_ult_30_vec(
2333; CHECK-NEXT:    [[CMP:%.*]] = icmp ult <2 x i32> [[V:%.*]], splat (i32 5)
2334; CHECK-NEXT:    ret <2 x i1> [[CMP]]
2335;
2336  %shl = shl <2 x i32> <i32 1, i32 1>, %V
2337  %cmp = icmp ult <2 x i32> %shl, <i32 30, i32 30>
2338  ret <2 x i1> %cmp
2339}
2340
2341define i1 @icmp_shl_1_V_ugt_30(i32 %V) {
2342; CHECK-LABEL: @icmp_shl_1_V_ugt_30(
2343; CHECK-NEXT:    [[CMP:%.*]] = icmp ugt i32 [[V:%.*]], 4
2344; CHECK-NEXT:    ret i1 [[CMP]]
2345;
2346  %shl = shl i32 1, %V
2347  %cmp = icmp ugt i32 %shl, 30
2348  ret i1 %cmp
2349}
2350
2351define <2 x i1> @icmp_shl_1_V_ugt_30_vec(<2 x i32> %V) {
2352; CHECK-LABEL: @icmp_shl_1_V_ugt_30_vec(
2353; CHECK-NEXT:    [[CMP:%.*]] = icmp ugt <2 x i32> [[V:%.*]], splat (i32 4)
2354; CHECK-NEXT:    ret <2 x i1> [[CMP]]
2355;
2356  %shl = shl <2 x i32> <i32 1, i32 1>, %V
2357  %cmp = icmp ugt <2 x i32> %shl, <i32 30, i32 30>
2358  ret <2 x i1> %cmp
2359}
2360
2361define i1 @icmp_shl_1_V_ule_30(i32 %V) {
2362; CHECK-LABEL: @icmp_shl_1_V_ule_30(
2363; CHECK-NEXT:    [[CMP:%.*]] = icmp ult i32 [[V:%.*]], 5
2364; CHECK-NEXT:    ret i1 [[CMP]]
2365;
2366  %shl = shl i32 1, %V
2367  %cmp = icmp ule i32 %shl, 30
2368  ret i1 %cmp
2369}
2370
2371define <2 x i1> @icmp_shl_1_V_ule_30_vec(<2 x i32> %V) {
2372; CHECK-LABEL: @icmp_shl_1_V_ule_30_vec(
2373; CHECK-NEXT:    [[CMP:%.*]] = icmp ult <2 x i32> [[V:%.*]], splat (i32 5)
2374; CHECK-NEXT:    ret <2 x i1> [[CMP]]
2375;
2376  %shl = shl <2 x i32> <i32 1, i32 1>, %V
2377  %cmp = icmp ule <2 x i32> %shl, <i32 30, i32 30>
2378  ret <2 x i1> %cmp
2379}
2380
2381define i1 @icmp_shl_1_V_uge_30(i32 %V) {
2382; CHECK-LABEL: @icmp_shl_1_V_uge_30(
2383; CHECK-NEXT:    [[CMP:%.*]] = icmp ugt i32 [[V:%.*]], 4
2384; CHECK-NEXT:    ret i1 [[CMP]]
2385;
2386  %shl = shl i32 1, %V
2387  %cmp = icmp uge i32 %shl, 30
2388  ret i1 %cmp
2389}
2390
2391define <2 x i1> @icmp_shl_1_V_uge_30_vec(<2 x i32> %V) {
2392; CHECK-LABEL: @icmp_shl_1_V_uge_30_vec(
2393; CHECK-NEXT:    [[CMP:%.*]] = icmp ugt <2 x i32> [[V:%.*]], splat (i32 4)
2394; CHECK-NEXT:    ret <2 x i1> [[CMP]]
2395;
2396  %shl = shl <2 x i32> <i32 1, i32 1>, %V
2397  %cmp = icmp uge <2 x i32> %shl, <i32 30, i32 30>
2398  ret <2 x i1> %cmp
2399}
2400
2401define i1 @icmp_shl_1_V_uge_2147483648(i32 %V) {
2402; CHECK-LABEL: @icmp_shl_1_V_uge_2147483648(
2403; CHECK-NEXT:    [[CMP:%.*]] = icmp eq i32 [[V:%.*]], 31
2404; CHECK-NEXT:    ret i1 [[CMP]]
2405;
2406  %shl = shl i32 1, %V
2407  %cmp = icmp uge i32 %shl, 2147483648
2408  ret i1 %cmp
2409}
2410
2411define <2 x i1> @icmp_shl_1_V_uge_2147483648_vec(<2 x i32> %V) {
2412; CHECK-LABEL: @icmp_shl_1_V_uge_2147483648_vec(
2413; CHECK-NEXT:    [[CMP:%.*]] = icmp eq <2 x i32> [[V:%.*]], splat (i32 31)
2414; CHECK-NEXT:    ret <2 x i1> [[CMP]]
2415;
2416  %shl = shl <2 x i32> <i32 1, i32 1>, %V
2417  %cmp = icmp uge <2 x i32> %shl, <i32 2147483648, i32 2147483648>
2418  ret <2 x i1> %cmp
2419}
2420
2421define i1 @icmp_shl_1_V_ult_2147483648(i32 %V) {
2422; CHECK-LABEL: @icmp_shl_1_V_ult_2147483648(
2423; CHECK-NEXT:    [[CMP:%.*]] = icmp ne i32 [[V:%.*]], 31
2424; CHECK-NEXT:    ret i1 [[CMP]]
2425;
2426  %shl = shl i32 1, %V
2427  %cmp = icmp ult i32 %shl, 2147483648
2428  ret i1 %cmp
2429}
2430
2431define <2 x i1> @icmp_shl_1_V_ult_2147483648_vec(<2 x i32> %V) {
2432; CHECK-LABEL: @icmp_shl_1_V_ult_2147483648_vec(
2433; CHECK-NEXT:    [[CMP:%.*]] = icmp ne <2 x i32> [[V:%.*]], splat (i32 31)
2434; CHECK-NEXT:    ret <2 x i1> [[CMP]]
2435;
2436  %shl = shl <2 x i32> <i32 1, i32 1>, %V
2437  %cmp = icmp ult <2 x i32> %shl, <i32 2147483648, i32 2147483648>
2438  ret <2 x i1> %cmp
2439}
2440
2441define i1 @icmp_shl_1_V_sle_0(i32 %V) {
2442; CHECK-LABEL: @icmp_shl_1_V_sle_0(
2443; CHECK-NEXT:    [[CMP:%.*]] = icmp eq i32 [[V:%.*]], 31
2444; CHECK-NEXT:    ret i1 [[CMP]]
2445;
2446  %shl = shl i32 1, %V
2447  %cmp = icmp sle i32 %shl, 0
2448  ret i1 %cmp
2449}
2450
2451define <2 x i1> @icmp_shl_1_V_sle_0_vec(<2 x i32> %V) {
2452; CHECK-LABEL: @icmp_shl_1_V_sle_0_vec(
2453; CHECK-NEXT:    [[CMP:%.*]] = icmp eq <2 x i32> [[V:%.*]], splat (i32 31)
2454; CHECK-NEXT:    ret <2 x i1> [[CMP]]
2455;
2456  %shl = shl <2 x i32> <i32 1, i32 1>, %V
2457  %cmp = icmp sle <2 x i32> %shl, <i32 0, i32 0>
2458  ret <2 x i1> %cmp
2459}
2460
2461define i1 @icmp_shl_1_V_sle_negative(i32 %V) {
2462; CHECK-LABEL: @icmp_shl_1_V_sle_negative(
2463; CHECK-NEXT:    [[CMP:%.*]] = icmp eq i32 [[V:%.*]], 31
2464; CHECK-NEXT:    ret i1 [[CMP]]
2465;
2466  %shl = shl i32 1, %V
2467  %cmp = icmp sle i32 %shl, -42
2468  ret i1 %cmp
2469}
2470
2471define <2 x i1> @icmp_shl_1_V_sle_0_negative(<2 x i32> %V) {
2472; CHECK-LABEL: @icmp_shl_1_V_sle_0_negative(
2473; CHECK-NEXT:    [[CMP:%.*]] = icmp eq <2 x i32> [[V:%.*]], splat (i32 31)
2474; CHECK-NEXT:    ret <2 x i1> [[CMP]]
2475;
2476  %shl = shl <2 x i32> <i32 1, i32 1>, %V
2477  %cmp = icmp sle <2 x i32> %shl, <i32 -2147483647, i32 -2147483647>
2478  ret <2 x i1> %cmp
2479}
2480
2481define i1 @icmp_shl_1_V_sgt_0(i32 %V) {
2482; CHECK-LABEL: @icmp_shl_1_V_sgt_0(
2483; CHECK-NEXT:    [[CMP:%.*]] = icmp ne i32 [[V:%.*]], 31
2484; CHECK-NEXT:    ret i1 [[CMP]]
2485;
2486  %shl = shl i32 1, %V
2487  %cmp = icmp sgt i32 %shl, 0
2488  ret i1 %cmp
2489}
2490
2491define <2 x i1> @icmp_shl_1_V_sgt_0_vec(<2 x i32> %V) {
2492; CHECK-LABEL: @icmp_shl_1_V_sgt_0_vec(
2493; CHECK-NEXT:    [[CMP:%.*]] = icmp ne <2 x i32> [[V:%.*]], splat (i32 31)
2494; CHECK-NEXT:    ret <2 x i1> [[CMP]]
2495;
2496  %shl = shl <2 x i32> <i32 1, i32 1>, %V
2497  %cmp = icmp sgt <2 x i32> %shl, <i32 0, i32 0>
2498  ret <2 x i1> %cmp
2499}
2500
2501define i1 @icmp_shl_1_V_sgt_negative(i32 %V) {
2502; CHECK-LABEL: @icmp_shl_1_V_sgt_negative(
2503; CHECK-NEXT:    [[CMP:%.*]] = icmp ne i32 [[V:%.*]], 31
2504; CHECK-NEXT:    ret i1 [[CMP]]
2505;
2506  %shl = shl i32 1, %V
2507  %cmp = icmp sgt i32 %shl, -12345
2508  ret i1 %cmp
2509}
2510
2511define <2 x i1> @icmp_shl_1_V_sgt_negative_vec(<2 x i32> %V) {
2512; CHECK-LABEL: @icmp_shl_1_V_sgt_negative_vec(
2513; CHECK-NEXT:    [[CMP:%.*]] = icmp ne <2 x i32> [[V:%.*]], splat (i32 31)
2514; CHECK-NEXT:    ret <2 x i1> [[CMP]]
2515;
2516  %shl = shl <2 x i32> <i32 1, i32 1>, %V
2517  %cmp = icmp sgt <2 x i32> %shl, <i32 -2, i32 -2>
2518  ret <2 x i1> %cmp
2519}
2520
2521define i1 @or_icmp_eq_B_0_icmp_ult_A_B(i64 %a, i64 %b) {
2522; CHECK-LABEL: @or_icmp_eq_B_0_icmp_ult_A_B(
2523; CHECK-NEXT:    [[TMP1:%.*]] = add i64 [[B:%.*]], -1
2524; CHECK-NEXT:    [[TMP2:%.*]] = icmp uge i64 [[TMP1]], [[A:%.*]]
2525; CHECK-NEXT:    ret i1 [[TMP2]]
2526;
2527  %1 = icmp eq i64 %b, 0
2528  %2 = icmp ult i64 %a, %b
2529  %3 = or i1 %1, %2
2530  ret i1 %3
2531}
2532
2533define i1 @or_icmp_eq_B_0_icmp_ult_A_B_logical(i64 %a, i64 %b) {
2534; CHECK-LABEL: @or_icmp_eq_B_0_icmp_ult_A_B_logical(
2535; CHECK-NEXT:    [[TMP1:%.*]] = freeze i64 [[A:%.*]]
2536; CHECK-NEXT:    [[TMP2:%.*]] = add i64 [[B:%.*]], -1
2537; CHECK-NEXT:    [[TMP3:%.*]] = icmp uge i64 [[TMP2]], [[TMP1]]
2538; CHECK-NEXT:    ret i1 [[TMP3]]
2539;
2540  %1 = icmp eq i64 %b, 0
2541  %2 = icmp ult i64 %a, %b
2542  %3 = select i1 %1, i1 true, i1 %2
2543  ret i1 %3
2544}
2545
2546define <2 x i1> @or_icmp_eq_B_0_icmp_ult_A_B_uniform(<2 x i64> %a, <2 x i64> %b) {
2547; CHECK-LABEL: @or_icmp_eq_B_0_icmp_ult_A_B_uniform(
2548; CHECK-NEXT:    [[TMP1:%.*]] = add <2 x i64> [[B:%.*]], splat (i64 -1)
2549; CHECK-NEXT:    [[TMP2:%.*]] = icmp uge <2 x i64> [[TMP1]], [[A:%.*]]
2550; CHECK-NEXT:    ret <2 x i1> [[TMP2]]
2551;
2552  %1 = icmp eq <2 x i64> %b, zeroinitializer
2553  %2 = icmp ult <2 x i64> %a, %b
2554  %3 = or <2 x i1> %1, %2
2555  ret <2 x i1> %3
2556}
2557
2558define <2 x i1> @or_icmp_eq_B_0_icmp_ult_A_B_poison(<2 x i64> %a, <2 x i64> %b) {
2559; CHECK-LABEL: @or_icmp_eq_B_0_icmp_ult_A_B_poison(
2560; CHECK-NEXT:    [[TMP1:%.*]] = add <2 x i64> [[B:%.*]], splat (i64 -1)
2561; CHECK-NEXT:    [[TMP2:%.*]] = icmp uge <2 x i64> [[TMP1]], [[A:%.*]]
2562; CHECK-NEXT:    ret <2 x i1> [[TMP2]]
2563;
2564  %1 = icmp eq <2 x i64> %b, <i64 0, i64 poison>
2565  %2 = icmp ult <2 x i64> %a, %b
2566  %3 = or <2 x i1> %1, %2
2567  ret <2 x i1> %3
2568}
2569
2570define i1 @or_icmp_ne_A_0_icmp_ne_B_0(i64 %a, i64 %b) {
2571; CHECK-LABEL: @or_icmp_ne_A_0_icmp_ne_B_0(
2572; CHECK-NEXT:    [[TMP1:%.*]] = or i64 [[A:%.*]], [[B:%.*]]
2573; CHECK-NEXT:    [[TMP2:%.*]] = icmp ne i64 [[TMP1]], 0
2574; CHECK-NEXT:    ret i1 [[TMP2]]
2575;
2576  %1 = icmp ne i64 %a, 0
2577  %2 = icmp ne i64 %b, 0
2578  %3 = or i1 %1, %2
2579  ret i1 %3
2580}
2581
2582define i1 @or_icmp_ne_A_0_icmp_ne_B_0_logical(i64 %a, i64 %b) {
2583; CHECK-LABEL: @or_icmp_ne_A_0_icmp_ne_B_0_logical(
2584; CHECK-NEXT:    [[TMP1:%.*]] = icmp ne i64 [[A:%.*]], 0
2585; CHECK-NEXT:    [[TMP2:%.*]] = icmp ne i64 [[B:%.*]], 0
2586; CHECK-NEXT:    [[TMP3:%.*]] = select i1 [[TMP1]], i1 true, i1 [[TMP2]]
2587; CHECK-NEXT:    ret i1 [[TMP3]]
2588;
2589  %1 = icmp ne i64 %a, 0
2590  %2 = icmp ne i64 %b, 0
2591  %3 = select i1 %1, i1 true, i1 %2
2592  ret i1 %3
2593}
2594
2595define <2 x i1> @or_icmp_ne_A_0_icmp_ne_B_0_uniform(<2 x i64> %a, <2 x i64> %b) {
2596; CHECK-LABEL: @or_icmp_ne_A_0_icmp_ne_B_0_uniform(
2597; CHECK-NEXT:    [[TMP1:%.*]] = or <2 x i64> [[A:%.*]], [[B:%.*]]
2598; CHECK-NEXT:    [[TMP2:%.*]] = icmp ne <2 x i64> [[TMP1]], zeroinitializer
2599; CHECK-NEXT:    ret <2 x i1> [[TMP2]]
2600;
2601  %1 = icmp ne <2 x i64> %a, zeroinitializer
2602  %2 = icmp ne <2 x i64> %b, zeroinitializer
2603  %3 = or <2 x i1> %1, %2
2604  ret <2 x i1> %3
2605}
2606
2607define <2 x i1> @or_icmp_ne_A_0_icmp_ne_B_0_poison(<2 x i64> %a, <2 x i64> %b) {
2608; CHECK-LABEL: @or_icmp_ne_A_0_icmp_ne_B_0_poison(
2609; CHECK-NEXT:    [[TMP1:%.*]] = or <2 x i64> [[A:%.*]], [[B:%.*]]
2610; CHECK-NEXT:    [[TMP2:%.*]] = icmp ne <2 x i64> [[TMP1]], zeroinitializer
2611; CHECK-NEXT:    ret <2 x i1> [[TMP2]]
2612;
2613  %1 = icmp ne <2 x i64> %a, <i64 0, i64 poison>
2614  %2 = icmp ne <2 x i64> %b, <i64 0, i64 poison>
2615  %3 = or <2 x i1> %1, %2
2616  ret <2 x i1> %3
2617}
2618
2619define i1 @and_icmp_ne_B_0_icmp_uge_A_B(i64 %a, i64 %b) {
2620; CHECK-LABEL: @and_icmp_ne_B_0_icmp_uge_A_B(
2621; CHECK-NEXT:    [[TMP1:%.*]] = add i64 [[B:%.*]], -1
2622; CHECK-NEXT:    [[TMP2:%.*]] = icmp ult i64 [[TMP1]], [[A:%.*]]
2623; CHECK-NEXT:    ret i1 [[TMP2]]
2624;
2625  %1 = icmp ne i64 %b, 0
2626  %2 = icmp uge i64 %a, %b
2627  %3 = and i1 %1, %2
2628  ret i1 %3
2629}
2630
2631define i1 @and_icmp_ne_B_0_icmp_uge_A_B_commuted1(i64 %a, i64 %b) {
2632; CHECK-LABEL: @and_icmp_ne_B_0_icmp_uge_A_B_commuted1(
2633; CHECK-NEXT:    [[TMP1:%.*]] = add i64 [[B:%.*]], -1
2634; CHECK-NEXT:    [[TMP2:%.*]] = icmp ult i64 [[TMP1]], [[A:%.*]]
2635; CHECK-NEXT:    ret i1 [[TMP2]]
2636;
2637  %1 = icmp uge i64 %a, %b
2638  %2 = icmp ne i64 %b, 0
2639  %3 = and i1 %1, %2
2640  ret i1 %3
2641}
2642
2643define i1 @and_icmp_ne_B_0_icmp_uge_A_B_commuted2(i64 %a, i64 %b) {
2644; CHECK-LABEL: @and_icmp_ne_B_0_icmp_uge_A_B_commuted2(
2645; CHECK-NEXT:    [[TMP1:%.*]] = add i64 [[B:%.*]], -1
2646; CHECK-NEXT:    [[TMP2:%.*]] = icmp ult i64 [[TMP1]], [[A:%.*]]
2647; CHECK-NEXT:    ret i1 [[TMP2]]
2648;
2649  %1 = icmp ne i64 %b, 0
2650  %2 = icmp ule i64 %b, %a
2651  %3 = and i1 %1, %2
2652  ret i1 %3
2653}
2654
2655define i1 @and_icmp_ne_B_0_icmp_uge_A_B_commuted1_logical(i64 %a, i64 %b) {
2656; CHECK-LABEL: @and_icmp_ne_B_0_icmp_uge_A_B_commuted1_logical(
2657; CHECK-NEXT:    [[TMP1:%.*]] = add i64 [[B:%.*]], -1
2658; CHECK-NEXT:    [[TMP2:%.*]] = icmp ult i64 [[TMP1]], [[A:%.*]]
2659; CHECK-NEXT:    ret i1 [[TMP2]]
2660;
2661  %1 = icmp uge i64 %a, %b
2662  %2 = icmp ne i64 %b, 0
2663  %3 = select i1 %1, i1 %2, i1 false
2664  ret i1 %3
2665}
2666
2667define i1 @and_icmp_ne_B_0_icmp_uge_A_B_commuted2_logical(i64 %a, i64 %b) {
2668; CHECK-LABEL: @and_icmp_ne_B_0_icmp_uge_A_B_commuted2_logical(
2669; CHECK-NEXT:    [[TMP1:%.*]] = freeze i64 [[A:%.*]]
2670; CHECK-NEXT:    [[TMP2:%.*]] = add i64 [[B:%.*]], -1
2671; CHECK-NEXT:    [[TMP3:%.*]] = icmp ult i64 [[TMP2]], [[TMP1]]
2672; CHECK-NEXT:    ret i1 [[TMP3]]
2673;
2674  %1 = icmp ne i64 %b, 0
2675  %2 = icmp ule i64 %b, %a
2676  %3 = select i1 %1, i1 %2, i1 false
2677  ret i1 %3
2678}
2679
2680define i1 @and_icmp_ne_B_0_icmp_uge_A_B_extra_use1(i64 %a, i64 %b) {
2681; CHECK-LABEL: @and_icmp_ne_B_0_icmp_uge_A_B_extra_use1(
2682; CHECK-NEXT:    [[TMP1:%.*]] = icmp ne i64 [[B:%.*]], 0
2683; CHECK-NEXT:    call void @use_i1(i1 [[TMP1]])
2684; CHECK-NEXT:    [[TMP2:%.*]] = add i64 [[B]], -1
2685; CHECK-NEXT:    [[TMP3:%.*]] = icmp ult i64 [[TMP2]], [[A:%.*]]
2686; CHECK-NEXT:    ret i1 [[TMP3]]
2687;
2688  %1 = icmp ne i64 %b, 0
2689  call void @use_i1(i1 %1)
2690  %2 = icmp uge i64 %a, %b
2691  %3 = and i1 %1, %2
2692  ret i1 %3
2693}
2694
2695define i1 @and_icmp_ne_B_0_icmp_uge_A_B_extra_use2(i64 %a, i64 %b) {
2696; CHECK-LABEL: @and_icmp_ne_B_0_icmp_uge_A_B_extra_use2(
2697; CHECK-NEXT:    [[TMP1:%.*]] = icmp uge i64 [[A:%.*]], [[B:%.*]]
2698; CHECK-NEXT:    call void @use_i1(i1 [[TMP1]])
2699; CHECK-NEXT:    [[TMP2:%.*]] = add i64 [[B]], -1
2700; CHECK-NEXT:    [[TMP3:%.*]] = icmp ult i64 [[TMP2]], [[A]]
2701; CHECK-NEXT:    ret i1 [[TMP3]]
2702;
2703  %1 = icmp ne i64 %b, 0
2704  %2 = icmp uge i64 %a, %b
2705  call void @use_i1(i1 %2)
2706  %3 = and i1 %1, %2
2707  ret i1 %3
2708}
2709
2710define i1 @and_icmp_ne_B_0_icmp_uge_A_B_extra_use3(i64 %a, i64 %b) {
2711; CHECK-LABEL: @and_icmp_ne_B_0_icmp_uge_A_B_extra_use3(
2712; CHECK-NEXT:    [[TMP1:%.*]] = icmp ne i64 [[B:%.*]], 0
2713; CHECK-NEXT:    call void @use_i1(i1 [[TMP1]])
2714; CHECK-NEXT:    [[TMP2:%.*]] = icmp uge i64 [[A:%.*]], [[B]]
2715; CHECK-NEXT:    call void @use_i1(i1 [[TMP2]])
2716; CHECK-NEXT:    [[TMP3:%.*]] = and i1 [[TMP1]], [[TMP2]]
2717; CHECK-NEXT:    ret i1 [[TMP3]]
2718;
2719  %1 = icmp ne i64 %b, 0
2720  call void @use_i1(i1 %1)
2721  %2 = icmp uge i64 %a, %b
2722  call void @use_i1(i1 %2)
2723  %3 = and i1 %1, %2
2724  ret i1 %3
2725}
2726
2727define i1 @and_icmp_ne_B_0_icmp_uge_A_B_wrong_pred1(i64 %a, i64 %b) {
2728; CHECK-LABEL: @and_icmp_ne_B_0_icmp_uge_A_B_wrong_pred1(
2729; CHECK-NEXT:    [[TMP1:%.*]] = icmp sgt i64 [[B:%.*]], 0
2730; CHECK-NEXT:    [[TMP2:%.*]] = icmp uge i64 [[A:%.*]], [[B]]
2731; CHECK-NEXT:    [[TMP3:%.*]] = and i1 [[TMP1]], [[TMP2]]
2732; CHECK-NEXT:    ret i1 [[TMP3]]
2733;
2734  %1 = icmp sgt i64 %b, 0
2735  %2 = icmp uge i64 %a, %b
2736  %3 = and i1 %1, %2
2737  ret i1 %3
2738}
2739
2740define i1 @and_icmp_ne_B_0_icmp_uge_A_B_wrong_pred2(i64 %a, i64 %b) {
2741; CHECK-LABEL: @and_icmp_ne_B_0_icmp_uge_A_B_wrong_pred2(
2742; CHECK-NEXT:    [[TMP1:%.*]] = icmp ne i64 [[B:%.*]], 0
2743; CHECK-NEXT:    [[TMP2:%.*]] = icmp ugt i64 [[A:%.*]], [[B]]
2744; CHECK-NEXT:    [[TMP3:%.*]] = and i1 [[TMP1]], [[TMP2]]
2745; CHECK-NEXT:    ret i1 [[TMP3]]
2746;
2747  %1 = icmp ne i64 %b, 0
2748  %2 = icmp ugt i64 %a, %b
2749  %3 = and i1 %1, %2
2750  ret i1 %3
2751}
2752
2753define i1 @and_icmp_ne_B_0_icmp_uge_A_B_wrong_op1(i64 %a, i64 %b) {
2754; CHECK-LABEL: @and_icmp_ne_B_0_icmp_uge_A_B_wrong_op1(
2755; CHECK-NEXT:    [[TMP1:%.*]] = icmp ne i64 [[B:%.*]], 1
2756; CHECK-NEXT:    [[TMP2:%.*]] = icmp uge i64 [[A:%.*]], [[B]]
2757; CHECK-NEXT:    [[TMP3:%.*]] = and i1 [[TMP1]], [[TMP2]]
2758; CHECK-NEXT:    ret i1 [[TMP3]]
2759;
2760  %1 = icmp ne i64 %b, 1
2761  %2 = icmp uge i64 %a, %b
2762  %3 = and i1 %1, %2
2763  ret i1 %3
2764}
2765
2766define i1 @and_icmp_ne_B_0_icmp_uge_A_B_wrong_op2(i64 %a, i64 %b, i64 %c) {
2767; CHECK-LABEL: @and_icmp_ne_B_0_icmp_uge_A_B_wrong_op2(
2768; CHECK-NEXT:    [[TMP1:%.*]] = icmp ne i64 [[B:%.*]], 0
2769; CHECK-NEXT:    [[TMP2:%.*]] = icmp uge i64 [[A:%.*]], [[C:%.*]]
2770; CHECK-NEXT:    [[TMP3:%.*]] = and i1 [[TMP1]], [[TMP2]]
2771; CHECK-NEXT:    ret i1 [[TMP3]]
2772;
2773  %1 = icmp ne i64 %b, 0
2774  %2 = icmp uge i64 %a, %c
2775  %3 = and i1 %1, %2
2776  ret i1 %3
2777}
2778
2779define i1 @and_icmp_ne_B_0_icmp_uge_A_B_logical(i64 %a, i64 %b) {
2780; CHECK-LABEL: @and_icmp_ne_B_0_icmp_uge_A_B_logical(
2781; CHECK-NEXT:    [[TMP1:%.*]] = freeze i64 [[A:%.*]]
2782; CHECK-NEXT:    [[TMP2:%.*]] = add i64 [[B:%.*]], -1
2783; CHECK-NEXT:    [[TMP3:%.*]] = icmp ult i64 [[TMP2]], [[TMP1]]
2784; CHECK-NEXT:    ret i1 [[TMP3]]
2785;
2786  %1 = icmp ne i64 %b, 0
2787  %2 = icmp uge i64 %a, %b
2788  %3 = select i1 %1, i1 %2, i1 false
2789  ret i1 %3
2790}
2791
2792define <2 x i1> @and_icmp_ne_B_0_icmp_uge_A_B_uniform(<2 x i64> %a, <2 x i64> %b) {
2793; CHECK-LABEL: @and_icmp_ne_B_0_icmp_uge_A_B_uniform(
2794; CHECK-NEXT:    [[TMP1:%.*]] = add <2 x i64> [[B:%.*]], splat (i64 -1)
2795; CHECK-NEXT:    [[TMP2:%.*]] = icmp ult <2 x i64> [[TMP1]], [[A:%.*]]
2796; CHECK-NEXT:    ret <2 x i1> [[TMP2]]
2797;
2798  %1 = icmp ne <2 x i64> %b, zeroinitializer
2799  %2 = icmp uge <2 x i64> %a, %b
2800  %3 = and <2 x i1> %1, %2
2801  ret <2 x i1> %3
2802}
2803
2804define <2 x i1> @and_icmp_ne_B_0_icmp_uge_A_B_poison(<2 x i64> %a, <2 x i64> %b) {
2805; CHECK-LABEL: @and_icmp_ne_B_0_icmp_uge_A_B_poison(
2806; CHECK-NEXT:    [[TMP1:%.*]] = add <2 x i64> [[B:%.*]], splat (i64 -1)
2807; CHECK-NEXT:    [[TMP2:%.*]] = icmp ult <2 x i64> [[TMP1]], [[A:%.*]]
2808; CHECK-NEXT:    ret <2 x i1> [[TMP2]]
2809;
2810  %1 = icmp ne <2 x i64> %b, <i64 0, i64 poison>
2811  %2 = icmp uge <2 x i64> %a, %b
2812  %3 = and <2 x i1> %1, %2
2813  ret <2 x i1> %3
2814}
2815
2816define i1 @icmp_add_ult_2(i32 %X) {
2817; CHECK-LABEL: @icmp_add_ult_2(
2818; CHECK-NEXT:    [[TMP1:%.*]] = and i32 [[X:%.*]], -2
2819; CHECK-NEXT:    [[CMP:%.*]] = icmp eq i32 [[TMP1]], 14
2820; CHECK-NEXT:    ret i1 [[CMP]]
2821;
2822  %add = add i32 %X, -14
2823  %cmp = icmp ult i32 %add, 2
2824  ret i1 %cmp
2825}
2826
2827define <2 x i1> @icmp_add_X_-14_ult_2_vec(<2 x i32> %X) {
2828; CHECK-LABEL: @icmp_add_X_-14_ult_2_vec(
2829; CHECK-NEXT:    [[TMP1:%.*]] = and <2 x i32> [[X:%.*]], splat (i32 -2)
2830; CHECK-NEXT:    [[CMP:%.*]] = icmp eq <2 x i32> [[TMP1]], splat (i32 14)
2831; CHECK-NEXT:    ret <2 x i1> [[CMP]]
2832;
2833  %add = add <2 x i32> %X, <i32 -14, i32 -14>
2834  %cmp = icmp ult <2 x i32> %add, <i32 2, i32 2>
2835  ret <2 x i1> %cmp
2836}
2837
2838define i1 @icmp_sub_3_X_ult_2(i32 %X) {
2839; CHECK-LABEL: @icmp_sub_3_X_ult_2(
2840; CHECK-NEXT:    [[TMP1:%.*]] = and i32 [[X:%.*]], -2
2841; CHECK-NEXT:    [[CMP:%.*]] = icmp eq i32 [[TMP1]], 2
2842; CHECK-NEXT:    ret i1 [[CMP]]
2843;
2844  %add = sub i32 3, %X
2845  %cmp = icmp ult i32 %add, 2
2846  ret i1 %cmp
2847}
2848
2849define <2 x i1> @icmp_sub_3_X_ult_2_vec(<2 x i32> %X) {
2850; CHECK-LABEL: @icmp_sub_3_X_ult_2_vec(
2851; CHECK-NEXT:    [[TMP1:%.*]] = and <2 x i32> [[X:%.*]], splat (i32 -2)
2852; CHECK-NEXT:    [[CMP:%.*]] = icmp eq <2 x i32> [[TMP1]], splat (i32 2)
2853; CHECK-NEXT:    ret <2 x i1> [[CMP]]
2854;
2855  %add = sub <2 x i32> <i32 3, i32 3>, %X
2856  %cmp = icmp ult <2 x i32> %add, <i32 2, i32 2>
2857  ret <2 x i1> %cmp
2858}
2859
2860define i1 @icmp_add_X_-14_uge_2(i32 %X) {
2861; CHECK-LABEL: @icmp_add_X_-14_uge_2(
2862; CHECK-NEXT:    [[TMP1:%.*]] = and i32 [[X:%.*]], -2
2863; CHECK-NEXT:    [[CMP:%.*]] = icmp ne i32 [[TMP1]], 14
2864; CHECK-NEXT:    ret i1 [[CMP]]
2865;
2866  %add = add i32 %X, -14
2867  %cmp = icmp uge i32 %add, 2
2868  ret i1 %cmp
2869}
2870
2871define <2 x i1> @icmp_add_X_-14_uge_2_vec(<2 x i32> %X) {
2872; CHECK-LABEL: @icmp_add_X_-14_uge_2_vec(
2873; CHECK-NEXT:    [[TMP1:%.*]] = and <2 x i32> [[X:%.*]], splat (i32 -2)
2874; CHECK-NEXT:    [[CMP:%.*]] = icmp ne <2 x i32> [[TMP1]], splat (i32 14)
2875; CHECK-NEXT:    ret <2 x i1> [[CMP]]
2876;
2877  %add = add <2 x i32> %X, <i32 -14, i32 -14>
2878  %cmp = icmp uge <2 x i32> %add, <i32 2, i32 2>
2879  ret <2 x i1> %cmp
2880}
2881
2882define i1 @icmp_sub_3_X_uge_2(i32 %X) {
2883; CHECK-LABEL: @icmp_sub_3_X_uge_2(
2884; CHECK-NEXT:    [[TMP1:%.*]] = and i32 [[X:%.*]], -2
2885; CHECK-NEXT:    [[CMP:%.*]] = icmp ne i32 [[TMP1]], 2
2886; CHECK-NEXT:    ret i1 [[CMP]]
2887;
2888  %add = sub i32 3, %X
2889  %cmp = icmp uge i32 %add, 2
2890  ret i1 %cmp
2891}
2892
2893define <2 x i1> @icmp_sub_3_X_uge_2_vec(<2 x i32> %X) {
2894; CHECK-LABEL: @icmp_sub_3_X_uge_2_vec(
2895; CHECK-NEXT:    [[TMP1:%.*]] = and <2 x i32> [[X:%.*]], splat (i32 -2)
2896; CHECK-NEXT:    [[CMP:%.*]] = icmp ne <2 x i32> [[TMP1]], splat (i32 2)
2897; CHECK-NEXT:    ret <2 x i1> [[CMP]]
2898;
2899  %add = sub <2 x i32> <i32 3, i32 3>, %X
2900  %cmp = icmp uge <2 x i32> %add, <i32 2, i32 2>
2901  ret <2 x i1> %cmp
2902}
2903
2904define i1 @icmp_and_X_-16_eq-16(i32 %X) {
2905; CHECK-LABEL: @icmp_and_X_-16_eq-16(
2906; CHECK-NEXT:    [[CMP:%.*]] = icmp ugt i32 [[X:%.*]], -17
2907; CHECK-NEXT:    ret i1 [[CMP]]
2908;
2909  %and = and i32 %X, -16
2910  %cmp = icmp eq i32 %and, -16
2911  ret i1 %cmp
2912}
2913
2914define <2 x i1> @icmp_and_X_-16_eq-16_vec(<2 x i32> %X) {
2915; CHECK-LABEL: @icmp_and_X_-16_eq-16_vec(
2916; CHECK-NEXT:    [[CMP:%.*]] = icmp ugt <2 x i32> [[X:%.*]], splat (i32 -17)
2917; CHECK-NEXT:    ret <2 x i1> [[CMP]]
2918;
2919  %and = and <2 x i32> %X, <i32 -16, i32 -16>
2920  %cmp = icmp eq <2 x i32> %and, <i32 -16, i32 -16>
2921  ret <2 x i1> %cmp
2922}
2923
2924define i1 @icmp_and_X_-16_ne-16(i32 %X) {
2925; CHECK-LABEL: @icmp_and_X_-16_ne-16(
2926; CHECK-NEXT:    [[CMP:%.*]] = icmp ult i32 [[X:%.*]], -16
2927; CHECK-NEXT:    ret i1 [[CMP]]
2928;
2929  %and = and i32 %X, -16
2930  %cmp = icmp ne i32 %and, -16
2931  ret i1 %cmp
2932}
2933
2934define <2 x i1> @icmp_and_X_-16_ne-16_vec(<2 x i32> %X) {
2935; CHECK-LABEL: @icmp_and_X_-16_ne-16_vec(
2936; CHECK-NEXT:    [[CMP:%.*]] = icmp ult <2 x i32> [[X:%.*]], splat (i32 -16)
2937; CHECK-NEXT:    ret <2 x i1> [[CMP]]
2938;
2939  %and = and <2 x i32> %X, <i32 -16, i32 -16>
2940  %cmp = icmp ne <2 x i32> %and, <i32 -16, i32 -16>
2941  ret <2 x i1> %cmp
2942}
2943
2944; PR32524: https://bugs.llvm.org/show_bug.cgi?id=32524
2945; X | C == C --> X <=u C (when C+1 is PowerOf2).
2946
2947define i1 @or1_eq1(i32 %x) {
2948; CHECK-LABEL: @or1_eq1(
2949; CHECK-NEXT:    [[T1:%.*]] = icmp ult i32 [[X:%.*]], 2
2950; CHECK-NEXT:    ret i1 [[T1]]
2951;
2952  %t0 = or i32 %x, 1
2953  %t1 = icmp eq i32 %t0, 1
2954  ret i1 %t1
2955}
2956
2957; X | C == C --> X <=u C (when C+1 is PowerOf2).
2958
2959define <2 x i1> @or3_eq3_vec(<2 x i8> %x) {
2960; CHECK-LABEL: @or3_eq3_vec(
2961; CHECK-NEXT:    [[T1:%.*]] = icmp ult <2 x i8> [[X:%.*]], splat (i8 4)
2962; CHECK-NEXT:    ret <2 x i1> [[T1]]
2963;
2964  %t0 = or <2 x i8> %x, <i8 3, i8 3>
2965  %t1 = icmp eq <2 x i8> %t0, <i8 3, i8 3>
2966  ret <2 x i1> %t1
2967}
2968
2969; X | C != C --> X >u C (when C+1 is PowerOf2).
2970
2971define i1 @or7_ne7(i32 %x) {
2972; CHECK-LABEL: @or7_ne7(
2973; CHECK-NEXT:    [[T1:%.*]] = icmp ugt i32 [[X:%.*]], 7
2974; CHECK-NEXT:    ret i1 [[T1]]
2975;
2976  %t0 = or i32 %x, 7
2977  %t1 = icmp ne i32 %t0, 7
2978  ret i1 %t1
2979}
2980
2981; X | C != C --> X >u C (when C+1 is PowerOf2).
2982
2983define <2 x i1> @or63_ne63_vec(<2 x i8> %x) {
2984; CHECK-LABEL: @or63_ne63_vec(
2985; CHECK-NEXT:    [[T1:%.*]] = icmp ugt <2 x i8> [[X:%.*]], splat (i8 63)
2986; CHECK-NEXT:    ret <2 x i1> [[T1]]
2987;
2988  %t0 = or <2 x i8> %x, <i8 63, i8 63>
2989  %t1 = icmp ne <2 x i8> %t0, <i8 63, i8 63>
2990  ret <2 x i1> %t1
2991}
2992
2993; PR40611: https://bugs.llvm.org/show_bug.cgi?id=40611
2994; X | C == C --> (X & ~C) == 0
2995
2996define i1 @orC_eqC(i32 %x) {
2997; CHECK-LABEL: @orC_eqC(
2998; CHECK-NEXT:    [[TMP1:%.*]] = and i32 [[X:%.*]], -43
2999; CHECK-NEXT:    [[T1:%.*]] = icmp eq i32 [[TMP1]], 0
3000; CHECK-NEXT:    ret i1 [[T1]]
3001;
3002  %t0 = or i32 %x, 42
3003  %t1 = icmp eq i32 %t0, 42
3004  ret i1 %t1
3005}
3006
3007; X | C == C --> (X & ~C) == 0
3008
3009define <2 x i1> @orC_eqC_vec(<2 x i8> %x) {
3010; CHECK-LABEL: @orC_eqC_vec(
3011; CHECK-NEXT:    [[TMP1:%.*]] = and <2 x i8> [[X:%.*]], splat (i8 -44)
3012; CHECK-NEXT:    [[T1:%.*]] = icmp eq <2 x i8> [[TMP1]], zeroinitializer
3013; CHECK-NEXT:    ret <2 x i1> [[T1]]
3014;
3015  %t0 = or <2 x i8> %x, <i8 43, i8 43>
3016  %t1 = icmp eq <2 x i8> %t0, <i8 43, i8 43>
3017  ret <2 x i1> %t1
3018}
3019
3020; X | C != C --> (X & ~C) != 0
3021
3022define i1 @orC_neC(i32 %x) {
3023; CHECK-LABEL: @orC_neC(
3024; CHECK-NEXT:    [[TMP1:%.*]] = and i32 [[X:%.*]], 41
3025; CHECK-NEXT:    [[T1:%.*]] = icmp ne i32 [[TMP1]], 0
3026; CHECK-NEXT:    ret i1 [[T1]]
3027;
3028  %t0 = or i32 %x, -42
3029  %t1 = icmp ne i32 %t0, -42
3030  ret i1 %t1
3031}
3032
3033; X | C != C --> (X & ~C) != 0
3034
3035define <2 x i1> @orC_neC_vec(<2 x i8> %x) {
3036; CHECK-LABEL: @orC_neC_vec(
3037; CHECK-NEXT:    [[TMP1:%.*]] = and <2 x i8> [[X:%.*]], splat (i8 42)
3038; CHECK-NEXT:    [[T1:%.*]] = icmp ne <2 x i8> [[TMP1]], zeroinitializer
3039; CHECK-NEXT:    ret <2 x i1> [[T1]]
3040;
3041  %t0 = or <2 x i8> %x, <i8 -43, i8 -43>
3042  %t1 = icmp ne <2 x i8> %t0, <i8 -43, i8 -43>
3043  ret <2 x i1> %t1
3044}
3045
3046define i1 @shrink_constant(i32 %X) {
3047; CHECK-LABEL: @shrink_constant(
3048; CHECK-NEXT:    [[XOR:%.*]] = xor i32 [[X:%.*]], -12
3049; CHECK-NEXT:    [[CMP:%.*]] = icmp ult i32 [[XOR]], 4
3050; CHECK-NEXT:    ret i1 [[CMP]]
3051;
3052  %xor = xor i32 %X, -9
3053  %cmp = icmp ult i32 %xor, 4
3054  ret i1 %cmp
3055}
3056
3057define <2 x i1> @shrink_constant_vec(<2 x i32> %X) {
3058; CHECK-LABEL: @shrink_constant_vec(
3059; CHECK-NEXT:    [[XOR:%.*]] = xor <2 x i32> [[X:%.*]], splat (i32 -12)
3060; CHECK-NEXT:    [[CMP:%.*]] = icmp ult <2 x i32> [[XOR]], splat (i32 4)
3061; CHECK-NEXT:    ret <2 x i1> [[CMP]]
3062;
3063  %xor = xor <2 x i32> %X, <i32 -9, i32 -9>
3064  %cmp = icmp ult <2 x i32> %xor, <i32 4, i32 4>
3065  ret <2 x i1> %cmp
3066}
3067
3068; This test requires 3 different transforms to get to the result.
3069define i1 @icmp_sub_-1_X_ult_4(i32 %X) {
3070; CHECK-LABEL: @icmp_sub_-1_X_ult_4(
3071; CHECK-NEXT:    [[CMP:%.*]] = icmp ugt i32 [[X:%.*]], -5
3072; CHECK-NEXT:    ret i1 [[CMP]]
3073;
3074  %sub = sub i32 -1, %X
3075  %cmp = icmp ult i32 %sub, 4
3076  ret i1 %cmp
3077}
3078
3079define <2 x i1> @icmp_xor_neg4_X_ult_4_vec(<2 x i32> %X) {
3080; CHECK-LABEL: @icmp_xor_neg4_X_ult_4_vec(
3081; CHECK-NEXT:    [[CMP:%.*]] = icmp ugt <2 x i32> [[X:%.*]], splat (i32 -5)
3082; CHECK-NEXT:    ret <2 x i1> [[CMP]]
3083;
3084  %xor = xor <2 x i32> %X, <i32 -4, i32 -4>
3085  %cmp = icmp ult <2 x i32> %xor, <i32 4, i32 4>
3086  ret <2 x i1> %cmp
3087}
3088
3089define i1 @icmp_sub_-1_X_uge_4(i32 %X) {
3090; CHECK-LABEL: @icmp_sub_-1_X_uge_4(
3091; CHECK-NEXT:    [[CMP:%.*]] = icmp ult i32 [[X:%.*]], -4
3092; CHECK-NEXT:    ret i1 [[CMP]]
3093;
3094  %sub = sub i32 -1, %X
3095  %cmp = icmp uge i32 %sub, 4
3096  ret i1 %cmp
3097}
3098
3099define <2 x i1> @icmp_xor_neg4_X_uge_4_vec(<2 x i32> %X) {
3100; CHECK-LABEL: @icmp_xor_neg4_X_uge_4_vec(
3101; CHECK-NEXT:    [[CMP:%.*]] = icmp ult <2 x i32> [[X:%.*]], splat (i32 -4)
3102; CHECK-NEXT:    ret <2 x i1> [[CMP]]
3103;
3104  %xor = xor <2 x i32> %X, <i32 -4, i32 -4>
3105  %cmp = icmp uge <2 x i32> %xor, <i32 4, i32 4>
3106  ret <2 x i1> %cmp
3107}
3108
3109define <2 x i1> @xor_ult(<2 x i8> %x) {
3110; CHECK-LABEL: @xor_ult(
3111; CHECK-NEXT:    [[R:%.*]] = icmp ugt <2 x i8> [[X:%.*]], splat (i8 3)
3112; CHECK-NEXT:    ret <2 x i1> [[R]]
3113;
3114  %xor = xor <2 x i8> %x, <i8 -4, i8 -4>
3115  %r = icmp ult <2 x i8> %xor, <i8 -4, i8 -4>
3116  ret <2 x i1> %r
3117}
3118
3119define i1 @xor_ult_extra_use(i8 %x, ptr %p) {
3120; CHECK-LABEL: @xor_ult_extra_use(
3121; CHECK-NEXT:    [[XOR:%.*]] = xor i8 [[X:%.*]], -32
3122; CHECK-NEXT:    store i8 [[XOR]], ptr [[P:%.*]], align 1
3123; CHECK-NEXT:    [[R:%.*]] = icmp ugt i8 [[X]], 31
3124; CHECK-NEXT:    ret i1 [[R]]
3125;
3126  %xor = xor i8 %x, -32
3127  store i8 %xor, ptr %p
3128  %r = icmp ult i8 %xor, -32
3129  ret i1 %r
3130}
3131
3132define <2 x i1> @xor_ugt(<2 x i8> %x) {
3133; CHECK-LABEL: @xor_ugt(
3134; CHECK-NEXT:    [[R:%.*]] = icmp ugt <2 x i8> [[X:%.*]], splat (i8 7)
3135; CHECK-NEXT:    ret <2 x i1> [[R]]
3136;
3137  %xor = xor <2 x i8> %x, <i8 7, i8 7>
3138  %r = icmp ugt <2 x i8> %xor, <i8 7, i8 7>
3139  ret <2 x i1> %r
3140}
3141
3142define i1 @xor_ugt_extra_use(i8 %x, ptr %p) {
3143; CHECK-LABEL: @xor_ugt_extra_use(
3144; CHECK-NEXT:    [[XOR:%.*]] = xor i8 [[X:%.*]], 63
3145; CHECK-NEXT:    store i8 [[XOR]], ptr [[P:%.*]], align 1
3146; CHECK-NEXT:    [[R:%.*]] = icmp ugt i8 [[X]], 63
3147; CHECK-NEXT:    ret i1 [[R]]
3148;
3149  %xor = xor i8 %x, 63
3150  store i8 %xor, ptr %p
3151  %r = icmp ugt i8 %xor, 63
3152  ret i1 %r
3153}
3154
3155define i1 @icmp_lshr_lshr_eq(i32 %a, i32 %b) {
3156; CHECK-LABEL: @icmp_lshr_lshr_eq(
3157; CHECK-NEXT:    [[Z_UNSHIFTED:%.*]] = xor i32 [[A:%.*]], [[B:%.*]]
3158; CHECK-NEXT:    [[Z:%.*]] = icmp ult i32 [[Z_UNSHIFTED]], 1073741824
3159; CHECK-NEXT:    ret i1 [[Z]]
3160;
3161  %x = lshr i32 %a, 30
3162  %y = lshr i32 %b, 30
3163  %z = icmp eq i32 %x, %y
3164  ret i1 %z
3165}
3166
3167define i1 @icmp_ashr_ashr_ne(i32 %a, i32 %b) {
3168; CHECK-LABEL: @icmp_ashr_ashr_ne(
3169; CHECK-NEXT:    [[Z_UNSHIFTED:%.*]] = xor i32 [[A:%.*]], [[B:%.*]]
3170; CHECK-NEXT:    [[Z:%.*]] = icmp ugt i32 [[Z_UNSHIFTED]], 255
3171; CHECK-NEXT:    ret i1 [[Z]]
3172;
3173  %x = ashr i32 %a, 8
3174  %y = ashr i32 %b, 8
3175  %z = icmp ne i32 %x, %y
3176  ret i1 %z
3177}
3178
3179define i1 @icmp_neg_cst_slt(i32 %a) {
3180; CHECK-LABEL: @icmp_neg_cst_slt(
3181; CHECK-NEXT:    [[TMP1:%.*]] = icmp sgt i32 [[A:%.*]], 10
3182; CHECK-NEXT:    ret i1 [[TMP1]]
3183;
3184  %1 = sub nsw i32 0, %a
3185  %2 = icmp slt i32 %1, -10
3186  ret i1 %2
3187}
3188
3189define i1 @icmp_and_or_lshr(i32 %x, i32 %y) {
3190; CHECK-LABEL: @icmp_and_or_lshr(
3191; CHECK-NEXT:    [[SHF1:%.*]] = shl nuw i32 1, [[Y:%.*]]
3192; CHECK-NEXT:    [[OR2:%.*]] = or i32 [[SHF1]], 1
3193; CHECK-NEXT:    [[AND3:%.*]] = and i32 [[X:%.*]], [[OR2]]
3194; CHECK-NEXT:    [[RET:%.*]] = icmp ne i32 [[AND3]], 0
3195; CHECK-NEXT:    ret i1 [[RET]]
3196;
3197  %shf = lshr i32 %x, %y
3198  %or = or i32 %shf, %x
3199  %and = and i32 %or, 1
3200  %ret = icmp ne i32 %and, 0
3201  ret i1 %ret
3202}
3203
3204define i1 @icmp_and_or_lshr_samesign(i32 %x, i32 %y) {
3205; CHECK-LABEL: @icmp_and_or_lshr_samesign(
3206; CHECK-NEXT:    [[SHF1:%.*]] = shl nuw i32 1, [[Y:%.*]]
3207; CHECK-NEXT:    [[OR2:%.*]] = or i32 [[SHF1]], 1
3208; CHECK-NEXT:    [[AND3:%.*]] = and i32 [[X:%.*]], [[OR2]]
3209; CHECK-NEXT:    [[RET:%.*]] = icmp ne i32 [[AND3]], 0
3210; CHECK-NEXT:    ret i1 [[RET]]
3211;
3212  %shf = lshr i32 %x, %y
3213  %or = or i32 %shf, %x
3214  %and = and i32 %or, 1
3215  %ret = icmp samesign ne i32 %and, 0
3216  ret i1 %ret
3217}
3218
3219define <2 x i1> @icmp_and_or_lshr_vec(<2 x i32> %x, <2 x i32> %y) {
3220; CHECK-LABEL: @icmp_and_or_lshr_vec(
3221; CHECK-NEXT:    [[SHF:%.*]] = lshr <2 x i32> [[X:%.*]], [[Y:%.*]]
3222; CHECK-NEXT:    [[OR:%.*]] = or <2 x i32> [[SHF]], [[X]]
3223; CHECK-NEXT:    [[RET:%.*]] = trunc <2 x i32> [[OR]] to <2 x i1>
3224; CHECK-NEXT:    ret <2 x i1> [[RET]]
3225;
3226  %shf = lshr <2 x i32> %x, %y
3227  %or = or <2 x i32> %shf, %x
3228  %and = and <2 x i32> %or, <i32 1, i32 1>
3229  %ret = icmp ne <2 x i32> %and, zeroinitializer
3230  ret <2 x i1> %ret
3231}
3232
3233define <2 x i1> @icmp_and_or_lshr_vec_commute(<2 x i32> %xp, <2 x i32> %y) {
3234; CHECK-LABEL: @icmp_and_or_lshr_vec_commute(
3235; CHECK-NEXT:    [[X:%.*]] = srem <2 x i32> [[XP:%.*]], splat (i32 42)
3236; CHECK-NEXT:    [[SHF:%.*]] = lshr <2 x i32> [[X]], [[Y:%.*]]
3237; CHECK-NEXT:    [[OR:%.*]] = or <2 x i32> [[X]], [[SHF]]
3238; CHECK-NEXT:    [[RET:%.*]] = trunc <2 x i32> [[OR]] to <2 x i1>
3239; CHECK-NEXT:    ret <2 x i1> [[RET]]
3240;
3241  %x = srem <2 x i32> %xp, <i32 42, i32 -42> ; prevent complexity-based canonicalization
3242  %shf = lshr <2 x i32> %x, %y
3243  %or = or <2 x i32> %x, %shf
3244  %and = and <2 x i32> %or, <i32 1, i32 1>
3245  %ret = icmp ne <2 x i32> %and, zeroinitializer
3246  ret <2 x i1> %ret
3247}
3248
3249define i1 @icmp_and_or_lshr_cst(i32 %x) {
3250; CHECK-LABEL: @icmp_and_or_lshr_cst(
3251; CHECK-NEXT:    [[AND1:%.*]] = and i32 [[X:%.*]], 3
3252; CHECK-NEXT:    [[RET:%.*]] = icmp ne i32 [[AND1]], 0
3253; CHECK-NEXT:    ret i1 [[RET]]
3254;
3255  %shf = lshr i32 %x, 1
3256  %or = or i32 %shf, %x
3257  %and = and i32 %or, 1
3258  %ret = icmp ne i32 %and, 0
3259  ret i1 %ret
3260}
3261
3262define <2 x i1> @icmp_and_or_lshr_cst_vec(<2 x i32> %x) {
3263; CHECK-LABEL: @icmp_and_or_lshr_cst_vec(
3264; CHECK-NEXT:    [[TMP1:%.*]] = and <2 x i32> [[X:%.*]], splat (i32 3)
3265; CHECK-NEXT:    [[RET:%.*]] = icmp ne <2 x i32> [[TMP1]], zeroinitializer
3266; CHECK-NEXT:    ret <2 x i1> [[RET]]
3267;
3268  %shf = lshr <2 x i32> %x, <i32 1, i32 1>
3269  %or = or <2 x i32> %shf, %x
3270  %and = and <2 x i32> %or, <i32 1, i32 1>
3271  %ret = icmp ne <2 x i32> %and, zeroinitializer
3272  ret <2 x i1> %ret
3273}
3274
3275define <2 x i1> @icmp_and_or_lshr_cst_vec_nonuniform(<2 x i32> %x) {
3276; CHECK-LABEL: @icmp_and_or_lshr_cst_vec_nonuniform(
3277; CHECK-NEXT:    [[TMP1:%.*]] = and <2 x i32> [[X:%.*]], <i32 3, i32 5>
3278; CHECK-NEXT:    [[RET:%.*]] = icmp ne <2 x i32> [[TMP1]], zeroinitializer
3279; CHECK-NEXT:    ret <2 x i1> [[RET]]
3280;
3281  %shf = lshr <2 x i32> %x, <i32 1, i32 2>
3282  %or = or <2 x i32> %shf, %x
3283  %and = and <2 x i32> %or, <i32 1, i32 1>
3284  %ret = icmp ne <2 x i32> %and, zeroinitializer
3285  ret <2 x i1> %ret
3286}
3287
3288define <2 x i1> @icmp_and_or_lshr_cst_vec_poison(<2 x i32> %x) {
3289; CHECK-LABEL: @icmp_and_or_lshr_cst_vec_poison(
3290; CHECK-NEXT:    [[TMP1:%.*]] = and <2 x i32> [[X:%.*]], <i32 3, i32 poison>
3291; CHECK-NEXT:    [[RET:%.*]] = icmp ne <2 x i32> [[TMP1]], zeroinitializer
3292; CHECK-NEXT:    ret <2 x i1> [[RET]]
3293;
3294  %shf = lshr <2 x i32> %x, <i32 1, i32 poison>
3295  %or = or <2 x i32> %shf, %x
3296  %and = and <2 x i32> %or, <i32 1, i32 1>
3297  %ret = icmp ne <2 x i32> %and, zeroinitializer
3298  ret <2 x i1> %ret
3299}
3300
3301define <2 x i1> @icmp_and_or_lshr_cst_vec_commute(<2 x i32> %xp) {
3302; CHECK-LABEL: @icmp_and_or_lshr_cst_vec_commute(
3303; CHECK-NEXT:    [[X:%.*]] = srem <2 x i32> [[XP:%.*]], splat (i32 42)
3304; CHECK-NEXT:    [[TMP1:%.*]] = and <2 x i32> [[X]], splat (i32 3)
3305; CHECK-NEXT:    [[RET:%.*]] = icmp ne <2 x i32> [[TMP1]], zeroinitializer
3306; CHECK-NEXT:    ret <2 x i1> [[RET]]
3307;
3308  %x = srem <2 x i32> %xp, <i32 42, i32 -42> ; prevent complexity-based canonicalization
3309  %shf = lshr <2 x i32> %x, <i32 1, i32 1>
3310  %or = or <2 x i32> %x, %shf
3311  %and = and <2 x i32> %or, <i32 1, i32 1>
3312  %ret = icmp ne <2 x i32> %and, zeroinitializer
3313  ret <2 x i1> %ret
3314}
3315
3316define <2 x i1> @icmp_and_or_lshr_cst_vec_nonuniform_commute(<2 x i32> %xp) {
3317; CHECK-LABEL: @icmp_and_or_lshr_cst_vec_nonuniform_commute(
3318; CHECK-NEXT:    [[X:%.*]] = srem <2 x i32> [[XP:%.*]], splat (i32 42)
3319; CHECK-NEXT:    [[TMP1:%.*]] = and <2 x i32> [[X]], <i32 3, i32 5>
3320; CHECK-NEXT:    [[RET:%.*]] = icmp ne <2 x i32> [[TMP1]], zeroinitializer
3321; CHECK-NEXT:    ret <2 x i1> [[RET]]
3322;
3323  %x = srem <2 x i32> %xp, <i32 42, i32 -42> ; prevent complexity-based canonicalization
3324  %shf = lshr <2 x i32> %x, <i32 1, i32 2>
3325  %or = or <2 x i32> %x, %shf
3326  %and = and <2 x i32> %or, <i32 1, i32 1>
3327  %ret = icmp ne <2 x i32> %and, zeroinitializer
3328  ret <2 x i1> %ret
3329}
3330
3331define <2 x i1> @icmp_and_or_lshr_cst_vec_poison_commute(<2 x i32> %xp) {
3332; CHECK-LABEL: @icmp_and_or_lshr_cst_vec_poison_commute(
3333; CHECK-NEXT:    [[X:%.*]] = srem <2 x i32> [[XP:%.*]], splat (i32 42)
3334; CHECK-NEXT:    [[TMP1:%.*]] = and <2 x i32> [[X]], <i32 3, i32 poison>
3335; CHECK-NEXT:    [[RET:%.*]] = icmp ne <2 x i32> [[TMP1]], zeroinitializer
3336; CHECK-NEXT:    ret <2 x i1> [[RET]]
3337;
3338  %x = srem <2 x i32> %xp, <i32 42, i32 -42> ; prevent complexity-based canonicalization
3339  %shf = lshr <2 x i32> %x, <i32 1, i32 poison>
3340  %or = or <2 x i32> %x, %shf
3341  %and = and <2 x i32> %or, <i32 1, i32 1>
3342  %ret = icmp ne <2 x i32> %and, zeroinitializer
3343  ret <2 x i1> %ret
3344}
3345
3346define i1 @shl_ap1_zero_ap2_non_zero_2(i32 %a) {
3347; CHECK-LABEL: @shl_ap1_zero_ap2_non_zero_2(
3348; CHECK-NEXT:    [[CMP:%.*]] = icmp ugt i32 [[A:%.*]], 29
3349; CHECK-NEXT:    ret i1 [[CMP]]
3350;
3351  %shl = shl i32 4, %a
3352  %cmp = icmp eq i32 %shl, 0
3353  ret i1 %cmp
3354}
3355
3356define <2 x i1> @shl_ap1_zero_ap2_non_zero_2_vec(<2 x i32> %a) {
3357; CHECK-LABEL: @shl_ap1_zero_ap2_non_zero_2_vec(
3358; CHECK-NEXT:    [[CMP:%.*]] = icmp ugt <2 x i32> [[A:%.*]], splat (i32 29)
3359; CHECK-NEXT:    ret <2 x i1> [[CMP]]
3360;
3361  %shl = shl <2 x i32> <i32 4, i32 4>, %a
3362  %cmp = icmp eq <2 x i32> %shl, zeroinitializer
3363  ret <2 x i1> %cmp
3364}
3365
3366define <2 x i1> @shl_ap1_zero_ap2_non_zero_2_vec_nonuniform(<2 x i32> %a) {
3367; CHECK-LABEL: @shl_ap1_zero_ap2_non_zero_2_vec_nonuniform(
3368; CHECK-NEXT:    [[SHL:%.*]] = shl <2 x i32> <i32 4, i32 5>, [[A:%.*]]
3369; CHECK-NEXT:    [[CMP:%.*]] = icmp eq <2 x i32> [[SHL]], zeroinitializer
3370; CHECK-NEXT:    ret <2 x i1> [[CMP]]
3371;
3372  %shl = shl <2 x i32> <i32 4, i32 5>, %a
3373  %cmp = icmp eq <2 x i32> %shl, zeroinitializer
3374  ret <2 x i1> %cmp
3375}
3376
3377define i1 @shl_ap1_zero_ap2_non_zero_4(i32 %a) {
3378; CHECK-LABEL: @shl_ap1_zero_ap2_non_zero_4(
3379; CHECK-NEXT:    [[CMP:%.*]] = icmp ugt i32 [[A:%.*]], 30
3380; CHECK-NEXT:    ret i1 [[CMP]]
3381;
3382  %shl = shl i32 -2, %a
3383  %cmp = icmp eq i32 %shl, 0
3384  ret i1 %cmp
3385}
3386
3387define i1 @shl_ap1_non_zero_ap2_non_zero_both_positive(i32 %a) {
3388; CHECK-LABEL: @shl_ap1_non_zero_ap2_non_zero_both_positive(
3389; CHECK-NEXT:    [[CMP:%.*]] = icmp eq i32 [[A:%.*]], 0
3390; CHECK-NEXT:    ret i1 [[CMP]]
3391;
3392  %shl = shl i32 50, %a
3393  %cmp = icmp eq i32 %shl, 50
3394  ret i1 %cmp
3395}
3396
3397define i1 @shl_ap1_non_zero_ap2_non_zero_both_negative(i32 %a) {
3398; CHECK-LABEL: @shl_ap1_non_zero_ap2_non_zero_both_negative(
3399; CHECK-NEXT:    [[CMP:%.*]] = icmp eq i32 [[A:%.*]], 0
3400; CHECK-NEXT:    ret i1 [[CMP]]
3401;
3402  %shl = shl i32 -50, %a
3403  %cmp = icmp eq i32 %shl, -50
3404  ret i1 %cmp
3405}
3406
3407define i1 @shl_ap1_non_zero_ap2_non_zero_ap1_1(i32 %a) {
3408; CHECK-LABEL: @shl_ap1_non_zero_ap2_non_zero_ap1_1(
3409; CHECK-NEXT:    ret i1 false
3410;
3411  %shl = shl i32 50, %a
3412  %cmp = icmp eq i32 %shl, 25
3413  ret i1 %cmp
3414}
3415
3416define i1 @shl_ap1_non_zero_ap2_non_zero_ap1_2(i32 %a) {
3417; CHECK-LABEL: @shl_ap1_non_zero_ap2_non_zero_ap1_2(
3418; CHECK-NEXT:    [[CMP:%.*]] = icmp eq i32 [[A:%.*]], 1
3419; CHECK-NEXT:    ret i1 [[CMP]]
3420;
3421  %shl = shl i32 25, %a
3422  %cmp = icmp eq i32 %shl, 50
3423  ret i1 %cmp
3424}
3425
3426define i1 @shl_ap1_non_zero_ap2_non_zero_ap1_3(i32 %a) {
3427; CHECK-LABEL: @shl_ap1_non_zero_ap2_non_zero_ap1_3(
3428; CHECK-NEXT:    ret i1 false
3429;
3430  %shl = shl i32 26, %a
3431  %cmp = icmp eq i32 %shl, 50
3432  ret i1 %cmp
3433}
3434
3435define i1 @icmp_sgt_zero_add_nsw(i32 %a) {
3436; CHECK-LABEL: @icmp_sgt_zero_add_nsw(
3437; CHECK-NEXT:    [[CMP:%.*]] = icmp sgt i32 [[A:%.*]], -1
3438; CHECK-NEXT:    ret i1 [[CMP]]
3439;
3440  %add = add nsw i32 %a, 1
3441  %cmp = icmp sgt i32 %add, 0
3442  ret i1 %cmp
3443}
3444
3445define i1 @icmp_sge_zero_add_nsw(i32 %a) {
3446; CHECK-LABEL: @icmp_sge_zero_add_nsw(
3447; CHECK-NEXT:    [[CMP:%.*]] = icmp sgt i32 [[A:%.*]], -2
3448; CHECK-NEXT:    ret i1 [[CMP]]
3449;
3450  %add = add nsw i32 %a, 1
3451  %cmp = icmp sge i32 %add, 0
3452  ret i1 %cmp
3453}
3454
3455define i1 @icmp_sle_zero_add_nsw(i32 %a) {
3456; CHECK-LABEL: @icmp_sle_zero_add_nsw(
3457; CHECK-NEXT:    [[CMP:%.*]] = icmp slt i32 [[A:%.*]], 0
3458; CHECK-NEXT:    ret i1 [[CMP]]
3459;
3460  %add = add nsw i32 %a, 1
3461  %cmp = icmp sle i32 %add, 0
3462  ret i1 %cmp
3463}
3464
3465define zeroext i1 @icmp_cmpxchg_strong(ptr %sc, i32 %old_val, i32 %new_val) {
3466; CHECK-LABEL: @icmp_cmpxchg_strong(
3467; CHECK-NEXT:    [[XCHG:%.*]] = cmpxchg ptr [[SC:%.*]], i32 [[OLD_VAL:%.*]], i32 [[NEW_VAL:%.*]] seq_cst seq_cst, align 4
3468; CHECK-NEXT:    [[ICMP:%.*]] = extractvalue { i32, i1 } [[XCHG]], 1
3469; CHECK-NEXT:    ret i1 [[ICMP]]
3470;
3471  %xchg = cmpxchg ptr %sc, i32 %old_val, i32 %new_val seq_cst seq_cst
3472  %xtrc = extractvalue { i32, i1 } %xchg, 0
3473  %icmp = icmp eq i32 %xtrc, %old_val
3474  ret i1 %icmp
3475}
3476
3477define i1 @f1(i64 %a, i64 %b) {
3478; CHECK-LABEL: @f1(
3479; CHECK-NEXT:    [[V:%.*]] = icmp sge i64 [[A:%.*]], [[B:%.*]]
3480; CHECK-NEXT:    ret i1 [[V]]
3481;
3482  %t = sub nsw i64 %a, %b
3483  %v = icmp sge i64 %t, 0
3484  ret i1 %v
3485}
3486
3487define <2 x i1> @f1_vec(<2 x i64> %a, <2 x i64> %b) {
3488; CHECK-LABEL: @f1_vec(
3489; CHECK-NEXT:    [[V:%.*]] = icmp sge <2 x i64> [[A:%.*]], [[B:%.*]]
3490; CHECK-NEXT:    ret <2 x i1> [[V]]
3491;
3492  %t = sub nsw <2 x i64> %a, %b
3493  %v = icmp sgt <2 x i64> %t, <i64 -1, i64 -1>
3494  ret <2 x i1> %v
3495}
3496
3497define i1 @f2(i64 %a, i64 %b) {
3498; CHECK-LABEL: @f2(
3499; CHECK-NEXT:    [[V:%.*]] = icmp sgt i64 [[A:%.*]], [[B:%.*]]
3500; CHECK-NEXT:    ret i1 [[V]]
3501;
3502  %t = sub nsw i64 %a, %b
3503  %v = icmp sgt i64 %t, 0
3504  ret i1 %v
3505}
3506
3507define <2 x i1> @f2_vec(<2 x i64> %a, <2 x i64> %b) {
3508; CHECK-LABEL: @f2_vec(
3509; CHECK-NEXT:    [[V:%.*]] = icmp sgt <2 x i64> [[A:%.*]], [[B:%.*]]
3510; CHECK-NEXT:    ret <2 x i1> [[V]]
3511;
3512  %t = sub nsw <2 x i64> %a, %b
3513  %v = icmp sgt <2 x i64> %t, zeroinitializer
3514  ret <2 x i1> %v
3515}
3516
3517define i1 @f3(i64 %a, i64 %b) {
3518; CHECK-LABEL: @f3(
3519; CHECK-NEXT:    [[V:%.*]] = icmp slt i64 [[A:%.*]], [[B:%.*]]
3520; CHECK-NEXT:    ret i1 [[V]]
3521;
3522  %t = sub nsw i64 %a, %b
3523  %v = icmp slt i64 %t, 0
3524  ret i1 %v
3525}
3526
3527define <2 x i1> @f3_vec(<2 x i64> %a, <2 x i64> %b) {
3528; CHECK-LABEL: @f3_vec(
3529; CHECK-NEXT:    [[V:%.*]] = icmp slt <2 x i64> [[A:%.*]], [[B:%.*]]
3530; CHECK-NEXT:    ret <2 x i1> [[V]]
3531;
3532  %t = sub nsw <2 x i64> %a, %b
3533  %v = icmp slt <2 x i64> %t, zeroinitializer
3534  ret <2 x i1> %v
3535}
3536
3537define i1 @f4(i64 %a, i64 %b) {
3538; CHECK-LABEL: @f4(
3539; CHECK-NEXT:    [[V:%.*]] = icmp sle i64 [[A:%.*]], [[B:%.*]]
3540; CHECK-NEXT:    ret i1 [[V]]
3541;
3542  %t = sub nsw i64 %a, %b
3543  %v = icmp sle i64 %t, 0
3544  ret i1 %v
3545}
3546
3547define <2 x i1> @f4_vec(<2 x i64> %a, <2 x i64> %b) {
3548; CHECK-LABEL: @f4_vec(
3549; CHECK-NEXT:    [[V:%.*]] = icmp sle <2 x i64> [[A:%.*]], [[B:%.*]]
3550; CHECK-NEXT:    ret <2 x i1> [[V]]
3551;
3552  %t = sub nsw <2 x i64> %a, %b
3553  %v = icmp slt <2 x i64> %t, <i64 1, i64 1>
3554  ret <2 x i1> %v
3555}
3556
3557define i32 @f5(i8 %a, i8 %b) {
3558; CHECK-LABEL: @f5(
3559; CHECK-NEXT:    [[CONV:%.*]] = zext i8 [[A:%.*]] to i32
3560; CHECK-NEXT:    [[CONV3:%.*]] = zext i8 [[B:%.*]] to i32
3561; CHECK-NEXT:    [[SUB:%.*]] = sub nsw i32 [[CONV]], [[CONV3]]
3562; CHECK-NEXT:    [[SUB7_SUB:%.*]] = call i32 @llvm.abs.i32(i32 [[SUB]], i1 true)
3563; CHECK-NEXT:    ret i32 [[SUB7_SUB]]
3564;
3565  %conv = zext i8 %a to i32
3566  %conv3 = zext i8 %b to i32
3567  %sub = sub nsw i32 %conv, %conv3
3568  %cmp4 = icmp slt i32 %sub, 0
3569  %sub7 = sub nsw i32 0, %sub
3570  %sub7.sub = select i1 %cmp4, i32 %sub7, i32 %sub
3571  ret i32 %sub7.sub
3572}
3573
3574define i32 @f6(i32 %a, i32 %b) {
3575; CHECK-LABEL: @f6(
3576; CHECK-NEXT:    [[CMP_UNSHIFTED:%.*]] = xor i32 [[A:%.*]], [[B:%.*]]
3577; CHECK-NEXT:    [[CMP_MASK:%.*]] = and i32 [[CMP_UNSHIFTED]], 255
3578; CHECK-NEXT:    [[CMP:%.*]] = icmp eq i32 [[CMP_MASK]], 0
3579; CHECK-NEXT:    [[S:%.*]] = select i1 [[CMP]], i32 10000, i32 0
3580; CHECK-NEXT:    ret i32 [[S]]
3581;
3582  %sext = shl i32 %a, 24
3583  %conv = ashr i32 %sext, 24
3584  %sext6 = shl i32 %b, 24
3585  %conv4 = ashr i32 %sext6, 24
3586  %cmp = icmp eq i32 %conv, %conv4
3587  %s = select i1 %cmp, i32 10000, i32 0
3588  ret i32 %s
3589}
3590
3591define i32 @f7(i32 %a, i32 %b) {
3592; CHECK-LABEL: @f7(
3593; CHECK-NEXT:    [[CMP_NOT_UNSHIFTED:%.*]] = xor i32 [[A:%.*]], [[B:%.*]]
3594; CHECK-NEXT:    [[CMP_NOT_MASK:%.*]] = and i32 [[CMP_NOT_UNSHIFTED]], 511
3595; CHECK-NEXT:    [[CMP_NOT:%.*]] = icmp eq i32 [[CMP_NOT_MASK]], 0
3596; CHECK-NEXT:    [[S:%.*]] = select i1 [[CMP_NOT]], i32 0, i32 10000
3597; CHECK-NEXT:    ret i32 [[S]]
3598;
3599  %sext = shl i32 %a, 23
3600  %sext6 = shl i32 %b, 23
3601  %cmp = icmp ne i32 %sext, %sext6
3602  %s = select i1 %cmp, i32 10000, i32 0
3603  ret i32 %s
3604}
3605
3606define i1 @f8(i32 %val, i32 %lim) {
3607; CHECK-LABEL: @f8(
3608; CHECK-NEXT:    [[R:%.*]] = icmp ne i32 [[LIM:%.*]], 0
3609; CHECK-NEXT:    ret i1 [[R]]
3610;
3611  %lim.sub = add i32 %lim, -1
3612  %val.and = and i32 %val, %lim.sub
3613  %r = icmp ult i32 %val.and, %lim
3614  ret i1 %r
3615}
3616
3617define i1 @f9(i32 %val, i32 %lim) {
3618; CHECK-LABEL: @f9(
3619; CHECK-NEXT:    [[R:%.*]] = icmp ne i32 [[LIM:%.*]], 0
3620; CHECK-NEXT:    ret i1 [[R]]
3621;
3622  %lim.sub = sub i32 %lim, 1
3623  %val.and = and i32 %val, %lim.sub
3624  %r = icmp ult i32 %val.and, %lim
3625  ret i1 %r
3626}
3627
3628define i1 @f10(i16 %p) {
3629; CHECK-LABEL: @f10(
3630; CHECK-NEXT:    [[EXT1:%.*]] = zext i8 ptrtoint (ptr @f10 to i8) to i16
3631; CHECK-NEXT:    [[EXT2:%.*]] = zext i8 ptrtoint (ptr @f10 to i8) to i16
3632; CHECK-NEXT:    [[MUL:%.*]] = mul nuw i16 [[EXT1]], [[EXT2]]
3633; CHECK-NEXT:    [[CMP580:%.*]] = icmp ule i16 [[MUL]], [[P:%.*]]
3634; CHECK-NEXT:    ret i1 [[CMP580]]
3635;
3636  %ext1 = zext i8 ptrtoint (ptr @f10 to i8) to i16
3637  %ext2 = zext i8 ptrtoint (ptr @f10 to i8) to i16
3638  %mul = mul i16 %ext1, %ext2
3639  %cmp580 = icmp ule i16 %mul, %p
3640  ret i1 %cmp580
3641}
3642
3643; Note: fptosi is used in various tests below to ensure that operand complexity
3644; canonicalization does not kick in, which would make some of the tests
3645; equivalent to one another.
3646
3647define i1 @cmp_sgt_rhs_dec(float %x, i32 %i) {
3648; CHECK-LABEL: @cmp_sgt_rhs_dec(
3649; CHECK-NEXT:    [[CONV:%.*]] = fptosi float [[X:%.*]] to i32
3650; CHECK-NEXT:    [[CMP:%.*]] = icmp sle i32 [[I:%.*]], [[CONV]]
3651; CHECK-NEXT:    ret i1 [[CMP]]
3652;
3653  %conv = fptosi float %x to i32
3654  %dec = sub nsw i32 %i, 1
3655  %cmp = icmp sgt i32 %conv, %dec
3656  ret i1 %cmp
3657}
3658
3659define i1 @cmp_sle_rhs_dec(float %x, i32 %i) {
3660; CHECK-LABEL: @cmp_sle_rhs_dec(
3661; CHECK-NEXT:    [[CONV:%.*]] = fptosi float [[X:%.*]] to i32
3662; CHECK-NEXT:    [[CMP:%.*]] = icmp sgt i32 [[I:%.*]], [[CONV]]
3663; CHECK-NEXT:    ret i1 [[CMP]]
3664;
3665  %conv = fptosi float %x to i32
3666  %dec = sub nsw i32 %i, 1
3667  %cmp = icmp sle i32 %conv, %dec
3668  ret i1 %cmp
3669}
3670
3671define i1 @cmp_sge_rhs_inc(float %x, i32 %i) {
3672; CHECK-LABEL: @cmp_sge_rhs_inc(
3673; CHECK-NEXT:    [[CONV:%.*]] = fptosi float [[X:%.*]] to i32
3674; CHECK-NEXT:    [[CMP:%.*]] = icmp slt i32 [[I:%.*]], [[CONV]]
3675; CHECK-NEXT:    ret i1 [[CMP]]
3676;
3677  %conv = fptosi float %x to i32
3678  %inc = add nsw i32 %i, 1
3679  %cmp = icmp sge i32 %conv, %inc
3680  ret i1 %cmp
3681}
3682
3683define i1 @cmp_slt_rhs_inc(float %x, i32 %i) {
3684; CHECK-LABEL: @cmp_slt_rhs_inc(
3685; CHECK-NEXT:    [[CONV:%.*]] = fptosi float [[X:%.*]] to i32
3686; CHECK-NEXT:    [[CMP:%.*]] = icmp sge i32 [[I:%.*]], [[CONV]]
3687; CHECK-NEXT:    ret i1 [[CMP]]
3688;
3689  %conv = fptosi float %x to i32
3690  %inc = add nsw i32 %i, 1
3691  %cmp = icmp slt i32 %conv, %inc
3692  ret i1 %cmp
3693}
3694
3695define i1 @PR26407(i32 %x, i32 %y) {
3696; CHECK-LABEL: @PR26407(
3697; CHECK-NEXT:    [[ADDX:%.*]] = add i32 [[X:%.*]], 2147483647
3698; CHECK-NEXT:    [[ADDY:%.*]] = add i32 [[Y:%.*]], 2147483647
3699; CHECK-NEXT:    [[CMP:%.*]] = icmp uge i32 [[ADDX]], [[ADDY]]
3700; CHECK-NEXT:    ret i1 [[CMP]]
3701;
3702  %addx = add i32 %x, 2147483647
3703  %addy = add i32 %y, 2147483647
3704  %cmp = icmp uge i32 %addx, %addy
3705  ret i1 %cmp
3706}
3707
3708define i1 @cmp_inverse_mask_bits_set_eq(i32 %x) {
3709; CHECK-LABEL: @cmp_inverse_mask_bits_set_eq(
3710; CHECK-NEXT:    [[TMP1:%.*]] = and i32 [[X:%.*]], -43
3711; CHECK-NEXT:    [[CMP:%.*]] = icmp eq i32 [[TMP1]], -43
3712; CHECK-NEXT:    ret i1 [[CMP]]
3713;
3714  %or = or i32 %x, 42
3715  %cmp = icmp eq i32 %or, -1
3716  ret i1 %cmp
3717}
3718
3719define <2 x i1> @cmp_inverse_mask_bits_set_eq_vec(<2 x i32> %x) {
3720; CHECK-LABEL: @cmp_inverse_mask_bits_set_eq_vec(
3721; CHECK-NEXT:    [[TMP1:%.*]] = and <2 x i32> [[X:%.*]], splat (i32 -43)
3722; CHECK-NEXT:    [[CMP:%.*]] = icmp eq <2 x i32> [[TMP1]], splat (i32 -43)
3723; CHECK-NEXT:    ret <2 x i1> [[CMP]]
3724;
3725  %or = or <2 x i32> %x, <i32 42, i32 42>
3726  %cmp = icmp eq <2 x i32> %or, <i32 -1, i32 -1>
3727  ret <2 x i1> %cmp
3728}
3729
3730define i1 @cmp_inverse_mask_bits_set_ne(i32 %x) {
3731; CHECK-LABEL: @cmp_inverse_mask_bits_set_ne(
3732; CHECK-NEXT:    [[TMP1:%.*]] = and i32 [[X:%.*]], -43
3733; CHECK-NEXT:    [[CMP:%.*]] = icmp ne i32 [[TMP1]], -43
3734; CHECK-NEXT:    ret i1 [[CMP]]
3735;
3736  %or = or i32 %x, 42
3737  %cmp = icmp ne i32 %or, -1
3738  ret i1 %cmp
3739}
3740
3741; When canonicalizing to 'gt/lt', make sure the constant is correct.
3742
3743define i1 @PR27792(i128 %a) {
3744; CHECK-LABEL: @PR27792(
3745; CHECK-NEXT:    [[CMP:%.*]] = icmp sgt i128 [[A:%.*]], -1
3746; CHECK-NEXT:    ret i1 [[CMP]]
3747;
3748  %cmp = icmp sge i128 %a, 0
3749  ret i1 %cmp
3750}
3751
3752define i1 @PR27792_2(i128 %a) {
3753; CHECK-LABEL: @PR27792_2(
3754; CHECK-NEXT:    [[B:%.*]] = icmp ne i128 [[A:%.*]], 0
3755; CHECK-NEXT:    ret i1 [[B]]
3756;
3757  %b = icmp uge i128 %a, 1
3758  ret i1 %b
3759}
3760
3761define i1 @ugtMaxSignedVal(i8 %a) {
3762; CHECK-LABEL: @ugtMaxSignedVal(
3763; CHECK-NEXT:    [[CMP:%.*]] = icmp slt i8 [[A:%.*]], 0
3764; CHECK-NEXT:    ret i1 [[CMP]]
3765;
3766  %cmp = icmp ugt i8 %a, 127
3767  ret i1 %cmp
3768}
3769
3770define <2 x i1> @ugtMaxSignedValVec(<2 x i8> %a) {
3771; CHECK-LABEL: @ugtMaxSignedValVec(
3772; CHECK-NEXT:    [[CMP:%.*]] = icmp slt <2 x i8> [[A:%.*]], zeroinitializer
3773; CHECK-NEXT:    ret <2 x i1> [[CMP]]
3774;
3775  %cmp = icmp ugt <2 x i8> %a, <i8 127, i8 127>
3776  ret <2 x i1> %cmp
3777}
3778
3779define i1 @ugtKnownBits(i8 %a) {
3780; CHECK-LABEL: @ugtKnownBits(
3781; CHECK-NEXT:    [[B:%.*]] = and i8 [[A:%.*]], 17
3782; CHECK-NEXT:    [[CMP:%.*]] = icmp eq i8 [[B]], 17
3783; CHECK-NEXT:    ret i1 [[CMP]]
3784;
3785  %b = and i8 %a, 17
3786  %cmp = icmp ugt i8 %b, 16
3787  ret i1 %cmp
3788}
3789
3790define <2 x i1> @ugtKnownBitsVec(<2 x i8> %a) {
3791; CHECK-LABEL: @ugtKnownBitsVec(
3792; CHECK-NEXT:    [[B:%.*]] = and <2 x i8> [[A:%.*]], splat (i8 17)
3793; CHECK-NEXT:    [[CMP:%.*]] = icmp eq <2 x i8> [[B]], splat (i8 17)
3794; CHECK-NEXT:    ret <2 x i1> [[CMP]]
3795;
3796  %b = and <2 x i8> %a, <i8 17, i8 17>
3797  %cmp = icmp ugt <2 x i8> %b, <i8 16, i8 16>
3798  ret <2 x i1> %cmp
3799}
3800
3801define i1 @or_ptrtoint_mismatch(ptr %p, ptr %q) {
3802; CHECK-LABEL: @or_ptrtoint_mismatch(
3803; CHECK-NEXT:    [[TMP1:%.*]] = icmp eq ptr [[P:%.*]], null
3804; CHECK-NEXT:    [[TMP2:%.*]] = icmp eq ptr [[Q:%.*]], null
3805; CHECK-NEXT:    [[B:%.*]] = and i1 [[TMP1]], [[TMP2]]
3806; CHECK-NEXT:    ret i1 [[B]]
3807;
3808
3809  %pp = ptrtoint ptr %p to i64
3810  %qq = ptrtoint ptr %q to i64
3811  %o = or i64 %pp, %qq
3812  %b = icmp eq i64 %o, 0
3813  ret i1 %b
3814}
3815
3816define i1 @icmp_add1_ugt(i32 %x, i32 %y) {
3817; CHECK-LABEL: @icmp_add1_ugt(
3818; CHECK-NEXT:    [[CMP:%.*]] = icmp uge i32 [[X:%.*]], [[Y:%.*]]
3819; CHECK-NEXT:    ret i1 [[CMP]]
3820;
3821  %add = add nuw i32 %x, 1
3822  %cmp = icmp ugt i32 %add, %y
3823  ret i1 %cmp
3824}
3825
3826define i1 @icmp_add1_ule(i32 %x, i32 %y) {
3827; CHECK-LABEL: @icmp_add1_ule(
3828; CHECK-NEXT:    [[CMP:%.*]] = icmp ult i32 [[X:%.*]], [[Y:%.*]]
3829; CHECK-NEXT:    ret i1 [[CMP]]
3830;
3831  %add = add nuw i32 %x, 1
3832  %cmp = icmp ule i32 %add, %y
3833  ret i1 %cmp
3834}
3835
3836define i1 @cmp_uge_rhs_inc(float %x, i32 %i) {
3837; CHECK-LABEL: @cmp_uge_rhs_inc(
3838; CHECK-NEXT:    [[CONV:%.*]] = fptosi float [[X:%.*]] to i32
3839; CHECK-NEXT:    [[CMP:%.*]] = icmp ult i32 [[I:%.*]], [[CONV]]
3840; CHECK-NEXT:    ret i1 [[CMP]]
3841;
3842  %conv = fptosi float %x to i32
3843  %inc = add nuw i32 %i, 1
3844  %cmp = icmp uge i32 %conv, %inc
3845  ret i1 %cmp
3846}
3847
3848define i1 @cmp_ult_rhs_inc(float %x, i32 %i) {
3849; CHECK-LABEL: @cmp_ult_rhs_inc(
3850; CHECK-NEXT:    [[CONV:%.*]] = fptosi float [[X:%.*]] to i32
3851; CHECK-NEXT:    [[CMP:%.*]] = icmp uge i32 [[I:%.*]], [[CONV]]
3852; CHECK-NEXT:    ret i1 [[CMP]]
3853;
3854  %conv = fptosi float %x to i32
3855  %inc = add nuw i32 %i, 1
3856  %cmp = icmp ult i32 %conv, %inc
3857  ret i1 %cmp
3858}
3859
3860define i1 @cmp_sge_lhs_inc(i32 %x, i32 %y) {
3861; CHECK-LABEL: @cmp_sge_lhs_inc(
3862; CHECK-NEXT:    [[INC:%.*]] = add nsw i32 [[X:%.*]], 1
3863; CHECK-NEXT:    [[CMP:%.*]] = icmp sge i32 [[INC]], [[Y:%.*]]
3864; CHECK-NEXT:    ret i1 [[CMP]]
3865;
3866  %inc = add nsw i32 %x, 1
3867  %cmp = icmp sge i32 %inc, %y
3868  ret i1 %cmp
3869}
3870
3871define i1 @cmp_uge_lhs_inc(i32 %x, i32 %y) {
3872; CHECK-LABEL: @cmp_uge_lhs_inc(
3873; CHECK-NEXT:    [[INC:%.*]] = add nuw i32 [[X:%.*]], 1
3874; CHECK-NEXT:    [[CMP:%.*]] = icmp uge i32 [[INC]], [[Y:%.*]]
3875; CHECK-NEXT:    ret i1 [[CMP]]
3876;
3877  %inc = add nuw i32 %x, 1
3878  %cmp = icmp uge i32 %inc, %y
3879  ret i1 %cmp
3880}
3881
3882define i1 @cmp_sgt_lhs_dec(i32 %x, i32 %y) {
3883; CHECK-LABEL: @cmp_sgt_lhs_dec(
3884; CHECK-NEXT:    [[DEC:%.*]] = add nsw i32 [[X:%.*]], -1
3885; CHECK-NEXT:    [[CMP:%.*]] = icmp sgt i32 [[DEC]], [[Y:%.*]]
3886; CHECK-NEXT:    ret i1 [[CMP]]
3887;
3888  %dec = sub nsw i32 %x, 1
3889  %cmp = icmp sgt i32 %dec, %y
3890  ret i1 %cmp
3891}
3892
3893define i1 @cmp_ugt_lhs_dec(i32 %x, i32 %y) {
3894; CHECK-LABEL: @cmp_ugt_lhs_dec(
3895; CHECK-NEXT:    [[DEC:%.*]] = add i32 [[X:%.*]], -1
3896; CHECK-NEXT:    [[CMP:%.*]] = icmp ugt i32 [[DEC]], [[Y:%.*]]
3897; CHECK-NEXT:    ret i1 [[CMP]]
3898;
3899  %dec = sub nuw i32 %x, 1
3900  %cmp = icmp ugt i32 %dec, %y
3901  ret i1 %cmp
3902}
3903
3904define i1 @cmp_sle_rhs_inc(float %x, i32 %y) {
3905; CHECK-LABEL: @cmp_sle_rhs_inc(
3906; CHECK-NEXT:    [[CONV:%.*]] = fptosi float [[X:%.*]] to i32
3907; CHECK-NEXT:    [[INC:%.*]] = add nsw i32 [[Y:%.*]], 1
3908; CHECK-NEXT:    [[CMP:%.*]] = icmp sge i32 [[INC]], [[CONV]]
3909; CHECK-NEXT:    ret i1 [[CMP]]
3910;
3911  %conv = fptosi float %x to i32
3912  %inc = add nsw i32 %y, 1
3913  %cmp = icmp sle i32 %conv, %inc
3914  ret i1 %cmp
3915}
3916
3917define i1 @cmp_ule_rhs_inc(float %x, i32 %y) {
3918; CHECK-LABEL: @cmp_ule_rhs_inc(
3919; CHECK-NEXT:    [[CONV:%.*]] = fptosi float [[X:%.*]] to i32
3920; CHECK-NEXT:    [[INC:%.*]] = add nuw i32 [[Y:%.*]], 1
3921; CHECK-NEXT:    [[CMP:%.*]] = icmp uge i32 [[INC]], [[CONV]]
3922; CHECK-NEXT:    ret i1 [[CMP]]
3923;
3924  %conv = fptosi float %x to i32
3925  %inc = add nuw i32 %y, 1
3926  %cmp = icmp ule i32 %conv, %inc
3927  ret i1 %cmp
3928}
3929
3930define i1 @cmp_slt_rhs_dec(float %x, i32 %y) {
3931; CHECK-LABEL: @cmp_slt_rhs_dec(
3932; CHECK-NEXT:    [[CONV:%.*]] = fptosi float [[X:%.*]] to i32
3933; CHECK-NEXT:    [[DEC:%.*]] = add nsw i32 [[Y:%.*]], -1
3934; CHECK-NEXT:    [[CMP:%.*]] = icmp sgt i32 [[DEC]], [[CONV]]
3935; CHECK-NEXT:    ret i1 [[CMP]]
3936;
3937  %conv = fptosi float %x to i32
3938  %dec = sub nsw i32 %y, 1
3939  %cmp = icmp slt i32 %conv, %dec
3940  ret i1 %cmp
3941}
3942
3943define i1 @cmp_ult_rhs_dec(float %x, i32 %y) {
3944; CHECK-LABEL: @cmp_ult_rhs_dec(
3945; CHECK-NEXT:    [[CONV:%.*]] = fptosi float [[X:%.*]] to i32
3946; CHECK-NEXT:    [[DEC:%.*]] = add i32 [[Y:%.*]], -1
3947; CHECK-NEXT:    [[CMP:%.*]] = icmp ugt i32 [[DEC]], [[CONV]]
3948; CHECK-NEXT:    ret i1 [[CMP]]
3949;
3950  %conv = fptosi float %x to i32
3951  %dec = sub nuw i32 %y, 1
3952  %cmp = icmp ult i32 %conv, %dec
3953  ret i1 %cmp
3954}
3955
3956define i1 @eq_add_constants(i32 %x, i32 %y) {
3957; CHECK-LABEL: @eq_add_constants(
3958; CHECK-NEXT:    [[C:%.*]] = icmp eq i32 [[X:%.*]], [[Y:%.*]]
3959; CHECK-NEXT:    ret i1 [[C]]
3960;
3961  %A = add i32 %x, 5
3962  %B = add i32 %y, 5
3963  %C = icmp eq i32 %A, %B
3964  ret i1 %C
3965}
3966
3967declare i32 @llvm.bswap.i32(i32)
3968
3969define i1 @bswap_ne(i32 %x, i32 %y) {
3970; CHECK-LABEL: @bswap_ne(
3971; CHECK-NEXT:    [[CMP:%.*]] = icmp ne i32 [[X:%.*]], [[Y:%.*]]
3972; CHECK-NEXT:    ret i1 [[CMP]]
3973;
3974  %swapx = call i32 @llvm.bswap.i32(i32 %x)
3975  %swapy = call i32 @llvm.bswap.i32(i32 %y)
3976  %cmp = icmp ne i32 %swapx, %swapy
3977  ret i1 %cmp
3978}
3979
3980declare <8 x i16> @llvm.bswap.v8i16(<8 x i16>)
3981
3982define <8 x i1> @bswap_vec_eq(<8 x i16> %x, <8 x i16> %y) {
3983; CHECK-LABEL: @bswap_vec_eq(
3984; CHECK-NEXT:    [[CMP:%.*]] = icmp eq <8 x i16> [[X:%.*]], [[Y:%.*]]
3985; CHECK-NEXT:    ret <8 x i1> [[CMP]]
3986;
3987  %swapx = call <8 x i16> @llvm.bswap.v8i16(<8 x i16> %x)
3988  %swapy = call <8 x i16> @llvm.bswap.v8i16(<8 x i16> %y)
3989  %cmp = icmp eq <8 x i16> %swapx, %swapy
3990  ret <8 x i1> %cmp
3991}
3992
3993declare i64 @llvm.bitreverse.i64(i64)
3994
3995define i1 @bitreverse_eq(i64 %x, i64 %y) {
3996; CHECK-LABEL: @bitreverse_eq(
3997; CHECK-NEXT:    [[CMP:%.*]] = icmp eq i64 [[X:%.*]], [[Y:%.*]]
3998; CHECK-NEXT:    ret i1 [[CMP]]
3999;
4000  %revx = call i64 @llvm.bitreverse.i64(i64 %x)
4001  %revy = call i64 @llvm.bitreverse.i64(i64 %y)
4002  %cmp = icmp eq i64 %revx, %revy
4003  ret i1 %cmp
4004}
4005
4006declare <8 x i16> @llvm.bitreverse.v8i16(<8 x i16>)
4007
4008define <8 x i1> @bitreverse_vec_ne(<8 x i16> %x, <8 x i16> %y) {
4009; CHECK-LABEL: @bitreverse_vec_ne(
4010; CHECK-NEXT:    [[CMP:%.*]] = icmp ne <8 x i16> [[X:%.*]], [[Y:%.*]]
4011; CHECK-NEXT:    ret <8 x i1> [[CMP]]
4012;
4013  %revx = call <8 x i16> @llvm.bitreverse.v8i16(<8 x i16> %x)
4014  %revy = call <8 x i16> @llvm.bitreverse.v8i16(<8 x i16> %y)
4015  %cmp = icmp ne <8 x i16> %revx, %revy
4016  ret <8 x i1> %cmp
4017}
4018
4019; These perform a comparison of a value known to be between 4 and 5 with a value between 5 and 7.
4020; They should all simplify to equality compares.
4021define i1 @knownbits1(i8 %a, i8 %b) {
4022; CHECK-LABEL: @knownbits1(
4023; CHECK-NEXT:    [[A1:%.*]] = and i8 [[A:%.*]], 1
4024; CHECK-NEXT:    [[B1:%.*]] = and i8 [[B:%.*]], 2
4025; CHECK-NEXT:    [[TMP1:%.*]] = or disjoint i8 [[B1]], 1
4026; CHECK-NEXT:    [[C:%.*]] = icmp eq i8 [[A1]], [[TMP1]]
4027; CHECK-NEXT:    ret i1 [[C]]
4028;
4029  %a1 = and i8 %a, 5
4030  %a2 = or i8 %a1, 4
4031  %b1 = and i8 %b, 7
4032  %b2 = or i8 %b1, 5
4033  %c = icmp uge i8 %a2, %b2
4034  ret i1 %c
4035}
4036
4037define i1 @knownbits2(i8 %a, i8 %b) {
4038; CHECK-LABEL: @knownbits2(
4039; CHECK-NEXT:    [[A1:%.*]] = and i8 [[A:%.*]], 1
4040; CHECK-NEXT:    [[B1:%.*]] = and i8 [[B:%.*]], 2
4041; CHECK-NEXT:    [[TMP1:%.*]] = or disjoint i8 [[B1]], 1
4042; CHECK-NEXT:    [[C:%.*]] = icmp ne i8 [[A1]], [[TMP1]]
4043; CHECK-NEXT:    ret i1 [[C]]
4044;
4045  %a1 = and i8 %a, 5
4046  %a2 = or i8 %a1, 4
4047  %b1 = and i8 %b, 7
4048  %b2 = or i8 %b1, 5
4049  %c = icmp ult i8 %a2, %b2
4050  ret i1 %c
4051}
4052
4053define i1 @knownbits3(i8 %a, i8 %b) {
4054; CHECK-LABEL: @knownbits3(
4055; CHECK-NEXT:    [[A1:%.*]] = and i8 [[A:%.*]], 1
4056; CHECK-NEXT:    [[B1:%.*]] = and i8 [[B:%.*]], 2
4057; CHECK-NEXT:    [[TMP1:%.*]] = or disjoint i8 [[B1]], 1
4058; CHECK-NEXT:    [[C:%.*]] = icmp eq i8 [[TMP1]], [[A1]]
4059; CHECK-NEXT:    ret i1 [[C]]
4060;
4061  %a1 = and i8 %a, 5
4062  %a2 = or i8 %a1, 4
4063  %b1 = and i8 %b, 7
4064  %b2 = or i8 %b1, 5
4065  %c = icmp ule i8 %b2, %a2
4066  ret i1 %c
4067}
4068
4069define <2 x i1> @knownbits4(<2 x i8> %a, <2 x i8> %b) {
4070; CHECK-LABEL: @knownbits4(
4071; CHECK-NEXT:    [[A1:%.*]] = and <2 x i8> [[A:%.*]], splat (i8 1)
4072; CHECK-NEXT:    [[B1:%.*]] = and <2 x i8> [[B:%.*]], splat (i8 2)
4073; CHECK-NEXT:    [[TMP1:%.*]] = or disjoint <2 x i8> [[B1]], splat (i8 1)
4074; CHECK-NEXT:    [[C:%.*]] = icmp ne <2 x i8> [[TMP1]], [[A1]]
4075; CHECK-NEXT:    ret <2 x i1> [[C]]
4076;
4077  %a1 = and <2 x i8> %a, <i8 5, i8 5>
4078  %a2 = or <2 x i8> %a1, <i8 4, i8 4>
4079  %b1 = and <2 x i8> %b, <i8 7, i8 7>
4080  %b2 = or <2 x i8> %b1, <i8 5, i8 5>
4081  %c = icmp ugt <2 x i8> %b2, %a2
4082  ret <2 x i1> %c
4083}
4084
4085; These are the signed versions of the above. One value is less than or equal to 5, but maybe negative.
4086; The other is known to be a value 5-7. These should simplify to equality comparisons.
4087define i1 @knownbits5(i8 %a, i8 %b) {
4088; CHECK-LABEL: @knownbits5(
4089; CHECK-NEXT:    [[A1:%.*]] = and i8 [[A:%.*]], -127
4090; CHECK-NEXT:    [[B1:%.*]] = and i8 [[B:%.*]], 2
4091; CHECK-NEXT:    [[TMP1:%.*]] = or disjoint i8 [[B1]], 1
4092; CHECK-NEXT:    [[C:%.*]] = icmp eq i8 [[A1]], [[TMP1]]
4093; CHECK-NEXT:    ret i1 [[C]]
4094;
4095  %a1 = and i8 %a, 133
4096  %a2 = or i8 %a1, 4
4097  %b1 = and i8 %b, 7
4098  %b2 = or i8 %b1, 5
4099  %c = icmp sge i8 %a2, %b2
4100  ret i1 %c
4101}
4102
4103define i1 @knownbits6(i8 %a, i8 %b) {
4104; CHECK-LABEL: @knownbits6(
4105; CHECK-NEXT:    [[A1:%.*]] = and i8 [[A:%.*]], -127
4106; CHECK-NEXT:    [[B1:%.*]] = and i8 [[B:%.*]], 2
4107; CHECK-NEXT:    [[TMP1:%.*]] = or disjoint i8 [[B1]], 1
4108; CHECK-NEXT:    [[C:%.*]] = icmp ne i8 [[A1]], [[TMP1]]
4109; CHECK-NEXT:    ret i1 [[C]]
4110;
4111  %a1 = and i8 %a, 133
4112  %a2 = or i8 %a1, 4
4113  %b1 = and i8 %b, 7
4114  %b2 = or i8 %b1, 5
4115  %c = icmp slt i8 %a2, %b2
4116  ret i1 %c
4117}
4118
4119define <2 x i1> @knownbits7(<2 x i8> %a, <2 x i8> %b) {
4120; CHECK-LABEL: @knownbits7(
4121; CHECK-NEXT:    [[A1:%.*]] = and <2 x i8> [[A:%.*]], splat (i8 -127)
4122; CHECK-NEXT:    [[B1:%.*]] = and <2 x i8> [[B:%.*]], splat (i8 2)
4123; CHECK-NEXT:    [[TMP1:%.*]] = or disjoint <2 x i8> [[B1]], splat (i8 1)
4124; CHECK-NEXT:    [[C:%.*]] = icmp eq <2 x i8> [[TMP1]], [[A1]]
4125; CHECK-NEXT:    ret <2 x i1> [[C]]
4126;
4127  %a1 = and <2 x i8> %a, <i8 133, i8 133>
4128  %a2 = or <2 x i8> %a1, <i8 4, i8 4>
4129  %b1 = and <2 x i8> %b, <i8 7, i8 7>
4130  %b2 = or <2 x i8> %b1, <i8 5, i8 5>
4131  %c = icmp sle <2 x i8> %b2, %a2
4132  ret <2 x i1> %c
4133}
4134
4135define i1 @knownbits8(i8 %a, i8 %b) {
4136; CHECK-LABEL: @knownbits8(
4137; CHECK-NEXT:    [[A1:%.*]] = and i8 [[A:%.*]], -127
4138; CHECK-NEXT:    [[B1:%.*]] = and i8 [[B:%.*]], 2
4139; CHECK-NEXT:    [[TMP1:%.*]] = or disjoint i8 [[B1]], 1
4140; CHECK-NEXT:    [[C:%.*]] = icmp ne i8 [[TMP1]], [[A1]]
4141; CHECK-NEXT:    ret i1 [[C]]
4142;
4143  %a1 = and i8 %a, 133
4144  %a2 = or i8 %a1, 4
4145  %b1 = and i8 %b, 7
4146  %b2 = or i8 %b1, 5
4147  %c = icmp sgt i8 %b2, %a2
4148  ret i1 %c
4149}
4150
4151; Make sure InstCombine doesn't try too hard to simplify the icmp and break the abs idiom
4152define i32 @abs_preserve(i32 %x) {
4153; CHECK-LABEL: @abs_preserve(
4154; CHECK-NEXT:    [[A:%.*]] = shl nsw i32 [[X:%.*]], 1
4155; CHECK-NEXT:    [[ABS:%.*]] = call i32 @llvm.abs.i32(i32 [[A]], i1 false)
4156; CHECK-NEXT:    ret i32 [[ABS]]
4157;
4158  %a = mul nsw i32 %x, 2
4159  %c = icmp sge i32 %a, 0
4160  %nega = sub i32 0, %a
4161  %abs = select i1 %c, i32 %a, i32 %nega
4162  ret i32 %abs
4163}
4164
4165; Don't crash by assuming the compared values are integers.
4166
4167declare void @llvm.assume(i1)
4168define i1 @PR35794(ptr %a) {
4169; CHECK-LABEL: @PR35794(
4170; CHECK-NEXT:    [[MASKCOND:%.*]] = icmp eq ptr [[A:%.*]], null
4171; CHECK-NEXT:    tail call void @llvm.assume(i1 [[MASKCOND]])
4172; CHECK-NEXT:    ret i1 true
4173;
4174  %cmp = icmp sgt ptr %a, inttoptr (i64 -1 to ptr)
4175  %maskcond = icmp eq ptr %a, null
4176  tail call void @llvm.assume(i1 %maskcond)
4177  ret i1 %cmp
4178}
4179
4180; Don't crash by assuming the compared values are integers.
4181define <2 x i1> @PR36583(<2 x ptr>)  {
4182; CHECK-LABEL: @PR36583(
4183; CHECK-NEXT:    [[RES:%.*]] = icmp eq <2 x ptr> [[TMP0:%.*]], zeroinitializer
4184; CHECK-NEXT:    ret <2 x i1> [[RES]]
4185;
4186  %cast = ptrtoint <2 x ptr> %0 to <2 x i64>
4187  %res = icmp eq <2 x i64> %cast, zeroinitializer
4188  ret <2 x i1> %res
4189}
4190
4191; fold (icmp pred (sub (0, X)) C1) for vec type
4192define <2 x i32> @Op1Negated_Vec(<2 x i32> %x) {
4193; CHECK-LABEL: @Op1Negated_Vec(
4194; CHECK-NEXT:    [[COND:%.*]] = call <2 x i32> @llvm.abs.v2i32(<2 x i32> [[X:%.*]], i1 true)
4195; CHECK-NEXT:    ret <2 x i32> [[COND]]
4196;
4197  %sub = sub nsw <2 x i32> zeroinitializer, %x
4198  %cmp = icmp sgt <2 x i32> %sub, <i32 -1, i32 -1>
4199  %cond = select <2 x i1> %cmp, <2 x i32> %sub, <2 x i32> %x
4200  ret <2 x i32> %cond
4201}
4202
4203define i1 @signbit_bitcast_fpext(float %x) {
4204; CHECK-LABEL: @signbit_bitcast_fpext(
4205; CHECK-NEXT:    [[TMP1:%.*]] = bitcast float [[X:%.*]] to i32
4206; CHECK-NEXT:    [[R:%.*]] = icmp slt i32 [[TMP1]], 0
4207; CHECK-NEXT:    ret i1 [[R]]
4208;
4209  %f = fpext float %x to double
4210  %b = bitcast double %f to i64
4211  %r = icmp slt i64 %b, 0
4212  ret i1 %r
4213}
4214
4215define <2 x i1> @signbit_bitcast_fpext_vec(<2 x half> %x) {
4216; CHECK-LABEL: @signbit_bitcast_fpext_vec(
4217; CHECK-NEXT:    [[TMP1:%.*]] = bitcast <2 x half> [[X:%.*]] to <2 x i16>
4218; CHECK-NEXT:    [[R:%.*]] = icmp slt <2 x i16> [[TMP1]], zeroinitializer
4219; CHECK-NEXT:    ret <2 x i1> [[R]]
4220;
4221  %f = fpext <2 x half> %x to <2 x float>
4222  %b = bitcast <2 x float> %f to <2 x i32>
4223  %r = icmp ugt <2 x i32> %b, <i32 2147483647, i32 2147483647>
4224  ret <2 x i1> %r
4225}
4226
4227define i1 @signbit_bitcast_fptrunc(float %x) {
4228; CHECK-LABEL: @signbit_bitcast_fptrunc(
4229; CHECK-NEXT:    [[TMP1:%.*]] = bitcast float [[X:%.*]] to i32
4230; CHECK-NEXT:    [[R:%.*]] = icmp sgt i32 [[TMP1]], -1
4231; CHECK-NEXT:    ret i1 [[R]]
4232;
4233  %f = fptrunc float %x to half
4234  %b = bitcast half %f to i16
4235  %r = icmp ult i16 %b, 32768
4236  ret i1 %r
4237}
4238
4239define <2 x i1> @signbit_bitcast_fptrunc_vec(<2 x double> %x) {
4240; CHECK-LABEL: @signbit_bitcast_fptrunc_vec(
4241; CHECK-NEXT:    [[TMP1:%.*]] = bitcast <2 x double> [[X:%.*]] to <2 x i64>
4242; CHECK-NEXT:    [[R:%.*]] = icmp sgt <2 x i64> [[TMP1]], splat (i64 -1)
4243; CHECK-NEXT:    ret <2 x i1> [[R]]
4244;
4245  %f = fptrunc <2 x double> %x to <2 x half>
4246  %b = bitcast <2 x half> %f to <2 x i16>
4247  %r = icmp sge <2 x i16> %b, zeroinitializer
4248  ret <2 x i1> %r
4249}
4250
4251define i1 @signbit_bitcast_fpext_wrong_cmp(float %x) {
4252; CHECK-LABEL: @signbit_bitcast_fpext_wrong_cmp(
4253; CHECK-NEXT:    [[F:%.*]] = fpext float [[X:%.*]] to double
4254; CHECK-NEXT:    [[B:%.*]] = bitcast double [[F]] to i64
4255; CHECK-NEXT:    [[R:%.*]] = icmp slt i64 [[B]], 1
4256; CHECK-NEXT:    ret i1 [[R]]
4257;
4258  %f = fpext float %x to double
4259  %b = bitcast double %f to i64
4260  %r = icmp slt i64 %b, 1
4261  ret i1 %r
4262}
4263
4264define <4 x i1> @signbit_bitcast_fpext_vec_wrong_bitcast(<2 x half> %x) {
4265; CHECK-LABEL: @signbit_bitcast_fpext_vec_wrong_bitcast(
4266; CHECK-NEXT:    [[F:%.*]] = fpext <2 x half> [[X:%.*]] to <2 x float>
4267; CHECK-NEXT:    [[B:%.*]] = bitcast <2 x float> [[F]] to <4 x i16>
4268; CHECK-NEXT:    [[R:%.*]] = icmp sgt <4 x i16> [[B]], splat (i16 -1)
4269; CHECK-NEXT:    ret <4 x i1> [[R]]
4270;
4271  %f = fpext <2 x half> %x to <2 x float>
4272  %b = bitcast <2 x float> %f to <4 x i16>
4273  %r = icmp sgt <4 x i16> %b, <i16 -1, i16 -1, i16 -1, i16 -1>
4274  ret <4 x i1> %r
4275}
4276
4277define i1 @signbit_bitcast_fpext_extra_use(float %x, ptr %p) {
4278; CHECK-LABEL: @signbit_bitcast_fpext_extra_use(
4279; CHECK-NEXT:    [[F:%.*]] = fpext float [[X:%.*]] to double
4280; CHECK-NEXT:    [[B:%.*]] = bitcast double [[F]] to i64
4281; CHECK-NEXT:    call void @use_i64(i64 [[B]])
4282; CHECK-NEXT:    [[R:%.*]] = icmp slt i64 [[B]], 0
4283; CHECK-NEXT:    ret i1 [[R]]
4284;
4285  %f = fpext float %x to double
4286  %b = bitcast double %f to i64
4287  call void @use_i64(i64 %b)
4288  %r = icmp slt i64 %b, 0
4289  ret i1 %r
4290}
4291
4292define i1 @signbit_bitcast_fpext_ppc_fp128(float %x) {
4293; CHECK-LABEL: @signbit_bitcast_fpext_ppc_fp128(
4294; CHECK-NEXT:    [[S2:%.*]] = fpext float [[X:%.*]] to ppc_fp128
4295; CHECK-NEXT:    [[S3:%.*]] = bitcast ppc_fp128 [[S2]] to i128
4296; CHECK-NEXT:    [[S4:%.*]] = icmp slt i128 [[S3]], 0
4297; CHECK-NEXT:    ret i1 [[S4]]
4298;
4299  %s2 = fpext float %x to ppc_fp128
4300  %s3 = bitcast ppc_fp128 %s2 to i128
4301  %s4 = icmp slt i128 %s3, 0
4302  ret i1 %s4
4303}
4304
4305define i1 @signbit_bitcast_fptrunc_ppc_fp128(ppc_fp128 %x) {
4306; CHECK-LABEL: @signbit_bitcast_fptrunc_ppc_fp128(
4307; CHECK-NEXT:    [[S2:%.*]] = fptrunc ppc_fp128 [[X:%.*]] to float
4308; CHECK-NEXT:    [[S3:%.*]] = bitcast float [[S2]] to i32
4309; CHECK-NEXT:    [[S4:%.*]] = icmp slt i32 [[S3]], 0
4310; CHECK-NEXT:    ret i1 [[S4]]
4311;
4312  %s2 = fptrunc ppc_fp128 %x to float
4313  %s3 = bitcast float %s2 to i32
4314  %s4 = icmp slt i32 %s3, 0
4315  ret i1 %s4
4316}
4317
4318@x = external dso_local local_unnamed_addr global i32, align 4
4319@y = external dso_local local_unnamed_addr global i32, align 4
4320define i1 @pr47997(i32 %arg) {
4321; CHECK-LABEL: @pr47997(
4322; CHECK-NEXT:  bb:
4323; CHECK-NEXT:    [[I:%.*]] = add nsw i32 [[ARG:%.*]], -1
4324; CHECK-NEXT:    store i32 [[I]], ptr @x, align 4
4325; CHECK-NEXT:    [[I1:%.*]] = sub nsw i32 1, [[ARG]]
4326; CHECK-NEXT:    store i32 [[I1]], ptr @y, align 4
4327; CHECK-NEXT:    ret i1 true
4328;
4329bb:
4330  %i = add nsw i32 %arg, -1
4331  store i32 %i, ptr @x
4332  %i1 = sub nsw i32 1, %arg
4333  store i32 %i1, ptr @y
4334  %i2 = sub nsw i32 0, %i1
4335  %i3 = icmp eq i32 %i, %i2
4336  ret i1 %i3
4337}
4338
4339; PR50944
4340
4341define i1 @thread_cmp_over_select_with_poison_trueval(i1 %b) {
4342; CHECK-LABEL: @thread_cmp_over_select_with_poison_trueval(
4343; CHECK-NEXT:    ret i1 false
4344;
4345  %s = select i1 %b, i32 poison, i32 0
4346  %tobool = icmp ne i32 %s, 0
4347  ret i1 %tobool
4348}
4349
4350define i1 @thread_cmp_over_select_with_poison_falseval(i1 %b) {
4351; CHECK-LABEL: @thread_cmp_over_select_with_poison_falseval(
4352; CHECK-NEXT:    ret i1 true
4353;
4354  %s = select i1 %b, i32 1, i32 poison
4355  %tobool = icmp ne i32 %s, 0
4356  ret i1 %tobool
4357}
4358
4359define i1 @signbit_true_logic(i8 %x) {
4360; CHECK-LABEL: @signbit_true_logic(
4361; CHECK-NEXT:    [[R:%.*]] = icmp eq i8 [[X:%.*]], 0
4362; CHECK-NEXT:    ret i1 [[R]]
4363;
4364  %dec = add i8 %x, -1
4365  %not = xor i8 %x, -1
4366  %and = and i8 %dec, %not
4367  %r = icmp slt i8 %and, 0
4368  ret i1 %r
4369}
4370
4371define <2 x i1> @signbit_false_logic(<2 x i5> %x) {
4372; CHECK-LABEL: @signbit_false_logic(
4373; CHECK-NEXT:    [[R:%.*]] = icmp ne <2 x i5> [[X:%.*]], zeroinitializer
4374; CHECK-NEXT:    ret <2 x i1> [[R]]
4375;
4376  %dec = add <2 x i5> %x,  <i5 -1, i5 poison>
4377  %not = xor <2 x i5> %x,  <i5 -1, i5 -1>
4378  %and = and <2 x i5> %dec, %not
4379  %r = icmp sgt <2 x i5> %and, <i5 -1, i5 -1>
4380  ret <2 x i1> %r
4381}
4382
4383; Confirm that complexity canonicalization works for commuted pattern.
4384
4385define i1 @signbit_true_logic_uses_commute(i64 %x) {
4386; CHECK-LABEL: @signbit_true_logic_uses_commute(
4387; CHECK-NEXT:    [[DEC:%.*]] = add i64 [[X:%.*]], -1
4388; CHECK-NEXT:    call void @use_i64(i64 [[DEC]])
4389; CHECK-NEXT:    [[NOT:%.*]] = xor i64 [[X]], -1
4390; CHECK-NEXT:    call void @use_i64(i64 [[NOT]])
4391; CHECK-NEXT:    [[AND:%.*]] = and i64 [[DEC]], [[NOT]]
4392; CHECK-NEXT:    call void @use_i64(i64 [[AND]])
4393; CHECK-NEXT:    [[R:%.*]] = icmp eq i64 [[X]], 0
4394; CHECK-NEXT:    ret i1 [[R]]
4395;
4396  %dec = add i64 %x, -1
4397  call void @use_i64(i64 %dec)
4398  %not = xor i64 %x, -1
4399  call void @use_i64(i64 %not)
4400  %and = and i64 %not, %dec
4401  call void @use_i64(i64 %and)
4402  %r = icmp slt i64 %and, 0
4403  ret i1 %r
4404}
4405
4406define i1 @redundant_sign_bit_count_ult_1_2(i32 %x) {
4407; CHECK-LABEL: @redundant_sign_bit_count_ult_1_2(
4408; CHECK-NEXT:    [[TMP1:%.*]] = add i32 [[X:%.*]], 4
4409; CHECK-NEXT:    [[C:%.*]] = icmp ult i32 [[TMP1]], 8
4410; CHECK-NEXT:    ret i1 [[C]]
4411;
4412  %y = ashr i32 %x, 1
4413  %z = xor i32 %y, %x
4414  %c = icmp ult i32 %z, 4
4415  ret i1 %c
4416}
4417
4418define i1 @redundant_sign_bit_count_ult_1_30(i32 %x) {
4419; CHECK-LABEL: @redundant_sign_bit_count_ult_1_30(
4420; CHECK-NEXT:    [[TMP1:%.*]] = add i32 [[X:%.*]], 1073741824
4421; CHECK-NEXT:    [[C:%.*]] = icmp sgt i32 [[TMP1]], -1
4422; CHECK-NEXT:    ret i1 [[C]]
4423;
4424  %y = ashr i32 %x, 1
4425  %z = xor i32 %y, %x
4426  %c = icmp ult i32 %z, 1073741824
4427  ret i1 %c
4428}
4429
4430define i1 @redundant_sign_bit_count_ult_31_2(i32 %x) {
4431; CHECK-LABEL: @redundant_sign_bit_count_ult_31_2(
4432; CHECK-NEXT:    [[TMP1:%.*]] = add i32 [[X:%.*]], 4
4433; CHECK-NEXT:    [[C:%.*]] = icmp ult i32 [[TMP1]], 8
4434; CHECK-NEXT:    ret i1 [[C]]
4435;
4436  %y = ashr i32 %x, 31
4437  %z = xor i32 %y, %x
4438  %c = icmp ult i32 %z, 4
4439  ret i1 %c
4440}
4441
4442define i1 @redundant_sign_bit_count_ult_31_30(i32 %x) {
4443; CHECK-LABEL: @redundant_sign_bit_count_ult_31_30(
4444; CHECK-NEXT:    [[TMP1:%.*]] = add i32 [[X:%.*]], 1073741824
4445; CHECK-NEXT:    [[C:%.*]] = icmp sgt i32 [[TMP1]], -1
4446; CHECK-NEXT:    ret i1 [[C]]
4447;
4448  %y = ashr i32 %x, 31
4449  %z = xor i32 %y, %x
4450  %c = icmp ult i32 %z, 1073741824
4451  ret i1 %c
4452}
4453
4454define i1 @redundant_sign_bit_count_ult_31_30_extra_use_ashr(i32 %x) {
4455; CHECK-LABEL: @redundant_sign_bit_count_ult_31_30_extra_use_ashr(
4456; CHECK-NEXT:    [[Y:%.*]] = ashr i32 [[X:%.*]], 31
4457; CHECK-NEXT:    call void @use_i32(i32 [[Y]])
4458; CHECK-NEXT:    [[TMP1:%.*]] = add i32 [[X]], 1073741824
4459; CHECK-NEXT:    [[C:%.*]] = icmp sgt i32 [[TMP1]], -1
4460; CHECK-NEXT:    ret i1 [[C]]
4461;
4462  %y = ashr i32 %x, 31
4463  call void @use_i32(i32 %y)
4464  %z = xor i32 %y, %x
4465  %c = icmp ult i32 %z, 1073741824
4466  ret i1 %c
4467}
4468
4469define i1 @redundant_sign_bit_count_ult_31_30_extra_use_xor(i32 %x) {
4470; CHECK-LABEL: @redundant_sign_bit_count_ult_31_30_extra_use_xor(
4471; CHECK-NEXT:    [[Y:%.*]] = ashr i32 [[X:%.*]], 31
4472; CHECK-NEXT:    [[Z:%.*]] = xor i32 [[Y]], [[X]]
4473; CHECK-NEXT:    call void @use_i32(i32 [[Z]])
4474; CHECK-NEXT:    [[C:%.*]] = icmp ult i32 [[Z]], 1073741824
4475; CHECK-NEXT:    ret i1 [[C]]
4476;
4477  %y = ashr i32 %x, 31
4478  %z = xor i32 %y, %x
4479  call void @use_i32(i32 %z)
4480  %c = icmp ult i32 %z, 1073741824
4481  ret i1 %c
4482}
4483
4484define i1 @not_redundant_sign_bit_count_ult(i32 %w, i32 %x) {
4485; CHECK-LABEL: @not_redundant_sign_bit_count_ult(
4486; CHECK-NEXT:    [[Y:%.*]] = ashr i32 [[X:%.*]], 31
4487; CHECK-NEXT:    [[Z:%.*]] = xor i32 [[Y]], [[W:%.*]]
4488; CHECK-NEXT:    [[C:%.*]] = icmp ult i32 [[Z]], 1073741824
4489; CHECK-NEXT:    ret i1 [[C]]
4490;
4491  %y = ashr i32 %x, 31
4492  %z = xor i32 %y, %w
4493  %c = icmp ult i32 %z, 1073741824
4494  ret i1 %c
4495}
4496
4497define i1 @wrong_shift_opcode_i8(i8 %x) {
4498; CHECK-LABEL: @wrong_shift_opcode_i8(
4499; CHECK-NEXT:    [[Y:%.*]] = lshr i8 [[X:%.*]], 5
4500; CHECK-NEXT:    [[Z:%.*]] = xor i8 [[Y]], [[X]]
4501; CHECK-NEXT:    [[C:%.*]] = icmp ult i8 [[Z]], 2
4502; CHECK-NEXT:    ret i1 [[C]]
4503;
4504  %y = lshr i8 %x, 5
4505  %z = xor i8 %y, %x
4506  %c = icmp ult i8 %z, 2
4507  ret i1 %c
4508}
4509
4510define i1 @redundant_sign_bit_count_ult_31_30_commute(i32 %xsrc) {
4511; CHECK-LABEL: @redundant_sign_bit_count_ult_31_30_commute(
4512; CHECK-NEXT:    [[X:%.*]] = mul i32 [[XSRC:%.*]], 13
4513; CHECK-NEXT:    [[TMP1:%.*]] = add i32 [[X]], 1073741824
4514; CHECK-NEXT:    [[C:%.*]] = icmp sgt i32 [[TMP1]], -1
4515; CHECK-NEXT:    ret i1 [[C]]
4516;
4517  %x = mul i32 %xsrc, 13 ; thwart complexity-based canonicalization
4518  %y = ashr i32 %x, 31
4519  %z = xor i32 %x, %y
4520  %c = icmp ult i32 %z, 1073741824
4521  ret i1 %c
4522}
4523
4524define i1 @redundant_sign_bit_count_i8(i8 %x) {
4525; CHECK-LABEL: @redundant_sign_bit_count_i8(
4526; CHECK-NEXT:    [[TMP1:%.*]] = add i8 [[X:%.*]], 2
4527; CHECK-NEXT:    [[C:%.*]] = icmp ult i8 [[TMP1]], 4
4528; CHECK-NEXT:    ret i1 [[C]]
4529;
4530  %y = ashr i8 %x, 5
4531  %z = xor i8 %y, %x
4532  %c = icmp ult i8 %z, 2
4533  ret i1 %c
4534}
4535
4536define <2 x i1> @redundant_sign_bit_count_ult_31_30_vector(<2 x i32> %xsrc) {
4537; CHECK-LABEL: @redundant_sign_bit_count_ult_31_30_vector(
4538; CHECK-NEXT:    [[X:%.*]] = mul <2 x i32> [[XSRC:%.*]], splat (i32 13)
4539; CHECK-NEXT:    [[TMP1:%.*]] = add <2 x i32> [[X]], splat (i32 1073741824)
4540; CHECK-NEXT:    [[C:%.*]] = icmp sgt <2 x i32> [[TMP1]], splat (i32 -1)
4541; CHECK-NEXT:    ret <2 x i1> [[C]]
4542;
4543  %x = mul <2 x i32> %xsrc, <i32 13, i32 13> ; thwart complexity-based canonicalization
4544  %y = ashr <2 x i32> %x, <i32 31, i32 31>
4545  %z = xor <2 x i32> %x, %y
4546  %c = icmp ult <2 x i32> %z, <i32 1073741824, i32 1073741824>
4547  ret <2 x i1> %c
4548}
4549
4550define i1 @redundant_sign_bit_count_ugt_1_2(i32 %x) {
4551; CHECK-LABEL: @redundant_sign_bit_count_ugt_1_2(
4552; CHECK-NEXT:    [[TMP1:%.*]] = add i32 [[X:%.*]], -4
4553; CHECK-NEXT:    [[C:%.*]] = icmp ult i32 [[TMP1]], -8
4554; CHECK-NEXT:    ret i1 [[C]]
4555;
4556  %y = ashr i32 %x, 1
4557  %z = xor i32 %y, %x
4558  %c = icmp ugt i32 %z, 3
4559  ret i1 %c
4560}
4561
4562define i1 @redundant_sign_bit_count_ugt_1_30(i32 %x) {
4563; CHECK-LABEL: @redundant_sign_bit_count_ugt_1_30(
4564; CHECK-NEXT:    [[TMP1:%.*]] = add i32 [[X:%.*]], 1073741824
4565; CHECK-NEXT:    [[C:%.*]] = icmp slt i32 [[TMP1]], 0
4566; CHECK-NEXT:    ret i1 [[C]]
4567;
4568  %y = ashr i32 %x, 1
4569  %z = xor i32 %y, %x
4570  %c = icmp ugt i32 %z, 1073741823
4571  ret i1 %c
4572}
4573
4574define i1 @redundant_sign_bit_count_ugt_31_2(i32 %x) {
4575; CHECK-LABEL: @redundant_sign_bit_count_ugt_31_2(
4576; CHECK-NEXT:    [[TMP1:%.*]] = add i32 [[X:%.*]], -4
4577; CHECK-NEXT:    [[C:%.*]] = icmp ult i32 [[TMP1]], -8
4578; CHECK-NEXT:    ret i1 [[C]]
4579;
4580  %y = ashr i32 %x, 31
4581  %z = xor i32 %y, %x
4582  %c = icmp ugt i32 %z, 3
4583  ret i1 %c
4584}
4585
4586define i1 @redundant_sign_bit_count_ugt_31_30(i32 %x) {
4587; CHECK-LABEL: @redundant_sign_bit_count_ugt_31_30(
4588; CHECK-NEXT:    [[TMP1:%.*]] = add i32 [[X:%.*]], 1073741824
4589; CHECK-NEXT:    [[C:%.*]] = icmp slt i32 [[TMP1]], 0
4590; CHECK-NEXT:    ret i1 [[C]]
4591;
4592  %y = ashr i32 %x, 31
4593  %z = xor i32 %y, %x
4594  %c = icmp ugt i32 %z, 1073741823
4595  ret i1 %c
4596}
4597
4598define i1 @zext_bool_and_eq0(i1 %x, i8 %y) {
4599; CHECK-LABEL: @zext_bool_and_eq0(
4600; CHECK-NEXT:    [[TMP1:%.*]] = and i8 [[Y:%.*]], 1
4601; CHECK-NEXT:    [[R1:%.*]] = icmp eq i8 [[TMP1]], 0
4602; CHECK-NEXT:    [[NOT_X:%.*]] = xor i1 [[X:%.*]], true
4603; CHECK-NEXT:    [[R:%.*]] = select i1 [[NOT_X]], i1 true, i1 [[R1]]
4604; CHECK-NEXT:    ret i1 [[R]]
4605;
4606  %zx = zext i1 %x to i8
4607  %a = and i8 %zx, %y
4608  %r = icmp eq i8 %a, 0
4609  ret i1 %r
4610}
4611
4612define <2 x i1> @zext_bool_and_eq0_commute(<2 x i1> %x, <2 x i8> %p) {
4613; CHECK-LABEL: @zext_bool_and_eq0_commute(
4614; CHECK-NEXT:    [[TMP1:%.*]] = and <2 x i8> [[P:%.*]], splat (i8 1)
4615; CHECK-NEXT:    [[R1:%.*]] = icmp eq <2 x i8> [[TMP1]], zeroinitializer
4616; CHECK-NEXT:    [[NOT_X:%.*]] = xor <2 x i1> [[X:%.*]], splat (i1 true)
4617; CHECK-NEXT:    [[R:%.*]] = select <2 x i1> [[NOT_X]], <2 x i1> splat (i1 true), <2 x i1> [[R1]]
4618; CHECK-NEXT:    ret <2 x i1> [[R]]
4619;
4620  %y = mul <2 x i8> %p, %p ; thwart complexity-based canonicalization
4621  %zx = zext <2 x i1> %x to <2 x i8>
4622  %a = and <2 x i8> %y, %zx
4623  %r = icmp eq <2 x i8> %a, zeroinitializer
4624  ret <2 x i1> %r
4625}
4626
4627define i1 @zext_bool_and_ne0(i1 %x, i8 %y) {
4628; CHECK-LABEL: @zext_bool_and_ne0(
4629; CHECK-NEXT:    [[TMP1:%.*]] = and i8 [[Y:%.*]], 1
4630; CHECK-NEXT:    [[R1:%.*]] = icmp ne i8 [[TMP1]], 0
4631; CHECK-NEXT:    [[R:%.*]] = select i1 [[X:%.*]], i1 [[R1]], i1 false
4632; CHECK-NEXT:    ret i1 [[R]]
4633;
4634  %zx = zext i1 %x to i8
4635  %a = and i8 %zx, %y
4636  %r = icmp ne i8 %a, 0
4637  ret i1 %r
4638}
4639
4640define i1 @zext_bool_and_ne1(i1 %x, i8 %y) {
4641; CHECK-LABEL: @zext_bool_and_ne1(
4642; CHECK-NEXT:    [[TMP1:%.*]] = and i8 [[Y:%.*]], 1
4643; CHECK-NEXT:    [[R1:%.*]] = icmp eq i8 [[TMP1]], 0
4644; CHECK-NEXT:    [[NOT_X:%.*]] = xor i1 [[X:%.*]], true
4645; CHECK-NEXT:    [[R:%.*]] = select i1 [[NOT_X]], i1 true, i1 [[R1]]
4646; CHECK-NEXT:    ret i1 [[R]]
4647;
4648  %zx = zext i1 %x to i8
4649  %a = and i8 %zx, %y
4650  %r = icmp ne i8 %a, 1
4651  ret i1 %r
4652}
4653
4654define <2 x i1> @zext_bool_and_eq1(<2 x i1> %x, <2 x i8> %y) {
4655; CHECK-LABEL: @zext_bool_and_eq1(
4656; CHECK-NEXT:    [[R1:%.*]] = trunc <2 x i8> [[Y:%.*]] to <2 x i1>
4657; CHECK-NEXT:    [[R:%.*]] = select <2 x i1> [[X:%.*]], <2 x i1> [[R1]], <2 x i1> zeroinitializer
4658; CHECK-NEXT:    ret <2 x i1> [[R]]
4659;
4660  %zx = zext <2 x i1> %x to <2 x i8>
4661  %a = and <2 x i8> %zx, %y
4662  %r = icmp eq <2 x i8> %a, <i8 1, i8 1>
4663  ret <2 x i1> %r
4664}
4665
4666; negative test - wrong logic op
4667
4668define i1 @zext_bool_or_eq0(i1 %x, i8 %y) {
4669; CHECK-LABEL: @zext_bool_or_eq0(
4670; CHECK-NEXT:    [[ZX:%.*]] = zext i1 [[X:%.*]] to i8
4671; CHECK-NEXT:    [[A:%.*]] = or i8 [[Y:%.*]], [[ZX]]
4672; CHECK-NEXT:    [[R:%.*]] = icmp eq i8 [[A]], 0
4673; CHECK-NEXT:    ret i1 [[R]]
4674;
4675  %zx = zext i1 %x to i8
4676  %a = or i8 %zx, %y
4677  %r = icmp eq i8 %a, 0
4678  ret i1 %r
4679}
4680
4681; negative test - extra use
4682
4683define i1 @zext_bool_and_eq0_use(i1 %x, i64 %y) {
4684; CHECK-LABEL: @zext_bool_and_eq0_use(
4685; CHECK-NEXT:    [[ZX:%.*]] = zext i1 [[X:%.*]] to i64
4686; CHECK-NEXT:    call void @use_i64(i64 [[ZX]])
4687; CHECK-NEXT:    [[A:%.*]] = and i64 [[Y:%.*]], [[ZX]]
4688; CHECK-NEXT:    [[R:%.*]] = icmp eq i64 [[A]], 0
4689; CHECK-NEXT:    ret i1 [[R]]
4690;
4691  %zx = zext i1 %x to i64
4692  call void @use_i64(i64 %zx)
4693  %a = and i64 %zx, %y
4694  %r = icmp eq i64 %a, 0
4695  ret i1 %r
4696}
4697
4698; negative test - extra use
4699
4700define i1 @zext_bool_and_ne0_use(i1 %x, i64 %y) {
4701; CHECK-LABEL: @zext_bool_and_ne0_use(
4702; CHECK-NEXT:    [[TMP1:%.*]] = and i64 [[Y:%.*]], 1
4703; CHECK-NEXT:    [[A:%.*]] = select i1 [[X:%.*]], i64 [[TMP1]], i64 0
4704; CHECK-NEXT:    call void @use_i64(i64 [[A]])
4705; CHECK-NEXT:    [[R:%.*]] = icmp ne i64 [[A]], 0
4706; CHECK-NEXT:    ret i1 [[R]]
4707;
4708  %zx = zext i1 %x to i64
4709  %a = and i64 %zx, %y
4710  call void @use_i64(i64 %a)
4711  %r = icmp ne i64 %a, 0
4712  ret i1 %r
4713}
4714
4715; negative test - must zext from i1
4716
4717define i1 @zext_notbool_and_ne0(i2 %x, i8 %y) {
4718; CHECK-LABEL: @zext_notbool_and_ne0(
4719; CHECK-NEXT:    [[ZX:%.*]] = zext i2 [[X:%.*]] to i8
4720; CHECK-NEXT:    [[A:%.*]] = and i8 [[Y:%.*]], [[ZX]]
4721; CHECK-NEXT:    [[R:%.*]] = icmp ne i8 [[A]], 0
4722; CHECK-NEXT:    ret i1 [[R]]
4723;
4724  %zx = zext i2 %x to i8
4725  %a = and i8 %zx, %y
4726  %r = icmp ne i8 %a, 0
4727  ret i1 %r
4728}
4729
4730; fold icmp(X | OrC, C) --> icmp(X, 0)
4731
4732define i1 @or_positive_sgt_zero(i8 %a) {
4733; CHECK-LABEL: @or_positive_sgt_zero(
4734; CHECK-NEXT:    [[CMP:%.*]] = icmp sgt i8 [[A:%.*]], -1
4735; CHECK-NEXT:    ret i1 [[CMP]]
4736;
4737  %b = or i8 %a, 24
4738  %cmp = icmp sgt i8 %b, 0
4739  ret i1 %cmp
4740}
4741
4742define <2 x i1> @or_postive_sgt_zero_vec(<2 x i8> %a) {
4743; CHECK-LABEL: @or_postive_sgt_zero_vec(
4744; CHECK-NEXT:    [[CMP:%.*]] = icmp sgt <2 x i8> [[A:%.*]], splat (i8 -1)
4745; CHECK-NEXT:    ret <2 x i1> [[CMP]]
4746;
4747
4748  %b = or <2 x i8> %a, <i8 24, i8 24>
4749  %cmp = icmp sgt <2 x i8> %b, <i8 0, i8 0>
4750  ret <2 x i1> %cmp
4751}
4752
4753define <2 x i1> @or_poison_vec_sgt_zero_vec(<2 x i8> %a) {
4754; CHECK-LABEL: @or_poison_vec_sgt_zero_vec(
4755; CHECK-NEXT:    ret <2 x i1> poison
4756;
4757
4758  %b = or <2 x i8> %a, <i8 poison, i8 poison>
4759  %cmp = icmp sgt <2 x i8> %b, <i8 0, i8 0>
4760  ret <2 x i1> %cmp
4761}
4762
4763define i1 @or_positive_sge_zero(i8 %a) {
4764; CHECK-LABEL: @or_positive_sge_zero(
4765; CHECK-NEXT:    [[CMP:%.*]] = icmp sgt i8 [[A:%.*]], -1
4766; CHECK-NEXT:    ret i1 [[CMP]]
4767;
4768  %b = or i8 %a, 24
4769  %cmp = icmp sge i8 %b, 0
4770  ret i1 %cmp
4771}
4772
4773define <2 x i1> @or_postive_sge_zero_vec(<2 x i8> %a) {
4774; CHECK-LABEL: @or_postive_sge_zero_vec(
4775; CHECK-NEXT:    [[CMP:%.*]] = icmp sgt <2 x i8> [[A:%.*]], splat (i8 -1)
4776; CHECK-NEXT:    ret <2 x i1> [[CMP]]
4777;
4778
4779  %b = or <2 x i8> %a, <i8 24, i8 24>
4780  %cmp = icmp sge <2 x i8> %b, <i8 0, i8 0>
4781  ret <2 x i1> %cmp
4782}
4783
4784define <2 x i1> @or_poison_vec_sge_zero_vec(<2 x i8> %a) {
4785; CHECK-LABEL: @or_poison_vec_sge_zero_vec(
4786; CHECK-NEXT:    ret <2 x i1> poison
4787;
4788
4789  %b = or <2 x i8> %a, <i8 poison, i8 poison>
4790  %cmp = icmp sge <2 x i8> %b, <i8 0, i8 0>
4791  ret <2 x i1> %cmp
4792}
4793
4794define i1 @or_positive_sge_postive(i8 %a) {
4795; CHECK-LABEL: @or_positive_sge_postive(
4796; CHECK-NEXT:    [[CMP:%.*]] = icmp sgt i8 [[A:%.*]], -1
4797; CHECK-NEXT:    ret i1 [[CMP]]
4798;
4799  %b = or i8 %a, 24
4800  %cmp = icmp sge i8 %b, 24
4801  ret i1 %cmp
4802}
4803
4804define <2 x i1> @or_postive_sge_positive_vec(<2 x i8> %a) {
4805; CHECK-LABEL: @or_postive_sge_positive_vec(
4806; CHECK-NEXT:    [[CMP:%.*]] = icmp sgt <2 x i8> [[A:%.*]], splat (i8 -1)
4807; CHECK-NEXT:    ret <2 x i1> [[CMP]]
4808;
4809
4810  %b = or <2 x i8> %a, <i8 24, i8 24>
4811  %cmp = icmp sge <2 x i8> %b, <i8 24, i8 24>
4812  ret <2 x i1> %cmp
4813}
4814
4815define <2 x i1> @or_poison_vec_sge_positive_vec(<2 x i8> %a) {
4816; CHECK-LABEL: @or_poison_vec_sge_positive_vec(
4817; CHECK-NEXT:    ret <2 x i1> poison
4818;
4819
4820  %b = or <2 x i8> %a, <i8 poison, i8 poison>
4821  %cmp = icmp sge <2 x i8> %b, <i8 24, i8 24>
4822  ret <2 x i1> %cmp
4823}
4824
4825define i1 @or_positive_sle_zero(i8 %a) {
4826; CHECK-LABEL: @or_positive_sle_zero(
4827; CHECK-NEXT:    [[CMP:%.*]] = icmp slt i8 [[A:%.*]], 0
4828; CHECK-NEXT:    ret i1 [[CMP]]
4829;
4830  %b = or i8 %a, 24
4831  %cmp = icmp sle i8 %b, 0
4832  ret i1 %cmp
4833}
4834
4835define <2 x i1> @or_postive_sle_zero_vec(<2 x i8> %a) {
4836; CHECK-LABEL: @or_postive_sle_zero_vec(
4837; CHECK-NEXT:    [[CMP:%.*]] = icmp slt <2 x i8> [[A:%.*]], zeroinitializer
4838; CHECK-NEXT:    ret <2 x i1> [[CMP]]
4839;
4840
4841  %b = or <2 x i8> %a, <i8 24, i8 24>
4842  %cmp = icmp sle <2 x i8> %b, <i8 0, i8 0>
4843  ret <2 x i1> %cmp
4844}
4845
4846define <2 x i1> @or_poison_vec_sle_zero_vec(<2 x i8> %a) {
4847; CHECK-LABEL: @or_poison_vec_sle_zero_vec(
4848; CHECK-NEXT:    ret <2 x i1> poison
4849;
4850
4851  %b = or <2 x i8> %a, <i8 poison, i8 poison>
4852  %cmp = icmp sle <2 x i8> %b, <i8 0, i8 0>
4853  ret <2 x i1> %cmp
4854}
4855
4856define i1 @or_positive_slt_zero(i8 %a) {
4857; CHECK-LABEL: @or_positive_slt_zero(
4858; CHECK-NEXT:    [[CMP:%.*]] = icmp slt i8 [[A:%.*]], 0
4859; CHECK-NEXT:    ret i1 [[CMP]]
4860;
4861  %b = or i8 %a, 24
4862  %cmp = icmp slt i8 %b, 0
4863  ret i1 %cmp
4864}
4865
4866define <2 x i1> @or_postive_slt_zero_vec(<2 x i8> %a) {
4867; CHECK-LABEL: @or_postive_slt_zero_vec(
4868; CHECK-NEXT:    [[CMP:%.*]] = icmp slt <2 x i8> [[A:%.*]], zeroinitializer
4869; CHECK-NEXT:    ret <2 x i1> [[CMP]]
4870;
4871
4872  %b = or <2 x i8> %a, <i8 24, i8 24>
4873  %cmp = icmp slt <2 x i8> %b, <i8 0, i8 0>
4874  ret <2 x i1> %cmp
4875}
4876
4877define <2 x i1> @or_poison_vec_slt_zero_vec(<2 x i8> %a) {
4878; CHECK-LABEL: @or_poison_vec_slt_zero_vec(
4879; CHECK-NEXT:    ret <2 x i1> poison
4880;
4881
4882  %b = or <2 x i8> %a, <i8 poison, i8 poison>
4883  %cmp = icmp slt <2 x i8> %b, <i8 0, i8 0>
4884  ret <2 x i1> %cmp
4885}
4886
4887define i1 @or_positive_slt_postive(i8 %a) {
4888; CHECK-LABEL: @or_positive_slt_postive(
4889; CHECK-NEXT:    [[CMP:%.*]] = icmp slt i8 [[A:%.*]], 0
4890; CHECK-NEXT:    ret i1 [[CMP]]
4891;
4892  %b = or i8 %a, 24
4893  %cmp = icmp slt i8 %b, 24
4894  ret i1 %cmp
4895}
4896
4897define <2 x i1> @or_postive_slt_positive_vec(<2 x i8> %a) {
4898; CHECK-LABEL: @or_postive_slt_positive_vec(
4899; CHECK-NEXT:    [[CMP:%.*]] = icmp slt <2 x i8> [[A:%.*]], zeroinitializer
4900; CHECK-NEXT:    ret <2 x i1> [[CMP]]
4901;
4902
4903  %b = or <2 x i8> %a, <i8 24, i8 24>
4904  %cmp = icmp slt <2 x i8> %b, <i8 24, i8 24>
4905  ret <2 x i1> %cmp
4906}
4907
4908define <2 x i1> @or_poison_vec_slt_positive_vec(<2 x i8> %a) {
4909; CHECK-LABEL: @or_poison_vec_slt_positive_vec(
4910; CHECK-NEXT:    ret <2 x i1> poison
4911;
4912
4913  %b = or <2 x i8> %a, <i8 poison, i8 poison>
4914  %cmp = icmp slt <2 x i8> %b, <i8 24, i8 24>
4915  ret <2 x i1> %cmp
4916}
4917
4918; negative tests for icmp(X | OrC, C) --> icmp(X, 0)
4919
4920define i1 @or_positive_sgt_neg(i8 %a) {
4921; CHECK-LABEL: @or_positive_sgt_neg(
4922; CHECK-NEXT:    [[CMP:%.*]] = icmp sgt i8 [[A:%.*]], -1
4923; CHECK-NEXT:    ret i1 [[CMP]]
4924;
4925  %b = or i8 %a, 24
4926  %cmp = icmp sgt i8 %b, -1
4927  ret i1 %cmp
4928}
4929
4930define <2 x i1> @or_postive_sgt_neg_vec(<2 x i8> %a) {
4931; CHECK-LABEL: @or_postive_sgt_neg_vec(
4932; CHECK-NEXT:    [[CMP:%.*]] = icmp sgt <2 x i8> [[A:%.*]], splat (i8 -1)
4933; CHECK-NEXT:    ret <2 x i1> [[CMP]]
4934;
4935
4936  %b = or <2 x i8> %a, <i8 24, i8 24>
4937  %cmp = icmp sgt <2 x i8> %b, <i8 -1, i8 -1>
4938  ret <2 x i1> %cmp
4939}
4940
4941define i1 @mul_or_positive_sge_neg(i8 %a) {
4942; CHECK-LABEL: @mul_or_positive_sge_neg(
4943; CHECK-NEXT:    [[B:%.*]] = or i8 [[A:%.*]], 24
4944; CHECK-NEXT:    [[CMP:%.*]] = icmp sgt i8 [[B]], -2
4945; CHECK-NEXT:    ret i1 [[CMP]]
4946;
4947  %b = or i8 %a, 24
4948  %cmp = icmp sge i8 %b, -1
4949  ret i1 %cmp
4950}
4951
4952define <2 x i1> @or_postive_sge_neg_vec(<2 x i8> %a) {
4953; CHECK-LABEL: @or_postive_sge_neg_vec(
4954; CHECK-NEXT:    [[B:%.*]] = or <2 x i8> [[A:%.*]], splat (i8 24)
4955; CHECK-NEXT:    [[CMP:%.*]] = icmp sgt <2 x i8> [[B]], splat (i8 -2)
4956; CHECK-NEXT:    ret <2 x i1> [[CMP]]
4957;
4958
4959  %b = or <2 x i8> %a, <i8 24, i8 24>
4960  %cmp = icmp sge <2 x i8> %b, <i8 -1, i8 -1>
4961  ret <2 x i1> %cmp
4962}
4963
4964define i1 @mul_or_small_sge_large(i8 %a) {
4965; CHECK-LABEL: @mul_or_small_sge_large(
4966; CHECK-NEXT:    [[B:%.*]] = or i8 [[A:%.*]], 24
4967; CHECK-NEXT:    [[CMP:%.*]] = icmp sgt i8 [[B]], 24
4968; CHECK-NEXT:    ret i1 [[CMP]]
4969;
4970  %b = or i8 %a, 24
4971  %cmp = icmp sge i8 %b, 25
4972  ret i1 %cmp
4973}
4974
4975define <2 x i1> @or_small_sge_large_vec(<2 x i8> %a) {
4976; CHECK-LABEL: @or_small_sge_large_vec(
4977; CHECK-NEXT:    [[B:%.*]] = or <2 x i8> [[A:%.*]], splat (i8 24)
4978; CHECK-NEXT:    [[CMP:%.*]] = icmp sgt <2 x i8> [[B]], splat (i8 24)
4979; CHECK-NEXT:    ret <2 x i1> [[CMP]]
4980;
4981
4982  %b = or <2 x i8> %a, <i8 24, i8 24>
4983  %cmp = icmp sge <2 x i8> %b, <i8 25, i8 25>
4984  ret <2 x i1> %cmp
4985}
4986
4987define i1 @or_positive_sle_neg(i8 %a) {
4988; CHECK-LABEL: @or_positive_sle_neg(
4989; CHECK-NEXT:    [[CMP:%.*]] = icmp slt i8 [[A:%.*]], 0
4990; CHECK-NEXT:    ret i1 [[CMP]]
4991;
4992  %b = or i8 %a, 24
4993  %cmp = icmp sle i8 %b, -1
4994  ret i1 %cmp
4995}
4996
4997define <2 x i1> @or_sle_neg_vec(<2 x i8> %a) {
4998; CHECK-LABEL: @or_sle_neg_vec(
4999; CHECK-NEXT:    [[CMP:%.*]] = icmp slt <2 x i8> [[A:%.*]], zeroinitializer
5000; CHECK-NEXT:    ret <2 x i1> [[CMP]]
5001;
5002
5003  %b = or <2 x i8> %a, <i8 24, i8 24>
5004  %cmp = icmp sle <2 x i8> %b, <i8 -1, i8 -1>
5005  ret <2 x i1> %cmp
5006}
5007
5008define i1 @or_positive_slt_neg(i8 %a) {
5009; CHECK-LABEL: @or_positive_slt_neg(
5010; CHECK-NEXT:    [[B:%.*]] = or i8 [[A:%.*]], 24
5011; CHECK-NEXT:    [[CMP:%.*]] = icmp slt i8 [[B]], -1
5012; CHECK-NEXT:    ret i1 [[CMP]]
5013;
5014  %b = or i8 %a, 24
5015  %cmp = icmp slt i8 %b, -1
5016  ret i1 %cmp
5017}
5018
5019define <2 x i1> @or_postive_slt_neg_vec(<2 x i8> %a) {
5020; CHECK-LABEL: @or_postive_slt_neg_vec(
5021; CHECK-NEXT:    [[B:%.*]] = or <2 x i8> [[A:%.*]], splat (i8 24)
5022; CHECK-NEXT:    [[CMP:%.*]] = icmp slt <2 x i8> [[B]], splat (i8 -1)
5023; CHECK-NEXT:    ret <2 x i1> [[CMP]]
5024;
5025
5026  %b = or <2 x i8> %a, <i8 24, i8 24>
5027  %cmp = icmp slt <2 x i8> %b, <i8 -1, i8 -1>
5028  ret <2 x i1> %cmp
5029}
5030
5031define i1 @or_small_slt_large(i8 %a) {
5032; CHECK-LABEL: @or_small_slt_large(
5033; CHECK-NEXT:    [[B:%.*]] = or i8 [[A:%.*]], 24
5034; CHECK-NEXT:    [[CMP:%.*]] = icmp slt i8 [[B]], 25
5035; CHECK-NEXT:    ret i1 [[CMP]]
5036;
5037  %b = or i8 %a, 24
5038  %cmp = icmp slt i8 %b, 25
5039  ret i1 %cmp
5040}
5041
5042define <2 x i1> @or_small_slt_large_vec(<2 x i8> %a) {
5043; CHECK-LABEL: @or_small_slt_large_vec(
5044; CHECK-NEXT:    [[B:%.*]] = or <2 x i8> [[A:%.*]], splat (i8 24)
5045; CHECK-NEXT:    [[CMP:%.*]] = icmp slt <2 x i8> [[B]], splat (i8 25)
5046; CHECK-NEXT:    ret <2 x i1> [[CMP]]
5047;
5048
5049  %b = or <2 x i8> %a, <i8 24, i8 24>
5050  %cmp = icmp slt <2 x i8> %b, <i8 25, i8 25>
5051  ret <2 x i1> %cmp
5052}
5053
5054define i1 @or_positive_sgt_zero_multi_use(i8 %a) {
5055; CHECK-LABEL: @or_positive_sgt_zero_multi_use(
5056; CHECK-NEXT:    [[B:%.*]] = or i8 [[A:%.*]], 24
5057; CHECK-NEXT:    call void @use_i8(i8 [[B]])
5058; CHECK-NEXT:    [[CMP:%.*]] = icmp sgt i8 [[A]], -1
5059; CHECK-NEXT:    ret i1 [[CMP]]
5060;
5061  %b = or i8 %a, 24
5062  call void @use_i8(i8 %b)
5063  %cmp = icmp sgt i8 %b, 0
5064  ret i1 %cmp
5065}
5066
5067
5068define i1 @disjoint_or_sgt_1(i8 %a, i8 %b) {
5069; CHECK-LABEL: @disjoint_or_sgt_1(
5070; CHECK-NEXT:    [[B1:%.*]] = add nsw i8 [[B:%.*]], 2
5071; CHECK-NEXT:    [[ICMP_:%.*]] = icmp sge i8 [[A:%.*]], [[B1]]
5072; CHECK-NEXT:    ret i1 [[ICMP_]]
5073;
5074  %a1 = or disjoint i8 %a, 1
5075  %b1 = add nsw i8 %b, 2
5076  %icmp_ = icmp sgt i8 %a1, %b1
5077  ret i1 %icmp_
5078}
5079
5080define i1 @disjoint_or_sgt_2(i8 %a, i8 %b) {
5081; CHECK-LABEL: @disjoint_or_sgt_2(
5082; CHECK-NEXT:    [[A1:%.*]] = or disjoint i8 [[A:%.*]], 2
5083; CHECK-NEXT:    [[B1:%.*]] = add i8 [[B:%.*]], 1
5084; CHECK-NEXT:    [[ICMP_:%.*]] = icmp sgt i8 [[A1]], [[B1]]
5085; CHECK-NEXT:    ret i1 [[ICMP_]]
5086;
5087  %a1 = or disjoint i8 %a, 2
5088  %b1 = add i8 %b, 1
5089  %icmp_ = icmp sgt i8 %a1, %b1
5090  ret i1 %icmp_
5091}
5092
5093define i1 @disjoint_or_sgt_3(i8 %a, i8 %b) {
5094; CHECK-LABEL: @disjoint_or_sgt_3(
5095; CHECK-NEXT:    [[A1:%.*]] = or disjoint i8 [[A:%.*]], 2
5096; CHECK-NEXT:    [[B1:%.*]] = add nuw i8 [[B:%.*]], 1
5097; CHECK-NEXT:    [[ICMP_:%.*]] = icmp sgt i8 [[A1]], [[B1]]
5098; CHECK-NEXT:    ret i1 [[ICMP_]]
5099;
5100  %a1 = or disjoint i8 %a, 2
5101  %b1 = add nuw i8 %b, 1
5102  %icmp_ = icmp sgt i8 %a1, %b1
5103  ret i1 %icmp_
5104}
5105
5106define i1 @disjoint_or_ugt_1(i8 %a, i8 %b) {
5107; CHECK-LABEL: @disjoint_or_ugt_1(
5108; CHECK-NEXT:    [[B1:%.*]] = add nsw i8 [[B:%.*]], 2
5109; CHECK-NEXT:    [[ICMP_:%.*]] = icmp uge i8 [[A:%.*]], [[B1]]
5110; CHECK-NEXT:    ret i1 [[ICMP_]]
5111;
5112  %a1 = or disjoint i8 %a, 1
5113  %b1 = add nsw i8 %b, 2
5114  %icmp_ = icmp ugt i8 %a1, %b1
5115  ret i1 %icmp_
5116}
5117
5118define i1 @disjoint_or_ugt_2(i8 %a, i8 %b) {
5119; CHECK-LABEL: @disjoint_or_ugt_2(
5120; CHECK-NEXT:    [[A1:%.*]] = or disjoint i8 [[A:%.*]], 2
5121; CHECK-NEXT:    [[B1:%.*]] = add i8 [[B:%.*]], 1
5122; CHECK-NEXT:    [[ICMP_:%.*]] = icmp ugt i8 [[A1]], [[B1]]
5123; CHECK-NEXT:    ret i1 [[ICMP_]]
5124;
5125  %a1 = or disjoint i8 %a, 2
5126  %b1 = add i8 %b, 1
5127  %icmp_ = icmp ugt i8 %a1, %b1
5128  ret i1 %icmp_
5129}
5130
5131define i1 @disjoint_or_ugt_3(i8 %a, i8 %b) {
5132; CHECK-LABEL: @disjoint_or_ugt_3(
5133; CHECK-NEXT:    [[A1:%.*]] = or disjoint i8 [[A:%.*]], 2
5134; CHECK-NEXT:    [[B1:%.*]] = add nuw i8 [[B:%.*]], 1
5135; CHECK-NEXT:    [[ICMP_:%.*]] = icmp ugt i8 [[A1]], [[B1]]
5136; CHECK-NEXT:    ret i1 [[ICMP_]]
5137;
5138  %a1 = or disjoint i8 %a, 2
5139  %b1 = add nuw i8 %b, 1
5140  %icmp_ = icmp ugt i8 %a1, %b1
5141  ret i1 %icmp_
5142}
5143
5144define i1 @deduce_nuw_flag_1(i8 %a, i8 %b) {
5145; CHECK-LABEL: @deduce_nuw_flag_1(
5146; CHECK-NEXT:  entry:
5147; CHECK-NEXT:    [[TMP0:%.*]] = add nuw i8 [[B:%.*]], 1
5148; CHECK-NEXT:    [[CMP:%.*]] = icmp eq i8 [[TMP0]], [[A:%.*]]
5149; CHECK-NEXT:    ret i1 [[CMP]]
5150;
5151entry:
5152  %add1 = add nuw i8 %b, 2
5153  %add2 = add i8 %a, 1
5154  %cmp = icmp eq i8 %add1, %add2
5155  ret i1 %cmp
5156}
5157
5158define i1 @deduce_nuw_flag_2(i8 %a, i8 %b) {
5159; CHECK-LABEL: @deduce_nuw_flag_2(
5160; CHECK-NEXT:  entry:
5161; CHECK-NEXT:    [[TMP0:%.*]] = add nuw i8 [[B:%.*]], 1
5162; CHECK-NEXT:    [[CMP:%.*]] = icmp eq i8 [[A:%.*]], [[TMP0]]
5163; CHECK-NEXT:    ret i1 [[CMP]]
5164;
5165entry:
5166  %add1 = add nuw i8 %b, 2
5167  %add2 = add i8 %a, 1
5168  %cmp = icmp eq i8 %add2, %add1
5169  ret i1 %cmp
5170}
5171
5172define i1 @dont_deduce_nuw_flag_1(i8 %a, i8 %b) {
5173; CHECK-LABEL: @dont_deduce_nuw_flag_1(
5174; CHECK-NEXT:  entry:
5175; CHECK-NEXT:    [[TMP0:%.*]] = add i8 [[B:%.*]], -1
5176; CHECK-NEXT:    [[CMP:%.*]] = icmp eq i8 [[TMP0]], [[A:%.*]]
5177; CHECK-NEXT:    ret i1 [[CMP]]
5178;
5179entry:
5180  %add1 = add nuw i8 %b, -2
5181  %add2 = add i8 %a, -1
5182  %cmp = icmp eq i8 %add1, %add2
5183  ret i1 %cmp
5184}
5185
5186define i1 @dont_deduce_nuw_flag_2(i8 %a, i8 %b) {
5187; CHECK-LABEL: @dont_deduce_nuw_flag_2(
5188; CHECK-NEXT:  entry:
5189; CHECK-NEXT:    [[TMP0:%.*]] = add i8 [[B:%.*]], -1
5190; CHECK-NEXT:    [[CMP:%.*]] = icmp eq i8 [[A:%.*]], [[TMP0]]
5191; CHECK-NEXT:    ret i1 [[CMP]]
5192;
5193entry:
5194  %add1 = add nuw i8 %b, -2
5195  %add2 = add i8 %a, -1
5196  %cmp = icmp eq i8 %add2, %add1
5197  ret i1 %cmp
5198}
5199
5200define i1 @icmp_freeze_sext(i16 %x, i16 %y) {
5201; CHECK-LABEL: @icmp_freeze_sext(
5202; CHECK-NEXT:    [[CMP1:%.*]] = icmp uge i16 [[X:%.*]], [[Y:%.*]]
5203; CHECK-NEXT:    [[CMP1_FR:%.*]] = freeze i1 [[CMP1]]
5204; CHECK-NEXT:    [[TMP1:%.*]] = icmp eq i16 [[Y]], 0
5205; CHECK-NEXT:    [[CMP2:%.*]] = or i1 [[TMP1]], [[CMP1_FR]]
5206; CHECK-NEXT:    ret i1 [[CMP2]]
5207;
5208  %cmp1 = icmp uge i16 %x, %y
5209  %ext = sext i1 %cmp1 to i16
5210  %ext.fr = freeze i16 %ext
5211  %cmp2 = icmp uge i16 %ext.fr, %y
5212  ret i1 %cmp2
5213}
5214
5215define i1 @test_icmp_shl(i64 %x) {
5216; CHECK-LABEL: @test_icmp_shl(
5217; CHECK-NEXT:    [[TMP1:%.*]] = trunc i64 [[X:%.*]] to i32
5218; CHECK-NEXT:    [[CMP:%.*]] = icmp ult i32 [[TMP1]], 3
5219; CHECK-NEXT:    ret i1 [[CMP]]
5220;
5221  %shl = shl i64 %x, 32
5222  %cmp = icmp ult i64 %shl, 8589934593
5223  ret i1 %cmp
5224}
5225
5226define i1 @test_icmp_shl_multiuse(i64 %x) {
5227; CHECK-LABEL: @test_icmp_shl_multiuse(
5228; CHECK-NEXT:    [[SHL:%.*]] = shl i64 [[X:%.*]], 32
5229; CHECK-NEXT:    call void @use_i64(i64 [[SHL]])
5230; CHECK-NEXT:    [[CMP:%.*]] = icmp ult i64 [[SHL]], 8589934593
5231; CHECK-NEXT:    ret i1 [[CMP]]
5232;
5233  %shl = shl i64 %x, 32
5234  call void @use_i64(i64 %shl)
5235  %cmp = icmp ult i64 %shl, 8589934593
5236  ret i1 %cmp
5237}
5238
5239define i1 @test_icmp_shl_illegal_length(i64 %x) {
5240; CHECK-LABEL: @test_icmp_shl_illegal_length(
5241; CHECK-NEXT:    [[SHL:%.*]] = shl i64 [[X:%.*]], 31
5242; CHECK-NEXT:    [[CMP:%.*]] = icmp ult i64 [[SHL]], 8589934593
5243; CHECK-NEXT:    ret i1 [[CMP]]
5244;
5245  %shl = shl i64 %x, 31
5246  %cmp = icmp ult i64 %shl, 8589934593
5247  ret i1 %cmp
5248}
5249
5250define i1 @test_icmp_shl_invalid_rhsc(i64 %x) {
5251; CHECK-LABEL: @test_icmp_shl_invalid_rhsc(
5252; CHECK-NEXT:    [[SHL:%.*]] = shl i64 [[X:%.*]], 32
5253; CHECK-NEXT:    [[CMP:%.*]] = icmp ult i64 [[SHL]], 8589934595
5254; CHECK-NEXT:    ret i1 [[CMP]]
5255;
5256  %shl = shl i64 %x, 32
5257  %cmp = icmp ult i64 %shl, 8589934595
5258  ret i1 %cmp
5259}
5260
5261define i1 @test_icmp_shl_nuw(i64 %x) {
5262; CHECK-LABEL: @test_icmp_shl_nuw(
5263; CHECK-NEXT:    [[CMP:%.*]] = icmp ult i64 [[X:%.*]], 3
5264; CHECK-NEXT:    ret i1 [[CMP]]
5265;
5266  %shl = shl nuw i64 %x, 32
5267  %cmp = icmp ult i64 %shl, 8589934593
5268  ret i1 %cmp
5269}
5270
5271define i1 @test_icmp_shl_nuw_i31(i31 %x) {
5272; CHECK-LABEL: @test_icmp_shl_nuw_i31(
5273; CHECK-NEXT:    [[CMP:%.*]] = icmp ugt i31 [[X:%.*]], 250
5274; CHECK-NEXT:    ret i1 [[CMP]]
5275;
5276  %shl = shl nuw i31 %x, 23
5277  %cmp = icmp ugt i31 %shl, -50331648
5278  ret i1 %cmp
5279}
5280
5281define i1 @test_icmp_shl_nsw(i64 %x) {
5282; CHECK-LABEL: @test_icmp_shl_nsw(
5283; CHECK-NEXT:    [[CMP:%.*]] = icmp ult i64 [[X:%.*]], 3
5284; CHECK-NEXT:    ret i1 [[CMP]]
5285;
5286  %shl = shl nsw i64 %x, 32
5287  %cmp = icmp ult i64 %shl, 8589934593
5288  ret i1 %cmp
5289}
5290
5291define i1 @test_icmp_shl_nsw_i31(i31 %x) {
5292; CHECK-LABEL: @test_icmp_shl_nsw_i31(
5293; CHECK-NEXT:    [[TMP1:%.*]] = trunc nsw i31 [[X:%.*]] to i8
5294; CHECK-NEXT:    [[CMP:%.*]] = icmp ugt i8 [[TMP1]], -6
5295; CHECK-NEXT:    ret i1 [[CMP]]
5296;
5297  %shl = shl nsw i31 %x, 23
5298  %cmp = icmp ugt i31 %shl, -50331648
5299  ret i1 %cmp
5300}
5301
5302define <2 x i1> @test_icmp_shl_vec(<2 x i64> %x) {
5303; CHECK-LABEL: @test_icmp_shl_vec(
5304; CHECK-NEXT:    [[TMP1:%.*]] = trunc <2 x i64> [[X:%.*]] to <2 x i32>
5305; CHECK-NEXT:    [[CMP:%.*]] = icmp ult <2 x i32> [[TMP1]], splat (i32 3)
5306; CHECK-NEXT:    ret <2 x i1> [[CMP]]
5307;
5308  %shl = shl <2 x i64> %x, splat(i64 32)
5309  %cmp = icmp ult <2 x i64> %shl, splat(i64 8589934593)
5310  ret <2 x i1> %cmp
5311}
5312
5313define i1 @test_icmp_shl_eq(i64 %x) {
5314; CHECK-LABEL: @test_icmp_shl_eq(
5315; CHECK-NEXT:    ret i1 false
5316;
5317  %shl = shl i64 %x, 32
5318  %cmp = icmp eq i64 %shl, 8589934593
5319  ret i1 %cmp
5320}
5321
5322define i1 @test_icmp_shl_sgt(i64 %x) {
5323; CHECK-LABEL: @test_icmp_shl_sgt(
5324; CHECK-NEXT:    [[TMP1:%.*]] = trunc i64 [[X:%.*]] to i32
5325; CHECK-NEXT:    [[CMP:%.*]] = icmp sgt i32 [[TMP1]], 1
5326; CHECK-NEXT:    ret i1 [[CMP]]
5327;
5328  %shl = shl i64 %x, 32
5329  %cmp = icmp sgt i64 %shl, 8589934591
5330  ret i1 %cmp
5331}
5332
5333define i1 @pr94897(i32 range(i32 -2147483648, 0) %x) {
5334; CHECK-LABEL: @pr94897(
5335; CHECK-NEXT:    [[CMP:%.*]] = icmp samesign ugt i32 [[X:%.*]], -3
5336; CHECK-NEXT:    ret i1 [[CMP]]
5337;
5338  %shl = shl nsw i32 %x, 24
5339  %cmp = icmp ugt i32 %shl, -50331648
5340  ret i1 %cmp
5341}
5342
5343define i1 @icmp_and_inv_pow2_ne_0(i32 %A, i32 %B) {
5344; CHECK-LABEL: @icmp_and_inv_pow2_ne_0(
5345; CHECK-NEXT:    [[POPCNT:%.*]] = tail call range(i32 0, 33) i32 @llvm.ctpop.i32(i32 [[A:%.*]])
5346; CHECK-NEXT:    [[COND:%.*]] = icmp eq i32 [[POPCNT]], 1
5347; CHECK-NEXT:    call void @llvm.assume(i1 [[COND]])
5348; CHECK-NEXT:    [[TMP1:%.*]] = and i32 [[A]], [[B:%.*]]
5349; CHECK-NEXT:    [[CMP:%.*]] = icmp eq i32 [[TMP1]], 0
5350; CHECK-NEXT:    ret i1 [[CMP]]
5351;
5352  %popcnt = tail call i32 @llvm.ctpop.i32(i32 %A)
5353  %cond = icmp eq i32 %popcnt, 1
5354  call void @llvm.assume(i1 %cond)
5355
5356  %inv = xor i32 %B, -1
5357  %and = and i32 %A, %inv
5358  %cmp = icmp ne i32 %and, 0
5359  ret i1 %cmp
5360}
5361
5362define i1 @icmp_and_inv_pow2_or_zero_ne_0(i32 %A, i32 %B) {
5363; CHECK-LABEL: @icmp_and_inv_pow2_or_zero_ne_0(
5364; CHECK-NEXT:    [[POPCNT:%.*]] = tail call range(i32 0, 33) i32 @llvm.ctpop.i32(i32 [[A:%.*]])
5365; CHECK-NEXT:    [[COND:%.*]] = icmp samesign ult i32 [[POPCNT]], 2
5366; CHECK-NEXT:    call void @llvm.assume(i1 [[COND]])
5367; CHECK-NEXT:    [[INV:%.*]] = xor i32 [[B:%.*]], -1
5368; CHECK-NEXT:    [[AND:%.*]] = and i32 [[A]], [[INV]]
5369; CHECK-NEXT:    [[CMP:%.*]] = icmp ne i32 [[AND]], 0
5370; CHECK-NEXT:    ret i1 [[CMP]]
5371;
5372  %popcnt = tail call i32 @llvm.ctpop.i32(i32 %A)
5373  %cond = icmp ult i32 %popcnt, 2
5374  call void @llvm.assume(i1 %cond)
5375
5376  %inv = xor i32 %B, -1
5377  %and = and i32 %A, %inv
5378  %cmp = icmp ne i32 %and, 0
5379  ret i1 %cmp
5380}
5381
5382define i1 @icmp_samesign_logical_and(i32 %In) {
5383; CHECK-LABEL: @icmp_samesign_logical_and(
5384; CHECK-NEXT:    [[C2:%.*]] = icmp eq i32 [[IN:%.*]], 1
5385; CHECK-NEXT:    ret i1 [[C2]]
5386;
5387  %c1 = icmp samesign sgt i32 %In, -1
5388  %c2 = icmp samesign eq i32 %In, 1
5389  %V = select i1 %c1, i1 %c2, i1 false
5390  ret i1 %V
5391}
5392
5393define i1 @icmp_samesign_logical_or(i32 %In) {
5394; CHECK-LABEL: @icmp_samesign_logical_or(
5395; CHECK-NEXT:    [[V:%.*]] = icmp ne i32 [[IN:%.*]], 1
5396; CHECK-NEXT:    ret i1 [[V]]
5397;
5398  %c1 = icmp samesign slt i32 %In, 0
5399  %c2 = icmp samesign ne i32 %In, 1
5400  %V = select i1 %c1, i1 true, i1 %c2
5401  ret i1 %V
5402}
5403