Index: llvm/trunk/lib/Transforms/Utils/CloneFunction.cpp =================================================================== --- llvm/trunk/lib/Transforms/Utils/CloneFunction.cpp +++ llvm/trunk/lib/Transforms/Utils/CloneFunction.cpp @@ -46,13 +46,21 @@ if (BB->hasName()) NewBB->setName(BB->getName()+NameSuffix); bool hasCalls = false, hasDynamicAllocas = false, hasStaticAllocas = false; - + Module *TheModule = F ? F->getParent() : nullptr; + // Loop over all instructions, and copy them over. for (BasicBlock::const_iterator II = BB->begin(), IE = BB->end(); II != IE; ++II) { - if (DIFinder && F->getParent() && II->getDebugLoc()) - DIFinder->processLocation(*F->getParent(), II->getDebugLoc().get()); + if (DIFinder && TheModule) { + if (auto *DDI = dyn_cast(II)) + DIFinder->processDeclare(*TheModule, DDI); + else if (auto *DVI = dyn_cast(II)) + DIFinder->processValue(*TheModule, DVI); + + if (auto DbgLoc = II->getDebugLoc()) + DIFinder->processLocation(*TheModule, DbgLoc.get()); + } Instruction *NewInst = II->clone(); if (II->hasName()) @@ -153,6 +161,8 @@ // When we remap instructions, we want to avoid duplicating inlined // DISubprograms, so record all subprograms we find as we duplicate // instructions and then freeze them in the MD map. + // We also record information about dbg.value and dbg.declare to avoid + // duplicating the types. DebugInfoFinder DIFinder; // Loop over all of the basic blocks in the function, cloning them as @@ -193,6 +203,10 @@ } } + for (auto *Type : DIFinder.types()) { + VMap.MD()[Type].reset(Type); + } + // Loop over all of the instructions in the function, fixing up operand // references as we go. This uses VMap to do all the hard work. for (Function::iterator BB = Index: llvm/trunk/unittests/Transforms/Utils/Cloning.cpp =================================================================== --- llvm/trunk/unittests/Transforms/Utils/Cloning.cpp +++ llvm/trunk/unittests/Transforms/Utils/Cloning.cpp @@ -312,11 +312,16 @@ DBuilder.insertDbgValueIntrinsic(AllocaContent, 0, Variable, E, DL, Entry); // Also create an inlined variable. + // Create a distinct struct type that we should not duplicate during + // cloning). + auto *StructType = DICompositeType::getDistinct( + C, dwarf::DW_TAG_structure_type, "some_struct", nullptr, 0, nullptr, + nullptr, 32, 32, 0, DINode::FlagZero, nullptr, 0, nullptr, nullptr); auto *InlinedSP = DBuilder.createFunction(CU, "inlined", "inlined", File, 8, FuncType, true, true, 9, DINode::FlagZero, false); auto *InlinedVar = - DBuilder.createAutoVariable(InlinedSP, "inlined", File, 5, IntType, true); + DBuilder.createAutoVariable(InlinedSP, "inlined", File, 5, StructType, true); auto *Scope = DBuilder.createLexicalBlock( DBuilder.createLexicalBlockFile(InlinedSP, File), File, 1, 1); auto InlinedDL = @@ -426,7 +431,11 @@ EXPECT_EQ(NewFunc, cast(NewIntrin->getAddress())-> getParent()->getParent()); - if (!OldIntrin->getDebugLoc()->getInlinedAt()) { + if (OldIntrin->getDebugLoc()->getInlinedAt()) { + // Inlined variable should refer to the same DILocalVariable as in the + // Old Function + EXPECT_EQ(OldIntrin->getVariable(), NewIntrin->getVariable()); + } else { // Old variable must belong to the old function. EXPECT_EQ(OldFunc->getSubprogram(), cast(OldIntrin->getVariable()->getScope()));