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