diff options
author | Roger Sayle <roger@eyesopen.com> | 2004-03-11 17:45:03 +0000 |
---|---|---|
committer | Roger Sayle <sayle@gcc.gnu.org> | 2004-03-11 17:45:03 +0000 |
commit | 239a625ee83ff08df15beab3ca2f1b37881e7f10 (patch) | |
tree | 53c0a411f358defff23d8e0c39b1dc0819424479 /gcc/fold-const.c | |
parent | 4b0b51c9706b25603247ec6e48d8ac53e8db64f3 (diff) | |
download | gcc-239a625ee83ff08df15beab3ca2f1b37881e7f10.zip gcc-239a625ee83ff08df15beab3ca2f1b37881e7f10.tar.gz gcc-239a625ee83ff08df15beab3ca2f1b37881e7f10.tar.bz2 |
fold-const.c (negate_expr_p): We can optimize -((int)X>>C) where C is an integer constant one bit less than...
* fold-const.c (negate_expr_p) <RSHIFT_EXPR>: We can optimize
-((int)X>>C) where C is an integer constant one bit less than the
size of X into (unsigned)X>>C. Similarly for unsigned->signed.
(negate_expr) <RSHIFT_EXPR>: Implement the above transformations.
* simplify-rtx.c (simplify_unary_operation): Also implement the
above transformations at the RTL level.
* gcc.c-torture/execute/20040311-1.c: New test case.
From-SVN: r79334
Diffstat (limited to 'gcc/fold-const.c')
-rw-r--r-- | gcc/fold-const.c | 31 |
1 files changed, 31 insertions, 0 deletions
diff --git a/gcc/fold-const.c b/gcc/fold-const.c index 58b6c70d..5e18d68 100644 --- a/gcc/fold-const.c +++ b/gcc/fold-const.c @@ -920,6 +920,18 @@ negate_expr_p (tree t) return negate_expr_p (TREE_VALUE (TREE_OPERAND (t, 1))); break; + case RSHIFT_EXPR: + /* Optimize -((int)x >> 31) into (unsigned)x >> 31. */ + if (TREE_CODE (TREE_OPERAND (t, 1)) == INTEGER_CST) + { + tree op1 = TREE_OPERAND (t, 1); + if (TREE_INT_CST_HIGH (op1) == 0 + && (unsigned HOST_WIDE_INT) (TYPE_PRECISION (type) - 1) + == TREE_INT_CST_LOW (op1)) + return true; + } + break; + default: break; } @@ -1065,6 +1077,25 @@ negate_expr (tree t) } break; + case RSHIFT_EXPR: + /* Optimize -((int)x >> 31) into (unsigned)x >> 31. */ + if (TREE_CODE (TREE_OPERAND (t, 1)) == INTEGER_CST) + { + tree op1 = TREE_OPERAND (t, 1); + if (TREE_INT_CST_HIGH (op1) == 0 + && (unsigned HOST_WIDE_INT) (TYPE_PRECISION (type) - 1) + == TREE_INT_CST_LOW (op1)) + { + tree ntype = TREE_UNSIGNED (type) + ? (*lang_hooks.types.signed_type) (type) + : (*lang_hooks.types.unsigned_type) (type); + tree temp = fold_convert (ntype, TREE_OPERAND (t, 0)); + temp = fold (build2 (RSHIFT_EXPR, ntype, temp, op1)); + return fold_convert (type, temp); + } + } + break; + default: break; } |