[PATCH] D120781: [IRLinker] materialize Functions before moving any

Nick Desaulniers via Phabricator via llvm-commits llvm-commits at lists.llvm.org
Tue Mar 1 15:16:15 PST 2022


nickdesaulniers created this revision.
nickdesaulniers added reviewers: dexonsmith, ricky, tejohnson, MaskRay, void.
Herald added a subscriber: hiraditya.
Herald added a project: All.
nickdesaulniers requested review of this revision.
Herald added a project: LLVM.
Herald added a subscriber: llvm-commits.

IRLinker builds a work list of functions to materialize, then moves them
from a source module to a destination module one at a time.

This is a problem for blockaddress Constants, since they need not refer
to the function they are used in; IPSCCP is quite good at sinking these
constants deep into other functions when passed as arguments.

This would lead to curious errors during LTO:

  ld.lld: error: Never resolved function from blockaddress ...

based on the ordering of function definitions in IR.

The problem was that IRLinker would basically do:

for function f in worklist:

  materialize f
  splice f from source module to destination module

This confuses BitcodeReader, which cannot disambiguate whether a
blockaddress is referring to a function which has not yet been parsed
("materialized") or is simply empty because its body was spliced out.
This causes BitcodeReader to insert Functions into its BasicBlockFwdRefs
list incorrectly, as it will never re-materialize an already
materialized (but spliced out) function.

This patch modifies the above loop to materialize functions from the
worklist first, then start splicing via re-mapping.
IRLinker::linkFunctionBody() will already try to materialize these
functions, we just need to do so sooner in order to avoid this ordering
related issue with blockaddresses.

Fixes: https://github.com/llvm/llvm-project/issues/52787
Fixes: https://github.com/ClangBuiltLinux/linux/issues/1215


Repository:
  rG LLVM Github Monorepo

https://reviews.llvm.org/D120781

Files:
  llvm/lib/Linker/IRMover.cpp
  llvm/test/Linker/blockaddress.ll


Index: llvm/test/Linker/blockaddress.ll
===================================================================
--- /dev/null
+++ llvm/test/Linker/blockaddress.ll
@@ -0,0 +1,55 @@
+; RUN: llvm-as %s -o %t.bc
+; RUN: llvm-link %t.bc 2>&1 | FileCheck %s
+
+; CHECK-NOT: Never resolved function from blockaddress
+
+declare void @f(i8*)
+
+; Test that a blockaddress in @y referring to %label in @x can be moved when @y
+; appears after @x.
+define void @x() {
+  br label %label
+
+label:
+  call void @y()
+  ret void
+}
+
+define void @y() {
+  call void @f(i8* blockaddress(@x, %label))
+  ret void
+}
+
+; Test that a blockaddress in @a referring to %label in @b can be moved when @a
+; appears after @b.
+define void @a() {
+  call void @f(i8* blockaddress(@b, %label))
+  ret void
+}
+
+define void @b() {
+  br label %label
+
+label:
+  call void @a()
+  ret void
+}
+
+; Test that @c and @d can both have blockaddress Constants that refer to one
+; another.
+
+define void @c() {
+  br label %label
+
+label:
+  call void @f(i8* blockaddress(@d, %label))
+  ret void
+}
+
+define void @d() {
+  br label %label
+
+label:
+  call void @f(i8* blockaddress(@c, %label))
+  ret void
+}
Index: llvm/lib/Linker/IRMover.cpp
===================================================================
--- llvm/lib/Linker/IRMover.cpp
+++ llvm/lib/Linker/IRMover.cpp
@@ -1516,6 +1516,15 @@
   computeTypeMapping();
 
   std::reverse(Worklist.begin(), Worklist.end());
+
+  // Materialize all Functions in Worklist prior to remapping otherwise
+  // blockaddress Constants may fail to materialize during IR moving.
+  for (GlobalValue *GV : Worklist)
+    if (auto *F = dyn_cast<Function>(GV))
+      if (!F->isDeclaration())
+        if (Error E = F->materialize())
+          return E;
+
   while (!Worklist.empty()) {
     GlobalValue *GV = Worklist.back();
     Worklist.pop_back();


-------------- next part --------------
A non-text attachment was scrubbed...
Name: D120781.412273.patch
Type: text/x-patch
Size: 1870 bytes
Desc: not available
URL: <http://lists.llvm.org/pipermail/llvm-commits/attachments/20220301/b757ea48/attachment.bin>


More information about the llvm-commits mailing list