Now that we handle pt.null conservatively we can implement the missing
tracking of constant pool entries (aka STRING_CST) and handle
ptr-ptr compares using points-to info in ptrs_compare_unequal.

Bootstrapped on x86_64-unknown-linux-gnu, (re-)testing in progress.

Richard.

        PR tree-optimization/13962
        PR tree-optimization/96564
        * tree-ssa-alias.h (pt_solution::const_pool): New flag.
        * tree-ssa-alias.cc (ptrs_compare_unequal): Handle pointer-pointer
        compares.
        (dump_points_to_solution): Dump the const_pool flag, fix guard
        of flag dumping.
        * gimple-pretty-print.cc (pp_points_to_solution): Likewise.
        * tree-ssa-structalias.cc (find_what_var_points_to): Set
        the const_pool flag for STRING.
        (pt_solution_ior_into): Handle the const_pool flag.
        (ipa_escaped_pt): Initialize it.

        * gcc.dg/tree-ssa/alias-39.c: New testcase.
        * g++.dg/vect/pr68145.cc: Use -fno-tree-pta to avoid UB
        to manifest in transforms no longer vectorizing this testcase
        for an ICE.
---
 gcc/gimple-pretty-print.cc               |  5 +++-
 gcc/testsuite/gcc.dg/tree-ssa/alias-39.c | 12 ++++++++++
 gcc/tree-ssa-alias.cc                    | 30 ++++++++++++++++++++----
 gcc/tree-ssa-alias.h                     |  5 ++++
 gcc/tree-ssa-structalias.cc              |  6 ++---
 5 files changed, 50 insertions(+), 8 deletions(-)
 create mode 100644 gcc/testsuite/gcc.dg/tree-ssa/alias-39.c

diff --git a/gcc/gimple-pretty-print.cc b/gcc/gimple-pretty-print.cc
index abda8871f97..a71e1e0efc7 100644
--- a/gcc/gimple-pretty-print.cc
+++ b/gcc/gimple-pretty-print.cc
@@ -822,6 +822,8 @@ pp_points_to_solution (pretty_printer *buffer, const 
pt_solution *pt)
     pp_string (buffer, "unit-escaped ");
   if (pt->null)
     pp_string (buffer, "null ");
+  if (pt->const_pool)
+    pp_string (buffer, "const-pool ");
   if (pt->vars
       && !bitmap_empty_p (pt->vars))
     {
@@ -838,7 +840,8 @@ pp_points_to_solution (pretty_printer *buffer, const 
pt_solution *pt)
       if (pt->vars_contains_nonlocal
          || pt->vars_contains_escaped
          || pt->vars_contains_escaped_heap
-         || pt->vars_contains_restrict)
+         || pt->vars_contains_restrict
+         || pt->vars_contains_interposable)
        {
          const char *comma = "";
          pp_string (buffer, " (");
diff --git a/gcc/testsuite/gcc.dg/tree-ssa/alias-39.c 
b/gcc/testsuite/gcc.dg/tree-ssa/alias-39.c
new file mode 100644
index 00000000000..3b452893f6b
--- /dev/null
+++ b/gcc/testsuite/gcc.dg/tree-ssa/alias-39.c
@@ -0,0 +1,12 @@
+/* { dg-do compile } */
+/* { dg-options "-O -fdump-tree-forwprop3" } */
+
+static int a, b;
+int foo (int n, int which)
+{
+  void *p = __builtin_malloc (n);
+  void *q = which ? &a : &b;
+  return p == q;
+}
+
+/* { dg-final { scan-tree-dump "return 0;" "forwprop3" } } */
diff --git a/gcc/tree-ssa-alias.cc b/gcc/tree-ssa-alias.cc
index 96301bbde7f..6d31fc83691 100644
--- a/gcc/tree-ssa-alias.cc
+++ b/gcc/tree-ssa-alias.cc
@@ -484,9 +484,27 @@ ptrs_compare_unequal (tree ptr1, tree ptr2)
        }
       return !pt_solution_includes (&pi->pt, obj1);
     }
-
-  /* ???  We'd like to handle ptr1 != NULL and ptr1 != ptr2
-     but those require pt.null to be conservatively correct.  */
+  else if (TREE_CODE (ptr1) == SSA_NAME)
+    {
+      struct ptr_info_def *pi1 = SSA_NAME_PTR_INFO (ptr1);
+      if (!pi1
+         || pi1->pt.vars_contains_restrict
+         || pi1->pt.vars_contains_interposable)
+       return false;
+      if (integer_zerop (ptr2) && !pi1->pt.null)
+       return true;
+      if (TREE_CODE (ptr2) == SSA_NAME)
+       {
+         struct ptr_info_def *pi2 = SSA_NAME_PTR_INFO (ptr2);
+         if (!pi2
+             || pi2->pt.vars_contains_restrict
+             || pi2->pt.vars_contains_interposable)
+           return false;
+         if ((!pi1->pt.null || !pi2->pt.null)
+             && (!pi1->pt.const_pool || !pi2->pt.const_pool))
+           return !pt_solutions_intersect (&pi1->pt, &pi2->pt);
+       }
+    }
 
   return false;
 }
@@ -636,6 +654,9 @@ dump_points_to_solution (FILE *file, struct pt_solution *pt)
   if (pt->null)
     fprintf (file, ", points-to NULL");
 
+  if (pt->const_pool)
+    fprintf (file, ", points-to const-pool");
+
   if (pt->vars)
     {
       fprintf (file, ", points-to vars: ");
@@ -643,7 +664,8 @@ dump_points_to_solution (FILE *file, struct pt_solution *pt)
       if (pt->vars_contains_nonlocal
          || pt->vars_contains_escaped
          || pt->vars_contains_escaped_heap
-         || pt->vars_contains_restrict)
+         || pt->vars_contains_restrict
+         || pt->vars_contains_interposable)
        {
          const char *comma = "";
          fprintf (file, " (");
diff --git a/gcc/tree-ssa-alias.h b/gcc/tree-ssa-alias.h
index b26fffeeb2d..e29dff58375 100644
--- a/gcc/tree-ssa-alias.h
+++ b/gcc/tree-ssa-alias.h
@@ -47,6 +47,11 @@ struct GTY(()) pt_solution
      includes memory at address NULL.  */
   unsigned int null : 1;
 
+  /* Nonzero if the points-to set includes a readonly object like a
+     STRING_CST that does not have an underlying declaration but will
+     end up in the constant pool.  */
+  unsigned int const_pool : 1;
+
   /* Nonzero if the vars bitmap includes a variable included in 'nonlocal'.  */
   unsigned int vars_contains_nonlocal : 1;
   /* Nonzero if the vars bitmap includes a variable included in 'escaped'.  */
diff --git a/gcc/tree-ssa-structalias.cc b/gcc/tree-ssa-structalias.cc
index f0454bea2ea..12424bbdfad 100644
--- a/gcc/tree-ssa-structalias.cc
+++ b/gcc/tree-ssa-structalias.cc
@@ -6799,8 +6799,7 @@ find_what_var_points_to (tree fndecl, varinfo_t orig_vi)
          else if (vi->id == nonlocal_id)
            pt->nonlocal = 1;
          else if (vi->id == string_id)
-           /* Nobody cares - STRING_CSTs are read-only entities.  */
-           ;
+           pt->const_pool = 1;
          else if (vi->id == anything_id
                   || vi->id == integer_id)
            pt->anything = 1;
@@ -6956,6 +6955,7 @@ pt_solution_ior_into (struct pt_solution *dest, struct 
pt_solution *src)
   dest->escaped |= src->escaped;
   dest->ipa_escaped |= src->ipa_escaped;
   dest->null |= src->null;
+  dest->const_pool |= src->const_pool ;
   dest->vars_contains_nonlocal |= src->vars_contains_nonlocal;
   dest->vars_contains_escaped |= src->vars_contains_escaped;
   dest->vars_contains_escaped_heap |= src->vars_contains_escaped_heap;
@@ -8128,7 +8128,7 @@ make_pass_build_ealias (gcc::context *ctxt)
 
 /* IPA PTA solutions for ESCAPED.  */
 struct pt_solution ipa_escaped_pt
-  = { true, false, false, false, false,
+  = { true, false, false, false, false, false,
       false, false, false, false, false, NULL };
 
 /* Associate node with varinfo DATA. Worker for
-- 
2.35.3

Reply via email to