-
Notifications
You must be signed in to change notification settings - Fork 5.2k
JIT: Assertprop improvements #97908
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: Assertprop improvements #97908
Conversation
Tagging subscribers to this area: @JulieLeeMSFT, @jakobbotsch Issue DetailsThis PR does:
static int Test(int x)
{
if ((uint)x < 100)
return x % 8;
return 0;
} Codegen diff: ; Method Program:Test(int):int (FullOpts)
G_M46009_IG01:
G_M46009_IG02:
xor eax, eax
mov edx, ecx
- sar edx, 31
and edx, 7
- add edx, ecx
- and edx, -8
- mov r8d, ecx
- sub r8d, edx
cmp ecx, 100
- cmovb eax, r8d
+ cmovb eax, edx
G_M46009_IG03:
ret
-; Total bytes of code: 29
+; Total bytes of code: 14
|
PTAL @AndyAyersMS @jakobbotsch @dotnet/jit-contrib |
// Note this tracks at most only 256 assertions. | ||
// | ||
static const AssertionIndex countFunc[] = {64, 128, 256, 64}; | ||
static const AssertionIndex countFunc[] = {64, 128, 256, 128, 64}; |
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.
Allowed a bit more assertions for large methods - it was done mainly to fix asm regressions introduced by new asserts where old ones were thrown away due to this limit.
// Cases where op1 holds the upper bound arithmetic and op2 is 0. | ||
// Loop condition like: "i < bnd +/-k == 0" | ||
// Assertion: "i < bnd +/- k == 0" | ||
if (hasTestAgainstZero && vnStore->IsVNCompareCheckedBoundArith(op1VN)) |
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.
testAgainstZero asserts have no diffs (x relop y) ==/!= 0
. All asserts are just x relop y
.
So I removed them.
{ | ||
// (uint)index < CNS | ||
// (uint)index >= CNS | ||
return (funcApp.m_func == VNF_LT_UN) || (funcApp.m_func == VNF_GE_UN); |
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.
IsVNConstantBoundUnsigned
was a bit conservative and only tried to detect useful cases. But it forgot that we create complimentary asserts as well which may turn useless ones into useful too.
// OAK_[NOT]_EQUAL assertion with op1 being O1K_CONSTANT_LOOP_BND | ||
// representing "(X relop CNS) ==/!= 0" assertion. | ||
if (!curAssertion->IsConstantBound()) | ||
if (!curAssertion->IsConstantBound() && !curAssertion->IsConstantBoundUnsigned()) |
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.
Here for optAssertionProp_ModDiv
I added IsConstantBoundUnsigned
(unsigned comparisons against constants).
Previously we could optimize div only for x > cns
assert. This adds (uint)x < cns
case as well.
Btw, just FYI: Diffs if we bump max assertions threshold to just 256. |
/azp run Fuzzlyn |
Azure Pipelines successfully started running 1 pipeline(s). |
CI Failure is known |
This PR does:
Codegen diff: