diff options
Diffstat (limited to 'gcc/tree-ssa-loop-niter.cc')
-rw-r--r-- | gcc/tree-ssa-loop-niter.cc | 47 |
1 files changed, 30 insertions, 17 deletions
diff --git a/gcc/tree-ssa-loop-niter.cc b/gcc/tree-ssa-loop-niter.cc index 705bcc0..718582a 100644 --- a/gcc/tree-ssa-loop-niter.cc +++ b/gcc/tree-ssa-loop-niter.cc @@ -3873,12 +3873,17 @@ do_warn_aggressive_loop_optimizations (class loop *loop, return; gimple *estmt = last_nondebug_stmt (e->src); - char buf[WIDE_INT_PRINT_BUFFER_SIZE]; - print_dec (i_bound, buf, TYPE_UNSIGNED (TREE_TYPE (loop->nb_iterations)) - ? UNSIGNED : SIGNED); + char buf[WIDE_INT_PRINT_BUFFER_SIZE], *p; + unsigned len; + if (print_dec_buf_size (i_bound, TYPE_SIGN (TREE_TYPE (loop->nb_iterations)), + &len)) + p = XALLOCAVEC (char, len); + else + p = buf; + print_dec (i_bound, p, TYPE_SIGN (TREE_TYPE (loop->nb_iterations))); auto_diagnostic_group d; if (warning_at (gimple_location (stmt), OPT_Waggressive_loop_optimizations, - "iteration %s invokes undefined behavior", buf)) + "iteration %s invokes undefined behavior", p)) inform (gimple_location (estmt), "within this loop"); loop->warned_aggressive_loop_optimizations = true; } @@ -3915,6 +3920,9 @@ record_estimate (class loop *loop, tree bound, const widest_int &i_bound, else gcc_checking_assert (i_bound == wi::to_widest (bound)); + if (wi::min_precision (i_bound, SIGNED) > bound_wide_int ().get_precision ()) + return; + /* If we have a guaranteed upper bound, record it in the appropriate list, unless this is an !is_exit bound (i.e. undefined behavior in at_stmt) in a loop with known constant number of iterations. */ @@ -3925,7 +3933,7 @@ record_estimate (class loop *loop, tree bound, const widest_int &i_bound, { class nb_iter_bound *elt = ggc_alloc<nb_iter_bound> (); - elt->bound = i_bound; + elt->bound = bound_wide_int::from (i_bound, SIGNED); elt->stmt = at_stmt; elt->is_exit = is_exit; elt->next = loop->bounds; @@ -4410,8 +4418,8 @@ infer_loop_bounds_from_undefined (class loop *loop, basic_block *bbs) static int wide_int_cmp (const void *p1, const void *p2) { - const widest_int *d1 = (const widest_int *) p1; - const widest_int *d2 = (const widest_int *) p2; + const bound_wide_int *d1 = (const bound_wide_int *) p1; + const bound_wide_int *d2 = (const bound_wide_int *) p2; return wi::cmpu (*d1, *d2); } @@ -4419,7 +4427,7 @@ wide_int_cmp (const void *p1, const void *p2) Lookup by binary search. */ static int -bound_index (const vec<widest_int> &bounds, const widest_int &bound) +bound_index (const vec<bound_wide_int> &bounds, const bound_wide_int &bound) { unsigned int end = bounds.length (); unsigned int begin = 0; @@ -4428,7 +4436,7 @@ bound_index (const vec<widest_int> &bounds, const widest_int &bound) while (begin != end) { unsigned int middle = (begin + end) / 2; - widest_int index = bounds[middle]; + bound_wide_int index = bounds[middle]; if (index == bound) return middle; @@ -4450,7 +4458,7 @@ static void discover_iteration_bound_by_body_walk (class loop *loop) { class nb_iter_bound *elt; - auto_vec<widest_int> bounds; + auto_vec<bound_wide_int> bounds; vec<vec<basic_block> > queues = vNULL; vec<basic_block> queue = vNULL; ptrdiff_t queue_index; @@ -4459,7 +4467,7 @@ discover_iteration_bound_by_body_walk (class loop *loop) /* Discover what bounds may interest us. */ for (elt = loop->bounds; elt; elt = elt->next) { - widest_int bound = elt->bound; + bound_wide_int bound = elt->bound; /* Exit terminates loop at given iteration, while non-exits produce undefined effect on the next iteration. */ @@ -4492,7 +4500,7 @@ discover_iteration_bound_by_body_walk (class loop *loop) hash_map<basic_block, ptrdiff_t> bb_bounds; for (elt = loop->bounds; elt; elt = elt->next) { - widest_int bound = elt->bound; + bound_wide_int bound = elt->bound; if (!elt->is_exit) { bound += 1; @@ -4601,7 +4609,8 @@ discover_iteration_bound_by_body_walk (class loop *loop) print_decu (bounds[latch_index], dump_file); fprintf (dump_file, "\n"); } - record_niter_bound (loop, bounds[latch_index], false, true); + record_niter_bound (loop, widest_int::from (bounds[latch_index], + SIGNED), false, true); } queues.release (); @@ -4704,7 +4713,8 @@ maybe_lower_iteration_bound (class loop *loop) if (dump_file && (dump_flags & TDF_DETAILS)) fprintf (dump_file, "Reducing loop iteration estimate by 1; " "undefined statement must be executed at the last iteration.\n"); - record_niter_bound (loop, loop->nb_iterations_upper_bound - 1, + record_niter_bound (loop, widest_int::from (loop->nb_iterations_upper_bound, + SIGNED) - 1, false, true); } @@ -4860,10 +4870,13 @@ estimate_numbers_of_iterations (class loop *loop) not break code with undefined behavior by not recording smaller maximum number of iterations. */ if (loop->nb_iterations - && TREE_CODE (loop->nb_iterations) == INTEGER_CST) + && TREE_CODE (loop->nb_iterations) == INTEGER_CST + && (wi::min_precision (wi::to_widest (loop->nb_iterations), SIGNED) + <= bound_wide_int ().get_precision ())) { loop->any_upper_bound = true; - loop->nb_iterations_upper_bound = wi::to_widest (loop->nb_iterations); + loop->nb_iterations_upper_bound + = bound_wide_int::from (wi::to_widest (loop->nb_iterations), SIGNED); } } @@ -5114,7 +5127,7 @@ n_of_executions_at_most (gimple *stmt, class nb_iter_bound *niter_bound, tree niter) { - widest_int bound = niter_bound->bound; + widest_int bound = widest_int::from (niter_bound->bound, SIGNED); tree nit_type = TREE_TYPE (niter), e; enum tree_code cmp; |