brintos

brintos / llvm-project-archived public Read only

0
0
Text · 115.8 KiB · 39f76f1 Raw
2569 lines · plain
1; NOTE: Assertions have been autogenerated by utils/update_test_checks.py2; RUN: opt < %s -passes=instcombine -S | FileCheck %s3 4declare <2 x half> @llvm.fabs.v2f16(<2 x half>)5declare <2 x float> @llvm.fabs.v2f32(<2 x float>)6declare <4 x float> @llvm.fabs.v4f32(<4 x float>)7declare <2 x double> @llvm.fabs.v2f64(<2 x double>)8declare <4 x double> @llvm.fabs.v4f64(<4 x double>)9 10define <4 x float> @test1(<4 x float> %v1) {11; CHECK-LABEL: @test1(12; CHECK-NEXT:    ret <4 x float> [[V1:%.*]]13;14  %v2 = shufflevector <4 x float> %v1, <4 x float> undef, <4 x i32> <i32 0, i32 1, i32 2, i32 3>15  ret <4 x float> %v216}17 18define <4 x float> @test2(<4 x float> %v1) {19; CHECK-LABEL: @test2(20; CHECK-NEXT:    ret <4 x float> [[V1:%.*]]21;22  %v2 = shufflevector <4 x float> %v1, <4 x float> %v1, <4 x i32> <i32 0, i32 5, i32 2, i32 7>23  ret <4 x float> %v224}25 26define float @test3(<4 x float> %A, <4 x float> %B, float %f) {27; CHECK-LABEL: @test3(28; CHECK-NEXT:    ret float [[F:%.*]]29;30  %C = insertelement <4 x float> %A, float %f, i32 031  %D = shufflevector <4 x float> %C, <4 x float> %B, <4 x i32> <i32 5, i32 0, i32 2, i32 7>32  %E = extractelement <4 x float> %D, i32 133  ret float %E34}35 36define i32 @test4(<4 x i32> %X) {37; CHECK-LABEL: @test4(38; CHECK-NEXT:    [[R:%.*]] = extractelement <4 x i32> [[X:%.*]], i64 039; CHECK-NEXT:    ret i32 [[R]]40;41  %t = shufflevector <4 x i32> %X, <4 x i32> undef, <4 x i32> zeroinitializer42  %r = extractelement <4 x i32> %t, i32 043  ret i32 %r44}45 46define i32 @test5(<4 x i32> %X) {47; CHECK-LABEL: @test5(48; CHECK-NEXT:    [[R:%.*]] = extractelement <4 x i32> [[X:%.*]], i64 349; CHECK-NEXT:    ret i32 [[R]]50;51  %t = shufflevector <4 x i32> %X, <4 x i32> undef, <4 x i32> <i32 3, i32 2, i32 undef, i32 undef>52  %r = extractelement <4 x i32> %t, i32 053  ret i32 %r54}55 56define float @test6(<4 x float> %X) {57; CHECK-LABEL: @test6(58; CHECK-NEXT:    [[R:%.*]] = extractelement <4 x float> [[X:%.*]], i64 059; CHECK-NEXT:    ret float [[R]]60;61  %X1 = bitcast <4 x float> %X to <4 x i32>62  %t = shufflevector <4 x i32> %X1, <4 x i32> undef, <4 x i32> zeroinitializer63  %t2 = bitcast <4 x i32> %t to <4 x float>64  %r = extractelement <4 x float> %t2, i32 065  ret float %r66}67 68define float @testvscale6(<vscale x 4 x float> %X) {69; CHECK-LABEL: @testvscale6(70; CHECK-NEXT:    [[R:%.*]] = extractelement <vscale x 4 x float> [[X:%.*]], i64 071; CHECK-NEXT:    ret float [[R]]72;73  %X1 = bitcast <vscale x 4 x float> %X to <vscale x 4 x i32>74  %t = shufflevector <vscale x 4 x i32> %X1, <vscale x 4 x i32> undef, <vscale x 4 x i32> zeroinitializer75  %t2 = bitcast <vscale x 4 x i32> %t to <vscale x 4 x float>76  %r = extractelement <vscale x 4 x float> %t2, i32 077  ret float %r78}79 80 81define <4 x float> @test7(<4 x float> %x) {82; CHECK-LABEL: @test7(83; CHECK-NEXT:    [[R:%.*]] = shufflevector <4 x float> [[X:%.*]], <4 x float> <float poison, float poison, float undef, float undef>, <4 x i32> <i32 0, i32 1, i32 6, i32 7>84; CHECK-NEXT:    ret <4 x float> [[R]]85;86  %r = shufflevector <4 x float> %x, <4 x float> undef, <4 x i32> < i32 0, i32 1, i32 6, i32 7 >87  ret <4 x float> %r88}89 90; This should not turn into a single shuffle.91define <4 x float> @test8(<4 x float> %x, <4 x float> %y) {92; CHECK-LABEL: @test8(93; 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>94; CHECK-NEXT:    [[T134:%.*]] = shufflevector <4 x float> [[T132]], <4 x float> [[Y:%.*]], <4 x i32> <i32 0, i32 1, i32 2, i32 4>95; CHECK-NEXT:    ret <4 x float> [[T134]]96;97  %t4 = extractelement <4 x float> %x, i32 198  %t2 = extractelement <4 x float> %x, i32 399  %t1 = extractelement <4 x float> %y, i32 0100  %t128 = insertelement <4 x float> undef, float %t4, i32 0101  %t130 = insertelement <4 x float> %t128, float undef, i32 1102  %t132 = insertelement <4 x float> %t130, float %t2, i32 2103  %t134 = insertelement <4 x float> %t132, float %t1, i32 3104  ret <4 x float> %t134105}106 107; Test fold of two shuffles where the first shuffle vectors inputs are a108; different length then the second.109define <4 x i8> @test9(<16 x i8> %t6) {110; CHECK-LABEL: @test9(111; CHECK-NEXT:    [[T9:%.*]] = shufflevector <16 x i8> [[T6:%.*]], <16 x i8> poison, <4 x i32> <i32 13, i32 9, i32 4, i32 13>112; CHECK-NEXT:    ret <4 x i8> [[T9]]113;114  %t7 = shufflevector <16 x i8> %t6, <16 x i8> undef, <4 x i32> < i32 13, i32 9, i32 4, i32 13 >115  %t9 = shufflevector <4 x i8> %t7, <4 x i8> undef, <4 x i32> < i32 3, i32 1, i32 2, i32 0 >116  ret <4 x i8> %t9117}118 119; Same as test9, but make sure that "undef" mask values are not confused with120; mask values of 2*N, where N is the mask length.  These shuffles should not121; be folded (because [8,9,4,8] may not be a mask supported by the target).122 123define <4 x i8> @test9a(<16 x i8> %t6) {124; CHECK-LABEL: @test9a(125; CHECK-NEXT:    [[T7:%.*]] = shufflevector <16 x i8> [[T6:%.*]], <16 x i8> poison, <4 x i32> <i32 poison, i32 9, i32 4, i32 8>126; CHECK-NEXT:    [[T9:%.*]] = shufflevector <4 x i8> [[T7]], <4 x i8> poison, <4 x i32> <i32 3, i32 1, i32 2, i32 poison>127; CHECK-NEXT:    ret <4 x i8> [[T9]]128;129  %t7 = shufflevector <16 x i8> %t6, <16 x i8> undef, <4 x i32> < i32 undef, i32 9, i32 4, i32 8 >130  %t9 = shufflevector <4 x i8> %t7, <4 x i8> undef, <4 x i32> < i32 3, i32 1, i32 2, i32 0 >131  ret <4 x i8> %t9132}133 134; Test fold of two shuffles where the first shuffle vectors inputs are a135; different length then the second.136define <4 x i8> @test9b(<4 x i8> %t6, <4 x i8> %t7) {137; CHECK-LABEL: @test9b(138; CHECK-NEXT:    [[T9:%.*]] = shufflevector <4 x i8> [[T6:%.*]], <4 x i8> [[T7:%.*]], <4 x i32> <i32 0, i32 1, i32 4, i32 5>139; CHECK-NEXT:    ret <4 x i8> [[T9]]140;141  %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>142  %t9 = shufflevector <8 x i8> %t1, <8 x i8> undef, <4 x i32> <i32 0, i32 1, i32 4, i32 5>143  ret <4 x i8> %t9144}145 146; Redundant vector splats should be removed.  Radar 8597790.147define <4 x i32> @test10(<4 x i32> %t5) {148; CHECK-LABEL: @test10(149; CHECK-NEXT:    [[T7:%.*]] = shufflevector <4 x i32> [[T5:%.*]], <4 x i32> poison, <4 x i32> <i32 1, i32 1, i32 1, i32 1>150; CHECK-NEXT:    ret <4 x i32> [[T7]]151;152  %t6 = shufflevector <4 x i32> %t5, <4 x i32> undef, <4 x i32> <i32 1, i32 undef, i32 undef, i32 undef>153  %t7 = shufflevector <4 x i32> %t6, <4 x i32> undef, <4 x i32> zeroinitializer154  ret <4 x i32> %t7155}156 157; Test fold of two shuffles where the two shufflevector inputs's op1 are the same.158 159define <8 x i8> @test11(<16 x i8> %t6) {160; CHECK-LABEL: @test11(161; 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>162; CHECK-NEXT:    ret <8 x i8> [[T3]]163;164  %t1 = shufflevector <16 x i8> %t6, <16 x i8> undef, <4 x i32> <i32 0, i32 1, i32 2, i32 3>165  %t2 = shufflevector <16 x i8> %t6, <16 x i8> undef, <4 x i32> <i32 4, i32 5, i32 6, i32 7>166  %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>167  ret <8 x i8> %t3168}169 170; Test fold of two shuffles where the first shufflevector's inputs are the same as the second.171 172define <8 x i8> @test12(<8 x i8> %t6, <8 x i8> %t2) {173; CHECK-LABEL: @test12(174; 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>175; CHECK-NEXT:    ret <8 x i8> [[T3]]176;177  %t1 = shufflevector <8 x i8> %t6, <8 x i8> undef, <8 x i32> <i32 0, i32 1, i32 2, i32 3, i32 5, i32 4, i32 undef, i32 7>178  %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>179  ret <8 x i8> %t3180}181 182; Test fold of two shuffles where the first shufflevector's inputs are the same as the second.183 184define <8 x i8> @test12a(<8 x i8> %t6, <8 x i8> %t2) {185; CHECK-LABEL: @test12a(186; 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>187; CHECK-NEXT:    ret <8 x i8> [[T3]]188;189  %t1 = shufflevector <8 x i8> %t6, <8 x i8> undef, <8 x i32> <i32 0, i32 1, i32 2, i32 3, i32 5, i32 4, i32 undef, i32 7>190  %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>191  ret <8 x i8> %t3192}193 194; The mask length of the 1st shuffle can be reduced to eliminate the 2nd shuffle.195 196define <2 x i8> @extract_subvector_of_shuffle(<2 x i8> %x, <2 x i8> %y) {197; CHECK-LABEL: @extract_subvector_of_shuffle(198; CHECK-NEXT:    [[EXTRACT_SUBV:%.*]] = shufflevector <2 x i8> [[X:%.*]], <2 x i8> [[Y:%.*]], <2 x i32> <i32 0, i32 2>199; CHECK-NEXT:    ret <2 x i8> [[EXTRACT_SUBV]]200;201  %shuf = shufflevector <2 x i8> %x, <2 x i8> %y, <3 x i32> <i32 0, i32 2, i32 0>202  %extract_subv = shufflevector <3 x i8> %shuf, <3 x i8> undef, <2 x i32> <i32 0, i32 1>203  ret <2 x i8> %extract_subv204}205 206; Undef elements in either mask are ok. Undefs from the 2nd shuffle mask should propagate to the new shuffle.207; The type of the inputs does not have to match the output type.208 209define <4 x i8> @extract_subvector_of_shuffle_undefs_types(<2 x i8> %x, <2 x i8> %y) {210; CHECK-LABEL: @extract_subvector_of_shuffle_undefs_types(211; CHECK-NEXT:    [[EXTRACT_SUBV:%.*]] = shufflevector <2 x i8> [[X:%.*]], <2 x i8> [[Y:%.*]], <4 x i32> <i32 poison, i32 2, i32 0, i32 poison>212; CHECK-NEXT:    ret <4 x i8> [[EXTRACT_SUBV]]213;214  %shuf = shufflevector <2 x i8> %x, <2 x i8> %y, <5 x i32> <i32 undef, i32 2, i32 0, i32 1, i32 0>215  %extract_subv = shufflevector <5 x i8> %shuf, <5 x i8> undef, <4 x i32> <i32 0, i32 1, i32 2, i32 undef>216  ret <4 x i8> %extract_subv217}218 219; Extra uses are not ok - we only do the transform when we can eliminate an instruction.220 221declare void @use_v5i8(<5 x i8>)222 223define <4 x i8> @extract_subvector_of_shuffle_extra_use(<2 x i8> %x, <2 x i8> %y) {224; CHECK-LABEL: @extract_subvector_of_shuffle_extra_use(225; 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>226; CHECK-NEXT:    call void @use_v5i8(<5 x i8> [[SHUF]])227; CHECK-NEXT:    [[EXTRACT_SUBV:%.*]] = shufflevector <5 x i8> [[SHUF]], <5 x i8> poison, <4 x i32> <i32 0, i32 1, i32 2, i32 poison>228; CHECK-NEXT:    ret <4 x i8> [[EXTRACT_SUBV]]229;230  %shuf = shufflevector <2 x i8> %x, <2 x i8> %y, <5 x i32> <i32 undef, i32 2, i32 0, i32 1, i32 0>231  call void @use_v5i8(<5 x i8> %shuf)232  %extract_subv = shufflevector <5 x i8> %shuf, <5 x i8> undef, <4 x i32> <i32 0, i32 1, i32 2, i32 undef>233  ret <4 x i8> %extract_subv234}235 236define <2 x i8> @test13a(i8 %x1, i8 %x2) {237; CHECK-LABEL: @test13a(238; CHECK-NEXT:    [[TMP1:%.*]] = insertelement <2 x i8> poison, i8 [[X2:%.*]], i64 0239; CHECK-NEXT:    [[TMP2:%.*]] = insertelement <2 x i8> [[TMP1]], i8 [[X1:%.*]], i64 1240; CHECK-NEXT:    [[D:%.*]] = add <2 x i8> [[TMP2]], <i8 7, i8 5>241; CHECK-NEXT:    ret <2 x i8> [[D]]242;243  %A = insertelement <2 x i8> undef, i8 %x1, i32 0244  %B = insertelement <2 x i8> %A, i8 %x2, i32 1245  %C = add <2 x i8> %B, <i8 5, i8 7>246  %D = shufflevector <2 x i8> %C, <2 x i8> undef, <2 x i32> <i32 1, i32 0>247  ret <2 x i8> %D248}249 250define <1 x ptr> @shuffle_gep(ptr %x1, ptr %x2) {251; CHECK-LABEL: @shuffle_gep(252; CHECK-NEXT:    [[TMP1:%.*]] = insertelement <1 x ptr> poison, ptr [[X2:%.*]], i64 0253; CHECK-NEXT:    [[RET:%.*]] = getelementptr i8, <1 x ptr> [[TMP1]], i64 5254; CHECK-NEXT:    ret <1 x ptr> [[RET]]255;256  %ins.1 = insertelement <2 x ptr> poison, ptr %x1, i32 0257  %ins.2 = insertelement <2 x ptr> %ins.1, ptr %x2, i32 1258  %gep = getelementptr i8, <2 x ptr> %ins.2, i64 5259  %ret = shufflevector <2 x ptr> %gep, <2 x ptr> poison, <1 x i32> <i32 1>260  ret <1 x ptr> %ret261}262 263define <1 x ptr> @shuffle_gep_inbounds(ptr %x1, ptr %x2) {264; CHECK-LABEL: @shuffle_gep_inbounds(265; CHECK-NEXT:    [[TMP1:%.*]] = insertelement <1 x ptr> poison, ptr [[X2:%.*]], i64 0266; CHECK-NEXT:    [[RET:%.*]] = getelementptr inbounds i8, <1 x ptr> [[TMP1]], i64 5267; CHECK-NEXT:    ret <1 x ptr> [[RET]]268;269  %ins.1 = insertelement <2 x ptr> poison, ptr %x1, i32 0270  %ins.2 = insertelement <2 x ptr> %ins.1, ptr %x2, i32 1271  %gep = getelementptr inbounds i8, <2 x ptr> %ins.2, i64 5272  %ret = shufflevector <2 x ptr> %gep, <2 x ptr> poison, <1 x i32> <i32 1>273  ret <1 x ptr> %ret274}275 276define <1 x ptr> @shuffle_gep_nuw(ptr %x1, ptr %x2) {277; CHECK-LABEL: @shuffle_gep_nuw(278; CHECK-NEXT:    [[TMP1:%.*]] = insertelement <1 x ptr> poison, ptr [[X2:%.*]], i64 0279; CHECK-NEXT:    [[RET:%.*]] = getelementptr nuw i8, <1 x ptr> [[TMP1]], i64 5280; CHECK-NEXT:    ret <1 x ptr> [[RET]]281;282  %ins.1 = insertelement <2 x ptr> poison, ptr %x1, i32 0283  %ins.2 = insertelement <2 x ptr> %ins.1, ptr %x2, i32 1284  %gep = getelementptr nuw i8, <2 x ptr> %ins.2, i64 5285  %ret = shufflevector <2 x ptr> %gep, <2 x ptr> poison, <1 x i32> <i32 1>286  ret <1 x ptr> %ret287}288 289define <1 x ptr> @shuffle_gep_nusw(ptr %x1, ptr %x2) {290; CHECK-LABEL: @shuffle_gep_nusw(291; CHECK-NEXT:    [[TMP1:%.*]] = insertelement <1 x ptr> poison, ptr [[X2:%.*]], i64 0292; CHECK-NEXT:    [[RET:%.*]] = getelementptr nusw i8, <1 x ptr> [[TMP1]], i64 5293; CHECK-NEXT:    ret <1 x ptr> [[RET]]294;295  %ins.1 = insertelement <2 x ptr> poison, ptr %x1, i32 0296  %ins.2 = insertelement <2 x ptr> %ins.1, ptr %x2, i32 1297  %gep = getelementptr nusw i8, <2 x ptr> %ins.2, i64 5298  %ret = shufflevector <2 x ptr> %gep, <2 x ptr> poison, <1 x i32> <i32 1>299  ret <1 x ptr> %ret300}301 302; Increasing length of vector ops is not a good canonicalization.303 304define <3 x i32> @add_wider(i32 %y, i32 %z) {305; CHECK-LABEL: @add_wider(306; CHECK-NEXT:    [[I0:%.*]] = insertelement <2 x i32> poison, i32 [[Y:%.*]], i64 0307; CHECK-NEXT:    [[I1:%.*]] = insertelement <2 x i32> [[I0]], i32 [[Z:%.*]], i64 1308; CHECK-NEXT:    [[A:%.*]] = add <2 x i32> [[I1]], splat (i32 255)309; CHECK-NEXT:    [[EXT:%.*]] = shufflevector <2 x i32> [[A]], <2 x i32> poison, <3 x i32> <i32 0, i32 1, i32 poison>310; CHECK-NEXT:    ret <3 x i32> [[EXT]]311;312  %i0 = insertelement <2 x i32> undef, i32 %y, i32 0313  %i1 = insertelement <2 x i32> %i0, i32 %z, i32 1314  %a = add <2 x i32> %i1, <i32 255, i32 255>315  %ext = shufflevector <2 x i32> %a, <2 x i32> undef, <3 x i32> <i32 0, i32 1, i32 undef>316  ret <3 x i32> %ext317}318 319; Increasing length of vector ops must be safe from illegal undef propagation.320 321define <3 x i32> @div_wider(i32 %y, i32 %z) {322; CHECK-LABEL: @div_wider(323; CHECK-NEXT:    [[I0:%.*]] = insertelement <2 x i32> poison, i32 [[Y:%.*]], i64 0324; CHECK-NEXT:    [[I1:%.*]] = insertelement <2 x i32> [[I0]], i32 [[Z:%.*]], i64 1325; CHECK-NEXT:    [[A:%.*]] = sdiv <2 x i32> [[I1]], splat (i32 255)326; CHECK-NEXT:    [[EXT:%.*]] = shufflevector <2 x i32> [[A]], <2 x i32> poison, <3 x i32> <i32 0, i32 1, i32 poison>327; CHECK-NEXT:    ret <3 x i32> [[EXT]]328;329  %i0 = insertelement <2 x i32> undef, i32 %y, i32 0330  %i1 = insertelement <2 x i32> %i0, i32 %z, i32 1331  %a = sdiv <2 x i32> %i1, <i32 255, i32 255>332  %ext = shufflevector <2 x i32> %a, <2 x i32> undef, <3 x i32> <i32 0, i32 1, i32 undef>333  ret <3 x i32> %ext334}335 336; Increasing length of insertelements (no math ops) is a good canonicalization.337 338define <3 x i8> @fold_inselts_with_widening_shuffle(i8 %x, i8 %y) {339; CHECK-LABEL: @fold_inselts_with_widening_shuffle(340; CHECK-NEXT:    [[TMP1:%.*]] = insertelement <3 x i8> poison, i8 [[X:%.*]], i64 0341; CHECK-NEXT:    [[WIDEN:%.*]] = insertelement <3 x i8> [[TMP1]], i8 [[Y:%.*]], i64 1342; CHECK-NEXT:    ret <3 x i8> [[WIDEN]]343;344  %ins0 = insertelement <2 x i8> undef, i8 %x, i32 0345  %ins1 = insertelement <2 x i8> %ins0, i8 %y, i32 1346  %widen = shufflevector <2 x i8> %ins1, <2 x i8> undef, <3 x i32> <i32 0, i32 1, i32 undef>347  ret <3 x i8> %widen348}349 350define <2 x i8> @test13b(i8 %x) {351; CHECK-LABEL: @test13b(352; CHECK-NEXT:    [[B:%.*]] = insertelement <2 x i8> poison, i8 [[X:%.*]], i64 1353; CHECK-NEXT:    ret <2 x i8> [[B]]354;355  %A = insertelement <2 x i8> undef, i8 %x, i32 0356  %B = shufflevector <2 x i8> %A, <2 x i8> undef, <2 x i32> <i32 undef, i32 0>357  ret <2 x i8> %B358}359 360define <2 x i8> @test13c(i8 %x1, i8 %x2) {361; CHECK-LABEL: @test13c(362; CHECK-NEXT:    [[TMP1:%.*]] = insertelement <2 x i8> poison, i8 [[X1:%.*]], i64 0363; CHECK-NEXT:    [[C:%.*]] = insertelement <2 x i8> [[TMP1]], i8 [[X2:%.*]], i64 1364; CHECK-NEXT:    ret <2 x i8> [[C]]365;366  %A = insertelement <4 x i8> undef, i8 %x1, i32 0367  %B = insertelement <4 x i8> %A, i8 %x2, i32 2368  %C = shufflevector <4 x i8> %B, <4 x i8> undef, <2 x i32> <i32 0, i32 2>369  ret <2 x i8> %C370}371 372define void @test14(i16 %conv10) {373; CHECK-LABEL: @test14(374; CHECK-NEXT:    store <4 x i16> <i16 undef, i16 undef, i16 undef, i16 23>, ptr undef, align 8375; CHECK-NEXT:    ret void376;377  %t = alloca <4 x i16>, align 8378  %vecinit6 = insertelement <4 x i16> undef, i16 23, i32 3379  store <4 x i16> %vecinit6, ptr undef380  %t1 = load <4 x i16>, ptr undef381  %vecinit11 = insertelement <4 x i16> undef, i16 %conv10, i32 3382  %div = udiv <4 x i16> %t1, %vecinit11383  store <4 x i16> %div, ptr %t384  %t4 = load <4 x i16>, ptr %t385  %t5 = shufflevector <4 x i16> %t4, <4 x i16> undef, <2 x i32> <i32 2, i32 0>386  %cmp = icmp ule <2 x i16> %t5, undef387  %sext = sext <2 x i1> %cmp to <2 x i16>388  ret void389}390 391; Check that sequences of insert/extract element are392; collapsed into valid shuffle instruction with correct shuffle indexes.393 394define <4 x float> @test15a(<4 x float> %LHS, <4 x float> %RHS) {395; CHECK-LABEL: @test15a(396; CHECK-NEXT:    [[T4:%.*]] = shufflevector <4 x float> [[LHS:%.*]], <4 x float> [[RHS:%.*]], <4 x i32> <i32 4, i32 0, i32 6, i32 6>397; CHECK-NEXT:    ret <4 x float> [[T4]]398;399  %t1 = extractelement <4 x float> %LHS, i32 0400  %t2 = insertelement <4 x float> %RHS, float %t1, i32 1401  %t3 = extractelement <4 x float> %RHS, i32 2402  %t4 = insertelement <4 x float> %t2, float %t3, i32 3403  ret <4 x float> %t4404}405 406define <4 x float> @test15b(<4 x float> %LHS, <4 x float> %RHS) {407; CHECK-LABEL: @test15b(408; CHECK-NEXT:    [[T5:%.*]] = shufflevector <4 x float> [[LHS:%.*]], <4 x float> [[RHS:%.*]], <4 x i32> <i32 4, i32 3, i32 6, i32 6>409; CHECK-NEXT:    ret <4 x float> [[T5]]410;411  %t0 = extractelement <4 x float> %LHS, i32 3412  %t1 = insertelement <4 x float> %RHS, float %t0, i32 0413  %t2 = extractelement <4 x float> %t1, i32 0414  %t3 = insertelement <4 x float> %RHS, float %t2, i32 1415  %t4 = extractelement <4 x float> %RHS, i32 2416  %t5 = insertelement <4 x float> %t3, float %t4, i32 3417  ret <4 x float> %t5418}419 420define <1 x i32> @test16a(i32 %ele) {421; CHECK-LABEL: @test16a(422; CHECK-NEXT:    ret <1 x i32> splat (i32 2)423;424  %t0 = insertelement <2 x i32> <i32 1, i32 undef>, i32 %ele, i32 1425  %t1 = shl <2 x i32> %t0, <i32 1, i32 1>426  %t2 = shufflevector <2 x i32> %t1, <2 x i32> undef, <1 x i32> <i32 0>427  ret <1 x i32> %t2428}429 430define <4 x i8> @test16b(i8 %ele) {431; CHECK-LABEL: @test16b(432; CHECK-NEXT:    ret <4 x i8> splat (i8 2)433;434  %t0 = insertelement <8 x i8> <i8 1, i8 1, i8 1, i8 1, i8 1, i8 1, i8 undef, i8 1>, i8 %ele, i32 6435  %t1 = shl <8 x i8> %t0, <i8 1, i8 1, i8 1, i8 1, i8 1, i8 1, i8 1, i8 1>436  %t2 = shufflevector <8 x i8> %t1, <8 x i8> undef, <4 x i32> <i32 1, i32 2, i32 3, i32 4>437  ret <4 x i8> %t2438}439 440; If composition of two shuffles is identity, shuffles can be removed.441define <4 x i32> @shuffle_17ident(<4 x i32> %v) {442; CHECK-LABEL: @shuffle_17ident(443; CHECK-NEXT:    ret <4 x i32> [[V:%.*]]444;445  %shuffle = shufflevector <4 x i32> %v, <4 x i32> zeroinitializer, <4 x i32> <i32 1, i32 2, i32 3, i32 0>446  %shuffle2 = shufflevector <4 x i32> %shuffle, <4 x i32> zeroinitializer, <4 x i32> <i32 3, i32 0, i32 1, i32 2>447  ret <4 x i32> %shuffle2448}449 450; swizzle can be put after operation451define <4 x i32> @shuffle_17and(<4 x i32> %v1, <4 x i32> %v2) {452; CHECK-LABEL: @shuffle_17and(453; CHECK-NEXT:    [[TMP1:%.*]] = and <4 x i32> [[V1:%.*]], [[V2:%.*]]454; CHECK-NEXT:    [[R:%.*]] = shufflevector <4 x i32> [[TMP1]], <4 x i32> poison, <4 x i32> <i32 1, i32 2, i32 3, i32 0>455; CHECK-NEXT:    ret <4 x i32> [[R]]456;457  %t1 = shufflevector <4 x i32> %v1, <4 x i32> zeroinitializer, <4 x i32> <i32 1, i32 2, i32 3, i32 0>458  %t2 = shufflevector <4 x i32> %v2, <4 x i32> zeroinitializer, <4 x i32> <i32 1, i32 2, i32 3, i32 0>459  %r = and <4 x i32> %t1, %t2460  ret <4 x i32> %r461}462 463declare void @use(<2 x float>)464declare void @use4(<4 x float>)465 466; One extra use is ok to transform.467 468define <2 x float> @shuffle_fadd_multiuse(<2 x float> %v1, <2 x float> %v2) {469; CHECK-LABEL: @shuffle_fadd_multiuse(470; CHECK-NEXT:    [[T1:%.*]] = shufflevector <2 x float> [[V1:%.*]], <2 x float> poison, <2 x i32> <i32 1, i32 0>471; CHECK-NEXT:    [[TMP1:%.*]] = fadd <2 x float> [[V1]], [[V2:%.*]]472; CHECK-NEXT:    [[R:%.*]] = shufflevector <2 x float> [[TMP1]], <2 x float> poison, <2 x i32> <i32 1, i32 0>473; CHECK-NEXT:    call void @use(<2 x float> [[T1]])474; CHECK-NEXT:    ret <2 x float> [[R]]475;476  %t1 = shufflevector <2 x float> %v1, <2 x float> undef, <2 x i32> <i32 1, i32 0>477  %t2 = shufflevector <2 x float> %v2, <2 x float> undef, <2 x i32> <i32 1, i32 0>478  %r = fadd <2 x float> %t1, %t2479  call void @use(<2 x float> %t1)480  ret <2 x float> %r481}482 483define <2 x float> @shuffle_fdiv_multiuse(<2 x float> %v1, <2 x float> %v2) {484; CHECK-LABEL: @shuffle_fdiv_multiuse(485; CHECK-NEXT:    [[T2:%.*]] = shufflevector <2 x float> [[V2:%.*]], <2 x float> poison, <2 x i32> <i32 1, i32 0>486; CHECK-NEXT:    [[TMP1:%.*]] = fdiv <2 x float> [[V1:%.*]], [[V2]]487; CHECK-NEXT:    [[R:%.*]] = shufflevector <2 x float> [[TMP1]], <2 x float> poison, <2 x i32> <i32 1, i32 0>488; CHECK-NEXT:    call void @use(<2 x float> [[T2]])489; CHECK-NEXT:    ret <2 x float> [[R]]490;491  %t1 = shufflevector <2 x float> %v1, <2 x float> undef, <2 x i32> <i32 1, i32 0>492  %t2 = shufflevector <2 x float> %v2, <2 x float> undef, <2 x i32> <i32 1, i32 0>493  %r = fdiv <2 x float> %t1, %t2494  call void @use(<2 x float> %t2)495  ret <2 x float> %r496}497 498; But 2 extra uses would require an extra instruction.499 500define <2 x float> @shuffle_fsub_multiuse(<2 x float> %v1, <2 x float> %v2) {501; CHECK-LABEL: @shuffle_fsub_multiuse(502; CHECK-NEXT:    [[T1:%.*]] = shufflevector <2 x float> [[V1:%.*]], <2 x float> poison, <2 x i32> <i32 1, i32 0>503; CHECK-NEXT:    [[T2:%.*]] = shufflevector <2 x float> [[V2:%.*]], <2 x float> poison, <2 x i32> <i32 1, i32 0>504; CHECK-NEXT:    [[R:%.*]] = fsub <2 x float> [[T1]], [[T2]]505; CHECK-NEXT:    call void @use(<2 x float> [[T1]])506; CHECK-NEXT:    call void @use(<2 x float> [[T2]])507; CHECK-NEXT:    ret <2 x float> [[R]]508;509  %t1 = shufflevector <2 x float> %v1, <2 x float> undef, <2 x i32> <i32 1, i32 0>510  %t2 = shufflevector <2 x float> %v2, <2 x float> undef, <2 x i32> <i32 1, i32 0>511  %r = fsub <2 x float> %t1, %t2512  call void @use(<2 x float> %t1)513  call void @use(<2 x float> %t2)514  ret <2 x float> %r515}516 517define <4 x i32> @shuffle_17add(<4 x i32> %v1, <4 x i32> %v2) {518; CHECK-LABEL: @shuffle_17add(519; CHECK-NEXT:    [[TMP1:%.*]] = add <4 x i32> [[V1:%.*]], [[V2:%.*]]520; CHECK-NEXT:    [[R:%.*]] = shufflevector <4 x i32> [[TMP1]], <4 x i32> poison, <4 x i32> <i32 1, i32 2, i32 3, i32 0>521; CHECK-NEXT:    ret <4 x i32> [[R]]522;523  %t1 = shufflevector <4 x i32> %v1, <4 x i32> zeroinitializer, <4 x i32> <i32 1, i32 2, i32 3, i32 0>524  %t2 = shufflevector <4 x i32> %v2, <4 x i32> zeroinitializer, <4 x i32> <i32 1, i32 2, i32 3, i32 0>525  %r = add <4 x i32> %t1, %t2526  ret <4 x i32> %r527}528 529define <4 x i32> @shuffle_17addnsw(<4 x i32> %v1, <4 x i32> %v2) {530; CHECK-LABEL: @shuffle_17addnsw(531; CHECK-NEXT:    [[TMP1:%.*]] = add nsw <4 x i32> [[V1:%.*]], [[V2:%.*]]532; CHECK-NEXT:    [[R:%.*]] = shufflevector <4 x i32> [[TMP1]], <4 x i32> poison, <4 x i32> <i32 1, i32 2, i32 3, i32 0>533; CHECK-NEXT:    ret <4 x i32> [[R]]534;535  %t1 = shufflevector <4 x i32> %v1, <4 x i32> zeroinitializer, <4 x i32> <i32 1, i32 2, i32 3, i32 0>536  %t2 = shufflevector <4 x i32> %v2, <4 x i32> zeroinitializer, <4 x i32> <i32 1, i32 2, i32 3, i32 0>537  %r = add nsw <4 x i32> %t1, %t2538  ret <4 x i32> %r539}540 541define <4 x i32> @shuffle_17addnuw(<4 x i32> %v1, <4 x i32> %v2) {542; CHECK-LABEL: @shuffle_17addnuw(543; CHECK-NEXT:    [[TMP1:%.*]] = add nuw <4 x i32> [[V1:%.*]], [[V2:%.*]]544; CHECK-NEXT:    [[R:%.*]] = shufflevector <4 x i32> [[TMP1]], <4 x i32> poison, <4 x i32> <i32 1, i32 2, i32 3, i32 0>545; CHECK-NEXT:    ret <4 x i32> [[R]]546;547  %t1 = shufflevector <4 x i32> %v1, <4 x i32> zeroinitializer, <4 x i32> <i32 1, i32 2, i32 3, i32 0>548  %t2 = shufflevector <4 x i32> %v2, <4 x i32> zeroinitializer, <4 x i32> <i32 1, i32 2, i32 3, i32 0>549  %r = add nuw <4 x i32> %t1, %t2550  ret <4 x i32> %r551}552 553define <4 x float> @shuffle_17fsub_fast(<4 x float> %v1, <4 x float> %v2) {554; CHECK-LABEL: @shuffle_17fsub_fast(555; CHECK-NEXT:    [[TMP1:%.*]] = fsub fast <4 x float> [[V1:%.*]], [[V2:%.*]]556; CHECK-NEXT:    [[R:%.*]] = shufflevector <4 x float> [[TMP1]], <4 x float> poison, <4 x i32> <i32 1, i32 2, i32 3, i32 0>557; CHECK-NEXT:    ret <4 x float> [[R]]558;559  %t1 = shufflevector <4 x float> %v1, <4 x float> zeroinitializer, <4 x i32> <i32 1, i32 2, i32 3, i32 0>560  %t2 = shufflevector <4 x float> %v2, <4 x float> zeroinitializer, <4 x i32> <i32 1, i32 2, i32 3, i32 0>561  %r = fsub fast <4 x float> %t1, %t2562  ret <4 x float> %r563}564 565define <4 x i32> @add_const(<4 x i32> %v) {566; CHECK-LABEL: @add_const(567; CHECK-NEXT:    [[TMP1:%.*]] = add <4 x i32> [[V:%.*]], <i32 44, i32 41, i32 42, i32 43>568; CHECK-NEXT:    [[R:%.*]] = shufflevector <4 x i32> [[TMP1]], <4 x i32> poison, <4 x i32> <i32 1, i32 2, i32 3, i32 0>569; CHECK-NEXT:    ret <4 x i32> [[R]]570;571  %t1 = shufflevector <4 x i32> %v, <4 x i32> undef, <4 x i32> <i32 1, i32 2, i32 3, i32 0>572  %r = add <4 x i32> %t1, <i32 41, i32 42, i32 43, i32 44>573  ret <4 x i32> %r574}575 576define <4 x i32> @sub_const(<4 x i32> %v) {577; CHECK-LABEL: @sub_const(578; CHECK-NEXT:    [[TMP1:%.*]] = sub <4 x i32> <i32 44, i32 43, i32 42, i32 41>, [[V:%.*]]579; CHECK-NEXT:    [[R:%.*]] = shufflevector <4 x i32> [[TMP1]], <4 x i32> poison, <4 x i32> <i32 3, i32 2, i32 1, i32 0>580; CHECK-NEXT:    ret <4 x i32> [[R]]581;582  %t1 = shufflevector <4 x i32> %v, <4 x i32> undef, <4 x i32> <i32 3, i32 2, i32 1, i32 0>583  %r = sub <4 x i32> <i32 41, i32 42, i32 43, i32 44>, %t1584  ret <4 x i32> %r585}586 587; Math before shuffle requires an extra shuffle.588 589define <2 x float> @fadd_const_multiuse(<2 x float> %v) {590; CHECK-LABEL: @fadd_const_multiuse(591; CHECK-NEXT:    [[T1:%.*]] = shufflevector <2 x float> [[V:%.*]], <2 x float> poison, <2 x i32> <i32 1, i32 0>592; CHECK-NEXT:    [[R:%.*]] = fadd <2 x float> [[T1]], <float 4.100000e+01, float 4.200000e+01>593; CHECK-NEXT:    call void @use(<2 x float> [[T1]])594; CHECK-NEXT:    ret <2 x float> [[R]]595;596  %t1 = shufflevector <2 x float> %v, <2 x float> undef, <2 x i32> <i32 1, i32 0>597  %r = fadd <2 x float> %t1, <float 41.0, float 42.0>598  call void @use(<2 x float> %t1)599  ret <2 x float> %r600}601 602; Math before splat allows replacing constant elements with undef lanes.603 604define <4 x i32> @mul_const_splat(<4 x i32> %v) {605; CHECK-LABEL: @mul_const_splat(606; CHECK-NEXT:    [[TMP1:%.*]] = mul <4 x i32> [[V:%.*]], <i32 poison, i32 42, i32 poison, i32 poison>607; CHECK-NEXT:    [[R:%.*]] = shufflevector <4 x i32> [[TMP1]], <4 x i32> poison, <4 x i32> <i32 1, i32 1, i32 1, i32 1>608; CHECK-NEXT:    ret <4 x i32> [[R]]609;610  %t1 = shufflevector <4 x i32> %v, <4 x i32> undef, <4 x i32> <i32 1, i32 1, i32 1, i32 1>611  %r = mul <4 x i32> <i32 42, i32 42, i32 42, i32 42>, %t1612  ret <4 x i32> %r613}614 615; Take 2 elements of a vector and shift each of those by a different amount616 617define <4 x i32> @lshr_const_half_splat(<4 x i32> %v) {618; CHECK-LABEL: @lshr_const_half_splat(619; CHECK-NEXT:    [[TMP1:%.*]] = lshr <4 x i32> <i32 poison, i32 8, i32 9, i32 poison>, [[V:%.*]]620; CHECK-NEXT:    [[R:%.*]] = shufflevector <4 x i32> [[TMP1]], <4 x i32> poison, <4 x i32> <i32 1, i32 1, i32 2, i32 2>621; CHECK-NEXT:    ret <4 x i32> [[R]]622;623  %t1 = shufflevector <4 x i32> %v, <4 x i32> undef, <4 x i32> <i32 1, i32 1, i32 2, i32 2>624  %r = lshr <4 x i32> <i32 8, i32 8, i32 9, i32 9>, %t1625  ret <4 x i32> %r626}627 628; We can't change this because there's no pre-shuffle version of the fmul constant.629 630define <2 x float> @fmul_const_invalid_constant(<2 x float> %v) {631; CHECK-LABEL: @fmul_const_invalid_constant(632; CHECK-NEXT:    [[T1:%.*]] = shufflevector <2 x float> [[V:%.*]], <2 x float> poison, <2 x i32> zeroinitializer633; CHECK-NEXT:    [[R:%.*]] = fmul <2 x float> [[T1]], <float 4.100000e+01, float 4.200000e+01>634; CHECK-NEXT:    ret <2 x float> [[R]]635;636  %t1 = shufflevector <2 x float> %v, <2 x float> undef, <2 x i32> <i32 0, i32 0>637  %r = fmul <2 x float> %t1, <float 41.0, float 42.0>638  ret <2 x float> %r639}640 641; Reduce the width of the binop by moving it ahead of a shuffle.642 643define <4 x i8> @widening_shuffle_add_1(<2 x i8> %x) {644; CHECK-LABEL: @widening_shuffle_add_1(645; CHECK-NEXT:    [[TMP1:%.*]] = add <2 x i8> [[X:%.*]], <i8 42, i8 43>646; CHECK-NEXT:    [[R:%.*]] = shufflevector <2 x i8> [[TMP1]], <2 x i8> poison, <4 x i32> <i32 0, i32 1, i32 poison, i32 poison>647; CHECK-NEXT:    ret <4 x i8> [[R]]648;649  %widex = shufflevector <2 x i8> %x, <2 x i8> undef, <4 x i32> <i32 0, i32 1, i32 undef, i32 undef>650  %r = add <4 x i8> %widex, <i8 42, i8 43, i8 44, i8 45>651  ret <4 x i8> %r652}653 654define <vscale x 4 x i8> @widening_shuffle_add_1_scalable(<vscale x 2 x i8> %x) {655; CHECK-LABEL: @widening_shuffle_add_1_scalable(656; CHECK-NEXT:    [[TMP1:%.*]] = add <vscale x 2 x i8> [[X:%.*]], splat (i8 42)657; CHECK-NEXT:    [[R:%.*]] = shufflevector <vscale x 2 x i8> [[TMP1]], <vscale x 2 x i8> poison, <vscale x 4 x i32> zeroinitializer658; CHECK-NEXT:    ret <vscale x 4 x i8> [[R]]659;660  %widex = shufflevector <vscale x 2 x i8> %x, <vscale x 2 x i8> poison, <vscale x 4 x i32> zeroinitializer661  %r = add <vscale x 4 x i8> %widex, splat (i8 42)662  ret <vscale x 4 x i8> %r663}664 665; Reduce the width of the binop by moving it ahead of a shuffle.666 667define <4 x i8> @widening_shuffle_add_2(<2 x i8> %x) {668; CHECK-LABEL: @widening_shuffle_add_2(669; CHECK-NEXT:    [[TMP1:%.*]] = add <2 x i8> [[X:%.*]], <i8 43, i8 42>670; CHECK-NEXT:    [[R:%.*]] = shufflevector <2 x i8> [[TMP1]], <2 x i8> poison, <4 x i32> <i32 1, i32 0, i32 poison, i32 poison>671; CHECK-NEXT:    ret <4 x i8> [[R]]672;673  %widex = shufflevector <2 x i8> %x, <2 x i8> undef, <4 x i32> <i32 1, i32 0, i32 undef, i32 undef>674  %r = add <4 x i8> %widex, <i8 42, i8 43, i8 44, i8 45>675  ret <4 x i8> %r676}677 678; Negative test - widening shuffles have the same mask/constant constraint as non-size-changing shuffles.679 680define <4 x i8> @widening_shuffle_add_invalid_constant(<2 x i8> %x) {681; CHECK-LABEL: @widening_shuffle_add_invalid_constant(682; CHECK-NEXT:    [[WIDEX:%.*]] = shufflevector <2 x i8> [[X:%.*]], <2 x i8> poison, <4 x i32> <i32 1, i32 1, i32 poison, i32 poison>683; CHECK-NEXT:    [[R:%.*]] = add <4 x i8> [[WIDEX]], <i8 42, i8 43, i8 44, i8 45>684; CHECK-NEXT:    ret <4 x i8> [[R]]685;686  %widex = shufflevector <2 x i8> %x, <2 x i8> undef, <4 x i32> <i32 1, i32 1, i32 undef, i32 undef>687  %r = add <4 x i8> %widex, <i8 42, i8 43, i8 44, i8 45>688  ret <4 x i8> %r689}690 691; Negative test - widening shuffles have an additional constraint: they must not extend with anything but undefs.692 693define <4 x i8> @widening_shuffle_add_invalid_mask(<2 x i8> %x) {694; CHECK-LABEL: @widening_shuffle_add_invalid_mask(695; CHECK-NEXT:    [[WIDEX:%.*]] = shufflevector <2 x i8> [[X:%.*]], <2 x i8> poison, <4 x i32> <i32 0, i32 1, i32 poison, i32 0>696; CHECK-NEXT:    [[R:%.*]] = add <4 x i8> [[WIDEX]], <i8 42, i8 43, i8 44, i8 45>697; CHECK-NEXT:    ret <4 x i8> [[R]]698;699  %widex = shufflevector <2 x i8> %x, <2 x i8> undef, <4 x i32> <i32 0, i32 1, i32 undef, i32 0>700  %r = add <4 x i8> %widex, <i8 42, i8 43, i8 44, i8 45>701  ret <4 x i8> %r702}703 704; A binop that produces undef in the high lanes can be moved before the shuffle.705; This is ok because 'shl C, undef --> undef'.706 707define <4 x i16> @widening_shuffle_shl_constant_op0(<2 x i16> %v) {708; CHECK-LABEL: @widening_shuffle_shl_constant_op0(709; CHECK-NEXT:    [[TMP1:%.*]] = shl <2 x i16> <i16 42, i16 -42>, [[V:%.*]]710; CHECK-NEXT:    [[BO:%.*]] = shufflevector <2 x i16> [[TMP1]], <2 x i16> poison, <4 x i32> <i32 0, i32 1, i32 poison, i32 poison>711; CHECK-NEXT:    ret <4 x i16> [[BO]]712;713  %shuf = shufflevector <2 x i16> %v, <2 x i16> undef, <4 x i32> <i32 0, i32 1, i32 undef, i32 undef>714  %bo = shl <4 x i16> <i16 42, i16 -42, i16 -1, i16 -1>, %shuf715  ret <4 x i16> %bo716}717 718; A binop that produces undef in the high lanes can be moved before the shuffle.719; This is ok because 'shl undef, 0 --> undef'.720 721define <4 x i16> @widening_shuffle_shl_constant_op1(<2 x i16> %v) {722; CHECK-LABEL: @widening_shuffle_shl_constant_op1(723; CHECK-NEXT:    [[TMP1:%.*]] = shl <2 x i16> [[V:%.*]], <i16 2, i16 4>724; CHECK-NEXT:    [[BO:%.*]] = shufflevector <2 x i16> [[TMP1]], <2 x i16> poison, <4 x i32> <i32 0, i32 1, i32 poison, i32 poison>725; CHECK-NEXT:    ret <4 x i16> [[BO]]726;727  %shuf = shufflevector <2 x i16> %v, <2 x i16> undef, <4 x i32> <i32 0, i32 1, i32 undef, i32 undef>728  %bo = shl <4 x i16> %shuf, <i16 2, i16 4, i16 0, i16 0>729  ret <4 x i16> %bo730}731 732; This is valid for poison, but would not be valid for undef.733 734define <4 x i16> @widening_shuffle_shl_constant_op1_non0(<2 x i16> %v) {735; CHECK-LABEL: @widening_shuffle_shl_constant_op1_non0(736; CHECK-NEXT:    [[TMP1:%.*]] = shl <2 x i16> [[V:%.*]], <i16 2, i16 4>737; CHECK-NEXT:    [[BO:%.*]] = shufflevector <2 x i16> [[TMP1]], <2 x i16> poison, <4 x i32> <i32 0, i32 1, i32 poison, i32 poison>738; CHECK-NEXT:    ret <4 x i16> [[BO]]739;740  %shuf = shufflevector <2 x i16> %v, <2 x i16> undef, <4 x i32> <i32 0, i32 1, i32 undef, i32 undef>741  %bo = shl <4 x i16> %shuf, <i16 2, i16 4, i16 1, i16 2>742  ret <4 x i16> %bo743}744 745; Previously, a shufflevector would produce an undef element from an undef mask746; index, which meant that pulling the shuffle out wasn't correct if the original747; binary op produced a non-undef result, e.g. or -1, undef --> -1.748;749; However nowadays shufflevector produces poison, which is safe to propagate.750 751define <4 x i16> @widening_shuffle_or(<2 x i16> %v) {752; CHECK-LABEL: @widening_shuffle_or(753; CHECK-NEXT:    [[TMP1:%.*]] = or <2 x i16> [[V:%.*]], <i16 42, i16 -42>754; CHECK-NEXT:    [[BO:%.*]] = shufflevector <2 x i16> [[TMP1]], <2 x i16> poison, <4 x i32> <i32 0, i32 1, i32 poison, i32 poison>755; CHECK-NEXT:    ret <4 x i16> [[BO]]756;757  %shuf = shufflevector <2 x i16> %v, <2 x i16> undef, <4 x i32> <i32 0, i32 1, i32 undef, i32 undef>758  %bo = or <4 x i16> %shuf, <i16 42, i16 -42, i16 -1, i16 -1>759  ret <4 x i16> %bo760}761 762define <4 x i32> @shuffle_17add2(<4 x i32> %v) {763; CHECK-LABEL: @shuffle_17add2(764; CHECK-NEXT:    [[TMP1:%.*]] = shl <4 x i32> [[V:%.*]], splat (i32 1)765; CHECK-NEXT:    ret <4 x i32> [[TMP1]]766;767  %t1 = shufflevector <4 x i32> %v, <4 x i32> zeroinitializer, <4 x i32> <i32 3, i32 2, i32 1, i32 0>768  %t2 = add <4 x i32> %t1, %t1769  %r = shufflevector <4 x i32> %t2, <4 x i32> zeroinitializer, <4 x i32> <i32 3, i32 2, i32 1, i32 0>770  ret <4 x i32> %r771}772 773define <4 x i32> @shuffle_17mulsplat(<4 x i32> %v) {774; CHECK-LABEL: @shuffle_17mulsplat(775; CHECK-NEXT:    [[TMP1:%.*]] = mul <4 x i32> [[V:%.*]], [[V]]776; CHECK-NEXT:    [[M1:%.*]] = shufflevector <4 x i32> [[TMP1]], <4 x i32> poison, <4 x i32> zeroinitializer777; CHECK-NEXT:    ret <4 x i32> [[M1]]778;779  %s1 = shufflevector <4 x i32> %v, <4 x i32> zeroinitializer, <4 x i32> zeroinitializer780  %m1 = mul <4 x i32> %s1, %s1781  %s2 = shufflevector <4 x i32> %m1, <4 x i32> zeroinitializer, <4 x i32> <i32 1, i32 1, i32 1, i32 1>782  ret <4 x i32> %s2783}784 785; Do not reorder shuffle and binop if LHS of shuffles are of different size786define <2 x i32> @pr19717(<4 x i32> %in0, <2 x i32> %in1) {787; CHECK-LABEL: @pr19717(788; CHECK-NEXT:    [[SHUFFLE:%.*]] = shufflevector <4 x i32> [[IN0:%.*]], <4 x i32> poison, <2 x i32> zeroinitializer789; CHECK-NEXT:    [[SHUFFLE4:%.*]] = shufflevector <2 x i32> [[IN1:%.*]], <2 x i32> poison, <2 x i32> zeroinitializer790; CHECK-NEXT:    [[MUL:%.*]] = mul <2 x i32> [[SHUFFLE]], [[SHUFFLE4]]791; CHECK-NEXT:    ret <2 x i32> [[MUL]]792;793  %shuffle = shufflevector <4 x i32> %in0, <4 x i32> %in0, <2 x i32> zeroinitializer794  %shuffle4 = shufflevector <2 x i32> %in1, <2 x i32> %in1, <2 x i32> zeroinitializer795  %mul = mul <2 x i32> %shuffle, %shuffle4796  ret <2 x i32> %mul797}798 799define <4 x i16> @pr19717a(<8 x i16> %in0, <8 x i16> %in1) {800; CHECK-LABEL: @pr19717a(801; CHECK-NEXT:    [[TMP1:%.*]] = mul <8 x i16> [[IN0:%.*]], [[IN1:%.*]]802; CHECK-NEXT:    [[MUL:%.*]] = shufflevector <8 x i16> [[TMP1]], <8 x i16> poison, <4 x i32> <i32 5, i32 5, i32 5, i32 5>803; CHECK-NEXT:    ret <4 x i16> [[MUL]]804;805  %shuffle = shufflevector <8 x i16> %in0, <8 x i16> %in0, <4 x i32> <i32 5, i32 5, i32 5, i32 5>806  %shuffle1 = shufflevector <8 x i16> %in1, <8 x i16> %in1, <4 x i32> <i32 5, i32 5, i32 5, i32 5>807  %mul = mul <4 x i16> %shuffle, %shuffle1808  ret <4 x i16> %mul809}810 811define <8 x i8> @pr19730(<16 x i8> %in0) {812; CHECK-LABEL: @pr19730(813; 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>814; 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>815; CHECK-NEXT:    ret <8 x i8> [[SHUFFLE1]]816;817  %shuffle = shufflevector <16 x i8> %in0, <16 x i8> undef, <8 x i32> <i32 7, i32 6, i32 5, i32 4, i32 3, i32 2, i32 1, i32 0>818  %shuffle1 = shufflevector <8 x i8> %shuffle, <8 x i8> undef, <8 x i32> <i32 7, i32 6, i32 5, i32 4, i32 3, i32 2, i32 1, i32 0>819  ret <8 x i8> %shuffle1820}821 822define i32 @pr19737(<4 x i32> %in0) {823; CHECK-LABEL: @pr19737(824; CHECK-NEXT:    [[TMP1:%.*]] = extractelement <4 x i32> [[IN0:%.*]], i64 0825; CHECK-NEXT:    ret i32 [[TMP1]]826;827  %shuffle.i = shufflevector <4 x i32> zeroinitializer, <4 x i32> %in0, <4 x i32> <i32 0, i32 4, i32 2, i32 6>828  %neg.i = xor <4 x i32> %shuffle.i, <i32 -1, i32 -1, i32 -1, i32 -1>829  %and.i = and <4 x i32> %in0, %neg.i830  %rv = extractelement <4 x i32> %and.i, i32 0831  ret i32 %rv832}833 834; In PR20059 ( http://llvm.org/pr20059 ), shufflevector operations are reordered/removed835; for an srem operation. This is not a valid optimization because it may cause a trap836; on div-by-zero.837 838define <4 x i32> @pr20059(<4 x i32> %p1, <4 x i32> %p2) {839; CHECK-LABEL: @pr20059(840; CHECK-NEXT:    [[SPLAT1:%.*]] = shufflevector <4 x i32> [[P1:%.*]], <4 x i32> poison, <4 x i32> zeroinitializer841; CHECK-NEXT:    [[SPLAT2:%.*]] = shufflevector <4 x i32> [[P2:%.*]], <4 x i32> poison, <4 x i32> zeroinitializer842; CHECK-NEXT:    [[RETVAL:%.*]] = srem <4 x i32> [[SPLAT1]], [[SPLAT2]]843; CHECK-NEXT:    ret <4 x i32> [[RETVAL]]844;845  %splat1 = shufflevector <4 x i32> %p1, <4 x i32> undef, <4 x i32> zeroinitializer846  %splat2 = shufflevector <4 x i32> %p2, <4 x i32> undef, <4 x i32> zeroinitializer847  %retval = srem <4 x i32> %splat1, %splat2848  ret <4 x i32> %retval849}850 851define <4 x i32> @pr20114(<4 x i32> %__mask) {852; CHECK-LABEL: @pr20114(853; CHECK-NEXT:    [[MASK01_I:%.*]] = shufflevector <4 x i32> [[__MASK:%.*]], <4 x i32> poison, <4 x i32> <i32 0, i32 0, i32 1, i32 1>854; 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>)855; CHECK-NEXT:    ret <4 x i32> [[MASKED_NEW_I_I_I]]856;857  %mask01.i = shufflevector <4 x i32> %__mask, <4 x i32> undef, <4 x i32> <i32 0, i32 0, i32 1, i32 1>858  %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.i859  ret <4 x i32> %masked_new.i.i.i860}861 862define <2 x ptr> @pr23113(<4 x ptr> %A) {863; CHECK-LABEL: @pr23113(864; CHECK-NEXT:    [[TMP1:%.*]] = shufflevector <4 x ptr> [[A:%.*]], <4 x ptr> poison, <2 x i32> <i32 0, i32 1>865; CHECK-NEXT:    ret <2 x ptr> [[TMP1]]866;867  %1 = shufflevector <4 x ptr> %A, <4 x ptr> undef, <2 x i32> <i32 0, i32 1>868  ret <2 x ptr> %1869}870 871; Unused lanes in the new binop should not kill the entire op (although it may simplify anyway as shown here).872 873define <2 x i32> @PR37648(<2 x i32> %x) {874; CHECK-LABEL: @PR37648(875; CHECK-NEXT:    ret <2 x i32> zeroinitializer876;877  %splat = shufflevector <2 x i32> %x, <2 x i32> undef, <2 x i32> zeroinitializer878  %r = urem <2 x i32> %splat, <i32 1, i32 1>879  ret <2 x i32> %r880}881 882; Test shuffle followed by binop with splat constant for all 18 binop opcodes.883; Test with constant as operand 0 and operand 1 for non-commutative opcodes.884 885define <2 x i32> @add_splat_constant(<2 x i32> %x) {886; CHECK-LABEL: @add_splat_constant(887; CHECK-NEXT:    [[TMP1:%.*]] = add <2 x i32> [[X:%.*]], <i32 42, i32 poison>888; CHECK-NEXT:    [[R:%.*]] = shufflevector <2 x i32> [[TMP1]], <2 x i32> poison, <2 x i32> zeroinitializer889; CHECK-NEXT:    ret <2 x i32> [[R]]890;891  %splat = shufflevector <2 x i32> %x, <2 x i32> undef, <2 x i32> zeroinitializer892  %r = add <2 x i32> %splat, <i32 42, i32 42>893  ret <2 x i32> %r894}895 896define <2 x i32> @sub_splat_constant0(<2 x i32> %x) {897; CHECK-LABEL: @sub_splat_constant0(898; CHECK-NEXT:    [[TMP1:%.*]] = sub <2 x i32> <i32 42, i32 poison>, [[X:%.*]]899; CHECK-NEXT:    [[R:%.*]] = shufflevector <2 x i32> [[TMP1]], <2 x i32> poison, <2 x i32> zeroinitializer900; CHECK-NEXT:    ret <2 x i32> [[R]]901;902  %splat = shufflevector <2 x i32> %x, <2 x i32> undef, <2 x i32> zeroinitializer903  %r = sub <2 x i32> <i32 42, i32 42>, %splat904  ret <2 x i32> %r905}906 907define <2 x i32> @sub_splat_constant1(<2 x i32> %x) {908; CHECK-LABEL: @sub_splat_constant1(909; CHECK-NEXT:    [[TMP1:%.*]] = add <2 x i32> [[X:%.*]], <i32 -42, i32 poison>910; CHECK-NEXT:    [[R:%.*]] = shufflevector <2 x i32> [[TMP1]], <2 x i32> poison, <2 x i32> zeroinitializer911; CHECK-NEXT:    ret <2 x i32> [[R]]912;913  %splat = shufflevector <2 x i32> %x, <2 x i32> undef, <2 x i32> zeroinitializer914  %r = sub <2 x i32> %splat, <i32 42, i32 42>915  ret <2 x i32> %r916}917 918define <2 x i32> @mul_splat_constant(<2 x i32> %x) {919; CHECK-LABEL: @mul_splat_constant(920; CHECK-NEXT:    [[TMP1:%.*]] = mul <2 x i32> [[X:%.*]], <i32 42, i32 poison>921; CHECK-NEXT:    [[R:%.*]] = shufflevector <2 x i32> [[TMP1]], <2 x i32> poison, <2 x i32> zeroinitializer922; CHECK-NEXT:    ret <2 x i32> [[R]]923;924  %splat = shufflevector <2 x i32> %x, <2 x i32> undef, <2 x i32> zeroinitializer925  %r = mul <2 x i32> %splat, <i32 42, i32 42>926  ret <2 x i32> %r927}928 929define <2 x i32> @shl_splat_constant0(<2 x i32> %x) {930; CHECK-LABEL: @shl_splat_constant0(931; CHECK-NEXT:    [[TMP1:%.*]] = shl <2 x i32> <i32 5, i32 poison>, [[X:%.*]]932; CHECK-NEXT:    [[R:%.*]] = shufflevector <2 x i32> [[TMP1]], <2 x i32> poison, <2 x i32> zeroinitializer933; CHECK-NEXT:    ret <2 x i32> [[R]]934;935  %splat = shufflevector <2 x i32> %x, <2 x i32> undef, <2 x i32> zeroinitializer936  %r = shl <2 x i32> <i32 5, i32 5>, %splat937  ret <2 x i32> %r938}939 940define <2 x i32> @shl_splat_constant1(<2 x i32> %x) {941; CHECK-LABEL: @shl_splat_constant1(942; CHECK-NEXT:    [[TMP1:%.*]] = shl <2 x i32> [[X:%.*]], <i32 5, i32 poison>943; CHECK-NEXT:    [[R:%.*]] = shufflevector <2 x i32> [[TMP1]], <2 x i32> poison, <2 x i32> zeroinitializer944; CHECK-NEXT:    ret <2 x i32> [[R]]945;946  %splat = shufflevector <2 x i32> %x, <2 x i32> undef, <2 x i32> zeroinitializer947  %r = shl <2 x i32> %splat, <i32 5, i32 5>948  ret <2 x i32> %r949}950 951define <vscale x 2 x i32> @shl_splat_constant0_scalable(<vscale x 2 x i32> %x) {952; CHECK-LABEL: @shl_splat_constant0_scalable(953; CHECK-NEXT:    [[TMP1:%.*]] = shl <vscale x 2 x i32> splat (i32 5), [[X:%.*]]954; CHECK-NEXT:    [[R:%.*]] = shufflevector <vscale x 2 x i32> [[TMP1]], <vscale x 2 x i32> poison, <vscale x 2 x i32> zeroinitializer955; CHECK-NEXT:    ret <vscale x 2 x i32> [[R]]956;957  %splat = shufflevector <vscale x 2 x i32> %x, <vscale x 2 x i32> poison, <vscale x 2 x i32> zeroinitializer958  %r = shl <vscale x 2 x i32> splat (i32 5), %splat959  ret <vscale x 2 x i32> %r960}961 962define <vscale x 2 x i32> @shl_splat_constant1_scalable(<vscale x 2 x i32> %x) {963; CHECK-LABEL: @shl_splat_constant1_scalable(964; CHECK-NEXT:    [[TMP1:%.*]] = shl <vscale x 2 x i32> [[X:%.*]], splat (i32 5)965; CHECK-NEXT:    [[R:%.*]] = shufflevector <vscale x 2 x i32> [[TMP1]], <vscale x 2 x i32> poison, <vscale x 2 x i32> zeroinitializer966; CHECK-NEXT:    ret <vscale x 2 x i32> [[R]]967;968  %splat = shufflevector <vscale x 2 x i32> %x, <vscale x 2 x i32> poison, <vscale x 2 x i32> zeroinitializer969  %r = shl <vscale x 2 x i32> %splat, splat (i32 5)970  ret <vscale x 2 x i32> %r971}972 973define <2 x i32> @ashr_splat_constant0(<2 x i32> %x) {974; CHECK-LABEL: @ashr_splat_constant0(975; CHECK-NEXT:    [[TMP1:%.*]] = lshr <2 x i32> <i32 5, i32 poison>, [[X:%.*]]976; CHECK-NEXT:    [[R:%.*]] = shufflevector <2 x i32> [[TMP1]], <2 x i32> poison, <2 x i32> zeroinitializer977; CHECK-NEXT:    ret <2 x i32> [[R]]978;979  %splat = shufflevector <2 x i32> %x, <2 x i32> undef, <2 x i32> zeroinitializer980  %r = ashr <2 x i32> <i32 5, i32 5>, %splat981  ret <2 x i32> %r982}983 984define <2 x i32> @ashr_splat_constant1(<2 x i32> %x) {985; CHECK-LABEL: @ashr_splat_constant1(986; CHECK-NEXT:    [[TMP1:%.*]] = ashr <2 x i32> [[X:%.*]], <i32 5, i32 poison>987; CHECK-NEXT:    [[R:%.*]] = shufflevector <2 x i32> [[TMP1]], <2 x i32> poison, <2 x i32> zeroinitializer988; CHECK-NEXT:    ret <2 x i32> [[R]]989;990  %splat = shufflevector <2 x i32> %x, <2 x i32> undef, <2 x i32> zeroinitializer991  %r = ashr <2 x i32> %splat, <i32 5, i32 5>992  ret <2 x i32> %r993}994 995define <2 x i32> @lshr_splat_constant0(<2 x i32> %x) {996; CHECK-LABEL: @lshr_splat_constant0(997; CHECK-NEXT:    [[TMP1:%.*]] = lshr <2 x i32> <i32 5, i32 poison>, [[X:%.*]]998; CHECK-NEXT:    [[R:%.*]] = shufflevector <2 x i32> [[TMP1]], <2 x i32> poison, <2 x i32> zeroinitializer999; CHECK-NEXT:    ret <2 x i32> [[R]]1000;1001  %splat = shufflevector <2 x i32> %x, <2 x i32> undef, <2 x i32> zeroinitializer1002  %r = lshr <2 x i32> <i32 5, i32 5>, %splat1003  ret <2 x i32> %r1004}1005 1006define <2 x i32> @lshr_splat_constant1(<2 x i32> %x) {1007; CHECK-LABEL: @lshr_splat_constant1(1008; CHECK-NEXT:    [[TMP1:%.*]] = lshr <2 x i32> [[X:%.*]], <i32 5, i32 poison>1009; CHECK-NEXT:    [[R:%.*]] = shufflevector <2 x i32> [[TMP1]], <2 x i32> poison, <2 x i32> zeroinitializer1010; CHECK-NEXT:    ret <2 x i32> [[R]]1011;1012  %splat = shufflevector <2 x i32> %x, <2 x i32> undef, <2 x i32> zeroinitializer1013  %r = lshr <2 x i32> %splat, <i32 5, i32 5>1014  ret <2 x i32> %r1015}1016 1017define <2 x i32> @urem_splat_constant0(<2 x i32> %x) {1018; CHECK-LABEL: @urem_splat_constant0(1019; CHECK-NEXT:    [[SPLAT:%.*]] = shufflevector <2 x i32> [[X:%.*]], <2 x i32> poison, <2 x i32> zeroinitializer1020; CHECK-NEXT:    [[R:%.*]] = urem <2 x i32> splat (i32 42), [[SPLAT]]1021; CHECK-NEXT:    ret <2 x i32> [[R]]1022;1023  %splat = shufflevector <2 x i32> %x, <2 x i32> undef, <2 x i32> zeroinitializer1024  %r = urem <2 x i32> <i32 42, i32 42>, %splat1025  ret <2 x i32> %r1026}1027 1028define <2 x i32> @urem_splat_constant1(<2 x i32> %x) {1029; CHECK-LABEL: @urem_splat_constant1(1030; CHECK-NEXT:    [[TMP1:%.*]] = urem <2 x i32> [[X:%.*]], <i32 42, i32 1>1031; CHECK-NEXT:    [[R:%.*]] = shufflevector <2 x i32> [[TMP1]], <2 x i32> poison, <2 x i32> zeroinitializer1032; CHECK-NEXT:    ret <2 x i32> [[R]]1033;1034  %splat = shufflevector <2 x i32> %x, <2 x i32> undef, <2 x i32> zeroinitializer1035  %r = urem <2 x i32> %splat, <i32 42, i32 42>1036  ret <2 x i32> %r1037}1038 1039define <2 x i32> @srem_splat_constant0(<2 x i32> %x) {1040; CHECK-LABEL: @srem_splat_constant0(1041; CHECK-NEXT:    [[SPLAT:%.*]] = shufflevector <2 x i32> [[X:%.*]], <2 x i32> poison, <2 x i32> zeroinitializer1042; CHECK-NEXT:    [[R:%.*]] = srem <2 x i32> splat (i32 42), [[SPLAT]]1043; CHECK-NEXT:    ret <2 x i32> [[R]]1044;1045  %splat = shufflevector <2 x i32> %x, <2 x i32> undef, <2 x i32> zeroinitializer1046  %r = srem <2 x i32> <i32 42, i32 42>, %splat1047  ret <2 x i32> %r1048}1049 1050define <2 x i32> @srem_splat_constant1(<2 x i32> %x) {1051; CHECK-LABEL: @srem_splat_constant1(1052; CHECK-NEXT:    [[TMP1:%.*]] = srem <2 x i32> [[X:%.*]], <i32 42, i32 1>1053; CHECK-NEXT:    [[R:%.*]] = shufflevector <2 x i32> [[TMP1]], <2 x i32> poison, <2 x i32> zeroinitializer1054; CHECK-NEXT:    ret <2 x i32> [[R]]1055;1056  %splat = shufflevector <2 x i32> %x, <2 x i32> undef, <2 x i32> zeroinitializer1057  %r = srem <2 x i32> %splat, <i32 42, i32 42>1058  ret <2 x i32> %r1059}1060 1061define <2 x i32> @udiv_splat_constant0(<2 x i32> %x) {1062; CHECK-LABEL: @udiv_splat_constant0(1063; CHECK-NEXT:    [[SPLAT:%.*]] = shufflevector <2 x i32> [[X:%.*]], <2 x i32> poison, <2 x i32> zeroinitializer1064; CHECK-NEXT:    [[R:%.*]] = udiv <2 x i32> splat (i32 42), [[SPLAT]]1065; CHECK-NEXT:    ret <2 x i32> [[R]]1066;1067  %splat = shufflevector <2 x i32> %x, <2 x i32> undef, <2 x i32> zeroinitializer1068  %r = udiv <2 x i32> <i32 42, i32 42>, %splat1069  ret <2 x i32> %r1070}1071 1072define <2 x i32> @udiv_splat_constant1(<2 x i32> %x) {1073; CHECK-LABEL: @udiv_splat_constant1(1074; CHECK-NEXT:    [[TMP1:%.*]] = udiv <2 x i32> [[X:%.*]], <i32 42, i32 1>1075; CHECK-NEXT:    [[R:%.*]] = shufflevector <2 x i32> [[TMP1]], <2 x i32> poison, <2 x i32> zeroinitializer1076; CHECK-NEXT:    ret <2 x i32> [[R]]1077;1078  %splat = shufflevector <2 x i32> %x, <2 x i32> undef, <2 x i32> zeroinitializer1079  %r = udiv <2 x i32> %splat, <i32 42, i32 42>1080  ret <2 x i32> %r1081}1082 1083define <vscale x 2 x i32> @udiv_splat_constant0_scalable(<vscale x 2 x i32> %x) {1084; CHECK-LABEL: @udiv_splat_constant0_scalable(1085; CHECK-NEXT:    [[SPLAT:%.*]] = shufflevector <vscale x 2 x i32> [[X:%.*]], <vscale x 2 x i32> poison, <vscale x 2 x i32> zeroinitializer1086; CHECK-NEXT:    [[R:%.*]] = udiv <vscale x 2 x i32> splat (i32 42), [[SPLAT]]1087; CHECK-NEXT:    ret <vscale x 2 x i32> [[R]]1088;1089  %splat = shufflevector <vscale x 2 x i32> %x, <vscale x 2 x i32> poison, <vscale x 2 x i32> zeroinitializer1090  %r = udiv <vscale x 2 x i32> splat (i32 42), %splat1091  ret <vscale x 2 x i32> %r1092}1093 1094define <vscale x 2 x i32> @udiv_splat_constant1_scalable(<vscale x 2 x i32> %x) {1095; CHECK-LABEL: @udiv_splat_constant1_scalable(1096; CHECK-NEXT:    [[TMP1:%.*]] = udiv <vscale x 2 x i32> [[X:%.*]], splat (i32 42)1097; CHECK-NEXT:    [[R:%.*]] = shufflevector <vscale x 2 x i32> [[TMP1]], <vscale x 2 x i32> poison, <vscale x 2 x i32> zeroinitializer1098; CHECK-NEXT:    ret <vscale x 2 x i32> [[R]]1099;1100  %splat = shufflevector <vscale x 2 x i32> %x, <vscale x 2 x i32> poison, <vscale x 2 x i32> zeroinitializer1101  %r = udiv <vscale x 2 x i32> %splat, splat (i32 42)1102  ret <vscale x 2 x i32> %r1103}1104 1105define <2 x i32> @sdiv_splat_constant0(<2 x i32> %x) {1106; CHECK-LABEL: @sdiv_splat_constant0(1107; CHECK-NEXT:    [[SPLAT:%.*]] = shufflevector <2 x i32> [[X:%.*]], <2 x i32> poison, <2 x i32> zeroinitializer1108; CHECK-NEXT:    [[R:%.*]] = sdiv <2 x i32> splat (i32 42), [[SPLAT]]1109; CHECK-NEXT:    ret <2 x i32> [[R]]1110;1111  %splat = shufflevector <2 x i32> %x, <2 x i32> undef, <2 x i32> zeroinitializer1112  %r = sdiv <2 x i32> <i32 42, i32 42>, %splat1113  ret <2 x i32> %r1114}1115 1116define <2 x i32> @sdiv_splat_constant1(<2 x i32> %x) {1117; CHECK-LABEL: @sdiv_splat_constant1(1118; CHECK-NEXT:    [[TMP1:%.*]] = sdiv <2 x i32> [[X:%.*]], <i32 42, i32 1>1119; CHECK-NEXT:    [[R:%.*]] = shufflevector <2 x i32> [[TMP1]], <2 x i32> poison, <2 x i32> zeroinitializer1120; CHECK-NEXT:    ret <2 x i32> [[R]]1121;1122  %splat = shufflevector <2 x i32> %x, <2 x i32> undef, <2 x i32> zeroinitializer1123  %r = sdiv <2 x i32> %splat, <i32 42, i32 42>1124  ret <2 x i32> %r1125}1126 1127define <2 x i32> @and_splat_constant(<2 x i32> %x) {1128; CHECK-LABEL: @and_splat_constant(1129; CHECK-NEXT:    [[TMP1:%.*]] = and <2 x i32> [[X:%.*]], <i32 42, i32 poison>1130; CHECK-NEXT:    [[R:%.*]] = shufflevector <2 x i32> [[TMP1]], <2 x i32> poison, <2 x i32> zeroinitializer1131; CHECK-NEXT:    ret <2 x i32> [[R]]1132;1133  %splat = shufflevector <2 x i32> %x, <2 x i32> undef, <2 x i32> zeroinitializer1134  %r = and <2 x i32> %splat, <i32 42, i32 42>1135  ret <2 x i32> %r1136}1137 1138define <4 x i16> @and_constant_mask_poison(<4 x i16> %add) {1139; CHECK-LABEL: @and_constant_mask_poison(1140; CHECK-NEXT:  entry:1141; CHECK-NEXT:    [[AND:%.*]] = shufflevector <4 x i16> [[ADD:%.*]], <4 x i16> poison, <4 x i32> <i32 poison, i32 poison, i32 1, i32 1>1142; CHECK-NEXT:    ret <4 x i16> [[AND]]1143;1144entry:1145  %shuffle = shufflevector <4 x i16> %add, <4 x i16> undef, <4 x i32> <i32 undef, i32 undef, i32 1, i32 1>1146  %and = and <4 x i16> %shuffle, <i16 0, i16 0, i16 -1, i16 -1>1147  ret <4 x i16> %and1148}1149 1150define <4 x i16> @and_constant_mask_poison_2(<4 x i16> %add) {1151; CHECK-LABEL: @and_constant_mask_poison_2(1152; CHECK-NEXT:  entry:1153; CHECK-NEXT:    [[AND:%.*]] = shufflevector <4 x i16> [[ADD:%.*]], <4 x i16> poison, <4 x i32> <i32 1, i32 1, i32 1, i32 poison>1154; CHECK-NEXT:    ret <4 x i16> [[AND]]1155;1156entry:1157  %shuffle = shufflevector <4 x i16> %add, <4 x i16> undef, <4 x i32> <i32 1, i32 1, i32 1, i32 undef>1158  %and = and <4 x i16> %shuffle, <i16 -1, i16 -1, i16 -1, i16 -0>1159  ret <4 x i16> %and1160}1161 1162; We can move the AND across the shuffle, as -1 (AND identity value) is used for undef lanes.1163define <4 x i16> @and_constant_mask_poison_3(<4 x i16> %add) {1164; CHECK-LABEL: @and_constant_mask_poison_3(1165; CHECK-NEXT:  entry:1166; CHECK-NEXT:    ret <4 x i16> <i16 0, i16 0, i16 0, i16 undef>1167;1168entry:1169  %shuffle = shufflevector <4 x i16> %add, <4 x i16> undef, <4 x i32> <i32 0, i32 1, i32 1, i32 undef>1170  %and = and <4 x i16> %shuffle, <i16 0, i16 0, i16 0, i16 -1>1171  ret <4 x i16> %and1172}1173 1174; We can move the AND across the shuffle, as -1 (AND identity value) is used for undef lanes.1175define <4 x i16> @and_constant_mask_poison_4(<4 x i16> %add) {1176; CHECK-LABEL: @and_constant_mask_poison_4(1177; CHECK-NEXT:  entry:1178; CHECK-NEXT:    [[TMP0:%.*]] = and <4 x i16> [[ADD:%.*]], <i16 9, i16 20, i16 poison, i16 poison>1179; CHECK-NEXT:    [[AND:%.*]] = shufflevector <4 x i16> [[TMP0]], <4 x i16> poison, <4 x i32> <i32 0, i32 1, i32 1, i32 poison>1180; CHECK-NEXT:    ret <4 x i16> [[AND]]1181;1182entry:1183  %shuffle = shufflevector <4 x i16> %add, <4 x i16> undef, <4 x i32> <i32 0, i32 1, i32 1, i32 undef>1184  %and = and <4 x i16> %shuffle, <i16 9, i16 20, i16 20, i16 -1>1185  ret <4 x i16> %and1186}1187 1188define <4 x i16> @and_constant_mask_not_undef(<4 x i16> %add) {1189; CHECK-LABEL: @and_constant_mask_not_undef(1190; CHECK-NEXT:  entry:1191; CHECK-NEXT:    [[TMP0:%.*]] = and <4 x i16> [[ADD:%.*]], <i16 poison, i16 -1, i16 0, i16 0>1192; CHECK-NEXT:    [[AND:%.*]] = shufflevector <4 x i16> [[TMP0]], <4 x i16> poison, <4 x i32> <i32 2, i32 3, i32 1, i32 1>1193; CHECK-NEXT:    ret <4 x i16> [[AND]]1194;1195entry:1196  %shuffle = shufflevector <4 x i16> %add, <4 x i16> undef, <4 x i32> <i32 2, i32 3, i32 1, i32 1>1197  %and = and <4 x i16> %shuffle, <i16 0, i16 0, i16 -1, i16 -1>1198  ret <4 x i16> %and1199}1200 1201define <4 x i16> @or_constant_mask_poison(<4 x i16> %in) {1202; CHECK-LABEL: @or_constant_mask_poison(1203; CHECK-NEXT:  entry:1204; CHECK-NEXT:    [[OR:%.*]] = shufflevector <4 x i16> [[IN:%.*]], <4 x i16> poison, <4 x i32> <i32 poison, i32 poison, i32 1, i32 1>1205; CHECK-NEXT:    ret <4 x i16> [[OR]]1206;1207entry:1208  %shuffle = shufflevector <4 x i16> %in, <4 x i16> undef, <4 x i32> <i32 undef, i32 undef, i32 1, i32 1>1209  %or = or <4 x i16> %shuffle, <i16 -1, i16 -1, i16 0, i16 0>1210  ret <4 x i16> %or1211}1212 1213define <4 x i16> @or_constant_mask_poison_2(<4 x i16> %in) {1214; CHECK-LABEL: @or_constant_mask_poison_2(1215; CHECK-NEXT:  entry:1216; CHECK-NEXT:    [[OR:%.*]] = shufflevector <4 x i16> [[IN:%.*]], <4 x i16> poison, <4 x i32> <i32 poison, i32 1, i32 1, i32 poison>1217; CHECK-NEXT:    ret <4 x i16> [[OR]]1218;1219entry:1220  %shuffle = shufflevector <4 x i16> %in, <4 x i16> undef, <4 x i32> <i32 undef, i32 1, i32 1, i32 undef>1221  %or = or <4 x i16> %shuffle, <i16 -1, i16 0, i16 0, i16 -1>1222  ret <4 x i16> %or1223}1224 1225; We can move the OR across the shuffle, as 0 (OR identity value) is used for undef lanes.1226define <4 x i16> @or_constant_mask_poison_3(<4 x i16> %in) {1227; CHECK-LABEL: @or_constant_mask_poison_3(1228; CHECK-NEXT:  entry:1229; CHECK-NEXT:    ret <4 x i16> <i16 undef, i16 -1, i16 -1, i16 undef>1230;1231entry:1232  %shuffle = shufflevector <4 x i16> %in, <4 x i16> undef, <4 x i32> <i32 undef, i32 1, i32 1, i32 undef>1233  %or = or <4 x i16> %shuffle, <i16 0, i16 -1, i16 -1, i16 0>1234  ret <4 x i16> %or1235}1236 1237; We can move the OR across the shuffle, as 0 (OR identity value) is used for undef lanes.1238define <4 x i16> @or_constant_mask_poison_4(<4 x i16> %in) {1239; CHECK-LABEL: @or_constant_mask_poison_4(1240; CHECK-NEXT:  entry:1241; CHECK-NEXT:    [[TMP0:%.*]] = or <4 x i16> [[IN:%.*]], <i16 poison, i16 99, i16 poison, i16 poison>1242; CHECK-NEXT:    [[OR:%.*]] = shufflevector <4 x i16> [[TMP0]], <4 x i16> poison, <4 x i32> <i32 poison, i32 1, i32 1, i32 poison>1243; CHECK-NEXT:    ret <4 x i16> [[OR]]1244;1245entry:1246  %shuffle = shufflevector <4 x i16> %in, <4 x i16> undef, <4 x i32> <i32 undef, i32 1, i32 1, i32 undef>1247  %or = or <4 x i16> %shuffle, <i16 0, i16 99, i16 99, i16 0>1248  ret <4 x i16> %or1249}1250 1251define <4 x i16> @or_constant_mask_not_undef(<4 x i16> %in) {1252; CHECK-LABEL: @or_constant_mask_not_undef(1253; CHECK-NEXT:  entry:1254; CHECK-NEXT:    [[TMP0:%.*]] = or <4 x i16> [[IN:%.*]], <i16 poison, i16 -1, i16 0, i16 0>1255; CHECK-NEXT:    [[AND:%.*]] = shufflevector <4 x i16> [[TMP0]], <4 x i16> poison, <4 x i32> <i32 2, i32 3, i32 1, i32 1>1256; CHECK-NEXT:    ret <4 x i16> [[AND]]1257;1258entry:1259  %shuffle = shufflevector <4 x i16> %in, <4 x i16> undef, <4 x i32> <i32 2, i32 3, i32 1, i32 1>1260  %and = or <4 x i16> %shuffle, <i16 0, i16 0, i16 -1, i16 -1>1261  ret <4 x i16> %and1262}1263 1264define <4 x i16> @shl_constant_mask_undef(<4 x i16> %in) {1265; CHECK-LABEL: @shl_constant_mask_undef(1266; CHECK-NEXT:  entry:1267; CHECK-NEXT:    [[TMP0:%.*]] = shl <4 x i16> [[IN:%.*]], <i16 10, i16 0, i16 poison, i16 poison>1268; CHECK-NEXT:    [[SHL:%.*]] = shufflevector <4 x i16> [[TMP0]], <4 x i16> poison, <4 x i32> <i32 0, i32 poison, i32 1, i32 1>1269; CHECK-NEXT:    ret <4 x i16> [[SHL]]1270;1271entry:1272  %shuffle = shufflevector <4 x i16> %in, <4 x i16> undef, <4 x i32> <i32 0, i32 undef, i32 1, i32 1>1273  %shl = shl <4 x i16> %shuffle, <i16 10, i16 3, i16 0, i16 0>1274  ret <4 x i16> %shl1275}1276 1277define <4 x i16> @add_constant_mask_undef(<4 x i16> %in) {1278; CHECK-LABEL: @add_constant_mask_undef(1279; CHECK-NEXT:  entry:1280; CHECK-NEXT:    [[ADD:%.*]] = shufflevector <4 x i16> [[IN:%.*]], <4 x i16> poison, <4 x i32> <i32 poison, i32 poison, i32 1, i32 1>1281; CHECK-NEXT:    ret <4 x i16> [[ADD]]1282;1283entry:1284  %shuffle = shufflevector <4 x i16> %in, <4 x i16> undef, <4 x i32> <i32 undef, i32 undef, i32 1, i32 1>1285  %add = add <4 x i16> %shuffle, <i16 10, i16 3, i16 0, i16 0>1286  ret <4 x i16> %add1287}1288 1289define <4 x i16> @add_constant_mask_undef_2(<4 x i16> %in) {1290; CHECK-LABEL: @add_constant_mask_undef_2(1291; CHECK-NEXT:  entry:1292; CHECK-NEXT:    [[TMP0:%.*]] = add <4 x i16> [[IN:%.*]], <i16 poison, i16 0, i16 3, i16 poison>1293; CHECK-NEXT:    [[ADD:%.*]] = shufflevector <4 x i16> [[TMP0]], <4 x i16> poison, <4 x i32> <i32 poison, i32 2, i32 1, i32 1>1294; CHECK-NEXT:    ret <4 x i16> [[ADD]]1295;1296entry:1297  %shuffle = shufflevector <4 x i16> %in, <4 x i16> undef, <4 x i32> <i32 undef, i32 2, i32 1, i32 1>1298  %add = add <4 x i16> %shuffle, <i16 10, i16 3, i16 0, i16 0>1299  ret <4 x i16> %add1300}1301 1302define <4 x i16> @sub_constant_mask_undef(<4 x i16> %in) {1303; CHECK-LABEL: @sub_constant_mask_undef(1304; CHECK-NEXT:  entry:1305; CHECK-NEXT:    [[SUB:%.*]] = shufflevector <4 x i16> [[IN:%.*]], <4 x i16> poison, <4 x i32> <i32 poison, i32 poison, i32 1, i32 1>1306; CHECK-NEXT:    ret <4 x i16> [[SUB]]1307;1308entry:1309  %shuffle = shufflevector <4 x i16> %in, <4 x i16> undef, <4 x i32> <i32 undef, i32 undef, i32 1, i32 1>1310  %sub = sub <4 x i16> %shuffle, <i16 10, i16 3, i16 0, i16 0>1311  ret <4 x i16> %sub1312}1313 1314define <4 x i16> @sub_constant_mask_undef_2(<4 x i16> %in) {1315; CHECK-LABEL: @sub_constant_mask_undef_2(1316; CHECK-NEXT:  entry:1317; CHECK-NEXT:    [[TMP0:%.*]] = add <4 x i16> [[IN:%.*]], <i16 poison, i16 0, i16 -10, i16 poison>1318; CHECK-NEXT:    [[SUB:%.*]] = shufflevector <4 x i16> [[TMP0]], <4 x i16> poison, <4 x i32> <i32 1, i32 1, i32 2, i32 poison>1319; CHECK-NEXT:    ret <4 x i16> [[SUB]]1320;1321entry:1322  %shuffle = shufflevector <4 x i16> %in, <4 x i16> undef, <4 x i32> <i32 1, i32 1, i32 2, i32 undef>1323  %sub = sub <4 x i16> %shuffle, <i16 0, i16 0, i16 10, i16 99>1324  ret <4 x i16> %sub1325}1326 1327define <2 x i32> @or_splat_constant(<2 x i32> %x) {1328; CHECK-LABEL: @or_splat_constant(1329; CHECK-NEXT:    [[TMP1:%.*]] = or <2 x i32> [[X:%.*]], <i32 42, i32 poison>1330; CHECK-NEXT:    [[R:%.*]] = shufflevector <2 x i32> [[TMP1]], <2 x i32> poison, <2 x i32> zeroinitializer1331; CHECK-NEXT:    ret <2 x i32> [[R]]1332;1333  %splat = shufflevector <2 x i32> %x, <2 x i32> undef, <2 x i32> zeroinitializer1334  %r = or <2 x i32> %splat, <i32 42, i32 42>1335  ret <2 x i32> %r1336}1337 1338define <2 x i32> @xor_splat_constant(<2 x i32> %x) {1339; CHECK-LABEL: @xor_splat_constant(1340; CHECK-NEXT:    [[TMP1:%.*]] = xor <2 x i32> [[X:%.*]], <i32 42, i32 poison>1341; CHECK-NEXT:    [[R:%.*]] = shufflevector <2 x i32> [[TMP1]], <2 x i32> poison, <2 x i32> zeroinitializer1342; CHECK-NEXT:    ret <2 x i32> [[R]]1343;1344  %splat = shufflevector <2 x i32> %x, <2 x i32> undef, <2 x i32> zeroinitializer1345  %r = xor <2 x i32> %splat, <i32 42, i32 42>1346  ret <2 x i32> %r1347}1348 1349define <2 x float> @fadd_splat_constant(<2 x float> %x) {1350; CHECK-LABEL: @fadd_splat_constant(1351; CHECK-NEXT:    [[TMP1:%.*]] = fadd <2 x float> [[X:%.*]], <float 4.200000e+01, float poison>1352; CHECK-NEXT:    [[R:%.*]] = shufflevector <2 x float> [[TMP1]], <2 x float> poison, <2 x i32> zeroinitializer1353; CHECK-NEXT:    ret <2 x float> [[R]]1354;1355  %splat = shufflevector <2 x float> %x, <2 x float> undef, <2 x i32> zeroinitializer1356  %r = fadd <2 x float> %splat, <float 42.0, float 42.0>1357  ret <2 x float> %r1358}1359 1360define <2 x float> @fsub_splat_constant0(<2 x float> %x) {1361; CHECK-LABEL: @fsub_splat_constant0(1362; CHECK-NEXT:    [[TMP1:%.*]] = fsub <2 x float> <float 4.200000e+01, float poison>, [[X:%.*]]1363; CHECK-NEXT:    [[R:%.*]] = shufflevector <2 x float> [[TMP1]], <2 x float> poison, <2 x i32> zeroinitializer1364; CHECK-NEXT:    ret <2 x float> [[R]]1365;1366  %splat = shufflevector <2 x float> %x, <2 x float> undef, <2 x i32> zeroinitializer1367  %r = fsub <2 x float> <float 42.0, float 42.0>, %splat1368  ret <2 x float> %r1369}1370 1371define <2 x float> @fsub_splat_constant1(<2 x float> %x) {1372; CHECK-LABEL: @fsub_splat_constant1(1373; CHECK-NEXT:    [[TMP1:%.*]] = fadd <2 x float> [[X:%.*]], <float -4.200000e+01, float poison>1374; CHECK-NEXT:    [[R:%.*]] = shufflevector <2 x float> [[TMP1]], <2 x float> poison, <2 x i32> zeroinitializer1375; CHECK-NEXT:    ret <2 x float> [[R]]1376;1377  %splat = shufflevector <2 x float> %x, <2 x float> undef, <2 x i32> zeroinitializer1378  %r = fsub <2 x float> %splat, <float 42.0, float 42.0>1379  ret <2 x float> %r1380}1381 1382define <2 x float> @fneg(<2 x float> %x) {1383; CHECK-LABEL: @fneg(1384; CHECK-NEXT:    [[R:%.*]] = fneg <2 x float> [[TMP1:%.*]]1385; CHECK-NEXT:    [[R1:%.*]] = shufflevector <2 x float> [[R]], <2 x float> poison, <2 x i32> zeroinitializer1386; CHECK-NEXT:    ret <2 x float> [[R1]]1387;1388  %splat = shufflevector <2 x float> %x, <2 x float> undef, <2 x i32> zeroinitializer1389  %r = fsub <2 x float> <float -0.0, float -0.0>, %splat1390  ret <2 x float> %r1391}1392 1393define <2 x float> @fneg_not_single_source(<2 x float> %x) {1394; CHECK-LABEL: @fneg_not_single_source(1395; CHECK-NEXT:    [[NEG:%.*]] = fneg <2 x float> [[X:%.*]]1396; CHECK-NEXT:    [[SPLAT1:%.*]] = insertelement <2 x float> [[NEG]], float undef, i64 11397; CHECK-NEXT:    ret <2 x float> [[SPLAT1]]1398;1399  %neg = fneg <2 x float> %x1400  %splat = shufflevector <2 x float> %neg, <2 x float> undef, <2 x i32> <i32 0, i32 2>1401  ret <2 x float> %splat1402}1403 1404define <2 x float> @fmul_splat_constant(<2 x float> %x) {1405; CHECK-LABEL: @fmul_splat_constant(1406; CHECK-NEXT:    [[TMP1:%.*]] = fmul <2 x float> [[X:%.*]], <float 4.200000e+01, float poison>1407; CHECK-NEXT:    [[R:%.*]] = shufflevector <2 x float> [[TMP1]], <2 x float> poison, <2 x i32> zeroinitializer1408; CHECK-NEXT:    ret <2 x float> [[R]]1409;1410  %splat = shufflevector <2 x float> %x, <2 x float> undef, <2 x i32> zeroinitializer1411  %r = fmul <2 x float> %splat, <float 42.0, float 42.0>1412  ret <2 x float> %r1413}1414 1415define <2 x float> @fdiv_splat_constant0(<2 x float> %x) {1416; CHECK-LABEL: @fdiv_splat_constant0(1417; CHECK-NEXT:    [[TMP1:%.*]] = fdiv <2 x float> <float 4.200000e+01, float poison>, [[X:%.*]]1418; CHECK-NEXT:    [[R:%.*]] = shufflevector <2 x float> [[TMP1]], <2 x float> poison, <2 x i32> zeroinitializer1419; CHECK-NEXT:    ret <2 x float> [[R]]1420;1421  %splat = shufflevector <2 x float> %x, <2 x float> undef, <2 x i32> zeroinitializer1422  %r = fdiv <2 x float> <float 42.0, float 42.0>, %splat1423  ret <2 x float> %r1424}1425 1426define <2 x float> @fdiv_splat_constant1(<2 x float> %x) {1427; CHECK-LABEL: @fdiv_splat_constant1(1428; CHECK-NEXT:    [[TMP1:%.*]] = fdiv <2 x float> [[X:%.*]], <float 4.200000e+01, float poison>1429; CHECK-NEXT:    [[R:%.*]] = shufflevector <2 x float> [[TMP1]], <2 x float> poison, <2 x i32> zeroinitializer1430; CHECK-NEXT:    ret <2 x float> [[R]]1431;1432  %splat = shufflevector <2 x float> %x, <2 x float> undef, <2 x i32> zeroinitializer1433  %r = fdiv <2 x float> %splat, <float 42.0, float 42.0>1434  ret <2 x float> %r1435}1436 1437define <2 x float> @frem_splat_constant0(<2 x float> %x) {1438; CHECK-LABEL: @frem_splat_constant0(1439; CHECK-NEXT:    [[TMP1:%.*]] = frem <2 x float> <float 4.200000e+01, float poison>, [[X:%.*]]1440; CHECK-NEXT:    [[R:%.*]] = shufflevector <2 x float> [[TMP1]], <2 x float> poison, <2 x i32> zeroinitializer1441; CHECK-NEXT:    ret <2 x float> [[R]]1442;1443  %splat = shufflevector <2 x float> %x, <2 x float> undef, <2 x i32> zeroinitializer1444  %r = frem <2 x float> <float 42.0, float 42.0>, %splat1445  ret <2 x float> %r1446}1447 1448define <2 x float> @frem_splat_constant1(<2 x float> %x) {1449; CHECK-LABEL: @frem_splat_constant1(1450; CHECK-NEXT:    [[TMP1:%.*]] = frem <2 x float> [[X:%.*]], <float 4.200000e+01, float poison>1451; CHECK-NEXT:    [[R:%.*]] = shufflevector <2 x float> [[TMP1]], <2 x float> poison, <2 x i32> zeroinitializer1452; CHECK-NEXT:    ret <2 x float> [[R]]1453;1454  %splat = shufflevector <2 x float> %x, <2 x float> undef, <2 x i32> zeroinitializer1455  %r = frem <2 x float> %splat, <float 42.0, float 42.0>1456  ret <2 x float> %r1457}1458 1459; Equivalent shuffle masks, but only one is a narrowing op.1460 1461define <2 x i1> @PR40734(<1 x i1> %x, <4 x i1> %y) {1462; CHECK-LABEL: @PR40734(1463; CHECK-NEXT:    [[WIDEN:%.*]] = shufflevector <1 x i1> zeroinitializer, <1 x i1> [[X:%.*]], <2 x i32> <i32 0, i32 1>1464; CHECK-NEXT:    [[NARROW:%.*]] = shufflevector <4 x i1> [[Y:%.*]], <4 x i1> poison, <2 x i32> <i32 0, i32 1>1465; CHECK-NEXT:    [[R:%.*]] = and <2 x i1> [[WIDEN]], [[NARROW]]1466; CHECK-NEXT:    ret <2 x i1> [[R]]1467;1468  %widen = shufflevector <1 x i1> zeroinitializer, <1 x i1> %x, <2 x i32> <i32 0, i32 1>1469  %narrow = shufflevector <4 x i1> %y, <4 x i1> undef, <2 x i32> <i32 0, i32 1>1470  %r = and <2 x i1> %widen, %narrow1471  ret <2 x i1> %r1472}1473 1474; Negative test - do not transform non-power-of-2 unless we know the backend handles these sequences identically.1475 1476define <7 x i8> @insert_subvector_shuffles(<3 x i8> %x, <3 x i8> %y) {1477; CHECK-LABEL: @insert_subvector_shuffles(1478; 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>1479; 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>1480; 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>1481; CHECK-NEXT:    ret <7 x i8> [[S3]]1482;1483  %s1 = shufflevector <3 x i8> %x, <3 x i8> undef, <7 x i32> <i32 0, i32 1, i32 undef, i32 undef, i32 undef, i32 undef, i32 undef>1484  %s2 = shufflevector <3 x i8> %y, <3 x i8> undef, <7 x i32> <i32 undef, i32 1, i32 2, i32 undef, i32 undef, i32 undef, i32 undef>1485  %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>1486  ret <7 x i8> %s31487}1488 1489define <8 x i8> @insert_subvector_shuffles_pow2elts(<2 x i8> %x, <2 x i8> %y) {1490; CHECK-LABEL: @insert_subvector_shuffles_pow2elts(1491; 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>1492; CHECK-NEXT:    ret <8 x i8> [[S3]]1493;1494  %s1 = shufflevector <2 x i8> %x, <2 x i8> undef, <8 x i32> <i32 0, i32 1, i32 undef, i32 undef, i32 undef, i32 undef, i32 undef, i32 undef>1495  %s2 = shufflevector <2 x i8> %y, <2 x i8> undef, <8 x i32> <i32 0, i32 1, i32 undef, i32 undef, i32 undef, i32 undef, i32 undef, i32 undef>1496  %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>1497  ret <8 x i8> %s31498}1499 1500; The last shuffle may change the vector type.1501; Negative test - do not transform non-power-of-2 unless we know the backend handles these sequences identically.1502 1503define <2 x i8> @insert_subvector_shuffles_narrowing(<3 x i8> %x, <3 x i8> %y) {1504; CHECK-LABEL: @insert_subvector_shuffles_narrowing(1505; 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>1506; 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>1507; CHECK-NEXT:    [[S3:%.*]] = shufflevector <7 x i8> [[S1]], <7 x i8> [[S2]], <2 x i32> <i32 0, i32 8>1508; CHECK-NEXT:    ret <2 x i8> [[S3]]1509;1510  %s1 = shufflevector <3 x i8> %x, <3 x i8> undef, <7 x i32> <i32 0, i32 1, i32 undef, i32 undef, i32 undef, i32 undef, i32 undef>1511  %s2 = shufflevector <3 x i8> %y, <3 x i8> undef, <7 x i32> <i32 undef, i32 1, i32 2, i32 undef, i32 undef, i32 undef, i32 undef>1512  %s3 = shufflevector <7 x i8> %s1, <7 x i8> %s2, <2 x i32> <i32 0, i32 8>1513  ret <2 x i8> %s31514}1515 1516define <2 x i8> @insert_subvector_shuffles_narrowing_pow2elts(<4 x i8> %x, <4 x i8> %y) {1517; CHECK-LABEL: @insert_subvector_shuffles_narrowing_pow2elts(1518; CHECK-NEXT:    [[S3:%.*]] = shufflevector <4 x i8> [[X:%.*]], <4 x i8> [[Y:%.*]], <2 x i32> <i32 0, i32 4>1519; CHECK-NEXT:    ret <2 x i8> [[S3]]1520;1521  %s1 = shufflevector <4 x i8> %x, <4 x i8> undef, <8 x i32> <i32 0, i32 1, i32 2, i32 undef, i32 undef, i32 undef, i32 undef, i32 undef>1522  %s2 = shufflevector <4 x i8> %y, <4 x i8> undef, <8 x i32> <i32 0, i32 1, i32 undef, i32 3, i32 undef, i32 undef, i32 undef, i32 undef>1523  %s3 = shufflevector <8 x i8> %s1, <8 x i8> %s2, <2 x i32> <i32 0, i32 8>1524  ret <2 x i8> %s31525}1526 1527; Similar to above, but this reduces to a widen with undefs of 'x'.1528 1529define <4 x double> @insert_subvector_shuffles_identity(<2 x double> %x) {1530; CHECK-LABEL: @insert_subvector_shuffles_identity(1531; CHECK-NEXT:    [[S3:%.*]] = shufflevector <2 x double> [[X:%.*]], <2 x double> poison, <4 x i32> <i32 0, i32 1, i32 poison, i32 poison>1532; CHECK-NEXT:    ret <4 x double> [[S3]]1533;1534  %s1 = shufflevector <2 x double> %x, <2 x double> undef, <4 x i32> <i32 undef, i32 1, i32 undef, i32 undef>1535  %s2 = shufflevector <2 x double> %x, <2 x double> undef, <4 x i32> <i32 0, i32 undef, i32 undef, i32 undef>1536  %s3 = shufflevector <4 x double> %s2, <4 x double> %s1, <4 x i32> <i32 0, i32 5, i32 undef, i32 undef>1537  ret <4 x double> %s31538}1539 1540; Negative test - not identity with padding (although this could be folded with better analysis).1541 1542define <4 x double> @not_insert_subvector_shuffle(<2 x double> %x) {1543; CHECK-LABEL: @not_insert_subvector_shuffle(1544; CHECK-NEXT:    [[S1:%.*]] = shufflevector <2 x double> [[X:%.*]], <2 x double> poison, <4 x i32> <i32 poison, i32 1, i32 poison, i32 1>1545; CHECK-NEXT:    [[S2:%.*]] = shufflevector <2 x double> [[X]], <2 x double> poison, <4 x i32> <i32 0, i32 poison, i32 poison, i32 poison>1546; CHECK-NEXT:    [[S3:%.*]] = shufflevector <4 x double> [[S2]], <4 x double> [[S1]], <4 x i32> <i32 0, i32 5, i32 7, i32 poison>1547; CHECK-NEXT:    ret <4 x double> [[S3]]1548;1549  %s1 = shufflevector <2 x double> %x, <2 x double> undef, <4 x i32> <i32 undef, i32 1, i32 undef, i32 1>1550  %s2 = shufflevector <2 x double> %x, <2 x double> undef, <4 x i32> <i32 0, i32 undef, i32 undef, i32 undef>1551  %s3 = shufflevector <4 x double> %s2, <4 x double> %s1, <4 x i32> <i32 0, i32 5, i32 7, i32 undef>1552  ret <4 x double> %s31553}1554 1555; Negative test - operands are not the same size (although this could be partly folded with better analysis).1556 1557define <4 x double> @not_insert_subvector_shuffles_with_same_size(<2 x double> %x, <3 x double> %y) {1558; CHECK-LABEL: @not_insert_subvector_shuffles_with_same_size(1559; CHECK-NEXT:    [[S1:%.*]] = shufflevector <2 x double> [[X:%.*]], <2 x double> poison, <4 x i32> <i32 poison, i32 1, i32 poison, i32 poison>1560; CHECK-NEXT:    [[S2:%.*]] = shufflevector <3 x double> [[Y:%.*]], <3 x double> poison, <4 x i32> <i32 0, i32 poison, i32 poison, i32 poison>1561; CHECK-NEXT:    [[S3:%.*]] = shufflevector <4 x double> [[S2]], <4 x double> [[S1]], <4 x i32> <i32 0, i32 5, i32 poison, i32 poison>1562; CHECK-NEXT:    ret <4 x double> [[S3]]1563;1564  %s1 = shufflevector <2 x double> %x, <2 x double> undef, <4 x i32> <i32 undef, i32 1, i32 undef, i32 undef>1565  %s2 = shufflevector <3 x double> %y, <3 x double> undef, <4 x i32> <i32 0, i32 undef, i32 undef, i32 undef>1566  %s3 = shufflevector <4 x double> %s2, <4 x double> %s1, <4 x i32> <i32 0, i32 5, i32 undef, i32 undef>1567  ret <4 x double> %s31568}1569 1570; Demanded vector elements may not be able to simplify a shuffle mask1571; before we try to narrow it. This used to crash.1572 1573define <4 x float> @insert_subvector_crash_invalid_mask_elt(<2 x float> %x, ptr %p) {1574; CHECK-LABEL: @insert_subvector_crash_invalid_mask_elt(1575; CHECK-NEXT:    [[WIDEN:%.*]] = shufflevector <2 x float> [[X:%.*]], <2 x float> poison, <4 x i32> <i32 0, i32 1, i32 poison, i32 poison>1576; CHECK-NEXT:    [[I:%.*]] = shufflevector <2 x float> [[X]], <2 x float> poison, <4 x i32> <i32 0, i32 1, i32 poison, i32 poison>1577; CHECK-NEXT:    store <4 x float> [[I]], ptr [[P:%.*]], align 161578; CHECK-NEXT:    ret <4 x float> [[WIDEN]]1579;1580  %widen = shufflevector <2 x float> %x, <2 x float> undef, <4 x i32> <i32 0, i32 1, i32 undef, i32 undef>1581  %ext2 = extractelement <2 x float> %x, i32 01582  %I = insertelement <4 x float> %widen, float %ext2, i16 01583  store <4 x float> %I, ptr %p1584  ret <4 x float> %widen1585}1586 1587define <4 x i32> @splat_assoc_add(<4 x i32> %x, <4 x i32> %y) {1588; CHECK-LABEL: @splat_assoc_add(1589; CHECK-NEXT:    [[TMP1:%.*]] = add <4 x i32> [[X:%.*]], <i32 317426, i32 poison, i32 poison, i32 poison>1590; CHECK-NEXT:    [[TMP2:%.*]] = shufflevector <4 x i32> [[TMP1]], <4 x i32> poison, <4 x i32> zeroinitializer1591; CHECK-NEXT:    [[R:%.*]] = add <4 x i32> [[TMP2]], [[Y:%.*]]1592; CHECK-NEXT:    ret <4 x i32> [[R]]1593;1594  %splatx = shufflevector <4 x i32> %x, <4 x i32> undef, <4 x i32> zeroinitializer1595  %a = add <4 x i32> %y, <i32 317426, i32 317426, i32 317426, i32 317426>1596  %r = add <4 x i32> %splatx, %a1597  ret <4 x i32> %r1598}1599 1600define <vscale x 4 x i32> @vsplat_assoc_add(<vscale x 4 x i32> %x, <vscale x 4 x i32> %y) {1601; CHECK-LABEL: @vsplat_assoc_add(1602; CHECK-NEXT:    [[TMP1:%.*]] = add <vscale x 4 x i32> [[X:%.*]], splat (i32 317426)1603; CHECK-NEXT:    [[TMP2:%.*]] = shufflevector <vscale x 4 x i32> [[TMP1]], <vscale x 4 x i32> poison, <vscale x 4 x i32> zeroinitializer1604; CHECK-NEXT:    [[R:%.*]] = add <vscale x 4 x i32> [[TMP2]], [[Y:%.*]]1605; CHECK-NEXT:    ret <vscale x 4 x i32> [[R]]1606;1607 1608  %splatx = shufflevector <vscale x 4 x i32> %x, <vscale x 4 x i32> undef, <vscale x 4 x i32> zeroinitializer1609  %a = add <vscale x 4 x i32> %y, splat (i32 317426)1610  %r = add <vscale x 4 x i32> %splatx, %a1611  ret <vscale x 4 x i32> %r1612}1613 1614; Undefs in splat mask are replaced with defined splat index1615 1616define <4 x i32> @splat_assoc_add_undef_mask_elts(<4 x i32> %x, <4 x i32> %y) {1617; CHECK-LABEL: @splat_assoc_add_undef_mask_elts(1618; CHECK-NEXT:    [[TMP1:%.*]] = add <4 x i32> [[X:%.*]], <i32 42, i32 poison, i32 poison, i32 poison>1619; CHECK-NEXT:    [[TMP2:%.*]] = shufflevector <4 x i32> [[TMP1]], <4 x i32> poison, <4 x i32> zeroinitializer1620; CHECK-NEXT:    [[R:%.*]] = add <4 x i32> [[TMP2]], [[Y:%.*]]1621; CHECK-NEXT:    ret <4 x i32> [[R]]1622;1623  %splatx = shufflevector <4 x i32> %x, <4 x i32> undef, <4 x i32> <i32 0, i32 0, i32 undef, i32 undef>1624  %a = add <4 x i32> %y, <i32 42, i32 42, i32 42, i32 42>1625  %r = add <4 x i32> %splatx, %a1626  ret <4 x i32> %r1627}1628 1629; Undefs in splat mask are replaced with defined splat index1630 1631define <4 x i32> @splat_assoc_add_undef_mask_elt_at_splat_index(<4 x i32> %x, <4 x i32> %y) {1632; CHECK-LABEL: @splat_assoc_add_undef_mask_elt_at_splat_index(1633; CHECK-NEXT:    [[TMP1:%.*]] = add <4 x i32> [[X:%.*]], <i32 42, i32 poison, i32 poison, i32 poison>1634; CHECK-NEXT:    [[TMP2:%.*]] = shufflevector <4 x i32> [[TMP1]], <4 x i32> poison, <4 x i32> zeroinitializer1635; CHECK-NEXT:    [[R:%.*]] = add <4 x i32> [[TMP2]], [[Y:%.*]]1636; CHECK-NEXT:    ret <4 x i32> [[R]]1637;1638  %splatx = shufflevector <4 x i32> %x, <4 x i32> undef, <4 x i32> <i32 undef, i32 0, i32 0, i32 0>1639  %a = add <4 x i32> %y, <i32 42, i32 42, i32 42, i32 42>1640  %r = add <4 x i32> %splatx, %a1641  ret <4 x i32> %r1642}1643 1644define <4 x i32> @splat_assoc_add_undef_constant_elts(<4 x i32> %x, <4 x i32> %y) {1645; CHECK-LABEL: @splat_assoc_add_undef_constant_elts(1646; CHECK-NEXT:    [[SPLATX:%.*]] = shufflevector <4 x i32> [[X:%.*]], <4 x i32> poison, <4 x i32> zeroinitializer1647; CHECK-NEXT:    [[A:%.*]] = add <4 x i32> [[Y:%.*]], <i32 42, i32 undef, i32 undef, i32 42>1648; CHECK-NEXT:    [[R:%.*]] = add <4 x i32> [[SPLATX]], [[A]]1649; CHECK-NEXT:    ret <4 x i32> [[R]]1650;1651  %splatx = shufflevector <4 x i32> %x, <4 x i32> undef, <4 x i32> zeroinitializer1652  %a = add <4 x i32> %y, <i32 42, i32 undef, i32 undef, i32 42>1653  %r = add <4 x i32> %splatx, %a1654  ret <4 x i32> %r1655}1656 1657define <4 x i32> @splat_assoc_add_undef_constant_elt_at_splat_index(<4 x i32> %x, <4 x i32> %y) {1658; CHECK-LABEL: @splat_assoc_add_undef_constant_elt_at_splat_index(1659; CHECK-NEXT:    [[SPLATX:%.*]] = shufflevector <4 x i32> [[X:%.*]], <4 x i32> poison, <4 x i32> zeroinitializer1660; CHECK-NEXT:    [[A:%.*]] = add <4 x i32> [[Y:%.*]], <i32 undef, i32 42, i32 undef, i32 42>1661; CHECK-NEXT:    [[R:%.*]] = add <4 x i32> [[SPLATX]], [[A]]1662; CHECK-NEXT:    ret <4 x i32> [[R]]1663;1664  %splatx = shufflevector <4 x i32> %x, <4 x i32> undef, <4 x i32> zeroinitializer1665  %a = add <4 x i32> %y, <i32 undef, i32 42, i32 undef, i32 42>1666  %r = add <4 x i32> %splatx, %a1667  ret <4 x i32> %r1668}1669 1670define <4 x i32> @splat_assoc_add_undef_mask_elts_undef_constant_elts(<4 x i32> %x, <4 x i32> %y) {1671; CHECK-LABEL: @splat_assoc_add_undef_mask_elts_undef_constant_elts(1672; CHECK-NEXT:    [[SPLATX:%.*]] = shufflevector <4 x i32> [[X:%.*]], <4 x i32> poison, <4 x i32> <i32 0, i32 poison, i32 0, i32 poison>1673; CHECK-NEXT:    [[A:%.*]] = add <4 x i32> [[Y:%.*]], <i32 42, i32 undef, i32 undef, i32 42>1674; CHECK-NEXT:    [[R:%.*]] = add <4 x i32> [[SPLATX]], [[A]]1675; CHECK-NEXT:    ret <4 x i32> [[R]]1676;1677  %splatx = shufflevector <4 x i32> %x, <4 x i32> undef, <4 x i32> <i32 0, i32 undef, i32 0, i32 undef>1678  %a = add <4 x i32> %y, <i32 42, i32 undef, i32 undef, i32 42>1679  %r = add <4 x i32> %splatx, %a1680  ret <4 x i32> %r1681}1682 1683define <4 x i32> @splat_assoc_add_undef_mask_elt_at_splat_index_undef_constant_elts(<4 x i32> %x, <4 x i32> %y) {1684; CHECK-LABEL: @splat_assoc_add_undef_mask_elt_at_splat_index_undef_constant_elts(1685; CHECK-NEXT:    [[SPLATX:%.*]] = shufflevector <4 x i32> [[X:%.*]], <4 x i32> poison, <4 x i32> <i32 poison, i32 0, i32 0, i32 0>1686; CHECK-NEXT:    [[A:%.*]] = add <4 x i32> [[Y:%.*]], <i32 42, i32 undef, i32 undef, i32 42>1687; CHECK-NEXT:    [[R:%.*]] = add <4 x i32> [[SPLATX]], [[A]]1688; CHECK-NEXT:    ret <4 x i32> [[R]]1689;1690  %splatx = shufflevector <4 x i32> %x, <4 x i32> undef, <4 x i32> <i32 undef, i32 0, i32 0, i32 0>1691  %a = add <4 x i32> %y, <i32 42, i32 undef, i32 undef, i32 42>1692  %r = add <4 x i32> %splatx, %a1693  ret <4 x i32> %r1694}1695 1696define <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) {1697; CHECK-LABEL: @splat_assoc_add_undef_mask_elt_at_splat_index_undef_constant_elt_at_splat_index(1698; CHECK-NEXT:    [[SPLATX:%.*]] = shufflevector <4 x i32> [[X:%.*]], <4 x i32> poison, <4 x i32> <i32 poison, i32 0, i32 0, i32 0>1699; CHECK-NEXT:    [[A:%.*]] = add <4 x i32> [[Y:%.*]], <i32 undef, i32 42, i32 undef, i32 42>1700; CHECK-NEXT:    [[R:%.*]] = add <4 x i32> [[SPLATX]], [[A]]1701; CHECK-NEXT:    ret <4 x i32> [[R]]1702;1703  %splatx = shufflevector <4 x i32> %x, <4 x i32> undef, <4 x i32> <i32 undef, i32 0, i32 0, i32 0>1704  %a = add <4 x i32> %y, <i32 undef, i32 42, i32 undef, i32 42>1705  %r = add <4 x i32> %splatx, %a1706  ret <4 x i32> %r1707}1708 1709; Non-zero splat index; commute operands; FMF intersect1710 1711define <2 x float> @splat_assoc_fmul(<2 x float> %x, <2 x float> %y) {1712; CHECK-LABEL: @splat_assoc_fmul(1713; CHECK-NEXT:    [[TMP1:%.*]] = fmul reassoc nsz <2 x float> [[X:%.*]], <float poison, float 3.000000e+00>1714; CHECK-NEXT:    [[TMP2:%.*]] = shufflevector <2 x float> [[TMP1]], <2 x float> poison, <2 x i32> <i32 1, i32 1>1715; CHECK-NEXT:    [[R:%.*]] = fmul reassoc nsz <2 x float> [[TMP2]], [[Y:%.*]]1716; CHECK-NEXT:    ret <2 x float> [[R]]1717;1718  %splatx = shufflevector <2 x float> %x, <2 x float> undef, <2 x i32> <i32 1, i32 1>1719  %a = fmul reassoc nsz <2 x float> %y, <float 3.0, float 3.0>1720  %r = fmul reassoc nsz nnan <2 x float> %a, %splatx1721  ret <2 x float> %r1722}1723 1724; Two splat shuffles; drop poison-generating flags1725 1726define <3 x i8> @splat_assoc_mul(<3 x i8> %x, <3 x i8> %y, <3 x i8> %z) {1727; CHECK-LABEL: @splat_assoc_mul(1728; CHECK-NEXT:    [[TMP1:%.*]] = mul <3 x i8> [[X:%.*]], [[Z:%.*]]1729; CHECK-NEXT:    [[TMP2:%.*]] = shufflevector <3 x i8> [[TMP1]], <3 x i8> poison, <3 x i32> <i32 2, i32 2, i32 2>1730; CHECK-NEXT:    [[R:%.*]] = mul <3 x i8> [[TMP2]], [[Y:%.*]]1731; CHECK-NEXT:    ret <3 x i8> [[R]]1732;1733  %splatx = shufflevector <3 x i8> %x, <3 x i8> undef, <3 x i32> <i32 2, i32 2, i32 2>1734  %splatz = shufflevector <3 x i8> %z, <3 x i8> undef, <3 x i32> <i32 2, i32 2, i32 2>1735  %a = mul nsw <3 x i8> %y, %splatz1736  %r = mul <3 x i8> %a, %splatx1737  ret <3 x i8> %r1738}1739 1740define <3 x i8> @splat_assoc_mul_undef_elt1(<3 x i8> %x, <3 x i8> %y, <3 x i8> %z) {1741; CHECK-LABEL: @splat_assoc_mul_undef_elt1(1742; CHECK-NEXT:    [[TMP1:%.*]] = mul <3 x i8> [[X:%.*]], [[Z:%.*]]1743; CHECK-NEXT:    [[TMP2:%.*]] = shufflevector <3 x i8> [[TMP1]], <3 x i8> poison, <3 x i32> <i32 2, i32 2, i32 2>1744; CHECK-NEXT:    [[R:%.*]] = mul <3 x i8> [[TMP2]], [[Y:%.*]]1745; CHECK-NEXT:    ret <3 x i8> [[R]]1746;1747  %splatx = shufflevector <3 x i8> %x, <3 x i8> undef, <3 x i32> <i32 undef, i32 2, i32 2>1748  %splatz = shufflevector <3 x i8> %z, <3 x i8> undef, <3 x i32> <i32 2, i32 2, i32 2>1749  %a = mul nsw <3 x i8> %y, %splatz1750  %r = mul nsw nuw <3 x i8> %a, %splatx1751  ret <3 x i8> %r1752}1753 1754define <3 x i8> @splat_assoc_mul_undef_elt2(<3 x i8> %x, <3 x i8> %y, <3 x i8> %z) {1755; CHECK-LABEL: @splat_assoc_mul_undef_elt2(1756; CHECK-NEXT:    [[SPLATX:%.*]] = shufflevector <3 x i8> [[X:%.*]], <3 x i8> poison, <3 x i32> <i32 2, i32 2, i32 2>1757; CHECK-NEXT:    [[SPLATZ:%.*]] = shufflevector <3 x i8> [[Z:%.*]], <3 x i8> poison, <3 x i32> <i32 poison, i32 2, i32 2>1758; CHECK-NEXT:    [[A:%.*]] = mul nsw <3 x i8> [[Y:%.*]], [[SPLATZ]]1759; CHECK-NEXT:    [[R:%.*]] = mul nuw nsw <3 x i8> [[A]], [[SPLATX]]1760; CHECK-NEXT:    ret <3 x i8> [[R]]1761;1762  %splatx = shufflevector <3 x i8> %x, <3 x i8> undef, <3 x i32> <i32 2, i32 2, i32 2>1763  %splatz = shufflevector <3 x i8> %z, <3 x i8> undef, <3 x i32> <i32 undef, i32 2, i32 2>1764  %a = mul nsw <3 x i8> %y, %splatz1765  %r = mul nsw nuw <3 x i8> %a, %splatx1766  ret <3 x i8> %r1767}1768 1769define <3 x i8> @splat_assoc_mul_undef_elt_at_splat_index1(<3 x i8> %x, <3 x i8> %y, <3 x i8> %z) {1770; CHECK-LABEL: @splat_assoc_mul_undef_elt_at_splat_index1(1771; CHECK-NEXT:    [[TMP1:%.*]] = mul <3 x i8> [[X:%.*]], [[Z:%.*]]1772; CHECK-NEXT:    [[TMP2:%.*]] = shufflevector <3 x i8> [[TMP1]], <3 x i8> poison, <3 x i32> <i32 2, i32 2, i32 2>1773; CHECK-NEXT:    [[R:%.*]] = mul <3 x i8> [[TMP2]], [[Y:%.*]]1774; CHECK-NEXT:    ret <3 x i8> [[R]]1775;1776  %splatx = shufflevector <3 x i8> %x, <3 x i8> undef, <3 x i32> <i32 2, i32 2, i32 undef>1777  %splatz = shufflevector <3 x i8> %z, <3 x i8> undef, <3 x i32> <i32 2, i32 2, i32 2>1778  %a = mul nsw <3 x i8> %y, %splatz1779  %r = mul nsw nuw <3 x i8> %a, %splatx1780  ret <3 x i8> %r1781}1782 1783define <3 x i8> @splat_assoc_mul_undef_elt_at_splat_index2(<3 x i8> %x, <3 x i8> %y, <3 x i8> %z) {1784; CHECK-LABEL: @splat_assoc_mul_undef_elt_at_splat_index2(1785; CHECK-NEXT:    [[SPLATX:%.*]] = shufflevector <3 x i8> [[X:%.*]], <3 x i8> poison, <3 x i32> <i32 2, i32 2, i32 2>1786; CHECK-NEXT:    [[SPLATZ:%.*]] = shufflevector <3 x i8> [[Z:%.*]], <3 x i8> poison, <3 x i32> <i32 2, i32 2, i32 poison>1787; CHECK-NEXT:    [[A:%.*]] = mul nsw <3 x i8> [[Y:%.*]], [[SPLATZ]]1788; CHECK-NEXT:    [[R:%.*]] = mul nuw nsw <3 x i8> [[A]], [[SPLATX]]1789; CHECK-NEXT:    ret <3 x i8> [[R]]1790;1791  %splatx = shufflevector <3 x i8> %x, <3 x i8> undef, <3 x i32> <i32 2, i32 2, i32 2>1792  %splatz = shufflevector <3 x i8> %z, <3 x i8> undef, <3 x i32> <i32 2, i32 2, i32 undef>1793  %a = mul nsw <3 x i8> %y, %splatz1794  %r = mul nsw nuw <3 x i8> %a, %splatx1795  ret <3 x i8> %r1796}1797 1798; Negative test - mismatched splat elements1799 1800define <3 x i8> @splat_assoc_or(<3 x i8> %x, <3 x i8> %y, <3 x i8> %z) {1801; CHECK-LABEL: @splat_assoc_or(1802; CHECK-NEXT:    [[SPLATX:%.*]] = shufflevector <3 x i8> [[X:%.*]], <3 x i8> poison, <3 x i32> <i32 1, i32 1, i32 1>1803; CHECK-NEXT:    [[SPLATZ:%.*]] = shufflevector <3 x i8> [[Z:%.*]], <3 x i8> poison, <3 x i32> <i32 2, i32 2, i32 2>1804; CHECK-NEXT:    [[A:%.*]] = or <3 x i8> [[Y:%.*]], [[SPLATZ]]1805; CHECK-NEXT:    [[R:%.*]] = or <3 x i8> [[A]], [[SPLATX]]1806; CHECK-NEXT:    ret <3 x i8> [[R]]1807;1808  %splatx = shufflevector <3 x i8> %x, <3 x i8> undef, <3 x i32> <i32 1, i32 1, i32 1>1809  %splatz = shufflevector <3 x i8> %z, <3 x i8> undef, <3 x i32> <i32 2, i32 2, i32 2>1810  %a = or <3 x i8> %y, %splatz1811  %r = or <3 x i8> %a, %splatx1812  ret <3 x i8> %r1813}1814 1815; Negative test - not associative1816 1817define <2 x float> @splat_assoc_fdiv(<2 x float> %x, <2 x float> %y) {1818; CHECK-LABEL: @splat_assoc_fdiv(1819; CHECK-NEXT:    [[SPLATX:%.*]] = shufflevector <2 x float> [[X:%.*]], <2 x float> poison, <2 x i32> zeroinitializer1820; CHECK-NEXT:    [[A:%.*]] = fdiv reassoc nsz <2 x float> [[Y:%.*]], splat (float 3.000000e+00)1821; CHECK-NEXT:    [[R:%.*]] = fdiv reassoc nsz <2 x float> [[A]], [[SPLATX]]1822; CHECK-NEXT:    ret <2 x float> [[R]]1823;1824  %splatx = shufflevector <2 x float> %x, <2 x float> undef, <2 x i32> zeroinitializer1825  %a = fdiv reassoc nsz <2 x float> %y, <float 3.0, float 3.0>1826  %r = fdiv reassoc nsz <2 x float> %a, %splatx1827  ret <2 x float> %r1828}1829 1830; Negative test - extra use1831 1832define <2 x float> @splat_assoc_fadd(<2 x float> %x, <2 x float> %y) {1833; CHECK-LABEL: @splat_assoc_fadd(1834; CHECK-NEXT:    [[SPLATX:%.*]] = shufflevector <2 x float> [[X:%.*]], <2 x float> poison, <2 x i32> <i32 1, i32 1>1835; CHECK-NEXT:    [[A:%.*]] = fadd fast <2 x float> [[Y:%.*]], splat (float 3.000000e+00)1836; CHECK-NEXT:    call void @use(<2 x float> [[A]])1837; CHECK-NEXT:    [[R:%.*]] = fadd fast <2 x float> [[A]], [[SPLATX]]1838; CHECK-NEXT:    ret <2 x float> [[R]]1839;1840  %splatx = shufflevector <2 x float> %x, <2 x float> undef, <2 x i32> <i32 1, i32 1>1841  %a = fadd fast <2 x float> %y, <float 3.0, float 3.0>1842  call void @use(<2 x float> %a)1843  %r = fadd fast <2 x float> %a, %splatx1844  ret <2 x float> %r1845}1846 1847; Negative test - narrowing splat1848 1849define <3 x i32> @splat_assoc_and(<4 x i32> %x, <3 x i32> %y) {1850; CHECK-LABEL: @splat_assoc_and(1851; CHECK-NEXT:    [[SPLATX:%.*]] = shufflevector <4 x i32> [[X:%.*]], <4 x i32> poison, <3 x i32> zeroinitializer1852; CHECK-NEXT:    [[A:%.*]] = and <3 x i32> [[Y:%.*]], splat (i32 42)1853; CHECK-NEXT:    [[R:%.*]] = and <3 x i32> [[SPLATX]], [[A]]1854; CHECK-NEXT:    ret <3 x i32> [[R]]1855;1856  %splatx = shufflevector <4 x i32> %x, <4 x i32> undef, <3 x i32> zeroinitializer1857  %a = and <3 x i32> %y, <i32 42, i32 42, i32 42>1858  %r = and <3 x i32> %splatx, %a1859  ret <3 x i32> %r1860}1861 1862; Negative test - widening splat1863 1864define <5 x i32> @splat_assoc_xor(<4 x i32> %x, <5 x i32> %y) {1865; CHECK-LABEL: @splat_assoc_xor(1866; CHECK-NEXT:    [[SPLATX:%.*]] = shufflevector <4 x i32> [[X:%.*]], <4 x i32> poison, <5 x i32> zeroinitializer1867; CHECK-NEXT:    [[TMP1:%.*]] = xor <5 x i32> [[Y:%.*]], [[SPLATX]]1868; CHECK-NEXT:    [[R:%.*]] = xor <5 x i32> [[TMP1]], splat (i32 42)1869; CHECK-NEXT:    ret <5 x i32> [[R]]1870;1871  %splatx = shufflevector <4 x i32> %x, <4 x i32> undef, <5 x i32> zeroinitializer1872  %a = xor <5 x i32> %y, <i32 42, i32 42, i32 42, i32 42, i32 42>1873  %r = xor <5 x i32> %splatx, %a1874  ret <5 x i32> %r1875}1876 1877; Negative test - opcode mismatch1878 1879define <4 x i32> @splat_assoc_add_mul(<4 x i32> %x, <4 x i32> %y) {1880; CHECK-LABEL: @splat_assoc_add_mul(1881; CHECK-NEXT:    [[SPLATX:%.*]] = shufflevector <4 x i32> [[X:%.*]], <4 x i32> poison, <4 x i32> zeroinitializer1882; CHECK-NEXT:    [[A:%.*]] = add <4 x i32> [[Y:%.*]], splat (i32 42)1883; CHECK-NEXT:    [[R:%.*]] = mul <4 x i32> [[SPLATX]], [[A]]1884; CHECK-NEXT:    ret <4 x i32> [[R]]1885;1886  %splatx = shufflevector <4 x i32> %x, <4 x i32> undef, <4 x i32> zeroinitializer1887  %a = add <4 x i32> %y, <i32 42, i32 42, i32 42, i32 42>1888  %r = mul <4 x i32> %splatx, %a1889  ret <4 x i32> %r1890}1891 1892 1893; Do not crash on constant expressions.1894 1895define <4 x i32> @PR46872(<4 x i32> %x) {1896; CHECK-LABEL: @PR46872(1897; CHECK-NEXT:    [[S:%.*]] = shufflevector <4 x i32> [[X:%.*]], <4 x i32> poison, <4 x i32> <i32 poison, i32 0, i32 1, i32 1>1898; 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>)1899; CHECK-NEXT:    ret <4 x i32> [[A]]1900;1901  %s = shufflevector <4 x i32> %x, <4 x i32> undef, <4 x i32> <i32 undef, i32 0, i32 1, i32 1>1902  %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>)1903  ret <4 x i32> %a1904}1905 1906define <2 x float> @fabs_unary_shuf(<2 x float> %x) {1907; CHECK-LABEL: @fabs_unary_shuf(1908; CHECK-NEXT:    [[R:%.*]] = call nnan nsz <2 x float> @llvm.fabs.v2f32(<2 x float> [[TMP1:%.*]])1909; CHECK-NEXT:    [[R1:%.*]] = shufflevector <2 x float> [[R]], <2 x float> poison, <2 x i32> <i32 1, i32 0>1910; CHECK-NEXT:    ret <2 x float> [[R1]]1911;1912  %nx = call nsz nnan <2 x float> @llvm.fabs.v2f32(<2 x float> %x)1913  %r = shufflevector <2 x float> %nx, <2 x float> poison, <2 x i32> <i32 1, i32 0>1914  ret <2 x float> %r1915}1916 1917define <4 x half> @fabs_unary_shuf_widen(<2 x half> %x) {1918; CHECK-LABEL: @fabs_unary_shuf_widen(1919; CHECK-NEXT:    [[X:%.*]] = call ninf <2 x half> @llvm.fabs.v2f16(<2 x half> [[X1:%.*]])1920; CHECK-NEXT:    [[TMP1:%.*]] = shufflevector <2 x half> [[X]], <2 x half> poison, <4 x i32> <i32 1, i32 0, i32 0, i32 poison>1921; CHECK-NEXT:    ret <4 x half> [[TMP1]]1922;1923  %nx = call ninf <2 x half> @llvm.fabs.v2f16(<2 x half> %x)1924  %r = shufflevector <2 x half> %nx, <2 x half> poison, <4 x i32> <i32 1, i32 0, i32 0, i32 poison>1925  ret <4 x half> %r1926}1927 1928define <2 x double> @fabs_unary_shuf_narrow(<4 x double> %x) {1929; CHECK-LABEL: @fabs_unary_shuf_narrow(1930; CHECK-NEXT:    [[X:%.*]] = call nsz <4 x double> @llvm.fabs.v4f64(<4 x double> [[X1:%.*]])1931; CHECK-NEXT:    [[TMP1:%.*]] = shufflevector <4 x double> [[X]], <4 x double> poison, <2 x i32> <i32 3, i32 0>1932; CHECK-NEXT:    ret <2 x double> [[TMP1]]1933;1934  %nx = call nsz <4 x double> @llvm.fabs.v4f64(<4 x double> %x)1935  %r = shufflevector <4 x double> %nx, <4 x double> poison, <2 x i32> <i32 3, i32 0>1936  ret <2 x double> %r1937}1938 1939; negative test - extra use prevents canonicalization1940 1941define <2 x float> @fabs_unary_shuf_use(<2 x float> %x) {1942; CHECK-LABEL: @fabs_unary_shuf_use(1943; CHECK-NEXT:    [[NX:%.*]] = call nsz <2 x float> @llvm.fabs.v2f32(<2 x float> [[X:%.*]])1944; CHECK-NEXT:    call void @use(<2 x float> [[NX]])1945; CHECK-NEXT:    [[R:%.*]] = shufflevector <2 x float> [[NX]], <2 x float> poison, <2 x i32> <i32 poison, i32 0>1946; CHECK-NEXT:    ret <2 x float> [[R]]1947;1948  %nx = call nsz <2 x float> @llvm.fabs.v2f32(<2 x float> %x)1949  call void @use(<2 x float> %nx)1950  %r = shufflevector <2 x float> %nx, <2 x float> poison, <2 x i32> <i32 3, i32 0>1951  ret <2 x float> %r1952}1953 1954; intersect FMF1955 1956define <4 x float> @fabs_shuf(<4 x float> %x, <4 x float> %y) {1957; CHECK-LABEL: @fabs_shuf(1958; CHECK-NEXT:    [[TMP1:%.*]] = shufflevector <4 x float> [[X:%.*]], <4 x float> [[Y:%.*]], <4 x i32> <i32 0, i32 1, i32 4, i32 5>1959; CHECK-NEXT:    [[R:%.*]] = call ninf <4 x float> @llvm.fabs.v4f32(<4 x float> [[TMP1]])1960; CHECK-NEXT:    ret <4 x float> [[R]]1961;1962  %nx = call nsz ninf <4 x float> @llvm.fabs.v4f32(<4 x float> %x)1963  %ny = call nnan ninf <4 x float> @llvm.fabs.v4f32(<4 x float> %y)1964  %r = shufflevector <4 x float> %nx, <4 x float> %ny, <4 x i32> <i32 0, i32 1, i32 4, i32 5>1965  ret <4 x float> %r1966}1967 1968; length-changing shuffle and extra use are ok1969 1970define <4 x float> @fabs_shuf_widen_use1(<2 x float> %x, <2 x float> %y) {1971; CHECK-LABEL: @fabs_shuf_widen_use1(1972; CHECK-NEXT:    [[NX:%.*]] = call nnan <2 x float> @llvm.fabs.v2f32(<2 x float> [[X:%.*]])1973; CHECK-NEXT:    call void @use(<2 x float> [[NX]])1974; CHECK-NEXT:    [[TMP1:%.*]] = shufflevector <2 x float> [[X]], <2 x float> [[Y:%.*]], <4 x i32> <i32 poison, i32 1, i32 2, i32 3>1975; CHECK-NEXT:    [[R:%.*]] = call nnan <4 x float> @llvm.fabs.v4f32(<4 x float> [[TMP1]])1976; CHECK-NEXT:    ret <4 x float> [[R]]1977;1978  %nx = call nnan <2 x float> @llvm.fabs.v2f32(<2 x float> %x)1979  call void @use(<2 x float> %nx)1980  %ny = call nnan <2 x float> @llvm.fabs.v2f32(<2 x float> %y)1981  %r = shufflevector <2 x float> %nx, <2 x float> %ny, <4 x i32> <i32 poison, i32 1, i32 2, i32 3>1982  ret <4 x float> %r1983}1984 1985; length-changing shuffle and extra use are ok1986 1987define <2 x float> @fabs_shuf_narrow_use2(<4 x float> %x, <4 x float> %y) {1988; CHECK-LABEL: @fabs_shuf_narrow_use2(1989; CHECK-NEXT:    [[NY:%.*]] = call nnan nsz <4 x float> @llvm.fabs.v4f32(<4 x float> [[Y:%.*]])1990; CHECK-NEXT:    call void @use4(<4 x float> [[NY]])1991; CHECK-NEXT:    [[TMP1:%.*]] = shufflevector <4 x float> [[X:%.*]], <4 x float> [[Y]], <2 x i32> <i32 3, i32 5>1992; CHECK-NEXT:    [[R:%.*]] = call nnan nsz <2 x float> @llvm.fabs.v2f32(<2 x float> [[TMP1]])1993; CHECK-NEXT:    ret <2 x float> [[R]]1994;1995  %nx = call nsz nnan <4 x float> @llvm.fabs.v4f32(<4 x float> %x)1996  %ny = call nsz nnan <4 x float> @llvm.fabs.v4f32(<4 x float> %y)1997  call void @use4(<4 x float> %ny)1998  %r = shufflevector <4 x float> %nx, <4 x float> %ny, <2 x i32> <i32 3, i32 5>1999  ret <2 x float> %r2000}2001 2002; negative test - too many extra uses2003 2004define <2 x float> @fabs_shuf_use3(<2 x float> %x, <2 x float> %y) {2005; CHECK-LABEL: @fabs_shuf_use3(2006; CHECK-NEXT:    [[NX:%.*]] = call nnan <2 x float> @llvm.fabs.v2f32(<2 x float> [[X:%.*]])2007; CHECK-NEXT:    call void @use(<2 x float> [[NX]])2008; CHECK-NEXT:    [[NY:%.*]] = call nnan <2 x float> @llvm.fabs.v2f32(<2 x float> [[Y:%.*]])2009; CHECK-NEXT:    call void @use(<2 x float> [[NY]])2010; CHECK-NEXT:    [[R:%.*]] = shufflevector <2 x float> [[NX]], <2 x float> [[NY]], <2 x i32> <i32 1, i32 2>2011; CHECK-NEXT:    ret <2 x float> [[R]]2012;2013  %nx = call nnan <2 x float> @llvm.fabs.v2f32(<2 x float> %x)2014  call void @use(<2 x float> %nx)2015  %ny = call nnan <2 x float> @llvm.fabs.v2f32(<2 x float> %y)2016  call void @use(<2 x float> %ny)2017  %r = shufflevector <2 x float> %nx, <2 x float> %ny, <2 x i32> <i32 1, i32 2>2018  ret <2 x float> %r2019}2020 2021define <2 x float> @fneg_unary_shuf(<2 x float> %x) {2022; CHECK-LABEL: @fneg_unary_shuf(2023; CHECK-NEXT:    [[R:%.*]] = fneg nnan nsz <2 x float> [[TMP1:%.*]]2024; CHECK-NEXT:    [[R1:%.*]] = shufflevector <2 x float> [[R]], <2 x float> poison, <2 x i32> <i32 1, i32 0>2025; CHECK-NEXT:    ret <2 x float> [[R1]]2026;2027  %nx = fneg nsz nnan <2 x float> %x2028  %r = shufflevector <2 x float> %nx, <2 x float> poison, <2 x i32> <i32 1, i32 0>2029  ret <2 x float> %r2030}2031 2032define <4 x half> @fneg_unary_shuf_widen(<2 x half> %x) {2033; CHECK-LABEL: @fneg_unary_shuf_widen(2034; CHECK-NEXT:    [[X:%.*]] = fneg ninf <2 x half> [[X1:%.*]]2035; CHECK-NEXT:    [[TMP1:%.*]] = shufflevector <2 x half> [[X]], <2 x half> poison, <4 x i32> <i32 1, i32 0, i32 0, i32 poison>2036; CHECK-NEXT:    ret <4 x half> [[TMP1]]2037;2038  %nx = fneg ninf <2 x half> %x2039  %r = shufflevector <2 x half> %nx, <2 x half> poison, <4 x i32> <i32 1, i32 0, i32 0, i32 poison>2040  ret <4 x half> %r2041}2042 2043define <2 x double> @fneg_unary_shuf_narrow(<4 x double> %x) {2044; CHECK-LABEL: @fneg_unary_shuf_narrow(2045; CHECK-NEXT:    [[X:%.*]] = fneg nsz <4 x double> [[X1:%.*]]2046; CHECK-NEXT:    [[TMP1:%.*]] = shufflevector <4 x double> [[X]], <4 x double> poison, <2 x i32> <i32 3, i32 0>2047; CHECK-NEXT:    ret <2 x double> [[TMP1]]2048;2049  %nx = fneg nsz <4 x double> %x2050  %r = shufflevector <4 x double> %nx, <4 x double> poison, <2 x i32> <i32 3, i32 0>2051  ret <2 x double> %r2052}2053 2054; negative test - extra use prevents canonicalization2055 2056define <2 x float> @fneg_unary_shuf_use(<2 x float> %x) {2057; CHECK-LABEL: @fneg_unary_shuf_use(2058; CHECK-NEXT:    [[NX:%.*]] = fneg nsz <2 x float> [[X:%.*]]2059; CHECK-NEXT:    call void @use(<2 x float> [[NX]])2060; CHECK-NEXT:    [[R:%.*]] = shufflevector <2 x float> [[NX]], <2 x float> poison, <2 x i32> <i32 poison, i32 0>2061; CHECK-NEXT:    ret <2 x float> [[R]]2062;2063  %nx = fneg nsz <2 x float> %x2064  call void @use(<2 x float> %nx)2065  %r = shufflevector <2 x float> %nx, <2 x float> poison, <2 x i32> <i32 3, i32 0>2066  ret <2 x float> %r2067}2068 2069; intersect FMF2070 2071define <4 x float> @fneg_shuf(<4 x float> %x, <4 x float> %y) {2072; CHECK-LABEL: @fneg_shuf(2073; CHECK-NEXT:    [[TMP1:%.*]] = shufflevector <4 x float> [[X:%.*]], <4 x float> [[Y:%.*]], <4 x i32> <i32 0, i32 1, i32 4, i32 5>2074; CHECK-NEXT:    [[R:%.*]] = fneg ninf <4 x float> [[TMP1]]2075; CHECK-NEXT:    ret <4 x float> [[R]]2076;2077  %nx = fneg nsz ninf <4 x float> %x2078  %ny = fneg nnan ninf <4 x float> %y2079  %r = shufflevector <4 x float> %nx, <4 x float> %ny, <4 x i32> <i32 0, i32 1, i32 4, i32 5>2080  ret <4 x float> %r2081}2082 2083; length-changing shuffle and extra use are ok2084 2085define <4 x float> @fneg_shuf_widen_use1(<2 x float> %x, <2 x float> %y) {2086; CHECK-LABEL: @fneg_shuf_widen_use1(2087; CHECK-NEXT:    [[NX:%.*]] = fneg nnan <2 x float> [[X:%.*]]2088; CHECK-NEXT:    call void @use(<2 x float> [[NX]])2089; CHECK-NEXT:    [[TMP1:%.*]] = shufflevector <2 x float> [[X]], <2 x float> [[Y:%.*]], <4 x i32> <i32 poison, i32 1, i32 2, i32 3>2090; CHECK-NEXT:    [[R:%.*]] = fneg nnan <4 x float> [[TMP1]]2091; CHECK-NEXT:    ret <4 x float> [[R]]2092;2093  %nx = fneg nnan <2 x float> %x2094  call void @use(<2 x float> %nx)2095  %ny = fneg nnan <2 x float> %y2096  %r = shufflevector <2 x float> %nx, <2 x float> %ny, <4 x i32> <i32 poison, i32 1, i32 2, i32 3>2097  ret <4 x float> %r2098}2099 2100; length-changing shuffle and extra use still ok2101 2102define <2 x float> @fneg_shuf_narrow_use2(<4 x float> %x, <4 x float> %y) {2103; CHECK-LABEL: @fneg_shuf_narrow_use2(2104; CHECK-NEXT:    [[NY:%.*]] = fneg nnan nsz <4 x float> [[Y:%.*]]2105; CHECK-NEXT:    call void @use4(<4 x float> [[NY]])2106; CHECK-NEXT:    [[TMP1:%.*]] = shufflevector <4 x float> [[X:%.*]], <4 x float> [[Y]], <2 x i32> <i32 3, i32 5>2107; CHECK-NEXT:    [[R:%.*]] = fneg nnan nsz <2 x float> [[TMP1]]2108; CHECK-NEXT:    ret <2 x float> [[R]]2109;2110  %nx = fneg nsz nnan <4 x float> %x2111  %ny = fneg nsz nnan <4 x float> %y2112  call void @use4(<4 x float> %ny)2113  %r = shufflevector <4 x float> %nx, <4 x float> %ny, <2 x i32> <i32 3, i32 5>2114  ret <2 x float> %r2115}2116 2117; negative test - too many extra uses2118 2119define <2 x float> @fneg_shuf_use3(<2 x float> %x, <2 x float> %y) {2120; CHECK-LABEL: @fneg_shuf_use3(2121; CHECK-NEXT:    [[NX:%.*]] = fneg nnan <2 x float> [[X:%.*]]2122; CHECK-NEXT:    call void @use(<2 x float> [[NX]])2123; CHECK-NEXT:    [[NY:%.*]] = fneg nnan <2 x float> [[Y:%.*]]2124; CHECK-NEXT:    call void @use(<2 x float> [[NY]])2125; CHECK-NEXT:    [[R:%.*]] = shufflevector <2 x float> [[NX]], <2 x float> [[NY]], <2 x i32> <i32 1, i32 2>2126; CHECK-NEXT:    ret <2 x float> [[R]]2127;2128  %nx = fneg nnan <2 x float> %x2129  call void @use(<2 x float> %nx)2130  %ny = fneg nnan <2 x float> %y2131  call void @use(<2 x float> %ny)2132  %r = shufflevector <2 x float> %nx, <2 x float> %ny, <2 x i32> <i32 1, i32 2>2133  ret <2 x float> %r2134}2135 2136; negative test - mixed opcodes2137 2138define <4 x float> @fabs_fneg_shuf(<4 x float> %x, <4 x float> %y) {2139; CHECK-LABEL: @fabs_fneg_shuf(2140; CHECK-NEXT:    [[NX:%.*]] = call <4 x float> @llvm.fabs.v4f32(<4 x float> [[X:%.*]])2141; CHECK-NEXT:    [[NY:%.*]] = fneg nnan ninf <4 x float> [[Y:%.*]]2142; CHECK-NEXT:    [[R:%.*]] = shufflevector <4 x float> [[NX]], <4 x float> [[NY]], <4 x i32> <i32 0, i32 1, i32 4, i32 5>2143; CHECK-NEXT:    ret <4 x float> [[R]]2144;2145  %nx = call <4 x float> @llvm.fabs.v4f32(<4 x float> %x)2146  %ny = fneg nnan ninf <4 x float> %y2147  %r = shufflevector <4 x float> %nx, <4 x float> %ny, <4 x i32> <i32 0, i32 1, i32 4, i32 5>2148  ret <4 x float> %r2149}2150 2151define <2 x i32> @fptosi_unary_shuf(<2 x float> %x) {2152; CHECK-LABEL: @fptosi_unary_shuf(2153; CHECK-NEXT:    [[NX:%.*]] = fptosi <2 x float> [[X:%.*]] to <2 x i32>2154; CHECK-NEXT:    [[R:%.*]] = shufflevector <2 x i32> [[NX]], <2 x i32> poison, <2 x i32> <i32 1, i32 0>2155; CHECK-NEXT:    ret <2 x i32> [[R]]2156;2157  %nx = fptosi <2 x float> %x to <2 x i32>2158  %r = shufflevector <2 x i32> %nx, <2 x i32> poison, <2 x i32> <i32 1, i32 0>2159  ret <2 x i32> %r2160}2161 2162define <2 x i64> @fptoui_unary_shuf_widen_elts(<2 x float> %x) {2163; CHECK-LABEL: @fptoui_unary_shuf_widen_elts(2164; CHECK-NEXT:    [[NX:%.*]] = fptoui <2 x float> [[X:%.*]] to <2 x i64>2165; CHECK-NEXT:    [[R:%.*]] = shufflevector <2 x i64> [[NX]], <2 x i64> poison, <2 x i32> <i32 1, i32 0>2166; CHECK-NEXT:    ret <2 x i64> [[R]]2167;2168  %nx = fptoui <2 x float> %x to <2 x i64>2169  %r = shufflevector <2 x i64> %nx, <2 x i64> poison, <2 x i32> <i32 1, i32 0>2170  ret <2 x i64> %r2171}2172 2173define <2 x half> @sitofp_unary_shuf_narrow_elts(<2 x i32> %x) {2174; CHECK-LABEL: @sitofp_unary_shuf_narrow_elts(2175; CHECK-NEXT:    [[NX:%.*]] = sitofp <2 x i32> [[X:%.*]] to <2 x half>2176; CHECK-NEXT:    [[R:%.*]] = shufflevector <2 x half> [[NX]], <2 x half> poison, <2 x i32> <i32 1, i32 0>2177; CHECK-NEXT:    ret <2 x half> [[R]]2178;2179  %nx = sitofp <2 x i32> %x to <2 x half>2180  %r = shufflevector <2 x half> %nx, <2 x half> poison, <2 x i32> <i32 1, i32 0>2181  ret <2 x half> %r2182}2183 2184define <2 x float> @uitofp_unary_shuf(<2 x i32> %x) {2185; CHECK-LABEL: @uitofp_unary_shuf(2186; CHECK-NEXT:    [[NX:%.*]] = uitofp <2 x i32> [[X:%.*]] to <2 x float>2187; CHECK-NEXT:    [[R:%.*]] = shufflevector <2 x float> [[NX]], <2 x float> poison, <2 x i32> <i32 1, i32 0>2188; CHECK-NEXT:    ret <2 x float> [[R]]2189;2190  %nx = uitofp <2 x i32> %x to <2 x float>2191  %r = shufflevector <2 x float> %nx, <2 x float> poison, <2 x i32> <i32 1, i32 0>2192  ret <2 x float> %r2193}2194 2195define <4 x i16> @fptosi_unary_shuf_widen(<2 x half> %x) {2196; CHECK-LABEL: @fptosi_unary_shuf_widen(2197; CHECK-NEXT:    [[NX:%.*]] = fptosi <2 x half> [[X:%.*]] to <2 x i16>2198; CHECK-NEXT:    [[R:%.*]] = shufflevector <2 x i16> [[NX]], <2 x i16> poison, <4 x i32> <i32 1, i32 0, i32 0, i32 poison>2199; CHECK-NEXT:    ret <4 x i16> [[R]]2200;2201  %nx = fptosi <2 x half> %x to <2 x i16>2202  %r = shufflevector <2 x i16> %nx, <2 x i16> poison, <4 x i32> <i32 1, i32 0, i32 0, i32 poison>2203  ret <4 x i16> %r2204}2205 2206define <4 x i32> @fptoui_unary_shuf_widen_widen_elts(<2 x half> %x) {2207; CHECK-LABEL: @fptoui_unary_shuf_widen_widen_elts(2208; CHECK-NEXT:    [[NX:%.*]] = fptoui <2 x half> [[X:%.*]] to <2 x i32>2209; CHECK-NEXT:    [[R:%.*]] = shufflevector <2 x i32> [[NX]], <2 x i32> poison, <4 x i32> <i32 1, i32 0, i32 0, i32 poison>2210; CHECK-NEXT:    ret <4 x i32> [[R]]2211;2212  %nx = fptoui <2 x half> %x to <2 x i32>2213  %r = shufflevector <2 x i32> %nx, <2 x i32> poison, <4 x i32> <i32 1, i32 0, i32 0, i32 poison>2214  ret <4 x i32> %r2215}2216 2217define <4 x half> @sitofp_unary_shuf_widen_narrow_elts(<2 x i32> %x) {2218; CHECK-LABEL: @sitofp_unary_shuf_widen_narrow_elts(2219; CHECK-NEXT:    [[NX:%.*]] = sitofp <2 x i32> [[X:%.*]] to <2 x half>2220; CHECK-NEXT:    [[R:%.*]] = shufflevector <2 x half> [[NX]], <2 x half> poison, <4 x i32> <i32 1, i32 0, i32 0, i32 poison>2221; CHECK-NEXT:    ret <4 x half> [[R]]2222;2223  %nx = sitofp <2 x i32> %x to <2 x half>2224  %r = shufflevector <2 x half> %nx, <2 x half> poison, <4 x i32> <i32 1, i32 0, i32 0, i32 poison>2225  ret <4 x half> %r2226}2227 2228define <4 x half> @uitofp_unary_shuf_widen(<2 x i16> %x) {2229; CHECK-LABEL: @uitofp_unary_shuf_widen(2230; CHECK-NEXT:    [[NX:%.*]] = uitofp <2 x i16> [[X:%.*]] to <2 x half>2231; CHECK-NEXT:    [[R:%.*]] = shufflevector <2 x half> [[NX]], <2 x half> poison, <4 x i32> <i32 1, i32 0, i32 0, i32 poison>2232; CHECK-NEXT:    ret <4 x half> [[R]]2233;2234  %nx = uitofp <2 x i16> %x to <2 x half>2235  %r = shufflevector <2 x half> %nx, <2 x half> poison, <4 x i32> <i32 1, i32 0, i32 0, i32 poison>2236  ret <4 x half> %r2237}2238 2239define <2 x i16> @fptosi_unary_shuf_narrow(<4 x half> %x) {2240; CHECK-LABEL: @fptosi_unary_shuf_narrow(2241; CHECK-NEXT:    [[NX:%.*]] = fptosi <4 x half> [[X:%.*]] to <4 x i16>2242; CHECK-NEXT:    [[R:%.*]] = shufflevector <4 x i16> [[NX]], <4 x i16> poison, <2 x i32> <i32 1, i32 0>2243; CHECK-NEXT:    ret <2 x i16> [[R]]2244;2245  %nx = fptosi <4 x half> %x to <4 x i16>2246  %r = shufflevector <4 x i16> %nx, <4 x i16> poison, <2 x i32> <i32 1, i32 0>2247  ret <2 x i16> %r2248}2249 2250define <2 x i32> @fptoui_unary_shuf_narrow_widen_elts(<4 x half> %x) {2251; CHECK-LABEL: @fptoui_unary_shuf_narrow_widen_elts(2252; CHECK-NEXT:    [[NX:%.*]] = fptoui <4 x half> [[X:%.*]] to <4 x i32>2253; CHECK-NEXT:    [[R:%.*]] = shufflevector <4 x i32> [[NX]], <4 x i32> poison, <2 x i32> <i32 3, i32 0>2254; CHECK-NEXT:    ret <2 x i32> [[R]]2255;2256  %nx = fptoui <4 x half> %x to <4 x i32>2257  %r = shufflevector <4 x i32> %nx, <4 x i32> poison, <2 x i32> <i32 3, i32 0>2258  ret <2 x i32> %r2259}2260 2261define <2 x double> @sitofp_unary_shuf_narrow(<4 x i64> %x) {2262; CHECK-LABEL: @sitofp_unary_shuf_narrow(2263; CHECK-NEXT:    [[NX:%.*]] = sitofp <4 x i64> [[X:%.*]] to <4 x double>2264; CHECK-NEXT:    [[R:%.*]] = shufflevector <4 x double> [[NX]], <4 x double> poison, <2 x i32> <i32 2, i32 1>2265; CHECK-NEXT:    ret <2 x double> [[R]]2266;2267  %nx = sitofp <4 x i64> %x to <4 x double>2268  %r = shufflevector <4 x double> %nx, <4 x double> poison, <2 x i32> <i32 2, i32 1>2269  ret <2 x double> %r2270}2271 2272define <2 x half> @uitofp_unary_shuf_narrow_narrow_elts(<4 x i32> %x) {2273; CHECK-LABEL: @uitofp_unary_shuf_narrow_narrow_elts(2274; CHECK-NEXT:    [[NX:%.*]] = uitofp <4 x i32> [[X:%.*]] to <4 x half>2275; CHECK-NEXT:    [[R:%.*]] = shufflevector <4 x half> [[NX]], <4 x half> poison, <2 x i32> <i32 3, i32 1>2276; CHECK-NEXT:    ret <2 x half> [[R]]2277;2278  %nx = uitofp <4 x i32> %x to <4 x half>2279  %r = shufflevector <4 x half> %nx, <4 x half> poison, <2 x i32> <i32 3, i32 1>2280  ret <2 x half> %r2281}2282 2283define <4 x i32> @fptosi_shuf(<4 x float> %x, <4 x float> %y) {2284; CHECK-LABEL: @fptosi_shuf(2285; CHECK-NEXT:    [[TMP1:%.*]] = shufflevector <4 x float> [[X:%.*]], <4 x float> [[Y:%.*]], <4 x i32> <i32 0, i32 1, i32 4, i32 5>2286; CHECK-NEXT:    [[R:%.*]] = fptosi <4 x float> [[TMP1]] to <4 x i32>2287; CHECK-NEXT:    ret <4 x i32> [[R]]2288;2289  %nx = fptosi <4 x float> %x to <4 x i32>2290  %ny = fptosi <4 x float> %y to <4 x i32>2291  %r = shufflevector <4 x i32> %nx, <4 x i32> %ny, <4 x i32> <i32 0, i32 1, i32 4, i32 5>2292  ret <4 x i32> %r2293}2294 2295define <3 x i16> @fptoui_shuf(<3 x half> %x, <3 x half> %y) {2296; CHECK-LABEL: @fptoui_shuf(2297; CHECK-NEXT:    [[TMP1:%.*]] = shufflevector <3 x half> [[X:%.*]], <3 x half> [[Y:%.*]], <3 x i32> <i32 0, i32 poison, i32 4>2298; CHECK-NEXT:    [[R:%.*]] = fptoui <3 x half> [[TMP1]] to <3 x i16>2299; CHECK-NEXT:    ret <3 x i16> [[R]]2300;2301  %nx = fptoui <3 x half> %x to <3 x i16>2302  %ny = fptoui <3 x half> %y to <3 x i16>2303  %r = shufflevector <3 x i16> %nx, <3 x i16> %ny, <3 x i32> <i32 0, i32 poison, i32 4>2304  ret <3 x i16> %r2305}2306 2307; negative test - must have same source types2308 2309define <3 x i16> @fptoui_shuf_different_source_types(<3 x float> %x, <3 x half> %y) {2310; CHECK-LABEL: @fptoui_shuf_different_source_types(2311; CHECK-NEXT:    [[NX:%.*]] = fptoui <3 x float> [[X:%.*]] to <3 x i16>2312; CHECK-NEXT:    [[NY:%.*]] = fptoui <3 x half> [[Y:%.*]] to <3 x i16>2313; CHECK-NEXT:    [[R:%.*]] = shufflevector <3 x i16> [[NX]], <3 x i16> [[NY]], <3 x i32> <i32 0, i32 2, i32 4>2314; CHECK-NEXT:    ret <3 x i16> [[R]]2315;2316  %nx = fptoui <3 x float> %x to <3 x i16>2317  %ny = fptoui <3 x half> %y to <3 x i16>2318  %r = shufflevector <3 x i16> %nx, <3 x i16> %ny, <3 x i32> <i32 0, i32 2, i32 4>2319  ret <3 x i16> %r2320}2321 2322define <4 x i32> @fptoui_shuf_widen_elts(<4 x half> %x, <4 x half> %y) {2323; CHECK-LABEL: @fptoui_shuf_widen_elts(2324; CHECK-NEXT:    [[TMP1:%.*]] = shufflevector <4 x half> [[X:%.*]], <4 x half> [[Y:%.*]], <4 x i32> <i32 0, i32 1, i32 4, i32 5>2325; CHECK-NEXT:    [[R:%.*]] = fptosi <4 x half> [[TMP1]] to <4 x i32>2326; CHECK-NEXT:    ret <4 x i32> [[R]]2327;2328  %nx = fptosi <4 x half> %x to <4 x i32>2329  %ny = fptosi <4 x half> %y to <4 x i32>2330  %r = shufflevector <4 x i32> %nx, <4 x i32> %ny, <4 x i32> <i32 0, i32 1, i32 4, i32 5>2331  ret <4 x i32> %r2332}2333 2334; negative test - must have same or smaller size source elements2335 2336define <4 x float> @sitofp_shuf_narrow_elts(<4 x i64> %x, <4 x i64> %y) {2337; CHECK-LABEL: @sitofp_shuf_narrow_elts(2338; CHECK-NEXT:    [[NX:%.*]] = sitofp <4 x i64> [[X:%.*]] to <4 x float>2339; CHECK-NEXT:    [[NY:%.*]] = sitofp <4 x i64> [[Y:%.*]] to <4 x float>2340; CHECK-NEXT:    [[R:%.*]] = shufflevector <4 x float> [[NX]], <4 x float> [[NY]], <4 x i32> <i32 0, i32 1, i32 4, i32 5>2341; CHECK-NEXT:    ret <4 x float> [[R]]2342;2343  %nx = sitofp <4 x i64> %x to <4 x float>2344  %ny = sitofp <4 x i64> %y to <4 x float>2345  %r = shufflevector <4 x float> %nx, <4 x float> %ny, <4 x i32> <i32 0, i32 1, i32 4, i32 5>2346  ret <4 x float> %r2347}2348 2349; one extra use is ok2350 2351define <4 x float> @uitofp_shuf_extra_use1(<4 x i32> %x, <4 x i32> %y) {2352; CHECK-LABEL: @uitofp_shuf_extra_use1(2353; CHECK-NEXT:    [[NX:%.*]] = uitofp <4 x i32> [[X:%.*]] to <4 x float>2354; CHECK-NEXT:    call void @use4(<4 x float> [[NX]])2355; CHECK-NEXT:    [[TMP1:%.*]] = shufflevector <4 x i32> [[X]], <4 x i32> [[Y:%.*]], <4 x i32> <i32 0, i32 0, i32 4, i32 5>2356; CHECK-NEXT:    [[R:%.*]] = uitofp <4 x i32> [[TMP1]] to <4 x float>2357; CHECK-NEXT:    ret <4 x float> [[R]]2358;2359  %nx = uitofp <4 x i32> %x to <4 x float>2360  call void @use4(<4 x float> %nx)2361  %ny = uitofp <4 x i32> %y to <4 x float>2362  %r = shufflevector <4 x float> %nx, <4 x float> %ny, <4 x i32> <i32 0, i32 0, i32 4, i32 5>2363  ret <4 x float> %r2364}2365 2366; one extra use is ok2367 2368define <4 x float> @sitofp_shuf_extra_use2(<4 x i32> %x, <4 x i32> %y) {2369; CHECK-LABEL: @sitofp_shuf_extra_use2(2370; CHECK-NEXT:    [[NY:%.*]] = sitofp <4 x i32> [[Y:%.*]] to <4 x float>2371; CHECK-NEXT:    call void @use4(<4 x float> [[NY]])2372; CHECK-NEXT:    [[TMP1:%.*]] = shufflevector <4 x i32> [[X:%.*]], <4 x i32> [[Y]], <4 x i32> <i32 7, i32 1, i32 4, i32 0>2373; CHECK-NEXT:    [[R:%.*]] = sitofp <4 x i32> [[TMP1]] to <4 x float>2374; CHECK-NEXT:    ret <4 x float> [[R]]2375;2376  %nx = sitofp <4 x i32> %x to <4 x float>2377  %ny = sitofp <4 x i32> %y to <4 x float>2378  call void @use4(<4 x float> %ny)2379  %r = shufflevector <4 x float> %nx, <4 x float> %ny, <4 x i32> <i32 7, i32 1, i32 4, i32 0>2380  ret <4 x float> %r2381}2382 2383; negative test - both ops have extra uses2384 2385define <2 x float> @sitofp_shuf_extra_use3(<2 x i32> %x, <2 x i32> %y) {2386; CHECK-LABEL: @sitofp_shuf_extra_use3(2387; CHECK-NEXT:    [[NX:%.*]] = sitofp <2 x i32> [[X:%.*]] to <2 x float>2388; CHECK-NEXT:    call void @use(<2 x float> [[NX]])2389; CHECK-NEXT:    [[NY:%.*]] = sitofp <2 x i32> [[Y:%.*]] to <2 x float>2390; CHECK-NEXT:    call void @use(<2 x float> [[NY]])2391; CHECK-NEXT:    [[R:%.*]] = shufflevector <2 x float> [[NX]], <2 x float> [[NY]], <2 x i32> <i32 3, i32 1>2392; CHECK-NEXT:    ret <2 x float> [[R]]2393;2394  %nx = sitofp <2 x i32> %x to <2 x float>2395  call void @use(<2 x float> %nx)2396  %ny = sitofp <2 x i32> %y to <2 x float>2397  call void @use(<2 x float> %ny)2398  %r = shufflevector <2 x float> %nx, <2 x float> %ny, <2 x i32> <i32 3, i32 1>2399  ret <2 x float> %r2400}2401 2402; negative test - mismatched casts2403 2404define <4 x i32> @fptoi_shuf(<4 x float> %x, <4 x float> %y) {2405; CHECK-LABEL: @fptoi_shuf(2406; CHECK-NEXT:    [[NX:%.*]] = fptoui <4 x float> [[X:%.*]] to <4 x i32>2407; CHECK-NEXT:    [[NY:%.*]] = fptosi <4 x float> [[Y:%.*]] to <4 x i32>2408; CHECK-NEXT:    [[R:%.*]] = shufflevector <4 x i32> [[NX]], <4 x i32> [[NY]], <4 x i32> <i32 0, i32 1, i32 4, i32 5>2409; CHECK-NEXT:    ret <4 x i32> [[R]]2410;2411  %nx = fptoui <4 x float> %x to <4 x i32>2412  %ny = fptosi <4 x float> %y to <4 x i32>2413  %r = shufflevector <4 x i32> %nx, <4 x i32> %ny, <4 x i32> <i32 0, i32 1, i32 4, i32 5>2414  ret <4 x i32> %r2415}2416 2417; negative test - length-increasing shuffle2418 2419define <4 x float> @sitofp_shuf_widen(<2 x i32> %x, <2 x i32> %y) {2420; CHECK-LABEL: @sitofp_shuf_widen(2421; CHECK-NEXT:    [[NX:%.*]] = sitofp <2 x i32> [[X:%.*]] to <2 x float>2422; CHECK-NEXT:    [[NY:%.*]] = sitofp <2 x i32> [[Y:%.*]] to <2 x float>2423; CHECK-NEXT:    [[R:%.*]] = shufflevector <2 x float> [[NX]], <2 x float> [[NY]], <4 x i32> <i32 poison, i32 1, i32 2, i32 3>2424; CHECK-NEXT:    ret <4 x float> [[R]]2425;2426  %nx = sitofp <2 x i32> %x to <2 x float>2427  %ny = sitofp <2 x i32> %y to <2 x float>2428  %r = shufflevector <2 x float> %nx, <2 x float> %ny, <4 x i32> <i32 poison, i32 1, i32 2, i32 3>2429  ret <4 x float> %r2430}2431 2432define <2 x float> @uitofp_shuf_narrow(<4 x i32> %x, <4 x i32> %y) {2433; CHECK-LABEL: @uitofp_shuf_narrow(2434; CHECK-NEXT:    [[TMP1:%.*]] = shufflevector <4 x i32> [[X:%.*]], <4 x i32> [[Y:%.*]], <2 x i32> <i32 3, i32 5>2435; CHECK-NEXT:    [[R:%.*]] = uitofp <2 x i32> [[TMP1]] to <2 x float>2436; CHECK-NEXT:    ret <2 x float> [[R]]2437;2438  %nx = uitofp <4 x i32> %x to <4 x float>2439  %ny = uitofp <4 x i32> %y to <4 x float>2440  %r = shufflevector <4 x float> %nx, <4 x float> %ny, <2 x i32> <i32 3, i32 5>2441  ret <2 x float> %r2442}2443 2444define <4 x i16> @blend_elements_from_load(ptr align 8 %_0) {2445; CHECK-LABEL: @blend_elements_from_load(2446; CHECK-NEXT:    [[LOAD:%.*]] = load <3 x i16>, ptr [[_0:%.*]], align 82447; CHECK-NEXT:    [[RV:%.*]] = shufflevector <3 x i16> <i16 0, i16 undef, i16 poison>, <3 x i16> [[LOAD]], <4 x i32> <i32 0, i32 1, i32 3, i32 5>2448; CHECK-NEXT:    ret <4 x i16> [[RV]]2449;2450  %load = load <3 x i16>, ptr %_0, align 82451  %rv = shufflevector <3 x i16> <i16 0, i16 undef, i16 undef>, <3 x i16> %load, <4 x i32> <i32 0, i32 1, i32 3, i32 5>2452  ret <4 x i16> %rv2453}2454 2455define i16 @pr92887(<2 x i16> %v) {2456; CHECK-LABEL: @pr92887(2457; CHECK-NEXT:    ret i16 undef2458;2459  %v0 = extractelement <2 x i16> %v, i64 02460  %v0lo = and i16 %v0, 12461  %v1 = extractelement <2 x i16> %v, i64 12462  %v1lo = and i16 %v1, 12463  %ins1 = insertelement <4 x i16> poison, i16 %v0lo, i64 02464  %ins2 = insertelement <4 x i16> %ins1, i16 %v1lo, i64 12465  %shuf = shufflevector <4 x i16> %ins2, <4 x i16> <i16 poison, i16 poison, i16 undef, i16 undef>, <4 x i32> <i32 0, i32 1, i32 6, i32 7>2466  %extract = extractelement <4 x i16> %shuf, i32 22467  ret i16 %extract2468}2469 2470define <2 x i32> @not_splat_shuffle1(i32 %x) {2471; CHECK-LABEL: @not_splat_shuffle1(2472; CHECK-NEXT:    [[SHUF:%.*]] = insertelement <2 x i32> <i32 poison, i32 undef>, i32 [[X:%.*]], i64 02473; CHECK-NEXT:    ret <2 x i32> [[SHUF]]2474;2475  %vec = insertelement <2 x i32> undef, i32 %x, i32 12476  %shuf = shufflevector <2 x i32> %vec, <2 x i32> poison, <2 x i32> <i32 1, i32 0>2477  ret <2 x i32> %shuf2478}2479 2480define <2 x i32> @not_splat_shuffle2(i32 %x) {2481; CHECK-LABEL: @not_splat_shuffle2(2482; CHECK-NEXT:    [[SHUF:%.*]] = insertelement <2 x i32> <i32 poison, i32 undef>, i32 [[X:%.*]], i64 02483; CHECK-NEXT:    ret <2 x i32> [[SHUF]]2484;2485  %vec = insertelement <2 x i32> poison, i32 %x, i32 12486  %shuf = shufflevector <2 x i32> %vec, <2 x i32> undef, <2 x i32> <i32 1, i32 3>2487  ret <2 x i32> %shuf2488}2489define <2 x i32> @foldselect0(i1 %c) {2490; CHECK-LABEL: @foldselect0(2491; CHECK-NEXT:    [[SHUF:%.*]] = select i1 [[C:%.*]], <2 x i32> <i32 7, i32 42>, <2 x i32> <i32 1, i32 0>2492; CHECK-NEXT:    ret <2 x i32> [[SHUF]]2493;2494  %sel = select i1 %c, <2 x i32> <i32 42, i32 7>, <2 x i32> <i32 0, i32 1>2495  %shuf = shufflevector <2 x i32> %sel, <2 x i32> poison, <2 x i32> <i32 1, i32 0>2496  ret <2 x i32> %shuf2497}2498 2499; Make sure we do not crash in this case.2500define <4 x float> @shuf_larger_length_vec_select(<2 x i1> %cond) {2501; CHECK-LABEL: @shuf_larger_length_vec_select(2502; CHECK-NEXT:    [[SEL:%.*]] = select <2 x i1> [[COND:%.*]], <2 x float> zeroinitializer, <2 x float> splat (float 1.000000e+00)2503; CHECK-NEXT:    [[SHUF:%.*]] = shufflevector <2 x float> [[SEL]], <2 x float> zeroinitializer, <4 x i32> <i32 0, i32 1, i32 2, i32 3>2504; CHECK-NEXT:    ret <4 x float> [[SHUF]]2505;2506  %sel = select <2 x i1> %cond, <2 x float> zeroinitializer, <2 x float> splat(float 1.000000e+00)2507  %shuf = shufflevector <2 x float> %sel, <2 x float> zeroinitializer, <4 x i32> <i32 0, i32 1, i32 2, i32 3>2508  ret <4 x float> %shuf2509}2510 2511; Make sure we do not fold in this case.2512define <4 x i32> @shuf_same_length_vec_select(<4 x i1> %cond) {2513; CHECK-LABEL: @shuf_same_length_vec_select(2514; CHECK-NEXT:    [[SEL:%.*]] = select <4 x i1> [[COND:%.*]], <4 x i32> <i32 poison, i32 1, i32 2, i32 3>, <4 x i32> <i32 poison, i32 5, i32 6, i32 7>2515; CHECK-NEXT:    [[SHUF:%.*]] = shufflevector <4 x i32> [[SEL]], <4 x i32> <i32 poison, i32 9, i32 poison, i32 poison>, <4 x i32> <i32 2, i32 1, i32 3, i32 5>2516; CHECK-NEXT:    ret <4 x i32> [[SHUF]]2517;2518  %sel = select <4 x i1> %cond, <4 x i32> <i32 0, i32 1, i32 2, i32 3>, <4 x i32> <i32 4, i32 5, i32 6, i32 7>2519  %shuf = shufflevector <4 x i32> %sel, <4 x i32> <i32 8, i32 9, i32 10, i32 11>, <4 x i32> <i32 2, i32 1, i32 3, i32 5>2520  ret <4 x i32> %shuf2521}2522 2523; Make sure we do not fold in this case.2524define <4 x i8> @shuf_cmp_may_be_poison(<4 x i8> %x, <4 x i8> %y, i1 %cmp) {2525; CHECK-LABEL: @shuf_cmp_may_be_poison(2526; CHECK-NEXT:    [[Y:%.*]] = select i1 [[CMP:%.*]], <4 x i8> [[Y1:%.*]], <4 x i8> <i8 0, i8 poison, i8 0, i8 poison>2527; CHECK-NEXT:    [[TMP1:%.*]] = shufflevector <4 x i8> [[Y]], <4 x i8> <i8 poison, i8 1, i8 poison, i8 3>, <4 x i32> <i32 0, i32 5, i32 2, i32 7>2528; CHECK-NEXT:    ret <4 x i8> [[TMP1]]2529;2530  %sel = select i1 %cmp, <4 x i8> %y, <4 x i8> <i8 0, i8 poison, i8 0, i8 poison>2531  %shuf = shufflevector <4 x i8> %sel, <4 x i8> <i8 poison, i8 1, i8 poison, i8 3>, <4 x i32> <i32 0, i32 5, i32 2, i32 7>2532  ret <4 x i8> %shuf2533}2534 2535declare i1 @cond()2536declare <4 x i32> @value()2537 2538define <4 x i32> @foldphi1() {2539; CHECK-LABEL: @foldphi1(2540; CHECK-NEXT:  entry:2541; CHECK-NEXT:    br label [[LOOP:%.*]]2542; CHECK:       loop:2543; CHECK-NEXT:    [[V:%.*]] = phi <4 x i32> [ zeroinitializer, [[ENTRY:%.*]] ], [ [[XOR:%.*]], [[LOOP]] ]2544; CHECK-NEXT:    [[VAL:%.*]] = call <4 x i32> @value()2545; CHECK-NEXT:    [[XOR]] = xor <4 x i32> [[V]], [[VAL]]2546; CHECK-NEXT:    [[C:%.*]] = call i1 @cond()2547; CHECK-NEXT:    br i1 [[C]], label [[LOOP]], label [[EXIT:%.*]]2548; CHECK:       exit:2549; CHECK-NEXT:    [[SHUF1:%.*]] = shufflevector <4 x i32> [[XOR]], <4 x i32> poison, <4 x i32> <i32 3, i32 0, i32 1, i32 2>2550; CHECK-NEXT:    ret <4 x i32> [[SHUF1]]2551;2552entry:2553  br label %loop2554 2555loop:2556  %v = phi <4 x i32> [zeroinitializer, %entry], [%shuf1, %loop]2557 2558  %shuf0 = shufflevector <4 x i32> %v, <4 x i32> poison, <4 x i32> <i32 1, i32 2, i32 3, i32 0>2559  %val = call <4 x i32> @value()2560  %xor = xor <4 x i32> %shuf0, %val2561  %shuf1 = shufflevector <4 x i32> %xor, <4 x i32> poison, <4 x i32> <i32 3, i32 0, i32 1, i32 2>2562 2563  %c = call i1 @cond()2564  br i1 %c, label %loop, label %exit2565 2566exit:2567  ret <4 x i32> %shuf12568}2569