public inbox for gcc-patches@gcc.gnu.org
 help / color / mirror / Atom feed
* Fold more boolean expressions
@ 2018-09-11 13:54 MCC CS
  2018-09-11 21:24 ` Marc Glisse
  0 siblings, 1 reply; 15+ messages in thread
From: MCC CS @ 2018-09-11 13:54 UTC (permalink / raw)
  To: gcc-patches

Hi everyone,

this patch optimizes a few boolean expressions,
and fixes some unneeded whitespace.
Will do a full make check soon.
 
Thanks for your time.

2018-09-11 MCC CS <deswurstes@users.noreply.github.com>

	gcc/
	PR tree-optimization/87261
	* match.pd: Add boolean optimizations,
	fix whitespace.

2018-09-11 MCC CS <deswurstes@users.noreply.github.com>

	gcc/testsuite/
	PR tree-optimization/87261
	* gcc.dg/pr87261.c: New test.

Index: gcc/match.pd
===================================================================
--- gcc/match.pd	(revision 264170)
+++ gcc/match.pd	(working copy)
@@ -92,7 +92,7 @@ DEFINE_INT_AND_FLOAT_ROUND_FN (RINT)
   IFN_FMA IFN_FMS IFN_FNMA IFN_FNMS)
 (define_operator_list COND_TERNARY
   IFN_COND_FMA IFN_COND_FMS IFN_COND_FNMA IFN_COND_FNMS)
-    
+
 /* As opposed to convert?, this still creates a single pattern, so
    it is not a suitable replacement for convert? in all cases.  */
 (match (nop_convert @0)
@@ -106,7 +106,7 @@ DEFINE_INT_AND_FLOAT_ROUND_FN (RINT)
       && tree_nop_conversion_p (TREE_TYPE (type), TREE_TYPE (TREE_TYPE (@0))))))
 /* This one has to be last, or it shadows the others.  */
 (match (nop_convert @0)
- @0) 
+ @0)
 
 /* Transform likes of (char) ABS_EXPR <(int) x> into (char) ABSU_EXPR <x>
    ABSU_EXPR returns unsigned absolute value of the operand and the operand
@@ -285,7 +285,7 @@ DEFINE_INT_AND_FLOAT_ROUND_FN (RINT)
      And not for _Fract types where we can't build 1.  */
   (if (!integer_zerop (@0) && !ALL_FRACT_MODE_P (TYPE_MODE (type)))
    { build_one_cst (type); }))
- /* X / abs (X) is X < 0 ? -1 : 1.  */ 
+ /* X / abs (X) is X < 0 ? -1 : 1.  */
  (simplify
    (div:C @0 (abs @0))
    (if (INTEGRAL_TYPE_P (type)
@@ -921,6 +921,31 @@ DEFINE_INT_AND_FLOAT_ROUND_FN (RINT)
   (bitop:c @0 (bit_not (bitop:cs @0 @1)))
   (bitop @0 (bit_not @1))))
 
+/* (~x & y) | ~(x | y) -> ~x */
+(simplify
+ (bit_ior:c (bit_and:c (bit_not @0) @1) (bit_not (bit_ior:s @0 @1)))
+ (bit_not @0))
+
+/* (x | y) ^ (x | ~y) -> ~x */
+(simplify
+ (bit_xor:c (bit_ior:s @0 @1) (bit_ior:c @0 (bit_not @1)))
+ (bit_not @0))
+
+/* (x & y) | ~(x | y) -> ~(x ^ y) */
+(simplify
+ (bit_ior:c (bit_and:s @0 @1) (bit_not (bit_ior:s @0 @1)))
+ (bit_not (bit_xor @0 @1)))
+
+/* (~x | y) ^ (x ^ y) -> x | ~y */
+(simplify
+ (bit_xor:c (bit_ior:c (bit_not @0) @1) (bit_xor:s @0 @1))
+ (bit_ior @0 (bit_not @1)))
+
+/* (x ^ y) | ~(x | y) -> ~(x & y) */
+(simplify
+ (bit_ior:c (bit_xor:s @0 @1) (bit_not (bit_ior:s @0 @1)))
+ (bit_not (bit_and @0 @1)))
+
 /* (x | y) & ~x -> y & ~x */
 /* (x & y) | ~x -> y | ~x */
 (for bitop (bit_and bit_ior)
@@ -1131,7 +1156,7 @@ DEFINE_INT_AND_FLOAT_ROUND_FN (RINT)
   (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))
@@ -3091,7 +3116,7 @@ DEFINE_INT_AND_FLOAT_ROUND_FN (RINT)
     (if (tree_int_cst_sgn (@1) < 0)
      (scmp @0 @2)
      (cmp @0 @2))))))
- 
+
 /* Simplify comparison of something with itself.  For IEEE
    floating-point, we can only do some of these simplifications.  */
 (for cmp (eq ge le)
@@ -3162,11 +3187,11 @@ DEFINE_INT_AND_FLOAT_ROUND_FN (RINT)
         }
       tree newtype
         = (TYPE_PRECISION (TREE_TYPE (@0)) > TYPE_PRECISION (type1)
-	   ? TREE_TYPE (@0) : type1); 
+	   ? TREE_TYPE (@0) : type1);
     }
     (if (TYPE_PRECISION (TREE_TYPE (@2)) > TYPE_PRECISION (newtype))
      (cmp (convert:newtype @0) (convert:newtype @1))))))
- 
+
  (simplify
   (cmp @0 REAL_CST@1)
   /* IEEE doesn't distinguish +0 and -0 in comparisons.  */
@@ -3414,7 +3439,7 @@ DEFINE_INT_AND_FLOAT_ROUND_FN (RINT)
 	    (FTYPE) N == CST -> 0
 	    (FTYPE) N != CST -> 1.  */
 	(if (cmp == EQ_EXPR || cmp == NE_EXPR)
-	 { constant_boolean_node (cmp == NE_EXPR, type); }) 
+	 { constant_boolean_node (cmp == NE_EXPR, type); })
 	/* Otherwise replace with sensible integer constant.  */
 	(with
 	 {
@@ -3656,7 +3681,7 @@ DEFINE_INT_AND_FLOAT_ROUND_FN (RINT)
  (simplify
   (cmp (bit_and@2 @0 integer_pow2p@1) @1)
   (icmp @2 { build_zero_cst (TREE_TYPE (@0)); })))
- 
+
 /* If we have (A & C) != 0 ? D : 0 where C and D are powers of 2,
    convert this into a shift followed by ANDing with D.  */
 (simplify
@@ -3876,7 +3901,7 @@ DEFINE_INT_AND_FLOAT_ROUND_FN (RINT)
         (if (cmp == LE_EXPR)
 	 (ge (convert:st @0) { build_zero_cst (st); })
 	 (lt (convert:st @0) { build_zero_cst (st); }))))))))))
- 
+
 (for cmp (unordered ordered unlt unle ungt unge uneq ltgt)
  /* If the second operand is NaN, the result is constant.  */
  (simplify
@@ -4530,7 +4555,7 @@ DEFINE_INT_AND_FLOAT_ROUND_FN (RINT)
   (if (wi::to_wide (@1) == -1)
    (rdiv { build_real (type, dconst1); } @0))))
 
-/* Narrowing of arithmetic and logical operations. 
+/* Narrowing of arithmetic and logical operations.
 
    These are conceptually similar to the transformations performed for
    the C/C++ front-ends by shorten_binary_op and shorten_compare.  Long
@@ -4602,7 +4627,7 @@ DEFINE_INT_AND_FLOAT_ROUND_FN (RINT)
      (convert (bit_and (op (convert:utype @0) (convert:utype @1))
 	       (convert:utype @4))))))))
 
-/* Transform (@0 < @1 and @0 < @2) to use min, 
+/* Transform (@0 < @1 and @0 < @2) to use min,
    (@0 > @1 and @0 > @2) to use max */
 (for logic (bit_and bit_and bit_and bit_and bit_ior bit_ior bit_ior bit_ior)
      op    (lt      le      gt      ge      lt      le      gt      ge     )
Index: gcc/testsuite/gcc.dg/pr87261.c
===================================================================
--- gcc/testsuite/gcc.dg/pr87261.c	(nonexistent)
+++ gcc/testsuite/gcc.dg/pr87261.c	(working copy)
@@ -0,0 +1,35 @@
+/* { dg-do compile } */
+/* { dg-options "-O -fdump-tree-original" } */
+
+int f1 (int a, int b)
+{
+ return ~(a|b)|(~a&b);
+}
+
+int f2 (int a, int b)
+{
+ return (a|b)^(a|~b);
+}
+
+/* { dg-final { scan-tree-dump-times "return \\~a;" 2 "original" } } */
+
+int f3 (int a, int b)
+{
+ return ~(a|b)|(a&b);
+}
+
+/* { dg-final { scan-tree-dump "return \\~\\(a \\^ b\\);" "original" } } */
+
+int f4 (int a, int b)
+{
+ return a^b^(~a|b);
+}
+
+/* { dg-final { scan-tree-dump "return \\~b \\| a;" "original" } } */
+
+int f5 (int a, int b)
+{
+ return (a^b)|~(a|b);
+}
+
+/* { dg-final { scan-tree-dump "return \\~\\(a \\& b\\);" "original" } } */

^ permalink raw reply	[flat|nested] 15+ messages in thread
* Re: Fold more boolean expressions
@ 2018-09-30 17:16 MCC CS
  2018-10-01  8:39 ` Richard Biener
  0 siblings, 1 reply; 15+ messages in thread
