aboutsummaryrefslogtreecommitdiff
path: root/gcc
diff options
context:
space:
mode:
authorJakub Jelinek <jakub@redhat.com>2024-10-22 20:21:56 +0200
committerJakub Jelinek <jakub@gcc.gnu.org>2024-10-22 20:21:56 +0200
commitf616bc412c820d1fe1211ab68873607d7bfe2709 (patch)
tree1a1a3d1edbaec88e5f0d350e56816f379aeceb85 /gcc
parent8f173da4520ddf64f3926580042f1103146bf0bd (diff)
downloadgcc-f616bc412c820d1fe1211ab68873607d7bfe2709.zip
gcc-f616bc412c820d1fe1211ab68873607d7bfe2709.tar.gz
gcc-f616bc412c820d1fe1211ab68873607d7bfe2709.tar.bz2
varasm: Handle RAW_DATA_CST in compare_constant [PR117199]
On the following testcase without LTO we unnecessarily don't merge two identical .LC* constants (constant hashing computes the same hash, but as compare_constant returned false for the RAW_DATA_CST in it, it never compares equal), and with LTO fails to link because LTO assumes such constants have to be merged and so doesn't emit the other constant. 2024-10-22 Jakub Jelinek <jakub@redhat.com> PR middle-end/117199 * varasm.cc (compare_constant): Handle RAW_DATA_CST. Formatting fix in the STRING_CST case. * gcc.dg/lto/pr117199_0.c: New test.
Diffstat (limited to 'gcc')
-rw-r--r--gcc/testsuite/gcc.dg/lto/pr117199_0.c45
-rw-r--r--gcc/varasm.cc7
2 files changed, 51 insertions, 1 deletions
diff --git a/gcc/testsuite/gcc.dg/lto/pr117199_0.c b/gcc/testsuite/gcc.dg/lto/pr117199_0.c
new file mode 100644
index 0000000..d47b491
--- /dev/null
+++ b/gcc/testsuite/gcc.dg/lto/pr117199_0.c
@@ -0,0 +1,45 @@
+/* PR middle-end/117199 */
+/* { dg-lto-do link } */
+/* { dg-lto-options { "-O2 -flto" } } */
+/* { dg-lto-options { "-O2 -flto -mtune=znver3" } { target i?86-*-* x86_64-*-* } } */
+
+__attribute__((used)) void
+foo (int *x, int y, int z)
+{
+ const unsigned char v[128] = {
+ 0, 64, 32, 96, 16, 80, 48, 112,
+ 8, 72, 40, 104, 24, 88, 56, 120,
+ 4, 68, 36, 100, 20, 84, 52, 116,
+ 12, 76, 44, 108, 28, 92, 60, 124,
+ 2, 66, 34, 98, 18, 82, 50, 114,
+ 10, 74, 42, 106, 26, 90, 58, 122,
+ 6, 70, 38, 102, 22, 86, 54, 118,
+ 14, 78, 46, 110, 30, 94, 62, 126,
+ 1, 65, 33, 97, 17, 81, 49, 113,
+ 9, 73, 41, 105, 25, 89, 57, 121
+ };
+ x[v[z]] = 1;
+}
+
+__attribute__((used)) void
+bar (int *x, int y, int z)
+{
+ const unsigned char v[128] = {
+ 0, 64, 32, 96, 16, 80, 48, 112,
+ 8, 72, 40, 104, 24, 88, 56, 120,
+ 4, 68, 36, 100, 20, 84, 52, 116,
+ 12, 76, 44, 108, 28, 92, 60, 124,
+ 2, 66, 34, 98, 18, 82, 50, 114,
+ 10, 74, 42, 106, 26, 90, 58, 122,
+ 6, 70, 38, 102, 22, 86, 54, 118,
+ 14, 78, 46, 110, 30, 94, 62, 126,
+ 1, 65, 33, 97, 17, 81, 49, 113,
+ 9, 73, 41, 105, 25, 89, 57, 121
+ };
+ x[v[z]] = 2;
+}
+
+int
+main ()
+{
+}
diff --git a/gcc/varasm.cc b/gcc/varasm.cc
index 0b3e800..8e492e3 100644
--- a/gcc/varasm.cc
+++ b/gcc/varasm.cc
@@ -3331,7 +3331,7 @@ compare_constant (const tree t1, const tree t2)
return (TREE_STRING_LENGTH (t1) == TREE_STRING_LENGTH (t2)
&& ! memcmp (TREE_STRING_POINTER (t1), TREE_STRING_POINTER (t2),
- TREE_STRING_LENGTH (t1)));
+ TREE_STRING_LENGTH (t1)));
case COMPLEX_CST:
return (compare_constant (TREE_REALPART (t1), TREE_REALPART (t2))
@@ -3356,6 +3356,11 @@ compare_constant (const tree t1, const tree t2)
return true;
}
+ case RAW_DATA_CST:
+ return (RAW_DATA_LENGTH (t1) == RAW_DATA_LENGTH (t2)
+ && ! memcmp (RAW_DATA_POINTER (t1), RAW_DATA_POINTER (t2),
+ RAW_DATA_LENGTH (t1)));
+
case CONSTRUCTOR:
{
vec<constructor_elt, va_gc> *v1, *v2;