> 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

Reply via email to