[clang] [llvm] [clang] Refactor CRC32 helper for x86 CRC builtins (PR #225774)

Shreesh Adiga via llvm-commits llvm-commits at lists.llvm.org
Wed Sep 23 06:49:32 PDT 2026


https://github.com/tantei3 created https://github.com/llvm/llvm-project/pull/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

>From f342bdd16cf316e5868fcd5afe9720daf39f905e Mon Sep 17 00:00:00 2001
From: Shreesh Adiga <16567adigashreesh at gmail.com>
Date: Wed, 23 Sep 2026 19:14:53 +0530
Subject: [PATCH] [clang] Refactor CRC32 helper for x86 CRC builtins

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.
---
 clang/lib/AST/ByteCode/InterpBuiltin.cpp | 12 +++---------
 clang/lib/AST/ExprConstant.cpp           | 12 +++---------
 llvm/include/llvm/Support/CRC.h          | 20 ++++++++++++++++++++
 3 files changed, 26 insertions(+), 18 deletions(-)

diff --git a/clang/lib/AST/ByteCode/InterpBuiltin.cpp b/clang/lib/AST/ByteCode/InterpBuiltin.cpp
index 843850af334a2b..58e407f154e8dc 100644
--- a/clang/lib/AST/ByteCode/InterpBuiltin.cpp
+++ b/clang/lib/AST/ByteCode/InterpBuiltin.cpp
@@ -21,6 +21,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/SipHash.h"
 
@@ -819,15 +820,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 bb7721df5a28b1..978f2b2954414a 100644
--- a/clang/lib/AST/ExprConstant.cpp
+++ b/clang/lib/AST/ExprConstant.cpp
@@ -60,6 +60,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/SaveAndRestore.h"
@@ -17010,15 +17011,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 a07b017d235198..39c03e2e69c036 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 llvm-commits mailing list