February 16, 2015
https://issues.dlang.org/show_bug.cgi?id=13474

--- Comment #17 from Илья Ярошенко <ilyayaroshenko@gmail.com> ---
(In reply to yebblies from comment #15)

Why you have changed the name of this issue?
Bug is not only for return. Truncation should be during all calculations.

> I've thought about it some more, and I don't think this is behaving incorrectly given what D does specify about floating point behaviour.

Yes. D is unique language in this question.
In other other words D is not a system language because it can't compile
correctly IEEE 754 standard.

I am disappointed.
All D contributors explain me that "it is a feature for precise math".
But this feature prohibits price math:
https://github.com/D-Programming-Language/phobos/pull/2513.

> 1. Nothing in any ABI I can find specifies that return values must be truncated.  (gcc does have a -ffloat-store flag)
>
> 2. D allows floating point intermediates to be at a higher precision than the operand types.  This doesn't explicitly include return values, but...
> 
> 3. D allows inlining, which means even if return values are explicitly excluded from (2) then it still can't be relied upon.
> 
> So, I conclude that calculating and returning floating point values at a higher precision than specified is allowed in D.
> 
> The code where you hit the problem can be fixed by:
> 
> 1. Fixing the tests to not rely on maximum precision.

The problem is that value isn't "more price". The value is wrong because truncation should be performed during ALL calculation.

> 2. Using a wrapper on function calls where precision must be forced. (An intrinsic to force precision loss has been discussed in the past)

It should be performed during all std.numeric.summation ;(

> 3. Lobbying Walter for a language change enforcing this in some way.

Can you help me to do it?

> I've changed the platform as this behaviour is possible on other platforms too even if the current code generator never hits those cases.

--
February 16, 2015
https://issues.dlang.org/show_bug.cgi?id=13474

--- Comment #18 from yebblies <yebblies@gmail.com> ---
(In reply to Илья Ярошенко from comment #17)
> (In reply to yebblies from comment #15)
> 
> Why you have changed the name of this issue?
> Bug is not only for return. Truncation should be during all calculations.
> 

I changed the title because the old one was not accurate.  The optimizer is working as designed, even if that design is not what you want.

Please change the title if you want to request no extra intermediate precision anywhere, I just kept it to the scope of the original report.

> 
> Yes. D is unique language in this question.
> In other other words D is not a system language because it can't compile
> correctly IEEE 754 standard.
> 

I'm not sure this counts as violating IEEE 754, though I'm not an expert.  C has the same problem, so I guess C isn't a system language either by that logic.

> I am disappointed.
> All D contributors explain me that "it is a feature for precise math".
> But this feature prohibits price math:
> https://github.com/D-Programming-Language/phobos/pull/2513.
> 

Maybe.  The logic in here does seem sound, although again I'm not an expert.

http://dlang.org/d-floating-point.html

So the idea is that strict double rounding would be a big performance hit, and

> The problem is that value isn't "more price". The value is wrong because truncation should be performed during ALL calculation.

Technically the value _is_ more precise.  The way it interacts with rounding is what produces the incorrect result.

Under the current spec the rounding is not required.

> 
> > 3. Lobbying Walter for a language change enforcing this in some way.
> 
> Can you help me to do it?
> 

I don't know enough about the algorithms you're using to be sure either you or Walter is right here.  You may want to comment on issue 9937 and see if Don agrees with you.

--
February 16, 2015
https://issues.dlang.org/show_bug.cgi?id=13474

--- Comment #19 from Илья Ярошенко <ilyayaroshenko@gmail.com> ---
(In reply to yebblies from comment #18)
> (In reply to Илья Ярошенко from comment #17)
> > (In reply to yebblies from comment #15)
> > 
> > Why you have changed the name of this issue?
> > Bug is not only for return. Truncation should be during all calculations.
> > 
> 
> I changed the title because the old one was not accurate.  The optimizer is working as designed, even if that design is not what you want.
> 
> Please change the title if you want to request no extra intermediate precision anywhere, I just kept it to the scope of the original report.
> 
> > 
> > Yes. D is unique language in this question.
> > In other other words D is not a system language because it can't compile
> > correctly IEEE 754 standard.
> > 
> 
> I'm not sure this counts as violating IEEE 754, though I'm not an expert.  C has the same problem, so I guess C isn't a system language either by that logic.

C has this problem only when special compiler flags enabled.
All this algorithms are from Python source code (C) or Wikipedia(C, Pascal).

> > I am disappointed.
> > All D contributors explain me that "it is a feature for precise math".
> > But this feature prohibits price math:
> > https://github.com/D-Programming-Language/phobos/pull/2513.
> > 
> 
> Maybe.  The logic in here does seem sound, although again I'm not an expert.
> 
> http://dlang.org/d-floating-point.html
> 
> So the idea is that strict double rounding would be a big performance hit, and
> 
> > The problem is that value isn't "more price". The value is wrong because truncation should be performed during ALL calculation.
> 
> Technically the value _is_ more precise.  The way it interacts with rounding is what produces the incorrect result.
> 
> Under the current spec the rounding is not required.
> 
> > 
> > > 3. Lobbying Walter for a language change enforcing this in some way.
> > 
> > Can you help me to do it?
> > 
> 
> I don't know enough about the algorithms you're using to be sure either you or Walter is right here.  You may want to comment on issue 9937 and see if Don agrees with you.

--
February 16, 2015
https://issues.dlang.org/show_bug.cgi?id=13474

Илья Ярошенко <ilyayaroshenko@gmail.com> changed:

           What    |Removed                     |Added
----------------------------------------------------------------------------
            Summary|Discard excess precision    |Discard excess precision
                   |when returning double in    |for float and double (x87)
                   |x87 register                |

--
February 16, 2015
https://issues.dlang.org/show_bug.cgi?id=13474

--- Comment #20 from yebblies <yebblies@gmail.com> ---
(In reply to Илья Ярошенко from comment #19)
>
> C has this problem only when special compiler flags enabled.
> All this algorithms are from Python source code (C) or Wikipedia(C, Pascal).

C does allow you to specify when excess precision should be lost, but it still has extra precision enabled for intermediate expressions IIUC.  So the problem still exists, but is easier to work around.

--
September 29, 2016
https://issues.dlang.org/show_bug.cgi?id=13474

Martin Nowak <code@dawg.eu> changed:

           What    |Removed                     |Added
----------------------------------------------------------------------------
                 CC|                            |code@dawg.eu

--- Comment #21 from Martin Nowak <code@dawg.eu> ---
(In reply to yebblies from comment #18)
> Maybe.  The logic in here does seem sound, although again I'm not an expert.
> 
> http://dlang.org/d-floating-point.html
> 
> So the idea is that strict double rounding would be a big performance hit

That doesn't make too much sense, and we shouldn't adapt the language to an x87 "coprocessor", using the old FPU nowadays is a performance hit and should be avoided unless you absolutely need the extra 16-bits of precision.

As C get's away with it's default behavior, I don't think need to make -ffast-math our default.

--
November 07, 2016
https://issues.dlang.org/show_bug.cgi?id=13474

Walter Bright <bugzilla@digitalmars.com> changed:

           What    |Removed                     |Added
----------------------------------------------------------------------------
                 CC|                            |bugzilla@digitalmars.com

--- Comment #22 from Walter Bright <bugzilla@digitalmars.com> ---
This boils down to the following code:

 double foo(double x, double t, double s, double c) {
    double y = x - t;
    c += y + s;
    return s + c;
 }

The body of which, when optimized, looks like:

    return s + (c + (x - t) + s);

Or, in x87 instructions:

       fld     qword ptr 01Ch[ESP]
       fld     qword ptr 0Ch[ESP]
       fxch    ST(1)
       fsub    qword ptr 014h[ESP]
       fadd    qword ptr 0Ch[ESP]
       fadd    qword ptr 4[ESP]
       fstp    qword ptr 4[ESP]
       fadd    qword ptr 4[ESP]
       ret     020h

The algorithm relies on rounding to double precision of the (x-t) calculation. The only way to get the x87 to do that is to actually assign it to memory. But the compiler optimizes away the assignment to memory, because it is substantially slower.

The 64 bit code does not have this problem, because the code gen looks like:

       push    RBP
       mov     RBP,RSP
       movsd   XMM4,XMM0
       movsd   XMM5,XMM1
       subsd   XMM3,XMM2
       addsd   XMM3,XMM5
       addsd   XMM4,XMM3
       movsd   XMM0,XMM5
       addsd   XMM0,XMM4
       pop     RBP
       ret

It's doing the same optimization, but the result is rounded to double because the XMM registers are doubles.

Note that the following targets generate x87 code, not XMM code:

    Win32, Linux32, FreeBSD32

because it is not guaranteed that the target has XMM registers. I suspect we don't really care about the floating point performance on those targets, but we do care that the code gives expected results.

So I propose that the fix is to disable optimizing away the assignment to y for x87 code gen targets.

--
November 07, 2016
https://issues.dlang.org/show_bug.cgi?id=13474

--- Comment #23 from yebblies <yebblies@gmail.com> ---

(In reply to Walter Bright from comment #22)
> 
> So I propose that the fix is to disable optimizing away the assignment to y for x87 code gen targets.

Are you suggesting disabling that optimization always, or allowing the programmer to specify that that particular assignment shouldn't be optimized?

If the latter, I would rather stop supporting targets without xmm regs than stop producing fast code on Win32 etc.

If the former, I think that's well covered by adding an intrinsic, so the code becomes:

 double foo(double x, double t, double s, double c) {
    double y = __builtin_that_forces_rounding_to_double(x - t);
    c += y + s;
    return s + c;
 }

And this seems like something that could be handled fairly easily in the dmd backend.  I think this covers all the cases where rounding must be required.

--
November 07, 2016
https://issues.dlang.org/show_bug.cgi?id=13474

--- Comment #24 from Илья Ярошенко <ilyayaroshenko@gmail.com> ---
(In reply to yebblies from comment #23)
> I would rather stop supporting targets without xmm regs than stop producing fast code on Win32 etc.

+1

--
November 07, 2016
https://issues.dlang.org/show_bug.cgi?id=13474

--- Comment #25 from Walter Bright <bugzilla@digitalmars.com> ---
https://github.com/dlang/dmd/pull/6247

--