[FastISel][AArch64] Fold Sign-/Zero-Extend into the shift immediate instruction.
[oota-llvm.git] / test / CodeGen / AArch64 / fast-isel-shift.ll
1 ; RUN: llc -fast-isel -fast-isel-abort -mtriple=arm64-apple-darwin -verify-machineinstrs < %s | FileCheck %s
2
3 ; CHECK-LABEL: lslv_i8
4 ; CHECK:       and [[REG1:w[0-9]+]], w1, #0xff
5 ; CHECK-NEXT:  lsl [[REG2:w[0-9]+]], w0, [[REG1]]
6 ; CHECK-NEXT:  and {{w[0-9]+}}, [[REG2]], #0xff
7 define zeroext i8 @lslv_i8(i8 %a, i8 %b) {
8   %1 = shl i8 %a, %b
9   ret i8 %1
10 }
11
12 ; CHECK-LABEL: lsl_i8
13 ; CHECK:       ubfiz {{w[0-9]*}}, {{w[0-9]*}}, #4, #4
14 define zeroext i8 @lsl_i8(i8 %a) {
15   %1 = shl i8 %a, 4
16   ret i8 %1
17 }
18
19 ; CHECK-LABEL: lsl_zext_i8_i16
20 ; CHECK:       ubfiz {{w[0-9]*}}, {{w[0-9]*}}, #4, #8
21 define zeroext i16 @lsl_zext_i8_i16(i8 %b) {
22   %1 = zext i8 %b to i16
23   %2 = shl i16 %1, 4
24   ret i16 %2
25 }
26
27 ; CHECK-LABEL: lsl_sext_i8_i16
28 ; CHECK:       sbfiz {{w[0-9]*}}, {{w[0-9]*}}, #4, #8
29 define signext i16 @lsl_sext_i8_i16(i8 %b) {
30   %1 = sext i8 %b to i16
31   %2 = shl i16 %1, 4
32   ret i16 %2
33 }
34
35 ; CHECK-LABEL: lsl_zext_i8_i32
36 ; CHECK:       ubfiz {{w[0-9]*}}, {{w[0-9]*}}, #4, #8
37 define i32 @lsl_zext_i8_i32(i8 %b) {
38   %1 = zext i8 %b to i32
39   %2 = shl i32 %1, 4
40   ret i32 %2
41 }
42
43 ; CHECK-LABEL: lsl_sext_i8_i32
44 ; CHECK:       sbfiz {{w[0-9]*}}, {{w[0-9]*}}, #4, #8
45 define i32 @lsl_sext_i8_i32(i8 %b) {
46   %1 = sext i8 %b to i32
47   %2 = shl i32 %1, 4
48   ret i32 %2
49 }
50
51 ; FIXME: Cannot test this yet, because the target-independent instruction
52 ; selector handles this.
53 ; CHECK-LABEL: lsl_zext_i8_i64
54 define i64 @lsl_zext_i8_i64(i8 %b) {
55   %1 = zext i8 %b to i64
56   %2 = shl i64 %1, 4
57   ret i64 %2
58 }
59
60 ; FIXME: Cannot test this yet, because the target-independent instruction
61 ; selector handles this.
62 ; CHECK-LABEL: lsl_sext_i8_i64
63 define i64 @lsl_sext_i8_i64(i8 %b) {
64   %1 = sext i8 %b to i64
65   %2 = shl i64 %1, 4
66   ret i64 %2
67 }
68
69 ; CHECK-LABEL: lslv_i16
70 ; CHECK:       and [[REG1:w[0-9]+]], w1, #0xffff
71 ; CHECK-NEXT:  lsl [[REG2:w[0-9]+]], w0, [[REG1]]
72 ; CHECK-NEXT:  and {{w[0-9]+}}, [[REG2]], #0xffff
73 define zeroext i16 @lslv_i16(i16 %a, i16 %b) {
74   %1 = shl i16 %a, %b
75   ret i16 %1
76 }
77
78 ; CHECK-LABEL: lsl_i16
79 ; CHECK:       ubfiz {{w[0-9]*}}, {{w[0-9]*}}, #8, #8
80 define zeroext i16 @lsl_i16(i16 %a) {
81   %1 = shl i16 %a, 8
82   ret i16 %1
83 }
84
85 ; CHECK-LABEL: lsl_zext_i16_i32
86 ; CHECK:       ubfiz {{w[0-9]*}}, {{w[0-9]*}}, #8, #16
87 define i32 @lsl_zext_i16_i32(i16 %b) {
88   %1 = zext i16 %b to i32
89   %2 = shl i32 %1, 8
90   ret i32 %2
91 }
92
93 ; CHECK-LABEL: lsl_sext_i16_i32
94 ; CHECK:       sbfiz {{w[0-9]*}}, {{w[0-9]*}}, #8, #16
95 define i32 @lsl_sext_i16_i32(i16 %b) {
96   %1 = sext i16 %b to i32
97   %2 = shl i32 %1, 8
98   ret i32 %2
99 }
100
101 ; FIXME: Cannot test this yet, because the target-independent instruction
102 ; selector handles this.
103 ; CHECK-LABEL: lsl_zext_i16_i64
104 define i64 @lsl_zext_i16_i64(i16 %b) {
105   %1 = zext i16 %b to i64
106   %2 = shl i64 %1, 8
107   ret i64 %2
108 }
109
110 ; FIXME: Cannot test this yet, because the target-independent instruction
111 ; selector handles this.
112 ; CHECK-LABEL: lsl_sext_i16_i64
113 define i64 @lsl_sext_i16_i64(i16 %b) {
114   %1 = sext i16 %b to i64
115   %2 = shl i64 %1, 8
116   ret i64 %2
117 }
118
119 ; CHECK-LABEL: lslv_i32
120 ; CHECK:       lsl {{w[0-9]*}}, w0, w1
121 define zeroext i32 @lslv_i32(i32 %a, i32 %b) {
122   %1 = shl i32 %a, %b
123   ret i32 %1
124 }
125
126 ; CHECK-LABEL: lsl_i32
127 ; CHECK:       lsl {{w[0-9]*}}, {{w[0-9]*}}, #16
128 define zeroext i32 @lsl_i32(i32 %a) {
129   %1 = shl i32 %a, 16
130   ret i32 %1
131 }
132
133 ; FIXME: Cannot test this yet, because the target-independent instruction
134 ; selector handles this.
135 ; CHECK-LABEL: lsl_zext_i32_i64
136 define i64 @lsl_zext_i32_i64(i32 %b) {
137   %1 = zext i32 %b to i64
138   %2 = shl i64 %1, 16
139   ret i64 %2
140 }
141
142 ; FIXME: Cannot test this yet, because the target-independent instruction
143 ; selector handles this.
144 ; CHECK-LABEL: lsl_sext_i32_i64
145 define i64 @lsl_sext_i32_i64(i32 %b) {
146   %1 = sext i32 %b to i64
147   %2 = shl i64 %1, 16
148   ret i64 %2
149 }
150
151 ; FIXME: Cannot test this yet, because the target-independent instruction
152 ; selector handles this.
153 ; CHECK-LABEL: lslv_i64
154 ; CHECK:       lsl {{x[0-9]*}}, x0, x1
155 define i64 @lslv_i64(i64 %a, i64 %b) {
156   %1 = shl i64 %a, %b
157   ret i64 %1
158 }
159
160 ; FIXME: This shouldn't use the variable shift version.
161 ; CHECK-LABEL: lsl_i64
162 ; CHECK:       lsl {{x[0-9]*}}, {{x[0-9]*}}, {{x[0-9]*}}
163 define i64 @lsl_i64(i64 %a) {
164   %1 = shl i64 %a, 32
165   ret i64 %1
166 }
167
168 ; CHECK-LABEL: lsrv_i8
169 ; CHECK:       and [[REG1:w[0-9]+]], w0, #0xff
170 ; CHECK-NEXT:  and [[REG2:w[0-9]+]], w1, #0xff
171 ; CHECK-NEXT:  lsr [[REG3:w[0-9]+]], [[REG1]], [[REG2]]
172 ; CHECK-NEXT:  and {{w[0-9]+}}, [[REG3]], #0xff
173 define zeroext i8 @lsrv_i8(i8 %a, i8 %b) {
174   %1 = lshr i8 %a, %b
175   ret i8 %1
176 }
177
178 ; CHECK-LABEL: lsr_i8
179 ; CHECK:       ubfx {{w[0-9]*}}, {{w[0-9]*}}, #4, #4
180 define zeroext i8 @lsr_i8(i8 %a) {
181   %1 = lshr i8 %a, 4
182   ret i8 %1
183 }
184
185 ; CHECK-LABEL: lsr_zext_i8_i16
186 ; CHECK:       ubfx {{w[0-9]*}}, {{w[0-9]*}}, #4, #4
187 define zeroext i16 @lsr_zext_i8_i16(i8 %b) {
188   %1 = zext i8 %b to i16
189   %2 = lshr i16 %1, 4
190   ret i16 %2
191 }
192
193 ; CHECK-LABEL: lsr_sext_i8_i16
194 ; CHECK:       sxtb [[REG:w[0-9]+]], w0
195 ; CHECK-NEXT:  ubfx {{w[0-9]*}}, [[REG]], #4, #12
196 define signext i16 @lsr_sext_i8_i16(i8 %b) {
197   %1 = sext i8 %b to i16
198   %2 = lshr i16 %1, 4
199   ret i16 %2
200 }
201
202 ; CHECK-LABEL: lsr_zext_i8_i32
203 ; CHECK:       ubfx {{w[0-9]*}}, {{w[0-9]*}}, #4, #4
204 define i32 @lsr_zext_i8_i32(i8 %b) {
205   %1 = zext i8 %b to i32
206   %2 = lshr i32 %1, 4
207   ret i32 %2
208 }
209
210 ; CHECK-LABEL: lsr_sext_i8_i32
211 ; CHECK:       sxtb [[REG:w[0-9]+]], w0
212 ; CHECK-NEXT:  lsr {{w[0-9]*}}, [[REG]], #4
213 define i32 @lsr_sext_i8_i32(i8 %b) {
214   %1 = sext i8 %b to i32
215   %2 = lshr i32 %1, 4
216   ret i32 %2
217 }
218
219 ; CHECK-LABEL: lsrv_i16
220 ; CHECK:       and [[REG1:w[0-9]+]], w0, #0xffff
221 ; CHECK-NEXT:  and [[REG2:w[0-9]+]], w1, #0xffff
222 ; CHECK-NEXT:  lsr [[REG3:w[0-9]+]], [[REG1]], [[REG2]]
223 ; CHECK-NEXT:  and {{w[0-9]+}}, [[REG3]], #0xffff
224 define zeroext i16 @lsrv_i16(i16 %a, i16 %b) {
225   %1 = lshr i16 %a, %b
226   ret i16 %1
227 }
228
229 ; CHECK-LABEL: lsr_i16
230 ; CHECK:       ubfx {{w[0-9]*}}, {{w[0-9]*}}, #8, #8
231 define zeroext i16 @lsr_i16(i16 %a) {
232   %1 = lshr i16 %a, 8
233   ret i16 %1
234 }
235
236 ; CHECK-LABEL: lsrv_i32
237 ; CHECK:       lsr {{w[0-9]*}}, w0, w1
238 define zeroext i32 @lsrv_i32(i32 %a, i32 %b) {
239   %1 = lshr i32 %a, %b
240   ret i32 %1
241 }
242
243 ; CHECK-LABEL: lsr_i32
244 ; CHECK:       lsr {{w[0-9]*}}, {{w[0-9]*}}, #16
245 define zeroext i32 @lsr_i32(i32 %a) {
246   %1 = lshr i32 %a, 16
247   ret i32 %1
248 }
249
250 ; CHECK-LABEL: lsrv_i64
251 ; CHECK:       lsr {{x[0-9]*}}, x0, x1
252 define i64 @lsrv_i64(i64 %a, i64 %b) {
253   %1 = lshr i64 %a, %b
254   ret i64 %1
255 }
256
257 ; FIXME: This shouldn't use the variable shift version.
258 ; CHECK-LABEL: lsr_i64
259 ; CHECK:       lsr {{x[0-9]*}}, {{x[0-9]*}}, {{x[0-9]*}}
260 define i64 @lsr_i64(i64 %a) {
261   %1 = lshr i64 %a, 32
262   ret i64 %1
263 }
264
265 ; CHECK-LABEL: asrv_i8
266 ; CHECK:       sxtb [[REG1:w[0-9]+]], w0
267 ; CHECK-NEXT:  and  [[REG2:w[0-9]+]], w1, #0xff
268 ; CHECK-NEXT:  asr  [[REG3:w[0-9]+]], [[REG1]], [[REG2]]
269 ; CHECK-NEXT:  and  {{w[0-9]+}}, [[REG3]], #0xff
270 define zeroext i8 @asrv_i8(i8 %a, i8 %b) {
271   %1 = ashr i8 %a, %b
272   ret i8 %1
273 }
274
275 ; CHECK-LABEL: asr_i8
276 ; CHECK:       sbfx {{w[0-9]*}}, {{w[0-9]*}}, #4, #4
277 define zeroext i8 @asr_i8(i8 %a) {
278   %1 = ashr i8 %a, 4
279   ret i8 %1
280 }
281
282 ; CHECK-LABEL: asr_zext_i8_i16
283 ; CHECK:       ubfx {{w[0-9]*}}, {{w[0-9]*}}, #4, #4
284 define zeroext i16 @asr_zext_i8_i16(i8 %b) {
285   %1 = zext i8 %b to i16
286   %2 = ashr i16 %1, 4
287   ret i16 %2
288 }
289
290 ; CHECK-LABEL: asr_sext_i8_i16
291 ; CHECK:       sbfx {{w[0-9]*}}, {{w[0-9]*}}, #4, #4
292 define signext i16 @asr_sext_i8_i16(i8 %b) {
293   %1 = sext i8 %b to i16
294   %2 = ashr i16 %1, 4
295   ret i16 %2
296 }
297
298 ; CHECK-LABEL: asr_zext_i8_i32
299 ; CHECK:       ubfx {{w[0-9]*}}, {{w[0-9]*}}, #4, #4
300 define i32 @asr_zext_i8_i32(i8 %b) {
301   %1 = zext i8 %b to i32
302   %2 = ashr i32 %1, 4
303   ret i32 %2
304 }
305
306 ; CHECK-LABEL: asr_sext_i8_i32
307 ; CHECK:       sbfx {{w[0-9]*}}, {{w[0-9]*}}, #4, #4
308 define i32 @asr_sext_i8_i32(i8 %b) {
309   %1 = sext i8 %b to i32
310   %2 = ashr i32 %1, 4
311   ret i32 %2
312 }
313
314 ; CHECK-LABEL: asrv_i16
315 ; CHECK:       sxth [[REG1:w[0-9]+]], w0
316 ; CHECK-NEXT:  and  [[REG2:w[0-9]+]], w1, #0xffff
317 ; CHECK-NEXT:  asr  [[REG3:w[0-9]+]], [[REG1]], [[REG2]]
318 ; CHECK-NEXT:  and  {{w[0-9]+}}, [[REG3]], #0xffff
319 define zeroext i16 @asrv_i16(i16 %a, i16 %b) {
320   %1 = ashr i16 %a, %b
321   ret i16 %1
322 }
323
324 ; CHECK-LABEL: asr_i16
325 ; CHECK:       sbfx {{w[0-9]*}}, {{w[0-9]*}}, #8, #8
326 define zeroext i16 @asr_i16(i16 %a) {
327   %1 = ashr i16 %a, 8
328   ret i16 %1
329 }
330
331 ; CHECK-LABEL: asrv_i32
332 ; CHECK:       asr {{w[0-9]*}}, w0, w1
333 define zeroext i32 @asrv_i32(i32 %a, i32 %b) {
334   %1 = ashr i32 %a, %b
335   ret i32 %1
336 }
337
338 ; CHECK-LABEL: asr_i32
339 ; CHECK:       asr {{w[0-9]*}}, {{w[0-9]*}}, #16
340 define zeroext i32 @asr_i32(i32 %a) {
341   %1 = ashr i32 %a, 16
342   ret i32 %1
343 }
344
345 ; CHECK-LABEL: asrv_i64
346 ; CHECK:       asr {{x[0-9]*}}, x0, x1
347 define i64 @asrv_i64(i64 %a, i64 %b) {
348   %1 = ashr i64 %a, %b
349   ret i64 %1
350 }
351
352 ; FIXME: This shouldn't use the variable shift version.
353 ; CHECK-LABEL: asr_i64
354 ; CHECK:       asr {{x[0-9]*}}, {{x[0-9]*}}, {{x[0-9]*}}
355 define i64 @asr_i64(i64 %a) {
356   %1 = ashr i64 %a, 32
357   ret i64 %1
358 }
359
360 ; CHECK-LABEL: shift_test1
361 ; CHECK:       ubfiz {{w[0-9]*}}, {{w[0-9]*}}, #4, #4
362 ; CHECK-NEXT:  sbfx  {{w[0-9]*}}, {{w[0-9]*}}, #4, #4
363 define i32 @shift_test1(i8 %a) {
364   %1 = shl i8 %a, 4
365   %2 = ashr i8 %1, 4
366   %3 = sext i8 %2 to i32
367   ret i32 %3
368 }
369