Commit 59896334 by Richard Biener Committed by Richard Biener

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
parent 4e7e89e8
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> 2016-09-27 Oleg Endo <olegendo@gcc.gnu.org>
PR target/51244 PR target/51244
......
2016-09-27 Richard Biener <rguenther@suse.de> 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 PR tree-optimization/77478
* gcc.dg/torture/pr77478.c: New testcase. * gcc.dg/torture/pr77478.c: New testcase.
......
// { 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();
}
...@@ -4431,26 +4431,34 @@ eliminate_dom_walker::before_dom_children (basic_block b) ...@@ -4431,26 +4431,34 @@ eliminate_dom_walker::before_dom_children (basic_block b)
&& !is_gimple_reg (gimple_assign_lhs (stmt)) && !is_gimple_reg (gimple_assign_lhs (stmt))
&& (TREE_CODE (gimple_assign_rhs1 (stmt)) == SSA_NAME && (TREE_CODE (gimple_assign_rhs1 (stmt)) == SSA_NAME
|| is_gimple_min_invariant (gimple_assign_rhs1 (stmt)))) || is_gimple_min_invariant (gimple_assign_rhs1 (stmt))))
{ {
tree val; tree val;
tree rhs = gimple_assign_rhs1 (stmt); tree rhs = gimple_assign_rhs1 (stmt);
val = vn_reference_lookup (gimple_assign_lhs (stmt), vn_reference_t vnresult;
gimple_vuse (stmt), VN_WALK, NULL, false); val = vn_reference_lookup (lhs, gimple_vuse (stmt), VN_WALKREWRITE,
if (TREE_CODE (rhs) == SSA_NAME) &vnresult, false);
rhs = VN_INFO (rhs)->valnum; if (TREE_CODE (rhs) == SSA_NAME)
if (val rhs = VN_INFO (rhs)->valnum;
&& operand_equal_p (val, rhs, 0)) if (val
{ && operand_equal_p (val, rhs, 0))
if (dump_file && (dump_flags & TDF_DETAILS)) {
{ /* We can only remove the later store if the former aliases
fprintf (dump_file, "Deleted redundant store "); at least all accesses the later one does. */
print_gimple_stmt (dump_file, stmt, 0, 0); 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. */ /* Queue stmt for removal. */
el_to_remove.safe_push (stmt); el_to_remove.safe_push (stmt);
continue; continue;
} }
}
} }
/* If this is a control statement value numbering left edges /* If this is a control statement value numbering left edges
......
...@@ -3599,13 +3599,21 @@ visit_reference_op_store (tree lhs, tree op, gimple *stmt) ...@@ -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 Otherwise, the vdefs for the store are used when inserting into
the table, since the store generates a new memory state. */ 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 (result)
{ {
if (TREE_CODE (result) == SSA_NAME) if (TREE_CODE (result) == SSA_NAME)
result = SSA_VAL (result); result = SSA_VAL (result);
resultsame = expressions_equal_p (result, op); 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) if ((!result || !resultsame)
......
Markdown is supported
0% or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment