Remove redundant ulong casts in Span.Slice for x64 targets#123635
Remove redundant ulong casts in Span.Slice for x64 targets#123635reedz wants to merge 2 commits intodotnet:mainfrom
Conversation
There was a problem hiding this comment.
Pull request overview
This PR removes platform-specific bounds checking workarounds for 64-bit targets in Span, Memory, and related types. The change simplifies the code by using a uniform bounds check pattern across all platforms, enabling better JIT optimization and eliminating unnecessary bounds checks in common slicing patterns.
Changes:
- Replaced complex 64-bit-specific bounds checks with simpler, JIT-friendly two-condition checks that work uniformly across all platforms
- Updated comment in ValueListBuilder.cs to reflect that the guard condition is now universal rather than 64-bit specific
- Removed all TARGET_64BIT conditional compilation directives related to bounds checking from Span, Memory, String, and related types
Reviewed changes
Copilot reviewed 8 out of 8 changed files in this pull request and generated no comments.
Show a summary per file
| File | Description |
|---|---|
| src/libraries/System.Private.CoreLib/src/System/Span.cs | Removed TARGET_64BIT conditional for Slice bounds checking in both constructor and Slice method |
| src/libraries/System.Private.CoreLib/src/System/ReadOnlySpan.cs | Removed TARGET_64BIT conditional for Slice bounds checking in both constructor and Slice method |
| src/libraries/System.Private.CoreLib/src/System/Memory.cs | Removed TARGET_64BIT conditional for Slice bounds checking in constructor, Slice method, and Span property getter |
| src/libraries/System.Private.CoreLib/src/System/ReadOnlyMemory.cs | Removed TARGET_64BIT conditional for Slice bounds checking in constructor, Slice method, and Span property getter |
| src/libraries/System.Private.CoreLib/src/System/String.cs | Removed TARGET_64BIT conditional from TryGetSpan method |
| src/libraries/System.Private.CoreLib/src/System/String.Manipulation.cs | Removed TARGET_64BIT conditional from Substring method |
| src/libraries/System.Private.CoreLib/src/System/MemoryExtensions.cs | Removed TARGET_64BIT conditionals from AsSpan and AsMemory extension methods |
| src/libraries/System.Private.CoreLib/src/System/Collections/Generic/ValueListBuilder.cs | Updated comment to reflect universal application of guard condition and simplified the bounds check |
| int pos = _pos; | ||
| Span<T> span = _span; | ||
| if ((ulong)(uint)pos + (ulong)(uint)length <= (ulong)(uint)span.Length) // same guard condition as in Span<T>.Slice on 64-bit | ||
| if ((uint)pos <= (uint)span.Length - (uint)length) // same guard condition as in Span<T>.Slice |
There was a problem hiding this comment.
you need the !TARGET_64BIT path from Slice here, this is not the same as before
There was a problem hiding this comment.
Thanks, this has been reverted.
@EgorBo is it possible we're seeing multiple regressions because of this change ? Would you mind re-running MihuBot once more for the fresh changes ? It seems I don't have access, and I'm not sure how I can run the same suite locally.
|
Some of my recent JIT changes were preparing for this actually, but I am not yet sure it won't regress today. the 64bit path messes with JIT's range check analysis which is built mostly around 32-bit integers (because of Array/Span Length being so), but at the same time it's just one condition+branch. The latter produces two jumps and JIT is not smart enough to merge it into one when it can (after opts). |
|
I think it's not ready for merge yet, needs more work in JIT |
Fixes #120607.
Related: #67044 , #119689
Remove 64-bit workarounds (ulong casts for 64-bit arithmetic) to produce JIT-friendly code that eliminates unnecessary bounds checks for Span slices. Presumably, this has become possible thanks to earlier work done in #62864,
Code from the issue:
Before changes:
After changes