Skip to content

Numerical < and == comparisons aren't fused into <= #78385

Closed

Description

@stephentoub

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

Activity

  1. ghost added
    area-CodeGen-coreclrCLR JIT compiler in src/coreclr/src/jit and related components such as SuperPMI
    on Nov 15, 2022
  2. ghost added
    untriagedNew issue has not been triaged by the area owner
    on Nov 15, 2022
  3. EgorBo commented on Nov 15, 2022

    @EgorBo
    Member

    I have a branch that does this, it's just that I didn't see a lot of diffs from it and gave up, might give it a try again.
    This might also be handled in optOptimizeBools. It looks similar to what we landed there recently by some community PR.

  4. stephentoub commented on Nov 15, 2022

    @stephentoub
    MemberAuthor

    I didn't see a lot of diffs from it

    I expect that will change once #78222 happens and rolls out. :)

    It's good to know this is fixable such that we don't need to change the API shape.

  5. EgorBo commented on Nov 15, 2022

    @EgorBo
    Member

    Similar to #61940 in case if @drewnoakes is interested in extending that to this case

  6. drewnoakes commented on Nov 15, 2022

    @drewnoakes
    Member

    Pinging @pedrobsaila who provided the implementation for that issue.

  7. EgorBo commented on Nov 15, 2022

    @EgorBo
    Member

    Ah, oops, pinged author of the issue instead of author of the PR 😄

  8. pedrobsaila commented on Nov 15, 2022

    @pedrobsaila
    Contributor

    Interested :) You can assign the issue to me

  9. added this to the 8.0.0 milestone on Nov 15, 2022
  10. ghost removed
    untriagedNew issue has not been triaged by the area owner
    on Nov 15, 2022
  11. ghost added
    in-prThere is an active PR which will close this issue when it is merged
    on Nov 23, 2022
  12. ghost removed
    in-prThere is an active PR which will close this issue when it is merged
    on Jun 10, 2023
  13. ghost locked as resolved and limited conversation to collaborators on Jul 10, 2023
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Metadata

Metadata

Labels

area-CodeGen-coreclrCLR JIT compiler in src/coreclr/src/jit and related components such as SuperPMI

Type

No type

Projects

No projects

    Milestone

    Relationships

    None yet

    Development

    No branches or pull requests

    Issue actions