[FastISel][AArch64] Fix "Fold sign-/zero-extends into the load instruction."
[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 = add 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 = add 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 = add 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 = add 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 = add 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 = add 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 = add 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 = add 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 = add 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 = add 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:       sxtw [[REG:x[0-9]+]], w1
375 ; CHECK-NEXT:  ldrb w0, [x0, [[REG]]]
376 ; CHECK-NOT:   uxtb
377   %1 = sext i32 %b to i64
378   %2 = add i64 %a, %1
379   %3 = inttoptr i64 %2 to i8*
380   %4 = load i8* %3
381   %5 = zext i8 %4 to i32
382   ret i32 %5
383 }
384
385 define i32 @load_extend_zext_i16_to_i32(i64 %a, i32 %b) {
386 ; CHECK-LABEL: load_extend_zext_i16_to_i32
387 ; CHECK:       sxtw [[REG:x[0-9]+]], w1
388 ; CHECK-NEXT:  ldrh w0, [x0, [[REG]]]
389 ; CHECK-NOT:   uxth
390   %1 = sext i32 %b to i64
391   %2 = add i64 %a, %1
392   %3 = inttoptr i64 %2 to i16*
393   %4 = load i16* %3
394   %5 = zext i16 %4 to i32
395   ret i32 %5
396 }
397
398 define i64 @load_extend_zext_i8_to_i64(i64 %a, i32 %b) {
399 ; CHECK-LABEL: load_extend_zext_i8_to_i64
400 ; CHECK:       sxtw [[REG:x[0-9]+]], w1
401 ; CHECK-NEXT:  ldrb w0, [x0, [[REG]]]
402 ; CHECK-NOT:   uxtb
403   %1 = sext i32 %b to i64
404   %2 = add i64 %a, %1
405   %3 = inttoptr i64 %2 to i8*
406   %4 = load i8* %3
407   %5 = zext i8 %4 to i64
408   ret i64 %5
409 }
410
411 define i64 @load_extend_zext_i16_to_i64(i64 %a, i32 %b) {
412 ; CHECK-LABEL: load_extend_zext_i16_to_i64
413 ; CHECK:       sxtw [[REG:x[0-9]+]], w1
414 ; CHECK-NEXT:  ldrh w0, [x0, [[REG]]]
415 ; CHECK-NOT:   uxth
416   %1 = sext i32 %b to i64
417   %2 = add i64 %a, %1
418   %3 = inttoptr i64 %2 to i16*
419   %4 = load i16* %3
420   %5 = zext i16 %4 to i64
421   ret i64 %5
422 }
423
424 define i64 @load_extend_zext_i32_to_i64(i64 %a, i32 %b) {
425 ; CHECK-LABEL: load_extend_zext_i32_to_i64
426 ; CHECK:       sxtw [[REG:x[0-9]+]], w1
427 ; CHECK-NEXT:  ldr w0, [x0, [[REG]]]
428 ; CHECK-NOT:   uxtw
429   %1 = sext i32 %b to i64
430   %2 = add i64 %a, %1
431   %3 = inttoptr i64 %2 to i32*
432   %4 = load i32* %3
433   %5 = zext i32 %4 to i64
434   ret i64 %5
435 }
436
437 define i32 @load_extend_sext_i8_to_i32(i64 %a, i32 %b) {
438 ; CHECK-LABEL: load_extend_sext_i8_to_i32
439 ; CHECK:       sxtw [[REG:x[0-9]+]], w1
440 ; CHECK-NEXT:  ldrsb w0, [x0, [[REG]]]
441 ; CHECK-NOT:   sxtb
442   %1 = sext i32 %b to i64
443   %2 = add i64 %a, %1
444   %3 = inttoptr i64 %2 to i8*
445   %4 = load i8* %3
446   %5 = sext i8 %4 to i32
447   ret i32 %5
448 }
449
450 define i32 @load_extend_sext_i16_to_i32(i64 %a, i32 %b) {
451 ; CHECK-LABEL: load_extend_sext_i16_to_i32
452 ; CHECK:       sxtw [[REG:x[0-9]+]], w1
453 ; CHECK-NEXT:  ldrsh w0, [x0, [[REG]]]
454 ; CHECK-NOT:   sxth
455   %1 = sext i32 %b to i64
456   %2 = add i64 %a, %1
457   %3 = inttoptr i64 %2 to i16*
458   %4 = load i16* %3
459   %5 = sext i16 %4 to i32
460   ret i32 %5
461 }
462
463 define i64 @load_extend_sext_i8_to_i64(i64 %a, i32 %b) {
464 ; CHECK-LABEL: load_extend_sext_i8_to_i64
465 ; CHECK:       sxtw [[REG:x[0-9]+]], w1
466 ; CHECK-NEXT:  ldrsb x0, [x0, [[REG]]]
467 ; CHECK-NOT:   sxtb
468   %1 = sext i32 %b to i64
469   %2 = add i64 %a, %1
470   %3 = inttoptr i64 %2 to i8*
471   %4 = load i8* %3
472   %5 = sext i8 %4 to i64
473   ret i64 %5
474 }
475
476 define i64 @load_extend_sext_i16_to_i64(i64 %a, i32 %b) {
477 ; CHECK-LABEL: load_extend_sext_i16_to_i64
478 ; CHECK:       sxtw [[REG:x[0-9]+]], w1
479 ; CHECK-NEXT:  ldrsh x0, [x0, [[REG]]]
480 ; CHECK-NOT:   sxth
481   %1 = sext i32 %b to i64
482   %2 = add i64 %a, %1
483   %3 = inttoptr i64 %2 to i16*
484   %4 = load i16* %3
485   %5 = sext i16 %4 to i64
486   ret i64 %5
487 }
488
489 define i64 @load_extend_sext_i32_to_i64(i64 %a, i32 %b) {
490 ; CHECK-LABEL: load_extend_sext_i32_to_i64
491 ; CHECK:       sxtw [[REG:x[0-9]+]], w1
492 ; CHECK-NEXT:  ldrsw x0, [x0, [[REG]]]
493 ; CHECK-NOT:   sxtw
494   %1 = sext i32 %b to i64
495   %2 = add i64 %a, %1
496   %3 = inttoptr i64 %2 to i32*
497   %4 = load i32* %3
498   %5 = sext i32 %4 to i64
499   ret i64 %5
500 }
501