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. -- H.J.