aboutsummaryrefslogtreecommitdiff
path: root/gcc/combine.c
diff options
context:
space:
mode:
authorBernd Schmidt <crux@pool.informatik.rwth-aachen.de>1999-01-06 16:33:29 -0700
committerJeff Law <law@gcc.gnu.org>1999-01-06 16:33:29 -0700
commit70186b342c44e983d7005488b9427f0d00907ae8 (patch)
tree1040cfc2130c6988db39bccbc1bcff506275d78c /gcc/combine.c
parent548e44b3366c210afee8754753a82a8641118684 (diff)
downloadgcc-70186b342c44e983d7005488b9427f0d00907ae8.zip
gcc-70186b342c44e983d7005488b9427f0d00907ae8.tar.gz
gcc-70186b342c44e983d7005488b9427f0d00907ae8.tar.bz2
combine.c (num_sign_bit_copies): In NEG...
* combine.c (num_sign_bit_copies): In NEG, MULT, DIV and MOD cases, when a test can't be performed due to limited width of HOST_BITS_PER_WIDE_INT, use the more conservative approximation. Fix UDIV case for cases where the first operand has the highest bit set. From-SVN: r24547
Diffstat (limited to 'gcc/combine.c')
-rw-r--r--gcc/combine.c46
1 files changed, 28 insertions, 18 deletions
diff --git a/gcc/combine.c b/gcc/combine.c
index bd0a225..a528a56 100644
--- a/gcc/combine.c
+++ b/gcc/combine.c
@@ -8020,13 +8020,15 @@ num_sign_bit_copies (x, mode)
is known to be positive, the number of sign bit copies is the
same as that of the input. Finally, if the input has just one bit
that might be nonzero, all the bits are copies of the sign bit. */
+ num0 = num_sign_bit_copies (XEXP (x, 0), mode);
+ if (bitwidth > HOST_BITS_PER_WIDE_INT)
+ return num0 > 1 ? num0 - 1 : 1;
+
nonzero = nonzero_bits (XEXP (x, 0), mode);
if (nonzero == 1)
return bitwidth;
- num0 = num_sign_bit_copies (XEXP (x, 0), mode);
if (num0 > 1
- && bitwidth <= HOST_BITS_PER_WIDE_INT
&& (((HOST_WIDE_INT) 1 << (bitwidth - 1)) & nonzero))
num0--;
@@ -8070,19 +8072,27 @@ num_sign_bit_copies (x, mode)
result = bitwidth - (bitwidth - num0) - (bitwidth - num1);
if (result > 0
- && bitwidth <= HOST_BITS_PER_WIDE_INT
- && ((nonzero_bits (XEXP (x, 0), mode)
- & ((HOST_WIDE_INT) 1 << (bitwidth - 1))) != 0)
- && ((nonzero_bits (XEXP (x, 1), mode)
- & ((HOST_WIDE_INT) 1 << (bitwidth - 1))) != 0))
+ && (bitwidth > HOST_BITS_PER_WIDE_INT
+ || (((nonzero_bits (XEXP (x, 0), mode)
+ & ((HOST_WIDE_INT) 1 << (bitwidth - 1))) != 0)
+ && ((nonzero_bits (XEXP (x, 1), mode)
+ & ((HOST_WIDE_INT) 1 << (bitwidth - 1))) != 0))))
result--;
return MAX (1, result);
case UDIV:
- /* The result must be <= the first operand. */
- return num_sign_bit_copies (XEXP (x, 0), mode);
-
+ /* The result must be <= the first operand. If the first operand
+ has the high bit set, we know nothing about the number of sign
+ bit copies. */
+ if (bitwidth > HOST_BITS_PER_WIDE_INT)
+ return 1;
+ else if ((nonzero_bits (XEXP (x, 0), mode)
+ & ((HOST_WIDE_INT) 1 << (bitwidth - 1))) != 0)
+ return 1;
+ else
+ return num_sign_bit_copies (XEXP (x, 0), mode);
+
case UMOD:
/* The result must be <= the scond operand. */
return num_sign_bit_copies (XEXP (x, 1), mode);
@@ -8093,20 +8103,20 @@ num_sign_bit_copies (x, mode)
to add 1. */
result = num_sign_bit_copies (XEXP (x, 0), mode);
if (result > 1
- && bitwidth <= HOST_BITS_PER_WIDE_INT
- && (nonzero_bits (XEXP (x, 1), mode)
- & ((HOST_WIDE_INT) 1 << (bitwidth - 1))) != 0)
- result --;
+ && (bitwidth > HOST_BITS_PER_WIDE_INT
+ || (nonzero_bits (XEXP (x, 1), mode)
+ & ((HOST_WIDE_INT) 1 << (bitwidth - 1))) != 0))
+ result--;
return result;
case MOD:
result = num_sign_bit_copies (XEXP (x, 1), mode);
if (result > 1
- && bitwidth <= HOST_BITS_PER_WIDE_INT
- && (nonzero_bits (XEXP (x, 1), mode)
- & ((HOST_WIDE_INT) 1 << (bitwidth - 1))) != 0)
- result --;
+ && (bitwidth > HOST_BITS_PER_WIDE_INT
+ || (nonzero_bits (XEXP (x, 1), mode)
+ & ((HOST_WIDE_INT) 1 << (bitwidth - 1))) != 0))
+ result--;
return result;