https://gcc.gnu.org/bugzilla/show_bug.cgi?id=108359
--- Comment #4 from Andrew Macleod <amacleod at redhat dot com> --- Well, range does know there is a relationship.. or at least could know: Partial equiv (i_23 pe8 _35) Partial equiv (k_24 pe8 _35) It knows they are both 8 bit equivalences of _35. I don't remember if it will then elide that they are equal... I *think* it will. It also knows their range is: i_23 : [irange] int [0, 0][5, 5] NONZERO 0x5 k_24 : [irange] unsigned int [0, 0][5, 5] NONZERO 0x5 Looking at the call to operator_rshift::fold_range, I see the relation passed in: (gdb) p rel.op1_op2() $3 = VREL_PE8 (gdb) p op1.dump(stderr) [irange] int [0, 0][5, 5] NONZERO 0x5 (gdb) p op2.dump(stderr) [irange] unsigned int [0, 0][5, 5] NONZERO 0x5 We know that 0 and 5 are both within the 8 bit equivalence, so the information is already there now to decide that the result would be 0 >> 0 or 5 >> 5. In fact, we could go one further. wi_fold_in_parts already breaks this down and invokes operator_rshift::wi_fold on [0,0],[0,0] [0, 0],[5, 5] [5,5],[0,0] and [5,5],[5,5] All we really need to do is teach range_operator::fold_range that rather than invoking wi_fold_in_parts() on every combination, that if there is an op1_op2 relation we may only need a subset..