1 ; NOTE: Assertions have been autogenerated by utils/update_llc_test_checks.py
2 ; RUN: llc -mattr=+sve -force-streaming-compatible-sve < %s | FileCheck %s
3 ; RUN: llc -mattr=+sme -force-streaming-compatible-sve < %s | FileCheck %s
6 target triple = "aarch64-unknown-linux-gnu"
12 define <16 x i8> @trunc_v16i16_v16i8(ptr %in) nounwind {
13 ; CHECK-LABEL: trunc_v16i16_v16i8:
15 ; CHECK-NEXT: ldp q0, q1, [x0]
16 ; CHECK-NEXT: ptrue p0.b, vl8
17 ; CHECK-NEXT: uzp1 z1.b, z1.b, z1.b
18 ; CHECK-NEXT: uzp1 z0.b, z0.b, z0.b
19 ; CHECK-NEXT: splice z0.b, p0, z0.b, z1.b
20 ; CHECK-NEXT: // kill: def $q0 killed $q0 killed $z0
22 %a = load <16 x i16>, ptr %in
23 %b = trunc <16 x i16> %a to <16 x i8>
27 ; NOTE: Extra 'add' is to prevent the truncate being combined with the store.
28 define void @trunc_v32i16_v32i8(ptr %in, ptr %out) nounwind {
29 ; CHECK-LABEL: trunc_v32i16_v32i8:
31 ; CHECK-NEXT: ldp q0, q1, [x0, #32]
32 ; CHECK-NEXT: ptrue p0.b, vl8
33 ; CHECK-NEXT: ldp q2, q3, [x0]
34 ; CHECK-NEXT: uzp1 z1.b, z1.b, z1.b
35 ; CHECK-NEXT: uzp1 z0.b, z0.b, z0.b
36 ; CHECK-NEXT: uzp1 z3.b, z3.b, z3.b
37 ; CHECK-NEXT: uzp1 z2.b, z2.b, z2.b
38 ; CHECK-NEXT: splice z0.b, p0, z0.b, z1.b
39 ; CHECK-NEXT: splice z2.b, p0, z2.b, z3.b
40 ; CHECK-NEXT: add z0.b, z0.b, z0.b
41 ; CHECK-NEXT: add z1.b, z2.b, z2.b
42 ; CHECK-NEXT: stp q1, q0, [x1]
44 %a = load <32 x i16>, ptr %in
45 %b = trunc <32 x i16> %a to <32 x i8>
46 %c = add <32 x i8> %b, %b
47 store <32 x i8> %c, ptr %out
51 ; NOTE: Extra 'add' is to prevent the truncate being combined with the store.
52 define void @trunc_v64i16_v64i8(ptr %in, ptr %out) nounwind {
53 ; CHECK-LABEL: trunc_v64i16_v64i8:
55 ; CHECK-NEXT: ldp q0, q1, [x0, #64]
56 ; CHECK-NEXT: ptrue p0.b, vl8
57 ; CHECK-NEXT: ldp q2, q3, [x0]
58 ; CHECK-NEXT: ldp q4, q5, [x0, #96]
59 ; CHECK-NEXT: ldp q6, q7, [x0, #32]
60 ; CHECK-NEXT: uzp1 z1.b, z1.b, z1.b
61 ; CHECK-NEXT: uzp1 z0.b, z0.b, z0.b
62 ; CHECK-NEXT: uzp1 z3.b, z3.b, z3.b
63 ; CHECK-NEXT: uzp1 z2.b, z2.b, z2.b
64 ; CHECK-NEXT: uzp1 z5.b, z5.b, z5.b
65 ; CHECK-NEXT: uzp1 z4.b, z4.b, z4.b
66 ; CHECK-NEXT: uzp1 z7.b, z7.b, z7.b
67 ; CHECK-NEXT: uzp1 z6.b, z6.b, z6.b
68 ; CHECK-NEXT: splice z0.b, p0, z0.b, z1.b
69 ; CHECK-NEXT: splice z2.b, p0, z2.b, z3.b
70 ; CHECK-NEXT: splice z4.b, p0, z4.b, z5.b
71 ; CHECK-NEXT: splice z6.b, p0, z6.b, z7.b
72 ; CHECK-NEXT: add z0.b, z0.b, z0.b
73 ; CHECK-NEXT: add z2.b, z2.b, z2.b
74 ; CHECK-NEXT: add z1.b, z4.b, z4.b
75 ; CHECK-NEXT: add z3.b, z6.b, z6.b
76 ; CHECK-NEXT: stp q0, q1, [x1, #32]
77 ; CHECK-NEXT: stp q2, q3, [x1]
79 %a = load <64 x i16>, ptr %in
80 %b = trunc <64 x i16> %a to <64 x i8>
81 %c = add <64 x i8> %b, %b
82 store <64 x i8> %c, ptr %out
86 ; NOTE: Extra 'add' is to prevent the truncate being combined with the store.
87 define void @trunc_v128i16_v128i8(ptr %in, ptr %out) nounwind {
88 ; CHECK-LABEL: trunc_v128i16_v128i8:
90 ; CHECK-NEXT: ldp q0, q1, [x0, #192]
91 ; CHECK-NEXT: ptrue p0.b, vl8
92 ; CHECK-NEXT: ldp q6, q7, [x0, #224]
93 ; CHECK-NEXT: ldp q2, q3, [x0, #32]
94 ; CHECK-NEXT: uzp1 z1.b, z1.b, z1.b
95 ; CHECK-NEXT: uzp1 z0.b, z0.b, z0.b
96 ; CHECK-NEXT: uzp1 z7.b, z7.b, z7.b
97 ; CHECK-NEXT: uzp1 z6.b, z6.b, z6.b
98 ; CHECK-NEXT: ldp q4, q5, [x0]
99 ; CHECK-NEXT: uzp1 z3.b, z3.b, z3.b
100 ; CHECK-NEXT: ldp q16, q17, [x0, #64]
101 ; CHECK-NEXT: uzp1 z2.b, z2.b, z2.b
102 ; CHECK-NEXT: ldp q18, q19, [x0, #128]
103 ; CHECK-NEXT: splice z0.b, p0, z0.b, z1.b
104 ; CHECK-NEXT: ldp q20, q21, [x0, #160]
105 ; CHECK-NEXT: splice z6.b, p0, z6.b, z7.b
106 ; CHECK-NEXT: ldp q22, q23, [x0, #96]
107 ; CHECK-NEXT: uzp1 z1.b, z17.b, z17.b
108 ; CHECK-NEXT: uzp1 z19.b, z19.b, z19.b
109 ; CHECK-NEXT: uzp1 z18.b, z18.b, z18.b
110 ; CHECK-NEXT: uzp1 z16.b, z16.b, z16.b
111 ; CHECK-NEXT: uzp1 z21.b, z21.b, z21.b
112 ; CHECK-NEXT: uzp1 z20.b, z20.b, z20.b
113 ; CHECK-NEXT: uzp1 z5.b, z5.b, z5.b
114 ; CHECK-NEXT: uzp1 z7.b, z23.b, z23.b
115 ; CHECK-NEXT: uzp1 z17.b, z22.b, z22.b
116 ; CHECK-NEXT: uzp1 z4.b, z4.b, z4.b
117 ; CHECK-NEXT: splice z2.b, p0, z2.b, z3.b
118 ; CHECK-NEXT: add z0.b, z0.b, z0.b
119 ; CHECK-NEXT: splice z18.b, p0, z18.b, z19.b
120 ; CHECK-NEXT: splice z16.b, p0, z16.b, z1.b
121 ; CHECK-NEXT: add z1.b, z6.b, z6.b
122 ; CHECK-NEXT: splice z20.b, p0, z20.b, z21.b
123 ; CHECK-NEXT: splice z17.b, p0, z17.b, z7.b
124 ; CHECK-NEXT: splice z4.b, p0, z4.b, z5.b
125 ; CHECK-NEXT: stp q0, q1, [x1, #96]
126 ; CHECK-NEXT: add z2.b, z2.b, z2.b
127 ; CHECK-NEXT: add z5.b, z18.b, z18.b
128 ; CHECK-NEXT: add z0.b, z16.b, z16.b
129 ; CHECK-NEXT: add z3.b, z20.b, z20.b
130 ; CHECK-NEXT: add z1.b, z17.b, z17.b
131 ; CHECK-NEXT: add z4.b, z4.b, z4.b
132 ; CHECK-NEXT: stp q5, q3, [x1, #64]
133 ; CHECK-NEXT: stp q4, q2, [x1]
134 ; CHECK-NEXT: stp q0, q1, [x1, #32]
136 %a = load <128 x i16>, ptr %in
137 %b = trunc <128 x i16> %a to <128 x i8>
138 %c = add <128 x i8> %b, %b
139 store <128 x i8> %c, ptr %out
147 define <8 x i8> @trunc_v8i32_v8i8(ptr %in) nounwind {
148 ; CHECK-LABEL: trunc_v8i32_v8i8:
150 ; CHECK-NEXT: ldp q0, q1, [x0]
151 ; CHECK-NEXT: ptrue p0.h, vl4
152 ; CHECK-NEXT: uzp1 z1.h, z1.h, z1.h
153 ; CHECK-NEXT: uzp1 z0.h, z0.h, z0.h
154 ; CHECK-NEXT: splice z0.h, p0, z0.h, z1.h
155 ; CHECK-NEXT: uzp1 z0.b, z0.b, z0.b
156 ; CHECK-NEXT: // kill: def $d0 killed $d0 killed $z0
158 %a = load <8 x i32>, ptr %in
159 %b = trunc <8 x i32> %a to <8 x i8>
163 define <16 x i8> @trunc_v16i32_v16i8(ptr %in) nounwind {
164 ; CHECK-LABEL: trunc_v16i32_v16i8:
166 ; CHECK-NEXT: ldp q1, q0, [x0, #32]
167 ; CHECK-NEXT: ptrue p0.h, vl4
168 ; CHECK-NEXT: ldp q2, q3, [x0]
169 ; CHECK-NEXT: uzp1 z0.h, z0.h, z0.h
170 ; CHECK-NEXT: uzp1 z1.h, z1.h, z1.h
171 ; CHECK-NEXT: uzp1 z3.h, z3.h, z3.h
172 ; CHECK-NEXT: uzp1 z2.h, z2.h, z2.h
173 ; CHECK-NEXT: splice z1.h, p0, z1.h, z0.h
174 ; CHECK-NEXT: splice z2.h, p0, z2.h, z3.h
175 ; CHECK-NEXT: ptrue p0.b, vl8
176 ; CHECK-NEXT: uzp1 z1.b, z1.b, z1.b
177 ; CHECK-NEXT: uzp1 z0.b, z2.b, z2.b
178 ; CHECK-NEXT: splice z0.b, p0, z0.b, z1.b
179 ; CHECK-NEXT: // kill: def $q0 killed $q0 killed $z0
181 %a = load <16 x i32>, ptr %in
182 %b = trunc <16 x i32> %a to <16 x i8>
186 ; NOTE: Extra 'add' is to prevent the truncate being combined with the store.
187 define void @trunc_v32i32_v32i8(ptr %in, ptr %out) nounwind {
188 ; CHECK-LABEL: trunc_v32i32_v32i8:
190 ; CHECK-NEXT: ldp q0, q1, [x0, #32]
191 ; CHECK-NEXT: ptrue p0.h, vl4
192 ; CHECK-NEXT: ldp q2, q3, [x0, #96]
193 ; CHECK-NEXT: ldp q4, q5, [x0, #64]
194 ; CHECK-NEXT: ldp q6, q7, [x0]
195 ; CHECK-NEXT: uzp1 z1.h, z1.h, z1.h
196 ; CHECK-NEXT: uzp1 z3.h, z3.h, z3.h
197 ; CHECK-NEXT: uzp1 z2.h, z2.h, z2.h
198 ; CHECK-NEXT: uzp1 z0.h, z0.h, z0.h
199 ; CHECK-NEXT: uzp1 z5.h, z5.h, z5.h
200 ; CHECK-NEXT: uzp1 z4.h, z4.h, z4.h
201 ; CHECK-NEXT: uzp1 z7.h, z7.h, z7.h
202 ; CHECK-NEXT: uzp1 z6.h, z6.h, z6.h
203 ; CHECK-NEXT: splice z2.h, p0, z2.h, z3.h
204 ; CHECK-NEXT: splice z0.h, p0, z0.h, z1.h
205 ; CHECK-NEXT: splice z4.h, p0, z4.h, z5.h
206 ; CHECK-NEXT: splice z6.h, p0, z6.h, z7.h
207 ; CHECK-NEXT: ptrue p0.b, vl8
208 ; CHECK-NEXT: uzp1 z1.b, z2.b, z2.b
209 ; CHECK-NEXT: uzp1 z0.b, z0.b, z0.b
210 ; CHECK-NEXT: uzp1 z2.b, z4.b, z4.b
211 ; CHECK-NEXT: uzp1 z3.b, z6.b, z6.b
212 ; CHECK-NEXT: splice z2.b, p0, z2.b, z1.b
213 ; CHECK-NEXT: splice z3.b, p0, z3.b, z0.b
214 ; CHECK-NEXT: add z0.b, z2.b, z2.b
215 ; CHECK-NEXT: add z1.b, z3.b, z3.b
216 ; CHECK-NEXT: stp q1, q0, [x1]
218 %a = load <32 x i32>, ptr %in
219 %b = trunc <32 x i32> %a to <32 x i8>
220 %c = add <32 x i8> %b, %b
221 store <32 x i8> %c, ptr %out
225 ; NOTE: Extra 'add' is to prevent the truncate being combined with the store.
226 define void @trunc_v64i32_v64i8(ptr %in, ptr %out) nounwind {
227 ; CHECK-LABEL: trunc_v64i32_v64i8:
229 ; CHECK-NEXT: ldp q0, q1, [x0, #64]
230 ; CHECK-NEXT: ptrue p0.h, vl4
231 ; CHECK-NEXT: ldp q2, q3, [x0, #160]
232 ; CHECK-NEXT: ptrue p1.b, vl8
233 ; CHECK-NEXT: ldp q4, q5, [x0, #96]
234 ; CHECK-NEXT: ldp q6, q7, [x0]
235 ; CHECK-NEXT: uzp1 z1.h, z1.h, z1.h
236 ; CHECK-NEXT: ldp q16, q17, [x0, #128]
237 ; CHECK-NEXT: uzp1 z3.h, z3.h, z3.h
238 ; CHECK-NEXT: ldp q18, q19, [x0, #192]
239 ; CHECK-NEXT: uzp1 z2.h, z2.h, z2.h
240 ; CHECK-NEXT: ldp q20, q21, [x0, #224]
241 ; CHECK-NEXT: uzp1 z7.h, z7.h, z7.h
242 ; CHECK-NEXT: ldp q22, q23, [x0, #32]
243 ; CHECK-NEXT: uzp1 z17.h, z17.h, z17.h
244 ; CHECK-NEXT: uzp1 z16.h, z16.h, z16.h
245 ; CHECK-NEXT: uzp1 z19.h, z19.h, z19.h
246 ; CHECK-NEXT: uzp1 z18.h, z18.h, z18.h
247 ; CHECK-NEXT: uzp1 z21.h, z21.h, z21.h
248 ; CHECK-NEXT: uzp1 z20.h, z20.h, z20.h
249 ; CHECK-NEXT: uzp1 z6.h, z6.h, z6.h
250 ; CHECK-NEXT: uzp1 z23.h, z23.h, z23.h
251 ; CHECK-NEXT: uzp1 z22.h, z22.h, z22.h
252 ; CHECK-NEXT: uzp1 z5.h, z5.h, z5.h
253 ; CHECK-NEXT: uzp1 z4.h, z4.h, z4.h
254 ; CHECK-NEXT: uzp1 z0.h, z0.h, z0.h
255 ; CHECK-NEXT: splice z2.h, p0, z2.h, z3.h
256 ; CHECK-NEXT: splice z16.h, p0, z16.h, z17.h
257 ; CHECK-NEXT: splice z18.h, p0, z18.h, z19.h
258 ; CHECK-NEXT: splice z20.h, p0, z20.h, z21.h
259 ; CHECK-NEXT: splice z6.h, p0, z6.h, z7.h
260 ; CHECK-NEXT: splice z22.h, p0, z22.h, z23.h
261 ; CHECK-NEXT: splice z4.h, p0, z4.h, z5.h
262 ; CHECK-NEXT: splice z0.h, p0, z0.h, z1.h
263 ; CHECK-NEXT: uzp1 z1.b, z2.b, z2.b
264 ; CHECK-NEXT: uzp1 z2.b, z16.b, z16.b
265 ; CHECK-NEXT: uzp1 z5.b, z18.b, z18.b
266 ; CHECK-NEXT: uzp1 z3.b, z20.b, z20.b
267 ; CHECK-NEXT: uzp1 z6.b, z6.b, z6.b
268 ; CHECK-NEXT: uzp1 z7.b, z22.b, z22.b
269 ; CHECK-NEXT: uzp1 z4.b, z4.b, z4.b
270 ; CHECK-NEXT: uzp1 z0.b, z0.b, z0.b
271 ; CHECK-NEXT: splice z2.b, p1, z2.b, z1.b
272 ; CHECK-NEXT: splice z5.b, p1, z5.b, z3.b
273 ; CHECK-NEXT: splice z6.b, p1, z6.b, z7.b
274 ; CHECK-NEXT: splice z0.b, p1, z0.b, z4.b
275 ; CHECK-NEXT: add z1.b, z2.b, z2.b
276 ; CHECK-NEXT: add z2.b, z5.b, z5.b
277 ; CHECK-NEXT: add z3.b, z6.b, z6.b
278 ; CHECK-NEXT: add z0.b, z0.b, z0.b
279 ; CHECK-NEXT: stp q1, q2, [x1, #32]
280 ; CHECK-NEXT: stp q3, q0, [x1]
282 %a = load <64 x i32>, ptr %in
283 %b = trunc <64 x i32> %a to <64 x i8>
284 %c = add <64 x i8> %b, %b
285 store <64 x i8> %c, ptr %out
290 ; truncate i32 -> i16
293 define <8 x i16> @trunc_v8i32_v8i16(ptr %in) nounwind {
294 ; CHECK-LABEL: trunc_v8i32_v8i16:
296 ; CHECK-NEXT: ldp q0, q1, [x0]
297 ; CHECK-NEXT: ptrue p0.h, vl4
298 ; CHECK-NEXT: uzp1 z1.h, z1.h, z1.h
299 ; CHECK-NEXT: uzp1 z0.h, z0.h, z0.h
300 ; CHECK-NEXT: splice z0.h, p0, z0.h, z1.h
301 ; CHECK-NEXT: // kill: def $q0 killed $q0 killed $z0
303 %a = load <8 x i32>, ptr %in
304 %b = trunc <8 x i32> %a to <8 x i16>
308 ; NOTE: Extra 'add' is to prevent the truncate being combined with the store.
309 define void @trunc_v16i32_v16i16(ptr %in, ptr %out) nounwind {
310 ; CHECK-LABEL: trunc_v16i32_v16i16:
312 ; CHECK-NEXT: ldp q0, q1, [x0, #32]
313 ; CHECK-NEXT: ptrue p0.h, vl4
314 ; CHECK-NEXT: ldp q2, q3, [x0]
315 ; CHECK-NEXT: uzp1 z1.h, z1.h, z1.h
316 ; CHECK-NEXT: uzp1 z0.h, z0.h, z0.h
317 ; CHECK-NEXT: uzp1 z3.h, z3.h, z3.h
318 ; CHECK-NEXT: uzp1 z2.h, z2.h, z2.h
319 ; CHECK-NEXT: splice z0.h, p0, z0.h, z1.h
320 ; CHECK-NEXT: splice z2.h, p0, z2.h, z3.h
321 ; CHECK-NEXT: add z0.h, z0.h, z0.h
322 ; CHECK-NEXT: add z1.h, z2.h, z2.h
323 ; CHECK-NEXT: stp q1, q0, [x1]
325 %a = load <16 x i32>, ptr %in
326 %b = trunc <16 x i32> %a to <16 x i16>
327 %c = add <16 x i16> %b, %b
328 store <16 x i16> %c, ptr %out
332 ; NOTE: Extra 'add' is to prevent the truncate being combined with the store.
333 define void @trunc_v32i32_v32i16(ptr %in, ptr %out) nounwind {
334 ; CHECK-LABEL: trunc_v32i32_v32i16:
336 ; CHECK-NEXT: ldp q0, q1, [x0, #64]
337 ; CHECK-NEXT: ptrue p0.h, vl4
338 ; CHECK-NEXT: ldp q2, q3, [x0]
339 ; CHECK-NEXT: ldp q4, q5, [x0, #96]
340 ; CHECK-NEXT: ldp q6, q7, [x0, #32]
341 ; CHECK-NEXT: uzp1 z1.h, z1.h, z1.h
342 ; CHECK-NEXT: uzp1 z0.h, z0.h, z0.h
343 ; CHECK-NEXT: uzp1 z3.h, z3.h, z3.h
344 ; CHECK-NEXT: uzp1 z2.h, z2.h, z2.h
345 ; CHECK-NEXT: uzp1 z5.h, z5.h, z5.h
346 ; CHECK-NEXT: uzp1 z4.h, z4.h, z4.h
347 ; CHECK-NEXT: uzp1 z7.h, z7.h, z7.h
348 ; CHECK-NEXT: uzp1 z6.h, z6.h, z6.h
349 ; CHECK-NEXT: splice z0.h, p0, z0.h, z1.h
350 ; CHECK-NEXT: splice z2.h, p0, z2.h, z3.h
351 ; CHECK-NEXT: splice z4.h, p0, z4.h, z5.h
352 ; CHECK-NEXT: splice z6.h, p0, z6.h, z7.h
353 ; CHECK-NEXT: add z0.h, z0.h, z0.h
354 ; CHECK-NEXT: add z2.h, z2.h, z2.h
355 ; CHECK-NEXT: add z1.h, z4.h, z4.h
356 ; CHECK-NEXT: add z3.h, z6.h, z6.h
357 ; CHECK-NEXT: stp q0, q1, [x1, #32]
358 ; CHECK-NEXT: stp q2, q3, [x1]
360 %a = load <32 x i32>, ptr %in
361 %b = trunc <32 x i32> %a to <32 x i16>
362 %c = add <32 x i16> %b, %b
363 store <32 x i16> %c, ptr %out
367 ; NOTE: Extra 'add' is to prevent the truncate being combined with the store.
368 define void @trunc_v64i32_v64i16(ptr %in, ptr %out) nounwind {
369 ; CHECK-LABEL: trunc_v64i32_v64i16:
371 ; CHECK-NEXT: ldp q0, q1, [x0, #192]
372 ; CHECK-NEXT: ptrue p0.h, vl4
373 ; CHECK-NEXT: ldp q6, q7, [x0, #224]
374 ; CHECK-NEXT: ldp q2, q3, [x0, #32]
375 ; CHECK-NEXT: uzp1 z1.h, z1.h, z1.h
376 ; CHECK-NEXT: uzp1 z0.h, z0.h, z0.h
377 ; CHECK-NEXT: uzp1 z7.h, z7.h, z7.h
378 ; CHECK-NEXT: uzp1 z6.h, z6.h, z6.h
379 ; CHECK-NEXT: ldp q4, q5, [x0]
380 ; CHECK-NEXT: uzp1 z3.h, z3.h, z3.h
381 ; CHECK-NEXT: ldp q16, q17, [x0, #64]
382 ; CHECK-NEXT: uzp1 z2.h, z2.h, z2.h
383 ; CHECK-NEXT: ldp q18, q19, [x0, #128]
384 ; CHECK-NEXT: splice z0.h, p0, z0.h, z1.h
385 ; CHECK-NEXT: ldp q20, q21, [x0, #160]
386 ; CHECK-NEXT: splice z6.h, p0, z6.h, z7.h
387 ; CHECK-NEXT: ldp q22, q23, [x0, #96]
388 ; CHECK-NEXT: uzp1 z1.h, z17.h, z17.h
389 ; CHECK-NEXT: uzp1 z19.h, z19.h, z19.h
390 ; CHECK-NEXT: uzp1 z18.h, z18.h, z18.h
391 ; CHECK-NEXT: uzp1 z16.h, z16.h, z16.h
392 ; CHECK-NEXT: uzp1 z21.h, z21.h, z21.h
393 ; CHECK-NEXT: uzp1 z20.h, z20.h, z20.h
394 ; CHECK-NEXT: uzp1 z5.h, z5.h, z5.h
395 ; CHECK-NEXT: uzp1 z7.h, z23.h, z23.h
396 ; CHECK-NEXT: uzp1 z17.h, z22.h, z22.h
397 ; CHECK-NEXT: uzp1 z4.h, z4.h, z4.h
398 ; CHECK-NEXT: splice z2.h, p0, z2.h, z3.h
399 ; CHECK-NEXT: add z0.h, z0.h, z0.h
400 ; CHECK-NEXT: splice z18.h, p0, z18.h, z19.h
401 ; CHECK-NEXT: splice z16.h, p0, z16.h, z1.h
402 ; CHECK-NEXT: add z1.h, z6.h, z6.h
403 ; CHECK-NEXT: splice z20.h, p0, z20.h, z21.h
404 ; CHECK-NEXT: splice z17.h, p0, z17.h, z7.h
405 ; CHECK-NEXT: splice z4.h, p0, z4.h, z5.h
406 ; CHECK-NEXT: stp q0, q1, [x1, #96]
407 ; CHECK-NEXT: add z2.h, z2.h, z2.h
408 ; CHECK-NEXT: add z5.h, z18.h, z18.h
409 ; CHECK-NEXT: add z0.h, z16.h, z16.h
410 ; CHECK-NEXT: add z3.h, z20.h, z20.h
411 ; CHECK-NEXT: add z1.h, z17.h, z17.h
412 ; CHECK-NEXT: add z4.h, z4.h, z4.h
413 ; CHECK-NEXT: stp q5, q3, [x1, #64]
414 ; CHECK-NEXT: stp q4, q2, [x1]
415 ; CHECK-NEXT: stp q0, q1, [x1, #32]
417 %a = load <64 x i32>, ptr %in
418 %b = trunc <64 x i32> %a to <64 x i16>
419 %c = add <64 x i16> %b, %b
420 store <64 x i16> %c, ptr %out
428 ; NOTE: v4i8 is not legal so result i8 elements are held within i16 containers.
429 define <4 x i8> @trunc_v4i64_v4i8(ptr %in) nounwind {
430 ; CHECK-LABEL: trunc_v4i64_v4i8:
432 ; CHECK-NEXT: ldp q0, q1, [x0]
433 ; CHECK-NEXT: ptrue p0.s, vl2
434 ; CHECK-NEXT: uzp1 z1.s, z1.s, z1.s
435 ; CHECK-NEXT: uzp1 z0.s, z0.s, z0.s
436 ; CHECK-NEXT: splice z0.s, p0, z0.s, z1.s
437 ; CHECK-NEXT: uzp1 z0.h, z0.h, z0.h
438 ; CHECK-NEXT: // kill: def $d0 killed $d0 killed $z0
440 %a = load <4 x i64>, ptr %in
441 %b = trunc <4 x i64> %a to <4 x i8>
445 define <8 x i8> @trunc_v8i64_v8i8(ptr %in) nounwind {
446 ; CHECK-LABEL: trunc_v8i64_v8i8:
448 ; CHECK-NEXT: ldp q1, q0, [x0, #32]
449 ; CHECK-NEXT: ptrue p0.s, vl2
450 ; CHECK-NEXT: ldp q2, q3, [x0]
451 ; CHECK-NEXT: uzp1 z0.s, z0.s, z0.s
452 ; CHECK-NEXT: uzp1 z1.s, z1.s, z1.s
453 ; CHECK-NEXT: uzp1 z3.s, z3.s, z3.s
454 ; CHECK-NEXT: uzp1 z2.s, z2.s, z2.s
455 ; CHECK-NEXT: splice z1.s, p0, z1.s, z0.s
456 ; CHECK-NEXT: splice z2.s, p0, z2.s, z3.s
457 ; CHECK-NEXT: ptrue p0.h, vl4
458 ; CHECK-NEXT: uzp1 z0.h, z1.h, z1.h
459 ; CHECK-NEXT: uzp1 z1.h, z2.h, z2.h
460 ; CHECK-NEXT: splice z1.h, p0, z1.h, z0.h
461 ; CHECK-NEXT: uzp1 z0.b, z1.b, z1.b
462 ; CHECK-NEXT: // kill: def $d0 killed $d0 killed $z0
464 %a = load <8 x i64>, ptr %in
465 %b = trunc <8 x i64> %a to <8 x i8>
469 define <16 x i8> @trunc_v16i64_v16i8(ptr %in) nounwind {
470 ; CHECK-LABEL: trunc_v16i64_v16i8:
472 ; CHECK-NEXT: ldp q0, q1, [x0, #32]
473 ; CHECK-NEXT: ptrue p0.s, vl2
474 ; CHECK-NEXT: ldp q2, q3, [x0, #96]
475 ; CHECK-NEXT: ldp q4, q5, [x0, #64]
476 ; CHECK-NEXT: ldp q6, q7, [x0]
477 ; CHECK-NEXT: uzp1 z1.s, z1.s, z1.s
478 ; CHECK-NEXT: uzp1 z3.s, z3.s, z3.s
479 ; CHECK-NEXT: uzp1 z2.s, z2.s, z2.s
480 ; CHECK-NEXT: uzp1 z0.s, z0.s, z0.s
481 ; CHECK-NEXT: uzp1 z5.s, z5.s, z5.s
482 ; CHECK-NEXT: uzp1 z4.s, z4.s, z4.s
483 ; CHECK-NEXT: uzp1 z7.s, z7.s, z7.s
484 ; CHECK-NEXT: uzp1 z6.s, z6.s, z6.s
485 ; CHECK-NEXT: splice z2.s, p0, z2.s, z3.s
486 ; CHECK-NEXT: splice z0.s, p0, z0.s, z1.s
487 ; CHECK-NEXT: splice z4.s, p0, z4.s, z5.s
488 ; CHECK-NEXT: splice z6.s, p0, z6.s, z7.s
489 ; CHECK-NEXT: ptrue p0.h, vl4
490 ; CHECK-NEXT: uzp1 z1.h, z2.h, z2.h
491 ; CHECK-NEXT: uzp1 z0.h, z0.h, z0.h
492 ; CHECK-NEXT: uzp1 z2.h, z4.h, z4.h
493 ; CHECK-NEXT: uzp1 z3.h, z6.h, z6.h
494 ; CHECK-NEXT: splice z2.h, p0, z2.h, z1.h
495 ; CHECK-NEXT: splice z3.h, p0, z3.h, z0.h
496 ; CHECK-NEXT: ptrue p0.b, vl8
497 ; CHECK-NEXT: uzp1 z1.b, z2.b, z2.b
498 ; CHECK-NEXT: uzp1 z0.b, z3.b, z3.b
499 ; CHECK-NEXT: splice z0.b, p0, z0.b, z1.b
500 ; CHECK-NEXT: // kill: def $q0 killed $q0 killed $z0
502 %a = load <16 x i64>, ptr %in
503 %b = trunc <16 x i64> %a to <16 x i8>
507 ; NOTE: Extra 'add' is to prevent the truncate being combined with the store.
508 define void @trunc_v32i64_v32i8(ptr %in, ptr %out) nounwind {
509 ; CHECK-LABEL: trunc_v32i64_v32i8:
511 ; CHECK-NEXT: ldp q0, q1, [x0]
512 ; CHECK-NEXT: ptrue p0.s, vl2
513 ; CHECK-NEXT: ldp q2, q3, [x0, #224]
514 ; CHECK-NEXT: ldp q4, q5, [x0, #32]
515 ; CHECK-NEXT: ldp q6, q7, [x0, #64]
516 ; CHECK-NEXT: uzp1 z1.s, z1.s, z1.s
517 ; CHECK-NEXT: ldp q16, q17, [x0, #192]
518 ; CHECK-NEXT: uzp1 z3.s, z3.s, z3.s
519 ; CHECK-NEXT: ldp q18, q19, [x0, #128]
520 ; CHECK-NEXT: uzp1 z2.s, z2.s, z2.s
521 ; CHECK-NEXT: ldp q20, q21, [x0, #160]
522 ; CHECK-NEXT: uzp1 z7.s, z7.s, z7.s
523 ; CHECK-NEXT: ldp q22, q23, [x0, #96]
524 ; CHECK-NEXT: uzp1 z17.s, z17.s, z17.s
525 ; CHECK-NEXT: uzp1 z16.s, z16.s, z16.s
526 ; CHECK-NEXT: uzp1 z19.s, z19.s, z19.s
527 ; CHECK-NEXT: uzp1 z18.s, z18.s, z18.s
528 ; CHECK-NEXT: uzp1 z21.s, z21.s, z21.s
529 ; CHECK-NEXT: uzp1 z20.s, z20.s, z20.s
530 ; CHECK-NEXT: uzp1 z6.s, z6.s, z6.s
531 ; CHECK-NEXT: uzp1 z23.s, z23.s, z23.s
532 ; CHECK-NEXT: uzp1 z22.s, z22.s, z22.s
533 ; CHECK-NEXT: uzp1 z5.s, z5.s, z5.s
534 ; CHECK-NEXT: uzp1 z4.s, z4.s, z4.s
535 ; CHECK-NEXT: uzp1 z0.s, z0.s, z0.s
536 ; CHECK-NEXT: splice z2.s, p0, z2.s, z3.s
537 ; CHECK-NEXT: splice z16.s, p0, z16.s, z17.s
538 ; CHECK-NEXT: splice z18.s, p0, z18.s, z19.s
539 ; CHECK-NEXT: splice z20.s, p0, z20.s, z21.s
540 ; CHECK-NEXT: splice z6.s, p0, z6.s, z7.s
541 ; CHECK-NEXT: splice z22.s, p0, z22.s, z23.s
542 ; CHECK-NEXT: splice z4.s, p0, z4.s, z5.s
543 ; CHECK-NEXT: splice z0.s, p0, z0.s, z1.s
544 ; CHECK-NEXT: ptrue p0.h, vl4
545 ; CHECK-NEXT: uzp1 z1.h, z2.h, z2.h
546 ; CHECK-NEXT: uzp1 z2.h, z16.h, z16.h
547 ; CHECK-NEXT: uzp1 z5.h, z18.h, z18.h
548 ; CHECK-NEXT: uzp1 z3.h, z20.h, z20.h
549 ; CHECK-NEXT: uzp1 z6.h, z6.h, z6.h
550 ; CHECK-NEXT: uzp1 z7.h, z22.h, z22.h
551 ; CHECK-NEXT: uzp1 z4.h, z4.h, z4.h
552 ; CHECK-NEXT: uzp1 z0.h, z0.h, z0.h
553 ; CHECK-NEXT: splice z2.h, p0, z2.h, z1.h
554 ; CHECK-NEXT: splice z5.h, p0, z5.h, z3.h
555 ; CHECK-NEXT: splice z6.h, p0, z6.h, z7.h
556 ; CHECK-NEXT: splice z0.h, p0, z0.h, z4.h
557 ; CHECK-NEXT: ptrue p0.b, vl8
558 ; CHECK-NEXT: uzp1 z1.b, z2.b, z2.b
559 ; CHECK-NEXT: uzp1 z2.b, z5.b, z5.b
560 ; CHECK-NEXT: uzp1 z3.b, z6.b, z6.b
561 ; CHECK-NEXT: uzp1 z0.b, z0.b, z0.b
562 ; CHECK-NEXT: splice z2.b, p0, z2.b, z1.b
563 ; CHECK-NEXT: splice z0.b, p0, z0.b, z3.b
564 ; CHECK-NEXT: add z1.b, z2.b, z2.b
565 ; CHECK-NEXT: add z0.b, z0.b, z0.b
566 ; CHECK-NEXT: stp q0, q1, [x1]
568 %a = load <32 x i64>, ptr %in
569 %b = trunc <32 x i64> %a to <32 x i8>
570 %c = add <32 x i8> %b, %b
571 store <32 x i8> %c, ptr %out
576 ; truncate i64 -> i16
579 define <4 x i16> @trunc_v4i64_v4i16(ptr %in) nounwind {
580 ; CHECK-LABEL: trunc_v4i64_v4i16:
582 ; CHECK-NEXT: ldp q0, q1, [x0]
583 ; CHECK-NEXT: ptrue p0.s, vl2
584 ; CHECK-NEXT: uzp1 z1.s, z1.s, z1.s
585 ; CHECK-NEXT: uzp1 z0.s, z0.s, z0.s
586 ; CHECK-NEXT: splice z0.s, p0, z0.s, z1.s
587 ; CHECK-NEXT: uzp1 z0.h, z0.h, z0.h
588 ; CHECK-NEXT: // kill: def $d0 killed $d0 killed $z0
590 %a = load <4 x i64>, ptr %in
591 %b = trunc <4 x i64> %a to <4 x i16>
595 define <8 x i16> @trunc_v8i64_v8i16(ptr %in) nounwind {
596 ; CHECK-LABEL: trunc_v8i64_v8i16:
598 ; CHECK-NEXT: ldp q1, q0, [x0, #32]
599 ; CHECK-NEXT: ptrue p0.s, vl2
600 ; CHECK-NEXT: ldp q2, q3, [x0]
601 ; CHECK-NEXT: uzp1 z0.s, z0.s, z0.s
602 ; CHECK-NEXT: uzp1 z1.s, z1.s, z1.s
603 ; CHECK-NEXT: uzp1 z3.s, z3.s, z3.s
604 ; CHECK-NEXT: uzp1 z2.s, z2.s, z2.s
605 ; CHECK-NEXT: splice z1.s, p0, z1.s, z0.s
606 ; CHECK-NEXT: splice z2.s, p0, z2.s, z3.s
607 ; CHECK-NEXT: ptrue p0.h, vl4
608 ; CHECK-NEXT: uzp1 z1.h, z1.h, z1.h
609 ; CHECK-NEXT: uzp1 z0.h, z2.h, z2.h
610 ; CHECK-NEXT: splice z0.h, p0, z0.h, z1.h
611 ; CHECK-NEXT: // kill: def $q0 killed $q0 killed $z0
613 %a = load <8 x i64>, ptr %in
614 %b = trunc <8 x i64> %a to <8 x i16>
618 ; NOTE: Extra 'add' is to prevent the truncate being combined with the store.
619 define void @trunc_v16i64_v16i16(ptr %in, ptr %out) nounwind {
620 ; CHECK-LABEL: trunc_v16i64_v16i16:
622 ; CHECK-NEXT: ldp q0, q1, [x0, #32]
623 ; CHECK-NEXT: ptrue p0.s, vl2
624 ; CHECK-NEXT: ldp q2, q3, [x0, #96]
625 ; CHECK-NEXT: ldp q4, q5, [x0, #64]
626 ; CHECK-NEXT: ldp q6, q7, [x0]
627 ; CHECK-NEXT: uzp1 z1.s, z1.s, z1.s
628 ; CHECK-NEXT: uzp1 z3.s, z3.s, z3.s
629 ; CHECK-NEXT: uzp1 z2.s, z2.s, z2.s
630 ; CHECK-NEXT: uzp1 z0.s, z0.s, z0.s
631 ; CHECK-NEXT: uzp1 z5.s, z5.s, z5.s
632 ; CHECK-NEXT: uzp1 z4.s, z4.s, z4.s
633 ; CHECK-NEXT: uzp1 z7.s, z7.s, z7.s
634 ; CHECK-NEXT: uzp1 z6.s, z6.s, z6.s
635 ; CHECK-NEXT: splice z2.s, p0, z2.s, z3.s
636 ; CHECK-NEXT: splice z0.s, p0, z0.s, z1.s
637 ; CHECK-NEXT: splice z4.s, p0, z4.s, z5.s
638 ; CHECK-NEXT: splice z6.s, p0, z6.s, z7.s
639 ; CHECK-NEXT: ptrue p0.h, vl4
640 ; CHECK-NEXT: uzp1 z1.h, z2.h, z2.h
641 ; CHECK-NEXT: uzp1 z0.h, z0.h, z0.h
642 ; CHECK-NEXT: uzp1 z2.h, z4.h, z4.h
643 ; CHECK-NEXT: uzp1 z3.h, z6.h, z6.h
644 ; CHECK-NEXT: splice z2.h, p0, z2.h, z1.h
645 ; CHECK-NEXT: splice z3.h, p0, z3.h, z0.h
646 ; CHECK-NEXT: add z0.h, z2.h, z2.h
647 ; CHECK-NEXT: add z1.h, z3.h, z3.h
648 ; CHECK-NEXT: stp q1, q0, [x1]
650 %a = load <16 x i64>, ptr %in
651 %b = trunc <16 x i64> %a to <16 x i16>
652 %c = add <16 x i16> %b, %b
653 store <16 x i16> %c, ptr %out
657 ; NOTE: Extra 'add' is to prevent the truncate being combined with the store.
658 define void @trunc_v32i64_v32i16(ptr %in, ptr %out) nounwind {
659 ; CHECK-LABEL: trunc_v32i64_v32i16:
661 ; CHECK-NEXT: ldp q0, q1, [x0, #64]
662 ; CHECK-NEXT: ptrue p0.s, vl2
663 ; CHECK-NEXT: ldp q2, q3, [x0, #160]
664 ; CHECK-NEXT: ptrue p1.h, vl4
665 ; CHECK-NEXT: ldp q4, q5, [x0, #96]
666 ; CHECK-NEXT: ldp q6, q7, [x0]
667 ; CHECK-NEXT: uzp1 z1.s, z1.s, z1.s
668 ; CHECK-NEXT: ldp q16, q17, [x0, #128]
669 ; CHECK-NEXT: uzp1 z3.s, z3.s, z3.s
670 ; CHECK-NEXT: ldp q18, q19, [x0, #192]
671 ; CHECK-NEXT: uzp1 z2.s, z2.s, z2.s
672 ; CHECK-NEXT: ldp q20, q21, [x0, #224]
673 ; CHECK-NEXT: uzp1 z7.s, z7.s, z7.s
674 ; CHECK-NEXT: ldp q22, q23, [x0, #32]
675 ; CHECK-NEXT: uzp1 z17.s, z17.s, z17.s
676 ; CHECK-NEXT: uzp1 z16.s, z16.s, z16.s
677 ; CHECK-NEXT: uzp1 z19.s, z19.s, z19.s
678 ; CHECK-NEXT: uzp1 z18.s, z18.s, z18.s
679 ; CHECK-NEXT: uzp1 z21.s, z21.s, z21.s
680 ; CHECK-NEXT: uzp1 z20.s, z20.s, z20.s
681 ; CHECK-NEXT: uzp1 z6.s, z6.s, z6.s
682 ; CHECK-NEXT: uzp1 z23.s, z23.s, z23.s
683 ; CHECK-NEXT: uzp1 z22.s, z22.s, z22.s
684 ; CHECK-NEXT: uzp1 z5.s, z5.s, z5.s
685 ; CHECK-NEXT: uzp1 z4.s, z4.s, z4.s
686 ; CHECK-NEXT: uzp1 z0.s, z0.s, z0.s
687 ; CHECK-NEXT: splice z2.s, p0, z2.s, z3.s
688 ; CHECK-NEXT: splice z16.s, p0, z16.s, z17.s
689 ; CHECK-NEXT: splice z18.s, p0, z18.s, z19.s
690 ; CHECK-NEXT: splice z20.s, p0, z20.s, z21.s
691 ; CHECK-NEXT: splice z6.s, p0, z6.s, z7.s
692 ; CHECK-NEXT: splice z22.s, p0, z22.s, z23.s
693 ; CHECK-NEXT: splice z4.s, p0, z4.s, z5.s
694 ; CHECK-NEXT: splice z0.s, p0, z0.s, z1.s
695 ; CHECK-NEXT: uzp1 z1.h, z2.h, z2.h
696 ; CHECK-NEXT: uzp1 z2.h, z16.h, z16.h
697 ; CHECK-NEXT: uzp1 z5.h, z18.h, z18.h
698 ; CHECK-NEXT: uzp1 z3.h, z20.h, z20.h
699 ; CHECK-NEXT: uzp1 z6.h, z6.h, z6.h
700 ; CHECK-NEXT: uzp1 z7.h, z22.h, z22.h
701 ; CHECK-NEXT: uzp1 z4.h, z4.h, z4.h
702 ; CHECK-NEXT: uzp1 z0.h, z0.h, z0.h
703 ; CHECK-NEXT: splice z2.h, p1, z2.h, z1.h
704 ; CHECK-NEXT: splice z5.h, p1, z5.h, z3.h
705 ; CHECK-NEXT: splice z6.h, p1, z6.h, z7.h
706 ; CHECK-NEXT: splice z0.h, p1, z0.h, z4.h
707 ; CHECK-NEXT: add z1.h, z2.h, z2.h
708 ; CHECK-NEXT: add z2.h, z5.h, z5.h
709 ; CHECK-NEXT: add z3.h, z6.h, z6.h
710 ; CHECK-NEXT: add z0.h, z0.h, z0.h
711 ; CHECK-NEXT: stp q1, q2, [x1, #32]
712 ; CHECK-NEXT: stp q3, q0, [x1]
714 %a = load <32 x i64>, ptr %in
715 %b = trunc <32 x i64> %a to <32 x i16>
716 %c = add <32 x i16> %b, %b
717 store <32 x i16> %c, ptr %out
722 ; truncate i64 -> i32
725 define <4 x i32> @trunc_v4i64_v4i32(ptr %in) nounwind {
726 ; CHECK-LABEL: trunc_v4i64_v4i32:
728 ; CHECK-NEXT: ldp q0, q1, [x0]
729 ; CHECK-NEXT: ptrue p0.s, vl2
730 ; CHECK-NEXT: uzp1 z1.s, z1.s, z1.s
731 ; CHECK-NEXT: uzp1 z0.s, z0.s, z0.s
732 ; CHECK-NEXT: splice z0.s, p0, z0.s, z1.s
733 ; CHECK-NEXT: // kill: def $q0 killed $q0 killed $z0
735 %a = load <4 x i64>, ptr %in
736 %b = trunc <4 x i64> %a to <4 x i32>
740 ; NOTE: Extra 'add' is to prevent the truncate being combined with the store.
741 define void @trunc_v8i64_v8i32(ptr %in, ptr %out) nounwind {
742 ; CHECK-LABEL: trunc_v8i64_v8i32:
744 ; CHECK-NEXT: ldp q0, q1, [x0, #32]
745 ; CHECK-NEXT: ptrue p0.s, vl2
746 ; CHECK-NEXT: ldp q2, q3, [x0]
747 ; CHECK-NEXT: uzp1 z1.s, z1.s, z1.s
748 ; CHECK-NEXT: uzp1 z0.s, z0.s, z0.s
749 ; CHECK-NEXT: uzp1 z3.s, z3.s, z3.s
750 ; CHECK-NEXT: uzp1 z2.s, z2.s, z2.s
751 ; CHECK-NEXT: splice z0.s, p0, z0.s, z1.s
752 ; CHECK-NEXT: splice z2.s, p0, z2.s, z3.s
753 ; CHECK-NEXT: add z0.s, z0.s, z0.s
754 ; CHECK-NEXT: add z1.s, z2.s, z2.s
755 ; CHECK-NEXT: stp q1, q0, [x1]
757 %a = load <8 x i64>, ptr %in
758 %b = trunc <8 x i64> %a to <8 x i32>
759 %c = add <8 x i32> %b, %b
760 store <8 x i32> %c, ptr %out
764 ; NOTE: Extra 'add' is to prevent the truncate being combined with the store.
765 define void @trunc_v16i64_v16i32(ptr %in, ptr %out) nounwind {
766 ; CHECK-LABEL: trunc_v16i64_v16i32:
768 ; CHECK-NEXT: ldp q0, q1, [x0, #64]
769 ; CHECK-NEXT: ptrue p0.s, vl2
770 ; CHECK-NEXT: ldp q2, q3, [x0]
771 ; CHECK-NEXT: ldp q4, q5, [x0, #96]
772 ; CHECK-NEXT: ldp q6, q7, [x0, #32]
773 ; CHECK-NEXT: uzp1 z1.s, z1.s, z1.s
774 ; CHECK-NEXT: uzp1 z0.s, z0.s, z0.s
775 ; CHECK-NEXT: uzp1 z3.s, z3.s, z3.s
776 ; CHECK-NEXT: uzp1 z2.s, z2.s, z2.s
777 ; CHECK-NEXT: uzp1 z5.s, z5.s, z5.s
778 ; CHECK-NEXT: uzp1 z4.s, z4.s, z4.s
779 ; CHECK-NEXT: uzp1 z7.s, z7.s, z7.s
780 ; CHECK-NEXT: uzp1 z6.s, z6.s, z6.s
781 ; CHECK-NEXT: splice z0.s, p0, z0.s, z1.s
782 ; CHECK-NEXT: splice z2.s, p0, z2.s, z3.s
783 ; CHECK-NEXT: splice z4.s, p0, z4.s, z5.s
784 ; CHECK-NEXT: splice z6.s, p0, z6.s, z7.s
785 ; CHECK-NEXT: add z0.s, z0.s, z0.s
786 ; CHECK-NEXT: add z2.s, z2.s, z2.s
787 ; CHECK-NEXT: add z1.s, z4.s, z4.s
788 ; CHECK-NEXT: add z3.s, z6.s, z6.s
789 ; CHECK-NEXT: stp q0, q1, [x1, #32]
790 ; CHECK-NEXT: stp q2, q3, [x1]
792 %a = load <16 x i64>, ptr %in
793 %b = trunc <16 x i64> %a to <16 x i32>
794 %c = add <16 x i32> %b, %b
795 store <16 x i32> %c, ptr %out
799 ; NOTE: Extra 'add' is to prevent the truncate being combined with the store.
800 define void @trunc_v32i64_v32i32(ptr %in, ptr %out) nounwind {
801 ; CHECK-LABEL: trunc_v32i64_v32i32:
803 ; CHECK-NEXT: ldp q0, q1, [x0, #192]
804 ; CHECK-NEXT: ptrue p0.s, vl2
805 ; CHECK-NEXT: ldp q6, q7, [x0, #224]
806 ; CHECK-NEXT: ldp q2, q3, [x0, #32]
807 ; CHECK-NEXT: uzp1 z1.s, z1.s, z1.s
808 ; CHECK-NEXT: uzp1 z0.s, z0.s, z0.s
809 ; CHECK-NEXT: uzp1 z7.s, z7.s, z7.s
810 ; CHECK-NEXT: uzp1 z6.s, z6.s, z6.s
811 ; CHECK-NEXT: ldp q4, q5, [x0]
812 ; CHECK-NEXT: uzp1 z3.s, z3.s, z3.s
813 ; CHECK-NEXT: ldp q16, q17, [x0, #64]
814 ; CHECK-NEXT: uzp1 z2.s, z2.s, z2.s
815 ; CHECK-NEXT: ldp q18, q19, [x0, #128]
816 ; CHECK-NEXT: splice z0.s, p0, z0.s, z1.s
817 ; CHECK-NEXT: ldp q20, q21, [x0, #160]
818 ; CHECK-NEXT: splice z6.s, p0, z6.s, z7.s
819 ; CHECK-NEXT: ldp q22, q23, [x0, #96]
820 ; CHECK-NEXT: uzp1 z1.s, z17.s, z17.s
821 ; CHECK-NEXT: uzp1 z19.s, z19.s, z19.s
822 ; CHECK-NEXT: uzp1 z18.s, z18.s, z18.s
823 ; CHECK-NEXT: uzp1 z16.s, z16.s, z16.s
824 ; CHECK-NEXT: uzp1 z21.s, z21.s, z21.s
825 ; CHECK-NEXT: uzp1 z20.s, z20.s, z20.s
826 ; CHECK-NEXT: uzp1 z5.s, z5.s, z5.s
827 ; CHECK-NEXT: uzp1 z7.s, z23.s, z23.s
828 ; CHECK-NEXT: uzp1 z17.s, z22.s, z22.s
829 ; CHECK-NEXT: uzp1 z4.s, z4.s, z4.s
830 ; CHECK-NEXT: splice z2.s, p0, z2.s, z3.s
831 ; CHECK-NEXT: add z0.s, z0.s, z0.s
832 ; CHECK-NEXT: splice z18.s, p0, z18.s, z19.s
833 ; CHECK-NEXT: splice z16.s, p0, z16.s, z1.s
834 ; CHECK-NEXT: add z1.s, z6.s, z6.s
835 ; CHECK-NEXT: splice z20.s, p0, z20.s, z21.s
836 ; CHECK-NEXT: splice z17.s, p0, z17.s, z7.s
837 ; CHECK-NEXT: splice z4.s, p0, z4.s, z5.s
838 ; CHECK-NEXT: stp q0, q1, [x1, #96]
839 ; CHECK-NEXT: add z2.s, z2.s, z2.s
840 ; CHECK-NEXT: add z5.s, z18.s, z18.s
841 ; CHECK-NEXT: add z0.s, z16.s, z16.s
842 ; CHECK-NEXT: add z3.s, z20.s, z20.s
843 ; CHECK-NEXT: add z1.s, z17.s, z17.s
844 ; CHECK-NEXT: add z4.s, z4.s, z4.s
845 ; CHECK-NEXT: stp q5, q3, [x1, #64]
846 ; CHECK-NEXT: stp q4, q2, [x1]
847 ; CHECK-NEXT: stp q0, q1, [x1, #32]
849 %a = load <32 x i64>, ptr %in
850 %b = trunc <32 x i64> %a to <32 x i32>
851 %c = add <32 x i32> %b, %b
852 store <32 x i32> %c, ptr %out