diff options
author | Richard Sandiford <richard.sandiford@arm.com> | 2015-10-08 16:49:24 +0000 |
---|---|---|
committer | Richard Sandiford <rsandifo@gcc.gnu.org> | 2015-10-08 16:49:24 +0000 |
commit | 68e57f040c6330eb853551622d458a67d6f9e572 (patch) | |
tree | 61678cfe315bf4f20ccae0603f837d13eeab72a5 /gcc/tree-vrp.c | |
parent | 170f473b525d0af69dc4577186762a3519b952a4 (diff) | |
download | gcc-68e57f040c6330eb853551622d458a67d6f9e572.zip gcc-68e57f040c6330eb853551622d458a67d6f9e572.tar.gz gcc-68e57f040c6330eb853551622d458a67d6f9e572.tar.bz2 |
Make tree_expr_nonnegative_warnv_p recurse into SSA names
The upcoming patch to move sqrt and cbrt simplifications to match.pd
caused a regression because the (abs @0)->@0 simplification didn't
trigger for:
(abs (convert (abs X)))
The simplification is based on tree_expr_nonnegative_p, which at
the moment just gives up if it sees an SSA_NAME.
This patch makes tree_expr_nonnegative_p recurse into SSA name
definitions, but limits the depth of recursion to a small number
for the reason mentioned in the comment (adapted from an existing
comment in gimple_val_nonnegative_real_p). The patch reuses code
in tree-vrp.c, moving it to gimple-fold.c. It also replaces calls
to gimple_val_nonnegative_real_p with calls to tree_expr_nonnegative_p.
A knock-on effect is that we can now prove _i_589 < 0 is false in
sequences like:
i_1917 = ASSERT_EXPR <i_1075, i_1075 == 0>;
_i_589 = (const int) i_1917;
_i_1507 = ASSERT_EXPR <_i_589, _i_589 < 0>;
This defeats an assert in tree-vrp.c that ASSERT_EXPR conditions
are never known to be false. Previously the assert only ever used
local knowledge and so would be limited to cases like x != x for
integer x. Now that we use global knowledge it's possible to prove
the assertion condition is false in blocks that are in practice
unreachable. The patch therefore removes the assert.
Bootstrapped & regression-tested on x86_64-linux-gnu. I didn't write
a specific test because this is already covered by the testsuite if
the follow-on patch is also applied.
gcc/
* params.def (PARAM_MAX_SSA_NAME_QUERY_DEPTH): New param.
* doc/invoke.texi (--param max-ssa-name-query-depth): Document.
* fold-const.h (tree_unary_nonnegative_warnv_p)
(tree_single_nonnegative_warnv_p, tree_call_nonnegative_warnv_p)
(tree_expr_nonnegative_warnv_p): Add depth parameters.
* fold-const.c: Include gimple-fold.h and params.h.
(tree_ssa_name_nonnegative_warnv_p): New function.
(tree_unary_nonnegative_warnv_p, tree_binary_nonnegative_warnv_p)
(tree_single_nonnegative_warnv_p, tree_call_nonnegative_warnv_p)
(tree_invalid_nonnegative_warnv_p, tree_expr_nonnegative_warnv_p):
Add a depth parameter and increment it for recursive calls to
tree_expr_nonnegative_warnv_p. Use tree_ssa_name_nonnegative_warnv_p
to handle SSA names.
* gimple-fold.h (gimple_val_nonnegative_real_p): Delete.
(gimple_stmt_nonnegative_warnv_p): Declare.
* tree-vrp.c (remove_range_assertions): Remove assert that condition
cannot be proven false.
(gimple_assign_nonnegative_warnv_p, gimple_call_nonnegative_warnv_p)
(gimple_stmt_nonnegative_warnv_p): Move to...
* gimple-fold.c: ...here. Add depth parameters and pass them
down to the tree routines. Accept statements that aren't
assignments or calls but just return false for them.
(gimple_val_nonnegative_real_p): Delete.
* tree-ssa-math-opts.c (gimple_expand_builtin_pow): Use
tree_expr_nonnegative_p instead of gimple_val_nonnegative_real_p.
Check HONOR_NANs first.
From-SVN: r228614
Diffstat (limited to 'gcc/tree-vrp.c')
-rw-r--r-- | gcc/tree-vrp.c | 77 |
1 files changed, 0 insertions, 77 deletions
diff --git a/gcc/tree-vrp.c b/gcc/tree-vrp.c index ef5ef10..fe34ffd 100644 --- a/gcc/tree-vrp.c +++ b/gcc/tree-vrp.c @@ -1007,80 +1007,6 @@ usable_range_p (value_range *vr, bool *strict_overflow_p) return true; } - -/* Return true if the result of assignment STMT is know to be non-negative. - If the return value is based on the assumption that signed overflow is - undefined, set *STRICT_OVERFLOW_P to true; otherwise, don't change - *STRICT_OVERFLOW_P.*/ - -static bool -gimple_assign_nonnegative_warnv_p (gimple *stmt, bool *strict_overflow_p) -{ - enum tree_code code = gimple_assign_rhs_code (stmt); - switch (get_gimple_rhs_class (code)) - { - case GIMPLE_UNARY_RHS: - return tree_unary_nonnegative_warnv_p (gimple_assign_rhs_code (stmt), - gimple_expr_type (stmt), - gimple_assign_rhs1 (stmt), - strict_overflow_p); - case GIMPLE_BINARY_RHS: - return tree_binary_nonnegative_warnv_p (gimple_assign_rhs_code (stmt), - gimple_expr_type (stmt), - gimple_assign_rhs1 (stmt), - gimple_assign_rhs2 (stmt), - strict_overflow_p); - case GIMPLE_TERNARY_RHS: - return false; - case GIMPLE_SINGLE_RHS: - return tree_single_nonnegative_warnv_p (gimple_assign_rhs1 (stmt), - strict_overflow_p); - case GIMPLE_INVALID_RHS: - gcc_unreachable (); - default: - gcc_unreachable (); - } -} - -/* Return true if return value of call STMT is know to be non-negative. - If the return value is based on the assumption that signed overflow is - undefined, set *STRICT_OVERFLOW_P to true; otherwise, don't change - *STRICT_OVERFLOW_P.*/ - -static bool -gimple_call_nonnegative_warnv_p (gimple *stmt, bool *strict_overflow_p) -{ - tree arg0 = gimple_call_num_args (stmt) > 0 ? - gimple_call_arg (stmt, 0) : NULL_TREE; - tree arg1 = gimple_call_num_args (stmt) > 1 ? - gimple_call_arg (stmt, 1) : NULL_TREE; - - return tree_call_nonnegative_warnv_p (gimple_expr_type (stmt), - gimple_call_fndecl (stmt), - arg0, - arg1, - strict_overflow_p); -} - -/* Return true if STMT is know to compute a non-negative value. - If the return value is based on the assumption that signed overflow is - undefined, set *STRICT_OVERFLOW_P to true; otherwise, don't change - *STRICT_OVERFLOW_P.*/ - -static bool -gimple_stmt_nonnegative_warnv_p (gimple *stmt, bool *strict_overflow_p) -{ - switch (gimple_code (stmt)) - { - case GIMPLE_ASSIGN: - return gimple_assign_nonnegative_warnv_p (stmt, strict_overflow_p); - case GIMPLE_CALL: - return gimple_call_nonnegative_warnv_p (stmt, strict_overflow_p); - default: - gcc_unreachable (); - } -} - /* Return true if the result of assignment STMT is know to be non-zero. If the return value is based on the assumption that signed overflow is undefined, set *STRICT_OVERFLOW_P to true; otherwise, don't change @@ -6858,12 +6784,9 @@ remove_range_assertions (void) tree lhs = gimple_assign_lhs (stmt); tree rhs = gimple_assign_rhs1 (stmt); tree var; - tree cond = fold (ASSERT_EXPR_COND (rhs)); use_operand_p use_p; imm_use_iterator iter; - gcc_assert (cond != boolean_false_node); - var = ASSERT_EXPR_VAR (rhs); gcc_assert (TREE_CODE (var) == SSA_NAME); |