https://gcc.gnu.org/bugzilla/show_bug.cgi?id=98028
--- Comment #4 from Andrew Macleod <amacleod at redhat dot com> --- I would expect in gcc 12 we'll be handling it differently than that. I have equivalences/relations up and running and will eventually get to applying those to general statements... which I haven't gotten to yet. the gimple_fold() routine uses fold_range () via range-ops to calculate a result. I plan to additionally check if there is a relation between the operands, and if so, invoke another range_ops routine to see if that relation makes any further adjustments. in this case, we'd have VARYING - VARYING, so ranges would resolve as expected to VARYING. A query if there is a relation between j_1 and i_2 =========== BB 4 ============ j_1(D) unsigned int VARYING i_2(D) unsigned int VARYING Equivalence set : [j_1(D), i_2(D)] <bb 4> : _3 = i_2(D) - j_1(D); return _3; shows they are in an equivalence set, so that would be trivial to fold to 0 for MINUS_EXPR. as well, if we see other relations if (j > i) __builtin_unreachable(); return i - j; =========== BB 4 ============ j_1(D) unsigned int VARYING i_2(D) unsigned int VARYING Relational : (j_1(D) <= i_2(D)) <bb 4> : _3 = i_2(D) - j_1(D); return _3; it would likewise be pretty straightforward to add the restriction that _3 will be [0, +INF] (or [1, +INF] if it were j_1 < i_2) If the relation is !=, we could also provide ~[0,0] I'd expect the routine for MINUS_EXPR to simply switch on the possible relations and intersect the current result with this reduced possible outcome. I hope to get most of this in early in stage 1 and we can begin enhancing/finding opportunities. .