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.