This is the mail archive of the
gcc-patches@gcc.gnu.org
mailing list for the GCC project.
Re: Paradoxical subreg in compare
- To: gcc-patches at gcc dot gnu dot org
- Subject: Re: Paradoxical subreg in compare
- From: Jim Wilson <wilson at cygnus dot com>
- Date: Tue, 30 May 2000 17:45:54 -0700
- Newsgroups: cygnus.egcs.patches
>3) find_equiv_reg() finds that (subreg:HI (reg:SI 0 d0) 0) already
>contains the value of the memory reference to `s', so it doesn't
>reload it.
The RTL is wrong after this point. If we are trying to reload
(subreg:SI (mem:HI)), and (subreg:HI (reg:SI)) has the same value as the
mem, then it is not OK to do the substitution, because we are not guaranteed
to have the correct value after canceling the subregs. This is OK only if
the (reg:SI) has the same 32-bit value as (subreg:SI (mem:HI)).
However, I suspect that there isn't enough info for find_equiv_reg to know
this. If neither rld[i].in nor rld[i].in_reg holds the SUBREG, then there
is nothing find_equiv_reg can do. We would have to modify push_reload to
save a little more info. If it decides to reload the inner part of a
paradoxical subreg of a mem, then it should set a new field in the rld
array to let find_equiv_reg know that it can't accept a non-paradoxical
subreg. Perhaps something like rld[i].nosubreg. Then in find_equiv_reg,
if nosubreg is true and goal_mem is true, then we reject valtry if it is
a SUBREG.
There is already code in push_reload for the special case we are interested in.
#if ! defined (LOAD_EXTEND_OP) && ! defined (WORD_REGISTER_OPERATIONS)
if (GET_CODE (in) == MEM)
/* This is supposed to happen only for paradoxical subregs made by
combine.c. (SUBREG (MEM)) isn't supposed to occur other ways. */
if (GET_MODE_SIZE (GET_MODE (in)) > GET_MODE_SIZE (inmode))
abort ();
#endif
This could be changed to something like:
if (GET_CODE (in) == MEM)
/* This is supposed to happen only for paradoxical subregs made by
combine.c. (SUBREG (MEM)) isn't supposed to occur other ways. */
if (GET_MODE_SIZE (GET_MODE (in)) > GET_MODE_SIZE (inmode))
{
#if ! defined (LOAD_EXTEND_OP) && ! defined (WORD_REGISTER_OPERATIONS)
abort ();
#else
nosubreg = 1;
#endif
}
This code appears twice, once for inputs, and once for outputs.
Jim