mirror of
https://github.com/intel/llvm.git
synced 2026-01-23 07:58:23 +08:00
[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
This commit is contained in:
@@ -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: {
|
||||
|
||||
@@ -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
|
||||
|
||||
Reference in New Issue
Block a user