summaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
-rw-r--r--llvm/lib/Transforms/Instrumentation/InstrProfiling.cpp8
-rw-r--r--llvm/test/Instrumentation/InstrProfiling/PR23499.ll4
-rw-r--r--llvm/test/Transforms/PGOProfile/indirect_call_profile.ll11
3 files changed, 20 insertions, 3 deletions
diff --git a/llvm/lib/Transforms/Instrumentation/InstrProfiling.cpp b/llvm/lib/Transforms/Instrumentation/InstrProfiling.cpp
index d2f5b29e24b..cf8f93d0407 100644
--- a/llvm/lib/Transforms/Instrumentation/InstrProfiling.cpp
+++ b/llvm/lib/Transforms/Instrumentation/InstrProfiling.cpp
@@ -258,7 +258,13 @@ static inline bool shouldRecordFunctionAddr(Function *F) {
if (F->hasLocalLinkage() && F->hasComdat())
return false;
// Check uses of this function for other than direct calls or invokes to it.
- return F->hasAddressTaken();
+ // Inline virtual functions have linkeOnceODR linkage. When a key method
+ // exists, the vtable will only be emitted in the TU where the key method
+ // is defined. In a TU where vtable is not available, the function won't
+ // be 'addresstaken'. If its address is not recorded here, the profile counter
+ // comdat group with missing address may be picked by the linker leading
+ // to missing indirect call target info.
+ return F->hasAddressTaken() || (F->hasLinkOnceLinkage() && F->hasComdat());
}
static inline bool needsComdatForCounter(Function &F, Module &M) {
diff --git a/llvm/test/Instrumentation/InstrProfiling/PR23499.ll b/llvm/test/Instrumentation/InstrProfiling/PR23499.ll
index ef8799c4449..df32d6560cd 100644
--- a/llvm/test/Instrumentation/InstrProfiling/PR23499.ll
+++ b/llvm/test/Instrumentation/InstrProfiling/PR23499.ll
@@ -15,13 +15,13 @@ $_Z3barIvEvv = comdat any
; CHECK: @__profn__Z3barIvEvv = private constant [11 x i8] c"_Z3barIvEvv", align 1
; CHECK: @__profc__Z3barIvEvv = linkonce_odr hidden global [1 x i64] zeroinitializer, section "{{.*}}__llvm_prf_cnts", comdat($__profv__Z3barIvEvv), align 8
-; CHECK: @__profd__Z3barIvEvv = linkonce_odr hidden global { i64, i64, i64*, i8*, i8*, i32, [1 x i16] } { i64 4947693190065689389, i64 0, i64* getelementptr inbounds ([1 x i64], [1 x i64]* @__profc__Z3barIvEvv, i32 0, i32 0), i8* null, i8* null, i32 1, [1 x i16] zeroinitializer }, section "{{.*}}__llvm_prf_data", comdat($__profv__Z3barIvEvv), align 8
+; CHECK: @__profd__Z3barIvEvv = linkonce_odr hidden global { i64, i64, i64*, i8*, i8*, i32, [1 x i16] } { i64 4947693190065689389, i64 0, i64* getelementptr inbounds ([1 x i64], [1 x i64]* @__profc__Z3barIvEvv, i32 0, i32 0), i8*{{.*}}, i8* null, i32 1, [1 x i16] zeroinitializer }, section "{{.*}}__llvm_prf_data", comdat($__profv__Z3barIvEvv), align 8
; CHECK: @__llvm_prf_nm = private constant [{{.*}} x i8] c"{{.*}}", section "{{.*}}__llvm_prf_names"
; COFF: @__profn__Z3barIvEvv = private constant [11 x i8] c"_Z3barIvEvv", align 1
; COFF: @__profc__Z3barIvEvv = linkonce_odr hidden global [1 x i64] zeroinitializer, section "{{.*}}__llvm_prf_cnts", comdat, align 8
-; COFF: @__profd__Z3barIvEvv = linkonce_odr hidden global { i64, i64, i64*, i8*, i8*, i32, [1 x i16] } { i64 4947693190065689389, i64 0, i64* getelementptr inbounds ([1 x i64], [1 x i64]* @__profc__Z3barIvEvv, i32 0, i32 0), i8* null, i8* null, i32 1, [1 x i16] zeroinitializer }, section "{{.*}}__llvm_prf_data", comdat($__profc__Z3barIvEvv), align 8
+; COFF: @__profd__Z3barIvEvv = linkonce_odr hidden global { i64, i64, i64*, i8*, i8*, i32, [1 x i16] } { i64 4947693190065689389, i64 0, i64* getelementptr inbounds ([1 x i64], [1 x i64]* @__profc__Z3barIvEvv, i32 0, i32 0), i8*{{.*}}, i8* null, i32 1, [1 x i16] zeroinitializer }, section "{{.*}}__llvm_prf_data", comdat($__profc__Z3barIvEvv), align 8
declare void @llvm.instrprof.increment(i8*, i64, i32, i32) #1
diff --git a/llvm/test/Transforms/PGOProfile/indirect_call_profile.ll b/llvm/test/Transforms/PGOProfile/indirect_call_profile.ll
index 0d934ba7584..e1753acb7c7 100644
--- a/llvm/test/Transforms/PGOProfile/indirect_call_profile.ll
+++ b/llvm/test/Transforms/PGOProfile/indirect_call_profile.ll
@@ -1,8 +1,12 @@
; RUN: opt < %s -pgo-instr-gen -S | FileCheck %s --check-prefix=GEN
; RUN: opt < %s -passes=pgo-instr-gen -S | FileCheck %s --check-prefix=GEN
+; RUN: opt < %s -passes=pgo-instr-gen,instrprof -S | FileCheck %s --check-prefix=LOWER
+
target datalayout = "e-m:e-i64:64-f80:128-n8:16:32:64-S128"
target triple = "x86_64-unknown-linux-gnu"
+$foo3 = comdat any
+
@bar = external global void ()*, align 8
; GEN: @__profn_foo = private constant [3 x i8] c"foo"
@@ -49,6 +53,13 @@ bb11: ; preds = %bb2
resume { i8*, i32 } %tmp3
}
+; Test that comdat function's address is recorded.
+; LOWER: @__profd_foo3 = linkonce_odr{{.*}}@foo3
+; Function Attrs: nounwind uwtable
+define linkonce_odr i32 @foo3() comdat {
+ ret i32 1
+}
+
declare i32 @__gxx_personality_v0(...)
; Function Attrs: nounwind readnone
OpenPOWER on IntegriCloud