Thread overview
[Issue 21376] [x86-only] Returning 32-bit floats have wrong precision
Nov 10, 2020
Iain Buclaw
Nov 10, 2020
Iain Buclaw
Nov 10, 2020
Iain Buclaw
Nov 10, 2020
Iain Buclaw
Nov 10, 2020
Iain Buclaw
Jan 21, 2021
Dlang Bot
Mar 21, 2021
Iain Buclaw
Mar 21, 2021
Iain Buclaw
Dec 17, 2022
Iain Buclaw
Jul 07, 2023
Iain Buclaw
November 10, 2020
https://issues.dlang.org/show_bug.cgi?id=21376

Iain Buclaw <ibuclaw@gdcproject.org> changed:

           What    |Removed                     |Added
----------------------------------------------------------------------------
                 CC|                            |ibuclaw@gdcproject.org

--- Comment #1 from Iain Buclaw <ibuclaw@gdcproject.org> ---
gdc x86 does not have this problem, so it is the dmd compiler emitting wrong code, not the FPU on i686.

--
November 10, 2020
https://issues.dlang.org/show_bug.cgi?id=21376

Iain Buclaw <ibuclaw@gdcproject.org> changed:

           What    |Removed                     |Added
----------------------------------------------------------------------------
           Keywords|                            |wrong-code

--
November 10, 2020
https://issues.dlang.org/show_bug.cgi?id=21376

--- Comment #2 from Iain Buclaw <ibuclaw@gdcproject.org> ---
Assembly dump of return statement in `float abs()`

-----------------------------------------------------
dmd x86:
    call   hypotFeeZe
    add    $0x8,%esp
    leave
    ret    $0x8
-----------------------------------------------------
dmd x86_64:
    callq  hypotFeeZe
    add    $0x20,%rsp
    fstpl  -0x20(%rbp)
    movsd  -0x20(%rbp),%xmm0
    cvtsd2ss %xmm0,%xmm0
    leaveq
    retq
-----------------------------------------------------
gdc x86:
    call   hypotFeeZe
    add    $0x18,%esp
    fstps  -0x4(%ebp)
    flds   -0x4(%ebp)
    leave
    ret
-----------------------------------------------------
gdc x86_64:
    callq  hypotFeeZe
    add    $0x20,%rsp
    fstps  -0xc(%rbp)
    movss  -0xc(%rbp),%xmm0
    leaveq
    retq
-----------------------------------------------------

As expected, there is no fstp/fld generated by dmd x86, so the real value returned by hypot is not truncated as per what x86_64 does.

--
November 10, 2020
https://issues.dlang.org/show_bug.cgi?id=21376

--- Comment #3 from Iain Buclaw <ibuclaw@gdcproject.org> ---
hypot() isn't necessary, so that leaves just the lack of fstp/fld after calling
fsqrt.

---
import core.math;

float abs(float re, float im)
{
    float u = fabs(re);
    float v = fabs(im);
    return sqrt(u*u + v*v);
}

void log(real x)
{
    assert(x == 1);
}

void main()
{
    float re = 0.866025403784438646787;
    float im = 0.5;
    return log(abs(re, im));
}

--
November 10, 2020
https://issues.dlang.org/show_bug.cgi?id=21376

--- Comment #4 from Iain Buclaw <ibuclaw@gdcproject.org> ---
(In reply to Iain Buclaw from comment #3)
>     return sqrt(u*u + v*v);

-----------------------------------------------------
dmd x86:
    movss  %xmm0,-0x18(%ebp)
    flds   -0x18(%ebp)
    fmul   %st(0),%st
    movss  %xmm2,-0x18(%ebp)
    flds   -0x18(%ebp)
    fmul   %st(0),%st
    faddp  %st,%st(1)
    fsqrt
    leave
    ret    $0x8
-----------------------------------------------------
dmd x86_64:
    movss  %xmm0,-0x30(%rbp)
    flds   -0x30(%rbp)
    fmul   %st(0),%st
    movss  %xmm2,-0x30(%rbp)
    flds   -0x30(%rbp)
    fmul   %st(0),%st
    faddp  %st,%st(1)
    fsqrt
    fstps  -0x30(%rbp)
    movss  -0x30(%rbp),%xmm0
    leaveq
    retq
-----------------------------------------------------

--
January 21, 2021
https://issues.dlang.org/show_bug.cgi?id=21376

Dlang Bot <dlang-bot@dlang.rocks> changed:

           What    |Removed                     |Added
----------------------------------------------------------------------------
           Keywords|                            |pull

--- Comment #5 from Dlang Bot <dlang-bot@dlang.rocks> ---
@ibuclaw updated dlang/dmd pull request #12073 "fix Issue 21515 extern(C) and
extern(C++) returns creal in wrong order" fixing this issue:

- fix Issue 21376 - Returning 32-bit floats have wrong precision on i386

https://github.com/dlang/dmd/pull/12073

--
March 21, 2021
https://issues.dlang.org/show_bug.cgi?id=21376

--- Comment #6 from Iain Buclaw <ibuclaw@gdcproject.org> ---
(In reply to Dlang Bot from comment #5)
> @ibuclaw updated dlang/dmd pull request #12073 "fix Issue 21515 extern(C)
> and extern(C++) returns creal in wrong order" fixing this issue:
> 
> - fix Issue 21376 - Returning 32-bit floats have wrong precision on i386
> 
> https://github.com/dlang/dmd/pull/12073

Ignore this, I attempted fixing, but it's all horribly broken.

--
March 21, 2021
https://issues.dlang.org/show_bug.cgi?id=21376

Iain Buclaw <ibuclaw@gdcproject.org> changed:

           What    |Removed                     |Added
----------------------------------------------------------------------------
           Keywords|                            |backend

--
December 17, 2022
https://issues.dlang.org/show_bug.cgi?id=21376

Iain Buclaw <ibuclaw@gdcproject.org> changed:

           What    |Removed                     |Added
----------------------------------------------------------------------------
           Priority|P1                          |P2

--
July 07, 2023
https://issues.dlang.org/show_bug.cgi?id=21376

Iain Buclaw <ibuclaw@gdcproject.org> changed:

           What    |Removed                     |Added
----------------------------------------------------------------------------
           See Also|                            |https://issues.dlang.org/sh
                   |                            |ow_bug.cgi?id=21581

--