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