[lld] r343340 - [WebAssembly] Preserve function signatures during LTO

Sam Clegg via llvm-commits llvm-commits at lists.llvm.org
Fri Sep 28 09:50:14 PDT 2018


Author: sbc
Date: Fri Sep 28 09:50:14 2018
New Revision: 343340

URL: http://llvm.org/viewvc/llvm-project?rev=343340&view=rev
Log:
[WebAssembly] Preserve function signatures during LTO

With LTO when and undefined function (with a known signature)
in replaced by a defined bitcode function we were loosing the
signature information (since bitcode functions don't have
signatures).

With this change we preserve the original signature from the
undefined function and verify that the post LTO compiled
function has the correct signature.

This change improves the error handling in the case where
there is a signature mismatch with a function defined in
a bitcode file.

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

Added:
    lld/trunk/test/wasm/lto/signature-mismatch.ll
Modified:
    lld/trunk/wasm/LTO.cpp
    lld/trunk/wasm/SymbolTable.cpp

Added: lld/trunk/test/wasm/lto/signature-mismatch.ll
URL: http://llvm.org/viewvc/llvm-project/lld/trunk/test/wasm/lto/signature-mismatch.ll?rev=343340&view=auto
==============================================================================
--- lld/trunk/test/wasm/lto/signature-mismatch.ll (added)
+++ lld/trunk/test/wasm/lto/signature-mismatch.ll Fri Sep 28 09:50:14 2018
@@ -0,0 +1,19 @@
+; RUN: llc -filetype=obj -o %t.o %s
+; RUN: llvm-as %S/Inputs/archive.ll -o %t1.o
+; RUN: not wasm-ld --fatal-warnings %t.o %t1.o -o %t.wasm 2>&1 | FileCheck %s
+
+; Test that functions defined in bitcode correctly report signature
+; mistmaches with existing undefined sybmols in normal objects.
+
+target triple = "wasm32-unknown-unknown"
+
+; f is defined to take no argument in archive.ll which is compiled to bitcode
+declare void @f(i32);
+
+define void @_start() {
+  call void @f(i32 0)
+  ret void
+}
+
+; CHECK: >>> defined as (I32) -> void in {{.*}}signature-mismatch.ll.tmp1.o
+; CHECK: >>> defined as () -> void in lto.tmp

Modified: lld/trunk/wasm/LTO.cpp
URL: http://llvm.org/viewvc/llvm-project/lld/trunk/wasm/LTO.cpp?rev=343340&r1=343339&r2=343340&view=diff
==============================================================================
--- lld/trunk/wasm/LTO.cpp (original)
+++ lld/trunk/wasm/LTO.cpp Fri Sep 28 09:50:14 2018
@@ -72,10 +72,11 @@ BitcodeCompiler::BitcodeCompiler() : LTO
 BitcodeCompiler::~BitcodeCompiler() = default;
 
 static void undefine(Symbol *S) {
-  if (isa<DefinedFunction>(S))
-    replaceSymbol<UndefinedFunction>(S, S->getName(), 0);
+  if (auto F = dyn_cast<DefinedFunction>(S))
+    replaceSymbol<UndefinedFunction>(F, F->getName(), 0, F->getFile(),
+                                     F->FunctionType);
   else if (isa<DefinedData>(S))
-    replaceSymbol<UndefinedData>(S, S->getName(), 0);
+    replaceSymbol<UndefinedData>(S, S->getName(), 0, S->getFile());
   else
     llvm_unreachable("unexpected symbol kind");
 }

Modified: lld/trunk/wasm/SymbolTable.cpp
URL: http://llvm.org/viewvc/llvm-project/lld/trunk/wasm/SymbolTable.cpp?rev=343340&r1=343339&r2=343340&view=diff
==============================================================================
--- lld/trunk/wasm/SymbolTable.cpp (original)
+++ lld/trunk/wasm/SymbolTable.cpp Fri Sep 28 09:50:14 2018
@@ -201,7 +201,9 @@ static bool shouldReplace(const Symbol *
 Symbol *SymbolTable::addDefinedFunction(StringRef Name, uint32_t Flags,
                                         InputFile *File,
                                         InputFunction *Function) {
-  LLVM_DEBUG(dbgs() << "addDefinedFunction: " << Name << "\n");
+  LLVM_DEBUG(dbgs() << "addDefinedFunction: " << Name << " ["
+                    << (Function ? toString(Function->Signature) : "none")
+                    << "]\n");
   Symbol *S;
   bool WasInserted;
   std::tie(S, WasInserted) = insert(Name, File);
@@ -214,8 +216,16 @@ Symbol *SymbolTable::addDefinedFunction(
   if (Function)
     checkFunctionType(S, File, &Function->Signature);
 
-  if (shouldReplace(S, File, Flags))
-    replaceSymbol<DefinedFunction>(S, Name, Flags, File, Function);
+  if (shouldReplace(S, File, Flags)) {
+    // If the new defined function doesn't have signture (i.e. bitcode
+    // functions) but the old symbols does then preserve the old signature
+    const WasmSignature *OldSig = nullptr;
+    if (auto* F = dyn_cast<FunctionSymbol>(S))
+      OldSig = F->FunctionType;
+    auto NewSym = replaceSymbol<DefinedFunction>(S, Name, Flags, File, Function);
+    if (!NewSym->FunctionType)
+      NewSym->FunctionType = OldSig;
+  }
   return S;
 }
 
@@ -263,7 +273,8 @@ Symbol *SymbolTable::addDefinedGlobal(St
 Symbol *SymbolTable::addUndefinedFunction(StringRef Name, uint32_t Flags,
                                           InputFile *File,
                                           const WasmSignature *Sig) {
-  LLVM_DEBUG(dbgs() << "addUndefinedFunction: " << Name << "\n");
+  LLVM_DEBUG(dbgs() << "addUndefinedFunction: " << Name <<
+             " [" << (Sig ? toString(*Sig) : "none") << "]\n");
 
   Symbol *S;
   bool WasInserted;




More information about the llvm-commits mailing list