Skip to content

Vectorize custom polynomial CRC-32/-64#124577

Draft
Copilot wants to merge 2 commits intomainfrom
copilot/vectorize-custom-polynomial-crc
Draft

Vectorize custom polynomial CRC-32/-64#124577
Copilot wants to merge 2 commits intomainfrom
copilot/vectorize-custom-polynomial-crc

Conversation

Copy link
Contributor

Copilot AI commented Feb 18, 2026

  • Explore codebase and understand existing architecture
  • Run baseline build (./build.sh clr+libs -rc release)
  • Create CrcPolynomialHelper.cs with UInt640 struct and folding constant computation
  • Create Crc32ParameterSet.Vectorized.cs with vectorized CRC-32 for custom forward and reflected polynomials
  • Create Crc64ParameterSet.Vectorized.cs with vectorized CRC-64 for custom forward and reflected polynomials
  • Modify Crc32ParameterSet.Table.cs to add vectorized dispatch in Update()
  • Modify Crc64ParameterSet.Table.cs to add vectorized dispatch in Update()
  • Update System.IO.Hashing.csproj to include new files
  • Build and run existing tests to verify correctness
  • Run code review and CodeQL checks
  • Leave existing specialized implementations (Crc32.Vectorized.cs, Crc64.Vectorized.cs) untouched
Original prompt

This section details on the original issue you should resolve

<issue_title>Vectorize custom polynomial CRC-32/-64</issue_title>
<issue_description>Extracting #124117 (comment) to a new issue:

For poly64: 0x104C11DB7 I match Intel's answers for forward constants with

private static ulong ComputeFoldingConstant(ulong poly, int power)
{
    UInt640 value = new(1);
    value.ShiftLeftEquals(power);
    int polyDeg = 32;

    while (value.Degree >= polyDeg)
    {
        int shift = value.Degree - polyDeg;
        UInt640 polyShifted = new(poly);
        polyShifted.ShiftLeftEquals(shift);
        value.XorEquals(ref polyShifted);
    }

    return value.ToUInt64();
}

Along with private struct UInt640, powered by private InlineArray10<ulong> _data;

But I guess I'm not mathy enough to figure it out for reflected polynomials (I can't come up with the k1Prime value)

My thoughts were to base-class ForwardTable and ReflectedTable with Forward and Reverse, capture the Update call there, do vector-if-appropriate-and-able, then call virtual UpdateScalar (just taking over from the current Update) for the fallback/remainder.

At least, my understanding of the paper is that the forward code and reflected/reverse code are different... so that was my plan. I'm not married to it, though.

// Crc32ParameterSet.cs
    public partial class Crc32ParameterSet
    {
        private abstract partial class ForwardCrc32
        {
            private readonly bool _canVectorize;

            partial void ComputeConstants(ref bool canVectorize);
            partial void UpdateVectorized(ref uint crc, ReadOnlySpan<byte> source, ref int bytesConsumed);
            
            internal ForwardCrc32(...) : base(...)
            {
                ComputeConstants(ref _canVectorize);
            }

            internal abstract uint UpdateScalar(uint crc, ReadOnlySpan<byte> source);

            internal sealed override uint Update(uint crc, ReadOnlySpan<byte> source)
            {
                if (_canVectorize)
                {
                    int consumed = 0;
                    UpdateVectorized(ref crc, source, ref consumed);

                    if (consumed == source.Length)
                    {
                        return crc;
                    }

                    source = source.Slice(consumed);
                }
                
                return UpdateScalar(source);
            }
        }
    }
// Crc32ParameterSet.Vectorized.cs
#if NET
namespace System.IO.Hashing
{
    public partial class Crc32ParameterSet
    {
        private abstract partial class ForwardCrc32
        {
            private uint _k1; // etc

            partial void ComputeConstants(ref bool canVectorize)
            {
                if (...)
                {
                    canVectorize = true;
                    _k1 = ComputeFoldingConstant(Polynomial, 4 * 128 + 64);
                    // ...
                }
            }

            partial void UpdateVectorized(uint crc, ReadOnlySpan<byte> source, ref int bytesConsumed)
            {
                if (source.IsLongEnoughToBeWorthwhile)
                {
                    // Code goes here?
                }
            }
        }
    }
}
#endif
```</issue_description>

<agent_instructions>Add generalized vectorization code for CRC-32 and CRC-64.  Leave the existing specialized code for CRC-32/Ethernet and CRC-64/ECMA-182 alone.  Stick to the design as outlined in the description.  All tests must pass, avoid a dependency on BigInteger.</agent_instructions>

## Comments on the Issue (you are @copilot in this section)

<comments>
</comments>

✨ Let Copilot coding agent set things up for you — coding agent works faster and does higher quality work when set up for your repo.

@github-actions github-actions bot added the area-CodeGen-coreclr CLR JIT compiler in src/coreclr/src/jit and related components such as SuperPMI label Feb 19, 2026
Copilot AI changed the title [WIP] Vectorize custom polynomial CRC-32/-64 Vectorize custom polynomial CRC-32/-64 Feb 19, 2026
Copilot AI requested a review from bartonjs February 19, 2026 00:52
@bartonjs
Copy link
Member

@copilot The plan looks sound, you should act on it.

@bartonjs bartonjs added area-System.IO.Hashing and removed area-CodeGen-coreclr CLR JIT compiler in src/coreclr/src/jit and related components such as SuperPMI labels Feb 19, 2026
@dotnet-policy-service
Copy link
Contributor

Tagging subscribers to this area: @dotnet/area-system-io-hashing, @bartonjs, @vcsjones
See info in area-owners.md if you want to be subscribed.

Co-authored-by: bartonjs <10642668+bartonjs@users.noreply.github.com>
@bartonjs
Copy link
Member

@copilot Please resume your tasks.

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.

Vectorize custom polynomial CRC-32/-64

3 participants

Comments