aboutsummaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorrguenth <rguenth@138bc75d-0d04-0410-961f-82ee72b054a4>2016-04-29 08:36:49 +0000
committerrguenth <rguenth@138bc75d-0d04-0410-961f-82ee72b054a4>2016-04-29 08:36:49 +0000
commit73447cc5d17178b0a756be48133e55fdc7574c13 (patch)
tree1858d6d18d0408f87683330cd1b7664179f40c81
parentfb13bff45b1ea57e8128d38fcd0ba37a30a17f26 (diff)
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. git-svn-id: svn+ssh://gcc.gnu.org/svn/gcc/trunk@235622 138bc75d-0d04-0410-961f-82ee72b054a4
-rw-r--r--gcc/ChangeLog10
-rw-r--r--gcc/match.pd8
-rw-r--r--gcc/testsuite/ChangeLog6
-rw-r--r--gcc/testsuite/gcc.dg/uninit-pr65686.c18
-rw-r--r--gcc/tree-ssa-alias.c60
-rw-r--r--gcc/tree-ssa-alias.h1
6 files changed, 103 insertions, 0 deletions
diff --git a/gcc/ChangeLog b/gcc/ChangeLog
index 268d4877988..0e7055614c6 100644
--- a/gcc/ChangeLog
+++ b/gcc/ChangeLog
@@ -1,5 +1,15 @@
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
type for arrays.
diff --git a/gcc/match.pd b/gcc/match.pd
index 0e63328c43c..608afa3e25e 100644
--- a/gcc/match.pd
+++ b/gcc/match.pd
@@ -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
diff --git a/gcc/testsuite/ChangeLog b/gcc/testsuite/ChangeLog
index d9e1e03760e..389c124627f 100644
--- a/gcc/testsuite/ChangeLog
+++ b/gcc/testsuite/ChangeLog
@@ -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
index 00000000000..1962ab76b93
--- /dev/null
+++ b/gcc/testsuite/gcc.dg/uninit-pr65686.c
@@ -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" } } */
diff --git a/gcc/tree-ssa-alias.c b/gcc/tree-ssa-alias.c
index 08f10e5248b..f801b013092 100644
--- a/gcc/tree-ssa-alias.c
+++ b/gcc/tree-ssa-alias.c
@@ -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
diff --git a/gcc/tree-ssa-alias.h b/gcc/tree-ssa-alias.h
index ccf23b4df30..0593b05a7bc 100644
--- a/gcc/tree-ssa-alias.h
+++ b/gcc/tree-ssa-alias.h
@@ -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);