https://gcc.gnu.org/bugzilla/show_bug.cgi?id=84071

--- Comment #5 from Wilco <wilco at gcc dot gnu.org> ---
(In reply to Eric Botcazou from comment #3)
> > PR59461 changed nonzero_bits1 incorrectly for subregs:
> > 
> >           /* On many CISC machines, accessing an object in a wider mode
> >              causes the high-order bits to become undefined.  So they are
> >              not known to be zero.  */
> >           rtx_code extend_op;
> >           if ((!WORD_REGISTER_OPERATIONS
> >                /* If this is a typical RISC machine, we only have to worry
> >                   about the way loads are extended.  */
> >                || ((extend_op = load_extend_op (inner_mode)) == SIGN_EXTEND
> >                    ? val_signbit_known_set_p (inner_mode, nonzero)
> >                    : extend_op != ZERO_EXTEND)
> >                || (!MEM_P (SUBREG_REG (x)) && !REG_P (SUBREG_REG (x))))
> >               && xmode_width > inner_width)
> >             nonzero
> >               |= (GET_MODE_MASK (GET_MODE (x)) & ~GET_MODE_MASK
> > (inner_mode));
> > 
> > If WORD_REGISTER_OPERATIONS is set and load_extend_op is ZERO_EXTEND, rtl
> > like
> > 
> > (subreg:SI (reg:HI 125) 0)
> > 
> > is assumed to be always zero-extended.
> 
> That's not what the code is supposed to do.  As explained in the comment,
> the code is intended to compute the nonzero bits of the subreg from the
> nonzero_bits of the inner reg:
> 
>         nonzero &= cached_nonzero_bits (SUBREG_REG (x), mode,
>                                         known_x, known_mode, known_ret);

That's based on the inner type alone and not correct for
WORD_REGISTER_OPERATIONS. The

nonzero |= (GET_MODE_MASK (GET_MODE (x)) & ~GET_MODE_MASK;

adds in the unknown bits for the wider type. And that's the bit that is no
longer triggering.

> > This is incorrect since modes that are smaller than WORD_MODE may contain
> > random top bits. This is equally true for RISC and CISC ISAs and 
> > independent 
> > of WORD_REGISTER_OPERATIONS, so it's unclear why the !REG_P check was added.
> 
> No, that's wrong, WORD_REGISTER_OPERATIONS precisely means that the bits up
> to the word are defined when operations operate in mode smaller than a word.

They are always written but have an undefined value. Adding 2 8-bit values
results in a 9-bit value with WORD_REGISTER_OPERATIONS.

Reply via email to