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
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*
16 %5 = load i64, i64* %4
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*
27 %5 = load i64, i64* %4
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*
38 %5 = load i64, i64* %4
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*
49 %5 = load i64, i64* %4
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*
60 %5 = load i64, i64* %4
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*
71 %5 = load i64, i64* %4
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*
85 %5 = load i64, i64* %4
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*
96 %5 = load i64, i64* %4
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*
107 %5 = load i64, i64* %4
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*
118 %5 = load i64, i64* %4
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*
129 %5 = load i64, i64* %4
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*
140 %5 = load i64, i64* %4
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*
167 %3 = load i16, i16* %2
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*
189 %3 = load i16, i16* %2
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*
200 %3 = load i32, i32* %2
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*
222 %3 = load i16, i16* %2
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*
244 %3 = load i16, i16* %2
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*
255 %3 = load i32, i32* %2
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*
278 %3 = load i16, i16* %2
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*
300 %3 = load i16, i16* %2
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*
311 %3 = load i32, i32* %2
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*
333 %3 = load i16, i16* %2
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*
355 %3 = load i16, i16* %2
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*
366 %3 = load i32, i32* %2
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: ldrb w0, [x0, w1, sxtw]
376 %1 = sext i32 %b to i64
378 %3 = inttoptr i64 %2 to i8*
380 %5 = zext i8 %4 to i32
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]
388 %1 = sext i32 %b to i64
390 %3 = inttoptr i64 %2 to i16*
391 %4 = load i16, i16* %3
392 %5 = zext i16 %4 to i32
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]
400 %1 = sext i32 %b to i64
402 %3 = inttoptr i64 %2 to i8*
404 %5 = zext i8 %4 to i64
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]
412 %1 = sext i32 %b to i64
414 %3 = inttoptr i64 %2 to i16*
415 %4 = load i16, i16* %3
416 %5 = zext i16 %4 to i64
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]
424 %1 = sext i32 %b to i64
426 %3 = inttoptr i64 %2 to i32*
427 %4 = load i32, i32* %3
428 %5 = zext i32 %4 to i64
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]
436 %1 = sext i32 %b to i64
438 %3 = inttoptr i64 %2 to i8*
440 %5 = sext i8 %4 to i32
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]
448 %1 = sext i32 %b to i64
450 %3 = inttoptr i64 %2 to i16*
451 %4 = load i16, i16* %3
452 %5 = sext i16 %4 to i32
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]
460 %1 = sext i32 %b to i64
462 %3 = inttoptr i64 %2 to i8*
464 %5 = sext i8 %4 to i64
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]
472 %1 = sext i32 %b to i64
474 %3 = inttoptr i64 %2 to i16*
475 %4 = load i16, i16* %3
476 %5 = sext i16 %4 to i64
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]
484 %1 = sext i32 %b to i64
486 %3 = inttoptr i64 %2 to i32*
487 %4 = load i32, i32* %3
488 %5 = sext i32 %4 to i64