For msp430-elf in the large memory model there are PSImode (20-bit) pointers. POINTERS_EXTEND_UNSIGNED == 1 and "char" is unsigned by default.
We get poor code generated for the following code snippet: const int table[2] = {1, 2}; int foo (char i) { return table[i]; } 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)) The zero extend is implicit with byte sized register operations, so this would result in assembly such as: MOV.B R12, R12 My question is whether this is the type of thing that should be handled with a peephole optimization or if it is worth trying to fix the initial RTL generated by expand (or in a later RTL pass e.g. combine)? Thanks, Jozef