Richard Biener <rguent...@suse.de> writes: > 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. > > Bootstrap and regtest running on x86_64-unknown-linux-gnu. > > 2020-12-07 Richard Biener <rguent...@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. > --- > gcc/testsuite/gcc.dg/torture/pr98117.c | 19 +++++++++++++++++ > gcc/tree-vect-loop-manip.c | 28 ++++++++++++++++++++------ > 2 files changed, 41 insertions(+), 6 deletions(-) > create mode 100644 gcc/testsuite/gcc.dg/torture/pr98117.c > > diff --git a/gcc/testsuite/gcc.dg/torture/pr98117.c > b/gcc/testsuite/gcc.dg/torture/pr98117.c > new file mode 100644 > index 00000000000..f2160257263 > --- /dev/null > +++ b/gcc/testsuite/gcc.dg/torture/pr98117.c > @@ -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; > +} > diff --git a/gcc/tree-vect-loop-manip.c b/gcc/tree-vect-loop-manip.c > index 36179188f6d..2370b879b21 100644 > --- a/gcc/tree-vect-loop-manip.c > +++ b/gcc/tree-vect-loop-manip.c > @@ -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)
This code is common to const vf and non-const vf, so const_vf isn't guaranteed to be valid. Thanks, Richard > + 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;