1; NOTE: Assertions have been autogenerated by utils/update_test_checks.py
2; RUN: opt < %s -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
6define i1 @lshr_eq_msb_low_last_zero(i8 %a) {
7; CHECK-LABEL: @lshr_eq_msb_low_last_zero(
8; CHECK-NEXT:    [[CMP:%.*]] = icmp ugt i8 %a, 6
9; CHECK-NEXT:    ret i1 [[CMP]]
10;
11  %shr = lshr i8 127, %a
12  %cmp = icmp eq i8 %shr, 0
13  ret i1 %cmp
14}
15
16define <2 x i1> @lshr_eq_msb_low_last_zero_vec(<2 x i8> %a) {
17; CHECK-LABEL: @lshr_eq_msb_low_last_zero_vec(
18; CHECK-NEXT:    [[CMP:%.*]] = icmp ugt <2 x i8> %a, <i8 6, i8 6>
19; CHECK-NEXT:    ret <2 x i1> [[CMP]]
20;
21  %shr = lshr <2 x i8> <i8 127, i8 127>, %a
22  %cmp = icmp eq <2 x i8> %shr, zeroinitializer
23  ret <2 x i1> %cmp
24}
25
26define i1 @ashr_eq_msb_low_second_zero(i8 %a) {
27; CHECK-LABEL: @ashr_eq_msb_low_second_zero(
28; CHECK-NEXT:    [[CMP:%.*]] = icmp ugt i8 %a, 6
29; CHECK-NEXT:    ret i1 [[CMP]]
30;
31  %shr = ashr i8 127, %a
32  %cmp = icmp eq i8 %shr, 0
33  ret i1 %cmp
34}
35
36define i1 @lshr_ne_msb_low_last_zero(i8 %a) {
37; CHECK-LABEL: @lshr_ne_msb_low_last_zero(
38; CHECK-NEXT:    [[CMP:%.*]] = icmp ult i8 %a, 7
39; CHECK-NEXT:    ret i1 [[CMP]]
40;
41  %shr = lshr i8 127, %a
42  %cmp = icmp ne i8 %shr, 0
43  ret i1 %cmp
44}
45
46define i1 @ashr_ne_msb_low_second_zero(i8 %a) {
47; CHECK-LABEL: @ashr_ne_msb_low_second_zero(
48; CHECK-NEXT:    [[CMP:%.*]] = icmp ult i8 %a, 7
49; CHECK-NEXT:    ret i1 [[CMP]]
50;
51  %shr = ashr i8 127, %a
52  %cmp = icmp ne i8 %shr, 0
53  ret i1 %cmp
54}
55
56define i1 @ashr_eq_both_equal(i8 %a) {
57; CHECK-LABEL: @ashr_eq_both_equal(
58; CHECK-NEXT:    [[CMP:%.*]] = icmp eq i8 %a, 0
59; CHECK-NEXT:    ret i1 [[CMP]]
60;
61  %shr = ashr i8 128, %a
62  %cmp = icmp eq i8 %shr, 128
63  ret i1 %cmp
64}
65
66define i1 @ashr_ne_both_equal(i8 %a) {
67; CHECK-LABEL: @ashr_ne_both_equal(
68; CHECK-NEXT:    [[CMP:%.*]] = icmp ne i8 %a, 0
69; CHECK-NEXT:    ret i1 [[CMP]]
70;
71  %shr = ashr i8 128, %a
72  %cmp = icmp ne i8 %shr, 128
73  ret i1 %cmp
74}
75
76define i1 @lshr_eq_both_equal(i8 %a) {
77; CHECK-LABEL: @lshr_eq_both_equal(
78; CHECK-NEXT:    [[CMP:%.*]] = icmp eq i8 %a, 0
79; CHECK-NEXT:    ret i1 [[CMP]]
80;
81  %shr = lshr i8 127, %a
82  %cmp = icmp eq i8 %shr, 127
83  ret i1 %cmp
84}
85
86define i1 @lshr_ne_both_equal(i8 %a) {
87; CHECK-LABEL: @lshr_ne_both_equal(
88; CHECK-NEXT:    [[CMP:%.*]] = icmp ne i8 %a, 0
89; CHECK-NEXT:    ret i1 [[CMP]]
90;
91  %shr = lshr i8 127, %a
92  %cmp = icmp ne i8 %shr, 127
93  ret i1 %cmp
94}
95
96define i1 @exact_ashr_eq_both_equal(i8 %a) {
97; CHECK-LABEL: @exact_ashr_eq_both_equal(
98; CHECK-NEXT:    [[CMP:%.*]] = icmp eq i8 %a, 0
99; CHECK-NEXT:    ret i1 [[CMP]]
100;
101  %shr = ashr exact i8 128, %a
102  %cmp = icmp eq i8 %shr, 128
103  ret i1 %cmp
104}
105
106define i1 @exact_ashr_ne_both_equal(i8 %a) {
107; CHECK-LABEL: @exact_ashr_ne_both_equal(
108; CHECK-NEXT:    [[CMP:%.*]] = icmp ne i8 %a, 0
109; CHECK-NEXT:    ret i1 [[CMP]]
110;
111  %shr = ashr exact i8 128, %a
112  %cmp = icmp ne i8 %shr, 128
113  ret i1 %cmp
114}
115
116define i1 @exact_lshr_eq_both_equal(i8 %a) {
117; CHECK-LABEL: @exact_lshr_eq_both_equal(
118; CHECK-NEXT:    [[CMP:%.*]] = icmp eq i8 %a, 0
119; CHECK-NEXT:    ret i1 [[CMP]]
120;
121  %shr = lshr exact i8 126, %a
122  %cmp = icmp eq i8 %shr, 126
123  ret i1 %cmp
124}
125
126define i1 @exact_lshr_ne_both_equal(i8 %a) {
127; CHECK-LABEL: @exact_lshr_ne_both_equal(
128; CHECK-NEXT:    [[CMP:%.*]] = icmp ne i8 %a, 0
129; CHECK-NEXT:    ret i1 [[CMP]]
130;
131  %shr = lshr exact i8 126, %a
132  %cmp = icmp ne i8 %shr, 126
133  ret i1 %cmp
134}
135
136define i1 @exact_lshr_eq_opposite_msb(i8 %a) {
137; CHECK-LABEL: @exact_lshr_eq_opposite_msb(
138; CHECK-NEXT:    [[CMP:%.*]] = icmp eq i8 %a, 7
139; CHECK-NEXT:    ret i1 [[CMP]]
140;
141  %shr = lshr exact i8 -128, %a
142  %cmp = icmp eq i8 %shr, 1
143  ret i1 %cmp
144}
145
146define i1 @lshr_eq_opposite_msb(i8 %a) {
147; CHECK-LABEL: @lshr_eq_opposite_msb(
148; CHECK-NEXT:    [[CMP:%.*]] = icmp eq i8 %a, 7
149; CHECK-NEXT:    ret i1 [[CMP]]
150;
151  %shr = lshr i8 -128, %a
152  %cmp = icmp eq i8 %shr, 1
153  ret i1 %cmp
154}
155
156define i1 @exact_lshr_ne_opposite_msb(i8 %a) {
157; CHECK-LABEL: @exact_lshr_ne_opposite_msb(
158; CHECK-NEXT:    [[CMP:%.*]] = icmp ne i8 %a, 7
159; CHECK-NEXT:    ret i1 [[CMP]]
160;
161  %shr = lshr exact i8 -128, %a
162  %cmp = icmp ne i8 %shr, 1
163  ret i1 %cmp
164}
165
166define i1 @lshr_ne_opposite_msb(i8 %a) {
167; CHECK-LABEL: @lshr_ne_opposite_msb(
168; CHECK-NEXT:    [[CMP:%.*]] = icmp ne i8 %a, 7
169; CHECK-NEXT:    ret i1 [[CMP]]
170;
171  %shr = lshr i8 -128, %a
172  %cmp = icmp ne i8 %shr, 1
173  ret i1 %cmp
174}
175
176define i1 @exact_ashr_eq(i8 %a) {
177; CHECK-LABEL: @exact_ashr_eq(
178; CHECK-NEXT:    [[CMP:%.*]] = icmp eq i8 %a, 7
179; CHECK-NEXT:    ret i1 [[CMP]]
180;
181  %shr = ashr exact i8 -128, %a
182  %cmp = icmp eq i8 %shr, -1
183  ret i1 %cmp
184}
185
186define i1 @exact_ashr_ne(i8 %a) {
187; CHECK-LABEL: @exact_ashr_ne(
188; CHECK-NEXT:    [[CMP:%.*]] = icmp ne i8 %a, 7
189; CHECK-NEXT:    ret i1 [[CMP]]
190;
191  %shr = ashr exact i8 -128, %a
192  %cmp = icmp ne i8 %shr, -1
193  ret i1 %cmp
194}
195
196define i1 @exact_lshr_eq(i8 %a) {
197; CHECK-LABEL: @exact_lshr_eq(
198; CHECK-NEXT:    [[CMP:%.*]] = icmp eq i8 %a, 2
199; CHECK-NEXT:    ret i1 [[CMP]]
200;
201  %shr = lshr exact i8 4, %a
202  %cmp = icmp eq i8 %shr, 1
203  ret i1 %cmp
204}
205
206define i1 @exact_lshr_ne(i8 %a) {
207; CHECK-LABEL: @exact_lshr_ne(
208; CHECK-NEXT:    [[CMP:%.*]] = icmp ne i8 %a, 2
209; CHECK-NEXT:    ret i1 [[CMP]]
210;
211  %shr = lshr exact i8 4, %a
212  %cmp = icmp ne i8 %shr, 1
213  ret i1 %cmp
214}
215
216define i1 @nonexact_ashr_eq(i8 %a) {
217; CHECK-LABEL: @nonexact_ashr_eq(
218; CHECK-NEXT:    [[CMP:%.*]] = icmp eq i8 %a, 7
219; CHECK-NEXT:    ret i1 [[CMP]]
220;
221  %shr = ashr i8 -128, %a
222  %cmp = icmp eq i8 %shr, -1
223  ret i1 %cmp
224}
225
226define i1 @nonexact_ashr_ne(i8 %a) {
227; CHECK-LABEL: @nonexact_ashr_ne(
228; CHECK-NEXT:    [[CMP:%.*]] = icmp ne i8 %a, 7
229; CHECK-NEXT:    ret i1 [[CMP]]
230;
231  %shr = ashr i8 -128, %a
232  %cmp = icmp ne i8 %shr, -1
233  ret i1 %cmp
234}
235
236define i1 @nonexact_lshr_eq(i8 %a) {
237; CHECK-LABEL: @nonexact_lshr_eq(
238; CHECK-NEXT:    [[CMP:%.*]] = icmp eq i8 %a, 2
239; CHECK-NEXT:    ret i1 [[CMP]]
240;
241  %shr = lshr i8 4, %a
242  %cmp = icmp eq i8 %shr, 1
243  ret i1 %cmp
244}
245
246define i1 @nonexact_lshr_ne(i8 %a) {
247; CHECK-LABEL: @nonexact_lshr_ne(
248; CHECK-NEXT:    [[CMP:%.*]] = icmp ne i8 %a, 2
249; CHECK-NEXT:    ret i1 [[CMP]]
250;
251  %shr = lshr i8 4, %a
252  %cmp = icmp ne i8 %shr, 1
253  ret i1 %cmp
254}
255
256define i1 @exact_lshr_eq_exactdiv(i8 %a) {
257; CHECK-LABEL: @exact_lshr_eq_exactdiv(
258; CHECK-NEXT:    [[CMP:%.*]] = icmp eq i8 %a, 4
259; CHECK-NEXT:    ret i1 [[CMP]]
260;
261  %shr = lshr exact i8 80, %a
262  %cmp = icmp eq i8 %shr, 5
263  ret i1 %cmp
264}
265
266define i1 @exact_lshr_ne_exactdiv(i8 %a) {
267; CHECK-LABEL: @exact_lshr_ne_exactdiv(
268; CHECK-NEXT:    [[CMP:%.*]] = icmp ne i8 %a, 4
269; CHECK-NEXT:    ret i1 [[CMP]]
270;
271  %shr = lshr exact i8 80, %a
272  %cmp = icmp ne i8 %shr, 5
273  ret i1 %cmp
274}
275
276define i1 @nonexact_lshr_eq_exactdiv(i8 %a) {
277; CHECK-LABEL: @nonexact_lshr_eq_exactdiv(
278; CHECK-NEXT:    [[CMP:%.*]] = icmp eq i8 %a, 4
279; CHECK-NEXT:    ret i1 [[CMP]]
280;
281  %shr = lshr i8 80, %a
282  %cmp = icmp eq i8 %shr, 5
283  ret i1 %cmp
284}
285
286define i1 @nonexact_lshr_ne_exactdiv(i8 %a) {
287; CHECK-LABEL: @nonexact_lshr_ne_exactdiv(
288; CHECK-NEXT:    [[CMP:%.*]] = icmp ne i8 %a, 4
289; CHECK-NEXT:    ret i1 [[CMP]]
290;
291  %shr = lshr i8 80, %a
292  %cmp = icmp ne i8 %shr, 5
293  ret i1 %cmp
294}
295
296define i1 @exact_ashr_eq_exactdiv(i8 %a) {
297; CHECK-LABEL: @exact_ashr_eq_exactdiv(
298; CHECK-NEXT:    [[CMP:%.*]] = icmp eq i8 %a, 4
299; CHECK-NEXT:    ret i1 [[CMP]]
300;
301  %shr = ashr exact i8 -80, %a
302  %cmp = icmp eq i8 %shr, -5
303  ret i1 %cmp
304}
305
306define i1 @exact_ashr_ne_exactdiv(i8 %a) {
307; CHECK-LABEL: @exact_ashr_ne_exactdiv(
308; CHECK-NEXT:    [[CMP:%.*]] = icmp ne i8 %a, 4
309; CHECK-NEXT:    ret i1 [[CMP]]
310;
311  %shr = ashr exact i8 -80, %a
312  %cmp = icmp ne i8 %shr, -5
313  ret i1 %cmp
314}
315
316define i1 @nonexact_ashr_eq_exactdiv(i8 %a) {
317; CHECK-LABEL: @nonexact_ashr_eq_exactdiv(
318; CHECK-NEXT:    [[CMP:%.*]] = icmp eq i8 %a, 4
319; CHECK-NEXT:    ret i1 [[CMP]]
320;
321  %shr = ashr i8 -80, %a
322  %cmp = icmp eq i8 %shr, -5
323  ret i1 %cmp
324}
325
326define i1 @nonexact_ashr_ne_exactdiv(i8 %a) {
327; CHECK-LABEL: @nonexact_ashr_ne_exactdiv(
328; CHECK-NEXT:    [[CMP:%.*]] = icmp ne i8 %a, 4
329; CHECK-NEXT:    ret i1 [[CMP]]
330;
331  %shr = ashr i8 -80, %a
332  %cmp = icmp ne i8 %shr, -5
333  ret i1 %cmp
334}
335
336define i1 @exact_lshr_eq_noexactdiv(i8 %a) {
337; CHECK-LABEL: @exact_lshr_eq_noexactdiv(
338; CHECK-NEXT:    ret i1 false
339;
340  %shr = lshr exact i8 80, %a
341  %cmp = icmp eq i8 %shr, 31
342  ret i1 %cmp
343}
344
345define i1 @exact_lshr_ne_noexactdiv(i8 %a) {
346; CHECK-LABEL: @exact_lshr_ne_noexactdiv(
347; CHECK-NEXT:    ret i1 true
348;
349  %shr = lshr exact i8 80, %a
350  %cmp = icmp ne i8 %shr, 31
351  ret i1 %cmp
352}
353
354define i1 @nonexact_lshr_eq_noexactdiv(i8 %a) {
355; CHECK-LABEL: @nonexact_lshr_eq_noexactdiv(
356; CHECK-NEXT:    ret i1 false
357;
358  %shr = lshr i8 80, %a
359  %cmp = icmp eq i8 %shr, 31
360  ret i1 %cmp
361}
362
363define i1 @nonexact_lshr_ne_noexactdiv(i8 %a) {
364; CHECK-LABEL: @nonexact_lshr_ne_noexactdiv(
365; CHECK-NEXT:    ret i1 true
366;
367  %shr = lshr i8 80, %a
368  %cmp = icmp ne i8 %shr, 31
369  ret i1 %cmp
370}
371
372define i1 @exact_ashr_eq_noexactdiv(i8 %a) {
373; CHECK-LABEL: @exact_ashr_eq_noexactdiv(
374; CHECK-NEXT:    ret i1 false
375;
376  %shr = ashr exact i8 -80, %a
377  %cmp = icmp eq i8 %shr, -31
378  ret i1 %cmp
379}
380
381define i1 @exact_ashr_ne_noexactdiv(i8 %a) {
382; CHECK-LABEL: @exact_ashr_ne_noexactdiv(
383; CHECK-NEXT:    ret i1 true
384;
385  %shr = ashr exact i8 -80, %a
386  %cmp = icmp ne i8 %shr, -31
387  ret i1 %cmp
388}
389
390define i1 @nonexact_ashr_eq_noexactdiv(i8 %a) {
391; CHECK-LABEL: @nonexact_ashr_eq_noexactdiv(
392; CHECK-NEXT:    ret i1 false
393;
394  %shr = ashr i8 -80, %a
395  %cmp = icmp eq i8 %shr, -31
396  ret i1 %cmp
397}
398
399define i1 @nonexact_ashr_ne_noexactdiv(i8 %a) {
400; CHECK-LABEL: @nonexact_ashr_ne_noexactdiv(
401; CHECK-NEXT:    ret i1 true
402;
403  %shr = ashr i8 -80, %a
404  %cmp = icmp ne i8 %shr, -31
405  ret i1 %cmp
406}
407
408define i1 @nonexact_lshr_eq_noexactlog(i8 %a) {
409; CHECK-LABEL: @nonexact_lshr_eq_noexactlog(
410; CHECK-NEXT:    ret i1 false
411;
412  %shr = lshr i8 90, %a
413  %cmp = icmp eq i8 %shr, 30
414  ret i1 %cmp
415}
416
417define i1 @nonexact_lshr_ne_noexactlog(i8 %a) {
418; CHECK-LABEL: @nonexact_lshr_ne_noexactlog(
419; CHECK-NEXT:    ret i1 true
420;
421  %shr = lshr i8 90, %a
422  %cmp = icmp ne i8 %shr, 30
423  ret i1 %cmp
424}
425
426define i1 @nonexact_ashr_eq_noexactlog(i8 %a) {
427; CHECK-LABEL: @nonexact_ashr_eq_noexactlog(
428; CHECK-NEXT:    ret i1 false
429;
430  %shr = ashr i8 -90, %a
431  %cmp = icmp eq i8 %shr, -30
432  ret i1 %cmp
433}
434
435define i1 @nonexact_ashr_ne_noexactlog(i8 %a) {
436; CHECK-LABEL: @nonexact_ashr_ne_noexactlog(
437; CHECK-NEXT:    ret i1 true
438;
439  %shr = ashr i8 -90, %a
440  %cmp = icmp ne i8 %shr, -30
441  ret i1 %cmp
442}
443
444; Don't try to fold the entire body of function @PR20945 into a
445; single `ret i1 true` statement.
446; If %B is equal to 1, then this function would return false.
447; As a consequence, the instruction combiner is not allowed to fold %cmp
448; to 'true'. Instead, it should replace %cmp with a simpler comparison
449; between %B and 1.
450
451define i1 @PR20945(i32 %B) {
452; CHECK-LABEL: @PR20945(
453; CHECK-NEXT:    [[CMP:%.*]] = icmp ne i32 %B, 1
454; CHECK-NEXT:    ret i1 [[CMP]]
455;
456  %shr = ashr i32 -9, %B
457  %cmp = icmp ne i32 %shr, -5
458  ret i1 %cmp
459}
460
461define i1 @PR21222(i32 %B) {
462; CHECK-LABEL: @PR21222(
463; CHECK-NEXT:    [[CMP:%.*]] = icmp eq i32 %B, 6
464; CHECK-NEXT:    ret i1 [[CMP]]
465;
466  %shr = ashr i32 -93, %B
467  %cmp = icmp eq i32 %shr, -2
468  ret i1 %cmp
469}
470
471define i1 @PR24873(i64 %V) {
472; CHECK-LABEL: @PR24873(
473; CHECK-NEXT:    [[ICMP:%.*]] = icmp ugt i64 %V, 61
474; CHECK-NEXT:    ret i1 [[ICMP]]
475;
476  %ashr = ashr i64 -4611686018427387904, %V
477  %icmp = icmp eq i64 %ashr, -1
478  ret i1 %icmp
479}
480
481declare void @foo(i32)
482
483define i1 @exact_multiuse(i32 %x) {
484; CHECK-LABEL: @exact_multiuse(
485; CHECK-NEXT:    [[SH:%.*]] = lshr exact i32 %x, 7
486; CHECK-NEXT:    [[CMP:%.*]] = icmp eq i32 %x, 131072
487; CHECK-NEXT:    call void @foo(i32 [[SH]])
488; CHECK-NEXT:    ret i1 [[CMP]]
489;
490  %sh = lshr exact i32 %x, 7
491  %cmp = icmp eq i32 %sh, 1024
492  call void @foo(i32 %sh)
493  ret i1 %cmp
494}
495
496declare void @foo2(<2 x i32>)
497define <2 x i1> @exact_eq0_multiuse(<2 x i32> %x, <2 x i32> %y) {
498; CHECK-LABEL: @exact_eq0_multiuse(
499; CHECK-NEXT:    [[SH:%.*]] = ashr exact <2 x i32> %x, %y
500; CHECK-NEXT:    [[CMP:%.*]] = icmp eq <2 x i32> [[SH]], zeroinitializer
501; CHECK-NEXT:    call void @foo2(<2 x i32> [[SH]])
502; CHECK-NEXT:    ret <2 x i1> [[CMP]]
503;
504  %sh = ashr exact <2 x i32> %x, %y
505  %cmp = icmp eq <2 x i32> %sh, zeroinitializer
506  call void @foo2(<2 x i32> %sh)
507  ret <2 x i1> %cmp
508}
509
510