https://gcc.gnu.org/bugzilla/show_bug.cgi?id=113440
--- Comment #2 from Andrew Macleod <amacleod at redhat dot com> --- (In reply to Richard Biener from comment #1) > Yeah, looks like > > if (a+a < a) > > for unsigned doesn't register the appropriate range on the false edge. _1 = a_5(D) * 2; if (_1 < a_5(D)) goto <bb 4>; [INV] else goto <bb 3>; [INV] <bb 3> : Relational : (_1 >= a_5(D)) if (a_5(D) == 0) goto <bb 4>; [INV] else goto <bb 5>; [INV] _1 [irange] unsigned int [0, 0][2, +INF] MASK 0xfffffffe VALUE 0x0 a_5(D) [irange] unsigned int [1, +INF] <bb 5> : _3 = _1 / a_5(D); n = _3; I think the ranges as such are fine, but the missing bit is that we KNOW _1 >= a_5, but we do not use that information. 1) Ranger doesn't fullt leverage relations everywhere yet, in particaulr multiply makes no attempt to use them or the recomputation _1 would be [2, +INF] in bb5 (Since a_5 is now [1, +INF]) 2) ranger could then utilize that in the divide to set the range of _3 to [1, +INF] (which we don't do currently). But neither of those are the real issue. 3) It requires a simplification type operation to look at _1 and understand that the divide is a_5 * 2 / a_5, with the known relation that a_5 * 2 >= a_5. This would be fairly trivial with the relation oracle if we can wire it into one of the simplification routines. For example, If I look in simplify_using_ranges::simplify_div_or_mod_using_ranges when we process the _3 = _1 / a_5(D) statement: p query->query_relation (stmt, op0, op1) VREL_GE so we know... but we do not look at _1 to see that it is defined as op1 * 2. I don't know if we can push that sort of thing into the more general match.pd code... it seems like it would be useful there too. It is something on the list to eventually look into.