This is the mail archive of the
gcc@gcc.gnu.org
mailing list for the GCC project.
Re: addsi3_mips16 and frame pointer with LRA
- From: Vladimir Makarov <vmakarov at redhat dot com>
- To: Matthew Fortune <Matthew dot Fortune at imgtec dot com>, Richard Sandiford <rdsandiford at googlemail dot com>
- Cc: "gcc at gcc dot gnu dot org" <gcc at gcc dot gnu dot org>
- Date: Tue, 29 Oct 2013 14:43:47 -0400
- Subject: Re: addsi3_mips16 and frame pointer with LRA
- Authentication-results: sourceware.org; auth=none
- References: <6D39441BF12EF246A7ABCE6654B02353417256 at LEMAIL01 dot le dot imgtec dot org>
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.
>