Skip to content

Commit 53544fc

Browse files
authored
[ELF] Respect ltoCanOmit for symbols in non-prevailing COMDAT
A linkonce_odr definition can be omitted in LTO compilation if `canBeOmittedFromSymbolTable()` is true in all bitcode files. Currently, we don't respect the `canBeOmittedFromSymbolTable()` bit from symbols in a non-prevailing COMDAT, which could lead to incorrect omission of a definition when merging a prevailing linkonce_odr and a non-prevailing weak_odr, e.g. an implicit template instantiation and an explicit template instantiation. To fix #111341, allow the non-prevailing COMDAT code path to clear the `ltoCanOmit` bit, so that `VisibleToRegularObj` could be false in LTO.cpp. We could resolve either an Undefined or a Defined. For simplicity, just use a Defined like the prevailing case (similar to how we resolve symbols in ObjectFile COMDAT reviews.llvm.org/D120626). Pull Request: #119332
1 parent 03661fb commit 53544fc

File tree

2 files changed

+8
-7
lines changed

2 files changed

+8
-7
lines changed

lld/ELF/InputFiles.cpp

Lines changed: 3 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -1709,7 +1709,6 @@ static uint8_t mapVisibility(GlobalValue::VisibilityTypes gvVisibility) {
17091709
}
17101710

17111711
static void createBitcodeSymbol(Ctx &ctx, Symbol *&sym,
1712-
const std::vector<bool> &keptComdats,
17131712
const lto::InputFile::Symbol &objSym,
17141713
BitcodeFile &f) {
17151714
uint8_t binding = objSym.isWeak() ? STB_WEAK : STB_GLOBAL;
@@ -1726,8 +1725,7 @@ static void createBitcodeSymbol(Ctx &ctx, Symbol *&sym,
17261725
sym = ctx.symtab->insert(objSym.getName());
17271726
}
17281727

1729-
int c = objSym.getComdatIndex();
1730-
if (objSym.isUndefined() || (c != -1 && !keptComdats[c])) {
1728+
if (objSym.isUndefined()) {
17311729
Undefined newSym(&f, StringRef(), binding, visibility, type);
17321730
sym->resolve(ctx, newSym);
17331731
sym->referenced = true;
@@ -1766,10 +1764,10 @@ void BitcodeFile::parse() {
17661764
// ObjFile<ELFT>::initializeSymbols.
17671765
for (auto [i, irSym] : llvm::enumerate(obj->symbols()))
17681766
if (!irSym.isUndefined())
1769-
createBitcodeSymbol(ctx, symbols[i], keptComdats, irSym, *this);
1767+
createBitcodeSymbol(ctx, symbols[i], irSym, *this);
17701768
for (auto [i, irSym] : llvm::enumerate(obj->symbols()))
17711769
if (irSym.isUndefined())
1772-
createBitcodeSymbol(ctx, symbols[i], keptComdats, irSym, *this);
1770+
createBitcodeSymbol(ctx, symbols[i], irSym, *this);
17731771

17741772
for (auto l : obj->getDependentLibraries())
17751773
addDependentLibrary(ctx, l, this);

lld/test/ELF/lto/internalize-exportdyn.ll

Lines changed: 5 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -56,16 +56,19 @@ define linkonce_odr void @baz() {
5656

5757
@use_baz = global ptr @baz
5858

59+
;; Test comdat symbols that are prevailing in this module and non-prevailing in the other module.
5960
define void @ext_and_ext() local_unnamed_addr comdat {
6061
call void @foo(i64 1)
6162
ret void
6263
}
6364

65+
;; linkonce_odr in this module and external in the other module.
6466
define linkonce_odr void @lo_and_ext() local_unnamed_addr comdat {
6567
call void @foo(i64 1)
6668
ret void
6769
}
6870

71+
;; linkonce_odr in this module and weak_odr in the other module.
6972
define linkonce_odr void @lo_and_wo() local_unnamed_addr comdat {
7073
ret void
7174
}
@@ -92,7 +95,7 @@ define weak_odr void @wo_and_lo() local_unnamed_addr comdat {
9295
; CHECK-NEXT: call void @foo(i64 1)
9396
; CHECK: define internal void @lo_and_ext() comdat
9497
; CHECK-NEXT: call void @foo(i64 1)
95-
; CHECK: define internal void @lo_and_wo() comdat
98+
; CHECK: define weak_odr dso_local void @lo_and_wo() comdat
9699
; CHECK: define weak_odr dso_local void @wo_and_lo() comdat
97100

98101
; DSO: @c = weak_odr constant i32 1
@@ -110,7 +113,7 @@ define weak_odr void @wo_and_lo() local_unnamed_addr comdat {
110113
; DSO: define weak_odr void @baz()
111114
; DSO: define void @ext_and_ext() comdat
112115
; DSO: define internal void @lo_and_ext() comdat
113-
; DSO: define internal void @lo_and_wo() comdat
116+
; DSO: define weak_odr void @lo_and_wo() comdat
114117
; DSO: define weak_odr void @wo_and_lo() comdat
115118

116119
;--- lib.s

0 commit comments

Comments
 (0)