> Thanks for the comments. Patch is updated. > > diff --git a/gcc/combine.c b/gcc/combine.c > index 1808f97..2e865d7 100644 > --- a/gcc/combine.c > +++ b/gcc/combine.c > @@ -1603,6 +1603,28 @@ setup_incoming_promotions (rtx_insn *first) > } > } > > +/* Update RSP from INSN's REG_EQUAL note and SRC. */ > + > +static void > +update_rsp_from_reg_equal (reg_stat_type *rsp, rtx_insn *insn, rtx src, rtx > x) > +{ > + rtx reg_equal = insn ? find_reg_equal_equiv_note (insn) : NULL_RTX; > + unsigned HOST_WIDE_INT bits = nonzero_bits (src, nonzero_bits_mode);
Note that "src" has taken the SHORT_IMMEDIATES_SIGN_EXTEND path here. > + if (reg_equal) > + { > + unsigned int num = num_sign_bit_copies (XEXP (reg_equal, 0), > + GET_MODE (x)); > + bits &= nonzero_bits (XEXP (reg_equal, 0), nonzero_bits_mode); But XEXP (reg_equal, 0) hasn't here. If we want to treat the datum of the REG_EQUAL or REG_EQUIV note as equivalent to the SET_SRC (set), and I think we should (see for example combine.c:9650), there is a problem. So I think we should create a new function, something along of: /* If MODE has a precision lower than PREC and SRC is a non-negative constant that would appear negative in MODE, sign-extend SRC for use in nonzero_bits because some machines (maybe most) will actually do the sign-extension and this is the conservative approach. ??? For 2.5, try to tighten up the MD files in this regard instead of this kludge. */ rtx sign_extend_short_imm (rtx src, machine_mode mode, unsigned int prec) { if (GET_MODE_PRECISION (mode) < prec && CONST_INT_P (src) && INTVAL (src) > 0 && val_signbit_known_set_p (mode, INTVAL (src))) src = GEN_INT (INTVAL (src) | ~GET_MODE_MASK (mode)); return src; } and calls it from combine.c:1702 #ifdef SHORT_IMMEDIATES_SIGN_EXTEND src = sign_extend_short_imm (src, GET_MODE (x), BITS_PER_WORD); #endif and from combine.c:9650 #ifdef SHORT_IMMEDIATES_SIGN_EXTEND tem = sign_extend_short_imm (tem, GET_MODE (x), GET_MODE_PRECISION (mode)); #endif Once this is done, the same thing needs to be applied to XEXP (reg_equal, 0) before it is sent to nonzero_bits. > - /* Don't call nonzero_bits if it cannot change anything. */ > - if (rsp->nonzero_bits != ~(unsigned HOST_WIDE_INT) 0) > - rsp->nonzero_bits |= nonzero_bits (src, nonzero_bits_mode); > num = num_sign_bit_copies (SET_SRC (set), GET_MODE (x)); > if (rsp->sign_bit_copies == 0 > > || rsp->sign_bit_copies > num) > > rsp->sign_bit_copies = num; > + > + /* Don't call nonzero_bits if it cannot change anything. */ > + if (rsp->nonzero_bits != ~(unsigned HOST_WIDE_INT) 0) > + update_rsp_from_reg_equal (rsp, insn, src, x); Can't we improve on this? rsp->sign_bit_copies is modified both here and in update_rsp_from_reg_equal, but rsp->nonzero_bits is modified only in the latter function. There is no reason for this discrepancy, so they ought to be handled the same way, either entirely here or entirely in the function. -- Eric Botcazou