On Thu, 19 May 2016, Marek Polacek wrote: > Since Bin's changes to the niter analysis in r231097, we find ourselves in > a situation where extract_range_from_binary_expr is given [1, od_5] + UINT_MAX > on type unsigned. We combine the lower bounds, which is 1 + UINT_MAX = > 0(OVF). > We then combine the upper bounds, because the max_op0 is not a constant, the > result of that is UINT_MAX. That results in min overflow -- and an assert is > unhappy about that. As suggested in the PR, a safe thing would be to change > the assert to dropping to varying. > > Bootstrapped/regtested on x86_64-linux, ok for trunk and 6?
Ok if you leave the assert in (there is at least one unhandled case, min_ovf == 1 && max_ovf == -1). Alternatively make the code match the comment and drop the == 0 checks in your added condition. Which would suggest to make the else { an else if (asserted condition) and common the varying case to else { }. Thanks, Richard. > 2016-05-19 Marek Polacek <pola...@redhat.com> > > PR tree-optimization/71031 > * tree-vrp.c (extract_range_from_binary_expr_1): Drop to varying for > min overflow or max underflow and remove an assert. > > * gcc.dg/tree-ssa/vrp100.c: New test. > > diff --git gcc/testsuite/gcc.dg/tree-ssa/vrp100.c > gcc/testsuite/gcc.dg/tree-ssa/vrp100.c > index e69de29..c0fe4b5 100644 > --- gcc/testsuite/gcc.dg/tree-ssa/vrp100.c > +++ gcc/testsuite/gcc.dg/tree-ssa/vrp100.c > @@ -0,0 +1,32 @@ > +/* PR tree-optimization/71031 */ > +/* { dg-do compile } */ > +/* { dg-options "-Os" } */ > + > +int zj; > +int **yr; > + > +void > +nn (void) > +{ > + unsigned int od = 4; > + > + for (;;) > + { > + int lk; > + > + for (lk = 0; lk < 2; ++lk) > + { > + static int cm; > + > + zj = 0; > + if (od == 0) > + return; > + ++od; > + for (cm = 0; cm < 2; ++cm) > + { > + --od; > + **yr = 0; > + } > + } > + } > +} > diff --git gcc/tree-vrp.c gcc/tree-vrp.c > index 69e6248..791d738 100644 > --- gcc/tree-vrp.c > +++ gcc/tree-vrp.c > @@ -2525,14 +2525,19 @@ extract_range_from_binary_expr_1 (value_range *vr, > set_value_range_to_varying (vr); > return; > } > + else if ((min_ovf == 1 && max_ovf == 0) > + || (min_ovf == 0 && max_ovf == -1)) > + { > + /* Min overflow or max underflow, drop to VR_VARYING. */ > + set_value_range_to_varying (vr); > + return; > + } > else > { > /* Min underflow or max overflow. The range kind > changes to VR_ANTI_RANGE. */ > bool covers = false; > wide_int tem = tmin; > - gcc_assert ((min_ovf == -1 && max_ovf == 0) > - || (max_ovf == 1 && min_ovf == 0)); > type = VR_ANTI_RANGE; > tmin = tmax + 1; > if (wi::cmp (tmin, tmax, sgn) < 0) > > Marek > > -- Richard Biener <rguent...@suse.de> SUSE LINUX GmbH, GF: Felix Imendoerffer, Jane Smithard, Graham Norton, HRB 21284 (AG Nuernberg)