This is the mail archive of the
gcc-patches@gcc.gnu.org
mailing list for the GCC project.
Re: [PATCH] Add (1 << A) & 1) folding (PR middle-end/64309)
- From: Richard Biener <rguenther at suse dot de>
- To: Marek Polacek <polacek at redhat dot com>
- Cc: GCC Patches <gcc-patches at gcc dot gnu dot org>
- Date: Tue, 16 Dec 2014 19:15:27 +0100 (CET)
- Subject: Re: [PATCH] Add (1 << A) & 1) folding (PR middle-end/64309)
- Authentication-results: sourceware.org; auth=none
- References: <20141216131553 dot GF16332 at redhat dot com> <alpine dot LSU dot 2 dot 11 dot 1412161504360 dot 25296 at zhemvz dot fhfr dot qr> <20141216151513 dot GG16332 at redhat dot com>
On Tue, 16 Dec 2014, Marek Polacek wrote:
> On Tue, Dec 16, 2014 at 03:08:23PM +0100, Richard Biener wrote:
> > You can use
> >
> > (for cmp (ne eq)
> > icmp (eq ne)
> > (simplify
> > (cmp (bit_and (lshift integer_onep @0) integer_onep) integer_zerop)
> > (icmp @0 { build_zero_cst (TREE_TYPE (@0)); })))
> >
> > to combine both patterns. Btw, shoudln't it be (bit_and (...)
>
> Ah, we can have multiple operators to iterate (and yes, it's
> documented, my bad).
>
> > integer_each_onep)? I'm always unsure about the complex integer case
> > (maybe try a runtime testcase and see what happens - eventually we
> > just don't support bit operations on them...)
>
> Correct - we don't allow complex operands for neither shift, nor bit and.
> So I left the integer_onep in there. Thanks.
Ok.
Thanks,
Richard.
> 2014-12-16 Marek Polacek <polacek@redhat.com>
>
> PR middle-end/64309
> * match.pd: Add ((1 << A) & 1) != 0 -> A == 0 and
> ((1 << A) & 1) == 0 -> A != 0.
>
> * gcc.dg/pr64309.c: New test.
>
> diff --git gcc/match.pd gcc/match.pd
> index 083d65f..dbca99e 100644
> --- gcc/match.pd
> +++ gcc/match.pd
> @@ -599,6 +599,13 @@ along with GCC; see the file COPYING3. If not see
> build_int_cst (TREE_TYPE (@1),
> element_precision (type)), @1); }))
>
> +/* ((1 << A) & 1) != 0 -> A == 0
> + ((1 << A) & 1) == 0 -> A != 0 */
> +(for cmp (ne eq)
> + icmp (eq ne)
> + (simplify
> + (cmp (bit_and (lshift integer_onep @0) integer_onep) integer_zerop)
> + (icmp @0 { build_zero_cst (TREE_TYPE (@0)); })))
>
> /* Simplifications of conversions. */
>
> diff --git gcc/testsuite/gcc.dg/pr64309.c gcc/testsuite/gcc.dg/pr64309.c
> index e69de29..710a762 100644
> --- gcc/testsuite/gcc.dg/pr64309.c
> +++ gcc/testsuite/gcc.dg/pr64309.c
> @@ -0,0 +1,66 @@
> +/* PR middle-end/64309 */
> +/* { dg-do run } */
> +/* { dg-options "-fdump-tree-original" } */
> +
> +int
> +fn1 (int n)
> +{
> + return ((1 << n) & 1) != 0;
> +}
> +
> +int
> +fn2 (int n)
> +{
> + return (1 & (1 << n)) != 0;
> +}
> +
> +int
> +fn3 (int n)
> +{
> + return ((1 << n) & 1) == 0;
> +}
> +
> +int
> +fn4 (int n)
> +{
> + return (1 & (1 << n)) == 0;
> +}
> +
> +int
> +main (void)
> +{
> + if (fn1 (0) != 1
> + || fn1 (1) != 0
> + || fn1 (2) != 0
> + || fn1 (3) != 0
> + || fn1 (4) != 0
> + || fn1 (5) != 0)
> + __builtin_abort ();
> +
> + if (fn2 (0) != 1
> + || fn2 (1) != 0
> + || fn2 (2) != 0
> + || fn2 (3) != 0
> + || fn2 (4) != 0
> + || fn2 (5) != 0)
> + __builtin_abort ();
> +
> + if (fn3 (0) != 0
> + || fn3 (1) != 1
> + || fn3 (2) != 1
> + || fn3 (3) != 1
> + || fn3 (4) != 1
> + || fn3 (5) != 1)
> + __builtin_abort ();
> +
> + if (fn4 (0) != 0
> + || fn4 (1) != 1
> + || fn4 (2) != 1
> + || fn4 (3) != 1
> + || fn4 (4) != 1
> + || fn4 (5) != 1)
> + __builtin_abort ();
> +}
> +
> +/* { dg-final { scan-tree-dump-not "(<<|>>)" "original" } } */
> +/* { dg-final { cleanup-tree-dump "original" } } */
>
> Marek
>
>
--
Richard Biener <rguenther@suse.de>
SUSE LINUX GmbH, GF: Felix Imendoerffer, Jane Smithard, Jennifer Guild,
Dilip Upmanyu, Graham Norton HRB 21284 (AG Nuernberg)