This is the mail archive of the gcc-patches@gcc.gnu.org mailing list for the GCC project.


Index Nav: [Date Index] [Subject Index] [Author Index] [Thread Index]
Message Nav: [Date Prev] [Date Next] [Thread Prev] [Thread Next]
Other format: [Raw text]

Re: PATCH: PR rtl-optimization/55093: [4.8 Regression] [x32] -maddress-mode=long failed


On 10/30/2012 06:34 AM, Richard Sandiford wrote:
"H.J. Lu" <hjl.tools@gmail.com> writes:
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.

Here is a patch to remove ra_in_progress check for
ARG_POINTER_REGNUM.  Tested on Linux.x86-64.
OK to install?
Thanks HJ.  This looks good to me.  As well as your testcase, I think
it would be dangerous to reduce this kind of subreg during non-final
elimination in cases where the argument pointer occupies more than one
hard register (like avr IIRC).  We could end up with something like
ARG_POINTER_REGNUM+1, which wouldn't show up as an elimination register
during the rest of LRA.

It's important that we do get rid of the subreg during the final
elimination stage, but I think alter_subreg already handles that case.

Since this code is outside the LRA files: patch is OK if Vlad agrees.

I added this code for a reason probably to solve some target problems.

So I am not sure but let us try.

It is ok for me to commit the patch if there are no regressions on x86/x86-64.



Index Nav: [Date Index] [Subject Index] [Author Index] [Thread Index]
Message Nav: [Date Prev] [Date Next] [Thread Prev] [Thread Next]