@@ -7397,7 +7397,7 @@ static bool planContainsAdditionalSimplifications(VPlan &Plan,
73977397 // VPExtendedReductionRecipe contains a folded extend instruction.
73987398 if (auto *ExtendedRed = dyn_cast<VPExtendedReductionRecipe>(&R))
73997399 SeenInstrs.insert (ExtendedRed->getExtInstr ());
7400- // VPMulAccRecupe constians a mul and otional extend instructions.
7400+ // VPMulAccRecipe constians a mul and otional extend instructions.
74017401 else if (auto *MulAcc = dyn_cast<VPMulAccRecipe>(&R)) {
74027402 SeenInstrs.insert (MulAcc->getMulInstr ());
74037403 if (MulAcc->isExtended ()) {
@@ -9390,77 +9390,82 @@ void LoopVectorizationPlanner::adjustRecipesForReductions(
93909390 if (CM.blockNeedsPredicationForAnyReason (BB))
93919391 CondOp = RecipeBuilder.getBlockInMask (BB);
93929392
9393- VPValue *A, *B;
9394- VPSingleDefRecipe *RedRecipe;
9395- // reduce.add(mul(ext, ext)) can folded into VPMulAccRecipe
9396- if (RdxDesc.getOpcode () == Instruction::Add &&
9397- match (VecOp, m_Mul (m_VPValue (A), m_VPValue (B)))) {
9398- VPRecipeBase *RecipeA = A->getDefiningRecipe ();
9399- VPRecipeBase *RecipeB = B->getDefiningRecipe ();
9400- if (RecipeA && RecipeB && match (RecipeA, m_ZExtOrSExt (m_VPValue ())) &&
9401- match (RecipeB, m_ZExtOrSExt (m_VPValue ())) &&
9402- cast<VPWidenCastRecipe>(RecipeA)->getOpcode () ==
9403- cast<VPWidenCastRecipe>(RecipeB)->getOpcode () &&
9404- !A->hasMoreThanOneUniqueUser () && !B->hasMoreThanOneUniqueUser ()) {
9405- RedRecipe = new VPMulAccRecipe (
9406- RdxDesc, CurrentLinkI, PreviousLink, CondOp,
9407- CM.useOrderedReductions (RdxDesc),
9408- cast<VPWidenRecipe>(VecOp->getDefiningRecipe ()),
9409- cast<VPWidenCastRecipe>(RecipeA),
9410- cast<VPWidenCastRecipe>(RecipeB));
9411- } else {
9412- RedRecipe = new VPMulAccRecipe (
9413- RdxDesc, CurrentLinkI, PreviousLink, CondOp,
9414- CM.useOrderedReductions (RdxDesc),
9415- cast<VPWidenRecipe>(VecOp->getDefiningRecipe ()));
9416- }
9417- } else if (RdxDesc.getOpcode () == Instruction::Add &&
9418- match (VecOp,
9419- m_ZExtOrSExt (m_Mul (m_ZExtOrSExt (m_VPValue (A)),
9420- m_ZExtOrSExt (m_VPValue (B)))))) {
9421- VPWidenCastRecipe *Ext =
9422- dyn_cast<VPWidenCastRecipe>(VecOp->getDefiningRecipe ());
9423- VPWidenRecipe *Mul =
9424- dyn_cast<VPWidenRecipe>(Ext->getOperand (0 )->getDefiningRecipe ());
9425- if (Mul && match (Mul, m_Mul (m_ZExtOrSExt (m_VPValue ()),
9426- m_ZExtOrSExt (m_VPValue ())))) {
9393+ auto TryToMatchMulAcc = [&]() -> VPSingleDefRecipe * {
9394+ VPValue *A, *B;
9395+ if (RdxDesc.getOpcode () != Instruction::Add)
9396+ return nullptr ;
9397+ // reduce.add(mul(ext, ext)) can folded into VPMulAccRecipe
9398+ if (match (VecOp, m_Mul (m_VPValue (A), m_VPValue (B))) &&
9399+ !VecOp->hasMoreThanOneUniqueUser ()) {
9400+ VPRecipeBase *RecipeA = A->getDefiningRecipe ();
9401+ VPRecipeBase *RecipeB = B->getDefiningRecipe ();
9402+ if (RecipeA && RecipeB && match (RecipeA, m_ZExtOrSExt (m_VPValue ())) &&
9403+ match (RecipeB, m_ZExtOrSExt (m_VPValue ())) &&
9404+ cast<VPWidenCastRecipe>(RecipeA)->getOpcode () ==
9405+ cast<VPWidenCastRecipe>(RecipeB)->getOpcode () &&
9406+ !A->hasMoreThanOneUniqueUser () &&
9407+ !B->hasMoreThanOneUniqueUser ()) {
9408+ return new VPMulAccRecipe (
9409+ RdxDesc, CurrentLinkI, PreviousLink, CondOp,
9410+ CM.useOrderedReductions (RdxDesc),
9411+ cast<VPWidenRecipe>(VecOp->getDefiningRecipe ()),
9412+ cast<VPWidenCastRecipe>(RecipeA),
9413+ cast<VPWidenCastRecipe>(RecipeB));
9414+ } else {
9415+ // Matched reduce.add(mul(...))
9416+ return new VPMulAccRecipe (
9417+ RdxDesc, CurrentLinkI, PreviousLink, CondOp,
9418+ CM.useOrderedReductions (RdxDesc),
9419+ cast<VPWidenRecipe>(VecOp->getDefiningRecipe ()));
9420+ }
9421+ // Matched reduce.add(ext(mul(ext, ext)))
9422+ // Note that 3 extend instructions must have same opcode.
9423+ } else if (match (VecOp,
9424+ m_ZExtOrSExt (m_Mul (m_ZExtOrSExt (m_VPValue ()),
9425+ m_ZExtOrSExt (m_VPValue ())))) &&
9426+ !VecOp->hasMoreThanOneUniqueUser ()) {
9427+ VPWidenCastRecipe *Ext =
9428+ dyn_cast<VPWidenCastRecipe>(VecOp->getDefiningRecipe ());
94279429 VPWidenRecipe *Mul =
9428- cast <VPWidenRecipe>(Ext->getOperand (0 )->getDefiningRecipe ());
9430+ dyn_cast <VPWidenRecipe>(Ext->getOperand (0 )->getDefiningRecipe ());
94299431 VPWidenCastRecipe *Ext0 =
94309432 cast<VPWidenCastRecipe>(Mul->getOperand (0 )->getDefiningRecipe ());
94319433 VPWidenCastRecipe *Ext1 =
94329434 cast<VPWidenCastRecipe>(Mul->getOperand (1 )->getDefiningRecipe ());
94339435 if (Ext->getOpcode () == Ext0->getOpcode () &&
9434- Ext0->getOpcode () == Ext1->getOpcode ()) {
9435- RedRecipe = new VPMulAccRecipe (
9436+ Ext0->getOpcode () == Ext1->getOpcode () &&
9437+ !Mul->hasMoreThanOneUniqueUser () &&
9438+ !Ext0->hasMoreThanOneUniqueUser () &&
9439+ !Ext1->hasMoreThanOneUniqueUser ()) {
9440+ return new VPMulAccRecipe (
94369441 RdxDesc, CurrentLinkI, PreviousLink, CondOp,
94379442 CM.useOrderedReductions (RdxDesc),
94389443 cast<VPWidenCastRecipe>(VecOp->getDefiningRecipe ()), Mul,
94399444 cast<VPWidenCastRecipe>(Ext0), cast<VPWidenCastRecipe>(Ext1));
9440- } else
9441- RedRecipe = new VPExtendedReductionRecipe (
9442- RdxDesc, CurrentLinkI,
9443- cast<CastInst>(
9444- cast<VPWidenCastRecipe>(VecOp)->getUnderlyingInstr ()),
9445- PreviousLink, cast<VPWidenCastRecipe>(VecOp)->getOperand (0 ),
9446- CondOp, CM.useOrderedReductions (RdxDesc),
9447- cast<VPWidenCastRecipe>(VecOp)->getResultType ());
9445+ }
94489446 }
9449- }
9450- // VPWidenCastRecipes can folded into VPReductionRecipe
9451- else if (match (VecOp, m_ZExtOrSExt (m_VPValue (A))) &&
9452- !VecOp->hasMoreThanOneUniqueUser ()) {
9453- RedRecipe = new VPExtendedReductionRecipe (
9454- RdxDesc, CurrentLinkI,
9455- cast<CastInst>(
9456- cast<VPWidenCastRecipe>(VecOp)->getUnderlyingInstr ()),
9457- PreviousLink, A, CondOp, CM.useOrderedReductions (RdxDesc),
9458- cast<VPWidenCastRecipe>(VecOp)->getResultType ());
9459- } else {
9447+ return nullptr ;
9448+ };
9449+ auto TryToMatchExtendedReduction = [&]() -> VPSingleDefRecipe * {
9450+ VPValue *A;
9451+ if (match (VecOp, m_ZExtOrSExt (m_VPValue (A))) &&
9452+ !VecOp->hasMoreThanOneUniqueUser ()) {
9453+ return new VPExtendedReductionRecipe (
9454+ RdxDesc, CurrentLinkI, PreviousLink,
9455+ cast<VPWidenCastRecipe>(VecOp), CondOp,
9456+ CM.useOrderedReductions (RdxDesc));
9457+ }
9458+ return nullptr ;
9459+ };
9460+ VPSingleDefRecipe *RedRecipe;
9461+ if (auto *MulAcc = TryToMatchMulAcc ())
9462+ RedRecipe = MulAcc;
9463+ else if (auto *ExtendedRed = TryToMatchExtendedReduction ())
9464+ RedRecipe = ExtendedRed;
9465+ else
94609466 RedRecipe =
94619467 new VPReductionRecipe (RdxDesc, CurrentLinkI, PreviousLink, VecOp,
94629468 CondOp, CM.useOrderedReductions (RdxDesc));
9463- }
94649469 // Append the recipe to the end of the VPBasicBlock because we need to
94659470 // ensure that it comes after all of it's inputs, including CondOp.
94669471 // Note that this transformation may leave over dead recipes (including
0 commit comments