@@ -7397,7 +7397,7 @@ static bool planContainsAdditionalSimplifications(VPlan &Plan,
7397
7397
// VPExtendedReductionRecipe contains a folded extend instruction.
7398
7398
if (auto *ExtendedRed = dyn_cast<VPExtendedReductionRecipe>(&R))
7399
7399
SeenInstrs.insert (ExtendedRed->getExtInstr ());
7400
- // VPMulAccRecupe constians a mul and otional extend instructions.
7400
+ // VPMulAccRecipe constians a mul and otional extend instructions.
7401
7401
else if (auto *MulAcc = dyn_cast<VPMulAccRecipe>(&R)) {
7402
7402
SeenInstrs.insert (MulAcc->getMulInstr ());
7403
7403
if (MulAcc->isExtended ()) {
@@ -9390,77 +9390,82 @@ void LoopVectorizationPlanner::adjustRecipesForReductions(
9390
9390
if (CM.blockNeedsPredicationForAnyReason (BB))
9391
9391
CondOp = RecipeBuilder.getBlockInMask (BB);
9392
9392
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 ());
9427
9429
VPWidenRecipe *Mul =
9428
- cast <VPWidenRecipe>(Ext->getOperand (0 )->getDefiningRecipe ());
9430
+ dyn_cast <VPWidenRecipe>(Ext->getOperand (0 )->getDefiningRecipe ());
9429
9431
VPWidenCastRecipe *Ext0 =
9430
9432
cast<VPWidenCastRecipe>(Mul->getOperand (0 )->getDefiningRecipe ());
9431
9433
VPWidenCastRecipe *Ext1 =
9432
9434
cast<VPWidenCastRecipe>(Mul->getOperand (1 )->getDefiningRecipe ());
9433
9435
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 (
9436
9441
RdxDesc, CurrentLinkI, PreviousLink, CondOp,
9437
9442
CM.useOrderedReductions (RdxDesc),
9438
9443
cast<VPWidenCastRecipe>(VecOp->getDefiningRecipe ()), Mul,
9439
9444
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
+ }
9448
9446
}
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
9460
9466
RedRecipe =
9461
9467
new VPReductionRecipe (RdxDesc, CurrentLinkI, PreviousLink, VecOp,
9462
9468
CondOp, CM.useOrderedReductions (RdxDesc));
9463
- }
9464
9469
// Append the recipe to the end of the VPBasicBlock because we need to
9465
9470
// ensure that it comes after all of it's inputs, including CondOp.
9466
9471
// Note that this transformation may leave over dead recipes (including
0 commit comments