https://gcc.gnu.org/bugzilla/show_bug.cgi?id=64277
--- Comment #16 from Richard Biener <rguenth at gcc dot gnu.org> --- (In reply to Ilya Enkovich from comment #13) > Ranges have to be used for maxiter computations to have consistent analysis > in complete unroll and vrp. Following patch allows to refine maxiter > estimation using ranges and avoid warnings. Looks good to me with... > diff --git a/gcc/tree-ssa-loop-niter.c b/gcc/tree-ssa-loop-niter.c > index 919f5c0..14cce2a 100644 > --- a/gcc/tree-ssa-loop-niter.c > +++ b/gcc/tree-ssa-loop-niter.c > @@ -2754,6 +2754,7 @@ record_nonwrapping_iv (struct loop *loop, tree base, > tree step, gimple stmt, > { > tree niter_bound, extreme, delta; > tree type = TREE_TYPE (base), unsigned_type; > + tree orig_base = base; > > if (TREE_CODE (step) != INTEGER_CST || integer_zerop (step)) > return; > @@ -2777,7 +2778,14 @@ record_nonwrapping_iv (struct loop *loop, tree base, > tree step, gimple stmt, > > if (tree_int_cst_sign_bit (step)) > { > + wide_int min, max, highwi = high; > extreme = fold_convert (unsigned_type, low); > + if (TREE_CODE (orig_base) == SSA_NAME > + && !POINTER_TYPE_P (TREE_TYPE (orig_base)) test INTEGRAL_TYPE_P (TREE_TYPE (orig_base)) instead > + && SSA_NAME_RANGE_INFO (orig_base) You can drop this check, get_range_info will return VR_VARYING. > + && get_range_info (orig_base, &min, &max) == VR_RANGE > + && wi::gts_p (highwi, max)) I think you can write && wi::gts_p (high.to_widest (), max)) and avoid the highwi temporary. Similar changes below. > + base = wide_int_to_tree (unsigned_type, max); > if (TREE_CODE (base) != INTEGER_CST) > base = fold_convert (unsigned_type, high); > delta = fold_build2 (MINUS_EXPR, unsigned_type, base, extreme); > @@ -2785,8 +2793,15 @@ record_nonwrapping_iv (struct loop *loop, tree base, > tree step, gimple stmt, > } > else > { > + wide_int min, max, lowwi = low; > extreme = fold_convert (unsigned_type, high); > - if (TREE_CODE (base) != INTEGER_CST) > + if (TREE_CODE (orig_base) == SSA_NAME > + && !POINTER_TYPE_P (TREE_TYPE (orig_base)) > + && SSA_NAME_RANGE_INFO (orig_base) > + && get_range_info (orig_base, &min, &max) == VR_RANGE > + && wi::gts_p (min, lowwi)) > + base = wide_int_to_tree (unsigned_type, min); > + else if (TREE_CODE (base) != INTEGER_CST) > base = fold_convert (unsigned_type, low); > delta = fold_build2 (MINUS_EXPR, unsigned_type, extreme, base); > } > diff --git a/gcc/testsuite/gcc.dg/pr64277.c b/gcc/testsuite/gcc.dg/pr64277.c > new file mode 100644 > index 0000000..0d5ef11 > --- /dev/null > +++ b/gcc/testsuite/gcc.dg/pr64277.c > @@ -0,0 +1,21 @@ > +/* PR tree-optimization/64277 */ > +/* { dg-do compile } */ > +/* { dg-options "-O3 -Wall -Werror" } */ > + > + > +int f1[10]; > +void test1 (short a[], short m, unsigned short l) > +{ > + int i = l; > + for (i = i + 5; i < m; i++) > + f1[i] = a[i]++; > +} > + > +void test2 (short a[], short m, short l) > +{ > + int i; > + if (m > 5) > + m = 5; > + for (i = m; i > l; i--) > + f1[i] = a[i]++; > +}