aboutsummaryrefslogtreecommitdiff
path: root/gcc/tree-vrp.c
diff options
context:
space:
mode:
authorJakub Jelinek <jakub@redhat.com>2017-02-14 09:26:26 +0100
committerJakub Jelinek <jakub@gcc.gnu.org>2017-02-14 09:26:26 +0100
commit73424a09736ea34e649dd9d86d829398b6365b3f (patch)
tree3ac2c9299dd9e1473a3a32c74eb60349fc07150a /gcc/tree-vrp.c
parent977472e8c683d25d5a7480c1316c9148bfe4932d (diff)
downloadgcc-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.c32
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;