The aarch64 backend expanded for 8/16/32 bit CRCs only and skipped
64-bit CRC expansion. This patch extends the routines to also support
64-bit CRC for both Bit-Forward and Bit-Reversed similar to
x86 clmul implementation.

gcc/ChangeLog:

        * config/aarch64/aarch64.cc (aarch64_crc_constants_gen): New
        function.
        (aarch64_expand_crc_using_pmull): Added support for 64-bit CRCs.
        (aarch64_expand_reversed_crc_using_pmull): Likewise.
        * config/aarch64/aarch64.md (crc_rev<ALLI:mode><ALLX:mode>4):
        Renamed ALLX to ALLI_2 to allow 64-bit CRC.
        (crc_rev<ALLI:mode><ALLI_2:mode>4): Likewise.
        (crc<ALLI:mode><ALLX:mode>4): Likewise.
        (crc<ALLI:mode><ALLI_2:mode>4): Likewise.
        * config/aarch64/iterators.md: Added new mode iterator ALLI_2
        which duplicates ALLI.

gcc/testsuite/ChangeLog:

        * gcc.target/aarch64/crc-34-pmul.c: New test.
        * gcc.target/aarch64/crc-35-pmul.c: New test.
        * gcc.target/aarch64/crc-36-pmul.c: New test.
        * gcc.target/aarch64/crc-37-pmul.c: New test.
        * gcc.target/aarch64/crc-38-pmul.c: New test.
        * gcc.target/aarch64/crc-39-pmul.c: New test.
        * gcc.target/aarch64/crc-40-pmul.c: New test.
        * gcc.target/aarch64/crc-41-pmul.c: New test.

Signed-off-by: Shreesh Adiga <[email protected]>
---
 gcc/config/aarch64/aarch64.cc                 | 136 +++++++++++++++---
 gcc/config/aarch64/aarch64.md                 |  32 +++--
 gcc/config/aarch64/iterators.md               |   3 +
 .../gcc.target/aarch64/crc-34-pmul.c          |   9 ++
 .../gcc.target/aarch64/crc-35-pmul.c          |   9 ++
 .../gcc.target/aarch64/crc-36-pmul.c          |   9 ++
 .../gcc.target/aarch64/crc-37-pmul.c          |   9 ++
 .../gcc.target/aarch64/crc-38-pmul.c          |   9 ++
 .../gcc.target/aarch64/crc-39-pmul.c          |   9 ++
 .../gcc.target/aarch64/crc-40-pmul.c          |   9 ++
 .../gcc.target/aarch64/crc-41-pmul.c          |   9 ++
 11 files changed, 207 insertions(+), 36 deletions(-)
 create mode 100644 gcc/testsuite/gcc.target/aarch64/crc-34-pmul.c
 create mode 100644 gcc/testsuite/gcc.target/aarch64/crc-35-pmul.c
 create mode 100644 gcc/testsuite/gcc.target/aarch64/crc-36-pmul.c
 create mode 100644 gcc/testsuite/gcc.target/aarch64/crc-37-pmul.c
 create mode 100644 gcc/testsuite/gcc.target/aarch64/crc-38-pmul.c
 create mode 100644 gcc/testsuite/gcc.target/aarch64/crc-39-pmul.c
 create mode 100644 gcc/testsuite/gcc.target/aarch64/crc-40-pmul.c
 create mode 100644 gcc/testsuite/gcc.target/aarch64/crc-41-pmul.c

diff --git a/gcc/config/aarch64/aarch64.cc b/gcc/config/aarch64/aarch64.cc
index 5b1c78462a3..ae61beda396 100644
--- a/gcc/config/aarch64/aarch64.cc
+++ b/gcc/config/aarch64/aarch64.cc
@@ -33860,6 +33860,22 @@ aarch64::report_not_enum (location_t location, tree 
fndecl, unsigned int argno,
            " a valid %qT value", actual, argno + 1, fndecl, enumtype);
 }
 
+/* Generate V2DImode reg with the required 64-bit pmull constants.
+   Mainly written to handle endianness for the lanes.  */
+static rtx
+aarch64_crc_constants_gen (unsigned HOST_WIDE_INT lo,
+                          unsigned HOST_WIDE_INT hi)
+{
+  rtx lo_rtx = gen_int_mode (lo, DImode);
+  rtx hi_rtx = gen_int_mode (hi, DImode);
+  rtvec constants_vec = (BYTES_BIG_ENDIAN
+                        ? gen_rtvec (2, hi_rtx, lo_rtx)
+                        : gen_rtvec (2, lo_rtx, hi_rtx));
+  rtx reg = gen_reg_rtx (V2DImode);
+  emit_move_insn (reg, gen_rtx_CONST_VECTOR (V2DImode, constants_vec));
+  return reg;
+}
+
 /* Generate assembly to calculate CRC
    using carry-less multiplication instruction.
    OPERANDS[1] is input CRC,
@@ -33880,7 +33896,7 @@ aarch64_expand_crc_using_pmull (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);
 
   /* Calculate the quotient.  */
@@ -33891,21 +33907,57 @@ aarch64_expand_crc_using_pmull (scalar_mode crc_mode,
     crc = expand_shift (RSHIFT_EXPR, DImode, crc, crc_size - data_size,
                        NULL_RTX, 1);
 
-  rtx t0 = force_reg (DImode, gen_int_mode (q, DImode));
+  rtx t0, t1, a0_x2;
+  rtx constants_reg;
   polynomial = simplify_gen_unary (ZERO_EXTEND, DImode, polynomial,
                                   GET_MODE (polynomial));
-  rtx t1 = force_reg (DImode, polynomial);
 
   rtx a0 = expand_binop (DImode, xor_optab, crc, data, NULL_RTX, 1,
                         OPTAB_WIDEN);
 
+  if (crc_size == 64)
+    {
+      /* Pack the 64-bit quotient and Polynomial pmull constants into a single
+        128-bit V2DImode constant and load it from memory.
+        a0 is loaded into both lanes as it is needed for performing
+        xor with upper lane after first clmul.
+        Since we need upper 64-bits of pmull (a0, q) for second pmull with
+        polynomial, polynomial is set at lane 1.  */
+      constants_reg = aarch64_crc_constants_gen (q, UINTVAL (polynomial));
+      a0_x2 = gen_reg_rtx (V2DImode);
+      rtx dup = gen_rtx_VEC_DUPLICATE (V2DImode, a0);
+      emit_move_insn (a0_x2, dup);
+      t0 = gen_lowpart (DImode, constants_reg);
+    }
+  else
+    {
+      t0 = force_reg (DImode, gen_int_mode (q, DImode));
+      t1 = force_reg (DImode, polynomial);
+    }
+
+  /* Perform carry-less multiplication with quotient.  */
   rtx pmull_res = gen_reg_rtx (TImode);
   emit_insn (gen_aarch64_crypto_pmulldi (pmull_res, a0, t0));
-  a0 = gen_lowpart (DImode, pmull_res);
 
-  a0 = expand_shift (RSHIFT_EXPR, DImode, a0, crc_size, NULL_RTX, 1);
+  if (crc_size == 64)
+    {
+      /* Perform xor of a0 with upper 64-bits of pmull_res to handle the
+        65th bit of quotient.  */
+      rtx pmull_vec = gen_lowpart (V2DImode, pmull_res);
+      pmull_vec = expand_binop (V2DImode, xor_optab, pmull_vec, a0_x2,
+                               NULL_RTX, 1, OPTAB_DIRECT);
+      /* Perform carry-less multiplication with polynomial.  */
+      emit_insn (gen_aarch64_crypto_pmullv2di (pmull_res,
+                                              constants_reg, pmull_vec));
+    }
+  else
+    {
+      a0 = gen_lowpart (DImode, pmull_res);
+      a0 = expand_shift (RSHIFT_EXPR, DImode, a0, crc_size, NULL_RTX, 1);
+      /* Perform carry-less multiplication with polynomial.  */
+      emit_insn (gen_aarch64_crypto_pmulldi (pmull_res, a0, t1));
+    }
 
-  emit_insn (gen_aarch64_crypto_pmulldi (pmull_res, a0, t1));
   a0 = gen_lowpart (DImode, pmull_res);
 
   if (crc_size > data_size)
@@ -33939,41 +33991,83 @@ aarch64_expand_reversed_crc_using_pmull (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);
 
   /* 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 t0 = force_reg (DImode, gen_int_mode (q, DImode));
+  q = (reflect_hwi (q, crc_size) << 1) + 1;
 
   /* Reflect the polynomial.  */
   unsigned HOST_WIDE_INT ref_polynomial = reflect_hwi (UINTVAL (polynomial),
                                                       crc_size);
-  /* An unshifted multiplier would require the final result to be extracted
-     using a shift right by DATA_SIZE - 1 bits.  Shift the multiplier left
-     so that the shift right can be by CRC_SIZE bits instead.  */
-  ref_polynomial <<= crc_size - data_size + 1;
-  rtx t1 = force_reg (DImode, gen_int_mode (ref_polynomial, DImode));
 
   /* CRC calculation's main part.  */
   rtx a0 = expand_binop (DImode, xor_optab, crc, data, NULL_RTX, 1,
                         OPTAB_WIDEN);
 
-  /* Perform carry-less multiplication and get low part.  */
   rtx pmull_res = gen_reg_rtx (TImode);
-  emit_insn (gen_aarch64_crypto_pmulldi (pmull_res, a0, t0));
-  a0 = gen_lowpart (DImode, pmull_res);
 
-  a0 = expand_binop (DImode, and_optab, a0,
-                    gen_int_mode (GET_MODE_MASK (data_mode), DImode),
-                    NULL_RTX, 1, OPTAB_WIDEN);
+  rtx t0, t1, a0_x2, constants_reg;
+  if (crc_size == 64)
+    {
+      /* Pack the 64-bit quotient and Polynomial pmull constants into a single
+        128-bit V2DImode constant and load it from memory.
+        a0 is loaded into lane 1, so that we can use PMULL2 with quotient.
+        Since we need lower 64-bits of pmull (a0, q) for second pmull with
+        polynomial, polynomial is set at lane 0.  */
+      constants_reg = aarch64_crc_constants_gen (ref_polynomial << 1, q);
+      a0_x2 = gen_reg_rtx (V2DImode);
+      rtx dup = gen_rtx_VEC_DUPLICATE (V2DImode, a0);
+      emit_move_insn (a0_x2, dup);
+      /* Perform carry-less multiplication with quotient and get low part.  */
+      emit_insn (gen_aarch64_crypto_pmullv2di (pmull_res,
+                                              constants_reg, a0_x2));
+      rtx pmull_vec = gen_lowpart (V2DImode, pmull_res);
+      if (data_size < 64)
+       pmull_vec = expand_shift (LSHIFT_EXPR, V2DImode, pmull_vec,
+                                 64 - data_size, NULL_RTX, 0);
+
+      a0 = gen_lowpart (DImode, pmull_vec);
+      t1 = gen_lowpart (DImode, constants_reg);
+      /* Regenerate pmull_res to preserve a0 needed for xor later.  */
+      pmull_res = gen_reg_rtx (TImode);
+    }
+  else
+    {
+      /* An unshifted multiplier would require the final result to be extracted
+        using a shift right by DATA_SIZE - 1 bits.  Shift the multiplier left
+        so that the shift right can be by CRC_SIZE bits instead.  */
+      ref_polynomial <<= crc_size - data_size + 1;
+      t0 = force_reg (DImode, gen_int_mode (q, DImode));
+      t1 = force_reg (DImode, gen_int_mode (ref_polynomial, DImode));
+      /* Perform carry-less multiplication and get low part.  */
+      emit_insn (gen_aarch64_crypto_pmulldi (pmull_res, a0, t0));
+      a0 = gen_lowpart (DImode, pmull_res);
+
+      a0 = expand_binop (DImode, and_optab, a0,
+                        gen_int_mode (GET_MODE_MASK (data_mode), DImode),
+                        NULL_RTX, 1, OPTAB_WIDEN);
+
+    }
 
-  /* Perform carry-less multiplication.  */
+  /* Perform carry-less multiplication with polynomial.  */
   emit_insn (gen_aarch64_crypto_pmulldi (pmull_res, a0, t1));
 
+  if ((crc_size == 64) && (UINTVAL (polynomial) & 1))
+    {
+      /* Perform xor of pmull_res[127:64] with a0.
+        This is needed when the 65th bit of reflected polynomial is 1.  */
+      rtx tmp = gen_reg_rtx (V2DImode);
+      emit_move_insn (tmp, gen_rtx_VEC_DUPLICATE (V2DImode, a0));
+      rtx xor_res = expand_binop (V2DImode, xor_optab,
+                                 gen_lowpart (V2DImode, pmull_res), tmp,
+                                 NULL_RTX, 1, OPTAB_DIRECT);
+      pmull_res = gen_lowpart (TImode, xor_res);
+    }
+
   /* Perform a shift right by CRC_SIZE as an extraction of lane 1.  */
   machine_mode crc_vmode = aarch64_v128_mode (crc_mode).require ();
   a0 = (crc_size > data_size ? gen_reg_rtx (crc_mode) : operands[0]);
diff --git a/gcc/config/aarch64/aarch64.md b/gcc/config/aarch64/aarch64.md
index 8d0e50db272..3e08d4dc3d1 100644
--- a/gcc/config/aarch64/aarch64.md
+++ b/gcc/config/aarch64/aarch64.md
@@ -5010,33 +5010,35 @@ (define_insn "aarch64_<crc_variant>"
 )
 
 ;; Reversed CRC
-(define_expand "crc_rev<ALLI:mode><ALLX:mode>4"
+(define_expand "crc_rev<ALLI:mode><ALLI_2:mode>4"
   [;; return value (calculated CRC)
-   (match_operand:ALLX 0 "register_operand" "=r")
+   (match_operand:ALLI_2 0 "register_operand" "=r")
    ;; initial CRC
-   (match_operand:ALLX 1 "register_operand" "r")
+   (match_operand:ALLI_2 1 "register_operand" "r")
    ;; data
    (match_operand:ALLI 2 "register_operand" "r")
    ;; polynomial without leading 1
-   (match_operand:ALLX 3 "const_int_operand")]
+   (match_operand:ALLI_2 3 "const_int_operand")]
   ""
   {
     /* If the polynomial is the same as the polynomial of crc32c* instruction,
        put that instruction.  crc32c uses iSCSI polynomial.  */
     if (TARGET_CRC32 && INTVAL (operands[3]) == 0x1EDC6F41
-       && <ALLX:MODE>mode == SImode)
+       && <ALLI_2:MODE>mode == SImode
+       && <ALLI:MODE>mode != DImode)
       emit_insn (gen_aarch64_crc32c<ALLI:crc_data_type> (operands[0],
                                                         operands[1],
                                                         operands[2]));
     /* If the polynomial is the same as the polynomial of crc32* instruction,
        put that instruction.  crc32 uses HDLC etc.  polynomial.  */
     else if (TARGET_CRC32 && INTVAL (operands[3]) == 0x04C11DB7
-            && <ALLX:MODE>mode == SImode)
+            && <ALLI_2:MODE>mode == SImode
+            && <ALLI:MODE>mode != DImode)
       emit_insn (gen_aarch64_crc32<ALLI:crc_data_type> (operands[0],
                                                        operands[1],
                                                        operands[2]));
-    else if (TARGET_AES && <ALLI:sizen> <= <ALLX:sizen>)
-      aarch64_expand_reversed_crc_using_pmull (<ALLX:MODE>mode,
+    else if (TARGET_AES && <ALLI:sizen> <= <ALLI_2:sizen>)
+      aarch64_expand_reversed_crc_using_pmull (<ALLI_2:MODE>mode,
                                               <ALLI:MODE>mode,
                                               operands);
     else
@@ -5048,18 +5050,18 @@ (define_expand "crc_rev<ALLI:mode><ALLX:mode>4"
 )
 
 ;; Bit-forward CRC
-(define_expand "crc<ALLI:mode><ALLX:mode>4"
+(define_expand "crc<ALLI:mode><ALLI_2:mode>4"
   [;; return value (calculated CRC)
-   (match_operand:ALLX 0 "register_operand" "=r")
+   (match_operand:ALLI_2 0 "register_operand" "=r")
    ;; initial CRC
-   (match_operand:ALLX 1 "register_operand" "r")
+   (match_operand:ALLI_2 1 "register_operand" "r")
    ;; data
-   (match_operand:ALLI 2 "register_operand" "r")
+   (match_operand:ALLI   2 "register_operand" "r")
    ;; polynomial without leading 1
-   (match_operand:ALLX 3 "const_int_operand")]
-  "TARGET_AES && <ALLI:sizen> <= <ALLX:sizen>"
+   (match_operand:ALLI_2 3 "const_int_operand")]
+  "TARGET_AES && <ALLI:sizen> <= <ALLI_2:sizen>"
   {
-    aarch64_expand_crc_using_pmull (<ALLX:MODE>mode, <ALLI:MODE>mode,
+    aarch64_expand_crc_using_pmull (<ALLI_2:MODE>mode, <ALLI:MODE>mode,
                                    operands);
     DONE;
   }
diff --git a/gcc/config/aarch64/iterators.md b/gcc/config/aarch64/iterators.md
index f38a39fd6e3..ad5252fb8a3 100644
--- a/gcc/config/aarch64/iterators.md
+++ b/gcc/config/aarch64/iterators.md
@@ -47,6 +47,9 @@ (define_mode_iterator V4SF_ONLY [V4SF])
 ;; Iterator for all integer modes (up to 64-bit)
 (define_mode_iterator ALLI [QI HI SI DI])
 
+;; Iterator for all integer modes (up to 64-bit) duplicated
+(define_mode_iterator ALLI_2 [QI HI SI DI])
+
 ;; Iterator for all integer modes (up to 128-bit)
 (define_mode_iterator ALLI_TI [QI HI SI DI TI])
 
diff --git a/gcc/testsuite/gcc.target/aarch64/crc-34-pmul.c 
b/gcc/testsuite/gcc.target/aarch64/crc-34-pmul.c
new file mode 100644
index 00000000000..374b81b5335
--- /dev/null
+++ b/gcc/testsuite/gcc.target/aarch64/crc-34-pmul.c
@@ -0,0 +1,9 @@
+/* { dg-do run } */
+/* { dg-options "-march=armv8-a+crypto -O2 -fdump-rtl-dfinish -fdump-tree-crc 
-fdisable-tree-phiopt2 -fdisable-tree-phiopt3" } */
+/* { dg-skip-if "" { *-*-* } { "-flto"} } */
+
+#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"} } */
+/* { dg-final { scan-rtl-dump "pmull" "dfinish"} } */
diff --git a/gcc/testsuite/gcc.target/aarch64/crc-35-pmul.c 
b/gcc/testsuite/gcc.target/aarch64/crc-35-pmul.c
new file mode 100644
index 00000000000..437356b9b9f
--- /dev/null
+++ b/gcc/testsuite/gcc.target/aarch64/crc-35-pmul.c
@@ -0,0 +1,9 @@
+/* { dg-do run } */
+/* { dg-options "-march=armv8-a+crypto -O2 -fdump-rtl-dfinish -fdump-tree-crc 
-fdisable-tree-phiopt2 -fdisable-tree-phiopt3" } */
+/* { dg-skip-if "" { *-*-* } { "-flto"} } */
+
+#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 "pmull" "dfinish"} } */
diff --git a/gcc/testsuite/gcc.target/aarch64/crc-36-pmul.c 
b/gcc/testsuite/gcc.target/aarch64/crc-36-pmul.c
new file mode 100644
index 00000000000..a631c0a73cc
--- /dev/null
+++ b/gcc/testsuite/gcc.target/aarch64/crc-36-pmul.c
@@ -0,0 +1,9 @@
+/* { dg-do run } */
+/* { dg-options "-march=armv8-a+crypto -O2 -fdump-rtl-dfinish -fdump-tree-crc 
-fdisable-tree-phiopt2 -fdisable-tree-phiopt3" } */
+/* { dg-skip-if "" { *-*-* } { "-flto"} } */
+
+#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 "pmull" "dfinish"} } */
diff --git a/gcc/testsuite/gcc.target/aarch64/crc-37-pmul.c 
b/gcc/testsuite/gcc.target/aarch64/crc-37-pmul.c
new file mode 100644
index 00000000000..16b9e6c039d
--- /dev/null
+++ b/gcc/testsuite/gcc.target/aarch64/crc-37-pmul.c
@@ -0,0 +1,9 @@
+/* { dg-do run } */
+/* { dg-options "-march=armv8-a+crypto -O2 -fdump-rtl-dfinish -fdump-tree-crc 
-fdisable-tree-phiopt2 -fdisable-tree-phiopt3" } */
+/* { dg-skip-if "" { *-*-* } { "-flto"} } */
+
+#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 "pmull" "dfinish"} } */
diff --git a/gcc/testsuite/gcc.target/aarch64/crc-38-pmul.c 
b/gcc/testsuite/gcc.target/aarch64/crc-38-pmul.c
new file mode 100644
index 00000000000..d447b49586d
--- /dev/null
+++ b/gcc/testsuite/gcc.target/aarch64/crc-38-pmul.c
@@ -0,0 +1,9 @@
+/* { dg-do run } */
+/* { dg-options "-march=armv8-a+crypto -O2 -fdump-rtl-dfinish -fdump-tree-crc 
-fdisable-tree-phiopt2 -fdisable-tree-phiopt3" } */
+/* { dg-skip-if "" { *-*-* } { "-flto"} } */
+
+#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"} } */
+/* { dg-final { scan-rtl-dump "pmull" "dfinish"} } */
diff --git a/gcc/testsuite/gcc.target/aarch64/crc-39-pmul.c 
b/gcc/testsuite/gcc.target/aarch64/crc-39-pmul.c
new file mode 100644
index 00000000000..9cf59083e47
--- /dev/null
+++ b/gcc/testsuite/gcc.target/aarch64/crc-39-pmul.c
@@ -0,0 +1,9 @@
+/* { dg-do run } */
+/* { dg-options "-march=armv8-a+crypto -O2 -fdump-rtl-dfinish -fdump-tree-crc 
-fdisable-tree-phiopt2 -fdisable-tree-phiopt3" } */
+/* { dg-skip-if "" { *-*-* } { "-flto"} } */
+
+#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 "pmull" "dfinish"} } */
diff --git a/gcc/testsuite/gcc.target/aarch64/crc-40-pmul.c 
b/gcc/testsuite/gcc.target/aarch64/crc-40-pmul.c
new file mode 100644
index 00000000000..72d806469a4
--- /dev/null
+++ b/gcc/testsuite/gcc.target/aarch64/crc-40-pmul.c
@@ -0,0 +1,9 @@
+/* { dg-do run } */
+/* { dg-options "-march=armv8-a+crypto -O2 -fdump-rtl-dfinish -fdump-tree-crc 
-fdisable-tree-phiopt2 -fdisable-tree-phiopt3" } */
+/* { dg-skip-if "" { *-*-* } { "-flto"} } */
+
+#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 "pmull" "dfinish"} } */
diff --git a/gcc/testsuite/gcc.target/aarch64/crc-41-pmul.c 
b/gcc/testsuite/gcc.target/aarch64/crc-41-pmul.c
new file mode 100644
index 00000000000..e526651474d
--- /dev/null
+++ b/gcc/testsuite/gcc.target/aarch64/crc-41-pmul.c
@@ -0,0 +1,9 @@
+/* { dg-do run } */
+/* { dg-options "-march=armv8-a+crypto -O2 -fdump-rtl-dfinish -fdump-tree-crc 
-fdisable-tree-phiopt2 -fdisable-tree-phiopt3" } */
+/* { dg-skip-if "" { *-*-* } { "-flto"} } */
+
+#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 "pmull" "dfinish"} } */
-- 
2.55.0

Reply via email to