On 28/06/11 16:53, Michael Matz wrote:
On Tue, 28 Jun 2011, Richard Guenther wrote:
I'd name the predicate value_preserving_conversion_p which I think is
what you mean. harmless isn't really descriptive.
Note that you include non-value-preserving conversions, namely int ->
unsigned int.
It seems that Andrew really does want to accept them. If so
value_preserving_conversion_p would be the wrong name. It seems to me he
wants to accept those conversions that make it possible to retrieve the
old value, i.e. when "T1 x; (T1)(T2)x == x", then T1->T2 has the
to-be-named property. bits_preserving? Hmm.
What I want (and I'm not totally clear on what this actually means) is
to be able to optimize all the cases where the end result will be the
same as the compiler produces now (using multiple multiply, shift, and
add operations).
Ok, so that's an obvious statement, but the point is that, right now,
the compiler does nothing special when you cast from int -> unsigned
int, or vice-versa, and I want to capture that somehow. There are some
exceptions, I'm sure, but what are they?
What is clear is that I don't want to just assume that casting from one
signedness to the other is a show-stopper.
For example:
unsigned long long
foo (unsigned long long a, unsigned char b, unsigned char c)
{
return a + b * c;
}
This appears to be entirely unsigned maths with plenty of spare
precision, and therefore a dead cert for any SI->DI
multiply-and-accumulate instruction, but not so - it is represented
internally as:
signed int tmp = (signed int)a * (signed int)b;
unsigned long long result = a + (unsigned long long)tmp;
Notice the unexpected signed int in the middle! I need to be able to get
past that to optimize this properly.
I've tried various test cases in which I cast signedness and mode around
a bit, and so far it appear to perform safely, but probably I'm not be
cunning enough.
Andrew