Commit e39dab2c by Marc Glisse Committed by Marc Glisse

Simple bitop reassoc in match.pd

2016-05-10  Marc Glisse  <marc.glisse@inria.fr>

gcc/
	* fold-const.c (fold_binary_loc) [(X ^ Y) & Y]: Remove and merge with...
	* match.pd ((X & Y) ^ Y): ... this.
	((X & Y) & Y, (X | Y) | Y, (X ^ Y) ^ Y, (X & Y) & (X & Z), (X | Y)
	| (X | Z), (X ^ Y) ^ (X ^ Z)): New transformations.

gcc/testsuite/
	* gcc.dg/tree-ssa/bit-assoc.c: New testcase.
	* gcc.dg/tree-ssa/pr69270.c: Adjust.
	* gcc.dg/tree-ssa/vrp59.c: Disable forwprop.

From-SVN: r236103
parent 601070fc
2016-05-10 Marc Glisse <marc.glisse@inria.fr>
* fold-const.c (fold_binary_loc) [(X ^ Y) & Y]: Remove and merge with...
* match.pd ((X & Y) ^ Y): ... this.
((X & Y) & Y, (X | Y) | Y, (X ^ Y) ^ Y, (X & Y) & (X & Z), (X | Y)
| (X | Z), (X ^ Y) ^ (X ^ Z)): New transformations.
2016-05-10 David Malcolm <dmalcolm@redhat.com> 2016-05-10 David Malcolm <dmalcolm@redhat.com>
* read-md.c (require_char_ws): New function. * read-md.c (require_char_ws): New function.
......
...@@ -10071,45 +10071,6 @@ fold_binary_loc (location_t loc, ...@@ -10071,45 +10071,6 @@ fold_binary_loc (location_t loc,
build_zero_cst (TREE_TYPE (tem))); build_zero_cst (TREE_TYPE (tem)));
} }
/* Fold (X ^ Y) & Y as ~X & Y. */
if (TREE_CODE (arg0) == BIT_XOR_EXPR
&& operand_equal_p (TREE_OPERAND (arg0, 1), arg1, 0))
{
tem = fold_convert_loc (loc, type, TREE_OPERAND (arg0, 0));
return fold_build2_loc (loc, BIT_AND_EXPR, type,
fold_build1_loc (loc, BIT_NOT_EXPR, type, tem),
fold_convert_loc (loc, type, arg1));
}
/* Fold (X ^ Y) & X as ~Y & X. */
if (TREE_CODE (arg0) == BIT_XOR_EXPR
&& operand_equal_p (TREE_OPERAND (arg0, 0), arg1, 0)
&& reorder_operands_p (TREE_OPERAND (arg0, 1), arg1))
{
tem = fold_convert_loc (loc, type, TREE_OPERAND (arg0, 1));
return fold_build2_loc (loc, BIT_AND_EXPR, type,
fold_build1_loc (loc, BIT_NOT_EXPR, type, tem),
fold_convert_loc (loc, type, arg1));
}
/* Fold X & (X ^ Y) as X & ~Y. */
if (TREE_CODE (arg1) == BIT_XOR_EXPR
&& operand_equal_p (arg0, TREE_OPERAND (arg1, 0), 0))
{
tem = fold_convert_loc (loc, type, TREE_OPERAND (arg1, 1));
return fold_build2_loc (loc, BIT_AND_EXPR, type,
fold_convert_loc (loc, type, arg0),
fold_build1_loc (loc, BIT_NOT_EXPR, type, tem));
}
/* Fold X & (Y ^ X) as ~Y & X. */
if (TREE_CODE (arg1) == BIT_XOR_EXPR
&& operand_equal_p (arg0, TREE_OPERAND (arg1, 1), 0)
&& reorder_operands_p (arg0, TREE_OPERAND (arg1, 0)))
{
tem = fold_convert_loc (loc, type, TREE_OPERAND (arg1, 0));
return fold_build2_loc (loc, BIT_AND_EXPR, type,
fold_build1_loc (loc, BIT_NOT_EXPR, type, tem),
fold_convert_loc (loc, type, arg0));
}
/* Fold (X * Y) & -(1 << CST) to X * Y if Y is a constant /* Fold (X * Y) & -(1 << CST) to X * Y if Y is a constant
multiple of 1 << CST. */ multiple of 1 << CST. */
if (TREE_CODE (arg1) == INTEGER_CST) if (TREE_CODE (arg1) == INTEGER_CST)
......
...@@ -674,10 +674,12 @@ DEFINE_INT_AND_FLOAT_ROUND_FN (RINT) ...@@ -674,10 +674,12 @@ DEFINE_INT_AND_FLOAT_ROUND_FN (RINT)
(if (tree_nop_conversion_p (type, TREE_TYPE (@0))) (if (tree_nop_conversion_p (type, TREE_TYPE (@0)))
(bit_xor (convert @0) (bit_not @1)))) (bit_xor (convert @0) (bit_not @1))))
/* Fold (X & Y) ^ Y as ~X & Y. */ /* Fold (X & Y) ^ Y and (X ^ Y) & Y as ~X & Y. */
(simplify (for opo (bit_and bit_xor)
(bit_xor:c (bit_and:c @0 @1) @1) opi (bit_xor bit_and)
(bit_and (bit_not @0) @1)) (simplify
(opo:c (opi:c @0 @1) @1)
(bit_and (bit_not @0) @1)))
/* Given a bit-wise operation CODE applied to ARG0 and ARG1, see if both /* Given a bit-wise operation CODE applied to ARG0 and ARG1, see if both
operands are another bit-wise operation with a common input. If so, operands are another bit-wise operation with a common input. If so,
...@@ -693,6 +695,35 @@ DEFINE_INT_AND_FLOAT_ROUND_FN (RINT) ...@@ -693,6 +695,35 @@ DEFINE_INT_AND_FLOAT_ROUND_FN (RINT)
&& tree_nop_conversion_p (type, TREE_TYPE (@2))) && tree_nop_conversion_p (type, TREE_TYPE (@2)))
(rop (convert @0) (op (convert @1) (convert @2)))))) (rop (convert @0) (op (convert @1) (convert @2))))))
/* Some simple reassociation for bit operations, also handled in reassoc. */
/* (X & Y) & Y -> X & Y
(X | Y) | Y -> X | Y */
(for op (bit_and bit_ior)
(simplify
(op:c (convert?@2 (op:c @0 @1)) (convert? @1))
@2))
/* (X ^ Y) ^ Y -> X */
(simplify
(bit_xor:c (convert? (bit_xor:c @0 @1)) (convert? @1))
(if (tree_nop_conversion_p (type, TREE_TYPE (@0)))
(convert @0)))
/* (X & Y) & (X & Z) -> (X & Y) & Z
(X | Y) | (X | Z) -> (X | Y) | Z */
(for op (bit_and bit_ior)
(simplify
(op:c (convert1?@3 (op:c@4 @0 @1)) (convert2?@5 (op:c@6 @0 @2)))
(if (tree_nop_conversion_p (type, TREE_TYPE (@1))
&& tree_nop_conversion_p (type, TREE_TYPE (@2)))
(if (single_use (@5) && single_use (@6))
(op @3 (convert @2))
(if (single_use (@3) && single_use (@4))
(op (convert @1) @5))))))
/* (X ^ Y) ^ (X ^ Z) -> Y ^ Z */
(simplify
(bit_xor (convert1? (bit_xor:c @0 @1)) (convert2? (bit_xor:c @0 @2)))
(if (tree_nop_conversion_p (type, TREE_TYPE (@1))
&& tree_nop_conversion_p (type, TREE_TYPE (@2)))
(convert (bit_xor @1 @2))))
(simplify (simplify
(abs (abs@1 @0)) (abs (abs@1 @0))
......
2016-05-10 Marc Glisse <marc.glisse@inria.fr>
* gcc.dg/tree-ssa/bit-assoc.c: New testcase.
* gcc.dg/tree-ssa/pr69270.c: Adjust.
* gcc.dg/tree-ssa/vrp59.c: Disable forwprop.
2016-05-10 Ilya Enkovich <ilya.enkovich@intel.com> 2016-05-10 Ilya Enkovich <ilya.enkovich@intel.com>
PR target/70799 PR target/70799
......
/* { dg-do compile } */
/* { dg-options "-O -fdump-tree-forwprop1-details -fdump-tree-ccp1-details" } */
int f1(int a, int b){
int c = a & b;
return c & b;
}
int f2(int a, int b){
int c = a | b;
return b | c;
}
int g1(int a, int b, int c){
int d = a & b;
int e = b & c;
return d & e;
}
int g2(int a, int b, int c){
int d = a | b;
int e = c | b;
return d | e;
}
int g3(int a, int b, int c){
int d = a ^ b;
int e = b ^ c;
return e ^ d;
}
/* { dg-final { scan-tree-dump-times "Match-and-simplified" 2 "ccp1" } } */
/* { dg-final { scan-tree-dump-times "gimple_simplified" 3 "forwprop1" } } */
...@@ -7,8 +7,10 @@ ...@@ -7,8 +7,10 @@
/* { dg-final { scan-tree-dump-times "Replaced .bufferstep_\[0-9\]+. with constant .1." 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. */ /* And some assignments ought to fold down to constants. */
/* { dg-final { scan-tree-dump-times "Folded to: _\[0-9\]+ = 1;" 2 "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;" 2 "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. */ /* The XOR operations should have been optimized to constants. */
/* { dg-final { scan-tree-dump-not "bit_xor" "dom3"} } */ /* { dg-final { scan-tree-dump-not "bit_xor" "dom3"} } */
......
/* { dg-do compile } */ /* { dg-do compile } */
/* { dg-options "-O2 -fno-tree-ccp -fdump-tree-vrp1" } */ /* { dg-options "-O2 -fno-tree-ccp -fno-tree-forwprop -fdump-tree-vrp1" } */
int f(int x) int f(int x)
{ {
......
Markdown is supported
0% or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment