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 < ®_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.