// { dg-do compile } // { dg-options "-O2 -fdump-tree-optimized-vops -fno-inline-functions --param max-inline-insns-single=200" } struct VBase; //Very minimal numeric vector class where Base provides the policy template<typename Base=VBase> struct Vector : public Base{ inline Vector(const Base& b) :Base(b) { } //Assignment from any other sort of Vector template<typename Base2> void operator= (const Vector<Base2>& 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<class B2> struct ScalarMulExpr { const int& mul; const Vector<B2>& vec; int size() const { return vec.size(); } double operator[](int i) const { return vec[i]*mul; } ScalarMulExpr(const Vector<B2>& vec_, const int& m) :mul(m),vec(vec_) { } }; //Allow vector to be multiplied by a scalar template<class B2> Vector<ScalarMulExpr<B2> > operator*(const Vector<B2>& lhs, const int& rhs) { return ScalarMulExpr<B2>(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" } }