1; NOTE: Assertions have been autogenerated by utils/update_llc_test_checks.py
2; RUN: llc < %s -mtriple=x86_64-unknown-linux-gnu | FileCheck %s --check-prefix=CHECK-ALL --check-prefix=CHECK-SSE --check-prefix=CHECK-NOSSSE3
3; RUN: llc < %s -mtriple=x86_64-unknown-linux-gnu -mattr=+ssse3 | FileCheck %s --check-prefix=CHECK-ALL --check-prefix=CHECK-SSE --check-prefix=CHECK-SSSE3
4; RUN: llc < %s -mtriple=x86_64-unknown-linux-gnu -mattr=+avx2 | FileCheck %s --check-prefix=CHECK-ALL --check-prefix=CHECK-AVX --check-prefix=CHECK-AVX2
5; RUN: llc < %s -mtriple=x86_64-unknown-linux-gnu -mattr=+avx2 -x86-experimental-vector-widening-legalization | FileCheck %s --check-prefix=CHECK-ALL --check-prefix=CHECK-WIDE-AVX --check-prefix=CHECK-WIDE-AVX2
6
7declare <8 x i16> @llvm.bswap.v8i16(<8 x i16>)
8declare <4 x i32> @llvm.bswap.v4i32(<4 x i32>)
9declare <2 x i64> @llvm.bswap.v2i64(<2 x i64>)
10
11define <8 x i16> @test1(<8 x i16> %v) {
12; CHECK-NOSSSE3-LABEL: test1:
13; CHECK-NOSSSE3:       # %bb.0: # %entry
14; CHECK-NOSSSE3-NEXT:    pxor %xmm1, %xmm1
15; CHECK-NOSSSE3-NEXT:    movdqa %xmm0, %xmm2
16; CHECK-NOSSSE3-NEXT:    punpckhbw {{.*#+}} xmm2 = xmm2[8],xmm1[8],xmm2[9],xmm1[9],xmm2[10],xmm1[10],xmm2[11],xmm1[11],xmm2[12],xmm1[12],xmm2[13],xmm1[13],xmm2[14],xmm1[14],xmm2[15],xmm1[15]
17; CHECK-NOSSSE3-NEXT:    pshuflw {{.*#+}} xmm2 = xmm2[1,0,3,2,4,5,6,7]
18; CHECK-NOSSSE3-NEXT:    pshufhw {{.*#+}} xmm2 = xmm2[0,1,2,3,5,4,7,6]
19; CHECK-NOSSSE3-NEXT:    punpcklbw {{.*#+}} xmm0 = xmm0[0],xmm1[0],xmm0[1],xmm1[1],xmm0[2],xmm1[2],xmm0[3],xmm1[3],xmm0[4],xmm1[4],xmm0[5],xmm1[5],xmm0[6],xmm1[6],xmm0[7],xmm1[7]
20; CHECK-NOSSSE3-NEXT:    pshuflw {{.*#+}} xmm0 = xmm0[1,0,3,2,4,5,6,7]
21; CHECK-NOSSSE3-NEXT:    pshufhw {{.*#+}} xmm0 = xmm0[0,1,2,3,5,4,7,6]
22; CHECK-NOSSSE3-NEXT:    packuswb %xmm2, %xmm0
23; CHECK-NOSSSE3-NEXT:    retq
24;
25; CHECK-SSSE3-LABEL: test1:
26; CHECK-SSSE3:       # %bb.0: # %entry
27; CHECK-SSSE3-NEXT:    pshufb {{.*#+}} xmm0 = xmm0[1,0,3,2,5,4,7,6,9,8,11,10,13,12,15,14]
28; CHECK-SSSE3-NEXT:    retq
29;
30; CHECK-AVX-LABEL: test1:
31; CHECK-AVX:       # %bb.0: # %entry
32; CHECK-AVX-NEXT:    vpshufb {{.*#+}} xmm0 = xmm0[1,0,3,2,5,4,7,6,9,8,11,10,13,12,15,14]
33; CHECK-AVX-NEXT:    retq
34;
35; CHECK-WIDE-AVX-LABEL: test1:
36; CHECK-WIDE-AVX:       # %bb.0: # %entry
37; CHECK-WIDE-AVX-NEXT:    vpshufb {{.*#+}} xmm0 = xmm0[1,0,3,2,5,4,7,6,9,8,11,10,13,12,15,14]
38; CHECK-WIDE-AVX-NEXT:    retq
39entry:
40  %r = call <8 x i16> @llvm.bswap.v8i16(<8 x i16> %v)
41  ret <8 x i16> %r
42}
43
44define <4 x i32> @test2(<4 x i32> %v) {
45; CHECK-NOSSSE3-LABEL: test2:
46; CHECK-NOSSSE3:       # %bb.0:
47; CHECK-NOSSSE3-NEXT:    pxor %xmm1, %xmm1
48; CHECK-NOSSSE3-NEXT:    movdqa %xmm0, %xmm2
49; CHECK-NOSSSE3-NEXT:    punpckhbw {{.*#+}} xmm2 = xmm2[8],xmm1[8],xmm2[9],xmm1[9],xmm2[10],xmm1[10],xmm2[11],xmm1[11],xmm2[12],xmm1[12],xmm2[13],xmm1[13],xmm2[14],xmm1[14],xmm2[15],xmm1[15]
50; CHECK-NOSSSE3-NEXT:    pshuflw {{.*#+}} xmm2 = xmm2[3,2,1,0,4,5,6,7]
51; CHECK-NOSSSE3-NEXT:    pshufhw {{.*#+}} xmm2 = xmm2[0,1,2,3,7,6,5,4]
52; CHECK-NOSSSE3-NEXT:    punpcklbw {{.*#+}} xmm0 = xmm0[0],xmm1[0],xmm0[1],xmm1[1],xmm0[2],xmm1[2],xmm0[3],xmm1[3],xmm0[4],xmm1[4],xmm0[5],xmm1[5],xmm0[6],xmm1[6],xmm0[7],xmm1[7]
53; CHECK-NOSSSE3-NEXT:    pshuflw {{.*#+}} xmm0 = xmm0[3,2,1,0,4,5,6,7]
54; CHECK-NOSSSE3-NEXT:    pshufhw {{.*#+}} xmm0 = xmm0[0,1,2,3,7,6,5,4]
55; CHECK-NOSSSE3-NEXT:    packuswb %xmm2, %xmm0
56; CHECK-NOSSSE3-NEXT:    retq
57;
58; CHECK-SSSE3-LABEL: test2:
59; CHECK-SSSE3:       # %bb.0:
60; CHECK-SSSE3-NEXT:    pshufb {{.*#+}} xmm0 = xmm0[3,2,1,0,7,6,5,4,11,10,9,8,15,14,13,12]
61; CHECK-SSSE3-NEXT:    retq
62;
63; CHECK-AVX-LABEL: test2:
64; CHECK-AVX:       # %bb.0:
65; CHECK-AVX-NEXT:    vpshufb {{.*#+}} xmm0 = xmm0[3,2,1,0,7,6,5,4,11,10,9,8,15,14,13,12]
66; CHECK-AVX-NEXT:    retq
67;
68; CHECK-WIDE-AVX-LABEL: test2:
69; CHECK-WIDE-AVX:       # %bb.0:
70; CHECK-WIDE-AVX-NEXT:    vpshufb {{.*#+}} xmm0 = xmm0[3,2,1,0,7,6,5,4,11,10,9,8,15,14,13,12]
71; CHECK-WIDE-AVX-NEXT:    retq
72  %r = call <4 x i32> @llvm.bswap.v4i32(<4 x i32> %v)
73  ret <4 x i32> %r
74}
75
76define <4 x i32> @or_bswap(<4 x i32> %x, <4 x i32> %y, <4 x i32>* %p1, <4 x i32>* %p2) {
77; CHECK-NOSSSE3-LABEL: or_bswap:
78; CHECK-NOSSSE3:       # %bb.0:
79; CHECK-NOSSSE3-NEXT:    por %xmm1, %xmm0
80; CHECK-NOSSSE3-NEXT:    pxor %xmm1, %xmm1
81; CHECK-NOSSSE3-NEXT:    movdqa %xmm0, %xmm2
82; CHECK-NOSSSE3-NEXT:    punpckhbw {{.*#+}} xmm2 = xmm2[8],xmm1[8],xmm2[9],xmm1[9],xmm2[10],xmm1[10],xmm2[11],xmm1[11],xmm2[12],xmm1[12],xmm2[13],xmm1[13],xmm2[14],xmm1[14],xmm2[15],xmm1[15]
83; CHECK-NOSSSE3-NEXT:    pshuflw {{.*#+}} xmm2 = xmm2[3,2,1,0,4,5,6,7]
84; CHECK-NOSSSE3-NEXT:    pshufhw {{.*#+}} xmm2 = xmm2[0,1,2,3,7,6,5,4]
85; CHECK-NOSSSE3-NEXT:    punpcklbw {{.*#+}} xmm0 = xmm0[0],xmm1[0],xmm0[1],xmm1[1],xmm0[2],xmm1[2],xmm0[3],xmm1[3],xmm0[4],xmm1[4],xmm0[5],xmm1[5],xmm0[6],xmm1[6],xmm0[7],xmm1[7]
86; CHECK-NOSSSE3-NEXT:    pshuflw {{.*#+}} xmm0 = xmm0[3,2,1,0,4,5,6,7]
87; CHECK-NOSSSE3-NEXT:    pshufhw {{.*#+}} xmm0 = xmm0[0,1,2,3,7,6,5,4]
88; CHECK-NOSSSE3-NEXT:    packuswb %xmm2, %xmm0
89; CHECK-NOSSSE3-NEXT:    retq
90;
91; CHECK-SSSE3-LABEL: or_bswap:
92; CHECK-SSSE3:       # %bb.0:
93; CHECK-SSSE3-NEXT:    por %xmm1, %xmm0
94; CHECK-SSSE3-NEXT:    pshufb {{.*#+}} xmm0 = xmm0[3,2,1,0,7,6,5,4,11,10,9,8,15,14,13,12]
95; CHECK-SSSE3-NEXT:    retq
96;
97; CHECK-AVX-LABEL: or_bswap:
98; CHECK-AVX:       # %bb.0:
99; CHECK-AVX-NEXT:    vpor %xmm1, %xmm0, %xmm0
100; CHECK-AVX-NEXT:    vpshufb {{.*#+}} xmm0 = xmm0[3,2,1,0,7,6,5,4,11,10,9,8,15,14,13,12]
101; CHECK-AVX-NEXT:    retq
102;
103; CHECK-WIDE-AVX-LABEL: or_bswap:
104; CHECK-WIDE-AVX:       # %bb.0:
105; CHECK-WIDE-AVX-NEXT:    vpor %xmm1, %xmm0, %xmm0
106; CHECK-WIDE-AVX-NEXT:    vpshufb {{.*#+}} xmm0 = xmm0[3,2,1,0,7,6,5,4,11,10,9,8,15,14,13,12]
107; CHECK-WIDE-AVX-NEXT:    retq
108  %xt = call <4 x i32> @llvm.bswap.v4i32(<4 x i32> %x)
109  %yt = call <4 x i32> @llvm.bswap.v4i32(<4 x i32> %y)
110  %r = or <4 x i32> %xt, %yt
111  ret <4 x i32> %r
112}
113
114define <2 x i64> @test3(<2 x i64> %v) {
115; CHECK-NOSSSE3-LABEL: test3:
116; CHECK-NOSSSE3:       # %bb.0: # %entry
117; CHECK-NOSSSE3-NEXT:    pxor %xmm1, %xmm1
118; CHECK-NOSSSE3-NEXT:    movdqa %xmm0, %xmm2
119; CHECK-NOSSSE3-NEXT:    punpckhbw {{.*#+}} xmm2 = xmm2[8],xmm1[8],xmm2[9],xmm1[9],xmm2[10],xmm1[10],xmm2[11],xmm1[11],xmm2[12],xmm1[12],xmm2[13],xmm1[13],xmm2[14],xmm1[14],xmm2[15],xmm1[15]
120; CHECK-NOSSSE3-NEXT:    pshufd {{.*#+}} xmm2 = xmm2[2,3,0,1]
121; CHECK-NOSSSE3-NEXT:    pshuflw {{.*#+}} xmm2 = xmm2[3,2,1,0,4,5,6,7]
122; CHECK-NOSSSE3-NEXT:    pshufhw {{.*#+}} xmm2 = xmm2[0,1,2,3,7,6,5,4]
123; CHECK-NOSSSE3-NEXT:    punpcklbw {{.*#+}} xmm0 = xmm0[0],xmm1[0],xmm0[1],xmm1[1],xmm0[2],xmm1[2],xmm0[3],xmm1[3],xmm0[4],xmm1[4],xmm0[5],xmm1[5],xmm0[6],xmm1[6],xmm0[7],xmm1[7]
124; CHECK-NOSSSE3-NEXT:    pshufd {{.*#+}} xmm0 = xmm0[2,3,0,1]
125; CHECK-NOSSSE3-NEXT:    pshuflw {{.*#+}} xmm0 = xmm0[3,2,1,0,4,5,6,7]
126; CHECK-NOSSSE3-NEXT:    pshufhw {{.*#+}} xmm0 = xmm0[0,1,2,3,7,6,5,4]
127; CHECK-NOSSSE3-NEXT:    packuswb %xmm2, %xmm0
128; CHECK-NOSSSE3-NEXT:    retq
129;
130; CHECK-SSSE3-LABEL: test3:
131; CHECK-SSSE3:       # %bb.0: # %entry
132; CHECK-SSSE3-NEXT:    pshufb {{.*#+}} xmm0 = xmm0[7,6,5,4,3,2,1,0,15,14,13,12,11,10,9,8]
133; CHECK-SSSE3-NEXT:    retq
134;
135; CHECK-AVX-LABEL: test3:
136; CHECK-AVX:       # %bb.0: # %entry
137; CHECK-AVX-NEXT:    vpshufb {{.*#+}} xmm0 = xmm0[7,6,5,4,3,2,1,0,15,14,13,12,11,10,9,8]
138; CHECK-AVX-NEXT:    retq
139;
140; CHECK-WIDE-AVX-LABEL: test3:
141; CHECK-WIDE-AVX:       # %bb.0: # %entry
142; CHECK-WIDE-AVX-NEXT:    vpshufb {{.*#+}} xmm0 = xmm0[7,6,5,4,3,2,1,0,15,14,13,12,11,10,9,8]
143; CHECK-WIDE-AVX-NEXT:    retq
144entry:
145  %r = call <2 x i64> @llvm.bswap.v2i64(<2 x i64> %v)
146  ret <2 x i64> %r
147}
148
149declare <16 x i16> @llvm.bswap.v16i16(<16 x i16>)
150declare <8 x i32> @llvm.bswap.v8i32(<8 x i32>)
151declare <4 x i64> @llvm.bswap.v4i64(<4 x i64>)
152
153define <16 x i16> @test4(<16 x i16> %v) {
154; CHECK-NOSSSE3-LABEL: test4:
155; CHECK-NOSSSE3:       # %bb.0: # %entry
156; CHECK-NOSSSE3-NEXT:    pxor %xmm2, %xmm2
157; CHECK-NOSSSE3-NEXT:    movdqa %xmm0, %xmm3
158; CHECK-NOSSSE3-NEXT:    punpckhbw {{.*#+}} xmm3 = xmm3[8],xmm2[8],xmm3[9],xmm2[9],xmm3[10],xmm2[10],xmm3[11],xmm2[11],xmm3[12],xmm2[12],xmm3[13],xmm2[13],xmm3[14],xmm2[14],xmm3[15],xmm2[15]
159; CHECK-NOSSSE3-NEXT:    pshuflw {{.*#+}} xmm3 = xmm3[1,0,3,2,4,5,6,7]
160; CHECK-NOSSSE3-NEXT:    pshufhw {{.*#+}} xmm3 = xmm3[0,1,2,3,5,4,7,6]
161; CHECK-NOSSSE3-NEXT:    punpcklbw {{.*#+}} xmm0 = xmm0[0],xmm2[0],xmm0[1],xmm2[1],xmm0[2],xmm2[2],xmm0[3],xmm2[3],xmm0[4],xmm2[4],xmm0[5],xmm2[5],xmm0[6],xmm2[6],xmm0[7],xmm2[7]
162; CHECK-NOSSSE3-NEXT:    pshuflw {{.*#+}} xmm0 = xmm0[1,0,3,2,4,5,6,7]
163; CHECK-NOSSSE3-NEXT:    pshufhw {{.*#+}} xmm0 = xmm0[0,1,2,3,5,4,7,6]
164; CHECK-NOSSSE3-NEXT:    packuswb %xmm3, %xmm0
165; CHECK-NOSSSE3-NEXT:    movdqa %xmm1, %xmm3
166; CHECK-NOSSSE3-NEXT:    punpckhbw {{.*#+}} xmm3 = xmm3[8],xmm2[8],xmm3[9],xmm2[9],xmm3[10],xmm2[10],xmm3[11],xmm2[11],xmm3[12],xmm2[12],xmm3[13],xmm2[13],xmm3[14],xmm2[14],xmm3[15],xmm2[15]
167; CHECK-NOSSSE3-NEXT:    pshuflw {{.*#+}} xmm3 = xmm3[1,0,3,2,4,5,6,7]
168; CHECK-NOSSSE3-NEXT:    pshufhw {{.*#+}} xmm3 = xmm3[0,1,2,3,5,4,7,6]
169; CHECK-NOSSSE3-NEXT:    punpcklbw {{.*#+}} xmm1 = xmm1[0],xmm2[0],xmm1[1],xmm2[1],xmm1[2],xmm2[2],xmm1[3],xmm2[3],xmm1[4],xmm2[4],xmm1[5],xmm2[5],xmm1[6],xmm2[6],xmm1[7],xmm2[7]
170; CHECK-NOSSSE3-NEXT:    pshuflw {{.*#+}} xmm1 = xmm1[1,0,3,2,4,5,6,7]
171; CHECK-NOSSSE3-NEXT:    pshufhw {{.*#+}} xmm1 = xmm1[0,1,2,3,5,4,7,6]
172; CHECK-NOSSSE3-NEXT:    packuswb %xmm3, %xmm1
173; CHECK-NOSSSE3-NEXT:    retq
174;
175; CHECK-SSSE3-LABEL: test4:
176; CHECK-SSSE3:       # %bb.0: # %entry
177; CHECK-SSSE3-NEXT:    movdqa {{.*#+}} xmm2 = [1,0,3,2,5,4,7,6,9,8,11,10,13,12,15,14]
178; CHECK-SSSE3-NEXT:    pshufb %xmm2, %xmm0
179; CHECK-SSSE3-NEXT:    pshufb %xmm2, %xmm1
180; CHECK-SSSE3-NEXT:    retq
181;
182; CHECK-AVX-LABEL: test4:
183; CHECK-AVX:       # %bb.0: # %entry
184; CHECK-AVX-NEXT:    vpshufb {{.*#+}} ymm0 = ymm0[1,0,3,2,5,4,7,6,9,8,11,10,13,12,15,14,17,16,19,18,21,20,23,22,25,24,27,26,29,28,31,30]
185; CHECK-AVX-NEXT:    retq
186;
187; CHECK-WIDE-AVX-LABEL: test4:
188; CHECK-WIDE-AVX:       # %bb.0: # %entry
189; CHECK-WIDE-AVX-NEXT:    vpshufb {{.*#+}} ymm0 = ymm0[1,0,3,2,5,4,7,6,9,8,11,10,13,12,15,14,17,16,19,18,21,20,23,22,25,24,27,26,29,28,31,30]
190; CHECK-WIDE-AVX-NEXT:    retq
191entry:
192  %r = call <16 x i16> @llvm.bswap.v16i16(<16 x i16> %v)
193  ret <16 x i16> %r
194}
195
196define <8 x i32> @test5(<8 x i32> %v) {
197; CHECK-NOSSSE3-LABEL: test5:
198; CHECK-NOSSSE3:       # %bb.0: # %entry
199; CHECK-NOSSSE3-NEXT:    pxor %xmm2, %xmm2
200; CHECK-NOSSSE3-NEXT:    movdqa %xmm0, %xmm3
201; CHECK-NOSSSE3-NEXT:    punpckhbw {{.*#+}} xmm3 = xmm3[8],xmm2[8],xmm3[9],xmm2[9],xmm3[10],xmm2[10],xmm3[11],xmm2[11],xmm3[12],xmm2[12],xmm3[13],xmm2[13],xmm3[14],xmm2[14],xmm3[15],xmm2[15]
202; CHECK-NOSSSE3-NEXT:    pshuflw {{.*#+}} xmm3 = xmm3[3,2,1,0,4,5,6,7]
203; CHECK-NOSSSE3-NEXT:    pshufhw {{.*#+}} xmm3 = xmm3[0,1,2,3,7,6,5,4]
204; CHECK-NOSSSE3-NEXT:    punpcklbw {{.*#+}} xmm0 = xmm0[0],xmm2[0],xmm0[1],xmm2[1],xmm0[2],xmm2[2],xmm0[3],xmm2[3],xmm0[4],xmm2[4],xmm0[5],xmm2[5],xmm0[6],xmm2[6],xmm0[7],xmm2[7]
205; CHECK-NOSSSE3-NEXT:    pshuflw {{.*#+}} xmm0 = xmm0[3,2,1,0,4,5,6,7]
206; CHECK-NOSSSE3-NEXT:    pshufhw {{.*#+}} xmm0 = xmm0[0,1,2,3,7,6,5,4]
207; CHECK-NOSSSE3-NEXT:    packuswb %xmm3, %xmm0
208; CHECK-NOSSSE3-NEXT:    movdqa %xmm1, %xmm3
209; CHECK-NOSSSE3-NEXT:    punpckhbw {{.*#+}} xmm3 = xmm3[8],xmm2[8],xmm3[9],xmm2[9],xmm3[10],xmm2[10],xmm3[11],xmm2[11],xmm3[12],xmm2[12],xmm3[13],xmm2[13],xmm3[14],xmm2[14],xmm3[15],xmm2[15]
210; CHECK-NOSSSE3-NEXT:    pshuflw {{.*#+}} xmm3 = xmm3[3,2,1,0,4,5,6,7]
211; CHECK-NOSSSE3-NEXT:    pshufhw {{.*#+}} xmm3 = xmm3[0,1,2,3,7,6,5,4]
212; CHECK-NOSSSE3-NEXT:    punpcklbw {{.*#+}} xmm1 = xmm1[0],xmm2[0],xmm1[1],xmm2[1],xmm1[2],xmm2[2],xmm1[3],xmm2[3],xmm1[4],xmm2[4],xmm1[5],xmm2[5],xmm1[6],xmm2[6],xmm1[7],xmm2[7]
213; CHECK-NOSSSE3-NEXT:    pshuflw {{.*#+}} xmm1 = xmm1[3,2,1,0,4,5,6,7]
214; CHECK-NOSSSE3-NEXT:    pshufhw {{.*#+}} xmm1 = xmm1[0,1,2,3,7,6,5,4]
215; CHECK-NOSSSE3-NEXT:    packuswb %xmm3, %xmm1
216; CHECK-NOSSSE3-NEXT:    retq
217;
218; CHECK-SSSE3-LABEL: test5:
219; CHECK-SSSE3:       # %bb.0: # %entry
220; CHECK-SSSE3-NEXT:    movdqa {{.*#+}} xmm2 = [3,2,1,0,7,6,5,4,11,10,9,8,15,14,13,12]
221; CHECK-SSSE3-NEXT:    pshufb %xmm2, %xmm0
222; CHECK-SSSE3-NEXT:    pshufb %xmm2, %xmm1
223; CHECK-SSSE3-NEXT:    retq
224;
225; CHECK-AVX-LABEL: test5:
226; CHECK-AVX:       # %bb.0: # %entry
227; CHECK-AVX-NEXT:    vpshufb {{.*#+}} ymm0 = ymm0[3,2,1,0,7,6,5,4,11,10,9,8,15,14,13,12,19,18,17,16,23,22,21,20,27,26,25,24,31,30,29,28]
228; CHECK-AVX-NEXT:    retq
229;
230; CHECK-WIDE-AVX-LABEL: test5:
231; CHECK-WIDE-AVX:       # %bb.0: # %entry
232; CHECK-WIDE-AVX-NEXT:    vpshufb {{.*#+}} ymm0 = ymm0[3,2,1,0,7,6,5,4,11,10,9,8,15,14,13,12,19,18,17,16,23,22,21,20,27,26,25,24,31,30,29,28]
233; CHECK-WIDE-AVX-NEXT:    retq
234entry:
235  %r = call <8 x i32> @llvm.bswap.v8i32(<8 x i32> %v)
236  ret <8 x i32> %r
237}
238
239define <4 x i64> @test6(<4 x i64> %v) {
240; CHECK-NOSSSE3-LABEL: test6:
241; CHECK-NOSSSE3:       # %bb.0: # %entry
242; CHECK-NOSSSE3-NEXT:    pxor %xmm2, %xmm2
243; CHECK-NOSSSE3-NEXT:    movdqa %xmm0, %xmm3
244; CHECK-NOSSSE3-NEXT:    punpckhbw {{.*#+}} xmm3 = xmm3[8],xmm2[8],xmm3[9],xmm2[9],xmm3[10],xmm2[10],xmm3[11],xmm2[11],xmm3[12],xmm2[12],xmm3[13],xmm2[13],xmm3[14],xmm2[14],xmm3[15],xmm2[15]
245; CHECK-NOSSSE3-NEXT:    pshufd {{.*#+}} xmm3 = xmm3[2,3,0,1]
246; CHECK-NOSSSE3-NEXT:    pshuflw {{.*#+}} xmm3 = xmm3[3,2,1,0,4,5,6,7]
247; CHECK-NOSSSE3-NEXT:    pshufhw {{.*#+}} xmm3 = xmm3[0,1,2,3,7,6,5,4]
248; CHECK-NOSSSE3-NEXT:    punpcklbw {{.*#+}} xmm0 = xmm0[0],xmm2[0],xmm0[1],xmm2[1],xmm0[2],xmm2[2],xmm0[3],xmm2[3],xmm0[4],xmm2[4],xmm0[5],xmm2[5],xmm0[6],xmm2[6],xmm0[7],xmm2[7]
249; CHECK-NOSSSE3-NEXT:    pshufd {{.*#+}} xmm0 = xmm0[2,3,0,1]
250; CHECK-NOSSSE3-NEXT:    pshuflw {{.*#+}} xmm0 = xmm0[3,2,1,0,4,5,6,7]
251; CHECK-NOSSSE3-NEXT:    pshufhw {{.*#+}} xmm0 = xmm0[0,1,2,3,7,6,5,4]
252; CHECK-NOSSSE3-NEXT:    packuswb %xmm3, %xmm0
253; CHECK-NOSSSE3-NEXT:    movdqa %xmm1, %xmm3
254; CHECK-NOSSSE3-NEXT:    punpckhbw {{.*#+}} xmm3 = xmm3[8],xmm2[8],xmm3[9],xmm2[9],xmm3[10],xmm2[10],xmm3[11],xmm2[11],xmm3[12],xmm2[12],xmm3[13],xmm2[13],xmm3[14],xmm2[14],xmm3[15],xmm2[15]
255; CHECK-NOSSSE3-NEXT:    pshufd {{.*#+}} xmm3 = xmm3[2,3,0,1]
256; CHECK-NOSSSE3-NEXT:    pshuflw {{.*#+}} xmm3 = xmm3[3,2,1,0,4,5,6,7]
257; CHECK-NOSSSE3-NEXT:    pshufhw {{.*#+}} xmm3 = xmm3[0,1,2,3,7,6,5,4]
258; CHECK-NOSSSE3-NEXT:    punpcklbw {{.*#+}} xmm1 = xmm1[0],xmm2[0],xmm1[1],xmm2[1],xmm1[2],xmm2[2],xmm1[3],xmm2[3],xmm1[4],xmm2[4],xmm1[5],xmm2[5],xmm1[6],xmm2[6],xmm1[7],xmm2[7]
259; CHECK-NOSSSE3-NEXT:    pshufd {{.*#+}} xmm1 = xmm1[2,3,0,1]
260; CHECK-NOSSSE3-NEXT:    pshuflw {{.*#+}} xmm1 = xmm1[3,2,1,0,4,5,6,7]
261; CHECK-NOSSSE3-NEXT:    pshufhw {{.*#+}} xmm1 = xmm1[0,1,2,3,7,6,5,4]
262; CHECK-NOSSSE3-NEXT:    packuswb %xmm3, %xmm1
263; CHECK-NOSSSE3-NEXT:    retq
264;
265; CHECK-SSSE3-LABEL: test6:
266; CHECK-SSSE3:       # %bb.0: # %entry
267; CHECK-SSSE3-NEXT:    movdqa {{.*#+}} xmm2 = [7,6,5,4,3,2,1,0,15,14,13,12,11,10,9,8]
268; CHECK-SSSE3-NEXT:    pshufb %xmm2, %xmm0
269; CHECK-SSSE3-NEXT:    pshufb %xmm2, %xmm1
270; CHECK-SSSE3-NEXT:    retq
271;
272; CHECK-AVX-LABEL: test6:
273; CHECK-AVX:       # %bb.0: # %entry
274; CHECK-AVX-NEXT:    vpshufb {{.*#+}} ymm0 = ymm0[7,6,5,4,3,2,1,0,15,14,13,12,11,10,9,8,23,22,21,20,19,18,17,16,31,30,29,28,27,26,25,24]
275; CHECK-AVX-NEXT:    retq
276;
277; CHECK-WIDE-AVX-LABEL: test6:
278; CHECK-WIDE-AVX:       # %bb.0: # %entry
279; CHECK-WIDE-AVX-NEXT:    vpshufb {{.*#+}} ymm0 = ymm0[7,6,5,4,3,2,1,0,15,14,13,12,11,10,9,8,23,22,21,20,19,18,17,16,31,30,29,28,27,26,25,24]
280; CHECK-WIDE-AVX-NEXT:    retq
281entry:
282  %r = call <4 x i64> @llvm.bswap.v4i64(<4 x i64> %v)
283  ret <4 x i64> %r
284}
285
286declare <4 x i16> @llvm.bswap.v4i16(<4 x i16>)
287
288define <4 x i16> @test7(<4 x i16> %v) {
289; CHECK-NOSSSE3-LABEL: test7:
290; CHECK-NOSSSE3:       # %bb.0: # %entry
291; CHECK-NOSSSE3-NEXT:    pxor %xmm1, %xmm1
292; CHECK-NOSSSE3-NEXT:    movdqa %xmm0, %xmm2
293; CHECK-NOSSSE3-NEXT:    punpckhbw {{.*#+}} xmm2 = xmm2[8],xmm1[8],xmm2[9],xmm1[9],xmm2[10],xmm1[10],xmm2[11],xmm1[11],xmm2[12],xmm1[12],xmm2[13],xmm1[13],xmm2[14],xmm1[14],xmm2[15],xmm1[15]
294; CHECK-NOSSSE3-NEXT:    pshuflw {{.*#+}} xmm2 = xmm2[3,2,1,0,4,5,6,7]
295; CHECK-NOSSSE3-NEXT:    pshufhw {{.*#+}} xmm2 = xmm2[0,1,2,3,7,6,5,4]
296; CHECK-NOSSSE3-NEXT:    punpcklbw {{.*#+}} xmm0 = xmm0[0],xmm1[0],xmm0[1],xmm1[1],xmm0[2],xmm1[2],xmm0[3],xmm1[3],xmm0[4],xmm1[4],xmm0[5],xmm1[5],xmm0[6],xmm1[6],xmm0[7],xmm1[7]
297; CHECK-NOSSSE3-NEXT:    pshuflw {{.*#+}} xmm0 = xmm0[3,2,1,0,4,5,6,7]
298; CHECK-NOSSSE3-NEXT:    pshufhw {{.*#+}} xmm0 = xmm0[0,1,2,3,7,6,5,4]
299; CHECK-NOSSSE3-NEXT:    packuswb %xmm2, %xmm0
300; CHECK-NOSSSE3-NEXT:    psrld $16, %xmm0
301; CHECK-NOSSSE3-NEXT:    retq
302;
303; CHECK-SSSE3-LABEL: test7:
304; CHECK-SSSE3:       # %bb.0: # %entry
305; CHECK-SSSE3-NEXT:    pshufb {{.*#+}} xmm0 = xmm0[1,0],zero,zero,xmm0[5,4],zero,zero,xmm0[9,8],zero,zero,xmm0[13,12],zero,zero
306; CHECK-SSSE3-NEXT:    retq
307;
308; CHECK-AVX-LABEL: test7:
309; CHECK-AVX:       # %bb.0: # %entry
310; CHECK-AVX-NEXT:    vpshufb {{.*#+}} xmm0 = xmm0[1,0],zero,zero,xmm0[5,4],zero,zero,xmm0[9,8],zero,zero,xmm0[13,12],zero,zero
311; CHECK-AVX-NEXT:    retq
312;
313; CHECK-WIDE-AVX-LABEL: test7:
314; CHECK-WIDE-AVX:       # %bb.0: # %entry
315; CHECK-WIDE-AVX-NEXT:    vpshufb {{.*#+}} xmm0 = xmm0[1,0,3,2,5,4,7,6,9,8,11,10,13,12,15,14]
316; CHECK-WIDE-AVX-NEXT:    retq
317entry:
318  %r = call <4 x i16> @llvm.bswap.v4i16(<4 x i16> %v)
319  ret <4 x i16> %r
320}
321
322;
323; Double BSWAP -> Identity
324;
325
326define <8 x i16> @identity_v8i16(<8 x i16> %v) {
327; CHECK-ALL-LABEL: identity_v8i16:
328; CHECK-ALL:       # %bb.0: # %entry
329; CHECK-ALL-NEXT:    retq
330entry:
331  %bs1 = call <8 x i16> @llvm.bswap.v8i16(<8 x i16> %v)
332  %bs2 = call <8 x i16> @llvm.bswap.v8i16(<8 x i16> %bs1)
333  ret <8 x i16> %bs2
334}
335
336define <4 x i32> @identity_v4i32(<4 x i32> %v) {
337; CHECK-ALL-LABEL: identity_v4i32:
338; CHECK-ALL:       # %bb.0: # %entry
339; CHECK-ALL-NEXT:    retq
340entry:
341  %bs1 = call <4 x i32> @llvm.bswap.v4i32(<4 x i32> %v)
342  %bs2 = call <4 x i32> @llvm.bswap.v4i32(<4 x i32> %bs1)
343  ret <4 x i32> %bs2
344}
345
346define <2 x i64> @identity_v2i64(<2 x i64> %v) {
347; CHECK-ALL-LABEL: identity_v2i64:
348; CHECK-ALL:       # %bb.0: # %entry
349; CHECK-ALL-NEXT:    retq
350entry:
351  %bs1 = call <2 x i64> @llvm.bswap.v2i64(<2 x i64> %v)
352  %bs2 = call <2 x i64> @llvm.bswap.v2i64(<2 x i64> %bs1)
353  ret <2 x i64> %bs2
354}
355
356define <16 x i16> @identity_v16i16(<16 x i16> %v) {
357; CHECK-ALL-LABEL: identity_v16i16:
358; CHECK-ALL:       # %bb.0: # %entry
359; CHECK-ALL-NEXT:    retq
360entry:
361  %bs1 = call <16 x i16> @llvm.bswap.v16i16(<16 x i16> %v)
362  %bs2 = call <16 x i16> @llvm.bswap.v16i16(<16 x i16> %bs1)
363  ret <16 x i16> %bs2
364}
365
366define <8 x i32> @identity_v8i32(<8 x i32> %v) {
367; CHECK-ALL-LABEL: identity_v8i32:
368; CHECK-ALL:       # %bb.0: # %entry
369; CHECK-ALL-NEXT:    retq
370entry:
371  %bs1 = call <8 x i32> @llvm.bswap.v8i32(<8 x i32> %v)
372  %bs2 = call <8 x i32> @llvm.bswap.v8i32(<8 x i32> %bs1)
373  ret <8 x i32> %bs2
374}
375
376define <4 x i64> @identity_v4i64(<4 x i64> %v) {
377; CHECK-ALL-LABEL: identity_v4i64:
378; CHECK-ALL:       # %bb.0: # %entry
379; CHECK-ALL-NEXT:    retq
380entry:
381  %bs1 = call <4 x i64> @llvm.bswap.v4i64(<4 x i64> %v)
382  %bs2 = call <4 x i64> @llvm.bswap.v4i64(<4 x i64> %bs1)
383  ret <4 x i64> %bs2
384}
385
386define <4 x i16> @identity_v4i16(<4 x i16> %v) {
387; CHECK-ALL-LABEL: identity_v4i16:
388; CHECK-ALL:       # %bb.0: # %entry
389; CHECK-ALL-NEXT:    retq
390entry:
391  %bs1 = call <4 x i16> @llvm.bswap.v4i16(<4 x i16> %v)
392  %bs2 = call <4 x i16> @llvm.bswap.v4i16(<4 x i16> %bs1)
393  ret <4 x i16> %bs2
394}
395
396;
397; Constant Folding
398;
399
400define <8 x i16> @fold_v8i16() {
401; CHECK-SSE-LABEL: fold_v8i16:
402; CHECK-SSE:       # %bb.0: # %entry
403; CHECK-SSE-NEXT:    movaps {{.*#+}} xmm0 = [0,256,65535,512,65023,1024,64511,1536]
404; CHECK-SSE-NEXT:    retq
405;
406; CHECK-AVX-LABEL: fold_v8i16:
407; CHECK-AVX:       # %bb.0: # %entry
408; CHECK-AVX-NEXT:    vmovaps {{.*#+}} xmm0 = [0,256,65535,512,65023,1024,64511,1536]
409; CHECK-AVX-NEXT:    retq
410;
411; CHECK-WIDE-AVX-LABEL: fold_v8i16:
412; CHECK-WIDE-AVX:       # %bb.0: # %entry
413; CHECK-WIDE-AVX-NEXT:    vmovaps {{.*#+}} xmm0 = [0,256,65535,512,65023,1024,64511,1536]
414; CHECK-WIDE-AVX-NEXT:    retq
415entry:
416  %r = call <8 x i16> @llvm.bswap.v8i16(<8 x i16> <i16 0, i16 1, i16 -1, i16 2, i16 -3, i16 4, i16 -5, i16 6>)
417  ret <8 x i16> %r
418}
419
420define <4 x i32> @fold_v4i32() {
421; CHECK-SSE-LABEL: fold_v4i32:
422; CHECK-SSE:       # %bb.0: # %entry
423; CHECK-SSE-NEXT:    movaps {{.*#+}} xmm0 = [0,4294967295,33554432,4261412863]
424; CHECK-SSE-NEXT:    retq
425;
426; CHECK-AVX-LABEL: fold_v4i32:
427; CHECK-AVX:       # %bb.0: # %entry
428; CHECK-AVX-NEXT:    vmovaps {{.*#+}} xmm0 = [0,4294967295,33554432,4261412863]
429; CHECK-AVX-NEXT:    retq
430;
431; CHECK-WIDE-AVX-LABEL: fold_v4i32:
432; CHECK-WIDE-AVX:       # %bb.0: # %entry
433; CHECK-WIDE-AVX-NEXT:    vmovaps {{.*#+}} xmm0 = [0,4294967295,33554432,4261412863]
434; CHECK-WIDE-AVX-NEXT:    retq
435entry:
436  %r = call <4 x i32> @llvm.bswap.v4i32(<4 x i32> <i32 0, i32 -1, i32 2, i32 -3>)
437  ret <4 x i32> %r
438}
439
440define <2 x i64> @fold_v2i64() {
441; CHECK-SSE-LABEL: fold_v2i64:
442; CHECK-SSE:       # %bb.0: # %entry
443; CHECK-SSE-NEXT:    movaps {{.*#+}} xmm0 = [18374686479671623680,18446744073709551615]
444; CHECK-SSE-NEXT:    retq
445;
446; CHECK-AVX-LABEL: fold_v2i64:
447; CHECK-AVX:       # %bb.0: # %entry
448; CHECK-AVX-NEXT:    vmovaps {{.*#+}} xmm0 = [18374686479671623680,18446744073709551615]
449; CHECK-AVX-NEXT:    retq
450;
451; CHECK-WIDE-AVX-LABEL: fold_v2i64:
452; CHECK-WIDE-AVX:       # %bb.0: # %entry
453; CHECK-WIDE-AVX-NEXT:    vmovaps {{.*#+}} xmm0 = [18374686479671623680,18446744073709551615]
454; CHECK-WIDE-AVX-NEXT:    retq
455entry:
456  %r = call <2 x i64> @llvm.bswap.v2i64(<2 x i64> <i64 255, i64 -1>)
457  ret <2 x i64> %r
458}
459
460define <16 x i16> @fold_v16i16() {
461; CHECK-SSE-LABEL: fold_v16i16:
462; CHECK-SSE:       # %bb.0: # %entry
463; CHECK-SSE-NEXT:    movaps {{.*#+}} xmm0 = [0,256,65535,512,65023,1024,64511,1536]
464; CHECK-SSE-NEXT:    movaps {{.*#+}} xmm1 = [63999,2048,63487,2560,62975,3072,62463,3584]
465; CHECK-SSE-NEXT:    retq
466;
467; CHECK-AVX-LABEL: fold_v16i16:
468; CHECK-AVX:       # %bb.0: # %entry
469; CHECK-AVX-NEXT:    vmovaps {{.*#+}} ymm0 = [0,256,65535,512,65023,1024,64511,1536,63999,2048,63487,2560,62975,3072,62463,3584]
470; CHECK-AVX-NEXT:    retq
471;
472; CHECK-WIDE-AVX-LABEL: fold_v16i16:
473; CHECK-WIDE-AVX:       # %bb.0: # %entry
474; CHECK-WIDE-AVX-NEXT:    vmovaps {{.*#+}} ymm0 = [0,256,65535,512,65023,1024,64511,1536,63999,2048,63487,2560,62975,3072,62463,3584]
475; CHECK-WIDE-AVX-NEXT:    retq
476entry:
477  %r = call <16 x i16> @llvm.bswap.v16i16(<16 x i16> <i16 0, i16 1, i16 -1, i16 2, i16 -3, i16 4, i16 -5, i16 6, i16 -7, i16 8, i16 -9, i16 10, i16 -11, i16 12, i16 -13, i16 14>)
478  ret <16 x i16> %r
479}
480
481define <8 x i32> @fold_v8i32() {
482; CHECK-SSE-LABEL: fold_v8i32:
483; CHECK-SSE:       # %bb.0: # %entry
484; CHECK-SSE-NEXT:    movaps {{.*#+}} xmm0 = [0,16777216,4294967295,33554432]
485; CHECK-SSE-NEXT:    movaps {{.*#+}} xmm1 = [4261412863,67108864,4227858431,100663296]
486; CHECK-SSE-NEXT:    retq
487;
488; CHECK-AVX-LABEL: fold_v8i32:
489; CHECK-AVX:       # %bb.0: # %entry
490; CHECK-AVX-NEXT:    vmovaps {{.*#+}} ymm0 = [0,16777216,4294967295,33554432,4261412863,67108864,4227858431,100663296]
491; CHECK-AVX-NEXT:    retq
492;
493; CHECK-WIDE-AVX-LABEL: fold_v8i32:
494; CHECK-WIDE-AVX:       # %bb.0: # %entry
495; CHECK-WIDE-AVX-NEXT:    vmovaps {{.*#+}} ymm0 = [0,16777216,4294967295,33554432,4261412863,67108864,4227858431,100663296]
496; CHECK-WIDE-AVX-NEXT:    retq
497entry:
498  %r = call <8 x i32> @llvm.bswap.v8i32(<8 x i32> <i32 0, i32 1, i32 -1, i32 2, i32 -3, i32 4, i32 -5, i32 6>)
499  ret <8 x i32> %r
500}
501
502define <4 x i64> @fold_v4i64() {
503; CHECK-SSE-LABEL: fold_v4i64:
504; CHECK-SSE:       # %bb.0: # %entry
505; CHECK-SSE-NEXT:    movaps {{.*#+}} xmm0 = [18374686479671623680,18446744073709551615]
506; CHECK-SSE-NEXT:    movaps {{.*#+}} xmm1 = [18446462598732840960,72056494526300160]
507; CHECK-SSE-NEXT:    retq
508;
509; CHECK-AVX-LABEL: fold_v4i64:
510; CHECK-AVX:       # %bb.0: # %entry
511; CHECK-AVX-NEXT:    vmovaps {{.*#+}} ymm0 = [18374686479671623680,18446744073709551615,18446462598732840960,72056494526300160]
512; CHECK-AVX-NEXT:    retq
513;
514; CHECK-WIDE-AVX-LABEL: fold_v4i64:
515; CHECK-WIDE-AVX:       # %bb.0: # %entry
516; CHECK-WIDE-AVX-NEXT:    vmovaps {{.*#+}} ymm0 = [18374686479671623680,18446744073709551615,18446462598732840960,72056494526300160]
517; CHECK-WIDE-AVX-NEXT:    retq
518entry:
519  %r = call <4 x i64> @llvm.bswap.v4i64(<4 x i64> <i64 255, i64 -1, i64 65535, i64 16776960>)
520  ret <4 x i64> %r
521}
522