1// { dg-do compile } 2// { dg-options "-O2 -fstrict-aliasing -fdump-tree-pre-details" } 3 4// Make sure we hoist invariants out of the loop even in the presence 5// of placement new. This is similar to code in tramp3d. 6 7typedef __SIZE_TYPE__ size_t; 8 9inline void* operator new(size_t, void* __p) throw() { return __p; } 10 11template <class T, int D> 12class Vector 13{ 14public: 15 Vector() 16 { 17 for (int i = 0; i < D; ++i) 18 new (&x_m[i]) T(); 19 } 20 T& operator[](int i) { return x_m[i]; } 21 22private: 23 T x_m[D]; 24}; 25 26struct sia 27{ 28 int ai[3]; 29}; 30 31struct s 32{ 33 struct si 34 { 35 sia* p; 36 } asi[3]; 37 float* pd; 38}; 39 40class c 41{ 42 int foo(int, int, int); 43 s sm; 44}; 45 46 47extern void bar(Vector<float, 3>*, int); 48int c::foo(int f1, int f2, int f3) 49{ 50 float sum = 0; 51 for (int i = 0; i < 3; ++i) 52 { 53 for (int j = 0; j < 3; ++j) 54 { 55 Vector<float, 3> v; 56 v[0] = 1.0; 57 v[1] = 2.0; 58 v[2] = 3.0; 59 for (int k = 0; k < 3; ++k) 60 { 61 float f = (f1 * this->sm.asi[0].p->ai[0] 62 + f2 * this->sm.asi[1].p->ai[0] 63 + f3 * this->sm.asi[2].p->ai[0]); 64 sum += f * v[k]; 65 } 66 *this->sm.pd = sum; 67 } 68 } 69 return sum; 70} 71 72// { dg-final { scan-tree-dump "Replaced.*->ai\\\[0\\\]" "pre" } } 73// { dg-final { cleanup-tree-dump "pre" } } 74