853 lines · plain
1; NOTE: Assertions have been autogenerated by utils/update_test_checks.py2; RUN: opt -S -passes=instcombine %s | FileCheck %s3 4define <1 x i8> @test1(<8 x i8> %in) {5; CHECK-LABEL: @test1(6; CHECK-NEXT: [[VEC:%.*]] = shufflevector <8 x i8> [[IN:%.*]], <8 x i8> poison, <1 x i32> <i32 5>7; CHECK-NEXT: ret <1 x i8> [[VEC]]8;9 %val = extractelement <8 x i8> %in, i32 510 %vec = insertelement <1 x i8> undef, i8 %val, i32 011 ret <1 x i8> %vec12}13 14define <4 x i16> @test2(<8 x i16> %in, <8 x i16> %in2) {15; CHECK-LABEL: @test2(16; CHECK-NEXT: [[VEC_3:%.*]] = shufflevector <8 x i16> [[IN2:%.*]], <8 x i16> [[IN:%.*]], <4 x i32> <i32 11, i32 9, i32 0, i32 10>17; CHECK-NEXT: ret <4 x i16> [[VEC_3]]18;19 %elt0 = extractelement <8 x i16> %in, i32 320 %elt1 = extractelement <8 x i16> %in, i32 121 %elt2 = extractelement <8 x i16> %in2, i32 022 %elt3 = extractelement <8 x i16> %in, i32 223 24 %vec.0 = insertelement <4 x i16> undef, i16 %elt0, i32 025 %vec.1 = insertelement <4 x i16> %vec.0, i16 %elt1, i32 126 %vec.2 = insertelement <4 x i16> %vec.1, i16 %elt2, i32 227 %vec.3 = insertelement <4 x i16> %vec.2, i16 %elt3, i32 328 29 ret <4 x i16> %vec.330}31 32define <2 x i64> @test_vcopyq_lane_p64(<2 x i64> %a, <1 x i64> %b) {33; CHECK-LABEL: @test_vcopyq_lane_p64(34; CHECK-NEXT: [[TMP1:%.*]] = shufflevector <1 x i64> [[B:%.*]], <1 x i64> poison, <2 x i32> <i32 0, i32 poison>35; CHECK-NEXT: [[RES:%.*]] = shufflevector <2 x i64> [[A:%.*]], <2 x i64> [[TMP1]], <2 x i32> <i32 0, i32 2>36; CHECK-NEXT: ret <2 x i64> [[RES]]37;38 %elt = extractelement <1 x i64> %b, i32 039 %res = insertelement <2 x i64> %a, i64 %elt, i32 140 ret <2 x i64> %res41}42 43; PR2109: https://llvm.org/bugs/show_bug.cgi?id=210944 45define <4 x float> @widen_extract2(<4 x float> %ins, <2 x float> %ext) {46; CHECK-LABEL: @widen_extract2(47; CHECK-NEXT: [[TMP1:%.*]] = shufflevector <2 x float> [[EXT:%.*]], <2 x float> poison, <4 x i32> <i32 0, i32 1, i32 poison, i32 poison>48; CHECK-NEXT: [[I2:%.*]] = shufflevector <4 x float> [[INS:%.*]], <4 x float> [[TMP1]], <4 x i32> <i32 0, i32 4, i32 2, i32 5>49; CHECK-NEXT: ret <4 x float> [[I2]]50;51 %e1 = extractelement <2 x float> %ext, i32 052 %e2 = extractelement <2 x float> %ext, i32 153 %i1 = insertelement <4 x float> %ins, float %e1, i32 154 %i2 = insertelement <4 x float> %i1, float %e2, i32 355 ret <4 x float> %i256}57 58define <4 x float> @widen_extract3(<4 x float> %ins, <3 x float> %ext) {59; CHECK-LABEL: @widen_extract3(60; CHECK-NEXT: [[TMP1:%.*]] = shufflevector <3 x float> [[EXT:%.*]], <3 x float> poison, <4 x i32> <i32 0, i32 1, i32 2, i32 poison>61; CHECK-NEXT: [[I3:%.*]] = shufflevector <4 x float> [[INS:%.*]], <4 x float> [[TMP1]], <4 x i32> <i32 6, i32 5, i32 4, i32 3>62; CHECK-NEXT: ret <4 x float> [[I3]]63;64 %e1 = extractelement <3 x float> %ext, i32 065 %e2 = extractelement <3 x float> %ext, i32 166 %e3 = extractelement <3 x float> %ext, i32 267 %i1 = insertelement <4 x float> %ins, float %e1, i32 268 %i2 = insertelement <4 x float> %i1, float %e2, i32 169 %i3 = insertelement <4 x float> %i2, float %e3, i32 070 ret <4 x float> %i371}72 73define <8 x float> @widen_extract4(<8 x float> %ins, <2 x float> %ext) {74; CHECK-LABEL: @widen_extract4(75; CHECK-NEXT: [[TMP1:%.*]] = shufflevector <2 x float> [[EXT:%.*]], <2 x float> poison, <8 x i32> <i32 0, i32 poison, i32 poison, i32 poison, i32 poison, i32 poison, i32 poison, i32 poison>76; CHECK-NEXT: [[I1:%.*]] = shufflevector <8 x float> [[INS:%.*]], <8 x float> [[TMP1]], <8 x i32> <i32 0, i32 1, i32 8, i32 3, i32 4, i32 5, i32 6, i32 7>77; CHECK-NEXT: ret <8 x float> [[I1]]78;79 %e1 = extractelement <2 x float> %ext, i32 080 %i1 = insertelement <8 x float> %ins, float %e1, i32 281 ret <8 x float> %i182}83 84; PR26015: https://llvm.org/bugs/show_bug.cgi?id=2601585; The widening shuffle must be inserted before any uses.86 87define <8 x i16> @pr26015(<4 x i16> %t0) {88; CHECK-LABEL: @pr26015(89; CHECK-NEXT: [[TMP1:%.*]] = shufflevector <4 x i16> [[T0:%.*]], <4 x i16> poison, <8 x i32> <i32 poison, i32 poison, i32 2, i32 3, i32 poison, i32 poison, i32 poison, i32 poison>90; CHECK-NEXT: [[T5:%.*]] = shufflevector <8 x i16> <i16 0, i16 0, i16 0, i16 poison, i16 0, i16 0, i16 0, i16 poison>, <8 x i16> [[TMP1]], <8 x i32> <i32 0, i32 1, i32 2, i32 10, i32 4, i32 5, i32 6, i32 11>91; CHECK-NEXT: ret <8 x i16> [[T5]]92;93 %t1 = extractelement <4 x i16> %t0, i32 294 %t2 = insertelement <8 x i16> zeroinitializer, i16 %t1, i32 395 %t3 = insertelement <8 x i16> %t2, i16 0, i32 696 %t4 = extractelement <4 x i16> %t0, i32 397 %t5 = insertelement <8 x i16> %t3, i16 %t4, i32 798 ret <8 x i16> %t599}100 101; PR25999: https://llvm.org/bugs/show_bug.cgi?id=25999102; TODO: The widening shuffle could be inserted at the start of the function to allow the first extract to use it.103 104define <8 x i16> @pr25999(<4 x i16> %t0, i1 %b) {105; CHECK-LABEL: @pr25999(106; CHECK-NEXT: [[T1:%.*]] = extractelement <4 x i16> [[T0:%.*]], i64 2107; CHECK-NEXT: br i1 [[B:%.*]], label [[IF:%.*]], label [[END:%.*]]108; CHECK: if:109; CHECK-NEXT: [[TMP1:%.*]] = shufflevector <4 x i16> [[T0]], <4 x i16> poison, <8 x i32> <i32 poison, i32 poison, i32 poison, i32 3, i32 poison, i32 poison, i32 poison, i32 poison>110; CHECK-NEXT: [[T3:%.*]] = insertelement <8 x i16> <i16 0, i16 0, i16 0, i16 poison, i16 0, i16 0, i16 0, i16 poison>, i16 [[T1]], i64 3111; CHECK-NEXT: [[T5:%.*]] = shufflevector <8 x i16> [[T3]], <8 x i16> [[TMP1]], <8 x i32> <i32 0, i32 1, i32 2, i32 3, i32 4, i32 5, i32 6, i32 11>112; CHECK-NEXT: ret <8 x i16> [[T5]]113; CHECK: end:114; CHECK-NEXT: [[A1:%.*]] = add i16 [[T1]], 4115; CHECK-NEXT: [[T6:%.*]] = insertelement <8 x i16> <i16 poison, i16 0, i16 0, i16 0, i16 0, i16 0, i16 0, i16 0>, i16 [[A1]], i64 0116; CHECK-NEXT: ret <8 x i16> [[T6]]117;118 119 %t1 = extractelement <4 x i16> %t0, i32 2120 br i1 %b, label %if, label %end121 122if:123 %t2 = insertelement <8 x i16> zeroinitializer, i16 %t1, i32 3124 %t3 = insertelement <8 x i16> %t2, i16 0, i32 6125 %t4 = extractelement <4 x i16> %t0, i32 3126 %t5 = insertelement <8 x i16> %t3, i16 %t4, i32 7127 ret <8 x i16> %t5128 129end:130 %a1 = add i16 %t1, 4131 %t6 = insertelement <8 x i16> zeroinitializer, i16 %a1, i32 0132 ret <8 x i16> %t6133}134 135; The widening shuffle must be inserted at a valid point (after the PHIs).136 137define <4 x double> @pr25999_phis1(i1 %c, <2 x double> %a, <4 x double> %b) {138; CHECK-LABEL: @pr25999_phis1(139; CHECK-NEXT: bb1:140; CHECK-NEXT: br i1 [[C:%.*]], label [[BB2:%.*]], label [[BB3:%.*]]141; CHECK: bb2:142; CHECK-NEXT: [[R:%.*]] = call <2 x double> @dummy(<2 x double> [[A:%.*]])143; CHECK-NEXT: br label [[BB3]]144; CHECK: bb3:145; CHECK-NEXT: [[T1:%.*]] = phi <2 x double> [ [[A]], [[BB1:%.*]] ], [ [[R]], [[BB2]] ]146; CHECK-NEXT: [[T2:%.*]] = phi <4 x double> [ [[B:%.*]], [[BB1]] ], [ zeroinitializer, [[BB2]] ]147; CHECK-NEXT: [[TMP0:%.*]] = shufflevector <2 x double> [[T1]], <2 x double> poison, <4 x i32> <i32 0, i32 poison, i32 poison, i32 poison>148; CHECK-NEXT: [[T4:%.*]] = shufflevector <4 x double> [[T2]], <4 x double> [[TMP0]], <4 x i32> <i32 0, i32 1, i32 4, i32 3>149; CHECK-NEXT: ret <4 x double> [[T4]]150;151bb1:152 br i1 %c, label %bb2, label %bb3153 154bb2:155 %r = call <2 x double> @dummy(<2 x double> %a)156 br label %bb3157 158bb3:159 %t1 = phi <2 x double> [ %a, %bb1 ], [ %r, %bb2 ]160 %t2 = phi <4 x double> [ %b, %bb1 ], [ zeroinitializer, %bb2 ]161 %t3 = extractelement <2 x double> %t1, i32 0162 %t4 = insertelement <4 x double> %t2, double %t3, i32 2163 ret <4 x double> %t4164}165 166declare <2 x double> @dummy(<2 x double>)167 168define <4 x double> @pr25999_phis2(i1 %c, <2 x double> %a, <4 x double> %b) {169; CHECK-LABEL: @pr25999_phis2(170; CHECK-NEXT: bb1:171; CHECK-NEXT: br i1 [[C:%.*]], label [[BB2:%.*]], label [[BB3:%.*]]172; CHECK: bb2:173; CHECK-NEXT: [[R:%.*]] = call <2 x double> @dummy(<2 x double> [[A:%.*]])174; CHECK-NEXT: br label [[BB3]]175; CHECK: bb3:176; CHECK-NEXT: [[T1:%.*]] = phi <2 x double> [ [[A]], [[BB1:%.*]] ], [ [[R]], [[BB2]] ]177; CHECK-NEXT: [[T2:%.*]] = phi <4 x double> [ [[B:%.*]], [[BB1]] ], [ zeroinitializer, [[BB2]] ]178; CHECK-NEXT: [[D:%.*]] = fadd <2 x double> [[T1]], [[T1]]179; CHECK-NEXT: [[TMP0:%.*]] = shufflevector <2 x double> [[D]], <2 x double> poison, <4 x i32> <i32 0, i32 poison, i32 poison, i32 poison>180; CHECK-NEXT: [[T4:%.*]] = shufflevector <4 x double> [[T2]], <4 x double> [[TMP0]], <4 x i32> <i32 0, i32 1, i32 4, i32 3>181; CHECK-NEXT: ret <4 x double> [[T4]]182;183bb1:184 br i1 %c, label %bb2, label %bb3185 186bb2:187 %r = call <2 x double> @dummy(<2 x double> %a)188 br label %bb3189 190bb3:191 %t1 = phi <2 x double> [ %a, %bb1 ], [ %r, %bb2 ]192 %t2 = phi <4 x double> [ %b, %bb1 ], [ zeroinitializer, %bb2 ]193 %d = fadd <2 x double> %t1, %t1194 %t3 = extractelement <2 x double> %d, i32 0195 %t4 = insertelement <4 x double> %t2, double %t3, i32 2196 ret <4 x double> %t4197}198 199; PR26354: https://llvm.org/bugs/show_bug.cgi?id=26354200; Don't create a shufflevector if we know that we're not going to replace the insertelement.201 202define double @pr26354(ptr %t, i1 %B) {203; CHECK-LABEL: @pr26354(204; CHECK-NEXT: entry:205; CHECK-NEXT: [[LD:%.*]] = load <2 x double>, ptr [[T:%.*]], align 16206; CHECK-NEXT: br i1 [[B:%.*]], label [[IF:%.*]], label [[END:%.*]]207; CHECK: if:208; CHECK-NEXT: [[E2:%.*]] = extractelement <2 x double> [[LD]], i64 1209; CHECK-NEXT: [[I1:%.*]] = insertelement <4 x double> <double 0.000000e+00, double 0.000000e+00, double 0.000000e+00, double poison>, double [[E2]], i64 3210; CHECK-NEXT: br label [[END]]211; CHECK: end:212; CHECK-NEXT: [[PH:%.*]] = phi <4 x double> [ undef, [[ENTRY:%.*]] ], [ [[I1]], [[IF]] ]213; CHECK-NEXT: [[E1:%.*]] = extractelement <2 x double> [[LD]], i64 0214; CHECK-NEXT: [[E3:%.*]] = extractelement <4 x double> [[PH]], i64 1215; CHECK-NEXT: [[MU:%.*]] = fmul double [[E1]], [[E3]]216; CHECK-NEXT: ret double [[MU]]217;218 219entry:220 %ld = load <2 x double>, ptr %t221 %e1 = extractelement <2 x double> %ld, i32 0222 %e2 = extractelement <2 x double> %ld, i32 1223 br i1 %B, label %if, label %end224 225if:226 %i1 = insertelement <4 x double> zeroinitializer, double %e2, i32 3227 br label %end228 229end:230 %ph = phi <4 x double> [ undef, %entry ], [ %i1, %if ]231 %e3 = extractelement <4 x double> %ph, i32 1232 %mu = fmul double %e1, %e3233 ret double %mu234}235 236; https://llvm.org/bugs/show_bug.cgi?id=30923237; Delete the widening shuffle if we're not going to reduce the extract/insert to a shuffle.238 239define <4 x float> @PR30923(<2 x float> %x, ptr %p) {240; CHECK-LABEL: @PR30923(241; CHECK-NEXT: bb1:242; CHECK-NEXT: [[EXT1:%.*]] = extractelement <2 x float> [[X:%.*]], i64 1243; CHECK-NEXT: store float [[EXT1]], ptr [[P:%.*]], align 4244; CHECK-NEXT: br label [[BB2:%.*]]245; CHECK: bb2:246; CHECK-NEXT: [[EXT2:%.*]] = extractelement <2 x float> [[X]], i64 0247; CHECK-NEXT: [[INS1:%.*]] = insertelement <4 x float> <float 0.000000e+00, float 0.000000e+00, float poison, float poison>, float [[EXT2]], i64 2248; CHECK-NEXT: [[INS2:%.*]] = insertelement <4 x float> [[INS1]], float [[EXT1]], i64 3249; CHECK-NEXT: ret <4 x float> [[INS2]]250;251bb1:252 %ext1 = extractelement <2 x float> %x, i32 1253 store float %ext1, ptr %p, align 4254 br label %bb2255 256bb2:257 %widen = shufflevector <2 x float> %x, <2 x float> undef, <4 x i32> <i32 0, i32 1, i32 undef, i32 undef>258 %ext2 = extractelement <4 x float> %widen, i32 0259 %ins1 = insertelement <4 x float> <float 0.0, float 0.0, float undef, float undef>, float %ext2, i32 2260 %ins2 = insertelement <4 x float> %ins1, float %ext1, i32 3261 ret <4 x float> %ins2262}263 264; Don't insert extractelements from the wider vector before the def of the index operand.265 266define <4 x i32> @extractelt_insertion(<2 x i32> %x, i32 %y) {267; CHECK-LABEL: @extractelt_insertion(268; CHECK-NEXT: entry:269; CHECK-NEXT: [[TMP0:%.*]] = shufflevector <2 x i32> [[X:%.*]], <2 x i32> poison, <4 x i32> <i32 0, i32 1, i32 poison, i32 poison>270; CHECK-NEXT: [[B:%.*]] = shufflevector <4 x i32> <i32 0, i32 poison, i32 poison, i32 poison>, <4 x i32> [[TMP0]], <4 x i32> <i32 0, i32 0, i32 0, i32 5>271; CHECK-NEXT: [[C:%.*]] = add i32 [[Y:%.*]], 3272; CHECK-NEXT: [[D:%.*]] = extractelement <4 x i32> [[TMP0]], i32 [[C]]273; CHECK-NEXT: [[E:%.*]] = icmp eq i32 [[D]], 0274; CHECK-NEXT: [[RET:%.*]] = select i1 [[E]], <4 x i32> [[B]], <4 x i32> zeroinitializer275; CHECK-NEXT: ret <4 x i32> [[RET]]276;277entry:278 %a = extractelement <2 x i32> %x, i32 1279 %b = insertelement <4 x i32> zeroinitializer, i32 %a, i64 3280 %c = add i32 %y, 3281 %d = extractelement <2 x i32> %x, i32 %c282 %e = icmp eq i32 %d, 0283 %ret = select i1 %e, <4 x i32> %b, <4 x i32> zeroinitializer284 ret <4 x i32> %ret285}286 287; PR34724: https://bugs.llvm.org/show_bug.cgi?id=34724288 289define <4 x float> @collectShuffleElts(<2 x float> %x, float %y) {290; CHECK-LABEL: @collectShuffleElts(291; CHECK-NEXT: [[X0:%.*]] = extractelement <2 x float> [[X:%.*]], i64 0292; CHECK-NEXT: [[X1:%.*]] = extractelement <2 x float> [[X]], i64 1293; CHECK-NEXT: [[V1:%.*]] = insertelement <4 x float> <float undef, float poison, float poison, float poison>, float [[X0]], i64 1294; CHECK-NEXT: [[V2:%.*]] = insertelement <4 x float> [[V1]], float [[X1]], i64 2295; CHECK-NEXT: [[V3:%.*]] = insertelement <4 x float> [[V2]], float [[Y:%.*]], i64 3296; CHECK-NEXT: ret <4 x float> [[V3]]297;298 %x0 = extractelement <2 x float> %x, i32 0299 %x1 = extractelement <2 x float> %x, i32 1300 %v1 = insertelement <4 x float> undef, float %x0, i32 1301 %v2 = insertelement <4 x float> %v1, float %x1, i32 2302 %v3 = insertelement <4 x float> %v2, float %y, i32 3303 ret <4 x float> %v3304}305 306; Simplest case - insert scalar into undef, then shuffle that value in place into another vector.307 308define <4 x float> @insert_shuffle(float %x, <4 x float> %y) {309; CHECK-LABEL: @insert_shuffle(310; CHECK-NEXT: [[R:%.*]] = insertelement <4 x float> [[Y:%.*]], float [[X:%.*]], i64 0311; CHECK-NEXT: ret <4 x float> [[R]]312;313 %xv = insertelement <4 x float> undef, float %x, i32 0314 %r = shufflevector <4 x float> %xv, <4 x float> %y, <4 x i32> <i32 0, i32 5, i32 6, i32 7>315 ret <4 x float> %r316}317 318; Insert scalar into some element of a dummy vector, then move it to a different element in another vector.319 320define <4 x float> @insert_shuffle_translate(float %x, <4 x float> %y) {321; CHECK-LABEL: @insert_shuffle_translate(322; CHECK-NEXT: [[R:%.*]] = insertelement <4 x float> [[Y:%.*]], float [[X:%.*]], i64 1323; CHECK-NEXT: ret <4 x float> [[R]]324;325 %xv = insertelement <4 x float> undef, float %x, i32 0326 %r = shufflevector <4 x float> %xv, <4 x float> %y, <4 x i32> <i32 4, i32 0, i32 6, i32 7>327 ret <4 x float> %r328}329 330; The vector operand of the insert is irrelevant.331 332define <4 x float> @insert_not_undef_shuffle_translate(float %x, <4 x float> %y, <4 x float> %q) {333; CHECK-LABEL: @insert_not_undef_shuffle_translate(334; CHECK-NEXT: [[R:%.*]] = insertelement <4 x float> [[Y:%.*]], float [[X:%.*]], i64 2335; CHECK-NEXT: ret <4 x float> [[R]]336;337 %xv = insertelement <4 x float> %q, float %x, i32 3338 %r = shufflevector <4 x float> %xv, <4 x float> %y, <4 x i32> <i32 4, i32 5, i32 3, i32 7>339 ret <4 x float> %r340}341 342; The insert may be the 2nd operand of the shuffle. The shuffle mask can include undef elements.343 344define <4 x float> @insert_not_undef_shuffle_translate_commute(float %x, <4 x float> %y, <4 x float> %q) {345; CHECK-LABEL: @insert_not_undef_shuffle_translate_commute(346; CHECK-NEXT: [[R:%.*]] = insertelement <4 x float> [[Y:%.*]], float [[X:%.*]], i64 1347; CHECK-NEXT: ret <4 x float> [[R]]348;349 %xv = insertelement <4 x float> %q, float %x, i32 2350 %r = shufflevector <4 x float> %y, <4 x float> %xv, <4 x i32> <i32 0, i32 6, i32 2, i32 undef>351 ret <4 x float> %r352}353 354; Both shuffle operands may be inserts - choose the correct side.355 356define <4 x float> @insert_insert_shuffle_translate(float %x1, float %x2, <4 x float> %q) {357; CHECK-LABEL: @insert_insert_shuffle_translate(358; CHECK-NEXT: [[TMP1:%.*]] = insertelement <4 x float> [[Q:%.*]], float [[X1:%.*]], i64 1359; CHECK-NEXT: [[R:%.*]] = insertelement <4 x float> [[TMP1]], float [[X2:%.*]], i64 2360; CHECK-NEXT: ret <4 x float> [[R]]361;362 %xv1 = insertelement <4 x float> %q, float %x1, i32 0363 %xv2 = insertelement <4 x float> %q, float %x2, i32 2364 %r = shufflevector <4 x float> %xv1, <4 x float> %xv2, <4 x i32> <i32 4, i32 0, i32 6, i32 7>365 ret <4 x float> %r366}367 368; Both shuffle operands may be inserts - choose the correct side.369 370define <4 x float> @insert_insert_shuffle_translate_commute(float %x1, float %x2, <4 x float> %q) {371; CHECK-LABEL: @insert_insert_shuffle_translate_commute(372; CHECK-NEXT: [[XV1:%.*]] = insertelement <4 x float> [[Q:%.*]], float [[X1:%.*]], i64 0373; CHECK-NEXT: [[R:%.*]] = insertelement <4 x float> [[XV1]], float [[X2:%.*]], i64 1374; CHECK-NEXT: ret <4 x float> [[R]]375;376 %xv1 = insertelement <4 x float> %q, float %x1, i32 0377 %xv2 = insertelement <4 x float> %q, float %x2, i32 2378 %r = shufflevector <4 x float> %xv1, <4 x float> %xv2, <4 x i32> <i32 0, i32 6, i32 2, i32 3>379 ret <4 x float> %r380}381 382; Negative test - this only works if the shuffle is choosing exactly 1 element from 1 of the inputs.383; TODO: But this could be a special-case because we're inserting into the same base vector.384 385define <4 x float> @insert_insert_shuffle_translate_wrong_mask(float %x1, float %x2, <4 x float> %q) {386; CHECK-LABEL: @insert_insert_shuffle_translate_wrong_mask(387; CHECK-NEXT: [[XV1:%.*]] = insertelement <4 x float> [[Q:%.*]], float [[X1:%.*]], i64 0388; CHECK-NEXT: [[XV2:%.*]] = insertelement <4 x float> [[Q]], float [[X2:%.*]], i64 2389; CHECK-NEXT: [[R:%.*]] = shufflevector <4 x float> [[XV1]], <4 x float> [[XV2]], <4 x i32> <i32 0, i32 6, i32 2, i32 7>390; CHECK-NEXT: ret <4 x float> [[R]]391;392 %xv1 = insertelement <4 x float> %q, float %x1, i32 0393 %xv2 = insertelement <4 x float> %q, float %x2, i32 2394 %r = shufflevector <4 x float> %xv1, <4 x float> %xv2, <4 x i32> <i32 0, i32 6, i32 2, i32 7>395 ret <4 x float> %r396}397 398; The insert may have other uses.399 400declare void @use(<4 x float>)401 402define <4 x float> @insert_not_undef_shuffle_translate_commute_uses(float %x, <4 x float> %y, <4 x float> %q) {403; CHECK-LABEL: @insert_not_undef_shuffle_translate_commute_uses(404; CHECK-NEXT: [[XV:%.*]] = insertelement <4 x float> [[Q:%.*]], float [[X:%.*]], i64 2405; CHECK-NEXT: call void @use(<4 x float> [[XV]])406; CHECK-NEXT: [[R:%.*]] = insertelement <4 x float> [[Y:%.*]], float [[X]], i64 0407; CHECK-NEXT: ret <4 x float> [[R]]408;409 %xv = insertelement <4 x float> %q, float %x, i32 2410 call void @use(<4 x float> %xv)411 %r = shufflevector <4 x float> %y, <4 x float> %xv, <4 x i32> <i32 6, i32 undef, i32 2, i32 3>412 ret <4 x float> %r413}414 415; Negative test - size-changing shuffle.416 417define <5 x float> @insert_not_undef_shuffle_translate_commute_lengthen(float %x, <4 x float> %y, <4 x float> %q) {418; CHECK-LABEL: @insert_not_undef_shuffle_translate_commute_lengthen(419; CHECK-NEXT: [[XV:%.*]] = insertelement <4 x float> poison, float [[X:%.*]], i64 2420; CHECK-NEXT: [[R:%.*]] = shufflevector <4 x float> [[Y:%.*]], <4 x float> [[XV]], <5 x i32> <i32 0, i32 6, i32 2, i32 poison, i32 poison>421; CHECK-NEXT: ret <5 x float> [[R]]422;423 %xv = insertelement <4 x float> %q, float %x, i32 2424 %r = shufflevector <4 x float> %y, <4 x float> %xv, <5 x i32> <i32 0, i32 6, i32 2, i32 undef, i32 undef>425 ret <5 x float> %r426}427 428define <4 x float> @insert_nonzero_index_splat(float %x) {429; CHECK-LABEL: @insert_nonzero_index_splat(430; CHECK-NEXT: [[TMP1:%.*]] = insertelement <4 x float> poison, float [[X:%.*]], i64 0431; CHECK-NEXT: [[SPLAT:%.*]] = shufflevector <4 x float> [[TMP1]], <4 x float> poison, <4 x i32> <i32 poison, i32 0, i32 0, i32 poison>432; CHECK-NEXT: ret <4 x float> [[SPLAT]]433;434 %xv = insertelement <4 x float> undef, float %x, i32 2435 %splat = shufflevector <4 x float> %xv, <4 x float> undef, <4 x i32> <i32 undef, i32 2, i32 2, i32 undef>436 ret <4 x float> %splat437}438 439define <3 x double> @insert_nonzero_index_splat_narrow(double %x) {440; CHECK-LABEL: @insert_nonzero_index_splat_narrow(441; CHECK-NEXT: [[TMP1:%.*]] = insertelement <3 x double> poison, double [[X:%.*]], i64 0442; CHECK-NEXT: [[SPLAT:%.*]] = shufflevector <3 x double> [[TMP1]], <3 x double> poison, <3 x i32> <i32 0, i32 poison, i32 0>443; CHECK-NEXT: ret <3 x double> [[SPLAT]]444;445 %xv = insertelement <4 x double> undef, double %x, i32 3446 %splat = shufflevector <4 x double> %xv, <4 x double> undef, <3 x i32> <i32 3, i32 undef, i32 3>447 ret <3 x double> %splat448}449 450define <5 x i7> @insert_nonzero_index_splat_widen(i7 %x) {451; CHECK-LABEL: @insert_nonzero_index_splat_widen(452; CHECK-NEXT: [[TMP1:%.*]] = insertelement <5 x i7> poison, i7 [[X:%.*]], i64 0453; CHECK-NEXT: [[SPLAT:%.*]] = shufflevector <5 x i7> [[TMP1]], <5 x i7> poison, <5 x i32> <i32 poison, i32 0, i32 0, i32 poison, i32 0>454; CHECK-NEXT: ret <5 x i7> [[SPLAT]]455;456 %xv = insertelement <4 x i7> undef, i7 %x, i32 1457 %splat = shufflevector <4 x i7> %xv, <4 x i7> undef, <5 x i32> <i32 undef, i32 1, i32 1, i32 undef, i32 1>458 ret <5 x i7> %splat459}460 461; Negative test - don't increase instruction count462 463define <4 x float> @insert_nonzero_index_splat_extra_use(float %x) {464; CHECK-LABEL: @insert_nonzero_index_splat_extra_use(465; CHECK-NEXT: [[XV:%.*]] = insertelement <4 x float> <float undef, float undef, float poison, float undef>, float [[X:%.*]], i64 2466; CHECK-NEXT: call void @use(<4 x float> [[XV]])467; CHECK-NEXT: [[SPLAT:%.*]] = shufflevector <4 x float> [[XV]], <4 x float> poison, <4 x i32> <i32 poison, i32 2, i32 2, i32 poison>468; CHECK-NEXT: ret <4 x float> [[SPLAT]]469;470 %xv = insertelement <4 x float> undef, float %x, i32 2471 call void @use(<4 x float> %xv)472 %splat = shufflevector <4 x float> %xv, <4 x float> undef, <4 x i32> <i32 undef, i32 2, i32 2, i32 undef>473 ret <4 x float> %splat474}475 476; Negative test - non-undef base vector477 478define <4 x float> @insert_nonzero_index_splat_wrong_base(float %x, <4 x float> %y) {479; CHECK-LABEL: @insert_nonzero_index_splat_wrong_base(480; CHECK-NEXT: [[XV:%.*]] = insertelement <4 x float> [[Y:%.*]], float [[X:%.*]], i64 2481; CHECK-NEXT: [[SPLAT:%.*]] = shufflevector <4 x float> [[XV]], <4 x float> poison, <4 x i32> <i32 poison, i32 2, i32 3, i32 poison>482; CHECK-NEXT: ret <4 x float> [[SPLAT]]483;484 %xv = insertelement <4 x float> %y, float %x, i32 2485 %splat = shufflevector <4 x float> %xv, <4 x float> undef, <4 x i32> <i32 undef, i32 2, i32 3, i32 undef>486 ret <4 x float> %splat487}488 489; Negative test - non-constant insert index490 491define <4 x float> @insert_nonzero_index_splat_wrong_index(float %x, i32 %index) {492; CHECK-LABEL: @insert_nonzero_index_splat_wrong_index(493; CHECK-NEXT: [[XV:%.*]] = insertelement <4 x float> <float poison, float undef, float poison, float poison>, float [[X:%.*]], i32 [[INDEX:%.*]]494; CHECK-NEXT: [[SPLAT:%.*]] = shufflevector <4 x float> [[XV]], <4 x float> poison, <4 x i32> <i32 poison, i32 1, i32 1, i32 poison>495; CHECK-NEXT: ret <4 x float> [[SPLAT]]496;497 %xv = insertelement <4 x float> undef, float %x, i32 %index498 %splat = shufflevector <4 x float> %xv, <4 x float> undef, <4 x i32> <i32 undef, i32 1, i32 1, i32 undef>499 ret <4 x float> %splat500}501 502define <4 x float> @insert_in_splat(float %x) {503; CHECK-LABEL: @insert_in_splat(504; CHECK-NEXT: [[XV:%.*]] = insertelement <4 x float> poison, float [[X:%.*]], i64 0505; CHECK-NEXT: [[R:%.*]] = shufflevector <4 x float> [[XV]], <4 x float> poison, <4 x i32> <i32 poison, i32 0, i32 0, i32 0>506; CHECK-NEXT: ret <4 x float> [[R]]507;508 %xv = insertelement <4 x float> undef, float %x, i32 0509 %splat = shufflevector <4 x float> %xv, <4 x float> undef, <4 x i32> <i32 undef, i32 0, i32 0, i32 undef>510 %r = insertelement <4 x float> %splat, float %x, i32 3511 ret <4 x float> %r512}513 514define <4 x float> @insert_in_splat_extra_uses(float %x) {515; CHECK-LABEL: @insert_in_splat_extra_uses(516; CHECK-NEXT: [[XV:%.*]] = insertelement <4 x float> <float poison, float undef, float undef, float undef>, float [[X:%.*]], i64 0517; CHECK-NEXT: call void @use(<4 x float> [[XV]])518; CHECK-NEXT: [[SPLAT:%.*]] = shufflevector <4 x float> [[XV]], <4 x float> poison, <4 x i32> <i32 poison, i32 0, i32 0, i32 poison>519; CHECK-NEXT: call void @use(<4 x float> [[SPLAT]])520; CHECK-NEXT: [[R:%.*]] = shufflevector <4 x float> [[XV]], <4 x float> poison, <4 x i32> <i32 poison, i32 0, i32 0, i32 0>521; CHECK-NEXT: ret <4 x float> [[R]]522;523 %xv = insertelement <4 x float> undef, float %x, i32 0524 call void @use(<4 x float> %xv)525 %splat = shufflevector <4 x float> %xv, <4 x float> undef, <4 x i32> <i32 undef, i32 0, i32 0, i32 undef>526 call void @use(<4 x float> %splat)527 %r = insertelement <4 x float> %splat, float %x, i32 3528 ret <4 x float> %r529}530 531; Negative test - not a constant index insert532 533define <4 x float> @insert_in_splat_variable_index(float %x, i32 %y) {534; CHECK-LABEL: @insert_in_splat_variable_index(535; CHECK-NEXT: [[XV:%.*]] = insertelement <4 x float> poison, float [[X:%.*]], i64 0536; CHECK-NEXT: [[SPLAT:%.*]] = shufflevector <4 x float> [[XV]], <4 x float> poison, <4 x i32> <i32 poison, i32 0, i32 0, i32 poison>537; CHECK-NEXT: [[R:%.*]] = insertelement <4 x float> [[SPLAT]], float [[X]], i32 [[Y:%.*]]538; CHECK-NEXT: ret <4 x float> [[R]]539;540 %xv = insertelement <4 x float> undef, float %x, i32 0541 %splat = shufflevector <4 x float> %xv, <4 x float> undef, <4 x i32> <i32 undef, i32 0, i32 0, i32 undef>542 %r = insertelement <4 x float> %splat, float %x, i32 %y543 ret <4 x float> %r544}545 546; Negative test - not a splat shuffle547 548define <4 x float> @insert_in_nonsplat(float %x, <4 x float> %y) {549; CHECK-LABEL: @insert_in_nonsplat(550; CHECK-NEXT: [[XV:%.*]] = insertelement <4 x float> poison, float [[X:%.*]], i64 0551; CHECK-NEXT: [[SPLAT:%.*]] = shufflevector <4 x float> [[XV]], <4 x float> [[Y:%.*]], <4 x i32> <i32 poison, i32 0, i32 4, i32 poison>552; CHECK-NEXT: [[R:%.*]] = insertelement <4 x float> [[SPLAT]], float [[X]], i64 3553; CHECK-NEXT: ret <4 x float> [[R]]554;555 %xv = insertelement <4 x float> undef, float %x, i32 0556 %splat = shufflevector <4 x float> %xv, <4 x float> %y, <4 x i32> <i32 undef, i32 0, i32 4, i32 undef>557 %r = insertelement <4 x float> %splat, float %x, i32 3558 ret <4 x float> %r559}560 561; Negative test - not a splat shuffle562 563define <4 x float> @insert_in_nonsplat2(float %x, <4 x float> %y) {564; CHECK-LABEL: @insert_in_nonsplat2(565; CHECK-NEXT: [[XV:%.*]] = insertelement <4 x float> [[Y:%.*]], float [[X:%.*]], i64 0566; CHECK-NEXT: [[SPLAT:%.*]] = shufflevector <4 x float> [[XV]], <4 x float> poison, <4 x i32> <i32 poison, i32 0, i32 1, i32 poison>567; CHECK-NEXT: [[R:%.*]] = insertelement <4 x float> [[SPLAT]], float [[X]], i64 3568; CHECK-NEXT: ret <4 x float> [[R]]569;570 %xv = insertelement <4 x float> %y, float %x, i32 0571 %splat = shufflevector <4 x float> %xv, <4 x float> undef, <4 x i32> <i32 undef, i32 0, i32 1, i32 undef>572 %r = insertelement <4 x float> %splat, float %x, i32 3573 ret <4 x float> %r574}575 576define <4 x i8> @shuf_identity_padding(<2 x i8> %x, i8 %y) {577; CHECK-LABEL: @shuf_identity_padding(578; CHECK-NEXT: [[V1:%.*]] = shufflevector <2 x i8> [[X:%.*]], <2 x i8> poison, <4 x i32> <i32 0, i32 1, i32 poison, i32 poison>579; CHECK-NEXT: [[V2:%.*]] = insertelement <4 x i8> [[V1]], i8 [[Y:%.*]], i64 2580; CHECK-NEXT: ret <4 x i8> [[V2]]581;582 %v0 = shufflevector <2 x i8> %x, <2 x i8> undef, <4 x i32> <i32 0, i32 1, i32 undef, i32 undef>583 %x1 = extractelement <2 x i8> %x, i32 1584 %v1 = insertelement <4 x i8> %v0, i8 %x1, i32 1585 %v2 = insertelement <4 x i8> %v1, i8 %y, i32 2586 ret <4 x i8> %v2587}588 589define <3 x i8> @shuf_identity_extract(<4 x i8> %x, i8 %y) {590; CHECK-LABEL: @shuf_identity_extract(591; CHECK-NEXT: [[V1:%.*]] = shufflevector <4 x i8> [[X:%.*]], <4 x i8> poison, <3 x i32> <i32 0, i32 1, i32 poison>592; CHECK-NEXT: [[V2:%.*]] = insertelement <3 x i8> [[V1]], i8 [[Y:%.*]], i64 2593; CHECK-NEXT: ret <3 x i8> [[V2]]594;595 %v0 = shufflevector <4 x i8> %x, <4 x i8> undef, <3 x i32> <i32 0, i32 undef, i32 undef>596 %x1 = extractelement <4 x i8> %x, i32 1597 %v1 = insertelement <3 x i8> %v0, i8 %x1, i32 1598 %v2 = insertelement <3 x i8> %v1, i8 %y, i32 2599 ret <3 x i8> %v2600}601 602define <4 x float> @shuf_identity_extract_extra_use(<6 x float> %x, float %y) {603; CHECK-LABEL: @shuf_identity_extract_extra_use(604; CHECK-NEXT: [[V0:%.*]] = shufflevector <6 x float> [[X:%.*]], <6 x float> poison, <4 x i32> <i32 0, i32 poison, i32 poison, i32 3>605; CHECK-NEXT: call void @use(<4 x float> [[V0]])606; CHECK-NEXT: [[V1:%.*]] = shufflevector <6 x float> [[X]], <6 x float> poison, <4 x i32> <i32 0, i32 poison, i32 2, i32 3>607; CHECK-NEXT: [[V2:%.*]] = insertelement <4 x float> [[V1]], float [[Y:%.*]], i64 1608; CHECK-NEXT: ret <4 x float> [[V2]]609;610 %v0 = shufflevector <6 x float> %x, <6 x float> undef, <4 x i32> <i32 0, i32 undef, i32 undef, i32 3>611 call void @use(<4 x float> %v0)612 %x1 = extractelement <6 x float> %x, i32 2613 %v1 = insertelement <4 x float> %v0, float %x1, i32 2614 %v2 = insertelement <4 x float> %v1, float %y, i32 1615 ret <4 x float> %v2616}617 618; Negative test - can't map variable index to shuffle mask.619 620define <4 x i8> @shuf_identity_padding_variable_index(<2 x i8> %x, i8 %y, i32 %index) {621; CHECK-LABEL: @shuf_identity_padding_variable_index(622; CHECK-NEXT: [[V0:%.*]] = shufflevector <2 x i8> [[X:%.*]], <2 x i8> poison, <4 x i32> <i32 0, i32 1, i32 poison, i32 poison>623; CHECK-NEXT: [[X1:%.*]] = extractelement <2 x i8> [[X]], i32 [[INDEX:%.*]]624; CHECK-NEXT: [[V1:%.*]] = insertelement <4 x i8> [[V0]], i8 [[X1]], i32 [[INDEX]]625; CHECK-NEXT: [[V2:%.*]] = insertelement <4 x i8> [[V1]], i8 [[Y:%.*]], i64 2626; CHECK-NEXT: ret <4 x i8> [[V2]]627;628 %v0 = shufflevector <2 x i8> %x, <2 x i8> undef, <4 x i32> <i32 0, i32 1, i32 undef, i32 undef>629 %x1 = extractelement <2 x i8> %x, i32 %index630 %v1 = insertelement <4 x i8> %v0, i8 %x1, i32 %index631 %v2 = insertelement <4 x i8> %v1, i8 %y, i32 2632 ret <4 x i8> %v2633}634 635; Negative test - don't create arbitrary shuffle masks.636 637define <4 x i8> @shuf_identity_padding_wrong_source_vec(<2 x i8> %x, i8 %y, <2 x i8> %other) {638; CHECK-LABEL: @shuf_identity_padding_wrong_source_vec(639; CHECK-NEXT: [[V0:%.*]] = shufflevector <2 x i8> [[X:%.*]], <2 x i8> poison, <4 x i32> <i32 0, i32 poison, i32 poison, i32 poison>640; CHECK-NEXT: [[X1:%.*]] = extractelement <2 x i8> [[OTHER:%.*]], i64 1641; CHECK-NEXT: [[V1:%.*]] = insertelement <4 x i8> [[V0]], i8 [[X1]], i64 1642; CHECK-NEXT: [[V2:%.*]] = insertelement <4 x i8> [[V1]], i8 [[Y:%.*]], i64 2643; CHECK-NEXT: ret <4 x i8> [[V2]]644;645 %v0 = shufflevector <2 x i8> %x, <2 x i8> undef, <4 x i32> <i32 0, i32 1, i32 undef, i32 undef>646 %x1 = extractelement <2 x i8> %other, i32 1647 %v1 = insertelement <4 x i8> %v0, i8 %x1, i32 1648 %v2 = insertelement <4 x i8> %v1, i8 %y, i32 2649 ret <4 x i8> %v2650}651 652; Negative test - don't create arbitrary shuffle masks.653 654define <4 x i8> @shuf_identity_padding_wrong_index(<2 x i8> %x, i8 %y) {655; CHECK-LABEL: @shuf_identity_padding_wrong_index(656; CHECK-NEXT: [[V0:%.*]] = shufflevector <2 x i8> [[X:%.*]], <2 x i8> poison, <4 x i32> <i32 0, i32 1, i32 poison, i32 poison>657; CHECK-NEXT: [[X1:%.*]] = extractelement <2 x i8> [[X]], i64 1658; CHECK-NEXT: [[V1:%.*]] = insertelement <4 x i8> [[V0]], i8 [[X1]], i64 2659; CHECK-NEXT: [[V2:%.*]] = insertelement <4 x i8> [[V1]], i8 [[Y:%.*]], i64 3660; CHECK-NEXT: ret <4 x i8> [[V2]]661;662 %v0 = shufflevector <2 x i8> %x, <2 x i8> undef, <4 x i32> <i32 0, i32 1, i32 undef, i32 undef>663 %x1 = extractelement <2 x i8> %x, i32 1664 %v1 = insertelement <4 x i8> %v0, i8 %x1, i32 2665 %v2 = insertelement <4 x i8> %v1, i8 %y, i32 3666 ret <4 x i8> %v2667}668 669define <4 x float> @insert_undemanded_element_op0(<4 x float> %x, <4 x float> %y) {670; CHECK-LABEL: @insert_undemanded_element_op0(671; CHECK-NEXT: [[INS:%.*]] = insertelement <4 x float> [[X:%.*]], float 4.200000e+01, i64 3672; CHECK-NEXT: call void @use(<4 x float> [[INS]])673; CHECK-NEXT: [[S:%.*]] = shufflevector <4 x float> [[X]], <4 x float> [[Y:%.*]], <4 x i32> <i32 0, i32 7, i32 1, i32 4>674; CHECK-NEXT: ret <4 x float> [[S]]675;676 %ins = insertelement <4 x float> %x, float 42.0, i32 3677 call void @use(<4 x float> %ins)678 %s = shufflevector <4 x float> %ins, <4 x float> %y, <4 x i32> <i32 0, i32 7, i32 1, i32 4>679 ret <4 x float> %s680}681 682define <4 x float> @insert_undemanded_element_op1(<4 x float> %x, <4 x float> %y) {683; CHECK-LABEL: @insert_undemanded_element_op1(684; CHECK-NEXT: [[INS:%.*]] = insertelement <4 x float> [[X:%.*]], float 4.200000e+01, i64 3685; CHECK-NEXT: call void @use(<4 x float> [[INS]])686; CHECK-NEXT: [[S:%.*]] = shufflevector <4 x float> [[Y:%.*]], <4 x float> [[X]], <4 x i32> <i32 3, i32 2, i32 1, i32 4>687; CHECK-NEXT: ret <4 x float> [[S]]688;689 %ins = insertelement <4 x float> %x, float 42.0, i32 3690 call void @use(<4 x float> %ins)691 %s = shufflevector <4 x float> %y, <4 x float> %ins, <4 x i32> <i32 3, i32 2, i32 1, i32 4>692 ret <4 x float> %s693}694 695define <5 x float> @insert_undemanded_element_unequal_length_op0(<4 x float> %x, <4 x float> %y) {696; CHECK-LABEL: @insert_undemanded_element_unequal_length_op0(697; CHECK-NEXT: [[INS:%.*]] = insertelement <4 x float> [[X:%.*]], float 4.200000e+01, i64 3698; CHECK-NEXT: call void @use(<4 x float> [[INS]])699; CHECK-NEXT: [[S:%.*]] = shufflevector <4 x float> [[X]], <4 x float> [[Y:%.*]], <5 x i32> <i32 poison, i32 0, i32 7, i32 1, i32 4>700; CHECK-NEXT: ret <5 x float> [[S]]701;702 %ins = insertelement <4 x float> %x, float 42.0, i32 3703 call void @use(<4 x float> %ins)704 %s = shufflevector <4 x float> %ins, <4 x float> %y, <5 x i32> <i32 undef, i32 0, i32 7, i32 1, i32 4>705 ret <5 x float> %s706}707 708define <5 x float> @insert_undemanded_element_unequal_length_op1(<4 x float> %x, <4 x float> %y) {709; CHECK-LABEL: @insert_undemanded_element_unequal_length_op1(710; CHECK-NEXT: [[INS:%.*]] = insertelement <4 x float> [[X:%.*]], float 4.200000e+01, i64 3711; CHECK-NEXT: call void @use(<4 x float> [[INS]])712; CHECK-NEXT: [[S:%.*]] = shufflevector <4 x float> [[Y:%.*]], <4 x float> [[X]], <5 x i32> <i32 poison, i32 3, i32 2, i32 1, i32 4>713; CHECK-NEXT: ret <5 x float> [[S]]714;715 %ins = insertelement <4 x float> %x, float 42.0, i32 3716 call void @use(<4 x float> %ins)717 %s = shufflevector <4 x float> %y, <4 x float> %ins, <5 x i32> <i32 undef, i32 3, i32 2, i32 1, i32 4>718 ret <5 x float> %s719}720 721; Negative test - shuffle chooses the inserted constant.722 723define <4 x float> @insert_demanded_element_op0(<4 x float> %x, <4 x float> %y) {724; CHECK-LABEL: @insert_demanded_element_op0(725; CHECK-NEXT: [[INS:%.*]] = insertelement <4 x float> [[X:%.*]], float 4.200000e+01, i64 3726; CHECK-NEXT: call void @use(<4 x float> [[INS]])727; CHECK-NEXT: [[S:%.*]] = shufflevector <4 x float> [[INS]], <4 x float> [[Y:%.*]], <4 x i32> <i32 3, i32 2, i32 1, i32 4>728; CHECK-NEXT: ret <4 x float> [[S]]729;730 %ins = insertelement <4 x float> %x, float 42.0, i32 3731 call void @use(<4 x float> %ins)732 %s = shufflevector <4 x float> %ins, <4 x float> %y, <4 x i32> <i32 3, i32 2, i32 1, i32 4>733 ret <4 x float> %s734}735 736; Negative test - shuffle chooses the inserted constant.737 738define <4 x float> @insert_demanded_element_op1(<4 x float> %x, <4 x float> %y) {739; CHECK-LABEL: @insert_demanded_element_op1(740; CHECK-NEXT: [[INS:%.*]] = insertelement <4 x float> [[X:%.*]], float 4.300000e+01, i64 3741; CHECK-NEXT: call void @use(<4 x float> [[INS]])742; CHECK-NEXT: [[S:%.*]] = shufflevector <4 x float> [[Y:%.*]], <4 x float> [[INS]], <4 x i32> <i32 0, i32 7, i32 1, i32 4>743; CHECK-NEXT: ret <4 x float> [[S]]744;745 %ins = insertelement <4 x float> %x, float 43.0, i32 3746 call void @use(<4 x float> %ins)747 %s = shufflevector <4 x float> %y, <4 x float> %ins, <4 x i32> <i32 0, i32 7, i32 1, i32 4>748 ret <4 x float> %s749}750 751; Negative test - shuffle chooses the inserted constant.752 753define <5 x float> @insert_demanded_element_unequal_length_op0(<4 x float> %x, <4 x float> %y) {754; CHECK-LABEL: @insert_demanded_element_unequal_length_op0(755; CHECK-NEXT: [[INS:%.*]] = insertelement <4 x float> [[X:%.*]], float 4.200000e+01, i64 3756; CHECK-NEXT: call void @use(<4 x float> [[INS]])757; CHECK-NEXT: [[S:%.*]] = shufflevector <4 x float> [[INS]], <4 x float> [[Y:%.*]], <5 x i32> <i32 poison, i32 3, i32 2, i32 1, i32 4>758; CHECK-NEXT: ret <5 x float> [[S]]759;760 %ins = insertelement <4 x float> %x, float 42.0, i32 3761 call void @use(<4 x float> %ins)762 %s = shufflevector <4 x float> %ins, <4 x float> %y, <5 x i32> <i32 undef, i32 3, i32 2, i32 1, i32 4>763 ret <5 x float> %s764}765 766; Negative test - shuffle chooses the inserted constant.767 768define <5 x float> @insert_demanded_element_unequal_length_op1(<4 x float> %x, <4 x float> %y) {769; CHECK-LABEL: @insert_demanded_element_unequal_length_op1(770; CHECK-NEXT: [[INS:%.*]] = insertelement <4 x float> [[X:%.*]], float 4.300000e+01, i64 3771; CHECK-NEXT: call void @use(<4 x float> [[INS]])772; CHECK-NEXT: [[S:%.*]] = shufflevector <4 x float> [[Y:%.*]], <4 x float> [[INS]], <5 x i32> <i32 poison, i32 0, i32 7, i32 1, i32 4>773; CHECK-NEXT: ret <5 x float> [[S]]774;775 %ins = insertelement <4 x float> %x, float 43.0, i32 3776 call void @use(<4 x float> %ins)777 %s = shufflevector <4 x float> %y, <4 x float> %ins, <5 x i32> <i32 undef, i32 0, i32 7, i32 1, i32 4>778 ret <5 x float> %s779}780 781define <4 x float> @splat_constant(<4 x float> %x) {782; CHECK-LABEL: @splat_constant(783; CHECK-NEXT: [[INS3:%.*]] = insertelement <4 x float> [[X:%.*]], float 3.000000e+00, i64 3784; CHECK-NEXT: [[R:%.*]] = fadd <4 x float> [[INS3]], splat (float 3.000000e+00)785; CHECK-NEXT: ret <4 x float> [[R]]786;787 %ins3 = insertelement <4 x float> %x, float 3.0, i32 3788 %splat3 = shufflevector <4 x float> %ins3, <4 x float> undef, <4 x i32> <i32 3, i32 3, i32 3, i32 3>789 %r = fadd <4 x float> %ins3, %splat3790 ret <4 x float> %r791}792 793define <4 x i32> @infloop_D151807(<4 x float> %arg) {794; CHECK-LABEL: @infloop_D151807(795; CHECK-NEXT: [[I:%.*]] = shufflevector <4 x float> [[ARG:%.*]], <4 x float> poison, <2 x i32> <i32 2, i32 poison>796; CHECK-NEXT: [[I1:%.*]] = bitcast <2 x float> [[I]] to <2 x i32>797; CHECK-NEXT: [[TMP1:%.*]] = shufflevector <2 x i32> [[I1]], <2 x i32> poison, <4 x i32> <i32 0, i32 poison, i32 poison, i32 poison>798; CHECK-NEXT: [[I4:%.*]] = shufflevector <4 x i32> <i32 0, i32 poison, i32 poison, i32 poison>, <4 x i32> [[TMP1]], <4 x i32> <i32 4, i32 0, i32 0, i32 0>799; CHECK-NEXT: ret <4 x i32> [[I4]]800;801 %i = shufflevector <4 x float> %arg, <4 x float> poison, <2 x i32> <i32 2, i32 poison>802 %i1 = bitcast <2 x float> %i to <2 x i32>803 %i3 = extractelement <2 x i32> %i1, i64 0804 %i4 = insertelement <4 x i32> zeroinitializer, i32 %i3, i64 0805 ret <4 x i32> %i4806}807 808; Make sure we don't crash in this case.809 810define i64 @pr160507(ptr %arg, i32 %arg1, i1 %arg2, i8 %arg3, i64 %arg4) {811; CHECK-LABEL: @pr160507(812; CHECK-NEXT: bb:813; CHECK-NEXT: br label [[BB5:%.*]]814; CHECK: bb5:815; CHECK-NEXT: br i1 [[ARG2:%.*]], label [[BB6:%.*]], label [[BB8:%.*]]816; CHECK: bb6:817; CHECK-NEXT: br label [[BB5]]818; CHECK: bb8:819; CHECK-NEXT: br label [[BB10:%.*]]820; CHECK: bb10:821; CHECK-NEXT: br label [[BB12:%.*]]822; CHECK: bb12:823; CHECK-NEXT: store i64 0, ptr [[ARG:%.*]], align 8824; CHECK-NEXT: br label [[BB5]]825;826bb:827 br label %bb5828 829bb5:830 %phi = phi i8 [ 0, %bb ], [ %extractelement, %bb6 ], [ 0, %bb12 ]831 br i1 %arg2, label %bb6, label %bb8832 833bb6:834 %extractelement = extractelement <2 x i8> zeroinitializer, i64 %arg4835 br label %bb5836 837bb8:838 %insertelement9 = insertelement <2 x i8> <i8 poison, i8 0>, i8 %phi, i64 0839 %zext = zext <2 x i8> %insertelement9 to <2 x i64>840 %shufflevector = shufflevector <2 x i64> %zext, <2 x i64> poison, <4 x i32> <i32 poison, i32 1, i32 1, i32 1>841 br label %bb10842 843bb10:844 br label %bb12845 846bb12:847 %extractelement11 = extractelement <2 x i64> %zext, i64 1848 %insertelement13 = insertelement <4 x i64> %shufflevector, i64 %extractelement11, i64 0849 %extractelement14 = extractelement <4 x i64> %insertelement13, i32 %arg1850 store i64 %extractelement14, ptr %arg, align 8851 br label %bb5852}853