diff --git a/llvm/lib/Transforms/Vectorize/LoopVectorize.cpp b/llvm/lib/Transforms/Vectorize/LoopVectorize.cpp index fee201ee3523a..8a75fb77f91d6 100644 --- a/llvm/lib/Transforms/Vectorize/LoopVectorize.cpp +++ b/llvm/lib/Transforms/Vectorize/LoopVectorize.cpp @@ -6901,11 +6901,12 @@ static bool planContainsAdditionalSimplifications(VPlan &Plan, // Unused FOR splices are removed by VPlan transforms, so the VPlan-based // cost model won't cost it whilst the legacy will. if (auto *FOR = dyn_cast(&R)) { - if (none_of(FOR->users(), [](VPUser *U) { - auto *VPI = dyn_cast(U); - return VPI && VPI->getOpcode() == - VPInstruction::FirstOrderRecurrenceSplice; - })) + using namespace VPlanPatternMatch; + if (none_of( + FOR->users(), + match_fn( + m_VPInstruction( + m_VPValue(), m_VPValue())))) return true; } // The VPlan-based cost model is more accurate for partial reduction and diff --git a/llvm/lib/Transforms/Vectorize/VPlanPatternMatch.h b/llvm/lib/Transforms/Vectorize/VPlanPatternMatch.h index 401a2cbd9a5ca..8f9ce7a74b58b 100644 --- a/llvm/lib/Transforms/Vectorize/VPlanPatternMatch.h +++ b/llvm/lib/Transforms/Vectorize/VPlanPatternMatch.h @@ -29,6 +29,19 @@ template bool match(VPUser *U, const Pattern &P) { return R && match(R, P); } +template struct VPMatchFunctor { + const Pattern &P; + VPMatchFunctor(const Pattern &P) : P(P) {} + bool operator()(Val *V) const { return match(V, P); } +}; + +/// A match functor that can be used as a UnaryPredicate in functional +/// algorithms like all_of. +template +VPMatchFunctor match_fn(const Pattern &P) { + return P; +} + template struct class_match { template bool match(ITy *V) const { return isa(V); } }; diff --git a/llvm/lib/Transforms/Vectorize/VPlanTransforms.cpp b/llvm/lib/Transforms/Vectorize/VPlanTransforms.cpp index dcc368933f2a1..9996b0167edcb 100644 --- a/llvm/lib/Transforms/Vectorize/VPlanTransforms.cpp +++ b/llvm/lib/Transforms/Vectorize/VPlanTransforms.cpp @@ -1149,11 +1149,10 @@ static void simplifyRecipe(VPRecipeBase &R, VPTypeAnalysis &TypeInfo) { CmpPredicate Pred; if (match(A, m_Cmp(Pred, m_VPValue(), m_VPValue()))) { auto *Cmp = cast(A); - if (all_of(Cmp->users(), [&Cmp](VPUser *U) { - return match(U, m_CombineOr(m_Not(m_Specific(Cmp)), - m_Select(m_Specific(Cmp), m_VPValue(), - m_VPValue()))); - })) { + if (all_of(Cmp->users(), + match_fn(m_CombineOr( + m_Not(m_Specific(Cmp)), + m_Select(m_Specific(Cmp), m_VPValue(), m_VPValue()))))) { Cmp->setPredicate(CmpInst::getInversePredicate(Pred)); for (VPUser *U : to_vector(Cmp->users())) { auto *R = cast(U); diff --git a/llvm/lib/Transforms/Vectorize/VPlanVerifier.cpp b/llvm/lib/Transforms/Vectorize/VPlanVerifier.cpp index 99f3bc367a548..92caa0b4e51d5 100644 --- a/llvm/lib/Transforms/Vectorize/VPlanVerifier.cpp +++ b/llvm/lib/Transforms/Vectorize/VPlanVerifier.cpp @@ -198,11 +198,11 @@ bool VPlanVerifier::verifyEVLRecipe(const VPInstruction &EVL) const { } // EVLIVIncrement is only used by EVLIV & BranchOnCount. // Having more than two users is unexpected. + using namespace llvm::VPlanPatternMatch; if ((I->getNumUsers() != 1) && - (I->getNumUsers() != 2 || none_of(I->users(), [&I](VPUser *U) { - using namespace llvm::VPlanPatternMatch; - return match(U, m_BranchOnCount(m_Specific(I), m_VPValue())); - }))) { + (I->getNumUsers() != 2 || + none_of(I->users(), match_fn(m_BranchOnCount(m_Specific(I), + m_VPValue()))))) { errs() << "EVL is used in VPInstruction with multiple users\n"; return false; }