[llvm] [LoopIdiomRecognize] Enable clmul optimization for CRC loops (PR #203405)
Piotr Fusik via llvm-commits
llvm-commits at lists.llvm.org
Wed Jul 15 05:02:59 PDT 2026
================
@@ -376,6 +376,72 @@ CRCTable HashRecognize::genSarwateTable(const APInt &GenPoly,
return Table;
}
+// Perform polynomial (GF(2)) floor division. This is based on the
+// floor_division(S, P) algorithm in
+// https://www.corsix.org/content/barrett-reduction-polynomials. Note that the
+// maximum degree of the returned polynomial is
+// max(0, deg(Dividend) - deg(Divisor)), but the bit width will be the same as
+// that of Dividend.
+static APInt floorDivideGF2(APInt Dividend, APInt Divisor) {
+ assert(!Divisor.isZero() && "Cannot divide by zero");
+
+ // Extend the divisor bit width to match the dividend.
+ Divisor = Divisor.zext(Dividend.getBitWidth());
+
+ // Note that getActiveBits returns deg+1, but the computation below
+ // still holds.
+ unsigned DivisorActiveBits = Divisor.getActiveBits();
+
+ // Q = 0
+ APInt Quotient = APInt::getZero(Dividend.getBitWidth());
+ // S != 0 and deg(S) >= deg(P)
+ // (S != 0 implied by DivisorActiveBits > 0)
+ while (Dividend.getActiveBits() >= DivisorActiveBits) {
+ // T = S[deg(S)] / P[deg(P)]
+ unsigned Shift = Dividend.getActiveBits() - DivisorActiveBits;
+ // Q = Q + T
+ Quotient.setBit(Shift);
+ // S = S - T * P
+ Dividend ^= Divisor.shl(Shift);
+ }
+ return Quotient;
+}
+
+// Generate the constants for performing a Polynomial (GF(2)) Barrett Reduction
+// according to Intel's Fast CRC Computation white paper with some adjustments
+// to account for the fact that bit width and trip count can vary.
+std::pair<APInt, APInt> HashRecognize::genBarrettConstants(const APInt &GenPoly,
----------------
pfusik wrote:
Is this well-defined for all possible `GenPoly`s, even ones that don't form a valid CRC?
https://github.com/llvm/llvm-project/pull/203405
More information about the llvm-commits
mailing list