-
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
Fix incorrect GTF_IND_NONFAULTING
setting that leads to an incorrect execution.
#13762
Comments
@CarolEidt could you please take a look and advise? I will try to create an IL repo to show bad execution tomorrow, but I am not sure how that can be fixed in general (except by forbidding revert or |
The code you show in I find it quite unfortunate that we are doing order-based assertions prior to actually setting the evaluation order, which seems like it has significant potential for issues like this. A couple of things come to mind:
I know that @erozenfeld has spent time with the side-effect flags and their propagation, and he might have some insight into this. |
Actually I hope I'll get to ASG elimination sooner rather than later. The more stuff like this I the less I believe that it can actually be fixed in a reliable manner. But yes, in the meantime there are better ways to deal with ASG. I already started this with dotnet/coreclr#27445 and next on the list is liveness. Eventually all the JIT should follow the same approach.
Yes, but we'll need to set it in morph. It's currently set during SSA construction.
I need to take a closer look at this, it's not clear to me what stops this kind of reordering from occurring in other situations that do not involve ASG nodes. Anyone knows? |
Ah, but assertion prop sets |
As far as I can tell there are 2 different problems here:
I'm guessing that the first problem may be easy to fix. The second one requires a bit more work :) |
@mikedn - thanks for the excellent summary! Agree on the observation that the second issue will likely require more work. |
Thank you both, @CarolEidt and @mikedn. |
Looking a bit more at // However, if the LHS is a lclVar address, SSA relies on using evaluation order for its
// renaming, and therefore the RHS must be evaluated first. Hmm, dotnet/coreclr#27445 changed SSA so this is no longer necessary. Though there are still cases where |
BTW, memory liveness is messed up because of the way this flag is set. Since first liveness run is done before SSA the flag is not set so this code: Also, rationalization clears So...
|
I have failed to create a repro that hits that bug and leads to an incorrect execution. However, I have found that
or Lucky for us, most of the internal assignments that we have now could write only to temporary variables (TMP0NN) that are not used in other parts of a tree. Also, I think the solution to this that requires minimal changes could be to better describe these special internal assignments. Like prove and check that it is safe to do what we do now. Add checks that we don't have assignments that write to |
Yes, so how did you manage to produce that tree? :) |
I was not able to do that honestly. |
FWIW CSE can create trees where swapping would lead to a use before def case: return x * 3 + x * 3; generates:
But CSE runs in linear order and at that point swapping no longer happens. Comma trees produced by |
@mikedn thanks for that example. It means our current contract is less obvious then I thought. So:
Am I missing something? |
We'd need to move the entire JIT to LIR or something similar. Maybe once we get rid of ASG, LIST & co. that would be easier but as is now moving to LIR would be too difficult. Practically impossible. It's also not 100% clear if moving to LIR would be a good thing. It has advantages but also downsides - tree transforms would need to manually maintain linear order. That's more work for the developer and it's also easy to make mistakes.
Have you tried that? For one thing, I would expect that there aren't that many internal assignments at the point where swapping is done. Keep in mind that once move to linear order (N.B
Besides, |
I have tried to correctly propagate If you also fix
I saw many assignments under call nodes for arg setup, so these nodes already had side effects but it was legal to swap the order if another subtree was free from them. |
Right, I've got lost in all this and forgot about that. So it seems that it's not a good idea to add The trouble is that this kind of special casing can't be handled easily in
Fixing only if ((secondNode->gtFlags & GTF_ASG) != 0)
{
if (!firstNode->OperIsConst())
{
return false;
}
} then the result is a very small diff and it is actually an improvement of ~80 bytes. But yes, if call nodes also get
|
Seems like there's a potential for a bug here, but we haven't found an actual test case. Moving to future. |
For such a test case:
we will generate a tree like:
where
000003 INDIR
doesn't have an exception flag and because clever morph can see that we have already dereferenced it in000007 INDIR
:so far so good, but then
fgSetBlockOrder
could decide to revert000008
and guess what now it can clear the exception flag from000007
because now we execute it after000003
that is known not to throw (because it gotGTF_IND_NONFAULTING
during the previous phase) so we end up proving that this indirection can't throw:when it is, of course, incorrect:Update: that is correct in this case because
this
is never null (we check it before a call to an instance method).TestClass obj = null;
obj.TestNullRef();we set revert flag here:
https://github.com/dotnet/coreclr/blob/68043c6306a0449bb5ed10fbdea9f14dafc99df4/src/jit/gentree.cpp#L4004-L4023
under conditions that are not clear to me.
Summary: if we fix #13758 we will have
GTF_ASG
on000006
. Then000008
won't be reverted (because of the strange condition that I showed earlier that checksGTF_ASG
), so we won't incorrectly dropGTF_EXC
from both indirections. However, it will lead to 0.07% code size regression in System.Private.Corelib and 0.31% on framework libraries and it is not a complete fix for the problem.Link #10813 and dotnet/coreclr#19334.
category:correctness
theme:optimization
skill-level:intermediate
cost:medium
The text was updated successfully, but these errors were encountered: