Eric Botcazou wrote:

> Reload 1 of insn #85 inherits the reload reg from reload 1 of insn #84, the
> bug being that the same reload reg is also used for reload 0 of insn #85.
> 
> This is supposed to work like so: the inheritance code in choose_reload_regs
> calls free_for_value_p with IGNORE_ADDRESS_RELOADS set to 1 to bypass the
> conflict with reload 0 because there is special code in the same function to
> discard reload 0 in this case:
> 
>         /* If we can inherit a RELOAD_FOR_INPUT, or can use a
>            reload_override_in, then we do not need its related
>            RELOAD_FOR_INPUT_ADDRESS / RELOAD_FOR_INPADDR_ADDRESS reloads;
>            likewise for other reload types.
>            We handle this by removing a reload when its only replacement
>            is mentioned in reload_in of the reload we are going to inherit.
>            A special case are auto_inc expressions; even if the input is
>            inherited, we still need the address for the output.  We can
>            recognize them because they have RELOAD_OUT set to RELOAD_IN.
>             If we succeeded removing some reload and we are doing a 
> preliminary
>            pass just to remove such reloads, make another pass, since the
>            removal of one reload might allow us to inherit another one.  */
>         else if (rld[r].in
>                  && rld[r].out != rld[r].in
>                  && remove_address_replacements (rld[r].in) && pass)
>           pass = 2;
> 
> But it is called with rld[r].in equal to:
> (gdb) p debug_rtx(in_rtx)
>   (reg:SI 40 %f8 [orig:109 prephitmp.12 ] [109])
> 
> and the following replacement for reload 0:
> (gdb) p debug_rtx(*replacements[0].where)
>   (plus:SI (reg/f:SI 30 %fp)
>         (const_int -6140 [0xffffffffffffe804]))
> 
> so loc_mentioned_in_p returns false and reload 0 isn't discarded.
> 
> The problem is that reload 0 is pushed because of SECONDARY_MEMORY_NEEDED,
> i.e. (reg:SI 40 %f8) is spilled to memory at the address
> (gdb) p debug_rtx(secondary_memlocs_elim[11][0])
>   (mem/c:SI (plus:SI (reg/f:SI 30 %fp)
>         (const_int -6140 [0xffffffffffffe804])) [0 S4 A32])
> 
> and replacements[0].where above points to within this MEM instead of IN_RTX.

This analysis looks correct to me.

> The attached patch fixes the problem (on the 4.6 branch) by also invoking 
> remove_address_replacements on the result of get_secondary_mem if a secondary 
> memory is needed.  The condition to detect it has been copied from 
> push_reload 
> on the 4.6 branch, but it has already slightly changed on the mainline and 
> I'm 
> not sure how to adjust it.

It is unfortunate that we need to re-do the test over and over ... longer term
it might be better to add a predicate to directly *check* whether we decided we
needed a secondary memory slot for the operand.

In any case, the change in the condition you noticed was introduced by a recent
patch by Bernd: http://gcc.gnu.org/ml/gcc-patches/2012-08/msg00171.html

It seems that we ought to use a similar test to what Bernd introduced in
gen_reload, that is, use the "replaced_subreg" routine on rld[r].in, check
whether the result is a hard register and use its REGNO_REG_CLASS.

Bernd, given that you worked on this recently, any other thoughts?

Bye,
Ulrich

-- 
  Dr. Ulrich Weigand
  GNU Toolchain for Linux on System z and Cell BE
  ulrich.weig...@de.ibm.com

Reply via email to