xref: /llvm-project/llvm/test/Transforms/InstCombine/vec_shuffle.ll (revision 56c091ea7106507b36015297ee9005c9d5fab0bf)
1; NOTE: Assertions have been autogenerated by utils/update_test_checks.py
2; RUN: opt < %s -passes=instcombine -S | FileCheck %s
3
4declare <2 x half> @llvm.fabs.v2f16(<2 x half>)
5declare <2 x float> @llvm.fabs.v2f32(<2 x float>)
6declare <4 x float> @llvm.fabs.v4f32(<4 x float>)
7declare <2 x double> @llvm.fabs.v2f64(<2 x double>)
8declare <4 x double> @llvm.fabs.v4f64(<4 x double>)
9
10define <4 x float> @test1(<4 x float> %v1) {
11; CHECK-LABEL: @test1(
12; CHECK-NEXT:    ret <4 x float> [[V1:%.*]]
13;
14  %v2 = shufflevector <4 x float> %v1, <4 x float> undef, <4 x i32> <i32 0, i32 1, i32 2, i32 3>
15  ret <4 x float> %v2
16}
17
18define <4 x float> @test2(<4 x float> %v1) {
19; CHECK-LABEL: @test2(
20; CHECK-NEXT:    ret <4 x float> [[V1:%.*]]
21;
22  %v2 = shufflevector <4 x float> %v1, <4 x float> %v1, <4 x i32> <i32 0, i32 5, i32 2, i32 7>
23  ret <4 x float> %v2
24}
25
26define float @test3(<4 x float> %A, <4 x float> %B, float %f) {
27; CHECK-LABEL: @test3(
28; CHECK-NEXT:    ret float [[F:%.*]]
29;
30  %C = insertelement <4 x float> %A, float %f, i32 0
31  %D = shufflevector <4 x float> %C, <4 x float> %B, <4 x i32> <i32 5, i32 0, i32 2, i32 7>
32  %E = extractelement <4 x float> %D, i32 1
33  ret float %E
34}
35
36define i32 @test4(<4 x i32> %X) {
37; CHECK-LABEL: @test4(
38; CHECK-NEXT:    [[R:%.*]] = extractelement <4 x i32> [[X:%.*]], i64 0
39; CHECK-NEXT:    ret i32 [[R]]
40;
41  %t = shufflevector <4 x i32> %X, <4 x i32> undef, <4 x i32> zeroinitializer
42  %r = extractelement <4 x i32> %t, i32 0
43  ret i32 %r
44}
45
46define i32 @test5(<4 x i32> %X) {
47; CHECK-LABEL: @test5(
48; CHECK-NEXT:    [[R:%.*]] = extractelement <4 x i32> [[X:%.*]], i64 3
49; CHECK-NEXT:    ret i32 [[R]]
50;
51  %t = shufflevector <4 x i32> %X, <4 x i32> undef, <4 x i32> <i32 3, i32 2, i32 undef, i32 undef>
52  %r = extractelement <4 x i32> %t, i32 0
53  ret i32 %r
54}
55
56define float @test6(<4 x float> %X) {
57; CHECK-LABEL: @test6(
58; CHECK-NEXT:    [[R:%.*]] = extractelement <4 x float> [[X:%.*]], i64 0
59; CHECK-NEXT:    ret float [[R]]
60;
61  %X1 = bitcast <4 x float> %X to <4 x i32>
62  %t = shufflevector <4 x i32> %X1, <4 x i32> undef, <4 x i32> zeroinitializer
63  %t2 = bitcast <4 x i32> %t to <4 x float>
64  %r = extractelement <4 x float> %t2, i32 0
65  ret float %r
66}
67
68define float @testvscale6(<vscale x 4 x float> %X) {
69; CHECK-LABEL: @testvscale6(
70; CHECK-NEXT:    [[T2:%.*]] = shufflevector <vscale x 4 x float> [[X:%.*]], <vscale x 4 x float> poison, <vscale x 4 x i32> zeroinitializer
71; CHECK-NEXT:    [[R:%.*]] = extractelement <vscale x 4 x float> [[T2]], i64 0
72; CHECK-NEXT:    ret float [[R]]
73;
74  %X1 = bitcast <vscale x 4 x float> %X to <vscale x 4 x i32>
75  %t = shufflevector <vscale x 4 x i32> %X1, <vscale x 4 x i32> undef, <vscale x 4 x i32> zeroinitializer
76  %t2 = bitcast <vscale x 4 x i32> %t to <vscale x 4 x float>
77  %r = extractelement <vscale x 4 x float> %t2, i32 0
78  ret float %r
79}
80
81
82define <4 x float> @test7(<4 x float> %x) {
83; CHECK-LABEL: @test7(
84; CHECK-NEXT:    [[R:%.*]] = shufflevector <4 x float> [[X:%.*]], <4 x float> <float poison, float poison, float undef, float undef>, <4 x i32> <i32 0, i32 1, i32 6, i32 7>
85; CHECK-NEXT:    ret <4 x float> [[R]]
86;
87  %r = shufflevector <4 x float> %x, <4 x float> undef, <4 x i32> < i32 0, i32 1, i32 6, i32 7 >
88  ret <4 x float> %r
89}
90
91; This should not turn into a single shuffle.
92define <4 x float> @test8(<4 x float> %x, <4 x float> %y) {
93; CHECK-LABEL: @test8(
94; CHECK-NEXT:    [[T132:%.*]] = shufflevector <4 x float> [[X:%.*]], <4 x float> <float poison, float undef, float poison, float poison>, <4 x i32> <i32 1, i32 5, i32 3, i32 poison>
95; CHECK-NEXT:    [[T134:%.*]] = shufflevector <4 x float> [[T132]], <4 x float> [[Y:%.*]], <4 x i32> <i32 0, i32 1, i32 2, i32 4>
96; CHECK-NEXT:    ret <4 x float> [[T134]]
97;
98  %t4 = extractelement <4 x float> %x, i32 1
99  %t2 = extractelement <4 x float> %x, i32 3
100  %t1 = extractelement <4 x float> %y, i32 0
101  %t128 = insertelement <4 x float> undef, float %t4, i32 0
102  %t130 = insertelement <4 x float> %t128, float undef, i32 1
103  %t132 = insertelement <4 x float> %t130, float %t2, i32 2
104  %t134 = insertelement <4 x float> %t132, float %t1, i32 3
105  ret <4 x float> %t134
106}
107
108; Test fold of two shuffles where the first shuffle vectors inputs are a
109; different length then the second.
110define <4 x i8> @test9(<16 x i8> %t6) {
111; CHECK-LABEL: @test9(
112; CHECK-NEXT:    [[T9:%.*]] = shufflevector <16 x i8> [[T6:%.*]], <16 x i8> poison, <4 x i32> <i32 13, i32 9, i32 4, i32 13>
113; CHECK-NEXT:    ret <4 x i8> [[T9]]
114;
115  %t7 = shufflevector <16 x i8> %t6, <16 x i8> undef, <4 x i32> < i32 13, i32 9, i32 4, i32 13 >
116  %t9 = shufflevector <4 x i8> %t7, <4 x i8> undef, <4 x i32> < i32 3, i32 1, i32 2, i32 0 >
117  ret <4 x i8> %t9
118}
119
120; Same as test9, but make sure that "undef" mask values are not confused with
121; mask values of 2*N, where N is the mask length.  These shuffles should not
122; be folded (because [8,9,4,8] may not be a mask supported by the target).
123
124define <4 x i8> @test9a(<16 x i8> %t6) {
125; CHECK-LABEL: @test9a(
126; CHECK-NEXT:    [[T7:%.*]] = shufflevector <16 x i8> [[T6:%.*]], <16 x i8> poison, <4 x i32> <i32 poison, i32 9, i32 4, i32 8>
127; CHECK-NEXT:    [[T9:%.*]] = shufflevector <4 x i8> [[T7]], <4 x i8> poison, <4 x i32> <i32 3, i32 1, i32 2, i32 poison>
128; CHECK-NEXT:    ret <4 x i8> [[T9]]
129;
130  %t7 = shufflevector <16 x i8> %t6, <16 x i8> undef, <4 x i32> < i32 undef, i32 9, i32 4, i32 8 >
131  %t9 = shufflevector <4 x i8> %t7, <4 x i8> undef, <4 x i32> < i32 3, i32 1, i32 2, i32 0 >
132  ret <4 x i8> %t9
133}
134
135; Test fold of two shuffles where the first shuffle vectors inputs are a
136; different length then the second.
137define <4 x i8> @test9b(<4 x i8> %t6, <4 x i8> %t7) {
138; CHECK-LABEL: @test9b(
139; CHECK-NEXT:    [[T9:%.*]] = shufflevector <4 x i8> [[T6:%.*]], <4 x i8> [[T7:%.*]], <4 x i32> <i32 0, i32 1, i32 4, i32 5>
140; CHECK-NEXT:    ret <4 x i8> [[T9]]
141;
142  %t1 = shufflevector <4 x i8> %t6, <4 x i8> %t7, <8 x i32> <i32 0, i32 1, i32 4, i32 5, i32 4, i32 5, i32 2, i32 3>
143  %t9 = shufflevector <8 x i8> %t1, <8 x i8> undef, <4 x i32> <i32 0, i32 1, i32 4, i32 5>
144  ret <4 x i8> %t9
145}
146
147; Redundant vector splats should be removed.  Radar 8597790.
148define <4 x i32> @test10(<4 x i32> %t5) {
149; CHECK-LABEL: @test10(
150; CHECK-NEXT:    [[T7:%.*]] = shufflevector <4 x i32> [[T5:%.*]], <4 x i32> poison, <4 x i32> <i32 1, i32 1, i32 1, i32 1>
151; CHECK-NEXT:    ret <4 x i32> [[T7]]
152;
153  %t6 = shufflevector <4 x i32> %t5, <4 x i32> undef, <4 x i32> <i32 1, i32 undef, i32 undef, i32 undef>
154  %t7 = shufflevector <4 x i32> %t6, <4 x i32> undef, <4 x i32> zeroinitializer
155  ret <4 x i32> %t7
156}
157
158; Test fold of two shuffles where the two shufflevector inputs's op1 are the same.
159
160define <8 x i8> @test11(<16 x i8> %t6) {
161; CHECK-LABEL: @test11(
162; CHECK-NEXT:    [[T3:%.*]] = shufflevector <16 x i8> [[T6:%.*]], <16 x i8> poison, <8 x i32> <i32 0, i32 1, i32 2, i32 3, i32 4, i32 5, i32 6, i32 7>
163; CHECK-NEXT:    ret <8 x i8> [[T3]]
164;
165  %t1 = shufflevector <16 x i8> %t6, <16 x i8> undef, <4 x i32> <i32 0, i32 1, i32 2, i32 3>
166  %t2 = shufflevector <16 x i8> %t6, <16 x i8> undef, <4 x i32> <i32 4, i32 5, i32 6, i32 7>
167  %t3 = shufflevector <4 x i8> %t1, <4 x i8> %t2, <8 x i32> <i32 0, i32 1, i32 2, i32 3, i32 4, i32 5, i32 6, i32 7>
168  ret <8 x i8> %t3
169}
170
171; Test fold of two shuffles where the first shufflevector's inputs are the same as the second.
172
173define <8 x i8> @test12(<8 x i8> %t6, <8 x i8> %t2) {
174; CHECK-LABEL: @test12(
175; CHECK-NEXT:    [[T3:%.*]] = shufflevector <8 x i8> [[T6:%.*]], <8 x i8> [[T2:%.*]], <8 x i32> <i32 0, i32 1, i32 2, i32 3, i32 9, i32 8, i32 11, i32 12>
176; CHECK-NEXT:    ret <8 x i8> [[T3]]
177;
178  %t1 = shufflevector <8 x i8> %t6, <8 x i8> undef, <8 x i32> <i32 0, i32 1, i32 2, i32 3, i32 5, i32 4, i32 undef, i32 7>
179  %t3 = shufflevector <8 x i8> %t1, <8 x i8> %t2, <8 x i32> <i32 0, i32 1, i32 2, i32 3, i32 9, i32 8, i32 11, i32 12>
180  ret <8 x i8> %t3
181}
182
183; Test fold of two shuffles where the first shufflevector's inputs are the same as the second.
184
185define <8 x i8> @test12a(<8 x i8> %t6, <8 x i8> %t2) {
186; CHECK-LABEL: @test12a(
187; CHECK-NEXT:    [[T3:%.*]] = shufflevector <8 x i8> [[T2:%.*]], <8 x i8> [[T6:%.*]], <8 x i32> <i32 0, i32 3, i32 1, i32 4, i32 8, i32 9, i32 10, i32 11>
188; CHECK-NEXT:    ret <8 x i8> [[T3]]
189;
190  %t1 = shufflevector <8 x i8> %t6, <8 x i8> undef, <8 x i32> <i32 0, i32 1, i32 2, i32 3, i32 5, i32 4, i32 undef, i32 7>
191  %t3 = shufflevector <8 x i8> %t2, <8 x i8> %t1, <8 x i32> <i32 0, i32 3, i32 1, i32 4, i32 8, i32 9, i32 10, i32 11>
192  ret <8 x i8> %t3
193}
194
195; The mask length of the 1st shuffle can be reduced to eliminate the 2nd shuffle.
196
197define <2 x i8> @extract_subvector_of_shuffle(<2 x i8> %x, <2 x i8> %y) {
198; CHECK-LABEL: @extract_subvector_of_shuffle(
199; CHECK-NEXT:    [[EXTRACT_SUBV:%.*]] = shufflevector <2 x i8> [[X:%.*]], <2 x i8> [[Y:%.*]], <2 x i32> <i32 0, i32 2>
200; CHECK-NEXT:    ret <2 x i8> [[EXTRACT_SUBV]]
201;
202  %shuf = shufflevector <2 x i8> %x, <2 x i8> %y, <3 x i32> <i32 0, i32 2, i32 0>
203  %extract_subv = shufflevector <3 x i8> %shuf, <3 x i8> undef, <2 x i32> <i32 0, i32 1>
204  ret <2 x i8> %extract_subv
205}
206
207; Undef elements in either mask are ok. Undefs from the 2nd shuffle mask should propagate to the new shuffle.
208; The type of the inputs does not have to match the output type.
209
210define <4 x i8> @extract_subvector_of_shuffle_undefs_types(<2 x i8> %x, <2 x i8> %y) {
211; CHECK-LABEL: @extract_subvector_of_shuffle_undefs_types(
212; CHECK-NEXT:    [[EXTRACT_SUBV:%.*]] = shufflevector <2 x i8> [[X:%.*]], <2 x i8> [[Y:%.*]], <4 x i32> <i32 poison, i32 2, i32 0, i32 poison>
213; CHECK-NEXT:    ret <4 x i8> [[EXTRACT_SUBV]]
214;
215  %shuf = shufflevector <2 x i8> %x, <2 x i8> %y, <5 x i32> <i32 undef, i32 2, i32 0, i32 1, i32 0>
216  %extract_subv = shufflevector <5 x i8> %shuf, <5 x i8> undef, <4 x i32> <i32 0, i32 1, i32 2, i32 undef>
217  ret <4 x i8> %extract_subv
218}
219
220; Extra uses are not ok - we only do the transform when we can eliminate an instruction.
221
222declare void @use_v5i8(<5 x i8>)
223
224define <4 x i8> @extract_subvector_of_shuffle_extra_use(<2 x i8> %x, <2 x i8> %y) {
225; CHECK-LABEL: @extract_subvector_of_shuffle_extra_use(
226; CHECK-NEXT:    [[SHUF:%.*]] = shufflevector <2 x i8> [[X:%.*]], <2 x i8> [[Y:%.*]], <5 x i32> <i32 poison, i32 2, i32 0, i32 1, i32 0>
227; CHECK-NEXT:    call void @use_v5i8(<5 x i8> [[SHUF]])
228; CHECK-NEXT:    [[EXTRACT_SUBV:%.*]] = shufflevector <5 x i8> [[SHUF]], <5 x i8> poison, <4 x i32> <i32 0, i32 1, i32 2, i32 poison>
229; CHECK-NEXT:    ret <4 x i8> [[EXTRACT_SUBV]]
230;
231  %shuf = shufflevector <2 x i8> %x, <2 x i8> %y, <5 x i32> <i32 undef, i32 2, i32 0, i32 1, i32 0>
232  call void @use_v5i8(<5 x i8> %shuf)
233  %extract_subv = shufflevector <5 x i8> %shuf, <5 x i8> undef, <4 x i32> <i32 0, i32 1, i32 2, i32 undef>
234  ret <4 x i8> %extract_subv
235}
236
237define <2 x i8> @test13a(i8 %x1, i8 %x2) {
238; CHECK-LABEL: @test13a(
239; CHECK-NEXT:    [[TMP1:%.*]] = insertelement <2 x i8> poison, i8 [[X2:%.*]], i64 0
240; CHECK-NEXT:    [[TMP2:%.*]] = insertelement <2 x i8> [[TMP1]], i8 [[X1:%.*]], i64 1
241; CHECK-NEXT:    [[D:%.*]] = add <2 x i8> [[TMP2]], <i8 7, i8 5>
242; CHECK-NEXT:    ret <2 x i8> [[D]]
243;
244  %A = insertelement <2 x i8> undef, i8 %x1, i32 0
245  %B = insertelement <2 x i8> %A, i8 %x2, i32 1
246  %C = add <2 x i8> %B, <i8 5, i8 7>
247  %D = shufflevector <2 x i8> %C, <2 x i8> undef, <2 x i32> <i32 1, i32 0>
248  ret <2 x i8> %D
249}
250
251; Increasing length of vector ops is not a good canonicalization.
252
253define <3 x i32> @add_wider(i32 %y, i32 %z) {
254; CHECK-LABEL: @add_wider(
255; CHECK-NEXT:    [[I0:%.*]] = insertelement <2 x i32> poison, i32 [[Y:%.*]], i64 0
256; CHECK-NEXT:    [[I1:%.*]] = insertelement <2 x i32> [[I0]], i32 [[Z:%.*]], i64 1
257; CHECK-NEXT:    [[A:%.*]] = add <2 x i32> [[I1]], splat (i32 255)
258; CHECK-NEXT:    [[EXT:%.*]] = shufflevector <2 x i32> [[A]], <2 x i32> poison, <3 x i32> <i32 0, i32 1, i32 poison>
259; CHECK-NEXT:    ret <3 x i32> [[EXT]]
260;
261  %i0 = insertelement <2 x i32> undef, i32 %y, i32 0
262  %i1 = insertelement <2 x i32> %i0, i32 %z, i32 1
263  %a = add <2 x i32> %i1, <i32 255, i32 255>
264  %ext = shufflevector <2 x i32> %a, <2 x i32> undef, <3 x i32> <i32 0, i32 1, i32 undef>
265  ret <3 x i32> %ext
266}
267
268; Increasing length of vector ops must be safe from illegal undef propagation.
269
270define <3 x i32> @div_wider(i32 %y, i32 %z) {
271; CHECK-LABEL: @div_wider(
272; CHECK-NEXT:    [[I0:%.*]] = insertelement <2 x i32> poison, i32 [[Y:%.*]], i64 0
273; CHECK-NEXT:    [[I1:%.*]] = insertelement <2 x i32> [[I0]], i32 [[Z:%.*]], i64 1
274; CHECK-NEXT:    [[A:%.*]] = sdiv <2 x i32> [[I1]], splat (i32 255)
275; CHECK-NEXT:    [[EXT:%.*]] = shufflevector <2 x i32> [[A]], <2 x i32> poison, <3 x i32> <i32 0, i32 1, i32 poison>
276; CHECK-NEXT:    ret <3 x i32> [[EXT]]
277;
278  %i0 = insertelement <2 x i32> undef, i32 %y, i32 0
279  %i1 = insertelement <2 x i32> %i0, i32 %z, i32 1
280  %a = sdiv <2 x i32> %i1, <i32 255, i32 255>
281  %ext = shufflevector <2 x i32> %a, <2 x i32> undef, <3 x i32> <i32 0, i32 1, i32 undef>
282  ret <3 x i32> %ext
283}
284
285; Increasing length of insertelements (no math ops) is a good canonicalization.
286
287define <3 x i8> @fold_inselts_with_widening_shuffle(i8 %x, i8 %y) {
288; CHECK-LABEL: @fold_inselts_with_widening_shuffle(
289; CHECK-NEXT:    [[TMP1:%.*]] = insertelement <3 x i8> poison, i8 [[X:%.*]], i64 0
290; CHECK-NEXT:    [[WIDEN:%.*]] = insertelement <3 x i8> [[TMP1]], i8 [[Y:%.*]], i64 1
291; CHECK-NEXT:    ret <3 x i8> [[WIDEN]]
292;
293  %ins0 = insertelement <2 x i8> undef, i8 %x, i32 0
294  %ins1 = insertelement <2 x i8> %ins0, i8 %y, i32 1
295  %widen = shufflevector <2 x i8> %ins1, <2 x i8> undef, <3 x i32> <i32 0, i32 1, i32 undef>
296  ret <3 x i8> %widen
297}
298
299define <2 x i8> @test13b(i8 %x) {
300; CHECK-LABEL: @test13b(
301; CHECK-NEXT:    [[B:%.*]] = insertelement <2 x i8> poison, i8 [[X:%.*]], i64 1
302; CHECK-NEXT:    ret <2 x i8> [[B]]
303;
304  %A = insertelement <2 x i8> undef, i8 %x, i32 0
305  %B = shufflevector <2 x i8> %A, <2 x i8> undef, <2 x i32> <i32 undef, i32 0>
306  ret <2 x i8> %B
307}
308
309define <2 x i8> @test13c(i8 %x1, i8 %x2) {
310; CHECK-LABEL: @test13c(
311; CHECK-NEXT:    [[TMP1:%.*]] = insertelement <2 x i8> poison, i8 [[X1:%.*]], i64 0
312; CHECK-NEXT:    [[C:%.*]] = insertelement <2 x i8> [[TMP1]], i8 [[X2:%.*]], i64 1
313; CHECK-NEXT:    ret <2 x i8> [[C]]
314;
315  %A = insertelement <4 x i8> undef, i8 %x1, i32 0
316  %B = insertelement <4 x i8> %A, i8 %x2, i32 2
317  %C = shufflevector <4 x i8> %B, <4 x i8> undef, <2 x i32> <i32 0, i32 2>
318  ret <2 x i8> %C
319}
320
321define void @test14(i16 %conv10) {
322; CHECK-LABEL: @test14(
323; CHECK-NEXT:    store <4 x i16> <i16 undef, i16 undef, i16 undef, i16 23>, ptr undef, align 8
324; CHECK-NEXT:    ret void
325;
326  %t = alloca <4 x i16>, align 8
327  %vecinit6 = insertelement <4 x i16> undef, i16 23, i32 3
328  store <4 x i16> %vecinit6, ptr undef
329  %t1 = load <4 x i16>, ptr undef
330  %vecinit11 = insertelement <4 x i16> undef, i16 %conv10, i32 3
331  %div = udiv <4 x i16> %t1, %vecinit11
332  store <4 x i16> %div, ptr %t
333  %t4 = load <4 x i16>, ptr %t
334  %t5 = shufflevector <4 x i16> %t4, <4 x i16> undef, <2 x i32> <i32 2, i32 0>
335  %cmp = icmp ule <2 x i16> %t5, undef
336  %sext = sext <2 x i1> %cmp to <2 x i16>
337  ret void
338}
339
340; Check that sequences of insert/extract element are
341; collapsed into valid shuffle instruction with correct shuffle indexes.
342
343define <4 x float> @test15a(<4 x float> %LHS, <4 x float> %RHS) {
344; CHECK-LABEL: @test15a(
345; CHECK-NEXT:    [[T4:%.*]] = shufflevector <4 x float> [[LHS:%.*]], <4 x float> [[RHS:%.*]], <4 x i32> <i32 4, i32 0, i32 6, i32 6>
346; CHECK-NEXT:    ret <4 x float> [[T4]]
347;
348  %t1 = extractelement <4 x float> %LHS, i32 0
349  %t2 = insertelement <4 x float> %RHS, float %t1, i32 1
350  %t3 = extractelement <4 x float> %RHS, i32 2
351  %t4 = insertelement <4 x float> %t2, float %t3, i32 3
352  ret <4 x float> %t4
353}
354
355define <4 x float> @test15b(<4 x float> %LHS, <4 x float> %RHS) {
356; CHECK-LABEL: @test15b(
357; CHECK-NEXT:    [[T5:%.*]] = shufflevector <4 x float> [[LHS:%.*]], <4 x float> [[RHS:%.*]], <4 x i32> <i32 4, i32 3, i32 6, i32 6>
358; CHECK-NEXT:    ret <4 x float> [[T5]]
359;
360  %t0 = extractelement <4 x float> %LHS, i32 3
361  %t1 = insertelement <4 x float> %RHS, float %t0, i32 0
362  %t2 = extractelement <4 x float> %t1, i32 0
363  %t3 = insertelement <4 x float> %RHS, float %t2, i32 1
364  %t4 = extractelement <4 x float> %RHS, i32 2
365  %t5 = insertelement <4 x float> %t3, float %t4, i32 3
366  ret <4 x float> %t5
367}
368
369define <1 x i32> @test16a(i32 %ele) {
370; CHECK-LABEL: @test16a(
371; CHECK-NEXT:    ret <1 x i32> splat (i32 2)
372;
373  %t0 = insertelement <2 x i32> <i32 1, i32 undef>, i32 %ele, i32 1
374  %t1 = shl <2 x i32> %t0, <i32 1, i32 1>
375  %t2 = shufflevector <2 x i32> %t1, <2 x i32> undef, <1 x i32> <i32 0>
376  ret <1 x i32> %t2
377}
378
379define <4 x i8> @test16b(i8 %ele) {
380; CHECK-LABEL: @test16b(
381; CHECK-NEXT:    ret <4 x i8> splat (i8 2)
382;
383  %t0 = insertelement <8 x i8> <i8 1, i8 1, i8 1, i8 1, i8 1, i8 1, i8 undef, i8 1>, i8 %ele, i32 6
384  %t1 = shl <8 x i8> %t0, <i8 1, i8 1, i8 1, i8 1, i8 1, i8 1, i8 1, i8 1>
385  %t2 = shufflevector <8 x i8> %t1, <8 x i8> undef, <4 x i32> <i32 1, i32 2, i32 3, i32 4>
386  ret <4 x i8> %t2
387}
388
389; If composition of two shuffles is identity, shuffles can be removed.
390define <4 x i32> @shuffle_17ident(<4 x i32> %v) {
391; CHECK-LABEL: @shuffle_17ident(
392; CHECK-NEXT:    ret <4 x i32> [[V:%.*]]
393;
394  %shuffle = shufflevector <4 x i32> %v, <4 x i32> zeroinitializer, <4 x i32> <i32 1, i32 2, i32 3, i32 0>
395  %shuffle2 = shufflevector <4 x i32> %shuffle, <4 x i32> zeroinitializer, <4 x i32> <i32 3, i32 0, i32 1, i32 2>
396  ret <4 x i32> %shuffle2
397}
398
399; swizzle can be put after operation
400define <4 x i32> @shuffle_17and(<4 x i32> %v1, <4 x i32> %v2) {
401; CHECK-LABEL: @shuffle_17and(
402; CHECK-NEXT:    [[TMP1:%.*]] = and <4 x i32> [[V1:%.*]], [[V2:%.*]]
403; CHECK-NEXT:    [[R:%.*]] = shufflevector <4 x i32> [[TMP1]], <4 x i32> poison, <4 x i32> <i32 1, i32 2, i32 3, i32 0>
404; CHECK-NEXT:    ret <4 x i32> [[R]]
405;
406  %t1 = shufflevector <4 x i32> %v1, <4 x i32> zeroinitializer, <4 x i32> <i32 1, i32 2, i32 3, i32 0>
407  %t2 = shufflevector <4 x i32> %v2, <4 x i32> zeroinitializer, <4 x i32> <i32 1, i32 2, i32 3, i32 0>
408  %r = and <4 x i32> %t1, %t2
409  ret <4 x i32> %r
410}
411
412declare void @use(<2 x float>)
413declare void @use4(<4 x float>)
414
415; One extra use is ok to transform.
416
417define <2 x float> @shuffle_fadd_multiuse(<2 x float> %v1, <2 x float> %v2) {
418; CHECK-LABEL: @shuffle_fadd_multiuse(
419; CHECK-NEXT:    [[T1:%.*]] = shufflevector <2 x float> [[V1:%.*]], <2 x float> poison, <2 x i32> <i32 1, i32 0>
420; CHECK-NEXT:    [[TMP1:%.*]] = fadd <2 x float> [[V1]], [[V2:%.*]]
421; CHECK-NEXT:    [[R:%.*]] = shufflevector <2 x float> [[TMP1]], <2 x float> poison, <2 x i32> <i32 1, i32 0>
422; CHECK-NEXT:    call void @use(<2 x float> [[T1]])
423; CHECK-NEXT:    ret <2 x float> [[R]]
424;
425  %t1 = shufflevector <2 x float> %v1, <2 x float> undef, <2 x i32> <i32 1, i32 0>
426  %t2 = shufflevector <2 x float> %v2, <2 x float> undef, <2 x i32> <i32 1, i32 0>
427  %r = fadd <2 x float> %t1, %t2
428  call void @use(<2 x float> %t1)
429  ret <2 x float> %r
430}
431
432define <2 x float> @shuffle_fdiv_multiuse(<2 x float> %v1, <2 x float> %v2) {
433; CHECK-LABEL: @shuffle_fdiv_multiuse(
434; CHECK-NEXT:    [[T2:%.*]] = shufflevector <2 x float> [[V2:%.*]], <2 x float> poison, <2 x i32> <i32 1, i32 0>
435; CHECK-NEXT:    [[TMP1:%.*]] = fdiv <2 x float> [[V1:%.*]], [[V2]]
436; CHECK-NEXT:    [[R:%.*]] = shufflevector <2 x float> [[TMP1]], <2 x float> poison, <2 x i32> <i32 1, i32 0>
437; CHECK-NEXT:    call void @use(<2 x float> [[T2]])
438; CHECK-NEXT:    ret <2 x float> [[R]]
439;
440  %t1 = shufflevector <2 x float> %v1, <2 x float> undef, <2 x i32> <i32 1, i32 0>
441  %t2 = shufflevector <2 x float> %v2, <2 x float> undef, <2 x i32> <i32 1, i32 0>
442  %r = fdiv <2 x float> %t1, %t2
443  call void @use(<2 x float> %t2)
444  ret <2 x float> %r
445}
446
447; But 2 extra uses would require an extra instruction.
448
449define <2 x float> @shuffle_fsub_multiuse(<2 x float> %v1, <2 x float> %v2) {
450; CHECK-LABEL: @shuffle_fsub_multiuse(
451; CHECK-NEXT:    [[T1:%.*]] = shufflevector <2 x float> [[V1:%.*]], <2 x float> poison, <2 x i32> <i32 1, i32 0>
452; CHECK-NEXT:    [[T2:%.*]] = shufflevector <2 x float> [[V2:%.*]], <2 x float> poison, <2 x i32> <i32 1, i32 0>
453; CHECK-NEXT:    [[R:%.*]] = fsub <2 x float> [[T1]], [[T2]]
454; CHECK-NEXT:    call void @use(<2 x float> [[T1]])
455; CHECK-NEXT:    call void @use(<2 x float> [[T2]])
456; CHECK-NEXT:    ret <2 x float> [[R]]
457;
458  %t1 = shufflevector <2 x float> %v1, <2 x float> undef, <2 x i32> <i32 1, i32 0>
459  %t2 = shufflevector <2 x float> %v2, <2 x float> undef, <2 x i32> <i32 1, i32 0>
460  %r = fsub <2 x float> %t1, %t2
461  call void @use(<2 x float> %t1)
462  call void @use(<2 x float> %t2)
463  ret <2 x float> %r
464}
465
466define <4 x i32> @shuffle_17add(<4 x i32> %v1, <4 x i32> %v2) {
467; CHECK-LABEL: @shuffle_17add(
468; CHECK-NEXT:    [[TMP1:%.*]] = add <4 x i32> [[V1:%.*]], [[V2:%.*]]
469; CHECK-NEXT:    [[R:%.*]] = shufflevector <4 x i32> [[TMP1]], <4 x i32> poison, <4 x i32> <i32 1, i32 2, i32 3, i32 0>
470; CHECK-NEXT:    ret <4 x i32> [[R]]
471;
472  %t1 = shufflevector <4 x i32> %v1, <4 x i32> zeroinitializer, <4 x i32> <i32 1, i32 2, i32 3, i32 0>
473  %t2 = shufflevector <4 x i32> %v2, <4 x i32> zeroinitializer, <4 x i32> <i32 1, i32 2, i32 3, i32 0>
474  %r = add <4 x i32> %t1, %t2
475  ret <4 x i32> %r
476}
477
478define <4 x i32> @shuffle_17addnsw(<4 x i32> %v1, <4 x i32> %v2) {
479; CHECK-LABEL: @shuffle_17addnsw(
480; CHECK-NEXT:    [[TMP1:%.*]] = add nsw <4 x i32> [[V1:%.*]], [[V2:%.*]]
481; CHECK-NEXT:    [[R:%.*]] = shufflevector <4 x i32> [[TMP1]], <4 x i32> poison, <4 x i32> <i32 1, i32 2, i32 3, i32 0>
482; CHECK-NEXT:    ret <4 x i32> [[R]]
483;
484  %t1 = shufflevector <4 x i32> %v1, <4 x i32> zeroinitializer, <4 x i32> <i32 1, i32 2, i32 3, i32 0>
485  %t2 = shufflevector <4 x i32> %v2, <4 x i32> zeroinitializer, <4 x i32> <i32 1, i32 2, i32 3, i32 0>
486  %r = add nsw <4 x i32> %t1, %t2
487  ret <4 x i32> %r
488}
489
490define <4 x i32> @shuffle_17addnuw(<4 x i32> %v1, <4 x i32> %v2) {
491; CHECK-LABEL: @shuffle_17addnuw(
492; CHECK-NEXT:    [[TMP1:%.*]] = add nuw <4 x i32> [[V1:%.*]], [[V2:%.*]]
493; CHECK-NEXT:    [[R:%.*]] = shufflevector <4 x i32> [[TMP1]], <4 x i32> poison, <4 x i32> <i32 1, i32 2, i32 3, i32 0>
494; CHECK-NEXT:    ret <4 x i32> [[R]]
495;
496  %t1 = shufflevector <4 x i32> %v1, <4 x i32> zeroinitializer, <4 x i32> <i32 1, i32 2, i32 3, i32 0>
497  %t2 = shufflevector <4 x i32> %v2, <4 x i32> zeroinitializer, <4 x i32> <i32 1, i32 2, i32 3, i32 0>
498  %r = add nuw <4 x i32> %t1, %t2
499  ret <4 x i32> %r
500}
501
502define <4 x float> @shuffle_17fsub_fast(<4 x float> %v1, <4 x float> %v2) {
503; CHECK-LABEL: @shuffle_17fsub_fast(
504; CHECK-NEXT:    [[TMP1:%.*]] = fsub fast <4 x float> [[V1:%.*]], [[V2:%.*]]
505; CHECK-NEXT:    [[R:%.*]] = shufflevector <4 x float> [[TMP1]], <4 x float> poison, <4 x i32> <i32 1, i32 2, i32 3, i32 0>
506; CHECK-NEXT:    ret <4 x float> [[R]]
507;
508  %t1 = shufflevector <4 x float> %v1, <4 x float> zeroinitializer, <4 x i32> <i32 1, i32 2, i32 3, i32 0>
509  %t2 = shufflevector <4 x float> %v2, <4 x float> zeroinitializer, <4 x i32> <i32 1, i32 2, i32 3, i32 0>
510  %r = fsub fast <4 x float> %t1, %t2
511  ret <4 x float> %r
512}
513
514define <4 x i32> @add_const(<4 x i32> %v) {
515; CHECK-LABEL: @add_const(
516; CHECK-NEXT:    [[TMP1:%.*]] = add <4 x i32> [[V:%.*]], <i32 44, i32 41, i32 42, i32 43>
517; CHECK-NEXT:    [[R:%.*]] = shufflevector <4 x i32> [[TMP1]], <4 x i32> poison, <4 x i32> <i32 1, i32 2, i32 3, i32 0>
518; CHECK-NEXT:    ret <4 x i32> [[R]]
519;
520  %t1 = shufflevector <4 x i32> %v, <4 x i32> undef, <4 x i32> <i32 1, i32 2, i32 3, i32 0>
521  %r = add <4 x i32> %t1, <i32 41, i32 42, i32 43, i32 44>
522  ret <4 x i32> %r
523}
524
525define <4 x i32> @sub_const(<4 x i32> %v) {
526; CHECK-LABEL: @sub_const(
527; CHECK-NEXT:    [[TMP1:%.*]] = sub <4 x i32> <i32 44, i32 43, i32 42, i32 41>, [[V:%.*]]
528; CHECK-NEXT:    [[R:%.*]] = shufflevector <4 x i32> [[TMP1]], <4 x i32> poison, <4 x i32> <i32 3, i32 2, i32 1, i32 0>
529; CHECK-NEXT:    ret <4 x i32> [[R]]
530;
531  %t1 = shufflevector <4 x i32> %v, <4 x i32> undef, <4 x i32> <i32 3, i32 2, i32 1, i32 0>
532  %r = sub <4 x i32> <i32 41, i32 42, i32 43, i32 44>, %t1
533  ret <4 x i32> %r
534}
535
536; Math before shuffle requires an extra shuffle.
537
538define <2 x float> @fadd_const_multiuse(<2 x float> %v) {
539; CHECK-LABEL: @fadd_const_multiuse(
540; CHECK-NEXT:    [[T1:%.*]] = shufflevector <2 x float> [[V:%.*]], <2 x float> poison, <2 x i32> <i32 1, i32 0>
541; CHECK-NEXT:    [[R:%.*]] = fadd <2 x float> [[T1]], <float 4.100000e+01, float 4.200000e+01>
542; CHECK-NEXT:    call void @use(<2 x float> [[T1]])
543; CHECK-NEXT:    ret <2 x float> [[R]]
544;
545  %t1 = shufflevector <2 x float> %v, <2 x float> undef, <2 x i32> <i32 1, i32 0>
546  %r = fadd <2 x float> %t1, <float 41.0, float 42.0>
547  call void @use(<2 x float> %t1)
548  ret <2 x float> %r
549}
550
551; Math before splat allows replacing constant elements with undef lanes.
552
553define <4 x i32> @mul_const_splat(<4 x i32> %v) {
554; CHECK-LABEL: @mul_const_splat(
555; CHECK-NEXT:    [[TMP1:%.*]] = mul <4 x i32> [[V:%.*]], <i32 poison, i32 42, i32 poison, i32 poison>
556; CHECK-NEXT:    [[R:%.*]] = shufflevector <4 x i32> [[TMP1]], <4 x i32> poison, <4 x i32> <i32 1, i32 1, i32 1, i32 1>
557; CHECK-NEXT:    ret <4 x i32> [[R]]
558;
559  %t1 = shufflevector <4 x i32> %v, <4 x i32> undef, <4 x i32> <i32 1, i32 1, i32 1, i32 1>
560  %r = mul <4 x i32> <i32 42, i32 42, i32 42, i32 42>, %t1
561  ret <4 x i32> %r
562}
563
564; Take 2 elements of a vector and shift each of those by a different amount
565
566define <4 x i32> @lshr_const_half_splat(<4 x i32> %v) {
567; CHECK-LABEL: @lshr_const_half_splat(
568; CHECK-NEXT:    [[TMP1:%.*]] = lshr <4 x i32> <i32 poison, i32 8, i32 9, i32 poison>, [[V:%.*]]
569; CHECK-NEXT:    [[R:%.*]] = shufflevector <4 x i32> [[TMP1]], <4 x i32> poison, <4 x i32> <i32 1, i32 1, i32 2, i32 2>
570; CHECK-NEXT:    ret <4 x i32> [[R]]
571;
572  %t1 = shufflevector <4 x i32> %v, <4 x i32> undef, <4 x i32> <i32 1, i32 1, i32 2, i32 2>
573  %r = lshr <4 x i32> <i32 8, i32 8, i32 9, i32 9>, %t1
574  ret <4 x i32> %r
575}
576
577; We can't change this because there's no pre-shuffle version of the fmul constant.
578
579define <2 x float> @fmul_const_invalid_constant(<2 x float> %v) {
580; CHECK-LABEL: @fmul_const_invalid_constant(
581; CHECK-NEXT:    [[T1:%.*]] = shufflevector <2 x float> [[V:%.*]], <2 x float> poison, <2 x i32> zeroinitializer
582; CHECK-NEXT:    [[R:%.*]] = fmul <2 x float> [[T1]], <float 4.100000e+01, float 4.200000e+01>
583; CHECK-NEXT:    ret <2 x float> [[R]]
584;
585  %t1 = shufflevector <2 x float> %v, <2 x float> undef, <2 x i32> <i32 0, i32 0>
586  %r = fmul <2 x float> %t1, <float 41.0, float 42.0>
587  ret <2 x float> %r
588}
589
590; Reduce the width of the binop by moving it ahead of a shuffle.
591
592define <4 x i8> @widening_shuffle_add_1(<2 x i8> %x) {
593; CHECK-LABEL: @widening_shuffle_add_1(
594; CHECK-NEXT:    [[TMP1:%.*]] = add <2 x i8> [[X:%.*]], <i8 42, i8 43>
595; CHECK-NEXT:    [[R:%.*]] = shufflevector <2 x i8> [[TMP1]], <2 x i8> poison, <4 x i32> <i32 0, i32 1, i32 poison, i32 poison>
596; CHECK-NEXT:    ret <4 x i8> [[R]]
597;
598  %widex = shufflevector <2 x i8> %x, <2 x i8> undef, <4 x i32> <i32 0, i32 1, i32 undef, i32 undef>
599  %r = add <4 x i8> %widex, <i8 42, i8 43, i8 44, i8 45>
600  ret <4 x i8> %r
601}
602
603; Reduce the width of the binop by moving it ahead of a shuffle.
604
605define <4 x i8> @widening_shuffle_add_2(<2 x i8> %x) {
606; CHECK-LABEL: @widening_shuffle_add_2(
607; CHECK-NEXT:    [[TMP1:%.*]] = add <2 x i8> [[X:%.*]], <i8 43, i8 42>
608; CHECK-NEXT:    [[R:%.*]] = shufflevector <2 x i8> [[TMP1]], <2 x i8> poison, <4 x i32> <i32 1, i32 0, i32 poison, i32 poison>
609; CHECK-NEXT:    ret <4 x i8> [[R]]
610;
611  %widex = shufflevector <2 x i8> %x, <2 x i8> undef, <4 x i32> <i32 1, i32 0, i32 undef, i32 undef>
612  %r = add <4 x i8> %widex, <i8 42, i8 43, i8 44, i8 45>
613  ret <4 x i8> %r
614}
615
616; Negative test - widening shuffles have the same mask/constant constraint as non-size-changing shuffles.
617
618define <4 x i8> @widening_shuffle_add_invalid_constant(<2 x i8> %x) {
619; CHECK-LABEL: @widening_shuffle_add_invalid_constant(
620; CHECK-NEXT:    [[WIDEX:%.*]] = shufflevector <2 x i8> [[X:%.*]], <2 x i8> poison, <4 x i32> <i32 1, i32 1, i32 poison, i32 poison>
621; CHECK-NEXT:    [[R:%.*]] = add <4 x i8> [[WIDEX]], <i8 42, i8 43, i8 44, i8 45>
622; CHECK-NEXT:    ret <4 x i8> [[R]]
623;
624  %widex = shufflevector <2 x i8> %x, <2 x i8> undef, <4 x i32> <i32 1, i32 1, i32 undef, i32 undef>
625  %r = add <4 x i8> %widex, <i8 42, i8 43, i8 44, i8 45>
626  ret <4 x i8> %r
627}
628
629; Negative test - widening shuffles have an additional constraint: they must not extend with anything but undefs.
630
631define <4 x i8> @widening_shuffle_add_invalid_mask(<2 x i8> %x) {
632; CHECK-LABEL: @widening_shuffle_add_invalid_mask(
633; CHECK-NEXT:    [[WIDEX:%.*]] = shufflevector <2 x i8> [[X:%.*]], <2 x i8> poison, <4 x i32> <i32 0, i32 1, i32 poison, i32 0>
634; CHECK-NEXT:    [[R:%.*]] = add <4 x i8> [[WIDEX]], <i8 42, i8 43, i8 44, i8 45>
635; CHECK-NEXT:    ret <4 x i8> [[R]]
636;
637  %widex = shufflevector <2 x i8> %x, <2 x i8> undef, <4 x i32> <i32 0, i32 1, i32 undef, i32 0>
638  %r = add <4 x i8> %widex, <i8 42, i8 43, i8 44, i8 45>
639  ret <4 x i8> %r
640}
641
642; A binop that produces undef in the high lanes can be moved before the shuffle.
643; This is ok because 'shl C, undef --> undef'.
644
645define <4 x i16> @widening_shuffle_shl_constant_op0(<2 x i16> %v) {
646; CHECK-LABEL: @widening_shuffle_shl_constant_op0(
647; CHECK-NEXT:    [[TMP1:%.*]] = shl <2 x i16> <i16 42, i16 -42>, [[V:%.*]]
648; CHECK-NEXT:    [[BO:%.*]] = shufflevector <2 x i16> [[TMP1]], <2 x i16> poison, <4 x i32> <i32 0, i32 1, i32 poison, i32 poison>
649; CHECK-NEXT:    ret <4 x i16> [[BO]]
650;
651  %shuf = shufflevector <2 x i16> %v, <2 x i16> undef, <4 x i32> <i32 0, i32 1, i32 undef, i32 undef>
652  %bo = shl <4 x i16> <i16 42, i16 -42, i16 -1, i16 -1>, %shuf
653  ret <4 x i16> %bo
654}
655
656; A binop that produces undef in the high lanes can be moved before the shuffle.
657; This is ok because 'shl undef, 0 --> undef'.
658
659define <4 x i16> @widening_shuffle_shl_constant_op1(<2 x i16> %v) {
660; CHECK-LABEL: @widening_shuffle_shl_constant_op1(
661; CHECK-NEXT:    [[TMP1:%.*]] = shl <2 x i16> [[V:%.*]], <i16 2, i16 4>
662; CHECK-NEXT:    [[BO:%.*]] = shufflevector <2 x i16> [[TMP1]], <2 x i16> poison, <4 x i32> <i32 0, i32 1, i32 poison, i32 poison>
663; CHECK-NEXT:    ret <4 x i16> [[BO]]
664;
665  %shuf = shufflevector <2 x i16> %v, <2 x i16> undef, <4 x i32> <i32 0, i32 1, i32 undef, i32 undef>
666  %bo = shl <4 x i16> %shuf, <i16 2, i16 4, i16 0, i16 0>
667  ret <4 x i16> %bo
668}
669
670; This is valid for poison, but would not be valid for undef.
671
672define <4 x i16> @widening_shuffle_shl_constant_op1_non0(<2 x i16> %v) {
673; CHECK-LABEL: @widening_shuffle_shl_constant_op1_non0(
674; CHECK-NEXT:    [[TMP1:%.*]] = shl <2 x i16> [[V:%.*]], <i16 2, i16 4>
675; CHECK-NEXT:    [[BO:%.*]] = shufflevector <2 x i16> [[TMP1]], <2 x i16> poison, <4 x i32> <i32 0, i32 1, i32 poison, i32 poison>
676; CHECK-NEXT:    ret <4 x i16> [[BO]]
677;
678  %shuf = shufflevector <2 x i16> %v, <2 x i16> undef, <4 x i32> <i32 0, i32 1, i32 undef, i32 undef>
679  %bo = shl <4 x i16> %shuf, <i16 2, i16 4, i16 1, i16 2>
680  ret <4 x i16> %bo
681}
682
683; A binop that does not produce undef in the high lanes can not be moved before the shuffle.
684; This is not ok because 'or -1, undef --> -1' but moving the shuffle results in undef instead.
685
686define <4 x i16> @widening_shuffle_or(<2 x i16> %v) {
687; CHECK-LABEL: @widening_shuffle_or(
688; CHECK-NEXT:    [[TMP1:%.*]] = or <2 x i16> [[V:%.*]], <i16 42, i16 -42>
689; CHECK-NEXT:    [[BO:%.*]] = shufflevector <2 x i16> [[TMP1]], <2 x i16> poison, <4 x i32> <i32 0, i32 1, i32 poison, i32 poison>
690; CHECK-NEXT:    ret <4 x i16> [[BO]]
691;
692  %shuf = shufflevector <2 x i16> %v, <2 x i16> undef, <4 x i32> <i32 0, i32 1, i32 undef, i32 undef>
693  %bo = or <4 x i16> %shuf, <i16 42, i16 -42, i16 -1, i16 -1>
694  ret <4 x i16> %bo
695}
696
697define <4 x i32> @shuffle_17add2(<4 x i32> %v) {
698; CHECK-LABEL: @shuffle_17add2(
699; CHECK-NEXT:    [[TMP1:%.*]] = shl <4 x i32> [[V:%.*]], splat (i32 1)
700; CHECK-NEXT:    ret <4 x i32> [[TMP1]]
701;
702  %t1 = shufflevector <4 x i32> %v, <4 x i32> zeroinitializer, <4 x i32> <i32 3, i32 2, i32 1, i32 0>
703  %t2 = add <4 x i32> %t1, %t1
704  %r = shufflevector <4 x i32> %t2, <4 x i32> zeroinitializer, <4 x i32> <i32 3, i32 2, i32 1, i32 0>
705  ret <4 x i32> %r
706}
707
708define <4 x i32> @shuffle_17mulsplat(<4 x i32> %v) {
709; CHECK-LABEL: @shuffle_17mulsplat(
710; CHECK-NEXT:    [[TMP1:%.*]] = mul <4 x i32> [[V:%.*]], [[V]]
711; CHECK-NEXT:    [[M1:%.*]] = shufflevector <4 x i32> [[TMP1]], <4 x i32> poison, <4 x i32> zeroinitializer
712; CHECK-NEXT:    ret <4 x i32> [[M1]]
713;
714  %s1 = shufflevector <4 x i32> %v, <4 x i32> zeroinitializer, <4 x i32> zeroinitializer
715  %m1 = mul <4 x i32> %s1, %s1
716  %s2 = shufflevector <4 x i32> %m1, <4 x i32> zeroinitializer, <4 x i32> <i32 1, i32 1, i32 1, i32 1>
717  ret <4 x i32> %s2
718}
719
720; Do not reorder shuffle and binop if LHS of shuffles are of different size
721define <2 x i32> @pr19717(<4 x i32> %in0, <2 x i32> %in1) {
722; CHECK-LABEL: @pr19717(
723; CHECK-NEXT:    [[SHUFFLE:%.*]] = shufflevector <4 x i32> [[IN0:%.*]], <4 x i32> poison, <2 x i32> zeroinitializer
724; CHECK-NEXT:    [[SHUFFLE4:%.*]] = shufflevector <2 x i32> [[IN1:%.*]], <2 x i32> poison, <2 x i32> zeroinitializer
725; CHECK-NEXT:    [[MUL:%.*]] = mul <2 x i32> [[SHUFFLE]], [[SHUFFLE4]]
726; CHECK-NEXT:    ret <2 x i32> [[MUL]]
727;
728  %shuffle = shufflevector <4 x i32> %in0, <4 x i32> %in0, <2 x i32> zeroinitializer
729  %shuffle4 = shufflevector <2 x i32> %in1, <2 x i32> %in1, <2 x i32> zeroinitializer
730  %mul = mul <2 x i32> %shuffle, %shuffle4
731  ret <2 x i32> %mul
732}
733
734define <4 x i16> @pr19717a(<8 x i16> %in0, <8 x i16> %in1) {
735; CHECK-LABEL: @pr19717a(
736; CHECK-NEXT:    [[TMP1:%.*]] = mul <8 x i16> [[IN0:%.*]], [[IN1:%.*]]
737; CHECK-NEXT:    [[MUL:%.*]] = shufflevector <8 x i16> [[TMP1]], <8 x i16> poison, <4 x i32> <i32 5, i32 5, i32 5, i32 5>
738; CHECK-NEXT:    ret <4 x i16> [[MUL]]
739;
740  %shuffle = shufflevector <8 x i16> %in0, <8 x i16> %in0, <4 x i32> <i32 5, i32 5, i32 5, i32 5>
741  %shuffle1 = shufflevector <8 x i16> %in1, <8 x i16> %in1, <4 x i32> <i32 5, i32 5, i32 5, i32 5>
742  %mul = mul <4 x i16> %shuffle, %shuffle1
743  ret <4 x i16> %mul
744}
745
746define <8 x i8> @pr19730(<16 x i8> %in0) {
747; CHECK-LABEL: @pr19730(
748; CHECK-NEXT:    [[SHUFFLE:%.*]] = shufflevector <16 x i8> [[IN0:%.*]], <16 x i8> poison, <8 x i32> <i32 7, i32 6, i32 5, i32 4, i32 3, i32 2, i32 1, i32 0>
749; CHECK-NEXT:    [[SHUFFLE1:%.*]] = shufflevector <8 x i8> [[SHUFFLE]], <8 x i8> poison, <8 x i32> <i32 7, i32 6, i32 5, i32 4, i32 3, i32 2, i32 1, i32 0>
750; CHECK-NEXT:    ret <8 x i8> [[SHUFFLE1]]
751;
752  %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>
753  %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>
754  ret <8 x i8> %shuffle1
755}
756
757define i32 @pr19737(<4 x i32> %in0) {
758; CHECK-LABEL: @pr19737(
759; CHECK-NEXT:    [[TMP1:%.*]] = extractelement <4 x i32> [[IN0:%.*]], i64 0
760; CHECK-NEXT:    ret i32 [[TMP1]]
761;
762  %shuffle.i = shufflevector <4 x i32> zeroinitializer, <4 x i32> %in0, <4 x i32> <i32 0, i32 4, i32 2, i32 6>
763  %neg.i = xor <4 x i32> %shuffle.i, <i32 -1, i32 -1, i32 -1, i32 -1>
764  %and.i = and <4 x i32> %in0, %neg.i
765  %rv = extractelement <4 x i32> %and.i, i32 0
766  ret i32 %rv
767}
768
769; In PR20059 ( http://llvm.org/pr20059 ), shufflevector operations are reordered/removed
770; for an srem operation. This is not a valid optimization because it may cause a trap
771; on div-by-zero.
772
773define <4 x i32> @pr20059(<4 x i32> %p1, <4 x i32> %p2) {
774; CHECK-LABEL: @pr20059(
775; CHECK-NEXT:    [[SPLAT1:%.*]] = shufflevector <4 x i32> [[P1:%.*]], <4 x i32> poison, <4 x i32> zeroinitializer
776; CHECK-NEXT:    [[SPLAT2:%.*]] = shufflevector <4 x i32> [[P2:%.*]], <4 x i32> poison, <4 x i32> zeroinitializer
777; CHECK-NEXT:    [[RETVAL:%.*]] = srem <4 x i32> [[SPLAT1]], [[SPLAT2]]
778; CHECK-NEXT:    ret <4 x i32> [[RETVAL]]
779;
780  %splat1 = shufflevector <4 x i32> %p1, <4 x i32> undef, <4 x i32> zeroinitializer
781  %splat2 = shufflevector <4 x i32> %p2, <4 x i32> undef, <4 x i32> zeroinitializer
782  %retval = srem <4 x i32> %splat1, %splat2
783  ret <4 x i32> %retval
784}
785
786define <4 x i32> @pr20114(<4 x i32> %__mask) {
787; CHECK-LABEL: @pr20114(
788; CHECK-NEXT:    [[MASK01_I:%.*]] = shufflevector <4 x i32> [[__MASK:%.*]], <4 x i32> poison, <4 x i32> <i32 0, i32 0, i32 1, i32 1>
789; CHECK-NEXT:    [[MASKED_NEW_I_I_I:%.*]] = and <4 x i32> [[MASK01_I]], bitcast (<2 x i64> <i64 ptrtoint (ptr @pr20114 to i64), i64 ptrtoint (ptr @pr20114 to i64)> to <4 x i32>)
790; CHECK-NEXT:    ret <4 x i32> [[MASKED_NEW_I_I_I]]
791;
792  %mask01.i = shufflevector <4 x i32> %__mask, <4 x i32> undef, <4 x i32> <i32 0, i32 0, i32 1, i32 1>
793  %masked_new.i.i.i = and <4 x i32> bitcast (<2 x i64> <i64 ptrtoint (ptr @pr20114 to i64), i64 ptrtoint (ptr @pr20114 to i64)> to <4 x i32>), %mask01.i
794  ret <4 x i32> %masked_new.i.i.i
795}
796
797define <2 x ptr> @pr23113(<4 x ptr> %A) {
798; CHECK-LABEL: @pr23113(
799; CHECK-NEXT:    [[TMP1:%.*]] = shufflevector <4 x ptr> [[A:%.*]], <4 x ptr> poison, <2 x i32> <i32 0, i32 1>
800; CHECK-NEXT:    ret <2 x ptr> [[TMP1]]
801;
802  %1 = shufflevector <4 x ptr> %A, <4 x ptr> undef, <2 x i32> <i32 0, i32 1>
803  ret <2 x ptr> %1
804}
805
806; Unused lanes in the new binop should not kill the entire op (although it may simplify anyway as shown here).
807
808define <2 x i32> @PR37648(<2 x i32> %x) {
809; CHECK-LABEL: @PR37648(
810; CHECK-NEXT:    ret <2 x i32> zeroinitializer
811;
812  %splat = shufflevector <2 x i32> %x, <2 x i32> undef, <2 x i32> zeroinitializer
813  %r = urem <2 x i32> %splat, <i32 1, i32 1>
814  ret <2 x i32> %r
815}
816
817; Test shuffle followed by binop with splat constant for all 18 binop opcodes.
818; Test with constant as operand 0 and operand 1 for non-commutative opcodes.
819
820define <2 x i32> @add_splat_constant(<2 x i32> %x) {
821; CHECK-LABEL: @add_splat_constant(
822; CHECK-NEXT:    [[TMP1:%.*]] = add <2 x i32> [[X:%.*]], <i32 42, i32 poison>
823; CHECK-NEXT:    [[R:%.*]] = shufflevector <2 x i32> [[TMP1]], <2 x i32> poison, <2 x i32> zeroinitializer
824; CHECK-NEXT:    ret <2 x i32> [[R]]
825;
826  %splat = shufflevector <2 x i32> %x, <2 x i32> undef, <2 x i32> zeroinitializer
827  %r = add <2 x i32> %splat, <i32 42, i32 42>
828  ret <2 x i32> %r
829}
830
831define <2 x i32> @sub_splat_constant0(<2 x i32> %x) {
832; CHECK-LABEL: @sub_splat_constant0(
833; CHECK-NEXT:    [[TMP1:%.*]] = sub <2 x i32> <i32 42, i32 poison>, [[X:%.*]]
834; CHECK-NEXT:    [[R:%.*]] = shufflevector <2 x i32> [[TMP1]], <2 x i32> poison, <2 x i32> zeroinitializer
835; CHECK-NEXT:    ret <2 x i32> [[R]]
836;
837  %splat = shufflevector <2 x i32> %x, <2 x i32> undef, <2 x i32> zeroinitializer
838  %r = sub <2 x i32> <i32 42, i32 42>, %splat
839  ret <2 x i32> %r
840}
841
842define <2 x i32> @sub_splat_constant1(<2 x i32> %x) {
843; CHECK-LABEL: @sub_splat_constant1(
844; CHECK-NEXT:    [[TMP1:%.*]] = add <2 x i32> [[X:%.*]], <i32 -42, i32 poison>
845; CHECK-NEXT:    [[R:%.*]] = shufflevector <2 x i32> [[TMP1]], <2 x i32> poison, <2 x i32> zeroinitializer
846; CHECK-NEXT:    ret <2 x i32> [[R]]
847;
848  %splat = shufflevector <2 x i32> %x, <2 x i32> undef, <2 x i32> zeroinitializer
849  %r = sub <2 x i32> %splat, <i32 42, i32 42>
850  ret <2 x i32> %r
851}
852
853define <2 x i32> @mul_splat_constant(<2 x i32> %x) {
854; CHECK-LABEL: @mul_splat_constant(
855; CHECK-NEXT:    [[TMP1:%.*]] = mul <2 x i32> [[X:%.*]], <i32 42, i32 poison>
856; CHECK-NEXT:    [[R:%.*]] = shufflevector <2 x i32> [[TMP1]], <2 x i32> poison, <2 x i32> zeroinitializer
857; CHECK-NEXT:    ret <2 x i32> [[R]]
858;
859  %splat = shufflevector <2 x i32> %x, <2 x i32> undef, <2 x i32> zeroinitializer
860  %r = mul <2 x i32> %splat, <i32 42, i32 42>
861  ret <2 x i32> %r
862}
863
864define <2 x i32> @shl_splat_constant0(<2 x i32> %x) {
865; CHECK-LABEL: @shl_splat_constant0(
866; CHECK-NEXT:    [[TMP1:%.*]] = shl <2 x i32> <i32 5, i32 poison>, [[X:%.*]]
867; CHECK-NEXT:    [[R:%.*]] = shufflevector <2 x i32> [[TMP1]], <2 x i32> poison, <2 x i32> zeroinitializer
868; CHECK-NEXT:    ret <2 x i32> [[R]]
869;
870  %splat = shufflevector <2 x i32> %x, <2 x i32> undef, <2 x i32> zeroinitializer
871  %r = shl <2 x i32> <i32 5, i32 5>, %splat
872  ret <2 x i32> %r
873}
874
875define <2 x i32> @shl_splat_constant1(<2 x i32> %x) {
876; CHECK-LABEL: @shl_splat_constant1(
877; CHECK-NEXT:    [[TMP1:%.*]] = shl <2 x i32> [[X:%.*]], <i32 5, i32 0>
878; CHECK-NEXT:    [[R:%.*]] = shufflevector <2 x i32> [[TMP1]], <2 x i32> poison, <2 x i32> zeroinitializer
879; CHECK-NEXT:    ret <2 x i32> [[R]]
880;
881  %splat = shufflevector <2 x i32> %x, <2 x i32> undef, <2 x i32> zeroinitializer
882  %r = shl <2 x i32> %splat, <i32 5, i32 5>
883  ret <2 x i32> %r
884}
885
886define <2 x i32> @ashr_splat_constant0(<2 x i32> %x) {
887; CHECK-LABEL: @ashr_splat_constant0(
888; CHECK-NEXT:    [[TMP1:%.*]] = lshr <2 x i32> <i32 5, i32 poison>, [[X:%.*]]
889; CHECK-NEXT:    [[R:%.*]] = shufflevector <2 x i32> [[TMP1]], <2 x i32> poison, <2 x i32> zeroinitializer
890; CHECK-NEXT:    ret <2 x i32> [[R]]
891;
892  %splat = shufflevector <2 x i32> %x, <2 x i32> undef, <2 x i32> zeroinitializer
893  %r = ashr <2 x i32> <i32 5, i32 5>, %splat
894  ret <2 x i32> %r
895}
896
897define <2 x i32> @ashr_splat_constant1(<2 x i32> %x) {
898; CHECK-LABEL: @ashr_splat_constant1(
899; CHECK-NEXT:    [[TMP1:%.*]] = ashr <2 x i32> [[X:%.*]], <i32 5, i32 0>
900; CHECK-NEXT:    [[R:%.*]] = shufflevector <2 x i32> [[TMP1]], <2 x i32> poison, <2 x i32> zeroinitializer
901; CHECK-NEXT:    ret <2 x i32> [[R]]
902;
903  %splat = shufflevector <2 x i32> %x, <2 x i32> undef, <2 x i32> zeroinitializer
904  %r = ashr <2 x i32> %splat, <i32 5, i32 5>
905  ret <2 x i32> %r
906}
907
908define <2 x i32> @lshr_splat_constant0(<2 x i32> %x) {
909; CHECK-LABEL: @lshr_splat_constant0(
910; CHECK-NEXT:    [[TMP1:%.*]] = lshr <2 x i32> <i32 5, i32 poison>, [[X:%.*]]
911; CHECK-NEXT:    [[R:%.*]] = shufflevector <2 x i32> [[TMP1]], <2 x i32> poison, <2 x i32> zeroinitializer
912; CHECK-NEXT:    ret <2 x i32> [[R]]
913;
914  %splat = shufflevector <2 x i32> %x, <2 x i32> undef, <2 x i32> zeroinitializer
915  %r = lshr <2 x i32> <i32 5, i32 5>, %splat
916  ret <2 x i32> %r
917}
918
919define <2 x i32> @lshr_splat_constant1(<2 x i32> %x) {
920; CHECK-LABEL: @lshr_splat_constant1(
921; CHECK-NEXT:    [[TMP1:%.*]] = lshr <2 x i32> [[X:%.*]], <i32 5, i32 0>
922; CHECK-NEXT:    [[R:%.*]] = shufflevector <2 x i32> [[TMP1]], <2 x i32> poison, <2 x i32> zeroinitializer
923; CHECK-NEXT:    ret <2 x i32> [[R]]
924;
925  %splat = shufflevector <2 x i32> %x, <2 x i32> undef, <2 x i32> zeroinitializer
926  %r = lshr <2 x i32> %splat, <i32 5, i32 5>
927  ret <2 x i32> %r
928}
929
930define <2 x i32> @urem_splat_constant0(<2 x i32> %x) {
931; CHECK-LABEL: @urem_splat_constant0(
932; CHECK-NEXT:    [[SPLAT:%.*]] = shufflevector <2 x i32> [[X:%.*]], <2 x i32> poison, <2 x i32> zeroinitializer
933; CHECK-NEXT:    [[R:%.*]] = urem <2 x i32> splat (i32 42), [[SPLAT]]
934; CHECK-NEXT:    ret <2 x i32> [[R]]
935;
936  %splat = shufflevector <2 x i32> %x, <2 x i32> undef, <2 x i32> zeroinitializer
937  %r = urem <2 x i32> <i32 42, i32 42>, %splat
938  ret <2 x i32> %r
939}
940
941define <2 x i32> @urem_splat_constant1(<2 x i32> %x) {
942; CHECK-LABEL: @urem_splat_constant1(
943; CHECK-NEXT:    [[TMP1:%.*]] = urem <2 x i32> [[X:%.*]], <i32 42, i32 1>
944; CHECK-NEXT:    [[R:%.*]] = shufflevector <2 x i32> [[TMP1]], <2 x i32> poison, <2 x i32> zeroinitializer
945; CHECK-NEXT:    ret <2 x i32> [[R]]
946;
947  %splat = shufflevector <2 x i32> %x, <2 x i32> undef, <2 x i32> zeroinitializer
948  %r = urem <2 x i32> %splat, <i32 42, i32 42>
949  ret <2 x i32> %r
950}
951
952define <2 x i32> @srem_splat_constant0(<2 x i32> %x) {
953; CHECK-LABEL: @srem_splat_constant0(
954; CHECK-NEXT:    [[SPLAT:%.*]] = shufflevector <2 x i32> [[X:%.*]], <2 x i32> poison, <2 x i32> zeroinitializer
955; CHECK-NEXT:    [[R:%.*]] = srem <2 x i32> splat (i32 42), [[SPLAT]]
956; CHECK-NEXT:    ret <2 x i32> [[R]]
957;
958  %splat = shufflevector <2 x i32> %x, <2 x i32> undef, <2 x i32> zeroinitializer
959  %r = srem <2 x i32> <i32 42, i32 42>, %splat
960  ret <2 x i32> %r
961}
962
963define <2 x i32> @srem_splat_constant1(<2 x i32> %x) {
964; CHECK-LABEL: @srem_splat_constant1(
965; CHECK-NEXT:    [[TMP1:%.*]] = srem <2 x i32> [[X:%.*]], <i32 42, i32 1>
966; CHECK-NEXT:    [[R:%.*]] = shufflevector <2 x i32> [[TMP1]], <2 x i32> poison, <2 x i32> zeroinitializer
967; CHECK-NEXT:    ret <2 x i32> [[R]]
968;
969  %splat = shufflevector <2 x i32> %x, <2 x i32> undef, <2 x i32> zeroinitializer
970  %r = srem <2 x i32> %splat, <i32 42, i32 42>
971  ret <2 x i32> %r
972}
973
974define <2 x i32> @udiv_splat_constant0(<2 x i32> %x) {
975; CHECK-LABEL: @udiv_splat_constant0(
976; CHECK-NEXT:    [[SPLAT:%.*]] = shufflevector <2 x i32> [[X:%.*]], <2 x i32> poison, <2 x i32> zeroinitializer
977; CHECK-NEXT:    [[R:%.*]] = udiv <2 x i32> splat (i32 42), [[SPLAT]]
978; CHECK-NEXT:    ret <2 x i32> [[R]]
979;
980  %splat = shufflevector <2 x i32> %x, <2 x i32> undef, <2 x i32> zeroinitializer
981  %r = udiv <2 x i32> <i32 42, i32 42>, %splat
982  ret <2 x i32> %r
983}
984
985define <2 x i32> @udiv_splat_constant1(<2 x i32> %x) {
986; CHECK-LABEL: @udiv_splat_constant1(
987; CHECK-NEXT:    [[TMP1:%.*]] = udiv <2 x i32> [[X:%.*]], <i32 42, i32 1>
988; CHECK-NEXT:    [[R:%.*]] = shufflevector <2 x i32> [[TMP1]], <2 x i32> poison, <2 x i32> zeroinitializer
989; CHECK-NEXT:    ret <2 x i32> [[R]]
990;
991  %splat = shufflevector <2 x i32> %x, <2 x i32> undef, <2 x i32> zeroinitializer
992  %r = udiv <2 x i32> %splat, <i32 42, i32 42>
993  ret <2 x i32> %r
994}
995
996define <2 x i32> @sdiv_splat_constant0(<2 x i32> %x) {
997; CHECK-LABEL: @sdiv_splat_constant0(
998; CHECK-NEXT:    [[SPLAT:%.*]] = shufflevector <2 x i32> [[X:%.*]], <2 x i32> poison, <2 x i32> zeroinitializer
999; CHECK-NEXT:    [[R:%.*]] = sdiv <2 x i32> splat (i32 42), [[SPLAT]]
1000; CHECK-NEXT:    ret <2 x i32> [[R]]
1001;
1002  %splat = shufflevector <2 x i32> %x, <2 x i32> undef, <2 x i32> zeroinitializer
1003  %r = sdiv <2 x i32> <i32 42, i32 42>, %splat
1004  ret <2 x i32> %r
1005}
1006
1007define <2 x i32> @sdiv_splat_constant1(<2 x i32> %x) {
1008; CHECK-LABEL: @sdiv_splat_constant1(
1009; CHECK-NEXT:    [[TMP1:%.*]] = sdiv <2 x i32> [[X:%.*]], <i32 42, i32 1>
1010; CHECK-NEXT:    [[R:%.*]] = shufflevector <2 x i32> [[TMP1]], <2 x i32> poison, <2 x i32> zeroinitializer
1011; CHECK-NEXT:    ret <2 x i32> [[R]]
1012;
1013  %splat = shufflevector <2 x i32> %x, <2 x i32> undef, <2 x i32> zeroinitializer
1014  %r = sdiv <2 x i32> %splat, <i32 42, i32 42>
1015  ret <2 x i32> %r
1016}
1017
1018define <2 x i32> @and_splat_constant(<2 x i32> %x) {
1019; CHECK-LABEL: @and_splat_constant(
1020; CHECK-NEXT:    [[TMP1:%.*]] = and <2 x i32> [[X:%.*]], <i32 42, i32 poison>
1021; CHECK-NEXT:    [[R:%.*]] = shufflevector <2 x i32> [[TMP1]], <2 x i32> poison, <2 x i32> zeroinitializer
1022; CHECK-NEXT:    ret <2 x i32> [[R]]
1023;
1024  %splat = shufflevector <2 x i32> %x, <2 x i32> undef, <2 x i32> zeroinitializer
1025  %r = and <2 x i32> %splat, <i32 42, i32 42>
1026  ret <2 x i32> %r
1027}
1028
1029define <4 x i16> @and_constant_mask_poison(<4 x i16> %add) {
1030; CHECK-LABEL: @and_constant_mask_poison(
1031; CHECK-NEXT:  entry:
1032; CHECK-NEXT:    [[AND:%.*]] = shufflevector <4 x i16> [[ADD:%.*]], <4 x i16> poison, <4 x i32> <i32 poison, i32 poison, i32 1, i32 1>
1033; CHECK-NEXT:    ret <4 x i16> [[AND]]
1034;
1035entry:
1036  %shuffle = shufflevector <4 x i16> %add, <4 x i16> undef, <4 x i32> <i32 undef, i32 undef, i32 1, i32 1>
1037  %and = and <4 x i16> %shuffle, <i16 0, i16 0, i16 -1, i16 -1>
1038  ret <4 x i16> %and
1039}
1040
1041define <4 x i16> @and_constant_mask_poison_2(<4 x i16> %add) {
1042; CHECK-LABEL: @and_constant_mask_poison_2(
1043; CHECK-NEXT:  entry:
1044; CHECK-NEXT:    [[AND:%.*]] = shufflevector <4 x i16> [[ADD:%.*]], <4 x i16> poison, <4 x i32> <i32 1, i32 1, i32 1, i32 poison>
1045; CHECK-NEXT:    ret <4 x i16> [[AND]]
1046;
1047entry:
1048  %shuffle = shufflevector <4 x i16> %add, <4 x i16> undef, <4 x i32> <i32 1, i32 1, i32 1, i32 undef>
1049  %and = and <4 x i16> %shuffle, <i16 -1, i16 -1, i16 -1, i16 -0>
1050  ret <4 x i16> %and
1051}
1052
1053; We can move the AND across the shuffle, as -1 (AND identity value) is used for undef lanes.
1054define <4 x i16> @and_constant_mask_poison_3(<4 x i16> %add) {
1055; CHECK-LABEL: @and_constant_mask_poison_3(
1056; CHECK-NEXT:  entry:
1057; CHECK-NEXT:    ret <4 x i16> <i16 0, i16 0, i16 0, i16 undef>
1058;
1059entry:
1060  %shuffle = shufflevector <4 x i16> %add, <4 x i16> undef, <4 x i32> <i32 0, i32 1, i32 1, i32 undef>
1061  %and = and <4 x i16> %shuffle, <i16 0, i16 0, i16 0, i16 -1>
1062  ret <4 x i16> %and
1063}
1064
1065; We can move the AND across the shuffle, as -1 (AND identity value) is used for undef lanes.
1066define <4 x i16> @and_constant_mask_poison_4(<4 x i16> %add) {
1067; CHECK-LABEL: @and_constant_mask_poison_4(
1068; CHECK-NEXT:  entry:
1069; CHECK-NEXT:    [[TMP0:%.*]] = and <4 x i16> [[ADD:%.*]], <i16 9, i16 20, i16 poison, i16 poison>
1070; CHECK-NEXT:    [[AND:%.*]] = shufflevector <4 x i16> [[TMP0]], <4 x i16> poison, <4 x i32> <i32 0, i32 1, i32 1, i32 poison>
1071; CHECK-NEXT:    ret <4 x i16> [[AND]]
1072;
1073entry:
1074  %shuffle = shufflevector <4 x i16> %add, <4 x i16> undef, <4 x i32> <i32 0, i32 1, i32 1, i32 undef>
1075  %and = and <4 x i16> %shuffle, <i16 9, i16 20, i16 20, i16 -1>
1076  ret <4 x i16> %and
1077}
1078
1079define <4 x i16> @and_constant_mask_not_undef(<4 x i16> %add) {
1080; CHECK-LABEL: @and_constant_mask_not_undef(
1081; CHECK-NEXT:  entry:
1082; CHECK-NEXT:    [[TMP0:%.*]] = and <4 x i16> [[ADD:%.*]], <i16 poison, i16 -1, i16 0, i16 0>
1083; CHECK-NEXT:    [[AND:%.*]] = shufflevector <4 x i16> [[TMP0]], <4 x i16> poison, <4 x i32> <i32 2, i32 3, i32 1, i32 1>
1084; CHECK-NEXT:    ret <4 x i16> [[AND]]
1085;
1086entry:
1087  %shuffle = shufflevector <4 x i16> %add, <4 x i16> undef, <4 x i32> <i32 2, i32 3, i32 1, i32 1>
1088  %and = and <4 x i16> %shuffle, <i16 0, i16 0, i16 -1, i16 -1>
1089  ret <4 x i16> %and
1090}
1091
1092define <4 x i16> @or_constant_mask_poison(<4 x i16> %in) {
1093; CHECK-LABEL: @or_constant_mask_poison(
1094; CHECK-NEXT:  entry:
1095; CHECK-NEXT:    [[OR:%.*]] = shufflevector <4 x i16> [[IN:%.*]], <4 x i16> poison, <4 x i32> <i32 poison, i32 poison, i32 1, i32 1>
1096; CHECK-NEXT:    ret <4 x i16> [[OR]]
1097;
1098entry:
1099  %shuffle = shufflevector <4 x i16> %in, <4 x i16> undef, <4 x i32> <i32 undef, i32 undef, i32 1, i32 1>
1100  %or = or <4 x i16> %shuffle, <i16 -1, i16 -1, i16 0, i16 0>
1101  ret <4 x i16> %or
1102}
1103
1104define <4 x i16> @or_constant_mask_poison_2(<4 x i16> %in) {
1105; CHECK-LABEL: @or_constant_mask_poison_2(
1106; CHECK-NEXT:  entry:
1107; CHECK-NEXT:    [[OR:%.*]] = shufflevector <4 x i16> [[IN:%.*]], <4 x i16> poison, <4 x i32> <i32 poison, i32 1, i32 1, i32 poison>
1108; CHECK-NEXT:    ret <4 x i16> [[OR]]
1109;
1110entry:
1111  %shuffle = shufflevector <4 x i16> %in, <4 x i16> undef, <4 x i32> <i32 undef, i32 1, i32 1, i32 undef>
1112  %or = or <4 x i16> %shuffle, <i16 -1, i16 0, i16 0, i16 -1>
1113  ret <4 x i16> %or
1114}
1115
1116; We can move the OR across the shuffle, as 0 (OR identity value) is used for undef lanes.
1117define <4 x i16> @or_constant_mask_poison_3(<4 x i16> %in) {
1118; CHECK-LABEL: @or_constant_mask_poison_3(
1119; CHECK-NEXT:  entry:
1120; CHECK-NEXT:    ret <4 x i16> <i16 undef, i16 -1, i16 -1, i16 undef>
1121;
1122entry:
1123  %shuffle = shufflevector <4 x i16> %in, <4 x i16> undef, <4 x i32> <i32 undef, i32 1, i32 1, i32 undef>
1124  %or = or <4 x i16> %shuffle, <i16 0, i16 -1, i16 -1, i16 0>
1125  ret <4 x i16> %or
1126}
1127
1128; We can move the OR across the shuffle, as 0 (OR identity value) is used for undef lanes.
1129define <4 x i16> @or_constant_mask_poison_4(<4 x i16> %in) {
1130; CHECK-LABEL: @or_constant_mask_poison_4(
1131; CHECK-NEXT:  entry:
1132; CHECK-NEXT:    [[TMP0:%.*]] = or <4 x i16> [[IN:%.*]], <i16 poison, i16 99, i16 poison, i16 poison>
1133; CHECK-NEXT:    [[OR:%.*]] = shufflevector <4 x i16> [[TMP0]], <4 x i16> poison, <4 x i32> <i32 poison, i32 1, i32 1, i32 poison>
1134; CHECK-NEXT:    ret <4 x i16> [[OR]]
1135;
1136entry:
1137  %shuffle = shufflevector <4 x i16> %in, <4 x i16> undef, <4 x i32> <i32 undef, i32 1, i32 1, i32 undef>
1138  %or = or <4 x i16> %shuffle, <i16 0, i16 99, i16 99, i16 0>
1139  ret <4 x i16> %or
1140}
1141
1142define <4 x i16> @or_constant_mask_not_undef(<4 x i16> %in) {
1143; CHECK-LABEL: @or_constant_mask_not_undef(
1144; CHECK-NEXT:  entry:
1145; CHECK-NEXT:    [[TMP0:%.*]] = or <4 x i16> [[IN:%.*]], <i16 poison, i16 -1, i16 0, i16 0>
1146; CHECK-NEXT:    [[AND:%.*]] = shufflevector <4 x i16> [[TMP0]], <4 x i16> poison, <4 x i32> <i32 2, i32 3, i32 1, i32 1>
1147; CHECK-NEXT:    ret <4 x i16> [[AND]]
1148;
1149entry:
1150  %shuffle = shufflevector <4 x i16> %in, <4 x i16> undef, <4 x i32> <i32 2, i32 3, i32 1, i32 1>
1151  %and = or <4 x i16> %shuffle, <i16 0, i16 0, i16 -1, i16 -1>
1152  ret <4 x i16> %and
1153}
1154
1155define <4 x i16> @shl_constant_mask_undef(<4 x i16> %in) {
1156; CHECK-LABEL: @shl_constant_mask_undef(
1157; CHECK-NEXT:  entry:
1158; CHECK-NEXT:    [[TMP0:%.*]] = shl <4 x i16> [[IN:%.*]], <i16 10, i16 0, i16 0, i16 0>
1159; CHECK-NEXT:    [[SHL:%.*]] = shufflevector <4 x i16> [[TMP0]], <4 x i16> poison, <4 x i32> <i32 0, i32 poison, i32 1, i32 1>
1160; CHECK-NEXT:    ret <4 x i16> [[SHL]]
1161;
1162entry:
1163  %shuffle = shufflevector <4 x i16> %in, <4 x i16> undef, <4 x i32> <i32 0, i32 undef, i32 1, i32 1>
1164  %shl = shl <4 x i16> %shuffle, <i16 10, i16 3, i16 0, i16 0>
1165  ret <4 x i16> %shl
1166}
1167
1168define <4 x i16> @add_constant_mask_undef(<4 x i16> %in) {
1169; CHECK-LABEL: @add_constant_mask_undef(
1170; CHECK-NEXT:  entry:
1171; CHECK-NEXT:    [[ADD:%.*]] = shufflevector <4 x i16> [[IN:%.*]], <4 x i16> poison, <4 x i32> <i32 poison, i32 poison, i32 1, i32 1>
1172; CHECK-NEXT:    ret <4 x i16> [[ADD]]
1173;
1174entry:
1175  %shuffle = shufflevector <4 x i16> %in, <4 x i16> undef, <4 x i32> <i32 undef, i32 undef, i32 1, i32 1>
1176  %add = add <4 x i16> %shuffle, <i16 10, i16 3, i16 0, i16 0>
1177  ret <4 x i16> %add
1178}
1179
1180define <4 x i16> @add_constant_mask_undef_2(<4 x i16> %in) {
1181; CHECK-LABEL: @add_constant_mask_undef_2(
1182; CHECK-NEXT:  entry:
1183; CHECK-NEXT:    [[TMP0:%.*]] = add <4 x i16> [[IN:%.*]], <i16 poison, i16 0, i16 3, i16 poison>
1184; CHECK-NEXT:    [[ADD:%.*]] = shufflevector <4 x i16> [[TMP0]], <4 x i16> poison, <4 x i32> <i32 poison, i32 2, i32 1, i32 1>
1185; CHECK-NEXT:    ret <4 x i16> [[ADD]]
1186;
1187entry:
1188  %shuffle = shufflevector <4 x i16> %in, <4 x i16> undef, <4 x i32> <i32 undef, i32 2, i32 1, i32 1>
1189  %add = add <4 x i16> %shuffle, <i16 10, i16 3, i16 0, i16 0>
1190  ret <4 x i16> %add
1191}
1192
1193define <4 x i16> @sub_constant_mask_undef(<4 x i16> %in) {
1194; CHECK-LABEL: @sub_constant_mask_undef(
1195; CHECK-NEXT:  entry:
1196; CHECK-NEXT:    [[SUB:%.*]] = shufflevector <4 x i16> [[IN:%.*]], <4 x i16> poison, <4 x i32> <i32 poison, i32 poison, i32 1, i32 1>
1197; CHECK-NEXT:    ret <4 x i16> [[SUB]]
1198;
1199entry:
1200  %shuffle = shufflevector <4 x i16> %in, <4 x i16> undef, <4 x i32> <i32 undef, i32 undef, i32 1, i32 1>
1201  %sub = sub <4 x i16> %shuffle, <i16 10, i16 3, i16 0, i16 0>
1202  ret <4 x i16> %sub
1203}
1204
1205define <4 x i16> @sub_constant_mask_undef_2(<4 x i16> %in) {
1206; CHECK-LABEL: @sub_constant_mask_undef_2(
1207; CHECK-NEXT:  entry:
1208; CHECK-NEXT:    [[TMP0:%.*]] = add <4 x i16> [[IN:%.*]], <i16 poison, i16 0, i16 -10, i16 poison>
1209; CHECK-NEXT:    [[SUB:%.*]] = shufflevector <4 x i16> [[TMP0]], <4 x i16> poison, <4 x i32> <i32 1, i32 1, i32 2, i32 poison>
1210; CHECK-NEXT:    ret <4 x i16> [[SUB]]
1211;
1212entry:
1213  %shuffle = shufflevector <4 x i16> %in, <4 x i16> undef, <4 x i32> <i32 1, i32 1, i32 2, i32 undef>
1214  %sub = sub <4 x i16> %shuffle, <i16 0, i16 0, i16 10, i16 99>
1215  ret <4 x i16> %sub
1216}
1217
1218define <2 x i32> @or_splat_constant(<2 x i32> %x) {
1219; CHECK-LABEL: @or_splat_constant(
1220; CHECK-NEXT:    [[TMP1:%.*]] = or <2 x i32> [[X:%.*]], <i32 42, i32 poison>
1221; CHECK-NEXT:    [[R:%.*]] = shufflevector <2 x i32> [[TMP1]], <2 x i32> poison, <2 x i32> zeroinitializer
1222; CHECK-NEXT:    ret <2 x i32> [[R]]
1223;
1224  %splat = shufflevector <2 x i32> %x, <2 x i32> undef, <2 x i32> zeroinitializer
1225  %r = or <2 x i32> %splat, <i32 42, i32 42>
1226  ret <2 x i32> %r
1227}
1228
1229define <2 x i32> @xor_splat_constant(<2 x i32> %x) {
1230; CHECK-LABEL: @xor_splat_constant(
1231; CHECK-NEXT:    [[TMP1:%.*]] = xor <2 x i32> [[X:%.*]], <i32 42, i32 poison>
1232; CHECK-NEXT:    [[R:%.*]] = shufflevector <2 x i32> [[TMP1]], <2 x i32> poison, <2 x i32> zeroinitializer
1233; CHECK-NEXT:    ret <2 x i32> [[R]]
1234;
1235  %splat = shufflevector <2 x i32> %x, <2 x i32> undef, <2 x i32> zeroinitializer
1236  %r = xor <2 x i32> %splat, <i32 42, i32 42>
1237  ret <2 x i32> %r
1238}
1239
1240define <2 x float> @fadd_splat_constant(<2 x float> %x) {
1241; CHECK-LABEL: @fadd_splat_constant(
1242; CHECK-NEXT:    [[TMP1:%.*]] = fadd <2 x float> [[X:%.*]], <float 4.200000e+01, float poison>
1243; CHECK-NEXT:    [[R:%.*]] = shufflevector <2 x float> [[TMP1]], <2 x float> poison, <2 x i32> zeroinitializer
1244; CHECK-NEXT:    ret <2 x float> [[R]]
1245;
1246  %splat = shufflevector <2 x float> %x, <2 x float> undef, <2 x i32> zeroinitializer
1247  %r = fadd <2 x float> %splat, <float 42.0, float 42.0>
1248  ret <2 x float> %r
1249}
1250
1251define <2 x float> @fsub_splat_constant0(<2 x float> %x) {
1252; CHECK-LABEL: @fsub_splat_constant0(
1253; CHECK-NEXT:    [[TMP1:%.*]] = fsub <2 x float> <float 4.200000e+01, float poison>, [[X:%.*]]
1254; CHECK-NEXT:    [[R:%.*]] = shufflevector <2 x float> [[TMP1]], <2 x float> poison, <2 x i32> zeroinitializer
1255; CHECK-NEXT:    ret <2 x float> [[R]]
1256;
1257  %splat = shufflevector <2 x float> %x, <2 x float> undef, <2 x i32> zeroinitializer
1258  %r = fsub <2 x float> <float 42.0, float 42.0>, %splat
1259  ret <2 x float> %r
1260}
1261
1262define <2 x float> @fsub_splat_constant1(<2 x float> %x) {
1263; CHECK-LABEL: @fsub_splat_constant1(
1264; CHECK-NEXT:    [[TMP1:%.*]] = fadd <2 x float> [[X:%.*]], <float -4.200000e+01, float poison>
1265; CHECK-NEXT:    [[R:%.*]] = shufflevector <2 x float> [[TMP1]], <2 x float> poison, <2 x i32> zeroinitializer
1266; CHECK-NEXT:    ret <2 x float> [[R]]
1267;
1268  %splat = shufflevector <2 x float> %x, <2 x float> undef, <2 x i32> zeroinitializer
1269  %r = fsub <2 x float> %splat, <float 42.0, float 42.0>
1270  ret <2 x float> %r
1271}
1272
1273define <2 x float> @fneg(<2 x float> %x) {
1274; CHECK-LABEL: @fneg(
1275; CHECK-NEXT:    [[TMP1:%.*]] = shufflevector <2 x float> [[X:%.*]], <2 x float> poison, <2 x i32> zeroinitializer
1276; CHECK-NEXT:    [[R:%.*]] = fneg <2 x float> [[TMP1]]
1277; CHECK-NEXT:    ret <2 x float> [[R]]
1278;
1279  %splat = shufflevector <2 x float> %x, <2 x float> undef, <2 x i32> zeroinitializer
1280  %r = fsub <2 x float> <float -0.0, float -0.0>, %splat
1281  ret <2 x float> %r
1282}
1283
1284define <2 x float> @fneg_not_single_source(<2 x float> %x) {
1285; CHECK-LABEL: @fneg_not_single_source(
1286; CHECK-NEXT:    [[NEG:%.*]] = fneg <2 x float> [[X:%.*]]
1287; CHECK-NEXT:    [[SPLAT1:%.*]] = insertelement <2 x float> [[NEG]], float undef, i64 1
1288; CHECK-NEXT:    ret <2 x float> [[SPLAT1]]
1289;
1290  %neg = fneg <2 x float> %x
1291  %splat = shufflevector <2 x float> %neg, <2 x float> undef, <2 x i32> <i32 0, i32 2>
1292  ret <2 x float> %splat
1293}
1294
1295define <2 x float> @fmul_splat_constant(<2 x float> %x) {
1296; CHECK-LABEL: @fmul_splat_constant(
1297; CHECK-NEXT:    [[TMP1:%.*]] = fmul <2 x float> [[X:%.*]], <float 4.200000e+01, float poison>
1298; CHECK-NEXT:    [[R:%.*]] = shufflevector <2 x float> [[TMP1]], <2 x float> poison, <2 x i32> zeroinitializer
1299; CHECK-NEXT:    ret <2 x float> [[R]]
1300;
1301  %splat = shufflevector <2 x float> %x, <2 x float> undef, <2 x i32> zeroinitializer
1302  %r = fmul <2 x float> %splat, <float 42.0, float 42.0>
1303  ret <2 x float> %r
1304}
1305
1306define <2 x float> @fdiv_splat_constant0(<2 x float> %x) {
1307; CHECK-LABEL: @fdiv_splat_constant0(
1308; CHECK-NEXT:    [[TMP1:%.*]] = fdiv <2 x float> <float 4.200000e+01, float poison>, [[X:%.*]]
1309; CHECK-NEXT:    [[R:%.*]] = shufflevector <2 x float> [[TMP1]], <2 x float> poison, <2 x i32> zeroinitializer
1310; CHECK-NEXT:    ret <2 x float> [[R]]
1311;
1312  %splat = shufflevector <2 x float> %x, <2 x float> undef, <2 x i32> zeroinitializer
1313  %r = fdiv <2 x float> <float 42.0, float 42.0>, %splat
1314  ret <2 x float> %r
1315}
1316
1317define <2 x float> @fdiv_splat_constant1(<2 x float> %x) {
1318; CHECK-LABEL: @fdiv_splat_constant1(
1319; CHECK-NEXT:    [[TMP1:%.*]] = fdiv <2 x float> [[X:%.*]], <float 4.200000e+01, float poison>
1320; CHECK-NEXT:    [[R:%.*]] = shufflevector <2 x float> [[TMP1]], <2 x float> poison, <2 x i32> zeroinitializer
1321; CHECK-NEXT:    ret <2 x float> [[R]]
1322;
1323  %splat = shufflevector <2 x float> %x, <2 x float> undef, <2 x i32> zeroinitializer
1324  %r = fdiv <2 x float> %splat, <float 42.0, float 42.0>
1325  ret <2 x float> %r
1326}
1327
1328define <2 x float> @frem_splat_constant0(<2 x float> %x) {
1329; CHECK-LABEL: @frem_splat_constant0(
1330; CHECK-NEXT:    [[TMP1:%.*]] = frem <2 x float> <float 4.200000e+01, float poison>, [[X:%.*]]
1331; CHECK-NEXT:    [[R:%.*]] = shufflevector <2 x float> [[TMP1]], <2 x float> poison, <2 x i32> zeroinitializer
1332; CHECK-NEXT:    ret <2 x float> [[R]]
1333;
1334  %splat = shufflevector <2 x float> %x, <2 x float> undef, <2 x i32> zeroinitializer
1335  %r = frem <2 x float> <float 42.0, float 42.0>, %splat
1336  ret <2 x float> %r
1337}
1338
1339define <2 x float> @frem_splat_constant1(<2 x float> %x) {
1340; CHECK-LABEL: @frem_splat_constant1(
1341; CHECK-NEXT:    [[TMP1:%.*]] = frem <2 x float> [[X:%.*]], <float 4.200000e+01, float poison>
1342; CHECK-NEXT:    [[R:%.*]] = shufflevector <2 x float> [[TMP1]], <2 x float> poison, <2 x i32> zeroinitializer
1343; CHECK-NEXT:    ret <2 x float> [[R]]
1344;
1345  %splat = shufflevector <2 x float> %x, <2 x float> undef, <2 x i32> zeroinitializer
1346  %r = frem <2 x float> %splat, <float 42.0, float 42.0>
1347  ret <2 x float> %r
1348}
1349
1350; Equivalent shuffle masks, but only one is a narrowing op.
1351
1352define <2 x i1> @PR40734(<1 x i1> %x, <4 x i1> %y) {
1353; CHECK-LABEL: @PR40734(
1354; CHECK-NEXT:    [[WIDEN:%.*]] = shufflevector <1 x i1> zeroinitializer, <1 x i1> [[X:%.*]], <2 x i32> <i32 0, i32 1>
1355; CHECK-NEXT:    [[NARROW:%.*]] = shufflevector <4 x i1> [[Y:%.*]], <4 x i1> poison, <2 x i32> <i32 0, i32 1>
1356; CHECK-NEXT:    [[R:%.*]] = and <2 x i1> [[WIDEN]], [[NARROW]]
1357; CHECK-NEXT:    ret <2 x i1> [[R]]
1358;
1359  %widen = shufflevector <1 x i1> zeroinitializer, <1 x i1> %x, <2 x i32> <i32 0, i32 1>
1360  %narrow = shufflevector <4 x i1> %y, <4 x i1> undef, <2 x i32> <i32 0, i32 1>
1361  %r = and <2 x i1> %widen, %narrow
1362  ret <2 x i1> %r
1363}
1364
1365; Negative test - do not transform non-power-of-2 unless we know the backend handles these sequences identically.
1366
1367define <7 x i8> @insert_subvector_shuffles(<3 x i8> %x, <3 x i8> %y) {
1368; CHECK-LABEL: @insert_subvector_shuffles(
1369; CHECK-NEXT:    [[S1:%.*]] = shufflevector <3 x i8> [[X:%.*]], <3 x i8> poison, <7 x i32> <i32 0, i32 1, i32 poison, i32 poison, i32 poison, i32 poison, i32 poison>
1370; CHECK-NEXT:    [[S2:%.*]] = shufflevector <3 x i8> [[Y:%.*]], <3 x i8> poison, <7 x i32> <i32 poison, i32 1, i32 2, i32 poison, i32 poison, i32 poison, i32 poison>
1371; CHECK-NEXT:    [[S3:%.*]] = shufflevector <7 x i8> [[S1]], <7 x i8> [[S2]], <7 x i32> <i32 0, i32 8, i32 1, i32 poison, i32 8, i32 1, i32 9>
1372; CHECK-NEXT:    ret <7 x i8> [[S3]]
1373;
1374  %s1 = shufflevector <3 x i8> %x, <3 x i8> undef, <7 x i32> <i32 0, i32 1, i32 undef, i32 undef, i32 undef, i32 undef, i32 undef>
1375  %s2 = shufflevector <3 x i8> %y, <3 x i8> undef, <7 x i32> <i32 undef, i32 1, i32 2, i32 undef, i32 undef, i32 undef, i32 undef>
1376  %s3 = shufflevector <7 x i8> %s1, <7 x i8> %s2, <7 x i32> <i32 0, i32 8, i32 1, i32 undef, i32 8, i32 1, i32 9>
1377  ret <7 x i8> %s3
1378}
1379
1380define <8 x i8> @insert_subvector_shuffles_pow2elts(<2 x i8> %x, <2 x i8> %y) {
1381; CHECK-LABEL: @insert_subvector_shuffles_pow2elts(
1382; CHECK-NEXT:    [[S3:%.*]] = shufflevector <2 x i8> [[X:%.*]], <2 x i8> [[Y:%.*]], <8 x i32> <i32 0, i32 2, i32 1, i32 poison, i32 2, i32 1, i32 3, i32 0>
1383; CHECK-NEXT:    ret <8 x i8> [[S3]]
1384;
1385  %s1 = shufflevector <2 x i8> %x, <2 x i8> undef, <8 x i32> <i32 0, i32 1, i32 undef, i32 undef, i32 undef, i32 undef, i32 undef, i32 undef>
1386  %s2 = shufflevector <2 x i8> %y, <2 x i8> undef, <8 x i32> <i32 0, i32 1, i32 undef, i32 undef, i32 undef, i32 undef, i32 undef, i32 undef>
1387  %s3 = shufflevector <8 x i8> %s1, <8 x i8> %s2, <8 x i32> <i32 0, i32 8, i32 1, i32 undef, i32 8, i32 1, i32 9, i32 0>
1388  ret <8 x i8> %s3
1389}
1390
1391; The last shuffle may change the vector type.
1392; Negative test - do not transform non-power-of-2 unless we know the backend handles these sequences identically.
1393
1394define <2 x i8> @insert_subvector_shuffles_narrowing(<3 x i8> %x, <3 x i8> %y) {
1395; CHECK-LABEL: @insert_subvector_shuffles_narrowing(
1396; CHECK-NEXT:    [[S1:%.*]] = shufflevector <3 x i8> [[X:%.*]], <3 x i8> poison, <7 x i32> <i32 0, i32 poison, i32 poison, i32 poison, i32 poison, i32 poison, i32 poison>
1397; CHECK-NEXT:    [[S2:%.*]] = shufflevector <3 x i8> [[Y:%.*]], <3 x i8> poison, <7 x i32> <i32 poison, i32 1, i32 poison, i32 poison, i32 poison, i32 poison, i32 poison>
1398; CHECK-NEXT:    [[S3:%.*]] = shufflevector <7 x i8> [[S1]], <7 x i8> [[S2]], <2 x i32> <i32 0, i32 8>
1399; CHECK-NEXT:    ret <2 x i8> [[S3]]
1400;
1401  %s1 = shufflevector <3 x i8> %x, <3 x i8> undef, <7 x i32> <i32 0, i32 1, i32 undef, i32 undef, i32 undef, i32 undef, i32 undef>
1402  %s2 = shufflevector <3 x i8> %y, <3 x i8> undef, <7 x i32> <i32 undef, i32 1, i32 2, i32 undef, i32 undef, i32 undef, i32 undef>
1403  %s3 = shufflevector <7 x i8> %s1, <7 x i8> %s2, <2 x i32> <i32 0, i32 8>
1404  ret <2 x i8> %s3
1405}
1406
1407define <2 x i8> @insert_subvector_shuffles_narrowing_pow2elts(<4 x i8> %x, <4 x i8> %y) {
1408; CHECK-LABEL: @insert_subvector_shuffles_narrowing_pow2elts(
1409; CHECK-NEXT:    [[S3:%.*]] = shufflevector <4 x i8> [[X:%.*]], <4 x i8> [[Y:%.*]], <2 x i32> <i32 0, i32 4>
1410; CHECK-NEXT:    ret <2 x i8> [[S3]]
1411;
1412  %s1 = shufflevector <4 x i8> %x, <4 x i8> undef, <8 x i32> <i32 0, i32 1, i32 2, i32 undef, i32 undef, i32 undef, i32 undef, i32 undef>
1413  %s2 = shufflevector <4 x i8> %y, <4 x i8> undef, <8 x i32> <i32 0, i32 1, i32 undef, i32 3, i32 undef, i32 undef, i32 undef, i32 undef>
1414  %s3 = shufflevector <8 x i8> %s1, <8 x i8> %s2, <2 x i32> <i32 0, i32 8>
1415  ret <2 x i8> %s3
1416}
1417
1418; Similar to above, but this reduces to a widen with undefs of 'x'.
1419
1420define <4 x double> @insert_subvector_shuffles_identity(<2 x double> %x) {
1421; CHECK-LABEL: @insert_subvector_shuffles_identity(
1422; CHECK-NEXT:    [[S3:%.*]] = shufflevector <2 x double> [[X:%.*]], <2 x double> poison, <4 x i32> <i32 0, i32 1, i32 poison, i32 poison>
1423; CHECK-NEXT:    ret <4 x double> [[S3]]
1424;
1425  %s1 = shufflevector <2 x double> %x, <2 x double> undef, <4 x i32> <i32 undef, i32 1, i32 undef, i32 undef>
1426  %s2 = shufflevector <2 x double> %x, <2 x double> undef, <4 x i32> <i32 0, i32 undef, i32 undef, i32 undef>
1427  %s3 = shufflevector <4 x double> %s2, <4 x double> %s1, <4 x i32> <i32 0, i32 5, i32 undef, i32 undef>
1428  ret <4 x double> %s3
1429}
1430
1431; Negative test - not identity with padding (although this could be folded with better analysis).
1432
1433define <4 x double> @not_insert_subvector_shuffle(<2 x double> %x) {
1434; CHECK-LABEL: @not_insert_subvector_shuffle(
1435; CHECK-NEXT:    [[S1:%.*]] = shufflevector <2 x double> [[X:%.*]], <2 x double> poison, <4 x i32> <i32 poison, i32 1, i32 poison, i32 1>
1436; CHECK-NEXT:    [[S2:%.*]] = shufflevector <2 x double> [[X]], <2 x double> poison, <4 x i32> <i32 0, i32 poison, i32 poison, i32 poison>
1437; CHECK-NEXT:    [[S3:%.*]] = shufflevector <4 x double> [[S2]], <4 x double> [[S1]], <4 x i32> <i32 0, i32 5, i32 7, i32 poison>
1438; CHECK-NEXT:    ret <4 x double> [[S3]]
1439;
1440  %s1 = shufflevector <2 x double> %x, <2 x double> undef, <4 x i32> <i32 undef, i32 1, i32 undef, i32 1>
1441  %s2 = shufflevector <2 x double> %x, <2 x double> undef, <4 x i32> <i32 0, i32 undef, i32 undef, i32 undef>
1442  %s3 = shufflevector <4 x double> %s2, <4 x double> %s1, <4 x i32> <i32 0, i32 5, i32 7, i32 undef>
1443  ret <4 x double> %s3
1444}
1445
1446; Negative test - operands are not the same size (although this could be partly folded with better analysis).
1447
1448define <4 x double> @not_insert_subvector_shuffles_with_same_size(<2 x double> %x, <3 x double> %y) {
1449; CHECK-LABEL: @not_insert_subvector_shuffles_with_same_size(
1450; CHECK-NEXT:    [[S1:%.*]] = shufflevector <2 x double> [[X:%.*]], <2 x double> poison, <4 x i32> <i32 poison, i32 1, i32 poison, i32 poison>
1451; CHECK-NEXT:    [[S2:%.*]] = shufflevector <3 x double> [[Y:%.*]], <3 x double> poison, <4 x i32> <i32 0, i32 poison, i32 poison, i32 poison>
1452; CHECK-NEXT:    [[S3:%.*]] = shufflevector <4 x double> [[S2]], <4 x double> [[S1]], <4 x i32> <i32 0, i32 5, i32 poison, i32 poison>
1453; CHECK-NEXT:    ret <4 x double> [[S3]]
1454;
1455  %s1 = shufflevector <2 x double> %x, <2 x double> undef, <4 x i32> <i32 undef, i32 1, i32 undef, i32 undef>
1456  %s2 = shufflevector <3 x double> %y, <3 x double> undef, <4 x i32> <i32 0, i32 undef, i32 undef, i32 undef>
1457  %s3 = shufflevector <4 x double> %s2, <4 x double> %s1, <4 x i32> <i32 0, i32 5, i32 undef, i32 undef>
1458  ret <4 x double> %s3
1459}
1460
1461; Demanded vector elements may not be able to simplify a shuffle mask
1462; before we try to narrow it. This used to crash.
1463
1464define <4 x float> @insert_subvector_crash_invalid_mask_elt(<2 x float> %x, ptr %p) {
1465; CHECK-LABEL: @insert_subvector_crash_invalid_mask_elt(
1466; CHECK-NEXT:    [[WIDEN:%.*]] = shufflevector <2 x float> [[X:%.*]], <2 x float> poison, <4 x i32> <i32 0, i32 1, i32 poison, i32 poison>
1467; CHECK-NEXT:    [[I:%.*]] = shufflevector <2 x float> [[X]], <2 x float> poison, <4 x i32> <i32 0, i32 1, i32 poison, i32 poison>
1468; CHECK-NEXT:    store <4 x float> [[I]], ptr [[P:%.*]], align 16
1469; CHECK-NEXT:    ret <4 x float> [[WIDEN]]
1470;
1471  %widen = shufflevector <2 x float> %x, <2 x float> undef, <4 x i32> <i32 0, i32 1, i32 undef, i32 undef>
1472  %ext2 = extractelement <2 x float> %x, i32 0
1473  %I = insertelement <4 x float> %widen, float %ext2, i16 0
1474  store <4 x float> %I, ptr %p
1475  ret <4 x float> %widen
1476}
1477
1478define <4 x i32> @splat_assoc_add(<4 x i32> %x, <4 x i32> %y) {
1479; CHECK-LABEL: @splat_assoc_add(
1480; CHECK-NEXT:    [[TMP1:%.*]] = add <4 x i32> [[X:%.*]], <i32 317426, i32 poison, i32 poison, i32 poison>
1481; CHECK-NEXT:    [[TMP2:%.*]] = shufflevector <4 x i32> [[TMP1]], <4 x i32> poison, <4 x i32> zeroinitializer
1482; CHECK-NEXT:    [[R:%.*]] = add <4 x i32> [[TMP2]], [[Y:%.*]]
1483; CHECK-NEXT:    ret <4 x i32> [[R]]
1484;
1485  %splatx = shufflevector <4 x i32> %x, <4 x i32> undef, <4 x i32> zeroinitializer
1486  %a = add <4 x i32> %y, <i32 317426, i32 317426, i32 317426, i32 317426>
1487  %r = add <4 x i32> %splatx, %a
1488  ret <4 x i32> %r
1489}
1490
1491define <vscale x 4 x i32> @vsplat_assoc_add(<vscale x 4 x i32> %x, <vscale x 4 x i32> %y) {
1492; CHECK-LABEL: @vsplat_assoc_add(
1493; CHECK-NEXT:    [[TMP1:%.*]] = add <vscale x 4 x i32> [[X:%.*]], splat (i32 317426)
1494; CHECK-NEXT:    [[TMP2:%.*]] = shufflevector <vscale x 4 x i32> [[TMP1]], <vscale x 4 x i32> poison, <vscale x 4 x i32> zeroinitializer
1495; CHECK-NEXT:    [[R:%.*]] = add <vscale x 4 x i32> [[TMP2]], [[Y:%.*]]
1496; CHECK-NEXT:    ret <vscale x 4 x i32> [[R]]
1497;
1498
1499  %splatx = shufflevector <vscale x 4 x i32> %x, <vscale x 4 x i32> undef, <vscale x 4 x i32> zeroinitializer
1500  %a = add <vscale x 4 x i32> %y, splat (i32 317426)
1501  %r = add <vscale x 4 x i32> %splatx, %a
1502  ret <vscale x 4 x i32> %r
1503}
1504
1505; Undefs in splat mask are replaced with defined splat index
1506
1507define <4 x i32> @splat_assoc_add_undef_mask_elts(<4 x i32> %x, <4 x i32> %y) {
1508; CHECK-LABEL: @splat_assoc_add_undef_mask_elts(
1509; CHECK-NEXT:    [[TMP1:%.*]] = add <4 x i32> [[X:%.*]], <i32 42, i32 poison, i32 poison, i32 poison>
1510; CHECK-NEXT:    [[TMP2:%.*]] = shufflevector <4 x i32> [[TMP1]], <4 x i32> poison, <4 x i32> zeroinitializer
1511; CHECK-NEXT:    [[R:%.*]] = add <4 x i32> [[TMP2]], [[Y:%.*]]
1512; CHECK-NEXT:    ret <4 x i32> [[R]]
1513;
1514  %splatx = shufflevector <4 x i32> %x, <4 x i32> undef, <4 x i32> <i32 0, i32 0, i32 undef, i32 undef>
1515  %a = add <4 x i32> %y, <i32 42, i32 42, i32 42, i32 42>
1516  %r = add <4 x i32> %splatx, %a
1517  ret <4 x i32> %r
1518}
1519
1520; Undefs in splat mask are replaced with defined splat index
1521
1522define <4 x i32> @splat_assoc_add_undef_mask_elt_at_splat_index(<4 x i32> %x, <4 x i32> %y) {
1523; CHECK-LABEL: @splat_assoc_add_undef_mask_elt_at_splat_index(
1524; CHECK-NEXT:    [[TMP1:%.*]] = add <4 x i32> [[X:%.*]], <i32 42, i32 poison, i32 poison, i32 poison>
1525; CHECK-NEXT:    [[TMP2:%.*]] = shufflevector <4 x i32> [[TMP1]], <4 x i32> poison, <4 x i32> zeroinitializer
1526; CHECK-NEXT:    [[R:%.*]] = add <4 x i32> [[TMP2]], [[Y:%.*]]
1527; CHECK-NEXT:    ret <4 x i32> [[R]]
1528;
1529  %splatx = shufflevector <4 x i32> %x, <4 x i32> undef, <4 x i32> <i32 undef, i32 0, i32 0, i32 0>
1530  %a = add <4 x i32> %y, <i32 42, i32 42, i32 42, i32 42>
1531  %r = add <4 x i32> %splatx, %a
1532  ret <4 x i32> %r
1533}
1534
1535define <4 x i32> @splat_assoc_add_undef_constant_elts(<4 x i32> %x, <4 x i32> %y) {
1536; CHECK-LABEL: @splat_assoc_add_undef_constant_elts(
1537; CHECK-NEXT:    [[SPLATX:%.*]] = shufflevector <4 x i32> [[X:%.*]], <4 x i32> poison, <4 x i32> zeroinitializer
1538; CHECK-NEXT:    [[A:%.*]] = add <4 x i32> [[Y:%.*]], <i32 42, i32 undef, i32 undef, i32 42>
1539; CHECK-NEXT:    [[R:%.*]] = add <4 x i32> [[SPLATX]], [[A]]
1540; CHECK-NEXT:    ret <4 x i32> [[R]]
1541;
1542  %splatx = shufflevector <4 x i32> %x, <4 x i32> undef, <4 x i32> zeroinitializer
1543  %a = add <4 x i32> %y, <i32 42, i32 undef, i32 undef, i32 42>
1544  %r = add <4 x i32> %splatx, %a
1545  ret <4 x i32> %r
1546}
1547
1548define <4 x i32> @splat_assoc_add_undef_constant_elt_at_splat_index(<4 x i32> %x, <4 x i32> %y) {
1549; CHECK-LABEL: @splat_assoc_add_undef_constant_elt_at_splat_index(
1550; CHECK-NEXT:    [[SPLATX:%.*]] = shufflevector <4 x i32> [[X:%.*]], <4 x i32> poison, <4 x i32> zeroinitializer
1551; CHECK-NEXT:    [[A:%.*]] = add <4 x i32> [[Y:%.*]], <i32 undef, i32 42, i32 undef, i32 42>
1552; CHECK-NEXT:    [[R:%.*]] = add <4 x i32> [[SPLATX]], [[A]]
1553; CHECK-NEXT:    ret <4 x i32> [[R]]
1554;
1555  %splatx = shufflevector <4 x i32> %x, <4 x i32> undef, <4 x i32> zeroinitializer
1556  %a = add <4 x i32> %y, <i32 undef, i32 42, i32 undef, i32 42>
1557  %r = add <4 x i32> %splatx, %a
1558  ret <4 x i32> %r
1559}
1560
1561define <4 x i32> @splat_assoc_add_undef_mask_elts_undef_constant_elts(<4 x i32> %x, <4 x i32> %y) {
1562; CHECK-LABEL: @splat_assoc_add_undef_mask_elts_undef_constant_elts(
1563; CHECK-NEXT:    [[SPLATX:%.*]] = shufflevector <4 x i32> [[X:%.*]], <4 x i32> poison, <4 x i32> <i32 0, i32 poison, i32 0, i32 poison>
1564; CHECK-NEXT:    [[A:%.*]] = add <4 x i32> [[Y:%.*]], <i32 42, i32 undef, i32 undef, i32 42>
1565; CHECK-NEXT:    [[R:%.*]] = add <4 x i32> [[SPLATX]], [[A]]
1566; CHECK-NEXT:    ret <4 x i32> [[R]]
1567;
1568  %splatx = shufflevector <4 x i32> %x, <4 x i32> undef, <4 x i32> <i32 0, i32 undef, i32 0, i32 undef>
1569  %a = add <4 x i32> %y, <i32 42, i32 undef, i32 undef, i32 42>
1570  %r = add <4 x i32> %splatx, %a
1571  ret <4 x i32> %r
1572}
1573
1574define <4 x i32> @splat_assoc_add_undef_mask_elt_at_splat_index_undef_constant_elts(<4 x i32> %x, <4 x i32> %y) {
1575; CHECK-LABEL: @splat_assoc_add_undef_mask_elt_at_splat_index_undef_constant_elts(
1576; CHECK-NEXT:    [[SPLATX:%.*]] = shufflevector <4 x i32> [[X:%.*]], <4 x i32> poison, <4 x i32> <i32 poison, i32 0, i32 0, i32 0>
1577; CHECK-NEXT:    [[A:%.*]] = add <4 x i32> [[Y:%.*]], <i32 42, i32 undef, i32 undef, i32 42>
1578; CHECK-NEXT:    [[R:%.*]] = add <4 x i32> [[SPLATX]], [[A]]
1579; CHECK-NEXT:    ret <4 x i32> [[R]]
1580;
1581  %splatx = shufflevector <4 x i32> %x, <4 x i32> undef, <4 x i32> <i32 undef, i32 0, i32 0, i32 0>
1582  %a = add <4 x i32> %y, <i32 42, i32 undef, i32 undef, i32 42>
1583  %r = add <4 x i32> %splatx, %a
1584  ret <4 x i32> %r
1585}
1586
1587define <4 x i32> @splat_assoc_add_undef_mask_elt_at_splat_index_undef_constant_elt_at_splat_index(<4 x i32> %x, <4 x i32> %y) {
1588; CHECK-LABEL: @splat_assoc_add_undef_mask_elt_at_splat_index_undef_constant_elt_at_splat_index(
1589; CHECK-NEXT:    [[SPLATX:%.*]] = shufflevector <4 x i32> [[X:%.*]], <4 x i32> poison, <4 x i32> <i32 poison, i32 0, i32 0, i32 0>
1590; CHECK-NEXT:    [[A:%.*]] = add <4 x i32> [[Y:%.*]], <i32 undef, i32 42, i32 undef, i32 42>
1591; CHECK-NEXT:    [[R:%.*]] = add <4 x i32> [[SPLATX]], [[A]]
1592; CHECK-NEXT:    ret <4 x i32> [[R]]
1593;
1594  %splatx = shufflevector <4 x i32> %x, <4 x i32> undef, <4 x i32> <i32 undef, i32 0, i32 0, i32 0>
1595  %a = add <4 x i32> %y, <i32 undef, i32 42, i32 undef, i32 42>
1596  %r = add <4 x i32> %splatx, %a
1597  ret <4 x i32> %r
1598}
1599
1600; Non-zero splat index; commute operands; FMF intersect
1601
1602define <2 x float> @splat_assoc_fmul(<2 x float> %x, <2 x float> %y) {
1603; CHECK-LABEL: @splat_assoc_fmul(
1604; CHECK-NEXT:    [[TMP1:%.*]] = fmul reassoc nsz <2 x float> [[X:%.*]], <float poison, float 3.000000e+00>
1605; CHECK-NEXT:    [[TMP2:%.*]] = shufflevector <2 x float> [[TMP1]], <2 x float> poison, <2 x i32> <i32 1, i32 1>
1606; CHECK-NEXT:    [[R:%.*]] = fmul reassoc nsz <2 x float> [[TMP2]], [[Y:%.*]]
1607; CHECK-NEXT:    ret <2 x float> [[R]]
1608;
1609  %splatx = shufflevector <2 x float> %x, <2 x float> undef, <2 x i32> <i32 1, i32 1>
1610  %a = fmul reassoc nsz <2 x float> %y, <float 3.0, float 3.0>
1611  %r = fmul reassoc nsz nnan <2 x float> %a, %splatx
1612  ret <2 x float> %r
1613}
1614
1615; Two splat shuffles; drop poison-generating flags
1616
1617define <3 x i8> @splat_assoc_mul(<3 x i8> %x, <3 x i8> %y, <3 x i8> %z) {
1618; CHECK-LABEL: @splat_assoc_mul(
1619; CHECK-NEXT:    [[TMP1:%.*]] = mul <3 x i8> [[X:%.*]], [[Z:%.*]]
1620; CHECK-NEXT:    [[TMP2:%.*]] = shufflevector <3 x i8> [[TMP1]], <3 x i8> poison, <3 x i32> <i32 2, i32 2, i32 2>
1621; CHECK-NEXT:    [[R:%.*]] = mul <3 x i8> [[TMP2]], [[Y:%.*]]
1622; CHECK-NEXT:    ret <3 x i8> [[R]]
1623;
1624  %splatx = shufflevector <3 x i8> %x, <3 x i8> undef, <3 x i32> <i32 2, i32 2, i32 2>
1625  %splatz = shufflevector <3 x i8> %z, <3 x i8> undef, <3 x i32> <i32 2, i32 2, i32 2>
1626  %a = mul nsw <3 x i8> %y, %splatz
1627  %r = mul <3 x i8> %a, %splatx
1628  ret <3 x i8> %r
1629}
1630
1631define <3 x i8> @splat_assoc_mul_undef_elt1(<3 x i8> %x, <3 x i8> %y, <3 x i8> %z) {
1632; CHECK-LABEL: @splat_assoc_mul_undef_elt1(
1633; CHECK-NEXT:    [[TMP1:%.*]] = mul <3 x i8> [[X:%.*]], [[Z:%.*]]
1634; CHECK-NEXT:    [[TMP2:%.*]] = shufflevector <3 x i8> [[TMP1]], <3 x i8> poison, <3 x i32> <i32 2, i32 2, i32 2>
1635; CHECK-NEXT:    [[R:%.*]] = mul <3 x i8> [[TMP2]], [[Y:%.*]]
1636; CHECK-NEXT:    ret <3 x i8> [[R]]
1637;
1638  %splatx = shufflevector <3 x i8> %x, <3 x i8> undef, <3 x i32> <i32 undef, i32 2, i32 2>
1639  %splatz = shufflevector <3 x i8> %z, <3 x i8> undef, <3 x i32> <i32 2, i32 2, i32 2>
1640  %a = mul nsw <3 x i8> %y, %splatz
1641  %r = mul nsw nuw <3 x i8> %a, %splatx
1642  ret <3 x i8> %r
1643}
1644
1645define <3 x i8> @splat_assoc_mul_undef_elt2(<3 x i8> %x, <3 x i8> %y, <3 x i8> %z) {
1646; CHECK-LABEL: @splat_assoc_mul_undef_elt2(
1647; CHECK-NEXT:    [[SPLATX:%.*]] = shufflevector <3 x i8> [[X:%.*]], <3 x i8> poison, <3 x i32> <i32 2, i32 2, i32 2>
1648; CHECK-NEXT:    [[SPLATZ:%.*]] = shufflevector <3 x i8> [[Z:%.*]], <3 x i8> poison, <3 x i32> <i32 poison, i32 2, i32 2>
1649; CHECK-NEXT:    [[A:%.*]] = mul nsw <3 x i8> [[Y:%.*]], [[SPLATZ]]
1650; CHECK-NEXT:    [[R:%.*]] = mul nuw nsw <3 x i8> [[A]], [[SPLATX]]
1651; CHECK-NEXT:    ret <3 x i8> [[R]]
1652;
1653  %splatx = shufflevector <3 x i8> %x, <3 x i8> undef, <3 x i32> <i32 2, i32 2, i32 2>
1654  %splatz = shufflevector <3 x i8> %z, <3 x i8> undef, <3 x i32> <i32 undef, i32 2, i32 2>
1655  %a = mul nsw <3 x i8> %y, %splatz
1656  %r = mul nsw nuw <3 x i8> %a, %splatx
1657  ret <3 x i8> %r
1658}
1659
1660define <3 x i8> @splat_assoc_mul_undef_elt_at_splat_index1(<3 x i8> %x, <3 x i8> %y, <3 x i8> %z) {
1661; CHECK-LABEL: @splat_assoc_mul_undef_elt_at_splat_index1(
1662; CHECK-NEXT:    [[TMP1:%.*]] = mul <3 x i8> [[X:%.*]], [[Z:%.*]]
1663; CHECK-NEXT:    [[TMP2:%.*]] = shufflevector <3 x i8> [[TMP1]], <3 x i8> poison, <3 x i32> <i32 2, i32 2, i32 2>
1664; CHECK-NEXT:    [[R:%.*]] = mul <3 x i8> [[TMP2]], [[Y:%.*]]
1665; CHECK-NEXT:    ret <3 x i8> [[R]]
1666;
1667  %splatx = shufflevector <3 x i8> %x, <3 x i8> undef, <3 x i32> <i32 2, i32 2, i32 undef>
1668  %splatz = shufflevector <3 x i8> %z, <3 x i8> undef, <3 x i32> <i32 2, i32 2, i32 2>
1669  %a = mul nsw <3 x i8> %y, %splatz
1670  %r = mul nsw nuw <3 x i8> %a, %splatx
1671  ret <3 x i8> %r
1672}
1673
1674define <3 x i8> @splat_assoc_mul_undef_elt_at_splat_index2(<3 x i8> %x, <3 x i8> %y, <3 x i8> %z) {
1675; CHECK-LABEL: @splat_assoc_mul_undef_elt_at_splat_index2(
1676; CHECK-NEXT:    [[SPLATX:%.*]] = shufflevector <3 x i8> [[X:%.*]], <3 x i8> poison, <3 x i32> <i32 2, i32 2, i32 2>
1677; CHECK-NEXT:    [[SPLATZ:%.*]] = shufflevector <3 x i8> [[Z:%.*]], <3 x i8> poison, <3 x i32> <i32 2, i32 2, i32 poison>
1678; CHECK-NEXT:    [[A:%.*]] = mul nsw <3 x i8> [[Y:%.*]], [[SPLATZ]]
1679; CHECK-NEXT:    [[R:%.*]] = mul nuw nsw <3 x i8> [[A]], [[SPLATX]]
1680; CHECK-NEXT:    ret <3 x i8> [[R]]
1681;
1682  %splatx = shufflevector <3 x i8> %x, <3 x i8> undef, <3 x i32> <i32 2, i32 2, i32 2>
1683  %splatz = shufflevector <3 x i8> %z, <3 x i8> undef, <3 x i32> <i32 2, i32 2, i32 undef>
1684  %a = mul nsw <3 x i8> %y, %splatz
1685  %r = mul nsw nuw <3 x i8> %a, %splatx
1686  ret <3 x i8> %r
1687}
1688
1689; Negative test - mismatched splat elements
1690
1691define <3 x i8> @splat_assoc_or(<3 x i8> %x, <3 x i8> %y, <3 x i8> %z) {
1692; CHECK-LABEL: @splat_assoc_or(
1693; CHECK-NEXT:    [[SPLATX:%.*]] = shufflevector <3 x i8> [[X:%.*]], <3 x i8> poison, <3 x i32> <i32 1, i32 1, i32 1>
1694; CHECK-NEXT:    [[SPLATZ:%.*]] = shufflevector <3 x i8> [[Z:%.*]], <3 x i8> poison, <3 x i32> <i32 2, i32 2, i32 2>
1695; CHECK-NEXT:    [[A:%.*]] = or <3 x i8> [[Y:%.*]], [[SPLATZ]]
1696; CHECK-NEXT:    [[R:%.*]] = or <3 x i8> [[A]], [[SPLATX]]
1697; CHECK-NEXT:    ret <3 x i8> [[R]]
1698;
1699  %splatx = shufflevector <3 x i8> %x, <3 x i8> undef, <3 x i32> <i32 1, i32 1, i32 1>
1700  %splatz = shufflevector <3 x i8> %z, <3 x i8> undef, <3 x i32> <i32 2, i32 2, i32 2>
1701  %a = or <3 x i8> %y, %splatz
1702  %r = or <3 x i8> %a, %splatx
1703  ret <3 x i8> %r
1704}
1705
1706; Negative test - not associative
1707
1708define <2 x float> @splat_assoc_fdiv(<2 x float> %x, <2 x float> %y) {
1709; CHECK-LABEL: @splat_assoc_fdiv(
1710; CHECK-NEXT:    [[SPLATX:%.*]] = shufflevector <2 x float> [[X:%.*]], <2 x float> poison, <2 x i32> zeroinitializer
1711; CHECK-NEXT:    [[A:%.*]] = fdiv reassoc nsz <2 x float> [[Y:%.*]], splat (float 3.000000e+00)
1712; CHECK-NEXT:    [[R:%.*]] = fdiv reassoc nsz <2 x float> [[A]], [[SPLATX]]
1713; CHECK-NEXT:    ret <2 x float> [[R]]
1714;
1715  %splatx = shufflevector <2 x float> %x, <2 x float> undef, <2 x i32> zeroinitializer
1716  %a = fdiv reassoc nsz <2 x float> %y, <float 3.0, float 3.0>
1717  %r = fdiv reassoc nsz <2 x float> %a, %splatx
1718  ret <2 x float> %r
1719}
1720
1721; Negative test - extra use
1722
1723define <2 x float> @splat_assoc_fadd(<2 x float> %x, <2 x float> %y) {
1724; CHECK-LABEL: @splat_assoc_fadd(
1725; CHECK-NEXT:    [[SPLATX:%.*]] = shufflevector <2 x float> [[X:%.*]], <2 x float> poison, <2 x i32> <i32 1, i32 1>
1726; CHECK-NEXT:    [[A:%.*]] = fadd fast <2 x float> [[Y:%.*]], splat (float 3.000000e+00)
1727; CHECK-NEXT:    call void @use(<2 x float> [[A]])
1728; CHECK-NEXT:    [[R:%.*]] = fadd fast <2 x float> [[A]], [[SPLATX]]
1729; CHECK-NEXT:    ret <2 x float> [[R]]
1730;
1731  %splatx = shufflevector <2 x float> %x, <2 x float> undef, <2 x i32> <i32 1, i32 1>
1732  %a = fadd fast <2 x float> %y, <float 3.0, float 3.0>
1733  call void @use(<2 x float> %a)
1734  %r = fadd fast <2 x float> %a, %splatx
1735  ret <2 x float> %r
1736}
1737
1738; Negative test - narrowing splat
1739
1740define <3 x i32> @splat_assoc_and(<4 x i32> %x, <3 x i32> %y) {
1741; CHECK-LABEL: @splat_assoc_and(
1742; CHECK-NEXT:    [[SPLATX:%.*]] = shufflevector <4 x i32> [[X:%.*]], <4 x i32> poison, <3 x i32> zeroinitializer
1743; CHECK-NEXT:    [[A:%.*]] = and <3 x i32> [[Y:%.*]], splat (i32 42)
1744; CHECK-NEXT:    [[R:%.*]] = and <3 x i32> [[SPLATX]], [[A]]
1745; CHECK-NEXT:    ret <3 x i32> [[R]]
1746;
1747  %splatx = shufflevector <4 x i32> %x, <4 x i32> undef, <3 x i32> zeroinitializer
1748  %a = and <3 x i32> %y, <i32 42, i32 42, i32 42>
1749  %r = and <3 x i32> %splatx, %a
1750  ret <3 x i32> %r
1751}
1752
1753; Negative test - widening splat
1754
1755define <5 x i32> @splat_assoc_xor(<4 x i32> %x, <5 x i32> %y) {
1756; CHECK-LABEL: @splat_assoc_xor(
1757; CHECK-NEXT:    [[SPLATX:%.*]] = shufflevector <4 x i32> [[X:%.*]], <4 x i32> poison, <5 x i32> zeroinitializer
1758; CHECK-NEXT:    [[TMP1:%.*]] = xor <5 x i32> [[Y:%.*]], [[SPLATX]]
1759; CHECK-NEXT:    [[R:%.*]] = xor <5 x i32> [[TMP1]], splat (i32 42)
1760; CHECK-NEXT:    ret <5 x i32> [[R]]
1761;
1762  %splatx = shufflevector <4 x i32> %x, <4 x i32> undef, <5 x i32> zeroinitializer
1763  %a = xor <5 x i32> %y, <i32 42, i32 42, i32 42, i32 42, i32 42>
1764  %r = xor <5 x i32> %splatx, %a
1765  ret <5 x i32> %r
1766}
1767
1768; Negative test - opcode mismatch
1769
1770define <4 x i32> @splat_assoc_add_mul(<4 x i32> %x, <4 x i32> %y) {
1771; CHECK-LABEL: @splat_assoc_add_mul(
1772; CHECK-NEXT:    [[SPLATX:%.*]] = shufflevector <4 x i32> [[X:%.*]], <4 x i32> poison, <4 x i32> zeroinitializer
1773; CHECK-NEXT:    [[A:%.*]] = add <4 x i32> [[Y:%.*]], splat (i32 42)
1774; CHECK-NEXT:    [[R:%.*]] = mul <4 x i32> [[SPLATX]], [[A]]
1775; CHECK-NEXT:    ret <4 x i32> [[R]]
1776;
1777  %splatx = shufflevector <4 x i32> %x, <4 x i32> undef, <4 x i32> zeroinitializer
1778  %a = add <4 x i32> %y, <i32 42, i32 42, i32 42, i32 42>
1779  %r = mul <4 x i32> %splatx, %a
1780  ret <4 x i32> %r
1781}
1782
1783
1784; Do not crash on constant expressions.
1785
1786define <4 x i32> @PR46872(<4 x i32> %x) {
1787; CHECK-LABEL: @PR46872(
1788; CHECK-NEXT:    [[S:%.*]] = shufflevector <4 x i32> [[X:%.*]], <4 x i32> poison, <4 x i32> <i32 poison, i32 0, i32 1, i32 1>
1789; CHECK-NEXT:    [[A:%.*]] = and <4 x i32> [[S]], bitcast (<2 x i64> <i64 ptrtoint (ptr @PR46872 to i64), i64 ptrtoint (ptr @PR46872 to i64)> to <4 x i32>)
1790; CHECK-NEXT:    ret <4 x i32> [[A]]
1791;
1792  %s = shufflevector <4 x i32> %x, <4 x i32> undef, <4 x i32> <i32 undef, i32 0, i32 1, i32 1>
1793  %a = and <4 x i32> %s, bitcast (<2 x i64> <i64 ptrtoint (ptr @PR46872 to i64), i64 ptrtoint (ptr @PR46872 to i64)> to <4 x i32>)
1794  ret <4 x i32> %a
1795}
1796
1797define <2 x float> @fabs_unary_shuf(<2 x float> %x) {
1798; CHECK-LABEL: @fabs_unary_shuf(
1799; CHECK-NEXT:    [[TMP1:%.*]] = shufflevector <2 x float> [[X:%.*]], <2 x float> poison, <2 x i32> <i32 1, i32 0>
1800; CHECK-NEXT:    [[R:%.*]] = call nnan nsz <2 x float> @llvm.fabs.v2f32(<2 x float> [[TMP1]])
1801; CHECK-NEXT:    ret <2 x float> [[R]]
1802;
1803  %nx = call nsz nnan <2 x float> @llvm.fabs.v2f32(<2 x float> %x)
1804  %r = shufflevector <2 x float> %nx, <2 x float> poison, <2 x i32> <i32 1, i32 0>
1805  ret <2 x float> %r
1806}
1807
1808define <4 x half> @fabs_unary_shuf_widen(<2 x half> %x) {
1809; CHECK-LABEL: @fabs_unary_shuf_widen(
1810; CHECK-NEXT:    [[TMP1:%.*]] = shufflevector <2 x half> [[X:%.*]], <2 x half> poison, <4 x i32> <i32 1, i32 0, i32 0, i32 poison>
1811; CHECK-NEXT:    [[R:%.*]] = call ninf <4 x half> @llvm.fabs.v4f16(<4 x half> [[TMP1]])
1812; CHECK-NEXT:    ret <4 x half> [[R]]
1813;
1814  %nx = call ninf <2 x half> @llvm.fabs.v2f16(<2 x half> %x)
1815  %r = shufflevector <2 x half> %nx, <2 x half> poison, <4 x i32> <i32 1, i32 0, i32 0, i32 poison>
1816  ret <4 x half> %r
1817}
1818
1819define <2 x double> @fabs_unary_shuf_narrow(<4 x double> %x) {
1820; CHECK-LABEL: @fabs_unary_shuf_narrow(
1821; CHECK-NEXT:    [[TMP1:%.*]] = shufflevector <4 x double> [[X:%.*]], <4 x double> poison, <2 x i32> <i32 3, i32 0>
1822; CHECK-NEXT:    [[R:%.*]] = call nsz <2 x double> @llvm.fabs.v2f64(<2 x double> [[TMP1]])
1823; CHECK-NEXT:    ret <2 x double> [[R]]
1824;
1825  %nx = call nsz <4 x double> @llvm.fabs.v4f64(<4 x double> %x)
1826  %r = shufflevector <4 x double> %nx, <4 x double> poison, <2 x i32> <i32 3, i32 0>
1827  ret <2 x double> %r
1828}
1829
1830; negative test - extra use prevents canonicalization
1831
1832define <2 x float> @fabs_unary_shuf_use(<2 x float> %x) {
1833; CHECK-LABEL: @fabs_unary_shuf_use(
1834; CHECK-NEXT:    [[NX:%.*]] = call nsz <2 x float> @llvm.fabs.v2f32(<2 x float> [[X:%.*]])
1835; CHECK-NEXT:    call void @use(<2 x float> [[NX]])
1836; CHECK-NEXT:    [[R:%.*]] = shufflevector <2 x float> [[NX]], <2 x float> poison, <2 x i32> <i32 poison, i32 0>
1837; CHECK-NEXT:    ret <2 x float> [[R]]
1838;
1839  %nx = call nsz <2 x float> @llvm.fabs.v2f32(<2 x float> %x)
1840  call void @use(<2 x float> %nx)
1841  %r = shufflevector <2 x float> %nx, <2 x float> poison, <2 x i32> <i32 3, i32 0>
1842  ret <2 x float> %r
1843}
1844
1845; intersect FMF
1846
1847define <4 x float> @fabs_shuf(<4 x float> %x, <4 x float> %y) {
1848; CHECK-LABEL: @fabs_shuf(
1849; CHECK-NEXT:    [[TMP1:%.*]] = shufflevector <4 x float> [[X:%.*]], <4 x float> [[Y:%.*]], <4 x i32> <i32 0, i32 1, i32 4, i32 5>
1850; CHECK-NEXT:    [[R:%.*]] = call ninf <4 x float> @llvm.fabs.v4f32(<4 x float> [[TMP1]])
1851; CHECK-NEXT:    ret <4 x float> [[R]]
1852;
1853  %nx = call nsz ninf <4 x float> @llvm.fabs.v4f32(<4 x float> %x)
1854  %ny = call nnan ninf <4 x float> @llvm.fabs.v4f32(<4 x float> %y)
1855  %r = shufflevector <4 x float> %nx, <4 x float> %ny, <4 x i32> <i32 0, i32 1, i32 4, i32 5>
1856  ret <4 x float> %r
1857}
1858
1859; length-changing shuffle and extra use are ok
1860
1861define <4 x float> @fabs_shuf_widen_use1(<2 x float> %x, <2 x float> %y) {
1862; CHECK-LABEL: @fabs_shuf_widen_use1(
1863; CHECK-NEXT:    [[NX:%.*]] = call nnan <2 x float> @llvm.fabs.v2f32(<2 x float> [[X:%.*]])
1864; CHECK-NEXT:    call void @use(<2 x float> [[NX]])
1865; CHECK-NEXT:    [[TMP1:%.*]] = shufflevector <2 x float> [[X]], <2 x float> [[Y:%.*]], <4 x i32> <i32 poison, i32 1, i32 2, i32 3>
1866; CHECK-NEXT:    [[R:%.*]] = call nnan <4 x float> @llvm.fabs.v4f32(<4 x float> [[TMP1]])
1867; CHECK-NEXT:    ret <4 x float> [[R]]
1868;
1869  %nx = call nnan <2 x float> @llvm.fabs.v2f32(<2 x float> %x)
1870  call void @use(<2 x float> %nx)
1871  %ny = call nnan <2 x float> @llvm.fabs.v2f32(<2 x float> %y)
1872  %r = shufflevector <2 x float> %nx, <2 x float> %ny, <4 x i32> <i32 poison, i32 1, i32 2, i32 3>
1873  ret <4 x float> %r
1874}
1875
1876; length-changing shuffle and extra use are ok
1877
1878define <2 x float> @fabs_shuf_narrow_use2(<4 x float> %x, <4 x float> %y) {
1879; CHECK-LABEL: @fabs_shuf_narrow_use2(
1880; CHECK-NEXT:    [[NY:%.*]] = call nnan nsz <4 x float> @llvm.fabs.v4f32(<4 x float> [[Y:%.*]])
1881; CHECK-NEXT:    call void @use4(<4 x float> [[NY]])
1882; CHECK-NEXT:    [[TMP1:%.*]] = shufflevector <4 x float> [[X:%.*]], <4 x float> [[Y]], <2 x i32> <i32 3, i32 5>
1883; CHECK-NEXT:    [[R:%.*]] = call nnan nsz <2 x float> @llvm.fabs.v2f32(<2 x float> [[TMP1]])
1884; CHECK-NEXT:    ret <2 x float> [[R]]
1885;
1886  %nx = call nsz nnan <4 x float> @llvm.fabs.v4f32(<4 x float> %x)
1887  %ny = call nsz nnan <4 x float> @llvm.fabs.v4f32(<4 x float> %y)
1888  call void @use4(<4 x float> %ny)
1889  %r = shufflevector <4 x float> %nx, <4 x float> %ny, <2 x i32> <i32 3, i32 5>
1890  ret <2 x float> %r
1891}
1892
1893; negative test - too many extra uses
1894
1895define <2 x float> @fabs_shuf_use3(<2 x float> %x, <2 x float> %y) {
1896; CHECK-LABEL: @fabs_shuf_use3(
1897; CHECK-NEXT:    [[NX:%.*]] = call nnan <2 x float> @llvm.fabs.v2f32(<2 x float> [[X:%.*]])
1898; CHECK-NEXT:    call void @use(<2 x float> [[NX]])
1899; CHECK-NEXT:    [[NY:%.*]] = call nnan <2 x float> @llvm.fabs.v2f32(<2 x float> [[Y:%.*]])
1900; CHECK-NEXT:    call void @use(<2 x float> [[NY]])
1901; CHECK-NEXT:    [[R:%.*]] = shufflevector <2 x float> [[NX]], <2 x float> [[NY]], <2 x i32> <i32 1, i32 2>
1902; CHECK-NEXT:    ret <2 x float> [[R]]
1903;
1904  %nx = call nnan <2 x float> @llvm.fabs.v2f32(<2 x float> %x)
1905  call void @use(<2 x float> %nx)
1906  %ny = call nnan <2 x float> @llvm.fabs.v2f32(<2 x float> %y)
1907  call void @use(<2 x float> %ny)
1908  %r = shufflevector <2 x float> %nx, <2 x float> %ny, <2 x i32> <i32 1, i32 2>
1909  ret <2 x float> %r
1910}
1911
1912define <2 x float> @fneg_unary_shuf(<2 x float> %x) {
1913; CHECK-LABEL: @fneg_unary_shuf(
1914; CHECK-NEXT:    [[TMP1:%.*]] = shufflevector <2 x float> [[X:%.*]], <2 x float> poison, <2 x i32> <i32 1, i32 0>
1915; CHECK-NEXT:    [[R:%.*]] = fneg nnan nsz <2 x float> [[TMP1]]
1916; CHECK-NEXT:    ret <2 x float> [[R]]
1917;
1918  %nx = fneg nsz nnan <2 x float> %x
1919  %r = shufflevector <2 x float> %nx, <2 x float> poison, <2 x i32> <i32 1, i32 0>
1920  ret <2 x float> %r
1921}
1922
1923define <4 x half> @fneg_unary_shuf_widen(<2 x half> %x) {
1924; CHECK-LABEL: @fneg_unary_shuf_widen(
1925; CHECK-NEXT:    [[TMP1:%.*]] = shufflevector <2 x half> [[X:%.*]], <2 x half> poison, <4 x i32> <i32 1, i32 0, i32 0, i32 poison>
1926; CHECK-NEXT:    [[R:%.*]] = fneg ninf <4 x half> [[TMP1]]
1927; CHECK-NEXT:    ret <4 x half> [[R]]
1928;
1929  %nx = fneg ninf <2 x half> %x
1930  %r = shufflevector <2 x half> %nx, <2 x half> poison, <4 x i32> <i32 1, i32 0, i32 0, i32 poison>
1931  ret <4 x half> %r
1932}
1933
1934define <2 x double> @fneg_unary_shuf_narrow(<4 x double> %x) {
1935; CHECK-LABEL: @fneg_unary_shuf_narrow(
1936; CHECK-NEXT:    [[TMP1:%.*]] = shufflevector <4 x double> [[X:%.*]], <4 x double> poison, <2 x i32> <i32 3, i32 0>
1937; CHECK-NEXT:    [[R:%.*]] = fneg nsz <2 x double> [[TMP1]]
1938; CHECK-NEXT:    ret <2 x double> [[R]]
1939;
1940  %nx = fneg nsz <4 x double> %x
1941  %r = shufflevector <4 x double> %nx, <4 x double> poison, <2 x i32> <i32 3, i32 0>
1942  ret <2 x double> %r
1943}
1944
1945; negative test - extra use prevents canonicalization
1946
1947define <2 x float> @fneg_unary_shuf_use(<2 x float> %x) {
1948; CHECK-LABEL: @fneg_unary_shuf_use(
1949; CHECK-NEXT:    [[NX:%.*]] = fneg nsz <2 x float> [[X:%.*]]
1950; CHECK-NEXT:    call void @use(<2 x float> [[NX]])
1951; CHECK-NEXT:    [[R:%.*]] = shufflevector <2 x float> [[NX]], <2 x float> poison, <2 x i32> <i32 poison, i32 0>
1952; CHECK-NEXT:    ret <2 x float> [[R]]
1953;
1954  %nx = fneg nsz <2 x float> %x
1955  call void @use(<2 x float> %nx)
1956  %r = shufflevector <2 x float> %nx, <2 x float> poison, <2 x i32> <i32 3, i32 0>
1957  ret <2 x float> %r
1958}
1959
1960; intersect FMF
1961
1962define <4 x float> @fneg_shuf(<4 x float> %x, <4 x float> %y) {
1963; CHECK-LABEL: @fneg_shuf(
1964; CHECK-NEXT:    [[TMP1:%.*]] = shufflevector <4 x float> [[X:%.*]], <4 x float> [[Y:%.*]], <4 x i32> <i32 0, i32 1, i32 4, i32 5>
1965; CHECK-NEXT:    [[R:%.*]] = fneg ninf <4 x float> [[TMP1]]
1966; CHECK-NEXT:    ret <4 x float> [[R]]
1967;
1968  %nx = fneg nsz ninf <4 x float> %x
1969  %ny = fneg nnan ninf <4 x float> %y
1970  %r = shufflevector <4 x float> %nx, <4 x float> %ny, <4 x i32> <i32 0, i32 1, i32 4, i32 5>
1971  ret <4 x float> %r
1972}
1973
1974; length-changing shuffle and extra use are ok
1975
1976define <4 x float> @fneg_shuf_widen_use1(<2 x float> %x, <2 x float> %y) {
1977; CHECK-LABEL: @fneg_shuf_widen_use1(
1978; CHECK-NEXT:    [[NX:%.*]] = fneg nnan <2 x float> [[X:%.*]]
1979; CHECK-NEXT:    call void @use(<2 x float> [[NX]])
1980; CHECK-NEXT:    [[TMP1:%.*]] = shufflevector <2 x float> [[X]], <2 x float> [[Y:%.*]], <4 x i32> <i32 poison, i32 1, i32 2, i32 3>
1981; CHECK-NEXT:    [[R:%.*]] = fneg nnan <4 x float> [[TMP1]]
1982; CHECK-NEXT:    ret <4 x float> [[R]]
1983;
1984  %nx = fneg nnan <2 x float> %x
1985  call void @use(<2 x float> %nx)
1986  %ny = fneg nnan <2 x float> %y
1987  %r = shufflevector <2 x float> %nx, <2 x float> %ny, <4 x i32> <i32 poison, i32 1, i32 2, i32 3>
1988  ret <4 x float> %r
1989}
1990
1991; length-changing shuffle and extra use still ok
1992
1993define <2 x float> @fneg_shuf_narrow_use2(<4 x float> %x, <4 x float> %y) {
1994; CHECK-LABEL: @fneg_shuf_narrow_use2(
1995; CHECK-NEXT:    [[NY:%.*]] = fneg nnan nsz <4 x float> [[Y:%.*]]
1996; CHECK-NEXT:    call void @use4(<4 x float> [[NY]])
1997; CHECK-NEXT:    [[TMP1:%.*]] = shufflevector <4 x float> [[X:%.*]], <4 x float> [[Y]], <2 x i32> <i32 3, i32 5>
1998; CHECK-NEXT:    [[R:%.*]] = fneg nnan nsz <2 x float> [[TMP1]]
1999; CHECK-NEXT:    ret <2 x float> [[R]]
2000;
2001  %nx = fneg nsz nnan <4 x float> %x
2002  %ny = fneg nsz nnan <4 x float> %y
2003  call void @use4(<4 x float> %ny)
2004  %r = shufflevector <4 x float> %nx, <4 x float> %ny, <2 x i32> <i32 3, i32 5>
2005  ret <2 x float> %r
2006}
2007
2008; negative test - too many extra uses
2009
2010define <2 x float> @fneg_shuf_use3(<2 x float> %x, <2 x float> %y) {
2011; CHECK-LABEL: @fneg_shuf_use3(
2012; CHECK-NEXT:    [[NX:%.*]] = fneg nnan <2 x float> [[X:%.*]]
2013; CHECK-NEXT:    call void @use(<2 x float> [[NX]])
2014; CHECK-NEXT:    [[NY:%.*]] = fneg nnan <2 x float> [[Y:%.*]]
2015; CHECK-NEXT:    call void @use(<2 x float> [[NY]])
2016; CHECK-NEXT:    [[R:%.*]] = shufflevector <2 x float> [[NX]], <2 x float> [[NY]], <2 x i32> <i32 1, i32 2>
2017; CHECK-NEXT:    ret <2 x float> [[R]]
2018;
2019  %nx = fneg nnan <2 x float> %x
2020  call void @use(<2 x float> %nx)
2021  %ny = fneg nnan <2 x float> %y
2022  call void @use(<2 x float> %ny)
2023  %r = shufflevector <2 x float> %nx, <2 x float> %ny, <2 x i32> <i32 1, i32 2>
2024  ret <2 x float> %r
2025}
2026
2027; negative test - mixed opcodes
2028
2029define <4 x float> @fabs_fneg_shuf(<4 x float> %x, <4 x float> %y) {
2030; CHECK-LABEL: @fabs_fneg_shuf(
2031; CHECK-NEXT:    [[NX:%.*]] = call <4 x float> @llvm.fabs.v4f32(<4 x float> [[X:%.*]])
2032; CHECK-NEXT:    [[NY:%.*]] = fneg nnan ninf <4 x float> [[Y:%.*]]
2033; CHECK-NEXT:    [[R:%.*]] = shufflevector <4 x float> [[NX]], <4 x float> [[NY]], <4 x i32> <i32 0, i32 1, i32 4, i32 5>
2034; CHECK-NEXT:    ret <4 x float> [[R]]
2035;
2036  %nx = call <4 x float> @llvm.fabs.v4f32(<4 x float> %x)
2037  %ny = fneg nnan ninf <4 x float> %y
2038  %r = shufflevector <4 x float> %nx, <4 x float> %ny, <4 x i32> <i32 0, i32 1, i32 4, i32 5>
2039  ret <4 x float> %r
2040}
2041
2042define <2 x i32> @fptosi_unary_shuf(<2 x float> %x) {
2043; CHECK-LABEL: @fptosi_unary_shuf(
2044; CHECK-NEXT:    [[NX:%.*]] = fptosi <2 x float> [[X:%.*]] to <2 x i32>
2045; CHECK-NEXT:    [[R:%.*]] = shufflevector <2 x i32> [[NX]], <2 x i32> poison, <2 x i32> <i32 1, i32 0>
2046; CHECK-NEXT:    ret <2 x i32> [[R]]
2047;
2048  %nx = fptosi <2 x float> %x to <2 x i32>
2049  %r = shufflevector <2 x i32> %nx, <2 x i32> poison, <2 x i32> <i32 1, i32 0>
2050  ret <2 x i32> %r
2051}
2052
2053define <2 x i64> @fptoui_unary_shuf_widen_elts(<2 x float> %x) {
2054; CHECK-LABEL: @fptoui_unary_shuf_widen_elts(
2055; CHECK-NEXT:    [[NX:%.*]] = fptoui <2 x float> [[X:%.*]] to <2 x i64>
2056; CHECK-NEXT:    [[R:%.*]] = shufflevector <2 x i64> [[NX]], <2 x i64> poison, <2 x i32> <i32 1, i32 0>
2057; CHECK-NEXT:    ret <2 x i64> [[R]]
2058;
2059  %nx = fptoui <2 x float> %x to <2 x i64>
2060  %r = shufflevector <2 x i64> %nx, <2 x i64> poison, <2 x i32> <i32 1, i32 0>
2061  ret <2 x i64> %r
2062}
2063
2064define <2 x half> @sitofp_unary_shuf_narrow_elts(<2 x i32> %x) {
2065; CHECK-LABEL: @sitofp_unary_shuf_narrow_elts(
2066; CHECK-NEXT:    [[NX:%.*]] = sitofp <2 x i32> [[X:%.*]] to <2 x half>
2067; CHECK-NEXT:    [[R:%.*]] = shufflevector <2 x half> [[NX]], <2 x half> poison, <2 x i32> <i32 1, i32 0>
2068; CHECK-NEXT:    ret <2 x half> [[R]]
2069;
2070  %nx = sitofp <2 x i32> %x to <2 x half>
2071  %r = shufflevector <2 x half> %nx, <2 x half> poison, <2 x i32> <i32 1, i32 0>
2072  ret <2 x half> %r
2073}
2074
2075define <2 x float> @uitofp_unary_shuf(<2 x i32> %x) {
2076; CHECK-LABEL: @uitofp_unary_shuf(
2077; CHECK-NEXT:    [[NX:%.*]] = uitofp <2 x i32> [[X:%.*]] to <2 x float>
2078; CHECK-NEXT:    [[R:%.*]] = shufflevector <2 x float> [[NX]], <2 x float> poison, <2 x i32> <i32 1, i32 0>
2079; CHECK-NEXT:    ret <2 x float> [[R]]
2080;
2081  %nx = uitofp <2 x i32> %x to <2 x float>
2082  %r = shufflevector <2 x float> %nx, <2 x float> poison, <2 x i32> <i32 1, i32 0>
2083  ret <2 x float> %r
2084}
2085
2086define <4 x i16> @fptosi_unary_shuf_widen(<2 x half> %x) {
2087; CHECK-LABEL: @fptosi_unary_shuf_widen(
2088; CHECK-NEXT:    [[NX:%.*]] = fptosi <2 x half> [[X:%.*]] to <2 x i16>
2089; CHECK-NEXT:    [[R:%.*]] = shufflevector <2 x i16> [[NX]], <2 x i16> poison, <4 x i32> <i32 1, i32 0, i32 0, i32 poison>
2090; CHECK-NEXT:    ret <4 x i16> [[R]]
2091;
2092  %nx = fptosi <2 x half> %x to <2 x i16>
2093  %r = shufflevector <2 x i16> %nx, <2 x i16> poison, <4 x i32> <i32 1, i32 0, i32 0, i32 poison>
2094  ret <4 x i16> %r
2095}
2096
2097define <4 x i32> @fptoui_unary_shuf_widen_widen_elts(<2 x half> %x) {
2098; CHECK-LABEL: @fptoui_unary_shuf_widen_widen_elts(
2099; CHECK-NEXT:    [[NX:%.*]] = fptoui <2 x half> [[X:%.*]] to <2 x i32>
2100; CHECK-NEXT:    [[R:%.*]] = shufflevector <2 x i32> [[NX]], <2 x i32> poison, <4 x i32> <i32 1, i32 0, i32 0, i32 poison>
2101; CHECK-NEXT:    ret <4 x i32> [[R]]
2102;
2103  %nx = fptoui <2 x half> %x to <2 x i32>
2104  %r = shufflevector <2 x i32> %nx, <2 x i32> poison, <4 x i32> <i32 1, i32 0, i32 0, i32 poison>
2105  ret <4 x i32> %r
2106}
2107
2108define <4 x half> @sitofp_unary_shuf_widen_narrow_elts(<2 x i32> %x) {
2109; CHECK-LABEL: @sitofp_unary_shuf_widen_narrow_elts(
2110; CHECK-NEXT:    [[NX:%.*]] = sitofp <2 x i32> [[X:%.*]] to <2 x half>
2111; CHECK-NEXT:    [[R:%.*]] = shufflevector <2 x half> [[NX]], <2 x half> poison, <4 x i32> <i32 1, i32 0, i32 0, i32 poison>
2112; CHECK-NEXT:    ret <4 x half> [[R]]
2113;
2114  %nx = sitofp <2 x i32> %x to <2 x half>
2115  %r = shufflevector <2 x half> %nx, <2 x half> poison, <4 x i32> <i32 1, i32 0, i32 0, i32 poison>
2116  ret <4 x half> %r
2117}
2118
2119define <4 x half> @uitofp_unary_shuf_widen(<2 x i16> %x) {
2120; CHECK-LABEL: @uitofp_unary_shuf_widen(
2121; CHECK-NEXT:    [[NX:%.*]] = uitofp <2 x i16> [[X:%.*]] to <2 x half>
2122; CHECK-NEXT:    [[R:%.*]] = shufflevector <2 x half> [[NX]], <2 x half> poison, <4 x i32> <i32 1, i32 0, i32 0, i32 poison>
2123; CHECK-NEXT:    ret <4 x half> [[R]]
2124;
2125  %nx = uitofp <2 x i16> %x to <2 x half>
2126  %r = shufflevector <2 x half> %nx, <2 x half> poison, <4 x i32> <i32 1, i32 0, i32 0, i32 poison>
2127  ret <4 x half> %r
2128}
2129
2130define <2 x i16> @fptosi_unary_shuf_narrow(<4 x half> %x) {
2131; CHECK-LABEL: @fptosi_unary_shuf_narrow(
2132; CHECK-NEXT:    [[NX:%.*]] = fptosi <4 x half> [[X:%.*]] to <4 x i16>
2133; CHECK-NEXT:    [[R:%.*]] = shufflevector <4 x i16> [[NX]], <4 x i16> poison, <2 x i32> <i32 1, i32 0>
2134; CHECK-NEXT:    ret <2 x i16> [[R]]
2135;
2136  %nx = fptosi <4 x half> %x to <4 x i16>
2137  %r = shufflevector <4 x i16> %nx, <4 x i16> poison, <2 x i32> <i32 1, i32 0>
2138  ret <2 x i16> %r
2139}
2140
2141define <2 x i32> @fptoui_unary_shuf_narrow_widen_elts(<4 x half> %x) {
2142; CHECK-LABEL: @fptoui_unary_shuf_narrow_widen_elts(
2143; CHECK-NEXT:    [[NX:%.*]] = fptoui <4 x half> [[X:%.*]] to <4 x i32>
2144; CHECK-NEXT:    [[R:%.*]] = shufflevector <4 x i32> [[NX]], <4 x i32> poison, <2 x i32> <i32 3, i32 0>
2145; CHECK-NEXT:    ret <2 x i32> [[R]]
2146;
2147  %nx = fptoui <4 x half> %x to <4 x i32>
2148  %r = shufflevector <4 x i32> %nx, <4 x i32> poison, <2 x i32> <i32 3, i32 0>
2149  ret <2 x i32> %r
2150}
2151
2152define <2 x double> @sitofp_unary_shuf_narrow(<4 x i64> %x) {
2153; CHECK-LABEL: @sitofp_unary_shuf_narrow(
2154; CHECK-NEXT:    [[NX:%.*]] = sitofp <4 x i64> [[X:%.*]] to <4 x double>
2155; CHECK-NEXT:    [[R:%.*]] = shufflevector <4 x double> [[NX]], <4 x double> poison, <2 x i32> <i32 2, i32 1>
2156; CHECK-NEXT:    ret <2 x double> [[R]]
2157;
2158  %nx = sitofp <4 x i64> %x to <4 x double>
2159  %r = shufflevector <4 x double> %nx, <4 x double> poison, <2 x i32> <i32 2, i32 1>
2160  ret <2 x double> %r
2161}
2162
2163define <2 x half> @uitofp_unary_shuf_narrow_narrow_elts(<4 x i32> %x) {
2164; CHECK-LABEL: @uitofp_unary_shuf_narrow_narrow_elts(
2165; CHECK-NEXT:    [[NX:%.*]] = uitofp <4 x i32> [[X:%.*]] to <4 x half>
2166; CHECK-NEXT:    [[R:%.*]] = shufflevector <4 x half> [[NX]], <4 x half> poison, <2 x i32> <i32 3, i32 1>
2167; CHECK-NEXT:    ret <2 x half> [[R]]
2168;
2169  %nx = uitofp <4 x i32> %x to <4 x half>
2170  %r = shufflevector <4 x half> %nx, <4 x half> poison, <2 x i32> <i32 3, i32 1>
2171  ret <2 x half> %r
2172}
2173
2174define <4 x i32> @fptosi_shuf(<4 x float> %x, <4 x float> %y) {
2175; CHECK-LABEL: @fptosi_shuf(
2176; CHECK-NEXT:    [[TMP1:%.*]] = shufflevector <4 x float> [[X:%.*]], <4 x float> [[Y:%.*]], <4 x i32> <i32 0, i32 1, i32 4, i32 5>
2177; CHECK-NEXT:    [[R:%.*]] = fptosi <4 x float> [[TMP1]] to <4 x i32>
2178; CHECK-NEXT:    ret <4 x i32> [[R]]
2179;
2180  %nx = fptosi <4 x float> %x to <4 x i32>
2181  %ny = fptosi <4 x float> %y to <4 x i32>
2182  %r = shufflevector <4 x i32> %nx, <4 x i32> %ny, <4 x i32> <i32 0, i32 1, i32 4, i32 5>
2183  ret <4 x i32> %r
2184}
2185
2186define <3 x i16> @fptoui_shuf(<3 x half> %x, <3 x half> %y) {
2187; CHECK-LABEL: @fptoui_shuf(
2188; CHECK-NEXT:    [[TMP1:%.*]] = shufflevector <3 x half> [[X:%.*]], <3 x half> [[Y:%.*]], <3 x i32> <i32 0, i32 poison, i32 4>
2189; CHECK-NEXT:    [[R:%.*]] = fptoui <3 x half> [[TMP1]] to <3 x i16>
2190; CHECK-NEXT:    ret <3 x i16> [[R]]
2191;
2192  %nx = fptoui <3 x half> %x to <3 x i16>
2193  %ny = fptoui <3 x half> %y to <3 x i16>
2194  %r = shufflevector <3 x i16> %nx, <3 x i16> %ny, <3 x i32> <i32 0, i32 poison, i32 4>
2195  ret <3 x i16> %r
2196}
2197
2198; negative test - must have same source types
2199
2200define <3 x i16> @fptoui_shuf_different_source_types(<3 x float> %x, <3 x half> %y) {
2201; CHECK-LABEL: @fptoui_shuf_different_source_types(
2202; CHECK-NEXT:    [[NX:%.*]] = fptoui <3 x float> [[X:%.*]] to <3 x i16>
2203; CHECK-NEXT:    [[NY:%.*]] = fptoui <3 x half> [[Y:%.*]] to <3 x i16>
2204; CHECK-NEXT:    [[R:%.*]] = shufflevector <3 x i16> [[NX]], <3 x i16> [[NY]], <3 x i32> <i32 0, i32 2, i32 4>
2205; CHECK-NEXT:    ret <3 x i16> [[R]]
2206;
2207  %nx = fptoui <3 x float> %x to <3 x i16>
2208  %ny = fptoui <3 x half> %y to <3 x i16>
2209  %r = shufflevector <3 x i16> %nx, <3 x i16> %ny, <3 x i32> <i32 0, i32 2, i32 4>
2210  ret <3 x i16> %r
2211}
2212
2213define <4 x i32> @fptoui_shuf_widen_elts(<4 x half> %x, <4 x half> %y) {
2214; CHECK-LABEL: @fptoui_shuf_widen_elts(
2215; CHECK-NEXT:    [[TMP1:%.*]] = shufflevector <4 x half> [[X:%.*]], <4 x half> [[Y:%.*]], <4 x i32> <i32 0, i32 1, i32 4, i32 5>
2216; CHECK-NEXT:    [[R:%.*]] = fptosi <4 x half> [[TMP1]] to <4 x i32>
2217; CHECK-NEXT:    ret <4 x i32> [[R]]
2218;
2219  %nx = fptosi <4 x half> %x to <4 x i32>
2220  %ny = fptosi <4 x half> %y to <4 x i32>
2221  %r = shufflevector <4 x i32> %nx, <4 x i32> %ny, <4 x i32> <i32 0, i32 1, i32 4, i32 5>
2222  ret <4 x i32> %r
2223}
2224
2225; negative test - must have same or smaller size source elements
2226
2227define <4 x float> @sitofp_shuf_narrow_elts(<4 x i64> %x, <4 x i64> %y) {
2228; CHECK-LABEL: @sitofp_shuf_narrow_elts(
2229; CHECK-NEXT:    [[NX:%.*]] = sitofp <4 x i64> [[X:%.*]] to <4 x float>
2230; CHECK-NEXT:    [[NY:%.*]] = sitofp <4 x i64> [[Y:%.*]] to <4 x float>
2231; CHECK-NEXT:    [[R:%.*]] = shufflevector <4 x float> [[NX]], <4 x float> [[NY]], <4 x i32> <i32 0, i32 1, i32 4, i32 5>
2232; CHECK-NEXT:    ret <4 x float> [[R]]
2233;
2234  %nx = sitofp <4 x i64> %x to <4 x float>
2235  %ny = sitofp <4 x i64> %y to <4 x float>
2236  %r = shufflevector <4 x float> %nx, <4 x float> %ny, <4 x i32> <i32 0, i32 1, i32 4, i32 5>
2237  ret <4 x float> %r
2238}
2239
2240; one extra use is ok
2241
2242define <4 x float> @uitofp_shuf_extra_use1(<4 x i32> %x, <4 x i32> %y) {
2243; CHECK-LABEL: @uitofp_shuf_extra_use1(
2244; CHECK-NEXT:    [[NX:%.*]] = uitofp <4 x i32> [[X:%.*]] to <4 x float>
2245; CHECK-NEXT:    call void @use4(<4 x float> [[NX]])
2246; CHECK-NEXT:    [[TMP1:%.*]] = shufflevector <4 x i32> [[X]], <4 x i32> [[Y:%.*]], <4 x i32> <i32 0, i32 0, i32 4, i32 5>
2247; CHECK-NEXT:    [[R:%.*]] = uitofp <4 x i32> [[TMP1]] to <4 x float>
2248; CHECK-NEXT:    ret <4 x float> [[R]]
2249;
2250  %nx = uitofp <4 x i32> %x to <4 x float>
2251  call void @use4(<4 x float> %nx)
2252  %ny = uitofp <4 x i32> %y to <4 x float>
2253  %r = shufflevector <4 x float> %nx, <4 x float> %ny, <4 x i32> <i32 0, i32 0, i32 4, i32 5>
2254  ret <4 x float> %r
2255}
2256
2257; one extra use is ok
2258
2259define <4 x float> @sitofp_shuf_extra_use2(<4 x i32> %x, <4 x i32> %y) {
2260; CHECK-LABEL: @sitofp_shuf_extra_use2(
2261; CHECK-NEXT:    [[NY:%.*]] = sitofp <4 x i32> [[Y:%.*]] to <4 x float>
2262; CHECK-NEXT:    call void @use4(<4 x float> [[NY]])
2263; CHECK-NEXT:    [[TMP1:%.*]] = shufflevector <4 x i32> [[X:%.*]], <4 x i32> [[Y]], <4 x i32> <i32 7, i32 1, i32 4, i32 0>
2264; CHECK-NEXT:    [[R:%.*]] = sitofp <4 x i32> [[TMP1]] to <4 x float>
2265; CHECK-NEXT:    ret <4 x float> [[R]]
2266;
2267  %nx = sitofp <4 x i32> %x to <4 x float>
2268  %ny = sitofp <4 x i32> %y to <4 x float>
2269  call void @use4(<4 x float> %ny)
2270  %r = shufflevector <4 x float> %nx, <4 x float> %ny, <4 x i32> <i32 7, i32 1, i32 4, i32 0>
2271  ret <4 x float> %r
2272}
2273
2274; negative test - both ops have extra uses
2275
2276define <2 x float> @sitofp_shuf_extra_use3(<2 x i32> %x, <2 x i32> %y) {
2277; CHECK-LABEL: @sitofp_shuf_extra_use3(
2278; CHECK-NEXT:    [[NX:%.*]] = sitofp <2 x i32> [[X:%.*]] to <2 x float>
2279; CHECK-NEXT:    call void @use(<2 x float> [[NX]])
2280; CHECK-NEXT:    [[NY:%.*]] = sitofp <2 x i32> [[Y:%.*]] to <2 x float>
2281; CHECK-NEXT:    call void @use(<2 x float> [[NY]])
2282; CHECK-NEXT:    [[R:%.*]] = shufflevector <2 x float> [[NX]], <2 x float> [[NY]], <2 x i32> <i32 3, i32 1>
2283; CHECK-NEXT:    ret <2 x float> [[R]]
2284;
2285  %nx = sitofp <2 x i32> %x to <2 x float>
2286  call void @use(<2 x float> %nx)
2287  %ny = sitofp <2 x i32> %y to <2 x float>
2288  call void @use(<2 x float> %ny)
2289  %r = shufflevector <2 x float> %nx, <2 x float> %ny, <2 x i32> <i32 3, i32 1>
2290  ret <2 x float> %r
2291}
2292
2293; negative test - mismatched casts
2294
2295define <4 x i32> @fptoi_shuf(<4 x float> %x, <4 x float> %y) {
2296; CHECK-LABEL: @fptoi_shuf(
2297; CHECK-NEXT:    [[NX:%.*]] = fptoui <4 x float> [[X:%.*]] to <4 x i32>
2298; CHECK-NEXT:    [[NY:%.*]] = fptosi <4 x float> [[Y:%.*]] to <4 x i32>
2299; CHECK-NEXT:    [[R:%.*]] = shufflevector <4 x i32> [[NX]], <4 x i32> [[NY]], <4 x i32> <i32 0, i32 1, i32 4, i32 5>
2300; CHECK-NEXT:    ret <4 x i32> [[R]]
2301;
2302  %nx = fptoui <4 x float> %x to <4 x i32>
2303  %ny = fptosi <4 x float> %y to <4 x i32>
2304  %r = shufflevector <4 x i32> %nx, <4 x i32> %ny, <4 x i32> <i32 0, i32 1, i32 4, i32 5>
2305  ret <4 x i32> %r
2306}
2307
2308; negative test - length-increasing shuffle
2309
2310define <4 x float> @sitofp_shuf_widen(<2 x i32> %x, <2 x i32> %y) {
2311; CHECK-LABEL: @sitofp_shuf_widen(
2312; CHECK-NEXT:    [[NX:%.*]] = sitofp <2 x i32> [[X:%.*]] to <2 x float>
2313; CHECK-NEXT:    [[NY:%.*]] = sitofp <2 x i32> [[Y:%.*]] to <2 x float>
2314; CHECK-NEXT:    [[R:%.*]] = shufflevector <2 x float> [[NX]], <2 x float> [[NY]], <4 x i32> <i32 poison, i32 1, i32 2, i32 3>
2315; CHECK-NEXT:    ret <4 x float> [[R]]
2316;
2317  %nx = sitofp <2 x i32> %x to <2 x float>
2318  %ny = sitofp <2 x i32> %y to <2 x float>
2319  %r = shufflevector <2 x float> %nx, <2 x float> %ny, <4 x i32> <i32 poison, i32 1, i32 2, i32 3>
2320  ret <4 x float> %r
2321}
2322
2323define <2 x float> @uitofp_shuf_narrow(<4 x i32> %x, <4 x i32> %y) {
2324; CHECK-LABEL: @uitofp_shuf_narrow(
2325; CHECK-NEXT:    [[TMP1:%.*]] = shufflevector <4 x i32> [[X:%.*]], <4 x i32> [[Y:%.*]], <2 x i32> <i32 3, i32 5>
2326; CHECK-NEXT:    [[R:%.*]] = uitofp <2 x i32> [[TMP1]] to <2 x float>
2327; CHECK-NEXT:    ret <2 x float> [[R]]
2328;
2329  %nx = uitofp <4 x i32> %x to <4 x float>
2330  %ny = uitofp <4 x i32> %y to <4 x float>
2331  %r = shufflevector <4 x float> %nx, <4 x float> %ny, <2 x i32> <i32 3, i32 5>
2332  ret <2 x float> %r
2333}
2334
2335define <4 x i16> @blend_elements_from_load(ptr align 8 %_0) {
2336; CHECK-LABEL: @blend_elements_from_load(
2337; CHECK-NEXT:    [[LOAD:%.*]] = load <3 x i16>, ptr [[_0:%.*]], align 8
2338; CHECK-NEXT:    [[RV:%.*]] = shufflevector <3 x i16> <i16 0, i16 undef, i16 poison>, <3 x i16> [[LOAD]], <4 x i32> <i32 0, i32 1, i32 3, i32 5>
2339; CHECK-NEXT:    ret <4 x i16> [[RV]]
2340;
2341  %load = load <3 x i16>, ptr %_0, align 8
2342  %rv = shufflevector <3 x i16> <i16 0, i16 undef, i16 undef>, <3 x i16> %load, <4 x i32> <i32 0, i32 1, i32 3, i32 5>
2343  ret <4 x i16> %rv
2344}
2345
2346define i16 @pr92887(<2 x i16> %v) {
2347; CHECK-LABEL: @pr92887(
2348; CHECK-NEXT:    ret i16 undef
2349;
2350  %v0 = extractelement <2 x i16> %v, i64 0
2351  %v0lo = and i16 %v0, 1
2352  %v1 = extractelement <2 x i16> %v, i64 1
2353  %v1lo = and i16 %v1, 1
2354  %ins1 = insertelement <4 x i16> poison, i16 %v0lo, i64 0
2355  %ins2 = insertelement <4 x i16> %ins1, i16 %v1lo, i64 1
2356  %shuf = shufflevector <4 x i16> %ins2, <4 x i16> <i16 poison, i16 poison, i16 undef, i16 undef>, <4 x i32> <i32 0, i32 1, i32 6, i32 7>
2357  %extract = extractelement <4 x i16> %shuf, i32 2
2358  ret i16 %extract
2359}
2360
2361define <2 x i32> @not_splat_shuffle1(i32 %x) {
2362; CHECK-LABEL: @not_splat_shuffle1(
2363; CHECK-NEXT:    [[SHUF:%.*]] = insertelement <2 x i32> <i32 poison, i32 undef>, i32 [[X:%.*]], i64 0
2364; CHECK-NEXT:    ret <2 x i32> [[SHUF]]
2365;
2366  %vec = insertelement <2 x i32> undef, i32 %x, i32 1
2367  %shuf = shufflevector <2 x i32> %vec, <2 x i32> poison, <2 x i32> <i32 1, i32 0>
2368  ret <2 x i32> %shuf
2369}
2370
2371define <2 x i32> @not_splat_shuffle2(i32 %x) {
2372; CHECK-LABEL: @not_splat_shuffle2(
2373; CHECK-NEXT:    [[SHUF:%.*]] = insertelement <2 x i32> <i32 poison, i32 undef>, i32 [[X:%.*]], i64 0
2374; CHECK-NEXT:    ret <2 x i32> [[SHUF]]
2375;
2376  %vec = insertelement <2 x i32> poison, i32 %x, i32 1
2377  %shuf = shufflevector <2 x i32> %vec, <2 x i32> undef, <2 x i32> <i32 1, i32 3>
2378  ret <2 x i32> %shuf
2379}
2380define <2 x i32> @foldselect0(i1 %c) {
2381; CHECK-LABEL: @foldselect0(
2382; CHECK-NEXT:    [[SHUF:%.*]] = select i1 [[C:%.*]], <2 x i32> <i32 7, i32 42>, <2 x i32> <i32 1, i32 0>
2383; CHECK-NEXT:    ret <2 x i32> [[SHUF]]
2384;
2385  %sel = select i1 %c, <2 x i32> <i32 42, i32 7>, <2 x i32> <i32 0, i32 1>
2386  %shuf = shufflevector <2 x i32> %sel, <2 x i32> poison, <2 x i32> <i32 1, i32 0>
2387  ret <2 x i32> %shuf
2388}
2389
2390; Make sure we do not crash in this case.
2391define <4 x float> @shuf_larger_length_vec_select(<2 x i1> %cond) {
2392; CHECK-LABEL: @shuf_larger_length_vec_select(
2393; CHECK-NEXT:    [[SEL:%.*]] = select <2 x i1> [[COND:%.*]], <2 x float> zeroinitializer, <2 x float> splat (float 1.000000e+00)
2394; CHECK-NEXT:    [[SHUF:%.*]] = shufflevector <2 x float> [[SEL]], <2 x float> zeroinitializer, <4 x i32> <i32 0, i32 1, i32 2, i32 3>
2395; CHECK-NEXT:    ret <4 x float> [[SHUF]]
2396;
2397  %sel = select <2 x i1> %cond, <2 x float> zeroinitializer, <2 x float> splat(float 1.000000e+00)
2398  %shuf = shufflevector <2 x float> %sel, <2 x float> zeroinitializer, <4 x i32> <i32 0, i32 1, i32 2, i32 3>
2399  ret <4 x float> %shuf
2400}
2401
2402; Make sure we do not fold in this case.
2403define <4 x i32> @shuf_same_length_vec_select(<4 x i1> %cond) {
2404; CHECK-LABEL: @shuf_same_length_vec_select(
2405; CHECK-NEXT:    [[SEL:%.*]] = select <4 x i1> [[COND:%.*]], <4 x i32> <i32 poison, i32 1, i32 2, i32 3>, <4 x i32> <i32 poison, i32 5, i32 6, i32 7>
2406; CHECK-NEXT:    [[SHUF:%.*]] = shufflevector <4 x i32> [[SEL]], <4 x i32> <i32 poison, i32 9, i32 poison, i32 poison>, <4 x i32> <i32 2, i32 1, i32 3, i32 5>
2407; CHECK-NEXT:    ret <4 x i32> [[SHUF]]
2408;
2409  %sel = select <4 x i1> %cond, <4 x i32> <i32 0, i32 1, i32 2, i32 3>, <4 x i32> <i32 4, i32 5, i32 6, i32 7>
2410  %shuf = shufflevector <4 x i32> %sel, <4 x i32> <i32 8, i32 9, i32 10, i32 11>, <4 x i32> <i32 2, i32 1, i32 3, i32 5>
2411  ret <4 x i32> %shuf
2412}
2413
2414; Make sure we do not fold in this case.
2415define <4 x i8> @shuf_cmp_may_be_poison(<4 x i8> %x, <4 x i8> %y, i1 %cmp) {
2416; CHECK-LABEL: @shuf_cmp_may_be_poison(
2417; CHECK-NEXT:    [[Y:%.*]] = select i1 [[CMP:%.*]], <4 x i8> [[Y1:%.*]], <4 x i8> <i8 0, i8 poison, i8 0, i8 poison>
2418; CHECK-NEXT:    [[TMP1:%.*]] = shufflevector <4 x i8> [[Y]], <4 x i8> <i8 poison, i8 1, i8 poison, i8 3>, <4 x i32> <i32 0, i32 5, i32 2, i32 7>
2419; CHECK-NEXT:    ret <4 x i8> [[TMP1]]
2420;
2421  %sel = select i1 %cmp, <4 x i8> %y, <4 x i8> <i8 0, i8 poison, i8 0, i8 poison>
2422  %shuf = shufflevector <4 x i8> %sel, <4 x i8> <i8 poison, i8 1, i8 poison, i8 3>, <4 x i32> <i32 0, i32 5, i32 2, i32 7>
2423  ret <4 x i8> %shuf
2424}
2425
2426declare i1 @cond()
2427declare <4 x i32> @value()
2428
2429define <4 x i32> @foldphi1() {
2430; CHECK-LABEL: @foldphi1(
2431; CHECK-NEXT:  entry:
2432; CHECK-NEXT:    br label [[LOOP:%.*]]
2433; CHECK:       loop:
2434; CHECK-NEXT:    [[V:%.*]] = phi <4 x i32> [ zeroinitializer, [[ENTRY:%.*]] ], [ [[XOR:%.*]], [[LOOP]] ]
2435; CHECK-NEXT:    [[VAL:%.*]] = call <4 x i32> @value()
2436; CHECK-NEXT:    [[XOR]] = xor <4 x i32> [[V]], [[VAL]]
2437; CHECK-NEXT:    [[C:%.*]] = call i1 @cond()
2438; CHECK-NEXT:    br i1 [[C]], label [[LOOP]], label [[EXIT:%.*]]
2439; CHECK:       exit:
2440; CHECK-NEXT:    [[SHUF1:%.*]] = shufflevector <4 x i32> [[XOR]], <4 x i32> poison, <4 x i32> <i32 3, i32 0, i32 1, i32 2>
2441; CHECK-NEXT:    ret <4 x i32> [[SHUF1]]
2442;
2443entry:
2444  br label %loop
2445
2446loop:
2447  %v = phi <4 x i32> [zeroinitializer, %entry], [%shuf1, %loop]
2448
2449  %shuf0 = shufflevector <4 x i32> %v, <4 x i32> poison, <4 x i32> <i32 1, i32 2, i32 3, i32 0>
2450  %val = call <4 x i32> @value()
2451  %xor = xor <4 x i32> %shuf0, %val
2452  %shuf1 = shufflevector <4 x i32> %xor, <4 x i32> poison, <4 x i32> <i32 3, i32 0, i32 1, i32 2>
2453
2454  %c = call i1 @cond()
2455  br i1 %c, label %loop, label %exit
2456
2457exit:
2458  ret <4 x i32> %shuf1
2459}
2460