Index: include/llvm/IR/PatternMatch.h =================================================================== --- include/llvm/IR/PatternMatch.h +++ include/llvm/IR/PatternMatch.h @@ -30,6 +30,7 @@ #include "llvm/ADT/APFloat.h" #include "llvm/ADT/APInt.h" +#include "llvm/Analysis/TargetLibraryInfo.h" #include "llvm/IR/Constant.h" #include "llvm/IR/Constants.h" #include "llvm/IR/InstrTypes.h" @@ -1764,6 +1765,91 @@ return Signum_match(V); } +/// \brief LibFunc matchers. +struct LibFunc_match { + LibFunc F; + TargetLibraryInfo TLI; + + LibFunc_match(LibFunc Func, TargetLibraryInfo TargetLI) + : F(Func), TLI(TargetLI) {} + + template bool match(OpTy *V) { + LibFunc LF; + if (const auto *CI = dyn_cast(V)) + if (CI->getCalledFunction() && + TLI.getLibFunc(*CI->getCalledFunction(), LF) && + LF == F && TLI.has(LF)) + return true; + return false; + } +}; + +/// LibFunc matches are combinations of Name matchers, and argument +/// matchers. +template +struct m_LibFunc_Ty; +template struct m_LibFunc_Ty { + using Ty = match_combine_and>; +}; +template struct m_LibFunc_Ty { + using Ty = + match_combine_and::Ty, + Argument_match>; +}; +template +struct m_LibFunc_Ty { + using Ty = + match_combine_and::Ty, + Argument_match>; +}; +template +struct m_LibFunc_Ty { + using Ty = + match_combine_and::Ty, + Argument_match>; +}; + +/// \brief Match LibFunc calls like this: +/// m_LibFunc(m_Value(X)) +template +inline LibFunc_match m_LibFunc(TargetLibraryInfo TLI) { + return LibFunc_match(F, TLI); +} + +template +inline typename m_LibFunc_Ty::Ty +m_LibFunc(const TargetLibraryInfo TLI, const T0 &Op0) { + return m_CombineAnd(m_LibFunc(TLI), m_Argument<0>(Op0)); +} + +template +inline typename m_LibFunc_Ty::Ty +m_LibFunc(const TargetLibraryInfo TLI, const T0 &Op0, const T0 &Op1) { + return m_CombineAnd(m_LibFunc(TLI, Op0), m_Argument<1>(Op1)); +} + +template +inline typename m_LibFunc_Ty::Ty +m_LibFunc(const TargetLibraryInfo TLI, + const T0 &Op0, + const T0 &Op1, + const T0 &Op2) { + return m_CombineAnd(m_LibFunc(TLI, Op0, Op1), m_Argument<2>(Op2)); +} + +template +inline typename m_LibFunc_Ty::Ty +m_LibFunc(const TargetLibraryInfo TLI, + const T0 &Op0, + const T0 &Op1, + const T0 &Op2, + const T0 &Op3) { + return m_CombineAnd(m_LibFunc(TLI, Op0, Op1, Op2), m_Argument<3>(Op3)); +} + } // end namespace PatternMatch } // end namespace llvm