diff options
Diffstat (limited to 'unittests/IR/BasicBlockTest.cpp')
-rw-r--r-- | unittests/IR/BasicBlockTest.cpp | 57 |
1 files changed, 57 insertions, 0 deletions
diff --git a/unittests/IR/BasicBlockTest.cpp b/unittests/IR/BasicBlockTest.cpp index f1777e35b82c..07ed997f6381 100644 --- a/unittests/IR/BasicBlockTest.cpp +++ b/unittests/IR/BasicBlockTest.cpp @@ -33,6 +33,12 @@ TEST(BasicBlockTest, PhiRange) { 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()); @@ -63,6 +69,15 @@ TEST(BasicBlockTest, PhiRange) { CI = BB->phis().begin(); EXPECT_NE(CI, BB->phis().end()); + // Test that filtering iterators work with basic blocks. + auto isPhi = [](Instruction &I) { return isa<PHINode>(&I); }; + auto Phis = make_filter_range(*BB, isPhi); + auto ReversedPhis = reverse(make_filter_range(*BB, isPhi)); + EXPECT_EQ(std::distance(Phis.begin(), Phis.end()), 3); + EXPECT_EQ(&*Phis.begin(), P1); + EXPECT_EQ(std::distance(ReversedPhis.begin(), ReversedPhis.end()), 3); + EXPECT_EQ(&*ReversedPhis.begin(), P3); + // And iterate a const range. for (const auto &PN : const_cast<const BasicBlock *>(BB.get())->phis()) { EXPECT_EQ(BB.get(), PN.getIncomingBlock(0)); @@ -71,5 +86,47 @@ TEST(BasicBlockTest, PhiRange) { } } +#define CHECK_ITERATORS(Range1, Range2) \ + EXPECT_EQ(std::distance(Range1.begin(), Range1.end()), \ + std::distance(Range2.begin(), Range2.end())); \ + for (auto Pair : zip(Range1, Range2)) \ + EXPECT_EQ(&std::get<0>(Pair), std::get<1>(Pair)); + +TEST(BasicBlockTest, TestInstructionsWithoutDebug) { + LLVMContext Ctx; + + Module *M = new Module("MyModule", Ctx); + Type *ArgTy1[] = {Type::getInt32PtrTy(Ctx)}; + FunctionType *FT = FunctionType::get(Type::getVoidTy(Ctx), ArgTy1, false); + Argument *V = new Argument(Type::getInt32Ty(Ctx)); + Function *F = Function::Create(FT, Function::ExternalLinkage, "", M); + + Value *DbgAddr = Intrinsic::getDeclaration(M, Intrinsic::dbg_addr); + Value *DbgDeclare = + Intrinsic::getDeclaration(M, Intrinsic::dbg_declare); + Value *DbgValue = Intrinsic::getDeclaration(M, Intrinsic::dbg_value); + Value *DIV = MetadataAsValue::get(Ctx, (Metadata *)nullptr); + SmallVector<Value *, 3> Args = {DIV, DIV, DIV}; + + BasicBlock *BB1 = BasicBlock::Create(Ctx, "", F); + const BasicBlock *BBConst = BB1; + IRBuilder<> Builder1(BB1); + + AllocaInst *Var = Builder1.CreateAlloca(Builder1.getInt8Ty()); + Builder1.CreateCall(DbgValue, Args); + Instruction *AddInst = cast<Instruction>(Builder1.CreateAdd(V, V)); + Instruction *MulInst = cast<Instruction>(Builder1.CreateMul(AddInst, V)); + Builder1.CreateCall(DbgDeclare, Args); + Instruction *SubInst = cast<Instruction>(Builder1.CreateSub(MulInst, V)); + Builder1.CreateCall(DbgAddr, Args); + + SmallVector<Instruction *, 4> Exp = {Var, AddInst, MulInst, SubInst}; + CHECK_ITERATORS(BB1->instructionsWithoutDebug(), Exp); + CHECK_ITERATORS(BBConst->instructionsWithoutDebug(), Exp); + + delete M; + delete V; +} + } // End anonymous namespace. } // End llvm namespace. |