diff options
-rw-r--r-- | gcc/ChangeLog | 8 | ||||
-rw-r--r-- | gcc/testsuite/ChangeLog | 6 | ||||
-rw-r--r-- | gcc/testsuite/gcc.dg/torture/pr93586.c | 21 | ||||
-rw-r--r-- | gcc/tree-ssa-alias.c | 42 |
4 files changed, 73 insertions, 4 deletions
diff --git a/gcc/ChangeLog b/gcc/ChangeLog index b6e5253..85630f3 100644 --- a/gcc/ChangeLog +++ b/gcc/ChangeLog @@ -1,3 +1,11 @@ +2020-02-21 Jan Hubicka <hubicka@ucw.cz> + Richard Biener <rguenther@suse.de> + + PR tree-optimization/93586 + * tree-ssa-alias.c (nonoverlapping_array_refs_p): Finish array walk + after mismatched array refs; do not sure type size information to + recover from unmatched referneces with !flag_strict_aliasing_p. + 2020-02-21 Andrew Stubbs <ams@codesourcery.com> * config/gcn/gcn-valu.md (gather_load<mode>): Rename to ... diff --git a/gcc/testsuite/ChangeLog b/gcc/testsuite/ChangeLog index ad4f435..606d009 100644 --- a/gcc/testsuite/ChangeLog +++ b/gcc/testsuite/ChangeLog @@ -1,3 +1,9 @@ +2020-02-21 Jan Hubicka <hubicka@ucw.cz> + Richard Biener <rguenther@suse.de> + + PR tree-optimization/93586 + * gcc.dg/torture/pr93586.c: New testcase. + 2020-02-21 Martin Jambor <mjambor@suse.cz> PR tree-optimization/93845 diff --git a/gcc/testsuite/gcc.dg/torture/pr93586.c b/gcc/testsuite/gcc.dg/torture/pr93586.c new file mode 100644 index 0000000..e861bdc --- /dev/null +++ b/gcc/testsuite/gcc.dg/torture/pr93586.c @@ -0,0 +1,21 @@ +/* { dg-do run } */ +/* { dg-additional-options "-fgimple" } */ + +int __GIMPLE(ssa) foo(int j) +{ + int c[1][10][1]; + int _1; + +__BB(2): + c[0][1][0] = 1; + c[0][1] = _Literal (int[1]) {}; + _1 = c[0][j_2(D)][0]; + return _1; +} + +int main() +{ + if (foo (1) != 0) + __builtin_abort (); + return 0; +} diff --git a/gcc/tree-ssa-alias.c b/gcc/tree-ssa-alias.c index fd78105..7554e20 100644 --- a/gcc/tree-ssa-alias.c +++ b/gcc/tree-ssa-alias.c @@ -1486,9 +1486,27 @@ nonoverlapping_refs_since_match_p (tree match1, tree ref1, .nonoverlapping_refs_since_match_p_no_alias; return 1; } - partial_overlap = false; if (cmp == -1) - seen_unmatched_ref_p = true; + { + seen_unmatched_ref_p = true; + /* We can not maintain the invariant that bases are either + same or completely disjoint. However we can still recover + from type based alias analysis if we reach referneces to + same sizes. We do not attempt to match array sizes, so + just finish array walking and look for component refs. */ + if (!flag_strict_aliasing) + { + ++alias_stats.nonoverlapping_refs_since_match_p_may_alias; + return -1; + } + for (i++; i < narray_refs1; i++) + { + component_refs1.pop (); + component_refs2.pop (); + } + break; + } + partial_overlap = false; } } @@ -1503,7 +1521,14 @@ nonoverlapping_refs_since_match_p (tree match1, tree ref1, } ref1 = component_refs1.pop (); if (TREE_CODE (ref1) != COMPONENT_REF) - seen_unmatched_ref_p = true; + { + seen_unmatched_ref_p = true; + if (!flag_strict_aliasing) + { + ++alias_stats.nonoverlapping_refs_since_match_p_may_alias; + return -1; + } + } } while (!RECORD_OR_UNION_TYPE_P (TREE_TYPE (TREE_OPERAND (ref1, 0)))); @@ -1517,7 +1542,14 @@ nonoverlapping_refs_since_match_p (tree match1, tree ref1, } ref2 = component_refs2.pop (); if (TREE_CODE (ref2) != COMPONENT_REF) - seen_unmatched_ref_p = true; + { + if (!flag_strict_aliasing) + { + ++alias_stats.nonoverlapping_refs_since_match_p_may_alias; + return -1; + } + seen_unmatched_ref_p = true; + } } while (!RECORD_OR_UNION_TYPE_P (TREE_TYPE (TREE_OPERAND (ref2, 0)))); @@ -1537,6 +1569,8 @@ nonoverlapping_refs_since_match_p (tree match1, tree ref1, partial_overlap = false; + gcc_checking_assert (!seen_unmatched_ref_p || flag_strict_aliasing); + /* If we skipped array refs on type of different sizes, we can no longer be sure that there are not partial overlaps. */ if (seen_unmatched_ref_p |