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