diff --git a/llvm/include/llvm/CodeGen/SDPatternMatch.h b/llvm/include/llvm/CodeGen/SDPatternMatch.h index 511cb56f73dcb..3c8d46aea505c 100644 --- a/llvm/include/llvm/CodeGen/SDPatternMatch.h +++ b/llvm/include/llvm/CodeGen/SDPatternMatch.h @@ -155,9 +155,76 @@ struct Opcode_match { } }; +// === Patterns combinators === +template struct And { + template bool match(const MatchContext &, SDValue N) { + return true; + } +}; + +template +struct And : And { + Pred P; + And(const Pred &p, const Preds &...preds) : And(preds...), P(p) {} + + template + bool match(const MatchContext &Ctx, SDValue N) { + return P.match(Ctx, N) && And::match(Ctx, N); + } +}; + +template struct Or { + template bool match(const MatchContext &, SDValue N) { + return false; + } +}; + +template +struct Or : Or { + Pred P; + Or(const Pred &p, const Preds &...preds) : Or(preds...), P(p) {} + + template + bool match(const MatchContext &Ctx, SDValue N) { + return P.match(Ctx, N) || Or::match(Ctx, N); + } +}; + +template struct Not { + Pred P; + + explicit Not(const Pred &P) : P(P) {} + + template + bool match(const MatchContext &Ctx, SDValue N) { + return !P.match(Ctx, N); + } +}; +// Explicit deduction guide. +template Not(const Pred &P) -> Not; + +/// Match if the inner pattern does NOT match. +template inline Not m_Unless(const Pred &P) { + return Not{P}; +} + +template And m_AllOf(const Preds &...preds) { + return And(preds...); +} + +template Or m_AnyOf(const Preds &...preds) { + return Or(preds...); +} + +template auto m_NoneOf(const Preds &...preds) { + return m_Unless(m_AnyOf(preds...)); +} + inline Opcode_match m_Opc(unsigned Opcode) { return Opcode_match(Opcode); } -inline Opcode_match m_Undef() { return Opcode_match(ISD::UNDEF); } +template auto m_Undef() { + return m_AnyOf(Opcode_match(ISD::UNDEF), Opcode_match(ISD::POISON)); +} inline Opcode_match m_Poison() { return Opcode_match(ISD::POISON); } @@ -373,71 +440,6 @@ template inline auto m_LegalType(const Pattern &P) { P}; } -// === Patterns combinators === -template struct And { - template bool match(const MatchContext &, SDValue N) { - return true; - } -}; - -template -struct And : And { - Pred P; - And(const Pred &p, const Preds &...preds) : And(preds...), P(p) {} - - template - bool match(const MatchContext &Ctx, SDValue N) { - return P.match(Ctx, N) && And::match(Ctx, N); - } -}; - -template struct Or { - template bool match(const MatchContext &, SDValue N) { - return false; - } -}; - -template -struct Or : Or { - Pred P; - Or(const Pred &p, const Preds &...preds) : Or(preds...), P(p) {} - - template - bool match(const MatchContext &Ctx, SDValue N) { - return P.match(Ctx, N) || Or::match(Ctx, N); - } -}; - -template struct Not { - Pred P; - - explicit Not(const Pred &P) : P(P) {} - - template - bool match(const MatchContext &Ctx, SDValue N) { - return !P.match(Ctx, N); - } -}; -// Explicit deduction guide. -template Not(const Pred &P) -> Not; - -/// Match if the inner pattern does NOT match. -template inline Not m_Unless(const Pred &P) { - return Not{P}; -} - -template And m_AllOf(const Preds &...preds) { - return And(preds...); -} - -template Or m_AnyOf(const Preds &...preds) { - return Or(preds...); -} - -template auto m_NoneOf(const Preds &...preds) { - return m_Unless(m_AnyOf(preds...)); -} - // === Generic node matching === template struct Operands_match { template