1; NOTE: Assertions have been autogenerated by utils/update_test_checks.py
2; RUN: opt < %s -instsimplify -S | FileCheck %s
3
4; Fold icmp with a constant operand.
5
6define i1 @tautological_ule(i8 %x) {
7; CHECK-LABEL: @tautological_ule(
8; CHECK-NEXT:    ret i1 true
9;
10  %cmp = icmp ule i8 %x, 255
11  ret i1 %cmp
12}
13
14define <2 x i1> @tautological_ule_vec(<2 x i8> %x) {
15; CHECK-LABEL: @tautological_ule_vec(
16; CHECK-NEXT:    ret <2 x i1> <i1 true, i1 true>
17;
18  %cmp = icmp ule <2 x i8> %x, <i8 255, i8 255>
19  ret <2 x i1> %cmp
20}
21
22define <2 x i1> @tautological_ule_vec_partial_undef(<2 x i8> %x) {
23; CHECK-LABEL: @tautological_ule_vec_partial_undef(
24; CHECK-NEXT:    ret <2 x i1> <i1 true, i1 true>
25;
26  %cmp = icmp ule <2 x i8> %x, <i8 255, i8 undef>
27  ret <2 x i1> %cmp
28}
29
30define i1 @tautological_ugt(i8 %x) {
31; CHECK-LABEL: @tautological_ugt(
32; CHECK-NEXT:    ret i1 false
33;
34  %cmp = icmp ugt i8 %x, 255
35  ret i1 %cmp
36}
37
38define <2 x i1> @tautological_ugt_vec(<2 x i8> %x) {
39; CHECK-LABEL: @tautological_ugt_vec(
40; CHECK-NEXT:    ret <2 x i1> zeroinitializer
41;
42  %cmp = icmp ugt <2 x i8> %x, <i8 255, i8 255>
43  ret <2 x i1> %cmp
44}
45
46define <2 x i1> @tautological_ugt_vec_partial_undef(<2 x i8> %x) {
47; CHECK-LABEL: @tautological_ugt_vec_partial_undef(
48; CHECK-NEXT:    ret <2 x i1> zeroinitializer
49;
50  %cmp = icmp ugt <2 x i8> %x, <i8 undef, i8 255>
51  ret <2 x i1> %cmp
52}
53
54; 'urem x, C2' produces [0, C2)
55define i1 @urem3(i32 %X) {
56; CHECK-LABEL: @urem3(
57; CHECK-NEXT:    ret i1 true
58;
59  %A = urem i32 %X, 10
60  %B = icmp ult i32 %A, 15
61  ret i1 %B
62}
63
64define <2 x i1> @urem3_vec(<2 x i32> %X) {
65; CHECK-LABEL: @urem3_vec(
66; CHECK-NEXT:    ret <2 x i1> <i1 true, i1 true>
67;
68  %A = urem <2 x i32> %X, <i32 10, i32 10>
69  %B = icmp ult <2 x i32> %A, <i32 15, i32 15>
70  ret <2 x i1> %B
71}
72
73define <2 x i1> @urem3_vec_partial_undef(<2 x i32> %X) {
74; CHECK-LABEL: @urem3_vec_partial_undef(
75; CHECK-NEXT:    ret <2 x i1> <i1 true, i1 true>
76;
77  %A = urem <2 x i32> %X, <i32 10, i32 10>
78  %B = icmp ult <2 x i32> %A, <i32 undef, i32 15>
79  ret <2 x i1> %B
80}
81
82;'srem x, C2' produces (-|C2|, |C2|)
83define i1 @srem1(i32 %X) {
84; CHECK-LABEL: @srem1(
85; CHECK-NEXT:    ret i1 false
86;
87  %A = srem i32 %X, -5
88  %B = icmp sgt i32 %A, 5
89  ret i1 %B
90}
91
92define <2 x i1> @srem1_vec(<2 x i32> %X) {
93; CHECK-LABEL: @srem1_vec(
94; CHECK-NEXT:    ret <2 x i1> zeroinitializer
95;
96  %A = srem <2 x i32> %X, <i32 -5, i32 -5>
97  %B = icmp sgt <2 x i32> %A, <i32 5, i32 5>
98  ret <2 x i1> %B
99}
100
101define <2 x i1> @srem1_vec_partial_undef(<2 x i32> %X) {
102; CHECK-LABEL: @srem1_vec_partial_undef(
103; CHECK-NEXT:    ret <2 x i1> zeroinitializer
104;
105  %A = srem <2 x i32> %X, <i32 -5, i32 -5>
106  %B = icmp sgt <2 x i32> %A, <i32 5, i32 undef>
107  ret <2 x i1> %B
108}
109
110;'udiv C2, x' produces [0, C2]
111define i1 @udiv5(i32 %X) {
112; CHECK-LABEL: @udiv5(
113; CHECK-NEXT:    ret i1 false
114;
115  %A = udiv i32 123, %X
116  %C = icmp ugt i32 %A, 124
117  ret i1 %C
118}
119
120define <2 x i1> @udiv5_vec(<2 x i32> %X) {
121; CHECK-LABEL: @udiv5_vec(
122; CHECK-NEXT:    ret <2 x i1> zeroinitializer
123;
124  %A = udiv <2 x i32> <i32 123, i32 123>, %X
125  %C = icmp ugt <2 x i32> %A, <i32 124, i32 124>
126  ret <2 x i1> %C
127}
128
129; 'udiv x, C2' produces [0, UINT_MAX / C2]
130define i1 @udiv1(i32 %X) {
131; CHECK-LABEL: @udiv1(
132; CHECK-NEXT:    ret i1 true
133;
134  %A = udiv i32 %X, 1000000
135  %B = icmp ult i32 %A, 5000
136  ret i1 %B
137}
138
139define <2 x i1> @udiv1_vec(<2 x i32> %X) {
140; CHECK-LABEL: @udiv1_vec(
141; CHECK-NEXT:    ret <2 x i1> <i1 true, i1 true>
142;
143  %A = udiv <2 x i32> %X, <i32 1000000, i32 1000000>
144  %B = icmp ult <2 x i32> %A, <i32 5000, i32 5000>
145  ret <2 x i1> %B
146}
147
148; 'sdiv C2, x' produces [-|C2|, |C2|]
149define i1 @compare_dividend(i32 %a) {
150; CHECK-LABEL: @compare_dividend(
151; CHECK-NEXT:    ret i1 false
152;
153  %div = sdiv i32 2, %a
154  %cmp = icmp eq i32 %div, 3
155  ret i1 %cmp
156}
157
158define <2 x i1> @compare_dividend_vec(<2 x i32> %a) {
159; CHECK-LABEL: @compare_dividend_vec(
160; CHECK-NEXT:    ret <2 x i1> zeroinitializer
161;
162  %div = sdiv <2 x i32> <i32 2, i32 2>, %a
163  %cmp = icmp eq <2 x i32> %div, <i32 3, i32 3>
164  ret <2 x i1> %cmp
165}
166
167; 'sdiv x, C2' produces [INT_MIN / C2, INT_MAX / C2]
168;    where C2 != -1 and C2 != 0 and C2 != 1
169define i1 @sdiv1(i32 %X) {
170; CHECK-LABEL: @sdiv1(
171; CHECK-NEXT:    ret i1 true
172;
173  %A = sdiv i32 %X, 1000000
174  %B = icmp slt i32 %A, 3000
175  ret i1 %B
176}
177
178define <2 x i1> @sdiv1_vec(<2 x i32> %X) {
179; CHECK-LABEL: @sdiv1_vec(
180; CHECK-NEXT:    ret <2 x i1> <i1 true, i1 true>
181;
182  %A = sdiv <2 x i32> %X, <i32 1000000, i32 1000000>
183  %B = icmp slt <2 x i32> %A, <i32 3000, i32 3000>
184  ret <2 x i1> %B
185}
186
187; 'shl nuw C2, x' produces [C2, C2 << CLZ(C2)]
188define i1 @shl5(i32 %X) {
189; CHECK-LABEL: @shl5(
190; CHECK-NEXT:    ret i1 true
191;
192  %sub = shl nuw i32 4, %X
193  %cmp = icmp ugt i32 %sub, 3
194  ret i1 %cmp
195}
196
197define <2 x i1> @shl5_vec(<2 x i32> %X) {
198; CHECK-LABEL: @shl5_vec(
199; CHECK-NEXT:    ret <2 x i1> <i1 true, i1 true>
200;
201  %sub = shl nuw <2 x i32> <i32 4, i32 4>, %X
202  %cmp = icmp ugt <2 x i32> %sub, <i32 3, i32 3>
203  ret <2 x i1> %cmp
204}
205
206define <2 x i1> @shl5_vec_partial_undef(<2 x i32> %X) {
207; CHECK-LABEL: @shl5_vec_partial_undef(
208; CHECK-NEXT:    ret <2 x i1> <i1 true, i1 true>
209;
210  %sub = shl nuw <2 x i32> <i32 4, i32 4>, %X
211  %cmp = icmp ugt <2 x i32> %sub, <i32 undef, i32 3>
212  ret <2 x i1> %cmp
213}
214
215; 'shl nsw C2, x' produces [C2 << CLO(C2)-1, C2]
216define i1 @shl2(i32 %X) {
217; CHECK-LABEL: @shl2(
218; CHECK-NEXT:    ret i1 false
219;
220  %sub = shl nsw i32 -1, %X
221  %cmp = icmp eq i32 %sub, 31
222  ret i1 %cmp
223}
224
225define <2 x i1> @shl2_vec(<2 x i32> %X) {
226; CHECK-LABEL: @shl2_vec(
227; CHECK-NEXT:    ret <2 x i1> zeroinitializer
228;
229  %sub = shl nsw <2 x i32> <i32 -1, i32 -1>, %X
230  %cmp = icmp eq <2 x i32> %sub, <i32 31, i32 31>
231  ret <2 x i1> %cmp
232}
233
234; 'shl nsw C2, x' produces [C2 << CLO(C2)-1, C2]
235define i1 @shl4(i32 %X) {
236; CHECK-LABEL: @shl4(
237; CHECK-NEXT:    ret i1 true
238;
239  %sub = shl nsw i32 -1, %X
240  %cmp = icmp sle i32 %sub, -1
241  ret i1 %cmp
242}
243
244define <2 x i1> @shl4_vec(<2 x i32> %X) {
245; CHECK-LABEL: @shl4_vec(
246; CHECK-NEXT:    ret <2 x i1> <i1 true, i1 true>
247;
248  %sub = shl nsw <2 x i32> <i32 -1, i32 -1>, %X
249  %cmp = icmp sle <2 x i32> %sub, <i32 -1, i32 -1>
250  ret <2 x i1> %cmp
251}
252
253; 'shl nsw C2, x' produces [C2, C2 << CLZ(C2)-1]
254define i1 @icmp_shl_nsw_1(i64 %a) {
255; CHECK-LABEL: @icmp_shl_nsw_1(
256; CHECK-NEXT:    ret i1 true
257;
258  %shl = shl nsw i64 1, %a
259  %cmp = icmp sge i64 %shl, 0
260  ret i1 %cmp
261}
262
263define <2 x i1> @icmp_shl_nsw_1_vec(<2 x i64> %a) {
264; CHECK-LABEL: @icmp_shl_nsw_1_vec(
265; CHECK-NEXT:    ret <2 x i1> <i1 true, i1 true>
266;
267  %shl = shl nsw <2 x i64> <i64 1, i64 1>, %a
268  %cmp = icmp sge <2 x i64> %shl, zeroinitializer
269  ret <2 x i1> %cmp
270}
271
272; 'shl nsw C2, x' produces [C2 << CLO(C2)-1, C2]
273define i1 @icmp_shl_nsw_neg1(i64 %a) {
274; CHECK-LABEL: @icmp_shl_nsw_neg1(
275; CHECK-NEXT:    ret i1 false
276;
277  %shl = shl nsw i64 -1, %a
278  %cmp = icmp sge i64 %shl, 3
279  ret i1 %cmp
280}
281
282define <2 x i1> @icmp_shl_nsw_neg1_vec(<2 x i64> %a) {
283; CHECK-LABEL: @icmp_shl_nsw_neg1_vec(
284; CHECK-NEXT:    ret <2 x i1> zeroinitializer
285;
286  %shl = shl nsw <2 x i64> <i64 -1, i64 -1>, %a
287  %cmp = icmp sge <2 x i64> %shl, <i64 3, i64 3>
288  ret <2 x i1> %cmp
289}
290
291; 'lshr x, C2' produces [0, UINT_MAX >> C2]
292define i1 @lshr2(i32 %x) {
293; CHECK-LABEL: @lshr2(
294; CHECK-NEXT:    ret i1 false
295;
296  %s = lshr i32 %x, 30
297  %c = icmp ugt i32 %s, 8
298  ret i1 %c
299}
300
301define <2 x i1> @lshr2_vec(<2 x i32> %x) {
302; CHECK-LABEL: @lshr2_vec(
303; CHECK-NEXT:    ret <2 x i1> zeroinitializer
304;
305  %s = lshr <2 x i32> %x, <i32 30, i32 30>
306  %c = icmp ugt <2 x i32> %s, <i32 8, i32 8>
307  ret <2 x i1> %c
308}
309
310; 'lshr C2, x' produces [C2 >> (Width-1), C2]
311define i1 @exact_lshr_ugt_false(i32 %a) {
312; CHECK-LABEL: @exact_lshr_ugt_false(
313; CHECK-NEXT:    ret i1 false
314;
315  %shr = lshr exact i32 30, %a
316  %cmp = icmp ult i32 %shr, 15
317  ret i1 %cmp
318}
319
320define <2 x i1> @exact_lshr_ugt_false_vec(<2 x i32> %a) {
321; CHECK-LABEL: @exact_lshr_ugt_false_vec(
322; CHECK-NEXT:    ret <2 x i1> zeroinitializer
323;
324  %shr = lshr exact <2 x i32> <i32 30, i32 30>, %a
325  %cmp = icmp ult <2 x i32> %shr, <i32 15, i32 15>
326  ret <2 x i1> %cmp
327}
328
329; 'lshr C2, x' produces [C2 >> (Width-1), C2]
330define i1 @lshr_sgt_false(i32 %a) {
331; CHECK-LABEL: @lshr_sgt_false(
332; CHECK-NEXT:    ret i1 false
333;
334  %shr = lshr i32 1, %a
335  %cmp = icmp sgt i32 %shr, 1
336  ret i1 %cmp
337}
338
339define <2 x i1> @lshr_sgt_false_vec(<2 x i32> %a) {
340; CHECK-LABEL: @lshr_sgt_false_vec(
341; CHECK-NEXT:    ret <2 x i1> zeroinitializer
342;
343  %shr = lshr <2 x i32> <i32 1, i32 1>, %a
344  %cmp = icmp sgt <2 x i32> %shr, <i32 1, i32 1>
345  ret <2 x i1> %cmp
346}
347
348; 'ashr x, C2' produces [INT_MIN >> C2, INT_MAX >> C2]
349define i1 @ashr2(i32 %x) {
350; CHECK-LABEL: @ashr2(
351; CHECK-NEXT:    ret i1 false
352;
353  %s = ashr i32 %x, 30
354  %c = icmp slt i32 %s, -5
355  ret i1 %c
356}
357
358define <2 x i1> @ashr2_vec(<2 x i32> %x) {
359; CHECK-LABEL: @ashr2_vec(
360; CHECK-NEXT:    ret <2 x i1> zeroinitializer
361;
362  %s = ashr <2 x i32> %x, <i32 30, i32 30>
363  %c = icmp slt <2 x i32> %s, <i32 -5, i32 -5>
364  ret <2 x i1> %c
365}
366
367; 'ashr C2, x' produces [C2, C2 >> (Width-1)]
368define i1 @ashr_sgt_false(i32 %a) {
369; CHECK-LABEL: @ashr_sgt_false(
370; CHECK-NEXT:    ret i1 false
371;
372  %shr = ashr i32 -30, %a
373  %cmp = icmp sgt i32 %shr, -1
374  ret i1 %cmp
375}
376
377define <2 x i1> @ashr_sgt_false_vec(<2 x i32> %a) {
378; CHECK-LABEL: @ashr_sgt_false_vec(
379; CHECK-NEXT:    ret <2 x i1> zeroinitializer
380;
381  %shr = ashr <2 x i32> <i32 -30, i32 -30>, %a
382  %cmp = icmp sgt <2 x i32> %shr, <i32 -1, i32 -1>
383  ret <2 x i1> %cmp
384}
385
386; 'ashr C2, x' produces [C2, C2 >> (Width-1)]
387define i1 @exact_ashr_sgt_false(i32 %a) {
388; CHECK-LABEL: @exact_ashr_sgt_false(
389; CHECK-NEXT:    ret i1 false
390;
391  %shr = ashr exact i32 -30, %a
392  %cmp = icmp sgt i32 %shr, -15
393  ret i1 %cmp
394}
395
396define <2 x i1> @exact_ashr_sgt_false_vec(<2 x i32> %a) {
397; CHECK-LABEL: @exact_ashr_sgt_false_vec(
398; CHECK-NEXT:    ret <2 x i1> zeroinitializer
399;
400  %shr = ashr exact <2 x i32> <i32 -30, i32 -30>, %a
401  %cmp = icmp sgt <2 x i32> %shr, <i32 -15, i32 -15>
402  ret <2 x i1> %cmp
403}
404
405; 'or x, C2' produces [C2, UINT_MAX]
406define i1 @or1(i32 %X) {
407; CHECK-LABEL: @or1(
408; CHECK-NEXT:    ret i1 false
409;
410  %A = or i32 %X, 62
411  %B = icmp ult i32 %A, 50
412  ret i1 %B
413}
414
415define <2 x i1> @or1_vec(<2 x i32> %X) {
416; CHECK-LABEL: @or1_vec(
417; CHECK-NEXT:    ret <2 x i1> zeroinitializer
418;
419  %A = or <2 x i32> %X, <i32 62, i32 62>
420  %B = icmp ult <2 x i32> %A, <i32 50, i32 50>
421  ret <2 x i1> %B
422}
423
424define <2 x i1> @or1_vec_partial_undef(<2 x i32> %X) {
425; CHECK-LABEL: @or1_vec_partial_undef(
426; CHECK-NEXT:    ret <2 x i1> zeroinitializer
427;
428  %A = or <2 x i32> %X, <i32 62, i32 62>
429  %B = icmp ult <2 x i32> %A, <i32 undef, i32 50>
430  ret <2 x i1> %B
431}
432
433; Single bit OR.
434define i1 @or2_true(i8 %x) {
435; CHECK-LABEL: @or2_true(
436; CHECK-NEXT:    [[Y:%.*]] = or i8 [[X:%.*]], 64
437; CHECK-NEXT:    [[Z:%.*]] = icmp sge i8 [[Y]], -64
438; CHECK-NEXT:    ret i1 [[Z]]
439;
440  %y = or i8 %x, 64
441  %z = icmp sge i8 %y, -64
442  ret i1 %z
443}
444
445define i1 @or2_unknown(i8 %x) {
446; CHECK-LABEL: @or2_unknown(
447; CHECK-NEXT:    [[Y:%.*]] = or i8 [[X:%.*]], 64
448; CHECK-NEXT:    [[Z:%.*]] = icmp sgt i8 [[Y]], -64
449; CHECK-NEXT:    ret i1 [[Z]]
450;
451  %y = or i8 %x, 64
452  %z = icmp sgt i8 %y, -64
453  ret i1 %z
454}
455
456; Multi bit OR.
457; 78 = 0b01001110; -50 = 0b11001110
458define i1 @or3_true(i8 %x) {
459; CHECK-LABEL: @or3_true(
460; CHECK-NEXT:    [[Y:%.*]] = or i8 [[X:%.*]], 78
461; CHECK-NEXT:    [[Z:%.*]] = icmp sge i8 [[Y]], -50
462; CHECK-NEXT:    ret i1 [[Z]]
463;
464  %y = or i8 %x, 78
465  %z = icmp sge i8 %y, -50
466  ret i1 %z
467}
468
469define i1 @or3_unknown(i8 %x) {
470; CHECK-LABEL: @or3_unknown(
471; CHECK-NEXT:    [[Y:%.*]] = or i8 [[X:%.*]], 78
472; CHECK-NEXT:    [[Z:%.*]] = icmp sgt i8 [[Y]], -50
473; CHECK-NEXT:    ret i1 [[Z]]
474;
475  %y = or i8 %x, 78
476  %z = icmp sgt i8 %y, -50
477  ret i1 %z
478}
479
480; OR with sign bit.
481define i1 @or4_true(i8 %x) {
482; CHECK-LABEL: @or4_true(
483; CHECK-NEXT:    ret i1 true
484;
485  %y = or i8 %x, -64
486  %z = icmp sge i8 %y, -64
487  ret i1 %z
488}
489
490define i1 @or4_unknown(i8 %x) {
491; CHECK-LABEL: @or4_unknown(
492; CHECK-NEXT:    [[Y:%.*]] = or i8 [[X:%.*]], -64
493; CHECK-NEXT:    [[Z:%.*]] = icmp sgt i8 [[Y]], -64
494; CHECK-NEXT:    ret i1 [[Z]]
495;
496  %y = or i8 %x, -64
497  %z = icmp sgt i8 %y, -64
498  ret i1 %z
499}
500
501; If sign bit is set, signed & unsigned ranges are the same.
502define i1 @or5_true(i8 %x) {
503; CHECK-LABEL: @or5_true(
504; CHECK-NEXT:    ret i1 true
505;
506  %y = or i8 %x, -64
507  %z = icmp uge i8 %y, -64
508  ret i1 %z
509}
510
511define i1 @or5_unknown(i8 %x) {
512; CHECK-LABEL: @or5_unknown(
513; CHECK-NEXT:    [[Y:%.*]] = or i8 [[X:%.*]], -64
514; CHECK-NEXT:    [[Z:%.*]] = icmp ugt i8 [[Y]], -64
515; CHECK-NEXT:    ret i1 [[Z]]
516;
517  %y = or i8 %x, -64
518  %z = icmp ugt i8 %y, -64
519  ret i1 %z
520}
521
522; 'and x, C2' produces [0, C2]
523define i1 @and1(i32 %X) {
524; CHECK-LABEL: @and1(
525; CHECK-NEXT:    ret i1 false
526;
527  %A = and i32 %X, 62
528  %B = icmp ugt i32 %A, 70
529  ret i1 %B
530}
531
532define <2 x i1> @and1_vec(<2 x i32> %X) {
533; CHECK-LABEL: @and1_vec(
534; CHECK-NEXT:    ret <2 x i1> zeroinitializer
535;
536  %A = and <2 x i32> %X, <i32 62, i32 62>
537  %B = icmp ugt <2 x i32> %A, <i32 70, i32 70>
538  ret <2 x i1> %B
539}
540
541; If the sign bit is not set, signed and unsigned ranges are the same.
542define i1 @and2(i32 %X) {
543; CHECK-LABEL: @and2(
544; CHECK-NEXT:    ret i1 false
545;
546  %A = and i32 %X, 62
547  %B = icmp sgt i32 %A, 70
548  ret i1 %B
549}
550
551; -75 = 0b10110101, 53 = 0b00110101
552define i1 @and3_true1(i8 %x) {
553; CHECK-LABEL: @and3_true1(
554; CHECK-NEXT:    [[Y:%.*]] = and i8 [[X:%.*]], -75
555; CHECK-NEXT:    [[Z:%.*]] = icmp sge i8 [[Y]], -75
556; CHECK-NEXT:    ret i1 [[Z]]
557;
558  %y = and i8 %x, -75
559  %z = icmp sge i8 %y, -75
560  ret i1 %z
561}
562
563define i1 @and3_unknown1(i8 %x) {
564; CHECK-LABEL: @and3_unknown1(
565; CHECK-NEXT:    [[Y:%.*]] = and i8 [[X:%.*]], -75
566; CHECK-NEXT:    [[Z:%.*]] = icmp sgt i8 [[Y]], -75
567; CHECK-NEXT:    ret i1 [[Z]]
568;
569  %y = and i8 %x, -75
570  %z = icmp sgt i8 %y, -75
571  ret i1 %z
572}
573
574define i1 @and3_true2(i8 %x) {
575; CHECK-LABEL: @and3_true2(
576; CHECK-NEXT:    [[Y:%.*]] = and i8 [[X:%.*]], -75
577; CHECK-NEXT:    [[Z:%.*]] = icmp sle i8 [[Y]], 53
578; CHECK-NEXT:    ret i1 [[Z]]
579;
580  %y = and i8 %x, -75
581  %z = icmp sle i8 %y, 53
582  ret i1 %z
583}
584
585define i1 @and3_unknown2(i8 %x) {
586; CHECK-LABEL: @and3_unknown2(
587; CHECK-NEXT:    [[Y:%.*]] = and i8 [[X:%.*]], -75
588; CHECK-NEXT:    [[Z:%.*]] = icmp slt i8 [[Y]], 53
589; CHECK-NEXT:    ret i1 [[Z]]
590;
591  %y = and i8 %x, -75
592  %z = icmp slt i8 %y, 53
593  ret i1 %z
594}
595
596; 'add nuw x, C2' produces [C2, UINT_MAX]
597define i1 @tautological9(i32 %x) {
598; CHECK-LABEL: @tautological9(
599; CHECK-NEXT:    ret i1 true
600;
601  %add = add nuw i32 %x, 13
602  %cmp = icmp ne i32 %add, 12
603  ret i1 %cmp
604}
605
606define <2 x i1> @tautological9_vec(<2 x i32> %x) {
607; CHECK-LABEL: @tautological9_vec(
608; CHECK-NEXT:    ret <2 x i1> <i1 true, i1 true>
609;
610  %add = add nuw <2 x i32> %x, <i32 13, i32 13>
611  %cmp = icmp ne <2 x i32> %add, <i32 12, i32 12>
612  ret <2 x i1> %cmp
613}
614
615; The upper bound of the 'add' is 0.
616
617define i1 @add_nsw_neg_const1(i32 %x) {
618; CHECK-LABEL: @add_nsw_neg_const1(
619; CHECK-NEXT:    ret i1 false
620;
621  %add = add nsw i32 %x, -2147483647
622  %cmp = icmp sgt i32 %add, 0
623  ret i1 %cmp
624}
625
626; InstCombine can fold this, but not InstSimplify.
627
628define i1 @add_nsw_neg_const2(i32 %x) {
629; CHECK-LABEL: @add_nsw_neg_const2(
630; CHECK-NEXT:    [[ADD:%.*]] = add nsw i32 [[X:%.*]], -2147483647
631; CHECK-NEXT:    [[CMP:%.*]] = icmp sgt i32 [[ADD]], -1
632; CHECK-NEXT:    ret i1 [[CMP]]
633;
634  %add = add nsw i32 %x, -2147483647
635  %cmp = icmp sgt i32 %add, -1
636  ret i1 %cmp
637}
638
639; The upper bound of the 'add' is 1 (move the constants to prove we're doing range-based analysis).
640
641define i1 @add_nsw_neg_const3(i32 %x) {
642; CHECK-LABEL: @add_nsw_neg_const3(
643; CHECK-NEXT:    ret i1 false
644;
645  %add = add nsw i32 %x, -2147483646
646  %cmp = icmp sgt i32 %add, 1
647  ret i1 %cmp
648}
649
650; InstCombine can fold this, but not InstSimplify.
651
652define i1 @add_nsw_neg_const4(i32 %x) {
653; CHECK-LABEL: @add_nsw_neg_const4(
654; CHECK-NEXT:    [[ADD:%.*]] = add nsw i32 [[X:%.*]], -2147483646
655; CHECK-NEXT:    [[CMP:%.*]] = icmp sgt i32 [[ADD]], 0
656; CHECK-NEXT:    ret i1 [[CMP]]
657;
658  %add = add nsw i32 %x, -2147483646
659  %cmp = icmp sgt i32 %add, 0
660  ret i1 %cmp
661}
662
663; The upper bound of the 'add' is 2147483647 - 42 = 2147483605 (move the constants again and try a different cmp predicate).
664
665define i1 @add_nsw_neg_const5(i32 %x) {
666; CHECK-LABEL: @add_nsw_neg_const5(
667; CHECK-NEXT:    ret i1 true
668;
669  %add = add nsw i32 %x, -42
670  %cmp = icmp ne i32 %add, 2147483606
671  ret i1 %cmp
672}
673
674; InstCombine can fold this, but not InstSimplify.
675
676define i1 @add_nsw_neg_const6(i32 %x) {
677; CHECK-LABEL: @add_nsw_neg_const6(
678; CHECK-NEXT:    [[ADD:%.*]] = add nsw i32 [[X:%.*]], -42
679; CHECK-NEXT:    [[CMP:%.*]] = icmp ne i32 [[ADD]], 2147483605
680; CHECK-NEXT:    ret i1 [[CMP]]
681;
682  %add = add nsw i32 %x, -42
683  %cmp = icmp ne i32 %add, 2147483605
684  ret i1 %cmp
685}
686
687; The lower bound of the 'add' is -1.
688
689define i1 @add_nsw_pos_const1(i32 %x) {
690; CHECK-LABEL: @add_nsw_pos_const1(
691; CHECK-NEXT:    ret i1 false
692;
693  %add = add nsw i32 %x, 2147483647
694  %cmp = icmp slt i32 %add, -1
695  ret i1 %cmp
696}
697
698; InstCombine can fold this, but not InstSimplify.
699
700define i1 @add_nsw_pos_const2(i32 %x) {
701; CHECK-LABEL: @add_nsw_pos_const2(
702; CHECK-NEXT:    [[ADD:%.*]] = add nsw i32 [[X:%.*]], 2147483647
703; CHECK-NEXT:    [[CMP:%.*]] = icmp slt i32 [[ADD]], 0
704; CHECK-NEXT:    ret i1 [[CMP]]
705;
706  %add = add nsw i32 %x, 2147483647
707  %cmp = icmp slt i32 %add, 0
708  ret i1 %cmp
709}
710
711; The lower bound of the 'add' is -2 (move the constants to prove we're doing range-based analysis).
712
713define i1 @add_nsw_pos_const3(i32 %x) {
714; CHECK-LABEL: @add_nsw_pos_const3(
715; CHECK-NEXT:    ret i1 false
716;
717  %add = add nsw i32 %x, 2147483646
718  %cmp = icmp slt i32 %add, -2
719  ret i1 %cmp
720}
721
722; InstCombine can fold this, but not InstSimplify.
723
724define i1 @add_nsw_pos_const4(i32 %x) {
725; CHECK-LABEL: @add_nsw_pos_const4(
726; CHECK-NEXT:    [[ADD:%.*]] = add nsw i32 [[X:%.*]], 2147483646
727; CHECK-NEXT:    [[CMP:%.*]] = icmp slt i32 [[ADD]], -1
728; CHECK-NEXT:    ret i1 [[CMP]]
729;
730  %add = add nsw i32 %x, 2147483646
731  %cmp = icmp slt i32 %add, -1
732  ret i1 %cmp
733}
734
735; The lower bound of the 'add' is -2147483648 + 42 = -2147483606 (move the constants again and change the cmp predicate).
736
737define i1 @add_nsw_pos_const5(i32 %x) {
738; CHECK-LABEL: @add_nsw_pos_const5(
739; CHECK-NEXT:    ret i1 false
740;
741  %add = add nsw i32 %x, 42
742  %cmp = icmp eq i32 %add, -2147483607
743  ret i1 %cmp
744}
745
746; InstCombine can fold this, but not InstSimplify.
747
748define i1 @add_nsw_pos_const6(i32 %x) {
749; CHECK-LABEL: @add_nsw_pos_const6(
750; CHECK-NEXT:    [[ADD:%.*]] = add nsw i32 [[X:%.*]], 42
751; CHECK-NEXT:    [[CMP:%.*]] = icmp eq i32 [[ADD]], -2147483606
752; CHECK-NEXT:    ret i1 [[CMP]]
753;
754  %add = add nsw i32 %x, 42
755  %cmp = icmp eq i32 %add, -2147483606
756  ret i1 %cmp
757}
758
759; Verify that vectors work too.
760
761define <2 x i1> @add_nsw_pos_const5_splat_vec(<2 x i32> %x) {
762; CHECK-LABEL: @add_nsw_pos_const5_splat_vec(
763; CHECK-NEXT:    ret <2 x i1> <i1 true, i1 true>
764;
765  %add = add nsw <2 x i32> %x, <i32 42, i32 42>
766  %cmp = icmp ne <2 x i32> %add, <i32 -2147483607, i32 -2147483607>
767  ret <2 x i1> %cmp
768}
769
770; PR34838 - https://bugs.llvm.org/show_bug.cgi?id=34838
771; The shift is known to create poison, so we can simplify the cmp.
772
773define i1 @ne_shl_by_constant_produces_poison(i8 %x) {
774; CHECK-LABEL: @ne_shl_by_constant_produces_poison(
775; CHECK-NEXT:    ret i1 poison
776;
777  %zx = zext i8 %x to i16      ; zx  = 0x00xx
778  %xor = xor i16 %zx, 32767    ; xor = 0x7fyy
779  %sub = sub nsw i16 %zx, %xor ; sub = 0x80zz  (the top bit is known one)
780  %poison = shl nsw i16 %sub, 2    ; oops! this shl can't be nsw; that's POISON
781  %cmp = icmp ne i16 %poison, 1
782  ret i1 %cmp
783}
784
785define i1 @eq_shl_by_constant_produces_poison(i8 %x) {
786; CHECK-LABEL: @eq_shl_by_constant_produces_poison(
787; CHECK-NEXT:    ret i1 poison
788;
789  %clear_high_bit = and i8 %x, 127                 ; 0x7f
790  %set_next_high_bits = or i8 %clear_high_bit, 112 ; 0x70
791  %poison = shl nsw i8 %set_next_high_bits, 3
792  %cmp = icmp eq i8 %poison, 15
793  ret i1 %cmp
794}
795
796; Shift-by-variable that produces poison is more complicated but still possible.
797; We guarantee that the shift will change the sign of the shifted value (and
798; therefore produce poison) by limiting its range from 1 to 3.
799
800define i1 @eq_shl_by_variable_produces_poison(i8 %x) {
801; CHECK-LABEL: @eq_shl_by_variable_produces_poison(
802; CHECK-NEXT:    ret i1 poison
803;
804  %clear_high_bit = and i8 %x, 127                 ; 0x7f
805  %set_next_high_bits = or i8 %clear_high_bit, 112 ; 0x70
806  %notundef_shiftamt = and i8 %x, 3
807  %nonzero_shiftamt = or i8 %notundef_shiftamt, 1
808  %poison = shl nsw i8 %set_next_high_bits, %nonzero_shiftamt
809  %cmp = icmp eq i8 %poison, 15
810  ret i1 %cmp
811}
812
813; No overflow, so mul constant must be a factor of cmp constant.
814
815define i1 @mul_nuw_urem_cmp_constant1(i8 %x) {
816; CHECK-LABEL: @mul_nuw_urem_cmp_constant1(
817; CHECK-NEXT:    ret i1 false
818;
819  %m = mul nuw i8 %x, 43
820  %r = icmp eq i8 %m, 42
821  ret i1 %r
822}
823
824; Invert predicate and check vector type.
825
826define <2 x i1> @mul_nuw_urem_cmp_constant_vec_splat(<2 x i8> %x) {
827; CHECK-LABEL: @mul_nuw_urem_cmp_constant_vec_splat(
828; CHECK-NEXT:    ret <2 x i1> <i1 true, i1 true>
829;
830  %m = mul nuw <2 x i8> %x, <i8 45, i8 45>
831  %r = icmp ne <2 x i8> %m, <i8 15, i8 15>
832  ret <2 x i1> %r
833}
834
835; Undefs in vector constants are ok.
836
837define <2 x i1> @mul_nuw_urem_cmp_constant_vec_splat_undef1(<2 x i8> %x) {
838; CHECK-LABEL: @mul_nuw_urem_cmp_constant_vec_splat_undef1(
839; CHECK-NEXT:    ret <2 x i1> <i1 true, i1 true>
840;
841  %m = mul nuw <2 x i8> %x, <i8 45, i8 45>
842  %r = icmp ne <2 x i8> %m, <i8 15, i8 undef>
843  ret <2 x i1> %r
844}
845
846; Undefs in vector constants are ok.
847
848define <2 x i1> @mul_nuw_urem_cmp_constant_vec_splat_undef2(<2 x i8> %x) {
849; CHECK-LABEL: @mul_nuw_urem_cmp_constant_vec_splat_undef2(
850; CHECK-NEXT:    ret <2 x i1> <i1 true, i1 true>
851;
852  %m = mul nuw <2 x i8> %x, <i8 undef, i8 45>
853  %r = icmp ne <2 x i8> %m, <i8 15, i8 15>
854  ret <2 x i1> %r
855}
856
857; Check "negative" numbers (constants should be analyzed as unsigned).
858
859define i1 @mul_nuw_urem_cmp_constant2(i8 %x) {
860; CHECK-LABEL: @mul_nuw_urem_cmp_constant2(
861; CHECK-NEXT:    ret i1 false
862;
863  %m = mul nuw i8 %x, -42
864  %r = icmp eq i8 %m, -84
865  ret i1 %r
866}
867
868; Negative test - require nuw.
869
870define i1 @mul_urem_cmp_constant1(i8 %x) {
871; CHECK-LABEL: @mul_urem_cmp_constant1(
872; CHECK-NEXT:    [[M:%.*]] = mul i8 [[X:%.*]], 43
873; CHECK-NEXT:    [[R:%.*]] = icmp eq i8 [[M]], 42
874; CHECK-NEXT:    ret i1 [[R]]
875;
876  %m = mul i8 %x, 43
877  %r = icmp eq i8 %m, 42
878  ret i1 %r
879}
880
881; Negative test - x could be 0.
882
883define i1 @mul_nuw_urem_cmp_constant0(i8 %x) {
884; CHECK-LABEL: @mul_nuw_urem_cmp_constant0(
885; CHECK-NEXT:    [[M:%.*]] = mul nuw i8 [[X:%.*]], 23
886; CHECK-NEXT:    [[R:%.*]] = icmp eq i8 [[M]], 0
887; CHECK-NEXT:    ret i1 [[R]]
888;
889  %m = mul nuw i8 %x, 23
890  %r = icmp eq i8 %m, 0
891  ret i1 %r
892}
893
894; Negative test - cmp constant is multiple of mul constant.
895
896define i1 @mul_nuw_urem_cmp_constant_is_0(i8 %x) {
897; CHECK-LABEL: @mul_nuw_urem_cmp_constant_is_0(
898; CHECK-NEXT:    [[M:%.*]] = mul nuw i8 [[X:%.*]], 42
899; CHECK-NEXT:    [[R:%.*]] = icmp eq i8 [[M]], 84
900; CHECK-NEXT:    ret i1 [[R]]
901;
902  %m = mul nuw i8 %x, 42
903  %r = icmp eq i8 %m, 84
904  ret i1 %r
905}
906
907; Negative test - cmp constant is multiple (treated as unsigned).
908
909define i1 @mul_nuw_urem_cmp_neg_constant_is_0(i8 %x) {
910; CHECK-LABEL: @mul_nuw_urem_cmp_neg_constant_is_0(
911; CHECK-NEXT:    [[M:%.*]] = mul nuw i8 [[X:%.*]], 43
912; CHECK-NEXT:    [[R:%.*]] = icmp eq i8 [[M]], -127
913; CHECK-NEXT:    ret i1 [[R]]
914;
915  %m = mul nuw i8 %x, 43
916  %r = icmp eq i8 %m, -127
917  ret i1 %r
918}
919
920; No overflow, so mul constant must be a factor of cmp constant.
921
922define i1 @mul_nsw_srem_cmp_constant1(i8 %x) {
923; CHECK-LABEL: @mul_nsw_srem_cmp_constant1(
924; CHECK-NEXT:    ret i1 false
925;
926  %m = mul nsw i8 %x, 43
927  %r = icmp eq i8 %m, 45
928  ret i1 %r
929}
930
931; Invert predicate and check vector type.
932
933define <2 x i1> @mul_nsw_srem_cmp_constant_vec_splat(<2 x i8> %x) {
934; CHECK-LABEL: @mul_nsw_srem_cmp_constant_vec_splat(
935; CHECK-NEXT:    ret <2 x i1> <i1 true, i1 true>
936;
937  %m = mul nsw <2 x i8> %x, <i8 45, i8 45>
938  %r = icmp ne <2 x i8> %m, <i8 15, i8 15>
939  ret <2 x i1> %r
940}
941
942; Undefs in vector constants are ok.
943
944define <2 x i1> @mul_nsw_srem_cmp_constant_vec_splat_undef1(<2 x i8> %x) {
945; CHECK-LABEL: @mul_nsw_srem_cmp_constant_vec_splat_undef1(
946; CHECK-NEXT:    ret <2 x i1> <i1 true, i1 true>
947;
948  %m = mul nsw <2 x i8> %x, <i8 45, i8 45>
949  %r = icmp ne <2 x i8> %m, <i8 15, i8 undef>
950  ret <2 x i1> %r
951}
952
953; Undefs in vector constants are ok.
954
955define <2 x i1> @mul_nsw_srem_cmp_constant_vec_splat_undef2(<2 x i8> %x) {
956; CHECK-LABEL: @mul_nsw_srem_cmp_constant_vec_splat_undef2(
957; CHECK-NEXT:    ret <2 x i1> <i1 true, i1 true>
958;
959  %m = mul nsw <2 x i8> %x, <i8 undef, i8 45>
960  %r = icmp ne <2 x i8> %m, <i8 15, i8 15>
961  ret <2 x i1> %r
962}
963
964; Check negative numbers (constants should be analyzed as signed).
965
966define i1 @mul_nsw_srem_cmp_constant2(i8 %x) {
967; CHECK-LABEL: @mul_nsw_srem_cmp_constant2(
968; CHECK-NEXT:    ret i1 false
969;
970  %m = mul nsw i8 %x, 43
971  %r = icmp eq i8 %m, -127
972  ret i1 %r
973}
974
975; Negative test - require nsw.
976
977define i1 @mul_srem_cmp_constant1(i8 %x) {
978; CHECK-LABEL: @mul_srem_cmp_constant1(
979; CHECK-NEXT:    [[M:%.*]] = mul i8 [[X:%.*]], 43
980; CHECK-NEXT:    [[R:%.*]] = icmp eq i8 [[M]], 42
981; CHECK-NEXT:    ret i1 [[R]]
982;
983  %m = mul i8 %x, 43
984  %r = icmp eq i8 %m, 42
985  ret i1 %r
986}
987
988; Negative test - x could be 0.
989
990define i1 @mul_nsw_srem_cmp_constant0(i8 %x) {
991; CHECK-LABEL: @mul_nsw_srem_cmp_constant0(
992; CHECK-NEXT:    [[M:%.*]] = mul nsw i8 [[X:%.*]], 23
993; CHECK-NEXT:    [[R:%.*]] = icmp eq i8 [[M]], 0
994; CHECK-NEXT:    ret i1 [[R]]
995;
996  %m = mul nsw i8 %x, 23
997  %r = icmp eq i8 %m, 0
998  ret i1 %r
999}
1000
1001; Negative test - cmp constant is multiple of mul constant.
1002
1003define i1 @mul_nsw_srem_cmp_constant_is_0(i8 %x) {
1004; CHECK-LABEL: @mul_nsw_srem_cmp_constant_is_0(
1005; CHECK-NEXT:    [[M:%.*]] = mul nsw i8 [[X:%.*]], 42
1006; CHECK-NEXT:    [[R:%.*]] = icmp eq i8 [[M]], 84
1007; CHECK-NEXT:    ret i1 [[R]]
1008;
1009  %m = mul nsw i8 %x, 42
1010  %r = icmp eq i8 %m, 84
1011  ret i1 %r
1012}
1013
1014; Negative test - cmp constant is multiple (treated as signed).
1015
1016define i1 @mul_nsw_srem_cmp_neg_constant_is_0(i8 %x) {
1017; CHECK-LABEL: @mul_nsw_srem_cmp_neg_constant_is_0(
1018; CHECK-NEXT:    [[M:%.*]] = mul nsw i8 [[X:%.*]], -42
1019; CHECK-NEXT:    [[R:%.*]] = icmp eq i8 [[M]], -84
1020; CHECK-NEXT:    ret i1 [[R]]
1021;
1022  %m = mul nsw i8 %x, -42
1023  %r = icmp eq i8 %m, -84
1024  ret i1 %r
1025}
1026
1027; Don't crash trying to div/rem-by-zero.
1028
1029define i1 @mul_nsw_by_zero(i8 %x) {
1030; CHECK-LABEL: @mul_nsw_by_zero(
1031; CHECK-NEXT:  bb1:
1032; CHECK-NEXT:    br label [[BB3:%.*]]
1033; CHECK:       bb2:
1034; CHECK-NEXT:    ret i1 false
1035; CHECK:       bb3:
1036; CHECK-NEXT:    br label [[BB2:%.*]]
1037;
1038bb1:
1039  br label %bb3
1040bb2:
1041  %r = icmp eq i8 %m, 45
1042  ret i1 %r
1043bb3:
1044  %m = mul nsw i8 %x, 0
1045  br label %bb2
1046}
1047
1048; Don't crash trying to div/rem-by-zero.
1049
1050define i1 @mul_nuw_by_zero(i8 %x) {
1051; CHECK-LABEL: @mul_nuw_by_zero(
1052; CHECK-NEXT:  bb1:
1053; CHECK-NEXT:    br label [[BB3:%.*]]
1054; CHECK:       bb2:
1055; CHECK-NEXT:    ret i1 false
1056; CHECK:       bb3:
1057; CHECK-NEXT:    br label [[BB2:%.*]]
1058;
1059bb1:
1060  br label %bb3
1061bb2:
1062  %r = icmp eq i8 %m, 45
1063  ret i1 %r
1064bb3:
1065  %m = mul nuw i8 %x, 0
1066  br label %bb2
1067}
1068
1069
1070define <2 x i1> @heterogeneous_constvector(<2 x i8> %x) {
1071; CHECK-LABEL: @heterogeneous_constvector(
1072; CHECK-NEXT:    ret <2 x i1> zeroinitializer
1073;
1074  %c = icmp ult <2 x i8> %x, <i8 undef, i8 poison>
1075  ret <2 x i1> %c
1076}
1077