[llvm] [WebAssembly] Define `__funcref_call_table` in generated asm and objects (PR #180900)

Demetrius Kanios via llvm-commits llvm-commits at lists.llvm.org
Thu Jun 11 22:42:52 PDT 2026


https://github.com/QuantumSegfault updated https://github.com/llvm/llvm-project/pull/180900

>From 8256b0278333cd4104c761c4753bc1abb0902728 Mon Sep 17 00:00:00 2001
From: Demetrius Kanios <demetrius at kanios.net>
Date: Thu, 11 Jun 2026 21:55:20 -0700
Subject: [PATCH 1/2] Define `__funcref_call_table` in generated asm and
 objects

---
 .../Target/WebAssembly/WebAssemblyAsmPrinter.cpp | 16 ++++++++++++++++
 llvm/test/CodeGen/WebAssembly/funcref-call.ll    |  1 +
 2 files changed, 17 insertions(+)

diff --git a/llvm/lib/Target/WebAssembly/WebAssemblyAsmPrinter.cpp b/llvm/lib/Target/WebAssembly/WebAssemblyAsmPrinter.cpp
index c25972343c96a..37eda16077bec 100644
--- a/llvm/lib/Target/WebAssembly/WebAssemblyAsmPrinter.cpp
+++ b/llvm/lib/Target/WebAssembly/WebAssemblyAsmPrinter.cpp
@@ -398,6 +398,22 @@ void WebAssemblyAsmPrinter::emitEndOfAsmFile(Module &M) {
   // emitDecls() is not called until now.
   emitDecls(M);
 
+  {
+    StringRef Name = "__funcref_call_table";
+    auto *Sym = static_cast<MCSymbolWasm *>(OutContext.lookupSymbol(Name));
+    if (Sym) {
+      if (!Sym->isFunctionTable())
+        OutContext.reportError(SMLoc(), "symbol is not a wasm funcref table");
+
+      if (Sym->isWeak()) {
+        OutStreamer->emitSymbolAttribute(Sym, MCSA_Weak);
+      }
+      if (!Sym->isDefined()) {
+        OutStreamer->emitLabel(Sym);
+        OutStreamer->addBlankLine();
+      }
+    }
+  }
   // When a function's address is taken, a TABLE_INDEX relocation is emitted
   // against the function symbol at the use site.  However the relocation
   // doesn't explicitly refer to the table.  In the future we may want to
diff --git a/llvm/test/CodeGen/WebAssembly/funcref-call.ll b/llvm/test/CodeGen/WebAssembly/funcref-call.ll
index 9904df2280e81..4f6025de4759c 100644
--- a/llvm/test/CodeGen/WebAssembly/funcref-call.ll
+++ b/llvm/test/CodeGen/WebAssembly/funcref-call.ll
@@ -1,6 +1,7 @@
 ; NOTE: Assertions have been autogenerated by utils/update_llc_test_checks.py
 ; RUN: llc < %s --mtriple=wasm32-unknown-unknown -fast-isel=0 -mattr=+reference-types | FileCheck %s
 ; RUN: llc < %s --mtriple=wasm32-unknown-unknown -fast-isel=1 -mattr=+reference-types | FileCheck %s
+; RUN: llc < %s --mtriple=wasm32-unknown-unknown --filetype=obj
 
 %funcref = type ptr addrspace(20) ;; addrspace 20 is nonintegral
 

>From 7b2714ca8a44ff727ff9d2967e10ce7d2d903c2c Mon Sep 17 00:00:00 2001
From: Demetrius Kanios <demetrius at kanios.net>
Date: Thu, 11 Jun 2026 22:38:37 -0700
Subject: [PATCH 2/2] Move definition to `emitDecls` and use asserts.

---
 .../WebAssembly/WebAssemblyAsmPrinter.cpp     | 32 +++++++++----------
 1 file changed, 16 insertions(+), 16 deletions(-)

diff --git a/llvm/lib/Target/WebAssembly/WebAssemblyAsmPrinter.cpp b/llvm/lib/Target/WebAssembly/WebAssemblyAsmPrinter.cpp
index 37eda16077bec..c78ca5fcda876 100644
--- a/llvm/lib/Target/WebAssembly/WebAssemblyAsmPrinter.cpp
+++ b/llvm/lib/Target/WebAssembly/WebAssemblyAsmPrinter.cpp
@@ -332,6 +332,22 @@ void WebAssemblyAsmPrinter::emitDecls(const Module &M) {
       emitSymbolType(Sym);
   }
 
+  {
+    StringRef Name = "__funcref_call_table";
+    auto *Sym = static_cast<MCSymbolWasm *>(OutContext.lookupSymbol(Name));
+    if (Sym) {
+      if (!Sym->isFunctionTable())
+        OutContext.reportError(SMLoc(), "symbol is not a wasm funcref table");
+
+      assert(Sym->isWeak());
+      assert(!Sym->isDefined());
+
+      OutStreamer->emitSymbolAttribute(Sym, MCSA_Weak);
+      OutStreamer->emitLabel(Sym);
+      OutStreamer->addBlankLine();
+    }
+  }
+
   DenseSet<MCSymbol *> InvokeSymbols;
   for (const auto &F : M) {
     if (F.isIntrinsic())
@@ -398,22 +414,6 @@ void WebAssemblyAsmPrinter::emitEndOfAsmFile(Module &M) {
   // emitDecls() is not called until now.
   emitDecls(M);
 
-  {
-    StringRef Name = "__funcref_call_table";
-    auto *Sym = static_cast<MCSymbolWasm *>(OutContext.lookupSymbol(Name));
-    if (Sym) {
-      if (!Sym->isFunctionTable())
-        OutContext.reportError(SMLoc(), "symbol is not a wasm funcref table");
-
-      if (Sym->isWeak()) {
-        OutStreamer->emitSymbolAttribute(Sym, MCSA_Weak);
-      }
-      if (!Sym->isDefined()) {
-        OutStreamer->emitLabel(Sym);
-        OutStreamer->addBlankLine();
-      }
-    }
-  }
   // When a function's address is taken, a TABLE_INDEX relocation is emitted
   // against the function symbol at the use site.  However the relocation
   // doesn't explicitly refer to the table.  In the future we may want to



More information about the llvm-commits mailing list