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.

-- 
H.J.

Reply via email to