diff options
| -rw-r--r-- | llvm/lib/Analysis/ModuleSummaryAnalysis.cpp | 9 | ||||
| -rw-r--r-- | llvm/test/Bitcode/thinlto-function-summary.ll | 18 | ||||
| -rw-r--r-- | llvm/test/Transforms/FunctionImport/Inputs/funcimport.ll | 17 | ||||
| -rw-r--r-- | llvm/test/Transforms/FunctionImport/funcimport.ll | 21 |
4 files changed, 50 insertions, 15 deletions
diff --git a/llvm/lib/Analysis/ModuleSummaryAnalysis.cpp b/llvm/lib/Analysis/ModuleSummaryAnalysis.cpp index 29b96ac746b..f0421782b66 100644 --- a/llvm/lib/Analysis/ModuleSummaryAnalysis.cpp +++ b/llvm/lib/Analysis/ModuleSummaryAnalysis.cpp @@ -246,10 +246,15 @@ static void computeFunctionSummary( findRefEdges(Index, &F, RefEdges, Visited); bool HasInlineAsmMaybeReferencingInternal = false; + bool InitsVarArgs = false; for (const BasicBlock &BB : F) for (const Instruction &I : BB) { if (isa<DbgInfoIntrinsic>(I)) continue; + if (const IntrinsicInst *II = dyn_cast<IntrinsicInst>(&I)) { + if (II->getIntrinsicID() == Intrinsic::vastart) + InitsVarArgs = true; + } ++NumInsts; findRefEdges(Index, &I, RefEdges, Visited); auto CS = ImmutableCallSite(&I); @@ -357,9 +362,9 @@ static void computeFunctionSummary( F.hasFnAttribute(Attribute::ReadNone), F.hasFnAttribute(Attribute::ReadOnly), F.hasFnAttribute(Attribute::NoRecurse), F.returnDoesNotAlias(), - // Inliner doesn't handle variadic functions. + // Inliner doesn't handle variadic functions with va_start calls. // FIXME: refactor this to use the same code that inliner is using. - F.isVarArg() || + InitsVarArgs || // Don't try to import functions with noinline attribute. F.getAttributes().hasFnAttribute(Attribute::NoInline)}; auto FuncSummary = llvm::make_unique<FunctionSummary>( diff --git a/llvm/test/Bitcode/thinlto-function-summary.ll b/llvm/test/Bitcode/thinlto-function-summary.ll index 7f59eeabd9c..8563d127ff6 100644 --- a/llvm/test/Bitcode/thinlto-function-summary.ll +++ b/llvm/test/Bitcode/thinlto-function-summary.ll @@ -13,18 +13,23 @@ ; BC-NEXT: <FUNCTION op0=7 op1=39 ; "variadic" ; BC-NEXT: <FUNCTION op0=46 op1=8 +; "llvm.va_start" +; BC-NEXT: <FUNCTION op0=54 op1=13 ; "f" -; BC-NEXT: <ALIAS op0=54 op1=1 +; BC-NEXT: <ALIAS op0=67 op1=1 ; BC: <GLOBALVAL_SUMMARY_BLOCK ; BC-NEXT: <VERSION ; BC-NEXT: <PERMODULE {{.*}} op0=1 op1=0 ; BC-NEXT: <PERMODULE {{.*}} op0=2 op1=0 ; BC-NEXT: <PERMODULE {{.*}} op0=3 op1=7 -; BC-NEXT: <PERMODULE {{.*}} op0=4 op1=0 op2=1 op3=16 -; BC-NEXT: <ALIAS {{.*}} op0=5 op1=0 op2=3 +; Summary for @variadic has flags (op3) = 16 since non-inlinable owing to +; va_start call. +; flag is set due to va_start call. +; BC-NEXT: <PERMODULE {{.*}} op0=4 op1=0 op2=4 op3=16 +; BC-NEXT: <ALIAS {{.*}} op0=6 op1=0 op2=3 ; BC-NEXT: </GLOBALVAL_SUMMARY_BLOCK ; BC: <STRTAB_BLOCK -; BC-NEXT: blob data = 'hfoobaranon.{{................................}}.0variadicf{{.*}}' +; BC-NEXT: blob data = 'hfoobaranon.{{................................}}.0variadicllvm.va_startf{{.*}}' ; RUN: opt -name-anon-globals -module-summary < %s | llvm-dis | FileCheck %s @@ -68,5 +73,10 @@ return: ; preds = %entry } define i32 @variadic(...) { + %ap = alloca i8*, align 8 + %ap.0 = bitcast i8** %ap to i8* + call void @llvm.va_start(i8* %ap.0) ret i32 42 } + +declare void @llvm.va_start(i8*) nounwind diff --git a/llvm/test/Transforms/FunctionImport/Inputs/funcimport.ll b/llvm/test/Transforms/FunctionImport/Inputs/funcimport.ll index c4ef37a168f..201d4492671 100644 --- a/llvm/test/Transforms/FunctionImport/Inputs/funcimport.ll +++ b/llvm/test/Transforms/FunctionImport/Inputs/funcimport.ll @@ -11,7 +11,7 @@ define void @globalfunc1() #0 { entry: call void @funcwithpersonality() - call void (...) @variadic() + call void (...) @variadic_va_start() ret void } @@ -147,8 +147,19 @@ entry: ret void } -; Variadic function should not be imported because inliner doesn't handle it. -define void @variadic(...) { +; Variadic function without va_start can be imported because inliner +; can handle it. +define void @variadic_no_va_start(...) { ret void } +; Variadic function with va_start should not be imported because inliner +; doesn't handle it. +define void @variadic_va_start(...) { + %ap = alloca i8*, align 8 + %ap.0 = bitcast i8** %ap to i8* + call void @llvm.va_start(i8* %ap.0) + ret void +} + +declare void @llvm.va_start(i8*) nounwind diff --git a/llvm/test/Transforms/FunctionImport/funcimport.ll b/llvm/test/Transforms/FunctionImport/funcimport.ll index bb974b587e3..b905549300a 100644 --- a/llvm/test/Transforms/FunctionImport/funcimport.ll +++ b/llvm/test/Transforms/FunctionImport/funcimport.ll @@ -29,7 +29,8 @@ entry: call void (...) @weakfunc() call void (...) @linkoncefunc2() call void (...) @referencelargelinkonce() - call void (...) @variadic() + call void (...) @variadic_no_va_start() + call void (...) @variadic_va_start() ret i32 0 } @@ -103,11 +104,19 @@ declare void @linkoncefunc2(...) #1 ; 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(...) +; We can import variadic functions without a va_start, since the inliner +; can handle them. +; INSTLIMDEF-DAG: Import variadic_no_va_start +; CHECK-DAG: define available_externally void @variadic_no_va_start(...) !thinlto_src_module !0 { +declare void @variadic_no_va_start(...) + +; We shouldn't import variadic functions without a va_start, since the inliner +; cannot handle them. +; CHECK-DAG: declare void @variadic_va_start(...) +declare void @variadic_va_start(...) ; INSTLIMDEF-DAG: Import globalfunc2 -; INSTLIMDEF-DAG: 13 function-import - Number of functions imported +; INSTLIMDEF-DAG: 14 function-import - Number of functions imported ; INSTLIMDEF-DAG: 4 function-import - Number of global variables imported ; CHECK-DAG: !0 = !{!"{{.*}}/Inputs/funcimport.ll"} @@ -147,7 +156,7 @@ declare void @variadic(...) ; GUID-DAG: GUID {{.*}} is linkoncefunc ; DUMP: Module [[M1:.*]] imports from 1 module -; DUMP-NEXT: 13 functions imported from [[M2:.*]] +; DUMP-NEXT: 14 functions imported from [[M2:.*]] ; DUMP-NEXT: 4 vars imported from [[M2]] -; DUMP: Imported 13 functions for Module [[M1]] +; DUMP: Imported 14 functions for Module [[M1]] ; DUMP-NEXT: Imported 4 global variables for Module [[M1]] |

