1; RUN: opt < %s -instcombine -S | FileCheck %s
2
3target 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"
4
5; CHECK-LABEL: @lshr_eq_msb_low_last_zero
6; CHECK-NEXT: icmp ugt i8 %a, 6
7define i1 @lshr_eq_msb_low_last_zero(i8 %a) {
8 %shr = lshr i8 127, %a
9 %cmp = icmp eq i8 %shr, 0
10 ret i1 %cmp
11}
12
13; CHECK-LABEL: @ashr_eq_msb_low_second_zero
14; CHECK-NEXT: icmp ugt i8 %a, 6
15define i1 @ashr_eq_msb_low_second_zero(i8 %a) {
16 %shr = ashr i8 127, %a
17 %cmp = icmp eq i8 %shr, 0
18 ret i1 %cmp
19}
20
21; CHECK-LABEL: @lshr_ne_msb_low_last_zero
22; CHECK-NEXT: icmp ult i8 %a, 7
23define i1 @lshr_ne_msb_low_last_zero(i8 %a) {
24 %shr = lshr i8 127, %a
25 %cmp = icmp ne i8 %shr, 0
26 ret i1 %cmp
27}
28
29; CHECK-LABEL: @ashr_ne_msb_low_second_zero
30; CHECK-NEXT: icmp ult i8 %a, 7
31define i1 @ashr_ne_msb_low_second_zero(i8 %a) {
32 %shr = ashr i8 127, %a
33 %cmp = icmp ne i8 %shr, 0
34 ret i1 %cmp
35}
36
37; CHECK-LABEL: @ashr_eq_both_equal
38; CHECK-NEXT: icmp eq i8 %a, 0
39define i1 @ashr_eq_both_equal(i8 %a) {
40 %shr = ashr i8 128, %a
41 %cmp = icmp eq i8 %shr, 128
42 ret i1 %cmp
43}
44
45; CHECK-LABEL: @ashr_ne_both_equal
46; CHECK-NEXT: icmp ne i8 %a, 0
47define i1 @ashr_ne_both_equal(i8 %a) {
48 %shr = ashr i8 128, %a
49 %cmp = icmp ne i8 %shr, 128
50 ret i1 %cmp
51}
52
53; CHECK-LABEL: @lshr_eq_both_equal
54; CHECK-NEXT: icmp eq i8 %a, 0
55define i1 @lshr_eq_both_equal(i8 %a) {
56 %shr = lshr i8 127, %a
57 %cmp = icmp eq i8 %shr, 127
58 ret i1 %cmp
59}
60
61; CHECK-LABEL: @lshr_ne_both_equal
62; CHECK-NEXT: icmp ne i8 %a, 0
63define i1 @lshr_ne_both_equal(i8 %a) {
64 %shr = lshr i8 127, %a
65 %cmp = icmp ne i8 %shr, 127
66 ret i1 %cmp
67}
68
69; CHECK-LABEL: @exact_ashr_eq_both_equal
70; CHECK-NEXT: icmp eq i8 %a, 0
71define i1 @exact_ashr_eq_both_equal(i8 %a) {
72 %shr = ashr exact i8 128, %a
73 %cmp = icmp eq i8 %shr, 128
74 ret i1 %cmp
75}
76
77; CHECK-LABEL: @exact_ashr_ne_both_equal
78; CHECK-NEXT: icmp ne i8 %a, 0
79define i1 @exact_ashr_ne_both_equal(i8 %a) {
80 %shr = ashr exact i8 128, %a
81 %cmp = icmp ne i8 %shr, 128
82 ret i1 %cmp
83}
84
85; CHECK-LABEL: @exact_lshr_eq_both_equal
86; CHECK-NEXT: icmp eq i8 %a, 0
87define i1 @exact_lshr_eq_both_equal(i8 %a) {
88 %shr = lshr exact i8 126, %a
89 %cmp = icmp eq i8 %shr, 126
90 ret i1 %cmp
91}
92
93; CHECK-LABEL: @exact_lshr_ne_both_equal
94; CHECK-NEXT: icmp ne i8 %a, 0
95define i1 @exact_lshr_ne_both_equal(i8 %a) {
96 %shr = lshr exact i8 126, %a
97 %cmp = icmp ne i8 %shr, 126
98 ret i1 %cmp
99}
100
101; CHECK-LABEL: @exact_lshr_eq_opposite_msb
102; CHECK-NEXT: icmp eq i8 %a, 7
103define i1 @exact_lshr_eq_opposite_msb(i8 %a) {
104 %shr = lshr exact i8 -128, %a
105 %cmp = icmp eq i8 %shr, 1
106 ret i1 %cmp
107}
108
109; CHECK-LABEL: @lshr_eq_opposite_msb
110; CHECK-NEXT: icmp eq i8 %a, 7
111define i1 @lshr_eq_opposite_msb(i8 %a) {
112 %shr = lshr i8 -128, %a
113 %cmp = icmp eq i8 %shr, 1
114 ret i1 %cmp
115}
116
117; CHECK-LABEL: @exact_lshr_ne_opposite_msb
118; CHECK-NEXT: icmp ne i8 %a, 7
119define i1 @exact_lshr_ne_opposite_msb(i8 %a) {
120 %shr = lshr exact i8 -128, %a
121 %cmp = icmp ne i8 %shr, 1
122 ret i1 %cmp
123}
124
125; CHECK-LABEL: @lshr_ne_opposite_msb
126; CHECK-NEXT: icmp ne i8 %a, 7
127define i1 @lshr_ne_opposite_msb(i8 %a) {
128 %shr = lshr i8 -128, %a
129 %cmp = icmp ne i8 %shr, 1
130 ret i1 %cmp
131}
132
133; CHECK-LABEL: @exact_ashr_eq
134; CHECK-NEXT: icmp eq i8 %a, 7
135define i1 @exact_ashr_eq(i8 %a) {
136 %shr = ashr exact i8 -128, %a
137 %cmp = icmp eq i8 %shr, -1
138 ret i1 %cmp
139}
140
141; CHECK-LABEL: @exact_ashr_ne
142; CHECK-NEXT: icmp ne i8 %a, 7
143define i1 @exact_ashr_ne(i8 %a) {
144 %shr = ashr exact i8 -128, %a
145 %cmp = icmp ne i8 %shr, -1
146 ret i1 %cmp
147}
148
149; CHECK-LABEL: @exact_lshr_eq
150; CHECK-NEXT: icmp eq i8 %a, 2
151define i1 @exact_lshr_eq(i8 %a) {
152 %shr = lshr exact i8 4, %a
153 %cmp = icmp eq i8 %shr, 1
154 ret i1 %cmp
155}
156
157; CHECK-LABEL: @exact_lshr_ne
158; CHECK-NEXT: icmp ne i8 %a, 2
159define i1 @exact_lshr_ne(i8 %a) {
160 %shr = lshr exact i8 4, %a
161 %cmp = icmp ne i8 %shr, 1
162 ret i1 %cmp
163}
164
165; CHECK-LABEL: @nonexact_ashr_eq
166; CHECK-NEXT: icmp eq i8 %a, 7
167define i1 @nonexact_ashr_eq(i8 %a) {
168 %shr = ashr i8 -128, %a
169 %cmp = icmp eq i8 %shr, -1
170 ret i1 %cmp
171}
172
173; CHECK-LABEL: @nonexact_ashr_ne
174; CHECK-NEXT: icmp ne i8 %a, 7
175define i1 @nonexact_ashr_ne(i8 %a) {
176 %shr = ashr i8 -128, %a
177 %cmp = icmp ne i8 %shr, -1
178 ret i1 %cmp
179}
180
181; CHECK-LABEL: @nonexact_lshr_eq
182; CHECK-NEXT: icmp eq i8 %a, 2
183define i1 @nonexact_lshr_eq(i8 %a) {
184 %shr = lshr i8 4, %a
185 %cmp = icmp eq i8 %shr, 1
186 ret i1 %cmp
187}
188
189; CHECK-LABEL: @nonexact_lshr_ne
190; CHECK-NEXT: icmp ne i8 %a, 2
191define i1 @nonexact_lshr_ne(i8 %a) {
192 %shr = lshr i8 4, %a
193 %cmp = icmp ne i8 %shr, 1
194 ret i1 %cmp
195}
196
197; CHECK-LABEL: @exact_lshr_eq_exactdiv
198; CHECK-NEXT: icmp eq i8 %a, 4
199define i1 @exact_lshr_eq_exactdiv(i8 %a) {
200 %shr = lshr exact i8 80, %a
201 %cmp = icmp eq i8 %shr, 5
202 ret i1 %cmp
203}
204
205; CHECK-LABEL: @exact_lshr_ne_exactdiv
206; CHECK-NEXT: icmp ne i8 %a, 4
207define i1 @exact_lshr_ne_exactdiv(i8 %a) {
208 %shr = lshr exact i8 80, %a
209 %cmp = icmp ne i8 %shr, 5
210 ret i1 %cmp
211}
212
213; CHECK-LABEL: @nonexact_lshr_eq_exactdiv
214; CHECK-NEXT: icmp eq i8 %a, 4
215define i1 @nonexact_lshr_eq_exactdiv(i8 %a) {
216 %shr = lshr i8 80, %a
217 %cmp = icmp eq i8 %shr, 5
218 ret i1 %cmp
219}
220
221; CHECK-LABEL: @nonexact_lshr_ne_exactdiv
222; CHECK-NEXT: icmp ne i8 %a, 4
223define i1 @nonexact_lshr_ne_exactdiv(i8 %a) {
224 %shr = lshr i8 80, %a
225 %cmp = icmp ne i8 %shr, 5
226 ret i1 %cmp
227}
228
229; CHECK-LABEL: @exact_ashr_eq_exactdiv
230; CHECK-NEXT: icmp eq i8 %a, 4
231define i1 @exact_ashr_eq_exactdiv(i8 %a) {
232 %shr = ashr exact i8 -80, %a
233 %cmp = icmp eq i8 %shr, -5
234 ret i1 %cmp
235}
236
237; CHECK-LABEL: @exact_ashr_ne_exactdiv
238; CHECK-NEXT: icmp ne i8 %a, 4
239define i1 @exact_ashr_ne_exactdiv(i8 %a) {
240 %shr = ashr exact i8 -80, %a
241 %cmp = icmp ne i8 %shr, -5
242 ret i1 %cmp
243}
244
245; CHECK-LABEL: @nonexact_ashr_eq_exactdiv
246; CHECK-NEXT: icmp eq i8 %a, 4
247define i1 @nonexact_ashr_eq_exactdiv(i8 %a) {
248 %shr = ashr i8 -80, %a
249 %cmp = icmp eq i8 %shr, -5
250 ret i1 %cmp
251}
252
253; CHECK-LABEL: @nonexact_ashr_ne_exactdiv
254; CHECK-NEXT: icmp ne i8 %a, 4
255define i1 @nonexact_ashr_ne_exactdiv(i8 %a) {
256 %shr = ashr i8 -80, %a
257 %cmp = icmp ne i8 %shr, -5
258 ret i1 %cmp
259}
260
261; CHECK-LABEL: @exact_lshr_eq_noexactdiv
262; CHECK-NEXT: ret i1 false
263define i1 @exact_lshr_eq_noexactdiv(i8 %a) {
264 %shr = lshr exact i8 80, %a
265 %cmp = icmp eq i8 %shr, 31
266 ret i1 %cmp
267}
268
269; CHECK-LABEL: @exact_lshr_ne_noexactdiv
270; CHECK-NEXT: ret i1 true
271define i1 @exact_lshr_ne_noexactdiv(i8 %a) {
272 %shr = lshr exact i8 80, %a
273 %cmp = icmp ne i8 %shr, 31
274 ret i1 %cmp
275}
276
277; CHECK-LABEL: @nonexact_lshr_eq_noexactdiv
278; CHECK-NEXT: ret i1 false
279define i1 @nonexact_lshr_eq_noexactdiv(i8 %a) {
280 %shr = lshr i8 80, %a
281 %cmp = icmp eq i8 %shr, 31
282 ret i1 %cmp
283}
284
285; CHECK-LABEL: @nonexact_lshr_ne_noexactdiv
286; CHECK-NEXT: ret i1 true
287define i1 @nonexact_lshr_ne_noexactdiv(i8 %a) {
288 %shr = lshr i8 80, %a
289 %cmp = icmp ne i8 %shr, 31
290 ret i1 %cmp
291}
292
293; CHECK-LABEL: @exact_ashr_eq_noexactdiv
294; CHECK-NEXT: ret i1 false
295define i1 @exact_ashr_eq_noexactdiv(i8 %a) {
296 %shr = ashr exact i8 -80, %a
297 %cmp = icmp eq i8 %shr, -31
298 ret i1 %cmp
299}
300
301; CHECK-LABEL: @exact_ashr_ne_noexactdiv
302; CHECK-NEXT: ret i1 true
303define i1 @exact_ashr_ne_noexactdiv(i8 %a) {
304 %shr = ashr exact i8 -80, %a
305 %cmp = icmp ne i8 %shr, -31
306 ret i1 %cmp
307}
308
309; CHECK-LABEL: @nonexact_ashr_eq_noexactdiv
310; CHECK-NEXT: ret i1 false
311define i1 @nonexact_ashr_eq_noexactdiv(i8 %a) {
312 %shr = ashr i8 -80, %a
313 %cmp = icmp eq i8 %shr, -31
314 ret i1 %cmp
315}
316
317; CHECK-LABEL: @nonexact_ashr_ne_noexactdiv
318; CHECK-NEXT: ret i1 true
319define i1 @nonexact_ashr_ne_noexactdiv(i8 %a) {
320 %shr = ashr i8 -80, %a
321 %cmp = icmp ne i8 %shr, -31
322 ret i1 %cmp
323}
324
325; CHECK-LABEL: @nonexact_lshr_eq_noexactlog
326; CHECK-NEXT: ret i1 false
327define i1 @nonexact_lshr_eq_noexactlog(i8 %a) {
328 %shr = lshr i8 90, %a
329 %cmp = icmp eq i8 %shr, 30
330 ret i1 %cmp
331}
332
333; CHECK-LABEL: @nonexact_lshr_ne_noexactlog
334; CHECK-NEXT: ret i1 true
335define i1 @nonexact_lshr_ne_noexactlog(i8 %a) {
336 %shr = lshr i8 90, %a
337 %cmp = icmp ne i8 %shr, 30
338 ret i1 %cmp
339}
340
341; CHECK-LABEL: @nonexact_ashr_eq_noexactlog
342; CHECK-NEXT: ret i1 false
343define i1 @nonexact_ashr_eq_noexactlog(i8 %a) {
344 %shr = ashr i8 -90, %a
345 %cmp = icmp eq i8 %shr, -30
346 ret i1 %cmp
347}
348
349; CHECK-LABEL: @nonexact_ashr_ne_noexactlog
350; CHECK-NEXT: ret i1 true
351define i1 @nonexact_ashr_ne_noexactlog(i8 %a) {
352 %shr = ashr i8 -90, %a
353 %cmp = icmp ne i8 %shr, -30
354 ret i1 %cmp
355}
356
357; Don't try to fold the entire body of function @PR20945 into a
358; single `ret i1 true` statement.
359; If %B is equal to 1, then this function would return false.
360; As a consequence, the instruction combiner is not allowed to fold %cmp
361; to 'true'. Instead, it should replace %cmp with a simpler comparison
362; between %B and 1.
363
364; CHECK-LABEL: @PR20945(
365; CHECK: icmp ne i32 %B, 1
366define i1 @PR20945(i32 %B) {
367  %shr = ashr i32 -9, %B
368  %cmp = icmp ne i32 %shr, -5
369  ret i1 %cmp
370}
371
372; CHECK-LABEL: @PR21222
373; CHECK: icmp eq i32 %B, 6
374define i1 @PR21222(i32 %B) {
375  %shr = ashr i32 -93, %B
376  %cmp = icmp eq i32 %shr, -2
377  ret i1 %cmp
378}
379
380; CHECK-LABEL: @PR24873(
381; CHECK:      %[[icmp:.*]] = icmp ugt i64 %V, 61
382; CHECK-NEXT: ret i1 %[[icmp]]
383define i1 @PR24873(i64 %V) {
384  %ashr = ashr i64 -4611686018427387904, %V
385  %icmp = icmp eq i64 %ashr, -1
386  ret i1 %icmp
387}
388