diff --git a/llvm/lib/Transforms/Utils/CodeExtractor.cpp b/llvm/lib/Transforms/Utils/CodeExtractor.cpp --- a/llvm/lib/Transforms/Utils/CodeExtractor.cpp +++ b/llvm/lib/Transforms/Utils/CodeExtractor.cpp @@ -1588,17 +1588,20 @@ DebugIntrinsicsToDelete.push_back(DVI); continue; } - - // Point the intrinsic to a fresh variable within the new function. - DILocalVariable *OldVar = DVI->getVariable(); - DINode *&NewVar = RemappedMetadata[OldVar]; - if (!NewVar) - NewVar = DIB.createAutoVariable( - NewSP, OldVar->getName(), OldVar->getFile(), OldVar->getLine(), - OldVar->getType(), /*AlwaysPreserve=*/false, DINode::FlagZero, - OldVar->getAlignInBits()); - DVI->setVariable(cast(NewVar)); + // If the variable was in the scope of the old function, i.e. it was not + // inlined, point the intrinsic to a fresh variable within the new function. + if (!DVI->getDebugLoc().getInlinedAt()) { + DILocalVariable *OldVar = DVI->getVariable(); + DINode *&NewVar = RemappedMetadata[OldVar]; + if (!NewVar) + NewVar = DIB.createAutoVariable( + NewSP, OldVar->getName(), OldVar->getFile(), OldVar->getLine(), + OldVar->getType(), /*AlwaysPreserve=*/false, DINode::FlagZero, + OldVar->getAlignInBits()); + DVI->setVariable(cast(NewVar)); + } } + for (auto *DII : DebugIntrinsicsToDelete) DII->eraseFromParent(); DIB.finalizeSubprogram(NewSP); diff --git a/llvm/test/Transforms/HotColdSplit/transfer-debug-info.ll b/llvm/test/Transforms/HotColdSplit/transfer-debug-info.ll --- a/llvm/test/Transforms/HotColdSplit/transfer-debug-info.ll +++ b/llvm/test/Transforms/HotColdSplit/transfer-debug-info.ll @@ -31,6 +31,10 @@ ; CHECK-NEXT: call void @sink(i32 [[ADD1]]), !dbg [[LINE2:![0-9]+]] ; CHECK-NEXT: call void @sink(i32 [[ADD1]]), !dbg [[LINE3:![0-9]+]] +; CHECK-NEXT: call void @llvm.dbg.value(metadata i32 [[ADD1]] +; CHECK-SAME: metadata [[VAR_FROM_INLINE_ME:![0-9]+]] +; CHECK-SAME: !dbg [[LINE2]] + ; - The DISubprogram for @foo.cold.1 has an empty DISubroutineType ; CHECK: [[FILE:![0-9]+]] = !DIFile(filename: "" ; CHECK: [[EMPTY_MD:![0-9]+]] = !{} @@ -47,6 +51,9 @@ ; CHECK: [[INLINED_SCOPE1]] = !DILexicalBlock(scope: [[INLINED_SCOPE2:![0-9]*]], file: [[FILE]], line: 4, column: 4) ; CHECK: [[INLINED_SCOPE2]] = !DILexicalBlock(scope: [[NEWSCOPE]], file: [[FILE]], line: 5, column: 5) +; CHECK: [[VAR_FROM_INLINE_ME]] = !DILocalVariable(name: "var_from_inline_me", +; CHECK-SAME: scope: [[INLINE_ME_SCOPE]] + define void @foo(i32 %arg1) !dbg !6 { entry: %var = add i32 0, 0, !dbg !11 @@ -64,6 +71,7 @@ call void @llvm.dbg.value(metadata i32 %add1, metadata !9, metadata !DIExpression(DW_OP_constu, 1, DW_OP_plus, DW_OP_stack_value)), !dbg !11 call void @sink(i32 %add1), !dbg !13 ; inlined from @inline_me call void @sink(i32 %add1), !dbg !14 ; not inlined, but inside some scope of foo + call void @llvm.dbg.value(metadata i32 %add1, metadata !17, metadata !DIExpression()), !dbg !13 ; variable from @inline_me, should preserve scope in !17. ret void } @@ -96,3 +104,4 @@ !14 = !DILocation(line: 3, column: 3, scope: !15) !15 = distinct !DILexicalBlock(scope: !16, file: !1, line: 4, column: 4) !16 = distinct !DILexicalBlock(scope: !6, file: !1, line: 5, column: 5) +!17 = !DILocalVariable(name: "var_from_inline_me", scope: !12, file: !1, line: 1, type: !10)