diff mbox series

tree-optimization/13962 - handle ptr-ptr compares in ptrs_compare_unequal

Message ID 20240516120345.68F3B384AB65@sourceware.org
State New
Headers show
Series tree-optimization/13962 - handle ptr-ptr compares in ptrs_compare_unequal | expand

Commit Message

Richard Biener May 16, 2024, 12:03 p.m. UTC
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 mbox series

Patch

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