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

Sean Clarke via llvm-commits llvm-commits at lists.llvm.org
Fri Jun 26 12:00:30 PDT 2026


================
@@ -1549,7 +1551,128 @@ bool LoopIdiomRecognize::avoidLIRForMultiBlockLoop(bool IsMemset,
   return false;
 }
 
-bool LoopIdiomRecognize::optimizeCRCLoop(const PolynomialInfo &Info) {
+bool LoopIdiomRecognize::optimizeCRCLoopToClmul(const PolynomialInfo &Info) {
+  Type *CRCTy = Info.LHS->getType();
+  LLVMContext &Ctx = CRCTy->getContext();
+  unsigned CRCBW = CRCTy->getIntegerBitWidth();
+  // The TripCount determines how many bits of data are processed, regardless of
+  // whether the actual data bit width matches (if auxiliary data is even used
+  // at all).
+  unsigned EffectiveDataBW = Info.TripCount;
+  // The width used for clmul operations should be a power of 2, and should be
+  // at least CRCBW + DataBW.
+  unsigned ClmulBW = 2 * std::max(CRCBW, EffectiveDataBW);
+  Type *ClmulTy = IntegerType::get(Ctx, ClmulBW);
+
+  // For big-endian CRC loops where the auxiliary data is XORed with the CRC
+  // inside the loop, the bits won't be aligned properly if the bit widths don't
+  // match, and thus the CRC computation is incorrect, but HashRecognize will
+  // still detect the loop. Since this optimization always produces a correct
+  // CRC computation, bail in this edge case.
----------------
xarkenz wrote:

I figured out how to get rid of this bailout and replace it with additional logic so that this specific case is transformed properly. As for the asymmetry, I think it stems from an underlying asymmetry in the HashRecognize detection, specifically where it allows both sides of the XOR between CRC and data to be `CastOrSelf`, regardless of ByteOrderSwapped.

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


More information about the llvm-commits mailing list