On Thu, 11 Jun 2015, Marek Polacek wrote: > This patch introduces a new pattern for the match-and-simplify > machinery. > > I have verified this transformation on a toy testcase (tried x and y > in the range [-1000,1000]) and it does a correct thing for all integers. > > The asm diff for fn1 is > - andl %esi, %eax > - orl %edi, %esi > so clearly a win. > > Bootstrapped/regtested on x86_64-linux, ok for trunk?
If the pattern doesn't exist in fold-const.c (obviously it doesn't) then I think it makes sense to only add testcases to match this on GIMPLE (because in the long run we'd like to _not_ transform things in GENERIC, at least not without -O). Thus sth like > +int > +fn1 (signed int x, signed int y) > +{ signed int tem1 = x & y; singed int tem2 = x | y; > + return tem1 ^ tem2; > +} and scanning the first DCE dump (cddec1) for the applied transform. Yes, the scanning is a little bit more complicated... Otherwise the patch is of course ok. (take the suggestion above for followup patches) Thanks, Richard. > 2015-06-11 Marek Polacek <pola...@redhat.com> > > * match.pd ((x & y) ^ (x | y) -> x ^ y): New pattern. > > * gcc.dg/fold-xor-3.c: New test. > > diff --git gcc/match.pd gcc/match.pd > index 48358a8..7a7b201 100644 > --- gcc/match.pd > +++ gcc/match.pd > @@ -320,6 +320,12 @@ along with GCC; see the file COPYING3. If not see > (bitop:c (rbitop:c @0 @1) (bit_not@2 @0)) > (bitop @1 @2))) > > +/* (x & y) ^ (x | y) -> x ^ y */ > +(simplify > + (bit_xor:c (bit_and@2 @0 @1) (bit_ior@3 @0 @1)) > + (if (single_use (@2) && single_use (@3)) > + (bit_xor @0 @1))) > + > (simplify > (abs (negate @0)) > (abs @0)) > diff --git gcc/testsuite/gcc.dg/fold-xor-3.c gcc/testsuite/gcc.dg/fold-xor-3.c > index e69de29..a66f89d 100644 > --- gcc/testsuite/gcc.dg/fold-xor-3.c > +++ gcc/testsuite/gcc.dg/fold-xor-3.c > @@ -0,0 +1,28 @@ > +/* { dg-do compile } */ > +/* { dg-options "-fdump-tree-original" } */ > + > +int > +fn1 (signed int x, signed int y) > +{ > + return (x & y) ^ (x | y); > +} > + > +unsigned int > +fn2 (unsigned int x, unsigned int y) > +{ > + return (x & y) ^ (x | y); > +} > + > +int > +fn3 (signed int x, signed int y) > +{ > + return (x | y) ^ (x & y); > +} > + > +unsigned int > +fn4 (unsigned int x, unsigned int y) > +{ > + return (x | y) ^ (x & y); > +} > + > +/* { dg-final { scan-tree-dump-times "return x \\^ y;" 4 "original" } } */ > > Marek > > -- Richard Biener <rguent...@suse.de> SUSE LINUX GmbH, GF: Felix Imendoerffer, Jane Smithard, Dilip Upmanyu, Graham Norton, HRB 21284 (AG Nuernberg)