1 ; RUN: llc -mtriple=aarch64-apple-darwin -fast-isel -fast-isel-abort -verify-machineinstrs < %s | FileCheck %s
4 ; Test that we only use the sign/zero extend in the address calculation when
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
15 %4 = inttoptr i64 %3 to i64*
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
26 %4 = inttoptr i64 %3 to i64*
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
37 %4 = inttoptr i64 %3 to i64*
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
48 %4 = inttoptr i64 %3 to i64*
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
59 %4 = inttoptr i64 %3 to i64*
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
70 %4 = inttoptr i64 %3 to i64*
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
84 %4 = inttoptr i64 %3 to i64*
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
95 %4 = inttoptr i64 %3 to i64*
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
106 %4 = inttoptr i64 %3 to i64*
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
117 %4 = inttoptr i64 %3 to i64*
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
128 %4 = inttoptr i64 %3 to i64*
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
139 %4 = inttoptr i64 %3 to i64*
146 ; Test folding of the sign-/zero-extend into the load instruction.
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]
155 %2 = inttoptr i64 %1 to i8*
157 %4 = zext i8 %3 to i32
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]
166 %2 = inttoptr i64 %1 to i16*
168 %4 = zext i16 %3 to i32
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]
177 %2 = inttoptr i64 %1 to i8*
179 %4 = zext i8 %3 to i64
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]
188 %2 = inttoptr i64 %1 to i16*
190 %4 = zext i16 %3 to i64
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]
199 %2 = inttoptr i64 %1 to i32*
201 %4 = zext i32 %3 to i64
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]
210 %2 = inttoptr i64 %1 to i8*
212 %4 = sext i8 %3 to i32
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]
221 %2 = inttoptr i64 %1 to i16*
223 %4 = sext i16 %3 to i32
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]
232 %2 = inttoptr i64 %1 to i8*
234 %4 = sext i8 %3 to i64
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]
243 %2 = inttoptr i64 %1 to i16*
245 %4 = sext i16 %3 to i64
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]
254 %2 = inttoptr i64 %1 to i32*
256 %4 = sext i32 %3 to i64
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]
266 %2 = inttoptr i64 %1 to i8*
268 %4 = zext i8 %3 to i32
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]
277 %2 = inttoptr i64 %1 to i16*
279 %4 = zext i16 %3 to i32
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]
288 %2 = inttoptr i64 %1 to i8*
290 %4 = zext i8 %3 to i64
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]
299 %2 = inttoptr i64 %1 to i16*
301 %4 = zext i16 %3 to i64
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]
310 %2 = inttoptr i64 %1 to i32*
312 %4 = zext i32 %3 to i64
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]
321 %2 = inttoptr i64 %1 to i8*
323 %4 = sext i8 %3 to i32
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]
332 %2 = inttoptr i64 %1 to i16*
334 %4 = sext i16 %3 to i32
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]
343 %2 = inttoptr i64 %1 to i8*
345 %4 = sext i8 %3 to i64
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]
354 %2 = inttoptr i64 %1 to i16*
356 %4 = sext i16 %3 to i64
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]
365 %2 = inttoptr i64 %1 to i32*
367 %4 = sext i32 %3 to i64
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]]]
377 %1 = sext i32 %b to i64
379 %3 = inttoptr i64 %2 to i8*
381 %5 = zext i8 %4 to i32
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]]]
390 %1 = sext i32 %b to i64
392 %3 = inttoptr i64 %2 to i16*
394 %5 = zext i16 %4 to i32
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]]]
403 %1 = sext i32 %b to i64
405 %3 = inttoptr i64 %2 to i8*
407 %5 = zext i8 %4 to i64
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]]]
416 %1 = sext i32 %b to i64
418 %3 = inttoptr i64 %2 to i16*
420 %5 = zext i16 %4 to i64
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]]]
429 %1 = sext i32 %b to i64
431 %3 = inttoptr i64 %2 to i32*
433 %5 = zext i32 %4 to i64
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]]]
442 %1 = sext i32 %b to i64
444 %3 = inttoptr i64 %2 to i8*
446 %5 = sext i8 %4 to i32
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]]]
455 %1 = sext i32 %b to i64
457 %3 = inttoptr i64 %2 to i16*
459 %5 = sext i16 %4 to i32
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]]]
468 %1 = sext i32 %b to i64
470 %3 = inttoptr i64 %2 to i8*
472 %5 = sext i8 %4 to i64
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]]]
481 %1 = sext i32 %b to i64
483 %3 = inttoptr i64 %2 to i16*
485 %5 = sext i16 %4 to i64
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]]]
494 %1 = sext i32 %b to i64
496 %3 = inttoptr i64 %2 to i32*
498 %5 = sext i32 %4 to i64