Do you have any horror stories to tell? The GCC Manual recently added a warning regarding -fstrict-aliasing and casting a pointer through a union:
[.
Here is mine: In think this is a bug in all GCC v5.x and later
#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;
}
Should give
c010200:~ peterboyle$ g++-mp-5 Gcc-test.cc -std=c++11
c010200:~ peterboyle$ ./a.out
(1,0)
But under -O3: I THINK THIS IS WRONG AND A COMPILER ERROR
c010200:~ peterboyle$ g++-mp-5 Gcc-test.cc -std=c++11 -O3
c010200:~ peterboyle$ ./a.out
(0,0)
Under g++4.9
c010200:~ peterboyle$ g++-4.9 Gcc-test.cc -std=c++11 -O3
c010200:~ peterboyle$ ./a.out
(1,0)
Under llvm xcode
c010200:~ peterboyle$ g++ Gcc-test.cc -std=c++11 -O3
c010200:~ peterboyle$ ./a.out
(1,0)