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.