[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:38:50 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 63ba5fcdea33e9603c324faf605637f6746fe492 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 | 37 ++++++++++---------
1 file changed, 19 insertions(+), 18 deletions(-)
diff --git a/llvm/lib/Target/WebAssembly/WebAssemblyAsmPrinter.cpp b/llvm/lib/Target/WebAssembly/WebAssemblyAsmPrinter.cpp
index 37eda16077bec..8f9aaebb72d9b 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
@@ -500,7 +500,7 @@ void WebAssemblyAsmPrinter::EmitProducerInfo(Module &M) {
OutStreamer->switchSection(Producers);
OutStreamer->emitULEB128IntValue(FieldCount);
for (auto &Producers : {std::make_pair("language", &Languages),
- std::make_pair("processed-by", &Tools)}) {
+ std::make_pair("processed-by", &Tools)}) {
if (Producers.second->empty())
continue;
OutStreamer->emitULEB128IntValue(strlen(Producers.first));
@@ -609,7 +609,8 @@ void WebAssemblyAsmPrinter::EmitFunctionAttributes(Module &M) {
// Emit a custom section for each unique attribute.
for (const auto &[Name, Symbols] : CustomSections) {
MCSectionWasm *CustomSection = OutContext.getWasmSection(
- ".custom_section.llvm.func_attr.annotate." + Name, SectionKind::getMetadata());
+ ".custom_section.llvm.func_attr.annotate." + Name,
+ SectionKind::getMetadata());
OutStreamer->pushSection();
OutStreamer->switchSection(CustomSection);
More information about the llvm-commits
mailing list