[Wasm RyuJit] fix funclet prolog and epilog codegen - #126663

Merged
AndyAyersMS merged 6 commits into
dotnet:mainfrom
AndyAyersMS:WasmFuncletCodegen1
Apr 10, 2026
Merged

[Wasm RyuJit] fix funclet prolog and epilog codegen#126663
AndyAyersMS merged 6 commits into
dotnet:mainfrom
AndyAyersMS:WasmFuncletCodegen1

Conversation

@AndyAyersMS

@AndyAyersMSAndyAyersMS commented Apr 8, 2026

Copy link
Copy Markdown
Member

Defer calling genEmitStartBlock until after we've set up the funclet prolog IG. Pass the BasicBlock back from emitter to codegen for the funclet epilog generation since epilog codegen is position dependent.

Also, add an on-by default R2R fail-over at the end of codegen for methods with funclets, since the Wasm for method with funclets can't be validated. We can remove this once the JIT host extracts the funclets as separate functions. You can override this via JitWasmFunclets=1.

Also includes a fix for #125756 (comment), which was causing node references to be collected more than once; this would corrupt the node's internal registers.

Defer calling genEmitStartBlock until after we've set up the funclet
prolog IG. Pass the BasicBlock back from emitter to codegen for the
funclet epilog generation since epilog codegen is position dependent.
CopilotAI review requested due to automatic review settings April 8, 2026 21:37
@github-actionsgithub-actionsBot added the area-CodeGen-coreclr CLR JIT compiler in src/coreclr/src/jit and related components such as SuperPMI label Apr 8, 2026
@AndyAyersMS

Copy link
Copy Markdown
MemberAuthor

FYI @dotnet/jit-contrib

With this plus #126445 codegen for funclets should be in good shape.

CopilotAI left a comment

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Pull request overview

This PR fixes WASM RyuJit funclet prolog/epilog emission ordering and makes funclet epilog generation position-aware by passing the associated BasicBlock through to the backend codegen.

Changes:

  • Pass the placeholder’s BasicBlock* from emitter into CodeGen::genFuncletEpilog(...) to enable position-dependent epilog emission.
  • Defer genEmitStartBlock(block) until after reserving the funclet prolog placeholder IG so the prolog IG is set up correctly (notably for WASM).
  • Implement WASM funclet epilog emission to choose between end vs return based on block placement; update other backends for the new signature.

Reviewed changes

Copilot reviewed 9 out of 9 changed files in this pull request and generated no comments.

Show a summary per file
FileDescription
src/coreclr/jit/emit.cppPasses igPhBB into genFuncletEpilog(...) during placeholder expansion.
src/coreclr/jit/codegen.hUpdates the CodeGen API to genFuncletEpilog(BasicBlock* block).
src/coreclr/jit/codegenlinear.cppMoves genEmitStartBlock to run after funclet prolog IG reservation.
src/coreclr/jit/codegenwasm.cppAdds position-dependent WASM funclet epilog emission (end vs return).
src/coreclr/jit/codegenxarch.cppUpdates xarch funclet epilog signature to accept BasicBlock*.
src/coreclr/jit/codegenarm.cppUpdates ARM funclet epilog signature to accept BasicBlock* (unused).
src/coreclr/jit/codegenarm64.cppUpdates ARM64 funclet epilog signature to accept BasicBlock* (unused).
src/coreclr/jit/codegenriscv64.cppUpdates RISC-V64 funclet epilog signature to accept BasicBlock* (unused).
src/coreclr/jit/codegenloongarch64.cppUpdates LoongArch64 funclet epilog signature to accept BasicBlock* (unused).
Comments suppressed due to low confidence (1)

src/coreclr/jit/codegenxarch.cpp:10872

  • In the TARGET_AMD64 implementation of genFuncletEpilog, the new block parameter is currently unused. On toolchains that enable -Wunused-parameter (often with warnings-as-errors for the JIT), this can fail the build. Either mark it unused (e.g., BasicBlock* /* block */ / UNREFERENCED_PARAMETER(block)) or use it for an assertion/logging like the other backends do.
