This is the mail archive of the
gcc-patches@gcc.gnu.org
mailing list for the GCC project.
match.pd: ~X & Y to X ^ Y in some cases
- From: Marc Glisse <marc dot glisse at inria dot fr>
- To: gcc-patches at gcc dot gnu dot org
- Date: Fri, 13 May 2016 21:07:10 +0200 (CEST)
- Subject: match.pd: ~X & Y to X ^ Y in some cases
- Authentication-results: sourceware.org; auth=none
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.
--
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