Index: include/llvm/IR/ModuleSummaryIndex.h =================================================================== --- include/llvm/IR/ModuleSummaryIndex.h +++ include/llvm/IR/ModuleSummaryIndex.h @@ -104,11 +104,21 @@ /// Indicate if the global value is located in a specific section. unsigned HasSection : 1; + /// Indicate if the function is variadic. Inliner doesn't inline variadic + /// functions, so it doesn't make sense to import it. + unsigned IsVariadicFunction : 1; + /// Convenience Constructors - explicit GVFlags(GlobalValue::LinkageTypes Linkage, bool HasSection) - : Linkage(Linkage), HasSection(HasSection) {} + explicit GVFlags(GlobalValue::LinkageTypes Linkage, bool HasSection, + bool IsVariadicFunction) + : Linkage(Linkage), HasSection(HasSection), + IsVariadicFunction(IsVariadicFunction) {} GVFlags(const GlobalValue &GV) - : Linkage(GV.getLinkage()), HasSection(GV.hasSection()) {} + : Linkage(GV.getLinkage()), HasSection(GV.hasSection()) { + IsVariadicFunction = 0; + if (const auto *F = dyn_cast(&GV)) + IsVariadicFunction = F->isVarArg(); + } }; private: @@ -197,6 +207,10 @@ addRefEdge(RI); } + bool isVariadicFunction() const { + return Flags.IsVariadicFunction; + } + /// Return the list of values referenced by this global value definition. std::vector &refs() { return RefEdgeList; } const std::vector &refs() const { return RefEdgeList; } Index: lib/Bitcode/Reader/BitcodeReader.cpp =================================================================== --- lib/Bitcode/Reader/BitcodeReader.cpp +++ lib/Bitcode/Reader/BitcodeReader.cpp @@ -720,7 +720,8 @@ } } -// Decode the flags for GlobalValue in the summary +/// Decode the flags for GlobalValue in the summary +/// FIXME: remove Version because it is not used. static GlobalValueSummary::GVFlags getDecodedGVSummaryFlags(uint64_t RawFlags, uint64_t Version) { // Summary were not emitted before LLVM 3.9, we don't need to upgrade Linkage @@ -728,8 +729,9 @@ // to getDecodedLinkage() will need to be taken into account here as above. auto Linkage = GlobalValue::LinkageTypes(RawFlags & 0xF); // 4 bits RawFlags = RawFlags >> 4; - auto HasSection = RawFlags & 0x1; // bool - return GlobalValueSummary::GVFlags(Linkage, HasSection); + bool HasSection = RawFlags & 0x1; + bool IsVariadicFunction = RawFlags & 0x2; + return GlobalValueSummary::GVFlags(Linkage, HasSection, IsVariadicFunction); } static GlobalValue::VisibilityTypes getDecodedVisibility(unsigned Val) { Index: lib/Bitcode/Writer/BitcodeWriter.cpp =================================================================== --- lib/Bitcode/Writer/BitcodeWriter.cpp +++ lib/Bitcode/Writer/BitcodeWriter.cpp @@ -991,7 +991,7 @@ uint64_t RawFlags = 0; RawFlags |= Flags.HasSection; // bool - + RawFlags |= (Flags.IsVariadicFunction << 1); // Linkage don't need to be remapped at that time for the summary. Any future // change to the getEncodedLinkage() function will need to be taken into // account here as well. Index: lib/Transforms/IPO/FunctionImport.cpp =================================================================== --- lib/Transforms/IPO/FunctionImport.cpp +++ lib/Transforms/IPO/FunctionImport.cpp @@ -130,6 +130,10 @@ // FIXME: we may be able to import it by copying it without promotion. return false; + // Don't import variadic functions because inliner doesn't handle it. + if (Summary.isVariadicFunction()) + return false; + // Check references (and potential calls) in the same module. If the current // value references a global that can't be externally referenced it is not // eligible for import. Index: test/Bitcode/thinlto-function-summary.ll =================================================================== --- test/Bitcode/thinlto-function-summary.ll +++ test/Bitcode/thinlto-function-summary.ll @@ -9,13 +9,17 @@ ; BC-NEXT: record string = 'anon. +; BC-NEXT: record string = 'variadic' ; BC-NEXT: record string = 'foo' ; BC-NEXT: record string = 'bar' -; BC-NEXT: record string = 'f' +; BC-NEXT: record string = 'f' +; BC-NEXT: record string = 'anon. + ; RUN: opt -name-anon-functions -module-summary < %s | llvm-dis | FileCheck %s ; Check that this round-trips correctly. @@ -56,3 +60,7 @@ return: ; preds = %entry ret void } + +define i32 @variadic(...) { + ret i32 42 +} Index: test/Transforms/FunctionImport/Inputs/funcimport.ll =================================================================== --- test/Transforms/FunctionImport/Inputs/funcimport.ll +++ test/Transforms/FunctionImport/Inputs/funcimport.ll @@ -11,6 +11,7 @@ define void @globalfunc1() #0 { entry: call void @funcwithpersonality() + call void (...) @variadic() ret void } @@ -146,4 +147,8 @@ ret void } +; Variadic function should not be imported because inliner doesn't handle it. +define void @variadic(...) { + ret void +} Index: test/Transforms/FunctionImport/funcimport.ll =================================================================== --- test/Transforms/FunctionImport/funcimport.ll +++ test/Transforms/FunctionImport/funcimport.ll @@ -32,6 +32,7 @@ call void (...) @weakfunc() call void (...) @linkoncefunc2() call void (...) @referencelargelinkonce() + call void (...) @variadic() ret i32 0 } @@ -105,6 +106,9 @@ ; INSTLIMDEF-DAG: define available_externally hidden void @funcwithpersonality.llvm.{{.*}}() personality i8* bitcast (i32 (...)* @__gxx_personality_v0 to i8*) !thinlto_src_module !0 { ; INSTLIM5-DAG: declare hidden void @funcwithpersonality.llvm.{{.*}}() +; CHECK-DAG: declare void @variadic(...) +declare void @variadic(...) + ; INSTLIMDEF-DAG: Import globalfunc2 ; INSTLIMDEF-DAG: 13 function-import - Number of functions imported ; CHECK-DAG: !0 = !{!"{{.*}}/Inputs/funcimport.ll"}