[clang][modules] Don't prevent translation of FW_Private includes when explicitly...
[llvm-project.git] / llvm / test / CodeGen / AArch64 / sve-streaming-mode-fixed-length-int-extends.ll
blobc7a89612d278f20ca06a238b682548b6c030d412
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 --check-prefixes=CHECK,SVE
3 ; RUN: llc -mattr=+sve2 -force-streaming-compatible-sve  < %s | FileCheck %s --check-prefixes=CHECK,SVE2
4 ; RUN: llc -mattr=+sme -force-streaming-compatible-sve  < %s | FileCheck %s --check-prefixes=CHECK,SVE2
6 target triple = "aarch64-unknown-linux-gnu"
9 ; sext i1 -> i32
12 ; NOTE: Covers the scenario where a SIGN_EXTEND_INREG is required, whose inreg
13 ; type's element type is not byte based and thus cannot be lowered directly to
14 ; an SVE instruction.
15 define void @sext_v8i1_v8i32(<8 x i1> %a, ptr %out) {
16 ; CHECK-LABEL: sext_v8i1_v8i32:
17 ; CHECK:       // %bb.0:
18 ; CHECK-NEXT:    // kill: def $d0 killed $d0 def $z0
19 ; CHECK-NEXT:    uunpklo z0.h, z0.b
20 ; CHECK-NEXT:    uunpklo z1.s, z0.h
21 ; CHECK-NEXT:    ext z0.b, z0.b, z0.b, #8
22 ; CHECK-NEXT:    uunpklo z0.s, z0.h
23 ; CHECK-NEXT:    lsl z1.s, z1.s, #31
24 ; CHECK-NEXT:    lsl z0.s, z0.s, #31
25 ; CHECK-NEXT:    asr z1.s, z1.s, #31
26 ; CHECK-NEXT:    asr z0.s, z0.s, #31
27 ; CHECK-NEXT:    stp q1, q0, [x0]
28 ; CHECK-NEXT:    ret
29   %b = sext <8 x i1> %a to <8 x i32>
30   store <8 x i32> %b, ptr %out
31   ret void
35 ; sext i3 -> i64
38 ; NOTE: Covers the scenario where a SIGN_EXTEND_INREG is required, whose inreg
39 ; type's element type is not power-of-2 based and thus cannot be lowered
40 ; directly to an SVE instruction.
41 define void @sext_v4i3_v4i64(<4 x i3> %a, ptr %out) {
42 ; CHECK-LABEL: sext_v4i3_v4i64:
43 ; CHECK:       // %bb.0:
44 ; CHECK-NEXT:    // kill: def $d0 killed $d0 def $z0
45 ; CHECK-NEXT:    uunpklo z0.s, z0.h
46 ; CHECK-NEXT:    uunpklo z1.d, z0.s
47 ; CHECK-NEXT:    ext z0.b, z0.b, z0.b, #8
48 ; CHECK-NEXT:    uunpklo z0.d, z0.s
49 ; CHECK-NEXT:    lsl z1.d, z1.d, #61
50 ; CHECK-NEXT:    lsl z0.d, z0.d, #61
51 ; CHECK-NEXT:    asr z1.d, z1.d, #61
52 ; CHECK-NEXT:    asr z0.d, z0.d, #61
53 ; CHECK-NEXT:    stp q1, q0, [x0]
54 ; CHECK-NEXT:    ret
55   %b = sext <4 x i3> %a to <4 x i64>
56   store <4 x i64> %b, ptr %out
57   ret void
61 ; sext i8 -> i16
64 define void @sext_v16i8_v16i16(<16 x i8> %a, ptr %out) {
65 ; CHECK-LABEL: sext_v16i8_v16i16:
66 ; CHECK:       // %bb.0:
67 ; CHECK-NEXT:    // kill: def $q0 killed $q0 def $z0
68 ; CHECK-NEXT:    sunpklo z1.h, z0.b
69 ; CHECK-NEXT:    ext z0.b, z0.b, z0.b, #8
70 ; CHECK-NEXT:    sunpklo z0.h, z0.b
71 ; CHECK-NEXT:    stp q1, q0, [x0]
72 ; CHECK-NEXT:    ret
73   %b = sext <16 x i8> %a to <16 x i16>
74   store <16 x i16>%b, ptr %out
75   ret void
78 ; NOTE: Extra 'add' is to prevent the extend being combined with the load.
79 define void @sext_v32i8_v32i16(ptr %in, ptr %out) {
80 ; CHECK-LABEL: sext_v32i8_v32i16:
81 ; CHECK:       // %bb.0:
82 ; CHECK-NEXT:    ldp q1, q0, [x0]
83 ; CHECK-NEXT:    add z0.b, z0.b, z0.b
84 ; CHECK-NEXT:    add z1.b, z1.b, z1.b
85 ; CHECK-NEXT:    sunpklo z2.h, z0.b
86 ; CHECK-NEXT:    ext z0.b, z0.b, z0.b, #8
87 ; CHECK-NEXT:    sunpklo z3.h, z1.b
88 ; CHECK-NEXT:    ext z1.b, z1.b, z1.b, #8
89 ; CHECK-NEXT:    sunpklo z0.h, z0.b
90 ; CHECK-NEXT:    sunpklo z1.h, z1.b
91 ; CHECK-NEXT:    stp q2, q0, [x1, #32]
92 ; CHECK-NEXT:    stp q3, q1, [x1]
93 ; CHECK-NEXT:    ret
94   %a = load <32 x i8>, ptr %in
95   %b = add <32 x i8> %a, %a
96   %c = sext <32 x i8> %b to <32 x i16>
97   store <32 x i16> %c, ptr %out
98   ret void
102 ; sext i8 -> i32
105 define void @sext_v8i8_v8i32(<8 x i8> %a, ptr %out) {
106 ; CHECK-LABEL: sext_v8i8_v8i32:
107 ; CHECK:       // %bb.0:
108 ; CHECK-NEXT:    // kill: def $d0 killed $d0 def $z0
109 ; CHECK-NEXT:    sunpklo z0.h, z0.b
110 ; CHECK-NEXT:    sunpklo z1.s, z0.h
111 ; CHECK-NEXT:    ext z0.b, z0.b, z0.b, #8
112 ; CHECK-NEXT:    sunpklo z0.s, z0.h
113 ; CHECK-NEXT:    stp q1, q0, [x0]
114 ; CHECK-NEXT:    ret
115   %b = sext <8 x i8> %a to <8 x i32>
116   store <8 x i32>%b, ptr %out
117   ret void
120 define void @sext_v16i8_v16i32(<16 x i8> %a, ptr %out) {
121 ; CHECK-LABEL: sext_v16i8_v16i32:
122 ; CHECK:       // %bb.0:
123 ; CHECK-NEXT:    // kill: def $q0 killed $q0 def $z0
124 ; CHECK-NEXT:    sunpklo z1.h, z0.b
125 ; CHECK-NEXT:    ext z0.b, z0.b, z0.b, #8
126 ; CHECK-NEXT:    sunpklo z0.h, z0.b
127 ; CHECK-NEXT:    sunpklo z2.s, z1.h
128 ; CHECK-NEXT:    ext z1.b, z1.b, z1.b, #8
129 ; CHECK-NEXT:    sunpklo z1.s, z1.h
130 ; CHECK-NEXT:    sunpklo z3.s, z0.h
131 ; CHECK-NEXT:    ext z0.b, z0.b, z0.b, #8
132 ; CHECK-NEXT:    sunpklo z0.s, z0.h
133 ; CHECK-NEXT:    stp q2, q1, [x0]
134 ; CHECK-NEXT:    stp q3, q0, [x0, #32]
135 ; CHECK-NEXT:    ret
136   %b = sext <16 x i8> %a to <16 x i32>
137   store <16 x i32> %b, ptr %out
138   ret void
141 define void @sext_v32i8_v32i32(ptr %in, ptr %out) {
142 ; CHECK-LABEL: sext_v32i8_v32i32:
143 ; CHECK:       // %bb.0:
144 ; CHECK-NEXT:    ldp q1, q0, [x0]
145 ; CHECK-NEXT:    add z0.b, z0.b, z0.b
146 ; CHECK-NEXT:    add z1.b, z1.b, z1.b
147 ; CHECK-NEXT:    sunpklo z2.h, z0.b
148 ; CHECK-NEXT:    ext z0.b, z0.b, z0.b, #8
149 ; CHECK-NEXT:    sunpklo z3.h, z1.b
150 ; CHECK-NEXT:    ext z1.b, z1.b, z1.b, #8
151 ; CHECK-NEXT:    sunpklo z0.h, z0.b
152 ; CHECK-NEXT:    sunpklo z1.h, z1.b
153 ; CHECK-NEXT:    sunpklo z4.s, z2.h
154 ; CHECK-NEXT:    ext z2.b, z2.b, z2.b, #8
155 ; CHECK-NEXT:    sunpklo z5.s, z3.h
156 ; CHECK-NEXT:    ext z3.b, z3.b, z3.b, #8
157 ; CHECK-NEXT:    sunpklo z6.s, z0.h
158 ; CHECK-NEXT:    ext z0.b, z0.b, z0.b, #8
159 ; CHECK-NEXT:    sunpklo z2.s, z2.h
160 ; CHECK-NEXT:    sunpklo z7.s, z1.h
161 ; CHECK-NEXT:    ext z1.b, z1.b, z1.b, #8
162 ; CHECK-NEXT:    sunpklo z3.s, z3.h
163 ; CHECK-NEXT:    sunpklo z0.s, z0.h
164 ; CHECK-NEXT:    sunpklo z1.s, z1.h
165 ; CHECK-NEXT:    stp q4, q2, [x1, #64]
166 ; CHECK-NEXT:    stp q5, q3, [x1]
167 ; CHECK-NEXT:    stp q6, q0, [x1, #96]
168 ; CHECK-NEXT:    stp q7, q1, [x1, #32]
169 ; CHECK-NEXT:    ret
170   %a = load <32 x i8>, ptr %in
171   %b = add <32 x i8> %a, %a
172   %c = sext <32 x i8> %b to <32 x i32>
173   store <32 x i32> %c, ptr %out
174   ret void
178 ; sext i8 -> i64
181 ; NOTE: v4i8 is an unpacked typed stored within a v4i16 container. The sign
182 ; extend is a two step process where the container is any_extend'd with the
183 ; result feeding an inreg sign extend.
184 define void @sext_v4i8_v4i64(<4 x i8> %a, ptr %out) {
185 ; CHECK-LABEL: sext_v4i8_v4i64:
186 ; CHECK:       // %bb.0:
187 ; CHECK-NEXT:    // kill: def $d0 killed $d0 def $z0
188 ; CHECK-NEXT:    ptrue p0.d, vl2
189 ; CHECK-NEXT:    uunpklo z0.s, z0.h
190 ; CHECK-NEXT:    uunpklo z1.d, z0.s
191 ; CHECK-NEXT:    ext z0.b, z0.b, z0.b, #8
192 ; CHECK-NEXT:    uunpklo z0.d, z0.s
193 ; CHECK-NEXT:    sxtb z1.d, p0/m, z1.d
194 ; CHECK-NEXT:    sxtb z0.d, p0/m, z0.d
195 ; CHECK-NEXT:    stp q1, q0, [x0]
196 ; CHECK-NEXT:    ret
197   %b = sext <4 x i8> %a to <4 x i64>
198   store <4 x i64>%b, ptr %out
199   ret void
202 define void @sext_v8i8_v8i64(<8 x i8> %a, ptr %out) {
203 ; CHECK-LABEL: sext_v8i8_v8i64:
204 ; CHECK:       // %bb.0:
205 ; CHECK-NEXT:    // kill: def $d0 killed $d0 def $z0
206 ; CHECK-NEXT:    sunpklo z0.h, z0.b
207 ; CHECK-NEXT:    sunpklo z1.s, z0.h
208 ; CHECK-NEXT:    ext z0.b, z0.b, z0.b, #8
209 ; CHECK-NEXT:    sunpklo z0.s, z0.h
210 ; CHECK-NEXT:    sunpklo z2.d, z1.s
211 ; CHECK-NEXT:    ext z1.b, z1.b, z1.b, #8
212 ; CHECK-NEXT:    sunpklo z3.d, z0.s
213 ; CHECK-NEXT:    ext z0.b, z0.b, z0.b, #8
214 ; CHECK-NEXT:    sunpklo z1.d, z1.s
215 ; CHECK-NEXT:    sunpklo z0.d, z0.s
216 ; CHECK-NEXT:    stp q2, q1, [x0]
217 ; CHECK-NEXT:    stp q3, q0, [x0, #32]
218 ; CHECK-NEXT:    ret
219   %b = sext <8 x i8> %a to <8 x i64>
220   store <8 x i64>%b, ptr %out
221   ret void
224 define void @sext_v16i8_v16i64(<16 x i8> %a, ptr %out) {
225 ; CHECK-LABEL: sext_v16i8_v16i64:
226 ; CHECK:       // %bb.0:
227 ; CHECK-NEXT:    // kill: def $q0 killed $q0 def $z0
228 ; CHECK-NEXT:    sunpklo z1.h, z0.b
229 ; CHECK-NEXT:    ext z0.b, z0.b, z0.b, #8
230 ; CHECK-NEXT:    sunpklo z0.h, z0.b
231 ; CHECK-NEXT:    sunpklo z2.s, z1.h
232 ; CHECK-NEXT:    ext z1.b, z1.b, z1.b, #8
233 ; CHECK-NEXT:    sunpklo z1.s, z1.h
234 ; CHECK-NEXT:    sunpklo z3.s, z0.h
235 ; CHECK-NEXT:    ext z0.b, z0.b, z0.b, #8
236 ; CHECK-NEXT:    sunpklo z4.d, z2.s
237 ; CHECK-NEXT:    ext z2.b, z2.b, z2.b, #8
238 ; CHECK-NEXT:    sunpklo z0.s, z0.h
239 ; CHECK-NEXT:    mov z7.d, z1.d
240 ; CHECK-NEXT:    sunpklo z2.d, z2.s
241 ; CHECK-NEXT:    sunpklo z5.d, z3.s
242 ; CHECK-NEXT:    ext z3.b, z3.b, z3.b, #8
243 ; CHECK-NEXT:    ext z7.b, z7.b, z1.b, #8
244 ; CHECK-NEXT:    sunpklo z1.d, z1.s
245 ; CHECK-NEXT:    mov z6.d, z0.d
246 ; CHECK-NEXT:    sunpklo z3.d, z3.s
247 ; CHECK-NEXT:    stp q4, q2, [x0]
248 ; CHECK-NEXT:    sunpklo z4.d, z7.s
249 ; CHECK-NEXT:    ext z6.b, z6.b, z0.b, #8
250 ; CHECK-NEXT:    sunpklo z0.d, z0.s
251 ; CHECK-NEXT:    stp q5, q3, [x0, #64]
252 ; CHECK-NEXT:    sunpklo z2.d, z6.s
253 ; CHECK-NEXT:    stp q1, q4, [x0, #32]
254 ; CHECK-NEXT:    stp q0, q2, [x0, #96]
255 ; CHECK-NEXT:    ret
256   %b = sext <16 x i8> %a to <16 x i64>
257   store <16 x i64> %b, ptr %out
258   ret void
261 define void @sext_v32i8_v32i64(ptr %in, ptr %out) {
262 ; CHECK-LABEL: sext_v32i8_v32i64:
263 ; CHECK:       // %bb.0:
264 ; CHECK-NEXT:    ldp q1, q0, [x0]
265 ; CHECK-NEXT:    add z0.b, z0.b, z0.b
266 ; CHECK-NEXT:    add z1.b, z1.b, z1.b
267 ; CHECK-NEXT:    mov z2.d, z0.d
268 ; CHECK-NEXT:    sunpklo z0.h, z0.b
269 ; CHECK-NEXT:    mov z3.d, z1.d
270 ; CHECK-NEXT:    sunpklo z1.h, z1.b
271 ; CHECK-NEXT:    ext z2.b, z2.b, z2.b, #8
272 ; CHECK-NEXT:    ext z3.b, z3.b, z3.b, #8
273 ; CHECK-NEXT:    sunpklo z4.s, z0.h
274 ; CHECK-NEXT:    ext z0.b, z0.b, z0.b, #8
275 ; CHECK-NEXT:    sunpklo z5.s, z1.h
276 ; CHECK-NEXT:    ext z1.b, z1.b, z1.b, #8
277 ; CHECK-NEXT:    sunpklo z2.h, z2.b
278 ; CHECK-NEXT:    sunpklo z3.h, z3.b
279 ; CHECK-NEXT:    sunpklo z0.s, z0.h
280 ; CHECK-NEXT:    sunpklo z16.d, z4.s
281 ; CHECK-NEXT:    ext z4.b, z4.b, z4.b, #8
282 ; CHECK-NEXT:    sunpklo z1.s, z1.h
283 ; CHECK-NEXT:    sunpklo z17.d, z5.s
284 ; CHECK-NEXT:    ext z5.b, z5.b, z5.b, #8
285 ; CHECK-NEXT:    sunpklo z6.s, z2.h
286 ; CHECK-NEXT:    sunpklo z7.s, z3.h
287 ; CHECK-NEXT:    ext z2.b, z2.b, z2.b, #8
288 ; CHECK-NEXT:    sunpklo z4.d, z4.s
289 ; CHECK-NEXT:    ext z3.b, z3.b, z3.b, #8
290 ; CHECK-NEXT:    sunpklo z19.d, z0.s
291 ; CHECK-NEXT:    sunpklo z5.d, z5.s
292 ; CHECK-NEXT:    ext z0.b, z0.b, z0.b, #8
293 ; CHECK-NEXT:    sunpklo z2.s, z2.h
294 ; CHECK-NEXT:    sunpklo z18.d, z6.s
295 ; CHECK-NEXT:    ext z6.b, z6.b, z6.b, #8
296 ; CHECK-NEXT:    sunpklo z3.s, z3.h
297 ; CHECK-NEXT:    stp q16, q4, [x1, #128]
298 ; CHECK-NEXT:    mov z16.d, z7.d
299 ; CHECK-NEXT:    sunpklo z0.d, z0.s
300 ; CHECK-NEXT:    stp q17, q5, [x1]
301 ; CHECK-NEXT:    sunpklo z5.d, z7.s
302 ; CHECK-NEXT:    sunpklo z4.d, z6.s
303 ; CHECK-NEXT:    mov z6.d, z1.d
304 ; CHECK-NEXT:    ext z16.b, z16.b, z7.b, #8
305 ; CHECK-NEXT:    mov z7.d, z2.d
306 ; CHECK-NEXT:    stp q19, q0, [x1, #160]
307 ; CHECK-NEXT:    sunpklo z0.d, z2.s
308 ; CHECK-NEXT:    ext z6.b, z6.b, z1.b, #8
309 ; CHECK-NEXT:    sunpklo z1.d, z1.s
310 ; CHECK-NEXT:    stp q18, q4, [x1, #192]
311 ; CHECK-NEXT:    mov z4.d, z3.d
312 ; CHECK-NEXT:    ext z7.b, z7.b, z2.b, #8
313 ; CHECK-NEXT:    sunpklo z16.d, z16.s
314 ; CHECK-NEXT:    sunpklo z6.d, z6.s
315 ; CHECK-NEXT:    ext z4.b, z4.b, z3.b, #8
316 ; CHECK-NEXT:    sunpklo z2.d, z7.s
317 ; CHECK-NEXT:    sunpklo z3.d, z3.s
318 ; CHECK-NEXT:    stp q5, q16, [x1, #64]
319 ; CHECK-NEXT:    stp q1, q6, [x1, #32]
320 ; CHECK-NEXT:    sunpklo z1.d, z4.s
321 ; CHECK-NEXT:    stp q0, q2, [x1, #224]
322 ; CHECK-NEXT:    stp q3, q1, [x1, #96]
323 ; CHECK-NEXT:    ret
324   %a = load <32 x i8>, ptr %in
325   %b = add <32 x i8> %a, %a
326   %c = sext <32 x i8> %b to <32 x i64>
327   store <32 x i64> %c, ptr %out
328   ret void
332 ; sext i16 -> i32
335 define void @sext_v8i16_v8i32(<8 x i16> %a, ptr %out) {
336 ; CHECK-LABEL: sext_v8i16_v8i32:
337 ; CHECK:       // %bb.0:
338 ; CHECK-NEXT:    // kill: def $q0 killed $q0 def $z0
339 ; CHECK-NEXT:    sunpklo z1.s, z0.h
340 ; CHECK-NEXT:    ext z0.b, z0.b, z0.b, #8
341 ; CHECK-NEXT:    sunpklo z0.s, z0.h
342 ; CHECK-NEXT:    stp q1, q0, [x0]
343 ; CHECK-NEXT:    ret
344   %b = sext <8 x i16> %a to <8 x i32>
345   store <8 x i32>%b, ptr %out
346   ret void
349 define void @sext_v16i16_v16i32(ptr %in, ptr %out) {
350 ; CHECK-LABEL: sext_v16i16_v16i32:
351 ; CHECK:       // %bb.0:
352 ; CHECK-NEXT:    ldp q1, q0, [x0]
353 ; CHECK-NEXT:    add z0.h, z0.h, z0.h
354 ; CHECK-NEXT:    add z1.h, z1.h, z1.h
355 ; CHECK-NEXT:    sunpklo z2.s, z0.h
356 ; CHECK-NEXT:    ext z0.b, z0.b, z0.b, #8
357 ; CHECK-NEXT:    sunpklo z3.s, z1.h
358 ; CHECK-NEXT:    ext z1.b, z1.b, z1.b, #8
359 ; CHECK-NEXT:    sunpklo z0.s, z0.h
360 ; CHECK-NEXT:    sunpklo z1.s, z1.h
361 ; CHECK-NEXT:    stp q2, q0, [x1, #32]
362 ; CHECK-NEXT:    stp q3, q1, [x1]
363 ; CHECK-NEXT:    ret
364   %a = load <16 x i16>, ptr %in
365   %b = add <16 x i16> %a, %a
366   %c = sext <16 x i16> %b to <16 x i32>
367   store <16 x i32> %c, ptr %out
368   ret void
372 ; sext i16 -> i64
375 define void @sext_v4i16_v4i64(<4 x i16> %a, ptr %out) {
376 ; CHECK-LABEL: sext_v4i16_v4i64:
377 ; CHECK:       // %bb.0:
378 ; CHECK-NEXT:    // kill: def $d0 killed $d0 def $z0
379 ; CHECK-NEXT:    sunpklo z0.s, z0.h
380 ; CHECK-NEXT:    sunpklo z1.d, z0.s
381 ; CHECK-NEXT:    ext z0.b, z0.b, z0.b, #8
382 ; CHECK-NEXT:    sunpklo z0.d, z0.s
383 ; CHECK-NEXT:    stp q1, q0, [x0]
384 ; CHECK-NEXT:    ret
385   %b = sext <4 x i16> %a to <4 x i64>
386   store <4 x i64>%b, ptr %out
387   ret void
390 define void @sext_v8i16_v8i64(<8 x i16> %a, ptr %out) {
391 ; CHECK-LABEL: sext_v8i16_v8i64:
392 ; CHECK:       // %bb.0:
393 ; CHECK-NEXT:    // kill: def $q0 killed $q0 def $z0
394 ; CHECK-NEXT:    sunpklo z1.s, z0.h
395 ; CHECK-NEXT:    ext z0.b, z0.b, z0.b, #8
396 ; CHECK-NEXT:    sunpklo z0.s, z0.h
397 ; CHECK-NEXT:    sunpklo z2.d, z1.s
398 ; CHECK-NEXT:    ext z1.b, z1.b, z1.b, #8
399 ; CHECK-NEXT:    sunpklo z1.d, z1.s
400 ; CHECK-NEXT:    sunpklo z3.d, z0.s
401 ; CHECK-NEXT:    ext z0.b, z0.b, z0.b, #8
402 ; CHECK-NEXT:    sunpklo z0.d, z0.s
403 ; CHECK-NEXT:    stp q2, q1, [x0]
404 ; CHECK-NEXT:    stp q3, q0, [x0, #32]
405 ; CHECK-NEXT:    ret
406   %b = sext <8 x i16> %a to <8 x i64>
407   store <8 x i64>%b, ptr %out
408   ret void
411 define void @sext_v16i16_v16i64(ptr %in, ptr %out) {
412 ; CHECK-LABEL: sext_v16i16_v16i64:
413 ; CHECK:       // %bb.0:
414 ; CHECK-NEXT:    ldp q1, q0, [x0]
415 ; CHECK-NEXT:    add z0.h, z0.h, z0.h
416 ; CHECK-NEXT:    add z1.h, z1.h, z1.h
417 ; CHECK-NEXT:    sunpklo z2.s, z0.h
418 ; CHECK-NEXT:    ext z0.b, z0.b, z0.b, #8
419 ; CHECK-NEXT:    sunpklo z3.s, z1.h
420 ; CHECK-NEXT:    ext z1.b, z1.b, z1.b, #8
421 ; CHECK-NEXT:    sunpklo z0.s, z0.h
422 ; CHECK-NEXT:    sunpklo z1.s, z1.h
423 ; CHECK-NEXT:    sunpklo z4.d, z2.s
424 ; CHECK-NEXT:    ext z2.b, z2.b, z2.b, #8
425 ; CHECK-NEXT:    sunpklo z5.d, z3.s
426 ; CHECK-NEXT:    ext z3.b, z3.b, z3.b, #8
427 ; CHECK-NEXT:    sunpklo z6.d, z0.s
428 ; CHECK-NEXT:    ext z0.b, z0.b, z0.b, #8
429 ; CHECK-NEXT:    sunpklo z2.d, z2.s
430 ; CHECK-NEXT:    sunpklo z7.d, z1.s
431 ; CHECK-NEXT:    ext z1.b, z1.b, z1.b, #8
432 ; CHECK-NEXT:    sunpklo z3.d, z3.s
433 ; CHECK-NEXT:    sunpklo z0.d, z0.s
434 ; CHECK-NEXT:    sunpklo z1.d, z1.s
435 ; CHECK-NEXT:    stp q4, q2, [x1, #64]
436 ; CHECK-NEXT:    stp q5, q3, [x1]
437 ; CHECK-NEXT:    stp q6, q0, [x1, #96]
438 ; CHECK-NEXT:    stp q7, q1, [x1, #32]
439 ; CHECK-NEXT:    ret
440   %a = load <16 x i16>, ptr %in
441   %b = add <16 x i16> %a, %a
442   %c = sext <16 x i16> %b to <16 x i64>
443   store <16 x i64> %c, ptr %out
444   ret void
448 ; sext i32 -> i64
451 define void @sext_v4i32_v4i64(<4 x i32> %a, ptr %out) {
452 ; CHECK-LABEL: sext_v4i32_v4i64:
453 ; CHECK:       // %bb.0:
454 ; CHECK-NEXT:    // kill: def $q0 killed $q0 def $z0
455 ; CHECK-NEXT:    sunpklo z1.d, z0.s
456 ; CHECK-NEXT:    ext z0.b, z0.b, z0.b, #8
457 ; CHECK-NEXT:    sunpklo z0.d, z0.s
458 ; CHECK-NEXT:    stp q1, q0, [x0]
459 ; CHECK-NEXT:    ret
460   %b = sext <4 x i32> %a to <4 x i64>
461   store <4 x i64>%b, ptr %out
462   ret void
465 define void @sext_v8i32_v8i64(ptr %in, ptr %out) {
466 ; CHECK-LABEL: sext_v8i32_v8i64:
467 ; CHECK:       // %bb.0:
468 ; CHECK-NEXT:    ldp q1, q0, [x0]
469 ; CHECK-NEXT:    add z0.s, z0.s, z0.s
470 ; CHECK-NEXT:    add z1.s, z1.s, z1.s
471 ; CHECK-NEXT:    sunpklo z2.d, z0.s
472 ; CHECK-NEXT:    ext z0.b, z0.b, z0.b, #8
473 ; CHECK-NEXT:    sunpklo z3.d, z1.s
474 ; CHECK-NEXT:    ext z1.b, z1.b, z1.b, #8
475 ; CHECK-NEXT:    sunpklo z0.d, z0.s
476 ; CHECK-NEXT:    sunpklo z1.d, z1.s
477 ; CHECK-NEXT:    stp q2, q0, [x1, #32]
478 ; CHECK-NEXT:    stp q3, q1, [x1]
479 ; CHECK-NEXT:    ret
480   %a = load <8 x i32>, ptr %in
481   %b = add <8 x i32> %a, %a
482   %c = sext <8 x i32> %b to <8 x i64>
483   store <8 x i64> %c, ptr %out
484   ret void
488 ; zext i8 -> i16
491 define void @zext_v16i8_v16i16(<16 x i8> %a, ptr %out) {
492 ; CHECK-LABEL: zext_v16i8_v16i16:
493 ; CHECK:       // %bb.0:
494 ; CHECK-NEXT:    // kill: def $q0 killed $q0 def $z0
495 ; CHECK-NEXT:    uunpklo z1.h, z0.b
496 ; CHECK-NEXT:    ext z0.b, z0.b, z0.b, #8
497 ; CHECK-NEXT:    uunpklo z0.h, z0.b
498 ; CHECK-NEXT:    stp q1, q0, [x0]
499 ; CHECK-NEXT:    ret
500   %b = zext <16 x i8> %a to <16 x i16>
501   store <16 x i16>%b, ptr %out
502   ret void
505 ; NOTE: Extra 'add' is to prevent the extend being combined with the load.
506 define void @zext_v32i8_v32i16(ptr %in, ptr %out) {
507 ; CHECK-LABEL: zext_v32i8_v32i16:
508 ; CHECK:       // %bb.0:
509 ; CHECK-NEXT:    ldp q1, q0, [x0]
510 ; CHECK-NEXT:    add z0.b, z0.b, z0.b
511 ; CHECK-NEXT:    add z1.b, z1.b, z1.b
512 ; CHECK-NEXT:    uunpklo z2.h, z0.b
513 ; CHECK-NEXT:    ext z0.b, z0.b, z0.b, #8
514 ; CHECK-NEXT:    uunpklo z3.h, z1.b
515 ; CHECK-NEXT:    ext z1.b, z1.b, z1.b, #8
516 ; CHECK-NEXT:    uunpklo z0.h, z0.b
517 ; CHECK-NEXT:    uunpklo z1.h, z1.b
518 ; CHECK-NEXT:    stp q2, q0, [x1, #32]
519 ; CHECK-NEXT:    stp q3, q1, [x1]
520 ; CHECK-NEXT:    ret
521   %a = load <32 x i8>, ptr %in
522   %b = add <32 x i8> %a, %a
523   %c = zext <32 x i8> %b to <32 x i16>
524   store <32 x i16> %c, ptr %out
525   ret void
529 ; zext i8 -> i32
532 define void @zext_v8i8_v8i32(<8 x i8> %a, ptr %out) {
533 ; CHECK-LABEL: zext_v8i8_v8i32:
534 ; CHECK:       // %bb.0:
535 ; CHECK-NEXT:    // kill: def $d0 killed $d0 def $z0
536 ; CHECK-NEXT:    uunpklo z0.h, z0.b
537 ; CHECK-NEXT:    uunpklo z1.s, z0.h
538 ; CHECK-NEXT:    ext z0.b, z0.b, z0.b, #8
539 ; CHECK-NEXT:    uunpklo z0.s, z0.h
540 ; CHECK-NEXT:    stp q1, q0, [x0]
541 ; CHECK-NEXT:    ret
542   %b = zext <8 x i8> %a to <8 x i32>
543   store <8 x i32>%b, ptr %out
544   ret void
547 define void @zext_v16i8_v16i32(<16 x i8> %a, ptr %out) {
548 ; CHECK-LABEL: zext_v16i8_v16i32:
549 ; CHECK:       // %bb.0:
550 ; CHECK-NEXT:    // kill: def $q0 killed $q0 def $z0
551 ; CHECK-NEXT:    uunpklo z1.h, z0.b
552 ; CHECK-NEXT:    ext z0.b, z0.b, z0.b, #8
553 ; CHECK-NEXT:    uunpklo z0.h, z0.b
554 ; CHECK-NEXT:    uunpklo z2.s, z1.h
555 ; CHECK-NEXT:    ext z1.b, z1.b, z1.b, #8
556 ; CHECK-NEXT:    uunpklo z1.s, z1.h
557 ; CHECK-NEXT:    uunpklo z3.s, z0.h
558 ; CHECK-NEXT:    ext z0.b, z0.b, z0.b, #8
559 ; CHECK-NEXT:    uunpklo z0.s, z0.h
560 ; CHECK-NEXT:    stp q2, q1, [x0]
561 ; CHECK-NEXT:    stp q3, q0, [x0, #32]
562 ; CHECK-NEXT:    ret
563   %b = zext <16 x i8> %a to <16 x i32>
564   store <16 x i32> %b, ptr %out
565   ret void
568 define void @zext_v32i8_v32i32(ptr %in, ptr %out) {
569 ; CHECK-LABEL: zext_v32i8_v32i32:
570 ; CHECK:       // %bb.0:
571 ; CHECK-NEXT:    ldp q1, q0, [x0]
572 ; CHECK-NEXT:    add z0.b, z0.b, z0.b
573 ; CHECK-NEXT:    add z1.b, z1.b, z1.b
574 ; CHECK-NEXT:    uunpklo z2.h, z0.b
575 ; CHECK-NEXT:    ext z0.b, z0.b, z0.b, #8
576 ; CHECK-NEXT:    uunpklo z3.h, z1.b
577 ; CHECK-NEXT:    ext z1.b, z1.b, z1.b, #8
578 ; CHECK-NEXT:    uunpklo z0.h, z0.b
579 ; CHECK-NEXT:    uunpklo z1.h, z1.b
580 ; CHECK-NEXT:    uunpklo z4.s, z2.h
581 ; CHECK-NEXT:    ext z2.b, z2.b, z2.b, #8
582 ; CHECK-NEXT:    uunpklo z5.s, z3.h
583 ; CHECK-NEXT:    ext z3.b, z3.b, z3.b, #8
584 ; CHECK-NEXT:    uunpklo z6.s, z0.h
585 ; CHECK-NEXT:    ext z0.b, z0.b, z0.b, #8
586 ; CHECK-NEXT:    uunpklo z2.s, z2.h
587 ; CHECK-NEXT:    uunpklo z7.s, z1.h
588 ; CHECK-NEXT:    ext z1.b, z1.b, z1.b, #8
589 ; CHECK-NEXT:    uunpklo z3.s, z3.h
590 ; CHECK-NEXT:    uunpklo z0.s, z0.h
591 ; CHECK-NEXT:    uunpklo z1.s, z1.h
592 ; CHECK-NEXT:    stp q4, q2, [x1, #64]
593 ; CHECK-NEXT:    stp q5, q3, [x1]
594 ; CHECK-NEXT:    stp q6, q0, [x1, #96]
595 ; CHECK-NEXT:    stp q7, q1, [x1, #32]
596 ; CHECK-NEXT:    ret
597   %a = load <32 x i8>, ptr %in
598   %b = add <32 x i8> %a, %a
599   %c = zext <32 x i8> %b to <32 x i32>
600   store <32 x i32> %c, ptr %out
601   ret void
605 ; zext i8 -> i64
608 ; NOTE: v4i8 is an unpacked typed stored within a v4i16 container. The zero
609 ; extend is a two step process where the container is zero_extend_inreg'd with
610 ; the result feeding a normal zero extend from halfs to doublewords.
611 define void @zext_v4i8_v4i64(<4 x i8> %a, ptr %out) {
612 ; CHECK-LABEL: zext_v4i8_v4i64:
613 ; CHECK:       // %bb.0:
614 ; CHECK-NEXT:    // kill: def $d0 killed $d0 def $z0
615 ; CHECK-NEXT:    and z0.h, z0.h, #0xff
616 ; CHECK-NEXT:    uunpklo z0.s, z0.h
617 ; CHECK-NEXT:    uunpklo z1.d, z0.s
618 ; CHECK-NEXT:    ext z0.b, z0.b, z0.b, #8
619 ; CHECK-NEXT:    uunpklo z0.d, z0.s
620 ; CHECK-NEXT:    stp q1, q0, [x0]
621 ; CHECK-NEXT:    ret
622   %b = zext <4 x i8> %a to <4 x i64>
623   store <4 x i64>%b, ptr %out
624   ret void
627 define void @zext_v8i8_v8i64(<8 x i8> %a, ptr %out) {
628 ; CHECK-LABEL: zext_v8i8_v8i64:
629 ; CHECK:       // %bb.0:
630 ; CHECK-NEXT:    // kill: def $d0 killed $d0 def $z0
631 ; CHECK-NEXT:    uunpklo z0.h, z0.b
632 ; CHECK-NEXT:    uunpklo z1.s, z0.h
633 ; CHECK-NEXT:    ext z0.b, z0.b, z0.b, #8
634 ; CHECK-NEXT:    uunpklo z0.s, z0.h
635 ; CHECK-NEXT:    uunpklo z2.d, z1.s
636 ; CHECK-NEXT:    ext z1.b, z1.b, z1.b, #8
637 ; CHECK-NEXT:    uunpklo z3.d, z0.s
638 ; CHECK-NEXT:    ext z0.b, z0.b, z0.b, #8
639 ; CHECK-NEXT:    uunpklo z1.d, z1.s
640 ; CHECK-NEXT:    uunpklo z0.d, z0.s
641 ; CHECK-NEXT:    stp q2, q1, [x0]
642 ; CHECK-NEXT:    stp q3, q0, [x0, #32]
643 ; CHECK-NEXT:    ret
644   %b = zext <8 x i8> %a to <8 x i64>
645   store <8 x i64>%b, ptr %out
646   ret void
649 define void @zext_v16i8_v16i64(<16 x i8> %a, ptr %out) {
650 ; CHECK-LABEL: zext_v16i8_v16i64:
651 ; CHECK:       // %bb.0:
652 ; CHECK-NEXT:    // kill: def $q0 killed $q0 def $z0
653 ; CHECK-NEXT:    uunpklo z1.h, z0.b
654 ; CHECK-NEXT:    ext z0.b, z0.b, z0.b, #8
655 ; CHECK-NEXT:    uunpklo z0.h, z0.b
656 ; CHECK-NEXT:    uunpklo z2.s, z1.h
657 ; CHECK-NEXT:    ext z1.b, z1.b, z1.b, #8
658 ; CHECK-NEXT:    uunpklo z1.s, z1.h
659 ; CHECK-NEXT:    uunpklo z3.s, z0.h
660 ; CHECK-NEXT:    ext z0.b, z0.b, z0.b, #8
661 ; CHECK-NEXT:    uunpklo z4.d, z2.s
662 ; CHECK-NEXT:    ext z2.b, z2.b, z2.b, #8
663 ; CHECK-NEXT:    uunpklo z0.s, z0.h
664 ; CHECK-NEXT:    mov z7.d, z1.d
665 ; CHECK-NEXT:    uunpklo z2.d, z2.s
666 ; CHECK-NEXT:    uunpklo z5.d, z3.s
667 ; CHECK-NEXT:    ext z3.b, z3.b, z3.b, #8
668 ; CHECK-NEXT:    ext z7.b, z7.b, z1.b, #8
669 ; CHECK-NEXT:    uunpklo z1.d, z1.s
670 ; CHECK-NEXT:    mov z6.d, z0.d
671 ; CHECK-NEXT:    uunpklo z3.d, z3.s
672 ; CHECK-NEXT:    stp q4, q2, [x0]
673 ; CHECK-NEXT:    uunpklo z4.d, z7.s
674 ; CHECK-NEXT:    ext z6.b, z6.b, z0.b, #8
675 ; CHECK-NEXT:    uunpklo z0.d, z0.s
676 ; CHECK-NEXT:    stp q5, q3, [x0, #64]
677 ; CHECK-NEXT:    uunpklo z2.d, z6.s
678 ; CHECK-NEXT:    stp q1, q4, [x0, #32]
679 ; CHECK-NEXT:    stp q0, q2, [x0, #96]
680 ; CHECK-NEXT:    ret
681   %b = zext <16 x i8> %a to <16 x i64>
682   store <16 x i64> %b, ptr %out
683   ret void
686 define void @zext_v32i8_v32i64(ptr %in, ptr %out) {
687 ; CHECK-LABEL: zext_v32i8_v32i64:
688 ; CHECK:       // %bb.0:
689 ; CHECK-NEXT:    ldp q1, q0, [x0]
690 ; CHECK-NEXT:    add z0.b, z0.b, z0.b
691 ; CHECK-NEXT:    add z1.b, z1.b, z1.b
692 ; CHECK-NEXT:    mov z2.d, z0.d
693 ; CHECK-NEXT:    uunpklo z0.h, z0.b
694 ; CHECK-NEXT:    mov z3.d, z1.d
695 ; CHECK-NEXT:    uunpklo z1.h, z1.b
696 ; CHECK-NEXT:    ext z2.b, z2.b, z2.b, #8
697 ; CHECK-NEXT:    ext z3.b, z3.b, z3.b, #8
698 ; CHECK-NEXT:    uunpklo z4.s, z0.h
699 ; CHECK-NEXT:    ext z0.b, z0.b, z0.b, #8
700 ; CHECK-NEXT:    uunpklo z5.s, z1.h
701 ; CHECK-NEXT:    ext z1.b, z1.b, z1.b, #8
702 ; CHECK-NEXT:    uunpklo z2.h, z2.b
703 ; CHECK-NEXT:    uunpklo z3.h, z3.b
704 ; CHECK-NEXT:    uunpklo z0.s, z0.h
705 ; CHECK-NEXT:    uunpklo z16.d, z4.s
706 ; CHECK-NEXT:    ext z4.b, z4.b, z4.b, #8
707 ; CHECK-NEXT:    uunpklo z1.s, z1.h
708 ; CHECK-NEXT:    uunpklo z17.d, z5.s
709 ; CHECK-NEXT:    ext z5.b, z5.b, z5.b, #8
710 ; CHECK-NEXT:    uunpklo z6.s, z2.h
711 ; CHECK-NEXT:    uunpklo z7.s, z3.h
712 ; CHECK-NEXT:    ext z2.b, z2.b, z2.b, #8
713 ; CHECK-NEXT:    uunpklo z4.d, z4.s
714 ; CHECK-NEXT:    ext z3.b, z3.b, z3.b, #8
715 ; CHECK-NEXT:    uunpklo z19.d, z0.s
716 ; CHECK-NEXT:    uunpklo z5.d, z5.s
717 ; CHECK-NEXT:    ext z0.b, z0.b, z0.b, #8
718 ; CHECK-NEXT:    uunpklo z2.s, z2.h
719 ; CHECK-NEXT:    uunpklo z18.d, z6.s
720 ; CHECK-NEXT:    ext z6.b, z6.b, z6.b, #8
721 ; CHECK-NEXT:    uunpklo z3.s, z3.h
722 ; CHECK-NEXT:    stp q16, q4, [x1, #128]
723 ; CHECK-NEXT:    mov z16.d, z7.d
724 ; CHECK-NEXT:    uunpklo z0.d, z0.s
725 ; CHECK-NEXT:    stp q17, q5, [x1]
726 ; CHECK-NEXT:    uunpklo z5.d, z7.s
727 ; CHECK-NEXT:    uunpklo z4.d, z6.s
728 ; CHECK-NEXT:    mov z6.d, z1.d
729 ; CHECK-NEXT:    ext z16.b, z16.b, z7.b, #8
730 ; CHECK-NEXT:    mov z7.d, z2.d
731 ; CHECK-NEXT:    stp q19, q0, [x1, #160]
732 ; CHECK-NEXT:    uunpklo z0.d, z2.s
733 ; CHECK-NEXT:    ext z6.b, z6.b, z1.b, #8
734 ; CHECK-NEXT:    uunpklo z1.d, z1.s
735 ; CHECK-NEXT:    stp q18, q4, [x1, #192]
736 ; CHECK-NEXT:    mov z4.d, z3.d
737 ; CHECK-NEXT:    ext z7.b, z7.b, z2.b, #8
738 ; CHECK-NEXT:    uunpklo z16.d, z16.s
739 ; CHECK-NEXT:    uunpklo z6.d, z6.s
740 ; CHECK-NEXT:    ext z4.b, z4.b, z3.b, #8
741 ; CHECK-NEXT:    uunpklo z2.d, z7.s
742 ; CHECK-NEXT:    uunpklo z3.d, z3.s
743 ; CHECK-NEXT:    stp q5, q16, [x1, #64]
744 ; CHECK-NEXT:    stp q1, q6, [x1, #32]
745 ; CHECK-NEXT:    uunpklo z1.d, z4.s
746 ; CHECK-NEXT:    stp q0, q2, [x1, #224]
747 ; CHECK-NEXT:    stp q3, q1, [x1, #96]
748 ; CHECK-NEXT:    ret
749   %a = load <32 x i8>, ptr %in
750   %b = add <32 x i8> %a, %a
751   %c = zext <32 x i8> %b to <32 x i64>
752   store <32 x i64> %c, ptr %out
753   ret void
757 ; zext i16 -> i32
760 define void @zext_v8i16_v8i32(<8 x i16> %a, ptr %out) {
761 ; CHECK-LABEL: zext_v8i16_v8i32:
762 ; CHECK:       // %bb.0:
763 ; CHECK-NEXT:    // kill: def $q0 killed $q0 def $z0
764 ; CHECK-NEXT:    uunpklo z1.s, z0.h
765 ; CHECK-NEXT:    ext z0.b, z0.b, z0.b, #8
766 ; CHECK-NEXT:    uunpklo z0.s, z0.h
767 ; CHECK-NEXT:    stp q1, q0, [x0]
768 ; CHECK-NEXT:    ret
769   %b = zext <8 x i16> %a to <8 x i32>
770   store <8 x i32>%b, ptr %out
771   ret void
774 define void @zext_v16i16_v16i32(ptr %in, ptr %out) {
775 ; CHECK-LABEL: zext_v16i16_v16i32:
776 ; CHECK:       // %bb.0:
777 ; CHECK-NEXT:    ldp q1, q0, [x0]
778 ; CHECK-NEXT:    add z0.h, z0.h, z0.h
779 ; CHECK-NEXT:    add z1.h, z1.h, z1.h
780 ; CHECK-NEXT:    uunpklo z2.s, z0.h
781 ; CHECK-NEXT:    ext z0.b, z0.b, z0.b, #8
782 ; CHECK-NEXT:    uunpklo z3.s, z1.h
783 ; CHECK-NEXT:    ext z1.b, z1.b, z1.b, #8
784 ; CHECK-NEXT:    uunpklo z0.s, z0.h
785 ; CHECK-NEXT:    uunpklo z1.s, z1.h
786 ; CHECK-NEXT:    stp q2, q0, [x1, #32]
787 ; CHECK-NEXT:    stp q3, q1, [x1]
788 ; CHECK-NEXT:    ret
789   %a = load <16 x i16>, ptr %in
790   %b = add <16 x i16> %a, %a
791   %c = zext <16 x i16> %b to <16 x i32>
792   store <16 x i32> %c, ptr %out
793   ret void
797 ; zext i16 -> i64
800 define void @zext_v4i16_v4i64(<4 x i16> %a, ptr %out) {
801 ; CHECK-LABEL: zext_v4i16_v4i64:
802 ; CHECK:       // %bb.0:
803 ; CHECK-NEXT:    // kill: def $d0 killed $d0 def $z0
804 ; CHECK-NEXT:    uunpklo z0.s, z0.h
805 ; CHECK-NEXT:    uunpklo z1.d, z0.s
806 ; CHECK-NEXT:    ext z0.b, z0.b, z0.b, #8
807 ; CHECK-NEXT:    uunpklo z0.d, z0.s
808 ; CHECK-NEXT:    stp q1, q0, [x0]
809 ; CHECK-NEXT:    ret
810   %b = zext <4 x i16> %a to <4 x i64>
811   store <4 x i64>%b, ptr %out
812   ret void
815 define void @zext_v8i16_v8i64(<8 x i16> %a, ptr %out) {
816 ; CHECK-LABEL: zext_v8i16_v8i64:
817 ; CHECK:       // %bb.0:
818 ; CHECK-NEXT:    // kill: def $q0 killed $q0 def $z0
819 ; CHECK-NEXT:    uunpklo z1.s, z0.h
820 ; CHECK-NEXT:    ext z0.b, z0.b, z0.b, #8
821 ; CHECK-NEXT:    uunpklo z0.s, z0.h
822 ; CHECK-NEXT:    uunpklo z2.d, z1.s
823 ; CHECK-NEXT:    ext z1.b, z1.b, z1.b, #8
824 ; CHECK-NEXT:    uunpklo z1.d, z1.s
825 ; CHECK-NEXT:    uunpklo z3.d, z0.s
826 ; CHECK-NEXT:    ext z0.b, z0.b, z0.b, #8
827 ; CHECK-NEXT:    uunpklo z0.d, z0.s
828 ; CHECK-NEXT:    stp q2, q1, [x0]
829 ; CHECK-NEXT:    stp q3, q0, [x0, #32]
830 ; CHECK-NEXT:    ret
831   %b = zext <8 x i16> %a to <8 x i64>
832   store <8 x i64>%b, ptr %out
833   ret void
836 define void @zext_v16i16_v16i64(ptr %in, ptr %out) {
837 ; CHECK-LABEL: zext_v16i16_v16i64:
838 ; CHECK:       // %bb.0:
839 ; CHECK-NEXT:    ldp q1, q0, [x0]
840 ; CHECK-NEXT:    add z0.h, z0.h, z0.h
841 ; CHECK-NEXT:    add z1.h, z1.h, z1.h
842 ; CHECK-NEXT:    uunpklo z2.s, z0.h
843 ; CHECK-NEXT:    ext z0.b, z0.b, z0.b, #8
844 ; CHECK-NEXT:    uunpklo z3.s, z1.h
845 ; CHECK-NEXT:    ext z1.b, z1.b, z1.b, #8
846 ; CHECK-NEXT:    uunpklo z0.s, z0.h
847 ; CHECK-NEXT:    uunpklo z1.s, z1.h
848 ; CHECK-NEXT:    uunpklo z4.d, z2.s
849 ; CHECK-NEXT:    ext z2.b, z2.b, z2.b, #8
850 ; CHECK-NEXT:    uunpklo z5.d, z3.s
851 ; CHECK-NEXT:    ext z3.b, z3.b, z3.b, #8
852 ; CHECK-NEXT:    uunpklo z6.d, z0.s
853 ; CHECK-NEXT:    ext z0.b, z0.b, z0.b, #8
854 ; CHECK-NEXT:    uunpklo z2.d, z2.s
855 ; CHECK-NEXT:    uunpklo z7.d, z1.s
856 ; CHECK-NEXT:    ext z1.b, z1.b, z1.b, #8
857 ; CHECK-NEXT:    uunpklo z3.d, z3.s
858 ; CHECK-NEXT:    uunpklo z0.d, z0.s
859 ; CHECK-NEXT:    uunpklo z1.d, z1.s
860 ; CHECK-NEXT:    stp q4, q2, [x1, #64]
861 ; CHECK-NEXT:    stp q5, q3, [x1]
862 ; CHECK-NEXT:    stp q6, q0, [x1, #96]
863 ; CHECK-NEXT:    stp q7, q1, [x1, #32]
864 ; CHECK-NEXT:    ret
865   %a = load <16 x i16>, ptr %in
866   %b = add <16 x i16> %a, %a
867   %c = zext <16 x i16> %b to <16 x i64>
868   store <16 x i64> %c, ptr %out
869   ret void
873 ; zext i32 -> i64
876 define void @zext_v4i32_v4i64(<4 x i32> %a, ptr %out) {
877 ; CHECK-LABEL: zext_v4i32_v4i64:
878 ; CHECK:       // %bb.0:
879 ; CHECK-NEXT:    // kill: def $q0 killed $q0 def $z0
880 ; CHECK-NEXT:    uunpklo z1.d, z0.s
881 ; CHECK-NEXT:    ext z0.b, z0.b, z0.b, #8
882 ; CHECK-NEXT:    uunpklo z0.d, z0.s
883 ; CHECK-NEXT:    stp q1, q0, [x0]
884 ; CHECK-NEXT:    ret
885   %b = zext <4 x i32> %a to <4 x i64>
886   store <4 x i64>%b, ptr %out
887   ret void
890 define void @zext_v8i32_v8i64(ptr %in, ptr %out) {
891 ; CHECK-LABEL: zext_v8i32_v8i64:
892 ; CHECK:       // %bb.0:
893 ; CHECK-NEXT:    ldp q1, q0, [x0]
894 ; CHECK-NEXT:    add z0.s, z0.s, z0.s
895 ; CHECK-NEXT:    add z1.s, z1.s, z1.s
896 ; CHECK-NEXT:    uunpklo z2.d, z0.s
897 ; CHECK-NEXT:    ext z0.b, z0.b, z0.b, #8
898 ; CHECK-NEXT:    uunpklo z3.d, z1.s
899 ; CHECK-NEXT:    ext z1.b, z1.b, z1.b, #8
900 ; CHECK-NEXT:    uunpklo z0.d, z0.s
901 ; CHECK-NEXT:    uunpklo z1.d, z1.s
902 ; CHECK-NEXT:    stp q2, q0, [x1, #32]
903 ; CHECK-NEXT:    stp q3, q1, [x1]
904 ; CHECK-NEXT:    ret
905   %a = load <8 x i32>, ptr %in
906   %b = add <8 x i32> %a, %a
907   %c = zext <8 x i32> %b to <8 x i64>
908   store <8 x i64> %c, ptr %out
909   ret void
912 define void @extend_and_mul(i32 %0, <2 x i64> %1, ptr %2) {
913 ; SVE-LABEL: extend_and_mul:
914 ; SVE:       // %bb.0:
915 ; SVE-NEXT:    mov z1.s, w0
916 ; SVE-NEXT:    ptrue p0.d, vl2
917 ; SVE-NEXT:    // kill: def $q0 killed $q0 def $z0
918 ; SVE-NEXT:    uunpklo z1.d, z1.s
919 ; SVE-NEXT:    mul z0.d, p0/m, z0.d, z1.d
920 ; SVE-NEXT:    str q0, [x1]
921 ; SVE-NEXT:    ret
923 ; SVE2-LABEL: extend_and_mul:
924 ; SVE2:       // %bb.0:
925 ; SVE2-NEXT:    mov z1.s, w0
926 ; SVE2-NEXT:    // kill: def $q0 killed $q0 def $z0
927 ; SVE2-NEXT:    uunpklo z1.d, z1.s
928 ; SVE2-NEXT:    mul z0.d, z1.d, z0.d
929 ; SVE2-NEXT:    str q0, [x1]
930 ; SVE2-NEXT:    ret
931   %broadcast.splatinsert2 = insertelement <2 x i32> poison, i32 %0, i64 0
932   %broadcast.splat3 = shufflevector <2 x i32> %broadcast.splatinsert2, <2 x i32> poison, <2 x i32> zeroinitializer
933   %4 = zext <2 x i32> %broadcast.splat3 to <2 x i64>
934   %5 = mul <2 x i64> %4, %1
935   store <2 x i64> %5, ptr %2, align 2
936   ret void
939 define void @extend_no_mul(i32 %0, <2 x i64> %1, ptr %2) {
940 ; CHECK-LABEL: extend_no_mul:
941 ; CHECK:       // %bb.0: // %entry
942 ; CHECK-NEXT:    mov w8, w0
943 ; CHECK-NEXT:    mov z0.d, x8
944 ; CHECK-NEXT:    str q0, [x1]
945 ; CHECK-NEXT:    ret
946 entry:
947   %broadcast.splatinsert2 = insertelement <2 x i32> poison, i32 %0, i64 0
948   %broadcast.splat3 = shufflevector <2 x i32> %broadcast.splatinsert2, <2 x i32> poison, <2 x i32> zeroinitializer
949   %3 = zext <2 x i32> %broadcast.splat3 to <2 x i64>
950   store <2 x i64> %3, ptr %2, align 2
951   ret void