My question is somehow related to an answer to this topic.
Consider the following C program:
#include <emmintrin.h>
#include <stdio.h>
void print(__m128* v)
{
union Helper
{
__m128 m128;
__attribute__((aligned(16))) float f[4];
};
Helper h;
h.m128 = *v;
printf("%f %f %f %f\n", h.f[0], h.f[1], h.f[2], h.f[3]);
}
int main()
{
__m128 a = _mm_set1_ps(0.0f / 0.0f);
__m128 b = _mm_set1_ps(0.0f);
__m128 m1 = _mm_max_ps(a, b);
__m128 m2 = _mm_max_ps(b, a);
print(&m1);
print(&m2);
}
which prints
0.000000 0.000000 0.000000 0.000000
nan nan nan nan
I compiled this with Mac OS X Clang from Xcode but observed similar behavior with GCC on Linux. Has anyone an explanation for this? Can I in general rely on this behavior (_mm_max_ps returning the value of its 2nd argument if one of its arguments is NaN or -NaN)? This document here states that if a single operand to MAXPS is NaN, the source operand is returned. While this seems somehow orthogonal to the behavior I observed, the intrinsic (as opposed to the actual SSE instruction) is a binary operation w/o side effects and one cannot speak of source operands or such in this case.