[llvm] [LoopIdiomRecognize] Enable clmul optimization for CRC loops (PR #203405)
Sean Clarke via llvm-commits
llvm-commits at lists.llvm.org
Fri Jun 12 08:04:10 PDT 2026
================
@@ -376,6 +376,48 @@ CRCTable HashRecognize::genSarwateTable(const APInt &GenPoly,
return Table;
}
+// Divide one GF(2) polynomial by another.
+static APInt calculateGF2Quotient(APInt Dividend, const APInt &Divisor) {
+ unsigned DivisorDeg = Divisor.getActiveBits() - 1;
+ APInt Quotient = APInt::getZero(Dividend.getBitWidth());
+ unsigned DividendDeg;
+ while (!Dividend.isZero() &&
+ (DividendDeg = Dividend.getActiveBits() - 1) >= DivisorDeg) {
+ unsigned Shift = DividendDeg - DivisorDeg;
+ Quotient.setBit(Shift);
+ Dividend ^= Divisor.shl(Shift);
+ }
+ return Quotient;
+}
+
+// Generate constants (mu/reciprocal, P/generator) for a Barrett-style
+// reduction. This reduction allows the Sarwate table entry to be computed on
+// the fly, rather than requiring a load from memory (on supporting hardware).
+CRCBarrettConstants HashRecognize::genBarrettConstants(const APInt &GenPoly,
+ bool ByteOrderSwapped) {
+ unsigned BW = GenPoly.getBitWidth();
+ unsigned ClmulBW = BW * 2;
+ unsigned DivBW = ClmulBW + 1;
+ APInt Dividend = APInt::getSignedMinValue(DivBW);
+ CRCBarrettConstants C;
+
+ if (ByteOrderSwapped) {
+ APInt G = GenPoly.zext(DivBW);
+ G.setBit(BW);
+ APInt Mu = calculateGF2Quotient(Dividend, G);
+ C.Reciprocal = Mu.trunc(ClmulBW);
+ C.Generator = G.trunc(ClmulBW);
+ return C;
+ }
+
+ APInt G = GenPoly.reverseBits().zext(DivBW);
+ G.setBit(BW);
+ APInt Mu = calculateGF2Quotient(Dividend, G);
+ C.Reciprocal = Mu.trunc(BW + 1).reverseBits().zext(ClmulBW).getLoBits(8);
----------------
xarkenz wrote:
The idea was that the clmul by `Reciprocal` gets immediately masked by 0xFF in the LE path (`%quot.le.mask`), so only the low 8 bits of the clmul inputs will actually affect the masked result. It should be equivalent to just skip the `getLoBits(8)`, though.
https://github.com/llvm/llvm-project/pull/203405
More information about the llvm-commits
mailing list