1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 69 70 71 72 73 74 75 76 77 78 79 80 81 82 83 84 85 86 87 88 89 90 91 92 93 94 95 96 97 98 99 100 101 102 103 104 105 106 107 108 109
|
//===- llvm/unittest/IR/IntrinsicsTest.cpp - ------------------------------===//
//
// Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions.
// See https://llvm.org/LICENSE.txt for license information.
// SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception
//
//===----------------------------------------------------------------------===//
#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;
namespace {
static const char *const NameTable1[] = {
"llvm.foo", "llvm.foo.a", "llvm.foo.b", "llvm.foo.b.a", "llvm.foo.c",
};
class IntrinsicsTest : public ::testing::Test {
LLVMContext Context;
std::unique_ptr<Module> M;
BasicBlock *BB = nullptr;
void TearDown() override { M.reset(); }
void SetUp() override {
M = std::make_unique<Module>("Test", Context);
auto F = M->getOrInsertFunction(
"test", FunctionType::get(Type::getVoidTy(Context), false));
BB = BasicBlock::Create(Context, "", cast<Function>(F.getCallee()));
EXPECT_NE(BB, nullptr);
}
public:
Instruction *makeIntrinsic(Intrinsic::ID ID) const {
IRBuilder<> Builder(BB);
SmallVector<Value *, 4> 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 <typename T> void checkIsa(const Instruction &I) {
EXPECT_TRUE(isa<T>(I));
}
};
TEST(IntrinsicNameLookup, Basic) {
int I = Intrinsic::lookupLLVMIntrinsicByName(NameTable1, "llvm.foo");
EXPECT_EQ(0, I);
I = Intrinsic::lookupLLVMIntrinsicByName(NameTable1, "llvm.foo.f64");
EXPECT_EQ(0, I);
I = Intrinsic::lookupLLVMIntrinsicByName(NameTable1, "llvm.foo.b");
EXPECT_EQ(2, I);
I = Intrinsic::lookupLLVMIntrinsicByName(NameTable1, "llvm.foo.b.a");
EXPECT_EQ(3, I);
I = Intrinsic::lookupLLVMIntrinsicByName(NameTable1, "llvm.foo.c");
EXPECT_EQ(4, I);
I = Intrinsic::lookupLLVMIntrinsicByName(NameTable1, "llvm.foo.c.f64");
EXPECT_EQ(4, I);
}
TEST_F(IntrinsicsTest, InstrProfInheritance) {
auto isInstrProfInstBase = [](const Instruction &I) {
return isa<InstrProfInstBase>(I);
};
#define __ISA(TYPE, PARENT) \
auto is##TYPE = [&](const Instruction &I) -> bool { \
return isa<TYPE>(I) && is##PARENT(I); \
}
__ISA(InstrProfCntrInstBase, InstrProfInstBase);
__ISA(InstrProfCoverInst, InstrProfCntrInstBase);
__ISA(InstrProfIncrementInst, InstrProfCntrInstBase);
__ISA(InstrProfIncrementInstStep, InstrProfIncrementInst);
__ISA(InstrProfCallsite, InstrProfCntrInstBase);
__ISA(InstrProfTimestampInst, InstrProfCntrInstBase);
__ISA(InstrProfValueProfileInst, InstrProfCntrInstBase);
__ISA(InstrProfMCDCBitmapInstBase, InstrProfInstBase);
__ISA(InstrProfMCDCBitmapParameters, InstrProfMCDCBitmapInstBase);
__ISA(InstrProfMCDCTVBitmapUpdate, InstrProfMCDCBitmapInstBase);
#undef __ISA
std::vector<
std::pair<Intrinsic::ID, std::function<bool(const Instruction &)>>>
LeafIDs = {
{Intrinsic::instrprof_cover, isInstrProfCoverInst},
{Intrinsic::instrprof_increment, isInstrProfIncrementInst},
{Intrinsic::instrprof_increment_step, isInstrProfIncrementInstStep},
{Intrinsic::instrprof_callsite, isInstrProfCallsite},
{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
|