[ORC] Add std::tuple support to SimplePackedSerialization.
[llvm-project.git] / llvm / test / CodeGen / AArch64 / sve-intrinsics-ldN-reg+imm-addr-mode.ll
blob1ffa78ec27352ecae28312f025eb5fffd0d075e0
1 ; RUN: llc -mtriple=aarch64--linux-gnu -mattr=sve < %s | FileCheck %s
3 ; NOTE: invalid, upper and lower bound immediate values of the regimm
4 ; addressing mode are checked only for the byte version of each
5 ; instruction (`ld<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 structure store, which is <N> = 2, 3, 4.
9 ; ld2b
10 define <vscale x 32 x i8> @ld2.nxv32i8(<vscale x 16 x i1> %Pg, <vscale x 16 x i8> *%addr) {
11 ; CHECK-LABEL: ld2.nxv32i8:
12 ; CHECK: ld2b { z0.b, z1.b }, p0/z, [x0, #2, mul vl]
13 ; CHECK-NEXT: ret
14 %base = getelementptr <vscale x 16 x i8>, <vscale x 16 x i8>* %addr, i64 2
15 %base_ptr = bitcast <vscale x 16 x i8>* %base to i8*
16 %res = call <vscale x 32 x i8> @llvm.aarch64.sve.ld2.nxv32i8.nxv16i1.p0i8(<vscale x 16 x i1> %Pg, i8 *%base_ptr)
17 ret <vscale x 32 x i8> %res
20 define <vscale x 32 x i8> @ld2.nxv32i8_lower_bound(<vscale x 16 x i1> %Pg, <vscale x 16 x i8> *%addr) {
21 ; CHECK-LABEL: ld2.nxv32i8_lower_bound:
22 ; CHECK: ld2b { z0.b, z1.b }, p0/z, [x0, #-16, mul vl]
23 ; CHECK-NEXT: ret
24 %base = getelementptr <vscale x 16 x i8>, <vscale x 16 x i8>* %addr, i64 -16
25 %base_ptr = bitcast <vscale x 16 x i8>* %base to i8 *
26 %res = call <vscale x 32 x i8> @llvm.aarch64.sve.ld2.nxv32i8.nxv16i1.p0i8(<vscale x 16 x i1> %Pg, i8 *%base_ptr)
27 ret <vscale x 32 x i8> %res
30 define <vscale x 32 x i8> @ld2.nxv32i8_upper_bound(<vscale x 16 x i1> %Pg, <vscale x 16 x i8> *%addr) {
31 ; CHECK-LABEL: ld2.nxv32i8_upper_bound:
32 ; CHECK: ld2b { z0.b, z1.b }, p0/z, [x0, #14, mul vl]
33 ; CHECK-NEXT: ret
34 %base = getelementptr <vscale x 16 x i8>, <vscale x 16 x i8>* %addr, i64 14
35 %base_ptr = bitcast <vscale x 16 x i8>* %base to i8 *
36 %res = call <vscale x 32 x i8> @llvm.aarch64.sve.ld2.nxv32i8.nxv16i1.p0i8(<vscale x 16 x i1> %Pg, i8 *%base_ptr)
37 ret <vscale x 32 x i8> %res
40 define <vscale x 32 x i8> @ld2.nxv32i8_not_multiple_of_2(<vscale x 16 x i1> %Pg, <vscale x 16 x i8> *%addr) {
41 ; CHECK-LABEL: ld2.nxv32i8_not_multiple_of_2:
42 ; CHECK:      rdvl x[[OFFSET:[0-9]]], #3
43 ; CHECK-NEXT: ld2b { z0.b, z1.b }, p0/z, [x0, x[[OFFSET]]]
44 ; CHECK-NEXT: ret
45 %base = getelementptr <vscale x 16 x i8>, <vscale x 16 x i8>* %addr, i64 3
46 %base_ptr = bitcast <vscale x 16 x i8>* %base to i8 *
47 %res = call <vscale x 32 x i8> @llvm.aarch64.sve.ld2.nxv32i8.nxv16i1.p0i8(<vscale x 16 x i1> %Pg, i8 *%base_ptr)
48 ret <vscale x 32 x i8> %res
51 define <vscale x 32 x i8> @ld2.nxv32i8_outside_lower_bound(<vscale x 16 x i1> %Pg, <vscale x 16 x i8> *%addr) {
52 ; CHECK-LABEL: ld2.nxv32i8_outside_lower_bound:
53 ; CHECK:      rdvl x[[OFFSET:[0-9]]], #-18
54 ; CHECK-NEXT: ld2b { z0.b, z1.b }, p0/z, [x0, x[[OFFSET]]]
55 ; CHECK-NEXT: ret
56 %base = getelementptr <vscale x 16 x i8>, <vscale x 16 x i8>* %addr, i64 -18
57 %base_ptr = bitcast <vscale x 16 x i8>* %base to i8 *
58 %res = call <vscale x 32 x i8> @llvm.aarch64.sve.ld2.nxv32i8.nxv16i1.p0i8(<vscale x 16 x i1> %Pg, i8 *%base_ptr)
59 ret <vscale x 32 x i8> %res
62 define <vscale x 32 x i8> @ld2.nxv32i8_outside_upper_bound(<vscale x 16 x i1> %Pg, <vscale x 16 x i8> *%addr) {
63 ; CHECK-LABEL: ld2.nxv32i8_outside_upper_bound:
64 ; CHECK:      rdvl x[[OFFSET:[0-9]]], #16
65 ; CHECK-NEXT: ld2b { z0.b, z1.b }, p0/z, [x0, x[[OFFSET]]]
66 ; CHECK-NEXT: ret
67 %base = getelementptr <vscale x 16 x i8>, <vscale x 16 x i8>* %addr, i64 16
68 %base_ptr = bitcast <vscale x 16 x i8>* %base to i8 *
69 %res = call <vscale x 32 x i8> @llvm.aarch64.sve.ld2.nxv32i8.nxv16i1.p0i8(<vscale x 16 x i1> %Pg, i8 *%base_ptr)
70 ret <vscale x 32 x i8> %res
73 ; ld2h
74 define <vscale x 16 x i16> @ld2.nxv16i16(<vscale x 8 x i1> %Pg, <vscale x 8 x i16>* %addr) {
75 ; CHECK-LABEL: ld2.nxv16i16:
76 ; CHECK: ld2h { z0.h, z1.h }, p0/z, [x0, #14, mul vl]
77 ; CHECK-NEXT: ret
78 %base = getelementptr <vscale x 8 x i16>, <vscale x 8 x i16>* %addr, i64 14
79 %base_ptr = bitcast <vscale x 8 x i16>* %base to i16 *
80 %res = call <vscale x 16 x i16> @llvm.aarch64.sve.ld2.nxv16i16.nxv8i1.p0i16(<vscale x 8 x i1> %Pg, i16 *%base_ptr)
81 ret <vscale x 16 x i16> %res
84 define <vscale x 16 x half> @ld2.nxv16f16(<vscale x 8 x i1> %Pg, <vscale x 8 x half>* %addr) {
85 ; CHECK-LABEL: ld2.nxv16f16:
86 ; CHECK: ld2h { z0.h, z1.h }, p0/z, [x0, #-16, mul vl]
87 ; CHECK-NEXT: ret
88 %base = getelementptr <vscale x 8 x half>, <vscale x 8 x half>* %addr, i64 -16
89 %base_ptr = bitcast <vscale x 8 x half>* %base to half *
90 %res = call <vscale x 16 x half> @llvm.aarch64.sve.ld2.nxv16f16.nxv8i1.p0f16(<vscale x 8 x i1> %Pg, half *%base_ptr)
91 ret <vscale x 16 x half> %res
94 define <vscale x 16 x bfloat> @ld2.nxv16bf16(<vscale x 8 x i1> %Pg, <vscale x 8 x bfloat>* %addr) #0 {
95 ; CHECK-LABEL: ld2.nxv16bf16:
96 ; CHECK: ld2h { z0.h, z1.h }, p0/z, [x0, #12, mul vl]
97 ; CHECK-NEXT: ret
98 %base = getelementptr <vscale x 8 x bfloat>, <vscale x 8 x bfloat>* %addr, i64 12
99 %base_ptr = bitcast <vscale x 8 x bfloat>* %base to bfloat *
100 %res = call <vscale x 16 x bfloat> @llvm.aarch64.sve.ld2.nxv16bf16.nxv8i1.p0bf16(<vscale x 8 x i1> %Pg, bfloat *%base_ptr)
101 ret <vscale x 16 x bfloat> %res
104 ; ld2w
105 define <vscale x 8 x i32> @ld2.nxv8i32(<vscale x 4 x i1> %Pg, <vscale x 4 x i32>* %addr) {
106 ; CHECK-LABEL: ld2.nxv8i32:
107 ; CHECK: ld2w { z0.s, z1.s }, p0/z, [x0, #14, mul vl]
108 ; CHECK-NEXT: ret
109 %base = getelementptr <vscale x 4 x i32>, <vscale x 4 x i32>* %addr, i64 14
110 %base_ptr = bitcast <vscale x 4 x i32>* %base to i32 *
111 %res = call <vscale x 8 x i32> @llvm.aarch64.sve.ld2.nxv8i32.nxv4i1.p0i32(<vscale x 4 x i1> %Pg, i32 *%base_ptr)
112 ret <vscale x 8 x i32> %res
115 define <vscale x 8 x float> @ld2.nxv8f32(<vscale x 4 x i1> %Pg, <vscale x 4 x float>* %addr) {
116 ; CHECK-LABEL: ld2.nxv8f32:
117 ; CHECK: ld2w { z0.s, z1.s }, p0/z, [x0, #-16, mul vl]
118 ; CHECK-NEXT: ret
119 %base = getelementptr <vscale x 4 x float>, <vscale x 4 x float>* %addr, i64 -16
120 %base_ptr = bitcast <vscale x 4 x float>* %base to float *
121 %res = call <vscale x 8 x float> @llvm.aarch64.sve.ld2.nxv8f32.nxv4i1.p0f32(<vscale x 4 x i1> %Pg, float *%base_ptr)
122 ret <vscale x 8 x float> %res
125 ; ld2d
126 define <vscale x 4 x i64> @ld2.nxv4i64(<vscale x 2 x i1> %Pg, <vscale x 2 x i64>* %addr) {
127 ; CHECK-LABEL: ld2.nxv4i64:
128 ; CHECK: ld2d { z0.d, z1.d }, p0/z, [x0, #14, mul vl]
129 ; CHECK-NEXT: ret
130 %base = getelementptr <vscale x 2 x i64>, <vscale x 2 x i64>* %addr, i64 14
131 %base_ptr = bitcast <vscale x 2 x i64>* %base to i64 *
132 %res = call <vscale x 4 x i64> @llvm.aarch64.sve.ld2.nxv4i64.nxv2i1.p0i64(<vscale x 2 x i1> %Pg, i64 *%base_ptr)
133 ret <vscale x 4 x i64> %res
136 define <vscale x 4 x double> @ld2.nxv4f64(<vscale x 2 x i1> %Pg, <vscale x 2 x double>* %addr) {
137 ; CHECK-LABEL: ld2.nxv4f64:
138 ; CHECK: ld2d { z0.d, z1.d }, p0/z, [x0, #-16, mul vl]
139 ; CHECK-NEXT: ret
140 %base = getelementptr <vscale x 2 x double>, <vscale x 2 x double>* %addr, i64 -16
141 %base_ptr = bitcast <vscale x 2 x double>* %base to double *
142 %res = call <vscale x 4 x double> @llvm.aarch64.sve.ld2.nxv4f64.nxv2i1.p0f64(<vscale x 2 x i1> %Pg, double *%base_ptr)
143 ret <vscale x 4 x double> %res
146 ; ld3b
147 define <vscale x 48 x i8> @ld3.nxv48i8(<vscale x 16 x i1> %Pg, <vscale x 16 x i8> *%addr) {
148 ; CHECK-LABEL: ld3.nxv48i8:
149 ; CHECK: ld3b { z0.b, z1.b, z2.b }, p0/z, [x0, #3, mul vl]
150 ; CHECK-NEXT: ret
151 %base = getelementptr <vscale x 16 x i8>, <vscale x 16 x i8>* %addr, i64 3
152 %base_ptr = bitcast <vscale x 16 x i8>* %base to i8 *
153 %res = call <vscale x 48 x i8> @llvm.aarch64.sve.ld3.nxv48i8.nxv16i1.p0i8(<vscale x 16 x i1> %Pg, i8 *%base_ptr)
154 ret <vscale x 48 x i8> %res
157 define <vscale x 48 x i8> @ld3.nxv48i8_lower_bound(<vscale x 16 x i1> %Pg, <vscale x 16 x i8> *%addr) {
158 ; CHECK-LABEL: ld3.nxv48i8_lower_bound:
159 ; CHECK: ld3b { z0.b, z1.b, z2.b }, p0/z, [x0, #-24, mul vl]
160 ; CHECK-NEXT: ret
161 %base = getelementptr <vscale x 16 x i8>, <vscale x 16 x i8>* %addr, i64 -24
162 %base_ptr = bitcast <vscale x 16 x i8>* %base to i8 *
163 %res = call <vscale x 48 x i8> @llvm.aarch64.sve.ld3.nxv48i8.nxv16i1.p0i8(<vscale x 16 x i1> %Pg, i8 *%base_ptr)
164 ret <vscale x 48 x i8> %res
167 define <vscale x 48 x i8> @ld3.nxv48i8_upper_bound(<vscale x 16 x i1> %Pg, <vscale x 16 x i8> *%addr) {
168 ; CHECK-LABEL: ld3.nxv48i8_upper_bound:
169 ; CHECK: ld3b { z0.b, z1.b, z2.b }, p0/z, [x0, #21, mul vl]
170 ; CHECK-NEXT: ret
171 %base = getelementptr <vscale x 16 x i8>, <vscale x 16 x i8>* %addr, i64 21
172 %base_ptr = bitcast <vscale x 16 x i8>* %base to i8 *
173 %res = call <vscale x 48 x i8> @llvm.aarch64.sve.ld3.nxv48i8.nxv16i1.p0i8(<vscale x 16 x i1> %Pg, i8 *%base_ptr)
174 ret <vscale x 48 x i8> %res
177 define <vscale x 48 x i8> @ld3.nxv48i8_not_multiple_of_3_01(<vscale x 16 x i1> %Pg, <vscale x 16 x i8> *%addr) {
178 ; CHECK-LABEL: ld3.nxv48i8_not_multiple_of_3_01:
179 ; CHECK:      rdvl x[[OFFSET:[0-9]]], #4
180 ; CHECK-NEXT: ld3b { z0.b, z1.b, z2.b }, p0/z, [x0, x[[OFFSET]]]
181 ; CHECK-NEXT: ret
182 %base = getelementptr <vscale x 16 x i8>, <vscale x 16 x i8>* %addr, i64 4
183 %base_ptr = bitcast <vscale x 16 x i8>* %base to i8 *
184 %res = call <vscale x 48 x i8> @llvm.aarch64.sve.ld3.nxv48i8.nxv16i1.p0i8(<vscale x 16 x i1> %Pg, i8 *%base_ptr)
185 ret <vscale x 48 x i8> %res
188 define <vscale x 48 x i8> @ld3.nxv48i8_not_multiple_of_3_02(<vscale x 16 x i1> %Pg, <vscale x 16 x i8> *%addr) {
189 ; CHECK-LABEL: ld3.nxv48i8_not_multiple_of_3_02:
190 ; CHECK:      rdvl x[[OFFSET:[0-9]]], #5
191 ; CHECK-NEXT: ld3b { z0.b, z1.b, z2.b }, p0/z, [x0, x[[OFFSET]]]
192 ; CHECK-NEXT: ret
193 %base = getelementptr <vscale x 16 x i8>, <vscale x 16 x i8>* %addr, i64 5
194 %base_ptr = bitcast <vscale x 16 x i8>* %base to i8 *
195 %res = call <vscale x 48 x i8> @llvm.aarch64.sve.ld3.nxv48i8.nxv16i1.p0i8(<vscale x 16 x i1> %Pg, i8 *%base_ptr)
196 ret <vscale x 48 x i8> %res
199 define <vscale x 48 x i8> @ld3.nxv48i8_outside_lower_bound(<vscale x 16 x i1> %Pg, <vscale x 16 x i8> *%addr) {
200 ; CHECK-LABEL: ld3.nxv48i8_outside_lower_bound:
201 ; CHECK:      rdvl x[[OFFSET:[0-9]]], #-27
202 ; CHECK-NEXT: ld3b { z0.b, z1.b, z2.b }, p0/z, [x0, x[[OFFSET]]]
203 ; CHECK-NEXT: ret
204 %base = getelementptr <vscale x 16 x i8>, <vscale x 16 x i8>* %addr, i64 -27
205 %base_ptr = bitcast <vscale x 16 x i8>* %base to i8 *
206 %res = call <vscale x 48 x i8> @llvm.aarch64.sve.ld3.nxv48i8.nxv16i1.p0i8(<vscale x 16 x i1> %Pg, i8 *%base_ptr)
207 ret <vscale x 48 x i8> %res
210 define <vscale x 48 x i8> @ld3.nxv48i8_outside_upper_bound(<vscale x 16 x i1> %Pg, <vscale x 16 x i8> *%addr) {
211 ; CHECK-LABEL: ld3.nxv48i8_outside_upper_bound:
212 ; CHECK:      rdvl x[[OFFSET:[0-9]]], #24
213 ; CHECK-NEXT: ld3b { z0.b, z1.b, z2.b }, p0/z, [x0, x[[OFFSET]]]
214 ; CHECK-NEXT: ret
215 %base = getelementptr <vscale x 16 x i8>, <vscale x 16 x i8>* %addr, i64 24
216 %base_ptr = bitcast <vscale x 16 x i8>* %base to i8 *
217 %res = call <vscale x 48 x i8> @llvm.aarch64.sve.ld3.nxv48i8.nxv16i1.p0i8(<vscale x 16 x i1> %Pg, i8 *%base_ptr)
218 ret <vscale x 48 x i8> %res
221 ; ld3h
222 define <vscale x 24 x i16> @ld3.nxv24i16(<vscale x 8 x i1> %Pg, <vscale x 8 x i16> *%addr) {
223 ; CHECK-LABEL: ld3.nxv24i16:
224 ; CHECK: ld3h { z0.h, z1.h, z2.h }, p0/z, [x0, #21, mul vl]
225 ; CHECK-NEXT: ret
226 %base = getelementptr <vscale x 8 x i16>, <vscale x 8 x i16>* %addr, i64 21
227 %base_ptr = bitcast <vscale x 8 x i16>* %base to i16 *
228 %res = call <vscale x 24 x i16> @llvm.aarch64.sve.ld3.nxv24i16.nxv8i1.p0i16(<vscale x 8 x i1> %Pg, i16 *%base_ptr)
229 ret <vscale x 24 x i16> %res
232 define <vscale x 24 x half> @ld3.nxv24f16(<vscale x 8 x i1> %Pg, <vscale x 8 x half> *%addr) {
233 ; CHECK-LABEL: ld3.nxv24f16:
234 ; CHECK: ld3h { z0.h, z1.h, z2.h }, p0/z, [x0, #21, mul vl]
235 ; CHECK-NEXT: ret
236 %base = getelementptr <vscale x 8 x half>, <vscale x 8 x half>* %addr, i64 21
237 %base_ptr = bitcast <vscale x 8 x half>* %base to half *
238 %res = call <vscale x 24 x half> @llvm.aarch64.sve.ld3.nxv24f16.nxv8i1.p0f16(<vscale x 8 x i1> %Pg, half *%base_ptr)
239 ret <vscale x 24 x half> %res
242 define <vscale x 24 x bfloat> @ld3.nxv24bf16(<vscale x 8 x i1> %Pg, <vscale x 8 x bfloat> *%addr) #0 {
243 ; CHECK-LABEL: ld3.nxv24bf16:
244 ; CHECK: ld3h { z0.h, z1.h, z2.h }, p0/z, [x0, #-24, mul vl]
245 ; CHECK-NEXT: ret
246 %base = getelementptr <vscale x 8 x bfloat>, <vscale x 8 x bfloat>* %addr, i64 -24
247 %base_ptr = bitcast <vscale x 8 x bfloat>* %base to bfloat *
248 %res = call <vscale x 24 x bfloat> @llvm.aarch64.sve.ld3.nxv24bf16.nxv8i1.p0bf16(<vscale x 8 x i1> %Pg, bfloat *%base_ptr)
249 ret <vscale x 24 x bfloat> %res
252 ; ld3w
253 define <vscale x 12 x i32> @ld3.nxv12i32(<vscale x 4 x i1> %Pg, <vscale x 4 x i32> *%addr) {
254 ; CHECK-LABEL: ld3.nxv12i32:
255 ; CHECK: ld3w { z0.s, z1.s, z2.s }, p0/z, [x0, #21, mul vl]
256 ; CHECK-NEXT: ret
257 %base = getelementptr <vscale x 4 x i32>, <vscale x 4 x i32>* %addr, i64 21
258 %base_ptr = bitcast <vscale x 4 x i32>* %base to i32 *
259 %res = call <vscale x 12 x i32> @llvm.aarch64.sve.ld3.nxv12i32.nxv4i1.p0i32(<vscale x 4 x i1> %Pg, i32 *%base_ptr)
260 ret <vscale x 12 x i32> %res
263 define <vscale x 12 x float> @ld3.nxv12f32(<vscale x 4 x i1> %Pg, <vscale x 4 x float> *%addr) {
264 ; CHECK-LABEL: ld3.nxv12f32:
265 ; CHECK: ld3w { z0.s, z1.s, z2.s }, p0/z, [x0, #-24, mul vl]
266 ; CHECK-NEXT: ret
267 %base = getelementptr <vscale x 4 x float>, <vscale x 4 x float>* %addr, i64 -24
268 %base_ptr = bitcast <vscale x 4 x float>* %base to float *
269 %res = call <vscale x 12 x float> @llvm.aarch64.sve.ld3.nxv12f32.nxv4i1.p0f32(<vscale x 4 x i1> %Pg, float *%base_ptr)
270 ret <vscale x 12 x float> %res
273 ; ld3d
274 define <vscale x 6 x i64> @ld3.nxv6i64(<vscale x 2 x i1> %Pg, <vscale x 2 x i64> *%addr) {
275 ; CHECK-LABEL: ld3.nxv6i64:
276 ; CHECK: ld3d { z0.d, z1.d, z2.d }, p0/z, [x0, #21, mul vl]
277 ; CHECK-NEXT: ret
278 %base = getelementptr <vscale x 2 x i64>, <vscale x 2 x i64>* %addr, i64 21
279 %base_ptr = bitcast <vscale x 2 x i64>* %base to i64 *
280 %res = call <vscale x 6 x i64> @llvm.aarch64.sve.ld3.nxv6i64.nxv2i1.p0i64(<vscale x 2 x i1> %Pg, i64 *%base_ptr)
281 ret <vscale x 6 x i64> %res
284 define <vscale x 6 x double> @ld3.nxv6f64(<vscale x 2 x i1> %Pg, <vscale x 2 x double> *%addr) {
285 ; CHECK-LABEL: ld3.nxv6f64:
286 ; CHECK: ld3d { z0.d, z1.d, z2.d }, p0/z, [x0, #-24, mul vl]
287 ; CHECK-NEXT: ret
288 %base = getelementptr <vscale x 2 x double>, <vscale x 2 x double>* %addr, i64 -24
289 %base_ptr = bitcast <vscale x 2 x double>* %base to double *
290 %res = call <vscale x 6 x double> @llvm.aarch64.sve.ld3.nxv6f64.nxv2i1.p0f64(<vscale x 2 x i1> %Pg, double *%base_ptr)
291 ret <vscale x 6 x double> %res
294 ; ; ld4b
295 define <vscale x 64 x i8> @ld4.nxv64i8(<vscale x 16 x i1> %Pg, <vscale x 16 x i8> *%addr) {
296 ; CHECK-LABEL: ld4.nxv64i8:
297 ; CHECK: ld4b { z0.b, z1.b, z2.b, z3.b }, p0/z, [x0, #4, mul vl]
298 ; CHECK-NEXT: ret
299 %base = getelementptr <vscale x 16 x i8>, <vscale x 16 x i8>* %addr, i64 4
300 %base_ptr = bitcast <vscale x 16 x i8>* %base to i8 *
301 %res = call <vscale x 64 x i8> @llvm.aarch64.sve.ld4.nxv64i8.nxv16i1.p0i8(<vscale x 16 x i1> %Pg, i8 *%base_ptr)
302 ret <vscale x 64 x i8> %res
305 define <vscale x 64 x i8> @ld4.nxv64i8_lower_bound(<vscale x 16 x i1> %Pg, <vscale x 16 x i8> *%addr) {
306 ; CHECK-LABEL: ld4.nxv64i8_lower_bound:
307 ; CHECK: ld4b { z0.b, z1.b, z2.b, z3.b }, p0/z, [x0, #-32, mul vl]
308 ; CHECK-NEXT: ret
309 %base = getelementptr <vscale x 16 x i8>, <vscale x 16 x i8>* %addr, i64 -32
310 %base_ptr = bitcast <vscale x 16 x i8>* %base to i8 *
311 %res = call <vscale x 64 x i8> @llvm.aarch64.sve.ld4.nxv64i8.nxv16i1.p0i8(<vscale x 16 x i1> %Pg, i8 *%base_ptr)
312 ret <vscale x 64 x i8> %res
315 define <vscale x 64 x i8> @ld4.nxv64i8_upper_bound(<vscale x 16 x i1> %Pg, <vscale x 16 x i8> *%addr) {
316 ; CHECK-LABEL: ld4.nxv64i8_upper_bound:
317 ; CHECK: ld4b { z0.b, z1.b, z2.b, z3.b }, p0/z, [x0, #28, mul vl]
318 ; CHECK-NEXT: ret
319 %base = getelementptr <vscale x 16 x i8>, <vscale x 16 x i8>* %addr, i64 28
320 %base_ptr = bitcast <vscale x 16 x i8>* %base to i8 *
321 %res = call <vscale x 64 x i8> @llvm.aarch64.sve.ld4.nxv64i8.nxv16i1.p0i8(<vscale x 16 x i1> %Pg, i8 *%base_ptr)
322 ret <vscale x 64 x i8> %res
325 define <vscale x 64 x i8> @ld4.nxv64i8_not_multiple_of_4_01(<vscale x 16 x i1> %Pg, <vscale x 16 x i8> *%addr) {
326 ; CHECK-LABEL: ld4.nxv64i8_not_multiple_of_4_01:
327 ; CHECK:      rdvl x[[OFFSET:[0-9]]], #5
328 ; CHECK-NEXT: ld4b { z0.b, z1.b, z2.b, z3.b }, p0/z, [x0, x[[OFFSET]]]
329 ; CHECK-NEXT: ret
330 %base = getelementptr <vscale x 16 x i8>, <vscale x 16 x i8>* %addr, i64 5
331 %base_ptr = bitcast <vscale x 16 x i8>* %base to i8 *
332 %res = call <vscale x 64 x i8> @llvm.aarch64.sve.ld4.nxv64i8.nxv16i1.p0i8(<vscale x 16 x i1> %Pg, i8 *%base_ptr)
333 ret <vscale x 64 x i8> %res
336 define <vscale x 64 x i8> @ld4.nxv64i8_not_multiple_of_4_02(<vscale x 16 x i1> %Pg, <vscale x 16 x i8> *%addr) {
337 ; CHECK-LABEL: ld4.nxv64i8_not_multiple_of_4_02:
338 ; CHECK:      rdvl x[[OFFSET:[0-9]]], #6
339 ; CHECK-NEXT: ld4b { z0.b, z1.b, z2.b, z3.b }, p0/z, [x0, x[[OFFSET]]]
340 ; CHECK-NEXT: ret
341 %base = getelementptr <vscale x 16 x i8>, <vscale x 16 x i8>* %addr, i64 6
342 %base_ptr = bitcast <vscale x 16 x i8>* %base to i8 *
343 %res = call <vscale x 64 x i8> @llvm.aarch64.sve.ld4.nxv64i8.nxv16i1.p0i8(<vscale x 16 x i1> %Pg, i8 *%base_ptr)
344 ret <vscale x 64 x i8> %res
347 define <vscale x 64 x i8> @ld4.nxv64i8_not_multiple_of_4_03(<vscale x 16 x i1> %Pg, <vscale x 16 x i8> *%addr) {
348 ; CHECK-LABEL: ld4.nxv64i8_not_multiple_of_4_03:
349 ; CHECK:      rdvl x[[OFFSET:[0-9]]], #7
350 ; CHECK-NEXT: ld4b { z0.b, z1.b, z2.b, z3.b }, p0/z, [x0, x[[OFFSET]]]
351 ; CHECK-NEXT: ret
352 %base = getelementptr <vscale x 16 x i8>, <vscale x 16 x i8>* %addr, i64 7
353 %base_ptr = bitcast <vscale x 16 x i8>* %base to i8 *
354 %res = call <vscale x 64 x i8> @llvm.aarch64.sve.ld4.nxv64i8.nxv16i1.p0i8(<vscale x 16 x i1> %Pg, i8 *%base_ptr)
355 ret <vscale x 64 x i8> %res
358 define <vscale x 64 x i8> @ld4.nxv64i8_outside_lower_bound(<vscale x 16 x i1> %Pg, <vscale x 16 x i8> *%addr) {
359 ; CHECK-LABEL: ld4.nxv64i8_outside_lower_bound:
360 ; FIXME: optimize OFFSET computation so that xOFFSET = (mul (RDVL #4) #9)
361 ; xM = -9 * 2^6
362 ; xP = RDVL * 2^-4 
363 ; xOFFSET = RDVL * 2^-4 * -9 * 2^6 = RDVL * -36
364 ; CHECK:      rdvl x[[N:[0-9]]], #1
365 ; CHECK-DAG:  mov  x[[M:[0-9]]], #-576
366 ; CHECK-DAG:  lsr  x[[P:[0-9]]], x[[N]], #4
367 ; CHECK-DAG:  mul  x[[OFFSET:[0-9]]], x[[P]], x[[M]]
368 ; CHECK-NEXT: ld4b { z0.b, z1.b, z2.b, z3.b }, p0/z, [x0, x[[OFFSET]]]
369 ; CHECK-NEXT: ret
370 %base = getelementptr <vscale x 16 x i8>, <vscale x 16 x i8>* %addr, i64 -36
371 %base_ptr = bitcast <vscale x 16 x i8>* %base to i8 *
372 %res = call <vscale x 64 x i8> @llvm.aarch64.sve.ld4.nxv64i8.nxv16i1.p0i8(<vscale x 16 x i1> %Pg, i8 *%base_ptr)
373 ret <vscale x 64 x i8> %res
376 define <vscale x 64 x i8> @ld4.nxv64i8_outside_upper_bound(<vscale x 16 x i1> %Pg, <vscale x 16 x i8> *%addr) {
377 ; CHECK-LABEL: ld4.nxv64i8_outside_upper_bound:
378 ; FIXME: optimize OFFSET computation so that xOFFSET = (mul (RDVL #16) #2)
379 ; xM = 2^9
380 ; xP = RDVL * 2^-4
381 ; xOFFSET = RDVL * 2^-4 * 2^9 = RDVL * 32
382 ; CHECK:      rdvl x[[N:[0-9]]], #1
383 ; CHECK-DAG:  mov  w[[M:[0-9]]], #512
384 ; CHECK-DAG:  lsr  x[[P:[0-9]]], x[[N]], #4
385 ; CHECK-DAG:  mul  x[[OFFSET:[0-9]]], x[[P]], x[[M]]
386 ; CHECK-NEXT: ld4b { z0.b, z1.b, z2.b, z3.b }, p0/z, [x0, x[[OFFSET]]]
387 ; CHECK-NEXT: ret
388 %base = getelementptr <vscale x 16 x i8>, <vscale x 16 x i8>* %addr, i64 32
389 %base_ptr = bitcast <vscale x 16 x i8>* %base to i8 *
390 %res = call <vscale x 64 x i8> @llvm.aarch64.sve.ld4.nxv64i8.nxv16i1.p0i8(<vscale x 16 x i1> %Pg, i8 *%base_ptr)
391 ret <vscale x 64 x i8> %res
394 ; ld4h
395 define <vscale x 32 x i16> @ld4.nxv32i16(<vscale x 8 x i1> %Pg, <vscale x 8 x i16> *%addr) {
396 ; CHECK-LABEL: ld4.nxv32i16:
397 ; CHECK: ld4h { z0.h, z1.h, z2.h, z3.h }, p0/z, [x0, #8, mul vl]
398 ; CHECK-NEXT: ret
399 %base = getelementptr <vscale x 8 x i16>, <vscale x 8 x i16>* %addr, i64 8
400 %base_ptr = bitcast <vscale x 8 x i16>* %base to i16 *
401 %res = call <vscale x 32 x i16> @llvm.aarch64.sve.ld4.nxv32i16.nxv8i1.p0i16(<vscale x 8 x i1> %Pg, i16 *%base_ptr)
402 ret <vscale x 32 x i16> %res
405 define <vscale x 32 x half> @ld4.nxv32f16(<vscale x 8 x i1> %Pg, <vscale x 8 x half> *%addr) {
406 ; CHECK-LABEL: ld4.nxv32f16:
407 ; CHECK: ld4h { z0.h, z1.h, z2.h, z3.h }, p0/z, [x0, #28, mul vl]
408 ; CHECK-NEXT: ret
409 %base = getelementptr <vscale x 8 x half>, <vscale x 8 x half>* %addr, i64 28
410 %base_ptr = bitcast <vscale x 8 x half>* %base to half *
411 %res = call <vscale x 32 x half> @llvm.aarch64.sve.ld4.nxv32f16.nxv8i1.p0f16(<vscale x 8 x i1> %Pg, half *%base_ptr)
412 ret <vscale x 32 x half> %res
415 define <vscale x 32 x bfloat> @ld4.nxv32bf16(<vscale x 8 x i1> %Pg, <vscale x 8 x bfloat> *%addr) #0 {
416 ; CHECK-LABEL: ld4.nxv32bf16:
417 ; CHECK: ld4h { z0.h, z1.h, z2.h, z3.h }, p0/z, [x0, #-32, mul vl]
418 ; CHECK-NEXT: ret
419 %base = getelementptr <vscale x 8 x bfloat>, <vscale x 8 x bfloat>* %addr, i64 -32
420 %base_ptr = bitcast <vscale x 8 x bfloat>* %base to bfloat *
421 %res = call <vscale x 32 x bfloat> @llvm.aarch64.sve.ld4.nxv32bf16.nxv8i1.p0bf16(<vscale x 8 x i1> %Pg, bfloat *%base_ptr)
422 ret <vscale x 32 x bfloat> %res
425 ; ld4w
426 define <vscale x 16 x i32> @ld4.nxv16i32(<vscale x 4 x i1> %Pg, <vscale x 4 x i32> *%addr) {
427 ; CHECK-LABEL: ld4.nxv16i32:
428 ; CHECK: ld4w { z0.s, z1.s, z2.s, z3.s }, p0/z, [x0, #28, mul vl]
429 ; CHECK-NEXT: ret
430 %base = getelementptr <vscale x 4 x i32>, <vscale x 4 x i32>* %addr, i64 28
431 %base_ptr = bitcast <vscale x 4 x i32>* %base to i32 *
432 %res = call <vscale x 16 x i32> @llvm.aarch64.sve.ld4.nxv16i32.nxv4i1.p0i32(<vscale x 4 x i1> %Pg, i32 *%base_ptr)
433 ret <vscale x 16 x i32> %res
436 define <vscale x 16 x float> @ld4.nxv16f32(<vscale x 4 x i1> %Pg, <vscale x 4 x float>* %addr) {
437 ; CHECK-LABEL: ld4.nxv16f32:
438 ; CHECK: ld4w { z0.s, z1.s, z2.s, z3.s }, p0/z, [x0, #-32, mul vl]
439 ; CHECK-NEXT: ret
440 %base = getelementptr <vscale x 4 x float>, <vscale x 4 x float>* %addr, i64 -32
441 %base_ptr = bitcast <vscale x 4 x float>* %base to float *
442 %res = call <vscale x 16 x float> @llvm.aarch64.sve.ld4.nxv16f32.nxv4i1.p0f32(<vscale x 4 x i1> %Pg, float *%base_ptr)
443 ret <vscale x 16 x float> %res
446 ; ld4d
447 define <vscale x 8 x i64> @ld4.nxv8i64(<vscale x 2 x i1> %Pg, <vscale x 2 x i64> *%addr) {
448 ; CHECK-LABEL: ld4.nxv8i64:
449 ; CHECK: ld4d { z0.d, z1.d, z2.d, z3.d }, p0/z, [x0, #28, mul vl]
450 ; CHECK-NEXT: ret
451 %base = getelementptr <vscale x 2 x i64>, <vscale x 2 x i64>* %addr, i64 28
452 %base_ptr = bitcast <vscale x 2 x i64>* %base to i64 *
453 %res = call <vscale x 8 x i64> @llvm.aarch64.sve.ld4.nxv8i64.nxv2i1.p0i64(<vscale x 2 x i1> %Pg, i64 *%base_ptr)
454 ret <vscale x 8 x i64> %res
457 define <vscale x 8 x double> @ld4.nxv8f64(<vscale x 2 x i1> %Pg, <vscale x 2 x double> *%addr) {
458 ; CHECK-LABEL: ld4.nxv8f64:
459 ; CHECK: ld4d { z0.d, z1.d, z2.d, z3.d }, p0/z, [x0, #-32, mul vl]
460 ; CHECK-NEXT: ret
461 %base = getelementptr <vscale x 2 x double>, <vscale x 2 x double>* %addr, i64 -32
462 %base_ptr = bitcast <vscale x 2 x double>* %base to double *
463 %res = call <vscale x 8 x double> @llvm.aarch64.sve.ld4.nxv8f64.nxv2i1.p0f64(<vscale x 2 x i1> %Pg, double * %base_ptr)
464 ret <vscale x 8 x double> %res
467 declare <vscale x 32 x i8> @llvm.aarch64.sve.ld2.nxv32i8.nxv16i1.p0i8(<vscale x 16 x i1>, i8*)
468 declare <vscale x 16 x i16> @llvm.aarch64.sve.ld2.nxv16i16.nxv8i1.p0i16(<vscale x 8 x i1>, i16*)
469 declare <vscale x 8 x i32> @llvm.aarch64.sve.ld2.nxv8i32.nxv4i1.p0i32(<vscale x 4 x i1>, i32*)
470 declare <vscale x 4 x i64> @llvm.aarch64.sve.ld2.nxv4i64.nxv2i1.p0i64(<vscale x 2 x i1>, i64*)
471 declare <vscale x 16 x half> @llvm.aarch64.sve.ld2.nxv16f16.nxv8i1.p0f16(<vscale x 8 x i1>, half*)
472 declare <vscale x 16 x bfloat> @llvm.aarch64.sve.ld2.nxv16bf16.nxv8i1.p0bf16(<vscale x 8 x i1>, bfloat*)
473 declare <vscale x 8 x float> @llvm.aarch64.sve.ld2.nxv8f32.nxv4i1.p0f32(<vscale x 4 x i1>, float*)
474 declare <vscale x 4 x double> @llvm.aarch64.sve.ld2.nxv4f64.nxv2i1.p0f64(<vscale x 2 x i1>, double*)
476 declare <vscale x 48 x i8> @llvm.aarch64.sve.ld3.nxv48i8.nxv16i1.p0i8(<vscale x 16 x i1>, i8*)
477 declare <vscale x 24 x i16> @llvm.aarch64.sve.ld3.nxv24i16.nxv8i1.p0i16(<vscale x 8 x i1>, i16*)
478 declare <vscale x 12 x i32> @llvm.aarch64.sve.ld3.nxv12i32.nxv4i1.p0i32(<vscale x 4 x i1>, i32*)
479 declare <vscale x 6 x i64> @llvm.aarch64.sve.ld3.nxv6i64.nxv2i1.p0i64(<vscale x 2 x i1>, i64*)
480 declare <vscale x 24 x half> @llvm.aarch64.sve.ld3.nxv24f16.nxv8i1.p0f16(<vscale x 8 x i1>, half*)
481 declare <vscale x 24 x bfloat> @llvm.aarch64.sve.ld3.nxv24bf16.nxv8i1.p0bf16(<vscale x 8 x i1>, bfloat*)
482 declare <vscale x 12 x float> @llvm.aarch64.sve.ld3.nxv12f32.nxv4i1.p0f32(<vscale x 4 x i1>, float*)
483 declare <vscale x 6 x double> @llvm.aarch64.sve.ld3.nxv6f64.nxv2i1.p0f64(<vscale x 2 x i1>, double*)
485 declare <vscale x 64 x i8> @llvm.aarch64.sve.ld4.nxv64i8.nxv16i1.p0i8(<vscale x 16 x i1>, i8*)
486 declare <vscale x 32 x i16> @llvm.aarch64.sve.ld4.nxv32i16.nxv8i1.p0i16(<vscale x 8 x i1>, i16*)
487 declare <vscale x 16 x i32> @llvm.aarch64.sve.ld4.nxv16i32.nxv4i1.p0i32(<vscale x 4 x i1>, i32*)
488 declare <vscale x 8 x i64> @llvm.aarch64.sve.ld4.nxv8i64.nxv2i1.p0i64(<vscale x 2 x i1>, i64*)
489 declare <vscale x 32 x half> @llvm.aarch64.sve.ld4.nxv32f16.nxv8i1.p0f16(<vscale x 8 x i1>, half*)
490 declare <vscale x 32 x bfloat> @llvm.aarch64.sve.ld4.nxv32bf16.nxv8i1.p0bf16(<vscale x 8 x i1>, bfloat*)
491 declare <vscale x 16 x float> @llvm.aarch64.sve.ld4.nxv16f32.nxv4i1.p0f32(<vscale x 4 x i1>, float*)
492 declare <vscale x 8 x double> @llvm.aarch64.sve.ld4.nxv8f64.nxv2i1.p0f64(<vscale x 2 x i1>, double*)
494 ; +bf16 is required for the bfloat version.
495 attributes #0 = { "target-features"="+sve,+bf16" }