dotnet/runtime
在 GitHub 查看Optimize some trivial comparison patterns for unsigned integer types
Open
#99,757 建立於 2024年3月14日
area-CodeGen-coreclrhelp wantedtenet-performance
倉庫指標
- Star
- (17,886 star)
- PR 合併指標
- (平均合併 12天 11小時) (30 天內合併 661 個 PR)
描述
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