From: MCC CS @ 2018-09-30 17:16 UTC (permalink / raw)
  To: gcc-patches


Now that it has got enough reviews and there's
been no comments for a week, I believe
now it's time for us to install it on trunk.
The patch is the same as previous, but rebased
on current trunk.

Could you please push it for me? If there's anything
I can do to help, just tell me.

2018-09-30 MCC CS <deswurstes@users.noreply.github.com>

gcc/
PR tree-optimization/87261
* match.pd: Add boolean optimizations,
fix whitespace.

2018-09-30 MCC CS <deswurstes@users.noreply.github.com>

gcc/testsuite/
PR tree-optimization/87261
* gcc.dg/pr87261.c: New test.

Index: gcc/match.pd
===================================================================
--- gcc/match.pd	(revision 264725)
+++ gcc/match.pd	(working copy)
@@ -92,7 +92,7 @@ DEFINE_INT_AND_FLOAT_ROUND_FN (RINT)
   IFN_FMA IFN_FMS IFN_FNMA IFN_FNMS)
 (define_operator_list COND_TERNARY
   IFN_COND_FMA IFN_COND_FMS IFN_COND_FNMA IFN_COND_FNMS)
-    
+
 /* As opposed to convert?, this still creates a single pattern, so
    it is not a suitable replacement for convert? in all cases.  */
 (match (nop_convert @0)
@@ -106,7 +106,7 @@ DEFINE_INT_AND_FLOAT_ROUND_FN (RINT)
       && tree_nop_conversion_p (TREE_TYPE (type), TREE_TYPE (TREE_TYPE (@0))))))
 /* This one has to be last, or it shadows the others.  */
 (match (nop_convert @0)
- @0) 
+ @0)
 
 /* Transform likes of (char) ABS_EXPR <(int) x> into (char) ABSU_EXPR <x>
    ABSU_EXPR returns unsigned absolute value of the operand and the operand
@@ -285,7 +285,7 @@ DEFINE_INT_AND_FLOAT_ROUND_FN (RINT)
      And not for _Fract types where we can't build 1.  */
   (if (!integer_zerop (@0) && !ALL_FRACT_MODE_P (TYPE_MODE (type)))
    { build_one_cst (type); }))
