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;