aboutsummaryrefslogtreecommitdiff
path: root/gcc/expr.cc
diff options
context:
space:
mode:
authorJakub Jelinek <jakub@redhat.com>2025-01-12 17:24:53 -0700
committerJeff Law <jlaw@ventanamicro.com>2025-01-12 17:54:37 -0700
commit9c387a99a911724546abe99ecd39bfc968ed6333 (patch)
tree2a850af881af259b73f7a7e1052e2244d4db1ca9 /gcc/expr.cc
parent422c58844ef0d788f45214a69cab97ee0b6414a9 (diff)
downloadgcc-9c387a99a911724546abe99ecd39bfc968ed6333.zip
gcc-9c387a99a911724546abe99ecd39bfc968ed6333.tar.gz
gcc-9c387a99a911724546abe99ecd39bfc968ed6333.tar.bz2
[PATCH] crc: Fix up some crc related wrong code issues [PR117997, PR118415]
Hi! As mentioned in the second PR, using table names like crc_table_for_crc_8_polynomial_0x12 in the user namespace is wrong, user could have defined such variables in their code and as can be seen on the last testcase, then it just misbehaves. At minimum such names should start with 2 underscores, moving it into implementation namespace, and if possible have some dot or dollar in the name if target supports it. I think assemble_crc_table right now always emits tables a local variables, I really don't see what would be setting TREE_PUBLIC flag on IDENTIFIER_NODEs. It might be nice to share the tables between TUs in the same binary or shared library, but it in that case should have hidden visibility if possible, so that it isn't exported from the libraries or binaries, we don't want the optimization to affect set of exported symbols from libraries. And, as can be seen in the first PR, building gen_rtx_SYMBOL_REF by hand is certainly unexpected on some targets, e.g. those which use -fsection-anchors, so we should instead use DECL_RTL of the VAR_DECL. For that we'd need to look it up if we haven't emitted it already, while IDENTIFIER_NODEs can be looked up easily, I guess for the VAR_DECLs we'd need custom hash table. Now, all of the above (except sharing between multiple TUs) is already implemented in output_constant_def, so I think it is much better to just use that function. And, if we want to share it between multiple TUs, we could extend the SHF_MERGE usage in gcc, currently we only use it for constant pool entries with same size as alignment, from 1 to 32 bytes, using .rodata.cstN sections. We could just use say .rodata.cstM.N sections where M would be alignment and N would be the entity size. We could use that for all constant pool entries say up to 2048 bytes. Though, as the current code doesn't share between multiple TUs, I think it can be done incrementally (either still for GCC 15, or GCC 16+). Bootstrapped/regtested on {x86_64,i686,aarch64,powerpc64le,s390x}-linux, on aarch64 it also fixes -FAIL: crypto/rsa -FAIL: hash ok for trunk? gcc/ PR tree-optimization/117997 PR middle-end/118415 * expr.cc (assemble_crc_table): Make static, remove id argument, use output_constant_def. Emit note if -fdump-rtl-expand-details about which table has been emitted. (generate_crc_table): Make static, adjust assemble_crc_table caller, call it always. (calculate_table_based_CRC): Make static. * internal-fn.cc (expand_crc_optab_fn): Emit note if -fdump-rtl-expand-details about using optab for crc. Formatting fix. gcc/testsuite/ * gcc.dg/crc-builtin-target32.c: Add -fdump-rtl-expand-details as dg-additional-options. Scan expand dump rather than assembly, adjust the regexps. * gcc.dg/crc-builtin-target64.c: Likewise. * gcc.dg/crc-builtin-rev-target32.c: Likewise. * gcc.dg/crc-builtin-rev-target64.c: Likewise. * gcc.dg/pr117997.c: New test. * gcc.dg/pr118415.c: New test.
Diffstat (limited to 'gcc/expr.cc')
-rw-r--r--gcc/expr.cc56
1 files changed, 17 insertions, 39 deletions
diff --git a/gcc/expr.cc b/gcc/expr.cc
index 235e795..07fc857 100644
--- a/gcc/expr.cc
+++ b/gcc/expr.cc
@@ -14247,25 +14247,16 @@ calculate_crc (unsigned HOST_WIDE_INT crc,
return crc;
}
-/* Assemble CRC table with 256 elements for the given POLYNOM and CRC_BITS with
- given ID.
- ID is the identifier of the table, the name of the table is unique,
- contains CRC size and the polynomial.
+/* Assemble CRC table with 256 elements for the given POLYNOM and CRC_BITS.
POLYNOM is the polynomial used to calculate the CRC table's elements.
CRC_BITS is the size of CRC, may be 8, 16, ... . */
-rtx
-assemble_crc_table (tree id, unsigned HOST_WIDE_INT polynom,
- unsigned short crc_bits)
+static rtx
+assemble_crc_table (unsigned HOST_WIDE_INT polynom, unsigned short crc_bits)
{
unsigned table_el_n = 0x100;
tree ar = build_array_type (make_unsigned_type (crc_bits),
build_index_type (size_int (table_el_n - 1)));
- tree decl = build_decl (UNKNOWN_LOCATION, VAR_DECL, id, ar);
- SET_DECL_ASSEMBLER_NAME (decl, id);
- DECL_ARTIFICIAL (decl) = 1;
- rtx tab = gen_rtx_SYMBOL_REF (Pmode, IDENTIFIER_POINTER (id));
- TREE_ASM_WRITTEN (decl) = 0;
/* Initialize the table. */
vec<tree, va_gc> *initial_values;
@@ -14276,21 +14267,20 @@ assemble_crc_table (tree id, unsigned HOST_WIDE_INT polynom,
tree element = build_int_cstu (make_unsigned_type (crc_bits), crc);
vec_safe_push (initial_values, element);
}
- DECL_INITIAL (decl) = build_constructor_from_vec (ar, initial_values);
-
- TREE_READONLY (decl) = 1;
- TREE_STATIC (decl) = 1;
-
- if (TREE_PUBLIC (id))
+ tree ctor = build_constructor_from_vec (ar, initial_values);
+ rtx mem = output_constant_def (ctor, 1);
+ gcc_assert (MEM_P (mem));
+ if (dump_file && (dump_flags & TDF_DETAILS))
{
- TREE_PUBLIC (decl) = 1;
- make_decl_one_only (decl, DECL_ASSEMBLER_NAME (decl));
+ fprintf (dump_file,
+ ";; emitting crc table crc_%u_polynomial_"
+ HOST_WIDE_INT_PRINT_HEX " ",
+ crc_bits, polynom);
+ print_rtl_single (dump_file, XEXP (mem, 0));
+ fprintf (dump_file, "\n");
}
- mark_decl_referenced (decl);
- varpool_node::finalize_decl (decl);
-
- return tab;
+ return XEXP (mem, 0);
}
/* Generate CRC lookup table by calculating CRC for all possible
@@ -14299,24 +14289,12 @@ assemble_crc_table (tree id, unsigned HOST_WIDE_INT polynom,
POLYNOM is the polynomial used to calculate the CRC table's elements.
CRC_BITS is the size of CRC, may be 8, 16, ... . */
-rtx
+static rtx
generate_crc_table (unsigned HOST_WIDE_INT polynom, unsigned short crc_bits)
{
gcc_assert (crc_bits <= 64);
- /* Buf size - 24 letters + 6 '_'
- + 20 numbers (2 for crc bit size + 2 for 0x + 16 for 64-bit polynomial)
- + 1 for \0. */
- char buf[51];
- sprintf (buf, "crc_table_for_crc_%u_polynomial_" HOST_WIDE_INT_PRINT_HEX,
- crc_bits, polynom);
-
- tree id = maybe_get_identifier (buf);
- if (id)
- return gen_rtx_SYMBOL_REF (Pmode, IDENTIFIER_POINTER (id));
-
- id = get_identifier (buf);
- return assemble_crc_table (id, polynom, crc_bits);
+ return assemble_crc_table (polynom, crc_bits);
}
/* Generate table-based CRC code for the given CRC, INPUT_DATA and the
@@ -14335,7 +14313,7 @@ generate_crc_table (unsigned HOST_WIDE_INT polynom, unsigned short crc_bits)
If input data size is not 8, then first we extract upper 8 bits,
then the other 8 bits, and so on. */
-void
+static void
calculate_table_based_CRC (rtx *crc, const rtx &input_data,
const rtx &polynomial,
machine_mode data_mode)