-
Notifications
You must be signed in to change notification settings - Fork 5.2k
JIT: Fix SysV first/second return register GC info mismatch when generating calls #115827
New issue
Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.
By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.
Already on GitHub? Sign in to your account
Conversation
…rating calls On SysV it is possible to have mixed SIMD/integer return registers for calls. This leads to a case where the first return register is a SIMD register, while the second return register is an integer register. In that particular case, the emitter would get confused and expect GC information for the second return register to refer to `rdx`, when in reality it refers to `rax`. Fix the problem by detecting the case where the second register is `rax`, and communicating the right information back to the emitter. Also add a test case that reliably segfaults under `DOTNET_GCStress=C` without the fix.
Tagging subscribers to this area: @JulieLeeMSFT, @jakobbotsch |
@shushanhf @tomeksowi You may want to check whether LA64/RISCV64 suffer from the same possibility, I am not familiar enough with the ABI there to know. |
/azp run runtime-coreclr gcstress0x3-gcstress0xc |
Azure Pipelines successfully started running 1 pipeline(s). |
Thanks for the heads-up. We have the same problem IMO, the integer field of an int-float struct is passed/returned in But it doesn't manifest in this testcase because the classification doesn't handle reordered fields well, it bails out here: runtime/src/coreclr/vm/methodtable.cpp Lines 2782 to 2794 in 4947a30
I'll try to fix it so KeyValuePair<Container, double> gets lowered. |
cc @dotnet/jit-contrib PTAL @kunalspathak |
There was a problem hiding this comment.
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 a mismatch in GC info for mixed SIMD/integer return registers on SysV when emitting calls, and adds a repro test that would segfault under GC stress without the fix.
- Adjusts
genCallInstruction
to swapretSize
when the second ABI return register israx
- Introduces a new JIT test (
Runtime_115815
) to catch the issue underDOTNET_GCStress=C
- Adds a project file for the new test
Reviewed Changes
Copilot reviewed 3 out of 3 changed files in this pull request and generated no comments.
File | Description |
---|---|
src/tests/JIT/Regression/JitBlue/Runtime_115815/Runtime_115815.csproj | Adds project file for the new GC-stress repro test |
src/tests/JIT/Regression/JitBlue/Runtime_115815/Runtime_115815.cs | Implements the test that exposes the return-reg mismatch |
src/coreclr/jit/codegenxarch.cpp | Swaps params.retSize and params.secondRetSize when second return register is REG_INTRET |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
LGTM
Thank you, LA64 has the same result with RV64. |
Yeah, looks like 1000000 allocations is too much for |
…rating calls (#115827) On SysV it is possible to have mixed SIMD/integer return registers for calls. This leads to a case where the first return register is a SIMD register, while the second return register is an integer register. In that particular case, the emitter would get confused and expect GC information for the second return register to refer to `rdx`, when in reality it refers to `rax`. Fix the problem by detecting the case where the second register is `rax`, and communicating the right information back to the emitter. Also add a test case that reliably segfaults under `DOTNET_GCStress=C` without the fix.
On SysV it is possible to have mixed SIMD/integer return registers for calls. This leads to a case where the first return register is a SIMD register, while the second return register is an integer register. In that particular case, the emitter would get confused and expect GC information for the second return register to refer to
rdx
, when in reality it refers torax
.Fix the problem by detecting the case where the second register is
rax
, and communicating the right information back to the emitter. Also add a test case that reliably segfaults underDOTNET_GCStress=C
without the fix.Fix #115815