[lld] [LLD] [COFF] Handle undefined weak symbols in LTO (PR #70430)

via llvm-commits llvm-commits at lists.llvm.org
Fri Oct 27 02:02:52 PDT 2023


llvmbot wrote:


<!--LLVM PR SUMMARY COMMENT-->

@llvm/pr-subscribers-lld-coff

Author: Martin Storsjö (mstorsjo)

<details>
<summary>Changes</summary>

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, 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.

---
Full diff: https://github.com/llvm/llvm-project/pull/70430.diff


2 Files Affected:

- (modified) lld/COFF/InputFiles.cpp (+2) 
- (added) lld/test/COFF/lto-weak-undefined.ll (+34) 


``````````diff
diff --git a/lld/COFF/InputFiles.cpp b/lld/COFF/InputFiles.cpp
index 38ce29e6ab68c04..b5db6d2e1613d75 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..408d4342431baa7
--- /dev/null
+++ b/lld/test/COFF/lto-weak-undefined.ll
@@ -0,0 +1,34 @@
+; REQUIRES: x86
+
+; 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
+}

``````````

</details>


https://github.com/llvm/llvm-project/pull/70430


More information about the llvm-commits mailing list