OSDN Git Service

PR tree-optimization/23434
[pf3gnuchains/gcc-fork.git] / gcc / tree-ssa-loop-niter.c
index 8399faf..a8e4737 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;
@@ -1465,14 +1465,14 @@ infer_loop_bounds_from_undefined (struct loop *loop)
 
                    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);
                  }
 
@@ -1653,6 +1653,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))
@@ -1891,19 +1895,24 @@ scev_probably_wraps_p (tree type, tree base, tree step,
 
   /* If AT_STMT represents a cast operation, we may not be able to
      take advantage of the undefinedness of signed type evolutions.
+
+     implement-c.texi states: "For conversion to a type of width
+     N, the value is reduced modulo 2^N to be within range of the
+     type;"
+
      See PR 21959 for a test case.  Essentially, given a cast
      operation
-               unsigned char i;
-               signed char i.0;
+               unsigned char uc;
+               signed char sc;
                ...
-               i.0_6 = (signed char) i_2;
-               if (i.0_6 < 0)
+               sc = (signed char) uc;
+               if (sc < 0)
                  ...
 
-     where i_2 and i.0_6 have the scev {0, +, 1}, we would consider
-     i_2 to wrap around, but not i.0_6, because it is of a signed
-     type.  This causes VRP to erroneously fold the predicate above
-     because it thinks that i.0_6 cannot be negative.  */
+     where uc and sc have the scev {0, +, 1}, we would consider uc to
+     wrap around, but not sc, because it is of a signed type.  This
+     causes VRP to erroneously fold the predicate above because it
+     thinks that sc cannot be negative.  */
   if (at_stmt && TREE_CODE (at_stmt) == MODIFY_EXPR)
     {
       tree rhs = TREE_OPERAND (at_stmt, 1);