Index: gcc/match.pd =================================================================== --- gcc/match.pd (revision 236488) +++ gcc/match.pd (working copy) @@ -447,21 +447,22 @@ DEFINE_INT_AND_FLOAT_ROUND_FN (RINT) (for ops (conj negate) (for cabss (CABS) (simplify (cabss (ops @0)) (cabss @0)))) /* Fold (a * (1 << b)) into (a << b) */ (simplify (mult:c @0 (convert? (lshift integer_onep@1 @2))) (if (! FLOAT_TYPE_P (type) - && tree_nop_conversion_p (type, TREE_TYPE (@1))) + && (element_precision (type) <= element_precision (TREE_TYPE (@1)) + || TYPE_UNSIGNED (TREE_TYPE (@1)))) (lshift @0 @2))) /* Fold (C1/X)*C2 into (C1*C2)/X. */ (simplify (mult (rdiv@3 REAL_CST@0 @1) REAL_CST@2) (if (flag_associative_math && single_use (@3)) (with { tree tem = const_binop (MULT_EXPR, type, @0, @2); } (if (tem) @@ -648,22 +649,22 @@ DEFINE_INT_AND_FLOAT_ROUND_FN (RINT) (simplify (bit_and:c (bit_ior:c @0 @1) (bit_xor:c @1 (bit_not @0))) (bit_and @0 @1)) /* ~x & ~y -> ~(x | y) ~x | ~y -> ~(x & y) */ (for op (bit_and bit_ior) rop (bit_ior bit_and) (simplify (op (convert1? (bit_not @0)) (convert2? (bit_not @1))) - (if (tree_nop_conversion_p (type, TREE_TYPE (@0)) - && tree_nop_conversion_p (type, TREE_TYPE (@1))) + (if (element_precision (type) <= element_precision (TREE_TYPE (@0)) + && element_precision (type) <= element_precision (TREE_TYPE (@1))) (bit_not (rop (convert @0) (convert @1)))))) /* If we are XORing or adding two BIT_AND_EXPR's, both of which are and'ing with a constant, and the two constants have no bits in common, we should treat this as a BIT_IOR_EXPR since this may produce more simplifications. */ (for op (bit_xor plus) (simplify (op (convert1? (bit_and@4 @0 INTEGER_CST@1)) (convert2? (bit_and@5 @2 INTEGER_CST@3))) @@ -674,22 +675,22 @@ DEFINE_INT_AND_FLOAT_ROUND_FN (RINT) /* (X | Y) ^ X -> Y & ~ X*/ (simplify (bit_xor:c (convert? (bit_ior:c @0 @1)) (convert? @0)) (if (tree_nop_conversion_p (type, TREE_TYPE (@0))) (convert (bit_and @1 (bit_not @0))))) /* Convert ~X ^ ~Y to X ^ Y. */ (simplify (bit_xor (convert1? (bit_not @0)) (convert2? (bit_not @1))) - (if (tree_nop_conversion_p (type, TREE_TYPE (@0)) - && tree_nop_conversion_p (type, TREE_TYPE (@1))) + (if (element_precision (type) <= element_precision (TREE_TYPE (@0)) + && element_precision (type) <= element_precision (TREE_TYPE (@1))) (bit_xor (convert @0) (convert @1)))) /* Convert ~X ^ C to X ^ ~C. */ (simplify (bit_xor (convert? (bit_not @0)) INTEGER_CST@1) (if (tree_nop_conversion_p (type, TREE_TYPE (@0))) (bit_xor (convert @0) (bit_not @1)))) /* Fold (X & Y) ^ Y and (X ^ Y) & Y as ~X & Y. */ (for opo (bit_and bit_xor) @@ -715,22 +716,21 @@ DEFINE_INT_AND_FLOAT_ROUND_FN (RINT) /* 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))) + (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)) @@ -908,31 +908,34 @@ DEFINE_INT_AND_FLOAT_ROUND_FN (RINT) (le @0 @1))) /* ~~x -> x */ (simplify (bit_not (bit_not @0)) @0) /* Convert ~ (-A) to A - 1. */ (simplify (bit_not (convert? (negate @0))) - (if (tree_nop_conversion_p (type, TREE_TYPE (@0))) + (if (element_precision (type) <= element_precision (TREE_TYPE (@0)) + || !TYPE_UNSIGNED (TREE_TYPE (@0))) (convert (minus @0 { build_each_one_cst (TREE_TYPE (@0)); })))) /* Convert ~ (A - 1) or ~ (A + -1) to -A. */ (simplify (bit_not (convert? (minus @0 integer_each_onep))) - (if (tree_nop_conversion_p (type, TREE_TYPE (@0))) + (if (element_precision (type) <= element_precision (TREE_TYPE (@0)) + || !TYPE_UNSIGNED (TREE_TYPE (@0))) (convert (negate @0)))) (simplify (bit_not (convert? (plus @0 integer_all_onesp))) - (if (tree_nop_conversion_p (type, TREE_TYPE (@0))) + (if (element_precision (type) <= element_precision (TREE_TYPE (@0)) + || !TYPE_UNSIGNED (TREE_TYPE (@0))) (convert (negate @0)))) /* Part of convert ~(X ^ Y) to ~X ^ Y or X ^ ~Y if ~X or ~Y simplify. */ (simplify (bit_not (convert? (bit_xor @0 INTEGER_CST@1))) (if (tree_nop_conversion_p (type, TREE_TYPE (@0))) (convert (bit_xor @0 (bit_not @1))))) (simplify (bit_not (convert? (bit_xor:c (bit_not @0) @1))) (if (tree_nop_conversion_p (type, TREE_TYPE (@0))) @@ -1498,34 +1501,37 @@ DEFINE_INT_AND_FLOAT_ROUND_FN (RINT) (simplify (shift (convert?:s (bit_op:s @0 INTEGER_CST@2)) INTEGER_CST@1) (if (tree_nop_conversion_p (type, TREE_TYPE (@0))) (with { tree mask = int_const_binop (shift, fold_convert (type, @2), @1); } (bit_op (shift (convert @0) @1) { mask; })))))) /* ~(~X >> Y) -> X >> Y (for arithmetic shift). */ (simplify (bit_not (convert1?:s (rshift:s (convert2?@0 (bit_not @1)) @2))) (if (!TYPE_UNSIGNED (TREE_TYPE (@0)) - && element_precision (TREE_TYPE (@0)) - <= element_precision (TREE_TYPE (@1)) - && element_precision (type) <= element_precision (TREE_TYPE (@0))) + && (element_precision (TREE_TYPE (@0)) + <= element_precision (TREE_TYPE (@1)) + || !TYPE_UNSIGNED (TREE_TYPE (@1)))) (with { tree shift_type = TREE_TYPE (@0); } (convert (rshift (convert:shift_type @1) @2))))) /* ~(~X >>r Y) -> X >>r Y ~(~X < X <> b); } int sl (int a, int b) { return ~((~a) << b); } -typedef __INT32_TYPE__ int32_t; +typedef unsigned __INT32_TYPE__ uint32_t; typedef __INT64_TYPE__ int64_t; int64_t -asr_widen1 (int32_t a, int b) +asr_widen1 (uint32_t a, int b) { return ~((int64_t)(~a) >> b); } int64_t -asr_widen2 (int32_t a, int b) +asr_widen2 (uint32_t a, int b) { return ~(int64_t)(~a >> b); } /* { dg-final { scan-tree-dump-times "~" 8 "cddce1" } } */