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

Reply via email to