[gcc r17-3815] [PATCH v5 1/2] middle-end: extend crc functions and make them publicly available

Jeff Law law@gcc.gnu.org
Tue Sep 1 13:56:23 GMT 2026


https://gcc.gnu.org/g:12392ed4c25f9daf0617d106e7d85113128e6cc9

commit r17-3815-g12392ed4c25f9daf0617d106e7d85113128e6cc9
Author: Shreesh Adiga <16567adigashreesh@gmail.com>
Date:   Tue Sep 1 07:54:15 2026 -0600

    [PATCH v5 1/2] middle-end: extend crc functions and make them publicly available
    
    The calculate_crc and calculate_reversed_crc functions assumed initial
    crc of 0 and only operated on 8 bits of data. This commit extends those
    functions to take explicit data arg and data size as well, so that it
    can compute CRC for >8 bits with a separate initial CRC.
    These functions are also made public so that they can be called from
    different modules. This will be used in the future to implement CRC
    const folding.
    
    gcc/ChangeLog:
    
            * expr.cc (calculate_crc): Moved to hwint.cc file.
            (assemble_crc_table): Updated function call.
            (calculate_reversed_crc): Moved to hwint.cc file.
            (assemble_reversed_crc_table): Updated function call.
            * hwint.cc (calculate_crc): Moved from expr.cc and made public.
            (calculate_reversed_crc): Moved from expr.cc and made public.
            * hwint.h (calculate_crc): Added function prototype.
            (calculate_reversed_crc): Added function prototype.
    
    Signed-off-by: Shreesh Adiga <16567adigashreesh@gmail.com>

Diff:
---
 gcc/expr.cc  | 50 +++--------------------------------------------
 gcc/hwint.cc | 64 ++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++
 gcc/hwint.h  | 13 ++++++++++++
 3 files changed, 80 insertions(+), 47 deletions(-)

diff --git a/gcc/expr.cc b/gcc/expr.cc
index 0a7013e3a255..3d99be8472f8 100644
--- a/gcc/expr.cc
+++ b/gcc/expr.cc
@@ -14581,29 +14581,6 @@ gf2n_poly_long_div_quotient (unsigned HOST_WIDE_INT polynomial,
   return quotient;
 }
 
-/* Calculate CRC for the initial CRC and given POLYNOMIAL.
-   CRC_BITS is CRC size.  */
-
-static unsigned HOST_WIDE_INT
-calculate_crc (unsigned HOST_WIDE_INT crc,
-	       unsigned HOST_WIDE_INT polynomial,
-	       unsigned short crc_bits)
-{
-  unsigned HOST_WIDE_INT msb = HOST_WIDE_INT_1U << (crc_bits - 1);
-  crc = crc << (crc_bits - 8);
-  for (short i = 8; i > 0; --i)
-    {
-      if (crc & msb)
-	crc = (crc << 1) ^ polynomial;
-      else
-	crc <<= 1;
-    }
-  /* Zero out bits in crc beyond the specified number of crc_bits.  */
-  if (crc_bits < sizeof (crc) * CHAR_BIT)
-    crc &= (HOST_WIDE_INT_1U << crc_bits) - 1;
-  return crc;
-}
-
 /* Assemble CRC table with 256 elements for the given POLYNOM and CRC_BITS.
    POLYNOM is the polynomial used to calculate the CRC table's elements.
    CRC_BITS is the size of CRC, may be 8, 16, ... . */
@@ -14620,7 +14597,7 @@ assemble_crc_table (unsigned HOST_WIDE_INT polynom, unsigned short crc_bits)
   vec_alloc (initial_values, table_el_n);
   for (size_t i = 0; i < table_el_n; ++i)
     {
-      unsigned HOST_WIDE_INT crc = calculate_crc (i, polynom, crc_bits);
+      unsigned HOST_WIDE_INT crc = calculate_crc (0, i, polynom, crc_bits, 8);
       tree element = build_int_cstu (make_unsigned_type (crc_bits), crc);
       vec_safe_push (initial_values, element);
     }
@@ -14654,28 +14631,6 @@ generate_crc_table (unsigned HOST_WIDE_INT polynom, unsigned short crc_bits)
   return assemble_crc_table (polynom, crc_bits);
 }
 
-/* Calculate CRC for the initial CRC and given POLYNOMIAL.
-   CRC_BITS is CRC size.  */
-
-static unsigned HOST_WIDE_INT
-calculate_reversed_crc (unsigned HOST_WIDE_INT crc,
-			unsigned HOST_WIDE_INT polynomial,
-			unsigned short crc_bits)
-{
-  unsigned HOST_WIDE_INT rev_polynom = reflect_hwi (polynomial, crc_bits);
-  for (int j = 0; j < 8; j++)
-    {
-      if (crc & 1)
-	crc = (crc >> 1) ^ rev_polynom;
-      else
-	crc >>= 1;
-    }
-  /* Zero out bits in crc beyond the specified number of crc_bits.  */
-  if (crc_bits < sizeof (crc) * CHAR_BIT)
-    crc &= (HOST_WIDE_INT_1U << crc_bits) - 1;
-  return crc;
-}
-
 /* Assemble CRC table with 256 elements for the given POLYNOM and CRC_BITS.
    POLYNOM is the polynomial used to calculate the CRC table's elements.
    CRC_BITS is the size of CRC, may be 8, 16, ... . */
