JIT: Fix register move ordering in genConsumeBlockOp when srcAddr is in dstReg#126133
Closed
JIT: Fix register move ordering in genConsumeBlockOp when srcAddr is in dstReg#126133
Conversation
Contributor
|
Tagging subscribers to this area: @JulieLeeMSFT, @jakobbotsch |
When the LSRA allocates the source address to the same register that
the destination address needs (dstReg), the original code would
incorrectly clobber the source address by copying the destination first:
mov rdi, rax ; dst -> dstReg (CLOBBERS srcAddr already in rdi!)
mov rsi, rdi ; src -> srcReg (copies destination, not source!)
Fix by detecting this case and moving the source to srcReg first when
srcAddr is currently in dstReg. Also update the existing comment which
incorrectly claimed the LSRA always guarantees safe copy ordering, and
add an assert to catch the unhandled swap case (srcAddr in dstReg AND
dstAddr in srcReg simultaneously) which would produce incorrect code.
Fixes: System.Diagnostics.Metrics.Tests.MetricsTests.PassingVariableTagsParametersTest
under JitStress=2 + JitStressRegs={2,0x80} on Linux x64.
Co-authored-by: mangod9 <61718172+mangod9@users.noreply.github.com>
Agent-Logs-Url: https://github.com/dotnet/runtime/sessions/1b13221b-a0c1-4742-8445-5ada9974b0de
Copilot
AI
changed the title
[WIP] Fix test failure in PassingVariableTagsParametersTest
JIT: Fix register move ordering in genConsumeBlockOp when srcAddr is in dstReg
Mar 25, 2026
Member
|
I don't think this is the right fix. Likely what I am working on in #125333 will fix this in a better way. |
Member
|
Ok will close this PR then if you are already working on a fix. Thx! |
Member
|
btw @jakobbotsch is the analysis on the issue incorrect or the proposed fix is not complete. Looks like as part of the analysis it validated the fix worked for a sample test case it had built. |
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment
Add this suggestion to a batch that can be applied as a single commit.This suggestion is invalid because no changes were made to the code.Suggestions cannot be applied while the pull request is closed.Suggestions cannot be applied while viewing a subset of changes.Only one suggestion per line can be applied in a batch.Add this suggestion to a batch that can be applied as a single commit.Applying suggestions on deleted lines is not supported.You must change the existing code in this line in order to create a valid suggestion.Outdated suggestions cannot be applied.This suggestion has been applied or marked resolved.Suggestions cannot be applied from pending reviews.Suggestions cannot be applied on multi-line comments.Suggestions cannot be applied while the pull request is queued to merge.Suggestion cannot be applied right now. Please check back later.
MetricsTests.PassingVariableTagsParametersTestfails underJitStress=2 + JitStressRegs={2,0x80}on Linux x64 because the JIT emits incorrect code for GC-aware block copies (CpObjUnroll) when the LSRA allocates the source address to the same register required for the destination (rdi).Description
Bug:
genConsumeBlockOpunconditionally performs the destination move before the source move. When the source address is indstReg, this silently overwrites it:Fix (
src/coreclr/jit/codegenlinear.cpp,genConsumeBlockOp):GT_INDCopyBlk) is currently indstReg, emit the source move tosrcRegfirst, then move the destination todstReg.assert(dstAddr->GetRegNum() != srcReg)to guard the unhandled cyclic-swap case (srcAddr in dstReg and dstAddr in srcReg simultaneously), which would need a temp register. The assert makes this fail loudly rather than silently corrupting data.The fix is generic: it applies to all architectures that use
genConsumeBlockOpwith fixed destination/source register requirements (REG_RDI/REG_RSIon x64,REG_WRITE_BARRIER_DST_BYREF/REG_WRITE_BARRIER_SRC_BYREFon ARM64/LoongArch64/RISCV64).Original prompt
This section details on the original issue you should resolve
<issue_title>Test failure: System.Diagnostics.Metrics.Tests.MetricsTests.PassingVariableTagsParametersTest</issue_title>
<issue_description>Failed in: runtime-coreclr libraries-jitstress2-jitstressregs 20260307.1
Failed tests:
Error message:
Stack trace: