xref: /llvm-project/llvm/test/Transforms/InstCombine/insert-extract-shuffle-inseltpoison.ll (revision 38fffa630ee80163dc65e759392ad29798905679)
1; NOTE: Assertions have been autogenerated by utils/update_test_checks.py
2; RUN: opt -S -passes=instcombine %s | FileCheck %s
3
4define <1 x i8> @test1(<8 x i8> %in) {
5; CHECK-LABEL: @test1(
6; CHECK-NEXT:    [[VEC:%.*]] = shufflevector <8 x i8> [[IN:%.*]], <8 x i8> poison, <1 x i32> <i32 5>
7; CHECK-NEXT:    ret <1 x i8> [[VEC]]
8;
9  %val = extractelement <8 x i8> %in, i32 5
10  %vec = insertelement <1 x i8> poison, i8 %val, i32 0
11  ret <1 x i8> %vec
12}
13
14define <4 x i16> @test2(<8 x i16> %in, <8 x i16> %in2) {
15; CHECK-LABEL: @test2(
16; CHECK-NEXT:    [[VEC_3:%.*]] = shufflevector <8 x i16> [[IN2:%.*]], <8 x i16> [[IN:%.*]], <4 x i32> <i32 11, i32 9, i32 0, i32 10>
17; CHECK-NEXT:    ret <4 x i16> [[VEC_3]]
18;
19  %elt0 = extractelement <8 x i16> %in, i32 3
20  %elt1 = extractelement <8 x i16> %in, i32 1
21  %elt2 = extractelement <8 x i16> %in2, i32 0
22  %elt3 = extractelement <8 x i16> %in, i32 2
23
24  %vec.0 = insertelement <4 x i16> poison, i16 %elt0, i32 0
25  %vec.1 = insertelement <4 x i16> %vec.0, i16 %elt1, i32 1
26  %vec.2 = insertelement <4 x i16> %vec.1, i16 %elt2, i32 2
27  %vec.3 = insertelement <4 x i16> %vec.2, i16 %elt3, i32 3
28
29  ret <4 x i16> %vec.3
30}
31
32define <2 x i64> @test_vcopyq_lane_p64(<2 x i64> %a, <1 x i64> %b) {
33; CHECK-LABEL: @test_vcopyq_lane_p64(
34; CHECK-NEXT:    [[TMP1:%.*]] = shufflevector <1 x i64> [[B:%.*]], <1 x i64> poison, <2 x i32> <i32 0, i32 poison>
35; CHECK-NEXT:    [[RES:%.*]] = shufflevector <2 x i64> [[A:%.*]], <2 x i64> [[TMP1]], <2 x i32> <i32 0, i32 2>
36; CHECK-NEXT:    ret <2 x i64> [[RES]]
37;
38  %elt = extractelement <1 x i64> %b, i32 0
39  %res = insertelement <2 x i64> %a, i64 %elt, i32 1
40  ret <2 x i64> %res
41}
42
43; PR2109: https://llvm.org/bugs/show_bug.cgi?id=2109
44
45define <4 x float> @widen_extract2(<4 x float> %ins, <2 x float> %ext) {
46; CHECK-LABEL: @widen_extract2(
47; CHECK-NEXT:    [[TMP1:%.*]] = shufflevector <2 x float> [[EXT:%.*]], <2 x float> poison, <4 x i32> <i32 0, i32 1, i32 poison, i32 poison>
48; CHECK-NEXT:    [[I2:%.*]] = shufflevector <4 x float> [[INS:%.*]], <4 x float> [[TMP1]], <4 x i32> <i32 0, i32 4, i32 2, i32 5>
49; CHECK-NEXT:    ret <4 x float> [[I2]]
50;
51  %e1 = extractelement <2 x float> %ext, i32 0
52  %e2 = extractelement <2 x float> %ext, i32 1
53  %i1 = insertelement <4 x float> %ins, float %e1, i32 1
54  %i2 = insertelement <4 x float> %i1, float %e2, i32 3
55  ret <4 x float> %i2
56}
57
58define <4 x float> @widen_extract3(<4 x float> %ins, <3 x float> %ext) {
59; CHECK-LABEL: @widen_extract3(
60; CHECK-NEXT:    [[TMP1:%.*]] = shufflevector <3 x float> [[EXT:%.*]], <3 x float> poison, <4 x i32> <i32 0, i32 1, i32 2, i32 poison>
61; CHECK-NEXT:    [[I3:%.*]] = shufflevector <4 x float> [[INS:%.*]], <4 x float> [[TMP1]], <4 x i32> <i32 6, i32 5, i32 4, i32 3>
62; CHECK-NEXT:    ret <4 x float> [[I3]]
63;
64  %e1 = extractelement <3 x float> %ext, i32 0
65  %e2 = extractelement <3 x float> %ext, i32 1
66  %e3 = extractelement <3 x float> %ext, i32 2
67  %i1 = insertelement <4 x float> %ins, float %e1, i32 2
68  %i2 = insertelement <4 x float> %i1, float %e2, i32 1
69  %i3 = insertelement <4 x float> %i2, float %e3, i32 0
70  ret <4 x float> %i3
71}
72
73define <8 x float> @widen_extract4(<8 x float> %ins, <2 x float> %ext) {
74; CHECK-LABEL: @widen_extract4(
75; CHECK-NEXT:    [[TMP1:%.*]] = shufflevector <2 x float> [[EXT:%.*]], <2 x float> poison, <8 x i32> <i32 0, i32 poison, i32 poison, i32 poison, i32 poison, i32 poison, i32 poison, i32 poison>
76; CHECK-NEXT:    [[I1:%.*]] = shufflevector <8 x float> [[INS:%.*]], <8 x float> [[TMP1]], <8 x i32> <i32 0, i32 1, i32 8, i32 3, i32 4, i32 5, i32 6, i32 7>
77; CHECK-NEXT:    ret <8 x float> [[I1]]
78;
79  %e1 = extractelement <2 x float> %ext, i32 0
80  %i1 = insertelement <8 x float> %ins, float %e1, i32 2
81  ret <8 x float> %i1
82}
83
84; PR26015: https://llvm.org/bugs/show_bug.cgi?id=26015
85; The widening shuffle must be inserted before any uses.
86
87define <8 x i16> @pr26015(<4 x i16> %t0) {
88; CHECK-LABEL: @pr26015(
89; CHECK-NEXT:    [[TMP1:%.*]] = shufflevector <4 x i16> [[T0:%.*]], <4 x i16> poison, <8 x i32> <i32 poison, i32 poison, i32 2, i32 3, i32 poison, i32 poison, i32 poison, i32 poison>
90; CHECK-NEXT:    [[T5:%.*]] = shufflevector <8 x i16> <i16 0, i16 0, i16 0, i16 poison, i16 0, i16 0, i16 0, i16 poison>, <8 x i16> [[TMP1]], <8 x i32> <i32 0, i32 1, i32 2, i32 10, i32 4, i32 5, i32 6, i32 11>
91; CHECK-NEXT:    ret <8 x i16> [[T5]]
92;
93  %t1 = extractelement <4 x i16> %t0, i32 2
94  %t2 = insertelement <8 x i16> zeroinitializer, i16 %t1, i32 3
95  %t3 = insertelement <8 x i16> %t2, i16 0, i32 6
96  %t4 = extractelement <4 x i16> %t0, i32 3
97  %t5 = insertelement <8 x i16> %t3, i16 %t4, i32 7
98  ret <8 x i16> %t5
99}
100
101; PR25999: https://llvm.org/bugs/show_bug.cgi?id=25999
102; TODO: The widening shuffle could be inserted at the start of the function to allow the first extract to use it.
103
104define <8 x i16> @pr25999(<4 x i16> %t0, i1 %b) {
105; CHECK-LABEL: @pr25999(
106; CHECK-NEXT:    [[T1:%.*]] = extractelement <4 x i16> [[T0:%.*]], i64 2
107; CHECK-NEXT:    br i1 [[B:%.*]], label [[IF:%.*]], label [[END:%.*]]
108; CHECK:       if:
109; CHECK-NEXT:    [[TMP1:%.*]] = shufflevector <4 x i16> [[T0]], <4 x i16> poison, <8 x i32> <i32 poison, i32 poison, i32 poison, i32 3, i32 poison, i32 poison, i32 poison, i32 poison>
110; CHECK-NEXT:    [[T3:%.*]] = insertelement <8 x i16> <i16 0, i16 0, i16 0, i16 poison, i16 0, i16 0, i16 0, i16 poison>, i16 [[T1]], i64 3
111; CHECK-NEXT:    [[T5:%.*]] = shufflevector <8 x i16> [[T3]], <8 x i16> [[TMP1]], <8 x i32> <i32 0, i32 1, i32 2, i32 3, i32 4, i32 5, i32 6, i32 11>
112; CHECK-NEXT:    ret <8 x i16> [[T5]]
113; CHECK:       end:
114; CHECK-NEXT:    [[A1:%.*]] = add i16 [[T1]], 4
115; CHECK-NEXT:    [[T6:%.*]] = insertelement <8 x i16> <i16 poison, i16 0, i16 0, i16 0, i16 0, i16 0, i16 0, i16 0>, i16 [[A1]], i64 0
116; CHECK-NEXT:    ret <8 x i16> [[T6]]
117;
118
119  %t1 = extractelement <4 x i16> %t0, i32 2
120  br i1 %b, label %if, label %end
121
122if:
123  %t2 = insertelement <8 x i16> zeroinitializer, i16 %t1, i32 3
124  %t3 = insertelement <8 x i16> %t2, i16 0, i32 6
125  %t4 = extractelement <4 x i16> %t0, i32 3
126  %t5 = insertelement <8 x i16> %t3, i16 %t4, i32 7
127  ret <8 x i16> %t5
128
129end:
130  %a1 = add i16 %t1, 4
131  %t6 = insertelement <8 x i16> zeroinitializer, i16 %a1, i32 0
132  ret <8 x i16> %t6
133}
134
135; The widening shuffle must be inserted at a valid point (after the PHIs).
136
137define <4 x double> @pr25999_phis1(i1 %c, <2 x double> %a, <4 x double> %b) {
138; CHECK-LABEL: @pr25999_phis1(
139; CHECK-NEXT:  bb1:
140; CHECK-NEXT:    br i1 [[C:%.*]], label [[BB2:%.*]], label [[BB3:%.*]]
141; CHECK:       bb2:
142; CHECK-NEXT:    [[R:%.*]] = call <2 x double> @dummy(<2 x double> [[A:%.*]])
143; CHECK-NEXT:    br label [[BB3]]
144; CHECK:       bb3:
145; CHECK-NEXT:    [[T1:%.*]] = phi <2 x double> [ [[A]], [[BB1:%.*]] ], [ [[R]], [[BB2]] ]
146; CHECK-NEXT:    [[T2:%.*]] = phi <4 x double> [ [[B:%.*]], [[BB1]] ], [ zeroinitializer, [[BB2]] ]
147; CHECK-NEXT:    [[TMP0:%.*]] = shufflevector <2 x double> [[T1]], <2 x double> poison, <4 x i32> <i32 0, i32 poison, i32 poison, i32 poison>
148; CHECK-NEXT:    [[T4:%.*]] = shufflevector <4 x double> [[T2]], <4 x double> [[TMP0]], <4 x i32> <i32 0, i32 1, i32 4, i32 3>
149; CHECK-NEXT:    ret <4 x double> [[T4]]
150;
151bb1:
152  br i1 %c, label %bb2, label %bb3
153
154bb2:
155  %r = call <2 x double> @dummy(<2 x double> %a)
156  br label %bb3
157
158bb3:
159  %t1 = phi <2 x double> [ %a, %bb1 ], [ %r, %bb2 ]
160  %t2 = phi <4 x double> [ %b, %bb1 ], [ zeroinitializer, %bb2 ]
161  %t3 = extractelement <2 x double> %t1, i32 0
162  %t4 = insertelement <4 x double> %t2, double %t3, i32 2
163  ret <4 x double> %t4
164}
165
166declare <2 x double> @dummy(<2 x double>)
167
168define <4 x double> @pr25999_phis2(i1 %c, <2 x double> %a, <4 x double> %b) {
169; CHECK-LABEL: @pr25999_phis2(
170; CHECK-NEXT:  bb1:
171; CHECK-NEXT:    br i1 [[C:%.*]], label [[BB2:%.*]], label [[BB3:%.*]]
172; CHECK:       bb2:
173; CHECK-NEXT:    [[R:%.*]] = call <2 x double> @dummy(<2 x double> [[A:%.*]])
174; CHECK-NEXT:    br label [[BB3]]
175; CHECK:       bb3:
176; CHECK-NEXT:    [[T1:%.*]] = phi <2 x double> [ [[A]], [[BB1:%.*]] ], [ [[R]], [[BB2]] ]
177; CHECK-NEXT:    [[T2:%.*]] = phi <4 x double> [ [[B:%.*]], [[BB1]] ], [ zeroinitializer, [[BB2]] ]
178; CHECK-NEXT:    [[D:%.*]] = fadd <2 x double> [[T1]], [[T1]]
179; CHECK-NEXT:    [[TMP0:%.*]] = shufflevector <2 x double> [[D]], <2 x double> poison, <4 x i32> <i32 0, i32 poison, i32 poison, i32 poison>
180; CHECK-NEXT:    [[T4:%.*]] = shufflevector <4 x double> [[T2]], <4 x double> [[TMP0]], <4 x i32> <i32 0, i32 1, i32 4, i32 3>
181; CHECK-NEXT:    ret <4 x double> [[T4]]
182;
183bb1:
184  br i1 %c, label %bb2, label %bb3
185
186bb2:
187  %r = call <2 x double> @dummy(<2 x double> %a)
188  br label %bb3
189
190bb3:
191  %t1 = phi <2 x double> [ %a, %bb1 ], [ %r, %bb2 ]
192  %t2 = phi <4 x double> [ %b, %bb1 ], [ zeroinitializer, %bb2 ]
193  %d = fadd <2 x double> %t1, %t1
194  %t3 = extractelement <2 x double> %d, i32 0
195  %t4 = insertelement <4 x double> %t2, double %t3, i32 2
196  ret <4 x double> %t4
197}
198
199; PR26354: https://llvm.org/bugs/show_bug.cgi?id=26354
200; Don't create a shufflevector if we know that we're not going to replace the insertelement.
201
202define double @pr26354(ptr %t, i1 %B) {
203; CHECK-LABEL: @pr26354(
204; CHECK-NEXT:  entry:
205; CHECK-NEXT:    [[LD:%.*]] = load <2 x double>, ptr [[T:%.*]], align 16
206; CHECK-NEXT:    br i1 [[B:%.*]], label [[IF:%.*]], label [[END:%.*]]
207; CHECK:       if:
208; CHECK-NEXT:    [[E2:%.*]] = extractelement <2 x double> [[LD]], i64 1
209; CHECK-NEXT:    [[I1:%.*]] = insertelement <4 x double> <double 0.000000e+00, double 0.000000e+00, double 0.000000e+00, double poison>, double [[E2]], i64 3
210; CHECK-NEXT:    br label [[END]]
211; CHECK:       end:
212; CHECK-NEXT:    [[PH:%.*]] = phi <4 x double> [ undef, [[ENTRY:%.*]] ], [ [[I1]], [[IF]] ]
213; CHECK-NEXT:    [[E1:%.*]] = extractelement <2 x double> [[LD]], i64 0
214; CHECK-NEXT:    [[E3:%.*]] = extractelement <4 x double> [[PH]], i64 1
215; CHECK-NEXT:    [[MU:%.*]] = fmul double [[E1]], [[E3]]
216; CHECK-NEXT:    ret double [[MU]]
217;
218
219entry:
220  %ld = load <2 x double>, ptr %t
221  %e1 = extractelement <2 x double> %ld, i32 0
222  %e2 = extractelement <2 x double> %ld, i32 1
223  br i1 %B, label %if, label %end
224
225if:
226  %i1 = insertelement <4 x double> zeroinitializer, double %e2, i32 3
227  br label %end
228
229end:
230  %ph = phi <4 x double> [ undef, %entry ], [ %i1, %if ]
231  %e3 = extractelement <4 x double> %ph, i32 1
232  %mu = fmul double %e1, %e3
233  ret double %mu
234}
235
236; https://llvm.org/bugs/show_bug.cgi?id=30923
237; Delete the widening shuffle if we're not going to reduce the extract/insert to a shuffle.
238
239define <4 x float> @PR30923(<2 x float> %x, ptr %p) {
240; CHECK-LABEL: @PR30923(
241; CHECK-NEXT:  bb1:
242; CHECK-NEXT:    [[EXT1:%.*]] = extractelement <2 x float> [[X:%.*]], i64 1
243; CHECK-NEXT:    store float [[EXT1]], ptr [[P:%.*]], align 4
244; CHECK-NEXT:    br label [[BB2:%.*]]
245; CHECK:       bb2:
246; CHECK-NEXT:    [[EXT2:%.*]] = extractelement <2 x float> [[X]], i64 0
247; CHECK-NEXT:    [[INS1:%.*]] = insertelement <4 x float> <float 0.000000e+00, float 0.000000e+00, float poison, float poison>, float [[EXT2]], i64 2
248; CHECK-NEXT:    [[INS2:%.*]] = insertelement <4 x float> [[INS1]], float [[EXT1]], i64 3
249; CHECK-NEXT:    ret <4 x float> [[INS2]]
250;
251bb1:
252  %ext1 = extractelement <2 x float> %x, i32 1
253  store float %ext1, ptr %p, align 4
254  br label %bb2
255
256bb2:
257  %widen = shufflevector <2 x float> %x, <2 x float> poison, <4 x i32> <i32 0, i32 1, i32 undef, i32 undef>
258  %ext2 = extractelement <4 x float> %widen, i32 0
259  %ins1 = insertelement <4 x float> <float 0.0, float 0.0, float undef, float undef>, float %ext2, i32 2
260  %ins2 = insertelement <4 x float> %ins1, float %ext1, i32 3
261  ret <4 x float> %ins2
262}
263
264; Don't insert extractelements from the wider vector before the def of the index operand.
265
266define <4 x i32> @extractelt_insertion(<2 x i32> %x, i32 %y) {
267; CHECK-LABEL: @extractelt_insertion(
268; CHECK-NEXT:  entry:
269; CHECK-NEXT:    [[TMP0:%.*]] = shufflevector <2 x i32> [[X:%.*]], <2 x i32> poison, <4 x i32> <i32 0, i32 1, i32 poison, i32 poison>
270; CHECK-NEXT:    [[B:%.*]] = shufflevector <4 x i32> <i32 0, i32 poison, i32 poison, i32 poison>, <4 x i32> [[TMP0]], <4 x i32> <i32 0, i32 0, i32 0, i32 5>
271; CHECK-NEXT:    [[C:%.*]] = add i32 [[Y:%.*]], 3
272; CHECK-NEXT:    [[D:%.*]] = extractelement <4 x i32> [[TMP0]], i32 [[C]]
273; CHECK-NEXT:    [[E:%.*]] = icmp eq i32 [[D]], 0
274; CHECK-NEXT:    [[RET:%.*]] = select i1 [[E]], <4 x i32> [[B]], <4 x i32> zeroinitializer
275; CHECK-NEXT:    ret <4 x i32> [[RET]]
276;
277entry:
278  %a = extractelement <2 x i32> %x, i32 1
279  %b = insertelement <4 x i32> zeroinitializer, i32 %a, i64 3
280  %c = add i32 %y, 3
281  %d = extractelement <2 x i32> %x, i32 %c
282  %e = icmp eq i32 %d, 0
283  %ret = select i1 %e, <4 x i32> %b, <4 x i32> zeroinitializer
284  ret <4 x i32> %ret
285}
286
287; PR34724: https://bugs.llvm.org/show_bug.cgi?id=34724
288
289define <4 x float> @collectShuffleElts(<2 x float> %x, float %y) {
290; CHECK-LABEL: @collectShuffleElts(
291; CHECK-NEXT:    [[X0:%.*]] = extractelement <2 x float> [[X:%.*]], i64 0
292; CHECK-NEXT:    [[X1:%.*]] = extractelement <2 x float> [[X]], i64 1
293; CHECK-NEXT:    [[V1:%.*]] = insertelement <4 x float> poison, float [[X0]], i64 1
294; CHECK-NEXT:    [[V2:%.*]] = insertelement <4 x float> [[V1]], float [[X1]], i64 2
295; CHECK-NEXT:    [[V3:%.*]] = insertelement <4 x float> [[V2]], float [[Y:%.*]], i64 3
296; CHECK-NEXT:    ret <4 x float> [[V3]]
297;
298  %x0 = extractelement <2 x float> %x, i32 0
299  %x1 = extractelement <2 x float> %x, i32 1
300  %v1 = insertelement <4 x float> poison, float %x0, i32 1
301  %v2 = insertelement <4 x float> %v1, float %x1, i32 2
302  %v3 = insertelement <4 x float> %v2, float %y, i32 3
303  ret <4 x float> %v3
304}
305
306; Simplest case - insert scalar into undef, then shuffle that value in place into another vector.
307
308define <4 x float> @insert_shuffle(float %x, <4 x float> %y) {
309; CHECK-LABEL: @insert_shuffle(
310; CHECK-NEXT:    [[R:%.*]] = insertelement <4 x float> [[Y:%.*]], float [[X:%.*]], i64 0
311; CHECK-NEXT:    ret <4 x float> [[R]]
312;
313  %xv = insertelement <4 x float> poison, float %x, i32 0
314  %r = shufflevector <4 x float> %xv, <4 x float> %y, <4 x i32> <i32 0, i32 5, i32 6, i32 7>
315  ret <4 x float> %r
316}
317
318; Insert scalar into some element of a dummy vector, then move it to a different element in another vector.
319
320define <4 x float> @insert_shuffle_translate(float %x, <4 x float> %y) {
321; CHECK-LABEL: @insert_shuffle_translate(
322; CHECK-NEXT:    [[R:%.*]] = insertelement <4 x float> [[Y:%.*]], float [[X:%.*]], i64 1
323; CHECK-NEXT:    ret <4 x float> [[R]]
324;
325  %xv = insertelement <4 x float> poison, float %x, i32 0
326  %r = shufflevector <4 x float> %xv, <4 x float> %y, <4 x i32> <i32 4, i32 0, i32 6, i32 7>
327  ret <4 x float> %r
328}
329
330; The vector operand of the insert is irrelevant.
331
332define <4 x float> @insert_not_undef_shuffle_translate(float %x, <4 x float> %y, <4 x float> %q) {
333; CHECK-LABEL: @insert_not_undef_shuffle_translate(
334; CHECK-NEXT:    [[R:%.*]] = insertelement <4 x float> [[Y:%.*]], float [[X:%.*]], i64 2
335; CHECK-NEXT:    ret <4 x float> [[R]]
336;
337  %xv = insertelement <4 x float> %q, float %x, i32 3
338  %r = shufflevector <4 x float> %xv, <4 x float> %y, <4 x i32> <i32 4, i32 5, i32 3, i32 7>
339  ret <4 x float> %r
340}
341
342; The insert may be the 2nd operand of the shuffle. The shuffle mask can include undef elements.
343
344define <4 x float> @insert_not_undef_shuffle_translate_commute(float %x, <4 x float> %y, <4 x float> %q) {
345; CHECK-LABEL: @insert_not_undef_shuffle_translate_commute(
346; CHECK-NEXT:    [[R:%.*]] = insertelement <4 x float> [[Y:%.*]], float [[X:%.*]], i64 1
347; CHECK-NEXT:    ret <4 x float> [[R]]
348;
349  %xv = insertelement <4 x float> %q, float %x, i32 2
350  %r = shufflevector <4 x float> %y, <4 x float> %xv, <4 x i32> <i32 0, i32 6, i32 2, i32 undef>
351  ret <4 x float> %r
352}
353
354; Both shuffle operands may be inserts - choose the correct side.
355
356define <4 x float> @insert_insert_shuffle_translate(float %x1, float %x2, <4 x float> %q) {
357; CHECK-LABEL: @insert_insert_shuffle_translate(
358; CHECK-NEXT:    [[TMP1:%.*]] = insertelement <4 x float> [[Q:%.*]], float [[X1:%.*]], i64 1
359; CHECK-NEXT:    [[R:%.*]] = insertelement <4 x float> [[TMP1]], float [[X2:%.*]], i64 2
360; CHECK-NEXT:    ret <4 x float> [[R]]
361;
362  %xv1 = insertelement <4 x float> %q, float %x1, i32 0
363  %xv2 = insertelement <4 x float> %q, float %x2, i32 2
364  %r = shufflevector <4 x float> %xv1, <4 x float> %xv2, <4 x i32> <i32 4, i32 0, i32 6, i32 7>
365  ret <4 x float> %r
366}
367
368; Both shuffle operands may be inserts - choose the correct side.
369
370define <4 x float> @insert_insert_shuffle_translate_commute(float %x1, float %x2, <4 x float> %q) {
371; CHECK-LABEL: @insert_insert_shuffle_translate_commute(
372; CHECK-NEXT:    [[XV1:%.*]] = insertelement <4 x float> [[Q:%.*]], float [[X1:%.*]], i64 0
373; CHECK-NEXT:    [[R:%.*]] = insertelement <4 x float> [[XV1]], float [[X2:%.*]], i64 1
374; CHECK-NEXT:    ret <4 x float> [[R]]
375;
376  %xv1 = insertelement <4 x float> %q, float %x1, i32 0
377  %xv2 = insertelement <4 x float> %q, float %x2, i32 2
378  %r = shufflevector <4 x float> %xv1, <4 x float> %xv2, <4 x i32> <i32 0, i32 6, i32 2, i32 3>
379  ret <4 x float> %r
380}
381
382; Negative test - this only works if the shuffle is choosing exactly 1 element from 1 of the inputs.
383; TODO: But this could be a special-case because we're inserting into the same base vector.
384
385define <4 x float> @insert_insert_shuffle_translate_wrong_mask(float %x1, float %x2, <4 x float> %q) {
386; CHECK-LABEL: @insert_insert_shuffle_translate_wrong_mask(
387; CHECK-NEXT:    [[XV1:%.*]] = insertelement <4 x float> [[Q:%.*]], float [[X1:%.*]], i64 0
388; CHECK-NEXT:    [[XV2:%.*]] = insertelement <4 x float> [[Q]], float [[X2:%.*]], i64 2
389; CHECK-NEXT:    [[R:%.*]] = shufflevector <4 x float> [[XV1]], <4 x float> [[XV2]], <4 x i32> <i32 0, i32 6, i32 2, i32 7>
390; CHECK-NEXT:    ret <4 x float> [[R]]
391;
392  %xv1 = insertelement <4 x float> %q, float %x1, i32 0
393  %xv2 = insertelement <4 x float> %q, float %x2, i32 2
394  %r = shufflevector <4 x float> %xv1, <4 x float> %xv2, <4 x i32> <i32 0, i32 6, i32 2, i32 7>
395  ret <4 x float> %r
396}
397
398; The insert may have other uses.
399
400declare void @use(<4 x float>)
401
402define <4 x float> @insert_not_undef_shuffle_translate_commute_uses(float %x, <4 x float> %y, <4 x float> %q) {
403; CHECK-LABEL: @insert_not_undef_shuffle_translate_commute_uses(
404; CHECK-NEXT:    [[XV:%.*]] = insertelement <4 x float> [[Q:%.*]], float [[X:%.*]], i64 2
405; CHECK-NEXT:    call void @use(<4 x float> [[XV]])
406; CHECK-NEXT:    [[R:%.*]] = insertelement <4 x float> [[Y:%.*]], float [[X]], i64 0
407; CHECK-NEXT:    ret <4 x float> [[R]]
408;
409  %xv = insertelement <4 x float> %q, float %x, i32 2
410  call void @use(<4 x float> %xv)
411  %r = shufflevector <4 x float> %y, <4 x float> %xv, <4 x i32> <i32 6, i32 undef, i32 2, i32 3>
412  ret <4 x float> %r
413}
414
415; Negative test - size-changing shuffle.
416
417define <5 x float> @insert_not_undef_shuffle_translate_commute_lengthen(float %x, <4 x float> %y, <4 x float> %q) {
418; CHECK-LABEL: @insert_not_undef_shuffle_translate_commute_lengthen(
419; CHECK-NEXT:    [[XV:%.*]] = insertelement <4 x float> poison, float [[X:%.*]], i64 2
420; CHECK-NEXT:    [[R:%.*]] = shufflevector <4 x float> [[Y:%.*]], <4 x float> [[XV]], <5 x i32> <i32 0, i32 6, i32 2, i32 poison, i32 poison>
421; CHECK-NEXT:    ret <5 x float> [[R]]
422;
423  %xv = insertelement <4 x float> %q, float %x, i32 2
424  %r = shufflevector <4 x float> %y, <4 x float> %xv, <5 x i32> <i32 0, i32 6, i32 2, i32 undef, i32 undef>
425  ret <5 x float> %r
426}
427
428define <4 x float> @insert_nonzero_index_splat(float %x) {
429; CHECK-LABEL: @insert_nonzero_index_splat(
430; CHECK-NEXT:    [[TMP1:%.*]] = insertelement <4 x float> poison, float [[X:%.*]], i64 0
431; CHECK-NEXT:    [[SPLAT:%.*]] = shufflevector <4 x float> [[TMP1]], <4 x float> poison, <4 x i32> <i32 poison, i32 0, i32 0, i32 poison>
432; CHECK-NEXT:    ret <4 x float> [[SPLAT]]
433;
434  %xv = insertelement <4 x float> poison, float %x, i32 2
435  %splat = shufflevector <4 x float> %xv, <4 x float> poison, <4 x i32> <i32 undef, i32 2, i32 2, i32 undef>
436  ret <4 x float> %splat
437}
438
439define <3 x double> @insert_nonzero_index_splat_narrow(double %x) {
440; CHECK-LABEL: @insert_nonzero_index_splat_narrow(
441; CHECK-NEXT:    [[TMP1:%.*]] = insertelement <3 x double> poison, double [[X:%.*]], i64 0
442; CHECK-NEXT:    [[SPLAT:%.*]] = shufflevector <3 x double> [[TMP1]], <3 x double> poison, <3 x i32> <i32 0, i32 poison, i32 0>
443; CHECK-NEXT:    ret <3 x double> [[SPLAT]]
444;
445  %xv = insertelement <4 x double> poison, double %x, i32 3
446  %splat = shufflevector <4 x double> %xv, <4 x double> poison, <3 x i32> <i32 3, i32 undef, i32 3>
447  ret <3 x double> %splat
448}
449
450define <5 x i7> @insert_nonzero_index_splat_widen(i7 %x) {
451; CHECK-LABEL: @insert_nonzero_index_splat_widen(
452; CHECK-NEXT:    [[TMP1:%.*]] = insertelement <5 x i7> poison, i7 [[X:%.*]], i64 0
453; CHECK-NEXT:    [[SPLAT:%.*]] = shufflevector <5 x i7> [[TMP1]], <5 x i7> poison, <5 x i32> <i32 poison, i32 0, i32 0, i32 poison, i32 0>
454; CHECK-NEXT:    ret <5 x i7> [[SPLAT]]
455;
456  %xv = insertelement <4 x i7> poison, i7 %x, i32 1
457  %splat = shufflevector <4 x i7> %xv, <4 x i7> poison, <5 x i32> <i32 undef, i32 1, i32 1, i32 undef, i32 1>
458  ret <5 x i7> %splat
459}
460
461; Negative test - don't increase instruction count
462
463define <4 x float> @insert_nonzero_index_splat_extra_use(float %x) {
464; CHECK-LABEL: @insert_nonzero_index_splat_extra_use(
465; CHECK-NEXT:    [[XV:%.*]] = insertelement <4 x float> poison, float [[X:%.*]], i64 2
466; CHECK-NEXT:    call void @use(<4 x float> [[XV]])
467; CHECK-NEXT:    [[SPLAT:%.*]] = shufflevector <4 x float> [[XV]], <4 x float> poison, <4 x i32> <i32 poison, i32 2, i32 2, i32 poison>
468; CHECK-NEXT:    ret <4 x float> [[SPLAT]]
469;
470  %xv = insertelement <4 x float> poison, float %x, i32 2
471  call void @use(<4 x float> %xv)
472  %splat = shufflevector <4 x float> %xv, <4 x float> poison, <4 x i32> <i32 undef, i32 2, i32 2, i32 undef>
473  ret <4 x float> %splat
474}
475
476; Negative test - non-undef base vector
477
478define <4 x float> @insert_nonzero_index_splat_wrong_base(float %x, <4 x float> %y) {
479; CHECK-LABEL: @insert_nonzero_index_splat_wrong_base(
480; CHECK-NEXT:    [[XV:%.*]] = insertelement <4 x float> [[Y:%.*]], float [[X:%.*]], i64 2
481; CHECK-NEXT:    [[SPLAT:%.*]] = shufflevector <4 x float> [[XV]], <4 x float> poison, <4 x i32> <i32 poison, i32 2, i32 3, i32 poison>
482; CHECK-NEXT:    ret <4 x float> [[SPLAT]]
483;
484  %xv = insertelement <4 x float> %y, float %x, i32 2
485  %splat = shufflevector <4 x float> %xv, <4 x float> poison, <4 x i32> <i32 undef, i32 2, i32 3, i32 undef>
486  ret <4 x float> %splat
487}
488
489; Negative test - non-constant insert index
490
491define <4 x float> @insert_nonzero_index_splat_wrong_index(float %x, i32 %index) {
492; CHECK-LABEL: @insert_nonzero_index_splat_wrong_index(
493; CHECK-NEXT:    [[XV:%.*]] = insertelement <4 x float> poison, float [[X:%.*]], i32 [[INDEX:%.*]]
494; CHECK-NEXT:    [[SPLAT:%.*]] = shufflevector <4 x float> [[XV]], <4 x float> poison, <4 x i32> <i32 poison, i32 1, i32 1, i32 poison>
495; CHECK-NEXT:    ret <4 x float> [[SPLAT]]
496;
497  %xv = insertelement <4 x float> poison, float %x, i32 %index
498  %splat = shufflevector <4 x float> %xv, <4 x float> poison, <4 x i32> <i32 undef, i32 1, i32 1, i32 undef>
499  ret <4 x float> %splat
500}
501
502define <4 x float> @insert_in_splat(float %x) {
503; CHECK-LABEL: @insert_in_splat(
504; CHECK-NEXT:    [[XV:%.*]] = insertelement <4 x float> poison, float [[X:%.*]], i64 0
505; CHECK-NEXT:    [[R:%.*]] = shufflevector <4 x float> [[XV]], <4 x float> poison, <4 x i32> <i32 poison, i32 0, i32 0, i32 0>
506; CHECK-NEXT:    ret <4 x float> [[R]]
507;
508  %xv = insertelement <4 x float> poison, float %x, i32 0
509  %splat = shufflevector <4 x float> %xv, <4 x float> poison, <4 x i32> <i32 undef, i32 0, i32 0, i32 undef>
510  %r = insertelement <4 x float> %splat, float %x, i32 3
511  ret <4 x float> %r
512}
513
514define <4 x float> @insert_in_splat_extra_uses(float %x) {
515; CHECK-LABEL: @insert_in_splat_extra_uses(
516; CHECK-NEXT:    [[XV:%.*]] = insertelement <4 x float> poison, float [[X:%.*]], i64 0
517; CHECK-NEXT:    call void @use(<4 x float> [[XV]])
518; CHECK-NEXT:    [[SPLAT:%.*]] = shufflevector <4 x float> [[XV]], <4 x float> poison, <4 x i32> <i32 poison, i32 0, i32 0, i32 poison>
519; CHECK-NEXT:    call void @use(<4 x float> [[SPLAT]])
520; CHECK-NEXT:    [[R:%.*]] = shufflevector <4 x float> [[XV]], <4 x float> poison, <4 x i32> <i32 poison, i32 0, i32 0, i32 0>
521; CHECK-NEXT:    ret <4 x float> [[R]]
522;
523  %xv = insertelement <4 x float> poison, float %x, i32 0
524  call void @use(<4 x float> %xv)
525  %splat = shufflevector <4 x float> %xv, <4 x float> poison, <4 x i32> <i32 undef, i32 0, i32 0, i32 undef>
526  call void @use(<4 x float> %splat)
527  %r = insertelement <4 x float> %splat, float %x, i32 3
528  ret <4 x float> %r
529}
530
531; Negative test - not a constant index insert
532
533define <4 x float> @insert_in_splat_variable_index(float %x, i32 %y) {
534; CHECK-LABEL: @insert_in_splat_variable_index(
535; CHECK-NEXT:    [[XV:%.*]] = insertelement <4 x float> poison, float [[X:%.*]], i64 0
536; CHECK-NEXT:    [[SPLAT:%.*]] = shufflevector <4 x float> [[XV]], <4 x float> poison, <4 x i32> <i32 poison, i32 0, i32 0, i32 poison>
537; CHECK-NEXT:    [[R:%.*]] = insertelement <4 x float> [[SPLAT]], float [[X]], i32 [[Y:%.*]]
538; CHECK-NEXT:    ret <4 x float> [[R]]
539;
540  %xv = insertelement <4 x float> poison, float %x, i32 0
541  %splat = shufflevector <4 x float> %xv, <4 x float> poison, <4 x i32> <i32 undef, i32 0, i32 0, i32 undef>
542  %r = insertelement <4 x float> %splat, float %x, i32 %y
543  ret <4 x float> %r
544}
545
546; Negative test - not a splat shuffle
547
548define <4 x float> @insert_in_nonsplat(float %x, <4 x float> %y) {
549; CHECK-LABEL: @insert_in_nonsplat(
550; CHECK-NEXT:    [[XV:%.*]] = insertelement <4 x float> poison, float [[X:%.*]], i64 0
551; CHECK-NEXT:    [[SPLAT:%.*]] = shufflevector <4 x float> [[XV]], <4 x float> [[Y:%.*]], <4 x i32> <i32 poison, i32 0, i32 4, i32 poison>
552; CHECK-NEXT:    [[R:%.*]] = insertelement <4 x float> [[SPLAT]], float [[X]], i64 3
553; CHECK-NEXT:    ret <4 x float> [[R]]
554;
555  %xv = insertelement <4 x float> poison, float %x, i32 0
556  %splat = shufflevector <4 x float> %xv, <4 x float> %y, <4 x i32> <i32 undef, i32 0, i32 4, i32 undef>
557  %r = insertelement <4 x float> %splat, float %x, i32 3
558  ret <4 x float> %r
559}
560
561; Negative test - not a splat shuffle
562
563define <4 x float> @insert_in_nonsplat2(float %x, <4 x float> %y) {
564; CHECK-LABEL: @insert_in_nonsplat2(
565; CHECK-NEXT:    [[XV:%.*]] = insertelement <4 x float> [[Y:%.*]], float [[X:%.*]], i64 0
566; CHECK-NEXT:    [[SPLAT:%.*]] = shufflevector <4 x float> [[XV]], <4 x float> poison, <4 x i32> <i32 poison, i32 0, i32 1, i32 poison>
567; CHECK-NEXT:    [[R:%.*]] = insertelement <4 x float> [[SPLAT]], float [[X]], i64 3
568; CHECK-NEXT:    ret <4 x float> [[R]]
569;
570  %xv = insertelement <4 x float> %y, float %x, i32 0
571  %splat = shufflevector <4 x float> %xv, <4 x float> poison, <4 x i32> <i32 undef, i32 0, i32 1, i32 undef>
572  %r = insertelement <4 x float> %splat, float %x, i32 3
573  ret <4 x float> %r
574}
575
576define <4 x i8> @shuf_identity_padding(<2 x i8> %x, i8 %y) {
577; CHECK-LABEL: @shuf_identity_padding(
578; CHECK-NEXT:    [[V1:%.*]] = shufflevector <2 x i8> [[X:%.*]], <2 x i8> poison, <4 x i32> <i32 0, i32 1, i32 poison, i32 poison>
579; CHECK-NEXT:    [[V2:%.*]] = insertelement <4 x i8> [[V1]], i8 [[Y:%.*]], i64 2
580; CHECK-NEXT:    ret <4 x i8> [[V2]]
581;
582  %v0 = shufflevector <2 x i8> %x, <2 x i8> poison, <4 x i32> <i32 0, i32 1, i32 undef, i32 undef>
583  %x1 = extractelement <2 x i8> %x, i32 1
584  %v1 = insertelement <4 x i8> %v0, i8 %x1, i32 1
585  %v2 = insertelement <4 x i8> %v1, i8 %y, i32 2
586  ret <4 x i8> %v2
587}
588
589define <3 x i8> @shuf_identity_extract(<4 x i8> %x, i8 %y) {
590; CHECK-LABEL: @shuf_identity_extract(
591; CHECK-NEXT:    [[V1:%.*]] = shufflevector <4 x i8> [[X:%.*]], <4 x i8> poison, <3 x i32> <i32 0, i32 1, i32 poison>
592; CHECK-NEXT:    [[V2:%.*]] = insertelement <3 x i8> [[V1]], i8 [[Y:%.*]], i64 2
593; CHECK-NEXT:    ret <3 x i8> [[V2]]
594;
595  %v0 = shufflevector <4 x i8> %x, <4 x i8> poison, <3 x i32> <i32 0, i32 undef, i32 undef>
596  %x1 = extractelement <4 x i8> %x, i32 1
597  %v1 = insertelement <3 x i8> %v0, i8 %x1, i32 1
598  %v2 = insertelement <3 x i8> %v1, i8 %y, i32 2
599  ret <3 x i8> %v2
600}
601
602define <4 x float> @shuf_identity_extract_extra_use(<6 x float> %x, float %y) {
603; CHECK-LABEL: @shuf_identity_extract_extra_use(
604; CHECK-NEXT:    [[V0:%.*]] = shufflevector <6 x float> [[X:%.*]], <6 x float> poison, <4 x i32> <i32 0, i32 poison, i32 poison, i32 3>
605; CHECK-NEXT:    call void @use(<4 x float> [[V0]])
606; CHECK-NEXT:    [[V1:%.*]] = shufflevector <6 x float> [[X]], <6 x float> poison, <4 x i32> <i32 0, i32 poison, i32 2, i32 3>
607; CHECK-NEXT:    [[V2:%.*]] = insertelement <4 x float> [[V1]], float [[Y:%.*]], i64 1
608; CHECK-NEXT:    ret <4 x float> [[V2]]
609;
610  %v0 = shufflevector <6 x float> %x, <6 x float> poison, <4 x i32> <i32 0, i32 undef, i32 undef, i32 3>
611  call void @use(<4 x float> %v0)
612  %x1 = extractelement <6 x float> %x, i32 2
613  %v1 = insertelement <4 x float> %v0, float %x1, i32 2
614  %v2 = insertelement <4 x float> %v1, float %y, i32 1
615  ret <4 x float> %v2
616}
617
618; Negative test - can't map variable index to shuffle mask.
619
620define <4 x i8> @shuf_identity_padding_variable_index(<2 x i8> %x, i8 %y, i32 %index) {
621; CHECK-LABEL: @shuf_identity_padding_variable_index(
622; CHECK-NEXT:    [[V0:%.*]] = shufflevector <2 x i8> [[X:%.*]], <2 x i8> poison, <4 x i32> <i32 0, i32 1, i32 poison, i32 poison>
623; CHECK-NEXT:    [[X1:%.*]] = extractelement <2 x i8> [[X]], i32 [[INDEX:%.*]]
624; CHECK-NEXT:    [[V1:%.*]] = insertelement <4 x i8> [[V0]], i8 [[X1]], i32 [[INDEX]]
625; CHECK-NEXT:    [[V2:%.*]] = insertelement <4 x i8> [[V1]], i8 [[Y:%.*]], i64 2
626; CHECK-NEXT:    ret <4 x i8> [[V2]]
627;
628  %v0 = shufflevector <2 x i8> %x, <2 x i8> poison, <4 x i32> <i32 0, i32 1, i32 undef, i32 undef>
629  %x1 = extractelement <2 x i8> %x, i32 %index
630  %v1 = insertelement <4 x i8> %v0, i8 %x1, i32 %index
631  %v2 = insertelement <4 x i8> %v1, i8 %y, i32 2
632  ret <4 x i8> %v2
633}
634
635; Negative test - don't create arbitrary shuffle masks.
636
637define <4 x i8> @shuf_identity_padding_wrong_source_vec(<2 x i8> %x, i8 %y, <2 x i8> %other) {
638; CHECK-LABEL: @shuf_identity_padding_wrong_source_vec(
639; CHECK-NEXT:    [[V0:%.*]] = shufflevector <2 x i8> [[X:%.*]], <2 x i8> poison, <4 x i32> <i32 0, i32 poison, i32 poison, i32 poison>
640; CHECK-NEXT:    [[X1:%.*]] = extractelement <2 x i8> [[OTHER:%.*]], i64 1
641; CHECK-NEXT:    [[V1:%.*]] = insertelement <4 x i8> [[V0]], i8 [[X1]], i64 1
642; CHECK-NEXT:    [[V2:%.*]] = insertelement <4 x i8> [[V1]], i8 [[Y:%.*]], i64 2
643; CHECK-NEXT:    ret <4 x i8> [[V2]]
644;
645  %v0 = shufflevector <2 x i8> %x, <2 x i8> poison, <4 x i32> <i32 0, i32 1, i32 undef, i32 undef>
646  %x1 = extractelement <2 x i8> %other, i32 1
647  %v1 = insertelement <4 x i8> %v0, i8 %x1, i32 1
648  %v2 = insertelement <4 x i8> %v1, i8 %y, i32 2
649  ret <4 x i8> %v2
650}
651
652; Negative test - don't create arbitrary shuffle masks.
653
654define <4 x i8> @shuf_identity_padding_wrong_index(<2 x i8> %x, i8 %y) {
655; CHECK-LABEL: @shuf_identity_padding_wrong_index(
656; CHECK-NEXT:    [[V0:%.*]] = shufflevector <2 x i8> [[X:%.*]], <2 x i8> poison, <4 x i32> <i32 0, i32 1, i32 poison, i32 poison>
657; CHECK-NEXT:    [[X1:%.*]] = extractelement <2 x i8> [[X]], i64 1
658; CHECK-NEXT:    [[V1:%.*]] = insertelement <4 x i8> [[V0]], i8 [[X1]], i64 2
659; CHECK-NEXT:    [[V2:%.*]] = insertelement <4 x i8> [[V1]], i8 [[Y:%.*]], i64 3
660; CHECK-NEXT:    ret <4 x i8> [[V2]]
661;
662  %v0 = shufflevector <2 x i8> %x, <2 x i8> poison, <4 x i32> <i32 0, i32 1, i32 undef, i32 undef>
663  %x1 = extractelement <2 x i8> %x, i32 1
664  %v1 = insertelement <4 x i8> %v0, i8 %x1, i32 2
665  %v2 = insertelement <4 x i8> %v1, i8 %y, i32 3
666  ret <4 x i8> %v2
667}
668
669define <4 x float> @insert_undemanded_element_op0(<4 x float> %x, <4 x float> %y) {
670; CHECK-LABEL: @insert_undemanded_element_op0(
671; CHECK-NEXT:    [[INS:%.*]] = insertelement <4 x float> [[X:%.*]], float 4.200000e+01, i64 3
672; CHECK-NEXT:    call void @use(<4 x float> [[INS]])
673; CHECK-NEXT:    [[S:%.*]] = shufflevector <4 x float> [[X]], <4 x float> [[Y:%.*]], <4 x i32> <i32 0, i32 7, i32 1, i32 4>
674; CHECK-NEXT:    ret <4 x float> [[S]]
675;
676  %ins = insertelement <4 x float> %x, float 42.0, i32 3
677  call void @use(<4 x float> %ins)
678  %s = shufflevector <4 x float> %ins, <4 x float> %y, <4 x i32> <i32 0, i32 7, i32 1, i32 4>
679  ret <4 x float> %s
680}
681
682define <4 x float> @insert_undemanded_element_op1(<4 x float> %x, <4 x float> %y) {
683; CHECK-LABEL: @insert_undemanded_element_op1(
684; CHECK-NEXT:    [[INS:%.*]] = insertelement <4 x float> [[X:%.*]], float 4.200000e+01, i64 3
685; CHECK-NEXT:    call void @use(<4 x float> [[INS]])
686; CHECK-NEXT:    [[S:%.*]] = shufflevector <4 x float> [[Y:%.*]], <4 x float> [[X]], <4 x i32> <i32 3, i32 2, i32 1, i32 4>
687; CHECK-NEXT:    ret <4 x float> [[S]]
688;
689  %ins = insertelement <4 x float> %x, float 42.0, i32 3
690  call void @use(<4 x float> %ins)
691  %s = shufflevector <4 x float> %y, <4 x float> %ins, <4 x i32> <i32 3, i32 2, i32 1, i32 4>
692  ret <4 x float> %s
693}
694
695; Negative test - shuffle chooses the inserted constant.
696
697define <4 x float> @insert_demanded_element_op0(<4 x float> %x, <4 x float> %y) {
698; CHECK-LABEL: @insert_demanded_element_op0(
699; CHECK-NEXT:    [[INS:%.*]] = insertelement <4 x float> [[X:%.*]], float 4.200000e+01, i64 3
700; CHECK-NEXT:    call void @use(<4 x float> [[INS]])
701; CHECK-NEXT:    [[S:%.*]] = shufflevector <4 x float> [[INS]], <4 x float> [[Y:%.*]], <4 x i32> <i32 3, i32 2, i32 1, i32 4>
702; CHECK-NEXT:    ret <4 x float> [[S]]
703;
704  %ins = insertelement <4 x float> %x, float 42.0, i32 3
705  call void @use(<4 x float> %ins)
706  %s = shufflevector <4 x float> %ins, <4 x float> %y, <4 x i32> <i32 3, i32 2, i32 1, i32 4>
707  ret <4 x float> %s
708}
709
710; Negative test - shuffle chooses the inserted constant.
711
712define <4 x float> @insert_demanded_element_op1(<4 x float> %x, <4 x float> %y) {
713; CHECK-LABEL: @insert_demanded_element_op1(
714; CHECK-NEXT:    [[INS:%.*]] = insertelement <4 x float> [[X:%.*]], float 4.300000e+01, i64 3
715; CHECK-NEXT:    call void @use(<4 x float> [[INS]])
716; CHECK-NEXT:    [[S:%.*]] = shufflevector <4 x float> [[Y:%.*]], <4 x float> [[INS]], <4 x i32> <i32 0, i32 7, i32 1, i32 4>
717; CHECK-NEXT:    ret <4 x float> [[S]]
718;
719  %ins = insertelement <4 x float> %x, float 43.0, i32 3
720  call void @use(<4 x float> %ins)
721  %s = shufflevector <4 x float> %y, <4 x float> %ins, <4 x i32> <i32 0, i32 7, i32 1, i32 4>
722  ret <4 x float> %s
723}
724
725define <4 x float> @splat_constant(<4 x float> %x) {
726; CHECK-LABEL: @splat_constant(
727; CHECK-NEXT:    [[INS3:%.*]] = insertelement <4 x float> [[X:%.*]], float 3.000000e+00, i64 3
728; CHECK-NEXT:    [[R:%.*]] = fadd <4 x float> [[INS3]], splat (float 3.000000e+00)
729; CHECK-NEXT:    ret <4 x float> [[R]]
730;
731  %ins3 = insertelement <4 x float> %x, float 3.0, i32 3
732  %splat3 = shufflevector <4 x float> %ins3, <4 x float> poison, <4 x i32> <i32 3, i32 3, i32 3, i32 3>
733  %r = fadd <4 x float> %ins3, %splat3
734  ret <4 x float> %r
735}
736