On Sun, Oct 11, 2026 at 1:29 PM Uros Bizjak <[email protected]> wrote:

> On Fri, Oct 9, 2026 at 5:09 PM Shreesh Adiga
> <[email protected]> wrote:
> >
> >
> >
> > On Thu, Oct 8, 2026 at 10:25 PM Uros Bizjak <[email protected]> wrote:
> >>
> >> On Wed, Oct 7, 2026 at 5:28 PM Shreesh Adiga
> >> <[email protected]> wrote:
> >> >
> >> > On Tue, Sep 8, 2026 at 3:46 PM Mariam Arutunian <
> [email protected]> wrote:
> >> >>
> >> >> Thanks for the patch!
> >> >>
> >> >> I've had a quick look, and everything looks okay so far.
> >> >
> >> >
> >> > Thanks Mariam for your review!
> >> >
> >> > GCC x86 maintainers: ping for review. Kindly assist with the next
> steps for this change.
> >> > I'm interested in working on 64-bit CRC expansion as a follow up once
> this is merged.
> >> >
> >> > Thanks,
> >> > Shreesh
> >> >
> >> >>
> >> >> On Mon, Sep 7, 2026 at 1:56 PM Shreesh Adiga <
> [email protected]> wrote:
> >> >>>
> >> >>> From: Mariam Arutunian <[email protected]>
> >> >>>
> >> >>> This patch introduces pclmul expanders for the i386 backend,
> >> >>> dedicated to generating optimized code for CRC computations.
> >> >>>
> >> >>> Expander 1: Bit-Forward CRC (crc<SWI1248x:mode><SWI124:mode>4)
> >> >>> For targets that support both pclmulqdq instruction (TARGET_PCLMUL)
> and are
> >> >>> 64-bit (TARGET_64BIT),
> >> >>> the expander will generate code that uses the pclmulqdq instruction
> for CRC
> >> >>> computation.
> >> >>>
> >> >>> Expander 2: Bit-Reversed CRC (crc_rev<SWI1248x:mode><SWI124:mode>4)
> >> >>> If the target does not support crc32 but supports pclmulqdq, it
> then uses
> >> >>> the pclmulqdq instruction for bit-reversed CRC computation.
> >> >>>
> >> >>> This makes the x86 backend similar to aarch64 which uses pmull.
> >> >>> This is based on earlier submitted patch which was not merged for
> x86:
> >> >>> https://gcc.gnu.org/pipermail/gcc-patches/2024-November/668248.html
> >> >>>
> >> >>> gcc/ChangeLog:
> >> >>>
> >> >>>         * config/i386/i386-expand.cc
> (ix86_expand_crc_using_pclmul): New
> >> >>>         function that implements pclmul expansion for Bit-Forward
> CRC
> >> >>>         computation.
> >> >>>         (ix86_expand_reversed_crc_using_pclmul): New function that
> >> >>>         implements pclmul expansion for Bit-Reversed CRC
> computation.
> >> >>>         * config/i386/i386-protos.h (ix86_expand_crc_using_pclmul):
> New
> >> >>>         extern function declaration.
> >> >>>         (ix86_expand_reversed_crc_using_pclmul): Likewise.
> >> >>>         * config/i386/i386.md (crc_rev<SWI124:mode>si4): Removed
> older
> >> >>>         expansion for Bit-Reversed CRC.
> >> >>>         (crc<SWI1248x:mode><SWI124:mode>4): Added new expander for
> >> >>>         Bit-Forward CRC.
> >> >>>         (crc_rev<SWI1248x:mode><SWI124:mode>4): Added new expander
> for
> >> >>>         Bit-Reversed CRC which extends previous CRC32 expansion.
> >> >>>
> >> >>> gcc/testsuite/ChangeLog:
> >> >>>
> >> >>>         * gcc.target/i386/crc-1-pclmul.c: New test.
> >> >>>         * gcc.target/i386/crc-10-pclmul.c: New test.
> >> >>>         * gcc.target/i386/crc-12-pclmul.c: New test.
> >> >>>         * gcc.target/i386/crc-13-pclmul.c: New test.
> >> >>>         * gcc.target/i386/crc-14-pclmul.c: New test.
> >> >>>         * gcc.target/i386/crc-17-pclmul.c: New test.
> >> >>>         * gcc.target/i386/crc-18-pclmul.c: New test.
> >> >>>         * gcc.target/i386/crc-21-pclmul.c: New test.
> >> >>>         * gcc.target/i386/crc-22-pclmul.c: New test.
> >> >>>         * gcc.target/i386/crc-23-pclmul.c: New test.
> >> >>>         * gcc.target/i386/crc-4-pclmul.c: New test.
> >> >>>         * gcc.target/i386/crc-5-pclmul.c: New test.
> >> >>>         * gcc.target/i386/crc-6-pclmul.c: New test.
> >> >>>         * gcc.target/i386/crc-7-pclmul.c: New test.
> >> >>>         * gcc.target/i386/crc-8-pclmul.c: New test.
> >> >>>         * gcc.target/i386/crc-9-pclmul.c: New test.
> >> >>>         * gcc.target/i386/crc-CCIT-data16-pclmul.c: New test.
> >> >>>         * gcc.target/i386/crc-CCIT-data8-pclmul.c: New test.
> >> >>>         * gcc.target/i386/crc-coremark-16bitdata-pclmul.c: New test.
> >> >>>         * gcc.target/i386/crc-crc32-data16.c: New test.
> >> >>>         * gcc.target/i386/crc-crc32-data32.c: New test.
> >> >>>         * gcc.target/i386/crc-crc32-data8.c: New test.
> >> >>>
> >> >>> Co-authored-by: Shreesh Adiga <[email protected]>
> >> >>> Signed-off-by: Shreesh Adiga <[email protected]>
> >>
> >> Mariam's signoff is needed here.
> >>
> >> >>> ---
> >> >>>  gcc/config/i386/i386-expand.cc                | 133
> ++++++++++++++++++
> >> >>>  gcc/config/i386/i386-protos.h                 |   3 +
> >> >>>  gcc/config/i386/i386.md                       |  53 +++++--
> >> >>>  gcc/testsuite/gcc.target/i386/crc-1-pclmul.c  |   8 ++
> >> >>>  gcc/testsuite/gcc.target/i386/crc-10-pclmul.c |   8 ++
> >> >>>  gcc/testsuite/gcc.target/i386/crc-12-pclmul.c |   9 ++
> >> >>>  gcc/testsuite/gcc.target/i386/crc-13-pclmul.c |   8 ++
> >> >>>  gcc/testsuite/gcc.target/i386/crc-14-pclmul.c |   8 ++
> >> >>>  gcc/testsuite/gcc.target/i386/crc-17-pclmul.c |   8 ++
> >> >>>  gcc/testsuite/gcc.target/i386/crc-18-pclmul.c |   8 ++
> >> >>>  gcc/testsuite/gcc.target/i386/crc-21-pclmul.c |   8 ++
> >> >>>  gcc/testsuite/gcc.target/i386/crc-22-pclmul.c |   8 ++
> >> >>>  gcc/testsuite/gcc.target/i386/crc-23-pclmul.c |   8 ++
> >> >>>  gcc/testsuite/gcc.target/i386/crc-4-pclmul.c  |   8 ++
> >> >>>  gcc/testsuite/gcc.target/i386/crc-5-pclmul.c  |   9 ++
> >> >>>  gcc/testsuite/gcc.target/i386/crc-6-pclmul.c  |   8 ++
> >> >>>  gcc/testsuite/gcc.target/i386/crc-7-pclmul.c  |   8 ++
> >> >>>  gcc/testsuite/gcc.target/i386/crc-8-pclmul.c  |   8 ++
> >> >>>  gcc/testsuite/gcc.target/i386/crc-9-pclmul.c  |   8 ++
> >> >>>  .../gcc.target/i386/crc-CCIT-data16-pclmul.c  |   9 ++
> >> >>>  .../gcc.target/i386/crc-CCIT-data8-pclmul.c   |   9 ++
> >> >>>  .../i386/crc-coremark-16bitdata-pclmul.c      |   9 ++
> >> >>>  .../gcc.target/i386/crc-crc32-data16.c        |  53 +++++++
> >> >>>  .../gcc.target/i386/crc-crc32-data32.c        |  53 +++++++
> >> >>>  .../gcc.target/i386/crc-crc32-data8.c         |  53 +++++++
> >> >>>  25 files changed, 492 insertions(+), 13 deletions(-)
> >> >>>  create mode 100644 gcc/testsuite/gcc.target/i386/crc-1-pclmul.c
> >> >>>  create mode 100644 gcc/testsuite/gcc.target/i386/crc-10-pclmul.c
> >> >>>  create mode 100644 gcc/testsuite/gcc.target/i386/crc-12-pclmul.c
> >> >>>  create mode 100644 gcc/testsuite/gcc.target/i386/crc-13-pclmul.c
> >> >>>  create mode 100644 gcc/testsuite/gcc.target/i386/crc-14-pclmul.c
> >> >>>  create mode 100644 gcc/testsuite/gcc.target/i386/crc-17-pclmul.c
> >> >>>  create mode 100644 gcc/testsuite/gcc.target/i386/crc-18-pclmul.c
> >> >>>  create mode 100644 gcc/testsuite/gcc.target/i386/crc-21-pclmul.c
> >> >>>  create mode 100644 gcc/testsuite/gcc.target/i386/crc-22-pclmul.c
> >> >>>  create mode 100644 gcc/testsuite/gcc.target/i386/crc-23-pclmul.c
> >> >>>  create mode 100644 gcc/testsuite/gcc.target/i386/crc-4-pclmul.c
> >> >>>  create mode 100644 gcc/testsuite/gcc.target/i386/crc-5-pclmul.c
> >> >>>  create mode 100644 gcc/testsuite/gcc.target/i386/crc-6-pclmul.c
> >> >>>  create mode 100644 gcc/testsuite/gcc.target/i386/crc-7-pclmul.c
> >> >>>  create mode 100644 gcc/testsuite/gcc.target/i386/crc-8-pclmul.c
> >> >>>  create mode 100644 gcc/testsuite/gcc.target/i386/crc-9-pclmul.c
> >> >>>  create mode 100644
> gcc/testsuite/gcc.target/i386/crc-CCIT-data16-pclmul.c
> >> >>>  create mode 100644
> gcc/testsuite/gcc.target/i386/crc-CCIT-data8-pclmul.c
> >> >>>  create mode 100644
> gcc/testsuite/gcc.target/i386/crc-coremark-16bitdata-pclmul.c
> >> >>>  create mode 100644 gcc/testsuite/gcc.target/i386/crc-crc32-data16.c
> >> >>>  create mode 100644 gcc/testsuite/gcc.target/i386/crc-crc32-data32.c
> >> >>>  create mode 100644 gcc/testsuite/gcc.target/i386/crc-crc32-data8.c
> >> >>>
> >> >>> diff --git a/gcc/config/i386/i386-expand.cc
> b/gcc/config/i386/i386-expand.cc
> >> >>> index fb4224af0da..6010892e3dc 100644
> >> >>> --- a/gcc/config/i386/i386-expand.cc
> >> >>> +++ b/gcc/config/i386/i386-expand.cc
> >> >>> @@ -29917,4 +29917,137 @@ ix86_expand_lcp_stall_peephole (rtx_insn
> *insn, rtx *operands,
> >> >>>    emit_insn (set);
> >> >>>  }
> >> >>>
> >> >>> +/* Generate assembly to calculate CRC using pclmulqdq instruction.
> >> >>> +   OPERANDS[1] is input CRC,
> >> >>> +   OPERANDS[2] is data (message),
> >> >>> +   OPERANDS[3] is the polynomial without the leading 1.  */
> >> >>> +
> >> >>> +void
> >> >>> +ix86_expand_crc_using_pclmul (scalar_mode crc_mode,
> >> >>> +                             scalar_mode data_mode,
> >> >>> +                             rtx *operands)
> >> >>> +{
> >> >>> +  /* Check and keep arguments.  */
> >> >>> +  gcc_assert (!CONST_INT_P (operands[0]));
> >> >>> +  gcc_assert (CONST_INT_P (operands[3]));
> >> >>> +  rtx crc = operands[1];
> >> >>> +  rtx data = operands[2];
> >> >>> +  rtx polynomial = operands[3];
> >> >>> +
> >> >>> +  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 (data_size <= crc_size);
> >> >>> +
> >> >>> +  /* 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, DImode, crc, crc_size -
> data_size,
> >> >>> +                       NULL_RTX, 1);
> >> >>> +
> >> >>> +  /* Keep the quotient in V2DImode.  */
> >> >>> +  rtx q_v2di = gen_reg_rtx (V2DImode);
> >> >>> +  rtx quotient = force_reg (DImode, gen_int_mode (q, DImode));
> >> >>> +  emit_insn (gen_vec_concatv2di (q_v2di, quotient, const0_rtx));
> >>
> >> This will move the constant through GPR and will result in movabs (a
> >> costly insn) and inter-unit movq. It is probably cheaper to have a
> >> DImode constant in the constant pool and movq it from there. I assume
> >> the compiler will move the memory load out of the loop by itself.
> >>
> >> >>> +  /* crc ^ data and keep in V2DImode.  */
> >> >>> +  rtx cd_xor = expand_binop (DImode, xor_optab, crc, data,
> NULL_RTX, 1,
> >> >>> +                            OPTAB_WIDEN);
> >> >>> +
> >> >>> +  rtx res = gen_reg_rtx (V2DImode);
> >> >>> +  emit_insn (gen_vec_concatv2di (res, cd_xor, const0_rtx));
> >> >>> +  /* Perform carry-less multiplication.  */
> >> >>> +  emit_insn (gen_pclmulqdq (res, res, q_v2di, gen_int_mode (0,
> SImode)));
> >>
> >> const0_rtx
> >>
> >> >>> +
> >> >>> +  res = expand_shift (RSHIFT_EXPR, V2DImode, res, crc_size,
> NULL_RTX, 1);
> >> >>> +
> >> >>> +  /* Keep the polynomial in V2DImode.  */
> >> >>> +  polynomial = simplify_gen_unary (ZERO_EXTEND, DImode, polynomial,
> >> >>> +                                  GET_MODE (polynomial));
> >> >>> +  rtx t1 = force_reg (DImode, polynomial);
> >> >>> +  rtx p_v2di = gen_reg_rtx (V2DImode);
> >> >>> +  emit_insn (gen_vec_concatv2di (p_v2di, t1, const0_rtx));
> >>
> >> Here you should use movd from memory (sse2_loadld + some subreg magic).
> >>
> >
> > Sure I have been looking into the review suggestions and have made the
> changes locally.
> > I just wanted to confirm if doing movq (quotient) + clmul + movd
> (polynomial) + clmul is better than doing
> > movdqa (quotient, polynomial) + clmul + clmul with different selector
> argument instead of 0.
> > Could you share your views on whether clubbing the two constants into a
> single XMM register load and
> > performing clmul with different lanes would be better or not?
>
> I don’t have performance data for this, and as the proposer it’s your
> job to benchmark the alternatives. My expectation is that a single
> 16-byte load with different clmul selectors is no worse than movq +
> movd (fewer uops, no GPR→XMM move), but please verify. Agner Fog’s
> tables [1] are a good start, and uiCA/llvm-mca can help with
> estimates. Please post measured numbers from at least Intel and AMD
> with the next revision.
>
>
Sorry I've already submitted v2 yesterday with the changes.
My reasoning was around reduced instruction count and register usage.
I briefly looked at the instruction table and for nehalem and zen 4.
I don't see movdqa being costlier than movq + movd with mem operand and
they all look the same cost wise.
Plus the constants reg is also preserved which should get hoisted in case
of inside a loop.
Therefore I think the v2 submission should be good enough.

Thanks,
Shreesh


> [1] https://www.agner.org/optimize/
>
> Uros.
>
> >
> > Thanks,
> > Shreesh
> >
> >> >>> +
> >> >>> +  /* Perform carry-less multiplication and get low part.  */
> >> >>> +  emit_insn (gen_pclmulqdq (res, res, p_v2di, gen_int_mode (0,
> SImode)));
> >> >>> +  rtx crc_part = gen_reg_rtx (DImode);
> >> >>> +  emit_insn (gen_vec_extractv2didi (crc_part, res, const0_rtx));
> >> >>> +
> >> >>> +  if (crc_size > data_size)
> >> >>> +    {
> >> >>> +      rtx shift = expand_shift (LSHIFT_EXPR, DImode, operands[1],
> data_size,
> >> >>> +                               NULL_RTX, 1);
> >> >>> +      crc_part = expand_binop (DImode, xor_optab, crc_part, shift,
> NULL_RTX, 1,
> >> >>> +                              OPTAB_DIRECT);
> >> >>> +    }
> >> >>> +  emit_move_insn (operands[0], gen_lowpart (crc_mode, crc_part));
> >> >>> +}
> >> >>> +
> >> >>> +/* Generate assembly to calculate reversed CRC using pclmulqdq
> instruction.
> >> >>> +   OPERANDS[1] is input CRC,
> >> >>> +   OPERANDS[2] is data (message),
> >> >>> +   OPERANDS[3] is the polynomial without the leading 1.  */
> >> >>> +
> >> >>> +void
> >> >>> +ix86_expand_reversed_crc_using_pclmul (scalar_mode crc_mode,
> >> >>> +                                      scalar_mode data_mode,
> >> >>> +                                      rtx *operands)
> >>
> >> The same comments as above apply to this function, too.
> >>
> >> >>> +{
> >> >>> +  /* Check and keep arguments.  */
> >> >>> +  gcc_assert (!CONST_INT_P (operands[0]));
> >> >>> +  gcc_assert (CONST_INT_P (operands[3]));
> >> >>> +  rtx crc = operands[1];
> >> >>> +  rtx data = operands[2];
> >> >>> +  rtx polynomial = operands[3];
> >> >>> +
> >> >>> +  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 (data_size <= crc_size);
> >> >>> +
> >> >>> +  /* 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);
> >> >>> +
> >> >>> +  rtx q_v2di = gen_reg_rtx (V2DImode);
> >> >>> +  rtx quotient = force_reg (DImode, gen_int_mode (q, DImode));
> >> >>> +  emit_insn (gen_vec_concatv2di (q_v2di, quotient, const0_rtx));
> >> >>> +
> >> >>> +  /* crc ^ data and keep in V2DImode.  */
> >> >>> +  rtx cd_xor = expand_binop (DImode, xor_optab, crc, data,
> NULL_RTX, 1,
> >> >>> +                            OPTAB_WIDEN);
> >> >>> +
> >> >>> +  /* Perform carry-less multiplication.  */
> >> >>> +  rtx res = gen_reg_rtx (V2DImode);
> >> >>> +  emit_insn (gen_vec_concatv2di (res, cd_xor, const0_rtx));
> >> >>> +  emit_insn (gen_pclmulqdq (res, res, q_v2di, gen_int_mode (0,
> SImode)));
> >> >>> +
> >> >>> +  res = expand_shift (LSHIFT_EXPR, V2DImode, res, 64 - data_size,
> NULL_RTX, 0);
> >> >>> +
> >> >>> +  /* Reflect the polynomial and keep in V2DImode.  */
> >> >>> +  unsigned HOST_WIDE_INT reflected_op3 = reflect_hwi (UINTVAL
> (polynomial),
> >> >>> +                                                     crc_size);
> >> >>> +  rtx ref_polynomial = force_reg (DImode,
> >> >>> +                                 gen_int_mode (reflected_op3 << 1,
> DImode));
> >> >>> +  rtx p_v2di = gen_reg_rtx (V2DImode);
> >> >>> +  emit_insn (gen_vec_concatv2di (p_v2di, ref_polynomial,
> const0_rtx));
> >> >>> +
> >> >>> +  /* Perform carry-less multiplication and get high part.  */
> >> >>> +  emit_insn (gen_pclmulqdq (res, res, p_v2di, gen_int_mode (0,
> SImode)));
> >> >>> +  rtx res_high = gen_reg_rtx (DImode);
> >> >>> +  emit_insn (gen_vec_extractv2didi (res_high, res, const1_rtx));
> >> >>> +
> >> >>> +  if (crc_size > data_size)
> >> >>> +    {
> >> >>> +      rtx shift = expand_shift (RSHIFT_EXPR, DImode, crc,
> data_size,
> >> >>> +                               NULL_RTX, 1);
> >> >>> +      res_high = expand_binop (DImode, xor_optab, res_high, shift,
> NULL_RTX, 1,
> >> >>> +                              OPTAB_DIRECT);
> >> >>> +    }
> >> >>> +  emit_move_insn (operands[0], gen_lowpart (crc_mode, res_high));
> >> >>> +}
> >> >>> +
> >> >>>  #include "gt-i386-expand.h"
> >> >>> diff --git a/gcc/config/i386/i386-protos.h
> b/gcc/config/i386/i386-protos.h
> >> >>> index 21994d3d498..d225a8fadc2 100644
> >> >>> --- a/gcc/config/i386/i386-protos.h
> >> >>> +++ b/gcc/config/i386/i386-protos.h
> >> >>> @@ -449,3 +449,6 @@ extern void ix86_set_handled_components
> (sbitmap);
> >> >>>  bool ix86_check_builtin_isa_match (unsigned int, HOST_WIDE_INT*,
> >> >>>                                    HOST_WIDE_INT*);
> >> >>>  rtx ix86_vgf2p8affine_shift_matrix (rtx, rtx, enum rtx_code);
> >> >>> +extern void ix86_expand_crc_using_pclmul (scalar_mode,
> scalar_mode, rtx *);
> >> >>> +extern void ix86_expand_reversed_crc_using_pclmul (scalar_mode,
> scalar_mode,
> >> >>> +                                                  rtx *);
> >> >>> diff --git a/gcc/config/i386/i386.md b/gcc/config/i386/i386.md
> >> >>> index 4e18797743f..7538b1f70f1 100644
> >> >>> --- a/gcc/config/i386/i386.md
> >> >>> +++ b/gcc/config/i386/i386.md
> >> >>> @@ -30504,19 +30504,46 @@ (define_insn "sse4_2_crc32di"
> >> >>>     (set_attr "prefix_extra" "1")
> >> >>>     (set_attr "mode" "DI")])
> >> >>>
> >> >>> -(define_expand "crc_rev<SWI124:mode>si4"
> >> >>> -  [(match_operand:SI 0 "register_operand")
> >> >>> -   (match_operand:SI 1 "register_operand")
> >> >>> -   (match_operand:SWI124 2 "nonimmediate_operand")
> >> >>> -   (match_operand:SI 3 "const_int_operand")]
> >> >>> -  "TARGET_CRC32"
> >> >>> -{
> >> >>> -  /* crc32 uses iSCSI polynomial */
> >> >>> -  if (INTVAL (operands[3]) == 0x1EDC6F41)
> >> >>> -    emit_insn (gen_sse4_2_crc32<mode> (operands[0], operands[1],
> operands[2]));
> >> >>> -  else
> >> >>> -    expand_reversed_crc_table_based (operands[0], operands[1],
> operands[2],
> >> >>> -                                    operands[3],
> <SWI124:MODE>mode);
> >> >>> +;; Bit-forward CRC
> >> >>> +(define_expand "crc<SWI1248x:mode><SWI124:mode>4"
> >> >>> +  [;; return value (calculated CRC)
> >> >>> +   (match_operand:SWI124 0 "register_operand" "=r")
> >> >>> +   ;; initial CRC
> >> >>> +   (match_operand:SWI124 1 "register_operand" "r")
> >> >>> +   ;; data
> >> >>> +   (match_operand:SWI1248x 2 "register_operand" "r")
> >>
> >> Please remove constraints, they are ignored in expanders. Also, please
> >> place comments after operands, see e.g. atomic_compare_and_swap<mode>.
> >>
> >> >>> +   ;; polynomial without leading 1
> >> >>> +   (match_operand:SWI124 3 "const_int_operand")]
> >> >>> +  "TARGET_PCLMUL && TARGET_64BIT && <SWI124:MODE>mode >=
> <SWI1248x:MODE>mode"
> >>
> >> Please write:
> >>
> >> TARGET_64BIT && TARGET_PCLMUL
> >> && <SWI124...
> >>
> >> Please mind the line length limit.
> >>
> >> >>> +{
> >> >>> +   ix86_expand_crc_using_pclmul (<SWI124:MODE>mode,
> <SWI1248x:MODE>mode,
> >> >>> +                                operands);
> >> >>> +   DONE;
> >> >>> +})
> >> >>> +
> >> >>> +;; Reversed CRC
> >> >>> +(define_expand "crc_rev<SWI1248x:mode><SWI124:mode>4"
> >> >>> +  [;; return value (calculated CRC)
> >> >>> +   (match_operand:SWI124 0 "register_operand" "=r")
> >> >>> +   ;; initial CRC
> >> >>> +   (match_operand:SWI124 1 "register_operand" "r")
> >> >>> +   ;; data
> >> >>> +   (match_operand:SWI1248x 2 "register_operand" "r")
> >> >>> +   ;; polynomial without leading 1
> >> >>> +   (match_operand:SWI124 3 "const_int_operand")]
> >>
> >> Same here.
> >>
> >> >>> +  "<SWI124:MODE>mode >= <SWI1248x:MODE>mode"
> >> >>> +  {
> >> >>> +    /* If it is iSCSI polynomial (0x1EDC6F41), generate crc32
> instruction.  */
> >> >>> +    if (TARGET_CRC32 && INTVAL (operands[3]) == 0x1EDC6F41
> >> >>> +       && <SWI124:MODE>mode == SImode)
> >> >>> +      emit_insn (gen_sse4_2_crc32<SWI1248x:mode> (operands[0],
> operands[1],
> >> >>> +                                                 operands[2]));
> >> >>> +    else if (TARGET_PCLMUL && TARGET_64BIT)
> >> >>> +      ix86_expand_reversed_crc_using_pclmul (<SWI124:MODE>mode,
> >> >>> +                                            <SWI1248x:MODE>mode,
> operands);
> >> >>> +    else
> >> >>> +      expand_reversed_crc_table_based (operands[0], operands[1],
> operands[2],
> >> >>> +                                      operands[3],
> <SWI1248x:MODE>mode);
> >> >>>    DONE;
> >> >>>  })
> >> >>>
> >> >>> diff --git a/gcc/testsuite/gcc.target/i386/crc-1-pclmul.c
> b/gcc/testsuite/gcc.target/i386/crc-1-pclmul.c
> >> >>> new file mode 100644
> >> >>> index 00000000000..21edf417f0c
> >> >>> --- /dev/null
> >> >>> +++ b/gcc/testsuite/gcc.target/i386/crc-1-pclmul.c
> >> >>> @@ -0,0 +1,8 @@
> >> >>> +/* { dg-do run } */
> >> >>> +/* { dg-options "-mpclmul -O2 -fdump-rtl-dfinish -fdump-tree-crc
> -fdisable-tree-phiopt2 -fdisable-tree-phiopt3" } */
> >> >>> +
> >> >>> +#include "../../gcc.dg/torture/crc-1.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"} } */
> >> >>> \ No newline at end of file
> >>
> >> Please put a newline here, also in other test files.
> >>
> >> Uros.
> >>
> >> >>> diff --git a/gcc/testsuite/gcc.target/i386/crc-10-pclmul.c
> b/gcc/testsuite/gcc.target/i386/crc-10-pclmul.c
> >> >>> new file mode 100644
> >> >>> index 00000000000..39bfd386d9c
> >> >>> --- /dev/null
> >> >>> +++ b/gcc/testsuite/gcc.target/i386/crc-10-pclmul.c
> >> >>> @@ -0,0 +1,8 @@
> >> >>> +/* { dg-do run } */
> >> >>> +/* { dg-options "-mpclmul -O2 -fdump-rtl-dfinish -fdump-tree-crc"
> } */
> >> >>> +
> >> >>> +#include "../../gcc.dg/torture/crc-10.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-12-pclmul.c
> b/gcc/testsuite/gcc.target/i386/crc-12-pclmul.c
> >> >>> new file mode 100644
> >> >>> index 00000000000..1ac9a6bf56d
> >> >>> --- /dev/null
> >> >>> +++ b/gcc/testsuite/gcc.target/i386/crc-12-pclmul.c
> >> >>> @@ -0,0 +1,9 @@
> >> >>> +/* { dg-do run } */
> >> >>> +/* { dg-options "-mpclmul -O2 -fdump-rtl-dfinish -fdump-tree-crc
> -fdisable-tree-phiopt2 -fdisable-tree-phiopt3" } */
> >> >>> +/* { dg-skip-if "" { *-*-* } { "-flto"} } */
> >> >>> +
> >> >>> +#include "../../gcc.dg/torture/crc-12.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-13-pclmul.c
> b/gcc/testsuite/gcc.target/i386/crc-13-pclmul.c
> >> >>> new file mode 100644
> >> >>> index 00000000000..c290539fad3
> >> >>> --- /dev/null
> >> >>> +++ b/gcc/testsuite/gcc.target/i386/crc-13-pclmul.c
> >> >>> @@ -0,0 +1,8 @@
> >> >>> +/* { dg-do run } */
> >> >>> +/* { dg-options "-mpclmul -O2 -fdump-rtl-dfinish -fdump-tree-crc"
> } */
> >> >>> +
> >> >>> +#include "../../gcc.dg/torture/crc-13.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-14-pclmul.c
> b/gcc/testsuite/gcc.target/i386/crc-14-pclmul.c
> >> >>> new file mode 100644
> >> >>> index 00000000000..cc62ee471c7
> >> >>> --- /dev/null
> >> >>> +++ b/gcc/testsuite/gcc.target/i386/crc-14-pclmul.c
> >> >>> @@ -0,0 +1,8 @@
> >> >>> +/* { dg-do run } */
> >> >>> +/* { dg-options "-mpclmul -O2 -fdump-rtl-dfinish -fdump-tree-crc"
> } */
> >> >>> +
> >> >>> +#include "../../gcc.dg/torture/crc-14.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-17-pclmul.c
> b/gcc/testsuite/gcc.target/i386/crc-17-pclmul.c
> >> >>> new file mode 100644
> >> >>> index 00000000000..660bff55e1b
> >> >>> --- /dev/null
> >> >>> +++ b/gcc/testsuite/gcc.target/i386/crc-17-pclmul.c
> >> >>> @@ -0,0 +1,8 @@
> >> >>> +/* { dg-do run } */
> >> >>> +/* { dg-options "-mpclmul -O2 -fdump-rtl-dfinish -fdump-tree-crc"
> } */
> >> >>> +
> >> >>> +#include "../../gcc.dg/torture/crc-17.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-18-pclmul.c
> b/gcc/testsuite/gcc.target/i386/crc-18-pclmul.c
> >> >>> new file mode 100644
> >> >>> index 00000000000..e54392b32a9
> >> >>> --- /dev/null
> >> >>> +++ b/gcc/testsuite/gcc.target/i386/crc-18-pclmul.c
> >> >>> @@ -0,0 +1,8 @@
> >> >>> +/* { dg-do run } */
> >> >>> +/* { dg-options "-mpclmul -O2 -fdump-rtl-dfinish -fdump-tree-crc"
> } */
> >> >>> +
> >> >>> +#include "../../gcc.dg/torture/crc-18.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-21-pclmul.c
> b/gcc/testsuite/gcc.target/i386/crc-21-pclmul.c
> >> >>> new file mode 100644
> >> >>> index 00000000000..4db1504cd49
> >> >>> --- /dev/null
> >> >>> +++ b/gcc/testsuite/gcc.target/i386/crc-21-pclmul.c
> >> >>> @@ -0,0 +1,8 @@
> >> >>> +/* { dg-do run } */
> >> >>> +/* { dg-options "-mpclmul -O2 -fdump-rtl-dfinish -fdump-tree-crc"
> } */
> >> >>> +
> >> >>> +#include "../../gcc.dg/torture/crc-21.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-22-pclmul.c
> b/gcc/testsuite/gcc.target/i386/crc-22-pclmul.c
> >> >>> new file mode 100644
> >> >>> index 00000000000..d0f27d96069
> >> >>> --- /dev/null
> >> >>> +++ b/gcc/testsuite/gcc.target/i386/crc-22-pclmul.c
> >> >>> @@ -0,0 +1,8 @@
> >> >>> +/* { dg-do run } */
> >> >>> +/* { dg-options "-mpclmul -O2 -fdump-rtl-dfinish -fdump-tree-crc"
> } */
> >> >>> +
> >> >>> +#include "../../gcc.dg/torture/crc-22.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-23-pclmul.c
> b/gcc/testsuite/gcc.target/i386/crc-23-pclmul.c
> >> >>> new file mode 100644
> >> >>> index 00000000000..666f3620597
> >> >>> --- /dev/null
> >> >>> +++ b/gcc/testsuite/gcc.target/i386/crc-23-pclmul.c
> >> >>> @@ -0,0 +1,8 @@
> >> >>> +/* { dg-do run } */
> >> >>> +/* { dg-options "-mpclmul -O2 -fdump-rtl-dfinish -fdump-tree-crc"
> } */
> >> >>> +
> >> >>> +#include "../../gcc.dg/torture/crc-23.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-4-pclmul.c
> b/gcc/testsuite/gcc.target/i386/crc-4-pclmul.c
> >> >>> new file mode 100644
> >> >>> index 00000000000..398ecaa4aba
> >> >>> --- /dev/null
> >> >>> +++ b/gcc/testsuite/gcc.target/i386/crc-4-pclmul.c
> >> >>> @@ -0,0 +1,8 @@
> >> >>> +/* { dg-do run } */
> >> >>> +/* { dg-options "-mpclmul -O2 -fdump-rtl-dfinish -fdump-tree-crc"
> } */
> >> >>> +
> >> >>> +#include "../../gcc.dg/torture/crc-4.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-5-pclmul.c
> b/gcc/testsuite/gcc.target/i386/crc-5-pclmul.c
> >> >>> new file mode 100644
> >> >>> index 00000000000..b80368e81bc
> >> >>> --- /dev/null
> >> >>> +++ b/gcc/testsuite/gcc.target/i386/crc-5-pclmul.c
> >> >>> @@ -0,0 +1,9 @@
> >> >>> +/* { dg-do run } */
> >> >>> +/* { dg-options "-mpclmul -O2 -w -fdump-rtl-dfinish
> -fdump-tree-crc" } */
> >> >>> +/* { dg-skip-if "" { *-*-* } { "-flto"} } */
> >> >>> +
> >> >>> +#include "../../gcc.dg/torture/crc-5.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"} } */
> >> >>> \ No newline at end of file
> >> >>> diff --git a/gcc/testsuite/gcc.target/i386/crc-6-pclmul.c
> b/gcc/testsuite/gcc.target/i386/crc-6-pclmul.c
> >> >>> new file mode 100644
> >> >>> index 00000000000..20b851e3596
> >> >>> --- /dev/null
> >> >>> +++ b/gcc/testsuite/gcc.target/i386/crc-6-pclmul.c
> >> >>> @@ -0,0 +1,8 @@
> >> >>> +/* { dg-do run } */
> >> >>> +/* { dg-options "-mpclmul -O2 -fdump-rtl-dfinish -fdump-tree-crc"
> } */
> >> >>> +
> >> >>> +#include "../../gcc.dg/torture/crc-6.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"} } */
> >> >>> \ No newline at end of file
> >> >>> diff --git a/gcc/testsuite/gcc.target/i386/crc-7-pclmul.c
> b/gcc/testsuite/gcc.target/i386/crc-7-pclmul.c
> >> >>> new file mode 100644
> >> >>> index 00000000000..3e5cc75338e
> >> >>> --- /dev/null
> >> >>> +++ b/gcc/testsuite/gcc.target/i386/crc-7-pclmul.c
> >> >>> @@ -0,0 +1,8 @@
> >> >>> +/* { dg-do run } */
> >> >>> +/* { dg-options "-mpclmul -O2 -fdump-rtl-dfinish -fdump-tree-crc"
> } */
> >> >>> +
> >> >>> +#include "../../gcc.dg/torture/crc-7.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-8-pclmul.c
> b/gcc/testsuite/gcc.target/i386/crc-8-pclmul.c
> >> >>> new file mode 100644
> >> >>> index 00000000000..4b1145553fc
> >> >>> --- /dev/null
> >> >>> +++ b/gcc/testsuite/gcc.target/i386/crc-8-pclmul.c
> >> >>> @@ -0,0 +1,8 @@
> >> >>> +/* { dg-do run } */
> >> >>> +/* { dg-options "-mpclmul -O2 -fdump-rtl-dfinish -fdump-tree-crc"
> } */
> >> >>> +
> >> >>> +#include "../../gcc.dg/torture/crc-8.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-9-pclmul.c
> b/gcc/testsuite/gcc.target/i386/crc-9-pclmul.c
> >> >>> new file mode 100644
> >> >>> index 00000000000..204d6c84d47
> >> >>> --- /dev/null
> >> >>> +++ b/gcc/testsuite/gcc.target/i386/crc-9-pclmul.c
> >> >>> @@ -0,0 +1,8 @@
> >> >>> +/* { dg-do run } */
> >> >>> +/* { dg-options "-mpclmul -O2 -fdump-rtl-dfinish -fdump-tree-crc"
> } */
> >> >>> +
> >> >>> +#include "../../gcc.dg/torture/crc-9.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-CCIT-data16-pclmul.c
> b/gcc/testsuite/gcc.target/i386/crc-CCIT-data16-pclmul.c
> >> >>> new file mode 100644
> >> >>> index 00000000000..ca728120858
> >> >>> --- /dev/null
> >> >>> +++ b/gcc/testsuite/gcc.target/i386/crc-CCIT-data16-pclmul.c
> >> >>> @@ -0,0 +1,9 @@
> >> >>> +/* { dg-do run } */
> >> >>> +/* { dg-options "-w -mpclmul -O2 -fdump-rtl-dfinish
> -fdump-tree-crc" } */
> >> >>> +/* { dg-skip-if "" { *-*-* } { "-flto"} } */
> >> >>> +
> >> >>> +#include "../../gcc.dg/torture/crc-CCIT-data16.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"} } */
> >> >>> \ No newline at end of file
> >> >>> diff --git a/gcc/testsuite/gcc.target/i386/crc-CCIT-data8-pclmul.c
> b/gcc/testsuite/gcc.target/i386/crc-CCIT-data8-pclmul.c
> >> >>> new file mode 100644
> >> >>> index 00000000000..816e0561d8f
> >> >>> --- /dev/null
> >> >>> +++ b/gcc/testsuite/gcc.target/i386/crc-CCIT-data8-pclmul.c
> >> >>> @@ -0,0 +1,9 @@
> >> >>> +/* { dg-do run } */
> >> >>> +/* { dg-options "-w -mpclmul -O2 -fdump-rtl-dfinish
> -fdump-tree-crc" } */
> >> >>> +/* { dg-skip-if "" { *-*-* } { "-flto" } } */
> >> >>> +
> >> >>> +#include "../../gcc.dg/torture/crc-CCIT-data8.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"} } */
> >> >>> \ No newline at end of file
> >> >>> diff --git
> a/gcc/testsuite/gcc.target/i386/crc-coremark-16bitdata-pclmul.c
> b/gcc/testsuite/gcc.target/i386/crc-coremark-16bitdata-pclmul.c
> >> >>> new file mode 100644
> >> >>> index 00000000000..817d960b0aa
> >> >>> --- /dev/null
> >> >>> +++ b/gcc/testsuite/gcc.target/i386/crc-coremark-16bitdata-pclmul.c
> >> >>> @@ -0,0 +1,9 @@
> >> >>> +/* { dg-do run } */
> >> >>> +/* { dg-options "-w -mpclmul -O2 -fdump-rtl-dfinish
> -fdump-tree-crc" } */
> >> >>> +/* { dg-skip-if "" { *-*-* } { "-flto"} } */
> >> >>> +
> >> >>> +#include "../../gcc.dg/torture/crc-coremark16-data16.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"} } */
> >> >>> \ No newline at end of file
> >> >>> diff --git a/gcc/testsuite/gcc.target/i386/crc-crc32-data16.c
> b/gcc/testsuite/gcc.target/i386/crc-crc32-data16.c
> >> >>> new file mode 100644
> >> >>> index 00000000000..49ab5f31ef0
> >> >>> --- /dev/null
> >> >>> +++ b/gcc/testsuite/gcc.target/i386/crc-crc32-data16.c
> >> >>> @@ -0,0 +1,53 @@
> >> >>> +/* { dg-do run } */
> >> >>> +/* { dg-options "-mcrc32 -O2 -fdump-rtl-dfinish -fdump-tree-crc" }
> */
> >> >>> +/* { dg-skip-if "" { *-*-* } { "-flto"} } */
> >> >>> +
> >> >>> +#include <stdint.h>
> >> >>> +#include <stdlib.h>
> >> >>> +
> >> >>> +__attribute__ ((noinline,optimize(0)))
> >> >>> +uint32_t _crc32_O0 (uint32_t crc, uint16_t data) {
> >> >>> +  int i;
> >> >>> +  crc = crc ^ data;
> >> >>> +
> >> >>> +  for (i = 0; i < 8; i++) {
> >> >>> +      if (crc & 1)
> >> >>> +       crc = (crc >> 1) ^ 0x82F63B78;
> >> >>> +      else
> >> >>> +       crc = (crc >> 1);
> >> >>> +    }
> >> >>> +
> >> >>> +  return crc;
> >> >>> +}
> >> >>> +
> >> >>> +uint32_t _crc32 (uint32_t crc, uint16_t data) {
> >> >>> +  int i;
> >> >>> +  crc = crc ^ data;
> >> >>> +
> >> >>> +  for (i = 0; i < 8; i++) {
> >> >>> +      if (crc & 1)
> >> >>> +       crc = (crc >> 1) ^ 0x82F63B78;
> >> >>> +      else
> >> >>> +       crc = (crc >> 1);
> >> >>> +    }
> >> >>> +
> >> >>> +  return crc;
> >> >>> +}
> >> >>> +
> >> >>> +int main ()
> >> >>> +{
> >> >>> +  uint32_t crc = 0x0D800D80;
> >> >>> +  for (uint16_t i = 0; i < 0xffff; i++)
> >> >>> +    {
> >> >>> +      uint32_t res1 = _crc32_O0 (crc, i);
> >> >>> +      uint32_t res2 = _crc32 (crc, i);
> >> >>> +      if (res1 != res2)
> >> >>> +       abort ();
> >> >>> +      crc = res1;
> >> >>> +    }
> >> >>> +}
> >> >>> +
> >> >>> +/* { 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 "UNSPEC_CRC32" "dfinish"} } */
> >> >>> +/* { dg-final { scan-rtl-dump-times "pclmulqdq" 0 "dfinish"} } */
> >> >>> diff --git a/gcc/testsuite/gcc.target/i386/crc-crc32-data32.c
> b/gcc/testsuite/gcc.target/i386/crc-crc32-data32.c
> >> >>> new file mode 100644
> >> >>> index 00000000000..08d6c193a77
> >> >>> --- /dev/null
> >> >>> +++ b/gcc/testsuite/gcc.target/i386/crc-crc32-data32.c
> >> >>> @@ -0,0 +1,53 @@
> >> >>> +/* { dg-do run } */
> >> >>> +/* { dg-options "-mcrc32 -O2 -fdump-rtl-dfinish -fdump-tree-crc" }
> */
> >> >>> +/* { dg-skip-if "" { *-*-* } { "-flto"} } */
> >> >>> +
> >> >>> +#include <stdint.h>
> >> >>> +#include <stdlib.h>
> >> >>> +
> >> >>> +__attribute__ ((noinline,optimize(0)))
> >> >>> +uint32_t _crc32_O0 (uint32_t crc, uint32_t data) {
> >> >>> +  int i;
> >> >>> +  crc = crc ^ data;
> >> >>> +
> >> >>> +  for (i = 0; i < 32; i++) {
> >> >>> +      if (crc & 1)
> >> >>> +       crc = (crc >> 1) ^ 0x82F63B78;
> >> >>> +      else
> >> >>> +       crc = (crc >> 1);
> >> >>> +    }
> >> >>> +
> >> >>> +  return crc;
> >> >>> +}
> >> >>> +
> >> >>> +uint32_t _crc32 (uint32_t crc, uint32_t data) {
> >> >>> +  int i;
> >> >>> +  crc = crc ^ data;
> >> >>> +
> >> >>> +  for (i = 0; i < 32; i++) {
> >> >>> +      if (crc & 1)
> >> >>> +       crc = (crc >> 1) ^ 0x82F63B78;
> >> >>> +      else
> >> >>> +       crc = (crc >> 1);
> >> >>> +    }
> >> >>> +
> >> >>> +  return crc;
> >> >>> +}
> >> >>> +
> >> >>> +int main ()
> >> >>> +{
> >> >>> +  uint32_t crc = 0x0D800D80;
> >> >>> +  for (uint8_t i = 0; i < 0xff; i++)
> >> >>> +    {
> >> >>> +      uint32_t res1 = _crc32_O0 (crc, i);
> >> >>> +      uint32_t res2 = _crc32 (crc, i);
> >> >>> +      if (res1 != res2)
> >> >>> +       abort ();
> >> >>> +      crc = res1;
> >> >>> +    }
> >> >>> +}
> >> >>> +
> >> >>> +/* { 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 "UNSPEC_CRC32" "dfinish"} } */
> >> >>> +/* { dg-final { scan-rtl-dump-times "pclmulqdq" 0 "dfinish"} } */
> >> >>> diff --git a/gcc/testsuite/gcc.target/i386/crc-crc32-data8.c
> b/gcc/testsuite/gcc.target/i386/crc-crc32-data8.c
> >> >>> new file mode 100644
> >> >>> index 00000000000..7a76b27fd28
> >> >>> --- /dev/null
> >> >>> +++ b/gcc/testsuite/gcc.target/i386/crc-crc32-data8.c
> >> >>> @@ -0,0 +1,53 @@
> >> >>> +/* { dg-do run } */
> >> >>> +/* { dg-options "-mcrc32 -O2 -fdump-rtl-dfinish -fdump-tree-crc" }
> */
> >> >>> +/* { dg-skip-if "" { *-*-* } { "-flto"} } */
> >> >>> +
> >> >>> +#include <stdint.h>
> >> >>> +#include <stdlib.h>
> >> >>> +
> >> >>> +__attribute__ ((noinline,optimize(0)))
> >> >>> +uint32_t _crc32_O0 (uint32_t crc, uint8_t data) {
> >> >>> +  int i;
> >> >>> +  crc = crc ^ data;
> >> >>> +
> >> >>> +  for (i = 0; i < 8; i++) {
> >> >>> +      if (crc & 1)
> >> >>> +       crc = (crc >> 1) ^ 0x82F63B78;
> >> >>> +      else
> >> >>> +       crc = (crc >> 1);
> >> >>> +    }
> >> >>> +
> >> >>> +  return crc;
> >> >>> +}
> >> >>> +
> >> >>> +uint32_t _crc32 (uint32_t crc, uint8_t data) {
> >> >>> +  int i;
> >> >>> +  crc = crc ^ data;
> >> >>> +
> >> >>> +  for (i = 0; i < 8; i++) {
> >> >>> +      if (crc & 1)
> >> >>> +       crc = (crc >> 1) ^ 0x82F63B78;
> >> >>> +      else
> >> >>> +       crc = (crc >> 1);
> >> >>> +    }
> >> >>> +
> >> >>> +  return crc;
> >> >>> +}
> >> >>> +
> >> >>> +int main ()
> >> >>> +{
> >> >>> +  uint32_t crc = 0x0D800D80;
> >> >>> +  for (uint8_t i = 0; i < 0xff; i++)
> >> >>> +    {
> >> >>> +      uint32_t res1 = _crc32_O0 (crc, i);
> >> >>> +      uint32_t res2 = _crc32 (crc, i);
> >> >>> +      if (res1 != res2)
> >> >>> +       abort ();
> >> >>> +      crc = res1;
> >> >>> +    }
> >> >>> +}
> >> >>> +
> >> >>> +/* { 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 "UNSPEC_CRC32" "dfinish"} } */
> >> >>> +/* { dg-final { scan-rtl-dump-times "pclmulqdq" 0 "dfinish"} } */
> >> >>> --
> >> >>> 2.55.0
> >> >>>
>

Reply via email to