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.