1; NOTE: Assertions have been autogenerated by utils/update_test_checks.py
2; RUN: opt < %s -instcombine -S | FileCheck %s
3
4define <4 x float> @test1(<4 x float> %v1) {
5; CHECK-LABEL: @test1(
6; CHECK-NEXT:    ret <4 x float> %v1
7;
8  %v2 = shufflevector <4 x float> %v1, <4 x float> undef, <4 x i32> <i32 0, i32 1, i32 2, i32 3>
9  ret <4 x float> %v2
10}
11
12define <4 x float> @test2(<4 x float> %v1) {
13; CHECK-LABEL: @test2(
14; CHECK-NEXT:    ret <4 x float> %v1
15;
16  %v2 = shufflevector <4 x float> %v1, <4 x float> %v1, <4 x i32> <i32 0, i32 5, i32 2, i32 7>
17  ret <4 x float> %v2
18}
19
20define float @test3(<4 x float> %A, <4 x float> %B, float %f) {
21; CHECK-LABEL: @test3(
22; CHECK-NEXT:    ret float %f
23;
24  %C = insertelement <4 x float> %A, float %f, i32 0
25  %D = shufflevector <4 x float> %C, <4 x float> %B, <4 x i32> <i32 5, i32 0, i32 2, i32 7>
26  %E = extractelement <4 x float> %D, i32 1
27  ret float %E
28}
29
30define i32 @test4(<4 x i32> %X) {
31; CHECK-LABEL: @test4(
32; CHECK-NEXT:    [[TMP34:%.*]] = extractelement <4 x i32> %X, i32 0
33; CHECK-NEXT:    ret i32 [[TMP34]]
34;
35  %tmp152.i53899.i = shufflevector <4 x i32> %X, <4 x i32> undef, <4 x i32> zeroinitializer
36  %tmp34 = extractelement <4 x i32> %tmp152.i53899.i, i32 0
37  ret i32 %tmp34
38}
39
40define i32 @test5(<4 x i32> %X) {
41; CHECK-LABEL: @test5(
42; CHECK-NEXT:    [[TMP34:%.*]] = extractelement <4 x i32> %X, i32 3
43; CHECK-NEXT:    ret i32 [[TMP34]]
44;
45  %tmp152.i53899.i = shufflevector <4 x i32> %X, <4 x i32> undef, <4 x i32> <i32 3, i32 2, i32 undef, i32 undef>
46  %tmp34 = extractelement <4 x i32> %tmp152.i53899.i, i32 0
47  ret i32 %tmp34
48}
49
50define float @test6(<4 x float> %X) {
51; CHECK-LABEL: @test6(
52; CHECK-NEXT:    [[TMP34:%.*]] = extractelement <4 x float> %X, i32 0
53; CHECK-NEXT:    ret float [[TMP34]]
54;
55  %X1 = bitcast <4 x float> %X to <4 x i32>
56  %tmp152.i53899.i = shufflevector <4 x i32> %X1, <4 x i32> undef, <4 x i32> zeroinitializer
57  %tmp152.i53900.i = bitcast <4 x i32> %tmp152.i53899.i to <4 x float>
58  %tmp34 = extractelement <4 x float> %tmp152.i53900.i, i32 0
59  ret float %tmp34
60}
61
62define <4 x float> @test7(<4 x float> %tmp45.i) {
63; CHECK-LABEL: @test7(
64; CHECK-NEXT:    ret <4 x float> %tmp45.i
65;
66  %tmp1642.i = shufflevector <4 x float> %tmp45.i, <4 x float> undef, <4 x i32> < i32 0, i32 1, i32 6, i32 7 >
67  ret <4 x float> %tmp1642.i
68}
69
70; This should turn into a single shuffle.
71define <4 x float> @test8(<4 x float> %tmp, <4 x float> %tmp1) {
72; CHECK-LABEL: @test8(
73; CHECK-NEXT:    [[TMP134:%.*]] = shufflevector <4 x float> %tmp, <4 x float> %tmp1, <4 x i32> <i32 1, i32 undef, i32 3, i32 4>
74; CHECK-NEXT:    ret <4 x float> [[TMP134]]
75;
76  %tmp4 = extractelement <4 x float> %tmp, i32 1
77  %tmp2 = extractelement <4 x float> %tmp, i32 3
78  %tmp1.upgrd.1 = extractelement <4 x float> %tmp1, i32 0
79  %tmp128 = insertelement <4 x float> undef, float %tmp4, i32 0
80  %tmp130 = insertelement <4 x float> %tmp128, float undef, i32 1
81  %tmp132 = insertelement <4 x float> %tmp130, float %tmp2, i32 2
82  %tmp134 = insertelement <4 x float> %tmp132, float %tmp1.upgrd.1, i32 3
83  ret <4 x float> %tmp134
84}
85
86; Test fold of two shuffles where the first shuffle vectors inputs are a
87; different length then the second.
88define <4 x i8> @test9(<16 x i8> %tmp6) nounwind {
89; CHECK-LABEL: @test9(
90; CHECK-NEXT:    [[TMP9:%.*]] = shufflevector <16 x i8> %tmp6, <16 x i8> undef, <4 x i32> <i32 13, i32 9, i32 4, i32 13>
91; CHECK-NEXT:    ret <4 x i8> [[TMP9]]
92;
93  %tmp7 = shufflevector <16 x i8> %tmp6, <16 x i8> undef, <4 x i32> < i32 13, i32 9, i32 4, i32 13 >		; <<4 x i8>> [#uses=1]
94  %tmp9 = shufflevector <4 x i8> %tmp7, <4 x i8> undef, <4 x i32> < i32 3, i32 1, i32 2, i32 0 >		; <<4 x i8>> [#uses=1]
95  ret <4 x i8> %tmp9
96}
97
98; Same as test9, but make sure that "undef" mask values are not confused with
99; mask values of 2*N, where N is the mask length.  These shuffles should not
100; be folded (because [8,9,4,8] may not be a mask supported by the target).
101define <4 x i8> @test9a(<16 x i8> %tmp6) nounwind {
102; CHECK-LABEL: @test9a(
103; CHECK-NEXT:    [[TMP7:%.*]] = shufflevector <16 x i8> %tmp6, <16 x i8> undef, <4 x i32> <i32 undef, i32 9, i32 4, i32 8>
104; CHECK-NEXT:    [[TMP9:%.*]] = shufflevector <4 x i8> [[TMP7]], <4 x i8> undef, <4 x i32> <i32 3, i32 1, i32 2, i32 undef>
105; CHECK-NEXT:    ret <4 x i8> [[TMP9]]
106;
107  %tmp7 = shufflevector <16 x i8> %tmp6, <16 x i8> undef, <4 x i32> < i32 undef, i32 9, i32 4, i32 8 >		; <<4 x i8>> [#uses=1]
108  %tmp9 = shufflevector <4 x i8> %tmp7, <4 x i8> undef, <4 x i32> < i32 3, i32 1, i32 2, i32 0 >		; <<4 x i8>> [#uses=1]
109  ret <4 x i8> %tmp9
110}
111
112; Test fold of two shuffles where the first shuffle vectors inputs are a
113; different length then the second.
114define <4 x i8> @test9b(<4 x i8> %tmp6, <4 x i8> %tmp7) nounwind {
115; CHECK-LABEL: @test9b(
116; CHECK-NEXT:    [[TMP9:%.*]] = shufflevector <4 x i8> %tmp6, <4 x i8> %tmp7, <4 x i32> <i32 0, i32 1, i32 4, i32 5>
117; CHECK-NEXT:    ret <4 x i8> [[TMP9]]
118;
119  %tmp1 = shufflevector <4 x i8> %tmp6, <4 x i8> %tmp7, <8 x i32> <i32 0, i32 1, i32 4, i32 5, i32 4, i32 5, i32 2, i32 3>		; <<4 x i8>> [#uses=1]
120  %tmp9 = shufflevector <8 x i8> %tmp1, <8 x i8> undef, <4 x i32> <i32 0, i32 1, i32 4, i32 5>		; <<4 x i8>> [#uses=1]
121  ret <4 x i8> %tmp9
122}
123
124; Redundant vector splats should be removed.  Radar 8597790.
125define <4 x i32> @test10(<4 x i32> %tmp5) nounwind {
126; CHECK-LABEL: @test10(
127; CHECK-NEXT:    [[TMP7:%.*]] = shufflevector <4 x i32> %tmp5, <4 x i32> undef, <4 x i32> <i32 1, i32 1, i32 1, i32 1>
128; CHECK-NEXT:    ret <4 x i32> [[TMP7]]
129;
130  %tmp6 = shufflevector <4 x i32> %tmp5, <4 x i32> undef, <4 x i32> <i32 1, i32 undef, i32 undef, i32 undef>
131  %tmp7 = shufflevector <4 x i32> %tmp6, <4 x i32> undef, <4 x i32> zeroinitializer
132  ret <4 x i32> %tmp7
133}
134
135; Test fold of two shuffles where the two shufflevector inputs's op1 are
136; the same
137define <8 x i8> @test11(<16 x i8> %tmp6) nounwind {
138; CHECK-LABEL: @test11(
139; CHECK-NEXT:    [[TMP3:%.*]] = shufflevector <16 x i8> %tmp6, <16 x i8> undef, <8 x i32> <i32 0, i32 1, i32 2, i32 3, i32 4, i32 5, i32 6, i32 7>
140; CHECK-NEXT:    ret <8 x i8> [[TMP3]]
141;
142  %tmp1 = shufflevector <16 x i8> %tmp6, <16 x i8> undef, <4 x i32> <i32 0, i32 1, i32 2, i32 3>		; <<4 x i8>> [#uses=1]
143  %tmp2 = shufflevector <16 x i8> %tmp6, <16 x i8> undef, <4 x i32> <i32 4, i32 5, i32 6, i32 7>		; <<4 x i8>> [#uses=1]
144  %tmp3 = shufflevector <4 x i8> %tmp1, <4 x i8> %tmp2, <8 x i32> <i32 0, i32 1, i32 2, i32 3, i32 4, i32 5, i32 6, i32 7>		; <<8 x i8>> [#uses=1]
145  ret <8 x i8> %tmp3
146}
147
148; Test fold of two shuffles where the first shufflevector's inputs are
149; the same as the second
150define <8 x i8> @test12(<8 x i8> %tmp6, <8 x i8> %tmp2) nounwind {
151; CHECK-LABEL: @test12(
152; CHECK-NEXT:    [[TMP3:%.*]] = shufflevector <8 x i8> %tmp6, <8 x i8> %tmp2, <8 x i32> <i32 0, i32 1, i32 2, i32 3, i32 9, i32 8, i32 11, i32 12>
153; CHECK-NEXT:    ret <8 x i8> [[TMP3]]
154;
155  %tmp1 = shufflevector <8 x i8> %tmp6, <8 x i8> undef, <8 x i32> <i32 0, i32 1, i32 2, i32 3, i32 5, i32 4, i32 undef, i32 7>	; <<8 x i8>> [#uses=1]
156  %tmp3 = shufflevector <8 x i8> %tmp1, <8 x i8> %tmp2, <8 x i32> <i32 0, i32 1, i32 2, i32 3, i32 9, i32 8, i32 11, i32 12>		; <<8 x i8>> [#uses=1]
157  ret <8 x i8> %tmp3
158}
159
160; Test fold of two shuffles where the first shufflevector's inputs are
161; the same as the second
162define <8 x i8> @test12a(<8 x i8> %tmp6, <8 x i8> %tmp2) nounwind {
163; CHECK-LABEL: @test12a(
164; CHECK-NEXT:    [[TMP3:%.*]] = shufflevector <8 x i8> %tmp2, <8 x i8> %tmp6, <8 x i32> <i32 0, i32 3, i32 1, i32 4, i32 8, i32 9, i32 10, i32 11>
165; CHECK-NEXT:    ret <8 x i8> [[TMP3]]
166;
167  %tmp1 = shufflevector <8 x i8> %tmp6, <8 x i8> undef, <8 x i32> <i32 0, i32 1, i32 2, i32 3, i32 5, i32 4, i32 undef, i32 7>	; <<8 x i8>> [#uses=1]
168  %tmp3 = shufflevector <8 x i8> %tmp2, <8 x i8> %tmp1, <8 x i32> <i32 0, i32 3, i32 1, i32 4, i32 8, i32 9, i32 10, i32 11>		; <<8 x i8>> [#uses=1]
169  ret <8 x i8> %tmp3
170}
171
172define <2 x i8> @test13a(i8 %x1, i8 %x2) {
173; CHECK-LABEL: @test13a(
174; CHECK-NEXT:    [[TMP1:%.*]] = insertelement <2 x i8> undef, i8 %x1, i32 1
175; CHECK-NEXT:    [[TMP2:%.*]] = insertelement <2 x i8> [[TMP1]], i8 %x2, i32 0
176; CHECK-NEXT:    [[TMP3:%.*]] = add <2 x i8> [[TMP2]], <i8 7, i8 5>
177; CHECK-NEXT:    ret <2 x i8> [[TMP3]]
178;
179  %A = insertelement <2 x i8> undef, i8 %x1, i32 0
180  %B = insertelement <2 x i8> %A, i8 %x2, i32 1
181  %C = add <2 x i8> %B, <i8 5, i8 7>
182  %D = shufflevector <2 x i8> %C, <2 x i8> undef, <2 x i32> <i32 1, i32 0>
183  ret <2 x i8> %D
184}
185
186define <2 x i8> @test13b(i8 %x) {
187; CHECK-LABEL: @test13b(
188; CHECK-NEXT:    [[TMP1:%.*]] = insertelement <2 x i8> undef, i8 %x, i32 1
189; CHECK-NEXT:    ret <2 x i8> [[TMP1]]
190;
191  %A = insertelement <2 x i8> undef, i8 %x, i32 0
192  %B = shufflevector <2 x i8> %A, <2 x i8> undef, <2 x i32> <i32 undef, i32 0>
193  ret <2 x i8> %B
194}
195
196define <2 x i8> @test13c(i8 %x1, i8 %x2) {
197; CHECK-LABEL: @test13c(
198; CHECK-NEXT:    [[TMP1:%.*]] = insertelement <2 x i8> undef, i8 %x1, i32 0
199; CHECK-NEXT:    [[TMP2:%.*]] = insertelement <2 x i8> [[TMP1]], i8 %x2, i32 1
200; CHECK-NEXT:    ret <2 x i8> [[TMP2]]
201;
202  %A = insertelement <4 x i8> undef, i8 %x1, i32 0
203  %B = insertelement <4 x i8> %A, i8 %x2, i32 2
204  %C = shufflevector <4 x i8> %B, <4 x i8> undef, <2 x i32> <i32 0, i32 2>
205  ret <2 x i8> %C
206}
207
208define void @test14(i16 %conv10) {
209; CHECK-LABEL: @test14(
210; CHECK-NEXT:    store <4 x i16> <i16 undef, i16 undef, i16 undef, i16 23>, <4 x i16>* undef, align 8
211; CHECK-NEXT:    ret void
212;
213  %tmp = alloca <4 x i16>, align 8
214  %vecinit6 = insertelement <4 x i16> undef, i16 23, i32 3
215  store <4 x i16> %vecinit6, <4 x i16>* undef
216  %tmp1 = load <4 x i16>, <4 x i16>* undef
217  %vecinit11 = insertelement <4 x i16> undef, i16 %conv10, i32 3
218  %div = udiv <4 x i16> %tmp1, %vecinit11
219  store <4 x i16> %div, <4 x i16>* %tmp
220  %tmp4 = load <4 x i16>, <4 x i16>* %tmp
221  %tmp5 = shufflevector <4 x i16> %tmp4, <4 x i16> undef, <2 x i32> <i32 2, i32 0>
222  %cmp = icmp ule <2 x i16> %tmp5, undef
223  %sext = sext <2 x i1> %cmp to <2 x i16>
224  ret void
225}
226
227; Check that sequences of insert/extract element are
228; collapsed into valid shuffle instruction with correct shuffle indexes.
229
230define <4 x float> @test15a(<4 x float> %LHS, <4 x float> %RHS) {
231; CHECK-LABEL: @test15a(
232; CHECK-NEXT:    [[TMP4:%.*]] = shufflevector <4 x float> %LHS, <4 x float> %RHS, <4 x i32> <i32 4, i32 0, i32 6, i32 6>
233; CHECK-NEXT:    ret <4 x float> [[TMP4]]
234;
235  %tmp1 = extractelement <4 x float> %LHS, i32 0
236  %tmp2 = insertelement <4 x float> %RHS, float %tmp1, i32 1
237  %tmp3 = extractelement <4 x float> %RHS, i32 2
238  %tmp4 = insertelement <4 x float> %tmp2, float %tmp3, i32 3
239  ret <4 x float> %tmp4
240}
241
242define <4 x float> @test15b(<4 x float> %LHS, <4 x float> %RHS) {
243; CHECK-LABEL: @test15b(
244; CHECK-NEXT:    [[TMP5:%.*]] = shufflevector <4 x float> %LHS, <4 x float> %RHS, <4 x i32> <i32 4, i32 3, i32 6, i32 6>
245; CHECK-NEXT:    ret <4 x float> [[TMP5]]
246;
247  %tmp0 = extractelement <4 x float> %LHS, i32 3
248  %tmp1 = insertelement <4 x float> %RHS, float %tmp0, i32 0
249  %tmp2 = extractelement <4 x float> %tmp1, i32 0
250  %tmp3 = insertelement <4 x float> %RHS, float %tmp2, i32 1
251  %tmp4 = extractelement <4 x float> %RHS, i32 2
252  %tmp5 = insertelement <4 x float> %tmp3, float %tmp4, i32 3
253  ret <4 x float> %tmp5
254}
255
256define <1 x i32> @test16a(i32 %ele) {
257; CHECK-LABEL: @test16a(
258; CHECK-NEXT:    ret <1 x i32> <i32 2>
259;
260  %tmp0 = insertelement <2 x i32> <i32 1, i32 undef>, i32 %ele, i32 1
261  %tmp1 = shl <2 x i32> %tmp0, <i32 1, i32 1>
262  %tmp2 = shufflevector <2 x i32> %tmp1, <2 x i32> undef, <1 x i32> <i32 0>
263  ret <1 x i32> %tmp2
264}
265
266define <4 x i8> @test16b(i8 %ele) {
267; CHECK-LABEL: @test16b(
268; CHECK-NEXT:    ret <4 x i8> <i8 2, i8 2, i8 2, i8 2>
269;
270  %tmp0 = insertelement <8 x i8> <i8 1, i8 1, i8 1, i8 1, i8 1, i8 1, i8 undef, i8 1>, i8 %ele, i32 6
271  %tmp1 = shl <8 x i8> %tmp0, <i8 1, i8 1, i8 1, i8 1, i8 1, i8 1, i8 1, i8 1>
272  %tmp2 = shufflevector <8 x i8> %tmp1, <8 x i8> undef, <4 x i32> <i32 1, i32 2, i32 3, i32 4>
273  ret <4 x i8> %tmp2
274}
275
276; If composition of two shuffles is identity, shuffles can be removed.
277define <4 x i32> @shuffle_17ident(<4 x i32> %v) nounwind uwtable {
278; CHECK-LABEL: @shuffle_17ident(
279; CHECK-NEXT:    ret <4 x i32> %v
280;
281  %shuffle = shufflevector <4 x i32> %v, <4 x i32> zeroinitializer, <4 x i32> <i32 1, i32 2, i32 3, i32 0>
282  %shuffle2 = shufflevector <4 x i32> %shuffle, <4 x i32> zeroinitializer, <4 x i32> <i32 3, i32 0, i32 1, i32 2>
283  ret <4 x i32> %shuffle2
284}
285
286; swizzle can be put after operation
287define <4 x i32> @shuffle_17and(<4 x i32> %v1, <4 x i32> %v2) nounwind uwtable {
288; CHECK-LABEL: @shuffle_17and(
289; CHECK-NEXT:    [[TMP1:%.*]] = and <4 x i32> %v1, %v2
290; CHECK-NEXT:    [[TMP2:%.*]] = shufflevector <4 x i32> [[TMP1]], <4 x i32> undef, <4 x i32> <i32 1, i32 2, i32 3, i32 0>
291; CHECK-NEXT:    ret <4 x i32> [[TMP2]]
292;
293  %t1 = shufflevector <4 x i32> %v1, <4 x i32> zeroinitializer, <4 x i32> <i32 1, i32 2, i32 3, i32 0>
294  %t2 = shufflevector <4 x i32> %v2, <4 x i32> zeroinitializer, <4 x i32> <i32 1, i32 2, i32 3, i32 0>
295  %r = and <4 x i32> %t1, %t2
296  ret <4 x i32> %r
297}
298
299define <4 x i32> @shuffle_17add(<4 x i32> %v1, <4 x i32> %v2) nounwind uwtable {
300; CHECK-LABEL: @shuffle_17add(
301; CHECK-NEXT:    [[TMP1:%.*]] = add <4 x i32> %v1, %v2
302; CHECK-NEXT:    [[TMP2:%.*]] = shufflevector <4 x i32> [[TMP1]], <4 x i32> undef, <4 x i32> <i32 1, i32 2, i32 3, i32 0>
303; CHECK-NEXT:    ret <4 x i32> [[TMP2]]
304;
305  %t1 = shufflevector <4 x i32> %v1, <4 x i32> zeroinitializer, <4 x i32> <i32 1, i32 2, i32 3, i32 0>
306  %t2 = shufflevector <4 x i32> %v2, <4 x i32> zeroinitializer, <4 x i32> <i32 1, i32 2, i32 3, i32 0>
307  %r = add <4 x i32> %t1, %t2
308  ret <4 x i32> %r
309}
310
311define <4 x i32> @shuffle_17addnsw(<4 x i32> %v1, <4 x i32> %v2) nounwind uwtable {
312; CHECK-LABEL: @shuffle_17addnsw(
313; CHECK-NEXT:    [[TMP1:%.*]] = add nsw <4 x i32> %v1, %v2
314; CHECK-NEXT:    [[TMP2:%.*]] = shufflevector <4 x i32> [[TMP1]], <4 x i32> undef, <4 x i32> <i32 1, i32 2, i32 3, i32 0>
315; CHECK-NEXT:    ret <4 x i32> [[TMP2]]
316;
317  %t1 = shufflevector <4 x i32> %v1, <4 x i32> zeroinitializer, <4 x i32> <i32 1, i32 2, i32 3, i32 0>
318  %t2 = shufflevector <4 x i32> %v2, <4 x i32> zeroinitializer, <4 x i32> <i32 1, i32 2, i32 3, i32 0>
319  %r = add nsw <4 x i32> %t1, %t2
320  ret <4 x i32> %r
321}
322
323define <4 x i32> @shuffle_17addnuw(<4 x i32> %v1, <4 x i32> %v2) nounwind uwtable {
324; CHECK-LABEL: @shuffle_17addnuw(
325; CHECK-NEXT:    [[TMP1:%.*]] = add nuw <4 x i32> %v1, %v2
326; CHECK-NEXT:    [[TMP2:%.*]] = shufflevector <4 x i32> [[TMP1]], <4 x i32> undef, <4 x i32> <i32 1, i32 2, i32 3, i32 0>
327; CHECK-NEXT:    ret <4 x i32> [[TMP2]]
328;
329  %t1 = shufflevector <4 x i32> %v1, <4 x i32> zeroinitializer, <4 x i32> <i32 1, i32 2, i32 3, i32 0>
330  %t2 = shufflevector <4 x i32> %v2, <4 x i32> zeroinitializer, <4 x i32> <i32 1, i32 2, i32 3, i32 0>
331  %r = add nuw <4 x i32> %t1, %t2
332  ret <4 x i32> %r
333}
334
335define <4 x float> @shuffle_17fsub_fast(<4 x float> %v1, <4 x float> %v2) nounwind uwtable {
336; CHECK-LABEL: @shuffle_17fsub_fast(
337; CHECK-NEXT:    [[TMP1:%.*]] = fsub fast <4 x float> %v1, %v2
338; CHECK-NEXT:    [[TMP2:%.*]] = shufflevector <4 x float> [[TMP1]], <4 x float> undef, <4 x i32> <i32 1, i32 2, i32 3, i32 0>
339; CHECK-NEXT:    ret <4 x float> [[TMP2]]
340;
341  %t1 = shufflevector <4 x float> %v1, <4 x float> zeroinitializer, <4 x i32> <i32 1, i32 2, i32 3, i32 0>
342  %t2 = shufflevector <4 x float> %v2, <4 x float> zeroinitializer, <4 x i32> <i32 1, i32 2, i32 3, i32 0>
343  %r = fsub fast <4 x float> %t1, %t2
344  ret <4 x float> %r
345}
346
347define <4 x i32> @shuffle_17addconst(<4 x i32> %v1, <4 x i32> %v2) {
348; CHECK-LABEL: @shuffle_17addconst(
349; CHECK-NEXT:    [[TMP1:%.*]] = add <4 x i32> %v1, <i32 4, i32 1, i32 2, i32 3>
350; CHECK-NEXT:    [[TMP2:%.*]] = shufflevector <4 x i32> [[TMP1]], <4 x i32> undef, <4 x i32> <i32 1, i32 2, i32 3, i32 0>
351; CHECK-NEXT:    ret <4 x i32> [[TMP2]]
352;
353  %t1 = shufflevector <4 x i32> %v1, <4 x i32> zeroinitializer, <4 x i32> <i32 1, i32 2, i32 3, i32 0>
354  %r = add <4 x i32> %t1, <i32 1, i32 2, i32 3, i32 4>
355  ret <4 x i32> %r
356}
357
358define <4 x i32> @shuffle_17add2(<4 x i32> %v) {
359; CHECK-LABEL: @shuffle_17add2(
360; CHECK-NEXT:    [[TMP1:%.*]] = shl <4 x i32> %v, <i32 1, i32 1, i32 1, i32 1>
361; CHECK-NEXT:    ret <4 x i32> [[TMP1]]
362;
363  %t1 = shufflevector <4 x i32> %v, <4 x i32> zeroinitializer, <4 x i32> <i32 3, i32 2, i32 1, i32 0>
364  %t2 = add <4 x i32> %t1, %t1
365  %r = shufflevector <4 x i32> %t2, <4 x i32> zeroinitializer, <4 x i32> <i32 3, i32 2, i32 1, i32 0>
366  ret <4 x i32> %r
367}
368
369define <4 x i32> @shuffle_17mulsplat(<4 x i32> %v) {
370; CHECK-LABEL: @shuffle_17mulsplat(
371; CHECK-NEXT:    [[TMP1:%.*]] = mul <4 x i32> %v, %v
372; CHECK-NEXT:    [[S2:%.*]] = shufflevector <4 x i32> [[TMP1]], <4 x i32> undef, <4 x i32> zeroinitializer
373; CHECK-NEXT:    ret <4 x i32> [[S2]]
374;
375  %s1 = shufflevector <4 x i32> %v, <4 x i32> zeroinitializer, <4 x i32> zeroinitializer
376  %m1 = mul <4 x i32> %s1, %s1
377  %s2 = shufflevector <4 x i32> %m1, <4 x i32> zeroinitializer, <4 x i32> <i32 1, i32 1, i32 1, i32 1>
378  ret <4 x i32> %s2
379}
380
381; Do not reorder shuffle and binop if LHS of shuffles are of different size
382define <2 x i32> @pr19717(<4 x i32> %in0, <2 x i32> %in1) {
383; CHECK-LABEL: @pr19717(
384; CHECK-NEXT:    [[SHUFFLE:%.*]] = shufflevector <4 x i32> %in0, <4 x i32> undef, <2 x i32> zeroinitializer
385; CHECK-NEXT:    [[SHUFFLE4:%.*]] = shufflevector <2 x i32> %in1, <2 x i32> undef, <2 x i32> zeroinitializer
386; CHECK-NEXT:    [[MUL:%.*]] = mul <2 x i32> [[SHUFFLE]], [[SHUFFLE4]]
387; CHECK-NEXT:    ret <2 x i32> [[MUL]]
388;
389  %shuffle = shufflevector <4 x i32> %in0, <4 x i32> %in0, <2 x i32> zeroinitializer
390  %shuffle4 = shufflevector <2 x i32> %in1, <2 x i32> %in1, <2 x i32> zeroinitializer
391  %mul = mul <2 x i32> %shuffle, %shuffle4
392  ret <2 x i32> %mul
393}
394
395define <4 x i16> @pr19717a(<8 x i16> %in0, <8 x i16> %in1) {
396; CHECK-LABEL: @pr19717a(
397; CHECK-NEXT:    [[TMP1:%.*]] = mul <8 x i16> %in0, %in1
398; CHECK-NEXT:    [[TMP2:%.*]] = shufflevector <8 x i16> [[TMP1]], <8 x i16> undef, <4 x i32> <i32 5, i32 5, i32 5, i32 5>
399; CHECK-NEXT:    ret <4 x i16> [[TMP2]]
400;
401  %shuffle = shufflevector <8 x i16> %in0, <8 x i16> %in0, <4 x i32> <i32 5, i32 5, i32 5, i32 5>
402  %shuffle1 = shufflevector <8 x i16> %in1, <8 x i16> %in1, <4 x i32> <i32 5, i32 5, i32 5, i32 5>
403  %mul = mul <4 x i16> %shuffle, %shuffle1
404  ret <4 x i16> %mul
405}
406
407define <8 x i8> @pr19730(<16 x i8> %in0) {
408; CHECK-LABEL: @pr19730(
409; CHECK-NEXT:    [[SHUFFLE:%.*]] = shufflevector <16 x i8> %in0, <16 x i8> undef, <8 x i32> <i32 7, i32 6, i32 5, i32 4, i32 3, i32 2, i32 1, i32 0>
410; CHECK-NEXT:    [[SHUFFLE1:%.*]] = shufflevector <8 x i8> [[SHUFFLE]], <8 x i8> undef, <8 x i32> <i32 7, i32 6, i32 5, i32 4, i32 3, i32 2, i32 1, i32 0>
411; CHECK-NEXT:    ret <8 x i8> [[SHUFFLE1]]
412;
413  %shuffle = shufflevector <16 x i8> %in0, <16 x i8> undef, <8 x i32> <i32 7, i32 6, i32 5, i32 4, i32 3, i32 2, i32 1, i32 0>
414  %shuffle1 = shufflevector <8 x i8> %shuffle, <8 x i8> undef, <8 x i32> <i32 7, i32 6, i32 5, i32 4, i32 3, i32 2, i32 1, i32 0>
415  ret <8 x i8> %shuffle1
416}
417
418define i32 @pr19737(<4 x i32> %in0) {
419; CHECK-LABEL: @pr19737(
420; CHECK-NEXT:    [[RV_LHS:%.*]] = extractelement <4 x i32> %in0, i32 0
421; CHECK-NEXT:    ret i32 [[RV_LHS]]
422;
423  %shuffle.i = shufflevector <4 x i32> zeroinitializer, <4 x i32> %in0, <4 x i32> <i32 0, i32 4, i32 2, i32 6>
424  %neg.i = xor <4 x i32> %shuffle.i, <i32 -1, i32 -1, i32 -1, i32 -1>
425  %and.i = and <4 x i32> %in0, %neg.i
426  %rv = extractelement <4 x i32> %and.i, i32 0
427  ret i32 %rv
428}
429
430; In PR20059 ( http://llvm.org/pr20059 ), shufflevector operations are reordered/removed
431; for an srem operation. This is not a valid optimization because it may cause a trap
432; on div-by-zero.
433
434define <4 x i32> @pr20059(<4 x i32> %p1, <4 x i32> %p2) {
435; CHECK-LABEL: @pr20059(
436; CHECK-NEXT:    [[SPLAT1:%.*]] = shufflevector <4 x i32> %p1, <4 x i32> undef, <4 x i32> zeroinitializer
437; CHECK-NEXT:    [[SPLAT2:%.*]] = shufflevector <4 x i32> %p2, <4 x i32> undef, <4 x i32> zeroinitializer
438; CHECK-NEXT:    [[RETVAL:%.*]] = srem <4 x i32> [[SPLAT1]], [[SPLAT2]]
439; CHECK-NEXT:    ret <4 x i32> [[RETVAL]]
440;
441  %splat1 = shufflevector <4 x i32> %p1, <4 x i32> undef, <4 x i32> zeroinitializer
442  %splat2 = shufflevector <4 x i32> %p2, <4 x i32> undef, <4 x i32> zeroinitializer
443  %retval = srem <4 x i32> %splat1, %splat2
444  ret <4 x i32> %retval
445}
446
447define <4 x i32> @pr20114(<4 x i32> %__mask) {
448; CHECK-LABEL: @pr20114(
449; CHECK-NEXT:    [[MASK01_I:%.*]] = shufflevector <4 x i32> %__mask, <4 x i32> undef, <4 x i32> <i32 0, i32 0, i32 1, i32 1>
450; CHECK-NEXT:    [[MASKED_NEW_I_I_I:%.*]] = and <4 x i32> [[MASK01_I]], bitcast (<2 x i64> <i64 ptrtoint (<4 x i32> (<4 x i32>)* @pr20114 to i64), i64 ptrtoint (<4 x i32> (<4 x i32>)* @pr20114 to i64)> to <4 x i32>)
451; CHECK-NEXT:    ret <4 x i32> [[MASKED_NEW_I_I_I]]
452;
453  %mask01.i = shufflevector <4 x i32> %__mask, <4 x i32> undef, <4 x i32> <i32 0, i32 0, i32 1, i32 1>
454  %masked_new.i.i.i = and <4 x i32> bitcast (<2 x i64> <i64 ptrtoint (<4 x i32> (<4 x i32>)* @pr20114 to i64), i64 ptrtoint (<4 x i32> (<4 x i32>)* @pr20114 to i64)> to <4 x i32>), %mask01.i
455  ret <4 x i32> %masked_new.i.i.i
456}
457
458define <2 x i32*> @pr23113(<4 x i32*> %A) {
459; CHECK-LABEL: @pr23113(
460; CHECK-NEXT:    [[TMP1:%.*]] = shufflevector <4 x i32*> %A, <4 x i32*> undef, <2 x i32> <i32 0, i32 1>
461; CHECK-NEXT:    ret <2 x i32*> [[TMP1]]
462;
463  %1 = shufflevector <4 x i32*> %A, <4 x i32*> undef, <2 x i32> <i32 0, i32 1>
464  ret <2 x i32*> %1
465}
466