This is the mail archive of the
gcc-patches@gcc.gnu.org
mailing list for the GCC project.
Re: Adding constants to LO_SUM
- To: kenner at vlsi1 dot ultra dot nyu dot edu (Richard Kenner)
- Subject: Re: Adding constants to LO_SUM
- From: Geoff Keating <geoffk at geoffk dot org>
- Date: 09 Jul 2001 12:59:57 -0700
- CC: gcc-patches at gcc dot gnu dot org
- References: <10107091923.AA07025@vlsi1.ultra.nyu.edu>
kenner@vlsi1.ultra.nyu.edu (Richard Kenner) writes:
> This might fix the problem, but it isn't correct. Just because it
> happens to work on rs6000 for 'long long', it doesn't follow it'll
> work everywhere. It is an inherently target-dependent thing, because
> LO_SUM is a target-dependent thing.
>
> I'm not certain what "correct" mean in this context, since there's no
> sufficiently-detailed definition of LO_SUM around.
It is defined in my manual as:
`(lo_sum:M X Y)'
Like `plus', except that it represents that sum of X and the
low-order bits of Y. The number of low order bits is
machine-dependent but is normally the number of bits in a `Pmode'
item minus the number of bits set by the `high' code (*note
Constants::.).
I can't imagine how to make that clearer.
The significance of this is as follows:
Suppose you have
(set (reg 3) (high (symbol_ref "foo")))
(set (reg 4) (lo_sum (reg 3) (plus (symbol_ref "foo") (const_int N))))
Now, under what circumstances will this be equivalent to
(set (reg 4) (plus (lo_sum (reg 3) (symbol_ref "foo")) (const_int N)))
which is the same as
(set (reg 4) (plus (symbol_ref "foo") (const_int N)))
Well, this will only fail if there is a carry out of the bits set by
lo_sum. So it will certainly fail if N is -1, and will always
succeed, of course, if N is 0. If we happen to know that, say,
(symbol_ref "foo") is even, then it will always succeed when N is 1.
So this is partly a question about the alignment of "foo".
That is not the only factor. Suppose that we know "foo" is aligned to
a 64k boundary. We still can't do this if N was 0xFFFF but there are
only 12 bits added by low_sum. So in addition to knowing about
alignment, there is a maximum value that can be added for any
particular target.
> However, this essentially restores the old behavior and so seems as
> "correct" as the old code was.
I don't think it's quite the same as the old behaviour. It used to be
that only a very few places would try to do this, and some of them had
comments explaining why the author thought it would be safe. Are the
places that your patch affects really the same places as the places
that used to do this?
> Do you have any other suggestions?
Perhaps you could have a target macro that describes this more
precisely? It is actually a new optimisation, because presumably before
the code would have been changed into
(set (reg 3) (high (plus (symbol_ref "foo") (const_int N))))
(set (reg 4) (lo_sum (reg 3) (plus (symbol_ref "foo") (const_int N))))
which is always safe (assuming it's a valid address), but will not CSE
as well.
--
- Geoffrey Keating <geoffk@geoffk.org>