diff options
author | Roger Sayle <roger@eyesopen.com> | 2006-02-18 05:22:46 +0000 |
---|---|---|
committer | Roger Sayle <sayle@gcc.gnu.org> | 2006-02-18 05:22:46 +0000 |
commit | 8305d7868da2a057825734b31113455ef97d9a76 (patch) | |
tree | 4d37d7702bbfbd33a364527a6c3b6ba57cad4e0a /gcc | |
parent | e097f8873d8389995b81b2794f7ec718064fb8b6 (diff) | |
download | gcc-8305d7868da2a057825734b31113455ef97d9a76.zip gcc-8305d7868da2a057825734b31113455ef97d9a76.tar.gz gcc-8305d7868da2a057825734b31113455ef97d9a76.tar.bz2 |
re PR rtl-optimization/25600 (unsigned>>31?-1:0 should be optimized to int>>31)
PR middle-end/25600
* fold-const.c (fold_binary): Fold (X >> C) != 0 into X < 0 when
C is one less than the width of X (and related transformations).
* simplify_rtx.c (simplify_unary_operation_1): Transform
(neg (lt x 0)) into either (ashiftrt X C) or (lshiftrt X C)
depending on STORE_FLAG_VALUE, were C is one less then the
width of X.
From-SVN: r111226
Diffstat (limited to 'gcc')
-rw-r--r-- | gcc/ChangeLog | 10 | ||||
-rw-r--r-- | gcc/fold-const.c | 24 | ||||
-rw-r--r-- | gcc/simplify-rtx.c | 13 |
3 files changed, 47 insertions, 0 deletions
diff --git a/gcc/ChangeLog b/gcc/ChangeLog index 479e8e8..9acf0ac 100644 --- a/gcc/ChangeLog +++ b/gcc/ChangeLog @@ -1,3 +1,13 @@ +2006-02-17 Roger Sayle <roger@eyesopen.com> + + PR middle-end/25600 + * fold-const.c (fold_binary): Fold (X >> C) != 0 into X < 0 when + C is one less than the width of X (and related transformations). + * simplify_rtx.c (simplify_unary_operation_1): Transform + (neg (lt x 0)) into either (ashiftrt X C) or (lshiftrt X C) + depending on STORE_FLAG_VALUE, were C is one less then the + width of X. + 2006-02-17 Daniel Berlin <dberlin@dberlin.org> Fix PR tree-optimization/26341 diff --git a/gcc/fold-const.c b/gcc/fold-const.c index 7413883..c77e7ba 100644 --- a/gcc/fold-const.c +++ b/gcc/fold-const.c @@ -10042,6 +10042,30 @@ fold_binary (enum tree_code code, tree type, tree op0, tree op1) return t1; } + /* Fold (X >> C) != 0 into X < 0 if C is one less than the width + of X. Similarly fold (X >> C) == 0 into X >= 0. */ + if ((code == EQ_EXPR || code == NE_EXPR) + && integer_zerop (arg1) + && TREE_CODE (arg0) == RSHIFT_EXPR + && TREE_CODE (TREE_OPERAND (arg0, 1)) == INTEGER_CST) + { + tree arg00 = TREE_OPERAND (arg0, 0); + tree arg01 = TREE_OPERAND (arg0, 1); + tree itype = TREE_TYPE (arg00); + if (TREE_INT_CST_HIGH (arg01) == 0 + && TREE_INT_CST_LOW (arg01) + == (unsigned HOST_WIDE_INT) (TYPE_PRECISION (itype) - 1)) + { + if (TYPE_UNSIGNED (itype)) + { + itype = lang_hooks.types.signed_type (itype); + arg00 = fold_convert (itype, arg00); + } + return fold_build2 (code == EQ_EXPR ? GE_EXPR : LT_EXPR, + type, arg00, build_int_cst (itype, 0)); + } + } + if ((code == EQ_EXPR || code == NE_EXPR) && integer_zerop (arg1) && tree_expr_nonzero_p (arg0)) diff --git a/gcc/simplify-rtx.c b/gcc/simplify-rtx.c index 6f4f09b..8b1f6fd 100644 --- a/gcc/simplify-rtx.c +++ b/gcc/simplify-rtx.c @@ -584,6 +584,19 @@ simplify_unary_operation_1 (enum rtx_code code, enum machine_mode mode, rtx op) && XEXP (op, 1) == const1_rtx && nonzero_bits (XEXP (op, 0), mode) == 1) return plus_constant (XEXP (op, 0), -1); + + /* (neg (lt x 0)) is (ashiftrt X C) if STORE_FLAG_VALUE is 1. */ + /* (neg (lt x 0)) is (lshiftrt X C) if STORE_FLAG_VALUE is -1. */ + if (GET_CODE (op) == LT + && XEXP (op, 1) == const0_rtx) + { + if (STORE_FLAG_VALUE == 1) + return simplify_gen_binary (ASHIFTRT, mode, XEXP (op, 0), + GEN_INT (GET_MODE_BITSIZE (mode) - 1)); + else if (STORE_FLAG_VALUE == -1) + return simplify_gen_binary (LSHIFTRT, mode, XEXP (op, 0), + GEN_INT (GET_MODE_BITSIZE (mode) - 1)); + } break; case TRUNCATE: |