https://github.com/ppenzin updated https://github.com/llvm/llvm-project/pull/178720
>From a81b640f7a648b3d82409ba38eea09271714d8f1 Mon Sep 17 00:00:00 2001 From: Demetrius Kanios <[email protected]> Date: Thu, 29 Jan 2026 00:54:20 -0800 Subject: [PATCH 1/3] Change `QualType::isWebAssemblyFuncrefType` to accept types attributed with `WebAssemblyFuncref` --- clang/lib/AST/Type.cpp | 3 ++- clang/test/CodeGen/WebAssembly/builtins-table.c | 17 +++++++++++++++++ 2 files changed, 19 insertions(+), 1 deletion(-) diff --git a/clang/lib/AST/Type.cpp b/clang/lib/AST/Type.cpp index 53082bcf78f6a..8cbe49a23c13d 100644 --- a/clang/lib/AST/Type.cpp +++ b/clang/lib/AST/Type.cpp @@ -2947,7 +2947,8 @@ bool QualType::isWebAssemblyExternrefType() const { bool QualType::isWebAssemblyFuncrefType() const { return getTypePtr()->isFunctionPointerType() && - getAddressSpace() == LangAS::wasm_funcref; + (getAddressSpace() == LangAS::wasm_funcref || + getTypePtr()->hasAttr(attr::WebAssemblyFuncref)); } QualType::PrimitiveDefaultInitializeKind diff --git a/clang/test/CodeGen/WebAssembly/builtins-table.c b/clang/test/CodeGen/WebAssembly/builtins-table.c index 74bb2442fe552..4069da2c4c225 100644 --- a/clang/test/CodeGen/WebAssembly/builtins-table.c +++ b/clang/test/CodeGen/WebAssembly/builtins-table.c @@ -65,3 +65,20 @@ static __externref_t other_table[0]; void test_table_copy(int dst_idx, int src_idx, int nelem) { __builtin_wasm_table_copy(table, other_table, dst_idx, src_idx, nelem); } + + +typedef void (*__funcref funcref_t)(); +static funcref_t funcref_table[0]; + +// CHECK-LABEL: define {{[^@]+}}@test_funcref_table +// CHECK-SAME: (ptr addrspace(20) noundef [[FUNCREF:%.*]], i32 noundef [[INDEX:%.*]]) #[[ATTR0]] { +// CHECK-NEXT: entry: +// CHECK-NEXT: call void @llvm.wasm.table.set.funcref(ptr addrspace(1) @funcref_table, i32 [[INDEX]], ptr addrspace(20) [[FUNCREF]]) +// CHECK-NEXT: [[TMP0:%.*]] = call ptr addrspace(20) @llvm.wasm.table.get.funcref(ptr addrspace(1) @funcref_table, i32 [[INDEX]]) +// CHECK-NEXT: ret ptr addrspace(20) [[TMP0]] +// +funcref_t test_funcref_table(funcref_t funcref, int index) { + __builtin_wasm_table_set(funcref_table, index, funcref); + + return __builtin_wasm_table_get(funcref_table, index); +} >From 9bb0dfce3e091b7ba74777e05352787f112b8065 Mon Sep 17 00:00:00 2001 From: Demetrius Kanios <[email protected]> Date: Thu, 29 Jan 2026 15:01:28 -0800 Subject: [PATCH 2/3] Alternative approach --- clang/lib/AST/Type.cpp | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/clang/lib/AST/Type.cpp b/clang/lib/AST/Type.cpp index 8cbe49a23c13d..dcdbb62f9d62b 100644 --- a/clang/lib/AST/Type.cpp +++ b/clang/lib/AST/Type.cpp @@ -2947,8 +2947,8 @@ bool QualType::isWebAssemblyExternrefType() const { bool QualType::isWebAssemblyFuncrefType() const { return getTypePtr()->isFunctionPointerType() && - (getAddressSpace() == LangAS::wasm_funcref || - getTypePtr()->hasAttr(attr::WebAssemblyFuncref)); + (getTypePtr()->getPointeeType().getAddressSpace() == + LangAS::wasm_funcref); } QualType::PrimitiveDefaultInitializeKind >From c93e4544dfc7a9d0dcb3bacec26a158bc2370b6f Mon Sep 17 00:00:00 2001 From: Demetrius Kanios <[email protected]> Date: Fri, 30 Jan 2026 12:27:35 -0800 Subject: [PATCH 3/3] Improve tests. Fix `__builtin_wasm_table_grow` for funcref. --- .../CodeGen/TargetBuiltins/WebAssembly.cpp | 4 +- ...ins-table.c => builtins-table-externref.c} | 17 ----- .../WebAssembly/builtins-table-funcref.c | 69 +++++++++++++++++++ clang/test/Sema/wasm-funcref-table.c | 18 +++++ 4 files changed, 89 insertions(+), 19 deletions(-) rename clang/test/CodeGen/WebAssembly/{builtins-table.c => builtins-table-externref.c} (80%) create mode 100644 clang/test/CodeGen/WebAssembly/builtins-table-funcref.c create mode 100644 clang/test/Sema/wasm-funcref-table.c diff --git a/clang/lib/CodeGen/TargetBuiltins/WebAssembly.cpp b/clang/lib/CodeGen/TargetBuiltins/WebAssembly.cpp index 1a1889a4139d3..edaba6e5998fc 100644 --- a/clang/lib/CodeGen/TargetBuiltins/WebAssembly.cpp +++ b/clang/lib/CodeGen/TargetBuiltins/WebAssembly.cpp @@ -633,8 +633,8 @@ Value *CodeGenFunction::EmitWebAssemblyBuiltinExpr(unsigned BuiltinID, Function *Callee; if (E->getArg(1)->getType().isWebAssemblyExternrefType()) Callee = CGM.getIntrinsic(Intrinsic::wasm_table_grow_externref); - else if (E->getArg(2)->getType().isWebAssemblyFuncrefType()) - Callee = CGM.getIntrinsic(Intrinsic::wasm_table_fill_funcref); + else if (E->getArg(1)->getType().isWebAssemblyFuncrefType()) + Callee = CGM.getIntrinsic(Intrinsic::wasm_table_grow_funcref); else llvm_unreachable( "Unexpected reference type for __builtin_wasm_table_grow"); diff --git a/clang/test/CodeGen/WebAssembly/builtins-table.c b/clang/test/CodeGen/WebAssembly/builtins-table-externref.c similarity index 80% rename from clang/test/CodeGen/WebAssembly/builtins-table.c rename to clang/test/CodeGen/WebAssembly/builtins-table-externref.c index 4069da2c4c225..74bb2442fe552 100644 --- a/clang/test/CodeGen/WebAssembly/builtins-table.c +++ b/clang/test/CodeGen/WebAssembly/builtins-table-externref.c @@ -65,20 +65,3 @@ static __externref_t other_table[0]; void test_table_copy(int dst_idx, int src_idx, int nelem) { __builtin_wasm_table_copy(table, other_table, dst_idx, src_idx, nelem); } - - -typedef void (*__funcref funcref_t)(); -static funcref_t funcref_table[0]; - -// CHECK-LABEL: define {{[^@]+}}@test_funcref_table -// CHECK-SAME: (ptr addrspace(20) noundef [[FUNCREF:%.*]], i32 noundef [[INDEX:%.*]]) #[[ATTR0]] { -// CHECK-NEXT: entry: -// CHECK-NEXT: call void @llvm.wasm.table.set.funcref(ptr addrspace(1) @funcref_table, i32 [[INDEX]], ptr addrspace(20) [[FUNCREF]]) -// CHECK-NEXT: [[TMP0:%.*]] = call ptr addrspace(20) @llvm.wasm.table.get.funcref(ptr addrspace(1) @funcref_table, i32 [[INDEX]]) -// CHECK-NEXT: ret ptr addrspace(20) [[TMP0]] -// -funcref_t test_funcref_table(funcref_t funcref, int index) { - __builtin_wasm_table_set(funcref_table, index, funcref); - - return __builtin_wasm_table_get(funcref_table, index); -} diff --git a/clang/test/CodeGen/WebAssembly/builtins-table-funcref.c b/clang/test/CodeGen/WebAssembly/builtins-table-funcref.c new file mode 100644 index 0000000000000..b4f729669a795 --- /dev/null +++ b/clang/test/CodeGen/WebAssembly/builtins-table-funcref.c @@ -0,0 +1,69 @@ +// NOTE: Assertions have been autogenerated by utils/update_cc_test_checks.py UTC_ARGS: --function-signature +// RUN: %clang_cc1 -triple wasm32 -target-feature +reference-types -disable-O0-optnone -emit-llvm %s -o - | opt -S -passes=mem2reg | FileCheck %s +// REQUIRES: webassembly-registered-target + +typedef void (*__funcref funcref_t)(); +static funcref_t table[0]; + +// CHECK-LABEL: define {{[^@]+}}@test_builtin_wasm_table_get +// CHECK-SAME: (i32 noundef [[INDEX:%.*]]) #[[ATTR0:[0-9]+]] { +// CHECK-NEXT: entry: +// CHECK-NEXT: [[TMP0:%.*]] = call ptr addrspace(20) @llvm.wasm.table.get.funcref(ptr addrspace(1) @table, i32 [[INDEX]]) +// CHECK-NEXT: ret ptr addrspace(20) [[TMP0]] +// +funcref_t test_builtin_wasm_table_get(int index) { + return __builtin_wasm_table_get(table, index); +} + +// CHECK-LABEL: define {{[^@]+}}@test_builtin_wasm_table_set +// CHECK-SAME: (i32 noundef [[INDEX:%.*]], ptr addrspace(20) noundef [[REF:%.*]]) #[[ATTR0]] { +// CHECK-NEXT: entry: +// CHECK-NEXT: call void @llvm.wasm.table.set.funcref(ptr addrspace(1) @table, i32 [[INDEX]], ptr addrspace(20) [[REF]]) +// CHECK-NEXT: ret void +// +void test_builtin_wasm_table_set(int index, funcref_t ref) { + return __builtin_wasm_table_set(table, index, ref); +} + +// CHECK-LABEL: define {{[^@]+}}@test_builtin_wasm_table_size +// CHECK-SAME: () #[[ATTR0]] { +// CHECK-NEXT: entry: +// CHECK-NEXT: [[TMP0:%.*]] = call i32 @llvm.wasm.table.size(ptr addrspace(1) @table) +// CHECK-NEXT: ret i32 [[TMP0]] +// +int test_builtin_wasm_table_size() { + return __builtin_wasm_table_size(table); +} + + +// CHECK-LABEL: define {{[^@]+}}@test_builtin_wasm_table_grow +// CHECK-SAME: (ptr addrspace(20) noundef [[REF:%.*]], i32 noundef [[NELEM:%.*]]) #[[ATTR0]] { +// CHECK-NEXT: entry: +// CHECK-NEXT: [[TMP0:%.*]] = call i32 @llvm.wasm.table.grow.funcref(ptr addrspace(1) @table, ptr addrspace(20) [[REF]], i32 [[NELEM]]) +// CHECK-NEXT: ret i32 [[TMP0]] +// +int test_builtin_wasm_table_grow(funcref_t ref, int nelem) { + return __builtin_wasm_table_grow(table, ref, nelem); +} + +// CHECK-LABEL: define {{[^@]+}}@test_builtin_wasm_table_fill +// CHECK-SAME: (i32 noundef [[INDEX:%.*]], ptr addrspace(20) noundef [[REF:%.*]], i32 noundef [[NELEM:%.*]]) #[[ATTR0]] { +// CHECK-NEXT: entry: +// CHECK-NEXT: call void @llvm.wasm.table.fill.funcref(ptr addrspace(1) @table, i32 [[INDEX]], ptr addrspace(20) [[REF]], i32 [[NELEM]]) +// CHECK-NEXT: ret void +// +void test_builtin_wasm_table_fill(int index, funcref_t ref, int nelem) { + __builtin_wasm_table_fill(table, index, ref, nelem); +} + +static funcref_t other_table[0]; + +// CHECK-LABEL: define {{[^@]+}}@test_table_copy +// CHECK-SAME: (i32 noundef [[DST_IDX:%.*]], i32 noundef [[SRC_IDX:%.*]], i32 noundef [[NELEM:%.*]]) #[[ATTR0]] { +// CHECK-NEXT: entry: +// CHECK-NEXT: call void @llvm.wasm.table.copy(ptr addrspace(1) @table, ptr addrspace(1) @other_table, i32 [[SRC_IDX]], i32 [[DST_IDX]], i32 [[NELEM]]) +// CHECK-NEXT: ret void +// +void test_table_copy(int dst_idx, int src_idx, int nelem) { + __builtin_wasm_table_copy(table, other_table, dst_idx, src_idx, nelem); +} diff --git a/clang/test/Sema/wasm-funcref-table.c b/clang/test/Sema/wasm-funcref-table.c new file mode 100644 index 0000000000000..9b4d53b8bbf08 --- /dev/null +++ b/clang/test/Sema/wasm-funcref-table.c @@ -0,0 +1,18 @@ +// RUN: %clang_cc1 -triple wasm32 -target-feature +reference-types -fsyntax-only -verify %s + +typedef void (*__funcref fn_funcref)(void); + +// Valid funcref table declaration (zero-length, static) +static fn_funcref valid_table[0]; // no error expected + +// Invalid: non-zero length +static fn_funcref bad_table[1]; // expected-error {{only zero-length WebAssembly tables are currently supported}} + +// Array subscript on funcref table should be rejected +void test_subscript(void) { + (void)valid_table[0]; // expected-error {{cannot subscript a WebAssembly table}} +} + +// Original reproducer from https://github.com/llvm/llvm-project/issues/140933 +// The declaration should be rejected (not static, non-zero length) +extern fn_funcref issue_table[1]; // expected-error {{WebAssembly table must be static}} _______________________________________________ cfe-commits mailing list [email protected] https://lists.llvm.org/cgi-bin/mailman/listinfo/cfe-commits
