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.

Reply via email to