- /* X / abs (X) is X < 0 ? -1 : 1.  */ 
+ /* X / abs (X) is X < 0 ? -1 : 1.  */
  (simplify
    (div:C @0 (abs @0))
    (if (INTEGRAL_TYPE_P (type)
@@ -929,6 +929,31 @@ DEFINE_INT_AND_FLOAT_ROUND_FN (RINT)
   (bitop:c @0 (bit_not (bitop:cs @0 @1)))
   (bitop @0 (bit_not @1))))
 
+/* (~x & y) | ~(x | y) -> ~x */
+(simplify
+ (bit_ior:c (bit_and:c (bit_not@2 @0) @1) (bit_not (bit_ior:c @0 @1)))
+ @2)
+
+/* (x | y) ^ (x | ~y) -> ~x */
+(simplify
+ (bit_xor:c (bit_ior:c @0 @1) (bit_ior:c @0 (bit_not @1)))
+ (bit_not @0))
+
+/* (x & y) | ~(x | y) -> ~(x ^ y) */
+(simplify
+ (bit_ior:c (bit_and:cs @0 @1) (bit_not:s (bit_ior:s @0 @1)))
+ (bit_not (bit_xor @0 @1)))
+
+/* (~x | y) ^ (x ^ y) -> x | ~y */
+(simplify
+ (bit_xor:c (bit_ior:cs (bit_not @0) @1) (bit_xor:s @0 @1))
+ (bit_ior @0 (bit_not @1)))
+
+/* (x ^ y) | ~(x | y) -> ~(x & y) */
+(simplify
+ (bit_ior:c (bit_xor:cs @0 @1) (bit_not:s (bit_ior:s @0 @1)))
+ (bit_not (bit_and @0 @1)))
+
 /* (x | y) & ~x -> y & ~x */
 /* (x & y) | ~x -> y | ~x */
 (for bitop (bit_and bit_ior)
@@ -1139,7 +1164,7 @@ DEFINE_INT_AND_FLOAT_ROUND_FN (RINT)
   (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))
@@ -3099,7 +3124,7 @@ DEFINE_INT_AND_FLOAT_ROUND_FN (RINT)
     (if (tree_int_cst_sgn (@1) < 0)
      (scmp @0 @2)
      (cmp @0 @2))))))
