1 //===- Cloning.cpp - Unit tests for the Cloner ----------------------------===//
2 //
3 // Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions.
4 // See https://llvm.org/LICENSE.txt for license information.
5 // SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception
6 //
7 //===----------------------------------------------------------------------===//
8
9 #include "llvm/Transforms/Utils/Cloning.h"
10 #include "llvm/ADT/STLExtras.h"
11 #include "llvm/ADT/SmallPtrSet.h"
12 #include "llvm/Analysis/AliasAnalysis.h"
13 #include "llvm/Analysis/DomTreeUpdater.h"
14 #include "llvm/Analysis/LoopInfo.h"
15 #include "llvm/AsmParser/Parser.h"
16 #include "llvm/IR/Argument.h"
17 #include "llvm/IR/Constant.h"
18 #include "llvm/IR/DIBuilder.h"
19 #include "llvm/IR/DebugInfo.h"
20 #include "llvm/IR/Function.h"
21 #include "llvm/IR/IRBuilder.h"
22 #include "llvm/IR/InstIterator.h"
23 #include "llvm/IR/Instructions.h"
24 #include "llvm/IR/IntrinsicInst.h"
25 #include "llvm/IR/LLVMContext.h"
26 #include "llvm/IR/Module.h"
27 #include "llvm/IR/Verifier.h"
28 #include "gtest/gtest.h"
29
30 using namespace llvm;
31
32 namespace {
33
34 class CloneInstruction : public ::testing::Test {
35 protected:
SetUp()36 void SetUp() override { V = nullptr; }
37
38 template <typename T>
clone(T * V1)39 T *clone(T *V1) {
40 Value *V2 = V1->clone();
41 Orig.insert(V1);
42 Clones.insert(V2);
43 return cast<T>(V2);
44 }
45
eraseClones()46 void eraseClones() {
47 for (Value *V : Clones)
48 V->deleteValue();
49 Clones.clear();
50 }
51
TearDown()52 void TearDown() override {
53 eraseClones();
54 for (Value *V : Orig)
55 V->deleteValue();
56 Orig.clear();
57 if (V)
58 V->deleteValue();
59 }
60
61 SmallPtrSet<Value *, 4> Orig; // Erase on exit
62 SmallPtrSet<Value *, 4> Clones; // Erase in eraseClones
63
64 LLVMContext context;
65 Value *V;
66 };
67
TEST_F(CloneInstruction,OverflowBits)68 TEST_F(CloneInstruction, OverflowBits) {
69 V = new Argument(Type::getInt32Ty(context));
70
71 BinaryOperator *Add = BinaryOperator::Create(Instruction::Add, V, V);
72 BinaryOperator *Sub = BinaryOperator::Create(Instruction::Sub, V, V);
73 BinaryOperator *Mul = BinaryOperator::Create(Instruction::Mul, V, V);
74
75 BinaryOperator *AddClone = this->clone(Add);
76 BinaryOperator *SubClone = this->clone(Sub);
77 BinaryOperator *MulClone = this->clone(Mul);
78
79 EXPECT_FALSE(AddClone->hasNoUnsignedWrap());
80 EXPECT_FALSE(AddClone->hasNoSignedWrap());
81 EXPECT_FALSE(SubClone->hasNoUnsignedWrap());
82 EXPECT_FALSE(SubClone->hasNoSignedWrap());
83 EXPECT_FALSE(MulClone->hasNoUnsignedWrap());
84 EXPECT_FALSE(MulClone->hasNoSignedWrap());
85
86 eraseClones();
87
88 Add->setHasNoUnsignedWrap();
89 Sub->setHasNoUnsignedWrap();
90 Mul->setHasNoUnsignedWrap();
91
92 AddClone = this->clone(Add);
93 SubClone = this->clone(Sub);
94 MulClone = this->clone(Mul);
95
96 EXPECT_TRUE(AddClone->hasNoUnsignedWrap());
97 EXPECT_FALSE(AddClone->hasNoSignedWrap());
98 EXPECT_TRUE(SubClone->hasNoUnsignedWrap());
99 EXPECT_FALSE(SubClone->hasNoSignedWrap());
100 EXPECT_TRUE(MulClone->hasNoUnsignedWrap());
101 EXPECT_FALSE(MulClone->hasNoSignedWrap());
102
103 eraseClones();
104
105 Add->setHasNoSignedWrap();
106 Sub->setHasNoSignedWrap();
107 Mul->setHasNoSignedWrap();
108
109 AddClone = this->clone(Add);
110 SubClone = this->clone(Sub);
111 MulClone = this->clone(Mul);
112
113 EXPECT_TRUE(AddClone->hasNoUnsignedWrap());
114 EXPECT_TRUE(AddClone->hasNoSignedWrap());
115 EXPECT_TRUE(SubClone->hasNoUnsignedWrap());
116 EXPECT_TRUE(SubClone->hasNoSignedWrap());
117 EXPECT_TRUE(MulClone->hasNoUnsignedWrap());
118 EXPECT_TRUE(MulClone->hasNoSignedWrap());
119
120 eraseClones();
121
122 Add->setHasNoUnsignedWrap(false);
123 Sub->setHasNoUnsignedWrap(false);
124 Mul->setHasNoUnsignedWrap(false);
125
126 AddClone = this->clone(Add);
127 SubClone = this->clone(Sub);
128 MulClone = this->clone(Mul);
129
130 EXPECT_FALSE(AddClone->hasNoUnsignedWrap());
131 EXPECT_TRUE(AddClone->hasNoSignedWrap());
132 EXPECT_FALSE(SubClone->hasNoUnsignedWrap());
133 EXPECT_TRUE(SubClone->hasNoSignedWrap());
134 EXPECT_FALSE(MulClone->hasNoUnsignedWrap());
135 EXPECT_TRUE(MulClone->hasNoSignedWrap());
136 }
137
TEST_F(CloneInstruction,Inbounds)138 TEST_F(CloneInstruction, Inbounds) {
139 V = new Argument(Type::getInt32PtrTy(context));
140
141 Constant *Z = Constant::getNullValue(Type::getInt32Ty(context));
142 std::vector<Value *> ops;
143 ops.push_back(Z);
144 GetElementPtrInst *GEP =
145 GetElementPtrInst::Create(Type::getInt32Ty(context), V, ops);
146 EXPECT_FALSE(this->clone(GEP)->isInBounds());
147
148 GEP->setIsInBounds();
149 EXPECT_TRUE(this->clone(GEP)->isInBounds());
150 }
151
TEST_F(CloneInstruction,Exact)152 TEST_F(CloneInstruction, Exact) {
153 V = new Argument(Type::getInt32Ty(context));
154
155 BinaryOperator *SDiv = BinaryOperator::Create(Instruction::SDiv, V, V);
156 EXPECT_FALSE(this->clone(SDiv)->isExact());
157
158 SDiv->setIsExact(true);
159 EXPECT_TRUE(this->clone(SDiv)->isExact());
160 }
161
TEST_F(CloneInstruction,Attributes)162 TEST_F(CloneInstruction, Attributes) {
163 Type *ArgTy1[] = { Type::getInt32PtrTy(context) };
164 FunctionType *FT1 = FunctionType::get(Type::getVoidTy(context), ArgTy1, false);
165
166 Function *F1 = Function::Create(FT1, Function::ExternalLinkage);
167 BasicBlock *BB = BasicBlock::Create(context, "", F1);
168 IRBuilder<> Builder(BB);
169 Builder.CreateRetVoid();
170
171 Function *F2 = Function::Create(FT1, Function::ExternalLinkage);
172
173 Argument *A = &*F1->arg_begin();
174 A->addAttr(Attribute::NoCapture);
175
176 SmallVector<ReturnInst*, 4> Returns;
177 ValueToValueMapTy VMap;
178 VMap[A] = UndefValue::get(A->getType());
179
180 CloneFunctionInto(F2, F1, VMap, false, Returns);
181 EXPECT_FALSE(F2->arg_begin()->hasNoCaptureAttr());
182
183 delete F1;
184 delete F2;
185 }
186
TEST_F(CloneInstruction,CallingConvention)187 TEST_F(CloneInstruction, CallingConvention) {
188 Type *ArgTy1[] = { Type::getInt32PtrTy(context) };
189 FunctionType *FT1 = FunctionType::get(Type::getVoidTy(context), ArgTy1, false);
190
191 Function *F1 = Function::Create(FT1, Function::ExternalLinkage);
192 F1->setCallingConv(CallingConv::Cold);
193 BasicBlock *BB = BasicBlock::Create(context, "", F1);
194 IRBuilder<> Builder(BB);
195 Builder.CreateRetVoid();
196
197 Function *F2 = Function::Create(FT1, Function::ExternalLinkage);
198
199 SmallVector<ReturnInst*, 4> Returns;
200 ValueToValueMapTy VMap;
201 VMap[&*F1->arg_begin()] = &*F2->arg_begin();
202
203 CloneFunctionInto(F2, F1, VMap, false, Returns);
204 EXPECT_EQ(CallingConv::Cold, F2->getCallingConv());
205
206 delete F1;
207 delete F2;
208 }
209
TEST_F(CloneInstruction,DuplicateInstructionsToSplit)210 TEST_F(CloneInstruction, DuplicateInstructionsToSplit) {
211 Type *ArgTy1[] = {Type::getInt32PtrTy(context)};
212 FunctionType *FT = FunctionType::get(Type::getVoidTy(context), ArgTy1, false);
213 V = new Argument(Type::getInt32Ty(context));
214
215 Function *F = Function::Create(FT, Function::ExternalLinkage);
216
217 BasicBlock *BB1 = BasicBlock::Create(context, "", F);
218 IRBuilder<> Builder1(BB1);
219
220 BasicBlock *BB2 = BasicBlock::Create(context, "", F);
221 IRBuilder<> Builder2(BB2);
222
223 Builder1.CreateBr(BB2);
224
225 Instruction *AddInst = cast<Instruction>(Builder2.CreateAdd(V, V));
226 Instruction *MulInst = cast<Instruction>(Builder2.CreateMul(AddInst, V));
227 Instruction *SubInst = cast<Instruction>(Builder2.CreateSub(MulInst, V));
228 Builder2.CreateRetVoid();
229
230 // Dummy DTU.
231 ValueToValueMapTy Mapping;
232 DomTreeUpdater DTU(DomTreeUpdater::UpdateStrategy::Lazy);
233 auto Split =
234 DuplicateInstructionsInSplitBetween(BB2, BB1, SubInst, Mapping, DTU);
235
236 EXPECT_TRUE(Split);
237 EXPECT_EQ(Mapping.size(), 2u);
238 EXPECT_TRUE(Mapping.find(AddInst) != Mapping.end());
239 EXPECT_TRUE(Mapping.find(MulInst) != Mapping.end());
240
241 auto AddSplit = dyn_cast<Instruction>(Mapping[AddInst]);
242 EXPECT_TRUE(AddSplit);
243 EXPECT_EQ(AddSplit->getOperand(0), V);
244 EXPECT_EQ(AddSplit->getOperand(1), V);
245 EXPECT_EQ(AddSplit->getParent(), Split);
246
247 auto MulSplit = dyn_cast<Instruction>(Mapping[MulInst]);
248 EXPECT_TRUE(MulSplit);
249 EXPECT_EQ(MulSplit->getOperand(0), AddSplit);
250 EXPECT_EQ(MulSplit->getOperand(1), V);
251 EXPECT_EQ(MulSplit->getParent(), Split);
252
253 EXPECT_EQ(AddSplit->getNextNode(), MulSplit);
254 EXPECT_EQ(MulSplit->getNextNode(), Split->getTerminator());
255
256 delete F;
257 }
258
TEST_F(CloneInstruction,DuplicateInstructionsToSplitBlocksEq1)259 TEST_F(CloneInstruction, DuplicateInstructionsToSplitBlocksEq1) {
260 Type *ArgTy1[] = {Type::getInt32PtrTy(context)};
261 FunctionType *FT = FunctionType::get(Type::getVoidTy(context), ArgTy1, false);
262 V = new Argument(Type::getInt32Ty(context));
263
264 Function *F = Function::Create(FT, Function::ExternalLinkage);
265
266 BasicBlock *BB1 = BasicBlock::Create(context, "", F);
267 IRBuilder<> Builder1(BB1);
268
269 BasicBlock *BB2 = BasicBlock::Create(context, "", F);
270 IRBuilder<> Builder2(BB2);
271
272 Builder1.CreateBr(BB2);
273
274 Instruction *AddInst = cast<Instruction>(Builder2.CreateAdd(V, V));
275 Instruction *MulInst = cast<Instruction>(Builder2.CreateMul(AddInst, V));
276 Instruction *SubInst = cast<Instruction>(Builder2.CreateSub(MulInst, V));
277 Builder2.CreateBr(BB2);
278
279 // Dummy DTU.
280 DomTreeUpdater DTU(DomTreeUpdater::UpdateStrategy::Lazy);
281 ValueToValueMapTy Mapping;
282 auto Split = DuplicateInstructionsInSplitBetween(
283 BB2, BB2, BB2->getTerminator(), Mapping, DTU);
284
285 EXPECT_TRUE(Split);
286 EXPECT_EQ(Mapping.size(), 3u);
287 EXPECT_TRUE(Mapping.find(AddInst) != Mapping.end());
288 EXPECT_TRUE(Mapping.find(MulInst) != Mapping.end());
289 EXPECT_TRUE(Mapping.find(SubInst) != Mapping.end());
290
291 auto AddSplit = dyn_cast<Instruction>(Mapping[AddInst]);
292 EXPECT_TRUE(AddSplit);
293 EXPECT_EQ(AddSplit->getOperand(0), V);
294 EXPECT_EQ(AddSplit->getOperand(1), V);
295 EXPECT_EQ(AddSplit->getParent(), Split);
296
297 auto MulSplit = dyn_cast<Instruction>(Mapping[MulInst]);
298 EXPECT_TRUE(MulSplit);
299 EXPECT_EQ(MulSplit->getOperand(0), AddSplit);
300 EXPECT_EQ(MulSplit->getOperand(1), V);
301 EXPECT_EQ(MulSplit->getParent(), Split);
302
303 auto SubSplit = dyn_cast<Instruction>(Mapping[SubInst]);
304 EXPECT_EQ(MulSplit->getNextNode(), SubSplit);
305 EXPECT_EQ(SubSplit->getNextNode(), Split->getTerminator());
306 EXPECT_EQ(Split->getSingleSuccessor(), BB2);
307 EXPECT_EQ(BB2->getSingleSuccessor(), Split);
308
309 delete F;
310 }
311
TEST_F(CloneInstruction,DuplicateInstructionsToSplitBlocksEq2)312 TEST_F(CloneInstruction, DuplicateInstructionsToSplitBlocksEq2) {
313 Type *ArgTy1[] = {Type::getInt32PtrTy(context)};
314 FunctionType *FT = FunctionType::get(Type::getVoidTy(context), ArgTy1, false);
315 V = new Argument(Type::getInt32Ty(context));
316
317 Function *F = Function::Create(FT, Function::ExternalLinkage);
318
319 BasicBlock *BB1 = BasicBlock::Create(context, "", F);
320 IRBuilder<> Builder1(BB1);
321
322 BasicBlock *BB2 = BasicBlock::Create(context, "", F);
323 IRBuilder<> Builder2(BB2);
324
325 Builder1.CreateBr(BB2);
326
327 Instruction *AddInst = cast<Instruction>(Builder2.CreateAdd(V, V));
328 Instruction *MulInst = cast<Instruction>(Builder2.CreateMul(AddInst, V));
329 Instruction *SubInst = cast<Instruction>(Builder2.CreateSub(MulInst, V));
330 Builder2.CreateBr(BB2);
331
332 // Dummy DTU.
333 DomTreeUpdater DTU(DomTreeUpdater::UpdateStrategy::Lazy);
334 ValueToValueMapTy Mapping;
335 auto Split =
336 DuplicateInstructionsInSplitBetween(BB2, BB2, SubInst, Mapping, DTU);
337
338 EXPECT_TRUE(Split);
339 EXPECT_EQ(Mapping.size(), 2u);
340 EXPECT_TRUE(Mapping.find(AddInst) != Mapping.end());
341 EXPECT_TRUE(Mapping.find(MulInst) != Mapping.end());
342
343 auto AddSplit = dyn_cast<Instruction>(Mapping[AddInst]);
344 EXPECT_TRUE(AddSplit);
345 EXPECT_EQ(AddSplit->getOperand(0), V);
346 EXPECT_EQ(AddSplit->getOperand(1), V);
347 EXPECT_EQ(AddSplit->getParent(), Split);
348
349 auto MulSplit = dyn_cast<Instruction>(Mapping[MulInst]);
350 EXPECT_TRUE(MulSplit);
351 EXPECT_EQ(MulSplit->getOperand(0), AddSplit);
352 EXPECT_EQ(MulSplit->getOperand(1), V);
353 EXPECT_EQ(MulSplit->getParent(), Split);
354 EXPECT_EQ(MulSplit->getNextNode(), Split->getTerminator());
355 EXPECT_EQ(Split->getSingleSuccessor(), BB2);
356 EXPECT_EQ(BB2->getSingleSuccessor(), Split);
357
358 delete F;
359 }
360
runWithLoopInfoAndDominatorTree(Module & M,StringRef FuncName,function_ref<void (Function & F,LoopInfo & LI,DominatorTree & DT)> Test)361 static void runWithLoopInfoAndDominatorTree(
362 Module &M, StringRef FuncName,
363 function_ref<void(Function &F, LoopInfo &LI, DominatorTree &DT)> Test) {
364 auto *F = M.getFunction(FuncName);
365 ASSERT_NE(F, nullptr) << "Could not find " << FuncName;
366
367 DominatorTree DT(*F);
368 LoopInfo LI(DT);
369
370 Test(*F, LI, DT);
371 }
372
parseIR(LLVMContext & C,const char * IR)373 static std::unique_ptr<Module> parseIR(LLVMContext &C, const char *IR) {
374 SMDiagnostic Err;
375 std::unique_ptr<Module> Mod = parseAssemblyString(IR, Err, C);
376 if (!Mod)
377 Err.print("CloneLoop", errs());
378 return Mod;
379 }
380
TEST(CloneLoop,CloneLoopNest)381 TEST(CloneLoop, CloneLoopNest) {
382 // Parse the module.
383 LLVMContext Context;
384
385 std::unique_ptr<Module> M = parseIR(
386 Context,
387 R"(define void @foo(i32* %A, i32 %ub) {
388 entry:
389 %guardcmp = icmp slt i32 0, %ub
390 br i1 %guardcmp, label %for.outer.preheader, label %for.end
391 for.outer.preheader:
392 br label %for.outer
393 for.outer:
394 %j = phi i32 [ 0, %for.outer.preheader ], [ %inc.outer, %for.outer.latch ]
395 br i1 %guardcmp, label %for.inner.preheader, label %for.outer.latch
396 for.inner.preheader:
397 br label %for.inner
398 for.inner:
399 %i = phi i32 [ 0, %for.inner.preheader ], [ %inc, %for.inner ]
400 %idxprom = sext i32 %i to i64
401 %arrayidx = getelementptr inbounds i32, i32* %A, i64 %idxprom
402 store i32 %i, i32* %arrayidx, align 4
403 %inc = add nsw i32 %i, 1
404 %cmp = icmp slt i32 %inc, %ub
405 br i1 %cmp, label %for.inner, label %for.inner.exit
406 for.inner.exit:
407 br label %for.outer.latch
408 for.outer.latch:
409 %inc.outer = add nsw i32 %j, 1
410 %cmp.outer = icmp slt i32 %inc.outer, %ub
411 br i1 %cmp.outer, label %for.outer, label %for.outer.exit
412 for.outer.exit:
413 br label %for.end
414 for.end:
415 ret void
416 })"
417 );
418
419 runWithLoopInfoAndDominatorTree(
420 *M, "foo", [&](Function &F, LoopInfo &LI, DominatorTree &DT) {
421 Function::iterator FI = F.begin();
422 // First basic block is entry - skip it.
423 BasicBlock *Preheader = &*(++FI);
424 BasicBlock *Header = &*(++FI);
425 assert(Header->getName() == "for.outer");
426 Loop *L = LI.getLoopFor(Header);
427 EXPECT_NE(L, nullptr);
428 EXPECT_EQ(Header, L->getHeader());
429 EXPECT_EQ(Preheader, L->getLoopPreheader());
430
431 ValueToValueMapTy VMap;
432 SmallVector<BasicBlock *, 4> ClonedLoopBlocks;
433 Loop *NewLoop = cloneLoopWithPreheader(Preheader, Preheader, L, VMap,
434 "", &LI, &DT, ClonedLoopBlocks);
435 EXPECT_NE(NewLoop, nullptr);
436 EXPECT_EQ(NewLoop->getSubLoops().size(), 1u);
437 Loop::block_iterator BI = NewLoop->block_begin();
438 EXPECT_TRUE((*BI)->getName().startswith("for.outer"));
439 EXPECT_TRUE((*(++BI))->getName().startswith("for.inner.preheader"));
440 EXPECT_TRUE((*(++BI))->getName().startswith("for.inner"));
441 EXPECT_TRUE((*(++BI))->getName().startswith("for.inner.exit"));
442 EXPECT_TRUE((*(++BI))->getName().startswith("for.outer.latch"));
443 });
444 }
445
446 class CloneFunc : public ::testing::Test {
447 protected:
SetUp()448 void SetUp() override {
449 SetupModule();
450 CreateOldFunc();
451 CreateNewFunc();
452 SetupFinder();
453 }
454
TearDown()455 void TearDown() override { delete Finder; }
456
SetupModule()457 void SetupModule() {
458 M = new Module("", C);
459 }
460
CreateOldFunc()461 void CreateOldFunc() {
462 FunctionType* FuncType = FunctionType::get(Type::getVoidTy(C), false);
463 OldFunc = Function::Create(FuncType, GlobalValue::PrivateLinkage, "f", M);
464 CreateOldFunctionBodyAndDI();
465 }
466
CreateOldFunctionBodyAndDI()467 void CreateOldFunctionBodyAndDI() {
468 DIBuilder DBuilder(*M);
469 IRBuilder<> IBuilder(C);
470
471 // Function DI
472 auto *File = DBuilder.createFile("filename.c", "/file/dir/");
473 DITypeRefArray ParamTypes = DBuilder.getOrCreateTypeArray(None);
474 DISubroutineType *FuncType =
475 DBuilder.createSubroutineType(ParamTypes);
476 auto *CU = DBuilder.createCompileUnit(dwarf::DW_LANG_C99,
477 DBuilder.createFile("filename.c",
478 "/file/dir"),
479 "CloneFunc", false, "", 0);
480
481 auto *Subprogram = DBuilder.createFunction(
482 CU, "f", "f", File, 4, FuncType, 3, DINode::FlagZero,
483 DISubprogram::SPFlagLocalToUnit | DISubprogram::SPFlagDefinition);
484 OldFunc->setSubprogram(Subprogram);
485
486 // Function body
487 BasicBlock* Entry = BasicBlock::Create(C, "", OldFunc);
488 IBuilder.SetInsertPoint(Entry);
489 DebugLoc Loc = DebugLoc::get(3, 2, Subprogram);
490 IBuilder.SetCurrentDebugLocation(Loc);
491 AllocaInst* Alloca = IBuilder.CreateAlloca(IntegerType::getInt32Ty(C));
492 IBuilder.SetCurrentDebugLocation(DebugLoc::get(4, 2, Subprogram));
493 Value* AllocaContent = IBuilder.getInt32(1);
494 Instruction* Store = IBuilder.CreateStore(AllocaContent, Alloca);
495 IBuilder.SetCurrentDebugLocation(DebugLoc::get(5, 2, Subprogram));
496
497 // Create a local variable around the alloca
498 auto *IntType = DBuilder.createBasicType("int", 32, dwarf::DW_ATE_signed);
499 auto *E = DBuilder.createExpression();
500 auto *Variable =
501 DBuilder.createAutoVariable(Subprogram, "x", File, 5, IntType, true);
502 auto *DL = DILocation::get(Subprogram->getContext(), 5, 0, Subprogram);
503 DBuilder.insertDeclare(Alloca, Variable, E, DL, Store);
504 DBuilder.insertDbgValueIntrinsic(AllocaContent, Variable, E, DL, Entry);
505 // Also create an inlined variable.
506 // Create a distinct struct type that we should not duplicate during
507 // cloning).
508 auto *StructType = DICompositeType::getDistinct(
509 C, dwarf::DW_TAG_structure_type, "some_struct", nullptr, 0, nullptr,
510 nullptr, 32, 32, 0, DINode::FlagZero, nullptr, 0, nullptr, nullptr);
511 auto *InlinedSP = DBuilder.createFunction(
512 CU, "inlined", "inlined", File, 8, FuncType, 9, DINode::FlagZero,
513 DISubprogram::SPFlagLocalToUnit | DISubprogram::SPFlagDefinition);
514 auto *InlinedVar =
515 DBuilder.createAutoVariable(InlinedSP, "inlined", File, 5, StructType, true);
516 auto *Scope = DBuilder.createLexicalBlock(
517 DBuilder.createLexicalBlockFile(InlinedSP, File), File, 1, 1);
518 auto InlinedDL =
519 DebugLoc::get(9, 4, Scope, DebugLoc::get(5, 2, Subprogram));
520 IBuilder.SetCurrentDebugLocation(InlinedDL);
521 DBuilder.insertDeclare(Alloca, InlinedVar, E, InlinedDL, Store);
522 IBuilder.CreateStore(IBuilder.getInt32(2), Alloca);
523 // Finalize the debug info.
524 DBuilder.finalize();
525 IBuilder.CreateRetVoid();
526
527 // Create another, empty, compile unit.
528 DIBuilder DBuilder2(*M);
529 DBuilder2.createCompileUnit(dwarf::DW_LANG_C99,
530 DBuilder.createFile("extra.c", "/file/dir"),
531 "CloneFunc", false, "", 0);
532 DBuilder2.finalize();
533 }
534
CreateNewFunc()535 void CreateNewFunc() {
536 ValueToValueMapTy VMap;
537 NewFunc = CloneFunction(OldFunc, VMap, nullptr);
538 }
539
SetupFinder()540 void SetupFinder() {
541 Finder = new DebugInfoFinder();
542 Finder->processModule(*M);
543 }
544
545 LLVMContext C;
546 Function* OldFunc;
547 Function* NewFunc;
548 Module* M;
549 DebugInfoFinder* Finder;
550 };
551
552 // Test that a new, distinct function was created.
TEST_F(CloneFunc,NewFunctionCreated)553 TEST_F(CloneFunc, NewFunctionCreated) {
554 EXPECT_NE(OldFunc, NewFunc);
555 }
556
557 // Test that a new subprogram entry was added and is pointing to the new
558 // function, while the original subprogram still points to the old one.
TEST_F(CloneFunc,Subprogram)559 TEST_F(CloneFunc, Subprogram) {
560 EXPECT_FALSE(verifyModule(*M, &errs()));
561 EXPECT_EQ(3U, Finder->subprogram_count());
562 EXPECT_NE(NewFunc->getSubprogram(), OldFunc->getSubprogram());
563 }
564
565 // Test that instructions in the old function still belong to it in the
566 // metadata, while instruction in the new function belong to the new one.
TEST_F(CloneFunc,InstructionOwnership)567 TEST_F(CloneFunc, InstructionOwnership) {
568 EXPECT_FALSE(verifyModule(*M));
569
570 inst_iterator OldIter = inst_begin(OldFunc);
571 inst_iterator OldEnd = inst_end(OldFunc);
572 inst_iterator NewIter = inst_begin(NewFunc);
573 inst_iterator NewEnd = inst_end(NewFunc);
574 while (OldIter != OldEnd && NewIter != NewEnd) {
575 Instruction& OldI = *OldIter;
576 Instruction& NewI = *NewIter;
577 EXPECT_NE(&OldI, &NewI);
578
579 EXPECT_EQ(OldI.hasMetadata(), NewI.hasMetadata());
580 if (OldI.hasMetadata()) {
581 const DebugLoc& OldDL = OldI.getDebugLoc();
582 const DebugLoc& NewDL = NewI.getDebugLoc();
583
584 // Verify that the debug location data is the same
585 EXPECT_EQ(OldDL.getLine(), NewDL.getLine());
586 EXPECT_EQ(OldDL.getCol(), NewDL.getCol());
587
588 // But that they belong to different functions
589 auto *OldSubprogram = cast<DISubprogram>(OldDL.getInlinedAtScope());
590 auto *NewSubprogram = cast<DISubprogram>(NewDL.getInlinedAtScope());
591 EXPECT_EQ(OldFunc->getSubprogram(), OldSubprogram);
592 EXPECT_EQ(NewFunc->getSubprogram(), NewSubprogram);
593 }
594
595 ++OldIter;
596 ++NewIter;
597 }
598 EXPECT_EQ(OldEnd, OldIter);
599 EXPECT_EQ(NewEnd, NewIter);
600 }
601
602 // Test that the arguments for debug intrinsics in the new function were
603 // properly cloned
TEST_F(CloneFunc,DebugIntrinsics)604 TEST_F(CloneFunc, DebugIntrinsics) {
605 EXPECT_FALSE(verifyModule(*M));
606
607 inst_iterator OldIter = inst_begin(OldFunc);
608 inst_iterator OldEnd = inst_end(OldFunc);
609 inst_iterator NewIter = inst_begin(NewFunc);
610 inst_iterator NewEnd = inst_end(NewFunc);
611 while (OldIter != OldEnd && NewIter != NewEnd) {
612 Instruction& OldI = *OldIter;
613 Instruction& NewI = *NewIter;
614 if (DbgDeclareInst* OldIntrin = dyn_cast<DbgDeclareInst>(&OldI)) {
615 DbgDeclareInst* NewIntrin = dyn_cast<DbgDeclareInst>(&NewI);
616 EXPECT_TRUE(NewIntrin);
617
618 // Old address must belong to the old function
619 EXPECT_EQ(OldFunc, cast<AllocaInst>(OldIntrin->getAddress())->
620 getParent()->getParent());
621 // New address must belong to the new function
622 EXPECT_EQ(NewFunc, cast<AllocaInst>(NewIntrin->getAddress())->
623 getParent()->getParent());
624
625 if (OldIntrin->getDebugLoc()->getInlinedAt()) {
626 // Inlined variable should refer to the same DILocalVariable as in the
627 // Old Function
628 EXPECT_EQ(OldIntrin->getVariable(), NewIntrin->getVariable());
629 } else {
630 // Old variable must belong to the old function.
631 EXPECT_EQ(OldFunc->getSubprogram(),
632 cast<DISubprogram>(OldIntrin->getVariable()->getScope()));
633 // New variable must belong to the new function.
634 EXPECT_EQ(NewFunc->getSubprogram(),
635 cast<DISubprogram>(NewIntrin->getVariable()->getScope()));
636 }
637 } else if (DbgValueInst* OldIntrin = dyn_cast<DbgValueInst>(&OldI)) {
638 DbgValueInst* NewIntrin = dyn_cast<DbgValueInst>(&NewI);
639 EXPECT_TRUE(NewIntrin);
640
641 if (!OldIntrin->getDebugLoc()->getInlinedAt()) {
642 // Old variable must belong to the old function.
643 EXPECT_EQ(OldFunc->getSubprogram(),
644 cast<DISubprogram>(OldIntrin->getVariable()->getScope()));
645 // New variable must belong to the new function.
646 EXPECT_EQ(NewFunc->getSubprogram(),
647 cast<DISubprogram>(NewIntrin->getVariable()->getScope()));
648 }
649 }
650
651 ++OldIter;
652 ++NewIter;
653 }
654 }
655
GetDICompileUnitCount(const Module & M)656 static int GetDICompileUnitCount(const Module& M) {
657 if (const auto* LLVM_DBG_CU = M.getNamedMetadata("llvm.dbg.cu")) {
658 return LLVM_DBG_CU->getNumOperands();
659 }
660 return 0;
661 }
662
TEST(CloneFunction,CloneEmptyFunction)663 TEST(CloneFunction, CloneEmptyFunction) {
664 StringRef ImplAssembly = R"(
665 define void @foo() {
666 ret void
667 }
668 declare void @bar()
669 )";
670
671 LLVMContext Context;
672 SMDiagnostic Error;
673
674 auto ImplModule = parseAssemblyString(ImplAssembly, Error, Context);
675 EXPECT_TRUE(ImplModule != nullptr);
676 auto *ImplFunction = ImplModule->getFunction("foo");
677 EXPECT_TRUE(ImplFunction != nullptr);
678 auto *DeclFunction = ImplModule->getFunction("bar");
679 EXPECT_TRUE(DeclFunction != nullptr);
680
681 ValueToValueMapTy VMap;
682 SmallVector<ReturnInst *, 8> Returns;
683 ClonedCodeInfo CCI;
684 CloneFunctionInto(ImplFunction, DeclFunction, VMap, true, Returns, "", &CCI);
685
686 EXPECT_FALSE(verifyModule(*ImplModule, &errs()));
687 EXPECT_FALSE(CCI.ContainsCalls);
688 EXPECT_FALSE(CCI.ContainsDynamicAllocas);
689 }
690
TEST(CloneFunction,CloneFunctionWithInalloca)691 TEST(CloneFunction, CloneFunctionWithInalloca) {
692 StringRef ImplAssembly = R"(
693 declare void @a(i32* inalloca)
694 define void @foo() {
695 %a = alloca inalloca i32
696 call void @a(i32* inalloca %a)
697 ret void
698 }
699 declare void @bar()
700 )";
701
702 LLVMContext Context;
703 SMDiagnostic Error;
704
705 auto ImplModule = parseAssemblyString(ImplAssembly, Error, Context);
706 EXPECT_TRUE(ImplModule != nullptr);
707 auto *ImplFunction = ImplModule->getFunction("foo");
708 EXPECT_TRUE(ImplFunction != nullptr);
709 auto *DeclFunction = ImplModule->getFunction("bar");
710 EXPECT_TRUE(DeclFunction != nullptr);
711
712 ValueToValueMapTy VMap;
713 SmallVector<ReturnInst *, 8> Returns;
714 ClonedCodeInfo CCI;
715 CloneFunctionInto(DeclFunction, ImplFunction, VMap, true, Returns, "", &CCI);
716
717 EXPECT_FALSE(verifyModule(*ImplModule, &errs()));
718 EXPECT_TRUE(CCI.ContainsCalls);
719 EXPECT_TRUE(CCI.ContainsDynamicAllocas);
720 }
721
TEST(CloneFunction,CloneFunctionWithSubprograms)722 TEST(CloneFunction, CloneFunctionWithSubprograms) {
723 // Tests that the debug info is duplicated correctly when a DISubprogram
724 // happens to be one of the operands of the DISubprogram that is being cloned.
725 // In general, operands of "test" that are distinct should be duplicated,
726 // but in this case "my_operator" should not be duplicated. If it is
727 // duplicated, the metadata in the llvm.dbg.declare could end up with
728 // different duplicates.
729 StringRef ImplAssembly = R"(
730 declare void @llvm.dbg.declare(metadata, metadata, metadata)
731
732 define void @test() !dbg !5 {
733 call void @llvm.dbg.declare(metadata i8* undef, metadata !4, metadata !DIExpression()), !dbg !6
734 ret void
735 }
736
737 declare void @cloned()
738
739 !llvm.dbg.cu = !{!0}
740 !llvm.module.flags = !{!2}
741 !0 = distinct !DICompileUnit(language: DW_LANG_C99, file: !1)
742 !1 = !DIFile(filename: "test.cpp", directory: "")
743 !2 = !{i32 1, !"Debug Info Version", i32 3}
744 !3 = distinct !DISubprogram(name: "my_operator", scope: !1, unit: !0, retainedNodes: !{!4})
745 !4 = !DILocalVariable(name: "awaitables", scope: !3)
746 !5 = distinct !DISubprogram(name: "test", scope: !3, unit: !0)
747 !6 = !DILocation(line: 55, column: 15, scope: !3, inlinedAt: !7)
748 !7 = distinct !DILocation(line: 73, column: 14, scope: !5)
749 )";
750
751 LLVMContext Context;
752 SMDiagnostic Error;
753
754 auto ImplModule = parseAssemblyString(ImplAssembly, Error, Context);
755 EXPECT_TRUE(ImplModule != nullptr);
756 auto *OldFunc = ImplModule->getFunction("test");
757 EXPECT_TRUE(OldFunc != nullptr);
758 auto *NewFunc = ImplModule->getFunction("cloned");
759 EXPECT_TRUE(NewFunc != nullptr);
760
761 ValueToValueMapTy VMap;
762 SmallVector<ReturnInst *, 8> Returns;
763 ClonedCodeInfo CCI;
764 CloneFunctionInto(NewFunc, OldFunc, VMap, true, Returns, "", &CCI);
765
766 // This fails if the scopes in the llvm.dbg.declare variable and location
767 // aren't the same.
768 EXPECT_FALSE(verifyModule(*ImplModule, &errs()));
769 }
770
TEST(CloneFunction,CloneFunctionToDifferentModule)771 TEST(CloneFunction, CloneFunctionToDifferentModule) {
772 StringRef ImplAssembly = R"(
773 define void @foo() {
774 ret void, !dbg !5
775 }
776
777 !llvm.module.flags = !{!0}
778 !llvm.dbg.cu = !{!2, !6}
779 !0 = !{i32 1, !"Debug Info Version", i32 3}
780 !1 = distinct !DISubprogram(unit: !2)
781 !2 = distinct !DICompileUnit(language: DW_LANG_C99, file: !3)
782 !3 = !DIFile(filename: "foo.c", directory: "/tmp")
783 !4 = distinct !DISubprogram(unit: !2)
784 !5 = !DILocation(line: 4, scope: !1)
785 !6 = distinct !DICompileUnit(language: DW_LANG_C99, file: !3)
786 )";
787 StringRef DeclAssembly = R"(
788 declare void @foo()
789 )";
790
791 LLVMContext Context;
792 SMDiagnostic Error;
793
794 auto ImplModule = parseAssemblyString(ImplAssembly, Error, Context);
795 EXPECT_TRUE(ImplModule != nullptr);
796 // DICompileUnits: !2, !6. Only !2 is reachable from @foo().
797 EXPECT_TRUE(GetDICompileUnitCount(*ImplModule) == 2);
798 auto* ImplFunction = ImplModule->getFunction("foo");
799 EXPECT_TRUE(ImplFunction != nullptr);
800
801 auto DeclModule = parseAssemblyString(DeclAssembly, Error, Context);
802 EXPECT_TRUE(DeclModule != nullptr);
803 // No DICompileUnits defined here.
804 EXPECT_TRUE(GetDICompileUnitCount(*DeclModule) == 0);
805 auto* DeclFunction = DeclModule->getFunction("foo");
806 EXPECT_TRUE(DeclFunction != nullptr);
807
808 ValueToValueMapTy VMap;
809 VMap[ImplFunction] = DeclFunction;
810 // No args to map
811 SmallVector<ReturnInst*, 8> Returns;
812 CloneFunctionInto(DeclFunction, ImplFunction, VMap, true, Returns);
813
814 EXPECT_FALSE(verifyModule(*ImplModule, &errs()));
815 EXPECT_FALSE(verifyModule(*DeclModule, &errs()));
816 // DICompileUnit !2 shall be inserted into DeclModule.
817 EXPECT_TRUE(GetDICompileUnitCount(*DeclModule) == 1);
818 }
819
820 class CloneModule : public ::testing::Test {
821 protected:
SetUp()822 void SetUp() override {
823 SetupModule();
824 CreateOldModule();
825 CreateNewModule();
826 }
827
SetupModule()828 void SetupModule() { OldM = new Module("", C); }
829
CreateOldModule()830 void CreateOldModule() {
831 auto *CD = OldM->getOrInsertComdat("comdat");
832 CD->setSelectionKind(Comdat::ExactMatch);
833
834 auto GV = new GlobalVariable(
835 *OldM, Type::getInt32Ty(C), false, GlobalValue::ExternalLinkage,
836 ConstantInt::get(Type::getInt32Ty(C), 1), "gv");
837 GV->addMetadata(LLVMContext::MD_type, *MDNode::get(C, {}));
838 GV->setComdat(CD);
839
840 DIBuilder DBuilder(*OldM);
841 IRBuilder<> IBuilder(C);
842
843 auto *FuncType = FunctionType::get(Type::getVoidTy(C), false);
844 auto *PersFn = Function::Create(FuncType, GlobalValue::ExternalLinkage,
845 "persfn", OldM);
846 auto *F =
847 Function::Create(FuncType, GlobalValue::PrivateLinkage, "f", OldM);
848 F->setPersonalityFn(PersFn);
849 F->setComdat(CD);
850
851 // Create debug info
852 auto *File = DBuilder.createFile("filename.c", "/file/dir/");
853 DITypeRefArray ParamTypes = DBuilder.getOrCreateTypeArray(None);
854 DISubroutineType *DFuncType = DBuilder.createSubroutineType(ParamTypes);
855 auto *CU = DBuilder.createCompileUnit(dwarf::DW_LANG_C99,
856 DBuilder.createFile("filename.c",
857 "/file/dir"),
858 "CloneModule", false, "", 0);
859 // Function DI
860 auto *Subprogram = DBuilder.createFunction(
861 CU, "f", "f", File, 4, DFuncType, 3, DINode::FlagZero,
862 DISubprogram::SPFlagLocalToUnit | DISubprogram::SPFlagDefinition);
863 F->setSubprogram(Subprogram);
864
865 // Create and assign DIGlobalVariableExpression to gv
866 auto GVExpression = DBuilder.createGlobalVariableExpression(
867 Subprogram, "gv", "gv", File, 1, DBuilder.createNullPtrType(), false);
868 GV->addDebugInfo(GVExpression);
869
870 // DIGlobalVariableExpression not attached to any global variable
871 auto Expr = DBuilder.createExpression(
872 ArrayRef<uint64_t>{dwarf::DW_OP_constu, 42U, dwarf::DW_OP_stack_value});
873
874 DBuilder.createGlobalVariableExpression(
875 Subprogram, "unattached", "unattached", File, 1,
876 DBuilder.createNullPtrType(), false, true, Expr);
877
878 auto *Entry = BasicBlock::Create(C, "", F);
879 IBuilder.SetInsertPoint(Entry);
880 IBuilder.CreateRetVoid();
881
882 // Finalize the debug info
883 DBuilder.finalize();
884 }
885
CreateNewModule()886 void CreateNewModule() { NewM = llvm::CloneModule(*OldM).release(); }
887
888 LLVMContext C;
889 Module *OldM;
890 Module *NewM;
891 };
892
TEST_F(CloneModule,Verify)893 TEST_F(CloneModule, Verify) {
894 EXPECT_FALSE(verifyModule(*NewM));
895 }
896
TEST_F(CloneModule,OldModuleUnchanged)897 TEST_F(CloneModule, OldModuleUnchanged) {
898 DebugInfoFinder Finder;
899 Finder.processModule(*OldM);
900 EXPECT_EQ(1U, Finder.subprogram_count());
901 }
902
TEST_F(CloneModule,Subprogram)903 TEST_F(CloneModule, Subprogram) {
904 Function *NewF = NewM->getFunction("f");
905 DISubprogram *SP = NewF->getSubprogram();
906 EXPECT_TRUE(SP != nullptr);
907 EXPECT_EQ(SP->getName(), "f");
908 EXPECT_EQ(SP->getFile()->getFilename(), "filename.c");
909 EXPECT_EQ(SP->getLine(), (unsigned)4);
910 }
911
TEST_F(CloneModule,GlobalMetadata)912 TEST_F(CloneModule, GlobalMetadata) {
913 GlobalVariable *NewGV = NewM->getGlobalVariable("gv");
914 EXPECT_NE(nullptr, NewGV->getMetadata(LLVMContext::MD_type));
915 }
916
TEST_F(CloneModule,GlobalDebugInfo)917 TEST_F(CloneModule, GlobalDebugInfo) {
918 GlobalVariable *NewGV = NewM->getGlobalVariable("gv");
919 EXPECT_TRUE(NewGV != nullptr);
920
921 // Find debug info expression assigned to global
922 SmallVector<DIGlobalVariableExpression *, 1> GVs;
923 NewGV->getDebugInfo(GVs);
924 EXPECT_EQ(GVs.size(), 1U);
925
926 DIGlobalVariableExpression *GVExpr = GVs[0];
927 DIGlobalVariable *GV = GVExpr->getVariable();
928 EXPECT_TRUE(GV != nullptr);
929
930 EXPECT_EQ(GV->getName(), "gv");
931 EXPECT_EQ(GV->getLine(), 1U);
932
933 // Assert that the scope of the debug info attached to
934 // global variable matches the cloned function.
935 DISubprogram *SP = NewM->getFunction("f")->getSubprogram();
936 EXPECT_TRUE(SP != nullptr);
937 EXPECT_EQ(GV->getScope(), SP);
938 }
939
TEST_F(CloneModule,CompileUnit)940 TEST_F(CloneModule, CompileUnit) {
941 // Find DICompileUnit listed in llvm.dbg.cu
942 auto *NMD = NewM->getNamedMetadata("llvm.dbg.cu");
943 EXPECT_TRUE(NMD != nullptr);
944 EXPECT_EQ(NMD->getNumOperands(), 1U);
945
946 DICompileUnit *CU = dyn_cast<llvm::DICompileUnit>(NMD->getOperand(0));
947 EXPECT_TRUE(CU != nullptr);
948
949 // Assert this CU is consistent with the cloned function debug info
950 DISubprogram *SP = NewM->getFunction("f")->getSubprogram();
951 EXPECT_TRUE(SP != nullptr);
952 EXPECT_EQ(SP->getUnit(), CU);
953
954 // Check globals listed in CU have the correct scope
955 DIGlobalVariableExpressionArray GlobalArray = CU->getGlobalVariables();
956 EXPECT_EQ(GlobalArray.size(), 2U);
957 for (DIGlobalVariableExpression *GVExpr : GlobalArray) {
958 DIGlobalVariable *GV = GVExpr->getVariable();
959 EXPECT_EQ(GV->getScope(), SP);
960 }
961 }
962
TEST_F(CloneModule,Comdat)963 TEST_F(CloneModule, Comdat) {
964 GlobalVariable *NewGV = NewM->getGlobalVariable("gv");
965 auto *CD = NewGV->getComdat();
966 ASSERT_NE(nullptr, CD);
967 EXPECT_EQ("comdat", CD->getName());
968 EXPECT_EQ(Comdat::ExactMatch, CD->getSelectionKind());
969
970 Function *NewF = NewM->getFunction("f");
971 EXPECT_EQ(CD, NewF->getComdat());
972 }
973 }
974