xref: /llvm-project/llvm/test/CodeGen/AArch64/store.ll (revision 61510b51c33464a6bc15e4cf5b1ee07e2e0ec1c9)
1; NOTE: Assertions have been autogenerated by utils/update_llc_test_checks.py UTC_ARGS: --version 4
2; RUN: llc -mtriple=aarch64 %s -o - | FileCheck %s --check-prefixes=CHECK,CHECK-SD
3; RUN: llc -mtriple=aarch64 -global-isel %s -o - | FileCheck %s --check-prefixes=CHECK,CHECK-GI
4
5; ===== Legal Scalars =====
6define void @store_i8(i8 %a, ptr %ptr){
7; CHECK-LABEL: store_i8:
8; CHECK:       // %bb.0:
9; CHECK-NEXT:    strb w0, [x1]
10; CHECK-NEXT:    ret
11    store i8 %a, ptr %ptr
12    ret void
13}
14
15define void @store_i16(i16 %a, ptr %ptr){
16; CHECK-LABEL: store_i16:
17; CHECK:       // %bb.0:
18; CHECK-NEXT:    strh w0, [x1]
19; CHECK-NEXT:    ret
20    store i16 %a, ptr %ptr
21    ret void
22}
23
24define void @store_i32(i32 %a, ptr %ptr){
25; CHECK-LABEL: store_i32:
26; CHECK:       // %bb.0:
27; CHECK-NEXT:    str w0, [x1]
28; CHECK-NEXT:    ret
29    store i32 %a, ptr %ptr
30    ret void
31}
32
33define void @store_i64(i64 %a, ptr %ptr){
34; CHECK-LABEL: store_i64:
35; CHECK:       // %bb.0:
36; CHECK-NEXT:    str x0, [x1]
37; CHECK-NEXT:    ret
38    store i64 %a, ptr %ptr
39    ret void
40}
41
42; ===== Legal Vector Types =====
43
44define void @store_v8i8(<8 x i8> %a, ptr %ptr){
45; CHECK-LABEL: store_v8i8:
46; CHECK:       // %bb.0:
47; CHECK-NEXT:    str d0, [x0]
48; CHECK-NEXT:    ret
49    store <8 x i8> %a, ptr %ptr
50    ret void
51}
52
53define void @store_v16i8(<16 x i8> %a, ptr %ptr){
54; CHECK-LABEL: store_v16i8:
55; CHECK:       // %bb.0:
56; CHECK-NEXT:    str q0, [x0]
57; CHECK-NEXT:    ret
58    store <16 x i8> %a, ptr %ptr
59    ret void
60}
61
62define void @store_v4i16(<4 x i16> %a, ptr %ptr){
63; CHECK-LABEL: store_v4i16:
64; CHECK:       // %bb.0:
65; CHECK-NEXT:    str d0, [x0]
66; CHECK-NEXT:    ret
67    store <4 x i16> %a, ptr %ptr
68    ret void
69}
70
71define void @store_v8i16(<8 x i16> %a, ptr %ptr){
72; CHECK-LABEL: store_v8i16:
73; CHECK:       // %bb.0:
74; CHECK-NEXT:    str q0, [x0]
75; CHECK-NEXT:    ret
76    store <8 x i16> %a, ptr %ptr
77    ret void
78}
79
80define void @store_v2i32(<2 x i32> %a, ptr %ptr){
81; CHECK-LABEL: store_v2i32:
82; CHECK:       // %bb.0:
83; CHECK-NEXT:    str d0, [x0]
84; CHECK-NEXT:    ret
85    store <2 x i32> %a, ptr %ptr
86    ret void
87}
88
89define void @store_v4i32(<4 x i32> %a, ptr %ptr){
90; CHECK-LABEL: store_v4i32:
91; CHECK:       // %bb.0:
92; CHECK-NEXT:    str q0, [x0]
93; CHECK-NEXT:    ret
94    store <4 x i32> %a, ptr %ptr
95    ret void
96}
97
98define void @store_v2i64(<2 x i64> %a, ptr %ptr){
99; CHECK-LABEL: store_v2i64:
100; CHECK:       // %bb.0:
101; CHECK-NEXT:    str q0, [x0]
102; CHECK-NEXT:    ret
103    store <2 x i64> %a, ptr %ptr
104    ret void
105}
106
107; ===== Smaller/Larger Width Vectors with Legal Element Sizes =====
108
109define void @store_v2i8(<2 x i8> %a, ptr %ptr){
110; CHECK-SD-LABEL: store_v2i8:
111; CHECK-SD:       // %bb.0:
112; CHECK-SD-NEXT:    // kill: def $d0 killed $d0 def $q0
113; CHECK-SD-NEXT:    mov w8, v0.s[1]
114; CHECK-SD-NEXT:    fmov w9, s0
115; CHECK-SD-NEXT:    strb w9, [x0]
116; CHECK-SD-NEXT:    strb w8, [x0, #1]
117; CHECK-SD-NEXT:    ret
118;
119; CHECK-GI-LABEL: store_v2i8:
120; CHECK-GI:       // %bb.0:
121; CHECK-GI-NEXT:    // kill: def $d0 killed $d0 def $q0
122; CHECK-GI-NEXT:    mov s1, v0.s[1]
123; CHECK-GI-NEXT:    str b0, [x0]
124; CHECK-GI-NEXT:    str b1, [x0, #1]
125; CHECK-GI-NEXT:    ret
126    store <2 x i8> %a, ptr %ptr
127    ret void
128}
129
130define void @store_v4i8(i32 %a, ptr %ptr) {
131; CHECK-LABEL: store_v4i8:
132; CHECK:       // %bb.0:
133; CHECK-NEXT:    str w0, [x1]
134; CHECK-NEXT:    ret
135    %c = bitcast i32 %a to <4 x i8>
136    store <4 x i8> %c, ptr %ptr
137    ret void
138}
139
140define void @store_v32i8(<32 x i8> %a, ptr %ptr){
141; CHECK-LABEL: store_v32i8:
142; CHECK:       // %bb.0:
143; CHECK-NEXT:    stp q0, q1, [x0]
144; CHECK-NEXT:    ret
145    store <32 x i8> %a, ptr %ptr
146    ret void
147}
148
149define void @store_v2i16(<2 x i16> %a, ptr %ptr){
150; CHECK-SD-LABEL: store_v2i16:
151; CHECK-SD:       // %bb.0:
152; CHECK-SD-NEXT:    // kill: def $d0 killed $d0 def $q0
153; CHECK-SD-NEXT:    mov w8, v0.s[1]
154; CHECK-SD-NEXT:    fmov w9, s0
155; CHECK-SD-NEXT:    strh w9, [x0]
156; CHECK-SD-NEXT:    strh w8, [x0, #2]
157; CHECK-SD-NEXT:    ret
158;
159; CHECK-GI-LABEL: store_v2i16:
160; CHECK-GI:       // %bb.0:
161; CHECK-GI-NEXT:    // kill: def $d0 killed $d0 def $q0
162; CHECK-GI-NEXT:    mov s1, v0.s[1]
163; CHECK-GI-NEXT:    str h0, [x0]
164; CHECK-GI-NEXT:    str h1, [x0, #2]
165; CHECK-GI-NEXT:    ret
166    store <2 x i16> %a, ptr %ptr
167    ret void
168}
169
170define void @store_v16i16(<16 x i16> %a, ptr %ptr){
171; CHECK-LABEL: store_v16i16:
172; CHECK:       // %bb.0:
173; CHECK-NEXT:    stp q0, q1, [x0]
174; CHECK-NEXT:    ret
175    store <16 x i16> %a, ptr %ptr
176    ret void
177}
178
179define void @store_v1i32(<1 x i32> %a, ptr %ptr){
180; CHECK-SD-LABEL: store_v1i32:
181; CHECK-SD:       // %bb.0:
182; CHECK-SD-NEXT:    // kill: def $d0 killed $d0 def $q0
183; CHECK-SD-NEXT:    str s0, [x0]
184; CHECK-SD-NEXT:    ret
185;
186; CHECK-GI-LABEL: store_v1i32:
187; CHECK-GI:       // %bb.0:
188; CHECK-GI-NEXT:    str s0, [x0]
189; CHECK-GI-NEXT:    ret
190    store <1 x i32> %a, ptr %ptr
191    ret void
192}
193
194define void @store_v8i32(<8 x i32> %a, ptr %ptr){
195; CHECK-LABEL: store_v8i32:
196; CHECK:       // %bb.0:
197; CHECK-NEXT:    stp q0, q1, [x0]
198; CHECK-NEXT:    ret
199    store <8 x i32> %a, ptr %ptr
200    ret void
201}
202
203define void @store_v4i64(<4 x i64> %a, ptr %ptr){
204; CHECK-LABEL: store_v4i64:
205; CHECK:       // %bb.0:
206; CHECK-NEXT:    stp q0, q1, [x0]
207; CHECK-NEXT:    ret
208    store <4 x i64> %a, ptr %ptr
209    ret void
210}
211
212; ===== Vectors with Non-Pow 2 Widths =====
213
214define void @store_v3i8(<3 x i8> %a, ptr %ptr){
215; CHECK-SD-LABEL: store_v3i8:
216; CHECK-SD:       // %bb.0:
217; CHECK-SD-NEXT:    sub sp, sp, #16
218; CHECK-SD-NEXT:    .cfi_def_cfa_offset 16
219; CHECK-SD-NEXT:    fmov s0, w0
220; CHECK-SD-NEXT:    mov v0.h[1], w1
221; CHECK-SD-NEXT:    mov v0.h[2], w2
222; CHECK-SD-NEXT:    xtn v0.8b, v0.8h
223; CHECK-SD-NEXT:    str s0, [sp, #12]
224; CHECK-SD-NEXT:    ldrh w8, [sp, #12]
225; CHECK-SD-NEXT:    strb w2, [x3, #2]
226; CHECK-SD-NEXT:    strh w8, [x3]
227; CHECK-SD-NEXT:    add sp, sp, #16
228; CHECK-SD-NEXT:    ret
229;
230; CHECK-GI-LABEL: store_v3i8:
231; CHECK-GI:       // %bb.0:
232; CHECK-GI-NEXT:    strb w0, [x3]
233; CHECK-GI-NEXT:    strb w1, [x3, #1]
234; CHECK-GI-NEXT:    strb w2, [x3, #2]
235; CHECK-GI-NEXT:    ret
236    store <3 x i8> %a, ptr %ptr
237    ret void
238}
239
240define void @store_v7i8(<7 x i8> %a, ptr %ptr){
241; CHECK-SD-LABEL: store_v7i8:
242; CHECK-SD:       // %bb.0:
243; CHECK-SD-NEXT:    add x8, x0, #6
244; CHECK-SD-NEXT:    add x9, x0, #4
245; CHECK-SD-NEXT:    // kill: def $d0 killed $d0 def $q0
246; CHECK-SD-NEXT:    str s0, [x0]
247; CHECK-SD-NEXT:    st1 { v0.b }[6], [x8]
248; CHECK-SD-NEXT:    st1 { v0.h }[2], [x9]
249; CHECK-SD-NEXT:    ret
250;
251; CHECK-GI-LABEL: store_v7i8:
252; CHECK-GI:       // %bb.0:
253; CHECK-GI-NEXT:    add x8, x0, #1
254; CHECK-GI-NEXT:    // kill: def $d0 killed $d0 def $q0
255; CHECK-GI-NEXT:    add x9, x0, #2
256; CHECK-GI-NEXT:    st1 { v0.b }[0], [x0]
257; CHECK-GI-NEXT:    st1 { v0.b }[1], [x8]
258; CHECK-GI-NEXT:    add x8, x0, #3
259; CHECK-GI-NEXT:    st1 { v0.b }[3], [x8]
260; CHECK-GI-NEXT:    add x8, x0, #4
261; CHECK-GI-NEXT:    st1 { v0.b }[4], [x8]
262; CHECK-GI-NEXT:    add x8, x0, #5
263; CHECK-GI-NEXT:    st1 { v0.b }[5], [x8]
264; CHECK-GI-NEXT:    add x8, x0, #6
265; CHECK-GI-NEXT:    st1 { v0.b }[2], [x9]
266; CHECK-GI-NEXT:    st1 { v0.b }[6], [x8]
267; CHECK-GI-NEXT:    ret
268    store <7 x i8> %a, ptr %ptr
269    ret void
270}
271
272define void @store_v3i16(<3 x i16> %a, ptr %ptr){
273; CHECK-SD-LABEL: store_v3i16:
274; CHECK-SD:       // %bb.0:
275; CHECK-SD-NEXT:    add x8, x0, #4
276; CHECK-SD-NEXT:    // kill: def $d0 killed $d0 def $q0
277; CHECK-SD-NEXT:    str s0, [x0]
278; CHECK-SD-NEXT:    st1 { v0.h }[2], [x8]
279; CHECK-SD-NEXT:    ret
280;
281; CHECK-GI-LABEL: store_v3i16:
282; CHECK-GI:       // %bb.0:
283; CHECK-GI-NEXT:    add x8, x0, #2
284; CHECK-GI-NEXT:    add x9, x0, #4
285; CHECK-GI-NEXT:    // kill: def $d0 killed $d0 def $q0
286; CHECK-GI-NEXT:    str h0, [x0]
287; CHECK-GI-NEXT:    st1 { v0.h }[1], [x8]
288; CHECK-GI-NEXT:    st1 { v0.h }[2], [x9]
289; CHECK-GI-NEXT:    ret
290    store <3 x i16> %a, ptr %ptr
291    ret void
292}
293
294define void @store_v7i16(<7 x i16> %a, ptr %ptr){
295; CHECK-SD-LABEL: store_v7i16:
296; CHECK-SD:       // %bb.0:
297; CHECK-SD-NEXT:    add x8, x0, #12
298; CHECK-SD-NEXT:    add x9, x0, #8
299; CHECK-SD-NEXT:    str d0, [x0]
300; CHECK-SD-NEXT:    st1 { v0.h }[6], [x8]
301; CHECK-SD-NEXT:    st1 { v0.s }[2], [x9]
302; CHECK-SD-NEXT:    ret
303;
304; CHECK-GI-LABEL: store_v7i16:
305; CHECK-GI:       // %bb.0:
306; CHECK-GI-NEXT:    add x8, x0, #2
307; CHECK-GI-NEXT:    add x9, x0, #4
308; CHECK-GI-NEXT:    str h0, [x0]
309; CHECK-GI-NEXT:    st1 { v0.h }[1], [x8]
310; CHECK-GI-NEXT:    add x8, x0, #6
311; CHECK-GI-NEXT:    st1 { v0.h }[3], [x8]
312; CHECK-GI-NEXT:    add x8, x0, #8
313; CHECK-GI-NEXT:    st1 { v0.h }[4], [x8]
314; CHECK-GI-NEXT:    add x8, x0, #10
315; CHECK-GI-NEXT:    st1 { v0.h }[5], [x8]
316; CHECK-GI-NEXT:    add x8, x0, #12
317; CHECK-GI-NEXT:    st1 { v0.h }[2], [x9]
318; CHECK-GI-NEXT:    st1 { v0.h }[6], [x8]
319; CHECK-GI-NEXT:    ret
320    store <7 x i16> %a, ptr %ptr
321    ret void
322}
323
324define void @store_v3i32(<3 x i32> %a, ptr %ptr){
325; CHECK-SD-LABEL: store_v3i32:
326; CHECK-SD:       // %bb.0:
327; CHECK-SD-NEXT:    add x8, x0, #8
328; CHECK-SD-NEXT:    str d0, [x0]
329; CHECK-SD-NEXT:    st1 { v0.s }[2], [x8]
330; CHECK-SD-NEXT:    ret
331;
332; CHECK-GI-LABEL: store_v3i32:
333; CHECK-GI:       // %bb.0:
334; CHECK-GI-NEXT:    add x8, x0, #4
335; CHECK-GI-NEXT:    add x9, x0, #8
336; CHECK-GI-NEXT:    str s0, [x0]
337; CHECK-GI-NEXT:    st1 { v0.s }[1], [x8]
338; CHECK-GI-NEXT:    st1 { v0.s }[2], [x9]
339; CHECK-GI-NEXT:    ret
340    store <3 x i32> %a, ptr %ptr
341    ret void
342}
343
344define void @store_v2i128(<2 x i128> %a, ptr %p) {
345; CHECK-SD-LABEL: store_v2i128:
346; CHECK-SD:       // %bb.0:
347; CHECK-SD-NEXT:    stp x2, x3, [x4, #16]
348; CHECK-SD-NEXT:    stp x0, x1, [x4]
349; CHECK-SD-NEXT:    ret
350;
351; CHECK-GI-LABEL: store_v2i128:
352; CHECK-GI:       // %bb.0:
353; CHECK-GI-NEXT:    mov v0.d[0], x0
354; CHECK-GI-NEXT:    mov v1.d[0], x2
355; CHECK-GI-NEXT:    mov v0.d[1], x1
356; CHECK-GI-NEXT:    mov v1.d[1], x3
357; CHECK-GI-NEXT:    stp q0, q1, [x4]
358; CHECK-GI-NEXT:    ret
359    store <2 x i128> %a, ptr %p
360    ret void
361}
362
363define void @store_v2f128(<2 x fp128> %a, ptr %p) {
364; CHECK-LABEL: store_v2f128:
365; CHECK:       // %bb.0:
366; CHECK-NEXT:    stp q0, q1, [x0]
367; CHECK-NEXT:    ret
368    store <2 x fp128> %a, ptr %p
369    ret void
370}
371