Skip to content

Commit b9355fe

Browse files
committed
[VPlan] Introduce m_ICmp matcher
1 parent f03345a commit b9355fe

File tree

2 files changed

+75
-14
lines changed

2 files changed

+75
-14
lines changed

llvm/lib/Transforms/Vectorize/VPlanPatternMatch.h

Lines changed: 65 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -461,6 +461,71 @@ 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 BinaryRecipe_match that also matches the
491+
/// comparison predicate.
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+
auto *DefR = V->getDefiningRecipe();
502+
return DefR && match(DefR);
503+
}
504+
505+
bool match(const VPRecipeBase *V) const {
506+
return m_Binary<Instruction::ICmp>(Op0, Op1).match(V) &&
507+
CmpPredicate::getMatching(
508+
cast<VPRecipeWithIRFlags>(V)->getPredicate(), Predicate);
509+
}
510+
};
511+
512+
template <typename Op0_t, typename Op1_t>
513+
inline ICmp_match<Op0_t, Op1_t> m_ICmp(const Op0_t &Op0, const Op1_t &Op1) {
514+
return ICmp_match<Op0_t, Op1_t>(Op0, Op1);
515+
}
516+
517+
template <typename Op0_t, typename Op1_t>
518+
inline ICmp_match<Op0_t, Op1_t> m_ICmp(CmpPredicate &Pred, const Op0_t &Op0,
519+
const Op1_t &Op1) {
520+
return ICmp_match<Op0_t, Op1_t>(Pred, Op0, Op1);
521+
}
522+
523+
template <typename Op0_t, typename Op1_t>
524+
inline SpecificICmp_match<Op0_t, Op1_t>
525+
m_SpecificICmp(CmpPredicate MatchPred, const Op0_t &Op0, const Op1_t &Op1) {
526+
return SpecificICmp_match<Op0_t, Op1_t>(MatchPred, Op0, Op1);
527+
}
528+
464529
template <typename Op0_t, typename Op1_t>
465530
using GEPLikeRecipe_match =
466531
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
@@ -1382,11 +1382,10 @@ static bool optimizeVectorInductionWidthForTCAndVFUF(VPlan &Plan,
13821382

13831383
// Currently only handle cases where the single user is a header-mask
13841384
// comparison with the backedge-taken-count.
1385-
if (!match(
1386-
*WideIV->user_begin(),
1387-
m_Binary<Instruction::ICmp>(
1388-
m_Specific(WideIV),
1389-
m_Broadcast(m_Specific(Plan.getOrCreateBackedgeTakenCount())))))
1385+
if (!match(*WideIV->user_begin(),
1386+
m_ICmp(m_Specific(WideIV),
1387+
m_Broadcast(
1388+
m_Specific(Plan.getOrCreateBackedgeTakenCount())))))
13901389
continue;
13911390

13921391
// Update IV operands and comparison bound to use new narrower type.
@@ -1419,11 +1418,9 @@ static bool isConditionTrueViaVFAndUF(VPValue *Cond, VPlan &Plan,
14191418
});
14201419

14211420
auto *CanIV = Plan.getCanonicalIV();
1422-
if (!match(Cond, m_Binary<Instruction::ICmp>(
1423-
m_Specific(CanIV->getBackedgeValue()),
1424-
m_Specific(&Plan.getVectorTripCount()))) ||
1425-
cast<VPRecipeWithIRFlags>(Cond->getDefiningRecipe())->getPredicate() !=
1426-
CmpInst::ICMP_EQ)
1421+
if (!match(Cond, m_SpecificICmp(CmpInst::ICMP_EQ,
1422+
m_Specific(CanIV->getBackedgeValue()),
1423+
m_Specific(&Plan.getVectorTripCount()))))
14271424
return false;
14281425

14291426
// The compare checks CanIV + VFxUF == vector trip count. The vector trip
@@ -1832,7 +1829,7 @@ void VPlanTransforms::truncateToMinimalBitwidths(
18321829
VPW->dropPoisonGeneratingFlags();
18331830

18341831
if (OldResSizeInBits != NewResSizeInBits &&
1835-
!match(&R, m_Binary<Instruction::ICmp>(m_VPValue(), m_VPValue()))) {
1832+
!match(&R, m_ICmp(m_VPValue(), m_VPValue()))) {
18361833
// Extend result to original width.
18371834
auto *Ext =
18381835
new VPWidenCastRecipe(Instruction::ZExt, ResultVPV, OldResTy);
@@ -1841,9 +1838,8 @@ void VPlanTransforms::truncateToMinimalBitwidths(
18411838
Ext->setOperand(0, ResultVPV);
18421839
assert(OldResSizeInBits > NewResSizeInBits && "Nothing to shrink?");
18431840
} else {
1844-
assert(
1845-
match(&R, m_Binary<Instruction::ICmp>(m_VPValue(), m_VPValue())) &&
1846-
"Only ICmps should not need extending the result.");
1841+
assert(match(&R, m_ICmp(m_VPValue(), m_VPValue())) &&
1842+
"Only ICmps should not need extending the result.");
18471843
}
18481844

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

0 commit comments

Comments
 (0)