+2015-06-30 Richard Biener <rguenther@suse.de>
+
+ * fold-const.c (fold_unary_loc): Move abs(abs(x)) -> abs(x),
+ ~ (-A) to A - 1, ~ (A - 1) or ~ (A + -1) to -A and some cases of
+ ~(X ^ Y) to ~X ^ Y or X ^ ~Y if ~X or ~Y simplify to ...
+ * match.pd: ... here.
+ Add a few cases of A - B -> A + (-B) when B "easily" negates.
+ Move (x & y) | x -> x and friends before
+ (x | CST1) & CST2 -> (x & CST2) | (CST1 & CST2).
+
2015-06-30 Eric Botcazou <ebotcazou@adacore.com>
* config/sparc/leon.md (leon_load): Enable for all LEON variants if
TREE_TYPE (targ0),
targ0));
}
- /* ABS_EXPR<ABS_EXPR<x>> = ABS_EXPR<x> even if flag_wrapv is on. */
- else if (TREE_CODE (arg0) == ABS_EXPR)
- return arg0;
/* Strip sign ops from argument. */
if (TREE_CODE (type) == REAL_TYPE)
return NULL_TREE;
case BIT_NOT_EXPR:
- /* Convert ~ (-A) to A - 1. */
- if (INTEGRAL_TYPE_P (type) && TREE_CODE (arg0) == NEGATE_EXPR)
- return fold_build2_loc (loc, MINUS_EXPR, type,
- fold_convert_loc (loc, type, TREE_OPERAND (arg0, 0)),
- build_int_cst (type, 1));
- /* Convert ~ (A - 1) or ~ (A + -1) to -A. */
- else if (INTEGRAL_TYPE_P (type)
- && ((TREE_CODE (arg0) == MINUS_EXPR
- && integer_onep (TREE_OPERAND (arg0, 1)))
- || (TREE_CODE (arg0) == PLUS_EXPR
- && integer_all_onesp (TREE_OPERAND (arg0, 1)))))
- {
- /* Perform the negation in ARG0's type and only then convert
- to TYPE as to avoid introducing undefined behavior. */
- tree t = fold_build1_loc (loc, NEGATE_EXPR,
- TREE_TYPE (TREE_OPERAND (arg0, 0)),
- TREE_OPERAND (arg0, 0));
- return fold_convert_loc (loc, type, t);
- }
/* Convert ~(X ^ Y) to ~X ^ Y or X ^ ~Y if ~X or ~Y simplify. */
- else if (TREE_CODE (arg0) == BIT_XOR_EXPR
- && (tem = fold_unary_loc (loc, BIT_NOT_EXPR, type,
- fold_convert_loc (loc, type,
- TREE_OPERAND (arg0, 0)))))
+ if (TREE_CODE (arg0) == BIT_XOR_EXPR
+ && (tem = fold_unary_loc (loc, BIT_NOT_EXPR, type,
+ fold_convert_loc (loc, type,
+ TREE_OPERAND (arg0, 0)))))
return fold_build2_loc (loc, BIT_XOR_EXPR, type, tem,
- fold_convert_loc (loc, type,
- TREE_OPERAND (arg0, 1)));
+ fold_convert_loc (loc, type,
+ TREE_OPERAND (arg0, 1)));
else if (TREE_CODE (arg0) == BIT_XOR_EXPR
&& (tem = fold_unary_loc (loc, BIT_NOT_EXPR, type,
fold_convert_loc (loc, type,
(bit_and:c (bit_ior:c @0 @1) (bit_xor:c @1 (bit_not @0)))
(bit_and @0 @1))
+(simplify
+ (abs (abs@1 @0))
+ @1)
(simplify
(abs (negate @0))
(abs @0))
(abs tree_expr_nonnegative_p@0)
@0)
+/* A - B -> A + (-B) if B is easily negatable. This just covers
+ very few cases of "easily negatable", effectively inlining negate_expr_p. */
+(simplify
+ (minus @0 INTEGER_CST@1)
+ (if ((INTEGRAL_TYPE_P (type)
+ && TYPE_OVERFLOW_WRAPS (type))
+ || (!TYPE_OVERFLOW_SANITIZED (type)
+ && may_negate_without_overflow_p (@1)))
+ (plus @0 (negate @1))))
+(simplify
+ (minus @0 REAL_CST@1)
+ (if (REAL_VALUE_NEGATIVE (TREE_REAL_CST (@1)))
+ (plus @0 (negate @1))))
+(simplify
+ (minus @0 VECTOR_CST@1)
+ (if (FLOAT_TYPE_P (type) || TYPE_OVERFLOW_WRAPS (type))
+ (plus @0 (negate @1))))
+
/* Try to fold (type) X op CST -> (type) (X op ((type-x) CST))
when profitable.
|| TYPE_PRECISION (type) != GET_MODE_PRECISION (TYPE_MODE (type))))
(convert (bitop @0 (convert @1))))))
+(for bitop (bit_and bit_ior)
+ rbitop (bit_ior bit_and)
+ /* (x | y) & x -> x */
+ /* (x & y) | x -> x */
+ (simplify
+ (bitop:c (rbitop:c @0 @1) @0)
+ @0)
+ /* (~x | y) & x -> x & y */
+ /* (~x & y) | x -> x | y */
+ (simplify
+ (bitop:c (rbitop:c (bit_not @0) @1) @0)
+ (bitop @0 @1)))
+
/* Simplify (A & B) OP0 (C & B) to (A OP0 C) & B. */
(for bitop (bit_and bit_ior bit_xor)
(simplify
(op:c truth_valued_p@0 (logical_inverted_value @0))
{ constant_boolean_node (true, type); }))
-(for bitop (bit_and bit_ior)
- rbitop (bit_ior bit_and)
- /* (x | y) & x -> x */
- /* (x & y) | x -> x */
- (simplify
- (bitop:c (rbitop:c @0 @1) @0)
- @0)
- /* (~x | y) & x -> x & y */
- /* (~x & y) | x -> x | y */
- (simplify
- (bitop:c (rbitop:c (bit_not @0) @1) @0)
- (bitop @0 @1)))
-
/* If arg1 and arg2 are booleans (or any single bit type)
then try to 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)))
+ (convert (minus @0 { build_one_cst (TREE_TYPE (@0)); }))))
+
+/* Convert ~ (A - 1) or ~ (A + -1) to -A. */
+(simplify
+ (bit_not (convert? (minus @0 integer_onep)))
+ (if (tree_nop_conversion_p (type, TREE_TYPE (@0)))
+ (convert (negate @0))))
+(simplify
+ (bit_not (convert? (plus @0 integer_all_onesp)))
+ (if (tree_nop_conversion_p (type, 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)))
+ (convert (bit_xor @0 @1))))
+
/* (x & ~m) | (y & m) -> ((x ^ y) & m) ^ x */
(simplify
(bit_ior:c (bit_and:c@3 @0 (bit_not @2)) (bit_and:c@4 @1 @2))