[clang] [WebAssembly][Clang] Add __builtin_wasm_ref_is_null_extern (PR #139580)
https://github.com/hoodmane edited https://github.com/llvm/llvm-project/pull/139580 ___ cfe-commits mailing list cfe-commits@lists.llvm.org https://lists.llvm.org/cgi-bin/mailman/listinfo/cfe-commits
[clang] [Wasm][Clang] Add __builtin_wasm_ref_is_null_extern (PR #139580)
https://github.com/hoodmane created https://github.com/llvm/llvm-project/pull/139580 I also fixed __builtin_wasm_ref_null_extern() to generate a diagnostic when it gets an argument. It seems like `SemaRef.checkArgCount()` has a bug that makes it unable to check for 0 args. cc @sbc100 @pmatos Rate limit · GitHub body { background-color: #f6f8fa; color: #24292e; font-family: -apple-system,BlinkMacSystemFont,Segoe UI,Helvetica,Arial,sans-serif,Apple Color Emoji,Segoe UI Emoji,Segoe UI Symbol; font-size: 14px; line-height: 1.5; margin: 0; } .container { margin: 50px auto; max-width: 600px; text-align: center; padding: 0 24px; } a { color: #0366d6; text-decoration: none; } a:hover { text-decoration: underline; } h1 { line-height: 60px; font-size: 48px; font-weight: 300; margin: 0px; text-shadow: 0 1px 0 #fff; } p { color: rgba(0, 0, 0, 0.5); margin: 20px 0 40px; } ul { list-style: none; margin: 25px 0; padding: 0; } li { display: table-cell; font-weight: bold; width: 1%; } .logo { display: inline-block; margin-top: 35px; } .logo-img-2x { display: none; } @media only screen and (-webkit-min-device-pixel-ratio: 2), only screen and ( min--moz-device-pixel-ratio: 2), only screen and ( -o-min-device-pixel-ratio: 2/1), only screen and (min-device-pixel-ratio: 2), only screen and (min-resolution: 192dpi), only screen and (min-resolution: 2dppx) { .logo-img-1x { display: none; } .logo-img-2x { display: inline-block; } } #suggestions { margin-top: 35px; color: #ccc; } #suggestions a { color: #66; font-weight: 200; font-size: 14px; margin: 0 10px; } Whoa there! You have exceeded a secondary rate limit. Please wait a few minutes before you try again; in some cases this may take up to an hour. https://support.github.com/contact";>Contact Support — https://githubstatus.com";>GitHub Status — https://twitter.com/githubstatus";>@githubstatus ___ cfe-commits mailing list cfe-commits@lists.llvm.org https://lists.llvm.org/cgi-bin/mailman/listinfo/cfe-commits
[clang] [Wasm][Clang] Add __builtin_wasm_ref_is_null_extern (PR #139580)
https://github.com/hoodmane updated https://github.com/llvm/llvm-project/pull/139580 >From 2ca282f0a20088bef15289a8ce5167d1e23595c3 Mon Sep 17 00:00:00 2001 From: Hood Chatham Date: Fri, 9 May 2025 00:16:26 -0400 Subject: [PATCH 1/2] [Wasm][Clang] Add __builtin_wasm_ref_is_null_extern I also fixed __builtin_wasm_ref_null_extern() to generate a diagnostic when it gets an argument. It seems like `SemaRef.checkArgCount()` has a bug that makes it unable to check for 0 args. --- .../clang/Basic/BuiltinsWebAssembly.def | 1 + .../clang/Basic/DiagnosticSemaKinds.td| 2 ++ clang/include/clang/Sema/SemaWasm.h | 1 + .../CodeGen/TargetBuiltins/WebAssembly.cpp| 5 clang/lib/Sema/SemaWasm.cpp | 26 +-- clang/test/CodeGen/builtins-wasm.c| 6 + clang/test/Sema/builtins-wasm.c | 4 +++ 7 files changed, 43 insertions(+), 2 deletions(-) diff --git a/clang/include/clang/Basic/BuiltinsWebAssembly.def b/clang/include/clang/Basic/BuiltinsWebAssembly.def index ab480369b3820..e2afcc08064b2 100644 --- a/clang/include/clang/Basic/BuiltinsWebAssembly.def +++ b/clang/include/clang/Basic/BuiltinsWebAssembly.def @@ -192,6 +192,7 @@ TARGET_BUILTIN(__builtin_wasm_replace_lane_f16x8, "V8hV8hIif", "nc", "fp16") // in which case the argument spec (second argument) is unused. TARGET_BUILTIN(__builtin_wasm_ref_null_extern, "i", "nct", "reference-types") +TARGET_BUILTIN(__builtin_wasm_ref_is_null_extern, "ii", "nct", "reference-types") // A funcref represented as a function pointer with the funcref attribute // attached to the type, therefore SemaChecking will check for the right diff --git a/clang/include/clang/Basic/DiagnosticSemaKinds.td b/clang/include/clang/Basic/DiagnosticSemaKinds.td index e5a7cdc14a737..d4abc46ae58ee 100644 --- a/clang/include/clang/Basic/DiagnosticSemaKinds.td +++ b/clang/include/clang/Basic/DiagnosticSemaKinds.td @@ -12991,6 +12991,8 @@ def err_wasm_reftype_multidimensional_array : Error< "multi-dimensional arrays of WebAssembly references are not allowed">; def err_wasm_builtin_arg_must_be_table_type : Error < "%ordinal0 argument must be a WebAssembly table">; +def err_wasm_builtin_arg_must_be_externref_type : Error < + "%ordinal0 argument must be an externref">; def err_wasm_builtin_arg_must_match_table_element_type : Error < "%ordinal0 argument must match the element type of the WebAssembly table in the %ordinal1 argument">; def err_wasm_builtin_arg_must_be_integer_type : Error < diff --git a/clang/include/clang/Sema/SemaWasm.h b/clang/include/clang/Sema/SemaWasm.h index 8841fdff23035..2123e073516cb 100644 --- a/clang/include/clang/Sema/SemaWasm.h +++ b/clang/include/clang/Sema/SemaWasm.h @@ -29,6 +29,7 @@ class SemaWasm : public SemaBase { CallExpr *TheCall); bool BuiltinWasmRefNullExtern(CallExpr *TheCall); + bool BuiltinWasmRefIsNullExtern(CallExpr *TheCall); bool BuiltinWasmRefNullFunc(CallExpr *TheCall); bool BuiltinWasmTableGet(CallExpr *TheCall); bool BuiltinWasmTableSet(CallExpr *TheCall); diff --git a/clang/lib/CodeGen/TargetBuiltins/WebAssembly.cpp b/clang/lib/CodeGen/TargetBuiltins/WebAssembly.cpp index 698f43215a1be..b7fd70e855d40 100644 --- a/clang/lib/CodeGen/TargetBuiltins/WebAssembly.cpp +++ b/clang/lib/CodeGen/TargetBuiltins/WebAssembly.cpp @@ -209,6 +209,11 @@ Value *CodeGenFunction::EmitWebAssemblyBuiltinExpr(unsigned BuiltinID, Function *Callee = CGM.getIntrinsic(Intrinsic::wasm_ref_null_extern); return Builder.CreateCall(Callee); } + case WebAssembly::BI__builtin_wasm_ref_is_null_extern: { +Value *Src = EmitScalarExpr(E->getArg(0)); +Function *Callee = CGM.getIntrinsic(Intrinsic::wasm_ref_is_null_extern); +return Builder.CreateCall(Callee, {Src}); + } case WebAssembly::BI__builtin_wasm_ref_null_func: { Function *Callee = CGM.getIntrinsic(Intrinsic::wasm_ref_null_func); return Builder.CreateCall(Callee); diff --git a/clang/lib/Sema/SemaWasm.cpp b/clang/lib/Sema/SemaWasm.cpp index c0fa05bc17609..4157e179c97d6 100644 --- a/clang/lib/Sema/SemaWasm.cpp +++ b/clang/lib/Sema/SemaWasm.cpp @@ -52,14 +52,34 @@ static bool CheckWasmBuiltinArgIsInteger(Sema &S, CallExpr *E, } bool SemaWasm::BuiltinWasmRefNullExtern(CallExpr *TheCall) { - if (TheCall->getNumArgs() != 0) + if (TheCall->getNumArgs() != 0) { +Diag(TheCall->getBeginLoc(), diag::err_typecheck_call_too_many_args) +<< 0 /*function call*/ << /*expected*/ 0 << TheCall->getNumArgs() +<< /*is non object*/ 0; return true; - + } TheCall->setType(getASTContext().getWebAssemblyExternrefType()); return false; } +bool SemaWasm::BuiltinWasmRefIsNullExtern(CallExpr *TheCall) { + if (SemaRef.checkArgCount(TheCall, 1)) { +return true; + } + + Expr *ArgExpr = TheCall->getArg(0); + if (!ArgExpr->getType().isWebAssemblyExternrefType()) { +SemaRef.Diag(ArgExpr->getBeginLoc(
[clang] [WebAssembly][Clang] Add __builtin_wasm_ref_is_null_extern (PR #139580)
@@ -52,14 +52,33 @@ static bool CheckWasmBuiltinArgIsInteger(Sema &S, CallExpr *E, } bool SemaWasm::BuiltinWasmRefNullExtern(CallExpr *TheCall) { - if (TheCall->getNumArgs() != 0) + if (TheCall->getNumArgs() != 0) { hoodmane wrote: Oh right, `getArg(1)` will fail if there is only one argument in the call expression. Okay I think I know how to fix this. https://github.com/llvm/llvm-project/pull/139580 ___ cfe-commits mailing list cfe-commits@lists.llvm.org https://lists.llvm.org/cgi-bin/mailman/listinfo/cfe-commits
[clang] [WebAssembly][Clang] Add __builtin_wasm_ref_is_null_extern (PR #139580)
https://github.com/hoodmane updated https://github.com/llvm/llvm-project/pull/139580 Rate limit · GitHub body { background-color: #f6f8fa; color: #24292e; font-family: -apple-system,BlinkMacSystemFont,Segoe UI,Helvetica,Arial,sans-serif,Apple Color Emoji,Segoe UI Emoji,Segoe UI Symbol; font-size: 14px; line-height: 1.5; margin: 0; } .container { margin: 50px auto; max-width: 600px; text-align: center; padding: 0 24px; } a { color: #0366d6; text-decoration: none; } a:hover { text-decoration: underline; } h1 { line-height: 60px; font-size: 48px; font-weight: 300; margin: 0px; text-shadow: 0 1px 0 #fff; } p { color: rgba(0, 0, 0, 0.5); margin: 20px 0 40px; } ul { list-style: none; margin: 25px 0; padding: 0; } li { display: table-cell; font-weight: bold; width: 1%; } .logo { display: inline-block; margin-top: 35px; } .logo-img-2x { display: none; } @media only screen and (-webkit-min-device-pixel-ratio: 2), only screen and ( min--moz-device-pixel-ratio: 2), only screen and ( -o-min-device-pixel-ratio: 2/1), only screen and (min-device-pixel-ratio: 2), only screen and (min-resolution: 192dpi), only screen and (min-resolution: 2dppx) { .logo-img-1x { display: none; } .logo-img-2x { display: inline-block; } } #suggestions { margin-top: 35px; color: #ccc; } #suggestions a { color: #66; font-weight: 200; font-size: 14px; margin: 0 10px; } Whoa there! You have exceeded a secondary rate limit. Please wait a few minutes before you try again; in some cases this may take up to an hour. https://support.github.com/contact";>Contact Support — https://githubstatus.com";>GitHub Status — https://twitter.com/githubstatus";>@githubstatus ___ cfe-commits mailing list cfe-commits@lists.llvm.org https://lists.llvm.org/cgi-bin/mailman/listinfo/cfe-commits
[clang] [WebAssembly][Clang] Add __builtin_wasm_ref_is_null_extern (PR #139580)
@@ -168,7 +168,7 @@ bool Sema::checkArgCount(CallExpr *Call, unsigned DesiredArgCount) { return Diag(Range.getBegin(), diag::err_typecheck_call_too_many_args) << 0 /*function call*/ << DesiredArgCount << ArgCount - << /*is non object*/ 0 << Call->getArg(1)->getSourceRange(); + << /*is non object*/ 0 << Range; hoodmane wrote: It seems to have fixed a real bug in the labeling: ```C $ clang -c a.c a.c:2:30: error: too many arguments to function call, expected 2, have 4 2 | __builtin_annotation(1, 2, 3, 4); | ~ ^ 1 error generated. $ ./bin/clang -c a.c a.c:2:30: error: too many arguments to function call, expected 2, have 4 2 | __builtin_annotation(1, 2, 3, 4); | ^~~~ 1 error generated. ``` https://github.com/llvm/llvm-project/pull/139580 ___ cfe-commits mailing list cfe-commits@lists.llvm.org https://lists.llvm.org/cgi-bin/mailman/listinfo/cfe-commits
[clang] [WebAssembly][Clang] Add __builtin_wasm_ref_is_null_extern (PR #139580)
https://github.com/hoodmane edited https://github.com/llvm/llvm-project/pull/139580 ___ cfe-commits mailing list cfe-commits@lists.llvm.org https://lists.llvm.org/cgi-bin/mailman/listinfo/cfe-commits
[clang] [WebAssembly][Clang] Add __builtin_wasm_ref_is_null_extern (PR #139580)
@@ -168,7 +168,7 @@ bool Sema::checkArgCount(CallExpr *Call, unsigned DesiredArgCount) { return Diag(Range.getBegin(), diag::err_typecheck_call_too_many_args) << 0 /*function call*/ << DesiredArgCount << ArgCount - << /*is non object*/ 0 << Call->getArg(1)->getSourceRange(); + << /*is non object*/ 0 << Range; hoodmane wrote: Should I split this change into a separate PR? https://github.com/llvm/llvm-project/pull/139580 ___ cfe-commits mailing list cfe-commits@lists.llvm.org https://lists.llvm.org/cgi-bin/mailman/listinfo/cfe-commits
[clang] [WebAssembly][Clang] Add __builtin_wasm_ref_is_null_extern (PR #139580)
https://github.com/hoodmane updated https://github.com/llvm/llvm-project/pull/139580 >From 2ca282f0a20088bef15289a8ce5167d1e23595c3 Mon Sep 17 00:00:00 2001 From: Hood Chatham Date: Fri, 9 May 2025 00:16:26 -0400 Subject: [PATCH 1/3] [Wasm][Clang] Add __builtin_wasm_ref_is_null_extern I also fixed __builtin_wasm_ref_null_extern() to generate a diagnostic when it gets an argument. It seems like `SemaRef.checkArgCount()` has a bug that makes it unable to check for 0 args. --- .../clang/Basic/BuiltinsWebAssembly.def | 1 + .../clang/Basic/DiagnosticSemaKinds.td| 2 ++ clang/include/clang/Sema/SemaWasm.h | 1 + .../CodeGen/TargetBuiltins/WebAssembly.cpp| 5 clang/lib/Sema/SemaWasm.cpp | 26 +-- clang/test/CodeGen/builtins-wasm.c| 6 + clang/test/Sema/builtins-wasm.c | 4 +++ 7 files changed, 43 insertions(+), 2 deletions(-) diff --git a/clang/include/clang/Basic/BuiltinsWebAssembly.def b/clang/include/clang/Basic/BuiltinsWebAssembly.def index ab480369b3820..e2afcc08064b2 100644 --- a/clang/include/clang/Basic/BuiltinsWebAssembly.def +++ b/clang/include/clang/Basic/BuiltinsWebAssembly.def @@ -192,6 +192,7 @@ TARGET_BUILTIN(__builtin_wasm_replace_lane_f16x8, "V8hV8hIif", "nc", "fp16") // in which case the argument spec (second argument) is unused. TARGET_BUILTIN(__builtin_wasm_ref_null_extern, "i", "nct", "reference-types") +TARGET_BUILTIN(__builtin_wasm_ref_is_null_extern, "ii", "nct", "reference-types") // A funcref represented as a function pointer with the funcref attribute // attached to the type, therefore SemaChecking will check for the right diff --git a/clang/include/clang/Basic/DiagnosticSemaKinds.td b/clang/include/clang/Basic/DiagnosticSemaKinds.td index e5a7cdc14a737..d4abc46ae58ee 100644 --- a/clang/include/clang/Basic/DiagnosticSemaKinds.td +++ b/clang/include/clang/Basic/DiagnosticSemaKinds.td @@ -12991,6 +12991,8 @@ def err_wasm_reftype_multidimensional_array : Error< "multi-dimensional arrays of WebAssembly references are not allowed">; def err_wasm_builtin_arg_must_be_table_type : Error < "%ordinal0 argument must be a WebAssembly table">; +def err_wasm_builtin_arg_must_be_externref_type : Error < + "%ordinal0 argument must be an externref">; def err_wasm_builtin_arg_must_match_table_element_type : Error < "%ordinal0 argument must match the element type of the WebAssembly table in the %ordinal1 argument">; def err_wasm_builtin_arg_must_be_integer_type : Error < diff --git a/clang/include/clang/Sema/SemaWasm.h b/clang/include/clang/Sema/SemaWasm.h index 8841fdff23035..2123e073516cb 100644 --- a/clang/include/clang/Sema/SemaWasm.h +++ b/clang/include/clang/Sema/SemaWasm.h @@ -29,6 +29,7 @@ class SemaWasm : public SemaBase { CallExpr *TheCall); bool BuiltinWasmRefNullExtern(CallExpr *TheCall); + bool BuiltinWasmRefIsNullExtern(CallExpr *TheCall); bool BuiltinWasmRefNullFunc(CallExpr *TheCall); bool BuiltinWasmTableGet(CallExpr *TheCall); bool BuiltinWasmTableSet(CallExpr *TheCall); diff --git a/clang/lib/CodeGen/TargetBuiltins/WebAssembly.cpp b/clang/lib/CodeGen/TargetBuiltins/WebAssembly.cpp index 698f43215a1be..b7fd70e855d40 100644 --- a/clang/lib/CodeGen/TargetBuiltins/WebAssembly.cpp +++ b/clang/lib/CodeGen/TargetBuiltins/WebAssembly.cpp @@ -209,6 +209,11 @@ Value *CodeGenFunction::EmitWebAssemblyBuiltinExpr(unsigned BuiltinID, Function *Callee = CGM.getIntrinsic(Intrinsic::wasm_ref_null_extern); return Builder.CreateCall(Callee); } + case WebAssembly::BI__builtin_wasm_ref_is_null_extern: { +Value *Src = EmitScalarExpr(E->getArg(0)); +Function *Callee = CGM.getIntrinsic(Intrinsic::wasm_ref_is_null_extern); +return Builder.CreateCall(Callee, {Src}); + } case WebAssembly::BI__builtin_wasm_ref_null_func: { Function *Callee = CGM.getIntrinsic(Intrinsic::wasm_ref_null_func); return Builder.CreateCall(Callee); diff --git a/clang/lib/Sema/SemaWasm.cpp b/clang/lib/Sema/SemaWasm.cpp index c0fa05bc17609..4157e179c97d6 100644 --- a/clang/lib/Sema/SemaWasm.cpp +++ b/clang/lib/Sema/SemaWasm.cpp @@ -52,14 +52,34 @@ static bool CheckWasmBuiltinArgIsInteger(Sema &S, CallExpr *E, } bool SemaWasm::BuiltinWasmRefNullExtern(CallExpr *TheCall) { - if (TheCall->getNumArgs() != 0) + if (TheCall->getNumArgs() != 0) { +Diag(TheCall->getBeginLoc(), diag::err_typecheck_call_too_many_args) +<< 0 /*function call*/ << /*expected*/ 0 << TheCall->getNumArgs() +<< /*is non object*/ 0; return true; - + } TheCall->setType(getASTContext().getWebAssemblyExternrefType()); return false; } +bool SemaWasm::BuiltinWasmRefIsNullExtern(CallExpr *TheCall) { + if (SemaRef.checkArgCount(TheCall, 1)) { +return true; + } + + Expr *ArgExpr = TheCall->getArg(0); + if (!ArgExpr->getType().isWebAssemblyExternrefType()) { +SemaRef.Diag(ArgExpr->getBeginLoc(
[clang] [Wasm][Clang] Add __builtin_wasm_ref_is_null_extern (PR #139580)
@@ -741,6 +741,12 @@ __externref_t externref_null() { // WEBASSEMBLY-NEXT: ret } +int externref_is_null(__externref_t arg) { + return __builtin_wasm_ref_is_null_extern(arg); + // WEBASSEMBLY: tail call i32 @llvm.wasm.ref.is_null.extern(ptr addrspace(10) %arg) hoodmane wrote: Yeah @pmatos implemented it four years ago: https://reviews.llvm.org/D114979 https://github.com/llvm/llvm-project/pull/139580 ___ cfe-commits mailing list cfe-commits@lists.llvm.org https://lists.llvm.org/cgi-bin/mailman/listinfo/cfe-commits
[clang] [Wasm][Clang] Add __builtin_wasm_ref_is_null_extern (PR #139580)
@@ -52,14 +52,33 @@ static bool CheckWasmBuiltinArgIsInteger(Sema &S, CallExpr *E, } bool SemaWasm::BuiltinWasmRefNullExtern(CallExpr *TheCall) { - if (TheCall->getNumArgs() != 0) + if (TheCall->getNumArgs() != 0) { hoodmane wrote: If a positive number of arguments are provided, it crashes on this line: https://github.com/llvm/llvm-project/blob/main/clang/lib/Sema/SemaChecking.cpp?plain=1#L171 evaluating `Call->getArg(1)`. But I don't understand why that would crash. If we reach this point in the function, `CallExpr` must have at least one argument, so why should it be a problem to look it up? There is exactly one other instance of `SemaRef.checkArgCount(TheCall, 0)` in the code base, but it's possible that there is no test coverage for errors for that. https://github.com/llvm/llvm-project/pull/139580 ___ cfe-commits mailing list cfe-commits@lists.llvm.org https://lists.llvm.org/cgi-bin/mailman/listinfo/cfe-commits
[clang] [Clang] Fix Sema::checkArgCount for 0-arg functions (PR #139638)
hoodmane wrote: > are we sure they weren't intentionally skipping diagnostic there? The behavior before was ``` error: cannot compile this scalar expression yet 2 | __externref_t ref = __builtin_wasm_ref_null_extern(0); | ^ PLEASE submit a bug report to https://github.com/llvm/llvm-project/issues/ and include the crash backtrace, preprocessed source, and associated run script. Stack dump: ... ``` And there was no test coverage. So I'm pretty confident that it was a mistake. https://github.com/llvm/llvm-project/pull/139638 ___ cfe-commits mailing list cfe-commits@lists.llvm.org https://lists.llvm.org/cgi-bin/mailman/listinfo/cfe-commits
[clang] [Clang] Fix Sema::checkArgCount for 0-arg functions (PR #139638)
hoodmane wrote: CI looks green now. https://github.com/llvm/llvm-project/pull/139638 ___ cfe-commits mailing list cfe-commits@lists.llvm.org https://lists.llvm.org/cgi-bin/mailman/listinfo/cfe-commits
[clang] [Clang] Fix Sema::checkArgCount for 0-arg functions (PR #139638)
hoodmane wrote: Can somebody merge when it's appropriate? I don't have merge rights. https://github.com/llvm/llvm-project/pull/139638 ___ cfe-commits mailing list cfe-commits@lists.llvm.org https://lists.llvm.org/cgi-bin/mailman/listinfo/cfe-commits
[clang] [llvm] Add __builtin_wasm_test_function_pointer_signature (PR #147076)
https://github.com/hoodmane updated https://github.com/llvm/llvm-project/pull/147076 >From ba4e21486455fcee36e5521050562cd9be35e9b4 Mon Sep 17 00:00:00 2001 From: Hood Chatham Date: Sat, 10 May 2025 22:01:09 -0400 Subject: [PATCH 1/5] [WebAssembly] Add ref.test_func handling to AsmParser --- .../AsmParser/WebAssemblyAsmParser.cpp| 2 ++ .../lib/Target/WebAssembly/WebAssemblyInstrRef.td | 8 llvm/test/MC/WebAssembly/reference-types.s| 15 +++ 3 files changed, 25 insertions(+) diff --git a/llvm/lib/Target/WebAssembly/AsmParser/WebAssemblyAsmParser.cpp b/llvm/lib/Target/WebAssembly/AsmParser/WebAssemblyAsmParser.cpp index 7ee6a3d8304be..3fad1710c30c4 100644 --- a/llvm/lib/Target/WebAssembly/AsmParser/WebAssemblyAsmParser.cpp +++ b/llvm/lib/Target/WebAssembly/AsmParser/WebAssemblyAsmParser.cpp @@ -668,6 +668,8 @@ class WebAssemblyAsmParser final : public MCTargetAsmParser { if (parseFunctionTableOperand(&FunctionTable)) return true; ExpectFuncType = true; +} else if (Name == "ref.test_func") { + ExpectFuncType = true; } // Returns true if the next tokens are a catch clause diff --git a/llvm/lib/Target/WebAssembly/WebAssemblyInstrRef.td b/llvm/lib/Target/WebAssembly/WebAssemblyInstrRef.td index 2654a09387fd4..8786d78c8e5af 100644 --- a/llvm/lib/Target/WebAssembly/WebAssemblyInstrRef.td +++ b/llvm/lib/Target/WebAssembly/WebAssemblyInstrRef.td @@ -36,6 +36,14 @@ multiclass REF_I { Requires<[HasReferenceTypes]>; } +defm REF_TEST_FUNCREF : + I<(outs I32: $res), +(ins TypeIndex:$type, FUNCREF: $ref), +(outs), +(ins TypeIndex:$type), +[], +"ref.test_func\t$type, $ref", "ref.test_func $type", 0xfb14>; + defm "" : REF_I; defm "" : REF_I; defm "" : REF_I; diff --git a/llvm/test/MC/WebAssembly/reference-types.s b/llvm/test/MC/WebAssembly/reference-types.s index cfadede8295ef..8f3bca79bb68f 100644 --- a/llvm/test/MC/WebAssembly/reference-types.s +++ b/llvm/test/MC/WebAssembly/reference-types.s @@ -27,6 +27,21 @@ ref_null_test: drop end_function +# CHECK-LABEL: ref_test_test: +# CHECK: ref.null_func # encoding: [0xd0,0x70] +# CHECK: ref.test () -> () # encoding: [0xfb,0x14,0x80'A',0x80'A',0x80'A',0x80'A',A] +# CHECK: # fixup A - offset: 2, value: .Ltypeindex0@TYPEINDEX, kind: fixup_uleb128_i32 +# CHECK: ref.null_func # encoding: [0xd0,0x70] +# CHECK: ref.test () -> (i32) # encoding: [0xfb,0x14,0x80'A',0x80'A',0x80'A',0x80'A',A] +# CHECK: # fixup A - offset: 2, value: .Ltypeindex1@TYPEINDEX, kind: fixup_uleb128_i32 +ref_test_test: + .functype ref_test_test () -> (i32, i32) + ref.null_func + ref.test_func () -> () + ref.null_func + ref.test_func () -> (i32) + end_function + # CHECK-LABEL: ref_sig_test_funcref: # CHECK-NEXT: .functype ref_sig_test_funcref (funcref) -> (funcref) ref_sig_test_funcref: >From 6a4693a238723f78c9126071b0b0be2ae5481af9 Mon Sep 17 00:00:00 2001 From: Hood Chatham Date: Mon, 12 May 2025 20:19:55 -0400 Subject: [PATCH 2/5] Rename to ref.test --- .../lib/Target/WebAssembly/AsmParser/WebAssemblyAsmParser.cpp | 2 +- llvm/lib/Target/WebAssembly/WebAssemblyInstrRef.td| 2 +- llvm/test/MC/WebAssembly/reference-types.s| 4 ++-- 3 files changed, 4 insertions(+), 4 deletions(-) diff --git a/llvm/lib/Target/WebAssembly/AsmParser/WebAssemblyAsmParser.cpp b/llvm/lib/Target/WebAssembly/AsmParser/WebAssemblyAsmParser.cpp index 3fad1710c30c4..c1b3936c1dcec 100644 --- a/llvm/lib/Target/WebAssembly/AsmParser/WebAssemblyAsmParser.cpp +++ b/llvm/lib/Target/WebAssembly/AsmParser/WebAssemblyAsmParser.cpp @@ -668,7 +668,7 @@ class WebAssemblyAsmParser final : public MCTargetAsmParser { if (parseFunctionTableOperand(&FunctionTable)) return true; ExpectFuncType = true; -} else if (Name == "ref.test_func") { +} else if (Name == "ref.test") { ExpectFuncType = true; } diff --git a/llvm/lib/Target/WebAssembly/WebAssemblyInstrRef.td b/llvm/lib/Target/WebAssembly/WebAssemblyInstrRef.td index 8786d78c8e5af..40b87a084c687 100644 --- a/llvm/lib/Target/WebAssembly/WebAssemblyInstrRef.td +++ b/llvm/lib/Target/WebAssembly/WebAssemblyInstrRef.td @@ -42,7 +42,7 @@ defm REF_TEST_FUNCREF : (outs), (ins TypeIndex:$type), [], -"ref.test_func\t$type, $ref", "ref.test_func $type", 0xfb14>; +"ref.test\t$type, $ref", "ref.test $type", 0xfb14>; defm "" : REF_I; defm "" : REF_I; diff --git a/llvm/test/MC/WebAssembly/reference-types.s b/llvm/test/MC/WebAssembly/reference-types.s index 8f3bca79bb68f..08aafb23969eb 100644 --- a/llvm/test/MC/WebAssembly/reference-types.s +++ b/llvm/test/MC/WebAssembly/reference-types.s @@ -37,9 +37,9 @@ ref_null_test: ref_test_test: .functype ref_test_test () -> (i32, i32) ref.null_func - ref.test_func () -> () + ref.test () -> () ref.null_func - ref.test_func () -> (i32) + ref.test () -> (i32) end_function # CHECK-LABEL: ref_sig_te
[clang] [llvm] Add __builtin_wasm_test_function_pointer_signature (PR #147076)
https://github.com/hoodmane created https://github.com/llvm/llvm-project/pull/147076 This uses ref.test to check whether the function pointer's runtime type matches its static type. If so, then calling it won't trap with "indirect call signature mismatch". This would be very useful here: https://github.com/python/cpython/blob/main/Python/emscripten_trampoline.c and would allow us to fix function pointer mismatches on the WASI target and the Emscripten target in a uniform way. This is on top of #139642. >From ba4e21486455fcee36e5521050562cd9be35e9b4 Mon Sep 17 00:00:00 2001 From: Hood Chatham Date: Sat, 10 May 2025 22:01:09 -0400 Subject: [PATCH 1/3] [WebAssembly] Add ref.test_func handling to AsmParser --- .../AsmParser/WebAssemblyAsmParser.cpp| 2 ++ .../lib/Target/WebAssembly/WebAssemblyInstrRef.td | 8 llvm/test/MC/WebAssembly/reference-types.s| 15 +++ 3 files changed, 25 insertions(+) diff --git a/llvm/lib/Target/WebAssembly/AsmParser/WebAssemblyAsmParser.cpp b/llvm/lib/Target/WebAssembly/AsmParser/WebAssemblyAsmParser.cpp index 7ee6a3d8304be..3fad1710c30c4 100644 --- a/llvm/lib/Target/WebAssembly/AsmParser/WebAssemblyAsmParser.cpp +++ b/llvm/lib/Target/WebAssembly/AsmParser/WebAssemblyAsmParser.cpp @@ -668,6 +668,8 @@ class WebAssemblyAsmParser final : public MCTargetAsmParser { if (parseFunctionTableOperand(&FunctionTable)) return true; ExpectFuncType = true; +} else if (Name == "ref.test_func") { + ExpectFuncType = true; } // Returns true if the next tokens are a catch clause diff --git a/llvm/lib/Target/WebAssembly/WebAssemblyInstrRef.td b/llvm/lib/Target/WebAssembly/WebAssemblyInstrRef.td index 2654a09387fd4..8786d78c8e5af 100644 --- a/llvm/lib/Target/WebAssembly/WebAssemblyInstrRef.td +++ b/llvm/lib/Target/WebAssembly/WebAssemblyInstrRef.td @@ -36,6 +36,14 @@ multiclass REF_I { Requires<[HasReferenceTypes]>; } +defm REF_TEST_FUNCREF : + I<(outs I32: $res), +(ins TypeIndex:$type, FUNCREF: $ref), +(outs), +(ins TypeIndex:$type), +[], +"ref.test_func\t$type, $ref", "ref.test_func $type", 0xfb14>; + defm "" : REF_I; defm "" : REF_I; defm "" : REF_I; diff --git a/llvm/test/MC/WebAssembly/reference-types.s b/llvm/test/MC/WebAssembly/reference-types.s index cfadede8295ef..8f3bca79bb68f 100644 --- a/llvm/test/MC/WebAssembly/reference-types.s +++ b/llvm/test/MC/WebAssembly/reference-types.s @@ -27,6 +27,21 @@ ref_null_test: drop end_function +# CHECK-LABEL: ref_test_test: +# CHECK: ref.null_func # encoding: [0xd0,0x70] +# CHECK: ref.test () -> () # encoding: [0xfb,0x14,0x80'A',0x80'A',0x80'A',0x80'A',A] +# CHECK: # fixup A - offset: 2, value: .Ltypeindex0@TYPEINDEX, kind: fixup_uleb128_i32 +# CHECK: ref.null_func # encoding: [0xd0,0x70] +# CHECK: ref.test () -> (i32) # encoding: [0xfb,0x14,0x80'A',0x80'A',0x80'A',0x80'A',A] +# CHECK: # fixup A - offset: 2, value: .Ltypeindex1@TYPEINDEX, kind: fixup_uleb128_i32 +ref_test_test: + .functype ref_test_test () -> (i32, i32) + ref.null_func + ref.test_func () -> () + ref.null_func + ref.test_func () -> (i32) + end_function + # CHECK-LABEL: ref_sig_test_funcref: # CHECK-NEXT: .functype ref_sig_test_funcref (funcref) -> (funcref) ref_sig_test_funcref: >From 6a4693a238723f78c9126071b0b0be2ae5481af9 Mon Sep 17 00:00:00 2001 From: Hood Chatham Date: Mon, 12 May 2025 20:19:55 -0400 Subject: [PATCH 2/3] Rename to ref.test --- .../lib/Target/WebAssembly/AsmParser/WebAssemblyAsmParser.cpp | 2 +- llvm/lib/Target/WebAssembly/WebAssemblyInstrRef.td| 2 +- llvm/test/MC/WebAssembly/reference-types.s| 4 ++-- 3 files changed, 4 insertions(+), 4 deletions(-) diff --git a/llvm/lib/Target/WebAssembly/AsmParser/WebAssemblyAsmParser.cpp b/llvm/lib/Target/WebAssembly/AsmParser/WebAssemblyAsmParser.cpp index 3fad1710c30c4..c1b3936c1dcec 100644 --- a/llvm/lib/Target/WebAssembly/AsmParser/WebAssemblyAsmParser.cpp +++ b/llvm/lib/Target/WebAssembly/AsmParser/WebAssemblyAsmParser.cpp @@ -668,7 +668,7 @@ class WebAssemblyAsmParser final : public MCTargetAsmParser { if (parseFunctionTableOperand(&FunctionTable)) return true; ExpectFuncType = true; -} else if (Name == "ref.test_func") { +} else if (Name == "ref.test") { ExpectFuncType = true; } diff --git a/llvm/lib/Target/WebAssembly/WebAssemblyInstrRef.td b/llvm/lib/Target/WebAssembly/WebAssemblyInstrRef.td index 8786d78c8e5af..40b87a084c687 100644 --- a/llvm/lib/Target/WebAssembly/WebAssemblyInstrRef.td +++ b/llvm/lib/Target/WebAssembly/WebAssemblyInstrRef.td @@ -42,7 +42,7 @@ defm REF_TEST_FUNCREF : (outs), (ins TypeIndex:$type), [], -"ref.test_func\t$type, $ref", "ref.test_func $type", 0xfb14>; +"ref.test\t$type, $ref", "ref.test $type", 0xfb14>; defm "" : REF_I; defm "" : REF_I; diff --git a/llvm/test/MC/WebAssembly/reference-types.s b/llvm/test/MC/WebAssembly/refe
[clang] [llvm] Add __builtin_wasm_test_function_pointer_signature (PR #147076)
https://github.com/hoodmane updated https://github.com/llvm/llvm-project/pull/147076 >From ba4e21486455fcee36e5521050562cd9be35e9b4 Mon Sep 17 00:00:00 2001 From: Hood Chatham Date: Sat, 10 May 2025 22:01:09 -0400 Subject: [PATCH 1/6] [WebAssembly] Add ref.test_func handling to AsmParser --- .../AsmParser/WebAssemblyAsmParser.cpp| 2 ++ .../lib/Target/WebAssembly/WebAssemblyInstrRef.td | 8 llvm/test/MC/WebAssembly/reference-types.s| 15 +++ 3 files changed, 25 insertions(+) diff --git a/llvm/lib/Target/WebAssembly/AsmParser/WebAssemblyAsmParser.cpp b/llvm/lib/Target/WebAssembly/AsmParser/WebAssemblyAsmParser.cpp index 7ee6a3d8304be..3fad1710c30c4 100644 --- a/llvm/lib/Target/WebAssembly/AsmParser/WebAssemblyAsmParser.cpp +++ b/llvm/lib/Target/WebAssembly/AsmParser/WebAssemblyAsmParser.cpp @@ -668,6 +668,8 @@ class WebAssemblyAsmParser final : public MCTargetAsmParser { if (parseFunctionTableOperand(&FunctionTable)) return true; ExpectFuncType = true; +} else if (Name == "ref.test_func") { + ExpectFuncType = true; } // Returns true if the next tokens are a catch clause diff --git a/llvm/lib/Target/WebAssembly/WebAssemblyInstrRef.td b/llvm/lib/Target/WebAssembly/WebAssemblyInstrRef.td index 2654a09387fd4..8786d78c8e5af 100644 --- a/llvm/lib/Target/WebAssembly/WebAssemblyInstrRef.td +++ b/llvm/lib/Target/WebAssembly/WebAssemblyInstrRef.td @@ -36,6 +36,14 @@ multiclass REF_I { Requires<[HasReferenceTypes]>; } +defm REF_TEST_FUNCREF : + I<(outs I32: $res), +(ins TypeIndex:$type, FUNCREF: $ref), +(outs), +(ins TypeIndex:$type), +[], +"ref.test_func\t$type, $ref", "ref.test_func $type", 0xfb14>; + defm "" : REF_I; defm "" : REF_I; defm "" : REF_I; diff --git a/llvm/test/MC/WebAssembly/reference-types.s b/llvm/test/MC/WebAssembly/reference-types.s index cfadede8295ef..8f3bca79bb68f 100644 --- a/llvm/test/MC/WebAssembly/reference-types.s +++ b/llvm/test/MC/WebAssembly/reference-types.s @@ -27,6 +27,21 @@ ref_null_test: drop end_function +# CHECK-LABEL: ref_test_test: +# CHECK: ref.null_func # encoding: [0xd0,0x70] +# CHECK: ref.test () -> () # encoding: [0xfb,0x14,0x80'A',0x80'A',0x80'A',0x80'A',A] +# CHECK: # fixup A - offset: 2, value: .Ltypeindex0@TYPEINDEX, kind: fixup_uleb128_i32 +# CHECK: ref.null_func # encoding: [0xd0,0x70] +# CHECK: ref.test () -> (i32) # encoding: [0xfb,0x14,0x80'A',0x80'A',0x80'A',0x80'A',A] +# CHECK: # fixup A - offset: 2, value: .Ltypeindex1@TYPEINDEX, kind: fixup_uleb128_i32 +ref_test_test: + .functype ref_test_test () -> (i32, i32) + ref.null_func + ref.test_func () -> () + ref.null_func + ref.test_func () -> (i32) + end_function + # CHECK-LABEL: ref_sig_test_funcref: # CHECK-NEXT: .functype ref_sig_test_funcref (funcref) -> (funcref) ref_sig_test_funcref: >From 6a4693a238723f78c9126071b0b0be2ae5481af9 Mon Sep 17 00:00:00 2001 From: Hood Chatham Date: Mon, 12 May 2025 20:19:55 -0400 Subject: [PATCH 2/6] Rename to ref.test --- .../lib/Target/WebAssembly/AsmParser/WebAssemblyAsmParser.cpp | 2 +- llvm/lib/Target/WebAssembly/WebAssemblyInstrRef.td| 2 +- llvm/test/MC/WebAssembly/reference-types.s| 4 ++-- 3 files changed, 4 insertions(+), 4 deletions(-) diff --git a/llvm/lib/Target/WebAssembly/AsmParser/WebAssemblyAsmParser.cpp b/llvm/lib/Target/WebAssembly/AsmParser/WebAssemblyAsmParser.cpp index 3fad1710c30c4..c1b3936c1dcec 100644 --- a/llvm/lib/Target/WebAssembly/AsmParser/WebAssemblyAsmParser.cpp +++ b/llvm/lib/Target/WebAssembly/AsmParser/WebAssemblyAsmParser.cpp @@ -668,7 +668,7 @@ class WebAssemblyAsmParser final : public MCTargetAsmParser { if (parseFunctionTableOperand(&FunctionTable)) return true; ExpectFuncType = true; -} else if (Name == "ref.test_func") { +} else if (Name == "ref.test") { ExpectFuncType = true; } diff --git a/llvm/lib/Target/WebAssembly/WebAssemblyInstrRef.td b/llvm/lib/Target/WebAssembly/WebAssemblyInstrRef.td index 8786d78c8e5af..40b87a084c687 100644 --- a/llvm/lib/Target/WebAssembly/WebAssemblyInstrRef.td +++ b/llvm/lib/Target/WebAssembly/WebAssemblyInstrRef.td @@ -42,7 +42,7 @@ defm REF_TEST_FUNCREF : (outs), (ins TypeIndex:$type), [], -"ref.test_func\t$type, $ref", "ref.test_func $type", 0xfb14>; +"ref.test\t$type, $ref", "ref.test $type", 0xfb14>; defm "" : REF_I; defm "" : REF_I; diff --git a/llvm/test/MC/WebAssembly/reference-types.s b/llvm/test/MC/WebAssembly/reference-types.s index 8f3bca79bb68f..08aafb23969eb 100644 --- a/llvm/test/MC/WebAssembly/reference-types.s +++ b/llvm/test/MC/WebAssembly/reference-types.s @@ -37,9 +37,9 @@ ref_null_test: ref_test_test: .functype ref_test_test () -> (i32, i32) ref.null_func - ref.test_func () -> () + ref.test () -> () ref.null_func - ref.test_func () -> (i32) + ref.test () -> (i32) end_function # CHECK-LABEL: ref_sig_te
[clang] [llvm] Add __builtin_wasm_test_function_pointer_signature (PR #147076)
https://github.com/hoodmane updated https://github.com/llvm/llvm-project/pull/147076 >From ba4e21486455fcee36e5521050562cd9be35e9b4 Mon Sep 17 00:00:00 2001 From: Hood Chatham Date: Sat, 10 May 2025 22:01:09 -0400 Subject: [PATCH 1/7] [WebAssembly] Add ref.test_func handling to AsmParser --- .../AsmParser/WebAssemblyAsmParser.cpp| 2 ++ .../lib/Target/WebAssembly/WebAssemblyInstrRef.td | 8 llvm/test/MC/WebAssembly/reference-types.s| 15 +++ 3 files changed, 25 insertions(+) diff --git a/llvm/lib/Target/WebAssembly/AsmParser/WebAssemblyAsmParser.cpp b/llvm/lib/Target/WebAssembly/AsmParser/WebAssemblyAsmParser.cpp index 7ee6a3d8304be..3fad1710c30c4 100644 --- a/llvm/lib/Target/WebAssembly/AsmParser/WebAssemblyAsmParser.cpp +++ b/llvm/lib/Target/WebAssembly/AsmParser/WebAssemblyAsmParser.cpp @@ -668,6 +668,8 @@ class WebAssemblyAsmParser final : public MCTargetAsmParser { if (parseFunctionTableOperand(&FunctionTable)) return true; ExpectFuncType = true; +} else if (Name == "ref.test_func") { + ExpectFuncType = true; } // Returns true if the next tokens are a catch clause diff --git a/llvm/lib/Target/WebAssembly/WebAssemblyInstrRef.td b/llvm/lib/Target/WebAssembly/WebAssemblyInstrRef.td index 2654a09387fd4..8786d78c8e5af 100644 --- a/llvm/lib/Target/WebAssembly/WebAssemblyInstrRef.td +++ b/llvm/lib/Target/WebAssembly/WebAssemblyInstrRef.td @@ -36,6 +36,14 @@ multiclass REF_I { Requires<[HasReferenceTypes]>; } +defm REF_TEST_FUNCREF : + I<(outs I32: $res), +(ins TypeIndex:$type, FUNCREF: $ref), +(outs), +(ins TypeIndex:$type), +[], +"ref.test_func\t$type, $ref", "ref.test_func $type", 0xfb14>; + defm "" : REF_I; defm "" : REF_I; defm "" : REF_I; diff --git a/llvm/test/MC/WebAssembly/reference-types.s b/llvm/test/MC/WebAssembly/reference-types.s index cfadede8295ef..8f3bca79bb68f 100644 --- a/llvm/test/MC/WebAssembly/reference-types.s +++ b/llvm/test/MC/WebAssembly/reference-types.s @@ -27,6 +27,21 @@ ref_null_test: drop end_function +# CHECK-LABEL: ref_test_test: +# CHECK: ref.null_func # encoding: [0xd0,0x70] +# CHECK: ref.test () -> () # encoding: [0xfb,0x14,0x80'A',0x80'A',0x80'A',0x80'A',A] +# CHECK: # fixup A - offset: 2, value: .Ltypeindex0@TYPEINDEX, kind: fixup_uleb128_i32 +# CHECK: ref.null_func # encoding: [0xd0,0x70] +# CHECK: ref.test () -> (i32) # encoding: [0xfb,0x14,0x80'A',0x80'A',0x80'A',0x80'A',A] +# CHECK: # fixup A - offset: 2, value: .Ltypeindex1@TYPEINDEX, kind: fixup_uleb128_i32 +ref_test_test: + .functype ref_test_test () -> (i32, i32) + ref.null_func + ref.test_func () -> () + ref.null_func + ref.test_func () -> (i32) + end_function + # CHECK-LABEL: ref_sig_test_funcref: # CHECK-NEXT: .functype ref_sig_test_funcref (funcref) -> (funcref) ref_sig_test_funcref: >From 6a4693a238723f78c9126071b0b0be2ae5481af9 Mon Sep 17 00:00:00 2001 From: Hood Chatham Date: Mon, 12 May 2025 20:19:55 -0400 Subject: [PATCH 2/7] Rename to ref.test --- .../lib/Target/WebAssembly/AsmParser/WebAssemblyAsmParser.cpp | 2 +- llvm/lib/Target/WebAssembly/WebAssemblyInstrRef.td| 2 +- llvm/test/MC/WebAssembly/reference-types.s| 4 ++-- 3 files changed, 4 insertions(+), 4 deletions(-) diff --git a/llvm/lib/Target/WebAssembly/AsmParser/WebAssemblyAsmParser.cpp b/llvm/lib/Target/WebAssembly/AsmParser/WebAssemblyAsmParser.cpp index 3fad1710c30c4..c1b3936c1dcec 100644 --- a/llvm/lib/Target/WebAssembly/AsmParser/WebAssemblyAsmParser.cpp +++ b/llvm/lib/Target/WebAssembly/AsmParser/WebAssemblyAsmParser.cpp @@ -668,7 +668,7 @@ class WebAssemblyAsmParser final : public MCTargetAsmParser { if (parseFunctionTableOperand(&FunctionTable)) return true; ExpectFuncType = true; -} else if (Name == "ref.test_func") { +} else if (Name == "ref.test") { ExpectFuncType = true; } diff --git a/llvm/lib/Target/WebAssembly/WebAssemblyInstrRef.td b/llvm/lib/Target/WebAssembly/WebAssemblyInstrRef.td index 8786d78c8e5af..40b87a084c687 100644 --- a/llvm/lib/Target/WebAssembly/WebAssemblyInstrRef.td +++ b/llvm/lib/Target/WebAssembly/WebAssemblyInstrRef.td @@ -42,7 +42,7 @@ defm REF_TEST_FUNCREF : (outs), (ins TypeIndex:$type), [], -"ref.test_func\t$type, $ref", "ref.test_func $type", 0xfb14>; +"ref.test\t$type, $ref", "ref.test $type", 0xfb14>; defm "" : REF_I; defm "" : REF_I; diff --git a/llvm/test/MC/WebAssembly/reference-types.s b/llvm/test/MC/WebAssembly/reference-types.s index 8f3bca79bb68f..08aafb23969eb 100644 --- a/llvm/test/MC/WebAssembly/reference-types.s +++ b/llvm/test/MC/WebAssembly/reference-types.s @@ -37,9 +37,9 @@ ref_null_test: ref_test_test: .functype ref_test_test () -> (i32, i32) ref.null_func - ref.test_func () -> () + ref.test () -> () ref.null_func - ref.test_func () -> (i32) + ref.test () -> (i32) end_function # CHECK-LABEL: ref_sig_te
[clang] [llvm] Add __builtin_wasm_test_function_pointer_signature (PR #147076)
https://github.com/hoodmane updated https://github.com/llvm/llvm-project/pull/147076 >From ba4e21486455fcee36e5521050562cd9be35e9b4 Mon Sep 17 00:00:00 2001 From: Hood Chatham Date: Sat, 10 May 2025 22:01:09 -0400 Subject: [PATCH 1/8] [WebAssembly] Add ref.test_func handling to AsmParser --- .../AsmParser/WebAssemblyAsmParser.cpp| 2 ++ .../lib/Target/WebAssembly/WebAssemblyInstrRef.td | 8 llvm/test/MC/WebAssembly/reference-types.s| 15 +++ 3 files changed, 25 insertions(+) diff --git a/llvm/lib/Target/WebAssembly/AsmParser/WebAssemblyAsmParser.cpp b/llvm/lib/Target/WebAssembly/AsmParser/WebAssemblyAsmParser.cpp index 7ee6a3d8304be..3fad1710c30c4 100644 --- a/llvm/lib/Target/WebAssembly/AsmParser/WebAssemblyAsmParser.cpp +++ b/llvm/lib/Target/WebAssembly/AsmParser/WebAssemblyAsmParser.cpp @@ -668,6 +668,8 @@ class WebAssemblyAsmParser final : public MCTargetAsmParser { if (parseFunctionTableOperand(&FunctionTable)) return true; ExpectFuncType = true; +} else if (Name == "ref.test_func") { + ExpectFuncType = true; } // Returns true if the next tokens are a catch clause diff --git a/llvm/lib/Target/WebAssembly/WebAssemblyInstrRef.td b/llvm/lib/Target/WebAssembly/WebAssemblyInstrRef.td index 2654a09387fd4..8786d78c8e5af 100644 --- a/llvm/lib/Target/WebAssembly/WebAssemblyInstrRef.td +++ b/llvm/lib/Target/WebAssembly/WebAssemblyInstrRef.td @@ -36,6 +36,14 @@ multiclass REF_I { Requires<[HasReferenceTypes]>; } +defm REF_TEST_FUNCREF : + I<(outs I32: $res), +(ins TypeIndex:$type, FUNCREF: $ref), +(outs), +(ins TypeIndex:$type), +[], +"ref.test_func\t$type, $ref", "ref.test_func $type", 0xfb14>; + defm "" : REF_I; defm "" : REF_I; defm "" : REF_I; diff --git a/llvm/test/MC/WebAssembly/reference-types.s b/llvm/test/MC/WebAssembly/reference-types.s index cfadede8295ef..8f3bca79bb68f 100644 --- a/llvm/test/MC/WebAssembly/reference-types.s +++ b/llvm/test/MC/WebAssembly/reference-types.s @@ -27,6 +27,21 @@ ref_null_test: drop end_function +# CHECK-LABEL: ref_test_test: +# CHECK: ref.null_func # encoding: [0xd0,0x70] +# CHECK: ref.test () -> () # encoding: [0xfb,0x14,0x80'A',0x80'A',0x80'A',0x80'A',A] +# CHECK: # fixup A - offset: 2, value: .Ltypeindex0@TYPEINDEX, kind: fixup_uleb128_i32 +# CHECK: ref.null_func # encoding: [0xd0,0x70] +# CHECK: ref.test () -> (i32) # encoding: [0xfb,0x14,0x80'A',0x80'A',0x80'A',0x80'A',A] +# CHECK: # fixup A - offset: 2, value: .Ltypeindex1@TYPEINDEX, kind: fixup_uleb128_i32 +ref_test_test: + .functype ref_test_test () -> (i32, i32) + ref.null_func + ref.test_func () -> () + ref.null_func + ref.test_func () -> (i32) + end_function + # CHECK-LABEL: ref_sig_test_funcref: # CHECK-NEXT: .functype ref_sig_test_funcref (funcref) -> (funcref) ref_sig_test_funcref: >From 6a4693a238723f78c9126071b0b0be2ae5481af9 Mon Sep 17 00:00:00 2001 From: Hood Chatham Date: Mon, 12 May 2025 20:19:55 -0400 Subject: [PATCH 2/8] Rename to ref.test --- .../lib/Target/WebAssembly/AsmParser/WebAssemblyAsmParser.cpp | 2 +- llvm/lib/Target/WebAssembly/WebAssemblyInstrRef.td| 2 +- llvm/test/MC/WebAssembly/reference-types.s| 4 ++-- 3 files changed, 4 insertions(+), 4 deletions(-) diff --git a/llvm/lib/Target/WebAssembly/AsmParser/WebAssemblyAsmParser.cpp b/llvm/lib/Target/WebAssembly/AsmParser/WebAssemblyAsmParser.cpp index 3fad1710c30c4..c1b3936c1dcec 100644 --- a/llvm/lib/Target/WebAssembly/AsmParser/WebAssemblyAsmParser.cpp +++ b/llvm/lib/Target/WebAssembly/AsmParser/WebAssemblyAsmParser.cpp @@ -668,7 +668,7 @@ class WebAssemblyAsmParser final : public MCTargetAsmParser { if (parseFunctionTableOperand(&FunctionTable)) return true; ExpectFuncType = true; -} else if (Name == "ref.test_func") { +} else if (Name == "ref.test") { ExpectFuncType = true; } diff --git a/llvm/lib/Target/WebAssembly/WebAssemblyInstrRef.td b/llvm/lib/Target/WebAssembly/WebAssemblyInstrRef.td index 8786d78c8e5af..40b87a084c687 100644 --- a/llvm/lib/Target/WebAssembly/WebAssemblyInstrRef.td +++ b/llvm/lib/Target/WebAssembly/WebAssemblyInstrRef.td @@ -42,7 +42,7 @@ defm REF_TEST_FUNCREF : (outs), (ins TypeIndex:$type), [], -"ref.test_func\t$type, $ref", "ref.test_func $type", 0xfb14>; +"ref.test\t$type, $ref", "ref.test $type", 0xfb14>; defm "" : REF_I; defm "" : REF_I; diff --git a/llvm/test/MC/WebAssembly/reference-types.s b/llvm/test/MC/WebAssembly/reference-types.s index 8f3bca79bb68f..08aafb23969eb 100644 --- a/llvm/test/MC/WebAssembly/reference-types.s +++ b/llvm/test/MC/WebAssembly/reference-types.s @@ -37,9 +37,9 @@ ref_null_test: ref_test_test: .functype ref_test_test () -> (i32, i32) ref.null_func - ref.test_func () -> () + ref.test () -> () ref.null_func - ref.test_func () -> (i32) + ref.test () -> (i32) end_function # CHECK-LABEL: ref_sig_te
[clang] [llvm] [WebAssembly,llvm] Add llvm.wasm.ref.test.func intrinsic (PR #147076)
hoodmane wrote: Okay I opened https://github.com/llvm/llvm-project/pull/147486/ with a second option. I think that's a bit cleaner, I modified SelectionDAG to be able to emit CImm arguments rather than going to all this trouble to avoid it. https://github.com/llvm/llvm-project/pull/147076 ___ cfe-commits mailing list cfe-commits@lists.llvm.org https://lists.llvm.org/cgi-bin/mailman/listinfo/cfe-commits
[clang] [llvm] [WebAssembly,llvm] Add llvm.wasm.ref.test.func intrinsic (PR #147076)
https://github.com/hoodmane edited https://github.com/llvm/llvm-project/pull/147076 ___ cfe-commits mailing list cfe-commits@lists.llvm.org https://lists.llvm.org/cgi-bin/mailman/listinfo/cfe-commits
[clang] [llvm] [WebAssembly,clang] Add __builtin_wasm_test_function_pointer_signature (PR #147076)
https://github.com/hoodmane updated https://github.com/llvm/llvm-project/pull/147076 >From 2009bb945f57c67daa522448eddb2cc01aac4369 Mon Sep 17 00:00:00 2001 From: Hood Chatham Date: Wed, 2 Jul 2025 20:53:56 +0200 Subject: [PATCH 1/8] Add __builtin_wasm_test_function_pointer_signature This uses ref.test to check whether the function pointer's runtime type matches its static type. If so, then calling it won't trap with "indirect call signature mismatch". This would be very useful here: https://github.com/python/cpython/blob/main/Python/emscripten_trampoline.c and would allow us to fix function pointer mismatches on the WASI target and the Emscripten target in a uniform way. --- .../clang/Basic/BuiltinsWebAssembly.def | 6 + .../clang/Basic/DiagnosticSemaKinds.td| 6 + clang/include/clang/Sema/SemaWasm.h | 1 + .../CodeGen/TargetBuiltins/WebAssembly.cpp| 58 + clang/lib/Sema/SemaWasm.cpp | 49 llvm/include/llvm/IR/IntrinsicsWebAssembly.td | 4 + .../WebAssembly/WebAssemblyISelLowering.cpp | 114 ++ .../Target/WebAssembly/WebAssemblyInstrRef.td | 5 + .../WebAssembly/WebAssemblyMCInstLower.cpp| 75 9 files changed, 318 insertions(+) diff --git a/clang/include/clang/Basic/BuiltinsWebAssembly.def b/clang/include/clang/Basic/BuiltinsWebAssembly.def index e2afcc08064b2..1e03a40b1a22b 100644 --- a/clang/include/clang/Basic/BuiltinsWebAssembly.def +++ b/clang/include/clang/Basic/BuiltinsWebAssembly.def @@ -199,6 +199,12 @@ TARGET_BUILTIN(__builtin_wasm_ref_is_null_extern, "ii", "nct", "reference-types" // return type. TARGET_BUILTIN(__builtin_wasm_ref_null_func, "i", "nct", "reference-types") +// Check if the static type of a function pointer matches its static type. Used +// to avoid "function signature mismatch" traps. Takes a function pointer, uses +// table.get to look up the pointer in __indirect_function_table and then +// ref.test to test the type. +TARGET_BUILTIN(__builtin_wasm_test_function_pointer_signature, "i.", "nct", "reference-types") + // Table builtins TARGET_BUILTIN(__builtin_wasm_table_set, "viii", "t", "reference-types") TARGET_BUILTIN(__builtin_wasm_table_get, "iii", "t", "reference-types") diff --git a/clang/include/clang/Basic/DiagnosticSemaKinds.td b/clang/include/clang/Basic/DiagnosticSemaKinds.td index 968edd967e0c5..3a0d69c9c097b 100644 --- a/clang/include/clang/Basic/DiagnosticSemaKinds.td +++ b/clang/include/clang/Basic/DiagnosticSemaKinds.td @@ -7566,6 +7566,8 @@ def err_typecheck_illegal_increment_decrement : Error< "cannot %select{decrement|increment}1 value of type %0">; def err_typecheck_expect_int : Error< "used type %0 where integer is required">; +def err_typecheck_expect_function_pointer +: Error<"used type %0 where function pointer is required">; def err_typecheck_expect_hlsl_resource : Error< "used type %0 where __hlsl_resource_t is required">; def err_typecheck_arithmetic_incomplete_or_sizeless_type : Error< @@ -13164,6 +13166,10 @@ def err_wasm_builtin_arg_must_match_table_element_type : Error < "%ordinal0 argument must match the element type of the WebAssembly table in the %ordinal1 argument">; def err_wasm_builtin_arg_must_be_integer_type : Error < "%ordinal0 argument must be an integer">; +def err_wasm_builtin_test_fp_sig_cannot_include_reference_type +: Error<"__builtin_wasm_test_function_pointer_signature not supported for " +"function pointers with reference types in their " +"%select{return|parameter}0 type">; // OpenACC diagnostics. def warn_acc_routine_unimplemented diff --git a/clang/include/clang/Sema/SemaWasm.h b/clang/include/clang/Sema/SemaWasm.h index 2123e073516cb..8c0639fd7e76f 100644 --- a/clang/include/clang/Sema/SemaWasm.h +++ b/clang/include/clang/Sema/SemaWasm.h @@ -37,6 +37,7 @@ class SemaWasm : public SemaBase { bool BuiltinWasmTableGrow(CallExpr *TheCall); bool BuiltinWasmTableFill(CallExpr *TheCall); bool BuiltinWasmTableCopy(CallExpr *TheCall); + bool BuiltinWasmTestFunctionPointerSignature(CallExpr *TheCall); WebAssemblyImportNameAttr * mergeImportNameAttr(Decl *D, const WebAssemblyImportNameAttr &AL); diff --git a/clang/lib/CodeGen/TargetBuiltins/WebAssembly.cpp b/clang/lib/CodeGen/TargetBuiltins/WebAssembly.cpp index b7fd70e855d40..0dc89e091eec9 100644 --- a/clang/lib/CodeGen/TargetBuiltins/WebAssembly.cpp +++ b/clang/lib/CodeGen/TargetBuiltins/WebAssembly.cpp @@ -12,7 +12,10 @@ #include "CGBuiltin.h" #include "clang/Basic/TargetBuiltins.h" +#include "llvm/ADT/APInt.h" +#include "llvm/IR/Constants.h" #include "llvm/IR/IntrinsicsWebAssembly.h" +#include "llvm/Support/ErrorHandling.h" using namespace clang; using namespace CodeGen; @@ -218,6 +221,61 @@ Value *CodeGenFunction::EmitWebAssemblyBuiltinExpr(unsigned BuiltinID, Function *Callee = CGM.getIntrinsic(Intrinsic::wasm_ref_null_func); return Builder.CreateCall(Callee);
[clang] [llvm] [WebAssembly,llvm] Add llvm.wasm.ref.test.func intrinsic (PR #147076)
https://github.com/hoodmane edited https://github.com/llvm/llvm-project/pull/147076 ___ cfe-commits mailing list cfe-commits@lists.llvm.org https://lists.llvm.org/cgi-bin/mailman/listinfo/cfe-commits
[clang] [llvm] Add __builtin_wasm_test_function_pointer_signature (PR #147076)
https://github.com/hoodmane updated https://github.com/llvm/llvm-project/pull/147076 >From ba4e21486455fcee36e5521050562cd9be35e9b4 Mon Sep 17 00:00:00 2001 From: Hood Chatham Date: Sat, 10 May 2025 22:01:09 -0400 Subject: [PATCH 1/9] [WebAssembly] Add ref.test_func handling to AsmParser --- .../AsmParser/WebAssemblyAsmParser.cpp| 2 ++ .../lib/Target/WebAssembly/WebAssemblyInstrRef.td | 8 llvm/test/MC/WebAssembly/reference-types.s| 15 +++ 3 files changed, 25 insertions(+) diff --git a/llvm/lib/Target/WebAssembly/AsmParser/WebAssemblyAsmParser.cpp b/llvm/lib/Target/WebAssembly/AsmParser/WebAssemblyAsmParser.cpp index 7ee6a3d8304be..3fad1710c30c4 100644 --- a/llvm/lib/Target/WebAssembly/AsmParser/WebAssemblyAsmParser.cpp +++ b/llvm/lib/Target/WebAssembly/AsmParser/WebAssemblyAsmParser.cpp @@ -668,6 +668,8 @@ class WebAssemblyAsmParser final : public MCTargetAsmParser { if (parseFunctionTableOperand(&FunctionTable)) return true; ExpectFuncType = true; +} else if (Name == "ref.test_func") { + ExpectFuncType = true; } // Returns true if the next tokens are a catch clause diff --git a/llvm/lib/Target/WebAssembly/WebAssemblyInstrRef.td b/llvm/lib/Target/WebAssembly/WebAssemblyInstrRef.td index 2654a09387fd4..8786d78c8e5af 100644 --- a/llvm/lib/Target/WebAssembly/WebAssemblyInstrRef.td +++ b/llvm/lib/Target/WebAssembly/WebAssemblyInstrRef.td @@ -36,6 +36,14 @@ multiclass REF_I { Requires<[HasReferenceTypes]>; } +defm REF_TEST_FUNCREF : + I<(outs I32: $res), +(ins TypeIndex:$type, FUNCREF: $ref), +(outs), +(ins TypeIndex:$type), +[], +"ref.test_func\t$type, $ref", "ref.test_func $type", 0xfb14>; + defm "" : REF_I; defm "" : REF_I; defm "" : REF_I; diff --git a/llvm/test/MC/WebAssembly/reference-types.s b/llvm/test/MC/WebAssembly/reference-types.s index cfadede8295ef..8f3bca79bb68f 100644 --- a/llvm/test/MC/WebAssembly/reference-types.s +++ b/llvm/test/MC/WebAssembly/reference-types.s @@ -27,6 +27,21 @@ ref_null_test: drop end_function +# CHECK-LABEL: ref_test_test: +# CHECK: ref.null_func # encoding: [0xd0,0x70] +# CHECK: ref.test () -> () # encoding: [0xfb,0x14,0x80'A',0x80'A',0x80'A',0x80'A',A] +# CHECK: # fixup A - offset: 2, value: .Ltypeindex0@TYPEINDEX, kind: fixup_uleb128_i32 +# CHECK: ref.null_func # encoding: [0xd0,0x70] +# CHECK: ref.test () -> (i32) # encoding: [0xfb,0x14,0x80'A',0x80'A',0x80'A',0x80'A',A] +# CHECK: # fixup A - offset: 2, value: .Ltypeindex1@TYPEINDEX, kind: fixup_uleb128_i32 +ref_test_test: + .functype ref_test_test () -> (i32, i32) + ref.null_func + ref.test_func () -> () + ref.null_func + ref.test_func () -> (i32) + end_function + # CHECK-LABEL: ref_sig_test_funcref: # CHECK-NEXT: .functype ref_sig_test_funcref (funcref) -> (funcref) ref_sig_test_funcref: >From 6a4693a238723f78c9126071b0b0be2ae5481af9 Mon Sep 17 00:00:00 2001 From: Hood Chatham Date: Mon, 12 May 2025 20:19:55 -0400 Subject: [PATCH 2/9] Rename to ref.test --- .../lib/Target/WebAssembly/AsmParser/WebAssemblyAsmParser.cpp | 2 +- llvm/lib/Target/WebAssembly/WebAssemblyInstrRef.td| 2 +- llvm/test/MC/WebAssembly/reference-types.s| 4 ++-- 3 files changed, 4 insertions(+), 4 deletions(-) diff --git a/llvm/lib/Target/WebAssembly/AsmParser/WebAssemblyAsmParser.cpp b/llvm/lib/Target/WebAssembly/AsmParser/WebAssemblyAsmParser.cpp index 3fad1710c30c4..c1b3936c1dcec 100644 --- a/llvm/lib/Target/WebAssembly/AsmParser/WebAssemblyAsmParser.cpp +++ b/llvm/lib/Target/WebAssembly/AsmParser/WebAssemblyAsmParser.cpp @@ -668,7 +668,7 @@ class WebAssemblyAsmParser final : public MCTargetAsmParser { if (parseFunctionTableOperand(&FunctionTable)) return true; ExpectFuncType = true; -} else if (Name == "ref.test_func") { +} else if (Name == "ref.test") { ExpectFuncType = true; } diff --git a/llvm/lib/Target/WebAssembly/WebAssemblyInstrRef.td b/llvm/lib/Target/WebAssembly/WebAssemblyInstrRef.td index 8786d78c8e5af..40b87a084c687 100644 --- a/llvm/lib/Target/WebAssembly/WebAssemblyInstrRef.td +++ b/llvm/lib/Target/WebAssembly/WebAssemblyInstrRef.td @@ -42,7 +42,7 @@ defm REF_TEST_FUNCREF : (outs), (ins TypeIndex:$type), [], -"ref.test_func\t$type, $ref", "ref.test_func $type", 0xfb14>; +"ref.test\t$type, $ref", "ref.test $type", 0xfb14>; defm "" : REF_I; defm "" : REF_I; diff --git a/llvm/test/MC/WebAssembly/reference-types.s b/llvm/test/MC/WebAssembly/reference-types.s index 8f3bca79bb68f..08aafb23969eb 100644 --- a/llvm/test/MC/WebAssembly/reference-types.s +++ b/llvm/test/MC/WebAssembly/reference-types.s @@ -37,9 +37,9 @@ ref_null_test: ref_test_test: .functype ref_test_test () -> (i32, i32) ref.null_func - ref.test_func () -> () + ref.test () -> () ref.null_func - ref.test_func () -> (i32) + ref.test () -> (i32) end_function # CHECK-LABEL: ref_sig_te
[clang] [llvm] [WebAssembly,llvm] Add llvm.wasm.ref.test.func intrinsic (PR #147076)
hoodmane wrote: The goal is as an alternative to `EMULATE_FUNCTION_POINTER_CASTS` for projects like Python and GLib that do dispatch with sometimes-incorrect function pointers. In particular, rather than having to `call_indirect` a function pointer and find out whether or not we trap, I want a way to query the function pointer ahead of time for whether the call will succeed. In the ideal case the solution should: 1. work on wasm32-unknown-unknown so it's portable between Emscripten and wasi 2. not require dropping down to assembly or JS My idea is to add a clang builtin `__builtin_wasm_test_function_pointer_signature` so I can replace this whole file: https://github.com/python/cpython/blob/main/Python/emscripten_trampoline.c with: ```C typedef PyObject* (*zero_arg)(void); typedef PyObject* (*one_arg)(PyObject*); typedef PyObject* (*two_arg)(PyObject*, PyObject*); typedef PyObject* (*three_arg)(PyObject*, PyObject*, PyObject*); PyObject* _PyEM_TrampolineCall(PyCFunctionWithKeywords func, PyObject* self, PyObject* args, PyObject* kw) { if (__builtin_wasm_test_function_pointer_signature((zero_arg)func)) return ((zero_arg)func)(); if (__builtin_wasm_test_function_pointer_signature((one_arg)func)) return ((one_arg)func)(self); if (__builtin_wasm_test_function_pointer_signature((two_arg)func)) return ((two_arg)func)(self, args); if (__builtin_wasm_test_function_pointer_signature((three_arg)func)) return ((three_arg)func)(self, args, kw); PyErr_SetString(PyExc_SystemError, "Handler has unexpected signature"); return NULL; } ``` https://github.com/llvm/llvm-project/pull/147076 ___ cfe-commits mailing list cfe-commits@lists.llvm.org https://lists.llvm.org/cgi-bin/mailman/listinfo/cfe-commits
[clang] [llvm] [WebAssembly,llvm] Add llvm.wasm.ref.test.func intrinsic (PR #147076)
hoodmane wrote: Closing in favor of #147486. https://github.com/llvm/llvm-project/pull/147076 ___ cfe-commits mailing list cfe-commits@lists.llvm.org https://lists.llvm.org/cgi-bin/mailman/listinfo/cfe-commits
[clang] [llvm] [WebAssembly,llvm] Add llvm.wasm.ref.test.func intrinsic (PR #147076)
https://github.com/hoodmane closed https://github.com/llvm/llvm-project/pull/147076 ___ cfe-commits mailing list cfe-commits@lists.llvm.org https://lists.llvm.org/cgi-bin/mailman/listinfo/cfe-commits