https://gcc.gnu.org/bugzilla/show_bug.cgi?id=65857
Bug ID: 65857 Summary: combine won't generate zero-extend from HImode memory Product: gcc Version: 6.0 Status: UNCONFIRMED Severity: normal Priority: P3 Component: rtl-optimization Assignee: unassigned at gcc dot gnu.org Reporter: ubizjak at gmail dot com Target: x86 Following testcase: --cut here-- extern unsigned char *a; int test (void) { return (unsigned char) a[0] | (unsigned char) a[1] << 8; } --cut here-- compiles (-O2 )nicely to: movq a(%rip), %rax movzwl (%rax), %eax ret However, combine will not combine HImode load with zero-extend: (insn 5 2 6 2 (set (reg/f:DI 92 [ a ]) (mem/f/c:DI (symbol_ref:DI ("a") [flags 0x40] <var_decl 0x2b006b8dfc60 a>) [1 a+0 S8 A64])) 85 {*movdi_internal} (nil)) (insn 6 5 11 2 (set (reg:SI 91 [ D.1849 ]) (zero_extend:SI (mem:HI (reg/f:DI 92 [ a ]) [0 MEM[(unsigned char *)_2]+0 S2 A8]))) ins.c:5 135 {*zero_extendhisi2} (expr_list:REG_DEAD (reg/f:DI 92 [ a ]) (nil))) It just chickens out with: Trying 5 -> 6: Failed to match this instruction: (set (reg:SI 91 [ D.1849 ]) (zero_extend:SI (mem:HI (mem/f/c:DI (symbol_ref:DI ("a") [flags 0x40] <var_decl 0x2b006b8dfc60 a>) [1 a+0 S8 A64]) [0 MEM[(unsigned char *)_2]+0 S2 A 8]))) Come on, combine ... the pattern is defined as: (define_insn "*zero_extend<mode>si2" [(set (match_operand:SI 0 "register_operand" "=r") (zero_extend:SI (match_operand:SWI12 1 "nonimmediate_operand" "<r>m")))] "!(TARGET_ZERO_EXTEND_WITH_AND && optimize_function_for_speed_p (cfun))" "movz{<imodesuffix>l|x}\t{%1, %0|%0, %1}" [(set_attr "type" "imovx") (set_attr "mode" "SI")])