[lld] [lld][WebAssembly] Allow defining of arbitrary symbols types in LTO objects (PR #196552)

via llvm-commits llvm-commits at lists.llvm.org
Fri May 8 08:34:52 PDT 2026


llvmorg-github-actions[bot] wrote:


<!--LLVM PR SUMMARY COMMENT-->

@llvm/pr-subscribers-lld-wasm

Author: Sam Clegg (sbc100)

<details>
<summary>Changes</summary>

Bitcode files don't contains precise symbol type information so we always allow new defined symbols overwrite bitcode symbols rather than reporting type mismatches.

Fixes: #<!-- -->195311

---
Full diff: https://github.com/llvm/llvm-project/pull/196552.diff


3 Files Affected:

- (added) lld/test/wasm/lto/inline-asm-symbols.ll (+26) 
- (modified) lld/test/wasm/lto/signature-mismatch.ll (+3-3) 
- (modified) lld/wasm/SymbolTable.cpp (+20-2) 


``````````diff
diff --git a/lld/test/wasm/lto/inline-asm-symbols.ll b/lld/test/wasm/lto/inline-asm-symbols.ll
new file mode 100644
index 0000000000000..59695ccddf739
--- /dev/null
+++ b/lld/test/wasm/lto/inline-asm-symbols.ll
@@ -0,0 +1,26 @@
+; RUN: split-file %s %t
+; RUN: llvm-as %t/bitcode.ll -o %t/bitcode.o
+
+;; Test that a bitcode symbol defined in inline assembly (which wasm-ld
+;; initially guesses is a FUNCTION) can be replaced by the LTO-generated
+;; object symbol (which is correctly identified as a TAG) without error.
+; RUN: wasm-ld --export=foo %t/bitcode.o -o %t.wasm
+; RUN: obj2yaml %t.wasm | FileCheck %s
+
+; CHECK:  - Type:            TAG
+; CHECK:    TagTypes:        [ 1 ]
+; CHECK:  - Name:            foo
+; CHECK:    Kind:            TAG
+; CHECK:    Index:           0
+
+;--- bitcode.ll
+target datalayout = "e-m:e-p:32:32-p10:8:8-p20:8:8-i64:64-n32:64-S128-ni:1:10:20"
+target triple = "wasm32-unknown-unknown"
+
+module asm ".globl foo"
+module asm ".tagtype foo i32"
+module asm "foo:"
+
+define void @_start() {
+  ret void
+}
diff --git a/lld/test/wasm/lto/signature-mismatch.ll b/lld/test/wasm/lto/signature-mismatch.ll
index 6580c8cf71b33..58ec045a77981 100644
--- a/lld/test/wasm/lto/signature-mismatch.ll
+++ b/lld/test/wasm/lto/signature-mismatch.ll
@@ -1,6 +1,6 @@
 ; 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
+; RUN: llvm-as %S/Inputs/archive.ll -o %t.archive.o
+; RUN: not wasm-ld --fatal-warnings %t.o %t.archive.o -o %t.wasm 2>&1 | FileCheck %s
 
 ; Test that functions defined in bitcode correctly report signature
 ; mismatches with existing undefined sybmols in normal objects.
@@ -16,5 +16,5 @@ define void @_start() {
 }
 
 ; CHECK: error: function signature mismatch: f
-; CHECK: >>> defined as (i32) -> void in {{.*}}signature-mismatch.ll.tmp1.o
+; CHECK: >>> defined as (i32) -> void in {{.*}}signature-mismatch.ll.tmp.archive.o
 ; CHECK: >>> defined as () -> void in {{.*}}signature-mismatch.ll.tmp.wasm.lto.o
diff --git a/lld/wasm/SymbolTable.cpp b/lld/wasm/SymbolTable.cpp
index cda192323f067..00bba35287167 100644
--- a/lld/wasm/SymbolTable.cpp
+++ b/lld/wasm/SymbolTable.cpp
@@ -165,6 +165,10 @@ std::pair<Symbol *, bool> SymbolTable::insert(StringRef name,
   return {s, wasInserted};
 }
 
+static bool isBitcodeSymbol(const Symbol *symbol) {
+  return symbol->getFile() && symbol->getFile()->kind() == InputFile::BitcodeKind;
+}
+
 static void reportTypeError(const Symbol *existing, const InputFile *file,
                             llvm::wasm::WasmSymbolType type) {
   error("symbol type mismatch: " + toString(*existing) + "\n>>> defined as " +
@@ -192,6 +196,8 @@ static bool signatureMatches(FunctionSymbol *existing,
 static void checkGlobalType(const Symbol *existing, const InputFile *file,
                             const WasmGlobalType *newType) {
   if (!isa<GlobalSymbol>(existing)) {
+    if (isBitcodeSymbol(existing))
+      return;
     reportTypeError(existing, file, WASM_SYMBOL_TYPE_GLOBAL);
     return;
   }
@@ -206,12 +212,15 @@ static void checkGlobalType(const Symbol *existing, const InputFile *file,
 
 static void checkTagType(const Symbol *existing, const InputFile *file,
                          const WasmSignature *newSig) {
-  const auto *existingTag = dyn_cast<TagSymbol>(existing);
   if (!isa<TagSymbol>(existing)) {
+    if (isBitcodeSymbol(existing))
+      return;
     reportTypeError(existing, file, WASM_SYMBOL_TYPE_TAG);
     return;
   }
 
+  const auto *existingTag = cast<TagSymbol>(existing);
+
   const WasmSignature *oldSig = existingTag->signature;
   if (*newSig != *oldSig)
     warn("Tag signature mismatch: " + existing->getName() +
@@ -223,6 +232,8 @@ static void checkTagType(const Symbol *existing, const InputFile *file,
 static void checkTableType(const Symbol *existing, const InputFile *file,
                            const WasmTableType *newType) {
   if (!isa<TableSymbol>(existing)) {
+    if (isBitcodeSymbol(existing))
+      return;
     reportTypeError(existing, file, WASM_SYMBOL_TYPE_TABLE);
     return;
   }
@@ -237,8 +248,11 @@ static void checkTableType(const Symbol *existing, const InputFile *file,
 }
 
 static void checkDataType(const Symbol *existing, const InputFile *file) {
-  if (!isa<DataSymbol>(existing))
+  if (!isa<DataSymbol>(existing)) {
+    if (isBitcodeSymbol(existing))
+      return;
     reportTypeError(existing, file, WASM_SYMBOL_TYPE_DATA);
+  }
 }
 
 DefinedFunction *SymbolTable::addSyntheticFunction(StringRef name,
@@ -511,6 +525,10 @@ Symbol *SymbolTable::addDefinedFunction(StringRef name, uint32_t flags,
 
   auto existingFunction = dyn_cast<FunctionSymbol>(s);
   if (!existingFunction) {
+    if (isBitcodeSymbol(s)) {
+      replaceSym(s);
+      return s;
+    }
     reportTypeError(s, file, WASM_SYMBOL_TYPE_FUNCTION);
     return s;
   }

``````````

</details>


https://github.com/llvm/llvm-project/pull/196552


More information about the llvm-commits mailing list