-
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
Forbid fgMorphCommutative during optValnumCSE_phase #57160
Conversation
A better fix is to check nodes for |
I believe it is an invariant in the optimizer that the morphing functions must always preserve VNs, otherwise we risk getting very hard to catch bugs in (currently, only) RangeCheck. I think this transform can actually preserve VNs without much difficulty, if it is restructured a little. Right now it does this:
Which leaves VNs of both It should be possible to make it do this:
Bashing Note: the current code fails to account for |
@SingleAccretion Thank you for detailed response! |
@EgorBo please review the code to merge this before RC1. |
From my understanding @echesakovMSFT is working on a less conservative fix (?) |
1. Maintain VNs of op1 and cns1 2. Use less conservative check for gtIsActiveCSE_Candidate() in fgMorphCommutative()
This is now "no-diffs" change. Note that with the new change folding of Before transformation:
After transformation:
|
As much as I would like to say that the change looks good, there are still problems.
tree $1 COMMA $1
COMMA $2 COMMA $2
COMMA $2 op1 $2
op1 $2 --> op $3
op $3 cns1 $4+$5
cns1 $4
cns2 $5
// But we need:
COMMA $1
COMMA $1
op1 $1
op $3
cns1 $4+$5 Or so one would think - what we actually need is complicated by the fact that COMMA's have side effects and thus add exception sets. So what actually has to happen is that we need to update the "normal" parts of the VN for the COMMA's, all the while op1's VN will have to exclude the exceptions coming only from the COMMA nodes (they may come from children too). Which is totally not worth the complexity, so I suggest disabling this transform if we're not in the global morphing phase and COMMA's are involved. Sorry for not bringing up the COMMA issues earlier, it is not very easy to reason about morphing and VN for me at times (and easy to forget about things like exception sets). |
I agree, but not 100% sure it's necessary if we return something with original tree's VN in the end. Good points, @SingleAccretion. Also, notes about |
Well, if we are going to delete the tree from IR, we need to make sure it is not a CSE candidate, otherwise all the familiar asserts about CSE failing to find the node will fail (or rather wait for someone to find a test case which exposes them...). CSE caches Edit: I also note that the concerns about CSE and preserving VNs are somewhat orthogonal. It is obvious we cannot change VNs of CSE candidates, or delete them. Effects of failing to update VNs, including the exception sets, (which must be done always regardless of CSE) are much more subtle by nature and are rooted in the implicit assumptions in the optimizer that the morphing functions do update the VNs properly. |
Shouldn't we just go with the original fix:
|
When tree.op1 is complex - don't run the optimization outside of global morph.
@SingleAccretion @EgorBo Thank you for your feedback! I agree, introducing COMMA handling would complicate the optimization too much. I pushed a second improvement where we check for complexity of |
@briansull I could go with the original solution a week ago (and we still can do it now if we think it is a better choice) but I've been trying to avoid introducing new regressions by stopping doing the optimization abruptly during VN/CSE phase. |
LGTM assuming CI failures are unrelated |
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.
Nice! Two small nits, feel free to ignore.
Thanks for review! I applied the first nit, the second one, unfortunately, would cause regressions (I tried this last week) - I added comment explaining why we need this handling of fieldSeq. |
runtime (Libraries Test Run checked coreclr windows x86 Release) failure is due to #57471 |
I am going to ignore runtime (Mono minijit Pri0 Runtime Tests Run OSX x64 release) and runtime (Mono monointerpreter Pri0 Runtime Tests Run OSX x64 release) since they are triggered only because I added a test and were passing on a previous attempt. EDIT: All the test legs except runtime (Libraries Test Run checked coreclr windows x86 Release) passed on a second attempt (see #20210817.55) |
During
fgMorphCommutative
we don't update a VN of modified trees properly and, as a result, in #56935 the JIT made wrong decision duringoptVNAssertionPropCurStmt
. (You can find out what exactly happens in the comments for the regression test).The fix is to not allow running
fgMorphCommutative
duringoptValnumCSE_phase
(as we do for similar optimizations).The change is conservative and results in some regressions (I will post the results later), but there nothing major as far as I can tell, so I am open for suggestions whether we can do anything that is better and still safe.
@dotnet/jit-contrib PTAL
Fixes #56935