aboutsummaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorRichard Biener <rguenther@suse.de>2021-04-13 10:12:03 +0200
committerRichard Biener <rguenther@suse.de>2021-04-27 11:06:33 +0200
commitd1d01a66012a93cc8cb7dafbe1b5ec453ec96b59 (patch)
tree4439a797fdaa7981d36b092f7383c582267d4b90
parentdfdc02bf29670c1c7f5f2820b6db11c66c258716 (diff)
downloadgcc-d1d01a66012a93cc8cb7dafbe1b5ec453ec96b59.zip
gcc-d1d01a66012a93cc8cb7dafbe1b5ec453ec96b59.tar.gz
gcc-d1d01a66012a93cc8cb7dafbe1b5ec453ec96b59.tar.bz2
tree-optimization/100051 - disambiguate access size vs decl
This adds disambiguation of the access size vs. the decl size in the pointer based vs. decl based disambiguator. We have a TBAA based check like this already but that's fend off when seeing alias-sets of zero or when -fno-strict-aliasing is in effect. Also the perceived dynamic type could be smaller than the actual access. 2021-04-13 Richard Biener <rguenther@suse.de> PR tree-optimization/100051 * tree-ssa-alias.c (indirect_ref_may_alias_decl_p): Add disambiguator based on access size vs. decl size. * gcc.dg/tree-ssa/ssa-fre-92.c: New testcase.
-rw-r--r--gcc/testsuite/gcc.dg/tree-ssa/ssa-fre-92.c21
-rw-r--r--gcc/tree-ssa-alias.c11
2 files changed, 32 insertions, 0 deletions
diff --git a/gcc/testsuite/gcc.dg/tree-ssa/ssa-fre-92.c b/gcc/testsuite/gcc.dg/tree-ssa/ssa-fre-92.c
new file mode 100644
index 0000000..c67fcea
--- /dev/null
+++ b/gcc/testsuite/gcc.dg/tree-ssa/ssa-fre-92.c
@@ -0,0 +1,21 @@
+/* { dg-do compile } */
+/* { dg-options "-O2 -fdump-tree-fre1" } */
+
+extern void foo(void);
+int a, c, *f, **d = &f;
+char b;
+int main()
+{
+ if (a) {
+ b = 0;
+ int *g = &c;
+ *g = 0;
+ f = *d;
+ *d = f;
+ if ((2 ^ b) == 0)
+ foo();
+ }
+ return 0;
+}
+
+/* { dg-final { scan-tree-dump-not "foo" "fre1" } } */
diff --git a/gcc/tree-ssa-alias.c b/gcc/tree-ssa-alias.c
index ebb3f49..6c7d2f1b 100644
--- a/gcc/tree-ssa-alias.c
+++ b/gcc/tree-ssa-alias.c
@@ -2034,6 +2034,17 @@ indirect_ref_may_alias_decl_p (tree ref1 ATTRIBUTE_UNUSED, tree base1,
if (TREE_CODE (base1) != TARGET_MEM_REF
&& !ranges_maybe_overlap_p (offset1 + moff, -1, offset2, max_size2))
return false;
+
+ /* If the pointer based access is bigger than the variable they cannot
+ alias. This is similar to the check below where we use TBAA to
+ increase the size of the pointer based access based on the dynamic
+ type of a containing object we can infer from it. */
+ poly_int64 dsize2;
+ if (known_size_p (size1)
+ && poly_int_tree_p (DECL_SIZE (base2), &dsize2)
+ && known_lt (dsize2, size1))
+ return false;
+
/* They also cannot alias if the pointer may not point to the decl. */
if (!ptr_deref_may_alias_decl_p (ptr1, base2))
return false;