diff --git a/gcc/Makefile.in b/gcc/Makefile.in
index 5610854e6f4505817d200a490492ec88c9838673..ad32d1c8d744fa18c9ca6b2d5762192876c425a7 100644
--- a/gcc/Makefile.in
+++ b/gcc/Makefile.in
@@ -1342,6 +1342,7 @@ OBJS = \
cppbuiltin.o \
cppdefault.o \
cprop.o \
+ crc32-tables.o \
cse.o \
cselib.o \
data-streamer.o \
diff --git a/gcc/common.opt b/gcc/common.opt
index 96888cf1ba3fd7aeee674040f7793cb57ee8265c..380d3ccf8d1f074c69e1a4824a55859cf395d4a9 100644
--- a/gcc/common.opt
+++ b/gcc/common.opt
@@ -1126,6 +1126,10 @@ fcrypto-accel-aes
Common Var(flag_crypto_accel_aes) Init(0) Optimization
Perform crypto acceleration AES pattern matching.
+fcrypto-accel-crc32
+Common Var(flag_crypto_accel_crc32) Init(0) Optimization
+Perform error-detecting code acceleration CRC32 pattern matching.
+
floop-crc
Common Var(flag_loop_crc) Optimization
Do the loop crc conversion.
diff --git a/gcc/config/aarch64/aarch64-builtins.cc b/gcc/config/aarch64/aarch64-builtins.cc
index b17ae28769c7b0ad997de2de849bfcf7805f4934..f329f08e3df755f51969d7a9396e166865e353c3 100644
--- a/gcc/config/aarch64/aarch64-builtins.cc
+++ b/gcc/config/aarch64/aarch64-builtins.cc
@@ -47,6 +47,7 @@
#include "stringpool.h"
#include "attribs.h"
#include "gimple-fold.h"
+#include "crc32-tables.h"
#define v8qi_UP E_V8QImode
#define v8di_UP E_V8DImode
@@ -1819,6 +1820,29 @@ aarch64_general_builtin_decl (unsigned code, bool)
return aarch64_builtin_decls[code];
}
+/* Implement TARGET_GET_CRC32_BUILTIN_CODE. */
+unsigned
+get_crc32_builtin_code (unsigned code)
+{
+ switch (code)
+ {
+ case BUILTIN_CRC32B:
+ return AARCH64_BUILTIN_crc32b;
+ case BUILTIN_CRC32H:
+ return AARCH64_BUILTIN_crc32h;
+ case BUILTIN_CRC32W:
+ return AARCH64_BUILTIN_crc32w;
+ case BUILTIN_CRC32CB:
+ return AARCH64_BUILTIN_crc32cb;
+ case BUILTIN_CRC32CH:
+ return AARCH64_BUILTIN_crc32ch;
+ case BUILTIN_CRC32CW:
+ return AARCH64_BUILTIN_crc32cw;
+ default:
+ return AARCH64_BUILTIN_MIN;
+ }
+}
+
/* Implement TARGET_GET_CRC_BUILTIN_CODE */
unsigned
get_crc_builtin_code(unsigned code, bool)
diff --git a/gcc/config/aarch64/aarch64-protos.h b/gcc/config/aarch64/aarch64-protos.h
index cbb844fbc56a7846eebc97dd62a56e3c61bab3be..6f5d300af453cf68c1700100076e3ec9a3c7a386 100644
--- a/gcc/config/aarch64/aarch64-protos.h
+++ b/gcc/config/aarch64/aarch64-protos.h
@@ -1002,6 +1002,7 @@ tree aarch64_general_builtin_rsqrt (unsigned int);
tree aarch64_builtin_vectorized_function (unsigned int, tree, tree);
void handle_arm_acle_h (void);
void handle_arm_neon_h (void);
+unsigned get_crc32_builtin_code (unsigned);
namespace aarch64_sve {
void init_builtins ();
diff --git a/gcc/config/aarch64/aarch64.cc b/gcc/config/aarch64/aarch64.cc
index 1d479f270e7146e2a766fade50363773f9a79020..38b1c4c191f36ebbe5b9c45283001cb8ff6649b3 100644
--- a/gcc/config/aarch64/aarch64.cc
+++ b/gcc/config/aarch64/aarch64.cc
@@ -3289,6 +3289,15 @@ aarch64_check_arm_new_against_type (tree args, tree decl)
return true;
}
+/* Implement TARGET_GET_CRC32_BUILTIN_CODE. */
+static unsigned
+aarch64_get_crc32_builtin_code (unsigned code)
+{
+ unsigned subcode = get_crc32_builtin_code (code);
+ unsigned res = subcode << AARCH64_BUILTIN_SHIFT;
+ return res;
+}
+
/* Callback for arm::new attributes. */
static tree
handle_arm_new (tree *node, tree name, tree args, int, bool *no_add_attrs)
@@ -31666,6 +31675,9 @@ aarch64_libgcc_floating_mode_supported_p
#undef TARGET_ASM_FUNCTION_EPILOGUE
#define TARGET_ASM_FUNCTION_EPILOGUE aarch64_sls_emit_blr_function_thunks
+#undef TARGET_GET_CRC32_BUILTIN_CODE
+#define TARGET_GET_CRC32_BUILTIN_CODE aarch64_get_crc32_builtin_code
+
#undef TARGET_HAVE_SHADOW_CALL_STACK
#define TARGET_HAVE_SHADOW_CALL_STACK true
diff --git a/gcc/crc32-tables.cc b/gcc/crc32-tables.cc
new file mode 100644
index 0000000000000000000000000000000000000000..cda4c1951450a7f82dddc6ad442bbdba3d89a073
--- /dev/null
+++ b/gcc/crc32-tables.cc
@@ -0,0 +1,460 @@
+/* CRC32 description for GCC compiler.
+ Copyright (C) 2024 Free Software Foundation, Inc.
+
+This file is part of GCC.
+
+GCC is free software; you can redistribute it and/or modify it under
+the terms of the GNU General Public License as published by the Free
+Software Foundation; either version 3, or (at your option) any later
+version.
+
+GCC is distributed in the hope that it will be useful, but WITHOUT ANY
+WARRANTY; without even the implied warranty of MERCHANTABILITY or
+FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License
+for more details.
+
+You should have received a copy of the GNU General Public License
+along with GCC; see the file COPYING3. If not see
+. */
+
+#include "config.h"
+#include
+#include
+#include
+#include "system.h"
+#include "coretypes.h"
+#include "backend.h"
+#include "tree.h"
+#include "gimple.h"
+#include "target.h"
+#include "ssa.h"
+#include "gimple-pretty-print.h"
+#include "diagnostic.h"
+#include "cgraph.h"
+#include "crc32-tables.h"
+
+#define CRC32_LOW_BOUND 0
+#define CRC32_UPPER_BOUND 255
+#define CRC32_ELEMENT_SIZE 4
+#define CRC32_DATA_SHIFT_8 8
+#define CRC32_DATA_SHIFT_16 16
+#define CRC32_DATA_SHIFT_24 24
+
+#define CRC32W_MAX_LOOKUP_DEPTH 4
+
+extern bool gimple_crc32_index_match (tree, tree *, tree (*) (tree));
+extern bool gimple_crc32b_result_match (tree, tree *, tree (*) (tree));
+extern bool gimple_crc32h_result_match (tree, tree *, tree (*) (tree));
+extern bool gimple_crc32w_result_match (tree, tree *, tree (*) (tree));
+
+/* Build architecture specific gimple for crc32 based on crc32 code. */
+static gimple *
+call_builtin_fun (crc32builtin code, tree &lhs, tree arg1, tree arg2)
+{
+ unsigned int builtin_code = targetm.get_crc32_builtin_code (code);
+ tree fn = targetm.builtin_decl (builtin_code, true);
+ if (!fn || fn == error_mark_node)
+ fatal_error (input_location, "target specific builtin not available");
+ gimple *call_builtin = gimple_build_call (fn, 2, arg1, arg2);
+ gimple_call_set_lhs (call_builtin, lhs);
+
+ return call_builtin;
+}
+
+/* Examine tree ref for nesting arrays.
+ Return true if tree node contains nested refs. */
+static bool
+detect_2d_array (tree var)
+{
+ if (TREE_CODE (var) != VAR_DECL)
+ return false;
+ tree type = TREE_TYPE (var);
+ if (TREE_CODE (type) != ARRAY_TYPE)
+ return false;
+ tree element_type = TREE_TYPE (type);
+ if (TREE_CODE (element_type) != INTEGER_TYPE)
+ return false;
+
+ return true;
+}
+
+/* Check values in crc32 array.
+ Examine EVERY value in crc32_table. */
+static bool
+is_crc32_table (tree ctor, const unsigned HOST_WIDE_INT *crc32_table,
+ HOST_WIDE_INT lb, HOST_WIDE_INT ub)
+{
+ for (HOST_WIDE_INT i = lb; i <= ub; i++)
+ {
+ unsigned HOST_WIDE_INT val
+ = tree_to_uhwi (CONSTRUCTOR_ELT (ctor, i)->value);
+ if (crc32_table[i] != val)
+ return false;
+ }
+ return true;
+}
+
+/* Check values in crc32 array. Return type of crc32. */
+static crc32type
+get_crc32_array_type (tree crc32_table_ref)
+{
+ tree low_bound = array_ref_low_bound (CONST_CAST_TREE (crc32_table_ref));
+ tree upper_bound = array_ref_up_bound (CONST_CAST_TREE (crc32_table_ref));
+ tree elem_size = array_ref_element_size (CONST_CAST_TREE (crc32_table_ref));
+ // Check for NULL or ERROR_MARK
+ if (!low_bound || !upper_bound || !elem_size
+ || TREE_CODE (low_bound) == ERROR_MARK
+ || TREE_CODE (upper_bound) == ERROR_MARK
+ || TREE_CODE (elem_size) == ERROR_MARK)
+ return CRC32UNDEFINED;
+
+ unsigned HOST_WIDE_INT lb = tree_to_uhwi (low_bound);
+ unsigned HOST_WIDE_INT ub = tree_to_uhwi (upper_bound);
+ unsigned HOST_WIDE_INT es = tree_to_uhwi (elem_size);
+ if (lb != CRC32_LOW_BOUND
+ || ub != CRC32_UPPER_BOUND
+ || es < CRC32_ELEMENT_SIZE)
+ return CRC32UNDEFINED;
+
+ /* Check values in crc32 array. */
+ tree decl = TREE_OPERAND (crc32_table_ref, 0);
+ tree ctor = ctor_for_folding (decl);
+
+ /* Check crc32 0-255 bytes. */
+ for (int i = 0; i < CRC32_TABLE_NUM; i++)
+ {
+ if (is_crc32_table (ctor, crc32_table[i], lb, ub))
+ return CRC32;
+ }
+
+ /* Check crc32c 0-1023 bytes
+ We expect that the user could use a width CRC32C.
+ So, we try to match values of CRC32C in range of 0-1023 bytes. */
+ for (int i = 0; i < CRC32C_TABLE_NUM; i++)
+ {
+ if (is_crc32_table (ctor, crc32c_table[i], lb, ub))
+ return CRC32C;
+ }
+
+ return CRC32UNDEFINED;
+}
+
+/* Examine array ref by criteria required for crc32* table.
+ return correct crc32type of CRC32UNDEFINED if crc32 wasn't detected. */
+crc32type
+match_crc32_table (tree crc32_table)
+{
+ /* Check read-only flag. */
+ if (!crc32_table->base.readonly_flag)
+ return CRC32UNDEFINED;
+ tree var_decl0 = TREE_OPERAND (crc32_table, 0);
+
+ /* Expected to get 1D array with INTEGER_TYPE values
+ as crc32 candidate array ref. Skip any nested array refs. */
+ if (!detect_2d_array (var_decl0))
+ return CRC32UNDEFINED;
+
+ /* Check a shape of array and return crc32 type. */
+ return get_crc32_array_type (crc32_table);
+}
+
+/* Build gimple for __builtin_crc32*. */
+gimple_seq
+get_combined_crc32_seq (crc32_builtin_params params)
+{
+ tree crc32 = params.crc32curr;
+ tree data = params.crc32data;
+ tree crc32res = params.crc32res;
+ crc32builtin crc32code = params.code;
+ gimple_seq seq = NULL;
+ gimple *g;
+
+ /* Create SSA names and GIMPLE assignments. */
+ tree crc32curr = make_ssa_name (unsigned_type_node);
+ g = gimple_build_assign (crc32curr, NOP_EXPR, crc32);
+ gimple_seq_add_stmt (&seq, g);
+
+ tree data_type;
+ switch (crc32code)
+ {
+ case BUILTIN_CRC32W:
+ case BUILTIN_CRC32CW:
+ data_type = make_ssa_name (uint32_type_node);
+ break;
+ case BUILTIN_CRC32H:
+ case BUILTIN_CRC32CH:
+ data_type = make_ssa_name (short_unsigned_type_node);
+ break;
+ case BUILTIN_CRC32B:
+ case BUILTIN_CRC32CB:
+ data_type = make_ssa_name (unsigned_char_type_node);
+ break;
+ default:
+ gcc_unreachable ();
+ }
+ g = gimple_build_assign (data_type, NOP_EXPR, data);
+ gimple_seq_add_stmt (&seq, g);
+
+ tree crc32lhs = make_ssa_name (unsigned_type_node);
+ gimple *call
+ = call_builtin_fun (crc32code, crc32lhs, crc32curr,
+ gimple_assign_lhs (g));
+ gimple_seq_add_stmt (&seq, call);
+
+ /* Assign result to the crc32res node. */
+ g = gimple_build_assign (crc32res, NOP_EXPR, crc32lhs);
+ gimple_seq_add_stmt (&seq, g);
+
+ return seq;
+}
+
+/* This filter controlls bit_and 0xff operation. crc32 index pattern
+ could containt rshift for getting next data and bit_and with 0xff
+ for cutting value by 255 max value boundary.
+ Sometimes one or another paramenter could be missed.
+ In case when the index starts from (bit_and @0 0xff) it returns @0.
+ In case when pure @0 it returns @0.
+
+ (c) & 0xff -> (c) [>>0]
+ (c>>8) & 0xff -> (c>>8)
+ (c>>16) & 0xff -> (c>>16)
+ (c>>24) -> (c>>24). */
+tree filter_crc32_index (tree T)
+{
+ gimple *stmt = SSA_NAME_DEF_STMT (T);
+ if (!is_gimple_assign (stmt))
+ return T;
+ tree_code rhs_code = gimple_assign_rhs_code (stmt);
+ if (rhs_code == NOP_EXPR || rhs_code == CONVERT_EXPR)
+ return filter_crc32_index (gimple_assign_rhs1 (stmt));
+
+ /* Check if T is a BIT_AND_EXPR. */
+ if (rhs_code == BIT_AND_EXPR)
+ {
+ tree rhs1 = gimple_assign_rhs1 (stmt);
+ tree rhs2 = gimple_assign_rhs2 (stmt);
+
+ /* Check if rhs1 is a RSHIFT_EXPR. */
+ gimple *inner_stmt = SSA_NAME_DEF_STMT (rhs1);
+ if (!is_gimple_assign (inner_stmt))
+ return T;
+ if (gimple_assign_rhs_code (inner_stmt) == RSHIFT_EXPR)
+ {
+ tree shift_rhs = gimple_assign_rhs2 (inner_stmt);
+
+ /* Verify if rhs2 equals CRC32_UPPER_BOUND
+ and shift_rhs is either CRC32_DATA_SHIFT. */
+ if ((tree_to_uhwi (rhs2) != CRC32_UPPER_BOUND)
+ || !((tree_to_uhwi (shift_rhs) == CRC32_DATA_SHIFT_8)
+ || (tree_to_uhwi (shift_rhs) == CRC32_DATA_SHIFT_16)
+ || (tree_to_uhwi (shift_rhs) == CRC32_DATA_SHIFT_24)))
+ return T;
+ }
+ return rhs1;
+ }
+ return T;
+}
+
+/* We have to check crc32array_ref indexes for consistency and sequence,
+ to be sure that all indexes defs have the same source. Working with
+ sub_res_ops array which has the next structure:
+ {crc32curr, crc32data, data_shift}. */
+static bool
+check_index_consistency (const tree * const res_ops, int size)
+{
+ struct TreeComp
+ {
+ bool operator ()(tree lhs, tree rhs) const
+ {
+ return tree_to_uhwi (lhs) < tree_to_uhwi (rhs);
+ }
+ };
+
+ std::set data_shifts;
+
+ /* Going across array_refs - trying to match array indexes as crc32 index
+ and collect data shifts to a set. */
+ for (int i = 0; i < size; i++)
+ {
+ tree sub_res_ops[3];
+ if (!res_ops[i] || !is_gimple_val (res_ops[i]))
+ continue;
+
+ gimple * def_stmt = SSA_NAME_DEF_STMT (res_ops[i]);
+ if (!is_gimple_assign (def_stmt))
+ continue;
+
+ tree def_tree = gimple_assign_rhs1 (def_stmt);
+ tree filtered_crc32_idx = filter_crc32_index (TREE_OPERAND (def_tree,1));
+ if (filtered_crc32_idx == NULL)
+ return false;
+
+ if (gimple_crc32_index_match (filtered_crc32_idx, sub_res_ops, NULL))
+ {
+ if (sub_res_ops[2] == NULL_TREE)
+ data_shifts.insert (build_int_cst (integer_type_node,0));
+ else
+ data_shifts.insert (sub_res_ops[2]);
+ }
+ }
+ if (data_shifts.size () < 2)
+ return false;
+
+ bool sequential = std::adjacent_find (data_shifts.begin (),
+ data_shifts.end (),
+ [](tree lhs, tree rhs)
+ {
+ return tree_to_uhwi (rhs)
+ - tree_to_uhwi (lhs) != 8;
+ }) == data_shifts.end ();
+
+ if (dump_file && (dump_flags & TDF_DETAILS))
+ fprintf (dump_file, "Matched %ld array_refs as consistent crc32arrays!\n",
+ data_shifts.size ());
+
+ return sequential;
+}
+
+/* Recursive lookup for crc32w result. */
+static gimple*
+lookup_crc32w (gimple *stmt, int iter)
+{
+ if (iter >= CRC32W_MAX_LOOKUP_DEPTH)
+ return NULL;
+ if (gimple_code (stmt) != GIMPLE_ASSIGN)
+ return NULL;
+
+ imm_use_iterator imm_iter;
+ gimple *local_stmt;
+ tree ssa_var = gimple_assign_lhs (stmt);
+
+ FOR_EACH_IMM_USE_STMT (local_stmt, imm_iter, ssa_var)
+ {
+ if (gimple_code (local_stmt) != GIMPLE_ASSIGN)
+ return NULL;
+
+ tree crc32w_res = gimple_assign_lhs (local_stmt);
+ tree res_ops_crc32w[4];
+
+ if (gimple_crc32w_result_match (crc32w_res, res_ops_crc32w, NULL)
+ && check_index_consistency (res_ops_crc32w, 4))
+ return local_stmt;
+ else
+ return lookup_crc32w (local_stmt, ++iter);
+ }
+ return NULL;
+}
+
+/* Examine the array reference. If crc32 table index has been recognized:
+ 1. return true
+ 2. write matched values into crc32params:
+ crc32params->crc32curr = idx_ops[0];
+ crc32params->crc32data = idx_ops[1]. */
+bool
+detect_crc32_index (tree array_ref, crc32_builtin_params *crc32params)
+{
+ tree idx_ops[3];
+ tree crc32_index = TREE_OPERAND (array_ref, 1);
+ tree filtered_crc32_idx = filter_crc32_index (crc32_index);
+
+ if (!gimple_crc32_index_match (filtered_crc32_idx, idx_ops, NULL))
+ {
+ if (dump_file && (dump_flags & TDF_DETAILS))
+ fprintf (dump_file, "Matching of crc32 index failed\n");
+ return false;
+ }
+
+ if (dump_file && (dump_flags & TDF_DETAILS))
+ fprintf (dump_file, "Detected crc32 array index!\n");
+
+ crc32params->crc32curr = idx_ops[0];
+ crc32params->crc32data = idx_ops[1];
+
+ return true;
+}
+
+/* Lookup a first widest crc32 result stmt.
+ This function should return a pointer for a statement of crc32res
+ and determine the type of crc32. */
+gimple *
+lookup_crc32_res (gimple * stmt, crc32_builtin_params *crc32params)
+{
+/* We have several cases of crc32 res:
+ crc32b:
+ - (xor (array_access) crc32)
+ crc32h:
+ - (crc32b (crc32b (crc32seed, data), data))
+ or
+ - (xor (array_access1) (array_access2))
+ crc32w:
+ - (xor (crc32h crc32h)). */
+ gimple *crc32res_stmt = NULL;
+ gimple *local_stmt;
+ imm_use_iterator imm_iter;
+ tree ssa_var = gimple_assign_lhs (stmt);
+ FOR_EACH_IMM_USE_STMT (local_stmt, imm_iter, ssa_var)
+ {
+ if (is_gimple_debug (local_stmt))
+ continue;
+
+ /* Skip current stmt and re-run lookup with next stmt,
+ If the current stmt is convert or nop expr. */
+ enum tree_code rhs_code = gimple_assign_rhs_code (local_stmt);
+ if (rhs_code == NOP_EXPR || rhs_code == CONVERT_EXPR)
+ return lookup_crc32_res (local_stmt, crc32params);
+
+ tree local_var = gimple_assign_lhs (local_stmt);
+ if (dump_file && (dump_flags & TDF_DETAILS))
+ {
+ fprintf (dump_file, "Detecting crc32 result... ");
+ fprintf (dump_file, "Examine tree: ");
+ print_generic_expr (dump_file, local_var);
+ fprintf (dump_file, "\n");
+ }
+
+ tree res_ops[3];
+ crc32builtin matched_width = UNDEFINED_BUILTIN;
+ if (gimple_crc32b_result_match (local_var, res_ops, NULL))
+ matched_width = BUILTIN_CRC32B;
+ else if (gimple_crc32h_result_match (local_var, res_ops, NULL))
+ {
+ matched_width = BUILTIN_CRC32H;
+ if (dump_file && (dump_flags & TDF_DETAILS))
+ {
+ fprintf (dump_file, "Detected crc32h candidate!\n");
+ print_gimple_stmt (dump_file, local_stmt, 0);
+ }
+ }
+ else
+ continue;
+
+ /* Save matched statement. */
+ crc32res_stmt = local_stmt;
+ crc32params->crc32res = local_var;
+
+ /* If we matched crc32*h, It potentially could be crc32*w.
+ Match XOR of 2 array refs:
+ XOR (XOR (a0 a1) XOR (b0 b1)).
+ */
+ if (matched_width == BUILTIN_CRC32H)
+ {
+ if (!check_index_consistency (res_ops, 3))
+ continue;
+
+ gimple * crc32w_stmt = lookup_crc32w (local_stmt, 0);
+ if (crc32w_stmt != NULL)
+ {
+ crc32res_stmt = crc32w_stmt;
+ crc32params->crc32res = gimple_assign_lhs (crc32w_stmt);
+ matched_width = BUILTIN_CRC32W;
+ }
+ }
+
+ crc32params->width = matched_width;
+ crc32params->code
+ = static_cast(crc32params->type | crc32params->width);
+
+ } /* end FOR_EACH_IMM_USE_STMT. */
+
+ return crc32res_stmt;
+}
diff --git a/gcc/crc32-tables.h b/gcc/crc32-tables.h
new file mode 100644
index 0000000000000000000000000000000000000000..f083a6a36b8e6704781fcfe90227c8cd359704ba
--- /dev/null
+++ b/gcc/crc32-tables.h
@@ -0,0 +1,303 @@
+/* CRC32 description for GCC compiler.
+ Copyright (C) 2024 Free Software Foundation, Inc.
+
+This file is part of GCC.
+
+GCC is free software; you can redistribute it and/or modify it under
+the terms of the GNU General Public License as published by the Free
+Software Foundation; either version 3, or (at your option) any later
+version.
+
+GCC is distributed in the hope that it will be useful, but WITHOUT ANY
+WARRANTY; without even the implied warranty of MERCHANTABILITY or
+FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License
+for more details.
+
+You should have received a copy of the GNU General Public License
+along with GCC; see the file COPYING3. If not see
+. */
+
+#ifndef GCC_CRC32_TABLES_H
+#define GCC_CRC32_TABLES_H
+
+#define CRC32_TABLE_NUM 1
+#define CRC32C_TABLE_NUM 4
+
+enum crc32type
+{
+ CRC32 = 0b0,
+ CRC32C = 0b10000000,
+ CRC32UNDEFINED
+};
+
+enum crc32builtin
+{
+ BUILTIN_CRC32B = 0b1,
+ BUILTIN_CRC32H = 0b10,
+ BUILTIN_CRC32W = 0b100,
+ BUILTIN_CRC32X = 0b1000,
+ BUILTIN_CRC32CB = BUILTIN_CRC32B | CRC32C,
+ BUILTIN_CRC32CH = BUILTIN_CRC32H | CRC32C,
+ BUILTIN_CRC32CW = BUILTIN_CRC32W | CRC32C,
+ BUILTIN_CRC32CX = BUILTIN_CRC32X | CRC32C,
+ UNDEFINED_BUILTIN
+};
+
+struct crc32_builtin_params
+{
+ tree crc32curr = NULL;
+ tree crc32data = NULL;
+ tree crc32res = NULL;
+ crc32builtin code = UNDEFINED_BUILTIN;
+ crc32type type = CRC32UNDEFINED;
+ crc32builtin width = UNDEFINED_BUILTIN;
+};
+
+// Static table for crc32c (0-1023 bits)
+static const unsigned HOST_WIDE_INT crc32c_table[CRC32C_TABLE_NUM][256] = {
+ {
+ 0x00000000, 0xf26b8303, 0xe13b70f7, 0x1350f3f4, 0xc79a971f, 0x35f1141c,
+ 0x26a1e7e8, 0xd4ca64eb, 0x8ad958cf, 0x78b2dbcc, 0x6be22838, 0x9989ab3b,
+ 0x4d43cfd0, 0xbf284cd3, 0xac78bf27, 0x5e133c24, 0x105ec76f, 0xe235446c,
+ 0xf165b798, 0x030e349b, 0xd7c45070, 0x25afd373, 0x36ff2087, 0xc494a384,
+ 0x9a879fa0, 0x68ec1ca3, 0x7bbcef57, 0x89d76c54, 0x5d1d08bf, 0xaf768bbc,
+ 0xbc267848, 0x4e4dfb4b, 0x20bd8ede, 0xd2d60ddd, 0xc186fe29, 0x33ed7d2a,
+ 0xe72719c1, 0x154c9ac2, 0x061c6936, 0xf477ea35, 0xaa64d611, 0x580f5512,
+ 0x4b5fa6e6, 0xb93425e5, 0x6dfe410e, 0x9f95c20d, 0x8cc531f9, 0x7eaeb2fa,
+ 0x30e349b1, 0xc288cab2, 0xd1d83946, 0x23b3ba45, 0xf779deae, 0x05125dad,
+ 0x1642ae59, 0xe4292d5a, 0xba3a117e, 0x4851927d, 0x5b016189, 0xa96ae28a,
+ 0x7da08661, 0x8fcb0562, 0x9c9bf696, 0x6ef07595, 0x417b1dbc, 0xb3109ebf,
+ 0xa0406d4b, 0x522bee48, 0x86e18aa3, 0x748a09a0, 0x67dafa54, 0x95b17957,
+ 0xcba24573, 0x39c9c670, 0x2a993584, 0xd8f2b687, 0x0c38d26c, 0xfe53516f,
+ 0xed03a29b, 0x1f682198, 0x5125dad3, 0xa34e59d0, 0xb01eaa24, 0x42752927,
+ 0x96bf4dcc, 0x64d4cecf, 0x77843d3b, 0x85efbe38, 0xdbfc821c, 0x2997011f,
+ 0x3ac7f2eb, 0xc8ac71e8, 0x1c661503, 0xee0d9600, 0xfd5d65f4, 0x0f36e6f7,
+ 0x61c69362, 0x93ad1061, 0x80fde395, 0x72966096, 0xa65c047d, 0x5437877e,
+ 0x4767748a, 0xb50cf789, 0xeb1fcbad, 0x197448ae, 0x0a24bb5a, 0xf84f3859,
+ 0x2c855cb2, 0xdeeedfb1, 0xcdbe2c45, 0x3fd5af46, 0x7198540d, 0x83f3d70e,
+ 0x90a324fa, 0x62c8a7f9, 0xb602c312, 0x44694011, 0x5739b3e5, 0xa55230e6,
+ 0xfb410cc2, 0x092a8fc1, 0x1a7a7c35, 0xe811ff36, 0x3cdb9bdd, 0xceb018de,
+ 0xdde0eb2a, 0x2f8b6829, 0x82f63b78, 0x709db87b, 0x63cd4b8f, 0x91a6c88c,
+ 0x456cac67, 0xb7072f64, 0xa457dc90, 0x563c5f93, 0x082f63b7, 0xfa44e0b4,
+ 0xe9141340, 0x1b7f9043, 0xcfb5f4a8, 0x3dde77ab, 0x2e8e845f, 0xdce5075c,
+ 0x92a8fc17, 0x60c37f14, 0x73938ce0, 0x81f80fe3, 0x55326b08, 0xa759e80b,
+ 0xb4091bff, 0x466298fc, 0x1871a4d8, 0xea1a27db, 0xf94ad42f, 0x0b21572c,
+ 0xdfeb33c7, 0x2d80b0c4, 0x3ed04330, 0xccbbc033, 0xa24bb5a6, 0x502036a5,
+ 0x4370c551, 0xb11b4652, 0x65d122b9, 0x97baa1ba, 0x84ea524e, 0x7681d14d,
+ 0x2892ed69, 0xdaf96e6a, 0xc9a99d9e, 0x3bc21e9d, 0xef087a76, 0x1d63f975,
+ 0x0e330a81, 0xfc588982, 0xb21572c9, 0x407ef1ca, 0x532e023e, 0xa145813d,
+ 0x758fe5d6, 0x87e466d5, 0x94b49521, 0x66df1622, 0x38cc2a06, 0xcaa7a905,
+ 0xd9f75af1, 0x2b9cd9f2, 0xff56bd19, 0x0d3d3e1a, 0x1e6dcdee, 0xec064eed,
+ 0xc38d26c4, 0x31e6a5c7, 0x22b65633, 0xd0ddd530, 0x0417b1db, 0xf67c32d8,
+ 0xe52cc12c, 0x1747422f, 0x49547e0b, 0xbb3ffd08, 0xa86f0efc, 0x5a048dff,
+ 0x8ecee914, 0x7ca56a17, 0x6ff599e3, 0x9d9e1ae0, 0xd3d3e1ab, 0x21b862a8,
+ 0x32e8915c, 0xc083125f, 0x144976b4, 0xe622f5b7, 0xf5720643, 0x07198540,
+ 0x590ab964, 0xab613a67, 0xb831c993, 0x4a5a4a90, 0x9e902e7b, 0x6cfbad78,
+ 0x7fab5e8c, 0x8dc0dd8f, 0xe330a81a, 0x115b2b19, 0x020bd8ed, 0xf0605bee,
+ 0x24aa3f05, 0xd6c1bc06, 0xc5914ff2, 0x37faccf1, 0x69e9f0d5, 0x9b8273d6,
+ 0x88d28022, 0x7ab90321, 0xae7367ca, 0x5c18e4c9, 0x4f48173d, 0xbd23943e,
+ 0xf36e6f75, 0x0105ec76, 0x12551f82, 0xe03e9c81, 0x34f4f86a, 0xc69f7b69,
+ 0xd5cf889d, 0x27a40b9e, 0x79b737ba, 0x8bdcb4b9, 0x988c474d, 0x6ae7c44e,
+ 0xbe2da0a5, 0x4c4623a6, 0x5f16d052, 0xad7d5351
+ },
+ {
+ 0x00000000, 0x13a29877, 0x274530ee, 0x34e7a899, 0x4e8a61dc, 0x5d28f9ab,
+ 0x69cf5132, 0x7a6dc945, 0x9d14c3b8, 0x8eb65bcf, 0xba51f356, 0xa9f36b21,
+ 0xd39ea264, 0xc03c3a13, 0xf4db928a, 0xe7790afd, 0x3fc5f181, 0x2c6769f6,
+ 0x1880c16f, 0x0b225918, 0x714f905d, 0x62ed082a, 0x560aa0b3, 0x45a838c4,
+ 0xa2d13239, 0xb173aa4e, 0x859402d7, 0x96369aa0, 0xec5b53e5, 0xfff9cb92,
+ 0xcb1e630b, 0xd8bcfb7c, 0x7f8be302, 0x6c297b75, 0x58ced3ec, 0x4b6c4b9b,
+ 0x310182de, 0x22a31aa9, 0x1644b230, 0x05e62a47, 0xe29f20ba, 0xf13db8cd,
+ 0xc5da1054, 0xd6788823, 0xac154166, 0xbfb7d911, 0x8b507188, 0x98f2e9ff,
+ 0x404e1283, 0x53ec8af4, 0x670b226d, 0x74a9ba1a, 0x0ec4735f, 0x1d66eb28,
+ 0x298143b1, 0x3a23dbc6, 0xdd5ad13b, 0xcef8494c, 0xfa1fe1d5, 0xe9bd79a2,
+ 0x93d0b0e7, 0x80722890, 0xb4958009, 0xa737187e, 0xff17c604, 0xecb55e73,
+ 0xd852f6ea, 0xcbf06e9d, 0xb19da7d8, 0xa23f3faf, 0x96d89736, 0x857a0f41,
+ 0x620305bc, 0x71a19dcb, 0x45463552, 0x56e4ad25, 0x2c896460, 0x3f2bfc17,
+ 0x0bcc548e, 0x186eccf9, 0xc0d23785, 0xd370aff2, 0xe797076b, 0xf4359f1c,
+ 0x8e585659, 0x9dface2e, 0xa91d66b7, 0xbabffec0, 0x5dc6f43d, 0x4e646c4a,
+ 0x7a83c4d3, 0x69215ca4, 0x134c95e1, 0x00ee0d96, 0x3409a50f, 0x27ab3d78,
+ 0x809c2506, 0x933ebd71, 0xa7d915e8, 0xb47b8d9f, 0xce1644da, 0xddb4dcad,
+ 0xe9537434, 0xfaf1ec43, 0x1d88e6be, 0x0e2a7ec9, 0x3acdd650, 0x296f4e27,
+ 0x53028762, 0x40a01f15, 0x7447b78c, 0x67e52ffb, 0xbf59d487, 0xacfb4cf0,
+ 0x981ce469, 0x8bbe7c1e, 0xf1d3b55b, 0xe2712d2c, 0xd69685b5, 0xc5341dc2,
+ 0x224d173f, 0x31ef8f48, 0x050827d1, 0x16aabfa6, 0x6cc776e3, 0x7f65ee94,
+ 0x4b82460d, 0x5820de7a, 0xfbc3faf9, 0xe861628e, 0xdc86ca17, 0xcf245260,
+ 0xb5499b25, 0xa6eb0352, 0x920cabcb, 0x81ae33bc, 0x66d73941, 0x7575a136,
+ 0x419209af, 0x523091d8, 0x285d589d, 0x3bffc0ea, 0x0f186873, 0x1cbaf004,
+ 0xc4060b78, 0xd7a4930f, 0xe3433b96, 0xf0e1a3e1, 0x8a8c6aa4, 0x992ef2d3,
+ 0xadc95a4a, 0xbe6bc23d, 0x5912c8c0, 0x4ab050b7, 0x7e57f82e, 0x6df56059,
+ 0x1798a91c, 0x043a316b, 0x30dd99f2, 0x237f0185, 0x844819fb, 0x97ea818c,
+ 0xa30d2915, 0xb0afb162, 0xcac27827, 0xd960e050, 0xed8748c9, 0xfe25d0be,
+ 0x195cda43, 0x0afe4234, 0x3e19eaad, 0x2dbb72da, 0x57d6bb9f, 0x447423e8,
+ 0x70938b71, 0x63311306, 0xbb8de87a, 0xa82f700d, 0x9cc8d894, 0x8f6a40e3,
+ 0xf50789a6, 0xe6a511d1, 0xd242b948, 0xc1e0213f, 0x26992bc2, 0x353bb3b5,
+ 0x01dc1b2c, 0x127e835b, 0x68134a1e, 0x7bb1d269, 0x4f567af0, 0x5cf4e287,
+ 0x04d43cfd, 0x1776a48a, 0x23910c13, 0x30339464, 0x4a5e5d21, 0x59fcc556,
+ 0x6d1b6dcf, 0x7eb9f5b8, 0x99c0ff45, 0x8a626732, 0xbe85cfab, 0xad2757dc,
+ 0xd74a9e99, 0xc4e806ee, 0xf00fae77, 0xe3ad3600, 0x3b11cd7c, 0x28b3550b,
+ 0x1c54fd92, 0x0ff665e5, 0x759baca0, 0x663934d7, 0x52de9c4e, 0x417c0439,
+ 0xa6050ec4, 0xb5a796b3, 0x81403e2a, 0x92e2a65d, 0xe88f6f18, 0xfb2df76f,
+ 0xcfca5ff6, 0xdc68c781, 0x7b5fdfff, 0x68fd4788, 0x5c1aef11, 0x4fb87766,
+ 0x35d5be23, 0x26772654, 0x12908ecd, 0x013216ba, 0xe64b1c47, 0xf5e98430,
+ 0xc10e2ca9, 0xd2acb4de, 0xa8c17d9b, 0xbb63e5ec, 0x8f844d75, 0x9c26d502,
+ 0x449a2e7e, 0x5738b609, 0x63df1e90, 0x707d86e7, 0x0a104fa2, 0x19b2d7d5,
+ 0x2d557f4c, 0x3ef7e73b, 0xd98eedc6, 0xca2c75b1, 0xfecbdd28, 0xed69455f,
+ 0x97048c1a, 0x84a6146d, 0xb041bcf4, 0xa3e32483
+ },
+ {
+ 0x00000000, 0xa541927e, 0x4f6f520d, 0xea2ec073, 0x9edea41a, 0x3b9f3664,
+ 0xd1b1f617, 0x74f06469, 0x38513ec5, 0x9d10acbb, 0x773e6cc8, 0xd27ffeb6,
+ 0xa68f9adf, 0x03ce08a1, 0xe9e0c8d2, 0x4ca15aac, 0x70a27d8a, 0xd5e3eff4,
+ 0x3fcd2f87, 0x9a8cbdf9, 0xee7cd990, 0x4b3d4bee, 0xa1138b9d, 0x045219e3,
+ 0x48f3434f, 0xedb2d131, 0x079c1142, 0xa2dd833c, 0xd62de755, 0x736c752b,
+ 0x9942b558, 0x3c032726, 0xe144fb14, 0x4405696a, 0xae2ba919, 0x0b6a3b67,
+ 0x7f9a5f0e, 0xdadbcd70, 0x30f50d03, 0x95b49f7d, 0xd915c5d1, 0x7c5457af,
+ 0x967a97dc, 0x333b05a2, 0x47cb61cb, 0xe28af3b5, 0x08a433c6, 0xade5a1b8,
+ 0x91e6869e, 0x34a714e0, 0xde89d493, 0x7bc846ed, 0x0f382284, 0xaa79b0fa,
+ 0x40577089, 0xe516e2f7, 0xa9b7b85b, 0x0cf62a25, 0xe6d8ea56, 0x43997828,
+ 0x37691c41, 0x92288e3f, 0x78064e4c, 0xdd47dc32, 0xc76580d9, 0x622412a7,
+ 0x880ad2d4, 0x2d4b40aa, 0x59bb24c3, 0xfcfab6bd, 0x16d476ce, 0xb395e4b0,
+ 0xff34be1c, 0x5a752c62, 0xb05bec11, 0x151a7e6f, 0x61ea1a06, 0xc4ab8878,
+ 0x2e85480b, 0x8bc4da75, 0xb7c7fd53, 0x12866f2d, 0xf8a8af5e, 0x5de93d20,
+ 0x29195949, 0x8c58cb37, 0x66760b44, 0xc337993a, 0x8f96c396, 0x2ad751e8,
+ 0xc0f9919b, 0x65b803e5, 0x1148678c, 0xb409f5f2, 0x5e273581, 0xfb66a7ff,
+ 0x26217bcd, 0x8360e9b3, 0x694e29c0, 0xcc0fbbbe, 0xb8ffdfd7, 0x1dbe4da9,
+ 0xf7908dda, 0x52d11fa4, 0x1e704508, 0xbb31d776, 0x511f1705, 0xf45e857b,
+ 0x80aee112, 0x25ef736c, 0xcfc1b31f, 0x6a802161, 0x56830647, 0xf3c29439,
+ 0x19ec544a, 0xbcadc634, 0xc85da25d, 0x6d1c3023, 0x8732f050, 0x2273622e,
+ 0x6ed23882, 0xcb93aafc, 0x21bd6a8f, 0x84fcf8f1, 0xf00c9c98, 0x554d0ee6,
+ 0xbf63ce95, 0x1a225ceb, 0x8b277743, 0x2e66e53d, 0xc448254e, 0x6109b730,
+ 0x15f9d359, 0xb0b84127, 0x5a968154, 0xffd7132a, 0xb3764986, 0x1637dbf8,
+ 0xfc191b8b, 0x595889f5, 0x2da8ed9c, 0x88e97fe2, 0x62c7bf91, 0xc7862def,
+ 0xfb850ac9, 0x5ec498b7, 0xb4ea58c4, 0x11abcaba, 0x655baed3, 0xc01a3cad,
+ 0x2a34fcde, 0x8f756ea0, 0xc3d4340c, 0x6695a672, 0x8cbb6601, 0x29faf47f,
+ 0x5d0a9016, 0xf84b0268, 0x1265c21b, 0xb7245065, 0x6a638c57, 0xcf221e29,
+ 0x250cde5a, 0x804d4c24, 0xf4bd284d, 0x51fcba33, 0xbbd27a40, 0x1e93e83e,
+ 0x5232b292, 0xf77320ec, 0x1d5de09f, 0xb81c72e1, 0xccec1688, 0x69ad84f6,
+ 0x83834485, 0x26c2d6fb, 0x1ac1f1dd, 0xbf8063a3, 0x55aea3d0, 0xf0ef31ae,
+ 0x841f55c7, 0x215ec7b9, 0xcb7007ca, 0x6e3195b4, 0x2290cf18, 0x87d15d66,
+ 0x6dff9d15, 0xc8be0f6b, 0xbc4e6b02, 0x190ff97c, 0xf321390f, 0x5660ab71,
+ 0x4c42f79a, 0xe90365e4, 0x032da597, 0xa66c37e9, 0xd29c5380, 0x77ddc1fe,
+ 0x9df3018d, 0x38b293f3, 0x7413c95f, 0xd1525b21, 0x3b7c9b52, 0x9e3d092c,
+ 0xeacd6d45, 0x4f8cff3b, 0xa5a23f48, 0x00e3ad36, 0x3ce08a10, 0x99a1186e,
+ 0x738fd81d, 0xd6ce4a63, 0xa23e2e0a, 0x077fbc74, 0xed517c07, 0x4810ee79,
+ 0x04b1b4d5, 0xa1f026ab, 0x4bdee6d8, 0xee9f74a6, 0x9a6f10cf, 0x3f2e82b1,
+ 0xd50042c2, 0x7041d0bc, 0xad060c8e, 0x08479ef0, 0xe2695e83, 0x4728ccfd,
+ 0x33d8a894, 0x96993aea, 0x7cb7fa99, 0xd9f668e7, 0x9557324b, 0x3016a035,
+ 0xda386046, 0x7f79f238, 0x0b899651, 0xaec8042f, 0x44e6c45c, 0xe1a75622,
+ 0xdda47104, 0x78e5e37a, 0x92cb2309, 0x378ab177, 0x437ad51e, 0xe63b4760,
+ 0x0c158713, 0xa954156d, 0xe5f54fc1, 0x40b4ddbf, 0xaa9a1dcc, 0x0fdb8fb2,
+ 0x7b2bebdb, 0xde6a79a5, 0x3444b9d6, 0x91052ba8
+ },
+ {
+ 0x00000000, 0xdd45aab8, 0xbf672381, 0x62228939, 0x7b2231f3, 0xa6679b4b,
+ 0xc4451272, 0x1900b8ca, 0xf64463e6, 0x2b01c95e, 0x49234067, 0x9466eadf,
+ 0x8d665215, 0x5023f8ad, 0x32017194, 0xef44db2c, 0xe964b13d, 0x34211b85,
+ 0x560392bc, 0x8b463804, 0x924680ce, 0x4f032a76, 0x2d21a34f, 0xf06409f7,
+ 0x1f20d2db, 0xc2657863, 0xa047f15a, 0x7d025be2, 0x6402e328, 0xb9474990,
+ 0xdb65c0a9, 0x06206a11, 0xd725148b, 0x0a60be33, 0x6842370a, 0xb5079db2,
+ 0xac072578, 0x71428fc0, 0x136006f9, 0xce25ac41, 0x2161776d, 0xfc24ddd5,
+ 0x9e0654ec, 0x4343fe54, 0x5a43469e, 0x8706ec26, 0xe524651f, 0x3861cfa7,
+ 0x3e41a5b6, 0xe3040f0e, 0x81268637, 0x5c632c8f, 0x45639445, 0x98263efd,
+ 0xfa04b7c4, 0x27411d7c, 0xc805c650, 0x15406ce8, 0x7762e5d1, 0xaa274f69,
+ 0xb327f7a3, 0x6e625d1b, 0x0c40d422, 0xd1057e9a, 0xaba65fe7, 0x76e3f55f,
+ 0x14c17c66, 0xc984d6de, 0xd0846e14, 0x0dc1c4ac, 0x6fe34d95, 0xb2a6e72d,
+ 0x5de23c01, 0x80a796b9, 0xe2851f80, 0x3fc0b538, 0x26c00df2, 0xfb85a74a,
+ 0x99a72e73, 0x44e284cb, 0x42c2eeda, 0x9f874462, 0xfda5cd5b, 0x20e067e3,
+ 0x39e0df29, 0xe4a57591, 0x8687fca8, 0x5bc25610, 0xb4868d3c, 0x69c32784,
+ 0x0be1aebd, 0xd6a40405, 0xcfa4bccf, 0x12e11677, 0x70c39f4e, 0xad8635f6,
+ 0x7c834b6c, 0xa1c6e1d4, 0xc3e468ed, 0x1ea1c255, 0x07a17a9f, 0xdae4d027,
+ 0xb8c6591e, 0x6583f3a6, 0x8ac7288a, 0x57828232, 0x35a00b0b, 0xe8e5a1b3,
+ 0xf1e51979, 0x2ca0b3c1, 0x4e823af8, 0x93c79040, 0x95e7fa51, 0x48a250e9,
+ 0x2a80d9d0, 0xf7c57368, 0xeec5cba2, 0x3380611a, 0x51a2e823, 0x8ce7429b,
+ 0x63a399b7, 0xbee6330f, 0xdcc4ba36, 0x0181108e, 0x1881a844, 0xc5c402fc,
+ 0xa7e68bc5, 0x7aa3217d, 0x52a0c93f, 0x8fe56387, 0xedc7eabe, 0x30824006,
+ 0x2982f8cc, 0xf4c75274, 0x96e5db4d, 0x4ba071f5, 0xa4e4aad9, 0x79a10061,
+ 0x1b838958, 0xc6c623e0, 0xdfc69b2a, 0x02833192, 0x60a1b8ab, 0xbde41213,
+ 0xbbc47802, 0x6681d2ba, 0x04a35b83, 0xd9e6f13b, 0xc0e649f1, 0x1da3e349,
+ 0x7f816a70, 0xa2c4c0c8, 0x4d801be4, 0x90c5b15c, 0xf2e73865, 0x2fa292dd,
+ 0x36a22a17, 0xebe780af, 0x89c50996, 0x5480a32e, 0x8585ddb4, 0x58c0770c,
+ 0x3ae2fe35, 0xe7a7548d, 0xfea7ec47, 0x23e246ff, 0x41c0cfc6, 0x9c85657e,
+ 0x73c1be52, 0xae8414ea, 0xcca69dd3, 0x11e3376b, 0x08e38fa1, 0xd5a62519,
+ 0xb784ac20, 0x6ac10698, 0x6ce16c89, 0xb1a4c631, 0xd3864f08, 0x0ec3e5b0,
+ 0x17c35d7a, 0xca86f7c2, 0xa8a47efb, 0x75e1d443, 0x9aa50f6f, 0x47e0a5d7,
+ 0x25c22cee, 0xf8878656, 0xe1873e9c, 0x3cc29424, 0x5ee01d1d, 0x83a5b7a5,
+ 0xf90696d8, 0x24433c60, 0x4661b559, 0x9b241fe1, 0x8224a72b, 0x5f610d93,
+ 0x3d4384aa, 0xe0062e12, 0x0f42f53e, 0xd2075f86, 0xb025d6bf, 0x6d607c07,
+ 0x7460c4cd, 0xa9256e75, 0xcb07e74c, 0x16424df4, 0x106227e5, 0xcd278d5d,
+ 0xaf050464, 0x7240aedc, 0x6b401616, 0xb605bcae, 0xd4273597, 0x09629f2f,
+ 0xe6264403, 0x3b63eebb, 0x59416782, 0x8404cd3a, 0x9d0475f0, 0x4041df48,
+ 0x22635671, 0xff26fcc9, 0x2e238253, 0xf36628eb, 0x9144a1d2, 0x4c010b6a,
+ 0x5501b3a0, 0x88441918, 0xea669021, 0x37233a99, 0xd867e1b5, 0x05224b0d,
+ 0x6700c234, 0xba45688c, 0xa345d046, 0x7e007afe, 0x1c22f3c7, 0xc167597f,
+ 0xc747336e, 0x1a0299d6, 0x782010ef, 0xa565ba57, 0xbc65029d, 0x6120a825,
+ 0x0302211c, 0xde478ba4, 0x31035088, 0xec46fa30, 0x8e647309, 0x5321d9b1,
+ 0x4a21617b, 0x9764cbc3, 0xf54642fa, 0x2803e842
+ }
+};
+// Static table for crc32 (0-255 bits)
+static const unsigned HOST_WIDE_INT crc32_table[CRC32_TABLE_NUM][256] = {
+ {
+ 0x00000000, 0x77073096, 0xee0e612c, 0x990951ba, 0x076dc419, 0x706af48f,
+ 0xe963a535, 0x9e6495a3, 0x0edb8832, 0x79dcb8a4, 0xe0d5e91e, 0x97d2d988,
+ 0x09b64c2b, 0x7eb17cbd, 0xe7b82d07, 0x90bf1d91, 0x1db71064, 0x6ab020f2,
+ 0xf3b97148, 0x84be41de, 0x1adad47d, 0x6ddde4eb, 0xf4d4b551, 0x83d385c7,
+ 0x136c9856, 0x646ba8c0, 0xfd62f97a, 0x8a65c9ec, 0x14015c4f, 0x63066cd9,
+ 0xfa0f3d63, 0x8d080df5, 0x3b6e20c8, 0x4c69105e, 0xd56041e4, 0xa2677172,
+ 0x3c03e4d1, 0x4b04d447, 0xd20d85fd, 0xa50ab56b, 0x35b5a8fa, 0x42b2986c,
+ 0xdbbbc9d6, 0xacbcf940, 0x32d86ce3, 0x45df5c75, 0xdcd60dcf, 0xabd13d59,
+ 0x26d930ac, 0x51de003a, 0xc8d75180, 0xbfd06116, 0x21b4f4b5, 0x56b3c423,
+ 0xcfba9599, 0xb8bda50f, 0x2802b89e, 0x5f058808, 0xc60cd9b2, 0xb10be924,
+ 0x2f6f7c87, 0x58684c11, 0xc1611dab, 0xb6662d3d, 0x76dc4190, 0x01db7106,
+ 0x98d220bc, 0xefd5102a, 0x71b18589, 0x06b6b51f, 0x9fbfe4a5, 0xe8b8d433,
+ 0x7807c9a2, 0x0f00f934, 0x9609a88e, 0xe10e9818, 0x7f6a0dbb, 0x086d3d2d,
+ 0x91646c97, 0xe6635c01, 0x6b6b51f4, 0x1c6c6162, 0x856530d8, 0xf262004e,
+ 0x6c0695ed, 0x1b01a57b, 0x8208f4c1, 0xf50fc457, 0x65b0d9c6, 0x12b7e950,
+ 0x8bbeb8ea, 0xfcb9887c, 0x62dd1ddf, 0x15da2d49, 0x8cd37cf3, 0xfbd44c65,
+ 0x4db26158, 0x3ab551ce, 0xa3bc0074, 0xd4bb30e2, 0x4adfa541, 0x3dd895d7,
+ 0xa4d1c46d, 0xd3d6f4fb, 0x4369e96a, 0x346ed9fc, 0xad678846, 0xda60b8d0,
+ 0x44042d73, 0x33031de5, 0xaa0a4c5f, 0xdd0d7cc9, 0x5005713c, 0x270241aa,
+ 0xbe0b1010, 0xc90c2086, 0x5768b525, 0x206f85b3, 0xb966d409, 0xce61e49f,
+ 0x5edef90e, 0x29d9c998, 0xb0d09822, 0xc7d7a8b4, 0x59b33d17, 0x2eb40d81,
+ 0xb7bd5c3b, 0xc0ba6cad, 0xedb88320, 0x9abfb3b6, 0x03b6e20c, 0x74b1d29a,
+ 0xead54739, 0x9dd277af, 0x04db2615, 0x73dc1683, 0xe3630b12, 0x94643b84,
+ 0x0d6d6a3e, 0x7a6a5aa8, 0xe40ecf0b, 0x9309ff9d, 0x0a00ae27, 0x7d079eb1,
+ 0xf00f9344, 0x8708a3d2, 0x1e01f268, 0x6906c2fe, 0xf762575d, 0x806567cb,
+ 0x196c3671, 0x6e6b06e7, 0xfed41b76, 0x89d32be0, 0x10da7a5a, 0x67dd4acc,
+ 0xf9b9df6f, 0x8ebeeff9, 0x17b7be43, 0x60b08ed5, 0xd6d6a3e8, 0xa1d1937e,
+ 0x38d8c2c4, 0x4fdff252, 0xd1bb67f1, 0xa6bc5767, 0x3fb506dd, 0x48b2364b,
+ 0xd80d2bda, 0xaf0a1b4c, 0x36034af6, 0x41047a60, 0xdf60efc3, 0xa867df55,
+ 0x316e8eef, 0x4669be79, 0xcb61b38c, 0xbc66831a, 0x256fd2a0, 0x5268e236,
+ 0xcc0c7795, 0xbb0b4703, 0x220216b9, 0x5505262f, 0xc5ba3bbe, 0xb2bd0b28,
+ 0x2bb45a92, 0x5cb36a04, 0xc2d7ffa7, 0xb5d0cf31, 0x2cd99e8b, 0x5bdeae1d,
+ 0x9b64c2b0, 0xec63f226, 0x756aa39c, 0x026d930a, 0x9c0906a9, 0xeb0e363f,
+ 0x72076785, 0x05005713, 0x95bf4a82, 0xe2b87a14, 0x7bb12bae, 0x0cb61b38,
+ 0x92d28e9b, 0xe5d5be0d, 0x7cdcefb7, 0x0bdbdf21, 0x86d3d2d4, 0xf1d4e242,
+ 0x68ddb3f8, 0x1fda836e, 0x81be16cd, 0xf6b9265b, 0x6fb077e1, 0x18b74777,
+ 0x88085ae6, 0xff0f6a70, 0x66063bca, 0x11010b5c, 0x8f659eff, 0xf862ae69,
+ 0x616bffd3, 0x166ccf45, 0xa00ae278, 0xd70dd2ee, 0x4e048354, 0x3903b3c2,
+ 0xa7672661, 0xd06016f7, 0x4969474d, 0x3e6e77db, 0xaed16a4a, 0xd9d65adc,
+ 0x40df0b66, 0x37d83bf0, 0xa9bcae53, 0xdebb9ec5, 0x47b2cf7f, 0x30b5ffe9,
+ 0xbdbdf21c, 0xcabac28a, 0x53b39330, 0x24b4a3a6, 0xbad03605, 0xcdd70693,
+ 0x54de5729, 0x23d967bf, 0xb3667a2e, 0xc4614ab8, 0x5d681b02, 0x2a6f2b94,
+ 0xb40bbe37, 0xc30c8ea1, 0x5a05df1b, 0x2d02ef8d
+ }
+};
+
+/* Examine array ref by criteria required for crc32* table.
+ return correct crc32type of CRC32UNDEFINED if crc32 wasn't detected. */
+crc32type
+match_crc32_table (tree crc32_table);
+
+/* Build gimple for __builtin_crc32*. */
+gimple_seq
+get_combined_crc32_seq (crc32_builtin_params);
+
+bool
+detect_crc32_index (tree, crc32_builtin_params *);
+
+gimple *
+lookup_crc32_res (gimple *, crc32_builtin_params *);
+
+#endif /* GCC_CRC32_TABLES_H. */
\ No newline at end of file
diff --git a/gcc/doc/tm.texi b/gcc/doc/tm.texi
index 50bbbbc425093fbd2b4ac9331664df982bccca93..f789c4b5827e84b392ce1366fe9d5fa09dcca7b6 100644
--- a/gcc/doc/tm.texi
+++ b/gcc/doc/tm.texi
@@ -11823,6 +11823,12 @@ If @var{code} is out of range the function should return
@code{error_mark_node}.
@end deftypefn
+@deftypefn {Target Hook} unsigned TARGET_GET_CRC32_BUILTIN_CODE (unsigned @var{code})
+Define this hook to get crc32 built-in code. It should be a function that
+returns the crc32 built-in function code @var{code}. If @var{code} is out of
+range the function should return @samp{AARCH64_BUILTIN_MIN}.
+@end deftypefn
+
@deftypefn {Target Hook} rtx TARGET_EXPAND_BUILTIN (tree @var{exp}, rtx @var{target}, rtx @var{subtarget}, machine_mode @var{mode}, int @var{ignore})
Expand a call to a machine specific built-in function that was set up by
diff --git a/gcc/doc/tm.texi.in b/gcc/doc/tm.texi.in
index cfda603042ac90412de08728989c1b464fb913d2..660ebc90b35767fe2f2972b53b7fc52e3d09bd3a 100644
--- a/gcc/doc/tm.texi.in
+++ b/gcc/doc/tm.texi.in
@@ -7724,6 +7724,8 @@ to by @var{ce_info}.
@hook TARGET_GET_CRC_BUILTIN_CODE
+@hook TARGET_GET_CRC32_BUILTIN_CODE
+
@hook TARGET_EXPAND_BUILTIN
@hook TARGET_RESOLVE_OVERLOADED_BUILTIN
diff --git a/gcc/match.pd b/gcc/match.pd
index 1ebbbfb1872fed0e164a01db91fbea4402b502d8..1b244b14dfde2254dbb955ed91036abd06891619 100644
--- a/gcc/match.pd
+++ b/gcc/match.pd
@@ -4432,6 +4432,116 @@ DEFINE_INT_AND_FLOAT_ROUND_FN (RINT)
)
#endif
+/* CRC32 matchers. */
+#if GIMPLE
+(match crc32ref
+ SSA_NAME@0
+ (with
+ {
+ auto base_stmt = SSA_NAME_DEF_STMT (@0);
+ tree base_tree = gimple_assign_rhs1 (base_stmt);
+ }
+ (if (INTEGRAL_TYPE_P (type) && REFERENCE_CLASS_P (base_tree)))
+ )
+)
+(match crc32data
+ SSA_NAME@0
+ (with
+ {
+ auto base_stmt = SSA_NAME_DEF_STMT (@0);
+ tree base_tree = (gimple_code (base_stmt) != GIMPLE_ASSIGN)
+ ? error_mark_node : gimple_assign_rhs1 (base_stmt);
+ }
+ (if (REFERENCE_CLASS_P (base_tree)))
+ )
+)
+/* Match crc32 table, first index without rshift
+ _4 = (int) _3; //NOP_EXPR (SSA_NAME @2)
+ _5 = _4 ^ c_10; //BIT_XOR_EXPR (SSA_NAME@1, SSA_NAME)
+ _6 = _5 & 255; //BIT_AND_EXPR (SSA_NAME, INTEGER_CST@3). */
+(match (crc32_index_match @0 @1 @2)
+ (convert1?
+ (bit_xor:c (convert2? crc32data@1) SSA_NAME@0)
+ )
+ (if (INTEGRAL_TYPE_P (type)))
+)
+/* Match crc32 table middle, last indexes with rshift. */
+(match (crc32_index_match @0 @1 @2)
+ (convert1?
+ (rshift (bit_xor:c (convert2? crc32data@1) SSA_NAME@0) INTEGER_CST@2)
+ )
+ (if (INTEGRAL_TYPE_P (type)))
+)
+
+/* The order of operations in CRC32 table index computation might vary.
+ In general this case is incorrect. _11 could point to any integer types,
+ not only uint8...
+ _9 = l_16 & 255;
+ _12 = (unsigned int) _11;
+ c_41 = _9 ^ _12;
+ _13 = table0_[c_41]; */
+(match (crc32_index_match @0 @1 @2)
+ (convert1?
+ (bit_xor:c
+ (bit_and SSA_NAME@0 INTEGER_CST@2)
+ (convert2? crc32data@1)
+ )
+ )
+ (if (INTEGRAL_TYPE_P (type) && tree_to_uhwi (@2) == 255))
+)
+
+/* Match simple case of crc32 result
+ _8 = c_12 >> 8;
+ c_19 = _7 ^ _8; */
+(match (crc32b_result_match @0 @1 @2)
+ (bit_xor:c (convert? SSA_NAME@1) (rshift SSA_NAME@0 INTEGER_CST@2))
+ (if (INTEGRAL_TYPE_P (type) && tree_to_uhwi (@2) == 8))
+)
+
+/* crc32 result with no shift
+ if we have no shift it's probably a complex crc32 case
+ so the pattern looks like
+ _8 = table[_6] // Where table[_6] could be a crc32 value
+ c_19 = _7 ^ 8
+ in this case we have to check the next things:
+ 1. both _7, _8 are array_refs
+ 2. indexes of tables emited from the same source
+ 3. the result of XOR for two crc32b results combines to crc32h. */
+(match (crc32h_result_match @0 @1 @2)
+ (bit_xor crc32ref@1 crc32ref@0)
+)
+
+/* if we detect crc32h_result_match it's important to check the last STMT
+ for crc32w/crc32*w is a XOR-combination of 4 table based crc32b results
+ _19 = table3_[_18];
+ _22 = table2_[_21];
+ l_71 = _19 ^ _22;
+ _25 = table1_[_24];
+ l_72 = l_71 ^ _25;
+ _27 = table0_[_26];
+ l_73 = l_72 ^ _27; */
+
+/* crc32*w 4-ops cases. */
+/* pure 3x inner xor, commutated. */
+(match (crc32w_result_match @0 @1 @2 @3)
+ (bit_xor:c
+ (bit_xor:c
+ (bit_xor crc32ref@0 crc32ref@1)
+ crc32ref@2
+ )
+ crc32ref@3
+ )
+)
+/* symmetric xor. */
+(match (crc32w_result_match @0 @1 @2 @3)
+ (bit_xor
+ (bit_xor crc32ref@0 crc32ref@1)
+ (bit_xor crc32ref@2 crc32ref@3)
+ )
+)
+#endif
+/* end of CRC32 matchers. */
+
/* Simplification moved from fold_cond_expr_with_comparison. It may also
be extended. */
/* This pattern implements two kinds simplification:
diff --git a/gcc/target.def b/gcc/target.def
index 142858fa34207fceb3774d375f03c4570b68a320..0e56086ccf36a6a6b0e8e593bb7e45305a5a8a0f 100644
--- a/gcc/target.def
+++ b/gcc/target.def
@@ -2434,6 +2434,16 @@ If @var{code} is out of range the function should return\n\
@code{error_mark_node}.",
tree, (unsigned code, bool initialize_p), NULL)
+/* Return the real code of target-specific crc32 built-in function.
+ Return @samp{AARCH64_BUILTIN_MIN} if CODE is out of the range of valid
+ crc32 codes. */
+DEFHOOK
+(get_crc32_builtin_code,
+ "Define this hook to get crc32 built-in code. It should be a function that\n\
+returns the crc32 built-in function code @var{code}. If @var{code} is out of\n\
+range the function should return @samp{AARCH64_BUILTIN_MIN}.",
+ unsigned, (unsigned code), NULL)
+
/* Initialize (if INITIALIZE_P is true) and return the real code of
target-specific built-in function.
Return NULL if that is not possible. Return error_mark_node if CODE
diff --git a/gcc/testsuite/g++.target/aarch64/crc32cBHW.C b/gcc/testsuite/g++.target/aarch64/crc32cBHW.C
new file mode 100644
index 0000000000000000000000000000000000000000..3963b153ad094f961998746459a26fd12dd2fe83
--- /dev/null
+++ b/gcc/testsuite/g++.target/aarch64/crc32cBHW.C
@@ -0,0 +1,311 @@
+/* { dg-do run } */
+/* { dg-options "-save-temps -O2 -fcrypto-accel-crc32 -march=armv8.2-a+crc -fdump-tree-forwprop-details" } */
+
+#include
+#include
+
+static const uint32_t table0_[256] = {
+ 0x00000000, 0xf26b8303, 0xe13b70f7, 0x1350f3f4, 0xc79a971f, 0x35f1141c,
+ 0x26a1e7e8, 0xd4ca64eb, 0x8ad958cf, 0x78b2dbcc, 0x6be22838, 0x9989ab3b,
+ 0x4d43cfd0, 0xbf284cd3, 0xac78bf27, 0x5e133c24, 0x105ec76f, 0xe235446c,
+ 0xf165b798, 0x030e349b, 0xd7c45070, 0x25afd373, 0x36ff2087, 0xc494a384,
+ 0x9a879fa0, 0x68ec1ca3, 0x7bbcef57, 0x89d76c54, 0x5d1d08bf, 0xaf768bbc,
+ 0xbc267848, 0x4e4dfb4b, 0x20bd8ede, 0xd2d60ddd, 0xc186fe29, 0x33ed7d2a,
+ 0xe72719c1, 0x154c9ac2, 0x061c6936, 0xf477ea35, 0xaa64d611, 0x580f5512,
+ 0x4b5fa6e6, 0xb93425e5, 0x6dfe410e, 0x9f95c20d, 0x8cc531f9, 0x7eaeb2fa,
+ 0x30e349b1, 0xc288cab2, 0xd1d83946, 0x23b3ba45, 0xf779deae, 0x05125dad,
+ 0x1642ae59, 0xe4292d5a, 0xba3a117e, 0x4851927d, 0x5b016189, 0xa96ae28a,
+ 0x7da08661, 0x8fcb0562, 0x9c9bf696, 0x6ef07595, 0x417b1dbc, 0xb3109ebf,
+ 0xa0406d4b, 0x522bee48, 0x86e18aa3, 0x748a09a0, 0x67dafa54, 0x95b17957,
+ 0xcba24573, 0x39c9c670, 0x2a993584, 0xd8f2b687, 0x0c38d26c, 0xfe53516f,
+ 0xed03a29b, 0x1f682198, 0x5125dad3, 0xa34e59d0, 0xb01eaa24, 0x42752927,
+ 0x96bf4dcc, 0x64d4cecf, 0x77843d3b, 0x85efbe38, 0xdbfc821c, 0x2997011f,
+ 0x3ac7f2eb, 0xc8ac71e8, 0x1c661503, 0xee0d9600, 0xfd5d65f4, 0x0f36e6f7,
+ 0x61c69362, 0x93ad1061, 0x80fde395, 0x72966096, 0xa65c047d, 0x5437877e,
+ 0x4767748a, 0xb50cf789, 0xeb1fcbad, 0x197448ae, 0x0a24bb5a, 0xf84f3859,
+ 0x2c855cb2, 0xdeeedfb1, 0xcdbe2c45, 0x3fd5af46, 0x7198540d, 0x83f3d70e,
+ 0x90a324fa, 0x62c8a7f9, 0xb602c312, 0x44694011, 0x5739b3e5, 0xa55230e6,
+ 0xfb410cc2, 0x092a8fc1, 0x1a7a7c35, 0xe811ff36, 0x3cdb9bdd, 0xceb018de,
+ 0xdde0eb2a, 0x2f8b6829, 0x82f63b78, 0x709db87b, 0x63cd4b8f, 0x91a6c88c,
+ 0x456cac67, 0xb7072f64, 0xa457dc90, 0x563c5f93, 0x082f63b7, 0xfa44e0b4,
+ 0xe9141340, 0x1b7f9043, 0xcfb5f4a8, 0x3dde77ab, 0x2e8e845f, 0xdce5075c,
+ 0x92a8fc17, 0x60c37f14, 0x73938ce0, 0x81f80fe3, 0x55326b08, 0xa759e80b,
+ 0xb4091bff, 0x466298fc, 0x1871a4d8, 0xea1a27db, 0xf94ad42f, 0x0b21572c,
+ 0xdfeb33c7, 0x2d80b0c4, 0x3ed04330, 0xccbbc033, 0xa24bb5a6, 0x502036a5,
+ 0x4370c551, 0xb11b4652, 0x65d122b9, 0x97baa1ba, 0x84ea524e, 0x7681d14d,
+ 0x2892ed69, 0xdaf96e6a, 0xc9a99d9e, 0x3bc21e9d, 0xef087a76, 0x1d63f975,
+ 0x0e330a81, 0xfc588982, 0xb21572c9, 0x407ef1ca, 0x532e023e, 0xa145813d,
+ 0x758fe5d6, 0x87e466d5, 0x94b49521, 0x66df1622, 0x38cc2a06, 0xcaa7a905,
+ 0xd9f75af1, 0x2b9cd9f2, 0xff56bd19, 0x0d3d3e1a, 0x1e6dcdee, 0xec064eed,
+ 0xc38d26c4, 0x31e6a5c7, 0x22b65633, 0xd0ddd530, 0x0417b1db, 0xf67c32d8,
+ 0xe52cc12c, 0x1747422f, 0x49547e0b, 0xbb3ffd08, 0xa86f0efc, 0x5a048dff,
+ 0x8ecee914, 0x7ca56a17, 0x6ff599e3, 0x9d9e1ae0, 0xd3d3e1ab, 0x21b862a8,
+ 0x32e8915c, 0xc083125f, 0x144976b4, 0xe622f5b7, 0xf5720643, 0x07198540,
+ 0x590ab964, 0xab613a67, 0xb831c993, 0x4a5a4a90, 0x9e902e7b, 0x6cfbad78,
+ 0x7fab5e8c, 0x8dc0dd8f, 0xe330a81a, 0x115b2b19, 0x020bd8ed, 0xf0605bee,
+ 0x24aa3f05, 0xd6c1bc06, 0xc5914ff2, 0x37faccf1, 0x69e9f0d5, 0x9b8273d6,
+ 0x88d28022, 0x7ab90321, 0xae7367ca, 0x5c18e4c9, 0x4f48173d, 0xbd23943e,
+ 0xf36e6f75, 0x0105ec76, 0x12551f82, 0xe03e9c81, 0x34f4f86a, 0xc69f7b69,
+ 0xd5cf889d, 0x27a40b9e, 0x79b737ba, 0x8bdcb4b9, 0x988c474d, 0x6ae7c44e,
+ 0xbe2da0a5, 0x4c4623a6, 0x5f16d052, 0xad7d5351};
+static const uint32_t table1_[256] = {
+ 0x00000000, 0x13a29877, 0x274530ee, 0x34e7a899, 0x4e8a61dc, 0x5d28f9ab,
+ 0x69cf5132, 0x7a6dc945, 0x9d14c3b8, 0x8eb65bcf, 0xba51f356, 0xa9f36b21,
+ 0xd39ea264, 0xc03c3a13, 0xf4db928a, 0xe7790afd, 0x3fc5f181, 0x2c6769f6,
+ 0x1880c16f, 0x0b225918, 0x714f905d, 0x62ed082a, 0x560aa0b3, 0x45a838c4,
+ 0xa2d13239, 0xb173aa4e, 0x859402d7, 0x96369aa0, 0xec5b53e5, 0xfff9cb92,
+ 0xcb1e630b, 0xd8bcfb7c, 0x7f8be302, 0x6c297b75, 0x58ced3ec, 0x4b6c4b9b,
+ 0x310182de, 0x22a31aa9, 0x1644b230, 0x05e62a47, 0xe29f20ba, 0xf13db8cd,
+ 0xc5da1054, 0xd6788823, 0xac154166, 0xbfb7d911, 0x8b507188, 0x98f2e9ff,
+ 0x404e1283, 0x53ec8af4, 0x670b226d, 0x74a9ba1a, 0x0ec4735f, 0x1d66eb28,
+ 0x298143b1, 0x3a23dbc6, 0xdd5ad13b, 0xcef8494c, 0xfa1fe1d5, 0xe9bd79a2,
+ 0x93d0b0e7, 0x80722890, 0xb4958009, 0xa737187e, 0xff17c604, 0xecb55e73,
+ 0xd852f6ea, 0xcbf06e9d, 0xb19da7d8, 0xa23f3faf, 0x96d89736, 0x857a0f41,
+ 0x620305bc, 0x71a19dcb, 0x45463552, 0x56e4ad25, 0x2c896460, 0x3f2bfc17,
+ 0x0bcc548e, 0x186eccf9, 0xc0d23785, 0xd370aff2, 0xe797076b, 0xf4359f1c,
+ 0x8e585659, 0x9dface2e, 0xa91d66b7, 0xbabffec0, 0x5dc6f43d, 0x4e646c4a,
+ 0x7a83c4d3, 0x69215ca4, 0x134c95e1, 0x00ee0d96, 0x3409a50f, 0x27ab3d78,
+ 0x809c2506, 0x933ebd71, 0xa7d915e8, 0xb47b8d9f, 0xce1644da, 0xddb4dcad,
+ 0xe9537434, 0xfaf1ec43, 0x1d88e6be, 0x0e2a7ec9, 0x3acdd650, 0x296f4e27,
+ 0x53028762, 0x40a01f15, 0x7447b78c, 0x67e52ffb, 0xbf59d487, 0xacfb4cf0,
+ 0x981ce469, 0x8bbe7c1e, 0xf1d3b55b, 0xe2712d2c, 0xd69685b5, 0xc5341dc2,
+ 0x224d173f, 0x31ef8f48, 0x050827d1, 0x16aabfa6, 0x6cc776e3, 0x7f65ee94,
+ 0x4b82460d, 0x5820de7a, 0xfbc3faf9, 0xe861628e, 0xdc86ca17, 0xcf245260,
+ 0xb5499b25, 0xa6eb0352, 0x920cabcb, 0x81ae33bc, 0x66d73941, 0x7575a136,
+ 0x419209af, 0x523091d8, 0x285d589d, 0x3bffc0ea, 0x0f186873, 0x1cbaf004,
+ 0xc4060b78, 0xd7a4930f, 0xe3433b96, 0xf0e1a3e1, 0x8a8c6aa4, 0x992ef2d3,
+ 0xadc95a4a, 0xbe6bc23d, 0x5912c8c0, 0x4ab050b7, 0x7e57f82e, 0x6df56059,
+ 0x1798a91c, 0x043a316b, 0x30dd99f2, 0x237f0185, 0x844819fb, 0x97ea818c,
+ 0xa30d2915, 0xb0afb162, 0xcac27827, 0xd960e050, 0xed8748c9, 0xfe25d0be,
+ 0x195cda43, 0x0afe4234, 0x3e19eaad, 0x2dbb72da, 0x57d6bb9f, 0x447423e8,
+ 0x70938b71, 0x63311306, 0xbb8de87a, 0xa82f700d, 0x9cc8d894, 0x8f6a40e3,
+ 0xf50789a6, 0xe6a511d1, 0xd242b948, 0xc1e0213f, 0x26992bc2, 0x353bb3b5,
+ 0x01dc1b2c, 0x127e835b, 0x68134a1e, 0x7bb1d269, 0x4f567af0, 0x5cf4e287,
+ 0x04d43cfd, 0x1776a48a, 0x23910c13, 0x30339464, 0x4a5e5d21, 0x59fcc556,
+ 0x6d1b6dcf, 0x7eb9f5b8, 0x99c0ff45, 0x8a626732, 0xbe85cfab, 0xad2757dc,
+ 0xd74a9e99, 0xc4e806ee, 0xf00fae77, 0xe3ad3600, 0x3b11cd7c, 0x28b3550b,
+ 0x1c54fd92, 0x0ff665e5, 0x759baca0, 0x663934d7, 0x52de9c4e, 0x417c0439,
+ 0xa6050ec4, 0xb5a796b3, 0x81403e2a, 0x92e2a65d, 0xe88f6f18, 0xfb2df76f,
+ 0xcfca5ff6, 0xdc68c781, 0x7b5fdfff, 0x68fd4788, 0x5c1aef11, 0x4fb87766,
+ 0x35d5be23, 0x26772654, 0x12908ecd, 0x013216ba, 0xe64b1c47, 0xf5e98430,
+ 0xc10e2ca9, 0xd2acb4de, 0xa8c17d9b, 0xbb63e5ec, 0x8f844d75, 0x9c26d502,
+ 0x449a2e7e, 0x5738b609, 0x63df1e90, 0x707d86e7, 0x0a104fa2, 0x19b2d7d5,
+ 0x2d557f4c, 0x3ef7e73b, 0xd98eedc6, 0xca2c75b1, 0xfecbdd28, 0xed69455f,
+ 0x97048c1a, 0x84a6146d, 0xb041bcf4, 0xa3e32483};
+static const uint32_t table2_[256] = {
+ 0x00000000, 0xa541927e, 0x4f6f520d, 0xea2ec073, 0x9edea41a, 0x3b9f3664,
+ 0xd1b1f617, 0x74f06469, 0x38513ec5, 0x9d10acbb, 0x773e6cc8, 0xd27ffeb6,
+ 0xa68f9adf, 0x03ce08a1, 0xe9e0c8d2, 0x4ca15aac, 0x70a27d8a, 0xd5e3eff4,
+ 0x3fcd2f87, 0x9a8cbdf9, 0xee7cd990, 0x4b3d4bee, 0xa1138b9d, 0x045219e3,
+ 0x48f3434f, 0xedb2d131, 0x079c1142, 0xa2dd833c, 0xd62de755, 0x736c752b,
+ 0x9942b558, 0x3c032726, 0xe144fb14, 0x4405696a, 0xae2ba919, 0x0b6a3b67,
+ 0x7f9a5f0e, 0xdadbcd70, 0x30f50d03, 0x95b49f7d, 0xd915c5d1, 0x7c5457af,
+ 0x967a97dc, 0x333b05a2, 0x47cb61cb, 0xe28af3b5, 0x08a433c6, 0xade5a1b8,
+ 0x91e6869e, 0x34a714e0, 0xde89d493, 0x7bc846ed, 0x0f382284, 0xaa79b0fa,
+ 0x40577089, 0xe516e2f7, 0xa9b7b85b, 0x0cf62a25, 0xe6d8ea56, 0x43997828,
+ 0x37691c41, 0x92288e3f, 0x78064e4c, 0xdd47dc32, 0xc76580d9, 0x622412a7,
+ 0x880ad2d4, 0x2d4b40aa, 0x59bb24c3, 0xfcfab6bd, 0x16d476ce, 0xb395e4b0,
+ 0xff34be1c, 0x5a752c62, 0xb05bec11, 0x151a7e6f, 0x61ea1a06, 0xc4ab8878,
+ 0x2e85480b, 0x8bc4da75, 0xb7c7fd53, 0x12866f2d, 0xf8a8af5e, 0x5de93d20,
+ 0x29195949, 0x8c58cb37, 0x66760b44, 0xc337993a, 0x8f96c396, 0x2ad751e8,
+ 0xc0f9919b, 0x65b803e5, 0x1148678c, 0xb409f5f2, 0x5e273581, 0xfb66a7ff,
+ 0x26217bcd, 0x8360e9b3, 0x694e29c0, 0xcc0fbbbe, 0xb8ffdfd7, 0x1dbe4da9,
+ 0xf7908dda, 0x52d11fa4, 0x1e704508, 0xbb31d776, 0x511f1705, 0xf45e857b,
+ 0x80aee112, 0x25ef736c, 0xcfc1b31f, 0x6a802161, 0x56830647, 0xf3c29439,
+ 0x19ec544a, 0xbcadc634, 0xc85da25d, 0x6d1c3023, 0x8732f050, 0x2273622e,
+ 0x6ed23882, 0xcb93aafc, 0x21bd6a8f, 0x84fcf8f1, 0xf00c9c98, 0x554d0ee6,
+ 0xbf63ce95, 0x1a225ceb, 0x8b277743, 0x2e66e53d, 0xc448254e, 0x6109b730,
+ 0x15f9d359, 0xb0b84127, 0x5a968154, 0xffd7132a, 0xb3764986, 0x1637dbf8,
+ 0xfc191b8b, 0x595889f5, 0x2da8ed9c, 0x88e97fe2, 0x62c7bf91, 0xc7862def,
+ 0xfb850ac9, 0x5ec498b7, 0xb4ea58c4, 0x11abcaba, 0x655baed3, 0xc01a3cad,
+ 0x2a34fcde, 0x8f756ea0, 0xc3d4340c, 0x6695a672, 0x8cbb6601, 0x29faf47f,
+ 0x5d0a9016, 0xf84b0268, 0x1265c21b, 0xb7245065, 0x6a638c57, 0xcf221e29,
+ 0x250cde5a, 0x804d4c24, 0xf4bd284d, 0x51fcba33, 0xbbd27a40, 0x1e93e83e,
+ 0x5232b292, 0xf77320ec, 0x1d5de09f, 0xb81c72e1, 0xccec1688, 0x69ad84f6,
+ 0x83834485, 0x26c2d6fb, 0x1ac1f1dd, 0xbf8063a3, 0x55aea3d0, 0xf0ef31ae,
+ 0x841f55c7, 0x215ec7b9, 0xcb7007ca, 0x6e3195b4, 0x2290cf18, 0x87d15d66,
+ 0x6dff9d15, 0xc8be0f6b, 0xbc4e6b02, 0x190ff97c, 0xf321390f, 0x5660ab71,
+ 0x4c42f79a, 0xe90365e4, 0x032da597, 0xa66c37e9, 0xd29c5380, 0x77ddc1fe,
+ 0x9df3018d, 0x38b293f3, 0x7413c95f, 0xd1525b21, 0x3b7c9b52, 0x9e3d092c,
+ 0xeacd6d45, 0x4f8cff3b, 0xa5a23f48, 0x00e3ad36, 0x3ce08a10, 0x99a1186e,
+ 0x738fd81d, 0xd6ce4a63, 0xa23e2e0a, 0x077fbc74, 0xed517c07, 0x4810ee79,
+ 0x04b1b4d5, 0xa1f026ab, 0x4bdee6d8, 0xee9f74a6, 0x9a6f10cf, 0x3f2e82b1,
+ 0xd50042c2, 0x7041d0bc, 0xad060c8e, 0x08479ef0, 0xe2695e83, 0x4728ccfd,
+ 0x33d8a894, 0x96993aea, 0x7cb7fa99, 0xd9f668e7, 0x9557324b, 0x3016a035,
+ 0xda386046, 0x7f79f238, 0x0b899651, 0xaec8042f, 0x44e6c45c, 0xe1a75622,
+ 0xdda47104, 0x78e5e37a, 0x92cb2309, 0x378ab177, 0x437ad51e, 0xe63b4760,
+ 0x0c158713, 0xa954156d, 0xe5f54fc1, 0x40b4ddbf, 0xaa9a1dcc, 0x0fdb8fb2,
+ 0x7b2bebdb, 0xde6a79a5, 0x3444b9d6, 0x91052ba8};
+static const uint32_t table3_[256] = {
+ 0x00000000, 0xdd45aab8, 0xbf672381, 0x62228939, 0x7b2231f3, 0xa6679b4b,
+ 0xc4451272, 0x1900b8ca, 0xf64463e6, 0x2b01c95e, 0x49234067, 0x9466eadf,
+ 0x8d665215, 0x5023f8ad, 0x32017194, 0xef44db2c, 0xe964b13d, 0x34211b85,
+ 0x560392bc, 0x8b463804, 0x924680ce, 0x4f032a76, 0x2d21a34f, 0xf06409f7,
+ 0x1f20d2db, 0xc2657863, 0xa047f15a, 0x7d025be2, 0x6402e328, 0xb9474990,
+ 0xdb65c0a9, 0x06206a11, 0xd725148b, 0x0a60be33, 0x6842370a, 0xb5079db2,
+ 0xac072578, 0x71428fc0, 0x136006f9, 0xce25ac41, 0x2161776d, 0xfc24ddd5,
+ 0x9e0654ec, 0x4343fe54, 0x5a43469e, 0x8706ec26, 0xe524651f, 0x3861cfa7,
+ 0x3e41a5b6, 0xe3040f0e, 0x81268637, 0x5c632c8f, 0x45639445, 0x98263efd,
+ 0xfa04b7c4, 0x27411d7c, 0xc805c650, 0x15406ce8, 0x7762e5d1, 0xaa274f69,
+ 0xb327f7a3, 0x6e625d1b, 0x0c40d422, 0xd1057e9a, 0xaba65fe7, 0x76e3f55f,
+ 0x14c17c66, 0xc984d6de, 0xd0846e14, 0x0dc1c4ac, 0x6fe34d95, 0xb2a6e72d,
+ 0x5de23c01, 0x80a796b9, 0xe2851f80, 0x3fc0b538, 0x26c00df2, 0xfb85a74a,
+ 0x99a72e73, 0x44e284cb, 0x42c2eeda, 0x9f874462, 0xfda5cd5b, 0x20e067e3,
+ 0x39e0df29, 0xe4a57591, 0x8687fca8, 0x5bc25610, 0xb4868d3c, 0x69c32784,
+ 0x0be1aebd, 0xd6a40405, 0xcfa4bccf, 0x12e11677, 0x70c39f4e, 0xad8635f6,
+ 0x7c834b6c, 0xa1c6e1d4, 0xc3e468ed, 0x1ea1c255, 0x07a17a9f, 0xdae4d027,
+ 0xb8c6591e, 0x6583f3a6, 0x8ac7288a, 0x57828232, 0x35a00b0b, 0xe8e5a1b3,
+ 0xf1e51979, 0x2ca0b3c1, 0x4e823af8, 0x93c79040, 0x95e7fa51, 0x48a250e9,
+ 0x2a80d9d0, 0xf7c57368, 0xeec5cba2, 0x3380611a, 0x51a2e823, 0x8ce7429b,
+ 0x63a399b7, 0xbee6330f, 0xdcc4ba36, 0x0181108e, 0x1881a844, 0xc5c402fc,
+ 0xa7e68bc5, 0x7aa3217d, 0x52a0c93f, 0x8fe56387, 0xedc7eabe, 0x30824006,
+ 0x2982f8cc, 0xf4c75274, 0x96e5db4d, 0x4ba071f5, 0xa4e4aad9, 0x79a10061,
+ 0x1b838958, 0xc6c623e0, 0xdfc69b2a, 0x02833192, 0x60a1b8ab, 0xbde41213,
+ 0xbbc47802, 0x6681d2ba, 0x04a35b83, 0xd9e6f13b, 0xc0e649f1, 0x1da3e349,
+ 0x7f816a70, 0xa2c4c0c8, 0x4d801be4, 0x90c5b15c, 0xf2e73865, 0x2fa292dd,
+ 0x36a22a17, 0xebe780af, 0x89c50996, 0x5480a32e, 0x8585ddb4, 0x58c0770c,
+ 0x3ae2fe35, 0xe7a7548d, 0xfea7ec47, 0x23e246ff, 0x41c0cfc6, 0x9c85657e,
+ 0x73c1be52, 0xae8414ea, 0xcca69dd3, 0x11e3376b, 0x08e38fa1, 0xd5a62519,
+ 0xb784ac20, 0x6ac10698, 0x6ce16c89, 0xb1a4c631, 0xd3864f08, 0x0ec3e5b0,
+ 0x17c35d7a, 0xca86f7c2, 0xa8a47efb, 0x75e1d443, 0x9aa50f6f, 0x47e0a5d7,
+ 0x25c22cee, 0xf8878656, 0xe1873e9c, 0x3cc29424, 0x5ee01d1d, 0x83a5b7a5,
+ 0xf90696d8, 0x24433c60, 0x4661b559, 0x9b241fe1, 0x8224a72b, 0x5f610d93,
+ 0x3d4384aa, 0xe0062e12, 0x0f42f53e, 0xd2075f86, 0xb025d6bf, 0x6d607c07,
+ 0x7460c4cd, 0xa9256e75, 0xcb07e74c, 0x16424df4, 0x106227e5, 0xcd278d5d,
+ 0xaf050464, 0x7240aedc, 0x6b401616, 0xb605bcae, 0xd4273597, 0x09629f2f,
+ 0xe6264403, 0x3b63eebb, 0x59416782, 0x8404cd3a, 0x9d0475f0, 0x4041df48,
+ 0x22635671, 0xff26fcc9, 0x2e238253, 0xf36628eb, 0x9144a1d2, 0x4c010b6a,
+ 0x5501b3a0, 0x88441918, 0xea669021, 0x37233a99, 0xd867e1b5, 0x05224b0d,
+ 0x6700c234, 0xba45688c, 0xa345d046, 0x7e007afe, 0x1c22f3c7, 0xc167597f,
+ 0xc747336e, 0x1a0299d6, 0x782010ef, 0xa565ba57, 0xbc65029d, 0x6120a825,
+ 0x0302211c, 0xde478ba4, 0x31035088, 0xec46fa30, 0x8e647309, 0x5321d9b1,
+ 0x4a21617b, 0x9764cbc3, 0xf54642fa, 0x2803e842};
+
+/* Simplifiled load function for case of crc32cw. */
+static inline uint32_t LE_LOAD32 (const uint8_t *ptr)
+{
+ uint32_t result;
+ memcpy (&result, ptr, sizeof (result));
+ return result;
+}
+/* Simplifiled load function for case of crc32ch. */
+static inline uint16_t LE_LOAD16 (const uint8_t *ptr)
+{
+ uint16_t result;
+ memcpy (&result, ptr, sizeof (result));
+ return result;
+}
+
+uint32_t Extend (uint32_t crc, const char *buf, size_t size)
+{
+ const uint8_t *p = reinterpret_cast(buf);
+ const uint8_t *e = p + size;
+ uint32_t l = crc ^ 0xffffffffu;
+
+#define STEP1 \
+ do { \
+ int c = (l & 0xff) ^ *p++; \
+ l = table0_[c] ^ (l >> 8); \
+ } while (0)
+
+#define STEP2 \
+ do { \
+ uint32_t c = (l) ^ LE_LOAD16 (p); \
+ p += 2; \
+ l = table1_[(c >> 0) & 0xff] ^ table0_[c >> 8]; \
+ } while (0)
+
+#define STEP2x2 \
+ do { \
+ uint32_t c = (l) ^ LE_LOAD16 (p); \
+ p += 2; \
+ l = table1_[(c >> 0) & 0xff] ^ table0_[c >> 8]; \
+ uint32_t c2 = (l) ^ LE_LOAD16(p); \
+ p += 2; \
+ l = table1_[(c2 >> 0) & 0xff] ^ table0_[c2 >> 8]; \
+ } while (0)
+
+#define STEP4 \
+ do { \
+ uint32_t c = l ^ LE_LOAD32 (p); \
+ p += 4; \
+ l = table3_[c & 0xff] ^ table2_[(c >> 8) & 0xff] ^ \
+ table1_[(c >> 16) & 0xff] ^ table0_[c >> 24]; \
+ } while (0)
+
+#define STEP4v2 \
+ do { \
+ uint32_t c = l ^ LE_LOAD32 (p); \
+ p += 4; \
+ uint32_t l1 = table3_[c & 0xff] ^ table2_[(c >> 8) & 0xff]; \
+ uint32_t l2 = table1_[(c >> 16) & 0xff] ^ table0_[c >> 24]; \
+ l = l1 ^ l2; \
+ } while (0)
+
+
+#define STEP4CRC32CW \
+ do { \
+ l = __builtin_aarch64_crc32cw (l, LE_LOAD32(p)); \
+ p += 4; \
+ } while(0) \
+
+ // Point x at first 4-byte aligned byte in string. This might be
+ // just past the end of the string.
+ const uintptr_t pval = reinterpret_cast(p);
+ const uint8_t *x = reinterpret_cast(((pval + 3) >> 2) << 2);
+ if (x <= e)
+ {
+ // Process bytes until finished or p is 4-byte aligned
+ while (p != x)
+ STEP1;
+ }
+
+ // Process bytes 4 at a time
+ while ((e-p) >= 8)
+ {
+ STEP4;
+ STEP4v2;
+ }
+
+ // Process bytes 4 at a time using crc32cH
+ while ((e - p) >= 2)
+ {
+ STEP2;
+ }
+
+ // Process the last few bytes
+ while (p != e)
+ {
+ STEP1;
+ }
+#undef STEP4
+#undef STEP4v2
+#undef STEP4CRC32CW
+#undef STEP2x2
+#undef STEP2
+#undef STEP1
+ return l ^ 0xffffffffu;
+}
+
+void test (unsigned int a, unsigned int b)
+{
+ if (a != b)
+ __builtin_abort ();
+}
+
+int main (){
+ char buf[32];
+
+ memset (buf, 0, sizeof (buf));
+ test (0x8a9136aa, Extend (0, buf, sizeof (buf)));
+
+ uint32_t crc = Extend (0, "hello ", 6);
+ uint32_t etalon_crc = Extend (0, "hello world", 11);
+ test (0xc99465aa, Extend (crc,"world",5));
+ return 0;
+}
+
+/* { dg-final { scan-assembler-times "crc32cw" 2 } } */
+/* { dg-final { scan-assembler "crc32ch" } } */
+/* { dg-final { scan-assembler-times "crc32cb" 2 } } */
+/* { dg-final { scan-tree-dump-times "Inserted crc32_builtin" 8 "forwprop1" } } */
\ No newline at end of file
diff --git a/gcc/testsuite/gcc.dg/tree-ssa/loop-crc-success.c b/gcc/testsuite/gcc.dg/tree-ssa/loop-crc-success.c
new file mode 100644
index 0000000000000000000000000000000000000000..c5d9f0995fb69b50d58e8d533c823478cfd97bac
--- /dev/null
+++ b/gcc/testsuite/gcc.dg/tree-ssa/loop-crc-success.c
@@ -0,0 +1,117 @@
+/* { dg-do compile } */
+/* { dg-options "-O3 -mabi=lp64 -fcrypto-accel-crc32 -march=armv8.1-a+crc -fdump-tree-forwprop-details" } */
+
+#include
+#include
+typedef unsigned long ulg;
+typedef unsigned char uch;
+
+static const ulg crc_32_tab[] = {
+ 0x00000000L, 0x77073096L, 0xee0e612cL, 0x990951baL, 0x076dc419L,
+ 0x706af48fL, 0xe963a535L, 0x9e6495a3L, 0x0edb8832L, 0x79dcb8a4L,
+ 0xe0d5e91eL, 0x97d2d988L, 0x09b64c2bL, 0x7eb17cbdL, 0xe7b82d07L,
+ 0x90bf1d91L, 0x1db71064L, 0x6ab020f2L, 0xf3b97148L, 0x84be41deL,
+ 0x1adad47dL, 0x6ddde4ebL, 0xf4d4b551L, 0x83d385c7L, 0x136c9856L,
+ 0x646ba8c0L, 0xfd62f97aL, 0x8a65c9ecL, 0x14015c4fL, 0x63066cd9L,
+ 0xfa0f3d63L, 0x8d080df5L, 0x3b6e20c8L, 0x4c69105eL, 0xd56041e4L,
+ 0xa2677172L, 0x3c03e4d1L, 0x4b04d447L, 0xd20d85fdL, 0xa50ab56bL,
+ 0x35b5a8faL, 0x42b2986cL, 0xdbbbc9d6L, 0xacbcf940L, 0x32d86ce3L,
+ 0x45df5c75L, 0xdcd60dcfL, 0xabd13d59L, 0x26d930acL, 0x51de003aL,
+ 0xc8d75180L, 0xbfd06116L, 0x21b4f4b5L, 0x56b3c423L, 0xcfba9599L,
+ 0xb8bda50fL, 0x2802b89eL, 0x5f058808L, 0xc60cd9b2L, 0xb10be924L,
+ 0x2f6f7c87L, 0x58684c11L, 0xc1611dabL, 0xb6662d3dL, 0x76dc4190L,
+ 0x01db7106L, 0x98d220bcL, 0xefd5102aL, 0x71b18589L, 0x06b6b51fL,
+ 0x9fbfe4a5L, 0xe8b8d433L, 0x7807c9a2L, 0x0f00f934L, 0x9609a88eL,
+ 0xe10e9818L, 0x7f6a0dbbL, 0x086d3d2dL, 0x91646c97L, 0xe6635c01L,
+ 0x6b6b51f4L, 0x1c6c6162L, 0x856530d8L, 0xf262004eL, 0x6c0695edL,
+ 0x1b01a57bL, 0x8208f4c1L, 0xf50fc457L, 0x65b0d9c6L, 0x12b7e950L,
+ 0x8bbeb8eaL, 0xfcb9887cL, 0x62dd1ddfL, 0x15da2d49L, 0x8cd37cf3L,
+ 0xfbd44c65L, 0x4db26158L, 0x3ab551ceL, 0xa3bc0074L, 0xd4bb30e2L,
+ 0x4adfa541L, 0x3dd895d7L, 0xa4d1c46dL, 0xd3d6f4fbL, 0x4369e96aL,
+ 0x346ed9fcL, 0xad678846L, 0xda60b8d0L, 0x44042d73L, 0x33031de5L,
+ 0xaa0a4c5fL, 0xdd0d7cc9L, 0x5005713cL, 0x270241aaL, 0xbe0b1010L,
+ 0xc90c2086L, 0x5768b525L, 0x206f85b3L, 0xb966d409L, 0xce61e49fL,
+ 0x5edef90eL, 0x29d9c998L, 0xb0d09822L, 0xc7d7a8b4L, 0x59b33d17L,
+ 0x2eb40d81L, 0xb7bd5c3bL, 0xc0ba6cadL, 0xedb88320L, 0x9abfb3b6L,
+ 0x03b6e20cL, 0x74b1d29aL, 0xead54739L, 0x9dd277afL, 0x04db2615L,
+ 0x73dc1683L, 0xe3630b12L, 0x94643b84L, 0x0d6d6a3eL, 0x7a6a5aa8L,
+ 0xe40ecf0bL, 0x9309ff9dL, 0x0a00ae27L, 0x7d079eb1L, 0xf00f9344L,
+ 0x8708a3d2L, 0x1e01f268L, 0x6906c2feL, 0xf762575dL, 0x806567cbL,
+ 0x196c3671L, 0x6e6b06e7L, 0xfed41b76L, 0x89d32be0L, 0x10da7a5aL,
+ 0x67dd4accL, 0xf9b9df6fL, 0x8ebeeff9L, 0x17b7be43L, 0x60b08ed5L,
+ 0xd6d6a3e8L, 0xa1d1937eL, 0x38d8c2c4L, 0x4fdff252L, 0xd1bb67f1L,
+ 0xa6bc5767L, 0x3fb506ddL, 0x48b2364bL, 0xd80d2bdaL, 0xaf0a1b4cL,
+ 0x36034af6L, 0x41047a60L, 0xdf60efc3L, 0xa867df55L, 0x316e8eefL,
+ 0x4669be79L, 0xcb61b38cL, 0xbc66831aL, 0x256fd2a0L, 0x5268e236L,
+ 0xcc0c7795L, 0xbb0b4703L, 0x220216b9L, 0x5505262fL, 0xc5ba3bbeL,
+ 0xb2bd0b28L, 0x2bb45a92L, 0x5cb36a04L, 0xc2d7ffa7L, 0xb5d0cf31L,
+ 0x2cd99e8bL, 0x5bdeae1dL, 0x9b64c2b0L, 0xec63f226L, 0x756aa39cL,
+ 0x026d930aL, 0x9c0906a9L, 0xeb0e363fL, 0x72076785L, 0x05005713L,
+ 0x95bf4a82L, 0xe2b87a14L, 0x7bb12baeL, 0x0cb61b38L, 0x92d28e9bL,
+ 0xe5d5be0dL, 0x7cdcefb7L, 0x0bdbdf21L, 0x86d3d2d4L, 0xf1d4e242L,
+ 0x68ddb3f8L, 0x1fda836eL, 0x81be16cdL, 0xf6b9265bL, 0x6fb077e1L,
+ 0x18b74777L, 0x88085ae6L, 0xff0f6a70L, 0x66063bcaL, 0x11010b5cL,
+ 0x8f659effL, 0xf862ae69L, 0x616bffd3L, 0x166ccf45L, 0xa00ae278L,
+ 0xd70dd2eeL, 0x4e048354L, 0x3903b3c2L, 0xa7672661L, 0xd06016f7L,
+ 0x4969474dL, 0x3e6e77dbL, 0xaed16a4aL, 0xd9d65adcL, 0x40df0b66L,
+ 0x37d83bf0L, 0xa9bcae53L, 0xdebb9ec5L, 0x47b2cf7fL, 0x30b5ffe9L,
+ 0xbdbdf21cL, 0xcabac28aL, 0x53b39330L, 0x24b4a3a6L, 0xbad03605L,
+ 0xcdd70693L, 0x54de5729L, 0x23d967bfL, 0xb3667a2eL, 0xc4614ab8L,
+ 0x5d681b02L, 0x2a6f2b94L, 0xb40bbe37L, 0xc30c8ea1L, 0x5a05df1bL,
+ 0x2d02ef8dL
+};
+
+ulg updcrc (s, n)
+ uch *s; /* pointer to bytes to pump through */
+ unsigned n; /* number of bytes in s[] */
+{
+ register ulg c; /* temporary variable */
+
+ static ulg crc = (ulg)0xffffffffL; /* shift register contents */
+
+ if (s == NULL)
+ {
+ c = 0xffffffffL;
+ }
+ else
+ {
+ c = crc;
+ if (n)
+ do
+ {
+ c = crc_32_tab[(c ^ (*s++)) & 0xff] ^ (c >> 8);
+ }
+ while (--n);
+ }
+ crc = c;
+ return c ^ 0xffffffffL; /* (instead of ~c for 64-bit machines) */
+};
+
+uint32_t updcrc_uint32 (s, n)
+ uch *s; /* pointer to bytes to pump through */
+ unsigned n; /* number of bytes in s[] */
+{
+ register uint32_t c; /* temporary variable */
+
+ static uint32_t crc = (uint32_t)0xffffffffL; /* shift register contents */
+
+ if (s == NULL)
+ {
+ c = 0xffffffffL;
+ }
+ else
+ {
+ c = crc;
+ if (n)
+ do
+ {
+ c = crc_32_tab[(c ^ (*s++)) & 0xff] ^ (c >> 8);
+ }
+ while (--n);
+ }
+ crc = c;
+ return c ^ 0xffffffffL; /* (instead of ~c for 64-bit machines) */
+}
+
+/* { dg-final { scan-assembler-times "crc32b" 2 } } */
+/* { dg-final { scan-tree-dump-times "Inserted crc32_builtin" 2 "forwprop1" } } */
diff --git a/gcc/tree-ssa-forwprop.cc b/gcc/tree-ssa-forwprop.cc
index 062f5667f14a65990329b826e3d4dfb3139337c3..d1deb56b5e76367e9bcd97368138c6cb4303fec8 100644
--- a/gcc/tree-ssa-forwprop.cc
+++ b/gcc/tree-ssa-forwprop.cc
@@ -52,6 +52,7 @@ along with GCC; see the file COPYING3. If not see
#include "cgraph.h"
#include "tree-ssa.h"
#include "gimple-range.h"
+#include "crc32-tables.h"
/* This pass propagates the RHS of assignment statements into use
sites of the LHS of the assignment. It's basically a specialized
@@ -2351,6 +2352,61 @@ optimize_count_trailing_zeroes (tree array_ref, tree x, tree mulc,
return false;
}
+/* crc32 optimization. */
+static bool
+simplify_crc32_table_index (gimple_stmt_iterator *gsi)
+{
+ gimple *stmt = gsi_stmt (*gsi);
+ tree rhs1 = gimple_assign_rhs1 (stmt);
+ crc32_builtin_params crc32params;
+
+ /* crc32type it's a type of polynomial for crc32. */
+ crc32params.type = match_crc32_table (rhs1);
+ if (crc32params.type >= CRC32UNDEFINED)
+ {
+ if (dump_file && (dump_flags & TDF_DETAILS))
+ fprintf (dump_file, "Can't recognize the type of crc32 table\n");
+ return false;
+ }
+
+ if (!detect_crc32_index (rhs1, &crc32params))
+ return false;
+
+ /* We have several cases here:
+ check_1. single crc32 in the loop
+ check_2. combination of crc32
+
+ Therefore if check_1 is missed we have to exec check_2 for more complex
+ case
+
+ crc32curr, crc32data are an input trees for futher builtin-call
+ crc32res is an output
+
+ if we detected complex crc32 we just modify the type of crc32 builtin and
+ select correct crc32res for injection. Example: crc32*w - 32 bits crc32
+ all other code cleaning would be a task for DCE-pass. */
+
+ /* Detect crc32 res. */
+ gimple * crc32res_stmt = lookup_crc32_res (stmt, &crc32params);
+ if (crc32res_stmt == NULL || crc32params.code == UNDEFINED_BUILTIN)
+ return false;
+
+ *gsi = gsi_for_stmt (crc32res_stmt);
+
+ /* Generate crc32_built_in call. */
+ gimple_seq seq;
+ seq = get_combined_crc32_seq (crc32params);
+
+ gsi_insert_seq_after (gsi, seq, GSI_SAME_STMT);
+ gsi_remove (gsi, true);
+ if (dump_file && (dump_flags & TDF_DETAILS))
+ fprintf (dump_file, "Inserted crc32_builtin! crc32code: %d\n",
+ crc32params.code);
+
+ return true;
+}
+/* end of crc32 optimization. */
+
/* Match.pd function to match the ctz expression. */
extern bool gimple_ctz_table_index (tree, tree *, tree (*)(tree));
@@ -3824,6 +3880,12 @@ pass_forwprop::execute (function *fun)
else if (code == CONSTRUCTOR
&& TREE_CODE (TREE_TYPE (rhs1)) == VECTOR_TYPE)
changed = simplify_vector_constructor (&gsi);
+ else if (code == ARRAY_REF
+ && INTEGRAL_TYPE_P (TREE_TYPE (rhs1))
+ && TARGET_CRC32
+ && targetm.get_crc32_builtin_code
+ && flag_crypto_accel_crc32)
+ changed = simplify_crc32_table_index (&gsi);
else if (code == ARRAY_REF)
changed = simplify_count_trailing_zeroes (&gsi);
break;