gcc/gcc11-pr98282.patch

119 lines
2.9 KiB
Diff

2020-12-15 Jakub Jelinek <jakub@redhat.com>
PR tree-optimization/98282
* tree-ssa-pre.c (compute_avail): Don't try to adjust alias set
if different when ref1->opcode is not MEM_REF or TARGET_MEM_REF.
* g++.dg/opt/pr98282.C: New test.
--- gcc/tree-ssa-pre.c.jj 2020-11-30 10:48:31.000000000 +0100
+++ gcc/tree-ssa-pre.c 2020-12-15 10:51:51.061206572 +0100
@@ -4176,13 +4176,17 @@ compute_avail (void)
&& ref2->opcode != MEM_REF
&& ref2 != &operands[0])
--ref2;
- if ((ref1->opcode == TARGET_MEM_REF
- || ref1->opcode == MEM_REF)
- && (TYPE_ALIGN (ref1->type)
- > TYPE_ALIGN (ref2->type)))
- ref1->type
- = build_aligned_type (ref1->type,
- TYPE_ALIGN (ref2->type));
+ if (ref1->opcode == TARGET_MEM_REF
+ || ref1->opcode == MEM_REF)
+ {
+ if (TYPE_ALIGN (ref1->type)
+ > TYPE_ALIGN (ref2->type))
+ ref1->type
+ = build_aligned_type (ref1->type,
+ TYPE_ALIGN (ref2->type));
+ }
+ else
+ set = ref->set;
/* TBAA behavior is an obvious part so make sure
that the hashtable one covers this as well
by adjusting the ref alias set and its base. */
--- gcc/testsuite/g++.dg/opt/pr98282.C.jj 2020-12-15 12:26:25.868415230 +0100
+++ gcc/testsuite/g++.dg/opt/pr98282.C 2020-12-15 12:28:00.346353067 +0100
@@ -0,0 +1,80 @@
+// PR tree-optimization/98282
+// { dg-do compile { target c++11 } }
+// { dg-options "-O2" }
+
+template <typename> struct g;
+template <typename b> struct g<b &> { typedef b c; };
+template <typename b> typename g<b>::c &&d(b &&e) {
+ return static_cast<typename g<b>::c &&>(e);
+}
+void *operator new(__SIZE_TYPE__, void *f) { return f; }
+struct h;
+struct k {
+ using i = h *;
+};
+struct D {
+ k::i j;
+};
+struct p : D {
+ p(p &&) : D() {}
+};
+struct r {
+ using l = int;
+ r(r &&) : ad() {}
+ l *ad;
+};
+struct s {
+ static s m();
+};
+struct t {
+ template <typename ah> void operator=(ah);
+};
+struct I {
+ template <typename o> void q(o ai) {
+ *ai = aj();
+ s::m();
+ }
+ h aj();
+};
+template <typename...> class as;
+struct J {
+ int a;
+ char av;
+};
+template <typename...> struct aw : J {
+ void ax(...) {}
+};
+template <typename... ay, typename an, typename... n>
+struct aw<as<ay...>, an, n...> : aw<as<ay...>, n...> {
+ using az = as<ay...>;
+ using ba = aw<az, n...>;
+ char bb;
+ an &bc() { return *reinterpret_cast<an *>(this); }
+ void ax(az *bd) {
+ if (bb)
+ new (bd) an(d(bc()));
+ ba::ax(bd);
+ }
+};
+template <typename... n> struct as : aw<as<n...>, n...> {
+ as();
+ as(as &&be) { be.ax(this); }
+ void operator=(as be) { be.ax(this); }
+};
+struct h {
+ as<decltype(nullptr), r, p> bg;
+};
+using bh = t;
+struct u {
+ bh bj;
+};
+I bk();
+template <typename> void bl() {
+ h a;
+ bk().q(&a);
+}
+template <typename> void bn(int) {
+ u b;
+ b.bj = bl<int>;
+}
+void bp() { bn<int>(0); }