[PATCH] Fix PR78035

Richard Biener rguenther@suse.de
Mon Oct 31 12:46:00 GMT 2016


This is an updated patch for PR78035 which is about optimizing
address comparisons using points-to info vs. directly looking
at two addr-exprs.  I've given up trying to dissect a predicate
more useful than decl_binds_to_current_def_p from
symtab_node::equal_address_to and thus I'm going with the former.

Bootstrap & regtest pending on x86_64-unknown-linux-gnu.

Richard.

2016-10-31  Richard Biener  <rguenther@suse.de>

	PR tree-optimization/78035
	* gimple-pretty-print.c (pp_points_to_solution): Print
	vars_contains_interposable.
	* tree-ssa-alias.c: Include varasm.h.
	(ptrs_compare_unequal): Check vars_contains_interposable and
	decl_binds_to_current_def_p.
	(dump_points_to_solution): Dump vars_contains_interposable.
	* tree-ssa-alias.h (struct pt_solution): Add vars_contains_interposable
	flag.
	* tree-ssa-structalias.c: Include varasm.h.
	(set_uids_in_ptset): Record whether vars contains a
	not decl_binds_to_current_def_p variable in vars_contains_interposable.
	(ipa_escaped_pt): Update initializer.

	* gcc.target/i386/pr78035.c: New testcase.

Index: trunk/gcc/testsuite/gcc.target/i386/pr78035.c
===================================================================
--- trunk/gcc/testsuite/gcc.target/i386/pr78035.c	(revision 0)
+++ trunk/gcc/testsuite/gcc.target/i386/pr78035.c	(working copy)
@@ -0,0 +1,24 @@
+/* { dg-do compile } */
+/* { dg-options "-O2" } */
+
+extern int a;
+extern int b;
+extern int c;
+
+int foo(int choose_a)
+{
+  int *p;
+  if (choose_a)
+    p = &a;
+  else
+    p = &b;
+  return p != &c;
+}
+
+int bar ()
+{
+  return &a != &c;
+}
+
+/* We should not optimize away either comparison.  */
+/* { dg-final { scan-assembler-times "cmp" 2 } } */
diff --git a/gcc/gimple-pretty-print.c b/gcc/gimple-pretty-print.c
index 9d47f7f..8286326 100644
--- a/gcc/gimple-pretty-print.c
+++ b/gcc/gimple-pretty-print.c
@@ -728,6 +728,12 @@ pp_points_to_solution (pretty_printer *buffer, struct pt_solution *pt)
 	    {
 	      pp_string (buffer, comma);
 	      pp_string (buffer, "restrict");
+	      comma = ", ";
+	    }
+	  if (pt->vars_contains_interposable)
+	    {
+	      pp_string (buffer, comma);
+	      pp_string (buffer, "interposable");
 	    }
 	  pp_string (buffer, ")");
 	}
diff --git a/gcc/tree-ssa-alias.c b/gcc/tree-ssa-alias.c
index 26c9f9e..ebae6cf 100644
--- a/gcc/tree-ssa-alias.c
+++ b/gcc/tree-ssa-alias.c
@@ -32,12 +32,12 @@ along with GCC; see the file COPYING3.  If not see
 #include "tree-pretty-print.h"
 #include "alias.h"
 #include "fold-const.h"
-
 #include "langhooks.h"
 #include "dumpfile.h"
 #include "tree-eh.h"
 #include "tree-dfa.h"
 #include "ipa-reference.h"
+#include "varasm.h"
 
 /* Broad overview of how alias analysis on gimple works:
 
@@ -373,14 +373,18 @@ ptrs_compare_unequal (tree ptr1, tree ptr2)
       /* We may not use restrict to optimize pointer comparisons.
          See PR71062.  So we have to assume that restrict-pointed-to
 	 may be in fact obj1.  */
-      if (!pi || pi->pt.vars_contains_restrict)
+      if (!pi
+	  || pi->pt.vars_contains_restrict
+	  || pi->pt.vars_contains_interposable)
 	return false;
       if (VAR_P (obj1)
 	  && (TREE_STATIC (obj1) || DECL_EXTERNAL (obj1)))
 	{
 	  varpool_node *node = varpool_node::get (obj1);
 	  /* If obj1 may bind to NULL give up (see below).  */
-	  if (! node || ! node->nonzero_address ())
+	  if (! node
+	      || ! node->nonzero_address ()
+	      || ! decl_binds_to_current_def_p (obj1))
 	    return false;
 	}
       return !pt_solution_includes (&pi->pt, obj1);
@@ -553,7 +557,12 @@ dump_points_to_solution (FILE *file, struct pt_solution *pt)
 	      comma = ", ";
 	    }
 	  if (pt->vars_contains_restrict)
-	    fprintf (file, "%srestrict", comma);
+	    {
+	      fprintf (file, "%srestrict", comma);
+	      comma = ", ";
+	    }
+	  if (pt->vars_contains_interposable)
+	    fprintf (file, "%sinterposable", comma);
 	  fprintf (file, ")");
 	}
     }
diff --git a/gcc/tree-ssa-alias.h b/gcc/tree-ssa-alias.h
index 27a06fc..810d83c 100644
--- a/gcc/tree-ssa-alias.h
+++ b/gcc/tree-ssa-alias.h
@@ -57,6 +57,8 @@ struct GTY(()) pt_solution
   /* Nonzero if the vars bitmap includes a anonymous variable used to
      represent storage pointed to by a restrict qualified pointer.  */
   unsigned int vars_contains_restrict : 1;
+  /* Nonzero if the vars bitmap includes an interposable variable.  */
+  unsigned int vars_contains_interposable : 1;
 
   /* Set of variables that this pointer may point to.  */
   bitmap vars;
diff --git a/gcc/tree-ssa-structalias.c b/gcc/tree-ssa-structalias.c
index fb364f1..10434f6 100644
--- a/gcc/tree-ssa-structalias.c
+++ b/gcc/tree-ssa-structalias.c
@@ -39,6 +39,8 @@
 #include "tree-dfa.h"
 #include "params.h"
 #include "gimple-walk.h"
+#include "varasm.h"
+
 
 /* The idea behind this analyzer is to generate set constraints from the
    program, then solve the resulting constraints in order to generate the
@@ -6360,6 +6362,13 @@ set_uids_in_ptset (bitmap into, bitmap from, struct pt_solution *pt,
 		  && fndecl
 		  && ! auto_var_in_fn_p (vi->decl, fndecl)))
 	    pt->vars_contains_nonlocal = true;
+
+	  /* If we have a variable that is interposable record that fact
+	     for pointer comparison simplification.  */
+	  if (VAR_P (vi->decl)
+	      && (TREE_STATIC (vi->decl) || DECL_EXTERNAL (vi->decl))
+	      && ! decl_binds_to_current_def_p (vi->decl))
+	    pt->vars_contains_interposable = true;
 	}
 
       else if (TREE_CODE (vi->decl) == FUNCTION_DECL
@@ -7592,7 +7601,8 @@ make_pass_build_ealias (gcc::context *ctxt)
 
 /* IPA PTA solutions for ESCAPED.  */
 struct pt_solution ipa_escaped_pt
-  = { true, false, false, false, false, false, false, false, false, NULL };
+  = { true, false, false, false, false,
+      false, false, false, false, false, NULL };
 
 /* Associate node with varinfo DATA. Worker for
    cgraph_for_symbol_thunks_and_aliases.  */



More information about the Gcc-patches mailing list