-
Notifications
You must be signed in to change notification settings - Fork 4.7k
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
JIT doesn't allow method prologues to have more than one instruction group #104585
Comments
Tagging subscribers to this area: @JulieLeeMSFT, @jakobbotsch |
The failure, with locals, looks like:
This is triggering in some SPMI replay runs. |
It looks like part of the issue is that most of the locals aren't aren't impacting For example
|
What are those many scenarios? Normally the prolog size is limited naturally by various factors, hence we never needed this support. It would still be nice to support it, but more so due to the flexibility – see #12302. But I think that's a separate work item and not going to happen in .NET 9.
I think the bug here is just around the accounting that you mention, and not related to multi IG support for the prolog, which I think will not be necessary with the bug fixed. |
#104593 should fix the issue by making sure the "needs zeroing" logic is synced in the two places. Thanks for investigating! |
Going to close this as a duplicate of #12302. |
The JIT currently has a restriction that there can only be one IG for the method prologue, this is unlike funclets or the method epilogue which can extend across several.
This is normally not problematic, however there are many scenarios under which the method prologue can extend past the limits of a single group since a single group has a finite number of instructions it can hold.
An example of this is the following program:
If this is run under a
checked
JIT withDOTNET_ReadyToRun=0
,DOTNET_TieredCompilation=0
, andDOTNET_JitStressRegs=0x80
then it will trigger the following assert: https://github.com/dotnet/runtime/blob/main/src/coreclr/jit/emit.cpp#L9670-L9672This happens because we set
genUseBlockInit = (genInitStkLclCnt > 4)
and then ingenZeroInitFrame
use that to determine if we're zeroing using SIMD or using a what is basicallysizeof(void*)
stores of the native general purpose registerThat itself seems "bad" from a performance perspective since it's not accounting for how big these 4 locals are and therefore whether block vs scalar zeroing is "better". But, independently it means that this code path is broken if the total number of store instructions required extends past the limits of a single IG as occurs if you have
4x TYP_SIMD64
as an example.The JIT needs to be updated to support prologues that extend past 1 group to ensure that we are robust in the face of having more than
EMIT_MAX_IG_INS_COUNT
(which can be less in practice for largeinstrDesc
, instructions, in the failure above we hit the limit at 61 instructions out of the maximum 256).Additionally, it would probably be beneficial to have zeroing pick the optimal strategy based on number of bytes needing to be zeroed rather than number of locals.
The text was updated successfully, but these errors were encountered: