blob: 86ba400cff27ddfbc900ccb48b0f319fdb9f4323 [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
110; Load / Store Base Register + Immediate Offset
111; Max supported negative offset
112define i32 @load_breg_immoff_1(i64 %a) {
113; CHECK-LABEL: load_breg_immoff_1
114; CHECK: ldur {{w[0-9]+}}, [x0, #-256]
115 %1 = add i64 %a, -256
116 %2 = inttoptr i64 %1 to i32*
117 %3 = load i32* %2
118 ret i32 %3
119}
120
121; Min not-supported negative offset
122define i32 @load_breg_immoff_2(i64 %a) {
123; SDAG-LABEL: load_breg_immoff_2
124; SDAG: sub [[REG:x[0-9]+]], x0, #257
125; SDAG-NEXT: ldr {{w[0-9]+}}, {{\[}}[[REG]]{{\]}}
126; FAST-LABEL: load_breg_immoff_2
127; FAST: add [[REG:x[0-9]+]], x0, {{x[0-9]+}}
128; FAST-NEXT: ldr {{w[0-9]+}}, {{\[}}[[REG]]{{\]}}
129 %1 = add i64 %a, -257
130 %2 = inttoptr i64 %1 to i32*
131 %3 = load i32* %2
132 ret i32 %3
133}
134
135; Max supported unscaled offset
136define i32 @load_breg_immoff_3(i64 %a) {
137; CHECK-LABEL: load_breg_immoff_3
138; CHECK: ldur {{w[0-9]+}}, [x0, #255]
139 %1 = add i64 %a, 255
140 %2 = inttoptr i64 %1 to i32*
141 %3 = load i32* %2
142 ret i32 %3
143}
144
145; Min un-supported unscaled offset
146define i32 @load_breg_immoff_4(i64 %a) {
147; SDAG-LABEL: load_breg_immoff_4
148; SDAG: add [[REG:x[0-9]+]], x0, #257
149; SDAG-NEXT: ldr {{w[0-9]+}}, {{\[}}[[REG]]{{\]}}
150; FAST-LABEL: load_breg_immoff_4
151; FAST: add [[REG:x[0-9]+]], x0, {{x[0-9]+}}
152; FAST-NEXT: ldr {{w[0-9]+}}, {{\[}}[[REG]]{{\]}}
153 %1 = add i64 %a, 257
154 %2 = inttoptr i64 %1 to i32*
155 %3 = load i32* %2
156 ret i32 %3
157}
158
159; Max supported scaled offset
160define i32 @load_breg_immoff_5(i64 %a) {
161; CHECK-LABEL: load_breg_immoff_5
162; CHECK: ldr {{w[0-9]+}}, [x0, #16380]
163 %1 = add i64 %a, 16380
164 %2 = inttoptr i64 %1 to i32*
165 %3 = load i32* %2
166 ret i32 %3
167}
168
169; Min un-supported scaled offset
170define i32 @load_breg_immoff_6(i64 %a) {
171; SDAG-LABEL: load_breg_immoff_6
172; SDAG: add [[REG:x[0-9]+]], x0, #4, lsl #12
173; SDAG-NEXT: ldr {{w[0-9]+}}, {{\[}}[[REG]]{{\]}}
174; FAST-LABEL: load_breg_immoff_6
175; FAST: add [[REG:x[0-9]+]], x0, {{x[0-9]+}}
176; FAST-NEXT: ldr {{w[0-9]+}}, {{\[}}[[REG]]{{\]}}
177 %1 = add i64 %a, 16384
178 %2 = inttoptr i64 %1 to i32*
179 %3 = load i32* %2
180 ret i32 %3
181}
182
183; Max supported negative offset
184define void @store_breg_immoff_1(i64 %a) {
185; CHECK-LABEL: store_breg_immoff_1
186; CHECK: stur wzr, [x0, #-256]
187 %1 = add i64 %a, -256
188 %2 = inttoptr i64 %1 to i32*
189 store i32 0, i32* %2
190 ret void
191}
192
193; Min not-supported negative offset
194define void @store_breg_immoff_2(i64 %a) {
195; SDAG-LABEL: store_breg_immoff_2
196; SDAG: sub [[REG:x[0-9]+]], x0, #257
197; SDAG-NEXT: str wzr, {{\[}}[[REG]]{{\]}}
198; FAST-LABEL: store_breg_immoff_2
199; FAST: add [[REG:x[0-9]+]], x0, {{x[0-9]+}}
200; FAST-NEXT: str wzr, {{\[}}[[REG]]{{\]}}
201 %1 = add i64 %a, -257
202 %2 = inttoptr i64 %1 to i32*
203 store i32 0, i32* %2
204 ret void
205}
206
207; Max supported unscaled offset
208define void @store_breg_immoff_3(i64 %a) {
209; CHECK-LABEL: store_breg_immoff_3
210; CHECK: stur wzr, [x0, #255]
211 %1 = add i64 %a, 255
212 %2 = inttoptr i64 %1 to i32*
213 store i32 0, i32* %2
214 ret void
215}
216
217; Min un-supported unscaled offset
218define void @store_breg_immoff_4(i64 %a) {
219; SDAG-LABEL: store_breg_immoff_4
220; SDAG: add [[REG:x[0-9]+]], x0, #257
221; SDAG-NEXT: str wzr, {{\[}}[[REG]]{{\]}}
222; FAST-LABEL: store_breg_immoff_4
223; FAST: add [[REG:x[0-9]+]], x0, {{x[0-9]+}}
224; FAST-NEXT: str wzr, {{\[}}[[REG]]{{\]}}
225 %1 = add i64 %a, 257
226 %2 = inttoptr i64 %1 to i32*
227 store i32 0, i32* %2
228 ret void
229}
230
231; Max supported scaled offset
232define void @store_breg_immoff_5(i64 %a) {
233; CHECK-LABEL: store_breg_immoff_5
234; CHECK: str wzr, [x0, #16380]
235 %1 = add i64 %a, 16380
236 %2 = inttoptr i64 %1 to i32*
237 store i32 0, i32* %2
238 ret void
239}
240
241; Min un-supported scaled offset
242define void @store_breg_immoff_6(i64 %a) {
243; SDAG-LABEL: store_breg_immoff_6
244; SDAG: add [[REG:x[0-9]+]], x0, #4, lsl #12
245; SDAG-NEXT: str wzr, {{\[}}[[REG]]{{\]}}
246; FAST-LABEL: store_breg_immoff_6
247; FAST: add [[REG:x[0-9]+]], x0, {{x[0-9]+}}
248; FAST-NEXT: str wzr, {{\[}}[[REG]]{{\]}}
249 %1 = add i64 %a, 16384
250 %2 = inttoptr i64 %1 to i32*
251 store i32 0, i32* %2
252 ret void
253}
254
255define i64 @load_breg_immoff_7(i64 %a) {
256; CHECK-LABEL: load_breg_immoff_7
257; CHECK: ldr {{x[0-9]+}}, [x0, #48]
258 %1 = add i64 %a, 48
259 %2 = inttoptr i64 %1 to i64*
260 %3 = load i64* %2
261 ret i64 %3
262}
263
264; Flip add operands
265define i64 @load_breg_immoff_8(i64 %a) {
266; CHECK-LABEL: load_breg_immoff_8
267; CHECK: ldr {{x[0-9]+}}, [x0, #48]
268 %1 = add i64 48, %a
269 %2 = inttoptr i64 %1 to i64*
270 %3 = load i64* %2
271 ret i64 %3
272}
273
274; Load Base Register + Register Offset
275define i64 @load_breg_offreg_1(i64 %a, i64 %b) {
276; CHECK-LABEL: load_breg_offreg_1
277; CHECK: ldr {{x[0-9]+}}, [x0, x1]
278 %1 = add i64 %a, %b
279 %2 = inttoptr i64 %1 to i64*
280 %3 = load i64* %2
281 ret i64 %3
282}
283
284; Flip add operands
285define i64 @load_breg_offreg_2(i64 %a, i64 %b) {
286; CHECK-LABEL: load_breg_offreg_2
287; CHECK: ldr {{x[0-9]+}}, [x1, x0]
288 %1 = add i64 %b, %a
289 %2 = inttoptr i64 %1 to i64*
290 %3 = load i64* %2
291 ret i64 %3
292}
293
294; Load Base Register + Register Offset + Immediate Offset
295define i64 @load_breg_offreg_immoff_1(i64 %a, i64 %b) {
296; CHECK-LABEL: load_breg_offreg_immoff_1
297; CHECK: add [[REG:x[0-9]+]], x0, x1
298; CHECK-NEXT: ldr x0, {{\[}}[[REG]], #48{{\]}}
299 %1 = add i64 %a, %b
300 %2 = add i64 %1, 48
301 %3 = inttoptr i64 %2 to i64*
302 %4 = load i64* %3
303 ret i64 %4
304}
305
306define i64 @load_breg_offreg_immoff_2(i64 %a, i64 %b) {
307; SDAG-LABEL: load_breg_offreg_immoff_2
308; SDAG: add [[REG1:x[0-9]+]], x0, x1
309; SDAG-NEXT: add [[REG2:x[0-9]+]], [[REG1]], #15, lsl #12
310; SDAG-NEXT: ldr x0, {{\[}}[[REG2]]{{\]}}
311; FAST-LABEL: load_breg_offreg_immoff_2
312; FAST: add [[REG:x[0-9]+]], x0, {{x[0-9]+}}
313; FAST-NEXT: ldr x0, {{\[}}[[REG]], x1{{\]}}
314 %1 = add i64 %a, %b
315 %2 = add i64 %1, 61440
316 %3 = inttoptr i64 %2 to i64*
317 %4 = load i64* %3
318 ret i64 %4
319}
320
321; Load Base Register + Scaled Register Offset
322define i32 @load_breg_shift_offreg_1(i64 %a, i64 %b) {
323; CHECK-LABEL: load_breg_shift_offreg_1
324; CHECK: ldr {{w[0-9]+}}, [x1, x0, lsl #2]
325 %1 = shl i64 %a, 2
326 %2 = add i64 %1, %b
327 %3 = inttoptr i64 %2 to i32*
328 %4 = load i32* %3
329 ret i32 %4
330}
331
332define i32 @load_breg_shift_offreg_2(i64 %a, i64 %b) {
333; CHECK-LABEL: load_breg_shift_offreg_2
334; CHECK: ldr {{w[0-9]+}}, [x1, x0, lsl #2]
335 %1 = shl i64 %a, 2
336 %2 = add i64 %b, %1
337 %3 = inttoptr i64 %2 to i32*
338 %4 = load i32* %3
339 ret i32 %4
340}
341
342define i32 @load_breg_shift_offreg_3(i64 %a, i64 %b) {
343; SDAG-LABEL: load_breg_shift_offreg_3
344; SDAG: lsl [[REG:x[0-9]+]], x0, #2
345; SDAG-NEXT: ldr {{w[0-9]+}}, {{\[}}[[REG]], x1, lsl #2{{\]}}
346; FAST-LABEL: load_breg_shift_offreg_3
347; FAST: lsl [[REG:x[0-9]+]], x1, {{x[0-9]+}}
348; FAST-NEXT: ldr {{w[0-9]+}}, {{\[}}[[REG]], x0, lsl #2{{\]}}
349 %1 = shl i64 %a, 2
350 %2 = shl i64 %b, 2
351 %3 = add i64 %1, %2
352 %4 = inttoptr i64 %3 to i32*
353 %5 = load i32* %4
354 ret i32 %5
355}
356
357define i32 @load_breg_shift_offreg_4(i64 %a, i64 %b) {
358; SDAG-LABEL: load_breg_shift_offreg_4
359; SDAG: lsl [[REG:x[0-9]+]], x1, #2
360; SDAG-NEXT: ldr {{w[0-9]+}}, {{\[}}[[REG]], x0, lsl #2{{\]}}
361; FAST-LABEL: load_breg_shift_offreg_4
362; FAST: lsl [[REG:x[0-9]+]], x0, {{x[0-9]+}}
363; FAST-NEXT: ldr {{w[0-9]+}}, {{\[}}[[REG]], x1, lsl #2{{\]}}
364 %1 = shl i64 %a, 2
365 %2 = shl i64 %b, 2
366 %3 = add i64 %2, %1
367 %4 = inttoptr i64 %3 to i32*
368 %5 = load i32* %4
369 ret i32 %5
370}
371
372define i32 @load_breg_shift_offreg_5(i64 %a, i64 %b) {
373; SDAG-LABEL: load_breg_shift_offreg_5
374; SDAG: lsl [[REG:x[0-9]+]], x1, #3
375; SDAG-NEXT: ldr {{w[0-9]+}}, {{\[}}[[REG]], x0, lsl #2{{\]}}
376; FAST-LABEL: load_breg_shift_offreg_5
377; FAST: lsl [[REG:x[0-9]+]], x1, {{x[0-9]+}}
378; FAST-NEXT: ldr {{w[0-9]+}}, {{\[}}[[REG]], x0, lsl #2{{\]}}
379 %1 = shl i64 %a, 2
380 %2 = shl i64 %b, 3
381 %3 = add i64 %1, %2
382 %4 = inttoptr i64 %3 to i32*
383 %5 = load i32* %4
384 ret i32 %5
385}
386
387
388; Load Base Register + Scaled Register Offset + Sign/Zero extension
389define i32 @load_breg_zext_shift_offreg_1(i32 %a, i64 %b) {
390; CHECK-LABEL: load_breg_zext_shift_offreg_1
391; CHECK: ldr {{w[0-9]+}}, [x1, w0, uxtw #2]
392 %1 = zext i32 %a to i64
393 %2 = shl i64 %1, 2
394 %3 = add i64 %2, %b
395 %4 = inttoptr i64 %3 to i32*
396 %5 = load i32* %4
397 ret i32 %5
398}
399
400define i32 @load_breg_zext_shift_offreg_2(i32 %a, i64 %b) {
401; CHECK-LABEL: load_breg_zext_shift_offreg_2
402; CHECK: ldr {{w[0-9]+}}, [x1, w0, uxtw #2]
403 %1 = zext i32 %a to i64
404 %2 = shl i64 %1, 2
405 %3 = add i64 %b, %2
406 %4 = inttoptr i64 %3 to i32*
407 %5 = load i32* %4
408 ret i32 %5
409}
410
411define i32 @load_breg_sext_shift_offreg_1(i32 %a, i64 %b) {
412; CHECK-LABEL: load_breg_sext_shift_offreg_1
413; CHECK: ldr {{w[0-9]+}}, [x1, w0, sxtw #2]
414 %1 = sext i32 %a to i64
415 %2 = shl i64 %1, 2
416 %3 = add i64 %2, %b
417 %4 = inttoptr i64 %3 to i32*
418 %5 = load i32* %4
419 ret i32 %5
420}
421
422define i32 @load_breg_sext_shift_offreg_2(i32 %a, i64 %b) {
423; CHECK-LABEL: load_breg_sext_shift_offreg_2
424; CHECK: ldr {{w[0-9]+}}, [x1, w0, sxtw #2]
425 %1 = sext i32 %a to i64
426 %2 = shl i64 %1, 2
427 %3 = add i64 %b, %2
428 %4 = inttoptr i64 %3 to i32*
429 %5 = load i32* %4
430 ret i32 %5
431}
432
Juergen Ributzkafb506a42014-08-27 00:58:30 +0000433; Load Scaled Register Offset + Immediate Offset + Sign/Zero extension
434define i64 @load_sext_shift_offreg_imm1(i32 %a) {
435; CHECK-LABEL: load_sext_shift_offreg_imm1
Juergen Ributzka100a9b72014-08-27 21:04:52 +0000436; CHECK: sbfiz [[REG:x[0-9]+]], {{x[0-9]+}}, #3, #32
Juergen Ributzkafb506a42014-08-27 00:58:30 +0000437; CHECK-NEXT: ldr {{x[0-9]+}}, {{\[}}[[REG]], #8{{\]}}
438 %1 = sext i32 %a to i64
439 %2 = shl i64 %1, 3
440 %3 = add i64 %2, 8
441 %4 = inttoptr i64 %3 to i64*
442 %5 = load i64* %4
443 ret i64 %5
444}
445
446; Load Base Register + Scaled Register Offset + Immediate Offset + Sign/Zero extension
447define i64 @load_breg_sext_shift_offreg_imm1(i32 %a, i64 %b) {
448; CHECK-LABEL: load_breg_sext_shift_offreg_imm1
449; CHECK: add [[REG:x[0-9]+]], x1, w0, sxtw #3
450; CHECK-NEXT: ldr {{x[0-9]+}}, {{\[}}[[REG]], #8{{\]}}
451 %1 = sext i32 %a to i64
452 %2 = shl i64 %1, 3
453 %3 = add i64 %b, %2
454 %4 = add i64 %3, 8
455 %5 = inttoptr i64 %4 to i64*
456 %6 = load i64* %5
457 ret i64 %6
458}
459