diff --git a/clang/test/Profile/cxx-templates.cpp b/clang/test/Profile/cxx-templates.cpp --- a/clang/test/Profile/cxx-templates.cpp +++ b/clang/test/Profile/cxx-templates.cpp @@ -10,8 +10,10 @@ // RUN: FileCheck --input-file=%tuse -check-prefix=T0USE -check-prefix=ALL %s // RUN: FileCheck --input-file=%tuse -check-prefix=T100USE -check-prefix=ALL %s -// T0GEN: @[[T0C:__profc__Z4loopILj0EEvv]] = linkonce_odr {{(hidden|dso_local)}} global [2 x i64] zeroinitializer -// T100GEN: @[[T100C:__profc__Z4loopILj100EEvv]] = linkonce_odr {{(hidden|dso_local)}} global [2 x i64] zeroinitializer +// The linkage can be target dependent, so accept all linkage here, +// the linkage tests for different target are in llvm/test/Instrumentation/InstrProfiling/profiling.ll +// T0GEN: @[[T0C:__profc__Z4loopILj0EEvv]] = {{.*}} global [2 x i64] zeroinitializer +// T100GEN: @[[T100C:__profc__Z4loopILj100EEvv]] = {{.*}} global [2 x i64] zeroinitializer // T0GEN-LABEL: define linkonce_odr {{.*}}void @_Z4loopILj0EEvv() // T0USE-LABEL: define linkonce_odr {{.*}}void @_Z4loopILj0EEvv() diff --git a/llvm/lib/Transforms/Instrumentation/InstrProfiling.cpp b/llvm/lib/Transforms/Instrumentation/InstrProfiling.cpp --- a/llvm/lib/Transforms/Instrumentation/InstrProfiling.cpp +++ b/llvm/lib/Transforms/Instrumentation/InstrProfiling.cpp @@ -862,6 +862,15 @@ GlobalValue::LinkageTypes Linkage = NamePtr->getLinkage(); GlobalValue::VisibilityTypes Visibility = NamePtr->getVisibility(); + // Due to the limitation of binder as of 2021/09/28, the duplicate weak + // symbols in the same csect won't be discarded. When there are duplicate weak + // symbols, we can NOT guarantee that the relocations get resolved to the + // intended weak symbol, so we can not ensure the correctness of the relative + // CounterPtr, so we have to use private linkage for counter and data symbols. + if (TT.isOSBinFormatXCOFF()) { + Linkage = GlobalValue::PrivateLinkage; + Visibility = GlobalValue::DefaultVisibility; + } // Move the name variable to the right section. Place them in a COMDAT group // if the associated function is a COMDAT. This will make sure that only one // copy of counters of the COMDAT function will be emitted after linking. Keep diff --git a/llvm/test/Instrumentation/InstrProfiling/profiling.ll b/llvm/test/Instrumentation/InstrProfiling/profiling.ll --- a/llvm/test/Instrumentation/InstrProfiling/profiling.ll +++ b/llvm/test/Instrumentation/InstrProfiling/profiling.ll @@ -45,8 +45,8 @@ ; MACHO: @__profd_foo_weak = weak hidden global ; COFF: @__profc_foo_weak = weak hidden global ; COFF: @__profd_foo_weak = private global -; XCOFF: @__profc_foo_weak = weak hidden global -; XCOFF: @__profd_foo_weak = weak hidden global +; XCOFF: @__profc_foo_weak = private global +; XCOFF: @__profd_foo_weak = private global define weak void @foo_weak() { call void @llvm.instrprof.increment(i8* getelementptr inbounds ([8 x i8], [8 x i8]* @__profn_foo_weak, i32 0, i32 0), i64 0, i32 1, i32 0) ret void @@ -71,8 +71,8 @@ ; MACHO: @__profd_foo_inline = linkonce_odr hidden global ; COFF: @__profc_foo_inline = linkonce_odr hidden global{{.*}} section ".lprfc$M", align 8 ; COFF: @__profd_foo_inline = private global{{.*}} section ".lprfd$M", align 8 -; XCOFF: @__profc_foo_inline = linkonce_odr hidden global -; XCOFF: @__profd_foo_inline = linkonce_odr hidden global +; XCOFF: @__profc_foo_inline = private global +; XCOFF: @__profd_foo_inline = private global define linkonce_odr void @foo_inline() { call void @llvm.instrprof.increment(i8* getelementptr inbounds ([10 x i8], [10 x i8]* @__profn_foo_inline, i32 0, i32 0), i64 0, i32 1, i32 0) ret void @@ -84,8 +84,8 @@ ; MACHO: @__profd_foo_extern = linkonce_odr hidden global ; COFF: @__profc_foo_extern = linkonce_odr hidden global {{.*}}section ".lprfc$M", comdat, align 8 ; COFF: @__profd_foo_extern = private global {{.*}}section ".lprfd$M", comdat($__profc_foo_extern), align 8 -; XCOFF: @__profc_foo_extern = linkonce_odr hidden global -; XCOFF: @__profd_foo_extern = linkonce_odr hidden global +; XCOFF: @__profc_foo_extern = private global +; XCOFF: @__profd_foo_extern = private global define available_externally void @foo_extern() { call void @llvm.instrprof.increment(i8* getelementptr inbounds ([10 x i8], [10 x i8]* @__profn_foo_extern, i32 0, i32 0), i64 0, i32 1, i32 0) ret void