Commit 87440c29 by Richard Biener Committed by Richard Biener

re PR tree-optimization/69776 (Wrong optimization with aliasing)

2016-02-16  Richard Biener  <rguenther@suse.de>

	PR tree-optimization/69776
	* tree-ssa-alias.c (indirect_ref_may_alias_decl_p): Get alias
	sets from caller.
	(indirect_refs_may_alias_p): Likewise.
	(refs_may_alias_p_1): Pass alias sets as from ao_ref.
	* tree-ssa-sccvn.c (vn_reference_lookup): Also adjust vr alias-set
	according to tbaa_p.
	* tree-ssa-dom.c (lookup_avail_expr): Add tbaa_p flag.
	(optimize_stmt): For redundant store discovery do not allow tbaa.

	* gcc.dg/torture/pr69776-2.c: New testcase.

From-SVN: r233453
parent 6d87c306
2016-02-16 Richard Biener <rguenther@suse.de>
PR tree-optimization/69776
* tree-ssa-alias.c (indirect_ref_may_alias_decl_p): Get alias
sets from caller.
(indirect_refs_may_alias_p): Likewise.
(refs_may_alias_p_1): Pass alias sets as from ao_ref.
* tree-ssa-sccvn.c (vn_reference_lookup): Also adjust vr alias-set
according to tbaa_p.
* tree-ssa-dom.c (lookup_avail_expr): Add tbaa_p flag.
(optimize_stmt): For redundant store discovery do not allow tbaa.
2016-02-16 Bernd Schmidt <bschmidt@redhat.com> 2016-02-16 Bernd Schmidt <bschmidt@redhat.com>
PR tree-optimization/69714 PR tree-optimization/69714
......
2016-02-16 Richard Biener <rguenther@suse.de>
PR tree-optimization/69776
* gcc.dg/torture/pr69776-2.c: New testcase.
2016-02-16 Bernd Schmidt <bschmidt@redhat.com> 2016-02-16 Bernd Schmidt <bschmidt@redhat.com>
PR tree-optimization/69714 PR tree-optimization/69714
......
/* { dg-do run } */
/* { dg-additional-options "-fstrict-aliasing" } */
extern void *malloc (__SIZE_TYPE__);
extern void abort (void);
__attribute__((noinline,noclone))
void f(int *qi, double *qd)
{
int i = *qi;
*qd = 0;
*qi = i;
}
int main()
{
int *p = malloc(sizeof(double));
*p = 1;
f(p, (double *)p);
if (*p != 1)
abort();
return 0;
}
...@@ -1067,12 +1067,8 @@ indirect_ref_may_alias_decl_p (tree ref1 ATTRIBUTE_UNUSED, tree base1, ...@@ -1067,12 +1067,8 @@ indirect_ref_may_alias_decl_p (tree ref1 ATTRIBUTE_UNUSED, tree base1,
ptrtype1 = TREE_TYPE (TREE_OPERAND (base1, 1)); ptrtype1 = TREE_TYPE (TREE_OPERAND (base1, 1));
/* If the alias set for a pointer access is zero all bets are off. */ /* If the alias set for a pointer access is zero all bets are off. */
if (base1_alias_set == -1)
base1_alias_set = get_deref_alias_set (ptrtype1);
if (base1_alias_set == 0) if (base1_alias_set == 0)
return true; return true;
if (base2_alias_set == -1)
base2_alias_set = get_alias_set (base2);
/* When we are trying to disambiguate an access with a pointer dereference /* When we are trying to disambiguate an access with a pointer dereference
as base versus one with a decl as base we can use both the size as base versus one with a decl as base we can use both the size
...@@ -1239,13 +1235,8 @@ indirect_refs_may_alias_p (tree ref1 ATTRIBUTE_UNUSED, tree base1, ...@@ -1239,13 +1235,8 @@ indirect_refs_may_alias_p (tree ref1 ATTRIBUTE_UNUSED, tree base1,
ptrtype2 = TREE_TYPE (TREE_OPERAND (base2, 1)); ptrtype2 = TREE_TYPE (TREE_OPERAND (base2, 1));
/* If the alias set for a pointer access is zero all bets are off. */ /* If the alias set for a pointer access is zero all bets are off. */
if (base1_alias_set == -1) if (base1_alias_set == 0
base1_alias_set = get_deref_alias_set (ptrtype1); || base2_alias_set == 0)
if (base1_alias_set == 0)
return true;
if (base2_alias_set == -1)
base2_alias_set = get_deref_alias_set (ptrtype2);
if (base2_alias_set == 0)
return true; return true;
/* If both references are through the same type, they do not alias /* If both references are through the same type, they do not alias
...@@ -1417,7 +1408,8 @@ refs_may_alias_p_1 (ao_ref *ref1, ao_ref *ref2, bool tbaa_p) ...@@ -1417,7 +1408,8 @@ refs_may_alias_p_1 (ao_ref *ref1, ao_ref *ref2, bool tbaa_p)
if (var1_p && ind2_p) if (var1_p && ind2_p)
return indirect_ref_may_alias_decl_p (ref2->ref, base2, return indirect_ref_may_alias_decl_p (ref2->ref, base2,
offset2, max_size2, offset2, max_size2,
ao_ref_alias_set (ref2), -1, ao_ref_alias_set (ref2),
ao_ref_base_alias_set (ref2),
ref1->ref, base1, ref1->ref, base1,
offset1, max_size1, offset1, max_size1,
ao_ref_alias_set (ref1), ao_ref_alias_set (ref1),
...@@ -1426,10 +1418,12 @@ refs_may_alias_p_1 (ao_ref *ref1, ao_ref *ref2, bool tbaa_p) ...@@ -1426,10 +1418,12 @@ refs_may_alias_p_1 (ao_ref *ref1, ao_ref *ref2, bool tbaa_p)
else if (ind1_p && ind2_p) else if (ind1_p && ind2_p)
return indirect_refs_may_alias_p (ref1->ref, base1, return indirect_refs_may_alias_p (ref1->ref, base1,
offset1, max_size1, offset1, max_size1,
ao_ref_alias_set (ref1), -1, ao_ref_alias_set (ref1),
ao_ref_base_alias_set (ref1),
ref2->ref, base2, ref2->ref, base2,
offset2, max_size2, offset2, max_size2,
ao_ref_alias_set (ref2), -1, ao_ref_alias_set (ref2),
ao_ref_base_alias_set (ref2),
tbaa_p); tbaa_p);
gcc_unreachable (); gcc_unreachable ();
......
...@@ -103,7 +103,8 @@ static struct opt_stats_d opt_stats; ...@@ -103,7 +103,8 @@ static struct opt_stats_d opt_stats;
static edge optimize_stmt (basic_block, gimple_stmt_iterator, static edge optimize_stmt (basic_block, gimple_stmt_iterator,
class const_and_copies *, class const_and_copies *,
class avail_exprs_stack *); class avail_exprs_stack *);
static tree lookup_avail_expr (gimple *, bool, class avail_exprs_stack *); static tree lookup_avail_expr (gimple *, bool, class avail_exprs_stack *,
bool = true);
static void record_cond (cond_equivalence *, class avail_exprs_stack *); static void record_cond (cond_equivalence *, class avail_exprs_stack *);
static void record_equality (tree, tree, class const_and_copies *); static void record_equality (tree, tree, class const_and_copies *);
static void record_equivalences_from_phis (basic_block); static void record_equivalences_from_phis (basic_block);
...@@ -1893,7 +1894,8 @@ optimize_stmt (basic_block bb, gimple_stmt_iterator si, ...@@ -1893,7 +1894,8 @@ optimize_stmt (basic_block bb, gimple_stmt_iterator si,
else else
new_stmt = gimple_build_assign (rhs, lhs); new_stmt = gimple_build_assign (rhs, lhs);
gimple_set_vuse (new_stmt, gimple_vuse (stmt)); gimple_set_vuse (new_stmt, gimple_vuse (stmt));
cached_lhs = lookup_avail_expr (new_stmt, false, avail_exprs_stack); cached_lhs = lookup_avail_expr (new_stmt, false, avail_exprs_stack,
false);
if (cached_lhs if (cached_lhs
&& rhs == cached_lhs) && rhs == cached_lhs)
{ {
...@@ -1997,7 +1999,7 @@ vuse_eq (ao_ref *, tree vuse1, unsigned int cnt, void *data) ...@@ -1997,7 +1999,7 @@ vuse_eq (ao_ref *, tree vuse1, unsigned int cnt, void *data)
static tree static tree
lookup_avail_expr (gimple *stmt, bool insert, lookup_avail_expr (gimple *stmt, bool insert,
class avail_exprs_stack *avail_exprs_stack) class avail_exprs_stack *avail_exprs_stack, bool tbaa_p)
{ {
expr_hash_elt **slot; expr_hash_elt **slot;
tree lhs; tree lhs;
...@@ -2054,7 +2056,8 @@ lookup_avail_expr (gimple *stmt, bool insert, ...@@ -2054,7 +2056,8 @@ lookup_avail_expr (gimple *stmt, bool insert,
if (!(vuse1 && vuse2 if (!(vuse1 && vuse2
&& gimple_assign_single_p (stmt) && gimple_assign_single_p (stmt)
&& TREE_CODE (gimple_assign_lhs (stmt)) == SSA_NAME && TREE_CODE (gimple_assign_lhs (stmt)) == SSA_NAME
&& (ao_ref_init (&ref, gimple_assign_rhs1 (stmt)), true) && (ao_ref_init (&ref, gimple_assign_rhs1 (stmt)),
ref.base_alias_set = ref.ref_alias_set = tbaa_p ? -1 : 0, true)
&& walk_non_aliased_vuses (&ref, vuse2, && walk_non_aliased_vuses (&ref, vuse2,
vuse_eq, NULL, NULL, vuse1) != NULL)) vuse_eq, NULL, NULL, vuse1) != NULL))
{ {
......
...@@ -2249,7 +2249,7 @@ vn_reference_lookup (tree op, tree vuse, vn_lookup_kind kind, ...@@ -2249,7 +2249,7 @@ vn_reference_lookup (tree op, tree vuse, vn_lookup_kind kind,
vr1.operands = operands vr1.operands = operands
= valueize_shared_reference_ops_from_ref (op, &valuezied_anything); = valueize_shared_reference_ops_from_ref (op, &valuezied_anything);
vr1.type = TREE_TYPE (op); vr1.type = TREE_TYPE (op);
vr1.set = get_alias_set (op); vr1.set = tbaa_p ? get_alias_set (op) : 0;
vr1.hashcode = vn_reference_compute_hash (&vr1); vr1.hashcode = vn_reference_compute_hash (&vr1);
if ((cst = fully_constant_vn_reference_p (&vr1))) if ((cst = fully_constant_vn_reference_p (&vr1)))
return cst; return cst;
......
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