InstCombine: Simplify FoldICmpCstShrCst
[oota-llvm.git] / test / Transforms / InstCombine / icmp-shr.ll
1 ; RUN: opt < %s -instcombine -S | FileCheck %s
2
3 target 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
7 define 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
15 define 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
23 define 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
31 define 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
39 define 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
47 define 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
55 define 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
63 define 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
71 define 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
79 define 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
87 define 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
95 define 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
103 define 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
111 define 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
119 define 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
127 define 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
135 define 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
143 define 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
151 define 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
159 define 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
167 define 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
175 define 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
183 define 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
191 define 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
199 define 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
207 define 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
215 define 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
223 define 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
231 define 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
239 define 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
247 define 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
255 define 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
263 define 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
271 define 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
279 define 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
287 define 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
295 define 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
303 define 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
311 define 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
319 define 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
327 define 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
335 define 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
343 define 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
351 define 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
366 define 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
374 define i1 @PR21222(i32 %B) {
375   %shr = ashr i32 -93, %B
376   %cmp = icmp eq i32 %shr, -2
377   ret i1 %cmp
378 }