OSDN Git Service

PR fortran/23516
[pf3gnuchains/gcc-fork.git] / gcc / tree-ssa-loop-niter.c
index ce4b3cf..b720e19 100644 (file)
@@ -117,10 +117,10 @@ inverse (tree x, tree mask)
       rslt = build_int_cst_type (type, 1);
       for (; ctr; ctr--)
        {
-         rslt = fold_binary_to_constant (MULT_EXPR, type, rslt, x);
-         x = fold_binary_to_constant (MULT_EXPR, type, x, x);
+         rslt = int_const_binop (MULT_EXPR, rslt, x, 0);
+         x = int_const_binop (MULT_EXPR, x, x, 0);
        }
-      rslt = fold_binary_to_constant (BIT_AND_EXPR, type, rslt, mask);
+      rslt = int_const_binop (BIT_AND_EXPR, rslt, mask, 0);
     }
 
   return rslt;
@@ -634,11 +634,15 @@ expand_simple_operations (tree expr)
 {
   unsigned i, n;
   tree ret = NULL_TREE, e, ee, stmt;
-  enum tree_code code = TREE_CODE (expr);
+  enum tree_code code;
+
+  if (expr == NULL_TREE)
+    return expr;
 
   if (is_gimple_min_invariant (expr))
     return expr;
 
+  code = TREE_CODE (expr);
   if (IS_EXPR_CODE_CLASS (TREE_CODE_CLASS (code)))
     {
       n = TREE_CODE_LENGTH (code);
@@ -1434,10 +1438,10 @@ infer_loop_bounds_from_undefined (struct loop *loop)
                /* For each array access, analyze its access function
                   and record a bound on the loop iteration domain.  */
                if (TREE_CODE (op1) == ARRAY_REF)
-                 analyze_array (stmt, op1, true);
+                 estimate_iters_using_array (stmt, op1);
 
                if (TREE_CODE (op0) == ARRAY_REF)
-                 analyze_array (stmt, op0, false);
+                 estimate_iters_using_array (stmt, op0);
 
                /* For each signed type variable in LOOP, analyze its
                   scalar evolution and record a bound of the loop
@@ -1460,19 +1464,21 @@ infer_loop_bounds_from_undefined (struct loop *loop)
                    if (init == NULL_TREE
                        || step == NULL_TREE
                        || TREE_CODE (init) != INTEGER_CST
-                       || TREE_CODE (step) != INTEGER_CST)
+                       || TREE_CODE (step) != INTEGER_CST
+                       || TYPE_MIN_VALUE (type) == NULL_TREE
+                       || TYPE_MAX_VALUE (type) == NULL_TREE)
                      break;
 
                    utype = unsigned_type_for (type);
                    if (tree_int_cst_lt (step, integer_zero_node))
-                     diff = fold (build2 (MINUS_EXPR, utype, init,
-                                          TYPE_MIN_VALUE (type)));
+                     diff = fold_build2 (MINUS_EXPR, utype, init,
+                                         TYPE_MIN_VALUE (type));
                    else
-                     diff = fold (build2 (MINUS_EXPR, utype,
-                                          TYPE_MAX_VALUE (type), init));
+                     diff = fold_build2 (MINUS_EXPR, utype,
+                                         TYPE_MAX_VALUE (type), init);
 
-                   estimation = fold (build2 (CEIL_DIV_EXPR, utype, diff,
-                                              step));
+                   estimation = fold_build2 (CEIL_DIV_EXPR, utype, diff,
+                                             step);
                    record_estimate (loop, estimation, boolean_true_node, stmt);
                  }
 
@@ -1486,7 +1492,7 @@ infer_loop_bounds_from_undefined (struct loop *loop)
                for (args = TREE_OPERAND (stmt, 1); args;
                     args = TREE_CHAIN (args))
                  if (TREE_CODE (TREE_VALUE (args)) == ARRAY_REF)
-                   analyze_array (stmt, TREE_VALUE (args), true);
+                   estimate_iters_using_array (stmt, TREE_VALUE (args));
 
                break;
              }
@@ -1653,6 +1659,10 @@ proved_non_wrapping_p (tree at_stmt,
   else
     valid_niter = fold_convert (TREE_TYPE (bound), valid_niter);
 
+  /* Give up if BOUND was not folded to an INTEGER_CST, as in PR23434.  */
+  if (TREE_CODE (bound) != INTEGER_CST)
+    return false;
+
   /* After the statement niter_bound->at_stmt we know that anything is
      executed at most BOUND times.  */
   if (at_stmt && stmt_dominates_stmt_p (niter_bound->at_stmt, at_stmt))
@@ -1817,7 +1827,8 @@ scev_probably_wraps_p (tree type, tree base, tree step,
   struct nb_iter_bound *bound;
   tree delta, step_abs;
   tree unsigned_type, valid_niter;
-  tree base_plus_step;
+  tree base_plus_step, bpsps;
+  int cps, cpsps;
 
   /* FIXME: The following code will not be used anymore once
      http://gcc.gnu.org/ml/gcc-patches/2005-06/msg02025.html is
@@ -1850,7 +1861,9 @@ scev_probably_wraps_p (tree type, tree base, tree step,
        }
     }
 
-  if (TREE_CODE (base) == REAL_CST
+  if (chrec_contains_undetermined (base)
+      || chrec_contains_undetermined (step)
+      || TREE_CODE (base) == REAL_CST
       || TREE_CODE (step) == REAL_CST)
     {
       *unknown_max = true;
@@ -1859,7 +1872,17 @@ scev_probably_wraps_p (tree type, tree base, tree step,
 
   *unknown_max = false;
   base_plus_step = fold_build2 (PLUS_EXPR, type, base, step);
-  switch (compare_trees (base_plus_step, base))
+  bpsps = fold_build2 (PLUS_EXPR, type, base_plus_step, step);
+  cps = compare_trees (base_plus_step, base);
+  cpsps = compare_trees (bpsps, base_plus_step);
+
+  /* Check that the sequence is not wrapping in the first step: it
+     should have the same monotonicity for the first two steps.  See
+     PR23410.  */
+  if (cps != cpsps)
+    return true;
+
+  switch (cps)
     {
     case -1:
       {
@@ -1961,7 +1984,13 @@ tree
 convert_step (struct loop *loop, tree new_type, tree base, tree step,
              tree at_stmt)
 {
-  tree base_type = TREE_TYPE (base);
+  tree base_type;
+
+  if (chrec_contains_undetermined (base)
+      || chrec_contains_undetermined (step))
+    return NULL_TREE;
+
+  base_type = TREE_TYPE (base);
 
   /* When not using wrapping arithmetic, signed types don't wrap.  */
   if (!flag_wrapv && !TYPE_UNSIGNED (base_type))