niters_vector = force_gimple_operand (niters_vector, &stmts, true, var);
gsi_insert_seq_on_edge_immediate (pe, stmts);
/* Peeling algorithm guarantees that vector loop bound is at least ONE,
- we set range information to make niters analyzer's life easier. */
+ we set range information to make niters analyzer's life easier.
+ Note the number of latch iteration value can be TYPE_MAX_VALUE so
+ we have to represent the vector niter TYPE_MAX_VALUE + 1 >> log_vf. */
if (stmts != NULL && log_vf)
- set_range_info (niters_vector, VR_RANGE,
- wi::to_wide (build_int_cst (type, 1)),
- wi::to_wide (fold_build2 (RSHIFT_EXPR, type,
- TYPE_MAX_VALUE (type),
- log_vf)));
+ {
+ if (niters_no_overflow)
+ set_range_info (niters_vector, VR_RANGE,
+ wi::one (TYPE_PRECISION (type)),
+ wi::rshift (wi::max_value (TYPE_PRECISION (type),
+ TYPE_SIGN (type)),
+ exact_log2 (const_vf),
+ TYPE_SIGN (type)));
+ /* For VF == 1 the vector IV might also overflow so we cannot
+ assert a minimum value of 1. */
+ else if (const_vf > 1)
+ set_range_info (niters_vector, VR_RANGE,
+ wi::one (TYPE_PRECISION (type)),
+ wi::rshift (wi::max_value (TYPE_PRECISION (type),
+ TYPE_SIGN (type))
+ - (const_vf - 1),
+ exact_log2 (const_vf), TYPE_SIGN (type))
+ + 1);
+ }
}
*niters_vector_ptr = niters_vector;
*step_vector_ptr = step_vector;