You've already forked linux-packaging-mono
Imported Upstream version 5.18.0.207
Former-commit-id: 3b152f462918d427ce18620a2cbe4f8b79650449
This commit is contained in:
parent
8e12397d70
commit
eb85e2fc17
54
external/llvm/unittests/IR/AsmWriterTest.cpp
vendored
54
external/llvm/unittests/IR/AsmWriterTest.cpp
vendored
@ -1,54 +0,0 @@
|
||||
//===- llvm/unittest/IR/AsmWriter.cpp - AsmWriter tests -------------------===//
|
||||
//
|
||||
// The LLVM Compiler Infrastructure
|
||||
//
|
||||
// This file is distributed under the University of Illinois Open Source
|
||||
// License. See LICENSE.TXT for details.
|
||||
//
|
||||
//===----------------------------------------------------------------------===//
|
||||
#include "llvm/BinaryFormat/Dwarf.h"
|
||||
#include "llvm/IR/DebugInfoMetadata.h"
|
||||
#include "llvm/IR/Function.h"
|
||||
#include "llvm/IR/IRBuilder.h"
|
||||
#include "llvm/IR/LLVMContext.h"
|
||||
#include "llvm/IR/MDBuilder.h"
|
||||
#include "llvm/IR/Module.h"
|
||||
#include "gtest/gtest.h"
|
||||
|
||||
using namespace llvm;
|
||||
|
||||
namespace {
|
||||
|
||||
TEST(AsmWriterTest, DebugPrintDetachedInstruction) {
|
||||
|
||||
// PR24852: Ensure that an instruction can be printed even when it
|
||||
// has metadata attached but no parent.
|
||||
LLVMContext Ctx;
|
||||
auto Ty = Type::getInt32Ty(Ctx);
|
||||
auto Undef = UndefValue::get(Ty);
|
||||
std::unique_ptr<BinaryOperator> Add(BinaryOperator::CreateAdd(Undef, Undef));
|
||||
Add->setMetadata(
|
||||
"", MDNode::get(Ctx, {ConstantAsMetadata::get(ConstantInt::get(Ty, 1))}));
|
||||
std::string S;
|
||||
raw_string_ostream OS(S);
|
||||
Add->print(OS);
|
||||
std::size_t r = OS.str().find("<badref> = add i32 undef, undef, !<empty");
|
||||
EXPECT_TRUE(r != std::string::npos);
|
||||
}
|
||||
|
||||
TEST(AsmWriterTest, DumpDIExpression) {
|
||||
LLVMContext Ctx;
|
||||
uint64_t Ops[] = {
|
||||
dwarf::DW_OP_constu, 4,
|
||||
dwarf::DW_OP_minus,
|
||||
dwarf::DW_OP_deref,
|
||||
};
|
||||
DIExpression *Expr = DIExpression::get(Ctx, Ops);
|
||||
std::string S;
|
||||
raw_string_ostream OS(S);
|
||||
Expr->print(OS);
|
||||
EXPECT_EQ("!DIExpression(DW_OP_constu, 4, DW_OP_minus, DW_OP_deref)",
|
||||
OS.str());
|
||||
}
|
||||
|
||||
}
|
92
external/llvm/unittests/IR/AttributesTest.cpp
vendored
92
external/llvm/unittests/IR/AttributesTest.cpp
vendored
@ -1,92 +0,0 @@
|
||||
//===- llvm/unittest/IR/AttributesTest.cpp - Attributes unit tests --------===//
|
||||
//
|
||||
// The LLVM Compiler Infrastructure
|
||||
//
|
||||
// This file is distributed under the University of Illinois Open Source
|
||||
// License. See LICENSE.TXT for details.
|
||||
//
|
||||
//===----------------------------------------------------------------------===//
|
||||
|
||||
#include "llvm/IR/Attributes.h"
|
||||
#include "llvm/IR/LLVMContext.h"
|
||||
#include "gtest/gtest.h"
|
||||
using namespace llvm;
|
||||
|
||||
namespace {
|
||||
|
||||
TEST(Attributes, Uniquing) {
|
||||
LLVMContext C;
|
||||
|
||||
Attribute AttrA = Attribute::get(C, Attribute::AlwaysInline);
|
||||
Attribute AttrB = Attribute::get(C, Attribute::AlwaysInline);
|
||||
EXPECT_EQ(AttrA, AttrB);
|
||||
|
||||
AttributeList ASs[] = {AttributeList::get(C, 1, Attribute::ZExt),
|
||||
AttributeList::get(C, 2, Attribute::SExt)};
|
||||
|
||||
AttributeList SetA = AttributeList::get(C, ASs);
|
||||
AttributeList SetB = AttributeList::get(C, ASs);
|
||||
EXPECT_EQ(SetA, SetB);
|
||||
}
|
||||
|
||||
TEST(Attributes, Ordering) {
|
||||
LLVMContext C;
|
||||
|
||||
Attribute Align4 = Attribute::get(C, Attribute::Alignment, 4);
|
||||
Attribute Align5 = Attribute::get(C, Attribute::Alignment, 5);
|
||||
Attribute Deref4 = Attribute::get(C, Attribute::Dereferenceable, 4);
|
||||
Attribute Deref5 = Attribute::get(C, Attribute::Dereferenceable, 5);
|
||||
EXPECT_TRUE(Align4 < Align5);
|
||||
EXPECT_TRUE(Align4 < Deref4);
|
||||
EXPECT_TRUE(Align4 < Deref5);
|
||||
EXPECT_TRUE(Align5 < Deref4);
|
||||
|
||||
AttributeList ASs[] = {AttributeList::get(C, 2, Attribute::ZExt),
|
||||
AttributeList::get(C, 1, Attribute::SExt)};
|
||||
|
||||
AttributeList SetA = AttributeList::get(C, ASs);
|
||||
AttributeList SetB = SetA.removeAttributes(C, 1, ASs[1].getAttributes(1));
|
||||
EXPECT_NE(SetA, SetB);
|
||||
}
|
||||
|
||||
TEST(Attributes, AddAttributes) {
|
||||
LLVMContext C;
|
||||
AttributeList AL;
|
||||
AttrBuilder B;
|
||||
B.addAttribute(Attribute::NoReturn);
|
||||
AL = AL.addAttributes(C, AttributeList::FunctionIndex, AttributeSet::get(C, B));
|
||||
EXPECT_TRUE(AL.hasFnAttribute(Attribute::NoReturn));
|
||||
B.clear();
|
||||
B.addAttribute(Attribute::SExt);
|
||||
AL = AL.addAttributes(C, AttributeList::ReturnIndex, B);
|
||||
EXPECT_TRUE(AL.hasAttribute(AttributeList::ReturnIndex, Attribute::SExt));
|
||||
EXPECT_TRUE(AL.hasFnAttribute(Attribute::NoReturn));
|
||||
}
|
||||
|
||||
TEST(Attributes, AddMatchingAlignAttr) {
|
||||
LLVMContext C;
|
||||
AttributeList AL;
|
||||
AL = AL.addAttribute(C, AttributeList::FirstArgIndex,
|
||||
Attribute::getWithAlignment(C, 8));
|
||||
AL = AL.addAttribute(C, AttributeList::FirstArgIndex + 1,
|
||||
Attribute::getWithAlignment(C, 32));
|
||||
EXPECT_EQ(8U, AL.getParamAlignment(0));
|
||||
EXPECT_EQ(32U, AL.getParamAlignment(1));
|
||||
|
||||
AttrBuilder B;
|
||||
B.addAttribute(Attribute::NonNull);
|
||||
B.addAlignmentAttr(8);
|
||||
AL = AL.addAttributes(C, AttributeList::FirstArgIndex, B);
|
||||
EXPECT_EQ(8U, AL.getParamAlignment(0));
|
||||
EXPECT_EQ(32U, AL.getParamAlignment(1));
|
||||
EXPECT_TRUE(AL.hasParamAttribute(0, Attribute::NonNull));
|
||||
}
|
||||
|
||||
TEST(Attributes, EmptyGet) {
|
||||
LLVMContext C;
|
||||
AttributeList EmptyLists[] = {AttributeList(), AttributeList()};
|
||||
AttributeList AL = AttributeList::get(C, EmptyLists);
|
||||
EXPECT_TRUE(AL.isEmpty());
|
||||
}
|
||||
|
||||
} // end anonymous namespace
|
81
external/llvm/unittests/IR/BasicBlockTest.cpp
vendored
81
external/llvm/unittests/IR/BasicBlockTest.cpp
vendored
@ -1,81 +0,0 @@
|
||||
//===- llvm/unittest/IR/BasicBlockTest.cpp - BasicBlock unit tests --------===//
|
||||
//
|
||||
// The LLVM Compiler Infrastructure
|
||||
//
|
||||
// This file is distributed under the University of Illinois Open Source
|
||||
// License. See LICENSE.TXT for details.
|
||||
//
|
||||
//===----------------------------------------------------------------------===//
|
||||
|
||||
#include "llvm/IR/BasicBlock.h"
|
||||
#include "llvm/ADT/STLExtras.h"
|
||||
#include "llvm/IR/Function.h"
|
||||
#include "llvm/IR/IRBuilder.h"
|
||||
#include "llvm/IR/LLVMContext.h"
|
||||
#include "llvm/IR/Module.h"
|
||||
#include "llvm/IR/NoFolder.h"
|
||||
#include "gmock/gmock-matchers.h"
|
||||
#include "gtest/gtest.h"
|
||||
#include <memory>
|
||||
|
||||
namespace llvm {
|
||||
namespace {
|
||||
|
||||
TEST(BasicBlockTest, PhiRange) {
|
||||
LLVMContext Context;
|
||||
|
||||
// Create the main block.
|
||||
std::unique_ptr<BasicBlock> BB(BasicBlock::Create(Context));
|
||||
|
||||
// Create some predecessors of it.
|
||||
std::unique_ptr<BasicBlock> BB1(BasicBlock::Create(Context));
|
||||
BranchInst::Create(BB.get(), BB1.get());
|
||||
std::unique_ptr<BasicBlock> BB2(BasicBlock::Create(Context));
|
||||
BranchInst::Create(BB.get(), BB2.get());
|
||||
|
||||
// Make sure this doesn't crash if there are no phis.
|
||||
for (auto &PN : BB->phis()) {
|
||||
(void)PN;
|
||||
EXPECT_TRUE(false) << "empty block should have no phis";
|
||||
}
|
||||
|
||||
// Make it a cycle.
|
||||
auto *BI = BranchInst::Create(BB.get(), BB.get());
|
||||
|
||||
// Now insert some PHI nodes.
|
||||
auto *Int32Ty = Type::getInt32Ty(Context);
|
||||
auto *P1 = PHINode::Create(Int32Ty, /*NumReservedValues*/ 3, "phi.1", BI);
|
||||
auto *P2 = PHINode::Create(Int32Ty, /*NumReservedValues*/ 3, "phi.2", BI);
|
||||
auto *P3 = PHINode::Create(Int32Ty, /*NumReservedValues*/ 3, "phi.3", BI);
|
||||
|
||||
// Some non-PHI nodes.
|
||||
auto *Sum = BinaryOperator::CreateAdd(P1, P2, "sum", BI);
|
||||
|
||||
// Now wire up the incoming values that are interesting.
|
||||
P1->addIncoming(P2, BB.get());
|
||||
P2->addIncoming(P1, BB.get());
|
||||
P3->addIncoming(Sum, BB.get());
|
||||
|
||||
// Finally, let's iterate them, which is the thing we're trying to test.
|
||||
// We'll use this to wire up the rest of the incoming values.
|
||||
for (auto &PN : BB->phis()) {
|
||||
PN.addIncoming(UndefValue::get(Int32Ty), BB1.get());
|
||||
PN.addIncoming(UndefValue::get(Int32Ty), BB2.get());
|
||||
}
|
||||
|
||||
// Test that we can use const iterators and generally that the iterators
|
||||
// behave like iterators.
|
||||
BasicBlock::const_phi_iterator CI;
|
||||
CI = BB->phis().begin();
|
||||
EXPECT_NE(CI, BB->phis().end());
|
||||
|
||||
// And iterate a const range.
|
||||
for (const auto &PN : const_cast<const BasicBlock *>(BB.get())->phis()) {
|
||||
EXPECT_EQ(BB.get(), PN.getIncomingBlock(0));
|
||||
EXPECT_EQ(BB1.get(), PN.getIncomingBlock(1));
|
||||
EXPECT_EQ(BB2.get(), PN.getIncomingBlock(2));
|
||||
}
|
||||
}
|
||||
|
||||
} // End anonymous namespace.
|
||||
} // End llvm namespace.
|
269
external/llvm/unittests/IR/CFGBuilder.cpp
vendored
269
external/llvm/unittests/IR/CFGBuilder.cpp
vendored
@ -1,269 +0,0 @@
|
||||
//===- llvm/Testing/Support/CFGBuilder.cpp --------------------------------===//
|
||||
//
|
||||
// The LLVM Compiler Infrastructure
|
||||
//
|
||||
// This file is distributed under the University of Illinois Open Source
|
||||
// License. See LICENSE.TXT for details.
|
||||
//
|
||||
//===----------------------------------------------------------------------===//
|
||||
|
||||
#include "CFGBuilder.h"
|
||||
|
||||
#include "llvm/IR/IRBuilder.h"
|
||||
#include "llvm/IR/LLVMContext.h"
|
||||
#include "llvm/IR/TypeBuilder.h"
|
||||
#include "llvm/Support/Debug.h"
|
||||
#include "llvm/Support/raw_ostream.h"
|
||||
#include "gtest/gtest.h"
|
||||
|
||||
#define DEBUG_TYPE "cfg-builder"
|
||||
|
||||
using namespace llvm;
|
||||
|
||||
CFGHolder::CFGHolder(StringRef ModuleName, StringRef FunctionName)
|
||||
: Context(llvm::make_unique<LLVMContext>()),
|
||||
M(llvm::make_unique<Module>(ModuleName, *Context)) {
|
||||
FunctionType *FTy = TypeBuilder<void(), false>::get(*Context);
|
||||
F = cast<Function>(M->getOrInsertFunction(FunctionName, FTy));
|
||||
}
|
||||
CFGHolder::~CFGHolder() = default;
|
||||
|
||||
CFGBuilder::CFGBuilder(Function *F, const std::vector<Arc> &InitialArcs,
|
||||
std::vector<Update> Updates)
|
||||
: F(F), Updates(std::move(Updates)) {
|
||||
assert(F);
|
||||
buildCFG(InitialArcs);
|
||||
}
|
||||
|
||||
static void ConnectBlocks(BasicBlock *From, BasicBlock *To) {
|
||||
DEBUG(dbgs() << "Creating BB arc " << From->getName() << " -> "
|
||||
<< To->getName() << "\n";
|
||||
dbgs().flush());
|
||||
auto *IntTy = IntegerType::get(From->getContext(), 32);
|
||||
|
||||
if (isa<UnreachableInst>(From->getTerminator()))
|
||||
From->getTerminator()->eraseFromParent();
|
||||
if (!From->getTerminator()) {
|
||||
IRBuilder<> IRB(From);
|
||||
IRB.CreateSwitch(ConstantInt::get(IntTy, 0), To);
|
||||
return;
|
||||
}
|
||||
|
||||
SwitchInst *SI = cast<SwitchInst>(From->getTerminator());
|
||||
const auto Last = SI->getNumCases();
|
||||
|
||||
auto *IntVal = ConstantInt::get(IntTy, Last);
|
||||
SI->addCase(IntVal, To);
|
||||
}
|
||||
|
||||
static void DisconnectBlocks(BasicBlock *From, BasicBlock *To) {
|
||||
DEBUG(dbgs() << "Deleting BB arc " << From->getName() << " -> "
|
||||
<< To->getName() << "\n";
|
||||
dbgs().flush());
|
||||
SwitchInst *SI = cast<SwitchInst>(From->getTerminator());
|
||||
|
||||
if (SI->getNumCases() == 0) {
|
||||
SI->eraseFromParent();
|
||||
IRBuilder<> IRB(From);
|
||||
IRB.CreateUnreachable();
|
||||
return;
|
||||
}
|
||||
|
||||
if (SI->getDefaultDest() == To) {
|
||||
auto FirstC = SI->case_begin();
|
||||
SI->setDefaultDest(FirstC->getCaseSuccessor());
|
||||
SI->removeCase(FirstC);
|
||||
return;
|
||||
}
|
||||
|
||||
for (auto CIt = SI->case_begin(); CIt != SI->case_end(); ++CIt)
|
||||
if (CIt->getCaseSuccessor() == To) {
|
||||
SI->removeCase(CIt);
|
||||
return;
|
||||
}
|
||||
}
|
||||
|
||||
BasicBlock *CFGBuilder::getOrAddBlock(StringRef BlockName) {
|
||||
auto BIt = NameToBlock.find(BlockName);
|
||||
if (BIt != NameToBlock.end())
|
||||
return BIt->second;
|
||||
|
||||
auto *BB = BasicBlock::Create(F->getParent()->getContext(), BlockName, F);
|
||||
IRBuilder<> IRB(BB);
|
||||
IRB.CreateUnreachable();
|
||||
NameToBlock[BlockName] = BB;
|
||||
return BB;
|
||||
}
|
||||
|
||||
bool CFGBuilder::connect(const Arc &A) {
|
||||
BasicBlock *From = getOrAddBlock(A.From);
|
||||
BasicBlock *To = getOrAddBlock(A.To);
|
||||
if (Arcs.count(A) != 0)
|
||||
return false;
|
||||
|
||||
Arcs.insert(A);
|
||||
ConnectBlocks(From, To);
|
||||
return true;
|
||||
}
|
||||
|
||||
bool CFGBuilder::disconnect(const Arc &A) {
|
||||
assert(NameToBlock.count(A.From) != 0 && "No block to disconnect (From)");
|
||||
assert(NameToBlock.count(A.To) != 0 && "No block to disconnect (To)");
|
||||
if (Arcs.count(A) == 0)
|
||||
return false;
|
||||
|
||||
BasicBlock *From = getOrAddBlock(A.From);
|
||||
BasicBlock *To = getOrAddBlock(A.To);
|
||||
Arcs.erase(A);
|
||||
DisconnectBlocks(From, To);
|
||||
return true;
|
||||
}
|
||||
|
||||
void CFGBuilder::buildCFG(const std::vector<Arc> &NewArcs) {
|
||||
for (const auto &A : NewArcs) {
|
||||
const bool Connected = connect(A);
|
||||
(void)Connected;
|
||||
assert(Connected);
|
||||
}
|
||||
}
|
||||
|
||||
Optional<CFGBuilder::Update> CFGBuilder::getNextUpdate() const {
|
||||
if (UpdateIdx == Updates.size())
|
||||
return None;
|
||||
return Updates[UpdateIdx];
|
||||
}
|
||||
|
||||
Optional<CFGBuilder::Update> CFGBuilder::applyUpdate() {
|
||||
if (UpdateIdx == Updates.size())
|
||||
return None;
|
||||
Update NextUpdate = Updates[UpdateIdx++];
|
||||
if (NextUpdate.Action == ActionKind::Insert)
|
||||
connect(NextUpdate.Edge);
|
||||
else
|
||||
disconnect(NextUpdate.Edge);
|
||||
|
||||
return NextUpdate;
|
||||
}
|
||||
|
||||
void CFGBuilder::dump(raw_ostream &OS) const {
|
||||
OS << "Arcs:\n";
|
||||
size_t i = 0;
|
||||
for (const auto &A : Arcs)
|
||||
OS << " " << i++ << ":\t" << A.From << " -> " << A.To << "\n";
|
||||
|
||||
OS << "Updates:\n";
|
||||
i = 0;
|
||||
for (const auto &U : Updates) {
|
||||
OS << (i + 1 == UpdateIdx ? "->" : " ") << i
|
||||
<< ((U.Action == ActionKind::Insert) ? "\tIns " : "\tDel ")
|
||||
<< U.Edge.From << " -> " << U.Edge.To << "\n";
|
||||
++i;
|
||||
}
|
||||
}
|
||||
|
||||
//---- CFGBuilder tests ---------------------------------------------------===//
|
||||
|
||||
TEST(CFGBuilder, Construction) {
|
||||
CFGHolder Holder;
|
||||
std::vector<CFGBuilder::Arc> Arcs = {{"entry", "a"}, {"a", "b"}, {"a", "c"},
|
||||
{"c", "d"}, {"d", "b"}, {"d", "e"},
|
||||
{"d", "f"}, {"e", "f"}};
|
||||
CFGBuilder B(Holder.F, Arcs, {});
|
||||
|
||||
EXPECT_TRUE(B.getOrAddBlock("entry") == &Holder.F->getEntryBlock());
|
||||
EXPECT_TRUE(isa<SwitchInst>(B.getOrAddBlock("entry")->getTerminator()));
|
||||
EXPECT_TRUE(isa<SwitchInst>(B.getOrAddBlock("a")->getTerminator()));
|
||||
EXPECT_TRUE(isa<UnreachableInst>(B.getOrAddBlock("b")->getTerminator()));
|
||||
EXPECT_TRUE(isa<SwitchInst>(B.getOrAddBlock("d")->getTerminator()));
|
||||
|
||||
auto *DSwitch = cast<SwitchInst>(B.getOrAddBlock("d")->getTerminator());
|
||||
// d has 3 successors, but one of them if going to be a default case
|
||||
EXPECT_EQ(DSwitch->getNumCases(), 2U);
|
||||
EXPECT_FALSE(B.getNextUpdate()); // No updates to apply.
|
||||
}
|
||||
|
||||
TEST(CFGBuilder, Insertions) {
|
||||
CFGHolder Holder;
|
||||
const auto Insert = CFGBuilder::ActionKind::Insert;
|
||||
std::vector<CFGBuilder::Update> Updates = {
|
||||
{Insert, {"entry", "a"}}, {Insert, {"a", "b"}}, {Insert, {"a", "c"}},
|
||||
{Insert, {"c", "d"}}, {Insert, {"d", "b"}}, {Insert, {"d", "e"}},
|
||||
{Insert, {"d", "f"}}, {Insert, {"e", "f"}}};
|
||||
const size_t NumUpdates = Updates.size();
|
||||
|
||||
CFGBuilder B(Holder.F, {}, Updates);
|
||||
|
||||
size_t i = 0;
|
||||
while (B.applyUpdate())
|
||||
++i;
|
||||
EXPECT_EQ(i, NumUpdates);
|
||||
|
||||
EXPECT_TRUE(B.getOrAddBlock("entry") == &Holder.F->getEntryBlock());
|
||||
EXPECT_TRUE(isa<SwitchInst>(B.getOrAddBlock("entry")->getTerminator()));
|
||||
EXPECT_TRUE(isa<SwitchInst>(B.getOrAddBlock("a")->getTerminator()));
|
||||
EXPECT_TRUE(isa<UnreachableInst>(B.getOrAddBlock("b")->getTerminator()));
|
||||
EXPECT_TRUE(isa<SwitchInst>(B.getOrAddBlock("d")->getTerminator()));
|
||||
|
||||
auto *DSwitch = cast<SwitchInst>(B.getOrAddBlock("d")->getTerminator());
|
||||
// d has 3 successors, but one of them if going to be a default case
|
||||
EXPECT_EQ(DSwitch->getNumCases(), 2U);
|
||||
EXPECT_FALSE(B.getNextUpdate()); // No updates to apply.
|
||||
}
|
||||
|
||||
TEST(CFGBuilder, Deletions) {
|
||||
CFGHolder Holder;
|
||||
std::vector<CFGBuilder::Arc> Arcs = {
|
||||
{"entry", "a"}, {"a", "b"}, {"a", "c"}, {"c", "d"}, {"d", "b"}};
|
||||
const auto Delete = CFGBuilder::ActionKind::Delete;
|
||||
std::vector<CFGBuilder::Update> Updates = {
|
||||
{Delete, {"c", "d"}}, {Delete, {"a", "c"}}, {Delete, {"entry", "a"}},
|
||||
};
|
||||
const size_t NumUpdates = Updates.size();
|
||||
|
||||
CFGBuilder B(Holder.F, Arcs, Updates);
|
||||
|
||||
EXPECT_TRUE(isa<SwitchInst>(B.getOrAddBlock("entry")->getTerminator()));
|
||||
EXPECT_TRUE(isa<SwitchInst>(B.getOrAddBlock("a")->getTerminator()));
|
||||
EXPECT_TRUE(isa<SwitchInst>(B.getOrAddBlock("c")->getTerminator()));
|
||||
EXPECT_TRUE(isa<SwitchInst>(B.getOrAddBlock("d")->getTerminator()));
|
||||
|
||||
auto UpdateC = B.applyUpdate();
|
||||
|
||||
EXPECT_TRUE(UpdateC);
|
||||
EXPECT_EQ(UpdateC->Action, CFGBuilder::ActionKind::Delete);
|
||||
EXPECT_EQ(UpdateC->Edge.From, "c");
|
||||
EXPECT_EQ(UpdateC->Edge.To, "d");
|
||||
EXPECT_TRUE(isa<UnreachableInst>(B.getOrAddBlock("c")->getTerminator()));
|
||||
|
||||
size_t i = 1;
|
||||
while (B.applyUpdate())
|
||||
++i;
|
||||
EXPECT_EQ(i, NumUpdates);
|
||||
|
||||
EXPECT_TRUE(isa<SwitchInst>(B.getOrAddBlock("a")->getTerminator()));
|
||||
EXPECT_TRUE(isa<UnreachableInst>(B.getOrAddBlock("entry")->getTerminator()));
|
||||
}
|
||||
|
||||
TEST(CFGBuilder, Rebuild) {
|
||||
CFGHolder Holder;
|
||||
std::vector<CFGBuilder::Arc> Arcs = {
|
||||
{"entry", "a"}, {"a", "b"}, {"a", "c"}, {"c", "d"}, {"d", "b"}};
|
||||
const auto Insert = CFGBuilder::ActionKind::Insert;
|
||||
const auto Delete = CFGBuilder::ActionKind::Delete;
|
||||
std::vector<CFGBuilder::Update> Updates = {
|
||||
{Delete, {"c", "d"}}, {Delete, {"a", "c"}}, {Delete, {"entry", "a"}},
|
||||
{Insert, {"c", "d"}}, {Insert, {"a", "c"}}, {Insert, {"entry", "a"}},
|
||||
};
|
||||
const size_t NumUpdates = Updates.size();
|
||||
|
||||
CFGBuilder B(Holder.F, Arcs, Updates);
|
||||
size_t i = 0;
|
||||
while (B.applyUpdate())
|
||||
++i;
|
||||
EXPECT_EQ(i, NumUpdates);
|
||||
|
||||
EXPECT_TRUE(isa<SwitchInst>(B.getOrAddBlock("entry")->getTerminator()));
|
||||
EXPECT_TRUE(isa<SwitchInst>(B.getOrAddBlock("a")->getTerminator()));
|
||||
EXPECT_TRUE(isa<SwitchInst>(B.getOrAddBlock("c")->getTerminator()));
|
||||
EXPECT_TRUE(isa<SwitchInst>(B.getOrAddBlock("d")->getTerminator()));
|
||||
}
|
94
external/llvm/unittests/IR/CFGBuilder.h
vendored
94
external/llvm/unittests/IR/CFGBuilder.h
vendored
@ -1,94 +0,0 @@
|
||||
//===- CFGBuilder.h - CFG building and updating utility ----------*- C++ -*-==//
|
||||
//
|
||||
// The LLVM Compiler Infrastructure
|
||||
//
|
||||
// This file is distributed under the University of Illinois Open Source
|
||||
// License. See LICENSE.TXT for details.
|
||||
//
|
||||
//===----------------------------------------------------------------------===//
|
||||
/// \file
|
||||
/// CFGBuilders provides utilities fo building and updating CFG for testing
|
||||
/// purposes.
|
||||
///
|
||||
//===----------------------------------------------------------------------===//
|
||||
|
||||
#ifndef LLVM_UNITTESTS_CFG_BUILDER_H
|
||||
#define LLVM_UNITTESTS_CFG_BUILDER_H
|
||||
|
||||
#include "llvm/ADT/DenseMap.h"
|
||||
#include "llvm/ADT/Optional.h"
|
||||
#include "llvm/ADT/StringMap.h"
|
||||
#include "llvm/ADT/StringRef.h"
|
||||
#include "llvm/Support/Debug.h"
|
||||
|
||||
#include <memory>
|
||||
#include <set>
|
||||
#include <tuple>
|
||||
#include <vector>
|
||||
|
||||
namespace llvm {
|
||||
|
||||
class LLVMContext;
|
||||
class Module;
|
||||
class Function;
|
||||
class BasicBlock;
|
||||
class raw_ostream;
|
||||
|
||||
struct CFGHolder {
|
||||
std::unique_ptr<LLVMContext> Context;
|
||||
std::unique_ptr<Module> M;
|
||||
Function *F;
|
||||
|
||||
CFGHolder(StringRef ModuleName = "m", StringRef FunctionName = "foo");
|
||||
~CFGHolder(); // Defined in the .cpp file so we can use forward declarations.
|
||||
};
|
||||
|
||||
/// \brief
|
||||
/// CFGBuilder builds IR with specific CFG, based on the supplied list of arcs.
|
||||
/// It's able to apply the provided updates and automatically modify the IR.
|
||||
///
|
||||
/// Internally it makes every basic block end with either SwitchInst or with
|
||||
/// UnreachableInst. When all arc to a BB are deleted, the BB remains in the
|
||||
/// function and doesn't get deleted.
|
||||
///
|
||||
class CFGBuilder {
|
||||
public:
|
||||
struct Arc {
|
||||
StringRef From;
|
||||
StringRef To;
|
||||
|
||||
friend bool operator<(const Arc &LHS, const Arc &RHS) {
|
||||
return std::tie(LHS.From, LHS.To) <
|
||||
std::tie(RHS.From, RHS.To);
|
||||
}
|
||||
};
|
||||
|
||||
enum class ActionKind { Insert, Delete };
|
||||
struct Update {
|
||||
ActionKind Action;
|
||||
Arc Edge;
|
||||
};
|
||||
|
||||
CFGBuilder(Function *F, const std::vector<Arc> &InitialArcs,
|
||||
std::vector<Update> Updates);
|
||||
|
||||
BasicBlock *getOrAddBlock(StringRef BlockName);
|
||||
Optional<Update> getNextUpdate() const;
|
||||
Optional<Update> applyUpdate();
|
||||
void dump(raw_ostream &OS = dbgs()) const;
|
||||
|
||||
private:
|
||||
void buildCFG(const std::vector<Arc> &Arcs);
|
||||
bool connect(const Arc &A);
|
||||
bool disconnect(const Arc &A);
|
||||
|
||||
Function *F;
|
||||
unsigned UpdateIdx = 0;
|
||||
StringMap<BasicBlock *> NameToBlock;
|
||||
std::set<Arc> Arcs;
|
||||
std::vector<Update> Updates;
|
||||
};
|
||||
|
||||
} // namespace llvm
|
||||
|
||||
#endif
|
50
external/llvm/unittests/IR/CMakeLists.txt
vendored
50
external/llvm/unittests/IR/CMakeLists.txt
vendored
@ -1,50 +0,0 @@
|
||||
set(LLVM_LINK_COMPONENTS
|
||||
Analysis
|
||||
AsmParser
|
||||
Core
|
||||
Support
|
||||
Passes
|
||||
)
|
||||
|
||||
set(IRSources
|
||||
AsmWriterTest.cpp
|
||||
AttributesTest.cpp
|
||||
BasicBlockTest.cpp
|
||||
CFGBuilder.cpp
|
||||
ConstantRangeTest.cpp
|
||||
ConstantsTest.cpp
|
||||
DebugInfoTest.cpp
|
||||
DebugTypeODRUniquingTest.cpp
|
||||
DominatorTreeTest.cpp
|
||||
DominatorTreeBatchUpdatesTest.cpp
|
||||
FunctionTest.cpp
|
||||
PassBuilderCallbacksTest.cpp
|
||||
IRBuilderTest.cpp
|
||||
InstructionsTest.cpp
|
||||
IntrinsicsTest.cpp
|
||||
LegacyPassManagerTest.cpp
|
||||
MDBuilderTest.cpp
|
||||
MetadataTest.cpp
|
||||
ModuleTest.cpp
|
||||
PassManagerTest.cpp
|
||||
PatternMatch.cpp
|
||||
TypeBuilderTest.cpp
|
||||
TypesTest.cpp
|
||||
UseTest.cpp
|
||||
UserTest.cpp
|
||||
ValueHandleTest.cpp
|
||||
ValueMapTest.cpp
|
||||
ValueTest.cpp
|
||||
VerifierTest.cpp
|
||||
WaymarkTest.cpp
|
||||
)
|
||||
|
||||
# HACK: Declare a couple of source files as optionally compiled to satisfy the
|
||||
# missing-file-checker in LLVM's weird CMake build.
|
||||
set(LLVM_OPTIONAL_SOURCES
|
||||
ValueMapTest.cpp
|
||||
)
|
||||
|
||||
add_llvm_unittest(IRTests
|
||||
${IRSources}
|
||||
)
|
1024
external/llvm/unittests/IR/ConstantRangeTest.cpp
vendored
1024
external/llvm/unittests/IR/ConstantRangeTest.cpp
vendored
File diff suppressed because it is too large
Load Diff
481
external/llvm/unittests/IR/ConstantsTest.cpp
vendored
481
external/llvm/unittests/IR/ConstantsTest.cpp
vendored
@ -1,481 +0,0 @@
|
||||
//===- llvm/unittest/IR/ConstantsTest.cpp - Constants unit tests ----------===//
|
||||
//
|
||||
// The LLVM Compiler Infrastructure
|
||||
//
|
||||
// This file is distributed under the University of Illinois Open Source
|
||||
// License. See LICENSE.TXT for details.
|
||||
//
|
||||
//===----------------------------------------------------------------------===//
|
||||
|
||||
#include "llvm/IR/Constants.h"
|
||||
#include "llvm-c/Core.h"
|
||||
#include "llvm/AsmParser/Parser.h"
|
||||
#include "llvm/IR/DerivedTypes.h"
|
||||
#include "llvm/IR/InstrTypes.h"
|
||||
#include "llvm/IR/Instruction.h"
|
||||
#include "llvm/IR/LLVMContext.h"
|
||||
#include "llvm/IR/Module.h"
|
||||
#include "llvm/Support/SourceMgr.h"
|
||||
#include "gtest/gtest.h"
|
||||
|
||||
namespace llvm {
|
||||
namespace {
|
||||
|
||||
TEST(ConstantsTest, Integer_i1) {
|
||||
LLVMContext Context;
|
||||
IntegerType *Int1 = IntegerType::get(Context, 1);
|
||||
Constant* One = ConstantInt::get(Int1, 1, true);
|
||||
Constant* Zero = ConstantInt::get(Int1, 0);
|
||||
Constant* NegOne = ConstantInt::get(Int1, static_cast<uint64_t>(-1), true);
|
||||
EXPECT_EQ(NegOne, ConstantInt::getSigned(Int1, -1));
|
||||
Constant* Undef = UndefValue::get(Int1);
|
||||
|
||||
// Input: @b = constant i1 add(i1 1 , i1 1)
|
||||
// Output: @b = constant i1 false
|
||||
EXPECT_EQ(Zero, ConstantExpr::getAdd(One, One));
|
||||
|
||||
// @c = constant i1 add(i1 -1, i1 1)
|
||||
// @c = constant i1 false
|
||||
EXPECT_EQ(Zero, ConstantExpr::getAdd(NegOne, One));
|
||||
|
||||
// @d = constant i1 add(i1 -1, i1 -1)
|
||||
// @d = constant i1 false
|
||||
EXPECT_EQ(Zero, ConstantExpr::getAdd(NegOne, NegOne));
|
||||
|
||||
// @e = constant i1 sub(i1 -1, i1 1)
|
||||
// @e = constant i1 false
|
||||
EXPECT_EQ(Zero, ConstantExpr::getSub(NegOne, One));
|
||||
|
||||
// @f = constant i1 sub(i1 1 , i1 -1)
|
||||
// @f = constant i1 false
|
||||
EXPECT_EQ(Zero, ConstantExpr::getSub(One, NegOne));
|
||||
|
||||
// @g = constant i1 sub(i1 1 , i1 1)
|
||||
// @g = constant i1 false
|
||||
EXPECT_EQ(Zero, ConstantExpr::getSub(One, One));
|
||||
|
||||
// @h = constant i1 shl(i1 1 , i1 1) ; undefined
|
||||
// @h = constant i1 undef
|
||||
EXPECT_EQ(Undef, ConstantExpr::getShl(One, One));
|
||||
|
||||
// @i = constant i1 shl(i1 1 , i1 0)
|
||||
// @i = constant i1 true
|
||||
EXPECT_EQ(One, ConstantExpr::getShl(One, Zero));
|
||||
|
||||
// @j = constant i1 lshr(i1 1, i1 1) ; undefined
|
||||
// @j = constant i1 undef
|
||||
EXPECT_EQ(Undef, ConstantExpr::getLShr(One, One));
|
||||
|
||||
// @m = constant i1 ashr(i1 1, i1 1) ; undefined
|
||||
// @m = constant i1 undef
|
||||
EXPECT_EQ(Undef, ConstantExpr::getAShr(One, One));
|
||||
|
||||
// @n = constant i1 mul(i1 -1, i1 1)
|
||||
// @n = constant i1 true
|
||||
EXPECT_EQ(One, ConstantExpr::getMul(NegOne, One));
|
||||
|
||||
// @o = constant i1 sdiv(i1 -1, i1 1) ; overflow
|
||||
// @o = constant i1 true
|
||||
EXPECT_EQ(One, ConstantExpr::getSDiv(NegOne, One));
|
||||
|
||||
// @p = constant i1 sdiv(i1 1 , i1 -1); overflow
|
||||
// @p = constant i1 true
|
||||
EXPECT_EQ(One, ConstantExpr::getSDiv(One, NegOne));
|
||||
|
||||
// @q = constant i1 udiv(i1 -1, i1 1)
|
||||
// @q = constant i1 true
|
||||
EXPECT_EQ(One, ConstantExpr::getUDiv(NegOne, One));
|
||||
|
||||
// @r = constant i1 udiv(i1 1, i1 -1)
|
||||
// @r = constant i1 true
|
||||
EXPECT_EQ(One, ConstantExpr::getUDiv(One, NegOne));
|
||||
|
||||
// @s = constant i1 srem(i1 -1, i1 1) ; overflow
|
||||
// @s = constant i1 false
|
||||
EXPECT_EQ(Zero, ConstantExpr::getSRem(NegOne, One));
|
||||
|
||||
// @t = constant i1 urem(i1 -1, i1 1)
|
||||
// @t = constant i1 false
|
||||
EXPECT_EQ(Zero, ConstantExpr::getURem(NegOne, One));
|
||||
|
||||
// @u = constant i1 srem(i1 1, i1 -1) ; overflow
|
||||
// @u = constant i1 false
|
||||
EXPECT_EQ(Zero, ConstantExpr::getSRem(One, NegOne));
|
||||
}
|
||||
|
||||
TEST(ConstantsTest, IntSigns) {
|
||||
LLVMContext Context;
|
||||
IntegerType *Int8Ty = Type::getInt8Ty(Context);
|
||||
EXPECT_EQ(100, ConstantInt::get(Int8Ty, 100, false)->getSExtValue());
|
||||
EXPECT_EQ(100, ConstantInt::get(Int8Ty, 100, true)->getSExtValue());
|
||||
EXPECT_EQ(100, ConstantInt::getSigned(Int8Ty, 100)->getSExtValue());
|
||||
EXPECT_EQ(-50, ConstantInt::get(Int8Ty, 206)->getSExtValue());
|
||||
EXPECT_EQ(-50, ConstantInt::getSigned(Int8Ty, -50)->getSExtValue());
|
||||
EXPECT_EQ(206U, ConstantInt::getSigned(Int8Ty, -50)->getZExtValue());
|
||||
|
||||
// Overflow is handled by truncation.
|
||||
EXPECT_EQ(0x3b, ConstantInt::get(Int8Ty, 0x13b)->getSExtValue());
|
||||
}
|
||||
|
||||
TEST(ConstantsTest, FP128Test) {
|
||||
LLVMContext Context;
|
||||
Type *FP128Ty = Type::getFP128Ty(Context);
|
||||
|
||||
IntegerType *Int128Ty = Type::getIntNTy(Context, 128);
|
||||
Constant *Zero128 = Constant::getNullValue(Int128Ty);
|
||||
Constant *X = ConstantExpr::getUIToFP(Zero128, FP128Ty);
|
||||
EXPECT_TRUE(isa<ConstantFP>(X));
|
||||
}
|
||||
|
||||
TEST(ConstantsTest, PointerCast) {
|
||||
LLVMContext C;
|
||||
Type *Int8PtrTy = Type::getInt8PtrTy(C);
|
||||
Type *Int32PtrTy = Type::getInt32PtrTy(C);
|
||||
Type *Int64Ty = Type::getInt64Ty(C);
|
||||
VectorType *Int8PtrVecTy = VectorType::get(Int8PtrTy, 4);
|
||||
VectorType *Int32PtrVecTy = VectorType::get(Int32PtrTy, 4);
|
||||
VectorType *Int64VecTy = VectorType::get(Int64Ty, 4);
|
||||
|
||||
// ptrtoint i8* to i64
|
||||
EXPECT_EQ(Constant::getNullValue(Int64Ty),
|
||||
ConstantExpr::getPointerCast(
|
||||
Constant::getNullValue(Int8PtrTy), Int64Ty));
|
||||
|
||||
// bitcast i8* to i32*
|
||||
EXPECT_EQ(Constant::getNullValue(Int32PtrTy),
|
||||
ConstantExpr::getPointerCast(
|
||||
Constant::getNullValue(Int8PtrTy), Int32PtrTy));
|
||||
|
||||
// ptrtoint <4 x i8*> to <4 x i64>
|
||||
EXPECT_EQ(Constant::getNullValue(Int64VecTy),
|
||||
ConstantExpr::getPointerCast(
|
||||
Constant::getNullValue(Int8PtrVecTy), Int64VecTy));
|
||||
|
||||
// bitcast <4 x i8*> to <4 x i32*>
|
||||
EXPECT_EQ(Constant::getNullValue(Int32PtrVecTy),
|
||||
ConstantExpr::getPointerCast(
|
||||
Constant::getNullValue(Int8PtrVecTy), Int32PtrVecTy));
|
||||
|
||||
Type *Int32Ptr1Ty = Type::getInt32PtrTy(C, 1);
|
||||
ConstantInt *K = ConstantInt::get(Type::getInt64Ty(C), 1234);
|
||||
|
||||
// Make sure that addrspacecast of inttoptr is not folded away.
|
||||
EXPECT_NE(K,
|
||||
ConstantExpr::getAddrSpaceCast(
|
||||
ConstantExpr::getIntToPtr(K, Int32PtrTy), Int32Ptr1Ty));
|
||||
EXPECT_NE(K,
|
||||
ConstantExpr::getAddrSpaceCast(
|
||||
ConstantExpr::getIntToPtr(K, Int32Ptr1Ty), Int32PtrTy));
|
||||
|
||||
Constant *NullInt32Ptr0 = Constant::getNullValue(Int32PtrTy);
|
||||
Constant *NullInt32Ptr1 = Constant::getNullValue(Int32Ptr1Ty);
|
||||
|
||||
// Make sure that addrspacecast of null is not folded away.
|
||||
EXPECT_NE(Constant::getNullValue(Int32PtrTy),
|
||||
ConstantExpr::getAddrSpaceCast(NullInt32Ptr0, Int32Ptr1Ty));
|
||||
|
||||
EXPECT_NE(Constant::getNullValue(Int32Ptr1Ty),
|
||||
ConstantExpr::getAddrSpaceCast(NullInt32Ptr1, Int32PtrTy));
|
||||
}
|
||||
|
||||
#define CHECK(x, y) \
|
||||
{ \
|
||||
std::string __s; \
|
||||
raw_string_ostream __o(__s); \
|
||||
Instruction *__I = cast<ConstantExpr>(x)->getAsInstruction(); \
|
||||
__I->print(__o); \
|
||||
__I->deleteValue(); \
|
||||
__o.flush(); \
|
||||
EXPECT_EQ(std::string(" <badref> = " y), __s); \
|
||||
}
|
||||
|
||||
TEST(ConstantsTest, AsInstructionsTest) {
|
||||
LLVMContext Context;
|
||||
std::unique_ptr<Module> M(new Module("MyModule", Context));
|
||||
|
||||
Type *Int64Ty = Type::getInt64Ty(Context);
|
||||
Type *Int32Ty = Type::getInt32Ty(Context);
|
||||
Type *Int16Ty = Type::getInt16Ty(Context);
|
||||
Type *Int1Ty = Type::getInt1Ty(Context);
|
||||
Type *FloatTy = Type::getFloatTy(Context);
|
||||
Type *DoubleTy = Type::getDoubleTy(Context);
|
||||
|
||||
Constant *Global = M->getOrInsertGlobal("dummy",
|
||||
PointerType::getUnqual(Int32Ty));
|
||||
Constant *Global2 = M->getOrInsertGlobal("dummy2",
|
||||
PointerType::getUnqual(Int32Ty));
|
||||
|
||||
Constant *P0 = ConstantExpr::getPtrToInt(Global, Int32Ty);
|
||||
Constant *P1 = ConstantExpr::getUIToFP(P0, FloatTy);
|
||||
Constant *P2 = ConstantExpr::getUIToFP(P0, DoubleTy);
|
||||
Constant *P3 = ConstantExpr::getTrunc(P0, Int1Ty);
|
||||
Constant *P4 = ConstantExpr::getPtrToInt(Global2, Int32Ty);
|
||||
Constant *P5 = ConstantExpr::getUIToFP(P4, FloatTy);
|
||||
Constant *P6 = ConstantExpr::getBitCast(P4, VectorType::get(Int16Ty, 2));
|
||||
|
||||
Constant *One = ConstantInt::get(Int32Ty, 1);
|
||||
Constant *Two = ConstantInt::get(Int64Ty, 2);
|
||||
Constant *Big = ConstantInt::get(Context, APInt{256, uint64_t(-1), true});
|
||||
Constant *Elt = ConstantInt::get(Int16Ty, 2015);
|
||||
Constant *Undef16 = UndefValue::get(Int16Ty);
|
||||
Constant *Undef64 = UndefValue::get(Int64Ty);
|
||||
Constant *UndefV16 = UndefValue::get(P6->getType());
|
||||
|
||||
#define P0STR "ptrtoint (i32** @dummy to i32)"
|
||||
#define P1STR "uitofp (i32 ptrtoint (i32** @dummy to i32) to float)"
|
||||
#define P2STR "uitofp (i32 ptrtoint (i32** @dummy to i32) to double)"
|
||||
#define P3STR "ptrtoint (i32** @dummy to i1)"
|
||||
#define P4STR "ptrtoint (i32** @dummy2 to i32)"
|
||||
#define P5STR "uitofp (i32 ptrtoint (i32** @dummy2 to i32) to float)"
|
||||
#define P6STR "bitcast (i32 ptrtoint (i32** @dummy2 to i32) to <2 x i16>)"
|
||||
|
||||
CHECK(ConstantExpr::getNeg(P0), "sub i32 0, " P0STR);
|
||||
CHECK(ConstantExpr::getFNeg(P1), "fsub float -0.000000e+00, " P1STR);
|
||||
CHECK(ConstantExpr::getNot(P0), "xor i32 " P0STR ", -1");
|
||||
CHECK(ConstantExpr::getAdd(P0, P0), "add i32 " P0STR ", " P0STR);
|
||||
CHECK(ConstantExpr::getAdd(P0, P0, false, true), "add nsw i32 " P0STR ", "
|
||||
P0STR);
|
||||
CHECK(ConstantExpr::getAdd(P0, P0, true, true), "add nuw nsw i32 " P0STR ", "
|
||||
P0STR);
|
||||
CHECK(ConstantExpr::getFAdd(P1, P1), "fadd float " P1STR ", " P1STR);
|
||||
CHECK(ConstantExpr::getSub(P0, P0), "sub i32 " P0STR ", " P0STR);
|
||||
CHECK(ConstantExpr::getFSub(P1, P1), "fsub float " P1STR ", " P1STR);
|
||||
CHECK(ConstantExpr::getMul(P0, P0), "mul i32 " P0STR ", " P0STR);
|
||||
CHECK(ConstantExpr::getFMul(P1, P1), "fmul float " P1STR ", " P1STR);
|
||||
CHECK(ConstantExpr::getUDiv(P0, P0), "udiv i32 " P0STR ", " P0STR);
|
||||
CHECK(ConstantExpr::getSDiv(P0, P0), "sdiv i32 " P0STR ", " P0STR);
|
||||
CHECK(ConstantExpr::getFDiv(P1, P1), "fdiv float " P1STR ", " P1STR);
|
||||
CHECK(ConstantExpr::getURem(P0, P0), "urem i32 " P0STR ", " P0STR);
|
||||
CHECK(ConstantExpr::getSRem(P0, P0), "srem i32 " P0STR ", " P0STR);
|
||||
CHECK(ConstantExpr::getFRem(P1, P1), "frem float " P1STR ", " P1STR);
|
||||
CHECK(ConstantExpr::getAnd(P0, P0), "and i32 " P0STR ", " P0STR);
|
||||
CHECK(ConstantExpr::getOr(P0, P0), "or i32 " P0STR ", " P0STR);
|
||||
CHECK(ConstantExpr::getXor(P0, P0), "xor i32 " P0STR ", " P0STR);
|
||||
CHECK(ConstantExpr::getShl(P0, P0), "shl i32 " P0STR ", " P0STR);
|
||||
CHECK(ConstantExpr::getShl(P0, P0, true), "shl nuw i32 " P0STR ", " P0STR);
|
||||
CHECK(ConstantExpr::getShl(P0, P0, false, true), "shl nsw i32 " P0STR ", "
|
||||
P0STR);
|
||||
CHECK(ConstantExpr::getLShr(P0, P0, false), "lshr i32 " P0STR ", " P0STR);
|
||||
CHECK(ConstantExpr::getLShr(P0, P0, true), "lshr exact i32 " P0STR ", " P0STR);
|
||||
CHECK(ConstantExpr::getAShr(P0, P0, false), "ashr i32 " P0STR ", " P0STR);
|
||||
CHECK(ConstantExpr::getAShr(P0, P0, true), "ashr exact i32 " P0STR ", " P0STR);
|
||||
|
||||
CHECK(ConstantExpr::getSExt(P0, Int64Ty), "sext i32 " P0STR " to i64");
|
||||
CHECK(ConstantExpr::getZExt(P0, Int64Ty), "zext i32 " P0STR " to i64");
|
||||
CHECK(ConstantExpr::getFPTrunc(P2, FloatTy), "fptrunc double " P2STR
|
||||
" to float");
|
||||
CHECK(ConstantExpr::getFPExtend(P1, DoubleTy), "fpext float " P1STR
|
||||
" to double");
|
||||
|
||||
CHECK(ConstantExpr::getExactUDiv(P0, P0), "udiv exact i32 " P0STR ", " P0STR);
|
||||
|
||||
CHECK(ConstantExpr::getSelect(P3, P0, P4), "select i1 " P3STR ", i32 " P0STR
|
||||
", i32 " P4STR);
|
||||
CHECK(ConstantExpr::getICmp(CmpInst::ICMP_EQ, P0, P4), "icmp eq i32 " P0STR
|
||||
", " P4STR);
|
||||
CHECK(ConstantExpr::getFCmp(CmpInst::FCMP_ULT, P1, P5), "fcmp ult float "
|
||||
P1STR ", " P5STR);
|
||||
|
||||
std::vector<Constant*> V;
|
||||
V.push_back(One);
|
||||
// FIXME: getGetElementPtr() actually creates an inbounds ConstantGEP,
|
||||
// not a normal one!
|
||||
//CHECK(ConstantExpr::getGetElementPtr(Global, V, false),
|
||||
// "getelementptr i32*, i32** @dummy, i32 1");
|
||||
CHECK(ConstantExpr::getInBoundsGetElementPtr(PointerType::getUnqual(Int32Ty),
|
||||
Global, V),
|
||||
"getelementptr inbounds i32*, i32** @dummy, i32 1");
|
||||
|
||||
CHECK(ConstantExpr::getExtractElement(P6, One), "extractelement <2 x i16> "
|
||||
P6STR ", i32 1");
|
||||
|
||||
EXPECT_EQ(Undef16, ConstantExpr::getExtractElement(P6, Two));
|
||||
EXPECT_EQ(Undef16, ConstantExpr::getExtractElement(P6, Big));
|
||||
EXPECT_EQ(Undef16, ConstantExpr::getExtractElement(P6, Undef64));
|
||||
|
||||
EXPECT_EQ(Elt, ConstantExpr::getExtractElement(
|
||||
ConstantExpr::getInsertElement(P6, Elt, One), One));
|
||||
EXPECT_EQ(UndefV16, ConstantExpr::getInsertElement(P6, Elt, Two));
|
||||
EXPECT_EQ(UndefV16, ConstantExpr::getInsertElement(P6, Elt, Big));
|
||||
EXPECT_EQ(UndefV16, ConstantExpr::getInsertElement(P6, Elt, Undef64));
|
||||
}
|
||||
|
||||
#ifdef GTEST_HAS_DEATH_TEST
|
||||
#ifndef NDEBUG
|
||||
TEST(ConstantsTest, ReplaceWithConstantTest) {
|
||||
LLVMContext Context;
|
||||
std::unique_ptr<Module> M(new Module("MyModule", Context));
|
||||
|
||||
Type *Int32Ty = Type::getInt32Ty(Context);
|
||||
Constant *One = ConstantInt::get(Int32Ty, 1);
|
||||
|
||||
Constant *Global =
|
||||
M->getOrInsertGlobal("dummy", PointerType::getUnqual(Int32Ty));
|
||||
Constant *GEP = ConstantExpr::getGetElementPtr(
|
||||
PointerType::getUnqual(Int32Ty), Global, One);
|
||||
EXPECT_DEATH(Global->replaceAllUsesWith(GEP),
|
||||
"this->replaceAllUsesWith\\(expr\\(this\\)\\) is NOT valid!");
|
||||
}
|
||||
|
||||
#endif
|
||||
#endif
|
||||
|
||||
#undef CHECK
|
||||
|
||||
TEST(ConstantsTest, ConstantArrayReplaceWithConstant) {
|
||||
LLVMContext Context;
|
||||
std::unique_ptr<Module> M(new Module("MyModule", Context));
|
||||
|
||||
Type *IntTy = Type::getInt8Ty(Context);
|
||||
ArrayType *ArrayTy = ArrayType::get(IntTy, 2);
|
||||
Constant *A01Vals[2] = {ConstantInt::get(IntTy, 0),
|
||||
ConstantInt::get(IntTy, 1)};
|
||||
Constant *A01 = ConstantArray::get(ArrayTy, A01Vals);
|
||||
|
||||
Constant *Global = new GlobalVariable(*M, IntTy, false,
|
||||
GlobalValue::ExternalLinkage, nullptr);
|
||||
Constant *GlobalInt = ConstantExpr::getPtrToInt(Global, IntTy);
|
||||
Constant *A0GVals[2] = {ConstantInt::get(IntTy, 0), GlobalInt};
|
||||
Constant *A0G = ConstantArray::get(ArrayTy, A0GVals);
|
||||
ASSERT_NE(A01, A0G);
|
||||
|
||||
GlobalVariable *RefArray =
|
||||
new GlobalVariable(*M, ArrayTy, false, GlobalValue::ExternalLinkage, A0G);
|
||||
ASSERT_EQ(A0G, RefArray->getInitializer());
|
||||
|
||||
GlobalInt->replaceAllUsesWith(ConstantInt::get(IntTy, 1));
|
||||
ASSERT_EQ(A01, RefArray->getInitializer());
|
||||
}
|
||||
|
||||
TEST(ConstantsTest, ConstantExprReplaceWithConstant) {
|
||||
LLVMContext Context;
|
||||
std::unique_ptr<Module> M(new Module("MyModule", Context));
|
||||
|
||||
Type *IntTy = Type::getInt8Ty(Context);
|
||||
Constant *G1 = new GlobalVariable(*M, IntTy, false,
|
||||
GlobalValue::ExternalLinkage, nullptr);
|
||||
Constant *G2 = new GlobalVariable(*M, IntTy, false,
|
||||
GlobalValue::ExternalLinkage, nullptr);
|
||||
ASSERT_NE(G1, G2);
|
||||
|
||||
Constant *Int1 = ConstantExpr::getPtrToInt(G1, IntTy);
|
||||
Constant *Int2 = ConstantExpr::getPtrToInt(G2, IntTy);
|
||||
ASSERT_NE(Int1, Int2);
|
||||
|
||||
GlobalVariable *Ref =
|
||||
new GlobalVariable(*M, IntTy, false, GlobalValue::ExternalLinkage, Int1);
|
||||
ASSERT_EQ(Int1, Ref->getInitializer());
|
||||
|
||||
G1->replaceAllUsesWith(G2);
|
||||
ASSERT_EQ(Int2, Ref->getInitializer());
|
||||
}
|
||||
|
||||
TEST(ConstantsTest, GEPReplaceWithConstant) {
|
||||
LLVMContext Context;
|
||||
std::unique_ptr<Module> M(new Module("MyModule", Context));
|
||||
|
||||
Type *IntTy = Type::getInt32Ty(Context);
|
||||
Type *PtrTy = PointerType::get(IntTy, 0);
|
||||
auto *C1 = ConstantInt::get(IntTy, 1);
|
||||
auto *Placeholder = new GlobalVariable(
|
||||
*M, IntTy, false, GlobalValue::ExternalWeakLinkage, nullptr);
|
||||
auto *GEP = ConstantExpr::getGetElementPtr(IntTy, Placeholder, C1);
|
||||
ASSERT_EQ(GEP->getOperand(0), Placeholder);
|
||||
|
||||
auto *Ref =
|
||||
new GlobalVariable(*M, PtrTy, false, GlobalValue::ExternalLinkage, GEP);
|
||||
ASSERT_EQ(GEP, Ref->getInitializer());
|
||||
|
||||
auto *Global = new GlobalVariable(*M, PtrTy, false,
|
||||
GlobalValue::ExternalLinkage, nullptr);
|
||||
auto *Alias = GlobalAlias::create(IntTy, 0, GlobalValue::ExternalLinkage,
|
||||
"alias", Global, M.get());
|
||||
Placeholder->replaceAllUsesWith(Alias);
|
||||
ASSERT_EQ(GEP, Ref->getInitializer());
|
||||
ASSERT_EQ(GEP->getOperand(0), Alias);
|
||||
}
|
||||
|
||||
TEST(ConstantsTest, AliasCAPI) {
|
||||
LLVMContext Context;
|
||||
SMDiagnostic Error;
|
||||
std::unique_ptr<Module> M =
|
||||
parseAssemblyString("@g = global i32 42", Error, Context);
|
||||
GlobalVariable *G = M->getGlobalVariable("g");
|
||||
Type *I16Ty = Type::getInt16Ty(Context);
|
||||
Type *I16PTy = PointerType::get(I16Ty, 0);
|
||||
Constant *Aliasee = ConstantExpr::getBitCast(G, I16PTy);
|
||||
LLVMValueRef AliasRef =
|
||||
LLVMAddAlias(wrap(M.get()), wrap(I16PTy), wrap(Aliasee), "a");
|
||||
ASSERT_EQ(unwrap<GlobalAlias>(AliasRef)->getAliasee(), Aliasee);
|
||||
}
|
||||
|
||||
static std::string getNameOfType(Type *T) {
|
||||
std::string S;
|
||||
raw_string_ostream RSOS(S);
|
||||
T->print(RSOS);
|
||||
return S;
|
||||
}
|
||||
|
||||
TEST(ConstantsTest, BuildConstantDataArrays) {
|
||||
LLVMContext Context;
|
||||
std::unique_ptr<Module> M(new Module("MyModule", Context));
|
||||
|
||||
for (Type *T : {Type::getInt8Ty(Context), Type::getInt16Ty(Context),
|
||||
Type::getInt32Ty(Context), Type::getInt64Ty(Context)}) {
|
||||
ArrayType *ArrayTy = ArrayType::get(T, 2);
|
||||
Constant *Vals[] = {ConstantInt::get(T, 0), ConstantInt::get(T, 1)};
|
||||
Constant *CDV = ConstantArray::get(ArrayTy, Vals);
|
||||
ASSERT_TRUE(dyn_cast<ConstantDataArray>(CDV) != nullptr)
|
||||
<< " T = " << getNameOfType(T);
|
||||
}
|
||||
|
||||
for (Type *T : {Type::getHalfTy(Context), Type::getFloatTy(Context),
|
||||
Type::getDoubleTy(Context)}) {
|
||||
ArrayType *ArrayTy = ArrayType::get(T, 2);
|
||||
Constant *Vals[] = {ConstantFP::get(T, 0), ConstantFP::get(T, 1)};
|
||||
Constant *CDV = ConstantArray::get(ArrayTy, Vals);
|
||||
ASSERT_TRUE(dyn_cast<ConstantDataArray>(CDV) != nullptr)
|
||||
<< " T = " << getNameOfType(T);
|
||||
}
|
||||
}
|
||||
|
||||
TEST(ConstantsTest, BuildConstantDataVectors) {
|
||||
LLVMContext Context;
|
||||
std::unique_ptr<Module> M(new Module("MyModule", Context));
|
||||
|
||||
for (Type *T : {Type::getInt8Ty(Context), Type::getInt16Ty(Context),
|
||||
Type::getInt32Ty(Context), Type::getInt64Ty(Context)}) {
|
||||
Constant *Vals[] = {ConstantInt::get(T, 0), ConstantInt::get(T, 1)};
|
||||
Constant *CDV = ConstantVector::get(Vals);
|
||||
ASSERT_TRUE(dyn_cast<ConstantDataVector>(CDV) != nullptr)
|
||||
<< " T = " << getNameOfType(T);
|
||||
}
|
||||
|
||||
for (Type *T : {Type::getHalfTy(Context), Type::getFloatTy(Context),
|
||||
Type::getDoubleTy(Context)}) {
|
||||
Constant *Vals[] = {ConstantFP::get(T, 0), ConstantFP::get(T, 1)};
|
||||
Constant *CDV = ConstantVector::get(Vals);
|
||||
ASSERT_TRUE(dyn_cast<ConstantDataVector>(CDV) != nullptr)
|
||||
<< " T = " << getNameOfType(T);
|
||||
}
|
||||
}
|
||||
|
||||
TEST(ConstantsTest, BitcastToGEP) {
|
||||
LLVMContext Context;
|
||||
std::unique_ptr<Module> M(new Module("MyModule", Context));
|
||||
|
||||
auto *i32 = Type::getInt32Ty(Context);
|
||||
auto *U = StructType::create(Context, "Unsized");
|
||||
Type *EltTys[] = {i32, U};
|
||||
auto *S = StructType::create(EltTys);
|
||||
|
||||
auto *G = new GlobalVariable(*M, S, false,
|
||||
GlobalValue::ExternalLinkage, nullptr);
|
||||
auto *PtrTy = PointerType::get(i32, 0);
|
||||
auto *C = ConstantExpr::getBitCast(G, PtrTy);
|
||||
ASSERT_EQ(dyn_cast<ConstantExpr>(C)->getOpcode(),
|
||||
Instruction::BitCast);
|
||||
}
|
||||
|
||||
} // end anonymous namespace
|
||||
} // end namespace llvm
|
83
external/llvm/unittests/IR/DebugInfoTest.cpp
vendored
83
external/llvm/unittests/IR/DebugInfoTest.cpp
vendored
@ -1,83 +0,0 @@
|
||||
//===- llvm/unittest/IR/DebugInfo.cpp - DebugInfo tests -------------------===//
|
||||
//
|
||||
// The LLVM Compiler Infrastructure
|
||||
//
|
||||
// This file is distributed under the University of Illinois Open Source
|
||||
// License. See LICENSE.TXT for details.
|
||||
//
|
||||
//===----------------------------------------------------------------------===//
|
||||
|
||||
#include "llvm/IR/DebugInfoMetadata.h"
|
||||
#include "gtest/gtest.h"
|
||||
|
||||
using namespace llvm;
|
||||
|
||||
namespace {
|
||||
|
||||
TEST(DINodeTest, getFlag) {
|
||||
// Some valid flags.
|
||||
EXPECT_EQ(DINode::FlagPublic, DINode::getFlag("DIFlagPublic"));
|
||||
EXPECT_EQ(DINode::FlagProtected, DINode::getFlag("DIFlagProtected"));
|
||||
EXPECT_EQ(DINode::FlagPrivate, DINode::getFlag("DIFlagPrivate"));
|
||||
EXPECT_EQ(DINode::FlagVector, DINode::getFlag("DIFlagVector"));
|
||||
EXPECT_EQ(DINode::FlagRValueReference,
|
||||
DINode::getFlag("DIFlagRValueReference"));
|
||||
|
||||
// FlagAccessibility shouldn't work.
|
||||
EXPECT_EQ(0u, DINode::getFlag("DIFlagAccessibility"));
|
||||
|
||||
// Some other invalid strings.
|
||||
EXPECT_EQ(0u, DINode::getFlag("FlagVector"));
|
||||
EXPECT_EQ(0u, DINode::getFlag("Vector"));
|
||||
EXPECT_EQ(0u, DINode::getFlag("other things"));
|
||||
EXPECT_EQ(0u, DINode::getFlag("DIFlagOther"));
|
||||
}
|
||||
|
||||
TEST(DINodeTest, getFlagString) {
|
||||
// Some valid flags.
|
||||
EXPECT_EQ(StringRef("DIFlagPublic"),
|
||||
DINode::getFlagString(DINode::FlagPublic));
|
||||
EXPECT_EQ(StringRef("DIFlagProtected"),
|
||||
DINode::getFlagString(DINode::FlagProtected));
|
||||
EXPECT_EQ(StringRef("DIFlagPrivate"),
|
||||
DINode::getFlagString(DINode::FlagPrivate));
|
||||
EXPECT_EQ(StringRef("DIFlagVector"),
|
||||
DINode::getFlagString(DINode::FlagVector));
|
||||
EXPECT_EQ(StringRef("DIFlagRValueReference"),
|
||||
DINode::getFlagString(DINode::FlagRValueReference));
|
||||
|
||||
// FlagAccessibility actually equals FlagPublic.
|
||||
EXPECT_EQ(StringRef("DIFlagPublic"),
|
||||
DINode::getFlagString(DINode::FlagAccessibility));
|
||||
|
||||
// Some other invalid flags.
|
||||
EXPECT_EQ(StringRef(),
|
||||
DINode::getFlagString(DINode::FlagPublic | DINode::FlagVector));
|
||||
EXPECT_EQ(StringRef(), DINode::getFlagString(DINode::FlagFwdDecl |
|
||||
DINode::FlagArtificial));
|
||||
EXPECT_EQ(StringRef(),
|
||||
DINode::getFlagString(static_cast<DINode::DIFlags>(0xffff)));
|
||||
}
|
||||
|
||||
TEST(DINodeTest, splitFlags) {
|
||||
// Some valid flags.
|
||||
#define CHECK_SPLIT(FLAGS, VECTOR, REMAINDER) \
|
||||
{ \
|
||||
SmallVector<DINode::DIFlags, 8> V; \
|
||||
EXPECT_EQ(REMAINDER, DINode::splitFlags(FLAGS, V)); \
|
||||
EXPECT_TRUE(makeArrayRef(V).equals(VECTOR)); \
|
||||
}
|
||||
CHECK_SPLIT(DINode::FlagPublic, {DINode::FlagPublic}, DINode::FlagZero);
|
||||
CHECK_SPLIT(DINode::FlagProtected, {DINode::FlagProtected}, DINode::FlagZero);
|
||||
CHECK_SPLIT(DINode::FlagPrivate, {DINode::FlagPrivate}, DINode::FlagZero);
|
||||
CHECK_SPLIT(DINode::FlagVector, {DINode::FlagVector}, DINode::FlagZero);
|
||||
CHECK_SPLIT(DINode::FlagRValueReference, {DINode::FlagRValueReference},
|
||||
DINode::FlagZero);
|
||||
DINode::DIFlags Flags[] = {DINode::FlagFwdDecl, DINode::FlagVector};
|
||||
CHECK_SPLIT(DINode::FlagFwdDecl | DINode::FlagVector, Flags,
|
||||
DINode::FlagZero);
|
||||
CHECK_SPLIT(DINode::FlagZero, {}, DINode::FlagZero);
|
||||
#undef CHECK_SPLIT
|
||||
}
|
||||
|
||||
} // end namespace
|
@ -1,159 +0,0 @@
|
||||
//===- DebugTypeODRUniquingTest.cpp - Debug type ODR uniquing tests -------===//
|
||||
//
|
||||
// The LLVM Compiler Infrastructure
|
||||
//
|
||||
// This file is distributed under the University of Illinois Open Source
|
||||
// License. See LICENSE.TXT for details.
|
||||
//
|
||||
//===----------------------------------------------------------------------===//
|
||||
|
||||
#include "llvm/IR/DebugInfoMetadata.h"
|
||||
#include "llvm/IR/LLVMContext.h"
|
||||
#include "gtest/gtest.h"
|
||||
using namespace llvm;
|
||||
|
||||
namespace {
|
||||
|
||||
TEST(DebugTypeODRUniquingTest, enableDebugTypeODRUniquing) {
|
||||
LLVMContext Context;
|
||||
EXPECT_FALSE(Context.isODRUniquingDebugTypes());
|
||||
Context.enableDebugTypeODRUniquing();
|
||||
EXPECT_TRUE(Context.isODRUniquingDebugTypes());
|
||||
Context.disableDebugTypeODRUniquing();
|
||||
EXPECT_FALSE(Context.isODRUniquingDebugTypes());
|
||||
}
|
||||
|
||||
TEST(DebugTypeODRUniquingTest, getODRType) {
|
||||
LLVMContext Context;
|
||||
MDString &UUID = *MDString::get(Context, "string");
|
||||
|
||||
// Without a type map, this should return null.
|
||||
EXPECT_FALSE(DICompositeType::getODRType(
|
||||
Context, UUID, dwarf::DW_TAG_class_type, nullptr, nullptr, 0, nullptr,
|
||||
nullptr, 0, 0, 0, DINode::FlagZero, nullptr, 0, nullptr, nullptr));
|
||||
|
||||
// Enable the mapping. There still shouldn't be a type.
|
||||
Context.enableDebugTypeODRUniquing();
|
||||
EXPECT_FALSE(DICompositeType::getODRTypeIfExists(Context, UUID));
|
||||
|
||||
// Create some ODR-uniqued type.
|
||||
auto &CT = *DICompositeType::getODRType(
|
||||
Context, UUID, dwarf::DW_TAG_class_type, nullptr, nullptr, 0, nullptr,
|
||||
nullptr, 0, 0, 0, DINode::FlagZero, nullptr, 0, nullptr, nullptr);
|
||||
EXPECT_EQ(UUID.getString(), CT.getIdentifier());
|
||||
|
||||
// Check that we get it back, even if we change a field.
|
||||
EXPECT_EQ(&CT, DICompositeType::getODRTypeIfExists(Context, UUID));
|
||||
EXPECT_EQ(&CT, DICompositeType::getODRType(
|
||||
Context, UUID, dwarf::DW_TAG_class_type, nullptr, nullptr,
|
||||
0, nullptr, nullptr, 0, 0, 0, DINode::FlagZero, nullptr, 0,
|
||||
nullptr, nullptr));
|
||||
EXPECT_EQ(&CT,
|
||||
DICompositeType::getODRType(
|
||||
Context, UUID, dwarf::DW_TAG_class_type,
|
||||
MDString::get(Context, "name"), nullptr, 0, nullptr, nullptr, 0,
|
||||
0, 0, DINode::FlagZero, nullptr, 0, nullptr, nullptr));
|
||||
|
||||
// Check that it's discarded with the type map.
|
||||
Context.disableDebugTypeODRUniquing();
|
||||
EXPECT_FALSE(DICompositeType::getODRTypeIfExists(Context, UUID));
|
||||
|
||||
// And it shouldn't magically reappear...
|
||||
Context.enableDebugTypeODRUniquing();
|
||||
EXPECT_FALSE(DICompositeType::getODRTypeIfExists(Context, UUID));
|
||||
}
|
||||
|
||||
TEST(DebugTypeODRUniquingTest, buildODRType) {
|
||||
LLVMContext Context;
|
||||
Context.enableDebugTypeODRUniquing();
|
||||
|
||||
// Build an ODR type that's a forward decl.
|
||||
MDString &UUID = *MDString::get(Context, "Type");
|
||||
auto &CT = *DICompositeType::buildODRType(
|
||||
Context, UUID, dwarf::DW_TAG_class_type, nullptr, nullptr, 0, nullptr,
|
||||
nullptr, 0, 0, 0, DINode::FlagFwdDecl, nullptr, 0, nullptr, nullptr);
|
||||
EXPECT_EQ(&CT, DICompositeType::getODRTypeIfExists(Context, UUID));
|
||||
EXPECT_EQ(dwarf::DW_TAG_class_type, CT.getTag());
|
||||
|
||||
// Update with another forward decl. This should be a no-op.
|
||||
EXPECT_EQ(&CT, DICompositeType::buildODRType(
|
||||
Context, UUID, dwarf::DW_TAG_structure_type, nullptr, nullptr, 0, nullptr,
|
||||
nullptr, 0, 0, 0, DINode::FlagFwdDecl, nullptr, 0, nullptr, nullptr));
|
||||
EXPECT_EQ(dwarf::DW_TAG_class_type, CT.getTag());
|
||||
|
||||
// Update with a definition. This time we should see a change.
|
||||
EXPECT_EQ(&CT, DICompositeType::buildODRType(
|
||||
Context, UUID, dwarf::DW_TAG_structure_type, nullptr,
|
||||
nullptr, 0, nullptr, nullptr, 0, 0, 0, DINode::FlagZero,
|
||||
nullptr, 0, nullptr, nullptr));
|
||||
EXPECT_EQ(dwarf::DW_TAG_structure_type, CT.getTag());
|
||||
|
||||
// Further updates should be ignored.
|
||||
EXPECT_EQ(&CT, DICompositeType::buildODRType(
|
||||
Context, UUID, dwarf::DW_TAG_class_type, nullptr, nullptr, 0, nullptr,
|
||||
nullptr, 0, 0, 0, DINode::FlagFwdDecl, nullptr, 0, nullptr, nullptr));
|
||||
EXPECT_EQ(dwarf::DW_TAG_structure_type, CT.getTag());
|
||||
EXPECT_EQ(&CT, DICompositeType::buildODRType(
|
||||
Context, UUID, dwarf::DW_TAG_class_type, nullptr, nullptr,
|
||||
0, nullptr, nullptr, 0, 0, 0, DINode::FlagZero, nullptr, 0,
|
||||
nullptr, nullptr));
|
||||
EXPECT_EQ(dwarf::DW_TAG_structure_type, CT.getTag());
|
||||
}
|
||||
|
||||
TEST(DebugTypeODRUniquingTest, buildODRTypeFields) {
|
||||
LLVMContext Context;
|
||||
Context.enableDebugTypeODRUniquing();
|
||||
|
||||
// Build an ODR type that's a forward decl with no other fields set.
|
||||
MDString &UUID = *MDString::get(Context, "UUID");
|
||||
auto &CT = *DICompositeType::buildODRType(
|
||||
Context, UUID, 0, nullptr, nullptr, 0, nullptr, nullptr, 0, 0, 0,
|
||||
DINode::FlagFwdDecl, nullptr, 0, nullptr, nullptr);
|
||||
|
||||
// Create macros for running through all the fields except Identifier and Flags.
|
||||
#define FOR_EACH_MDFIELD() \
|
||||
DO_FOR_FIELD(Name) \
|
||||
DO_FOR_FIELD(File) \
|
||||
DO_FOR_FIELD(Scope) \
|
||||
DO_FOR_FIELD(BaseType) \
|
||||
DO_FOR_FIELD(Elements) \
|
||||
DO_FOR_FIELD(VTableHolder) \
|
||||
DO_FOR_FIELD(TemplateParams)
|
||||
#define FOR_EACH_INLINEFIELD() \
|
||||
DO_FOR_FIELD(Tag) \
|
||||
DO_FOR_FIELD(Line) \
|
||||
DO_FOR_FIELD(SizeInBits) \
|
||||
DO_FOR_FIELD(AlignInBits) \
|
||||
DO_FOR_FIELD(OffsetInBits) \
|
||||
DO_FOR_FIELD(RuntimeLang)
|
||||
|
||||
// Create all the fields.
|
||||
#define DO_FOR_FIELD(X) auto *X = MDString::get(Context, #X);
|
||||
FOR_EACH_MDFIELD();
|
||||
#undef DO_FOR_FIELD
|
||||
unsigned NonZeroInit = 0;
|
||||
#define DO_FOR_FIELD(X) auto X = ++NonZeroInit;
|
||||
FOR_EACH_INLINEFIELD();
|
||||
#undef DO_FOR_FIELD
|
||||
|
||||
// Replace all the fields with new values that are distinct from each other.
|
||||
EXPECT_EQ(&CT,
|
||||
DICompositeType::buildODRType(
|
||||
Context, UUID, Tag, Name, File, Line, Scope, BaseType,
|
||||
SizeInBits, AlignInBits, OffsetInBits, DINode::FlagArtificial,
|
||||
Elements, RuntimeLang, VTableHolder, TemplateParams));
|
||||
|
||||
// Confirm that all the right fields got updated.
|
||||
#define DO_FOR_FIELD(X) EXPECT_EQ(X, CT.getRaw##X());
|
||||
FOR_EACH_MDFIELD();
|
||||
#undef DO_FOR_FIELD
|
||||
#undef FOR_EACH_MDFIELD
|
||||
#define DO_FOR_FIELD(X) EXPECT_EQ(X, CT.get##X());
|
||||
FOR_EACH_INLINEFIELD();
|
||||
#undef DO_FOR_FIELD
|
||||
#undef FOR_EACH_INLINEFIELD
|
||||
EXPECT_EQ(DINode::FlagArtificial, CT.getFlags());
|
||||
EXPECT_EQ(&UUID, CT.getRawIdentifier());
|
||||
}
|
||||
|
||||
} // end namespace
|
@ -1,355 +0,0 @@
|
||||
//===- llvm/unittests/IR/DominatorTreeBatchUpdatesTest.cpp ----------------===//
|
||||
//
|
||||
// The LLVM Compiler Infrastructure
|
||||
//
|
||||
// This file is distributed under the University of Illinois Open Source
|
||||
// License. See LICENSE.TXT for details.
|
||||
//
|
||||
//===----------------------------------------------------------------------===//
|
||||
|
||||
#include <random>
|
||||
#include "CFGBuilder.h"
|
||||
#include "gtest/gtest.h"
|
||||
#include "llvm/Analysis/PostDominators.h"
|
||||
#include "llvm/IR/Dominators.h"
|
||||
#include "llvm/Support/GenericDomTreeConstruction.h"
|
||||
|
||||
#define DEBUG_TYPE "batch-update-tests"
|
||||
|
||||
using namespace llvm;
|
||||
|
||||
namespace {
|
||||
const auto CFGInsert = CFGBuilder::ActionKind::Insert;
|
||||
const auto CFGDelete = CFGBuilder::ActionKind::Delete;
|
||||
|
||||
struct PostDomTree : PostDomTreeBase<BasicBlock> {
|
||||
PostDomTree(Function &F) { recalculate(F); }
|
||||
};
|
||||
|
||||
using DomUpdate = DominatorTree::UpdateType;
|
||||
static_assert(
|
||||
std::is_same<DomUpdate, PostDomTree::UpdateType>::value,
|
||||
"Trees differing only in IsPostDom should have the same update types");
|
||||
using DomSNCA = DomTreeBuilder::SemiNCAInfo<DomTreeBuilder::BBDomTree>;
|
||||
using PostDomSNCA = DomTreeBuilder::SemiNCAInfo<DomTreeBuilder::BBPostDomTree>;
|
||||
const auto Insert = DominatorTree::Insert;
|
||||
const auto Delete = DominatorTree::Delete;
|
||||
|
||||
std::vector<DomUpdate> ToDomUpdates(CFGBuilder &B,
|
||||
std::vector<CFGBuilder::Update> &In) {
|
||||
std::vector<DomUpdate> Res;
|
||||
Res.reserve(In.size());
|
||||
|
||||
for (const auto &CFGU : In)
|
||||
Res.push_back({CFGU.Action == CFGInsert ? Insert : Delete,
|
||||
B.getOrAddBlock(CFGU.Edge.From),
|
||||
B.getOrAddBlock(CFGU.Edge.To)});
|
||||
return Res;
|
||||
}
|
||||
} // namespace
|
||||
|
||||
TEST(DominatorTreeBatchUpdates, LegalizeDomUpdates) {
|
||||
CFGHolder Holder;
|
||||
CFGBuilder Builder(Holder.F, {{"A", "B"}}, {});
|
||||
|
||||
BasicBlock *A = Builder.getOrAddBlock("A");
|
||||
BasicBlock *B = Builder.getOrAddBlock("B");
|
||||
BasicBlock *C = Builder.getOrAddBlock("C");
|
||||
BasicBlock *D = Builder.getOrAddBlock("D");
|
||||
|
||||
std::vector<DomUpdate> Updates = {
|
||||
{Insert, B, C}, {Insert, C, D}, {Delete, B, C}, {Insert, B, C},
|
||||
{Insert, B, D}, {Delete, C, D}, {Delete, A, B}};
|
||||
SmallVector<DomUpdate, 4> Legalized;
|
||||
DomSNCA::LegalizeUpdates(Updates, Legalized);
|
||||
DEBUG(dbgs() << "Legalized updates:\t");
|
||||
DEBUG(for (auto &U : Legalized) dbgs() << U << ", ");
|
||||
DEBUG(dbgs() << "\n");
|
||||
EXPECT_EQ(Legalized.size(), 3UL);
|
||||
EXPECT_NE(llvm::find(Legalized, DomUpdate{Insert, B, C}), Legalized.end());
|
||||
EXPECT_NE(llvm::find(Legalized, DomUpdate{Insert, B, D}), Legalized.end());
|
||||
EXPECT_NE(llvm::find(Legalized, DomUpdate{Delete, A, B}), Legalized.end());
|
||||
}
|
||||
|
||||
TEST(DominatorTreeBatchUpdates, LegalizePostDomUpdates) {
|
||||
CFGHolder Holder;
|
||||
CFGBuilder Builder(Holder.F, {{"A", "B"}}, {});
|
||||
|
||||
BasicBlock *A = Builder.getOrAddBlock("A");
|
||||
BasicBlock *B = Builder.getOrAddBlock("B");
|
||||
BasicBlock *C = Builder.getOrAddBlock("C");
|
||||
BasicBlock *D = Builder.getOrAddBlock("D");
|
||||
|
||||
std::vector<DomUpdate> Updates = {
|
||||
{Insert, B, C}, {Insert, C, D}, {Delete, B, C}, {Insert, B, C},
|
||||
{Insert, B, D}, {Delete, C, D}, {Delete, A, B}};
|
||||
SmallVector<DomUpdate, 4> Legalized;
|
||||
PostDomSNCA::LegalizeUpdates(Updates, Legalized);
|
||||
DEBUG(dbgs() << "Legalized postdom updates:\t");
|
||||
DEBUG(for (auto &U : Legalized) dbgs() << U << ", ");
|
||||
DEBUG(dbgs() << "\n");
|
||||
EXPECT_EQ(Legalized.size(), 3UL);
|
||||
EXPECT_NE(llvm::find(Legalized, DomUpdate{Insert, C, B}), Legalized.end());
|
||||
EXPECT_NE(llvm::find(Legalized, DomUpdate{Insert, D, B}), Legalized.end());
|
||||
EXPECT_NE(llvm::find(Legalized, DomUpdate{Delete, B, A}), Legalized.end());
|
||||
}
|
||||
|
||||
TEST(DominatorTreeBatchUpdates, SingleInsertion) {
|
||||
CFGHolder Holder;
|
||||
CFGBuilder Builder(Holder.F, {{"A", "B"}}, {{CFGInsert, {"B", "C"}}});
|
||||
|
||||
DominatorTree DT(*Holder.F);
|
||||
EXPECT_TRUE(DT.verify());
|
||||
PostDomTree PDT(*Holder.F);
|
||||
EXPECT_TRUE(DT.verify());
|
||||
|
||||
BasicBlock *B = Builder.getOrAddBlock("B");
|
||||
BasicBlock *C = Builder.getOrAddBlock("C");
|
||||
std::vector<DomUpdate> Updates = {{Insert, B, C}};
|
||||
|
||||
ASSERT_TRUE(Builder.applyUpdate());
|
||||
|
||||
DT.applyUpdates(Updates);
|
||||
EXPECT_TRUE(DT.verify());
|
||||
PDT.applyUpdates(Updates);
|
||||
EXPECT_TRUE(PDT.verify());
|
||||
}
|
||||
|
||||
TEST(DominatorTreeBatchUpdates, SingleDeletion) {
|
||||
CFGHolder Holder;
|
||||
CFGBuilder Builder(Holder.F, {{"A", "B"}, {"B", "C"}},
|
||||
{{CFGDelete, {"B", "C"}}});
|
||||
|
||||
DominatorTree DT(*Holder.F);
|
||||
EXPECT_TRUE(DT.verify());
|
||||
PostDomTree PDT(*Holder.F);
|
||||
EXPECT_TRUE(DT.verify());
|
||||
|
||||
BasicBlock *B = Builder.getOrAddBlock("B");
|
||||
BasicBlock *C = Builder.getOrAddBlock("C");
|
||||
std::vector<DomUpdate> Updates = {{Delete, B, C}};
|
||||
|
||||
ASSERT_TRUE(Builder.applyUpdate());
|
||||
|
||||
DT.applyUpdates(Updates);
|
||||
EXPECT_TRUE(DT.verify());
|
||||
PDT.applyUpdates(Updates);
|
||||
EXPECT_TRUE(PDT.verify());
|
||||
}
|
||||
|
||||
TEST(DominatorTreeBatchUpdates, FewInsertion) {
|
||||
std::vector<CFGBuilder::Update> CFGUpdates = {{CFGInsert, {"B", "C"}},
|
||||
{CFGInsert, {"C", "B"}},
|
||||
{CFGInsert, {"C", "D"}},
|
||||
{CFGInsert, {"D", "E"}}};
|
||||
|
||||
CFGHolder Holder;
|
||||
CFGBuilder Builder(Holder.F, {{"A", "B"}}, CFGUpdates);
|
||||
|
||||
DominatorTree DT(*Holder.F);
|
||||
EXPECT_TRUE(DT.verify());
|
||||
PostDomTree PDT(*Holder.F);
|
||||
EXPECT_TRUE(PDT.verify());
|
||||
|
||||
BasicBlock *B = Builder.getOrAddBlock("B");
|
||||
BasicBlock *C = Builder.getOrAddBlock("C");
|
||||
BasicBlock *D = Builder.getOrAddBlock("D");
|
||||
BasicBlock *E = Builder.getOrAddBlock("E");
|
||||
|
||||
std::vector<DomUpdate> Updates = {
|
||||
{Insert, B, C}, {Insert, C, B}, {Insert, C, D}, {Insert, D, E}};
|
||||
|
||||
while (Builder.applyUpdate())
|
||||
;
|
||||
|
||||
DT.applyUpdates(Updates);
|
||||
EXPECT_TRUE(DT.verify());
|
||||
PDT.applyUpdates(Updates);
|
||||
EXPECT_TRUE(PDT.verify());
|
||||
}
|
||||
|
||||
TEST(DominatorTreeBatchUpdates, FewDeletions) {
|
||||
std::vector<CFGBuilder::Update> CFGUpdates = {{CFGDelete, {"B", "C"}},
|
||||
{CFGDelete, {"C", "B"}},
|
||||
{CFGDelete, {"B", "D"}},
|
||||
{CFGDelete, {"D", "E"}}};
|
||||
|
||||
CFGHolder Holder;
|
||||
CFGBuilder Builder(
|
||||
Holder.F, {{"A", "B"}, {"B", "C"}, {"B", "D"}, {"D", "E"}, {"C", "B"}},
|
||||
CFGUpdates);
|
||||
|
||||
DominatorTree DT(*Holder.F);
|
||||
EXPECT_TRUE(DT.verify());
|
||||
PostDomTree PDT(*Holder.F);
|
||||
EXPECT_TRUE(PDT.verify());
|
||||
|
||||
auto Updates = ToDomUpdates(Builder, CFGUpdates);
|
||||
|
||||
while (Builder.applyUpdate())
|
||||
;
|
||||
|
||||
DT.applyUpdates(Updates);
|
||||
EXPECT_TRUE(DT.verify());
|
||||
PDT.applyUpdates(Updates);
|
||||
EXPECT_TRUE(PDT.verify());
|
||||
}
|
||||
|
||||
TEST(DominatorTreeBatchUpdates, InsertDelete) {
|
||||
std::vector<CFGBuilder::Arc> Arcs = {
|
||||
{"1", "2"}, {"2", "3"}, {"3", "4"}, {"4", "5"}, {"5", "6"}, {"5", "7"},
|
||||
{"3", "8"}, {"8", "9"}, {"9", "10"}, {"8", "11"}, {"11", "12"}};
|
||||
|
||||
std::vector<CFGBuilder::Update> Updates = {
|
||||
{CFGInsert, {"2", "4"}}, {CFGInsert, {"12", "10"}},
|
||||
{CFGInsert, {"10", "9"}}, {CFGInsert, {"7", "6"}},
|
||||
{CFGInsert, {"7", "5"}}, {CFGDelete, {"3", "8"}},
|
||||
{CFGInsert, {"10", "7"}}, {CFGInsert, {"2", "8"}},
|
||||
{CFGDelete, {"3", "4"}}, {CFGDelete, {"8", "9"}},
|
||||
{CFGDelete, {"11", "12"}}};
|
||||
|
||||
CFGHolder Holder;
|
||||
CFGBuilder B(Holder.F, Arcs, Updates);
|
||||
DominatorTree DT(*Holder.F);
|
||||
EXPECT_TRUE(DT.verify());
|
||||
PostDomTree PDT(*Holder.F);
|
||||
EXPECT_TRUE(PDT.verify());
|
||||
|
||||
while (B.applyUpdate())
|
||||
;
|
||||
|
||||
auto DomUpdates = ToDomUpdates(B, Updates);
|
||||
DT.applyUpdates(DomUpdates);
|
||||
EXPECT_TRUE(DT.verify());
|
||||
PDT.applyUpdates(DomUpdates);
|
||||
EXPECT_TRUE(PDT.verify());
|
||||
}
|
||||
|
||||
TEST(DominatorTreeBatchUpdates, InsertDeleteExhaustive) {
|
||||
std::vector<CFGBuilder::Arc> Arcs = {
|
||||
{"1", "2"}, {"2", "3"}, {"3", "4"}, {"4", "5"}, {"5", "6"}, {"5", "7"},
|
||||
{"3", "8"}, {"8", "9"}, {"9", "10"}, {"8", "11"}, {"11", "12"}};
|
||||
|
||||
std::vector<CFGBuilder::Update> Updates = {
|
||||
{CFGInsert, {"2", "4"}}, {CFGInsert, {"12", "10"}},
|
||||
{CFGInsert, {"10", "9"}}, {CFGInsert, {"7", "6"}},
|
||||
{CFGInsert, {"7", "5"}}, {CFGDelete, {"3", "8"}},
|
||||
{CFGInsert, {"10", "7"}}, {CFGInsert, {"2", "8"}},
|
||||
{CFGDelete, {"3", "4"}}, {CFGDelete, {"8", "9"}},
|
||||
{CFGDelete, {"11", "12"}}};
|
||||
|
||||
std::mt19937 Generator(0);
|
||||
for (unsigned i = 0; i < 16; ++i) {
|
||||
std::shuffle(Updates.begin(), Updates.end(), Generator);
|
||||
CFGHolder Holder;
|
||||
CFGBuilder B(Holder.F, Arcs, Updates);
|
||||
DominatorTree DT(*Holder.F);
|
||||
EXPECT_TRUE(DT.verify());
|
||||
PostDomTree PDT(*Holder.F);
|
||||
EXPECT_TRUE(PDT.verify());
|
||||
|
||||
while (B.applyUpdate())
|
||||
;
|
||||
|
||||
auto DomUpdates = ToDomUpdates(B, Updates);
|
||||
DT.applyUpdates(DomUpdates);
|
||||
EXPECT_TRUE(DT.verify());
|
||||
PDT.applyUpdates(DomUpdates);
|
||||
EXPECT_TRUE(PDT.verify());
|
||||
}
|
||||
}
|
||||
|
||||
// These are some odd flowgraphs, usually generated from csmith cases,
|
||||
// which are difficult on post dom trees.
|
||||
TEST(DominatorTreeBatchUpdates, InfiniteLoop) {
|
||||
std::vector<CFGBuilder::Arc> Arcs = {
|
||||
{"1", "2"},
|
||||
{"2", "3"},
|
||||
{"3", "6"}, {"3", "5"},
|
||||
{"4", "5"},
|
||||
{"5", "2"},
|
||||
{"6", "3"}, {"6", "4"}};
|
||||
|
||||
// SplitBlock on 3 -> 5
|
||||
std::vector<CFGBuilder::Update> Updates = {
|
||||
{CFGInsert, {"N", "5"}}, {CFGInsert, {"3", "N"}}, {CFGDelete, {"3", "5"}}};
|
||||
|
||||
CFGHolder Holder;
|
||||
CFGBuilder B(Holder.F, Arcs, Updates);
|
||||
DominatorTree DT(*Holder.F);
|
||||
EXPECT_TRUE(DT.verify());
|
||||
PostDomTree PDT(*Holder.F);
|
||||
EXPECT_TRUE(PDT.verify());
|
||||
|
||||
while (B.applyUpdate())
|
||||
;
|
||||
|
||||
auto DomUpdates = ToDomUpdates(B, Updates);
|
||||
DT.applyUpdates(DomUpdates);
|
||||
EXPECT_TRUE(DT.verify());
|
||||
PDT.applyUpdates(DomUpdates);
|
||||
EXPECT_TRUE(PDT.verify());
|
||||
}
|
||||
|
||||
TEST(DominatorTreeBatchUpdates, DeadBlocks) {
|
||||
std::vector<CFGBuilder::Arc> Arcs = {
|
||||
{"1", "2"},
|
||||
{"2", "3"},
|
||||
{"3", "4"}, {"3", "7"},
|
||||
{"4", "4"},
|
||||
{"5", "6"}, {"5", "7"},
|
||||
{"6", "7"},
|
||||
{"7", "2"}, {"7", "8"}};
|
||||
|
||||
// Remove dead 5 and 7,
|
||||
// plus SplitBlock on 7 -> 8
|
||||
std::vector<CFGBuilder::Update> Updates = {
|
||||
{CFGDelete, {"6", "7"}}, {CFGDelete, {"5", "7"}}, {CFGDelete, {"5", "6"}},
|
||||
{CFGInsert, {"N", "8"}}, {CFGInsert, {"7", "N"}}, {CFGDelete, {"7", "8"}}};
|
||||
|
||||
CFGHolder Holder;
|
||||
CFGBuilder B(Holder.F, Arcs, Updates);
|
||||
DominatorTree DT(*Holder.F);
|
||||
EXPECT_TRUE(DT.verify());
|
||||
PostDomTree PDT(*Holder.F);
|
||||
EXPECT_TRUE(PDT.verify());
|
||||
|
||||
while (B.applyUpdate())
|
||||
;
|
||||
|
||||
auto DomUpdates = ToDomUpdates(B, Updates);
|
||||
DT.applyUpdates(DomUpdates);
|
||||
EXPECT_TRUE(DT.verify());
|
||||
PDT.applyUpdates(DomUpdates);
|
||||
EXPECT_TRUE(PDT.verify());
|
||||
}
|
||||
|
||||
TEST(DominatorTreeBatchUpdates, InfiniteLoop2) {
|
||||
std::vector<CFGBuilder::Arc> Arcs = {
|
||||
{"1", "2"},
|
||||
{"2", "6"}, {"2", "3"},
|
||||
{"3", "4"},
|
||||
{"4", "5"}, {"4", "6"},
|
||||
{"5", "4"},
|
||||
{"6", "2"}};
|
||||
|
||||
// SplitBlock on 4 -> 6
|
||||
std::vector<CFGBuilder::Update> Updates = {
|
||||
{CFGInsert, {"N", "6"}}, {CFGInsert, {"4", "N"}}, {CFGDelete, {"4", "6"}}};
|
||||
|
||||
CFGHolder Holder;
|
||||
CFGBuilder B(Holder.F, Arcs, Updates);
|
||||
DominatorTree DT(*Holder.F);
|
||||
EXPECT_TRUE(DT.verify());
|
||||
PostDomTree PDT(*Holder.F);
|
||||
EXPECT_TRUE(PDT.verify());
|
||||
|
||||
while (B.applyUpdate())
|
||||
;
|
||||
|
||||
auto DomUpdates = ToDomUpdates(B, Updates);
|
||||
DT.applyUpdates(DomUpdates);
|
||||
EXPECT_TRUE(DT.verify());
|
||||
PDT.applyUpdates(DomUpdates);
|
||||
EXPECT_TRUE(PDT.verify());
|
||||
}
|
952
external/llvm/unittests/IR/DominatorTreeTest.cpp
vendored
952
external/llvm/unittests/IR/DominatorTreeTest.cpp
vendored
File diff suppressed because it is too large
Load Diff
133
external/llvm/unittests/IR/FunctionTest.cpp
vendored
133
external/llvm/unittests/IR/FunctionTest.cpp
vendored
@ -1,133 +0,0 @@
|
||||
//===- FunctionTest.cpp - Function unit tests -----------------------------===//
|
||||
//
|
||||
// The LLVM Compiler Infrastructure
|
||||
//
|
||||
// This file is distributed under the University of Illinois Open Source
|
||||
// License. See LICENSE.TXT for details.
|
||||
//
|
||||
//===----------------------------------------------------------------------===//
|
||||
|
||||
#include "llvm/IR/Function.h"
|
||||
#include "llvm/IR/Module.h"
|
||||
#include "gtest/gtest.h"
|
||||
using namespace llvm;
|
||||
|
||||
namespace {
|
||||
|
||||
TEST(FunctionTest, hasLazyArguments) {
|
||||
LLVMContext C;
|
||||
|
||||
Type *ArgTypes[] = {Type::getInt8Ty(C), Type::getInt32Ty(C)};
|
||||
FunctionType *FTy = FunctionType::get(Type::getVoidTy(C), ArgTypes, false);
|
||||
|
||||
// Functions start out with lazy arguments.
|
||||
std::unique_ptr<Function> F(
|
||||
Function::Create(FTy, GlobalValue::ExternalLinkage, "F"));
|
||||
EXPECT_TRUE(F->hasLazyArguments());
|
||||
|
||||
// Checking for empty or size shouldn't force arguments to be instantiated.
|
||||
EXPECT_FALSE(F->arg_empty());
|
||||
EXPECT_TRUE(F->hasLazyArguments());
|
||||
EXPECT_EQ(2u, F->arg_size());
|
||||
EXPECT_TRUE(F->hasLazyArguments());
|
||||
|
||||
// The argument list should be populated at first access.
|
||||
(void)F->arg_begin();
|
||||
EXPECT_FALSE(F->hasLazyArguments());
|
||||
}
|
||||
|
||||
TEST(FunctionTest, stealArgumentListFrom) {
|
||||
LLVMContext C;
|
||||
|
||||
Type *ArgTypes[] = {Type::getInt8Ty(C), Type::getInt32Ty(C)};
|
||||
FunctionType *FTy = FunctionType::get(Type::getVoidTy(C), ArgTypes, false);
|
||||
std::unique_ptr<Function> F1(
|
||||
Function::Create(FTy, GlobalValue::ExternalLinkage, "F1"));
|
||||
std::unique_ptr<Function> F2(
|
||||
Function::Create(FTy, GlobalValue::ExternalLinkage, "F1"));
|
||||
EXPECT_TRUE(F1->hasLazyArguments());
|
||||
EXPECT_TRUE(F2->hasLazyArguments());
|
||||
|
||||
// Steal arguments before they've been accessed. Nothing should change; both
|
||||
// functions should still have lazy arguments.
|
||||
//
|
||||
// steal(empty); drop (empty)
|
||||
F1->stealArgumentListFrom(*F2);
|
||||
EXPECT_TRUE(F1->hasLazyArguments());
|
||||
EXPECT_TRUE(F2->hasLazyArguments());
|
||||
|
||||
// Save arguments from F1 for later assertions. F1 won't have lazy arguments
|
||||
// anymore.
|
||||
SmallVector<Argument *, 4> Args;
|
||||
for (Argument &A : F1->args())
|
||||
Args.push_back(&A);
|
||||
EXPECT_EQ(2u, Args.size());
|
||||
EXPECT_FALSE(F1->hasLazyArguments());
|
||||
|
||||
// Steal arguments from F1 to F2. F1's arguments should be lazy again.
|
||||
//
|
||||
// steal(real); drop (empty)
|
||||
F2->stealArgumentListFrom(*F1);
|
||||
EXPECT_TRUE(F1->hasLazyArguments());
|
||||
EXPECT_FALSE(F2->hasLazyArguments());
|
||||
unsigned I = 0;
|
||||
for (Argument &A : F2->args()) {
|
||||
EXPECT_EQ(Args[I], &A);
|
||||
I++;
|
||||
}
|
||||
EXPECT_EQ(2u, I);
|
||||
|
||||
// Check that arguments in F1 don't have pointer equality with the saved ones.
|
||||
// This also instantiates F1's arguments.
|
||||
I = 0;
|
||||
for (Argument &A : F1->args()) {
|
||||
EXPECT_NE(Args[I], &A);
|
||||
I++;
|
||||
}
|
||||
EXPECT_EQ(2u, I);
|
||||
EXPECT_FALSE(F1->hasLazyArguments());
|
||||
EXPECT_FALSE(F2->hasLazyArguments());
|
||||
|
||||
// Steal back from F2. F2's arguments should be lazy again.
|
||||
//
|
||||
// steal(real); drop (real)
|
||||
F1->stealArgumentListFrom(*F2);
|
||||
EXPECT_FALSE(F1->hasLazyArguments());
|
||||
EXPECT_TRUE(F2->hasLazyArguments());
|
||||
I = 0;
|
||||
for (Argument &A : F1->args()) {
|
||||
EXPECT_EQ(Args[I], &A);
|
||||
I++;
|
||||
}
|
||||
EXPECT_EQ(2u, I);
|
||||
|
||||
// Steal from F2 a second time. Now both functions should have lazy
|
||||
// arguments.
|
||||
//
|
||||
// steal(empty); drop (real)
|
||||
F1->stealArgumentListFrom(*F2);
|
||||
EXPECT_TRUE(F1->hasLazyArguments());
|
||||
EXPECT_TRUE(F2->hasLazyArguments());
|
||||
}
|
||||
|
||||
// Test setting and removing section information
|
||||
TEST(FunctionTest, setSection) {
|
||||
LLVMContext C;
|
||||
Module M("test", C);
|
||||
|
||||
llvm::Function *F =
|
||||
Function::Create(llvm::FunctionType::get(llvm::Type::getVoidTy(C), false),
|
||||
llvm::GlobalValue::ExternalLinkage, "F", &M);
|
||||
|
||||
F->setSection(".text.test");
|
||||
EXPECT_TRUE(F->getSection() == ".text.test");
|
||||
EXPECT_TRUE(F->hasSection());
|
||||
F->setSection("");
|
||||
EXPECT_FALSE(F->hasSection());
|
||||
F->setSection(".text.test");
|
||||
F->setSection(".text.test2");
|
||||
EXPECT_TRUE(F->getSection() == ".text.test2");
|
||||
EXPECT_TRUE(F->hasSection());
|
||||
}
|
||||
|
||||
} // end namespace
|
590
external/llvm/unittests/IR/IRBuilderTest.cpp
vendored
590
external/llvm/unittests/IR/IRBuilderTest.cpp
vendored
File diff suppressed because it is too large
Load Diff
751
external/llvm/unittests/IR/InstructionsTest.cpp
vendored
751
external/llvm/unittests/IR/InstructionsTest.cpp
vendored
File diff suppressed because it is too large
Load Diff
40
external/llvm/unittests/IR/IntrinsicsTest.cpp
vendored
40
external/llvm/unittests/IR/IntrinsicsTest.cpp
vendored
@ -1,40 +0,0 @@
|
||||
//===- llvm/unittest/IR/IntrinsicsTest.cpp - ------------------------------===//
|
||||
//
|
||||
// The LLVM Compiler Infrastructure
|
||||
//
|
||||
// This file is distributed under the University of Illinois Open Source
|
||||
// License. See LICENSE.TXT for details.
|
||||
//
|
||||
//===----------------------------------------------------------------------===//
|
||||
|
||||
#include "llvm/IR/IntrinsicInst.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",
|
||||
};
|
||||
|
||||
TEST(IntrinNameLookup, 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);
|
||||
}
|
||||
|
||||
} // end namespace
|
553
external/llvm/unittests/IR/LegacyPassManagerTest.cpp
vendored
553
external/llvm/unittests/IR/LegacyPassManagerTest.cpp
vendored
File diff suppressed because it is too large
Load Diff
108
external/llvm/unittests/IR/MDBuilderTest.cpp
vendored
108
external/llvm/unittests/IR/MDBuilderTest.cpp
vendored
@ -1,108 +0,0 @@
|
||||
//===- llvm/unittests/MDBuilderTest.cpp - MDBuilder unit tests ------------===//
|
||||
//
|
||||
// The LLVM Compiler Infrastructure
|
||||
//
|
||||
// This file is distributed under the University of Illinois Open Source
|
||||
// License. See LICENSE.TXT for details.
|
||||
//
|
||||
//===----------------------------------------------------------------------===//
|
||||
|
||||
#include "llvm/IR/MDBuilder.h"
|
||||
#include "llvm/IR/IRBuilder.h"
|
||||
#include "llvm/IR/Metadata.h"
|
||||
#include "llvm/IR/Operator.h"
|
||||
#include "gtest/gtest.h"
|
||||
|
||||
using namespace llvm;
|
||||
|
||||
namespace {
|
||||
|
||||
class MDBuilderTest : public testing::Test {
|
||||
protected:
|
||||
LLVMContext Context;
|
||||
};
|
||||
|
||||
TEST_F(MDBuilderTest, createString) {
|
||||
MDBuilder MDHelper(Context);
|
||||
MDString *Str0 = MDHelper.createString("");
|
||||
MDString *Str1 = MDHelper.createString("string");
|
||||
EXPECT_EQ(Str0->getString(), StringRef(""));
|
||||
EXPECT_EQ(Str1->getString(), StringRef("string"));
|
||||
}
|
||||
TEST_F(MDBuilderTest, createFPMath) {
|
||||
MDBuilder MDHelper(Context);
|
||||
MDNode *MD0 = MDHelper.createFPMath(0.0);
|
||||
MDNode *MD1 = MDHelper.createFPMath(1.0);
|
||||
EXPECT_EQ(MD0, (MDNode *)nullptr);
|
||||
EXPECT_NE(MD1, (MDNode *)nullptr);
|
||||
EXPECT_EQ(MD1->getNumOperands(), 1U);
|
||||
Metadata *Op = MD1->getOperand(0);
|
||||
EXPECT_TRUE(mdconst::hasa<ConstantFP>(Op));
|
||||
ConstantFP *Val = mdconst::extract<ConstantFP>(Op);
|
||||
EXPECT_TRUE(Val->getType()->isFloatingPointTy());
|
||||
EXPECT_TRUE(Val->isExactlyValue(1.0));
|
||||
}
|
||||
TEST_F(MDBuilderTest, createRangeMetadata) {
|
||||
MDBuilder MDHelper(Context);
|
||||
APInt A(8, 1), B(8, 2);
|
||||
MDNode *R0 = MDHelper.createRange(A, A);
|
||||
MDNode *R1 = MDHelper.createRange(A, B);
|
||||
EXPECT_EQ(R0, (MDNode *)nullptr);
|
||||
EXPECT_NE(R1, (MDNode *)nullptr);
|
||||
EXPECT_EQ(R1->getNumOperands(), 2U);
|
||||
EXPECT_TRUE(mdconst::hasa<ConstantInt>(R1->getOperand(0)));
|
||||
EXPECT_TRUE(mdconst::hasa<ConstantInt>(R1->getOperand(1)));
|
||||
ConstantInt *C0 = mdconst::extract<ConstantInt>(R1->getOperand(0));
|
||||
ConstantInt *C1 = mdconst::extract<ConstantInt>(R1->getOperand(1));
|
||||
EXPECT_EQ(C0->getValue(), A);
|
||||
EXPECT_EQ(C1->getValue(), B);
|
||||
}
|
||||
TEST_F(MDBuilderTest, createAnonymousTBAARoot) {
|
||||
MDBuilder MDHelper(Context);
|
||||
MDNode *R0 = MDHelper.createAnonymousTBAARoot();
|
||||
MDNode *R1 = MDHelper.createAnonymousTBAARoot();
|
||||
EXPECT_NE(R0, R1);
|
||||
EXPECT_GE(R0->getNumOperands(), 1U);
|
||||
EXPECT_GE(R1->getNumOperands(), 1U);
|
||||
EXPECT_EQ(R0->getOperand(0), R0);
|
||||
EXPECT_EQ(R1->getOperand(0), R1);
|
||||
EXPECT_TRUE(R0->getNumOperands() == 1 || R0->getOperand(1) == nullptr);
|
||||
EXPECT_TRUE(R1->getNumOperands() == 1 || R1->getOperand(1) == nullptr);
|
||||
}
|
||||
TEST_F(MDBuilderTest, createTBAARoot) {
|
||||
MDBuilder MDHelper(Context);
|
||||
MDNode *R0 = MDHelper.createTBAARoot("Root");
|
||||
MDNode *R1 = MDHelper.createTBAARoot("Root");
|
||||
EXPECT_EQ(R0, R1);
|
||||
EXPECT_GE(R0->getNumOperands(), 1U);
|
||||
EXPECT_TRUE(isa<MDString>(R0->getOperand(0)));
|
||||
EXPECT_EQ(cast<MDString>(R0->getOperand(0))->getString(), "Root");
|
||||
EXPECT_TRUE(R0->getNumOperands() == 1 || R0->getOperand(1) == nullptr);
|
||||
}
|
||||
TEST_F(MDBuilderTest, createTBAANode) {
|
||||
MDBuilder MDHelper(Context);
|
||||
MDNode *R = MDHelper.createTBAARoot("Root");
|
||||
MDNode *N0 = MDHelper.createTBAANode("Node", R);
|
||||
MDNode *N1 = MDHelper.createTBAANode("edoN", R);
|
||||
MDNode *N2 = MDHelper.createTBAANode("Node", R, true);
|
||||
MDNode *N3 = MDHelper.createTBAANode("Node", R);
|
||||
EXPECT_EQ(N0, N3);
|
||||
EXPECT_NE(N0, N1);
|
||||
EXPECT_NE(N0, N2);
|
||||
EXPECT_GE(N0->getNumOperands(), 2U);
|
||||
EXPECT_GE(N1->getNumOperands(), 2U);
|
||||
EXPECT_GE(N2->getNumOperands(), 3U);
|
||||
EXPECT_TRUE(isa<MDString>(N0->getOperand(0)));
|
||||
EXPECT_TRUE(isa<MDString>(N1->getOperand(0)));
|
||||
EXPECT_TRUE(isa<MDString>(N2->getOperand(0)));
|
||||
EXPECT_EQ(cast<MDString>(N0->getOperand(0))->getString(), "Node");
|
||||
EXPECT_EQ(cast<MDString>(N1->getOperand(0))->getString(), "edoN");
|
||||
EXPECT_EQ(cast<MDString>(N2->getOperand(0))->getString(), "Node");
|
||||
EXPECT_EQ(N0->getOperand(1), R);
|
||||
EXPECT_EQ(N1->getOperand(1), R);
|
||||
EXPECT_EQ(N2->getOperand(1), R);
|
||||
EXPECT_TRUE(mdconst::hasa<ConstantInt>(N2->getOperand(2)));
|
||||
EXPECT_EQ(mdconst::extract<ConstantInt>(N2->getOperand(2))->getZExtValue(),
|
||||
1U);
|
||||
}
|
||||
}
|
2536
external/llvm/unittests/IR/MetadataTest.cpp
vendored
2536
external/llvm/unittests/IR/MetadataTest.cpp
vendored
File diff suppressed because it is too large
Load Diff
75
external/llvm/unittests/IR/ModuleTest.cpp
vendored
75
external/llvm/unittests/IR/ModuleTest.cpp
vendored
@ -1,75 +0,0 @@
|
||||
//===- unittests/IR/ModuleTest.cpp - Module unit tests --------------------===//
|
||||
//
|
||||
// The LLVM Compiler Infrastructure
|
||||
//
|
||||
// This file is distributed under the University of Illinois Open Source
|
||||
// License. See LICENSE.TXT for details.
|
||||
//
|
||||
//===----------------------------------------------------------------------===//
|
||||
|
||||
#include "llvm/IR/Module.h"
|
||||
#include "llvm/IR/GlobalVariable.h"
|
||||
#include "llvm/Support/RandomNumberGenerator.h"
|
||||
#include "gtest/gtest.h"
|
||||
|
||||
#include <random>
|
||||
|
||||
using namespace llvm;
|
||||
|
||||
namespace {
|
||||
|
||||
bool sortByName(const GlobalVariable &L, const GlobalVariable &R) {
|
||||
return L.getName() < R.getName();
|
||||
}
|
||||
|
||||
bool sortByNameReverse(const GlobalVariable &L, const GlobalVariable &R) {
|
||||
return sortByName(R, L);
|
||||
}
|
||||
|
||||
TEST(ModuleTest, sortGlobalsByName) {
|
||||
LLVMContext Context;
|
||||
for (auto compare : {&sortByName, &sortByNameReverse}) {
|
||||
Module M("M", Context);
|
||||
Type *T = Type::getInt8Ty(Context);
|
||||
GlobalValue::LinkageTypes L = GlobalValue::ExternalLinkage;
|
||||
(void)new GlobalVariable(M, T, false, L, nullptr, "A");
|
||||
(void)new GlobalVariable(M, T, false, L, nullptr, "F");
|
||||
(void)new GlobalVariable(M, T, false, L, nullptr, "G");
|
||||
(void)new GlobalVariable(M, T, false, L, nullptr, "E");
|
||||
(void)new GlobalVariable(M, T, false, L, nullptr, "B");
|
||||
(void)new GlobalVariable(M, T, false, L, nullptr, "H");
|
||||
(void)new GlobalVariable(M, T, false, L, nullptr, "C");
|
||||
(void)new GlobalVariable(M, T, false, L, nullptr, "D");
|
||||
|
||||
// Sort the globals by name.
|
||||
EXPECT_FALSE(std::is_sorted(M.global_begin(), M.global_end(), compare));
|
||||
M.getGlobalList().sort(compare);
|
||||
EXPECT_TRUE(std::is_sorted(M.global_begin(), M.global_end(), compare));
|
||||
}
|
||||
}
|
||||
|
||||
TEST(ModuleTest, randomNumberGenerator) {
|
||||
LLVMContext Context;
|
||||
static char ID;
|
||||
struct DummyPass : ModulePass {
|
||||
DummyPass() : ModulePass(ID) {}
|
||||
bool runOnModule(Module &) { return true; }
|
||||
} DP;
|
||||
|
||||
Module M("R", Context);
|
||||
|
||||
std::uniform_int_distribution<int> dist;
|
||||
const size_t NBCheck = 10;
|
||||
|
||||
std::array<int, NBCheck> RandomStreams[2];
|
||||
for (auto &RandomStream : RandomStreams) {
|
||||
std::unique_ptr<RandomNumberGenerator> RNG = M.createRNG(&DP);
|
||||
std::generate(RandomStream.begin(), RandomStream.end(),
|
||||
[&]() { return dist(*RNG); });
|
||||
}
|
||||
|
||||
EXPECT_TRUE(std::equal(RandomStreams[0].begin(), RandomStreams[0].end(),
|
||||
RandomStreams[1].begin()));
|
||||
}
|
||||
|
||||
} // end namespace
|
Some files were not shown because too many files have changed in this diff Show More
Reference in New Issue
Block a user