[PATCH (3/7)] Widening multiply-and-accumulate pattern matching

Bernd Schmidt bernds@codesourcery.com
Fri Jul 1 16:40:00 GMT 2011


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



More information about the Gcc-patches mailing list