KEMBAR78
IComparer<T> constraint leads to worse codegen than IComparisonOperators<T,T,bool> constraint · Issue #78383 · dotnet/runtime · GitHub
Skip to content

IComparer<T> constraint leads to worse codegen than IComparisonOperators<T,T,bool> constraint #78383

@stephentoub

Description

@stephentoub

We introduced the new IComparisonOperators<,,> interface as part of the generic math APIs work in .NET 7, but for general-purpose APIs that need to compare and aren't constrained to numerical types, it's preferable from a design perspective to use the longer-standing IComparable<T>. Unfortunately, the codegen that's produced with IComparable<T> can end up being worse than that for IComparisonOperators<,,>, forcing a hard choice. Can we improve the JIT here?

Example:
SharpLab

#nullable disable
using System;
using System.Numerics;
using SharpLab.Runtime;

public class C
{
    [JitGeneric(typeof(int))]
    public static bool M1<T>(T value, T other) where T : IComparable<T>, IComparisonOperators<T, T, bool> =>
        value.CompareTo(other) > 0;
    
    [JitGeneric(typeof(int))]
    public static bool M2<T>(T value, T other) where T : IComparable<T>, IComparisonOperators<T, T, bool> =>
        value > other;
    
    public static bool M3(int value, int other) =>
        value.CompareTo(other) > 0;
    
    public static bool M4(int value, int other) =>
        value > other;
}

Both M1 (generic) and M3 (non-generic) that use CompareTo end up producing:

    L0000: cmp ecx, edx
    L0002: jl short L0013
    L0004: cmp ecx, edx
    L0006: jg short L001a
    L0008: xor eax, eax
    L000a: test eax, eax
    L000c: setg al
    L000f: movzx eax, al
    L0012: ret
    L0013: mov eax, 0xffffffff
    L0018: jmp short L000a
    L001a: mov eax, 1
    L001f: jmp short L000a

whereas both M2 (generic) and M4 (non-generic) that use IComparisonOperators<T,T,bool> end up producing:

    L0000: xor eax, eax
    L0002: cmp ecx, edx
    L0004: setg al
    L0007: ret

Related to #78222
cc: @EgorBo, @tannergooding

Metadata

Metadata

Assignees

Labels

Priority:3Work that is nice to havearea-CodeGen-coreclrCLR JIT compiler in src/coreclr/src/jit and related components such as SuperPMI

Type

No type

Projects

No projects

Relationships

None yet

Development

No branches or pull requests

Issue actions