1 // { dg-do compile } 2 // { dg-options "-O2 -fdump-tree-optimized-vops" } 3 4 struct VBase; 5 6 //Very minimal numeric vector class where Base provides the policy 7 template<typename Base=VBase> 8 struct Vector : public Base{ 9 VectorVector10 inline Vector(const Base& b) 11 :Base(b) 12 { 13 } 14 15 //Assignment from any other sort of Vector 16 template<typename Base2> 17 void operator= (const Vector<Base2>& from) 18 { 19 for(int i=0; i<100; i++){ 20 (*this)[i]=from[i]; 21 } 22 } 23 }; 24 25 26 //Base class to represent pointer as a Vector 27 struct VBase{ 28 double * const my_data; 29 30 double& operator[](int i) { 31 return my_data[i]; 32 } 33 34 const double& operator[](int i) const { 35 return my_data[i]; 36 } 37 }; 38 39 //Base class providing very minimalistic expression template 40 template<class B2> struct ScalarMulExpr 41 { 42 const int& mul; 43 const Vector<B2>& vec; 44 sizeScalarMulExpr45 int size() const 46 { 47 return vec.size(); 48 } 49 50 double operator[](int i) const 51 { 52 return vec[i]*mul; 53 } 54 ScalarMulExprScalarMulExpr55 ScalarMulExpr(const Vector<B2>& vec_, const int& m) 56 :mul(m),vec(vec_) 57 { 58 } 59 }; 60 61 //Allow vector to be multiplied by a scalar 62 template<class B2> 63 Vector<ScalarMulExpr<B2> > operator*(const Vector<B2>& lhs, const int& rhs) 64 { 65 return ScalarMulExpr<B2>(lhs, rhs); 66 } 67 68 //Test function producing suboptimal asm code test(const Vector<> & in,Vector<> & out,int i)69void test(const Vector<>& in, Vector<>& out, int i) 70 { 71 out=in*1*1*1*1*1*1*1*1*1*1*1; 72 } 73 74 // There should be a single store remaining, inside the loops. All 75 // dead stores to unused temporaries should have been removed. 76 77 // { dg-final { scan-tree-dump-times "VDEF" 1 "optimized" } } 78 // { dg-final { cleanup-tree-dump "optimized" } } 79