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() {
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) {
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*>,