Re: [PATCH 1/2] simplify unsigned compares against 0

[Date Prev][Date Next][Thread Prev][Thread Next][Date Index][Thread Index]

 



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



[Index of Archives]     [Newbies FAQ]     [LKML]     [IETF Annouce]     [DCCP]     [Netdev]     [Networking]     [Security]     [Bugtraq]     [Yosemite]     [MIPS Linux]     [ARM Linux]     [Linux Security]     [Linux RAID]     [Linux SCSI]     [Trinity Fuzzer Tool]

  Powered by Linux