aboutsummaryrefslogtreecommitdiff
path: root/llvm/lib/Linker/LinkModules.cpp
diff options
context:
space:
mode:
authorPetr Hosek <phosek@google.com>2021-08-25 01:12:19 -0700
committerPetr Hosek <phosek@google.com>2021-08-31 17:44:33 -0700
commit92f54e1c752253b5a17eb9ec7942f580d878f64d (patch)
tree914d039ebc13766cc6bbca1721b7a75eb0addf52 /llvm/lib/Linker/LinkModules.cpp
parentc2162e4d89d6f99bbbe96beaa9156dbb2dba8344 (diff)
downloadllvm-92f54e1c752253b5a17eb9ec7942f580d878f64d.zip
llvm-92f54e1c752253b5a17eb9ec7942f580d878f64d.tar.gz
llvm-92f54e1c752253b5a17eb9ec7942f580d878f64d.tar.bz2
[Linker] Support weak symbols in nodeduplicate COMDAT group
When a nodeduplicate COMDAT group contains a weak symbol, choose a non-weak symbol (or one of the weak ones) rather than reporting an error. This should address issue PR51394. With the current IR representation, a generic comdat nodeduplicate semantics is not representable for LTO. In the linker, sections and symbols are separate concepts. A dropped weak symbol does not force the defining input section to be dropped as well (though it can be collected by GC). In the IR, when a weak linkage symbol is dropped, its associate section content is dropped as well. For InstrProfiling, which is where ran into this issue in PR51394, the deduplication semantic is a sufficient workaround. Differential Revision: https://reviews.llvm.org/D108689
Diffstat (limited to 'llvm/lib/Linker/LinkModules.cpp')
-rw-r--r--llvm/lib/Linker/LinkModules.cpp22
1 files changed, 19 insertions, 3 deletions
diff --git a/llvm/lib/Linker/LinkModules.cpp b/llvm/lib/Linker/LinkModules.cpp
index 555aeea..2a44800 100644
--- a/llvm/lib/Linker/LinkModules.cpp
+++ b/llvm/lib/Linker/LinkModules.cpp
@@ -179,9 +179,25 @@ bool ModuleLinker::computeResultingSelectionKind(StringRef ComdatName,
// Go with Dst.
From = LinkFrom::Dst;
break;
- case Comdat::SelectionKind::NoDeduplicate:
- return emitError("Linking COMDATs named '" + ComdatName +
- "': nodeduplicate has been violated!");
+ case Comdat::SelectionKind::NoDeduplicate: {
+ const GlobalVariable *DstGV;
+ const GlobalVariable *SrcGV;
+ if (getComdatLeader(DstM, ComdatName, DstGV) ||
+ getComdatLeader(*SrcM, ComdatName, SrcGV))
+ return true;
+
+ if (SrcGV->isWeakForLinker()) {
+ // Go with Dst.
+ From = LinkFrom::Dst;
+ } else if (DstGV->isWeakForLinker()) {
+ // Go with Src.
+ From = LinkFrom::Src;
+ } else {
+ return emitError("Linking COMDATs named '" + ComdatName +
+ "': nodeduplicate has been violated!");
+ }
+ break;
+ }
case Comdat::SelectionKind::ExactMatch:
case Comdat::SelectionKind::Largest:
case Comdat::SelectionKind::SameSize: {