https://gcc.gnu.org/bugzilla/show_bug.cgi?id=69526
--- Comment #11 from Richard Biener <rguenth at gcc dot gnu.org> --- (In reply to rdapp from comment #10) > Created attachment 38144 [details] > Tentative patch for VRP and loop-doloop > > Meanwhile I found the time to implement a pattern for VRP which seems to do > the job on tree level. Although larger now (and not many cases are covered > yet) I suppose I agree that it fits better in VRP than in ivopts and might > even catch more cases than before. > > The fix on RTL level is nonetheless necessary since doloop calculates the > number of iterations independently of the code before and also adds a +1. > I cleaned up the fix a little by introducing niterp1_expr (niter plus 1) but > there's still room for improvement. > > No regressions so far, improvement ideas welcome. It's a bit very ad-hoc (looking at the VRP part). I think what we'd need to do is a) in VRP have a general helper telling you whether UNOP A or A BINOP B overflows/underflows b) in the existing patterns that would handle this and similar situations in match.pd: /* (A +- CST) +- CST -> A + CST */ (for outer_op (plus minus) (for inner_op (plus minus) ... use such a generic predicate to handle cases with (A +- CST) wrapped inside a conversion (it should already be fine to handle this case if A +- CST cannot overflow because TYPE_OVERFLOW_UNDEFINED). c) use fold_stmt (or gimple_simplify directly) in vrp_fold_stmt to invoke the folding machinery - eventually simply unconditionally call fold_stmt in tree-ssa-propagate.c:substitute_and_fold_dom_walker::before_dom_children rather than only when we progagated into a stmt. Even when doing the "ad-hoc" thing initially splitting out a) (implementing only a subset of operations) would be a useful thing to do. Note that during VRP itself you can use its own lattice while when not in VRP you'd have to rely on SSA_NAME_RANGE_INFO.