PATCH [10/n]: Prepare x32: PR rtl-optimization/49114: Reload failed to handle (set reg:X (plus:X (subreg:X (reg:Y) 0) (const

H.J. Lu hjl.tools@gmail.com
Tue Jun 28 22:16:00 GMT 2011


On Tue, Jun 28, 2011 at 8:44 AM, H.J. Lu <hjl.tools@gmail.com> wrote:
> On Tue, Jun 28, 2011 at 8:19 AM, Ulrich Weigand <uweigand@de.ibm.com> wrote:
>> H.J. Lu wrote:
>>> > it doesn't work;
>>> >
>>> > allocation.f: In function 'allocation':
>>> > allocation.f:1048:0: internal compiler error: in subreg_get_info, at
>>> > rtlanal.c:3235
>>> > Please submit a full bug report,
>>> > with preprocessed source if appropriate.
>>> > See <http://gcc.gnu.org/bugs.html> for instructions.
>>
>>> > since subreg_regno_offset only works on hard registers.
>>
>> Hmm, OK.  That look like another latent bug in the original code ...
>>
>>> +         if (r->mode != VOIDmode && GET_MODE (reloadreg) != r->mode)
>>> +           reloadreg = gen_rtx_REG (r->mode, REGNO (reloadreg));
>>
>> (As an aside, this is wrong; it's already wrong in the place where you
>> copied it from.  This should now use reload_adjust_reg_for_mode just
>> like subst_reload does.)
>>
>>> +
>>> +         if ((WORDS_BIG_ENDIAN || BYTES_BIG_ENDIAN)
>>> +             && GET_MODE_SIZE (Pmode) > GET_MODE_SIZE (ptr_mode))
>>> +           {
>>> +             offset = GET_MODE_SIZE (Pmode) - GET_MODE_SIZE (ptr_mode);
>>> +             if (! BYTES_BIG_ENDIAN)
>>> +               offset = (offset / UNITS_PER_WORD) * UNITS_PER_WORD;
>>> +             else if (! WORDS_BIG_ENDIAN)
>>> +               offset %= UNITS_PER_WORD;
>>> +           }
>>> +          else
>>> +            offset = 0;
>>> +
>>> +         return gen_rtx_SUBREG (ptr_mode, reloadreg, offset);
>>>
>>> works for me.
>>
>> This doesn't seem correct either, it completely ignores the SUBREG_BYTE
>> of the original SUBREG ...   Also, I don't quite see why this should
>> have anything special for Pmode / ptr_mode.
>>
>> It seems simplest to just use simplify_gen_subreg here.  Can you try
>> the following version?
>>
>> Thanks,
>> Ulrich
>>
>>
>> ChangeLog:
>>
>>        * reload.c (struct replacement): Remove SUBREG_LOC member.
>>        (push_reload): Do not set it.
>>        (push_replacement): Likewise.
>>        (subst_reload): Remove dead code.
>>        (copy_replacements): Remove assertion.
>>        (copy_replacements_1): Do not handle SUBREG_LOC.
>>        (move_replacements): Likewise.
>>        (find_replacement): Remove dead code.  Use reload_adjust_reg_for_mode.
>>        Detect subregs via recursive descent instead of via SUBREG_LOC.
>>
>>
>
> It works much better.  I am testing it now.
>

It works.  There are no regressions on Linux/ia32 nor Linux/x86-64.
Can you check it in and mention PR rtl-optimization/49114 ChangeLog?

Thanks.

-- 
H.J.



More information about the Gcc-patches mailing list