https://gcc.gnu.org/bugzilla/show_bug.cgi?id=78904
--- Comment #7 from Segher Boessenkool <segher at gcc dot gnu.org> --- Ah, "high byte" registers are never a separate register in the i386 backend, I see. combine would need to combine four insns to arrive at your current pattern, but it doesn't try because it thinks they are too complex. If I change this code to count ZERO_EXTRACT in nshift as well, combine does try, but comes up with (set (zero_extract:SI (reg:SI 92 [ D.1801 ]) (const_int 8 [0x8]) (const_int 8 [0x8])) (subreg:SI (plus:QI (subreg:QI (zero_extract:SI (reg/v:SI 94 [ a ]) (const_int 8 [0x8]) (const_int 8 [0x8])) 0) (subreg:QI (zero_extract:SI (reg/v:SI 95 [ b ]) (const_int 8 [0x8]) (const_int 8 [0x8])) 0)) 0)) (so it does the plus as QImode).