diff options
author | Jan Hubicka <hubicka@ucw.cz> | 2019-10-20 20:53:37 +0200 |
---|---|---|
committer | Jan Hubicka <hubicka@gcc.gnu.org> | 2019-10-20 18:53:37 +0000 |
commit | f373041ce59c7a1d13b733a167339815717e19f5 (patch) | |
tree | d3a20e37543b746b78ce38a8cb0aa0d976a698d9 /gcc/tree-ssa-alias.c | |
parent | 1d778697b37aec23db5b6003dfe08d2d78bd9424 (diff) | |
download | gcc-f373041ce59c7a1d13b733a167339815717e19f5.zip gcc-f373041ce59c7a1d13b733a167339815717e19f5.tar.gz gcc-f373041ce59c7a1d13b733a167339815717e19f5.tar.bz2 |
tree-ssa-alias.c (nonoverlapping_refs_since_match_p): Do not skip non-zero array accesses.
* tree-ssa-alias.c (nonoverlapping_refs_since_match_p): Do not
skip non-zero array accesses.
* gcc.c-torture/execute/alias-access-path-2.c: New testcase.
* gcc.dg/tree-ssa/alias-access-path-11.c: xfail.
From-SVN: r277214
Diffstat (limited to 'gcc/tree-ssa-alias.c')
-rw-r--r-- | gcc/tree-ssa-alias.c | 28 |
1 files changed, 22 insertions, 6 deletions
diff --git a/gcc/tree-ssa-alias.c b/gcc/tree-ssa-alias.c index d6c4438..4cfe3e2 100644 --- a/gcc/tree-ssa-alias.c +++ b/gcc/tree-ssa-alias.c @@ -1444,20 +1444,36 @@ nonoverlapping_refs_since_match_p (tree match1, tree ref1, for (; narray_refs1 > narray_refs2; narray_refs1--) { ref1 = component_refs1.pop (); - /* Track whether we possibly introduced partial overlap assuming - that innermost type sizes does not match. This only can - happen if the offset introduced by the ARRAY_REF - is non-zero. */ + + /* If index is non-zero we need to check whether the reference + does not break the main invariant that bases are either + disjoint or equal. Consider the example: + + unsigned char out[][1]; + out[1]="a"; + out[i][0]; + + Here bases out and out are same, but after removing the + [i] index, this invariant no longer holds, because + out[i] points to the middle of array out. + + TODO: If size of type of the skipped reference is an integer + multiply of the size of type of the other reference this + invariant can be verified, but even then it is not completely + safe with !flag_strict_aliasing if the other reference contains + unbounded array accesses. + See */ + if (!operand_equal_p (TREE_OPERAND (ref1, 1), cheap_array_ref_low_bound (ref1), 0)) - seen_unmatched_ref_p = true; + return 0; } for (; narray_refs2 > narray_refs1; narray_refs2--) { ref2 = component_refs2.pop (); if (!operand_equal_p (TREE_OPERAND (ref2, 1), cheap_array_ref_low_bound (ref2), 0)) - seen_unmatched_ref_p = true; + return 0; } /* Try to disambiguate matched arrays. */ for (unsigned int i = 0; i < narray_refs1; i++) |