tree-optimization/98282 - classify V_C_E<constant> as nary
authorRichard Biener <rguenther@suse.de>
Mon, 4 Jan 2021 10:40:40 +0000 (11:40 +0100)
committerRichard Biener <rguenther@suse.de>
Mon, 4 Jan 2021 11:59:44 +0000 (12:59 +0100)
This avoids running into memory reference code in compute_avail by
properly classifying unfolded reference trees on constants.

2021-01-04  Richard Biener  <rguenther@suse.de>

PR tree-optimization/98282
* tree-ssa-sccvn.c (vn_get_stmt_kind): Classify tcc_reference on
invariants as VN_NARY.

* g++.dg/opt/pr98282.C: New testcase.

gcc/testsuite/g++.dg/opt/pr98282.C [new file with mode: 0644]
gcc/tree-ssa-sccvn.c

diff --git a/gcc/testsuite/g++.dg/opt/pr98282.C b/gcc/testsuite/g++.dg/opt/pr98282.C
new file mode 100644 (file)
index 0000000..5450841
--- /dev/null
@@ -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); }
index d944b9565ace7722af7351d8769bc9793918e560..19defc0cccc35eaf9b6e0a0a0fc75739a529accc 100644 (file)
@@ -543,7 +543,8 @@ vn_get_stmt_kind (gimple *stmt)
                     || code == IMAGPART_EXPR
                     || code == VIEW_CONVERT_EXPR
                     || code == BIT_FIELD_REF)
-                   && TREE_CODE (TREE_OPERAND (rhs1, 0)) == SSA_NAME)
+                   && (TREE_CODE (TREE_OPERAND (rhs1, 0)) == SSA_NAME
+                       || is_gimple_min_invariant (TREE_OPERAND (rhs1, 0))))
                  return VN_NARY;
 
                /* Fallthrough.  */