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?