* [RFC/RFA][PATCH v2 03/12] RISC-V: Add CRC expander to generate faster CRC.
@ 2024-07-26 18:06 Mariam Arutunian
2024-08-25 17:41 ` Jeff Law
0 siblings, 1 reply; 4+ messages in thread
From: Mariam Arutunian @ 2024-07-26 18:06 UTC (permalink / raw)
To: GCC Patches
[-- Attachment #1.1: Type: text/plain, Size: 2887 bytes --]
If the target is ZBC or ZBKC, it uses clmul instruction for the CRC
calculation.
Otherwise, if the target is ZBKB, generates table-based CRC, but for
reversing inputs and the output uses bswap and brev8 instructions.
Add new tests to check CRC generation for ZBC, ZBKC and ZBKB targets.
gcc/
* expr.cc (reflect): New function.
(gf2n_poly_long_div_quotient): Likewise.
* expr.h (reflect): New function declaration.
(gf2n_poly_long_div_quotient): Likewise.
gcc/config/riscv/
* bitmanip.md (crc_rev<ANYI1:mode><ANYI:mode>4): New expander for
reversed CRC.
(crc<SUBX1:mode><SUBX:mode>4): New expander for bit-forward CRC.
(SUBX1, ANYI1): New iterators.
* riscv-protos.h (generate_reflecting_code_using_brev): New
function declaration.
(expand_crc_using_clmul): Likewise.
(expand_reversed_crc_using_clmul): Likewise.
* riscv.cc (generate_reflecting_code_using_brev): New function.
(expand_crc_using_clmul): Likewise.
(expand_reversed_crc_using_clmul): Likewise.
* riscv.md (UNSPEC_CRC, UNSPEC_CRC_REV): New unspecs.
gcc/testsuite/gcc.target/riscv/
* crc-1-zbc.c: New test.
* crc-1-zbc.c: Likewise.
* crc-10-zbc.c: Likewise.
* crc-10-zbkc.c: Likewise.
* crc-12-zbc.c: Likewise.
* crc-12-zbkc.c: Likewise.
* crc-13-zbc.c: Likewise.
* crc-13-zbkc.c: Likewise.
* crc-14-zbc.c: Likewise.
* crc-14-zbkc.c: Likewise.
* crc-17-zbc.c: Likewise.
* crc-17-zbkc.c: Likewise.
* crc-18-zbc.c: Likewise.
* crc-18-zbkc.c: Likewise.
* crc-21-zbc.c: Likewise.
* crc-21-zbkc.c: Likewise.
* crc-22-rv64-zbc.c: Likewise.
* crc-22-rv64-zbkb.c: Likewise.
* crc-22-rv64-zbkc.c: Likewise.
* crc-23-zbc.c: Likewise.
* crc-23-zbkc.c: Likewise.
* crc-4-zbc.c: Likewise.
* crc-4-zbkb.c: Likewise.
* crc-4-zbkc.c: Likewise.
* crc-5-zbc.c: Likewise.
* crc-5-zbkb.c: Likewise.
* crc-5-zbkc.c: Likewise.
* crc-6-zbc.c: Likewise.
* crc-6-zbkc.c: Likewise.
* crc-7-zbc.c: Likewise.
* crc-7-zbkc.c: Likewise.
* crc-8-zbc.c: Likewise.
* crc-8-zbkb.c: Likewise.
* crc-8-zbkc.c: Likewise.
* crc-9-zbc.c: Likewise.
* crc-9-zbkc.c: Likewise.
* crc-CCIT-data16-zbc.c: Likewise.
* crc-CCIT-data16-zbkc.c: Likewise.
* crc-CCIT-data8-zbc.c: Likewise.
* crc-CCIT-data8-zbkc.c: Likewise.
* crc-coremark-16bitdata-zbc.c: Likewise.
* crc-coremark-16bitdata-zbkc.c: Likewise.
Signed-off-by: Mariam Arutunian <mariamarutunian@gmail.com>
[-- Attachment #2: 0003-RISC-V-Add-CRC-expander-to-generate-faster-CRC.patch --]
[-- Type: text/x-patch, Size: 46132 bytes --]
diff --git a/gcc/config/riscv/bitmanip.md b/gcc/config/riscv/bitmanip.md
index 8769a6b818b..9683ac48ef6 100644
--- a/gcc/config/riscv/bitmanip.md
+++ b/gcc/config/riscv/bitmanip.md
@@ -973,3 +973,67 @@
"TARGET_ZBC"
"clmulr\t%0,%1,%2"
[(set_attr "type" "clmul")])
+
+
+;; Iterator for hardware integer modes narrower than XLEN, same as SUBX
+(define_mode_iterator SUBX1 [QI HI (SI "TARGET_64BIT")])
+
+;; Iterator for hardware integer modes narrower than XLEN, same as ANYI
+(define_mode_iterator ANYI1 [QI HI SI (DI "TARGET_64BIT")])
+
+;; Reversed CRC 8, 16, 32 for TARGET_64
+(define_expand "crc_rev<ANYI1:mode><ANYI:mode>4"
+ ;; return value (calculated CRC)
+ [(set (match_operand:ANYI 0 "register_operand" "=r")
+ ;; initial CRC
+ (unspec:ANYI [(match_operand:ANYI 1 "register_operand" "r")
+ ;; data
+ (match_operand:ANYI1 2 "register_operand" "r")
+ ;; polynomial without leading 1
+ (match_operand:ANYI 3)]
+ UNSPEC_CRC_REV))]
+ /* We don't support the case when data's size is bigger than CRC's size. */
+ "(((TARGET_ZBKC || TARGET_ZBC) && <ANYI:MODE>mode < word_mode)
+ || TARGET_ZBKB) && <ANYI:MODE>mode >= <ANYI1:MODE>mode"
+{
+ /* If we have the ZBC or ZBKC extension (ie, clmul) and
+ it is possible to store the quotient within a single variable
+ (E.g. CRC64's quotient may need 65 bits,
+ we can't keep it in 64 bit variable.)
+ then use clmul instruction to implement the CRC,
+ otherwise (TARGET_ZBKB) generate table based using brev. */
+ if ((TARGET_ZBKC || TARGET_ZBC) && <ANYI:MODE>mode < word_mode)
+ expand_reversed_crc_using_clmul (<ANYI:MODE>mode, <ANYI1:MODE>mode,
+ operands);
+ else
+ /* Generate table-based CRC.
+ To reflect values use brev and bswap instructions. */
+ expand_reversed_crc_table_based (operands[0], operands[1],
+ operands[2], operands[3],
+ GET_MODE (operands[2]),
+ generate_reflecting_code_using_brev);
+ DONE;
+})
+
+;; CRC 8, 16, (32 for TARGET_64)
+(define_expand "crc<SUBX1:mode><SUBX:mode>4"
+ ;; return value (calculated CRC)
+ [(set (match_operand:SUBX 0 "register_operand" "=r")
+ ;; initial CRC
+ (unspec:SUBX [(match_operand:SUBX 1 "register_operand" "r")
+ ;; data
+ (match_operand:SUBX1 2 "register_operand" "r")
+ ;; polynomial without leading 1
+ (match_operand:SUBX 3)]
+ UNSPEC_CRC))]
+ /* We don't support the case when data's size is bigger than CRC's size. */
+ "(TARGET_ZBKC || TARGET_ZBC) && <SUBX:MODE>mode >= <SUBX1:MODE>mode"
+{
+ /* If we have the ZBC or ZBKC extension (ie, clmul) and
+ it is possible to store the quotient within a single variable
+ (E.g. CRC64's quotient may need 65 bits,
+ we can't keep it in 64 bit variable.)
+ then use clmul instruction to implement the CRC. */
+ expand_crc_using_clmul (<SUBX:MODE>mode, <SUBX1:MODE>mode, operands);
+ DONE;
+})
diff --git a/gcc/config/riscv/riscv-protos.h b/gcc/config/riscv/riscv-protos.h
index 0704968561b..9cac9b9ae7f 100644
--- a/gcc/config/riscv/riscv-protos.h
+++ b/gcc/config/riscv/riscv-protos.h
@@ -169,6 +169,9 @@ extern enum memmodel riscv_union_memmodels (enum memmodel, enum memmodel);
extern bool riscv_reg_frame_related (rtx);
extern void riscv_split_sum_of_two_s12 (HOST_WIDE_INT, HOST_WIDE_INT *,
HOST_WIDE_INT *);
+extern void generate_reflecting_code_using_brev (rtx *, int);
+extern void expand_crc_using_clmul (scalar_mode, scalar_mode, rtx *);
+extern void expand_reversed_crc_using_clmul (scalar_mode, scalar_mode, rtx *);
/* Routines implemented in riscv-c.cc. */
void riscv_cpu_cpp_builtins (cpp_reader *);
diff --git a/gcc/config/riscv/riscv.cc b/gcc/config/riscv/riscv.cc
index 85df5b7ab49..ccfd57c1da4 100644
--- a/gcc/config/riscv/riscv.cc
+++ b/gcc/config/riscv/riscv.cc
@@ -11415,6 +11415,158 @@ riscv_expand_usadd (rtx dest, rtx x, rtx y)
emit_move_insn (dest, gen_lowpart (mode, xmode_dest));
}
+/* Generate instruction sequence
+ which reflects the value of the OP using bswap and brev8 instructions.
+ OP's mode may be less than word_mode, to get the correct number,
+ after reflecting we shift right the value by SHIFT_VAL.
+ E.g. we have 1111 0001, after reflection (target 32-bit) we will get
+ 1000 1111 0000 0000, if we shift-out 16 bits,
+ we will get the desired one: 1000 1111. */
+
+void
+generate_reflecting_code_using_brev (rtx *op, int shift_val)
+{
+
+ riscv_expand_op (BSWAP, word_mode, *op, *op, *op);
+ riscv_expand_op (LSHIFTRT, word_mode, *op, *op,
+ gen_int_mode (shift_val, word_mode));
+ if (TARGET_64BIT)
+ emit_insn (gen_riscv_brev8_di (*op, *op));
+ else
+ emit_insn (gen_riscv_brev8_si (*op, *op));
+}
+
+
+/* Generate assembly to calculate CRC using clmul instruction.
+ The following code will be generated when the CRC and data sizes are equal:
+ li a4,quotient
+ li a5,polynomial
+ xor a0,a1,a0
+ clmul a0,a0,a4
+ srli a0,a0,crc_size
+ clmul a0,a0,a5
+ slli a0,a0,word_mode_size - crc_size
+ srli a0,a0,word_mode_size - crc_size
+ ret
+ crc_size may be 8, 16, 32.
+ Some instructions will be added for the cases when CRC's size is larger than
+ data's size.
+ OPERANDS[1] is input CRC,
+ OPERANDS[2] is data (message),
+ OPERANDS[3] is the polynomial without the leading 1. */
+
+void
+expand_crc_using_clmul (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]));
+ unsigned short crc_size = GET_MODE_BITSIZE (crc_mode);
+ gcc_assert (crc_size <= 32);
+ unsigned short data_size = GET_MODE_BITSIZE (data_mode);
+
+ /* Calculate the quotient. */
+ unsigned HOST_WIDE_INT
+ q = gf2n_poly_long_div_quotient (UINTVAL (operands[3]), crc_size);
+
+ rtx crc_extended = gen_rtx_ZERO_EXTEND (word_mode, operands[1]);
+ rtx crc = gen_reg_rtx (word_mode);
+ if (crc_size > data_size)
+ riscv_expand_op (LSHIFTRT, word_mode, crc, crc_extended,
+ gen_int_mode (crc_size - data_size, word_mode));
+ else
+ crc = gen_rtx_ZERO_EXTEND (word_mode, operands[1]);
+ rtx t0 = gen_reg_rtx (word_mode);
+ riscv_emit_move (t0, gen_int_mode (q, word_mode));
+ rtx t1 = gen_reg_rtx (word_mode);
+ riscv_emit_move (t1, operands[3]);
+
+ rtx a0 = gen_reg_rtx (word_mode);
+ rtx data = gen_rtx_ZERO_EXTEND (word_mode, operands[2]);
+ riscv_expand_op (XOR, word_mode, a0, crc, data);
+
+ if (TARGET_64BIT)
+ emit_insn (gen_riscv_clmul_di (a0, a0, t0));
+ else
+ emit_insn (gen_riscv_clmul_si (a0, a0, t0));
+
+ riscv_expand_op (LSHIFTRT, word_mode, a0, a0,
+ gen_int_mode (crc_size, word_mode));
+ if (TARGET_64BIT)
+ emit_insn (gen_riscv_clmul_di (a0, a0, t1));
+ else
+ emit_insn (gen_riscv_clmul_si (a0, a0, t1));
+
+ if (crc_size > data_size)
+ {
+ rtx crc_part = gen_reg_rtx (word_mode);
+ riscv_expand_op (ASHIFT, word_mode, crc_part, operands[1],
+ gen_int_mode (data_size, word_mode));
+ riscv_expand_op (XOR, word_mode, a0, a0, crc_part);
+ }
+ riscv_emit_move (operands[0], gen_lowpart (crc_mode, a0));
+}
+
+/* Generate assembly to calculate reversed CRC using clmul instruction.
+ OPERANDS[1] is input CRC,
+ OPERANDS[2] is data (message),
+ OPERANDS[3] is the polynomial without the leading 1. */
+
+void
+expand_reversed_crc_using_clmul (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]));
+ unsigned short crc_size = GET_MODE_BITSIZE (crc_mode);
+ gcc_assert (crc_size <= 32);
+ unsigned short data_size = GET_MODE_BITSIZE (data_mode);
+
+ /* Calculate the quotient. */
+ unsigned HOST_WIDE_INT
+ q = gf2n_poly_long_div_quotient (UINTVAL (operands[3]), crc_size);
+ /* Reflect the calculated quotient. */
+ q = reflect (q);
+ rtx t0 = gen_reg_rtx (word_mode);
+ riscv_emit_move (t0, gen_int_mode (q >> (data_size - 4), word_mode));
+
+ /* Reflect the polynomial. */
+ unsigned HOST_WIDE_INT polynomial = reflect (UINTVAL (operands[3]));
+ rtx t1 = gen_reg_rtx (word_mode);
+ riscv_emit_move (t1, gen_int_mode (polynomial << 1, word_mode));
+
+ rtx crc = gen_rtx_ZERO_EXTEND (word_mode, operands[1]);
+ rtx data = gen_rtx_ZERO_EXTEND (word_mode, operands[2]);
+ rtx a0 = gen_reg_rtx (word_mode);
+ riscv_expand_op (XOR, word_mode, a0, crc, data);
+
+ if (TARGET_64BIT)
+ emit_insn (gen_riscv_clmul_di (a0, a0, t0));
+ else
+ emit_insn (gen_riscv_clmul_si (a0, a0, t0));
+ rtx num_shift = gen_int_mode (GET_MODE_BITSIZE (word_mode) - crc_size - 3,
+ word_mode);
+ riscv_expand_op (ASHIFT, word_mode, a0, a0, num_shift);
+
+ if (TARGET_64BIT)
+ emit_insn (gen_riscv_clmulh_di (a0, a0, t1));
+ else
+ emit_insn (gen_riscv_clmulh_si (a0, a0, t1));
+
+ if (crc_size > data_size)
+ {
+ rtx data_size_shift = gen_int_mode (data_size, word_mode);
+ rtx crc_part = gen_reg_rtx (word_mode);
+ riscv_expand_op (LSHIFTRT, word_mode, crc_part, crc, data_size_shift);
+ riscv_expand_op (XOR, word_mode, a0, a0, crc_part);
+ }
+
+ riscv_emit_move (operands[0], gen_lowpart (crc_mode, a0));
+
+}
+
/* Initialize the GCC target structure. */
#undef TARGET_ASM_ALIGNED_HI_OP
#define TARGET_ASM_ALIGNED_HI_OP "\t.half\t"
diff --git a/gcc/config/riscv/riscv.md b/gcc/config/riscv/riscv.md
index 78c16adee98..1b216b01766 100644
--- a/gcc/config/riscv/riscv.md
+++ b/gcc/config/riscv/riscv.md
@@ -92,6 +92,10 @@
;; XTheadFmv moves
UNSPEC_XTHEADFMV
UNSPEC_XTHEADFMV_HW
+
+ ;; CRC unspecs
+ UNSPEC_CRC
+ UNSPEC_CRC_REV
])
(define_c_enum "unspecv" [
diff --git a/gcc/expr.cc b/gcc/expr.cc
index c9a049aeecc..57b12784895 100644
--- a/gcc/expr.cc
+++ b/gcc/expr.cc
@@ -14092,6 +14092,52 @@ int_expr_size (const_tree exp)
return tree_to_shwi (size);
}
+/* Reflect the VALUE.
+ If we have 0000 0000 0101 0111, we will get 1110 1010. */
+
+unsigned HOST_WIDE_INT
+reflect (unsigned HOST_WIDE_INT value)
+{
+ unsigned HOST_WIDE_INT reflectedValue = 0;
+ /* Looping through each bit in the byte. */
+ for (size_t i = 0; value || !(i == 8 || i == 16 || i == 32 || i == 64); i++)
+ {
+ reflectedValue <<= 1;
+ /* Add the least significant bit of the original value to the
+ reflected value. */
+ reflectedValue |= (value & 1);
+ value >>= 1;
+ }
+ return reflectedValue;
+}
+
+/* Return the quotient of polynomial long division of x^2N by POLYNOMIAL
+ in GF (2^N).
+ Author: Richard Sandiford <richard.sandiford@arm.com> */
+
+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);
+
+ /* Perform a division step for the x^2N coefficient. At this point the
+ quotient and remainder have N implicit trailing zeros. */
+ unsigned HOST_WIDE_INT quotient = 1;
+ unsigned HOST_WIDE_INT remainder = polynomial;
+
+ /* Process the coefficients for x^(2N-1) down to x^N, with each step
+ reducing the number of implicit trailing zeros by one. */
+ for (unsigned int i = 0; i < n; ++i)
+ {
+ bool coeff = remainder & (HOST_WIDE_INT_1U << (n - 1));
+ quotient = (quotient << 1) | coeff;
+ remainder = (remainder << 1) ^ (coeff ? polynomial : 0);
+ }
+ return quotient;
+}
+
/* Calculate CRC for the initial CRC and given POLYNOMIAL.
CRC_BITS is CRC size. */
diff --git a/gcc/expr.h b/gcc/expr.h
index 74634d22777..114f1e2fb7a 100644
--- a/gcc/expr.h
+++ b/gcc/expr.h
@@ -374,6 +374,15 @@ extern rtx expr_size (tree);
extern bool mem_ref_refers_to_non_mem_p (tree);
extern bool non_mem_decl_p (tree);
+/* Reflect the VALUE.
+ If we have 0000 0000 0101 0111, we will get 1110 1010. */
+extern unsigned HOST_WIDE_INT reflect (unsigned HOST_WIDE_INT);
+
+/* Return the quotient of the polynomial long division of x^2N by POLYNOMIAL
+ in GF (2^N). */
+extern unsigned HOST_WIDE_INT
+gf2n_poly_long_div_quotient (unsigned HOST_WIDE_INT, unsigned short);
+
/* Generate table-based CRC. */
extern void generate_reflecting_code_standard (rtx *, int);
extern void expand_crc_table_based (rtx, rtx, rtx, rtx, machine_mode);
diff --git a/gcc/testsuite/gcc.target/riscv/crc-1-zbc.c b/gcc/testsuite/gcc.target/riscv/crc-1-zbc.c
new file mode 100644
index 00000000000..a554ff97bb9
--- /dev/null
+++ b/gcc/testsuite/gcc.target/riscv/crc-1-zbc.c
@@ -0,0 +1,11 @@
+/* { dg-do run } */
+/* { dg-options "-fdump-tree-crc -fdump-rtl-dfinish -fdisable-tree-phiopt2 -fdisable-tree-phiopt3" } */
+/* { dg-additional-options "-march=rv64gc_zbc" { target { rv64 } } } */
+/* { dg-additional-options "-march=rv32gc_zbc" { target { rv32 } } } */
+/* { dg-skip-if "" { *-*-* } { "-O0" "-O1" "-Os" "-Oz" "-Og" "-flto"} } */
+
+#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 "clmul" "dfinish"} } */
\ No newline at end of file
diff --git a/gcc/testsuite/gcc.target/riscv/crc-1-zbkc.c b/gcc/testsuite/gcc.target/riscv/crc-1-zbkc.c
new file mode 100644
index 00000000000..861dd982e9e
--- /dev/null
+++ b/gcc/testsuite/gcc.target/riscv/crc-1-zbkc.c
@@ -0,0 +1,11 @@
+/* { dg-do run } */
+/* { dg-options "-fdump-tree-crc -fdump-rtl-dfinish -fdisable-tree-phiopt2 -fdisable-tree-phiopt3" } */
+/* { dg-additional-options "-march=rv64gc_zbkc" { target { rv64 } } } */
+/* { dg-additional-options "-march=rv32gc_zbkc" { target { rv32 } } } */
+/* { dg-skip-if "" { *-*-* } { "-O0" "-O1" "-Os" "-Oz" "-Og" "-flto"} } */
+
+#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 "clmul" "dfinish"} } */
\ No newline at end of file
diff --git a/gcc/testsuite/gcc.target/riscv/crc-10-zbc.c b/gcc/testsuite/gcc.target/riscv/crc-10-zbc.c
new file mode 100644
index 00000000000..1778315efb9
--- /dev/null
+++ b/gcc/testsuite/gcc.target/riscv/crc-10-zbc.c
@@ -0,0 +1,11 @@
+/* { dg-do run } */
+/* { dg-options "-fdump-tree-crc -fdump-rtl-dfinish " } */
+/* { dg-additional-options "-march=rv64gc_zbc" { target { rv64 } } } */
+/* { dg-additional-options "-march=rv32gc_zbc" { target { rv32 } } } */
+/* { dg-skip-if "" { *-*-* } { "-O0" "-O1" "-Os" "-Oz" "-Og" "-flto"} } */
+
+#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 "clmul" "dfinish"} } */
diff --git a/gcc/testsuite/gcc.target/riscv/crc-10-zbkc.c b/gcc/testsuite/gcc.target/riscv/crc-10-zbkc.c
new file mode 100644
index 00000000000..587a8d8bb80
--- /dev/null
+++ b/gcc/testsuite/gcc.target/riscv/crc-10-zbkc.c
@@ -0,0 +1,11 @@
+/* { dg-do run } */
+/* { dg-options "-fdump-tree-crc -fdump-rtl-dfinish " } */
+/* { dg-additional-options "-march=rv64gc_zbkc" { target { rv64 } } } */
+/* { dg-additional-options "-march=rv32gc_zbkc" { target { rv32 } } } */
+/* { dg-skip-if "" { *-*-* } { "-O0" "-O1" "-Os" "-Oz" "-Og" "-flto"} } */
+
+#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 "clmul" "dfinish"} } */
diff --git a/gcc/testsuite/gcc.target/riscv/crc-12-zbc.c b/gcc/testsuite/gcc.target/riscv/crc-12-zbc.c
new file mode 100644
index 00000000000..a096e529019
--- /dev/null
+++ b/gcc/testsuite/gcc.target/riscv/crc-12-zbc.c
@@ -0,0 +1,11 @@
+/* { dg-do run } */
+/* { dg-options "-fdump-tree-crc -fdump-rtl-dfinish -fdisable-tree-phiopt2 -fdisable-tree-phiopt3" } */
+/* { dg-additional-options "-march=rv64gc_zbc" { target { rv64 } } } */
+/* { dg-additional-options "-march=rv32gc_zbc" { target { rv32 } } } */
+/* { dg-skip-if "" { *-*-* } { "-O0" "-O1" "-Os" "-Oz" "-Og" "-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 "clmul" "dfinish"} } */
diff --git a/gcc/testsuite/gcc.target/riscv/crc-12-zbkc.c b/gcc/testsuite/gcc.target/riscv/crc-12-zbkc.c
new file mode 100644
index 00000000000..4ea76d2b923
--- /dev/null
+++ b/gcc/testsuite/gcc.target/riscv/crc-12-zbkc.c
@@ -0,0 +1,11 @@
+/* { dg-do run } */
+/* { dg-options "-fdump-tree-crc -fdump-rtl-dfinish -fdisable-tree-phiopt2 -fdisable-tree-phiopt3" } */
+/* { dg-additional-options "-march=rv64gc_zbkc" { target { rv64 } } } */
+/* { dg-additional-options "-march=rv32gc_zbkc" { target { rv32 } } } */
+/* { dg-skip-if "" { *-*-* } { "-O0" "-O1" "-Os" "-Oz" "-Og" "-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 "clmul" "dfinish"} } */
diff --git a/gcc/testsuite/gcc.target/riscv/crc-13-zbc.c b/gcc/testsuite/gcc.target/riscv/crc-13-zbc.c
new file mode 100644
index 00000000000..dbcb66a8379
--- /dev/null
+++ b/gcc/testsuite/gcc.target/riscv/crc-13-zbc.c
@@ -0,0 +1,11 @@
+/* { dg-do run } */
+/* { dg-options "-fdump-tree-crc -fdump-rtl-dfinish " } */
+/* { dg-additional-options "-march=rv64gc_zbc" { target { rv64 } } } */
+/* { dg-additional-options "-march=rv32gc_zbc" { target { rv32 } } } */
+/* { dg-skip-if "" { *-*-* } { "-O0" "-O1" "-Os" "-Oz" "-Og" "-flto"} } */
+
+#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 "clmul" "dfinish"} } */
diff --git a/gcc/testsuite/gcc.target/riscv/crc-13-zbkc.c b/gcc/testsuite/gcc.target/riscv/crc-13-zbkc.c
new file mode 100644
index 00000000000..f545f3303ee
--- /dev/null
+++ b/gcc/testsuite/gcc.target/riscv/crc-13-zbkc.c
@@ -0,0 +1,11 @@
+/* { dg-do run } */
+/* { dg-options "-fdump-tree-crc -fdump-rtl-dfinish " } */
+/* { dg-additional-options "-march=rv64gc_zbkc" { target { rv64 } } } */
+/* { dg-additional-options "-march=rv32gc_zbkc" { target { rv32 } } } */
+/* { dg-skip-if "" { *-*-* } { "-O0" "-O1" "-Os" "-Oz" "-Og" "-flto"} } */
+
+#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 "clmul" "dfinish"} } */
diff --git a/gcc/testsuite/gcc.target/riscv/crc-14-zbc.c b/gcc/testsuite/gcc.target/riscv/crc-14-zbc.c
new file mode 100644
index 00000000000..6bdf04406c2
--- /dev/null
+++ b/gcc/testsuite/gcc.target/riscv/crc-14-zbc.c
@@ -0,0 +1,11 @@
+/* { dg-do run } */
+/* { dg-options "-fdump-tree-crc -fdump-rtl-dfinish " } */
+/* { dg-additional-options "-march=rv64gc_zbc" { target { rv64 } } } */
+/* { dg-additional-options "-march=rv32gc_zbc" { target { rv32 } } } */
+/* { dg-skip-if "" { *-*-* } { "-O0" "-O1" "-Os" "-Oz" "-Og" "-flto"} } */
+
+#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 "clmul" "dfinish"} } */
diff --git a/gcc/testsuite/gcc.target/riscv/crc-14-zbkc.c b/gcc/testsuite/gcc.target/riscv/crc-14-zbkc.c
new file mode 100644
index 00000000000..2a0211ff0b0
--- /dev/null
+++ b/gcc/testsuite/gcc.target/riscv/crc-14-zbkc.c
@@ -0,0 +1,11 @@
+/* { dg-do run } */
+/* { dg-options "-fdump-tree-crc -fdump-rtl-dfinish " } */
+/* { dg-additional-options "-march=rv64gc_zbkc" { target { rv64 } } } */
+/* { dg-additional-options "-march=rv32gc_zbkc" { target { rv32 } } } */
+/* { dg-skip-if "" { *-*-* } { "-O0" "-O1" "-Os" "-Oz" "-Og" "-flto"} } */
+
+#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 "clmul" "dfinish"} } */
diff --git a/gcc/testsuite/gcc.target/riscv/crc-17-zbc.c b/gcc/testsuite/gcc.target/riscv/crc-17-zbc.c
new file mode 100644
index 00000000000..8dc16a87ce1
--- /dev/null
+++ b/gcc/testsuite/gcc.target/riscv/crc-17-zbc.c
@@ -0,0 +1,11 @@
+/* { dg-do run } */
+/* { dg-options "-fdump-tree-crc -fdump-rtl-dfinish " } */
+/* { dg-additional-options "-march=rv64gc_zbc" { target { rv64 } } } */
+/* { dg-additional-options "-march=rv32gc_zbc" { target { rv32 } } } */
+/* { dg-skip-if "" { *-*-* } { "-O0" "-O1" "-Os" "-Oz" "-Og" "-flto"} } */
+
+#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 "clmul" "dfinish"} } */
diff --git a/gcc/testsuite/gcc.target/riscv/crc-17-zbkc.c b/gcc/testsuite/gcc.target/riscv/crc-17-zbkc.c
new file mode 100644
index 00000000000..3099385924d
--- /dev/null
+++ b/gcc/testsuite/gcc.target/riscv/crc-17-zbkc.c
@@ -0,0 +1,11 @@
+/* { dg-do run } */
+/* { dg-options "-fdump-tree-crc -fdump-rtl-dfinish " } */
+/* { dg-additional-options "-march=rv64gc_zbkc" { target { rv64 } } } */
+/* { dg-additional-options "-march=rv32gc_zbkc" { target { rv32 } } } */
+/* { dg-skip-if "" { *-*-* } { "-O0" "-O1" "-Os" "-Oz" "-Og" "-flto"} } */
+
+#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 "clmul" "dfinish"} } */
diff --git a/gcc/testsuite/gcc.target/riscv/crc-18-zbc.c b/gcc/testsuite/gcc.target/riscv/crc-18-zbc.c
new file mode 100644
index 00000000000..bd239926d8e
--- /dev/null
+++ b/gcc/testsuite/gcc.target/riscv/crc-18-zbc.c
@@ -0,0 +1,11 @@
+/* { dg-do run } */
+/* { dg-options "-fdump-tree-crc -fdump-rtl-dfinish " } */
+/* { dg-additional-options "-march=rv64gc_zbc" { target { rv64 } } } */
+/* { dg-additional-options "-march=rv32gc_zbc" { target { rv32 } } } */
+/* { dg-skip-if "" { *-*-* } { "-O0" "-O1" "-Os" "-Oz" "-Og" "-flto"} } */
+
+#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 "clmul" "dfinish"} } */
diff --git a/gcc/testsuite/gcc.target/riscv/crc-18-zbkc.c b/gcc/testsuite/gcc.target/riscv/crc-18-zbkc.c
new file mode 100644
index 00000000000..856d0b59441
--- /dev/null
+++ b/gcc/testsuite/gcc.target/riscv/crc-18-zbkc.c
@@ -0,0 +1,11 @@
+/* { dg-do run } */
+/* { dg-options "-fdump-tree-crc -fdump-rtl-dfinish " } */
+/* { dg-additional-options "-march=rv64gc_zbkc" { target { rv64 } } } */
+/* { dg-additional-options "-march=rv32gc_zbkc" { target { rv32 } } } */
+/* { dg-skip-if "" { *-*-* } { "-O0" "-O1" "-Os" "-Oz" "-Og" "-flto"} } */
+
+#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 "clmul" "dfinish"} } */
diff --git a/gcc/testsuite/gcc.target/riscv/crc-21-rv64-zbc.c b/gcc/testsuite/gcc.target/riscv/crc-21-rv64-zbc.c
new file mode 100644
index 00000000000..f4adcde2f7f
--- /dev/null
+++ b/gcc/testsuite/gcc.target/riscv/crc-21-rv64-zbc.c
@@ -0,0 +1,9 @@
+/* { dg-do run { target { riscv64*-*-* } } } */
+/* { dg-options "-fdump-tree-crc -fdump-rtl-dfinish -march=rv64gc_zbc" } */
+/* { dg-skip-if "" { *-*-* } { "-O0" "-O1" "-Os" "-Oz" "-Og" "-flto"} } */
+
+#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 "clmul" "dfinish"} } */
diff --git a/gcc/testsuite/gcc.target/riscv/crc-21-rv64-zbkc.c b/gcc/testsuite/gcc.target/riscv/crc-21-rv64-zbkc.c
new file mode 100644
index 00000000000..4f0b44e9624
--- /dev/null
+++ b/gcc/testsuite/gcc.target/riscv/crc-21-rv64-zbkc.c
@@ -0,0 +1,9 @@
+/* { dg-do run { target { riscv64*-*-* } } } */
+/* { dg-options "-fdump-tree-crc -fdump-rtl-dfinish -march=rv64gc_zbkc" } */
+/* { dg-skip-if "" { *-*-* } { "-O0" "-O1" "-Os" "-Oz" "-Og" "-flto"} } */
+
+#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 "clmul" "dfinish"} } */
diff --git a/gcc/testsuite/gcc.target/riscv/crc-22-zbc.c b/gcc/testsuite/gcc.target/riscv/crc-22-zbc.c
new file mode 100644
index 00000000000..295834e0ebf
--- /dev/null
+++ b/gcc/testsuite/gcc.target/riscv/crc-22-zbc.c
@@ -0,0 +1,11 @@
+/* { dg-do run } */
+/* { dg-options "-fdump-tree-crc -fdump-rtl-dfinish " } */
+/* { dg-additional-options "-march=rv64gc_zbc" { target { rv64 } } } */
+/* { dg-additional-options "-march=rv32gc_zbc" { target { rv32 } } } */
+/* { dg-skip-if "" { *-*-* } { "-O0" "-O1" "-Os" "-Oz" "-Og" "-flto"} } */
+
+#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 "clmul" "dfinish"} } */
diff --git a/gcc/testsuite/gcc.target/riscv/crc-22-zbkb.c b/gcc/testsuite/gcc.target/riscv/crc-22-zbkb.c
new file mode 100644
index 00000000000..9c89219e169
--- /dev/null
+++ b/gcc/testsuite/gcc.target/riscv/crc-22-zbkb.c
@@ -0,0 +1,11 @@
+/* { dg-do run } */
+/* { dg-options "-fdump-tree-crc-details" } */
+/* { dg-additional-options "-march=rv64gc_zbkb" { target { rv64 } } } */
+/* { dg-additional-options "-march=rv32gc_zbkb" { target { rv32 } } } */
+/* { dg-skip-if "" { *-*-* } { "-O0" "-O1" "-Os" "-Oz" "-Og" "-flto"} } */
+
+#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 "clmul" "dfinish"} } */
diff --git a/gcc/testsuite/gcc.target/riscv/crc-22-zbkc.c b/gcc/testsuite/gcc.target/riscv/crc-22-zbkc.c
new file mode 100644
index 00000000000..506af22169f
--- /dev/null
+++ b/gcc/testsuite/gcc.target/riscv/crc-22-zbkc.c
@@ -0,0 +1,11 @@
+/* { dg-do run } */
+/* { dg-options "-fdump-tree-crc -fdump-rtl-dfinish " } */
+/* { dg-additional-options "-march=rv64gc_zbkc" { target { rv64 } } } */
+/* { dg-additional-options "-march=rv32gc_zbkc" { target { rv32 } } } */
+/* { dg-skip-if "" { *-*-* } { "-O0" "-O1" "-Os" "-Oz" "-Og" "-flto"} } */
+
+#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 "clmul" "dfinish"} } */
diff --git a/gcc/testsuite/gcc.target/riscv/crc-23-zbc.c b/gcc/testsuite/gcc.target/riscv/crc-23-zbc.c
new file mode 100644
index 00000000000..5f3d53910f4
--- /dev/null
+++ b/gcc/testsuite/gcc.target/riscv/crc-23-zbc.c
@@ -0,0 +1,11 @@
+/* { dg-do run } */
+/* { dg-options "-fdump-tree-crc -fdump-rtl-dfinish " } */
+/* { dg-additional-options "-march=rv64gc_zbc" { target { rv64 } } } */
+/* { dg-additional-options "-march=rv32gc_zbc" { target { rv32 } } } */
+/* { dg-skip-if "" { *-*-* } { "-O0" "-O1" "-Os" "-Oz" "-Og" "-flto"} } */
+
+#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 "clmul" "dfinish"} } */
diff --git a/gcc/testsuite/gcc.target/riscv/crc-23-zbkc.c b/gcc/testsuite/gcc.target/riscv/crc-23-zbkc.c
new file mode 100644
index 00000000000..87a5dc0790f
--- /dev/null
+++ b/gcc/testsuite/gcc.target/riscv/crc-23-zbkc.c
@@ -0,0 +1,11 @@
+/* { dg-do run } */
+/* { dg-options "-fdump-tree-crc -fdump-rtl-dfinish " } */
+/* { dg-additional-options "-march=rv64gc_zbkc" { target { rv64 } } } */
+/* { dg-additional-options "-march=rv32gc_zbkc" { target { rv32 } } } */
+/* { dg-skip-if "" { *-*-* } { "-O0" "-O1" "-Os" "-Oz" "-Og" "-flto"} } */
+
+#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 "clmul" "dfinish"} } */
diff --git a/gcc/testsuite/gcc.target/riscv/crc-4-zbc.c b/gcc/testsuite/gcc.target/riscv/crc-4-zbc.c
new file mode 100644
index 00000000000..94af839aa79
--- /dev/null
+++ b/gcc/testsuite/gcc.target/riscv/crc-4-zbc.c
@@ -0,0 +1,11 @@
+/* { dg-do run } */
+/* { dg-options "-fdump-tree-crc -fdump-rtl-dfinish " } */
+/* { dg-additional-options "-march=rv64gc_zbc" { target { rv64 } } } */
+/* { dg-additional-options "-march=rv32gc_zbc" { target { rv32 } } } */
+/* { dg-skip-if "" { *-*-* } { "-O0" "-O1" "-Os" "-Oz" "-Og" "-flto"} } */
+
+#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 "clmul" "dfinish"} } */
diff --git a/gcc/testsuite/gcc.target/riscv/crc-4-zbkb.c b/gcc/testsuite/gcc.target/riscv/crc-4-zbkb.c
new file mode 100644
index 00000000000..7017de9bec9
--- /dev/null
+++ b/gcc/testsuite/gcc.target/riscv/crc-4-zbkb.c
@@ -0,0 +1,10 @@
+/* { dg-do run } */
+/* { dg-options "-fdump-tree-crc-details" } */
+/* { dg-additional-options "-march=rv64gc_zbkb" { target { rv64 } } } */
+/* { dg-additional-options "-march=rv32gc_zbkb" { target { rv32 } } } */
+/* { dg-skip-if "" { *-*-* } { "-O0" "-O1" "-Os" "-Oz" "-Og" "-flto"} } */
+
+#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"} } */
diff --git a/gcc/testsuite/gcc.target/riscv/crc-4-zbkc.c b/gcc/testsuite/gcc.target/riscv/crc-4-zbkc.c
new file mode 100644
index 00000000000..40c033c4b80
--- /dev/null
+++ b/gcc/testsuite/gcc.target/riscv/crc-4-zbkc.c
@@ -0,0 +1,11 @@
+/* { dg-do run } */
+/* { dg-options "-fdump-tree-crc -fdump-rtl-dfinish " } */
+/* { dg-additional-options "-march=rv64gc_zbkc" { target { rv64 } } } */
+/* { dg-additional-options "-march=rv32gc_zbkc" { target { rv32 } } } */
+/* { dg-skip-if "" { *-*-* } { "-O0" "-O1" "-Os" "-Oz" "-Og" "-flto"} } */
+
+#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 "clmul" "dfinish"} } */
diff --git a/gcc/testsuite/gcc.target/riscv/crc-5-zbc.c b/gcc/testsuite/gcc.target/riscv/crc-5-zbc.c
new file mode 100644
index 00000000000..24633539d1d
--- /dev/null
+++ b/gcc/testsuite/gcc.target/riscv/crc-5-zbc.c
@@ -0,0 +1,11 @@
+/* { dg-do run } */
+/* { dg-options "-w -fdump-tree-crc -fdump-rtl-dfinish " } */
+/* { dg-additional-options "-march=rv64gc_zbc" { target { rv64 } } } */
+/* { dg-additional-options "-march=rv32gc_zbc" { target { rv32 } } } */
+/* { dg-skip-if "" { *-*-* } { "-O0" "-O1" "-Os" "-Oz" "-Og" "-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 "clmul" "dfinish"} } */
\ No newline at end of file
diff --git a/gcc/testsuite/gcc.target/riscv/crc-5-zbkb.c b/gcc/testsuite/gcc.target/riscv/crc-5-zbkb.c
new file mode 100644
index 00000000000..ee327064dce
--- /dev/null
+++ b/gcc/testsuite/gcc.target/riscv/crc-5-zbkb.c
@@ -0,0 +1,10 @@
+/* { dg-do run } */
+/* { dg-options "-w -fdump-tree-crc-details" } */
+/* { dg-additional-options "-march=rv64gc_zbkb" { target { rv64 } } } */
+/* { dg-additional-options "-march=rv32gc_zbkb" { target { rv32 } } } */
+/* { dg-skip-if "" { *-*-* } { "-O0" "-O1" "-Os" "-Oz" "-Og" "-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"} } */
\ No newline at end of file
diff --git a/gcc/testsuite/gcc.target/riscv/crc-5-zbkc.c b/gcc/testsuite/gcc.target/riscv/crc-5-zbkc.c
new file mode 100644
index 00000000000..fe2cada70a6
--- /dev/null
+++ b/gcc/testsuite/gcc.target/riscv/crc-5-zbkc.c
@@ -0,0 +1,11 @@
+/* { dg-do run } */
+/* { dg-options "-w -fdump-tree-crc -fdump-rtl-dfinish " } */
+/* { dg-additional-options "-march=rv64gc_zbkc" { target { rv64 } } } */
+/* { dg-additional-options "-march=rv32gc_zbkc" { target { rv32 } } } */
+/* { dg-skip-if "" { *-*-* } { "-O0" "-O1" "-Os" "-Oz" "-Og" "-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 "clmul" "dfinish"} } */
\ No newline at end of file
diff --git a/gcc/testsuite/gcc.target/riscv/crc-6-zbc.c b/gcc/testsuite/gcc.target/riscv/crc-6-zbc.c
new file mode 100644
index 00000000000..c771326991b
--- /dev/null
+++ b/gcc/testsuite/gcc.target/riscv/crc-6-zbc.c
@@ -0,0 +1,11 @@
+/* { dg-do run } */
+/* { dg-options "-fdump-tree-crc -fdump-rtl-dfinish " } */
+/* { dg-additional-options "-march=rv64gc_zbc" { target { rv64 } } } */
+/* { dg-additional-options "-march=rv32gc_zbc" { target { rv32 } } } */
+/* { dg-skip-if "" { *-*-* } { "-O0" "-O1" "-O3" "-Os" "-Oz" "-Og" "-flto"} } */
+
+#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 "clmul" "dfinish"} } */
\ No newline at end of file
diff --git a/gcc/testsuite/gcc.target/riscv/crc-6-zbkc.c b/gcc/testsuite/gcc.target/riscv/crc-6-zbkc.c
new file mode 100644
index 00000000000..b4d03f67d98
--- /dev/null
+++ b/gcc/testsuite/gcc.target/riscv/crc-6-zbkc.c
@@ -0,0 +1,11 @@
+/* { dg-do run } */
+/* { dg-options "-fdump-tree-crc -fdump-rtl-dfinish " } */
+/* { dg-additional-options "-march=rv64gc_zbkc" { target { rv64 } } } */
+/* { dg-additional-options "-march=rv32gc_zbkc" { target { rv32 } } } */
+/* { dg-skip-if "" { *-*-* } { "-O0" "-O1" "-O3" "-Os" "-Oz" "-Og" "-flto"} } */
+
+#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 "clmul" "dfinish"} } */
\ No newline at end of file
diff --git a/gcc/testsuite/gcc.target/riscv/crc-7-zbc.c b/gcc/testsuite/gcc.target/riscv/crc-7-zbc.c
new file mode 100644
index 00000000000..574caf1286f
--- /dev/null
+++ b/gcc/testsuite/gcc.target/riscv/crc-7-zbc.c
@@ -0,0 +1,11 @@
+/* { dg-do run } */
+/* { dg-options "-fdump-tree-crc -fdump-rtl-dfinish " } */
+/* { dg-additional-options "-march=rv64gc_zbc" { target { rv64 } } } */
+/* { dg-additional-options "-march=rv32gc_zbc" { target { rv32 } } } */
+/* { dg-skip-if "" { *-*-* } { "-O0" "-O1" "-Os" "-Oz" "-Og" "-flto"} } */
+
+#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 "clmul" "dfinish"} } */
diff --git a/gcc/testsuite/gcc.target/riscv/crc-7-zbkc.c b/gcc/testsuite/gcc.target/riscv/crc-7-zbkc.c
new file mode 100644
index 00000000000..15f2232e58e
--- /dev/null
+++ b/gcc/testsuite/gcc.target/riscv/crc-7-zbkc.c
@@ -0,0 +1,11 @@
+/* { dg-do run } */
+/* { dg-options "-fdump-tree-crc -fdump-rtl-dfinish " } */
+/* { dg-additional-options "-march=rv64gc_zbkc" { target { rv64 } } } */
+/* { dg-additional-options "-march=rv32gc_zbkc" { target { rv32 } } } */
+/* { dg-skip-if "" { *-*-* } { "-O0" "-O1" "-Os" "-Oz" "-Og" "-flto"} } */
+
+#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 "clmul" "dfinish"} } */
diff --git a/gcc/testsuite/gcc.target/riscv/crc-8-zbc.c b/gcc/testsuite/gcc.target/riscv/crc-8-zbc.c
new file mode 100644
index 00000000000..a4b719045fe
--- /dev/null
+++ b/gcc/testsuite/gcc.target/riscv/crc-8-zbc.c
@@ -0,0 +1,11 @@
+/* { dg-do run } */
+/* { dg-options "-fdump-tree-crc -fdump-rtl-dfinish " } */
+/* { dg-additional-options "-march=rv64gc_zbc" { target { rv64 } } } */
+/* { dg-additional-options "-march=rv32gc_zbc" { target { rv32 } } } */
+/* { dg-skip-if "" { *-*-* } { "-O0" "-O1" "-Os" "-Oz" "-Og" "-flto"} } */
+
+#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 "clmul" "dfinish"} } */
diff --git a/gcc/testsuite/gcc.target/riscv/crc-8-zbkb.c b/gcc/testsuite/gcc.target/riscv/crc-8-zbkb.c
new file mode 100644
index 00000000000..f9bd4945fbf
--- /dev/null
+++ b/gcc/testsuite/gcc.target/riscv/crc-8-zbkb.c
@@ -0,0 +1,10 @@
+/* { dg-do run } */
+/* { dg-options "-fdump-tree-crc-details" } */
+/* { dg-additional-options "-march=rv64gc_zbkb" { target { rv64 } } } */
+/* { dg-additional-options "-march=rv32gc_zbkb" { target { rv32 } } } */
+/* { dg-skip-if "" { *-*-* } { "-O0" "-O1" "-Os" "-Oz" "-Og" "-flto"} } */
+
+#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"} } */
diff --git a/gcc/testsuite/gcc.target/riscv/crc-8-zbkc.c b/gcc/testsuite/gcc.target/riscv/crc-8-zbkc.c
new file mode 100644
index 00000000000..55189b0c8c9
--- /dev/null
+++ b/gcc/testsuite/gcc.target/riscv/crc-8-zbkc.c
@@ -0,0 +1,11 @@
+/* { dg-do run } */
+/* { dg-options "-fdump-tree-crc -fdump-rtl-dfinish " } */
+/* { dg-additional-options "-march=rv64gc_zbkc" { target { rv64 } } } */
+/* { dg-additional-options "-march=rv32gc_zbkc" { target { rv32 } } } */
+/* { dg-skip-if "" { *-*-* } { "-O0" "-O1" "-Os" "-Oz" "-Og" "-flto"} } */
+
+#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 "clmul" "dfinish"} } */
diff --git a/gcc/testsuite/gcc.target/riscv/crc-9-zbc.c b/gcc/testsuite/gcc.target/riscv/crc-9-zbc.c
new file mode 100644
index 00000000000..88b5aaba3aa
--- /dev/null
+++ b/gcc/testsuite/gcc.target/riscv/crc-9-zbc.c
@@ -0,0 +1,11 @@
+/* { dg-do run } */
+/* { dg-options "-fdump-tree-crc -fdump-rtl-dfinish " } */
+/* { dg-additional-options "-march=rv64gc_zbc" { target { rv64 } } } */
+/* { dg-additional-options "-march=rv32gc_zbc" { target { rv32 } } } */
+/* { dg-skip-if "" { *-*-* } { "-O0" "-O1" "-O3" "-Os" "-Oz" "-Og" "-flto"} } */
+
+#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 "clmul" "dfinish"} } */
diff --git a/gcc/testsuite/gcc.target/riscv/crc-9-zbkc.c b/gcc/testsuite/gcc.target/riscv/crc-9-zbkc.c
new file mode 100644
index 00000000000..1dfd1802e41
--- /dev/null
+++ b/gcc/testsuite/gcc.target/riscv/crc-9-zbkc.c
@@ -0,0 +1,11 @@
+/* { dg-do run } */
+/* { dg-options "-fdump-tree-crc -fdump-rtl-dfinish " } */
+/* { dg-additional-options "-march=rv64gc_zbkc" { target { rv64 } } } */
+/* { dg-additional-options "-march=rv32gc_zbkc" { target { rv32 } } } */
+/* { dg-skip-if "" { *-*-* } { "-O0" "-O1" "-O3" "-Os" "-Oz" "-Og" "-flto"} } */
+
+#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 "clmul" "dfinish"} } */
diff --git a/gcc/testsuite/gcc.target/riscv/crc-CCIT-data16-zbc.c b/gcc/testsuite/gcc.target/riscv/crc-CCIT-data16-zbc.c
new file mode 100644
index 00000000000..79bb48d33b1
--- /dev/null
+++ b/gcc/testsuite/gcc.target/riscv/crc-CCIT-data16-zbc.c
@@ -0,0 +1,11 @@
+/* { dg-do run } */
+/* { dg-options "-w -fdump-tree-crc -fdump-rtl-dfinish " } */
+/* { dg-additional-options "-march=rv64gc_zbc" { target { rv64 } } } */
+/* { dg-additional-options "-march=rv32gc_zbc" { target { rv32 } } } */
+/* { dg-skip-if "" { *-*-* } { "-O0" "-O1" "-Os" "-Oz" "-Og" "-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 "clmul" "dfinish"} } */
\ No newline at end of file
diff --git a/gcc/testsuite/gcc.target/riscv/crc-CCIT-data16-zbkc.c b/gcc/testsuite/gcc.target/riscv/crc-CCIT-data16-zbkc.c
new file mode 100644
index 00000000000..4018dfa8e69
--- /dev/null
+++ b/gcc/testsuite/gcc.target/riscv/crc-CCIT-data16-zbkc.c
@@ -0,0 +1,11 @@
+/* { dg-do run } */
+/* { dg-options "-w -fdump-tree-crc -fdump-rtl-dfinish " } */
+/* { dg-additional-options "-march=rv64gc_zbkc" { target { rv64 } } } */
+/* { dg-additional-options "-march=rv32gc_zbkc" { target { rv32 } } } */
+/* { dg-skip-if "" { *-*-* } { "-O0" "-O1" "-Os" "-Oz" "-Og" "-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 "clmul" "dfinish"} } */
\ No newline at end of file
diff --git a/gcc/testsuite/gcc.target/riscv/crc-CCIT-data8-zbc.c b/gcc/testsuite/gcc.target/riscv/crc-CCIT-data8-zbc.c
new file mode 100644
index 00000000000..fcc413c7d76
--- /dev/null
+++ b/gcc/testsuite/gcc.target/riscv/crc-CCIT-data8-zbc.c
@@ -0,0 +1,11 @@
+/* { dg-do run } */
+/* { dg-options "-w -fdump-tree-crc -fdump-rtl-dfinish " } */
+/* { dg-additional-options "-march=rv64gc_zbc" { target { rv64 } } } */
+/* { dg-additional-options "-march=rv32gc_zbc" { target { rv32 } } } */
+/* { dg-skip-if "" { *-*-* } { "-O0" "-O1" "-Os" "-Oz" "-Og" "-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 "clmul" "dfinish"} } */
\ No newline at end of file
diff --git a/gcc/testsuite/gcc.target/riscv/crc-CCIT-data8-zbkc.c b/gcc/testsuite/gcc.target/riscv/crc-CCIT-data8-zbkc.c
new file mode 100644
index 00000000000..7e4a36dd7bf
--- /dev/null
+++ b/gcc/testsuite/gcc.target/riscv/crc-CCIT-data8-zbkc.c
@@ -0,0 +1,11 @@
+/* { dg-do run } */
+/* { dg-options "-w -fdump-tree-crc -fdump-rtl-dfinish " } */
+/* { dg-additional-options "-march=rv64gc_zbkc" { target { rv64 } } } */
+/* { dg-additional-options "-march=rv32gc_zbkc" { target { rv32 } } } */
+/* { dg-skip-if "" { *-*-* } { "-O0" "-O1" "-Os" "-Oz" "-Og" "-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 "clmul" "dfinish"} } */
\ No newline at end of file
diff --git a/gcc/testsuite/gcc.target/riscv/crc-coremark-16bitdata-zbc.c b/gcc/testsuite/gcc.target/riscv/crc-coremark-16bitdata-zbc.c
new file mode 100644
index 00000000000..88da999c4e3
--- /dev/null
+++ b/gcc/testsuite/gcc.target/riscv/crc-coremark-16bitdata-zbc.c
@@ -0,0 +1,11 @@
+/* { dg-do run } */
+/* { dg-options "-w -fdump-tree-crc -fdump-rtl-dfinish " } */
+/* { dg-additional-options "-march=rv64gc_zbc" { target { rv64 } } } */
+/* { dg-additional-options "-march=rv32gc_zbc" { target { rv32 } } } */
+/* { dg-skip-if "" { *-*-* } { "-O0" "-O1" "-Os" "-Oz" "-Og" "-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 "clmul" "dfinish"} } */
\ No newline at end of file
diff --git a/gcc/testsuite/gcc.target/riscv/crc-coremark-16bitdata-zbkc.c b/gcc/testsuite/gcc.target/riscv/crc-coremark-16bitdata-zbkc.c
new file mode 100644
index 00000000000..ef0083e33c2
--- /dev/null
+++ b/gcc/testsuite/gcc.target/riscv/crc-coremark-16bitdata-zbkc.c
@@ -0,0 +1,11 @@
+/* { dg-do run } */
+/* { dg-options "-w -fdump-tree-crc -fdump-rtl-dfinish " } */
+/* { dg-additional-options "-march=rv64gc_zbkc" { target { rv64 } } } */
+/* { dg-additional-options "-march=rv32gc_zbkc" { target { rv32 } } } */
+/* { dg-skip-if "" { *-*-* } { "-O0" "-O1" "-Os" "-Oz" "-Og" "-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 "clmul" "dfinish"} } */
\ No newline at end of file
--
2.25.1
^ permalink raw reply [flat|nested] 4+ messages in thread
* Re: [RFC/RFA][PATCH v2 03/12] RISC-V: Add CRC expander to generate faster CRC.
2024-07-26 18:06 [RFC/RFA][PATCH v2 03/12] RISC-V: Add CRC expander to generate faster CRC Mariam Arutunian
@ 2024-08-25 17:41 ` Jeff Law
2024-08-28 8:14 ` Mariam Arutunian
0 siblings, 1 reply; 4+ messages in thread
From: Jeff Law @ 2024-08-25 17:41 UTC (permalink / raw)
To: Mariam Arutunian, GCC Patches
On 7/26/24 12:06 PM, Mariam Arutunian wrote:
> If the target is ZBC or ZBKC, it uses clmul instruction for the CRC
> calculation.
> Otherwise, if the target is ZBKB, generates table-based CRC, but for
> reversing inputs and the output uses bswap and brev8 instructions.
> Add new tests to check CRC generation for ZBC, ZBKC and ZBKB targets.
>
> gcc/
>
> * expr.cc (reflect): New function.
> (gf2n_poly_long_div_quotient): Likewise.
> * expr.h (reflect): New function declaration.
> (gf2n_poly_long_div_quotient): Likewise.
>
> gcc/config/riscv/
>
> * bitmanip.md (crc_rev<ANYI1:mode><ANYI:mode>4): New expander
> for reversed CRC.
> (crc<SUBX1:mode><SUBX:mode>4): New expander for bit-forward CRC.
> (SUBX1, ANYI1): New iterators.
> * riscv-protos.h (generate_reflecting_code_using_brev): New
> function declaration.
> (expand_crc_using_clmul): Likewise.
> (expand_reversed_crc_using_clmul): Likewise.
> * riscv.cc (generate_reflecting_code_using_brev): New function.
> (expand_crc_using_clmul): Likewise.
> (expand_reversed_crc_using_clmul): Likewise.
> * riscv.md (UNSPEC_CRC, UNSPEC_CRC_REV): New unspecs.
>
> gcc/testsuite/gcc.target/riscv/
>
> * crc-1-zbc.c: New test.
> * crc-1-zbc.c: Likewise.
> * crc-10-zbc.c: Likewise.
> * crc-10-zbkc.c: Likewise.
> * crc-12-zbc.c: Likewise.
> * crc-12-zbkc.c: Likewise.
> * crc-13-zbc.c: Likewise.
> * crc-13-zbkc.c: Likewise.
> * crc-14-zbc.c: Likewise.
> * crc-14-zbkc.c: Likewise.
> * crc-17-zbc.c: Likewise.
> * crc-17-zbkc.c: Likewise.
> * crc-18-zbc.c: Likewise.
> * crc-18-zbkc.c: Likewise.
> * crc-21-zbc.c: Likewise.
> * crc-21-zbkc.c: Likewise.
> * crc-22-rv64-zbc.c: Likewise.
> * crc-22-rv64-zbkb.c: Likewise.
> * crc-22-rv64-zbkc.c: Likewise.
> * crc-23-zbc.c: Likewise.
> * crc-23-zbkc.c: Likewise.
> * crc-4-zbc.c: Likewise.
> * crc-4-zbkb.c: Likewise.
> * crc-4-zbkc.c: Likewise.
> * crc-5-zbc.c: Likewise.
> * crc-5-zbkb.c: Likewise.
> * crc-5-zbkc.c: Likewise.
> * crc-6-zbc.c: Likewise.
> * crc-6-zbkc.c: Likewise.
> * crc-7-zbc.c: Likewise.
> * crc-7-zbkc.c: Likewise.
> * crc-8-zbc.c: Likewise.
> * crc-8-zbkb.c: Likewise.
> * crc-8-zbkc.c: Likewise.
> * crc-9-zbc.c: Likewise.
> * crc-9-zbkc.c: Likewise.
> * crc-CCIT-data16-zbc.c: Likewise.
> * crc-CCIT-data16-zbkc.c: Likewise.
> * crc-CCIT-data8-zbc.c: Likewise.
> * crc-CCIT-data8-zbkc.c: Likewise.
> * crc-coremark-16bitdata-zbc.c: Likewise.
> * crc-coremark-16bitdata-zbkc.c: Likewise.
>
> Signed-off-by: Mariam Arutunian <mariamarutunian@gmail.com
> <mailto:mariamarutunian@gmail.com>>
>
>
> 0003-RISC-V-Add-CRC-expander-to-generate-faster-CRC.patch
>
> diff --git a/gcc/config/riscv/bitmanip.md b/gcc/config/riscv/bitmanip.md
> index 8769a6b818b..9683ac48ef6 100644
> --- a/gcc/config/riscv/bitmanip.md
> +++ b/gcc/config/riscv/bitmanip.md
> @@ -973,3 +973,67 @@
> "TARGET_ZBC"
> "clmulr\t%0,%1,%2"
> [(set_attr "type" "clmul")])
> +
> +
> +;; Iterator for hardware integer modes narrower than XLEN, same as SUBX
> +(define_mode_iterator SUBX1 [QI HI (SI "TARGET_64BIT")])
> +
> +;; Iterator for hardware integer modes narrower than XLEN, same as ANYI
> +(define_mode_iterator ANYI1 [QI HI SI (DI "TARGET_64BIT")])
Might as well go ahead and put these into iterators.md.
> +
> +;; Reversed CRC 8, 16, 32 for TARGET_64
> +(define_expand "crc_rev<ANYI1:mode><ANYI:mode>4"
> + ;; return value (calculated CRC)
> + [(set (match_operand:ANYI 0 "register_operand" "=r")
> + ;; initial CRC
> + (unspec:ANYI [(match_operand:ANYI 1 "register_operand" "r")
> + ;; data
> + (match_operand:ANYI1 2 "register_operand" "r")
> + ;; polynomial without leading 1
> + (match_operand:ANYI 3)]
> + UNSPEC_CRC_REV))]
> + /* We don't support the case when data's size is bigger than CRC's size. */
> + "(((TARGET_ZBKC || TARGET_ZBC) && <ANYI:MODE>mode < word_mode)
> + || TARGET_ZBKB) && <ANYI:MODE>mode >= <ANYI1:MODE>mode"
This condition should get reformatted. Ideally the condition should be
fairly obvious, but it's fairly obfuscated here.
I would expect that the TARGET_ZBKB likely belongs inside the
conditional with the other TARGET tests. Perhaps something like this:
> "(TARGET_ZBKB || TARGET_ZBKC || TARGET_ZBC)
> && <ANYI:MODE>mode < word_mode
> && <ANYI:MODE>mode >= <ANYI1:MODE>mode"
Or did you mean to allow ZBKB even if the quotient needs 65 bits? If so
the condition still needs adjustment, just a different adjustment.
Otherwise this looks fine to me. Were there any adjustments you were
considering after working through the aarch64 expansion with Richard S?
jeff
^ permalink raw reply [flat|nested] 4+ messages in thread
* Re: [RFC/RFA][PATCH v2 03/12] RISC-V: Add CRC expander to generate faster CRC.
2024-08-25 17:41 ` Jeff Law
@ 2024-08-28 8:14 ` Mariam Arutunian
2024-09-29 22:22 ` Jeff Law
0 siblings, 1 reply; 4+ messages in thread
From: Mariam Arutunian @ 2024-08-28 8:14 UTC (permalink / raw)
To: Jeff Law; +Cc: GCC Patches
[-- Attachment #1: Type: text/plain, Size: 6493 bytes --]
On Sun, Aug 25, 2024 at 9:41 PM Jeff Law <jeffreyalaw@gmail.com> wrote:
>
>
> On 7/26/24 12:06 PM, Mariam Arutunian wrote:
> > If the target is ZBC or ZBKC, it uses clmul instruction for the CRC
> > calculation.
> > Otherwise, if the target is ZBKB, generates table-based CRC, but for
> > reversing inputs and the output uses bswap and brev8 instructions.
> > Add new tests to check CRC generation for ZBC, ZBKC and ZBKB targets.
> >
> > gcc/
> >
> > * expr.cc (reflect): New function.
> > (gf2n_poly_long_div_quotient): Likewise.
> > * expr.h (reflect): New function declaration.
> > (gf2n_poly_long_div_quotient): Likewise.
> >
> > gcc/config/riscv/
> >
> > * bitmanip.md (crc_rev<ANYI1:mode><ANYI:mode>4): New expander
> > for reversed CRC.
> > (crc<SUBX1:mode><SUBX:mode>4): New expander for bit-forward CRC.
> > (SUBX1, ANYI1): New iterators.
> > * riscv-protos.h (generate_reflecting_code_using_brev): New
> > function declaration.
> > (expand_crc_using_clmul): Likewise.
> > (expand_reversed_crc_using_clmul): Likewise.
> > * riscv.cc (generate_reflecting_code_using_brev): New function.
> > (expand_crc_using_clmul): Likewise.
> > (expand_reversed_crc_using_clmul): Likewise.
> > * riscv.md (UNSPEC_CRC, UNSPEC_CRC_REV): New unspecs.
> >
> > gcc/testsuite/gcc.target/riscv/
> >
> > * crc-1-zbc.c: New test.
> > * crc-1-zbc.c: Likewise.
> > * crc-10-zbc.c: Likewise.
> > * crc-10-zbkc.c: Likewise.
> > * crc-12-zbc.c: Likewise.
> > * crc-12-zbkc.c: Likewise.
> > * crc-13-zbc.c: Likewise.
> > * crc-13-zbkc.c: Likewise.
> > * crc-14-zbc.c: Likewise.
> > * crc-14-zbkc.c: Likewise.
> > * crc-17-zbc.c: Likewise.
> > * crc-17-zbkc.c: Likewise.
> > * crc-18-zbc.c: Likewise.
> > * crc-18-zbkc.c: Likewise.
> > * crc-21-zbc.c: Likewise.
> > * crc-21-zbkc.c: Likewise.
> > * crc-22-rv64-zbc.c: Likewise.
> > * crc-22-rv64-zbkb.c: Likewise.
> > * crc-22-rv64-zbkc.c: Likewise.
> > * crc-23-zbc.c: Likewise.
> > * crc-23-zbkc.c: Likewise.
> > * crc-4-zbc.c: Likewise.
> > * crc-4-zbkb.c: Likewise.
> > * crc-4-zbkc.c: Likewise.
> > * crc-5-zbc.c: Likewise.
> > * crc-5-zbkb.c: Likewise.
> > * crc-5-zbkc.c: Likewise.
> > * crc-6-zbc.c: Likewise.
> > * crc-6-zbkc.c: Likewise.
> > * crc-7-zbc.c: Likewise.
> > * crc-7-zbkc.c: Likewise.
> > * crc-8-zbc.c: Likewise.
> > * crc-8-zbkb.c: Likewise.
> > * crc-8-zbkc.c: Likewise.
> > * crc-9-zbc.c: Likewise.
> > * crc-9-zbkc.c: Likewise.
> > * crc-CCIT-data16-zbc.c: Likewise.
> > * crc-CCIT-data16-zbkc.c: Likewise.
> > * crc-CCIT-data8-zbc.c: Likewise.
> > * crc-CCIT-data8-zbkc.c: Likewise.
> > * crc-coremark-16bitdata-zbc.c: Likewise.
> > * crc-coremark-16bitdata-zbkc.c: Likewise.
> >
> > Signed-off-by: Mariam Arutunian <mariamarutunian@gmail.com
> > <mailto:mariamarutunian@gmail.com>>
> >
> >
> > 0003-RISC-V-Add-CRC-expander-to-generate-faster-CRC.patch
> >
> > diff --git a/gcc/config/riscv/bitmanip.md b/gcc/config/riscv/bitmanip.md
> > index 8769a6b818b..9683ac48ef6 100644
> > --- a/gcc/config/riscv/bitmanip.md
> > +++ b/gcc/config/riscv/bitmanip.md
> > @@ -973,3 +973,67 @@
> > "TARGET_ZBC"
> > "clmulr\t%0,%1,%2"
> > [(set_attr "type" "clmul")])
> > +
> > +
> > +;; Iterator for hardware integer modes narrower than XLEN, same as SUBX
> > +(define_mode_iterator SUBX1 [QI HI (SI "TARGET_64BIT")])
> > +
> > +;; Iterator for hardware integer modes narrower than XLEN, same as ANYI
> > +(define_mode_iterator ANYI1 [QI HI SI (DI "TARGET_64BIT")])
> Might as well go ahead and put these into iterators.md.
Ok.
>
>
> > +
> > +;; Reversed CRC 8, 16, 32 for TARGET_64
> > +(define_expand "crc_rev<ANYI1:mode><ANYI:mode>4"
> > + ;; return value (calculated CRC)
> > + [(set (match_operand:ANYI 0 "register_operand" "=r")
> > + ;; initial CRC
> > + (unspec:ANYI [(match_operand:ANYI 1 "register_operand" "r")
> > + ;; data
> > + (match_operand:ANYI1 2 "register_operand" "r")
> > + ;; polynomial without leading 1
> > + (match_operand:ANYI 3)]
> > + UNSPEC_CRC_REV))]
> > + /* We don't support the case when data's size is bigger than CRC's
> size. */
> > + "(((TARGET_ZBKC || TARGET_ZBC) && <ANYI:MODE>mode < word_mode)
> > + || TARGET_ZBKB) && <ANYI:MODE>mode >= <ANYI1:MODE>mode"
> This condition should get reformatted. Ideally the condition should be
> fairly obvious, but it's fairly obfuscated here.
>
> I would expect that the TARGET_ZBKB likely belongs inside the
> conditional with the other TARGET tests. Perhaps something like this:
>
> > "(TARGET_ZBKB || TARGET_ZBKC || TARGET_ZBC)
> > && <ANYI:MODE>mode < word_mode
> > && <ANYI:MODE>mode >= <ANYI1:MODE>mode"
>
> Or did you mean to allow ZBKB even if the quotient needs 65 bits? If so
> the condition still needs adjustment, just a different adjustment.
Yes, in the case of ZBKB I generate table-based CRC, just use specific
instructions to reverse values.
Would it be okay if I just leave "<ANYI:MODE>mode >= <ANYI1:MODE>",
and then generate a standard table-based implementation in the body if none
of the conditions are met?
Or just write this way:
"(TARGET_ZBKB
|| ((TARGET_ZBKC || TARGET_ZBC) && <ANYI:MODE>mode < word_mode))
&& <ANYI:MODE>mode >= <ANYI1:MODE>mode"
>
> Otherwise this looks fine to me. Were there any adjustments you were
> considering after working through the aarch64 expansion with Richard S?
>
Yes, I applied some of the changes I made in AArch64 here as well, where
possible and worked.
Also, in AArch64, I used force_reg in some cases, but here, I didn't
change, as you had told me to use riscv_expand_* instead of force_reg.
Thanks,
Mariam
> jeff
>
>
>
^ permalink raw reply [flat|nested] 4+ messages in thread
* Re: [RFC/RFA][PATCH v2 03/12] RISC-V: Add CRC expander to generate faster CRC.
2024-08-28 8:14 ` Mariam Arutunian
@ 2024-09-29 22:22 ` Jeff Law
0 siblings, 0 replies; 4+ messages in thread
From: Jeff Law @ 2024-09-29 22:22 UTC (permalink / raw)
To: Mariam Arutunian; +Cc: GCC Patches
On 8/28/24 2:14 AM, Mariam Arutunian wrote:
>
>
> Yes, I applied some of the changes I made in AArch64 here as well, where
> possible and worked.
> Also, in AArch64, I used force_reg in some cases, but here, I didn't
> change, as you had told me to use riscv_expand_* instead of force_reg.
I don't recall avoiding force_reg, I do vaguely recall wanting the
expanders to be used rather than using emit_move_insn directly.
Anyway, just wanted to check in that if there were any lessons learned
from the aarch64 work that we should apply to riscv. Sounds like
nothing major. Thanks!
jeff
^ permalink raw reply [flat|nested] 4+ messages in thread
end of thread, other threads:[~2024-09-29 22:22 UTC | newest]
Thread overview: 4+ messages (download: mbox.gz / follow: Atom feed)
-- links below jump to the message on this page --
2024-07-26 18:06 [RFC/RFA][PATCH v2 03/12] RISC-V: Add CRC expander to generate faster CRC Mariam Arutunian
2024-08-25 17:41 ` Jeff Law
2024-08-28 8:14 ` Mariam Arutunian
2024-09-29 22:22 ` Jeff Law
This is a public inbox, see mirroring instructions
for how to clone and mirror all data and code used for this inbox;
as well as URLs for read-only IMAP folder(s) and NNTP newsgroup(s).