Reload bug causing x86 problems

Joern Rennecke amylaar@cygnus.co.uk
Wed May 26 17:18:00 GMT 1999


> Then we try to create a second optional reload for the same expression and
> we get into this code in push_reload:
...
> When creating the second optional reload, we find a reusable reload.  Since
> the reusable reload is for a distinct rtl expression that is identical in
> content, we end up removing the address replacements for the new reload.
> 
> The net result is we never perform the replacement on the second instance
> of (mem (plus (reg 22) (const_int 4)).  So after reload we have:
...
> I'm not real familiar with how this code is supposed to work, but clearly
> something is broken.  It seems to me you can't simply delete address
> replacements like that without (at least) some additional checks for when
> it is safe.

As long as the merged reloads are actually done, everything is fine: the
address reloads have the replacements inside the reload_in expressions,
thus we'll end up loading the reload_in expression with the remaining
replacements into the reload register, and the reload register replaces
the two different reload_in-s.
The problem is really that the merged reload is optional, and not done after
all.

There are two ways to fix it:

- disable the call to remove_address_replacements if both merged
  reloads are optional (because that means that the merged one
  will be optional too).

- calling transfer_replacements instead to transfer all the replacements
  to the merged reload.  However, that is not really useful, since
  choose_reload_regs uses remove_address_replacements to chancel
  address reloads of inherited reloads; the transferred replacements
  would still linger on.

So I think you should go with the first way and make a comment why the
second one is wrong.



Looking at remove_address_replacements, I wonder if we can also end up
using a single register for an address that is used in another reload
as part of a group?

If so, then remove_address_replacements needs to loop in the case
that the replacement's location is not found in in_rtx to mark all
hard registers of this reload as still used.


More information about the Gcc-bugs mailing list