aboutsummaryrefslogtreecommitdiff
path: root/gcc/match.pd
diff options
context:
space:
mode:
authorMarc Glisse <marc.glisse@inria.fr>2016-05-02 16:09:07 +0200
committerMarc Glisse <glisse@gcc.gnu.org>2016-05-02 14:09:07 +0000
commita8b85ce9e2bffc9fcacaf0cfbbb803b01f7598e8 (patch)
tree7567c427730a007f93a9f0c7a26e2c9deebd6207 /gcc/match.pd
parent5b37e8664b05336df60996a2411b4d61a852c613 (diff)
downloadgcc-a8b85ce9e2bffc9fcacaf0cfbbb803b01f7598e8.zip
gcc-a8b85ce9e2bffc9fcacaf0cfbbb803b01f7598e8.tar.gz
gcc-a8b85ce9e2bffc9fcacaf0cfbbb803b01f7598e8.tar.bz2
Move "X +- C1 CMP C2 to X CMP C2 -+ C1" to match.pd
2016-05-02 Marc Glisse <marc.glisse@inria.fr> gcc/ * flag-types.h (enum warn_strict_overflow_code): Move ... * coretypes.h: ... here. * fold-const.h (fold_overflow_warning): Declare. * fold-const.c (fold_overflow_warning): Make non-static. (fold_comparison): Move the transformation of X +- C1 CMP C2 into X CMP C2 -+ C1 ... * match.pd: ... here. * gimple-fold.c (fold_stmt_1): Protect with fold_defer_overflow_warnings. gcc/testsuite/ * gcc.dg/tree-ssa/20040305-1.c: Adjust. From-SVN: r235760
Diffstat (limited to 'gcc/match.pd')
-rw-r--r--gcc/match.pd44
1 files changed, 44 insertions, 0 deletions
diff --git a/gcc/match.pd b/gcc/match.pd
index 608afa3..f1b1f15 100644
--- a/gcc/match.pd
+++ b/gcc/match.pd
@@ -3186,3 +3186,47 @@ DEFINE_INT_AND_FLOAT_ROUND_FN (RINT)
(SIGNBIT @0)
(if (!HONOR_SIGNED_ZEROS (@0))
(convert (lt @0 { build_real (TREE_TYPE (@0), dconst0); }))))
+
+/* Transform comparisons of the form X +- C1 CMP C2 to X CMP C2 -+ C1. */
+(for cmp (eq ne)
+ (for op (plus minus)
+ rop (minus plus)
+ (simplify
+ (cmp (op@3 @0 INTEGER_CST@1) INTEGER_CST@2)
+ (if (!TREE_OVERFLOW (@1) && !TREE_OVERFLOW (@2)
+ && !TYPE_OVERFLOW_SANITIZED (TREE_TYPE (@0))
+ && !TYPE_OVERFLOW_TRAPS (TREE_TYPE (@0))
+ && !TYPE_SATURATING (TREE_TYPE (@0)))
+ (with { tree res = int_const_binop (rop, @2, @1); }
+ (if (TREE_OVERFLOW (res))
+ { constant_boolean_node (cmp == NE_EXPR, type); }
+ (if (single_use (@3))
+ (cmp @0 { res; }))))))))
+(for cmp (lt le gt ge)
+ (for op (plus minus)
+ rop (minus plus)
+ (simplify
+ (cmp (op@3 @0 INTEGER_CST@1) INTEGER_CST@2)
+ (if (!TREE_OVERFLOW (@1) && !TREE_OVERFLOW (@2)
+ && TYPE_OVERFLOW_UNDEFINED (TREE_TYPE (@0)))
+ (with { tree res = int_const_binop (rop, @2, @1); }
+ (if (TREE_OVERFLOW (res))
+ {
+ fold_overflow_warning (("assuming signed overflow does not occur "
+ "when simplifying conditional to constant"),
+ WARN_STRICT_OVERFLOW_CONDITIONAL);
+ bool less = cmp == LE_EXPR || cmp == LT_EXPR;
+ /* wi::ges_p (@2, 0) should be sufficient for a signed type. */
+ bool ovf_high = wi::lt_p (@1, 0, TYPE_SIGN (TREE_TYPE (@1)))
+ != (op == MINUS_EXPR);
+ constant_boolean_node (less == ovf_high, type);
+ }
+ (if (single_use (@3))
+ (with
+ {
+ fold_overflow_warning (("assuming signed overflow does not occur "
+ "when changing X +- C1 cmp C2 to "
+ "X cmp C2 -+ C1"),
+ WARN_STRICT_OVERFLOW_COMPARISON);
+ }
+ (cmp @0 { res; })))))))))