summaryrefslogtreecommitdiff
path: root/unittests/IR
diff options
context:
space:
mode:
Diffstat (limited to 'unittests/IR')
-rw-r--r--unittests/IR/BasicBlockTest.cpp75
-rw-r--r--unittests/IR/CMakeLists.txt1
-rw-r--r--unittests/IR/DominatorTreeTest.cpp129
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)