Skip to content

Use safe spans in ReverseEndianness#127411

Closed
EgorBo wants to merge 1 commit intodotnet:mainfrom
EgorBo:safe-span-reverse-endianness
Closed

Use safe spans in ReverseEndianness#127411
EgorBo wants to merge 1 commit intodotnet:mainfrom
EgorBo:safe-span-reverse-endianness

Conversation

@EgorBo
Copy link
Copy Markdown
Member

@EgorBo EgorBo commented Apr 24, 2026

Note

This PR description was generated by GitHub Copilot.

Summary

  • Rewrite the generic vectorized ReverseEndianness span helper to use safe span slicing with Vector*.Create and CopyTo
  • Preserve forward/backward processing for overlapping source and destination spans
  • Remove ref arithmetic / LoadUnsafe / StoreUnsafe usage from this helper

Validation

  • build.cmd clr.corelib+clr.nativecorelib+libs.pretest -rc checked
  • dotnet.cmd build /t:test src\libraries\System.Memory\tests\System.Memory.Tests.csproj -p:XUnitClassName=System.Buffers.Binary.Tests.ReverseEndiannessUnitTests -v:minimal (368 tests, 0 failed)

Rewrite the vectorized span helper to use Span slices with Vector*.Create and CopyTo while preserving overlap direction handling.

Co-authored-by: Copilot <223556219+Copilot@users.noreply.github.com>
Copilot AI review requested due to automatic review settings April 24, 2026 22:21
@EgorBo EgorBo closed this Apr 24, 2026
@dotnet-policy-service
Copy link
Copy Markdown
Contributor

Tagging subscribers to this area: @dotnet/area-system-memory
See info in area-owners.md if you want to be subscribed.

Copy link
Copy Markdown
Contributor

Copilot AI left a comment

Choose a reason for hiding this comment

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

Pull request overview

This PR updates the span-based BinaryPrimitives.ReverseEndianness implementation in System.Private.CoreLib to use span slicing plus Vector*.Create(ReadOnlySpan<T>) and CopyTo(Span<T>) for the vectorized path, avoiding explicit ref arithmetic and LoadUnsafe/StoreUnsafe usage while still handling overlapping source/destination spans safely.

Changes:

  • Rewrote the generic vectorized ReverseEndianness<T, TReverser> helper to process via safe span slicing (forward/backward depending on overlap).
  • Updated overlap-direction checks to rely on Span.Overlaps(..., out elementOffset) with elementOffset <= 0 for forward iteration.
  • Applied the same overlap-direction simplification to the Int128 overload.

Comment on lines 304 to 321
if (Vector256.IsHardwareAccelerated)
{
while (i <= source.Length - Vector256<T>.Count)
while (source.Length >= Vector256<T>.Count)
{
Vector256.StoreUnsafe(TReverser.Reverse(Vector256.LoadUnsafe(ref sourceRef, (uint)i)), ref destRef, (uint)i);
i += Vector256<T>.Count;
TReverser.Reverse(Vector256.Create(source)).CopyTo(target);
source = source.Slice(Vector256<T>.Count);
target = target.Slice(Vector256<T>.Count);
}
}

if (Vector128.IsHardwareAccelerated)
{
while (i <= source.Length - Vector128<T>.Count)
while (source.Length >= Vector128<T>.Count)
{
Vector128.StoreUnsafe(TReverser.Reverse(Vector128.LoadUnsafe(ref sourceRef, (uint)i)), ref destRef, (uint)i);
i += Vector128<T>.Count;
TReverser.Reverse(Vector128.Create(source)).CopyTo(target);
source = source.Slice(Vector128<T>.Count);
target = target.Slice(Vector128<T>.Count);
}
Copy link

Copilot AI Apr 24, 2026

Choose a reason for hiding this comment

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

The Vector256/Vector128 fast paths call Vector*.Create(ReadOnlySpan<T>) and CopyTo(Span<T>), and both APIs perform a destination/source length check internally. Since the surrounding loop already guards source.Length >= Vector*.Count, this can introduce redundant per-iteration checks (unless the JIT reliably inlines and eliminates them), which may regress performance compared to the prior LoadUnsafe/StoreUnsafe approach. Consider switching to a load/store strategy that avoids additional range checks (e.g., read/write unaligned via span references) while keeping the overlap-safe slicing logic.

Copilot uses AI. Check for mistakes.
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Projects

None yet

Development

Successfully merging this pull request may close these issues.

2 participants