[WebAssembly] Fix signatures of undefined function in LTO object which are not called...
authorSam Clegg <sbc@chromium.org>
Wed, 29 May 2019 15:36:42 +0000 (15:36 +0000)
committerSam Clegg <sbc@chromium.org>
Wed, 29 May 2019 15:36:42 +0000 (15:36 +0000)
We recently added special handling for function that are not called
directly but failed to add testing for the LTO case.

See https://reviews.llvm.org/D62153

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

llvm-svn: 361975

lld/test/wasm/lto/undef.ll
lld/wasm/SymbolTable.cpp

index 729007b..65e8e46 100644 (file)
@@ -5,10 +5,22 @@
 target datalayout = "e-m:e-p:32:32-i64:64-n32:64-S128"
 target triple = "wasm32-unknown-unknown"
 
-declare void @bar()
+declare i32 @bar()
+
+; Symbols such as foo which are only called indirectly are handled slightly
+; differently with resepect to signature checking.
+declare i32 @foo()
+
+@ptr = global i8* bitcast (i32 ()* @foo to i8*), align 8
+; Ensure access to ptr is not inlined below, even under LTO
+@llvm.used = appending global [1 x i8**] [i8** @ptr], section "llvm.metadata"
 
 define void @_start() {
-  call void @bar()
+  call i32 @bar()
+
+  %addr = load i32 ()*, i32 ()** bitcast (i8** @ptr to i32 ()**), align 8
+  call i32 %addr()
+
   ret void
 }
 
@@ -18,3 +30,7 @@ define void @_start() {
 ; CHECK-NEXT:        Field:           bar
 ; CHECK-NEXT:        Kind:            FUNCTION
 ; CHECK-NEXT:        SigIndex:        0
+; CHECK-NEXT:      - Module:          env
+; CHECK-NEXT:        Field:           foo
+; CHECK-NEXT:        Kind:            FUNCTION
+; CHECK-NEXT:        SigIndex:        0
index ae42474..dec59cb 100644 (file)
@@ -136,14 +136,13 @@ static void reportTypeError(const Symbol *Existing, const InputFile *File,
 // mismatch.
 static bool signatureMatches(FunctionSymbol *Existing,
                              const WasmSignature *NewSig) {
-  if (!NewSig)
-    return true;
-
   const WasmSignature *OldSig = Existing->Signature;
-  if (!OldSig) {
-    Existing->Signature = NewSig;
+
+  // If either function is missing a signature (this happend for bitcode
+  // symbols) then assume they match.  Any mismatch will be reported later
+  // when the LTO objects are added.
+  if (!NewSig || !OldSig)
     return true;
-  }
 
   return *NewSig == *OldSig;
 }
@@ -390,8 +389,9 @@ Symbol *SymbolTable::addUndefinedFunction(StringRef Name, StringRef ImportName,
                                           uint32_t Flags, InputFile *File,
                                           const WasmSignature *Sig,
                                           bool IsCalledDirectly) {
-  LLVM_DEBUG(dbgs() << "addUndefinedFunction: " << Name <<
-             " [" << (Sig ? toString(*Sig) : "none") << "]\n");
+  LLVM_DEBUG(dbgs() << "addUndefinedFunction: " << Name << " ["
+                    << (Sig ? toString(*Sig) : "none")
+                    << "] IsCalledDirectly:" << IsCalledDirectly << "\n");
 
   Symbol *S;
   bool WasInserted;
@@ -414,6 +414,8 @@ Symbol *SymbolTable::addUndefinedFunction(StringRef Name, StringRef ImportName,
       reportTypeError(S, File, WASM_SYMBOL_TYPE_FUNCTION);
       return S;
     }
+    if (!ExistingFunction->Signature && Sig)
+      ExistingFunction->Signature = Sig;
     if (IsCalledDirectly && !signatureMatches(ExistingFunction, Sig))
       if (getFunctionVariant(S, Sig, File, &S))
         Replace();