Skip to content

Commit 0923881

Browse files
authored
[VPlan] Introduce m_[Specific]ICmp matcher (#151540)
1 parent 25d1285 commit 0923881

File tree

2 files changed

+70
-14
lines changed

2 files changed

+70
-14
lines changed

llvm/lib/Transforms/Vectorize/VPlanPatternMatch.h

Lines changed: 60 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -461,6 +461,66 @@ m_c_BinaryOr(const Op0_t &Op0, const Op1_t &Op1) {
461461
return m_BinaryOr<Op0_t, Op1_t, /*Commutative*/ true>(Op0, Op1);
462462
}
463463

464+
/// ICmp_match is a variant of BinaryRecipe_match that also binds the comparison
465+
/// predicate.
466+
template <typename Op0_t, typename Op1_t> struct ICmp_match {
467+
CmpPredicate *Predicate = nullptr;
468+
Op0_t Op0;
469+
Op1_t Op1;
470+
471+
ICmp_match(CmpPredicate &Pred, const Op0_t &Op0, const Op1_t &Op1)
472+
: Predicate(&Pred), Op0(Op0), Op1(Op1) {}
473+
ICmp_match(const Op0_t &Op0, const Op1_t &Op1) : Op0(Op0), Op1(Op1) {}
474+
475+
bool match(const VPValue *V) const {
476+
auto *DefR = V->getDefiningRecipe();
477+
return DefR && match(DefR);
478+
}
479+
480+
bool match(const VPRecipeBase *V) const {
481+
if (m_Binary<Instruction::ICmp>(Op0, Op1).match(V)) {
482+
if (Predicate)
483+
*Predicate = cast<VPRecipeWithIRFlags>(V)->getPredicate();
484+
return true;
485+
}
486+
return false;
487+
}
488+
};
489+
490+
/// SpecificICmp_match is a variant of ICmp_match that matches the comparison
491+
/// predicate, instead of binding it.
492+
template <typename Op0_t, typename Op1_t> struct SpecificICmp_match {
493+
const CmpPredicate Predicate;
494+
Op0_t Op0;
495+
Op1_t Op1;
496+
497+
SpecificICmp_match(CmpPredicate Pred, const Op0_t &LHS, const Op1_t &RHS)
498+
: Predicate(Pred), Op0(LHS), Op1(RHS) {}
499+
500+
bool match(const VPValue *V) const {
501+
CmpPredicate CurrentPred;
502+
return ICmp_match<Op0_t, Op1_t>(CurrentPred, Op0, Op1).match(V) &&
503+
CmpPredicate::getMatching(CurrentPred, Predicate);
504+
}
505+
};
506+
507+
template <typename Op0_t, typename Op1_t>
508+
inline ICmp_match<Op0_t, Op1_t> m_ICmp(const Op0_t &Op0, const Op1_t &Op1) {
509+
return ICmp_match<Op0_t, Op1_t>(Op0, Op1);
510+
}
511+
512+
template <typename Op0_t, typename Op1_t>
513+
inline ICmp_match<Op0_t, Op1_t> m_ICmp(CmpPredicate &Pred, const Op0_t &Op0,
514+
const Op1_t &Op1) {
515+
return ICmp_match<Op0_t, Op1_t>(Pred, Op0, Op1);
516+
}
517+
518+
template <typename Op0_t, typename Op1_t>
519+
inline SpecificICmp_match<Op0_t, Op1_t>
520+
m_SpecificICmp(CmpPredicate MatchPred, const Op0_t &Op0, const Op1_t &Op1) {
521+
return SpecificICmp_match<Op0_t, Op1_t>(MatchPred, Op0, Op1);
522+
}
523+
464524
template <typename Op0_t, typename Op1_t>
465525
using GEPLikeRecipe_match =
466526
BinaryRecipe_match<Op0_t, Op1_t, Instruction::GetElementPtr, false,

llvm/lib/Transforms/Vectorize/VPlanTransforms.cpp

Lines changed: 10 additions & 14 deletions
Original file line numberDiff line numberDiff line change
@@ -1391,11 +1391,10 @@ static bool optimizeVectorInductionWidthForTCAndVFUF(VPlan &Plan,
13911391

13921392
// Currently only handle cases where the single user is a header-mask
13931393
// comparison with the backedge-taken-count.
1394-
if (!match(
1395-
*WideIV->user_begin(),
1396-
m_Binary<Instruction::ICmp>(
1397-
m_Specific(WideIV),
1398-
m_Broadcast(m_Specific(Plan.getOrCreateBackedgeTakenCount())))))
1394+
if (!match(*WideIV->user_begin(),
1395+
m_ICmp(m_Specific(WideIV),
1396+
m_Broadcast(
1397+
m_Specific(Plan.getOrCreateBackedgeTakenCount())))))
13991398
continue;
14001399

14011400
// Update IV operands and comparison bound to use new narrower type.
@@ -1428,11 +1427,9 @@ static bool isConditionTrueViaVFAndUF(VPValue *Cond, VPlan &Plan,
14281427
});
14291428

14301429
auto *CanIV = Plan.getCanonicalIV();
1431-
if (!match(Cond, m_Binary<Instruction::ICmp>(
1432-
m_Specific(CanIV->getBackedgeValue()),
1433-
m_Specific(&Plan.getVectorTripCount()))) ||
1434-
cast<VPRecipeWithIRFlags>(Cond->getDefiningRecipe())->getPredicate() !=
1435-
CmpInst::ICMP_EQ)
1430+
if (!match(Cond, m_SpecificICmp(CmpInst::ICMP_EQ,
1431+
m_Specific(CanIV->getBackedgeValue()),
1432+
m_Specific(&Plan.getVectorTripCount()))))
14361433
return false;
14371434

14381435
// The compare checks CanIV + VFxUF == vector trip count. The vector trip
@@ -1841,7 +1838,7 @@ void VPlanTransforms::truncateToMinimalBitwidths(
18411838
VPW->dropPoisonGeneratingFlags();
18421839

18431840
if (OldResSizeInBits != NewResSizeInBits &&
1844-
!match(&R, m_Binary<Instruction::ICmp>(m_VPValue(), m_VPValue()))) {
1841+
!match(&R, m_ICmp(m_VPValue(), m_VPValue()))) {
18451842
// Extend result to original width.
18461843
auto *Ext =
18471844
new VPWidenCastRecipe(Instruction::ZExt, ResultVPV, OldResTy);
@@ -1850,9 +1847,8 @@ void VPlanTransforms::truncateToMinimalBitwidths(
18501847
Ext->setOperand(0, ResultVPV);
18511848
assert(OldResSizeInBits > NewResSizeInBits && "Nothing to shrink?");
18521849
} else {
1853-
assert(
1854-
match(&R, m_Binary<Instruction::ICmp>(m_VPValue(), m_VPValue())) &&
1855-
"Only ICmps should not need extending the result.");
1850+
assert(match(&R, m_ICmp(m_VPValue(), m_VPValue())) &&
1851+
"Only ICmps should not need extending the result.");
18561852
}
18571853

18581854
assert(!isa<VPWidenStoreRecipe>(&R) && "stores cannot be narrowed");

0 commit comments

Comments
 (0)