From 6c9df5a0014040115ebe576c4c0b7914a0414422 Mon Sep 17 00:00:00 2001
From: Richard Guenther <rguenther@suse.de>
Date: Wed, 4 Jul 2012 12:10:40 +0000
Subject: [PATCH] re PR middle-end/53844 (GCC generates suboptimal code for
 unused members of classes in some cases on multiple targets.)

2012-07-04  Richard Guenther  <rguenther@suse.de>

	PR tree-optimization/53844
	* tree-ssa-dse.c (dse_possible_dead_store_p): Properly handle
	the loop virtual PHI.

	* g++.dg/tree-ssa/pr53844.C: New testcase.

From-SVN: r189256
---
 gcc/ChangeLog                           |  6 ++
 gcc/testsuite/ChangeLog                 |  5 ++
 gcc/testsuite/g++.dg/tree-ssa/pr53844.C | 78 +++++++++++++++++++++++++
 gcc/tree-ssa-dse.c                      | 12 +++-
 4 files changed, 99 insertions(+), 2 deletions(-)
 create mode 100644 gcc/testsuite/g++.dg/tree-ssa/pr53844.C

diff --git a/gcc/ChangeLog b/gcc/ChangeLog
index 27c8cfcaa071..c33c5a5b4b04 100644
--- a/gcc/ChangeLog
+++ b/gcc/ChangeLog
@@ -1,3 +1,9 @@
+2012-07-04  Richard Guenther  <rguenther@suse.de>
+
+	PR tree-optimization/53844
+	* tree-ssa-dse.c (dse_possible_dead_store_p): Properly handle
+	the loop virtual PHI.
+
 2012-07-04  Richard Guenther  <rguenther@suse.de>
 
 	PR tree-optimization/53849
diff --git a/gcc/testsuite/ChangeLog b/gcc/testsuite/ChangeLog
index 884f66bfa4ec..3d1fda9e16ca 100644
--- a/gcc/testsuite/ChangeLog
+++ b/gcc/testsuite/ChangeLog
@@ -1,3 +1,8 @@
+2012-07-04  Richard Guenther  <rguenther@suse.de>
+
+	PR tree-optimization/53844
+	* g++.dg/tree-ssa/pr53844.C: New testcase.
+
 2012-07-04  Richard Guenther  <rguenther@suse.de>
 
 	PR tree-optimization/53849
diff --git a/gcc/testsuite/g++.dg/tree-ssa/pr53844.C b/gcc/testsuite/g++.dg/tree-ssa/pr53844.C
new file mode 100644
index 000000000000..0be29d86cbfe
--- /dev/null
+++ b/gcc/testsuite/g++.dg/tree-ssa/pr53844.C
@@ -0,0 +1,78 @@
+// { dg-do compile }
+// { dg-options "-O2 -fdump-tree-optimized-vops" }
+
+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" } }
+// { dg-final { cleanup-tree-dump "optimized" } }
diff --git a/gcc/tree-ssa-dse.c b/gcc/tree-ssa-dse.c
index 5fdba8c543be..04cc6ad5009c 100644
--- a/gcc/tree-ssa-dse.c
+++ b/gcc/tree-ssa-dse.c
@@ -94,7 +94,7 @@ dse_possible_dead_store_p (gimple stmt, gimple *use_stmt)
   temp = stmt;
   do
     {
-      gimple use_stmt;
+      gimple use_stmt, defvar_def;
       imm_use_iterator ui;
       bool fail = false;
       tree defvar;
@@ -108,6 +108,7 @@ dse_possible_dead_store_p (gimple stmt, gimple *use_stmt)
 	defvar = PHI_RESULT (temp);
       else
 	defvar = gimple_vdef (temp);
+      defvar_def = temp;
       temp = NULL;
       FOR_EACH_IMM_USE_STMT (use_stmt, ui, defvar)
 	{
@@ -139,7 +140,14 @@ dse_possible_dead_store_p (gimple stmt, gimple *use_stmt)
 		  fail = true;
 		  BREAK_FROM_IMM_USE_STMT (ui);
 		}
-	      temp = use_stmt;
+	      /* Do not consider the PHI as use if it dominates the 
+	         stmt defining the virtual operand we are processing,
+		 we have processed it already in this case.  */
+	      if (gimple_bb (defvar_def) != gimple_bb (use_stmt)
+		  && !dominated_by_p (CDI_DOMINATORS,
+				      gimple_bb (defvar_def),
+				      gimple_bb (use_stmt)))
+		temp = use_stmt;
 	    }
 	  /* If the statement is a use the store is not dead.  */
 	  else if (ref_maybe_used_by_stmt_p (use_stmt,
-- 
GitLab