[MIParser] Set RegClassOrRegBank during instruction parsing
[llvm-complete.git] / test / CodeGen / AArch64 / fast-isel-int-ext.ll
blob4b2cab5fa7289ad29d6d23d3c5271f49bc2e52a0
1 ; RUN: llc -mtriple=aarch64-apple-darwin -fast-isel -fast-isel-abort=1 -verify-machineinstrs < %s | FileCheck %s
4 ; Test that we only use the sign/zero extend in the address calculation when
5 ; necessary.
7 ; SHIFT
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, i64* %4
17   ret i64 %5
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, i64* %4
28   ret i64 %5
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, i64* %4
39   ret i64 %5
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, i64* %4
50   ret i64 %5
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, i64* %4
61   ret i64 %5
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, i64* %4
72   ret i64 %5
76 ; MUL
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, i64* %4
86   ret i64 %5
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, i64* %4
97   ret i64 %5
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, i64* %4
108   ret i64 %5
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, i64* %4
119   ret i64 %5
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, i64* %4
130   ret i64 %5
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, i64* %4
141   ret i64 %5
146 ; Test folding of the sign-/zero-extend into the load instruction.
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, i8* %2
157   %4 = zext i8 %3 to i32
158   ret i32 %4
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, i16* %2
168   %4 = zext i16 %3 to i32
169   ret i32 %4
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, i8* %2
179   %4 = zext i8 %3 to i64
180   ret i64 %4
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, i16* %2
190   %4 = zext i16 %3 to i64
191   ret i64 %4
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, i32* %2
201   %4 = zext i32 %3 to i64
202   ret i64 %4
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, i8* %2
212   %4 = sext i8 %3 to i32
213   ret i32 %4
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, i16* %2
223   %4 = sext i16 %3 to i32
224   ret i32 %4
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, i8* %2
234   %4 = sext i8 %3 to i64
235   ret i64 %4
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, i16* %2
245   %4 = sext i16 %3 to i64
246   ret i64 %4
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, i32* %2
256   %4 = sext i32 %3 to i64
257   ret i64 %4
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, i8* %2
268   %4 = zext i8 %3 to i32
269   ret i32 %4
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, i16* %2
279   %4 = zext i16 %3 to i32
280   ret i32 %4
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, i8* %2
290   %4 = zext i8 %3 to i64
291   ret i64 %4
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, i16* %2
301   %4 = zext i16 %3 to i64
302   ret i64 %4
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, i32* %2
312   %4 = zext i32 %3 to i64
313   ret i64 %4
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, i8* %2
323   %4 = sext i8 %3 to i32
324   ret i32 %4
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, i16* %2
334   %4 = sext i16 %3 to i32
335   ret i32 %4
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, i8* %2
345   %4 = sext i8 %3 to i64
346   ret i64 %4
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, i16* %2
356   %4 = sext i16 %3 to i64
357   ret i64 %4
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, i32* %2
367   %4 = sext i32 %3 to i64
368   ret i64 %4
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, i8* %3
380   %5 = zext i8 %4 to i32
381   ret i32 %5
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, i16* %3
392   %5 = zext i16 %4 to i32
393   ret i32 %5
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, i8* %3
404   %5 = zext i8 %4 to i64
405   ret i64 %5
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, i16* %3
416   %5 = zext i16 %4 to i64
417   ret i64 %5
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, i32* %3
428   %5 = zext i32 %4 to i64
429   ret i64 %5
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, i8* %3
440   %5 = sext i8 %4 to i32
441   ret i32 %5
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, i16* %3
452   %5 = sext i16 %4 to i32
453   ret i32 %5
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, i8* %3
464   %5 = sext i8 %4 to i64
465   ret i64 %5
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, i16* %3
476   %5 = sext i16 %4 to i64
477   ret i64 %5
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, i32* %3
488   %5 = sext i32 %4 to i64
489   ret i64 %5