https://gcc.gnu.org/bugzilla/show_bug.cgi?id=91865
Bug ID: 91865 Summary: Combine misses opportunity to remove (sign_extend (zero_extend)) before searching for insn patterns Product: gcc Version: 9.0 Status: UNCONFIRMED Severity: normal Priority: P3 Component: rtl-optimization Assignee: unassigned at gcc dot gnu.org Reporter: jozefl.gcc at gmail dot com Target Milestone: --- Created attachment 46913 --> https://gcc.gnu.org/bugzilla/attachment.cgi?id=46913&action=edit msp430-movqipsi.diff The following program generates poor code for msp430-elf in the large memory model: const int table[2] = {1, 2}; int foo (char i) { return table[i]; } > msp430-elf-gcc -S tester.i -mlarge -Os The RTL generated by expand uses two insns to convert "i" to a register's natural mode; there is a sign extension which would be unnecessary if the first instruction had a PSImode register as the lvalue: (insn 2 4 3 2 (set (reg/v:HI 25 [ i ]) (zero_extend:HI (reg:QI 12 R12 [ i ]))) (nil)) ..... (insn 7 6 8 2 (set (reg:PSI 28) (subreg:PSI (sign_extend:SI (reg/v:HI 25 [ i ])) 0)) (nil)) All we really need is: (insn (set (reg:PSI 28 [ i ]) (zero_extend:PSI (reg:QI 12 R12 [ i ]))) (nil)) Combine tries to combine the insns but doesn't recognize that the following transformation could be applied: (sign_extend:PSI (zero_extend:HI)) -> (zero_extend:PSI) Trying 2 -> 7: 2: r25:HI=zero_extend(R12:QI) REG_DEAD R12:QI 7: r28:PSI=sign_extend(r25:HI)#0 REG_DEAD r25:HI Failed to match this instruction: (set (reg:PSI 28 [ i ]) (sign_extend:PSI (zero_extend:HI (reg:QI 12 R12 [ i ])))) Failed to match this instruction: (set (reg:PSI 28 [ i ]) (sign_extend:PSI (and:HI (reg:HI 12 R12) (const_int 255 [0xff])))) A separate issue is that the movqipsi pattern is undefined, a patch containing the pattern is attached and would match if the above transformation were applied by combine.