- 
+
 /* Simplify comparison of something with itself.  For IEEE
    floating-point, we can only do some of these simplifications.  */
 (for cmp (eq ge le)
@@ -3170,11 +3195,11 @@ DEFINE_INT_AND_FLOAT_ROUND_FN (RINT)
         }
       tree newtype
         = (TYPE_PRECISION (TREE_TYPE (@0)) > TYPE_PRECISION (type1)
-	   ? TREE_TYPE (@0) : type1); 
+	   ? TREE_TYPE (@0) : type1);
     }
     (if (TYPE_PRECISION (TREE_TYPE (@2)) > TYPE_PRECISION (newtype))
      (cmp (convert:newtype @0) (convert:newtype @1))))))
- 
+
  (simplify
   (cmp @0 REAL_CST@1)
   /* IEEE doesn't distinguish +0 and -0 in comparisons.  */
@@ -3422,7 +3447,7 @@ DEFINE_INT_AND_FLOAT_ROUND_FN (RINT)
 	    (FTYPE) N == CST -> 0
 	    (FTYPE) N != CST -> 1.  */
 	(if (cmp == EQ_EXPR || cmp == NE_EXPR)
-	 { constant_boolean_node (cmp == NE_EXPR, type); }) 
+	 { constant_boolean_node (cmp == NE_EXPR, type); })
 	/* Otherwise replace with sensible integer constant.  */
 	(with
 	 {
@@ -3666,7 +3691,7 @@ DEFINE_INT_AND_FLOAT_ROUND_FN (RINT)
  (simplify
   (cmp (bit_and@2 @0 integer_pow2p@1) @1)
   (icmp @2 { build_zero_cst (TREE_TYPE (@0)); })))
- 
+
 /* If we have (A & C) != 0 ? D : 0 where C and D are powers of 2,
    convert this into a shift followed by ANDing with D.  */
 (simplify
@@ -3886,7 +3911,7 @@ DEFINE_INT_AND_FLOAT_ROUND_FN (RINT)
         (if (cmp == LE_EXPR)
 	 (ge (convert:st @0) { build_zero_cst (st); })
 	 (lt (convert:st @0) { build_zero_cst (st); }))))))))))
