On Mon, Jan 8, 2024 at 6:44 AM Uros Bizjak <ubiz...@gmail.com> 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.

Reply via email to