Skip to content

[Wasm RyuJIT] Fix for assert in obscure block store scenario#126392

Open
kg wants to merge 2 commits intodotnet:mainfrom
kg:wasm-blockstore-5
Open

[Wasm RyuJIT] Fix for assert in obscure block store scenario#126392
kg wants to merge 2 commits intodotnet:mainfrom
kg:wasm-blockstore-5

Conversation

@kg
Copy link
Copy Markdown
Member

@kg kg commented Apr 1, 2026

This fixes the assert about temporary regs from System.ValueTuple`4[System.__Canon,System.__Canon,System.__Canon,System.__Canon]:System.IComparable.CompareTo(System.Object):int:this in #125756

Copilot AI review requested due to automatic review settings April 1, 2026 01:37
@kg kg added arch-wasm WebAssembly architecture area-CodeGen-coreclr CLR JIT compiler in src/coreclr/src/jit and related components such as SuperPMI labels Apr 1, 2026
@dotnet-policy-service
Copy link
Copy Markdown
Contributor

Tagging subscribers to this area: @JulieLeeMSFT, @jakobbotsch
See info in area-owners.md if you want to be subscribed.

Copy link
Copy Markdown
Contributor

Copilot AI left a comment

Choose a reason for hiding this comment

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

Pull request overview

Fixes a WASM RyuJIT assertion/regalloc issue in an edge-case block-store lowering/codegen path by avoiding creation/consumption of temporary regs when using native memory.copy/memory.fill and the corresponding address is marked non-faulting.

Changes:

  • Adjusted WASM lowering (LowerBlockStore) to only mark src/dst addresses as multiply-used when null-checking (or non-native lowering) requires it.
  • Updated WASM codegen for GT_STORE_BLK to skip GetMultiUseOperandReg in native-op + non-faulting cases, and tightened an invariant with a debug assert.

Reviewed changes

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

File Description
src/coreclr/jit/lowerwasm.cpp Refines when block-store src/dst addresses are marked multiply-used to avoid unnecessary temps for non-faulting native ops.
src/coreclr/jit/codegenwasm.cpp Avoids fetching temp regs for native memory.copy/fill when no null check is needed; adds an assert guarding a contained-src path.

@kg kg marked this pull request as ready for review April 1, 2026 18:43
Copilot AI review requested due to automatic review settings April 1, 2026 18:43
@kg
Copy link
Copy Markdown
Member Author

kg commented Apr 1, 2026

@dotnet/jit-contrib PTAL

Copy link
Copy Markdown
Contributor

Copilot AI left a comment

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 2 out of 2 changed files in this pull request and generated 1 comment.

// For native opcode copies/fills with a non-faulting destination, we can't reliably mark the address as
// multiply-used - it will cause failures later in compilation. So avoid those cases too.
((blkNode->gtBlkOpKind != GenTreeBlk::BlkOpKindNativeOpcode) ||
((blkNode->gtFlags & GTF_IND_NONFAULTING) == 0)))
Copy link

Copilot AI Apr 1, 2026

Choose a reason for hiding this comment

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

LowerBlockStore’s destination MultiplyUsed decision only checks GTF_IND_NONFAULTING, but codegen’s nullCheckDest also depends on dstOnStack = blkOp->IsAddressNotOnHeap(...). For native memory.copy/fill, destinations that are stack-only / GTF_IND_TGT_NOT_HEAP can still have GTF_IND_NONFAULTING cleared, so lowering may mark dstAddr multiply-used while codegen won’t ever request/consume a multi-use dest reg. Consider mirroring codegen’s condition here (e.g., include !blkNode->IsAddressNotOnHeap(m_compiler)), so lowering/codegen stay in sync and you don’t reintroduce the temp-reg ordering failures this PR is addressing.

Suggested change
((blkNode->gtFlags & GTF_IND_NONFAULTING) == 0)))
((blkNode->gtFlags & GTF_IND_NONFAULTING) == 0)) &&
// We also don't nullcheck destinations that are known not to reside on the heap (e.g. stack-only), so avoid
// marking those addresses as multiply-used to keep lowering and codegen behavior in sync.
!blkNode->IsAddressNotOnHeap(m_compiler))

Copilot uses AI. Check for mistakes.
// skip generating the temporary for that case. If we don't do this, we get an error during regalloc caused
// by RewriteLocalStackStore creating and lowering a block store too 'late' to mark the dstAddr as multiply
// used successfully.
!dstAddr->OperIs(GT_LCL_ADDR) &&
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.

Remove this condition? It is now subsumed by the nonfaulting check.

Comment on lines +306 to +307
// For native opcode copies/fills with a non-faulting destination, we can't reliably mark the address as
// multiply-used - it will cause failures later in compilation. So avoid those cases too.
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.

we can't reliably mark the address as multiply-used

What do you mean here? The same RewriteLocalStackStore restriction?

Copy link
Copy Markdown
Member Author

Choose a reason for hiding this comment

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

I never figured out specifically what was going wrong, the jitdump was enormous.

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

arch-wasm WebAssembly architecture area-CodeGen-coreclr CLR 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.

3 participants