@@ -466,25 +466,39 @@ void VPlanTransforms::unrollByUF(VPlan &Plan, unsigned UF) {
466466// / Create a single-scalar clone of \p DefR (must be a VPReplicateRecipe or
467467// / VPInstruction) for lane \p Lane. Use \p Def2LaneDefs to look up scalar
468468// / definitions for operands of \DefR.
469- static VPRecipeWithIRFlags *
469+ static VPValue *
470470cloneForLane (VPlan &Plan, VPBuilder &Builder, Type *IdxTy,
471471 VPRecipeWithIRFlags *DefR, VPLane Lane,
472472 const DenseMap<VPValue *, SmallVector<VPValue *>> &Def2LaneDefs) {
473+
474+ VPValue *Op;
475+ if (match (DefR, m_VPInstruction<VPInstruction::Unpack>(m_VPValue (Op)))) {
476+ auto LaneDefs = Def2LaneDefs.find (Op);
477+ if (LaneDefs != Def2LaneDefs.end ())
478+ return LaneDefs->second [Lane.getKnownLane ()];
479+
480+ VPValue *Idx =
481+ Plan.getOrAddLiveIn (ConstantInt::get (IdxTy, Lane.getKnownLane ()));
482+ return Builder.createNaryOp (Instruction::ExtractElement, {Op, Idx});
483+ }
484+
473485 // Collect the operands at Lane, creating extracts as needed.
474486 SmallVector<VPValue *> NewOps;
475487 for (VPValue *Op : DefR->operands ()) {
488+ if (Lane.getKind () == VPLane::Kind::ScalableLast) {
489+ match (Op, m_VPInstruction<VPInstruction::Unpack>(m_VPValue (Op)));
490+ NewOps.push_back (
491+ Builder.createNaryOp (VPInstruction::ExtractLastElement, {Op}));
492+ continue ;
493+ }
494+
476495 // If Op is a definition that has been unrolled, directly use the clone for
477496 // the corresponding lane.
478497 auto LaneDefs = Def2LaneDefs.find (Op);
479498 if (LaneDefs != Def2LaneDefs.end ()) {
480499 NewOps.push_back (LaneDefs->second [Lane.getKnownLane ()]);
481500 continue ;
482501 }
483- if (Lane.getKind () == VPLane::Kind::ScalableLast) {
484- NewOps.push_back (
485- Builder.createNaryOp (VPInstruction::ExtractLastElement, {Op}));
486- continue ;
487- }
488502 if (vputils::isSingleScalar (Op)) {
489503 NewOps.push_back (Op);
490504 continue ;
@@ -498,8 +512,8 @@ cloneForLane(VPlan &Plan, VPBuilder &Builder, Type *IdxTy,
498512 }
499513 VPValue *Idx =
500514 Plan.getOrAddLiveIn (ConstantInt::get (IdxTy, Lane.getKnownLane ()));
501- VPValue *Ext = Builder. createNaryOp (Instruction::ExtractElement, {Op, Idx});
502- NewOps. push_back (Ext );
515+ NewOps. push_back (
516+ Builder. createNaryOp (Instruction::ExtractElement, {Op, Idx}) );
503517 }
504518
505519 VPRecipeWithIRFlags *New;
@@ -548,7 +562,7 @@ void VPlanTransforms::replicateByVF(VPlan &Plan, ElementCount VF) {
548562 (isa<VPReplicateRecipe>(&R) &&
549563 cast<VPReplicateRecipe>(&R)->isSingleScalar ()) ||
550564 (isa<VPInstruction>(&R) &&
551- !cast<VPInstruction>(&R)->doesGeneratePerAllLanes ()))
565+ !cast<VPInstruction>(&R)->doesGeneratePerAllLanes () && cast<VPInstruction>(&R)-> getOpcode () != VPInstruction::Unpack ))
552566 continue ;
553567
554568 auto *DefR = cast<VPRecipeWithIRFlags>(&R);
0 commit comments