Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

JIT: simple range check is not branchless #96819

Open
EgorBo opened this issue Jan 10, 2024 · 7 comments · May be fixed by #112945
Open

JIT: simple range check is not branchless #96819

EgorBo opened this issue Jan 10, 2024 · 7 comments · May be fixed by #112945
Assignees
Labels
area-CodeGen-coreclr CLR JIT compiler in src/coreclr/src/jit and related components such as SuperPMI in-pr There is an active PR which will close this issue when it is merged
Milestone

Comments

@EgorBo
Copy link
Member

EgorBo commented Jan 10, 2024

bool IsInRange(int value, int lower, int upper) => 
    value >= lower && value <= upper;

Current arm64 codegen:

; Method Program:IsInRange(int,int,int):ubyte:this (FullOpts)
G_M32893_IG01:  ;; offset=0x0000
            stp     fp, lr, [sp, #-0x10]!
            mov     fp, sp
G_M32893_IG02:  ;; offset=0x0008
            cmp     w1, w2
            blt     G_M32893_IG05
G_M32893_IG03:  ;; offset=0x0010
            cmp     w1, w3
            cset    x0, le
G_M32893_IG04:  ;; offset=0x0018
            ldp     fp, lr, [sp], #0x10
            ret     lr
G_M32893_IG05:  ;; offset=0x0020
            mov     w0, wzr
G_M32893_IG06:  ;; offset=0x0024
            ldp     fp, lr, [sp], #0x10
            ret     lr
; Total bytes of code: 44

Expected codgen:

G_M32893_IG01:  ;; offset=0x0000
            stp     fp, lr, [sp, #-0x10]!
            mov     fp, sp
G_M32893_IG02:  ;; offset=0x0008
            cmp     w1, w2
            ccmp    w1, w3, #0, ge
            cset    w1, le
            ret
G_M32893_IG06:  ;; offset=0x0024
            ldp     fp, lr, [sp], #0x10
            ret     lr
; Total bytes of code: 32

(based on https://godbolt.org/z/oqjfMPosj)

cc @jakobbotsch @dotnet/jit-contrib

@ghost ghost added the untriaged New issue has not been triaged by the area owner label Jan 10, 2024
@dotnet-issue-labeler dotnet-issue-labeler bot added the area-CodeGen-coreclr CLR JIT compiler in src/coreclr/src/jit and related components such as SuperPMI label Jan 10, 2024
@ghost
Copy link

ghost commented Jan 10, 2024

Tagging subscribers to this area: @JulieLeeMSFT, @jakobbotsch
See info in area-owners.md if you want to be subscribed.

Issue Details
bool IsInRange(int value, int lower, int upper) => 
    value >= lower && value <= upper;

Current arm64 codegen:

; Method Program:IsInRange(int,int,int):ubyte:this (FullOpts)
G_M32893_IG01:  ;; offset=0x0000
            stp     fp, lr, [sp, #-0x10]!
            mov     fp, sp
G_M32893_IG02:  ;; offset=0x0008
            cmp     w1, w2
            blt     G_M32893_IG05
G_M32893_IG03:  ;; offset=0x0010
            cmp     w1, w3
            cset    x0, le
G_M32893_IG04:  ;; offset=0x0018
            ldp     fp, lr, [sp], #0x10
            ret     lr
G_M32893_IG05:  ;; offset=0x0020
            mov     w0, wzr
G_M32893_IG06:  ;; offset=0x0024
            ldp     fp, lr, [sp], #0x10
            ret     lr
; Total bytes of code: 44

Expected codgen:

G_M32893_IG01:  ;; offset=0x0000
            stp     fp, lr, [sp, #-0x10]!
            mov     fp, sp
G_M32893_IG02:  ;; offset=0x0008
        cmp     w1, w2
        ccmp    w1, w3, #0, ge
        cset    w1, le
        ret
G_M32893_IG06:  ;; offset=0x0024
            ldp     fp, lr, [sp], #0x10
            ret     lr

(based on https://godbolt.org/z/oqjfMPosj)

cc @jakobbotsch @dotnet/jit-contrib

Author: EgorBo
Assignees: -
Labels:

area-CodeGen-coreclr, untriaged

Milestone: -

@EgorBo
Copy link
Member Author

EgorBo commented Jan 10, 2024

Ah, I presume it's BBJ_RETURN <cond> messes things up.

void IsInRange(int value, int lower, int upper)
{
    if (value >= lower && value <= upper)
        Console.WriteLine();
}

works as expected

@jakobbotsch
Copy link
Member

cc @a74nh

@jakobbotsch
Copy link
Member

jakobbotsch commented Jan 11, 2024

Note that the handling of conversion from short circuiting to bitwise ops is done inside "optimize bools" phase, in optOptimizeCompareChainCondBlock, so likely that's where there we could enhance treatment of GT_RETURN. Ideally these kind of conversions would be PGO based since it's not clear that it is always an optimization to make your example branchless. That would require us to have reliable PGO data at the point of "optimize bools" though, which we don't have yet. The example works fine if the user themselves make it branchless (=> value >= lower & value <= upper).

@a74nh are you interested in working on it?

@a74nh
Copy link
Contributor

a74nh commented Jan 11, 2024

Note that the handling of conversion from short circuiting to bitwise ops is done inside "optimize bools" phase, in optOptimizeCompareChainCondBlock, so likely that's where there we could enhance treatment of GT_RETURN.

Right, should be similar to the if conversion code.

@a74nh are you interested in working on it?

Yes, but not in the immediate future as there is a lot of SVE work to do.

@JulieLeeMSFT JulieLeeMSFT added this to the 9.0.0 milestone Jan 13, 2024
@ghost ghost removed the untriaged New issue has not been triaged by the area owner label Jan 13, 2024
@AndyAyersMS
Copy link
Member

Seems like we should move this one out of .NET 9?

@a74nh
Copy link
Contributor

a74nh commented Aug 9, 2024

Seems like we should move this one out of .NET 9?

Agreed. We're not going to get to this in time.

@a74nh a74nh modified the milestones: 9.0.0, 10.0.0 Aug 9, 2024
@dotnet-policy-service dotnet-policy-service bot added the in-pr There is an active PR which will close this issue when it is merged label Feb 25, 2025
jonathandavies-arm added a commit to jonathandavies-arm/runtime that referenced this issue Feb 26, 2025
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
area-CodeGen-coreclr CLR JIT compiler in src/coreclr/src/jit and related components such as SuperPMI in-pr There is an active PR which will close this issue when it is merged
Projects
None yet
Development

Successfully merging a pull request may close this issue.

5 participants