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/fold-const.c | |
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/fold-const.c')
-rw-r--r-- | gcc/fold-const.c | 71 |
1 files changed, 1 insertions, 70 deletions
diff --git a/gcc/fold-const.c b/gcc/fold-const.c index 3c389ee..0004f78 100644 --- a/gcc/fold-const.c +++ b/gcc/fold-const.c @@ -297,7 +297,7 @@ fold_deferring_overflow_warnings_p (void) /* This is called when we fold something based on the fact that signed overflow is undefined. */ -static void +void fold_overflow_warning (const char* gmsgid, enum warn_strict_overflow_code wc) { if (fold_deferring_overflow_warnings > 0) @@ -8392,75 +8392,6 @@ fold_comparison (location_t loc, enum tree_code code, tree type, STRIP_SIGN_NOPS (arg0); STRIP_SIGN_NOPS (arg1); - /* Transform comparisons of the form X +- C1 CMP C2 to X CMP C2 -+ C1. */ - if ((TREE_CODE (arg0) == PLUS_EXPR || TREE_CODE (arg0) == MINUS_EXPR) - && (equality_code - || (ANY_INTEGRAL_TYPE_P (TREE_TYPE (arg0)) - && TYPE_OVERFLOW_UNDEFINED (TREE_TYPE (arg0)))) - && TREE_CODE (TREE_OPERAND (arg0, 1)) == INTEGER_CST - && !TREE_OVERFLOW (TREE_OPERAND (arg0, 1)) - && TREE_CODE (arg1) == INTEGER_CST - && !TREE_OVERFLOW (arg1)) - { - const enum tree_code - reverse_op = TREE_CODE (arg0) == PLUS_EXPR ? MINUS_EXPR : PLUS_EXPR; - tree const1 = TREE_OPERAND (arg0, 1); - tree const2 = fold_convert_loc (loc, TREE_TYPE (const1), arg1); - tree variable = TREE_OPERAND (arg0, 0); - tree new_const = int_const_binop (reverse_op, const2, const1); - - /* If the constant operation overflowed this can be - simplified as a comparison against INT_MAX/INT_MIN. */ - if (TREE_OVERFLOW (new_const) - && !TYPE_OVERFLOW_WRAPS (TREE_TYPE (arg0))) - { - int const1_sgn = tree_int_cst_sgn (const1); - enum tree_code code2 = code; - - /* Get the sign of the constant on the lhs if the - operation were VARIABLE + CONST1. */ - if (TREE_CODE (arg0) == MINUS_EXPR) - const1_sgn = -const1_sgn; - - /* The sign of the constant determines if we overflowed - INT_MAX (const1_sgn == -1) or INT_MIN (const1_sgn == 1). - Canonicalize to the INT_MIN overflow by swapping the comparison - if necessary. */ - if (const1_sgn == -1) - code2 = swap_tree_comparison (code); - - /* We now can look at the canonicalized case - VARIABLE + 1 CODE2 INT_MIN - and decide on the result. */ - switch (code2) - { - case EQ_EXPR: - case LT_EXPR: - case LE_EXPR: - return - omit_one_operand_loc (loc, type, boolean_false_node, variable); - - case NE_EXPR: - case GE_EXPR: - case GT_EXPR: - return - omit_one_operand_loc (loc, type, boolean_true_node, variable); - - default: - gcc_unreachable (); - } - } - else - { - if (!equality_code) - fold_overflow_warning ("assuming signed overflow does not occur " - "when changing X +- C1 cmp C2 to " - "X cmp C2 -+ C1", - WARN_STRICT_OVERFLOW_COMPARISON); - return fold_build2_loc (loc, code, type, variable, new_const); - } - } - /* For comparisons of pointers we can decompose it to a compile time comparison of the base objects and the offsets into the object. This requires at least one operand being an ADDR_EXPR or a |