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