On Wed, Oct 21, 2026 at 12:21 PM Shreesh Adiga
<[email protected]> wrote:
>
> This patch extends pclmul expanders for the i386 backend to
> generate optimized code for CRC64 computations.
>
> This is an extension to the 16-bit and 32-bit data CRC computation added
> earlier. The algorithm is slightly different which is described in the
> paper "Fast CRC Computation for Generic Polynomials Using PCLMULQDQ
> Instruction" described in the section
> "Barrett Reduction Algorithm for a degree-64 polynomial modulus
> (polynomials defined over GF(2))" Page 17 and 18.
>
> Bit-reverse CRC also is based on the above, except that the bit 65 after
> performing bit-reflect of polynomial maybe 0 and thus the xor operation
> needs to be conditionally performed only when LSB=1.
>
> The quotient computation which needs 65 bits now returns the lower 64
> bits and the 65th bit is assumed to be 1 since the polynomials are
> expected to have the leading bit to be 1. Thus the assert is modified to
> allow the 64 bit cases as well.
>
> Added tests for covering 8-bit, 16-bit, 32-bit and 64-bit for both
> forward and reverse CRC64, along with reverse CRC64 testing for
> polynomials with LSB=0 and LSB=1 as well that gets passed into the CRC
> expander.
>
> gcc/ChangeLog:
>
>         * config/i386/i386-expand.cc (ix86_expand_crc_using_pclmul):
>         Modified to allow 64-bit CRC.
>         (ix86_expand_reversed_crc_using_pclmul): Likewise.
>         * config/i386/i386.md (crc<SWI248x:mode><SWI24:mode>4): Renamed
>         the second iterator to allow 64-bit CRC.
>         (crc<SWI1248x:mode><SWI248x:mode>4): Likewise.
>         (crc_rev<SWI1248x:mode><SWI24:mode>4): Likewise.
>         (crc_rev<SWI1248x:mode><SWI248x:mode>4): Likewise.
>         * expr.cc (gf2n_poly_long_div_quotient): Relaxed assert to allow
>         computing lower 64-bit of quotient for 64-bit CRC.
>
> gcc/testsuite/ChangeLog:
>
>         * gcc.dg/torture/crc-34.c: New test.
>         * gcc.dg/torture/crc-35.c: New test.
>         * gcc.dg/torture/crc-36.c: New test.
>         * gcc.dg/torture/crc-37.c: New test.
>         * gcc.dg/torture/crc-38.c: New test.
>         * gcc.dg/torture/crc-39.c: New test.
>         * gcc.dg/torture/crc-40.c: New test.
>         * gcc.dg/torture/crc-41.c: New test.
>         * gcc.target/i386/crc-34-pclmul.c: New test.
>         * gcc.target/i386/crc-35-pclmul.c: New test.
>         * gcc.target/i386/crc-36-pclmul.c: New test.
>         * gcc.target/i386/crc-37-pclmul.c: New test.
>         * gcc.target/i386/crc-38-pclmul.c: New test.
>         * gcc.target/i386/crc-39-pclmul.c: New test.
>         * gcc.target/i386/crc-40-pclmul.c: New test.
>         * gcc.target/i386/crc-41-pclmul.c: New test.

OK.

Reviewed-by: Uros Bizjak <[email protected]>

expr.cc change was approved by Jeff in [1].

Pushed.

[1] https://gcc.gnu.org/pipermail/gcc-patches/2026-October/735613.html

Thanks,
Uros.

