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)

Reply via email to