dotnet/runtime
Vedi su GitHubOptimize some trivial comparison patterns for unsigned integer types
Open
#99.757 aperta il 14 mar 2024
area-CodeGen-coreclrhelp wantedtenet-performance
Metriche repository
- Star
- (17.886 star)
- Metriche merge PR
- (Merge medio 12g 11h) (661 PR mergiate in 30 g)
Descrizione
Description
I noticed that RyuJIT doesn't even optimize some simple comparison against unsigned integers.
Case 1: value - N < value is equivalent to value > N - 1 for any N
Consider this code:
using System;
using System.Runtime.CompilerServices;
public static class _____AAAAA
{
[MethodImpl(MethodImplOptions.AggressiveInlining)]
public static bool Q(nuint a, nuint b)
{
return a < b;
}
public static bool QTest0(nuint b) => Q(b - 1, b);
public static bool QTest1(nuint b) => b == 0 || Q(b - 1, b);
}
The QTest0 could just be
xor eax, eax
test rcx, rcx
setne al
ret
but it is:
lea rax, [rcx-1]
cmp rax, rcx
setb al
movzx eax, al
ret
And the QTest1 could just be
mov eax, 1
ret
but it is:
test rcx, rcx
je short L0013
lea rax, [rcx-1]
cmp rax, rcx
setb al
movzx eax, al
ret
mov eax, 1
ret
Case 2: (value - N) != value is equivalent to N != 0
Consider this code:
using System;
using System.Runtime.CompilerServices;
public static class _____AAAAA
{
[MethodImpl(MethodImplOptions.AggressiveInlining)]
public static bool R(nuint a, nuint b)
{
return a != b;
}
public static bool RTest0(nuint b) => R(b - 1, b);
public static bool RTest1(nuint b) => R(b + 1, b);
}
The RyuJIT currently generates the code below:
; Core CLR 8.0.123.58001 on x64
_____AAAAA.R(UIntPtr, UIntPtr)
L0000: xor eax, eax
L0002: cmp rcx, rdx
L0005: setne al
L0008: ret
_____AAAAA.RTest0(UIntPtr)
L0000: lea rax, [rcx-1]
L0004: cmp rax, rcx
L0007: setne al
L000a: movzx eax, al
L000d: ret
_____AAAAA.RTest1(UIntPtr)
L0000: lea rax, [rcx+1]
L0004: cmp rax, rcx
L0007: setne al
L000a: movzx eax, al
L000d: ret
In this case, RTest0 and RTest1 could just return true without checking anything.
Configuration
Regression?
Unknown