https://gcc.gnu.org/bugzilla/show_bug.cgi?id=84071
--- Comment #15 from Wilco <wilco at gcc dot gnu.org> --- (In reply to Eric Botcazou from comment #10) > > The addition is performed on the full 32-bit register, so this obviously > > means that the top 24 bits have an undefined value. > > Not if the entire registers have a defined value before the addition. The > point of WORD_REGISTER_OPERATIONS is the following: you have a pair of > SImode registers with known values and you do a QImode addition on them. If > the macro is defined, then the compiler considers that the result has a > defined value in SImode. That's the best description of WORD_REGISTER_OPERATIONS I've seen - maybe we should fix the docs to be clearer? Also I wonder whether this means AArch64 should set it since targets like MIPS and Sparc already set it. > In any case, that's not really the issue here and I'll just fix the combiner. Thanks for fixing this. I'm still not convinced that the logic of this is right: 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) So assuming WORD_REGISTER_OPERATIONS and load_extend_op is ZERO_EXTEND, we fall into the (!MEM_P (SUBREG_REG (x)) && !REG_P (SUBREG_REG (x))). But that effectively means that load_extend_op applies to REG_P as well as MEM_P, which can't be right...