Bug#706207: gcc-4.6, gcc-4.7: invalid optimization when doing double -> int math and conversion (on big endian archs(?))
On Fri, Apr 26, 2013 at 12:43 PM, Bastian Blank <waldi@debian.org> wrote:
> On Fri, Apr 26, 2013 at 12:27:53PM +0200, Ondřej Surý wrote:
>> This code from libgd2:src/gd.c:clip_1d:
>> *y1 -= m * (*x1 - mindim);
>> where
>> m = (double) -0.050000
>> *x1 = -200
>> mindim = 0
>> *y1 = 15
>> results in *y1 = 4, which is incorrect value, since it should be 5.
>
> Nope. The result of "m * (*x1 - mindim)" is not 10, it is a floating
> point value near 10, as 10 can't be expressed in double. So this is:
> 15 - 10.00000001 = 4.9999999. This converted to int is 4.
>
>> Most simple workaround, which allows gcc to produce correct value:
>> *y1 -= (int)(m * (*x1 - mindim));
>
> Here you force the later part to be 10.
>
>> Assigning to some other variable also works ok:
>> int t;
>> t = m * (*x1 - mindim);
>> *y1 -= t;
>
> The same.
>
>> gcc-4.7 is unfortunatelly also affected.
>> I just hope we don't compile the nuclear reactor controls with gcc :)
>
> Just don't convert floating point to fixed point.
I don't object to this, but somehow I fail to grasp the idea that the
result depends on architecture and optimization level.
I would expect consistent results, even consistent *bad* results would be ok.
But you're right that the code would benefit with a rewrite to whole
number math anyway.
O.
--
Ondřej Surý <ondrej@sury.org>
Reply to: