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