[X86][SSE] Added dual vector truncation tests.
[oota-llvm.git] / test / CodeGen / X86 / vector-trunc.ll
1 ; RUN: llc < %s -mtriple=x86_64-unknown-unknown -mcpu=x86-64 -mattr=+sse2 | FileCheck %s --check-prefix=SSE --check-prefix=SSE2
2 ; RUN: llc < %s -mtriple=x86_64-unknown-unknown -mcpu=x86-64 -mattr=+ssse3 | FileCheck %s --check-prefix=SSE --check-prefix=SSSE3
3 ; RUN: llc < %s -mtriple=x86_64-unknown-unknown -mcpu=x86-64 -mattr=+sse4.1 | FileCheck %s --check-prefix=SSE --check-prefix=SSE41
4 ; RUN: llc < %s -mtriple=x86_64-unknown-unknown -mcpu=x86-64 -mattr=+avx | FileCheck %s --check-prefix=AVX --check-prefix=AVX1
5
6 define <4 x i32> @trunc2x2i64(<2 x i64> %a, <2 x i64> %b) {
7 ; SSE-LABEL:  trunc2x2i64:
8 ; SSE:        # BB#0: # %entry
9 ; SSE-NEXT:   shufps {{.*#+}} xmm0 = xmm0[0,2],xmm1[0,2]
10 ; SSE-NEXT:   retq
11
12 ; AVX-LABEL:  trunc2x2i64:
13 ; AVX:        # BB#0: # %entry
14 ; AVX-NEXT:   vshufps {{.*#+}} xmm0 = xmm0[0,2],xmm1[0,2]
15 ; AVX-NEXT:   retq
16
17 entry:
18   %0 = trunc <2 x i64> %a to <2 x i32>
19   %1 = trunc <2 x i64> %b to <2 x i32>
20   %2 = shufflevector <2 x i32> %0, <2 x i32> %1, <4 x i32> <i32 0, i32 1, i32 2, i32 3>
21   ret <4 x i32> %2
22 }
23
24 define i64 @trunc2i64(<2 x i64> %inval) {
25 ; SSE-LABEL:  trunc2i64:
26 ; SSE:        # BB#0: # %entry
27 ; SSE-NEXT:   pshufd {{.*#+}} xmm0 = xmm0[0,2,2,3]
28 ; SSE-NEXT:   movd %xmm0, %rax
29 ; SSE-NEXT:   retq
30
31 ; AVX-LABEL:  trunc2i64:
32 ; AVX:        # BB#0: # %entry
33 ; AVX-NEXT:   vpshufd {{.*#+}} xmm0 = xmm0[0,2,2,3]
34 ; AVX-NEXT:   vmovq %xmm0, %rax
35 ; AVX-NEXT:   retq
36
37 entry:
38   %0 = trunc <2 x i64> %inval to <2 x i32>
39   %1 = bitcast <2 x i32> %0 to i64
40   ret i64 %1
41 }
42
43 define <8 x i16> @trunc2x4i32(<4 x i32> %a, <4 x i32> %b) {
44 ; SSE2-LABEL:  trunc2x4i32:
45 ; SSE2:        # BB#0: # %entry
46 ; SSE2-NEXT:   pshuflw {{.*#+}} xmm1 = xmm1[0,2,2,3,4,5,6,7]
47 ; SSE2-NEXT:   pshufhw {{.*#+}} xmm1 = xmm1[0,1,2,3,4,6,6,7]
48 ; SSE2-NEXT:   pshufd  {{.*#+}} xmm1 = xmm1[0,2,2,3]
49 ; SSE2-NEXT:   pshuflw {{.*#+}} xmm0 = xmm0[0,2,2,3,4,5,6,7]
50 ; SSE2-NEXT:   pshufhw {{.*#+}} xmm0 = xmm0[0,1,2,3,4,6,6,7]
51 ; SSE2-NEXT:   pshufd  {{.*#+}} xmm0 = xmm0[0,2,2,3]
52 ; SSE2-NEXT:   punpcklqdq {{.*#+}} xmm0 = xmm0[0],xmm1[0]
53 ; SSE2-NEXT:   retq
54
55 ; SSSE3-LABEL:  trunc2x4i32:
56 ; SSSE3:        # BB#0: # %entry
57 ; SSSE3-NEXT:   movdqa {{.*#+}} xmm2 = [0,1,4,5,8,9,12,13,8,9,12,13,12,13,14,15]
58 ; SSSE3-NEXT:   pshufb %xmm2, %xmm1
59 ; SSSE3-NEXT:   pshufb %xmm2, %xmm0
60 ; SSSE3-NEXT:   punpcklqdq {{.*#+}} xmm0 = xmm0[0],xmm1[0]
61 ; SSSE3-NEXT:   retq
62
63 ; SSE41-LABEL:  trunc2x4i32:
64 ; SSE41:        # BB#0: # %entry
65 ; SSE41-NEXT:   movdqa {{.*#+}} xmm2 = [0,1,4,5,8,9,12,13,8,9,12,13,12,13,14,15]
66 ; SSE41-NEXT:   pshufb %xmm2, %xmm1
67 ; SSE41-NEXT:   pshufb %xmm2, %xmm0
68 ; SSE41-NEXT:   punpcklqdq {{.*#+}} xmm0 = xmm0[0],xmm1[0]
69 ; SSE41-NEXT:   retq
70
71 ; AVX-LABEL:  trunc2x4i32:
72 ; AVX:        # BB#0: # %entry
73 ; AVX-NEXT:   vmovdqa {{.*#+}} xmm2 = [0,1,4,5,8,9,12,13,8,9,12,13,12,13,14,15]
74 ; AVX-NEXT:   vpshufb %xmm2, %xmm1, %xmm1
75 ; AVX-NEXT:   vpshufb %xmm2, %xmm0, %xmm0
76 ; AVX-NEXT:   vpunpcklqdq {{.*#+}} xmm0 = xmm0[0],xmm1[0]
77 ; AVX-NEXT:   retq
78
79 entry:
80   %0 = trunc <4 x i32> %a to <4 x i16>
81   %1 = trunc <4 x i32> %b to <4 x i16>
82   %2 = shufflevector <4 x i16> %0, <4 x i16> %1, <8 x i32> <i32 0, i32 1, i32 2, i32 3, i32 4, i32 5, i32 6, i32 7>
83   ret <8 x i16> %2
84 }
85
86 ; PR15524 http://llvm.org/bugs/show_bug.cgi?id=15524
87 define i64 @trunc4i32(<4 x i32> %inval) {
88 ; SSE2-LABEL:  trunc4i32:
89 ; SSE2:        # BB#0: # %entry
90 ; SSE2-NEXT:   pshuflw {{.*#+}} xmm0 = xmm0[0,2,2,3,4,5,6,7]
91 ; SSE2-NEXT:   pshufhw {{.*#+}} xmm0 = xmm0[0,1,2,3,4,6,6,7]
92 ; SSE2-NEXT:   pshufd {{.*#+}} xmm0 = xmm0[0,2,2,3]
93 ; SSE2-NEXT:   movd %xmm0, %rax
94 ; SSE2-NEXT:   retq
95
96 ; SSSE3-LABEL: trunc4i32:
97 ; SSSE3:       # BB#0: # %entry
98 ; SSSE3-NEXT:  pshufb {{.*#+}} xmm0 = xmm0[0,1,4,5,8,9,12,13,8,9,12,13,12,13,14,15]
99 ; SSSE3-NEXT:  movd %xmm0, %rax
100 ; SSSE3-NEXT:  retq
101
102 ; SSE41-LABEL: trunc4i32:
103 ; SSE41:       # BB#0: # %entry
104 ; SSE41-NEXT:  pshufb {{.*#+}} xmm0 = xmm0[0,1,4,5,8,9,12,13,8,9,12,13,12,13,14,15]
105 ; SSE41-NEXT:  movd %xmm0, %rax
106 ; SSE41-NEXT:  retq
107
108 ; AVX-LABEL:  trunc4i32:
109 ; AVX:        # BB#0: # %entry
110 ; AVX-NEXT:   vpshufb {{.*#+}} xmm0 = xmm0[0,1,4,5,8,9,12,13,8,9,12,13,12,13,14,15]
111 ; AVX-NEXT:   vmovq %xmm0, %rax
112 ; AVX-NEXT:   retq
113
114 entry:
115   %0 = trunc <4 x i32> %inval to <4 x i16>
116   %1 = bitcast <4 x i16> %0 to i64
117   ret i64 %1
118 }
119
120 define <16 x i8> @trunc2x8i16(<8 x i16> %a, <8 x i16> %b) {
121 ; SSE2-LABEL:  trunc2x8i16:
122 ; SSE2:        # BB#0: # %entry
123 ; SSE2-NEXT:   movdqa {{.*#+}} xmm2 = [255,255,255,255,255,255,255,255]
124 ; SSE2-NEXT:   pand %xmm2, %xmm1
125 ; SSE2-NEXT:   pand %xmm2, %xmm0
126 ; SSE2-NEXT:   packuswb %xmm1, %xmm0
127 ; SSE2-NEXT:   retq
128
129 ; SSSE3-LABEL:  trunc2x8i16:
130 ; SSSE3:        # BB#0: # %entry
131 ; SSSE3-NEXT:   pshufb {{.*#+}} xmm1 = zero,zero,zero,zero,zero,zero,zero,zero,xmm1[0,2,4,6,8,10,12,14]
132 ; SSSE3-NEXT:   pshufb {{.*#+}} xmm0 = xmm0[0,2,4,6,8,10,12,14],zero,zero,zero,zero,zero,zero,zero,zero
133 ; SSSE3-NEXT:   por %xmm1, %xmm0
134 ; SSSE3-NEXT:   retq
135
136 ; SSE41-LABEL:  trunc2x8i16:
137 ; SSE41:        # BB#0: # %entry
138 ; SSE41-NEXT:   pshufb {{.*#+}} xmm1 = zero,zero,zero,zero,zero,zero,zero,zero,xmm1[0,2,4,6,8,10,12,14]
139 ; SSE41-NEXT:   pshufb {{.*#+}} xmm0 = xmm0[0,2,4,6,8,10,12,14],zero,zero,zero,zero,zero,zero,zero,zero
140 ; SSE41-NEXT:   por %xmm1, %xmm0
141 ; SSE41-NEXT:   retq
142
143 ; AVX-LABEL:  trunc2x8i16:
144 ; AVX:        # BB#0: # %entry
145 ; AVX-NEXT:   vpshufb {{.*#+}} xmm1 = zero,zero,zero,zero,zero,zero,zero,zero,xmm1[0,2,4,6,8,10,12,14]
146 ; AVX-NEXT:   vpshufb {{.*#+}} xmm0 = xmm0[0,2,4,6,8,10,12,14],zero,zero,zero,zero,zero,zero,zero,zero
147 ; AVX-NEXT:   vpor %xmm1, %xmm0, %xmm0
148 ; AVX-NEXT:   retq
149
150 entry:
151   %0 = trunc <8 x i16> %a to <8 x i8>
152   %1 = trunc <8 x i16> %b to <8 x i8>
153   %2 = shufflevector <8 x i8> %0, <8 x i8> %1, <16 x i32> <i32 0, i32 1, i32 2, i32 3, i32 4, i32 5, i32 6, i32 7, i32 8, i32 9, i32 10, i32 11, i32 12, i32 13, i32 14, i32 15>
154   ret <16 x i8> %2
155 }
156
157 ; PR15524 http://llvm.org/bugs/show_bug.cgi?id=15524
158 define i64 @trunc8i16(<8 x i16> %inval) {
159 ; SSE2-LABEL:  trunc8i16:
160 ; SSE2:        # BB#0: # %entry
161 ; SSE2-NEXT:   pand .LCP{{.*}}(%rip), %xmm0
162 ; SSE2-NEXT:   packuswb %xmm0, %xmm0
163 ; SSE2-NEXT:   movd %xmm0, %rax
164 ; SSE2-NEXT:   retq
165
166 ; SSSE3-LABEL: trunc8i16:
167 ; SSSE3:       # BB#0: # %entry
168 ; SSSE3-NEXT:  pshufb {{.*#+}} xmm0 = xmm0[0,2,4,6,8,10,12,14,u,u,u,u,u,u,u,u]
169 ; SSSE3-NEXT:  movd %xmm0, %rax
170 ; SSSE3-NEXT:  retq
171
172 ; SSE41-LABEL: trunc8i16:
173 ; SSE41:       # BB#0: # %entry
174 ; SSE41-NEXT:  pshufb {{.*#+}} xmm0 = xmm0[0,2,4,6,8,10,12,14,u,u,u,u,u,u,u,u]
175 ; SSE41-NEXT:  movd %xmm0, %rax
176 ; SSE41-NEXT:  retq
177
178 ; AVX-LABEL:  trunc8i16:
179 ; AVX:        # BB#0: # %entry
180 ; AVX-NEXT:   vpshufb {{.*#+}} xmm0 = xmm0[0,2,4,6,8,10,12,14,u,u,u,u,u,u,u,u]
181 ; AVX-NEXT:   vmovq %xmm0, %rax
182 ; AVX-NEXT:   retq
183
184 entry:
185   %0 = trunc <8 x i16> %inval to <8 x i8>
186   %1 = bitcast <8 x i8> %0 to i64
187   ret i64 %1
188 }