diff --git a/lib/Transforms/Instrumentation/InstrProfiling.cpp b/lib/Transforms/Instrumentation/InstrProfiling.cpp index d2f5b29e24b..cf8f93d0407 100644 --- a/lib/Transforms/Instrumentation/InstrProfiling.cpp +++ b/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/test/Instrumentation/InstrProfiling/PR23499.ll b/test/Instrumentation/InstrProfiling/PR23499.ll index ef8799c4449..df32d6560cd 100644 --- a/test/Instrumentation/InstrProfiling/PR23499.ll +++ b/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/test/Transforms/PGOProfile/indirect_call_profile.ll b/test/Transforms/PGOProfile/indirect_call_profile.ll index 0d934ba7584..e1753acb7c7 100644 --- a/test/Transforms/PGOProfile/indirect_call_profile.ll +++ b/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