brintos

brintos / llvm-project-archived public Read only

0
0
Text · 83.8 KiB · 86fc5bb Raw
1827 lines · plain
1; NOTE: Assertions have been autogenerated by utils/update_test_checks.py2; RUN: opt < %s -passes=instcombine -S | FileCheck %s3 4define <4 x float> @test1(<4 x float> %v1) {5; CHECK-LABEL: @test1(6; CHECK-NEXT:    ret <4 x float> [[V1:%.*]]7;8  %v2 = shufflevector <4 x float> %v1, <4 x float> poison, <4 x i32> <i32 0, i32 1, i32 2, i32 3>9  ret <4 x float> %v210}11 12define <4 x float> @test2(<4 x float> %v1) {13; CHECK-LABEL: @test2(14; CHECK-NEXT:    ret <4 x float> [[V1:%.*]]15;16  %v2 = shufflevector <4 x float> %v1, <4 x float> %v1, <4 x i32> <i32 0, i32 5, i32 2, i32 7>17  ret <4 x float> %v218}19 20define float @test3(<4 x float> %A, <4 x float> %B, float %f) {21; CHECK-LABEL: @test3(22; CHECK-NEXT:    ret float [[F:%.*]]23;24  %C = insertelement <4 x float> %A, float %f, i32 025  %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 127  ret float %E28}29 30define i32 @test4(<4 x i32> %X) {31; CHECK-LABEL: @test4(32; CHECK-NEXT:    [[R:%.*]] = extractelement <4 x i32> [[X:%.*]], i64 033; CHECK-NEXT:    ret i32 [[R]]34;35  %t = shufflevector <4 x i32> %X, <4 x i32> poison, <4 x i32> zeroinitializer36  %r = extractelement <4 x i32> %t, i32 037  ret i32 %r38}39 40define i32 @test5(<4 x i32> %X) {41; CHECK-LABEL: @test5(42; CHECK-NEXT:    [[R:%.*]] = extractelement <4 x i32> [[X:%.*]], i64 343; CHECK-NEXT:    ret i32 [[R]]44;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 047  ret i32 %r48}49 50define float @test6(<4 x float> %X) {51; CHECK-LABEL: @test6(52; CHECK-NEXT:    [[R:%.*]] = extractelement <4 x float> [[X:%.*]], i64 053; CHECK-NEXT:    ret float [[R]]54;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> zeroinitializer57  %t2 = bitcast <4 x i32> %t to <4 x float>58  %r = extractelement <4 x float> %t2, i32 059  ret float %r60}61 62define float @testvscale6(<vscale x 4 x float> %X) {63; CHECK-LABEL: @testvscale6(64; CHECK-NEXT:    [[R:%.*]] = extractelement <vscale x 4 x float> [[X:%.*]], i64 065; CHECK-NEXT:    ret float [[R]]66;67  %X1 = bitcast <vscale x 4 x float> %X to <vscale x 4 x i32>68  %t = shufflevector <vscale x 4 x i32> %X1, <vscale x 4 x i32> poison, <vscale x 4 x i32> zeroinitializer69  %t2 = bitcast <vscale x 4 x i32> %t to <vscale x 4 x float>70  %r = extractelement <vscale x 4 x float> %t2, i32 071  ret float %r72}73 74 75define <4 x float> @test7(<4 x float> %x) {76; CHECK-LABEL: @test7(77; CHECK-NEXT:    [[R:%.*]] = shufflevector <4 x float> [[X:%.*]], <4 x float> poison, <4 x i32> <i32 0, i32 1, i32 poison, i32 poison>78; CHECK-NEXT:    ret <4 x float> [[R]]79;80  %r = shufflevector <4 x float> %x, <4 x float> poison, <4 x i32> < i32 0, i32 1, i32 6, i32 7 >81  ret <4 x float> %r82}83 84; This should turn into a single shuffle.85define <4 x float> @test8(<4 x float> %x, <4 x float> %y) {86; CHECK-LABEL: @test8(87; CHECK-NEXT:    [[T134:%.*]] = shufflevector <4 x float> [[X:%.*]], <4 x float> [[Y:%.*]], <4 x i32> <i32 1, i32 poison, i32 3, i32 4>88; CHECK-NEXT:    ret <4 x float> [[T134]]89;90  %t4 = extractelement <4 x float> %x, i32 191  %t2 = extractelement <4 x float> %x, i32 392  %t1 = extractelement <4 x float> %y, i32 093  %t128 = insertelement <4 x float> poison, float %t4, i32 094  %t130 = insertelement <4 x float> %t128, float poison, i32 195  %t132 = insertelement <4 x float> %t130, float %t2, i32 296  %t134 = insertelement <4 x float> %t132, float %t1, i32 397  ret <4 x float> %t13498}99 100; This shouldn't turn into a single shuffle101define <4 x float> @test8_undef(<4 x float> %x, <4 x float> %y) {102; CHECK-LABEL: @test8_undef(103; 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>104; CHECK-NEXT:    [[T134:%.*]] = shufflevector <4 x float> [[T132]], <4 x float> [[Y:%.*]], <4 x i32> <i32 0, i32 1, i32 2, i32 4>105; CHECK-NEXT:    ret <4 x float> [[T134]]106;107  %t4 = extractelement <4 x float> %x, i32 1108  %t2 = extractelement <4 x float> %x, i32 3109  %t1 = extractelement <4 x float> %y, i32 0110  %t128 = insertelement <4 x float> poison, float %t4, i32 0111  %t130 = insertelement <4 x float> %t128, float undef, i32 1112  %t132 = insertelement <4 x float> %t130, float %t2, i32 2113  %t134 = insertelement <4 x float> %t132, float %t1, i32 3114  ret <4 x float> %t134115}116 117; Test fold of two shuffles where the first shuffle vectors inputs are a118; different length then the second.119define <4 x i8> @test9(<16 x i8> %t6) {120; CHECK-LABEL: @test9(121; CHECK-NEXT:    [[T9:%.*]] = shufflevector <16 x i8> [[T6:%.*]], <16 x i8> poison, <4 x i32> <i32 13, i32 9, i32 4, i32 13>122; CHECK-NEXT:    ret <4 x i8> [[T9]]123;124  %t7 = shufflevector <16 x i8> %t6, <16 x i8> poison, <4 x i32> < i32 13, i32 9, i32 4, i32 13 >125  %t9 = shufflevector <4 x i8> %t7, <4 x i8> poison, <4 x i32> < i32 3, i32 1, i32 2, i32 0 >126  ret <4 x i8> %t9127}128 129; Same as test9, but make sure that "undef" mask values are not confused with130; mask values of 2*N, where N is the mask length.  These shuffles should not131; be folded (because [8,9,4,8] may not be a mask supported by the target).132 133define <4 x i8> @test9a(<16 x i8> %t6) {134; CHECK-LABEL: @test9a(135; CHECK-NEXT:    [[T7:%.*]] = shufflevector <16 x i8> [[T6:%.*]], <16 x i8> poison, <4 x i32> <i32 poison, i32 9, i32 4, i32 8>136; CHECK-NEXT:    [[T9:%.*]] = shufflevector <4 x i8> [[T7]], <4 x i8> poison, <4 x i32> <i32 3, i32 1, i32 2, i32 poison>137; CHECK-NEXT:    ret <4 x i8> [[T9]]138;139  %t7 = shufflevector <16 x i8> %t6, <16 x i8> poison, <4 x i32> < i32 undef, i32 9, i32 4, i32 8 >140  %t9 = shufflevector <4 x i8> %t7, <4 x i8> poison, <4 x i32> < i32 3, i32 1, i32 2, i32 0 >141  ret <4 x i8> %t9142}143 144; Test fold of two shuffles where the first shuffle vectors inputs are a145; different length then the second.146define <4 x i8> @test9b(<4 x i8> %t6, <4 x i8> %t7) {147; CHECK-LABEL: @test9b(148; CHECK-NEXT:    [[T9:%.*]] = shufflevector <4 x i8> [[T6:%.*]], <4 x i8> [[T7:%.*]], <4 x i32> <i32 0, i32 1, i32 4, i32 5>149; CHECK-NEXT:    ret <4 x i8> [[T9]]150;151  %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>152  %t9 = shufflevector <8 x i8> %t1, <8 x i8> poison, <4 x i32> <i32 0, i32 1, i32 4, i32 5>153  ret <4 x i8> %t9154}155 156; Redundant vector splats should be removed.  Radar 8597790.157define <4 x i32> @test10(<4 x i32> %t5) {158; CHECK-LABEL: @test10(159; CHECK-NEXT:    [[T7:%.*]] = shufflevector <4 x i32> [[T5:%.*]], <4 x i32> poison, <4 x i32> <i32 1, i32 1, i32 1, i32 1>160; CHECK-NEXT:    ret <4 x i32> [[T7]]161;162  %t6 = shufflevector <4 x i32> %t5, <4 x i32> poison, <4 x i32> <i32 1, i32 undef, i32 undef, i32 undef>163  %t7 = shufflevector <4 x i32> %t6, <4 x i32> poison, <4 x i32> zeroinitializer164  ret <4 x i32> %t7165}166 167; Test fold of two shuffles where the two shufflevector inputs's op1 are the same.168 169define <8 x i8> @test11(<16 x i8> %t6) {170; CHECK-LABEL: @test11(171; 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>172; CHECK-NEXT:    ret <8 x i8> [[T3]]173;174  %t1 = shufflevector <16 x i8> %t6, <16 x i8> poison, <4 x i32> <i32 0, i32 1, i32 2, i32 3>175  %t2 = shufflevector <16 x i8> %t6, <16 x i8> poison, <4 x i32> <i32 4, i32 5, i32 6, i32 7>176  %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>177  ret <8 x i8> %t3178}179 180; Test fold of two shuffles where the first shufflevector's inputs are the same as the second.181 182define <8 x i8> @test12(<8 x i8> %t6, <8 x i8> %t2) {183; CHECK-LABEL: @test12(184; 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>185; CHECK-NEXT:    ret <8 x i8> [[T3]]186;187  %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>188  %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>189  ret <8 x i8> %t3190}191 192; Test fold of two shuffles where the first shufflevector's inputs are the same as the second.193 194define <8 x i8> @test12a(<8 x i8> %t6, <8 x i8> %t2) {195; CHECK-LABEL: @test12a(196; 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>197; CHECK-NEXT:    ret <8 x i8> [[T3]]198;199  %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>200  %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>201  ret <8 x i8> %t3202}203 204; The mask length of the 1st shuffle can be reduced to eliminate the 2nd shuffle.205 206define <2 x i8> @extract_subvector_of_shuffle(<2 x i8> %x, <2 x i8> %y) {207; CHECK-LABEL: @extract_subvector_of_shuffle(208; CHECK-NEXT:    [[EXTRACT_SUBV:%.*]] = shufflevector <2 x i8> [[X:%.*]], <2 x i8> [[Y:%.*]], <2 x i32> <i32 0, i32 2>209; CHECK-NEXT:    ret <2 x i8> [[EXTRACT_SUBV]]210;211  %shuf = shufflevector <2 x i8> %x, <2 x i8> %y, <3 x i32> <i32 0, i32 2, i32 0>212  %extract_subv = shufflevector <3 x i8> %shuf, <3 x i8> poison, <2 x i32> <i32 0, i32 1>213  ret <2 x i8> %extract_subv214}215 216; Undef elements in either mask are ok. Undefs from the 2nd shuffle mask should propagate to the new shuffle.217; The type of the inputs does not have to match the output type.218 219define <4 x i8> @extract_subvector_of_shuffle_undefs_types(<2 x i8> %x, <2 x i8> %y) {220; CHECK-LABEL: @extract_subvector_of_shuffle_undefs_types(221; CHECK-NEXT:    [[EXTRACT_SUBV:%.*]] = shufflevector <2 x i8> [[X:%.*]], <2 x i8> [[Y:%.*]], <4 x i32> <i32 poison, i32 2, i32 0, i32 poison>222; CHECK-NEXT:    ret <4 x i8> [[EXTRACT_SUBV]]223;224  %shuf = shufflevector <2 x i8> %x, <2 x i8> %y, <5 x i32> <i32 undef, i32 2, i32 0, i32 1, i32 0>225  %extract_subv = shufflevector <5 x i8> %shuf, <5 x i8> poison, <4 x i32> <i32 0, i32 1, i32 2, i32 undef>226  ret <4 x i8> %extract_subv227}228 229; Extra uses are not ok - we only do the transform when we can eliminate an instruction.230 231declare void @use_v5i8(<5 x i8>)232 233define <4 x i8> @extract_subvector_of_shuffle_extra_use(<2 x i8> %x, <2 x i8> %y) {234; CHECK-LABEL: @extract_subvector_of_shuffle_extra_use(235; 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>236; CHECK-NEXT:    call void @use_v5i8(<5 x i8> [[SHUF]])237; CHECK-NEXT:    [[EXTRACT_SUBV:%.*]] = shufflevector <5 x i8> [[SHUF]], <5 x i8> poison, <4 x i32> <i32 0, i32 1, i32 2, i32 poison>238; CHECK-NEXT:    ret <4 x i8> [[EXTRACT_SUBV]]239;240  %shuf = shufflevector <2 x i8> %x, <2 x i8> %y, <5 x i32> <i32 undef, i32 2, i32 0, i32 1, i32 0>241  call void @use_v5i8(<5 x i8> %shuf)242  %extract_subv = shufflevector <5 x i8> %shuf, <5 x i8> poison, <4 x i32> <i32 0, i32 1, i32 2, i32 undef>243  ret <4 x i8> %extract_subv244}245 246define <2 x i8> @test13a(i8 %x1, i8 %x2) {247; CHECK-LABEL: @test13a(248; CHECK-NEXT:    [[TMP1:%.*]] = insertelement <2 x i8> poison, i8 [[X2:%.*]], i64 0249; CHECK-NEXT:    [[TMP2:%.*]] = insertelement <2 x i8> [[TMP1]], i8 [[X1:%.*]], i64 1250; CHECK-NEXT:    [[D:%.*]] = add <2 x i8> [[TMP2]], <i8 7, i8 5>251; CHECK-NEXT:    ret <2 x i8> [[D]]252;253  %A = insertelement <2 x i8> poison, i8 %x1, i32 0254  %B = insertelement <2 x i8> %A, i8 %x2, i32 1255  %C = add <2 x i8> %B, <i8 5, i8 7>256  %D = shufflevector <2 x i8> %C, <2 x i8> poison, <2 x i32> <i32 1, i32 0>257  ret <2 x i8> %D258}259 260; Increasing length of vector ops is not a good canonicalization.261 262define <3 x i32> @add_wider(i32 %y, i32 %z) {263; CHECK-LABEL: @add_wider(264; CHECK-NEXT:    [[I0:%.*]] = insertelement <2 x i32> poison, i32 [[Y:%.*]], i64 0265; CHECK-NEXT:    [[I1:%.*]] = insertelement <2 x i32> [[I0]], i32 [[Z:%.*]], i64 1266; CHECK-NEXT:    [[A:%.*]] = add <2 x i32> [[I1]], splat (i32 255)267; CHECK-NEXT:    [[EXT:%.*]] = shufflevector <2 x i32> [[A]], <2 x i32> poison, <3 x i32> <i32 0, i32 1, i32 poison>268; CHECK-NEXT:    ret <3 x i32> [[EXT]]269;270  %i0 = insertelement <2 x i32> poison, i32 %y, i32 0271  %i1 = insertelement <2 x i32> %i0, i32 %z, i32 1272  %a = add <2 x i32> %i1, <i32 255, i32 255>273  %ext = shufflevector <2 x i32> %a, <2 x i32> poison, <3 x i32> <i32 0, i32 1, i32 undef>274  ret <3 x i32> %ext275}276 277; Increasing length of vector ops must be safe from illegal undef propagation.278 279define <3 x i32> @div_wider(i32 %y, i32 %z) {280; CHECK-LABEL: @div_wider(281; CHECK-NEXT:    [[I0:%.*]] = insertelement <2 x i32> poison, i32 [[Y:%.*]], i64 0282; CHECK-NEXT:    [[I1:%.*]] = insertelement <2 x i32> [[I0]], i32 [[Z:%.*]], i64 1283; CHECK-NEXT:    [[A:%.*]] = sdiv <2 x i32> [[I1]], splat (i32 255)284; CHECK-NEXT:    [[EXT:%.*]] = shufflevector <2 x i32> [[A]], <2 x i32> poison, <3 x i32> <i32 0, i32 1, i32 poison>285; CHECK-NEXT:    ret <3 x i32> [[EXT]]286;287  %i0 = insertelement <2 x i32> poison, i32 %y, i32 0288  %i1 = insertelement <2 x i32> %i0, i32 %z, i32 1289  %a = sdiv <2 x i32> %i1, <i32 255, i32 255>290  %ext = shufflevector <2 x i32> %a, <2 x i32> poison, <3 x i32> <i32 0, i32 1, i32 undef>291  ret <3 x i32> %ext292}293 294; Increasing length of insertelements (no math ops) is a good canonicalization.295 296define <3 x i8> @fold_inselts_with_widening_shuffle(i8 %x, i8 %y) {297; CHECK-LABEL: @fold_inselts_with_widening_shuffle(298; CHECK-NEXT:    [[TMP1:%.*]] = insertelement <3 x i8> poison, i8 [[X:%.*]], i64 0299; CHECK-NEXT:    [[WIDEN:%.*]] = insertelement <3 x i8> [[TMP1]], i8 [[Y:%.*]], i64 1300; CHECK-NEXT:    ret <3 x i8> [[WIDEN]]301;302  %ins0 = insertelement <2 x i8> poison, i8 %x, i32 0303  %ins1 = insertelement <2 x i8> %ins0, i8 %y, i32 1304  %widen = shufflevector <2 x i8> %ins1, <2 x i8> poison, <3 x i32> <i32 0, i32 1, i32 undef>305  ret <3 x i8> %widen306}307 308define <2 x i8> @test13b(i8 %x) {309; CHECK-LABEL: @test13b(310; CHECK-NEXT:    [[B:%.*]] = insertelement <2 x i8> poison, i8 [[X:%.*]], i64 1311; CHECK-NEXT:    ret <2 x i8> [[B]]312;313  %A = insertelement <2 x i8> poison, i8 %x, i32 0314  %B = shufflevector <2 x i8> %A, <2 x i8> poison, <2 x i32> <i32 undef, i32 0>315  ret <2 x i8> %B316}317 318define <2 x i8> @test13c(i8 %x1, i8 %x2) {319; CHECK-LABEL: @test13c(320; CHECK-NEXT:    [[TMP1:%.*]] = insertelement <2 x i8> poison, i8 [[X1:%.*]], i64 0321; CHECK-NEXT:    [[C:%.*]] = insertelement <2 x i8> [[TMP1]], i8 [[X2:%.*]], i64 1322; CHECK-NEXT:    ret <2 x i8> [[C]]323;324  %A = insertelement <4 x i8> poison, i8 %x1, i32 0325  %B = insertelement <4 x i8> %A, i8 %x2, i32 2326  %C = shufflevector <4 x i8> %B, <4 x i8> poison, <2 x i32> <i32 0, i32 2>327  ret <2 x i8> %C328}329 330define void @test14(i16 %conv10) {331; CHECK-LABEL: @test14(332; CHECK-NEXT:    store <4 x i16> <i16 poison, i16 poison, i16 poison, i16 23>, ptr undef, align 8333; CHECK-NEXT:    ret void334;335  %t = alloca <4 x i16>, align 8336  %vecinit6 = insertelement <4 x i16> poison, i16 23, i32 3337  store <4 x i16> %vecinit6, ptr undef338  %t1 = load <4 x i16>, ptr undef339  %vecinit11 = insertelement <4 x i16> poison, i16 %conv10, i32 3340  %div = udiv <4 x i16> %t1, %vecinit11341  store <4 x i16> %div, ptr %t342  %t4 = load <4 x i16>, ptr %t343  %t5 = shufflevector <4 x i16> %t4, <4 x i16> poison, <2 x i32> <i32 2, i32 0>344  %cmp = icmp ule <2 x i16> %t5, undef345  %sext = sext <2 x i1> %cmp to <2 x i16>346  ret void347}348 349; Check that sequences of insert/extract element are350; collapsed into valid shuffle instruction with correct shuffle indexes.351 352define <4 x float> @test15a(<4 x float> %LHS, <4 x float> %RHS) {353; CHECK-LABEL: @test15a(354; CHECK-NEXT:    [[T4:%.*]] = shufflevector <4 x float> [[LHS:%.*]], <4 x float> [[RHS:%.*]], <4 x i32> <i32 4, i32 0, i32 6, i32 6>355; CHECK-NEXT:    ret <4 x float> [[T4]]356;357  %t1 = extractelement <4 x float> %LHS, i32 0358  %t2 = insertelement <4 x float> %RHS, float %t1, i32 1359  %t3 = extractelement <4 x float> %RHS, i32 2360  %t4 = insertelement <4 x float> %t2, float %t3, i32 3361  ret <4 x float> %t4362}363 364define <4 x float> @test15b(<4 x float> %LHS, <4 x float> %RHS) {365; CHECK-LABEL: @test15b(366; CHECK-NEXT:    [[T5:%.*]] = shufflevector <4 x float> [[LHS:%.*]], <4 x float> [[RHS:%.*]], <4 x i32> <i32 4, i32 3, i32 6, i32 6>367; CHECK-NEXT:    ret <4 x float> [[T5]]368;369  %t0 = extractelement <4 x float> %LHS, i32 3370  %t1 = insertelement <4 x float> %RHS, float %t0, i32 0371  %t2 = extractelement <4 x float> %t1, i32 0372  %t3 = insertelement <4 x float> %RHS, float %t2, i32 1373  %t4 = extractelement <4 x float> %RHS, i32 2374  %t5 = insertelement <4 x float> %t3, float %t4, i32 3375  ret <4 x float> %t5376}377 378define <1 x i32> @test16a(i32 %ele) {379; CHECK-LABEL: @test16a(380; CHECK-NEXT:    ret <1 x i32> splat (i32 2)381;382  %t0 = insertelement <2 x i32> <i32 1, i32 undef>, i32 %ele, i32 1383  %t1 = shl <2 x i32> %t0, <i32 1, i32 1>384  %t2 = shufflevector <2 x i32> %t1, <2 x i32> poison, <1 x i32> <i32 0>385  ret <1 x i32> %t2386}387 388define <4 x i8> @test16b(i8 %ele) {389; CHECK-LABEL: @test16b(390; CHECK-NEXT:    ret <4 x i8> splat (i8 2)391;392  %t0 = insertelement <8 x i8> <i8 1, i8 1, i8 1, i8 1, i8 1, i8 1, i8 undef, i8 1>, i8 %ele, i32 6393  %t1 = shl <8 x i8> %t0, <i8 1, i8 1, i8 1, i8 1, i8 1, i8 1, i8 1, i8 1>394  %t2 = shufflevector <8 x i8> %t1, <8 x i8> poison, <4 x i32> <i32 1, i32 2, i32 3, i32 4>395  ret <4 x i8> %t2396}397 398; If composition of two shuffles is identity, shuffles can be removed.399define <4 x i32> @shuffle_17ident(<4 x i32> %v) {400; CHECK-LABEL: @shuffle_17ident(401; CHECK-NEXT:    ret <4 x i32> [[V:%.*]]402;403  %shuffle = shufflevector <4 x i32> %v, <4 x i32> zeroinitializer, <4 x i32> <i32 1, i32 2, i32 3, i32 0>404  %shuffle2 = shufflevector <4 x i32> %shuffle, <4 x i32> zeroinitializer, <4 x i32> <i32 3, i32 0, i32 1, i32 2>405  ret <4 x i32> %shuffle2406}407 408; swizzle can be put after operation409define <4 x i32> @shuffle_17and(<4 x i32> %v1, <4 x i32> %v2) {410; CHECK-LABEL: @shuffle_17and(411; CHECK-NEXT:    [[TMP1:%.*]] = and <4 x i32> [[V1:%.*]], [[V2:%.*]]412; CHECK-NEXT:    [[R:%.*]] = shufflevector <4 x i32> [[TMP1]], <4 x i32> poison, <4 x i32> <i32 1, i32 2, i32 3, i32 0>413; CHECK-NEXT:    ret <4 x i32> [[R]]414;415  %t1 = shufflevector <4 x i32> %v1, <4 x i32> zeroinitializer, <4 x i32> <i32 1, i32 2, i32 3, i32 0>416  %t2 = shufflevector <4 x i32> %v2, <4 x i32> zeroinitializer, <4 x i32> <i32 1, i32 2, i32 3, i32 0>417  %r = and <4 x i32> %t1, %t2418  ret <4 x i32> %r419}420 421declare void @use(<2 x float>)422 423; One extra use is ok to transform.424 425define <2 x float> @shuffle_fadd_multiuse(<2 x float> %v1, <2 x float> %v2) {426; CHECK-LABEL: @shuffle_fadd_multiuse(427; CHECK-NEXT:    [[T1:%.*]] = shufflevector <2 x float> [[V1:%.*]], <2 x float> poison, <2 x i32> <i32 1, i32 0>428; CHECK-NEXT:    [[TMP1:%.*]] = fadd <2 x float> [[V1]], [[V2:%.*]]429; CHECK-NEXT:    [[R:%.*]] = shufflevector <2 x float> [[TMP1]], <2 x float> poison, <2 x i32> <i32 1, i32 0>430; CHECK-NEXT:    call void @use(<2 x float> [[T1]])431; CHECK-NEXT:    ret <2 x float> [[R]]432;433  %t1 = shufflevector <2 x float> %v1, <2 x float> poison, <2 x i32> <i32 1, i32 0>434  %t2 = shufflevector <2 x float> %v2, <2 x float> poison, <2 x i32> <i32 1, i32 0>435  %r = fadd <2 x float> %t1, %t2436  call void @use(<2 x float> %t1)437  ret <2 x float> %r438}439 440define <2 x float> @shuffle_fdiv_multiuse(<2 x float> %v1, <2 x float> %v2) {441; CHECK-LABEL: @shuffle_fdiv_multiuse(442; CHECK-NEXT:    [[T2:%.*]] = shufflevector <2 x float> [[V2:%.*]], <2 x float> poison, <2 x i32> <i32 1, i32 0>443; CHECK-NEXT:    [[TMP1:%.*]] = fdiv <2 x float> [[V1:%.*]], [[V2]]444; CHECK-NEXT:    [[R:%.*]] = shufflevector <2 x float> [[TMP1]], <2 x float> poison, <2 x i32> <i32 1, i32 0>445; CHECK-NEXT:    call void @use(<2 x float> [[T2]])446; CHECK-NEXT:    ret <2 x float> [[R]]447;448  %t1 = shufflevector <2 x float> %v1, <2 x float> poison, <2 x i32> <i32 1, i32 0>449  %t2 = shufflevector <2 x float> %v2, <2 x float> poison, <2 x i32> <i32 1, i32 0>450  %r = fdiv <2 x float> %t1, %t2451  call void @use(<2 x float> %t2)452  ret <2 x float> %r453}454 455; But 2 extra uses would require an extra instruction.456 457define <2 x float> @shuffle_fsub_multiuse(<2 x float> %v1, <2 x float> %v2) {458; CHECK-LABEL: @shuffle_fsub_multiuse(459; CHECK-NEXT:    [[T1:%.*]] = shufflevector <2 x float> [[V1:%.*]], <2 x float> poison, <2 x i32> <i32 1, i32 0>460; CHECK-NEXT:    [[T2:%.*]] = shufflevector <2 x float> [[V2:%.*]], <2 x float> poison, <2 x i32> <i32 1, i32 0>461; CHECK-NEXT:    [[R:%.*]] = fsub <2 x float> [[T1]], [[T2]]462; CHECK-NEXT:    call void @use(<2 x float> [[T1]])463; CHECK-NEXT:    call void @use(<2 x float> [[T2]])464; CHECK-NEXT:    ret <2 x float> [[R]]465;466  %t1 = shufflevector <2 x float> %v1, <2 x float> poison, <2 x i32> <i32 1, i32 0>467  %t2 = shufflevector <2 x float> %v2, <2 x float> poison, <2 x i32> <i32 1, i32 0>468  %r = fsub <2 x float> %t1, %t2469  call void @use(<2 x float> %t1)470  call void @use(<2 x float> %t2)471  ret <2 x float> %r472}473 474define <4 x i32> @shuffle_17add(<4 x i32> %v1, <4 x i32> %v2) {475; CHECK-LABEL: @shuffle_17add(476; CHECK-NEXT:    [[TMP1:%.*]] = add <4 x i32> [[V1:%.*]], [[V2:%.*]]477; CHECK-NEXT:    [[R:%.*]] = shufflevector <4 x i32> [[TMP1]], <4 x i32> poison, <4 x i32> <i32 1, i32 2, i32 3, i32 0>478; CHECK-NEXT:    ret <4 x i32> [[R]]479;480  %t1 = shufflevector <4 x i32> %v1, <4 x i32> zeroinitializer, <4 x i32> <i32 1, i32 2, i32 3, i32 0>481  %t2 = shufflevector <4 x i32> %v2, <4 x i32> zeroinitializer, <4 x i32> <i32 1, i32 2, i32 3, i32 0>482  %r = add <4 x i32> %t1, %t2483  ret <4 x i32> %r484}485 486define <4 x i32> @shuffle_17addnsw(<4 x i32> %v1, <4 x i32> %v2) {487; CHECK-LABEL: @shuffle_17addnsw(488; CHECK-NEXT:    [[TMP1:%.*]] = add nsw <4 x i32> [[V1:%.*]], [[V2:%.*]]489; CHECK-NEXT:    [[R:%.*]] = shufflevector <4 x i32> [[TMP1]], <4 x i32> poison, <4 x i32> <i32 1, i32 2, i32 3, i32 0>490; CHECK-NEXT:    ret <4 x i32> [[R]]491;492  %t1 = shufflevector <4 x i32> %v1, <4 x i32> zeroinitializer, <4 x i32> <i32 1, i32 2, i32 3, i32 0>493  %t2 = shufflevector <4 x i32> %v2, <4 x i32> zeroinitializer, <4 x i32> <i32 1, i32 2, i32 3, i32 0>494  %r = add nsw <4 x i32> %t1, %t2495  ret <4 x i32> %r496}497 498define <4 x i32> @shuffle_17addnuw(<4 x i32> %v1, <4 x i32> %v2) {499; CHECK-LABEL: @shuffle_17addnuw(500; CHECK-NEXT:    [[TMP1:%.*]] = add nuw <4 x i32> [[V1:%.*]], [[V2:%.*]]501; CHECK-NEXT:    [[R:%.*]] = shufflevector <4 x i32> [[TMP1]], <4 x i32> poison, <4 x i32> <i32 1, i32 2, i32 3, i32 0>502; CHECK-NEXT:    ret <4 x i32> [[R]]503;504  %t1 = shufflevector <4 x i32> %v1, <4 x i32> zeroinitializer, <4 x i32> <i32 1, i32 2, i32 3, i32 0>505  %t2 = shufflevector <4 x i32> %v2, <4 x i32> zeroinitializer, <4 x i32> <i32 1, i32 2, i32 3, i32 0>506  %r = add nuw <4 x i32> %t1, %t2507  ret <4 x i32> %r508}509 510define <4 x float> @shuffle_17fsub_fast(<4 x float> %v1, <4 x float> %v2) {511; CHECK-LABEL: @shuffle_17fsub_fast(512; CHECK-NEXT:    [[TMP1:%.*]] = fsub fast <4 x float> [[V1:%.*]], [[V2:%.*]]513; CHECK-NEXT:    [[R:%.*]] = shufflevector <4 x float> [[TMP1]], <4 x float> poison, <4 x i32> <i32 1, i32 2, i32 3, i32 0>514; CHECK-NEXT:    ret <4 x float> [[R]]515;516  %t1 = shufflevector <4 x float> %v1, <4 x float> zeroinitializer, <4 x i32> <i32 1, i32 2, i32 3, i32 0>517  %t2 = shufflevector <4 x float> %v2, <4 x float> zeroinitializer, <4 x i32> <i32 1, i32 2, i32 3, i32 0>518  %r = fsub fast <4 x float> %t1, %t2519  ret <4 x float> %r520}521 522define <4 x i32> @add_const(<4 x i32> %v) {523; CHECK-LABEL: @add_const(524; CHECK-NEXT:    [[TMP1:%.*]] = add <4 x i32> [[V:%.*]], <i32 44, i32 41, i32 42, i32 43>525; CHECK-NEXT:    [[R:%.*]] = shufflevector <4 x i32> [[TMP1]], <4 x i32> poison, <4 x i32> <i32 1, i32 2, i32 3, i32 0>526; CHECK-NEXT:    ret <4 x i32> [[R]]527;528  %t1 = shufflevector <4 x i32> %v, <4 x i32> poison, <4 x i32> <i32 1, i32 2, i32 3, i32 0>529  %r = add <4 x i32> %t1, <i32 41, i32 42, i32 43, i32 44>530  ret <4 x i32> %r531}532 533define <4 x i32> @sub_const(<4 x i32> %v) {534; CHECK-LABEL: @sub_const(535; CHECK-NEXT:    [[TMP1:%.*]] = sub <4 x i32> <i32 44, i32 43, i32 42, i32 41>, [[V:%.*]]536; CHECK-NEXT:    [[R:%.*]] = shufflevector <4 x i32> [[TMP1]], <4 x i32> poison, <4 x i32> <i32 3, i32 2, i32 1, i32 0>537; CHECK-NEXT:    ret <4 x i32> [[R]]538;539  %t1 = shufflevector <4 x i32> %v, <4 x i32> poison, <4 x i32> <i32 3, i32 2, i32 1, i32 0>540  %r = sub <4 x i32> <i32 41, i32 42, i32 43, i32 44>, %t1541  ret <4 x i32> %r542}543 544; Math before shuffle requires an extra shuffle.545 546define <2 x float> @fadd_const_multiuse(<2 x float> %v) {547; CHECK-LABEL: @fadd_const_multiuse(548; CHECK-NEXT:    [[T1:%.*]] = shufflevector <2 x float> [[V:%.*]], <2 x float> poison, <2 x i32> <i32 1, i32 0>549; CHECK-NEXT:    [[R:%.*]] = fadd <2 x float> [[T1]], <float 4.100000e+01, float 4.200000e+01>550; CHECK-NEXT:    call void @use(<2 x float> [[T1]])551; CHECK-NEXT:    ret <2 x float> [[R]]552;553  %t1 = shufflevector <2 x float> %v, <2 x float> poison, <2 x i32> <i32 1, i32 0>554  %r = fadd <2 x float> %t1, <float 41.0, float 42.0>555  call void @use(<2 x float> %t1)556  ret <2 x float> %r557}558 559; Math before splat allows replacing constant elements with undef lanes.560 561define <4 x i32> @mul_const_splat(<4 x i32> %v) {562; CHECK-LABEL: @mul_const_splat(563; CHECK-NEXT:    [[TMP1:%.*]] = mul <4 x i32> [[V:%.*]], <i32 poison, i32 42, i32 poison, i32 poison>564; CHECK-NEXT:    [[R:%.*]] = shufflevector <4 x i32> [[TMP1]], <4 x i32> poison, <4 x i32> <i32 1, i32 1, i32 1, i32 1>565; CHECK-NEXT:    ret <4 x i32> [[R]]566;567  %t1 = shufflevector <4 x i32> %v, <4 x i32> poison, <4 x i32> <i32 1, i32 1, i32 1, i32 1>568  %r = mul <4 x i32> <i32 42, i32 42, i32 42, i32 42>, %t1569  ret <4 x i32> %r570}571 572; Take 2 elements of a vector and shift each of those by a different amount573 574define <4 x i32> @lshr_const_half_splat(<4 x i32> %v) {575; CHECK-LABEL: @lshr_const_half_splat(576; CHECK-NEXT:    [[TMP1:%.*]] = lshr <4 x i32> <i32 poison, i32 8, i32 9, i32 poison>, [[V:%.*]]577; CHECK-NEXT:    [[R:%.*]] = shufflevector <4 x i32> [[TMP1]], <4 x i32> poison, <4 x i32> <i32 1, i32 1, i32 2, i32 2>578; CHECK-NEXT:    ret <4 x i32> [[R]]579;580  %t1 = shufflevector <4 x i32> %v, <4 x i32> poison, <4 x i32> <i32 1, i32 1, i32 2, i32 2>581  %r = lshr <4 x i32> <i32 8, i32 8, i32 9, i32 9>, %t1582  ret <4 x i32> %r583}584 585; We can't change this because there's no pre-shuffle version of the fmul constant.586 587define <2 x float> @fmul_const_invalid_constant(<2 x float> %v) {588; CHECK-LABEL: @fmul_const_invalid_constant(589; CHECK-NEXT:    [[T1:%.*]] = shufflevector <2 x float> [[V:%.*]], <2 x float> poison, <2 x i32> zeroinitializer590; CHECK-NEXT:    [[R:%.*]] = fmul <2 x float> [[T1]], <float 4.100000e+01, float 4.200000e+01>591; CHECK-NEXT:    ret <2 x float> [[R]]592;593  %t1 = shufflevector <2 x float> %v, <2 x float> poison, <2 x i32> <i32 0, i32 0>594  %r = fmul <2 x float> %t1, <float 41.0, float 42.0>595  ret <2 x float> %r596}597 598; Reduce the width of the binop by moving it ahead of a shuffle.599 600define <4 x i8> @widening_shuffle_add_1(<2 x i8> %x) {601; CHECK-LABEL: @widening_shuffle_add_1(602; CHECK-NEXT:    [[TMP1:%.*]] = add <2 x i8> [[X:%.*]], <i8 42, i8 43>603; CHECK-NEXT:    [[R:%.*]] = shufflevector <2 x i8> [[TMP1]], <2 x i8> poison, <4 x i32> <i32 0, i32 1, i32 poison, i32 poison>604; CHECK-NEXT:    ret <4 x i8> [[R]]605;606  %widex = shufflevector <2 x i8> %x, <2 x i8> poison, <4 x i32> <i32 0, i32 1, i32 undef, i32 undef>607  %r = add <4 x i8> %widex, <i8 42, i8 43, i8 44, i8 45>608  ret <4 x i8> %r609}610 611; Reduce the width of the binop by moving it ahead of a shuffle.612 613define <4 x i8> @widening_shuffle_add_2(<2 x i8> %x) {614; CHECK-LABEL: @widening_shuffle_add_2(615; CHECK-NEXT:    [[TMP1:%.*]] = add <2 x i8> [[X:%.*]], <i8 43, i8 42>616; CHECK-NEXT:    [[R:%.*]] = shufflevector <2 x i8> [[TMP1]], <2 x i8> poison, <4 x i32> <i32 1, i32 0, i32 poison, i32 poison>617; CHECK-NEXT:    ret <4 x i8> [[R]]618;619  %widex = shufflevector <2 x i8> %x, <2 x i8> poison, <4 x i32> <i32 1, i32 0, i32 undef, i32 undef>620  %r = add <4 x i8> %widex, <i8 42, i8 43, i8 44, i8 45>621  ret <4 x i8> %r622}623 624; Negative test - widening shuffles have the same mask/constant constraint as non-size-changing shuffles.625 626define <4 x i8> @widening_shuffle_add_invalid_constant(<2 x i8> %x) {627; CHECK-LABEL: @widening_shuffle_add_invalid_constant(628; CHECK-NEXT:    [[WIDEX:%.*]] = shufflevector <2 x i8> [[X:%.*]], <2 x i8> poison, <4 x i32> <i32 1, i32 1, i32 poison, i32 poison>629; CHECK-NEXT:    [[R:%.*]] = add <4 x i8> [[WIDEX]], <i8 42, i8 43, i8 44, i8 45>630; CHECK-NEXT:    ret <4 x i8> [[R]]631;632  %widex = shufflevector <2 x i8> %x, <2 x i8> poison, <4 x i32> <i32 1, i32 1, i32 undef, i32 undef>633  %r = add <4 x i8> %widex, <i8 42, i8 43, i8 44, i8 45>634  ret <4 x i8> %r635}636 637; Negative test - widening shuffles have an additional constraint: they must not extend with anything but undefs.638 639define <4 x i8> @widening_shuffle_add_invalid_mask(<2 x i8> %x) {640; CHECK-LABEL: @widening_shuffle_add_invalid_mask(641; CHECK-NEXT:    [[WIDEX:%.*]] = shufflevector <2 x i8> [[X:%.*]], <2 x i8> poison, <4 x i32> <i32 0, i32 1, i32 poison, i32 0>642; CHECK-NEXT:    [[R:%.*]] = add <4 x i8> [[WIDEX]], <i8 42, i8 43, i8 44, i8 45>643; CHECK-NEXT:    ret <4 x i8> [[R]]644;645  %widex = shufflevector <2 x i8> %x, <2 x i8> poison, <4 x i32> <i32 0, i32 1, i32 undef, i32 0>646  %r = add <4 x i8> %widex, <i8 42, i8 43, i8 44, i8 45>647  ret <4 x i8> %r648}649 650; A binop that produces undef in the high lanes can be moved before the shuffle.651; This is ok because 'shl C, undef --> undef'.652 653define <4 x i16> @widening_shuffle_shl_constant_op0(<2 x i16> %v) {654; CHECK-LABEL: @widening_shuffle_shl_constant_op0(655; CHECK-NEXT:    [[TMP1:%.*]] = shl <2 x i16> <i16 42, i16 -42>, [[V:%.*]]656; CHECK-NEXT:    [[BO:%.*]] = shufflevector <2 x i16> [[TMP1]], <2 x i16> poison, <4 x i32> <i32 0, i32 1, i32 poison, i32 poison>657; CHECK-NEXT:    ret <4 x i16> [[BO]]658;659  %shuf = shufflevector <2 x i16> %v, <2 x i16> poison, <4 x i32> <i32 0, i32 1, i32 undef, i32 undef>660  %bo = shl <4 x i16> <i16 42, i16 -42, i16 -1, i16 -1>, %shuf661  ret <4 x i16> %bo662}663 664; A binop that produces undef in the high lanes can be moved before the shuffle.665; This is ok because 'shl undef, 0 --> undef'.666 667define <4 x i16> @widening_shuffle_shl_constant_op1(<2 x i16> %v) {668; CHECK-LABEL: @widening_shuffle_shl_constant_op1(669; CHECK-NEXT:    [[TMP1:%.*]] = shl <2 x i16> [[V:%.*]], <i16 2, i16 4>670; CHECK-NEXT:    [[BO:%.*]] = shufflevector <2 x i16> [[TMP1]], <2 x i16> poison, <4 x i32> <i32 0, i32 1, i32 poison, i32 poison>671; CHECK-NEXT:    ret <4 x i16> [[BO]]672;673  %shuf = shufflevector <2 x i16> %v, <2 x i16> poison, <4 x i32> <i32 0, i32 1, i32 undef, i32 undef>674  %bo = shl <4 x i16> %shuf, <i16 2, i16 4, i16 0, i16 0>675  ret <4 x i16> %bo676}677 678; This is valid for poison, but would not be valid for undef.679 680define <4 x i16> @widening_shuffle_shl_constant_op1_non0(<2 x i16> %v) {681; CHECK-LABEL: @widening_shuffle_shl_constant_op1_non0(682; CHECK-NEXT:    [[TMP1:%.*]] = shl <2 x i16> [[V:%.*]], <i16 2, i16 4>683; CHECK-NEXT:    [[BO:%.*]] = shufflevector <2 x i16> [[TMP1]], <2 x i16> poison, <4 x i32> <i32 0, i32 1, i32 poison, i32 poison>684; CHECK-NEXT:    ret <4 x i16> [[BO]]685;686  %shuf = shufflevector <2 x i16> %v, <2 x i16> poison, <4 x i32> <i32 0, i32 1, i32 undef, i32 undef>687  %bo = shl <4 x i16> %shuf, <i16 2, i16 4, i16 1, i16 2>688  ret <4 x i16> %bo689}690 691define <4 x i16> @widening_shuffle_or(<2 x i16> %v) {692; CHECK-LABEL: @widening_shuffle_or(693; CHECK-NEXT:    [[TMP1:%.*]] = or <2 x i16> [[V:%.*]], <i16 42, i16 -42>694; CHECK-NEXT:    [[BO:%.*]] = shufflevector <2 x i16> [[TMP1]], <2 x i16> poison, <4 x i32> <i32 0, i32 1, i32 poison, i32 poison>695; CHECK-NEXT:    ret <4 x i16> [[BO]]696;697  %shuf = shufflevector <2 x i16> %v, <2 x i16> poison, <4 x i32> <i32 0, i32 1, i32 undef, i32 undef>698  %bo = or <4 x i16> %shuf, <i16 42, i16 -42, i16 -1, i16 -1>699  ret <4 x i16> %bo700}701 702define <4 x i32> @shuffle_17add2(<4 x i32> %v) {703; CHECK-LABEL: @shuffle_17add2(704; CHECK-NEXT:    [[TMP1:%.*]] = shl <4 x i32> [[V:%.*]], splat (i32 1)705; CHECK-NEXT:    ret <4 x i32> [[TMP1]]706;707  %t1 = shufflevector <4 x i32> %v, <4 x i32> zeroinitializer, <4 x i32> <i32 3, i32 2, i32 1, i32 0>708  %t2 = add <4 x i32> %t1, %t1709  %r = shufflevector <4 x i32> %t2, <4 x i32> zeroinitializer, <4 x i32> <i32 3, i32 2, i32 1, i32 0>710  ret <4 x i32> %r711}712 713define <4 x i32> @shuffle_17mulsplat(<4 x i32> %v) {714; CHECK-LABEL: @shuffle_17mulsplat(715; CHECK-NEXT:    [[TMP1:%.*]] = mul <4 x i32> [[V:%.*]], [[V]]716; CHECK-NEXT:    [[M1:%.*]] = shufflevector <4 x i32> [[TMP1]], <4 x i32> poison, <4 x i32> zeroinitializer717; CHECK-NEXT:    ret <4 x i32> [[M1]]718;719  %s1 = shufflevector <4 x i32> %v, <4 x i32> zeroinitializer, <4 x i32> zeroinitializer720  %m1 = mul <4 x i32> %s1, %s1721  %s2 = shufflevector <4 x i32> %m1, <4 x i32> zeroinitializer, <4 x i32> <i32 1, i32 1, i32 1, i32 1>722  ret <4 x i32> %s2723}724 725; Do not reorder shuffle and binop if LHS of shuffles are of different size726define <2 x i32> @pr19717(<4 x i32> %in0, <2 x i32> %in1) {727; CHECK-LABEL: @pr19717(728; CHECK-NEXT:    [[SHUFFLE:%.*]] = shufflevector <4 x i32> [[IN0:%.*]], <4 x i32> poison, <2 x i32> zeroinitializer729; CHECK-NEXT:    [[SHUFFLE4:%.*]] = shufflevector <2 x i32> [[IN1:%.*]], <2 x i32> poison, <2 x i32> zeroinitializer730; CHECK-NEXT:    [[MUL:%.*]] = mul <2 x i32> [[SHUFFLE]], [[SHUFFLE4]]731; CHECK-NEXT:    ret <2 x i32> [[MUL]]732;733  %shuffle = shufflevector <4 x i32> %in0, <4 x i32> %in0, <2 x i32> zeroinitializer734  %shuffle4 = shufflevector <2 x i32> %in1, <2 x i32> %in1, <2 x i32> zeroinitializer735  %mul = mul <2 x i32> %shuffle, %shuffle4736  ret <2 x i32> %mul737}738 739define <4 x i16> @pr19717a(<8 x i16> %in0, <8 x i16> %in1) {740; CHECK-LABEL: @pr19717a(741; CHECK-NEXT:    [[TMP1:%.*]] = mul <8 x i16> [[IN0:%.*]], [[IN1:%.*]]742; CHECK-NEXT:    [[MUL:%.*]] = shufflevector <8 x i16> [[TMP1]], <8 x i16> poison, <4 x i32> <i32 5, i32 5, i32 5, i32 5>743; CHECK-NEXT:    ret <4 x i16> [[MUL]]744;745  %shuffle = shufflevector <8 x i16> %in0, <8 x i16> %in0, <4 x i32> <i32 5, i32 5, i32 5, i32 5>746  %shuffle1 = shufflevector <8 x i16> %in1, <8 x i16> %in1, <4 x i32> <i32 5, i32 5, i32 5, i32 5>747  %mul = mul <4 x i16> %shuffle, %shuffle1748  ret <4 x i16> %mul749}750 751define <8 x i8> @pr19730(<16 x i8> %in0) {752; CHECK-LABEL: @pr19730(753; 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>754; 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>755; CHECK-NEXT:    ret <8 x i8> [[SHUFFLE1]]756;757  %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>758  %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>759  ret <8 x i8> %shuffle1760}761 762define i32 @pr19737(<4 x i32> %in0) {763; CHECK-LABEL: @pr19737(764; CHECK-NEXT:    [[TMP1:%.*]] = extractelement <4 x i32> [[IN0:%.*]], i64 0765; CHECK-NEXT:    ret i32 [[TMP1]]766;767  %shuffle.i = shufflevector <4 x i32> zeroinitializer, <4 x i32> %in0, <4 x i32> <i32 0, i32 4, i32 2, i32 6>768  %neg.i = xor <4 x i32> %shuffle.i, <i32 -1, i32 -1, i32 -1, i32 -1>769  %and.i = and <4 x i32> %in0, %neg.i770  %rv = extractelement <4 x i32> %and.i, i32 0771  ret i32 %rv772}773 774; In PR20059 ( http://llvm.org/pr20059 ), shufflevector operations are reordered/removed775; for an srem operation. This is not a valid optimization because it may cause a trap776; on div-by-zero.777 778define <4 x i32> @pr20059(<4 x i32> %p1, <4 x i32> %p2) {779; CHECK-LABEL: @pr20059(780; CHECK-NEXT:    [[SPLAT1:%.*]] = shufflevector <4 x i32> [[P1:%.*]], <4 x i32> poison, <4 x i32> zeroinitializer781; CHECK-NEXT:    [[SPLAT2:%.*]] = shufflevector <4 x i32> [[P2:%.*]], <4 x i32> poison, <4 x i32> zeroinitializer782; CHECK-NEXT:    [[RETVAL:%.*]] = srem <4 x i32> [[SPLAT1]], [[SPLAT2]]783; CHECK-NEXT:    ret <4 x i32> [[RETVAL]]784;785  %splat1 = shufflevector <4 x i32> %p1, <4 x i32> poison, <4 x i32> zeroinitializer786  %splat2 = shufflevector <4 x i32> %p2, <4 x i32> poison, <4 x i32> zeroinitializer787  %retval = srem <4 x i32> %splat1, %splat2788  ret <4 x i32> %retval789}790 791define <4 x i32> @pr20114(<4 x i32> %__mask) {792; CHECK-LABEL: @pr20114(793; CHECK-NEXT:    [[MASK01_I:%.*]] = shufflevector <4 x i32> [[__MASK:%.*]], <4 x i32> poison, <4 x i32> <i32 0, i32 0, i32 1, i32 1>794; 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>)795; CHECK-NEXT:    ret <4 x i32> [[MASKED_NEW_I_I_I]]796;797  %mask01.i = shufflevector <4 x i32> %__mask, <4 x i32> poison, <4 x i32> <i32 0, i32 0, i32 1, i32 1>798  %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.i799  ret <4 x i32> %masked_new.i.i.i800}801 802define <2 x ptr> @pr23113(<4 x ptr> %A) {803; CHECK-LABEL: @pr23113(804; CHECK-NEXT:    [[TMP1:%.*]] = shufflevector <4 x ptr> [[A:%.*]], <4 x ptr> poison, <2 x i32> <i32 0, i32 1>805; CHECK-NEXT:    ret <2 x ptr> [[TMP1]]806;807  %1 = shufflevector <4 x ptr> %A, <4 x ptr> poison, <2 x i32> <i32 0, i32 1>808  ret <2 x ptr> %1809}810 811; Unused lanes in the new binop should not kill the entire op (although it may simplify anyway as shown here).812 813define <2 x i32> @PR37648(<2 x i32> %x) {814; CHECK-LABEL: @PR37648(815; CHECK-NEXT:    ret <2 x i32> zeroinitializer816;817  %splat = shufflevector <2 x i32> %x, <2 x i32> poison, <2 x i32> zeroinitializer818  %r = urem <2 x i32> %splat, <i32 1, i32 1>819  ret <2 x i32> %r820}821 822; Test shuffle followed by binop with splat constant for all 18 binop opcodes.823; Test with constant as operand 0 and operand 1 for non-commutative opcodes.824 825define <2 x i32> @add_splat_constant(<2 x i32> %x) {826; CHECK-LABEL: @add_splat_constant(827; CHECK-NEXT:    [[TMP1:%.*]] = add <2 x i32> [[X:%.*]], <i32 42, i32 poison>828; CHECK-NEXT:    [[R:%.*]] = shufflevector <2 x i32> [[TMP1]], <2 x i32> poison, <2 x i32> zeroinitializer829; CHECK-NEXT:    ret <2 x i32> [[R]]830;831  %splat = shufflevector <2 x i32> %x, <2 x i32> poison, <2 x i32> zeroinitializer832  %r = add <2 x i32> %splat, <i32 42, i32 42>833  ret <2 x i32> %r834}835 836define <2 x i32> @sub_splat_constant0(<2 x i32> %x) {837; CHECK-LABEL: @sub_splat_constant0(838; CHECK-NEXT:    [[TMP1:%.*]] = sub <2 x i32> <i32 42, i32 poison>, [[X:%.*]]839; CHECK-NEXT:    [[R:%.*]] = shufflevector <2 x i32> [[TMP1]], <2 x i32> poison, <2 x i32> zeroinitializer840; CHECK-NEXT:    ret <2 x i32> [[R]]841;842  %splat = shufflevector <2 x i32> %x, <2 x i32> poison, <2 x i32> zeroinitializer843  %r = sub <2 x i32> <i32 42, i32 42>, %splat844  ret <2 x i32> %r845}846 847define <2 x i32> @sub_splat_constant1(<2 x i32> %x) {848; CHECK-LABEL: @sub_splat_constant1(849; CHECK-NEXT:    [[TMP1:%.*]] = add <2 x i32> [[X:%.*]], <i32 -42, i32 poison>850; CHECK-NEXT:    [[R:%.*]] = shufflevector <2 x i32> [[TMP1]], <2 x i32> poison, <2 x i32> zeroinitializer851; CHECK-NEXT:    ret <2 x i32> [[R]]852;853  %splat = shufflevector <2 x i32> %x, <2 x i32> poison, <2 x i32> zeroinitializer854  %r = sub <2 x i32> %splat, <i32 42, i32 42>855  ret <2 x i32> %r856}857 858define <2 x i32> @mul_splat_constant(<2 x i32> %x) {859; CHECK-LABEL: @mul_splat_constant(860; CHECK-NEXT:    [[TMP1:%.*]] = mul <2 x i32> [[X:%.*]], <i32 42, i32 poison>861; CHECK-NEXT:    [[R:%.*]] = shufflevector <2 x i32> [[TMP1]], <2 x i32> poison, <2 x i32> zeroinitializer862; CHECK-NEXT:    ret <2 x i32> [[R]]863;864  %splat = shufflevector <2 x i32> %x, <2 x i32> poison, <2 x i32> zeroinitializer865  %r = mul <2 x i32> %splat, <i32 42, i32 42>866  ret <2 x i32> %r867}868 869define <2 x i32> @shl_splat_constant0(<2 x i32> %x) {870; CHECK-LABEL: @shl_splat_constant0(871; CHECK-NEXT:    [[TMP1:%.*]] = shl <2 x i32> <i32 5, i32 poison>, [[X:%.*]]872; CHECK-NEXT:    [[R:%.*]] = shufflevector <2 x i32> [[TMP1]], <2 x i32> poison, <2 x i32> zeroinitializer873; CHECK-NEXT:    ret <2 x i32> [[R]]874;875  %splat = shufflevector <2 x i32> %x, <2 x i32> poison, <2 x i32> zeroinitializer876  %r = shl <2 x i32> <i32 5, i32 5>, %splat877  ret <2 x i32> %r878}879 880define <2 x i32> @shl_splat_constant1(<2 x i32> %x) {881; CHECK-LABEL: @shl_splat_constant1(882; CHECK-NEXT:    [[TMP1:%.*]] = shl <2 x i32> [[X:%.*]], <i32 5, i32 poison>883; CHECK-NEXT:    [[R:%.*]] = shufflevector <2 x i32> [[TMP1]], <2 x i32> poison, <2 x i32> zeroinitializer884; CHECK-NEXT:    ret <2 x i32> [[R]]885;886  %splat = shufflevector <2 x i32> %x, <2 x i32> poison, <2 x i32> zeroinitializer887  %r = shl <2 x i32> %splat, <i32 5, i32 5>888  ret <2 x i32> %r889}890 891define <2 x i32> @ashr_splat_constant0(<2 x i32> %x) {892; CHECK-LABEL: @ashr_splat_constant0(893; CHECK-NEXT:    [[TMP1:%.*]] = lshr <2 x i32> <i32 5, i32 poison>, [[X:%.*]]894; CHECK-NEXT:    [[R:%.*]] = shufflevector <2 x i32> [[TMP1]], <2 x i32> poison, <2 x i32> zeroinitializer895; CHECK-NEXT:    ret <2 x i32> [[R]]896;897  %splat = shufflevector <2 x i32> %x, <2 x i32> poison, <2 x i32> zeroinitializer898  %r = ashr <2 x i32> <i32 5, i32 5>, %splat899  ret <2 x i32> %r900}901 902define <2 x i32> @ashr_splat_constant1(<2 x i32> %x) {903; CHECK-LABEL: @ashr_splat_constant1(904; CHECK-NEXT:    [[TMP1:%.*]] = ashr <2 x i32> [[X:%.*]], <i32 5, i32 poison>905; CHECK-NEXT:    [[R:%.*]] = shufflevector <2 x i32> [[TMP1]], <2 x i32> poison, <2 x i32> zeroinitializer906; CHECK-NEXT:    ret <2 x i32> [[R]]907;908  %splat = shufflevector <2 x i32> %x, <2 x i32> poison, <2 x i32> zeroinitializer909  %r = ashr <2 x i32> %splat, <i32 5, i32 5>910  ret <2 x i32> %r911}912 913define <2 x i32> @lshr_splat_constant0(<2 x i32> %x) {914; CHECK-LABEL: @lshr_splat_constant0(915; CHECK-NEXT:    [[TMP1:%.*]] = lshr <2 x i32> <i32 5, i32 poison>, [[X:%.*]]916; CHECK-NEXT:    [[R:%.*]] = shufflevector <2 x i32> [[TMP1]], <2 x i32> poison, <2 x i32> zeroinitializer917; CHECK-NEXT:    ret <2 x i32> [[R]]918;919  %splat = shufflevector <2 x i32> %x, <2 x i32> poison, <2 x i32> zeroinitializer920  %r = lshr <2 x i32> <i32 5, i32 5>, %splat921  ret <2 x i32> %r922}923 924define <2 x i32> @lshr_splat_constant1(<2 x i32> %x) {925; CHECK-LABEL: @lshr_splat_constant1(926; CHECK-NEXT:    [[TMP1:%.*]] = lshr <2 x i32> [[X:%.*]], <i32 5, i32 poison>927; CHECK-NEXT:    [[R:%.*]] = shufflevector <2 x i32> [[TMP1]], <2 x i32> poison, <2 x i32> zeroinitializer928; CHECK-NEXT:    ret <2 x i32> [[R]]929;930  %splat = shufflevector <2 x i32> %x, <2 x i32> poison, <2 x i32> zeroinitializer931  %r = lshr <2 x i32> %splat, <i32 5, i32 5>932  ret <2 x i32> %r933}934 935define <2 x i32> @urem_splat_constant0(<2 x i32> %x) {936; CHECK-LABEL: @urem_splat_constant0(937; CHECK-NEXT:    [[SPLAT:%.*]] = shufflevector <2 x i32> [[X:%.*]], <2 x i32> poison, <2 x i32> zeroinitializer938; CHECK-NEXT:    [[R:%.*]] = urem <2 x i32> splat (i32 42), [[SPLAT]]939; CHECK-NEXT:    ret <2 x i32> [[R]]940;941  %splat = shufflevector <2 x i32> %x, <2 x i32> poison, <2 x i32> zeroinitializer942  %r = urem <2 x i32> <i32 42, i32 42>, %splat943  ret <2 x i32> %r944}945 946define <2 x i32> @urem_splat_constant1(<2 x i32> %x) {947; CHECK-LABEL: @urem_splat_constant1(948; CHECK-NEXT:    [[TMP1:%.*]] = urem <2 x i32> [[X:%.*]], <i32 42, i32 1>949; CHECK-NEXT:    [[R:%.*]] = shufflevector <2 x i32> [[TMP1]], <2 x i32> poison, <2 x i32> zeroinitializer950; CHECK-NEXT:    ret <2 x i32> [[R]]951;952  %splat = shufflevector <2 x i32> %x, <2 x i32> poison, <2 x i32> zeroinitializer953  %r = urem <2 x i32> %splat, <i32 42, i32 42>954  ret <2 x i32> %r955}956 957define <2 x i32> @srem_splat_constant0(<2 x i32> %x) {958; CHECK-LABEL: @srem_splat_constant0(959; CHECK-NEXT:    [[SPLAT:%.*]] = shufflevector <2 x i32> [[X:%.*]], <2 x i32> poison, <2 x i32> zeroinitializer960; CHECK-NEXT:    [[R:%.*]] = srem <2 x i32> splat (i32 42), [[SPLAT]]961; CHECK-NEXT:    ret <2 x i32> [[R]]962;963  %splat = shufflevector <2 x i32> %x, <2 x i32> poison, <2 x i32> zeroinitializer964  %r = srem <2 x i32> <i32 42, i32 42>, %splat965  ret <2 x i32> %r966}967 968define <2 x i32> @srem_splat_constant1(<2 x i32> %x) {969; CHECK-LABEL: @srem_splat_constant1(970; CHECK-NEXT:    [[TMP1:%.*]] = srem <2 x i32> [[X:%.*]], <i32 42, i32 1>971; CHECK-NEXT:    [[R:%.*]] = shufflevector <2 x i32> [[TMP1]], <2 x i32> poison, <2 x i32> zeroinitializer972; CHECK-NEXT:    ret <2 x i32> [[R]]973;974  %splat = shufflevector <2 x i32> %x, <2 x i32> poison, <2 x i32> zeroinitializer975  %r = srem <2 x i32> %splat, <i32 42, i32 42>976  ret <2 x i32> %r977}978 979define <2 x i32> @udiv_splat_constant0(<2 x i32> %x) {980; CHECK-LABEL: @udiv_splat_constant0(981; CHECK-NEXT:    [[SPLAT:%.*]] = shufflevector <2 x i32> [[X:%.*]], <2 x i32> poison, <2 x i32> zeroinitializer982; CHECK-NEXT:    [[R:%.*]] = udiv <2 x i32> splat (i32 42), [[SPLAT]]983; CHECK-NEXT:    ret <2 x i32> [[R]]984;985  %splat = shufflevector <2 x i32> %x, <2 x i32> poison, <2 x i32> zeroinitializer986  %r = udiv <2 x i32> <i32 42, i32 42>, %splat987  ret <2 x i32> %r988}989 990define <2 x i32> @udiv_splat_constant1(<2 x i32> %x) {991; CHECK-LABEL: @udiv_splat_constant1(992; CHECK-NEXT:    [[TMP1:%.*]] = udiv <2 x i32> [[X:%.*]], <i32 42, i32 1>993; CHECK-NEXT:    [[R:%.*]] = shufflevector <2 x i32> [[TMP1]], <2 x i32> poison, <2 x i32> zeroinitializer994; CHECK-NEXT:    ret <2 x i32> [[R]]995;996  %splat = shufflevector <2 x i32> %x, <2 x i32> poison, <2 x i32> zeroinitializer997  %r = udiv <2 x i32> %splat, <i32 42, i32 42>998  ret <2 x i32> %r999}1000 1001define <2 x i32> @sdiv_splat_constant0(<2 x i32> %x) {1002; CHECK-LABEL: @sdiv_splat_constant0(1003; CHECK-NEXT:    [[SPLAT:%.*]] = shufflevector <2 x i32> [[X:%.*]], <2 x i32> poison, <2 x i32> zeroinitializer1004; CHECK-NEXT:    [[R:%.*]] = sdiv <2 x i32> splat (i32 42), [[SPLAT]]1005; CHECK-NEXT:    ret <2 x i32> [[R]]1006;1007  %splat = shufflevector <2 x i32> %x, <2 x i32> poison, <2 x i32> zeroinitializer1008  %r = sdiv <2 x i32> <i32 42, i32 42>, %splat1009  ret <2 x i32> %r1010}1011 1012define <2 x i32> @sdiv_splat_constant1(<2 x i32> %x) {1013; CHECK-LABEL: @sdiv_splat_constant1(1014; CHECK-NEXT:    [[TMP1:%.*]] = sdiv <2 x i32> [[X:%.*]], <i32 42, i32 1>1015; CHECK-NEXT:    [[R:%.*]] = shufflevector <2 x i32> [[TMP1]], <2 x i32> poison, <2 x i32> zeroinitializer1016; CHECK-NEXT:    ret <2 x i32> [[R]]1017;1018  %splat = shufflevector <2 x i32> %x, <2 x i32> poison, <2 x i32> zeroinitializer1019  %r = sdiv <2 x i32> %splat, <i32 42, i32 42>1020  ret <2 x i32> %r1021}1022 1023define <2 x i32> @and_splat_constant(<2 x i32> %x) {1024; CHECK-LABEL: @and_splat_constant(1025; CHECK-NEXT:    [[TMP1:%.*]] = and <2 x i32> [[X:%.*]], <i32 42, i32 poison>1026; CHECK-NEXT:    [[R:%.*]] = shufflevector <2 x i32> [[TMP1]], <2 x i32> poison, <2 x i32> zeroinitializer1027; CHECK-NEXT:    ret <2 x i32> [[R]]1028;1029  %splat = shufflevector <2 x i32> %x, <2 x i32> poison, <2 x i32> zeroinitializer1030  %r = and <2 x i32> %splat, <i32 42, i32 42>1031  ret <2 x i32> %r1032}1033 1034define <4 x i16> @and_constant_mask_poison(<4 x i16> %add) {1035; CHECK-LABEL: @and_constant_mask_poison(1036; CHECK-NEXT:  entry:1037; CHECK-NEXT:    [[AND:%.*]] = shufflevector <4 x i16> [[ADD:%.*]], <4 x i16> poison, <4 x i32> <i32 poison, i32 poison, i32 1, i32 1>1038; CHECK-NEXT:    ret <4 x i16> [[AND]]1039;1040entry:1041  %shuffle = shufflevector <4 x i16> %add, <4 x i16> poison, <4 x i32> <i32 undef, i32 undef, i32 1, i32 1>1042  %and = and <4 x i16> %shuffle, <i16 0, i16 0, i16 -1, i16 -1>1043  ret <4 x i16> %and1044}1045 1046define <4 x i16> @and_constant_mask_poison_2(<4 x i16> %add) {1047; CHECK-LABEL: @and_constant_mask_poison_2(1048; CHECK-NEXT:  entry:1049; CHECK-NEXT:    [[AND:%.*]] = shufflevector <4 x i16> [[ADD:%.*]], <4 x i16> poison, <4 x i32> <i32 1, i32 1, i32 1, i32 poison>1050; CHECK-NEXT:    ret <4 x i16> [[AND]]1051;1052entry:1053  %shuffle = shufflevector <4 x i16> %add, <4 x i16> poison, <4 x i32> <i32 1, i32 1, i32 1, i32 undef>1054  %and = and <4 x i16> %shuffle, <i16 -1, i16 -1, i16 -1, i16 -0>1055  ret <4 x i16> %and1056}1057 1058; We can move the AND across the shuffle, as -1 (AND identity value) is used for undef lanes.1059define <4 x i16> @and_constant_mask_poison_3(<4 x i16> %add) {1060; CHECK-LABEL: @and_constant_mask_poison_3(1061; CHECK-NEXT:  entry:1062; CHECK-NEXT:    ret <4 x i16> <i16 0, i16 0, i16 0, i16 undef>1063;1064entry:1065  %shuffle = shufflevector <4 x i16> %add, <4 x i16> poison, <4 x i32> <i32 0, i32 1, i32 1, i32 undef>1066  %and = and <4 x i16> %shuffle, <i16 0, i16 0, i16 0, i16 -1>1067  ret <4 x i16> %and1068}1069 1070; We can move the AND across the shuffle, as -1 (AND identity value) is used for undef lanes.1071define <4 x i16> @and_constant_mask_poison_4(<4 x i16> %add) {1072; CHECK-LABEL: @and_constant_mask_poison_4(1073; CHECK-NEXT:  entry:1074; CHECK-NEXT:    [[TMP0:%.*]] = and <4 x i16> [[ADD:%.*]], <i16 9, i16 20, i16 poison, i16 poison>1075; CHECK-NEXT:    [[AND:%.*]] = shufflevector <4 x i16> [[TMP0]], <4 x i16> poison, <4 x i32> <i32 0, i32 1, i32 1, i32 poison>1076; CHECK-NEXT:    ret <4 x i16> [[AND]]1077;1078entry:1079  %shuffle = shufflevector <4 x i16> %add, <4 x i16> poison, <4 x i32> <i32 0, i32 1, i32 1, i32 undef>1080  %and = and <4 x i16> %shuffle, <i16 9, i16 20, i16 20, i16 -1>1081  ret <4 x i16> %and1082}1083 1084define <4 x i16> @and_constant_mask_not_undef(<4 x i16> %add) {1085; CHECK-LABEL: @and_constant_mask_not_undef(1086; CHECK-NEXT:  entry:1087; CHECK-NEXT:    [[TMP0:%.*]] = and <4 x i16> [[ADD:%.*]], <i16 poison, i16 -1, i16 0, i16 0>1088; CHECK-NEXT:    [[AND:%.*]] = shufflevector <4 x i16> [[TMP0]], <4 x i16> poison, <4 x i32> <i32 2, i32 3, i32 1, i32 1>1089; CHECK-NEXT:    ret <4 x i16> [[AND]]1090;1091entry:1092  %shuffle = shufflevector <4 x i16> %add, <4 x i16> poison, <4 x i32> <i32 2, i32 3, i32 1, i32 1>1093  %and = and <4 x i16> %shuffle, <i16 0, i16 0, i16 -1, i16 -1>1094  ret <4 x i16> %and1095}1096 1097define <4 x i16> @or_constant_mask_poison(<4 x i16> %in) {1098; CHECK-LABEL: @or_constant_mask_poison(1099; CHECK-NEXT:  entry:1100; CHECK-NEXT:    [[OR:%.*]] = shufflevector <4 x i16> [[IN:%.*]], <4 x i16> poison, <4 x i32> <i32 poison, i32 poison, i32 1, i32 1>1101; CHECK-NEXT:    ret <4 x i16> [[OR]]1102;1103entry:1104  %shuffle = shufflevector <4 x i16> %in, <4 x i16> poison, <4 x i32> <i32 undef, i32 undef, i32 1, i32 1>1105  %or = or <4 x i16> %shuffle, <i16 -1, i16 -1, i16 0, i16 0>1106  ret <4 x i16> %or1107}1108 1109define <4 x i16> @or_constant_mask_poison_2(<4 x i16> %in) {1110; CHECK-LABEL: @or_constant_mask_poison_2(1111; CHECK-NEXT:  entry:1112; CHECK-NEXT:    [[OR:%.*]] = shufflevector <4 x i16> [[IN:%.*]], <4 x i16> poison, <4 x i32> <i32 poison, i32 1, i32 1, i32 poison>1113; CHECK-NEXT:    ret <4 x i16> [[OR]]1114;1115entry:1116  %shuffle = shufflevector <4 x i16> %in, <4 x i16> poison, <4 x i32> <i32 undef, i32 1, i32 1, i32 undef>1117  %or = or <4 x i16> %shuffle, <i16 -1, i16 0, i16 0, i16 -1>1118  ret <4 x i16> %or1119}1120 1121; We can move the OR across the shuffle, as 0 (OR identity value) is used for undef lanes.1122define <4 x i16> @or_constant_mask_poison_3(<4 x i16> %in) {1123; CHECK-LABEL: @or_constant_mask_poison_3(1124; CHECK-NEXT:  entry:1125; CHECK-NEXT:    ret <4 x i16> <i16 undef, i16 -1, i16 -1, i16 undef>1126;1127entry:1128  %shuffle = shufflevector <4 x i16> %in, <4 x i16> poison, <4 x i32> <i32 undef, i32 1, i32 1, i32 undef>1129  %or = or <4 x i16> %shuffle, <i16 0, i16 -1, i16 -1, i16 0>1130  ret <4 x i16> %or1131}1132 1133; We can move the OR across the shuffle, as 0 (OR identity value) is used for undef lanes.1134define <4 x i16> @or_constant_mask_poison_4(<4 x i16> %in) {1135; CHECK-LABEL: @or_constant_mask_poison_4(1136; CHECK-NEXT:  entry:1137; CHECK-NEXT:    [[TMP0:%.*]] = or <4 x i16> [[IN:%.*]], <i16 poison, i16 99, i16 poison, i16 poison>1138; CHECK-NEXT:    [[OR:%.*]] = shufflevector <4 x i16> [[TMP0]], <4 x i16> poison, <4 x i32> <i32 poison, i32 1, i32 1, i32 poison>1139; CHECK-NEXT:    ret <4 x i16> [[OR]]1140;1141entry:1142  %shuffle = shufflevector <4 x i16> %in, <4 x i16> poison, <4 x i32> <i32 undef, i32 1, i32 1, i32 undef>1143  %or = or <4 x i16> %shuffle, <i16 0, i16 99, i16 99, i16 0>1144  ret <4 x i16> %or1145}1146 1147define <4 x i16> @or_constant_mask_not_undef(<4 x i16> %in) {1148; CHECK-LABEL: @or_constant_mask_not_undef(1149; CHECK-NEXT:  entry:1150; CHECK-NEXT:    [[TMP0:%.*]] = or <4 x i16> [[IN:%.*]], <i16 poison, i16 -1, i16 0, i16 0>1151; CHECK-NEXT:    [[AND:%.*]] = shufflevector <4 x i16> [[TMP0]], <4 x i16> poison, <4 x i32> <i32 2, i32 3, i32 1, i32 1>1152; CHECK-NEXT:    ret <4 x i16> [[AND]]1153;1154entry:1155  %shuffle = shufflevector <4 x i16> %in, <4 x i16> poison, <4 x i32> <i32 2, i32 3, i32 1, i32 1>1156  %and = or <4 x i16> %shuffle, <i16 0, i16 0, i16 -1, i16 -1>1157  ret <4 x i16> %and1158}1159 1160define <4 x i16> @shl_constant_mask_undef(<4 x i16> %in) {1161; CHECK-LABEL: @shl_constant_mask_undef(1162; CHECK-NEXT:  entry:1163; CHECK-NEXT:    [[TMP0:%.*]] = shl <4 x i16> [[IN:%.*]], <i16 10, i16 0, i16 poison, i16 poison>1164; CHECK-NEXT:    [[SHL:%.*]] = shufflevector <4 x i16> [[TMP0]], <4 x i16> poison, <4 x i32> <i32 0, i32 poison, i32 1, i32 1>1165; CHECK-NEXT:    ret <4 x i16> [[SHL]]1166;1167entry:1168  %shuffle = shufflevector <4 x i16> %in, <4 x i16> poison, <4 x i32> <i32 0, i32 undef, i32 1, i32 1>1169  %shl = shl <4 x i16> %shuffle, <i16 10, i16 3, i16 0, i16 0>1170  ret <4 x i16> %shl1171}1172 1173define <4 x i16> @add_constant_mask_undef(<4 x i16> %in) {1174; CHECK-LABEL: @add_constant_mask_undef(1175; CHECK-NEXT:  entry:1176; CHECK-NEXT:    [[ADD:%.*]] = shufflevector <4 x i16> [[IN:%.*]], <4 x i16> poison, <4 x i32> <i32 poison, i32 poison, i32 1, i32 1>1177; CHECK-NEXT:    ret <4 x i16> [[ADD]]1178;1179entry:1180  %shuffle = shufflevector <4 x i16> %in, <4 x i16> poison, <4 x i32> <i32 undef, i32 undef, i32 1, i32 1>1181  %add = add <4 x i16> %shuffle, <i16 10, i16 3, i16 0, i16 0>1182  ret <4 x i16> %add1183}1184 1185define <4 x i16> @add_constant_mask_undef_2(<4 x i16> %in) {1186; CHECK-LABEL: @add_constant_mask_undef_2(1187; CHECK-NEXT:  entry:1188; CHECK-NEXT:    [[TMP0:%.*]] = add <4 x i16> [[IN:%.*]], <i16 poison, i16 0, i16 3, i16 poison>1189; CHECK-NEXT:    [[ADD:%.*]] = shufflevector <4 x i16> [[TMP0]], <4 x i16> poison, <4 x i32> <i32 poison, i32 2, i32 1, i32 1>1190; CHECK-NEXT:    ret <4 x i16> [[ADD]]1191;1192entry:1193  %shuffle = shufflevector <4 x i16> %in, <4 x i16> poison, <4 x i32> <i32 undef, i32 2, i32 1, i32 1>1194  %add = add <4 x i16> %shuffle, <i16 10, i16 3, i16 0, i16 0>1195  ret <4 x i16> %add1196}1197 1198define <4 x i16> @sub_constant_mask_undef(<4 x i16> %in) {1199; CHECK-LABEL: @sub_constant_mask_undef(1200; CHECK-NEXT:  entry:1201; CHECK-NEXT:    [[SUB:%.*]] = shufflevector <4 x i16> [[IN:%.*]], <4 x i16> poison, <4 x i32> <i32 poison, i32 poison, i32 1, i32 1>1202; CHECK-NEXT:    ret <4 x i16> [[SUB]]1203;1204entry:1205  %shuffle = shufflevector <4 x i16> %in, <4 x i16> poison, <4 x i32> <i32 undef, i32 undef, i32 1, i32 1>1206  %sub = sub <4 x i16> %shuffle, <i16 10, i16 3, i16 0, i16 0>1207  ret <4 x i16> %sub1208}1209 1210define <4 x i16> @sub_constant_mask_undef_2(<4 x i16> %in) {1211; CHECK-LABEL: @sub_constant_mask_undef_2(1212; CHECK-NEXT:  entry:1213; CHECK-NEXT:    [[TMP0:%.*]] = add <4 x i16> [[IN:%.*]], <i16 poison, i16 0, i16 -10, i16 poison>1214; CHECK-NEXT:    [[SUB:%.*]] = shufflevector <4 x i16> [[TMP0]], <4 x i16> poison, <4 x i32> <i32 1, i32 1, i32 2, i32 poison>1215; CHECK-NEXT:    ret <4 x i16> [[SUB]]1216;1217entry:1218  %shuffle = shufflevector <4 x i16> %in, <4 x i16> poison, <4 x i32> <i32 1, i32 1, i32 2, i32 undef>1219  %sub = sub <4 x i16> %shuffle, <i16 0, i16 0, i16 10, i16 99>1220  ret <4 x i16> %sub1221}1222 1223define <2 x i32> @or_splat_constant(<2 x i32> %x) {1224; CHECK-LABEL: @or_splat_constant(1225; CHECK-NEXT:    [[TMP1:%.*]] = or <2 x i32> [[X:%.*]], <i32 42, i32 poison>1226; CHECK-NEXT:    [[R:%.*]] = shufflevector <2 x i32> [[TMP1]], <2 x i32> poison, <2 x i32> zeroinitializer1227; CHECK-NEXT:    ret <2 x i32> [[R]]1228;1229  %splat = shufflevector <2 x i32> %x, <2 x i32> poison, <2 x i32> zeroinitializer1230  %r = or <2 x i32> %splat, <i32 42, i32 42>1231  ret <2 x i32> %r1232}1233 1234define <2 x i32> @xor_splat_constant(<2 x i32> %x) {1235; CHECK-LABEL: @xor_splat_constant(1236; CHECK-NEXT:    [[TMP1:%.*]] = xor <2 x i32> [[X:%.*]], <i32 42, i32 poison>1237; CHECK-NEXT:    [[R:%.*]] = shufflevector <2 x i32> [[TMP1]], <2 x i32> poison, <2 x i32> zeroinitializer1238; CHECK-NEXT:    ret <2 x i32> [[R]]1239;1240  %splat = shufflevector <2 x i32> %x, <2 x i32> poison, <2 x i32> zeroinitializer1241  %r = xor <2 x i32> %splat, <i32 42, i32 42>1242  ret <2 x i32> %r1243}1244 1245define <2 x float> @fadd_splat_constant(<2 x float> %x) {1246; CHECK-LABEL: @fadd_splat_constant(1247; CHECK-NEXT:    [[TMP1:%.*]] = fadd <2 x float> [[X:%.*]], <float 4.200000e+01, float poison>1248; CHECK-NEXT:    [[R:%.*]] = shufflevector <2 x float> [[TMP1]], <2 x float> poison, <2 x i32> zeroinitializer1249; CHECK-NEXT:    ret <2 x float> [[R]]1250;1251  %splat = shufflevector <2 x float> %x, <2 x float> poison, <2 x i32> zeroinitializer1252  %r = fadd <2 x float> %splat, <float 42.0, float 42.0>1253  ret <2 x float> %r1254}1255 1256define <2 x float> @fsub_splat_constant0(<2 x float> %x) {1257; CHECK-LABEL: @fsub_splat_constant0(1258; CHECK-NEXT:    [[TMP1:%.*]] = fsub <2 x float> <float 4.200000e+01, float poison>, [[X:%.*]]1259; CHECK-NEXT:    [[R:%.*]] = shufflevector <2 x float> [[TMP1]], <2 x float> poison, <2 x i32> zeroinitializer1260; CHECK-NEXT:    ret <2 x float> [[R]]1261;1262  %splat = shufflevector <2 x float> %x, <2 x float> poison, <2 x i32> zeroinitializer1263  %r = fsub <2 x float> <float 42.0, float 42.0>, %splat1264  ret <2 x float> %r1265}1266 1267define <2 x float> @fsub_splat_constant1(<2 x float> %x) {1268; CHECK-LABEL: @fsub_splat_constant1(1269; CHECK-NEXT:    [[TMP1:%.*]] = fadd <2 x float> [[X:%.*]], <float -4.200000e+01, float poison>1270; CHECK-NEXT:    [[R:%.*]] = shufflevector <2 x float> [[TMP1]], <2 x float> poison, <2 x i32> zeroinitializer1271; CHECK-NEXT:    ret <2 x float> [[R]]1272;1273  %splat = shufflevector <2 x float> %x, <2 x float> poison, <2 x i32> zeroinitializer1274  %r = fsub <2 x float> %splat, <float 42.0, float 42.0>1275  ret <2 x float> %r1276}1277 1278define <2 x float> @fneg(<2 x float> %x) {1279; CHECK-LABEL: @fneg(1280; CHECK-NEXT:    [[R:%.*]] = fneg <2 x float> [[TMP1:%.*]]1281; CHECK-NEXT:    [[R1:%.*]] = shufflevector <2 x float> [[R]], <2 x float> poison, <2 x i32> zeroinitializer1282; CHECK-NEXT:    ret <2 x float> [[R1]]1283;1284  %splat = shufflevector <2 x float> %x, <2 x float> poison, <2 x i32> zeroinitializer1285  %r = fsub <2 x float> <float -0.0, float -0.0>, %splat1286  ret <2 x float> %r1287}1288 1289define <2 x float> @fmul_splat_constant(<2 x float> %x) {1290; CHECK-LABEL: @fmul_splat_constant(1291; CHECK-NEXT:    [[TMP1:%.*]] = fmul <2 x float> [[X:%.*]], <float 4.200000e+01, float poison>1292; CHECK-NEXT:    [[R:%.*]] = shufflevector <2 x float> [[TMP1]], <2 x float> poison, <2 x i32> zeroinitializer1293; CHECK-NEXT:    ret <2 x float> [[R]]1294;1295  %splat = shufflevector <2 x float> %x, <2 x float> poison, <2 x i32> zeroinitializer1296  %r = fmul <2 x float> %splat, <float 42.0, float 42.0>1297  ret <2 x float> %r1298}1299 1300define <2 x float> @fdiv_splat_constant0(<2 x float> %x) {1301; CHECK-LABEL: @fdiv_splat_constant0(1302; CHECK-NEXT:    [[TMP1:%.*]] = fdiv <2 x float> <float 4.200000e+01, float poison>, [[X:%.*]]1303; CHECK-NEXT:    [[R:%.*]] = shufflevector <2 x float> [[TMP1]], <2 x float> poison, <2 x i32> zeroinitializer1304; CHECK-NEXT:    ret <2 x float> [[R]]1305;1306  %splat = shufflevector <2 x float> %x, <2 x float> poison, <2 x i32> zeroinitializer1307  %r = fdiv <2 x float> <float 42.0, float 42.0>, %splat1308  ret <2 x float> %r1309}1310 1311define <2 x float> @fdiv_splat_constant1(<2 x float> %x) {1312; CHECK-LABEL: @fdiv_splat_constant1(1313; CHECK-NEXT:    [[TMP1:%.*]] = fdiv <2 x float> [[X:%.*]], <float 4.200000e+01, float poison>1314; CHECK-NEXT:    [[R:%.*]] = shufflevector <2 x float> [[TMP1]], <2 x float> poison, <2 x i32> zeroinitializer1315; CHECK-NEXT:    ret <2 x float> [[R]]1316;1317  %splat = shufflevector <2 x float> %x, <2 x float> poison, <2 x i32> zeroinitializer1318  %r = fdiv <2 x float> %splat, <float 42.0, float 42.0>1319  ret <2 x float> %r1320}1321 1322define <2 x float> @frem_splat_constant0(<2 x float> %x) {1323; CHECK-LABEL: @frem_splat_constant0(1324; CHECK-NEXT:    [[TMP1:%.*]] = frem <2 x float> <float 4.200000e+01, float poison>, [[X:%.*]]1325; CHECK-NEXT:    [[R:%.*]] = shufflevector <2 x float> [[TMP1]], <2 x float> poison, <2 x i32> zeroinitializer1326; CHECK-NEXT:    ret <2 x float> [[R]]1327;1328  %splat = shufflevector <2 x float> %x, <2 x float> poison, <2 x i32> zeroinitializer1329  %r = frem <2 x float> <float 42.0, float 42.0>, %splat1330  ret <2 x float> %r1331}1332 1333define <2 x float> @frem_splat_constant1(<2 x float> %x) {1334; CHECK-LABEL: @frem_splat_constant1(1335; CHECK-NEXT:    [[TMP1:%.*]] = frem <2 x float> [[X:%.*]], <float 4.200000e+01, float poison>1336; CHECK-NEXT:    [[R:%.*]] = shufflevector <2 x float> [[TMP1]], <2 x float> poison, <2 x i32> zeroinitializer1337; CHECK-NEXT:    ret <2 x float> [[R]]1338;1339  %splat = shufflevector <2 x float> %x, <2 x float> poison, <2 x i32> zeroinitializer1340  %r = frem <2 x float> %splat, <float 42.0, float 42.0>1341  ret <2 x float> %r1342}1343 1344; Equivalent shuffle masks, but only one is a narrowing op.1345 1346define <2 x i1> @PR40734(<1 x i1> %x, <4 x i1> %y) {1347; CHECK-LABEL: @PR40734(1348; CHECK-NEXT:    [[WIDEN:%.*]] = shufflevector <1 x i1> zeroinitializer, <1 x i1> [[X:%.*]], <2 x i32> <i32 0, i32 1>1349; CHECK-NEXT:    [[NARROW:%.*]] = shufflevector <4 x i1> [[Y:%.*]], <4 x i1> poison, <2 x i32> <i32 0, i32 1>1350; CHECK-NEXT:    [[R:%.*]] = and <2 x i1> [[WIDEN]], [[NARROW]]1351; CHECK-NEXT:    ret <2 x i1> [[R]]1352;1353  %widen = shufflevector <1 x i1> zeroinitializer, <1 x i1> %x, <2 x i32> <i32 0, i32 1>1354  %narrow = shufflevector <4 x i1> %y, <4 x i1> poison, <2 x i32> <i32 0, i32 1>1355  %r = and <2 x i1> %widen, %narrow1356  ret <2 x i1> %r1357}1358 1359; Negative test - do not transform non-power-of-2 unless we know the backend handles these sequences identically.1360 1361define <7 x i8> @insert_subvector_shuffles(<3 x i8> %x, <3 x i8> %y) {1362; CHECK-LABEL: @insert_subvector_shuffles(1363; 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>1364; 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>1365; 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>1366; CHECK-NEXT:    ret <7 x i8> [[S3]]1367;1368  %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>1369  %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>1370  %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>1371  ret <7 x i8> %s31372}1373 1374define <8 x i8> @insert_subvector_shuffles_pow2elts(<2 x i8> %x, <2 x i8> %y) {1375; CHECK-LABEL: @insert_subvector_shuffles_pow2elts(1376; 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>1377; CHECK-NEXT:    ret <8 x i8> [[S3]]1378;1379  %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>1380  %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>1381  %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>1382  ret <8 x i8> %s31383}1384 1385; The last shuffle may change the vector type.1386; Negative test - do not transform non-power-of-2 unless we know the backend handles these sequences identically.1387 1388define <2 x i8> @insert_subvector_shuffles_narrowing(<3 x i8> %x, <3 x i8> %y) {1389; CHECK-LABEL: @insert_subvector_shuffles_narrowing(1390; 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>1391; 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>1392; CHECK-NEXT:    [[S3:%.*]] = shufflevector <7 x i8> [[S1]], <7 x i8> [[S2]], <2 x i32> <i32 0, i32 8>1393; CHECK-NEXT:    ret <2 x i8> [[S3]]1394;1395  %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>1396  %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>1397  %s3 = shufflevector <7 x i8> %s1, <7 x i8> %s2, <2 x i32> <i32 0, i32 8>1398  ret <2 x i8> %s31399}1400 1401define <2 x i8> @insert_subvector_shuffles_narrowing_pow2elts(<4 x i8> %x, <4 x i8> %y) {1402; CHECK-LABEL: @insert_subvector_shuffles_narrowing_pow2elts(1403; CHECK-NEXT:    [[S3:%.*]] = shufflevector <4 x i8> [[X:%.*]], <4 x i8> [[Y:%.*]], <2 x i32> <i32 0, i32 4>1404; CHECK-NEXT:    ret <2 x i8> [[S3]]1405;1406  %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>1407  %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>1408  %s3 = shufflevector <8 x i8> %s1, <8 x i8> %s2, <2 x i32> <i32 0, i32 8>1409  ret <2 x i8> %s31410}1411 1412; Similar to above, but this reduces to a widen with undefs of 'x'.1413 1414define <4 x double> @insert_subvector_shuffles_identity(<2 x double> %x) {1415; CHECK-LABEL: @insert_subvector_shuffles_identity(1416; CHECK-NEXT:    [[S3:%.*]] = shufflevector <2 x double> [[X:%.*]], <2 x double> poison, <4 x i32> <i32 0, i32 1, i32 poison, i32 poison>1417; CHECK-NEXT:    ret <4 x double> [[S3]]1418;1419  %s1 = shufflevector <2 x double> %x, <2 x double> poison, <4 x i32> <i32 undef, i32 1, i32 undef, i32 undef>1420  %s2 = shufflevector <2 x double> %x, <2 x double> poison, <4 x i32> <i32 0, i32 undef, i32 undef, i32 undef>1421  %s3 = shufflevector <4 x double> %s2, <4 x double> %s1, <4 x i32> <i32 0, i32 5, i32 undef, i32 undef>1422  ret <4 x double> %s31423}1424 1425; Negative test - not identity with padding (although this could be folded with better analysis).1426 1427define <4 x double> @not_insert_subvector_shuffle(<2 x double> %x) {1428; CHECK-LABEL: @not_insert_subvector_shuffle(1429; CHECK-NEXT:    [[S1:%.*]] = shufflevector <2 x double> [[X:%.*]], <2 x double> poison, <4 x i32> <i32 poison, i32 1, i32 poison, i32 1>1430; CHECK-NEXT:    [[S2:%.*]] = shufflevector <2 x double> [[X]], <2 x double> poison, <4 x i32> <i32 0, i32 poison, i32 poison, i32 poison>1431; CHECK-NEXT:    [[S3:%.*]] = shufflevector <4 x double> [[S2]], <4 x double> [[S1]], <4 x i32> <i32 0, i32 5, i32 7, i32 poison>1432; CHECK-NEXT:    ret <4 x double> [[S3]]1433;1434  %s1 = shufflevector <2 x double> %x, <2 x double> poison, <4 x i32> <i32 undef, i32 1, i32 undef, i32 1>1435  %s2 = shufflevector <2 x double> %x, <2 x double> poison, <4 x i32> <i32 0, i32 undef, i32 undef, i32 undef>1436  %s3 = shufflevector <4 x double> %s2, <4 x double> %s1, <4 x i32> <i32 0, i32 5, i32 7, i32 undef>1437  ret <4 x double> %s31438}1439 1440; Negative test - operands are not the same size (although this could be partly folded with better analysis).1441 1442define <4 x double> @not_insert_subvector_shuffles_with_same_size(<2 x double> %x, <3 x double> %y) {1443; CHECK-LABEL: @not_insert_subvector_shuffles_with_same_size(1444; CHECK-NEXT:    [[S1:%.*]] = shufflevector <2 x double> [[X:%.*]], <2 x double> poison, <4 x i32> <i32 poison, i32 1, i32 poison, i32 poison>1445; CHECK-NEXT:    [[S2:%.*]] = shufflevector <3 x double> [[Y:%.*]], <3 x double> poison, <4 x i32> <i32 0, i32 poison, i32 poison, i32 poison>1446; CHECK-NEXT:    [[S3:%.*]] = shufflevector <4 x double> [[S2]], <4 x double> [[S1]], <4 x i32> <i32 0, i32 5, i32 poison, i32 poison>1447; CHECK-NEXT:    ret <4 x double> [[S3]]1448;1449  %s1 = shufflevector <2 x double> %x, <2 x double> poison, <4 x i32> <i32 undef, i32 1, i32 undef, i32 undef>1450  %s2 = shufflevector <3 x double> %y, <3 x double> poison, <4 x i32> <i32 0, i32 undef, i32 undef, i32 undef>1451  %s3 = shufflevector <4 x double> %s2, <4 x double> %s1, <4 x i32> <i32 0, i32 5, i32 undef, i32 undef>1452  ret <4 x double> %s31453}1454 1455; Demanded vector elements may not be able to simplify a shuffle mask1456; before we try to narrow it. This used to crash.1457 1458define <4 x float> @insert_subvector_crash_invalid_mask_elt(<2 x float> %x, ptr %p) {1459; CHECK-LABEL: @insert_subvector_crash_invalid_mask_elt(1460; CHECK-NEXT:    [[WIDEN:%.*]] = shufflevector <2 x float> [[X:%.*]], <2 x float> poison, <4 x i32> <i32 0, i32 1, i32 poison, i32 poison>1461; CHECK-NEXT:    [[I:%.*]] = shufflevector <2 x float> [[X]], <2 x float> poison, <4 x i32> <i32 0, i32 1, i32 poison, i32 poison>1462; CHECK-NEXT:    store <4 x float> [[I]], ptr [[P:%.*]], align 161463; CHECK-NEXT:    ret <4 x float> [[WIDEN]]1464;1465  %widen = shufflevector <2 x float> %x, <2 x float> poison, <4 x i32> <i32 0, i32 1, i32 undef, i32 undef>1466  %ext2 = extractelement <2 x float> %x, i32 01467  %I = insertelement <4 x float> %widen, float %ext2, i16 01468  store <4 x float> %I, ptr %p1469  ret <4 x float> %widen1470}1471 1472define <4 x i32> @splat_assoc_add(<4 x i32> %x, <4 x i32> %y) {1473; CHECK-LABEL: @splat_assoc_add(1474; CHECK-NEXT:    [[TMP1:%.*]] = add <4 x i32> [[X:%.*]], <i32 317426, i32 poison, i32 poison, i32 poison>1475; CHECK-NEXT:    [[TMP2:%.*]] = shufflevector <4 x i32> [[TMP1]], <4 x i32> poison, <4 x i32> zeroinitializer1476; CHECK-NEXT:    [[R:%.*]] = add <4 x i32> [[TMP2]], [[Y:%.*]]1477; CHECK-NEXT:    ret <4 x i32> [[R]]1478;1479  %splatx = shufflevector <4 x i32> %x, <4 x i32> poison, <4 x i32> zeroinitializer1480  %a = add <4 x i32> %y, <i32 317426, i32 317426, i32 317426, i32 317426>1481  %r = add <4 x i32> %splatx, %a1482  ret <4 x i32> %r1483}1484 1485define <vscale x 4 x i32> @vsplat_assoc_add(<vscale x 4 x i32> %x, <vscale x 4 x i32> %y) {1486; CHECK-LABEL: @vsplat_assoc_add(1487; CHECK-NEXT:    [[TMP1:%.*]] = add <vscale x 4 x i32> [[X:%.*]], splat (i32 317426)1488; CHECK-NEXT:    [[TMP2:%.*]] = shufflevector <vscale x 4 x i32> [[TMP1]], <vscale x 4 x i32> poison, <vscale x 4 x i32> zeroinitializer1489; CHECK-NEXT:    [[R:%.*]] = add <vscale x 4 x i32> [[TMP2]], [[Y:%.*]]1490; CHECK-NEXT:    ret <vscale x 4 x i32> [[R]]1491;1492 1493  %splatx = shufflevector <vscale x 4 x i32> %x, <vscale x 4 x i32> poison, <vscale x 4 x i32> zeroinitializer1494  %a = add <vscale x 4 x i32> %y, splat (i32 317426)1495  %r = add <vscale x 4 x i32> %splatx, %a1496  ret <vscale x 4 x i32> %r1497}1498 1499; Undefs in splat mask are replaced with defined splat index1500 1501define <4 x i32> @splat_assoc_add_undef_mask_elts(<4 x i32> %x, <4 x i32> %y) {1502; CHECK-LABEL: @splat_assoc_add_undef_mask_elts(1503; CHECK-NEXT:    [[TMP1:%.*]] = add <4 x i32> [[X:%.*]], <i32 42, i32 poison, i32 poison, i32 poison>1504; CHECK-NEXT:    [[TMP2:%.*]] = shufflevector <4 x i32> [[TMP1]], <4 x i32> poison, <4 x i32> zeroinitializer1505; CHECK-NEXT:    [[R:%.*]] = add <4 x i32> [[TMP2]], [[Y:%.*]]1506; CHECK-NEXT:    ret <4 x i32> [[R]]1507;1508  %splatx = shufflevector <4 x i32> %x, <4 x i32> poison, <4 x i32> <i32 0, i32 0, i32 undef, i32 undef>1509  %a = add <4 x i32> %y, <i32 42, i32 42, i32 42, i32 42>1510  %r = add <4 x i32> %splatx, %a1511  ret <4 x i32> %r1512}1513 1514; Undefs in splat mask are replaced with defined splat index1515 1516define <4 x i32> @splat_assoc_add_undef_mask_elt_at_splat_index(<4 x i32> %x, <4 x i32> %y) {1517; CHECK-LABEL: @splat_assoc_add_undef_mask_elt_at_splat_index(1518; CHECK-NEXT:    [[TMP1:%.*]] = add <4 x i32> [[X:%.*]], <i32 42, i32 poison, i32 poison, i32 poison>1519; CHECK-NEXT:    [[TMP2:%.*]] = shufflevector <4 x i32> [[TMP1]], <4 x i32> poison, <4 x i32> zeroinitializer1520; CHECK-NEXT:    [[R:%.*]] = add <4 x i32> [[TMP2]], [[Y:%.*]]1521; CHECK-NEXT:    ret <4 x i32> [[R]]1522;1523  %splatx = shufflevector <4 x i32> %x, <4 x i32> poison, <4 x i32> <i32 undef, i32 0, i32 0, i32 0>1524  %a = add <4 x i32> %y, <i32 42, i32 42, i32 42, i32 42>1525  %r = add <4 x i32> %splatx, %a1526  ret <4 x i32> %r1527}1528 1529define <4 x i32> @splat_assoc_add_undef_constant_elts(<4 x i32> %x, <4 x i32> %y) {1530; CHECK-LABEL: @splat_assoc_add_undef_constant_elts(1531; CHECK-NEXT:    [[SPLATX:%.*]] = shufflevector <4 x i32> [[X:%.*]], <4 x i32> poison, <4 x i32> zeroinitializer1532; CHECK-NEXT:    [[A:%.*]] = add <4 x i32> [[Y:%.*]], <i32 42, i32 undef, i32 undef, i32 42>1533; CHECK-NEXT:    [[R:%.*]] = add <4 x i32> [[SPLATX]], [[A]]1534; CHECK-NEXT:    ret <4 x i32> [[R]]1535;1536  %splatx = shufflevector <4 x i32> %x, <4 x i32> poison, <4 x i32> zeroinitializer1537  %a = add <4 x i32> %y, <i32 42, i32 undef, i32 undef, i32 42>1538  %r = add <4 x i32> %splatx, %a1539  ret <4 x i32> %r1540}1541 1542define <4 x i32> @splat_assoc_add_undef_constant_elt_at_splat_index(<4 x i32> %x, <4 x i32> %y) {1543; CHECK-LABEL: @splat_assoc_add_undef_constant_elt_at_splat_index(1544; CHECK-NEXT:    [[SPLATX:%.*]] = shufflevector <4 x i32> [[X:%.*]], <4 x i32> poison, <4 x i32> zeroinitializer1545; CHECK-NEXT:    [[A:%.*]] = add <4 x i32> [[Y:%.*]], <i32 undef, i32 42, i32 undef, i32 42>1546; CHECK-NEXT:    [[R:%.*]] = add <4 x i32> [[SPLATX]], [[A]]1547; CHECK-NEXT:    ret <4 x i32> [[R]]1548;1549  %splatx = shufflevector <4 x i32> %x, <4 x i32> poison, <4 x i32> zeroinitializer1550  %a = add <4 x i32> %y, <i32 undef, i32 42, i32 undef, i32 42>1551  %r = add <4 x i32> %splatx, %a1552  ret <4 x i32> %r1553}1554 1555define <4 x i32> @splat_assoc_add_undef_mask_elts_undef_constant_elts(<4 x i32> %x, <4 x i32> %y) {1556; CHECK-LABEL: @splat_assoc_add_undef_mask_elts_undef_constant_elts(1557; CHECK-NEXT:    [[SPLATX:%.*]] = shufflevector <4 x i32> [[X:%.*]], <4 x i32> poison, <4 x i32> <i32 0, i32 poison, i32 0, i32 poison>1558; CHECK-NEXT:    [[A:%.*]] = add <4 x i32> [[Y:%.*]], <i32 42, i32 undef, i32 undef, i32 42>1559; CHECK-NEXT:    [[R:%.*]] = add <4 x i32> [[SPLATX]], [[A]]1560; CHECK-NEXT:    ret <4 x i32> [[R]]1561;1562  %splatx = shufflevector <4 x i32> %x, <4 x i32> poison, <4 x i32> <i32 0, i32 undef, i32 0, i32 undef>1563  %a = add <4 x i32> %y, <i32 42, i32 undef, i32 undef, i32 42>1564  %r = add <4 x i32> %splatx, %a1565  ret <4 x i32> %r1566}1567 1568define <4 x i32> @splat_assoc_add_undef_mask_elt_at_splat_index_undef_constant_elts(<4 x i32> %x, <4 x i32> %y) {1569; CHECK-LABEL: @splat_assoc_add_undef_mask_elt_at_splat_index_undef_constant_elts(1570; CHECK-NEXT:    [[SPLATX:%.*]] = shufflevector <4 x i32> [[X:%.*]], <4 x i32> poison, <4 x i32> <i32 poison, i32 0, i32 0, i32 0>1571; CHECK-NEXT:    [[A:%.*]] = add <4 x i32> [[Y:%.*]], <i32 42, i32 undef, i32 undef, i32 42>1572; CHECK-NEXT:    [[R:%.*]] = add <4 x i32> [[SPLATX]], [[A]]1573; CHECK-NEXT:    ret <4 x i32> [[R]]1574;1575  %splatx = shufflevector <4 x i32> %x, <4 x i32> poison, <4 x i32> <i32 undef, i32 0, i32 0, i32 0>1576  %a = add <4 x i32> %y, <i32 42, i32 undef, i32 undef, i32 42>1577  %r = add <4 x i32> %splatx, %a1578  ret <4 x i32> %r1579}1580 1581define <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) {1582; CHECK-LABEL: @splat_assoc_add_undef_mask_elt_at_splat_index_undef_constant_elt_at_splat_index(1583; CHECK-NEXT:    [[SPLATX:%.*]] = shufflevector <4 x i32> [[X:%.*]], <4 x i32> poison, <4 x i32> <i32 poison, i32 0, i32 0, i32 0>1584; CHECK-NEXT:    [[A:%.*]] = add <4 x i32> [[Y:%.*]], <i32 undef, i32 42, i32 undef, i32 42>1585; CHECK-NEXT:    [[R:%.*]] = add <4 x i32> [[SPLATX]], [[A]]1586; CHECK-NEXT:    ret <4 x i32> [[R]]1587;1588  %splatx = shufflevector <4 x i32> %x, <4 x i32> poison, <4 x i32> <i32 undef, i32 0, i32 0, i32 0>1589  %a = add <4 x i32> %y, <i32 undef, i32 42, i32 undef, i32 42>1590  %r = add <4 x i32> %splatx, %a1591  ret <4 x i32> %r1592}1593 1594; Non-zero splat index; commute operands; FMF intersect1595 1596define <2 x float> @splat_assoc_fmul(<2 x float> %x, <2 x float> %y) {1597; CHECK-LABEL: @splat_assoc_fmul(1598; CHECK-NEXT:    [[TMP1:%.*]] = fmul reassoc nsz <2 x float> [[X:%.*]], <float poison, float 3.000000e+00>1599; CHECK-NEXT:    [[TMP2:%.*]] = shufflevector <2 x float> [[TMP1]], <2 x float> poison, <2 x i32> <i32 1, i32 1>1600; CHECK-NEXT:    [[R:%.*]] = fmul reassoc nsz <2 x float> [[TMP2]], [[Y:%.*]]1601; CHECK-NEXT:    ret <2 x float> [[R]]1602;1603  %splatx = shufflevector <2 x float> %x, <2 x float> poison, <2 x i32> <i32 1, i32 1>1604  %a = fmul reassoc nsz <2 x float> %y, <float 3.0, float 3.0>1605  %r = fmul reassoc nsz nnan <2 x float> %a, %splatx1606  ret <2 x float> %r1607}1608 1609; Two splat shuffles; drop poison-generating flags1610 1611define <3 x i8> @splat_assoc_mul(<3 x i8> %x, <3 x i8> %y, <3 x i8> %z) {1612; CHECK-LABEL: @splat_assoc_mul(1613; CHECK-NEXT:    [[TMP1:%.*]] = mul <3 x i8> [[X:%.*]], [[Z:%.*]]1614; CHECK-NEXT:    [[TMP2:%.*]] = shufflevector <3 x i8> [[TMP1]], <3 x i8> poison, <3 x i32> <i32 2, i32 2, i32 2>1615; CHECK-NEXT:    [[R:%.*]] = mul <3 x i8> [[TMP2]], [[Y:%.*]]1616; CHECK-NEXT:    ret <3 x i8> [[R]]1617;1618  %splatx = shufflevector <3 x i8> %x, <3 x i8> poison, <3 x i32> <i32 2, i32 2, i32 2>1619  %splatz = shufflevector <3 x i8> %z, <3 x i8> poison, <3 x i32> <i32 2, i32 2, i32 2>1620  %a = mul nsw <3 x i8> %y, %splatz1621  %r = mul <3 x i8> %a, %splatx1622  ret <3 x i8> %r1623}1624 1625define <3 x i8> @splat_assoc_mul_undef_elt1(<3 x i8> %x, <3 x i8> %y, <3 x i8> %z) {1626; CHECK-LABEL: @splat_assoc_mul_undef_elt1(1627; CHECK-NEXT:    [[TMP1:%.*]] = mul <3 x i8> [[X:%.*]], [[Z:%.*]]1628; CHECK-NEXT:    [[TMP2:%.*]] = shufflevector <3 x i8> [[TMP1]], <3 x i8> poison, <3 x i32> <i32 2, i32 2, i32 2>1629; CHECK-NEXT:    [[R:%.*]] = mul <3 x i8> [[TMP2]], [[Y:%.*]]1630; CHECK-NEXT:    ret <3 x i8> [[R]]1631;1632  %splatx = shufflevector <3 x i8> %x, <3 x i8> poison, <3 x i32> <i32 undef, i32 2, i32 2>1633  %splatz = shufflevector <3 x i8> %z, <3 x i8> poison, <3 x i32> <i32 2, i32 2, i32 2>1634  %a = mul nsw <3 x i8> %y, %splatz1635  %r = mul nsw nuw <3 x i8> %a, %splatx1636  ret <3 x i8> %r1637}1638 1639define <3 x i8> @splat_assoc_mul_undef_elt2(<3 x i8> %x, <3 x i8> %y, <3 x i8> %z) {1640; CHECK-LABEL: @splat_assoc_mul_undef_elt2(1641; CHECK-NEXT:    [[SPLATX:%.*]] = shufflevector <3 x i8> [[X:%.*]], <3 x i8> poison, <3 x i32> <i32 2, i32 2, i32 2>1642; CHECK-NEXT:    [[SPLATZ:%.*]] = shufflevector <3 x i8> [[Z:%.*]], <3 x i8> poison, <3 x i32> <i32 poison, i32 2, i32 2>1643; CHECK-NEXT:    [[A:%.*]] = mul nsw <3 x i8> [[Y:%.*]], [[SPLATZ]]1644; CHECK-NEXT:    [[R:%.*]] = mul nuw nsw <3 x i8> [[A]], [[SPLATX]]1645; CHECK-NEXT:    ret <3 x i8> [[R]]1646;1647  %splatx = shufflevector <3 x i8> %x, <3 x i8> poison, <3 x i32> <i32 2, i32 2, i32 2>1648  %splatz = shufflevector <3 x i8> %z, <3 x i8> poison, <3 x i32> <i32 undef, i32 2, i32 2>1649  %a = mul nsw <3 x i8> %y, %splatz1650  %r = mul nsw nuw <3 x i8> %a, %splatx1651  ret <3 x i8> %r1652}1653 1654define <3 x i8> @splat_assoc_mul_undef_elt_at_splat_index1(<3 x i8> %x, <3 x i8> %y, <3 x i8> %z) {1655; CHECK-LABEL: @splat_assoc_mul_undef_elt_at_splat_index1(1656; CHECK-NEXT:    [[TMP1:%.*]] = mul <3 x i8> [[X:%.*]], [[Z:%.*]]1657; CHECK-NEXT:    [[TMP2:%.*]] = shufflevector <3 x i8> [[TMP1]], <3 x i8> poison, <3 x i32> <i32 2, i32 2, i32 2>1658; CHECK-NEXT:    [[R:%.*]] = mul <3 x i8> [[TMP2]], [[Y:%.*]]1659; CHECK-NEXT:    ret <3 x i8> [[R]]1660;1661  %splatx = shufflevector <3 x i8> %x, <3 x i8> poison, <3 x i32> <i32 2, i32 2, i32 undef>1662  %splatz = shufflevector <3 x i8> %z, <3 x i8> poison, <3 x i32> <i32 2, i32 2, i32 2>1663  %a = mul nsw <3 x i8> %y, %splatz1664  %r = mul nsw nuw <3 x i8> %a, %splatx1665  ret <3 x i8> %r1666}1667 1668define <3 x i8> @splat_assoc_mul_undef_elt_at_splat_index2(<3 x i8> %x, <3 x i8> %y, <3 x i8> %z) {1669; CHECK-LABEL: @splat_assoc_mul_undef_elt_at_splat_index2(1670; CHECK-NEXT:    [[SPLATX:%.*]] = shufflevector <3 x i8> [[X:%.*]], <3 x i8> poison, <3 x i32> <i32 2, i32 2, i32 2>1671; CHECK-NEXT:    [[SPLATZ:%.*]] = shufflevector <3 x i8> [[Z:%.*]], <3 x i8> poison, <3 x i32> <i32 2, i32 2, i32 poison>1672; CHECK-NEXT:    [[A:%.*]] = mul nsw <3 x i8> [[Y:%.*]], [[SPLATZ]]1673; CHECK-NEXT:    [[R:%.*]] = mul nuw nsw <3 x i8> [[A]], [[SPLATX]]1674; CHECK-NEXT:    ret <3 x i8> [[R]]1675;1676  %splatx = shufflevector <3 x i8> %x, <3 x i8> poison, <3 x i32> <i32 2, i32 2, i32 2>1677  %splatz = shufflevector <3 x i8> %z, <3 x i8> poison, <3 x i32> <i32 2, i32 2, i32 undef>1678  %a = mul nsw <3 x i8> %y, %splatz1679  %r = mul nsw nuw <3 x i8> %a, %splatx1680  ret <3 x i8> %r1681}1682 1683; Negative test - mismatched splat elements1684 1685define <3 x i8> @splat_assoc_or(<3 x i8> %x, <3 x i8> %y, <3 x i8> %z) {1686; CHECK-LABEL: @splat_assoc_or(1687; CHECK-NEXT:    [[SPLATX:%.*]] = shufflevector <3 x i8> [[X:%.*]], <3 x i8> poison, <3 x i32> <i32 1, i32 1, i32 1>1688; CHECK-NEXT:    [[SPLATZ:%.*]] = shufflevector <3 x i8> [[Z:%.*]], <3 x i8> poison, <3 x i32> <i32 2, i32 2, i32 2>1689; CHECK-NEXT:    [[A:%.*]] = or <3 x i8> [[Y:%.*]], [[SPLATZ]]1690; CHECK-NEXT:    [[R:%.*]] = or <3 x i8> [[A]], [[SPLATX]]1691; CHECK-NEXT:    ret <3 x i8> [[R]]1692;1693  %splatx = shufflevector <3 x i8> %x, <3 x i8> poison, <3 x i32> <i32 1, i32 1, i32 1>1694  %splatz = shufflevector <3 x i8> %z, <3 x i8> poison, <3 x i32> <i32 2, i32 2, i32 2>1695  %a = or <3 x i8> %y, %splatz1696  %r = or <3 x i8> %a, %splatx1697  ret <3 x i8> %r1698}1699 1700; Negative test - not associative1701 1702define <2 x float> @splat_assoc_fdiv(<2 x float> %x, <2 x float> %y) {1703; CHECK-LABEL: @splat_assoc_fdiv(1704; CHECK-NEXT:    [[SPLATX:%.*]] = shufflevector <2 x float> [[X:%.*]], <2 x float> poison, <2 x i32> zeroinitializer1705; CHECK-NEXT:    [[A:%.*]] = fdiv reassoc nsz <2 x float> [[Y:%.*]], splat (float 3.000000e+00)1706; CHECK-NEXT:    [[R:%.*]] = fdiv reassoc nsz <2 x float> [[A]], [[SPLATX]]1707; CHECK-NEXT:    ret <2 x float> [[R]]1708;1709  %splatx = shufflevector <2 x float> %x, <2 x float> poison, <2 x i32> zeroinitializer1710  %a = fdiv reassoc nsz <2 x float> %y, <float 3.0, float 3.0>1711  %r = fdiv reassoc nsz <2 x float> %a, %splatx1712  ret <2 x float> %r1713}1714 1715; Negative test - extra use1716 1717define <2 x float> @splat_assoc_fadd(<2 x float> %x, <2 x float> %y) {1718; CHECK-LABEL: @splat_assoc_fadd(1719; CHECK-NEXT:    [[SPLATX:%.*]] = shufflevector <2 x float> [[X:%.*]], <2 x float> poison, <2 x i32> <i32 1, i32 1>1720; CHECK-NEXT:    [[A:%.*]] = fadd fast <2 x float> [[Y:%.*]], splat (float 3.000000e+00)1721; CHECK-NEXT:    call void @use(<2 x float> [[A]])1722; CHECK-NEXT:    [[R:%.*]] = fadd fast <2 x float> [[A]], [[SPLATX]]1723; CHECK-NEXT:    ret <2 x float> [[R]]1724;1725  %splatx = shufflevector <2 x float> %x, <2 x float> poison, <2 x i32> <i32 1, i32 1>1726  %a = fadd fast <2 x float> %y, <float 3.0, float 3.0>1727  call void @use(<2 x float> %a)1728  %r = fadd fast <2 x float> %a, %splatx1729  ret <2 x float> %r1730}1731 1732; Negative test - narrowing splat1733 1734define <3 x i32> @splat_assoc_and(<4 x i32> %x, <3 x i32> %y) {1735; CHECK-LABEL: @splat_assoc_and(1736; CHECK-NEXT:    [[SPLATX:%.*]] = shufflevector <4 x i32> [[X:%.*]], <4 x i32> poison, <3 x i32> zeroinitializer1737; CHECK-NEXT:    [[A:%.*]] = and <3 x i32> [[Y:%.*]], splat (i32 42)1738; CHECK-NEXT:    [[R:%.*]] = and <3 x i32> [[SPLATX]], [[A]]1739; CHECK-NEXT:    ret <3 x i32> [[R]]1740;1741  %splatx = shufflevector <4 x i32> %x, <4 x i32> poison, <3 x i32> zeroinitializer1742  %a = and <3 x i32> %y, <i32 42, i32 42, i32 42>1743  %r = and <3 x i32> %splatx, %a1744  ret <3 x i32> %r1745}1746 1747; Negative test - widening splat1748 1749define <5 x i32> @splat_assoc_xor(<4 x i32> %x, <5 x i32> %y) {1750; CHECK-LABEL: @splat_assoc_xor(1751; CHECK-NEXT:    [[SPLATX:%.*]] = shufflevector <4 x i32> [[X:%.*]], <4 x i32> poison, <5 x i32> zeroinitializer1752; CHECK-NEXT:    [[TMP1:%.*]] = xor <5 x i32> [[Y:%.*]], [[SPLATX]]1753; CHECK-NEXT:    [[R:%.*]] = xor <5 x i32> [[TMP1]], splat (i32 42)1754; CHECK-NEXT:    ret <5 x i32> [[R]]1755;1756  %splatx = shufflevector <4 x i32> %x, <4 x i32> poison, <5 x i32> zeroinitializer1757  %a = xor <5 x i32> %y, <i32 42, i32 42, i32 42, i32 42, i32 42>1758  %r = xor <5 x i32> %splatx, %a1759  ret <5 x i32> %r1760}1761 1762; Negative test - opcode mismatch1763 1764define <4 x i32> @splat_assoc_add_mul(<4 x i32> %x, <4 x i32> %y) {1765; CHECK-LABEL: @splat_assoc_add_mul(1766; CHECK-NEXT:    [[SPLATX:%.*]] = shufflevector <4 x i32> [[X:%.*]], <4 x i32> poison, <4 x i32> zeroinitializer1767; CHECK-NEXT:    [[A:%.*]] = add <4 x i32> [[Y:%.*]], splat (i32 42)1768; CHECK-NEXT:    [[R:%.*]] = mul <4 x i32> [[SPLATX]], [[A]]1769; CHECK-NEXT:    ret <4 x i32> [[R]]1770;1771  %splatx = shufflevector <4 x i32> %x, <4 x i32> poison, <4 x i32> zeroinitializer1772  %a = add <4 x i32> %y, <i32 42, i32 42, i32 42, i32 42>1773  %r = mul <4 x i32> %splatx, %a1774  ret <4 x i32> %r1775}1776 1777 1778; Do not crash on constant expressions.1779 1780define <4 x i32> @PR46872(<4 x i32> %x) {1781; CHECK-LABEL: @PR46872(1782; CHECK-NEXT:    [[S:%.*]] = shufflevector <4 x i32> [[X:%.*]], <4 x i32> poison, <4 x i32> <i32 poison, i32 0, i32 1, i32 1>1783; 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>)1784; CHECK-NEXT:    ret <4 x i32> [[A]]1785;1786  %s = shufflevector <4 x i32> %x, <4 x i32> poison, <4 x i32> <i32 undef, i32 0, i32 1, i32 1>1787  %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>)1788  ret <4 x i32> %a1789}1790 1791define <vscale x 4 x i32> @scalable_splat_binop_constant_rhs(<vscale x 4 x i32> %x) {1792; CHECK-LABEL: @scalable_splat_binop_constant_rhs(1793; CHECK-NEXT:    [[R1:%.*]] = add <vscale x 4 x i32> [[R:%.*]], splat (i32 42)1794; CHECK-NEXT:    [[R2:%.*]] = shufflevector <vscale x 4 x i32> [[R1]], <vscale x 4 x i32> poison, <vscale x 4 x i32> zeroinitializer1795; CHECK-NEXT:    ret <vscale x 4 x i32> [[R2]]1796;1797 1798  %splatx = shufflevector <vscale x 4 x i32> %x, <vscale x 4 x i32> poison, <vscale x 4 x i32> zeroinitializer1799  %r = add <vscale x 4 x i32> %splatx, splat (i32 42)1800  ret <vscale x 4 x i32> %r1801}1802 1803define <vscale x 4 x float> @scalable_splat_binop_constant_lhs(<vscale x 4 x float> %x) {1804; CHECK-LABEL: @scalable_splat_binop_constant_lhs(1805; CHECK-NEXT:    [[R1:%.*]] = fadd <vscale x 4 x float> [[R:%.*]], splat (float 4.200000e+01)1806; CHECK-NEXT:    [[R2:%.*]] = shufflevector <vscale x 4 x float> [[R1]], <vscale x 4 x float> poison, <vscale x 4 x i32> zeroinitializer1807; CHECK-NEXT:    ret <vscale x 4 x float> [[R2]]1808;1809 1810  %splatx = shufflevector <vscale x 4 x float> %x, <vscale x 4 x float> poison, <vscale x 4 x i32> zeroinitializer1811  %r = fadd <vscale x 4 x float> splat (float 42.0), %splatx1812  ret <vscale x 4 x float> %r1813}1814 1815; Negative test - shouldn't pull shuffle out as it udiv isn't safe to speculate.1816define <vscale x 4 x i32> @scalable_splat_binop_constant_ub(<vscale x 4 x i32> %x) {1817; CHECK-LABEL: @scalable_splat_binop_constant_ub(1818; CHECK-NEXT:    [[SPLATX:%.*]] = shufflevector <vscale x 4 x i32> [[X:%.*]], <vscale x 4 x i32> poison, <vscale x 4 x i32> zeroinitializer1819; CHECK-NEXT:    [[R:%.*]] = udiv <vscale x 4 x i32> splat (i32 42), [[SPLATX]]1820; CHECK-NEXT:    ret <vscale x 4 x i32> [[R]]1821;1822 1823  %splatx = shufflevector <vscale x 4 x i32> %x, <vscale x 4 x i32> poison, <vscale x 4 x i32> zeroinitializer1824  %r = udiv <vscale x 4 x i32> splat (i32 42), %splatx1825  ret <vscale x 4 x i32> %r1826}1827