aboutsummaryrefslogtreecommitdiff
path: root/gcc/tree-vrp.c
diff options
context:
space:
mode:
authorJakub Jelinek <jakub@redhat.com>2016-01-09 08:37:04 +0100
committerJakub Jelinek <jakub@gcc.gnu.org>2016-01-09 08:37:04 +0100
commit20b8d7342cc4920c79aebc0317150abe66068957 (patch)
tree45e51c7b289d01fdbda2b9323067a5127cd78f76 /gcc/tree-vrp.c
parentc50e614be6bb98f8a67f6fda4f73b412b035329d (diff)
downloadgcc-20b8d7342cc4920c79aebc0317150abe66068957.zip
gcc-20b8d7342cc4920c79aebc0317150abe66068957.tar.gz
gcc-20b8d7342cc4920c79aebc0317150abe66068957.tar.bz2
re PR middle-end/50865 (Invalid code generation for INT64_MIN % 1 on x86_64)
PR middle-end/50865 PR tree-optimization/69097 * fold-const.h (expr_not_equal_to): New prototype. * fold-const.c: Include stringpool.h and tree-ssanames.h. (expr_not_equal_to): New function. * match.pd (X % -Y is the same as X % Y): Don't optimize unless X is known not to be equal to minimum or Y is known not to be equal to -1. * tree-vrp.c (simplify_div_or_mod_using_ranges): Add GSI argument. fold TRUNC_MOD_EXPR if the second argument is not a power of two. (simplify_stmt_using_ranges): Adjust caller. (vrp_finalize): Call set_value_range on SSA_NAMEs before calling substitute_and_fold. * gcc.c-torture/execute/pr50865.c: New test. * gcc.c-torture/execute/pr69097-1.c: New test. * gcc.c-torture/execute/pr69097-2.c: New test. * gcc.dg/pr69097-1.c: New test. * gcc.dg/pr69097-2.c: New test. From-SVN: r232188
Diffstat (limited to 'gcc/tree-vrp.c')
-rw-r--r--gcc/tree-vrp.c39
1 files changed, 23 insertions, 16 deletions
diff --git a/gcc/tree-vrp.c b/gcc/tree-vrp.c
index 2cc33aa..e6c11e0 100644
--- a/gcc/tree-vrp.c
+++ b/gcc/tree-vrp.c
@@ -8942,7 +8942,7 @@ simplify_truth_ops_using_ranges (gimple_stmt_iterator *gsi, gimple *stmt)
modulo. */
static bool
-simplify_div_or_mod_using_ranges (gimple *stmt)
+simplify_div_or_mod_using_ranges (gimple_stmt_iterator *gsi, gimple *stmt)
{
enum tree_code rhs_code = gimple_assign_rhs_code (stmt);
tree val = NULL;
@@ -8971,12 +8971,19 @@ simplify_div_or_mod_using_ranges (gimple *stmt)
}
if (!integer_pow2p (op1))
- return false;
-
- if (TYPE_UNSIGNED (TREE_TYPE (op0)))
{
- val = integer_one_node;
+ /* X % -Y can be only optimized into X % Y either if
+ X is not INT_MIN, or Y is not -1. Fold it now, as after
+ remove_range_assertions the range info might be not available
+ anymore. */
+ if (rhs_code == TRUNC_MOD_EXPR
+ && fold_stmt (gsi, follow_single_use_edges))
+ return true;
+ return false;
}
+
+ if (TYPE_UNSIGNED (TREE_TYPE (op0)))
+ val = integer_one_node;
else
{
bool sop = false;
@@ -9890,7 +9897,7 @@ simplify_stmt_using_ranges (gimple_stmt_iterator *gsi)
case TRUNC_MOD_EXPR:
if (TREE_CODE (rhs1) == SSA_NAME
&& INTEGRAL_TYPE_P (TREE_TYPE (rhs1)))
- return simplify_div_or_mod_using_ranges (stmt);
+ return simplify_div_or_mod_using_ranges (gsi, stmt);
break;
/* Transform ABS (X) into X or -X as appropriate. */
@@ -10200,16 +10207,6 @@ vrp_finalize (bool warn_array_bounds_p)
fprintf (dump_file, "\n");
}
- substitute_and_fold (op_with_constant_singleton_value_range,
- vrp_fold_stmt, false);
-
- if (warn_array_bounds && warn_array_bounds_p)
- check_all_array_refs ();
-
- /* We must identify jump threading opportunities before we release
- the datastructures built by VRP. */
- identify_jump_threads ();
-
/* Set value range to non pointer SSA_NAMEs. */
for (i = 0; i < num_vr_values; i++)
if (vr_value[i])
@@ -10230,6 +10227,16 @@ vrp_finalize (bool warn_array_bounds_p)
vr_value[i]->max);
}
+ substitute_and_fold (op_with_constant_singleton_value_range,
+ vrp_fold_stmt, false);
+
+ if (warn_array_bounds && warn_array_bounds_p)
+ check_all_array_refs ();
+
+ /* We must identify jump threading opportunities before we release
+ the datastructures built by VRP. */
+ identify_jump_threads ();
+
/* Free allocated memory. */
for (i = 0; i < num_vr_values; i++)
if (vr_value[i])