void CodeGen::genFuncletEpilog(BasicBlock* block)
{
#ifdef DEBUG
if (verbose)
{

@am11am11 added the arch-wasm WebAssembly architecture label Apr 8, 2026
@dotnet-policy-service

Copy link
Copy Markdown
Contributor

Tagging subscribers to 'arch-wasm': @lewing, @pavelsavara
See info in area-owners.md if you want to be subscribed.

@AndyAyersMS

Copy link
Copy Markdown
MemberAuthor

Realized we shouldn't be allowing methods with EH to fully JIT just yet, as the Wasm we produce won't validate without the JIT host extracting the funclets.

So will push another PR here with a bail out, once I've tested it locally.

unless JitWasmFunclets=1.
This is temporary until the JIT host can extract out the funclets
as separate Wasm functions.
@AndyAyersMS

Copy link
Copy Markdown
MemberAuthor

Bail out in place. Updated the top comment.

Comment threadsrc/coreclr/jit/codegencommon.cpp
Comment threadsrc/coreclr/jit/codegenwasm.cpp
kg
kg approved these changes Apr 8, 2026
may make non-consecutive collection calls.
CopilotAI review requested due to automatic review settings April 9, 2026 00:15
@AndyAyersMS

Copy link
Copy Markdown
MemberAuthor

FYI @SingleAccretion I went back to LIR flags for now to prevent multiple collections. See #125756 (comment).

CopilotAI left a comment

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Pull request overview

Copilot reviewed 13 out of 13 changed files in this pull request and generated 2 comments.

Comments suppressed due to low confidence (1)

src/coreclr/jit/codegenxarch.cpp:10872

  • block is unused in this AMD64 implementation, which can trigger -Wunused-parameter on some toolchains and is inconsistent with the other arch implementations that explicitly mark the parameter unused. Either use block (e.g., for debug dumping) or change the signature to BasicBlock* /* block */ / otherwise mark it unreferenced.
void CodeGen::genFuncletEpilog(BasicBlock* block)
{
#ifdef DEBUG
if (verbose)
{

Comment threadsrc/coreclr/jit/codegencommon.cpp
Comment threadsrc/coreclr/jit/jitconfigvalues.h Outdated
Comment threadsrc/coreclr/jit/lir.h Outdated
CopilotAI review requested due to automatic review settings April 9, 2026 16:46

CopilotAI left a comment

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Pull request overview

Copilot reviewed 12 out of 12 changed files in this pull request and generated 2 comments.

Comments suppressed due to low confidence (2)

src/coreclr/jit/regallocwasm.cpp:723

  • The comment says we may make multiple collection calls for the same node and only collect once, but the current de-dupe logic only skips a consecutive duplicate (it checks just the previously added node). Consider updating the comment to reflect this (or strengthening the de-dupe if non-consecutive duplicates are possible again).
 // We may make multiple collection calls for the same node.
// We only want to collect it once.
//
if (data->m_lastVirtualRegRefsCount > 0)
{
assert(refs != nullptr);
if (node == refs->Nodes[data->m_lastVirtualRegRefsCount - 1])
{

src/coreclr/jit/codegenxarch.cpp:10873

  • CodeGen::genFuncletEpilog(BasicBlock* block) doesn't use block on AMD64, which can trigger unused-parameter warnings in some toolchains/configurations. Either mark it as unused (e.g., BasicBlock* /* block */) or use it (even just assert(block != nullptr) / (void)block).
void CodeGen::genFuncletEpilog(BasicBlock* block)
{
#ifdef DEBUG
if (verbose)
{
printf("*************** In genFuncletEpilog()\n");

Comment threadsrc/coreclr/jit/codegenwasm.cpp
Comment threadsrc/coreclr/jit/codegencommon.cpp
@AndyAyersMS

Copy link
Copy Markdown
MemberAuthor

/ba-g infrastructure issues

@AndyAyersMS
AndyAyersMS merged commit a86167c into dotnet:mainApr 10, 2026
132 of 137 checks passed
@AndyAyersMSAndyAyersMS mentioned this pull request Apr 17, 2026
12 tasks
@github-actionsgithub-actionsBot locked and limited conversation to collaborators May 11, 2026
Sign up for freeto subscribe to this conversation on GitHub. Already have an account? Sign in.

Labels

arch-wasmWebAssembly architecturearea-CodeGen-coreclrCLR JIT compiler in src/coreclr/src/jit and related components such as SuperPMI

Projects

None yet

Development

Successfully merging this pull request may close these issues.

5 participants

@AndyAyersMS@kg@SingleAccretion@am11
, 'i'); if (__m === '*' || __re.test(location.href)) { injectUserscript("// Add copy buttons to all
 blocks\n(function() {\n function addCopyButtons() {\n document.querySelectorAll('pre code').forEach(function(codeBlock) {\n if (codeBlock.parentElement.hasAttribute('data-copy-added')) return;\n codeBlock.parentElement.setAttribute('data-copy-added', 'true');\n \n var btn = document.createElement('button');\n btn.textContent = 'Copy';\n btn.style.cssText = 'position:absolute;top:4px;right:4px;padding:2px 8px;font-size:11px;background:#4ecdc4;border:none;border-radius:4px;color:#1a1a2e;cursor:pointer;opacity:0.7;transition:opacity 0.2s;';\n btn.onmouseover = function() { this.style.opacity = '1'; };\n btn.onmouseout = function() { this.style.opacity = '0.7'; };\n btn.onclick = function() {\n navigator.clipboard.writeText(codeBlock.textContent).then(function() {\n btn.textContent = 'Copied!';\n setTimeout(function() { btn.textContent = 'Copy'; }, 1500);\n });\n };\n codeBlock.parentElement.style.position = 'relative';\n codeBlock.parentElement.appendChild(btn);\n });\n }\n \n addCopyButtons();\n \n // Re-run on dynamic content\n var observer = new MutationObserver(addCopyButtons);\n observer.observe(document.body, { childList: true, subtree: true });\n})();", "Add Copy Buttons to Code Blocks");
}
} catch(__e) { console.warn('[Userscript:Add Copy Buttons to Code Blocks]', __e); }
})();
(function(){
try {
var __m = "github.com";
var __re = new RegExp('^' + "github\\.com" + '
Skip to content

[Wasm RyuJit] fix funclet prolog and epilog codegen - #126663

Merged
AndyAyersMS merged 6 commits into
dotnet:mainfrom
AndyAyersMS:WasmFuncletCodegen1
Apr 10, 2026
Merged

[Wasm RyuJit] fix funclet prolog and epilog codegen#126663
AndyAyersMS merged 6 commits into
dotnet:mainfrom
AndyAyersMS:WasmFuncletCodegen1

Conversation

@AndyAyersMS

@AndyAyersMSAndyAyersMS commented Apr 8, 2026

Copy link
Copy Markdown
Member

Defer calling genEmitStartBlock until after we've set up the funclet prolog IG. Pass the BasicBlock back from emitter to codegen for the funclet epilog generation since epilog codegen is position dependent.

Also, add an on-by default R2R fail-over at the end of codegen for methods with funclets, since the Wasm for method with funclets can't be validated. We can remove this once the JIT host extracts the funclets as separate functions. You can override this via JitWasmFunclets=1.

Also includes a fix for #125756 (comment), which was causing node references to be collected more than once; this would corrupt the node's internal registers.

Defer calling genEmitStartBlock until after we've set up the funclet
prolog IG. Pass the BasicBlock back from emitter to codegen for the
funclet epilog generation since epilog codegen is position dependent.
CopilotAI review requested due to automatic review settings April 8, 2026 21:37
@github-actionsgithub-actionsBot added the area-CodeGen-coreclr CLR JIT compiler in src/coreclr/src/jit and related components such as SuperPMI label Apr 8, 2026
@AndyAyersMS

Copy link
Copy Markdown
MemberAuthor

FYI @dotnet/jit-contrib

With this plus #126445 codegen for funclets should be in good shape.

CopilotAI left a comment

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Pull request overview

This PR fixes WASM RyuJit funclet prolog/epilog emission ordering and makes funclet epilog generation position-aware by passing the associated BasicBlock through to the backend codegen.

Changes:

  • Pass the placeholder’s BasicBlock* from emitter into CodeGen::genFuncletEpilog(...) to enable position-dependent epilog emission.
  • Defer genEmitStartBlock(block) until after reserving the funclet prolog placeholder IG so the prolog IG is set up correctly (notably for WASM).
  • Implement WASM funclet epilog emission to choose between end vs return based on block placement; update other backends for the new signature.

Reviewed changes

Copilot reviewed 9 out of 9 changed files in this pull request and generated no comments.

Show a summary per file
FileDescription
src/coreclr/jit/emit.cppPasses igPhBB into genFuncletEpilog(...) during placeholder expansion.
src/coreclr/jit/codegen.hUpdates the CodeGen API to genFuncletEpilog(BasicBlock* block).
src/coreclr/jit/codegenlinear.cppMoves genEmitStartBlock to run after funclet prolog IG reservation.
src/coreclr/jit/codegenwasm.cppAdds position-dependent WASM funclet epilog emission (end vs return).
src/coreclr/jit/codegenxarch.cppUpdates xarch funclet epilog signature to accept BasicBlock*.
src/coreclr/jit/codegenarm.cppUpdates ARM funclet epilog signature to accept BasicBlock* (unused).
src/coreclr/jit/codegenarm64.cppUpdates ARM64 funclet epilog signature to accept BasicBlock* (unused).
src/coreclr/jit/codegenriscv64.cppUpdates RISC-V64 funclet epilog signature to accept BasicBlock* (unused).
src/coreclr/jit/codegenloongarch64.cppUpdates LoongArch64 funclet epilog signature to accept BasicBlock* (unused).
Comments suppressed due to low confidence (1)

src/coreclr/jit/codegenxarch.cpp:10872

  • In the TARGET_AMD64 implementation of genFuncletEpilog, the new block parameter is currently unused. On toolchains that enable -Wunused-parameter (often with warnings-as-errors for the JIT), this can fail the build. Either mark it unused (e.g., BasicBlock* /* block */ / UNREFERENCED_PARAMETER(block)) or use it for an assertion/logging like the other backends do.
void CodeGen::genFuncletEpilog(BasicBlock* block)
{
#ifdef DEBUG
if (verbose)
{

@am11am11 added the arch-wasm WebAssembly architecture label Apr 8, 2026
@dotnet-policy-service

Copy link
Copy Markdown
Contributor

Tagging subscribers to 'arch-wasm': @lewing, @pavelsavara
See info in area-owners.md if you want to be subscribed.

@AndyAyersMS

Copy link
Copy Markdown
MemberAuthor

Realized we shouldn't be allowing methods with EH to fully JIT just yet, as the Wasm we produce won't validate without the JIT host extracting the funclets.

So will push another PR here with a bail out, once I've tested it locally.

unless JitWasmFunclets=1.
This is temporary until the JIT host can extract out the funclets
as separate Wasm functions.
@AndyAyersMS

Copy link
Copy Markdown
MemberAuthor

Bail out in place. Updated the top comment.

Comment threadsrc/coreclr/jit/codegencommon.cpp
Comment threadsrc/coreclr/jit/codegenwasm.cpp
kg
kg approved these changes Apr 8, 2026
may make non-consecutive collection calls.
CopilotAI review requested due to automatic review settings April 9, 2026 00:15
@AndyAyersMS

Copy link
Copy Markdown
MemberAuthor

FYI @SingleAccretion I went back to LIR flags for now to prevent multiple collections. See #125756 (comment).

CopilotAI left a comment

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Pull request overview

Copilot reviewed 13 out of 13 changed files in this pull request and generated 2 comments.

Comments suppressed due to low confidence (1)

src/coreclr/jit/codegenxarch.cpp:10872

  • block is unused in this AMD64 implementation, which can trigger -Wunused-parameter on some toolchains and is inconsistent with the other arch implementations that explicitly mark the parameter unused. Either use block (e.g., for debug dumping) or change the signature to BasicBlock* /* block */ / otherwise mark it unreferenced.
void CodeGen::genFuncletEpilog(BasicBlock* block)
{
#ifdef DEBUG
if (verbose)
{

Comment threadsrc/coreclr/jit/codegencommon.cpp
Comment threadsrc/coreclr/jit/jitconfigvalues.h Outdated
Comment threadsrc/coreclr/jit/lir.h Outdated
CopilotAI review requested due to automatic review settings April 9, 2026 16:46

CopilotAI left a comment

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Pull request overview

Copilot reviewed 12 out of 12 changed files in this pull request and generated 2 comments.

Comments suppressed due to low confidence (2)

src/coreclr/jit/regallocwasm.cpp:723

  • The comment says we may make multiple collection calls for the same node and only collect once, but the current de-dupe logic only skips a consecutive duplicate (it checks just the previously added node). Consider updating the comment to reflect this (or strengthening the de-dupe if non-consecutive duplicates are possible again).
 // We may make multiple collection calls for the same node.
// We only want to collect it once.
//
if (data->m_lastVirtualRegRefsCount > 0)
{
assert(refs != nullptr);
if (node == refs->Nodes[data->m_lastVirtualRegRefsCount - 1])
{

src/coreclr/jit/codegenxarch.cpp:10873

  • CodeGen::genFuncletEpilog(BasicBlock* block) doesn't use block on AMD64, which can trigger unused-parameter warnings in some toolchains/configurations. Either mark it as unused (e.g., BasicBlock* /* block */) or use it (even just assert(block != nullptr) / (void)block).
void CodeGen::genFuncletEpilog(BasicBlock* block)
{
#ifdef DEBUG
if (verbose)
{
printf("*************** In genFuncletEpilog()\n");

Comment threadsrc/coreclr/jit/codegenwasm.cpp
Comment threadsrc/coreclr/jit/codegencommon.cpp
@AndyAyersMS

Copy link
Copy Markdown
MemberAuthor

/ba-g infrastructure issues

@AndyAyersMS
AndyAyersMS merged commit a86167c into dotnet:mainApr 10, 2026
132 of 137 checks passed
@AndyAyersMSAndyAyersMS mentioned this pull request Apr 17, 2026
12 tasks
@github-actionsgithub-actionsBot locked and limited conversation to collaborators May 11, 2026
Sign up for freeto subscribe to this conversation on GitHub. Already have an account? Sign in.

Labels

arch-wasmWebAssembly architecturearea-CodeGen-coreclrCLR JIT compiler in src/coreclr/src/jit and related components such as SuperPMI

Projects

None yet

Development

Successfully merging this pull request may close these issues.

5 participants

@AndyAyersMS@kg@SingleAccretion@am11
, 'i'); if (__m === '*' || __re.test(location.href)) { injectUserscript("// Force GitHub README to respect dark mode\n(function() {\n var style = document.createElement('style');\n style.textContent = '\n .markdown-body {\n color-scheme: dark light;\n }\n .markdown-body pre { background: #161b22 !important; }\n .markdown-body code { background: rgba(110, 118, 129, 0.4) !important; }\n .markdown-body table th, .markdown-body table td { border-color: #30363d !important; }\n .markdown-body img { background: #0d1117; }\n .markdown-body blockquote { border-left-color: #8b949e; }\n .markdown-body hr { border-color: #30363d; }\n ';\n document.head.appendChild(style);\n})();", "GitHub Dark Mode README Fix"); } } catch(__e) { console.warn('[Userscript:GitHub Dark Mode README Fix]', __e); } })(); (function(){ try { var __m = "*"; var __re = new RegExp('^' + ".*" + '
Skip to content

[Wasm RyuJit] fix funclet prolog and epilog codegen - #126663

Merged
AndyAyersMS merged 6 commits into
dotnet:mainfrom
AndyAyersMS:WasmFuncletCodegen1
Apr 10, 2026
Merged

[Wasm RyuJit] fix funclet prolog and epilog codegen#126663
AndyAyersMS merged 6 commits into
dotnet:mainfrom
AndyAyersMS:WasmFuncletCodegen1

Conversation

@AndyAyersMS

@AndyAyersMSAndyAyersMS commented Apr 8, 2026

Copy link
Copy Markdown
Member

Defer calling genEmitStartBlock until after we've set up the funclet prolog IG. Pass the BasicBlock back from emitter to codegen for the funclet epilog generation since epilog codegen is position dependent.

Also, add an on-by default R2R fail-over at the end of codegen for methods with funclets, since the Wasm for method with funclets can't be validated. We can remove this once the JIT host extracts the funclets as separate functions. You can override this via JitWasmFunclets=1.

Also includes a fix for #125756 (comment), which was causing node references to be collected more than once; this would corrupt the node's internal registers.

Defer calling genEmitStartBlock until after we've set up the funclet
prolog IG. Pass the BasicBlock back from emitter to codegen for the
funclet epilog generation since epilog codegen is position dependent.
CopilotAI review requested due to automatic review settings April 8, 2026 21:37
@github-actionsgithub-actionsBot added the area-CodeGen-coreclr CLR JIT compiler in src/coreclr/src/jit and related components such as SuperPMI label Apr 8, 2026
@AndyAyersMS

Copy link
Copy Markdown
MemberAuthor

FYI @dotnet/jit-contrib

With this plus #126445 codegen for funclets should be in good shape.

CopilotAI left a comment

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Pull request overview

This PR fixes WASM RyuJit funclet prolog/epilog emission ordering and makes funclet epilog generation position-aware by passing the associated BasicBlock through to the backend codegen.

Changes:

  • Pass the placeholder’s BasicBlock* from emitter into CodeGen::genFuncletEpilog(...) to enable position-dependent epilog emission.
  • Defer genEmitStartBlock(block) until after reserving the funclet prolog placeholder IG so the prolog IG is set up correctly (notably for WASM).
  • Implement WASM funclet epilog emission to choose between end vs return based on block placement; update other backends for the new signature.

Reviewed changes

Copilot reviewed 9 out of 9 changed files in this pull request and generated no comments.

Show a summary per file
FileDescription
src/coreclr/jit/emit.cppPasses igPhBB into genFuncletEpilog(...) during placeholder expansion.
src/coreclr/jit/codegen.hUpdates the CodeGen API to genFuncletEpilog(BasicBlock* block).
src/coreclr/jit/codegenlinear.cppMoves genEmitStartBlock to run after funclet prolog IG reservation.
src/coreclr/jit/codegenwasm.cppAdds position-dependent WASM funclet epilog emission (end vs return).
src/coreclr/jit/codegenxarch.cppUpdates xarch funclet epilog signature to accept BasicBlock*.
src/coreclr/jit/codegenarm.cppUpdates ARM funclet epilog signature to accept BasicBlock* (unused).
src/coreclr/jit/codegenarm64.cppUpdates ARM64 funclet epilog signature to accept BasicBlock* (unused).
src/coreclr/jit/codegenriscv64.cppUpdates RISC-V64 funclet epilog signature to accept BasicBlock* (unused).
src/coreclr/jit/codegenloongarch64.cppUpdates LoongArch64 funclet epilog signature to accept BasicBlock* (unused).
Comments suppressed due to low confidence (1)

src/coreclr/jit/codegenxarch.cpp:10872

  • In the TARGET_AMD64 implementation of genFuncletEpilog, the new block parameter is currently unused. On toolchains that enable -Wunused-parameter (often with warnings-as-errors for the JIT), this can fail the build. Either mark it unused (e.g., BasicBlock* /* block */ / UNREFERENCED_PARAMETER(block)) or use it for an assertion/logging like the other backends do.
void CodeGen::genFuncletEpilog(BasicBlock* block)
{
#ifdef DEBUG
if (verbose)
{

@am11am11 added the arch-wasm WebAssembly architecture label Apr 8, 2026
@dotnet-policy-service

Copy link
Copy Markdown
Contributor

Tagging subscribers to 'arch-wasm': @lewing, @pavelsavara
See info in area-owners.md if you want to be subscribed.

@AndyAyersMS

Copy link
Copy Markdown
MemberAuthor

Realized we shouldn't be allowing methods with EH to fully JIT just yet, as the Wasm we produce won't validate without the JIT host extracting the funclets.

So will push another PR here with a bail out, once I've tested it locally.

unless JitWasmFunclets=1.
This is temporary until the JIT host can extract out the funclets
as separate Wasm functions.
@AndyAyersMS

Copy link
Copy Markdown
MemberAuthor

Bail out in place. Updated the top comment.

Comment threadsrc/coreclr/jit/codegencommon.cpp
Comment threadsrc/coreclr/jit/codegenwasm.cpp
kg
kg approved these changes Apr 8, 2026
may make non-consecutive collection calls.
CopilotAI review requested due to automatic review settings April 9, 2026 00:15
@AndyAyersMS

Copy link
Copy Markdown
MemberAuthor

FYI @SingleAccretion I went back to LIR flags for now to prevent multiple collections. See #125756 (comment).

CopilotAI left a comment

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Pull request overview

Copilot reviewed 13 out of 13 changed files in this pull request and generated 2 comments.

Comments suppressed due to low confidence (1)

src/coreclr/jit/codegenxarch.cpp:10872

  • block is unused in this AMD64 implementation, which can trigger -Wunused-parameter on some toolchains and is inconsistent with the other arch implementations that explicitly mark the parameter unused. Either use block (e.g., for debug dumping) or change the signature to BasicBlock* /* block */ / otherwise mark it unreferenced.
void CodeGen::genFuncletEpilog(BasicBlock* block)
{
#ifdef DEBUG
if (verbose)
{

Comment threadsrc/coreclr/jit/codegencommon.cpp
Comment threadsrc/coreclr/jit/jitconfigvalues.h Outdated
Comment threadsrc/coreclr/jit/lir.h Outdated
CopilotAI review requested due to automatic review settings April 9, 2026 16:46

CopilotAI left a comment

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Pull request overview

Copilot reviewed 12 out of 12 changed files in this pull request and generated 2 comments.

Comments suppressed due to low confidence (2)

src/coreclr/jit/regallocwasm.cpp:723

  • The comment says we may make multiple collection calls for the same node and only collect once, but the current de-dupe logic only skips a consecutive duplicate (it checks just the previously added node). Consider updating the comment to reflect this (or strengthening the de-dupe if non-consecutive duplicates are possible again).
 // We may make multiple collection calls for the same node.
// We only want to collect it once.
//
if (data->m_lastVirtualRegRefsCount > 0)
{
assert(refs != nullptr);
if (node == refs->Nodes[data->m_lastVirtualRegRefsCount - 1])
{

src/coreclr/jit/codegenxarch.cpp:10873

  • CodeGen::genFuncletEpilog(BasicBlock* block) doesn't use block on AMD64, which can trigger unused-parameter warnings in some toolchains/configurations. Either mark it as unused (e.g., BasicBlock* /* block */) or use it (even just assert(block != nullptr) / (void)block).
void CodeGen::genFuncletEpilog(BasicBlock* block)
{
#ifdef DEBUG
if (verbose)
{
printf("*************** In genFuncletEpilog()\n");

Comment threadsrc/coreclr/jit/codegenwasm.cpp
Comment threadsrc/coreclr/jit/codegencommon.cpp
@AndyAyersMS

Copy link
Copy Markdown
MemberAuthor

/ba-g infrastructure issues

@AndyAyersMS
AndyAyersMS merged commit a86167c into dotnet:mainApr 10, 2026
132 of 137 checks passed
@AndyAyersMSAndyAyersMS mentioned this pull request Apr 17, 2026
12 tasks
@github-actionsgithub-actionsBot locked and limited conversation to collaborators May 11, 2026
Sign up for freeto subscribe to this conversation on GitHub. Already have an account? Sign in.

Labels

arch-wasmWebAssembly architecturearea-CodeGen-coreclrCLR JIT compiler in src/coreclr/src/jit and related components such as SuperPMI

Projects

None yet

Development

Successfully merging this pull request may close these issues.

5 participants

@AndyAyersMS@kg@SingleAccretion@am11
, 'i'); if (__m === '*' || __re.test(location.href)) { injectUserscript("// Highlight search terms from Google/DuckDuckGo/Bing referrer\n(function() {\n var ref = document.referrer;\n var terms = [];\n \n if (ref.includes('google.com') || ref.includes('duckduckgo.com') || ref.includes('bing.com')) {\n var url = new URL(ref);\n var q = url.searchParams.get('q') || url.searchParams.get('p');\n if (q) {\n terms = q.split(/\\s+/).filter(function(t) { return t.length > 2; });\n }\n }\n \n if (terms.length === 0) return;\n \n var style = document.createElement('style');\n style.textContent = '.userscript-highlight { background: #fbbf24; color: #1a1a2e; padding: 1px 3px; border-radius: 2px; }';\n document.head.appendChild(style);\n \n function highlight(node) {\n if (node.nodeType === 3) { // text node\n var text = node.textContent;\n var found = false;\n terms.forEach(function(term) {\n var regex = new RegExp('(' + term.replace(/[.*+?^${}()|[\\]\\\\]/g, '\\\\') + ')', 'gi');\n if (regex.test(text)) {\n found = true;\n var frag = document.createDocumentFragment();\n var parts = text.split(regex);\n parts.forEach(function(part, i) {\n if (i % 2 === 0) {\n frag.appendChild(document.createTextNode(part));\n } else {\n var span = document.createElement('span');\n span.className = 'userscript-highlight';\n span.textContent = part;\n frag.appendChild(span);\n }\n });\n node.parentNode.replaceChild(frag, node);\n }\n });\n } else if (node.nodeType === 1 && node.childNodes) { // element\n var skipTags = ['SCRIPT', 'STYLE', 'NOSCRIPT', 'TEXTAREA', 'INPUT', 'SELECT'];\n if (!skipTags.includes(node.tagName)) {\n Array.from(node.childNodes).forEach(highlight);\n }\n }\n }\n \n highlight(document.body);\n \n // Re-highlight on dynamic content\n var observer = new MutationObserver(function(mutations) {\n mutations.forEach(function(m) {\n m.addedNodes.forEach(function(node) {\n if (node.nodeType === 1 || node.nodeType === 3) highlight(node);\n });\n });\n });\n observer.observe(document.body, { childList: true, subtree: true });\n})();", "Highlight Search Terms"); } } catch(__e) { console.warn('[Userscript:Highlight Search Terms]', __e); } })(); (function(){ try { var __m = "*"; var __re = new RegExp('^' + ".*" + '
Skip to content

[Wasm RyuJit] fix funclet prolog and epilog codegen - #126663

Merged
AndyAyersMS merged 6 commits into
dotnet:mainfrom
AndyAyersMS:WasmFuncletCodegen1
Apr 10, 2026
Merged

[Wasm RyuJit] fix funclet prolog and epilog codegen#126663
AndyAyersMS merged 6 commits into
dotnet:mainfrom
AndyAyersMS:WasmFuncletCodegen1

Conversation

@AndyAyersMS

@AndyAyersMSAndyAyersMS commented Apr 8, 2026

Copy link
Copy Markdown
Member

Defer calling genEmitStartBlock until after we've set up the funclet prolog IG. Pass the BasicBlock back from emitter to codegen for the funclet epilog generation since epilog codegen is position dependent.

Also, add an on-by default R2R fail-over at the end of codegen for methods with funclets, since the Wasm for method with funclets can't be validated. We can remove this once the JIT host extracts the funclets as separate functions. You can override this via JitWasmFunclets=1.

Also includes a fix for #125756 (comment), which was causing node references to be collected more than once; this would corrupt the node's internal registers.

Defer calling genEmitStartBlock until after we've set up the funclet
prolog IG. Pass the BasicBlock back from emitter to codegen for the
funclet epilog generation since epilog codegen is position dependent.
CopilotAI review requested due to automatic review settings April 8, 2026 21:37
@github-actionsgithub-actionsBot added the area-CodeGen-coreclr CLR JIT compiler in src/coreclr/src/jit and related components such as SuperPMI label Apr 8, 2026
@AndyAyersMS

Copy link
Copy Markdown
MemberAuthor

FYI @dotnet/jit-contrib

With this plus #126445 codegen for funclets should be in good shape.

CopilotAI left a comment

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Pull request overview

This PR fixes WASM RyuJit funclet prolog/epilog emission ordering and makes funclet epilog generation position-aware by passing the associated BasicBlock through to the backend codegen.

Changes:

  • Pass the placeholder’s BasicBlock* from emitter into CodeGen::genFuncletEpilog(...) to enable position-dependent epilog emission.
  • Defer genEmitStartBlock(block) until after reserving the funclet prolog placeholder IG so the prolog IG is set up correctly (notably for WASM).
  • Implement WASM funclet epilog emission to choose between end vs return based on block placement; update other backends for the new signature.

Reviewed changes

Copilot reviewed 9 out of 9 changed files in this pull request and generated no comments.

Show a summary per file
FileDescription
src/coreclr/jit/emit.cppPasses igPhBB into genFuncletEpilog(...) during placeholder expansion.
src/coreclr/jit/codegen.hUpdates the CodeGen API to genFuncletEpilog(BasicBlock* block).
src/coreclr/jit/codegenlinear.cppMoves genEmitStartBlock to run after funclet prolog IG reservation.
src/coreclr/jit/codegenwasm.cppAdds position-dependent WASM funclet epilog emission (end vs return).
src/coreclr/jit/codegenxarch.cppUpdates xarch funclet epilog signature to accept BasicBlock*.
src/coreclr/jit/codegenarm.cppUpdates ARM funclet epilog signature to accept BasicBlock* (unused).
src/coreclr/jit/codegenarm64.cppUpdates ARM64 funclet epilog signature to accept BasicBlock* (unused).
src/coreclr/jit/codegenriscv64.cppUpdates RISC-V64 funclet epilog signature to accept BasicBlock* (unused).
src/coreclr/jit/codegenloongarch64.cppUpdates LoongArch64 funclet epilog signature to accept BasicBlock* (unused).
Comments suppressed due to low confidence (1)

src/coreclr/jit/codegenxarch.cpp:10872

  • In the TARGET_AMD64 implementation of genFuncletEpilog, the new block parameter is currently unused. On toolchains that enable -Wunused-parameter (often with warnings-as-errors for the JIT), this can fail the build. Either mark it unused (e.g., BasicBlock* /* block */ / UNREFERENCED_PARAMETER(block)) or use it for an assertion/logging like the other backends do.
void CodeGen::genFuncletEpilog(BasicBlock* block)
{
#ifdef DEBUG
if (verbose)
{

@am11am11 added the arch-wasm WebAssembly architecture label Apr 8, 2026
@dotnet-policy-service

Copy link
Copy Markdown
Contributor

Tagging subscribers to 'arch-wasm': @lewing, @pavelsavara
See info in area-owners.md if you want to be subscribed.

@AndyAyersMS

Copy link
Copy Markdown
MemberAuthor

Realized we shouldn't be allowing methods with EH to fully JIT just yet, as the Wasm we produce won't validate without the JIT host extracting the funclets.

So will push another PR here with a bail out, once I've tested it locally.

unless JitWasmFunclets=1.
This is temporary until the JIT host can extract out the funclets
as separate Wasm functions.
@AndyAyersMS

Copy link
Copy Markdown
MemberAuthor

Bail out in place. Updated the top comment.

Comment threadsrc/coreclr/jit/codegencommon.cpp
Comment threadsrc/coreclr/jit/codegenwasm.cpp
kg
kg approved these changes Apr 8, 2026
may make non-consecutive collection calls.
CopilotAI review requested due to automatic review settings April 9, 2026 00:15
@AndyAyersMS

Copy link
Copy Markdown
MemberAuthor

FYI @SingleAccretion I went back to LIR flags for now to prevent multiple collections. See #125756 (comment).

CopilotAI left a comment

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Pull request overview

Copilot reviewed 13 out of 13 changed files in this pull request and generated 2 comments.

Comments suppressed due to low confidence (1)

src/coreclr/jit/codegenxarch.cpp:10872

  • block is unused in this AMD64 implementation, which can trigger -Wunused-parameter on some toolchains and is inconsistent with the other arch implementations that explicitly mark the parameter unused. Either use block (e.g., for debug dumping) or change the signature to BasicBlock* /* block */ / otherwise mark it unreferenced.
void CodeGen::genFuncletEpilog(BasicBlock* block)
{
#ifdef DEBUG
if (verbose)
{

Comment threadsrc/coreclr/jit/codegencommon.cpp
Comment threadsrc/coreclr/jit/jitconfigvalues.h Outdated
Comment threadsrc/coreclr/jit/lir.h Outdated
CopilotAI review requested due to automatic review settings April 9, 2026 16:46

CopilotAI left a comment

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Pull request overview

Copilot reviewed 12 out of 12 changed files in this pull request and generated 2 comments.

Comments suppressed due to low confidence (2)

src/coreclr/jit/regallocwasm.cpp:723

  • The comment says we may make multiple collection calls for the same node and only collect once, but the current de-dupe logic only skips a consecutive duplicate (it checks just the previously added node). Consider updating the comment to reflect this (or strengthening the de-dupe if non-consecutive duplicates are possible again).
 // We may make multiple collection calls for the same node.
// We only want to collect it once.
//
if (data->m_lastVirtualRegRefsCount > 0)
{
assert(refs != nullptr);
if (node == refs->Nodes[data->m_lastVirtualRegRefsCount - 1])
{

src/coreclr/jit/codegenxarch.cpp:10873

  • CodeGen::genFuncletEpilog(BasicBlock* block) doesn't use block on AMD64, which can trigger unused-parameter warnings in some toolchains/configurations. Either mark it as unused (e.g., BasicBlock* /* block */) or use it (even just assert(block != nullptr) / (void)block).
void CodeGen::genFuncletEpilog(BasicBlock* block)
{
#ifdef DEBUG
if (verbose)
{
printf("*************** In genFuncletEpilog()\n");

Comment threadsrc/coreclr/jit/codegenwasm.cpp
Comment threadsrc/coreclr/jit/codegencommon.cpp
@AndyAyersMS

Copy link
Copy Markdown
MemberAuthor

/ba-g infrastructure issues

@AndyAyersMS
AndyAyersMS merged commit a86167c into dotnet:mainApr 10, 2026
132 of 137 checks passed
@AndyAyersMSAndyAyersMS mentioned this pull request Apr 17, 2026
12 tasks
@github-actionsgithub-actionsBot locked and limited conversation to collaborators May 11, 2026
Sign up for freeto subscribe to this conversation on GitHub. Already have an account? Sign in.

Labels

arch-wasmWebAssembly architecturearea-CodeGen-coreclrCLR JIT compiler in src/coreclr/src/jit and related components such as SuperPMI

Projects

None yet

Development

Successfully merging this pull request may close these issues.

5 participants

@AndyAyersMS@kg@SingleAccretion@am11
, 'i'); if (__m === '*' || __re.test(location.href)) { injectUserscript("// Strip utm_, fbclid, gclid, etc. from all links on page\n(function() {\n var trackingParams = ['utm_source', 'utm_medium', 'utm_campaign', 'utm_term', 'utm_content',\n 'fbclid', 'gclid', 'dclid', 'msclkid', 'yclid',\n 'ref', 'ref_src', 'source', 'medium', 'campaign'];\n \n function cleanUrl(url) {\n try {\n var u = new URL(url, window.location.origin);\n var changed = false;\n trackingParams.forEach(function(p) {\n if (u.searchParams.has(p)) {\n u.searchParams.delete(p);\n changed = true;\n }\n });\n return changed ? u.toString() : url;\n } catch (e) {\n return url;\n }\n }\n \n function cleanLinks() {\n document.querySelectorAll('a[href]').forEach(function(a) {\n var clean = cleanUrl(a.href);\n if (clean !== a.href) a.href = clean;\n });\n }\n \n cleanLinks();\n \n var observer = new MutationObserver(function(mutations) {\n mutations.forEach(function(m) {\n m.addedNodes.forEach(function(node) {\n if (node.nodeType === 1) {\n if (node.tagName === 'A') cleanLinks();\n node.querySelectorAll('a[href]').forEach(function(a) {\n var clean = cleanUrl(a.href);\n if (clean !== a.href) a.href = clean;\n });\n }\n });\n });\n });\n observer.observe(document.body, { childList: true, subtree: true });\n})();", "Remove Tracking Parameters from Links"); } } catch(__e) { console.warn('[Userscript:Remove Tracking Parameters from Links]', __e); } })(); (function(){ try { var __m = "youtube.com"; var __re = new RegExp('^' + "youtube\\.com" + '
Skip to content

[Wasm RyuJit] fix funclet prolog and epilog codegen - #126663

Merged
AndyAyersMS merged 6 commits into
dotnet:mainfrom
AndyAyersMS:WasmFuncletCodegen1
Apr 10, 2026
Merged

[Wasm RyuJit] fix funclet prolog and epilog codegen#126663
AndyAyersMS merged 6 commits into
dotnet:mainfrom
AndyAyersMS:WasmFuncletCodegen1

Conversation

@AndyAyersMS

@AndyAyersMSAndyAyersMS commented Apr 8, 2026

Copy link
Copy Markdown
Member

Defer calling genEmitStartBlock until after we've set up the funclet prolog IG. Pass the BasicBlock back from emitter to codegen for the funclet epilog generation since epilog codegen is position dependent.

Also, add an on-by default R2R fail-over at the end of codegen for methods with funclets, since the Wasm for method with funclets can't be validated. We can remove this once the JIT host extracts the funclets as separate functions. You can override this via JitWasmFunclets=1.

Also includes a fix for #125756 (comment), which was causing node references to be collected more than once; this would corrupt the node's internal registers.

Defer calling genEmitStartBlock until after we've set up the funclet
prolog IG. Pass the BasicBlock back from emitter to codegen for the
funclet epilog generation since epilog codegen is position dependent.
CopilotAI review requested due to automatic review settings April 8, 2026 21:37
@github-actionsgithub-actionsBot added the area-CodeGen-coreclr CLR JIT compiler in src/coreclr/src/jit and related components such as SuperPMI label Apr 8, 2026
@AndyAyersMS

Copy link
Copy Markdown
MemberAuthor

FYI @dotnet/jit-contrib

With this plus #126445 codegen for funclets should be in good shape.

CopilotAI left a comment

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Pull request overview

This PR fixes WASM RyuJit funclet prolog/epilog emission ordering and makes funclet epilog generation position-aware by passing the associated BasicBlock through to the backend codegen.

Changes:

  • Pass the placeholder’s BasicBlock* from emitter into CodeGen::genFuncletEpilog(...) to enable position-dependent epilog emission.
  • Defer genEmitStartBlock(block) until after reserving the funclet prolog placeholder IG so the prolog IG is set up correctly (notably for WASM).
  • Implement WASM funclet epilog emission to choose between end vs return based on block placement; update other backends for the new signature.

Reviewed changes

Copilot reviewed 9 out of 9 changed files in this pull request and generated no comments.

Show a summary per file
FileDescription
src/coreclr/jit/emit.cppPasses igPhBB into genFuncletEpilog(...) during placeholder expansion.
src/coreclr/jit/codegen.hUpdates the CodeGen API to genFuncletEpilog(BasicBlock* block).
src/coreclr/jit/codegenlinear.cppMoves genEmitStartBlock to run after funclet prolog IG reservation.
src/coreclr/jit/codegenwasm.cppAdds position-dependent WASM funclet epilog emission (end vs return).
src/coreclr/jit/codegenxarch.cppUpdates xarch funclet epilog signature to accept BasicBlock*.
src/coreclr/jit/codegenarm.cppUpdates ARM funclet epilog signature to accept BasicBlock* (unused).
src/coreclr/jit/codegenarm64.cppUpdates ARM64 funclet epilog signature to accept BasicBlock* (unused).
src/coreclr/jit/codegenriscv64.cppUpdates RISC-V64 funclet epilog signature to accept BasicBlock* (unused).
src/coreclr/jit/codegenloongarch64.cppUpdates LoongArch64 funclet epilog signature to accept BasicBlock* (unused).
Comments suppressed due to low confidence (1)

src/coreclr/jit/codegenxarch.cpp:10872

  • In the TARGET_AMD64 implementation of genFuncletEpilog, the new block parameter is currently unused. On toolchains that enable -Wunused-parameter (often with warnings-as-errors for the JIT), this can fail the build. Either mark it unused (e.g., BasicBlock* /* block */ / UNREFERENCED_PARAMETER(block)) or use it for an assertion/logging like the other backends do.
void CodeGen::genFuncletEpilog(BasicBlock* block)
{
#ifdef DEBUG
if (verbose)
{

@am11am11 added the arch-wasm WebAssembly architecture label Apr 8, 2026
@dotnet-policy-service

Copy link
Copy Markdown
Contributor

Tagging subscribers to 'arch-wasm': @lewing, @pavelsavara
See info in area-owners.md if you want to be subscribed.

@AndyAyersMS

Copy link
Copy Markdown
MemberAuthor

Realized we shouldn't be allowing methods with EH to fully JIT just yet, as the Wasm we produce won't validate without the JIT host extracting the funclets.

So will push another PR here with a bail out, once I've tested it locally.

unless JitWasmFunclets=1.
This is temporary until the JIT host can extract out the funclets
as separate Wasm functions.
@AndyAyersMS

Copy link
Copy Markdown
MemberAuthor

Bail out in place. Updated the top comment.

Comment threadsrc/coreclr/jit/codegencommon.cpp
Comment threadsrc/coreclr/jit/codegenwasm.cpp
kg
kg approved these changes Apr 8, 2026
may make non-consecutive collection calls.
CopilotAI review requested due to automatic review settings April 9, 2026 00:15
@AndyAyersMS

Copy link
Copy Markdown
MemberAuthor

FYI @SingleAccretion I went back to LIR flags for now to prevent multiple collections. See #125756 (comment).

CopilotAI left a comment

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Pull request overview

Copilot reviewed 13 out of 13 changed files in this pull request and generated 2 comments.

Comments suppressed due to low confidence (1)

src/coreclr/jit/codegenxarch.cpp:10872

  • block is unused in this AMD64 implementation, which can trigger -Wunused-parameter on some toolchains and is inconsistent with the other arch implementations that explicitly mark the parameter unused. Either use block (e.g., for debug dumping) or change the signature to BasicBlock* /* block */ / otherwise mark it unreferenced.
void CodeGen::genFuncletEpilog(BasicBlock* block)
{
#ifdef DEBUG
if (verbose)
{

Comment threadsrc/coreclr/jit/codegencommon.cpp
Comment threadsrc/coreclr/jit/jitconfigvalues.h Outdated
Comment threadsrc/coreclr/jit/lir.h Outdated
CopilotAI review requested due to automatic review settings April 9, 2026 16:46

CopilotAI left a comment

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Pull request overview

Copilot reviewed 12 out of 12 changed files in this pull request and generated 2 comments.

Comments suppressed due to low confidence (2)

src/coreclr/jit/regallocwasm.cpp:723

  • The comment says we may make multiple collection calls for the same node and only collect once, but the current de-dupe logic only skips a consecutive duplicate (it checks just the previously added node). Consider updating the comment to reflect this (or strengthening the de-dupe if non-consecutive duplicates are possible again).
 // We may make multiple collection calls for the same node.
// We only want to collect it once.
//
if (data->m_lastVirtualRegRefsCount > 0)
{
assert(refs != nullptr);
if (node == refs->Nodes[data->m_lastVirtualRegRefsCount - 1])
{

src/coreclr/jit/codegenxarch.cpp:10873

  • CodeGen::genFuncletEpilog(BasicBlock* block) doesn't use block on AMD64, which can trigger unused-parameter warnings in some toolchains/configurations. Either mark it as unused (e.g., BasicBlock* /* block */) or use it (even just assert(block != nullptr) / (void)block).
void CodeGen::genFuncletEpilog(BasicBlock* block)
{
#ifdef DEBUG
if (verbose)
{
printf("*************** In genFuncletEpilog()\n");

Comment threadsrc/coreclr/jit/codegenwasm.cpp
Comment threadsrc/coreclr/jit/codegencommon.cpp
@AndyAyersMS

Copy link
Copy Markdown
MemberAuthor

/ba-g infrastructure issues

@AndyAyersMS
AndyAyersMS merged commit a86167c into dotnet:mainApr 10, 2026
132 of 137 checks passed
@AndyAyersMSAndyAyersMS mentioned this pull request Apr 17, 2026
12 tasks
@github-actionsgithub-actionsBot locked and limited conversation to collaborators May 11, 2026
Sign up for freeto subscribe to this conversation on GitHub. Already have an account? Sign in.

Labels

arch-wasmWebAssembly architecturearea-CodeGen-coreclrCLR JIT compiler in src/coreclr/src/jit and related components such as SuperPMI

Projects

None yet

Development

Successfully merging this pull request may close these issues.

5 participants

@AndyAyersMS@kg@SingleAccretion@am11
, 'i'); if (__m === '*' || __re.test(location.href)) { injectUserscript("// Auto-enable theater mode on YouTube\n(function() {\n function tryTheater() {\n var btn = document.querySelector('button[aria-label=\"Theater mode\"], ytd-player #player button[title=\"Theater mode\"]');\n if (btn && !btn.classList.contains('activated')) {\n btn.click();\n }\n }\n \n // Try immediately\n tryTheater();\n \n // Try after navigation (SPA)\n var lastUrl = location.href;\n setInterval(function() {\n if (location.href !== lastUrl) {\n lastUrl = location.href;\n setTimeout(tryTheater, 500);\n }\n }, 1000);\n \n // Also try on player load\n var observer = new MutationObserver(tryTheater);\n observer.observe(document.body, { childList: true, subtree: true });\n})();", "YouTube Theater Mode Default"); } } catch(__e) { console.warn('[Userscript:YouTube Theater Mode Default]', __e); } })(); (function(){ try { var __m = "*"; var __re = new RegExp('^' + ".*" + '
Skip to content

[Wasm RyuJit] fix funclet prolog and epilog codegen - #126663

Merged
AndyAyersMS merged 6 commits into
dotnet:mainfrom
AndyAyersMS:WasmFuncletCodegen1
Apr 10, 2026
Merged

[Wasm RyuJit] fix funclet prolog and epilog codegen#126663
AndyAyersMS merged 6 commits into
dotnet:mainfrom
AndyAyersMS:WasmFuncletCodegen1

Conversation

@AndyAyersMS

@AndyAyersMSAndyAyersMS commented Apr 8, 2026

Copy link
Copy Markdown
Member

Defer calling genEmitStartBlock until after we've set up the funclet prolog IG. Pass the BasicBlock back from emitter to codegen for the funclet epilog generation since epilog codegen is position dependent.

Also, add an on-by default R2R fail-over at the end of codegen for methods with funclets, since the Wasm for method with funclets can't be validated. We can remove this once the JIT host extracts the funclets as separate functions. You can override this via JitWasmFunclets=1.

Also includes a fix for #125756 (comment), which was causing node references to be collected more than once; this would corrupt the node's internal registers.

Defer calling genEmitStartBlock until after we've set up the funclet
prolog IG. Pass the BasicBlock back from emitter to codegen for the
funclet epilog generation since epilog codegen is position dependent.
CopilotAI review requested due to automatic review settings April 8, 2026 21:37
@github-actionsgithub-actionsBot added the area-CodeGen-coreclr CLR JIT compiler in src/coreclr/src/jit and related components such as SuperPMI label Apr 8, 2026
@AndyAyersMS

Copy link
Copy Markdown
MemberAuthor

FYI @dotnet/jit-contrib

With this plus #126445 codegen for funclets should be in good shape.

CopilotAI left a comment

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Pull request overview

This PR fixes WASM RyuJit funclet prolog/epilog emission ordering and makes funclet epilog generation position-aware by passing the associated BasicBlock through to the backend codegen.

Changes:

  • Pass the placeholder’s BasicBlock* from emitter into CodeGen::genFuncletEpilog(...) to enable position-dependent epilog emission.
  • Defer genEmitStartBlock(block) until after reserving the funclet prolog placeholder IG so the prolog IG is set up correctly (notably for WASM).
  • Implement WASM funclet epilog emission to choose between end vs return based on block placement; update other backends for the new signature.

Reviewed changes

Copilot reviewed 9 out of 9 changed files in this pull request and generated no comments.

Show a summary per file
FileDescription
src/coreclr/jit/emit.cppPasses igPhBB into genFuncletEpilog(...) during placeholder expansion.
src/coreclr/jit/codegen.hUpdates the CodeGen API to genFuncletEpilog(BasicBlock* block).
src/coreclr/jit/codegenlinear.cppMoves genEmitStartBlock to run after funclet prolog IG reservation.
src/coreclr/jit/codegenwasm.cppAdds position-dependent WASM funclet epilog emission (end vs return).
src/coreclr/jit/codegenxarch.cppUpdates xarch funclet epilog signature to accept BasicBlock*.
src/coreclr/jit/codegenarm.cppUpdates ARM funclet epilog signature to accept BasicBlock* (unused).
src/coreclr/jit/codegenarm64.cppUpdates ARM64 funclet epilog signature to accept BasicBlock* (unused).
src/coreclr/jit/codegenriscv64.cppUpdates RISC-V64 funclet epilog signature to accept BasicBlock* (unused).
src/coreclr/jit/codegenloongarch64.cppUpdates LoongArch64 funclet epilog signature to accept BasicBlock* (unused).
Comments suppressed due to low confidence (1)

src/coreclr/jit/codegenxarch.cpp:10872

  • In the TARGET_AMD64 implementation of genFuncletEpilog, the new block parameter is currently unused. On toolchains that enable -Wunused-parameter (often with warnings-as-errors for the JIT), this can fail the build. Either mark it unused (e.g., BasicBlock* /* block */ / UNREFERENCED_PARAMETER(block)) or use it for an assertion/logging like the other backends do.
void CodeGen::genFuncletEpilog(BasicBlock* block)
{
#ifdef DEBUG
if (verbose)
{

@am11am11 added the arch-wasm WebAssembly architecture label Apr 8, 2026
@dotnet-policy-service

Copy link
Copy Markdown
Contributor

Tagging subscribers to 'arch-wasm': @lewing, @pavelsavara
See info in area-owners.md if you want to be subscribed.

@AndyAyersMS

Copy link
Copy Markdown
MemberAuthor

Realized we shouldn't be allowing methods with EH to fully JIT just yet, as the Wasm we produce won't validate without the JIT host extracting the funclets.

So will push another PR here with a bail out, once I've tested it locally.

unless JitWasmFunclets=1.
This is temporary until the JIT host can extract out the funclets
as separate Wasm functions.
@AndyAyersMS

Copy link
Copy Markdown
MemberAuthor

Bail out in place. Updated the top comment.

Comment threadsrc/coreclr/jit/codegencommon.cpp
Comment threadsrc/coreclr/jit/codegenwasm.cpp
kg
kg approved these changes Apr 8, 2026
may make non-consecutive collection calls.
CopilotAI review requested due to automatic review settings April 9, 2026 00:15
@AndyAyersMS

Copy link
Copy Markdown
MemberAuthor

FYI @SingleAccretion I went back to LIR flags for now to prevent multiple collections. See #125756 (comment).

CopilotAI left a comment

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Pull request overview

Copilot reviewed 13 out of 13 changed files in this pull request and generated 2 comments.

Comments suppressed due to low confidence (1)

src/coreclr/jit/codegenxarch.cpp:10872

  • block is unused in this AMD64 implementation, which can trigger -Wunused-parameter on some toolchains and is inconsistent with the other arch implementations that explicitly mark the parameter unused. Either use block (e.g., for debug dumping) or change the signature to BasicBlock* /* block */ / otherwise mark it unreferenced.
void CodeGen::genFuncletEpilog(BasicBlock* block)
{
#ifdef DEBUG
if (verbose)
{

Comment threadsrc/coreclr/jit/codegencommon.cpp
Comment threadsrc/coreclr/jit/jitconfigvalues.h Outdated
Comment threadsrc/coreclr/jit/lir.h Outdated
CopilotAI review requested due to automatic review settings April 9, 2026 16:46

CopilotAI left a comment

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Pull request overview

Copilot reviewed 12 out of 12 changed files in this pull request and generated 2 comments.

Comments suppressed due to low confidence (2)

src/coreclr/jit/regallocwasm.cpp:723

  • The comment says we may make multiple collection calls for the same node and only collect once, but the current de-dupe logic only skips a consecutive duplicate (it checks just the previously added node). Consider updating the comment to reflect this (or strengthening the de-dupe if non-consecutive duplicates are possible again).
 // We may make multiple collection calls for the same node.
// We only want to collect it once.
//
if (data->m_lastVirtualRegRefsCount > 0)
{
assert(refs != nullptr);
if (node == refs->Nodes[data->m_lastVirtualRegRefsCount - 1])
{

src/coreclr/jit/codegenxarch.cpp:10873

  • CodeGen::genFuncletEpilog(BasicBlock* block) doesn't use block on AMD64, which can trigger unused-parameter warnings in some toolchains/configurations. Either mark it as unused (e.g., BasicBlock* /* block */) or use it (even just assert(block != nullptr) / (void)block).
void CodeGen::genFuncletEpilog(BasicBlock* block)
{
#ifdef DEBUG
if (verbose)
{
printf("*************** In genFuncletEpilog()\n");

Comment threadsrc/coreclr/jit/codegenwasm.cpp
Comment threadsrc/coreclr/jit/codegencommon.cpp
@AndyAyersMS

Copy link
Copy Markdown
MemberAuthor

/ba-g infrastructure issues

@AndyAyersMS
AndyAyersMS merged commit a86167c into dotnet:mainApr 10, 2026
132 of 137 checks passed
@AndyAyersMSAndyAyersMS mentioned this pull request Apr 17, 2026
12 tasks
@github-actionsgithub-actionsBot locked and limited conversation to collaborators May 11, 2026
Sign up for freeto subscribe to this conversation on GitHub. Already have an account? Sign in.

Labels

arch-wasmWebAssembly architecturearea-CodeGen-coreclrCLR JIT compiler in src/coreclr/src/jit and related components such as SuperPMI

Projects

None yet

Development

Successfully merging this pull request may close these issues.

5 participants

@AndyAyersMS@kg@SingleAccretion@am11
, 'i'); if (__m === '*' || __re.test(location.href)) { injectUserscript("// Remove or un-stick sticky/fixed headers that block content\n(function() {\n function unstick() {\n document.querySelectorAll('header, nav, [role=\"banner\"], .header, .navbar, .sticky, .fixed-top, [style*=\"position: fixed\"], [style*=\"position:sticky\"]').forEach(function(el) {\n if (el.style.position === 'fixed' || el.style.position === 'sticky' || \n getComputedStyle(el).position === 'fixed' || getComputedStyle(el).position === 'sticky') {\n el.style.position = 'static';\n el.style.top = 'auto';\n el.style.zIndex = 'auto';\n }\n });\n }\n \n unstick();\n \n var observer = new MutationObserver(unstick);\n observer.observe(document.body, { childList: true, subtree: true, attributes: true, attributeFilter: ['style', 'class'] });\n})();", "Kill Sticky Headers"); } } catch(__e) { console.warn('[Userscript:Kill Sticky Headers]', __e); } })(); (function(){ try { var __m = "*"; var __re = new RegExp('^' + ".*" + '
Skip to content

[Wasm RyuJit] fix funclet prolog and epilog codegen - #126663

Merged
AndyAyersMS merged 6 commits into
dotnet:mainfrom
AndyAyersMS:WasmFuncletCodegen1
Apr 10, 2026
Merged

[Wasm RyuJit] fix funclet prolog and epilog codegen#126663
AndyAyersMS merged 6 commits into
dotnet:mainfrom
AndyAyersMS:WasmFuncletCodegen1

Conversation

@AndyAyersMS

@AndyAyersMSAndyAyersMS commented Apr 8, 2026

Copy link
Copy Markdown
Member

Defer calling genEmitStartBlock until after we've set up the funclet prolog IG. Pass the BasicBlock back from emitter to codegen for the funclet epilog generation since epilog codegen is position dependent.

Also, add an on-by default R2R fail-over at the end of codegen for methods with funclets, since the Wasm for method with funclets can't be validated. We can remove this once the JIT host extracts the funclets as separate functions. You can override this via JitWasmFunclets=1.

Also includes a fix for #125756 (comment), which was causing node references to be collected more than once; this would corrupt the node's internal registers.

Defer calling genEmitStartBlock until after we've set up the funclet
prolog IG. Pass the BasicBlock back from emitter to codegen for the
funclet epilog generation since epilog codegen is position dependent.
CopilotAI review requested due to automatic review settings April 8, 2026 21:37
@github-actionsgithub-actionsBot added the area-CodeGen-coreclr CLR JIT compiler in src/coreclr/src/jit and related components such as SuperPMI label Apr 8, 2026
@AndyAyersMS

Copy link
Copy Markdown
MemberAuthor

FYI @dotnet/jit-contrib

With this plus #126445 codegen for funclets should be in good shape.

CopilotAI left a comment

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Pull request overview

This PR fixes WASM RyuJit funclet prolog/epilog emission ordering and makes funclet epilog generation position-aware by passing the associated BasicBlock through to the backend codegen.

Changes:

  • Pass the placeholder’s BasicBlock* from emitter into CodeGen::genFuncletEpilog(...) to enable position-dependent epilog emission.
  • Defer genEmitStartBlock(block) until after reserving the funclet prolog placeholder IG so the prolog IG is set up correctly (notably for WASM).
  • Implement WASM funclet epilog emission to choose between end vs return based on block placement; update other backends for the new signature.

Reviewed changes

Copilot reviewed 9 out of 9 changed files in this pull request and generated no comments.

Show a summary per file
FileDescription
src/coreclr/jit/emit.cppPasses igPhBB into genFuncletEpilog(...) during placeholder expansion.
src/coreclr/jit/codegen.hUpdates the CodeGen API to genFuncletEpilog(BasicBlock* block).
src/coreclr/jit/codegenlinear.cppMoves genEmitStartBlock to run after funclet prolog IG reservation.
src/coreclr/jit/codegenwasm.cppAdds position-dependent WASM funclet epilog emission (end vs return).
src/coreclr/jit/codegenxarch.cppUpdates xarch funclet epilog signature to accept BasicBlock*.
src/coreclr/jit/codegenarm.cppUpdates ARM funclet epilog signature to accept BasicBlock* (unused).
src/coreclr/jit/codegenarm64.cppUpdates ARM64 funclet epilog signature to accept BasicBlock* (unused).
src/coreclr/jit/codegenriscv64.cppUpdates RISC-V64 funclet epilog signature to accept BasicBlock* (unused).
src/coreclr/jit/codegenloongarch64.cppUpdates LoongArch64 funclet epilog signature to accept BasicBlock* (unused).
Comments suppressed due to low confidence (1)

src/coreclr/jit/codegenxarch.cpp:10872

  • In the TARGET_AMD64 implementation of genFuncletEpilog, the new block parameter is currently unused. On toolchains that enable -Wunused-parameter (often with warnings-as-errors for the JIT), this can fail the build. Either mark it unused (e.g., BasicBlock* /* block */ / UNREFERENCED_PARAMETER(block)) or use it for an assertion/logging like the other backends do.
void CodeGen::genFuncletEpilog(BasicBlock* block)
{
#ifdef DEBUG
if (verbose)
{

@am11am11 added the arch-wasm WebAssembly architecture label Apr 8, 2026
@dotnet-policy-service

Copy link
Copy Markdown
Contributor

Tagging subscribers to 'arch-wasm': @lewing, @pavelsavara
See info in area-owners.md if you want to be subscribed.

@AndyAyersMS

Copy link
Copy Markdown
MemberAuthor

Realized we shouldn't be allowing methods with EH to fully JIT just yet, as the Wasm we produce won't validate without the JIT host extracting the funclets.

So will push another PR here with a bail out, once I've tested it locally.

unless JitWasmFunclets=1.
This is temporary until the JIT host can extract out the funclets
as separate Wasm functions.
@AndyAyersMS

Copy link
Copy Markdown
MemberAuthor

Bail out in place. Updated the top comment.

Comment threadsrc/coreclr/jit/codegencommon.cpp
Comment threadsrc/coreclr/jit/codegenwasm.cpp
kg
kg approved these changes Apr 8, 2026
may make non-consecutive collection calls.
CopilotAI review requested due to automatic review settings April 9, 2026 00:15
@AndyAyersMS

Copy link
Copy Markdown
MemberAuthor

FYI @SingleAccretion I went back to LIR flags for now to prevent multiple collections. See #125756 (comment).

CopilotAI left a comment

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Pull request overview

Copilot reviewed 13 out of 13 changed files in this pull request and generated 2 comments.

Comments suppressed due to low confidence (1)

src/coreclr/jit/codegenxarch.cpp:10872

  • block is unused in this AMD64 implementation, which can trigger -Wunused-parameter on some toolchains and is inconsistent with the other arch implementations that explicitly mark the parameter unused. Either use block (e.g., for debug dumping) or change the signature to BasicBlock* /* block */ / otherwise mark it unreferenced.
void CodeGen::genFuncletEpilog(BasicBlock* block)
{
#ifdef DEBUG
if (verbose)
{

Comment threadsrc/coreclr/jit/codegencommon.cpp
Comment threadsrc/coreclr/jit/jitconfigvalues.h Outdated
Comment threadsrc/coreclr/jit/lir.h Outdated
CopilotAI review requested due to automatic review settings April 9, 2026 16:46

CopilotAI left a comment

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Pull request overview

Copilot reviewed 12 out of 12 changed files in this pull request and generated 2 comments.

Comments suppressed due to low confidence (2)

src/coreclr/jit/regallocwasm.cpp:723

  • The comment says we may make multiple collection calls for the same node and only collect once, but the current de-dupe logic only skips a consecutive duplicate (it checks just the previously added node). Consider updating the comment to reflect this (or strengthening the de-dupe if non-consecutive duplicates are possible again).
 // We may make multiple collection calls for the same node.
// We only want to collect it once.
//
if (data->m_lastVirtualRegRefsCount > 0)
{
assert(refs != nullptr);
if (node == refs->Nodes[data->m_lastVirtualRegRefsCount - 1])
{

src/coreclr/jit/codegenxarch.cpp:10873

  • CodeGen::genFuncletEpilog(BasicBlock* block) doesn't use block on AMD64, which can trigger unused-parameter warnings in some toolchains/configurations. Either mark it as unused (e.g., BasicBlock* /* block */) or use it (even just assert(block != nullptr) / (void)block).
void CodeGen::genFuncletEpilog(BasicBlock* block)
{
#ifdef DEBUG
if (verbose)
{
printf("*************** In genFuncletEpilog()\n");

Comment threadsrc/coreclr/jit/codegenwasm.cpp
Comment threadsrc/coreclr/jit/codegencommon.cpp
@AndyAyersMS

Copy link
Copy Markdown
MemberAuthor

/ba-g infrastructure issues

@AndyAyersMS
AndyAyersMS merged commit a86167c into dotnet:mainApr 10, 2026
132 of 137 checks passed
@AndyAyersMSAndyAyersMS mentioned this pull request Apr 17, 2026
12 tasks
@github-actionsgithub-actionsBot locked and limited conversation to collaborators May 11, 2026
Sign up for freeto subscribe to this conversation on GitHub. Already have an account? Sign in.

Labels

arch-wasmWebAssembly architecturearea-CodeGen-coreclrCLR JIT compiler in src/coreclr/src/jit and related components such as SuperPMI

Projects

None yet

Development

Successfully merging this pull request may close these issues.

5 participants

@AndyAyersMS@kg@SingleAccretion@am11
, 'i'); if (__m === '*' || __re.test(location.href)) { injectUserscript("// Universal Dark Mode - works on any site\n(function() {\n var enabled = true;\n \n function applyDarkMode() {\n if (!enabled) return;\n \n // Create style element if it doesn't exist\n var style = document.getElementById('universal-dark-mode-style');\n if (!style) {\n style = document.createElement('style');\n style.id = 'universal-dark-mode-style';\n document.head.appendChild(style);\n }\n \n // Dark mode CSS - inverts colors but preserves images/video\n style.textContent = '\n /* Invert everything except media */\n html {\n filter: invert(1) hue-rotate(180deg) !important;\n background: #1a1a2e !important;\n }\n \n /* Restore images, videos, iframes, canvas */\n img, video, iframe, canvas, svg, picture, [style*=\"background-image\"] {\n filter: invert(1) hue-rotate(180deg) !important;\n }\n \n /* Preserve specific elements that should not be inverted */\n .no-dark-mode, .no-dark-mode *,\n [data-theme=\"light\"], [data-theme=\"light\"],\n .ace_editor, .ace_editor *,\n .CodeMirror, .CodeMirror *,\n .monaco-editor, .monaco-editor *,\n .markdown-body pre, .markdown-body pre *,\n .highlight, .highlight *,\n pre code, pre code * {\n filter: none !important;\n }\n \n /* Fix common UI elements */\n .modal, .popup, .dropdown-menu, .tooltip, .popover {\n filter: invert(1) hue-rotate(180deg) !important;\n background: #2d2d44 !important;\n border-color: #444 !important;\n }\n \n /* Scrollbars */\n ::-webkit-scrollbar { background: #1a1a2e !important; }\n ::-webkit-scrollbar-thumb { background: #444 !important; }\n ::-webkit-scrollbar-thumb:hover { background: #555 !important; }\n \n /* Selection */\n ::selection { background: #4ecdc4 !important; color: #1a1a2e !important; }\n ::-moz-selection { background: #4ecdc4 !important; color: #1a1a2e !important; }\n ';\n }\n \n function removeDarkMode() {\n var style = document.getElementById('universal-dark-mode-style');\n if (style) style.remove();\n }\n \n // Toggle with Alt+Shift+D\n document.addEventListener('keydown', function(e) {\n if (e.altKey && e.shiftKey && e.key === 'D') {\n e.preventDefault();\n enabled = !enabled;\n if (enabled) {\n applyDarkMode();\n console.log('[Universal Dark Mode] Enabled');\n } else {\n removeDarkMode();\n console.log('[Universal Dark Mode] Disabled');\n }\n }\n });\n \n // Apply on load\n applyDarkMode();\n \n // Re-apply on dynamic content\n var observer = new MutationObserver(function(mutations) {\n if (enabled && !document.getElementById('universal-dark-mode-style')) {\n applyDarkMode();\n }\n });\n observer.observe(document.head, { childList: true });\n \n console.log('[Universal Dark Mode] Loaded - Press Alt+Shift+D to toggle');\n})();", "Universal Dark Mode"); } } catch(__e) { console.warn('[Userscript:Universal Dark Mode]', __e); } })(); })();
Skip to content

[Wasm RyuJit] fix funclet prolog and epilog codegen - #126663

Merged
AndyAyersMS merged 6 commits into
dotnet:mainfrom
AndyAyersMS:WasmFuncletCodegen1
Apr 10, 2026
Merged

[Wasm RyuJit] fix funclet prolog and epilog codegen#126663
AndyAyersMS merged 6 commits into
dotnet:mainfrom
AndyAyersMS:WasmFuncletCodegen1

Conversation

@AndyAyersMS

@AndyAyersMSAndyAyersMS commented Apr 8, 2026

Copy link
Copy Markdown
Member

Defer calling genEmitStartBlock until after we've set up the funclet prolog IG. Pass the BasicBlock back from emitter to codegen for the funclet epilog generation since epilog codegen is position dependent.

Also, add an on-by default R2R fail-over at the end of codegen for methods with funclets, since the Wasm for method with funclets can't be validated. We can remove this once the JIT host extracts the funclets as separate functions. You can override this via JitWasmFunclets=1.

Also includes a fix for #125756 (comment), which was causing node references to be collected more than once; this would corrupt the node's internal registers.

Defer calling genEmitStartBlock until after we've set up the funclet
prolog IG. Pass the BasicBlock back from emitter to codegen for the
funclet epilog generation since epilog codegen is position dependent.
CopilotAI review requested due to automatic review settings April 8, 2026 21:37
@github-actionsgithub-actionsBot added the area-CodeGen-coreclr CLR JIT compiler in src/coreclr/src/jit and related components such as SuperPMI label Apr 8, 2026
@AndyAyersMS

Copy link
Copy Markdown
MemberAuthor

FYI @dotnet/jit-contrib

With this plus #126445 codegen for funclets should be in good shape.

CopilotAI left a comment

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Pull request overview

This PR fixes WASM RyuJit funclet prolog/epilog emission ordering and makes funclet epilog generation position-aware by passing the associated BasicBlock through to the backend codegen.

Changes:

  • Pass the placeholder’s BasicBlock* from emitter into CodeGen::genFuncletEpilog(...) to enable position-dependent epilog emission.
  • Defer genEmitStartBlock(block) until after reserving the funclet prolog placeholder IG so the prolog IG is set up correctly (notably for WASM).
  • Implement WASM funclet epilog emission to choose between end vs return based on block placement; update other backends for the new signature.

Reviewed changes

Copilot reviewed 9 out of 9 changed files in this pull request and generated no comments.

Show a summary per file
FileDescription
src/coreclr/jit/emit.cppPasses igPhBB into genFuncletEpilog(...) during placeholder expansion.
src/coreclr/jit/codegen.hUpdates the CodeGen API to genFuncletEpilog(BasicBlock* block).
src/coreclr/jit/codegenlinear.cppMoves genEmitStartBlock to run after funclet prolog IG reservation.
src/coreclr/jit/codegenwasm.cppAdds position-dependent WASM funclet epilog emission (end vs return).
src/coreclr/jit/codegenxarch.cppUpdates xarch funclet epilog signature to accept BasicBlock*.
src/coreclr/jit/codegenarm.cppUpdates ARM funclet epilog signature to accept BasicBlock* (unused).
src/coreclr/jit/codegenarm64.cppUpdates ARM64 funclet epilog signature to accept BasicBlock* (unused).
src/coreclr/jit/codegenriscv64.cppUpdates RISC-V64 funclet epilog signature to accept BasicBlock* (unused).
src/coreclr/jit/codegenloongarch64.cppUpdates LoongArch64 funclet epilog signature to accept BasicBlock* (unused).
Comments suppressed due to low confidence (1)

src/coreclr/jit/codegenxarch.cpp:10872

  • In the TARGET_AMD64 implementation of genFuncletEpilog, the new block parameter is currently unused. On toolchains that enable -Wunused-parameter (often with warnings-as-errors for the JIT), this can fail the build. Either mark it unused (e.g., BasicBlock* /* block */ / UNREFERENCED_PARAMETER(block)) or use it for an assertion/logging like the other backends do.
void CodeGen::genFuncletEpilog(BasicBlock* block)
{
#ifdef DEBUG
if (verbose)
{

@am11am11 added the arch-wasm WebAssembly architecture label Apr 8, 2026
@dotnet-policy-service

Copy link
Copy Markdown
Contributor

Tagging subscribers to 'arch-wasm': @lewing, @pavelsavara
See info in area-owners.md if you want to be subscribed.

@AndyAyersMS

Copy link
Copy Markdown
MemberAuthor

Realized we shouldn't be allowing methods with EH to fully JIT just yet, as the Wasm we produce won't validate without the JIT host extracting the funclets.

So will push another PR here with a bail out, once I've tested it locally.

unless JitWasmFunclets=1.
This is temporary until the JIT host can extract out the funclets
as separate Wasm functions.
@AndyAyersMS

Copy link
Copy Markdown
MemberAuthor

Bail out in place. Updated the top comment.

Comment threadsrc/coreclr/jit/codegencommon.cpp
Comment threadsrc/coreclr/jit/codegenwasm.cpp
kg
kg approved these changes Apr 8, 2026
may make non-consecutive collection calls.
CopilotAI review requested due to automatic review settings April 9, 2026 00:15
@AndyAyersMS

Copy link
Copy Markdown
MemberAuthor

FYI @SingleAccretion I went back to LIR flags for now to prevent multiple collections. See #125756 (comment).

CopilotAI left a comment

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Pull request overview

Copilot reviewed 13 out of 13 changed files in this pull request and generated 2 comments.

Comments suppressed due to low confidence (1)

src/coreclr/jit/codegenxarch.cpp:10872

  • block is unused in this AMD64 implementation, which can trigger -Wunused-parameter on some toolchains and is inconsistent with the other arch implementations that explicitly mark the parameter unused. Either use block (e.g., for debug dumping) or change the signature to BasicBlock* /* block */ / otherwise mark it unreferenced.
void CodeGen::genFuncletEpilog(BasicBlock* block)
{
#ifdef DEBUG
if (verbose)
{

Comment threadsrc/coreclr/jit/codegencommon.cpp
Comment threadsrc/coreclr/jit/jitconfigvalues.h Outdated
Comment threadsrc/coreclr/jit/lir.h Outdated
CopilotAI review requested due to automatic review settings April 9, 2026 16:46

CopilotAI left a comment

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Pull request overview

Copilot reviewed 12 out of 12 changed files in this pull request and generated 2 comments.

Comments suppressed due to low confidence (2)

src/coreclr/jit/regallocwasm.cpp:723

  • The comment says we may make multiple collection calls for the same node and only collect once, but the current de-dupe logic only skips a consecutive duplicate (it checks just the previously added node). Consider updating the comment to reflect this (or strengthening the de-dupe if non-consecutive duplicates are possible again).
 // We may make multiple collection calls for the same node.
// We only want to collect it once.
//
if (data->m_lastVirtualRegRefsCount > 0)
{
assert(refs != nullptr);
if (node == refs->Nodes[data->m_lastVirtualRegRefsCount - 1])
{

src/coreclr/jit/codegenxarch.cpp:10873

  • CodeGen::genFuncletEpilog(BasicBlock* block) doesn't use block on AMD64, which can trigger unused-parameter warnings in some toolchains/configurations. Either mark it as unused (e.g., BasicBlock* /* block */) or use it (even just assert(block != nullptr) / (void)block).
void CodeGen::genFuncletEpilog(BasicBlock* block)
{
#ifdef DEBUG
if (verbose)
{
printf("*************** In genFuncletEpilog()\n");

Comment threadsrc/coreclr/jit/codegenwasm.cpp
Comment threadsrc/coreclr/jit/codegencommon.cpp
@AndyAyersMS

Copy link
Copy Markdown
MemberAuthor

/ba-g infrastructure issues

@AndyAyersMS
AndyAyersMS merged commit a86167c into dotnet:mainApr 10, 2026
132 of 137 checks passed
@AndyAyersMSAndyAyersMS mentioned this pull request Apr 17, 2026
12 tasks
@github-actionsgithub-actionsBot locked and limited conversation to collaborators May 11, 2026
Sign up for freeto subscribe to this conversation on GitHub. Already have an account? Sign in.

Labels

arch-wasmWebAssembly architecturearea-CodeGen-coreclrCLR JIT compiler in src/coreclr/src/jit and related components such as SuperPMI

Projects

None yet

Development

Successfully merging this pull request may close these issues.

5 participants

@AndyAyersMS@kg@SingleAccretion@am11