http://gcc.gnu.org/bugzilla/show_bug.cgi?id=53987
--- Comment #2 from Oleg Endo <olegendo at gcc dot gnu.org> --- As of rev 204180 (4.9) this problem still exists. As far as I understand, the actual root of the problem is that the 'unsigned char' mem loads into regs are neither sign nor zero extended. So combine sees the following: (insn 11 6 12 2 (set (reg:QI 169 [ *a_3(D) ]) (mem:QI (reg:SI 4 r4 [ a ]) [0 *a_3(D)+0 S1 A8])) {*movqi} (expr_list:REG_DEAD (reg:SI 4 r4 [ a ]) (nil))) (insn 12 11 13 2 (set (reg:SI 168 [ *a_3(D)+-3 ]) (zero_extend:SI (reg:QI 169 [ *a_3(D) ]))) {*zero_extendqisi2_compact} (expr_list:REG_DEAD (reg:QI 169 [ *a_3(D) ]) (nil))) (insn 13 12 14 2 (set (reg:QI 171 [ *b_5(D) ]) (mem:QI (reg:SI 5 r5 [ b ]) [0 *b_5(D)+0 S1 A8])) {*movqi} (expr_list:REG_DEAD (reg:SI 5 r5 [ b ]) (nil))) (insn 14 13 15 2 (set (reg:SI 170 [ *b_5(D)+-3 ]) (zero_extend:SI (reg:QI 171 [ *b_5(D) ]))) {*zero_extendqisi2_compact} (expr_list:REG_DEAD (reg:QI 171 [ *b_5(D) ]) (nil))) (insn 15 14 16 2 (set (reg:SI 147 t) (eq:SI (reg:SI 168 [ *a_3(D)+-3 ]) (reg:SI 170 [ *b_5(D)+-3 ]))) {cmpeqsi_t} (expr_list:REG_DEAD (reg:SI 170 [ *b_5(D)+-3 ]) (expr_list:REG_DEAD (reg:SI 168 [ *a_3(D)+-3 ]) (nil)))) On the other hand, signed char mem loads are expanded as sign extending. Since LOAD_EXTEND_OP tells that any mem loads but SImode are sign extending, one could expect that all mem loads will be automatically expanded as such, which is not the case.