@@ -14692,7 +14647,8 @@ assemble_reversed_crc_table (unsigned HOST_WIDE_INT polynom, unsigned short crc_
   vec_alloc (initial_values, table_el_n);
   for (size_t i = 0; i < table_el_n; ++i)
     {
-      unsigned HOST_WIDE_INT crc = calculate_reversed_crc (i, polynom, crc_bits);
+      unsigned HOST_WIDE_INT crc = calculate_reversed_crc (0, i, polynom,
+							   crc_bits, 8);
       tree element = build_int_cstu (make_unsigned_type (crc_bits), crc);
       vec_safe_push (initial_values, element);
     }
diff --git a/gcc/hwint.cc b/gcc/hwint.cc
index da7bc05f0859..065911d0a774 100644
--- a/gcc/hwint.cc
+++ b/gcc/hwint.cc
@@ -217,3 +217,67 @@ reflect_hwi (unsigned HOST_WIDE_INT value, unsigned bitwidth)
   return reflected_value;
 #endif
 }
+
+/* Calculate CRC for the initial CRC, DATA and given POLYNOMIAL.
+   CRC_BITS is CRC size and DATA_BITS is the data size.  */
+
+unsigned HOST_WIDE_INT
+calculate_crc (unsigned HOST_WIDE_INT crc,
+	       unsigned HOST_WIDE_INT data,
+	       unsigned HOST_WIDE_INT polynomial,
+	       unsigned short crc_bits,
+	       unsigned short data_bits)
+{
+  if (data_bits == 0)
+    return crc;
+
+  gcc_checking_assert (crc_bits <= 64);
+  gcc_checking_assert (data_bits <= 64);
+  gcc_checking_assert (crc_bits >= data_bits);
+
+  unsigned HOST_WIDE_INT msb = HOST_WIDE_INT_1U << (crc_bits - 1);
+  crc ^= (data << (crc_bits - data_bits));
+  for (short i = data_bits; i > 0; --i)
+    {
+      if (crc & msb)
+	crc = (crc << 1) ^ polynomial;
+      else
+	crc <<= 1;
+    }
+  /* Zero out bits in crc beyond the specified number of crc_bits.  */
+  if (crc_bits < HOST_BITS_PER_WIDE_INT)
+    crc &= (HOST_WIDE_INT_1U << crc_bits) - 1;
+  return crc;
+}
+
+/* Calculate CRC for the initial CRC, DATA and given POLYNOMIAL.
+   CRC_BITS is CRC size and DATA_BITS is the DATA size.  */
+
+unsigned HOST_WIDE_INT
+calculate_reversed_crc (unsigned HOST_WIDE_INT crc,
+			unsigned HOST_WIDE_INT data,
+			unsigned HOST_WIDE_INT polynomial,
+			unsigned short crc_bits,
+			unsigned short data_bits)
+{
+  if (data_bits == 0)
+    return crc;
+
+  gcc_checking_assert (crc_bits <= 64);
+  gcc_checking_assert (data_bits <= 64);
+  gcc_checking_assert (crc_bits >= data_bits);
+
+  unsigned HOST_WIDE_INT rev_polynom = reflect_hwi (polynomial, crc_bits);
+  crc ^= data;
+  for (int j = 0; j < data_bits; j++)
+    {
+      if (crc & 1)
+	crc = (crc >> 1) ^ rev_polynom;
+      else
+	crc >>= 1;
+    }
+  /* Zero out bits in crc beyond the specified number of crc_bits.  */
+  if (crc_bits < HOST_BITS_PER_WIDE_INT)
+    crc &= (HOST_WIDE_INT_1U << crc_bits) - 1;
+  return crc;
+}
diff --git a/gcc/hwint.h b/gcc/hwint.h
index ebb4253e89db..94df889a0e85 100644
--- a/gcc/hwint.h
+++ b/gcc/hwint.h
@@ -286,6 +286,19 @@ extern HOST_WIDE_INT mul_hwi (HOST_WIDE_INT, HOST_WIDE_INT);
 extern HOST_WIDE_INT least_common_multiple (HOST_WIDE_INT, HOST_WIDE_INT);
 extern unsigned HOST_WIDE_INT reflect_hwi (unsigned HOST_WIDE_INT, unsigned);
 
+/* Calculate CRC for a given initial CRC, DATA, POLYNOMIAL,
+   CRC_SIZE in bits and DATA_SIZE in bits.  */
+extern unsigned HOST_WIDE_INT
+calculate_crc (unsigned HOST_WIDE_INT, unsigned HOST_WIDE_INT,
+	       unsigned HOST_WIDE_INT, unsigned short, unsigned short);
+
+/* Calculate reversed CRC for a given initial CRC, DATA, POLYNOMIAL,
+   CRC_SIZE in bits and DATA_SIZE in bits.  */
+extern unsigned HOST_WIDE_INT
+calculate_reversed_crc (unsigned HOST_WIDE_INT, unsigned HOST_WIDE_INT,
+			unsigned HOST_WIDE_INT, unsigned short,
+			unsigned short);
+
 /* Like ctz_hwi, except 0 when x == 0.  */
 
 inline int


More information about the Gcc-cvs mailing list