On 2008-04-28, Ralf Hildebrandt <[email protected]> wrote:

> First of all: msp430-gcc and IAR have the same behavior
>
> my_long = (long)my_int_a * my_int_b; -- 32bit = 16bit * 16bit;
>
> But is this a violation of the standard?

No.

> I don't think so. If there is a cast of one operand to type
> long the compiler shall promote the other operand too, because
> arithmetics shall always use the "bigger" type. Up to here I
> agree with you. But after this the compiler is free to
> optimize everything away that is not needed to get a
> mathematically correct result. For the multiplication this
> means, that the upper 16 Bits of the two operands are not
> needed for a 32 bit wide result.  Therefore the compiler is
> free to reduce the multiplication to a 16bit*16bit one.

Indeed.  It can be proven mathematically that when the upper 16
bits of both operands are 0, the 32 bit result is the same for
a 16*16 multiply as it is for a 32*32 multiply. Therefore, the
compiler is free to do a 16*16 multiply, and many compilers
quite correctly do so.

> Using these thoughts one could say, that
>
> my_long = (long)my_int_a * (long)my_int_b;
>
> should do the same, because again the compiler is free to
> reduce the multiplication bitwidth.

Correct.  There's no reason the compiler shouldn't generate the
same code for the case with two typecasts.

> But unfortunately the compiler is just a machine and
> optimization of arithmetic therms is not its main target.  (It
> would be great, if the compiler would do it, but it is not
> state of the art.) Therefore the user has to give the compiler
> a hint and this hint is the rule: "cast only one operand of
> the multiplication to the target bitwidth".

-- 
Grant Edwards                   grante             Yow! Here I am in 53
                                  at               B.C. and all I want is a
                               visi.com            dill pickle!!


Reply via email to