1 ; NOTE: Assertions have been autogenerated by utils/update_test_checks.py
2 ; RUN: opt < %s -passes=instcombine -S | FileCheck %s
4 define <4 x float> @test1(<4 x float> %v1) {
6 ; CHECK-NEXT: ret <4 x float> [[V1:%.*]]
8 %v2 = shufflevector <4 x float> %v1, <4 x float> poison, <4 x i32> <i32 0, i32 1, i32 2, i32 3>
12 define <4 x float> @test2(<4 x float> %v1) {
13 ; CHECK-LABEL: @test2(
14 ; CHECK-NEXT: ret <4 x float> [[V1:%.*]]
16 %v2 = shufflevector <4 x float> %v1, <4 x float> %v1, <4 x i32> <i32 0, i32 5, i32 2, i32 7>
20 define float @test3(<4 x float> %A, <4 x float> %B, float %f) {
21 ; CHECK-LABEL: @test3(
22 ; CHECK-NEXT: ret float [[F:%.*]]
24 %C = insertelement <4 x float> %A, float %f, i32 0
25 %D = shufflevector <4 x float> %C, <4 x float> %B, <4 x i32> <i32 5, i32 0, i32 2, i32 7>
26 %E = extractelement <4 x float> %D, i32 1
30 define i32 @test4(<4 x i32> %X) {
31 ; CHECK-LABEL: @test4(
32 ; CHECK-NEXT: [[R:%.*]] = extractelement <4 x i32> [[X:%.*]], i64 0
33 ; CHECK-NEXT: ret i32 [[R]]
35 %t = shufflevector <4 x i32> %X, <4 x i32> poison, <4 x i32> zeroinitializer
36 %r = extractelement <4 x i32> %t, i32 0
40 define i32 @test5(<4 x i32> %X) {
41 ; CHECK-LABEL: @test5(
42 ; CHECK-NEXT: [[R:%.*]] = extractelement <4 x i32> [[X:%.*]], i64 3
43 ; CHECK-NEXT: ret i32 [[R]]
45 %t = shufflevector <4 x i32> %X, <4 x i32> poison, <4 x i32> <i32 3, i32 2, i32 undef, i32 undef>
46 %r = extractelement <4 x i32> %t, i32 0
50 define float @test6(<4 x float> %X) {
51 ; CHECK-LABEL: @test6(
52 ; CHECK-NEXT: [[R:%.*]] = extractelement <4 x float> [[X:%.*]], i64 0
53 ; CHECK-NEXT: ret float [[R]]
55 %X1 = bitcast <4 x float> %X to <4 x i32>
56 %t = shufflevector <4 x i32> %X1, <4 x i32> poison, <4 x i32> zeroinitializer
57 %t2 = bitcast <4 x i32> %t to <4 x float>
58 %r = extractelement <4 x float> %t2, i32 0
62 define float @testvscale6(<vscale x 4 x float> %X) {
63 ; CHECK-LABEL: @testvscale6(
64 ; CHECK-NEXT: [[T2:%.*]] = shufflevector <vscale x 4 x float> [[X:%.*]], <vscale x 4 x float> poison, <vscale x 4 x i32> zeroinitializer
65 ; CHECK-NEXT: [[R:%.*]] = extractelement <vscale x 4 x float> [[T2]], i64 0
66 ; CHECK-NEXT: ret float [[R]]
68 %X1 = bitcast <vscale x 4 x float> %X to <vscale x 4 x i32>
69 %t = shufflevector <vscale x 4 x i32> %X1, <vscale x 4 x i32> poison, <vscale x 4 x i32> zeroinitializer
70 %t2 = bitcast <vscale x 4 x i32> %t to <vscale x 4 x float>
71 %r = extractelement <vscale x 4 x float> %t2, i32 0
76 define <4 x float> @test7(<4 x float> %x) {
77 ; CHECK-LABEL: @test7(
78 ; CHECK-NEXT: [[R:%.*]] = shufflevector <4 x float> [[X:%.*]], <4 x float> poison, <4 x i32> <i32 0, i32 1, i32 poison, i32 poison>
79 ; CHECK-NEXT: ret <4 x float> [[R]]
81 %r = shufflevector <4 x float> %x, <4 x float> poison, <4 x i32> < i32 0, i32 1, i32 6, i32 7 >
85 ; This should turn into a single shuffle.
86 define <4 x float> @test8(<4 x float> %x, <4 x float> %y) {
87 ; CHECK-LABEL: @test8(
88 ; CHECK-NEXT: [[T134:%.*]] = shufflevector <4 x float> [[X:%.*]], <4 x float> [[Y:%.*]], <4 x i32> <i32 1, i32 poison, i32 3, i32 4>
89 ; CHECK-NEXT: ret <4 x float> [[T134]]
91 %t4 = extractelement <4 x float> %x, i32 1
92 %t2 = extractelement <4 x float> %x, i32 3
93 %t1 = extractelement <4 x float> %y, i32 0
94 %t128 = insertelement <4 x float> poison, float %t4, i32 0
95 %t130 = insertelement <4 x float> %t128, float poison, i32 1
96 %t132 = insertelement <4 x float> %t130, float %t2, i32 2
97 %t134 = insertelement <4 x float> %t132, float %t1, i32 3
101 ; This shouldn't turn into a single shuffle
102 define <4 x float> @test8_undef(<4 x float> %x, <4 x float> %y) {
103 ; CHECK-LABEL: @test8_undef(
104 ; 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>
105 ; CHECK-NEXT: [[T134:%.*]] = shufflevector <4 x float> [[T132]], <4 x float> [[Y:%.*]], <4 x i32> <i32 0, i32 1, i32 2, i32 4>
106 ; CHECK-NEXT: ret <4 x float> [[T134]]
108 %t4 = extractelement <4 x float> %x, i32 1
109 %t2 = extractelement <4 x float> %x, i32 3
110 %t1 = extractelement <4 x float> %y, i32 0
111 %t128 = insertelement <4 x float> poison, float %t4, i32 0
112 %t130 = insertelement <4 x float> %t128, float undef, i32 1
113 %t132 = insertelement <4 x float> %t130, float %t2, i32 2
114 %t134 = insertelement <4 x float> %t132, float %t1, i32 3
115 ret <4 x float> %t134
118 ; Test fold of two shuffles where the first shuffle vectors inputs are a
119 ; different length then the second.
120 define <4 x i8> @test9(<16 x i8> %t6) {
121 ; CHECK-LABEL: @test9(
122 ; CHECK-NEXT: [[T9:%.*]] = shufflevector <16 x i8> [[T6:%.*]], <16 x i8> poison, <4 x i32> <i32 13, i32 9, i32 4, i32 13>
123 ; CHECK-NEXT: ret <4 x i8> [[T9]]
125 %t7 = shufflevector <16 x i8> %t6, <16 x i8> poison, <4 x i32> < i32 13, i32 9, i32 4, i32 13 >
126 %t9 = shufflevector <4 x i8> %t7, <4 x i8> poison, <4 x i32> < i32 3, i32 1, i32 2, i32 0 >
130 ; Same as test9, but make sure that "undef" mask values are not confused with
131 ; mask values of 2*N, where N is the mask length. These shuffles should not
132 ; be folded (because [8,9,4,8] may not be a mask supported by the target).
134 define <4 x i8> @test9a(<16 x i8> %t6) {
135 ; CHECK-LABEL: @test9a(
136 ; CHECK-NEXT: [[T7:%.*]] = shufflevector <16 x i8> [[T6:%.*]], <16 x i8> poison, <4 x i32> <i32 poison, i32 9, i32 4, i32 8>
137 ; CHECK-NEXT: [[T9:%.*]] = shufflevector <4 x i8> [[T7]], <4 x i8> poison, <4 x i32> <i32 3, i32 1, i32 2, i32 poison>
138 ; CHECK-NEXT: ret <4 x i8> [[T9]]
140 %t7 = shufflevector <16 x i8> %t6, <16 x i8> poison, <4 x i32> < i32 undef, i32 9, i32 4, i32 8 >
141 %t9 = shufflevector <4 x i8> %t7, <4 x i8> poison, <4 x i32> < i32 3, i32 1, i32 2, i32 0 >
145 ; Test fold of two shuffles where the first shuffle vectors inputs are a
146 ; different length then the second.
147 define <4 x i8> @test9b(<4 x i8> %t6, <4 x i8> %t7) {
148 ; CHECK-LABEL: @test9b(
149 ; CHECK-NEXT: [[T9:%.*]] = shufflevector <4 x i8> [[T6:%.*]], <4 x i8> [[T7:%.*]], <4 x i32> <i32 0, i32 1, i32 4, i32 5>
150 ; CHECK-NEXT: ret <4 x i8> [[T9]]
152 %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>
153 %t9 = shufflevector <8 x i8> %t1, <8 x i8> poison, <4 x i32> <i32 0, i32 1, i32 4, i32 5>
157 ; Redundant vector splats should be removed. Radar 8597790.
158 define <4 x i32> @test10(<4 x i32> %t5) {
159 ; CHECK-LABEL: @test10(
160 ; CHECK-NEXT: [[T7:%.*]] = shufflevector <4 x i32> [[T5:%.*]], <4 x i32> poison, <4 x i32> <i32 1, i32 1, i32 1, i32 1>
161 ; CHECK-NEXT: ret <4 x i32> [[T7]]
163 %t6 = shufflevector <4 x i32> %t5, <4 x i32> poison, <4 x i32> <i32 1, i32 undef, i32 undef, i32 undef>
164 %t7 = shufflevector <4 x i32> %t6, <4 x i32> poison, <4 x i32> zeroinitializer
168 ; Test fold of two shuffles where the two shufflevector inputs's op1 are the same.
170 define <8 x i8> @test11(<16 x i8> %t6) {
171 ; CHECK-LABEL: @test11(
172 ; 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>
173 ; CHECK-NEXT: ret <8 x i8> [[T3]]
175 %t1 = shufflevector <16 x i8> %t6, <16 x i8> poison, <4 x i32> <i32 0, i32 1, i32 2, i32 3>
176 %t2 = shufflevector <16 x i8> %t6, <16 x i8> poison, <4 x i32> <i32 4, i32 5, i32 6, i32 7>
177 %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>
181 ; Test fold of two shuffles where the first shufflevector's inputs are the same as the second.
183 define <8 x i8> @test12(<8 x i8> %t6, <8 x i8> %t2) {
184 ; CHECK-LABEL: @test12(
185 ; 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>
186 ; CHECK-NEXT: ret <8 x i8> [[T3]]
188 %t1 = shufflevector <8 x i8> %t6, <8 x i8> poison, <8 x i32> <i32 0, i32 1, i32 2, i32 3, i32 5, i32 4, i32 undef, i32 7>
189 %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>
193 ; Test fold of two shuffles where the first shufflevector's inputs are the same as the second.
195 define <8 x i8> @test12a(<8 x i8> %t6, <8 x i8> %t2) {
196 ; CHECK-LABEL: @test12a(
197 ; 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>
198 ; CHECK-NEXT: ret <8 x i8> [[T3]]
200 %t1 = shufflevector <8 x i8> %t6, <8 x i8> poison, <8 x i32> <i32 0, i32 1, i32 2, i32 3, i32 5, i32 4, i32 undef, i32 7>
201 %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>
205 ; The mask length of the 1st shuffle can be reduced to eliminate the 2nd shuffle.
207 define <2 x i8> @extract_subvector_of_shuffle(<2 x i8> %x, <2 x i8> %y) {
208 ; CHECK-LABEL: @extract_subvector_of_shuffle(
209 ; CHECK-NEXT: [[EXTRACT_SUBV:%.*]] = shufflevector <2 x i8> [[X:%.*]], <2 x i8> [[Y:%.*]], <2 x i32> <i32 0, i32 2>
210 ; CHECK-NEXT: ret <2 x i8> [[EXTRACT_SUBV]]
212 %shuf = shufflevector <2 x i8> %x, <2 x i8> %y, <3 x i32> <i32 0, i32 2, i32 0>
213 %extract_subv = shufflevector <3 x i8> %shuf, <3 x i8> poison, <2 x i32> <i32 0, i32 1>
214 ret <2 x i8> %extract_subv
217 ; Undef elements in either mask are ok. Undefs from the 2nd shuffle mask should propagate to the new shuffle.
218 ; The type of the inputs does not have to match the output type.
220 define <4 x i8> @extract_subvector_of_shuffle_undefs_types(<2 x i8> %x, <2 x i8> %y) {
221 ; CHECK-LABEL: @extract_subvector_of_shuffle_undefs_types(
222 ; CHECK-NEXT: [[EXTRACT_SUBV:%.*]] = shufflevector <2 x i8> [[X:%.*]], <2 x i8> [[Y:%.*]], <4 x i32> <i32 poison, i32 2, i32 0, i32 poison>
223 ; CHECK-NEXT: ret <4 x i8> [[EXTRACT_SUBV]]
225 %shuf = shufflevector <2 x i8> %x, <2 x i8> %y, <5 x i32> <i32 undef, i32 2, i32 0, i32 1, i32 0>
226 %extract_subv = shufflevector <5 x i8> %shuf, <5 x i8> poison, <4 x i32> <i32 0, i32 1, i32 2, i32 undef>
227 ret <4 x i8> %extract_subv
230 ; Extra uses are not ok - we only do the transform when we can eliminate an instruction.
232 declare void @use_v5i8(<5 x i8>)
234 define <4 x i8> @extract_subvector_of_shuffle_extra_use(<2 x i8> %x, <2 x i8> %y) {
235 ; CHECK-LABEL: @extract_subvector_of_shuffle_extra_use(
236 ; 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>
237 ; CHECK-NEXT: call void @use_v5i8(<5 x i8> [[SHUF]])
238 ; CHECK-NEXT: [[EXTRACT_SUBV:%.*]] = shufflevector <5 x i8> [[SHUF]], <5 x i8> poison, <4 x i32> <i32 0, i32 1, i32 2, i32 poison>
239 ; CHECK-NEXT: ret <4 x i8> [[EXTRACT_SUBV]]
241 %shuf = shufflevector <2 x i8> %x, <2 x i8> %y, <5 x i32> <i32 undef, i32 2, i32 0, i32 1, i32 0>
242 call void @use_v5i8(<5 x i8> %shuf)
243 %extract_subv = shufflevector <5 x i8> %shuf, <5 x i8> poison, <4 x i32> <i32 0, i32 1, i32 2, i32 undef>
244 ret <4 x i8> %extract_subv
247 define <2 x i8> @test13a(i8 %x1, i8 %x2) {
248 ; CHECK-LABEL: @test13a(
249 ; CHECK-NEXT: [[TMP1:%.*]] = insertelement <2 x i8> poison, i8 [[X2:%.*]], i64 0
250 ; CHECK-NEXT: [[TMP2:%.*]] = insertelement <2 x i8> [[TMP1]], i8 [[X1:%.*]], i64 1
251 ; CHECK-NEXT: [[D:%.*]] = add <2 x i8> [[TMP2]], <i8 7, i8 5>
252 ; CHECK-NEXT: ret <2 x i8> [[D]]
254 %A = insertelement <2 x i8> poison, i8 %x1, i32 0
255 %B = insertelement <2 x i8> %A, i8 %x2, i32 1
256 %C = add <2 x i8> %B, <i8 5, i8 7>
257 %D = shufflevector <2 x i8> %C, <2 x i8> poison, <2 x i32> <i32 1, i32 0>
261 ; Increasing length of vector ops is not a good canonicalization.
263 define <3 x i32> @add_wider(i32 %y, i32 %z) {
264 ; CHECK-LABEL: @add_wider(
265 ; CHECK-NEXT: [[I0:%.*]] = insertelement <2 x i32> poison, i32 [[Y:%.*]], i64 0
266 ; CHECK-NEXT: [[I1:%.*]] = insertelement <2 x i32> [[I0]], i32 [[Z:%.*]], i64 1
267 ; CHECK-NEXT: [[A:%.*]] = add <2 x i32> [[I1]], splat (i32 255)
268 ; CHECK-NEXT: [[EXT:%.*]] = shufflevector <2 x i32> [[A]], <2 x i32> poison, <3 x i32> <i32 0, i32 1, i32 poison>
269 ; CHECK-NEXT: ret <3 x i32> [[EXT]]
271 %i0 = insertelement <2 x i32> poison, i32 %y, i32 0
272 %i1 = insertelement <2 x i32> %i0, i32 %z, i32 1
273 %a = add <2 x i32> %i1, <i32 255, i32 255>
274 %ext = shufflevector <2 x i32> %a, <2 x i32> poison, <3 x i32> <i32 0, i32 1, i32 undef>
278 ; Increasing length of vector ops must be safe from illegal undef propagation.
280 define <3 x i32> @div_wider(i32 %y, i32 %z) {
281 ; CHECK-LABEL: @div_wider(
282 ; CHECK-NEXT: [[I0:%.*]] = insertelement <2 x i32> poison, i32 [[Y:%.*]], i64 0
283 ; CHECK-NEXT: [[I1:%.*]] = insertelement <2 x i32> [[I0]], i32 [[Z:%.*]], i64 1
284 ; CHECK-NEXT: [[A:%.*]] = sdiv <2 x i32> [[I1]], splat (i32 255)
285 ; CHECK-NEXT: [[EXT:%.*]] = shufflevector <2 x i32> [[A]], <2 x i32> poison, <3 x i32> <i32 0, i32 1, i32 poison>
286 ; CHECK-NEXT: ret <3 x i32> [[EXT]]
288 %i0 = insertelement <2 x i32> poison, i32 %y, i32 0
289 %i1 = insertelement <2 x i32> %i0, i32 %z, i32 1
290 %a = sdiv <2 x i32> %i1, <i32 255, i32 255>
291 %ext = shufflevector <2 x i32> %a, <2 x i32> poison, <3 x i32> <i32 0, i32 1, i32 undef>
295 ; Increasing length of insertelements (no math ops) is a good canonicalization.
297 define <3 x i8> @fold_inselts_with_widening_shuffle(i8 %x, i8 %y) {
298 ; CHECK-LABEL: @fold_inselts_with_widening_shuffle(
299 ; CHECK-NEXT: [[TMP1:%.*]] = insertelement <3 x i8> poison, i8 [[X:%.*]], i64 0
300 ; CHECK-NEXT: [[WIDEN:%.*]] = insertelement <3 x i8> [[TMP1]], i8 [[Y:%.*]], i64 1
301 ; CHECK-NEXT: ret <3 x i8> [[WIDEN]]
303 %ins0 = insertelement <2 x i8> poison, i8 %x, i32 0
304 %ins1 = insertelement <2 x i8> %ins0, i8 %y, i32 1
305 %widen = shufflevector <2 x i8> %ins1, <2 x i8> poison, <3 x i32> <i32 0, i32 1, i32 undef>
309 define <2 x i8> @test13b(i8 %x) {
310 ; CHECK-LABEL: @test13b(
311 ; CHECK-NEXT: [[B:%.*]] = insertelement <2 x i8> poison, i8 [[X:%.*]], i64 1
312 ; CHECK-NEXT: ret <2 x i8> [[B]]
314 %A = insertelement <2 x i8> poison, i8 %x, i32 0
315 %B = shufflevector <2 x i8> %A, <2 x i8> poison, <2 x i32> <i32 undef, i32 0>
319 define <2 x i8> @test13c(i8 %x1, i8 %x2) {
320 ; CHECK-LABEL: @test13c(
321 ; CHECK-NEXT: [[TMP1:%.*]] = insertelement <2 x i8> poison, i8 [[X1:%.*]], i64 0
322 ; CHECK-NEXT: [[C:%.*]] = insertelement <2 x i8> [[TMP1]], i8 [[X2:%.*]], i64 1
323 ; CHECK-NEXT: ret <2 x i8> [[C]]
325 %A = insertelement <4 x i8> poison, i8 %x1, i32 0
326 %B = insertelement <4 x i8> %A, i8 %x2, i32 2
327 %C = shufflevector <4 x i8> %B, <4 x i8> poison, <2 x i32> <i32 0, i32 2>
331 define void @test14(i16 %conv10) {
332 ; CHECK-LABEL: @test14(
333 ; CHECK-NEXT: store <4 x i16> <i16 poison, i16 poison, i16 poison, i16 23>, ptr undef, align 8
334 ; CHECK-NEXT: ret void
336 %t = alloca <4 x i16>, align 8
337 %vecinit6 = insertelement <4 x i16> poison, i16 23, i32 3
338 store <4 x i16> %vecinit6, ptr undef
339 %t1 = load <4 x i16>, ptr undef
340 %vecinit11 = insertelement <4 x i16> poison, i16 %conv10, i32 3
341 %div = udiv <4 x i16> %t1, %vecinit11
342 store <4 x i16> %div, ptr %t
343 %t4 = load <4 x i16>, ptr %t
344 %t5 = shufflevector <4 x i16> %t4, <4 x i16> poison, <2 x i32> <i32 2, i32 0>
345 %cmp = icmp ule <2 x i16> %t5, undef
346 %sext = sext <2 x i1> %cmp to <2 x i16>
350 ; Check that sequences of insert/extract element are
351 ; collapsed into valid shuffle instruction with correct shuffle indexes.
353 define <4 x float> @test15a(<4 x float> %LHS, <4 x float> %RHS) {
354 ; CHECK-LABEL: @test15a(
355 ; CHECK-NEXT: [[T4:%.*]] = shufflevector <4 x float> [[LHS:%.*]], <4 x float> [[RHS:%.*]], <4 x i32> <i32 4, i32 0, i32 6, i32 6>
356 ; CHECK-NEXT: ret <4 x float> [[T4]]
358 %t1 = extractelement <4 x float> %LHS, i32 0
359 %t2 = insertelement <4 x float> %RHS, float %t1, i32 1
360 %t3 = extractelement <4 x float> %RHS, i32 2
361 %t4 = insertelement <4 x float> %t2, float %t3, i32 3
365 define <4 x float> @test15b(<4 x float> %LHS, <4 x float> %RHS) {
366 ; CHECK-LABEL: @test15b(
367 ; CHECK-NEXT: [[T5:%.*]] = shufflevector <4 x float> [[LHS:%.*]], <4 x float> [[RHS:%.*]], <4 x i32> <i32 4, i32 3, i32 6, i32 6>
368 ; CHECK-NEXT: ret <4 x float> [[T5]]
370 %t0 = extractelement <4 x float> %LHS, i32 3
371 %t1 = insertelement <4 x float> %RHS, float %t0, i32 0
372 %t2 = extractelement <4 x float> %t1, i32 0
373 %t3 = insertelement <4 x float> %RHS, float %t2, i32 1
374 %t4 = extractelement <4 x float> %RHS, i32 2
375 %t5 = insertelement <4 x float> %t3, float %t4, i32 3
379 define <1 x i32> @test16a(i32 %ele) {
380 ; CHECK-LABEL: @test16a(
381 ; CHECK-NEXT: ret <1 x i32> splat (i32 2)
383 %t0 = insertelement <2 x i32> <i32 1, i32 undef>, i32 %ele, i32 1
384 %t1 = shl <2 x i32> %t0, <i32 1, i32 1>
385 %t2 = shufflevector <2 x i32> %t1, <2 x i32> poison, <1 x i32> <i32 0>
389 define <4 x i8> @test16b(i8 %ele) {
390 ; CHECK-LABEL: @test16b(
391 ; CHECK-NEXT: ret <4 x i8> splat (i8 2)
393 %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
394 %t1 = shl <8 x i8> %t0, <i8 1, i8 1, i8 1, i8 1, i8 1, i8 1, i8 1, i8 1>
395 %t2 = shufflevector <8 x i8> %t1, <8 x i8> poison, <4 x i32> <i32 1, i32 2, i32 3, i32 4>
399 ; If composition of two shuffles is identity, shuffles can be removed.
400 define <4 x i32> @shuffle_17ident(<4 x i32> %v) {
401 ; CHECK-LABEL: @shuffle_17ident(
402 ; CHECK-NEXT: ret <4 x i32> [[V:%.*]]
404 %shuffle = shufflevector <4 x i32> %v, <4 x i32> zeroinitializer, <4 x i32> <i32 1, i32 2, i32 3, i32 0>
405 %shuffle2 = shufflevector <4 x i32> %shuffle, <4 x i32> zeroinitializer, <4 x i32> <i32 3, i32 0, i32 1, i32 2>
406 ret <4 x i32> %shuffle2
409 ; swizzle can be put after operation
410 define <4 x i32> @shuffle_17and(<4 x i32> %v1, <4 x i32> %v2) {
411 ; CHECK-LABEL: @shuffle_17and(
412 ; CHECK-NEXT: [[TMP1:%.*]] = and <4 x i32> [[V1:%.*]], [[V2:%.*]]
413 ; CHECK-NEXT: [[R:%.*]] = shufflevector <4 x i32> [[TMP1]], <4 x i32> poison, <4 x i32> <i32 1, i32 2, i32 3, i32 0>
414 ; CHECK-NEXT: ret <4 x i32> [[R]]
416 %t1 = shufflevector <4 x i32> %v1, <4 x i32> zeroinitializer, <4 x i32> <i32 1, i32 2, i32 3, i32 0>
417 %t2 = shufflevector <4 x i32> %v2, <4 x i32> zeroinitializer, <4 x i32> <i32 1, i32 2, i32 3, i32 0>
418 %r = and <4 x i32> %t1, %t2
422 declare void @use(<2 x float>)
424 ; One extra use is ok to transform.
426 define <2 x float> @shuffle_fadd_multiuse(<2 x float> %v1, <2 x float> %v2) {
427 ; CHECK-LABEL: @shuffle_fadd_multiuse(
428 ; CHECK-NEXT: [[T1:%.*]] = shufflevector <2 x float> [[V1:%.*]], <2 x float> poison, <2 x i32> <i32 1, i32 0>
429 ; CHECK-NEXT: [[TMP1:%.*]] = fadd <2 x float> [[V1]], [[V2:%.*]]
430 ; CHECK-NEXT: [[R:%.*]] = shufflevector <2 x float> [[TMP1]], <2 x float> poison, <2 x i32> <i32 1, i32 0>
431 ; CHECK-NEXT: call void @use(<2 x float> [[T1]])
432 ; CHECK-NEXT: ret <2 x float> [[R]]
434 %t1 = shufflevector <2 x float> %v1, <2 x float> poison, <2 x i32> <i32 1, i32 0>
435 %t2 = shufflevector <2 x float> %v2, <2 x float> poison, <2 x i32> <i32 1, i32 0>
436 %r = fadd <2 x float> %t1, %t2
437 call void @use(<2 x float> %t1)
441 define <2 x float> @shuffle_fdiv_multiuse(<2 x float> %v1, <2 x float> %v2) {
442 ; CHECK-LABEL: @shuffle_fdiv_multiuse(
443 ; CHECK-NEXT: [[T2:%.*]] = shufflevector <2 x float> [[V2:%.*]], <2 x float> poison, <2 x i32> <i32 1, i32 0>
444 ; CHECK-NEXT: [[TMP1:%.*]] = fdiv <2 x float> [[V1:%.*]], [[V2]]
445 ; CHECK-NEXT: [[R:%.*]] = shufflevector <2 x float> [[TMP1]], <2 x float> poison, <2 x i32> <i32 1, i32 0>
446 ; CHECK-NEXT: call void @use(<2 x float> [[T2]])
447 ; CHECK-NEXT: ret <2 x float> [[R]]
449 %t1 = shufflevector <2 x float> %v1, <2 x float> poison, <2 x i32> <i32 1, i32 0>
450 %t2 = shufflevector <2 x float> %v2, <2 x float> poison, <2 x i32> <i32 1, i32 0>
451 %r = fdiv <2 x float> %t1, %t2
452 call void @use(<2 x float> %t2)
456 ; But 2 extra uses would require an extra instruction.
458 define <2 x float> @shuffle_fsub_multiuse(<2 x float> %v1, <2 x float> %v2) {
459 ; CHECK-LABEL: @shuffle_fsub_multiuse(
460 ; CHECK-NEXT: [[T1:%.*]] = shufflevector <2 x float> [[V1:%.*]], <2 x float> poison, <2 x i32> <i32 1, i32 0>
461 ; CHECK-NEXT: [[T2:%.*]] = shufflevector <2 x float> [[V2:%.*]], <2 x float> poison, <2 x i32> <i32 1, i32 0>
462 ; CHECK-NEXT: [[R:%.*]] = fsub <2 x float> [[T1]], [[T2]]
463 ; CHECK-NEXT: call void @use(<2 x float> [[T1]])
464 ; CHECK-NEXT: call void @use(<2 x float> [[T2]])
465 ; CHECK-NEXT: ret <2 x float> [[R]]
467 %t1 = shufflevector <2 x float> %v1, <2 x float> poison, <2 x i32> <i32 1, i32 0>
468 %t2 = shufflevector <2 x float> %v2, <2 x float> poison, <2 x i32> <i32 1, i32 0>
469 %r = fsub <2 x float> %t1, %t2
470 call void @use(<2 x float> %t1)
471 call void @use(<2 x float> %t2)
475 define <4 x i32> @shuffle_17add(<4 x i32> %v1, <4 x i32> %v2) {
476 ; CHECK-LABEL: @shuffle_17add(
477 ; CHECK-NEXT: [[TMP1:%.*]] = add <4 x i32> [[V1:%.*]], [[V2:%.*]]
478 ; CHECK-NEXT: [[R:%.*]] = shufflevector <4 x i32> [[TMP1]], <4 x i32> poison, <4 x i32> <i32 1, i32 2, i32 3, i32 0>
479 ; CHECK-NEXT: ret <4 x i32> [[R]]
481 %t1 = shufflevector <4 x i32> %v1, <4 x i32> zeroinitializer, <4 x i32> <i32 1, i32 2, i32 3, i32 0>
482 %t2 = shufflevector <4 x i32> %v2, <4 x i32> zeroinitializer, <4 x i32> <i32 1, i32 2, i32 3, i32 0>
483 %r = add <4 x i32> %t1, %t2
487 define <4 x i32> @shuffle_17addnsw(<4 x i32> %v1, <4 x i32> %v2) {
488 ; CHECK-LABEL: @shuffle_17addnsw(
489 ; CHECK-NEXT: [[TMP1:%.*]] = add nsw <4 x i32> [[V1:%.*]], [[V2:%.*]]
490 ; CHECK-NEXT: [[R:%.*]] = shufflevector <4 x i32> [[TMP1]], <4 x i32> poison, <4 x i32> <i32 1, i32 2, i32 3, i32 0>
491 ; CHECK-NEXT: ret <4 x i32> [[R]]
493 %t1 = shufflevector <4 x i32> %v1, <4 x i32> zeroinitializer, <4 x i32> <i32 1, i32 2, i32 3, i32 0>
494 %t2 = shufflevector <4 x i32> %v2, <4 x i32> zeroinitializer, <4 x i32> <i32 1, i32 2, i32 3, i32 0>
495 %r = add nsw <4 x i32> %t1, %t2
499 define <4 x i32> @shuffle_17addnuw(<4 x i32> %v1, <4 x i32> %v2) {
500 ; CHECK-LABEL: @shuffle_17addnuw(
501 ; CHECK-NEXT: [[TMP1:%.*]] = add nuw <4 x i32> [[V1:%.*]], [[V2:%.*]]
502 ; CHECK-NEXT: [[R:%.*]] = shufflevector <4 x i32> [[TMP1]], <4 x i32> poison, <4 x i32> <i32 1, i32 2, i32 3, i32 0>
503 ; CHECK-NEXT: ret <4 x i32> [[R]]
505 %t1 = shufflevector <4 x i32> %v1, <4 x i32> zeroinitializer, <4 x i32> <i32 1, i32 2, i32 3, i32 0>
506 %t2 = shufflevector <4 x i32> %v2, <4 x i32> zeroinitializer, <4 x i32> <i32 1, i32 2, i32 3, i32 0>
507 %r = add nuw <4 x i32> %t1, %t2
511 define <4 x float> @shuffle_17fsub_fast(<4 x float> %v1, <4 x float> %v2) {
512 ; CHECK-LABEL: @shuffle_17fsub_fast(
513 ; CHECK-NEXT: [[TMP1:%.*]] = fsub fast <4 x float> [[V1:%.*]], [[V2:%.*]]
514 ; CHECK-NEXT: [[R:%.*]] = shufflevector <4 x float> [[TMP1]], <4 x float> poison, <4 x i32> <i32 1, i32 2, i32 3, i32 0>
515 ; CHECK-NEXT: ret <4 x float> [[R]]
517 %t1 = shufflevector <4 x float> %v1, <4 x float> zeroinitializer, <4 x i32> <i32 1, i32 2, i32 3, i32 0>
518 %t2 = shufflevector <4 x float> %v2, <4 x float> zeroinitializer, <4 x i32> <i32 1, i32 2, i32 3, i32 0>
519 %r = fsub fast <4 x float> %t1, %t2
523 define <4 x i32> @add_const(<4 x i32> %v) {
524 ; CHECK-LABEL: @add_const(
525 ; CHECK-NEXT: [[TMP1:%.*]] = add <4 x i32> [[V:%.*]], <i32 44, i32 41, i32 42, i32 43>
526 ; CHECK-NEXT: [[R:%.*]] = shufflevector <4 x i32> [[TMP1]], <4 x i32> poison, <4 x i32> <i32 1, i32 2, i32 3, i32 0>
527 ; CHECK-NEXT: ret <4 x i32> [[R]]
529 %t1 = shufflevector <4 x i32> %v, <4 x i32> poison, <4 x i32> <i32 1, i32 2, i32 3, i32 0>
530 %r = add <4 x i32> %t1, <i32 41, i32 42, i32 43, i32 44>
534 define <4 x i32> @sub_const(<4 x i32> %v) {
535 ; CHECK-LABEL: @sub_const(
536 ; CHECK-NEXT: [[TMP1:%.*]] = sub <4 x i32> <i32 44, i32 43, i32 42, i32 41>, [[V:%.*]]
537 ; CHECK-NEXT: [[R:%.*]] = shufflevector <4 x i32> [[TMP1]], <4 x i32> poison, <4 x i32> <i32 3, i32 2, i32 1, i32 0>
538 ; CHECK-NEXT: ret <4 x i32> [[R]]
540 %t1 = shufflevector <4 x i32> %v, <4 x i32> poison, <4 x i32> <i32 3, i32 2, i32 1, i32 0>
541 %r = sub <4 x i32> <i32 41, i32 42, i32 43, i32 44>, %t1
545 ; Math before shuffle requires an extra shuffle.
547 define <2 x float> @fadd_const_multiuse(<2 x float> %v) {
548 ; CHECK-LABEL: @fadd_const_multiuse(
549 ; CHECK-NEXT: [[T1:%.*]] = shufflevector <2 x float> [[V:%.*]], <2 x float> poison, <2 x i32> <i32 1, i32 0>
550 ; CHECK-NEXT: [[R:%.*]] = fadd <2 x float> [[T1]], <float 4.100000e+01, float 4.200000e+01>
551 ; CHECK-NEXT: call void @use(<2 x float> [[T1]])
552 ; CHECK-NEXT: ret <2 x float> [[R]]
554 %t1 = shufflevector <2 x float> %v, <2 x float> poison, <2 x i32> <i32 1, i32 0>
555 %r = fadd <2 x float> %t1, <float 41.0, float 42.0>
556 call void @use(<2 x float> %t1)
560 ; Math before splat allows replacing constant elements with undef lanes.
562 define <4 x i32> @mul_const_splat(<4 x i32> %v) {
563 ; CHECK-LABEL: @mul_const_splat(
564 ; CHECK-NEXT: [[TMP1:%.*]] = mul <4 x i32> [[V:%.*]], <i32 poison, i32 42, i32 poison, i32 poison>
565 ; CHECK-NEXT: [[R:%.*]] = shufflevector <4 x i32> [[TMP1]], <4 x i32> poison, <4 x i32> <i32 1, i32 1, i32 1, i32 1>
566 ; CHECK-NEXT: ret <4 x i32> [[R]]
568 %t1 = shufflevector <4 x i32> %v, <4 x i32> poison, <4 x i32> <i32 1, i32 1, i32 1, i32 1>
569 %r = mul <4 x i32> <i32 42, i32 42, i32 42, i32 42>, %t1
573 ; Take 2 elements of a vector and shift each of those by a different amount
575 define <4 x i32> @lshr_const_half_splat(<4 x i32> %v) {
576 ; CHECK-LABEL: @lshr_const_half_splat(
577 ; CHECK-NEXT: [[TMP1:%.*]] = lshr <4 x i32> <i32 poison, i32 8, i32 9, i32 poison>, [[V:%.*]]
578 ; CHECK-NEXT: [[R:%.*]] = shufflevector <4 x i32> [[TMP1]], <4 x i32> poison, <4 x i32> <i32 1, i32 1, i32 2, i32 2>
579 ; CHECK-NEXT: ret <4 x i32> [[R]]
581 %t1 = shufflevector <4 x i32> %v, <4 x i32> poison, <4 x i32> <i32 1, i32 1, i32 2, i32 2>
582 %r = lshr <4 x i32> <i32 8, i32 8, i32 9, i32 9>, %t1
586 ; We can't change this because there's no pre-shuffle version of the fmul constant.
588 define <2 x float> @fmul_const_invalid_constant(<2 x float> %v) {
589 ; CHECK-LABEL: @fmul_const_invalid_constant(
590 ; CHECK-NEXT: [[T1:%.*]] = shufflevector <2 x float> [[V:%.*]], <2 x float> poison, <2 x i32> zeroinitializer
591 ; CHECK-NEXT: [[R:%.*]] = fmul <2 x float> [[T1]], <float 4.100000e+01, float 4.200000e+01>
592 ; CHECK-NEXT: ret <2 x float> [[R]]
594 %t1 = shufflevector <2 x float> %v, <2 x float> poison, <2 x i32> <i32 0, i32 0>
595 %r = fmul <2 x float> %t1, <float 41.0, float 42.0>
599 ; Reduce the width of the binop by moving it ahead of a shuffle.
601 define <4 x i8> @widening_shuffle_add_1(<2 x i8> %x) {
602 ; CHECK-LABEL: @widening_shuffle_add_1(
603 ; CHECK-NEXT: [[TMP1:%.*]] = add <2 x i8> [[X:%.*]], <i8 42, i8 43>
604 ; CHECK-NEXT: [[R:%.*]] = shufflevector <2 x i8> [[TMP1]], <2 x i8> poison, <4 x i32> <i32 0, i32 1, i32 poison, i32 poison>
605 ; CHECK-NEXT: ret <4 x i8> [[R]]
607 %widex = shufflevector <2 x i8> %x, <2 x i8> poison, <4 x i32> <i32 0, i32 1, i32 undef, i32 undef>
608 %r = add <4 x i8> %widex, <i8 42, i8 43, i8 44, i8 45>
612 ; Reduce the width of the binop by moving it ahead of a shuffle.
614 define <4 x i8> @widening_shuffle_add_2(<2 x i8> %x) {
615 ; CHECK-LABEL: @widening_shuffle_add_2(
616 ; CHECK-NEXT: [[TMP1:%.*]] = add <2 x i8> [[X:%.*]], <i8 43, i8 42>
617 ; CHECK-NEXT: [[R:%.*]] = shufflevector <2 x i8> [[TMP1]], <2 x i8> poison, <4 x i32> <i32 1, i32 0, i32 poison, i32 poison>
618 ; CHECK-NEXT: ret <4 x i8> [[R]]
620 %widex = shufflevector <2 x i8> %x, <2 x i8> poison, <4 x i32> <i32 1, i32 0, i32 undef, i32 undef>
621 %r = add <4 x i8> %widex, <i8 42, i8 43, i8 44, i8 45>
625 ; Negative test - widening shuffles have the same mask/constant constraint as non-size-changing shuffles.
627 define <4 x i8> @widening_shuffle_add_invalid_constant(<2 x i8> %x) {
628 ; CHECK-LABEL: @widening_shuffle_add_invalid_constant(
629 ; CHECK-NEXT: [[WIDEX:%.*]] = shufflevector <2 x i8> [[X:%.*]], <2 x i8> poison, <4 x i32> <i32 1, i32 1, i32 poison, i32 poison>
630 ; CHECK-NEXT: [[R:%.*]] = add <4 x i8> [[WIDEX]], <i8 42, i8 43, i8 44, i8 45>
631 ; CHECK-NEXT: ret <4 x i8> [[R]]
633 %widex = shufflevector <2 x i8> %x, <2 x i8> poison, <4 x i32> <i32 1, i32 1, i32 undef, i32 undef>
634 %r = add <4 x i8> %widex, <i8 42, i8 43, i8 44, i8 45>
638 ; Negative test - widening shuffles have an additional constraint: they must not extend with anything but undefs.
640 define <4 x i8> @widening_shuffle_add_invalid_mask(<2 x i8> %x) {
641 ; CHECK-LABEL: @widening_shuffle_add_invalid_mask(
642 ; CHECK-NEXT: [[WIDEX:%.*]] = shufflevector <2 x i8> [[X:%.*]], <2 x i8> poison, <4 x i32> <i32 0, i32 1, i32 poison, i32 0>
643 ; CHECK-NEXT: [[R:%.*]] = add <4 x i8> [[WIDEX]], <i8 42, i8 43, i8 44, i8 45>
644 ; CHECK-NEXT: ret <4 x i8> [[R]]
646 %widex = shufflevector <2 x i8> %x, <2 x i8> poison, <4 x i32> <i32 0, i32 1, i32 undef, i32 0>
647 %r = add <4 x i8> %widex, <i8 42, i8 43, i8 44, i8 45>
651 ; A binop that produces undef in the high lanes can be moved before the shuffle.
652 ; This is ok because 'shl C, undef --> undef'.
654 define <4 x i16> @widening_shuffle_shl_constant_op0(<2 x i16> %v) {
655 ; CHECK-LABEL: @widening_shuffle_shl_constant_op0(
656 ; CHECK-NEXT: [[TMP1:%.*]] = shl <2 x i16> <i16 42, i16 -42>, [[V:%.*]]
657 ; CHECK-NEXT: [[BO:%.*]] = shufflevector <2 x i16> [[TMP1]], <2 x i16> poison, <4 x i32> <i32 0, i32 1, i32 poison, i32 poison>
658 ; CHECK-NEXT: ret <4 x i16> [[BO]]
660 %shuf = shufflevector <2 x i16> %v, <2 x i16> poison, <4 x i32> <i32 0, i32 1, i32 undef, i32 undef>
661 %bo = shl <4 x i16> <i16 42, i16 -42, i16 -1, i16 -1>, %shuf
665 ; A binop that produces undef in the high lanes can be moved before the shuffle.
666 ; This is ok because 'shl undef, 0 --> undef'.
668 define <4 x i16> @widening_shuffle_shl_constant_op1(<2 x i16> %v) {
669 ; CHECK-LABEL: @widening_shuffle_shl_constant_op1(
670 ; CHECK-NEXT: [[TMP1:%.*]] = shl <2 x i16> [[V:%.*]], <i16 2, i16 4>
671 ; CHECK-NEXT: [[BO:%.*]] = shufflevector <2 x i16> [[TMP1]], <2 x i16> poison, <4 x i32> <i32 0, i32 1, i32 poison, i32 poison>
672 ; CHECK-NEXT: ret <4 x i16> [[BO]]
674 %shuf = shufflevector <2 x i16> %v, <2 x i16> poison, <4 x i32> <i32 0, i32 1, i32 undef, i32 undef>
675 %bo = shl <4 x i16> %shuf, <i16 2, i16 4, i16 0, i16 0>
679 ; This is valid for poison, but would not be valid for undef.
681 define <4 x i16> @widening_shuffle_shl_constant_op1_non0(<2 x i16> %v) {
682 ; CHECK-LABEL: @widening_shuffle_shl_constant_op1_non0(
683 ; CHECK-NEXT: [[TMP1:%.*]] = shl <2 x i16> [[V:%.*]], <i16 2, i16 4>
684 ; CHECK-NEXT: [[BO:%.*]] = shufflevector <2 x i16> [[TMP1]], <2 x i16> poison, <4 x i32> <i32 0, i32 1, i32 poison, i32 poison>
685 ; CHECK-NEXT: ret <4 x i16> [[BO]]
687 %shuf = shufflevector <2 x i16> %v, <2 x i16> poison, <4 x i32> <i32 0, i32 1, i32 undef, i32 undef>
688 %bo = shl <4 x i16> %shuf, <i16 2, i16 4, i16 1, i16 2>
692 define <4 x i16> @widening_shuffle_or(<2 x i16> %v) {
693 ; CHECK-LABEL: @widening_shuffle_or(
694 ; CHECK-NEXT: [[TMP1:%.*]] = or <2 x i16> [[V:%.*]], <i16 42, i16 -42>
695 ; CHECK-NEXT: [[BO:%.*]] = shufflevector <2 x i16> [[TMP1]], <2 x i16> poison, <4 x i32> <i32 0, i32 1, i32 poison, i32 poison>
696 ; CHECK-NEXT: ret <4 x i16> [[BO]]
698 %shuf = shufflevector <2 x i16> %v, <2 x i16> poison, <4 x i32> <i32 0, i32 1, i32 undef, i32 undef>
699 %bo = or <4 x i16> %shuf, <i16 42, i16 -42, i16 -1, i16 -1>
703 define <4 x i32> @shuffle_17add2(<4 x i32> %v) {
704 ; CHECK-LABEL: @shuffle_17add2(
705 ; CHECK-NEXT: [[TMP1:%.*]] = shl <4 x i32> [[V:%.*]], splat (i32 1)
706 ; CHECK-NEXT: ret <4 x i32> [[TMP1]]
708 %t1 = shufflevector <4 x i32> %v, <4 x i32> zeroinitializer, <4 x i32> <i32 3, i32 2, i32 1, i32 0>
709 %t2 = add <4 x i32> %t1, %t1
710 %r = shufflevector <4 x i32> %t2, <4 x i32> zeroinitializer, <4 x i32> <i32 3, i32 2, i32 1, i32 0>
714 define <4 x i32> @shuffle_17mulsplat(<4 x i32> %v) {
715 ; CHECK-LABEL: @shuffle_17mulsplat(
716 ; CHECK-NEXT: [[TMP1:%.*]] = mul <4 x i32> [[V:%.*]], [[V]]
717 ; CHECK-NEXT: [[M1:%.*]] = shufflevector <4 x i32> [[TMP1]], <4 x i32> poison, <4 x i32> zeroinitializer
718 ; CHECK-NEXT: ret <4 x i32> [[M1]]
720 %s1 = shufflevector <4 x i32> %v, <4 x i32> zeroinitializer, <4 x i32> zeroinitializer
721 %m1 = mul <4 x i32> %s1, %s1
722 %s2 = shufflevector <4 x i32> %m1, <4 x i32> zeroinitializer, <4 x i32> <i32 1, i32 1, i32 1, i32 1>
726 ; Do not reorder shuffle and binop if LHS of shuffles are of different size
727 define <2 x i32> @pr19717(<4 x i32> %in0, <2 x i32> %in1) {
728 ; CHECK-LABEL: @pr19717(
729 ; CHECK-NEXT: [[SHUFFLE:%.*]] = shufflevector <4 x i32> [[IN0:%.*]], <4 x i32> poison, <2 x i32> zeroinitializer
730 ; CHECK-NEXT: [[SHUFFLE4:%.*]] = shufflevector <2 x i32> [[IN1:%.*]], <2 x i32> poison, <2 x i32> zeroinitializer
731 ; CHECK-NEXT: [[MUL:%.*]] = mul <2 x i32> [[SHUFFLE]], [[SHUFFLE4]]
732 ; CHECK-NEXT: ret <2 x i32> [[MUL]]
734 %shuffle = shufflevector <4 x i32> %in0, <4 x i32> %in0, <2 x i32> zeroinitializer
735 %shuffle4 = shufflevector <2 x i32> %in1, <2 x i32> %in1, <2 x i32> zeroinitializer
736 %mul = mul <2 x i32> %shuffle, %shuffle4
740 define <4 x i16> @pr19717a(<8 x i16> %in0, <8 x i16> %in1) {
741 ; CHECK-LABEL: @pr19717a(
742 ; CHECK-NEXT: [[TMP1:%.*]] = mul <8 x i16> [[IN0:%.*]], [[IN1:%.*]]
743 ; CHECK-NEXT: [[MUL:%.*]] = shufflevector <8 x i16> [[TMP1]], <8 x i16> poison, <4 x i32> <i32 5, i32 5, i32 5, i32 5>
744 ; CHECK-NEXT: ret <4 x i16> [[MUL]]
746 %shuffle = shufflevector <8 x i16> %in0, <8 x i16> %in0, <4 x i32> <i32 5, i32 5, i32 5, i32 5>
747 %shuffle1 = shufflevector <8 x i16> %in1, <8 x i16> %in1, <4 x i32> <i32 5, i32 5, i32 5, i32 5>
748 %mul = mul <4 x i16> %shuffle, %shuffle1
752 define <8 x i8> @pr19730(<16 x i8> %in0) {
753 ; CHECK-LABEL: @pr19730(
754 ; 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>
755 ; 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>
756 ; CHECK-NEXT: ret <8 x i8> [[SHUFFLE1]]
758 %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>
759 %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>
760 ret <8 x i8> %shuffle1
763 define i32 @pr19737(<4 x i32> %in0) {
764 ; CHECK-LABEL: @pr19737(
765 ; CHECK-NEXT: [[TMP1:%.*]] = extractelement <4 x i32> [[IN0:%.*]], i64 0
766 ; CHECK-NEXT: ret i32 [[TMP1]]
768 %shuffle.i = shufflevector <4 x i32> zeroinitializer, <4 x i32> %in0, <4 x i32> <i32 0, i32 4, i32 2, i32 6>
769 %neg.i = xor <4 x i32> %shuffle.i, <i32 -1, i32 -1, i32 -1, i32 -1>
770 %and.i = and <4 x i32> %in0, %neg.i
771 %rv = extractelement <4 x i32> %and.i, i32 0
775 ; In PR20059 ( http://llvm.org/pr20059 ), shufflevector operations are reordered/removed
776 ; for an srem operation. This is not a valid optimization because it may cause a trap
779 define <4 x i32> @pr20059(<4 x i32> %p1, <4 x i32> %p2) {
780 ; CHECK-LABEL: @pr20059(
781 ; CHECK-NEXT: [[SPLAT1:%.*]] = shufflevector <4 x i32> [[P1:%.*]], <4 x i32> poison, <4 x i32> zeroinitializer
782 ; CHECK-NEXT: [[SPLAT2:%.*]] = shufflevector <4 x i32> [[P2:%.*]], <4 x i32> poison, <4 x i32> zeroinitializer
783 ; CHECK-NEXT: [[RETVAL:%.*]] = srem <4 x i32> [[SPLAT1]], [[SPLAT2]]
784 ; CHECK-NEXT: ret <4 x i32> [[RETVAL]]
786 %splat1 = shufflevector <4 x i32> %p1, <4 x i32> poison, <4 x i32> zeroinitializer
787 %splat2 = shufflevector <4 x i32> %p2, <4 x i32> poison, <4 x i32> zeroinitializer
788 %retval = srem <4 x i32> %splat1, %splat2
789 ret <4 x i32> %retval
792 define <4 x i32> @pr20114(<4 x i32> %__mask) {
793 ; CHECK-LABEL: @pr20114(
794 ; CHECK-NEXT: [[MASK01_I:%.*]] = shufflevector <4 x i32> [[__MASK:%.*]], <4 x i32> poison, <4 x i32> <i32 0, i32 0, i32 1, i32 1>
795 ; 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>)
796 ; CHECK-NEXT: ret <4 x i32> [[MASKED_NEW_I_I_I]]
798 %mask01.i = shufflevector <4 x i32> %__mask, <4 x i32> poison, <4 x i32> <i32 0, i32 0, i32 1, i32 1>
799 %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
800 ret <4 x i32> %masked_new.i.i.i
803 define <2 x ptr> @pr23113(<4 x ptr> %A) {
804 ; CHECK-LABEL: @pr23113(
805 ; CHECK-NEXT: [[TMP1:%.*]] = shufflevector <4 x ptr> [[A:%.*]], <4 x ptr> poison, <2 x i32> <i32 0, i32 1>
806 ; CHECK-NEXT: ret <2 x ptr> [[TMP1]]
808 %1 = shufflevector <4 x ptr> %A, <4 x ptr> poison, <2 x i32> <i32 0, i32 1>
812 ; Unused lanes in the new binop should not kill the entire op (although it may simplify anyway as shown here).
814 define <2 x i32> @PR37648(<2 x i32> %x) {
815 ; CHECK-LABEL: @PR37648(
816 ; CHECK-NEXT: ret <2 x i32> zeroinitializer
818 %splat = shufflevector <2 x i32> %x, <2 x i32> poison, <2 x i32> zeroinitializer
819 %r = urem <2 x i32> %splat, <i32 1, i32 1>
823 ; Test shuffle followed by binop with splat constant for all 18 binop opcodes.
824 ; Test with constant as operand 0 and operand 1 for non-commutative opcodes.
826 define <2 x i32> @add_splat_constant(<2 x i32> %x) {
827 ; CHECK-LABEL: @add_splat_constant(
828 ; CHECK-NEXT: [[TMP1:%.*]] = add <2 x i32> [[X:%.*]], <i32 42, i32 poison>
829 ; CHECK-NEXT: [[R:%.*]] = shufflevector <2 x i32> [[TMP1]], <2 x i32> poison, <2 x i32> zeroinitializer
830 ; CHECK-NEXT: ret <2 x i32> [[R]]
832 %splat = shufflevector <2 x i32> %x, <2 x i32> poison, <2 x i32> zeroinitializer
833 %r = add <2 x i32> %splat, <i32 42, i32 42>
837 define <2 x i32> @sub_splat_constant0(<2 x i32> %x) {
838 ; CHECK-LABEL: @sub_splat_constant0(
839 ; CHECK-NEXT: [[TMP1:%.*]] = sub <2 x i32> <i32 42, i32 poison>, [[X:%.*]]
840 ; CHECK-NEXT: [[R:%.*]] = shufflevector <2 x i32> [[TMP1]], <2 x i32> poison, <2 x i32> zeroinitializer
841 ; CHECK-NEXT: ret <2 x i32> [[R]]
843 %splat = shufflevector <2 x i32> %x, <2 x i32> poison, <2 x i32> zeroinitializer
844 %r = sub <2 x i32> <i32 42, i32 42>, %splat
848 define <2 x i32> @sub_splat_constant1(<2 x i32> %x) {
849 ; CHECK-LABEL: @sub_splat_constant1(
850 ; CHECK-NEXT: [[TMP1:%.*]] = add <2 x i32> [[X:%.*]], <i32 -42, i32 poison>
851 ; CHECK-NEXT: [[R:%.*]] = shufflevector <2 x i32> [[TMP1]], <2 x i32> poison, <2 x i32> zeroinitializer
852 ; CHECK-NEXT: ret <2 x i32> [[R]]
854 %splat = shufflevector <2 x i32> %x, <2 x i32> poison, <2 x i32> zeroinitializer
855 %r = sub <2 x i32> %splat, <i32 42, i32 42>
859 define <2 x i32> @mul_splat_constant(<2 x i32> %x) {
860 ; CHECK-LABEL: @mul_splat_constant(
861 ; CHECK-NEXT: [[TMP1:%.*]] = mul <2 x i32> [[X:%.*]], <i32 42, i32 poison>
862 ; CHECK-NEXT: [[R:%.*]] = shufflevector <2 x i32> [[TMP1]], <2 x i32> poison, <2 x i32> zeroinitializer
863 ; CHECK-NEXT: ret <2 x i32> [[R]]
865 %splat = shufflevector <2 x i32> %x, <2 x i32> poison, <2 x i32> zeroinitializer
866 %r = mul <2 x i32> %splat, <i32 42, i32 42>
870 define <2 x i32> @shl_splat_constant0(<2 x i32> %x) {
871 ; CHECK-LABEL: @shl_splat_constant0(
872 ; CHECK-NEXT: [[TMP1:%.*]] = shl <2 x i32> <i32 5, i32 poison>, [[X:%.*]]
873 ; CHECK-NEXT: [[R:%.*]] = shufflevector <2 x i32> [[TMP1]], <2 x i32> poison, <2 x i32> zeroinitializer
874 ; CHECK-NEXT: ret <2 x i32> [[R]]
876 %splat = shufflevector <2 x i32> %x, <2 x i32> poison, <2 x i32> zeroinitializer
877 %r = shl <2 x i32> <i32 5, i32 5>, %splat
881 define <2 x i32> @shl_splat_constant1(<2 x i32> %x) {
882 ; CHECK-LABEL: @shl_splat_constant1(
883 ; CHECK-NEXT: [[TMP1:%.*]] = shl <2 x i32> [[X:%.*]], <i32 5, i32 0>
884 ; CHECK-NEXT: [[R:%.*]] = shufflevector <2 x i32> [[TMP1]], <2 x i32> poison, <2 x i32> zeroinitializer
885 ; CHECK-NEXT: ret <2 x i32> [[R]]
887 %splat = shufflevector <2 x i32> %x, <2 x i32> poison, <2 x i32> zeroinitializer
888 %r = shl <2 x i32> %splat, <i32 5, i32 5>
892 define <2 x i32> @ashr_splat_constant0(<2 x i32> %x) {
893 ; CHECK-LABEL: @ashr_splat_constant0(
894 ; CHECK-NEXT: [[TMP1:%.*]] = lshr <2 x i32> <i32 5, i32 poison>, [[X:%.*]]
895 ; CHECK-NEXT: [[R:%.*]] = shufflevector <2 x i32> [[TMP1]], <2 x i32> poison, <2 x i32> zeroinitializer
896 ; CHECK-NEXT: ret <2 x i32> [[R]]
898 %splat = shufflevector <2 x i32> %x, <2 x i32> poison, <2 x i32> zeroinitializer
899 %r = ashr <2 x i32> <i32 5, i32 5>, %splat
903 define <2 x i32> @ashr_splat_constant1(<2 x i32> %x) {
904 ; CHECK-LABEL: @ashr_splat_constant1(
905 ; CHECK-NEXT: [[TMP1:%.*]] = ashr <2 x i32> [[X:%.*]], <i32 5, i32 0>
906 ; CHECK-NEXT: [[R:%.*]] = shufflevector <2 x i32> [[TMP1]], <2 x i32> poison, <2 x i32> zeroinitializer
907 ; CHECK-NEXT: ret <2 x i32> [[R]]
909 %splat = shufflevector <2 x i32> %x, <2 x i32> poison, <2 x i32> zeroinitializer
910 %r = ashr <2 x i32> %splat, <i32 5, i32 5>
914 define <2 x i32> @lshr_splat_constant0(<2 x i32> %x) {
915 ; CHECK-LABEL: @lshr_splat_constant0(
916 ; CHECK-NEXT: [[TMP1:%.*]] = lshr <2 x i32> <i32 5, i32 poison>, [[X:%.*]]
917 ; CHECK-NEXT: [[R:%.*]] = shufflevector <2 x i32> [[TMP1]], <2 x i32> poison, <2 x i32> zeroinitializer
918 ; CHECK-NEXT: ret <2 x i32> [[R]]
920 %splat = shufflevector <2 x i32> %x, <2 x i32> poison, <2 x i32> zeroinitializer
921 %r = lshr <2 x i32> <i32 5, i32 5>, %splat
925 define <2 x i32> @lshr_splat_constant1(<2 x i32> %x) {
926 ; CHECK-LABEL: @lshr_splat_constant1(
927 ; CHECK-NEXT: [[TMP1:%.*]] = lshr <2 x i32> [[X:%.*]], <i32 5, i32 0>
928 ; CHECK-NEXT: [[R:%.*]] = shufflevector <2 x i32> [[TMP1]], <2 x i32> poison, <2 x i32> zeroinitializer
929 ; CHECK-NEXT: ret <2 x i32> [[R]]
931 %splat = shufflevector <2 x i32> %x, <2 x i32> poison, <2 x i32> zeroinitializer
932 %r = lshr <2 x i32> %splat, <i32 5, i32 5>
936 define <2 x i32> @urem_splat_constant0(<2 x i32> %x) {
937 ; CHECK-LABEL: @urem_splat_constant0(
938 ; CHECK-NEXT: [[SPLAT:%.*]] = shufflevector <2 x i32> [[X:%.*]], <2 x i32> poison, <2 x i32> zeroinitializer
939 ; CHECK-NEXT: [[R:%.*]] = urem <2 x i32> splat (i32 42), [[SPLAT]]
940 ; CHECK-NEXT: ret <2 x i32> [[R]]
942 %splat = shufflevector <2 x i32> %x, <2 x i32> poison, <2 x i32> zeroinitializer
943 %r = urem <2 x i32> <i32 42, i32 42>, %splat
947 define <2 x i32> @urem_splat_constant1(<2 x i32> %x) {
948 ; CHECK-LABEL: @urem_splat_constant1(
949 ; CHECK-NEXT: [[TMP1:%.*]] = urem <2 x i32> [[X:%.*]], <i32 42, i32 1>
950 ; CHECK-NEXT: [[R:%.*]] = shufflevector <2 x i32> [[TMP1]], <2 x i32> poison, <2 x i32> zeroinitializer
951 ; CHECK-NEXT: ret <2 x i32> [[R]]
953 %splat = shufflevector <2 x i32> %x, <2 x i32> poison, <2 x i32> zeroinitializer
954 %r = urem <2 x i32> %splat, <i32 42, i32 42>
958 define <2 x i32> @srem_splat_constant0(<2 x i32> %x) {
959 ; CHECK-LABEL: @srem_splat_constant0(
960 ; CHECK-NEXT: [[SPLAT:%.*]] = shufflevector <2 x i32> [[X:%.*]], <2 x i32> poison, <2 x i32> zeroinitializer
961 ; CHECK-NEXT: [[R:%.*]] = srem <2 x i32> splat (i32 42), [[SPLAT]]
962 ; CHECK-NEXT: ret <2 x i32> [[R]]
964 %splat = shufflevector <2 x i32> %x, <2 x i32> poison, <2 x i32> zeroinitializer
965 %r = srem <2 x i32> <i32 42, i32 42>, %splat
969 define <2 x i32> @srem_splat_constant1(<2 x i32> %x) {
970 ; CHECK-LABEL: @srem_splat_constant1(
971 ; CHECK-NEXT: [[TMP1:%.*]] = srem <2 x i32> [[X:%.*]], <i32 42, i32 1>
972 ; CHECK-NEXT: [[R:%.*]] = shufflevector <2 x i32> [[TMP1]], <2 x i32> poison, <2 x i32> zeroinitializer
973 ; CHECK-NEXT: ret <2 x i32> [[R]]
975 %splat = shufflevector <2 x i32> %x, <2 x i32> poison, <2 x i32> zeroinitializer
976 %r = srem <2 x i32> %splat, <i32 42, i32 42>
980 define <2 x i32> @udiv_splat_constant0(<2 x i32> %x) {
981 ; CHECK-LABEL: @udiv_splat_constant0(
982 ; CHECK-NEXT: [[SPLAT:%.*]] = shufflevector <2 x i32> [[X:%.*]], <2 x i32> poison, <2 x i32> zeroinitializer
983 ; CHECK-NEXT: [[R:%.*]] = udiv <2 x i32> splat (i32 42), [[SPLAT]]
984 ; CHECK-NEXT: ret <2 x i32> [[R]]
986 %splat = shufflevector <2 x i32> %x, <2 x i32> poison, <2 x i32> zeroinitializer
987 %r = udiv <2 x i32> <i32 42, i32 42>, %splat
991 define <2 x i32> @udiv_splat_constant1(<2 x i32> %x) {
992 ; CHECK-LABEL: @udiv_splat_constant1(
993 ; CHECK-NEXT: [[TMP1:%.*]] = udiv <2 x i32> [[X:%.*]], <i32 42, i32 1>
994 ; CHECK-NEXT: [[R:%.*]] = shufflevector <2 x i32> [[TMP1]], <2 x i32> poison, <2 x i32> zeroinitializer
995 ; CHECK-NEXT: ret <2 x i32> [[R]]
997 %splat = shufflevector <2 x i32> %x, <2 x i32> poison, <2 x i32> zeroinitializer
998 %r = udiv <2 x i32> %splat, <i32 42, i32 42>
1002 define <2 x i32> @sdiv_splat_constant0(<2 x i32> %x) {
1003 ; CHECK-LABEL: @sdiv_splat_constant0(
1004 ; CHECK-NEXT: [[SPLAT:%.*]] = shufflevector <2 x i32> [[X:%.*]], <2 x i32> poison, <2 x i32> zeroinitializer
1005 ; CHECK-NEXT: [[R:%.*]] = sdiv <2 x i32> splat (i32 42), [[SPLAT]]
1006 ; CHECK-NEXT: ret <2 x i32> [[R]]
1008 %splat = shufflevector <2 x i32> %x, <2 x i32> poison, <2 x i32> zeroinitializer
1009 %r = sdiv <2 x i32> <i32 42, i32 42>, %splat
1013 define <2 x i32> @sdiv_splat_constant1(<2 x i32> %x) {
1014 ; CHECK-LABEL: @sdiv_splat_constant1(
1015 ; CHECK-NEXT: [[TMP1:%.*]] = sdiv <2 x i32> [[X:%.*]], <i32 42, i32 1>
1016 ; CHECK-NEXT: [[R:%.*]] = shufflevector <2 x i32> [[TMP1]], <2 x i32> poison, <2 x i32> zeroinitializer
1017 ; CHECK-NEXT: ret <2 x i32> [[R]]
1019 %splat = shufflevector <2 x i32> %x, <2 x i32> poison, <2 x i32> zeroinitializer
1020 %r = sdiv <2 x i32> %splat, <i32 42, i32 42>
1024 define <2 x i32> @and_splat_constant(<2 x i32> %x) {
1025 ; CHECK-LABEL: @and_splat_constant(
1026 ; CHECK-NEXT: [[TMP1:%.*]] = and <2 x i32> [[X:%.*]], <i32 42, i32 poison>
1027 ; CHECK-NEXT: [[R:%.*]] = shufflevector <2 x i32> [[TMP1]], <2 x i32> poison, <2 x i32> zeroinitializer
1028 ; CHECK-NEXT: ret <2 x i32> [[R]]
1030 %splat = shufflevector <2 x i32> %x, <2 x i32> poison, <2 x i32> zeroinitializer
1031 %r = and <2 x i32> %splat, <i32 42, i32 42>
1035 define <4 x i16> @and_constant_mask_poison(<4 x i16> %add) {
1036 ; CHECK-LABEL: @and_constant_mask_poison(
1037 ; CHECK-NEXT: entry:
1038 ; CHECK-NEXT: [[AND:%.*]] = shufflevector <4 x i16> [[ADD:%.*]], <4 x i16> poison, <4 x i32> <i32 poison, i32 poison, i32 1, i32 1>
1039 ; CHECK-NEXT: ret <4 x i16> [[AND]]
1042 %shuffle = shufflevector <4 x i16> %add, <4 x i16> poison, <4 x i32> <i32 undef, i32 undef, i32 1, i32 1>
1043 %and = and <4 x i16> %shuffle, <i16 0, i16 0, i16 -1, i16 -1>
1047 define <4 x i16> @and_constant_mask_poison_2(<4 x i16> %add) {
1048 ; CHECK-LABEL: @and_constant_mask_poison_2(
1049 ; CHECK-NEXT: entry:
1050 ; CHECK-NEXT: [[AND:%.*]] = shufflevector <4 x i16> [[ADD:%.*]], <4 x i16> poison, <4 x i32> <i32 1, i32 1, i32 1, i32 poison>
1051 ; CHECK-NEXT: ret <4 x i16> [[AND]]
1054 %shuffle = shufflevector <4 x i16> %add, <4 x i16> poison, <4 x i32> <i32 1, i32 1, i32 1, i32 undef>
1055 %and = and <4 x i16> %shuffle, <i16 -1, i16 -1, i16 -1, i16 -0>
1059 ; We can move the AND across the shuffle, as -1 (AND identity value) is used for undef lanes.
1060 define <4 x i16> @and_constant_mask_poison_3(<4 x i16> %add) {
1061 ; CHECK-LABEL: @and_constant_mask_poison_3(
1062 ; CHECK-NEXT: entry:
1063 ; CHECK-NEXT: ret <4 x i16> <i16 0, i16 0, i16 0, i16 undef>
1066 %shuffle = shufflevector <4 x i16> %add, <4 x i16> poison, <4 x i32> <i32 0, i32 1, i32 1, i32 undef>
1067 %and = and <4 x i16> %shuffle, <i16 0, i16 0, i16 0, i16 -1>
1071 ; We can move the AND across the shuffle, as -1 (AND identity value) is used for undef lanes.
1072 define <4 x i16> @and_constant_mask_poison_4(<4 x i16> %add) {
1073 ; CHECK-LABEL: @and_constant_mask_poison_4(
1074 ; CHECK-NEXT: entry:
1075 ; CHECK-NEXT: [[TMP0:%.*]] = and <4 x i16> [[ADD:%.*]], <i16 9, i16 20, i16 poison, i16 poison>
1076 ; CHECK-NEXT: [[AND:%.*]] = shufflevector <4 x i16> [[TMP0]], <4 x i16> poison, <4 x i32> <i32 0, i32 1, i32 1, i32 poison>
1077 ; CHECK-NEXT: ret <4 x i16> [[AND]]
1080 %shuffle = shufflevector <4 x i16> %add, <4 x i16> poison, <4 x i32> <i32 0, i32 1, i32 1, i32 undef>
1081 %and = and <4 x i16> %shuffle, <i16 9, i16 20, i16 20, i16 -1>
1085 define <4 x i16> @and_constant_mask_not_undef(<4 x i16> %add) {
1086 ; CHECK-LABEL: @and_constant_mask_not_undef(
1087 ; CHECK-NEXT: entry:
1088 ; CHECK-NEXT: [[TMP0:%.*]] = and <4 x i16> [[ADD:%.*]], <i16 poison, i16 -1, i16 0, i16 0>
1089 ; CHECK-NEXT: [[AND:%.*]] = shufflevector <4 x i16> [[TMP0]], <4 x i16> poison, <4 x i32> <i32 2, i32 3, i32 1, i32 1>
1090 ; CHECK-NEXT: ret <4 x i16> [[AND]]
1093 %shuffle = shufflevector <4 x i16> %add, <4 x i16> poison, <4 x i32> <i32 2, i32 3, i32 1, i32 1>
1094 %and = and <4 x i16> %shuffle, <i16 0, i16 0, i16 -1, i16 -1>
1098 define <4 x i16> @or_constant_mask_poison(<4 x i16> %in) {
1099 ; CHECK-LABEL: @or_constant_mask_poison(
1100 ; CHECK-NEXT: entry:
1101 ; CHECK-NEXT: [[OR:%.*]] = shufflevector <4 x i16> [[IN:%.*]], <4 x i16> poison, <4 x i32> <i32 poison, i32 poison, i32 1, i32 1>
1102 ; CHECK-NEXT: ret <4 x i16> [[OR]]
1105 %shuffle = shufflevector <4 x i16> %in, <4 x i16> poison, <4 x i32> <i32 undef, i32 undef, i32 1, i32 1>
1106 %or = or <4 x i16> %shuffle, <i16 -1, i16 -1, i16 0, i16 0>
1110 define <4 x i16> @or_constant_mask_poison_2(<4 x i16> %in) {
1111 ; CHECK-LABEL: @or_constant_mask_poison_2(
1112 ; CHECK-NEXT: entry:
1113 ; CHECK-NEXT: [[OR:%.*]] = shufflevector <4 x i16> [[IN:%.*]], <4 x i16> poison, <4 x i32> <i32 poison, i32 1, i32 1, i32 poison>
1114 ; CHECK-NEXT: ret <4 x i16> [[OR]]
1117 %shuffle = shufflevector <4 x i16> %in, <4 x i16> poison, <4 x i32> <i32 undef, i32 1, i32 1, i32 undef>
1118 %or = or <4 x i16> %shuffle, <i16 -1, i16 0, i16 0, i16 -1>
1122 ; We can move the OR across the shuffle, as 0 (OR identity value) is used for undef lanes.
1123 define <4 x i16> @or_constant_mask_poison_3(<4 x i16> %in) {
1124 ; CHECK-LABEL: @or_constant_mask_poison_3(
1125 ; CHECK-NEXT: entry:
1126 ; CHECK-NEXT: ret <4 x i16> <i16 undef, i16 -1, i16 -1, i16 undef>
1129 %shuffle = shufflevector <4 x i16> %in, <4 x i16> poison, <4 x i32> <i32 undef, i32 1, i32 1, i32 undef>
1130 %or = or <4 x i16> %shuffle, <i16 0, i16 -1, i16 -1, i16 0>
1134 ; We can move the OR across the shuffle, as 0 (OR identity value) is used for undef lanes.
1135 define <4 x i16> @or_constant_mask_poison_4(<4 x i16> %in) {
1136 ; CHECK-LABEL: @or_constant_mask_poison_4(
1137 ; CHECK-NEXT: entry:
1138 ; CHECK-NEXT: [[TMP0:%.*]] = or <4 x i16> [[IN:%.*]], <i16 poison, i16 99, i16 poison, i16 poison>
1139 ; CHECK-NEXT: [[OR:%.*]] = shufflevector <4 x i16> [[TMP0]], <4 x i16> poison, <4 x i32> <i32 poison, i32 1, i32 1, i32 poison>
1140 ; CHECK-NEXT: ret <4 x i16> [[OR]]
1143 %shuffle = shufflevector <4 x i16> %in, <4 x i16> poison, <4 x i32> <i32 undef, i32 1, i32 1, i32 undef>
1144 %or = or <4 x i16> %shuffle, <i16 0, i16 99, i16 99, i16 0>
1148 define <4 x i16> @or_constant_mask_not_undef(<4 x i16> %in) {
1149 ; CHECK-LABEL: @or_constant_mask_not_undef(
1150 ; CHECK-NEXT: entry:
1151 ; CHECK-NEXT: [[TMP0:%.*]] = or <4 x i16> [[IN:%.*]], <i16 poison, i16 -1, i16 0, i16 0>
1152 ; CHECK-NEXT: [[AND:%.*]] = shufflevector <4 x i16> [[TMP0]], <4 x i16> poison, <4 x i32> <i32 2, i32 3, i32 1, i32 1>
1153 ; CHECK-NEXT: ret <4 x i16> [[AND]]
1156 %shuffle = shufflevector <4 x i16> %in, <4 x i16> poison, <4 x i32> <i32 2, i32 3, i32 1, i32 1>
1157 %and = or <4 x i16> %shuffle, <i16 0, i16 0, i16 -1, i16 -1>
1161 define <4 x i16> @shl_constant_mask_undef(<4 x i16> %in) {
1162 ; CHECK-LABEL: @shl_constant_mask_undef(
1163 ; CHECK-NEXT: entry:
1164 ; CHECK-NEXT: [[TMP0:%.*]] = shl <4 x i16> [[IN:%.*]], <i16 10, i16 0, i16 0, i16 0>
1165 ; CHECK-NEXT: [[SHL:%.*]] = shufflevector <4 x i16> [[TMP0]], <4 x i16> poison, <4 x i32> <i32 0, i32 poison, i32 1, i32 1>
1166 ; CHECK-NEXT: ret <4 x i16> [[SHL]]
1169 %shuffle = shufflevector <4 x i16> %in, <4 x i16> poison, <4 x i32> <i32 0, i32 undef, i32 1, i32 1>
1170 %shl = shl <4 x i16> %shuffle, <i16 10, i16 3, i16 0, i16 0>
1174 define <4 x i16> @add_constant_mask_undef(<4 x i16> %in) {
1175 ; CHECK-LABEL: @add_constant_mask_undef(
1176 ; CHECK-NEXT: entry:
1177 ; CHECK-NEXT: [[ADD:%.*]] = shufflevector <4 x i16> [[IN:%.*]], <4 x i16> poison, <4 x i32> <i32 poison, i32 poison, i32 1, i32 1>
1178 ; CHECK-NEXT: ret <4 x i16> [[ADD]]
1181 %shuffle = shufflevector <4 x i16> %in, <4 x i16> poison, <4 x i32> <i32 undef, i32 undef, i32 1, i32 1>
1182 %add = add <4 x i16> %shuffle, <i16 10, i16 3, i16 0, i16 0>
1186 define <4 x i16> @add_constant_mask_undef_2(<4 x i16> %in) {
1187 ; CHECK-LABEL: @add_constant_mask_undef_2(
1188 ; CHECK-NEXT: entry:
1189 ; CHECK-NEXT: [[TMP0:%.*]] = add <4 x i16> [[IN:%.*]], <i16 poison, i16 0, i16 3, i16 poison>
1190 ; CHECK-NEXT: [[ADD:%.*]] = shufflevector <4 x i16> [[TMP0]], <4 x i16> poison, <4 x i32> <i32 poison, i32 2, i32 1, i32 1>
1191 ; CHECK-NEXT: ret <4 x i16> [[ADD]]
1194 %shuffle = shufflevector <4 x i16> %in, <4 x i16> poison, <4 x i32> <i32 undef, i32 2, i32 1, i32 1>
1195 %add = add <4 x i16> %shuffle, <i16 10, i16 3, i16 0, i16 0>
1199 define <4 x i16> @sub_constant_mask_undef(<4 x i16> %in) {
1200 ; CHECK-LABEL: @sub_constant_mask_undef(
1201 ; CHECK-NEXT: entry:
1202 ; CHECK-NEXT: [[SUB:%.*]] = shufflevector <4 x i16> [[IN:%.*]], <4 x i16> poison, <4 x i32> <i32 poison, i32 poison, i32 1, i32 1>
1203 ; CHECK-NEXT: ret <4 x i16> [[SUB]]
1206 %shuffle = shufflevector <4 x i16> %in, <4 x i16> poison, <4 x i32> <i32 undef, i32 undef, i32 1, i32 1>
1207 %sub = sub <4 x i16> %shuffle, <i16 10, i16 3, i16 0, i16 0>
1211 define <4 x i16> @sub_constant_mask_undef_2(<4 x i16> %in) {
1212 ; CHECK-LABEL: @sub_constant_mask_undef_2(
1213 ; CHECK-NEXT: entry:
1214 ; CHECK-NEXT: [[TMP0:%.*]] = add <4 x i16> [[IN:%.*]], <i16 poison, i16 0, i16 -10, i16 poison>
1215 ; CHECK-NEXT: [[SUB:%.*]] = shufflevector <4 x i16> [[TMP0]], <4 x i16> poison, <4 x i32> <i32 1, i32 1, i32 2, i32 poison>
1216 ; CHECK-NEXT: ret <4 x i16> [[SUB]]
1219 %shuffle = shufflevector <4 x i16> %in, <4 x i16> poison, <4 x i32> <i32 1, i32 1, i32 2, i32 undef>
1220 %sub = sub <4 x i16> %shuffle, <i16 0, i16 0, i16 10, i16 99>
1224 define <2 x i32> @or_splat_constant(<2 x i32> %x) {
1225 ; CHECK-LABEL: @or_splat_constant(
1226 ; CHECK-NEXT: [[TMP1:%.*]] = or <2 x i32> [[X:%.*]], <i32 42, i32 poison>
1227 ; CHECK-NEXT: [[R:%.*]] = shufflevector <2 x i32> [[TMP1]], <2 x i32> poison, <2 x i32> zeroinitializer
1228 ; CHECK-NEXT: ret <2 x i32> [[R]]
1230 %splat = shufflevector <2 x i32> %x, <2 x i32> poison, <2 x i32> zeroinitializer
1231 %r = or <2 x i32> %splat, <i32 42, i32 42>
1235 define <2 x i32> @xor_splat_constant(<2 x i32> %x) {
1236 ; CHECK-LABEL: @xor_splat_constant(
1237 ; CHECK-NEXT: [[TMP1:%.*]] = xor <2 x i32> [[X:%.*]], <i32 42, i32 poison>
1238 ; CHECK-NEXT: [[R:%.*]] = shufflevector <2 x i32> [[TMP1]], <2 x i32> poison, <2 x i32> zeroinitializer
1239 ; CHECK-NEXT: ret <2 x i32> [[R]]
1241 %splat = shufflevector <2 x i32> %x, <2 x i32> poison, <2 x i32> zeroinitializer
1242 %r = xor <2 x i32> %splat, <i32 42, i32 42>
1246 define <2 x float> @fadd_splat_constant(<2 x float> %x) {
1247 ; CHECK-LABEL: @fadd_splat_constant(
1248 ; CHECK-NEXT: [[TMP1:%.*]] = fadd <2 x float> [[X:%.*]], <float 4.200000e+01, float poison>
1249 ; CHECK-NEXT: [[R:%.*]] = shufflevector <2 x float> [[TMP1]], <2 x float> poison, <2 x i32> zeroinitializer
1250 ; CHECK-NEXT: ret <2 x float> [[R]]
1252 %splat = shufflevector <2 x float> %x, <2 x float> poison, <2 x i32> zeroinitializer
1253 %r = fadd <2 x float> %splat, <float 42.0, float 42.0>
1257 define <2 x float> @fsub_splat_constant0(<2 x float> %x) {
1258 ; CHECK-LABEL: @fsub_splat_constant0(
1259 ; CHECK-NEXT: [[TMP1:%.*]] = fsub <2 x float> <float 4.200000e+01, float poison>, [[X:%.*]]
1260 ; CHECK-NEXT: [[R:%.*]] = shufflevector <2 x float> [[TMP1]], <2 x float> poison, <2 x i32> zeroinitializer
1261 ; CHECK-NEXT: ret <2 x float> [[R]]
1263 %splat = shufflevector <2 x float> %x, <2 x float> poison, <2 x i32> zeroinitializer
1264 %r = fsub <2 x float> <float 42.0, float 42.0>, %splat
1268 define <2 x float> @fsub_splat_constant1(<2 x float> %x) {
1269 ; CHECK-LABEL: @fsub_splat_constant1(
1270 ; CHECK-NEXT: [[TMP1:%.*]] = fadd <2 x float> [[X:%.*]], <float -4.200000e+01, float poison>
1271 ; CHECK-NEXT: [[R:%.*]] = shufflevector <2 x float> [[TMP1]], <2 x float> poison, <2 x i32> zeroinitializer
1272 ; CHECK-NEXT: ret <2 x float> [[R]]
1274 %splat = shufflevector <2 x float> %x, <2 x float> poison, <2 x i32> zeroinitializer
1275 %r = fsub <2 x float> %splat, <float 42.0, float 42.0>
1279 define <2 x float> @fneg(<2 x float> %x) {
1280 ; CHECK-LABEL: @fneg(
1281 ; CHECK-NEXT: [[TMP1:%.*]] = shufflevector <2 x float> [[X:%.*]], <2 x float> poison, <2 x i32> zeroinitializer
1282 ; CHECK-NEXT: [[R:%.*]] = fneg <2 x float> [[TMP1]]
1283 ; CHECK-NEXT: ret <2 x float> [[R]]
1285 %splat = shufflevector <2 x float> %x, <2 x float> poison, <2 x i32> zeroinitializer
1286 %r = fsub <2 x float> <float -0.0, float -0.0>, %splat
1290 define <2 x float> @fmul_splat_constant(<2 x float> %x) {
1291 ; CHECK-LABEL: @fmul_splat_constant(
1292 ; CHECK-NEXT: [[TMP1:%.*]] = fmul <2 x float> [[X:%.*]], <float 4.200000e+01, float poison>
1293 ; CHECK-NEXT: [[R:%.*]] = shufflevector <2 x float> [[TMP1]], <2 x float> poison, <2 x i32> zeroinitializer
1294 ; CHECK-NEXT: ret <2 x float> [[R]]
1296 %splat = shufflevector <2 x float> %x, <2 x float> poison, <2 x i32> zeroinitializer
1297 %r = fmul <2 x float> %splat, <float 42.0, float 42.0>
1301 define <2 x float> @fdiv_splat_constant0(<2 x float> %x) {
1302 ; CHECK-LABEL: @fdiv_splat_constant0(
1303 ; CHECK-NEXT: [[TMP1:%.*]] = fdiv <2 x float> <float 4.200000e+01, float poison>, [[X:%.*]]
1304 ; CHECK-NEXT: [[R:%.*]] = shufflevector <2 x float> [[TMP1]], <2 x float> poison, <2 x i32> zeroinitializer
1305 ; CHECK-NEXT: ret <2 x float> [[R]]
1307 %splat = shufflevector <2 x float> %x, <2 x float> poison, <2 x i32> zeroinitializer
1308 %r = fdiv <2 x float> <float 42.0, float 42.0>, %splat
1312 define <2 x float> @fdiv_splat_constant1(<2 x float> %x) {
1313 ; CHECK-LABEL: @fdiv_splat_constant1(
1314 ; CHECK-NEXT: [[TMP1:%.*]] = fdiv <2 x float> [[X:%.*]], <float 4.200000e+01, float poison>
1315 ; CHECK-NEXT: [[R:%.*]] = shufflevector <2 x float> [[TMP1]], <2 x float> poison, <2 x i32> zeroinitializer
1316 ; CHECK-NEXT: ret <2 x float> [[R]]
1318 %splat = shufflevector <2 x float> %x, <2 x float> poison, <2 x i32> zeroinitializer
1319 %r = fdiv <2 x float> %splat, <float 42.0, float 42.0>
1323 define <2 x float> @frem_splat_constant0(<2 x float> %x) {
1324 ; CHECK-LABEL: @frem_splat_constant0(
1325 ; CHECK-NEXT: [[TMP1:%.*]] = frem <2 x float> <float 4.200000e+01, float poison>, [[X:%.*]]
1326 ; CHECK-NEXT: [[R:%.*]] = shufflevector <2 x float> [[TMP1]], <2 x float> poison, <2 x i32> zeroinitializer
1327 ; CHECK-NEXT: ret <2 x float> [[R]]
1329 %splat = shufflevector <2 x float> %x, <2 x float> poison, <2 x i32> zeroinitializer
1330 %r = frem <2 x float> <float 42.0, float 42.0>, %splat
1334 define <2 x float> @frem_splat_constant1(<2 x float> %x) {
1335 ; CHECK-LABEL: @frem_splat_constant1(
1336 ; CHECK-NEXT: [[TMP1:%.*]] = frem <2 x float> [[X:%.*]], <float 4.200000e+01, float poison>
1337 ; CHECK-NEXT: [[R:%.*]] = shufflevector <2 x float> [[TMP1]], <2 x float> poison, <2 x i32> zeroinitializer
1338 ; CHECK-NEXT: ret <2 x float> [[R]]
1340 %splat = shufflevector <2 x float> %x, <2 x float> poison, <2 x i32> zeroinitializer
1341 %r = frem <2 x float> %splat, <float 42.0, float 42.0>
1345 ; Equivalent shuffle masks, but only one is a narrowing op.
1347 define <2 x i1> @PR40734(<1 x i1> %x, <4 x i1> %y) {
1348 ; CHECK-LABEL: @PR40734(
1349 ; CHECK-NEXT: [[WIDEN:%.*]] = shufflevector <1 x i1> zeroinitializer, <1 x i1> [[X:%.*]], <2 x i32> <i32 0, i32 1>
1350 ; CHECK-NEXT: [[NARROW:%.*]] = shufflevector <4 x i1> [[Y:%.*]], <4 x i1> poison, <2 x i32> <i32 0, i32 1>
1351 ; CHECK-NEXT: [[R:%.*]] = and <2 x i1> [[WIDEN]], [[NARROW]]
1352 ; CHECK-NEXT: ret <2 x i1> [[R]]
1354 %widen = shufflevector <1 x i1> zeroinitializer, <1 x i1> %x, <2 x i32> <i32 0, i32 1>
1355 %narrow = shufflevector <4 x i1> %y, <4 x i1> poison, <2 x i32> <i32 0, i32 1>
1356 %r = and <2 x i1> %widen, %narrow
1360 ; Negative test - do not transform non-power-of-2 unless we know the backend handles these sequences identically.
1362 define <7 x i8> @insert_subvector_shuffles(<3 x i8> %x, <3 x i8> %y) {
1363 ; CHECK-LABEL: @insert_subvector_shuffles(
1364 ; 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>
1365 ; 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>
1366 ; 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>
1367 ; CHECK-NEXT: ret <7 x i8> [[S3]]
1369 %s1 = shufflevector <3 x i8> %x, <3 x i8> poison, <7 x i32> <i32 0, i32 1, i32 undef, i32 undef, i32 undef, i32 undef, i32 undef>
1370 %s2 = shufflevector <3 x i8> %y, <3 x i8> poison, <7 x i32> <i32 undef, i32 1, i32 2, i32 undef, i32 undef, i32 undef, i32 undef>
1371 %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>
1375 define <8 x i8> @insert_subvector_shuffles_pow2elts(<2 x i8> %x, <2 x i8> %y) {
1376 ; CHECK-LABEL: @insert_subvector_shuffles_pow2elts(
1377 ; 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>
1378 ; CHECK-NEXT: ret <8 x i8> [[S3]]
1380 %s1 = shufflevector <2 x i8> %x, <2 x i8> poison, <8 x i32> <i32 0, i32 1, i32 undef, i32 undef, i32 undef, i32 undef, i32 undef, i32 undef>
1381 %s2 = shufflevector <2 x i8> %y, <2 x i8> poison, <8 x i32> <i32 0, i32 1, i32 undef, i32 undef, i32 undef, i32 undef, i32 undef, i32 undef>
1382 %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>
1386 ; The last shuffle may change the vector type.
1387 ; Negative test - do not transform non-power-of-2 unless we know the backend handles these sequences identically.
1389 define <2 x i8> @insert_subvector_shuffles_narrowing(<3 x i8> %x, <3 x i8> %y) {
1390 ; CHECK-LABEL: @insert_subvector_shuffles_narrowing(
1391 ; 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>
1392 ; 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>
1393 ; CHECK-NEXT: [[S3:%.*]] = shufflevector <7 x i8> [[S1]], <7 x i8> [[S2]], <2 x i32> <i32 0, i32 8>
1394 ; CHECK-NEXT: ret <2 x i8> [[S3]]
1396 %s1 = shufflevector <3 x i8> %x, <3 x i8> poison, <7 x i32> <i32 0, i32 1, i32 undef, i32 undef, i32 undef, i32 undef, i32 undef>
1397 %s2 = shufflevector <3 x i8> %y, <3 x i8> poison, <7 x i32> <i32 undef, i32 1, i32 2, i32 undef, i32 undef, i32 undef, i32 undef>
1398 %s3 = shufflevector <7 x i8> %s1, <7 x i8> %s2, <2 x i32> <i32 0, i32 8>
1402 define <2 x i8> @insert_subvector_shuffles_narrowing_pow2elts(<4 x i8> %x, <4 x i8> %y) {
1403 ; CHECK-LABEL: @insert_subvector_shuffles_narrowing_pow2elts(
1404 ; CHECK-NEXT: [[S3:%.*]] = shufflevector <4 x i8> [[X:%.*]], <4 x i8> [[Y:%.*]], <2 x i32> <i32 0, i32 4>
1405 ; CHECK-NEXT: ret <2 x i8> [[S3]]
1407 %s1 = shufflevector <4 x i8> %x, <4 x i8> poison, <8 x i32> <i32 0, i32 1, i32 2, i32 undef, i32 undef, i32 undef, i32 undef, i32 undef>
1408 %s2 = shufflevector <4 x i8> %y, <4 x i8> poison, <8 x i32> <i32 0, i32 1, i32 undef, i32 3, i32 undef, i32 undef, i32 undef, i32 undef>
1409 %s3 = shufflevector <8 x i8> %s1, <8 x i8> %s2, <2 x i32> <i32 0, i32 8>
1413 ; Similar to above, but this reduces to a widen with undefs of 'x'.
1415 define <4 x double> @insert_subvector_shuffles_identity(<2 x double> %x) {
1416 ; CHECK-LABEL: @insert_subvector_shuffles_identity(
1417 ; CHECK-NEXT: [[S3:%.*]] = shufflevector <2 x double> [[X:%.*]], <2 x double> poison, <4 x i32> <i32 0, i32 1, i32 poison, i32 poison>
1418 ; CHECK-NEXT: ret <4 x double> [[S3]]
1420 %s1 = shufflevector <2 x double> %x, <2 x double> poison, <4 x i32> <i32 undef, i32 1, i32 undef, i32 undef>
1421 %s2 = shufflevector <2 x double> %x, <2 x double> poison, <4 x i32> <i32 0, i32 undef, i32 undef, i32 undef>
1422 %s3 = shufflevector <4 x double> %s2, <4 x double> %s1, <4 x i32> <i32 0, i32 5, i32 undef, i32 undef>
1423 ret <4 x double> %s3
1426 ; Negative test - not identity with padding (although this could be folded with better analysis).
1428 define <4 x double> @not_insert_subvector_shuffle(<2 x double> %x) {
1429 ; CHECK-LABEL: @not_insert_subvector_shuffle(
1430 ; CHECK-NEXT: [[S1:%.*]] = shufflevector <2 x double> [[X:%.*]], <2 x double> poison, <4 x i32> <i32 poison, i32 1, i32 poison, i32 1>
1431 ; CHECK-NEXT: [[S2:%.*]] = shufflevector <2 x double> [[X]], <2 x double> poison, <4 x i32> <i32 0, i32 poison, i32 poison, i32 poison>
1432 ; CHECK-NEXT: [[S3:%.*]] = shufflevector <4 x double> [[S2]], <4 x double> [[S1]], <4 x i32> <i32 0, i32 5, i32 7, i32 poison>
1433 ; CHECK-NEXT: ret <4 x double> [[S3]]
1435 %s1 = shufflevector <2 x double> %x, <2 x double> poison, <4 x i32> <i32 undef, i32 1, i32 undef, i32 1>
1436 %s2 = shufflevector <2 x double> %x, <2 x double> poison, <4 x i32> <i32 0, i32 undef, i32 undef, i32 undef>
1437 %s3 = shufflevector <4 x double> %s2, <4 x double> %s1, <4 x i32> <i32 0, i32 5, i32 7, i32 undef>
1438 ret <4 x double> %s3
1441 ; Negative test - operands are not the same size (although this could be partly folded with better analysis).
1443 define <4 x double> @not_insert_subvector_shuffles_with_same_size(<2 x double> %x, <3 x double> %y) {
1444 ; CHECK-LABEL: @not_insert_subvector_shuffles_with_same_size(
1445 ; CHECK-NEXT: [[S1:%.*]] = shufflevector <2 x double> [[X:%.*]], <2 x double> poison, <4 x i32> <i32 poison, i32 1, i32 poison, i32 poison>
1446 ; CHECK-NEXT: [[S2:%.*]] = shufflevector <3 x double> [[Y:%.*]], <3 x double> poison, <4 x i32> <i32 0, i32 poison, i32 poison, i32 poison>
1447 ; CHECK-NEXT: [[S3:%.*]] = shufflevector <4 x double> [[S2]], <4 x double> [[S1]], <4 x i32> <i32 0, i32 5, i32 poison, i32 poison>
1448 ; CHECK-NEXT: ret <4 x double> [[S3]]
1450 %s1 = shufflevector <2 x double> %x, <2 x double> poison, <4 x i32> <i32 undef, i32 1, i32 undef, i32 undef>
1451 %s2 = shufflevector <3 x double> %y, <3 x double> poison, <4 x i32> <i32 0, i32 undef, i32 undef, i32 undef>
1452 %s3 = shufflevector <4 x double> %s2, <4 x double> %s1, <4 x i32> <i32 0, i32 5, i32 undef, i32 undef>
1453 ret <4 x double> %s3
1456 ; Demanded vector elements may not be able to simplify a shuffle mask
1457 ; before we try to narrow it. This used to crash.
1459 define <4 x float> @insert_subvector_crash_invalid_mask_elt(<2 x float> %x, ptr %p) {
1460 ; CHECK-LABEL: @insert_subvector_crash_invalid_mask_elt(
1461 ; CHECK-NEXT: [[WIDEN:%.*]] = shufflevector <2 x float> [[X:%.*]], <2 x float> poison, <4 x i32> <i32 0, i32 1, i32 poison, i32 poison>
1462 ; CHECK-NEXT: [[I:%.*]] = shufflevector <2 x float> [[X]], <2 x float> poison, <4 x i32> <i32 0, i32 1, i32 poison, i32 poison>
1463 ; CHECK-NEXT: store <4 x float> [[I]], ptr [[P:%.*]], align 16
1464 ; CHECK-NEXT: ret <4 x float> [[WIDEN]]
1466 %widen = shufflevector <2 x float> %x, <2 x float> poison, <4 x i32> <i32 0, i32 1, i32 undef, i32 undef>
1467 %ext2 = extractelement <2 x float> %x, i32 0
1468 %I = insertelement <4 x float> %widen, float %ext2, i16 0
1469 store <4 x float> %I, ptr %p
1470 ret <4 x float> %widen
1473 define <4 x i32> @splat_assoc_add(<4 x i32> %x, <4 x i32> %y) {
1474 ; CHECK-LABEL: @splat_assoc_add(
1475 ; CHECK-NEXT: [[TMP1:%.*]] = add <4 x i32> [[X:%.*]], <i32 317426, i32 poison, i32 poison, i32 poison>
1476 ; CHECK-NEXT: [[TMP2:%.*]] = shufflevector <4 x i32> [[TMP1]], <4 x i32> poison, <4 x i32> zeroinitializer
1477 ; CHECK-NEXT: [[R:%.*]] = add <4 x i32> [[TMP2]], [[Y:%.*]]
1478 ; CHECK-NEXT: ret <4 x i32> [[R]]
1480 %splatx = shufflevector <4 x i32> %x, <4 x i32> poison, <4 x i32> zeroinitializer
1481 %a = add <4 x i32> %y, <i32 317426, i32 317426, i32 317426, i32 317426>
1482 %r = add <4 x i32> %splatx, %a
1486 define <vscale x 4 x i32> @vsplat_assoc_add(<vscale x 4 x i32> %x, <vscale x 4 x i32> %y) {
1487 ; CHECK-LABEL: @vsplat_assoc_add(
1488 ; CHECK-NEXT: [[TMP1:%.*]] = add <vscale x 4 x i32> [[X:%.*]], splat (i32 317426)
1489 ; CHECK-NEXT: [[TMP2:%.*]] = shufflevector <vscale x 4 x i32> [[TMP1]], <vscale x 4 x i32> poison, <vscale x 4 x i32> zeroinitializer
1490 ; CHECK-NEXT: [[R:%.*]] = add <vscale x 4 x i32> [[TMP2]], [[Y:%.*]]
1491 ; CHECK-NEXT: ret <vscale x 4 x i32> [[R]]
1494 %splatx = shufflevector <vscale x 4 x i32> %x, <vscale x 4 x i32> poison, <vscale x 4 x i32> zeroinitializer
1495 %a = add <vscale x 4 x i32> %y, splat (i32 317426)
1496 %r = add <vscale x 4 x i32> %splatx, %a
1497 ret <vscale x 4 x i32> %r
1500 ; Undefs in splat mask are replaced with defined splat index
1502 define <4 x i32> @splat_assoc_add_undef_mask_elts(<4 x i32> %x, <4 x i32> %y) {
1503 ; CHECK-LABEL: @splat_assoc_add_undef_mask_elts(
1504 ; CHECK-NEXT: [[TMP1:%.*]] = add <4 x i32> [[X:%.*]], <i32 42, i32 poison, i32 poison, i32 poison>
1505 ; CHECK-NEXT: [[TMP2:%.*]] = shufflevector <4 x i32> [[TMP1]], <4 x i32> poison, <4 x i32> zeroinitializer
1506 ; CHECK-NEXT: [[R:%.*]] = add <4 x i32> [[TMP2]], [[Y:%.*]]
1507 ; CHECK-NEXT: ret <4 x i32> [[R]]
1509 %splatx = shufflevector <4 x i32> %x, <4 x i32> poison, <4 x i32> <i32 0, i32 0, i32 undef, i32 undef>
1510 %a = add <4 x i32> %y, <i32 42, i32 42, i32 42, i32 42>
1511 %r = add <4 x i32> %splatx, %a
1515 ; Undefs in splat mask are replaced with defined splat index
1517 define <4 x i32> @splat_assoc_add_undef_mask_elt_at_splat_index(<4 x i32> %x, <4 x i32> %y) {
1518 ; CHECK-LABEL: @splat_assoc_add_undef_mask_elt_at_splat_index(
1519 ; CHECK-NEXT: [[TMP1:%.*]] = add <4 x i32> [[X:%.*]], <i32 42, i32 poison, i32 poison, i32 poison>
1520 ; CHECK-NEXT: [[TMP2:%.*]] = shufflevector <4 x i32> [[TMP1]], <4 x i32> poison, <4 x i32> zeroinitializer
1521 ; CHECK-NEXT: [[R:%.*]] = add <4 x i32> [[TMP2]], [[Y:%.*]]
1522 ; CHECK-NEXT: ret <4 x i32> [[R]]
1524 %splatx = shufflevector <4 x i32> %x, <4 x i32> poison, <4 x i32> <i32 undef, i32 0, i32 0, i32 0>
1525 %a = add <4 x i32> %y, <i32 42, i32 42, i32 42, i32 42>
1526 %r = add <4 x i32> %splatx, %a
1530 define <4 x i32> @splat_assoc_add_undef_constant_elts(<4 x i32> %x, <4 x i32> %y) {
1531 ; CHECK-LABEL: @splat_assoc_add_undef_constant_elts(
1532 ; CHECK-NEXT: [[SPLATX:%.*]] = shufflevector <4 x i32> [[X:%.*]], <4 x i32> poison, <4 x i32> zeroinitializer
1533 ; CHECK-NEXT: [[A:%.*]] = add <4 x i32> [[Y:%.*]], <i32 42, i32 undef, i32 undef, i32 42>
1534 ; CHECK-NEXT: [[R:%.*]] = add <4 x i32> [[SPLATX]], [[A]]
1535 ; CHECK-NEXT: ret <4 x i32> [[R]]
1537 %splatx = shufflevector <4 x i32> %x, <4 x i32> poison, <4 x i32> zeroinitializer
1538 %a = add <4 x i32> %y, <i32 42, i32 undef, i32 undef, i32 42>
1539 %r = add <4 x i32> %splatx, %a
1543 define <4 x i32> @splat_assoc_add_undef_constant_elt_at_splat_index(<4 x i32> %x, <4 x i32> %y) {
1544 ; CHECK-LABEL: @splat_assoc_add_undef_constant_elt_at_splat_index(
1545 ; CHECK-NEXT: [[SPLATX:%.*]] = shufflevector <4 x i32> [[X:%.*]], <4 x i32> poison, <4 x i32> zeroinitializer
1546 ; CHECK-NEXT: [[A:%.*]] = add <4 x i32> [[Y:%.*]], <i32 undef, i32 42, i32 undef, i32 42>
1547 ; CHECK-NEXT: [[R:%.*]] = add <4 x i32> [[SPLATX]], [[A]]
1548 ; CHECK-NEXT: ret <4 x i32> [[R]]
1550 %splatx = shufflevector <4 x i32> %x, <4 x i32> poison, <4 x i32> zeroinitializer
1551 %a = add <4 x i32> %y, <i32 undef, i32 42, i32 undef, i32 42>
1552 %r = add <4 x i32> %splatx, %a
1556 define <4 x i32> @splat_assoc_add_undef_mask_elts_undef_constant_elts(<4 x i32> %x, <4 x i32> %y) {
1557 ; CHECK-LABEL: @splat_assoc_add_undef_mask_elts_undef_constant_elts(
1558 ; CHECK-NEXT: [[SPLATX:%.*]] = shufflevector <4 x i32> [[X:%.*]], <4 x i32> poison, <4 x i32> <i32 0, i32 poison, i32 0, i32 poison>
1559 ; CHECK-NEXT: [[A:%.*]] = add <4 x i32> [[Y:%.*]], <i32 42, i32 undef, i32 undef, i32 42>
1560 ; CHECK-NEXT: [[R:%.*]] = add <4 x i32> [[SPLATX]], [[A]]
1561 ; CHECK-NEXT: ret <4 x i32> [[R]]
1563 %splatx = shufflevector <4 x i32> %x, <4 x i32> poison, <4 x i32> <i32 0, i32 undef, i32 0, i32 undef>
1564 %a = add <4 x i32> %y, <i32 42, i32 undef, i32 undef, i32 42>
1565 %r = add <4 x i32> %splatx, %a
1569 define <4 x i32> @splat_assoc_add_undef_mask_elt_at_splat_index_undef_constant_elts(<4 x i32> %x, <4 x i32> %y) {
1570 ; CHECK-LABEL: @splat_assoc_add_undef_mask_elt_at_splat_index_undef_constant_elts(
1571 ; CHECK-NEXT: [[SPLATX:%.*]] = shufflevector <4 x i32> [[X:%.*]], <4 x i32> poison, <4 x i32> <i32 poison, i32 0, i32 0, i32 0>
1572 ; CHECK-NEXT: [[A:%.*]] = add <4 x i32> [[Y:%.*]], <i32 42, i32 undef, i32 undef, i32 42>
1573 ; CHECK-NEXT: [[R:%.*]] = add <4 x i32> [[SPLATX]], [[A]]
1574 ; CHECK-NEXT: ret <4 x i32> [[R]]
1576 %splatx = shufflevector <4 x i32> %x, <4 x i32> poison, <4 x i32> <i32 undef, i32 0, i32 0, i32 0>
1577 %a = add <4 x i32> %y, <i32 42, i32 undef, i32 undef, i32 42>
1578 %r = add <4 x i32> %splatx, %a
1582 define <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) {
1583 ; CHECK-LABEL: @splat_assoc_add_undef_mask_elt_at_splat_index_undef_constant_elt_at_splat_index(
1584 ; CHECK-NEXT: [[SPLATX:%.*]] = shufflevector <4 x i32> [[X:%.*]], <4 x i32> poison, <4 x i32> <i32 poison, i32 0, i32 0, i32 0>
1585 ; CHECK-NEXT: [[A:%.*]] = add <4 x i32> [[Y:%.*]], <i32 undef, i32 42, i32 undef, i32 42>
1586 ; CHECK-NEXT: [[R:%.*]] = add <4 x i32> [[SPLATX]], [[A]]
1587 ; CHECK-NEXT: ret <4 x i32> [[R]]
1589 %splatx = shufflevector <4 x i32> %x, <4 x i32> poison, <4 x i32> <i32 undef, i32 0, i32 0, i32 0>
1590 %a = add <4 x i32> %y, <i32 undef, i32 42, i32 undef, i32 42>
1591 %r = add <4 x i32> %splatx, %a
1595 ; Non-zero splat index; commute operands; FMF intersect
1597 define <2 x float> @splat_assoc_fmul(<2 x float> %x, <2 x float> %y) {
1598 ; CHECK-LABEL: @splat_assoc_fmul(
1599 ; CHECK-NEXT: [[TMP1:%.*]] = fmul reassoc nsz <2 x float> [[X:%.*]], <float poison, float 3.000000e+00>
1600 ; CHECK-NEXT: [[TMP2:%.*]] = shufflevector <2 x float> [[TMP1]], <2 x float> poison, <2 x i32> <i32 1, i32 1>
1601 ; CHECK-NEXT: [[R:%.*]] = fmul reassoc nsz <2 x float> [[TMP2]], [[Y:%.*]]
1602 ; CHECK-NEXT: ret <2 x float> [[R]]
1604 %splatx = shufflevector <2 x float> %x, <2 x float> poison, <2 x i32> <i32 1, i32 1>
1605 %a = fmul reassoc nsz <2 x float> %y, <float 3.0, float 3.0>
1606 %r = fmul reassoc nsz nnan <2 x float> %a, %splatx
1610 ; Two splat shuffles; drop poison-generating flags
1612 define <3 x i8> @splat_assoc_mul(<3 x i8> %x, <3 x i8> %y, <3 x i8> %z) {
1613 ; CHECK-LABEL: @splat_assoc_mul(
1614 ; CHECK-NEXT: [[TMP1:%.*]] = mul <3 x i8> [[X:%.*]], [[Z:%.*]]
1615 ; CHECK-NEXT: [[TMP2:%.*]] = shufflevector <3 x i8> [[TMP1]], <3 x i8> poison, <3 x i32> <i32 2, i32 2, i32 2>
1616 ; CHECK-NEXT: [[R:%.*]] = mul <3 x i8> [[TMP2]], [[Y:%.*]]
1617 ; CHECK-NEXT: ret <3 x i8> [[R]]
1619 %splatx = shufflevector <3 x i8> %x, <3 x i8> poison, <3 x i32> <i32 2, i32 2, i32 2>
1620 %splatz = shufflevector <3 x i8> %z, <3 x i8> poison, <3 x i32> <i32 2, i32 2, i32 2>
1621 %a = mul nsw <3 x i8> %y, %splatz
1622 %r = mul <3 x i8> %a, %splatx
1626 define <3 x i8> @splat_assoc_mul_undef_elt1(<3 x i8> %x, <3 x i8> %y, <3 x i8> %z) {
1627 ; CHECK-LABEL: @splat_assoc_mul_undef_elt1(
1628 ; CHECK-NEXT: [[TMP1:%.*]] = mul <3 x i8> [[X:%.*]], [[Z:%.*]]
1629 ; CHECK-NEXT: [[TMP2:%.*]] = shufflevector <3 x i8> [[TMP1]], <3 x i8> poison, <3 x i32> <i32 2, i32 2, i32 2>
1630 ; CHECK-NEXT: [[R:%.*]] = mul <3 x i8> [[TMP2]], [[Y:%.*]]
1631 ; CHECK-NEXT: ret <3 x i8> [[R]]
1633 %splatx = shufflevector <3 x i8> %x, <3 x i8> poison, <3 x i32> <i32 undef, i32 2, i32 2>
1634 %splatz = shufflevector <3 x i8> %z, <3 x i8> poison, <3 x i32> <i32 2, i32 2, i32 2>
1635 %a = mul nsw <3 x i8> %y, %splatz
1636 %r = mul nsw nuw <3 x i8> %a, %splatx
1640 define <3 x i8> @splat_assoc_mul_undef_elt2(<3 x i8> %x, <3 x i8> %y, <3 x i8> %z) {
1641 ; CHECK-LABEL: @splat_assoc_mul_undef_elt2(
1642 ; CHECK-NEXT: [[SPLATX:%.*]] = shufflevector <3 x i8> [[X:%.*]], <3 x i8> poison, <3 x i32> <i32 2, i32 2, i32 2>
1643 ; CHECK-NEXT: [[SPLATZ:%.*]] = shufflevector <3 x i8> [[Z:%.*]], <3 x i8> poison, <3 x i32> <i32 poison, i32 2, i32 2>
1644 ; CHECK-NEXT: [[A:%.*]] = mul nsw <3 x i8> [[Y:%.*]], [[SPLATZ]]
1645 ; CHECK-NEXT: [[R:%.*]] = mul nuw nsw <3 x i8> [[A]], [[SPLATX]]
1646 ; CHECK-NEXT: ret <3 x i8> [[R]]
1648 %splatx = shufflevector <3 x i8> %x, <3 x i8> poison, <3 x i32> <i32 2, i32 2, i32 2>
1649 %splatz = shufflevector <3 x i8> %z, <3 x i8> poison, <3 x i32> <i32 undef, i32 2, i32 2>
1650 %a = mul nsw <3 x i8> %y, %splatz
1651 %r = mul nsw nuw <3 x i8> %a, %splatx
1655 define <3 x i8> @splat_assoc_mul_undef_elt_at_splat_index1(<3 x i8> %x, <3 x i8> %y, <3 x i8> %z) {
1656 ; CHECK-LABEL: @splat_assoc_mul_undef_elt_at_splat_index1(
1657 ; CHECK-NEXT: [[TMP1:%.*]] = mul <3 x i8> [[X:%.*]], [[Z:%.*]]
1658 ; CHECK-NEXT: [[TMP2:%.*]] = shufflevector <3 x i8> [[TMP1]], <3 x i8> poison, <3 x i32> <i32 2, i32 2, i32 2>
1659 ; CHECK-NEXT: [[R:%.*]] = mul <3 x i8> [[TMP2]], [[Y:%.*]]
1660 ; CHECK-NEXT: ret <3 x i8> [[R]]
1662 %splatx = shufflevector <3 x i8> %x, <3 x i8> poison, <3 x i32> <i32 2, i32 2, i32 undef>
1663 %splatz = shufflevector <3 x i8> %z, <3 x i8> poison, <3 x i32> <i32 2, i32 2, i32 2>
1664 %a = mul nsw <3 x i8> %y, %splatz
1665 %r = mul nsw nuw <3 x i8> %a, %splatx
1669 define <3 x i8> @splat_assoc_mul_undef_elt_at_splat_index2(<3 x i8> %x, <3 x i8> %y, <3 x i8> %z) {
1670 ; CHECK-LABEL: @splat_assoc_mul_undef_elt_at_splat_index2(
1671 ; CHECK-NEXT: [[SPLATX:%.*]] = shufflevector <3 x i8> [[X:%.*]], <3 x i8> poison, <3 x i32> <i32 2, i32 2, i32 2>
1672 ; CHECK-NEXT: [[SPLATZ:%.*]] = shufflevector <3 x i8> [[Z:%.*]], <3 x i8> poison, <3 x i32> <i32 2, i32 2, i32 poison>
1673 ; CHECK-NEXT: [[A:%.*]] = mul nsw <3 x i8> [[Y:%.*]], [[SPLATZ]]
1674 ; CHECK-NEXT: [[R:%.*]] = mul nuw nsw <3 x i8> [[A]], [[SPLATX]]
1675 ; CHECK-NEXT: ret <3 x i8> [[R]]
1677 %splatx = shufflevector <3 x i8> %x, <3 x i8> poison, <3 x i32> <i32 2, i32 2, i32 2>
1678 %splatz = shufflevector <3 x i8> %z, <3 x i8> poison, <3 x i32> <i32 2, i32 2, i32 undef>
1679 %a = mul nsw <3 x i8> %y, %splatz
1680 %r = mul nsw nuw <3 x i8> %a, %splatx
1684 ; Negative test - mismatched splat elements
1686 define <3 x i8> @splat_assoc_or(<3 x i8> %x, <3 x i8> %y, <3 x i8> %z) {
1687 ; CHECK-LABEL: @splat_assoc_or(
1688 ; CHECK-NEXT: [[SPLATX:%.*]] = shufflevector <3 x i8> [[X:%.*]], <3 x i8> poison, <3 x i32> <i32 1, i32 1, i32 1>
1689 ; CHECK-NEXT: [[SPLATZ:%.*]] = shufflevector <3 x i8> [[Z:%.*]], <3 x i8> poison, <3 x i32> <i32 2, i32 2, i32 2>
1690 ; CHECK-NEXT: [[A:%.*]] = or <3 x i8> [[Y:%.*]], [[SPLATZ]]
1691 ; CHECK-NEXT: [[R:%.*]] = or <3 x i8> [[A]], [[SPLATX]]
1692 ; CHECK-NEXT: ret <3 x i8> [[R]]
1694 %splatx = shufflevector <3 x i8> %x, <3 x i8> poison, <3 x i32> <i32 1, i32 1, i32 1>
1695 %splatz = shufflevector <3 x i8> %z, <3 x i8> poison, <3 x i32> <i32 2, i32 2, i32 2>
1696 %a = or <3 x i8> %y, %splatz
1697 %r = or <3 x i8> %a, %splatx
1701 ; Negative test - not associative
1703 define <2 x float> @splat_assoc_fdiv(<2 x float> %x, <2 x float> %y) {
1704 ; CHECK-LABEL: @splat_assoc_fdiv(
1705 ; CHECK-NEXT: [[SPLATX:%.*]] = shufflevector <2 x float> [[X:%.*]], <2 x float> poison, <2 x i32> zeroinitializer
1706 ; CHECK-NEXT: [[A:%.*]] = fdiv reassoc nsz <2 x float> [[Y:%.*]], splat (float 3.000000e+00)
1707 ; CHECK-NEXT: [[R:%.*]] = fdiv reassoc nsz <2 x float> [[A]], [[SPLATX]]
1708 ; CHECK-NEXT: ret <2 x float> [[R]]
1710 %splatx = shufflevector <2 x float> %x, <2 x float> poison, <2 x i32> zeroinitializer
1711 %a = fdiv reassoc nsz <2 x float> %y, <float 3.0, float 3.0>
1712 %r = fdiv reassoc nsz <2 x float> %a, %splatx
1716 ; Negative test - extra use
1718 define <2 x float> @splat_assoc_fadd(<2 x float> %x, <2 x float> %y) {
1719 ; CHECK-LABEL: @splat_assoc_fadd(
1720 ; CHECK-NEXT: [[SPLATX:%.*]] = shufflevector <2 x float> [[X:%.*]], <2 x float> poison, <2 x i32> <i32 1, i32 1>
1721 ; CHECK-NEXT: [[A:%.*]] = fadd fast <2 x float> [[Y:%.*]], splat (float 3.000000e+00)
1722 ; CHECK-NEXT: call void @use(<2 x float> [[A]])
1723 ; CHECK-NEXT: [[R:%.*]] = fadd fast <2 x float> [[A]], [[SPLATX]]
1724 ; CHECK-NEXT: ret <2 x float> [[R]]
1726 %splatx = shufflevector <2 x float> %x, <2 x float> poison, <2 x i32> <i32 1, i32 1>
1727 %a = fadd fast <2 x float> %y, <float 3.0, float 3.0>
1728 call void @use(<2 x float> %a)
1729 %r = fadd fast <2 x float> %a, %splatx
1733 ; Negative test - narrowing splat
1735 define <3 x i32> @splat_assoc_and(<4 x i32> %x, <3 x i32> %y) {
1736 ; CHECK-LABEL: @splat_assoc_and(
1737 ; CHECK-NEXT: [[SPLATX:%.*]] = shufflevector <4 x i32> [[X:%.*]], <4 x i32> poison, <3 x i32> zeroinitializer
1738 ; CHECK-NEXT: [[A:%.*]] = and <3 x i32> [[Y:%.*]], splat (i32 42)
1739 ; CHECK-NEXT: [[R:%.*]] = and <3 x i32> [[SPLATX]], [[A]]
1740 ; CHECK-NEXT: ret <3 x i32> [[R]]
1742 %splatx = shufflevector <4 x i32> %x, <4 x i32> poison, <3 x i32> zeroinitializer
1743 %a = and <3 x i32> %y, <i32 42, i32 42, i32 42>
1744 %r = and <3 x i32> %splatx, %a
1748 ; Negative test - widening splat
1750 define <5 x i32> @splat_assoc_xor(<4 x i32> %x, <5 x i32> %y) {
1751 ; CHECK-LABEL: @splat_assoc_xor(
1752 ; CHECK-NEXT: [[SPLATX:%.*]] = shufflevector <4 x i32> [[X:%.*]], <4 x i32> poison, <5 x i32> zeroinitializer
1753 ; CHECK-NEXT: [[TMP1:%.*]] = xor <5 x i32> [[Y:%.*]], [[SPLATX]]
1754 ; CHECK-NEXT: [[R:%.*]] = xor <5 x i32> [[TMP1]], splat (i32 42)
1755 ; CHECK-NEXT: ret <5 x i32> [[R]]
1757 %splatx = shufflevector <4 x i32> %x, <4 x i32> poison, <5 x i32> zeroinitializer
1758 %a = xor <5 x i32> %y, <i32 42, i32 42, i32 42, i32 42, i32 42>
1759 %r = xor <5 x i32> %splatx, %a
1763 ; Negative test - opcode mismatch
1765 define <4 x i32> @splat_assoc_add_mul(<4 x i32> %x, <4 x i32> %y) {
1766 ; CHECK-LABEL: @splat_assoc_add_mul(
1767 ; CHECK-NEXT: [[SPLATX:%.*]] = shufflevector <4 x i32> [[X:%.*]], <4 x i32> poison, <4 x i32> zeroinitializer
1768 ; CHECK-NEXT: [[A:%.*]] = add <4 x i32> [[Y:%.*]], splat (i32 42)
1769 ; CHECK-NEXT: [[R:%.*]] = mul <4 x i32> [[SPLATX]], [[A]]
1770 ; CHECK-NEXT: ret <4 x i32> [[R]]
1772 %splatx = shufflevector <4 x i32> %x, <4 x i32> poison, <4 x i32> zeroinitializer
1773 %a = add <4 x i32> %y, <i32 42, i32 42, i32 42, i32 42>
1774 %r = mul <4 x i32> %splatx, %a
1779 ; Do not crash on constant expressions.
1781 define <4 x i32> @PR46872(<4 x i32> %x) {
1782 ; CHECK-LABEL: @PR46872(
1783 ; CHECK-NEXT: [[S:%.*]] = shufflevector <4 x i32> [[X:%.*]], <4 x i32> poison, <4 x i32> <i32 poison, i32 0, i32 1, i32 1>
1784 ; 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>)
1785 ; CHECK-NEXT: ret <4 x i32> [[A]]
1787 %s = shufflevector <4 x i32> %x, <4 x i32> poison, <4 x i32> <i32 undef, i32 0, i32 1, i32 1>
1788 %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>)