So there's the same issue left in DOM and an "optimization" in the alias machinery fails to honor the overridden alias-sets.
Bootstrapped and tested on x86_64-unknown-linux-gnu, applied. Richard. 2016-02-16 Richard Biener <rguent...@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. Index: gcc/tree-ssa-alias.c =================================================================== *** gcc/tree-ssa-alias.c (revision 233418) --- gcc/tree-ssa-alias.c (working copy) *************** indirect_ref_may_alias_decl_p (tree ref1 *** 1067,1078 **** ptrtype1 = TREE_TYPE (TREE_OPERAND (base1, 1)); /* 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) 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 as base versus one with a decl as base we can use both the size --- 1067,1074 ---- *************** indirect_refs_may_alias_p (tree ref1 ATT *** 1239,1251 **** ptrtype2 = TREE_TYPE (TREE_OPERAND (base2, 1)); /* 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) ! return true; ! if (base2_alias_set == -1) ! base2_alias_set = get_deref_alias_set (ptrtype2); ! if (base2_alias_set == 0) return true; /* If both references are through the same type, they do not alias --- 1235,1242 ---- ptrtype2 = TREE_TYPE (TREE_OPERAND (base2, 1)); /* If the alias set for a pointer access is zero all bets are off. */ ! if (base1_alias_set == 0 ! || base2_alias_set == 0) return true; /* If both references are through the same type, they do not alias *************** refs_may_alias_p_1 (ao_ref *ref1, ao_ref *** 1417,1423 **** if (var1_p && ind2_p) return indirect_ref_may_alias_decl_p (ref2->ref, base2, offset2, max_size2, ! ao_ref_alias_set (ref2), -1, ref1->ref, base1, offset1, max_size1, ao_ref_alias_set (ref1), --- 1408,1415 ---- if (var1_p && ind2_p) return indirect_ref_may_alias_decl_p (ref2->ref, base2, offset2, max_size2, ! ao_ref_alias_set (ref2), ! ao_ref_base_alias_set (ref2), ref1->ref, base1, offset1, max_size1, ao_ref_alias_set (ref1), *************** refs_may_alias_p_1 (ao_ref *ref1, ao_ref *** 1426,1435 **** else if (ind1_p && ind2_p) return indirect_refs_may_alias_p (ref1->ref, base1, offset1, max_size1, ! ao_ref_alias_set (ref1), -1, ref2->ref, base2, offset2, max_size2, ! ao_ref_alias_set (ref2), -1, tbaa_p); gcc_unreachable (); --- 1418,1429 ---- else if (ind1_p && ind2_p) return indirect_refs_may_alias_p (ref1->ref, base1, offset1, max_size1, ! ao_ref_alias_set (ref1), ! ao_ref_base_alias_set (ref1), ref2->ref, base2, offset2, max_size2, ! ao_ref_alias_set (ref2), ! ao_ref_base_alias_set (ref2), tbaa_p); gcc_unreachable (); Index: gcc/tree-ssa-sccvn.c =================================================================== *** gcc/tree-ssa-sccvn.c (revision 233418) --- gcc/tree-ssa-sccvn.c (working copy) *************** vn_reference_lookup (tree op, tree vuse, *** 2249,2255 **** vr1.operands = operands = valueize_shared_reference_ops_from_ref (op, &valuezied_anything); vr1.type = TREE_TYPE (op); ! vr1.set = get_alias_set (op); vr1.hashcode = vn_reference_compute_hash (&vr1); if ((cst = fully_constant_vn_reference_p (&vr1))) return cst; --- 2249,2255 ---- vr1.operands = operands = valueize_shared_reference_ops_from_ref (op, &valuezied_anything); vr1.type = TREE_TYPE (op); ! vr1.set = tbaa_p ? get_alias_set (op) : 0; vr1.hashcode = vn_reference_compute_hash (&vr1); if ((cst = fully_constant_vn_reference_p (&vr1))) return cst; Index: gcc/tree-ssa-dom.c =================================================================== *** gcc/tree-ssa-dom.c (revision 233418) --- gcc/tree-ssa-dom.c (working copy) *************** static struct opt_stats_d opt_stats; *** 103,109 **** static edge optimize_stmt (basic_block, gimple_stmt_iterator, class const_and_copies *, class avail_exprs_stack *); ! static tree lookup_avail_expr (gimple *, bool, 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_equivalences_from_phis (basic_block); --- 103,110 ---- static edge optimize_stmt (basic_block, gimple_stmt_iterator, class const_and_copies *, 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_equality (tree, tree, class const_and_copies *); static void record_equivalences_from_phis (basic_block); *************** optimize_stmt (basic_block bb, gimple_st *** 1893,1899 **** else new_stmt = gimple_build_assign (rhs, lhs); gimple_set_vuse (new_stmt, gimple_vuse (stmt)); ! cached_lhs = lookup_avail_expr (new_stmt, false, avail_exprs_stack); if (cached_lhs && rhs == cached_lhs) { --- 1894,1901 ---- else new_stmt = gimple_build_assign (rhs, lhs); gimple_set_vuse (new_stmt, gimple_vuse (stmt)); ! cached_lhs = lookup_avail_expr (new_stmt, false, avail_exprs_stack, ! false); if (cached_lhs && rhs == cached_lhs) { *************** vuse_eq (ao_ref *, tree vuse1, unsigned *** 1997,2003 **** static tree lookup_avail_expr (gimple *stmt, bool insert, ! class avail_exprs_stack *avail_exprs_stack) { expr_hash_elt **slot; tree lhs; --- 1999,2005 ---- static tree lookup_avail_expr (gimple *stmt, bool insert, ! class avail_exprs_stack *avail_exprs_stack, bool tbaa_p) { expr_hash_elt **slot; tree lhs; *************** lookup_avail_expr (gimple *stmt, bool in *** 2054,2060 **** if (!(vuse1 && vuse2 && gimple_assign_single_p (stmt) && TREE_CODE (gimple_assign_lhs (stmt)) == SSA_NAME ! && (ao_ref_init (&ref, gimple_assign_rhs1 (stmt)), true) && walk_non_aliased_vuses (&ref, vuse2, vuse_eq, NULL, NULL, vuse1) != NULL)) { --- 2056,2063 ---- if (!(vuse1 && vuse2 && gimple_assign_single_p (stmt) && TREE_CODE (gimple_assign_lhs (stmt)) == SSA_NAME ! && (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, vuse_eq, NULL, NULL, vuse1) != NULL)) { Index: gcc/testsuite/gcc.dg/torture/pr69776-2.c =================================================================== *** gcc/testsuite/gcc.dg/torture/pr69776-2.c (revision 0) --- gcc/testsuite/gcc.dg/torture/pr69776-2.c (working copy) *************** *** 0 **** --- 1,25 ---- + /* { 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; + } +