aboutsummaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorRichard Biener <rguenther@suse.de>2016-09-27 12:56:38 +0000
committerRichard Biener <rguenth@gcc.gnu.org>2016-09-27 12:56:38 +0000
commit59896334f97c1d58c221d2975e33abccd0d331d5 (patch)
tree98081d1a890b16cf38fe47a5ae0e7aa4b27bb30d
parent4e7e89e8c9acdbffa6546d5e6056c7b81238c88f (diff)
downloadgcc-59896334f97c1d58c221d2975e33abccd0d331d5.zip
gcc-59896334f97c1d58c221d2975e33abccd0d331d5.tar.gz
gcc-59896334f97c1d58c221d2975e33abccd0d331d5.tar.bz2
re PR tree-optimization/77745 (Inconsistent application of aliasing rules)
2016-09-27 Richard Biener <rguenther@suse.de> PR tree-optimization/77745 * tree-ssa-pre.c (eliminate_dom_walker::before_dom_children): When removing redundant stores make sure to check compatibility of the TBAA state for downstream accesses. * tree-ssa-sccvn.c (visit_reference_op_store): Likewise for when value-numbering virtual operands for store matches. * g++.dg/torture/pr77745.C: New testcase. From-SVN: r240534
-rw-r--r--gcc/ChangeLog9
-rw-r--r--gcc/testsuite/ChangeLog5
-rw-r--r--gcc/testsuite/g++.dg/torture/pr77745.C24
-rw-r--r--gcc/tree-ssa-pre.c44
-rw-r--r--gcc/tree-ssa-sccvn.c12
5 files changed, 74 insertions, 20 deletions
diff --git a/gcc/ChangeLog b/gcc/ChangeLog
index 0255b93..15346af 100644
--- a/gcc/ChangeLog
+++ b/gcc/ChangeLog
@@ -1,3 +1,12 @@
+2016-09-27 Richard Biener <rguenther@suse.de>
+
+ PR tree-optimization/77745
+ * tree-ssa-pre.c (eliminate_dom_walker::before_dom_children):
+ When removing redundant stores make sure to check compatibility
+ of the TBAA state for downstream accesses.
+ * tree-ssa-sccvn.c (visit_reference_op_store): Likewise for when
+ value-numbering virtual operands for store matches.
+
2016-09-27 Oleg Endo <olegendo@gcc.gnu.org>
PR target/51244
diff --git a/gcc/testsuite/ChangeLog b/gcc/testsuite/ChangeLog
index 20680cb..8b6c7d6 100644
--- a/gcc/testsuite/ChangeLog
+++ b/gcc/testsuite/ChangeLog
@@ -1,5 +1,10 @@
2016-09-27 Richard Biener <rguenther@suse.de>
+ PR tree-optimization/77745
+ * g++.dg/torture/pr77745.C: New testcase.
+
+2016-09-27 Richard Biener <rguenther@suse.de>
+
PR tree-optimization/77478
* gcc.dg/torture/pr77478.c: New testcase.
diff --git a/gcc/testsuite/g++.dg/torture/pr77745.C b/gcc/testsuite/g++.dg/torture/pr77745.C
new file mode 100644
index 0000000..59d86b5
--- /dev/null
+++ b/gcc/testsuite/g++.dg/torture/pr77745.C
@@ -0,0 +1,24 @@
+// { dg-do run }
+
+inline void* operator new(__SIZE_TYPE__, void* __p) noexcept { return __p; }
+
+long foo(char *c1, char *c2)
+{
+ long *p1 = new (c1) long;
+ *p1 = 100;
+ long long *p2 = new (c2) long long;
+ *p2 = 200;
+ long *p3 = new (c2) long;
+ *p3 = 200;
+ return *p1;
+}
+int main()
+{
+ union {
+ char c;
+ long l;
+ long long ll;
+ } c;
+ if (foo(&c.c, &c.c) != 200)
+ __builtin_abort();
+}
diff --git a/gcc/tree-ssa-pre.c b/gcc/tree-ssa-pre.c
index 0c6f820..3675fb9 100644
--- a/gcc/tree-ssa-pre.c
+++ b/gcc/tree-ssa-pre.c
@@ -4431,26 +4431,34 @@ eliminate_dom_walker::before_dom_children (basic_block b)
&& !is_gimple_reg (gimple_assign_lhs (stmt))
&& (TREE_CODE (gimple_assign_rhs1 (stmt)) == SSA_NAME
|| is_gimple_min_invariant (gimple_assign_rhs1 (stmt))))
- {
- tree val;
+ {
+ tree val;
tree rhs = gimple_assign_rhs1 (stmt);
- val = vn_reference_lookup (gimple_assign_lhs (stmt),
- gimple_vuse (stmt), VN_WALK, NULL, false);
- if (TREE_CODE (rhs) == SSA_NAME)
- rhs = VN_INFO (rhs)->valnum;
- if (val
- && operand_equal_p (val, rhs, 0))
- {
- if (dump_file && (dump_flags & TDF_DETAILS))
- {
- fprintf (dump_file, "Deleted redundant store ");
- print_gimple_stmt (dump_file, stmt, 0, 0);
- }
+ vn_reference_t vnresult;
+ val = vn_reference_lookup (lhs, gimple_vuse (stmt), VN_WALKREWRITE,
+ &vnresult, false);
+ if (TREE_CODE (rhs) == SSA_NAME)
+ rhs = VN_INFO (rhs)->valnum;
+ if (val
+ && operand_equal_p (val, rhs, 0))
+ {
+ /* We can only remove the later store if the former aliases
+ at least all accesses the later one does. */
+ alias_set_type set = get_alias_set (lhs);
+ if (vnresult->set == set
+ || alias_set_subset_of (set, vnresult->set))
+ {
+ if (dump_file && (dump_flags & TDF_DETAILS))
+ {
+ fprintf (dump_file, "Deleted redundant store ");
+ print_gimple_stmt (dump_file, stmt, 0, 0);
+ }
- /* Queue stmt for removal. */
- el_to_remove.safe_push (stmt);
- continue;
- }
+ /* Queue stmt for removal. */
+ el_to_remove.safe_push (stmt);
+ continue;
+ }
+ }
}
/* If this is a control statement value numbering left edges
diff --git a/gcc/tree-ssa-sccvn.c b/gcc/tree-ssa-sccvn.c
index 7f44ec8..94fd66a 100644
--- a/gcc/tree-ssa-sccvn.c
+++ b/gcc/tree-ssa-sccvn.c
@@ -3599,13 +3599,21 @@ visit_reference_op_store (tree lhs, tree op, gimple *stmt)
Otherwise, the vdefs for the store are used when inserting into
the table, since the store generates a new memory state. */
- result = vn_reference_lookup (lhs, vuse, VN_NOWALK, NULL, false);
-
+ result = vn_reference_lookup (lhs, vuse, VN_NOWALK, &vnresult, false);
if (result)
{
if (TREE_CODE (result) == SSA_NAME)
result = SSA_VAL (result);
resultsame = expressions_equal_p (result, op);
+ if (resultsame)
+ {
+ /* If the TBAA state isn't compatible for downstream reads
+ we cannot value-number the VDEFs the same. */
+ alias_set_type set = get_alias_set (lhs);
+ if (vnresult->set != set
+ && ! alias_set_subset_of (set, vnresult->set))
+ resultsame = false;
+ }
}
if ((!result || !resultsame)