summaryrefslogtreecommitdiff
path: root/gcc/rtlanal.c
diff options
context:
space:
mode:
authornemet <nemet@138bc75d-0d04-0410-961f-82ee72b054a4>2007-07-06 00:20:46 +0000
committernemet <nemet@138bc75d-0d04-0410-961f-82ee72b054a4>2007-07-06 00:20:46 +0000
commitc07054e9cb2002971dbefcf713d5dd3ee131bfc4 (patch)
treef707059f7c1e3dc69a66829d782c26a55fe2be16 /gcc/rtlanal.c
parentcfaeedae3635b0dc78d5ffc3b0df8a6f91a1231e (diff)
downloadgcc-c07054e9cb2002971dbefcf713d5dd3ee131bfc4.tar.gz
* rtlanal.c (num_sign_bit_copies1): Improve cases of ANDing or
IORing with a constant. git-svn-id: svn+ssh://gcc.gnu.org/svn/gcc/trunk@126397 138bc75d-0d04-0410-961f-82ee72b054a4
Diffstat (limited to 'gcc/rtlanal.c')
-rw-r--r--gcc/rtlanal.c19
1 files changed, 19 insertions, 0 deletions
diff --git a/gcc/rtlanal.c b/gcc/rtlanal.c
index 3cdb76a16bd..9535104e707 100644
--- a/gcc/rtlanal.c
+++ b/gcc/rtlanal.c
@@ -4290,6 +4290,25 @@ num_sign_bit_copies1 (rtx x, enum machine_mode mode, rtx known_x,
known_x, known_mode, known_ret);
num1 = cached_num_sign_bit_copies (XEXP (x, 1), mode,
known_x, known_mode, known_ret);
+
+ /* If num1 is clearing some of the top bits then regardless of
+ the other term, we are guaranteed to have at least that many
+ high-order zero bits. */
+ if (code == AND
+ && num1 > 1
+ && bitwidth <= HOST_BITS_PER_WIDE_INT
+ && GET_CODE (XEXP (x, 1)) == CONST_INT
+ && !(INTVAL (XEXP (x, 1)) & ((HOST_WIDE_INT) 1 << (bitwidth - 1))))
+ return num1;
+
+ /* Similarly for IOR when setting high-order bits. */
+ if (code == IOR
+ && num1 > 1
+ && bitwidth <= HOST_BITS_PER_WIDE_INT
+ && GET_CODE (XEXP (x, 1)) == CONST_INT
+ && (INTVAL (XEXP (x, 1)) & ((HOST_WIDE_INT) 1 << (bitwidth - 1))))
+ return num1;
+
return MIN (num0, num1);
case PLUS: case MINUS: