https://gcc.gnu.org/bugzilla/show_bug.cgi?id=96542
--- Comment #5 from Andrew Macleod <amacleod at redhat dot com> --- I think this all goes away when multi-range is enabled. The original testcase produces: =========== BB 2 ============ x_4(D) unsigned int VARYING <bb 2> : tmp_5 = x_4(D) != 0; _1 = (int) tmp_5; _2 = 255 >> _1; _3 = (unsigned char) _2; _6 = _3 * 2; return _6; _1 : int [0, 1] _2 : int [127, 255] _3 : unsigned char [127, +INF] A number of the range-ops routines are simply inherited from the single range codebase of value_range, and are not multi-range enabled yet. In particular, rshift here. with a tweak to operator_rshift, we can take 255 >> [0,1] and instead calculate _2 = [127,127][255,255] which would make the results: _1 : int [0, 1] _2 : int [127, 127][255, 255] _3 : unsigned char [127, 127] [255, 255] Then when _6 is calculated as [127, 127][255, 255] * 2 , range-ops will calculate the result to be [254, 254] The whole thing will just fold away to return 254 (or -2 if you want to sign it :-) All we need to do is get the multi-range code enabled.... it's coming.