blob: 86755d90c63241666cc263a6cabb3545af61e6d5 [file] [log] [blame]
Juergen Ributzka100a9b72014-08-27 21:04:52 +00001; RUN: llc -mtriple=aarch64-apple-darwin -verify-machineinstrs < %s | FileCheck %s --check-prefix=CHECK --check-prefix=SDAG
2; RUN: llc -mtriple=aarch64-apple-darwin -O0 -fast-isel-abort -verify-machineinstrs < %s | FileCheck %s --check-prefix=CHECK --check-prefix=FAST
Juergen Ributzkab46ea082014-08-19 19:44:17 +00003
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
Juergen Ributzka100a9b72014-08-27 21:04:52 +000056; CHECK: strb wzr, [x0]
Juergen Ributzkab46ea082014-08-19 19:44:17 +000057 store i1 0, i1* %a
58 ret void
59}
60
Juergen Ributzka100a9b72014-08-27 21:04:52 +000061define 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
Juergen Ributzkab46ea082014-08-19 19:44:17 +000068define 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
Juergen Ributzka100a9b72014-08-27 21:04:52 +000098; CHECK: str wzr, [x0]
Juergen Ributzkab46ea082014-08-19 19:44:17 +000099 store float 0.0, float* %a
100 ret void
101}
102
103define void @store_breg_f64(double* %a) {
104; CHECK-LABEL: store_breg_f64
Juergen Ributzka100a9b72014-08-27 21:04:52 +0000105; CHECK: str xzr, [x0]
Juergen Ributzkab46ea082014-08-19 19:44:17 +0000106 store double 0.0, double* %a
107 ret void
108}
109
Juergen Ributzka3c1b2862014-08-27 21:38:33 +0000110; 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
Juergen Ributzkab46ea082014-08-19 19:44:17 +0000120; 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; SDAG-LABEL: load_breg_immoff_2
134; SDAG: sub [[REG:x[0-9]+]], x0, #257
135; SDAG-NEXT: ldr {{w[0-9]+}}, {{\[}}[[REG]]{{\]}}
136; FAST-LABEL: load_breg_immoff_2
137; FAST: add [[REG:x[0-9]+]], x0, {{x[0-9]+}}
138; FAST-NEXT: ldr {{w[0-9]+}}, {{\[}}[[REG]]{{\]}}
139 %1 = add i64 %a, -257
140 %2 = inttoptr i64 %1 to i32*
141 %3 = load i32* %2
142 ret i32 %3
143}
144
145; Max supported unscaled offset
146define i32 @load_breg_immoff_3(i64 %a) {
147; CHECK-LABEL: load_breg_immoff_3
148; CHECK: ldur {{w[0-9]+}}, [x0, #255]
149 %1 = add i64 %a, 255
150 %2 = inttoptr i64 %1 to i32*
151 %3 = load i32* %2
152 ret i32 %3
153}
154
155; Min un-supported unscaled offset
156define i32 @load_breg_immoff_4(i64 %a) {
157; SDAG-LABEL: load_breg_immoff_4
158; SDAG: add [[REG:x[0-9]+]], x0, #257
159; SDAG-NEXT: ldr {{w[0-9]+}}, {{\[}}[[REG]]{{\]}}
160; FAST-LABEL: load_breg_immoff_4
161; FAST: add [[REG:x[0-9]+]], x0, {{x[0-9]+}}
162; FAST-NEXT: ldr {{w[0-9]+}}, {{\[}}[[REG]]{{\]}}
163 %1 = add i64 %a, 257
164 %2 = inttoptr i64 %1 to i32*
165 %3 = load i32* %2
166 ret i32 %3
167}
168
169; Max supported scaled offset
170define i32 @load_breg_immoff_5(i64 %a) {
171; CHECK-LABEL: load_breg_immoff_5
172; CHECK: ldr {{w[0-9]+}}, [x0, #16380]
173 %1 = add i64 %a, 16380
174 %2 = inttoptr i64 %1 to i32*
175 %3 = load i32* %2
176 ret i32 %3
177}
178
179; Min un-supported scaled offset
180define i32 @load_breg_immoff_6(i64 %a) {
181; SDAG-LABEL: load_breg_immoff_6
182; SDAG: add [[REG:x[0-9]+]], x0, #4, lsl #12
183; SDAG-NEXT: ldr {{w[0-9]+}}, {{\[}}[[REG]]{{\]}}
184; FAST-LABEL: load_breg_immoff_6
185; FAST: add [[REG:x[0-9]+]], x0, {{x[0-9]+}}
186; FAST-NEXT: ldr {{w[0-9]+}}, {{\[}}[[REG]]{{\]}}
187 %1 = add i64 %a, 16384
188 %2 = inttoptr i64 %1 to i32*
189 %3 = load i32* %2
190 ret i32 %3
191}
192
193; Max supported negative offset
194define void @store_breg_immoff_1(i64 %a) {
195; CHECK-LABEL: store_breg_immoff_1
196; CHECK: stur wzr, [x0, #-256]
197 %1 = add i64 %a, -256
198 %2 = inttoptr i64 %1 to i32*
199 store i32 0, i32* %2
200 ret void
201}
202
203; Min not-supported negative offset
204define void @store_breg_immoff_2(i64 %a) {
205; SDAG-LABEL: store_breg_immoff_2
206; SDAG: sub [[REG:x[0-9]+]], x0, #257
207; SDAG-NEXT: str wzr, {{\[}}[[REG]]{{\]}}
208; FAST-LABEL: store_breg_immoff_2
209; FAST: add [[REG:x[0-9]+]], x0, {{x[0-9]+}}
210; FAST-NEXT: str wzr, {{\[}}[[REG]]{{\]}}
211 %1 = add i64 %a, -257
212 %2 = inttoptr i64 %1 to i32*
213 store i32 0, i32* %2
214 ret void
215}
216
217; Max supported unscaled offset
218define void @store_breg_immoff_3(i64 %a) {
219; CHECK-LABEL: store_breg_immoff_3
220; CHECK: stur wzr, [x0, #255]
221 %1 = add i64 %a, 255
222 %2 = inttoptr i64 %1 to i32*
223 store i32 0, i32* %2
224 ret void
225}
226
227; Min un-supported unscaled offset
228define void @store_breg_immoff_4(i64 %a) {
229; SDAG-LABEL: store_breg_immoff_4
230; SDAG: add [[REG:x[0-9]+]], x0, #257
231; SDAG-NEXT: str wzr, {{\[}}[[REG]]{{\]}}
232; FAST-LABEL: store_breg_immoff_4
233; FAST: add [[REG:x[0-9]+]], x0, {{x[0-9]+}}
234; FAST-NEXT: str wzr, {{\[}}[[REG]]{{\]}}
235 %1 = add i64 %a, 257
236 %2 = inttoptr i64 %1 to i32*
237 store i32 0, i32* %2
238 ret void
239}
240
241; Max supported scaled offset
242define void @store_breg_immoff_5(i64 %a) {
243; CHECK-LABEL: store_breg_immoff_5
244; CHECK: str wzr, [x0, #16380]
245 %1 = add i64 %a, 16380
246 %2 = inttoptr i64 %1 to i32*
247 store i32 0, i32* %2
248 ret void
249}
250
251; Min un-supported scaled offset
252define void @store_breg_immoff_6(i64 %a) {
253; SDAG-LABEL: store_breg_immoff_6
254; SDAG: add [[REG:x[0-9]+]], x0, #4, lsl #12
255; SDAG-NEXT: str wzr, {{\[}}[[REG]]{{\]}}
256; FAST-LABEL: store_breg_immoff_6
257; FAST: add [[REG:x[0-9]+]], x0, {{x[0-9]+}}
258; FAST-NEXT: str wzr, {{\[}}[[REG]]{{\]}}
259 %1 = add i64 %a, 16384
260 %2 = inttoptr i64 %1 to i32*
261 store i32 0, i32* %2
262 ret void
263}
264
265define i64 @load_breg_immoff_7(i64 %a) {
266; CHECK-LABEL: load_breg_immoff_7
267; CHECK: ldr {{x[0-9]+}}, [x0, #48]
268 %1 = add i64 %a, 48
269 %2 = inttoptr i64 %1 to i64*
270 %3 = load i64* %2
271 ret i64 %3
272}
273
274; Flip add operands
275define i64 @load_breg_immoff_8(i64 %a) {
276; CHECK-LABEL: load_breg_immoff_8
277; CHECK: ldr {{x[0-9]+}}, [x0, #48]
278 %1 = add i64 48, %a
279 %2 = inttoptr i64 %1 to i64*
280 %3 = load i64* %2
281 ret i64 %3
282}
283
284; Load Base Register + Register Offset
285define i64 @load_breg_offreg_1(i64 %a, i64 %b) {
286; CHECK-LABEL: load_breg_offreg_1
287; CHECK: ldr {{x[0-9]+}}, [x0, x1]
288 %1 = add i64 %a, %b
289 %2 = inttoptr i64 %1 to i64*
290 %3 = load i64* %2
291 ret i64 %3
292}
293
294; Flip add operands
295define i64 @load_breg_offreg_2(i64 %a, i64 %b) {
296; CHECK-LABEL: load_breg_offreg_2
297; CHECK: ldr {{x[0-9]+}}, [x1, x0]
298 %1 = add i64 %b, %a
299 %2 = inttoptr i64 %1 to i64*
300 %3 = load i64* %2
301 ret i64 %3
302}
303
304; Load Base Register + Register Offset + Immediate Offset
305define i64 @load_breg_offreg_immoff_1(i64 %a, i64 %b) {
306; CHECK-LABEL: load_breg_offreg_immoff_1
307; CHECK: add [[REG:x[0-9]+]], x0, x1
308; CHECK-NEXT: ldr x0, {{\[}}[[REG]], #48{{\]}}
309 %1 = add i64 %a, %b
310 %2 = add i64 %1, 48
311 %3 = inttoptr i64 %2 to i64*
312 %4 = load i64* %3
313 ret i64 %4
314}
315
316define i64 @load_breg_offreg_immoff_2(i64 %a, i64 %b) {
317; SDAG-LABEL: load_breg_offreg_immoff_2
318; SDAG: add [[REG1:x[0-9]+]], x0, x1
319; SDAG-NEXT: add [[REG2:x[0-9]+]], [[REG1]], #15, lsl #12
320; SDAG-NEXT: ldr x0, {{\[}}[[REG2]]{{\]}}
321; FAST-LABEL: load_breg_offreg_immoff_2
322; FAST: add [[REG:x[0-9]+]], x0, {{x[0-9]+}}
323; FAST-NEXT: ldr x0, {{\[}}[[REG]], x1{{\]}}
324 %1 = add i64 %a, %b
325 %2 = add i64 %1, 61440
326 %3 = inttoptr i64 %2 to i64*
327 %4 = load i64* %3
328 ret i64 %4
329}
330
Juergen Ributzka3c1b2862014-08-27 21:38:33 +0000331; Load Scaled Register Offset
332define i32 @load_shift_offreg_1(i64 %a) {
333; CHECK-LABEL: load_shift_offreg_1
334; CHECK: lsl [[REG:x[0-9]+]], x0, #2
335; CHECK: ldr {{w[0-9]+}}, {{\[}}[[REG]]{{\]}}
336 %1 = shl i64 %a, 2
337 %2 = inttoptr i64 %1 to i32*
338 %3 = load i32* %2
339 ret i32 %3
340}
341
Juergen Ributzkab46ea082014-08-19 19:44:17 +0000342; Load Base Register + Scaled Register Offset
343define i32 @load_breg_shift_offreg_1(i64 %a, i64 %b) {
344; CHECK-LABEL: load_breg_shift_offreg_1
345; CHECK: ldr {{w[0-9]+}}, [x1, x0, lsl #2]
346 %1 = shl i64 %a, 2
347 %2 = add i64 %1, %b
348 %3 = inttoptr i64 %2 to i32*
349 %4 = load i32* %3
350 ret i32 %4
351}
352
353define i32 @load_breg_shift_offreg_2(i64 %a, i64 %b) {
354; CHECK-LABEL: load_breg_shift_offreg_2
355; CHECK: ldr {{w[0-9]+}}, [x1, x0, lsl #2]
356 %1 = shl i64 %a, 2
357 %2 = add i64 %b, %1
358 %3 = inttoptr i64 %2 to i32*
359 %4 = load i32* %3
360 ret i32 %4
361}
362
363define i32 @load_breg_shift_offreg_3(i64 %a, i64 %b) {
364; SDAG-LABEL: load_breg_shift_offreg_3
365; SDAG: lsl [[REG:x[0-9]+]], x0, #2
366; SDAG-NEXT: ldr {{w[0-9]+}}, {{\[}}[[REG]], x1, lsl #2{{\]}}
367; FAST-LABEL: load_breg_shift_offreg_3
368; FAST: lsl [[REG:x[0-9]+]], x1, {{x[0-9]+}}
369; FAST-NEXT: ldr {{w[0-9]+}}, {{\[}}[[REG]], x0, lsl #2{{\]}}
370 %1 = shl i64 %a, 2
371 %2 = shl i64 %b, 2
372 %3 = add i64 %1, %2
373 %4 = inttoptr i64 %3 to i32*
374 %5 = load i32* %4
375 ret i32 %5
376}
377
378define i32 @load_breg_shift_offreg_4(i64 %a, i64 %b) {
379; SDAG-LABEL: load_breg_shift_offreg_4
380; SDAG: lsl [[REG:x[0-9]+]], x1, #2
381; SDAG-NEXT: ldr {{w[0-9]+}}, {{\[}}[[REG]], x0, lsl #2{{\]}}
382; FAST-LABEL: load_breg_shift_offreg_4
383; FAST: lsl [[REG:x[0-9]+]], x0, {{x[0-9]+}}
384; FAST-NEXT: ldr {{w[0-9]+}}, {{\[}}[[REG]], x1, lsl #2{{\]}}
385 %1 = shl i64 %a, 2
386 %2 = shl i64 %b, 2
387 %3 = add i64 %2, %1
388 %4 = inttoptr i64 %3 to i32*
389 %5 = load i32* %4
390 ret i32 %5
391}
392
393define i32 @load_breg_shift_offreg_5(i64 %a, i64 %b) {
394; SDAG-LABEL: load_breg_shift_offreg_5
395; SDAG: lsl [[REG:x[0-9]+]], x1, #3
396; SDAG-NEXT: ldr {{w[0-9]+}}, {{\[}}[[REG]], x0, lsl #2{{\]}}
397; FAST-LABEL: load_breg_shift_offreg_5
398; FAST: lsl [[REG:x[0-9]+]], x1, {{x[0-9]+}}
399; FAST-NEXT: ldr {{w[0-9]+}}, {{\[}}[[REG]], x0, lsl #2{{\]}}
400 %1 = shl i64 %a, 2
401 %2 = shl i64 %b, 3
402 %3 = add i64 %1, %2
403 %4 = inttoptr i64 %3 to i32*
404 %5 = load i32* %4
405 ret i32 %5
406}
407
408
409; Load Base Register + Scaled Register Offset + Sign/Zero extension
410define i32 @load_breg_zext_shift_offreg_1(i32 %a, i64 %b) {
411; CHECK-LABEL: load_breg_zext_shift_offreg_1
412; CHECK: ldr {{w[0-9]+}}, [x1, w0, uxtw #2]
413 %1 = zext i32 %a to i64
414 %2 = shl i64 %1, 2
415 %3 = add i64 %2, %b
416 %4 = inttoptr i64 %3 to i32*
417 %5 = load i32* %4
418 ret i32 %5
419}
420
421define i32 @load_breg_zext_shift_offreg_2(i32 %a, i64 %b) {
422; CHECK-LABEL: load_breg_zext_shift_offreg_2
423; CHECK: ldr {{w[0-9]+}}, [x1, w0, uxtw #2]
424 %1 = zext i32 %a to i64
425 %2 = shl i64 %1, 2
426 %3 = add i64 %b, %2
427 %4 = inttoptr i64 %3 to i32*
428 %5 = load i32* %4
429 ret i32 %5
430}
431
432define i32 @load_breg_sext_shift_offreg_1(i32 %a, i64 %b) {
433; CHECK-LABEL: load_breg_sext_shift_offreg_1
434; CHECK: ldr {{w[0-9]+}}, [x1, w0, sxtw #2]
435 %1 = sext i32 %a to i64
436 %2 = shl i64 %1, 2
437 %3 = add i64 %2, %b
438 %4 = inttoptr i64 %3 to i32*
439 %5 = load i32* %4
440 ret i32 %5
441}
442
443define i32 @load_breg_sext_shift_offreg_2(i32 %a, i64 %b) {
444; CHECK-LABEL: load_breg_sext_shift_offreg_2
445; CHECK: ldr {{w[0-9]+}}, [x1, w0, sxtw #2]
446 %1 = sext i32 %a to i64
447 %2 = shl i64 %1, 2
448 %3 = add i64 %b, %2
449 %4 = inttoptr i64 %3 to i32*
450 %5 = load i32* %4
451 ret i32 %5
452}
453
Juergen Ributzkafb506a42014-08-27 00:58:30 +0000454; Load Scaled Register Offset + Immediate Offset + Sign/Zero extension
455define i64 @load_sext_shift_offreg_imm1(i32 %a) {
456; CHECK-LABEL: load_sext_shift_offreg_imm1
Juergen Ributzka100a9b72014-08-27 21:04:52 +0000457; CHECK: sbfiz [[REG:x[0-9]+]], {{x[0-9]+}}, #3, #32
Juergen Ributzkafb506a42014-08-27 00:58:30 +0000458; CHECK-NEXT: ldr {{x[0-9]+}}, {{\[}}[[REG]], #8{{\]}}
459 %1 = sext i32 %a to i64
460 %2 = shl i64 %1, 3
461 %3 = add i64 %2, 8
462 %4 = inttoptr i64 %3 to i64*
463 %5 = load i64* %4
464 ret i64 %5
465}
466
467; Load Base Register + Scaled Register Offset + Immediate Offset + Sign/Zero extension
468define i64 @load_breg_sext_shift_offreg_imm1(i32 %a, i64 %b) {
469; CHECK-LABEL: load_breg_sext_shift_offreg_imm1
470; CHECK: add [[REG:x[0-9]+]], x1, w0, sxtw #3
471; CHECK-NEXT: ldr {{x[0-9]+}}, {{\[}}[[REG]], #8{{\]}}
472 %1 = sext i32 %a to i64
473 %2 = shl i64 %1, 3
474 %3 = add i64 %b, %2
475 %4 = add i64 %3, 8
476 %5 = inttoptr i64 %4 to i64*
477 %6 = load i64* %5
478 ret i64 %6
479}
480
Juergen Ributzka4f1a54a2014-08-28 00:09:46 +0000481; Test that the kill flag is not set - the machine instruction verifier does that for us.
482define i64 @kill_reg(i64 %a) {
483 %1 = sub i64 %a, 8
484 %2 = add i64 %1, 96
485 %3 = inttoptr i64 %2 to i64*
486 %4 = load i64* %3
487 %5 = add i64 %2, %4
488 ret i64 %5
489}
490