[llvm] r366069 - [PatternMatch] Implement matching code for LibFunc

Dmitry Venikov via llvm-commits llvm-commits at lists.llvm.org
Mon Jul 15 07:47:46 PDT 2019


Author: quolyk
Date: Mon Jul 15 07:47:45 2019
New Revision: 366069

URL: http://llvm.org/viewvc/llvm-project?rev=366069&view=rev
Log:
[PatternMatch] Implement matching code for LibFunc

Summary: Provides m_LibFunc pattern that can be used to match LibFuncs.

Reviewers: spatel, hfinkel, efriedma, lebedev.ri

Reviewed By: lebedev.ri

Subscribers: lebedev.ri, llvm-commits

Tags: #llvm

Differential Revision: https://reviews.llvm.org/D42047

Modified:
    llvm/trunk/include/llvm/IR/PatternMatch.h
    llvm/trunk/unittests/IR/PatternMatch.cpp

Modified: llvm/trunk/include/llvm/IR/PatternMatch.h
URL: http://llvm.org/viewvc/llvm-project/llvm/trunk/include/llvm/IR/PatternMatch.h?rev=366069&r1=366068&r2=366069&view=diff
==============================================================================
--- llvm/trunk/include/llvm/IR/PatternMatch.h (original)
+++ llvm/trunk/include/llvm/IR/PatternMatch.h Mon Jul 15 07:47:45 2019
@@ -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"
@@ -1812,6 +1813,57 @@ template <typename Val_t> inline Signum_
   return Signum_match<Val_t>(V);
 }
 
+/// \brief LibFunc matchers.
+struct LibFunc_match {
+  LibFunc F;
+  TargetLibraryInfo TLI;
+  
+  LibFunc_match(LibFunc Func, TargetLibraryInfo TargetLI)
+  : F(Func), TLI(TargetLI) {}
+  
+  template <typename OpTy> bool match(OpTy *V) {
+    LibFunc LF;
+    if (const auto *CI = dyn_cast<CallInst>(V))
+      if (!CI->isNoBuiltin() && 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 <typename T0 = void, typename T1 = void, typename T2 = void>
+struct m_LibFunc_Ty;
+template <typename T0> struct m_LibFunc_Ty<T0> {
+  using Ty = match_combine_and<LibFunc_match, Argument_match<T0>>;
+};
+template <typename T0, typename T1> struct m_LibFunc_Ty<T0, T1> {
+  using Ty =
+  match_combine_and<typename m_LibFunc_Ty<T0>::Ty,
+  Argument_match<T1>>;
+};
+
+/// \brief Match LibFunc calls like this:
+/// m_LibFunc<LibFunc_tan>(m_Value(X))
+template <LibFunc F>
+inline LibFunc_match m_LibFunc(TargetLibraryInfo TLI) {
+  return LibFunc_match(F, TLI);
+}
+
+template <LibFunc F, typename T0>
+inline typename m_LibFunc_Ty<T0>::Ty
+m_LibFunc(const TargetLibraryInfo TLI, const T0 &Op0) {
+  return m_CombineAnd(m_LibFunc<F>(TLI), m_Argument<0>(Op0));
+}
+
+template <LibFunc F, typename T0, typename T1>
+inline typename m_LibFunc_Ty<T0, T1>::Ty
+m_LibFunc(const TargetLibraryInfo TLI, const T0 &Op0, const T1 &Op1) {
+  return m_CombineAnd(m_LibFunc<F>(TLI, Op0), m_Argument<1>(Op1));
+}
+
 } // end namespace PatternMatch
 } // end namespace llvm
 

Modified: llvm/trunk/unittests/IR/PatternMatch.cpp
URL: http://llvm.org/viewvc/llvm-project/llvm/trunk/unittests/IR/PatternMatch.cpp?rev=366069&r1=366068&r2=366069&view=diff
==============================================================================
--- llvm/trunk/unittests/IR/PatternMatch.cpp (original)
+++ llvm/trunk/unittests/IR/PatternMatch.cpp Mon Jul 15 07:47:45 2019
@@ -35,13 +35,15 @@ struct PatternMatchTest : ::testing::Tes
   Function *F;
   BasicBlock *BB;
   IRBuilder<NoFolder> IRB;
+  TargetLibraryInfoImpl TLII;
+  TargetLibraryInfo TLI;
 
   PatternMatchTest()
       : M(new Module("PatternMatchTestModule", Ctx)),
         F(Function::Create(
             FunctionType::get(Type::getVoidTy(Ctx), /* IsVarArg */ false),
             Function::ExternalLinkage, "f", M.get())),
-        BB(BasicBlock::Create(Ctx, "entry", F)), IRB(BB) {}
+        BB(BasicBlock::Create(Ctx, "entry", F)), IRB(BB), TLI(TLII) {}
 };
 
 TEST_F(PatternMatchTest, OneUse) {
@@ -1008,6 +1010,40 @@ TEST_F(PatternMatchTest, FloatingPointFN
   EXPECT_FALSE(match(V3, m_FNeg(m_Value(Match))));
 }
 
+TEST_F(PatternMatchTest, LibFunc) {
+  Type *FltTy = IRB.getFloatTy();
+  Value *One = ConstantFP::get(FltTy, 1.0);
+  Value *Two = ConstantFP::get(FltTy, 2.0);
+  Value *MatchOne, *MatchTwo;
+
+  StringRef TanName = TLI.getName(LibFunc_tan);
+  FunctionCallee TanCallee = M->getOrInsertFunction(TanName, FltTy, FltTy);
+  CallInst *Tan = IRB.CreateCall(TanCallee, One, TanName);
+
+  StringRef PowName = TLI.getName(LibFunc_pow);
+  FunctionCallee PowCallee = M->getOrInsertFunction(PowName, FltTy, FltTy, FltTy);
+  CallInst *Pow = IRB.CreateCall(PowCallee, {One, Two}, PowName);
+
+  EXPECT_TRUE(match(Tan, m_LibFunc<LibFunc_tan>(TLI)));
+  EXPECT_FALSE(match(Tan, m_LibFunc<LibFunc_pow>(TLI)));
+  EXPECT_FALSE(match(Pow, m_LibFunc<LibFunc_tan>(TLI)));
+
+  EXPECT_TRUE(match(Tan, m_LibFunc<LibFunc_tan>(TLI, m_Value(MatchOne))));
+  EXPECT_EQ(One, MatchOne);
+  EXPECT_FALSE(match(Tan, m_LibFunc<LibFunc_sin>(TLI, m_Value())));
+
+  EXPECT_TRUE(match(Pow, m_LibFunc<LibFunc_pow>(TLI, m_Value(MatchOne),
+                                                m_Value(MatchTwo))));
+  EXPECT_EQ(One, MatchOne);
+  EXPECT_EQ(Two, MatchTwo);
+  EXPECT_FALSE(match(Pow, m_LibFunc<LibFunc_fminf>(TLI, m_Value(), m_Value())));
+  
+  TLII.disableAllFunctions();
+  EXPECT_FALSE(match(Tan, m_LibFunc<LibFunc_tan>(TLI)));
+  EXPECT_FALSE(match(Tan, m_LibFunc<LibFunc_tan>(TLI, m_Value())));
+  EXPECT_FALSE(match(Pow, m_LibFunc<LibFunc_pow>(TLI, m_Value(), m_Value())));
+}
+
 template <typename T> struct MutableConstTest : PatternMatchTest { };
 
 typedef ::testing::Types<std::tuple<Value*, Instruction*>,




More information about the llvm-commits mailing list