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