On Tue, Oct 13, 2026 at 10:27 AM Shreesh Adiga
<[email protected]> wrote:
>
>
>
> On Mon, Oct 12, 2026 at 2:06 PM Uros Bizjak <[email protected]> wrote:
>>
>> On Wed, Oct 7, 2026 at 6:32 PM Shreesh Adiga
>> <[email protected]> wrote:
>> >
>> >
>> >
>> > On Tue, Sep 15, 2026 at 10:03 PM Uros Bizjak <[email protected]> wrote:
>> >>
>> >> On Tue, Sep 15, 2026 at 3:54 PM Shreesh Adiga
>> >> <[email protected]> wrote:
>> >> >
>> >> > Add const folding for x86 _mm_crc32_u8/u16/u32/u64 intrinsics.
>> >> > Added tests to ensure the values are computed as expected.
>> >> >
>> >> > gcc/ChangeLog:
>> >> >
>> >> >         * config/i386/i386.cc (ix86_fold_builtin): Add constant folding
>> >> >         for the SSE4.2 crc32 intrinsics (_mm_crc32_u8/u16/u32/u64) by
>> >> >         invoking calculate_reversed_crc with the CRC32C polynomial.
>> >> >         * hwint.cc (calculate_reversed_crc): Relax the crc_bits >=
>> >> >         data_bits assertion; the shift-register loop still resolves the
>> >> >         low crc_bits correctly before the upper data_bits reach bit 0,
>> >> >         so this allows folding _mm_crc32_u64 where crc_bits == 32 and
>> >> >         data_bits == 64.
>> >> >
>> >> > gcc/testsuite/ChangeLog:
>> >> >
>> >> >         * gcc.target/i386/crc32-const-fold.c: New test.
>> >>
>> >> Please follow GNU ChangeLog standards, like:
>> >>
>> >> gcc/ChangeLog:
>> >>
>> >>         * config/i386/i386.cc (ix86_fold_builtin) <IX86_BUILTIN_CRC32QI,
>> >>         IX86_BUILTIN_CRC32HI, IX86_BUILTIN_CRC32SI, IX86_BUILTIN_CRC32DI>:
>> >>         Add constant folding for the SSE4.2 crc32 intrinsics.
>> >>         * hwint.cc (calculate_reversed_crc): Remove the crc_bits >=
>> >>         data_bits assertion.
>> >>
>> >> gcc/testsuite/ChangeLog:
>> >>
>> >>         * gcc.target/i386/crc32-const-fold.c: New test.
>> >>
>> >> ChangeLog entry should say *what* is changed, not *why* it is changed.
>> >> The explanation itself should go in the commit message.
>> >>
>> >> OK for the x86 part, the hwint.cc needs a middle-end maintainer's review.
>> >>
>> >
>> > Hi Andrea, can you help with this hwint.cc changes review part?
>>
>> A quick chat with AI returned the following solution:
>>
>> You can avoid touching hwint.cc. crc32q (c, d) == crc32l (crc32l (c, d
>> & 0xffffffff), d >> 32), so ix86_fold_builtin can call
>> calculate_reversed_crc twice with crc_bits == data_bits == 32. That
>> keeps the assertion for the other callers (the middle-end CRC code)
>> and removes the need for the middle-end change.
>>
>
> Sure it might work but I'd not want to do extra work making more changes
> in x86 and aarch64 :(
> I'm rather surprised to see this series is still not merged given that LLVM 
> merged
> my PRs for this exact optimization of const folding crc32 intrinsics for X86,
> aarch64 and ARM along with few refactoring changes all within a span of 2 
> weeks.
> I'm also working on folding "_mm_crc32_u32(x, x) -> 0" for LLVM currently.

Note I have not responded until now since the GNU cauldron was the
first weekend in October and I am still recovering from the trip.
So partly this got caught during the conference.  Sorry about that.
I am still trying to understand the assert and why it is there to make
sure it can be safely removed.  I had wished someone like Jeff would
review it since he worked on this code the most. Anyways I should have
a good understanding of the code later today and make a good review on
it.

Thanks,
Andrea


>
> Anyways I am not in a hurry :) so hopefully this can be merged eventually.
>
> Thanks,
> Shreesh
>
>>
>> Uros.
>>
>> >
>> > Thanks,
>> > Shreesh
>> >
>> >>
>> >> Thanks,
>> >> Uros.
>> >>
>> >> > Signed-off-by: Shreesh Adiga <[email protected]>
>> >> > ---
>> >> >  gcc/config/i386/i386.cc                       |  18 ++
>> >> >  gcc/hwint.cc                                  |   2 +-
>> >> >  .../gcc.target/i386/crc32-const-fold.c        | 154 ++++++++++++++++++
>> >> >  3 files changed, 173 insertions(+), 1 deletion(-)
>> >> >  create mode 100644 gcc/testsuite/gcc.target/i386/crc32-const-fold.c
>> >> >
>> >> > diff --git a/gcc/config/i386/i386.cc b/gcc/config/i386/i386.cc
>> >> > index bbb60163a75..79970003cf1 100644
>> >> > --- a/gcc/config/i386/i386.cc
>> >> > +++ b/gcc/config/i386/i386.cc
>> >> > @@ -19246,6 +19246,24 @@ ix86_fold_builtin (tree fndecl, int n_args,
>> >> >             }
>> >> >           break;
>> >> >
>> >> > +       case IX86_BUILTIN_CRC32QI:
>> >> > +       case IX86_BUILTIN_CRC32HI:
>> >> > +       case IX86_BUILTIN_CRC32SI:
>> >> > +       case IX86_BUILTIN_CRC32DI:
>> >> > +         gcc_assert (n_args == 2);
>> >> > +         if (tree_fits_uhwi_p (args[0]) && tree_fits_uhwi_p (args[1]))
>> >> > +         {
>> >> > +           unsigned HOST_WIDE_INT crc = tree_to_uhwi (args[0]);
>> >> > +           crc &= 0xffffffff;
>> >> > +           unsigned HOST_WIDE_INT data = tree_to_uhwi (args[1]);
>> >> > +           unsigned short data_bits = TYPE_PRECISION (TREE_TYPE 
>> >> > (args[1]));
>> >> > +           unsigned HOST_WIDE_INT res = calculate_reversed_crc (crc, 
>> >> > data,
>> >> > +                                                                
>> >> > 0x1EDC6F41,
>> >> > +                                                                32, 
>> >> > data_bits);
>> >> > +           return build_int_cstu (TREE_TYPE (TREE_TYPE (fndecl)), res);
>> >> > +         }
>> >> > +         break;
>> >> > +
>> >> >         case IX86_BUILTIN_BEXTR32:
>> >> >         case IX86_BUILTIN_BEXTR64:
>> >> >         case IX86_BUILTIN_BEXTRI32:
>> >> > diff --git a/gcc/hwint.cc b/gcc/hwint.cc
>> >> > index 065911d0a77..d89be33f636 100644
>> >> > --- a/gcc/hwint.cc
>> >> > +++ b/gcc/hwint.cc
>> >> > @@ -265,7 +265,7 @@ calculate_reversed_crc (unsigned HOST_WIDE_INT crc,
>> >> >
>> >> >    gcc_checking_assert (crc_bits <= 64);
>> >> >    gcc_checking_assert (data_bits <= 64);
>> >> > -  gcc_checking_assert (crc_bits >= data_bits);
>> >> > +  /* allow data_bits > crc_bits for folding _mm_crc32_u64.  */
>> >> >
>> >> >    unsigned HOST_WIDE_INT rev_polynom = reflect_hwi (polynomial, 
>> >> > crc_bits);
>> >> >    crc ^= data;
>> >> > diff --git a/gcc/testsuite/gcc.target/i386/crc32-const-fold.c 
>> >> > b/gcc/testsuite/gcc.target/i386/crc32-const-fold.c
>> >> > new file mode 100644
>> >> > index 00000000000..92825c4fc1d
>> >> > --- /dev/null
>> >> > +++ b/gcc/testsuite/gcc.target/i386/crc32-const-fold.c
>> >> > @@ -0,0 +1,154 @@
>> >> > +/* { dg-do compile } */
>> >> > +/* { dg-options "-O2 -mcrc32" } */
>> >> > +
>> >> > +#include <immintrin.h>
>> >> > +
>> >> > +unsigned int
>> >> > +test_u8_1 ()
>> >> > +{
>> >> > +  return _mm_crc32_u8 (0x02a24bf8, 0xba);
>> >> > +}
>> >> > +
>> >> > +unsigned int
>> >> > +test_u8_2 ()
>> >> > +{
>> >> > +  return _mm_crc32_u8 (0x0cd5e10f, 0xe7);
>> >> > +}
>> >> > +
>> >> > +unsigned int
>> >> > +test_u8_3 ()
>> >> > +{
>> >> > +  return _mm_crc32_u8 (0x50e739b8, 0x2e);
>> >> > +}
>> >> > +
>> >> > +unsigned int
>> >> > +test_u8_4 ()
>> >> > +{
>> >> > +  return _mm_crc32_u8 (0x3c2db116, 0x3d);
>> >> > +}
>> >> > +
>> >> > +unsigned int
>> >> > +test_u8_5 ()
>> >> > +{
>> >> > +  return _mm_crc32_u8 (-1, -1);
>> >> > +}
>> >> > +
>> >> > +unsigned int
>> >> > +test_u16_1 ()
>> >> > +{
>> >> > +  return _mm_crc32_u16 (0x02a24bf8, 0xd4ba);
>> >> > +}
>> >> > +
>> >> > +unsigned int
>> >> > +test_u16_2 ()
>> >> > +{
>> >> > +  return _mm_crc32_u16 (0x0cd5e10f, 0x42e7);
>> >> > +}
>> >> > +
>> >> > +unsigned int
>> >> > +test_u16_3 ()
>> >> > +{
>> >> > +  return _mm_crc32_u16 (0x50e739b8, 0x382e);
>> >> > +}
>> >> > +
>> >> > +unsigned int
>> >> > +test_u16_4 ()
>> >> > +{
>> >> > +  return _mm_crc32_u16 (0x3c2db116, 0x7f3d);
>> >> > +}
>> >> > +
>> >> > +unsigned int
>> >> > +test_u16_5 ()
>> >> > +{
>> >> > +  return _mm_crc32_u16 (-1, -1);
>> >> > +}
>> >> > +
>> >> > +unsigned int
>> >> > +test_u32_1 ()
>> >> > +{
>> >> > +  return _mm_crc32_u32 (0x02a24bf8, 0xf37dd4ba);
>> >> > +}
>> >> > +
>> >> > +unsigned int
>> >> > +test_u32_2 ()
>> >> > +{
>> >> > +  return _mm_crc32_u32 (0x0cd5e10f, 0x832b42e7);
>> >> > +}
>> >> > +
>> >> > +unsigned int
>> >> > +test_u32_3 ()
>> >> > +{
>> >> > +  return _mm_crc32_u32 (0x50e739b8, 0xcefb382e);
>> >> > +}
>> >> > +
>> >> > +unsigned int
>> >> > +test_u32_4 ()
>> >> > +{
>> >> > +  return _mm_crc32_u32 (0x3c2db116, 0xd3947f3d);
>> >> > +}
>> >> > +
>> >> > +unsigned int
>> >> > +test_u32_5 ()
>> >> > +{
>> >> > +  return _mm_crc32_u32 (-1, -1);
>> >> > +}
>> >> > +
>> >> > +#ifdef __x86_64__
>> >> > +unsigned long long
>> >> > +test_u64_1 ()
>> >> > +{
>> >> > +  return _mm_crc32_u64 (0x9f65239602a24bf8, 0x894a58bff37dd4ba);
>> >> > +}
>> >> > +
>> >> > +unsigned long long
>> >> > +test_u64_2 ()
>> >> > +{
>> >> > +  return _mm_crc32_u64 (0x06ef97970cd5e10f, 0x24334e2e832b42e7);
>> >> > +}
>> >> > +
>> >> > +unsigned long long
>> >> > +test_u64_3 ()
>> >> > +{
>> >> > +  return _mm_crc32_u64 (0x5024a45450e739b8, 0x289ee1b7cefb382e);
>> >> > +}
>> >> > +
>> >> > +unsigned long long
>> >> > +test_u64_4 ()
>> >> > +{
>> >> > +  return _mm_crc32_u64 (0xcbc89e1c3c2db116, 0xa89143dad3947f3d);
>> >> > +}
>> >> > +
>> >> > +unsigned long long
>> >> > +test_u64_5 ()
>> >> > +{
>> >> > +  return _mm_crc32_u64 (-1, -1);
>> >> > +}
>> >> > +#endif
>> >> > +
>> >> > +/* Test that there is no crc32 instruction emitted.  */
>> >> > +/* { dg-final { scan-assembler-not "crc32\[bwlq\]" } } */
>> >> > +
>> >> > +/* Test the expected values.  */
>> >> > +/* { dg-final { scan-assembler-times "-1606234368," 1 } } */
>> >> > +/* { dg-final { scan-assembler-times "1776624948," 1 } } */
>> >> > +/* { dg-final { scan-assembler-times "-1269171002," 1 } } */
>> >> > +/* { dg-final { scan-assembler-times "-1190655916," 1 } } */
>> >> > +/* { dg-final { scan-assembler-times "16777215," 1 } } */
>> >> > +
>> >> > +/* { dg-final { scan-assembler-times "350827643," 1 } } */
>> >> > +/* { dg-final { scan-assembler-times "1464882880," 1 } } */
>> >> > +/* { dg-final { scan-assembler-times "1604487598," 1 } } */
>> >> > +/* { dg-final { scan-assembler-times "-1181930003," 1 } } */
>> >> > +/* { dg-final { scan-assembler-times "65535," 1 } } */
>> >> > +
>> >> > +/* { dg-final { scan-assembler-times "2122844148," 1 } } */
>> >> > +/* { dg-final { scan-assembler-times "881727033," 1 } } */
>> >> > +/* { dg-final { scan-assembler-times "139192539," 1 } } */
>> >> > +/* { dg-final { scan-assembler-times "1861871255," 1 } } */
>> >> > +/* { dg-final { scan-assembler-times "xorl\[\\t \]+%eax, %eax" 1 } } */
>> >> > +
>> >> > +/* { dg-final { scan-assembler-times "3230864714" 1 { target { ! ia32 
>> >> > } } } } */
>> >> > +/* { dg-final { scan-assembler-times "337502055" 1 { target { ! ia32 } 
>> >> > } } } */
>> >> > +/* { dg-final { scan-assembler-times "712052683" 1 { target { ! ia32 } 
>> >> > } } } */
>> >> > +/* { dg-final { scan-assembler-times "1390230251" 1 { target { ! ia32 
>> >> > } } } } */
>> >> > +/* { dg-final { scan-assembler-times "3080238136" 1 { target { ! ia32 
>> >> > } } } } */
>> >> > --
>> >> > 2.55.0
>> >> >

Reply via email to