From cdd4b0d464c4873e72866d5bb9dc239141a20e28 Mon Sep 17 00:00:00 2001
From: Arend Bayer <arend.bayer@web.de>
Date: Sun, 16 Feb 2003 08:24:25 +0000
Subject: [PATCH] fold-const.c (extract_muldiv_1): Rename from extract_muldiv;
 rearrange mult arguments for less recursion.

        * fold-const.c (extract_muldiv_1): Rename from extract_muldiv;
        rearrange mult arguments for less recursion.
        (extract_muldiv): New.  Prevent runaway recursion.

Co-Authored-By: Richard Henderson <rth@redhat.com>

From-SVN: r62963
---
 gcc/ChangeLog    |  7 +++++++
 gcc/fold-const.c | 34 ++++++++++++++++++++++++++++++++++
 2 files changed, 41 insertions(+)

diff --git a/gcc/ChangeLog b/gcc/ChangeLog
index 3f8587cdc2bd..235712403245 100644
--- a/gcc/ChangeLog
+++ b/gcc/ChangeLog
@@ -1,3 +1,10 @@
+2003-02-16 Arend Bayer <arend.bayer@web.de>
+	   Richard Henderson  <rth@redhat.com>
+
+	* fold-const.c (extract_muldiv_1): Rename from extract_muldiv;
+	rearrange mult arguments for less recursion.
+	(extract_muldiv): New.  Prevent runaway recursion.
+
 2003-02-16  Danny Smith  <dannysmith@users.sourceforge.net>
 
 	* config/i386/cygwin.h (TARGET_SUBTARGET_DEFAULT): Set
diff --git a/gcc/fold-const.c b/gcc/fold-const.c
index 0e301a726902..d6f356104c38 100644
--- a/gcc/fold-const.c
+++ b/gcc/fold-const.c
@@ -104,6 +104,7 @@ static tree unextend		PARAMS ((tree, int, int, tree));
 static tree fold_truthop	PARAMS ((enum tree_code, tree, tree, tree));
 static tree optimize_minmax_comparison PARAMS ((tree));
 static tree extract_muldiv	PARAMS ((tree, tree, enum tree_code, tree));
+static tree extract_muldiv_1	PARAMS ((tree, tree, enum tree_code, tree));
 static tree strip_compound_expr PARAMS ((tree, tree));
 static int multiple_of_p	PARAMS ((tree, tree, tree));
 static tree constant_boolean_node PARAMS ((int, tree));
@@ -4045,6 +4046,31 @@ extract_muldiv (t, c, code, wide_type)
      tree c;
      enum tree_code code;
      tree wide_type;
+{
+  /* To avoid exponential search depth, refuse to allow recursion past
+     three levels.  Beyond that (1) it's highly unlikely that we'll find
+     something interesting and (2) we've probably processed it before
+     when we built the inner expression.  */
+
+  static int depth;
+  tree ret;
+
+  if (depth > 3)
+    return NULL;
+
+  depth++;
+  ret = extract_muldiv_1 (t, c, code, wide_type);
+  depth--;
+
+  return ret;
+}
+
+static tree
+extract_muldiv_1 (t, c, code, wide_type)
+     tree t;
+     tree c;
+     enum tree_code code;
+     tree wide_type;
 {
   tree type = TREE_TYPE (t);
   enum tree_code tcode = TREE_CODE (t);
@@ -4254,6 +4280,14 @@ extract_muldiv (t, c, code, wide_type)
 	  && integer_zerop (const_binop (TRUNC_MOD_EXPR, op1, c, 0)))
 	return omit_one_operand (type, integer_zero_node, op0);
 
+      /* Arrange for the code below to simplify two constants first.  */
+      if (TREE_CODE (op1) == INTEGER_CST && TREE_CODE (op0) != INTEGER_CST)
+	{
+	  tree tmp = op0;
+	  op0 = op1;
+	  op1 = tmp;
+	}
+
       /* ... fall through ...  */
 
     case TRUNC_DIV_EXPR:  case CEIL_DIV_EXPR:  case FLOOR_DIV_EXPR:
-- 
GitLab