Index: lib/Bitcode/Writer/BitcodeWriter.cpp =================================================================== --- lib/Bitcode/Writer/BitcodeWriter.cpp +++ lib/Bitcode/Writer/BitcodeWriter.cpp @@ -336,18 +336,33 @@ *ModuleToSummariesForIndex = nullptr) : BitcodeWriterBase(Stream), Index(Index), ModuleToSummariesForIndex(ModuleToSummariesForIndex) { - // Assign unique value ids to all summaries to be written, for use - // in writing out the call graph edges. Save the mapping from GUID + // Assign unique value ids to all unique GUID with summaries to be written, + // for use in writing out the call graph edges. Save the mapping from GUID // to the new global value id to use when writing those edges, which // are currently saved in the index in terms of GUID. - forEachSummary([&](GVInfo I) { - GUIDToValueIdMap[I.first] = ++GlobalValueId; + forEachGUID([&](GlobalValue::GUID GUID) { + GUIDToValueIdMap[GUID] = ++GlobalValueId; }); } /// The below iterator returns the GUID and associated summary. typedef std::pair GVInfo; + /// Calls the callback for each value GUID with a summary to be written to + /// bitcode. This hides the details of whether they are being pulled from the + /// entire index or just those in a provided ModuleToSummariesForIndex map. + void forEachGUID(std::function Callback) { + if (ModuleToSummariesForIndex) { + for (auto &M : *ModuleToSummariesForIndex) + for (auto &Summary : M.second) + Callback(Summary.first); + } else { + for (auto &Summaries : Index) + if (Summaries.second.SummaryList.size()) + Callback(Summaries.first); + } + } + /// Calls the callback for each value GUID and summary to be written to /// bitcode. This hides the details of whether they are being pulled from the /// entire index or just those in a provided ModuleToSummariesForIndex map. Index: test/Bitcode/Inputs/thinlto-function-summary-callgraph-linkonce.ll =================================================================== --- /dev/null +++ test/Bitcode/Inputs/thinlto-function-summary-callgraph-linkonce.ll @@ -0,0 +1,9 @@ +; ModuleID = 'thinlto-function-summary-callgraph-linkonce2.ll' +target datalayout = "e-m:e-i64:64-f80:128-n8:16:32:64-S128" +target triple = "x86_64-unknown-linux-gnu" + +; Function Attrs: nounwind uwtable +define linkonce_odr void @func() #0 { +entry: + ret void +} Index: test/Bitcode/thinlto-function-summary-callgraph-linkonce.ll =================================================================== --- /dev/null +++ test/Bitcode/thinlto-function-summary-callgraph-linkonce.ll @@ -0,0 +1,36 @@ +; Test to check for correct value numbering when there are multiple copies of a +; (linkonce) function. +; RUN: opt -module-summary %s -o %t.o +; RUN: opt -module-summary %p/Inputs/thinlto-function-summary-callgraph-linkonce.ll -o %t2.o +; RUN: llvm-lto -thinlto -o %t3 %t.o %t2.o +; RUN: llvm-bcanalyzer -dump %t3.thinlto.bc | FileCheck %s --check-prefix=COMBINED + +; COMBINED: +; main: +; COMBINED-NEXT: +; COMBINED-NEXT: + +; ModuleID = 'thinlto-function-summary-callgraph-linkonce.ll' +target datalayout = "e-m:e-i64:64-f80:128-n8:16:32:64-S128" +target triple = "x86_64-unknown-linux-gnu" + +; Function Attrs: nounwind uwtable +define linkonce_odr void @func() #0 { +entry: + ret void +} + +; Function Attrs: nounwind uwtable +define void @main() #0 { +entry: + call void () @func() + ret void +}