https://gcc.gnu.org/bugzilla/show_bug.cgi?id=109907
--- Comment #27 from Andrew Pinski <pinskia at gcc dot gnu.org> --- I should note the middle-end could also improve here: /* If we are comparing a double-word integer with zero or -1, we can convert the comparison into one involving a single word. */ if (is_int_mode (mode, &int_mode) && GET_MODE_BITSIZE (int_mode) == BITS_PER_WORD * 2 && (!MEM_P (op0) || ! MEM_VOLATILE_P (op0))) In the case of SImode, GET_MODE_BITSIZE is 32 while BITS_PER_WORD is just 8. We could use a loop (to generate the and/ior) if GET_MODE_BITSIZE (int_mode) is a (non-1) multiple of BITS_PER_WORD instead of the 1 expand_binop. But that is left for another person to do. That would also improve the comment #20 case too. Avr might be the only target which supports a mode size that is *4 of the BIT_PER_WORD fully.