Commit b14a9c57 by Richard Biener Committed by Richard Biener

fold-const.c (fold_unary_loc): Move abs(abs(x)) -> abs(x)...

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).

From-SVN: r225178
parent ebc30bf9
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
......
......@@ -8125,9 +8125,6 @@ fold_unary_loc (location_t loc, enum tree_code code, tree type, tree op0)
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)
......@@ -8155,33 +8152,14 @@ fold_unary_loc (location_t loc, enum tree_code code, tree type, tree op0)
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,
......
......@@ -390,12 +390,33 @@ along with GCC; see the file COPYING3. If not see
(bit_and @0 @1))
(simplify
(abs (abs@1 @0))
@1)
(simplify
(abs (negate @0))
(abs @0))
(simplify
(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.
......@@ -427,6 +448,19 @@ along with GCC; see the file COPYING3. If not see
|| 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
......@@ -474,19 +508,6 @@ along with GCC; see the file COPYING3. If not see
(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:
......@@ -515,6 +536,32 @@ along with GCC; see the file COPYING3. If not see
(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))
......
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