https://gcc.gnu.org/bugzilla/show_bug.cgi?id=96703

--- Comment #2 from Andrew Pinski <pinskia at gcc dot gnu.org> ---
Hmm for
```
#define cst 0x1234

bool f(int x, int y)
{
    return x > y && y == cst;
}

bool f0(int x, int y)
{
    return x > cst && y == cst;
}
```

currently for GCC on aarch64:
```
f:
        cmp     w0, w1
        mov     w2, 4660
        ccmp    w1, w2, 0, gt
        cset    w0, eq
        ret
f0:
        mov     w2, 4660
        cmp     w0, w2
        ccmp    w1, w2, 0, gt
        cset    w0, eq
        ret
```
The f is actually better because the first cmp is indepdent from the move.
So for a dual issue CPU, f would be better almost always. Even if the move does
not occupy an issue slot.

For RISCV not doing is actually better:
        li      a5,4096
        addi    a5,a5,564
        sub     a5,a1,a5
        sgt     a0,a0,a1
        seqz    a5,a5
        and     a0,a5,a0
        ret

vs
        li      a5,4096
        addi    a5,a5,564
        sub     a1,a1,a5
        seqz    a1,a1
        sgt     a0,a0,a5
        and     a0,a1,a0
        ret

The sgt without doing this is indepdent of the constant forming.

Now 0 could be handled as a special case because most targets handle 0 nicely.

I see doing it is better for power but I don't know if that is true in general
or just the constants I tried.

Reply via email to