diff options
author | Jakub Jelinek <jakub@redhat.com> | 2014-03-26 10:17:10 +0100 |
---|---|---|
committer | Jakub Jelinek <jakub@gcc.gnu.org> | 2014-03-26 10:17:10 +0100 |
commit | 368b454d67fe613c8f7d588400b874584ef9f893 (patch) | |
tree | e5851048627095b50a086856c5651b462c6c116f /gcc/tree-vrp.c | |
parent | ee0cff60490d42c50e5db6a5cba41c70ac6c1433 (diff) | |
download | gcc-368b454d67fe613c8f7d588400b874584ef9f893.zip gcc-368b454d67fe613c8f7d588400b874584ef9f893.tar.gz gcc-368b454d67fe613c8f7d588400b874584ef9f893.tar.bz2 |
tree-vrp.c (simplify_internal_call_using_ranges): If only one range is range_int_cst_p...
* tree-vrp.c (simplify_internal_call_using_ranges): If only
one range is range_int_cst_p, but not both, at least optimize
addition/subtraction of 0 and multiplication by 0 or 1.
* gimple-fold.c (gimple_fold_call): Fold
IFN_UBSAN_CHECK_{ADD,SUB,MUL}.
(gimple_fold_stmt_to_constant_1): If both op0 and op1 aren't
INTEGER_CSTs, try to fold at least x * 0 and y - y.
From-SVN: r208840
Diffstat (limited to 'gcc/tree-vrp.c')
-rw-r--r-- | gcc/tree-vrp.c | 57 |
1 files changed, 42 insertions, 15 deletions
diff --git a/gcc/tree-vrp.c b/gcc/tree-vrp.c index 3060210..14f1526 100644 --- a/gcc/tree-vrp.c +++ b/gcc/tree-vrp.c @@ -9336,31 +9336,58 @@ simplify_internal_call_using_ranges (gimple_stmt_iterator *gsi, gimple stmt) else if (TREE_CODE (op0) == INTEGER_CST) set_value_range_to_value (&vr0, op0, NULL); else - return false; + set_value_range_to_varying (&vr0); if (TREE_CODE (op1) == SSA_NAME) vr1 = *get_value_range (op1); else if (TREE_CODE (op1) == INTEGER_CST) set_value_range_to_value (&vr1, op1, NULL); else - return false; - - if (!range_int_cst_p (&vr0) || !range_int_cst_p (&vr1)) - return false; + set_value_range_to_varying (&vr1); - tree r1 = int_const_binop (subcode, vr0.min, vr1.min); - tree r2 = int_const_binop (subcode, vr0.max, vr1.max); - if (r1 == NULL_TREE || TREE_OVERFLOW (r1) - || r2 == NULL_TREE || TREE_OVERFLOW (r2)) - return false; - if (subcode == MULT_EXPR) + if (!range_int_cst_p (&vr0)) { - tree r3 = int_const_binop (subcode, vr0.min, vr1.max); - tree r4 = int_const_binop (subcode, vr0.max, vr1.min); - if (r3 == NULL_TREE || TREE_OVERFLOW (r3) - || r4 == NULL_TREE || TREE_OVERFLOW (r4)) + /* If one range is VR_ANTI_RANGE, VR_VARYING etc., + optimize at least x = y + 0; x = y - 0; x = y * 0; + and x = y * 1; which never overflow. */ + if (!range_int_cst_p (&vr1)) + return false; + if (tree_int_cst_sgn (vr1.min) == -1) + return false; + if (compare_tree_int (vr1.max, subcode == MULT_EXPR) == 1) return false; } + else if (!range_int_cst_p (&vr1)) + { + /* If one range is VR_ANTI_RANGE, VR_VARYING etc., + optimize at least x = 0 + y; x = 0 * y; and x = 1 * y; + which never overflow. */ + if (subcode == MINUS_EXPR) + return false; + if (!range_int_cst_p (&vr0)) + return false; + if (tree_int_cst_sgn (vr0.min) == -1) + return false; + if (compare_tree_int (vr0.max, subcode == MULT_EXPR) == 1) + return false; + } + else + { + tree r1 = int_const_binop (subcode, vr0.min, vr1.min); + tree r2 = int_const_binop (subcode, vr0.max, vr1.max); + if (r1 == NULL_TREE || TREE_OVERFLOW (r1) + || r2 == NULL_TREE || TREE_OVERFLOW (r2)) + return false; + if (subcode == MULT_EXPR) + { + tree r3 = int_const_binop (subcode, vr0.min, vr1.max); + tree r4 = int_const_binop (subcode, vr0.max, vr1.min); + if (r3 == NULL_TREE || TREE_OVERFLOW (r3) + || r4 == NULL_TREE || TREE_OVERFLOW (r4)) + return false; + } + } + gimple g = gimple_build_assign_with_ops (subcode, gimple_call_lhs (stmt), op0, op1); gsi_replace (gsi, g, false); |