re PR tree-optimization/13962 ([tree-ssa] make "fold" use alias information to optimi...
authorRichard Biener <rguenther@suse.de>
Fri, 29 Apr 2016 08:36:49 +0000 (08:36 +0000)
committerRichard Biener <rguenth@gcc.gnu.org>
Fri, 29 Apr 2016 08:36:49 +0000 (08:36 +0000)
2016-04-29  Richard Biener  <rguenther@suse.de>

PR tree-optimization/13962
PR tree-optimization/65686
* tree-ssa-alias.h (ptrs_compare_unequal): Declare.
* tree-ssa-alias.c (ptrs_compare_unequal): New function
using PTA to compare pointers.
* match.pd: Add pattern for pointer equality compare simplification
using ptrs_compare_unequal.

* gcc.dg/uninit-pr65686.c: New testcase.

From-SVN: r235622

gcc/ChangeLog
gcc/match.pd
gcc/testsuite/ChangeLog
gcc/testsuite/gcc.dg/uninit-pr65686.c [new file with mode: 0644]
gcc/tree-ssa-alias.c
gcc/tree-ssa-alias.h

index 268d4877988836a4a2f098e8f285df4752118235..0e7055614c6348d0b98a00bcce90804af39dbeb9 100644 (file)
@@ -1,3 +1,13 @@
+2016-04-29  Richard Biener  <rguenther@suse.de>
+
+       PR tree-optimization/13962
+       PR tree-optimization/65686
+       * tree-ssa-alias.h (ptrs_compare_unequal): Declare.
+       * tree-ssa-alias.c (ptrs_compare_unequal): New function
+       using PTA to compare pointers.
+       * match.pd: Add pattern for pointer equality compare simplification
+       using ptrs_compare_unequal.
+
 2016-04-29  Richard Biener  <rguenther@suse.de>
 
        * stor-layout.c (layout_type): Do not build a pointer-to-element
index 0e63328c43c911ff0e5de3c5f51729c9365d95ff..608afa3e25eb885efcd4af002727bf0e8cc8ecdb 100644 (file)
@@ -2400,6 +2400,14 @@ DEFINE_INT_AND_FLOAT_ROUND_FN (RINT)
        (if (cmp == NE_EXPR)
         { constant_boolean_node (true, type); })))))))))
 
+/* Simplify pointer equality compares using PTA.  */
+(for neeq (ne eq)
+ (simplify
+  (neeq @0 @1)
+  (if (POINTER_TYPE_P (TREE_TYPE (@0))
+       && ptrs_compare_unequal (@0, @1))
+   { neeq == EQ_EXPR ? boolean_false_node : boolean_true_node; })))
+
 /* Non-equality compare simplifications from fold_binary  */
 (for cmp (lt gt le ge)
  /* Comparisons with the highest or lowest possible integer of
index d9e1e03760eebae18a551d5f734bd6245044bee3..389c124627f0ae520be63f104c8061d1a885a43a 100644 (file)
@@ -1,3 +1,9 @@
+2016-04-29  Richard Biener  <rguenther@suse.de>
+
+       PR tree-optimization/13962
+       PR tree-optimization/65686
+       * gcc.dg/uninit-pr65686.c: New testcase.
+
 2016-04-29  Jakub Jelinek  <jakub@redhat.com>
 
        PR middle-end/70843
diff --git a/gcc/testsuite/gcc.dg/uninit-pr65686.c b/gcc/testsuite/gcc.dg/uninit-pr65686.c
new file mode 100644 (file)
index 0000000..1962ab7
--- /dev/null
@@ -0,0 +1,18 @@
+/* { dg-do compile } */
+/* { dg-options "-O2 -Wall -fdump-tree-optimized" } */
+
+typedef unsigned mytype;
+
+struct S {
+    mytype *pu;
+};
+
+mytype f(struct S *e)
+{
+  mytype x;  /* { dg-bogus { "uninitialized" } } */
+  if(&x != e->pu)
+    __builtin_memcpy(&x, e->pu, sizeof(unsigned));
+  return x;
+}
+
+/* { dg-final { scan-tree-dump-not "if" "optimized" } } */
index 08f10e5248b568f7252d4b54868bd22ab7767d12..f801b013092cdad13fb8f186f004e5c4d4759168 100644 (file)
@@ -321,6 +321,66 @@ ptr_deref_may_alias_ref_p_1 (tree ptr, ao_ref *ref)
   return true;
 }
 
