1; RUN: llc -mtriple aarch64_be < %s -aarch64-enable-ldst-opt=false -O1 -o - | FileCheck %s
2; RUN: llc -mtriple aarch64_be < %s -aarch64-enable-ldst-opt=false -O0 -fast-isel=true -o - | FileCheck %s
3
4; CHECK-LABEL: test_i64_f64:
5define void @test_i64_f64(double* %p, i64* %q) {
6; CHECK: ldr
7; CHECK: str
8    %1 = load double, double* %p
9    %2 = fadd double %1, %1
10    %3 = bitcast double %2 to i64
11    %4 = add i64 %3, %3
12    store i64 %4, i64* %q
13    ret void
14}
15
16; CHECK-LABEL: test_i64_v1i64:
17define void @test_i64_v1i64(<1 x i64>* %p, i64* %q) {
18; CHECK: ldr
19; CHECK: str
20    %1 = load <1 x i64>, <1 x i64>* %p
21    %2 = add <1 x i64> %1, %1
22    %3 = bitcast <1 x i64> %2 to i64
23    %4 = add i64 %3, %3
24    store i64 %4, i64* %q
25    ret void
26}
27
28; CHECK-LABEL: test_i64_v2f32:
29define void @test_i64_v2f32(<2 x float>* %p, i64* %q) {
30; CHECK: ld1 { v{{[0-9]+}}.2s }
31; CHECK: rev64 v{{[0-9]+}}.2s
32; CHECK: str
33    %1 = load <2 x float>, <2 x float>* %p
34    %2 = fadd <2 x float> %1, %1
35    %3 = bitcast <2 x float> %2 to i64
36    %4 = add i64 %3, %3
37    store i64 %4, i64* %q
38    ret void
39}
40
41; CHECK-LABEL: test_i64_v2i32:
42define void @test_i64_v2i32(<2 x i32>* %p, i64* %q) {
43; CHECK: ld1 { v{{[0-9]+}}.2s }
44; CHECK: rev64 v{{[0-9]+}}.2s
45; CHECK: str
46    %1 = load <2 x i32>, <2 x i32>* %p
47    %2 = add <2 x i32> %1, %1
48    %3 = bitcast <2 x i32> %2 to i64
49    %4 = add i64 %3, %3
50    store i64 %4, i64* %q
51    ret void
52}
53
54; CHECK-LABEL: test_i64_v4f16:
55define void @test_i64_v4f16(<4 x half>* %p, i64* %q) {
56; CHECK: ld1 { v{{[0-9]+}}.4h }
57; CHECK-NOT: rev
58; CHECK: fadd
59; CHECK: rev64 v{{[0-9]+}}.4h
60; CHECK: str
61    %1 = load <4 x half>, <4 x half>* %p
62    %2 = fadd <4 x half> %1, %1
63    %3 = bitcast <4 x half> %2 to i64
64    %4 = add i64 %3, %3
65    store i64 %4, i64* %q
66    ret void
67}
68
69; CHECK-LABEL: test_i64_v4i16:
70define void @test_i64_v4i16(<4 x i16>* %p, i64* %q) {
71; CHECK: ld1 { v{{[0-9]+}}.4h }
72; CHECK: rev64 v{{[0-9]+}}.4h
73; CHECK: str
74    %1 = load <4 x i16>, <4 x i16>* %p
75    %2 = add <4 x i16> %1, %1
76    %3 = bitcast <4 x i16> %2 to i64
77    %4 = add i64 %3, %3
78    store i64 %4, i64* %q
79    ret void
80}
81
82; CHECK-LABEL: test_i64_v8i8:
83define void @test_i64_v8i8(<8 x i8>* %p, i64* %q) {
84; CHECK: ld1 { v{{[0-9]+}}.8b }
85; CHECK: rev64 v{{[0-9]+}}.8b
86; CHECK: str
87    %1 = load <8 x i8>, <8 x i8>* %p
88    %2 = add <8 x i8> %1, %1
89    %3 = bitcast <8 x i8> %2 to i64
90    %4 = add i64 %3, %3
91    store i64 %4, i64* %q
92    ret void
93}
94
95; CHECK-LABEL: test_f64_i64:
96define void @test_f64_i64(i64* %p, double* %q) {
97; CHECK: ldr
98; CHECK: str
99    %1 = load i64, i64* %p
100    %2 = add i64 %1, %1
101    %3 = bitcast i64 %2 to double
102    %4 = fadd double %3, %3
103    store double %4, double* %q
104    ret void
105}
106
107; CHECK-LABEL: test_f64_v1i64:
108define void @test_f64_v1i64(<1 x i64>* %p, double* %q) {
109; CHECK: ldr
110; CHECK: str
111    %1 = load <1 x i64>, <1 x i64>* %p
112    %2 = add <1 x i64> %1, %1
113    %3 = bitcast <1 x i64> %2 to double
114    %4 = fadd double %3, %3
115    store double %4, double* %q
116    ret void
117}
118
119; CHECK-LABEL: test_f64_v2f32:
120define void @test_f64_v2f32(<2 x float>* %p, double* %q) {
121; CHECK: ld1 { v{{[0-9]+}}.2s }
122; CHECK: rev64 v{{[0-9]+}}.2s
123; CHECK: str
124    %1 = load <2 x float>, <2 x float>* %p
125    %2 = fadd <2 x float> %1, %1
126    %3 = bitcast <2 x float> %2 to double
127    %4 = fadd double %3, %3
128    store double %4, double* %q
129    ret void
130}
131
132; CHECK-LABEL: test_f64_v2i32:
133define void @test_f64_v2i32(<2 x i32>* %p, double* %q) {
134; CHECK: ld1 { v{{[0-9]+}}.2s }
135; CHECK: rev64 v{{[0-9]+}}.2s
136; CHECK: str
137    %1 = load <2 x i32>, <2 x i32>* %p
138    %2 = add <2 x i32> %1, %1
139    %3 = bitcast <2 x i32> %2 to double
140    %4 = fadd double %3, %3
141    store double %4, double* %q
142    ret void
143}
144
145; CHECK-LABEL: test_f64_v4i16:
146define void @test_f64_v4i16(<4 x i16>* %p, double* %q) {
147; CHECK: ld1 { v{{[0-9]+}}.4h }
148; CHECK: rev64 v{{[0-9]+}}.4h
149; CHECK: str
150    %1 = load <4 x i16>, <4 x i16>* %p
151    %2 = add <4 x i16> %1, %1
152    %3 = bitcast <4 x i16> %2 to double
153    %4 = fadd double %3, %3
154    store double %4, double* %q
155    ret void
156}
157
158; CHECK-LABEL: test_f64_v4f16:
159define void @test_f64_v4f16(<4 x half>* %p, double* %q) {
160; CHECK: ld1 { v{{[0-9]+}}.4h }
161; CHECK-NOT: rev
162; CHECK: fadd
163; CHECK: rev64 v{{[0-9]+}}.4h
164; CHECK: fadd
165; CHECK: str
166    %1 = load <4 x half>, <4 x half>* %p
167    %2 = fadd <4 x half> %1, %1
168    %3 = bitcast <4 x half> %2 to double
169    %4 = fadd double %3, %3
170    store double %4, double* %q
171    ret void
172}
173
174; CHECK-LABEL: test_f64_v8i8:
175define void @test_f64_v8i8(<8 x i8>* %p, double* %q) {
176; CHECK: ld1 { v{{[0-9]+}}.8b }
177; CHECK: rev64 v{{[0-9]+}}.8b
178; CHECK: str
179    %1 = load <8 x i8>, <8 x i8>* %p
180    %2 = add <8 x i8> %1, %1
181    %3 = bitcast <8 x i8> %2 to double
182    %4 = fadd double %3, %3
183    store double %4, double* %q
184    ret void
185}
186
187; CHECK-LABEL: test_v1i64_i64:
188define void @test_v1i64_i64(i64* %p, <1 x i64>* %q) {
189; CHECK: ldr
190; CHECK: str
191    %1 = load i64, i64* %p
192    %2 = add i64 %1, %1
193    %3 = bitcast i64 %2 to <1 x i64>
194    %4 = add <1 x i64> %3, %3
195    store <1 x i64> %4, <1 x i64>* %q
196    ret void
197}
198
199; CHECK-LABEL: test_v1i64_f64:
200define void @test_v1i64_f64(double* %p, <1 x i64>* %q) {
201; CHECK: ldr
202; CHECK: str
203    %1 = load double, double* %p
204    %2 = fadd double %1, %1
205    %3 = bitcast double %2 to <1 x i64>
206    %4 = add <1 x i64> %3, %3
207    store <1 x i64> %4, <1 x i64>* %q
208    ret void
209}
210
211; CHECK-LABEL: test_v1i64_v2f32:
212define void @test_v1i64_v2f32(<2 x float>* %p, <1 x i64>* %q) {
213; CHECK: ld1 { v{{[0-9]+}}.2s }
214; CHECK: rev64 v{{[0-9]+}}.2s
215; CHECK: str
216    %1 = load <2 x float>, <2 x float>* %p
217    %2 = fadd <2 x float> %1, %1
218    %3 = bitcast <2 x float> %2 to <1 x i64>
219    %4 = add <1 x i64> %3, %3
220    store <1 x i64> %4, <1 x i64>* %q
221    ret void
222}
223
224; CHECK-LABEL: test_v1i64_v2i32:
225define void @test_v1i64_v2i32(<2 x i32>* %p, <1 x i64>* %q) {
226; CHECK: ld1 { v{{[0-9]+}}.2s }
227; CHECK: rev64 v{{[0-9]+}}.2s
228; CHECK: str
229    %1 = load <2 x i32>, <2 x i32>* %p
230    %2 = add <2 x i32> %1, %1
231    %3 = bitcast <2 x i32> %2 to <1 x i64>
232    %4 = add <1 x i64> %3, %3
233    store <1 x i64> %4, <1 x i64>* %q
234    ret void
235}
236
237; CHECK-LABEL: test_v1i64_v4f16:
238define void @test_v1i64_v4f16(<4 x half>* %p, <1 x i64>* %q) {
239; CHECK: ld1 { v{{[0-9]+}}.4h }
240; CHECK-NOT: rev
241; CHECK: fadd
242; CHECK: rev64 v{{[0-9]+}}.4h
243; CHECK: str
244    %1 = load <4 x half>, <4 x half>* %p
245    %2 = fadd <4 x half> %1, %1
246    %3 = bitcast <4 x half> %2 to <1 x i64>
247    %4 = add <1 x i64> %3, %3
248    store <1 x i64> %4, <1 x i64>* %q
249    ret void
250}
251
252; CHECK-LABEL: test_v1i64_v4i16:
253define void @test_v1i64_v4i16(<4 x i16>* %p, <1 x i64>* %q) {
254; CHECK: ld1 { v{{[0-9]+}}.4h }
255; CHECK: rev64 v{{[0-9]+}}.4h
256; CHECK: str
257    %1 = load <4 x i16>, <4 x i16>* %p
258    %2 = add <4 x i16> %1, %1
259    %3 = bitcast <4 x i16> %2 to <1 x i64>
260    %4 = add <1 x i64> %3, %3
261    store <1 x i64> %4, <1 x i64>* %q
262    ret void
263}
264
265; CHECK-LABEL: test_v1i64_v8i8:
266define void @test_v1i64_v8i8(<8 x i8>* %p, <1 x i64>* %q) {
267; CHECK: ld1 { v{{[0-9]+}}.8b }
268; CHECK: rev64 v{{[0-9]+}}.8b
269; CHECK: str
270    %1 = load <8 x i8>, <8 x i8>* %p
271    %2 = add <8 x i8> %1, %1
272    %3 = bitcast <8 x i8> %2 to <1 x i64>
273    %4 = add <1 x i64> %3, %3
274    store <1 x i64> %4, <1 x i64>* %q
275    ret void
276}
277
278; CHECK-LABEL: test_v2f32_i64:
279define void @test_v2f32_i64(i64* %p, <2 x float>* %q) {
280; CHECK: ldr
281; CHECK: rev64 v{{[0-9]+}}.2s
282; CHECK: st1 { v{{[0-9]+}}.2s }
283    %1 = load i64, i64* %p
284    %2 = add i64 %1, %1
285    %3 = bitcast i64 %2 to <2 x float>
286    %4 = fadd <2 x float> %3, %3
287    store <2 x float> %4, <2 x float>* %q
288    ret void
289}
290
291; CHECK-LABEL: test_v2f32_f64:
292define void @test_v2f32_f64(double* %p, <2 x float>* %q) {
293; CHECK: ldr
294; CHECK: rev64 v{{[0-9]+}}.2s
295; CHECK: st1 { v{{[0-9]+}}.2s }
296    %1 = load double, double* %p
297    %2 = fadd double %1, %1
298    %3 = bitcast double %2 to <2 x float>
299    %4 = fadd <2 x float> %3, %3
300    store <2 x float> %4, <2 x float>* %q
301    ret void
302}
303
304; CHECK-LABEL: test_v2f32_v1i64:
305define void @test_v2f32_v1i64(<1 x i64>* %p, <2 x float>* %q) {
306; CHECK: ldr
307; CHECK: rev64 v{{[0-9]+}}.2s
308; CHECK: st1 { v{{[0-9]+}}.2s }
309    %1 = load <1 x i64>, <1 x i64>* %p
310    %2 = add <1 x i64> %1, %1
311    %3 = bitcast <1 x i64> %2 to <2 x float>
312    %4 = fadd <2 x float> %3, %3
313    store <2 x float> %4, <2 x float>* %q
314    ret void
315}
316
317; CHECK-LABEL: test_v2f32_v2i32:
318define void @test_v2f32_v2i32(<2 x i32>* %p, <2 x float>* %q) {
319; CHECK: ld1 { v{{[0-9]+}}.2s }
320; CHECK: st1 { v{{[0-9]+}}.2s }
321    %1 = load <2 x i32>, <2 x i32>* %p
322    %2 = add <2 x i32> %1, %1
323    %3 = bitcast <2 x i32> %2 to <2 x float>
324    %4 = fadd <2 x float> %3, %3
325    store <2 x float> %4, <2 x float>* %q
326    ret void
327}
328
329; CHECK-LABEL: test_v2f32_v4i16:
330define void @test_v2f32_v4i16(<4 x i16>* %p, <2 x float>* %q) {
331; CHECK: ld1 { v{{[0-9]+}}.4h }
332; CHECK: rev32 v{{[0-9]+}}.4h
333; CHECK: st1 { v{{[0-9]+}}.2s }
334    %1 = load <4 x i16>, <4 x i16>* %p
335    %2 = add <4 x i16> %1, %1
336    %3 = bitcast <4 x i16> %2 to <2 x float>
337    %4 = fadd <2 x float> %3, %3
338    store <2 x float> %4, <2 x float>* %q
339    ret void
340}
341
342; CHECK-LABEL: test_v2f32_v4f16:
343define void @test_v2f32_v4f16(<4 x half>* %p, <2 x float>* %q) {
344; CHECK: ld1 { v{{[0-9]+}}.4h }
345; CHECK-NOT: rev
346; CHECK: fadd
347; CHECK: rev32 v{{[0-9]+}}.4h
348; CHECK: st1 { v{{[0-9]+}}.2s }
349    %1 = load <4 x half>, <4 x half>* %p
350    %2 = fadd <4 x half> %1, %1
351    %3 = bitcast <4 x half> %2 to <2 x float>
352    %4 = fadd <2 x float> %3, %3
353    store <2 x float> %4, <2 x float>* %q
354    ret void
355}
356
357; CHECK-LABEL: test_v2f32_v8i8:
358define void @test_v2f32_v8i8(<8 x i8>* %p, <2 x float>* %q) {
359; CHECK: ld1 { v{{[0-9]+}}.8b }
360; CHECK: rev32 v{{[0-9]+}}.8b
361; CHECK: st1 { v{{[0-9]+}}.2s }
362    %1 = load <8 x i8>, <8 x i8>* %p
363    %2 = add <8 x i8> %1, %1
364    %3 = bitcast <8 x i8> %2 to <2 x float>
365    %4 = fadd <2 x float> %3, %3
366    store <2 x float> %4, <2 x float>* %q
367    ret void
368}
369
370; CHECK-LABEL: test_v2i32_i64:
371define void @test_v2i32_i64(i64* %p, <2 x i32>* %q) {
372; CHECK: ldr
373; CHECK: rev64 v{{[0-9]+}}.2s
374; CHECK: st1 { v{{[0-9]+}}.2s }
375    %1 = load i64, i64* %p
376    %2 = add i64 %1, %1
377    %3 = bitcast i64 %2 to <2 x i32>
378    %4 = add <2 x i32> %3, %3
379    store <2 x i32> %4, <2 x i32>* %q
380    ret void
381}
382
383; CHECK-LABEL: test_v2i32_f64:
384define void @test_v2i32_f64(double* %p, <2 x i32>* %q) {
385; CHECK: ldr
386; CHECK: rev64 v{{[0-9]+}}.2s
387; CHECK: st1 { v{{[0-9]+}}.2s }
388    %1 = load double, double* %p
389    %2 = fadd double %1, %1
390    %3 = bitcast double %2 to <2 x i32>
391    %4 = add <2 x i32> %3, %3
392    store <2 x i32> %4, <2 x i32>* %q
393    ret void
394}
395
396; CHECK-LABEL: test_v2i32_v1i64:
397define void @test_v2i32_v1i64(<1 x i64>* %p, <2 x i32>* %q) {
398; CHECK: ldr
399; CHECK: rev64 v{{[0-9]+}}.2s
400; CHECK: st1 { v{{[0-9]+}}.2s }
401    %1 = load <1 x i64>, <1 x i64>* %p
402    %2 = add <1 x i64> %1, %1
403    %3 = bitcast <1 x i64> %2 to <2 x i32>
404    %4 = add <2 x i32> %3, %3
405    store <2 x i32> %4, <2 x i32>* %q
406    ret void
407}
408
409; CHECK-LABEL: test_v2i32_v2f32:
410define void @test_v2i32_v2f32(<2 x float>* %p, <2 x i32>* %q) {
411; CHECK: ld1 { v{{[0-9]+}}.2s }
412; CHECK: st1 { v{{[0-9]+}}.2s }
413    %1 = load <2 x float>, <2 x float>* %p
414    %2 = fadd <2 x float> %1, %1
415    %3 = bitcast <2 x float> %2 to <2 x i32>
416    %4 = add <2 x i32> %3, %3
417    store <2 x i32> %4, <2 x i32>* %q
418    ret void
419}
420
421; CHECK-LABEL: test_v2i32_v4i16:
422define void @test_v2i32_v4i16(<4 x i16>* %p, <2 x i32>* %q) {
423; CHECK: ld1 { v{{[0-9]+}}.4h }
424; CHECK: rev32 v{{[0-9]+}}.4h
425; CHECK: st1 { v{{[0-9]+}}.2s }
426    %1 = load <4 x i16>, <4 x i16>* %p
427    %2 = add <4 x i16> %1, %1
428    %3 = bitcast <4 x i16> %2 to <2 x i32>
429    %4 = add <2 x i32> %3, %3
430    store <2 x i32> %4, <2 x i32>* %q
431    ret void
432}
433
434; CHECK-LABEL: test_v2i32_v8i8:
435define void @test_v2i32_v8i8(<8 x i8>* %p, <2 x i32>* %q) {
436; CHECK: ld1 { v{{[0-9]+}}.8b }
437; CHECK: rev32 v{{[0-9]+}}.8b
438; CHECK: st1 { v{{[0-9]+}}.2s }
439    %1 = load <8 x i8>, <8 x i8>* %p
440    %2 = add <8 x i8> %1, %1
441    %3 = bitcast <8 x i8> %2 to <2 x i32>
442    %4 = add <2 x i32> %3, %3
443    store <2 x i32> %4, <2 x i32>* %q
444    ret void
445}
446
447; CHECK-LABEL: test_v4i16_i64:
448define void @test_v4i16_i64(i64* %p, <4 x i16>* %q) {
449; CHECK: ldr
450; CHECK: rev64 v{{[0-9]+}}.4h
451; CHECK: st1 { v{{[0-9]+}}.4h }
452    %1 = load i64, i64* %p
453    %2 = add i64 %1, %1
454    %3 = bitcast i64 %2 to <4 x i16>
455    %4 = add <4 x i16> %3, %3
456    store <4 x i16> %4, <4 x i16>* %q
457    ret void
458}
459
460; CHECK-LABEL: test_v4i16_f64:
461define void @test_v4i16_f64(double* %p, <4 x i16>* %q) {
462; CHECK: ldr
463; CHECK: rev64 v{{[0-9]+}}.4h
464; CHECK: st1 { v{{[0-9]+}}.4h }
465    %1 = load double, double* %p
466    %2 = fadd double %1, %1
467    %3 = bitcast double %2 to <4 x i16>
468    %4 = add <4 x i16> %3, %3
469    store <4 x i16> %4, <4 x i16>* %q
470    ret void
471}
472
473; CHECK-LABEL: test_v4i16_v1i64:
474define void @test_v4i16_v1i64(<1 x i64>* %p, <4 x i16>* %q) {
475; CHECK: ldr
476; CHECK: rev64 v{{[0-9]+}}.4h
477; CHECK: st1 { v{{[0-9]+}}.4h }
478    %1 = load <1 x i64>, <1 x i64>* %p
479    %2 = add <1 x i64> %1, %1
480    %3 = bitcast <1 x i64> %2 to <4 x i16>
481    %4 = add <4 x i16> %3, %3
482    store <4 x i16> %4, <4 x i16>* %q
483    ret void
484}
485
486; CHECK-LABEL: test_v4i16_v2f32:
487define void @test_v4i16_v2f32(<2 x float>* %p, <4 x i16>* %q) {
488; CHECK: ld1 { v{{[0-9]+}}.2s }
489; CHECK: rev32 v{{[0-9]+}}.4h
490; CHECK: st1 { v{{[0-9]+}}.4h }
491    %1 = load <2 x float>, <2 x float>* %p
492    %2 = fadd <2 x float> %1, %1
493    %3 = bitcast <2 x float> %2 to <4 x i16>
494    %4 = add <4 x i16> %3, %3
495    store <4 x i16> %4, <4 x i16>* %q
496    ret void
497}
498
499; CHECK-LABEL: test_v4i16_v2i32:
500define void @test_v4i16_v2i32(<2 x i32>* %p, <4 x i16>* %q) {
501; CHECK: ld1 { v{{[0-9]+}}.2s }
502; CHECK: rev32 v{{[0-9]+}}.4h
503; CHECK: st1 { v{{[0-9]+}}.4h }
504    %1 = load <2 x i32>, <2 x i32>* %p
505    %2 = add <2 x i32> %1, %1
506    %3 = bitcast <2 x i32> %2 to <4 x i16>
507    %4 = add <4 x i16> %3, %3
508    store <4 x i16> %4, <4 x i16>* %q
509    ret void
510}
511
512; CHECK-LABEL: test_v4i16_v4f16:
513define void @test_v4i16_v4f16(<4 x half>* %p, <4 x i16>* %q) {
514; CHECK: ld1 { v{{[0-9]+}}.4h }
515; CHECK-NOT: rev
516; CHECK: st1 { v{{[0-9]+}}.4h }
517    %1 = load <4 x half>, <4 x half>* %p
518    %2 = fadd <4 x half> %1, %1
519    %3 = bitcast <4 x half> %2 to <4 x i16>
520    %4 = add <4 x i16> %3, %3
521    store <4 x i16> %4, <4 x i16>* %q
522    ret void
523}
524
525; CHECK-LABEL: test_v4i16_v8i8:
526define void @test_v4i16_v8i8(<8 x i8>* %p, <4 x i16>* %q) {
527; CHECK: ld1 { v{{[0-9]+}}.8b }
528; CHECK: rev16 v{{[0-9]+}}.8b
529; CHECK: st1 { v{{[0-9]+}}.4h }
530    %1 = load <8 x i8>, <8 x i8>* %p
531    %2 = add <8 x i8> %1, %1
532    %3 = bitcast <8 x i8> %2 to <4 x i16>
533    %4 = add <4 x i16> %3, %3
534    store <4 x i16> %4, <4 x i16>* %q
535    ret void
536}
537
538; CHECK-LABEL: test_v4f16_i64:
539define void @test_v4f16_i64(i64* %p, <4 x half>* %q) {
540; CHECK: ldr
541; CHECK: rev64 v{{[0-9]+}}.4h
542; CHECK: fadd
543; CHECK-NOT: rev
544; CHECK: st1 { v{{[0-9]+}}.4h }
545    %1 = load i64, i64* %p
546    %2 = add i64 %1, %1
547    %3 = bitcast i64 %2 to <4 x half>
548    %4 = fadd <4 x half> %3, %3
549    store <4 x half> %4, <4 x half>* %q
550    ret void
551}
552
553; CHECK-LABEL: test_v4f16_f64:
554define void @test_v4f16_f64(double* %p, <4 x half>* %q) {
555; CHECK: ldr
556; CHECK: rev64 v{{[0-9]+}}.4h
557; CHECK: fadd
558; CHECK-NOT: rev
559; CHECK: st1 { v{{[0-9]+}}.4h }
560    %1 = load double, double* %p
561    %2 = fadd double %1, %1
562    %3 = bitcast double %2 to <4 x half>
563    %4 = fadd <4 x half> %3, %3
564    store <4 x half> %4, <4 x half>* %q
565    ret void
566}
567
568; CHECK-LABEL: test_v4f16_v1i64:
569define void @test_v4f16_v1i64(<1 x i64>* %p, <4 x half>* %q) {
570; CHECK: ldr
571; CHECK: rev64 v{{[0-9]+}}.4h
572; CHECK: fadd
573; CHECK-NOT: rev
574; CHECK: st1 { v{{[0-9]+}}.4h }
575    %1 = load <1 x i64>, <1 x i64>* %p
576    %2 = add <1 x i64> %1, %1
577    %3 = bitcast <1 x i64> %2 to <4 x half>
578    %4 = fadd <4 x half> %3, %3
579    store <4 x half> %4, <4 x half>* %q
580    ret void
581}
582
583; CHECK-LABEL: test_v4f16_v2f32:
584define void @test_v4f16_v2f32(<2 x float>* %p, <4 x half>* %q) {
585; CHECK: ld1 { v{{[0-9]+}}.2s }
586; CHECK: rev32 v{{[0-9]+}}.4h
587; CHECK: fadd
588; CHECK-NOT: rev
589; CHECK: st1 { v{{[0-9]+}}.4h }
590    %1 = load <2 x float>, <2 x float>* %p
591    %2 = fadd <2 x float> %1, %1
592    %3 = bitcast <2 x float> %2 to <4 x half>
593    %4 = fadd <4 x half> %3, %3
594    store <4 x half> %4, <4 x half>* %q
595    ret void
596}
597
598; CHECK-LABEL: test_v4f16_v2i32:
599define void @test_v4f16_v2i32(<2 x i32>* %p, <4 x half>* %q) {
600; CHECK: ld1 { v{{[0-9]+}}.2s }
601; CHECK: rev32 v{{[0-9]+}}.4h
602; CHECK: fadd
603; CHECK-NOT: rev
604; CHECK: st1 { v{{[0-9]+}}.4h }
605    %1 = load <2 x i32>, <2 x i32>* %p
606    %2 = add <2 x i32> %1, %1
607    %3 = bitcast <2 x i32> %2 to <4 x half>
608    %4 = fadd <4 x half> %3, %3
609    store <4 x half> %4, <4 x half>* %q
610    ret void
611}
612
613; CHECK-LABEL: test_v4f16_v4i16:
614define void @test_v4f16_v4i16(<4 x i16>* %p, <4 x half>* %q) {
615; CHECK: ld1 { v{{[0-9]+}}.4h }
616; CHECK-NOT: rev
617; CHECK: st1 { v{{[0-9]+}}.4h }
618    %1 = load <4 x i16>, <4 x i16>* %p
619    %2 = add <4 x i16> %1, %1
620    %3 = bitcast <4 x i16> %2 to <4 x half>
621    %4 = fadd <4 x half> %3, %3
622    store <4 x half> %4, <4 x half>* %q
623    ret void
624}
625
626; CHECK-LABEL: test_v4f16_v8i8:
627define void @test_v4f16_v8i8(<8 x i8>* %p, <4 x half>* %q) {
628; CHECK: ld1 { v{{[0-9]+}}.8b }
629; CHECK: rev16 v{{[0-9]+}}.8b
630; CHECK: fadd
631; CHECK-NOT: rev
632; CHECK: st1 { v{{[0-9]+}}.4h }
633    %1 = load <8 x i8>, <8 x i8>* %p
634    %2 = add <8 x i8> %1, %1
635    %3 = bitcast <8 x i8> %2 to <4 x half>
636    %4 = fadd <4 x half> %3, %3
637    store <4 x half> %4, <4 x half>* %q
638    ret void
639}
640
641; CHECK-LABEL: test_v8i8_i64:
642define void @test_v8i8_i64(i64* %p, <8 x i8>* %q) {
643; CHECK: ldr
644; CHECK: rev64 v{{[0-9]+}}.8b
645; CHECK: st1 { v{{[0-9]+}}.8b }
646    %1 = load i64, i64* %p
647    %2 = add i64 %1, %1
648    %3 = bitcast i64 %2 to <8 x i8>
649    %4 = add <8 x i8> %3, %3
650    store <8 x i8> %4, <8 x i8>* %q
651    ret void
652}
653
654; CHECK-LABEL: test_v8i8_f64:
655define void @test_v8i8_f64(double* %p, <8 x i8>* %q) {
656; CHECK: ldr
657; CHECK: rev64 v{{[0-9]+}}.8b
658; CHECK: st1 { v{{[0-9]+}}.8b }
659    %1 = load double, double* %p
660    %2 = fadd double %1, %1
661    %3 = bitcast double %2 to <8 x i8>
662    %4 = add <8 x i8> %3, %3
663    store <8 x i8> %4, <8 x i8>* %q
664    ret void
665}
666
667; CHECK-LABEL: test_v8i8_v1i64:
668define void @test_v8i8_v1i64(<1 x i64>* %p, <8 x i8>* %q) {
669; CHECK: ldr
670; CHECK: rev64 v{{[0-9]+}}.8b
671; CHECK: st1 { v{{[0-9]+}}.8b }
672    %1 = load <1 x i64>, <1 x i64>* %p
673    %2 = add <1 x i64> %1, %1
674    %3 = bitcast <1 x i64> %2 to <8 x i8>
675    %4 = add <8 x i8> %3, %3
676    store <8 x i8> %4, <8 x i8>* %q
677    ret void
678}
679
680; CHECK-LABEL: test_v8i8_v2f32:
681define void @test_v8i8_v2f32(<2 x float>* %p, <8 x i8>* %q) {
682; CHECK: ld1 { v{{[0-9]+}}.2s }
683; CHECK: rev32 v{{[0-9]+}}.8b
684; CHECK: st1 { v{{[0-9]+}}.8b }
685    %1 = load <2 x float>, <2 x float>* %p
686    %2 = fadd <2 x float> %1, %1
687    %3 = bitcast <2 x float> %2 to <8 x i8>
688    %4 = add <8 x i8> %3, %3
689    store <8 x i8> %4, <8 x i8>* %q
690    ret void
691}
692
693; CHECK-LABEL: test_v8i8_v2i32:
694define void @test_v8i8_v2i32(<2 x i32>* %p, <8 x i8>* %q) {
695; CHECK: ld1 { v{{[0-9]+}}.2s }
696; CHECK: rev32 v{{[0-9]+}}.8b
697; CHECK: st1 { v{{[0-9]+}}.8b }
698    %1 = load <2 x i32>, <2 x i32>* %p
699    %2 = add <2 x i32> %1, %1
700    %3 = bitcast <2 x i32> %2 to <8 x i8>
701    %4 = add <8 x i8> %3, %3
702    store <8 x i8> %4, <8 x i8>* %q
703    ret void
704}
705
706; CHECK-LABEL: test_v8i8_v4i16:
707define void @test_v8i8_v4i16(<4 x i16>* %p, <8 x i8>* %q) {
708; CHECK: ld1 { v{{[0-9]+}}.4h }
709; CHECK: rev16 v{{[0-9]+}}.8b
710; CHECK: st1 { v{{[0-9]+}}.8b }
711    %1 = load <4 x i16>, <4 x i16>* %p
712    %2 = add <4 x i16> %1, %1
713    %3 = bitcast <4 x i16> %2 to <8 x i8>
714    %4 = add <8 x i8> %3, %3
715    store <8 x i8> %4, <8 x i8>* %q
716    ret void
717}
718
719; CHECK-LABEL: test_f128_v2f64:
720define void @test_f128_v2f64(<2 x double>* %p, fp128* %q) {
721; CHECK: ld1 { v{{[0-9]+}}.2d }
722; CHECK: ext
723; CHECK: str
724    %1 = load <2 x double>, <2 x double>* %p
725    %2 = fadd <2 x double> %1, %1
726    %3 = bitcast <2 x double> %2 to fp128
727    %4 = fadd fp128 %3, %3
728    store fp128 %4, fp128* %q
729    ret void
730}
731
732; CHECK-LABEL: test_f128_v2i64:
733define void @test_f128_v2i64(<2 x i64>* %p, fp128* %q) {
734; CHECK: ld1 { v{{[0-9]+}}.2d }
735; CHECK: ext
736; CHECK: str
737    %1 = load <2 x i64>, <2 x i64>* %p
738    %2 = add <2 x i64> %1, %1
739    %3 = bitcast <2 x i64> %2 to fp128
740    %4 = fadd fp128 %3, %3
741    store fp128 %4, fp128* %q
742    ret void
743}
744
745; CHECK-LABEL: test_f128_v4f32:
746define void @test_f128_v4f32(<4 x float>* %p, fp128* %q) {
747; CHECK: ld1 { v{{[0-9]+}}.4s }
748; CHECK-NOT: rev
749; CHECK: fadd
750; CHECK: rev64 v{{[0-9]+}}.4s
751; CHECK: ext
752; CHECK: str q
753    %1 = load <4 x float>, <4 x float>* %p
754    %2 = fadd <4 x float> %1, %1
755    %3 = bitcast <4 x float> %2 to fp128
756    %4 = fadd fp128 %3, %3
757    store fp128 %4, fp128* %q
758    ret void
759}
760
761; CHECK-LABEL: test_f128_v4i32:
762define void @test_f128_v4i32(<4 x i32>* %p, fp128* %q) {
763; CHECK: ld1 { v{{[0-9]+}}.4s }
764; CHECK: rev64 v{{[0-9]+}}.4s
765; CHECK: ext
766; CHECK: str
767    %1 = load <4 x i32>, <4 x i32>* %p
768    %2 = add <4 x i32> %1, %1
769    %3 = bitcast <4 x i32> %2 to fp128
770    %4 = fadd fp128 %3, %3
771    store fp128 %4, fp128* %q
772    ret void
773}
774
775; CHECK-LABEL: test_f128_v8i16:
776define void @test_f128_v8i16(<8 x i16>* %p, fp128* %q) {
777; CHECK: ld1 { v{{[0-9]+}}.8h }
778; CHECK: rev64 v{{[0-9]+}}.8h
779; CHECK: ext
780; CHECK: str
781    %1 = load <8 x i16>, <8 x i16>* %p
782    %2 = add <8 x i16> %1, %1
783    %3 = bitcast <8 x i16> %2 to fp128
784    %4 = fadd fp128 %3, %3
785    store fp128 %4, fp128* %q
786    ret void
787}
788
789; CHECK-LABEL: test_f128_v16i8:
790define void @test_f128_v16i8(<16 x i8>* %p, fp128* %q) {
791; CHECK: ld1 { v{{[0-9]+}}.16b }
792; CHECK: ext
793; CHECK: str q
794    %1 = load <16 x i8>, <16 x i8>* %p
795    %2 = add <16 x i8> %1, %1
796    %3 = bitcast <16 x i8> %2 to fp128
797    %4 = fadd fp128 %3, %3
798    store fp128 %4, fp128* %q
799    ret void
800}
801
802; CHECK-LABEL: test_v2f64_f128:
803define void @test_v2f64_f128(fp128* %p, <2 x double>* %q) {
804; CHECK: ldr
805; CHECK: ext
806; CHECK: st1 { v{{[0-9]+}}.2d }
807    %1 = load fp128, fp128* %p
808    %2 = fadd fp128 %1, %1
809    %3 = bitcast fp128 %2 to <2 x double>
810    %4 = fadd <2 x double> %3, %3
811    store <2 x double> %4, <2 x double>* %q
812    ret void
813}
814
815; CHECK-LABEL: test_v2f64_v2i64:
816define void @test_v2f64_v2i64(<2 x i64>* %p, <2 x double>* %q) {
817; CHECK: ld1 { v{{[0-9]+}}.2d }
818; CHECK: st1 { v{{[0-9]+}}.2d }
819    %1 = load <2 x i64>, <2 x i64>* %p
820    %2 = add <2 x i64> %1, %1
821    %3 = bitcast <2 x i64> %2 to <2 x double>
822    %4 = fadd <2 x double> %3, %3
823    store <2 x double> %4, <2 x double>* %q
824    ret void
825}
826
827; CHECK-LABEL: test_v2f64_v4f32:
828define void @test_v2f64_v4f32(<4 x float>* %p, <2 x double>* %q) {
829; CHECK: ld1 { v{{[0-9]+}}.4s }
830; CHECK-NOT: rev
831; CHECK: fadd
832; CHECK: rev64 v{{[0-9]+}}.4s
833; CHECK: st1 { v{{[0-9]+}}.2d }
834    %1 = load <4 x float>, <4 x float>* %p
835    %2 = fadd <4 x float> %1, %1
836    %3 = bitcast <4 x float> %2 to <2 x double>
837    %4 = fadd <2 x double> %3, %3
838    store <2 x double> %4, <2 x double>* %q
839    ret void
840}
841
842; CHECK-LABEL: test_v2f64_v4i32:
843define void @test_v2f64_v4i32(<4 x i32>* %p, <2 x double>* %q) {
844; CHECK: ld1 { v{{[0-9]+}}.4s }
845; CHECK: rev64 v{{[0-9]+}}.4s
846; CHECK: st1 { v{{[0-9]+}}.2d }
847    %1 = load <4 x i32>, <4 x i32>* %p
848    %2 = add <4 x i32> %1, %1
849    %3 = bitcast <4 x i32> %2 to <2 x double>
850    %4 = fadd <2 x double> %3, %3
851    store <2 x double> %4, <2 x double>* %q
852    ret void
853}
854
855; CHECK-LABEL: test_v2f64_v8i16:
856define void @test_v2f64_v8i16(<8 x i16>* %p, <2 x double>* %q) {
857; CHECK: ld1 { v{{[0-9]+}}.8h }
858; CHECK: rev64 v{{[0-9]+}}.8h
859; CHECK: st1 { v{{[0-9]+}}.2d }
860    %1 = load <8 x i16>, <8 x i16>* %p
861    %2 = add <8 x i16> %1, %1
862    %3 = bitcast <8 x i16> %2 to <2 x double>
863    %4 = fadd <2 x double> %3, %3
864    store <2 x double> %4, <2 x double>* %q
865    ret void
866}
867
868; CHECK-LABEL: test_v2f64_v16i8:
869define void @test_v2f64_v16i8(<16 x i8>* %p, <2 x double>* %q) {
870; CHECK: ld1 { v{{[0-9]+}}.16b }
871; CHECK: rev64 v{{[0-9]+}}.16b
872; CHECK: st1 { v{{[0-9]+}}.2d }
873    %1 = load <16 x i8>, <16 x i8>* %p
874    %2 = add <16 x i8> %1, %1
875    %3 = bitcast <16 x i8> %2 to <2 x double>
876    %4 = fadd <2 x double> %3, %3
877    store <2 x double> %4, <2 x double>* %q
878    ret void
879}
880
881; CHECK-LABEL: test_v2i64_f128:
882define void @test_v2i64_f128(fp128* %p, <2 x i64>* %q) {
883; CHECK: ldr
884; CHECK: ext
885; CHECK: st1 { v{{[0-9]+}}.2d }
886    %1 = load fp128, fp128* %p
887    %2 = fadd fp128 %1, %1
888    %3 = bitcast fp128 %2 to <2 x i64>
889    %4 = add <2 x i64> %3, %3
890    store <2 x i64> %4, <2 x i64>* %q
891    ret void
892}
893
894; CHECK-LABEL: test_v2i64_v2f64:
895define void @test_v2i64_v2f64(<2 x double>* %p, <2 x i64>* %q) {
896; CHECK: ld1 { v{{[0-9]+}}.2d }
897; CHECK: st1 { v{{[0-9]+}}.2d }
898    %1 = load <2 x double>, <2 x double>* %p
899    %2 = fadd <2 x double> %1, %1
900    %3 = bitcast <2 x double> %2 to <2 x i64>
901    %4 = add <2 x i64> %3, %3
902    store <2 x i64> %4, <2 x i64>* %q
903    ret void
904}
905
906; CHECK-LABEL: test_v2i64_v4f32:
907define void @test_v2i64_v4f32(<4 x float>* %p, <2 x i64>* %q) {
908; CHECK: ld1 { v{{[0-9]+}}.4s }
909; CHECK-NOT: rev
910; CHECK: fadd
911; CHECK: rev64 v{{[0-9]+}}.4s
912; CHECK: add
913; CHECK: st1 { v{{[0-9]+}}.2d }
914    %1 = load <4 x float>, <4 x float>* %p
915    %2 = fadd <4 x float> %1, %1
916    %3 = bitcast <4 x float> %2 to <2 x i64>
917    %4 = add <2 x i64> %3, %3
918    store <2 x i64> %4, <2 x i64>* %q
919    ret void
920}
921
922; CHECK-LABEL: test_v2i64_v4i32:
923define void @test_v2i64_v4i32(<4 x i32>* %p, <2 x i64>* %q) {
924; CHECK: ld1 { v{{[0-9]+}}.4s }
925; CHECK: rev64 v{{[0-9]+}}.4s
926; CHECK: st1 { v{{[0-9]+}}.2d }
927    %1 = load <4 x i32>, <4 x i32>* %p
928    %2 = add <4 x i32> %1, %1
929    %3 = bitcast <4 x i32> %2 to <2 x i64>
930    %4 = add <2 x i64> %3, %3
931    store <2 x i64> %4, <2 x i64>* %q
932    ret void
933}
934
935; CHECK-LABEL: test_v2i64_v8i16:
936define void @test_v2i64_v8i16(<8 x i16>* %p, <2 x i64>* %q) {
937; CHECK: ld1 { v{{[0-9]+}}.8h }
938; CHECK: rev64 v{{[0-9]+}}.8h
939; CHECK: st1 { v{{[0-9]+}}.2d }
940    %1 = load <8 x i16>, <8 x i16>* %p
941    %2 = add <8 x i16> %1, %1
942    %3 = bitcast <8 x i16> %2 to <2 x i64>
943    %4 = add <2 x i64> %3, %3
944    store <2 x i64> %4, <2 x i64>* %q
945    ret void
946}
947
948; CHECK-LABEL: test_v2i64_v16i8:
949define void @test_v2i64_v16i8(<16 x i8>* %p, <2 x i64>* %q) {
950; CHECK: ld1 { v{{[0-9]+}}.16b }
951; CHECK: rev64 v{{[0-9]+}}.16b
952; CHECK: st1 { v{{[0-9]+}}.2d }
953    %1 = load <16 x i8>, <16 x i8>* %p
954    %2 = add <16 x i8> %1, %1
955    %3 = bitcast <16 x i8> %2 to <2 x i64>
956    %4 = add <2 x i64> %3, %3
957    store <2 x i64> %4, <2 x i64>* %q
958    ret void
959}
960
961; CHECK-LABEL: test_v4f32_f128:
962define void @test_v4f32_f128(fp128* %p, <4 x float>* %q) {
963; CHECK: ldr q
964; CHECK: rev64 v{{[0-9]+}}.4s
965; CHECK: ext
966; CHECK-NOT: rev
967; CHECK: st1 { v{{[0-9]+}}.4s }
968    %1 = load fp128, fp128* %p
969    %2 = fadd fp128 %1, %1
970    %3 = bitcast fp128 %2 to <4 x float>
971    %4 = fadd <4 x float> %3, %3
972    store <4 x float> %4, <4 x float>* %q
973    ret void
974}
975
976; CHECK-LABEL: test_v4f32_v2f64:
977define void @test_v4f32_v2f64(<2 x double>* %p, <4 x float>* %q) {
978; CHECK: ld1 { v{{[0-9]+}}.2d }
979; CHECK: rev64 v{{[0-9]+}}.4s
980; CHECK-NOT: rev
981; CHECK: st1 { v{{[0-9]+}}.4s }
982    %1 = load <2 x double>, <2 x double>* %p
983    %2 = fadd <2 x double> %1, %1
984    %3 = bitcast <2 x double> %2 to <4 x float>
985    %4 = fadd <4 x float> %3, %3
986    store <4 x float> %4, <4 x float>* %q
987    ret void
988}
989
990; CHECK-LABEL: test_v4f32_v2i64:
991define void @test_v4f32_v2i64(<2 x i64>* %p, <4 x float>* %q) {
992; CHECK: ld1 { v{{[0-9]+}}.2d }
993; CHECK: rev64 v{{[0-9]+}}.4s
994; CHECK: fadd
995; CHECK-NOT: rev
996; CHECK: st1 { v{{[0-9]+}}.4s }
997    %1 = load <2 x i64>, <2 x i64>* %p
998    %2 = add <2 x i64> %1, %1
999    %3 = bitcast <2 x i64> %2 to <4 x float>
1000    %4 = fadd <4 x float> %3, %3
1001    store <4 x float> %4, <4 x float>* %q
1002    ret void
1003}
1004
1005; CHECK-LABEL: test_v4f32_v4i32:
1006define void @test_v4f32_v4i32(<4 x i32>* %p, <4 x float>* %q) {
1007; CHECK: ld1 { v{{[0-9]+}}.4s }
1008; CHECK-NOT: rev
1009; CHECK: st1 { v{{[0-9]+}}.4s }
1010    %1 = load <4 x i32>, <4 x i32>* %p
1011    %2 = add <4 x i32> %1, %1
1012    %3 = bitcast <4 x i32> %2 to <4 x float>
1013    %4 = fadd <4 x float> %3, %3
1014    store <4 x float> %4, <4 x float>* %q
1015    ret void
1016}
1017
1018; CHECK-LABEL: test_v4f32_v8i16:
1019define void @test_v4f32_v8i16(<8 x i16>* %p, <4 x float>* %q) {
1020; CHECK: ld1 { v{{[0-9]+}}.8h }
1021; CHECK: rev32 v{{[0-9]+}}.8h
1022; CHECK-NOT: rev
1023; CHECK: st1 { v{{[0-9]+}}.4s }
1024    %1 = load <8 x i16>, <8 x i16>* %p
1025    %2 = add <8 x i16> %1, %1
1026    %3 = bitcast <8 x i16> %2 to <4 x float>
1027    %4 = fadd <4 x float> %3, %3
1028    store <4 x float> %4, <4 x float>* %q
1029    ret void
1030}
1031
1032; CHECK-LABEL: test_v4f32_v16i8:
1033define void @test_v4f32_v16i8(<16 x i8>* %p, <4 x float>* %q) {
1034; CHECK: ld1 { v{{[0-9]+}}.16b }
1035; CHECK: rev32 v{{[0-9]+}}.16b
1036; CHECK-NOT: rev
1037; CHECK: st1 { v{{[0-9]+}}.4s }
1038    %1 = load <16 x i8>, <16 x i8>* %p
1039    %2 = add <16 x i8> %1, %1
1040    %3 = bitcast <16 x i8> %2 to <4 x float>
1041    %4 = fadd <4 x float> %3, %3
1042    store <4 x float> %4, <4 x float>* %q
1043    ret void
1044}
1045
1046; CHECK-LABEL: test_v4i32_f128:
1047define void @test_v4i32_f128(fp128* %p, <4 x i32>* %q) {
1048; CHECK: ldr
1049; CHECK: rev64 v{{[0-9]+}}.4s
1050; CHECK: ext
1051; CHECK: st1 { v{{[0-9]+}}.4s }
1052    %1 = load fp128, fp128* %p
1053    %2 = fadd fp128 %1, %1
1054    %3 = bitcast fp128 %2 to <4 x i32>
1055    %4 = add <4 x i32> %3, %3
1056    store <4 x i32> %4, <4 x i32>* %q
1057    ret void
1058}
1059
1060; CHECK-LABEL: test_v4i32_v2f64:
1061define void @test_v4i32_v2f64(<2 x double>* %p, <4 x i32>* %q) {
1062; CHECK: ld1 { v{{[0-9]+}}.2d }
1063; CHECK: rev64 v{{[0-9]+}}.4s
1064; CHECK: st1 { v{{[0-9]+}}.4s }
1065    %1 = load <2 x double>, <2 x double>* %p
1066    %2 = fadd <2 x double> %1, %1
1067    %3 = bitcast <2 x double> %2 to <4 x i32>
1068    %4 = add <4 x i32> %3, %3
1069    store <4 x i32> %4, <4 x i32>* %q
1070    ret void
1071}
1072
1073; CHECK-LABEL: test_v4i32_v2i64:
1074define void @test_v4i32_v2i64(<2 x i64>* %p, <4 x i32>* %q) {
1075; CHECK: ld1 { v{{[0-9]+}}.2d }
1076; CHECK: rev64 v{{[0-9]+}}.4s
1077; CHECK: st1 { v{{[0-9]+}}.4s }
1078    %1 = load <2 x i64>, <2 x i64>* %p
1079    %2 = add <2 x i64> %1, %1
1080    %3 = bitcast <2 x i64> %2 to <4 x i32>
1081    %4 = add <4 x i32> %3, %3
1082    store <4 x i32> %4, <4 x i32>* %q
1083    ret void
1084}
1085
1086; CHECK-LABEL: test_v4i32_v4f32:
1087define void @test_v4i32_v4f32(<4 x float>* %p, <4 x i32>* %q) {
1088; CHECK: ld1 { v{{[0-9]+}}.4s }
1089; CHECK-NOT: rev
1090; CHECK: st1 { v{{[0-9]+}}.4s }
1091    %1 = load <4 x float>, <4 x float>* %p
1092    %2 = fadd <4 x float> %1, %1
1093    %3 = bitcast <4 x float> %2 to <4 x i32>
1094    %4 = add <4 x i32> %3, %3
1095    store <4 x i32> %4, <4 x i32>* %q
1096    ret void
1097}
1098
1099; CHECK-LABEL: test_v4i32_v8i16:
1100define void @test_v4i32_v8i16(<8 x i16>* %p, <4 x i32>* %q) {
1101; CHECK: ld1 { v{{[0-9]+}}.8h }
1102; CHECK: rev32 v{{[0-9]+}}.8h
1103; CHECK: st1 { v{{[0-9]+}}.4s }
1104    %1 = load <8 x i16>, <8 x i16>* %p
1105    %2 = add <8 x i16> %1, %1
1106    %3 = bitcast <8 x i16> %2 to <4 x i32>
1107    %4 = add <4 x i32> %3, %3
1108    store <4 x i32> %4, <4 x i32>* %q
1109    ret void
1110}
1111
1112; CHECK-LABEL: test_v4i32_v16i8:
1113define void @test_v4i32_v16i8(<16 x i8>* %p, <4 x i32>* %q) {
1114; CHECK: ld1 { v{{[0-9]+}}.16b }
1115; CHECK: rev32 v{{[0-9]+}}.16b
1116; CHECK: st1 { v{{[0-9]+}}.4s }
1117    %1 = load <16 x i8>, <16 x i8>* %p
1118    %2 = add <16 x i8> %1, %1
1119    %3 = bitcast <16 x i8> %2 to <4 x i32>
1120    %4 = add <4 x i32> %3, %3
1121    store <4 x i32> %4, <4 x i32>* %q
1122    ret void
1123}
1124
1125; CHECK-LABEL: test_v8i16_f128:
1126define void @test_v8i16_f128(fp128* %p, <8 x i16>* %q) {
1127; CHECK: ldr
1128; CHECK: rev64 v{{[0-9]+}}.8h
1129; CHECK: ext
1130; CHECK: st1 { v{{[0-9]+}}.8h }
1131    %1 = load fp128, fp128* %p
1132    %2 = fadd fp128 %1, %1
1133    %3 = bitcast fp128 %2 to <8 x i16>
1134    %4 = add <8 x i16> %3, %3
1135    store <8 x i16> %4, <8 x i16>* %q
1136    ret void
1137}
1138
1139; CHECK-LABEL: test_v8i16_v2f64:
1140define void @test_v8i16_v2f64(<2 x double>* %p, <8 x i16>* %q) {
1141; CHECK: ld1 { v{{[0-9]+}}.2d }
1142; CHECK: rev64 v{{[0-9]+}}.8h
1143; CHECK: st1 { v{{[0-9]+}}.8h }
1144    %1 = load <2 x double>, <2 x double>* %p
1145    %2 = fadd <2 x double> %1, %1
1146    %3 = bitcast <2 x double> %2 to <8 x i16>
1147    %4 = add <8 x i16> %3, %3
1148    store <8 x i16> %4, <8 x i16>* %q
1149    ret void
1150}
1151
1152; CHECK-LABEL: test_v8i16_v2i64:
1153define void @test_v8i16_v2i64(<2 x i64>* %p, <8 x i16>* %q) {
1154; CHECK: ld1 { v{{[0-9]+}}.2d }
1155; CHECK: rev64 v{{[0-9]+}}.8h
1156; CHECK: st1 { v{{[0-9]+}}.8h }
1157    %1 = load <2 x i64>, <2 x i64>* %p
1158    %2 = add <2 x i64> %1, %1
1159    %3 = bitcast <2 x i64> %2 to <8 x i16>
1160    %4 = add <8 x i16> %3, %3
1161    store <8 x i16> %4, <8 x i16>* %q
1162    ret void
1163}
1164
1165; CHECK-LABEL: test_v8i16_v4f32:
1166define void @test_v8i16_v4f32(<4 x float>* %p, <8 x i16>* %q) {
1167; CHECK: ld1 { v{{[0-9]+}}.4s }
1168; CHECK: rev32 v{{[0-9]+}}.8h
1169; CHECK-NOT: rev
1170; CHECK: st1 { v{{[0-9]+}}.8h }
1171    %1 = load <4 x float>, <4 x float>* %p
1172    %2 = fadd <4 x float> %1, %1
1173    %3 = bitcast <4 x float> %2 to <8 x i16>
1174    %4 = add <8 x i16> %3, %3
1175    store <8 x i16> %4, <8 x i16>* %q
1176    ret void
1177}
1178
1179; CHECK-LABEL: test_v8i16_v4i32:
1180define void @test_v8i16_v4i32(<4 x i32>* %p, <8 x i16>* %q) {
1181; CHECK: ld1 { v{{[0-9]+}}.4s }
1182; CHECK: rev32 v{{[0-9]+}}.8h
1183; CHECK: st1 { v{{[0-9]+}}.8h }
1184    %1 = load <4 x i32>, <4 x i32>* %p
1185    %2 = add <4 x i32> %1, %1
1186    %3 = bitcast <4 x i32> %2 to <8 x i16>
1187    %4 = add <8 x i16> %3, %3
1188    store <8 x i16> %4, <8 x i16>* %q
1189    ret void
1190}
1191
1192; CHECK-LABEL: test_v8i16_v8f16:
1193define void @test_v8i16_v8f16(<8 x half>* %p, <8 x i16>* %q) {
1194; CHECK: ld1 { v{{[0-9]+}}.8h }
1195; CHECK-NOT: rev
1196; CHECK: st1 { v{{[0-9]+}}.8h }
1197    %1 = load <8 x half>, <8 x half>* %p
1198    %2 = fadd <8 x half> %1, %1
1199    %3 = bitcast <8 x half> %2 to <8 x i16>
1200    %4 = add <8 x i16> %3, %3
1201    store <8 x i16> %4, <8 x i16>* %q
1202    ret void
1203}
1204
1205; CHECK-LABEL: test_v8i16_v16i8:
1206define void @test_v8i16_v16i8(<16 x i8>* %p, <8 x i16>* %q) {
1207; CHECK: ld1 { v{{[0-9]+}}.16b }
1208; CHECK: rev16 v{{[0-9]+}}.16b
1209; CHECK: st1 { v{{[0-9]+}}.8h }
1210    %1 = load <16 x i8>, <16 x i8>* %p
1211    %2 = add <16 x i8> %1, %1
1212    %3 = bitcast <16 x i8> %2 to <8 x i16>
1213    %4 = add <8 x i16> %3, %3
1214    store <8 x i16> %4, <8 x i16>* %q
1215    ret void
1216}
1217
1218; CHECK-LABEL: test_v16i8_f128:
1219define void @test_v16i8_f128(fp128* %p, <16 x i8>* %q) {
1220; CHECK: ldr q
1221; CHECK: rev64 v{{[0-9]+}}.16b
1222; CHECK: ext
1223; CHECK: st1 { v{{[0-9]+}}.16b }
1224    %1 = load fp128, fp128* %p
1225    %2 = fadd fp128 %1, %1
1226    %3 = bitcast fp128 %2 to <16 x i8>
1227    %4 = add <16 x i8> %3, %3
1228    store <16 x i8> %4, <16 x i8>* %q
1229    ret void
1230}
1231
1232; CHECK-LABEL: test_v16i8_v2f64:
1233define void @test_v16i8_v2f64(<2 x double>* %p, <16 x i8>* %q) {
1234; CHECK: ld1 { v{{[0-9]+}}.2d }
1235; CHECK: rev64 v{{[0-9]+}}.16b
1236; CHECK: st1 { v{{[0-9]+}}.16b }
1237    %1 = load <2 x double>, <2 x double>* %p
1238    %2 = fadd <2 x double> %1, %1
1239    %3 = bitcast <2 x double> %2 to <16 x i8>
1240    %4 = add <16 x i8> %3, %3
1241    store <16 x i8> %4, <16 x i8>* %q
1242    ret void
1243}
1244
1245; CHECK-LABEL: test_v16i8_v2i64:
1246define void @test_v16i8_v2i64(<2 x i64>* %p, <16 x i8>* %q) {
1247; CHECK: ld1 { v{{[0-9]+}}.2d }
1248; CHECK: rev64 v{{[0-9]+}}.16b
1249; CHECK: st1 { v{{[0-9]+}}.16b }
1250    %1 = load <2 x i64>, <2 x i64>* %p
1251    %2 = add <2 x i64> %1, %1
1252    %3 = bitcast <2 x i64> %2 to <16 x i8>
1253    %4 = add <16 x i8> %3, %3
1254    store <16 x i8> %4, <16 x i8>* %q
1255    ret void
1256}
1257
1258; CHECK-LABEL: test_v16i8_v4f32:
1259define void @test_v16i8_v4f32(<4 x float>* %p, <16 x i8>* %q) {
1260; CHECK: ld1 { v{{[0-9]+}}.4s }
1261; CHECK: rev32 v{{[0-9]+}}.16b
1262; CHECK-NOT: rev
1263; CHECK: st1 { v{{[0-9]+}}.16b }
1264    %1 = load <4 x float>, <4 x float>* %p
1265    %2 = fadd <4 x float> %1, %1
1266    %3 = bitcast <4 x float> %2 to <16 x i8>
1267    %4 = add <16 x i8> %3, %3
1268    store <16 x i8> %4, <16 x i8>* %q
1269    ret void
1270}
1271
1272; CHECK-LABEL: test_v16i8_v4i32:
1273define void @test_v16i8_v4i32(<4 x i32>* %p, <16 x i8>* %q) {
1274; CHECK: ld1 { v{{[0-9]+}}.4s }
1275; CHECK: rev32 v{{[0-9]+}}.16b
1276; CHECK: st1 { v{{[0-9]+}}.16b }
1277    %1 = load <4 x i32>, <4 x i32>* %p
1278    %2 = add <4 x i32> %1, %1
1279    %3 = bitcast <4 x i32> %2 to <16 x i8>
1280    %4 = add <16 x i8> %3, %3
1281    store <16 x i8> %4, <16 x i8>* %q
1282    ret void
1283}
1284
1285; CHECK-LABEL: test_v16i8_v8f16:
1286define void @test_v16i8_v8f16(<8 x half>* %p, <16 x i8>* %q) {
1287; CHECK: ld1 { v{{[0-9]+}}.8h }
1288; CHECK: rev16 v{{[0-9]+}}.16b
1289; CHECK-NOT: rev
1290; CHECK: st1 { v{{[0-9]+}}.16b }
1291    %1 = load <8 x half>, <8 x half>* %p
1292    %2 = fadd <8 x half> %1, %1
1293    %3 = bitcast <8 x half> %2 to <16 x i8>
1294    %4 = add <16 x i8> %3, %3
1295    store <16 x i8> %4, <16 x i8>* %q
1296    ret void
1297}
1298
1299; CHECK-LABEL: test_v16i8_v8i16:
1300define void @test_v16i8_v8i16(<8 x i16>* %p, <16 x i8>* %q) {
1301; CHECK: ld1 { v{{[0-9]+}}.8h }
1302; CHECK: rev16 v{{[0-9]+}}.16b
1303; CHECK: st1 { v{{[0-9]+}}.16b }
1304    %1 = load <8 x i16>, <8 x i16>* %p
1305    %2 = add <8 x i16> %1, %1
1306    %3 = bitcast <8 x i16> %2 to <16 x i8>
1307    %4 = add <16 x i8> %3, %3
1308    store <16 x i8> %4, <16 x i8>* %q
1309    ret void
1310}
1311
1312; CHECK-LABEL: test_v4f16_struct:
1313%struct.struct1 = type { half, half, half, half }
1314define %struct.struct1 @test_v4f16_struct(%struct.struct1* %ret) {
1315entry:
1316; CHECK: ld1 { {{v[0-9]+}}.4h }
1317; CHECK-NOT: rev
1318  %0 = bitcast %struct.struct1* %ret to <4 x half>*
1319  %1 = load <4 x half>, <4 x half>* %0, align 2
1320  %2 = extractelement <4 x half> %1, i32 0
1321  %.fca.0.insert = insertvalue %struct.struct1 undef, half %2, 0
1322  ret %struct.struct1 %.fca.0.insert
1323}
1324