aboutsummaryrefslogtreecommitdiff
path: root/gcc/fold-const.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/fold-const.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/fold-const.c')
-rw-r--r--gcc/fold-const.c41
1 files changed, 41 insertions, 0 deletions
diff --git a/gcc/fold-const.c b/gcc/fold-const.c
index 23d1be3..abd5360 100644
--- a/gcc/fold-const.c
+++ b/gcc/fold-const.c
@@ -74,6 +74,8 @@ along with GCC; see the file COPYING3. If not see
#include "tree-into-ssa.h"
#include "md5.h"
#include "case-cfn-macros.h"
+#include "stringpool.h"
+#include "tree-ssanames.h"
#ifndef LOAD_EXTEND_OP
#define LOAD_EXTEND_OP(M) UNKNOWN
@@ -9101,6 +9103,45 @@ tree_expr_nonzero_p (tree t)
return ret;
}
+/* Return true if T is known not to be equal to an integer W. */
+
+bool
+expr_not_equal_to (tree t, const wide_int &w)
+{
+ wide_int min, max, nz;
+ value_range_type rtype;
+ switch (TREE_CODE (t))
+ {
+ case INTEGER_CST:
+ return wi::ne_p (t, w);
+
+ case SSA_NAME:
+ if (!INTEGRAL_TYPE_P (TREE_TYPE (t)))
+ return false;
+ rtype = get_range_info (t, &min, &max);
+ if (rtype == VR_RANGE)
+ {
+ if (wi::lt_p (max, w, TYPE_SIGN (TREE_TYPE (t))))
+ return true;
+ if (wi::lt_p (w, min, TYPE_SIGN (TREE_TYPE (t))))
+ return true;
+ }
+ else if (rtype == VR_ANTI_RANGE
+ && wi::le_p (min, w, TYPE_SIGN (TREE_TYPE (t)))
+ && wi::le_p (w, max, TYPE_SIGN (TREE_TYPE (t))))
+ return true;
+ /* If T has some known zero bits and W has any of those bits set,
+ then T is known not to be equal to W. */
+ if (wi::ne_p (wi::zext (wi::bit_and_not (w, get_nonzero_bits (t)),
+ TYPE_PRECISION (TREE_TYPE (t))), 0))
+ return true;
+ return false;
+
+ default:
+ return false;
+ }
+}
+
/* Fold a binary expression of code CODE and type TYPE with operands
OP0 and OP1. LOC is the location of the resulting expression.
Return the folded expression if folding is successful. Otherwise,