aboutsummaryrefslogtreecommitdiff
path: root/gcc/combine.c
diff options
context:
space:
mode:
authorRichard Kenner <kenner@vlsi1.ultra.nyu.edu>2001-02-06 12:39:15 +0000
committerRichard Kenner <kenner@gcc.gnu.org>2001-02-06 07:39:15 -0500
commitd14057222fec681710cd1b1ac1d47478c0466bfb (patch)
treeef948bedc788321fdca09d6b2f508f386ee213d9 /gcc/combine.c
parenta87b4257946d4453f250585aa22adc4f70db1165 (diff)
downloadgcc-d14057222fec681710cd1b1ac1d47478c0466bfb.zip
gcc-d14057222fec681710cd1b1ac1d47478c0466bfb.tar.gz
gcc-d14057222fec681710cd1b1ac1d47478c0466bfb.tar.bz2
combine.c (nonzero_bits, case PLUS): If pointers extend unsigned and this is the sum of a pointer and a constant...
* combine.c (nonzero_bits, case PLUS): If pointers extend unsigned and this is the sum of a pointer and a constant, we know the result did not overflow. (num_sign_bit_copies, case PLUS): Likewise. * explow.c (convert_memory_address): Remove opposite SUBREG. * function.c (instantiate_new_reg): New function (from common code). (instantiate_virtual_regs_1): Call it. For PLUS, handle if (plus (subreg (virt-reg) (const_int)) if pointers sign- or zero-extend. * simplify-rtx.c (simplify_unary_operation, case ZERO_EXTEND): If pointers extend unsigned, use inside of SUBREG. (simplify_unary_operation, case SIGN_EXTEND): Likewise, if sign extend. From-SVN: r39489
Diffstat (limited to 'gcc/combine.c')
-rw-r--r--gcc/combine.c25
1 files changed, 24 insertions, 1 deletions
diff --git a/gcc/combine.c b/gcc/combine.c
index 74b02b5..662f05f 100644
--- a/gcc/combine.c
+++ b/gcc/combine.c
@@ -8308,6 +8308,16 @@ nonzero_bits (x, mode)
if (result_low > 0)
nonzero &= ~(((HOST_WIDE_INT) 1 << result_low) - 1);
+
+#ifdef POINTERS_EXTEND_UNSIGNED
+ /* If pointers extend unsigned and this is an addition or subtraction
+ to a pointer in Pmode, all the bits above ptr_mode are known to be
+ zero. */
+ if (POINTERS_EXTEND_UNSIGNED && GET_MODE (x) == Pmode
+ && (code == PLUS || code == MINUS)
+ && GET_CODE (XEXP (x, 0)) == REG && REG_POINTER (XEXP (x, 0)))
+ nonzero &= GET_MODE_MASK (ptr_mode);
+#endif
}
break;
@@ -8646,7 +8656,20 @@ num_sign_bit_copies (x, mode)
num0 = num_sign_bit_copies (XEXP (x, 0), mode);
num1 = num_sign_bit_copies (XEXP (x, 1), mode);
- return MAX (1, MIN (num0, num1) - 1);
+ result = MAX (1, MIN (num0, num1) - 1);
+
+#ifdef POINTERS_EXTEND_UNSIGNED
+ /* If pointers extend signed and this is an addition or subtraction
+ to a pointer in Pmode, all the bits above ptr_mode are known to be
+ sign bit copies. */
+ if (! POINTERS_EXTEND_UNSIGNED && GET_MODE (x) == Pmode
+ && (code == PLUS || code == MINUS)
+ && GET_CODE (XEXP (x, 0)) == REG && REG_POINTER (XEXP (x, 0)))
+ result = MAX ((GET_MODE_BITSIZE (Pmode)
+ - GET_MODE_BITSIZE (ptr_mode) + 1),
+ result);
+#endif
+ return result;
case MULT:
/* The number of bits of the product is the sum of the number of