The problem is that ThinLTO is not dropping the non-prevailing definitions, and they end up being emitted into the object file for b.o.
$ ../ra/bin/llvm-dis -o - b.o0.0.preopt.bc | grep __llvm_prof
$__llvm_profile_raw_version = comdat any
$__llvm_profile_filename = comdat any
@__llvm_profile_raw_version = constant i64 72057594037927940, comdat
@__llvm_profile_filename = constant [19 x i8] c"default_%m.profraw\00", comdat
lld ignores comdats in LTO object files because it expects all comdats to have already been resolved. So we see this error.
We are supposed to drop non-prevailing symbols here, but for some reason we do it only for weak symbols. That's not correct in ELF where comdat symbols can be both strong and non-prevailing.
This patch fixes the reproducer but it leads to other test failures that would need to be looked at.
diff --git a/llvm/lib/LTO/LTO.cpp b/llvm/lib/LTO/LTO.cpp
index 7e8b9b3c6390..ee11d07d6b8e 100644
--- a/llvm/lib/LTO/LTO.cpp
+++ b/llvm/lib/LTO/LTO.cpp
@@ -287,7 +287,7 @@ static void thinLTOResolveWeakForLinkerGUID(
recordNewLinkage) {
for (auto &S : GVSummaryList) {
GlobalValue::LinkageTypes OriginalLinkage = S->linkage();
- if (!GlobalValue::isWeakForLinker(OriginalLinkage))
+ if (GlobalValue::isLocalLinkage(OriginalLinkage))
continue;
// We need to emit only one of these. The prevailing module will keep it,
// but turned into a weak, while the others will drop it when possible.
diff --git a/llvm/lib/Transforms/IPO/FunctionImport.cpp b/llvm/lib/Transforms/IPO/FunctionImport.cpp
index 246d75caefa2..61790c9fc435 100644
--- a/llvm/lib/Transforms/IPO/FunctionImport.cpp
+++ b/llvm/lib/Transforms/IPO/FunctionImport.cpp
@@ -765,7 +765,7 @@ void llvm::thinLTOResolveWeakForLinkerModule(
return;
}
- if (!GlobalValue::isWeakForLinker(GV.getLinkage()))
+ if (GlobalValue::isLocalLinkage(GV.getLinkage()))
return;
// Check for a non-prevailing def that has interposable linkage
// (e.g. non-odr weak or linkonce). In that case we can't simply