[DAGCombiner] Improve the shuffle-vector folding logic.
[oota-llvm.git] / test / CodeGen / X86 / combine-vec-shuffle-5.ll
1 ; RUN: llc < %s -mtriple=x86_64-unknown-linux-gnu -mcpu=corei7 | FileCheck %s
2
3 ; Verify that the DAGCombiner correctly folds all the shufflevector pairs
4 ; into a single shuffle operation.
5
6 define <4 x float> @test1(<4 x float> %a, <4 x float> %b) {
7   %1 = shufflevector <4 x float> %a, <4 x float> %b, <4 x i32> <i32 4, i32 1, i32 6, i32 3>
8   %2 = shufflevector <4 x float> %b, <4 x float> %1, <4 x i32> <i32 4, i32 1, i32 6, i32 3>
9   ret <4 x float> %2
10 }
11 ; CHECK-LABEL: test1
12 ; Mask: [0,1,2,3]
13 ; CHECK: movaps
14 ; CHECK: ret
15
16 define <4 x float> @test2(<4 x float> %a, <4 x float> %b) {
17   %1 = shufflevector <4 x float> %a, <4 x float> %b, <4 x i32> <i32 0, i32 5, i32 2, i32 7>
18   %2 = shufflevector <4 x float> %b, <4 x float> %1, <4 x i32> <i32 4, i32 5, i32 2, i32 7>
19   ret <4 x float> %2
20 }
21 ; CHECK-LABEL: test2
22 ; Mask: [0,5,6,7]
23 ; CHECK: movss
24 ; CHECK: ret
25
26 define <4 x float> @test3(<4 x float> %a, <4 x float> %b) {
27   %1 = shufflevector <4 x float> %a, <4 x float> %b, <4 x i32> <i32 0, i32 5, i32 1, i32 7>
28   %2 = shufflevector <4 x float> %b, <4 x float> %1, <4 x i32> <i32 4, i32 6, i32 0, i32 5>
29   ret <4 x float> %2
30 }
31 ; CHECK-LABEL: test3
32 ; Mask: [0,1,4,5]
33 ; CHECK: movlhps
34 ; CHECK: ret
35
36 define <4 x float> @test4(<4 x float> %a, <4 x float> %b) {
37   %1 = shufflevector <4 x float> %a, <4 x float> %b, <4 x i32> <i32 2, i32 3, i32 5, i32 5>
38   %2 = shufflevector <4 x float> %b, <4 x float> %1, <4 x i32> <i32 2, i32 3, i32 4, i32 5>
39   ret <4 x float> %2
40 }
41 ; CHECK-LABEL: test4
42 ; Mask: [6,7,2,3]
43 ; CHECK: movhlps
44 ; CHECK-NEXT: ret
45
46 define <4 x float> @test5(<4 x float> %a, <4 x float> %b) {
47   %1 = shufflevector <4 x float> %a, <4 x float> %b, <4 x i32> <i32 4, i32 1, i32 6, i32 3>
48   %2 = shufflevector <4 x float> %b, <4 x float> %1, <4 x i32> <i32 4, i32 5, i32 6, i32 3>
49   ret <4 x float> %2
50 }
51 ; CHECK-LABEL: test5
52 ; Mask: [4,1,6,7]
53 ; CHECK: blendps $13
54 ; CHECK: ret
55
56
57 define <4 x i32> @test6(<4 x i32> %a, <4 x i32> %b) {
58   %1 = shufflevector <4 x i32> %a, <4 x i32> %b, <4 x i32> <i32 4, i32 1, i32 6, i32 3>
59   %2 = shufflevector <4 x i32> %b, <4 x i32> %1, <4 x i32> <i32 4, i32 1, i32 6, i32 3>
60   ret <4 x i32> %2
61 }
62 ; CHECK-LABEL: test6
63 ; Mask: [4,5,6,7]
64 ; CHECK: movaps
65 ; CHECK: ret
66
67 define <4 x i32> @test7(<4 x i32> %a, <4 x i32> %b) {
68   %1 = shufflevector <4 x i32> %a, <4 x i32> %b, <4 x i32> <i32 0, i32 5, i32 2, i32 7>
69   %2 = shufflevector <4 x i32> %b, <4 x i32> %1, <4 x i32> <i32 4, i32 5, i32 2, i32 7>
70   ret <4 x i32> %2
71 }
72 ; CHECK-LABEL: test7
73 ; Mask: [0,5,6,7]
74 ; CHECK: movss
75 ; CHECK: ret
76
77 define <4 x i32> @test8(<4 x i32> %a, <4 x i32> %b) {
78   %1 = shufflevector <4 x i32> %a, <4 x i32> %b, <4 x i32> <i32 0, i32 5, i32 1, i32 7>
79   %2 = shufflevector <4 x i32> %b, <4 x i32> %1, <4 x i32> <i32 4, i32 6, i32 0, i32 5>
80   ret <4 x i32> %2
81 }
82 ; CHECK-LABEL: test8
83 ; Mask: [0,1,4,5]
84 ; CHECK: movlhps
85 ; CHECK: ret
86
87 define <4 x i32> @test9(<4 x i32> %a, <4 x i32> %b) {
88   %1 = shufflevector <4 x i32> %a, <4 x i32> %b, <4 x i32> <i32 2, i32 3, i32 5, i32 5>
89   %2 = shufflevector <4 x i32> %b, <4 x i32> %1, <4 x i32> <i32 2, i32 3, i32 4, i32 5>
90   ret <4 x i32> %2
91 }
92 ; CHECK-LABEL: test9
93 ; Mask: [6,7,2,3]
94 ; CHECK: movhlps
95 ; CHECK-NEXT: ret
96
97 define <4 x i32> @test10(<4 x i32> %a, <4 x i32> %b) {
98   %1 = shufflevector <4 x i32> %a, <4 x i32> %b, <4 x i32> <i32 4, i32 1, i32 6, i32 3>
99   %2 = shufflevector <4 x i32> %b, <4 x i32> %1, <4 x i32> <i32 4, i32 5, i32 6, i32 3>
100   ret <4 x i32> %2
101 }
102 ; CHECK-LABEL: test10
103 ; Mask: [4,1,6,7]
104 ; CHECK: blendps
105 ; CHECK: ret
106
107 define <4 x float> @test11(<4 x float> %a, <4 x float> %b) {
108   %1 = shufflevector <4 x float> %a, <4 x float> %b, <4 x i32> <i32 4, i32 1, i32 6, i32 3>
109   %2 = shufflevector <4 x float> %a, <4 x float> %1, <4 x i32> <i32 0, i32 5, i32 2, i32 7>
110   ret <4 x float> %2
111 }
112 ; CHECK-LABEL: test11
113 ; Mask: [0,1,2,3]
114 ; CHECK-NOT: movaps
115 ; CHECK-NOT: blendps
116 ; CHECK: ret
117
118 define <4 x float> @test12(<4 x float> %a, <4 x float> %b) {
119   %1 = shufflevector <4 x float> %a, <4 x float> %b, <4 x i32> <i32 0, i32 5, i32 6, i32 7>
120   %2 = shufflevector <4 x float> %a, <4 x float> %1, <4 x i32> <i32 0, i32 5, i32 6, i32 7>
121   ret <4 x float> %2
122 }
123 ; CHECK-LABEL: test12
124 ; Mask: [0,5,6,7]
125 ; CHECK: movss
126 ; CHECK: ret
127
128 define <4 x float> @test13(<4 x float> %a, <4 x float> %b) {
129   %1 = shufflevector <4 x float> %a, <4 x float> %b, <4 x i32> <i32 0, i32 1, i32 4, i32 5>
130   %2 = shufflevector <4 x float> %a, <4 x float> %1, <4 x i32> <i32 0, i32 1, i32 6, i32 7>
131   ret <4 x float> %2
132 }
133 ; CHECK-LABEL: test13
134 ; Mask: [0,1,4,5]
135 ; CHECK: movlhps
136 ; CHECK: ret
137
138 define <4 x float> @test14(<4 x float> %a, <4 x float> %b) {
139   %1 = shufflevector <4 x float> %a, <4 x float> %b, <4 x i32> <i32 6, i32 7, i32 5, i32 5>
140   %2 = shufflevector <4 x float> %a, <4 x float> %1, <4 x i32> <i32 2, i32 3, i32 4, i32 5>
141   ret <4 x float> %2
142 }
143 ; CHECK-LABEL: test14
144 ; Mask: [6,7,2,3]
145 ; CHECK: movhlps
146 ; CHECK: ret
147
148 define <4 x float> @test15(<4 x float> %a, <4 x float> %b) {
149   %1 = shufflevector <4 x float> %a, <4 x float> %b, <4 x i32> <i32 4, i32 1, i32 6, i32 7>
150   %2 = shufflevector <4 x float> %a, <4 x float> %1, <4 x i32> <i32 4, i32 1, i32 6, i32 7>
151   ret <4 x float> %2
152 }
153 ; CHECK-LABEL: test15
154 ; Mask: [4,1,6,7]
155 ; CHECK: blendps $13
156 ; CHECK: ret
157
158 define <4 x i32> @test16(<4 x i32> %a, <4 x i32> %b) {
159   %1 = shufflevector <4 x i32> %a, <4 x i32> %b, <4 x i32> <i32 4, i32 1, i32 6, i32 3>
160   %2 = shufflevector <4 x i32> %a, <4 x i32> %1, <4 x i32> <i32 0, i32 5, i32 2, i32 7>
161   ret <4 x i32> %2
162 }
163 ; CHECK-LABEL: test16
164 ; Mask: [0,1,2,3]
165 ; CHECK-NOT: movaps
166 ; CHECK-NOT: blendps
167 ; CHECK: ret
168
169 define <4 x i32> @test17(<4 x i32> %a, <4 x i32> %b) {
170   %1 = shufflevector <4 x i32> %a, <4 x i32> %b, <4 x i32> <i32 0, i32 5, i32 6, i32 7>
171   %2 = shufflevector <4 x i32> %a, <4 x i32> %1, <4 x i32> <i32 0, i32 5, i32 6, i32 7>
172   ret <4 x i32> %2
173 }
174 ; CHECK-LABEL: test17
175 ; Mask: [0,5,6,7]
176 ; CHECK: movss
177 ; CHECK: ret
178
179 define <4 x i32> @test18(<4 x i32> %a, <4 x i32> %b) {
180   %1 = shufflevector <4 x i32> %a, <4 x i32> %b, <4 x i32> <i32 0, i32 1, i32 4, i32 5>
181   %2 = shufflevector <4 x i32> %a, <4 x i32> %1, <4 x i32> <i32 0, i32 1, i32 6, i32 7>
182   ret <4 x i32> %2
183 }
184 ; CHECK-LABEL: test18
185 ; Mask: [0,1,4,5]
186 ; CHECK: movlhps
187 ; CHECK: ret
188
189 define <4 x i32> @test19(<4 x i32> %a, <4 x i32> %b) {
190   %1 = shufflevector <4 x i32> %a, <4 x i32> %b, <4 x i32> <i32 6, i32 7, i32 5, i32 5>
191   %2 = shufflevector <4 x i32> %a, <4 x i32> %1, <4 x i32> <i32 2, i32 3, i32 4, i32 5>
192   ret <4 x i32> %2
193 }
194 ; CHECK-LABEL: test19
195 ; Mask: [6,7,2,3]
196 ; CHECK: movhlps
197 ; CHECK: ret
198
199 define <4 x i32> @test20(<4 x i32> %a, <4 x i32> %b) {
200   %1 = shufflevector <4 x i32> %a, <4 x i32> %b, <4 x i32> <i32 4, i32 1, i32 6, i32 7>
201   %2 = shufflevector <4 x i32> %a, <4 x i32> %1, <4 x i32> <i32 4, i32 1, i32 6, i32 7>
202   ret <4 x i32> %2
203 }
204 ; CHECK-LABEL: test20
205 ; Mask: [4,1,6,7]
206 ; CHECK: blendps $13
207 ; CHECK: ret
208
209 ; Verify that we correctly fold shuffles even when we use illegal vector types.
210 define <4 x i8> @test1c(<4 x i8>* %a, <4 x i8>* %b) {
211   %A = load <4 x i8>* %a
212   %B = load <4 x i8>* %b
213   %1 = shufflevector <4 x i8> %A, <4 x i8> %B, <4 x i32> <i32 0, i32 5, i32 2, i32 7>
214   %2 = shufflevector <4 x i8> %B, <4 x i8> %1, <4 x i32> <i32 4, i32 5, i32 2, i32 7>
215   ret <4 x i8> %2
216 }
217 ; CHECK-LABEL: test1c
218 ; Mask: [0,5,6,7]
219 ; CHECK: movss
220 ; CHECK-NEXT: ret
221
222 define <4 x i8> @test2c(<4 x i8>* %a, <4 x i8>* %b) {
223   %A = load <4 x i8>* %a
224   %B = load <4 x i8>* %b
225   %1 = shufflevector <4 x i8> %A, <4 x i8> %B, <4 x i32> <i32 0, i32 5, i32 1, i32 5>
226   %2 = shufflevector <4 x i8> %B, <4 x i8> %1, <4 x i32> <i32 4, i32 6, i32 0, i32 5>
227   ret <4 x i8> %2
228 }
229 ; CHECK-LABEL: test2c
230 ; Mask: [0,1,4,5]
231 ; CHECK: movlhps
232 ; CHECK-NEXT: ret
233
234 define <4 x i8> @test3c(<4 x i8>* %a, <4 x i8>* %b) {
235   %A = load <4 x i8>* %a
236   %B = load <4 x i8>* %b
237   %1 = shufflevector <4 x i8> %A, <4 x i8> %B, <4 x i32> <i32 2, i32 3, i32 5, i32 5>
238   %2 = shufflevector <4 x i8> %B, <4 x i8> %1, <4 x i32> <i32 2, i32 3, i32 4, i32 5>
239   ret <4 x i8> %2
240 }
241 ; CHECK-LABEL: test3c
242 ; Mask: [6,7,2,3]
243 ; CHECK: movhlps
244 ; CHECK: ret
245
246 define <4 x i8> @test4c(<4 x i8>* %a, <4 x i8>* %b) {
247   %A = load <4 x i8>* %a
248   %B = load <4 x i8>* %b
249   %1 = shufflevector <4 x i8> %A, <4 x i8> %B, <4 x i32> <i32 4, i32 1, i32 6, i32 3>
250   %2 = shufflevector <4 x i8> %B, <4 x i8> %1, <4 x i32> <i32 4, i32 5, i32 6, i32 3>
251   ret <4 x i8> %2
252 }
253 ; CHECK-LABEL: test4c
254 ; Mask: [4,1,6,7]
255 ; CHECK: blendps $13
256 ; CHECK: ret
257