blob: aab58ff706b9835d1d9ab1100751eab8923c9c21 [file] [log] [blame]
// { dg-do compile }
// { dg-options "-O2 -fstrict-aliasing -fdump-tree-pre-details" }
// Make sure we hoist invariants out of the loop even in the presence
// of placement new. This is similar to code in tramp3d.
typedef __SIZE_TYPE__ size_t;
inline void* operator new(size_t, void* __p) throw() { return __p; }
template <class T, int D>
class Vector
{
public:
Vector()
{
for (int i = 0; i < D; ++i)
new (&x_m[i]) T();
}
T& operator[](int i) { return x_m[i]; }
private:
T x_m[D];
};
struct sia
{
int ai[3];
};
struct s
{
struct si
{
sia* p;
} asi[3];
float* pd;
};
class c
{
int foo(int, int, int);
s sm;
};
extern void bar(Vector<float, 3>*, int);
int c::foo(int f1, int f2, int f3)
{
float sum = 0;
for (int i = 0; i < 3; ++i)
{
for (int j = 0; j < 3; ++j)
{
Vector<float, 3> v;
v[0] = 1.0;
v[1] = 2.0;
v[2] = 3.0;
for (int k = 0; k < 3; ++k)
{
float f = (f1 * this->sm.asi[0].p->ai[0]
+ f2 * this->sm.asi[1].p->ai[0]
+ f3 * this->sm.asi[2].p->ai[0]);
sum += f * v[k];
}
*this->sm.pd = sum;
}
}
return sum;
}
// { dg-final { scan-tree-dump "Replaced.*->ai\\\[0\\\]" "pre" } }