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
3
4; Load / Store Base Register only
5define zeroext i1 @load_breg_i1(i1* %a) {
6; CHECK-LABEL: load_breg_i1
7; CHECK:       ldrb {{w[0-9]+}}, [x0]
8  %1 = load i1* %a
9  ret i1 %1
10}
11
12define zeroext i8 @load_breg_i8(i8* %a) {
13; CHECK-LABEL: load_breg_i8
14; CHECK:       ldrb {{w[0-9]+}}, [x0]
15  %1 = load i8* %a
16  ret i8 %1
17}
18
19define zeroext i16 @load_breg_i16(i16* %a) {
20; CHECK-LABEL: load_breg_i16
21; CHECK:       ldrh {{w[0-9]+}}, [x0]
22  %1 = load i16* %a
23  ret i16 %1
24}
25
26define i32 @load_breg_i32(i32* %a) {
27; CHECK-LABEL: load_breg_i32
28; CHECK:       ldr {{w[0-9]+}}, [x0]
29  %1 = load i32* %a
30  ret i32 %1
31}
32
33define i64 @load_breg_i64(i64* %a) {
34; CHECK-LABEL: load_breg_i64
35; CHECK:       ldr {{x[0-9]+}}, [x0]
36  %1 = load i64* %a
37  ret i64 %1
38}
39
40define float @load_breg_f32(float* %a) {
41; CHECK-LABEL: load_breg_f32
42; CHECK:       ldr {{s[0-9]+}}, [x0]
43  %1 = load float* %a
44  ret float %1
45}
46
47define double @load_breg_f64(double* %a) {
48; CHECK-LABEL: load_breg_f64
49; CHECK:       ldr {{d[0-9]+}}, [x0]
50  %1 = load double* %a
51  ret double %1
52}
53
54define void @store_breg_i1(i1* %a) {
55; CHECK-LABEL: store_breg_i1
56; CHECK:       strb wzr, [x0]
57  store i1 0, i1* %a
58  ret void
59}
60
61define void @store_breg_i1_2(i1* %a) {
62; CHECK-LABEL: store_breg_i1_2
63; CHECK:       strb {{w[0-9]+}}, [x0]
64  store i1 true, i1* %a
65  ret void
66}
67
68define void @store_breg_i8(i8* %a) {
69; CHECK-LABEL: store_breg_i8
70; CHECK:       strb wzr, [x0]
71  store i8 0, i8* %a
72  ret void
73}
74
75define void @store_breg_i16(i16* %a) {
76; CHECK-LABEL: store_breg_i16
77; CHECK:       strh wzr, [x0]
78  store i16 0, i16* %a
79  ret void
80}
81
82define void @store_breg_i32(i32* %a) {
83; CHECK-LABEL: store_breg_i32
84; CHECK:       str wzr, [x0]
85  store i32 0, i32* %a
86  ret void
87}
88
89define void @store_breg_i64(i64* %a) {
90; CHECK-LABEL: store_breg_i64
91; CHECK:       str xzr, [x0]
92  store i64 0, i64* %a
93  ret void
94}
95
96define void @store_breg_f32(float* %a) {
97; CHECK-LABEL: store_breg_f32
98; CHECK:       str wzr, [x0]
99  store float 0.0, float* %a
100  ret void
101}
102
103define void @store_breg_f64(double* %a) {
104; CHECK-LABEL: store_breg_f64
105; CHECK:       str xzr, [x0]
106  store double 0.0, double* %a
107  ret void
108}
109
110; Load Immediate
111define i32 @load_immoff_1() {
112; CHECK-LABEL: load_immoff_1
113; CHECK:       orr {{w|x}}[[REG:[0-9]+]], {{wzr|xzr}}, #0x80
114; CHECK:       ldr {{w[0-9]+}}, {{\[}}x[[REG]]{{\]}}
115  %1 = inttoptr i64 128 to i32*
116  %2 = load i32* %1
117  ret i32 %2
118}
119
120; Load / Store Base Register + Immediate Offset
121; Max supported negative offset
122define i32 @load_breg_immoff_1(i64 %a) {
123; CHECK-LABEL: load_breg_immoff_1
124; CHECK:       ldur {{w[0-9]+}}, [x0, #-256]
125  %1 = add i64 %a, -256
126  %2 = inttoptr i64 %1 to i32*
127  %3 = load i32* %2
128  ret i32 %3
129}
130
131; Min not-supported negative offset
132define i32 @load_breg_immoff_2(i64 %a) {
133; CHECK-LABEL: load_breg_immoff_2
134; CHECK:       sub [[REG:x[0-9]+]], x0, #257
135; CHECK-NEXT:  ldr {{w[0-9]+}}, {{\[}}[[REG]]{{\]}}
136  %1 = add i64 %a, -257
137  %2 = inttoptr i64 %1 to i32*
138  %3 = load i32* %2
139  ret i32 %3
140}
141
142; Max supported unscaled offset
143define i32 @load_breg_immoff_3(i64 %a) {
144; CHECK-LABEL: load_breg_immoff_3
145; CHECK:       ldur {{w[0-9]+}}, [x0, #255]
146  %1 = add i64 %a, 255
147  %2 = inttoptr i64 %1 to i32*
148  %3 = load i32* %2
149  ret i32 %3
150}
151
152; Min un-supported unscaled offset
153define i32 @load_breg_immoff_4(i64 %a) {
154; CHECK-LABEL: load_breg_immoff_4
155; CHECK:       add [[REG:x[0-9]+]], x0, #257
156; CHECK-NEXT:  ldr {{w[0-9]+}}, {{\[}}[[REG]]{{\]}}
157  %1 = add i64 %a, 257
158  %2 = inttoptr i64 %1 to i32*
159  %3 = load i32* %2
160  ret i32 %3
161}
162
163; Max supported scaled offset
164define i32 @load_breg_immoff_5(i64 %a) {
165; CHECK-LABEL: load_breg_immoff_5
166; CHECK:       ldr {{w[0-9]+}}, [x0, #16380]
167  %1 = add i64 %a, 16380
168  %2 = inttoptr i64 %1 to i32*
169  %3 = load i32* %2
170  ret i32 %3
171}
172
173; Min un-supported scaled offset
174define i32 @load_breg_immoff_6(i64 %a) {
175; SDAG-LABEL: load_breg_immoff_6
176; SDAG:       orr	w[[NUM:[0-9]+]], wzr, #0x4000
177; SDAG-NEXT:  ldr {{w[0-9]+}}, [x0, x[[NUM]]]
178; FAST-LABEL: load_breg_immoff_6
179; FAST:       add [[REG:x[0-9]+]], x0, #4, lsl #12
180; FAST-NEXT:  ldr {{w[0-9]+}}, {{\[}}[[REG]]{{\]}}
181  %1 = add i64 %a, 16384
182  %2 = inttoptr i64 %1 to i32*
183  %3 = load i32* %2
184  ret i32 %3
185}
186
187; Max supported negative offset
188define void @store_breg_immoff_1(i64 %a) {
189; CHECK-LABEL: store_breg_immoff_1
190; CHECK:       stur wzr, [x0, #-256]
191  %1 = add i64 %a, -256
192  %2 = inttoptr i64 %1 to i32*
193  store i32 0, i32* %2
194  ret void
195}
196
197; Min not-supported negative offset
198define void @store_breg_immoff_2(i64 %a) {
199; CHECK-LABEL: store_breg_immoff_2
200; CHECK:       sub [[REG:x[0-9]+]], x0, #257
201; CHECK-NEXT:  str wzr, {{\[}}[[REG]]{{\]}}
202  %1 = add i64 %a, -257
203  %2 = inttoptr i64 %1 to i32*
204  store i32 0, i32* %2
205  ret void
206}
207
208; Max supported unscaled offset
209define void @store_breg_immoff_3(i64 %a) {
210; CHECK-LABEL: store_breg_immoff_3
211; CHECK:       stur wzr, [x0, #255]
212  %1 = add i64 %a, 255
213  %2 = inttoptr i64 %1 to i32*
214  store i32 0, i32* %2
215  ret void
216}
217
218; Min un-supported unscaled offset
219define void @store_breg_immoff_4(i64 %a) {
220; CHECK-LABEL: store_breg_immoff_4
221; CHECK:       add [[REG:x[0-9]+]], x0, #257
222; CHECK-NEXT:  str wzr, {{\[}}[[REG]]{{\]}}
223  %1 = add i64 %a, 257
224  %2 = inttoptr i64 %1 to i32*
225  store i32 0, i32* %2
226  ret void
227}
228
229; Max supported scaled offset
230define void @store_breg_immoff_5(i64 %a) {
231; CHECK-LABEL: store_breg_immoff_5
232; CHECK:       str wzr, [x0, #16380]
233  %1 = add i64 %a, 16380
234  %2 = inttoptr i64 %1 to i32*
235  store i32 0, i32* %2
236  ret void
237}
238
239; Min un-supported scaled offset
240define void @store_breg_immoff_6(i64 %a) {
241; SDAG-LABEL: store_breg_immoff_6
242; SDAG:       orr	w[[NUM:[0-9]+]], wzr, #0x4000
243; SDAG-NEXT:  str wzr, [x0, x[[NUM]]]
244; FAST-LABEL: store_breg_immoff_6
245; FAST:       add [[REG:x[0-9]+]], x0, #4, lsl #12
246; FAST-NEXT:  str wzr, {{\[}}[[REG]]{{\]}}
247  %1 = add i64 %a, 16384
248  %2 = inttoptr i64 %1 to i32*
249  store i32 0, i32* %2
250  ret void
251}
252
253define i64 @load_breg_immoff_7(i64 %a) {
254; CHECK-LABEL: load_breg_immoff_7
255; CHECK:       ldr {{x[0-9]+}}, [x0, #48]
256  %1 = add i64 %a, 48
257  %2 = inttoptr i64 %1 to i64*
258  %3 = load i64* %2
259  ret i64 %3
260}
261
262; Flip add operands
263define i64 @load_breg_immoff_8(i64 %a) {
264; CHECK-LABEL: load_breg_immoff_8
265; CHECK:       ldr {{x[0-9]+}}, [x0, #48]
266  %1 = add i64 48, %a
267  %2 = inttoptr i64 %1 to i64*
268  %3 = load i64* %2
269  ret i64 %3
270}
271
272; Load Base Register + Register Offset
273define i64 @load_breg_offreg_1(i64 %a, i64 %b) {
274; CHECK-LABEL: load_breg_offreg_1
275; CHECK:       ldr {{x[0-9]+}}, [x0, x1]
276  %1 = add i64 %a, %b
277  %2 = inttoptr i64 %1 to i64*
278  %3 = load i64* %2
279  ret i64 %3
280}
281
282; Flip add operands
283define i64 @load_breg_offreg_2(i64 %a, i64 %b) {
284; CHECK-LABEL: load_breg_offreg_2
285; CHECK:       ldr {{x[0-9]+}}, [x1, x0]
286  %1 = add i64 %b, %a
287  %2 = inttoptr i64 %1 to i64*
288  %3 = load i64* %2
289  ret i64 %3
290}
291
292; Load Base Register + Register Offset + Immediate Offset
293define i64 @load_breg_offreg_immoff_1(i64 %a, i64 %b) {
294; CHECK-LABEL: load_breg_offreg_immoff_1
295; CHECK:       add [[REG:x[0-9]+]], x0, x1
296; CHECK-NEXT:  ldr x0, {{\[}}[[REG]], #48{{\]}}
297  %1 = add i64 %a, %b
298  %2 = add i64 %1, 48
299  %3 = inttoptr i64 %2 to i64*
300  %4 = load i64* %3
301  ret i64 %4
302}
303
304define i64 @load_breg_offreg_immoff_2(i64 %a, i64 %b) {
305; SDAG-LABEL: load_breg_offreg_immoff_2
306; SDAG:       add [[REG1:x[0-9]+]], x0, x1
307; SDAG-NEXT:  orr w[[NUM:[0-9]+]], wzr, #0xf000
308; SDAG-NEXT:  ldr x0, {{\[}}[[REG1]], x[[NUM]]]
309; FAST-LABEL: load_breg_offreg_immoff_2
310; FAST:       add [[REG:x[0-9]+]], x0, #15, lsl #12
311; FAST-NEXT:  ldr x0, {{\[}}[[REG]], x1{{\]}}
312  %1 = add i64 %a, %b
313  %2 = add i64 %1, 61440
314  %3 = inttoptr i64 %2 to i64*
315  %4 = load i64* %3
316  ret i64 %4
317}
318
319; Load Scaled Register Offset
320define i32 @load_shift_offreg_1(i64 %a) {
321; CHECK-LABEL: load_shift_offreg_1
322; CHECK:       lsl [[REG:x[0-9]+]], x0, #2
323; CHECK:       ldr {{w[0-9]+}}, {{\[}}[[REG]]{{\]}}
324  %1 = shl i64 %a, 2
325  %2 = inttoptr i64 %1 to i32*
326  %3 = load i32* %2
327  ret i32 %3
328}
329
330define i32 @load_mul_offreg_1(i64 %a) {
331; CHECK-LABEL: load_mul_offreg_1
332; CHECK:       lsl [[REG:x[0-9]+]], x0, #2
333; CHECK:       ldr {{w[0-9]+}}, {{\[}}[[REG]]{{\]}}
334  %1 = mul i64 %a, 4
335  %2 = inttoptr i64 %1 to i32*
336  %3 = load i32* %2
337  ret i32 %3
338}
339
340; Load Base Register + Scaled Register Offset
341define i32 @load_breg_shift_offreg_1(i64 %a, i64 %b) {
342; CHECK-LABEL: load_breg_shift_offreg_1
343; CHECK:       ldr {{w[0-9]+}}, [x1, x0, lsl #2]
344  %1 = shl i64 %a, 2
345  %2 = add i64 %1, %b
346  %3 = inttoptr i64 %2 to i32*
347  %4 = load i32* %3
348  ret i32 %4
349}
350
351define i32 @load_breg_shift_offreg_2(i64 %a, i64 %b) {
352; CHECK-LABEL: load_breg_shift_offreg_2
353; CHECK:       ldr {{w[0-9]+}}, [x1, x0, lsl #2]
354  %1 = shl i64 %a, 2
355  %2 = add i64 %b, %1
356  %3 = inttoptr i64 %2 to i32*
357  %4 = load i32* %3
358  ret i32 %4
359}
360
361define i32 @load_breg_shift_offreg_3(i64 %a, i64 %b) {
362; SDAG-LABEL: load_breg_shift_offreg_3
363; SDAG:       lsl [[REG:x[0-9]+]], x0, #2
364; SDAG-NEXT:  ldr {{w[0-9]+}}, {{\[}}[[REG]], x1, lsl #2{{\]}}
365; FAST-LABEL: load_breg_shift_offreg_3
366; FAST:       lsl [[REG:x[0-9]+]], x1, #2
367; FAST-NEXT:  ldr {{w[0-9]+}}, {{\[}}[[REG]], x0, lsl #2{{\]}}
368  %1 = shl i64 %a, 2
369  %2 = shl i64 %b, 2
370  %3 = add i64 %1, %2
371  %4 = inttoptr i64 %3 to i32*
372  %5 = load i32* %4
373  ret i32 %5
374}
375
376define i32 @load_breg_shift_offreg_4(i64 %a, i64 %b) {
377; SDAG-LABEL: load_breg_shift_offreg_4
378; SDAG:       lsl [[REG:x[0-9]+]], x1, #2
379; SDAG-NEXT:  ldr {{w[0-9]+}}, {{\[}}[[REG]], x0, lsl #2{{\]}}
380; FAST-LABEL: load_breg_shift_offreg_4
381; FAST:       lsl [[REG:x[0-9]+]], x0, #2
382; FAST-NEXT:  ldr {{w[0-9]+}}, {{\[}}[[REG]], x1, lsl #2{{\]}}
383  %1 = shl i64 %a, 2
384  %2 = shl i64 %b, 2
385  %3 = add i64 %2, %1
386  %4 = inttoptr i64 %3 to i32*
387  %5 = load i32* %4
388  ret i32 %5
389}
390
391define i32 @load_breg_shift_offreg_5(i64 %a, i64 %b) {
392; SDAG-LABEL: load_breg_shift_offreg_5
393; SDAG:       lsl [[REG:x[0-9]+]], x1, #3
394; SDAG-NEXT:  ldr {{w[0-9]+}}, {{\[}}[[REG]], x0, lsl #2{{\]}}
395; FAST-LABEL: load_breg_shift_offreg_5
396; FAST:       lsl [[REG:x[0-9]+]], x1, #3
397; FAST-NEXT:  ldr {{w[0-9]+}}, {{\[}}[[REG]], x0, lsl #2{{\]}}
398  %1 = shl i64 %a, 2
399  %2 = shl i64 %b, 3
400  %3 = add i64 %1, %2
401  %4 = inttoptr i64 %3 to i32*
402  %5 = load i32* %4
403  ret i32 %5
404}
405
406define i32 @load_breg_mul_offreg_1(i64 %a, i64 %b) {
407; CHECK-LABEL: load_breg_mul_offreg_1
408; CHECK:       ldr {{w[0-9]+}}, [x1, x0, lsl #2]
409  %1 = mul i64 %a, 4
410  %2 = add i64 %1, %b
411  %3 = inttoptr i64 %2 to i32*
412  %4 = load i32* %3
413  ret i32 %4
414}
415
416define zeroext i8 @load_breg_and_offreg_1(i64 %a, i64 %b) {
417; CHECK-LABEL: load_breg_and_offreg_1
418; CHECK:       ldrb {{w[0-9]+}}, [x1, w0, uxtw]
419  %1 = and i64 %a, 4294967295
420  %2 = add i64 %1, %b
421  %3 = inttoptr i64 %2 to i8*
422  %4 = load i8* %3
423  ret i8 %4
424}
425
426define zeroext i16 @load_breg_and_offreg_2(i64 %a, i64 %b) {
427; CHECK-LABEL: load_breg_and_offreg_2
428; CHECK:       ldrh {{w[0-9]+}}, [x1, w0, uxtw #1]
429  %1 = and i64 %a, 4294967295
430  %2 = shl i64 %1, 1
431  %3 = add i64 %2, %b
432  %4 = inttoptr i64 %3 to i16*
433  %5 = load i16* %4
434  ret i16 %5
435}
436
437define i32 @load_breg_and_offreg_3(i64 %a, i64 %b) {
438; CHECK-LABEL: load_breg_and_offreg_3
439; CHECK:       ldr {{w[0-9]+}}, [x1, w0, uxtw #2]
440  %1 = and i64 %a, 4294967295
441  %2 = shl i64 %1, 2
442  %3 = add i64 %2, %b
443  %4 = inttoptr i64 %3 to i32*
444  %5 = load i32* %4
445  ret i32 %5
446}
447
448define i64 @load_breg_and_offreg_4(i64 %a, i64 %b) {
449; CHECK-LABEL: load_breg_and_offreg_4
450; CHECK:       ldr {{x[0-9]+}}, [x1, w0, uxtw #3]
451  %1 = and i64 %a, 4294967295
452  %2 = shl i64 %1, 3
453  %3 = add i64 %2, %b
454  %4 = inttoptr i64 %3 to i64*
455  %5 = load i64* %4
456  ret i64 %5
457}
458
459; Not all 'and' instructions have immediates.
460define i64 @load_breg_and_offreg_5(i64 %a, i64 %b, i64 %c) {
461; CHECK-LABEL: load_breg_and_offreg_5
462; CHECK:       and [[REG:x[0-9]+]], x0, x2
463; CHECK-NEXT:  ldr {{x[0-9]+}}, {{\[}}[[REG]], x1{{\]}}
464  %1 = and i64 %a, %c
465  %2 = add i64 %1, %b
466  %3 = inttoptr i64 %2 to i64*
467  %4 = load i64* %3
468  ret i64 %4
469}
470
471define i64 @load_breg_and_offreg_6(i64 %a, i64 %b, i64 %c) {
472; CHECK-LABEL: load_breg_and_offreg_6
473; CHECK:       and [[REG:x[0-9]+]], x0, x2
474; CHECK-NEXT:  ldr {{x[0-9]+}}, {{\[}}x1, [[REG]], lsl #3{{\]}}
475  %1 = and i64 %a, %c
476  %2 = shl i64 %1, 3
477  %3 = add i64 %2, %b
478  %4 = inttoptr i64 %3 to i64*
479  %5 = load i64* %4
480  ret i64 %5
481}
482
483; Load Base Register + Scaled Register Offset + Sign/Zero extension
484define i32 @load_breg_zext_shift_offreg_1(i32 %a, i64 %b) {
485; CHECK-LABEL: load_breg_zext_shift_offreg_1
486; CHECK:       ldr {{w[0-9]+}}, [x1, w0, uxtw #2]
487  %1 = zext i32 %a to i64
488  %2 = shl i64 %1, 2
489  %3 = add i64 %2, %b
490  %4 = inttoptr i64 %3 to i32*
491  %5 = load i32* %4
492  ret i32 %5
493}
494
495define i32 @load_breg_zext_shift_offreg_2(i32 %a, i64 %b) {
496; CHECK-LABEL: load_breg_zext_shift_offreg_2
497; CHECK:       ldr {{w[0-9]+}}, [x1, w0, uxtw #2]
498  %1 = zext i32 %a to i64
499  %2 = shl i64 %1, 2
500  %3 = add i64 %b, %2
501  %4 = inttoptr i64 %3 to i32*
502  %5 = load i32* %4
503  ret i32 %5
504}
505
506define i32 @load_breg_zext_mul_offreg_1(i32 %a, i64 %b) {
507; CHECK-LABEL: load_breg_zext_mul_offreg_1
508; CHECK:       ldr {{w[0-9]+}}, [x1, w0, uxtw #2]
509  %1 = zext i32 %a to i64
510  %2 = mul i64 %1, 4
511  %3 = add i64 %2, %b
512  %4 = inttoptr i64 %3 to i32*
513  %5 = load i32* %4
514  ret i32 %5
515}
516
517define i32 @load_breg_sext_shift_offreg_1(i32 %a, i64 %b) {
518; CHECK-LABEL: load_breg_sext_shift_offreg_1
519; CHECK:       ldr {{w[0-9]+}}, [x1, w0, sxtw #2]
520  %1 = sext i32 %a to i64
521  %2 = shl i64 %1, 2
522  %3 = add i64 %2, %b
523  %4 = inttoptr i64 %3 to i32*
524  %5 = load i32* %4
525  ret i32 %5
526}
527
528define i32 @load_breg_sext_shift_offreg_2(i32 %a, i64 %b) {
529; CHECK-LABEL: load_breg_sext_shift_offreg_2
530; CHECK:       ldr {{w[0-9]+}}, [x1, w0, sxtw #2]
531  %1 = sext i32 %a to i64
532  %2 = shl i64 %1, 2
533  %3 = add i64 %b, %2
534  %4 = inttoptr i64 %3 to i32*
535  %5 = load i32* %4
536  ret i32 %5
537}
538
539; Make sure that we don't drop the first 'add' instruction.
540define i32 @load_breg_sext_shift_offreg_3(i32 %a, i64 %b) {
541; CHECK-LABEL: load_breg_sext_shift_offreg_3
542; CHECK:       add [[REG:w[0-9]+]], w0, #4
543; CHECK:       ldr {{w[0-9]+}}, {{\[}}x1, [[REG]], sxtw #2{{\]}}
544  %1 = add i32 %a, 4
545  %2 = sext i32 %1 to i64
546  %3 = shl i64 %2, 2
547  %4 = add i64 %b, %3
548  %5 = inttoptr i64 %4 to i32*
549  %6 = load i32* %5
550  ret i32 %6
551}
552
553
554define i32 @load_breg_sext_mul_offreg_1(i32 %a, i64 %b) {
555; CHECK-LABEL: load_breg_sext_mul_offreg_1
556; CHECK:       ldr {{w[0-9]+}}, [x1, w0, sxtw #2]
557  %1 = sext i32 %a to i64
558  %2 = mul i64 %1, 4
559  %3 = add i64 %2, %b
560  %4 = inttoptr i64 %3 to i32*
561  %5 = load i32* %4
562  ret i32 %5
563}
564
565; Load Scaled Register Offset + Immediate Offset + Sign/Zero extension
566define i64 @load_sext_shift_offreg_imm1(i32 %a) {
567; CHECK-LABEL: load_sext_shift_offreg_imm1
568; CHECK:       sbfiz [[REG:x[0-9]+]], {{x[0-9]+}}, #3, #32
569; CHECK-NEXT:  ldr {{x[0-9]+}}, {{\[}}[[REG]], #8{{\]}}
570  %1 = sext i32 %a to i64
571  %2 = shl i64 %1, 3
572  %3 = add i64 %2, 8
573  %4 = inttoptr i64 %3 to i64*
574  %5 = load i64* %4
575  ret i64 %5
576}
577
578; Load Base Register + Scaled Register Offset + Immediate Offset + Sign/Zero extension
579define i64 @load_breg_sext_shift_offreg_imm1(i32 %a, i64 %b) {
580; CHECK-LABEL: load_breg_sext_shift_offreg_imm1
581; CHECK:       add [[REG:x[0-9]+]], x1, w0, sxtw #3
582; CHECK-NEXT:  ldr {{x[0-9]+}}, {{\[}}[[REG]], #8{{\]}}
583  %1 = sext i32 %a to i64
584  %2 = shl i64 %1, 3
585  %3 = add i64 %b, %2
586  %4 = add i64 %3, 8
587  %5 = inttoptr i64 %4 to i64*
588  %6 = load i64* %5
589  ret i64 %6
590}
591
592; Test that the kill flag is not set - the machine instruction verifier does that for us.
593define i64 @kill_reg(i64 %a) {
594  %1 = sub i64 %a, 8
595  %2 = add i64 %1, 96
596  %3 = inttoptr i64 %2 to i64*
597  %4 = load i64* %3
598  %5 = add i64 %2, %4
599  ret i64 %5
600}
601
602define void @store_fi(i64 %i) {
603; CHECK-LABEL: store_fi
604; CHECK:       mov [[REG:x[0-9]+]], sp
605; CHECK:       str {{w[0-9]+}}, {{\[}}[[REG]], x0, lsl #2{{\]}}
606  %1 = alloca [8 x i32]
607  %2 = ptrtoint [8 x i32]* %1 to i64
608  %3 = mul i64 %i, 4
609  %4 = add i64 %2, %3
610  %5 = inttoptr i64 %4 to i32*
611  store i32 47, i32* %5, align 4
612  ret void
613}
614
615define i32 @load_fi(i64 %i) {
616; CHECK-LABEL: load_fi
617; CHECK:       mov [[REG:x[0-9]+]], sp
618; CHECK:       ldr {{w[0-9]+}}, {{\[}}[[REG]], x0, lsl #2{{\]}}
619  %1 = alloca [8 x i32]
620  %2 = ptrtoint [8 x i32]* %1 to i64
621  %3 = mul i64 %i, 4
622  %4 = add i64 %2, %3
623  %5 = inttoptr i64 %4 to i32*
624  %6 = load i32* %5, align 4
625  ret i32 %6
626}
627
628