forked from OSchip/llvm-project
[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
This commit is contained in:
parent
96552036e3
commit
aca7aab90d
|
@ -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) {
|
||||
|
|
|
@ -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*>,
|
||||
|
|
Loading…
Reference in New Issue