From: Richard Biener Date: Fri, 29 Apr 2016 08:36:49 +0000 (+0000) Subject: re PR tree-optimization/13962 ([tree-ssa] make "fold" use alias information to optimi... X-Git-Tag: basepoints/gcc-8~7309 X-Git-Url: http://git.ipfire.org/?a=commitdiff_plain;h=98998245d99f06946b4d5ed6744c77c3760f1141;p=thirdparty%2Fgcc.git re PR tree-optimization/13962 ([tree-ssa] make "fold" use alias information to optimize pointer comparisons) 2016-04-29 Richard Biener 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 --- diff --git a/gcc/ChangeLog b/gcc/ChangeLog index 268d48779888..0e7055614c63 100644 --- a/gcc/ChangeLog +++ b/gcc/ChangeLog @@ -1,3 +1,13 @@ +2016-04-29 Richard Biener + + 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 * stor-layout.c (layout_type): Do not build a pointer-to-element diff --git a/gcc/match.pd b/gcc/match.pd index 0e63328c43c9..608afa3e25eb 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 d9e1e03760ee..389c124627f0 100644 --- a/gcc/testsuite/ChangeLog +++ b/gcc/testsuite/ChangeLog @@ -1,3 +1,9 @@ +2016-04-29 Richard Biener + + PR tree-optimization/13962 + PR tree-optimization/65686 + * gcc.dg/uninit-pr65686.c: New testcase. + 2016-04-29 Jakub Jelinek 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 000000000000..1962ab76b938 --- /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 08f10e5248b5..f801b013092c 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 ccf23b4df30e..0593b05a7bcf 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);