diff options
author | Jakub Jelinek <jakub@redhat.com> | 2017-02-14 09:26:26 +0100 |
---|---|---|
committer | Jakub Jelinek <jakub@gcc.gnu.org> | 2017-02-14 09:26:26 +0100 |
commit | 73424a09736ea34e649dd9d86d829398b6365b3f (patch) | |
tree | 3ac2c9299dd9e1473a3a32c74eb60349fc07150a /gcc/tree-vrp.c | |
parent | 977472e8c683d25d5a7480c1316c9148bfe4932d (diff) | |
download | gcc-73424a09736ea34e649dd9d86d829398b6365b3f.zip gcc-73424a09736ea34e649dd9d86d829398b6365b3f.tar.gz gcc-73424a09736ea34e649dd9d86d829398b6365b3f.tar.bz2 |
re PR tree-optimization/79408 (Missed VRP optimization of integer modulo)
PR tree-optimization/79408
* tree-vrp.c (simplify_div_or_mod_using_ranges): Handle also the
case when on TRUNC_MOD_EXPR op0 is INTEGER_CST.
(simplify_stmt_using_ranges): Call simplify_div_or_mod_using_ranges
also if rhs1 is INTEGER_CST.
* gcc.dg/tree-ssa/pr79408-2.c: New test.
From-SVN: r245420
Diffstat (limited to 'gcc/tree-vrp.c')
-rw-r--r-- | gcc/tree-vrp.c | 32 |
1 files changed, 26 insertions, 6 deletions
diff --git a/gcc/tree-vrp.c b/gcc/tree-vrp.c index e058d8d..9ffecc9 100644 --- a/gcc/tree-vrp.c +++ b/gcc/tree-vrp.c @@ -9241,8 +9241,24 @@ simplify_div_or_mod_using_ranges (gimple_stmt_iterator *gsi, gimple *stmt) tree val = NULL; tree op0 = gimple_assign_rhs1 (stmt); tree op1 = gimple_assign_rhs2 (stmt); + tree op0min = NULL_TREE, op0max = NULL_TREE; tree op1min = op1; - value_range *vr = get_value_range (op0); + value_range *vr = NULL; + + if (TREE_CODE (op0) == INTEGER_CST) + { + op0min = op0; + op0max = op0; + } + else + { + vr = get_value_range (op0); + if (range_int_cst_p (vr)) + { + op0min = vr->min; + op0max = vr->max; + } + } if (rhs_code == TRUNC_MOD_EXPR && TREE_CODE (op1) == SSA_NAME) @@ -9254,13 +9270,13 @@ simplify_div_or_mod_using_ranges (gimple_stmt_iterator *gsi, gimple *stmt) if (rhs_code == TRUNC_MOD_EXPR && TREE_CODE (op1min) == INTEGER_CST && tree_int_cst_sgn (op1min) == 1 - && range_int_cst_p (vr) - && tree_int_cst_lt (vr->max, op1min)) + && op0max + && tree_int_cst_lt (op0max, op1min)) { if (TYPE_UNSIGNED (TREE_TYPE (op0)) - || tree_int_cst_sgn (vr->min) >= 0 + || tree_int_cst_sgn (op0min) >= 0 || tree_int_cst_lt (fold_unary (NEGATE_EXPR, TREE_TYPE (op1min), op1min), - vr->min)) + op0min)) { /* If op0 already has the range op0 % op1 has, then TRUNC_MOD_EXPR won't change anything. */ @@ -9269,6 +9285,9 @@ simplify_div_or_mod_using_ranges (gimple_stmt_iterator *gsi, gimple *stmt) } } + if (TREE_CODE (op0) != SSA_NAME) + return false; + if (!integer_pow2p (op1)) { /* X % -Y can be only optimized into X % Y either if @@ -10377,7 +10396,8 @@ simplify_stmt_using_ranges (gimple_stmt_iterator *gsi) range. */ case TRUNC_DIV_EXPR: case TRUNC_MOD_EXPR: - if (TREE_CODE (rhs1) == SSA_NAME + if ((TREE_CODE (rhs1) == SSA_NAME + || TREE_CODE (rhs1) == INTEGER_CST) && INTEGRAL_TYPE_P (TREE_TYPE (rhs1))) return simplify_div_or_mod_using_ranges (gsi, stmt); break; |