More fold_negate in match.pd
authorMarc Glisse <marc.glisse@inria.fr>
Tue, 7 Nov 2017 11:04:14 +0000 (12:04 +0100)
committerMarc Glisse <glisse@gcc.gnu.org>
Tue, 7 Nov 2017 11:04:14 +0000 (11:04 +0000)
gcc/ChangeLog:

2017-11-07  Marc Glisse  <marc.glisse@inria.fr>

* fold-const.c (negate_expr_p) [PLUS_EXPR, MINUS_EXPR]: Handle
non-scalar integral types.
* match.pd (negate_expr_p): Handle MINUS_EXPR.
(-(A-B), -(~A)): New transformations.

gcc/testsuite/ChangeLog:

2017-11-07  Marc Glisse  <marc.glisse@inria.fr>

* gcc.dg/tree-ssa/negminus.c: New test.

From-SVN: r254494

gcc/ChangeLog
gcc/fold-const.c
gcc/match.pd
gcc/testsuite/ChangeLog
gcc/testsuite/gcc.dg/tree-ssa/negminus.c [new file with mode: 0644]

index 4b4706b9bab9cf12183229f22d4cd6e10054fa0d..d06fcee491ec14680bb8cfd7a09d259536ce59f1 100644 (file)
@@ -1,3 +1,10 @@
+2017-11-07  Marc Glisse  <marc.glisse@inria.fr>
+
+       * fold-const.c (negate_expr_p) [PLUS_EXPR, MINUS_EXPR]: Handle
+       non-scalar integral types.
+       * match.pd (negate_expr_p): Handle MINUS_EXPR.
+       (-(A-B), -(~A)): New transformations.
+
 2017-11-07  Tom de Vries  <tom@codesourcery.com>
 
        * config/powerpcspe/aix43.h (SUBTARGET_OVERRIDE_OPTIONS): Remove
index 1109f5e3bc53f9e9fe238f7d7b4f7914addcafa7..e9cd968887f5d9ab356a433c4071476d54fa6bec 100644 (file)
@@ -428,7 +428,7 @@ negate_expr_p (tree t)
     case PLUS_EXPR:
       if (HONOR_SIGN_DEPENDENT_ROUNDING (element_mode (type))
          || HONOR_SIGNED_ZEROS (element_mode (type))
-         || (INTEGRAL_TYPE_P (type)
+         || (ANY_INTEGRAL_TYPE_P (type)
              && ! TYPE_OVERFLOW_WRAPS (type)))
        return false;
       /* -(A + B) -> (-B) - A.  */
@@ -441,7 +441,7 @@ negate_expr_p (tree t)
       /* We can't turn -(A-B) into B-A when we honor signed zeros.  */
       return !HONOR_SIGN_DEPENDENT_ROUNDING (element_mode (type))
             && !HONOR_SIGNED_ZEROS (element_mode (type))
-            && (! INTEGRAL_TYPE_P (type)
+            && (! ANY_INTEGRAL_TYPE_P (type)
                 || TYPE_OVERFLOW_WRAPS (type));
 
     case MULT_EXPR:
index f22286e0c2e49108809cb0586e584d77badc0f8d..9113fd183acf7efd153b714b4c60d1736bfd067e 100644 (file)
@@ -958,6 +958,12 @@ DEFINE_INT_AND_FLOAT_ROUND_FN (RINT)
 (match negate_expr_p
  VECTOR_CST
  (if (FLOAT_TYPE_P (TREE_TYPE (type)) || TYPE_OVERFLOW_WRAPS (type))))
+(match negate_expr_p
+ (minus @0 @1)
+ (if ((ANY_INTEGRAL_TYPE_P (type) && TYPE_OVERFLOW_WRAPS (type))
+      || (FLOAT_TYPE_P (type)
+         && !HONOR_SIGN_DEPENDENT_ROUNDING (type)
+         && !HONOR_SIGNED_ZEROS (type)))))
 
 /* (-A) * (-B) -> A * B  */
 (simplify
@@ -973,6 +979,15 @@ DEFINE_INT_AND_FLOAT_ROUND_FN (RINT)
       && !HONOR_SIGNED_ZEROS (element_mode (type)))
   (minus (negate @1) @0)))
 
+/* -(A - B) -> B - A.  */
+(simplify
+ (negate (minus @0 @1))
+ (if ((ANY_INTEGRAL_TYPE_P (type) && !TYPE_OVERFLOW_SANITIZED (type))
+      || (FLOAT_TYPE_P (type)
+         && !HONOR_SIGN_DEPENDENT_ROUNDING (type)
+         && !HONOR_SIGNED_ZEROS (type)))
+  (minus @1 @0)))
+
 /* A - B -> A + (-B) if B is easily negatable.  */
 (simplify
  (minus @0 negate_expr_p@1)
@@ -1082,6 +1097,11 @@ DEFINE_INT_AND_FLOAT_ROUND_FN (RINT)
       || !TYPE_UNSIGNED (TREE_TYPE (@0)))
   (convert (minus @0 { build_each_one_cst (TREE_TYPE (@0)); }))))
 
+/* Convert - (~A) to A + 1.  */
+(simplify
+ (negate (nop_convert (bit_not @0)))
+ (plus (view_convert @0) { build_each_one_cst (type); }))
+
 /* Convert ~ (A - 1) or ~ (A + -1) to -A.  */
 (simplify
  (bit_not (convert? (minus @0 integer_each_onep)))
index 6403283dafa568e006fa908e76dc995196f9623a..7f33b7c7337f51bcb32bb521228b412dfb77614c 100644 (file)
@@ -1,3 +1,7 @@
+2017-11-07  Marc Glisse  <marc.glisse@inria.fr>
+
+       * gcc.dg/tree-ssa/negminus.c: New test.
+
 2017-11-06  Jeff Law  <law@redhat.com>
 
        * gcc.target/i386/stack-check-12.c: Revert to initial version.  Then..
diff --git a/gcc/testsuite/gcc.dg/tree-ssa/negminus.c b/gcc/testsuite/gcc.dg/tree-ssa/negminus.c
new file mode 100644 (file)
index 0000000..f857a00
--- /dev/null
@@ -0,0 +1,21 @@
+/* { dg-do compile } */
+/* { dg-options "-O -fno-rounding-math -fno-signed-zeros -fdump-tree-optimized-raw" } */
+
+double f(double a, double b){
+    double c = a - b;
+    return -c;
+}
+
+int g(unsigned x){
+    unsigned y = ~x;
+    int z = (int) y;
+    return -z;
+}
+
+unsigned h(unsigned a, unsigned b, unsigned c){
+    unsigned d = b - c;
+    unsigned e = a + d;
+    return -e;
+}
+
+/* { dg-final { scan-tree-dump-not "negate_expr" "optimized"} } */