https://gcc.gnu.org/bugzilla/show_bug.cgi?id=80652
Bug ID: 80652 Summary: Union conversion between __m128d and double array does not work under 5.0 through 6.2 Product: gcc Version: 6.2.0 Status: UNCONFIRMED Severity: normal Priority: P3 Component: c++ Assignee: unassigned at gcc dot gnu.org Reporter: paboyle at ph dot ed.ac.uk Target Milestone: --- Union conversion between __m128d and double array does not work under -O3 for g++ versions 5.0 to 6.2. Compiled with -std=c++11 -O3 . https://wandbox.org/permlink/tzssJza6R9XnqANw Code: #include <iostream> #include <complex> #include <pmmintrin.h> template <class Scalar_type, class Vector_type> class simd { public: typedef Vector_type vector_type; typedef Scalar_type scalar_type; typedef union conv_t_union { Vector_type v; Scalar_type s[sizeof(Vector_type) / sizeof(Scalar_type)]; conv_t_union(){}; } conv_t; static inline constexpr int Nsimd(void) { return sizeof(Vector_type) / sizeof(Scalar_type); } Vector_type v; template <class functor> friend inline simd SimdApply(const functor &func, const simd &v) { simd ret; simd::conv_t conv; conv.v = v.v; for (int i = 0; i < simd::Nsimd(); i++) { conv.s[i] = func(conv.s[i]); } ret.v = conv.v; return ret; } }; template <class scalar> struct RealFunctor { scalar operator()(const scalar &a) const { return std::real(a); } }; template <class S, class V> inline simd<S, V> real(const simd<S, V> &r) { return SimdApply(RealFunctor<S>(), r); } typedef simd<std::complex<double>, __m128d> vcomplexd; int main(int argc, char **argv) { vcomplexd a,b; a.v=_mm_set_pd(2.0,1.0); b = real(a); vcomplexd::conv_t conv; conv.v = b.v; for(int i=0;i<vcomplexd::Nsimd();i++){ std::cout << conv.s[i]<<" "; } std::cout << std::endl; }