diff options
author | jakub <jakub@138bc75d-0d04-0410-961f-82ee72b054a4> | 2004-06-30 10:09:55 +0000 |
---|---|---|
committer | jakub <jakub@138bc75d-0d04-0410-961f-82ee72b054a4> | 2004-06-30 10:09:55 +0000 |
commit | 0717ec39a9d30b63907795856db1f0b4e78fbde8 (patch) | |
tree | de710deee48e0626b77470a406d37539f06fe50a /gcc/simplify-rtx.c | |
parent | b589ba75d933c6f66bdefcd4bcce5276d9be5848 (diff) | |
download | ppe42-gcc-0717ec39a9d30b63907795856db1f0b4e78fbde8.tar.gz ppe42-gcc-0717ec39a9d30b63907795856db1f0b4e78fbde8.zip |
* simplify-rtx.c (simplify_binary_operation): Simplify
((A & N) + B) & M -> (A + B) & M if M is pow2 minus 1 constant and
N has at least all bits in M set as well.
PR tree-optimization/15310
* expr.c (expand_assignment): Optimize += or -= on a bit field in
most significant bits.
* gcc.c-torture/execute/20040629-1.c: New test.
git-svn-id: svn+ssh://gcc.gnu.org/svn/gcc/trunk@83900 138bc75d-0d04-0410-961f-82ee72b054a4
Diffstat (limited to 'gcc/simplify-rtx.c')
-rw-r--r-- | gcc/simplify-rtx.c | 46 |
1 files changed, 46 insertions, 0 deletions
diff --git a/gcc/simplify-rtx.c b/gcc/simplify-rtx.c index 0b716a40a0e..1ca27b288f4 100644 --- a/gcc/simplify-rtx.c +++ b/gcc/simplify-rtx.c @@ -1894,6 +1894,52 @@ simplify_binary_operation (enum rtx_code code, enum machine_mode mode, && ! side_effects_p (op0) && GET_MODE_CLASS (mode) != MODE_CC) return const0_rtx; + /* For constants M and N, if M == (1LL << cst) - 1 && (N & M) == M, + ((A & N) + B) & M -> (A + B) & M + Similarly if (N & M) == 0, + ((A | N) + B) & M -> (A + B) & M + and for - instead of + and/or ^ instead of |. */ + if (GET_CODE (trueop1) == CONST_INT + && GET_MODE_BITSIZE (mode) <= HOST_BITS_PER_WIDE_INT + && ~INTVAL (trueop1) + && (INTVAL (trueop1) & (INTVAL (trueop1) + 1)) == 0 + && (GET_CODE (op0) == PLUS || GET_CODE (op0) == MINUS)) + { + rtx pmop[2]; + int which; + + pmop[0] = XEXP (op0, 0); + pmop[1] = XEXP (op0, 1); + + for (which = 0; which < 2; which++) + { + tem = pmop[which]; + switch (GET_CODE (tem)) + { + case AND: + if (GET_CODE (XEXP (tem, 1)) == CONST_INT + && (INTVAL (XEXP (tem, 1)) & INTVAL (trueop1)) + == INTVAL (trueop1)) + pmop[which] = XEXP (tem, 0); + break; + case IOR: + case XOR: + if (GET_CODE (XEXP (tem, 1)) == CONST_INT + && (INTVAL (XEXP (tem, 1)) & INTVAL (trueop1)) == 0) + pmop[which] = XEXP (tem, 0); + break; + default: + break; + } + } + + if (pmop[0] != XEXP (op0, 0) || pmop[1] != XEXP (op0, 1)) + { + tem = simplify_gen_binary (GET_CODE (op0), mode, + pmop[0], pmop[1]); + return simplify_gen_binary (code, mode, tem, op1); + } + } tem = simplify_associative_operation (code, mode, op0, op1); if (tem) return tem; |