66//
77// ===----------------------------------------------------------------------===//
88
9+ #include " llvm/IR/Intrinsics.h"
10+ #include " llvm/ADT/SmallVector.h"
11+ #include " llvm/IR/Constant.h"
12+ #include " llvm/IR/IRBuilder.h"
913#include " llvm/IR/IntrinsicInst.h"
14+ #include " llvm/IR/Module.h"
1015#include " gtest/gtest.h"
1116
1217using namespace llvm ;
1318
1419namespace {
1520
1621static const char *const NameTable1[] = {
17- " llvm.foo" ,
18- " llvm.foo.a" ,
19- " llvm.foo.b" ,
20- " llvm.foo.b.a" ,
21- " llvm.foo.c" ,
22+ " llvm.foo" , " llvm.foo.a" , " llvm.foo.b" , " llvm.foo.b.a" , " llvm.foo.c" ,
2223};
2324
24- TEST (IntrinNameLookup, Basic) {
25+ class IntrinsicsTest : public ::testing::Test {
26+ LLVMContext Context;
27+ std::unique_ptr<Module> M;
28+ BasicBlock *BB = nullptr ;
29+
30+ void TearDown () override { M.reset (); }
31+
32+ void SetUp () override {
33+ M = std::make_unique<Module>(" Test" , Context);
34+ auto F = M->getOrInsertFunction (
35+ " test" , FunctionType::get (Type::getVoidTy (Context), false ));
36+ BB = BasicBlock::Create (Context, " " , cast<Function>(F.getCallee ()));
37+ EXPECT_NE (BB, nullptr );
38+ }
39+
40+ public:
41+ Instruction *makeIntrinsic (Intrinsic::ID ID) const {
42+ IRBuilder<> Builder (BB);
43+ SmallVector<Value *, 4 > ProcessedArgs;
44+ auto *Decl = Intrinsic::getDeclaration (M.get (), ID);
45+ for (auto *Ty : Decl->getFunctionType ()->params ()) {
46+ auto *Val = Constant::getNullValue (Ty);
47+ ProcessedArgs.push_back (Val);
48+ }
49+ return Builder.CreateCall (Decl, ProcessedArgs);
50+ }
51+ template <typename T> void checkIsa (const Instruction &I) {
52+ EXPECT_TRUE (isa<T>(I));
53+ }
54+ };
55+
56+ TEST (IntrinsicNameLookup, Basic) {
2557 int I = Intrinsic::lookupLLVMIntrinsicByName (NameTable1, " llvm.foo" );
2658 EXPECT_EQ (0 , I);
2759 I = Intrinsic::lookupLLVMIntrinsicByName (NameTable1, " llvm.foo.f64" );
@@ -36,4 +68,43 @@ TEST(IntrinNameLookup, Basic) {
3668 EXPECT_EQ (4 , I);
3769}
3870
71+ TEST_F (IntrinsicsTest, InstrProfInheritance) {
72+ auto isInstrProfInstBase = [](const Instruction &I) {
73+ return isa<InstrProfInstBase>(I);
74+ };
75+ #define __ISA (TYPE, PARENT ) \
76+ auto is##TYPE = [&](const Instruction &I) -> bool { \
77+ return isa<TYPE>(I) && is##PARENT (I); \
78+ }
79+ __ISA (InstrProfCntrInstBase, InstrProfInstBase);
80+ __ISA (InstrProfMCDCCondBitmapUpdate, InstrProfInstBase);
81+ __ISA (InstrProfCoverInst, InstrProfCntrInstBase);
82+ __ISA (InstrProfIncrementInst, InstrProfCntrInstBase);
83+ __ISA (InstrProfIncrementInstStep, InstrProfIncrementInst);
84+ __ISA (InstrProfTimestampInst, InstrProfCntrInstBase);
85+ __ISA (InstrProfValueProfileInst, InstrProfCntrInstBase);
86+ __ISA (InstrProfMCDCBitmapInstBase, InstrProfInstBase);
87+ __ISA (InstrProfMCDCBitmapParameters, InstrProfMCDCBitmapInstBase);
88+ __ISA (InstrProfMCDCTVBitmapUpdate, InstrProfMCDCBitmapInstBase);
89+ #undef __ISA
90+
91+ std::vector<
92+ std::pair<Intrinsic::ID, std::function<bool (const Instruction &)>>>
93+ LeafIDs = {
94+ {Intrinsic::instrprof_cover, isInstrProfCoverInst},
95+ {Intrinsic::instrprof_increment, isInstrProfIncrementInst},
96+ {Intrinsic::instrprof_increment_step, isInstrProfIncrementInstStep},
97+ {Intrinsic::instrprof_mcdc_condbitmap_update,
98+ isInstrProfMCDCCondBitmapUpdate},
99+ {Intrinsic::instrprof_mcdc_parameters,
100+ isInstrProfMCDCBitmapParameters},
101+ {Intrinsic::instrprof_mcdc_tvbitmap_update,
102+ isInstrProfMCDCTVBitmapUpdate},
103+ {Intrinsic::instrprof_timestamp, isInstrProfTimestampInst},
104+ {Intrinsic::instrprof_value_profile, isInstrProfValueProfileInst}};
105+ for (const auto &[ID, Checker] : LeafIDs) {
106+ auto *Intr = makeIntrinsic (ID);
107+ EXPECT_TRUE (Checker (*Intr));
108+ }
109+ }
39110} // end namespace
0 commit comments