diff options
author | glisse <glisse@138bc75d-0d04-0410-961f-82ee72b054a4> | 2016-05-10 19:52:20 +0000 |
---|---|---|
committer | glisse <glisse@138bc75d-0d04-0410-961f-82ee72b054a4> | 2016-05-10 19:52:20 +0000 |
commit | f9153689e2ce4b8e19fbe2303a545d3cbedfa34e (patch) | |
tree | 0a73b6e9c04150d305bc301e3cee930e37a9d50d /gcc/match.pd | |
parent | 3604118da2f0e62a75ebd6d206a8cd3ef2573b01 (diff) | |
download | gcc-f9153689e2ce4b8e19fbe2303a545d3cbedfa34e.tar.gz |
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.
git-svn-id: svn+ssh://gcc.gnu.org/svn/gcc/trunk@236103 138bc75d-0d04-0410-961f-82ee72b054a4
Diffstat (limited to 'gcc/match.pd')
-rw-r--r-- | gcc/match.pd | 39 |
1 files changed, 35 insertions, 4 deletions
diff --git a/gcc/match.pd b/gcc/match.pd index e511e9a6b9b..5b3cb3bfd5e 100644 --- a/gcc/match.pd +++ b/gcc/match.pd @@ -674,10 +674,12 @@ DEFINE_INT_AND_FLOAT_ROUND_FN (RINT) (if (tree_nop_conversion_p (type, TREE_TYPE (@0))) (bit_xor (convert @0) (bit_not @1)))) -/* Fold (X & Y) ^ Y as ~X & Y. */ -(simplify - (bit_xor:c (bit_and:c @0 @1) @1) - (bit_and (bit_not @0) @1)) +/* Fold (X & Y) ^ Y and (X ^ Y) & Y as ~X & Y. */ +(for opo (bit_and bit_xor) + opi (bit_xor bit_and) + (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 operands are another bit-wise operation with a common input. If so, @@ -693,6 +695,35 @@ DEFINE_INT_AND_FLOAT_ROUND_FN (RINT) && tree_nop_conversion_p (type, TREE_TYPE (@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 (abs (abs@1 @0)) |