diff options
Diffstat (limited to 'unittests/IR')
-rw-r--r-- | unittests/IR/BasicBlockTest.cpp | 75 | ||||
-rw-r--r-- | unittests/IR/CMakeLists.txt | 1 | ||||
-rw-r--r-- | unittests/IR/DominatorTreeTest.cpp | 129 |
3 files changed, 135 insertions, 70 deletions
diff --git a/unittests/IR/BasicBlockTest.cpp b/unittests/IR/BasicBlockTest.cpp new file mode 100644 index 000000000000..f1777e35b82c --- /dev/null +++ b/unittests/IR/BasicBlockTest.cpp @@ -0,0 +1,75 @@ +//===- 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 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. diff --git a/unittests/IR/CMakeLists.txt b/unittests/IR/CMakeLists.txt index 750f638c7a42..6734de8e2d95 100644 --- a/unittests/IR/CMakeLists.txt +++ b/unittests/IR/CMakeLists.txt @@ -8,6 +8,7 @@ set(LLVM_LINK_COMPONENTS set(IRSources AsmWriterTest.cpp AttributesTest.cpp + BasicBlockTest.cpp ConstantRangeTest.cpp ConstantsTest.cpp DebugInfoTest.cpp diff --git a/unittests/IR/DominatorTreeTest.cpp b/unittests/IR/DominatorTreeTest.cpp index 498e111a31f6..d2062839a734 100644 --- a/unittests/IR/DominatorTreeTest.cpp +++ b/unittests/IR/DominatorTreeTest.cpp @@ -7,30 +7,73 @@ // //===----------------------------------------------------------------------===// -#include "llvm/IR/Dominators.h" #include "llvm/Analysis/PostDominators.h" #include "llvm/AsmParser/Parser.h" #include "llvm/IR/Constants.h" +#include "llvm/IR/Dominators.h" #include "llvm/IR/Instructions.h" #include "llvm/IR/LLVMContext.h" #include "llvm/IR/Module.h" -#include "llvm/IR/LegacyPassManager.h" #include "llvm/Support/SourceMgr.h" #include "gtest/gtest.h" using namespace llvm; -namespace llvm { - void initializeDPassPass(PassRegistry&); - - namespace { - struct DPass : public FunctionPass { - static char ID; - bool runOnFunction(Function &F) override { - DominatorTree *DT = - &getAnalysis<DominatorTreeWrapperPass>().getDomTree(); - PostDominatorTree *PDT = - &getAnalysis<PostDominatorTreeWrapperPass>().getPostDomTree(); +/// Build the dominator tree for the function and run the Test. +static void +runWithDomTree(Module &M, StringRef FuncName, + function_ref<void(Function &F, DominatorTree *DT, + DominatorTreeBase<BasicBlock> *PDT)> + Test) { + auto *F = M.getFunction(FuncName); + ASSERT_NE(F, nullptr) << "Could not find " << FuncName; + // Compute the dominator tree for the function. + DominatorTree DT(*F); + DominatorTreeBase<BasicBlock> PDT(/*isPostDom*/ true); + PDT.recalculate(*F); + Test(*F, &DT, &PDT); +} + +static std::unique_ptr<Module> makeLLVMModule(LLVMContext &Context, + StringRef ModuleStr) { + SMDiagnostic Err; + std::unique_ptr<Module> M = parseAssemblyString(ModuleStr, Err, Context); + assert(M && "Bad assembly?"); + return M; +} + +TEST(DominatorTree, Unreachable) { + StringRef ModuleString = + "declare i32 @g()\n" + "define void @f(i32 %x) personality i32 ()* @g {\n" + "bb0:\n" + " %y1 = add i32 %x, 1\n" + " %y2 = add i32 %x, 1\n" + " %y3 = invoke i32 @g() to label %bb1 unwind label %bb2\n" + "bb1:\n" + " %y4 = add i32 %x, 1\n" + " br label %bb4\n" + "bb2:\n" + " %y5 = landingpad i32\n" + " cleanup\n" + " br label %bb4\n" + "bb3:\n" + " %y6 = add i32 %x, 1\n" + " %y7 = add i32 %x, 1\n" + " ret void\n" + "bb4:\n" + " %y8 = phi i32 [0, %bb2], [%y4, %bb1]\n" + " %y9 = phi i32 [0, %bb2], [%y4, %bb1]\n" + " ret void\n" + "}\n"; + + // Parse the module. + LLVMContext Context; + std::unique_ptr<Module> M = makeLLVMModule(Context, ModuleString); + + runWithDomTree( + *M, "f", + [&](Function &F, DominatorTree *DT, DominatorTreeBase<BasicBlock> *PDT) { Function::iterator FI = F.begin(); BasicBlock *BB0 = &*FI++; @@ -205,66 +248,12 @@ namespace llvm { // Change root node DT->verifyDomTree(); - BasicBlock *NewEntry = BasicBlock::Create(F.getContext(), "new_entry", - &F, BB0); + BasicBlock *NewEntry = + BasicBlock::Create(F.getContext(), "new_entry", &F, BB0); BranchInst::Create(BB0, NewEntry); EXPECT_EQ(F.begin()->getName(), NewEntry->getName()); EXPECT_TRUE(&F.getEntryBlock() == NewEntry); DT->setNewRoot(NewEntry); DT->verifyDomTree(); - - return false; - } - void getAnalysisUsage(AnalysisUsage &AU) const override { - AU.addRequired<DominatorTreeWrapperPass>(); - AU.addRequired<PostDominatorTreeWrapperPass>(); - } - DPass() : FunctionPass(ID) { - initializeDPassPass(*PassRegistry::getPassRegistry()); - } - }; - char DPass::ID = 0; - - std::unique_ptr<Module> makeLLVMModule(LLVMContext &Context, DPass *P) { - const char *ModuleString = - "declare i32 @g()\n" \ - "define void @f(i32 %x) personality i32 ()* @g {\n" \ - "bb0:\n" \ - " %y1 = add i32 %x, 1\n" \ - " %y2 = add i32 %x, 1\n" \ - " %y3 = invoke i32 @g() to label %bb1 unwind label %bb2\n" \ - "bb1:\n" \ - " %y4 = add i32 %x, 1\n" \ - " br label %bb4\n" \ - "bb2:\n" \ - " %y5 = landingpad i32\n" \ - " cleanup\n" \ - " br label %bb4\n" \ - "bb3:\n" \ - " %y6 = add i32 %x, 1\n" \ - " %y7 = add i32 %x, 1\n" \ - " ret void\n" \ - "bb4:\n" \ - " %y8 = phi i32 [0, %bb2], [%y4, %bb1]\n" - " %y9 = phi i32 [0, %bb2], [%y4, %bb1]\n" - " ret void\n" \ - "}\n"; - SMDiagnostic Err; - return parseAssemblyString(ModuleString, Err, Context); - } - - TEST(DominatorTree, Unreachable) { - DPass *P = new DPass(); - LLVMContext Context; - std::unique_ptr<Module> M = makeLLVMModule(Context, P); - legacy::PassManager Passes; - Passes.add(P); - Passes.run(*M); - } - } + }); } - -INITIALIZE_PASS_BEGIN(DPass, "dpass", "dpass", false, false) -INITIALIZE_PASS_DEPENDENCY(DominatorTreeWrapperPass) -INITIALIZE_PASS_DEPENDENCY(PostDominatorTreeWrapperPass) -INITIALIZE_PASS_END(DPass, "dpass", "dpass", false, false) |