aboutsummaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorJan Hubicka <jh@suse.cz>2020-02-21 15:36:00 +0100
committerJan Hubicka <jh@suse.cz>2020-02-21 15:36:00 +0100
commit91e50b2aa2dece9e22ae793d2a1a14b33bf3859d (patch)
treec07cc9a38c80730fe953d5b3c245db682ac00f8a
parentb5fb73b6bed11aaa87919c3885349e6f1ca0349f (diff)
downloadgcc-91e50b2aa2dece9e22ae793d2a1a14b33bf3859d.zip
gcc-91e50b2aa2dece9e22ae793d2a1a14b33bf3859d.tar.gz
gcc-91e50b2aa2dece9e22ae793d2a1a14b33bf3859d.tar.bz2
tree-optimization: fix access path oracle on mismatched array refs [PR93586]
nonoverlapping_array_refs_p is not supposed to give meaningful results when bases of ref1 and ref2 are not same or completely disjoint and here it is called on c[0][j_2][0] and c[0][1] so bases in sence of this functions are "c[0][j_2]" and "c[0]" which do partially overlap. nonoverlapping_array_refs however walks pair of array references and in this case it misses to note the fact that if it walked across first mismatched pair it is no longer safe to compare rest. The reason why it continues matching is because it hopes it will eventually get pair of COMPONENT_REFs from types of same size and use TBAA to conclude that their addresses must be either same or completely disjoint. This patch makes the loop to terminate early but popping all the remaining pairs so walking can continue. We could re-synchronize on arrays of same size with TBAA but this is bit fishy (because we try to support some sort of partial array overlaps) and hard to implement (because of zero sized arrays and VLAs) so I think it is not worth the effort. In addition I notied that the function is not !flag_strict_aliasing safe and added early exits on places we set seen_unmatched_ref_p since later we do not check that in: /* 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 && !operand_equal_p (TYPE_SIZE (type1), TYPE_SIZE (type2), 0)) { ++alias_stats .nonoverlapping_refs_since_match_p_may_alias; } 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. * gcc.dg/torture/pr93586.c: New testcase.
-rw-r--r--gcc/ChangeLog8
-rw-r--r--gcc/testsuite/ChangeLog6
-rw-r--r--gcc/testsuite/gcc.dg/torture/pr93586.c21
-rw-r--r--gcc/tree-ssa-alias.c42
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