Closed
Description
Repro:
SharpLab
#nullable disable
using System.Numerics;
using SharpLab.Runtime;
public class C
{
[JitGeneric(typeof(int))]
public static bool M1<T>(T value) where T : INumberBase<T> =>
T.IsNegative(value) || T.IsZero(value);
public static bool M2(int value) =>
value < 0 || value == 0;
[JitGeneric(typeof(int))]
public static bool M3<T>(T value) where T : INumberBase<T>, IComparisonOperators<T,T,bool> =>
value <= T.Zero;
public static bool M4(int value) =>
value <= 0;
}
Both M1 (generic) and M2 (non-generic) that do separate negative and zero checks produce:
L0000: test ecx, ecx
L0002: jl short L000c
L0004: xor eax, eax
L0006: test ecx, ecx
L0008: sete al
L000b: ret
L000c: mov eax, 1
L0011: ret
whereas both M3 (generic) and M4 (non-generic) that do combined negative and zero checks produce:
L0000: xor eax, eax
L0002: test ecx, ecx
L0004: setle al
L0007: ret
Similarly for >=
.
The approved design of #78222 was based on the idea that these would be the same, and thus the generic methods there could constrain T to just being INumberBase<T>
and not require IComparisonOperators<T,T,bool>
as well, but if it's going to remain producing worse code, we should reconsider.
cc: @EgorBo, @tannergooding