From cc603b4051d06937fbb33e1e591a444ab06cb8e0 Mon Sep 17 00:00:00 2001
From: Jakub Jelinek <jakub@redhat.com>
Date: Wed, 9 May 2012 14:19:34 +0200
Subject: [PATCH] re PR tree-optimization/53226 (Endless loop in forwprop)

	PR tree-optimization/53226
	* tree-ssa-forwprop.c (ssa_forward_propagate_and_combine): Remove
	prev and prev_initialized vars, gimple_set_plf (stmt, GF_PLF_1, false)
	before processing it and gimple_set_plf (stmt, GF_PLF_1, true) if it
	doesn't need to be revisited, look for earliest stmt with
	!gimple_plf (stmt, GF_PLF_1) if something changed.

	* gcc.c-torture/compile/pr53226.c: New test.

From-SVN: r187328
---
 gcc/ChangeLog                                 |  9 ++++++++
 gcc/testsuite/ChangeLog                       |  5 +++++
 gcc/testsuite/gcc.c-torture/compile/pr53226.c | 13 ++++++++++++
 gcc/tree-ssa-forwprop.c                       | 21 ++++++++++---------
 4 files changed, 38 insertions(+), 10 deletions(-)
 create mode 100644 gcc/testsuite/gcc.c-torture/compile/pr53226.c

diff --git a/gcc/ChangeLog b/gcc/ChangeLog
index 49670046a0f5..b96afa0803c2 100644
--- a/gcc/ChangeLog
+++ b/gcc/ChangeLog
@@ -1,3 +1,12 @@
+2012-05-09  Jakub Jelinek  <jakub@redhat.com>
+
+	PR tree-optimization/53226
+	* tree-ssa-forwprop.c (ssa_forward_propagate_and_combine): Remove
+	prev and prev_initialized vars, gimple_set_plf (stmt, GF_PLF_1, false)
+	before processing it and gimple_set_plf (stmt, GF_PLF_1, true) if it
+	doesn't need to be revisited, look for earliest stmt with
+	!gimple_plf (stmt, GF_PLF_1) if something changed.
+
 2012-05-09  Terry Guo  <terry.guo@arm.com>
 
 	* genmultilib: Update copyright dates.
diff --git a/gcc/testsuite/ChangeLog b/gcc/testsuite/ChangeLog
index 0b739da17bef..84c31a066762 100644
--- a/gcc/testsuite/ChangeLog
+++ b/gcc/testsuite/ChangeLog
@@ -1,3 +1,8 @@
+2012-05-09  Jakub Jelinek  <jakub@redhat.com>
+
+	PR tree-optimization/53226
+	* gcc.c-torture/compile/pr53226.c: New test.
+
 2012-05-09  Rainer Orth  <ro@CeBiTec.Uni-Bielefeld.DE>
 
 	* gcc.target/i386/hle-add-acq-1.c: Allow for ; after lock.
diff --git a/gcc/testsuite/gcc.c-torture/compile/pr53226.c b/gcc/testsuite/gcc.c-torture/compile/pr53226.c
new file mode 100644
index 000000000000..2d0284fb006d
--- /dev/null
+++ b/gcc/testsuite/gcc.c-torture/compile/pr53226.c
@@ -0,0 +1,13 @@
+/* PR tree-optimization/53226 */
+
+void
+foo (unsigned long *x, char y, char z)
+{
+  int i;
+  for (i = y; i < z; ++i)
+    {
+      unsigned long a = ((unsigned char) i) & 63UL;
+      unsigned long b = 1ULL << a;
+      *x |= b;
+    }
+}
diff --git a/gcc/tree-ssa-forwprop.c b/gcc/tree-ssa-forwprop.c
index e14627d9f3a1..3c01623130ca 100644
--- a/gcc/tree-ssa-forwprop.c
+++ b/gcc/tree-ssa-forwprop.c
@@ -2677,8 +2677,7 @@ ssa_forward_propagate_and_combine (void)
 
   FOR_EACH_BB (bb)
     {
-      gimple_stmt_iterator gsi, prev;
-      bool prev_initialized;
+      gimple_stmt_iterator gsi;
 
       /* Apply forward propagation to all stmts in the basic-block.
 	 Note we update GSI within the loop as necessary.  */
@@ -2771,12 +2770,14 @@ ssa_forward_propagate_and_combine (void)
 
       /* Combine stmts with the stmts defining their operands.
 	 Note we update GSI within the loop as necessary.  */
-      prev_initialized = false;
       for (gsi = gsi_start_bb (bb); !gsi_end_p (gsi);)
 	{
 	  gimple stmt = gsi_stmt (gsi);
 	  bool changed = false;
 
+	  /* Mark stmt as potentially needing revisiting.  */
+	  gimple_set_plf (stmt, GF_PLF_1, false);
+
 	  switch (gimple_code (stmt))
 	    {
 	    case GIMPLE_ASSIGN:
@@ -2856,18 +2857,18 @@ ssa_forward_propagate_and_combine (void)
 	    {
 	      /* If the stmt changed then re-visit it and the statements
 		 inserted before it.  */
-	      if (!prev_initialized)
+	      for (; !gsi_end_p (gsi); gsi_prev (&gsi))
+		if (gimple_plf (gsi_stmt (gsi), GF_PLF_1))
+		  break;
+	      if (gsi_end_p (gsi))
 		gsi = gsi_start_bb (bb);
 	      else
-		{
-		  gsi = prev;
-		  gsi_next (&gsi);
-		}
+		gsi_next (&gsi);
 	    }
 	  else
 	    {
-	      prev = gsi;
-	      prev_initialized = true;
+	      /* Stmt no longer needs to be revisited.  */
+	      gimple_set_plf (stmt, GF_PLF_1, true);
 	      gsi_next (&gsi);
 	    }
 	}
-- 
GitLab