diff --git a/llvm/unittests/IR/IntrinsicsTest.cpp b/llvm/unittests/IR/IntrinsicsTest.cpp index a500346b66a5e..3fa4b2cf73b6b 100644 --- a/llvm/unittests/IR/IntrinsicsTest.cpp +++ b/llvm/unittests/IR/IntrinsicsTest.cpp @@ -6,7 +6,12 @@ // //===----------------------------------------------------------------------===// +#include "llvm/IR/Intrinsics.h" +#include "llvm/ADT/SmallVector.h" +#include "llvm/IR/Constant.h" +#include "llvm/IR/IRBuilder.h" #include "llvm/IR/IntrinsicInst.h" +#include "llvm/IR/Module.h" #include "gtest/gtest.h" using namespace llvm; @@ -14,14 +19,41 @@ using namespace llvm; namespace { static const char *const NameTable1[] = { - "llvm.foo", - "llvm.foo.a", - "llvm.foo.b", - "llvm.foo.b.a", - "llvm.foo.c", + "llvm.foo", "llvm.foo.a", "llvm.foo.b", "llvm.foo.b.a", "llvm.foo.c", }; -TEST(IntrinNameLookup, Basic) { +class IntrinsicsTest : public ::testing::Test { + LLVMContext Context; + std::unique_ptr M; + BasicBlock *BB = nullptr; + + void TearDown() override { M.reset(); } + + void SetUp() override { + M = std::make_unique("Test", Context); + auto F = M->getOrInsertFunction( + "test", FunctionType::get(Type::getVoidTy(Context), false)); + BB = BasicBlock::Create(Context, "", cast(F.getCallee())); + EXPECT_NE(BB, nullptr); + } + +public: + Instruction *makeIntrinsic(Intrinsic::ID ID) const { + IRBuilder<> Builder(BB); + SmallVector ProcessedArgs; + auto *Decl = Intrinsic::getDeclaration(M.get(), ID); + for (auto *Ty : Decl->getFunctionType()->params()) { + auto *Val = Constant::getNullValue(Ty); + ProcessedArgs.push_back(Val); + } + return Builder.CreateCall(Decl, ProcessedArgs); + } + template void checkIsa(const Instruction &I) { + EXPECT_TRUE(isa(I)); + } +}; + +TEST(IntrinsicNameLookup, Basic) { int I = Intrinsic::lookupLLVMIntrinsicByName(NameTable1, "llvm.foo"); EXPECT_EQ(0, I); I = Intrinsic::lookupLLVMIntrinsicByName(NameTable1, "llvm.foo.f64"); @@ -36,4 +68,43 @@ TEST(IntrinNameLookup, Basic) { EXPECT_EQ(4, I); } +TEST_F(IntrinsicsTest, InstrProfInheritance) { + auto isInstrProfInstBase = [](const Instruction &I) { + return isa(I); + }; +#define __ISA(TYPE, PARENT) \ + auto is##TYPE = [&](const Instruction &I) -> bool { \ + return isa(I) && is##PARENT(I); \ + } + __ISA(InstrProfCntrInstBase, InstrProfInstBase); + __ISA(InstrProfMCDCCondBitmapUpdate, InstrProfInstBase); + __ISA(InstrProfCoverInst, InstrProfCntrInstBase); + __ISA(InstrProfIncrementInst, InstrProfCntrInstBase); + __ISA(InstrProfIncrementInstStep, InstrProfIncrementInst); + __ISA(InstrProfTimestampInst, InstrProfCntrInstBase); + __ISA(InstrProfValueProfileInst, InstrProfCntrInstBase); + __ISA(InstrProfMCDCBitmapInstBase, InstrProfInstBase); + __ISA(InstrProfMCDCBitmapParameters, InstrProfMCDCBitmapInstBase); + __ISA(InstrProfMCDCTVBitmapUpdate, InstrProfMCDCBitmapInstBase); +#undef __ISA + + std::vector< + std::pair>> + LeafIDs = { + {Intrinsic::instrprof_cover, isInstrProfCoverInst}, + {Intrinsic::instrprof_increment, isInstrProfIncrementInst}, + {Intrinsic::instrprof_increment_step, isInstrProfIncrementInstStep}, + {Intrinsic::instrprof_mcdc_condbitmap_update, + isInstrProfMCDCCondBitmapUpdate}, + {Intrinsic::instrprof_mcdc_parameters, + isInstrProfMCDCBitmapParameters}, + {Intrinsic::instrprof_mcdc_tvbitmap_update, + isInstrProfMCDCTVBitmapUpdate}, + {Intrinsic::instrprof_timestamp, isInstrProfTimestampInst}, + {Intrinsic::instrprof_value_profile, isInstrProfValueProfileInst}}; + for (const auto &[ID, Checker] : LeafIDs) { + auto *Intr = makeIntrinsic(ID); + EXPECT_TRUE(Checker(*Intr)); + } +} } // end namespace