diff options
author | Marc Glisse <marc.glisse@inria.fr> | 2016-05-02 16:09:07 +0200 |
---|---|---|
committer | Marc Glisse <glisse@gcc.gnu.org> | 2016-05-02 14:09:07 +0000 |
commit | a8b85ce9e2bffc9fcacaf0cfbbb803b01f7598e8 (patch) | |
tree | 7567c427730a007f93a9f0c7a26e2c9deebd6207 /gcc/match.pd | |
parent | 5b37e8664b05336df60996a2411b4d61a852c613 (diff) | |
download | gcc-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.pd | 44 |
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; }))))))))) |