1; NOTE: Assertions have been autogenerated by utils/update_llc_test_checks.py
2; RUN: llc -verify-machineinstrs  < %s 2>%t | FileCheck %s
3
4; RUN: FileCheck --check-prefix=WARN --allow-empty %s <%t
5
6; If this check fails please read test/CodeGen/AArch64/README for instructions on how to resolve it.
7; WARN-NOT: warning
8
9
10target triple = "x86_64-unknown-unknown"
11
12;
13; VECTOR_REVERSE
14;
15
16define <16 x i8> @reverse_v16i8(<16 x i8> %a) #0 {
17; CHECK-LABEL: reverse_v16i8:
18; CHECK:       # %bb.0:
19; CHECK-NEXT:    pxor      %xmm1, %xmm1
20; CHECK-NEXT:    movdqa    %xmm0, %xmm2
21; CHECK-NEXT:    punpcklbw  %xmm1, %xmm
22; CHECK-NEXT:    pshufd     $78, %xmm2, %xmm2
23; CHECK-NEXT:    pshuflw    $27, %xmm2, %xmm2
24; CHECK-NEXT:    pshufhw    $27, %xmm2, %xmm2
25; CHECK-NEXT:    punpckhbw  %xmm1, %xmm0
26; CHECK-NEXT:    pshufd     $78, %xmm0, %xmm0
27; CHECK-NEXT:    pshuflw    $27, %xmm0, %xmm0
28; CHECK-NEXT:    pshufhw    $27, %xmm0, %xmm0
29; CHECK-NEXT:    packuswb   %xmm2, %xmm0
30; CHECK-NEXT:    retq
31
32  %res = call <16 x i8> @llvm.experimental.vector.reverse.v16i8(<16 x i8> %a)
33  ret <16 x i8> %res
34}
35
36define <8 x i16> @reverse_v8i16(<8 x i16> %a) #0 {
37; CHECK-LABEL: reverse_v8i16:
38; CHECK:       # %bb.0:
39; CHECK-NEXT:    pshufd     $78, %xmm0, %xmm
40; CHECK-NEXT:    pshuflw    $27, %xmm0, %xmm0
41; CHECK-NEXT:    pshufhw    $27, %xmm0, %xmm0
42; CHECK-NEXT:    retq
43  %res = call <8 x i16> @llvm.experimental.vector.reverse.v8i16(<8 x i16> %a)
44  ret <8 x i16> %res
45}
46
47define <4 x i32> @reverse_v4i32(<4 x i32> %a) #0 {
48; CHECK-LABEL: reverse_v4i32:
49; CHECK:       # %bb.0:
50; CHECK-NEXT:    pshufd    $27, %xmm0, %xmm0
51; CHECK-NEXT:    retq
52  %res = call <4 x i32> @llvm.experimental.vector.reverse.v4i32(<4 x i32> %a)
53  ret <4 x i32> %res
54}
55
56define <2 x i64> @reverse_v2i64(<2 x i64> %a) #0 {
57; CHECK-LABEL: reverse_v2i64:
58; CHECK:       # %bb.0:
59; CHECK-NEXT:    pshufd    $78, %xmm0, %xmm0
60; CHECK-NEXT:    retq
61  %res = call <2 x i64> @llvm.experimental.vector.reverse.v2i64(<2 x i64> %a)
62  ret <2 x i64> %res
63}
64
65define <4 x float> @reverse_v4f32(<4 x float> %a) #0 {
66; CHECK-LABEL: reverse_v4f32:
67; CHECK:       # %bb.0:
68; CHECK-NEXT:    shufps    $27, %xmm0, %xmm0
69; CHECK-NEXT:    retq
70  %res = call <4 x float> @llvm.experimental.vector.reverse.v4f32(<4 x float> %a)
71  ret <4 x float> %res
72}
73
74define <2 x double> @reverse_v2f64(<2 x double> %a) #0 {
75; CHECK-LABEL: reverse_v2f64:
76; CHECK:       # %bb.0:
77; CHECK-NEXT:    shufps    $78, %xmm0, %xmm0
78; CHECK-NEXT:    retq
79  %res = call <2 x double> @llvm.experimental.vector.reverse.v2f64(<2 x double> %a)
80  ret <2 x double> %res
81}
82
83; Verify promote type legalisation works as expected.
84define <2 x i8> @reverse_v2i8(<2 x i8> %a) #0 {
85; CHECK-LABEL: reverse_v2i8:
86; CHECK:       # %bb.0:
87; CHECK-NEXT:    movdqa   %xmm0, %xmm1
88; CHECK-NEXT:    psrlw    $8, %xmm1
89; CHECK-NEXT:    psllw    $8, %xmm0
90; CHECK-NEXT:    por      %xmm1, %xmm0
91; CHECK-NEXT:    retq
92  %res = call <2 x i8> @llvm.experimental.vector.reverse.v2i8(<2 x i8> %a)
93  ret <2 x i8> %res
94}
95
96; Verify splitvec type legalisation works as expected.
97define <8 x i32> @reverse_v8i32(<8 x i32> %a) #0 {
98; CHECK-LABEL: reverse_v8i32:
99; CHECK:       # %bb.0:
100; CHECK-NEXT:    pshufd    $27, %xmm1, %xmm2
101; CHECK-NEXT:    pshufd    $27, %xmm0, %xmm1
102; CHECK-NEXT:    movdqa %xmm2, %xmm0
103; CHECK-NEXT:    retq
104  %res = call <8 x i32> @llvm.experimental.vector.reverse.v8i32(<8 x i32> %a)
105  ret <8 x i32> %res
106}
107
108; Verify splitvec type legalisation works as expected.
109define <16 x float> @reverse_v16f32(<16 x float> %a) #0 {
110; CHECK-LABEL: reverse_v16f32:
111; CHECK:       # %bb.0:
112; CHECK-NEXT:    movaps    %xmm1, %xmm4
113; CHECK-NEXT:    movaps    %xmm0, %xmm5
114; CHECK-NEXT:    shufps    $27, %xmm3, %xmm
115; CHECK-NEXT:    shufps    $27, %xmm2, %xmm2
116; CHECK-NEXT:    shufps    $27, %xmm1, %xmm4
117; CHECK-NEXT:    shufps    $27, %xmm0, %xmm5
118; CHECK-NEXT:    movaps    %xmm3, %xmm0
119; CHECK-NEXT:    movaps    %xmm2, %xmm1
120; CHECK-NEXT:    movaps    %xmm4, %xmm2
121; CHECK-NEXT:    movaps    %xmm5, %xmm3
122
123  %res = call <16 x float> @llvm.experimental.vector.reverse.v16f32(<16 x float> %a)
124  ret <16 x float> %res
125}
126
127
128declare <2 x i8> @llvm.experimental.vector.reverse.v2i8(<2 x i8>)
129declare <16 x i8> @llvm.experimental.vector.reverse.v16i8(<16 x i8>)
130declare <8 x i16> @llvm.experimental.vector.reverse.v8i16(<8 x i16>)
131declare <4 x i32> @llvm.experimental.vector.reverse.v4i32(<4 x i32>)
132declare <8 x i32> @llvm.experimental.vector.reverse.v8i32(<8 x i32>)
133declare <2 x i64> @llvm.experimental.vector.reverse.v2i64(<2 x i64>)
134declare <8 x half> @llvm.experimental.vector.reverse.v8f16(<8 x half>)
135declare <4 x float> @llvm.experimental.vector.reverse.v4f32(<4 x float>)
136declare <16 x float> @llvm.experimental.vector.reverse.v16f32(<16 x float>)
137declare <2 x double> @llvm.experimental.vector.reverse.v2f64(<2 x double>)
138
139attributes #0 = { nounwind }
140