I recently read this about NaN
values in SSE arithmetic operations:
The result of arithmetic operations acting on two not a number (NAN) arguments is undefined. Therefore, floating-point operations using NAN arguments will not match the expected behavior of the corresponding assembly instructions.
Source: http://msdn.microsoft.com/en-us/library/x5c07e2a(v=vs.100).aspx
Does this mean that, say, adding two __m128
values might convert a NaN
to a real?
If a calculation relied on a NaN
value, I need the final result to be NaN
as well. Is there any way to do this?
As I interpret that text, what it is saying is that the compiler offers various intrinsics which roughly correspond to SSE instructions. Generally, you can expect that the compiler will use SSE instructions to implement the intrinsics. However, this is not strict. The intrinsics actually specify operations in some abstract model of computation; they do not specify SSE instructions directly. In that abstract model, the result of operating on two NaNs (odd that it does not seem to allow for one NaN and one number) is undefined. Therefore, the result you get from, for example, adding two NaNs might not be a NaN.
In particular, operations in the abstract model would be subject to compiler optimizations, and those optimizations might result in things other than SSE instructions (calculations at compile time, omitted instructions if the compiler can deduce that NaNs are present so it does not need to actually perform an add, et cetera).
It seems that if you want to guarantee the semantics specified for SSE instructions, you might have to write in assembly language rather than using intrinsics in Microsoft’s compiler.
I do wish vendors would stop giving short shrift to floating-point semantics. It is difficult to do engineering in the absence of well-specified behavior.