-
Notifications
You must be signed in to change notification settings - Fork 4.8k
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: emitter assert running PMI #10821
Comments
Had forgotten about this one and hoped some of the recent fixes in this area (eg dotnet/coreclr#21217 or dotnet/coreclr#21477) might have fixed it, but it still repros. In we see tmp2 defined as a long and then used as a byref:
Here
So perhaps we need some kind of special cast here in jit IR? |
But does that actually matter? The value must have been a native pointer to begin with and changing its type to byref shouldn't have any effect (e.g. not reporting it to the GC won't make a difference because it isn't a managed pointer). |
Agree there's probably not a correctness issue here -- it's more a question of how robust the jit can be about tracking an asserting GC consistency. |
Will take another look at this. |
I think the rough plan for this kind of issue is to have a phase that tries to provide a globally consistent view of byrefs and native ints -- perhaps generalizing the kind of type updating that @erozenfeld introduced as part of the stack allocation work. The importer/inliner has too limited of a window on things to fix this properly. Once we tolerate a mismatch (say at an inline) we can't easily tell what all needs to change to restore order. This rewriting is probably too ambitious to fit into 3.0. Opened dotnet/coreclr#22837 (#12121) to consider implementing a type checker, dotnet/coreclr#22838 (aka #12122) to implement a type rewriter. |
22837 => #12121 |
Still repros:
|
Seems many of these cases are introduced by arg passing during inlining. Looking at handling them by modifying |
That handles one class of changes, but we can also see this retyping for methods like Unsafe.AsRef that retype via local reinterpretation:
We can see this assert fire if we have a long chain of temp copies, reinterpret from long to byref along the way, and then add to the byref, eg
Say we allocate all the RHS temps into RDX. During codegen we see the switch from long to byref, but don't emit any code for it. The last instruction emits an add which is marked as a GC instruction. But the emitter GC tracking only tracks what we actually emit, which is
A couple possible ideas.
And some thoughts on testing: Likely most cases of this are benign because the values are stack references and don't need tracking. But we might see actual GC holes for methods with implicit byref args that are invoked by reflection. |
Having done much less analysis and understanding on this issue than you... it seems like option #2 above is preferable as it is (a) simple, and (b) doesn't lose important type information that seems useful to maintain for modeling. It seems like we should always maintain all type conversions explicitly in the IR (even the late "IR"/emitter) -- I think we don't fully follow this "rule" even in the IR today, where type casts are in some cases omitted (?). |
Here's a bit of the codegen trace from the SPMI example you pointed me at:
Codegen would emit this no-op mov for node However, I'm not sure this really adds anything useful, other than more surgically quieting the emitter assert. We still might be losing track of byrefs in the code upstream of this point. |
If we can add "no encoding" move in an isolated PR we would be able to then remove |
Recent repro:
|
I think in the case above this is a spurious assert. We have a last-use byref in
and this is where we assert later on. In practice RDX will stay GC live after this instruction since we have a "lazy kill" model. |
Reopening since the PR had to be reverted |
Compile attached test case (from #7279, requires
/langversion:latest
) and jit via PMI to get the following emitter assert:This assert is new in the past 10 months or so...(edit: probably not relevant -- we didn't have PMI back then, and this instantiation is not created when you run the test normally).cc @dotnet/jit-contrib
Test case
category:correctness
theme:ir
skill-level:expert
cost:large
The text was updated successfully, but these errors were encountered: