I'm using gcc-4.5.0-1 of MinGW with Intel x86. When I execute the following test code with '-O -msse' compiler options, it outputs the wrong value. I'm expecting that v2.e[3] will be 7.0f.
And, when I exclude LINE_A, LINE_B, LINE_C or LINE_D as a comment, the program outputs the expected value. -- begin test code -- // g++ -O -msse test.cpp typedef float __m128 __attribute__ ((__vector_size__ (16), __may_alias__)); typedef float __v4sf __attribute__ ((__vector_size__ (16))); extern __inline __m128 __attribute__((__gnu_inline__, __always_inline__, __artificial__)) _mm_set_ps (const float __Z, const float __Y, const float __X, const float __W) { return __extension__ (__m128)(__v4sf){ __W, __X, __Y, __Z }; } struct vec { union { __m128 v; float e[4]; }; static const vec & zero() { static const vec v = _mm_set_ps(0, 0, 0, 0); return v; } vec() {} vec(const __m128 & a) : v(a) {} operator const __m128&() const { return v; } }; struct vec2 { vec _v1; vec _v2; vec2() {} vec2(const vec & a, const vec & b) : _v1(a), _v2(b) {} static vec2 load(const float * a) { return vec2( __builtin_ia32_loadups(&a[0]), __builtin_ia32_loadups(&a[4])); } const vec & v1() const { return _v1; } const vec & v2() const { return _v2; } }; extern "C" { int* _errno(void); int printf (const char*, ...); } inline bool test_assert( bool is_succeed, const char * file_name, int line_num ) { if ( !is_succeed ) { printf("error: %s(%d)\n", file_name, line_num); if ( *_errno() ) // LINE_A { printf("errno: %d\n", *_errno()); } } return is_succeed; } inline bool operator==(const vec & a, const vec & b) { return 0xf == __builtin_ia32_movmskps(__builtin_ia32_cmpeqps(a, b)); } #define test(x, y) test_assert( (x)==(y), __FILE__, __LINE__ ) int main( int argc, char * argv[] ) { __attribute__((aligned(16))) float data[] = { 16, 15, 14, 13, 12, 11, 10, 9, 8, 7, 6, 5 }; float * p = &data[2]; vec2 a; a = vec2::load(p); vec v1 = a.v1(); vec v2 = a.v2(); printf( "v1: %f, %f, %f, %f\n" "v2: %f, %f, %f, %f\n", v1.e[0], v1.e[1], v1.e[2], v1.e[3], v2.e[0], v2.e[1], v2.e[2], v2.e[3]); test(_mm_set_ps(11, 12, 13, 14), a.v1()); // LINE_B test(_mm_set_ps( 7, 8, 9, 10), a.v2()); // LINE_C a._v1 = vec::zero(); test(_mm_set_ps(0, 0, 0, 0), a.v1()); // LINE_D return 0; } -- end test code -- -- begin output -- v1: 14.000000, 13.000000, 12.000000, 11.000000 v2: 10.000000, 9.000000, 8.000000, 0.000000 error: test.cpp(92) -- end output -- -- Summary: The variable of SSE will be broken Product: gcc Version: 4.5.0 Status: UNCONFIRMED Severity: normal Priority: P3 Component: c++ AssignedTo: unassigned at gcc dot gnu dot org ReportedBy: yottui at yahoo dot co dot jp http://gcc.gnu.org/bugzilla/show_bug.cgi?id=44900