tree-ssa-sccvn.c (visit_phi): Compare invariant addresses as base and offset.
authorRichard Biener <rguenther@suse.de>
Wed, 1 Aug 2018 12:03:29 +0000 (12:03 +0000)
committerRichard Biener <rguenth@gcc.gnu.org>
Wed, 1 Aug 2018 12:03:29 +0000 (12:03 +0000)
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.

From-SVN: r263206

gcc/ChangeLog
gcc/testsuite/ChangeLog
gcc/testsuite/gcc.dg/tree-ssa/ssa-fre-68.c [new file with mode: 0644]
gcc/tree-ssa-sccvn.c

index 477b245f146b918ed1baae432f9adcada0c657f4..0d10e950e230ce86c5ff135aa681eac2d33fa6b2 100644 (file)
@@ -1,3 +1,8 @@
+2018-08-01  Richard Biener  <rguenther@suse.de>
+
+       * tree-ssa-sccvn.c (visit_phi): Compare invariant addresses
+       as base and offset.
+
 2018-08-01  Martin Liska  <mliska@suse.cz>
 
        * value-prof.c (gimple_divmod_fixed_value_transform): Unify
index 0743b9593aa63d583f7201385e2bffcef627a778..7fcc05da6a9339be66a7b062de8afe5f5f20fa49 100644 (file)
@@ -1,3 +1,7 @@
+2018-08-01  Richard Biener  <rguenther@suse.de>
+
+       * gcc.dg/tree-ssa/ssa-fre-68.c: New testcase.
+
 2018-08-01  Uros Bizjak  <ubizjak@gmail.com>
 
        * gcc.dg/plugin/poly-int-07_plugin.c (dg-options): Use -O0.
diff --git a/gcc/testsuite/gcc.dg/tree-ssa/ssa-fre-68.c b/gcc/testsuite/gcc.dg/tree-ssa/ssa-fre-68.c
new file mode 100644 (file)
index 0000000..d9f07bd
--- /dev/null
@@ -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" } } */
index 833291a57a662730250b95d7e11384447380330c..43f3313911f8ba006eb65b34197ed0d57815f562 100644 (file)
@@ -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;
          }