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?