[NFC][RemoveDIs] Prefer iterators over inst-pointers in InstCombine
[llvm-project.git] / llvm / test / CodeGen / AArch64 / sve-pred-contiguous-ldst-addressing-mode-reg-imm.ll
blobc85779b99b048aa3db5780c75be356ae835542ca
1 ; NOTE: Assertions have been autogenerated by utils/update_llc_test_checks.py
2 ; RUN: llc -mtriple=aarch64-linux-gnu -mattr=+sve < %s | FileCheck %s
4 ; Range checks: for all the instruction tested in this file, the
5 ; immediate must be within the range [-8, 7] (4-bit immediate). Out of
6 ; range values are tested only in one case (following). Valid values
7 ; are tested all through the rest of the file.
9 define void @imm_out_of_range(<vscale x 2 x i64> * %base, <vscale x 2 x i1> %mask) nounwind {
10 ; CHECK-LABEL: imm_out_of_range:
11 ; CHECK:       // %bb.0:
12 ; CHECK-NEXT:    addvl x8, x0, #8
13 ; CHECK-NEXT:    ld1d { z0.d }, p0/z, [x8]
14 ; CHECK-NEXT:    addvl x8, x0, #-9
15 ; CHECK-NEXT:    st1d { z0.d }, p0, [x8]
16 ; CHECK-NEXT:    ret
17   %base_load = getelementptr <vscale x 2 x i64>, <vscale x 2 x i64>* %base, i64 8
18   %data = call <vscale x 2 x i64> @llvm.masked.load.nxv2i64(<vscale x 2 x i64>* %base_load,
19                                                             i32 1,
20                                                             <vscale x 2 x i1> %mask,
21                                                             <vscale x 2 x i64> undef)
22   %base_store = getelementptr <vscale x 2 x i64>, <vscale x 2 x i64> * %base, i64 -9
23   call void @llvm.masked.store.nxv2i64(<vscale x 2 x i64> %data,
24                                        <vscale x 2 x i64>* %base_store,
25                                        i32 1,
26                                        <vscale x 2 x i1> %mask)
27   ret void
30 ; 2-lane contiguous load/stores
32 define void @test_masked_ldst_sv2i8(<vscale x 2 x i8> * %base, <vscale x 2 x i1> %mask) nounwind {
33 ; CHECK-LABEL: test_masked_ldst_sv2i8:
34 ; CHECK:       // %bb.0:
35 ; CHECK-NEXT:    ld1b { z0.d }, p0/z, [x0, #-8, mul vl]
36 ; CHECK-NEXT:    st1b { z0.d }, p0, [x0, #-7, mul vl]
37 ; CHECK-NEXT:    ret
38   %base_load = getelementptr <vscale x 2 x i8>, <vscale x 2 x i8>* %base, i64 -8
39   %data = call <vscale x 2 x i8> @llvm.masked.load.nxv2i8(<vscale x 2 x i8>* %base_load,
40                                                           i32 1,
41                                                           <vscale x 2 x i1> %mask,
42                                                           <vscale x 2 x i8> undef)
43   %base_store = getelementptr <vscale x 2 x i8>, <vscale x 2 x i8> * %base, i64 -7
44   call void @llvm.masked.store.nxv2i8(<vscale x 2 x i8> %data,
45                                       <vscale x 2 x i8>* %base_store,
46                                       i32 1,
47                                       <vscale x 2 x i1> %mask)
48   ret void
51 define void @test_masked_ldst_sv2i16(<vscale x 2 x i16> * %base, <vscale x 2 x i1> %mask) nounwind {
52 ; CHECK-LABEL: test_masked_ldst_sv2i16:
53 ; CHECK:       // %bb.0:
54 ; CHECK-NEXT:    ld1h { z0.d }, p0/z, [x0, #-8, mul vl]
55 ; CHECK-NEXT:    st1h { z0.d }, p0, [x0, #-7, mul vl]
56 ; CHECK-NEXT:    ret
57   %base_load = getelementptr <vscale x 2 x i16>, <vscale x 2 x i16>* %base, i64 -8
58   %data = call <vscale x 2 x i16> @llvm.masked.load.nxv2i16(<vscale x 2 x i16>* %base_load,
59                                                             i32 1,
60                                                             <vscale x 2 x i1> %mask,
61                                                             <vscale x 2 x i16> undef)
62   %base_store = getelementptr <vscale x 2 x i16>, <vscale x 2 x i16> * %base, i64 -7
63   call void @llvm.masked.store.nxv2i16(<vscale x 2 x i16> %data,
64                                        <vscale x 2 x i16>* %base_store,
65                                        i32 1,
66                                        <vscale x 2 x i1> %mask)
67   ret void
71 define void @test_masked_ldst_sv2i32(<vscale x 2 x i32> * %base, <vscale x 2 x i1> %mask) nounwind {
72 ; CHECK-LABEL: test_masked_ldst_sv2i32:
73 ; CHECK:       // %bb.0:
74 ; CHECK-NEXT:    ld1w { z0.d }, p0/z, [x0, #-8, mul vl]
75 ; CHECK-NEXT:    st1w { z0.d }, p0, [x0, #-7, mul vl]
76 ; CHECK-NEXT:    ret
77   %base_load = getelementptr <vscale x 2 x i32>, <vscale x 2 x i32>* %base, i64 -8
78   %data = call <vscale x 2 x i32> @llvm.masked.load.nxv2i32(<vscale x 2 x i32>* %base_load,
79                                                             i32 1,
80                                                             <vscale x 2 x i1> %mask,
81                                                             <vscale x 2 x i32> undef)
82   %base_store = getelementptr <vscale x 2 x i32>, <vscale x 2 x i32> * %base, i64 -7
83   call void @llvm.masked.store.nxv2i32(<vscale x 2 x i32> %data,
84                                        <vscale x 2 x i32>* %base_store,
85                                        i32 1,
86                                        <vscale x 2 x i1> %mask)
87   ret void
90 define void @test_masked_ldst_sv2i64(<vscale x 2 x i64> * %base, <vscale x 2 x i1> %mask) nounwind {
91 ; CHECK-LABEL: test_masked_ldst_sv2i64:
92 ; CHECK:       // %bb.0:
93 ; CHECK-NEXT:    ld1d { z0.d }, p0/z, [x0, #-8, mul vl]
94 ; CHECK-NEXT:    st1d { z0.d }, p0, [x0, #-7, mul vl]
95 ; CHECK-NEXT:    ret
96   %base_load = getelementptr <vscale x 2 x i64>, <vscale x 2 x i64>* %base, i64 -8
97   %data = call <vscale x 2 x i64> @llvm.masked.load.nxv2i64(<vscale x 2 x i64>* %base_load,
98                                                             i32 1,
99                                                             <vscale x 2 x i1> %mask,
100                                                             <vscale x 2 x i64> undef)
101   %base_store = getelementptr <vscale x 2 x i64>, <vscale x 2 x i64> * %base, i64 -7
102   call void @llvm.masked.store.nxv2i64(<vscale x 2 x i64> %data,
103                                        <vscale x 2 x i64>* %base_store,
104                                        i32 1,
105                                        <vscale x 2 x i1> %mask)
106   ret void
109 define void @test_masked_ldst_sv2f16(<vscale x 2 x half> * %base, <vscale x 2 x i1> %mask) nounwind {
110 ; CHECK-LABEL: test_masked_ldst_sv2f16:
111 ; CHECK:       // %bb.0:
112 ; CHECK-NEXT:    ld1h { z0.d }, p0/z, [x0, #-8, mul vl]
113 ; CHECK-NEXT:    st1h { z0.d }, p0, [x0, #-7, mul vl]
114 ; CHECK-NEXT:    ret
115   %base_load = getelementptr <vscale x 2 x half>, <vscale x 2 x half>* %base, i64 -8
116   %data = call <vscale x 2 x half> @llvm.masked.load.nxv2f16(<vscale x 2 x half>* %base_load,
117                                                              i32 1,
118                                                              <vscale x 2 x i1> %mask,
119                                                              <vscale x 2 x half> undef)
120   %base_store = getelementptr <vscale x 2 x half>, <vscale x 2 x half> * %base, i64 -7
121   call void @llvm.masked.store.nxv2f16(<vscale x 2 x half> %data,
122                                        <vscale x 2 x half>* %base_store,
123                                        i32 1,
124                                        <vscale x 2 x i1> %mask)
125   ret void
129 define void @test_masked_ldst_sv2f32(<vscale x 2 x float> * %base, <vscale x 2 x i1> %mask) nounwind {
130 ; CHECK-LABEL: test_masked_ldst_sv2f32:
131 ; CHECK:       // %bb.0:
132 ; CHECK-NEXT:    ld1w { z0.d }, p0/z, [x0, #-8, mul vl]
133 ; CHECK-NEXT:    st1w { z0.d }, p0, [x0, #-7, mul vl]
134 ; CHECK-NEXT:    ret
135   %base_load = getelementptr <vscale x 2 x float>, <vscale x 2 x float>* %base, i64 -8
136   %data = call <vscale x 2 x float> @llvm.masked.load.nxv2f32(<vscale x 2 x float>* %base_load,
137                                                               i32 1,
138                                                               <vscale x 2 x i1> %mask,
139                                                               <vscale x 2 x float> undef)
140   %base_store = getelementptr <vscale x 2 x float>, <vscale x 2 x float> * %base, i64 -7
141   call void @llvm.masked.store.nxv2f32(<vscale x 2 x float> %data,
142                                        <vscale x 2 x float>* %base_store,
143                                        i32 1,
144                                        <vscale x 2 x i1> %mask)
145   ret void
148 define void @test_masked_ldst_sv2f64(<vscale x 2 x double> * %base, <vscale x 2 x i1> %mask) nounwind {
149 ; CHECK-LABEL: test_masked_ldst_sv2f64:
150 ; CHECK:       // %bb.0:
151 ; CHECK-NEXT:    ld1d { z0.d }, p0/z, [x0, #-6, mul vl]
152 ; CHECK-NEXT:    st1d { z0.d }, p0, [x0, #-5, mul vl]
153 ; CHECK-NEXT:    ret
154   %base_load = getelementptr <vscale x 2 x double>, <vscale x 2 x double>* %base, i64 -6
155   %data = call <vscale x 2 x double> @llvm.masked.load.nxv2f64(<vscale x 2 x double>* %base_load,
156                                                                i32 1,
157                                                                <vscale x 2 x i1> %mask,
158                                                                <vscale x 2 x double> undef)
159   %base_store = getelementptr <vscale x 2 x double>, <vscale x 2 x double> * %base, i64 -5
160   call void @llvm.masked.store.nxv2f64(<vscale x 2 x double> %data,
161                                        <vscale x 2 x double>* %base_store,
162                                        i32 1,
163                                        <vscale x 2 x i1> %mask)
164   ret void
167 ; 2-lane zero/sign extended contiguous loads.
169 define <vscale x 2 x i64> @masked_zload_sv2i8_to_sv2i64(<vscale x 2 x i8>* %base, <vscale x 2 x i1> %mask) nounwind {
170 ; CHECK-LABEL: masked_zload_sv2i8_to_sv2i64:
171 ; CHECK:       // %bb.0:
172 ; CHECK-NEXT:    ld1b { z0.d }, p0/z, [x0, #-4, mul vl]
173 ; CHECK-NEXT:    ret
174   %base_load = getelementptr <vscale x 2 x i8>, <vscale x 2 x i8>* %base, i64 -4
175   %load = call <vscale x 2 x i8> @llvm.masked.load.nxv2i8(<vscale x 2 x i8>* %base_load,
176                                                           i32 1,
177                                                           <vscale x 2 x i1> %mask,
178                                                           <vscale x 2 x i8> undef)
179   %ext = zext <vscale x 2 x i8> %load to <vscale x 2 x i64>
180   ret <vscale x 2 x i64> %ext
183 define <vscale x 2 x i64> @masked_sload_sv2i8_to_sv2i64(<vscale x 2 x i8>* %base, <vscale x 2 x i1> %mask) nounwind {
184 ; CHECK-LABEL: masked_sload_sv2i8_to_sv2i64:
185 ; CHECK:       // %bb.0:
186 ; CHECK-NEXT:    ld1sb { z0.d }, p0/z, [x0, #-3, mul vl]
187 ; CHECK-NEXT:    ret
188   %base_load = getelementptr <vscale x 2 x i8>, <vscale x 2 x i8>* %base, i64 -3
189   %load = call <vscale x 2 x i8> @llvm.masked.load.nxv2i8(<vscale x 2 x i8>* %base_load,
190                                                           i32 1,
191                                                           <vscale x 2 x i1> %mask,
192                                                           <vscale x 2 x i8> undef)
193   %ext = sext <vscale x 2 x i8> %load to <vscale x 2 x i64>
194   ret <vscale x 2 x i64> %ext
197 define <vscale x 2 x i64> @masked_zload_sv2i16_to_sv2i64(<vscale x 2 x i16>* %base, <vscale x 2 x i1> %mask) nounwind {
198 ; CHECK-LABEL: masked_zload_sv2i16_to_sv2i64:
199 ; CHECK:       // %bb.0:
200 ; CHECK-NEXT:    ld1h { z0.d }, p0/z, [x0, #1, mul vl]
201 ; CHECK-NEXT:    ret
202   %base_load = getelementptr <vscale x 2 x i16>, <vscale x 2 x i16>* %base, i64 1
203   %load = call <vscale x 2 x i16> @llvm.masked.load.nxv2i16(<vscale x 2 x i16>* %base_load,
204                                                             i32 1,
205                                                             <vscale x 2 x i1> %mask,
206                                                             <vscale x 2 x i16> undef)
207   %ext = zext <vscale x 2 x i16> %load to <vscale x 2 x i64>
208   ret <vscale x 2 x i64> %ext
211 define <vscale x 2 x i64> @masked_sload_sv2i16_to_sv2i64(<vscale x 2 x i16>* %base, <vscale x 2 x i1> %mask) nounwind {
212 ; CHECK-LABEL: masked_sload_sv2i16_to_sv2i64:
213 ; CHECK:       // %bb.0:
214 ; CHECK-NEXT:    ld1sh { z0.d }, p0/z, [x0, #2, mul vl]
215 ; CHECK-NEXT:    ret
216   %base_load = getelementptr <vscale x 2 x i16>, <vscale x 2 x i16>* %base, i64 2
217   %load = call <vscale x 2 x i16> @llvm.masked.load.nxv2i16(<vscale x 2 x i16>* %base_load,
218                                                             i32 1,
219                                                             <vscale x 2 x i1> %mask,
220                                                             <vscale x 2 x i16> undef)
221   %ext = sext <vscale x 2 x i16> %load to <vscale x 2 x i64>
222   ret <vscale x 2 x i64> %ext
225 define <vscale x 2 x i64> @masked_zload_sv2i32_to_sv2i64(<vscale x 2 x i32>* %base, <vscale x 2 x i1> %mask) nounwind {
226 ; CHECK-LABEL: masked_zload_sv2i32_to_sv2i64:
227 ; CHECK:       // %bb.0:
228 ; CHECK-NEXT:    ld1w { z0.d }, p0/z, [x0, #-2, mul vl]
229 ; CHECK-NEXT:    ret
230   %base_load = getelementptr <vscale x 2 x i32>, <vscale x 2 x i32>* %base, i64 -2
231   %load = call <vscale x 2 x i32> @llvm.masked.load.nxv2i32(<vscale x 2 x i32>* %base_load,
232                                                             i32 1,
233                                                             <vscale x 2 x i1> %mask,
234                                                             <vscale x 2 x i32> undef)
235   %ext = zext <vscale x 2 x i32> %load to <vscale x 2 x i64>
236   ret <vscale x 2 x i64> %ext
239 define <vscale x 2 x i64> @masked_sload_sv2i32_to_sv2i64(<vscale x 2 x i32>* %base, <vscale x 2 x i1> %mask) nounwind {
240 ; CHECK-LABEL: masked_sload_sv2i32_to_sv2i64:
241 ; CHECK:       // %bb.0:
242 ; CHECK-NEXT:    ld1sw { z0.d }, p0/z, [x0, #-1, mul vl]
243 ; CHECK-NEXT:    ret
244   %base_load = getelementptr <vscale x 2 x i32>, <vscale x 2 x i32>* %base, i64 -1
245   %load = call <vscale x 2 x i32> @llvm.masked.load.nxv2i32(<vscale x 2 x i32>* %base_load,
246                                                             i32 1,
247                                                             <vscale x 2 x i1> %mask,
248                                                             <vscale x 2 x i32> undef)
249   %ext = sext <vscale x 2 x i32> %load to <vscale x 2 x i64>
250   ret <vscale x 2 x i64> %ext
253 ; 2-lane truncating contiguous stores.
255 define void @masked_trunc_store_sv2i64_to_sv2i8(<vscale x 2 x i64> %val, <vscale x 2 x i8> *%base, <vscale x 2 x i1> %mask) nounwind {
256 ; CHECK-LABEL: masked_trunc_store_sv2i64_to_sv2i8:
257 ; CHECK:       // %bb.0:
258 ; CHECK-NEXT:    st1b { z0.d }, p0, [x0, #3, mul vl]
259 ; CHECK-NEXT:    ret
260   %base_load = getelementptr <vscale x 2 x i8>, <vscale x 2 x i8>* %base, i64 3
261   %trunc = trunc <vscale x 2 x i64> %val to <vscale x 2 x i8>
262   call void @llvm.masked.store.nxv2i8(<vscale x 2 x i8> %trunc,
263                                       <vscale x 2 x i8> *%base_load,
264                                       i32 1,
265                                       <vscale x 2 x i1> %mask)
266   ret void
270 define void @masked_trunc_store_sv2i64_to_sv2i16(<vscale x 2 x i64> %val, <vscale x 2 x i16> *%base, <vscale x 2 x i1> %mask) nounwind {
271 ; CHECK-LABEL: masked_trunc_store_sv2i64_to_sv2i16:
272 ; CHECK:       // %bb.0:
273 ; CHECK-NEXT:    st1h { z0.d }, p0, [x0, #4, mul vl]
274 ; CHECK-NEXT:    ret
275   %base_load = getelementptr <vscale x 2 x i16>, <vscale x 2 x i16>* %base, i64 4
276   %trunc = trunc <vscale x 2 x i64> %val to <vscale x 2 x i16>
277   call void @llvm.masked.store.nxv2i16(<vscale x 2 x i16> %trunc,
278                                        <vscale x 2 x i16> *%base_load,
279                                        i32 1,
280                                        <vscale x 2 x i1> %mask)
281   ret void
284 define void @masked_trunc_store_sv2i64_to_sv2i32(<vscale x 2 x i64> %val, <vscale x 2 x i32> *%base, <vscale x 2 x i1> %mask) nounwind {
285 ; CHECK-LABEL: masked_trunc_store_sv2i64_to_sv2i32:
286 ; CHECK:       // %bb.0:
287 ; CHECK-NEXT:    st1w { z0.d }, p0, [x0, #5, mul vl]
288 ; CHECK-NEXT:    ret
289   %base_load = getelementptr <vscale x 2 x i32>, <vscale x 2 x i32>* %base, i64 5
290   %trunc = trunc <vscale x 2 x i64> %val to <vscale x 2 x i32>
291   call void @llvm.masked.store.nxv2i32(<vscale x 2 x i32> %trunc,
292                                        <vscale x 2 x i32> *%base_load,
293                                        i32 1,
294                                        <vscale x 2 x i1> %mask)
295   ret void
298 ; 4-lane contiguous load/stores.
300 define void @test_masked_ldst_sv4i8(<vscale x 4 x i8> * %base, <vscale x 4 x i1> %mask) nounwind {
301 ; CHECK-LABEL: test_masked_ldst_sv4i8:
302 ; CHECK:       // %bb.0:
303 ; CHECK-NEXT:    ld1b { z0.s }, p0/z, [x0, #-1, mul vl]
304 ; CHECK-NEXT:    st1b { z0.s }, p0, [x0, #2, mul vl]
305 ; CHECK-NEXT:    ret
306   %base_load = getelementptr <vscale x 4 x i8>, <vscale x 4 x i8>* %base, i64 -1
307   %data = call <vscale x 4 x i8> @llvm.masked.load.nxv4i8(<vscale x 4 x i8>* %base_load,
308                                                           i32 1,
309                                                           <vscale x 4 x i1> %mask,
310                                                           <vscale x 4 x i8> undef)
311   %base_store = getelementptr <vscale x 4 x i8>, <vscale x 4 x i8> * %base, i64 2
312   call void @llvm.masked.store.nxv4i8(<vscale x 4 x i8> %data,
313                                       <vscale x 4 x i8>* %base_store,
314                                       i32 1,
315                                       <vscale x 4 x i1> %mask)
316   ret void
319 define void @test_masked_ldst_sv4i16(<vscale x 4 x i16> * %base, <vscale x 4 x i1> %mask) nounwind {
320 ; CHECK-LABEL: test_masked_ldst_sv4i16:
321 ; CHECK:       // %bb.0:
322 ; CHECK-NEXT:    ld1h { z0.s }, p0/z, [x0, #-1, mul vl]
323 ; CHECK-NEXT:    st1h { z0.s }, p0, [x0, #2, mul vl]
324 ; CHECK-NEXT:    ret
325   %base_load = getelementptr <vscale x 4 x i16>, <vscale x 4 x i16>* %base, i64 -1
326   %data = call <vscale x 4 x i16> @llvm.masked.load.nxv4i16(<vscale x 4 x i16>* %base_load,
327                                                             i32 1,
328                                                             <vscale x 4 x i1> %mask,
329                                                             <vscale x 4 x i16> undef)
330   %base_store = getelementptr <vscale x 4 x i16>, <vscale x 4 x i16> * %base, i64 2
331   call void @llvm.masked.store.nxv4i16(<vscale x 4 x i16> %data,
332                                        <vscale x 4 x i16>* %base_store,
333                                        i32 1,
334                                        <vscale x 4 x i1> %mask)
335   ret void
338 define void @test_masked_ldst_sv4i32(<vscale x 4 x i32> * %base, <vscale x 4 x i1> %mask) nounwind {
339 ; CHECK-LABEL: test_masked_ldst_sv4i32:
340 ; CHECK:       // %bb.0:
341 ; CHECK-NEXT:    ld1w { z0.s }, p0/z, [x0, #6, mul vl]
342 ; CHECK-NEXT:    st1w { z0.s }, p0, [x0, #7, mul vl]
343 ; CHECK-NEXT:    ret
344   %base_load = getelementptr <vscale x 4 x i32>, <vscale x 4 x i32>* %base, i64 6
345   %data = call <vscale x 4 x i32> @llvm.masked.load.nxv4i32(<vscale x 4 x i32>* %base_load,
346                                                             i32 1,
347                                                             <vscale x 4 x i1> %mask,
348                                                             <vscale x 4 x i32> undef)
349   %base_store = getelementptr <vscale x 4 x i32>, <vscale x 4 x i32> * %base, i64 7
350   call void @llvm.masked.store.nxv4i32(<vscale x 4 x i32> %data,
351                                        <vscale x 4 x i32>* %base_store,
352                                        i32 1,
353                                        <vscale x 4 x i1> %mask)
354   ret void
357 define void @test_masked_ldst_sv4f16(<vscale x 4 x half> * %base, <vscale x 4 x i1> %mask) nounwind {
358 ; CHECK-LABEL: test_masked_ldst_sv4f16:
359 ; CHECK:       // %bb.0:
360 ; CHECK-NEXT:    ld1h { z0.s }, p0/z, [x0, #-1, mul vl]
361 ; CHECK-NEXT:    st1h { z0.s }, p0, [x0, #2, mul vl]
362 ; CHECK-NEXT:    ret
363   %base_load = getelementptr <vscale x 4 x half>, <vscale x 4 x half>* %base, i64 -1
364   %data = call <vscale x 4 x half> @llvm.masked.load.nxv4f16(<vscale x 4 x half>* %base_load,
365                                                              i32 1,
366                                                              <vscale x 4 x i1> %mask,
367                                                              <vscale x 4 x half> undef)
368   %base_store = getelementptr <vscale x 4 x half>, <vscale x 4 x half> * %base, i64 2
369   call void @llvm.masked.store.nxv4f16(<vscale x 4 x half> %data,
370                                        <vscale x 4 x half>* %base_store,
371                                        i32 1,
372                                        <vscale x 4 x i1> %mask)
373   ret void
376 define void @test_masked_ldst_sv4f32(<vscale x 4 x float> * %base, <vscale x 4 x i1> %mask) nounwind {
377 ; CHECK-LABEL: test_masked_ldst_sv4f32:
378 ; CHECK:       // %bb.0:
379 ; CHECK-NEXT:    ld1w { z0.s }, p0/z, [x0, #-1, mul vl]
380 ; CHECK-NEXT:    st1w { z0.s }, p0, [x0, #2, mul vl]
381 ; CHECK-NEXT:    ret
382   %base_load = getelementptr <vscale x 4 x float>, <vscale x 4 x float>* %base, i64 -1
383   %data = call <vscale x 4 x float> @llvm.masked.load.nxv4f32(<vscale x 4 x float>* %base_load,
384                                                               i32 1,
385                                                               <vscale x 4 x i1> %mask,
386                                                               <vscale x 4 x float> undef)
387   %base_store = getelementptr <vscale x 4 x float>, <vscale x 4 x float> * %base, i64 2
388   call void @llvm.masked.store.nxv4f32(<vscale x 4 x float> %data,
389                                        <vscale x 4 x float>* %base_store,
390                                        i32 1,
391                                        <vscale x 4 x i1> %mask)
392   ret void
395 ; 4-lane zero/sign extended contiguous loads.
397 define <vscale x 4 x i32> @masked_zload_sv4i8_to_sv4i32(<vscale x 4 x i8>* %base, <vscale x 4 x i1> %mask) nounwind {
398 ; CHECK-LABEL: masked_zload_sv4i8_to_sv4i32:
399 ; CHECK:       // %bb.0:
400 ; CHECK-NEXT:    ld1b { z0.s }, p0/z, [x0, #-4, mul vl]
401 ; CHECK-NEXT:    ret
402   %base_load = getelementptr <vscale x 4 x i8>, <vscale x 4 x i8>* %base, i64 -4
403   %load = call <vscale x 4 x i8> @llvm.masked.load.nxv4i8(<vscale x 4 x i8>* %base_load,
404                                                           i32 1,
405                                                           <vscale x 4 x i1> %mask,
406                                                           <vscale x 4 x i8> undef)
407   %ext = zext <vscale x 4 x i8> %load to <vscale x 4 x i32>
408   ret <vscale x 4 x i32> %ext
411 define <vscale x 4 x i32> @masked_sload_sv4i8_to_sv4i32(<vscale x 4 x i8>* %base, <vscale x 4 x i1> %mask) nounwind {
412 ; CHECK-LABEL: masked_sload_sv4i8_to_sv4i32:
413 ; CHECK:       // %bb.0:
414 ; CHECK-NEXT:    ld1sb { z0.s }, p0/z, [x0, #-3, mul vl]
415 ; CHECK-NEXT:    ret
416   %base_load = getelementptr <vscale x 4 x i8>, <vscale x 4 x i8>* %base, i64 -3
417   %load = call <vscale x 4 x i8> @llvm.masked.load.nxv4i8(<vscale x 4 x i8>* %base_load,
418                                                           i32 1,
419                                                           <vscale x 4 x i1> %mask,
420                                                           <vscale x 4 x i8> undef)
421   %ext = sext <vscale x 4 x i8> %load to <vscale x 4 x i32>
422   ret <vscale x 4 x i32> %ext
425 define <vscale x 4 x i32> @masked_zload_sv4i16_to_sv4i32(<vscale x 4 x i16>* %base, <vscale x 4 x i1> %mask) nounwind {
426 ; CHECK-LABEL: masked_zload_sv4i16_to_sv4i32:
427 ; CHECK:       // %bb.0:
428 ; CHECK-NEXT:    ld1h { z0.s }, p0/z, [x0, #1, mul vl]
429 ; CHECK-NEXT:    ret
430   %base_load = getelementptr <vscale x 4 x i16>, <vscale x 4 x i16>* %base, i64 1
431   %load = call <vscale x 4 x i16> @llvm.masked.load.nxv4i16(<vscale x 4 x i16>* %base_load,
432                                                             i32 1,
433                                                             <vscale x 4 x i1> %mask,
434                                                             <vscale x 4 x i16> undef)
435   %ext = zext <vscale x 4 x i16> %load to <vscale x 4 x i32>
436   ret <vscale x 4 x i32> %ext
439 define <vscale x 4 x i32> @masked_sload_sv4i16_to_sv4i32(<vscale x 4 x i16>* %base, <vscale x 4 x i1> %mask) nounwind {
440 ; CHECK-LABEL: masked_sload_sv4i16_to_sv4i32:
441 ; CHECK:       // %bb.0:
442 ; CHECK-NEXT:    ld1sh { z0.s }, p0/z, [x0, #2, mul vl]
443 ; CHECK-NEXT:    ret
444   %base_load = getelementptr <vscale x 4 x i16>, <vscale x 4 x i16>* %base, i64 2
445   %load = call <vscale x 4 x i16> @llvm.masked.load.nxv4i16(<vscale x 4 x i16>* %base_load,
446                                                             i32 1,
447                                                             <vscale x 4 x i1> %mask,
448                                                             <vscale x 4 x i16> undef)
449   %ext = sext <vscale x 4 x i16> %load to <vscale x 4 x i32>
450   ret <vscale x 4 x i32> %ext
453 ; 4-lane truncating contiguous stores.
455 define void @masked_trunc_store_sv4i32_to_sv4i8(<vscale x 4 x i32> %val, <vscale x 4 x i8> *%base, <vscale x 4 x i1> %mask) nounwind {
456 ; CHECK-LABEL: masked_trunc_store_sv4i32_to_sv4i8:
457 ; CHECK:       // %bb.0:
458 ; CHECK-NEXT:    st1b { z0.s }, p0, [x0, #3, mul vl]
459 ; CHECK-NEXT:    ret
460   %base_load = getelementptr <vscale x 4 x i8>, <vscale x 4 x i8>* %base, i64 3
461   %trunc = trunc <vscale x 4 x i32> %val to <vscale x 4 x i8>
462   call void @llvm.masked.store.nxv4i8(<vscale x 4 x i8> %trunc,
463                                       <vscale x 4 x i8> *%base_load,
464                                       i32 1,
465                                       <vscale x 4 x i1> %mask)
466   ret void
470 define void @masked_trunc_store_sv4i32_to_sv4i16(<vscale x 4 x i32> %val, <vscale x 4 x i16> *%base, <vscale x 4 x i1> %mask) nounwind {
471 ; CHECK-LABEL: masked_trunc_store_sv4i32_to_sv4i16:
472 ; CHECK:       // %bb.0:
473 ; CHECK-NEXT:    st1h { z0.s }, p0, [x0, #4, mul vl]
474 ; CHECK-NEXT:    ret
475   %base_load = getelementptr <vscale x 4 x i16>, <vscale x 4 x i16>* %base, i64 4
476   %trunc = trunc <vscale x 4 x i32> %val to <vscale x 4 x i16>
477   call void @llvm.masked.store.nxv4i16(<vscale x 4 x i16> %trunc,
478                                        <vscale x 4 x i16> *%base_load,
479                                        i32 1,
480                                        <vscale x 4 x i1> %mask)
481   ret void
484 ; 8-lane contiguous load/stores.
486 define void @test_masked_ldst_sv8i8(<vscale x 8 x i8> * %base, <vscale x 8 x i1> %mask) nounwind {
487 ; CHECK-LABEL: test_masked_ldst_sv8i8:
488 ; CHECK:       // %bb.0:
489 ; CHECK-NEXT:    ld1b { z0.h }, p0/z, [x0, #6, mul vl]
490 ; CHECK-NEXT:    st1b { z0.h }, p0, [x0, #7, mul vl]
491 ; CHECK-NEXT:    ret
492   %base_load = getelementptr <vscale x 8 x i8>, <vscale x 8 x i8>* %base, i64 6
493   %data = call <vscale x 8 x i8> @llvm.masked.load.nxv8i8(<vscale x 8 x i8>* %base_load,
494                                                           i32 1,
495                                                           <vscale x 8 x i1> %mask,
496                                                           <vscale x 8 x i8> undef)
497   %base_store = getelementptr <vscale x 8 x i8>, <vscale x 8 x i8> * %base, i64 7
498   call void @llvm.masked.store.nxv8i8(<vscale x 8 x i8> %data,
499                                       <vscale x 8 x i8>* %base_store,
500                                       i32 1,
501                                       <vscale x 8 x i1> %mask)
502   ret void
505 define void @test_masked_ldst_sv8i16(<vscale x 8 x i16> * %base, <vscale x 8 x i1> %mask) nounwind {
506 ; CHECK-LABEL: test_masked_ldst_sv8i16:
507 ; CHECK:       // %bb.0:
508 ; CHECK-NEXT:    ld1h { z0.h }, p0/z, [x0, #6, mul vl]
509 ; CHECK-NEXT:    st1h { z0.h }, p0, [x0, #7, mul vl]
510 ; CHECK-NEXT:    ret
511   %base_load = getelementptr <vscale x 8 x i16>, <vscale x 8 x i16>* %base, i64 6
512   %data = call <vscale x 8 x i16> @llvm.masked.load.nxv8i16(<vscale x 8 x i16>* %base_load,
513                                                             i32 1,
514                                                             <vscale x 8 x i1> %mask,
515                                                             <vscale x 8 x i16> undef)
516   %base_store = getelementptr <vscale x 8 x i16>, <vscale x 8 x i16> * %base, i64 7
517   call void @llvm.masked.store.nxv8i16(<vscale x 8 x i16> %data,
518                                        <vscale x 8 x i16>* %base_store,
519                                        i32 1,
520                                        <vscale x 8 x i1> %mask)
521   ret void
524 define void @test_masked_ldst_sv8f16(<vscale x 8 x half> * %base, <vscale x 8 x i1> %mask) nounwind {
525 ; CHECK-LABEL: test_masked_ldst_sv8f16:
526 ; CHECK:       // %bb.0:
527 ; CHECK-NEXT:    ld1h { z0.h }, p0/z, [x0, #-1, mul vl]
528 ; CHECK-NEXT:    st1h { z0.h }, p0, [x0, #2, mul vl]
529 ; CHECK-NEXT:    ret
530   %base_load = getelementptr <vscale x 8 x half>, <vscale x 8 x half>* %base, i64 -1
531   %data = call <vscale x 8 x half> @llvm.masked.load.nxv8f16(<vscale x 8 x half>* %base_load,
532                                                              i32 1,
533                                                              <vscale x 8 x i1> %mask,
534                                                              <vscale x 8 x half> undef)
535   %base_store = getelementptr <vscale x 8 x half>, <vscale x 8 x half> * %base, i64 2
536   call void @llvm.masked.store.nxv8f16(<vscale x 8 x half> %data,
537                                        <vscale x 8 x half>* %base_store,
538                                        i32 1,
539                                        <vscale x 8 x i1> %mask)
540   ret void
543 define void @test_masked_ldst_sv8bf16(<vscale x 8 x bfloat> * %base, <vscale x 8 x i1> %mask) nounwind #0 {
544 ; CHECK-LABEL: test_masked_ldst_sv8bf16:
545 ; CHECK:       // %bb.0:
546 ; CHECK-NEXT:    ld1h { z0.h }, p0/z, [x0, #-1, mul vl]
547 ; CHECK-NEXT:    st1h { z0.h }, p0, [x0, #2, mul vl]
548 ; CHECK-NEXT:    ret
549   %base_load = getelementptr <vscale x 8 x bfloat>, <vscale x 8 x bfloat>* %base, i64 -1
550   %data = call <vscale x 8 x bfloat> @llvm.masked.load.nxv8bf16(<vscale x 8 x bfloat>* %base_load,
551                                                                 i32 1,
552                                                                 <vscale x 8 x i1> %mask,
553                                                                 <vscale x 8 x bfloat> undef)
554   %base_store = getelementptr <vscale x 8 x bfloat>, <vscale x 8 x bfloat> * %base, i64 2
555   call void @llvm.masked.store.nxv8bf16(<vscale x 8 x bfloat> %data,
556                                         <vscale x 8 x bfloat>* %base_store,
557                                         i32 1,
558                                         <vscale x 8 x i1> %mask)
559   ret void
562 ; 8-lane zero/sign extended contiguous loads.
564 define <vscale x 8 x i16> @masked_zload_sv8i8_to_sv8i16(<vscale x 8 x i8>* %base, <vscale x 8 x i1> %mask) nounwind {
565 ; CHECK-LABEL: masked_zload_sv8i8_to_sv8i16:
566 ; CHECK:       // %bb.0:
567 ; CHECK-NEXT:    ld1b { z0.h }, p0/z, [x0, #-4, mul vl]
568 ; CHECK-NEXT:    ret
569   %base_load = getelementptr <vscale x 8 x i8>, <vscale x 8 x i8>* %base, i64 -4
570   %load = call <vscale x 8 x i8> @llvm.masked.load.nxv8i8(<vscale x 8 x i8>* %base_load,
571                                                           i32 1,
572                                                           <vscale x 8 x i1> %mask,
573                                                           <vscale x 8 x i8> undef)
574   %ext = zext <vscale x 8 x i8> %load to <vscale x 8 x i16>
575   ret <vscale x 8 x i16> %ext
578 define <vscale x 8 x i16> @masked_sload_sv8i8_to_sv8i16(<vscale x 8 x i8>* %base, <vscale x 8 x i1> %mask) nounwind {
579 ; CHECK-LABEL: masked_sload_sv8i8_to_sv8i16:
580 ; CHECK:       // %bb.0:
581 ; CHECK-NEXT:    ld1sb { z0.h }, p0/z, [x0, #-3, mul vl]
582 ; CHECK-NEXT:    ret
583   %base_load = getelementptr <vscale x 8 x i8>, <vscale x 8 x i8>* %base, i64 -3
584   %load = call <vscale x 8 x i8> @llvm.masked.load.nxv8i8(<vscale x 8 x i8>* %base_load,
585                                                           i32 1,
586                                                           <vscale x 8 x i1> %mask,
587                                                           <vscale x 8 x i8> undef)
588   %ext = sext <vscale x 8 x i8> %load to <vscale x 8 x i16>
589   ret <vscale x 8 x i16> %ext
592 ; 8-lane truncating contiguous stores.
594 define void @masked_trunc_store_sv8i16_to_sv8i8(<vscale x 8 x i16> %val, <vscale x 8 x i8> *%base, <vscale x 8 x i1> %mask) nounwind {
595 ; CHECK-LABEL: masked_trunc_store_sv8i16_to_sv8i8:
596 ; CHECK:       // %bb.0:
597 ; CHECK-NEXT:    st1b { z0.h }, p0, [x0, #3, mul vl]
598 ; CHECK-NEXT:    ret
599   %base_load = getelementptr <vscale x 8 x i8>, <vscale x 8 x i8>* %base, i64 3
600   %trunc = trunc <vscale x 8 x i16> %val to <vscale x 8 x i8>
601   call void @llvm.masked.store.nxv8i8(<vscale x 8 x i8> %trunc,
602                                       <vscale x 8 x i8> *%base_load,
603                                       i32 1,
604                                       <vscale x 8 x i1> %mask)
605   ret void
608 ; 16-lane contiguous load/stores.
610 define void @test_masked_ldst_sv16i8(<vscale x 16 x i8> * %base, <vscale x 16 x i1> %mask) nounwind {
611 ; CHECK-LABEL: test_masked_ldst_sv16i8:
612 ; CHECK:       // %bb.0:
613 ; CHECK-NEXT:    ld1b { z0.b }, p0/z, [x0, #6, mul vl]
614 ; CHECK-NEXT:    st1b { z0.b }, p0, [x0, #7, mul vl]
615 ; CHECK-NEXT:    ret
616   %base_load = getelementptr <vscale x 16 x i8>, <vscale x 16 x i8>* %base, i64 6
617   %data = call <vscale x 16 x i8> @llvm.masked.load.nxv16i8(<vscale x 16 x i8>* %base_load,
618                                                             i32 1,
619                                                             <vscale x 16 x i1> %mask,
620                                                             <vscale x 16 x i8> undef)
621   %base_store = getelementptr <vscale x 16 x i8>, <vscale x 16 x i8> * %base, i64 7
622   call void @llvm.masked.store.nxv16i8(<vscale x 16 x i8> %data,
623                                        <vscale x 16 x i8>* %base_store,
624                                        i32 1,
625                                        <vscale x 16 x i1> %mask)
626   ret void
629 ; 2-element contiguous loads.
630 declare <vscale x 2 x i8>  @llvm.masked.load.nxv2i8 (<vscale x 2 x i8>* , i32, <vscale x 2 x i1>, <vscale x 2 x i8> )
631 declare <vscale x 2 x i16> @llvm.masked.load.nxv2i16(<vscale x 2 x i16>*, i32, <vscale x 2 x i1>, <vscale x 2 x i16>)
632 declare <vscale x 2 x i32> @llvm.masked.load.nxv2i32(<vscale x 2 x i32>*, i32, <vscale x 2 x i1>, <vscale x 2 x i32>)
633 declare <vscale x 2 x i64> @llvm.masked.load.nxv2i64(<vscale x 2 x i64>*, i32, <vscale x 2 x i1>, <vscale x 2 x i64>)
634 declare <vscale x 2 x half> @llvm.masked.load.nxv2f16(<vscale x 2 x half>*, i32, <vscale x 2 x i1>, <vscale x 2 x half>)
635 declare <vscale x 2 x float> @llvm.masked.load.nxv2f32(<vscale x 2 x float>*, i32, <vscale x 2 x i1>, <vscale x 2 x float>)
636 declare <vscale x 2 x double> @llvm.masked.load.nxv2f64(<vscale x 2 x double>*, i32, <vscale x 2 x i1>, <vscale x 2 x double>)
638 ; 4-element contiguous loads.
639 declare <vscale x 4 x i8>  @llvm.masked.load.nxv4i8 (<vscale x 4 x i8>* , i32, <vscale x 4 x i1>, <vscale x 4 x i8> )
640 declare <vscale x 4 x i16> @llvm.masked.load.nxv4i16(<vscale x 4 x i16>*, i32, <vscale x 4 x i1>, <vscale x 4 x i16>)
641 declare <vscale x 4 x i32> @llvm.masked.load.nxv4i32(<vscale x 4 x i32>*, i32, <vscale x 4 x i1>, <vscale x 4 x i32>)
642 declare <vscale x 4 x half> @llvm.masked.load.nxv4f16(<vscale x 4 x half>*, i32, <vscale x 4 x i1>, <vscale x 4 x half>)
643 declare <vscale x 4 x float> @llvm.masked.load.nxv4f32(<vscale x 4 x float>*, i32, <vscale x 4 x i1>, <vscale x 4 x float>)
645 ; 8-element contiguous loads.
646 declare <vscale x 8 x i8>  @llvm.masked.load.nxv8i8 (<vscale x 8 x i8>* , i32, <vscale x 8 x i1>, <vscale x 8 x i8> )
647 declare <vscale x 8 x i16> @llvm.masked.load.nxv8i16(<vscale x 8 x i16>*, i32, <vscale x 8 x i1>, <vscale x 8 x i16>)
648 declare <vscale x 8 x half> @llvm.masked.load.nxv8f16(<vscale x 8 x half>*, i32, <vscale x 8 x i1>, <vscale x 8 x half>)
649 declare <vscale x 8 x bfloat> @llvm.masked.load.nxv8bf16(<vscale x 8 x bfloat>*, i32, <vscale x 8 x i1>, <vscale x 8 x bfloat>)
651 ; 16-element contiguous loads.
652 declare <vscale x 16 x i8> @llvm.masked.load.nxv16i8(<vscale x 16 x i8>*, i32, <vscale x 16 x i1>, <vscale x 16 x i8>)
654 ; 2-element contiguous stores.
655 declare void @llvm.masked.store.nxv2i8 (<vscale x 2 x i8> , <vscale x 2 x i8>* , i32, <vscale x 2 x i1>)
656 declare void @llvm.masked.store.nxv2i16(<vscale x 2 x i16>, <vscale x 2 x i16>*, i32, <vscale x 2 x i1>)
657 declare void @llvm.masked.store.nxv2i32(<vscale x 2 x i32>, <vscale x 2 x i32>*, i32, <vscale x 2 x i1>)
658 declare void @llvm.masked.store.nxv2i64(<vscale x 2 x i64>, <vscale x 2 x i64>*, i32, <vscale x 2 x i1>)
659 declare void @llvm.masked.store.nxv2f16(<vscale x 2 x half>, <vscale x 2 x half>*, i32, <vscale x 2 x i1>)
660 declare void @llvm.masked.store.nxv2f32(<vscale x 2 x float>, <vscale x 2 x float>*, i32, <vscale x 2 x i1>)
661 declare void @llvm.masked.store.nxv2f64(<vscale x 2 x double>, <vscale x 2 x double>*, i32, <vscale x 2 x i1>)
663 ; 4-element contiguous stores.
664 declare void @llvm.masked.store.nxv4i8 (<vscale x 4 x i8> , <vscale x 4 x i8>* , i32, <vscale x 4 x i1>)
665 declare void @llvm.masked.store.nxv4i16(<vscale x 4 x i16>, <vscale x 4 x i16>*, i32, <vscale x 4 x i1>)
666 declare void @llvm.masked.store.nxv4i32(<vscale x 4 x i32>, <vscale x 4 x i32>*, i32, <vscale x 4 x i1>)
667 declare void @llvm.masked.store.nxv4f16(<vscale x 4 x half>, <vscale x 4 x half>*, i32, <vscale x 4 x i1>)
668 declare void @llvm.masked.store.nxv4f32(<vscale x 4 x float>, <vscale x 4 x float>*, i32, <vscale x 4 x i1>)
670 ; 8-element contiguous stores.
671 declare void @llvm.masked.store.nxv8i8 (<vscale x 8 x i8> , <vscale x 8 x i8>* , i32, <vscale x 8 x i1>)
672 declare void @llvm.masked.store.nxv8i16(<vscale x 8 x i16>, <vscale x 8 x i16>*, i32, <vscale x 8 x i1>)
673 declare void @llvm.masked.store.nxv8f16(<vscale x 8 x half>, <vscale x 8 x half>*, i32, <vscale x 8 x i1>)
674 declare void @llvm.masked.store.nxv8bf16(<vscale x 8 x bfloat>, <vscale x 8 x bfloat>*, i32, <vscale x 8 x i1>)
676 ; 16-element contiguous stores.
677 declare void @llvm.masked.store.nxv16i8(<vscale x 16 x i8>, <vscale x 16 x i8>*, i32, <vscale x 16 x i1>)
679 ; +bf16 is required for the bfloat version.
680 attributes #0 = { "target-features"="+sve,+bf16" }