6
6
//
7
7
// ===----------------------------------------------------------------------===//
8
8
9
+ #include " llvm/IR/Intrinsics.h"
10
+ #include " llvm/ADT/SmallVector.h"
11
+ #include " llvm/IR/Constant.h"
12
+ #include " llvm/IR/IRBuilder.h"
9
13
#include " llvm/IR/IntrinsicInst.h"
14
+ #include " llvm/IR/Module.h"
10
15
#include " gtest/gtest.h"
11
16
12
17
using namespace llvm ;
13
18
14
19
namespace {
15
20
16
21
static 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" ,
22
23
};
23
24
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) {
25
57
int I = Intrinsic::lookupLLVMIntrinsicByName (NameTable1, " llvm.foo" );
26
58
EXPECT_EQ (0 , I);
27
59
I = Intrinsic::lookupLLVMIntrinsicByName (NameTable1, " llvm.foo.f64" );
@@ -36,4 +68,43 @@ TEST(IntrinNameLookup, Basic) {
36
68
EXPECT_EQ (4 , I);
37
69
}
38
70
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
+ }
39
110
} // end namespace
0 commit comments