https://gcc.gnu.org/bugzilla/show_bug.cgi?id=42117
--- Comment #4 from Andrew Pinski <pinskia at gcc dot gnu.org> --- So I think VRP is almost there on the trunk, it just needs to know if you have a range of a and that a is defined by b|c, then b and c ranges can be just the same as a. That is: _10 = x_5(D) | y_6(D); _11 = (unsigned int) _10; if (_11 <= 1) goto <bb 3>; [57.43%] else goto <bb 4>; [42.57%] 2->3 (T) _10 : [irange] int [0, 1] NONZERO 0x1 2->3 (T) _11 : [irange] unsigned int [0, 1] NONZERO 0x1 2->4 (F) _10 : [irange] int [-INF, -1][2, +INF] 2->4 (F) _11 : [irange] unsigned int [2, +INF] We should have done: 2->3 (T) x_5(D) : [irange] int [0, 1] NONZERO 0x1 2->3 (T) y_6(D) : [irange] int [0, 1] NONZERO 0x1 ... This is only true for bit_ior.