1 ; RUN: llc -mtriple=aarch64-apple-darwin -verify-machineinstrs < %s | FileCheck %s --check-prefix=CHECK --check-prefix=SDAG
2 ; RUN: llc -mtriple=aarch64-apple-darwin -fast-isel -fast-isel-abort -verify-machineinstrs < %s | FileCheck %s --check-prefix=CHECK --check-prefix=FAST
4 ; Load / Store Base Register only
5 define zeroext i1 @load_breg_i1(i1* %a) {
6 ; CHECK-LABEL: load_breg_i1
7 ; CHECK: ldrb {{w[0-9]+}}, [x0]
12 define zeroext i8 @load_breg_i8(i8* %a) {
13 ; CHECK-LABEL: load_breg_i8
14 ; CHECK: ldrb {{w[0-9]+}}, [x0]
19 define zeroext i16 @load_breg_i16(i16* %a) {
20 ; CHECK-LABEL: load_breg_i16
21 ; CHECK: ldrh {{w[0-9]+}}, [x0]
26 define i32 @load_breg_i32(i32* %a) {
27 ; CHECK-LABEL: load_breg_i32
28 ; CHECK: ldr {{w[0-9]+}}, [x0]
33 define i64 @load_breg_i64(i64* %a) {
34 ; CHECK-LABEL: load_breg_i64
35 ; CHECK: ldr {{x[0-9]+}}, [x0]
40 define float @load_breg_f32(float* %a) {
41 ; CHECK-LABEL: load_breg_f32
42 ; CHECK: ldr {{s[0-9]+}}, [x0]
47 define double @load_breg_f64(double* %a) {
48 ; CHECK-LABEL: load_breg_f64
49 ; CHECK: ldr {{d[0-9]+}}, [x0]
54 define void @store_breg_i1(i1* %a) {
55 ; CHECK-LABEL: store_breg_i1
56 ; CHECK: strb {{wzr|w[0-9]+}}, [x0]
61 define void @store_breg_i8(i8* %a) {
62 ; CHECK-LABEL: store_breg_i8
63 ; CHECK: strb wzr, [x0]
68 define void @store_breg_i16(i16* %a) {
69 ; CHECK-LABEL: store_breg_i16
70 ; CHECK: strh wzr, [x0]
75 define void @store_breg_i32(i32* %a) {
76 ; CHECK-LABEL: store_breg_i32
77 ; CHECK: str wzr, [x0]
82 define void @store_breg_i64(i64* %a) {
83 ; CHECK-LABEL: store_breg_i64
84 ; CHECK: str xzr, [x0]
89 define void @store_breg_f32(float* %a) {
90 ; CHECK-LABEL: store_breg_f32
91 ; CHECK: str {{wzr|s[0-9]+}}, [x0]
92 store float 0.0, float* %a
96 define void @store_breg_f64(double* %a) {
97 ; CHECK-LABEL: store_breg_f64
98 ; CHECK: str {{xzr|d[0-9]+}}, [x0]
99 store double 0.0, double* %a
103 ; Load / Store Base Register + Immediate Offset
104 ; Max supported negative offset
105 define i32 @load_breg_immoff_1(i64 %a) {
106 ; CHECK-LABEL: load_breg_immoff_1
107 ; CHECK: ldur {{w[0-9]+}}, [x0, #-256]
108 %1 = add i64 %a, -256
109 %2 = inttoptr i64 %1 to i32*
114 ; Min not-supported negative offset
115 define i32 @load_breg_immoff_2(i64 %a) {
116 ; SDAG-LABEL: load_breg_immoff_2
117 ; SDAG: sub [[REG:x[0-9]+]], x0, #257
118 ; SDAG-NEXT: ldr {{w[0-9]+}}, {{\[}}[[REG]]{{\]}}
119 ; FAST-LABEL: load_breg_immoff_2
120 ; FAST: add [[REG:x[0-9]+]], x0, {{x[0-9]+}}
121 ; FAST-NEXT: ldr {{w[0-9]+}}, {{\[}}[[REG]]{{\]}}
122 %1 = add i64 %a, -257
123 %2 = inttoptr i64 %1 to i32*
128 ; Max supported unscaled offset
129 define i32 @load_breg_immoff_3(i64 %a) {
130 ; CHECK-LABEL: load_breg_immoff_3
131 ; CHECK: ldur {{w[0-9]+}}, [x0, #255]
133 %2 = inttoptr i64 %1 to i32*
138 ; Min un-supported unscaled offset
139 define i32 @load_breg_immoff_4(i64 %a) {
140 ; SDAG-LABEL: load_breg_immoff_4
141 ; SDAG: add [[REG:x[0-9]+]], x0, #257
142 ; SDAG-NEXT: ldr {{w[0-9]+}}, {{\[}}[[REG]]{{\]}}
143 ; FAST-LABEL: load_breg_immoff_4
144 ; FAST: add [[REG:x[0-9]+]], x0, {{x[0-9]+}}
145 ; FAST-NEXT: ldr {{w[0-9]+}}, {{\[}}[[REG]]{{\]}}
147 %2 = inttoptr i64 %1 to i32*
152 ; Max supported scaled offset
153 define i32 @load_breg_immoff_5(i64 %a) {
154 ; CHECK-LABEL: load_breg_immoff_5
155 ; CHECK: ldr {{w[0-9]+}}, [x0, #16380]
156 %1 = add i64 %a, 16380
157 %2 = inttoptr i64 %1 to i32*
162 ; Min un-supported scaled offset
163 define i32 @load_breg_immoff_6(i64 %a) {
164 ; SDAG-LABEL: load_breg_immoff_6
165 ; SDAG: add [[REG:x[0-9]+]], x0, #4, lsl #12
166 ; SDAG-NEXT: ldr {{w[0-9]+}}, {{\[}}[[REG]]{{\]}}
167 ; FAST-LABEL: load_breg_immoff_6
168 ; FAST: add [[REG:x[0-9]+]], x0, {{x[0-9]+}}
169 ; FAST-NEXT: ldr {{w[0-9]+}}, {{\[}}[[REG]]{{\]}}
170 %1 = add i64 %a, 16384
171 %2 = inttoptr i64 %1 to i32*
176 ; Max supported negative offset
177 define void @store_breg_immoff_1(i64 %a) {
178 ; CHECK-LABEL: store_breg_immoff_1
179 ; CHECK: stur wzr, [x0, #-256]
180 %1 = add i64 %a, -256
181 %2 = inttoptr i64 %1 to i32*
186 ; Min not-supported negative offset
187 define void @store_breg_immoff_2(i64 %a) {
188 ; SDAG-LABEL: store_breg_immoff_2
189 ; SDAG: sub [[REG:x[0-9]+]], x0, #257
190 ; SDAG-NEXT: str wzr, {{\[}}[[REG]]{{\]}}
191 ; FAST-LABEL: store_breg_immoff_2
192 ; FAST: add [[REG:x[0-9]+]], x0, {{x[0-9]+}}
193 ; FAST-NEXT: str wzr, {{\[}}[[REG]]{{\]}}
194 %1 = add i64 %a, -257
195 %2 = inttoptr i64 %1 to i32*
200 ; Max supported unscaled offset
201 define void @store_breg_immoff_3(i64 %a) {
202 ; CHECK-LABEL: store_breg_immoff_3
203 ; CHECK: stur wzr, [x0, #255]
205 %2 = inttoptr i64 %1 to i32*
210 ; Min un-supported unscaled offset
211 define void @store_breg_immoff_4(i64 %a) {
212 ; SDAG-LABEL: store_breg_immoff_4
213 ; SDAG: add [[REG:x[0-9]+]], x0, #257
214 ; SDAG-NEXT: str wzr, {{\[}}[[REG]]{{\]}}
215 ; FAST-LABEL: store_breg_immoff_4
216 ; FAST: add [[REG:x[0-9]+]], x0, {{x[0-9]+}}
217 ; FAST-NEXT: str wzr, {{\[}}[[REG]]{{\]}}
219 %2 = inttoptr i64 %1 to i32*
224 ; Max supported scaled offset
225 define void @store_breg_immoff_5(i64 %a) {
226 ; CHECK-LABEL: store_breg_immoff_5
227 ; CHECK: str wzr, [x0, #16380]
228 %1 = add i64 %a, 16380
229 %2 = inttoptr i64 %1 to i32*
234 ; Min un-supported scaled offset
235 define void @store_breg_immoff_6(i64 %a) {
236 ; SDAG-LABEL: store_breg_immoff_6
237 ; SDAG: add [[REG:x[0-9]+]], x0, #4, lsl #12
238 ; SDAG-NEXT: str wzr, {{\[}}[[REG]]{{\]}}
239 ; FAST-LABEL: store_breg_immoff_6
240 ; FAST: add [[REG:x[0-9]+]], x0, {{x[0-9]+}}
241 ; FAST-NEXT: str wzr, {{\[}}[[REG]]{{\]}}
242 %1 = add i64 %a, 16384
243 %2 = inttoptr i64 %1 to i32*
248 define i64 @load_breg_immoff_7(i64 %a) {
249 ; CHECK-LABEL: load_breg_immoff_7
250 ; CHECK: ldr {{x[0-9]+}}, [x0, #48]
252 %2 = inttoptr i64 %1 to i64*
258 define i64 @load_breg_immoff_8(i64 %a) {
259 ; CHECK-LABEL: load_breg_immoff_8
260 ; CHECK: ldr {{x[0-9]+}}, [x0, #48]
262 %2 = inttoptr i64 %1 to i64*
267 ; Load Base Register + Register Offset
268 define i64 @load_breg_offreg_1(i64 %a, i64 %b) {
269 ; CHECK-LABEL: load_breg_offreg_1
270 ; CHECK: ldr {{x[0-9]+}}, [x0, x1]
272 %2 = inttoptr i64 %1 to i64*
278 define i64 @load_breg_offreg_2(i64 %a, i64 %b) {
279 ; CHECK-LABEL: load_breg_offreg_2
280 ; CHECK: ldr {{x[0-9]+}}, [x1, x0]
282 %2 = inttoptr i64 %1 to i64*
287 ; Load Base Register + Register Offset + Immediate Offset
288 define i64 @load_breg_offreg_immoff_1(i64 %a, i64 %b) {
289 ; CHECK-LABEL: load_breg_offreg_immoff_1
290 ; CHECK: add [[REG:x[0-9]+]], x0, x1
291 ; CHECK-NEXT: ldr x0, {{\[}}[[REG]], #48{{\]}}
294 %3 = inttoptr i64 %2 to i64*
299 define i64 @load_breg_offreg_immoff_2(i64 %a, i64 %b) {
300 ; SDAG-LABEL: load_breg_offreg_immoff_2
301 ; SDAG: add [[REG1:x[0-9]+]], x0, x1
302 ; SDAG-NEXT: add [[REG2:x[0-9]+]], [[REG1]], #15, lsl #12
303 ; SDAG-NEXT: ldr x0, {{\[}}[[REG2]]{{\]}}
304 ; FAST-LABEL: load_breg_offreg_immoff_2
305 ; FAST: add [[REG:x[0-9]+]], x0, {{x[0-9]+}}
306 ; FAST-NEXT: ldr x0, {{\[}}[[REG]], x1{{\]}}
308 %2 = add i64 %1, 61440
309 %3 = inttoptr i64 %2 to i64*
314 ; Load Base Register + Scaled Register Offset
315 define i32 @load_breg_shift_offreg_1(i64 %a, i64 %b) {
316 ; CHECK-LABEL: load_breg_shift_offreg_1
317 ; CHECK: ldr {{w[0-9]+}}, [x1, x0, lsl #2]
320 %3 = inttoptr i64 %2 to i32*
325 define i32 @load_breg_shift_offreg_2(i64 %a, i64 %b) {
326 ; CHECK-LABEL: load_breg_shift_offreg_2
327 ; CHECK: ldr {{w[0-9]+}}, [x1, x0, lsl #2]
330 %3 = inttoptr i64 %2 to i32*
335 define i32 @load_breg_shift_offreg_3(i64 %a, i64 %b) {
336 ; SDAG-LABEL: load_breg_shift_offreg_3
337 ; SDAG: lsl [[REG:x[0-9]+]], x0, #2
338 ; SDAG-NEXT: ldr {{w[0-9]+}}, {{\[}}[[REG]], x1, lsl #2{{\]}}
339 ; FAST-LABEL: load_breg_shift_offreg_3
340 ; FAST: lsl [[REG:x[0-9]+]], x1, {{x[0-9]+}}
341 ; FAST-NEXT: ldr {{w[0-9]+}}, {{\[}}[[REG]], x0, lsl #2{{\]}}
345 %4 = inttoptr i64 %3 to i32*
350 define i32 @load_breg_shift_offreg_4(i64 %a, i64 %b) {
351 ; SDAG-LABEL: load_breg_shift_offreg_4
352 ; SDAG: lsl [[REG:x[0-9]+]], x1, #2
353 ; SDAG-NEXT: ldr {{w[0-9]+}}, {{\[}}[[REG]], x0, lsl #2{{\]}}
354 ; FAST-LABEL: load_breg_shift_offreg_4
355 ; FAST: lsl [[REG:x[0-9]+]], x0, {{x[0-9]+}}
356 ; FAST-NEXT: ldr {{w[0-9]+}}, {{\[}}[[REG]], x1, lsl #2{{\]}}
360 %4 = inttoptr i64 %3 to i32*
365 define i32 @load_breg_shift_offreg_5(i64 %a, i64 %b) {
366 ; SDAG-LABEL: load_breg_shift_offreg_5
367 ; SDAG: lsl [[REG:x[0-9]+]], x1, #3
368 ; SDAG-NEXT: ldr {{w[0-9]+}}, {{\[}}[[REG]], x0, lsl #2{{\]}}
369 ; FAST-LABEL: load_breg_shift_offreg_5
370 ; FAST: lsl [[REG:x[0-9]+]], x1, {{x[0-9]+}}
371 ; FAST-NEXT: ldr {{w[0-9]+}}, {{\[}}[[REG]], x0, lsl #2{{\]}}
375 %4 = inttoptr i64 %3 to i32*
381 ; Load Base Register + Scaled Register Offset + Sign/Zero extension
382 define i32 @load_breg_zext_shift_offreg_1(i32 %a, i64 %b) {
383 ; CHECK-LABEL: load_breg_zext_shift_offreg_1
384 ; CHECK: ldr {{w[0-9]+}}, [x1, w0, uxtw #2]
385 %1 = zext i32 %a to i64
388 %4 = inttoptr i64 %3 to i32*
393 define i32 @load_breg_zext_shift_offreg_2(i32 %a, i64 %b) {
394 ; CHECK-LABEL: load_breg_zext_shift_offreg_2
395 ; CHECK: ldr {{w[0-9]+}}, [x1, w0, uxtw #2]
396 %1 = zext i32 %a to i64
399 %4 = inttoptr i64 %3 to i32*
404 define i32 @load_breg_sext_shift_offreg_1(i32 %a, i64 %b) {
405 ; CHECK-LABEL: load_breg_sext_shift_offreg_1
406 ; CHECK: ldr {{w[0-9]+}}, [x1, w0, sxtw #2]
407 %1 = sext i32 %a to i64
410 %4 = inttoptr i64 %3 to i32*
415 define i32 @load_breg_sext_shift_offreg_2(i32 %a, i64 %b) {
416 ; CHECK-LABEL: load_breg_sext_shift_offreg_2
417 ; CHECK: ldr {{w[0-9]+}}, [x1, w0, sxtw #2]
418 %1 = sext i32 %a to i64
421 %4 = inttoptr i64 %3 to i32*