> 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.
I'm afraid the patch in the bug report includes some incorrect workarounds which were my early attempt at resolving this issue. > 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. Attached is a reduced patch to enable LRA for mips16 with my workarounds omitted. Also attached is frametest.c which should be compiled with -O2 -mips16. Add -mreload to compare with reload and you will see the extra instruction that LRA produces. When not omitting the frame pointer, LRA and reload behave the same. Regards, Matthew > >
mips16lra.patch
Description: mips16lra.patch
int g(int*); int foo() { int b = 1; g(&b); return b; }