@@ -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 ()) {
@@ -9388,77 +9388,82 @@ void LoopVectorizationPlanner::adjustRecipesForReductions(
9388
9388
if (CM.blockNeedsPredicationForAnyReason (BB))
9389
9389
CondOp = RecipeBuilder.getBlockInMask (BB);
9390
9390
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 ());
9425
9427
VPWidenRecipe *Mul =
9426
- cast <VPWidenRecipe>(Ext->getOperand (0 )->getDefiningRecipe ());
9428
+ dyn_cast <VPWidenRecipe>(Ext->getOperand (0 )->getDefiningRecipe ());
9427
9429
VPWidenCastRecipe *Ext0 =
9428
9430
cast<VPWidenCastRecipe>(Mul->getOperand (0 )->getDefiningRecipe ());
9429
9431
VPWidenCastRecipe *Ext1 =
9430
9432
cast<VPWidenCastRecipe>(Mul->getOperand (1 )->getDefiningRecipe ());
9431
9433
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 (
9434
9439
RdxDesc, CurrentLinkI, PreviousLink, CondOp,
9435
9440
CM.useOrderedReductions (RdxDesc),
9436
9441
cast<VPWidenCastRecipe>(VecOp->getDefiningRecipe ()), Mul,
9437
9442
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
+ }
9446
9444
}
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
9458
9464
RedRecipe =
9459
9465
new VPReductionRecipe (RdxDesc, CurrentLinkI, PreviousLink, VecOp,
9460
9466
CondOp, CM.useOrderedReductions (RdxDesc));
9461
- }
9462
9467
// Append the recipe to the end of the VPBasicBlock because we need to
9463
9468
// ensure that it comes after all of it's inputs, including CondOp.
9464
9469
// Note that this transformation may leave over dead recipes (including
0 commit comments