Index: lib/IR/DebugInfo.cpp =================================================================== --- lib/IR/DebugInfo.cpp +++ lib/IR/DebugInfo.cpp @@ -79,9 +79,19 @@ processScope(M->getScope()); } } - for (auto &F : M.functions()) + for (auto &F : M.functions()) { if (auto *SP = cast_or_null(F.getSubprogram())) processSubprogram(SP); + // There could be subprograms from inlined functions referenced from + // instructions only. Walk the function to find them. + for (const BasicBlock &BB : F) { + for (const Instruction &I : BB) { + if (!I.getDebugLoc()) + continue; + processLocation(M, I.getDebugLoc().get()); + } + } + } } void DebugInfoFinder::processLocation(const Module &M, const DILocation *Loc) { Index: lib/Transforms/IPO/StripSymbols.cpp =================================================================== --- lib/Transforms/IPO/StripSymbols.cpp +++ lib/Transforms/IPO/StripSymbols.cpp @@ -324,10 +324,9 @@ } std::set LiveCUs; - // Any CU referenced from a function is live. - for (Function &F : M.functions()) { - DISubprogram *SP = F.getSubprogram(); - if (SP && SP->getUnit()) + // Any CU referenced from a subprogram is live. + for (DISubprogram *SP : F.subprograms()) { + if (SP->getUnit()) LiveCUs.insert(SP->getUnit()); } Index: test/Transforms/StripSymbols/strip-dead-debug-info.ll =================================================================== --- test/Transforms/StripSymbols/strip-dead-debug-info.ll +++ test/Transforms/StripSymbols/strip-dead-debug-info.ll @@ -24,7 +24,7 @@ define i32 @foo(i32 %i) #2 !dbg !15 { entry: tail call void @llvm.dbg.value(metadata i32 %i, i64 0, metadata !18, metadata !19), !dbg !20 - %.0 = load i32, i32* @xyz, align 4 + %.0 = load i32, i32* @xyz, align 4, !dbg !30 ret i32 %.0, !dbg !21 } @@ -32,7 +32,7 @@ attributes #1 = { nounwind readnone ssp } attributes #2 = { nounwind readonly ssp } -!llvm.dbg.cu = !{!4, !23, !24} +!llvm.dbg.cu = !{!4, !23, !24, !28} !llvm.module.flags = !{!9} !0 = !DIGlobalVariableExpression(var: !1) @@ -63,3 +63,6 @@ !25 = !{!26} !26 = !DIGlobalVariableExpression(var: !27, expr: !DIExpression(DW_OP_constu, 0, DW_OP_stack_value)) !27 = !DIGlobalVariable(name: "abcd2", scope: !2, file: !2, line: 2, type: !3, isLocal: true, isDefinition: true) +!28 = distinct !DICompileUnit(language: DW_LANG_C89, file: !2, producer: "InlineTest", isOptimized: true, runtimeVersion: 0, emissionKind: FullDebug, enums: !5, retainedTypes: !5, globals: !5) +!29 = distinct !DISubprogram(name: "inlinefunc", linkageName: "inlinefunc", scope: null, file: !2, line: 7, type: !16, isLocal: false, isDefinition: true, isOptimized: true, unit: !28) +!30 = !DILocation(line: 100, scope: !29, inlinedAt: !21)