Skip to content

[LLD] [COFF] Handle undefined weak symbols in LTO #70430

New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Merged
merged 1 commit into from
Nov 5, 2023

Conversation

mstorsjo
Copy link
Member

@mstorsjo mstorsjo commented Oct 27, 2023

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 3785a41 / 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 #64513.

@llvmbot
Copy link
Member

llvmbot commented Oct 27, 2023

@llvm/pr-subscribers-lto
@llvm/pr-subscribers-lld
@llvm/pr-subscribers-platform-windows

@llvm/pr-subscribers-lld-coff

Author: Martin Storsjö (mstorsjo)

Changes

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 #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 --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
+}

@mstorsjo mstorsjo added the LTO Link time optimization (regular/full LTO or ThinLTO) label Oct 27, 2023
@mstorsjo
Copy link
Member Author

mstorsjo commented Nov 2, 2023

Ping

@ZequanWu ZequanWu removed their request for review November 3, 2023 19:05
@ZequanWu
Copy link
Contributor

ZequanWu commented Nov 3, 2023

I'm not familiar with that.

Copy link
Member

@MaskRay MaskRay left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I think this is correct.
Perhaps augment the description to say that deferUndefined from https://reviews.llvm.org/D89004 for -wrap is reused.

@@ -0,0 +1,34 @@
; REQUIRES: x86

Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Add a file-level comment about the purpose as this may be less intuitive.

Copy link
Member Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Thanks, I added this now.

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
3785a41 /
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 llvm#64513.
@mstorsjo
Copy link
Member Author

mstorsjo commented Nov 5, 2023

Perhaps augment the description to say that deferUndefined from https://reviews.llvm.org/D89004 for -wrap is reused.

Sure, will do that when landing it, thanks!

@mstorsjo mstorsjo merged commit 1d95a07 into llvm:main Nov 5, 2023
@mstorsjo mstorsjo deleted the lld-lto-weak branch November 5, 2023 22:00
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
lld:COFF lld LTO Link time optimization (regular/full LTO or ThinLTO) platform:windows
Projects
None yet
Development

Successfully merging this pull request may close these issues.

[LTO] [MinGW] Use of thread locals from different translation unit broken with LTO
4 participants