Skip to content

Commit

Permalink
[Linker] Support weak symbols in nodeduplicate COMDAT group
Browse files Browse the repository at this point in the history
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
  • Loading branch information
petrhosek committed Sep 1, 2021
1 parent c2162e4 commit 92f54e1
Show file tree
Hide file tree
Showing 2 changed files with 25 additions and 7 deletions.
22 changes: 19 additions & 3 deletions llvm/lib/Linker/LinkModules.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -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: {
Expand Down
10 changes: 6 additions & 4 deletions llvm/test/Linker/comdat-nodeduplicate.ll
Original file line number Diff line number Diff line change
Expand Up @@ -3,14 +3,16 @@

; CHECK: error: Linking COMDATs named 'foo': nodeduplicate has been violated!

; RUN: not llvm-link -S %t/2.ll %t/2-aux.ll 2>&1 | FileCheck %s --check-prefix=CHECK2
; RUN: not llvm-link -S %t/2-aux.ll %t/2.ll 2>&1 | FileCheck %s --check-prefix=CHECK2
; RUN: llvm-link -S %t/2.ll %t/2-aux.ll | FileCheck %s --check-prefix=CHECK2
; RUN: llvm-link -S %t/2-aux.ll %t/2.ll | FileCheck %s --check-prefix=CHECK2

; CHECK2: error: Linking COMDATs named 'foo'
; CHECK2-DAG: @foo = global i64 2, section "data", comdat, align 8
; CHECK2-DAG: @bar = weak global i64 0, section "cnts", comdat($foo)
; CHECK2-DAG: @qux = weak_odr global i64 4, comdat($foo)

; RUN: not llvm-link -S %t/non-var.ll %t/non-var.ll 2>&1 | FileCheck %s --check-prefix=NONVAR

; NONVAR: error: Linking COMDATs named 'foo': nodeduplicate has been violated!
; NONVAR: error: Linking COMDATs named 'foo': GlobalVariable required for data dependent selection!

;--- 1.ll
$foo = comdat nodeduplicate
Expand Down

0 comments on commit 92f54e1

Please sign in to comment.