public inbox for gcc-patches@gcc.gnu.org
 help / color / mirror / Atom feed
* More fold_negate in match.pd
@ 2017-11-04  9:58 Marc Glisse
  2017-11-07 10:44 ` Richard Biener
  0 siblings, 1 reply; 2+ messages in thread
From: Marc Glisse @ 2017-11-04  9:58 UTC (permalink / raw)
  To: gcc-patches

[-- Attachment #1: Type: TEXT/PLAIN, Size: 743 bytes --]

Hello,

this copies some more transformations from fold_negate_expr to match.pd. 
Mostly, I wanted to add (negate (pointer_diff @0 @1)), and couldn't find 
the corresponding transformation with minus_expr... We can see about 
generalizing a bit with conversions later, I wanted to have something at 
least.

Bootstrap+regtest on powerpc64le-unknown-linux-gnu.

gcc/ChangeLog:

2017-11-04  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-04  Marc Glisse  <marc.glisse@inria.fr>

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

-- 
Marc Glisse

[-- Warning: decoded text below may be mangled, UTF-8 assumed --]
[-- Attachment #2: Type: TEXT/x-diff; name=negate.patch, Size: 5203 bytes --]

Index: gcc/fold-const.c
===================================================================
--- gcc/fold-const.c	(revision 254399)
+++ gcc/fold-const.c	(working copy)
@@ -421,34 +421,34 @@ negate_expr_p (tree t)
     case COMPLEX_EXPR:
       return negate_expr_p (TREE_OPERAND (t, 0))
 	     && negate_expr_p (TREE_OPERAND (t, 1));
 
     case CONJ_EXPR:
       return negate_expr_p (TREE_OPERAND (t, 0));
 
     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.  */
       if (negate_expr_p (TREE_OPERAND (t, 1)))
 	return true;
       /* -(A + B) -> (-A) - B.  */
       return negate_expr_p (TREE_OPERAND (t, 0));
 
     case MINUS_EXPR:
       /* 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:
       if (TYPE_UNSIGNED (type))
 	break;
       /* INT_MIN/n * n doesn't overflow while negating one operand it does
          if n is a (negative) power of two.  */
       if (INTEGRAL_TYPE_P (TREE_TYPE (t))
 	  && ! TYPE_OVERFLOW_WRAPS (TREE_TYPE (t))
 	  && ! ((TREE_CODE (TREE_OPERAND (t, 0)) == INTEGER_CST
Index: gcc/match.pd
===================================================================
--- gcc/match.pd	(revision 254399)
+++ gcc/match.pd	(working copy)
@@ -951,35 +951,50 @@ DEFINE_INT_AND_FLOAT_ROUND_FN (RINT)
  (negate @0)
  (if (!TYPE_OVERFLOW_SANITIZED (type))))
 (match negate_expr_p
  REAL_CST
  (if (REAL_VALUE_NEGATIVE (TREE_REAL_CST (t)))))
 /* VECTOR_CST handling of non-wrapping types would recurse in unsupported
    ways.  */
 (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
  (mult:c (convert1? (negate @0)) (convert2? negate_expr_p@1))
   (if (tree_nop_conversion_p (type, TREE_TYPE (@0))
        && tree_nop_conversion_p (type, TREE_TYPE (@1)))
    (mult (convert @0) (convert (negate @1)))))
  
 /* -(A + B) -> (-B) - A.  */
 (simplify
  (negate (plus:c @0 negate_expr_p@1))
  (if (!HONOR_SIGN_DEPENDENT_ROUNDING (element_mode (type))
       && !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)
  (if (!FIXED_POINT_TYPE_P (type))
  (plus @0 (negate @1))))
 
 /* Try to fold (type) X op CST -> (type) (X op ((type-x) CST))
    when profitable.
    For bitwise binary operations apply operand conversions to the
    binary operation result instead of to the operands.  This allows
@@ -1075,20 +1090,25 @@ DEFINE_INT_AND_FLOAT_ROUND_FN (RINT)
   (bit_not (bit_not @0))
   @0)
 
 /* Convert ~ (-A) to A - 1.  */
 (simplify
  (bit_not (convert? (negate @0)))
  (if (element_precision (type) <= element_precision (TREE_TYPE (@0))
       || !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)))
  (if (element_precision (type) <= element_precision (TREE_TYPE (@0))
       || !TYPE_UNSIGNED (TREE_TYPE (@0)))
   (convert (negate @0))))
 (simplify
  (bit_not (convert? (plus @0 integer_all_onesp)))
  (if (element_precision (type) <= element_precision (TREE_TYPE (@0))
       || !TYPE_UNSIGNED (TREE_TYPE (@0)))
Index: gcc/testsuite/gcc.dg/tree-ssa/negminus.c
===================================================================
--- gcc/testsuite/gcc.dg/tree-ssa/negminus.c	(nonexistent)
+++ gcc/testsuite/gcc.dg/tree-ssa/negminus.c	(working copy)
@@ -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"} } */

^ permalink raw reply	[flat|nested] 2+ messages in thread

* Re: More fold_negate in match.pd
  2017-11-04  9:58 More fold_negate in match.pd Marc Glisse
@ 2017-11-07 10:44 ` Richard Biener
  0 siblings, 0 replies; 2+ messages in thread
From: Richard Biener @ 2017-11-07 10:44 UTC (permalink / raw)
  To: Marc Glisse; +Cc: GCC Patches

On Sat, Nov 4, 2017 at 10:58 AM, Marc Glisse <marc.glisse@inria.fr> wrote:
> Hello,
>
> this copies some more transformations from fold_negate_expr to match.pd.
> Mostly, I wanted to add (negate (pointer_diff @0 @1)), and couldn't find the
> corresponding transformation with minus_expr... We can see about
> generalizing a bit with conversions later, I wanted to have something at
> least.
>
> Bootstrap+regtest on powerpc64le-unknown-linux-gnu.

Ok.

Thanks,
Richard.

> gcc/ChangeLog:
>
> 2017-11-04  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-04  Marc Glisse  <marc.glisse@inria.fr>
>
>         * gcc.dg/tree-ssa/negminus.c: New test.
>
> --
> Marc Glisse

^ permalink raw reply	[flat|nested] 2+ messages in thread

end of thread, other threads:[~2017-11-07 10:37 UTC | newest]

Thread overview: 2+ messages (download: mbox.gz / follow: Atom feed)
-- links below jump to the message on this page --
2017-11-04  9:58 More fold_negate in match.pd Marc Glisse
2017-11-07 10:44 ` Richard Biener

This is a public inbox, see mirroring instructions
for how to clone and mirror all data and code used for this inbox;
as well as URLs for read-only IMAP folder(s) and NNTP newsgroup(s).