aboutsummaryrefslogtreecommitdiff
path: root/gcc
diff options
context:
space:
mode:
authorRichard Biener <rguenther@suse.de>2021-01-04 11:40:40 +0100
committerRichard Biener <rguenther@suse.de>2021-01-04 12:59:44 +0100
commit13b80a7d1b9b712651f5ece589634a6e57c26362 (patch)
tree0067893ed4d2a3e27465eabdb9ac70055c8aebff /gcc
parentb41e6dd50f329b0291457e939d4c0dacd81c82c1 (diff)
downloadgcc-13b80a7d1b9b712651f5ece589634a6e57c26362.zip
gcc-13b80a7d1b9b712651f5ece589634a6e57c26362.tar.gz
gcc-13b80a7d1b9b712651f5ece589634a6e57c26362.tar.bz2
tree-optimization/98282 - classify V_C_E<constant> as nary
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.
Diffstat (limited to 'gcc')
-rw-r--r--gcc/testsuite/g++.dg/opt/pr98282.C80
-rw-r--r--gcc/tree-ssa-sccvn.c3
2 files changed, 82 insertions, 1 deletions
diff --git a/gcc/testsuite/g++.dg/opt/pr98282.C b/gcc/testsuite/g++.dg/opt/pr98282.C
new file mode 100644
index 0000000..5450841
--- /dev/null
+++ b/gcc/testsuite/g++.dg/opt/pr98282.C
@@ -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); }
diff --git a/gcc/tree-ssa-sccvn.c b/gcc/tree-ssa-sccvn.c
index d944b95..19defc0 100644
--- a/gcc/tree-ssa-sccvn.c
+++ b/gcc/tree-ssa-sccvn.c
@@ -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. */