-
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 could further optimize "== 0" checks in Boolean logic #13573
Comments
Interesting, 3 (and more) arguments in AreZero actually use this optimization: private static bool AreZero(int x, int y, int z)
{
return x == 0 && y == 0 && z == 0;
} Codegen: ; Method ConsoleApp2.Program:AreZero(int,int,int):bool
G_M22205_IG01:
G_M22205_IG02:
or edx, ecx
jne SHORT G_M22205_IG05
G_M22205_IG03: ;; bbWeight=0.50
test r8d, r8d
sete al
movzx rax, al
G_M22205_IG04: ;; bbWeight=0.50
ret
G_M22205_IG05: ;; bbWeight=0.50
xor eax, eax
G_M22205_IG06: ;; bbWeight=0.50
ret
; Total bytes of code: 17 (I suspect it happens in |
Hack: private static bool AreZero(int x, int y)
{
return x == 0 && y == 0 && BitConverter.IsLittleEndian;
} where Codegen: ; Method ConsoleApp2.Program:AreZero(int,int):bool
G_M22205_IG01:
G_M22205_IG02:
or edx, ecx
jne SHORT G_M22205_IG05
G_M22205_IG03: ;; bbWeight=0.50
mov eax, 1
G_M22205_IG04: ;; bbWeight=0.50
ret
G_M22205_IG05: ;; bbWeight=0.50
xor eax, eax
G_M22205_IG06: ;; bbWeight=0.50
ret
; Total bytes of code: 13 |
Similarly: [MethodImpl(MethodImplOptions.AggressiveInlining)]
private static bool IsEitherNegative(int a, int b)
{
return a < 0 || b < 0;
} Current codegen: L0000: test ecx, ecx
L0002: jl L000d
L0004: test edx, edx
L0006: setl al
L0009: movzx eax, al
L000c: ret
L000d: mov eax, 0x1
L0012: ret Possible optimal codegen below, using the fact that the or ecx, edx
sets al ; or setl, if you prefer, since "or" is known to clear OF
movzx eax, al
ret |
Reproduced
will check where the optimization happens. |
Plan:
|
I was able to modify the code to generate the optimized code for the two argument case.
will run diffs and tests. |
jit-diff shows 1440 methods improvement.
|
Unfortunately I think this may be telling you something has gone wrong -- for a change like this we would expect baseline and new jit to process the exact same number of methods. Output like this means the new jit did not jit (or failed while trying to jit) some methods.
Was there a message printed before he output you show above about "reconciling"? |
@AndyAyersMS you are right. There were 2 base and 3 diff error messages before this, and I was looking into it. Will ping you. |
jit-diff error message
This is the error message when running one of them, but I cannot relate it with my code change.
|
Reproduced the issue. Debugging. In |
* Equals to 0 optimization in Boolean logic * Limit bool optimization to Integral return type only * Use the updated flowList:setEdgeWeights method with the 3rd parameter * Skip bool optimization for cases that require NOT transformation * Skip bool optimization when the third block GT_RETURN is not CNT_INT int * format patch * Added more bool optimization cases * format patch * Refactored setting fold type and comparison type to fix jitstress error * format patch * Refactored common codes for conditional block and return block boolean optimizations * format patch * Unit test changed to remove EH handling and add return value checks * Unit test: add back test cases for ANDing and NE cases * Made OptBoolsDsc struct to pass it off to the helper methods. * format patch * Changed to substructure OptTestInfo within OptBoolsDisc * Cleaned up tree variables in OptBoolsDsc struct * Moved some methods for Boolean Optimization to OptBoolsDsc struct * Moved all private methods for Boolean Optimization to OptBoolsDsc struct * Boolean Optimization: Handled code review feedback * Optimize bools: hoisted jump destination check to optOptimizeBools() and added test cases * format patch * Moved initialization to OptBoolsDsc constructor * format patch Co-authored-by: Julie Lee <jeonlee@microsoft.com>
There are some well-known bit manipulation patterns that the JIT doesn't currently optimize. For instance:
Produces this codegen:
But it could produce this more optimal codegen, folding the two comparisons together into a single
or
and zero check:category:cq
theme:basic-cq
skill-level:beginner
cost:small
The text was updated successfully, but these errors were encountered: