> If the > (and:SI (subreg:SI (reg:HI xxx) 0) (const_int 0x84c)) > to > (subreg:SI (and:HI (reg:HI xxx) (const_int 0x84c)) 0) > transformation is kosher for WORD_REGISTER_OPERATIONS, then I guess the > invalid operation is then in > simplify_context::simplify_binary_operation_1 > case AND: > ... > if (HWI_COMPUTABLE_MODE_P (mode)) > { > HOST_WIDE_INT nzop0 = nonzero_bits (trueop0, mode); > HOST_WIDE_INT nzop1; > if (CONST_INT_P (trueop1)) > { > HOST_WIDE_INT val1 = INTVAL (trueop1); > /* If we are turning off bits already known off in OP0, we > need not do an AND. */ > if ((nzop0 & ~val1) == 0) > return op0; > } > We have there op0==trueop0 (reg:HI 175) and op1==trueop1 (const_int 2124 > [0x84c]). > We then for integral? modes smaller than word_mode would then need to > actually check nonzero_bits in the word_mode (on paradoxical subreg of > trueop0?). If INTVAL (trueop1) is >= 0, then I think just doing > nonzero_bits in the wider mode would be all we need (although the > subsequent (nzop1 & nzop0) == 0 case probably wants to have the current > nonzero_bits calls), not really sure what for WORD_REGISTER_OPERATIONS > means AND with a constant which has the most significant bit set for the > upper bits.
Yes, I agree that there is a tension between this AND case and the swapping done in the combiner for WORD_REGISTER_OPERATIONS. I also agree that it would make sense do call nonzero_bits on word_mode instead of mode here in this case because AND is a word_register_operation_p. > So, perhaps just in the return op0; case add further code for > WORD_REGISTER_OPERATIONS and sub-word modes which will call nonzero_bits > again for the word mode and decide if it is still safe. Does it work to just replace mode by word_mode in the calls to nonzero_bits? > That patch doesn't change anything at all on the testcase, it is still > miscompiled. OK, too bad, thanks for trying it! -- Eric Botcazou