1 //===- Cloning.cpp - Unit tests for the Cloner ----------------------------===//
2 //
3 // The LLVM Compiler Infrastructure
4 //
5 // This file is distributed under the University of Illinois Open Source
6 // License. See LICENSE.TXT for details.
7 //
8 //===----------------------------------------------------------------------===//
9
10 #include "llvm/Transforms/Utils/Cloning.h"
11 #include "llvm/ADT/STLExtras.h"
12 #include "llvm/ADT/SmallPtrSet.h"
13 #include "llvm/IR/Argument.h"
14 #include "llvm/IR/Constant.h"
15 #include "llvm/IR/DIBuilder.h"
16 #include "llvm/IR/DebugInfo.h"
17 #include "llvm/IR/Function.h"
18 #include "llvm/IR/IRBuilder.h"
19 #include "llvm/IR/InstIterator.h"
20 #include "llvm/IR/Instructions.h"
21 #include "llvm/IR/IntrinsicInst.h"
22 #include "llvm/IR/LLVMContext.h"
23 #include "llvm/IR/Module.h"
24 #include "llvm/IR/Verifier.h"
25 #include "gtest/gtest.h"
26
27 using namespace llvm;
28
29 namespace {
30
31 class CloneInstruction : public ::testing::Test {
32 protected:
SetUp()33 void SetUp() override { V = nullptr; }
34
35 template <typename T>
clone(T * V1)36 T *clone(T *V1) {
37 Value *V2 = V1->clone();
38 Orig.insert(V1);
39 Clones.insert(V2);
40 return cast<T>(V2);
41 }
42
eraseClones()43 void eraseClones() {
44 for (Value *V : Clones)
45 V->deleteValue();
46 Clones.clear();
47 }
48
TearDown()49 void TearDown() override {
50 eraseClones();
51 for (Value *V : Orig)
52 V->deleteValue();
53 Orig.clear();
54 if (V)
55 V->deleteValue();
56 }
57
58 SmallPtrSet<Value *, 4> Orig; // Erase on exit
59 SmallPtrSet<Value *, 4> Clones; // Erase in eraseClones
60
61 LLVMContext context;
62 Value *V;
63 };
64
TEST_F(CloneInstruction,OverflowBits)65 TEST_F(CloneInstruction, OverflowBits) {
66 V = new Argument(Type::getInt32Ty(context));
67
68 BinaryOperator *Add = BinaryOperator::Create(Instruction::Add, V, V);
69 BinaryOperator *Sub = BinaryOperator::Create(Instruction::Sub, V, V);
70 BinaryOperator *Mul = BinaryOperator::Create(Instruction::Mul, V, V);
71
72 BinaryOperator *AddClone = this->clone(Add);
73 BinaryOperator *SubClone = this->clone(Sub);
74 BinaryOperator *MulClone = this->clone(Mul);
75
76 EXPECT_FALSE(AddClone->hasNoUnsignedWrap());
77 EXPECT_FALSE(AddClone->hasNoSignedWrap());
78 EXPECT_FALSE(SubClone->hasNoUnsignedWrap());
79 EXPECT_FALSE(SubClone->hasNoSignedWrap());
80 EXPECT_FALSE(MulClone->hasNoUnsignedWrap());
81 EXPECT_FALSE(MulClone->hasNoSignedWrap());
82
83 eraseClones();
84
85 Add->setHasNoUnsignedWrap();
86 Sub->setHasNoUnsignedWrap();
87 Mul->setHasNoUnsignedWrap();
88
89 AddClone = this->clone(Add);
90 SubClone = this->clone(Sub);
91 MulClone = this->clone(Mul);
92
93 EXPECT_TRUE(AddClone->hasNoUnsignedWrap());
94 EXPECT_FALSE(AddClone->hasNoSignedWrap());
95 EXPECT_TRUE(SubClone->hasNoUnsignedWrap());
96 EXPECT_FALSE(SubClone->hasNoSignedWrap());
97 EXPECT_TRUE(MulClone->hasNoUnsignedWrap());
98 EXPECT_FALSE(MulClone->hasNoSignedWrap());
99
100 eraseClones();
101
102 Add->setHasNoSignedWrap();
103 Sub->setHasNoSignedWrap();
104 Mul->setHasNoSignedWrap();
105
106 AddClone = this->clone(Add);
107 SubClone = this->clone(Sub);
108 MulClone = this->clone(Mul);
109
110 EXPECT_TRUE(AddClone->hasNoUnsignedWrap());
111 EXPECT_TRUE(AddClone->hasNoSignedWrap());
112 EXPECT_TRUE(SubClone->hasNoUnsignedWrap());
113 EXPECT_TRUE(SubClone->hasNoSignedWrap());
114 EXPECT_TRUE(MulClone->hasNoUnsignedWrap());
115 EXPECT_TRUE(MulClone->hasNoSignedWrap());
116
117 eraseClones();
118
119 Add->setHasNoUnsignedWrap(false);
120 Sub->setHasNoUnsignedWrap(false);
121 Mul->setHasNoUnsignedWrap(false);
122
123 AddClone = this->clone(Add);
124 SubClone = this->clone(Sub);
125 MulClone = this->clone(Mul);
126
127 EXPECT_FALSE(AddClone->hasNoUnsignedWrap());
128 EXPECT_TRUE(AddClone->hasNoSignedWrap());
129 EXPECT_FALSE(SubClone->hasNoUnsignedWrap());
130 EXPECT_TRUE(SubClone->hasNoSignedWrap());
131 EXPECT_FALSE(MulClone->hasNoUnsignedWrap());
132 EXPECT_TRUE(MulClone->hasNoSignedWrap());
133 }
134
TEST_F(CloneInstruction,Inbounds)135 TEST_F(CloneInstruction, Inbounds) {
136 V = new Argument(Type::getInt32PtrTy(context));
137
138 Constant *Z = Constant::getNullValue(Type::getInt32Ty(context));
139 std::vector<Value *> ops;
140 ops.push_back(Z);
141 GetElementPtrInst *GEP =
142 GetElementPtrInst::Create(Type::getInt32Ty(context), V, ops);
143 EXPECT_FALSE(this->clone(GEP)->isInBounds());
144
145 GEP->setIsInBounds();
146 EXPECT_TRUE(this->clone(GEP)->isInBounds());
147 }
148
TEST_F(CloneInstruction,Exact)149 TEST_F(CloneInstruction, Exact) {
150 V = new Argument(Type::getInt32Ty(context));
151
152 BinaryOperator *SDiv = BinaryOperator::Create(Instruction::SDiv, V, V);
153 EXPECT_FALSE(this->clone(SDiv)->isExact());
154
155 SDiv->setIsExact(true);
156 EXPECT_TRUE(this->clone(SDiv)->isExact());
157 }
158
TEST_F(CloneInstruction,Attributes)159 TEST_F(CloneInstruction, Attributes) {
160 Type *ArgTy1[] = { Type::getInt32PtrTy(context) };
161 FunctionType *FT1 = FunctionType::get(Type::getVoidTy(context), ArgTy1, false);
162
163 Function *F1 = Function::Create(FT1, Function::ExternalLinkage);
164 BasicBlock *BB = BasicBlock::Create(context, "", F1);
165 IRBuilder<> Builder(BB);
166 Builder.CreateRetVoid();
167
168 Function *F2 = Function::Create(FT1, Function::ExternalLinkage);
169
170 Argument *A = &*F1->arg_begin();
171 A->addAttr(Attribute::NoCapture);
172
173 SmallVector<ReturnInst*, 4> Returns;
174 ValueToValueMapTy VMap;
175 VMap[A] = UndefValue::get(A->getType());
176
177 CloneFunctionInto(F2, F1, VMap, false, Returns);
178 EXPECT_FALSE(F2->arg_begin()->hasNoCaptureAttr());
179
180 delete F1;
181 delete F2;
182 }
183
TEST_F(CloneInstruction,CallingConvention)184 TEST_F(CloneInstruction, CallingConvention) {
185 Type *ArgTy1[] = { Type::getInt32PtrTy(context) };
186 FunctionType *FT1 = FunctionType::get(Type::getVoidTy(context), ArgTy1, false);
187
188 Function *F1 = Function::Create(FT1, Function::ExternalLinkage);
189 F1->setCallingConv(CallingConv::Cold);
190 BasicBlock *BB = BasicBlock::Create(context, "", F1);
191 IRBuilder<> Builder(BB);
192 Builder.CreateRetVoid();
193
194 Function *F2 = Function::Create(FT1, Function::ExternalLinkage);
195
196 SmallVector<ReturnInst*, 4> Returns;
197 ValueToValueMapTy VMap;
198 VMap[&*F1->arg_begin()] = &*F2->arg_begin();
199
200 CloneFunctionInto(F2, F1, VMap, false, Returns);
201 EXPECT_EQ(CallingConv::Cold, F2->getCallingConv());
202
203 delete F1;
204 delete F2;
205 }
206
TEST_F(CloneInstruction,DuplicateInstructionsToSplit)207 TEST_F(CloneInstruction, DuplicateInstructionsToSplit) {
208 Type *ArgTy1[] = {Type::getInt32PtrTy(context)};
209 FunctionType *FT = FunctionType::get(Type::getVoidTy(context), ArgTy1, false);
210 V = new Argument(Type::getInt32Ty(context));
211
212 Function *F = Function::Create(FT, Function::ExternalLinkage);
213
214 BasicBlock *BB1 = BasicBlock::Create(context, "", F);
215 IRBuilder<> Builder1(BB1);
216
217 BasicBlock *BB2 = BasicBlock::Create(context, "", F);
218 IRBuilder<> Builder2(BB2);
219
220 Builder1.CreateBr(BB2);
221
222 Instruction *AddInst = cast<Instruction>(Builder2.CreateAdd(V, V));
223 Instruction *MulInst = cast<Instruction>(Builder2.CreateMul(AddInst, V));
224 Instruction *SubInst = cast<Instruction>(Builder2.CreateSub(MulInst, V));
225 Builder2.CreateRetVoid();
226
227 ValueToValueMapTy Mapping;
228
229 auto Split = DuplicateInstructionsInSplitBetween(BB2, BB1, SubInst, Mapping);
230
231 EXPECT_TRUE(Split);
232 EXPECT_EQ(Mapping.size(), 2u);
233 EXPECT_TRUE(Mapping.find(AddInst) != Mapping.end());
234 EXPECT_TRUE(Mapping.find(MulInst) != Mapping.end());
235
236 auto AddSplit = dyn_cast<Instruction>(Mapping[AddInst]);
237 EXPECT_TRUE(AddSplit);
238 EXPECT_EQ(AddSplit->getOperand(0), V);
239 EXPECT_EQ(AddSplit->getOperand(1), V);
240 EXPECT_EQ(AddSplit->getParent(), Split);
241
242 auto MulSplit = dyn_cast<Instruction>(Mapping[MulInst]);
243 EXPECT_TRUE(MulSplit);
244 EXPECT_EQ(MulSplit->getOperand(0), AddSplit);
245 EXPECT_EQ(MulSplit->getOperand(1), V);
246 EXPECT_EQ(MulSplit->getParent(), Split);
247
248 EXPECT_EQ(AddSplit->getNextNode(), MulSplit);
249 EXPECT_EQ(MulSplit->getNextNode(), Split->getTerminator());
250
251 delete F;
252 }
253
TEST_F(CloneInstruction,DuplicateInstructionsToSplitBlocksEq1)254 TEST_F(CloneInstruction, DuplicateInstructionsToSplitBlocksEq1) {
255 Type *ArgTy1[] = {Type::getInt32PtrTy(context)};
256 FunctionType *FT = FunctionType::get(Type::getVoidTy(context), ArgTy1, false);
257 V = new Argument(Type::getInt32Ty(context));
258
259 Function *F = Function::Create(FT, Function::ExternalLinkage);
260
261 BasicBlock *BB1 = BasicBlock::Create(context, "", F);
262 IRBuilder<> Builder1(BB1);
263
264 BasicBlock *BB2 = BasicBlock::Create(context, "", F);
265 IRBuilder<> Builder2(BB2);
266
267 Builder1.CreateBr(BB2);
268
269 Instruction *AddInst = cast<Instruction>(Builder2.CreateAdd(V, V));
270 Instruction *MulInst = cast<Instruction>(Builder2.CreateMul(AddInst, V));
271 Instruction *SubInst = cast<Instruction>(Builder2.CreateSub(MulInst, V));
272 Builder2.CreateBr(BB2);
273
274 ValueToValueMapTy Mapping;
275
276 auto Split = DuplicateInstructionsInSplitBetween(BB2, BB2, BB2->getTerminator(), Mapping);
277
278 EXPECT_TRUE(Split);
279 EXPECT_EQ(Mapping.size(), 3u);
280 EXPECT_TRUE(Mapping.find(AddInst) != Mapping.end());
281 EXPECT_TRUE(Mapping.find(MulInst) != Mapping.end());
282 EXPECT_TRUE(Mapping.find(SubInst) != Mapping.end());
283
284 auto AddSplit = dyn_cast<Instruction>(Mapping[AddInst]);
285 EXPECT_TRUE(AddSplit);
286 EXPECT_EQ(AddSplit->getOperand(0), V);
287 EXPECT_EQ(AddSplit->getOperand(1), V);
288 EXPECT_EQ(AddSplit->getParent(), Split);
289
290 auto MulSplit = dyn_cast<Instruction>(Mapping[MulInst]);
291 EXPECT_TRUE(MulSplit);
292 EXPECT_EQ(MulSplit->getOperand(0), AddSplit);
293 EXPECT_EQ(MulSplit->getOperand(1), V);
294 EXPECT_EQ(MulSplit->getParent(), Split);
295
296 auto SubSplit = dyn_cast<Instruction>(Mapping[SubInst]);
297 EXPECT_EQ(MulSplit->getNextNode(), SubSplit);
298 EXPECT_EQ(SubSplit->getNextNode(), Split->getTerminator());
299 EXPECT_EQ(Split->getSingleSuccessor(), BB2);
300 EXPECT_EQ(BB2->getSingleSuccessor(), Split);
301
302 delete F;
303 }
304
TEST_F(CloneInstruction,DuplicateInstructionsToSplitBlocksEq2)305 TEST_F(CloneInstruction, DuplicateInstructionsToSplitBlocksEq2) {
306 Type *ArgTy1[] = {Type::getInt32PtrTy(context)};
307 FunctionType *FT = FunctionType::get(Type::getVoidTy(context), ArgTy1, false);
308 V = new Argument(Type::getInt32Ty(context));
309
310 Function *F = Function::Create(FT, Function::ExternalLinkage);
311
312 BasicBlock *BB1 = BasicBlock::Create(context, "", F);
313 IRBuilder<> Builder1(BB1);
314
315 BasicBlock *BB2 = BasicBlock::Create(context, "", F);
316 IRBuilder<> Builder2(BB2);
317
318 Builder1.CreateBr(BB2);
319
320 Instruction *AddInst = cast<Instruction>(Builder2.CreateAdd(V, V));
321 Instruction *MulInst = cast<Instruction>(Builder2.CreateMul(AddInst, V));
322 Instruction *SubInst = cast<Instruction>(Builder2.CreateSub(MulInst, V));
323 Builder2.CreateBr(BB2);
324
325 ValueToValueMapTy Mapping;
326
327 auto Split = DuplicateInstructionsInSplitBetween(BB2, BB2, SubInst, Mapping);
328
329 EXPECT_TRUE(Split);
330 EXPECT_EQ(Mapping.size(), 2u);
331 EXPECT_TRUE(Mapping.find(AddInst) != Mapping.end());
332 EXPECT_TRUE(Mapping.find(MulInst) != Mapping.end());
333
334 auto AddSplit = dyn_cast<Instruction>(Mapping[AddInst]);
335 EXPECT_TRUE(AddSplit);
336 EXPECT_EQ(AddSplit->getOperand(0), V);
337 EXPECT_EQ(AddSplit->getOperand(1), V);
338 EXPECT_EQ(AddSplit->getParent(), Split);
339
340 auto MulSplit = dyn_cast<Instruction>(Mapping[MulInst]);
341 EXPECT_TRUE(MulSplit);
342 EXPECT_EQ(MulSplit->getOperand(0), AddSplit);
343 EXPECT_EQ(MulSplit->getOperand(1), V);
344 EXPECT_EQ(MulSplit->getParent(), Split);
345 EXPECT_EQ(MulSplit->getNextNode(), Split->getTerminator());
346 EXPECT_EQ(Split->getSingleSuccessor(), BB2);
347 EXPECT_EQ(BB2->getSingleSuccessor(), Split);
348
349 delete F;
350 }
351
352 class CloneFunc : public ::testing::Test {
353 protected:
SetUp()354 void SetUp() override {
355 SetupModule();
356 CreateOldFunc();
357 CreateNewFunc();
358 SetupFinder();
359 }
360
TearDown()361 void TearDown() override { delete Finder; }
362
SetupModule()363 void SetupModule() {
364 M = new Module("", C);
365 }
366
CreateOldFunc()367 void CreateOldFunc() {
368 FunctionType* FuncType = FunctionType::get(Type::getVoidTy(C), false);
369 OldFunc = Function::Create(FuncType, GlobalValue::PrivateLinkage, "f", M);
370 CreateOldFunctionBodyAndDI();
371 }
372
CreateOldFunctionBodyAndDI()373 void CreateOldFunctionBodyAndDI() {
374 DIBuilder DBuilder(*M);
375 IRBuilder<> IBuilder(C);
376
377 // Function DI
378 auto *File = DBuilder.createFile("filename.c", "/file/dir/");
379 DITypeRefArray ParamTypes = DBuilder.getOrCreateTypeArray(None);
380 DISubroutineType *FuncType =
381 DBuilder.createSubroutineType(ParamTypes);
382 auto *CU = DBuilder.createCompileUnit(dwarf::DW_LANG_C99,
383 DBuilder.createFile("filename.c",
384 "/file/dir"),
385 "CloneFunc", false, "", 0);
386
387 auto *Subprogram =
388 DBuilder.createFunction(CU, "f", "f", File, 4, FuncType, true, true, 3,
389 DINode::FlagZero, false);
390 OldFunc->setSubprogram(Subprogram);
391
392 // Function body
393 BasicBlock* Entry = BasicBlock::Create(C, "", OldFunc);
394 IBuilder.SetInsertPoint(Entry);
395 DebugLoc Loc = DebugLoc::get(3, 2, Subprogram);
396 IBuilder.SetCurrentDebugLocation(Loc);
397 AllocaInst* Alloca = IBuilder.CreateAlloca(IntegerType::getInt32Ty(C));
398 IBuilder.SetCurrentDebugLocation(DebugLoc::get(4, 2, Subprogram));
399 Value* AllocaContent = IBuilder.getInt32(1);
400 Instruction* Store = IBuilder.CreateStore(AllocaContent, Alloca);
401 IBuilder.SetCurrentDebugLocation(DebugLoc::get(5, 2, Subprogram));
402
403 // Create a local variable around the alloca
404 auto *IntType = DBuilder.createBasicType("int", 32, dwarf::DW_ATE_signed);
405 auto *E = DBuilder.createExpression();
406 auto *Variable =
407 DBuilder.createAutoVariable(Subprogram, "x", File, 5, IntType, true);
408 auto *DL = DILocation::get(Subprogram->getContext(), 5, 0, Subprogram);
409 DBuilder.insertDeclare(Alloca, Variable, E, DL, Store);
410 DBuilder.insertDbgValueIntrinsic(AllocaContent, Variable, E, DL, Entry);
411 // Also create an inlined variable.
412 // Create a distinct struct type that we should not duplicate during
413 // cloning).
414 auto *StructType = DICompositeType::getDistinct(
415 C, dwarf::DW_TAG_structure_type, "some_struct", nullptr, 0, nullptr,
416 nullptr, 32, 32, 0, DINode::FlagZero, nullptr, 0, nullptr, nullptr);
417 auto *InlinedSP =
418 DBuilder.createFunction(CU, "inlined", "inlined", File, 8, FuncType,
419 true, true, 9, DINode::FlagZero, false);
420 auto *InlinedVar =
421 DBuilder.createAutoVariable(InlinedSP, "inlined", File, 5, StructType, true);
422 auto *Scope = DBuilder.createLexicalBlock(
423 DBuilder.createLexicalBlockFile(InlinedSP, File), File, 1, 1);
424 auto InlinedDL =
425 DebugLoc::get(9, 4, Scope, DebugLoc::get(5, 2, Subprogram));
426 IBuilder.SetCurrentDebugLocation(InlinedDL);
427 DBuilder.insertDeclare(Alloca, InlinedVar, E, InlinedDL, Store);
428 IBuilder.CreateStore(IBuilder.getInt32(2), Alloca);
429 // Finalize the debug info.
430 DBuilder.finalize();
431 IBuilder.CreateRetVoid();
432
433 // Create another, empty, compile unit.
434 DIBuilder DBuilder2(*M);
435 DBuilder2.createCompileUnit(dwarf::DW_LANG_C99,
436 DBuilder.createFile("extra.c", "/file/dir"),
437 "CloneFunc", false, "", 0);
438 DBuilder2.finalize();
439 }
440
CreateNewFunc()441 void CreateNewFunc() {
442 ValueToValueMapTy VMap;
443 NewFunc = CloneFunction(OldFunc, VMap, nullptr);
444 }
445
SetupFinder()446 void SetupFinder() {
447 Finder = new DebugInfoFinder();
448 Finder->processModule(*M);
449 }
450
451 LLVMContext C;
452 Function* OldFunc;
453 Function* NewFunc;
454 Module* M;
455 DebugInfoFinder* Finder;
456 };
457
458 // Test that a new, distinct function was created.
TEST_F(CloneFunc,NewFunctionCreated)459 TEST_F(CloneFunc, NewFunctionCreated) {
460 EXPECT_NE(OldFunc, NewFunc);
461 }
462
463 // Test that a new subprogram entry was added and is pointing to the new
464 // function, while the original subprogram still points to the old one.
TEST_F(CloneFunc,Subprogram)465 TEST_F(CloneFunc, Subprogram) {
466 EXPECT_FALSE(verifyModule(*M, &errs()));
467 EXPECT_EQ(3U, Finder->subprogram_count());
468 EXPECT_NE(NewFunc->getSubprogram(), OldFunc->getSubprogram());
469 }
470
471 // Test that instructions in the old function still belong to it in the
472 // metadata, while instruction in the new function belong to the new one.
TEST_F(CloneFunc,InstructionOwnership)473 TEST_F(CloneFunc, InstructionOwnership) {
474 EXPECT_FALSE(verifyModule(*M));
475
476 inst_iterator OldIter = inst_begin(OldFunc);
477 inst_iterator OldEnd = inst_end(OldFunc);
478 inst_iterator NewIter = inst_begin(NewFunc);
479 inst_iterator NewEnd = inst_end(NewFunc);
480 while (OldIter != OldEnd && NewIter != NewEnd) {
481 Instruction& OldI = *OldIter;
482 Instruction& NewI = *NewIter;
483 EXPECT_NE(&OldI, &NewI);
484
485 EXPECT_EQ(OldI.hasMetadata(), NewI.hasMetadata());
486 if (OldI.hasMetadata()) {
487 const DebugLoc& OldDL = OldI.getDebugLoc();
488 const DebugLoc& NewDL = NewI.getDebugLoc();
489
490 // Verify that the debug location data is the same
491 EXPECT_EQ(OldDL.getLine(), NewDL.getLine());
492 EXPECT_EQ(OldDL.getCol(), NewDL.getCol());
493
494 // But that they belong to different functions
495 auto *OldSubprogram = cast<DISubprogram>(OldDL.getInlinedAtScope());
496 auto *NewSubprogram = cast<DISubprogram>(NewDL.getInlinedAtScope());
497 EXPECT_EQ(OldFunc->getSubprogram(), OldSubprogram);
498 EXPECT_EQ(NewFunc->getSubprogram(), NewSubprogram);
499 }
500
501 ++OldIter;
502 ++NewIter;
503 }
504 EXPECT_EQ(OldEnd, OldIter);
505 EXPECT_EQ(NewEnd, NewIter);
506 }
507
508 // Test that the arguments for debug intrinsics in the new function were
509 // properly cloned
TEST_F(CloneFunc,DebugIntrinsics)510 TEST_F(CloneFunc, DebugIntrinsics) {
511 EXPECT_FALSE(verifyModule(*M));
512
513 inst_iterator OldIter = inst_begin(OldFunc);
514 inst_iterator OldEnd = inst_end(OldFunc);
515 inst_iterator NewIter = inst_begin(NewFunc);
516 inst_iterator NewEnd = inst_end(NewFunc);
517 while (OldIter != OldEnd && NewIter != NewEnd) {
518 Instruction& OldI = *OldIter;
519 Instruction& NewI = *NewIter;
520 if (DbgDeclareInst* OldIntrin = dyn_cast<DbgDeclareInst>(&OldI)) {
521 DbgDeclareInst* NewIntrin = dyn_cast<DbgDeclareInst>(&NewI);
522 EXPECT_TRUE(NewIntrin);
523
524 // Old address must belong to the old function
525 EXPECT_EQ(OldFunc, cast<AllocaInst>(OldIntrin->getAddress())->
526 getParent()->getParent());
527 // New address must belong to the new function
528 EXPECT_EQ(NewFunc, cast<AllocaInst>(NewIntrin->getAddress())->
529 getParent()->getParent());
530
531 if (OldIntrin->getDebugLoc()->getInlinedAt()) {
532 // Inlined variable should refer to the same DILocalVariable as in the
533 // Old Function
534 EXPECT_EQ(OldIntrin->getVariable(), NewIntrin->getVariable());
535 } else {
536 // Old variable must belong to the old function.
537 EXPECT_EQ(OldFunc->getSubprogram(),
538 cast<DISubprogram>(OldIntrin->getVariable()->getScope()));
539 // New variable must belong to the new function.
540 EXPECT_EQ(NewFunc->getSubprogram(),
541 cast<DISubprogram>(NewIntrin->getVariable()->getScope()));
542 }
543 } else if (DbgValueInst* OldIntrin = dyn_cast<DbgValueInst>(&OldI)) {
544 DbgValueInst* NewIntrin = dyn_cast<DbgValueInst>(&NewI);
545 EXPECT_TRUE(NewIntrin);
546
547 if (!OldIntrin->getDebugLoc()->getInlinedAt()) {
548 // Old variable must belong to the old function.
549 EXPECT_EQ(OldFunc->getSubprogram(),
550 cast<DISubprogram>(OldIntrin->getVariable()->getScope()));
551 // New variable must belong to the new function.
552 EXPECT_EQ(NewFunc->getSubprogram(),
553 cast<DISubprogram>(NewIntrin->getVariable()->getScope()));
554 }
555 }
556
557 ++OldIter;
558 ++NewIter;
559 }
560 }
561
562 class CloneModule : public ::testing::Test {
563 protected:
SetUp()564 void SetUp() override {
565 SetupModule();
566 CreateOldModule();
567 CreateNewModule();
568 }
569
SetupModule()570 void SetupModule() { OldM = new Module("", C); }
571
CreateOldModule()572 void CreateOldModule() {
573 auto *CD = OldM->getOrInsertComdat("comdat");
574 CD->setSelectionKind(Comdat::ExactMatch);
575
576 auto GV = new GlobalVariable(
577 *OldM, Type::getInt32Ty(C), false, GlobalValue::ExternalLinkage,
578 ConstantInt::get(Type::getInt32Ty(C), 1), "gv");
579 GV->addMetadata(LLVMContext::MD_type, *MDNode::get(C, {}));
580 GV->setComdat(CD);
581
582 DIBuilder DBuilder(*OldM);
583 IRBuilder<> IBuilder(C);
584
585 auto *FuncType = FunctionType::get(Type::getVoidTy(C), false);
586 auto *PersFn = Function::Create(FuncType, GlobalValue::ExternalLinkage,
587 "persfn", OldM);
588 auto *F =
589 Function::Create(FuncType, GlobalValue::PrivateLinkage, "f", OldM);
590 F->setPersonalityFn(PersFn);
591 F->setComdat(CD);
592
593 // Create debug info
594 auto *File = DBuilder.createFile("filename.c", "/file/dir/");
595 DITypeRefArray ParamTypes = DBuilder.getOrCreateTypeArray(None);
596 DISubroutineType *DFuncType = DBuilder.createSubroutineType(ParamTypes);
597 auto *CU = DBuilder.createCompileUnit(dwarf::DW_LANG_C99,
598 DBuilder.createFile("filename.c",
599 "/file/dir"),
600 "CloneModule", false, "", 0);
601 // Function DI
602 auto *Subprogram =
603 DBuilder.createFunction(CU, "f", "f", File, 4, DFuncType, true, true, 3,
604 DINode::FlagZero, false);
605 F->setSubprogram(Subprogram);
606
607 // Create and assign DIGlobalVariableExpression to gv
608 auto GVExpression = DBuilder.createGlobalVariableExpression(
609 Subprogram, "gv", "gv", File, 1, DBuilder.createNullPtrType(), false);
610 GV->addDebugInfo(GVExpression);
611
612 // DIGlobalVariableExpression not attached to any global variable
613 auto Expr = DBuilder.createExpression(
614 ArrayRef<uint64_t>{dwarf::DW_OP_constu, 42U, dwarf::DW_OP_stack_value});
615
616 DBuilder.createGlobalVariableExpression(
617 Subprogram, "unattached", "unattached", File, 1,
618 DBuilder.createNullPtrType(), false, Expr);
619
620 auto *Entry = BasicBlock::Create(C, "", F);
621 IBuilder.SetInsertPoint(Entry);
622 IBuilder.CreateRetVoid();
623
624 // Finalize the debug info
625 DBuilder.finalize();
626 }
627
CreateNewModule()628 void CreateNewModule() { NewM = llvm::CloneModule(*OldM).release(); }
629
630 LLVMContext C;
631 Module *OldM;
632 Module *NewM;
633 };
634
TEST_F(CloneModule,Verify)635 TEST_F(CloneModule, Verify) {
636 EXPECT_FALSE(verifyModule(*NewM));
637 }
638
TEST_F(CloneModule,OldModuleUnchanged)639 TEST_F(CloneModule, OldModuleUnchanged) {
640 DebugInfoFinder Finder;
641 Finder.processModule(*OldM);
642 EXPECT_EQ(1U, Finder.subprogram_count());
643 }
644
TEST_F(CloneModule,Subprogram)645 TEST_F(CloneModule, Subprogram) {
646 Function *NewF = NewM->getFunction("f");
647 DISubprogram *SP = NewF->getSubprogram();
648 EXPECT_TRUE(SP != nullptr);
649 EXPECT_EQ(SP->getName(), "f");
650 EXPECT_EQ(SP->getFile()->getFilename(), "filename.c");
651 EXPECT_EQ(SP->getLine(), (unsigned)4);
652 }
653
TEST_F(CloneModule,GlobalMetadata)654 TEST_F(CloneModule, GlobalMetadata) {
655 GlobalVariable *NewGV = NewM->getGlobalVariable("gv");
656 EXPECT_NE(nullptr, NewGV->getMetadata(LLVMContext::MD_type));
657 }
658
TEST_F(CloneModule,GlobalDebugInfo)659 TEST_F(CloneModule, GlobalDebugInfo) {
660 GlobalVariable *NewGV = NewM->getGlobalVariable("gv");
661 EXPECT_TRUE(NewGV != nullptr);
662
663 // Find debug info expression assigned to global
664 SmallVector<DIGlobalVariableExpression *, 1> GVs;
665 NewGV->getDebugInfo(GVs);
666 EXPECT_EQ(GVs.size(), 1U);
667
668 DIGlobalVariableExpression *GVExpr = GVs[0];
669 DIGlobalVariable *GV = GVExpr->getVariable();
670 EXPECT_TRUE(GV != nullptr);
671
672 EXPECT_EQ(GV->getName(), "gv");
673 EXPECT_EQ(GV->getLine(), 1U);
674
675 // Assert that the scope of the debug info attached to
676 // global variable matches the cloned function.
677 DISubprogram *SP = NewM->getFunction("f")->getSubprogram();
678 EXPECT_TRUE(SP != nullptr);
679 EXPECT_EQ(GV->getScope(), SP);
680 }
681
TEST_F(CloneModule,CompileUnit)682 TEST_F(CloneModule, CompileUnit) {
683 // Find DICompileUnit listed in llvm.dbg.cu
684 auto *NMD = NewM->getNamedMetadata("llvm.dbg.cu");
685 EXPECT_TRUE(NMD != nullptr);
686 EXPECT_EQ(NMD->getNumOperands(), 1U);
687
688 DICompileUnit *CU = dyn_cast<llvm::DICompileUnit>(NMD->getOperand(0));
689 EXPECT_TRUE(CU != nullptr);
690
691 // Assert this CU is consistent with the cloned function debug info
692 DISubprogram *SP = NewM->getFunction("f")->getSubprogram();
693 EXPECT_TRUE(SP != nullptr);
694 EXPECT_EQ(SP->getUnit(), CU);
695
696 // Check globals listed in CU have the correct scope
697 DIGlobalVariableExpressionArray GlobalArray = CU->getGlobalVariables();
698 EXPECT_EQ(GlobalArray.size(), 2U);
699 for (DIGlobalVariableExpression *GVExpr : GlobalArray) {
700 DIGlobalVariable *GV = GVExpr->getVariable();
701 EXPECT_EQ(GV->getScope(), SP);
702 }
703 }
704
TEST_F(CloneModule,Comdat)705 TEST_F(CloneModule, Comdat) {
706 GlobalVariable *NewGV = NewM->getGlobalVariable("gv");
707 auto *CD = NewGV->getComdat();
708 ASSERT_NE(nullptr, CD);
709 EXPECT_EQ("comdat", CD->getName());
710 EXPECT_EQ(Comdat::ExactMatch, CD->getSelectionKind());
711
712 Function *NewF = NewM->getFunction("f");
713 EXPECT_EQ(CD, NewF->getComdat());
714 }
715 }
716