[lld] 53544fc - [ELF] Respect ltoCanOmit for symbols in non-prevailing COMDAT

via llvm-commits llvm-commits at lists.llvm.org
Wed Dec 11 08:55:09 PST 2024


Author: Fangrui Song
Date: 2024-12-11T08:55:05-08:00
New Revision: 53544fc15f08687c14becced4ecc22c2356265cd

URL: https://github.com/llvm/llvm-project/commit/53544fc15f08687c14becced4ecc22c2356265cd
DIFF: https://github.com/llvm/llvm-project/commit/53544fc15f08687c14becced4ecc22c2356265cd.diff

LOG: [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: https://github.com/llvm/llvm-project/pull/119332

Added: 
    

Modified: 
    lld/ELF/InputFiles.cpp
    lld/test/ELF/lto/internalize-exportdyn.ll

Removed: 
    


################################################################################
diff  --git a/lld/ELF/InputFiles.cpp b/lld/ELF/InputFiles.cpp
index 2084fcfd4d651a..c44773d0b7dabe 100644
--- a/lld/ELF/InputFiles.cpp
+++ b/lld/ELF/InputFiles.cpp
@@ -1709,7 +1709,6 @@ static uint8_t mapVisibility(GlobalValue::VisibilityTypes gvVisibility) {
 }
 
 static void createBitcodeSymbol(Ctx &ctx, Symbol *&sym,
-                                const std::vector<bool> &keptComdats,
                                 const lto::InputFile::Symbol &objSym,
                                 BitcodeFile &f) {
   uint8_t binding = objSym.isWeak() ? STB_WEAK : STB_GLOBAL;
@@ -1726,8 +1725,7 @@ static void createBitcodeSymbol(Ctx &ctx, Symbol *&sym,
     sym = ctx.symtab->insert(objSym.getName());
   }
 
-  int c = objSym.getComdatIndex();
-  if (objSym.isUndefined() || (c != -1 && !keptComdats[c])) {
+  if (objSym.isUndefined()) {
     Undefined newSym(&f, StringRef(), binding, visibility, type);
     sym->resolve(ctx, newSym);
     sym->referenced = true;
@@ -1766,10 +1764,10 @@ void BitcodeFile::parse() {
   // ObjFile<ELFT>::initializeSymbols.
   for (auto [i, irSym] : llvm::enumerate(obj->symbols()))
     if (!irSym.isUndefined())
-      createBitcodeSymbol(ctx, symbols[i], keptComdats, irSym, *this);
+      createBitcodeSymbol(ctx, symbols[i], irSym, *this);
   for (auto [i, irSym] : llvm::enumerate(obj->symbols()))
     if (irSym.isUndefined())
-      createBitcodeSymbol(ctx, symbols[i], keptComdats, irSym, *this);
+      createBitcodeSymbol(ctx, symbols[i], irSym, *this);
 
   for (auto l : obj->getDependentLibraries())
     addDependentLibrary(ctx, l, this);

diff  --git a/lld/test/ELF/lto/internalize-exportdyn.ll b/lld/test/ELF/lto/internalize-exportdyn.ll
index 7c670a548025f1..25e319269bbdb6 100644
--- a/lld/test/ELF/lto/internalize-exportdyn.ll
+++ b/lld/test/ELF/lto/internalize-exportdyn.ll
@@ -56,16 +56,19 @@ define linkonce_odr void @baz() {
 
 @use_baz = global ptr @baz
 
+;; Test comdat symbols that are prevailing in this module and non-prevailing in the other module.
 define void @ext_and_ext() local_unnamed_addr comdat {
   call void @foo(i64 1)
   ret void
 }
 
+;; linkonce_odr in this module and external in the other module.
 define linkonce_odr void @lo_and_ext() local_unnamed_addr comdat {
   call void @foo(i64 1)
   ret void
 }
 
+;; linkonce_odr in this module and weak_odr in the other module.
 define linkonce_odr void @lo_and_wo() local_unnamed_addr comdat {
   ret void
 }
@@ -92,7 +95,7 @@ define weak_odr void @wo_and_lo() local_unnamed_addr comdat {
 ; CHECK-NEXT: call void @foo(i64 1)
 ; CHECK: define internal void @lo_and_ext() comdat
 ; CHECK-NEXT: call void @foo(i64 1)
-; CHECK: define internal void @lo_and_wo() comdat
+; CHECK: define weak_odr dso_local void @lo_and_wo() comdat
 ; CHECK: define weak_odr dso_local void @wo_and_lo() comdat
 
 ; DSO: @c = weak_odr constant i32 1
@@ -110,7 +113,7 @@ define weak_odr void @wo_and_lo() local_unnamed_addr comdat {
 ; DSO: define weak_odr void @baz()
 ; DSO: define void @ext_and_ext() comdat
 ; DSO: define internal void @lo_and_ext() comdat
-; DSO: define internal void @lo_and_wo() comdat
+; DSO: define weak_odr void @lo_and_wo() comdat
 ; DSO: define weak_odr void @wo_and_lo() comdat
 
 ;--- lib.s


        


More information about the llvm-commits mailing list