Skip to content

RyuJIT: Don't convert GT/LE to EQ/NE for "ARR_LEN cmp 0" - #35758

Closed
EgorBo wants to merge 1 commit into
dotnet:masterfrom
EgorBo:bc-cmp-0
Closed

RyuJIT: Don't convert GT/LE to EQ/NE for "ARR_LEN cmp 0"#35758
EgorBo wants to merge 1 commit into
dotnet:masterfrom
EgorBo:bc-cmp-0

Conversation

@EgorBo

@EgorBoEgorBo commented May 2, 2020

Copy link
Copy Markdown
Member

RyuJIT converts (uint)x > 0 to x != 0 (same for <=) but I suggest we keep it as it is for things like (uint)array.Length > 0 since != and == operators are not bound checks elimination friendly, e.g.:

publicstaticvoidFoo1(int[]array){if((uint)array.Length>0)array[0]=42;}publicstaticvoidFoo2(int[]array){if(0<(uint)array.Length)// same condition, different orderarray[0]=42;}

Before my changes

; Method Egor:Foo1(System.Int32[]) 4883EC28 subrsp,40 8B4108 moveax, dword ptr [rcx+8] 85C0 testeax,eax 740C je SHORT G_M52406_IG04 83F800 cmpeax,0 760C jbe SHORT G_M52406_IG05 C741102A000000 mov dword ptr [rcx+16],42G_M52406_IG04: 4883C428 addrsp,40 C3 retG_M52406_IG05: E81FC5485F call CORINFO_HELP_RNGCHKFAIL CC int3; Total bytes of code: 34; Method Egor:Foo2(System.Int32[]) 8B4108 moveax, dword ptr [rcx+8] 85C0 testeax,eax7407je SHORT G_M52789_IG04 C741102A000000 mov dword ptr [rcx+16],42G_M52789_IG04: C3 ret; Total bytes of code: 15

^ As you can see, bound checks are removed only for "unnatural" (IMO) condition in Foo3
That's why we have this "unnatural" conditions in String.IsNullOrEmpty and other places.

After my changes

; Method Egor:Foo1(System.Int32[]) 8B4108 moveax, dword ptr [rcx+8] 85C0 testeax,eax7407je SHORT G_M52406_IG04 C741102A000000 mov dword ptr [rcx+16],42G_M52406_IG04: C3 ret; Total bytes of code: 15; Method Egor:Foo2(System.Int32[]) 8B4108 moveax, dword ptr [rcx+8] 85C0 testeax,eax7407je SHORT G_M52789_IG04 C741102A000000 mov dword ptr [rcx+16],42G_M52789_IG04: C3 ret; Total bytes of code: 15

@Dotnet-GitSync-BotDotnet-GitSync-Bot added the area-CodeGen-coreclr CLR JIT compiler in src/coreclr/src/jit and related components such as SuperPMI label May 2, 2020
@benaadams

Copy link
Copy Markdown
Member

Span<int> has same issue

publicstaticvoidFoo1(Span<int>array){if((uint)array.Length>0)array[0]=42;}publicstaticvoidFoo2(Span<int>array){if(0<(uint)array.Length)// same condition, different orderarray[0]=42;}
C.Foo1(System.Span`1<Int32>) L0000: pushebp L0001: movebp,esp L0003: moveax,[ebp+0xc] L0006: testeax,eax L0008: jz L0018 L000a: cmpeax,0x0 L000d: jbe L001c L000f: moveax,[ebp+0x8] L0012: mov dword [eax],0x2a L0018: popebp L0019: ret0x8 L001c: call0x62022680 L0021: int3C.Foo2(System.Span`1<Int32>) L0000: moveax,[esp+0x8] L0004: testeax,eax L0006: jz L0012 L0008: moveax,[esp+0x4] L000c: mov dword [eax],0x2a L0012: ret0x8

// and (x GT_LE.unsigned 0) into (x GT_EQ 0). The later case is rare, it sometimes
// occurs as a result of branch inversion.
// NOTE: keep it as it is for Array.Length op1 since GT_NE/GT_EQ operators are
// not bounds check elimination friendly yet.

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Do you know how hard it is to make it friendly?
As I see we use

staticboolOperIsBoundsCheck(genTreeOps op)
to find what we optimize as a bound check and we don't have EQ/NE there, should we add them?

@EgorBo

Copy link
Copy Markdown
MemberAuthor

As far as I understand it's already handled in #40180

@EgorBoEgorBo closed this Sep 10, 2020
@nathan-moore

Copy link
Copy Markdown
Contributor

As far as I understand it's already handled in #40180

I checked, it indeed is :). Should also handle the span case.

@ghostghost locked as resolved and limited conversation to collaborators Dec 9, 2020
Sign up for freeto subscribe to this conversation on GitHub. Already have an account? Sign in.

Labels

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

Projects

None yet

Development

Successfully merging this pull request may close these issues.

5 participants

@EgorBo@benaadams@nathan-moore@sandreenko@Dotnet-GitSync-Bot