tree-optimization/98117 - fix range set by vectorization on niter IVs

This avoids the degenerate case of a TYPE_MAX_VALUE latch iteration
count value causing wrong range info for the vector IV.  There's
still the case of VF == 1 where if we don't know whether we hit the
above case we cannot emit a range.

2020-12-07  Richard Biener  <rguenther@suse.de>

	PR tree-optimization/98117
	* tree-vect-loop-manip.c (vect_gen_vector_loop_niters):
	Properly handle degenerate niter when setting the vector
	loop IV range.

	* gcc.dg/torture/pr98117.c: New testcase.
This commit is contained in:
Richard Biener 2020-12-07 10:29:07 +01:00
parent f8fb01fbb0
commit cdcbef3c33
2 changed files with 41 additions and 6 deletions

View File

@ -0,0 +1,19 @@
/* { dg-do run } */
/* { dg-additional-options "-fno-tree-scev-cprop" } */
unsigned char c;
void __attribute__((noipa))
e()
{
do
{
}
while (++c);
}
int main()
{
e();
if (c != 0)
__builtin_abort ();
return 0;
}

View File

@ -2034,13 +2034,29 @@ vect_gen_vector_loop_niters (loop_vec_info loop_vinfo, tree niters,
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;