[Bug d/98607] GDC merging computations but rounding mode has changed
ibuclaw at gdcproject dot org
gcc-bugzilla@gcc.gnu.org
Sat Jan 9 20:54:57 GMT 2021
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);
}
---
More information about the Gcc-bugs
mailing list