https://gcc.gnu.org/bugzilla/show_bug.cgi?id=98607

--- Comment #8 from Iain Buclaw <ibuclaw at gdcproject dot org> ---
(In reply to Guillaume Piolat from comment #6)
> I provide intel intrinsics API for D, these intrinsics (like in C++) allows
> to change the rounding mode, and about 200 other functions that depend on
> the rounding mode can be called. I'm not the one in control of who calls
> what.
> 
> I don't see a workaround for C++ headers at
> https://github.com/gcc-mirror/gcc/blob/
> 16e2427f50c208dfe07d07f18009969502c25dc8/gcc/config/i386/xmmintrin.h#L872

Ah, I was mistaken last night.  Probably my quick conversion was wrong in some
way that prevented inlining.  On a second look, you'll find nothing in
xmmintrin.h that'll help you.

---
#include <immintrin.h>
int main()
{
    unsigned savedRounding = _MM_GET_ROUNDING_MODE();

    _MM_SET_ROUNDING_MODE(_MM_ROUND_NEAREST);
    union {
        __m128i vec;
        int array[4];
    } A;
    A.vec = _mm_cvtps_epi32(_mm_setr_ps(1.4f, -2.1f, 53.5f, -2.9f));
    assert(A.array[0] == 1);
    assert(A.array[1] == -2);
    assert(A.array[2] == 54);
    assert(A.array[3] == -3);

    // GCC might merge this branch with above! Despite _MM_SET_ROUNDING_MODE 
    // not being pure.
    _MM_SET_ROUNDING_MODE(_MM_ROUND_DOWN);
    A.vec = _mm_cvtps_epi32(_mm_setr_ps(1.4f, -2.1f, 53.5f, -2.9f));
    assert(A.array[0] == 1);
    assert(A.array[1] == -3);  // fails
    assert(A.array[2] == 53);
    assert(A.array[3] == -3);
    return 0;
}
---

One workaround for the intel-intrinsics D library might be to insert a barrier
in _MM_SET_ROUNDING_MODE.

---
void _MM_SET_ROUNDING_MODE(int _MM_ROUND_xxxx)
{
    asm { "" : : : "memory"; }
    _mm_setcsr((_mm_getcsr() & ~_MM_ROUND_MASK) | _MM_ROUND_xxxx);
}

---

Reply via email to