[ORC] Add std::tuple support to SimplePackedSerialization.
[llvm-project.git] / llvm / test / CodeGen / AArch64 / sve-intrinsics-stN-reg-imm-addr-mode.ll
bloba5e278c651093eef35f5ab1a55b8ef6790631139
1 ; RUN: llc -mtriple=aarch64-linux-gnu -mattr=+sve -asm-verbose=0 < %s | FileCheck %s
3 ; NOTE: invalid, upper and lower bound immediate values of the reg+imm
4 ; addressing mode are checked only for the byte version of each
5 ; instruction (`st<N>b`), as the code for detecting the immediate is
6 ; common to all instructions, and varies only for the number of
7 ; elements of the structured store, which is <N> = 2, 3, 4.
10 ; ST2B
13 define void @st2b_i8_valid_imm(<vscale x 16 x i8> %v0, <vscale x 16 x i8> %v1, <vscale x 16 x i1> %pred, <vscale x 16 x i8>* %addr) {
14 ; CHECK-LABEL: st2b_i8_valid_imm:
15 ; CHECK: st2b { z0.b, z1.b }, p0, [x0, #2, mul vl]
16 ; CHECK-NEXT: ret
17   %base = getelementptr <vscale x 16 x i8>, <vscale x 16 x i8>* %addr, i64 2, i64 0
18   call void @llvm.aarch64.sve.st2.nxv16i8(<vscale x 16 x i8> %v0,
19                                           <vscale x 16 x i8> %v1,
20                                           <vscale x 16 x i1> %pred,
21                                           i8* %base)
22   ret void
25 define void @st2b_i8_invalid_imm_not_multiple_of_2(<vscale x 16 x i8> %v0, <vscale x 16 x i8> %v1, <vscale x 16 x i1> %pred, <vscale x 16 x i8>* %addr) {
26 ; CHECK-LABEL: st2b_i8_invalid_imm_not_multiple_of_2:
27 ; CHECK: rdvl x[[N:[0-9]+]], #3
28 ; CHECK-NEXT: st2b { z0.b, z1.b }, p0, [x0, x[[N]]]
29 ; CHECK-NEXT: ret
30   %base = getelementptr <vscale x 16 x i8>, <vscale x 16 x i8>* %addr, i64 3, i64 0
31   call void @llvm.aarch64.sve.st2.nxv16i8(<vscale x 16 x i8> %v0,
32                                           <vscale x 16 x i8> %v1,
33                                           <vscale x 16 x i1> %pred,
34                                           i8* %base)
35   ret void
38 define void @st2b_i8_invalid_imm_out_of_lower_bound(<vscale x 16 x i8> %v0, <vscale x 16 x i8> %v1, <vscale x 16 x i1> %pred, <vscale x 16 x i8>* %addr) {
39 ; CHECK-LABEL: st2b_i8_invalid_imm_out_of_lower_bound:
40 ; CHECK: rdvl x[[N:[0-9]+]], #-18
41 ; CHECK-NEXT: st2b { z0.b, z1.b }, p0, [x0, x[[N]]]
42 ; CHECK-NEXT: ret
43   %base = getelementptr <vscale x 16 x i8>, <vscale x 16 x i8>* %addr, i64 -18, i64 0
44   call void @llvm.aarch64.sve.st2.nxv16i8(<vscale x 16 x i8> %v0,
45                                           <vscale x 16 x i8> %v1,
46                                           <vscale x 16 x i1> %pred,
47                                           i8* %base)
48   ret void
51 define void @st2b_i8_invalid_imm_out_of_upper_bound(<vscale x 16 x i8> %v0, <vscale x 16 x i8> %v1, <vscale x 16 x i1> %pred, <vscale x 16 x i8>* %addr) {
52 ; CHECK-LABEL: st2b_i8_invalid_imm_out_of_upper_bound:
53 ; CHECK: rdvl x[[N:[0-9]+]], #16
54 ; CHECK-NEXT: st2b { z0.b, z1.b }, p0, [x0, x[[N]]]
55 ; CHECK-NEXT: ret
56   %base = getelementptr <vscale x 16 x i8>, <vscale x 16 x i8>* %addr, i64 16, i64 0
57   call void @llvm.aarch64.sve.st2.nxv16i8(<vscale x 16 x i8> %v0,
58                                           <vscale x 16 x i8> %v1,
59                                           <vscale x 16 x i1> %pred,
60                                           i8* %base)
61   ret void
64 define void @st2b_i8_valid_imm_lower_bound(<vscale x 16 x i8> %v0, <vscale x 16 x i8> %v1, <vscale x 16 x i1> %pred, <vscale x 16 x i8>* %addr) {
65 ; CHECK-LABEL: st2b_i8_valid_imm_lower_bound:
66 ; CHECK: st2b { z0.b, z1.b }, p0, [x0, #-16, mul vl]
67 ; CHECK-NEXT: ret
68   %base = getelementptr <vscale x 16 x i8>, <vscale x 16 x i8>* %addr, i64 -16, i64 0
69   call void @llvm.aarch64.sve.st2.nxv16i8(<vscale x 16 x i8> %v0,
70                                           <vscale x 16 x i8> %v1,
71                                           <vscale x 16 x i1> %pred,
72                                           i8* %base)
73   ret void
76 define void @st2b_i8_valid_imm_upper_bound(<vscale x 16 x i8> %v0, <vscale x 16 x i8> %v1, <vscale x 16 x i1> %pred, <vscale x 16 x i8>* %addr) {
77 ; CHECK-LABEL: st2b_i8_valid_imm_upper_bound:
78 ; CHECK: st2b { z0.b, z1.b }, p0, [x0, #14, mul vl]
79 ; CHECK-NEXT: ret
80   %base = getelementptr <vscale x 16 x i8>, <vscale x 16 x i8>* %addr, i64 14, i64 0
81   call void @llvm.aarch64.sve.st2.nxv16i8(<vscale x 16 x i8> %v0,
82                                           <vscale x 16 x i8> %v1,
83                                           <vscale x 16 x i1> %pred,
84                                           i8* %base)
85   ret void
89 ; ST2H
92 define void @st2h_i16(<vscale x 8 x i16> %v0, <vscale x 8 x i16> %v1, <vscale x 8 x i1> %pred, <vscale x 8 x i16>* %addr) {
93 ; CHECK-LABEL: st2h_i16:
94 ; CHECK: st2h { z0.h, z1.h }, p0, [x0, #2, mul vl]
95 ; CHECK-NEXT: ret
96   %base = getelementptr <vscale x 8 x i16>, <vscale x 8 x i16>* %addr, i64 2, i64 0
97   call void @llvm.aarch64.sve.st2.nxv8i16(<vscale x 8 x i16> %v0,
98                                           <vscale x 8 x i16> %v1,
99                                           <vscale x 8 x i1> %pred,
100                                           i16* %base)
101   ret void
104 define void @st2h_f16(<vscale x 8 x half> %v0, <vscale x 8 x half> %v1, <vscale x 8 x i1> %pred, <vscale x 8 x half>* %addr) {
105 ; CHECK-LABEL: st2h_f16:
106 ; CHECK: st2h { z0.h, z1.h }, p0, [x0, #2, mul vl]
107 ; CHECK-NEXT: ret
108   %base = getelementptr <vscale x 8 x half>, <vscale x 8 x half>* %addr, i64 2, i64 0
109   call void @llvm.aarch64.sve.st2.nxv8f16(<vscale x 8 x half> %v0,
110                                           <vscale x 8 x half> %v1,
111                                           <vscale x 8 x i1> %pred,
112                                           half* %base)
113   ret void
117 ; ST2W
120 define void @st2w_i32(<vscale x 4 x i32> %v0, <vscale x 4 x i32> %v1, <vscale x 4 x i1> %pred, <vscale x 4 x i32>* %addr) {
121 ; CHECK-LABEL: st2w_i32:
122 ; CHECK: st2w { z0.s, z1.s }, p0, [x0, #4, mul vl]
123 ; CHECK-NEXT: ret
124   %base = getelementptr <vscale x 4 x i32>, <vscale x 4 x i32>* %addr, i64 4, i64 0
125   call void @llvm.aarch64.sve.st2.nxv4i32(<vscale x 4 x i32> %v0,
126                                           <vscale x 4 x i32> %v1,
127                                           <vscale x 4 x i1> %pred,
128                                           i32* %base)
129   ret void
132 define void @st2w_f32(<vscale x 4 x float> %v0, <vscale x 4 x float> %v1, <vscale x 4 x i1> %pred, <vscale x 4 x float>* %addr) {
133 ; CHECK-LABEL: st2w_f32:
134 ; CHECK: st2w { z0.s, z1.s }, p0, [x0, #6, mul vl]
135 ; CHECK-NEXT: ret
136   %base = getelementptr <vscale x 4 x float>, <vscale x 4 x float>* %addr, i64 6, i64 0
137   call void @llvm.aarch64.sve.st2.nxv4f32(<vscale x 4 x float> %v0,
138                                           <vscale x 4 x float> %v1,
139                                           <vscale x 4 x i1> %pred,
140                                           float* %base)
141   ret void
145 ; ST2D
148 define void @st2d_i64(<vscale x 2 x i64> %v0, <vscale x 2 x i64> %v1, <vscale x 2 x i1> %pred, <vscale x 2 x i64>* %addr) {
149 ; CHECK-LABEL: st2d_i64:
150 ; CHECK: st2d { z0.d, z1.d }, p0, [x0, #8, mul vl]
151 ; CHECK-NEXT: ret
152   %base = getelementptr <vscale x 2 x i64>, <vscale x 2 x i64>* %addr, i64 8, i64 0
153   call void @llvm.aarch64.sve.st2.nxv2i64(<vscale x 2 x i64> %v0,
154                                           <vscale x 2 x i64> %v1,
155                                           <vscale x 2 x i1> %pred,
156                                           i64* %base)
157   ret void
160 define void @st2d_f64(<vscale x 2 x double> %v0, <vscale x 2 x double> %v1, <vscale x 2 x i1> %pred, <vscale x 2 x double>* %addr) {
161 ; CHECK-LABEL: st2d_f64:
162 ; CHECK: st2d { z0.d, z1.d }, p0, [x0, #10, mul vl]
163 ; CHECK-NEXT: ret
164   %base = getelementptr <vscale x 2 x double>, <vscale x 2 x double>* %addr, i64 10, i64 0
165   call void @llvm.aarch64.sve.st2.nxv2f64(<vscale x 2 x double> %v0,
166                                           <vscale x 2 x double> %v1,
167                                           <vscale x 2 x i1> %pred,
168                                           double* %base)
169   ret void
173 ; ST3B
176 define void @st3b_i8_valid_imm(<vscale x 16 x i8> %v0, <vscale x 16 x i8> %v1, <vscale x 16 x i8> %v2, <vscale x 16 x i1> %pred, <vscale x 16 x i8>* %addr) {
177 ; CHECK-LABEL: st3b_i8_valid_imm:
178 ; CHECK: st3b { z0.b, z1.b, z2.b }, p0, [x0, #3, mul vl]
179 ; CHECK-NEXT: ret
180   %base = getelementptr <vscale x 16 x i8>, <vscale x 16 x i8>* %addr, i64 3, i64 0
181   call void @llvm.aarch64.sve.st3.nxv16i8(<vscale x 16 x i8> %v0,
182                                           <vscale x 16 x i8> %v1,
183                                           <vscale x 16 x i8> %v2,
184                                           <vscale x 16 x i1> %pred,
185                                           i8* %base)
186   ret void
189 define void @st3b_i8_invalid_imm_not_multiple_of_3_01(<vscale x 16 x i8> %v0, <vscale x 16 x i8> %v1, <vscale x 16 x i8> %v2, <vscale x 16 x i1> %pred, <vscale x 16 x i8>* %addr) {
190 ; CHECK-LABEL: st3b_i8_invalid_imm_not_multiple_of_3_01:
191 ; CHECK: rdvl x[[N:[0-9]+]], #4
192 ; CHECK-NEXT: st3b { z0.b, z1.b, z2.b }, p0, [x0, x[[N]]]
193 ; CHECK-NEXT: ret
194   %base = getelementptr <vscale x 16 x i8>, <vscale x 16 x i8>* %addr, i64 4, i64 0
195   call void @llvm.aarch64.sve.st3.nxv16i8(<vscale x 16 x i8> %v0,
196                                           <vscale x 16 x i8> %v1,
197                                           <vscale x 16 x i8> %v2,
198                                           <vscale x 16 x i1> %pred,
199                                           i8* %base)
200   ret void
203 define void @st3b_i8_invalid_imm_not_multiple_of_3_02(<vscale x 16 x i8> %v0, <vscale x 16 x i8> %v1, <vscale x 16 x i8> %v2, <vscale x 16 x i1> %pred, <vscale x 16 x i8>* %addr) {
204 ; CHECK-LABEL: st3b_i8_invalid_imm_not_multiple_of_3_02:
205 ; CHECK: rdvl x[[N:[0-9]+]], #5
206 ; CHECK-NEXT: st3b { z0.b, z1.b, z2.b }, p0, [x0, x[[N]]]
207 ; CHECK-NEXT: ret
208   %base = getelementptr <vscale x 16 x i8>, <vscale x 16 x i8>* %addr, i64 5, i64 0
209   call void @llvm.aarch64.sve.st3.nxv16i8(<vscale x 16 x i8> %v0,
210                                           <vscale x 16 x i8> %v1,
211                                           <vscale x 16 x i8> %v2,
212                                           <vscale x 16 x i1> %pred,
213                                           i8* %base)
214   ret void
217 define void @st3b_i8_invalid_imm_out_of_lower_bound(<vscale x 16 x i8> %v0, <vscale x 16 x i8> %v1, <vscale x 16 x i8> %v2, <vscale x 16 x i1> %pred, <vscale x 16 x i8>* %addr) {
218 ; CHECK-LABEL: st3b_i8_invalid_imm_out_of_lower_bound:
219 ; CHECK: rdvl x[[N:[0-9]+]], #-27
220 ; CHECK-NEXT: st3b { z0.b, z1.b, z2.b }, p0, [x0, x[[N]]]
221 ; CHECK-NEXT: ret
222   %base = getelementptr <vscale x 16 x i8>, <vscale x 16 x i8>* %addr, i64 -27, i64 0
223   call void @llvm.aarch64.sve.st3.nxv16i8(<vscale x 16 x i8> %v0,
224                                           <vscale x 16 x i8> %v1,
225                                           <vscale x 16 x i8> %v2,
226                                           <vscale x 16 x i1> %pred,
227                                           i8* %base)
228   ret void
231 define void @st3b_i8_invalid_imm_out_of_upper_bound(<vscale x 16 x i8> %v0, <vscale x 16 x i8> %v1, <vscale x 16 x i8> %v2, <vscale x 16 x i1> %pred, <vscale x 16 x i8>* %addr) {
232 ; CHECK-LABEL: st3b_i8_invalid_imm_out_of_upper_bound:
233 ; CHECK: rdvl x[[N:[0-9]+]], #24
234 ; CHECK-NEXT: st3b { z0.b, z1.b, z2.b }, p0, [x0, x[[N]]]
235 ; CHECK-NEXT: ret
236   %base = getelementptr <vscale x 16 x i8>, <vscale x 16 x i8>* %addr, i64 24, i64 0
237   call void @llvm.aarch64.sve.st3.nxv16i8(<vscale x 16 x i8> %v0,
238                                           <vscale x 16 x i8> %v1,
239                                           <vscale x 16 x i8> %v2,
240                                           <vscale x 16 x i1> %pred,
241                                           i8* %base)
242   ret void
245 define void @st3b_i8_valid_imm_lower_bound(<vscale x 16 x i8> %v0, <vscale x 16 x i8> %v1, <vscale x 16 x i8> %v2, <vscale x 16 x i1> %pred, <vscale x 16 x i8>* %addr) {
246 ; CHECK-LABEL: st3b_i8_valid_imm_lower_bound:
247 ; CHECK: st3b { z0.b, z1.b, z2.b }, p0, [x0, #-24, mul vl]
248 ; CHECK-NEXT: ret
249   %base = getelementptr <vscale x 16 x i8>, <vscale x 16 x i8>* %addr, i64 -24, i64 0
250   call void @llvm.aarch64.sve.st3.nxv16i8(<vscale x 16 x i8> %v0,
251                                           <vscale x 16 x i8> %v1,
252                                           <vscale x 16 x i8> %v2,
253                                           <vscale x 16 x i1> %pred,
254                                           i8* %base)
255   ret void
258 define void @st3b_i8_valid_imm_upper_bound(<vscale x 16 x i8> %v0, <vscale x 16 x i8> %v1, <vscale x 16 x i8> %v2, <vscale x 16 x i1> %pred, <vscale x 16 x i8>* %addr) {
259 ; CHECK-LABEL: st3b_i8_valid_imm_upper_bound:
260 ; CHECK: st3b { z0.b, z1.b, z2.b }, p0, [x0, #21, mul vl]
261 ; CHECK-NEXT: ret
262   %base = getelementptr <vscale x 16 x i8>, <vscale x 16 x i8>* %addr, i64 21, i64 0
263   call void @llvm.aarch64.sve.st3.nxv16i8(<vscale x 16 x i8> %v0,
264                                           <vscale x 16 x i8> %v1,
265                                           <vscale x 16 x i8> %v2,
266                                           <vscale x 16 x i1> %pred,
267                                           i8* %base)
268   ret void
272 ; ST3H
275 define void @st3h_i16(<vscale x 8 x i16> %v0, <vscale x 8 x i16> %v1, <vscale x 8 x i16> %v2, <vscale x 8 x i1> %pred, <vscale x 8 x i16>* %addr) {
276 ; CHECK-LABEL: st3h_i16:
277 ; CHECK: st3h { z0.h, z1.h, z2.h }, p0, [x0, #6, mul vl]
278 ; CHECK-NEXT: ret
279   %base = getelementptr <vscale x 8 x i16>, <vscale x 8 x i16>* %addr, i64 6, i64 0
280   call void @llvm.aarch64.sve.st3.nxv8i16(<vscale x 8 x i16> %v0,
281                                           <vscale x 8 x i16> %v1,
282                                           <vscale x 8 x i16> %v2,
283                                           <vscale x 8 x i1> %pred,
284                                           i16* %base)
285   ret void
288 define void @st3h_f16(<vscale x 8 x half> %v0, <vscale x 8 x half> %v1, <vscale x 8 x half> %v2, <vscale x 8 x i1> %pred, <vscale x 8 x half>* %addr) {
289 ; CHECK-LABEL: st3h_f16:
290 ; CHECK: st3h { z0.h, z1.h, z2.h }, p0, [x0, #9, mul vl]
291 ; CHECK-NEXT: ret
292   %base = getelementptr <vscale x 8 x half>, <vscale x 8 x half>* %addr, i64 9, i64 0
293   call void @llvm.aarch64.sve.st3.nxv8f16(<vscale x 8 x half> %v0,
294                                           <vscale x 8 x half> %v1,
295                                           <vscale x 8 x half> %v2,
296                                           <vscale x 8 x i1> %pred,
297                                           half* %base)
298   ret void
302 ; ST3W
305 define void @st3w_i32(<vscale x 4 x i32> %v0, <vscale x 4 x i32> %v1, <vscale x 4 x i32> %v2, <vscale x 4 x i1> %pred, <vscale x 4 x i32>* %addr) {
306 ; CHECK-LABEL: st3w_i32:
307 ; CHECK: st3w { z0.s, z1.s, z2.s }, p0, [x0, #12, mul vl]
308 ; CHECK-NEXT: ret
309   %base = getelementptr <vscale x 4 x i32>, <vscale x 4 x i32>* %addr, i64 12, i64 0
310   call void @llvm.aarch64.sve.st3.nxv4i32(<vscale x 4 x i32> %v0,
311                                           <vscale x 4 x i32> %v1,
312                                           <vscale x 4 x i32> %v2,
313                                           <vscale x 4 x i1> %pred,
314                                           i32* %base)
315   ret void
318 define void @st3w_f32(<vscale x 4 x float> %v0, <vscale x 4 x float> %v1, <vscale x 4 x float> %v2, <vscale x 4 x i1> %pred, <vscale x 4 x float>* %addr) {
319 ; CHECK-LABEL: st3w_f32:
320 ; CHECK: st3w { z0.s, z1.s, z2.s }, p0, [x0, #15, mul vl]
321 ; CHECK-NEXT: ret
322   %base = getelementptr <vscale x 4 x float>, <vscale x 4 x float>* %addr, i64 15, i64 0
323   call void @llvm.aarch64.sve.st3.nxv4f32(<vscale x 4 x float> %v0,
324                                           <vscale x 4 x float> %v1,
325                                           <vscale x 4 x float> %v2,
326                                           <vscale x 4 x i1> %pred,
327                                           float* %base)
328   ret void
332 ; ST3D
335 define void @st3d_i64(<vscale x 2 x i64> %v0, <vscale x 2 x i64> %v1, <vscale x 2 x i64> %v2, <vscale x 2 x i1> %pred, <vscale x 2 x i64>* %addr) {
336 ; CHECK-LABEL: st3d_i64:
337 ; CHECK: st3d { z0.d, z1.d, z2.d }, p0, [x0, #18, mul vl]
338 ; CHECK-NEXT: ret
339   %base = getelementptr <vscale x 2 x i64>, <vscale x 2 x i64>* %addr, i64 18, i64 0
340   call void @llvm.aarch64.sve.st3.nxv2i64(<vscale x 2 x i64> %v0,
341                                           <vscale x 2 x i64> %v1,
342                                           <vscale x 2 x i64> %v2,
343                                           <vscale x 2 x i1> %pred,
344                                           i64* %base)
345   ret void
348 define void @st3d_f64(<vscale x 2 x double> %v0, <vscale x 2 x double> %v1, <vscale x 2 x double> %v2, <vscale x 2 x i1> %pred, <vscale x 2 x double>* %addr) {
349 ; CHECK-LABEL: st3d_f64:
350 ; CHECK: st3d { z0.d, z1.d, z2.d }, p0, [x0, #-3, mul vl]
351 ; CHECK-NEXT: ret
352   %base = getelementptr <vscale x 2 x double>, <vscale x 2 x double>* %addr, i64 -3, i64 0
353   call void @llvm.aarch64.sve.st3.nxv2f64(<vscale x 2 x double> %v0,
354                                           <vscale x 2 x double> %v1,
355                                           <vscale x 2 x double> %v2,
356                                           <vscale x 2 x i1> %pred,
357                                           double* %base)
358   ret void
362 ; ST4B
365 define void @st4b_i8_valid_imm(<vscale x 16 x i8> %v0, <vscale x 16 x i8> %v1, <vscale x 16 x i8> %v2, <vscale x 16 x i8> %v3, <vscale x 16 x i1> %pred, <vscale x 16 x i8>* %addr) {
366 ; CHECK-LABEL: st4b_i8_valid_imm:
367 ; CHECK: st4b { z0.b, z1.b, z2.b, z3.b }, p0, [x0, #4, mul vl]
368 ; CHECK-NEXT: ret
369   %base = getelementptr <vscale x 16 x i8>, <vscale x 16 x i8>* %addr, i64 4, i64 0
370   call void @llvm.aarch64.sve.st4.nxv16i8(<vscale x 16 x i8> %v0,
371                                           <vscale x 16 x i8> %v1,
372                                           <vscale x 16 x i8> %v2,
373                                           <vscale x 16 x i8> %v3,
374                                           <vscale x 16 x i1> %pred,
375                                           i8* %base)
376   ret void
379 define void @st4b_i8_invalid_imm_not_multiple_of_4_01(<vscale x 16 x i8> %v0, <vscale x 16 x i8> %v1, <vscale x 16 x i8> %v2, <vscale x 16 x i8> %v3, <vscale x 16 x i1> %pred, <vscale x 16 x i8>* %addr) {
380 ; CHECK-LABEL: st4b_i8_invalid_imm_not_multiple_of_4_01:
381 ; CHECK: rdvl x[[N:[0-9]+]], #5
382 ; CHECK-NEXT: st4b { z0.b, z1.b, z2.b, z3.b }, p0, [x0, x[[N]]]
383 ; CHECK-NEXT: ret
384   %base = getelementptr <vscale x 16 x i8>, <vscale x 16 x i8>* %addr, i64 5, i64 0
385   call void @llvm.aarch64.sve.st4.nxv16i8(<vscale x 16 x i8> %v0,
386                                           <vscale x 16 x i8> %v1,
387                                           <vscale x 16 x i8> %v2,
388                                           <vscale x 16 x i8> %v3,
389                                           <vscale x 16 x i1> %pred,
390                                           i8* %base)
391   ret void
394 define void @st4b_i8_invalid_imm_not_multiple_of_4_02(<vscale x 16 x i8> %v0, <vscale x 16 x i8> %v1, <vscale x 16 x i8> %v2, <vscale x 16 x i8> %v3, <vscale x 16 x i1> %pred, <vscale x 16 x i8>* %addr) {
395 ; CHECK-LABEL: st4b_i8_invalid_imm_not_multiple_of_4_02:
396 ; CHECK: rdvl x[[N:[0-9]+]], #6
397 ; CHECK-NEXT: st4b { z0.b, z1.b, z2.b, z3.b }, p0, [x0, x[[N]]]
398 ; CHECK-NEXT: ret
399   %base = getelementptr <vscale x 16 x i8>, <vscale x 16 x i8>* %addr, i64 6, i64 0
400   call void @llvm.aarch64.sve.st4.nxv16i8(<vscale x 16 x i8> %v0,
401                                           <vscale x 16 x i8> %v1,
402                                           <vscale x 16 x i8> %v2,
403                                           <vscale x 16 x i8> %v3,
404                                           <vscale x 16 x i1> %pred,
405                                           i8* %base)
406   ret void
409 define void @st4b_i8_invalid_imm_not_multiple_of_4_03(<vscale x 16 x i8> %v0, <vscale x 16 x i8> %v1, <vscale x 16 x i8> %v2, <vscale x 16 x i8> %v3, <vscale x 16 x i1> %pred, <vscale x 16 x i8>* %addr) {
410 ; CHECK-LABEL: st4b_i8_invalid_imm_not_multiple_of_4_03:
411 ; CHECK: rdvl x[[N:[0-9]+]], #7
412 ; CHECK-NEXT: st4b { z0.b, z1.b, z2.b, z3.b }, p0, [x0, x[[N]]]
413 ; CHECK-NEXT: ret
414   %base = getelementptr <vscale x 16 x i8>, <vscale x 16 x i8>* %addr, i64 7, i64 0
415   call void @llvm.aarch64.sve.st4.nxv16i8(<vscale x 16 x i8> %v0,
416                                           <vscale x 16 x i8> %v1,
417                                           <vscale x 16 x i8> %v2,
418                                           <vscale x 16 x i8> %v3,
419                                           <vscale x 16 x i1> %pred,
420                                           i8* %base)
421   ret void
424 define void @st4b_i8_invalid_imm_out_of_lower_bound(<vscale x 16 x i8> %v0, <vscale x 16 x i8> %v1, <vscale x 16 x i8> %v2, <vscale x 16 x i8> %v3, <vscale x 16 x i1> %pred, <vscale x 16 x i8>* %addr) {
425 ; CHECK-LABEL: st4b_i8_invalid_imm_out_of_lower_bound:
426 ; FIXME: optimize OFFSET computation so that xOFFSET = (mul (RDVL #4) #9)
427 ; xM = -9 * 2^6
428 ; xP = RDVL * 2^-4
429 ; xBASE = RDVL * 2^-4 * -9 * 2^6 = RDVL * -36
430 ; CHECK: rdvl x[[N:[0-9]+]], #1
431 ; CHECK-DAG:  mov  x[[M:[0-9]+]], #-576
432 ; CHECK-DAG:  lsr  x[[P:[0-9]+]], x[[N]], #4
433 ; CHECK-DAG:  mul  x[[OFFSET:[0-9]+]], x[[P]], x[[M]]
434 ; CHECK-NEXT: st4b { z0.b, z1.b, z2.b, z3.b }, p0, [x0, x[[OFFSET]]]
435 ; CHECK-NEXT: ret
436   %base = getelementptr <vscale x 16 x i8>, <vscale x 16 x i8>* %addr, i64 -36, i64 0
437   call void @llvm.aarch64.sve.st4.nxv16i8(<vscale x 16 x i8> %v0,
438                                           <vscale x 16 x i8> %v1,
439                                           <vscale x 16 x i8> %v2,
440                                           <vscale x 16 x i8> %v3,
441                                           <vscale x 16 x i1> %pred,
442                                           i8* %base)
443   ret void
446 define void @st4b_i8_invalid_imm_out_of_upper_bound(<vscale x 16 x i8> %v0, <vscale x 16 x i8> %v1, <vscale x 16 x i8> %v2, <vscale x 16 x i8> %v3, <vscale x 16 x i1> %pred, <vscale x 16 x i8>* %addr) {
447 ; CHECK-LABEL: st4b_i8_invalid_imm_out_of_upper_bound:
448 ; FIXME: optimize OFFSET computation so that xOFFSET = (shl (RDVL #16) #1)
449 ; xM = 2^9
450 ; xP = RDVL * 2^-4
451 ; xOFFSET = RDVL * 2^-4 * 2^9 = RDVL * 32
452 ; CHECK: rdvl x[[N:[0-9]+]], #1
453 ; CHECK-DAG:  mov  w[[M:[0-9]+]], #512
454 ; CHECK-DAG:  lsr  x[[P:[0-9]+]], x[[N]], #4
455 ; CHECK-DAG:  mul  x[[OFFSET:[0-9]+]], x[[P]], x[[M]]
456 ; CHECK-NEXT: st4b { z0.b, z1.b, z2.b, z3.b }, p0, [x0, x[[OFFSET]]]
457 ; CHECK-NEXT: ret
458   %base = getelementptr <vscale x 16 x i8>, <vscale x 16 x i8>* %addr, i64 32, i64 0
459   call void @llvm.aarch64.sve.st4.nxv16i8(<vscale x 16 x i8> %v0,
460                                           <vscale x 16 x i8> %v1,
461                                           <vscale x 16 x i8> %v2,
462                                           <vscale x 16 x i8> %v3,
463                                           <vscale x 16 x i1> %pred,
464                                           i8* %base)
465   ret void
468 define void @st4b_i8_valid_imm_lower_bound(<vscale x 16 x i8> %v0, <vscale x 16 x i8> %v1, <vscale x 16 x i8> %v2, <vscale x 16 x i8> %v3, <vscale x 16 x i1> %pred, <vscale x 16 x i8>* %addr) {
469 ; CHECK-LABEL: st4b_i8_valid_imm_lower_bound:
470 ; CHECK: st4b { z0.b, z1.b, z2.b, z3.b }, p0, [x0, #-32, mul vl]
471 ; CHECK-NEXT: ret
472   %base = getelementptr <vscale x 16 x i8>, <vscale x 16 x i8>* %addr, i64 -32, i64 0
473   call void @llvm.aarch64.sve.st4.nxv16i8(<vscale x 16 x i8> %v0,
474                                           <vscale x 16 x i8> %v1,
475                                           <vscale x 16 x i8> %v2,
476                                           <vscale x 16 x i8> %v3,
477                                           <vscale x 16 x i1> %pred,
478                                           i8* %base)
479   ret void
482 define void @st4b_i8_valid_imm_upper_bound(<vscale x 16 x i8> %v0, <vscale x 16 x i8> %v1, <vscale x 16 x i8> %v2, <vscale x 16 x i8> %v3, <vscale x 16 x i1> %pred, <vscale x 16 x i8>* %addr) {
483 ; CHECK-LABEL: st4b_i8_valid_imm_upper_bound:
484 ; CHECK: st4b { z0.b, z1.b, z2.b, z3.b }, p0, [x0, #28, mul vl]
485 ; CHECK-NEXT: ret
486   %base = getelementptr <vscale x 16 x i8>, <vscale x 16 x i8>* %addr, i64 28, i64 0
487   call void @llvm.aarch64.sve.st4.nxv16i8(<vscale x 16 x i8> %v0,
488                                           <vscale x 16 x i8> %v1,
489                                           <vscale x 16 x i8> %v2,
490                                           <vscale x 16 x i8> %v3,
491                                           <vscale x 16 x i1> %pred,
492                                           i8* %base)
493   ret void
497 ; ST4H
500 define void @st4h_i16(<vscale x 8 x i16> %v0, <vscale x 8 x i16> %v1, <vscale x 8 x i16> %v2, <vscale x 8 x i16> %v3, <vscale x 8 x i1> %pred, <vscale x 8 x i16>* %addr) {
501 ; CHECK-LABEL: st4h_i16:
502 ; CHECK: st4h { z0.h, z1.h, z2.h, z3.h }, p0, [x0, #8, mul vl]
503 ; CHECK-NEXT: ret
504   %base = getelementptr <vscale x 8 x i16>, <vscale x 8 x i16>* %addr, i64 8, i64 0
505   call void @llvm.aarch64.sve.st4.nxv8i16(<vscale x 8 x i16> %v0,
506                                           <vscale x 8 x i16> %v1,
507                                           <vscale x 8 x i16> %v2,
508                                           <vscale x 8 x i16> %v3,
509                                           <vscale x 8 x i1> %pred,
510                                           i16* %base)
511   ret void
514 define void @st4h_f16(<vscale x 8 x half> %v0, <vscale x 8 x half> %v1, <vscale x 8 x half> %v2, <vscale x 8 x half> %v3, <vscale x 8 x i1> %pred, <vscale x 8 x half>* %addr) {
515 ; CHECK-LABEL: st4h_f16:
516 ; CHECK: st4h { z0.h, z1.h, z2.h, z3.h }, p0, [x0, #12, mul vl]
517 ; CHECK-NEXT: ret
518   %base = getelementptr <vscale x 8 x half>, <vscale x 8 x half>* %addr, i64 12, i64 0
519   call void @llvm.aarch64.sve.st4.nxv8f16(<vscale x 8 x half> %v0,
520                                           <vscale x 8 x half> %v1,
521                                           <vscale x 8 x half> %v2,
522                                           <vscale x 8 x half> %v3,
523                                           <vscale x 8 x i1> %pred,
524                                           half* %base)
525   ret void
529 ; ST4W
532 define void @st4w_i32(<vscale x 4 x i32> %v0, <vscale x 4 x i32> %v1, <vscale x 4 x i32> %v2, <vscale x 4 x i32> %v3, <vscale x 4 x i1> %pred, <vscale x 4 x i32>* %addr) {
533 ; CHECK-LABEL: st4w_i32:
534 ; CHECK: st4w { z0.s, z1.s, z2.s, z3.s }, p0, [x0, #16, mul vl]
535 ; CHECK-NEXT: ret
536   %base = getelementptr <vscale x 4 x i32>, <vscale x 4 x i32>* %addr, i64 16, i64 0
537   call void @llvm.aarch64.sve.st4.nxv4i32(<vscale x 4 x i32> %v0,
538                                           <vscale x 4 x i32> %v1,
539                                           <vscale x 4 x i32> %v2,
540                                           <vscale x 4 x i32> %v3,
541                                           <vscale x 4 x i1> %pred,
542                                           i32* %base)
543   ret void
546 define void @st4w_f32(<vscale x 4 x float> %v0, <vscale x 4 x float> %v1, <vscale x 4 x float> %v2, <vscale x 4 x float> %v3, <vscale x 4 x i1> %pred, <vscale x 4 x float>* %addr) {
547 ; CHECK-LABEL: st4w_f32:
548 ; CHECK: st4w { z0.s, z1.s, z2.s, z3.s }, p0, [x0, #20, mul vl]
549 ; CHECK-NEXT: ret
550   %base = getelementptr <vscale x 4 x float>, <vscale x 4 x float>* %addr, i64 20, i64 0
551   call void @llvm.aarch64.sve.st4.nxv4f32(<vscale x 4 x float> %v0,
552                                           <vscale x 4 x float> %v1,
553                                           <vscale x 4 x float> %v2,
554                                           <vscale x 4 x float> %v3,
555                                           <vscale x 4 x i1> %pred,
556                                           float* %base)
557   ret void
561 ; ST4D
564 define void @st4d_i64(<vscale x 2 x i64> %v0, <vscale x 2 x i64> %v1, <vscale x 2 x i64> %v2, <vscale x 2 x i64> %v3, <vscale x 2 x i1> %pred, <vscale x 2 x i64>* %addr) {
565 ; CHECK-LABEL: st4d_i64:
566 ; CHECK: st4d { z0.d, z1.d, z2.d, z3.d }, p0, [x0, #24, mul vl]
567 ; CHECK-NEXT: ret
568   %base = getelementptr <vscale x 2 x i64>, <vscale x 2 x i64>* %addr, i64 24, i64 0
569   call void @llvm.aarch64.sve.st4.nxv2i64(<vscale x 2 x i64> %v0,
570                                           <vscale x 2 x i64> %v1,
571                                           <vscale x 2 x i64> %v2,
572                                           <vscale x 2 x i64> %v3,
573                                           <vscale x 2 x i1> %pred,
574                                           i64* %base)
575   ret void
578 define void @st4d_f64(<vscale x 2 x double> %v0, <vscale x 2 x double> %v1, <vscale x 2 x double> %v2, <vscale x 2 x double> %v3, <vscale x 2 x i1> %pred, <vscale x 2 x double>* %addr) {
579 ; CHECK-LABEL: st4d_f64:
580 ; CHECK: st4d { z0.d, z1.d, z2.d, z3.d }, p0, [x0, #28, mul vl]
581 ; CHECK-NEXT: ret
582   %base = getelementptr <vscale x 2 x double>, <vscale x 2 x double>* %addr, i64 28, i64 0
583   call void @llvm.aarch64.sve.st4.nxv2f64(<vscale x 2 x double> %v0,
584                                           <vscale x 2 x double> %v1,
585                                           <vscale x 2 x double> %v2,
586                                           <vscale x 2 x double> %v3,
587                                           <vscale x 2 x i1> %pred,
588                                           double* %base)
589   ret void
592 declare void @llvm.aarch64.sve.st2.nxv16i8(<vscale x 16 x i8>, <vscale x 16 x i8>, <vscale x 16 x i1>, i8*)
593 declare void @llvm.aarch64.sve.st2.nxv8i16(<vscale x 8 x i16>, <vscale x 8 x i16>, <vscale x 8 x i1>, i16*)
594 declare void @llvm.aarch64.sve.st2.nxv4i32(<vscale x 4 x i32>, <vscale x 4 x i32>, <vscale x 4 x i1>, i32*)
595 declare void @llvm.aarch64.sve.st2.nxv2i64(<vscale x 2 x i64>, <vscale x 2 x i64>, <vscale x 2 x i1>, i64*)
596 declare void @llvm.aarch64.sve.st2.nxv8f16(<vscale x 8 x half>, <vscale x 8 x half>, <vscale x 8 x i1>, half*)
597 declare void @llvm.aarch64.sve.st2.nxv4f32(<vscale x 4 x float>, <vscale x 4 x float>, <vscale x 4 x i1>, float*)
598 declare void @llvm.aarch64.sve.st2.nxv2f64(<vscale x 2 x double>, <vscale x 2 x double>, <vscale x 2 x i1>, double*)
600 declare void @llvm.aarch64.sve.st3.nxv16i8(<vscale x 16 x i8>, <vscale x 16 x i8>, <vscale x 16 x i8>, <vscale x 16 x i1>, i8*)
601 declare void @llvm.aarch64.sve.st3.nxv8i16(<vscale x 8 x i16>, <vscale x 8 x i16>, <vscale x 8 x i16>, <vscale x 8 x i1>, i16*)
602 declare void @llvm.aarch64.sve.st3.nxv4i32(<vscale x 4 x i32>, <vscale x 4 x i32>, <vscale x 4 x i32>, <vscale x 4 x i1>, i32*)
603 declare void @llvm.aarch64.sve.st3.nxv2i64(<vscale x 2 x i64>, <vscale x 2 x i64>, <vscale x 2 x i64>, <vscale x 2 x i1>, i64*)
604 declare void @llvm.aarch64.sve.st3.nxv8f16(<vscale x 8 x half>, <vscale x 8 x half>, <vscale x 8 x half>, <vscale x 8 x i1>, half*)
605 declare void @llvm.aarch64.sve.st3.nxv4f32(<vscale x 4 x float>, <vscale x 4 x float>, <vscale x 4 x float>, <vscale x 4 x i1>, float*)
606 declare void @llvm.aarch64.sve.st3.nxv2f64(<vscale x 2 x double>, <vscale x 2 x double>, <vscale x 2 x double>, <vscale x 2 x i1>, double*)
608 declare void @llvm.aarch64.sve.st4.nxv16i8(<vscale x 16 x i8>, <vscale x 16 x i8>, <vscale x 16 x i8>, <vscale x 16 x i8>, <vscale x 16 x i1>, i8*)
609 declare void @llvm.aarch64.sve.st4.nxv8i16(<vscale x 8 x i16>, <vscale x 8 x i16>, <vscale x 8 x i16>, <vscale x 8 x i16>, <vscale x 8 x i1>, i16*)
610 declare void @llvm.aarch64.sve.st4.nxv4i32(<vscale x 4 x i32>, <vscale x 4 x i32>, <vscale x 4 x i32>, <vscale x 4 x i32>, <vscale x 4 x i1>, i32*)
611 declare void @llvm.aarch64.sve.st4.nxv2i64(<vscale x 2 x i64>, <vscale x 2 x i64>, <vscale x 2 x i64>, <vscale x 2 x i64>, <vscale x 2 x i1>, i64*)
612 declare void @llvm.aarch64.sve.st4.nxv8f16(<vscale x 8 x half>, <vscale x 8 x half>, <vscale x 8 x half>, <vscale x 8 x half>, <vscale x 8 x i1>, half*)
613 declare void @llvm.aarch64.sve.st4.nxv4f32(<vscale x 4 x float>, <vscale x 4 x float>, <vscale x 4 x float>, <vscale x 4 x float>, <vscale x 4 x i1>, float*)
614 declare void @llvm.aarch64.sve.st4.nxv2f64(<vscale x 2 x double>, <vscale x 2 x double>, <vscale x 2 x double>, <vscale x 2 x double>, <vscale x 2 x i1>, double*)