On Fri, Oct 23, 2020 at 8:58 AM Luc Van Oostenryck <luc.vanoostenryck@xxxxxxxxx> wrote: > > Some unsigned compares against 0 are always true or always false > (x < 0 or x >= 0). Simplify them. Fair enough, but if you're simplifying compares, one of the more important simplifications is to make the compare unsigned in the first place. IOW, simplifying (signed >= 0 && signed < X) into (unsigned < X) if you can show that X is positive (most trivially a constant). Example: int cmp(int i) { return i >= 0 && i < 4; } which currently generates setge.1 %r3 <- %arg1, $0 setlt.1 %r6 <- %arg1, $4 and.1 %r7 <- %r3, %r6 zext.32 %r8 <- (1) %r7 ret.32 %r8 which is obviously not great. Another comparison simplification often worth doing is to do cast simplification, ie ((cast) X cmpop Y) where 'Y' already fits in the original type of 'X', and the cast is unnecessary. Test-case: int cmp(int i) { return i < sizeof(i); } and notice how sparse generates sext.64 %r2 <- (32) %arg1 setb.32 %r3 <- %r2, $4 ret.32 %r3 with that entirely unnecessary sign extension that doesn't really help.. The related simplification is then (signed >= 0 && unsigned < X) and just removing the "signed > 0" case. These happen when you have code that checks for sizes: int cmp(int i) { return i >= 0 && i < sizeof(i); } where that "i < sizeof(i)" ended up being not just extended to 64-bit, but an unsigned compare due to the 'sizeof()' being unsigned. Linus