On 1/4/2021 4:11 AM, 9il wrote:
[...]
The reason those switches are provided is because the write/read is a performance hog.

D provides a couple functions in druntime which guarantee rounding intermediate values to float/double precision. Those can be used as required. This is better than a compiler switch because having compiler switches that influence floating point results is poor design.

> Since C99 the default x87 behavior is precise.

Not entirely:

 float f(float a, float b) {
    float d = (a + b) - b;
    return d;
 }

 f:
        sub     esp, 4
        fld     DWORD PTR [esp+12]
        fld     st(0)
        fadd    DWORD PTR [esp+8]
        [no write/read to memory here, so no round to float]
        fsubrp  st(1), st
        fstp    DWORD PTR [esp]
        fld     DWORD PTR [esp]
        add     esp, 4
        ret

In any case, let's try your example https://cpp.godbolt.org/z/7sa8dP with dmd for 32 bits:

                push    EAX
                push    EAX
                fld     float ptr 010h[ESP]
                fadd    float ptr 0Ch[ESP]
                fstp    float ptr [ESP]     // there's the write
                fld     float ptr [ESP]     // there's the read!
                fsub    float ptr 0Ch[ESP]
                fstp    float ptr 4[ESP]    // the write
                fld     float ptr 4[ESP]    // the read
                add     ESP,8
                ret     8

It's semantically equivalent to the godbolt asm you posted.

Reply via email to