diff options
author | Jakub Jelinek <jakub@redhat.com> | 2016-01-09 08:37:04 +0100 |
---|---|---|
committer | Jakub Jelinek <jakub@gcc.gnu.org> | 2016-01-09 08:37:04 +0100 |
commit | 20b8d7342cc4920c79aebc0317150abe66068957 (patch) | |
tree | 45e51c7b289d01fdbda2b9323067a5127cd78f76 /gcc/tree-vrp.c | |
parent | c50e614be6bb98f8a67f6fda4f73b412b035329d (diff) | |
download | gcc-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.c | 39 |
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]) |