[lld] b062fe1 - [lld][WebAssembly] Fail if bitcode objects are pulled in after LTO

Sam Clegg via llvm-commits llvm-commits at lists.llvm.org
Tue Feb 11 17:43:50 PST 2020


Author: Sam Clegg
Date: 2020-02-11T17:36:15-08:00
New Revision: b062fe181625bd1944ca9ca2a58246ffd7cd3536

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

LOG: [lld][WebAssembly] Fail if bitcode objects are pulled in after LTO

This can happen if lto::LTO::getRuntimeLibcallSymbols doesn't return
an complete/accurate list of libcalls.  In this case new bitcode
object can be linked in after LTO.

For example the WebAssembly backend currently calls:
  setLibcallName(RTLIB::FPROUND_F32_F16, "__truncsfhf2");

But `__truncsfhf2` is not part of `getRuntimeLibcallSymbols` so if
this symbol is generated during LTO the link will currently fail.

Without this change the linker crashes because the bitcode symbol
makes it all the way to the output phase.

See: https://bugs.llvm.org/show_bug.cgi?id=44353

Differential Revision: https://reviews.llvm.org/D71632

Added: 
    lld/test/wasm/lto/Inputs/libcall-truncsfhf2.ll
    lld/test/wasm/lto/libcall-truncsfhf2.ll

Modified: 
    lld/wasm/InputFiles.cpp
    lld/wasm/InputFiles.h
    lld/wasm/SymbolTable.cpp

Removed: 
    


################################################################################
diff  --git a/lld/test/wasm/lto/Inputs/libcall-truncsfhf2.ll b/lld/test/wasm/lto/Inputs/libcall-truncsfhf2.ll
new file mode 100644
index 000000000000..839890ee1d9a
--- /dev/null
+++ b/lld/test/wasm/lto/Inputs/libcall-truncsfhf2.ll
@@ -0,0 +1,6 @@
+target datalayout = "e-m:e-p:32:32-i64:64-n32:64-S128"
+target triple = "wasm32-unknown-unknown"
+
+define half @__truncsfhf2(float) {
+  ret half 0.0
+}

diff  --git a/lld/test/wasm/lto/libcall-truncsfhf2.ll b/lld/test/wasm/lto/libcall-truncsfhf2.ll
new file mode 100644
index 000000000000..a427acd139d8
--- /dev/null
+++ b/lld/test/wasm/lto/libcall-truncsfhf2.ll
@@ -0,0 +1,20 @@
+; RUN: llvm-as %s -o %t.o
+; RUN: llvm-as %p/Inputs/libcall-truncsfhf2.ll -o %t.truncsfhf2.o
+; RUN: rm -f %t.a
+; RUN: llvm-ar rcs %t.a %t.truncsfhf2.o
+; RUN: not wasm-ld --export-all %t.o %t.a -o %t.wasm 2>&1 | FileCheck %s
+
+target datalayout = "e-m:e-p:32:32-i64:64-n32:64-S128"
+target triple = "wasm32-unknown-unknown"
+
+ at g_float = global float 0.0
+ at g_half = global half 0.0
+
+define void @_start() {
+  %val1 = load float, float* @g_float
+  %v0 = fptrunc float %val1 to half
+  store half %v0, half* @g_half
+  ret void
+}
+
+; CHECK: wasm-ld: error: {{.*}}truncsfhf2.o: attempt to add bitcode file after LTO.

diff  --git a/lld/wasm/InputFiles.cpp b/lld/wasm/InputFiles.cpp
index 2d96062739dc..d71a2b4f083d 100644
--- a/lld/wasm/InputFiles.cpp
+++ b/lld/wasm/InputFiles.cpp
@@ -536,7 +536,15 @@ static Symbol *createBitcodeSymbol(const std::vector<bool> &keptComdats,
   return symtab->addDefinedData(name, flags, &f, nullptr, 0, 0);
 }
 
+bool BitcodeFile::doneLTO = false;
+
 void BitcodeFile::parse() {
+  if (doneLTO) {
+    error(toString(mb.getBufferIdentifier()) +
+          ": attempt to add bitcode file after LTO.");
+    return;
+  }
+
   obj = check(lto::InputFile::create(MemoryBufferRef(
       mb.getBuffer(), saver.save(archiveName + mb.getBufferIdentifier()))));
   Triple t(obj->getTargetTriple());

diff  --git a/lld/wasm/InputFiles.h b/lld/wasm/InputFiles.h
index d5aebf46b477..bf4a4ec99abf 100644
--- a/lld/wasm/InputFiles.h
+++ b/lld/wasm/InputFiles.h
@@ -160,6 +160,10 @@ class BitcodeFile : public InputFile {
 
   void parse();
   std::unique_ptr<llvm::lto::InputFile> obj;
+
+  // Set to true once LTO is complete in order prevent further bitcode objects
+  // being added.
+  static bool doneLTO;
 };
 
 inline bool isBitcode(MemoryBufferRef mb) {

diff  --git a/lld/wasm/SymbolTable.cpp b/lld/wasm/SymbolTable.cpp
index 3c1acbd2c68f..ce74b6ad7ea5 100644
--- a/lld/wasm/SymbolTable.cpp
+++ b/lld/wasm/SymbolTable.cpp
@@ -65,6 +65,9 @@ void SymbolTable::addFile(InputFile *file) {
 // Because all bitcode files that the program consists of are passed
 // to the compiler at once, it can do whole-program optimization.
 void SymbolTable::addCombinedLTOObject() {
+  // Prevent further LTO objects being included
+  BitcodeFile::doneLTO = true;
+
   if (bitcodeFiles.empty())
     return;
 


        


More information about the llvm-commits mailing list