// { dg-do compile } // { dg-options "-O2 -fdump-tree-optimized-vops" } struct VBase; //Very minimal numeric vector class where Base provides the policy template struct Vector : public Base{ inline Vector(const Base& b) :Base(b) { } //Assignment from any other sort of Vector template void operator= (const Vector& from) { for(int i=0; i<100; i++){ (*this)[i]=from[i]; } } }; //Base class to represent pointer as a Vector struct VBase{ double * const my_data; double& operator[](int i) { return my_data[i]; } const double& operator[](int i) const { return my_data[i]; } }; //Base class providing very minimalistic expression template template struct ScalarMulExpr { const int& mul; const Vector& vec; int size() const { return vec.size(); } double operator[](int i) const { return vec[i]*mul; } ScalarMulExpr(const Vector& vec_, const int& m) :mul(m),vec(vec_) { } }; //Allow vector to be multiplied by a scalar template Vector > operator*(const Vector& lhs, const int& rhs) { return ScalarMulExpr(lhs, rhs); } //Test function producing suboptimal asm code void test(const Vector<>& in, Vector<>& out, int i) { out=in*1*1*1*1*1*1*1*1*1*1*1; } // There should be a single store remaining, inside the loops. All // dead stores to unused temporaries should have been removed. // { dg-final { scan-tree-dump-times "VDEF" 1 "optimized" } } // { dg-final { cleanup-tree-dump "optimized" } }