title: checking for nans with intrinsics in c++
body: <p>I'm new to using intrinsics but I wanted to write a function that takes a vector of 4 doubles computes <code>a &gt; 1e-5 ? std::sqrt(a) : 0.0</code> my first instinct was to write this as follows</p>
  
  <pre><code>#include &lt;immintrin.h&gt;
  __m256d f(__m256d a)
  {
    __m256d is_valid = a &gt; _mm256_set1_pd(1e-5);
    __m256d sqrt_val = _mm256_sqrt_pd(a);
    return is_valid * sqrt_val;
  }
  </code></pre>
  
  <p>which according to gcc.godbolt.com compiles to the following</p>
  
  <pre><code>f(double __vector(4)):
      vsqrtpd  ymm1, ymm0
      vcmpgtpd ymm0, ymm0, YMMWORD PTR .LC0[rip]
      vmulpd   ymm0, ymm1, ymm0
      ret
  .LC0:
      .long   2296604913
      .long   1055193269
      .long   2296604913
      .long   1055193269
      .long   2296604913
      .long   1055193269
      .long   2296604913
      .long   1055193269
  </code></pre>
  
  <p>but i'm worried what will happen if <code>sqrt_val</code> contains a <code>nan</code>. i dont think <code>0.0 * nan</code> will work. what are the best practices to do here?</p>
  
  <p><strong>Edit</strong></p>
  
  <p>After reading the comment from @ChrisCooper (and @njuffa) I was linked to another stack overflow answer and so I will test for self equality and then <code>and</code> this with my result.</p>
  
  <pre><code>#include &lt;immintrin.h&gt;
  __m256d f(__m256d a)
  {
    __m256d is_valid = a &gt; _mm256_set1_pd(1e-5);
    __m256d sqrt_val = _mm256_sqrt_pd(a);
    __m256d result = is_valid * sqrt_val;
    __m256d cmpeq = result == result;
    return  _mm256_and_pd(cmpeq, result);
  } 
  </code></pre>
  
  <p>which compiles to the following</p>
  
  <pre><code>f(double __vector(4)):
      vsqrtpd  ymm1, ymm0
      vcmpgtpd ymm0, ymm0, YMMWORD PTR .LC0[rip]
      vmulpd   ymm0, ymm1, ymm0
      vcmpeqpd ymm1, ymm0, ymm0
      vandpd   ymm0, ymm1, ymm0
      ret
  .LC0:
      .long   2296604913
      .long   1055193269
      .long   2296604913
      .long   1055193269
      .long   2296604913
      .long   1055193269
      .long   2296604913
      .long   1055193269
  </code></pre>