[lld] 1d95a07 - [LLD] [COFF] Handle undefined weak symbols in LTO (#70430)

via llvm-commits llvm-commits at lists.llvm.org
Sun Nov 5 14:00:28 PST 2023


Author: Martin Storsjö
Date: 2023-11-06T00:00:24+02:00
New Revision: 1d95a071d6fc43fb413a0d3f5a9d1e52a18abab0

URL: https://github.com/llvm/llvm-project/commit/1d95a071d6fc43fb413a0d3f5a9d1e52a18abab0
DIFF: https://github.com/llvm/llvm-project/commit/1d95a071d6fc43fb413a0d3f5a9d1e52a18abab0.diff

LOG: [LLD] [COFF] Handle undefined weak symbols in LTO (#70430)

When reading the bitcode input, undefined weak symbols will show up as
undefined symbols - which fails the early pass of checking for missing
symbols in symtab.reportUnresolvable(), before doing the actual LTO
compilation.

Mark such symbols as deferUndefined (added in
3785a413feef896e8a022731cc6ed405d5ebe81b /
https://reviews.llvm.org/D89004 for the -wrap option), to let them pass
through this LTO precheck. After the LTO compilation, the weak undefined
symbols will point towards an absolute null symbol as default.

Such weak undefined symbols are used for the TLS init function in the
Itanium C++ ABI, for TLS variables that potentially need to run a
constructor, when accessed across translation units.

This fixes https://github.com/llvm/llvm-project/issues/64513.

Added: 
    lld/test/COFF/lto-weak-undefined.ll

Modified: 
    lld/COFF/InputFiles.cpp

Removed: 
    


################################################################################
diff  --git a/lld/COFF/InputFiles.cpp b/lld/COFF/InputFiles.cpp
index 3ae05f42ac5ff63..79d0ed62307ba23 100644
--- a/lld/COFF/InputFiles.cpp
+++ b/lld/COFF/InputFiles.cpp
@@ -1040,6 +1040,8 @@ void BitcodeFile::parse() {
       fakeSC = &ctx.ltoDataSectionChunk.chunk;
     if (objSym.isUndefined()) {
       sym = ctx.symtab.addUndefined(symName, this, false);
+      if (objSym.isWeak())
+        sym->deferUndefined = true;
     } else if (objSym.isCommon()) {
       sym = ctx.symtab.addCommon(this, symName, objSym.getCommonSize());
     } else if (objSym.isWeak() && objSym.isIndirect()) {

diff  --git a/lld/test/COFF/lto-weak-undefined.ll b/lld/test/COFF/lto-weak-undefined.ll
new file mode 100644
index 000000000000000..037ecc2b1209b16
--- /dev/null
+++ b/lld/test/COFF/lto-weak-undefined.ll
@@ -0,0 +1,40 @@
+; REQUIRES: x86
+
+;; Test linking of weak symbols with LTO. The weak symbol may be defined
+;; by another object file, or may be left undefined. When compiling the
+;; IR with an undefined weak symbol, the emitted object file will contain
+;; a weak alias pointing at an absolute symbol for the address null.
+;; Make sure both cases can be linked correctly.
+
+; RUN: split-file %s %t.dir
+; RUN: llvm-as %t.dir/main.ll -o %t.main.obj
+; RUN: llvm-as %t.dir/optional.ll -o %t.optional.obj
+
+; RUN: lld-link /entry:main %t.main.obj /out:%t-undef.exe
+; RUN: lld-link /entry:main %t.main.obj %t.optional.obj /out:%t-def.exe
+
+;--- main.ll
+target datalayout = "e-m:w-p270:32:32-p271:32:32-p272:64:64-i64:64-f80:128-n8:16:32:64-S128"
+target triple = "x86_64-pc-windows-msvc"
+
+define dso_local i32 @main() {
+entry:
+  br i1 icmp ne (ptr @optionalFunc, ptr null), label %if.then, label %if.end
+
+if.then:
+  tail call void @optionalFunc()
+  br label %if.end
+
+if.end:
+  ret i32 0
+}
+
+declare extern_weak void @optionalFunc()
+
+;--- optional.ll
+target datalayout = "e-m:w-p270:32:32-p271:32:32-p272:64:64-i64:64-f80:128-n8:16:32:64-S128"
+target triple = "x86_64-pc-windows-msvc"
+
+define void @optionalFunc() {
+  ret void
+}


        


More information about the llvm-commits mailing list