xref: /llvm-project/llvm/test/Transforms/InstSimplify/icmp-constant.ll (revision 38fffa630ee80163dc65e759392ad29798905679)
1; NOTE: Assertions have been autogenerated by utils/update_test_checks.py
2; RUN: opt < %s -passes=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> splat (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_poison(<2 x i8> %x) {
23; CHECK-LABEL: @tautological_ule_vec_partial_poison(
24; CHECK-NEXT:    ret <2 x i1> splat (i1 true)
25;
26  %cmp = icmp ule <2 x i8> %x, <i8 255, i8 poison>
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_poison(<2 x i8> %x) {
47; CHECK-LABEL: @tautological_ugt_vec_partial_poison(
48; CHECK-NEXT:    ret <2 x i1> zeroinitializer
49;
50  %cmp = icmp ugt <2 x i8> %x, <i8 poison, 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> splat (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_poison(<2 x i32> %X) {
74; CHECK-LABEL: @urem3_vec_partial_poison(
75; CHECK-NEXT:    ret <2 x i1> splat (i1 true)
76;
77  %A = urem <2 x i32> %X, <i32 10, i32 10>
78  %B = icmp ult <2 x i32> %A, <i32 poison, 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_poison(<2 x i32> %X) {
102; CHECK-LABEL: @srem1_vec_partial_poison(
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 poison>
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> splat (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> splat (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> splat (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_poison(<2 x i32> %X) {
207; CHECK-LABEL: @shl5_vec_partial_poison(
208; CHECK-NEXT:    ret <2 x i1> splat (i1 true)
209;
210  %sub = shl nuw <2 x i32> <i32 4, i32 4>, %X
211  %cmp = icmp ugt <2 x i32> %sub, <i32 poison, 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> splat (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> splat (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_poison(<2 x i32> %X) {
425; CHECK-LABEL: @or1_vec_partial_poison(
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 poison, 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> splat (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
626define i1 @add_nsw_sgt(i8 %x) {
627; CHECK-LABEL: @add_nsw_sgt(
628; CHECK-NEXT:    ret i1 true
629;
630  %add = add nsw i8 %x, 5
631  %cmp = icmp sgt i8 %add, -124
632  ret i1 %cmp
633}
634
635; nuw should not inhibit the fold.
636
637define i1 @add_nsw_nuw_sgt(i8 %x) {
638; CHECK-LABEL: @add_nsw_nuw_sgt(
639; CHECK-NEXT:    ret i1 true
640;
641  %add = add nsw nuw i8 %x, 5
642  %cmp = icmp sgt i8 %add, -124
643  ret i1 %cmp
644}
645
646; negative test - minimum x is -128, so add could be -124.
647
648define i1 @add_nsw_sgt_limit(i8 %x) {
649; CHECK-LABEL: @add_nsw_sgt_limit(
650; CHECK-NEXT:    [[ADD:%.*]] = add nsw i8 [[X:%.*]], 4
651; CHECK-NEXT:    [[CMP:%.*]] = icmp sgt i8 [[ADD]], -124
652; CHECK-NEXT:    ret i1 [[CMP]]
653;
654  %add = add nsw i8 %x, 4
655  %cmp = icmp sgt i8 %add, -124
656  ret i1 %cmp
657}
658
659define i1 @add_nsw_slt(i8 %x) {
660; CHECK-LABEL: @add_nsw_slt(
661; CHECK-NEXT:    ret i1 false
662;
663  %add = add nsw i8 %x, 5
664  %cmp = icmp slt i8 %add, -123
665  ret i1 %cmp
666}
667
668; nuw should not inhibit the fold.
669
670define i1 @add_nsw_nuw_slt(i8 %x) {
671; CHECK-LABEL: @add_nsw_nuw_slt(
672; CHECK-NEXT:    ret i1 false
673;
674  %add = add nsw nuw i8 %x, 5
675  %cmp = icmp slt i8 %add, -123
676  ret i1 %cmp
677}
678
679; negative test - minimum x is -128, so add could be -123.
680
681define i1 @add_nsw_slt_limit(i8 %x) {
682; CHECK-LABEL: @add_nsw_slt_limit(
683; CHECK-NEXT:    [[ADD:%.*]] = add nsw i8 [[X:%.*]], 5
684; CHECK-NEXT:    [[CMP:%.*]] = icmp slt i8 [[ADD]], -122
685; CHECK-NEXT:    ret i1 [[CMP]]
686;
687  %add = add nsw i8 %x, 5
688  %cmp = icmp slt i8 %add, -122
689  ret i1 %cmp
690}
691
692; InstCombine can fold this, but not InstSimplify.
693
694define i1 @add_nsw_neg_const2(i32 %x) {
695; CHECK-LABEL: @add_nsw_neg_const2(
696; CHECK-NEXT:    [[ADD:%.*]] = add nsw i32 [[X:%.*]], -2147483647
697; CHECK-NEXT:    [[CMP:%.*]] = icmp sgt i32 [[ADD]], -1
698; CHECK-NEXT:    ret i1 [[CMP]]
699;
700  %add = add nsw i32 %x, -2147483647
701  %cmp = icmp sgt i32 %add, -1
702  ret i1 %cmp
703}
704
705; The upper bound of the 'add' is 1 (move the constants to prove we're doing range-based analysis).
706
707define i1 @add_nsw_neg_const3(i32 %x) {
708; CHECK-LABEL: @add_nsw_neg_const3(
709; CHECK-NEXT:    ret i1 false
710;
711  %add = add nsw i32 %x, -2147483646
712  %cmp = icmp sgt i32 %add, 1
713  ret i1 %cmp
714}
715
716; InstCombine can fold this, but not InstSimplify.
717
718define i1 @add_nsw_neg_const4(i32 %x) {
719; CHECK-LABEL: @add_nsw_neg_const4(
720; CHECK-NEXT:    [[ADD:%.*]] = add nsw i32 [[X:%.*]], -2147483646
721; CHECK-NEXT:    [[CMP:%.*]] = icmp sgt i32 [[ADD]], 0
722; CHECK-NEXT:    ret i1 [[CMP]]
723;
724  %add = add nsw i32 %x, -2147483646
725  %cmp = icmp sgt i32 %add, 0
726  ret i1 %cmp
727}
728
729; The upper bound of the 'add' is 2147483647 - 42 = 2147483605 (move the constants again and try a different cmp predicate).
730
731define i1 @add_nsw_neg_const5(i32 %x) {
732; CHECK-LABEL: @add_nsw_neg_const5(
733; CHECK-NEXT:    ret i1 true
734;
735  %add = add nsw i32 %x, -42
736  %cmp = icmp ne i32 %add, 2147483606
737  ret i1 %cmp
738}
739
740; InstCombine can fold this, but not InstSimplify.
741
742define i1 @add_nsw_neg_const6(i32 %x) {
743; CHECK-LABEL: @add_nsw_neg_const6(
744; CHECK-NEXT:    [[ADD:%.*]] = add nsw i32 [[X:%.*]], -42
745; CHECK-NEXT:    [[CMP:%.*]] = icmp ne i32 [[ADD]], 2147483605
746; CHECK-NEXT:    ret i1 [[CMP]]
747;
748  %add = add nsw i32 %x, -42
749  %cmp = icmp ne i32 %add, 2147483605
750  ret i1 %cmp
751}
752
753; The lower bound of the 'add' is -1.
754
755define i1 @add_nsw_pos_const1(i32 %x) {
756; CHECK-LABEL: @add_nsw_pos_const1(
757; CHECK-NEXT:    ret i1 false
758;
759  %add = add nsw i32 %x, 2147483647
760  %cmp = icmp slt i32 %add, -1
761  ret i1 %cmp
762}
763
764; InstCombine can fold this, but not InstSimplify.
765
766define i1 @add_nsw_pos_const2(i32 %x) {
767; CHECK-LABEL: @add_nsw_pos_const2(
768; CHECK-NEXT:    [[ADD:%.*]] = add nsw i32 [[X:%.*]], 2147483647
769; CHECK-NEXT:    [[CMP:%.*]] = icmp slt i32 [[ADD]], 0
770; CHECK-NEXT:    ret i1 [[CMP]]
771;
772  %add = add nsw i32 %x, 2147483647
773  %cmp = icmp slt i32 %add, 0
774  ret i1 %cmp
775}
776
777; The lower bound of the 'add' is -2 (move the constants to prove we're doing range-based analysis).
778
779define i1 @add_nsw_pos_const3(i32 %x) {
780; CHECK-LABEL: @add_nsw_pos_const3(
781; CHECK-NEXT:    ret i1 false
782;
783  %add = add nsw i32 %x, 2147483646
784  %cmp = icmp slt i32 %add, -2
785  ret i1 %cmp
786}
787
788; InstCombine can fold this, but not InstSimplify.
789
790define i1 @add_nsw_pos_const4(i32 %x) {
791; CHECK-LABEL: @add_nsw_pos_const4(
792; CHECK-NEXT:    [[ADD:%.*]] = add nsw i32 [[X:%.*]], 2147483646
793; CHECK-NEXT:    [[CMP:%.*]] = icmp slt i32 [[ADD]], -1
794; CHECK-NEXT:    ret i1 [[CMP]]
795;
796  %add = add nsw i32 %x, 2147483646
797  %cmp = icmp slt i32 %add, -1
798  ret i1 %cmp
799}
800
801; The lower bound of the 'add' is -2147483648 + 42 = -2147483606 (move the constants again and change the cmp predicate).
802
803define i1 @add_nsw_pos_const5(i32 %x) {
804; CHECK-LABEL: @add_nsw_pos_const5(
805; CHECK-NEXT:    ret i1 false
806;
807  %add = add nsw i32 %x, 42
808  %cmp = icmp eq i32 %add, -2147483607
809  ret i1 %cmp
810}
811
812; InstCombine can fold this, but not InstSimplify.
813
814define i1 @add_nsw_pos_const6(i32 %x) {
815; CHECK-LABEL: @add_nsw_pos_const6(
816; CHECK-NEXT:    [[ADD:%.*]] = add nsw i32 [[X:%.*]], 42
817; CHECK-NEXT:    [[CMP:%.*]] = icmp eq i32 [[ADD]], -2147483606
818; CHECK-NEXT:    ret i1 [[CMP]]
819;
820  %add = add nsw i32 %x, 42
821  %cmp = icmp eq i32 %add, -2147483606
822  ret i1 %cmp
823}
824
825; Verify that vectors work too.
826
827define <2 x i1> @add_nsw_pos_const5_splat_vec(<2 x i32> %x) {
828; CHECK-LABEL: @add_nsw_pos_const5_splat_vec(
829; CHECK-NEXT:    ret <2 x i1> splat (i1 true)
830;
831  %add = add nsw <2 x i32> %x, <i32 42, i32 42>
832  %cmp = icmp ne <2 x i32> %add, <i32 -2147483607, i32 -2147483607>
833  ret <2 x i1> %cmp
834}
835
836; PR34838 - https://bugs.llvm.org/show_bug.cgi?id=34838
837; The shift is known to create poison, so we can simplify the cmp.
838
839define i1 @ne_shl_by_constant_produces_poison(i8 %x) {
840; CHECK-LABEL: @ne_shl_by_constant_produces_poison(
841; CHECK-NEXT:    ret i1 poison
842;
843  %zx = zext i8 %x to i16      ; zx  = 0x00xx
844  %xor = xor i16 %zx, 32767    ; xor = 0x7fyy
845  %sub = sub nsw i16 %zx, %xor ; sub = 0x80zz  (the top bit is known one)
846  %poison = shl nsw i16 %sub, 2    ; oops! this shl can't be nsw; that's POISON
847  %cmp = icmp ne i16 %poison, 1
848  ret i1 %cmp
849}
850
851define i1 @eq_shl_by_constant_produces_poison(i8 %x) {
852; CHECK-LABEL: @eq_shl_by_constant_produces_poison(
853; CHECK-NEXT:    ret i1 poison
854;
855  %clear_high_bit = and i8 %x, 127                 ; 0x7f
856  %set_next_high_bits = or i8 %clear_high_bit, 112 ; 0x70
857  %poison = shl nsw i8 %set_next_high_bits, 3
858  %cmp = icmp eq i8 %poison, 15
859  ret i1 %cmp
860}
861
862; Shift-by-variable that produces poison is more complicated but still possible.
863; We guarantee that the shift will change the sign of the shifted value (and
864; therefore produce poison) by limiting its range from 1 to 3.
865
866define i1 @eq_shl_by_variable_produces_poison(i8 %x) {
867; CHECK-LABEL: @eq_shl_by_variable_produces_poison(
868; CHECK-NEXT:    ret i1 poison
869;
870  %clear_high_bit = and i8 %x, 127                 ; 0x7f
871  %set_next_high_bits = or i8 %clear_high_bit, 112 ; 0x70
872  %notundef_shiftamt = and i8 %x, 3
873  %nonzero_shiftamt = or i8 %notundef_shiftamt, 1
874  %poison = shl nsw i8 %set_next_high_bits, %nonzero_shiftamt
875  %cmp = icmp eq i8 %poison, 15
876  ret i1 %cmp
877}
878
879; No overflow, so mul constant must be a factor of cmp constant.
880
881define i1 @mul_nuw_urem_cmp_constant1(i8 %x) {
882; CHECK-LABEL: @mul_nuw_urem_cmp_constant1(
883; CHECK-NEXT:    ret i1 false
884;
885  %m = mul nuw i8 %x, 43
886  %r = icmp eq i8 %m, 42
887  ret i1 %r
888}
889
890; Invert predicate and check vector type.
891
892define <2 x i1> @mul_nuw_urem_cmp_constant_vec_splat(<2 x i8> %x) {
893; CHECK-LABEL: @mul_nuw_urem_cmp_constant_vec_splat(
894; CHECK-NEXT:    ret <2 x i1> splat (i1 true)
895;
896  %m = mul nuw <2 x i8> %x, <i8 45, i8 45>
897  %r = icmp ne <2 x i8> %m, <i8 15, i8 15>
898  ret <2 x i1> %r
899}
900
901; Undefs in vector constants are ok.
902
903define <2 x i1> @mul_nuw_urem_cmp_constant_vec_splat_poison1(<2 x i8> %x) {
904; CHECK-LABEL: @mul_nuw_urem_cmp_constant_vec_splat_poison1(
905; CHECK-NEXT:    ret <2 x i1> splat (i1 true)
906;
907  %m = mul nuw <2 x i8> %x, <i8 45, i8 45>
908  %r = icmp ne <2 x i8> %m, <i8 15, i8 poison>
909  ret <2 x i1> %r
910}
911
912; Undefs in vector constants are ok.
913
914define <2 x i1> @mul_nuw_urem_cmp_constant_vec_splat_poison2(<2 x i8> %x) {
915; CHECK-LABEL: @mul_nuw_urem_cmp_constant_vec_splat_poison2(
916; CHECK-NEXT:    ret <2 x i1> splat (i1 true)
917;
918  %m = mul nuw <2 x i8> %x, <i8 poison, i8 45>
919  %r = icmp ne <2 x i8> %m, <i8 15, i8 15>
920  ret <2 x i1> %r
921}
922
923; Check "negative" numbers (constants should be analyzed as unsigned).
924
925define i1 @mul_nuw_urem_cmp_constant2(i8 %x) {
926; CHECK-LABEL: @mul_nuw_urem_cmp_constant2(
927; CHECK-NEXT:    ret i1 false
928;
929  %m = mul nuw i8 %x, -42
930  %r = icmp eq i8 %m, -84
931  ret i1 %r
932}
933
934; Negative test - require nuw.
935
936define i1 @mul_urem_cmp_constant1(i8 %x) {
937; CHECK-LABEL: @mul_urem_cmp_constant1(
938; CHECK-NEXT:    [[M:%.*]] = mul i8 [[X:%.*]], 43
939; CHECK-NEXT:    [[R:%.*]] = icmp eq i8 [[M]], 42
940; CHECK-NEXT:    ret i1 [[R]]
941;
942  %m = mul i8 %x, 43
943  %r = icmp eq i8 %m, 42
944  ret i1 %r
945}
946
947; Negative test - x could be 0.
948
949define i1 @mul_nuw_urem_cmp_constant0(i8 %x) {
950; CHECK-LABEL: @mul_nuw_urem_cmp_constant0(
951; CHECK-NEXT:    [[M:%.*]] = mul nuw i8 [[X:%.*]], 23
952; CHECK-NEXT:    [[R:%.*]] = icmp eq i8 [[M]], 0
953; CHECK-NEXT:    ret i1 [[R]]
954;
955  %m = mul nuw i8 %x, 23
956  %r = icmp eq i8 %m, 0
957  ret i1 %r
958}
959
960; Negative test - cmp constant is multiple of mul constant.
961
962define i1 @mul_nuw_urem_cmp_constant_is_0(i8 %x) {
963; CHECK-LABEL: @mul_nuw_urem_cmp_constant_is_0(
964; CHECK-NEXT:    [[M:%.*]] = mul nuw i8 [[X:%.*]], 42
965; CHECK-NEXT:    [[R:%.*]] = icmp eq i8 [[M]], 84
966; CHECK-NEXT:    ret i1 [[R]]
967;
968  %m = mul nuw i8 %x, 42
969  %r = icmp eq i8 %m, 84
970  ret i1 %r
971}
972
973; Negative test - cmp constant is multiple (treated as unsigned).
974
975define i1 @mul_nuw_urem_cmp_neg_constant_is_0(i8 %x) {
976; CHECK-LABEL: @mul_nuw_urem_cmp_neg_constant_is_0(
977; CHECK-NEXT:    [[M:%.*]] = mul nuw i8 [[X:%.*]], 43
978; CHECK-NEXT:    [[R:%.*]] = icmp eq i8 [[M]], -127
979; CHECK-NEXT:    ret i1 [[R]]
980;
981  %m = mul nuw i8 %x, 43
982  %r = icmp eq i8 %m, -127
983  ret i1 %r
984}
985
986; No overflow, so mul constant must be a factor of cmp constant.
987
988define i1 @mul_nsw_srem_cmp_constant1(i8 %x) {
989; CHECK-LABEL: @mul_nsw_srem_cmp_constant1(
990; CHECK-NEXT:    ret i1 false
991;
992  %m = mul nsw i8 %x, 43
993  %r = icmp eq i8 %m, 45
994  ret i1 %r
995}
996
997; Invert predicate and check vector type.
998
999define <2 x i1> @mul_nsw_srem_cmp_constant_vec_splat(<2 x i8> %x) {
1000; CHECK-LABEL: @mul_nsw_srem_cmp_constant_vec_splat(
1001; CHECK-NEXT:    ret <2 x i1> splat (i1 true)
1002;
1003  %m = mul nsw <2 x i8> %x, <i8 45, i8 45>
1004  %r = icmp ne <2 x i8> %m, <i8 15, i8 15>
1005  ret <2 x i1> %r
1006}
1007
1008; Undefs in vector constants are ok.
1009
1010define <2 x i1> @mul_nsw_srem_cmp_constant_vec_splat_poison1(<2 x i8> %x) {
1011; CHECK-LABEL: @mul_nsw_srem_cmp_constant_vec_splat_poison1(
1012; CHECK-NEXT:    ret <2 x i1> splat (i1 true)
1013;
1014  %m = mul nsw <2 x i8> %x, <i8 45, i8 45>
1015  %r = icmp ne <2 x i8> %m, <i8 15, i8 poison>
1016  ret <2 x i1> %r
1017}
1018
1019; Undefs in vector constants are ok.
1020
1021define <2 x i1> @mul_nsw_srem_cmp_constant_vec_splat_poison2(<2 x i8> %x) {
1022; CHECK-LABEL: @mul_nsw_srem_cmp_constant_vec_splat_poison2(
1023; CHECK-NEXT:    ret <2 x i1> splat (i1 true)
1024;
1025  %m = mul nsw <2 x i8> %x, <i8 poison, i8 45>
1026  %r = icmp ne <2 x i8> %m, <i8 15, i8 15>
1027  ret <2 x i1> %r
1028}
1029
1030; Check negative numbers (constants should be analyzed as signed).
1031
1032define i1 @mul_nsw_srem_cmp_constant2(i8 %x) {
1033; CHECK-LABEL: @mul_nsw_srem_cmp_constant2(
1034; CHECK-NEXT:    ret i1 false
1035;
1036  %m = mul nsw i8 %x, 43
1037  %r = icmp eq i8 %m, -127
1038  ret i1 %r
1039}
1040
1041; Negative test - require nsw.
1042
1043define i1 @mul_srem_cmp_constant1(i8 %x) {
1044; CHECK-LABEL: @mul_srem_cmp_constant1(
1045; CHECK-NEXT:    [[M:%.*]] = mul i8 [[X:%.*]], 43
1046; CHECK-NEXT:    [[R:%.*]] = icmp eq i8 [[M]], 42
1047; CHECK-NEXT:    ret i1 [[R]]
1048;
1049  %m = mul i8 %x, 43
1050  %r = icmp eq i8 %m, 42
1051  ret i1 %r
1052}
1053
1054; Negative test - x could be 0.
1055
1056define i1 @mul_nsw_srem_cmp_constant0(i8 %x) {
1057; CHECK-LABEL: @mul_nsw_srem_cmp_constant0(
1058; CHECK-NEXT:    [[M:%.*]] = mul nsw i8 [[X:%.*]], 23
1059; CHECK-NEXT:    [[R:%.*]] = icmp eq i8 [[M]], 0
1060; CHECK-NEXT:    ret i1 [[R]]
1061;
1062  %m = mul nsw i8 %x, 23
1063  %r = icmp eq i8 %m, 0
1064  ret i1 %r
1065}
1066
1067; Negative test - cmp constant is multiple of mul constant.
1068
1069define i1 @mul_nsw_srem_cmp_constant_is_0(i8 %x) {
1070; CHECK-LABEL: @mul_nsw_srem_cmp_constant_is_0(
1071; CHECK-NEXT:    [[M:%.*]] = mul nsw i8 [[X:%.*]], 42
1072; CHECK-NEXT:    [[R:%.*]] = icmp eq i8 [[M]], 84
1073; CHECK-NEXT:    ret i1 [[R]]
1074;
1075  %m = mul nsw i8 %x, 42
1076  %r = icmp eq i8 %m, 84
1077  ret i1 %r
1078}
1079
1080; Negative test - cmp constant is multiple (treated as signed).
1081
1082define i1 @mul_nsw_srem_cmp_neg_constant_is_0(i8 %x) {
1083; CHECK-LABEL: @mul_nsw_srem_cmp_neg_constant_is_0(
1084; CHECK-NEXT:    [[M:%.*]] = mul nsw i8 [[X:%.*]], -42
1085; CHECK-NEXT:    [[R:%.*]] = icmp eq i8 [[M]], -84
1086; CHECK-NEXT:    ret i1 [[R]]
1087;
1088  %m = mul nsw i8 %x, -42
1089  %r = icmp eq i8 %m, -84
1090  ret i1 %r
1091}
1092
1093; Don't crash trying to div/rem-by-zero.
1094
1095define i1 @mul_nsw_by_zero(i8 %x) {
1096; CHECK-LABEL: @mul_nsw_by_zero(
1097; CHECK-NEXT:  bb1:
1098; CHECK-NEXT:    br label [[BB3:%.*]]
1099; CHECK:       bb2:
1100; CHECK-NEXT:    ret i1 false
1101; CHECK:       bb3:
1102; CHECK-NEXT:    br label [[BB2:%.*]]
1103;
1104bb1:
1105  br label %bb3
1106bb2:
1107  %r = icmp eq i8 %m, 45
1108  ret i1 %r
1109bb3:
1110  %m = mul nsw i8 %x, 0
1111  br label %bb2
1112}
1113
1114; Don't crash trying to div/rem-by-zero.
1115
1116define i1 @mul_nuw_by_zero(i8 %x) {
1117; CHECK-LABEL: @mul_nuw_by_zero(
1118; CHECK-NEXT:  bb1:
1119; CHECK-NEXT:    br label [[BB3:%.*]]
1120; CHECK:       bb2:
1121; CHECK-NEXT:    ret i1 false
1122; CHECK:       bb3:
1123; CHECK-NEXT:    br label [[BB2:%.*]]
1124;
1125bb1:
1126  br label %bb3
1127bb2:
1128  %r = icmp eq i8 %m, 45
1129  ret i1 %r
1130bb3:
1131  %m = mul nuw i8 %x, 0
1132  br label %bb2
1133}
1134
1135
1136define <2 x i1> @heterogeneous_constvector(<2 x i8> %x) {
1137; CHECK-LABEL: @heterogeneous_constvector(
1138; CHECK-NEXT:    ret <2 x i1> zeroinitializer
1139;
1140  %c = icmp ult <2 x i8> %x, <i8 undef, i8 poison>
1141  ret <2 x i1> %c
1142}
1143
1144define i1 @icmp_eq_constant_range_attr(i8 range(i8 0, 10) %i) {
1145; CHECK-LABEL: @icmp_eq_constant_range_attr(
1146; CHECK-NEXT:    ret i1 false
1147;
1148  %cmp = icmp eq i8 %i, 10
1149  ret i1 %cmp
1150}
1151
1152define i1 @neg_icmp_eq_constant_range_attr(i8 range(i8 0, 11) %i) {
1153; CHECK-LABEL: @neg_icmp_eq_constant_range_attr(
1154; CHECK-NEXT:    [[CMP:%.*]] = icmp eq i8 [[I:%.*]], 10
1155; CHECK-NEXT:    ret i1 [[CMP]]
1156;
1157  %cmp = icmp eq i8 %i, 10
1158  ret i1 %cmp
1159}
1160
1161declare range(i8 1, 0) i8 @returns_non_ten_range_helper()
1162declare range(i8 -1, 1) i8 @returns_contain_ten_range_helper()
1163
1164define i1 @icmp_eq_constant_range_return() {
1165; CHECK-LABEL: @icmp_eq_constant_range_return(
1166; CHECK-NEXT:    [[I:%.*]] = call i8 @returns_non_ten_range_helper()
1167; CHECK-NEXT:    [[CMP:%.*]] = icmp eq i8 [[I]], 10
1168; CHECK-NEXT:    ret i1 [[CMP]]
1169;
1170  %i = call i8 @returns_non_ten_range_helper()
1171  %cmp = icmp eq i8 %i, 10
1172  ret i1 %cmp
1173}
1174
1175define i1 @neg_icmp_eq_constant_range_return() {
1176; CHECK-LABEL: @neg_icmp_eq_constant_range_return(
1177; CHECK-NEXT:    [[I:%.*]] = call i8 @returns_contain_ten_range_helper()
1178; CHECK-NEXT:    ret i1 false
1179;
1180  %i = call i8 @returns_contain_ten_range_helper()
1181  %cmp = icmp eq i8 %i, 10
1182  ret i1 %cmp
1183}
1184
1185declare i8 @returns_i8_helper()
1186
1187define i1 @icmp_eq_constant_range_call() {
1188; CHECK-LABEL: @icmp_eq_constant_range_call(
1189; CHECK-NEXT:    [[I:%.*]] = call range(i8 0, 10) i8 @returns_i8_helper()
1190; CHECK-NEXT:    ret i1 false
1191;
1192  %i = call range(i8 0, 10) i8 @returns_i8_helper()
1193  %cmp = icmp eq i8 %i, 10
1194  ret i1 %cmp
1195}
1196
1197define i1 @neg_icmp_eq_constant_range_call() {
1198; CHECK-LABEL: @neg_icmp_eq_constant_range_call(
1199; CHECK-NEXT:    [[I:%.*]] = call range(i8 0, 11) i8 @returns_i8_helper()
1200; CHECK-NEXT:    [[CMP:%.*]] = icmp eq i8 [[I]], 10
1201; CHECK-NEXT:    ret i1 [[CMP]]
1202;
1203  %i = call range(i8 0, 11) i8 @returns_i8_helper()
1204  %cmp = icmp eq i8 %i, 10
1205  ret i1 %cmp
1206}
1207
1208define <2 x i1> @icmp_eq_constant_range_attr_vec(<2 x i8> range(i8 0, 10) %i) {
1209; CHECK-LABEL: @icmp_eq_constant_range_attr_vec(
1210; CHECK-NEXT:    ret <2 x i1> zeroinitializer
1211;
1212  %cmp = icmp eq <2 x i8> %i, <i8 10, i8 10>
1213  ret <2 x i1> %cmp
1214}
1215
1216define <2 x i1> @neg_icmp_eq_constant_range_attr_vec(<2 x i8> range(i8 0, 11) %i) {
1217; CHECK-LABEL: @neg_icmp_eq_constant_range_attr_vec(
1218; CHECK-NEXT:    [[CMP:%.*]] = icmp eq <2 x i8> [[I:%.*]], splat (i8 10)
1219; CHECK-NEXT:    ret <2 x i1> [[CMP]]
1220;
1221  %cmp = icmp eq <2 x i8> %i, <i8 10, i8 10>
1222  ret <2 x i1> %cmp
1223}
1224
1225declare range(i8 0, 10) <2 x i8> @returns_non_ten_range_helper_vec()
1226declare range(i8 0, 11) <2 x i8> @returns_contain_ten_range_helper_vec()
1227
1228define <2 x i1> @icmp_eq_constant_range_return_vec() {
1229; CHECK-LABEL: @icmp_eq_constant_range_return_vec(
1230; CHECK-NEXT:    [[I:%.*]] = call <2 x i8> @returns_non_ten_range_helper_vec()
1231; CHECK-NEXT:    ret <2 x i1> zeroinitializer
1232;
1233  %i = call <2 x i8> @returns_non_ten_range_helper_vec()
1234  %cmp = icmp eq <2 x i8> %i, <i8 10, i8 10>
1235  ret <2 x i1> %cmp
1236}
1237
1238define <2 x i1> @neg_icmp_eq_constant_range_return_vec() {
1239; CHECK-LABEL: @neg_icmp_eq_constant_range_return_vec(
1240; CHECK-NEXT:    [[I:%.*]] = call <2 x i8> @returns_contain_ten_range_helper_vec()
1241; CHECK-NEXT:    [[CMP:%.*]] = icmp eq <2 x i8> [[I]], splat (i8 10)
1242; CHECK-NEXT:    ret <2 x i1> [[CMP]]
1243;
1244  %i = call <2 x i8> @returns_contain_ten_range_helper_vec()
1245  %cmp = icmp eq <2 x i8> %i, <i8 10, i8 10>
1246  ret <2 x i1> %cmp
1247}
1248
1249declare <2 x i8> @returns_i8_helper_vec()
1250
1251define <2 x i1> @icmp_eq_constant_range_call_vec() {
1252; CHECK-LABEL: @icmp_eq_constant_range_call_vec(
1253; CHECK-NEXT:    [[I:%.*]] = call range(i8 0, 10) <2 x i8> @returns_i8_helper_vec()
1254; CHECK-NEXT:    ret <2 x i1> zeroinitializer
1255;
1256  %i = call range(i8 0, 10) <2 x i8> @returns_i8_helper_vec()
1257  %cmp = icmp eq <2 x i8> %i, <i8 10, i8 10>
1258  ret <2 x i1> %cmp
1259}
1260
1261define <2 x i1> @neg_icmp_eq_constant_range_call_vec() {
1262; CHECK-LABEL: @neg_icmp_eq_constant_range_call_vec(
1263; CHECK-NEXT:    [[I:%.*]] = call range(i8 0, 11) <2 x i8> @returns_i8_helper_vec()
1264; CHECK-NEXT:    [[CMP:%.*]] = icmp eq <2 x i8> [[I]], splat (i8 10)
1265; CHECK-NEXT:    ret <2 x i1> [[CMP]]
1266;
1267  %i = call range(i8 0, 11) <2 x i8> @returns_i8_helper_vec()
1268  %cmp = icmp eq <2 x i8> %i, <i8 10, i8 10>
1269  ret <2 x i1> %cmp
1270}
1271