[llvm-branch-commits] [llvm] 77b5097 - [ICP] Don't promote when target not defined in module

Teresa Johnson via llvm-branch-commits llvm-branch-commits at lists.llvm.org
Tue Dec 8 07:50:35 PST 2020


Author: Teresa Johnson
Date: 2020-12-08T07:45:36-08:00
New Revision: 77b509710ce7e6aec9ab460bc22a34f44fa94ab3

URL: https://github.com/llvm/llvm-project/commit/77b509710ce7e6aec9ab460bc22a34f44fa94ab3
DIFF: https://github.com/llvm/llvm-project/commit/77b509710ce7e6aec9ab460bc22a34f44fa94ab3.diff

LOG: [ICP] Don't promote when target not defined in module

This guards against cases where the symbol was dead code eliminated in
the binary by ThinLTO, and we have a sample profile collected for one
binary but used to optimize another.

Most of the benefit from ICP comes from inlining the target, which we
can't do with only a declaration anyway. If this is in the pre-ThinLTO
link step (e.g. for instrumentation based PGO), we will attempt the
promotion again in the ThinLTO backend after importing anyway, and we
don't need the early promotion to facilitate that.

Differential Revision: https://reviews.llvm.org/D92804

Added: 
    

Modified: 
    llvm/lib/Transforms/Instrumentation/IndirectCallPromotion.cpp
    llvm/test/LTO/Resolution/X86/load-sample-prof-icp.ll
    llvm/test/Transforms/PGOProfile/icp_covariant_call_return.ll
    llvm/test/Transforms/PGOProfile/icp_covariant_invoke_return.ll
    llvm/test/Transforms/PGOProfile/indirect_call_promotion_musttail.ll

Removed: 
    


################################################################################
diff  --git a/llvm/lib/Transforms/Instrumentation/IndirectCallPromotion.cpp b/llvm/lib/Transforms/Instrumentation/IndirectCallPromotion.cpp
index bcd4e2e8e33c..5b9557a9b328 100644
--- a/llvm/lib/Transforms/Instrumentation/IndirectCallPromotion.cpp
+++ b/llvm/lib/Transforms/Instrumentation/IndirectCallPromotion.cpp
@@ -263,8 +263,15 @@ ICallPromotionFunc::getPromotionCandidatesForCallSite(
       break;
     }
 
+    // Don't promote if the symbol is not defined in the module. This avoids
+    // creating a reference to a symbol that doesn't exist in the module
+    // This can happen when we compile with a sample profile collected from
+    // one binary but used for another, which may have profiled targets that
+    // aren't used in the new binary. We might have a declaration initially in
+    // the case where the symbol is globally dead in the binary and removed by
+    // ThinLTO.
     Function *TargetFunction = Symtab->getFunction(Target);
-    if (TargetFunction == nullptr) {
+    if (TargetFunction == nullptr || TargetFunction->isDeclaration()) {
       LLVM_DEBUG(dbgs() << " Not promote: Cannot find the target\n");
       ORE.emit([&]() {
         return OptimizationRemarkMissed(DEBUG_TYPE, "UnableToFindTarget", &CB)

diff  --git a/llvm/test/LTO/Resolution/X86/load-sample-prof-icp.ll b/llvm/test/LTO/Resolution/X86/load-sample-prof-icp.ll
index 8ebb0a134ffd..d4af2c4cc447 100644
--- a/llvm/test/LTO/Resolution/X86/load-sample-prof-icp.ll
+++ b/llvm/test/LTO/Resolution/X86/load-sample-prof-icp.ll
@@ -3,11 +3,11 @@
 ;
 ; RUN: opt -module-summary < %s -o %t.bc
 ; RUN: llvm-lto2 run -o %t.out %t.bc -save-temps \
-; RUN:   -r %t.bc,test,px -r %t.bc,bar,x \
+; RUN:   -r %t.bc,test,px -r %t.bc,bar,px -r %t.bc,externfunc,x \
 ; RUN:   -lto-sample-profile-file=%S/Inputs/load-sample-prof-icp.prof
 ; RUN: llvm-dis %t.out.1.4.opt.bc -o - | FileCheck %s
 ; RUN: llvm-lto2 run -o %t.out %t.bc -save-temps \
-; RUN:   -r %t.bc,test,px -r %t.bc,bar,x -use-new-pm \
+; RUN:   -r %t.bc,test,px -r %t.bc,bar,px -r %t.bc,externfunc,x -use-new-pm \
 ; RUN:   -lto-sample-profile-file=%S/Inputs/load-sample-prof-icp.prof
 ; RUN: llvm-dis %t.out.1.4.opt.bc -o - | FileCheck %s
 
@@ -26,9 +26,14 @@ define void @test(void ()*) #0 !dbg !7 {
   ret void
 }
 
-declare void @bar() local_unnamed_addr
+declare void @externfunc()
 
-attributes #0 = {"use-sample-profile"}
+define void @bar() #0 {
+  call void @externfunc()
+  ret void
+}
+
+attributes #0 = {"use-sample-profile" noinline}
 
 !llvm.dbg.cu = !{!0}
 !llvm.module.flags = !{!3, !4, !5}

diff  --git a/llvm/test/Transforms/PGOProfile/icp_covariant_call_return.ll b/llvm/test/Transforms/PGOProfile/icp_covariant_call_return.ll
index c2101a98d0d1..a4f10c64170c 100644
--- a/llvm/test/Transforms/PGOProfile/icp_covariant_call_return.ll
+++ b/llvm/test/Transforms/PGOProfile/icp_covariant_call_return.ll
@@ -10,7 +10,9 @@ target triple = "x86_64-unknown-linux-gnu"
 
 declare noalias i8* @_Znwm(i64)
 declare void @_ZN1DC2Ev(%struct.D*);
-declare %struct.Derived* @_ZN1D4funcEv(%struct.D*);
+define %struct.Derived* @_ZN1D4funcEv(%struct.D*) {
+  ret %struct.Derived* null
+}
 
 define %struct.Base* @bar() {
 entry:

diff  --git a/llvm/test/Transforms/PGOProfile/icp_covariant_invoke_return.ll b/llvm/test/Transforms/PGOProfile/icp_covariant_invoke_return.ll
index d0f27ac73e78..c36b2e90ec7a 100644
--- a/llvm/test/Transforms/PGOProfile/icp_covariant_invoke_return.ll
+++ b/llvm/test/Transforms/PGOProfile/icp_covariant_invoke_return.ll
@@ -10,7 +10,9 @@ target triple = "x86_64-unknown-linux-gnu"
 @_ZTIi = external constant i8*
 declare i8* @_Znwm(i64)
 declare void @_ZN1DC2Ev(%struct.D*)
-declare %struct.Derived* @_ZN1D4funcEv(%struct.D*)
+define %struct.Derived* @_ZN1D4funcEv(%struct.D*) {
+  ret %struct.Derived* null
+}
 declare void @_ZN1DD0Ev(%struct.D*)
 declare void @_ZdlPv(i8*)
 declare i32 @__gxx_personality_v0(...)

diff  --git a/llvm/test/Transforms/PGOProfile/indirect_call_promotion_musttail.ll b/llvm/test/Transforms/PGOProfile/indirect_call_promotion_musttail.ll
index e79e533c4af2..6dea060d6c26 100644
--- a/llvm/test/Transforms/PGOProfile/indirect_call_promotion_musttail.ll
+++ b/llvm/test/Transforms/PGOProfile/indirect_call_promotion_musttail.ll
@@ -6,13 +6,21 @@ target triple = "x86_64-unknown-linux-gnu"
 
 @foo = common global i32* ()* null, align 8
 
-declare i32* @func1()
+define i32* @func1() {
+  ret i32* null
+}
 
-declare i32* @func2()
+define i32* @func2() {
+  ret i32* null
+}
 
-declare i32* @func3()
+define i32* @func3() {
+  ret i32* null
+}
 
-declare i32* @func4()
+define i32* @func4() {
+  ret i32* null
+}
 
 define i32* @bar() {
 entry:


        


More information about the llvm-branch-commits mailing list