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