On 10/29/2013 09:43 AM, Matthew Fortune wrote: > Hi Richard/Vladimir, > > I believe I finally understand one of the issues with LRA and mips16 but I > can't see how to solve it. Take the following instruction: > > (insn 5 18 6 2 (set (reg:SI 4 $4) > (plus:SI (reg/f:SI 78 $frame) > (const_int 16 [0x10]))) test.c:6 13 {*addsi3_mips16} > (nil)) > > $frame will be eliminated to either $sp or the hard frame pointer, which for > mips16 is $17. The problem here is that there is no single alternative that > accepts either $sp or $17 because the supported immediate range is different > for $sp(ks) and $17(d). The "ks" alternative is disregarded (presumably > because there is no way to reload into $sp if that ended up being necessary) > and instead the "d" alternative is chosen. If the frame pointer is needed > then this works well because $17 is used and fits the "d" constraint however > when the frame pointer is omitted $sp has to be reloaded into a "d" register > even though there is another alternative which it would directly match. > > The fragment of the reload dump: > > 1 Matching alt: reject+=2 > 1 Non-pseudo reload: reject+=2 > alt=4,overall=10,losers=1,rld_nregs=1 > 1 Matching alt: reject+=2 > 1 Non-pseudo reload: reject+=2 > alt=5,overall=10,losers=1,rld_nregs=1 > 1 Non-pseudo reload: reject+=2 > 1 Non-pseudo reload: reject+=2 > alt=7,overall=8,losers=1,rld_nregs=1 > 1 Non-pseudo reload: reject+=2 > 2 Non-pseudo reload: reject+=2 > 2 Non input pseudo reload: reject++ > alt=8,overall=17,losers=2 -- refuse > Choosing alt 7 in insn 5: (0) d (1) d (2) O {*addsi3_mips16} > Creating newreg=198 from oldreg=78, assigning class M16_REGS to r198 > > And the end result is: > > (insn 20 18 5 2 (set (reg/f:SI 2 $2 [198]) > (reg/f:SI 29 $sp)) test.c:6 290 {*movsi_mips16} > (nil)) > (insn 5 20 6 2 (set (reg:SI 4 $4) > (plus:SI (reg/f:SI 2 $2 [198]) > (const_int 16 [0x10]))) test.c:6 13 {*addsi3_mips16} > (nil)) > > The only way I can currently see to get any direct usage of $sp in an add > instruction would be to artificially reduce the permitted immediate range by > 1 bit so that there is a single alternative that allows either "ks" or "d" > with a 15bit immediate. I don't really want to do that though. I initially > allowed $frame to be treated as per $sp but that led to an ICE when $frame > was eliminated to $17 and the immediate was out of range. > > Have I missed anything that would allow me to support the full immediate > range in all cases? Sorry, I can not reproduce this using a test from PR58461 and patch enabling LRA for mips.
It is hard for me to say what is going on. Elimination is done when we match hard reg against constraints. May be elimination to hfp is rejected on some sub-pass and LRA don't try all alternatives after this. Could you send me the test from which you got this dumps and what options did you use. I can say more. As I understand there should be no such problem. If reload can do right think, LRA should do the same. >