aboutsummaryrefslogtreecommitdiff
path: root/gcc/simplify-rtx.c
diff options
context:
space:
mode:
authorBernd Schmidt <bernds@codesourcery.com>2011-07-06 14:21:03 +0000
committerBernd Schmidt <bernds@gcc.gnu.org>2011-07-06 14:21:03 +0000
commit2d0c270fd266218ff040965bb8231729df9144f1 (patch)
tree2a2d891d415bcfdd26b794dc666ecd03b7565eee /gcc/simplify-rtx.c
parent6d6c952527c53637280297b2e6a48d6b21606294 (diff)
downloadgcc-2d0c270fd266218ff040965bb8231729df9144f1.zip
gcc-2d0c270fd266218ff040965bb8231729df9144f1.tar.gz
gcc-2d0c270fd266218ff040965bb8231729df9144f1.tar.bz2
cse.c (find_comparison_args): Use val_mode_signbit_set_p.
* cse.c (find_comparison_args): Use val_mode_signbit_set_p. * simplify-rtx.c (mode_signbit_p): Use GET_MODE_PRECISION. (val_mode_signbit_p, val_mode_signbit_set_p): New functions. (simplify_const_unary_operation, simplify_binary_operation_1, simplify_const_binary_operation, simplify_const_relational_operation): Use them. Use GET_MODE_MASK for masking and sign-extensions. * combine.c (set_nonzero_bits_and_sign_copies, simplify_set, combine_simplify_rtx, force_to_mode, reg_nonzero_bits_for_combine, simplify_shift_const_1, simplify_comparison): Likewise. * expr.c (convert_modes): Likewise. * rtlanal.c (nonzero_bits1, canonicalize_condition): Likewise. * expmed.c (emit_cstore, emit_store_flag_1, emit_store_flag): Likewise. * rtl.h (val_mode_signbit_p, val_mode_signbit_set_p): Declare. From-SVN: r175917
Diffstat (limited to 'gcc/simplify-rtx.c')
-rw-r--r--gcc/simplify-rtx.c118
1 files changed, 80 insertions, 38 deletions
diff --git a/gcc/simplify-rtx.c b/gcc/simplify-rtx.c
index f7669b1..6a5ec1a 100644
--- a/gcc/simplify-rtx.c
+++ b/gcc/simplify-rtx.c
@@ -82,7 +82,7 @@ mode_signbit_p (enum machine_mode mode, const_rtx x)
if (GET_MODE_CLASS (mode) != MODE_INT)
return false;
- width = GET_MODE_BITSIZE (mode);
+ width = GET_MODE_PRECISION (mode);
if (width == 0)
return false;
@@ -103,6 +103,62 @@ mode_signbit_p (enum machine_mode mode, const_rtx x)
val &= ((unsigned HOST_WIDE_INT) 1 << width) - 1;
return val == ((unsigned HOST_WIDE_INT) 1 << (width - 1));
}
+
+/* Test whether VAL is equal to the most significant bit of mode MODE
+ (after masking with the mode mask of MODE). Returns false if the
+ precision of MODE is too large to handle. */
+
+bool
+val_signbit_p (enum machine_mode mode, unsigned HOST_WIDE_INT val)
+{
+ unsigned int width;
+
+ if (GET_MODE_CLASS (mode) != MODE_INT)
+ return false;
+
+ width = GET_MODE_PRECISION (mode);
+ if (width == 0 || width > HOST_BITS_PER_WIDE_INT)
+ return false;
+
+ val &= GET_MODE_MASK (mode);
+ return val == ((unsigned HOST_WIDE_INT) 1 << (width - 1));
+}
+
+/* Test whether the most significant bit of mode MODE is set in VAL.
+ Returns false if the precision of MODE is too large to handle. */
+bool
+val_signbit_known_set_p (enum machine_mode mode, unsigned HOST_WIDE_INT val)
+{
+ unsigned int width;
+
+ if (GET_MODE_CLASS (mode) != MODE_INT)
+ return false;
+
+ width = GET_MODE_PRECISION (mode);
+ if (width == 0 || width > HOST_BITS_PER_WIDE_INT)
+ return false;
+
+ val &= (unsigned HOST_WIDE_INT) 1 << (width - 1);
+ return val != 0;
+}
+
+/* Test whether the most significant bit of mode MODE is clear in VAL.
+ Returns false if the precision of MODE is too large to handle. */
+bool
+val_signbit_known_clear_p (enum machine_mode mode, unsigned HOST_WIDE_INT val)
+{
+ unsigned int width;
+
+ if (GET_MODE_CLASS (mode) != MODE_INT)
+ return false;
+
+ width = GET_MODE_PRECISION (mode);
+ if (width == 0 || width > HOST_BITS_PER_WIDE_INT)
+ return false;
+
+ val &= (unsigned HOST_WIDE_INT) 1 << (width - 1);
+ return val == 0;
+}
/* Make a binary operation by properly ordering the operands and
seeing if the expression folds. */
@@ -908,12 +964,8 @@ simplify_unary_operation_1 (enum rtx_code code, enum machine_mode mode, rtx op)
/* If operand is something known to be positive, ignore the ABS. */
if (GET_CODE (op) == FFS || GET_CODE (op) == ABS
- || ((GET_MODE_BITSIZE (GET_MODE (op))
- <= HOST_BITS_PER_WIDE_INT)
- && ((nonzero_bits (op, GET_MODE (op))
- & ((unsigned HOST_WIDE_INT) 1
- << (GET_MODE_BITSIZE (GET_MODE (op)) - 1)))
- == 0)))
+ || val_signbit_known_clear_p (GET_MODE (op),
+ nonzero_bits (op, GET_MODE (op))))
return op;
/* If operand is known to be only -1 or 0, convert ABS to NEG. */
@@ -1425,8 +1477,7 @@ simplify_const_unary_operation (enum rtx_code code, enum machine_mode mode,
val = arg0;
}
else if (GET_MODE_BITSIZE (op_mode) < HOST_BITS_PER_WIDE_INT)
- val = arg0 & ~((unsigned HOST_WIDE_INT) (-1)
- << GET_MODE_BITSIZE (op_mode));
+ val = arg0 & GET_MODE_MASK (op_mode);
else
return 0;
break;
@@ -1444,13 +1495,9 @@ simplify_const_unary_operation (enum rtx_code code, enum machine_mode mode,
}
else if (GET_MODE_BITSIZE (op_mode) < HOST_BITS_PER_WIDE_INT)
{
- val
- = arg0 & ~((unsigned HOST_WIDE_INT) (-1)
- << GET_MODE_BITSIZE (op_mode));
- if (val & ((unsigned HOST_WIDE_INT) 1
- << (GET_MODE_BITSIZE (op_mode) - 1)))
- val
- -= (unsigned HOST_WIDE_INT) 1 << GET_MODE_BITSIZE (op_mode);
+ val = arg0 & GET_MODE_MASK (op_mode);
+ if (val_signbit_known_set_p (op_mode, val))
+ val |= ~GET_MODE_MASK (op_mode);
}
else
return 0;
@@ -1602,10 +1649,8 @@ simplify_const_unary_operation (enum rtx_code code, enum machine_mode mode,
else
{
lv = l1 & GET_MODE_MASK (op_mode);
- if (GET_MODE_BITSIZE (op_mode) < HOST_BITS_PER_WIDE_INT
- && (lv & ((unsigned HOST_WIDE_INT) 1
- << (GET_MODE_BITSIZE (op_mode) - 1))) != 0)
- lv -= (unsigned HOST_WIDE_INT) 1 << GET_MODE_BITSIZE (op_mode);
+ if (val_signbit_known_set_p (op_mode, lv))
+ lv |= ~GET_MODE_MASK (op_mode);
hv = HWI_SIGN_EXTEND (lv);
}
@@ -2663,9 +2708,7 @@ simplify_binary_operation_1 (enum rtx_code code, enum machine_mode mode,
/* (xor (comparison foo bar) (const_int sign-bit))
when STORE_FLAG_VALUE is the sign bit. */
- if (GET_MODE_BITSIZE (mode) <= HOST_BITS_PER_WIDE_INT
- && ((STORE_FLAG_VALUE & GET_MODE_MASK (mode))
- == (unsigned HOST_WIDE_INT) 1 << (GET_MODE_BITSIZE (mode) - 1))
+ if (val_signbit_p (mode, STORE_FLAG_VALUE)
&& trueop1 == const_true_rtx
&& COMPARISON_P (op0)
&& (reversed = reversed_comparison (op0, mode)))
@@ -3028,8 +3071,7 @@ simplify_binary_operation_1 (enum rtx_code code, enum machine_mode mode,
case SMIN:
if (width <= HOST_BITS_PER_WIDE_INT
- && CONST_INT_P (trueop1)
- && UINTVAL (trueop1) == (unsigned HOST_WIDE_INT) 1 << (width -1)
+ && mode_signbit_p (mode, trueop1)
&& ! side_effects_p (op0))
return op1;
if (rtx_equal_p (trueop0, trueop1) && ! side_effects_p (op0))
@@ -3634,16 +3676,16 @@ simplify_const_binary_operation (enum rtx_code code, enum machine_mode mode,
if (width < HOST_BITS_PER_WIDE_INT)
{
- arg0 &= ((unsigned HOST_WIDE_INT) 1 << width) - 1;
- arg1 &= ((unsigned HOST_WIDE_INT) 1 << width) - 1;
+ arg0 &= GET_MODE_MASK (mode);
+ arg1 &= GET_MODE_MASK (mode);
arg0s = arg0;
- if (arg0s & ((unsigned HOST_WIDE_INT) 1 << (width - 1)))
- arg0s |= ((unsigned HOST_WIDE_INT) (-1) << width);
+ if (val_signbit_known_set_p (mode, arg0s))
+ arg0s |= ~GET_MODE_MASK (mode);
- arg1s = arg1;
- if (arg1s & ((unsigned HOST_WIDE_INT) 1 << (width - 1)))
- arg1s |= ((unsigned HOST_WIDE_INT) (-1) << width);
+ arg1s = arg1;
+ if (val_signbit_known_set_p (mode, arg1s))
+ arg1s |= ~GET_MODE_MASK (mode);
}
else
{
@@ -4616,14 +4658,14 @@ simplify_const_relational_operation (enum rtx_code code,
we have to sign or zero-extend the values. */
if (width != 0 && width < HOST_BITS_PER_WIDE_INT)
{
- l0u &= ((unsigned HOST_WIDE_INT) 1 << width) - 1;
- l1u &= ((unsigned HOST_WIDE_INT) 1 << width) - 1;
+ l0u &= GET_MODE_MASK (mode);
+ l1u &= GET_MODE_MASK (mode);
- if (l0s & ((unsigned HOST_WIDE_INT) 1 << (width - 1)))
- l0s |= ((unsigned HOST_WIDE_INT) (-1) << width);
+ if (val_signbit_known_set_p (mode, l0s))
+ l0s |= ~GET_MODE_MASK (mode);
- if (l1s & ((unsigned HOST_WIDE_INT) 1 << (width - 1)))
- l1s |= ((unsigned HOST_WIDE_INT) (-1) << width);
+ if (val_signbit_known_set_p (mode, l1s))
+ l1s |= ~GET_MODE_MASK (mode);
}
if (width != 0 && width <= HOST_BITS_PER_WIDE_INT)
h0u = h1u = 0, h0s = HWI_SIGN_EXTEND (l0s), h1s = HWI_SIGN_EXTEND (l1s);