aboutsummaryrefslogtreecommitdiff
path: root/gcc
diff options
context:
space:
mode:
authorRichard Biener <rguenther@suse.de>2023-10-09 13:05:10 +0200
committerRichard Biener <rguenther@suse.de>2023-10-09 15:17:11 +0200
commit11b8cf1685bb40af5b86653e492e350983025957 (patch)
treee36f31f6385cf45d32d0ec74a519dedc357c70b0 /gcc
parent841668aa02a05deca06e68a5931408d970f5c8b2 (diff)
downloadgcc-11b8cf1685bb40af5b86653e492e350983025957.zip
gcc-11b8cf1685bb40af5b86653e492e350983025957.tar.gz
gcc-11b8cf1685bb40af5b86653e492e350983025957.tar.bz2
tree-optimization/111715 - improve TBAA for access paths with pun
The following improves basic TBAA for access paths formed by C++ abstraction where we are able to combine a path from an address-taking operation with a path based on that access using a pun to avoid memory access semantics on the address-taking part. The trick is to identify the point the semantic memory access path starts which allows us to use the alias set of the outermost access instead of only that of the base of this path. PR tree-optimization/111715 * alias.cc (reference_alias_ptr_type_1): When we have a type-punning ref at the base search for the access path part that's still semantically valid. * gcc.dg/tree-ssa/ssa-fre-102.c: New testcase.
Diffstat (limited to 'gcc')
-rw-r--r--gcc/alias.cc17
-rw-r--r--gcc/testsuite/gcc.dg/tree-ssa/ssa-fre-102.c32
2 files changed, 48 insertions, 1 deletions
diff --git a/gcc/alias.cc b/gcc/alias.cc
index 7c1af1f..86d8f71 100644
--- a/gcc/alias.cc
+++ b/gcc/alias.cc
@@ -774,7 +774,22 @@ reference_alias_ptr_type_1 (tree *t)
&& (TYPE_MAIN_VARIANT (TREE_TYPE (inner))
!= TYPE_MAIN_VARIANT
(TREE_TYPE (TREE_TYPE (TREE_OPERAND (inner, 1))))))
- return TREE_TYPE (TREE_OPERAND (inner, 1));
+ {
+ tree alias_ptrtype = TREE_TYPE (TREE_OPERAND (inner, 1));
+ /* Unless we have the (aggregate) effective type of the access
+ somewhere on the access path. If we have for example
+ (&a->elts[i])->l.len exposed by abstraction we'd see
+ MEM <A> [(B *)a].elts[i].l.len and we can use the alias set
+ of 'len' when typeof (MEM <A> [(B *)a].elts[i]) == B for
+ example. See PR111715. */
+ tree inner = *t;
+ while (handled_component_p (inner)
+ && (TYPE_MAIN_VARIANT (TREE_TYPE (inner))
+ != TYPE_MAIN_VARIANT (TREE_TYPE (alias_ptrtype))))
+ inner = TREE_OPERAND (inner, 0);
+ if (TREE_CODE (inner) == MEM_REF)
+ return alias_ptrtype;
+ }
/* Otherwise, pick up the outermost object that we could have
a pointer to. */
diff --git a/gcc/testsuite/gcc.dg/tree-ssa/ssa-fre-102.c b/gcc/testsuite/gcc.dg/tree-ssa/ssa-fre-102.c
new file mode 100644
index 0000000..afd4805
--- /dev/null
+++ b/gcc/testsuite/gcc.dg/tree-ssa/ssa-fre-102.c
@@ -0,0 +1,32 @@
+/* PR/111715 */
+/* { dg-do compile } */
+/* { dg-options "-O2 -fdump-tree-fre1" } */
+
+struct B {
+ struct { int len; } l;
+ long n;
+};
+struct A {
+ struct B elts[8];
+};
+
+static void
+set_len (struct B *b, int len)
+{
+ b->l.len = len;
+}
+
+static int
+get_len (struct B *b)
+{
+ return b->l.len;
+}
+
+int foo (struct A *a, int i, long *q)
+{
+ set_len (&a->elts[i], 1);
+ *q = 2;
+ return get_len (&a->elts[i]);
+}
+
+/* { dg-final { scan-tree-dump "return 1;" "fre1" } } */