The following backports limiting match.pd recursion together with a
new testcase, also applied to trunk.

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

2018-10-19  Richard Biener  <rguent...@suse.de>

        PR middle-end/87645
        Backport from mainline
        2018-07-12  Richard Biener  <rguent...@suse.de>

        * tree-ssa-sccvn.c (mprts_hook_cnt): Remove.
        (vn_lookup_simplify_result): Remove recursion limit applied
        here.
        (vn_nary_build_or_lookup_1): Adjust.
        (try_to_simplify): Likewise.
        * gimple-match-head.c (gimple_resimplify1): Instead apply one
        here.
        (gimple_resimplify2): Likewise.
        (gimple_resimplify3): Likewise.
        (gimple_resimplify4): Likewise.

        * gcc.dg/torture/pr87645.c: New testcase.

Index: gcc/tree-ssa-sccvn.c
===================================================================
--- gcc/tree-ssa-sccvn.c        (revision 265312)
+++ gcc/tree-ssa-sccvn.c        (working copy)
@@ -1650,7 +1650,6 @@ vn_reference_lookup_or_insert_for_pieces
 }
 
 static vn_nary_op_t vn_nary_op_insert_stmt (gimple *stmt, tree result);
-static unsigned mprts_hook_cnt;
 
 /* Hook for maybe_push_res_to_seq, lookup the expression in the VN tables.  */
 
@@ -1672,22 +1671,8 @@ vn_lookup_simplify_result (code_helper r
        ops[i] = CONSTRUCTOR_ELT (ops_[0], i)->value;
     }
   vn_nary_op_t vnresult = NULL;
-  tree res = vn_nary_op_lookup_pieces (length, (tree_code) rcode,
-                                      type, ops, &vnresult);
-  /* We can end up endlessly recursing simplifications if the lookup above
-     presents us with a def-use chain that mirrors the original simplification.
-     See PR80887 for an example.  Limit successful lookup artificially
-     to 10 times if we are called as mprts_hook.  */
-  if (res
-      && mprts_hook
-      && --mprts_hook_cnt == 0)
-    {
-      if (dump_file && (dump_flags & TDF_DETAILS))
-       fprintf (dump_file, "Resetting mprts_hook after too many "
-                "invocations.\n");
-      mprts_hook = NULL;
-    }
-  return res;
+  return vn_nary_op_lookup_pieces (length, (tree_code) rcode,
+                                  type, ops, &vnresult);
 }
 
 /* Return a value-number for RCODE OPS... either by looking up an existing
@@ -1704,7 +1689,6 @@ vn_nary_build_or_lookup_1 (code_helper r
      So first simplify and lookup this expression to see if it
      is already available.  */
   mprts_hook = vn_lookup_simplify_result;
-  mprts_hook_cnt = 9;
   bool res = false;
   switch (TREE_CODE_LENGTH ((tree_code) rcode))
     {
@@ -3979,7 +3963,6 @@ try_to_simplify (gassign *stmt)
 
   /* First try constant folding based on our current lattice.  */
   mprts_hook = vn_lookup_simplify_result;
-  mprts_hook_cnt = 9;
   tem = gimple_fold_stmt_to_constant_1 (stmt, vn_valueize, vn_valueize);
   mprts_hook = NULL;
   if (tem
Index: gcc/gimple-match-head.c
===================================================================
--- gcc/gimple-match-head.c     (revision 265312)
+++ gcc/gimple-match-head.c     (working copy)
@@ -100,17 +100,34 @@ gimple_resimplify1 (gimple_seq *seq,
        }
     }
 
+  /* Limit recursion, there are cases like PR80887 and others, for
+     example when value-numbering presents us with unfolded expressions
+     that we are really not prepared to handle without eventual
+     oscillation like ((_50 + 0) + 8) where _50 gets mapped to _50
+     itself as available expression.  */
+  static unsigned depth;
+  if (depth > 10)
+    {
+      if (dump_file && (dump_flags & TDF_FOLDING))
+       fprintf (dump_file, "Aborting expression simplification due to "
+                "deep recursion\n");
+      return false;
+    }
+
+  ++depth;
   code_helper res_code2;
   tree res_ops2[3] = {};
   if (gimple_simplify (&res_code2, res_ops2, seq, valueize,
                       *res_code, type, res_ops[0]))
     {
+      --depth;
       *res_code = res_code2;
       res_ops[0] = res_ops2[0];
       res_ops[1] = res_ops2[1];
       res_ops[2] = res_ops2[2];
       return true;
     }
+  --depth;
 
   return false;
 }
@@ -160,17 +177,30 @@ gimple_resimplify2 (gimple_seq *seq,
       canonicalized = true;
     }
 
+  /* Limit recursion, see gimple_resimplify1.  */
+  static unsigned depth;
+  if (depth > 10)
+    {
+      if (dump_file && (dump_flags & TDF_FOLDING))
+       fprintf (dump_file, "Aborting expression simplification due to "
+                "deep recursion\n");
+      return false;
+    }
+
+  ++depth;
   code_helper res_code2;
   tree res_ops2[3] = {};
   if (gimple_simplify (&res_code2, res_ops2, seq, valueize,
                       *res_code, type, res_ops[0], res_ops[1]))
     {
+      --depth;
       *res_code = res_code2;
       res_ops[0] = res_ops2[0];
       res_ops[1] = res_ops2[1];
       res_ops[2] = res_ops2[2];
       return true;
     }
+  --depth;
 
   return canonicalized;
 }
@@ -219,18 +249,31 @@ gimple_resimplify3 (gimple_seq *seq,
       canonicalized = true;
     }
 
+  /* Limit recursion, see gimple_resimplify1.  */
+  static unsigned depth;
+  if (depth > 10)
+    {
+      if (dump_file && (dump_flags & TDF_FOLDING))
+       fprintf (dump_file, "Aborting expression simplification due to "
+                "deep recursion\n");
+      return false;
+    }
+
+  ++depth;
   code_helper res_code2;
   tree res_ops2[3] = {};
   if (gimple_simplify (&res_code2, res_ops2, seq, valueize,
                       *res_code, type,
                       res_ops[0], res_ops[1], res_ops[2]))
     {
+      --depth;
       *res_code = res_code2;
       res_ops[0] = res_ops2[0];
       res_ops[1] = res_ops2[1];
       res_ops[2] = res_ops2[2];
       return true;
     }
+  --depth;
 
   return canonicalized;
 }
Index: gcc/testsuite/gcc.dg/torture/pr87645.c
===================================================================
--- gcc/testsuite/gcc.dg/torture/pr87645.c      (nonexistent)
+++ gcc/testsuite/gcc.dg/torture/pr87645.c      (working copy)
@@ -0,0 +1,21 @@
+/* { dg-do compile } */
+
+typedef unsigned a[8];
+a b, g;
+int c, d, e, f;
+int h() {
+    unsigned i = 2;
+    for (; i < 8; i++)
+      b[i] = 0;
+    for (; f;) {
+       d = 1;
+       for (; d < 14; d += 3) {
+           e = 0;
+           for (; e < 8; e++) {
+               i = 2;
+               for (; i < 8; i++)
+                 b[i] = 5 - (c - g[e] + b[i]);
+           }
+       }
+    }
+}

Reply via email to