https://gcc.gnu.org/bugzilla/show_bug.cgi?id=77898

--- Comment #8 from Martin Sebor <msebor at gcc dot gnu.org> ---
No, I get the range for _2 with a "def_stmt _2 = (sizetype) i_4;"

i.0_1: [0, +INF]
_2: ~[2147483648, 18446744071562067967]
_3: [0, +INF]
i_4: VARYING
i_6(D): VARYING

...
  # i_4 = PHI <i_6(D)(2), 0(3)>
  _2 = (sizetype) i_4;
  p_8 = "ab" + _2;

I don't think this is a bug (anymore).  I understand that it's 1) a limitation
of the EVRP pass as you explained (thank you), combined with 2) the sensible
get_range_info() property that it can return an increasingly refined range each
time it's called, combined with 3) the (possibly deliberate) limitation of the
tree-object-size pass that wasn't written to make use of VRP, and combined with
4) the quirk of POINTER_PLUS_EXPR taking an unsigned operand even for signed
arguments.  (Though the last one does feel like a design defect.)

I agree that in many cases there isn't enough information to tell that a range
is final and can't be further improved.  But there certainly are such cases
(the test case in comment #0 is an example of one) and it seems to me that
distinguishing the two sets from one another would be useful in order to avoid
recomputing the same result over and over.

I think it should be possible to call set_range_info() on the result of the
__builtin_object_size, and perhaps even on the offset variable in (p += i)
since its value is constrained not only by the range of its type (before VRP1)
and by statements like the 'if (i < 0 || 1 < i) i = 0;' (after VRP1) but also
by the increment '(p += i)' which is only defined for i in [0, 3] as determined
by the tree-object-size pass before VRP1.  Let me give that a try.

It seems to me that there should many other opportunities to call
set_range_info() in GCC that could help improve the generated code (and the
ability to find bugs via warnings).  I count just 9 calls to the function in
the whole code base.

Reply via email to