This is the mail archive of the
gcc-patches@gcc.gnu.org
mailing list for the GCC project.
[PATCH] Improve address CSE
- From: Richard Biener <rguenther at suse dot de>
- To: gcc-patches at gcc dot gnu dot org
- Date: Wed, 1 Aug 2018 14:02:06 +0200 (CEST)
- Subject: [PATCH] Improve address CSE
This removes an odd CSE failure of invariant addresses vs. non-invariant
ones.
Bootstrapped and tested on x86_64-unknown-linux-gnu, applied to trunk.
Richard.
2018-08-01 Richard Biener <rguenther@suse.de>
* tree-ssa-sccvn.c (visit_phi): Compare invariant addresses
as base and offset.
* gcc.dg/tree-ssa/ssa-fre-68.c: New testcase.
Index: gcc/tree-ssa-sccvn.c
===================================================================
--- gcc/tree-ssa-sccvn.c (revision 263190)
+++ gcc/tree-ssa-sccvn.c (working copy)
@@ -3941,6 +3941,8 @@ static bool
visit_phi (gimple *phi)
{
tree result, sameval = VN_TOP, seen_undef = NULL_TREE;
+ tree sameval_base = NULL_TREE;
+ poly_int64 soff, doff;
unsigned n_executable = 0;
bool allsame = true;
edge_iterator ei;
@@ -3971,6 +3973,23 @@ visit_phi (gimple *phi)
sameval = def;
else if (!expressions_equal_p (def, sameval))
{
+ /* We know we're arriving only with invariant addresses here,
+ try harder comparing them. We can do some caching here
+ which we cannot do in expressions_equal_p. */
+ if (TREE_CODE (def) == ADDR_EXPR
+ && TREE_CODE (sameval) == ADDR_EXPR
+ && sameval_base != (void *)-1)
+ {
+ if (!sameval_base)
+ sameval_base = get_addr_base_and_unit_offset
+ (TREE_OPERAND (sameval, 0), &soff);
+ if (!sameval_base)
+ sameval_base = (tree)(void *)-1;
+ else if ((get_addr_base_and_unit_offset
+ (TREE_OPERAND (def, 0), &doff) == sameval_base)
+ && known_eq (soff, doff))
+ continue;
+ }
allsame = false;
break;
}
Index: gcc/testsuite/gcc.dg/tree-ssa/ssa-fre-68.c
===================================================================
--- gcc/testsuite/gcc.dg/tree-ssa/ssa-fre-68.c (nonexistent)
+++ gcc/testsuite/gcc.dg/tree-ssa/ssa-fre-68.c (working copy)
@@ -0,0 +1,28 @@
+/* { dg-do compile } */
+/* { dg-options "-O -fdump-tree-fre1" } */
+
+struct S { char a[3]; char b[5]; } s = { "abc", "defg" };
+
+__SIZE_TYPE__
+foo (struct S s, int a, int b)
+{
+ char *p = (char *) &s.a[0];
+ if (a)
+ p = (char *) &s.a;
+ else if (b)
+ p = (char *) &s;
+ return __builtin_strlen (p);
+}
+
+__SIZE_TYPE__
+bar (int a, int b)
+{
+ char *p = (char *) &s.a[0];
+ if (a)
+ p = (char *) &s.a;
+ else if (b)
+ p = (char *) &s;
+ return __builtin_strlen (p);
+}
+
+/* { dg-final { scan-tree-dump-times "strlen \\\(&s" 2 "fre1" } } */