aboutsummaryrefslogtreecommitdiff
path: root/gcc/testsuite
diff options
context:
space:
mode:
authorJakub Jelinek <jakub@redhat.com>2020-01-10 22:18:22 +0100
committerJakub Jelinek <jakub@gcc.gnu.org>2020-01-10 22:18:22 +0100
commitea69031c5facc70e4a96df83cd58702900fd54b6 (patch)
tree879c6e151d192e9ac99c83999572027edc8d0517 /gcc/testsuite
parent974bb8a4dcbf51a153ab72da91a7256a296e7fa1 (diff)
downloadgcc-ea69031c5facc70e4a96df83cd58702900fd54b6.zip
gcc-ea69031c5facc70e4a96df83cd58702900fd54b6.tar.gz
gcc-ea69031c5facc70e4a96df83cd58702900fd54b6.tar.bz2
re PR tree-optimization/93210 (Sub-optimal code optimization on struct/combound constexpr (gcc vs. clang))
PR tree-optimization/93210 * fold-const.h (native_encode_initializer, can_native_interpret_type_p): Declare. * fold-const.c (native_encode_string): Fix up handling with off != -1, simplify. (native_encode_initializer): New function, moved from dwarf2out.c. Adjust to native_encode_expr compatible arguments, including dry-run and partial extraction modes. Don't handle STRING_CST. (can_native_interpret_type_p): No longer static. * gimple-fold.c (fold_ctor_reference): For native_encode_expr, verify offset / BITS_PER_UNIT fits into int and don't call it if can_native_interpret_type_p fails. If suboff is NULL and for CONSTRUCTOR fold_{,non}array_ctor_reference returns NULL, retry with native_encode_initializer. (fold_const_aggregate_ref_1): Formatting fix. * dwarf2out.c (native_encode_initializer): Moved to fold-const.c. (tree_add_const_value_attribute): Adjust caller. * gcc.dg/pr93210.c: New test. * g++.dg/opt/pr93210.C: New test. From-SVN: r280141
Diffstat (limited to 'gcc/testsuite')
-rw-r--r--gcc/testsuite/ChangeLog6
-rw-r--r--gcc/testsuite/g++.dg/opt/pr93210.C37
-rw-r--r--gcc/testsuite/gcc.dg/pr93210.c66
3 files changed, 109 insertions, 0 deletions
diff --git a/gcc/testsuite/ChangeLog b/gcc/testsuite/ChangeLog
index 26c4f6c..527d53b 100644
--- a/gcc/testsuite/ChangeLog
+++ b/gcc/testsuite/ChangeLog
@@ -1,3 +1,9 @@
+2020-01-10 Jakub Jelinek <jakub@redhat.com>
+
+ PR tree-optimization/93210
+ * gcc.dg/pr93210.c: New test.
+ * g++.dg/opt/pr93210.C: New test.
+
2020-01-10 Vladimir Makarov <vmakarov@redhat.com>
PR inline-asm/93027
diff --git a/gcc/testsuite/g++.dg/opt/pr93210.C b/gcc/testsuite/g++.dg/opt/pr93210.C
new file mode 100644
index 0000000..11ade7b
--- /dev/null
+++ b/gcc/testsuite/g++.dg/opt/pr93210.C
@@ -0,0 +1,37 @@
+// PR tree-optimization/93210
+// { dg-do compile { target c++11 } }
+// { dg-options "-O2 -fdump-tree-optimized" }
+// { dg-final { scan-tree-dump-not "static_member\.d" "optimized" } }
+
+union U { struct { unsigned int a, b; } c; unsigned long long d; };
+
+inline
+bool operator == (U const &x, U const &y) noexcept
+{
+ return x.d == y.d;
+};
+
+struct S
+{
+ static constexpr U static_member = { { 13, 42 } };
+ bool foo (U const &y) const noexcept;
+ bool bar (U const &y) const noexcept;
+};
+
+#if __cpp_inline_variables < 201606L
+constexpr U S::static_member;
+#endif
+
+#if __SIZEOF_INT__ * 2 == __SIZEOF_LONG_LONG__
+bool
+S::foo (U const &y) const noexcept
+{
+ return static_member == y;
+}
+
+bool
+S::bar (U const &y) const noexcept
+{
+ return U (static_member) == y;
+}
+#endif
diff --git a/gcc/testsuite/gcc.dg/pr93210.c b/gcc/testsuite/gcc.dg/pr93210.c
new file mode 100644
index 0000000..ec4194b
--- /dev/null
+++ b/gcc/testsuite/gcc.dg/pr93210.c
@@ -0,0 +1,66 @@
+/* PR tree-optimization/93210 */
+/* { dg-do run } */
+/* { dg-options "-O2 -fdump-tree-optimized" } */
+/* { dg-final { scan-tree-dump-times "return \[0-9]\[0-9a-fA-FxX]*;" 31 "optimized" } } */
+
+#ifdef __SIZEOF_INT128__
+typedef unsigned __int128 L;
+#else
+typedef unsigned long long L;
+#endif
+struct S { signed char a, b; unsigned char c; };
+struct T { signed char d; struct S e[25]; signed char f; };
+union U { struct T g; L h[10]; };
+const union U u = { { 1, { { 2, 3, 4 }, { 5, 6, 7 }, { 8, 9, 10 },
+ { 12, 13, 14 }, { 15, 16, 17 }, { 18, 19, 20 },
+ { 22, 23, 24 }, { 25, 26, 27 }, { 28, 29, 30 },
+ { 32, 33, 34 }, { 35, 36, 37 }, { 38, 39, 40 },
+ { 42, 43, 44 }, { 45, 46, 47 }, { 48, 49, 50 },
+ { 52, 53, 54 }, { 55, 56, 57 }, { 58, 59, 60 },
+ { 62, 63, 64 }, { 65, 66, 67 }, { 68, 69, 70 },
+ { 72, 73, 74 }, { 75, 76, 77 }, { 78, 79, 80 },
+ { 82, 83, 84 } }, 85 } };
+const union U v = { { 1, { { 2, 3, 4 }, [1 ... 23] = { 5, 6, 7 },
+ { 8, 9, 10 } }, 86 } };
+struct A { char a[5]; char b[16]; char c[7]; };
+union V { struct A d; unsigned int e[10]; };
+const union V w = { { "abcde", "ijkl", "mnopqr" } };
+#define N(n) __attribute__((noipa)) L foo##n (void) { return u.h[n]; }
+#define M N(0) N(1) N(2) N(3) N(4) N(5) N(6) N(7) N(8) N(9)
+M
+#undef N
+#define N(n) __attribute__((noipa)) L bar##n (void) { return v.h[n]; }
+M
+#undef N
+#define N(n) __attribute__((noipa)) L baz##n (void) { return w.e[n]; }
+M
+
+typedef L (*F) (void);
+F arr[30] = {
+#undef N
+#define N(n) foo##n,
+M
+#undef N
+#define N(n) bar##n,
+M
+#undef N
+#define N(n) baz##n,
+M
+};
+
+int
+main ()
+{
+ const union U *p = &u;
+ const union U *q = &v;
+ const union V *r = &w;
+ __asm ("" : "+g" (p));
+ __asm ("" : "+g" (q));
+ __asm ("" : "+g" (r));
+ for (int i = 0; i < 10; i++)
+ if (arr[i] () != p->h[i]
+ || arr[i + 10] () != q->h[i]
+ || arr[i + 20] () != r->e[i])
+ __builtin_abort ();
+ return 0;
+}