@@ -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 ()) {
@@ -9388,77 +9388,82 @@ void LoopVectorizationPlanner::adjustRecipesForReductions(
93889388 if (CM.blockNeedsPredicationForAnyReason (BB))
93899389 CondOp = RecipeBuilder.getBlockInMask (BB);
93909390
9391- VPValue *A, *B;
9392- VPSingleDefRecipe *RedRecipe;
9393- // reduce.add(mul(ext, ext)) can folded into VPMulAccRecipe
9394- if (RdxDesc.getOpcode () == Instruction::Add &&
9395- match (VecOp, m_Mul (m_VPValue (A), m_VPValue (B)))) {
9396- VPRecipeBase *RecipeA = A->getDefiningRecipe ();
9397- VPRecipeBase *RecipeB = B->getDefiningRecipe ();
9398- if (RecipeA && RecipeB && match (RecipeA, m_ZExtOrSExt (m_VPValue ())) &&
9399- match (RecipeB, m_ZExtOrSExt (m_VPValue ())) &&
9400- cast<VPWidenCastRecipe>(RecipeA)->getOpcode () ==
9401- cast<VPWidenCastRecipe>(RecipeB)->getOpcode () &&
9402- !A->hasMoreThanOneUniqueUser () && !B->hasMoreThanOneUniqueUser ()) {
9403- RedRecipe = new VPMulAccRecipe (
9404- RdxDesc, CurrentLinkI, PreviousLink, CondOp,
9405- CM.useOrderedReductions (RdxDesc),
9406- cast<VPWidenRecipe>(VecOp->getDefiningRecipe ()),
9407- cast<VPWidenCastRecipe>(RecipeA),
9408- cast<VPWidenCastRecipe>(RecipeB));
9409- } else {
9410- RedRecipe = new VPMulAccRecipe (
9411- RdxDesc, CurrentLinkI, PreviousLink, CondOp,
9412- CM.useOrderedReductions (RdxDesc),
9413- cast<VPWidenRecipe>(VecOp->getDefiningRecipe ()));
9414- }
9415- } else if (RdxDesc.getOpcode () == Instruction::Add &&
9416- match (VecOp,
9417- m_ZExtOrSExt (m_Mul (m_ZExtOrSExt (m_VPValue (A)),
9418- m_ZExtOrSExt (m_VPValue (B)))))) {
9419- VPWidenCastRecipe *Ext =
9420- dyn_cast<VPWidenCastRecipe>(VecOp->getDefiningRecipe ());
9421- VPWidenRecipe *Mul =
9422- dyn_cast<VPWidenRecipe>(Ext->getOperand (0 )->getDefiningRecipe ());
9423- if (Mul && match (Mul, m_Mul (m_ZExtOrSExt (m_VPValue ()),
9424- m_ZExtOrSExt (m_VPValue ())))) {
9391+ auto TryToMatchMulAcc = [&]() -> VPSingleDefRecipe * {
9392+ VPValue *A, *B;
9393+ if (RdxDesc.getOpcode () != Instruction::Add)
9394+ return nullptr ;
9395+ // reduce.add(mul(ext, ext)) can folded into VPMulAccRecipe
9396+ if (match (VecOp, m_Mul (m_VPValue (A), m_VPValue (B))) &&
9397+ !VecOp->hasMoreThanOneUniqueUser ()) {
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 () &&
9405+ !B->hasMoreThanOneUniqueUser ()) {
9406+ return new VPMulAccRecipe (
9407+ RdxDesc, CurrentLinkI, PreviousLink, CondOp,
9408+ CM.useOrderedReductions (RdxDesc),
9409+ cast<VPWidenRecipe>(VecOp->getDefiningRecipe ()),
9410+ cast<VPWidenCastRecipe>(RecipeA),
9411+ cast<VPWidenCastRecipe>(RecipeB));
9412+ } else {
9413+ // Matched reduce.add(mul(...))
9414+ return new VPMulAccRecipe (
9415+ RdxDesc, CurrentLinkI, PreviousLink, CondOp,
9416+ CM.useOrderedReductions (RdxDesc),
9417+ cast<VPWidenRecipe>(VecOp->getDefiningRecipe ()));
9418+ }
9419+ // Matched reduce.add(ext(mul(ext, ext)))
9420+ // Note that 3 extend instructions must have same opcode.
9421+ } else if (match (VecOp,
9422+ m_ZExtOrSExt (m_Mul (m_ZExtOrSExt (m_VPValue ()),
9423+ m_ZExtOrSExt (m_VPValue ())))) &&
9424+ !VecOp->hasMoreThanOneUniqueUser ()) {
9425+ VPWidenCastRecipe *Ext =
9426+ dyn_cast<VPWidenCastRecipe>(VecOp->getDefiningRecipe ());
94259427 VPWidenRecipe *Mul =
9426- cast <VPWidenRecipe>(Ext->getOperand (0 )->getDefiningRecipe ());
9428+ dyn_cast <VPWidenRecipe>(Ext->getOperand (0 )->getDefiningRecipe ());
94279429 VPWidenCastRecipe *Ext0 =
94289430 cast<VPWidenCastRecipe>(Mul->getOperand (0 )->getDefiningRecipe ());
94299431 VPWidenCastRecipe *Ext1 =
94309432 cast<VPWidenCastRecipe>(Mul->getOperand (1 )->getDefiningRecipe ());
94319433 if (Ext->getOpcode () == Ext0->getOpcode () &&
9432- Ext0->getOpcode () == Ext1->getOpcode ()) {
9433- RedRecipe = new VPMulAccRecipe (
9434+ Ext0->getOpcode () == Ext1->getOpcode () &&
9435+ !Mul->hasMoreThanOneUniqueUser () &&
9436+ !Ext0->hasMoreThanOneUniqueUser () &&
9437+ !Ext1->hasMoreThanOneUniqueUser ()) {
9438+ return new VPMulAccRecipe (
94349439 RdxDesc, CurrentLinkI, PreviousLink, CondOp,
94359440 CM.useOrderedReductions (RdxDesc),
94369441 cast<VPWidenCastRecipe>(VecOp->getDefiningRecipe ()), Mul,
94379442 cast<VPWidenCastRecipe>(Ext0), cast<VPWidenCastRecipe>(Ext1));
9438- } else
9439- RedRecipe = new VPExtendedReductionRecipe (
9440- RdxDesc, CurrentLinkI,
9441- cast<CastInst>(
9442- cast<VPWidenCastRecipe>(VecOp)->getUnderlyingInstr ()),
9443- PreviousLink, cast<VPWidenCastRecipe>(VecOp)->getOperand (0 ),
9444- CondOp, CM.useOrderedReductions (RdxDesc),
9445- cast<VPWidenCastRecipe>(VecOp)->getResultType ());
9443+ }
94469444 }
9447- }
9448- // VPWidenCastRecipes can folded into VPReductionRecipe
9449- else if (match (VecOp, m_ZExtOrSExt (m_VPValue (A))) &&
9450- !VecOp->hasMoreThanOneUniqueUser ()) {
9451- RedRecipe = new VPExtendedReductionRecipe (
9452- RdxDesc, CurrentLinkI,
9453- cast<CastInst>(
9454- cast<VPWidenCastRecipe>(VecOp)->getUnderlyingInstr ()),
9455- PreviousLink, A, CondOp, CM.useOrderedReductions (RdxDesc),
9456- cast<VPWidenCastRecipe>(VecOp)->getResultType ());
9457- } else {
9445+ return nullptr ;
9446+ };
9447+ auto TryToMatchExtendedReduction = [&]() -> VPSingleDefRecipe * {
9448+ VPValue *A;
9449+ if (match (VecOp, m_ZExtOrSExt (m_VPValue (A))) &&
9450+ !VecOp->hasMoreThanOneUniqueUser ()) {
9451+ return new VPExtendedReductionRecipe (
9452+ RdxDesc, CurrentLinkI, PreviousLink,
9453+ cast<VPWidenCastRecipe>(VecOp), CondOp,
9454+ CM.useOrderedReductions (RdxDesc));
9455+ }
9456+ return nullptr ;
9457+ };
9458+ VPSingleDefRecipe *RedRecipe;
9459+ if (auto *MulAcc = TryToMatchMulAcc ())
9460+ RedRecipe = MulAcc;
9461+ else if (auto *ExtendedRed = TryToMatchExtendedReduction ())
9462+ RedRecipe = ExtendedRed;
9463+ else
94589464 RedRecipe =
94599465 new VPReductionRecipe (RdxDesc, CurrentLinkI, PreviousLink, VecOp,
94609466 CondOp, CM.useOrderedReductions (RdxDesc));
9461- }
94629467 // Append the recipe to the end of the VPBasicBlock because we need to
94639468 // ensure that it comes after all of it's inputs, including CondOp.
94649469 // Note that this transformation may leave over dead recipes (including
0 commit comments