tree-optimization/125040 - iterate PRE clean

The testcase has a cycle in the value graph of ANTIC_IN, this means
we have to iterate to correctly prune all invalid expressions.

	PR tree-optimization/125040
	* tree-ssa-pre.cc (clean): Iterate processing.

	* gcc.dg/torture/pr125040.c: New testcase.
diff --git a/gcc/testsuite/gcc.dg/torture/pr125040.c b/gcc/testsuite/gcc.dg/torture/pr125040.c
new file mode 100644
index 0000000..be73208
--- /dev/null
+++ b/gcc/testsuite/gcc.dg/torture/pr125040.c
@@ -0,0 +1,14 @@
+/* { dg-do compile } */
+
+int a() {
+  int b;
+  int *c = __builtin_calloc(sizeof(int), b);
+  int count;
+  for (int d; d;)
+    for (int e;; b++) {
+      c[e] = c[b - count - 1];
+      c[b - count - 1] = count;
+      count = count + 1;
+    }
+  __builtin_printf("", c);
+}
diff --git a/gcc/tree-ssa-pre.cc b/gcc/tree-ssa-pre.cc
index cc182f6..79f1639 100644
--- a/gcc/tree-ssa-pre.cc
+++ b/gcc/tree-ssa-pre.cc
@@ -2171,22 +2171,38 @@
 clean (bitmap_set_t set1, bitmap_set_t set2 = NULL)
 {
   vec<pre_expr> exprs = sorted_array_from_bitmap_set (set1, false);
-  pre_expr expr;
-  int i;
+  bool changed;
 
-  FOR_EACH_VEC_ELT (exprs, i, expr)
+  do
     {
-      if (!valid_in_sets (set1, set2, expr))
+      unsigned j = 0;
+      changed = false;
+      for (unsigned i = 0; i < exprs.length (); ++i)
 	{
-	  unsigned int val  = get_expr_value_id (expr);
-	  bitmap_clear_bit (&set1->expressions, get_expression_id (expr));
-	  /* We are entered with possibly multiple expressions for a value
-	     so before removing a value from the set see if there's an
-	     expression for it left.  */
-	  if (! bitmap_find_leader (set1, val))
-	    bitmap_clear_bit (&set1->values, val);
+	  pre_expr expr = exprs[i];
+	  if (!valid_in_sets (set1, set2, expr))
+	    {
+	      unsigned int val = get_expr_value_id (expr);
+	      bitmap_clear_bit (&set1->expressions, get_expression_id (expr));
+	      /* We are entered with possibly multiple expressions for a value
+		 so before removing a value from the set see if there's an
+		 expression for it left.  */
+	      if (! bitmap_find_leader (set1, val))
+		{
+		  bitmap_clear_bit (&set1->values, val);
+		  changed = true;
+		}
+	    }
+	  else
+	    {
+	      exprs[j] = expr;
+	      ++j;
+	    }
 	}
+      exprs.truncate (j);
     }
+  /* As the value graph can have cycles we have to iterate here.  */
+  while (changed);
   exprs.release ();
 
   if (flag_checking)