diff mbox

Fix PR53844

Message ID alpine.LNX.2.00.1207041404000.17233@jbgna.fhfr.qr
State New
Headers show

Commit Message

Richard Biener July 4, 2012, 12:05 p.m. UTC
This fixes a missed dead store elimination case.  We were not
properly disregarding a loop PHI use we have already visited.

Bootstrapped and tested on x86_64-unknown-linux-gnu, applied.

Richard.

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.
diff mbox

Patch

Index: gcc/tree-ssa-dse.c
===================================================================
--- gcc/tree-ssa-dse.c	(revision 189248)
+++ gcc/tree-ssa-dse.c	(working copy)
@@ -94,7 +94,7 @@  dse_possible_dead_store_p (gimple 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,
 	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,
 		  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,
Index: gcc/testsuite/g++.dg/tree-ssa/pr53844.C
===================================================================
--- gcc/testsuite/g++.dg/tree-ssa/pr53844.C	(revision 0)
+++ gcc/testsuite/g++.dg/tree-ssa/pr53844.C	(working copy)
@@ -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" } }