diff --git a/llvm/include/llvm/IR/PatternMatch.h b/llvm/include/llvm/IR/PatternMatch.h --- a/llvm/include/llvm/IR/PatternMatch.h +++ b/llvm/include/llvm/IR/PatternMatch.h @@ -1673,66 +1673,6 @@ return MaxMin_match(L, R); } -//===----------------------------------------------------------------------===// -// Matchers for overflow check patterns: e.g. (a + b) u< a -// - -template -struct UAddWithOverflow_match { - LHS_t L; - RHS_t R; - Sum_t S; - - UAddWithOverflow_match(const LHS_t &L, const RHS_t &R, const Sum_t &S) - : L(L), R(R), S(S) {} - - template bool match(OpTy *V) { - Value *ICmpLHS, *ICmpRHS; - ICmpInst::Predicate Pred; - if (!m_ICmp(Pred, m_Value(ICmpLHS), m_Value(ICmpRHS)).match(V)) - return false; - - Value *AddLHS, *AddRHS; - auto AddExpr = m_Add(m_Value(AddLHS), m_Value(AddRHS)); - - // (a + b) u< a, (a + b) u< b - if (Pred == ICmpInst::ICMP_ULT) - if (AddExpr.match(ICmpLHS) && (ICmpRHS == AddLHS || ICmpRHS == AddRHS)) - return L.match(AddLHS) && R.match(AddRHS) && S.match(ICmpLHS); - - // a >u (a + b), b >u (a + b) - if (Pred == ICmpInst::ICMP_UGT) - if (AddExpr.match(ICmpRHS) && (ICmpLHS == AddLHS || ICmpLHS == AddRHS)) - return L.match(AddLHS) && R.match(AddRHS) && S.match(ICmpRHS); - - // Match special-case for increment-by-1. - if (Pred == ICmpInst::ICMP_EQ) { - // (a + 1) == 0 - // (1 + a) == 0 - if (AddExpr.match(ICmpLHS) && m_ZeroInt().match(ICmpRHS) && - (m_One().match(AddLHS) || m_One().match(AddRHS))) - return L.match(AddLHS) && R.match(AddRHS) && S.match(ICmpLHS); - // 0 == (a + 1) - // 0 == (1 + a) - if (m_ZeroInt().match(ICmpLHS) && AddExpr.match(ICmpRHS) && - (m_One().match(AddLHS) || m_One().match(AddRHS))) - return L.match(AddLHS) && R.match(AddRHS) && S.match(ICmpRHS); - } - - return false; - } -}; - -/// Match an icmp instruction checking for unsigned overflow on addition. -/// -/// S is matched to the addition whose result is being checked for overflow, and -/// L and R are matched to the LHS and RHS of S. -template -UAddWithOverflow_match -m_UAddWithOverflow(const LHS_t &L, const RHS_t &R, const Sum_t &S) { - return UAddWithOverflow_match(L, R, S); -} - template struct Argument_match { unsigned OpI; Opnd_t Val; @@ -2076,6 +2016,66 @@ return VScaleVal_match(DL); } +//===----------------------------------------------------------------------===// +// Matchers for overflow check patterns: e.g. (a + b) u< a +// + +template +struct UAddWithOverflow_match { + LHS_t L; + RHS_t R; + Sum_t S; + + UAddWithOverflow_match(const LHS_t &L, const RHS_t &R, const Sum_t &S) + : L(L), R(R), S(S) {} + + template bool match(OpTy *V) { + Value *ICmpLHS, *ICmpRHS; + ICmpInst::Predicate Pred; + if (!m_ICmp(Pred, m_Value(ICmpLHS), m_Value(ICmpRHS)).match(V)) + return false; + + Value *AddLHS, *AddRHS; + auto AddExpr = m_Add(m_Value(AddLHS), m_Value(AddRHS)); + + // (a + b) u< a, (a + b) u< b + if (Pred == ICmpInst::ICMP_ULT) + if (AddExpr.match(ICmpLHS) && (ICmpRHS == AddLHS || ICmpRHS == AddRHS)) + return L.match(AddLHS) && R.match(AddRHS) && S.match(ICmpLHS); + + // a >u (a + b), b >u (a + b) + if (Pred == ICmpInst::ICMP_UGT) + if (AddExpr.match(ICmpRHS) && (ICmpLHS == AddLHS || ICmpLHS == AddRHS)) + return L.match(AddLHS) && R.match(AddRHS) && S.match(ICmpRHS); + + // Match special-case for increment-by-1. + if (Pred == ICmpInst::ICMP_EQ) { + // (a + 1) == 0 + // (1 + a) == 0 + if (AddExpr.match(ICmpLHS) && m_ZeroInt().match(ICmpRHS) && + (m_One().match(AddLHS) || m_One().match(AddRHS))) + return L.match(AddLHS) && R.match(AddRHS) && S.match(ICmpLHS); + // 0 == (a + 1) + // 0 == (1 + a) + if (m_ZeroInt().match(ICmpLHS) && AddExpr.match(ICmpRHS) && + (m_One().match(AddLHS) || m_One().match(AddRHS))) + return L.match(AddLHS) && R.match(AddRHS) && S.match(ICmpRHS); + } + + return false; + } +}; + +/// Match an icmp instruction checking for unsigned overflow on addition. +/// +/// S is matched to the addition whose result is being checked for overflow, and +/// L and R are matched to the LHS and RHS of S. +template +UAddWithOverflow_match +m_UAddWithOverflow(const LHS_t &L, const RHS_t &R, const Sum_t &S) { + return UAddWithOverflow_match(L, R, S); +} + } // end namespace PatternMatch } // end namespace llvm