866febac26222e2d777a1c8d66503061204ee0c9
[oota-llvm.git] / test / CodeGen / AArch64 / fast-isel-int-ext.ll
1 ; RUN: llc -mtriple=aarch64-apple-darwin -fast-isel -fast-isel-abort -verify-machineinstrs < %s | FileCheck %s
2
3 ;
4 ; Test that we only use the sign/zero extend in the address calculation when
5 ; necessary.
6 ;
7 ; SHIFT
8 ;
9 define i64 @load_addr_shift_zext1(i32 %a, i64 %b) {
10 ; CHECK-LABEL: load_addr_shift_zext1
11 ; CHECK:       ldr {{x[0-9]+}}, [x1, w0, uxtw #3]
12   %1 = zext i32 %a to i64
13   %2 = shl i64 %1, 3
14   %3 = add i64 %b, %2
15   %4 = inttoptr i64 %3 to i64*
16   %5 = load i64* %4
17   ret i64 %5
18 }
19
20 define i64 @load_addr_shift_zext2(i32 zeroext %a, i64 %b) {
21 ; CHECK-LABEL: load_addr_shift_zext2
22 ; CHECK:       ldr {{x[0-9]+}}, [x1, x0, lsl #3]
23   %1 = zext i32 %a to i64
24   %2 = shl i64 %1, 3
25   %3 = add i64 %b, %2
26   %4 = inttoptr i64 %3 to i64*
27   %5 = load i64* %4
28   ret i64 %5
29 }
30
31 define i64 @load_addr_shift_zext3(i32 signext %a, i64 %b) {
32 ; CHECK-LABEL: load_addr_shift_zext3
33 ; CHECK:       ldr {{x[0-9]+}}, [x1, w0, uxtw #3]
34   %1 = zext i32 %a to i64
35   %2 = shl i64 %1, 3
36   %3 = add i64 %b, %2
37   %4 = inttoptr i64 %3 to i64*
38   %5 = load i64* %4
39   ret i64 %5
40 }
41
42 define i64 @load_addr_shift_sext1(i32 %a, i64 %b) {
43 ; CHECK-LABEL: load_addr_shift_sext1
44 ; CHECK:       ldr {{x[0-9]+}}, [x1, w0, sxtw #3]
45   %1 = sext i32 %a to i64
46   %2 = shl i64 %1, 3
47   %3 = add i64 %b, %2
48   %4 = inttoptr i64 %3 to i64*
49   %5 = load i64* %4
50   ret i64 %5
51 }
52
53 define i64 @load_addr_shift_sext2(i32 zeroext %a, i64 %b) {
54 ; CHECK-LABEL: load_addr_shift_sext2
55 ; CHECK:       ldr {{x[0-9]+}}, [x1, w0, sxtw #3]
56   %1 = sext i32 %a to i64
57   %2 = shl i64 %1, 3
58   %3 = add i64 %b, %2
59   %4 = inttoptr i64 %3 to i64*
60   %5 = load i64* %4
61   ret i64 %5
62 }
63
64 define i64 @load_addr_shift_sext3(i32 signext %a, i64 %b) {
65 ; CHECK-LABEL: load_addr_shift_sext3
66 ; CHECK:       ldr {{x[0-9]+}}, [x1, x0, lsl #3]
67   %1 = sext i32 %a to i64
68   %2 = shl i64 %1, 3
69   %3 = add i64 %b, %2
70   %4 = inttoptr i64 %3 to i64*
71   %5 = load i64* %4
72   ret i64 %5
73 }
74
75 ;
76 ; MUL
77 ;
78 define i64 @load_addr_mul_zext1(i32 %a, i64 %b) {
79 ; CHECK-LABEL: load_addr_mul_zext1
80 ; CHECK:       ldr {{x[0-9]+}}, [x1, w0, uxtw #3]
81   %1 = zext i32 %a to i64
82   %2 = mul i64 %1, 8
83   %3 = add i64 %b, %2
84   %4 = inttoptr i64 %3 to i64*
85   %5 = load i64* %4
86   ret i64 %5
87 }
88
89 define i64 @load_addr_mul_zext2(i32 zeroext %a, i64 %b) {
90 ; CHECK-LABEL: load_addr_mul_zext2
91 ; CHECK:       ldr {{x[0-9]+}}, [x1, x0, lsl #3]
92   %1 = zext i32 %a to i64
93   %2 = mul i64 %1, 8
94   %3 = add i64 %b, %2
95   %4 = inttoptr i64 %3 to i64*
96   %5 = load i64* %4
97   ret i64 %5
98 }
99
100 define i64 @load_addr_mul_zext3(i32 signext %a, i64 %b) {
101 ; CHECK-LABEL: load_addr_mul_zext3
102 ; CHECK:       ldr {{x[0-9]+}}, [x1, w0, uxtw #3]
103   %1 = zext i32 %a to i64
104   %2 = mul i64 %1, 8
105   %3 = add i64 %b, %2
106   %4 = inttoptr i64 %3 to i64*
107   %5 = load i64* %4
108   ret i64 %5
109 }
110
111 define i64 @load_addr_mul_sext1(i32 %a, i64 %b) {
112 ; CHECK-LABEL: load_addr_mul_sext1
113 ; CHECK:       ldr {{x[0-9]+}}, [x1, w0, sxtw #3]
114   %1 = sext i32 %a to i64
115   %2 = mul i64 %1, 8
116   %3 = add i64 %b, %2
117   %4 = inttoptr i64 %3 to i64*
118   %5 = load i64* %4
119   ret i64 %5
120 }
121
122 define i64 @load_addr_mul_sext2(i32 zeroext %a, i64 %b) {
123 ; CHECK-LABEL: load_addr_mul_sext2
124 ; CHECK:       ldr {{x[0-9]+}}, [x1, w0, sxtw #3]
125   %1 = sext i32 %a to i64
126   %2 = mul i64 %1, 8
127   %3 = add i64 %b, %2
128   %4 = inttoptr i64 %3 to i64*
129   %5 = load i64* %4
130   ret i64 %5
131 }
132
133 define i64 @load_addr_mul_sext3(i32 signext %a, i64 %b) {
134 ; CHECK-LABEL: load_addr_mul_sext3
135 ; CHECK:       ldr {{x[0-9]+}}, [x1, x0, lsl #3]
136   %1 = sext i32 %a to i64
137   %2 = mul i64 %1, 8
138   %3 = add i64 %b, %2
139   %4 = inttoptr i64 %3 to i64*
140   %5 = load i64* %4
141   ret i64 %5
142 }
143
144
145 ;
146 ; Test folding of the sign-/zero-extend into the load instruction.
147 ;
148
149 ; Unscaled
150 define i32 @load_unscaled_zext_i8_to_i32(i64 %a) {
151 ; CHECK-LABEL: load_unscaled_zext_i8_to_i32
152 ; CHECK:       ldurb w0, [x0, #-8]
153 ; CHECK-NOT:   uxtb
154   %1 = sub i64 %a, 8
155   %2 = inttoptr i64 %1 to i8*
156   %3 = load i8* %2
157   %4 = zext i8 %3 to i32
158   ret i32 %4
159 }
160
161 define i32 @load_unscaled_zext_i16_to_i32(i64 %a) {
162 ; CHECK-LABEL: load_unscaled_zext_i16_to_i32
163 ; CHECK:       ldurh w0, [x0, #-8]
164 ; CHECK-NOT:   uxth
165   %1 = sub i64 %a, 8
166   %2 = inttoptr i64 %1 to i16*
167   %3 = load i16* %2
168   %4 = zext i16 %3 to i32
169   ret i32 %4
170 }
171
172 define i64 @load_unscaled_zext_i8_to_i64(i64 %a) {
173 ; CHECK-LABEL: load_unscaled_zext_i8_to_i64
174 ; CHECK:       ldurb w0, [x0, #-8]
175 ; CHECK-NOT:   uxtb
176   %1 = sub i64 %a, 8
177   %2 = inttoptr i64 %1 to i8*
178   %3 = load i8* %2
179   %4 = zext i8 %3 to i64
180   ret i64 %4
181 }
182
183 define i64 @load_unscaled_zext_i16_to_i64(i64 %a) {
184 ; CHECK-LABEL: load_unscaled_zext_i16_to_i64
185 ; CHECK:       ldurh w0, [x0, #-8]
186 ; CHECK-NOT:   uxth
187   %1 = sub i64 %a, 8
188   %2 = inttoptr i64 %1 to i16*
189   %3 = load i16* %2
190   %4 = zext i16 %3 to i64
191   ret i64 %4
192 }
193
194 define i64 @load_unscaled_zext_i32_to_i64(i64 %a) {
195 ; CHECK-LABEL: load_unscaled_zext_i32_to_i64
196 ; CHECK:       ldur w0, [x0, #-8]
197 ; CHECK-NOT:   uxtw
198   %1 = sub i64 %a, 8
199   %2 = inttoptr i64 %1 to i32*
200   %3 = load i32* %2
201   %4 = zext i32 %3 to i64
202   ret i64 %4
203 }
204
205 define i32 @load_unscaled_sext_i8_to_i32(i64 %a) {
206 ; CHECK-LABEL: load_unscaled_sext_i8_to_i32
207 ; CHECK:       ldursb w0, [x0, #-8]
208 ; CHECK-NOT:   sxtb
209   %1 = sub i64 %a, 8
210   %2 = inttoptr i64 %1 to i8*
211   %3 = load i8* %2
212   %4 = sext i8 %3 to i32
213   ret i32 %4
214 }
215
216 define i32 @load_unscaled_sext_i16_to_i32(i64 %a) {
217 ; CHECK-LABEL: load_unscaled_sext_i16_to_i32
218 ; CHECK:       ldursh w0, [x0, #-8]
219 ; CHECK-NOT:   sxth
220   %1 = sub i64 %a, 8
221   %2 = inttoptr i64 %1 to i16*
222   %3 = load i16* %2
223   %4 = sext i16 %3 to i32
224   ret i32 %4
225 }
226
227 define i64 @load_unscaled_sext_i8_to_i64(i64 %a) {
228 ; CHECK-LABEL: load_unscaled_sext_i8_to_i64
229 ; CHECK:       ldursb x0, [x0, #-8]
230 ; CHECK-NOT:   sxtb
231   %1 = sub i64 %a, 8
232   %2 = inttoptr i64 %1 to i8*
233   %3 = load i8* %2
234   %4 = sext i8 %3 to i64
235   ret i64 %4
236 }
237
238 define i64 @load_unscaled_sext_i16_to_i64(i64 %a) {
239 ; CHECK-LABEL: load_unscaled_sext_i16_to_i64
240 ; CHECK:       ldursh x0, [x0, #-8]
241 ; CHECK-NOT:   sxth
242   %1 = sub i64 %a, 8
243   %2 = inttoptr i64 %1 to i16*
244   %3 = load i16* %2
245   %4 = sext i16 %3 to i64
246   ret i64 %4
247 }
248
249 define i64 @load_unscaled_sext_i32_to_i64(i64 %a) {
250 ; CHECK-LABEL: load_unscaled_sext_i32_to_i64
251 ; CHECK:       ldursw x0, [x0, #-8]
252 ; CHECK-NOT:   sxtw
253   %1 = sub i64 %a, 8
254   %2 = inttoptr i64 %1 to i32*
255   %3 = load i32* %2
256   %4 = sext i32 %3 to i64
257   ret i64 %4
258 }
259
260 ; Register
261 define i32 @load_register_zext_i8_to_i32(i64 %a, i64 %b) {
262 ; CHECK-LABEL: load_register_zext_i8_to_i32
263 ; CHECK:       ldrb w0, [x0, x1]
264 ; CHECK-NOT:   uxtb
265   %1 = add i64 %a, %b
266   %2 = inttoptr i64 %1 to i8*
267   %3 = load i8* %2
268   %4 = zext i8 %3 to i32
269   ret i32 %4
270 }
271
272 define i32 @load_register_zext_i16_to_i32(i64 %a, i64 %b) {
273 ; CHECK-LABEL: load_register_zext_i16_to_i32
274 ; CHECK:       ldrh w0, [x0, x1]
275 ; CHECK-NOT:   uxth
276   %1 = add i64 %a, %b
277   %2 = inttoptr i64 %1 to i16*
278   %3 = load i16* %2
279   %4 = zext i16 %3 to i32
280   ret i32 %4
281 }
282
283 define i64 @load_register_zext_i8_to_i64(i64 %a, i64 %b) {
284 ; CHECK-LABEL: load_register_zext_i8_to_i64
285 ; CHECK:       ldrb w0, [x0, x1]
286 ; CHECK-NOT:   uxtb
287   %1 = add i64 %a, %b
288   %2 = inttoptr i64 %1 to i8*
289   %3 = load i8* %2
290   %4 = zext i8 %3 to i64
291   ret i64 %4
292 }
293
294 define i64 @load_register_zext_i16_to_i64(i64 %a, i64 %b) {
295 ; CHECK-LABEL: load_register_zext_i16_to_i64
296 ; CHECK:       ldrh w0, [x0, x1]
297 ; CHECK-NOT:   uxth
298   %1 = add i64 %a, %b
299   %2 = inttoptr i64 %1 to i16*
300   %3 = load i16* %2
301   %4 = zext i16 %3 to i64
302   ret i64 %4
303 }
304
305 define i64 @load_register_zext_i32_to_i64(i64 %a, i64 %b) {
306 ; CHECK-LABEL: load_register_zext_i32_to_i64
307 ; CHECK:       ldr w0, [x0, x1]
308 ; CHECK-NOT:   uxtw
309   %1 = add i64 %a, %b
310   %2 = inttoptr i64 %1 to i32*
311   %3 = load i32* %2
312   %4 = zext i32 %3 to i64
313   ret i64 %4
314 }
315
316 define i32 @load_register_sext_i8_to_i32(i64 %a, i64 %b) {
317 ; CHECK-LABEL: load_register_sext_i8_to_i32
318 ; CHECK:       ldrsb w0, [x0, x1]
319 ; CHECK-NOT:   sxtb
320   %1 = add i64 %a, %b
321   %2 = inttoptr i64 %1 to i8*
322   %3 = load i8* %2
323   %4 = sext i8 %3 to i32
324   ret i32 %4
325 }
326
327 define i32 @load_register_sext_i16_to_i32(i64 %a, i64 %b) {
328 ; CHECK-LABEL: load_register_sext_i16_to_i32
329 ; CHECK:       ldrsh w0, [x0, x1]
330 ; CHECK-NOT:   sxth
331   %1 = add i64 %a, %b
332   %2 = inttoptr i64 %1 to i16*
333   %3 = load i16* %2
334   %4 = sext i16 %3 to i32
335   ret i32 %4
336 }
337
338 define i64 @load_register_sext_i8_to_i64(i64 %a, i64 %b) {
339 ; CHECK-LABEL: load_register_sext_i8_to_i64
340 ; CHECK:       ldrsb x0, [x0, x1]
341 ; CHECK-NOT:   sxtb
342   %1 = add i64 %a, %b
343   %2 = inttoptr i64 %1 to i8*
344   %3 = load i8* %2
345   %4 = sext i8 %3 to i64
346   ret i64 %4
347 }
348
349 define i64 @load_register_sext_i16_to_i64(i64 %a, i64 %b) {
350 ; CHECK-LABEL: load_register_sext_i16_to_i64
351 ; CHECK:       ldrsh x0, [x0, x1]
352 ; CHECK-NOT:   sxth
353   %1 = add i64 %a, %b
354   %2 = inttoptr i64 %1 to i16*
355   %3 = load i16* %2
356   %4 = sext i16 %3 to i64
357   ret i64 %4
358 }
359
360 define i64 @load_register_sext_i32_to_i64(i64 %a, i64 %b) {
361 ; CHECK-LABEL: load_register_sext_i32_to_i64
362 ; CHECK:       ldrsw x0, [x0, x1]
363 ; CHECK-NOT:   sxtw
364   %1 = add i64 %a, %b
365   %2 = inttoptr i64 %1 to i32*
366   %3 = load i32* %2
367   %4 = sext i32 %3 to i64
368   ret i64 %4
369 }
370
371 ; Extend
372 define i32 @load_extend_zext_i8_to_i32(i64 %a, i32 %b) {
373 ; CHECK-LABEL: load_extend_zext_i8_to_i32
374 ; CHECK:       ldrb w0, [x0, w1, sxtw]
375 ; CHECK-NOT:   uxtb
376   %1 = sext i32 %b to i64
377   %2 = add i64 %a, %1
378   %3 = inttoptr i64 %2 to i8*
379   %4 = load i8* %3
380   %5 = zext i8 %4 to i32
381   ret i32 %5
382 }
383
384 define i32 @load_extend_zext_i16_to_i32(i64 %a, i32 %b) {
385 ; CHECK-LABEL: load_extend_zext_i16_to_i32
386 ; CHECK:       ldrh w0, [x0, w1, sxtw]
387 ; CHECK-NOT:   uxth
388   %1 = sext i32 %b to i64
389   %2 = add i64 %a, %1
390   %3 = inttoptr i64 %2 to i16*
391   %4 = load i16* %3
392   %5 = zext i16 %4 to i32
393   ret i32 %5
394 }
395
396 define i64 @load_extend_zext_i8_to_i64(i64 %a, i32 %b) {
397 ; CHECK-LABEL: load_extend_zext_i8_to_i64
398 ; CHECK:       ldrb w0, [x0, w1, sxtw]
399 ; CHECK-NOT:   uxtb
400   %1 = sext i32 %b to i64
401   %2 = add i64 %a, %1
402   %3 = inttoptr i64 %2 to i8*
403   %4 = load i8* %3
404   %5 = zext i8 %4 to i64
405   ret i64 %5
406 }
407
408 define i64 @load_extend_zext_i16_to_i64(i64 %a, i32 %b) {
409 ; CHECK-LABEL: load_extend_zext_i16_to_i64
410 ; CHECK:       ldrh w0, [x0, w1, sxtw]
411 ; CHECK-NOT:   uxth
412   %1 = sext i32 %b to i64
413   %2 = add i64 %a, %1
414   %3 = inttoptr i64 %2 to i16*
415   %4 = load i16* %3
416   %5 = zext i16 %4 to i64
417   ret i64 %5
418 }
419
420 define i64 @load_extend_zext_i32_to_i64(i64 %a, i32 %b) {
421 ; CHECK-LABEL: load_extend_zext_i32_to_i64
422 ; CHECK:       ldr w0, [x0, w1, sxtw]
423 ; CHECK-NOT:   uxtw
424   %1 = sext i32 %b to i64
425   %2 = add i64 %a, %1
426   %3 = inttoptr i64 %2 to i32*
427   %4 = load i32* %3
428   %5 = zext i32 %4 to i64
429   ret i64 %5
430 }
431
432 define i32 @load_extend_sext_i8_to_i32(i64 %a, i32 %b) {
433 ; CHECK-LABEL: load_extend_sext_i8_to_i32
434 ; CHECK:       ldrsb w0, [x0, w1, sxtw]
435 ; CHECK-NOT:   sxtb
436   %1 = sext i32 %b to i64
437   %2 = add i64 %a, %1
438   %3 = inttoptr i64 %2 to i8*
439   %4 = load i8* %3
440   %5 = sext i8 %4 to i32
441   ret i32 %5
442 }
443
444 define i32 @load_extend_sext_i16_to_i32(i64 %a, i32 %b) {
445 ; CHECK-LABEL: load_extend_sext_i16_to_i32
446 ; CHECK:       ldrsh w0, [x0, w1, sxtw]
447 ; CHECK-NOT:   sxth
448   %1 = sext i32 %b to i64
449   %2 = add i64 %a, %1
450   %3 = inttoptr i64 %2 to i16*
451   %4 = load i16* %3
452   %5 = sext i16 %4 to i32
453   ret i32 %5
454 }
455
456 define i64 @load_extend_sext_i8_to_i64(i64 %a, i32 %b) {
457 ; CHECK-LABEL: load_extend_sext_i8_to_i64
458 ; CHECK:       ldrsb x0, [x0, w1, sxtw]
459 ; CHECK-NOT:   sxtb
460   %1 = sext i32 %b to i64
461   %2 = add i64 %a, %1
462   %3 = inttoptr i64 %2 to i8*
463   %4 = load i8* %3
464   %5 = sext i8 %4 to i64
465   ret i64 %5
466 }
467
468 define i64 @load_extend_sext_i16_to_i64(i64 %a, i32 %b) {
469 ; CHECK-LABEL: load_extend_sext_i16_to_i64
470 ; CHECK:       ldrsh x0, [x0, w1, sxtw]
471 ; CHECK-NOT:   sxth
472   %1 = sext i32 %b to i64
473   %2 = add i64 %a, %1
474   %3 = inttoptr i64 %2 to i16*
475   %4 = load i16* %3
476   %5 = sext i16 %4 to i64
477   ret i64 %5
478 }
479
480 define i64 @load_extend_sext_i32_to_i64(i64 %a, i32 %b) {
481 ; CHECK-LABEL: load_extend_sext_i32_to_i64
482 ; CHECK:       ldrsw x0, [x0, w1, sxtw]
483 ; CHECK-NOT:   sxtw
484   %1 = sext i32 %b to i64
485   %2 = add i64 %a, %1
486   %3 = inttoptr i64 %2 to i32*
487   %4 = load i32* %3
488   %5 = sext i32 %4 to i64
489   ret i64 %5
490 }
491