+/* Returns true if PTR1 and PTR2 compare unequal because of points-to.  */
+
+bool
+ptrs_compare_unequal (tree ptr1, tree ptr2)
+{
+  /* First resolve the pointers down to a SSA name pointer base or
+     a VAR_DECL, PARM_DECL or RESULT_DECL.  This explicitely does
+     not yet try to handle LABEL_DECLs, FUNCTION_DECLs, CONST_DECLs
+     or STRING_CSTs which needs points-to adjustments to track them
+     in the points-to sets.  */
+  tree obj1 = NULL_TREE;
+  tree obj2 = NULL_TREE;
+  if (TREE_CODE (ptr1) == ADDR_EXPR)
+    {
+      tree tem = get_base_address (TREE_OPERAND (ptr1, 0));
+      if (! tem)
+       return false;
+      if (TREE_CODE (tem) == VAR_DECL
+         || TREE_CODE (tem) == PARM_DECL
+         || TREE_CODE (tem) == RESULT_DECL)
+       obj1 = tem;
+      else if (TREE_CODE (tem) == MEM_REF)
+       ptr1 = TREE_OPERAND (tem, 0);
+    }
+  if (TREE_CODE (ptr2) == ADDR_EXPR)
+    {
+      tree tem = get_base_address (TREE_OPERAND (ptr2, 0));
+      if (! tem)
+       return false;
+      if (TREE_CODE (tem) == VAR_DECL
+         || TREE_CODE (tem) == PARM_DECL
+         || TREE_CODE (tem) == RESULT_DECL)
+       obj2 = tem;
+      else if (TREE_CODE (tem) == MEM_REF)
+       ptr2 = TREE_OPERAND (tem, 0);
+    }
+
+  if (obj1 && obj2)
+    /* Other code handles this correctly, no need to duplicate it here.  */;
+  else if (obj1 && TREE_CODE (ptr2) == SSA_NAME)
+    {
+      struct ptr_info_def *pi = SSA_NAME_PTR_INFO (ptr2);
+      if (!pi)
+       return false;
+      return !pt_solution_includes (&pi->pt, obj1);
+    }
+  else if (TREE_CODE (ptr1) == SSA_NAME && obj2)
+    {
+      struct ptr_info_def *pi = SSA_NAME_PTR_INFO (ptr1);
+      if (!pi)
+       return false;
+      return !pt_solution_includes (&pi->pt, obj2);
+    }
+
+  /* ???  We'd like to handle ptr1 != NULL and ptr1 != ptr2
+     but those require pt.null to be conservatively correct.  */
+
+  return false;
+}
+
 /* Returns whether reference REF to BASE may refer to global memory.  */
 
 static bool
index ccf23b4df30e1d4c312fd98b050c8729295f1c9d..0593b05a7bcf321712d3b70b56b17f891d2a663b 100644 (file)
@@ -101,6 +101,7 @@ extern alias_set_type ao_ref_alias_set (ao_ref *);
 extern alias_set_type ao_ref_base_alias_set (ao_ref *);
 extern bool ptr_deref_may_alias_global_p (tree);
 extern bool ptr_derefs_may_alias_p (tree, tree);
+extern bool ptrs_compare_unequal (tree, tree);
 extern bool ref_may_alias_global_p (tree);
 extern bool ref_may_alias_global_p (ao_ref *);
 extern bool refs_may_alias_p (tree, tree);