@@ -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