Alexey Dokuchaev
2013-Nov-22 09:20 UTC
[LLVMdev] [clang] SSE2 intrinsics (emmintrin.h): _mm_movpi64_pi64 should be _mm_movpi64_epi64?
Hi there, I've recently encountered a piece of code that uses some SSE2 intrinsics and builds with gcc46, but not clang: clang can't find _mm_movpi64_epi64(), while gcc46 defines it in its lib/gcc46/gcc/.../4.6.3/include/emmintrin.h: extern __inline __m128i __attribute__((__gnu_inline__, __always_inline__, __artificial__)) _mm_movpi64_epi64 (__m64 __A) { return _mm_set_epi64 ((__m64)0LL, __A); } extern __inline __m128i __attribute__((__gnu_inline__, __always_inline__, __artificial__)) _mm_set_epi64x (long long __q1, long long __q0) { return __extension__ (__m128i)(__v2di){ __q0, __q1 }; } Now, Clang in /usr/include/clang/3.3/emmintrin.h defines similar function, but without the `e', _mm_movpi64_pi64(): static __inline__ __m128i __attribute__((__always_inline__, __nodebug__)) _mm_movpi64_pi64(__m64 __a) { return (__m128i){ (long long)__a, 0 }; } Microsoft (http://msdn.microsoft.com/en-us/library/has3d153(v=vs.90).aspx) defines these two: _mm_movepi64_pi64 MOVDQ2Q Move _mm_movpi64_epi64 MOVQ2DQ Move That is: __m64 _mm_movepi64_pi64 (__m128i a); MOVDQ2Q r0 := a0 ; __m128i _mm_movpi64_epi64 (__m64 a); MOVDQ2Q r0 := a0 ; r1 := 0X0 ; Cf. Intel's manual [1]: _mm_movepi64_pi64 Move MOVDQ2Q _mm_movpi64_epi64 Move MOVDQ2Q __m64 _mm_movepi64_pi64(__m128i a) Returns the lower 64 bits of a as an __m64 type: R0 := a0 __m128i _mm_movpi64_pi64(__m64 a) <<< TYPO?! Moves the 64 bits of a to the lower 64 bits of the result, zeroing the upper bits: R0 := a0, R1 = 0X0 Assuming that both documents correctly assign instructions to function names (bonus clue: it also makes them symmetrical), then _mm_movpi64_pi64 is indeed a typo and Clang's header is wrong, while GCC's is correct: it should read _mm_movpi64_epi64(), not _mm_movpi64_pi64(). ./danfe [1] http://software.intel.com/sites/products/documentation/doclib/iss/2013/compiler/cpp-lin/GUID-AFA947A7-8490-443B-9946-C7B16C8E6244.htm