Skip to content

remove bounds checks for some more unsigned comparisons #43568

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

Merged
merged 4 commits into from
Feb 10, 2021

Conversation

nathan-moore
Copy link
Contributor

Remove bounds checks for unsigned constant comparisons against constants of the form
(uint)arr.Length >= 1
(uint)arr.Length >= (uint)1

Of all the different ways of permutating uint casts, the only one we don't remove bound checks is for forms like arr.Length >= (uint)1, due to the vn changing on the array length due to the inserted cast. I haven't looked, but I don't think this particular pattern is common.

Only diff for this change is in corelib:

Total bytes of delta: -128 (-0.004% of base)
    diff is an improvement.

Top file improvements (bytes):
        -128 : System.Private.CoreLib.dasm (-0.004% of base)

1 total files with Code Size differences (1 improved, 0 regressed), 0 unchanged.

Top method regressions (bytes):
           2 (0.056% of base) : System.Private.CoreLib.dasm - DateTimeFormatInfo:CreateTokenHashTable():ref:this (2 methods)

Top method improvements (bytes):
        -130 (-7.501% of base) : System.Private.CoreLib.dasm - DateTimeParse:ParseFormatO(ReadOnlySpan`1,byref):bool

Top method regressions (percentages):
           2 (0.056% of base) : System.Private.CoreLib.dasm - DateTimeFormatInfo:CreateTokenHashTable():ref:this (2 methods)

Top method improvements (percentages):
        -130 (-7.501% of base) : System.Private.CoreLib.dasm - DateTimeParse:ParseFormatO(ReadOnlySpan`1,byref):bool

The regression is that we run out of table space generating an unused assertion, and thus don't eliminate a null check.

Assuming we don't want to keep it open to track arr.Length >= (uint)1, this fixes #11623

cc @briansull

@Dotnet-GitSync-Bot Dotnet-GitSync-Bot added the area-CodeGen-coreclr CLR JIT compiler in src/coreclr/src/jit and related components such as SuperPMI label Oct 19, 2020
@sandreenko
Copy link
Contributor

PTAL @dotnet/jit-contrib

@sandreenko sandreenko self-requested a review November 12, 2020 04:50
@sandreenko
Copy link
Contributor

/azp run runtime-coreclr outerloop

@azure-pipelines
Copy link

Azure Pipelines successfully started running 1 pipeline(s).

Copy link
Contributor

@sandreenko sandreenko left a comment

Choose a reason for hiding this comment

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

Looks good in general, I like the testing, thanks @nathan-moore!

A few nits and questions.

Assuming we don't want to keep it open to track arr.Length >= (uint)1, this fixes #11623

Could you please clarify this? Is this case optimized now? Is not it the same case as "if (destination.Length >= 5)" that is already marked as eliminated in #11623 (comment)

@ViktorHofer
Copy link
Member

// Auto-generated message

69e114c which was merged 12/7 removed the intermediate src/coreclr/src/ folder. This PR needs to be updated as it touches files in that directory which causes conflicts.

To update your commits you can use this bash script: https://gist.github.com/ViktorHofer/6d24f62abdcddb518b4966ead5ef3783. Feel free to use the comment section of the gist to improve the script for others.

Copy link
Contributor

@sandreenko sandreenko left a comment

Choose a reason for hiding this comment

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

@nathan-moore do you have time to finish this PR now? Could you please fix the typos/add requested comments and answer a few questions that were left?

Then I will review it again and merge.

@JulieLeeMSFT JulieLeeMSFT added needs author feedback blocked Issue/PR is blocked on something - see comments labels Feb 8, 2021
@JulieLeeMSFT JulieLeeMSFT added this to the 6.0.0 milestone Feb 8, 2021
@JulieLeeMSFT
Copy link
Member

@nathan-moore do you have time to finish this PR now? Could you please fix the typos/add requested comments and answer a few questions that were left?

Then I will review it again and merge.

Ping @nathan-moore to answer to sandreenko's question.

@nathan-moore
Copy link
Contributor Author

nathan-moore commented Feb 9, 2021

Sorry about taking so long to get back to this.

Assuming we don't want to keep it open to track arr.Length >= (uint)1, this fixes #11623

Could you please clarify this? Is this case optimized now? Is not it the same case as "if (destination.Length >= 5)" that is already marked as eliminated in #11623 (comment)

