On Fri, May 13, 2016 at 9:07 PM, Marc Glisse <marc.gli...@inria.fr> wrote: > Hello, > > maybe this would fit better in VRP, but it is easier (and not completely > useless) to put it in match.pd. > > Since the transformation is restricted to GIMPLE, I think I don't need to > check that @0 is SSA_NAME. I didn't test if @0 has pointer type before > calling get_range_info because we are doing bit_not on it, but it looks like > I should because we can do bitops on pointers?
Yes, also because for odd reasons we may get constants into it here (which would admittedly be a bug). Thanks, Richard. > Adjustment for pr69270.c is exactly the same as in the previous patch from > today :-) > > Bootstrap+regtest on powerpc64le-unknown-linux-gnu. > > > 2016-05-16 Marc Glisse <marc.gli...@inria.fr> > > gcc/ > * match.pd (~X & Y): New transformation. > > gcc/testsuite/ > * gcc.dg/tree-ssa/pr69270.c: Adjust. > * gcc.dg/tree-ssa/andnot-1.c: New testcase. > > > -- > Marc Glisse > Index: gcc/match.pd > =================================================================== > --- gcc/match.pd (revision 236194) > +++ gcc/match.pd (working copy) > @@ -496,20 +496,27 @@ DEFINE_INT_AND_FLOAT_ROUND_FN (RINT) > (minus @1 (bit_xor @0 @1))) > > /* Simplify (X & ~Y) | (~X & Y) -> X ^ Y. */ > (simplify > (bit_ior (bit_and:c @0 (bit_not @1)) (bit_and:c (bit_not @0) @1)) > (bit_xor @0 @1)) > (simplify > (bit_ior:c (bit_and @0 INTEGER_CST@2) (bit_and (bit_not @0) > INTEGER_CST@1)) > (if (wi::bit_not (@2) == @1) > (bit_xor @0 @1))) > +/* Simplify (~X & Y) to X ^ Y if we know that (X & ~Y) is 0. */ > +#if GIMPLE > +(simplify > + (bit_and (bit_not @0) INTEGER_CST@1) > + (if ((get_nonzero_bits (@0) & wi::bit_not (@1)) == 0) > + (bit_xor @0 @1))) > +#endif > > /* X % Y is smaller than Y. */ > (for cmp (lt ge) > (simplify > (cmp (trunc_mod @0 @1) @1) > (if (TYPE_UNSIGNED (TREE_TYPE (@0))) > { constant_boolean_node (cmp == LT_EXPR, type); }))) > (for cmp (gt le) > (simplify > (cmp @1 (trunc_mod @0 @1)) > Index: gcc/testsuite/gcc.dg/tree-ssa/andnot-1.c > =================================================================== > --- gcc/testsuite/gcc.dg/tree-ssa/andnot-1.c (revision 0) > +++ gcc/testsuite/gcc.dg/tree-ssa/andnot-1.c (working copy) > @@ -0,0 +1,12 @@ > +/* { dg-do compile } */ > +/* { dg-options "-O -fdump-tree-optimized-raw" } */ > + > +unsigned f(unsigned i){ > + i >>= __SIZEOF_INT__ * __CHAR_BIT__ - 3; > + i = ~i; > + return i & 7; > +} > + > +/* { dg-final { scan-tree-dump "bit_xor_expr" "optimized" } } */ > +/* { dg-final { scan-tree-dump-not "bit_not_expr" "optimized" } } */ > +/* { dg-final { scan-tree-dump-not "bit_and_expr" "optimized" } } */ > Index: gcc/testsuite/gcc.dg/tree-ssa/pr69270.c > =================================================================== > --- gcc/testsuite/gcc.dg/tree-ssa/pr69270.c (revision 236194) > +++ gcc/testsuite/gcc.dg/tree-ssa/pr69270.c (working copy) > @@ -1,21 +1,19 @@ > /* { dg-do compile } */ > /* { dg-options "-O2 -fsplit-paths -fdump-tree-dom3-details" } */ > > /* There should be two references to bufferstep that turn into > constants. */ > /* { dg-final { scan-tree-dump-times "Replaced .bufferstep_\[0-9\]+. with > constant .0." 1 "dom3"} } */ > /* { dg-final { scan-tree-dump-times "Replaced .bufferstep_\[0-9\]+. with > constant .1." 1 "dom3"} } */ > > /* And some assignments ought to fold down to constants. */ > -/* { dg-final { scan-tree-dump-times "Folded to: _\[0-9\]+ = -1;" 1 "dom3"} > } */ > -/* { dg-final { scan-tree-dump-times "Folded to: _\[0-9\]+ = -2;" 1 "dom3"} > } */ > /* { dg-final { scan-tree-dump-times "Folded to: _\[0-9\]+ = 1;" 1 "dom3"} > } */ > /* { dg-final { scan-tree-dump-times "Folded to: _\[0-9\]+ = 0;" 1 "dom3"} > } */ > > /* The XOR operations should have been optimized to constants. */ > /* { dg-final { scan-tree-dump-not "bit_xor" "dom3"} } */ > > > extern int *stepsizeTable; > > void >