On Mon, Jan 8, 2024 at 6:44 AM Uros Bizjak <[email protected]> wrote:
>
> Instead of converting XOR or PLUS of two values, ANDed with two constants that
> have no bits in common, to IOR expression, convert IOR or XOR of said two
> ANDed values to PLUS expression.
I think this only helps targets which have leal like instruction. Also
I think it is the same issue as I recorded as PR 111763 . I suspect
BIT_IOR is more of a Canonical form for GIMPLE while we should handle
this in expand to decide if we want to use PLUS or IOR.
Thanks,
Andrew Pinski
>
> If we consider the following testcase:
>
> --cut here--
> unsigned int foo (unsigned int a, unsigned int b)
> {
> unsigned int r = a & 0x1;
> unsigned int p = b & ~0x3;
>
> return r + p + 2;
> }
>
> unsigned int bar (unsigned int a, unsigned int b)
> {
> unsigned int r = a & 0x1;
> unsigned int p = b & ~0x3;
>
> return r | p | 2;
> }
> --cut here--
>
> the above testcase compiles (x86_64 -O2) to:
>
> foo:
> andl $1, %edi
> andl $-4, %esi
> orl %esi, %edi
> leal 2(%rdi), %eax
> ret
>
> bar:
> andl $1, %edi
> andl $-4, %esi
> orl %esi, %edi
> movl %edi, %eax
> orl $2, %eax
> ret
>
> There is no further simplification possible in any case, we can't combine
> OR with a PLUS in the first case, and we don't have OR instruction with
> multiple inputs in the second case.
>
> If we switch around the logic in the conversion and convert from IOR/XOR
> to PLUS, then the resulting assembly reads:
>
> foo:
> andl $-4, %esi
> andl $1, %edi
> leal 2(%rsi,%rdi), %eax
> ret
>
> bar:
> andl $1, %edi
> andl $-4, %esi
> leal (%rdi,%rsi), %eax
> orl $2, %eax
> ret
>
> On x86, the conversion can now use LEA instruction, which is much more
> usable than OR instruction. In the first case, LEA implements three input
> ADD instruction, while in the second case, even though the instruction
> can't be combined with a follow-up OR, the non-destructive LEA avoids a move.
>
> PR target/108477
>
> gcc/ChangeLog:
>
> * match.pd (A & CST1 | B & CST2 -> A & CST1 + B & CST2):
> Do not convert PLUS of two values, ANDed with two constants
> that have no bits in common to IOR exporession, convert
> IOR or XOR of said two ANDed values to PLUS expression.
>
> gcc/testsuite/ChangeLog:
>
> * gcc.target/i386/pr108477.c: New test.
>
> Bootstrapped and regression tested on x86_64-linux-gnu {,-m32}.
>
> OK for mainline?
>
> Uros.