summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorrguenth <rguenth@138bc75d-0d04-0410-961f-82ee72b054a4>2015-06-30 11:58:48 +0000
committerrguenth <rguenth@138bc75d-0d04-0410-961f-82ee72b054a4>2015-06-30 11:58:48 +0000
commit98b69bccadeae2fb64adde8ff008f79ec5963381 (patch)
treef7cd6a66425a4813b96dd9a091c09540c5b92b2e
parentd7a904bc5095619f4baa84acdf6d08ee67f693bf (diff)
downloadgcc-98b69bccadeae2fb64adde8ff008f79ec5963381.tar.gz
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). git-svn-id: svn+ssh://gcc.gnu.org/svn/gcc/trunk@225178 138bc75d-0d04-0410-961f-82ee72b054a4
-rw-r--r--gcc/ChangeLog10
-rw-r--r--gcc/fold-const.c34
-rw-r--r--gcc/match.pd73
3 files changed, 76 insertions, 41 deletions
diff --git a/gcc/ChangeLog b/gcc/ChangeLog
index 6a36140057e..6f919643f37 100644
--- a/gcc/ChangeLog
+++ b/gcc/ChangeLog
@@ -1,3 +1,13 @@
+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
diff --git a/gcc/fold-const.c b/gcc/fold-const.c
index f330d78904a..67115d2377e 100644
--- a/gcc/fold-const.c
+++ b/gcc/fold-const.c
@@ -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,
diff --git a/gcc/match.pd b/gcc/match.pd
index 5dcbc1a47e0..d81ea53dae4 100644
--- a/gcc/match.pd
+++ b/gcc/match.pd
@@ -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))