>
> Signed-off-by: Shreesh Adiga <[email protected]>
> ---
> Changes in v4:
>   Removed extra braces for single line statements.
>   Removed extra gen_lowpart for V2DImode.
>   Updated CRC64_POLY2 in test to be consistent.
>   Renamed temp variable to crc_temp as per review request.
>
> Changes in v3:
>   Incorporated review suggestions around untangling the clmul expander
>   to have less duplications.
>   Made the tests run for 256 iterations and renamed expand8 as well.
>   Clarified commit message comment around LSB for bit-reverse.
>
> Changes in v2:
>   extended the existing routines instead of adding new expanders.
>   changed the iterators in md file to be able to support 64-bit CRC.
>
>  gcc/config/i386/i386-expand.cc                | 119 +++++++++++++-----
>  gcc/config/i386/i386.md                       |  38 +++---
>  gcc/expr.cc                                   |   6 +-
>  gcc/testsuite/gcc.dg/torture/crc-34.c         |  56 +++++++++
>  gcc/testsuite/gcc.dg/torture/crc-35.c         |  56 +++++++++
>  gcc/testsuite/gcc.dg/torture/crc-36.c         |  65 ++++++++++
>  gcc/testsuite/gcc.dg/torture/crc-37.c         |  65 ++++++++++
>  gcc/testsuite/gcc.dg/torture/crc-38.c         |  89 +++++++++++++
>  gcc/testsuite/gcc.dg/torture/crc-39.c         |  89 +++++++++++++
>  gcc/testsuite/gcc.dg/torture/crc-40.c         |  98 +++++++++++++++
>  gcc/testsuite/gcc.dg/torture/crc-41.c         |  98 +++++++++++++++
>  gcc/testsuite/gcc.target/i386/crc-34-pclmul.c |   9 ++
>  gcc/testsuite/gcc.target/i386/crc-35-pclmul.c |   8 ++
>  gcc/testsuite/gcc.target/i386/crc-36-pclmul.c |   8 ++
>  gcc/testsuite/gcc.target/i386/crc-37-pclmul.c |   8 ++
>  gcc/testsuite/gcc.target/i386/crc-38-pclmul.c |   9 ++
>  gcc/testsuite/gcc.target/i386/crc-39-pclmul.c |   8 ++
>  gcc/testsuite/gcc.target/i386/crc-40-pclmul.c |   8 ++
>  gcc/testsuite/gcc.target/i386/crc-41-pclmul.c |   8 ++
>  19 files changed, 792 insertions(+), 53 deletions(-)
>  create mode 100644 gcc/testsuite/gcc.dg/torture/crc-34.c
>  create mode 100644 gcc/testsuite/gcc.dg/torture/crc-35.c
>  create mode 100644 gcc/testsuite/gcc.dg/torture/crc-36.c
>  create mode 100644 gcc/testsuite/gcc.dg/torture/crc-37.c
>  create mode 100644 gcc/testsuite/gcc.dg/torture/crc-38.c
>  create mode 100644 gcc/testsuite/gcc.dg/torture/crc-39.c
>  create mode 100644 gcc/testsuite/gcc.dg/torture/crc-40.c
>  create mode 100644 gcc/testsuite/gcc.dg/torture/crc-41.c
>  create mode 100644 gcc/testsuite/gcc.target/i386/crc-34-pclmul.c
>  create mode 100644 gcc/testsuite/gcc.target/i386/crc-35-pclmul.c
>  create mode 100644 gcc/testsuite/gcc.target/i386/crc-36-pclmul.c
>  create mode 100644 gcc/testsuite/gcc.target/i386/crc-37-pclmul.c
>  create mode 100644 gcc/testsuite/gcc.target/i386/crc-38-pclmul.c
>  create mode 100644 gcc/testsuite/gcc.target/i386/crc-39-pclmul.c
>  create mode 100644 gcc/testsuite/gcc.target/i386/crc-40-pclmul.c
>  create mode 100644 gcc/testsuite/gcc.target/i386/crc-41-pclmul.c
>
> diff --git a/gcc/config/i386/i386-expand.cc b/gcc/config/i386/i386-expand.cc
> index c0869abcf49..2b709a9262f 100644
> --- a/gcc/config/i386/i386-expand.cc
> +++ b/gcc/config/i386/i386-expand.cc
> @@ -29936,15 +29936,17 @@ ix86_expand_crc_using_pclmul (scalar_mode crc_mode,
>
>    unsigned HOST_WIDE_INT crc_size = GET_MODE_BITSIZE (crc_mode);
>    unsigned HOST_WIDE_INT data_size = GET_MODE_BITSIZE (data_mode);
> -  gcc_assert (crc_size <= 32);
> +  gcc_assert (crc_size <= 64);
>    gcc_assert (data_size <= crc_size);
>
> +  machine_mode op_mode = crc_size == 64 ? DImode : SImode;
> +
>    /* Calculate the quotient.  */
>    unsigned HOST_WIDE_INT
>        q = gf2n_poly_long_div_quotient (UINTVAL (polynomial), crc_size);
>
>    if (crc_size > data_size)
> -    crc = expand_shift (RSHIFT_EXPR, SImode, crc, crc_size - data_size,
> +    crc = expand_shift (RSHIFT_EXPR, op_mode, crc, crc_size - data_size,
>                         NULL_RTX, 1);
>
>    /* Keep the quotient and polynomial in V2DImode.  */
> @@ -29956,29 +29958,53 @@ ix86_expand_crc_using_pclmul (scalar_mode crc_mode,
>    emit_move_insn (constants_reg, constants_v2di);
>
>    /* crc ^ data and keep in V2DImode.  */
> -  rtx cd_xor = expand_binop (SImode, xor_optab, crc, data, NULL_RTX, 1,
> +  rtx cd_xor = expand_binop (op_mode, xor_optab, crc, data, NULL_RTX, 1,
>                              OPTAB_WIDEN);
> -  rtx res = gen_reg_rtx (V4SImode);
> -  emit_insn (gen_vec_setv4si_0 (res, CONST0_RTX (V4SImode), cd_xor));
> -  res = gen_lowpart (V2DImode, res);
> +  rtx crc_temp;
> +  if (op_mode == DImode)
> +    {
> +      crc_temp = gen_reg_rtx (V2DImode);
> +      emit_insn (gen_vec_concatv2di (crc_temp, cd_xor, cd_xor));
> +    }
> +  else
> +    {
> +      crc_temp = gen_reg_rtx (V4SImode);
> +      emit_insn (gen_vec_setv4si_0 (crc_temp, CONST0_RTX (V4SImode), 
> cd_xor));
> +      crc_temp = gen_lowpart (V2DImode, crc_temp);
> +    }
> +
>    /* Perform carry-less multiplication with quotient.  */
> -  emit_insn (gen_pclmulqdq (res, res, constants_reg, const0_rtx));
> +  rtx res = gen_reg_rtx (V2DImode);
> +  emit_insn (gen_pclmulqdq (res, crc_temp, constants_reg, const0_rtx));
>
> -  res = expand_shift (RSHIFT_EXPR, V2DImode, res, crc_size, NULL_RTX, 1);
> +  if (op_mode == DImode)
> +    {
> +      /* Perform res ^ crc to handle 65th bit of quotient.  */
> +      res = expand_binop (V2DImode, xor_optab, res, crc_temp, NULL_RTX, 1,
> +                         OPTAB_WIDEN);
> +    }
> +  else
> +    res = expand_shift (RSHIFT_EXPR, V2DImode, res, crc_size, NULL_RTX, 1);
>
>    /* Perform carry-less multiplication with polynomial and get low part.  */
>    emit_insn (gen_pclmulqdq (res, res, constants_reg,
> -                           gen_int_mode (0x10, SImode)));
> -  rtx crc_part = gen_reg_rtx (SImode);
> -  res = gen_lowpart (V4SImode, res);
> -  emit_insn (gen_vec_extractv4sisi (crc_part, res, const0_rtx));
> +                           GEN_INT (op_mode == DImode ? 0x11 : 0x10)));
> +
> +  rtx crc_part = gen_reg_rtx (op_mode);
> +  if (op_mode == DImode)
> +    emit_insn (gen_vec_extractv2didi (crc_part, res, const0_rtx));
> +  else
> +    {
> +      res = gen_lowpart (V4SImode, res);
> +      emit_insn (gen_vec_extractv4sisi (crc_part, res, const0_rtx));
> +    }
>
>    if (crc_size > data_size)
>      {
> -      rtx shift = expand_shift (LSHIFT_EXPR, SImode, operands[1], data_size,
> +      rtx shift = expand_shift (LSHIFT_EXPR, op_mode, operands[1], data_size,
>                                 NULL_RTX, 1);
> -      crc_part = expand_binop (SImode, xor_optab, crc_part, shift, NULL_RTX, 
> 1,
> -                              OPTAB_DIRECT);
> +      crc_part = expand_binop (op_mode, xor_optab, crc_part, shift,
> +                              NULL_RTX, 1, OPTAB_DIRECT);
>      }
>    emit_move_insn (operands[0], gen_lowpart (crc_mode, crc_part));
>  }
> @@ -30002,14 +30028,16 @@ ix86_expand_reversed_crc_using_pclmul (scalar_mode 
> crc_mode,
>
>    unsigned HOST_WIDE_INT crc_size = GET_MODE_BITSIZE (crc_mode);
>    unsigned HOST_WIDE_INT data_size = GET_MODE_BITSIZE (data_mode);
> -  gcc_assert (crc_size <= 32);
> +  gcc_assert (crc_size <= 64);
>    gcc_assert (data_size <= crc_size);
>
> +  machine_mode op_mode = crc_size == 64 ? DImode : SImode;
> +
>    /* Calculate the quotient.  */
>    unsigned HOST_WIDE_INT
>        q = gf2n_poly_long_div_quotient (UINTVAL (polynomial), crc_size);
>    /* Reflect the calculated quotient.  */
> -  q = reflect_hwi (q, crc_size + 1);
> +  q = (reflect_hwi (q, crc_size) << 1) + 1;
>
>    unsigned HOST_WIDE_INT reflected_op3 = reflect_hwi (UINTVAL (polynomial),
>                                                       crc_size);
> @@ -30022,30 +30050,55 @@ ix86_expand_reversed_crc_using_pclmul (scalar_mode 
> crc_mode,
>    emit_move_insn (constants_reg, constants_v2di);
>
>    /* crc ^ data and keep in V2DImode.  */
> -  rtx cd_xor = expand_binop (SImode, xor_optab, crc, data, NULL_RTX, 1,
> +  rtx cd_xor = expand_binop (op_mode, xor_optab, crc, data, NULL_RTX, 1,
>                              OPTAB_WIDEN);
>
> -  /* Perform carry-less multiplication with quotient.  */
> -  rtx res = gen_reg_rtx (V4SImode);
> -  emit_insn (gen_vec_setv4si_0 (res, CONST0_RTX (V4SImode), cd_xor));
> -  res = gen_lowpart (V2DImode, res);
> -  emit_insn (gen_pclmulqdq (res, res, constants_reg, const0_rtx));
> +  rtx crc_temp;
> +  if (op_mode == DImode)
> +    {
> +      crc_temp = gen_reg_rtx (V2DImode);
> +      emit_insn (gen_vec_concatv2di (crc_temp, cd_xor, const0_rtx));
> +    }
> +  else
> +    {
> +      crc_temp = gen_reg_rtx (V4SImode);
> +      emit_insn (gen_vec_setv4si_0 (crc_temp, CONST0_RTX (V4SImode), 
> cd_xor));
> +      crc_temp = gen_lowpart (V2DImode, crc_temp);
> +    }
>
> -  res = expand_shift (LSHIFT_EXPR, V2DImode, res, 64 - data_size, NULL_RTX, 
> 0);
> +  /* Perform carry-less multiplication with quotient.  */
> +  emit_insn (gen_pclmulqdq (crc_temp, crc_temp, constants_reg, const0_rtx));
> +  if (data_size < 64)
> +    crc_temp = expand_shift (LSHIFT_EXPR, V2DImode, crc_temp, 64 - data_size,
> +                            NULL_RTX, 0);
> +
> +  rtx res = gen_reg_rtx (V2DImode);
> +  /* Perform carry-less multiplication with polynomial.  */
> +  emit_insn (gen_pclmulqdq (res, crc_temp, constants_reg, GEN_INT (0x10)));
> +  if (op_mode == DImode && (UINTVAL (polynomial) & 1))
> +    {
> +      /* Perform xor of res[127:64] with temp[63:0].
> +        This is needed when the 65th bit of reflected polynomial is 1.  */
> +      emit_insn (gen_vec_interleave_lowv2di (crc_temp, crc_temp, crc_temp));
> +      res = expand_binop (V2DImode, xor_optab, res, crc_temp, NULL_RTX, 1,
> +                         OPTAB_WIDEN);
> +    }
>
> -  /* Perform carry-less multiplication with polynomial and get high part.  */
> -  emit_insn (gen_pclmulqdq (res, res, constants_reg,
> -                           gen_int_mode (0x10, SImode)));
> -  rtx res_high = gen_reg_rtx (SImode);
> -  res = gen_lowpart (V4SImode, res);
> -  emit_insn (gen_vec_extractv4sisi (res_high, res, const2_rtx));
> +  rtx res_high = gen_reg_rtx (op_mode);
> +  if (op_mode == DImode)
> +    emit_insn (gen_vec_extractv2didi (res_high, res, const1_rtx));
> +  else
> +    {
> +      res = gen_lowpart (V4SImode, res);
> +      emit_insn (gen_vec_extractv4sisi (res_high, res, const2_rtx));
> +    }
>
>    if (crc_size > data_size)
>      {
> -      rtx shift = expand_shift (RSHIFT_EXPR, SImode, crc, data_size,
> +      rtx shift = expand_shift (RSHIFT_EXPR, op_mode, crc, data_size,
>                                 NULL_RTX, 1);
> -      res_high = expand_binop (SImode, xor_optab, res_high, shift, NULL_RTX, 
> 1,
> -                              OPTAB_DIRECT);
> +      res_high = expand_binop (op_mode, xor_optab, res_high, shift,
> +                              NULL_RTX, 1, OPTAB_DIRECT);
>      }
>    emit_move_insn (operands[0], gen_lowpart (crc_mode, res_high));
>  }
> diff --git a/gcc/config/i386/i386.md b/gcc/config/i386/i386.md
> index fbd227ac40a..89745e9a810 100644
> --- a/gcc/config/i386/i386.md
> +++ b/gcc/config/i386/i386.md
> @@ -30505,37 +30505,39 @@ (define_insn "sse4_2_crc32di"
>     (set_attr "mode" "DI")])
>
>  ;; Bit-forward CRC
> -(define_expand "crc<SWI248x:mode><SWI24:mode>4"
> -  [(match_operand:SWI24   0 "register_operand")     ;; return value (CRC)
> -   (match_operand:SWI24   1 "register_operand")     ;; initial CRC
> -   (match_operand:SWI248x 2 "nonimmediate_operand") ;; data
> -   (match_operand:SWI24   3 "const_int_operand")]   ;; polynomial
> -  "TARGET_PCLMUL && <SWI24:MODE>mode >= <SWI248x:MODE>mode"
> -{
> -   ix86_expand_crc_using_pclmul (<SWI24:MODE>mode, <SWI248x:MODE>mode,
> +(define_expand "crc<SWI1248x:mode><SWI248x:mode>4"
> +  [(match_operand:SWI248x  0 "register_operand")     ;; return value (CRC)
> +   (match_operand:SWI248x  1 "register_operand")     ;; initial CRC
> +   (match_operand:SWI1248x 2 "nonimmediate_operand") ;; data
> +   (match_operand:SWI248x  3 "const_int_operand")]   ;; polynomial
> +  "TARGET_PCLMUL && <SWI248x:MODE>mode >= <SWI1248x:MODE>mode
> +   && <SWI1248x:MODE>mode != QImode"
> +{
> +   /* Generate pclmul expansion for 16-bit, 32-bit and 64-bit data.  */
> +   ix86_expand_crc_using_pclmul (<SWI248x:MODE>mode, <SWI1248x:MODE>mode,
>                                  operands);
>     DONE;
>  })
>
>  ;; Reversed CRC
> -(define_expand "crc_rev<SWI1248x:mode><SWI24:mode>4"
> -  [(match_operand:SWI24    0 "register_operand")      ;; return value (CRC)
> -   (match_operand:SWI24    1 "register_operand")      ;; initial CRC
> +(define_expand "crc_rev<SWI1248x:mode><SWI248x:mode>4"
> +  [(match_operand:SWI248x  0 "register_operand")      ;; return value (CRC)
> +   (match_operand:SWI248x  1 "register_operand")      ;; initial CRC
>     (match_operand:SWI1248x 2 "nonimmediate_operand")  ;; data
> -   (match_operand:SWI24    3 "const_int_operand")]    ;; polynomial
> -  "(TARGET_PCLMUL && <SWI24:MODE>mode >= <SWI1248x:MODE>mode
> +   (match_operand:SWI248x  3 "const_int_operand")]    ;; polynomial
> +  "(TARGET_PCLMUL && <SWI248x:MODE>mode >= <SWI1248x:MODE>mode
>        && <SWI1248x:MODE>mode != QImode)
> -    || (TARGET_CRC32 && <SWI24:MODE>mode == SImode)"
> +    || (TARGET_CRC32 && <SWI248x:MODE>mode == SImode)"
>    {
>      /* If it is iSCSI polynomial (0x1EDC6F41), generate crc32 instruction.  
> */
>      if (TARGET_CRC32 && INTVAL (operands[3]) == 0x1EDC6F41
> -       && <SWI24:MODE>mode == SImode)
> +       && <SWI248x:MODE>mode == SImode)
>        emit_insn (gen_sse4_2_crc32<SWI1248x:mode> (operands[0], operands[1],
>                                                   operands[2]));
> -    /* Generate pclmul expansion for 16-bit and 32-bit data.  */
> -    else if (TARGET_PCLMUL && <SWI24:MODE>mode >= <SWI1248x:MODE>mode
> +    /* Generate pclmul expansion for 16-bit, 32-bit and 64-bit data.  */
> +    else if (TARGET_PCLMUL && <SWI248x:MODE>mode >= <SWI1248x:MODE>mode
>         && <SWI1248x:MODE>mode != QImode)
> -      ix86_expand_reversed_crc_using_pclmul (<SWI24:MODE>mode,
> +      ix86_expand_reversed_crc_using_pclmul (<SWI248x:MODE>mode,
>                                              <SWI1248x:MODE>mode, operands);
>      else
>        expand_reversed_crc_table_based (operands[0], operands[1], operands[2],
> diff --git a/gcc/expr.cc b/gcc/expr.cc
> index 3d99be8472f..6c98277aaaa 100644
> --- a/gcc/expr.cc
> +++ b/gcc/expr.cc
> @@ -14562,8 +14562,10 @@ unsigned HOST_WIDE_INT
>  gf2n_poly_long_div_quotient (unsigned HOST_WIDE_INT polynomial,
>                              unsigned short n)
>  {
> -  /* The result has degree N, so needs N + 1 bits.  */
> -  gcc_assert (n < 64);
> +  /* The result has degree N, so needs N + 1 bits.
> +     For 64-bit CRC, compute the lower 64 bits of the division.
> +     The 65th bit is 1 since the leading bit of polynomial is 1.  */
> +  gcc_assert (n <= 64);
>
>    /* Perform a division step for the x^2N coefficient.  At this point the
>       quotient and remainder have N implicit trailing zeros.  */
> diff --git a/gcc/testsuite/gcc.dg/torture/crc-34.c 
> b/gcc/testsuite/gcc.dg/torture/crc-34.c
> new file mode 100644
> index 00000000000..d25fcc51620
> --- /dev/null
> +++ b/gcc/testsuite/gcc.dg/torture/crc-34.c
> @@ -0,0 +1,56 @@
> +/* { dg-do run { target lp64 } } */
> +/* { dg-options "-fdump-tree-crc-details -w" } */
> +/* { dg-skip-if "" { *-*-* } { "-O0" "-O1" "-g" "-Os" "-flto" } } */
> +
> +#include <stdint.h>
> +#include <stdlib.h>
> +
> +// CRC64_ECMA_182
> +#define CRC64_POLY 0x42F0E1EBA9EA3693
> +
> +// Test bit-forward CRC64 8-bit data
> +__attribute__ ((noinline,optimize(0)))
> +uint64_t _crc64_O0 (uint8_t data, uint64_t crc) {
> +  int i;
> +  for (i = 0; i < 8; i++) {
> +      if (((crc & 0x8000000000000000) >> 56 ^ (data & 0x80)))
> +       crc = (crc << 1) ^ CRC64_POLY;
> +      else
> +       crc = (crc << 1);
> +      data <<= 1;
> +    }
> +  return crc;
> +}
> +
> +uint64_t _crc64 (uint8_t data, uint64_t crc) {
> +  int i;
> +  for (i = 0; i < 8; i++) {
> +      if (((crc & 0x8000000000000000) >> 56 ^ (data & 0x80)))
> +       crc = (crc << 1) ^ CRC64_POLY;
> +      else
> +       crc = (crc << 1);
> +      data <<= 1;
> +    }
> +  return crc;
> +}
> +
> +int main ()
> +{
> +  uint64_t crc = 0;
> +
> +  for (uint16_t i = 0; i <= 0xff; i++)
> +    {
> +      uint8_t data = (uint8_t)i;
> +      uint64_t res1 = _crc64_O0 (data, crc);
> +      uint64_t res2 = _crc64 (data, crc);
> +      crc = res2;
> +      if (res1 != res2)
> +       abort ();
> +    }
> +}
> +
> +/* { dg-final { scan-tree-dump "function maybe contains CRC calculation." 
> "crc" } } */
> +/* { dg-final { scan-tree-dump "Loop iteration number is 7" "crc" } } */
> +/* { dg-final { scan-tree-dump "Bit forward" "crc" } } */
> +/* { dg-final { scan-tree-dump "calculates CRC!" "crc" } } */
> +/* { dg-final { scan-tree-dump-times "Couldn't generate faster CRC code." 0 
> "crc" } } */
> diff --git a/gcc/testsuite/gcc.dg/torture/crc-35.c 
> b/gcc/testsuite/gcc.dg/torture/crc-35.c
> new file mode 100644
> index 00000000000..40e7d447395
> --- /dev/null
> +++ b/gcc/testsuite/gcc.dg/torture/crc-35.c
> @@ -0,0 +1,56 @@
> +/* { dg-do run { target lp64 } } */
> +/* { dg-options "-fdump-tree-crc-details -w" } */
> +/* { dg-skip-if "" { *-*-* } { "-O0" "-O1" "-g" "-Os" "-flto" } } */
> +
> +#include <stdint.h>
> +#include <stdlib.h>
> +
> +// CRC64_ECMA_182
> +#define CRC64_POLY 0x42F0E1EBA9EA3693
> +
> +// Test bit-forward CRC64 16-bit data
> +__attribute__ ((noinline,optimize(0)))
> +uint64_t _crc64_O0 (uint16_t data, uint64_t crc) {
> +  int i;
> +  for (i = 0; i < 16; i++) {
> +      if (((crc & 0x8000000000000000) >> 48 ^ (data & 0x8000)))
> +       crc = (crc << 1) ^ CRC64_POLY;
> +      else
> +       crc = (crc << 1);
> +      data <<= 1;
> +    }
> +  return crc;
> +}
> +
> +uint64_t _crc64 (uint16_t data, uint64_t crc) {
> +  int i;
> +  for (i = 0; i < 16; i++) {
> +      if (((crc & 0x8000000000000000) >> 48 ^ (data & 0x8000)))
> +       crc = (crc << 1) ^ CRC64_POLY;
> +      else
> +       crc = (crc << 1);
> +      data <<= 1;
> +    }
> +  return crc;
> +}
> +
> +int main ()
> +{
> +  uint64_t crc = 0;
> +
> +  for (uint16_t i = 0; i <= 0xff; i++)
> +    {
> +      uint16_t data = (i << 8) | (~i); // cover 2-byte range
> +      uint64_t res1 = _crc64_O0 (data, crc);
> +      uint64_t res2 = _crc64 (data, crc);
> +      crc = res2;
> +      if (res1 != res2)
> +       abort ();
> +    }
> +}
> +
> +/* { dg-final { scan-tree-dump "function maybe contains CRC calculation." 
> "crc" } } */
> +/* { dg-final { scan-tree-dump "Loop iteration number is 15" "crc" } } */
> +/* { dg-final { scan-tree-dump "Bit forward" "crc" } } */
> +/* { dg-final { scan-tree-dump "calculates CRC!" "crc" } } */
> +/* { dg-final { scan-tree-dump-times "Couldn't generate faster CRC code." 0 
> "crc" } } */
> diff --git a/gcc/testsuite/gcc.dg/torture/crc-36.c 
> b/gcc/testsuite/gcc.dg/torture/crc-36.c
> new file mode 100644
> index 00000000000..b9b0c3fc7bd
> --- /dev/null
> +++ b/gcc/testsuite/gcc.dg/torture/crc-36.c
> @@ -0,0 +1,65 @@
> +/* { dg-do run { target lp64 } } */
> +/* { dg-options "-fdump-tree-crc-details -w" } */
> +/* { dg-skip-if "" { *-*-* } { "-O0" "-O1" "-g" "-Os" "-flto" } } */
> +
> +#include <stdint.h>
> +#include <stdlib.h>
> +
> +// CRC64_ECMA_182
> +#define CRC64_POLY 0x42F0E1EBA9EA3693
> +
> +uint32_t expand8to32 (uint32_t x) {
> +  x ^= x >> 16;
> +  x *= 0x7feb352dU;
> +  x ^= x >> 15;
> +  x *= 0x846ca68bU;
> +  x ^= x >> 16;
> +  return x;
> +}
> +
> +// Test bit-forward CRC64 32-bit data
> +__attribute__ ((noinline,optimize(0)))
> +uint64_t _crc64_O0 (uint32_t data, uint64_t crc) {
> +  int i;
> +  for (i = 0; i < 32; i++) {
> +      if (((crc & 0x8000000000000000) >> 32 ^ (data & 0x80000000)))
> +       crc = (crc << 1) ^ CRC64_POLY;
> +      else
> +       crc = (crc << 1);
> +      data <<= 1;
> +    }
> +  return crc;
> +}
> +
> +uint64_t _crc64 (uint32_t data, uint64_t crc) {
> +  int i;
> +  for (i = 0; i < 32; i++) {
> +      if (((crc & 0x8000000000000000) >> 32 ^ (data & 0x80000000)))
> +       crc = (crc << 1) ^ CRC64_POLY;
> +      else
> +       crc = (crc << 1);
> +      data <<= 1;
> +    }
> +  return crc;
> +}
> +
> +int main ()
> +{
> +  uint64_t crc = 0;
> +
> +  for (uint32_t i = 0; i <= 0xff; i++)
> +    {
> +      uint32_t data = expand8to32 (i);
> +      uint64_t res1 = _crc64_O0 (data, crc);
> +      uint64_t res2 = _crc64 (data, crc);
> +      crc = res2;
> +      if (res1 != res2)
> +       abort ();
> +    }
> +}
> +
> +/* { dg-final { scan-tree-dump "function maybe contains CRC calculation." 
> "crc" } } */
> +/* { dg-final { scan-tree-dump "Loop iteration number is 31" "crc" } } */
> +/* { dg-final { scan-tree-dump "Bit forward" "crc" } } */
> +/* { dg-final { scan-tree-dump "calculates CRC!" "crc" } } */
> +/* { dg-final { scan-tree-dump-times "Couldn't generate faster CRC code." 0 
> "crc" } } */
> diff --git a/gcc/testsuite/gcc.dg/torture/crc-37.c 
> b/gcc/testsuite/gcc.dg/torture/crc-37.c
> new file mode 100644
> index 00000000000..2445730d449
> --- /dev/null
> +++ b/gcc/testsuite/gcc.dg/torture/crc-37.c
> @@ -0,0 +1,65 @@
> +/* { dg-do run { target lp64 } } */
> +/* { dg-options "-fdump-tree-crc-details -w" } */
> +/* { dg-skip-if "" { *-*-* } { "-O0" "-O1" "-g" "-Os" "-flto" } } */
> +
> +#include <stdint.h>
> +#include <stdlib.h>
> +
> +// CRC64_ECMA_182
> +#define CRC64_POLY 0x42F0E1EBA9EA3693
> +
> +uint64_t expand8to64 (uint64_t x) {
> +  x ^= x >> 30;
> +  x *= UINT64_C(0xbf58476d1ce4e5b9);
> +  x ^= x >> 27;
> +  x *= UINT64_C(0x94d049bb133111eb);
> +  x ^= x >> 31;
> +  return x;
> +}
> +
> +// Test bit-forward CRC64 64-bit data
> +__attribute__ ((noinline,optimize(0)))
> +uint64_t _crc64_O0 (uint64_t data, uint64_t crc) {
> +  int i;
> +  for (i = 0; i < 64; i++) {
> +      if (((crc & 0x8000000000000000)  ^ (data & 0x8000000000000000)))
> +       crc = (crc << 1) ^ CRC64_POLY;
> +      else
> +       crc = (crc << 1);
> +      data <<= 1;
> +    }
> +  return crc;
> +}
> +
> +uint64_t _crc64 (uint64_t data, uint64_t crc) {
> +  int i;
> +  for (i = 0; i < 64; i++) {
> +      if (((crc & 0x8000000000000000)  ^ (data & 0x8000000000000000)))
> +       crc = (crc << 1) ^ CRC64_POLY;
> +      else
> +       crc = (crc << 1);
> +      data <<= 1;
> +    }
> +  return crc;
> +}
> +
> +int main ()
> +{
> +  uint64_t crc = 0;
> +
> +  for (uint64_t i = 0; i <= 0xff; i++)
> +    {
> +      uint64_t data = expand8to64 (i);
> +      uint64_t res1 = _crc64_O0 (data, crc);
> +      uint64_t res2 = _crc64 (data, crc);
> +      crc = res2;
> +      if (res1 != res2)
> +       abort ();
> +    }
> +}
> +
> +/* { dg-final { scan-tree-dump "function maybe contains CRC calculation." 
> "crc" } } */
> +/* { dg-final { scan-tree-dump "Loop iteration number is 63" "crc" } } */
> +/* { dg-final { scan-tree-dump "Bit forward" "crc" } } */
> +/* { dg-final { scan-tree-dump "calculates CRC!" "crc" } } */
> +/* { dg-final { scan-tree-dump-times "Couldn't generate faster CRC code." 0 
> "crc" } } */
> diff --git a/gcc/testsuite/gcc.dg/torture/crc-38.c 
> b/gcc/testsuite/gcc.dg/torture/crc-38.c
> new file mode 100644
> index 00000000000..a37aa492a17
> --- /dev/null
> +++ b/gcc/testsuite/gcc.dg/torture/crc-38.c
> @@ -0,0 +1,89 @@
> +/* { dg-do run { target lp64 } } */
> +/* { dg-options "-fdump-tree-crc-details -w" } */
> +/* { dg-skip-if "" { *-*-* } { "-O0" "-O1" "-g" "-Os" "-flto" } } */
> +
> +#include <stdint.h>
> +#include <stdlib.h>
> +
> +#define CRC64_POLY1 0x9A6C9329AC4BC9B5
> +#define CRC64_POLY2 0x1A6C9329AC4BC9B4
> +
> +// Test bit-reverse CRC64 8-bit data with Poly having LSB=1
> +__attribute__ ((noinline,optimize(0)))
> +uint64_t _crc64_poly1_O0 (uint8_t data, uint64_t crc) {
> +  int i;
> +  for (i = 0; i < 8; i++) {
> +      if (((crc & 0x1) ^ (data & 0x1)))
> +       crc = (crc >> 1) ^ CRC64_POLY1;
> +      else
> +       crc = (crc >> 1);
> +      data >>= 1;
> +    }
> +  return crc;
> +}
> +
> +uint64_t _crc64_poly1 (uint8_t data, uint64_t crc) {
> +  int i;
> +  for (i = 0; i < 8; i++) {
> +      if (((crc & 0x1) ^ (data & 0x1)))
> +       crc = (crc >> 1) ^ CRC64_POLY1;
> +      else
> +       crc = (crc >> 1);
> +      data >>= 1;
> +    }
> +  return crc;
> +}
> +
> +// Test bit-reverse CRC64 8-bit data with Poly having LSB=0
> +__attribute__ ((noinline,optimize(0)))
> +uint64_t _crc64_poly2_O0 (uint8_t data, uint64_t crc) {
> +  int i;
> +  for (i = 0; i < 8; i++) {
> +      if (((crc & 0x1) ^ (data & 0x1)))
> +       crc = (crc >> 1) ^ CRC64_POLY2;
> +      else
> +       crc = (crc >> 1);
> +      data >>= 1;
> +    }
> +  return crc;
> +}
> +
> +uint64_t _crc64_poly2 (uint8_t data, uint64_t crc) {
> +  int i;
> +  for (i = 0; i < 8; i++) {
> +      if (((crc & 0x1) ^ (data & 0x1)))
> +       crc = (crc >> 1) ^ CRC64_POLY2;
> +      else
> +       crc = (crc >> 1);
> +      data >>= 1;
> +    }
> +  return crc;
> +}
> +
> +int main ()
> +{
> +  uint64_t crc1 = 0;
> +  uint64_t crc2 = 0;
> +
> +  for (uint16_t i = 0; i <= 0xff; i++)
> +    {
> +      uint8_t data = (uint8_t)i;
> +      uint64_t res1 = _crc64_poly1_O0 (data, crc1);
> +      uint64_t res2 = _crc64_poly1 (data, crc1);
> +      crc1 = res2;
> +      if (res1 != res2)
> +       abort ();
> +
> +      uint64_t res3 = _crc64_poly2_O0 (data, crc2);
> +      uint64_t res4 = _crc64_poly2 (data, crc2);
> +      crc2 = res4;
> +      if (res3 != res4)
> +       abort ();
> +    }
> +}
> +
> +/* { dg-final { scan-tree-dump "function maybe contains CRC calculation." 
> "crc" } } */
> +/* { dg-final { scan-tree-dump "Loop iteration number is 7" "crc" } } */
> +/* { dg-final { scan-tree-dump "Bit reverse" "crc" } } */
> +/* { dg-final { scan-tree-dump "calculates CRC!" "crc" } } */
> +/* { dg-final { scan-tree-dump-times "Couldn't generate faster CRC code." 0 
> "crc" } } */
> diff --git a/gcc/testsuite/gcc.dg/torture/crc-39.c 
> b/gcc/testsuite/gcc.dg/torture/crc-39.c
> new file mode 100644
> index 00000000000..2bc5894009f
> --- /dev/null
> +++ b/gcc/testsuite/gcc.dg/torture/crc-39.c
> @@ -0,0 +1,89 @@
> +/* { dg-do run { target lp64 } } */
> +/* { dg-options "-fdump-tree-crc-details -w" } */
> +/* { dg-skip-if "" { *-*-* } { "-O0" "-O1" "-g" "-Os" "-flto" } } */
> +
> +#include <stdint.h>
> +#include <stdlib.h>
> +
> +#define CRC64_POLY1 0x9A6C9329AC4BC9B5
> +#define CRC64_POLY2 0x1A6C9329AC4BC9B4
> +
> +// Test bit-reverse CRC64 16-bit data with Poly having LSB=1
> +__attribute__ ((noinline,optimize(0)))
> +uint64_t _crc64_poly1_O0 (uint16_t data, uint64_t crc) {
> +  int i;
> +  for (i = 0; i < 16; i++) {
> +      if (((crc & 0x1) ^ (data & 0x1)))
> +       crc = (crc >> 1) ^ CRC64_POLY1;
> +      else
> +       crc = (crc >> 1);
> +      data >>= 1;
> +    }
> +  return crc;
> +}
> +
> +uint64_t _crc64_poly1 (uint16_t data, uint64_t crc) {
> +  int i;
> +  for (i = 0; i < 16; i++) {
> +      if (((crc & 0x1) ^ (data & 0x1)))
> +       crc = (crc >> 1) ^ CRC64_POLY1;
> +      else
> +       crc = (crc >> 1);
> +      data >>= 1;
> +    }
> +  return crc;
> +}
> +
> +// Test bit-reverse CRC64 16-bit data with Poly having LSB=0
> +__attribute__ ((noinline,optimize(0)))
> +uint64_t _crc64_poly2_O0 (uint16_t data, uint64_t crc) {
> +  int i;
> +  for (i = 0; i < 16; i++) {
> +      if (((crc & 0x1) ^ (data & 0x1)))
> +       crc = (crc >> 1) ^ CRC64_POLY2;
> +      else
> +       crc = (crc >> 1);
> +      data >>= 1;
> +    }
> +  return crc;
> +}
> +
> +uint64_t _crc64_poly2 (uint16_t data, uint64_t crc) {
> +  int i;
> +  for (i = 0; i < 16; i++) {
> +      if (((crc & 0x1) ^ (data & 0x1)))
> +       crc = (crc >> 1) ^ CRC64_POLY2;
> +      else
> +       crc = (crc >> 1);
> +      data >>= 1;
> +    }
> +  return crc;
> +}
> +
> +int main ()
> +{
> +  uint64_t crc1 = 0;
> +  uint64_t crc2 = 0;
> +
> +  for (uint16_t i = 0; i <= 0xff; i++)
> +    {
> +      uint16_t data = (i << 8) | (~i);
> +      uint64_t res1 = _crc64_poly1_O0 (data, crc1);
> +      uint64_t res2 = _crc64_poly1 (data, crc1);
> +      crc1 = res2;
> +      if (res1 != res2)
> +       abort ();
> +
> +      uint64_t res3 = _crc64_poly2_O0 (data, crc2);
> +      uint64_t res4 = _crc64_poly2 (data, crc2);
> +      crc2 = res4;
> +      if (res3 != res4)
> +       abort ();
> +    }
> +}
> +
> +/* { dg-final { scan-tree-dump "function maybe contains CRC calculation." 
> "crc" } } */
> +/* { dg-final { scan-tree-dump "Loop iteration number is 15" "crc" } } */
> +/* { dg-final { scan-tree-dump "Bit reverse" "crc" } } */
> +/* { dg-final { scan-tree-dump "calculates CRC!" "crc" } } */
> +/* { dg-final { scan-tree-dump-times "Couldn't generate faster CRC code." 0 
> "crc" } } */
> diff --git a/gcc/testsuite/gcc.dg/torture/crc-40.c 
> b/gcc/testsuite/gcc.dg/torture/crc-40.c
> new file mode 100644
> index 00000000000..47556c91ab9
> --- /dev/null
> +++ b/gcc/testsuite/gcc.dg/torture/crc-40.c
> @@ -0,0 +1,98 @@
> +/* { dg-do run { target lp64 } } */
> +/* { dg-options "-fdump-tree-crc-details -w" } */
> +/* { dg-skip-if "" { *-*-* } { "-O0" "-O1" "-g" "-Os" "-flto" } } */
> +
> +#include <stdint.h>
> +#include <stdlib.h>
> +
> +#define CRC64_POLY1 0x9A6C9329AC4BC9B5
> +#define CRC64_POLY2 0x1A6C9329AC4BC9B4
> +
> +uint32_t expand8to32 (uint32_t x) {
> +  x ^= x >> 16;
> +  x *= 0x7feb352dU;
> +  x ^= x >> 15;
> +  x *= 0x846ca68bU;
> +  x ^= x >> 16;
> +  return x;
> +}
> +
> +// Test bit-reverse CRC64 32-bit data with Poly having LSB=1
> +__attribute__ ((noinline,optimize(0)))
> +uint64_t _crc64_poly1_O0 (uint32_t data, uint64_t crc) {
> +  int i;
> +  for (i = 0; i < 32; i++) {
> +      if (((crc & 0x1) ^ (data & 0x1)))
> +       crc = (crc >> 1) ^ CRC64_POLY1;
> +      else
> +       crc = (crc >> 1);
> +      data >>= 1;
> +    }
> +  return crc;
> +}
> +
> +uint64_t _crc64_poly1 (uint32_t data, uint64_t crc) {
> +  int i;
> +  for (i = 0; i < 32; i++) {
> +      if (((crc & 0x1) ^ (data & 0x1)))
> +       crc = (crc >> 1) ^ CRC64_POLY1;
> +      else
> +       crc = (crc >> 1);
> +      data >>= 1;
> +    }
> +  return crc;
> +}
> +
> +// Test bit-reverse CRC64 32-bit data with Poly having LSB=0
> +__attribute__ ((noinline,optimize(0)))
> +uint64_t _crc64_poly2_O0 (uint32_t data, uint64_t crc) {
> +  int i;
> +  for (i = 0; i < 32; i++) {
> +      if (((crc & 0x1) ^ (data & 0x1)))
> +       crc = (crc >> 1) ^ CRC64_POLY2;
> +      else
> +       crc = (crc >> 1);
> +      data >>= 1;
> +    }
> +  return crc;
> +}
> +
> +uint64_t _crc64_poly2 (uint32_t data, uint64_t crc) {
> +  int i;
> +  for (i = 0; i < 32; i++) {
> +      if (((crc & 0x1) ^ (data & 0x1)))
> +       crc = (crc >> 1) ^ CRC64_POLY2;
> +      else
> +       crc = (crc >> 1);
> +      data >>= 1;
> +    }
> +  return crc;
> +}
> +
> +int main ()
> +{
> +  uint64_t crc1 = 0;
> +  uint64_t crc2 = 0;
> +
> +  for (uint32_t i = 0; i <= 0xff; i++)
> +    {
> +      uint32_t data = expand8to32 (i);
> +      uint64_t res1 = _crc64_poly1_O0 (data, crc1);
> +      uint64_t res2 = _crc64_poly1 (data, crc1);
> +      crc1 = res2;
> +      if (res1 != res2)
> +       abort ();
> +
> +      uint64_t res3 = _crc64_poly2_O0 (data, crc2);
> +      uint64_t res4 = _crc64_poly2 (data, crc2);
> +      crc2 = res4;
> +      if (res3 != res4)
> +       abort ();
> +    }
> +}
> +
> +/* { dg-final { scan-tree-dump "function maybe contains CRC calculation." 
> "crc" } } */
> +/* { dg-final { scan-tree-dump "Loop iteration number is 31" "crc" } } */
> +/* { dg-final { scan-tree-dump "Bit reverse" "crc" } } */
> +/* { dg-final { scan-tree-dump "calculates CRC!" "crc" } } */
> +/* { dg-final { scan-tree-dump-times "Couldn't generate faster CRC code." 0 
> "crc" } } */
> diff --git a/gcc/testsuite/gcc.dg/torture/crc-41.c 
> b/gcc/testsuite/gcc.dg/torture/crc-41.c
> new file mode 100644
> index 00000000000..6aaa71c41e5
> --- /dev/null
> +++ b/gcc/testsuite/gcc.dg/torture/crc-41.c
> @@ -0,0 +1,98 @@
> +/* { dg-do run { target lp64 } } */
> +/* { dg-options "-fdump-tree-crc-details -w" } */
> +/* { dg-skip-if "" { *-*-* } { "-O0" "-O1" "-g" "-Os" "-flto" } } */
> +
> +#include <stdint.h>
> +#include <stdlib.h>
> +
> +#define CRC64_POLY1 0x9A6C9329AC4BC9B5
> +#define CRC64_POLY2 0x1A6C9329AC4BC9B4
> +
> +uint64_t expand8to64 (uint64_t x) {
> +  x ^= x >> 30;
> +  x *= UINT64_C(0xbf58476d1ce4e5b9);
> +  x ^= x >> 27;
> +  x *= UINT64_C(0x94d049bb133111eb);
> +  x ^= x >> 31;
> +  return x;
> +}
> +
> +// Test bit-reverse CRC64 64-bit data with Poly having LSB=1
> +__attribute__ ((noinline,optimize(0)))
> +uint64_t _crc64_poly1_O0 (uint64_t data, uint64_t crc) {
> +  int i;
> +  for (i = 0; i < 64; i++) {
> +      if (((crc & 0x1) ^ (data & 0x1)))
> +       crc = (crc >> 1) ^ CRC64_POLY1;
> +      else
> +       crc = (crc >> 1);
> +      data >>= 1;
> +    }
> +  return crc;
> +}
> +
> +uint64_t _crc64_poly1 (uint64_t data, uint64_t crc) {
> +  int i;
> +  for (i = 0; i < 64; i++) {
> +      if (((crc & 0x1) ^ (data & 0x1)))
> +       crc = (crc >> 1) ^ CRC64_POLY1;
> +      else
> +       crc = (crc >> 1);
> +      data >>= 1;
> +    }
> +  return crc;
> +}
> +
> +// Test bit-reverse CRC64 64-bit data with Poly having LSB=0
> +__attribute__ ((noinline,optimize(0)))
> +uint64_t _crc64_poly2_O0 (uint64_t data, uint64_t crc) {
> +  int i;
> +  for (i = 0; i < 64; i++) {
> +      if (((crc & 0x1) ^ (data & 0x1)))
> +       crc = (crc >> 1) ^ CRC64_POLY2;
> +      else
> +       crc = (crc >> 1);
> +      data >>= 1;
> +    }
> +  return crc;
> +}
> +
> +uint64_t _crc64_poly2 (uint64_t data, uint64_t crc) {
> +  int i;
> +  for (i = 0; i < 64; i++) {
> +      if (((crc & 0x1) ^ (data & 0x1)))
> +       crc = (crc >> 1) ^ CRC64_POLY2;
> +      else
> +       crc = (crc >> 1);
> +      data >>= 1;
> +    }
> +  return crc;
> +}
> +
> +int main ()
> +{
> +  uint64_t crc1 = 0;
> +  uint64_t crc2 = 0;
> +
> +  for (uint64_t i = 0; i <= 0xff; i++)
> +    {
> +      uint64_t data = expand8to64 (i);
> +      uint64_t res1 = _crc64_poly1_O0 (data, crc1);
> +      uint64_t res2 = _crc64_poly1 (data, crc1);
> +      crc1 = res2;
> +      if (res1 != res2)
> +       abort ();
> +
> +      uint64_t res3 = _crc64_poly2_O0 (data, crc2);
> +      uint64_t res4 = _crc64_poly2 (data, crc2);
> +      crc2 = res4;
> +      if (res3 != res4)
> +       abort ();
> +    }
> +}
> +
> +/* { dg-final { scan-tree-dump "function maybe contains CRC calculation." 
> "crc" } } */
> +/* { dg-final { scan-tree-dump "Loop iteration number is 63" "crc" } } */
> +/* { dg-final { scan-tree-dump "Bit reverse" "crc" } } */
> +/* { dg-final { scan-tree-dump "calculates CRC!" "crc" } } */
> +/* { dg-final { scan-tree-dump-times "Couldn't generate faster CRC code." 0 
> "crc" } } */
> diff --git a/gcc/testsuite/gcc.target/i386/crc-34-pclmul.c 
> b/gcc/testsuite/gcc.target/i386/crc-34-pclmul.c
> new file mode 100644
> index 00000000000..51f747ed11c
> --- /dev/null
> +++ b/gcc/testsuite/gcc.target/i386/crc-34-pclmul.c
> @@ -0,0 +1,9 @@
> +/* { dg-do run { target { pclmul_runtime } } } */
> +/* { dg-options "-mpclmul -O2 -fdump-rtl-dfinish -fdump-tree-crc" } */
> +
> +#include "../../gcc.dg/torture/crc-34.c"
> +
> +/* { dg-final { scan-tree-dump "calculates CRC!" "crc"} } */
> +/* { dg-final { scan-tree-dump-times "Couldn't generate faster CRC code." 0 
> "crc"} } */
> +/* Check 8-bit data CRC doesn't expand with pclmul */
> +/* { dg-final { scan-rtl-dump-not "pclmulqdq" "dfinish"} } */
> diff --git a/gcc/testsuite/gcc.target/i386/crc-35-pclmul.c 
> b/gcc/testsuite/gcc.target/i386/crc-35-pclmul.c
> new file mode 100644
> index 00000000000..054928ccae4
> --- /dev/null
> +++ b/gcc/testsuite/gcc.target/i386/crc-35-pclmul.c
> @@ -0,0 +1,8 @@
> +/* { dg-do run { target { pclmul_runtime } } } */
> +/* { dg-options "-mpclmul -O2 -fdump-rtl-dfinish -fdump-tree-crc" } */
> +
> +#include "../../gcc.dg/torture/crc-35.c"
> +
> +/* { dg-final { scan-tree-dump "calculates CRC!" "crc"} } */
> +/* { dg-final { scan-tree-dump-times "Couldn't generate faster CRC code." 0 
> "crc"} } */
> +/* { dg-final { scan-rtl-dump "pclmulqdq" "dfinish"} } */
> diff --git a/gcc/testsuite/gcc.target/i386/crc-36-pclmul.c 
> b/gcc/testsuite/gcc.target/i386/crc-36-pclmul.c
> new file mode 100644
> index 00000000000..8db16b4c09a
> --- /dev/null
> +++ b/gcc/testsuite/gcc.target/i386/crc-36-pclmul.c
> @@ -0,0 +1,8 @@
> +/* { dg-do run { target { pclmul_runtime } } } */
> +/* { dg-options "-mpclmul -O2 -fdump-rtl-dfinish -fdump-tree-crc" } */
> +
> +#include "../../gcc.dg/torture/crc-36.c"
> +
> +/* { dg-final { scan-tree-dump "calculates CRC!" "crc"} } */
> +/* { dg-final { scan-tree-dump-times "Couldn't generate faster CRC code." 0 
> "crc"} } */
> +/* { dg-final { scan-rtl-dump "pclmulqdq" "dfinish"} } */
> diff --git a/gcc/testsuite/gcc.target/i386/crc-37-pclmul.c 
> b/gcc/testsuite/gcc.target/i386/crc-37-pclmul.c
> new file mode 100644
> index 00000000000..8d8567732df
> --- /dev/null
> +++ b/gcc/testsuite/gcc.target/i386/crc-37-pclmul.c
> @@ -0,0 +1,8 @@
> +/* { dg-do run { target { pclmul_runtime } } } */
> +/* { dg-options "-mpclmul -O2 -fdump-rtl-dfinish -fdump-tree-crc" } */
> +
> +#include "../../gcc.dg/torture/crc-37.c"
> +
> +/* { dg-final { scan-tree-dump "calculates CRC!" "crc"} } */
> +/* { dg-final { scan-tree-dump-times "Couldn't generate faster CRC code." 0 
> "crc"} } */
> +/* { dg-final { scan-rtl-dump "pclmulqdq" "dfinish"} } */
> diff --git a/gcc/testsuite/gcc.target/i386/crc-38-pclmul.c 
> b/gcc/testsuite/gcc.target/i386/crc-38-pclmul.c
> new file mode 100644
> index 00000000000..55767ac1c71
> --- /dev/null
> +++ b/gcc/testsuite/gcc.target/i386/crc-38-pclmul.c
> @@ -0,0 +1,9 @@
> +/* { dg-do run { target { pclmul_runtime } } } */
> +/* { dg-options "-mpclmul -O2 -fdump-rtl-dfinish -fdump-tree-crc" } */
> +
> +#include "../../gcc.dg/torture/crc-38.c"
> +
> +/* { dg-final { scan-tree-dump "calculates CRC!" "crc"} } */
> +/* { dg-final { scan-tree-dump-times "Couldn't generate faster CRC code." 0 
> "crc"} } */
> +/* Check 8-bit data CRC doesn't expand with pclmul */
> +/* { dg-final { scan-rtl-dump-not "pclmulqdq" "dfinish"} } */
> diff --git a/gcc/testsuite/gcc.target/i386/crc-39-pclmul.c 
> b/gcc/testsuite/gcc.target/i386/crc-39-pclmul.c
> new file mode 100644
> index 00000000000..b26b93139aa
> --- /dev/null
> +++ b/gcc/testsuite/gcc.target/i386/crc-39-pclmul.c
> @@ -0,0 +1,8 @@
> +/* { dg-do run { target { pclmul_runtime } } } */
> +/* { dg-options "-mpclmul -O2 -fdump-rtl-dfinish -fdump-tree-crc" } */
> +
> +#include "../../gcc.dg/torture/crc-39.c"
> +
> +/* { dg-final { scan-tree-dump "calculates CRC!" "crc"} } */
> +/* { dg-final { scan-tree-dump-times "Couldn't generate faster CRC code." 0 
> "crc"} } */
> +/* { dg-final { scan-rtl-dump "pclmulqdq" "dfinish"} } */
> diff --git a/gcc/testsuite/gcc.target/i386/crc-40-pclmul.c 
> b/gcc/testsuite/gcc.target/i386/crc-40-pclmul.c
> new file mode 100644
> index 00000000000..3f48f84a1cf
> --- /dev/null
> +++ b/gcc/testsuite/gcc.target/i386/crc-40-pclmul.c
> @@ -0,0 +1,8 @@
> +/* { dg-do run { target { pclmul_runtime } } } */
> +/* { dg-options "-mpclmul -O2 -fdump-rtl-dfinish -fdump-tree-crc" } */
> +
> +#include "../../gcc.dg/torture/crc-40.c"
> +
> +/* { dg-final { scan-tree-dump "calculates CRC!" "crc"} } */
> +/* { dg-final { scan-tree-dump-times "Couldn't generate faster CRC code." 0 
> "crc"} } */
> +/* { dg-final { scan-rtl-dump "pclmulqdq" "dfinish"} } */
> diff --git a/gcc/testsuite/gcc.target/i386/crc-41-pclmul.c 
> b/gcc/testsuite/gcc.target/i386/crc-41-pclmul.c
> new file mode 100644
> index 00000000000..734b81bb4bb
> --- /dev/null
> +++ b/gcc/testsuite/gcc.target/i386/crc-41-pclmul.c
> @@ -0,0 +1,8 @@
> +/* { dg-do run { target { pclmul_runtime } } } */
> +/* { dg-options "-mpclmul -O2 -fdump-rtl-dfinish -fdump-tree-crc" } */
> +
> +#include "../../gcc.dg/torture/crc-41.c"
> +
> +/* { dg-final { scan-tree-dump "calculates CRC!" "crc"} } */
> +/* { dg-final { scan-tree-dump-times "Couldn't generate faster CRC code." 0 
> "crc"} } */
> +/* { dg-final { scan-rtl-dump "pclmulqdq" "dfinish"} } */
> --
> 2.55.0
>

Reply via email to