[clang] de20437 - [clang] Refactor CRC32 helper for x86 CRC builtins (#225774)

via cfe-commits cfe-commits at lists.llvm.org
Sat Oct 3 02:01:00 PDT 2026


Author: Shreesh Adiga
Date: 2026-10-03T09:00:52Z
New Revision: de20437cafa5d4e05b1e71008ef2b7c0a955d7c9

URL: https://github.com/llvm/llvm-project/commit/de20437cafa5d4e05b1e71008ef2b7c0a955d7c9
DIFF: https://github.com/llvm/llvm-project/commit/de20437cafa5d4e05b1e71008ef2b7c0a955d7c9.diff

LOG: [clang] Refactor CRC32 helper for x86 CRC builtins (#225774)

Move the reflected CRC32 calculation used by the x86 CRC builtins into
llvm::calculateReflectedCRC32() and reuse it from both the AST
interpreter and constant expression evaluator.

This removes duplicated CRC32 implementation logic from Clang. This is
planned to be used for implementing const folding CRC instructions for
x86 and AArch64 in the future in LLVM.

Based on suggestion in
https://github.com/llvm/llvm-project/pull/219452#discussion_r4070846498

Added: 
    

Modified: 
    clang/lib/AST/ByteCode/InterpBuiltin.cpp
    clang/lib/AST/ExprConstant.cpp
    llvm/include/llvm/Support/CRC.h

Removed: 
    


################################################################################
diff  --git a/clang/lib/AST/ByteCode/InterpBuiltin.cpp b/clang/lib/AST/ByteCode/InterpBuiltin.cpp
index c88f767ade4b6..5589ae141f66f 100644
--- a/clang/lib/AST/ByteCode/InterpBuiltin.cpp
+++ b/clang/lib/AST/ByteCode/InterpBuiltin.cpp
@@ -22,6 +22,7 @@
 #include "clang/Basic/TargetInfo.h"
 #include "llvm/ADT/StringExtras.h"
 #include "llvm/Support/AllocToken.h"
+#include "llvm/Support/CRC.h"
 #include "llvm/Support/ErrorHandling.h"
 #include "llvm/Support/MathExtras.h"
 #include "llvm/Support/SipHash.h"
@@ -821,15 +822,8 @@ static bool interp__builtin_ia32_crc32(InterpState &S, CodePtr OpPC,
   // CRC32C polynomial (iSCSI polynomial, bit-reversed)
   static const uint32_t CRC32C_POLY = 0x82F63B78;
 
-  // Process each byte
-  uint32_t Result = static_cast<uint32_t>(CRCVal);
-  for (unsigned I = 0; I != DataBytes; ++I) {
-    uint8_t Byte = static_cast<uint8_t>((DataVal >> (I * 8)) & 0xFF);
-    Result ^= Byte;
-    for (int J = 0; J != 8; ++J) {
-      Result = (Result >> 1) ^ ((Result & 1) ? CRC32C_POLY : 0);
-    }
-  }
+  uint32_t Result = llvm::calculateReflectedCRC32(
+      static_cast<uint32_t>(CRCVal), DataVal, DataBytes, CRC32C_POLY);
 
   pushInteger(S, Result, Call->getType());
   return true;

diff  --git a/clang/lib/AST/ExprConstant.cpp b/clang/lib/AST/ExprConstant.cpp
index 3f295f35d1361..68c5e275dd48f 100644
--- a/clang/lib/AST/ExprConstant.cpp
+++ b/clang/lib/AST/ExprConstant.cpp
@@ -62,6 +62,7 @@
 #include "llvm/ADT/Sequence.h"
 #include "llvm/ADT/SmallBitVector.h"
 #include "llvm/ADT/StringExtras.h"
+#include "llvm/Support/CRC.h"
 #include "llvm/Support/Casting.h"
 #include "llvm/Support/Debug.h"
 #include "llvm/Support/MathExtras.h"
@@ -17044,15 +17045,8 @@ bool IntExprEvaluator::VisitBuiltinCallExpr(const CallExpr *E,
     // CRC32C polynomial (iSCSI polynomial, bit-reversed)
     static const uint32_t CRC32C_POLY = 0x82F63B78;
 
-    // Process each byte
-    uint32_t Result = static_cast<uint32_t>(CRCVal);
-    for (unsigned I = 0; I != DataBytes; ++I) {
-      uint8_t Byte = static_cast<uint8_t>((DataVal >> (I * 8)) & 0xFF);
-      Result ^= Byte;
-      for (int J = 0; J != 8; ++J) {
-        Result = (Result >> 1) ^ ((Result & 1) ? CRC32C_POLY : 0);
-      }
-    }
+    uint32_t Result = llvm::calculateReflectedCRC32(
+        static_cast<uint32_t>(CRCVal), DataVal, DataBytes, CRC32C_POLY);
 
     return Success(Result, E);
   };

diff  --git a/llvm/include/llvm/Support/CRC.h b/llvm/include/llvm/Support/CRC.h
index a07b017d23519..39c03e2e69c03 100644
--- a/llvm/include/llvm/Support/CRC.h
+++ b/llvm/include/llvm/Support/CRC.h
@@ -26,6 +26,26 @@ LLVM_ABI uint32_t crc32(ArrayRef<uint8_t> Data);
 // checksum.
 LLVM_ABI uint32_t crc32(uint32_t CRC, ArrayRef<uint8_t> Data);
 
+// Calculate bit-reflected CRC for given initial CRC, Data and Polynomial.
+// It processes the lower DataBytes of Data from LSB onwards.
+// DataBytes must be 1/2/4/8.
+// Poly must already be in the bit-reflected form.
+constexpr inline uint32_t calculateReflectedCRC32(uint32_t Crc, uint64_t Data,
+                                                  unsigned DataBytes,
+                                                  uint32_t Poly) {
+  uint32_t Result = Crc;
+  // Process each byte
+  for (unsigned I = 0; I != DataBytes; ++I) {
+    uint8_t Byte = static_cast<uint8_t>((Data >> (I * 8)) & 0xFF);
+    Result ^= Byte;
+    for (int J = 0; J != 8; ++J) {
+      Result = (Result >> 1) ^ ((Result & 1) ? Poly : 0);
+    }
+  }
+
+  return Result;
+}
+
 // Class for computing the JamCRC.
 //
 // We will use the "Rocksoft^tm Model CRC Algorithm" to describe the properties


        


More information about the cfe-commits mailing list