llvm.org GIT mirror llvm / 6fdde84
[CloneFunction] Support BB == PredBB in DuplicateInstructionsInSplit. In case PredBB == BB and StopAt == BB's terminator, StopAt != &*BI will fail, because BB's terminator instruction gets replaced. By using BB.getTerminator() we get the current terminator which we can use to compare. Reviewers: sanjoy, anna, reames Reviewed By: anna Differential Revision: https://reviews.llvm.org/D43822 git-svn-id: https://llvm.org/svn/llvm-project/llvm/trunk@326779 91177308-0d34-0410-b5e6-96231b3b80d8 Florian Hahn 2 years ago
2 changed file(s) with 101 addition(s) and 1 deletion(s). Raw diff Collapse all Expand all
810810
811811 // Clone the non-phi instructions of BB into NewBB, keeping track of the
812812 // mapping and using it to remap operands in the cloned instructions.
813 for (; StopAt != &*BI; ++BI) {
813 // Stop once we see the terminator too. This covers the case where BB's
814 // terminator gets replaced and StopAt == BB's terminator.
815 for (; StopAt != &*BI && BB->getTerminator() != &*BI; ++BI) {
814816 Instruction *New = BI->clone();
815817 New->setName(BI->getName());
816818 New->insertBefore(NewTerm);
246246
247247 EXPECT_EQ(AddSplit->getNextNode(), MulSplit);
248248 EXPECT_EQ(MulSplit->getNextNode(), Split->getTerminator());
249
250 delete F;
251 }
252
253 TEST_F(CloneInstruction, DuplicateInstructionsToSplitBlocksEq1) {
254 Type *ArgTy1[] = {Type::getInt32PtrTy(context)};
255 FunctionType *FT = FunctionType::get(Type::getVoidTy(context), ArgTy1, false);
256 V = new Argument(Type::getInt32Ty(context));
257
258 Function *F = Function::Create(FT, Function::ExternalLinkage);
259
260 BasicBlock *BB1 = BasicBlock::Create(context, "", F);
261 IRBuilder<> Builder1(BB1);
262
263 BasicBlock *BB2 = BasicBlock::Create(context, "", F);
264 IRBuilder<> Builder2(BB2);
265
266 Builder1.CreateBr(BB2);
267
268 Instruction *AddInst = cast(Builder2.CreateAdd(V, V));
269 Instruction *MulInst = cast(Builder2.CreateMul(AddInst, V));
270 Instruction *SubInst = cast(Builder2.CreateSub(MulInst, V));
271 Builder2.CreateBr(BB2);
272
273 ValueToValueMapTy Mapping;
274
275 auto Split = DuplicateInstructionsInSplitBetween(BB2, BB2, BB2->getTerminator(), Mapping);
276
277 EXPECT_TRUE(Split);
278 EXPECT_EQ(Mapping.size(), 3u);
279 EXPECT_TRUE(Mapping.find(AddInst) != Mapping.end());
280 EXPECT_TRUE(Mapping.find(MulInst) != Mapping.end());
281 EXPECT_TRUE(Mapping.find(SubInst) != Mapping.end());
282
283 auto AddSplit = dyn_cast(Mapping[AddInst]);
284 EXPECT_TRUE(AddSplit);
285 EXPECT_EQ(AddSplit->getOperand(0), V);
286 EXPECT_EQ(AddSplit->getOperand(1), V);
287 EXPECT_EQ(AddSplit->getParent(), Split);
288
289 auto MulSplit = dyn_cast(Mapping[MulInst]);
290 EXPECT_TRUE(MulSplit);
291 EXPECT_EQ(MulSplit->getOperand(0), AddSplit);
292 EXPECT_EQ(MulSplit->getOperand(1), V);
293 EXPECT_EQ(MulSplit->getParent(), Split);
294
295 auto SubSplit = dyn_cast(Mapping[SubInst]);
296 EXPECT_EQ(MulSplit->getNextNode(), SubSplit);
297 EXPECT_EQ(SubSplit->getNextNode(), Split->getTerminator());
298 EXPECT_EQ(Split->getSingleSuccessor(), BB2);
299 EXPECT_EQ(BB2->getSingleSuccessor(), Split);
300
301 delete F;
302 }
303
304 TEST_F(CloneInstruction, DuplicateInstructionsToSplitBlocksEq2) {
305 Type *ArgTy1[] = {Type::getInt32PtrTy(context)};
306 FunctionType *FT = FunctionType::get(Type::getVoidTy(context), ArgTy1, false);
307 V = new Argument(Type::getInt32Ty(context));
308
309 Function *F = Function::Create(FT, Function::ExternalLinkage);
310
311 BasicBlock *BB1 = BasicBlock::Create(context, "", F);
312 IRBuilder<> Builder1(BB1);
313
314 BasicBlock *BB2 = BasicBlock::Create(context, "", F);
315 IRBuilder<> Builder2(BB2);
316
317 Builder1.CreateBr(BB2);
318
319 Instruction *AddInst = cast(Builder2.CreateAdd(V, V));
320 Instruction *MulInst = cast(Builder2.CreateMul(AddInst, V));
321 Instruction *SubInst = cast(Builder2.CreateSub(MulInst, V));
322 Builder2.CreateBr(BB2);
323
324 ValueToValueMapTy Mapping;
325
326 auto Split = DuplicateInstructionsInSplitBetween(BB2, BB2, SubInst, Mapping);
327
328 EXPECT_TRUE(Split);
329 EXPECT_EQ(Mapping.size(), 2u);
330 EXPECT_TRUE(Mapping.find(AddInst) != Mapping.end());
331 EXPECT_TRUE(Mapping.find(MulInst) != Mapping.end());
332
333 auto AddSplit = dyn_cast(Mapping[AddInst]);
334 EXPECT_TRUE(AddSplit);
335 EXPECT_EQ(AddSplit->getOperand(0), V);
336 EXPECT_EQ(AddSplit->getOperand(1), V);
337 EXPECT_EQ(AddSplit->getParent(), Split);
338
339 auto MulSplit = dyn_cast(Mapping[MulInst]);
340 EXPECT_TRUE(MulSplit);
341 EXPECT_EQ(MulSplit->getOperand(0), AddSplit);
342 EXPECT_EQ(MulSplit->getOperand(1), V);
343 EXPECT_EQ(MulSplit->getParent(), Split);
344 EXPECT_EQ(MulSplit->getNextNode(), Split->getTerminator());
345 EXPECT_EQ(Split->getSingleSuccessor(), BB2);
346 EXPECT_EQ(BB2->getSingleSuccessor(), Split);
249347
250348 delete F;
251349 }