diff options
| author | Florian Hahn <flo@fhahn.com> | 2019-12-02 15:29:53 +0000 |
|---|---|---|
| committer | Florian Hahn <flo@fhahn.com> | 2019-12-02 15:38:22 +0000 |
| commit | aca7aab90d79df08ecadde798e2172f4995ab601 (patch) | |
| tree | 43d3ee96be44c19ad2adf845ec63a91044bdf9b5 | |
| parent | 96552036e307f7b0dd6477583c3fdb7de17e8aac (diff) | |
| download | bcm5719-llvm-aca7aab90d79df08ecadde798e2172f4995ab601.tar.gz bcm5719-llvm-aca7aab90d79df08ecadde798e2172f4995ab601.zip | |
[PatternMatch] Add support for matching intrinsics with 5 operands.
Summary: Also adds a test to the pattern matching unit tests.
Reviewers: spatel, craig.topper, RKSimon, majnemer, lebedev.ri
Reviewed By: spatel
Subscribers: merge_guards_bot, llvm-commits
Tags: #llvm
Differential Revision: https://reviews.llvm.org/D70892
| -rw-r--r-- | llvm/include/llvm/IR/PatternMatch.h | 15 | ||||
| -rw-r--r-- | llvm/unittests/IR/PatternMatch.cpp | 79 |
2 files changed, 94 insertions, 0 deletions
diff --git a/llvm/include/llvm/IR/PatternMatch.h b/llvm/include/llvm/IR/PatternMatch.h index 5d4ce4955b9..64ffb59a0b1 100644 --- a/llvm/include/llvm/IR/PatternMatch.h +++ b/llvm/include/llvm/IR/PatternMatch.h @@ -1736,6 +1736,12 @@ struct m_Intrinsic_Ty<T0, T1, T2, T3> { Argument_match<T3>>; }; +template <typename T0, typename T1, typename T2, typename T3, typename T4> +struct m_Intrinsic_Ty<T0, T1, T2, T3, T4> { + using Ty = match_combine_and<typename m_Intrinsic_Ty<T0, T1, T2, T3>::Ty, + Argument_match<T4>>; +}; + /// Match intrinsic calls like this: /// m_Intrinsic<Intrinsic::fabs>(m_Value(X)) template <Intrinsic::ID IntrID> inline IntrinsicID_match m_Intrinsic() { @@ -1766,6 +1772,15 @@ m_Intrinsic(const T0 &Op0, const T1 &Op1, const T2 &Op2, const T3 &Op3) { return m_CombineAnd(m_Intrinsic<IntrID>(Op0, Op1, Op2), m_Argument<3>(Op3)); } +template <Intrinsic::ID IntrID, typename T0, typename T1, typename T2, + typename T3, typename T4> +inline typename m_Intrinsic_Ty<T0, T1, T2, T3, T4>::Ty +m_Intrinsic(const T0 &Op0, const T1 &Op1, const T2 &Op2, const T3 &Op3, + const T4 &Op4) { + return m_CombineAnd(m_Intrinsic<IntrID>(Op0, Op1, Op2, Op3), + m_Argument<4>(Op4)); +} + // Helper intrinsic matching specializations. template <typename Opnd0> inline typename m_Intrinsic_Ty<Opnd0>::Ty m_BitReverse(const Opnd0 &Op0) { diff --git a/llvm/unittests/IR/PatternMatch.cpp b/llvm/unittests/IR/PatternMatch.cpp index f624024d584..0c2ec36f878 100644 --- a/llvm/unittests/IR/PatternMatch.cpp +++ b/llvm/unittests/IR/PatternMatch.cpp @@ -1133,6 +1133,85 @@ TEST_F(PatternMatchTest, WithOverflowInst) { EXPECT_EQ(Add, WOI); } +TEST_F(PatternMatchTest, IntrinsicMatcher) { + Value *Name = IRB.CreateAlloca(IRB.getInt8Ty()); + Value *Hash = IRB.getInt64(0); + Value *Num = IRB.getInt32(1); + Value *Index = IRB.getInt32(2); + Value *Step = IRB.getInt64(3); + + Value *Ops[] = {Name, Hash, Num, Index, Step}; + Module *M = BB->getParent()->getParent(); + Function *TheFn = + Intrinsic::getDeclaration(M, Intrinsic::instrprof_increment_step); + + Value *Intrinsic5 = CallInst::Create(TheFn, Ops, "", BB); + + // Match without capturing. + EXPECT_TRUE(match( + Intrinsic5, m_Intrinsic<Intrinsic::instrprof_increment_step>( + m_Value(), m_Value(), m_Value(), m_Value(), m_Value()))); + EXPECT_FALSE(match( + Intrinsic5, m_Intrinsic<Intrinsic::memmove>( + m_Value(), m_Value(), m_Value(), m_Value(), m_Value()))); + + // Match with capturing. + Value *Arg1 = nullptr; + Value *Arg2 = nullptr; + Value *Arg3 = nullptr; + Value *Arg4 = nullptr; + Value *Arg5 = nullptr; + EXPECT_TRUE( + match(Intrinsic5, m_Intrinsic<Intrinsic::instrprof_increment_step>( + m_Value(Arg1), m_Value(Arg2), m_Value(Arg3), + m_Value(Arg4), m_Value(Arg5)))); + EXPECT_EQ(Arg1, Name); + EXPECT_EQ(Arg2, Hash); + EXPECT_EQ(Arg3, Num); + EXPECT_EQ(Arg4, Index); + EXPECT_EQ(Arg5, Step); + + // Match specific second argument. + EXPECT_TRUE( + match(Intrinsic5, + m_Intrinsic<Intrinsic::instrprof_increment_step>( + m_Value(), m_SpecificInt(0), m_Value(), m_Value(), m_Value()))); + EXPECT_FALSE( + match(Intrinsic5, m_Intrinsic<Intrinsic::instrprof_increment_step>( + m_Value(), m_SpecificInt(10), m_Value(), m_Value(), + m_Value()))); + + // Match specific third argument. + EXPECT_TRUE( + match(Intrinsic5, + m_Intrinsic<Intrinsic::instrprof_increment_step>( + m_Value(), m_Value(), m_SpecificInt(1), m_Value(), m_Value()))); + EXPECT_FALSE( + match(Intrinsic5, m_Intrinsic<Intrinsic::instrprof_increment_step>( + m_Value(), m_Value(), m_SpecificInt(10), m_Value(), + m_Value()))); + + // Match specific fourth argument. + EXPECT_TRUE( + match(Intrinsic5, + m_Intrinsic<Intrinsic::instrprof_increment_step>( + m_Value(), m_Value(), m_Value(), m_SpecificInt(2), m_Value()))); + EXPECT_FALSE( + match(Intrinsic5, m_Intrinsic<Intrinsic::instrprof_increment_step>( + m_Value(), m_Value(), m_Value(), m_SpecificInt(10), + m_Value()))); + + // Match specific fifth argument. + EXPECT_TRUE( + match(Intrinsic5, + m_Intrinsic<Intrinsic::instrprof_increment_step>( + m_Value(), m_Value(), m_Value(), m_Value(), m_SpecificInt(3)))); + EXPECT_FALSE( + match(Intrinsic5, m_Intrinsic<Intrinsic::instrprof_increment_step>( + m_Value(), m_Value(), m_Value(), m_Value(), + m_SpecificInt(10)))); +} + template <typename T> struct MutableConstTest : PatternMatchTest { }; typedef ::testing::Types<std::tuple<Value*, Instruction*>, |

