Floating point rounding
ag0aep6g via Digitalmars-d-learn
digitalmars-d-learn at puremagic.com
Fri Mar 3 08:39:09 PST 2017
On 03/02/2017 10:49 PM, Guillaume Chatelet wrote:
> Thx for the investigation!
> Here is the code for FloatingPointControl
> https://github.com/dlang/phobos/blob/master/std/math.d#L4809
>
> Other code (enableExceptions / disableExceptions) seems to have two code
> path depending on "version(X86_Any)", rounding doesn't.
>
> Maybe that's the bug?
I don't think that's it. But I think I've figured out what's wrong:
dmd generates SSE instructions for floating point math.
FloatingPointControl only minds the control register for the FPU. But
SSE instructions are not affected by that. SSE has a separate control
register: MXCSR.
Too see that dmd generates SSE instructions:
echo 'void main() { float x; x += 0.1f; }' > test.d && \
dmd -c test.d && \
objdump -d -Mintel -j.text._Dmain test.o
Note the instructions movss and addss, and the xmm registers.
To affect those instructions, FloatinPointControl.setsetControlState [1]
must use ldmxcsr in addition to or instead of fldcw.
This should be a pretty obvious bug. Rounding (and floating point
exceptions?) must not be covered in the phobos tests at all.
[1]
https://github.com/dlang/phobos/blob/750593738bcbe9577c3f5951b5b639392871f90e/std/math.d#L4906-L4933
More information about the Digitalmars-d-learn
mailing list