On 06/28/11 18:14, Andrew Stubbs wrote: > 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.
Since both inputs are positive in a signed int (they must be, being cast from a smaller unsigned value), you can infer that it does not matter whether you treat the result of the multiplication as a signed or an unsigned value. It is positive in any case. So, I think the thing to test is: if the accumulate step requires widening the result of the multiplication, either the cast must be value preserving (widening unsigned to signed), or you must be able to prove that the multiplication produces a positive result. If the accumulate step just casts the multiplication result from signed to unsigned, keeping the precision the same, you can ignore the cast since the addition is unaffected by it. Bernd