On Mon, Oct 29, 2012 at 3:44 PM, H.J. Lu <hjl.to...@gmail.com> wrote:
> On Mon, Oct 29, 2012 at 8:15 AM, Richard Sandiford
> <rdsandif...@googlemail.com> wrote:
>> "H.J. Lu" <hjl.to...@gmail.com> writes:
>>> Hi,
>>>
>>> This patch changes get_elimination to check register number instead of
>>> RTX.  Tested on Linux/x32 with -maddress-mode=long.  OK to install?
>>
>> FWIW, this doesn't sound right to me, at least not without more 
>> justification.
>> The idea is that things like frame_pointer_rtx are supposed to be unique,
>> so the original code:
>>
>>>    if ((ep = elimination_map[hard_regno]) != NULL)
>>> -    return ep->from_rtx != reg ? NULL : ep;
>>> from != hard_regno ? NULL : ep;
>>
>> ought to be correct in itself.  reload did the same thing:
>>
>>           for (ep = reg_eliminate; ep < &reg_eliminate[NUM_ELIMINABLE_REGS];
>>                ep++)
>>             if (ep->from_rtx == x && ep->can_eliminate)
>>               return plus_constant (Pmode, ep->to_rtx, ep->previous_offset);
>>
>> It sounds on the face of it like the bug is elsewhere.
>>
>
> LRA has
>
>       if (REG_P (reg) && (ep = get_elimination (reg)) != NULL)
>         {
>           rtx to_rtx = replace_p ? ep->to_rtx : ep->from_rtx;
>
>           if (! replace_p)
>             {
>               offset += (ep->offset - ep->previous_offset);
>               offset = trunc_int_for_mode (offset, GET_MODE (plus_cst_src));
>             }
>
>           if (GET_CODE (XEXP (plus_cst_src, 0)) == SUBREG)
>             to_rtx = gen_lowpart (GET_MODE (XEXP (plus_cst_src, 0)), to_rtx);
>
> Reload has
>
>             rtx to_rtx = ep->to_rtx;
>             offset += ep->offset;
>             offset = trunc_int_for_mode (offset, GET_MODE (plus_cst_src));
>
>             if (GET_CODE (XEXP (plus_cst_src, 0)) == SUBREG)
>               to_rtx = gen_lowpart (GET_MODE (XEXP (plus_cst_src, 0)),
>                                     to_rtx);
>
> (gdb) call debug_rtx (ep->to_rtx)
> (reg/f:DI 7 sp)
> (gdb) call debug_rtx (ep->from_rtx)
> (reg/f:DI 16 argp)
> (gdb)
>
> gen_lowpart returns (reg/f:DI 7 sp) for reload and (reg:SI 16 argp)
> for LRA.   They are caused by
>
>   if (FRAME_POINTER_REGNUM != ARG_POINTER_REGNUM
>       /* We should convert arg register in LRA after the elimination
>          if it is possible.  */
>       && xregno == ARG_POINTER_REGNUM
>       && ! lra_in_progress)
>     return -1;
>
> It doesn't work in this case.
>

This testcase shows that LRA can't convert arg register after
the elimination.

-- 
H.J.

Reply via email to