Hi,

On Tue, 28 Jun 2011, Andrew Stubbs wrote:

> 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).

Okay, then you really want to look through value-preserving conversions.

> 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?

Same-sized signed <-> unsigned conversions aren't value preserving:
  unsigned char c = 255; (signed char)c == -1; 255 != -1
unsigned -> larger sized signed is value preserving
  unsigned char c = 255; (signed short)c == 255;
signed -> unsigned never is value preserving

> 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!

Yeah, the C standard requires this.

> I need to be able to get past that to optimize this properly.

Then you're lucky because unsigned char -> signed int is an embedding, 
hence value preserving.  I thought we had a predicate for such conversions 
already, but seems I was wrong.  So, create it as Richi said, but 
enumerate explicitely the cases you want to handle, and include only those 
that really are value preserving.


Ciao,
Michael.

Reply via email to