c1f6c79e81acada32a9227a6de338dcf18cfd463
[oota-llvm.git] / test / CodeGen / X86 / combine-or.ll
1 ; RUN: llc < %s -mtriple=x86_64-unknown-linux-gnu -mcpu=corei7 | FileCheck %s
2
3
4 ; Verify that each of the following test cases is folded into a single
5 ; instruction which performs a blend operation.
6
7 define <2 x i64> @test1(<2 x i64> %a, <2 x i64> %b) {
8 ; CHECK-LABEL: test1:
9 ; CHECK:       # BB#0:
10 ; CHECK-NEXT:    movsd %xmm0, %xmm1
11 ; CHECK-NEXT:    movaps %xmm1, %xmm0
12 ; CHECK-NEXT:    retq
13   %shuf1 = shufflevector <2 x i64> %a, <2 x i64> zeroinitializer, <2 x i32><i32 0, i32 2>
14   %shuf2 = shufflevector <2 x i64> %b, <2 x i64> zeroinitializer, <2 x i32><i32 2, i32 1>
15   %or = or <2 x i64> %shuf1, %shuf2
16   ret <2 x i64> %or
17 }
18
19
20 define <4 x i32> @test2(<4 x i32> %a, <4 x i32> %b) {
21 ; CHECK-LABEL: test2:
22 ; CHECK:       # BB#0:
23 ; CHECK-NEXT:    movsd %xmm1, %xmm0
24 ; CHECK-NEXT:    retq
25   %shuf1 = shufflevector <4 x i32> %a, <4 x i32> zeroinitializer, <4 x i32><i32 4, i32 4, i32 2, i32 3>
26   %shuf2 = shufflevector <4 x i32> %b, <4 x i32> zeroinitializer, <4 x i32><i32 0, i32 1, i32 4, i32 4>
27   %or = or <4 x i32> %shuf1, %shuf2
28   ret <4 x i32> %or
29 }
30
31
32 define <2 x i64> @test3(<2 x i64> %a, <2 x i64> %b) {
33 ; CHECK-LABEL: test3:
34 ; CHECK:       # BB#0:
35 ; CHECK-NEXT:    movsd %xmm1, %xmm0
36 ; CHECK-NEXT:    retq
37   %shuf1 = shufflevector <2 x i64> %a, <2 x i64> zeroinitializer, <2 x i32><i32 2, i32 1>
38   %shuf2 = shufflevector <2 x i64> %b, <2 x i64> zeroinitializer, <2 x i32><i32 0, i32 2>
39   %or = or <2 x i64> %shuf1, %shuf2
40   ret <2 x i64> %or
41 }
42
43
44 define <4 x i32> @test4(<4 x i32> %a, <4 x i32> %b) {
45 ; CHECK-LABEL: test4:
46 ; CHECK:       # BB#0:
47 ; CHECK-NEXT:    movss %xmm0, %xmm1
48 ; CHECK-NEXT:    movaps %xmm1, %xmm0
49 ; CHECK-NEXT:    retq
50   %shuf1 = shufflevector <4 x i32> %a, <4 x i32> zeroinitializer, <4 x i32><i32 0, i32 4, i32 4, i32 4>
51   %shuf2 = shufflevector <4 x i32> %b, <4 x i32> zeroinitializer, <4 x i32><i32 4, i32 1, i32 2, i32 3>
52   %or = or <4 x i32> %shuf1, %shuf2
53   ret <4 x i32> %or
54 }
55
56
57 define <4 x i32> @test5(<4 x i32> %a, <4 x i32> %b) {
58 ; CHECK-LABEL: test5:
59 ; CHECK:       # BB#0:
60 ; CHECK-NEXT:    movss %xmm1, %xmm0
61 ; CHECK-NEXT:    retq
62   %shuf1 = shufflevector <4 x i32> %a, <4 x i32> zeroinitializer, <4 x i32><i32 4, i32 1, i32 2, i32 3>
63   %shuf2 = shufflevector <4 x i32> %b, <4 x i32> zeroinitializer, <4 x i32><i32 0, i32 4, i32 4, i32 4>
64   %or = or <4 x i32> %shuf1, %shuf2
65   ret <4 x i32> %or
66 }
67
68
69 define <4 x i32> @test6(<4 x i32> %a, <4 x i32> %b) {
70 ; CHECK-LABEL: test6:
71 ; CHECK:       # BB#0:
72 ; CHECK-NEXT:    blendps {{.*#+}} xmm0 = xmm0[0,1],xmm1[2,3]
73 ; CHECK-NEXT:    retq
74   %shuf1 = shufflevector <4 x i32> %a, <4 x i32> zeroinitializer, <4 x i32><i32 0, i32 1, i32 4, i32 4>
75   %shuf2 = shufflevector <4 x i32> %b, <4 x i32> zeroinitializer, <4 x i32><i32 4, i32 4, i32 2, i32 3>
76   %or = or <4 x i32> %shuf1, %shuf2
77   ret <4 x i32> %or
78 }
79
80
81 define <4 x i32> @test7(<4 x i32> %a, <4 x i32> %b) {
82 ; CHECK-LABEL: test7:
83 ; CHECK:       # BB#0:
84 ; CHECK-NEXT:    blendps {{.*#+}} xmm0 = xmm0[0,1],xmm1[2,3]
85 ; CHECK-NEXT:    retq
86   %and1 = and <4 x i32> %a, <i32 -1, i32 -1, i32 0, i32 0>
87   %and2 = and <4 x i32> %b, <i32 0, i32 0, i32 -1, i32 -1>
88   %or = or <4 x i32> %and1, %and2
89   ret <4 x i32> %or
90 }
91
92
93 define <2 x i64> @test8(<2 x i64> %a, <2 x i64> %b) {
94 ; CHECK-LABEL: test8:
95 ; CHECK:       # BB#0:
96 ; CHECK-NEXT:    movsd %xmm0, %xmm1
97 ; CHECK-NEXT:    movaps %xmm1, %xmm0
98 ; CHECK-NEXT:    retq
99   %and1 = and <2 x i64> %a, <i64 -1, i64 0>
100   %and2 = and <2 x i64> %b, <i64 0, i64 -1>
101   %or = or <2 x i64> %and1, %and2
102   ret <2 x i64> %or
103 }
104
105
106 define <4 x i32> @test9(<4 x i32> %a, <4 x i32> %b) {
107 ; CHECK-LABEL: test9:
108 ; CHECK:       # BB#0:
109 ; CHECK-NEXT:    movsd %xmm1, %xmm0
110 ; CHECK-NEXT:    retq
111   %and1 = and <4 x i32> %a, <i32 0, i32 0, i32 -1, i32 -1>
112   %and2 = and <4 x i32> %b, <i32 -1, i32 -1, i32 0, i32 0>
113   %or = or <4 x i32> %and1, %and2
114   ret <4 x i32> %or
115 }
116
117
118 define <2 x i64> @test10(<2 x i64> %a, <2 x i64> %b) {
119 ; CHECK-LABEL: test10:
120 ; CHECK:       # BB#0:
121 ; CHECK-NEXT:    movsd %xmm1, %xmm0
122 ; CHECK-NEXT:    retq
123   %and1 = and <2 x i64> %a, <i64 0, i64 -1>
124   %and2 = and <2 x i64> %b, <i64 -1, i64 0>
125   %or = or <2 x i64> %and1, %and2
126   ret <2 x i64> %or
127 }
128
129
130 define <4 x i32> @test11(<4 x i32> %a, <4 x i32> %b) {
131 ; CHECK-LABEL: test11:
132 ; CHECK:       # BB#0:
133 ; CHECK-NEXT:    movss %xmm0, %xmm1
134 ; CHECK-NEXT:    movaps %xmm1, %xmm0
135 ; CHECK-NEXT:    retq
136   %and1 = and <4 x i32> %a, <i32 -1, i32 0, i32 0, i32 0>
137   %and2 = and <4 x i32> %b, <i32 0, i32 -1, i32 -1, i32 -1>
138   %or = or <4 x i32> %and1, %and2
139   ret <4 x i32> %or
140 }
141
142
143 define <4 x i32> @test12(<4 x i32> %a, <4 x i32> %b) {
144 ; CHECK-LABEL: test12:
145 ; CHECK:       # BB#0:
146 ; CHECK-NEXT:    movss %xmm1, %xmm0
147 ; CHECK-NEXT:    retq
148   %and1 = and <4 x i32> %a, <i32 0, i32 -1, i32 -1, i32 -1>
149   %and2 = and <4 x i32> %b, <i32 -1, i32 0, i32 0, i32 0>
150   %or = or <4 x i32> %and1, %and2
151   ret <4 x i32> %or
152 }
153
154
155 ; Verify that the following test cases are folded into single shuffles.
156
157 define <4 x i32> @test13(<4 x i32> %a, <4 x i32> %b) {
158 ; CHECK-LABEL: test13:
159 ; CHECK:       # BB#0:
160 ; CHECK-NEXT:    shufps {{.*#+}} xmm0 = xmm0[1,1],xmm1[2,3]
161 ; CHECK-NEXT:    retq
162   %shuf1 = shufflevector <4 x i32> %a, <4 x i32> zeroinitializer, <4 x i32><i32 1, i32 1, i32 4, i32 4>
163   %shuf2 = shufflevector <4 x i32> %b, <4 x i32> zeroinitializer, <4 x i32><i32 4, i32 4, i32 2, i32 3>
164   %or = or <4 x i32> %shuf1, %shuf2
165   ret <4 x i32> %or
166 }
167
168
169 define <2 x i64> @test14(<2 x i64> %a, <2 x i64> %b) {
170 ; CHECK-LABEL: test14:
171 ; CHECK:       # BB#0:
172 ; CHECK-NEXT:    punpcklqdq {{.*#+}} xmm0 = xmm0[0],xmm1[0]
173 ; CHECK-NEXT:    retq
174   %shuf1 = shufflevector <2 x i64> %a, <2 x i64> zeroinitializer, <2 x i32><i32 0, i32 2>
175   %shuf2 = shufflevector <2 x i64> %b, <2 x i64> zeroinitializer, <2 x i32><i32 2, i32 0>
176   %or = or <2 x i64> %shuf1, %shuf2
177   ret <2 x i64> %or
178 }
179
180
181 define <4 x i32> @test15(<4 x i32> %a, <4 x i32> %b) {
182 ; CHECK-LABEL: test15:
183 ; CHECK:       # BB#0:
184 ; CHECK-NEXT:    shufps {{.*#+}} xmm1 = xmm1[2,1],xmm0[2,1]
185 ; CHECK-NEXT:    movaps %xmm1, %xmm0
186 ; CHECK-NEXT:    retq
187   %shuf1 = shufflevector <4 x i32> %a, <4 x i32> zeroinitializer, <4 x i32><i32 4, i32 4, i32 2, i32 1>
188   %shuf2 = shufflevector <4 x i32> %b, <4 x i32> zeroinitializer, <4 x i32><i32 2, i32 1, i32 4, i32 4>
189   %or = or <4 x i32> %shuf1, %shuf2
190   ret <4 x i32> %or
191 }
192
193
194 define <2 x i64> @test16(<2 x i64> %a, <2 x i64> %b) {
195 ; CHECK-LABEL: test16:
196 ; CHECK:       # BB#0:
197 ; CHECK-NEXT:    punpcklqdq {{.*#+}} xmm1 = xmm1[0],xmm0[0]
198 ; CHECK-NEXT:    movdqa %xmm1, %xmm0
199 ; CHECK-NEXT:    retq
200   %shuf1 = shufflevector <2 x i64> %a, <2 x i64> zeroinitializer, <2 x i32><i32 2, i32 0>
201   %shuf2 = shufflevector <2 x i64> %b, <2 x i64> zeroinitializer, <2 x i32><i32 0, i32 2>
202   %or = or <2 x i64> %shuf1, %shuf2
203   ret <2 x i64> %or
204 }
205
206
207 ; Verify that the dag-combiner does not fold a OR of two shuffles into a single
208 ; shuffle instruction when the shuffle indexes are not compatible.
209
210 define <4 x i32> @test17(<4 x i32> %a, <4 x i32> %b) {
211 ; CHECK-LABEL: test17:
212 ; CHECK:       # BB#0:
213 ; CHECK-NEXT:    xorps %xmm2, %xmm2
214 ; CHECK-NEXT:    shufps {{.*#+}} xmm0 = xmm0[0,2],xmm2[0,0]
215 ; CHECK-NEXT:    pshufd {{.*#+}} xmm0 = xmm0[2,0,3,1]
216 ; CHECK-NEXT:    shufps {{.*#+}} xmm1 = xmm1[0,1],xmm2[0,0]
217 ; CHECK-NEXT:    por %xmm1, %xmm0
218 ; CHECK-NEXT:    retq
219   %shuf1 = shufflevector <4 x i32> %a, <4 x i32> zeroinitializer, <4 x i32><i32 4, i32 0, i32 4, i32 2>
220   %shuf2 = shufflevector <4 x i32> %b, <4 x i32> zeroinitializer, <4 x i32><i32 0, i32 1, i32 4, i32 4>
221   %or = or <4 x i32> %shuf1, %shuf2
222   ret <4 x i32> %or
223 }
224
225
226 define <4 x i32> @test18(<4 x i32> %a, <4 x i32> %b) {
227 ; CHECK-LABEL: test18:
228 ; CHECK:       # BB#0:
229 ; CHECK-NEXT:    xorps %xmm2, %xmm2
230 ; CHECK-NEXT:    xorps %xmm3, %xmm3
231 ; CHECK-NEXT:    blendps $1, %xmm0, %xmm3
232 ; CHECK-NEXT:    shufps {{.*#+}} xmm3 = xmm3[2,0],xmm2[0,0]
233 ; CHECK-NEXT:    blendps $1, %xmm1, %xmm2
234 ; CHECK-NEXT:    orps %xmm3, %xmm2
235 ; CHECK-NEXT:    movaps %xmm2, %xmm0
236 ; CHECK-NEXT:    retq
237   %shuf1 = shufflevector <4 x i32> %a, <4 x i32> zeroinitializer, <4 x i32><i32 4, i32 0, i32 4, i32 4>
238   %shuf2 = shufflevector <4 x i32> %b, <4 x i32> zeroinitializer, <4 x i32><i32 0, i32 4, i32 4, i32 4>
239   %or = or <4 x i32> %shuf1, %shuf2
240   ret <4 x i32> %or
241 }
242
243
244 define <4 x i32> @test19(<4 x i32> %a, <4 x i32> %b) {
245 ; CHECK-LABEL: test19:
246 ; CHECK:       # BB#0:
247 ; CHECK-NEXT:    xorps %xmm2, %xmm2
248 ; CHECK-NEXT:    shufps {{.*#+}} xmm0 = xmm0[0,3],xmm2[0,0]
249 ; CHECK-NEXT:    pshufd {{.*#+}} xmm0 = xmm0[2,0,3,1]
250 ; CHECK-NEXT:    movdqa %xmm1, %xmm2
251 ; CHECK-NEXT:    pslldq $8, %xmm2
252 ; CHECK-NEXT:    shufps {{.*#+}} xmm2 = xmm2[2,0],xmm1[2,2]
253 ; CHECK-NEXT:    por %xmm2, %xmm0
254 ; CHECK-NEXT:    retq
255   %shuf1 = shufflevector <4 x i32> %a, <4 x i32> zeroinitializer, <4 x i32><i32 4, i32 0, i32 4, i32 3>
256   %shuf2 = shufflevector <4 x i32> %b, <4 x i32> zeroinitializer, <4 x i32><i32 0, i32 4, i32 2, i32 2>
257   %or = or <4 x i32> %shuf1, %shuf2
258   ret <4 x i32> %or
259 }
260
261
262 define <2 x i64> @test20(<2 x i64> %a, <2 x i64> %b) {
263 ; CHECK-LABEL: test20:
264 ; CHECK:       # BB#0:
265 ; CHECK-NEXT:    orps %xmm1, %xmm0
266 ; CHECK-NEXT:    movq %xmm0, %xmm0
267 ; CHECK-NEXT:    retq
268   %shuf1 = shufflevector <2 x i64> %a, <2 x i64> zeroinitializer, <2 x i32><i32 0, i32 2>
269   %shuf2 = shufflevector <2 x i64> %b, <2 x i64> zeroinitializer, <2 x i32><i32 0, i32 2>
270   %or = or <2 x i64> %shuf1, %shuf2
271   ret <2 x i64> %or
272 }
273
274
275 define <2 x i64> @test21(<2 x i64> %a, <2 x i64> %b) {
276 ; CHECK-LABEL: test21:
277 ; CHECK:       # BB#0:
278 ; CHECK-NEXT:    por %xmm1, %xmm0
279 ; CHECK-NEXT:    pslldq $8, %xmm0
280 ; CHECK-NEXT:    retq
281   %shuf1 = shufflevector <2 x i64> %a, <2 x i64> zeroinitializer, <2 x i32><i32 2, i32 0>
282   %shuf2 = shufflevector <2 x i64> %b, <2 x i64> zeroinitializer, <2 x i32><i32 2, i32 0>
283   %or = or <2 x i64> %shuf1, %shuf2
284   ret <2 x i64> %or
285 }
286
287 ; Verify that the DAGCombiner doesn't crash in the attempt to check if a shuffle
288 ; with illegal type has a legal mask. Method 'isShuffleMaskLegal' only knows how to
289 ; handle legal vector value types.
290 define <4 x i8> @test_crash(<4 x i8> %a, <4 x i8> %b) {
291 ; CHECK-LABEL: test_crash:
292 ; CHECK:       # BB#0:
293 ; CHECK-NEXT:    movsd %xmm1, %xmm0
294 ; CHECK-NEXT:    retq
295   %shuf1 = shufflevector <4 x i8> %a, <4 x i8> zeroinitializer, <4 x i32><i32 4, i32 4, i32 2, i32 3>
296   %shuf2 = shufflevector <4 x i8> %b, <4 x i8> zeroinitializer, <4 x i32><i32 0, i32 1, i32 4, i32 4>
297   %or = or <4 x i8> %shuf1, %shuf2
298   ret <4 x i8> %or
299 }
300