diff mbox

match.pd: ~X & Y to X ^ Y in some cases

Message ID alpine.DEB.2.02.1605132050510.21219@laptop-mg.saclay.inria.fr
State New
Headers show

Commit Message

Marc Glisse May 13, 2016, 7:07 p.m. UTC
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?

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.glisse@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.

Comments

Jeff Law May 16, 2016, 8:27 p.m. UTC | #1
On 05/13/2016 01:07 PM, Marc Glisse 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?
>
> 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.glisse@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.
>
>
Please use if (GIMPLE
         && ((get_nonzero_bits ...)

Rather than #if GIMPLE

With that, OK.

jeff
Marc Glisse May 16, 2016, 10:31 p.m. UTC | #2
On Mon, 16 May 2016, Jeff Law wrote:

> Please use if (GIMPLE
>        && ((get_nonzero_bits ...)
>
> Rather than #if GIMPLE

Richard asked for the reverse in some previous patch:
https://gcc.gnu.org/ml/gcc-patches/2016-04/msg01617.html

I don't really care which one we settle on...
Jeff Law May 16, 2016, 10:42 p.m. UTC | #3
On 05/16/2016 04:31 PM, Marc Glisse wrote:
> On Mon, 16 May 2016, Jeff Law wrote:
>
>> Please use if (GIMPLE
>>        && ((get_nonzero_bits ...)
>>
>> Rather than #if GIMPLE
>
> Richard asked for the reverse in some previous patch:
> https://gcc.gnu.org/ml/gcc-patches/2016-04/msg01617.html
>
> I don't really care which one we settle on...
>
If Richi wanted the reverse, then go with it.  I'm not going to object 
over something like that.

jeff
Richard Biener May 17, 2016, 11:26 a.m. UTC | #4
On Fri, May 13, 2016 at 9:07 PM, Marc Glisse <marc.glisse@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.glisse@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
>
Andrew Pinski June 3, 2021, 12:41 a.m. UTC | #5
On Fri, May 13, 2016 at 12:07 PM Marc Glisse <marc.glisse@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?

I just noticed this was PR 52254 also :).  I closed it as fixed after
putting in a reference to the revision this was committed.

Thanks,
Andrew

>
> 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.glisse@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
diff mbox

Patch

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