diff options
Diffstat (limited to 'gcc/match.pd')
-rw-r--r-- | gcc/match.pd | 54 |
1 files changed, 54 insertions, 0 deletions
diff --git a/gcc/match.pd b/gcc/match.pd index c1e0963..3b02db3 100644 --- a/gcc/match.pd +++ b/gcc/match.pd @@ -779,6 +779,60 @@ DEFINE_INT_AND_FLOAT_ROUND_FN (RINT) (bit_xor @0 @1))) #endif +/* For constants M and N, if M == (1LL << cst) - 1 && (N & M) == M, + ((A & N) + B) & M -> (A + B) & M + Similarly if (N & M) == 0, + ((A | N) + B) & M -> (A + B) & M + and for - instead of + (or unary - instead of +) + and/or ^ instead of |. + If B is constant and (B & M) == 0, fold into A & M. */ +(for op (plus minus) + (for bitop (bit_and bit_ior bit_xor) + (simplify + (bit_and (op:s (bitop:s@0 @3 INTEGER_CST@4) @1) INTEGER_CST@2) + (with + { tree pmop[2]; + tree utype = fold_bit_and_mask (TREE_TYPE (@0), @2, op, @0, bitop, + @3, @4, @1, ERROR_MARK, NULL_TREE, + NULL_TREE, pmop); } + (if (utype) + (convert (bit_and (op (convert:utype { pmop[0]; }) + (convert:utype { pmop[1]; })) + (convert:utype @2)))))) + (simplify + (bit_and (op:s @0 (bitop:s@1 @3 INTEGER_CST@4)) INTEGER_CST@2) + (with + { tree pmop[2]; + tree utype = fold_bit_and_mask (TREE_TYPE (@0), @2, op, @0, ERROR_MARK, + NULL_TREE, NULL_TREE, @1, bitop, @3, + @4, pmop); } + (if (utype) + (convert (bit_and (op (convert:utype { pmop[0]; }) + (convert:utype { pmop[1]; })) + (convert:utype @2))))))) + (simplify + (bit_and (op:s @0 @1) INTEGER_CST@2) + (with + { tree pmop[2]; + tree utype = fold_bit_and_mask (TREE_TYPE (@0), @2, op, @0, ERROR_MARK, + NULL_TREE, NULL_TREE, @1, ERROR_MARK, + NULL_TREE, NULL_TREE, pmop); } + (if (utype) + (convert (bit_and (op (convert:utype { pmop[0]; }) + (convert:utype { pmop[1]; })) + (convert:utype @2))))))) +(for bitop (bit_and bit_ior bit_xor) + (simplify + (bit_and (negate:s (bitop:s@0 @2 INTEGER_CST@3)) INTEGER_CST@1) + (with + { tree pmop[2]; + tree utype = fold_bit_and_mask (TREE_TYPE (@0), @1, NEGATE_EXPR, @0, + bitop, @2, @3, NULL_TREE, ERROR_MARK, + NULL_TREE, NULL_TREE, pmop); } + (if (utype) + (convert (bit_and (negate (convert:utype { pmop[0]; })) + (convert:utype @1))))))) + /* X % Y is smaller than Y. */ (for cmp (lt ge) (simplify |