This isn't something that is optimized currently. If my memory serves right, internally a cast is inserted for the array length, and then value numbering puts a different vn on the cast. From a bounds check perspective, I don't see anyone writing code like this, but we can keep the issue open to track it. Note that similar patterns work (uint)arr.Length >= (uint)1, arr.Length >= 1, and (uint)arr.Length >= 1 (and similarly with > and such).

This pattern has also become more popular since I last touched this:

Total bytes of base: 31548082
Total bytes of diff: 31547910
Total bytes of delta: -172 (-0.001% of base)
    diff is an improvement.

Top file improvements (bytes):
        -128 : System.Private.CoreLib.dasm (-0.004% of base)
         -44 : System.Net.Http.dasm (-0.008% of base)

2 total files with Code Size differences (2 improved, 0 regressed), 267 unchanged.

Top method regressions (bytes):
           2 (0.056% of base) : System.Private.CoreLib.dasm - DateTimeFormatInfo:CreateTokenHashTable():ref:this

Top method improvements (bytes):
        -130 (-7.545% of base) : System.Private.CoreLib.dasm - DateTimeParse:ParseFormatO(ReadOnlySpan`1,byref):bool
         -20 (-9.756% of base) : System.Net.Http.dasm - HPackEncoder:EncodeLiteralHeaderFieldWithoutIndexingNewName(String,ReadOnlySpan`1,String,Encoding,Span`1,byref):bool
         -12 (-7.643% of base) : System.Net.Http.dasm - HPackEncoder:EncodeLiteralHeaderFieldWithoutIndexing(int,String,Span`1,byref):bool
         -12 (-9.917% of base) : System.Net.Http.dasm - HPackEncoder:EncodeLiteralHeaderFieldWithoutIndexingNewName(String,Span`1,byref):bool

Top method regressions (percentages):
           2 (0.056% of base) : System.Private.CoreLib.dasm - DateTimeFormatInfo:CreateTokenHashTable():ref:this

Top method improvements (percentages):
         -12 (-9.917% of base) : System.Net.Http.dasm - HPackEncoder:EncodeLiteralHeaderFieldWithoutIndexingNewName(String,Span`1,byref):bool
         -20 (-9.756% of base) : System.Net.Http.dasm - HPackEncoder:EncodeLiteralHeaderFieldWithoutIndexingNewName(String,ReadOnlySpan`1,String,Encoding,Span`1,byref):bool
         -12 (-7.643% of base) : System.Net.Http.dasm - HPackEncoder:EncodeLiteralHeaderFieldWithoutIndexing(int,String,Span`1,byref):bool
        -130 (-7.545% of base) : System.Private.CoreLib.dasm - DateTimeParse:ParseFormatO(ReadOnlySpan`1,byref):bool

Also, I noticed that we're still lacking test coverage for when the bounds check removal is on the next edge. I can add that tuesday.

@JulieLeeMSFT JulieLeeMSFT removed blocked Issue/PR is blocked on something - see comments needs author feedback labels Feb 9, 2021
Copy link
Contributor

@sandreenko sandreenko left a comment

Choose a reason for hiding this comment

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

LGTM, thanks @nathan-moore . I like this version that is much simpler than the previous one.

@sandreenko
Copy link
Contributor

It makes everything very simple and is true, but we're also changing how the relop is represented.

Not sure I understand, could you please explain?

@sandreenko
Copy link
Contributor

/azp run runtime-coreclr jitstress

@azure-pipelines
Copy link

Azure Pipelines successfully started running 1 pipeline(s).

@nathan-moore
Copy link
Contributor Author

It makes everything very simple and is true, but we're also changing how the relop is represented.

Not sure I understand, could you please explain?

It's not a big deal. I just have a feeling that someone is going to see <= suddenly get treated as < and get confused.

@sandreenko sandreenko merged commit 6d38a7f into dotnet:master Feb 10, 2021
@ghost ghost locked as resolved and limited conversation to collaborators Mar 12, 2021
Sign up for free to subscribe to this conversation on GitHub. Already have an account? Sign in.
Labels
area-CodeGen-coreclr CLR JIT compiler in src/coreclr/src/jit and related components such as SuperPMI
Projects
Archived in project
Development

Successfully merging this pull request may close these issues.

JIT doesn't eliminate bounds checks sometimes
7 participants