- 
+
 (for cmp (unordered ordered unlt unle ungt unge uneq ltgt)
  /* If the second operand is NaN, the result is constant.  */
  (simplify
@@ -4540,7 +4565,7 @@ DEFINE_INT_AND_FLOAT_ROUND_FN (RINT)
   (if (wi::to_wide (@1) == -1)
    (rdiv { build_real (type, dconst1); } @0))))
 
-/* Narrowing of arithmetic and logical operations. 
+/* Narrowing of arithmetic and logical operations.
 
    These are conceptually similar to the transformations performed for
    the C/C++ front-ends by shorten_binary_op and shorten_compare.  Long
@@ -4612,7 +4637,7 @@ DEFINE_INT_AND_FLOAT_ROUND_FN (RINT)
      (convert (bit_and (op (convert:utype @0) (convert:utype @1))
 	       (convert:utype @4))))))))
 
-/* Transform (@0 < @1 and @0 < @2) to use min, 
+/* Transform (@0 < @1 and @0 < @2) to use min,
    (@0 > @1 and @0 > @2) to use max */
 (for logic (bit_and bit_and bit_and bit_and bit_ior bit_ior bit_ior bit_ior)
      op    (lt      le      gt      ge      lt      le      gt      ge     )
Index: gcc/testsuite/gcc.dg/pr87261.c
===================================================================
--- gcc/testsuite/gcc.dg/pr87261.c	(nonexistent)
+++ gcc/testsuite/gcc.dg/pr87261.c	(working copy)
@@ -0,0 +1,35 @@
+/* { dg-do compile } */
+/* { dg-options "-O -fdump-tree-original" } */
+
+int f1 (int a, int b)
+{
+ return ~(a|b)|(~a&b);
+}
+
+int f2 (int a, int b)
+{
+ return (a|b)^(a|~b);
+}
+
+/* { dg-final { scan-tree-dump-times "return \\~a;" 2 "original" } } */
+
+int f3 (int a, int b)
+{
+ return ~(a|b)|(a&b);
+}
+
+/* { dg-final { scan-tree-dump "return \\~\\(a \\^ b\\);" "original" } } */
+
+int f4 (int a, int b)
+{
+ return a^b^(~a|b);
+}
+
+/* { dg-final { scan-tree-dump "return \\~b \\| a;" "original" } } */
+
+int f5 (int a, int b)
+{
+ return (a^b)|~(a|b);
+}
+
+/* { dg-final { scan-tree-dump "return \\~\\(a \\& b\\);" "original" } } */

^ permalink raw reply	[flat|nested] 15+ messages in thread
* Re: Fold more boolean expressions
@ 2018-10-03  8:56 graham stott via gcc-patches
  0 siblings, 0 replies; 15+ messages in thread
From: graham stott via gcc-patches @ 2018-10-03  8:56 UTC (permalink / raw)
  To: MCC CS, gcc-patches


    


-------- Original message --------
From: MCC CS <mcccs@gmx.com> 
Date: 02/10/2018  14:38  (GMT+00:00) 
To: gcc-patches@gcc.gnu.org 
Subject: Re: Fold more boolean expressions 

Thanks a lot!

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

end of thread, other threads:[~2018-10-04  7:43 UTC | newest]

Thread overview: 15+ messages (download: mbox.gz / follow: Atom feed)
-- links below jump to the message on this page --
2018-09-11 13:54 Fold more boolean expressions MCC CS
2018-09-11 21:24 ` Marc Glisse
2018-09-14 15:37   ` MCC CS
2018-09-14 16:55     ` Marc Glisse
2018-09-15  8:14       ` MCC CS
2018-09-20 13:34         ` Richard Biener
2018-09-20 14:04           ` Marc Glisse
2018-09-20 14:19             ` Richard Biener
2018-09-22  9:08           ` MCC CS
2018-09-16 17:20       ` MCC CS
2018-09-30 17:16 MCC CS
2018-10-01  8:39 ` Richard Biener
2018-10-02 14:01   ` MCC CS
2018-10-04  8:08     ` Richard Biener
2018-10-03  8:56 graham stott via gcc-patches

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