aboutsummaryrefslogtreecommitdiff
path: root/gcc/match.pd
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/match.pd
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/match.pd')
-rw-r--r--gcc/match.pd8
1 files changed, 7 insertions, 1 deletions
diff --git a/gcc/match.pd b/gcc/match.pd
index 3913073..64e718c 100644
--- a/gcc/match.pd
+++ b/gcc/match.pd
@@ -295,7 +295,13 @@ DEFINE_INT_AND_FLOAT_ROUND_FN (RINT)
(trunc_mod @0 (convert? (negate @1)))
(if (!TYPE_UNSIGNED (type)
&& !TYPE_OVERFLOW_TRAPS (type)
- && tree_nop_conversion_p (type, TREE_TYPE (@1)))
+ && tree_nop_conversion_p (type, TREE_TYPE (@1))
+ /* Avoid this transformation if X might be INT_MIN or
+ Y might be -1, because we would then change valid
+ INT_MIN % -(-1) into invalid INT_MIN % -1. */
+ && (expr_not_equal_to (@0, TYPE_MIN_VALUE (type))
+ || expr_not_equal_to (@1, wi::minus_one (TYPE_PRECISION
+ (TREE_TYPE (@1))))))
(trunc_mod @0 (convert @1))))
/* X - (X / Y) * Y is the same as X % Y. */