This is the mail archive of the
gcc-patches@gcc.gnu.org
mailing list for the GCC project.
Re: match.pd: Three new patterns (and some more)
- From: Richard Biener <rguenther at suse dot de>
- To: Marek Polacek <polacek at redhat dot com>
- Cc: Marc Glisse <marc dot glisse at inria dot fr>, GCC Patches <gcc-patches at gcc dot gnu dot org>
- Date: Mon, 22 Jun 2015 16:38:09 +0200 (CEST)
- Subject: Re: match.pd: Three new patterns (and some more)
- Authentication-results: sourceware.org; auth=none
- References: <20150612121332 dot GH2756 at redhat dot com> <alpine dot DEB dot 2 dot 20 dot 1506131138460 dot 2373 at laptop-mg dot saclay dot inria dot fr> <alpine dot LSU dot 2 dot 11 dot 1506161531510 dot 31770 at zhemvz dot fhfr dot qr> <20150618164757 dot GE10139 at redhat dot com>
On Thu, 18 Jun 2015, Marek Polacek wrote:
> On Tue, Jun 16, 2015 at 03:35:15PM +0200, Richard Biener wrote:
> > We already have
> >
> > /* (x & y) ^ (x | y) -> x ^ y */
> > (simplify
> > (bit_xor:c (bit_and @0 @1) (bit_ior @0 @1))
> > (bit_xor @0 @1))
> >
> > but of course with minus it doesn't commutate so it's hard to
> > merge.
>
> Yeah :(.
>
> > > > +/* (x & y) + (x | y) -> x + y */
> > >
> > > Again for symmetry, it seems like this comes with
> > > x + y - (x | y) -> x & y
> > > x + y - (x & y) -> x | y
> > > which seem fine when overflow is undefined or wraps, but not if for instance
> > > it saturates.
> >
> > Can you adjust according to Marcs comment and re-submit? If you like
> > you can do it as followup as well and thus the original patch is ok
> > as well.
>
> Sure. This is a new version with some more patters. Thanks.
>
> Bootstrapped/regtested on x86_64-linux, ok for trunk?
Ok.
Thanks,
Richard.
> 2015-06-18 Marek Polacek <polacek@redhat.com>
>
> * match.pd ((x ^ y) ^ (x | y) -> x & y,
> (x & y) + (x ^ y) -> x | y, (x & y) | (x ^ y) -> x | y,
> (x & y) ^ (x ^ y) -> x | y, (x & y) + (x | y) -> x + y,
> (x | y) - (x ^ y) -> x & y, (x | y) - (x & y) -> x ^ y): New patterns.
>
> * gcc.dg/fold-ior-1.c: New test.
> * gcc.dg/fold-minus-2.c: New test.
> * gcc.dg/fold-minus-3.c: New test.
> * gcc.dg/fold-plus-1.c: New test.
> * gcc.dg/fold-plus-2.c: New test.
> * gcc.dg/fold-xor-4.c: New test.
> * gcc.dg/fold-xor-5.c: New test.
>
> diff --git gcc/match.pd gcc/match.pd
> index 1ab2b1c..badb80a 100644
> --- gcc/match.pd
> +++ gcc/match.pd
> @@ -325,6 +325,34 @@ along with GCC; see the file COPYING3. If not see
> (bit_xor:c (bit_and @0 @1) (bit_ior @0 @1))
> (bit_xor @0 @1))
>
> +/* (x ^ y) ^ (x | y) -> x & y */
> +(simplify
> + (bit_xor:c (bit_xor @0 @1) (bit_ior @0 @1))
> + (bit_and @0 @1))
> +
> +/* (x & y) + (x ^ y) -> x | y */
> +/* (x & y) | (x ^ y) -> x | y */
> +/* (x & y) ^ (x ^ y) -> x | y */
> +(for op (plus bit_ior bit_xor)
> + (simplify
> + (op:c (bit_and @0 @1) (bit_xor @0 @1))
> + (bit_ior @0 @1)))
> +
> +/* (x & y) + (x | y) -> x + y */
> +(simplify
> + (plus:c (bit_and @0 @1) (bit_ior @0 @1))
> + (plus @0 @1))
> +
> +/* (x | y) - (x ^ y) -> x & y */
> +(simplify
> + (minus (bit_ior @0 @1) (bit_xor @0 @1))
> + (bit_and @0 @1))
> +
> +/* (x | y) - (x & y) -> x ^ y */
> +(simplify
> + (minus (bit_ior @0 @1) (bit_and @0 @1))
> + (bit_xor @0 @1))
> +
> (simplify
> (abs (negate @0))
> (abs @0))
> diff --git gcc/testsuite/gcc.dg/fold-ior-1.c gcc/testsuite/gcc.dg/fold-ior-1.c
> index e69de29..0358eb5 100644
> --- gcc/testsuite/gcc.dg/fold-ior-1.c
> +++ gcc/testsuite/gcc.dg/fold-ior-1.c
> @@ -0,0 +1,69 @@
> +/* { dg-do compile } */
> +/* { dg-options "-O -fdump-tree-cddce1" } */
> +
> +int
> +fn1 (int a, int b)
> +{
> + int tem1 = a & b;
> + int tem2 = a ^ b;
> + return tem1 | tem2;
> +}
> +
> +int
> +fn2 (int a, int b)
> +{
> + int tem1 = b & a;
> + int tem2 = a ^ b;
> + return tem1 | tem2;
> +}
> +
> +int
> +fn3 (int a, int b)
> +{
> + int tem1 = a & b;
> + int tem2 = b ^ a;
> + return tem1 | tem2;
> +}
> +
> +int
> +fn4 (int a, int b)
> +{
> + int tem1 = b & a;
> + int tem2 = b ^ a;
> + return tem1 | tem2;
> +}
> +
> +int
> +fn5 (int a, int b)
> +{
> + int tem1 = a ^ b;
> + int tem2 = a & b;
> + return tem1 | tem2;
> +}
> +
> +int
> +fn6 (int a, int b)
> +{
> + int tem1 = b ^ a;
> + int tem2 = a & b;
> + return tem1 | tem2;
> +}
> +
> +int
> +fn7 (int a, int b)
> +{
> + int tem1 = a ^ b;
> + int tem2 = b & a;
> + return tem1 | tem2;
> +}
> +
> +int
> +fn8 (int a, int b)
> +{
> + int tem1 = b ^ a;
> + int tem2 = b & a;
> + return tem1 | tem2;
> +}
> +
> +/* { dg-final { scan-tree-dump-not " & " "cddce1" } } */
> +/* { dg-final { scan-tree-dump-not " \\^ " "cddce1" } } */
> diff --git gcc/testsuite/gcc.dg/fold-minus-2.c gcc/testsuite/gcc.dg/fold-minus-2.c
> index e69de29..6501f2f 100644
> --- gcc/testsuite/gcc.dg/fold-minus-2.c
> +++ gcc/testsuite/gcc.dg/fold-minus-2.c
> @@ -0,0 +1,37 @@
> +/* { dg-do compile } */
> +/* { dg-options "-O -fdump-tree-cddce1" } */
> +
> +int
> +fn1 (int a, int b)
> +{
> + int tem1 = a | b;
> + int tem2 = a ^ b;
> + return tem1 - tem2;
> +}
> +
> +int
> +fn2 (int a, int b)
> +{
> + int tem1 = b | a;
> + int tem2 = a ^ b;
> + return tem1 - tem2;
> +}
> +
> +int
> +fn3 (int a, int b)
> +{
> + int tem1 = a | b;
> + int tem2 = b ^ a;
> + return tem1 - tem2;
> +}
> +
> +int
> +fn4 (int a, int b)
> +{
> + int tem1 = b | a;
> + int tem2 = b ^ a;
> + return tem1 - tem2;
> +}
> +
> +/* { dg-final { scan-tree-dump-not " \\^ " "cddce1" } } */
> +/* { dg-final { scan-tree-dump-not " \\| " "cddce1" } } */
> diff --git gcc/testsuite/gcc.dg/fold-minus-3.c gcc/testsuite/gcc.dg/fold-minus-3.c
> index e69de29..e7adce6 100644
> --- gcc/testsuite/gcc.dg/fold-minus-3.c
> +++ gcc/testsuite/gcc.dg/fold-minus-3.c
> @@ -0,0 +1,37 @@
> +/* { dg-do compile } */
> +/* { dg-options "-O -fdump-tree-cddce1" } */
> +
> +int
> +fn1 (int a, int b)
> +{
> + int tem1 = a | b;
> + int tem2 = a & b;
> + return tem1 - tem2;
> +}
> +
> +int
> +fn2 (int a, int b)
> +{
> + int tem1 = b | a;
> + int tem2 = a & b;
> + return tem1 - tem2;
> +}
> +
> +int
> +fn3 (int a, int b)
> +{
> + int tem1 = a | b;
> + int tem2 = b & a;
> + return tem1 - tem2;
> +}
> +
> +int
> +fn4 (int a, int b)
> +{
> + int tem1 = b | a;
> + int tem2 = b & a;
> + return tem1 - tem2;
> +}
> +
> +/* { dg-final { scan-tree-dump-not " \\| " "cddce1" } } */
> +/* { dg-final { scan-tree-dump-not " & " "cddce1" } } */
> diff --git gcc/testsuite/gcc.dg/fold-plus-1.c gcc/testsuite/gcc.dg/fold-plus-1.c
> index e69de29..40d6aa2 100644
> --- gcc/testsuite/gcc.dg/fold-plus-1.c
> +++ gcc/testsuite/gcc.dg/fold-plus-1.c
> @@ -0,0 +1,70 @@
> +/* { dg-do compile } */
> +/* { dg-options "-O -fdump-tree-cddce1" } */
> +
> +int
> +fn1 (int a, int b)
> +{
> + int tem1 = a & b;
> + int tem2 = a ^ b;
> + return tem1 + tem2;
> +}
> +
> +int
> +fn2 (int a, int b)
> +{
> + int tem1 = b & a;
> + int tem2 = a ^ b;
> + return tem1 + tem2;
> +}
> +
> +int
> +fn3 (int a, int b)
> +{
> + int tem1 = a & b;
> + int tem2 = b ^ a;
> + return tem1 + tem2;
> +}
> +
> +int
> +fn4 (int a, int b)
> +{
> + int tem1 = b & a;
> + int tem2 = b ^ a;
> + return tem1 + tem2;
> +}
> +
> +int
> +fn5 (int a, int b)
> +{
> + int tem1 = a ^ b;
> + int tem2 = a & b;
> + return tem1 + tem2;
> +}
> +
> +int
> +fn6 (int a, int b)
> +{
> + int tem1 = b ^ a;
> + int tem2 = a & b;
> + return tem1 + tem2;
> +}
> +
> +int
> +fn7 (int a, int b)
> +{
> + int tem1 = a ^ b;
> + int tem2 = b & a;
> + return tem1 + tem2;
> +}
> +
> +int
> +fn8 (int a, int b)
> +{
> + int tem1 = b ^ a;
> + int tem2 = b & a;
> + return tem1 + tem2;
> +}
> +
> +/* { dg-final { scan-tree-dump-not " & " "cddce1" } } */
> +/* { dg-final { scan-tree-dump-not " \\^ " "cddce1" } } */
> +/* { dg-final { scan-tree-dump-not " \\+ " "cddce1" } } */
> diff --git gcc/testsuite/gcc.dg/fold-plus-2.c gcc/testsuite/gcc.dg/fold-plus-2.c
> index e69de29..713abf6 100644
> --- gcc/testsuite/gcc.dg/fold-plus-2.c
> +++ gcc/testsuite/gcc.dg/fold-plus-2.c
> @@ -0,0 +1,69 @@
> +/* { dg-do compile } */
> +/* { dg-options "-O -fdump-tree-cddce1" } */
> +
> +int
> +fn1 (int a, int b)
> +{
> + int tem1 = a & b;
> + int tem2 = a | b;
> + return tem1 + tem2;
> +}
> +
> +int
> +fn2 (int a, int b)
> +{
> + int tem1 = b & a;
> + int tem2 = a | b;
> + return tem1 + tem2;
> +}
> +
> +int
> +fn3 (int a, int b)
> +{
> + int tem1 = a & b;
> + int tem2 = b | a;
> + return tem1 + tem2;
> +}
> +
> +int
> +fn4 (int a, int b)
> +{
> + int tem1 = b & a;
> + int tem2 = b | a;
> + return tem1 + tem2;
> +}
> +
> +int
> +fn5 (int a, int b)
> +{
> + int tem1 = a | b;
> + int tem2 = a & b;
> + return tem1 + tem2;
> +}
> +
> +int
> +fn6 (int a, int b)
> +{
> + int tem1 = b | a;
> + int tem2 = a & b;
> + return tem1 + tem2;
> +}
> +
> +int
> +fn7 (int a, int b)
> +{
> + int tem1 = a | b;
> + int tem2 = b & a;
> + return tem1 + tem2;
> +}
> +
> +int
> +fn8 (int a, int b)
> +{
> + int tem1 = b | a;
> + int tem2 = b & a;
> + return tem1 + tem2;
> +}
> +
> +/* { dg-final { scan-tree-dump-not " & " "cddce1" } } */
> +/* { dg-final { scan-tree-dump-not " \\| " "cddce1" } } */
> diff --git gcc/testsuite/gcc.dg/fold-xor-4.c gcc/testsuite/gcc.dg/fold-xor-4.c
> index e69de29..b5a2c48 100644
> --- gcc/testsuite/gcc.dg/fold-xor-4.c
> +++ gcc/testsuite/gcc.dg/fold-xor-4.c
> @@ -0,0 +1,69 @@
> +/* { dg-do compile } */
> +/* { dg-options "-O -fdump-tree-cddce1" } */
> +
> +int
> +fn1 (int a, int b)
> +{
> + int tem1 = a & b;
> + int tem2 = a ^ b;
> + return tem1 ^ tem2;
> +}
> +
> +int
> +fn2 (int a, int b)
> +{
> + int tem1 = b & a;
> + int tem2 = a ^ b;
> + return tem1 ^ tem2;
> +}
> +
> +int
> +fn3 (int a, int b)
> +{
> + int tem1 = a & b;
> + int tem2 = b ^ a;
> + return tem1 ^ tem2;
> +}
> +
> +int
> +fn4 (int a, int b)
> +{
> + int tem1 = b & a;
> + int tem2 = b ^ a;
> + return tem1 ^ tem2;
> +}
> +
> +int
> +fn5 (int a, int b)
> +{
> + int tem1 = a ^ b;
> + int tem2 = a & b;
> + return tem1 ^ tem2;
> +}
> +
> +int
> +fn6 (int a, int b)
> +{
> + int tem1 = b ^ a;
> + int tem2 = a & b;
> + return tem1 ^ tem2;
> +}
> +
> +int
> +fn7 (int a, int b)
> +{
> + int tem1 = a ^ b;
> + int tem2 = b & a;
> + return tem1 ^ tem2;
> +}
> +
> +int
> +fn8 (int a, int b)
> +{
> + int tem1 = b ^ a;
> + int tem2 = b & a;
> + return tem1 ^ tem2;
> +}
> +
> +/* { dg-final { scan-tree-dump-not " & " "cddce1" } } */
> +/* { dg-final { scan-tree-dump-not " \\^ " "cddce1" } } */
> diff --git gcc/testsuite/gcc.dg/fold-xor-5.c gcc/testsuite/gcc.dg/fold-xor-5.c
> index e69de29..15ee76c 100644
> --- gcc/testsuite/gcc.dg/fold-xor-5.c
> +++ gcc/testsuite/gcc.dg/fold-xor-5.c
> @@ -0,0 +1,69 @@
> +/* { dg-do compile } */
> +/* { dg-options "-O -fdump-tree-cddce1" } */
> +
> +int
> +fn1 (int a, int b)
> +{
> + int tem1 = a | b;
> + int tem2 = a ^ b;
> + return tem1 ^ tem2;
> +}
> +
> +int
> +fn2 (int a, int b)
> +{
> + int tem1 = b | a;
> + int tem2 = a ^ b;
> + return tem1 ^ tem2;
> +}
> +
> +int
> +fn3 (int a, int b)
> +{
> + int tem1 = a | b;
> + int tem2 = b ^ a;
> + return tem1 ^ tem2;
> +}
> +
> +int
> +fn4 (int a, int b)
> +{
> + int tem1 = b | a;
> + int tem2 = b ^ a;
> + return tem1 ^ tem2;
> +}
> +
> +int
> +fn5 (int a, int b)
> +{
> + int tem1 = a ^ b;
> + int tem2 = a | b;
> + return tem1 ^ tem2;
> +}
> +
> +int
> +fn6 (int a, int b)
> +{
> + int tem1 = b ^ a;
> + int tem2 = a | b;
> + return tem1 ^ tem2;
> +}
> +
> +int
> +fn7 (int a, int b)
> +{
> + int tem1 = a ^ b;
> + int tem2 = b | a;
> + return tem1 ^ tem2;
> +}
> +
> +int
> +fn8 (int a, int b)
> +{
> + int tem1 = b ^ a;
> + int tem2 = b | a;
> + return tem1 ^ tem2;
> +}
> +
> +/* { dg-final { scan-tree-dump-not " \\| " "cddce1" } } */
> +/* { dg-final { scan-tree-dump-not " \\^ " "cddce1" } } */
>
>
> Marek
>
>
--
Richard Biener <rguenther@suse.de>
SUSE LINUX GmbH, GF: Felix Imendoerffer, Jane Smithard, Dilip Upmanyu, Graham Norton, HRB 21284 (AG Nuernberg)