diff options
Diffstat (limited to 'unittests/Transforms/Utils/Cloning.cpp')
-rw-r--r-- | unittests/Transforms/Utils/Cloning.cpp | 100 |
1 files changed, 99 insertions, 1 deletions
diff --git a/unittests/Transforms/Utils/Cloning.cpp b/unittests/Transforms/Utils/Cloning.cpp index fe4e2ba7e943..9a1ad19ebaa4 100644 --- a/unittests/Transforms/Utils/Cloning.cpp +++ b/unittests/Transforms/Utils/Cloning.cpp @@ -251,6 +251,104 @@ TEST_F(CloneInstruction, DuplicateInstructionsToSplit) { delete F; } +TEST_F(CloneInstruction, DuplicateInstructionsToSplitBlocksEq1) { + Type *ArgTy1[] = {Type::getInt32PtrTy(context)}; + FunctionType *FT = FunctionType::get(Type::getVoidTy(context), ArgTy1, false); + V = new Argument(Type::getInt32Ty(context)); + + Function *F = Function::Create(FT, Function::ExternalLinkage); + + BasicBlock *BB1 = BasicBlock::Create(context, "", F); + IRBuilder<> Builder1(BB1); + + BasicBlock *BB2 = BasicBlock::Create(context, "", F); + IRBuilder<> Builder2(BB2); + + Builder1.CreateBr(BB2); + + Instruction *AddInst = cast<Instruction>(Builder2.CreateAdd(V, V)); + Instruction *MulInst = cast<Instruction>(Builder2.CreateMul(AddInst, V)); + Instruction *SubInst = cast<Instruction>(Builder2.CreateSub(MulInst, V)); + Builder2.CreateBr(BB2); + + ValueToValueMapTy Mapping; + + auto Split = DuplicateInstructionsInSplitBetween(BB2, BB2, BB2->getTerminator(), Mapping); + + EXPECT_TRUE(Split); + EXPECT_EQ(Mapping.size(), 3u); + EXPECT_TRUE(Mapping.find(AddInst) != Mapping.end()); + EXPECT_TRUE(Mapping.find(MulInst) != Mapping.end()); + EXPECT_TRUE(Mapping.find(SubInst) != Mapping.end()); + + auto AddSplit = dyn_cast<Instruction>(Mapping[AddInst]); + EXPECT_TRUE(AddSplit); + EXPECT_EQ(AddSplit->getOperand(0), V); + EXPECT_EQ(AddSplit->getOperand(1), V); + EXPECT_EQ(AddSplit->getParent(), Split); + + auto MulSplit = dyn_cast<Instruction>(Mapping[MulInst]); + EXPECT_TRUE(MulSplit); + EXPECT_EQ(MulSplit->getOperand(0), AddSplit); + EXPECT_EQ(MulSplit->getOperand(1), V); + EXPECT_EQ(MulSplit->getParent(), Split); + + auto SubSplit = dyn_cast<Instruction>(Mapping[SubInst]); + EXPECT_EQ(MulSplit->getNextNode(), SubSplit); + EXPECT_EQ(SubSplit->getNextNode(), Split->getTerminator()); + EXPECT_EQ(Split->getSingleSuccessor(), BB2); + EXPECT_EQ(BB2->getSingleSuccessor(), Split); + + delete F; +} + +TEST_F(CloneInstruction, DuplicateInstructionsToSplitBlocksEq2) { + Type *ArgTy1[] = {Type::getInt32PtrTy(context)}; + FunctionType *FT = FunctionType::get(Type::getVoidTy(context), ArgTy1, false); + V = new Argument(Type::getInt32Ty(context)); + + Function *F = Function::Create(FT, Function::ExternalLinkage); + + BasicBlock *BB1 = BasicBlock::Create(context, "", F); + IRBuilder<> Builder1(BB1); + + BasicBlock *BB2 = BasicBlock::Create(context, "", F); + IRBuilder<> Builder2(BB2); + + Builder1.CreateBr(BB2); + + Instruction *AddInst = cast<Instruction>(Builder2.CreateAdd(V, V)); + Instruction *MulInst = cast<Instruction>(Builder2.CreateMul(AddInst, V)); + Instruction *SubInst = cast<Instruction>(Builder2.CreateSub(MulInst, V)); + Builder2.CreateBr(BB2); + + ValueToValueMapTy Mapping; + + auto Split = DuplicateInstructionsInSplitBetween(BB2, BB2, SubInst, Mapping); + + EXPECT_TRUE(Split); + EXPECT_EQ(Mapping.size(), 2u); + EXPECT_TRUE(Mapping.find(AddInst) != Mapping.end()); + EXPECT_TRUE(Mapping.find(MulInst) != Mapping.end()); + + auto AddSplit = dyn_cast<Instruction>(Mapping[AddInst]); + EXPECT_TRUE(AddSplit); + EXPECT_EQ(AddSplit->getOperand(0), V); + EXPECT_EQ(AddSplit->getOperand(1), V); + EXPECT_EQ(AddSplit->getParent(), Split); + + auto MulSplit = dyn_cast<Instruction>(Mapping[MulInst]); + EXPECT_TRUE(MulSplit); + EXPECT_EQ(MulSplit->getOperand(0), AddSplit); + EXPECT_EQ(MulSplit->getOperand(1), V); + EXPECT_EQ(MulSplit->getParent(), Split); + EXPECT_EQ(MulSplit->getNextNode(), Split->getTerminator()); + EXPECT_EQ(Split->getSingleSuccessor(), BB2); + EXPECT_EQ(BB2->getSingleSuccessor(), Split); + + delete F; +} + class CloneFunc : public ::testing::Test { protected: void SetUp() override { @@ -527,7 +625,7 @@ protected: DBuilder.finalize(); } - void CreateNewModule() { NewM = llvm::CloneModule(OldM).release(); } + void CreateNewModule() { NewM = llvm::CloneModule(*OldM).release(); } LLVMContext C; Module *OldM; |