http://gcc.gnu.org/bugzilla/show_bug.cgi?id=59058

--- Comment #5 from Richard Biener <rguenth at gcc dot gnu.org> ---
Unfortunately

@@ -2930,11 +2931,31 @@ number_of_exit_cond_executions (struct l
   if (chrec_contains_undetermined (ret))
     return ret;

-  ret = chrec_fold_plus (type, ret, build_int_cst (type, 1));
-  if (TREE_CODE (ret) == INTEGER_CST
-      && TREE_OVERFLOW (ret))
+  /* Handle constants without widening.  */
+  if (TREE_CODE (ret) == INTEGER_CST)
+    {
+      double_int adj = tree_to_double_int (ret) + double_int_one;
+      if (double_int_fits_to_tree_p (type, adj))
+       return double_int_to_tree (type, adj);
+    }
+
+  /* For the remaining case widen to an unsigned type from a
+     signed one or to one with at least one bit more precision
+     but not larger than using word_mode.  */
+  if (!TYPE_UNSIGNED (type))
+    type = unsigned_type_for (type);
+  else if (GET_MODE_CLASS (TYPE_MODE (type)) == MODE_INT
+          && TYPE_PRECISION (type) < GET_MODE_PRECISION (word_mode))
+    {
+      enum machine_mode mode;
+      mode = smallest_mode_for_size (TYPE_PRECISION (type) + 1, MODE_INT);
+      type = build_nonstandard_integer_type (GET_MODE_PRECISION (mode), 1);
+    }
+  else
     return chrec_dont_know;

+  ret = chrec_convert (type, ret, NULL);
+  ret = chrec_fold_plus (type, ret, build_int_cst (type, 1));
   return ret;
 }

breaks loops which use size_t as induction variable type.  But they
are possibly miscompiled anyway.  Not sure if we can rely on
the availability of arithmetics on modes > word_mode, can we?

Reply via email to