-
Notifications
You must be signed in to change notification settings - Fork 4.9k
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: Fix physical promotion creating overlapping local uses #91058
Conversation
Physical promotion could in some cases create uses overlapping illegally with defs when faced with seemingly last uses of structs. This is a result of a mismatch between our model for liveness and the actual model of local uses in the backend. In the actual model, the uses of LCL_VARs occur at the user, which means that it is possible for there to be no place at which to insert IR between to local uses. The example looks like the following. Physical promotion would be faced with a tree like ``` ▌ CALL void Program:Foo(Program+S,Program+S) ├──▌ LCL_VAR struct<Program+S, 4> V01 loc0 └──▌ LCL_VAR struct<Program+S, 4> V01 loc0 ``` When V01 was fully promoted, both of these are logically last uses since all state of V01 is stored in promoted field locals. Because of that we would make the following transformation: ``` ▌ CALL void Program:Foo(Program+S,Program+S) ├──▌ LCL_VAR struct<Program+S, 4> V01 loc0 (last use) └──▌ COMMA struct ├──▌ STORE_LCL_FLD int V01 loc0 [+0] │ └──▌ LCL_VAR int V02 tmp0 └──▌ LCL_VAR struct<Program+S, 4> V01 loc0 (last use) ``` This creates an illegally overlapping use and def; additionally, it is correct only in a world where the store actually would happen between the two uses. It is also moderately dangerous to mark both of these as last uses given the implicit byref transformation. The fix is to avoid marking a struct use as a last use if we see more struct uses in the same statement. Fix dotnet#91056
Tagging subscribers to this area: @JulieLeeMSFT, @jakobbotsch Issue DetailsPhysical promotion could in some cases create uses overlapping illegally with defs when faced with seemingly last uses of structs. This is a result of a mismatch between our model for liveness and the actual model of local uses in the backend. In the actual model, the uses of LCL_VARs occur at the user, which means that it is possible for there to be no place at which to insert IR between to local uses. The example looks like the following. Physical promotion would be faced with a tree like
When V01 was fully promoted, both of these are logically last uses since all state of V01 is stored in promoted field locals. Because of that we would make the following transformation:
This creates an illegally overlapping use and def; additionally, it is correct only in a world where the store actually would happen between the two uses. It is also moderately dangerous to mark both of these as last uses given the implicit byref transformation. The fix is to avoid marking a struct use as a last use if we see more struct uses in the same statement. Fix #91056
|
cc @dotnet/jit-contrib PTAL @AndyAyersMS Diffs. Just a single one in a test case. |
/backport to release/8.0 |
Started backporting to release/8.0: https://github.com/dotnet/runtime/actions/runs/5967909534 |
Physical promotion could in some cases create uses overlapping illegally with defs when faced with seemingly last uses of structs. This is a result of a mismatch between our model for liveness and the actual model of local uses in the backend. In the actual model, the uses of LCL_VARs occur at the user, which means that it is possible for there to be no place at which to insert IR between two local uses.
The example looks like the following. Physical promotion would be faced with a tree like
When V01 was fully promoted, both of these are logically last uses since all state of V01 is stored in promoted field locals. Because of that we would make the following transformation:
This creates an illegally overlapping use and def; additionally, it is correct only in a world where the store actually would happen between the two uses. It is also moderately dangerous to mark both of these as last uses given the implicit byref transformation.
The fix is to avoid marking a struct use as a last use if we see more struct uses in the same statement.
Fix #91056