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)
;
; 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
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}
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:
@_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(...)