[llvm] [LoopIdiomRecognize] Enable clmul optimization for CRC loops (PR #203405)

Sean Clarke via llvm-commits llvm-commits at lists.llvm.org
Wed Jul 15 07:08:18 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,
----------------
xarkenz wrote:

Yes, the algorithm doesn't rely on any properties of GenPoly. It could even be zero, and the algorithm would still work. The only requirement is that the bit width of GenPoly matches that of the CRC value, and that is guaranteed by HashRecognize. I've also done some fuzz testing in Python, and it supports this claim.

https://github.com/llvm/llvm-project/pull/203405


More information about the llvm-commits mailing list