On 9/23/19 5:56 AM, Jozef Lawrynowicz wrote: > 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)? Ideally it'd be fixed earlier, but that can be painful due to the way promotions work.
I certainly recall doing some combiner patterns to catch the more egregious codegen issues on the mn102 port (similar, but with 24bit pointers). I think I mostly focused on stuff that showed up with integer loop indices and their annoying promotion to ptrdiff_t when used for array indexing. I'd bet if you extracted mn10200.md out of the archive the patterns would be obvious ;-) In this specific case I'd think a combiner pattern ought to do the right thing except for the fact that you're probably dealing with hard registers which combine no longer handles as aggressively. jeff