The duplicate symbol errors are for __llvm_profile_filename and __llvm_profile_raw_version. IIUC, these are supposed to be weak symbols but Thin LTO seems to break this in some way. This does’t happen with gold or no LTO or full LTO.
defined at a.c
lto.tmp:(__llvm_profile_raw_version)
defined at b.c
lto.tmp:(.rodata.__llvm_profile_raw_version+0x0)
clang-7: error: linker command failed with exit code 1 (use -v to see invocation)
Makefile:10: recipe for target ‘a.out’ failed
make: *** [a.out] Error 1
Sorry, operator error. I can reproduce now. Interestingly, this does not reproduce using gold, and they utilize the same underlying LTO API. Let me dig a little using save-temps and see where they diverge.
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. http://llvm-cs.pcc.me.uk/lib/LTO/LTO.cpp#290
This patch fixes the reproducer but it leads to other test failures that would need to be looked at.
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
Thanks Peter, your patch does fix the reproducer. I filed https://bugs.llvm.org/show_bug.cgi?id=37422 to track this bug. I have no clue on how to resolve the tests - whether further cleanup is required in the code or in the tests. But if Teresa or you cannot get to it, I can, with some help, take a crack at fixing the tests.