[ELF] Avoid make in elf::writeARMCmseImportLib
[llvm-project.git] / llvm / test / CodeGen / AArch64 / vecreduce-add.ll
blob184aa0226fe774010fa84e8c17ec23ba4a146e88
1 ; NOTE: Assertions have been autogenerated by utils/update_llc_test_checks.py
2 ; RUN: llc -mtriple=aarch64-none-linux-gnu %s -o - | FileCheck %s --check-prefixes=CHECK,CHECK-SD,CHECK-SD-BASE
3 ; RUN: llc -mtriple=aarch64-none-linux-gnu -mattr=+dotprod %s -o - | FileCheck %s --check-prefixes=CHECK,CHECK-SD,CHECK-SD-DOT
4 ; RUN: llc -mtriple=aarch64-none-linux-gnu -global-isel %s -o - | FileCheck %s --check-prefixes=CHECK,CHECK-GI,CHECK-GI-BASE
5 ; RUN: llc -mtriple=aarch64-none-linux-gnu -mattr=+dotprod -global-isel %s -o - | FileCheck %s --check-prefixes=CHECK,CHECK-GI,CHECK-GI-DOT
7 define i32 @addv_v2i32(<2 x i32> %a) {
8 ; CHECK-LABEL: addv_v2i32:
9 ; CHECK:       // %bb.0: // %entry
10 ; CHECK-NEXT:    addp v0.2s, v0.2s, v0.2s
11 ; CHECK-NEXT:    fmov w0, s0
12 ; CHECK-NEXT:    ret
13 entry:
14   %arg1 = call i32 @llvm.vector.reduce.add.v2i32(<2 x i32> %a)
15   ret i32 %arg1
18 define i16 @addv_v4i16(<4 x i16> %a) {
19 ; CHECK-LABEL: addv_v4i16:
20 ; CHECK:       // %bb.0: // %entry
21 ; CHECK-NEXT:    addv h0, v0.4h
22 ; CHECK-NEXT:    fmov w0, s0
23 ; CHECK-NEXT:    ret
24 entry:
25   %arg1 = call i16 @llvm.vector.reduce.add.v4i16(<4 x i16> %a)
26   ret i16 %arg1
29 define i32 @add_v4i32_v4i32(<4 x i32> %x) {
30 ; CHECK-LABEL: add_v4i32_v4i32:
31 ; CHECK:       // %bb.0: // %entry
32 ; CHECK-NEXT:    addv s0, v0.4s
33 ; CHECK-NEXT:    fmov w0, s0
34 ; CHECK-NEXT:    ret
35 entry:
36   %z = call i32 @llvm.vector.reduce.add.v4i32(<4 x i32> %x)
37   ret i32 %z
40 define i8 @addv_v8i8(<8 x i8> %a) {
41 ; CHECK-LABEL: addv_v8i8:
42 ; CHECK:       // %bb.0: // %entry
43 ; CHECK-NEXT:    addv b0, v0.8b
44 ; CHECK-NEXT:    fmov w0, s0
45 ; CHECK-NEXT:    ret
46 entry:
47   %arg1 = call i8 @llvm.vector.reduce.add.v8i8(<8 x i8> %a)
48   ret i8 %arg1
51 define i64 @add_v4i32_v4i64_zext(<4 x i32> %x) {
52 ; CHECK-LABEL: add_v4i32_v4i64_zext:
53 ; CHECK:       // %bb.0: // %entry
54 ; CHECK-NEXT:    uaddlv d0, v0.4s
55 ; CHECK-NEXT:    fmov x0, d0
56 ; CHECK-NEXT:    ret
57 entry:
58   %xx = zext <4 x i32> %x to <4 x i64>
59   %z = call i64 @llvm.vector.reduce.add.v4i64(<4 x i64> %xx)
60   ret i64 %z
63 define i64 @add_v4i32_v4i64_sext(<4 x i32> %x) {
64 ; CHECK-LABEL: add_v4i32_v4i64_sext:
65 ; CHECK:       // %bb.0: // %entry
66 ; CHECK-NEXT:    saddlv d0, v0.4s
67 ; CHECK-NEXT:    fmov x0, d0
68 ; CHECK-NEXT:    ret
69 entry:
70   %xx = sext <4 x i32> %x to <4 x i64>
71   %z = call i64 @llvm.vector.reduce.add.v4i64(<4 x i64> %xx)
72   ret i64 %z
75 define i64 @add_v2i32_v2i64_zext(<2 x i32> %x) {
76 ; CHECK-LABEL: add_v2i32_v2i64_zext:
77 ; CHECK:       // %bb.0: // %entry
78 ; CHECK-NEXT:    ushll v0.2d, v0.2s, #0
79 ; CHECK-NEXT:    addp d0, v0.2d
80 ; CHECK-NEXT:    fmov x0, d0
81 ; CHECK-NEXT:    ret
82 entry:
83   %xx = zext <2 x i32> %x to <2 x i64>
84   %z = call i64 @llvm.vector.reduce.add.v2i64(<2 x i64> %xx)
85   ret i64 %z
88 define i64 @add_v2i32_v2i64_sext(<2 x i32> %x) {
89 ; CHECK-LABEL: add_v2i32_v2i64_sext:
90 ; CHECK:       // %bb.0: // %entry
91 ; CHECK-NEXT:    sshll v0.2d, v0.2s, #0
92 ; CHECK-NEXT:    addp d0, v0.2d
93 ; CHECK-NEXT:    fmov x0, d0
94 ; CHECK-NEXT:    ret
95 entry:
96   %xx = sext <2 x i32> %x to <2 x i64>
97   %z = call i64 @llvm.vector.reduce.add.v2i64(<2 x i64> %xx)
98   ret i64 %z
101 define i32 @add_v8i16_v8i32_zext(<8 x i16> %x) {
102 ; CHECK-LABEL: add_v8i16_v8i32_zext:
103 ; CHECK:       // %bb.0: // %entry
104 ; CHECK-NEXT:    uaddlv s0, v0.8h
105 ; CHECK-NEXT:    fmov w0, s0
106 ; CHECK-NEXT:    ret
107 entry:
108   %xx = zext <8 x i16> %x to <8 x i32>
109   %z = call i32 @llvm.vector.reduce.add.v8i32(<8 x i32> %xx)
110   ret i32 %z
113 define i32 @add_v8i16_v8i32_sext(<8 x i16> %x) {
114 ; CHECK-LABEL: add_v8i16_v8i32_sext:
115 ; CHECK:       // %bb.0: // %entry
116 ; CHECK-NEXT:    saddlv s0, v0.8h
117 ; CHECK-NEXT:    fmov w0, s0
118 ; CHECK-NEXT:    ret
119 entry:
120   %xx = sext <8 x i16> %x to <8 x i32>
121   %z = call i32 @llvm.vector.reduce.add.v8i32(<8 x i32> %xx)
122   ret i32 %z
125 define i32 @add_v4i16_v4i32_zext(<4 x i16> %x) {
126 ; CHECK-SD-LABEL: add_v4i16_v4i32_zext:
127 ; CHECK-SD:       // %bb.0: // %entry
128 ; CHECK-SD-NEXT:    ushll v0.4s, v0.4h, #0
129 ; CHECK-SD-NEXT:    addv s0, v0.4s
130 ; CHECK-SD-NEXT:    fmov w0, s0
131 ; CHECK-SD-NEXT:    ret
133 ; CHECK-GI-LABEL: add_v4i16_v4i32_zext:
134 ; CHECK-GI:       // %bb.0: // %entry
135 ; CHECK-GI-NEXT:    uaddlv s0, v0.4h
136 ; CHECK-GI-NEXT:    fmov w0, s0
137 ; CHECK-GI-NEXT:    ret
138 entry:
139   %xx = zext <4 x i16> %x to <4 x i32>
140   %z = call i32 @llvm.vector.reduce.add.v4i32(<4 x i32> %xx)
141   ret i32 %z
144 define i32 @add_v4i16_v4i32_sext(<4 x i16> %x) {
145 ; CHECK-SD-LABEL: add_v4i16_v4i32_sext:
146 ; CHECK-SD:       // %bb.0: // %entry
147 ; CHECK-SD-NEXT:    sshll v0.4s, v0.4h, #0
148 ; CHECK-SD-NEXT:    addv s0, v0.4s
149 ; CHECK-SD-NEXT:    fmov w0, s0
150 ; CHECK-SD-NEXT:    ret
152 ; CHECK-GI-LABEL: add_v4i16_v4i32_sext:
153 ; CHECK-GI:       // %bb.0: // %entry
154 ; CHECK-GI-NEXT:    saddlv s0, v0.4h
155 ; CHECK-GI-NEXT:    fmov w0, s0
156 ; CHECK-GI-NEXT:    ret
157 entry:
158   %xx = sext <4 x i16> %x to <4 x i32>
159   %z = call i32 @llvm.vector.reduce.add.v4i32(<4 x i32> %xx)
160   ret i32 %z
163 define zeroext i16 @add_v8i16_v8i16(<8 x i16> %x) {
164 ; CHECK-SD-LABEL: add_v8i16_v8i16:
165 ; CHECK-SD:       // %bb.0: // %entry
166 ; CHECK-SD-NEXT:    addv h0, v0.8h
167 ; CHECK-SD-NEXT:    fmov w0, s0
168 ; CHECK-SD-NEXT:    ret
170 ; CHECK-GI-LABEL: add_v8i16_v8i16:
171 ; CHECK-GI:       // %bb.0: // %entry
172 ; CHECK-GI-NEXT:    addv h0, v0.8h
173 ; CHECK-GI-NEXT:    fmov w8, s0
174 ; CHECK-GI-NEXT:    uxth w0, w8
175 ; CHECK-GI-NEXT:    ret
176 entry:
177   %z = call i16 @llvm.vector.reduce.add.v8i16(<8 x i16> %x)
178   ret i16 %z
181 define i64 @add_v8i16_v8i64_zext(<8 x i16> %x) {
182 ; CHECK-SD-LABEL: add_v8i16_v8i64_zext:
183 ; CHECK-SD:       // %bb.0: // %entry
184 ; CHECK-SD-NEXT:    ushll2 v1.4s, v0.8h, #0
185 ; CHECK-SD-NEXT:    ushll v0.4s, v0.4h, #0
186 ; CHECK-SD-NEXT:    uaddl2 v2.2d, v0.4s, v1.4s
187 ; CHECK-SD-NEXT:    uaddl v0.2d, v0.2s, v1.2s
188 ; CHECK-SD-NEXT:    add v0.2d, v0.2d, v2.2d
189 ; CHECK-SD-NEXT:    addp d0, v0.2d
190 ; CHECK-SD-NEXT:    fmov x0, d0
191 ; CHECK-SD-NEXT:    ret
193 ; CHECK-GI-LABEL: add_v8i16_v8i64_zext:
194 ; CHECK-GI:       // %bb.0: // %entry
195 ; CHECK-GI-NEXT:    uaddlv s0, v0.8h
196 ; CHECK-GI-NEXT:    mov w0, v0.s[0]
197 ; CHECK-GI-NEXT:    ret
198 entry:
199   %xx = zext <8 x i16> %x to <8 x i64>
200   %z = call i64 @llvm.vector.reduce.add.v8i64(<8 x i64> %xx)
201   ret i64 %z
204 define i64 @add_v8i16_v8i64_sext(<8 x i16> %x) {
205 ; CHECK-SD-LABEL: add_v8i16_v8i64_sext:
206 ; CHECK-SD:       // %bb.0: // %entry
207 ; CHECK-SD-NEXT:    sshll2 v1.4s, v0.8h, #0
208 ; CHECK-SD-NEXT:    sshll v0.4s, v0.4h, #0
209 ; CHECK-SD-NEXT:    saddl2 v2.2d, v0.4s, v1.4s
210 ; CHECK-SD-NEXT:    saddl v0.2d, v0.2s, v1.2s
211 ; CHECK-SD-NEXT:    add v0.2d, v0.2d, v2.2d
212 ; CHECK-SD-NEXT:    addp d0, v0.2d
213 ; CHECK-SD-NEXT:    fmov x0, d0
214 ; CHECK-SD-NEXT:    ret
216 ; CHECK-GI-LABEL: add_v8i16_v8i64_sext:
217 ; CHECK-GI:       // %bb.0: // %entry
218 ; CHECK-GI-NEXT:    saddlv s0, v0.8h
219 ; CHECK-GI-NEXT:    smov x0, v0.s[0]
220 ; CHECK-GI-NEXT:    ret
221 entry:
222   %xx = sext <8 x i16> %x to <8 x i64>
223   %z = call i64 @llvm.vector.reduce.add.v8i64(<8 x i64> %xx)
224   ret i64 %z
227 define i64 @add_v4i16_v4i64_zext(<4 x i16> %x) {
228 ; CHECK-SD-LABEL: add_v4i16_v4i64_zext:
229 ; CHECK-SD:       // %bb.0: // %entry
230 ; CHECK-SD-NEXT:    ushll v0.4s, v0.4h, #0
231 ; CHECK-SD-NEXT:    uaddlv d0, v0.4s
232 ; CHECK-SD-NEXT:    fmov x0, d0
233 ; CHECK-SD-NEXT:    ret
235 ; CHECK-GI-LABEL: add_v4i16_v4i64_zext:
236 ; CHECK-GI:       // %bb.0: // %entry
237 ; CHECK-GI-NEXT:    uaddlv s0, v0.4h
238 ; CHECK-GI-NEXT:    mov w0, v0.s[0]
239 ; CHECK-GI-NEXT:    ret
240 entry:
241   %xx = zext <4 x i16> %x to <4 x i64>
242   %z = call i64 @llvm.vector.reduce.add.v4i64(<4 x i64> %xx)
243   ret i64 %z
246 define i64 @add_v4i16_v4i64_sext(<4 x i16> %x) {
247 ; CHECK-SD-LABEL: add_v4i16_v4i64_sext:
248 ; CHECK-SD:       // %bb.0: // %entry
249 ; CHECK-SD-NEXT:    sshll v0.4s, v0.4h, #0
250 ; CHECK-SD-NEXT:    saddlv d0, v0.4s
251 ; CHECK-SD-NEXT:    fmov x0, d0
252 ; CHECK-SD-NEXT:    ret
254 ; CHECK-GI-LABEL: add_v4i16_v4i64_sext:
255 ; CHECK-GI:       // %bb.0: // %entry
256 ; CHECK-GI-NEXT:    saddlv s0, v0.4h
257 ; CHECK-GI-NEXT:    smov x0, v0.s[0]
258 ; CHECK-GI-NEXT:    ret
259 entry:
260   %xx = sext <4 x i16> %x to <4 x i64>
261   %z = call i64 @llvm.vector.reduce.add.v4i64(<4 x i64> %xx)
262   ret i64 %z
265 define i64 @add_v2i16_v2i64_zext(<2 x i16> %x) {
266 ; CHECK-SD-LABEL: add_v2i16_v2i64_zext:
267 ; CHECK-SD:       // %bb.0: // %entry
268 ; CHECK-SD-NEXT:    movi d1, #0x00ffff0000ffff
269 ; CHECK-SD-NEXT:    and v0.8b, v0.8b, v1.8b
270 ; CHECK-SD-NEXT:    ushll v0.2d, v0.2s, #0
271 ; CHECK-SD-NEXT:    addp d0, v0.2d
272 ; CHECK-SD-NEXT:    fmov x0, d0
273 ; CHECK-SD-NEXT:    ret
275 ; CHECK-GI-LABEL: add_v2i16_v2i64_zext:
276 ; CHECK-GI:       // %bb.0: // %entry
277 ; CHECK-GI-NEXT:    movi v1.2d, #0x0000000000ffff
278 ; CHECK-GI-NEXT:    ushll v0.2d, v0.2s, #0
279 ; CHECK-GI-NEXT:    and v0.16b, v0.16b, v1.16b
280 ; CHECK-GI-NEXT:    addp d0, v0.2d
281 ; CHECK-GI-NEXT:    fmov x0, d0
282 ; CHECK-GI-NEXT:    ret
283 entry:
284   %xx = zext <2 x i16> %x to <2 x i64>
285   %z = call i64 @llvm.vector.reduce.add.v2i64(<2 x i64> %xx)
286   ret i64 %z
289 define i64 @add_v2i16_v2i64_sext(<2 x i16> %x) {
290 ; CHECK-LABEL: add_v2i16_v2i64_sext:
291 ; CHECK:       // %bb.0: // %entry
292 ; CHECK-NEXT:    ushll v0.2d, v0.2s, #0
293 ; CHECK-NEXT:    shl v0.2d, v0.2d, #48
294 ; CHECK-NEXT:    sshr v0.2d, v0.2d, #48
295 ; CHECK-NEXT:    addp d0, v0.2d
296 ; CHECK-NEXT:    fmov x0, d0
297 ; CHECK-NEXT:    ret
298 entry:
299   %xx = sext <2 x i16> %x to <2 x i64>
300   %z = call i64 @llvm.vector.reduce.add.v2i64(<2 x i64> %xx)
301   ret i64 %z
304 define i32 @add_v16i8_v16i32_zext(<16 x i8> %x) {
305 ; CHECK-SD-BASE-LABEL: add_v16i8_v16i32_zext:
306 ; CHECK-SD-BASE:       // %bb.0: // %entry
307 ; CHECK-SD-BASE-NEXT:    ushll2 v1.8h, v0.16b, #0
308 ; CHECK-SD-BASE-NEXT:    ushll v0.8h, v0.8b, #0
309 ; CHECK-SD-BASE-NEXT:    uaddl2 v2.4s, v0.8h, v1.8h
310 ; CHECK-SD-BASE-NEXT:    uaddl v0.4s, v0.4h, v1.4h
311 ; CHECK-SD-BASE-NEXT:    add v0.4s, v0.4s, v2.4s
312 ; CHECK-SD-BASE-NEXT:    addv s0, v0.4s
313 ; CHECK-SD-BASE-NEXT:    fmov w0, s0
314 ; CHECK-SD-BASE-NEXT:    ret
316 ; CHECK-SD-DOT-LABEL: add_v16i8_v16i32_zext:
317 ; CHECK-SD-DOT:       // %bb.0: // %entry
318 ; CHECK-SD-DOT-NEXT:    movi v1.16b, #1
319 ; CHECK-SD-DOT-NEXT:    movi v2.2d, #0000000000000000
320 ; CHECK-SD-DOT-NEXT:    udot v2.4s, v0.16b, v1.16b
321 ; CHECK-SD-DOT-NEXT:    addv s0, v2.4s
322 ; CHECK-SD-DOT-NEXT:    fmov w0, s0
323 ; CHECK-SD-DOT-NEXT:    ret
325 ; CHECK-GI-BASE-LABEL: add_v16i8_v16i32_zext:
326 ; CHECK-GI-BASE:       // %bb.0: // %entry
327 ; CHECK-GI-BASE-NEXT:    uaddlv h0, v0.16b
328 ; CHECK-GI-BASE-NEXT:    fmov w8, s0
329 ; CHECK-GI-BASE-NEXT:    and w0, w8, #0xffff
330 ; CHECK-GI-BASE-NEXT:    ret
332 ; CHECK-GI-DOT-LABEL: add_v16i8_v16i32_zext:
333 ; CHECK-GI-DOT:       // %bb.0: // %entry
334 ; CHECK-GI-DOT-NEXT:    movi v1.16b, #1
335 ; CHECK-GI-DOT-NEXT:    movi v2.2d, #0000000000000000
336 ; CHECK-GI-DOT-NEXT:    udot v2.4s, v0.16b, v1.16b
337 ; CHECK-GI-DOT-NEXT:    addv s0, v2.4s
338 ; CHECK-GI-DOT-NEXT:    fmov w0, s0
339 ; CHECK-GI-DOT-NEXT:    ret
340 entry:
341   %xx = zext <16 x i8> %x to <16 x i32>
342   %z = call i32 @llvm.vector.reduce.add.v16i32(<16 x i32> %xx)
343   ret i32 %z
346 define i32 @add_v16i8_v16i32_sext(<16 x i8> %x) {
347 ; CHECK-SD-BASE-LABEL: add_v16i8_v16i32_sext:
348 ; CHECK-SD-BASE:       // %bb.0: // %entry
349 ; CHECK-SD-BASE-NEXT:    sshll2 v1.8h, v0.16b, #0
350 ; CHECK-SD-BASE-NEXT:    sshll v0.8h, v0.8b, #0
351 ; CHECK-SD-BASE-NEXT:    saddl2 v2.4s, v0.8h, v1.8h
352 ; CHECK-SD-BASE-NEXT:    saddl v0.4s, v0.4h, v1.4h
353 ; CHECK-SD-BASE-NEXT:    add v0.4s, v0.4s, v2.4s
354 ; CHECK-SD-BASE-NEXT:    addv s0, v0.4s
355 ; CHECK-SD-BASE-NEXT:    fmov w0, s0
356 ; CHECK-SD-BASE-NEXT:    ret
358 ; CHECK-SD-DOT-LABEL: add_v16i8_v16i32_sext:
359 ; CHECK-SD-DOT:       // %bb.0: // %entry
360 ; CHECK-SD-DOT-NEXT:    movi v1.16b, #1
361 ; CHECK-SD-DOT-NEXT:    movi v2.2d, #0000000000000000
362 ; CHECK-SD-DOT-NEXT:    sdot v2.4s, v0.16b, v1.16b
363 ; CHECK-SD-DOT-NEXT:    addv s0, v2.4s
364 ; CHECK-SD-DOT-NEXT:    fmov w0, s0
365 ; CHECK-SD-DOT-NEXT:    ret
367 ; CHECK-GI-BASE-LABEL: add_v16i8_v16i32_sext:
368 ; CHECK-GI-BASE:       // %bb.0: // %entry
369 ; CHECK-GI-BASE-NEXT:    saddlv h0, v0.16b
370 ; CHECK-GI-BASE-NEXT:    fmov w8, s0
371 ; CHECK-GI-BASE-NEXT:    sxth w0, w8
372 ; CHECK-GI-BASE-NEXT:    ret
374 ; CHECK-GI-DOT-LABEL: add_v16i8_v16i32_sext:
375 ; CHECK-GI-DOT:       // %bb.0: // %entry
376 ; CHECK-GI-DOT-NEXT:    movi v1.16b, #1
377 ; CHECK-GI-DOT-NEXT:    movi v2.2d, #0000000000000000
378 ; CHECK-GI-DOT-NEXT:    sdot v2.4s, v0.16b, v1.16b
379 ; CHECK-GI-DOT-NEXT:    addv s0, v2.4s
380 ; CHECK-GI-DOT-NEXT:    fmov w0, s0
381 ; CHECK-GI-DOT-NEXT:    ret
382 entry:
383   %xx = sext <16 x i8> %x to <16 x i32>
384   %z = call i32 @llvm.vector.reduce.add.v16i32(<16 x i32> %xx)
385   ret i32 %z
388 define i32 @add_v8i8_v8i32_zext(<8 x i8> %x) {
389 ; CHECK-SD-BASE-LABEL: add_v8i8_v8i32_zext:
390 ; CHECK-SD-BASE:       // %bb.0: // %entry
391 ; CHECK-SD-BASE-NEXT:    ushll v0.8h, v0.8b, #0
392 ; CHECK-SD-BASE-NEXT:    uaddlv s0, v0.8h
393 ; CHECK-SD-BASE-NEXT:    fmov w0, s0
394 ; CHECK-SD-BASE-NEXT:    ret
396 ; CHECK-SD-DOT-LABEL: add_v8i8_v8i32_zext:
397 ; CHECK-SD-DOT:       // %bb.0: // %entry
398 ; CHECK-SD-DOT-NEXT:    movi v1.2d, #0000000000000000
399 ; CHECK-SD-DOT-NEXT:    movi v2.8b, #1
400 ; CHECK-SD-DOT-NEXT:    udot v1.2s, v0.8b, v2.8b
401 ; CHECK-SD-DOT-NEXT:    addp v0.2s, v1.2s, v1.2s
402 ; CHECK-SD-DOT-NEXT:    fmov w0, s0
403 ; CHECK-SD-DOT-NEXT:    ret
405 ; CHECK-GI-BASE-LABEL: add_v8i8_v8i32_zext:
406 ; CHECK-GI-BASE:       // %bb.0: // %entry
407 ; CHECK-GI-BASE-NEXT:    uaddlv h0, v0.8b
408 ; CHECK-GI-BASE-NEXT:    fmov w8, s0
409 ; CHECK-GI-BASE-NEXT:    and w0, w8, #0xffff
410 ; CHECK-GI-BASE-NEXT:    ret
412 ; CHECK-GI-DOT-LABEL: add_v8i8_v8i32_zext:
413 ; CHECK-GI-DOT:       // %bb.0: // %entry
414 ; CHECK-GI-DOT-NEXT:    movi v1.8b, #1
415 ; CHECK-GI-DOT-NEXT:    movi v2.2d, #0000000000000000
416 ; CHECK-GI-DOT-NEXT:    udot v2.2s, v0.8b, v1.8b
417 ; CHECK-GI-DOT-NEXT:    addp v0.2s, v2.2s, v2.2s
418 ; CHECK-GI-DOT-NEXT:    fmov w0, s0
419 ; CHECK-GI-DOT-NEXT:    ret
420 entry:
421   %xx = zext <8 x i8> %x to <8 x i32>
422   %z = call i32 @llvm.vector.reduce.add.v8i32(<8 x i32> %xx)
423   ret i32 %z
426 define i32 @add_v8i8_v8i32_sext(<8 x i8> %x) {
427 ; CHECK-SD-BASE-LABEL: add_v8i8_v8i32_sext:
428 ; CHECK-SD-BASE:       // %bb.0: // %entry
429 ; CHECK-SD-BASE-NEXT:    sshll v0.8h, v0.8b, #0
430 ; CHECK-SD-BASE-NEXT:    saddlv s0, v0.8h
431 ; CHECK-SD-BASE-NEXT:    fmov w0, s0
432 ; CHECK-SD-BASE-NEXT:    ret
434 ; CHECK-SD-DOT-LABEL: add_v8i8_v8i32_sext:
435 ; CHECK-SD-DOT:       // %bb.0: // %entry
436 ; CHECK-SD-DOT-NEXT:    movi v1.2d, #0000000000000000
437 ; CHECK-SD-DOT-NEXT:    movi v2.8b, #1
438 ; CHECK-SD-DOT-NEXT:    sdot v1.2s, v0.8b, v2.8b
439 ; CHECK-SD-DOT-NEXT:    addp v0.2s, v1.2s, v1.2s
440 ; CHECK-SD-DOT-NEXT:    fmov w0, s0
441 ; CHECK-SD-DOT-NEXT:    ret
443 ; CHECK-GI-BASE-LABEL: add_v8i8_v8i32_sext:
444 ; CHECK-GI-BASE:       // %bb.0: // %entry
445 ; CHECK-GI-BASE-NEXT:    saddlv h0, v0.8b
446 ; CHECK-GI-BASE-NEXT:    fmov w8, s0
447 ; CHECK-GI-BASE-NEXT:    sxth w0, w8
448 ; CHECK-GI-BASE-NEXT:    ret
450 ; CHECK-GI-DOT-LABEL: add_v8i8_v8i32_sext:
451 ; CHECK-GI-DOT:       // %bb.0: // %entry
452 ; CHECK-GI-DOT-NEXT:    movi v1.8b, #1
453 ; CHECK-GI-DOT-NEXT:    movi v2.2d, #0000000000000000
454 ; CHECK-GI-DOT-NEXT:    sdot v2.2s, v0.8b, v1.8b
455 ; CHECK-GI-DOT-NEXT:    addp v0.2s, v2.2s, v2.2s
456 ; CHECK-GI-DOT-NEXT:    fmov w0, s0
457 ; CHECK-GI-DOT-NEXT:    ret
458 entry:
459   %xx = sext <8 x i8> %x to <8 x i32>
460   %z = call i32 @llvm.vector.reduce.add.v8i32(<8 x i32> %xx)
461   ret i32 %z
464 define i32 @add_v4i8_v4i32_zext(<4 x i8> %x) {
465 ; CHECK-SD-LABEL: add_v4i8_v4i32_zext:
466 ; CHECK-SD:       // %bb.0: // %entry
467 ; CHECK-SD-NEXT:    bic v0.4h, #255, lsl #8
468 ; CHECK-SD-NEXT:    ushll v0.4s, v0.4h, #0
469 ; CHECK-SD-NEXT:    addv s0, v0.4s
470 ; CHECK-SD-NEXT:    fmov w0, s0
471 ; CHECK-SD-NEXT:    ret
473 ; CHECK-GI-LABEL: add_v4i8_v4i32_zext:
474 ; CHECK-GI:       // %bb.0: // %entry
475 ; CHECK-GI-NEXT:    movi d1, #0xff00ff00ff00ff
476 ; CHECK-GI-NEXT:    and v0.8b, v0.8b, v1.8b
477 ; CHECK-GI-NEXT:    uaddlv s0, v0.4h
478 ; CHECK-GI-NEXT:    fmov w8, s0
479 ; CHECK-GI-NEXT:    and w0, w8, #0xffff
480 ; CHECK-GI-NEXT:    ret
481 entry:
482   %xx = zext <4 x i8> %x to <4 x i32>
483   %z = call i32 @llvm.vector.reduce.add.v4i32(<4 x i32> %xx)
484   ret i32 %z
487 define i32 @add_v4i8_v4i32_sext(<4 x i8> %x) {
488 ; CHECK-SD-LABEL: add_v4i8_v4i32_sext:
489 ; CHECK-SD:       // %bb.0: // %entry
490 ; CHECK-SD-NEXT:    ushll v0.4s, v0.4h, #0
491 ; CHECK-SD-NEXT:    shl v0.4s, v0.4s, #24
492 ; CHECK-SD-NEXT:    sshr v0.4s, v0.4s, #24
493 ; CHECK-SD-NEXT:    addv s0, v0.4s
494 ; CHECK-SD-NEXT:    fmov w0, s0
495 ; CHECK-SD-NEXT:    ret
497 ; CHECK-GI-LABEL: add_v4i8_v4i32_sext:
498 ; CHECK-GI:       // %bb.0: // %entry
499 ; CHECK-GI-NEXT:    shl v0.4h, v0.4h, #8
500 ; CHECK-GI-NEXT:    sshr v0.4h, v0.4h, #8
501 ; CHECK-GI-NEXT:    saddlv s0, v0.4h
502 ; CHECK-GI-NEXT:    fmov w8, s0
503 ; CHECK-GI-NEXT:    sxth w0, w8
504 ; CHECK-GI-NEXT:    ret
505 entry:
506   %xx = sext <4 x i8> %x to <4 x i32>
507   %z = call i32 @llvm.vector.reduce.add.v4i32(<4 x i32> %xx)
508   ret i32 %z
511 define zeroext i16 @add_v16i8_v16i16_zext(<16 x i8> %x) {
512 ; CHECK-SD-LABEL: add_v16i8_v16i16_zext:
513 ; CHECK-SD:       // %bb.0: // %entry
514 ; CHECK-SD-NEXT:    uaddlp v0.8h, v0.16b
515 ; CHECK-SD-NEXT:    addv h0, v0.8h
516 ; CHECK-SD-NEXT:    fmov w0, s0
517 ; CHECK-SD-NEXT:    ret
519 ; CHECK-GI-LABEL: add_v16i8_v16i16_zext:
520 ; CHECK-GI:       // %bb.0: // %entry
521 ; CHECK-GI-NEXT:    uaddlv h0, v0.16b
522 ; CHECK-GI-NEXT:    fmov w8, s0
523 ; CHECK-GI-NEXT:    and w0, w8, #0xffff
524 ; CHECK-GI-NEXT:    ret
525 entry:
526   %xx = zext <16 x i8> %x to <16 x i16>
527   %z = call i16 @llvm.vector.reduce.add.v16i16(<16 x i16> %xx)
528   ret i16 %z
531 define signext i16 @add_v16i8_v16i16_sext(<16 x i8> %x) {
532 ; CHECK-SD-LABEL: add_v16i8_v16i16_sext:
533 ; CHECK-SD:       // %bb.0: // %entry
534 ; CHECK-SD-NEXT:    saddlp v0.8h, v0.16b
535 ; CHECK-SD-NEXT:    addv h0, v0.8h
536 ; CHECK-SD-NEXT:    smov w0, v0.h[0]
537 ; CHECK-SD-NEXT:    ret
539 ; CHECK-GI-LABEL: add_v16i8_v16i16_sext:
540 ; CHECK-GI:       // %bb.0: // %entry
541 ; CHECK-GI-NEXT:    saddlv h0, v0.16b
542 ; CHECK-GI-NEXT:    fmov w8, s0
543 ; CHECK-GI-NEXT:    sxth w0, w8
544 ; CHECK-GI-NEXT:    ret
545 entry:
546   %xx = sext <16 x i8> %x to <16 x i16>
547   %z = call i16 @llvm.vector.reduce.add.v16i16(<16 x i16> %xx)
548   ret i16 %z
551 define zeroext i16 @add_v8i8_v8i16_zext(<8 x i8> %x) {
552 ; CHECK-SD-LABEL: add_v8i8_v8i16_zext:
553 ; CHECK-SD:       // %bb.0: // %entry
554 ; CHECK-SD-NEXT:    ushll v0.8h, v0.8b, #0
555 ; CHECK-SD-NEXT:    addv h0, v0.8h
556 ; CHECK-SD-NEXT:    fmov w0, s0
557 ; CHECK-SD-NEXT:    ret
559 ; CHECK-GI-LABEL: add_v8i8_v8i16_zext:
560 ; CHECK-GI:       // %bb.0: // %entry
561 ; CHECK-GI-NEXT:    uaddlv h0, v0.8b
562 ; CHECK-GI-NEXT:    fmov w8, s0
563 ; CHECK-GI-NEXT:    and w0, w8, #0xffff
564 ; CHECK-GI-NEXT:    ret
565 entry:
566   %xx = zext <8 x i8> %x to <8 x i16>
567   %z = call i16 @llvm.vector.reduce.add.v8i16(<8 x i16> %xx)
568   ret i16 %z
571 define signext i16 @add_v8i8_v8i16_sext(<8 x i8> %x) {
572 ; CHECK-SD-LABEL: add_v8i8_v8i16_sext:
573 ; CHECK-SD:       // %bb.0: // %entry
574 ; CHECK-SD-NEXT:    sshll v0.8h, v0.8b, #0
575 ; CHECK-SD-NEXT:    addv h0, v0.8h
576 ; CHECK-SD-NEXT:    smov w0, v0.h[0]
577 ; CHECK-SD-NEXT:    ret
579 ; CHECK-GI-LABEL: add_v8i8_v8i16_sext:
580 ; CHECK-GI:       // %bb.0: // %entry
581 ; CHECK-GI-NEXT:    saddlv h0, v0.8b
582 ; CHECK-GI-NEXT:    fmov w8, s0
583 ; CHECK-GI-NEXT:    sxth w0, w8
584 ; CHECK-GI-NEXT:    ret
585 entry:
586   %xx = sext <8 x i8> %x to <8 x i16>
587   %z = call i16 @llvm.vector.reduce.add.v8i16(<8 x i16> %xx)
588   ret i16 %z
591 define zeroext i8 @add_v16i8_v16i8(<16 x i8> %x) {
592 ; CHECK-SD-LABEL: add_v16i8_v16i8:
593 ; CHECK-SD:       // %bb.0: // %entry
594 ; CHECK-SD-NEXT:    addv b0, v0.16b
595 ; CHECK-SD-NEXT:    fmov w0, s0
596 ; CHECK-SD-NEXT:    ret
598 ; CHECK-GI-LABEL: add_v16i8_v16i8:
599 ; CHECK-GI:       // %bb.0: // %entry
600 ; CHECK-GI-NEXT:    addv b0, v0.16b
601 ; CHECK-GI-NEXT:    fmov w8, s0
602 ; CHECK-GI-NEXT:    uxtb w0, w8
603 ; CHECK-GI-NEXT:    ret
604 entry:
605   %z = call i8 @llvm.vector.reduce.add.v16i8(<16 x i8> %x)
606   ret i8 %z
609 define i64 @add_v16i8_v16i64_zext(<16 x i8> %x) {
610 ; CHECK-SD-LABEL: add_v16i8_v16i64_zext:
611 ; CHECK-SD:       // %bb.0: // %entry
612 ; CHECK-SD-NEXT:    ushll2 v1.8h, v0.16b, #0
613 ; CHECK-SD-NEXT:    ushll v0.8h, v0.8b, #0
614 ; CHECK-SD-NEXT:    ushll2 v2.4s, v1.8h, #0
615 ; CHECK-SD-NEXT:    ushll2 v3.4s, v0.8h, #0
616 ; CHECK-SD-NEXT:    ushll v1.4s, v1.4h, #0
617 ; CHECK-SD-NEXT:    ushll v0.4s, v0.4h, #0
618 ; CHECK-SD-NEXT:    uaddl2 v4.2d, v3.4s, v2.4s
619 ; CHECK-SD-NEXT:    uaddl v2.2d, v3.2s, v2.2s
620 ; CHECK-SD-NEXT:    uaddl2 v5.2d, v0.4s, v1.4s
621 ; CHECK-SD-NEXT:    uaddl v0.2d, v0.2s, v1.2s
622 ; CHECK-SD-NEXT:    add v1.2d, v5.2d, v4.2d
623 ; CHECK-SD-NEXT:    add v0.2d, v0.2d, v2.2d
624 ; CHECK-SD-NEXT:    add v0.2d, v0.2d, v1.2d
625 ; CHECK-SD-NEXT:    addp d0, v0.2d
626 ; CHECK-SD-NEXT:    fmov x0, d0
627 ; CHECK-SD-NEXT:    ret
629 ; CHECK-GI-LABEL: add_v16i8_v16i64_zext:
630 ; CHECK-GI:       // %bb.0: // %entry
631 ; CHECK-GI-NEXT:    uaddlv h0, v0.16b
632 ; CHECK-GI-NEXT:    fmov w8, s0
633 ; CHECK-GI-NEXT:    and x0, x8, #0xffff
634 ; CHECK-GI-NEXT:    ret
635 entry:
636   %xx = zext <16 x i8> %x to <16 x i64>
637   %z = call i64 @llvm.vector.reduce.add.v16i64(<16 x i64> %xx)
638   ret i64 %z
641 define i64 @add_v16i8_v16i64_sext(<16 x i8> %x) {
642 ; CHECK-SD-LABEL: add_v16i8_v16i64_sext:
643 ; CHECK-SD:       // %bb.0: // %entry
644 ; CHECK-SD-NEXT:    sshll2 v1.8h, v0.16b, #0
645 ; CHECK-SD-NEXT:    sshll v0.8h, v0.8b, #0
646 ; CHECK-SD-NEXT:    sshll2 v2.4s, v1.8h, #0
647 ; CHECK-SD-NEXT:    sshll2 v3.4s, v0.8h, #0
648 ; CHECK-SD-NEXT:    sshll v1.4s, v1.4h, #0
649 ; CHECK-SD-NEXT:    sshll v0.4s, v0.4h, #0
650 ; CHECK-SD-NEXT:    saddl2 v4.2d, v3.4s, v2.4s
651 ; CHECK-SD-NEXT:    saddl v2.2d, v3.2s, v2.2s
652 ; CHECK-SD-NEXT:    saddl2 v5.2d, v0.4s, v1.4s
653 ; CHECK-SD-NEXT:    saddl v0.2d, v0.2s, v1.2s
654 ; CHECK-SD-NEXT:    add v1.2d, v5.2d, v4.2d
655 ; CHECK-SD-NEXT:    add v0.2d, v0.2d, v2.2d
656 ; CHECK-SD-NEXT:    add v0.2d, v0.2d, v1.2d
657 ; CHECK-SD-NEXT:    addp d0, v0.2d
658 ; CHECK-SD-NEXT:    fmov x0, d0
659 ; CHECK-SD-NEXT:    ret
661 ; CHECK-GI-LABEL: add_v16i8_v16i64_sext:
662 ; CHECK-GI:       // %bb.0: // %entry
663 ; CHECK-GI-NEXT:    saddlv h0, v0.16b
664 ; CHECK-GI-NEXT:    fmov w8, s0
665 ; CHECK-GI-NEXT:    sxth x0, w8
666 ; CHECK-GI-NEXT:    ret
667 entry:
668   %xx = sext <16 x i8> %x to <16 x i64>
669   %z = call i64 @llvm.vector.reduce.add.v16i64(<16 x i64> %xx)
670   ret i64 %z
673 define i64 @add_v8i8_v8i64_zext(<8 x i8> %x) {
674 ; CHECK-SD-LABEL: add_v8i8_v8i64_zext:
675 ; CHECK-SD:       // %bb.0: // %entry
676 ; CHECK-SD-NEXT:    ushll v0.8h, v0.8b, #0
677 ; CHECK-SD-NEXT:    ushll2 v1.4s, v0.8h, #0
678 ; CHECK-SD-NEXT:    ushll v0.4s, v0.4h, #0
679 ; CHECK-SD-NEXT:    uaddl2 v2.2d, v0.4s, v1.4s
680 ; CHECK-SD-NEXT:    uaddl v0.2d, v0.2s, v1.2s
681 ; CHECK-SD-NEXT:    add v0.2d, v0.2d, v2.2d
682 ; CHECK-SD-NEXT:    addp d0, v0.2d
683 ; CHECK-SD-NEXT:    fmov x0, d0
684 ; CHECK-SD-NEXT:    ret
686 ; CHECK-GI-LABEL: add_v8i8_v8i64_zext:
687 ; CHECK-GI:       // %bb.0: // %entry
688 ; CHECK-GI-NEXT:    uaddlv h0, v0.8b
689 ; CHECK-GI-NEXT:    fmov w8, s0
690 ; CHECK-GI-NEXT:    and x0, x8, #0xffff
691 ; CHECK-GI-NEXT:    ret
692 entry:
693   %xx = zext <8 x i8> %x to <8 x i64>
694   %z = call i64 @llvm.vector.reduce.add.v8i64(<8 x i64> %xx)
695   ret i64 %z
698 define i64 @add_v8i8_v8i64_sext(<8 x i8> %x) {
699 ; CHECK-SD-LABEL: add_v8i8_v8i64_sext:
700 ; CHECK-SD:       // %bb.0: // %entry
701 ; CHECK-SD-NEXT:    sshll v0.8h, v0.8b, #0
702 ; CHECK-SD-NEXT:    sshll2 v1.4s, v0.8h, #0
703 ; CHECK-SD-NEXT:    sshll v0.4s, v0.4h, #0
704 ; CHECK-SD-NEXT:    saddl2 v2.2d, v0.4s, v1.4s
705 ; CHECK-SD-NEXT:    saddl v0.2d, v0.2s, v1.2s
706 ; CHECK-SD-NEXT:    add v0.2d, v0.2d, v2.2d
707 ; CHECK-SD-NEXT:    addp d0, v0.2d
708 ; CHECK-SD-NEXT:    fmov x0, d0
709 ; CHECK-SD-NEXT:    ret
711 ; CHECK-GI-LABEL: add_v8i8_v8i64_sext:
712 ; CHECK-GI:       // %bb.0: // %entry
713 ; CHECK-GI-NEXT:    saddlv h0, v0.8b
714 ; CHECK-GI-NEXT:    fmov w8, s0
715 ; CHECK-GI-NEXT:    sxth x0, w8
716 ; CHECK-GI-NEXT:    ret
717 entry:
718   %xx = sext <8 x i8> %x to <8 x i64>
719   %z = call i64 @llvm.vector.reduce.add.v8i64(<8 x i64> %xx)
720   ret i64 %z
723 define i64 @add_v4i8_v4i64_zext(<4 x i8> %x) {
724 ; CHECK-SD-LABEL: add_v4i8_v4i64_zext:
725 ; CHECK-SD:       // %bb.0: // %entry
726 ; CHECK-SD-NEXT:    bic v0.4h, #255, lsl #8
727 ; CHECK-SD-NEXT:    ushll v0.4s, v0.4h, #0
728 ; CHECK-SD-NEXT:    uaddlv d0, v0.4s
729 ; CHECK-SD-NEXT:    fmov x0, d0
730 ; CHECK-SD-NEXT:    ret
732 ; CHECK-GI-LABEL: add_v4i8_v4i64_zext:
733 ; CHECK-GI:       // %bb.0: // %entry
734 ; CHECK-GI-NEXT:    movi d1, #0xff00ff00ff00ff
735 ; CHECK-GI-NEXT:    and v0.8b, v0.8b, v1.8b
736 ; CHECK-GI-NEXT:    uaddlv s0, v0.4h
737 ; CHECK-GI-NEXT:    fmov w8, s0
738 ; CHECK-GI-NEXT:    and x0, x8, #0xffff
739 ; CHECK-GI-NEXT:    ret
740 entry:
741   %xx = zext <4 x i8> %x to <4 x i64>
742   %z = call i64 @llvm.vector.reduce.add.v4i64(<4 x i64> %xx)
743   ret i64 %z
746 define i64 @add_v4i8_v4i64_sext(<4 x i8> %x) {
747 ; CHECK-SD-LABEL: add_v4i8_v4i64_sext:
748 ; CHECK-SD:       // %bb.0: // %entry
749 ; CHECK-SD-NEXT:    ushll v0.4s, v0.4h, #0
750 ; CHECK-SD-NEXT:    ushll v1.2d, v0.2s, #0
751 ; CHECK-SD-NEXT:    ushll2 v0.2d, v0.4s, #0
752 ; CHECK-SD-NEXT:    shl v1.2d, v1.2d, #56
753 ; CHECK-SD-NEXT:    shl v0.2d, v0.2d, #56
754 ; CHECK-SD-NEXT:    sshr v1.2d, v1.2d, #56
755 ; CHECK-SD-NEXT:    ssra v1.2d, v0.2d, #56
756 ; CHECK-SD-NEXT:    addp d0, v1.2d
757 ; CHECK-SD-NEXT:    fmov x0, d0
758 ; CHECK-SD-NEXT:    ret
760 ; CHECK-GI-LABEL: add_v4i8_v4i64_sext:
761 ; CHECK-GI:       // %bb.0: // %entry
762 ; CHECK-GI-NEXT:    shl v0.4h, v0.4h, #8
763 ; CHECK-GI-NEXT:    sshr v0.4h, v0.4h, #8
764 ; CHECK-GI-NEXT:    saddlv s0, v0.4h
765 ; CHECK-GI-NEXT:    fmov w8, s0
766 ; CHECK-GI-NEXT:    sxth x0, w8
767 ; CHECK-GI-NEXT:    ret
768 entry:
769   %xx = sext <4 x i8> %x to <4 x i64>
770   %z = call i64 @llvm.vector.reduce.add.v4i64(<4 x i64> %xx)
771   ret i64 %z
774 define i64 @add_v2i8_v2i64_zext(<2 x i8> %x) {
775 ; CHECK-SD-LABEL: add_v2i8_v2i64_zext:
776 ; CHECK-SD:       // %bb.0: // %entry
777 ; CHECK-SD-NEXT:    movi d1, #0x0000ff000000ff
778 ; CHECK-SD-NEXT:    and v0.8b, v0.8b, v1.8b
779 ; CHECK-SD-NEXT:    ushll v0.2d, v0.2s, #0
780 ; CHECK-SD-NEXT:    addp d0, v0.2d
781 ; CHECK-SD-NEXT:    fmov x0, d0
782 ; CHECK-SD-NEXT:    ret
784 ; CHECK-GI-LABEL: add_v2i8_v2i64_zext:
785 ; CHECK-GI:       // %bb.0: // %entry
786 ; CHECK-GI-NEXT:    movi v1.2d, #0x000000000000ff
787 ; CHECK-GI-NEXT:    ushll v0.2d, v0.2s, #0
788 ; CHECK-GI-NEXT:    and v0.16b, v0.16b, v1.16b
789 ; CHECK-GI-NEXT:    addp d0, v0.2d
790 ; CHECK-GI-NEXT:    fmov x0, d0
791 ; CHECK-GI-NEXT:    ret
792 entry:
793   %xx = zext <2 x i8> %x to <2 x i64>
794   %z = call i64 @llvm.vector.reduce.add.v2i64(<2 x i64> %xx)
795   ret i64 %z
798 define i64 @add_v2i8_v2i64_sext(<2 x i8> %x) {
799 ; CHECK-LABEL: add_v2i8_v2i64_sext:
800 ; CHECK:       // %bb.0: // %entry
801 ; CHECK-NEXT:    ushll v0.2d, v0.2s, #0
802 ; CHECK-NEXT:    shl v0.2d, v0.2d, #56
803 ; CHECK-NEXT:    sshr v0.2d, v0.2d, #56
804 ; CHECK-NEXT:    addp d0, v0.2d
805 ; CHECK-NEXT:    fmov x0, d0
806 ; CHECK-NEXT:    ret
807 entry:
808   %xx = sext <2 x i8> %x to <2 x i64>
809   %z = call i64 @llvm.vector.reduce.add.v2i64(<2 x i64> %xx)
810   ret i64 %z
813 define i64 @add_v2i64_v2i64(<2 x i64> %x) {
814 ; CHECK-LABEL: add_v2i64_v2i64:
815 ; CHECK:       // %bb.0: // %entry
816 ; CHECK-NEXT:    addp d0, v0.2d
817 ; CHECK-NEXT:    fmov x0, d0
818 ; CHECK-NEXT:    ret
819 entry:
820   %z = call i64 @llvm.vector.reduce.add.v2i64(<2 x i64> %x)
821   ret i64 %z
824 define i32 @add_v4i32_v4i32_acc(<4 x i32> %x, i32 %a) {
825 ; CHECK-LABEL: add_v4i32_v4i32_acc:
826 ; CHECK:       // %bb.0: // %entry
827 ; CHECK-NEXT:    addv s0, v0.4s
828 ; CHECK-NEXT:    fmov w8, s0
829 ; CHECK-NEXT:    add w0, w8, w0
830 ; CHECK-NEXT:    ret
831 entry:
832   %z = call i32 @llvm.vector.reduce.add.v4i32(<4 x i32> %x)
833   %r = add i32 %z, %a
834   ret i32 %r
837 define i64 @add_v4i32_v4i64_acc_zext(<4 x i32> %x, i64 %a) {
838 ; CHECK-LABEL: add_v4i32_v4i64_acc_zext:
839 ; CHECK:       // %bb.0: // %entry
840 ; CHECK-NEXT:    uaddlv d0, v0.4s
841 ; CHECK-NEXT:    fmov x8, d0
842 ; CHECK-NEXT:    add x0, x8, x0
843 ; CHECK-NEXT:    ret
844 entry:
845   %xx = zext <4 x i32> %x to <4 x i64>
846   %z = call i64 @llvm.vector.reduce.add.v4i64(<4 x i64> %xx)
847   %r = add i64 %z, %a
848   ret i64 %r
851 define i64 @add_v4i32_v4i64_acc_sext(<4 x i32> %x, i64 %a) {
852 ; CHECK-LABEL: add_v4i32_v4i64_acc_sext:
853 ; CHECK:       // %bb.0: // %entry
854 ; CHECK-NEXT:    saddlv d0, v0.4s
855 ; CHECK-NEXT:    fmov x8, d0
856 ; CHECK-NEXT:    add x0, x8, x0
857 ; CHECK-NEXT:    ret
858 entry:
859   %xx = sext <4 x i32> %x to <4 x i64>
860   %z = call i64 @llvm.vector.reduce.add.v4i64(<4 x i64> %xx)
861   %r = add i64 %z, %a
862   ret i64 %r
865 define i64 @add_v2i32_v2i64_acc_zext(<2 x i32> %x, i64 %a) {
866 ; CHECK-LABEL: add_v2i32_v2i64_acc_zext:
867 ; CHECK:       // %bb.0: // %entry
868 ; CHECK-NEXT:    ushll v0.2d, v0.2s, #0
869 ; CHECK-NEXT:    addp d0, v0.2d
870 ; CHECK-NEXT:    fmov x8, d0
871 ; CHECK-NEXT:    add x0, x8, x0
872 ; CHECK-NEXT:    ret
873 entry:
874   %xx = zext <2 x i32> %x to <2 x i64>
875   %z = call i64 @llvm.vector.reduce.add.v2i64(<2 x i64> %xx)
876   %r = add i64 %z, %a
877   ret i64 %r
880 define i64 @add_v2i32_v2i64_acc_sext(<2 x i32> %x, i64 %a) {
881 ; CHECK-LABEL: add_v2i32_v2i64_acc_sext:
882 ; CHECK:       // %bb.0: // %entry
883 ; CHECK-NEXT:    sshll v0.2d, v0.2s, #0
884 ; CHECK-NEXT:    addp d0, v0.2d
885 ; CHECK-NEXT:    fmov x8, d0
886 ; CHECK-NEXT:    add x0, x8, x0
887 ; CHECK-NEXT:    ret
888 entry:
889   %xx = sext <2 x i32> %x to <2 x i64>
890   %z = call i64 @llvm.vector.reduce.add.v2i64(<2 x i64> %xx)
891   %r = add i64 %z, %a
892   ret i64 %r
895 define i32 @add_v8i16_v8i32_acc_zext(<8 x i16> %x, i32 %a) {
896 ; CHECK-LABEL: add_v8i16_v8i32_acc_zext:
897 ; CHECK:       // %bb.0: // %entry
898 ; CHECK-NEXT:    uaddlv s0, v0.8h
899 ; CHECK-NEXT:    fmov w8, s0
900 ; CHECK-NEXT:    add w0, w8, w0
901 ; CHECK-NEXT:    ret
902 entry:
903   %xx = zext <8 x i16> %x to <8 x i32>
904   %z = call i32 @llvm.vector.reduce.add.v8i32(<8 x i32> %xx)
905   %r = add i32 %z, %a
906   ret i32 %r
909 define i32 @add_v8i16_v8i32_acc_sext(<8 x i16> %x, i32 %a) {
910 ; CHECK-LABEL: add_v8i16_v8i32_acc_sext:
911 ; CHECK:       // %bb.0: // %entry
912 ; CHECK-NEXT:    saddlv s0, v0.8h
913 ; CHECK-NEXT:    fmov w8, s0
914 ; CHECK-NEXT:    add w0, w8, w0
915 ; CHECK-NEXT:    ret
916 entry:
917   %xx = sext <8 x i16> %x to <8 x i32>
918   %z = call i32 @llvm.vector.reduce.add.v8i32(<8 x i32> %xx)
919   %r = add i32 %z, %a
920   ret i32 %r
923 define i32 @add_v4i16_v4i32_acc_zext(<4 x i16> %x, i32 %a) {
924 ; CHECK-SD-LABEL: add_v4i16_v4i32_acc_zext:
925 ; CHECK-SD:       // %bb.0: // %entry
926 ; CHECK-SD-NEXT:    ushll v0.4s, v0.4h, #0
927 ; CHECK-SD-NEXT:    addv s0, v0.4s
928 ; CHECK-SD-NEXT:    fmov w8, s0
929 ; CHECK-SD-NEXT:    add w0, w8, w0
930 ; CHECK-SD-NEXT:    ret
932 ; CHECK-GI-LABEL: add_v4i16_v4i32_acc_zext:
933 ; CHECK-GI:       // %bb.0: // %entry
934 ; CHECK-GI-NEXT:    uaddlv s0, v0.4h
935 ; CHECK-GI-NEXT:    fmov w8, s0
936 ; CHECK-GI-NEXT:    add w0, w8, w0
937 ; CHECK-GI-NEXT:    ret
938 entry:
939   %xx = zext <4 x i16> %x to <4 x i32>
940   %z = call i32 @llvm.vector.reduce.add.v4i32(<4 x i32> %xx)
941   %r = add i32 %z, %a
942   ret i32 %r
945 define i32 @add_v4i16_v4i32_acc_sext(<4 x i16> %x, i32 %a) {
946 ; CHECK-SD-LABEL: add_v4i16_v4i32_acc_sext:
947 ; CHECK-SD:       // %bb.0: // %entry
948 ; CHECK-SD-NEXT:    sshll v0.4s, v0.4h, #0
949 ; CHECK-SD-NEXT:    addv s0, v0.4s
950 ; CHECK-SD-NEXT:    fmov w8, s0
951 ; CHECK-SD-NEXT:    add w0, w8, w0
952 ; CHECK-SD-NEXT:    ret
954 ; CHECK-GI-LABEL: add_v4i16_v4i32_acc_sext:
955 ; CHECK-GI:       // %bb.0: // %entry
956 ; CHECK-GI-NEXT:    saddlv s0, v0.4h
957 ; CHECK-GI-NEXT:    fmov w8, s0
958 ; CHECK-GI-NEXT:    add w0, w8, w0
959 ; CHECK-GI-NEXT:    ret
960 entry:
961   %xx = sext <4 x i16> %x to <4 x i32>
962   %z = call i32 @llvm.vector.reduce.add.v4i32(<4 x i32> %xx)
963   %r = add i32 %z, %a
964   ret i32 %r
967 define zeroext i16 @add_v8i16_v8i16_acc(<8 x i16> %x, i16 %a) {
968 ; CHECK-SD-LABEL: add_v8i16_v8i16_acc:
969 ; CHECK-SD:       // %bb.0: // %entry
970 ; CHECK-SD-NEXT:    addv h0, v0.8h
971 ; CHECK-SD-NEXT:    fmov w8, s0
972 ; CHECK-SD-NEXT:    add w8, w8, w0
973 ; CHECK-SD-NEXT:    and w0, w8, #0xffff
974 ; CHECK-SD-NEXT:    ret
976 ; CHECK-GI-LABEL: add_v8i16_v8i16_acc:
977 ; CHECK-GI:       // %bb.0: // %entry
978 ; CHECK-GI-NEXT:    addv h0, v0.8h
979 ; CHECK-GI-NEXT:    fmov w8, s0
980 ; CHECK-GI-NEXT:    add w8, w0, w8, uxth
981 ; CHECK-GI-NEXT:    and w0, w8, #0xffff
982 ; CHECK-GI-NEXT:    ret
983 entry:
984   %z = call i16 @llvm.vector.reduce.add.v8i16(<8 x i16> %x)
985   %r = add i16 %z, %a
986   ret i16 %r
989 define i64 @add_v8i16_v8i64_acc_zext(<8 x i16> %x, i64 %a) {
990 ; CHECK-SD-LABEL: add_v8i16_v8i64_acc_zext:
991 ; CHECK-SD:       // %bb.0: // %entry
992 ; CHECK-SD-NEXT:    ushll2 v1.4s, v0.8h, #0
993 ; CHECK-SD-NEXT:    ushll v0.4s, v0.4h, #0
994 ; CHECK-SD-NEXT:    uaddl2 v2.2d, v0.4s, v1.4s
995 ; CHECK-SD-NEXT:    uaddl v0.2d, v0.2s, v1.2s
996 ; CHECK-SD-NEXT:    add v0.2d, v0.2d, v2.2d
997 ; CHECK-SD-NEXT:    addp d0, v0.2d
998 ; CHECK-SD-NEXT:    fmov x8, d0
999 ; CHECK-SD-NEXT:    add x0, x8, x0
1000 ; CHECK-SD-NEXT:    ret
1002 ; CHECK-GI-LABEL: add_v8i16_v8i64_acc_zext:
1003 ; CHECK-GI:       // %bb.0: // %entry
1004 ; CHECK-GI-NEXT:    uaddlv s0, v0.8h
1005 ; CHECK-GI-NEXT:    fmov w8, s0
1006 ; CHECK-GI-NEXT:    add x0, x0, w8, uxtw
1007 ; CHECK-GI-NEXT:    ret
1008 entry:
1009   %xx = zext <8 x i16> %x to <8 x i64>
1010   %z = call i64 @llvm.vector.reduce.add.v8i64(<8 x i64> %xx)
1011   %r = add i64 %z, %a
1012   ret i64 %r
1015 define i64 @add_v8i16_v8i64_acc_sext(<8 x i16> %x, i64 %a) {
1016 ; CHECK-SD-LABEL: add_v8i16_v8i64_acc_sext:
1017 ; CHECK-SD:       // %bb.0: // %entry
1018 ; CHECK-SD-NEXT:    sshll2 v1.4s, v0.8h, #0
1019 ; CHECK-SD-NEXT:    sshll v0.4s, v0.4h, #0
1020 ; CHECK-SD-NEXT:    saddl2 v2.2d, v0.4s, v1.4s
1021 ; CHECK-SD-NEXT:    saddl v0.2d, v0.2s, v1.2s
1022 ; CHECK-SD-NEXT:    add v0.2d, v0.2d, v2.2d
1023 ; CHECK-SD-NEXT:    addp d0, v0.2d
1024 ; CHECK-SD-NEXT:    fmov x8, d0
1025 ; CHECK-SD-NEXT:    add x0, x8, x0
1026 ; CHECK-SD-NEXT:    ret
1028 ; CHECK-GI-LABEL: add_v8i16_v8i64_acc_sext:
1029 ; CHECK-GI:       // %bb.0: // %entry
1030 ; CHECK-GI-NEXT:    saddlv s0, v0.8h
1031 ; CHECK-GI-NEXT:    fmov w8, s0
1032 ; CHECK-GI-NEXT:    add x0, x0, w8, sxtw
1033 ; CHECK-GI-NEXT:    ret
1034 entry:
1035   %xx = sext <8 x i16> %x to <8 x i64>
1036   %z = call i64 @llvm.vector.reduce.add.v8i64(<8 x i64> %xx)
1037   %r = add i64 %z, %a
1038   ret i64 %r
1041 define i64 @add_v4i16_v4i64_acc_zext(<4 x i16> %x, i64 %a) {
1042 ; CHECK-SD-LABEL: add_v4i16_v4i64_acc_zext:
1043 ; CHECK-SD:       // %bb.0: // %entry
1044 ; CHECK-SD-NEXT:    ushll v0.4s, v0.4h, #0
1045 ; CHECK-SD-NEXT:    uaddlv d0, v0.4s
1046 ; CHECK-SD-NEXT:    fmov x8, d0
1047 ; CHECK-SD-NEXT:    add x0, x8, x0
1048 ; CHECK-SD-NEXT:    ret
1050 ; CHECK-GI-LABEL: add_v4i16_v4i64_acc_zext:
1051 ; CHECK-GI:       // %bb.0: // %entry
1052 ; CHECK-GI-NEXT:    uaddlv s0, v0.4h
1053 ; CHECK-GI-NEXT:    fmov w8, s0
1054 ; CHECK-GI-NEXT:    add x0, x0, w8, uxtw
1055 ; CHECK-GI-NEXT:    ret
1056 entry:
1057   %xx = zext <4 x i16> %x to <4 x i64>
1058   %z = call i64 @llvm.vector.reduce.add.v4i64(<4 x i64> %xx)
1059   %r = add i64 %z, %a
1060   ret i64 %r
1063 define i64 @add_v4i16_v4i64_acc_sext(<4 x i16> %x, i64 %a) {
1064 ; CHECK-SD-LABEL: add_v4i16_v4i64_acc_sext:
1065 ; CHECK-SD:       // %bb.0: // %entry
1066 ; CHECK-SD-NEXT:    sshll v0.4s, v0.4h, #0
1067 ; CHECK-SD-NEXT:    saddlv d0, v0.4s
1068 ; CHECK-SD-NEXT:    fmov x8, d0
1069 ; CHECK-SD-NEXT:    add x0, x8, x0
1070 ; CHECK-SD-NEXT:    ret
1072 ; CHECK-GI-LABEL: add_v4i16_v4i64_acc_sext:
1073 ; CHECK-GI:       // %bb.0: // %entry
1074 ; CHECK-GI-NEXT:    saddlv s0, v0.4h
1075 ; CHECK-GI-NEXT:    fmov w8, s0
1076 ; CHECK-GI-NEXT:    add x0, x0, w8, sxtw
1077 ; CHECK-GI-NEXT:    ret
1078 entry:
1079   %xx = sext <4 x i16> %x to <4 x i64>
1080   %z = call i64 @llvm.vector.reduce.add.v4i64(<4 x i64> %xx)
1081   %r = add i64 %z, %a
1082   ret i64 %r
1085 define i64 @add_v2i16_v2i64_acc_zext(<2 x i16> %x, i64 %a) {
1086 ; CHECK-SD-LABEL: add_v2i16_v2i64_acc_zext:
1087 ; CHECK-SD:       // %bb.0: // %entry
1088 ; CHECK-SD-NEXT:    movi d1, #0x00ffff0000ffff
1089 ; CHECK-SD-NEXT:    and v0.8b, v0.8b, v1.8b
1090 ; CHECK-SD-NEXT:    ushll v0.2d, v0.2s, #0
1091 ; CHECK-SD-NEXT:    addp d0, v0.2d
1092 ; CHECK-SD-NEXT:    fmov x8, d0
1093 ; CHECK-SD-NEXT:    add x0, x8, x0
1094 ; CHECK-SD-NEXT:    ret
1096 ; CHECK-GI-LABEL: add_v2i16_v2i64_acc_zext:
1097 ; CHECK-GI:       // %bb.0: // %entry
1098 ; CHECK-GI-NEXT:    movi v1.2d, #0x0000000000ffff
1099 ; CHECK-GI-NEXT:    ushll v0.2d, v0.2s, #0
1100 ; CHECK-GI-NEXT:    and v0.16b, v0.16b, v1.16b
1101 ; CHECK-GI-NEXT:    addp d0, v0.2d
1102 ; CHECK-GI-NEXT:    fmov x8, d0
1103 ; CHECK-GI-NEXT:    add x0, x8, x0
1104 ; CHECK-GI-NEXT:    ret
1105 entry:
1106   %xx = zext <2 x i16> %x to <2 x i64>
1107   %z = call i64 @llvm.vector.reduce.add.v2i64(<2 x i64> %xx)
1108   %r = add i64 %z, %a
1109   ret i64 %r
1112 define i64 @add_v2i16_v2i64_acc_sext(<2 x i16> %x, i64 %a) {
1113 ; CHECK-LABEL: add_v2i16_v2i64_acc_sext:
1114 ; CHECK:       // %bb.0: // %entry
1115 ; CHECK-NEXT:    ushll v0.2d, v0.2s, #0
1116 ; CHECK-NEXT:    shl v0.2d, v0.2d, #48
1117 ; CHECK-NEXT:    sshr v0.2d, v0.2d, #48
1118 ; CHECK-NEXT:    addp d0, v0.2d
1119 ; CHECK-NEXT:    fmov x8, d0
1120 ; CHECK-NEXT:    add x0, x8, x0
1121 ; CHECK-NEXT:    ret
1122 entry:
1123   %xx = sext <2 x i16> %x to <2 x i64>
1124   %z = call i64 @llvm.vector.reduce.add.v2i64(<2 x i64> %xx)
1125   %r = add i64 %z, %a
1126   ret i64 %r
1129 define i32 @add_v16i8_v16i32_acc_zext(<16 x i8> %x, i32 %a) {
1130 ; CHECK-SD-BASE-LABEL: add_v16i8_v16i32_acc_zext:
1131 ; CHECK-SD-BASE:       // %bb.0: // %entry
1132 ; CHECK-SD-BASE-NEXT:    ushll2 v1.8h, v0.16b, #0
1133 ; CHECK-SD-BASE-NEXT:    ushll v0.8h, v0.8b, #0
1134 ; CHECK-SD-BASE-NEXT:    uaddl2 v2.4s, v0.8h, v1.8h
1135 ; CHECK-SD-BASE-NEXT:    uaddl v0.4s, v0.4h, v1.4h
1136 ; CHECK-SD-BASE-NEXT:    add v0.4s, v0.4s, v2.4s
1137 ; CHECK-SD-BASE-NEXT:    addv s0, v0.4s
1138 ; CHECK-SD-BASE-NEXT:    fmov w8, s0
1139 ; CHECK-SD-BASE-NEXT:    add w0, w8, w0
1140 ; CHECK-SD-BASE-NEXT:    ret
1142 ; CHECK-SD-DOT-LABEL: add_v16i8_v16i32_acc_zext:
1143 ; CHECK-SD-DOT:       // %bb.0: // %entry
1144 ; CHECK-SD-DOT-NEXT:    movi v1.16b, #1
1145 ; CHECK-SD-DOT-NEXT:    movi v2.2d, #0000000000000000
1146 ; CHECK-SD-DOT-NEXT:    udot v2.4s, v0.16b, v1.16b
1147 ; CHECK-SD-DOT-NEXT:    addv s0, v2.4s
1148 ; CHECK-SD-DOT-NEXT:    fmov w8, s0
1149 ; CHECK-SD-DOT-NEXT:    add w0, w8, w0
1150 ; CHECK-SD-DOT-NEXT:    ret
1152 ; CHECK-GI-BASE-LABEL: add_v16i8_v16i32_acc_zext:
1153 ; CHECK-GI-BASE:       // %bb.0: // %entry
1154 ; CHECK-GI-BASE-NEXT:    uaddlv h0, v0.16b
1155 ; CHECK-GI-BASE-NEXT:    fmov w8, s0
1156 ; CHECK-GI-BASE-NEXT:    add w0, w0, w8, uxth
1157 ; CHECK-GI-BASE-NEXT:    ret
1159 ; CHECK-GI-DOT-LABEL: add_v16i8_v16i32_acc_zext:
1160 ; CHECK-GI-DOT:       // %bb.0: // %entry
1161 ; CHECK-GI-DOT-NEXT:    movi v1.16b, #1
1162 ; CHECK-GI-DOT-NEXT:    movi v2.2d, #0000000000000000
1163 ; CHECK-GI-DOT-NEXT:    udot v2.4s, v0.16b, v1.16b
1164 ; CHECK-GI-DOT-NEXT:    addv s0, v2.4s
1165 ; CHECK-GI-DOT-NEXT:    fmov w8, s0
1166 ; CHECK-GI-DOT-NEXT:    add w0, w8, w0
1167 ; CHECK-GI-DOT-NEXT:    ret
1168 entry:
1169   %xx = zext <16 x i8> %x to <16 x i32>
1170   %z = call i32 @llvm.vector.reduce.add.v16i32(<16 x i32> %xx)
1171   %r = add i32 %z, %a
1172   ret i32 %r
1175 define i32 @add_v16i8_v16i32_acc_sext(<16 x i8> %x, i32 %a) {
1176 ; CHECK-SD-BASE-LABEL: add_v16i8_v16i32_acc_sext:
1177 ; CHECK-SD-BASE:       // %bb.0: // %entry
1178 ; CHECK-SD-BASE-NEXT:    sshll2 v1.8h, v0.16b, #0
1179 ; CHECK-SD-BASE-NEXT:    sshll v0.8h, v0.8b, #0
1180 ; CHECK-SD-BASE-NEXT:    saddl2 v2.4s, v0.8h, v1.8h
1181 ; CHECK-SD-BASE-NEXT:    saddl v0.4s, v0.4h, v1.4h
1182 ; CHECK-SD-BASE-NEXT:    add v0.4s, v0.4s, v2.4s
1183 ; CHECK-SD-BASE-NEXT:    addv s0, v0.4s
1184 ; CHECK-SD-BASE-NEXT:    fmov w8, s0
1185 ; CHECK-SD-BASE-NEXT:    add w0, w8, w0
1186 ; CHECK-SD-BASE-NEXT:    ret
1188 ; CHECK-SD-DOT-LABEL: add_v16i8_v16i32_acc_sext:
1189 ; CHECK-SD-DOT:       // %bb.0: // %entry
1190 ; CHECK-SD-DOT-NEXT:    movi v1.16b, #1
1191 ; CHECK-SD-DOT-NEXT:    movi v2.2d, #0000000000000000
1192 ; CHECK-SD-DOT-NEXT:    sdot v2.4s, v0.16b, v1.16b
1193 ; CHECK-SD-DOT-NEXT:    addv s0, v2.4s
1194 ; CHECK-SD-DOT-NEXT:    fmov w8, s0
1195 ; CHECK-SD-DOT-NEXT:    add w0, w8, w0
1196 ; CHECK-SD-DOT-NEXT:    ret
1198 ; CHECK-GI-BASE-LABEL: add_v16i8_v16i32_acc_sext:
1199 ; CHECK-GI-BASE:       // %bb.0: // %entry
1200 ; CHECK-GI-BASE-NEXT:    saddlv h0, v0.16b
1201 ; CHECK-GI-BASE-NEXT:    fmov w8, s0
1202 ; CHECK-GI-BASE-NEXT:    add w0, w0, w8, sxth
1203 ; CHECK-GI-BASE-NEXT:    ret
1205 ; CHECK-GI-DOT-LABEL: add_v16i8_v16i32_acc_sext:
1206 ; CHECK-GI-DOT:       // %bb.0: // %entry
1207 ; CHECK-GI-DOT-NEXT:    movi v1.16b, #1
1208 ; CHECK-GI-DOT-NEXT:    movi v2.2d, #0000000000000000
1209 ; CHECK-GI-DOT-NEXT:    sdot v2.4s, v0.16b, v1.16b
1210 ; CHECK-GI-DOT-NEXT:    addv s0, v2.4s
1211 ; CHECK-GI-DOT-NEXT:    fmov w8, s0
1212 ; CHECK-GI-DOT-NEXT:    add w0, w8, w0
1213 ; CHECK-GI-DOT-NEXT:    ret
1214 entry:
1215   %xx = sext <16 x i8> %x to <16 x i32>
1216   %z = call i32 @llvm.vector.reduce.add.v16i32(<16 x i32> %xx)
1217   %r = add i32 %z, %a
1218   ret i32 %r
1221 define i32 @add_v8i8_v8i32_acc_zext(<8 x i8> %x, i32 %a) {
1222 ; CHECK-SD-BASE-LABEL: add_v8i8_v8i32_acc_zext:
1223 ; CHECK-SD-BASE:       // %bb.0: // %entry
1224 ; CHECK-SD-BASE-NEXT:    ushll v0.8h, v0.8b, #0
1225 ; CHECK-SD-BASE-NEXT:    uaddlv s0, v0.8h
1226 ; CHECK-SD-BASE-NEXT:    fmov w8, s0
1227 ; CHECK-SD-BASE-NEXT:    add w0, w8, w0
1228 ; CHECK-SD-BASE-NEXT:    ret
1230 ; CHECK-SD-DOT-LABEL: add_v8i8_v8i32_acc_zext:
1231 ; CHECK-SD-DOT:       // %bb.0: // %entry
1232 ; CHECK-SD-DOT-NEXT:    movi v1.2d, #0000000000000000
1233 ; CHECK-SD-DOT-NEXT:    movi v2.8b, #1
1234 ; CHECK-SD-DOT-NEXT:    udot v1.2s, v0.8b, v2.8b
1235 ; CHECK-SD-DOT-NEXT:    addp v0.2s, v1.2s, v1.2s
1236 ; CHECK-SD-DOT-NEXT:    fmov w8, s0
1237 ; CHECK-SD-DOT-NEXT:    add w0, w8, w0
1238 ; CHECK-SD-DOT-NEXT:    ret
1240 ; CHECK-GI-BASE-LABEL: add_v8i8_v8i32_acc_zext:
1241 ; CHECK-GI-BASE:       // %bb.0: // %entry
1242 ; CHECK-GI-BASE-NEXT:    uaddlv h0, v0.8b
1243 ; CHECK-GI-BASE-NEXT:    fmov w8, s0
1244 ; CHECK-GI-BASE-NEXT:    add w0, w0, w8, uxth
1245 ; CHECK-GI-BASE-NEXT:    ret
1247 ; CHECK-GI-DOT-LABEL: add_v8i8_v8i32_acc_zext:
1248 ; CHECK-GI-DOT:       // %bb.0: // %entry
1249 ; CHECK-GI-DOT-NEXT:    movi v1.8b, #1
1250 ; CHECK-GI-DOT-NEXT:    movi v2.2d, #0000000000000000
1251 ; CHECK-GI-DOT-NEXT:    udot v2.2s, v0.8b, v1.8b
1252 ; CHECK-GI-DOT-NEXT:    addp v0.2s, v2.2s, v2.2s
1253 ; CHECK-GI-DOT-NEXT:    fmov w8, s0
1254 ; CHECK-GI-DOT-NEXT:    add w0, w8, w0
1255 ; CHECK-GI-DOT-NEXT:    ret
1256 entry:
1257   %xx = zext <8 x i8> %x to <8 x i32>
1258   %z = call i32 @llvm.vector.reduce.add.v8i32(<8 x i32> %xx)
1259   %r = add i32 %z, %a
1260   ret i32 %r
1263 define i32 @add_v8i8_v8i32_acc_sext(<8 x i8> %x, i32 %a) {
1264 ; CHECK-SD-BASE-LABEL: add_v8i8_v8i32_acc_sext:
1265 ; CHECK-SD-BASE:       // %bb.0: // %entry
1266 ; CHECK-SD-BASE-NEXT:    sshll v0.8h, v0.8b, #0
1267 ; CHECK-SD-BASE-NEXT:    saddlv s0, v0.8h
1268 ; CHECK-SD-BASE-NEXT:    fmov w8, s0
1269 ; CHECK-SD-BASE-NEXT:    add w0, w8, w0
1270 ; CHECK-SD-BASE-NEXT:    ret
1272 ; CHECK-SD-DOT-LABEL: add_v8i8_v8i32_acc_sext:
1273 ; CHECK-SD-DOT:       // %bb.0: // %entry
1274 ; CHECK-SD-DOT-NEXT:    movi v1.2d, #0000000000000000
1275 ; CHECK-SD-DOT-NEXT:    movi v2.8b, #1
1276 ; CHECK-SD-DOT-NEXT:    sdot v1.2s, v0.8b, v2.8b
1277 ; CHECK-SD-DOT-NEXT:    addp v0.2s, v1.2s, v1.2s
1278 ; CHECK-SD-DOT-NEXT:    fmov w8, s0
1279 ; CHECK-SD-DOT-NEXT:    add w0, w8, w0
1280 ; CHECK-SD-DOT-NEXT:    ret
1282 ; CHECK-GI-BASE-LABEL: add_v8i8_v8i32_acc_sext:
1283 ; CHECK-GI-BASE:       // %bb.0: // %entry
1284 ; CHECK-GI-BASE-NEXT:    saddlv h0, v0.8b
1285 ; CHECK-GI-BASE-NEXT:    fmov w8, s0
1286 ; CHECK-GI-BASE-NEXT:    add w0, w0, w8, sxth
1287 ; CHECK-GI-BASE-NEXT:    ret
1289 ; CHECK-GI-DOT-LABEL: add_v8i8_v8i32_acc_sext:
1290 ; CHECK-GI-DOT:       // %bb.0: // %entry
1291 ; CHECK-GI-DOT-NEXT:    movi v1.8b, #1
1292 ; CHECK-GI-DOT-NEXT:    movi v2.2d, #0000000000000000
1293 ; CHECK-GI-DOT-NEXT:    sdot v2.2s, v0.8b, v1.8b
1294 ; CHECK-GI-DOT-NEXT:    addp v0.2s, v2.2s, v2.2s
1295 ; CHECK-GI-DOT-NEXT:    fmov w8, s0
1296 ; CHECK-GI-DOT-NEXT:    add w0, w8, w0
1297 ; CHECK-GI-DOT-NEXT:    ret
1298 entry:
1299   %xx = sext <8 x i8> %x to <8 x i32>
1300   %z = call i32 @llvm.vector.reduce.add.v8i32(<8 x i32> %xx)
1301   %r = add i32 %z, %a
1302   ret i32 %r
1305 define i32 @add_v4i8_v4i32_acc_zext(<4 x i8> %x, i32 %a) {
1306 ; CHECK-SD-LABEL: add_v4i8_v4i32_acc_zext:
1307 ; CHECK-SD:       // %bb.0: // %entry
1308 ; CHECK-SD-NEXT:    bic v0.4h, #255, lsl #8
1309 ; CHECK-SD-NEXT:    ushll v0.4s, v0.4h, #0
1310 ; CHECK-SD-NEXT:    addv s0, v0.4s
1311 ; CHECK-SD-NEXT:    fmov w8, s0
1312 ; CHECK-SD-NEXT:    add w0, w8, w0
1313 ; CHECK-SD-NEXT:    ret
1315 ; CHECK-GI-LABEL: add_v4i8_v4i32_acc_zext:
1316 ; CHECK-GI:       // %bb.0: // %entry
1317 ; CHECK-GI-NEXT:    movi d1, #0xff00ff00ff00ff
1318 ; CHECK-GI-NEXT:    and v0.8b, v0.8b, v1.8b
1319 ; CHECK-GI-NEXT:    uaddlv s0, v0.4h
1320 ; CHECK-GI-NEXT:    fmov w8, s0
1321 ; CHECK-GI-NEXT:    add w0, w0, w8, uxth
1322 ; CHECK-GI-NEXT:    ret
1323 entry:
1324   %xx = zext <4 x i8> %x to <4 x i32>
1325   %z = call i32 @llvm.vector.reduce.add.v4i32(<4 x i32> %xx)
1326   %r = add i32 %z, %a
1327   ret i32 %r
1330 define i32 @add_v4i8_v4i32_acc_sext(<4 x i8> %x, i32 %a) {
1331 ; CHECK-SD-LABEL: add_v4i8_v4i32_acc_sext:
1332 ; CHECK-SD:       // %bb.0: // %entry
1333 ; CHECK-SD-NEXT:    ushll v0.4s, v0.4h, #0
1334 ; CHECK-SD-NEXT:    shl v0.4s, v0.4s, #24
1335 ; CHECK-SD-NEXT:    sshr v0.4s, v0.4s, #24
1336 ; CHECK-SD-NEXT:    addv s0, v0.4s
1337 ; CHECK-SD-NEXT:    fmov w8, s0
1338 ; CHECK-SD-NEXT:    add w0, w8, w0
1339 ; CHECK-SD-NEXT:    ret
1341 ; CHECK-GI-LABEL: add_v4i8_v4i32_acc_sext:
1342 ; CHECK-GI:       // %bb.0: // %entry
1343 ; CHECK-GI-NEXT:    shl v0.4h, v0.4h, #8
1344 ; CHECK-GI-NEXT:    sshr v0.4h, v0.4h, #8
1345 ; CHECK-GI-NEXT:    saddlv s0, v0.4h
1346 ; CHECK-GI-NEXT:    fmov w8, s0
1347 ; CHECK-GI-NEXT:    add w0, w0, w8, sxth
1348 ; CHECK-GI-NEXT:    ret
1349 entry:
1350   %xx = sext <4 x i8> %x to <4 x i32>
1351   %z = call i32 @llvm.vector.reduce.add.v4i32(<4 x i32> %xx)
1352   %r = add i32 %z, %a
1353   ret i32 %r
1356 define zeroext i16 @add_v16i8_v16i16_acc_zext(<16 x i8> %x, i16 %a) {
1357 ; CHECK-LABEL: add_v16i8_v16i16_acc_zext:
1358 ; CHECK:       // %bb.0: // %entry
1359 ; CHECK-NEXT:    uaddlv h0, v0.16b
1360 ; CHECK-NEXT:    fmov w8, s0
1361 ; CHECK-NEXT:    add w8, w8, w0
1362 ; CHECK-NEXT:    and w0, w8, #0xffff
1363 ; CHECK-NEXT:    ret
1364 entry:
1365   %xx = zext <16 x i8> %x to <16 x i16>
1366   %z = call i16 @llvm.vector.reduce.add.v16i16(<16 x i16> %xx)
1367   %r = add i16 %z, %a
1368   ret i16 %r
1371 define signext i16 @add_v16i8_v16i16_acc_sext(<16 x i8> %x, i16 %a) {
1372 ; CHECK-LABEL: add_v16i8_v16i16_acc_sext:
1373 ; CHECK:       // %bb.0: // %entry
1374 ; CHECK-NEXT:    saddlv h0, v0.16b
1375 ; CHECK-NEXT:    fmov w8, s0
1376 ; CHECK-NEXT:    add w8, w8, w0
1377 ; CHECK-NEXT:    sxth w0, w8
1378 ; CHECK-NEXT:    ret
1379 entry:
1380   %xx = sext <16 x i8> %x to <16 x i16>
1381   %z = call i16 @llvm.vector.reduce.add.v16i16(<16 x i16> %xx)
1382   %r = add i16 %z, %a
1383   ret i16 %r
1386 define zeroext i16 @add_v8i8_v8i16_acc_zext(<8 x i8> %x, i16 %a) {
1387 ; CHECK-SD-LABEL: add_v8i8_v8i16_acc_zext:
1388 ; CHECK-SD:       // %bb.0: // %entry
1389 ; CHECK-SD-NEXT:    ushll v0.8h, v0.8b, #0
1390 ; CHECK-SD-NEXT:    addv h0, v0.8h
1391 ; CHECK-SD-NEXT:    fmov w8, s0
1392 ; CHECK-SD-NEXT:    add w8, w8, w0
1393 ; CHECK-SD-NEXT:    and w0, w8, #0xffff
1394 ; CHECK-SD-NEXT:    ret
1396 ; CHECK-GI-LABEL: add_v8i8_v8i16_acc_zext:
1397 ; CHECK-GI:       // %bb.0: // %entry
1398 ; CHECK-GI-NEXT:    uaddlv h0, v0.8b
1399 ; CHECK-GI-NEXT:    fmov w8, s0
1400 ; CHECK-GI-NEXT:    add w8, w8, w0
1401 ; CHECK-GI-NEXT:    and w0, w8, #0xffff
1402 ; CHECK-GI-NEXT:    ret
1403 entry:
1404   %xx = zext <8 x i8> %x to <8 x i16>
1405   %z = call i16 @llvm.vector.reduce.add.v8i16(<8 x i16> %xx)
1406   %r = add i16 %z, %a
1407   ret i16 %r
1410 define signext i16 @add_v8i8_v8i16_acc_sext(<8 x i8> %x, i16 %a) {
1411 ; CHECK-SD-LABEL: add_v8i8_v8i16_acc_sext:
1412 ; CHECK-SD:       // %bb.0: // %entry
1413 ; CHECK-SD-NEXT:    sshll v0.8h, v0.8b, #0
1414 ; CHECK-SD-NEXT:    addv h0, v0.8h
1415 ; CHECK-SD-NEXT:    fmov w8, s0
1416 ; CHECK-SD-NEXT:    add w8, w8, w0
1417 ; CHECK-SD-NEXT:    sxth w0, w8
1418 ; CHECK-SD-NEXT:    ret
1420 ; CHECK-GI-LABEL: add_v8i8_v8i16_acc_sext:
1421 ; CHECK-GI:       // %bb.0: // %entry
1422 ; CHECK-GI-NEXT:    saddlv h0, v0.8b
1423 ; CHECK-GI-NEXT:    fmov w8, s0
1424 ; CHECK-GI-NEXT:    add w8, w8, w0
1425 ; CHECK-GI-NEXT:    sxth w0, w8
1426 ; CHECK-GI-NEXT:    ret
1427 entry:
1428   %xx = sext <8 x i8> %x to <8 x i16>
1429   %z = call i16 @llvm.vector.reduce.add.v8i16(<8 x i16> %xx)
1430   %r = add i16 %z, %a
1431   ret i16 %r
1434 define zeroext i8 @add_v16i8_v16i8_acc(<16 x i8> %x, i8 %a) {
1435 ; CHECK-SD-LABEL: add_v16i8_v16i8_acc:
1436 ; CHECK-SD:       // %bb.0: // %entry
1437 ; CHECK-SD-NEXT:    addv b0, v0.16b
1438 ; CHECK-SD-NEXT:    fmov w8, s0
1439 ; CHECK-SD-NEXT:    add w8, w8, w0
1440 ; CHECK-SD-NEXT:    and w0, w8, #0xff
1441 ; CHECK-SD-NEXT:    ret
1443 ; CHECK-GI-LABEL: add_v16i8_v16i8_acc:
1444 ; CHECK-GI:       // %bb.0: // %entry
1445 ; CHECK-GI-NEXT:    addv b0, v0.16b
1446 ; CHECK-GI-NEXT:    fmov w8, s0
1447 ; CHECK-GI-NEXT:    add w8, w0, w8, uxtb
1448 ; CHECK-GI-NEXT:    and w0, w8, #0xff
1449 ; CHECK-GI-NEXT:    ret
1450 entry:
1451   %z = call i8 @llvm.vector.reduce.add.v16i8(<16 x i8> %x)
1452   %r = add i8 %z, %a
1453   ret i8 %r
1456 define i64 @add_v16i8_v16i64_acc_zext(<16 x i8> %x, i64 %a) {
1457 ; CHECK-SD-LABEL: add_v16i8_v16i64_acc_zext:
1458 ; CHECK-SD:       // %bb.0: // %entry
1459 ; CHECK-SD-NEXT:    ushll2 v1.8h, v0.16b, #0
1460 ; CHECK-SD-NEXT:    ushll v0.8h, v0.8b, #0
1461 ; CHECK-SD-NEXT:    ushll2 v2.4s, v1.8h, #0
1462 ; CHECK-SD-NEXT:    ushll2 v3.4s, v0.8h, #0
1463 ; CHECK-SD-NEXT:    ushll v1.4s, v1.4h, #0
1464 ; CHECK-SD-NEXT:    ushll v0.4s, v0.4h, #0
1465 ; CHECK-SD-NEXT:    uaddl2 v4.2d, v3.4s, v2.4s
1466 ; CHECK-SD-NEXT:    uaddl v2.2d, v3.2s, v2.2s
1467 ; CHECK-SD-NEXT:    uaddl2 v5.2d, v0.4s, v1.4s
1468 ; CHECK-SD-NEXT:    uaddl v0.2d, v0.2s, v1.2s
1469 ; CHECK-SD-NEXT:    add v1.2d, v5.2d, v4.2d
1470 ; CHECK-SD-NEXT:    add v0.2d, v0.2d, v2.2d
1471 ; CHECK-SD-NEXT:    add v0.2d, v0.2d, v1.2d
1472 ; CHECK-SD-NEXT:    addp d0, v0.2d
1473 ; CHECK-SD-NEXT:    fmov x8, d0
1474 ; CHECK-SD-NEXT:    add x0, x8, x0
1475 ; CHECK-SD-NEXT:    ret
1477 ; CHECK-GI-LABEL: add_v16i8_v16i64_acc_zext:
1478 ; CHECK-GI:       // %bb.0: // %entry
1479 ; CHECK-GI-NEXT:    uaddlv h0, v0.16b
1480 ; CHECK-GI-NEXT:    fmov w8, s0
1481 ; CHECK-GI-NEXT:    add x0, x0, w8, uxth
1482 ; CHECK-GI-NEXT:    ret
1483 entry:
1484   %xx = zext <16 x i8> %x to <16 x i64>
1485   %z = call i64 @llvm.vector.reduce.add.v16i64(<16 x i64> %xx)
1486   %r = add i64 %z, %a
1487   ret i64 %r
1490 define i64 @add_v16i8_v16i64_acc_sext(<16 x i8> %x, i64 %a) {
1491 ; CHECK-SD-LABEL: add_v16i8_v16i64_acc_sext:
1492 ; CHECK-SD:       // %bb.0: // %entry
1493 ; CHECK-SD-NEXT:    sshll2 v1.8h, v0.16b, #0
1494 ; CHECK-SD-NEXT:    sshll v0.8h, v0.8b, #0
1495 ; CHECK-SD-NEXT:    sshll2 v2.4s, v1.8h, #0
1496 ; CHECK-SD-NEXT:    sshll2 v3.4s, v0.8h, #0
1497 ; CHECK-SD-NEXT:    sshll v1.4s, v1.4h, #0
1498 ; CHECK-SD-NEXT:    sshll v0.4s, v0.4h, #0
1499 ; CHECK-SD-NEXT:    saddl2 v4.2d, v3.4s, v2.4s
1500 ; CHECK-SD-NEXT:    saddl v2.2d, v3.2s, v2.2s
1501 ; CHECK-SD-NEXT:    saddl2 v5.2d, v0.4s, v1.4s
1502 ; CHECK-SD-NEXT:    saddl v0.2d, v0.2s, v1.2s
1503 ; CHECK-SD-NEXT:    add v1.2d, v5.2d, v4.2d
1504 ; CHECK-SD-NEXT:    add v0.2d, v0.2d, v2.2d
1505 ; CHECK-SD-NEXT:    add v0.2d, v0.2d, v1.2d
1506 ; CHECK-SD-NEXT:    addp d0, v0.2d
1507 ; CHECK-SD-NEXT:    fmov x8, d0
1508 ; CHECK-SD-NEXT:    add x0, x8, x0
1509 ; CHECK-SD-NEXT:    ret
1511 ; CHECK-GI-LABEL: add_v16i8_v16i64_acc_sext:
1512 ; CHECK-GI:       // %bb.0: // %entry
1513 ; CHECK-GI-NEXT:    saddlv h0, v0.16b
1514 ; CHECK-GI-NEXT:    fmov w8, s0
1515 ; CHECK-GI-NEXT:    add x0, x0, w8, sxth
1516 ; CHECK-GI-NEXT:    ret
1517 entry:
1518   %xx = sext <16 x i8> %x to <16 x i64>
1519   %z = call i64 @llvm.vector.reduce.add.v16i64(<16 x i64> %xx)
1520   %r = add i64 %z, %a
1521   ret i64 %r
1524 define i64 @add_v8i8_v8i64_acc_zext(<8 x i8> %x, i64 %a) {
1525 ; CHECK-SD-LABEL: add_v8i8_v8i64_acc_zext:
1526 ; CHECK-SD:       // %bb.0: // %entry
1527 ; CHECK-SD-NEXT:    ushll v0.8h, v0.8b, #0
1528 ; CHECK-SD-NEXT:    ushll2 v1.4s, v0.8h, #0
1529 ; CHECK-SD-NEXT:    ushll v0.4s, v0.4h, #0
1530 ; CHECK-SD-NEXT:    uaddl2 v2.2d, v0.4s, v1.4s
1531 ; CHECK-SD-NEXT:    uaddl v0.2d, v0.2s, v1.2s
1532 ; CHECK-SD-NEXT:    add v0.2d, v0.2d, v2.2d
1533 ; CHECK-SD-NEXT:    addp d0, v0.2d
1534 ; CHECK-SD-NEXT:    fmov x8, d0
1535 ; CHECK-SD-NEXT:    add x0, x8, x0
1536 ; CHECK-SD-NEXT:    ret
1538 ; CHECK-GI-LABEL: add_v8i8_v8i64_acc_zext:
1539 ; CHECK-GI:       // %bb.0: // %entry
1540 ; CHECK-GI-NEXT:    uaddlv h0, v0.8b
1541 ; CHECK-GI-NEXT:    fmov w8, s0
1542 ; CHECK-GI-NEXT:    add x0, x0, w8, uxth
1543 ; CHECK-GI-NEXT:    ret
1544 entry:
1545   %xx = zext <8 x i8> %x to <8 x i64>
1546   %z = call i64 @llvm.vector.reduce.add.v8i64(<8 x i64> %xx)
1547   %r = add i64 %z, %a
1548   ret i64 %r
1551 define i64 @add_v8i8_v8i64_acc_sext(<8 x i8> %x, i64 %a) {
1552 ; CHECK-SD-LABEL: add_v8i8_v8i64_acc_sext:
1553 ; CHECK-SD:       // %bb.0: // %entry
1554 ; CHECK-SD-NEXT:    sshll v0.8h, v0.8b, #0
1555 ; CHECK-SD-NEXT:    sshll2 v1.4s, v0.8h, #0
1556 ; CHECK-SD-NEXT:    sshll v0.4s, v0.4h, #0
1557 ; CHECK-SD-NEXT:    saddl2 v2.2d, v0.4s, v1.4s
1558 ; CHECK-SD-NEXT:    saddl v0.2d, v0.2s, v1.2s
1559 ; CHECK-SD-NEXT:    add v0.2d, v0.2d, v2.2d
1560 ; CHECK-SD-NEXT:    addp d0, v0.2d
1561 ; CHECK-SD-NEXT:    fmov x8, d0
1562 ; CHECK-SD-NEXT:    add x0, x8, x0
1563 ; CHECK-SD-NEXT:    ret
1565 ; CHECK-GI-LABEL: add_v8i8_v8i64_acc_sext:
1566 ; CHECK-GI:       // %bb.0: // %entry
1567 ; CHECK-GI-NEXT:    saddlv h0, v0.8b
1568 ; CHECK-GI-NEXT:    fmov w8, s0
1569 ; CHECK-GI-NEXT:    add x0, x0, w8, sxth
1570 ; CHECK-GI-NEXT:    ret
1571 entry:
1572   %xx = sext <8 x i8> %x to <8 x i64>
1573   %z = call i64 @llvm.vector.reduce.add.v8i64(<8 x i64> %xx)
1574   %r = add i64 %z, %a
1575   ret i64 %r
1578 define i64 @add_v4i8_v4i64_acc_zext(<4 x i8> %x, i64 %a) {
1579 ; CHECK-SD-LABEL: add_v4i8_v4i64_acc_zext:
1580 ; CHECK-SD:       // %bb.0: // %entry
1581 ; CHECK-SD-NEXT:    bic v0.4h, #255, lsl #8
1582 ; CHECK-SD-NEXT:    ushll v0.4s, v0.4h, #0
1583 ; CHECK-SD-NEXT:    uaddlv d0, v0.4s
1584 ; CHECK-SD-NEXT:    fmov x8, d0
1585 ; CHECK-SD-NEXT:    add x0, x8, x0
1586 ; CHECK-SD-NEXT:    ret
1588 ; CHECK-GI-LABEL: add_v4i8_v4i64_acc_zext:
1589 ; CHECK-GI:       // %bb.0: // %entry
1590 ; CHECK-GI-NEXT:    movi d1, #0xff00ff00ff00ff
1591 ; CHECK-GI-NEXT:    and v0.8b, v0.8b, v1.8b
1592 ; CHECK-GI-NEXT:    uaddlv s0, v0.4h
1593 ; CHECK-GI-NEXT:    fmov w8, s0
1594 ; CHECK-GI-NEXT:    add x0, x0, w8, uxth
1595 ; CHECK-GI-NEXT:    ret
1596 entry:
1597   %xx = zext <4 x i8> %x to <4 x i64>
1598   %z = call i64 @llvm.vector.reduce.add.v4i64(<4 x i64> %xx)
1599   %r = add i64 %z, %a
1600   ret i64 %r
1603 define i64 @add_v4i8_v4i64_acc_sext(<4 x i8> %x, i64 %a) {
1604 ; CHECK-SD-LABEL: add_v4i8_v4i64_acc_sext:
1605 ; CHECK-SD:       // %bb.0: // %entry
1606 ; CHECK-SD-NEXT:    ushll v0.4s, v0.4h, #0
1607 ; CHECK-SD-NEXT:    ushll v1.2d, v0.2s, #0
1608 ; CHECK-SD-NEXT:    ushll2 v0.2d, v0.4s, #0
1609 ; CHECK-SD-NEXT:    shl v1.2d, v1.2d, #56
1610 ; CHECK-SD-NEXT:    shl v0.2d, v0.2d, #56
1611 ; CHECK-SD-NEXT:    sshr v1.2d, v1.2d, #56
1612 ; CHECK-SD-NEXT:    ssra v1.2d, v0.2d, #56
1613 ; CHECK-SD-NEXT:    addp d0, v1.2d
1614 ; CHECK-SD-NEXT:    fmov x8, d0
1615 ; CHECK-SD-NEXT:    add x0, x8, x0
1616 ; CHECK-SD-NEXT:    ret
1618 ; CHECK-GI-LABEL: add_v4i8_v4i64_acc_sext:
1619 ; CHECK-GI:       // %bb.0: // %entry
1620 ; CHECK-GI-NEXT:    shl v0.4h, v0.4h, #8
1621 ; CHECK-GI-NEXT:    sshr v0.4h, v0.4h, #8
1622 ; CHECK-GI-NEXT:    saddlv s0, v0.4h
1623 ; CHECK-GI-NEXT:    fmov w8, s0
1624 ; CHECK-GI-NEXT:    add x0, x0, w8, sxth
1625 ; CHECK-GI-NEXT:    ret
1626 entry:
1627   %xx = sext <4 x i8> %x to <4 x i64>
1628   %z = call i64 @llvm.vector.reduce.add.v4i64(<4 x i64> %xx)
1629   %r = add i64 %z, %a
1630   ret i64 %r
1633 define i64 @add_v2i8_v2i64_acc_zext(<2 x i8> %x, i64 %a) {
1634 ; CHECK-SD-LABEL: add_v2i8_v2i64_acc_zext:
1635 ; CHECK-SD:       // %bb.0: // %entry
1636 ; CHECK-SD-NEXT:    movi d1, #0x0000ff000000ff
1637 ; CHECK-SD-NEXT:    and v0.8b, v0.8b, v1.8b
1638 ; CHECK-SD-NEXT:    ushll v0.2d, v0.2s, #0
1639 ; CHECK-SD-NEXT:    addp d0, v0.2d
1640 ; CHECK-SD-NEXT:    fmov x8, d0
1641 ; CHECK-SD-NEXT:    add x0, x8, x0
1642 ; CHECK-SD-NEXT:    ret
1644 ; CHECK-GI-LABEL: add_v2i8_v2i64_acc_zext:
1645 ; CHECK-GI:       // %bb.0: // %entry
1646 ; CHECK-GI-NEXT:    movi v1.2d, #0x000000000000ff
1647 ; CHECK-GI-NEXT:    ushll v0.2d, v0.2s, #0
1648 ; CHECK-GI-NEXT:    and v0.16b, v0.16b, v1.16b
1649 ; CHECK-GI-NEXT:    addp d0, v0.2d
1650 ; CHECK-GI-NEXT:    fmov x8, d0
1651 ; CHECK-GI-NEXT:    add x0, x8, x0
1652 ; CHECK-GI-NEXT:    ret
1653 entry:
1654   %xx = zext <2 x i8> %x to <2 x i64>
1655   %z = call i64 @llvm.vector.reduce.add.v2i64(<2 x i64> %xx)
1656   %r = add i64 %z, %a
1657   ret i64 %r
1660 define i64 @add_v2i8_v2i64_acc_sext(<2 x i8> %x, i64 %a) {
1661 ; CHECK-LABEL: add_v2i8_v2i64_acc_sext:
1662 ; CHECK:       // %bb.0: // %entry
1663 ; CHECK-NEXT:    ushll v0.2d, v0.2s, #0
1664 ; CHECK-NEXT:    shl v0.2d, v0.2d, #56
1665 ; CHECK-NEXT:    sshr v0.2d, v0.2d, #56
1666 ; CHECK-NEXT:    addp d0, v0.2d
1667 ; CHECK-NEXT:    fmov x8, d0
1668 ; CHECK-NEXT:    add x0, x8, x0
1669 ; CHECK-NEXT:    ret
1670 entry:
1671   %xx = sext <2 x i8> %x to <2 x i64>
1672   %z = call i64 @llvm.vector.reduce.add.v2i64(<2 x i64> %xx)
1673   %r = add i64 %z, %a
1674   ret i64 %r
1677 define i64 @add_v2i64_v2i64_acc(<2 x i64> %x, i64 %a) {
1678 ; CHECK-LABEL: add_v2i64_v2i64_acc:
1679 ; CHECK:       // %bb.0: // %entry
1680 ; CHECK-NEXT:    addp d0, v0.2d
1681 ; CHECK-NEXT:    fmov x8, d0
1682 ; CHECK-NEXT:    add x0, x8, x0
1683 ; CHECK-NEXT:    ret
1684 entry:
1685   %z = call i64 @llvm.vector.reduce.add.v2i64(<2 x i64> %x)
1686   %r = add i64 %z, %a
1687   ret i64 %r
1690 define i32 @add_pair_v4i32_v4i32(<4 x i32> %x, <4 x i32> %y) {
1691 ; CHECK-SD-LABEL: add_pair_v4i32_v4i32:
1692 ; CHECK-SD:       // %bb.0: // %entry
1693 ; CHECK-SD-NEXT:    add v0.4s, v0.4s, v1.4s
1694 ; CHECK-SD-NEXT:    addv s0, v0.4s
1695 ; CHECK-SD-NEXT:    fmov w0, s0
1696 ; CHECK-SD-NEXT:    ret
1698 ; CHECK-GI-LABEL: add_pair_v4i32_v4i32:
1699 ; CHECK-GI:       // %bb.0: // %entry
1700 ; CHECK-GI-NEXT:    addv s0, v0.4s
1701 ; CHECK-GI-NEXT:    addv s1, v1.4s
1702 ; CHECK-GI-NEXT:    fmov w8, s0
1703 ; CHECK-GI-NEXT:    fmov w9, s1
1704 ; CHECK-GI-NEXT:    add w0, w8, w9
1705 ; CHECK-GI-NEXT:    ret
1706 entry:
1707   %z1 = call i32 @llvm.vector.reduce.add.v4i32(<4 x i32> %x)
1708   %z2 = call i32 @llvm.vector.reduce.add.v4i32(<4 x i32> %y)
1709   %z = add i32 %z1, %z2
1710   ret i32 %z
1713 define i64 @add_pair_v4i32_v4i64_zext(<4 x i32> %x, <4 x i32> %y) {
1714 ; CHECK-SD-LABEL: add_pair_v4i32_v4i64_zext:
1715 ; CHECK-SD:       // %bb.0: // %entry
1716 ; CHECK-SD-NEXT:    uaddlp v1.2d, v1.4s
1717 ; CHECK-SD-NEXT:    uadalp v1.2d, v0.4s
1718 ; CHECK-SD-NEXT:    addp d0, v1.2d
1719 ; CHECK-SD-NEXT:    fmov x0, d0
1720 ; CHECK-SD-NEXT:    ret
1722 ; CHECK-GI-LABEL: add_pair_v4i32_v4i64_zext:
1723 ; CHECK-GI:       // %bb.0: // %entry
1724 ; CHECK-GI-NEXT:    uaddlv d0, v0.4s
1725 ; CHECK-GI-NEXT:    uaddlv d1, v1.4s
1726 ; CHECK-GI-NEXT:    fmov x8, d0
1727 ; CHECK-GI-NEXT:    fmov x9, d1
1728 ; CHECK-GI-NEXT:    add x0, x8, x9
1729 ; CHECK-GI-NEXT:    ret
1730 entry:
1731   %xx = zext <4 x i32> %x to <4 x i64>
1732   %z1 = call i64 @llvm.vector.reduce.add.v4i64(<4 x i64> %xx)
1733   %yy = zext <4 x i32> %y to <4 x i64>
1734   %z2 = call i64 @llvm.vector.reduce.add.v4i64(<4 x i64> %yy)
1735   %z = add i64 %z1, %z2
1736   ret i64 %z
1739 define i64 @add_pair_v4i32_v4i64_sext(<4 x i32> %x, <4 x i32> %y) {
1740 ; CHECK-SD-LABEL: add_pair_v4i32_v4i64_sext:
1741 ; CHECK-SD:       // %bb.0: // %entry
1742 ; CHECK-SD-NEXT:    saddlp v1.2d, v1.4s
1743 ; CHECK-SD-NEXT:    sadalp v1.2d, v0.4s
1744 ; CHECK-SD-NEXT:    addp d0, v1.2d
1745 ; CHECK-SD-NEXT:    fmov x0, d0
1746 ; CHECK-SD-NEXT:    ret
1748 ; CHECK-GI-LABEL: add_pair_v4i32_v4i64_sext:
1749 ; CHECK-GI:       // %bb.0: // %entry
1750 ; CHECK-GI-NEXT:    saddlv d0, v0.4s
1751 ; CHECK-GI-NEXT:    saddlv d1, v1.4s
1752 ; CHECK-GI-NEXT:    fmov x8, d0
1753 ; CHECK-GI-NEXT:    fmov x9, d1
1754 ; CHECK-GI-NEXT:    add x0, x8, x9
1755 ; CHECK-GI-NEXT:    ret
1756 entry:
1757   %xx = sext <4 x i32> %x to <4 x i64>
1758   %z1 = call i64 @llvm.vector.reduce.add.v4i64(<4 x i64> %xx)
1759   %yy = sext <4 x i32> %y to <4 x i64>
1760   %z2 = call i64 @llvm.vector.reduce.add.v4i64(<4 x i64> %yy)
1761   %z = add i64 %z1, %z2
1762   ret i64 %z
1765 define i64 @add_pair_v2i32_v2i64_zext(<2 x i32> %x, <2 x i32> %y) {
1766 ; CHECK-SD-LABEL: add_pair_v2i32_v2i64_zext:
1767 ; CHECK-SD:       // %bb.0: // %entry
1768 ; CHECK-SD-NEXT:    // kill: def $d0 killed $d0 def $q0
1769 ; CHECK-SD-NEXT:    // kill: def $d1 killed $d1 def $q1
1770 ; CHECK-SD-NEXT:    mov v0.d[1], v1.d[0]
1771 ; CHECK-SD-NEXT:    uaddlv d0, v0.4s
1772 ; CHECK-SD-NEXT:    fmov x0, d0
1773 ; CHECK-SD-NEXT:    ret
1775 ; CHECK-GI-LABEL: add_pair_v2i32_v2i64_zext:
1776 ; CHECK-GI:       // %bb.0: // %entry
1777 ; CHECK-GI-NEXT:    ushll v0.2d, v0.2s, #0
1778 ; CHECK-GI-NEXT:    ushll v1.2d, v1.2s, #0
1779 ; CHECK-GI-NEXT:    addp d0, v0.2d
1780 ; CHECK-GI-NEXT:    addp d1, v1.2d
1781 ; CHECK-GI-NEXT:    fmov x8, d0
1782 ; CHECK-GI-NEXT:    fmov x9, d1
1783 ; CHECK-GI-NEXT:    add x0, x8, x9
1784 ; CHECK-GI-NEXT:    ret
1785 entry:
1786   %xx = zext <2 x i32> %x to <2 x i64>
1787   %z1 = call i64 @llvm.vector.reduce.add.v2i64(<2 x i64> %xx)
1788   %yy = zext <2 x i32> %y to <2 x i64>
1789   %z2 = call i64 @llvm.vector.reduce.add.v2i64(<2 x i64> %yy)
1790   %z = add i64 %z1, %z2
1791   ret i64 %z
1794 define i64 @add_pair_v2i32_v2i64_sext(<2 x i32> %x, <2 x i32> %y) {
1795 ; CHECK-SD-LABEL: add_pair_v2i32_v2i64_sext:
1796 ; CHECK-SD:       // %bb.0: // %entry
1797 ; CHECK-SD-NEXT:    saddl v0.2d, v0.2s, v1.2s
1798 ; CHECK-SD-NEXT:    addp d0, v0.2d
1799 ; CHECK-SD-NEXT:    fmov x0, d0
1800 ; CHECK-SD-NEXT:    ret
1802 ; CHECK-GI-LABEL: add_pair_v2i32_v2i64_sext:
1803 ; CHECK-GI:       // %bb.0: // %entry
1804 ; CHECK-GI-NEXT:    sshll v0.2d, v0.2s, #0
1805 ; CHECK-GI-NEXT:    sshll v1.2d, v1.2s, #0
1806 ; CHECK-GI-NEXT:    addp d0, v0.2d
1807 ; CHECK-GI-NEXT:    addp d1, v1.2d
1808 ; CHECK-GI-NEXT:    fmov x8, d0
1809 ; CHECK-GI-NEXT:    fmov x9, d1
1810 ; CHECK-GI-NEXT:    add x0, x8, x9
1811 ; CHECK-GI-NEXT:    ret
1812 entry:
1813   %xx = sext <2 x i32> %x to <2 x i64>
1814   %z1 = call i64 @llvm.vector.reduce.add.v2i64(<2 x i64> %xx)
1815   %yy = sext <2 x i32> %y to <2 x i64>
1816   %z2 = call i64 @llvm.vector.reduce.add.v2i64(<2 x i64> %yy)
1817   %z = add i64 %z1, %z2
1818   ret i64 %z
1821 define i32 @add_pair_v8i16_v8i32_zext(<8 x i16> %x, <8 x i16> %y) {
1822 ; CHECK-SD-LABEL: add_pair_v8i16_v8i32_zext:
1823 ; CHECK-SD:       // %bb.0: // %entry
1824 ; CHECK-SD-NEXT:    uaddlp v1.4s, v1.8h
1825 ; CHECK-SD-NEXT:    uadalp v1.4s, v0.8h
1826 ; CHECK-SD-NEXT:    addv s0, v1.4s
1827 ; CHECK-SD-NEXT:    fmov w0, s0
1828 ; CHECK-SD-NEXT:    ret
1830 ; CHECK-GI-LABEL: add_pair_v8i16_v8i32_zext:
1831 ; CHECK-GI:       // %bb.0: // %entry
1832 ; CHECK-GI-NEXT:    uaddlv s0, v0.8h
1833 ; CHECK-GI-NEXT:    uaddlv s1, v1.8h
1834 ; CHECK-GI-NEXT:    fmov w8, s0
1835 ; CHECK-GI-NEXT:    fmov w9, s1
1836 ; CHECK-GI-NEXT:    add w0, w8, w9
1837 ; CHECK-GI-NEXT:    ret
1838 entry:
1839   %xx = zext <8 x i16> %x to <8 x i32>
1840   %z1 = call i32 @llvm.vector.reduce.add.v8i32(<8 x i32> %xx)
1841   %yy = zext <8 x i16> %y to <8 x i32>
1842   %z2 = call i32 @llvm.vector.reduce.add.v8i32(<8 x i32> %yy)
1843   %z = add i32 %z1, %z2
1844   ret i32 %z
1847 define i32 @add_pair_v8i16_v8i32_sext(<8 x i16> %x, <8 x i16> %y) {
1848 ; CHECK-SD-LABEL: add_pair_v8i16_v8i32_sext:
1849 ; CHECK-SD:       // %bb.0: // %entry
1850 ; CHECK-SD-NEXT:    saddlp v1.4s, v1.8h
1851 ; CHECK-SD-NEXT:    sadalp v1.4s, v0.8h
1852 ; CHECK-SD-NEXT:    addv s0, v1.4s
1853 ; CHECK-SD-NEXT:    fmov w0, s0
1854 ; CHECK-SD-NEXT:    ret
1856 ; CHECK-GI-LABEL: add_pair_v8i16_v8i32_sext:
1857 ; CHECK-GI:       // %bb.0: // %entry
1858 ; CHECK-GI-NEXT:    saddlv s0, v0.8h
1859 ; CHECK-GI-NEXT:    saddlv s1, v1.8h
1860 ; CHECK-GI-NEXT:    fmov w8, s0
1861 ; CHECK-GI-NEXT:    fmov w9, s1
1862 ; CHECK-GI-NEXT:    add w0, w8, w9
1863 ; CHECK-GI-NEXT:    ret
1864 entry:
1865   %xx = sext <8 x i16> %x to <8 x i32>
1866   %z1 = call i32 @llvm.vector.reduce.add.v8i32(<8 x i32> %xx)
1867   %yy = sext <8 x i16> %y to <8 x i32>
1868   %z2 = call i32 @llvm.vector.reduce.add.v8i32(<8 x i32> %yy)
1869   %z = add i32 %z1, %z2
1870   ret i32 %z
1873 define i32 @add_pair_v4i16_v4i32_zext(<4 x i16> %x, <4 x i16> %y) {
1874 ; CHECK-SD-LABEL: add_pair_v4i16_v4i32_zext:
1875 ; CHECK-SD:       // %bb.0: // %entry
1876 ; CHECK-SD-NEXT:    // kill: def $d0 killed $d0 def $q0
1877 ; CHECK-SD-NEXT:    // kill: def $d1 killed $d1 def $q1
1878 ; CHECK-SD-NEXT:    mov v0.d[1], v1.d[0]
1879 ; CHECK-SD-NEXT:    uaddlv s0, v0.8h
1880 ; CHECK-SD-NEXT:    fmov w0, s0
1881 ; CHECK-SD-NEXT:    ret
1883 ; CHECK-GI-LABEL: add_pair_v4i16_v4i32_zext:
1884 ; CHECK-GI:       // %bb.0: // %entry
1885 ; CHECK-GI-NEXT:    uaddlv s0, v0.4h
1886 ; CHECK-GI-NEXT:    uaddlv s1, v1.4h
1887 ; CHECK-GI-NEXT:    fmov w8, s0
1888 ; CHECK-GI-NEXT:    fmov w9, s1
1889 ; CHECK-GI-NEXT:    add w0, w8, w9
1890 ; CHECK-GI-NEXT:    ret
1891 entry:
1892   %xx = zext <4 x i16> %x to <4 x i32>
1893   %z1 = call i32 @llvm.vector.reduce.add.v4i32(<4 x i32> %xx)
1894   %yy = zext <4 x i16> %y to <4 x i32>
1895   %z2 = call i32 @llvm.vector.reduce.add.v4i32(<4 x i32> %yy)
1896   %z = add i32 %z1, %z2
1897   ret i32 %z
1900 define i32 @add_pair_v4i16_v4i32_sext(<4 x i16> %x, <4 x i16> %y) {
1901 ; CHECK-SD-LABEL: add_pair_v4i16_v4i32_sext:
1902 ; CHECK-SD:       // %bb.0: // %entry
1903 ; CHECK-SD-NEXT:    saddl v0.4s, v0.4h, v1.4h
1904 ; CHECK-SD-NEXT:    addv s0, v0.4s
1905 ; CHECK-SD-NEXT:    fmov w0, s0
1906 ; CHECK-SD-NEXT:    ret
1908 ; CHECK-GI-LABEL: add_pair_v4i16_v4i32_sext:
1909 ; CHECK-GI:       // %bb.0: // %entry
1910 ; CHECK-GI-NEXT:    saddlv s0, v0.4h
1911 ; CHECK-GI-NEXT:    saddlv s1, v1.4h
1912 ; CHECK-GI-NEXT:    fmov w8, s0
1913 ; CHECK-GI-NEXT:    fmov w9, s1
1914 ; CHECK-GI-NEXT:    add w0, w8, w9
1915 ; CHECK-GI-NEXT:    ret
1916 entry:
1917   %xx = sext <4 x i16> %x to <4 x i32>
1918   %z1 = call i32 @llvm.vector.reduce.add.v4i32(<4 x i32> %xx)
1919   %yy = sext <4 x i16> %y to <4 x i32>
1920   %z2 = call i32 @llvm.vector.reduce.add.v4i32(<4 x i32> %yy)
1921   %z = add i32 %z1, %z2
1922   ret i32 %z
1925 define i32 @test_udot_v8i8(<8 x i8> %a, <8 x i8> %b) {
1926 ; CHECK-SD-BASE-LABEL: test_udot_v8i8:
1927 ; CHECK-SD-BASE:       // %bb.0: // %entry
1928 ; CHECK-SD-BASE-NEXT:    umull v0.8h, v1.8b, v0.8b
1929 ; CHECK-SD-BASE-NEXT:    uaddlv s0, v0.8h
1930 ; CHECK-SD-BASE-NEXT:    fmov w0, s0
1931 ; CHECK-SD-BASE-NEXT:    ret
1933 ; CHECK-SD-DOT-LABEL: test_udot_v8i8:
1934 ; CHECK-SD-DOT:       // %bb.0: // %entry
1935 ; CHECK-SD-DOT-NEXT:    movi v2.2d, #0000000000000000
1936 ; CHECK-SD-DOT-NEXT:    udot v2.2s, v1.8b, v0.8b
1937 ; CHECK-SD-DOT-NEXT:    addp v0.2s, v2.2s, v2.2s
1938 ; CHECK-SD-DOT-NEXT:    fmov w0, s0
1939 ; CHECK-SD-DOT-NEXT:    ret
1941 ; CHECK-GI-BASE-LABEL: test_udot_v8i8:
1942 ; CHECK-GI-BASE:       // %bb.0: // %entry
1943 ; CHECK-GI-BASE-NEXT:    ushll v0.8h, v0.8b, #0
1944 ; CHECK-GI-BASE-NEXT:    ushll v1.8h, v1.8b, #0
1945 ; CHECK-GI-BASE-NEXT:    umull v2.4s, v1.4h, v0.4h
1946 ; CHECK-GI-BASE-NEXT:    umlal2 v2.4s, v1.8h, v0.8h
1947 ; CHECK-GI-BASE-NEXT:    addv s0, v2.4s
1948 ; CHECK-GI-BASE-NEXT:    fmov w0, s0
1949 ; CHECK-GI-BASE-NEXT:    ret
1951 ; CHECK-GI-DOT-LABEL: test_udot_v8i8:
1952 ; CHECK-GI-DOT:       // %bb.0: // %entry
1953 ; CHECK-GI-DOT-NEXT:    movi v2.2d, #0000000000000000
1954 ; CHECK-GI-DOT-NEXT:    udot v2.2s, v1.8b, v0.8b
1955 ; CHECK-GI-DOT-NEXT:    addp v0.2s, v2.2s, v2.2s
1956 ; CHECK-GI-DOT-NEXT:    fmov w0, s0
1957 ; CHECK-GI-DOT-NEXT:    ret
1958 entry:
1959   %0 = zext <8 x i8> %a to <8 x i32>
1960   %1 = zext <8 x i8> %b to <8 x i32>
1961   %2 = mul nuw nsw <8 x i32> %1, %0
1962   %3 = call i32 @llvm.vector.reduce.add.v8i32(<8 x i32> %2)
1963   ret i32 %3
1966 define i32 @test_udot_v16i8(<16 x i8> %a, <16 x i8> %b) {
1967 ; CHECK-SD-BASE-LABEL: test_udot_v16i8:
1968 ; CHECK-SD-BASE:       // %bb.0: // %entry
1969 ; CHECK-SD-BASE-NEXT:    umull2 v2.8h, v1.16b, v0.16b
1970 ; CHECK-SD-BASE-NEXT:    umull v0.8h, v1.8b, v0.8b
1971 ; CHECK-SD-BASE-NEXT:    uaddl2 v1.4s, v0.8h, v2.8h
1972 ; CHECK-SD-BASE-NEXT:    uaddl v0.4s, v0.4h, v2.4h
1973 ; CHECK-SD-BASE-NEXT:    add v0.4s, v0.4s, v1.4s
1974 ; CHECK-SD-BASE-NEXT:    addv s0, v0.4s
1975 ; CHECK-SD-BASE-NEXT:    fmov w0, s0
1976 ; CHECK-SD-BASE-NEXT:    ret
1978 ; CHECK-SD-DOT-LABEL: test_udot_v16i8:
1979 ; CHECK-SD-DOT:       // %bb.0: // %entry
1980 ; CHECK-SD-DOT-NEXT:    movi v2.2d, #0000000000000000
1981 ; CHECK-SD-DOT-NEXT:    udot v2.4s, v1.16b, v0.16b
1982 ; CHECK-SD-DOT-NEXT:    addv s0, v2.4s
1983 ; CHECK-SD-DOT-NEXT:    fmov w0, s0
1984 ; CHECK-SD-DOT-NEXT:    ret
1986 ; CHECK-GI-BASE-LABEL: test_udot_v16i8:
1987 ; CHECK-GI-BASE:       // %bb.0: // %entry
1988 ; CHECK-GI-BASE-NEXT:    ushll v2.8h, v0.8b, #0
1989 ; CHECK-GI-BASE-NEXT:    ushll2 v0.8h, v0.16b, #0
1990 ; CHECK-GI-BASE-NEXT:    ushll v3.8h, v1.8b, #0
1991 ; CHECK-GI-BASE-NEXT:    ushll2 v1.8h, v1.16b, #0
1992 ; CHECK-GI-BASE-NEXT:    umull v4.4s, v3.4h, v2.4h
1993 ; CHECK-GI-BASE-NEXT:    umull v5.4s, v1.4h, v0.4h
1994 ; CHECK-GI-BASE-NEXT:    umlal2 v4.4s, v3.8h, v2.8h
1995 ; CHECK-GI-BASE-NEXT:    umlal2 v5.4s, v1.8h, v0.8h
1996 ; CHECK-GI-BASE-NEXT:    add v0.4s, v4.4s, v5.4s
1997 ; CHECK-GI-BASE-NEXT:    addv s0, v0.4s
1998 ; CHECK-GI-BASE-NEXT:    fmov w0, s0
1999 ; CHECK-GI-BASE-NEXT:    ret
2001 ; CHECK-GI-DOT-LABEL: test_udot_v16i8:
2002 ; CHECK-GI-DOT:       // %bb.0: // %entry
2003 ; CHECK-GI-DOT-NEXT:    movi v2.2d, #0000000000000000
2004 ; CHECK-GI-DOT-NEXT:    udot v2.4s, v1.16b, v0.16b
2005 ; CHECK-GI-DOT-NEXT:    addv s0, v2.4s
2006 ; CHECK-GI-DOT-NEXT:    fmov w0, s0
2007 ; CHECK-GI-DOT-NEXT:    ret
2008 entry:
2009   %0 = zext <16 x i8> %a to <16 x i32>
2010   %1 = zext <16 x i8> %b to <16 x i32>
2011   %2 = mul nuw nsw <16 x i32> %1, %0
2012   %3 = call i32 @llvm.vector.reduce.add.v16i32(<16 x i32> %2)
2013   ret i32 %3
2016 define i32 @test_udot_v24i8(ptr %p1, ptr %p2) {
2017 ; CHECK-SD-BASE-LABEL: test_udot_v24i8:
2018 ; CHECK-SD-BASE:       // %bb.0: // %entry
2019 ; CHECK-SD-BASE-NEXT:    ldr q0, [x0]
2020 ; CHECK-SD-BASE-NEXT:    ldr q1, [x1]
2021 ; CHECK-SD-BASE-NEXT:    ldr d2, [x0, #16]
2022 ; CHECK-SD-BASE-NEXT:    ldr d3, [x1, #16]
2023 ; CHECK-SD-BASE-NEXT:    umull v2.8h, v3.8b, v2.8b
2024 ; CHECK-SD-BASE-NEXT:    umull v3.8h, v1.8b, v0.8b
2025 ; CHECK-SD-BASE-NEXT:    umull2 v0.8h, v1.16b, v0.16b
2026 ; CHECK-SD-BASE-NEXT:    uaddl2 v1.4s, v3.8h, v2.8h
2027 ; CHECK-SD-BASE-NEXT:    uaddl v2.4s, v3.4h, v2.4h
2028 ; CHECK-SD-BASE-NEXT:    uaddw2 v1.4s, v1.4s, v0.8h
2029 ; CHECK-SD-BASE-NEXT:    uaddw v0.4s, v2.4s, v0.4h
2030 ; CHECK-SD-BASE-NEXT:    add v0.4s, v0.4s, v1.4s
2031 ; CHECK-SD-BASE-NEXT:    addv s0, v0.4s
2032 ; CHECK-SD-BASE-NEXT:    fmov w0, s0
2033 ; CHECK-SD-BASE-NEXT:    ret
2035 ; CHECK-SD-DOT-LABEL: test_udot_v24i8:
2036 ; CHECK-SD-DOT:       // %bb.0: // %entry
2037 ; CHECK-SD-DOT-NEXT:    movi v0.2d, #0000000000000000
2038 ; CHECK-SD-DOT-NEXT:    movi v1.2d, #0000000000000000
2039 ; CHECK-SD-DOT-NEXT:    ldr q2, [x0]
2040 ; CHECK-SD-DOT-NEXT:    ldr q3, [x1]
2041 ; CHECK-SD-DOT-NEXT:    ldr d4, [x0, #16]
2042 ; CHECK-SD-DOT-NEXT:    ldr d5, [x1, #16]
2043 ; CHECK-SD-DOT-NEXT:    udot v1.2s, v5.8b, v4.8b
2044 ; CHECK-SD-DOT-NEXT:    udot v0.4s, v3.16b, v2.16b
2045 ; CHECK-SD-DOT-NEXT:    addp v1.2s, v1.2s, v1.2s
2046 ; CHECK-SD-DOT-NEXT:    addv s0, v0.4s
2047 ; CHECK-SD-DOT-NEXT:    fmov w8, s1
2048 ; CHECK-SD-DOT-NEXT:    fmov w9, s0
2049 ; CHECK-SD-DOT-NEXT:    add w0, w9, w8
2050 ; CHECK-SD-DOT-NEXT:    ret
2052 ; CHECK-GI-BASE-LABEL: test_udot_v24i8:
2053 ; CHECK-GI-BASE:       // %bb.0: // %entry
2054 ; CHECK-GI-BASE-NEXT:    ldr q0, [x0]
2055 ; CHECK-GI-BASE-NEXT:    ldr q1, [x1]
2056 ; CHECK-GI-BASE-NEXT:    ldr d2, [x0, #16]
2057 ; CHECK-GI-BASE-NEXT:    ldr d3, [x1, #16]
2058 ; CHECK-GI-BASE-NEXT:    ushll v4.8h, v0.8b, #0
2059 ; CHECK-GI-BASE-NEXT:    ushll2 v0.8h, v0.16b, #0
2060 ; CHECK-GI-BASE-NEXT:    ushll v5.8h, v1.8b, #0
2061 ; CHECK-GI-BASE-NEXT:    ushll v2.8h, v2.8b, #0
2062 ; CHECK-GI-BASE-NEXT:    ushll2 v1.8h, v1.16b, #0
2063 ; CHECK-GI-BASE-NEXT:    ushll v3.8h, v3.8b, #0
2064 ; CHECK-GI-BASE-NEXT:    umull v6.4s, v5.4h, v4.4h
2065 ; CHECK-GI-BASE-NEXT:    umull2 v4.4s, v5.8h, v4.8h
2066 ; CHECK-GI-BASE-NEXT:    umull2 v5.4s, v1.8h, v0.8h
2067 ; CHECK-GI-BASE-NEXT:    umull v7.4s, v3.4h, v2.4h
2068 ; CHECK-GI-BASE-NEXT:    umull v0.4s, v1.4h, v0.4h
2069 ; CHECK-GI-BASE-NEXT:    umull2 v1.4s, v3.8h, v2.8h
2070 ; CHECK-GI-BASE-NEXT:    addv s2, v6.4s
2071 ; CHECK-GI-BASE-NEXT:    addv s3, v4.4s
2072 ; CHECK-GI-BASE-NEXT:    addv s4, v5.4s
2073 ; CHECK-GI-BASE-NEXT:    addv s5, v7.4s
2074 ; CHECK-GI-BASE-NEXT:    addv s0, v0.4s
2075 ; CHECK-GI-BASE-NEXT:    addv s1, v1.4s
2076 ; CHECK-GI-BASE-NEXT:    fmov w8, s2
2077 ; CHECK-GI-BASE-NEXT:    fmov w9, s3
2078 ; CHECK-GI-BASE-NEXT:    fmov w10, s4
2079 ; CHECK-GI-BASE-NEXT:    fmov w11, s5
2080 ; CHECK-GI-BASE-NEXT:    add w8, w8, w9
2081 ; CHECK-GI-BASE-NEXT:    fmov w9, s0
2082 ; CHECK-GI-BASE-NEXT:    add w10, w10, w11
2083 ; CHECK-GI-BASE-NEXT:    fmov w11, s1
2084 ; CHECK-GI-BASE-NEXT:    add w8, w8, w9
2085 ; CHECK-GI-BASE-NEXT:    add w9, w10, w11
2086 ; CHECK-GI-BASE-NEXT:    add w0, w8, w9
2087 ; CHECK-GI-BASE-NEXT:    ret
2089 ; CHECK-GI-DOT-LABEL: test_udot_v24i8:
2090 ; CHECK-GI-DOT:       // %bb.0: // %entry
2091 ; CHECK-GI-DOT-NEXT:    movi v0.2d, #0000000000000000
2092 ; CHECK-GI-DOT-NEXT:    movi v1.2d, #0000000000000000
2093 ; CHECK-GI-DOT-NEXT:    ldr q2, [x0]
2094 ; CHECK-GI-DOT-NEXT:    ldr d3, [x0, #16]
2095 ; CHECK-GI-DOT-NEXT:    ldr q4, [x1]
2096 ; CHECK-GI-DOT-NEXT:    ldr d5, [x1, #16]
2097 ; CHECK-GI-DOT-NEXT:    udot v1.4s, v4.16b, v2.16b
2098 ; CHECK-GI-DOT-NEXT:    udot v0.4s, v5.16b, v3.16b
2099 ; CHECK-GI-DOT-NEXT:    add v0.4s, v1.4s, v0.4s
2100 ; CHECK-GI-DOT-NEXT:    addv s0, v0.4s
2101 ; CHECK-GI-DOT-NEXT:    fmov w0, s0
2102 ; CHECK-GI-DOT-NEXT:    ret
2103 entry:
2104   %a = load <24 x i8>, ptr %p1
2105   %b = load <24 x i8>, ptr %p2
2106   %0 = zext <24 x i8> %a to <24 x i32>
2107   %1 = zext <24 x i8> %b to <24 x i32>
2108   %2 = mul nuw nsw <24 x i32> %1, %0
2109   %3 = call i32 @llvm.vector.reduce.add.v24i32(<24 x i32> %2)
2110   ret i32 %3
2113 define i32 @test_udot_v48i8(ptr %p1, ptr %p2) {
2114 ; CHECK-SD-BASE-LABEL: test_udot_v48i8:
2115 ; CHECK-SD-BASE:       // %bb.0: // %entry
2116 ; CHECK-SD-BASE-NEXT:    ldp q4, q0, [x0, #16]
2117 ; CHECK-SD-BASE-NEXT:    ldr q2, [x1, #32]
2118 ; CHECK-SD-BASE-NEXT:    ldp q1, q5, [x1]
2119 ; CHECK-SD-BASE-NEXT:    ldr q3, [x0]
2120 ; CHECK-SD-BASE-NEXT:    umull2 v6.8h, v2.16b, v0.16b
2121 ; CHECK-SD-BASE-NEXT:    umull v0.8h, v2.8b, v0.8b
2122 ; CHECK-SD-BASE-NEXT:    umull2 v7.8h, v1.16b, v3.16b
2123 ; CHECK-SD-BASE-NEXT:    umull v1.8h, v1.8b, v3.8b
2124 ; CHECK-SD-BASE-NEXT:    umull2 v2.8h, v5.16b, v4.16b
2125 ; CHECK-SD-BASE-NEXT:    umull v3.8h, v5.8b, v4.8b
2126 ; CHECK-SD-BASE-NEXT:    uaddl2 v4.4s, v7.8h, v6.8h
2127 ; CHECK-SD-BASE-NEXT:    uaddl2 v5.4s, v1.8h, v0.8h
2128 ; CHECK-SD-BASE-NEXT:    uaddl v6.4s, v7.4h, v6.4h
2129 ; CHECK-SD-BASE-NEXT:    uaddl v0.4s, v1.4h, v0.4h
2130 ; CHECK-SD-BASE-NEXT:    uaddw2 v1.4s, v4.4s, v2.8h
2131 ; CHECK-SD-BASE-NEXT:    uaddw2 v4.4s, v5.4s, v3.8h
2132 ; CHECK-SD-BASE-NEXT:    uaddw v2.4s, v6.4s, v2.4h
2133 ; CHECK-SD-BASE-NEXT:    uaddw v0.4s, v0.4s, v3.4h
2134 ; CHECK-SD-BASE-NEXT:    add v1.4s, v4.4s, v1.4s
2135 ; CHECK-SD-BASE-NEXT:    add v0.4s, v0.4s, v2.4s
2136 ; CHECK-SD-BASE-NEXT:    add v0.4s, v0.4s, v1.4s
2137 ; CHECK-SD-BASE-NEXT:    addv s0, v0.4s
2138 ; CHECK-SD-BASE-NEXT:    fmov w0, s0
2139 ; CHECK-SD-BASE-NEXT:    ret
2141 ; CHECK-SD-DOT-LABEL: test_udot_v48i8:
2142 ; CHECK-SD-DOT:       // %bb.0: // %entry
2143 ; CHECK-SD-DOT-NEXT:    movi v0.2d, #0000000000000000
2144 ; CHECK-SD-DOT-NEXT:    ldr q1, [x0, #32]
2145 ; CHECK-SD-DOT-NEXT:    ldr q2, [x1, #32]
2146 ; CHECK-SD-DOT-NEXT:    udot v0.4s, v2.16b, v1.16b
2147 ; CHECK-SD-DOT-NEXT:    ldp q3, q1, [x0]
2148 ; CHECK-SD-DOT-NEXT:    ldp q4, q2, [x1]
2149 ; CHECK-SD-DOT-NEXT:    udot v0.4s, v4.16b, v3.16b
2150 ; CHECK-SD-DOT-NEXT:    udot v0.4s, v2.16b, v1.16b
2151 ; CHECK-SD-DOT-NEXT:    addv s0, v0.4s
2152 ; CHECK-SD-DOT-NEXT:    fmov w0, s0
2153 ; CHECK-SD-DOT-NEXT:    ret
2155 ; CHECK-GI-BASE-LABEL: test_udot_v48i8:
2156 ; CHECK-GI-BASE:       // %bb.0: // %entry
2157 ; CHECK-GI-BASE-NEXT:    ldp q0, q3, [x1]
2158 ; CHECK-GI-BASE-NEXT:    ldr q6, [x0, #32]
2159 ; CHECK-GI-BASE-NEXT:    ldp q1, q2, [x0]
2160 ; CHECK-GI-BASE-NEXT:    ldr q7, [x1, #32]
2161 ; CHECK-GI-BASE-NEXT:    ushll v20.8h, v6.8b, #0
2162 ; CHECK-GI-BASE-NEXT:    ushll2 v6.8h, v6.16b, #0
2163 ; CHECK-GI-BASE-NEXT:    ushll v4.8h, v0.8b, #0
2164 ; CHECK-GI-BASE-NEXT:    ushll2 v0.8h, v0.16b, #0
2165 ; CHECK-GI-BASE-NEXT:    ushll v16.8h, v3.8b, #0
2166 ; CHECK-GI-BASE-NEXT:    ushll v5.8h, v1.8b, #0
2167 ; CHECK-GI-BASE-NEXT:    ushll2 v1.8h, v1.16b, #0
2168 ; CHECK-GI-BASE-NEXT:    ushll v17.8h, v2.8b, #0
2169 ; CHECK-GI-BASE-NEXT:    ushll2 v3.8h, v3.16b, #0
2170 ; CHECK-GI-BASE-NEXT:    ushll2 v2.8h, v2.16b, #0
2171 ; CHECK-GI-BASE-NEXT:    umull v18.4s, v4.4h, v5.4h
2172 ; CHECK-GI-BASE-NEXT:    umull2 v4.4s, v4.8h, v5.8h
2173 ; CHECK-GI-BASE-NEXT:    umull v5.4s, v0.4h, v1.4h
2174 ; CHECK-GI-BASE-NEXT:    umull2 v0.4s, v0.8h, v1.8h
2175 ; CHECK-GI-BASE-NEXT:    umull v19.4s, v16.4h, v17.4h
2176 ; CHECK-GI-BASE-NEXT:    ushll v1.8h, v7.8b, #0
2177 ; CHECK-GI-BASE-NEXT:    umull2 v16.4s, v16.8h, v17.8h
2178 ; CHECK-GI-BASE-NEXT:    umull v17.4s, v3.4h, v2.4h
2179 ; CHECK-GI-BASE-NEXT:    umull2 v2.4s, v3.8h, v2.8h
2180 ; CHECK-GI-BASE-NEXT:    ushll2 v7.8h, v7.16b, #0
2181 ; CHECK-GI-BASE-NEXT:    addv s18, v18.4s
2182 ; CHECK-GI-BASE-NEXT:    addv s4, v4.4s
2183 ; CHECK-GI-BASE-NEXT:    addv s5, v5.4s
2184 ; CHECK-GI-BASE-NEXT:    addv s0, v0.4s
2185 ; CHECK-GI-BASE-NEXT:    addv s19, v19.4s
2186 ; CHECK-GI-BASE-NEXT:    umull v3.4s, v1.4h, v20.4h
2187 ; CHECK-GI-BASE-NEXT:    addv s2, v2.4s
2188 ; CHECK-GI-BASE-NEXT:    umull2 v1.4s, v1.8h, v20.8h
2189 ; CHECK-GI-BASE-NEXT:    umull v20.4s, v7.4h, v6.4h
2190 ; CHECK-GI-BASE-NEXT:    fmov w8, s18
2191 ; CHECK-GI-BASE-NEXT:    fmov w9, s4
2192 ; CHECK-GI-BASE-NEXT:    fmov w10, s5
2193 ; CHECK-GI-BASE-NEXT:    fmov w11, s0
2194 ; CHECK-GI-BASE-NEXT:    fmov w12, s19
2195 ; CHECK-GI-BASE-NEXT:    addv s4, v16.4s
2196 ; CHECK-GI-BASE-NEXT:    addv s5, v17.4s
2197 ; CHECK-GI-BASE-NEXT:    addv s3, v3.4s
2198 ; CHECK-GI-BASE-NEXT:    umull2 v0.4s, v7.8h, v6.8h
2199 ; CHECK-GI-BASE-NEXT:    add w8, w8, w9
2200 ; CHECK-GI-BASE-NEXT:    addv s1, v1.4s
2201 ; CHECK-GI-BASE-NEXT:    add w9, w11, w12
2202 ; CHECK-GI-BASE-NEXT:    add w8, w8, w10
2203 ; CHECK-GI-BASE-NEXT:    fmov w10, s4
2204 ; CHECK-GI-BASE-NEXT:    fmov w11, s5
2205 ; CHECK-GI-BASE-NEXT:    fmov w12, s2
2206 ; CHECK-GI-BASE-NEXT:    addv s4, v20.4s
2207 ; CHECK-GI-BASE-NEXT:    addv s0, v0.4s
2208 ; CHECK-GI-BASE-NEXT:    add w9, w9, w10
2209 ; CHECK-GI-BASE-NEXT:    add w10, w11, w12
2210 ; CHECK-GI-BASE-NEXT:    fmov w11, s3
2211 ; CHECK-GI-BASE-NEXT:    add w8, w8, w9
2212 ; CHECK-GI-BASE-NEXT:    add w9, w10, w11
2213 ; CHECK-GI-BASE-NEXT:    fmov w10, s1
2214 ; CHECK-GI-BASE-NEXT:    fmov w11, s0
2215 ; CHECK-GI-BASE-NEXT:    add w9, w9, w10
2216 ; CHECK-GI-BASE-NEXT:    fmov w10, s4
2217 ; CHECK-GI-BASE-NEXT:    add w8, w8, w9
2218 ; CHECK-GI-BASE-NEXT:    add w9, w10, w11
2219 ; CHECK-GI-BASE-NEXT:    add w0, w8, w9
2220 ; CHECK-GI-BASE-NEXT:    ret
2222 ; CHECK-GI-DOT-LABEL: test_udot_v48i8:
2223 ; CHECK-GI-DOT:       // %bb.0: // %entry
2224 ; CHECK-GI-DOT-NEXT:    movi v0.2d, #0000000000000000
2225 ; CHECK-GI-DOT-NEXT:    movi v1.2d, #0000000000000000
2226 ; CHECK-GI-DOT-NEXT:    ldr q7, [x0, #32]
2227 ; CHECK-GI-DOT-NEXT:    ldp q3, q4, [x0]
2228 ; CHECK-GI-DOT-NEXT:    movi v2.2d, #0000000000000000
2229 ; CHECK-GI-DOT-NEXT:    ldp q5, q6, [x1]
2230 ; CHECK-GI-DOT-NEXT:    ldr q16, [x1, #32]
2231 ; CHECK-GI-DOT-NEXT:    udot v0.4s, v5.16b, v3.16b
2232 ; CHECK-GI-DOT-NEXT:    udot v1.4s, v6.16b, v4.16b
2233 ; CHECK-GI-DOT-NEXT:    udot v2.4s, v16.16b, v7.16b
2234 ; CHECK-GI-DOT-NEXT:    addv s0, v0.4s
2235 ; CHECK-GI-DOT-NEXT:    addv s1, v1.4s
2236 ; CHECK-GI-DOT-NEXT:    addv s2, v2.4s
2237 ; CHECK-GI-DOT-NEXT:    fmov w8, s0
2238 ; CHECK-GI-DOT-NEXT:    fmov w9, s1
2239 ; CHECK-GI-DOT-NEXT:    add w8, w8, w9
2240 ; CHECK-GI-DOT-NEXT:    fmov w9, s2
2241 ; CHECK-GI-DOT-NEXT:    add w0, w8, w9
2242 ; CHECK-GI-DOT-NEXT:    ret
2243 entry:
2244   %a = load <48 x i8>, ptr %p1
2245   %b = load <48 x i8>, ptr %p2
2246   %0 = zext <48 x i8> %a to <48 x i32>
2247   %1 = zext <48 x i8> %b to <48 x i32>
2248   %2 = mul nuw nsw <48 x i32> %1, %0
2249   %3 = call i32 @llvm.vector.reduce.add.v48i32(<48 x i32> %2)
2250   ret i32 %3
2253 define i32 @test_sdot_v8i8(<8 x i8> %a, <8 x i8> %b) {
2254 ; CHECK-SD-BASE-LABEL: test_sdot_v8i8:
2255 ; CHECK-SD-BASE:       // %bb.0: // %entry
2256 ; CHECK-SD-BASE-NEXT:    smull v0.8h, v1.8b, v0.8b
2257 ; CHECK-SD-BASE-NEXT:    saddlv s0, v0.8h
2258 ; CHECK-SD-BASE-NEXT:    fmov w0, s0
2259 ; CHECK-SD-BASE-NEXT:    ret
2261 ; CHECK-SD-DOT-LABEL: test_sdot_v8i8:
2262 ; CHECK-SD-DOT:       // %bb.0: // %entry
2263 ; CHECK-SD-DOT-NEXT:    movi v2.2d, #0000000000000000
2264 ; CHECK-SD-DOT-NEXT:    sdot v2.2s, v1.8b, v0.8b
2265 ; CHECK-SD-DOT-NEXT:    addp v0.2s, v2.2s, v2.2s
2266 ; CHECK-SD-DOT-NEXT:    fmov w0, s0
2267 ; CHECK-SD-DOT-NEXT:    ret
2269 ; CHECK-GI-BASE-LABEL: test_sdot_v8i8:
2270 ; CHECK-GI-BASE:       // %bb.0: // %entry
2271 ; CHECK-GI-BASE-NEXT:    sshll v0.8h, v0.8b, #0
2272 ; CHECK-GI-BASE-NEXT:    sshll v1.8h, v1.8b, #0
2273 ; CHECK-GI-BASE-NEXT:    smull v2.4s, v1.4h, v0.4h
2274 ; CHECK-GI-BASE-NEXT:    smlal2 v2.4s, v1.8h, v0.8h
2275 ; CHECK-GI-BASE-NEXT:    addv s0, v2.4s
2276 ; CHECK-GI-BASE-NEXT:    fmov w0, s0
2277 ; CHECK-GI-BASE-NEXT:    ret
2279 ; CHECK-GI-DOT-LABEL: test_sdot_v8i8:
2280 ; CHECK-GI-DOT:       // %bb.0: // %entry
2281 ; CHECK-GI-DOT-NEXT:    movi v2.2d, #0000000000000000
2282 ; CHECK-GI-DOT-NEXT:    sdot v2.2s, v1.8b, v0.8b
2283 ; CHECK-GI-DOT-NEXT:    addp v0.2s, v2.2s, v2.2s
2284 ; CHECK-GI-DOT-NEXT:    fmov w0, s0
2285 ; CHECK-GI-DOT-NEXT:    ret
2286 entry:
2287   %0 = sext <8 x i8> %a to <8 x i32>
2288   %1 = sext <8 x i8> %b to <8 x i32>
2289   %2 = mul nuw nsw <8 x i32> %1, %0
2290   %3 = call i32 @llvm.vector.reduce.add.v8i32(<8 x i32> %2)
2291   ret i32 %3
2294 define i32 @test_sdot_v16i8(<16 x i8> %a, <16 x i8> %b) {
2295 ; CHECK-SD-BASE-LABEL: test_sdot_v16i8:
2296 ; CHECK-SD-BASE:       // %bb.0: // %entry
2297 ; CHECK-SD-BASE-NEXT:    smull2 v2.8h, v1.16b, v0.16b
2298 ; CHECK-SD-BASE-NEXT:    smull v0.8h, v1.8b, v0.8b
2299 ; CHECK-SD-BASE-NEXT:    saddl2 v1.4s, v0.8h, v2.8h
2300 ; CHECK-SD-BASE-NEXT:    saddl v0.4s, v0.4h, v2.4h
2301 ; CHECK-SD-BASE-NEXT:    add v0.4s, v0.4s, v1.4s
2302 ; CHECK-SD-BASE-NEXT:    addv s0, v0.4s
2303 ; CHECK-SD-BASE-NEXT:    fmov w0, s0
2304 ; CHECK-SD-BASE-NEXT:    ret
2306 ; CHECK-SD-DOT-LABEL: test_sdot_v16i8:
2307 ; CHECK-SD-DOT:       // %bb.0: // %entry
2308 ; CHECK-SD-DOT-NEXT:    movi v2.2d, #0000000000000000
2309 ; CHECK-SD-DOT-NEXT:    sdot v2.4s, v1.16b, v0.16b
2310 ; CHECK-SD-DOT-NEXT:    addv s0, v2.4s
2311 ; CHECK-SD-DOT-NEXT:    fmov w0, s0
2312 ; CHECK-SD-DOT-NEXT:    ret
2314 ; CHECK-GI-BASE-LABEL: test_sdot_v16i8:
2315 ; CHECK-GI-BASE:       // %bb.0: // %entry
2316 ; CHECK-GI-BASE-NEXT:    sshll v2.8h, v0.8b, #0
2317 ; CHECK-GI-BASE-NEXT:    sshll2 v0.8h, v0.16b, #0
2318 ; CHECK-GI-BASE-NEXT:    sshll v3.8h, v1.8b, #0
2319 ; CHECK-GI-BASE-NEXT:    sshll2 v1.8h, v1.16b, #0
2320 ; CHECK-GI-BASE-NEXT:    smull v4.4s, v3.4h, v2.4h
2321 ; CHECK-GI-BASE-NEXT:    smull v5.4s, v1.4h, v0.4h
2322 ; CHECK-GI-BASE-NEXT:    smlal2 v4.4s, v3.8h, v2.8h
2323 ; CHECK-GI-BASE-NEXT:    smlal2 v5.4s, v1.8h, v0.8h
2324 ; CHECK-GI-BASE-NEXT:    add v0.4s, v4.4s, v5.4s
2325 ; CHECK-GI-BASE-NEXT:    addv s0, v0.4s
2326 ; CHECK-GI-BASE-NEXT:    fmov w0, s0
2327 ; CHECK-GI-BASE-NEXT:    ret
2329 ; CHECK-GI-DOT-LABEL: test_sdot_v16i8:
2330 ; CHECK-GI-DOT:       // %bb.0: // %entry
2331 ; CHECK-GI-DOT-NEXT:    movi v2.2d, #0000000000000000
2332 ; CHECK-GI-DOT-NEXT:    sdot v2.4s, v1.16b, v0.16b
2333 ; CHECK-GI-DOT-NEXT:    addv s0, v2.4s
2334 ; CHECK-GI-DOT-NEXT:    fmov w0, s0
2335 ; CHECK-GI-DOT-NEXT:    ret
2336 entry:
2337   %0 = sext <16 x i8> %a to <16 x i32>
2338   %1 = sext <16 x i8> %b to <16 x i32>
2339   %2 = mul nuw nsw <16 x i32> %1, %0
2340   %3 = call i32 @llvm.vector.reduce.add.v16i32(<16 x i32> %2)
2341   ret i32 %3
2344 define i32 @test_sdot_v24i8(ptr %p1, ptr %p2) {
2345 ; CHECK-SD-BASE-LABEL: test_sdot_v24i8:
2346 ; CHECK-SD-BASE:       // %bb.0: // %entry
2347 ; CHECK-SD-BASE-NEXT:    ldr q0, [x0]
2348 ; CHECK-SD-BASE-NEXT:    ldr q1, [x1]
2349 ; CHECK-SD-BASE-NEXT:    ldr d2, [x0, #16]
2350 ; CHECK-SD-BASE-NEXT:    ldr d3, [x1, #16]
2351 ; CHECK-SD-BASE-NEXT:    smull v2.8h, v3.8b, v2.8b
2352 ; CHECK-SD-BASE-NEXT:    smull v3.8h, v1.8b, v0.8b
2353 ; CHECK-SD-BASE-NEXT:    smull2 v0.8h, v1.16b, v0.16b
2354 ; CHECK-SD-BASE-NEXT:    saddl2 v1.4s, v3.8h, v2.8h
2355 ; CHECK-SD-BASE-NEXT:    saddl v2.4s, v3.4h, v2.4h
2356 ; CHECK-SD-BASE-NEXT:    saddw2 v1.4s, v1.4s, v0.8h
2357 ; CHECK-SD-BASE-NEXT:    saddw v0.4s, v2.4s, v0.4h
2358 ; CHECK-SD-BASE-NEXT:    add v0.4s, v0.4s, v1.4s
2359 ; CHECK-SD-BASE-NEXT:    addv s0, v0.4s
2360 ; CHECK-SD-BASE-NEXT:    fmov w0, s0
2361 ; CHECK-SD-BASE-NEXT:    ret
2363 ; CHECK-SD-DOT-LABEL: test_sdot_v24i8:
2364 ; CHECK-SD-DOT:       // %bb.0: // %entry
2365 ; CHECK-SD-DOT-NEXT:    movi v0.2d, #0000000000000000
2366 ; CHECK-SD-DOT-NEXT:    movi v1.2d, #0000000000000000
2367 ; CHECK-SD-DOT-NEXT:    ldr q2, [x0]
2368 ; CHECK-SD-DOT-NEXT:    ldr q3, [x1]
2369 ; CHECK-SD-DOT-NEXT:    ldr d4, [x0, #16]
2370 ; CHECK-SD-DOT-NEXT:    ldr d5, [x1, #16]
2371 ; CHECK-SD-DOT-NEXT:    sdot v1.2s, v5.8b, v4.8b
2372 ; CHECK-SD-DOT-NEXT:    sdot v0.4s, v3.16b, v2.16b
2373 ; CHECK-SD-DOT-NEXT:    addp v1.2s, v1.2s, v1.2s
2374 ; CHECK-SD-DOT-NEXT:    addv s0, v0.4s
2375 ; CHECK-SD-DOT-NEXT:    fmov w8, s1
2376 ; CHECK-SD-DOT-NEXT:    fmov w9, s0
2377 ; CHECK-SD-DOT-NEXT:    add w0, w9, w8
2378 ; CHECK-SD-DOT-NEXT:    ret
2380 ; CHECK-GI-BASE-LABEL: test_sdot_v24i8:
2381 ; CHECK-GI-BASE:       // %bb.0: // %entry
2382 ; CHECK-GI-BASE-NEXT:    ldr q0, [x0]
2383 ; CHECK-GI-BASE-NEXT:    ldr q1, [x1]
2384 ; CHECK-GI-BASE-NEXT:    ldr d2, [x0, #16]
2385 ; CHECK-GI-BASE-NEXT:    ldr d3, [x1, #16]
2386 ; CHECK-GI-BASE-NEXT:    sshll v4.8h, v0.8b, #0
2387 ; CHECK-GI-BASE-NEXT:    sshll2 v0.8h, v0.16b, #0
2388 ; CHECK-GI-BASE-NEXT:    sshll v5.8h, v1.8b, #0
2389 ; CHECK-GI-BASE-NEXT:    sshll v2.8h, v2.8b, #0
2390 ; CHECK-GI-BASE-NEXT:    sshll2 v1.8h, v1.16b, #0
2391 ; CHECK-GI-BASE-NEXT:    sshll v3.8h, v3.8b, #0
2392 ; CHECK-GI-BASE-NEXT:    smull v6.4s, v5.4h, v4.4h
2393 ; CHECK-GI-BASE-NEXT:    smull2 v4.4s, v5.8h, v4.8h
2394 ; CHECK-GI-BASE-NEXT:    smull2 v5.4s, v1.8h, v0.8h
2395 ; CHECK-GI-BASE-NEXT:    smull v7.4s, v3.4h, v2.4h
2396 ; CHECK-GI-BASE-NEXT:    smull v0.4s, v1.4h, v0.4h
2397 ; CHECK-GI-BASE-NEXT:    smull2 v1.4s, v3.8h, v2.8h
2398 ; CHECK-GI-BASE-NEXT:    addv s2, v6.4s
2399 ; CHECK-GI-BASE-NEXT:    addv s3, v4.4s
2400 ; CHECK-GI-BASE-NEXT:    addv s4, v5.4s
2401 ; CHECK-GI-BASE-NEXT:    addv s5, v7.4s
2402 ; CHECK-GI-BASE-NEXT:    addv s0, v0.4s
2403 ; CHECK-GI-BASE-NEXT:    addv s1, v1.4s
2404 ; CHECK-GI-BASE-NEXT:    fmov w8, s2
2405 ; CHECK-GI-BASE-NEXT:    fmov w9, s3
2406 ; CHECK-GI-BASE-NEXT:    fmov w10, s4
2407 ; CHECK-GI-BASE-NEXT:    fmov w11, s5
2408 ; CHECK-GI-BASE-NEXT:    add w8, w8, w9
2409 ; CHECK-GI-BASE-NEXT:    fmov w9, s0
2410 ; CHECK-GI-BASE-NEXT:    add w10, w10, w11
2411 ; CHECK-GI-BASE-NEXT:    fmov w11, s1
2412 ; CHECK-GI-BASE-NEXT:    add w8, w8, w9
2413 ; CHECK-GI-BASE-NEXT:    add w9, w10, w11
2414 ; CHECK-GI-BASE-NEXT:    add w0, w8, w9
2415 ; CHECK-GI-BASE-NEXT:    ret
2417 ; CHECK-GI-DOT-LABEL: test_sdot_v24i8:
2418 ; CHECK-GI-DOT:       // %bb.0: // %entry
2419 ; CHECK-GI-DOT-NEXT:    movi v0.2d, #0000000000000000
2420 ; CHECK-GI-DOT-NEXT:    movi v1.2d, #0000000000000000
2421 ; CHECK-GI-DOT-NEXT:    ldr q2, [x0]
2422 ; CHECK-GI-DOT-NEXT:    ldr d3, [x0, #16]
2423 ; CHECK-GI-DOT-NEXT:    ldr q4, [x1]
2424 ; CHECK-GI-DOT-NEXT:    ldr d5, [x1, #16]
2425 ; CHECK-GI-DOT-NEXT:    sdot v1.4s, v4.16b, v2.16b
2426 ; CHECK-GI-DOT-NEXT:    sdot v0.4s, v5.16b, v3.16b
2427 ; CHECK-GI-DOT-NEXT:    add v0.4s, v1.4s, v0.4s
2428 ; CHECK-GI-DOT-NEXT:    addv s0, v0.4s
2429 ; CHECK-GI-DOT-NEXT:    fmov w0, s0
2430 ; CHECK-GI-DOT-NEXT:    ret
2431 entry:
2432   %a = load <24 x i8>, ptr %p1
2433   %b = load <24 x i8>, ptr %p2
2434   %0 = sext <24 x i8> %a to <24 x i32>
2435   %1 = sext <24 x i8> %b to <24 x i32>
2436   %2 = mul nuw nsw <24 x i32> %1, %0
2437   %3 = call i32 @llvm.vector.reduce.add.v24i32(<24 x i32> %2)
2438   ret i32 %3
2441 define i32 @test_sdot_v48i8(ptr %p1, ptr %p2) {
2442 ; CHECK-SD-BASE-LABEL: test_sdot_v48i8:
2443 ; CHECK-SD-BASE:       // %bb.0: // %entry
2444 ; CHECK-SD-BASE-NEXT:    ldp q4, q0, [x0, #16]
2445 ; CHECK-SD-BASE-NEXT:    ldr q2, [x1, #32]
2446 ; CHECK-SD-BASE-NEXT:    ldp q1, q5, [x1]
2447 ; CHECK-SD-BASE-NEXT:    ldr q3, [x0]
2448 ; CHECK-SD-BASE-NEXT:    smull2 v6.8h, v2.16b, v0.16b
2449 ; CHECK-SD-BASE-NEXT:    smull v0.8h, v2.8b, v0.8b
2450 ; CHECK-SD-BASE-NEXT:    smull2 v7.8h, v1.16b, v3.16b
2451 ; CHECK-SD-BASE-NEXT:    smull v1.8h, v1.8b, v3.8b
2452 ; CHECK-SD-BASE-NEXT:    smull2 v2.8h, v5.16b, v4.16b
2453 ; CHECK-SD-BASE-NEXT:    smull v3.8h, v5.8b, v4.8b
2454 ; CHECK-SD-BASE-NEXT:    saddl2 v4.4s, v7.8h, v6.8h
2455 ; CHECK-SD-BASE-NEXT:    saddl2 v5.4s, v1.8h, v0.8h
2456 ; CHECK-SD-BASE-NEXT:    saddl v6.4s, v7.4h, v6.4h
2457 ; CHECK-SD-BASE-NEXT:    saddl v0.4s, v1.4h, v0.4h
2458 ; CHECK-SD-BASE-NEXT:    saddw2 v1.4s, v4.4s, v2.8h
2459 ; CHECK-SD-BASE-NEXT:    saddw2 v4.4s, v5.4s, v3.8h
2460 ; CHECK-SD-BASE-NEXT:    saddw v2.4s, v6.4s, v2.4h
2461 ; CHECK-SD-BASE-NEXT:    saddw v0.4s, v0.4s, v3.4h
2462 ; CHECK-SD-BASE-NEXT:    add v1.4s, v4.4s, v1.4s
2463 ; CHECK-SD-BASE-NEXT:    add v0.4s, v0.4s, v2.4s
2464 ; CHECK-SD-BASE-NEXT:    add v0.4s, v0.4s, v1.4s
2465 ; CHECK-SD-BASE-NEXT:    addv s0, v0.4s
2466 ; CHECK-SD-BASE-NEXT:    fmov w0, s0
2467 ; CHECK-SD-BASE-NEXT:    ret
2469 ; CHECK-SD-DOT-LABEL: test_sdot_v48i8:
2470 ; CHECK-SD-DOT:       // %bb.0: // %entry
2471 ; CHECK-SD-DOT-NEXT:    movi v0.2d, #0000000000000000
2472 ; CHECK-SD-DOT-NEXT:    ldr q1, [x0, #32]
2473 ; CHECK-SD-DOT-NEXT:    ldr q2, [x1, #32]
2474 ; CHECK-SD-DOT-NEXT:    sdot v0.4s, v2.16b, v1.16b
2475 ; CHECK-SD-DOT-NEXT:    ldp q3, q1, [x0]
2476 ; CHECK-SD-DOT-NEXT:    ldp q4, q2, [x1]
2477 ; CHECK-SD-DOT-NEXT:    sdot v0.4s, v4.16b, v3.16b
2478 ; CHECK-SD-DOT-NEXT:    sdot v0.4s, v2.16b, v1.16b
2479 ; CHECK-SD-DOT-NEXT:    addv s0, v0.4s
2480 ; CHECK-SD-DOT-NEXT:    fmov w0, s0
2481 ; CHECK-SD-DOT-NEXT:    ret
2483 ; CHECK-GI-BASE-LABEL: test_sdot_v48i8:
2484 ; CHECK-GI-BASE:       // %bb.0: // %entry
2485 ; CHECK-GI-BASE-NEXT:    ldp q0, q3, [x1]
2486 ; CHECK-GI-BASE-NEXT:    ldr q6, [x0, #32]
2487 ; CHECK-GI-BASE-NEXT:    ldp q1, q2, [x0]
2488 ; CHECK-GI-BASE-NEXT:    ldr q7, [x1, #32]
2489 ; CHECK-GI-BASE-NEXT:    sshll v20.8h, v6.8b, #0
2490 ; CHECK-GI-BASE-NEXT:    sshll2 v6.8h, v6.16b, #0
2491 ; CHECK-GI-BASE-NEXT:    sshll v4.8h, v0.8b, #0
2492 ; CHECK-GI-BASE-NEXT:    sshll2 v0.8h, v0.16b, #0
2493 ; CHECK-GI-BASE-NEXT:    sshll v16.8h, v3.8b, #0
2494 ; CHECK-GI-BASE-NEXT:    sshll v5.8h, v1.8b, #0
2495 ; CHECK-GI-BASE-NEXT:    sshll2 v1.8h, v1.16b, #0
2496 ; CHECK-GI-BASE-NEXT:    sshll v17.8h, v2.8b, #0
2497 ; CHECK-GI-BASE-NEXT:    sshll2 v3.8h, v3.16b, #0
2498 ; CHECK-GI-BASE-NEXT:    sshll2 v2.8h, v2.16b, #0
2499 ; CHECK-GI-BASE-NEXT:    smull v18.4s, v4.4h, v5.4h
2500 ; CHECK-GI-BASE-NEXT:    smull2 v4.4s, v4.8h, v5.8h
2501 ; CHECK-GI-BASE-NEXT:    smull v5.4s, v0.4h, v1.4h
2502 ; CHECK-GI-BASE-NEXT:    smull2 v0.4s, v0.8h, v1.8h
2503 ; CHECK-GI-BASE-NEXT:    smull v19.4s, v16.4h, v17.4h
2504 ; CHECK-GI-BASE-NEXT:    sshll v1.8h, v7.8b, #0
2505 ; CHECK-GI-BASE-NEXT:    smull2 v16.4s, v16.8h, v17.8h
2506 ; CHECK-GI-BASE-NEXT:    smull v17.4s, v3.4h, v2.4h
2507 ; CHECK-GI-BASE-NEXT:    smull2 v2.4s, v3.8h, v2.8h
2508 ; CHECK-GI-BASE-NEXT:    sshll2 v7.8h, v7.16b, #0
2509 ; CHECK-GI-BASE-NEXT:    addv s18, v18.4s
2510 ; CHECK-GI-BASE-NEXT:    addv s4, v4.4s
2511 ; CHECK-GI-BASE-NEXT:    addv s5, v5.4s
2512 ; CHECK-GI-BASE-NEXT:    addv s0, v0.4s
2513 ; CHECK-GI-BASE-NEXT:    addv s19, v19.4s
2514 ; CHECK-GI-BASE-NEXT:    smull v3.4s, v1.4h, v20.4h
2515 ; CHECK-GI-BASE-NEXT:    addv s2, v2.4s
2516 ; CHECK-GI-BASE-NEXT:    smull2 v1.4s, v1.8h, v20.8h
2517 ; CHECK-GI-BASE-NEXT:    smull v20.4s, v7.4h, v6.4h
2518 ; CHECK-GI-BASE-NEXT:    fmov w8, s18
2519 ; CHECK-GI-BASE-NEXT:    fmov w9, s4
2520 ; CHECK-GI-BASE-NEXT:    fmov w10, s5
2521 ; CHECK-GI-BASE-NEXT:    fmov w11, s0
2522 ; CHECK-GI-BASE-NEXT:    fmov w12, s19
2523 ; CHECK-GI-BASE-NEXT:    addv s4, v16.4s
2524 ; CHECK-GI-BASE-NEXT:    addv s5, v17.4s
2525 ; CHECK-GI-BASE-NEXT:    addv s3, v3.4s
2526 ; CHECK-GI-BASE-NEXT:    smull2 v0.4s, v7.8h, v6.8h
2527 ; CHECK-GI-BASE-NEXT:    add w8, w8, w9
2528 ; CHECK-GI-BASE-NEXT:    addv s1, v1.4s
2529 ; CHECK-GI-BASE-NEXT:    add w9, w11, w12
2530 ; CHECK-GI-BASE-NEXT:    add w8, w8, w10
2531 ; CHECK-GI-BASE-NEXT:    fmov w10, s4
2532 ; CHECK-GI-BASE-NEXT:    fmov w11, s5
2533 ; CHECK-GI-BASE-NEXT:    fmov w12, s2
2534 ; CHECK-GI-BASE-NEXT:    addv s4, v20.4s
2535 ; CHECK-GI-BASE-NEXT:    addv s0, v0.4s
2536 ; CHECK-GI-BASE-NEXT:    add w9, w9, w10
2537 ; CHECK-GI-BASE-NEXT:    add w10, w11, w12
2538 ; CHECK-GI-BASE-NEXT:    fmov w11, s3
2539 ; CHECK-GI-BASE-NEXT:    add w8, w8, w9
2540 ; CHECK-GI-BASE-NEXT:    add w9, w10, w11
2541 ; CHECK-GI-BASE-NEXT:    fmov w10, s1
2542 ; CHECK-GI-BASE-NEXT:    fmov w11, s0
2543 ; CHECK-GI-BASE-NEXT:    add w9, w9, w10
2544 ; CHECK-GI-BASE-NEXT:    fmov w10, s4
2545 ; CHECK-GI-BASE-NEXT:    add w8, w8, w9
2546 ; CHECK-GI-BASE-NEXT:    add w9, w10, w11
2547 ; CHECK-GI-BASE-NEXT:    add w0, w8, w9
2548 ; CHECK-GI-BASE-NEXT:    ret
2550 ; CHECK-GI-DOT-LABEL: test_sdot_v48i8:
2551 ; CHECK-GI-DOT:       // %bb.0: // %entry
2552 ; CHECK-GI-DOT-NEXT:    movi v0.2d, #0000000000000000
2553 ; CHECK-GI-DOT-NEXT:    movi v1.2d, #0000000000000000
2554 ; CHECK-GI-DOT-NEXT:    ldr q7, [x0, #32]
2555 ; CHECK-GI-DOT-NEXT:    ldp q3, q4, [x0]
2556 ; CHECK-GI-DOT-NEXT:    movi v2.2d, #0000000000000000
2557 ; CHECK-GI-DOT-NEXT:    ldp q5, q6, [x1]
2558 ; CHECK-GI-DOT-NEXT:    ldr q16, [x1, #32]
2559 ; CHECK-GI-DOT-NEXT:    sdot v0.4s, v5.16b, v3.16b
2560 ; CHECK-GI-DOT-NEXT:    sdot v1.4s, v6.16b, v4.16b
2561 ; CHECK-GI-DOT-NEXT:    sdot v2.4s, v16.16b, v7.16b
2562 ; CHECK-GI-DOT-NEXT:    addv s0, v0.4s
2563 ; CHECK-GI-DOT-NEXT:    addv s1, v1.4s
2564 ; CHECK-GI-DOT-NEXT:    addv s2, v2.4s
2565 ; CHECK-GI-DOT-NEXT:    fmov w8, s0
2566 ; CHECK-GI-DOT-NEXT:    fmov w9, s1
2567 ; CHECK-GI-DOT-NEXT:    add w8, w8, w9
2568 ; CHECK-GI-DOT-NEXT:    fmov w9, s2
2569 ; CHECK-GI-DOT-NEXT:    add w0, w8, w9
2570 ; CHECK-GI-DOT-NEXT:    ret
2571 entry:
2572   %a = load <48 x i8>, ptr %p1
2573   %b = load <48 x i8>, ptr %p2
2574   %0 = sext <48 x i8> %a to <48 x i32>
2575   %1 = sext <48 x i8> %b to <48 x i32>
2576   %2 = mul nuw nsw <48 x i32> %1, %0
2577   %3 = call i32 @llvm.vector.reduce.add.v48i32(<48 x i32> %2)
2578   ret i32 %3
2581 ; Test to ensure that if G_MUL has more than 1 use, it should not be combined to UDOT
2582 define i32 @test_udot_v8i8_multi_use(<8 x i8> %a, <8 x i8> %b) {
2583 ; CHECK-SD-BASE-LABEL: test_udot_v8i8_multi_use:
2584 ; CHECK-SD-BASE:       // %bb.0: // %entry
2585 ; CHECK-SD-BASE-NEXT:    umull v0.8h, v1.8b, v0.8b
2586 ; CHECK-SD-BASE-NEXT:    uaddlv s1, v0.8h
2587 ; CHECK-SD-BASE-NEXT:    ushll v0.4s, v0.4h, #0
2588 ; CHECK-SD-BASE-NEXT:    fmov w9, s0
2589 ; CHECK-SD-BASE-NEXT:    fmov w8, s1
2590 ; CHECK-SD-BASE-NEXT:    add w0, w8, w9
2591 ; CHECK-SD-BASE-NEXT:    ret
2593 ; CHECK-SD-DOT-LABEL: test_udot_v8i8_multi_use:
2594 ; CHECK-SD-DOT:       // %bb.0: // %entry
2595 ; CHECK-SD-DOT-NEXT:    movi v2.2d, #0000000000000000
2596 ; CHECK-SD-DOT-NEXT:    umull v3.8h, v1.8b, v0.8b
2597 ; CHECK-SD-DOT-NEXT:    udot v2.2s, v1.8b, v0.8b
2598 ; CHECK-SD-DOT-NEXT:    ushll v0.4s, v3.4h, #0
2599 ; CHECK-SD-DOT-NEXT:    fmov w9, s0
2600 ; CHECK-SD-DOT-NEXT:    addp v1.2s, v2.2s, v2.2s
2601 ; CHECK-SD-DOT-NEXT:    fmov w8, s1
2602 ; CHECK-SD-DOT-NEXT:    add w0, w8, w9
2603 ; CHECK-SD-DOT-NEXT:    ret
2605 ; CHECK-GI-LABEL: test_udot_v8i8_multi_use:
2606 ; CHECK-GI:       // %bb.0: // %entry
2607 ; CHECK-GI-NEXT:    ushll v0.8h, v0.8b, #0
2608 ; CHECK-GI-NEXT:    ushll v1.8h, v1.8b, #0
2609 ; CHECK-GI-NEXT:    umull v2.4s, v1.4h, v0.4h
2610 ; CHECK-GI-NEXT:    mov v3.16b, v2.16b
2611 ; CHECK-GI-NEXT:    fmov w8, s2
2612 ; CHECK-GI-NEXT:    umlal2 v3.4s, v1.8h, v0.8h
2613 ; CHECK-GI-NEXT:    addv s0, v3.4s
2614 ; CHECK-GI-NEXT:    fmov w9, s0
2615 ; CHECK-GI-NEXT:    add w0, w9, w8
2616 ; CHECK-GI-NEXT:    ret
2617 entry:
2618   %0 = zext <8 x i8> %a to <8 x i32>
2619   %1 = zext <8 x i8> %b to <8 x i32>
2620   %2 = mul nuw nsw <8 x i32> %1, %0
2621   %3 = call i32 @llvm.vector.reduce.add.v8i32(<8 x i32> %2)
2622   %4 = extractelement <8 x i32> %2, i32 0
2623   %5 = add nuw nsw i32 %3, %4
2624   ret i32 %5
2627 define zeroext i16 @add_pair_v8i16_v8i16(<8 x i16> %x, <8 x i16> %y) {
2628 ; CHECK-SD-LABEL: add_pair_v8i16_v8i16:
2629 ; CHECK-SD:       // %bb.0: // %entry
2630 ; CHECK-SD-NEXT:    add v0.8h, v0.8h, v1.8h
2631 ; CHECK-SD-NEXT:    addv h0, v0.8h
2632 ; CHECK-SD-NEXT:    fmov w0, s0
2633 ; CHECK-SD-NEXT:    ret
2635 ; CHECK-GI-LABEL: add_pair_v8i16_v8i16:
2636 ; CHECK-GI:       // %bb.0: // %entry
2637 ; CHECK-GI-NEXT:    addv h0, v0.8h
2638 ; CHECK-GI-NEXT:    addv h1, v1.8h
2639 ; CHECK-GI-NEXT:    fmov w8, s0
2640 ; CHECK-GI-NEXT:    fmov w9, s1
2641 ; CHECK-GI-NEXT:    add w8, w9, w8, uxth
2642 ; CHECK-GI-NEXT:    and w0, w8, #0xffff
2643 ; CHECK-GI-NEXT:    ret
2644 entry:
2645   %z1 = call i16 @llvm.vector.reduce.add.v8i16(<8 x i16> %x)
2646   %z2 = call i16 @llvm.vector.reduce.add.v8i16(<8 x i16> %y)
2647   %z = add i16 %z1, %z2
2648   ret i16 %z
2651 define i64 @add_pair_v8i16_v8i64_zext(<8 x i16> %x, <8 x i16> %y) {
2652 ; CHECK-SD-LABEL: add_pair_v8i16_v8i64_zext:
2653 ; CHECK-SD:       // %bb.0: // %entry
2654 ; CHECK-SD-NEXT:    ushll2 v2.4s, v0.8h, #0
2655 ; CHECK-SD-NEXT:    ushll v0.4s, v0.4h, #0
2656 ; CHECK-SD-NEXT:    ushll2 v3.4s, v1.8h, #0
2657 ; CHECK-SD-NEXT:    ushll v1.4s, v1.4h, #0
2658 ; CHECK-SD-NEXT:    uaddl2 v4.2d, v0.4s, v2.4s
2659 ; CHECK-SD-NEXT:    uaddl v0.2d, v0.2s, v2.2s
2660 ; CHECK-SD-NEXT:    uaddl2 v2.2d, v1.4s, v3.4s
2661 ; CHECK-SD-NEXT:    uaddl v1.2d, v1.2s, v3.2s
2662 ; CHECK-SD-NEXT:    add v0.2d, v0.2d, v4.2d
2663 ; CHECK-SD-NEXT:    add v1.2d, v1.2d, v2.2d
2664 ; CHECK-SD-NEXT:    add v0.2d, v0.2d, v1.2d
2665 ; CHECK-SD-NEXT:    addp d0, v0.2d
2666 ; CHECK-SD-NEXT:    fmov x0, d0
2667 ; CHECK-SD-NEXT:    ret
2669 ; CHECK-GI-LABEL: add_pair_v8i16_v8i64_zext:
2670 ; CHECK-GI:       // %bb.0: // %entry
2671 ; CHECK-GI-NEXT:    uaddlv s1, v1.8h
2672 ; CHECK-GI-NEXT:    uaddlv s0, v0.8h
2673 ; CHECK-GI-NEXT:    mov w8, v1.s[0]
2674 ; CHECK-GI-NEXT:    fmov w9, s0
2675 ; CHECK-GI-NEXT:    add x0, x8, w9, uxtw
2676 ; CHECK-GI-NEXT:    ret
2677 entry:
2678   %xx = zext <8 x i16> %x to <8 x i64>
2679   %z1 = call i64 @llvm.vector.reduce.add.v8i64(<8 x i64> %xx)
2680   %yy = zext <8 x i16> %y to <8 x i64>
2681   %z2 = call i64 @llvm.vector.reduce.add.v8i64(<8 x i64> %yy)
2682   %z = add i64 %z1, %z2
2683   ret i64 %z
2686 define i64 @add_pair_v8i16_v8i64_sext(<8 x i16> %x, <8 x i16> %y) {
2687 ; CHECK-SD-LABEL: add_pair_v8i16_v8i64_sext:
2688 ; CHECK-SD:       // %bb.0: // %entry
2689 ; CHECK-SD-NEXT:    sshll2 v2.4s, v0.8h, #0
2690 ; CHECK-SD-NEXT:    sshll v0.4s, v0.4h, #0
2691 ; CHECK-SD-NEXT:    sshll2 v3.4s, v1.8h, #0
2692 ; CHECK-SD-NEXT:    sshll v1.4s, v1.4h, #0
2693 ; CHECK-SD-NEXT:    saddl2 v4.2d, v0.4s, v2.4s
2694 ; CHECK-SD-NEXT:    saddl v0.2d, v0.2s, v2.2s
2695 ; CHECK-SD-NEXT:    saddl2 v2.2d, v1.4s, v3.4s
2696 ; CHECK-SD-NEXT:    saddl v1.2d, v1.2s, v3.2s
2697 ; CHECK-SD-NEXT:    add v0.2d, v0.2d, v4.2d
2698 ; CHECK-SD-NEXT:    add v1.2d, v1.2d, v2.2d
2699 ; CHECK-SD-NEXT:    add v0.2d, v0.2d, v1.2d
2700 ; CHECK-SD-NEXT:    addp d0, v0.2d
2701 ; CHECK-SD-NEXT:    fmov x0, d0
2702 ; CHECK-SD-NEXT:    ret
2704 ; CHECK-GI-LABEL: add_pair_v8i16_v8i64_sext:
2705 ; CHECK-GI:       // %bb.0: // %entry
2706 ; CHECK-GI-NEXT:    saddlv s1, v1.8h
2707 ; CHECK-GI-NEXT:    saddlv s0, v0.8h
2708 ; CHECK-GI-NEXT:    smov x8, v1.s[0]
2709 ; CHECK-GI-NEXT:    fmov w9, s0
2710 ; CHECK-GI-NEXT:    add x0, x8, w9, sxtw
2711 ; CHECK-GI-NEXT:    ret
2712 entry:
2713   %xx = sext <8 x i16> %x to <8 x i64>
2714   %z1 = call i64 @llvm.vector.reduce.add.v8i64(<8 x i64> %xx)
2715   %yy = sext <8 x i16> %y to <8 x i64>
2716   %z2 = call i64 @llvm.vector.reduce.add.v8i64(<8 x i64> %yy)
2717   %z = add i64 %z1, %z2
2718   ret i64 %z
2721 define i64 @add_pair_v4i16_v4i64_zext(<4 x i16> %x, <4 x i16> %y) {
2722 ; CHECK-SD-LABEL: add_pair_v4i16_v4i64_zext:
2723 ; CHECK-SD:       // %bb.0: // %entry
2724 ; CHECK-SD-NEXT:    ushll v1.4s, v1.4h, #0
2725 ; CHECK-SD-NEXT:    ushll v0.4s, v0.4h, #0
2726 ; CHECK-SD-NEXT:    uaddlp v1.2d, v1.4s
2727 ; CHECK-SD-NEXT:    uadalp v1.2d, v0.4s
2728 ; CHECK-SD-NEXT:    addp d0, v1.2d
2729 ; CHECK-SD-NEXT:    fmov x0, d0
2730 ; CHECK-SD-NEXT:    ret
2732 ; CHECK-GI-LABEL: add_pair_v4i16_v4i64_zext:
2733 ; CHECK-GI:       // %bb.0: // %entry
2734 ; CHECK-GI-NEXT:    uaddlv s1, v1.4h
2735 ; CHECK-GI-NEXT:    uaddlv s0, v0.4h
2736 ; CHECK-GI-NEXT:    mov w8, v1.s[0]
2737 ; CHECK-GI-NEXT:    fmov w9, s0
2738 ; CHECK-GI-NEXT:    add x0, x8, w9, uxtw
2739 ; CHECK-GI-NEXT:    ret
2740 entry:
2741   %xx = zext <4 x i16> %x to <4 x i64>
2742   %z1 = call i64 @llvm.vector.reduce.add.v4i64(<4 x i64> %xx)
2743   %yy = zext <4 x i16> %y to <4 x i64>
2744   %z2 = call i64 @llvm.vector.reduce.add.v4i64(<4 x i64> %yy)
2745   %z = add i64 %z1, %z2
2746   ret i64 %z
2749 define i64 @add_pair_v4i16_v4i64_sext(<4 x i16> %x, <4 x i16> %y) {
2750 ; CHECK-SD-LABEL: add_pair_v4i16_v4i64_sext:
2751 ; CHECK-SD:       // %bb.0: // %entry
2752 ; CHECK-SD-NEXT:    sshll v1.4s, v1.4h, #0
2753 ; CHECK-SD-NEXT:    sshll v0.4s, v0.4h, #0
2754 ; CHECK-SD-NEXT:    saddlp v1.2d, v1.4s
2755 ; CHECK-SD-NEXT:    sadalp v1.2d, v0.4s
2756 ; CHECK-SD-NEXT:    addp d0, v1.2d
2757 ; CHECK-SD-NEXT:    fmov x0, d0
2758 ; CHECK-SD-NEXT:    ret
2760 ; CHECK-GI-LABEL: add_pair_v4i16_v4i64_sext:
2761 ; CHECK-GI:       // %bb.0: // %entry
2762 ; CHECK-GI-NEXT:    saddlv s1, v1.4h
2763 ; CHECK-GI-NEXT:    saddlv s0, v0.4h
2764 ; CHECK-GI-NEXT:    smov x8, v1.s[0]
2765 ; CHECK-GI-NEXT:    fmov w9, s0
2766 ; CHECK-GI-NEXT:    add x0, x8, w9, sxtw
2767 ; CHECK-GI-NEXT:    ret
2768 entry:
2769   %xx = sext <4 x i16> %x to <4 x i64>
2770   %z1 = call i64 @llvm.vector.reduce.add.v4i64(<4 x i64> %xx)
2771   %yy = sext <4 x i16> %y to <4 x i64>
2772   %z2 = call i64 @llvm.vector.reduce.add.v4i64(<4 x i64> %yy)
2773   %z = add i64 %z1, %z2
2774   ret i64 %z
2777 define i64 @add_pair_v2i16_v2i64_zext(<2 x i16> %x, <2 x i16> %y) {
2778 ; CHECK-SD-LABEL: add_pair_v2i16_v2i64_zext:
2779 ; CHECK-SD:       // %bb.0: // %entry
2780 ; CHECK-SD-NEXT:    // kill: def $d0 killed $d0 def $q0
2781 ; CHECK-SD-NEXT:    // kill: def $d1 killed $d1 def $q1
2782 ; CHECK-SD-NEXT:    movi v2.2d, #0x00ffff0000ffff
2783 ; CHECK-SD-NEXT:    mov v0.d[1], v1.d[0]
2784 ; CHECK-SD-NEXT:    and v0.16b, v0.16b, v2.16b
2785 ; CHECK-SD-NEXT:    uaddlv d0, v0.4s
2786 ; CHECK-SD-NEXT:    fmov x0, d0
2787 ; CHECK-SD-NEXT:    ret
2789 ; CHECK-GI-LABEL: add_pair_v2i16_v2i64_zext:
2790 ; CHECK-GI:       // %bb.0: // %entry
2791 ; CHECK-GI-NEXT:    movi v2.2d, #0x0000000000ffff
2792 ; CHECK-GI-NEXT:    ushll v0.2d, v0.2s, #0
2793 ; CHECK-GI-NEXT:    ushll v1.2d, v1.2s, #0
2794 ; CHECK-GI-NEXT:    and v0.16b, v0.16b, v2.16b
2795 ; CHECK-GI-NEXT:    and v1.16b, v1.16b, v2.16b
2796 ; CHECK-GI-NEXT:    addp d0, v0.2d
2797 ; CHECK-GI-NEXT:    addp d1, v1.2d
2798 ; CHECK-GI-NEXT:    fmov x8, d0
2799 ; CHECK-GI-NEXT:    fmov x9, d1
2800 ; CHECK-GI-NEXT:    add x0, x8, x9
2801 ; CHECK-GI-NEXT:    ret
2802 entry:
2803   %xx = zext <2 x i16> %x to <2 x i64>
2804   %z1 = call i64 @llvm.vector.reduce.add.v2i64(<2 x i64> %xx)
2805   %yy = zext <2 x i16> %y to <2 x i64>
2806   %z2 = call i64 @llvm.vector.reduce.add.v2i64(<2 x i64> %yy)
2807   %z = add i64 %z1, %z2
2808   ret i64 %z
2811 define i64 @add_pair_v2i16_v2i64_sext(<2 x i16> %x, <2 x i16> %y) {
2812 ; CHECK-SD-LABEL: add_pair_v2i16_v2i64_sext:
2813 ; CHECK-SD:       // %bb.0: // %entry
2814 ; CHECK-SD-NEXT:    ushll v0.2d, v0.2s, #0
2815 ; CHECK-SD-NEXT:    ushll v1.2d, v1.2s, #0
2816 ; CHECK-SD-NEXT:    shl v0.2d, v0.2d, #48
2817 ; CHECK-SD-NEXT:    shl v1.2d, v1.2d, #48
2818 ; CHECK-SD-NEXT:    sshr v0.2d, v0.2d, #48
2819 ; CHECK-SD-NEXT:    ssra v0.2d, v1.2d, #48
2820 ; CHECK-SD-NEXT:    addp d0, v0.2d
2821 ; CHECK-SD-NEXT:    fmov x0, d0
2822 ; CHECK-SD-NEXT:    ret
2824 ; CHECK-GI-LABEL: add_pair_v2i16_v2i64_sext:
2825 ; CHECK-GI:       // %bb.0: // %entry
2826 ; CHECK-GI-NEXT:    ushll v0.2d, v0.2s, #0
2827 ; CHECK-GI-NEXT:    ushll v1.2d, v1.2s, #0
2828 ; CHECK-GI-NEXT:    shl v0.2d, v0.2d, #48
2829 ; CHECK-GI-NEXT:    shl v1.2d, v1.2d, #48
2830 ; CHECK-GI-NEXT:    sshr v0.2d, v0.2d, #48
2831 ; CHECK-GI-NEXT:    sshr v1.2d, v1.2d, #48
2832 ; CHECK-GI-NEXT:    addp d0, v0.2d
2833 ; CHECK-GI-NEXT:    addp d1, v1.2d
2834 ; CHECK-GI-NEXT:    fmov x8, d0
2835 ; CHECK-GI-NEXT:    fmov x9, d1
2836 ; CHECK-GI-NEXT:    add x0, x8, x9
2837 ; CHECK-GI-NEXT:    ret
2838 entry:
2839   %xx = sext <2 x i16> %x to <2 x i64>
2840   %z1 = call i64 @llvm.vector.reduce.add.v2i64(<2 x i64> %xx)
2841   %yy = sext <2 x i16> %y to <2 x i64>
2842   %z2 = call i64 @llvm.vector.reduce.add.v2i64(<2 x i64> %yy)
2843   %z = add i64 %z1, %z2
2844   ret i64 %z
2847 define i32 @add_pair_v16i8_v16i32_zext(<16 x i8> %x, <16 x i8> %y) {
2848 ; CHECK-SD-BASE-LABEL: add_pair_v16i8_v16i32_zext:
2849 ; CHECK-SD-BASE:       // %bb.0: // %entry
2850 ; CHECK-SD-BASE-NEXT:    ushll2 v2.8h, v0.16b, #0
2851 ; CHECK-SD-BASE-NEXT:    ushll v0.8h, v0.8b, #0
2852 ; CHECK-SD-BASE-NEXT:    ushll2 v3.8h, v1.16b, #0
2853 ; CHECK-SD-BASE-NEXT:    ushll v1.8h, v1.8b, #0
2854 ; CHECK-SD-BASE-NEXT:    uaddl2 v4.4s, v0.8h, v2.8h
2855 ; CHECK-SD-BASE-NEXT:    uaddl v0.4s, v0.4h, v2.4h
2856 ; CHECK-SD-BASE-NEXT:    uaddl2 v2.4s, v1.8h, v3.8h
2857 ; CHECK-SD-BASE-NEXT:    uaddl v1.4s, v1.4h, v3.4h
2858 ; CHECK-SD-BASE-NEXT:    add v0.4s, v0.4s, v4.4s
2859 ; CHECK-SD-BASE-NEXT:    add v1.4s, v1.4s, v2.4s
2860 ; CHECK-SD-BASE-NEXT:    add v0.4s, v0.4s, v1.4s
2861 ; CHECK-SD-BASE-NEXT:    addv s0, v0.4s
2862 ; CHECK-SD-BASE-NEXT:    fmov w0, s0
2863 ; CHECK-SD-BASE-NEXT:    ret
2865 ; CHECK-SD-DOT-LABEL: add_pair_v16i8_v16i32_zext:
2866 ; CHECK-SD-DOT:       // %bb.0: // %entry
2867 ; CHECK-SD-DOT-NEXT:    movi v2.16b, #1
2868 ; CHECK-SD-DOT-NEXT:    movi v3.2d, #0000000000000000
2869 ; CHECK-SD-DOT-NEXT:    udot v3.4s, v1.16b, v2.16b
2870 ; CHECK-SD-DOT-NEXT:    udot v3.4s, v0.16b, v2.16b
2871 ; CHECK-SD-DOT-NEXT:    addv s0, v3.4s
2872 ; CHECK-SD-DOT-NEXT:    fmov w0, s0
2873 ; CHECK-SD-DOT-NEXT:    ret
2875 ; CHECK-GI-BASE-LABEL: add_pair_v16i8_v16i32_zext:
2876 ; CHECK-GI-BASE:       // %bb.0: // %entry
2877 ; CHECK-GI-BASE-NEXT:    uaddlv h1, v1.16b
2878 ; CHECK-GI-BASE-NEXT:    uaddlv h0, v0.16b
2879 ; CHECK-GI-BASE-NEXT:    fmov w8, s1
2880 ; CHECK-GI-BASE-NEXT:    fmov w9, s0
2881 ; CHECK-GI-BASE-NEXT:    and w8, w8, #0xffff
2882 ; CHECK-GI-BASE-NEXT:    add w0, w8, w9, uxth
2883 ; CHECK-GI-BASE-NEXT:    ret
2885 ; CHECK-GI-DOT-LABEL: add_pair_v16i8_v16i32_zext:
2886 ; CHECK-GI-DOT:       // %bb.0: // %entry
2887 ; CHECK-GI-DOT-NEXT:    movi v2.16b, #1
2888 ; CHECK-GI-DOT-NEXT:    movi v3.2d, #0000000000000000
2889 ; CHECK-GI-DOT-NEXT:    movi v4.2d, #0000000000000000
2890 ; CHECK-GI-DOT-NEXT:    udot v4.4s, v0.16b, v2.16b
2891 ; CHECK-GI-DOT-NEXT:    udot v3.4s, v1.16b, v2.16b
2892 ; CHECK-GI-DOT-NEXT:    addv s0, v4.4s
2893 ; CHECK-GI-DOT-NEXT:    addv s1, v3.4s
2894 ; CHECK-GI-DOT-NEXT:    fmov w8, s0
2895 ; CHECK-GI-DOT-NEXT:    fmov w9, s1
2896 ; CHECK-GI-DOT-NEXT:    add w0, w8, w9
2897 ; CHECK-GI-DOT-NEXT:    ret
2898 entry:
2899   %xx = zext <16 x i8> %x to <16 x i32>
2900   %z1 = call i32 @llvm.vector.reduce.add.v16i32(<16 x i32> %xx)
2901   %yy = zext <16 x i8> %y to <16 x i32>
2902   %z2 = call i32 @llvm.vector.reduce.add.v16i32(<16 x i32> %yy)
2903   %z = add i32 %z1, %z2
2904   ret i32 %z
2907 define i32 @add_pair_v16i8_v16i32_sext(<16 x i8> %x, <16 x i8> %y) {
2908 ; CHECK-SD-BASE-LABEL: add_pair_v16i8_v16i32_sext:
2909 ; CHECK-SD-BASE:       // %bb.0: // %entry
2910 ; CHECK-SD-BASE-NEXT:    sshll2 v2.8h, v0.16b, #0
2911 ; CHECK-SD-BASE-NEXT:    sshll v0.8h, v0.8b, #0
2912 ; CHECK-SD-BASE-NEXT:    sshll2 v3.8h, v1.16b, #0
2913 ; CHECK-SD-BASE-NEXT:    sshll v1.8h, v1.8b, #0
2914 ; CHECK-SD-BASE-NEXT:    saddl2 v4.4s, v0.8h, v2.8h
2915 ; CHECK-SD-BASE-NEXT:    saddl v0.4s, v0.4h, v2.4h
2916 ; CHECK-SD-BASE-NEXT:    saddl2 v2.4s, v1.8h, v3.8h
2917 ; CHECK-SD-BASE-NEXT:    saddl v1.4s, v1.4h, v3.4h
2918 ; CHECK-SD-BASE-NEXT:    add v0.4s, v0.4s, v4.4s
2919 ; CHECK-SD-BASE-NEXT:    add v1.4s, v1.4s, v2.4s
2920 ; CHECK-SD-BASE-NEXT:    add v0.4s, v0.4s, v1.4s
2921 ; CHECK-SD-BASE-NEXT:    addv s0, v0.4s
2922 ; CHECK-SD-BASE-NEXT:    fmov w0, s0
2923 ; CHECK-SD-BASE-NEXT:    ret
2925 ; CHECK-SD-DOT-LABEL: add_pair_v16i8_v16i32_sext:
2926 ; CHECK-SD-DOT:       // %bb.0: // %entry
2927 ; CHECK-SD-DOT-NEXT:    movi v2.16b, #1
2928 ; CHECK-SD-DOT-NEXT:    movi v3.2d, #0000000000000000
2929 ; CHECK-SD-DOT-NEXT:    sdot v3.4s, v1.16b, v2.16b
2930 ; CHECK-SD-DOT-NEXT:    sdot v3.4s, v0.16b, v2.16b
2931 ; CHECK-SD-DOT-NEXT:    addv s0, v3.4s
2932 ; CHECK-SD-DOT-NEXT:    fmov w0, s0
2933 ; CHECK-SD-DOT-NEXT:    ret
2935 ; CHECK-GI-BASE-LABEL: add_pair_v16i8_v16i32_sext:
2936 ; CHECK-GI-BASE:       // %bb.0: // %entry
2937 ; CHECK-GI-BASE-NEXT:    saddlv h1, v1.16b
2938 ; CHECK-GI-BASE-NEXT:    saddlv h0, v0.16b
2939 ; CHECK-GI-BASE-NEXT:    fmov w8, s1
2940 ; CHECK-GI-BASE-NEXT:    fmov w9, s0
2941 ; CHECK-GI-BASE-NEXT:    sxth w8, w8
2942 ; CHECK-GI-BASE-NEXT:    add w0, w8, w9, sxth
2943 ; CHECK-GI-BASE-NEXT:    ret
2945 ; CHECK-GI-DOT-LABEL: add_pair_v16i8_v16i32_sext:
2946 ; CHECK-GI-DOT:       // %bb.0: // %entry
2947 ; CHECK-GI-DOT-NEXT:    movi v2.16b, #1
2948 ; CHECK-GI-DOT-NEXT:    movi v3.2d, #0000000000000000
2949 ; CHECK-GI-DOT-NEXT:    movi v4.2d, #0000000000000000
2950 ; CHECK-GI-DOT-NEXT:    sdot v4.4s, v0.16b, v2.16b
2951 ; CHECK-GI-DOT-NEXT:    sdot v3.4s, v1.16b, v2.16b
2952 ; CHECK-GI-DOT-NEXT:    addv s0, v4.4s
2953 ; CHECK-GI-DOT-NEXT:    addv s1, v3.4s
2954 ; CHECK-GI-DOT-NEXT:    fmov w8, s0
2955 ; CHECK-GI-DOT-NEXT:    fmov w9, s1
2956 ; CHECK-GI-DOT-NEXT:    add w0, w8, w9
2957 ; CHECK-GI-DOT-NEXT:    ret
2958 entry:
2959   %xx = sext <16 x i8> %x to <16 x i32>
2960   %z1 = call i32 @llvm.vector.reduce.add.v16i32(<16 x i32> %xx)
2961   %yy = sext <16 x i8> %y to <16 x i32>
2962   %z2 = call i32 @llvm.vector.reduce.add.v16i32(<16 x i32> %yy)
2963   %z = add i32 %z1, %z2
2964   ret i32 %z
2967 define i32 @add_pair_v8i8_v8i32_zext(<8 x i8> %x, <8 x i8> %y) {
2968 ; CHECK-SD-BASE-LABEL: add_pair_v8i8_v8i32_zext:
2969 ; CHECK-SD-BASE:       // %bb.0: // %entry
2970 ; CHECK-SD-BASE-NEXT:    ushll v1.8h, v1.8b, #0
2971 ; CHECK-SD-BASE-NEXT:    ushll v0.8h, v0.8b, #0
2972 ; CHECK-SD-BASE-NEXT:    uaddlp v1.4s, v1.8h
2973 ; CHECK-SD-BASE-NEXT:    uadalp v1.4s, v0.8h
2974 ; CHECK-SD-BASE-NEXT:    addv s0, v1.4s
2975 ; CHECK-SD-BASE-NEXT:    fmov w0, s0
2976 ; CHECK-SD-BASE-NEXT:    ret
2978 ; CHECK-SD-DOT-LABEL: add_pair_v8i8_v8i32_zext:
2979 ; CHECK-SD-DOT:       // %bb.0: // %entry
2980 ; CHECK-SD-DOT-NEXT:    movi v2.2d, #0000000000000000
2981 ; CHECK-SD-DOT-NEXT:    movi v3.8b, #1
2982 ; CHECK-SD-DOT-NEXT:    udot v2.2s, v1.8b, v3.8b
2983 ; CHECK-SD-DOT-NEXT:    udot v2.2s, v0.8b, v3.8b
2984 ; CHECK-SD-DOT-NEXT:    addp v0.2s, v2.2s, v2.2s
2985 ; CHECK-SD-DOT-NEXT:    fmov w0, s0
2986 ; CHECK-SD-DOT-NEXT:    ret
2988 ; CHECK-GI-BASE-LABEL: add_pair_v8i8_v8i32_zext:
2989 ; CHECK-GI-BASE:       // %bb.0: // %entry
2990 ; CHECK-GI-BASE-NEXT:    uaddlv h1, v1.8b
2991 ; CHECK-GI-BASE-NEXT:    uaddlv h0, v0.8b
2992 ; CHECK-GI-BASE-NEXT:    fmov w8, s1
2993 ; CHECK-GI-BASE-NEXT:    fmov w9, s0
2994 ; CHECK-GI-BASE-NEXT:    and w8, w8, #0xffff
2995 ; CHECK-GI-BASE-NEXT:    add w0, w8, w9, uxth
2996 ; CHECK-GI-BASE-NEXT:    ret
2998 ; CHECK-GI-DOT-LABEL: add_pair_v8i8_v8i32_zext:
2999 ; CHECK-GI-DOT:       // %bb.0: // %entry
3000 ; CHECK-GI-DOT-NEXT:    movi v2.8b, #1
3001 ; CHECK-GI-DOT-NEXT:    movi v3.2d, #0000000000000000
3002 ; CHECK-GI-DOT-NEXT:    movi v4.2d, #0000000000000000
3003 ; CHECK-GI-DOT-NEXT:    udot v4.2s, v0.8b, v2.8b
3004 ; CHECK-GI-DOT-NEXT:    udot v3.2s, v1.8b, v2.8b
3005 ; CHECK-GI-DOT-NEXT:    addp v0.2s, v4.2s, v4.2s
3006 ; CHECK-GI-DOT-NEXT:    addp v1.2s, v3.2s, v3.2s
3007 ; CHECK-GI-DOT-NEXT:    fmov w8, s0
3008 ; CHECK-GI-DOT-NEXT:    fmov w9, s1
3009 ; CHECK-GI-DOT-NEXT:    add w0, w8, w9
3010 ; CHECK-GI-DOT-NEXT:    ret
3011 entry:
3012   %xx = zext <8 x i8> %x to <8 x i32>
3013   %z1 = call i32 @llvm.vector.reduce.add.v8i32(<8 x i32> %xx)
3014   %yy = zext <8 x i8> %y to <8 x i32>
3015   %z2 = call i32 @llvm.vector.reduce.add.v8i32(<8 x i32> %yy)
3016   %z = add i32 %z1, %z2
3017   ret i32 %z
3020 define i32 @add_pair_v8i8_v8i32_sext(<8 x i8> %x, <8 x i8> %y) {
3021 ; CHECK-SD-BASE-LABEL: add_pair_v8i8_v8i32_sext:
3022 ; CHECK-SD-BASE:       // %bb.0: // %entry
3023 ; CHECK-SD-BASE-NEXT:    sshll v1.8h, v1.8b, #0
3024 ; CHECK-SD-BASE-NEXT:    sshll v0.8h, v0.8b, #0
3025 ; CHECK-SD-BASE-NEXT:    saddlp v1.4s, v1.8h
3026 ; CHECK-SD-BASE-NEXT:    sadalp v1.4s, v0.8h
3027 ; CHECK-SD-BASE-NEXT:    addv s0, v1.4s
3028 ; CHECK-SD-BASE-NEXT:    fmov w0, s0
3029 ; CHECK-SD-BASE-NEXT:    ret
3031 ; CHECK-SD-DOT-LABEL: add_pair_v8i8_v8i32_sext:
3032 ; CHECK-SD-DOT:       // %bb.0: // %entry
3033 ; CHECK-SD-DOT-NEXT:    movi v2.2d, #0000000000000000
3034 ; CHECK-SD-DOT-NEXT:    movi v3.8b, #1
3035 ; CHECK-SD-DOT-NEXT:    sdot v2.2s, v1.8b, v3.8b
3036 ; CHECK-SD-DOT-NEXT:    sdot v2.2s, v0.8b, v3.8b
3037 ; CHECK-SD-DOT-NEXT:    addp v0.2s, v2.2s, v2.2s
3038 ; CHECK-SD-DOT-NEXT:    fmov w0, s0
3039 ; CHECK-SD-DOT-NEXT:    ret
3041 ; CHECK-GI-BASE-LABEL: add_pair_v8i8_v8i32_sext:
3042 ; CHECK-GI-BASE:       // %bb.0: // %entry
3043 ; CHECK-GI-BASE-NEXT:    saddlv h1, v1.8b
3044 ; CHECK-GI-BASE-NEXT:    saddlv h0, v0.8b
3045 ; CHECK-GI-BASE-NEXT:    fmov w8, s1
3046 ; CHECK-GI-BASE-NEXT:    fmov w9, s0
3047 ; CHECK-GI-BASE-NEXT:    sxth w8, w8
3048 ; CHECK-GI-BASE-NEXT:    add w0, w8, w9, sxth
3049 ; CHECK-GI-BASE-NEXT:    ret
3051 ; CHECK-GI-DOT-LABEL: add_pair_v8i8_v8i32_sext:
3052 ; CHECK-GI-DOT:       // %bb.0: // %entry
3053 ; CHECK-GI-DOT-NEXT:    movi v2.8b, #1
3054 ; CHECK-GI-DOT-NEXT:    movi v3.2d, #0000000000000000
3055 ; CHECK-GI-DOT-NEXT:    movi v4.2d, #0000000000000000
3056 ; CHECK-GI-DOT-NEXT:    sdot v4.2s, v0.8b, v2.8b
3057 ; CHECK-GI-DOT-NEXT:    sdot v3.2s, v1.8b, v2.8b
3058 ; CHECK-GI-DOT-NEXT:    addp v0.2s, v4.2s, v4.2s
3059 ; CHECK-GI-DOT-NEXT:    addp v1.2s, v3.2s, v3.2s
3060 ; CHECK-GI-DOT-NEXT:    fmov w8, s0
3061 ; CHECK-GI-DOT-NEXT:    fmov w9, s1
3062 ; CHECK-GI-DOT-NEXT:    add w0, w8, w9
3063 ; CHECK-GI-DOT-NEXT:    ret
3064 entry:
3065   %xx = sext <8 x i8> %x to <8 x i32>
3066   %z1 = call i32 @llvm.vector.reduce.add.v8i32(<8 x i32> %xx)
3067   %yy = sext <8 x i8> %y to <8 x i32>
3068   %z2 = call i32 @llvm.vector.reduce.add.v8i32(<8 x i32> %yy)
3069   %z = add i32 %z1, %z2
3070   ret i32 %z
3073 define i32 @add_pair_v4i8_v4i32_zext(<4 x i8> %x, <4 x i8> %y) {
3074 ; CHECK-SD-LABEL: add_pair_v4i8_v4i32_zext:
3075 ; CHECK-SD:       // %bb.0: // %entry
3076 ; CHECK-SD-NEXT:    // kill: def $d1 killed $d1 def $q1
3077 ; CHECK-SD-NEXT:    // kill: def $d0 killed $d0 def $q0
3078 ; CHECK-SD-NEXT:    bic v0.4h, #255, lsl #8
3079 ; CHECK-SD-NEXT:    bic v1.4h, #255, lsl #8
3080 ; CHECK-SD-NEXT:    mov v0.d[1], v1.d[0]
3081 ; CHECK-SD-NEXT:    uaddlv s0, v0.8h
3082 ; CHECK-SD-NEXT:    fmov w0, s0
3083 ; CHECK-SD-NEXT:    ret
3085 ; CHECK-GI-LABEL: add_pair_v4i8_v4i32_zext:
3086 ; CHECK-GI:       // %bb.0: // %entry
3087 ; CHECK-GI-NEXT:    movi d2, #0xff00ff00ff00ff
3088 ; CHECK-GI-NEXT:    and v1.8b, v1.8b, v2.8b
3089 ; CHECK-GI-NEXT:    and v0.8b, v0.8b, v2.8b
3090 ; CHECK-GI-NEXT:    uaddlv s1, v1.4h
3091 ; CHECK-GI-NEXT:    uaddlv s0, v0.4h
3092 ; CHECK-GI-NEXT:    fmov w8, s1
3093 ; CHECK-GI-NEXT:    fmov w9, s0
3094 ; CHECK-GI-NEXT:    and w8, w8, #0xffff
3095 ; CHECK-GI-NEXT:    add w0, w8, w9, uxth
3096 ; CHECK-GI-NEXT:    ret
3097 entry:
3098   %xx = zext <4 x i8> %x to <4 x i32>
3099   %z1 = call i32 @llvm.vector.reduce.add.v4i32(<4 x i32> %xx)
3100   %yy = zext <4 x i8> %y to <4 x i32>
3101   %z2 = call i32 @llvm.vector.reduce.add.v4i32(<4 x i32> %yy)
3102   %z = add i32 %z1, %z2
3103   ret i32 %z
3106 define i32 @add_pair_v4i8_v4i32_sext(<4 x i8> %x, <4 x i8> %y) {
3107 ; CHECK-SD-LABEL: add_pair_v4i8_v4i32_sext:
3108 ; CHECK-SD:       // %bb.0: // %entry
3109 ; CHECK-SD-NEXT:    ushll v0.4s, v0.4h, #0
3110 ; CHECK-SD-NEXT:    ushll v1.4s, v1.4h, #0
3111 ; CHECK-SD-NEXT:    shl v0.4s, v0.4s, #24
3112 ; CHECK-SD-NEXT:    shl v1.4s, v1.4s, #24
3113 ; CHECK-SD-NEXT:    sshr v0.4s, v0.4s, #24
3114 ; CHECK-SD-NEXT:    ssra v0.4s, v1.4s, #24
3115 ; CHECK-SD-NEXT:    addv s0, v0.4s
3116 ; CHECK-SD-NEXT:    fmov w0, s0
3117 ; CHECK-SD-NEXT:    ret
3119 ; CHECK-GI-LABEL: add_pair_v4i8_v4i32_sext:
3120 ; CHECK-GI:       // %bb.0: // %entry
3121 ; CHECK-GI-NEXT:    shl v1.4h, v1.4h, #8
3122 ; CHECK-GI-NEXT:    shl v0.4h, v0.4h, #8
3123 ; CHECK-GI-NEXT:    sshr v1.4h, v1.4h, #8
3124 ; CHECK-GI-NEXT:    sshr v0.4h, v0.4h, #8
3125 ; CHECK-GI-NEXT:    saddlv s1, v1.4h
3126 ; CHECK-GI-NEXT:    saddlv s0, v0.4h
3127 ; CHECK-GI-NEXT:    fmov w8, s1
3128 ; CHECK-GI-NEXT:    fmov w9, s0
3129 ; CHECK-GI-NEXT:    sxth w8, w8
3130 ; CHECK-GI-NEXT:    add w0, w8, w9, sxth
3131 ; CHECK-GI-NEXT:    ret
3132 entry:
3133   %xx = sext <4 x i8> %x to <4 x i32>
3134   %z1 = call i32 @llvm.vector.reduce.add.v4i32(<4 x i32> %xx)
3135   %yy = sext <4 x i8> %y to <4 x i32>
3136   %z2 = call i32 @llvm.vector.reduce.add.v4i32(<4 x i32> %yy)
3137   %z = add i32 %z1, %z2
3138   ret i32 %z
3141 define zeroext i16 @add_pair_v16i8_v16i16_zext(<16 x i8> %x, <16 x i8> %y) {
3142 ; CHECK-SD-LABEL: add_pair_v16i8_v16i16_zext:
3143 ; CHECK-SD:       // %bb.0: // %entry
3144 ; CHECK-SD-NEXT:    uaddlp v1.8h, v1.16b
3145 ; CHECK-SD-NEXT:    uadalp v1.8h, v0.16b
3146 ; CHECK-SD-NEXT:    addv h0, v1.8h
3147 ; CHECK-SD-NEXT:    fmov w0, s0
3148 ; CHECK-SD-NEXT:    ret
3150 ; CHECK-GI-LABEL: add_pair_v16i8_v16i16_zext:
3151 ; CHECK-GI:       // %bb.0: // %entry
3152 ; CHECK-GI-NEXT:    uaddlv h0, v0.16b
3153 ; CHECK-GI-NEXT:    uaddlv h1, v1.16b
3154 ; CHECK-GI-NEXT:    fmov w8, s0
3155 ; CHECK-GI-NEXT:    fmov w9, s1
3156 ; CHECK-GI-NEXT:    add w8, w8, w9
3157 ; CHECK-GI-NEXT:    and w0, w8, #0xffff
3158 ; CHECK-GI-NEXT:    ret
3159 entry:
3160   %xx = zext <16 x i8> %x to <16 x i16>
3161   %z1 = call i16 @llvm.vector.reduce.add.v16i16(<16 x i16> %xx)
3162   %yy = zext <16 x i8> %y to <16 x i16>
3163   %z2 = call i16 @llvm.vector.reduce.add.v16i16(<16 x i16> %yy)
3164   %z = add i16 %z1, %z2
3165   ret i16 %z
3168 define signext i16 @add_pair_v16i8_v16i16_sext(<16 x i8> %x, <16 x i8> %y) {
3169 ; CHECK-SD-LABEL: add_pair_v16i8_v16i16_sext:
3170 ; CHECK-SD:       // %bb.0: // %entry
3171 ; CHECK-SD-NEXT:    saddlp v1.8h, v1.16b
3172 ; CHECK-SD-NEXT:    sadalp v1.8h, v0.16b
3173 ; CHECK-SD-NEXT:    addv h0, v1.8h
3174 ; CHECK-SD-NEXT:    smov w0, v0.h[0]
3175 ; CHECK-SD-NEXT:    ret
3177 ; CHECK-GI-LABEL: add_pair_v16i8_v16i16_sext:
3178 ; CHECK-GI:       // %bb.0: // %entry
3179 ; CHECK-GI-NEXT:    saddlv h0, v0.16b
3180 ; CHECK-GI-NEXT:    saddlv h1, v1.16b
3181 ; CHECK-GI-NEXT:    fmov w8, s0
3182 ; CHECK-GI-NEXT:    fmov w9, s1
3183 ; CHECK-GI-NEXT:    add w8, w8, w9
3184 ; CHECK-GI-NEXT:    sxth w0, w8
3185 ; CHECK-GI-NEXT:    ret
3186 entry:
3187   %xx = sext <16 x i8> %x to <16 x i16>
3188   %z1 = call i16 @llvm.vector.reduce.add.v16i16(<16 x i16> %xx)
3189   %yy = sext <16 x i8> %y to <16 x i16>
3190   %z2 = call i16 @llvm.vector.reduce.add.v16i16(<16 x i16> %yy)
3191   %z = add i16 %z1, %z2
3192   ret i16 %z
3195 define zeroext i16 @add_pair_v8i8_v8i16_zext(<8 x i8> %x, <8 x i8> %y) {
3196 ; CHECK-SD-LABEL: add_pair_v8i8_v8i16_zext:
3197 ; CHECK-SD:       // %bb.0: // %entry
3198 ; CHECK-SD-NEXT:    // kill: def $d0 killed $d0 def $q0
3199 ; CHECK-SD-NEXT:    // kill: def $d1 killed $d1 def $q1
3200 ; CHECK-SD-NEXT:    mov v0.d[1], v1.d[0]
3201 ; CHECK-SD-NEXT:    uaddlv h0, v0.16b
3202 ; CHECK-SD-NEXT:    umov w0, v0.h[0]
3203 ; CHECK-SD-NEXT:    ret
3205 ; CHECK-GI-LABEL: add_pair_v8i8_v8i16_zext:
3206 ; CHECK-GI:       // %bb.0: // %entry
3207 ; CHECK-GI-NEXT:    uaddlv h0, v0.8b
3208 ; CHECK-GI-NEXT:    uaddlv h1, v1.8b
3209 ; CHECK-GI-NEXT:    fmov w8, s0
3210 ; CHECK-GI-NEXT:    fmov w9, s1
3211 ; CHECK-GI-NEXT:    add w8, w8, w9
3212 ; CHECK-GI-NEXT:    and w0, w8, #0xffff
3213 ; CHECK-GI-NEXT:    ret
3214 entry:
3215   %xx = zext <8 x i8> %x to <8 x i16>
3216   %z1 = call i16 @llvm.vector.reduce.add.v8i16(<8 x i16> %xx)
3217   %yy = zext <8 x i8> %y to <8 x i16>
3218   %z2 = call i16 @llvm.vector.reduce.add.v8i16(<8 x i16> %yy)
3219   %z = add i16 %z1, %z2
3220   ret i16 %z
3223 define signext i16 @add_pair_v8i8_v8i16_sext(<8 x i8> %x, <8 x i8> %y) {
3224 ; CHECK-SD-LABEL: add_pair_v8i8_v8i16_sext:
3225 ; CHECK-SD:       // %bb.0: // %entry
3226 ; CHECK-SD-NEXT:    saddl v0.8h, v0.8b, v1.8b
3227 ; CHECK-SD-NEXT:    addv h0, v0.8h
3228 ; CHECK-SD-NEXT:    smov w0, v0.h[0]
3229 ; CHECK-SD-NEXT:    ret
3231 ; CHECK-GI-LABEL: add_pair_v8i8_v8i16_sext:
3232 ; CHECK-GI:       // %bb.0: // %entry
3233 ; CHECK-GI-NEXT:    saddlv h0, v0.8b
3234 ; CHECK-GI-NEXT:    saddlv h1, v1.8b
3235 ; CHECK-GI-NEXT:    fmov w8, s0
3236 ; CHECK-GI-NEXT:    fmov w9, s1
3237 ; CHECK-GI-NEXT:    add w8, w8, w9
3238 ; CHECK-GI-NEXT:    sxth w0, w8
3239 ; CHECK-GI-NEXT:    ret
3240 entry:
3241   %xx = sext <8 x i8> %x to <8 x i16>
3242   %z1 = call i16 @llvm.vector.reduce.add.v8i16(<8 x i16> %xx)
3243   %yy = sext <8 x i8> %y to <8 x i16>
3244   %z2 = call i16 @llvm.vector.reduce.add.v8i16(<8 x i16> %yy)
3245   %z = add i16 %z1, %z2
3246   ret i16 %z
3249 define zeroext i8 @add_pair_v16i8_v16i8(<16 x i8> %x, <16 x i8> %y) {
3250 ; CHECK-SD-LABEL: add_pair_v16i8_v16i8:
3251 ; CHECK-SD:       // %bb.0: // %entry
3252 ; CHECK-SD-NEXT:    add v0.16b, v0.16b, v1.16b
3253 ; CHECK-SD-NEXT:    addv b0, v0.16b
3254 ; CHECK-SD-NEXT:    fmov w0, s0
3255 ; CHECK-SD-NEXT:    ret
3257 ; CHECK-GI-LABEL: add_pair_v16i8_v16i8:
3258 ; CHECK-GI:       // %bb.0: // %entry
3259 ; CHECK-GI-NEXT:    addv b0, v0.16b
3260 ; CHECK-GI-NEXT:    addv b1, v1.16b
3261 ; CHECK-GI-NEXT:    fmov w8, s0
3262 ; CHECK-GI-NEXT:    fmov w9, s1
3263 ; CHECK-GI-NEXT:    add w8, w9, w8, uxtb
3264 ; CHECK-GI-NEXT:    and w0, w8, #0xff
3265 ; CHECK-GI-NEXT:    ret
3266 entry:
3267   %z1 = call i8 @llvm.vector.reduce.add.v16i8(<16 x i8> %x)
3268   %z2 = call i8 @llvm.vector.reduce.add.v16i8(<16 x i8> %y)
3269   %z = add i8 %z1, %z2
3270   ret i8 %z
3273 define i64 @add_pair_v16i8_v16i64_zext(<16 x i8> %x, <16 x i8> %y) {
3274 ; CHECK-SD-LABEL: add_pair_v16i8_v16i64_zext:
3275 ; CHECK-SD:       // %bb.0: // %entry
3276 ; CHECK-SD-NEXT:    ushll2 v2.8h, v0.16b, #0
3277 ; CHECK-SD-NEXT:    ushll v0.8h, v0.8b, #0
3278 ; CHECK-SD-NEXT:    ushll2 v3.8h, v1.16b, #0
3279 ; CHECK-SD-NEXT:    ushll v1.8h, v1.8b, #0
3280 ; CHECK-SD-NEXT:    ushll v4.4s, v2.4h, #0
3281 ; CHECK-SD-NEXT:    ushll2 v2.4s, v2.8h, #0
3282 ; CHECK-SD-NEXT:    ushll2 v5.4s, v0.8h, #0
3283 ; CHECK-SD-NEXT:    ushll v0.4s, v0.4h, #0
3284 ; CHECK-SD-NEXT:    ushll2 v6.4s, v3.8h, #0
3285 ; CHECK-SD-NEXT:    ushll2 v7.4s, v1.8h, #0
3286 ; CHECK-SD-NEXT:    ushll v3.4s, v3.4h, #0
3287 ; CHECK-SD-NEXT:    ushll v1.4s, v1.4h, #0
3288 ; CHECK-SD-NEXT:    uaddl2 v16.2d, v5.4s, v2.4s
3289 ; CHECK-SD-NEXT:    uaddl v2.2d, v5.2s, v2.2s
3290 ; CHECK-SD-NEXT:    uaddl2 v5.2d, v0.4s, v4.4s
3291 ; CHECK-SD-NEXT:    uaddl v0.2d, v0.2s, v4.2s
3292 ; CHECK-SD-NEXT:    uaddl2 v4.2d, v7.4s, v6.4s
3293 ; CHECK-SD-NEXT:    uaddl v6.2d, v7.2s, v6.2s
3294 ; CHECK-SD-NEXT:    uaddl2 v7.2d, v1.4s, v3.4s
3295 ; CHECK-SD-NEXT:    uaddl v1.2d, v1.2s, v3.2s
3296 ; CHECK-SD-NEXT:    add v3.2d, v5.2d, v16.2d
3297 ; CHECK-SD-NEXT:    add v0.2d, v0.2d, v2.2d
3298 ; CHECK-SD-NEXT:    add v2.2d, v7.2d, v4.2d
3299 ; CHECK-SD-NEXT:    add v1.2d, v1.2d, v6.2d
3300 ; CHECK-SD-NEXT:    add v0.2d, v0.2d, v3.2d
3301 ; CHECK-SD-NEXT:    add v1.2d, v1.2d, v2.2d
3302 ; CHECK-SD-NEXT:    add v0.2d, v0.2d, v1.2d
3303 ; CHECK-SD-NEXT:    addp d0, v0.2d
3304 ; CHECK-SD-NEXT:    fmov x0, d0
3305 ; CHECK-SD-NEXT:    ret
3307 ; CHECK-GI-LABEL: add_pair_v16i8_v16i64_zext:
3308 ; CHECK-GI:       // %bb.0: // %entry
3309 ; CHECK-GI-NEXT:    uaddlv h1, v1.16b
3310 ; CHECK-GI-NEXT:    uaddlv h0, v0.16b
3311 ; CHECK-GI-NEXT:    fmov w8, s1
3312 ; CHECK-GI-NEXT:    fmov w9, s0
3313 ; CHECK-GI-NEXT:    and x8, x8, #0xffff
3314 ; CHECK-GI-NEXT:    add x0, x8, w9, uxth
3315 ; CHECK-GI-NEXT:    ret
3316 entry:
3317   %xx = zext <16 x i8> %x to <16 x i64>
3318   %z1 = call i64 @llvm.vector.reduce.add.v16i64(<16 x i64> %xx)
3319   %yy = zext <16 x i8> %y to <16 x i64>
3320   %z2 = call i64 @llvm.vector.reduce.add.v16i64(<16 x i64> %yy)
3321   %z = add i64 %z1, %z2
3322   ret i64 %z
3325 define i64 @add_pair_v16i8_v16i64_sext(<16 x i8> %x, <16 x i8> %y) {
3326 ; CHECK-SD-LABEL: add_pair_v16i8_v16i64_sext:
3327 ; CHECK-SD:       // %bb.0: // %entry
3328 ; CHECK-SD-NEXT:    sshll2 v2.8h, v0.16b, #0
3329 ; CHECK-SD-NEXT:    sshll v0.8h, v0.8b, #0
3330 ; CHECK-SD-NEXT:    sshll2 v3.8h, v1.16b, #0
3331 ; CHECK-SD-NEXT:    sshll v1.8h, v1.8b, #0
3332 ; CHECK-SD-NEXT:    sshll v4.4s, v2.4h, #0
3333 ; CHECK-SD-NEXT:    sshll2 v2.4s, v2.8h, #0
3334 ; CHECK-SD-NEXT:    sshll2 v5.4s, v0.8h, #0
3335 ; CHECK-SD-NEXT:    sshll v0.4s, v0.4h, #0
3336 ; CHECK-SD-NEXT:    sshll2 v6.4s, v3.8h, #0
3337 ; CHECK-SD-NEXT:    sshll2 v7.4s, v1.8h, #0
3338 ; CHECK-SD-NEXT:    sshll v3.4s, v3.4h, #0
3339 ; CHECK-SD-NEXT:    sshll v1.4s, v1.4h, #0
3340 ; CHECK-SD-NEXT:    saddl2 v16.2d, v5.4s, v2.4s
3341 ; CHECK-SD-NEXT:    saddl v2.2d, v5.2s, v2.2s
3342 ; CHECK-SD-NEXT:    saddl2 v5.2d, v0.4s, v4.4s
3343 ; CHECK-SD-NEXT:    saddl v0.2d, v0.2s, v4.2s
3344 ; CHECK-SD-NEXT:    saddl2 v4.2d, v7.4s, v6.4s
3345 ; CHECK-SD-NEXT:    saddl v6.2d, v7.2s, v6.2s
3346 ; CHECK-SD-NEXT:    saddl2 v7.2d, v1.4s, v3.4s
3347 ; CHECK-SD-NEXT:    saddl v1.2d, v1.2s, v3.2s
3348 ; CHECK-SD-NEXT:    add v3.2d, v5.2d, v16.2d
3349 ; CHECK-SD-NEXT:    add v0.2d, v0.2d, v2.2d
3350 ; CHECK-SD-NEXT:    add v2.2d, v7.2d, v4.2d
3351 ; CHECK-SD-NEXT:    add v1.2d, v1.2d, v6.2d
3352 ; CHECK-SD-NEXT:    add v0.2d, v0.2d, v3.2d
3353 ; CHECK-SD-NEXT:    add v1.2d, v1.2d, v2.2d
3354 ; CHECK-SD-NEXT:    add v0.2d, v0.2d, v1.2d
3355 ; CHECK-SD-NEXT:    addp d0, v0.2d
3356 ; CHECK-SD-NEXT:    fmov x0, d0
3357 ; CHECK-SD-NEXT:    ret
3359 ; CHECK-GI-LABEL: add_pair_v16i8_v16i64_sext:
3360 ; CHECK-GI:       // %bb.0: // %entry
3361 ; CHECK-GI-NEXT:    saddlv h1, v1.16b
3362 ; CHECK-GI-NEXT:    saddlv h0, v0.16b
3363 ; CHECK-GI-NEXT:    fmov w8, s1
3364 ; CHECK-GI-NEXT:    fmov w9, s0
3365 ; CHECK-GI-NEXT:    sxth x8, w8
3366 ; CHECK-GI-NEXT:    add x0, x8, w9, sxth
3367 ; CHECK-GI-NEXT:    ret
3368 entry:
3369   %xx = sext <16 x i8> %x to <16 x i64>
3370   %z1 = call i64 @llvm.vector.reduce.add.v16i64(<16 x i64> %xx)
3371   %yy = sext <16 x i8> %y to <16 x i64>
3372   %z2 = call i64 @llvm.vector.reduce.add.v16i64(<16 x i64> %yy)
3373   %z = add i64 %z1, %z2
3374   ret i64 %z
3377 define i64 @add_pair_v8i8_v8i64_zext(<8 x i8> %x, <8 x i8> %y) {
3378 ; CHECK-SD-LABEL: add_pair_v8i8_v8i64_zext:
3379 ; CHECK-SD:       // %bb.0: // %entry
3380 ; CHECK-SD-NEXT:    ushll v0.8h, v0.8b, #0
3381 ; CHECK-SD-NEXT:    ushll v1.8h, v1.8b, #0
3382 ; CHECK-SD-NEXT:    ushll2 v2.4s, v0.8h, #0
3383 ; CHECK-SD-NEXT:    ushll v0.4s, v0.4h, #0
3384 ; CHECK-SD-NEXT:    ushll2 v3.4s, v1.8h, #0
3385 ; CHECK-SD-NEXT:    ushll v1.4s, v1.4h, #0
3386 ; CHECK-SD-NEXT:    uaddl2 v4.2d, v0.4s, v2.4s
3387 ; CHECK-SD-NEXT:    uaddl v0.2d, v0.2s, v2.2s
3388 ; CHECK-SD-NEXT:    uaddl2 v2.2d, v1.4s, v3.4s
3389 ; CHECK-SD-NEXT:    uaddl v1.2d, v1.2s, v3.2s
3390 ; CHECK-SD-NEXT:    add v0.2d, v0.2d, v4.2d
3391 ; CHECK-SD-NEXT:    add v1.2d, v1.2d, v2.2d
3392 ; CHECK-SD-NEXT:    add v0.2d, v0.2d, v1.2d
3393 ; CHECK-SD-NEXT:    addp d0, v0.2d
3394 ; CHECK-SD-NEXT:    fmov x0, d0
3395 ; CHECK-SD-NEXT:    ret
3397 ; CHECK-GI-LABEL: add_pair_v8i8_v8i64_zext:
3398 ; CHECK-GI:       // %bb.0: // %entry
3399 ; CHECK-GI-NEXT:    uaddlv h1, v1.8b
3400 ; CHECK-GI-NEXT:    uaddlv h0, v0.8b
3401 ; CHECK-GI-NEXT:    fmov w8, s1
3402 ; CHECK-GI-NEXT:    fmov w9, s0
3403 ; CHECK-GI-NEXT:    and x8, x8, #0xffff
3404 ; CHECK-GI-NEXT:    add x0, x8, w9, uxth
3405 ; CHECK-GI-NEXT:    ret
3406 entry:
3407   %xx = zext <8 x i8> %x to <8 x i64>
3408   %z1 = call i64 @llvm.vector.reduce.add.v8i64(<8 x i64> %xx)
3409   %yy = zext <8 x i8> %y to <8 x i64>
3410   %z2 = call i64 @llvm.vector.reduce.add.v8i64(<8 x i64> %yy)
3411   %z = add i64 %z1, %z2
3412   ret i64 %z
3415 define i64 @add_pair_v8i8_v8i64_sext(<8 x i8> %x, <8 x i8> %y) {
3416 ; CHECK-SD-LABEL: add_pair_v8i8_v8i64_sext:
3417 ; CHECK-SD:       // %bb.0: // %entry
3418 ; CHECK-SD-NEXT:    sshll v0.8h, v0.8b, #0
3419 ; CHECK-SD-NEXT:    sshll v1.8h, v1.8b, #0
3420 ; CHECK-SD-NEXT:    sshll2 v2.4s, v0.8h, #0
3421 ; CHECK-SD-NEXT:    sshll v0.4s, v0.4h, #0
3422 ; CHECK-SD-NEXT:    sshll2 v3.4s, v1.8h, #0
3423 ; CHECK-SD-NEXT:    sshll v1.4s, v1.4h, #0
3424 ; CHECK-SD-NEXT:    saddl2 v4.2d, v0.4s, v2.4s
3425 ; CHECK-SD-NEXT:    saddl v0.2d, v0.2s, v2.2s
3426 ; CHECK-SD-NEXT:    saddl2 v2.2d, v1.4s, v3.4s
3427 ; CHECK-SD-NEXT:    saddl v1.2d, v1.2s, v3.2s
3428 ; CHECK-SD-NEXT:    add v0.2d, v0.2d, v4.2d
3429 ; CHECK-SD-NEXT:    add v1.2d, v1.2d, v2.2d
3430 ; CHECK-SD-NEXT:    add v0.2d, v0.2d, v1.2d
3431 ; CHECK-SD-NEXT:    addp d0, v0.2d
3432 ; CHECK-SD-NEXT:    fmov x0, d0
3433 ; CHECK-SD-NEXT:    ret
3435 ; CHECK-GI-LABEL: add_pair_v8i8_v8i64_sext:
3436 ; CHECK-GI:       // %bb.0: // %entry
3437 ; CHECK-GI-NEXT:    saddlv h1, v1.8b
3438 ; CHECK-GI-NEXT:    saddlv h0, v0.8b
3439 ; CHECK-GI-NEXT:    fmov w8, s1
3440 ; CHECK-GI-NEXT:    fmov w9, s0
3441 ; CHECK-GI-NEXT:    sxth x8, w8
3442 ; CHECK-GI-NEXT:    add x0, x8, w9, sxth
3443 ; CHECK-GI-NEXT:    ret
3444 entry:
3445   %xx = sext <8 x i8> %x to <8 x i64>
3446   %z1 = call i64 @llvm.vector.reduce.add.v8i64(<8 x i64> %xx)
3447   %yy = sext <8 x i8> %y to <8 x i64>
3448   %z2 = call i64 @llvm.vector.reduce.add.v8i64(<8 x i64> %yy)
3449   %z = add i64 %z1, %z2
3450   ret i64 %z
3453 define i64 @add_pair_v4i8_v4i64_zext(<4 x i8> %x, <4 x i8> %y) {
3454 ; CHECK-SD-LABEL: add_pair_v4i8_v4i64_zext:
3455 ; CHECK-SD:       // %bb.0: // %entry
3456 ; CHECK-SD-NEXT:    bic v1.4h, #255, lsl #8
3457 ; CHECK-SD-NEXT:    bic v0.4h, #255, lsl #8
3458 ; CHECK-SD-NEXT:    ushll v1.4s, v1.4h, #0
3459 ; CHECK-SD-NEXT:    ushll v0.4s, v0.4h, #0
3460 ; CHECK-SD-NEXT:    uaddlp v1.2d, v1.4s
3461 ; CHECK-SD-NEXT:    uadalp v1.2d, v0.4s
3462 ; CHECK-SD-NEXT:    addp d0, v1.2d
3463 ; CHECK-SD-NEXT:    fmov x0, d0
3464 ; CHECK-SD-NEXT:    ret
3466 ; CHECK-GI-LABEL: add_pair_v4i8_v4i64_zext:
3467 ; CHECK-GI:       // %bb.0: // %entry
3468 ; CHECK-GI-NEXT:    movi d2, #0xff00ff00ff00ff
3469 ; CHECK-GI-NEXT:    and v1.8b, v1.8b, v2.8b
3470 ; CHECK-GI-NEXT:    and v0.8b, v0.8b, v2.8b
3471 ; CHECK-GI-NEXT:    uaddlv s1, v1.4h
3472 ; CHECK-GI-NEXT:    uaddlv s0, v0.4h
3473 ; CHECK-GI-NEXT:    fmov w8, s1
3474 ; CHECK-GI-NEXT:    fmov w9, s0
3475 ; CHECK-GI-NEXT:    and x8, x8, #0xffff
3476 ; CHECK-GI-NEXT:    add x0, x8, w9, uxth
3477 ; CHECK-GI-NEXT:    ret
3478 entry:
3479   %xx = zext <4 x i8> %x to <4 x i64>
3480   %z1 = call i64 @llvm.vector.reduce.add.v4i64(<4 x i64> %xx)
3481   %yy = zext <4 x i8> %y to <4 x i64>
3482   %z2 = call i64 @llvm.vector.reduce.add.v4i64(<4 x i64> %yy)
3483   %z = add i64 %z1, %z2
3484   ret i64 %z
3487 define i64 @add_pair_v4i8_v4i64_sext(<4 x i8> %x, <4 x i8> %y) {
3488 ; CHECK-SD-LABEL: add_pair_v4i8_v4i64_sext:
3489 ; CHECK-SD:       // %bb.0: // %entry
3490 ; CHECK-SD-NEXT:    ushll v1.4s, v1.4h, #0
3491 ; CHECK-SD-NEXT:    ushll v0.4s, v0.4h, #0
3492 ; CHECK-SD-NEXT:    ushll v2.2d, v1.2s, #0
3493 ; CHECK-SD-NEXT:    ushll v3.2d, v0.2s, #0
3494 ; CHECK-SD-NEXT:    ushll2 v0.2d, v0.4s, #0
3495 ; CHECK-SD-NEXT:    ushll2 v1.2d, v1.4s, #0
3496 ; CHECK-SD-NEXT:    shl v3.2d, v3.2d, #56
3497 ; CHECK-SD-NEXT:    shl v2.2d, v2.2d, #56
3498 ; CHECK-SD-NEXT:    shl v0.2d, v0.2d, #56
3499 ; CHECK-SD-NEXT:    shl v1.2d, v1.2d, #56
3500 ; CHECK-SD-NEXT:    sshr v3.2d, v3.2d, #56
3501 ; CHECK-SD-NEXT:    sshr v2.2d, v2.2d, #56
3502 ; CHECK-SD-NEXT:    ssra v3.2d, v0.2d, #56
3503 ; CHECK-SD-NEXT:    ssra v2.2d, v1.2d, #56
3504 ; CHECK-SD-NEXT:    add v0.2d, v3.2d, v2.2d
3505 ; CHECK-SD-NEXT:    addp d0, v0.2d
3506 ; CHECK-SD-NEXT:    fmov x0, d0
3507 ; CHECK-SD-NEXT:    ret
3509 ; CHECK-GI-LABEL: add_pair_v4i8_v4i64_sext:
3510 ; CHECK-GI:       // %bb.0: // %entry
3511 ; CHECK-GI-NEXT:    shl v1.4h, v1.4h, #8
3512 ; CHECK-GI-NEXT:    shl v0.4h, v0.4h, #8
3513 ; CHECK-GI-NEXT:    sshr v1.4h, v1.4h, #8
3514 ; CHECK-GI-NEXT:    sshr v0.4h, v0.4h, #8
3515 ; CHECK-GI-NEXT:    saddlv s1, v1.4h
3516 ; CHECK-GI-NEXT:    saddlv s0, v0.4h
3517 ; CHECK-GI-NEXT:    fmov w8, s1
3518 ; CHECK-GI-NEXT:    fmov w9, s0
3519 ; CHECK-GI-NEXT:    sxth x8, w8
3520 ; CHECK-GI-NEXT:    add x0, x8, w9, sxth
3521 ; CHECK-GI-NEXT:    ret
3522 entry:
3523   %xx = sext <4 x i8> %x to <4 x i64>
3524   %z1 = call i64 @llvm.vector.reduce.add.v4i64(<4 x i64> %xx)
3525   %yy = sext <4 x i8> %y to <4 x i64>
3526   %z2 = call i64 @llvm.vector.reduce.add.v4i64(<4 x i64> %yy)
3527   %z = add i64 %z1, %z2
3528   ret i64 %z
3531 define i64 @add_pair_v2i8_v2i64_zext(<2 x i8> %x, <2 x i8> %y) {
3532 ; CHECK-SD-LABEL: add_pair_v2i8_v2i64_zext:
3533 ; CHECK-SD:       // %bb.0: // %entry
3534 ; CHECK-SD-NEXT:    // kill: def $d0 killed $d0 def $q0
3535 ; CHECK-SD-NEXT:    // kill: def $d1 killed $d1 def $q1
3536 ; CHECK-SD-NEXT:    movi v2.2d, #0x0000ff000000ff
3537 ; CHECK-SD-NEXT:    mov v0.d[1], v1.d[0]
3538 ; CHECK-SD-NEXT:    and v0.16b, v0.16b, v2.16b
3539 ; CHECK-SD-NEXT:    uaddlv d0, v0.4s
3540 ; CHECK-SD-NEXT:    fmov x0, d0
3541 ; CHECK-SD-NEXT:    ret
3543 ; CHECK-GI-LABEL: add_pair_v2i8_v2i64_zext:
3544 ; CHECK-GI:       // %bb.0: // %entry
3545 ; CHECK-GI-NEXT:    movi v2.2d, #0x000000000000ff
3546 ; CHECK-GI-NEXT:    ushll v0.2d, v0.2s, #0
3547 ; CHECK-GI-NEXT:    ushll v1.2d, v1.2s, #0
3548 ; CHECK-GI-NEXT:    and v0.16b, v0.16b, v2.16b
3549 ; CHECK-GI-NEXT:    and v1.16b, v1.16b, v2.16b
3550 ; CHECK-GI-NEXT:    addp d0, v0.2d
3551 ; CHECK-GI-NEXT:    addp d1, v1.2d
3552 ; CHECK-GI-NEXT:    fmov x8, d0
3553 ; CHECK-GI-NEXT:    fmov x9, d1
3554 ; CHECK-GI-NEXT:    add x0, x8, x9
3555 ; CHECK-GI-NEXT:    ret
3556 entry:
3557   %xx = zext <2 x i8> %x to <2 x i64>
3558   %z1 = call i64 @llvm.vector.reduce.add.v2i64(<2 x i64> %xx)
3559   %yy = zext <2 x i8> %y to <2 x i64>
3560   %z2 = call i64 @llvm.vector.reduce.add.v2i64(<2 x i64> %yy)
3561   %z = add i64 %z1, %z2
3562   ret i64 %z
3565 define i64 @add_pair_v2i8_v2i64_sext(<2 x i8> %x, <2 x i8> %y) {
3566 ; CHECK-SD-LABEL: add_pair_v2i8_v2i64_sext:
3567 ; CHECK-SD:       // %bb.0: // %entry
3568 ; CHECK-SD-NEXT:    ushll v0.2d, v0.2s, #0
3569 ; CHECK-SD-NEXT:    ushll v1.2d, v1.2s, #0
3570 ; CHECK-SD-NEXT:    shl v0.2d, v0.2d, #56
3571 ; CHECK-SD-NEXT:    shl v1.2d, v1.2d, #56
3572 ; CHECK-SD-NEXT:    sshr v0.2d, v0.2d, #56
3573 ; CHECK-SD-NEXT:    ssra v0.2d, v1.2d, #56
3574 ; CHECK-SD-NEXT:    addp d0, v0.2d
3575 ; CHECK-SD-NEXT:    fmov x0, d0
3576 ; CHECK-SD-NEXT:    ret
3578 ; CHECK-GI-LABEL: add_pair_v2i8_v2i64_sext:
3579 ; CHECK-GI:       // %bb.0: // %entry
3580 ; CHECK-GI-NEXT:    ushll v0.2d, v0.2s, #0
3581 ; CHECK-GI-NEXT:    ushll v1.2d, v1.2s, #0
3582 ; CHECK-GI-NEXT:    shl v0.2d, v0.2d, #56
3583 ; CHECK-GI-NEXT:    shl v1.2d, v1.2d, #56
3584 ; CHECK-GI-NEXT:    sshr v0.2d, v0.2d, #56
3585 ; CHECK-GI-NEXT:    sshr v1.2d, v1.2d, #56
3586 ; CHECK-GI-NEXT:    addp d0, v0.2d
3587 ; CHECK-GI-NEXT:    addp d1, v1.2d
3588 ; CHECK-GI-NEXT:    fmov x8, d0
3589 ; CHECK-GI-NEXT:    fmov x9, d1
3590 ; CHECK-GI-NEXT:    add x0, x8, x9
3591 ; CHECK-GI-NEXT:    ret
3592 entry:
3593   %xx = sext <2 x i8> %x to <2 x i64>
3594   %z1 = call i64 @llvm.vector.reduce.add.v2i64(<2 x i64> %xx)
3595   %yy = sext <2 x i8> %y to <2 x i64>
3596   %z2 = call i64 @llvm.vector.reduce.add.v2i64(<2 x i64> %yy)
3597   %z = add i64 %z1, %z2
3598   ret i64 %z
3601 define i32 @add_pair_v8i8_v8i32_double_sext_zext(<8 x i8> %ax, <8 x i8> %ay, <8 x i8> %bx, <8 x i8> %by) {
3602 ; CHECK-SD-BASE-LABEL: add_pair_v8i8_v8i32_double_sext_zext:
3603 ; CHECK-SD-BASE:       // %bb.0: // %entry
3604 ; CHECK-SD-BASE-NEXT:    ushll v1.8h, v1.8b, #0
3605 ; CHECK-SD-BASE-NEXT:    sshll v3.8h, v3.8b, #0
3606 ; CHECK-SD-BASE-NEXT:    ushll v0.8h, v0.8b, #0
3607 ; CHECK-SD-BASE-NEXT:    sshll v2.8h, v2.8b, #0
3608 ; CHECK-SD-BASE-NEXT:    uaddlp v1.4s, v1.8h
3609 ; CHECK-SD-BASE-NEXT:    saddlp v3.4s, v3.8h
3610 ; CHECK-SD-BASE-NEXT:    uadalp v1.4s, v0.8h
3611 ; CHECK-SD-BASE-NEXT:    sadalp v3.4s, v2.8h
3612 ; CHECK-SD-BASE-NEXT:    add v0.4s, v3.4s, v1.4s
3613 ; CHECK-SD-BASE-NEXT:    addv s0, v0.4s
3614 ; CHECK-SD-BASE-NEXT:    fmov w0, s0
3615 ; CHECK-SD-BASE-NEXT:    ret
3617 ; CHECK-SD-DOT-LABEL: add_pair_v8i8_v8i32_double_sext_zext:
3618 ; CHECK-SD-DOT:       // %bb.0: // %entry
3619 ; CHECK-SD-DOT-NEXT:    movi v4.2d, #0000000000000000
3620 ; CHECK-SD-DOT-NEXT:    movi v5.8b, #1
3621 ; CHECK-SD-DOT-NEXT:    movi v6.2d, #0000000000000000
3622 ; CHECK-SD-DOT-NEXT:    udot v6.2s, v1.8b, v5.8b
3623 ; CHECK-SD-DOT-NEXT:    sdot v4.2s, v3.8b, v5.8b
3624 ; CHECK-SD-DOT-NEXT:    udot v6.2s, v0.8b, v5.8b
3625 ; CHECK-SD-DOT-NEXT:    sdot v4.2s, v2.8b, v5.8b
3626 ; CHECK-SD-DOT-NEXT:    add v0.2s, v6.2s, v4.2s
3627 ; CHECK-SD-DOT-NEXT:    addp v0.2s, v0.2s, v0.2s
3628 ; CHECK-SD-DOT-NEXT:    fmov w0, s0
3629 ; CHECK-SD-DOT-NEXT:    ret
3631 ; CHECK-GI-BASE-LABEL: add_pair_v8i8_v8i32_double_sext_zext:
3632 ; CHECK-GI-BASE:       // %bb.0: // %entry
3633 ; CHECK-GI-BASE-NEXT:    saddlv h3, v3.8b
3634 ; CHECK-GI-BASE-NEXT:    uaddlv h1, v1.8b
3635 ; CHECK-GI-BASE-NEXT:    uaddlv h0, v0.8b
3636 ; CHECK-GI-BASE-NEXT:    saddlv h2, v2.8b
3637 ; CHECK-GI-BASE-NEXT:    fmov w8, s3
3638 ; CHECK-GI-BASE-NEXT:    fmov w9, s1
3639 ; CHECK-GI-BASE-NEXT:    fmov w10, s0
3640 ; CHECK-GI-BASE-NEXT:    fmov w11, s2
3641 ; CHECK-GI-BASE-NEXT:    sxth w8, w8
3642 ; CHECK-GI-BASE-NEXT:    and w9, w9, #0xffff
3643 ; CHECK-GI-BASE-NEXT:    add w9, w9, w10, uxth
3644 ; CHECK-GI-BASE-NEXT:    add w8, w8, w11, sxth
3645 ; CHECK-GI-BASE-NEXT:    add w0, w9, w8
3646 ; CHECK-GI-BASE-NEXT:    ret
3648 ; CHECK-GI-DOT-LABEL: add_pair_v8i8_v8i32_double_sext_zext:
3649 ; CHECK-GI-DOT:       // %bb.0: // %entry
3650 ; CHECK-GI-DOT-NEXT:    movi v4.8b, #1
3651 ; CHECK-GI-DOT-NEXT:    movi v5.2d, #0000000000000000
3652 ; CHECK-GI-DOT-NEXT:    movi v6.2d, #0000000000000000
3653 ; CHECK-GI-DOT-NEXT:    movi v7.2d, #0000000000000000
3654 ; CHECK-GI-DOT-NEXT:    movi v16.2d, #0000000000000000
3655 ; CHECK-GI-DOT-NEXT:    udot v5.2s, v0.8b, v4.8b
3656 ; CHECK-GI-DOT-NEXT:    sdot v6.2s, v3.8b, v4.8b
3657 ; CHECK-GI-DOT-NEXT:    udot v7.2s, v1.8b, v4.8b
3658 ; CHECK-GI-DOT-NEXT:    sdot v16.2s, v2.8b, v4.8b
3659 ; CHECK-GI-DOT-NEXT:    addp v0.2s, v5.2s, v5.2s
3660 ; CHECK-GI-DOT-NEXT:    addp v3.2s, v6.2s, v6.2s
3661 ; CHECK-GI-DOT-NEXT:    addp v1.2s, v7.2s, v7.2s
3662 ; CHECK-GI-DOT-NEXT:    addp v2.2s, v16.2s, v16.2s
3663 ; CHECK-GI-DOT-NEXT:    fmov w8, s0
3664 ; CHECK-GI-DOT-NEXT:    fmov w11, s3
3665 ; CHECK-GI-DOT-NEXT:    fmov w9, s1
3666 ; CHECK-GI-DOT-NEXT:    fmov w10, s2
3667 ; CHECK-GI-DOT-NEXT:    add w8, w8, w9
3668 ; CHECK-GI-DOT-NEXT:    add w9, w10, w11
3669 ; CHECK-GI-DOT-NEXT:    add w0, w8, w9
3670 ; CHECK-GI-DOT-NEXT:    ret
3671 entry:
3672   %axx = zext <8 x i8> %ax to <8 x i32>
3673   %az1 = call i32 @llvm.vector.reduce.add.v8i32(<8 x i32> %axx)
3674   %ayy = zext <8 x i8> %ay to <8 x i32>
3675   %az2 = call i32 @llvm.vector.reduce.add.v8i32(<8 x i32> %ayy)
3676   %az = add i32 %az1, %az2
3677   %bxx = sext <8 x i8> %bx to <8 x i32>
3678   %bz1 = call i32 @llvm.vector.reduce.add.v8i32(<8 x i32> %bxx)
3679   %byy = sext <8 x i8> %by to <8 x i32>
3680   %bz2 = call i32 @llvm.vector.reduce.add.v8i32(<8 x i32> %byy)
3681   %bz = add i32 %bz1, %bz2
3682   %z = add i32 %az, %bz
3683   ret i32 %z
3686 define i32 @add_pair_v8i16_v4i32_double_sext_zext_shuffle(<8 x i16> %ax, <8 x i16> %ay, <8 x i16> %bx, <8 x i16> %by) {
3687 ; CHECK-SD-LABEL: add_pair_v8i16_v4i32_double_sext_zext_shuffle:
3688 ; CHECK-SD:       // %bb.0: // %entry
3689 ; CHECK-SD-NEXT:    uaddlp v1.4s, v1.8h
3690 ; CHECK-SD-NEXT:    uaddlp v3.4s, v3.8h
3691 ; CHECK-SD-NEXT:    uadalp v1.4s, v0.8h
3692 ; CHECK-SD-NEXT:    uadalp v3.4s, v2.8h
3693 ; CHECK-SD-NEXT:    add v0.4s, v3.4s, v1.4s
3694 ; CHECK-SD-NEXT:    addv s0, v0.4s
3695 ; CHECK-SD-NEXT:    fmov w0, s0
3696 ; CHECK-SD-NEXT:    ret
3698 ; CHECK-GI-LABEL: add_pair_v8i16_v4i32_double_sext_zext_shuffle:
3699 ; CHECK-GI:       // %bb.0: // %entry
3700 ; CHECK-GI-NEXT:    ushll v4.4s, v0.4h, #0
3701 ; CHECK-GI-NEXT:    ushll2 v0.4s, v0.8h, #0
3702 ; CHECK-GI-NEXT:    ushll v5.4s, v1.4h, #0
3703 ; CHECK-GI-NEXT:    ushll2 v1.4s, v1.8h, #0
3704 ; CHECK-GI-NEXT:    ushll v6.4s, v2.4h, #0
3705 ; CHECK-GI-NEXT:    ushll2 v2.4s, v2.8h, #0
3706 ; CHECK-GI-NEXT:    ushll v7.4s, v3.4h, #0
3707 ; CHECK-GI-NEXT:    ushll2 v3.4s, v3.8h, #0
3708 ; CHECK-GI-NEXT:    add v0.4s, v4.4s, v0.4s
3709 ; CHECK-GI-NEXT:    add v1.4s, v5.4s, v1.4s
3710 ; CHECK-GI-NEXT:    add v2.4s, v6.4s, v2.4s
3711 ; CHECK-GI-NEXT:    add v3.4s, v7.4s, v3.4s
3712 ; CHECK-GI-NEXT:    add v0.4s, v0.4s, v1.4s
3713 ; CHECK-GI-NEXT:    add v1.4s, v2.4s, v3.4s
3714 ; CHECK-GI-NEXT:    add v0.4s, v0.4s, v1.4s
3715 ; CHECK-GI-NEXT:    addv s0, v0.4s
3716 ; CHECK-GI-NEXT:    fmov w0, s0
3717 ; CHECK-GI-NEXT:    ret
3718 entry:
3719   %axx = zext <8 x i16> %ax to <8 x i32>
3720   %s1h = shufflevector <8 x i32> %axx, <8 x i32> undef, <4 x i32> <i32 0, i32 1, i32 2, i32 3>
3721   %s1l = shufflevector <8 x i32> %axx, <8 x i32> undef, <4 x i32> <i32 4, i32 5, i32 6, i32 7>
3722   %axs = add <4 x i32> %s1h, %s1l
3723   %ayy = zext <8 x i16> %ay to <8 x i32>
3724   %s2h = shufflevector <8 x i32> %ayy, <8 x i32> undef, <4 x i32> <i32 0, i32 1, i32 2, i32 3>
3725   %s2l = shufflevector <8 x i32> %ayy, <8 x i32> undef, <4 x i32> <i32 4, i32 5, i32 6, i32 7>
3726   %ays = add <4 x i32> %s2h, %s2l
3727   %az = add <4 x i32> %axs, %ays
3728   %bxx = zext <8 x i16> %bx to <8 x i32>
3729   %s3h = shufflevector <8 x i32> %bxx, <8 x i32> undef, <4 x i32> <i32 0, i32 1, i32 2, i32 3>
3730   %s3l = shufflevector <8 x i32> %bxx, <8 x i32> undef, <4 x i32> <i32 4, i32 5, i32 6, i32 7>
3731   %bxs = add <4 x i32> %s3h, %s3l
3732   %byy = zext <8 x i16> %by to <8 x i32>
3733   %s4h = shufflevector <8 x i32> %byy, <8 x i32> undef, <4 x i32> <i32 0, i32 1, i32 2, i32 3>
3734   %s4l = shufflevector <8 x i32> %byy, <8 x i32> undef, <4 x i32> <i32 4, i32 5, i32 6, i32 7>
3735   %bys = add <4 x i32> %s4h, %s4l
3736   %bz = add <4 x i32> %bxs, %bys
3737   %z = add <4 x i32> %az, %bz
3738   %z2 = call i32 @llvm.vector.reduce.add.v4i32(<4 x i32> %z)
3739   ret i32 %z2
3742 define i64 @add_pair_v2i64_v2i64(<2 x i64> %x, <2 x i64> %y) {
3743 ; CHECK-SD-LABEL: add_pair_v2i64_v2i64:
3744 ; CHECK-SD:       // %bb.0: // %entry
3745 ; CHECK-SD-NEXT:    add v0.2d, v0.2d, v1.2d
3746 ; CHECK-SD-NEXT:    addp d0, v0.2d
3747 ; CHECK-SD-NEXT:    fmov x0, d0
3748 ; CHECK-SD-NEXT:    ret
3750 ; CHECK-GI-LABEL: add_pair_v2i64_v2i64:
3751 ; CHECK-GI:       // %bb.0: // %entry
3752 ; CHECK-GI-NEXT:    addp d0, v0.2d
3753 ; CHECK-GI-NEXT:    addp d1, v1.2d
3754 ; CHECK-GI-NEXT:    fmov x8, d0
3755 ; CHECK-GI-NEXT:    fmov x9, d1
3756 ; CHECK-GI-NEXT:    add x0, x8, x9
3757 ; CHECK-GI-NEXT:    ret
3758 entry:
3759   %z1 = call i64 @llvm.vector.reduce.add.v2i64(<2 x i64> %x)
3760   %z2 = call i64 @llvm.vector.reduce.add.v2i64(<2 x i64> %y)
3761   %z = add i64 %z1, %z2
3762   ret i64 %z
3765 ; Irregularly sized vectors
3766 define i16 @add_v24i8_v24i16_zext(<24 x i8> %x) {
3767 ; CHECK-SD-LABEL: add_v24i8_v24i16_zext:
3768 ; CHECK-SD:       // %bb.0: // %entry
3769 ; CHECK-SD-NEXT:    fmov s0, w0
3770 ; CHECK-SD-NEXT:    ldr b1, [sp, #64]
3771 ; CHECK-SD-NEXT:    add x8, sp, #72
3772 ; CHECK-SD-NEXT:    ldr b2, [sp]
3773 ; CHECK-SD-NEXT:    add x9, sp, #80
3774 ; CHECK-SD-NEXT:    ld1 { v1.b }[1], [x8]
3775 ; CHECK-SD-NEXT:    add x8, sp, #8
3776 ; CHECK-SD-NEXT:    mov v0.b[1], w1
3777 ; CHECK-SD-NEXT:    ld1 { v2.b }[1], [x8]
3778 ; CHECK-SD-NEXT:    add x8, sp, #16
3779 ; CHECK-SD-NEXT:    ld1 { v1.b }[2], [x9]
3780 ; CHECK-SD-NEXT:    add x9, sp, #88
3781 ; CHECK-SD-NEXT:    ld1 { v2.b }[2], [x8]
3782 ; CHECK-SD-NEXT:    add x8, sp, #24
3783 ; CHECK-SD-NEXT:    mov v0.b[2], w2
3784 ; CHECK-SD-NEXT:    ld1 { v1.b }[3], [x9]
3785 ; CHECK-SD-NEXT:    add x9, sp, #96
3786 ; CHECK-SD-NEXT:    ld1 { v2.b }[3], [x8]
3787 ; CHECK-SD-NEXT:    add x8, sp, #32
3788 ; CHECK-SD-NEXT:    mov v0.b[3], w3
3789 ; CHECK-SD-NEXT:    ld1 { v1.b }[4], [x9]
3790 ; CHECK-SD-NEXT:    add x9, sp, #104
3791 ; CHECK-SD-NEXT:    ld1 { v2.b }[4], [x8]
3792 ; CHECK-SD-NEXT:    add x8, sp, #40
3793 ; CHECK-SD-NEXT:    ld1 { v1.b }[5], [x9]
3794 ; CHECK-SD-NEXT:    add x9, sp, #112
3795 ; CHECK-SD-NEXT:    mov v0.b[4], w4
3796 ; CHECK-SD-NEXT:    ld1 { v2.b }[5], [x8]
3797 ; CHECK-SD-NEXT:    add x8, sp, #48
3798 ; CHECK-SD-NEXT:    ld1 { v1.b }[6], [x9]
3799 ; CHECK-SD-NEXT:    add x9, sp, #120
3800 ; CHECK-SD-NEXT:    ld1 { v2.b }[6], [x8]
3801 ; CHECK-SD-NEXT:    add x8, sp, #56
3802 ; CHECK-SD-NEXT:    mov v0.b[5], w5
3803 ; CHECK-SD-NEXT:    ld1 { v1.b }[7], [x9]
3804 ; CHECK-SD-NEXT:    ld1 { v2.b }[7], [x8]
3805 ; CHECK-SD-NEXT:    mov v0.b[6], w6
3806 ; CHECK-SD-NEXT:    mov v0.b[7], w7
3807 ; CHECK-SD-NEXT:    uaddl v0.8h, v0.8b, v1.8b
3808 ; CHECK-SD-NEXT:    uaddw v0.8h, v0.8h, v2.8b
3809 ; CHECK-SD-NEXT:    addv h0, v0.8h
3810 ; CHECK-SD-NEXT:    fmov w0, s0
3811 ; CHECK-SD-NEXT:    ret
3813 ; CHECK-GI-LABEL: add_v24i8_v24i16_zext:
3814 ; CHECK-GI:       // %bb.0: // %entry
3815 ; CHECK-GI-NEXT:    fmov s0, w0
3816 ; CHECK-GI-NEXT:    ldr w8, [sp]
3817 ; CHECK-GI-NEXT:    ldr w9, [sp, #8]
3818 ; CHECK-GI-NEXT:    ldr w10, [sp, #72]
3819 ; CHECK-GI-NEXT:    mov v0.b[1], w1
3820 ; CHECK-GI-NEXT:    mov v0.b[2], w2
3821 ; CHECK-GI-NEXT:    mov v0.b[3], w3
3822 ; CHECK-GI-NEXT:    mov v0.b[4], w4
3823 ; CHECK-GI-NEXT:    mov v0.b[5], w5
3824 ; CHECK-GI-NEXT:    mov v0.b[6], w6
3825 ; CHECK-GI-NEXT:    mov v0.b[7], w7
3826 ; CHECK-GI-NEXT:    mov v0.b[8], w8
3827 ; CHECK-GI-NEXT:    ldr w8, [sp, #64]
3828 ; CHECK-GI-NEXT:    fmov s1, w8
3829 ; CHECK-GI-NEXT:    ldr w8, [sp, #16]
3830 ; CHECK-GI-NEXT:    mov v0.b[9], w9
3831 ; CHECK-GI-NEXT:    ldr w9, [sp, #80]
3832 ; CHECK-GI-NEXT:    mov v1.b[1], w10
3833 ; CHECK-GI-NEXT:    mov v0.b[10], w8
3834 ; CHECK-GI-NEXT:    ldr w8, [sp, #24]
3835 ; CHECK-GI-NEXT:    mov v1.b[2], w9
3836 ; CHECK-GI-NEXT:    ldr w9, [sp, #88]
3837 ; CHECK-GI-NEXT:    mov v0.b[11], w8
3838 ; CHECK-GI-NEXT:    ldr w8, [sp, #32]
3839 ; CHECK-GI-NEXT:    mov v1.b[3], w9
3840 ; CHECK-GI-NEXT:    ldr w9, [sp, #96]
3841 ; CHECK-GI-NEXT:    mov v0.b[12], w8
3842 ; CHECK-GI-NEXT:    ldr w8, [sp, #40]
3843 ; CHECK-GI-NEXT:    mov v1.b[4], w9
3844 ; CHECK-GI-NEXT:    ldr w9, [sp, #104]
3845 ; CHECK-GI-NEXT:    mov v0.b[13], w8
3846 ; CHECK-GI-NEXT:    ldr w8, [sp, #48]
3847 ; CHECK-GI-NEXT:    mov v1.b[5], w9
3848 ; CHECK-GI-NEXT:    ldr w9, [sp, #112]
3849 ; CHECK-GI-NEXT:    mov v0.b[14], w8
3850 ; CHECK-GI-NEXT:    ldr w8, [sp, #56]
3851 ; CHECK-GI-NEXT:    mov v1.b[6], w9
3852 ; CHECK-GI-NEXT:    ldr w9, [sp, #120]
3853 ; CHECK-GI-NEXT:    mov v0.b[15], w8
3854 ; CHECK-GI-NEXT:    mov v1.b[7], w9
3855 ; CHECK-GI-NEXT:    uaddlv h0, v0.16b
3856 ; CHECK-GI-NEXT:    uaddlv h1, v1.8b
3857 ; CHECK-GI-NEXT:    fmov w8, s0
3858 ; CHECK-GI-NEXT:    fmov w9, s1
3859 ; CHECK-GI-NEXT:    add w0, w8, w9
3860 ; CHECK-GI-NEXT:    ret
3861 entry:
3862   %xx = zext <24 x i8> %x to <24 x i16>
3863   %z = call i16 @llvm.vector.reduce.add.v24i16(<24 x i16> %xx)
3864   ret i16 %z
3867 define i16 @add_v32i8_v32i16_zext(<32 x i8> %x) {
3868 ; CHECK-SD-LABEL: add_v32i8_v32i16_zext:
3869 ; CHECK-SD:       // %bb.0: // %entry
3870 ; CHECK-SD-NEXT:    uaddl2 v2.8h, v0.16b, v1.16b
3871 ; CHECK-SD-NEXT:    uaddl v0.8h, v0.8b, v1.8b
3872 ; CHECK-SD-NEXT:    add v0.8h, v0.8h, v2.8h
3873 ; CHECK-SD-NEXT:    addv h0, v0.8h
3874 ; CHECK-SD-NEXT:    fmov w0, s0
3875 ; CHECK-SD-NEXT:    ret
3877 ; CHECK-GI-LABEL: add_v32i8_v32i16_zext:
3878 ; CHECK-GI:       // %bb.0: // %entry
3879 ; CHECK-GI-NEXT:    uaddlv h0, v0.16b
3880 ; CHECK-GI-NEXT:    uaddlv h1, v1.16b
3881 ; CHECK-GI-NEXT:    fmov w8, s0
3882 ; CHECK-GI-NEXT:    fmov w9, s1
3883 ; CHECK-GI-NEXT:    add w0, w8, w9
3884 ; CHECK-GI-NEXT:    ret
3885 entry:
3886   %xx = zext <32 x i8> %x to <32 x i16>
3887   %z = call i16 @llvm.vector.reduce.add.v32i16(<32 x i16> %xx)
3888   ret i16 %z
3891 define i16 @add_v24i8_v24i16_sext(<24 x i8> %x) {
3892 ; CHECK-SD-LABEL: add_v24i8_v24i16_sext:
3893 ; CHECK-SD:       // %bb.0: // %entry
3894 ; CHECK-SD-NEXT:    fmov s0, w0
3895 ; CHECK-SD-NEXT:    ldr b1, [sp, #64]
3896 ; CHECK-SD-NEXT:    add x8, sp, #72
3897 ; CHECK-SD-NEXT:    ldr b2, [sp]
3898 ; CHECK-SD-NEXT:    add x9, sp, #80
3899 ; CHECK-SD-NEXT:    ld1 { v1.b }[1], [x8]
3900 ; CHECK-SD-NEXT:    add x8, sp, #8
3901 ; CHECK-SD-NEXT:    mov v0.b[1], w1
3902 ; CHECK-SD-NEXT:    ld1 { v2.b }[1], [x8]
3903 ; CHECK-SD-NEXT:    add x8, sp, #16
3904 ; CHECK-SD-NEXT:    ld1 { v1.b }[2], [x9]
3905 ; CHECK-SD-NEXT:    add x9, sp, #88
3906 ; CHECK-SD-NEXT:    ld1 { v2.b }[2], [x8]
3907 ; CHECK-SD-NEXT:    add x8, sp, #24
3908 ; CHECK-SD-NEXT:    mov v0.b[2], w2
3909 ; CHECK-SD-NEXT:    ld1 { v1.b }[3], [x9]
3910 ; CHECK-SD-NEXT:    add x9, sp, #96
3911 ; CHECK-SD-NEXT:    ld1 { v2.b }[3], [x8]
3912 ; CHECK-SD-NEXT:    add x8, sp, #32
3913 ; CHECK-SD-NEXT:    mov v0.b[3], w3
3914 ; CHECK-SD-NEXT:    ld1 { v1.b }[4], [x9]
3915 ; CHECK-SD-NEXT:    add x9, sp, #104
3916 ; CHECK-SD-NEXT:    ld1 { v2.b }[4], [x8]
3917 ; CHECK-SD-NEXT:    add x8, sp, #40
3918 ; CHECK-SD-NEXT:    ld1 { v1.b }[5], [x9]
3919 ; CHECK-SD-NEXT:    add x9, sp, #112
3920 ; CHECK-SD-NEXT:    mov v0.b[4], w4
3921 ; CHECK-SD-NEXT:    ld1 { v2.b }[5], [x8]
3922 ; CHECK-SD-NEXT:    add x8, sp, #48
3923 ; CHECK-SD-NEXT:    ld1 { v1.b }[6], [x9]
3924 ; CHECK-SD-NEXT:    add x9, sp, #120
3925 ; CHECK-SD-NEXT:    ld1 { v2.b }[6], [x8]
3926 ; CHECK-SD-NEXT:    add x8, sp, #56
3927 ; CHECK-SD-NEXT:    mov v0.b[5], w5
3928 ; CHECK-SD-NEXT:    ld1 { v1.b }[7], [x9]
3929 ; CHECK-SD-NEXT:    ld1 { v2.b }[7], [x8]
3930 ; CHECK-SD-NEXT:    mov v0.b[6], w6
3931 ; CHECK-SD-NEXT:    mov v0.b[7], w7
3932 ; CHECK-SD-NEXT:    saddl v0.8h, v0.8b, v1.8b
3933 ; CHECK-SD-NEXT:    saddw v0.8h, v0.8h, v2.8b
3934 ; CHECK-SD-NEXT:    addv h0, v0.8h
3935 ; CHECK-SD-NEXT:    fmov w0, s0
3936 ; CHECK-SD-NEXT:    ret
3938 ; CHECK-GI-LABEL: add_v24i8_v24i16_sext:
3939 ; CHECK-GI:       // %bb.0: // %entry
3940 ; CHECK-GI-NEXT:    fmov s0, w0
3941 ; CHECK-GI-NEXT:    ldr w8, [sp]
3942 ; CHECK-GI-NEXT:    ldr w9, [sp, #8]
3943 ; CHECK-GI-NEXT:    ldr w10, [sp, #72]
3944 ; CHECK-GI-NEXT:    mov v0.b[1], w1
3945 ; CHECK-GI-NEXT:    mov v0.b[2], w2
3946 ; CHECK-GI-NEXT:    mov v0.b[3], w3
3947 ; CHECK-GI-NEXT:    mov v0.b[4], w4
3948 ; CHECK-GI-NEXT:    mov v0.b[5], w5
3949 ; CHECK-GI-NEXT:    mov v0.b[6], w6
3950 ; CHECK-GI-NEXT:    mov v0.b[7], w7
3951 ; CHECK-GI-NEXT:    mov v0.b[8], w8
3952 ; CHECK-GI-NEXT:    ldr w8, [sp, #64]
3953 ; CHECK-GI-NEXT:    fmov s1, w8
3954 ; CHECK-GI-NEXT:    ldr w8, [sp, #16]
3955 ; CHECK-GI-NEXT:    mov v0.b[9], w9
3956 ; CHECK-GI-NEXT:    ldr w9, [sp, #80]
3957 ; CHECK-GI-NEXT:    mov v1.b[1], w10
3958 ; CHECK-GI-NEXT:    mov v0.b[10], w8
3959 ; CHECK-GI-NEXT:    ldr w8, [sp, #24]
3960 ; CHECK-GI-NEXT:    mov v1.b[2], w9
3961 ; CHECK-GI-NEXT:    ldr w9, [sp, #88]
3962 ; CHECK-GI-NEXT:    mov v0.b[11], w8
3963 ; CHECK-GI-NEXT:    ldr w8, [sp, #32]
3964 ; CHECK-GI-NEXT:    mov v1.b[3], w9
3965 ; CHECK-GI-NEXT:    ldr w9, [sp, #96]
3966 ; CHECK-GI-NEXT:    mov v0.b[12], w8
3967 ; CHECK-GI-NEXT:    ldr w8, [sp, #40]
3968 ; CHECK-GI-NEXT:    mov v1.b[4], w9
3969 ; CHECK-GI-NEXT:    ldr w9, [sp, #104]
3970 ; CHECK-GI-NEXT:    mov v0.b[13], w8
3971 ; CHECK-GI-NEXT:    ldr w8, [sp, #48]
3972 ; CHECK-GI-NEXT:    mov v1.b[5], w9
3973 ; CHECK-GI-NEXT:    ldr w9, [sp, #112]
3974 ; CHECK-GI-NEXT:    mov v0.b[14], w8
3975 ; CHECK-GI-NEXT:    ldr w8, [sp, #56]
3976 ; CHECK-GI-NEXT:    mov v1.b[6], w9
3977 ; CHECK-GI-NEXT:    ldr w9, [sp, #120]
3978 ; CHECK-GI-NEXT:    mov v0.b[15], w8
3979 ; CHECK-GI-NEXT:    mov v1.b[7], w9
3980 ; CHECK-GI-NEXT:    saddlv h0, v0.16b
3981 ; CHECK-GI-NEXT:    saddlv h1, v1.8b
3982 ; CHECK-GI-NEXT:    fmov w8, s0
3983 ; CHECK-GI-NEXT:    fmov w9, s1
3984 ; CHECK-GI-NEXT:    add w0, w8, w9
3985 ; CHECK-GI-NEXT:    ret
3986 entry:
3987   %xx = sext <24 x i8> %x to <24 x i16>
3988   %z = call i16 @llvm.vector.reduce.add.v24i16(<24 x i16> %xx)
3989   ret i16 %z
3992 define i16 @add_v32i8_v32i16_sext(<32 x i8> %x) {
3993 ; CHECK-SD-LABEL: add_v32i8_v32i16_sext:
3994 ; CHECK-SD:       // %bb.0: // %entry
3995 ; CHECK-SD-NEXT:    saddl2 v2.8h, v0.16b, v1.16b
3996 ; CHECK-SD-NEXT:    saddl v0.8h, v0.8b, v1.8b
3997 ; CHECK-SD-NEXT:    add v0.8h, v0.8h, v2.8h
3998 ; CHECK-SD-NEXT:    addv h0, v0.8h
3999 ; CHECK-SD-NEXT:    fmov w0, s0
4000 ; CHECK-SD-NEXT:    ret
4002 ; CHECK-GI-LABEL: add_v32i8_v32i16_sext:
4003 ; CHECK-GI:       // %bb.0: // %entry
4004 ; CHECK-GI-NEXT:    saddlv h0, v0.16b
4005 ; CHECK-GI-NEXT:    saddlv h1, v1.16b
4006 ; CHECK-GI-NEXT:    fmov w8, s0
4007 ; CHECK-GI-NEXT:    fmov w9, s1
4008 ; CHECK-GI-NEXT:    add w0, w8, w9
4009 ; CHECK-GI-NEXT:    ret
4010 entry:
4011   %xx = sext <32 x i8> %x to <32 x i16>
4012   %z = call i16 @llvm.vector.reduce.add.v32i16(<32 x i16> %xx)
4013   ret i16 %z
4016 ; Irregularly sized vectors and larger extends
4017 define i32 @add_v24i8_v24i32_zext(<24 x i8> %x) {
4018 ; CHECK-SD-BASE-LABEL: add_v24i8_v24i32_zext:
4019 ; CHECK-SD-BASE:       // %bb.0: // %entry
4020 ; CHECK-SD-BASE-NEXT:    fmov s0, w0
4021 ; CHECK-SD-BASE-NEXT:    ldr b1, [sp, #64]
4022 ; CHECK-SD-BASE-NEXT:    add x8, sp, #72
4023 ; CHECK-SD-BASE-NEXT:    ldr b2, [sp]
4024 ; CHECK-SD-BASE-NEXT:    add x9, sp, #80
4025 ; CHECK-SD-BASE-NEXT:    ld1 { v1.b }[1], [x8]
4026 ; CHECK-SD-BASE-NEXT:    add x8, sp, #8
4027 ; CHECK-SD-BASE-NEXT:    mov v0.b[1], w1
4028 ; CHECK-SD-BASE-NEXT:    ld1 { v2.b }[1], [x8]
4029 ; CHECK-SD-BASE-NEXT:    add x8, sp, #16
4030 ; CHECK-SD-BASE-NEXT:    ld1 { v1.b }[2], [x9]
4031 ; CHECK-SD-BASE-NEXT:    add x9, sp, #88
4032 ; CHECK-SD-BASE-NEXT:    ld1 { v2.b }[2], [x8]
4033 ; CHECK-SD-BASE-NEXT:    add x8, sp, #24
4034 ; CHECK-SD-BASE-NEXT:    mov v0.b[2], w2
4035 ; CHECK-SD-BASE-NEXT:    ld1 { v1.b }[3], [x9]
4036 ; CHECK-SD-BASE-NEXT:    add x9, sp, #96
4037 ; CHECK-SD-BASE-NEXT:    ld1 { v2.b }[3], [x8]
4038 ; CHECK-SD-BASE-NEXT:    add x8, sp, #32
4039 ; CHECK-SD-BASE-NEXT:    mov v0.b[3], w3
4040 ; CHECK-SD-BASE-NEXT:    ld1 { v1.b }[4], [x9]
4041 ; CHECK-SD-BASE-NEXT:    add x9, sp, #104
4042 ; CHECK-SD-BASE-NEXT:    ld1 { v2.b }[4], [x8]
4043 ; CHECK-SD-BASE-NEXT:    add x8, sp, #40
4044 ; CHECK-SD-BASE-NEXT:    ld1 { v1.b }[5], [x9]
4045 ; CHECK-SD-BASE-NEXT:    add x9, sp, #112
4046 ; CHECK-SD-BASE-NEXT:    mov v0.b[4], w4
4047 ; CHECK-SD-BASE-NEXT:    ld1 { v2.b }[5], [x8]
4048 ; CHECK-SD-BASE-NEXT:    add x8, sp, #48
4049 ; CHECK-SD-BASE-NEXT:    ld1 { v1.b }[6], [x9]
4050 ; CHECK-SD-BASE-NEXT:    add x9, sp, #120
4051 ; CHECK-SD-BASE-NEXT:    ld1 { v2.b }[6], [x8]
4052 ; CHECK-SD-BASE-NEXT:    add x8, sp, #56
4053 ; CHECK-SD-BASE-NEXT:    mov v0.b[5], w5
4054 ; CHECK-SD-BASE-NEXT:    ld1 { v1.b }[7], [x9]
4055 ; CHECK-SD-BASE-NEXT:    ld1 { v2.b }[7], [x8]
4056 ; CHECK-SD-BASE-NEXT:    mov v0.b[6], w6
4057 ; CHECK-SD-BASE-NEXT:    ushll v1.8h, v1.8b, #0
4058 ; CHECK-SD-BASE-NEXT:    ushll v2.8h, v2.8b, #0
4059 ; CHECK-SD-BASE-NEXT:    mov v0.b[7], w7
4060 ; CHECK-SD-BASE-NEXT:    ushll v0.8h, v0.8b, #0
4061 ; CHECK-SD-BASE-NEXT:    uaddl2 v3.4s, v0.8h, v1.8h
4062 ; CHECK-SD-BASE-NEXT:    uaddl v0.4s, v0.4h, v1.4h
4063 ; CHECK-SD-BASE-NEXT:    uaddw2 v1.4s, v3.4s, v2.8h
4064 ; CHECK-SD-BASE-NEXT:    uaddw v0.4s, v0.4s, v2.4h
4065 ; CHECK-SD-BASE-NEXT:    add v0.4s, v0.4s, v1.4s
4066 ; CHECK-SD-BASE-NEXT:    addv s0, v0.4s
4067 ; CHECK-SD-BASE-NEXT:    fmov w0, s0
4068 ; CHECK-SD-BASE-NEXT:    ret
4070 ; CHECK-SD-DOT-LABEL: add_v24i8_v24i32_zext:
4071 ; CHECK-SD-DOT:       // %bb.0: // %entry
4072 ; CHECK-SD-DOT-NEXT:    fmov s0, w0
4073 ; CHECK-SD-DOT-NEXT:    mov x8, sp
4074 ; CHECK-SD-DOT-NEXT:    ldr b1, [sp, #64]
4075 ; CHECK-SD-DOT-NEXT:    add x9, sp, #72
4076 ; CHECK-SD-DOT-NEXT:    movi v2.16b, #1
4077 ; CHECK-SD-DOT-NEXT:    movi v3.2d, #0000000000000000
4078 ; CHECK-SD-DOT-NEXT:    ld1 { v1.b }[1], [x9]
4079 ; CHECK-SD-DOT-NEXT:    add x9, sp, #80
4080 ; CHECK-SD-DOT-NEXT:    movi v4.2d, #0000000000000000
4081 ; CHECK-SD-DOT-NEXT:    mov v0.b[1], w1
4082 ; CHECK-SD-DOT-NEXT:    movi v5.8b, #1
4083 ; CHECK-SD-DOT-NEXT:    ld1 { v1.b }[2], [x9]
4084 ; CHECK-SD-DOT-NEXT:    add x9, sp, #88
4085 ; CHECK-SD-DOT-NEXT:    mov v0.b[2], w2
4086 ; CHECK-SD-DOT-NEXT:    ld1 { v1.b }[3], [x9]
4087 ; CHECK-SD-DOT-NEXT:    add x9, sp, #96
4088 ; CHECK-SD-DOT-NEXT:    mov v0.b[3], w3
4089 ; CHECK-SD-DOT-NEXT:    ld1 { v1.b }[4], [x9]
4090 ; CHECK-SD-DOT-NEXT:    add x9, sp, #104
4091 ; CHECK-SD-DOT-NEXT:    ld1 { v1.b }[5], [x9]
4092 ; CHECK-SD-DOT-NEXT:    add x9, sp, #112
4093 ; CHECK-SD-DOT-NEXT:    mov v0.b[4], w4
4094 ; CHECK-SD-DOT-NEXT:    ld1 { v1.b }[6], [x9]
4095 ; CHECK-SD-DOT-NEXT:    add x9, sp, #120
4096 ; CHECK-SD-DOT-NEXT:    mov v0.b[5], w5
4097 ; CHECK-SD-DOT-NEXT:    ld1 { v1.b }[7], [x9]
4098 ; CHECK-SD-DOT-NEXT:    mov v0.b[6], w6
4099 ; CHECK-SD-DOT-NEXT:    udot v4.2s, v1.8b, v5.8b
4100 ; CHECK-SD-DOT-NEXT:    mov v0.b[7], w7
4101 ; CHECK-SD-DOT-NEXT:    addp v1.2s, v4.2s, v4.2s
4102 ; CHECK-SD-DOT-NEXT:    fmov w9, s1
4103 ; CHECK-SD-DOT-NEXT:    ld1 { v0.b }[8], [x8]
4104 ; CHECK-SD-DOT-NEXT:    add x8, sp, #8
4105 ; CHECK-SD-DOT-NEXT:    ld1 { v0.b }[9], [x8]
4106 ; CHECK-SD-DOT-NEXT:    add x8, sp, #16
4107 ; CHECK-SD-DOT-NEXT:    ld1 { v0.b }[10], [x8]
4108 ; CHECK-SD-DOT-NEXT:    add x8, sp, #24
4109 ; CHECK-SD-DOT-NEXT:    ld1 { v0.b }[11], [x8]
4110 ; CHECK-SD-DOT-NEXT:    add x8, sp, #32
4111 ; CHECK-SD-DOT-NEXT:    ld1 { v0.b }[12], [x8]
4112 ; CHECK-SD-DOT-NEXT:    add x8, sp, #40
4113 ; CHECK-SD-DOT-NEXT:    ld1 { v0.b }[13], [x8]
4114 ; CHECK-SD-DOT-NEXT:    add x8, sp, #48
4115 ; CHECK-SD-DOT-NEXT:    ld1 { v0.b }[14], [x8]
4116 ; CHECK-SD-DOT-NEXT:    add x8, sp, #56
4117 ; CHECK-SD-DOT-NEXT:    ld1 { v0.b }[15], [x8]
4118 ; CHECK-SD-DOT-NEXT:    udot v3.4s, v0.16b, v2.16b
4119 ; CHECK-SD-DOT-NEXT:    addv s0, v3.4s
4120 ; CHECK-SD-DOT-NEXT:    fmov w8, s0
4121 ; CHECK-SD-DOT-NEXT:    add w0, w8, w9
4122 ; CHECK-SD-DOT-NEXT:    ret
4124 ; CHECK-GI-BASE-LABEL: add_v24i8_v24i32_zext:
4125 ; CHECK-GI-BASE:       // %bb.0: // %entry
4126 ; CHECK-GI-BASE-NEXT:    fmov s0, w0
4127 ; CHECK-GI-BASE-NEXT:    ldr w8, [sp]
4128 ; CHECK-GI-BASE-NEXT:    ldr w9, [sp, #8]
4129 ; CHECK-GI-BASE-NEXT:    ldr w10, [sp, #72]
4130 ; CHECK-GI-BASE-NEXT:    mov v0.b[1], w1
4131 ; CHECK-GI-BASE-NEXT:    mov v0.b[2], w2
4132 ; CHECK-GI-BASE-NEXT:    mov v0.b[3], w3
4133 ; CHECK-GI-BASE-NEXT:    mov v0.b[4], w4
4134 ; CHECK-GI-BASE-NEXT:    mov v0.b[5], w5
4135 ; CHECK-GI-BASE-NEXT:    mov v0.b[6], w6
4136 ; CHECK-GI-BASE-NEXT:    mov v0.b[7], w7
4137 ; CHECK-GI-BASE-NEXT:    mov v0.b[8], w8
4138 ; CHECK-GI-BASE-NEXT:    ldr w8, [sp, #64]
4139 ; CHECK-GI-BASE-NEXT:    fmov s1, w8
4140 ; CHECK-GI-BASE-NEXT:    ldr w8, [sp, #16]
4141 ; CHECK-GI-BASE-NEXT:    mov v0.b[9], w9
4142 ; CHECK-GI-BASE-NEXT:    ldr w9, [sp, #80]
4143 ; CHECK-GI-BASE-NEXT:    mov v1.b[1], w10
4144 ; CHECK-GI-BASE-NEXT:    mov v0.b[10], w8
4145 ; CHECK-GI-BASE-NEXT:    ldr w8, [sp, #24]
4146 ; CHECK-GI-BASE-NEXT:    mov v1.b[2], w9
4147 ; CHECK-GI-BASE-NEXT:    ldr w9, [sp, #88]
4148 ; CHECK-GI-BASE-NEXT:    mov v0.b[11], w8
4149 ; CHECK-GI-BASE-NEXT:    ldr w8, [sp, #32]
4150 ; CHECK-GI-BASE-NEXT:    mov v1.b[3], w9
4151 ; CHECK-GI-BASE-NEXT:    ldr w9, [sp, #96]
4152 ; CHECK-GI-BASE-NEXT:    mov v0.b[12], w8
4153 ; CHECK-GI-BASE-NEXT:    ldr w8, [sp, #40]
4154 ; CHECK-GI-BASE-NEXT:    mov v1.b[4], w9
4155 ; CHECK-GI-BASE-NEXT:    ldr w9, [sp, #104]
4156 ; CHECK-GI-BASE-NEXT:    mov v0.b[13], w8
4157 ; CHECK-GI-BASE-NEXT:    ldr w8, [sp, #48]
4158 ; CHECK-GI-BASE-NEXT:    mov v1.b[5], w9
4159 ; CHECK-GI-BASE-NEXT:    ldr w9, [sp, #112]
4160 ; CHECK-GI-BASE-NEXT:    mov v0.b[14], w8
4161 ; CHECK-GI-BASE-NEXT:    ldr w8, [sp, #56]
4162 ; CHECK-GI-BASE-NEXT:    mov v1.b[6], w9
4163 ; CHECK-GI-BASE-NEXT:    ldr w9, [sp, #120]
4164 ; CHECK-GI-BASE-NEXT:    mov v0.b[15], w8
4165 ; CHECK-GI-BASE-NEXT:    mov v1.b[7], w9
4166 ; CHECK-GI-BASE-NEXT:    uaddlv h0, v0.16b
4167 ; CHECK-GI-BASE-NEXT:    uaddlv h1, v1.8b
4168 ; CHECK-GI-BASE-NEXT:    fmov w8, s0
4169 ; CHECK-GI-BASE-NEXT:    fmov w9, s1
4170 ; CHECK-GI-BASE-NEXT:    add w8, w8, w9
4171 ; CHECK-GI-BASE-NEXT:    and w0, w8, #0xffff
4172 ; CHECK-GI-BASE-NEXT:    ret
4174 ; CHECK-GI-DOT-LABEL: add_v24i8_v24i32_zext:
4175 ; CHECK-GI-DOT:       // %bb.0: // %entry
4176 ; CHECK-GI-DOT-NEXT:    fmov s0, w0
4177 ; CHECK-GI-DOT-NEXT:    ldr w9, [sp, #64]
4178 ; CHECK-GI-DOT-NEXT:    ldr w8, [sp]
4179 ; CHECK-GI-DOT-NEXT:    ldr w10, [sp, #72]
4180 ; CHECK-GI-DOT-NEXT:    movi v2.8b, #1
4181 ; CHECK-GI-DOT-NEXT:    movi v3.8b, #1
4182 ; CHECK-GI-DOT-NEXT:    fmov s1, w9
4183 ; CHECK-GI-DOT-NEXT:    ldr w9, [sp, #80]
4184 ; CHECK-GI-DOT-NEXT:    movi v4.2d, #0000000000000000
4185 ; CHECK-GI-DOT-NEXT:    mov v0.b[1], w1
4186 ; CHECK-GI-DOT-NEXT:    movi v5.2d, #0000000000000000
4187 ; CHECK-GI-DOT-NEXT:    mov v1.b[1], w10
4188 ; CHECK-GI-DOT-NEXT:    mov v3.d[1], v2.d[0]
4189 ; CHECK-GI-DOT-NEXT:    mov v0.b[2], w2
4190 ; CHECK-GI-DOT-NEXT:    mov v1.b[2], w9
4191 ; CHECK-GI-DOT-NEXT:    ldr w9, [sp, #88]
4192 ; CHECK-GI-DOT-NEXT:    mov v0.b[3], w3
4193 ; CHECK-GI-DOT-NEXT:    mov v1.b[3], w9
4194 ; CHECK-GI-DOT-NEXT:    ldr w9, [sp, #96]
4195 ; CHECK-GI-DOT-NEXT:    mov v0.b[4], w4
4196 ; CHECK-GI-DOT-NEXT:    mov v1.b[4], w9
4197 ; CHECK-GI-DOT-NEXT:    ldr w9, [sp, #104]
4198 ; CHECK-GI-DOT-NEXT:    mov v0.b[5], w5
4199 ; CHECK-GI-DOT-NEXT:    mov v1.b[5], w9
4200 ; CHECK-GI-DOT-NEXT:    ldr w9, [sp, #112]
4201 ; CHECK-GI-DOT-NEXT:    mov v0.b[6], w6
4202 ; CHECK-GI-DOT-NEXT:    mov v1.b[6], w9
4203 ; CHECK-GI-DOT-NEXT:    ldr w9, [sp, #120]
4204 ; CHECK-GI-DOT-NEXT:    mov v0.b[7], w7
4205 ; CHECK-GI-DOT-NEXT:    mov v1.b[7], w9
4206 ; CHECK-GI-DOT-NEXT:    mov v0.b[8], w8
4207 ; CHECK-GI-DOT-NEXT:    ldr w8, [sp, #8]
4208 ; CHECK-GI-DOT-NEXT:    fmov d1, d1
4209 ; CHECK-GI-DOT-NEXT:    mov v0.b[9], w8
4210 ; CHECK-GI-DOT-NEXT:    ldr w8, [sp, #16]
4211 ; CHECK-GI-DOT-NEXT:    udot v4.4s, v1.16b, v2.16b
4212 ; CHECK-GI-DOT-NEXT:    mov v0.b[10], w8
4213 ; CHECK-GI-DOT-NEXT:    ldr w8, [sp, #24]
4214 ; CHECK-GI-DOT-NEXT:    mov v0.b[11], w8
4215 ; CHECK-GI-DOT-NEXT:    ldr w8, [sp, #32]
4216 ; CHECK-GI-DOT-NEXT:    mov v0.b[12], w8
4217 ; CHECK-GI-DOT-NEXT:    ldr w8, [sp, #40]
4218 ; CHECK-GI-DOT-NEXT:    mov v0.b[13], w8
4219 ; CHECK-GI-DOT-NEXT:    ldr w8, [sp, #48]
4220 ; CHECK-GI-DOT-NEXT:    mov v0.b[14], w8
4221 ; CHECK-GI-DOT-NEXT:    ldr w8, [sp, #56]
4222 ; CHECK-GI-DOT-NEXT:    mov v0.b[15], w8
4223 ; CHECK-GI-DOT-NEXT:    udot v5.4s, v0.16b, v3.16b
4224 ; CHECK-GI-DOT-NEXT:    add v0.4s, v5.4s, v4.4s
4225 ; CHECK-GI-DOT-NEXT:    addv s0, v0.4s
4226 ; CHECK-GI-DOT-NEXT:    fmov w0, s0
4227 ; CHECK-GI-DOT-NEXT:    ret
4228 entry:
4229   %xx = zext <24 x i8> %x to <24 x i32>
4230   %z = call i32 @llvm.vector.reduce.add.v24i32(<24 x i32> %xx)
4231   ret i32 %z
4234 define i32 @add_v32i8_v32i32_zext(<32 x i8> %x) {
4235 ; CHECK-SD-BASE-LABEL: add_v32i8_v32i32_zext:
4236 ; CHECK-SD-BASE:       // %bb.0: // %entry
4237 ; CHECK-SD-BASE-NEXT:    ushll2 v2.8h, v1.16b, #0
4238 ; CHECK-SD-BASE-NEXT:    ushll2 v3.8h, v0.16b, #0
4239 ; CHECK-SD-BASE-NEXT:    ushll v1.8h, v1.8b, #0
4240 ; CHECK-SD-BASE-NEXT:    ushll v0.8h, v0.8b, #0
4241 ; CHECK-SD-BASE-NEXT:    uaddl2 v4.4s, v3.8h, v2.8h
4242 ; CHECK-SD-BASE-NEXT:    uaddl v2.4s, v3.4h, v2.4h
4243 ; CHECK-SD-BASE-NEXT:    uaddl2 v5.4s, v0.8h, v1.8h
4244 ; CHECK-SD-BASE-NEXT:    uaddl v0.4s, v0.4h, v1.4h
4245 ; CHECK-SD-BASE-NEXT:    add v1.4s, v5.4s, v4.4s
4246 ; CHECK-SD-BASE-NEXT:    add v0.4s, v0.4s, v2.4s
4247 ; CHECK-SD-BASE-NEXT:    add v0.4s, v0.4s, v1.4s
4248 ; CHECK-SD-BASE-NEXT:    addv s0, v0.4s
4249 ; CHECK-SD-BASE-NEXT:    fmov w0, s0
4250 ; CHECK-SD-BASE-NEXT:    ret
4252 ; CHECK-SD-DOT-LABEL: add_v32i8_v32i32_zext:
4253 ; CHECK-SD-DOT:       // %bb.0: // %entry
4254 ; CHECK-SD-DOT-NEXT:    movi v2.16b, #1
4255 ; CHECK-SD-DOT-NEXT:    movi v3.2d, #0000000000000000
4256 ; CHECK-SD-DOT-NEXT:    udot v3.4s, v1.16b, v2.16b
4257 ; CHECK-SD-DOT-NEXT:    udot v3.4s, v0.16b, v2.16b
4258 ; CHECK-SD-DOT-NEXT:    addv s0, v3.4s
4259 ; CHECK-SD-DOT-NEXT:    fmov w0, s0
4260 ; CHECK-SD-DOT-NEXT:    ret
4262 ; CHECK-GI-BASE-LABEL: add_v32i8_v32i32_zext:
4263 ; CHECK-GI-BASE:       // %bb.0: // %entry
4264 ; CHECK-GI-BASE-NEXT:    uaddlv h0, v0.16b
4265 ; CHECK-GI-BASE-NEXT:    uaddlv h1, v1.16b
4266 ; CHECK-GI-BASE-NEXT:    fmov w8, s0
4267 ; CHECK-GI-BASE-NEXT:    fmov w9, s1
4268 ; CHECK-GI-BASE-NEXT:    add w8, w8, w9
4269 ; CHECK-GI-BASE-NEXT:    and w0, w8, #0xffff
4270 ; CHECK-GI-BASE-NEXT:    ret
4272 ; CHECK-GI-DOT-LABEL: add_v32i8_v32i32_zext:
4273 ; CHECK-GI-DOT:       // %bb.0: // %entry
4274 ; CHECK-GI-DOT-NEXT:    movi v2.16b, #1
4275 ; CHECK-GI-DOT-NEXT:    movi v3.2d, #0000000000000000
4276 ; CHECK-GI-DOT-NEXT:    movi v4.2d, #0000000000000000
4277 ; CHECK-GI-DOT-NEXT:    udot v4.4s, v0.16b, v2.16b
4278 ; CHECK-GI-DOT-NEXT:    udot v3.4s, v1.16b, v2.16b
4279 ; CHECK-GI-DOT-NEXT:    add v0.4s, v4.4s, v3.4s
4280 ; CHECK-GI-DOT-NEXT:    addv s0, v0.4s
4281 ; CHECK-GI-DOT-NEXT:    fmov w0, s0
4282 ; CHECK-GI-DOT-NEXT:    ret
4283 entry:
4284   %xx = zext <32 x i8> %x to <32 x i32>
4285   %z = call i32 @llvm.vector.reduce.add.v32i32(<32 x i32> %xx)
4286   ret i32 %z
4289 define i32 @add_v24i8_v24i32_sext(<24 x i8> %x) {
4290 ; CHECK-SD-BASE-LABEL: add_v24i8_v24i32_sext:
4291 ; CHECK-SD-BASE:       // %bb.0: // %entry
4292 ; CHECK-SD-BASE-NEXT:    fmov s0, w0
4293 ; CHECK-SD-BASE-NEXT:    ldr b1, [sp, #64]
4294 ; CHECK-SD-BASE-NEXT:    add x8, sp, #72
4295 ; CHECK-SD-BASE-NEXT:    ldr b2, [sp]
4296 ; CHECK-SD-BASE-NEXT:    add x9, sp, #80
4297 ; CHECK-SD-BASE-NEXT:    ld1 { v1.b }[1], [x8]
4298 ; CHECK-SD-BASE-NEXT:    add x8, sp, #8
4299 ; CHECK-SD-BASE-NEXT:    mov v0.b[1], w1
4300 ; CHECK-SD-BASE-NEXT:    ld1 { v2.b }[1], [x8]
4301 ; CHECK-SD-BASE-NEXT:    add x8, sp, #16
4302 ; CHECK-SD-BASE-NEXT:    ld1 { v1.b }[2], [x9]
4303 ; CHECK-SD-BASE-NEXT:    add x9, sp, #88
4304 ; CHECK-SD-BASE-NEXT:    ld1 { v2.b }[2], [x8]
4305 ; CHECK-SD-BASE-NEXT:    add x8, sp, #24
4306 ; CHECK-SD-BASE-NEXT:    mov v0.b[2], w2
4307 ; CHECK-SD-BASE-NEXT:    ld1 { v1.b }[3], [x9]
4308 ; CHECK-SD-BASE-NEXT:    add x9, sp, #96
4309 ; CHECK-SD-BASE-NEXT:    ld1 { v2.b }[3], [x8]
4310 ; CHECK-SD-BASE-NEXT:    add x8, sp, #32
4311 ; CHECK-SD-BASE-NEXT:    mov v0.b[3], w3
4312 ; CHECK-SD-BASE-NEXT:    ld1 { v1.b }[4], [x9]
4313 ; CHECK-SD-BASE-NEXT:    add x9, sp, #104
4314 ; CHECK-SD-BASE-NEXT:    ld1 { v2.b }[4], [x8]
4315 ; CHECK-SD-BASE-NEXT:    add x8, sp, #40
4316 ; CHECK-SD-BASE-NEXT:    ld1 { v1.b }[5], [x9]
4317 ; CHECK-SD-BASE-NEXT:    add x9, sp, #112
4318 ; CHECK-SD-BASE-NEXT:    mov v0.b[4], w4
4319 ; CHECK-SD-BASE-NEXT:    ld1 { v2.b }[5], [x8]
4320 ; CHECK-SD-BASE-NEXT:    add x8, sp, #48
4321 ; CHECK-SD-BASE-NEXT:    ld1 { v1.b }[6], [x9]
4322 ; CHECK-SD-BASE-NEXT:    add x9, sp, #120
4323 ; CHECK-SD-BASE-NEXT:    ld1 { v2.b }[6], [x8]
4324 ; CHECK-SD-BASE-NEXT:    add x8, sp, #56
4325 ; CHECK-SD-BASE-NEXT:    mov v0.b[5], w5
4326 ; CHECK-SD-BASE-NEXT:    ld1 { v1.b }[7], [x9]
4327 ; CHECK-SD-BASE-NEXT:    ld1 { v2.b }[7], [x8]
4328 ; CHECK-SD-BASE-NEXT:    mov v0.b[6], w6
4329 ; CHECK-SD-BASE-NEXT:    sshll v1.8h, v1.8b, #0
4330 ; CHECK-SD-BASE-NEXT:    sshll v2.8h, v2.8b, #0
4331 ; CHECK-SD-BASE-NEXT:    mov v0.b[7], w7
4332 ; CHECK-SD-BASE-NEXT:    sshll v0.8h, v0.8b, #0
4333 ; CHECK-SD-BASE-NEXT:    saddl2 v3.4s, v0.8h, v1.8h
4334 ; CHECK-SD-BASE-NEXT:    saddl v0.4s, v0.4h, v1.4h
4335 ; CHECK-SD-BASE-NEXT:    saddw2 v1.4s, v3.4s, v2.8h
4336 ; CHECK-SD-BASE-NEXT:    saddw v0.4s, v0.4s, v2.4h
4337 ; CHECK-SD-BASE-NEXT:    add v0.4s, v0.4s, v1.4s
4338 ; CHECK-SD-BASE-NEXT:    addv s0, v0.4s
4339 ; CHECK-SD-BASE-NEXT:    fmov w0, s0
4340 ; CHECK-SD-BASE-NEXT:    ret
4342 ; CHECK-SD-DOT-LABEL: add_v24i8_v24i32_sext:
4343 ; CHECK-SD-DOT:       // %bb.0: // %entry
4344 ; CHECK-SD-DOT-NEXT:    fmov s0, w0
4345 ; CHECK-SD-DOT-NEXT:    mov x8, sp
4346 ; CHECK-SD-DOT-NEXT:    ldr b1, [sp, #64]
4347 ; CHECK-SD-DOT-NEXT:    add x9, sp, #72
4348 ; CHECK-SD-DOT-NEXT:    movi v2.16b, #1
4349 ; CHECK-SD-DOT-NEXT:    movi v3.2d, #0000000000000000
4350 ; CHECK-SD-DOT-NEXT:    ld1 { v1.b }[1], [x9]
4351 ; CHECK-SD-DOT-NEXT:    add x9, sp, #80
4352 ; CHECK-SD-DOT-NEXT:    movi v4.2d, #0000000000000000
4353 ; CHECK-SD-DOT-NEXT:    mov v0.b[1], w1
4354 ; CHECK-SD-DOT-NEXT:    movi v5.8b, #1
4355 ; CHECK-SD-DOT-NEXT:    ld1 { v1.b }[2], [x9]
4356 ; CHECK-SD-DOT-NEXT:    add x9, sp, #88
4357 ; CHECK-SD-DOT-NEXT:    mov v0.b[2], w2
4358 ; CHECK-SD-DOT-NEXT:    ld1 { v1.b }[3], [x9]
4359 ; CHECK-SD-DOT-NEXT:    add x9, sp, #96
4360 ; CHECK-SD-DOT-NEXT:    mov v0.b[3], w3
4361 ; CHECK-SD-DOT-NEXT:    ld1 { v1.b }[4], [x9]
4362 ; CHECK-SD-DOT-NEXT:    add x9, sp, #104
4363 ; CHECK-SD-DOT-NEXT:    ld1 { v1.b }[5], [x9]
4364 ; CHECK-SD-DOT-NEXT:    add x9, sp, #112
4365 ; CHECK-SD-DOT-NEXT:    mov v0.b[4], w4
4366 ; CHECK-SD-DOT-NEXT:    ld1 { v1.b }[6], [x9]
4367 ; CHECK-SD-DOT-NEXT:    add x9, sp, #120
4368 ; CHECK-SD-DOT-NEXT:    mov v0.b[5], w5
4369 ; CHECK-SD-DOT-NEXT:    ld1 { v1.b }[7], [x9]
4370 ; CHECK-SD-DOT-NEXT:    mov v0.b[6], w6
4371 ; CHECK-SD-DOT-NEXT:    sdot v4.2s, v1.8b, v5.8b
4372 ; CHECK-SD-DOT-NEXT:    mov v0.b[7], w7
4373 ; CHECK-SD-DOT-NEXT:    addp v1.2s, v4.2s, v4.2s
4374 ; CHECK-SD-DOT-NEXT:    fmov w9, s1
4375 ; CHECK-SD-DOT-NEXT:    ld1 { v0.b }[8], [x8]
4376 ; CHECK-SD-DOT-NEXT:    add x8, sp, #8
4377 ; CHECK-SD-DOT-NEXT:    ld1 { v0.b }[9], [x8]
4378 ; CHECK-SD-DOT-NEXT:    add x8, sp, #16
4379 ; CHECK-SD-DOT-NEXT:    ld1 { v0.b }[10], [x8]
4380 ; CHECK-SD-DOT-NEXT:    add x8, sp, #24
4381 ; CHECK-SD-DOT-NEXT:    ld1 { v0.b }[11], [x8]
4382 ; CHECK-SD-DOT-NEXT:    add x8, sp, #32
4383 ; CHECK-SD-DOT-NEXT:    ld1 { v0.b }[12], [x8]
4384 ; CHECK-SD-DOT-NEXT:    add x8, sp, #40
4385 ; CHECK-SD-DOT-NEXT:    ld1 { v0.b }[13], [x8]
4386 ; CHECK-SD-DOT-NEXT:    add x8, sp, #48
4387 ; CHECK-SD-DOT-NEXT:    ld1 { v0.b }[14], [x8]
4388 ; CHECK-SD-DOT-NEXT:    add x8, sp, #56
4389 ; CHECK-SD-DOT-NEXT:    ld1 { v0.b }[15], [x8]
4390 ; CHECK-SD-DOT-NEXT:    sdot v3.4s, v0.16b, v2.16b
4391 ; CHECK-SD-DOT-NEXT:    addv s0, v3.4s
4392 ; CHECK-SD-DOT-NEXT:    fmov w8, s0
4393 ; CHECK-SD-DOT-NEXT:    add w0, w8, w9
4394 ; CHECK-SD-DOT-NEXT:    ret
4396 ; CHECK-GI-BASE-LABEL: add_v24i8_v24i32_sext:
4397 ; CHECK-GI-BASE:       // %bb.0: // %entry
4398 ; CHECK-GI-BASE-NEXT:    fmov s0, w0
4399 ; CHECK-GI-BASE-NEXT:    ldr w8, [sp]
4400 ; CHECK-GI-BASE-NEXT:    ldr w9, [sp, #8]
4401 ; CHECK-GI-BASE-NEXT:    ldr w10, [sp, #72]
4402 ; CHECK-GI-BASE-NEXT:    mov v0.b[1], w1
4403 ; CHECK-GI-BASE-NEXT:    mov v0.b[2], w2
4404 ; CHECK-GI-BASE-NEXT:    mov v0.b[3], w3
4405 ; CHECK-GI-BASE-NEXT:    mov v0.b[4], w4
4406 ; CHECK-GI-BASE-NEXT:    mov v0.b[5], w5
4407 ; CHECK-GI-BASE-NEXT:    mov v0.b[6], w6
4408 ; CHECK-GI-BASE-NEXT:    mov v0.b[7], w7
4409 ; CHECK-GI-BASE-NEXT:    mov v0.b[8], w8
4410 ; CHECK-GI-BASE-NEXT:    ldr w8, [sp, #64]
4411 ; CHECK-GI-BASE-NEXT:    fmov s1, w8
4412 ; CHECK-GI-BASE-NEXT:    ldr w8, [sp, #16]
4413 ; CHECK-GI-BASE-NEXT:    mov v0.b[9], w9
4414 ; CHECK-GI-BASE-NEXT:    ldr w9, [sp, #80]
4415 ; CHECK-GI-BASE-NEXT:    mov v1.b[1], w10
4416 ; CHECK-GI-BASE-NEXT:    mov v0.b[10], w8
4417 ; CHECK-GI-BASE-NEXT:    ldr w8, [sp, #24]
4418 ; CHECK-GI-BASE-NEXT:    mov v1.b[2], w9
4419 ; CHECK-GI-BASE-NEXT:    ldr w9, [sp, #88]
4420 ; CHECK-GI-BASE-NEXT:    mov v0.b[11], w8
4421 ; CHECK-GI-BASE-NEXT:    ldr w8, [sp, #32]
4422 ; CHECK-GI-BASE-NEXT:    mov v1.b[3], w9
4423 ; CHECK-GI-BASE-NEXT:    ldr w9, [sp, #96]
4424 ; CHECK-GI-BASE-NEXT:    mov v0.b[12], w8
4425 ; CHECK-GI-BASE-NEXT:    ldr w8, [sp, #40]
4426 ; CHECK-GI-BASE-NEXT:    mov v1.b[4], w9
4427 ; CHECK-GI-BASE-NEXT:    ldr w9, [sp, #104]
4428 ; CHECK-GI-BASE-NEXT:    mov v0.b[13], w8
4429 ; CHECK-GI-BASE-NEXT:    ldr w8, [sp, #48]
4430 ; CHECK-GI-BASE-NEXT:    mov v1.b[5], w9
4431 ; CHECK-GI-BASE-NEXT:    ldr w9, [sp, #112]
4432 ; CHECK-GI-BASE-NEXT:    mov v0.b[14], w8
4433 ; CHECK-GI-BASE-NEXT:    ldr w8, [sp, #56]
4434 ; CHECK-GI-BASE-NEXT:    mov v1.b[6], w9
4435 ; CHECK-GI-BASE-NEXT:    ldr w9, [sp, #120]
4436 ; CHECK-GI-BASE-NEXT:    mov v0.b[15], w8
4437 ; CHECK-GI-BASE-NEXT:    mov v1.b[7], w9
4438 ; CHECK-GI-BASE-NEXT:    saddlv h0, v0.16b
4439 ; CHECK-GI-BASE-NEXT:    saddlv h1, v1.8b
4440 ; CHECK-GI-BASE-NEXT:    fmov w8, s0
4441 ; CHECK-GI-BASE-NEXT:    fmov w9, s1
4442 ; CHECK-GI-BASE-NEXT:    add w8, w8, w9
4443 ; CHECK-GI-BASE-NEXT:    sxth w0, w8
4444 ; CHECK-GI-BASE-NEXT:    ret
4446 ; CHECK-GI-DOT-LABEL: add_v24i8_v24i32_sext:
4447 ; CHECK-GI-DOT:       // %bb.0: // %entry
4448 ; CHECK-GI-DOT-NEXT:    fmov s0, w0
4449 ; CHECK-GI-DOT-NEXT:    ldr w9, [sp, #64]
4450 ; CHECK-GI-DOT-NEXT:    ldr w8, [sp]
4451 ; CHECK-GI-DOT-NEXT:    ldr w10, [sp, #72]
4452 ; CHECK-GI-DOT-NEXT:    movi v2.8b, #1
4453 ; CHECK-GI-DOT-NEXT:    movi v3.8b, #1
4454 ; CHECK-GI-DOT-NEXT:    fmov s1, w9
4455 ; CHECK-GI-DOT-NEXT:    ldr w9, [sp, #80]
4456 ; CHECK-GI-DOT-NEXT:    movi v4.2d, #0000000000000000
4457 ; CHECK-GI-DOT-NEXT:    mov v0.b[1], w1
4458 ; CHECK-GI-DOT-NEXT:    movi v5.2d, #0000000000000000
4459 ; CHECK-GI-DOT-NEXT:    mov v1.b[1], w10
4460 ; CHECK-GI-DOT-NEXT:    mov v3.d[1], v2.d[0]
4461 ; CHECK-GI-DOT-NEXT:    mov v0.b[2], w2
4462 ; CHECK-GI-DOT-NEXT:    mov v1.b[2], w9
4463 ; CHECK-GI-DOT-NEXT:    ldr w9, [sp, #88]
4464 ; CHECK-GI-DOT-NEXT:    mov v0.b[3], w3
4465 ; CHECK-GI-DOT-NEXT:    mov v1.b[3], w9
4466 ; CHECK-GI-DOT-NEXT:    ldr w9, [sp, #96]
4467 ; CHECK-GI-DOT-NEXT:    mov v0.b[4], w4
4468 ; CHECK-GI-DOT-NEXT:    mov v1.b[4], w9
4469 ; CHECK-GI-DOT-NEXT:    ldr w9, [sp, #104]
4470 ; CHECK-GI-DOT-NEXT:    mov v0.b[5], w5
4471 ; CHECK-GI-DOT-NEXT:    mov v1.b[5], w9
4472 ; CHECK-GI-DOT-NEXT:    ldr w9, [sp, #112]
4473 ; CHECK-GI-DOT-NEXT:    mov v0.b[6], w6
4474 ; CHECK-GI-DOT-NEXT:    mov v1.b[6], w9
4475 ; CHECK-GI-DOT-NEXT:    ldr w9, [sp, #120]
4476 ; CHECK-GI-DOT-NEXT:    mov v0.b[7], w7
4477 ; CHECK-GI-DOT-NEXT:    mov v1.b[7], w9
4478 ; CHECK-GI-DOT-NEXT:    mov v0.b[8], w8
4479 ; CHECK-GI-DOT-NEXT:    ldr w8, [sp, #8]
4480 ; CHECK-GI-DOT-NEXT:    fmov d1, d1
4481 ; CHECK-GI-DOT-NEXT:    mov v0.b[9], w8
4482 ; CHECK-GI-DOT-NEXT:    ldr w8, [sp, #16]
4483 ; CHECK-GI-DOT-NEXT:    sdot v4.4s, v1.16b, v2.16b
4484 ; CHECK-GI-DOT-NEXT:    mov v0.b[10], w8
4485 ; CHECK-GI-DOT-NEXT:    ldr w8, [sp, #24]
4486 ; CHECK-GI-DOT-NEXT:    mov v0.b[11], w8
4487 ; CHECK-GI-DOT-NEXT:    ldr w8, [sp, #32]
4488 ; CHECK-GI-DOT-NEXT:    mov v0.b[12], w8
4489 ; CHECK-GI-DOT-NEXT:    ldr w8, [sp, #40]
4490 ; CHECK-GI-DOT-NEXT:    mov v0.b[13], w8
4491 ; CHECK-GI-DOT-NEXT:    ldr w8, [sp, #48]
4492 ; CHECK-GI-DOT-NEXT:    mov v0.b[14], w8
4493 ; CHECK-GI-DOT-NEXT:    ldr w8, [sp, #56]
4494 ; CHECK-GI-DOT-NEXT:    mov v0.b[15], w8
4495 ; CHECK-GI-DOT-NEXT:    sdot v5.4s, v0.16b, v3.16b
4496 ; CHECK-GI-DOT-NEXT:    add v0.4s, v5.4s, v4.4s
4497 ; CHECK-GI-DOT-NEXT:    addv s0, v0.4s
4498 ; CHECK-GI-DOT-NEXT:    fmov w0, s0
4499 ; CHECK-GI-DOT-NEXT:    ret
4500 entry:
4501   %xx = sext <24 x i8> %x to <24 x i32>
4502   %z = call i32 @llvm.vector.reduce.add.v24i32(<24 x i32> %xx)
4503   ret i32 %z
4506 define i32 @add_v32i8_v32i32_sext(<32 x i8> %x) {
4507 ; CHECK-SD-BASE-LABEL: add_v32i8_v32i32_sext:
4508 ; CHECK-SD-BASE:       // %bb.0: // %entry
4509 ; CHECK-SD-BASE-NEXT:    sshll2 v2.8h, v1.16b, #0
4510 ; CHECK-SD-BASE-NEXT:    sshll2 v3.8h, v0.16b, #0
4511 ; CHECK-SD-BASE-NEXT:    sshll v1.8h, v1.8b, #0
4512 ; CHECK-SD-BASE-NEXT:    sshll v0.8h, v0.8b, #0
4513 ; CHECK-SD-BASE-NEXT:    saddl2 v4.4s, v3.8h, v2.8h
4514 ; CHECK-SD-BASE-NEXT:    saddl v2.4s, v3.4h, v2.4h
4515 ; CHECK-SD-BASE-NEXT:    saddl2 v5.4s, v0.8h, v1.8h
4516 ; CHECK-SD-BASE-NEXT:    saddl v0.4s, v0.4h, v1.4h
4517 ; CHECK-SD-BASE-NEXT:    add v1.4s, v5.4s, v4.4s
4518 ; CHECK-SD-BASE-NEXT:    add v0.4s, v0.4s, v2.4s
4519 ; CHECK-SD-BASE-NEXT:    add v0.4s, v0.4s, v1.4s
4520 ; CHECK-SD-BASE-NEXT:    addv s0, v0.4s
4521 ; CHECK-SD-BASE-NEXT:    fmov w0, s0
4522 ; CHECK-SD-BASE-NEXT:    ret
4524 ; CHECK-SD-DOT-LABEL: add_v32i8_v32i32_sext:
4525 ; CHECK-SD-DOT:       // %bb.0: // %entry
4526 ; CHECK-SD-DOT-NEXT:    movi v2.16b, #1
4527 ; CHECK-SD-DOT-NEXT:    movi v3.2d, #0000000000000000
4528 ; CHECK-SD-DOT-NEXT:    sdot v3.4s, v1.16b, v2.16b
4529 ; CHECK-SD-DOT-NEXT:    sdot v3.4s, v0.16b, v2.16b
4530 ; CHECK-SD-DOT-NEXT:    addv s0, v3.4s
4531 ; CHECK-SD-DOT-NEXT:    fmov w0, s0
4532 ; CHECK-SD-DOT-NEXT:    ret
4534 ; CHECK-GI-BASE-LABEL: add_v32i8_v32i32_sext:
4535 ; CHECK-GI-BASE:       // %bb.0: // %entry
4536 ; CHECK-GI-BASE-NEXT:    saddlv h0, v0.16b
4537 ; CHECK-GI-BASE-NEXT:    saddlv h1, v1.16b
4538 ; CHECK-GI-BASE-NEXT:    fmov w8, s0
4539 ; CHECK-GI-BASE-NEXT:    fmov w9, s1
4540 ; CHECK-GI-BASE-NEXT:    add w8, w8, w9
4541 ; CHECK-GI-BASE-NEXT:    sxth w0, w8
4542 ; CHECK-GI-BASE-NEXT:    ret
4544 ; CHECK-GI-DOT-LABEL: add_v32i8_v32i32_sext:
4545 ; CHECK-GI-DOT:       // %bb.0: // %entry
4546 ; CHECK-GI-DOT-NEXT:    movi v2.16b, #1
4547 ; CHECK-GI-DOT-NEXT:    movi v3.2d, #0000000000000000
4548 ; CHECK-GI-DOT-NEXT:    movi v4.2d, #0000000000000000
4549 ; CHECK-GI-DOT-NEXT:    sdot v4.4s, v0.16b, v2.16b
4550 ; CHECK-GI-DOT-NEXT:    sdot v3.4s, v1.16b, v2.16b
4551 ; CHECK-GI-DOT-NEXT:    add v0.4s, v4.4s, v3.4s
4552 ; CHECK-GI-DOT-NEXT:    addv s0, v0.4s
4553 ; CHECK-GI-DOT-NEXT:    fmov w0, s0
4554 ; CHECK-GI-DOT-NEXT:    ret
4555 entry:
4556   %xx = sext <32 x i8> %x to <32 x i32>
4557   %z = call i32 @llvm.vector.reduce.add.v32i32(<32 x i32> %xx)
4558   ret i32 %z
4561 define i32 @full(ptr %p1, i32 noundef %s1, ptr %p2, i32 noundef %s2) {
4562 ; CHECK-SD-BASE-LABEL: full:
4563 ; CHECK-SD-BASE:       // %bb.0: // %entry
4564 ; CHECK-SD-BASE-NEXT:    // kill: def $w3 killed $w3 def $x3
4565 ; CHECK-SD-BASE-NEXT:    // kill: def $w1 killed $w1 def $x1
4566 ; CHECK-SD-BASE-NEXT:    sxtw x8, w3
4567 ; CHECK-SD-BASE-NEXT:    sxtw x9, w1
4568 ; CHECK-SD-BASE-NEXT:    ldr d0, [x0]
4569 ; CHECK-SD-BASE-NEXT:    ldr d1, [x2]
4570 ; CHECK-SD-BASE-NEXT:    add x10, x0, x9
4571 ; CHECK-SD-BASE-NEXT:    add x11, x2, x8
4572 ; CHECK-SD-BASE-NEXT:    uabdl v0.8h, v0.8b, v1.8b
4573 ; CHECK-SD-BASE-NEXT:    ldr d1, [x10]
4574 ; CHECK-SD-BASE-NEXT:    ldr d2, [x11]
4575 ; CHECK-SD-BASE-NEXT:    add x10, x10, x9
4576 ; CHECK-SD-BASE-NEXT:    add x11, x11, x8
4577 ; CHECK-SD-BASE-NEXT:    uabdl v1.8h, v1.8b, v2.8b
4578 ; CHECK-SD-BASE-NEXT:    ldr d2, [x11]
4579 ; CHECK-SD-BASE-NEXT:    add x11, x11, x8
4580 ; CHECK-SD-BASE-NEXT:    uaddlp v0.4s, v0.8h
4581 ; CHECK-SD-BASE-NEXT:    uadalp v0.4s, v1.8h
4582 ; CHECK-SD-BASE-NEXT:    ldr d1, [x10]
4583 ; CHECK-SD-BASE-NEXT:    add x10, x10, x9
4584 ; CHECK-SD-BASE-NEXT:    uabdl v1.8h, v1.8b, v2.8b
4585 ; CHECK-SD-BASE-NEXT:    ldr d2, [x11]
4586 ; CHECK-SD-BASE-NEXT:    add x11, x11, x8
4587 ; CHECK-SD-BASE-NEXT:    uadalp v0.4s, v1.8h
4588 ; CHECK-SD-BASE-NEXT:    ldr d1, [x10]
4589 ; CHECK-SD-BASE-NEXT:    add x10, x10, x9
4590 ; CHECK-SD-BASE-NEXT:    uabdl v1.8h, v1.8b, v2.8b
4591 ; CHECK-SD-BASE-NEXT:    ldr d2, [x11]
4592 ; CHECK-SD-BASE-NEXT:    add x11, x11, x8
4593 ; CHECK-SD-BASE-NEXT:    uadalp v0.4s, v1.8h
4594 ; CHECK-SD-BASE-NEXT:    ldr d1, [x10]
4595 ; CHECK-SD-BASE-NEXT:    add x10, x10, x9
4596 ; CHECK-SD-BASE-NEXT:    uabdl v1.8h, v1.8b, v2.8b
4597 ; CHECK-SD-BASE-NEXT:    ldr d2, [x11]
4598 ; CHECK-SD-BASE-NEXT:    add x11, x11, x8
4599 ; CHECK-SD-BASE-NEXT:    uadalp v0.4s, v1.8h
4600 ; CHECK-SD-BASE-NEXT:    ldr d1, [x10]
4601 ; CHECK-SD-BASE-NEXT:    add x10, x10, x9
4602 ; CHECK-SD-BASE-NEXT:    uabdl v1.8h, v1.8b, v2.8b
4603 ; CHECK-SD-BASE-NEXT:    ldr d2, [x11]
4604 ; CHECK-SD-BASE-NEXT:    uadalp v0.4s, v1.8h
4605 ; CHECK-SD-BASE-NEXT:    ldr d1, [x10]
4606 ; CHECK-SD-BASE-NEXT:    uabdl v1.8h, v1.8b, v2.8b
4607 ; CHECK-SD-BASE-NEXT:    ldr d2, [x11, x8]
4608 ; CHECK-SD-BASE-NEXT:    uadalp v0.4s, v1.8h
4609 ; CHECK-SD-BASE-NEXT:    ldr d1, [x10, x9]
4610 ; CHECK-SD-BASE-NEXT:    uabdl v1.8h, v1.8b, v2.8b
4611 ; CHECK-SD-BASE-NEXT:    uadalp v0.4s, v1.8h
4612 ; CHECK-SD-BASE-NEXT:    addv s0, v0.4s
4613 ; CHECK-SD-BASE-NEXT:    fmov w0, s0
4614 ; CHECK-SD-BASE-NEXT:    ret
4616 ; CHECK-SD-DOT-LABEL: full:
4617 ; CHECK-SD-DOT:       // %bb.0: // %entry
4618 ; CHECK-SD-DOT-NEXT:    ldr d0, [x0]
4619 ; CHECK-SD-DOT-NEXT:    ldr d1, [x2]
4620 ; CHECK-SD-DOT-NEXT:    // kill: def $w3 killed $w3 def $x3
4621 ; CHECK-SD-DOT-NEXT:    // kill: def $w1 killed $w1 def $x1
4622 ; CHECK-SD-DOT-NEXT:    sxtw x8, w3
4623 ; CHECK-SD-DOT-NEXT:    sxtw x9, w1
4624 ; CHECK-SD-DOT-NEXT:    movi v2.2d, #0000000000000000
4625 ; CHECK-SD-DOT-NEXT:    movi v3.8b, #1
4626 ; CHECK-SD-DOT-NEXT:    uabd v0.8b, v0.8b, v1.8b
4627 ; CHECK-SD-DOT-NEXT:    add x11, x2, x8
4628 ; CHECK-SD-DOT-NEXT:    add x10, x0, x9
4629 ; CHECK-SD-DOT-NEXT:    ldr d4, [x11]
4630 ; CHECK-SD-DOT-NEXT:    add x11, x11, x8
4631 ; CHECK-SD-DOT-NEXT:    ldr d1, [x10]
4632 ; CHECK-SD-DOT-NEXT:    add x10, x10, x9
4633 ; CHECK-SD-DOT-NEXT:    udot v2.2s, v0.8b, v3.8b
4634 ; CHECK-SD-DOT-NEXT:    uabd v0.8b, v1.8b, v4.8b
4635 ; CHECK-SD-DOT-NEXT:    ldr d1, [x10]
4636 ; CHECK-SD-DOT-NEXT:    ldr d4, [x11]
4637 ; CHECK-SD-DOT-NEXT:    add x10, x10, x9
4638 ; CHECK-SD-DOT-NEXT:    add x11, x11, x8
4639 ; CHECK-SD-DOT-NEXT:    udot v2.2s, v0.8b, v3.8b
4640 ; CHECK-SD-DOT-NEXT:    uabd v0.8b, v1.8b, v4.8b
4641 ; CHECK-SD-DOT-NEXT:    ldr d1, [x10]
4642 ; CHECK-SD-DOT-NEXT:    ldr d4, [x11]
4643 ; CHECK-SD-DOT-NEXT:    add x10, x10, x9
4644 ; CHECK-SD-DOT-NEXT:    add x11, x11, x8
4645 ; CHECK-SD-DOT-NEXT:    udot v2.2s, v0.8b, v3.8b
4646 ; CHECK-SD-DOT-NEXT:    uabd v0.8b, v1.8b, v4.8b
4647 ; CHECK-SD-DOT-NEXT:    ldr d1, [x10]
4648 ; CHECK-SD-DOT-NEXT:    ldr d4, [x11]
4649 ; CHECK-SD-DOT-NEXT:    add x10, x10, x9
4650 ; CHECK-SD-DOT-NEXT:    add x11, x11, x8
4651 ; CHECK-SD-DOT-NEXT:    udot v2.2s, v0.8b, v3.8b
4652 ; CHECK-SD-DOT-NEXT:    uabd v0.8b, v1.8b, v4.8b
4653 ; CHECK-SD-DOT-NEXT:    ldr d1, [x10]
4654 ; CHECK-SD-DOT-NEXT:    ldr d4, [x11]
4655 ; CHECK-SD-DOT-NEXT:    add x10, x10, x9
4656 ; CHECK-SD-DOT-NEXT:    add x11, x11, x8
4657 ; CHECK-SD-DOT-NEXT:    udot v2.2s, v0.8b, v3.8b
4658 ; CHECK-SD-DOT-NEXT:    uabd v0.8b, v1.8b, v4.8b
4659 ; CHECK-SD-DOT-NEXT:    ldr d1, [x10]
4660 ; CHECK-SD-DOT-NEXT:    ldr d4, [x11]
4661 ; CHECK-SD-DOT-NEXT:    udot v2.2s, v0.8b, v3.8b
4662 ; CHECK-SD-DOT-NEXT:    uabd v0.8b, v1.8b, v4.8b
4663 ; CHECK-SD-DOT-NEXT:    ldr d1, [x10, x9]
4664 ; CHECK-SD-DOT-NEXT:    ldr d4, [x11, x8]
4665 ; CHECK-SD-DOT-NEXT:    udot v2.2s, v0.8b, v3.8b
4666 ; CHECK-SD-DOT-NEXT:    uabd v0.8b, v1.8b, v4.8b
4667 ; CHECK-SD-DOT-NEXT:    udot v2.2s, v0.8b, v3.8b
4668 ; CHECK-SD-DOT-NEXT:    addp v0.2s, v2.2s, v2.2s
4669 ; CHECK-SD-DOT-NEXT:    fmov w0, s0
4670 ; CHECK-SD-DOT-NEXT:    ret
4672 ; CHECK-GI-LABEL: full:
4673 ; CHECK-GI:       // %bb.0: // %entry
4674 ; CHECK-GI-NEXT:    // kill: def $w1 killed $w1 def $x1
4675 ; CHECK-GI-NEXT:    // kill: def $w3 killed $w3 def $x3
4676 ; CHECK-GI-NEXT:    sxtw x9, w1
4677 ; CHECK-GI-NEXT:    sxtw x8, w3
4678 ; CHECK-GI-NEXT:    ldr d0, [x0]
4679 ; CHECK-GI-NEXT:    ldr d1, [x2]
4680 ; CHECK-GI-NEXT:    add x10, x0, x9
4681 ; CHECK-GI-NEXT:    add x11, x2, x8
4682 ; CHECK-GI-NEXT:    usubl v0.8h, v0.8b, v1.8b
4683 ; CHECK-GI-NEXT:    ldr d1, [x10]
4684 ; CHECK-GI-NEXT:    ldr d2, [x11]
4685 ; CHECK-GI-NEXT:    add x10, x10, x9
4686 ; CHECK-GI-NEXT:    add x11, x11, x8
4687 ; CHECK-GI-NEXT:    usubl v1.8h, v1.8b, v2.8b
4688 ; CHECK-GI-NEXT:    ldr d3, [x10]
4689 ; CHECK-GI-NEXT:    ldr d4, [x11]
4690 ; CHECK-GI-NEXT:    sshll v5.4s, v0.4h, #0
4691 ; CHECK-GI-NEXT:    sshll2 v0.4s, v0.8h, #0
4692 ; CHECK-GI-NEXT:    add x10, x10, x9
4693 ; CHECK-GI-NEXT:    add x11, x11, x8
4694 ; CHECK-GI-NEXT:    ldr d2, [x10]
4695 ; CHECK-GI-NEXT:    add x10, x10, x9
4696 ; CHECK-GI-NEXT:    sshll v7.4s, v1.4h, #0
4697 ; CHECK-GI-NEXT:    sshll2 v1.4s, v1.8h, #0
4698 ; CHECK-GI-NEXT:    ldr d6, [x11]
4699 ; CHECK-GI-NEXT:    add x11, x11, x8
4700 ; CHECK-GI-NEXT:    usubl v3.8h, v3.8b, v4.8b
4701 ; CHECK-GI-NEXT:    abs v5.4s, v5.4s
4702 ; CHECK-GI-NEXT:    abs v0.4s, v0.4s
4703 ; CHECK-GI-NEXT:    ldr d4, [x10]
4704 ; CHECK-GI-NEXT:    ldr d16, [x11]
4705 ; CHECK-GI-NEXT:    abs v7.4s, v7.4s
4706 ; CHECK-GI-NEXT:    abs v1.4s, v1.4s
4707 ; CHECK-GI-NEXT:    add x10, x10, x9
4708 ; CHECK-GI-NEXT:    add x11, x11, x8
4709 ; CHECK-GI-NEXT:    usubl v2.8h, v2.8b, v6.8b
4710 ; CHECK-GI-NEXT:    ldr d6, [x10]
4711 ; CHECK-GI-NEXT:    ldr d17, [x11]
4712 ; CHECK-GI-NEXT:    add x10, x10, x9
4713 ; CHECK-GI-NEXT:    add x11, x11, x8
4714 ; CHECK-GI-NEXT:    usubl v4.8h, v4.8b, v16.8b
4715 ; CHECK-GI-NEXT:    sshll v16.4s, v3.4h, #0
4716 ; CHECK-GI-NEXT:    sshll2 v3.4s, v3.8h, #0
4717 ; CHECK-GI-NEXT:    add v0.4s, v5.4s, v0.4s
4718 ; CHECK-GI-NEXT:    add v1.4s, v7.4s, v1.4s
4719 ; CHECK-GI-NEXT:    ldr d5, [x10]
4720 ; CHECK-GI-NEXT:    ldr d7, [x11]
4721 ; CHECK-GI-NEXT:    sshll v18.4s, v2.4h, #0
4722 ; CHECK-GI-NEXT:    sshll2 v2.4s, v2.8h, #0
4723 ; CHECK-GI-NEXT:    usubl v6.8h, v6.8b, v17.8b
4724 ; CHECK-GI-NEXT:    ldr d17, [x11, x8]
4725 ; CHECK-GI-NEXT:    sshll v19.4s, v4.4h, #0
4726 ; CHECK-GI-NEXT:    usubl v5.8h, v5.8b, v7.8b
4727 ; CHECK-GI-NEXT:    ldr d7, [x10, x9]
4728 ; CHECK-GI-NEXT:    sshll2 v4.4s, v4.8h, #0
4729 ; CHECK-GI-NEXT:    abs v16.4s, v16.4s
4730 ; CHECK-GI-NEXT:    abs v3.4s, v3.4s
4731 ; CHECK-GI-NEXT:    abs v18.4s, v18.4s
4732 ; CHECK-GI-NEXT:    abs v2.4s, v2.4s
4733 ; CHECK-GI-NEXT:    usubl v7.8h, v7.8b, v17.8b
4734 ; CHECK-GI-NEXT:    sshll v17.4s, v6.4h, #0
4735 ; CHECK-GI-NEXT:    sshll2 v6.4s, v6.8h, #0
4736 ; CHECK-GI-NEXT:    abs v19.4s, v19.4s
4737 ; CHECK-GI-NEXT:    abs v4.4s, v4.4s
4738 ; CHECK-GI-NEXT:    add v3.4s, v16.4s, v3.4s
4739 ; CHECK-GI-NEXT:    sshll v16.4s, v5.4h, #0
4740 ; CHECK-GI-NEXT:    sshll2 v5.4s, v5.8h, #0
4741 ; CHECK-GI-NEXT:    add v2.4s, v18.4s, v2.4s
4742 ; CHECK-GI-NEXT:    abs v17.4s, v17.4s
4743 ; CHECK-GI-NEXT:    addv s1, v1.4s
4744 ; CHECK-GI-NEXT:    abs v6.4s, v6.4s
4745 ; CHECK-GI-NEXT:    addv s0, v0.4s
4746 ; CHECK-GI-NEXT:    add v4.4s, v19.4s, v4.4s
4747 ; CHECK-GI-NEXT:    addv s3, v3.4s
4748 ; CHECK-GI-NEXT:    sshll v18.4s, v7.4h, #0
4749 ; CHECK-GI-NEXT:    sshll2 v7.4s, v7.8h, #0
4750 ; CHECK-GI-NEXT:    abs v16.4s, v16.4s
4751 ; CHECK-GI-NEXT:    abs v5.4s, v5.4s
4752 ; CHECK-GI-NEXT:    fmov w8, s1
4753 ; CHECK-GI-NEXT:    add v6.4s, v17.4s, v6.4s
4754 ; CHECK-GI-NEXT:    addv s2, v2.4s
4755 ; CHECK-GI-NEXT:    fmov w9, s0
4756 ; CHECK-GI-NEXT:    addv s4, v4.4s
4757 ; CHECK-GI-NEXT:    fmov w10, s3
4758 ; CHECK-GI-NEXT:    abs v18.4s, v18.4s
4759 ; CHECK-GI-NEXT:    abs v7.4s, v7.4s
4760 ; CHECK-GI-NEXT:    add v1.4s, v16.4s, v5.4s
4761 ; CHECK-GI-NEXT:    add w8, w8, w9
4762 ; CHECK-GI-NEXT:    addv s3, v6.4s
4763 ; CHECK-GI-NEXT:    fmov w9, s2
4764 ; CHECK-GI-NEXT:    add w8, w10, w8
4765 ; CHECK-GI-NEXT:    fmov w10, s4
4766 ; CHECK-GI-NEXT:    add v0.4s, v18.4s, v7.4s
4767 ; CHECK-GI-NEXT:    addv s1, v1.4s
4768 ; CHECK-GI-NEXT:    add w8, w9, w8
4769 ; CHECK-GI-NEXT:    fmov w9, s3
4770 ; CHECK-GI-NEXT:    add w8, w10, w8
4771 ; CHECK-GI-NEXT:    addv s0, v0.4s
4772 ; CHECK-GI-NEXT:    add w8, w9, w8
4773 ; CHECK-GI-NEXT:    fmov w9, s1
4774 ; CHECK-GI-NEXT:    add w8, w9, w8
4775 ; CHECK-GI-NEXT:    fmov w9, s0
4776 ; CHECK-GI-NEXT:    add w0, w9, w8
4777 ; CHECK-GI-NEXT:    ret
4778 entry:
4779   %idx.ext8 = sext i32 %s2 to i64
4780   %idx.ext = sext i32 %s1 to i64
4781   %0 = load <8 x i8>, ptr %p1, align 1
4782   %1 = zext <8 x i8> %0 to <8 x i32>
4783   %2 = load <8 x i8>, ptr %p2, align 1
4784   %3 = zext <8 x i8> %2 to <8 x i32>
4785   %4 = sub nsw <8 x i32> %1, %3
4786   %5 = tail call <8 x i32> @llvm.abs.v8i32(<8 x i32> %4, i1 true)
4787   %6 = tail call i32 @llvm.vector.reduce.add.v8i32(<8 x i32> %5)
4788   %add.ptr = getelementptr inbounds i8, ptr %p1, i64 %idx.ext
4789   %add.ptr9 = getelementptr inbounds i8, ptr %p2, i64 %idx.ext8
4790   %7 = load <8 x i8>, ptr %add.ptr, align 1
4791   %8 = zext <8 x i8> %7 to <8 x i32>
4792   %9 = load <8 x i8>, ptr %add.ptr9, align 1
4793   %10 = zext <8 x i8> %9 to <8 x i32>
4794   %11 = sub nsw <8 x i32> %8, %10
4795   %12 = tail call <8 x i32> @llvm.abs.v8i32(<8 x i32> %11, i1 true)
4796   %13 = tail call i32 @llvm.vector.reduce.add.v8i32(<8 x i32> %12)
4797   %op.rdx.1 = add i32 %13, %6
4798   %add.ptr.1 = getelementptr inbounds i8, ptr %add.ptr, i64 %idx.ext
4799   %add.ptr9.1 = getelementptr inbounds i8, ptr %add.ptr9, i64 %idx.ext8
4800   %14 = load <8 x i8>, ptr %add.ptr.1, align 1
4801   %15 = zext <8 x i8> %14 to <8 x i32>
4802   %16 = load <8 x i8>, ptr %add.ptr9.1, align 1
4803   %17 = zext <8 x i8> %16 to <8 x i32>
4804   %18 = sub nsw <8 x i32> %15, %17
4805   %19 = tail call <8 x i32> @llvm.abs.v8i32(<8 x i32> %18, i1 true)
4806   %20 = tail call i32 @llvm.vector.reduce.add.v8i32(<8 x i32> %19)
4807   %op.rdx.2 = add i32 %20, %op.rdx.1
4808   %add.ptr.2 = getelementptr inbounds i8, ptr %add.ptr.1, i64 %idx.ext
4809   %add.ptr9.2 = getelementptr inbounds i8, ptr %add.ptr9.1, i64 %idx.ext8
4810   %21 = load <8 x i8>, ptr %add.ptr.2, align 1
4811   %22 = zext <8 x i8> %21 to <8 x i32>
4812   %23 = load <8 x i8>, ptr %add.ptr9.2, align 1
4813   %24 = zext <8 x i8> %23 to <8 x i32>
4814   %25 = sub nsw <8 x i32> %22, %24
4815   %26 = tail call <8 x i32> @llvm.abs.v8i32(<8 x i32> %25, i1 true)
4816   %27 = tail call i32 @llvm.vector.reduce.add.v8i32(<8 x i32> %26)
4817   %op.rdx.3 = add i32 %27, %op.rdx.2
4818   %add.ptr.3 = getelementptr inbounds i8, ptr %add.ptr.2, i64 %idx.ext
4819   %add.ptr9.3 = getelementptr inbounds i8, ptr %add.ptr9.2, i64 %idx.ext8
4820   %28 = load <8 x i8>, ptr %add.ptr.3, align 1
4821   %29 = zext <8 x i8> %28 to <8 x i32>
4822   %30 = load <8 x i8>, ptr %add.ptr9.3, align 1
4823   %31 = zext <8 x i8> %30 to <8 x i32>
4824   %32 = sub nsw <8 x i32> %29, %31
4825   %33 = tail call <8 x i32> @llvm.abs.v8i32(<8 x i32> %32, i1 true)
4826   %34 = tail call i32 @llvm.vector.reduce.add.v8i32(<8 x i32> %33)
4827   %op.rdx.4 = add i32 %34, %op.rdx.3
4828   %add.ptr.4 = getelementptr inbounds i8, ptr %add.ptr.3, i64 %idx.ext
4829   %add.ptr9.4 = getelementptr inbounds i8, ptr %add.ptr9.3, i64 %idx.ext8
4830   %35 = load <8 x i8>, ptr %add.ptr.4, align 1
4831   %36 = zext <8 x i8> %35 to <8 x i32>
4832   %37 = load <8 x i8>, ptr %add.ptr9.4, align 1
4833   %38 = zext <8 x i8> %37 to <8 x i32>
4834   %39 = sub nsw <8 x i32> %36, %38
4835   %40 = tail call <8 x i32> @llvm.abs.v8i32(<8 x i32> %39, i1 true)
4836   %41 = tail call i32 @llvm.vector.reduce.add.v8i32(<8 x i32> %40)
4837   %op.rdx.5 = add i32 %41, %op.rdx.4
4838   %add.ptr.5 = getelementptr inbounds i8, ptr %add.ptr.4, i64 %idx.ext
4839   %add.ptr9.5 = getelementptr inbounds i8, ptr %add.ptr9.4, i64 %idx.ext8
4840   %42 = load <8 x i8>, ptr %add.ptr.5, align 1
4841   %43 = zext <8 x i8> %42 to <8 x i32>
4842   %44 = load <8 x i8>, ptr %add.ptr9.5, align 1
4843   %45 = zext <8 x i8> %44 to <8 x i32>
4844   %46 = sub nsw <8 x i32> %43, %45
4845   %47 = tail call <8 x i32> @llvm.abs.v8i32(<8 x i32> %46, i1 true)
4846   %48 = tail call i32 @llvm.vector.reduce.add.v8i32(<8 x i32> %47)
4847   %op.rdx.6 = add i32 %48, %op.rdx.5
4848   %add.ptr.6 = getelementptr inbounds i8, ptr %add.ptr.5, i64 %idx.ext
4849   %add.ptr9.6 = getelementptr inbounds i8, ptr %add.ptr9.5, i64 %idx.ext8
4850   %49 = load <8 x i8>, ptr %add.ptr.6, align 1
4851   %50 = zext <8 x i8> %49 to <8 x i32>
4852   %51 = load <8 x i8>, ptr %add.ptr9.6, align 1
4853   %52 = zext <8 x i8> %51 to <8 x i32>
4854   %53 = sub nsw <8 x i32> %50, %52
4855   %54 = tail call <8 x i32> @llvm.abs.v8i32(<8 x i32> %53, i1 true)
4856   %55 = tail call i32 @llvm.vector.reduce.add.v8i32(<8 x i32> %54)
4857   %op.rdx.7 = add i32 %55, %op.rdx.6
4858   ret i32 %op.rdx.7
4861 define i32 @extract_hi_lo(<8 x i16> %a) {
4862 ; CHECK-SD-LABEL: extract_hi_lo:
4863 ; CHECK-SD:       // %bb.0: // %entry
4864 ; CHECK-SD-NEXT:    uaddlv s0, v0.8h
4865 ; CHECK-SD-NEXT:    fmov w0, s0
4866 ; CHECK-SD-NEXT:    ret
4868 ; CHECK-GI-LABEL: extract_hi_lo:
4869 ; CHECK-GI:       // %bb.0: // %entry
4870 ; CHECK-GI-NEXT:    ushll v1.4s, v0.4h, #0
4871 ; CHECK-GI-NEXT:    uaddw2 v0.4s, v1.4s, v0.8h
4872 ; CHECK-GI-NEXT:    addv s0, v0.4s
4873 ; CHECK-GI-NEXT:    fmov w0, s0
4874 ; CHECK-GI-NEXT:    ret
4875 entry:
4876   %e1 = shufflevector <8 x i16> %a, <8 x i16> undef, <4 x i32> <i32 0, i32 1, i32 2, i32 3>
4877   %e2 = shufflevector <8 x i16> %a, <8 x i16> undef, <4 x i32> <i32 4, i32 5, i32 6, i32 7>
4878   %z1 = zext <4 x i16> %e1 to <4 x i32>
4879   %z2 = zext <4 x i16> %e2 to <4 x i32>
4880   %z4 = add <4 x i32> %z1, %z2
4881   %z5 = call i32 @llvm.vector.reduce.add.v4i32(<4 x i32> %z4)
4882   ret i32 %z5
4885 define i32 @extract_hi_hi(<8 x i16> %a) {
4886 ; CHECK-SD-LABEL: extract_hi_hi:
4887 ; CHECK-SD:       // %bb.0: // %entry
4888 ; CHECK-SD-NEXT:    ext v0.16b, v0.16b, v0.16b, #8
4889 ; CHECK-SD-NEXT:    mov v0.d[1], v0.d[0]
4890 ; CHECK-SD-NEXT:    uaddlv s0, v0.8h
4891 ; CHECK-SD-NEXT:    fmov w0, s0
4892 ; CHECK-SD-NEXT:    ret
4894 ; CHECK-GI-LABEL: extract_hi_hi:
4895 ; CHECK-GI:       // %bb.0: // %entry
4896 ; CHECK-GI-NEXT:    uaddl2 v0.4s, v0.8h, v0.8h
4897 ; CHECK-GI-NEXT:    addv s0, v0.4s
4898 ; CHECK-GI-NEXT:    fmov w0, s0
4899 ; CHECK-GI-NEXT:    ret
4900 entry:
4901   %e2 = shufflevector <8 x i16> %a, <8 x i16> undef, <4 x i32> <i32 4, i32 5, i32 6, i32 7>
4902   %z2 = zext <4 x i16> %e2 to <4 x i32>
4903   %z4 = add <4 x i32> %z2, %z2
4904   %z5 = call i32 @llvm.vector.reduce.add.v4i32(<4 x i32> %z4)
4905   ret i32 %z5
4908 define i32 @extract_lo_lo(<8 x i16> %a) {
4909 ; CHECK-SD-LABEL: extract_lo_lo:
4910 ; CHECK-SD:       // %bb.0: // %entry
4911 ; CHECK-SD-NEXT:    mov v0.d[1], v0.d[0]
4912 ; CHECK-SD-NEXT:    uaddlv s0, v0.8h
4913 ; CHECK-SD-NEXT:    fmov w0, s0
4914 ; CHECK-SD-NEXT:    ret
4916 ; CHECK-GI-LABEL: extract_lo_lo:
4917 ; CHECK-GI:       // %bb.0: // %entry
4918 ; CHECK-GI-NEXT:    uaddl v0.4s, v0.4h, v0.4h
4919 ; CHECK-GI-NEXT:    addv s0, v0.4s
4920 ; CHECK-GI-NEXT:    fmov w0, s0
4921 ; CHECK-GI-NEXT:    ret
4922 entry:
4923   %e1 = shufflevector <8 x i16> %a, <8 x i16> undef, <4 x i32> <i32 0, i32 1, i32 2, i32 3>
4924   %z1 = zext <4 x i16> %e1 to <4 x i32>
4925   %z4 = add <4 x i32> %z1, %z1
4926   %z5 = call i32 @llvm.vector.reduce.add.v4i32(<4 x i32> %z4)
4927   ret i32 %z5
4930 declare <8 x i32> @llvm.abs.v8i32(<8 x i32>, i1 immarg) #1
4931 declare i16 @llvm.vector.reduce.add.v32i16(<32 x i16>)
4932 declare i16 @llvm.vector.reduce.add.v24i16(<24 x i16>)
4933 declare i16 @llvm.vector.reduce.add.v16i16(<16 x i16>)
4934 declare i16 @llvm.vector.reduce.add.v8i16(<8 x i16>)
4935 declare i16 @llvm.vector.reduce.add.v4i16(<4 x i16>)
4936 declare i32 @llvm.vector.reduce.add.v16i32(<16 x i32>)
4937 declare i32 @llvm.vector.reduce.add.v2i32(<2 x i32>)
4938 declare i32 @llvm.vector.reduce.add.v4i32(<4 x i32>)
4939 declare i32 @llvm.vector.reduce.add.v8i32(<8 x i32>)
4940 declare i32 @llvm.vector.reduce.add.v24i32(<24 x i32>)
4941 declare i32 @llvm.vector.reduce.add.v32i32(<32 x i32>)
4942 declare i32 @llvm.vector.reduce.add.v48i32(<48 x i32>)
4943 declare i64 @llvm.vector.reduce.add.v16i64(<16 x i64>)
4944 declare i64 @llvm.vector.reduce.add.v2i64(<2 x i64>)
4945 declare i64 @llvm.vector.reduce.add.v4i64(<4 x i64>)
4946 declare i64 @llvm.vector.reduce.add.v8i64(<8 x i64>)
4947 declare i8 @llvm.vector.reduce.add.v16i8(<16 x i8>)
4948 declare i8 @llvm.vector.reduce.add.v8i8(<8 x i8>)