https://gcc.gnu.org/bugzilla/show_bug.cgi?id=102950
--- Comment #3 from Andrew Macleod <amacleod at redhat dot com> --- Im not sure what the pre-ranger trick was, but the shortcoming we have it the following: a.0_1 = a; _2 = (int) a.0_1; _3 = _2 ^ 233; _4 = (unsigned int) _3; b_8 = (char) _3; a = b_8; if (b_8 != 0) we know _2 : int [-128, 127] but when we calculate _3, [-128, 127] ^ 233 uses the original bitwise XOR code, and it returns VARYING for that range. therefore We only know _3 is VARYING and therefore 2->3 (F) _3 : int [-INF, -256][0, 0][256, +INF] 2->3 (F) _4 : unsigned int [0, 0][256, 4294967040] When when we later get to if (_4 <= 1) goto <bb 4>; [25.50%] we're kinda of stuck. whereas in reality, properly calculated, we'd know that _3 = [-128, 127], _4 = [-128, 127] And as you can see on the outgoing edges, we see thru the casts to trim out the other bits in _3 and _4 on the 2->3 edge, so with those proper inputs, we would end up with _4 and _3 == [0,0]. so, if no one else gets to it, I'll eventually teach range-op.cc::operator_bitwise_xor::wi_fold to do something about this. special case constants, or maybe look at the ranges and if the RHS fits within the LHS effective precision, produce a better result.