title: How to implement "_mm_storeu_epi64" without aliasing problems?
body: <p>(Note: Although this question is about "store", the "load" case has the same issues and is perfectly symmetric.)</p>
  
  <p>The SSE intrinsics provide an <a href="http://msdn.microsoft.com/en-us/library/7ek6y8w1(v=vs.90).aspx" rel="noreferrer"><code>_mm_storeu_pd</code></a> function with the following signature:</p>
  
  <pre><code>void _mm_storeu_pd (double *p, __m128d a);
  </code></pre>
  
  <p>So if I have vector of two doubles, and I want to store it to an array of two doubles, I can just use this intrinsic.</p>
  
  <p>However, my vector is not two doubles; it is two 64-bit integers, and I want to store it to an array of two 64-bit integers. That is, I want a function with the following signature:</p>
  
  <pre><code>void _mm_storeu_epi64 (int64_t *p, __m128i a);
  </code></pre>
  
  <p>But the intrinsics provide no such function. The closest they have is <a href="http://msdn.microsoft.com/en-us/library/w1k1k29t(v=vs.90).aspx" rel="noreferrer"><code>_mm_storeu_si128</code></a>:</p>
  
  <pre><code>void _mm_storeu_si128 (__m128i *p, __m128i a);
  </code></pre>
  
  <p>The problem is that this function takes a pointer to <code>__m128i</code>, while my array is an array of <code>int64_t</code>. Writing to an object via the wrong type of pointer is a violation of <a href="https://stackoverflow.com/questions/98650/">strict aliasing</a> and is definitely undefined behavior. I am concerned that my compiler, now or in the future, will reorder or otherwise optimize away the store thus breaking my program in strange ways.</p>
  
  <p>To be clear, what I want is a function I can invoke like this:</p>
  
  <pre><code>__m128i v = _mm_set_epi64x(2,1);
  int64_t ra[2];
  _mm_storeu_epi64(&amp;ra[0], v); // does not exist, so I want to implement it
  </code></pre>
  
  <p>Here are six attempts to create such a function.</p>
  
  <h2>Attempt #1</h2>
  
  <pre><code>void _mm_storeu_epi64(int64_t *p, __m128i a) {
      _mm_storeu_si128(reinterpret_cast&lt;__m128i *&gt;(p), a);
  }
  </code></pre>
  
  <p>This appears to have the strict aliasing problem I am worried about.</p>
  
  <h2>Attempt #2</h2>
  
  <pre><code>void _mm_storeu_epi64(int64_t *p, __m128i a) {
      _mm_storeu_si128(static_cast&lt;__m128i *&gt;(static_cast&lt;void *&gt;(p)), a);
  }
  </code></pre>
  
  <p><a href="https://stackoverflow.com/questions/1863069/">Possibly better in general</a>, but I do not think it makes any difference in this case.</p>
  
  <h2>Attempt #3</h2>
  
  <pre><code>void _mm_storeu_epi64(int64_t *p, __m128i a) {
      union TypePun {
          int64_t a[2];
          __m128i v;
       };
      TypePun *p_u = reinterpret_cast&lt;TypePun *&gt;(p);
      p_u-&gt;v = a;
  }
  </code></pre>
  
  <p>This generates incorrect code on my compiler (GCC 4.9.0), which emits an aligned <code>movaps</code> instruction instead of an unaligned <code>movups</code>. (The union is aligned, so the <code>reinterpret_cast</code> tricks GCC into assuming <code>p_u</code> is aligned, too.)</p>
  
  <h2>Attempt #4</h2>
  
  <pre><code>void _mm_storeu_epi64(int64_t *p, __m128i a) {
      union TypePun {
          int64_t a[2];
          __m128i v;
       };
      TypePun *p_u = reinterpret_cast&lt;TypePun *&gt;(p);
      _mm_storeu_si128(&amp;p_u-&gt;v, a);
  }
  </code></pre>
  
  <p>This appears to emit the code I want. The "type-punning via union" trick, although <a href="https://stackoverflow.com/questions/11373203/">technically undefined in C++</a>, is <a href="https://stackoverflow.com/questions/346622/">widely-supported</a>. But is this example -- where I pass a pointer to an element of a union rather than access via the union itself -- really a valid way to use the union for type-punning?</p>
  
  <h2>Attempt #5</h2>
  
  <pre><code>void _mm_storeu_epi64(int64_t *p, __m128i a) {
      p[0] = _mm_extract_epi64(a, 0);
      p[1] = _mm_extract_epi64(a, 1);
  }
  </code></pre>
  
  <p>This works and is perfectly valid, but it emits two instructions instead of one.</p>
  
  <h2>Attempt #6</h2>
  
  <pre><code>void _mm_storeu_epi64(int64_t *p, __m128i a) {
      std::memcpy(p, &amp;a, sizeof(a));
  }
  </code></pre>
  
  <p>This works and is perfectly valid... I think. But it emits frankly terrible code on my system. GCC spills <code>a</code> to an aligned stack slot via an aligned store, then manually moves the component words to the destination. (Actually it spills it twice, once for each component. Very strange.)</p>
  
  <p>...</p>
  
  <p>Is there any way to write this function that will (a) generate optimal code on a typical modern compiler and (b) have minimal risk of running afoul of strict aliasing?</p>