diff options
| -rw-r--r-- | llvm/lib/Transforms/Utils/CloneModule.cpp | 3 | ||||
| -rw-r--r-- | llvm/unittests/Transforms/Utils/Cloning.cpp | 59 | 
2 files changed, 61 insertions, 1 deletions
diff --git a/llvm/lib/Transforms/Utils/CloneModule.cpp b/llvm/lib/Transforms/Utils/CloneModule.cpp index d27cb45c7d7..e5392b53050 100644 --- a/llvm/lib/Transforms/Utils/CloneModule.cpp +++ b/llvm/lib/Transforms/Utils/CloneModule.cpp @@ -132,7 +132,8 @@ std::unique_ptr<Module> llvm::CloneModule(      SmallVector<std::pair<unsigned, MDNode *>, 1> MDs;      I->getAllMetadata(MDs);      for (auto MD : MDs) -      GV->addMetadata(MD.first, *MapMetadata(MD.second, VMap)); +      GV->addMetadata(MD.first, +                      *MapMetadata(MD.second, VMap, RF_MoveDistinctMDs));      copyComdat(GV, &*I);    } diff --git a/llvm/unittests/Transforms/Utils/Cloning.cpp b/llvm/unittests/Transforms/Utils/Cloning.cpp index 01ee9b841f8..fe4e2ba7e94 100644 --- a/llvm/unittests/Transforms/Utils/Cloning.cpp +++ b/llvm/unittests/Transforms/Utils/Cloning.cpp @@ -506,6 +506,19 @@ protected:                                  DINode::FlagZero, false);      F->setSubprogram(Subprogram); +    // Create and assign DIGlobalVariableExpression to gv +    auto GVExpression = DBuilder.createGlobalVariableExpression( +        Subprogram, "gv", "gv", File, 1, DBuilder.createNullPtrType(), false); +    GV->addDebugInfo(GVExpression); + +    // DIGlobalVariableExpression not attached to any global variable +    auto Expr = DBuilder.createExpression( +        ArrayRef<uint64_t>{dwarf::DW_OP_constu, 42U, dwarf::DW_OP_stack_value}); + +    DBuilder.createGlobalVariableExpression( +        Subprogram, "unattached", "unattached", File, 1, +        DBuilder.createNullPtrType(), false, Expr); +      auto *Entry = BasicBlock::Create(C, "", F);      IBuilder.SetInsertPoint(Entry);      IBuilder.CreateRetVoid(); @@ -545,6 +558,52 @@ TEST_F(CloneModule, GlobalMetadata) {    EXPECT_NE(nullptr, NewGV->getMetadata(LLVMContext::MD_type));  } +TEST_F(CloneModule, GlobalDebugInfo) { +  GlobalVariable *NewGV = NewM->getGlobalVariable("gv"); +  EXPECT_TRUE(NewGV != nullptr); + +  // Find debug info expression assigned to global +  SmallVector<DIGlobalVariableExpression *, 1> GVs; +  NewGV->getDebugInfo(GVs); +  EXPECT_EQ(GVs.size(), 1U); + +  DIGlobalVariableExpression *GVExpr = GVs[0]; +  DIGlobalVariable *GV = GVExpr->getVariable(); +  EXPECT_TRUE(GV != nullptr); + +  EXPECT_EQ(GV->getName(), "gv"); +  EXPECT_EQ(GV->getLine(), 1U); + +  // Assert that the scope of the debug info attached to +  // global variable matches the cloned function. +  DISubprogram *SP = NewM->getFunction("f")->getSubprogram(); +  EXPECT_TRUE(SP != nullptr); +  EXPECT_EQ(GV->getScope(), SP); +} + +TEST_F(CloneModule, CompileUnit) { +  // Find DICompileUnit listed in llvm.dbg.cu +  auto *NMD = NewM->getNamedMetadata("llvm.dbg.cu"); +  EXPECT_TRUE(NMD != nullptr); +  EXPECT_EQ(NMD->getNumOperands(), 1U); + +  DICompileUnit *CU = dyn_cast<llvm::DICompileUnit>(NMD->getOperand(0)); +  EXPECT_TRUE(CU != nullptr); + +  // Assert this CU is consistent with the cloned function debug info +  DISubprogram *SP = NewM->getFunction("f")->getSubprogram(); +  EXPECT_TRUE(SP != nullptr); +  EXPECT_EQ(SP->getUnit(), CU); + +  // Check globals listed in CU have the correct scope +  DIGlobalVariableExpressionArray GlobalArray = CU->getGlobalVariables(); +  EXPECT_EQ(GlobalArray.size(), 2U); +  for (DIGlobalVariableExpression *GVExpr : GlobalArray) { +    DIGlobalVariable *GV = GVExpr->getVariable(); +    EXPECT_EQ(GV->getScope(), SP); +  } +} +  TEST_F(CloneModule, Comdat) {    GlobalVariable *NewGV = NewM->getGlobalVariable("gv");    auto *CD = NewGV->getComdat();  | 

