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 <pola...@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 <rguent...@suse.de> SUSE LINUX GmbH, GF: Felix Imendoerffer, Jane Smithard, Jennifer Guild, Dilip Upmanyu, Graham Norton HRB 21284 (AG Nuernberg)