fold-const.c (fold_unary_loc): Move abs(abs(x)) -> abs(x)...
authorRichard Biener <rguenther@suse.de>
Tue, 30 Jun 2015 11:58:48 +0000 (11:58 +0000)
committerRichard Biener <rguenth@gcc.gnu.org>
Tue, 30 Jun 2015 11:58:48 +0000 (11:58 +0000)
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

gcc/ChangeLog
gcc/fold-const.c
gcc/match.pd

index 6a36140057e2aa2aca2368d2a7cf3e62a3b7bd38..6f919643f37a9b678cf20d985ebae5e3121643a6 100644 (file)
@@ -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
index f330d78904acde2c76eefffcd6f88104e3859d7d..67115d2377eb001a7b715a1317e9699fe78113d0 100644 (file)
@@ -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,
index 5dcbc1a47e08d9b5fcf64bf1e65e372f32f25b0c..d81ea53dae406b1b90b27c5750fae2634c6d3a64 100644 (file)
@@ -389,6 +389,9 @@ along with GCC; see the file COPYING3.  If not see
  (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))
@@ -396,6 +399,24 @@ along with GCC; see the file COPYING3.  If not see
  (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))