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.