-
Notifications
You must be signed in to change notification settings - Fork 5k
Fold "X < NN && X >= 0" to "X u>= NN" #115240
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
base: main
Are you sure you want to change the base?
Conversation
Tagging subscribers to this area: @JulieLeeMSFT, @jakobbotsch |
@@ -5551,6 +5551,17 @@ GenTree* Compiler::optAssertionProp(ASSERT_VALARG_TP assertions, GenTree* tree, | |||
case GT_NULLCHECK: | |||
return optAssertionProp_Ind(assertions, tree, stmt); | |||
|
|||
case GT_ARR_LENGTH: |
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.
Does this handling mean Span won't quite light up?
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.
In this specific case we have ARR_LENGTH(obj)
and we try to remove GTF_EXCEPT
from ARR_LENGTH
node if obj
is known to be non-null (e.g. via assertions). It's not needed for span because: 1) in 99% of cases Span is promoted to locals (so the length is a local) 2) null check is not needed for Span anyway
Do you really want to apply this on such a scale? How about There must be some code relying on these simple checks to just work as expected. This is a nice optimization under controlled circumstances like Span, but can break spectacular. |
What change?
It transforms that to — In general Speaking of, however, are we handling both forms of the comparison @EgorBo? That is both the && and the || variants to ensure either branching pattern works? |
Test(int.MinValye+4) was the case I tried to write. Sorry for the confusion. You might get away with this if you are at the same time using a bigger types, which may just work on 64 bit depending on processor type. But we can't just break normal integer ranges. |
That wouldn’t fail either, it is This transform is safe for any two’s complement integer where NN is known to not have the most significant bit set (and therefore would be never negative if interpreted as a signed value). |
Yes, under that assumption the >= 0 check is always true. But with the short sample code it is impossible to prove that it is net set. And using the array length is just any other positive integer as bound as it is not used to access the array. That doesn't say anything about the index integer. But it looks like the changed code already does 'a fe'w more checks than this simple example code. |
The length of an array is statically known to be “never negative” when interpreted as signed, it is an invariant of the runtime and is what makes this safe. This PR is taking advantage of that invariant |
codegen diff: https://www.diffchecker.com/x8sugXxP/
Also, I used the logic from #93531 but guarded it under "global prop" only to avoid regressions.