We have a function mode_signbit_p, which tests whether a given rtx is equal to the sign bit of a given mode. This patch adds some similar helper functions and uses them to simplify tests. Also, in some instances of zero- and sign-extending, I've changed some bit shifting to uses of GET_MODE_MASK.
Bernd
* 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. Index: gcc/cse.c =================================================================== --- gcc/cse.c.orig +++ gcc/cse.c @@ -3063,12 +3063,8 @@ find_comparison_args (enum rtx_code code for STORE_FLAG_VALUE, also look at LT and GE operations. */ || ((code == NE || (code == LT - && GET_MODE_CLASS (inner_mode) == MODE_INT - && (GET_MODE_BITSIZE (inner_mode) - <= HOST_BITS_PER_WIDE_INT) - && (STORE_FLAG_VALUE - & ((HOST_WIDE_INT) 1 - << (GET_MODE_BITSIZE (inner_mode) - 1)))) + && val_signbit_known_set_p (inner_mode, + STORE_FLAG_VALUE)) #ifdef FLOAT_STORE_FLAG_VALUE || (code == LT && SCALAR_FLOAT_MODE_P (inner_mode) @@ -3083,12 +3079,8 @@ find_comparison_args (enum rtx_code code } else if ((code == EQ || (code == GE - && GET_MODE_CLASS (inner_mode) == MODE_INT - && (GET_MODE_BITSIZE (inner_mode) - <= HOST_BITS_PER_WIDE_INT) - && (STORE_FLAG_VALUE - & ((HOST_WIDE_INT) 1 - << (GET_MODE_BITSIZE (inner_mode) - 1)))) + && val_signbit_known_set_p (inner_mode, + STORE_FLAG_VALUE)) #ifdef FLOAT_STORE_FLAG_VALUE || (code == GE && SCALAR_FLOAT_MODE_P (inner_mode) Index: gcc/simplify-rtx.c =================================================================== --- gcc/simplify-rtx.c.orig +++ gcc/simplify-rtx.c @@ -82,7 +82,7 @@ mode_signbit_p (enum machine_mode mode, 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, 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_cod /* 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 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 } 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 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); } @@ -2641,9 +2686,7 @@ simplify_binary_operation_1 (enum rtx_co /* (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))) @@ -3006,8 +3049,7 @@ simplify_binary_operation_1 (enum rtx_co 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)) @@ -3612,16 +3654,16 @@ simplify_const_binary_operation (enum rt 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 { @@ -4594,14 +4636,14 @@ simplify_const_relational_operation (enu 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); Index: gcc/rtl.h =================================================================== --- gcc/rtl.h.orig +++ gcc/rtl.h @@ -1816,6 +1816,11 @@ extern rtx simplify_rtx (const_rtx); extern rtx avoid_constant_pool_reference (rtx); extern rtx delegitimize_mem_from_attrs (rtx); extern bool mode_signbit_p (enum machine_mode, const_rtx); +extern bool val_signbit_p (enum machine_mode, unsigned HOST_WIDE_INT); +extern bool val_signbit_known_set_p (enum machine_mode, + unsigned HOST_WIDE_INT); +extern bool val_signbit_known_clear_p (enum machine_mode, + unsigned HOST_WIDE_INT); /* In reginfo.c */ extern enum machine_mode choose_hard_reg_mode (unsigned int, unsigned int, Index: gcc/combine.c =================================================================== --- gcc/combine.c.orig +++ gcc/combine.c @@ -1627,15 +1627,11 @@ set_nonzero_bits_and_sign_copies (rtx x, ??? For 2.5, try to tighten up the MD files in this regard instead of this kludge. */ - if (GET_MODE_BITSIZE (GET_MODE (x)) < BITS_PER_WORD + if (GET_MODE_PRECISION (GET_MODE (x)) < BITS_PER_WORD && CONST_INT_P (src) && INTVAL (src) > 0 - && 0 != (UINTVAL (src) - & ((unsigned HOST_WIDE_INT) 1 - << (GET_MODE_BITSIZE (GET_MODE (x)) - 1)))) - src = GEN_INT (UINTVAL (src) - | ((unsigned HOST_WIDE_INT) (-1) - << GET_MODE_BITSIZE (GET_MODE (x)))); + && val_signbit_known_set_p (GET_MODE (x), INTVAL (src))) + src = GEN_INT (INTVAL (src) | ~GET_MODE_MASK (GET_MODE (x))); #endif /* Don't call nonzero_bits if it cannot change anything. */ @@ -5882,8 +5878,7 @@ combine_simplify_rtx (rtx x, enum machin going to test the sign bit. */ if (new_code == NE && GET_MODE_CLASS (mode) == MODE_INT && 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)) + && val_signbit_p (mode, STORE_FLAG_VALUE) && op1 == const0_rtx && mode == GET_MODE (op0) && (i = exact_log2 (nonzero_bits (op0, mode))) >= 0) @@ -6546,10 +6541,8 @@ simplify_set (rtx x) enum machine_mode inner_mode = GET_MODE (inner); /* Here we make sure that we don't have a sign bit on. */ - if (GET_MODE_BITSIZE (inner_mode) <= HOST_BITS_PER_WIDE_INT - && (nonzero_bits (inner, inner_mode) - < ((unsigned HOST_WIDE_INT) 1 - << (GET_MODE_BITSIZE (GET_MODE (src)) - 1)))) + if (val_signbit_known_clear_p (GET_MODE (src), + nonzero_bits (inner, inner_mode))) { SUBST (SET_SRC (x), inner); src = SET_SRC (x); @@ -8440,9 +8433,7 @@ force_to_mode (rtx x, enum machine_mode case ASHIFTRT: /* If we are just looking for the sign bit, we don't need this shift at all, even if it has a variable count. */ - if (GET_MODE_BITSIZE (GET_MODE (x)) <= HOST_BITS_PER_WIDE_INT - && (mask == ((unsigned HOST_WIDE_INT) 1 - << (GET_MODE_BITSIZE (GET_MODE (x)) - 1)))) + if (val_signbit_p (GET_MODE (x), mask)) return force_to_mode (XEXP (x, 0), mode, mask, next_select); /* If this is a shift by a constant, get a mask that contains those bits @@ -9584,15 +9575,11 @@ reg_nonzero_bits_for_combine (const_rtx ??? For 2.5, try to tighten up the MD files in this regard instead of this kludge. */ - if (GET_MODE_BITSIZE (GET_MODE (x)) < GET_MODE_BITSIZE (mode) + if (GET_MODE_PRECISION (GET_MODE (x)) < GET_MODE_PRECISION (mode) && CONST_INT_P (tem) && INTVAL (tem) > 0 - && 0 != (UINTVAL (tem) - & ((unsigned HOST_WIDE_INT) 1 - << (GET_MODE_BITSIZE (GET_MODE (x)) - 1)))) - tem = GEN_INT (UINTVAL (tem) - | ((unsigned HOST_WIDE_INT) (-1) - << GET_MODE_BITSIZE (GET_MODE (x)))); + && val_signbit_known_set_p (GET_MODE (x), INTVAL (tem))) + tem = GEN_INT (INTVAL (tem) | ~GET_MODE_MASK (GET_MODE (x))); #endif return tem; } @@ -9982,11 +9969,9 @@ simplify_shift_const_1 (enum rtx_code co ASHIFTRT to LSHIFTRT if we know the sign bit is clear. `make_compound_operation' will convert it to an ASHIFTRT for those machines (such as VAX) that don't have an LSHIFTRT. */ - if (GET_MODE_BITSIZE (shift_mode) <= HOST_BITS_PER_WIDE_INT - && code == ASHIFTRT - && ((nonzero_bits (varop, shift_mode) - & ((unsigned HOST_WIDE_INT) 1 - << (GET_MODE_BITSIZE (shift_mode) - 1))) == 0)) + if (code == ASHIFTRT + && val_signbit_known_clear_p (shift_mode, + nonzero_bits (varop, shift_mode))) code = LSHIFTRT; if (((code == LSHIFTRT @@ -11419,10 +11404,7 @@ simplify_comparison (enum rtx_code code, mode = GET_MODE (XEXP (op0, 0)); if (mode != VOIDmode && GET_MODE_CLASS (mode) == MODE_INT && ! unsigned_comparison_p - && (GET_MODE_BITSIZE (mode) <= HOST_BITS_PER_WIDE_INT) - && ((unsigned HOST_WIDE_INT) const_op - < (((unsigned HOST_WIDE_INT) 1 - << (GET_MODE_BITSIZE (mode) - 1)))) + && val_signbit_known_clear_p (mode, const_op) && have_insn_for (COMPARE, mode)) { op0 = XEXP (op0, 0); @@ -11609,11 +11591,7 @@ simplify_comparison (enum rtx_code code, /* Check for the cases where we simply want the result of the earlier test or the opposite of that result. */ if (code == NE || code == EQ - || (GET_MODE_BITSIZE (GET_MODE (op0)) <= HOST_BITS_PER_WIDE_INT - && GET_MODE_CLASS (GET_MODE (op0)) == MODE_INT - && (STORE_FLAG_VALUE - & (((unsigned HOST_WIDE_INT) 1 - << (GET_MODE_BITSIZE (GET_MODE (op0)) - 1)))) + || (val_signbit_known_set_p (GET_MODE (op0), STORE_FLAG_VALUE) && (code == LT || code == GE))) { enum rtx_code new_code; Index: gcc/expr.c =================================================================== --- gcc/expr.c.orig +++ gcc/expr.c @@ -764,14 +764,13 @@ convert_modes (enum machine_mode mode, e && GET_MODE_SIZE (mode) > GET_MODE_SIZE (oldmode)) { HOST_WIDE_INT val = INTVAL (x); - int width = GET_MODE_BITSIZE (oldmode); /* We must sign or zero-extend in this case. Start by zero-extending, then sign extend if we need to. */ - val &= ((HOST_WIDE_INT) 1 << width) - 1; + val &= GET_MODE_MASK (oldmode); if (! unsignedp - && (val & ((HOST_WIDE_INT) 1 << (width - 1)))) - val |= (HOST_WIDE_INT) (-1) << width; + && val_signbit_known_set_p (oldmode, val)) + val |= ~GET_MODE_MASK (oldmode); return gen_int_mode (val, mode); } Index: gcc/rtlanal.c =================================================================== --- gcc/rtlanal.c.orig +++ gcc/rtlanal.c @@ -3849,6 +3849,7 @@ nonzero_bits1 (const_rtx x, enum machine unsigned HOST_WIDE_INT nonzero = GET_MODE_MASK (mode); unsigned HOST_WIDE_INT inner_nz; enum rtx_code code; + enum machine_mode inner_mode; unsigned int mode_width = GET_MODE_BITSIZE (mode); /* For floating-point and vector values, assume all bits are needed. */ @@ -4028,9 +4029,7 @@ nonzero_bits1 (const_rtx x, enum machine if (GET_MODE (XEXP (x, 0)) != VOIDmode) { inner_nz &= GET_MODE_MASK (GET_MODE (XEXP (x, 0))); - if (inner_nz - & (((unsigned HOST_WIDE_INT) 1 - << (GET_MODE_BITSIZE (GET_MODE (XEXP (x, 0))) - 1)))) + if (val_signbit_known_set_p (GET_MODE (XEXP (x, 0)), inner_nz)) inner_nz |= (GET_MODE_MASK (mode) & ~GET_MODE_MASK (GET_MODE (XEXP (x, 0)))); } @@ -4153,12 +4152,12 @@ nonzero_bits1 (const_rtx x, enum machine & cached_nonzero_bits (SUBREG_REG (x), GET_MODE (x), known_x, known_mode, known_ret); + inner_mode = GET_MODE (SUBREG_REG (x)); /* If the inner mode is a single word for both the host and target machines, we can compute this from which bits of the inner object might be nonzero. */ - if (GET_MODE_BITSIZE (GET_MODE (SUBREG_REG (x))) <= BITS_PER_WORD - && (GET_MODE_BITSIZE (GET_MODE (SUBREG_REG (x))) - <= HOST_BITS_PER_WIDE_INT)) + if (GET_MODE_BITSIZE (inner_mode) <= BITS_PER_WORD + && (GET_MODE_BITSIZE (inner_mode) <= HOST_BITS_PER_WIDE_INT)) { nonzero &= cached_nonzero_bits (SUBREG_REG (x), mode, known_x, known_mode, known_ret); @@ -4166,12 +4165,9 @@ nonzero_bits1 (const_rtx x, enum machine #if defined (WORD_REGISTER_OPERATIONS) && defined (LOAD_EXTEND_OP) /* If this is a typical RISC machine, we only have to worry about the way loads are extended. */ - if ((LOAD_EXTEND_OP (GET_MODE (SUBREG_REG (x))) == SIGN_EXTEND - ? (((nonzero - & (((unsigned HOST_WIDE_INT) 1 - << (GET_MODE_BITSIZE (GET_MODE (SUBREG_REG (x))) - 1)))) - != 0)) - : LOAD_EXTEND_OP (GET_MODE (SUBREG_REG (x))) != ZERO_EXTEND) + if ((LOAD_EXTEND_OP (inner_mode) == SIGN_EXTEND + ? val_signbit_known_set_p (inner_mode, nonzero) + : LOAD_EXTEND_OP (inner_mode) != ZERO_EXTEND) || !MEM_P (SUBREG_REG (x))) #endif { @@ -4179,9 +4175,9 @@ nonzero_bits1 (const_rtx x, enum machine causes the high-order bits to become undefined. So they are not known to be zero. */ if (GET_MODE_SIZE (GET_MODE (x)) - > GET_MODE_SIZE (GET_MODE (SUBREG_REG (x)))) + > GET_MODE_SIZE (inner_mode)) nonzero |= (GET_MODE_MASK (GET_MODE (x)) - & ~GET_MODE_MASK (GET_MODE (SUBREG_REG (x)))); + & ~GET_MODE_MASK (inner_mode)); } } break; @@ -4921,12 +4917,8 @@ canonicalize_condition (rtx insn, rtx co if ((GET_CODE (SET_SRC (set)) == COMPARE || (((code == NE || (code == LT - && GET_MODE_CLASS (inner_mode) == MODE_INT - && (GET_MODE_BITSIZE (inner_mode) - <= HOST_BITS_PER_WIDE_INT) - && (STORE_FLAG_VALUE - & ((unsigned HOST_WIDE_INT) 1 - << (GET_MODE_BITSIZE (inner_mode) - 1)))) + && val_signbit_known_set_p (inner_mode, + STORE_FLAG_VALUE)) #ifdef FLOAT_STORE_FLAG_VALUE || (code == LT && SCALAR_FLOAT_MODE_P (inner_mode) @@ -4941,12 +4933,8 @@ canonicalize_condition (rtx insn, rtx co x = SET_SRC (set); else if (((code == EQ || (code == GE - && (GET_MODE_BITSIZE (inner_mode) - <= HOST_BITS_PER_WIDE_INT) - && GET_MODE_CLASS (inner_mode) == MODE_INT - && (STORE_FLAG_VALUE - & ((unsigned HOST_WIDE_INT) 1 - << (GET_MODE_BITSIZE (inner_mode) - 1)))) + && val_signbit_known_set_p (inner_mode, + STORE_FLAG_VALUE)) #ifdef FLOAT_STORE_FLAG_VALUE || (code == GE && SCALAR_FLOAT_MODE_P (inner_mode) Index: gcc/expmed.c =================================================================== --- gcc/expmed.c.orig +++ gcc/expmed.c @@ -5039,10 +5039,8 @@ emit_cstore (rtx target, enum insn_code if (GET_MODE_SIZE (target_mode) > GET_MODE_SIZE (result_mode)) { convert_move (target, subtarget, - (GET_MODE_BITSIZE (result_mode) <= HOST_BITS_PER_WIDE_INT) - && 0 == (STORE_FLAG_VALUE - & ((HOST_WIDE_INT) 1 - << (GET_MODE_BITSIZE (result_mode) -1)))); + val_signbit_known_clear_p (result_mode, + STORE_FLAG_VALUE)); op0 = target; result_mode = target_mode; } @@ -5066,9 +5064,7 @@ emit_cstore (rtx target, enum insn_code /* We don't want to use STORE_FLAG_VALUE < 0 below since this makes it hard to use a value of just the sign bit due to ANSI integer constant typing rules. */ - else if (GET_MODE_BITSIZE (result_mode) <= HOST_BITS_PER_WIDE_INT - && (STORE_FLAG_VALUE - & ((HOST_WIDE_INT) 1 << (GET_MODE_BITSIZE (result_mode) - 1)))) + else if (val_signbit_known_set_p (result_mode, STORE_FLAG_VALUE)) op0 = expand_shift (RSHIFT_EXPR, result_mode, op0, GET_MODE_BITSIZE (result_mode) - 1, subtarget, normalizep == 1); @@ -5206,9 +5202,9 @@ emit_store_flag_1 (rtx target, enum rtx_ target = gen_reg_rtx (target_mode); convert_move (target, tem, - 0 == ((normalizep ? normalizep : STORE_FLAG_VALUE) - & ((HOST_WIDE_INT) 1 - << (GET_MODE_BITSIZE (word_mode) -1)))); + !val_signbit_known_set_p (word_mode, + (normalizep ? normalizep + : STORE_FLAG_VALUE))); return target; } } @@ -5218,10 +5214,7 @@ emit_store_flag_1 (rtx target, enum rtx_ if (op1 == const0_rtx && (code == LT || code == GE) && GET_MODE_CLASS (mode) == MODE_INT && (normalizep || STORE_FLAG_VALUE == 1 - || (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)))))) + || val_signbit_p (mode, STORE_FLAG_VALUE))) { subtarget = target; @@ -5330,9 +5323,7 @@ emit_store_flag (rtx target, enum rtx_co if (STORE_FLAG_VALUE == 1 || STORE_FLAG_VALUE == -1) normalizep = STORE_FLAG_VALUE; - else 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))) + else if (val_signbit_p (mode, STORE_FLAG_VALUE)) ; else return 0;