diff mbox series

match.pd: A ^ ((A ^ B) & -(C cmp D)) -> (C cmp D) ? B : A simplification [PR94786]

Message ID 20200508074029.GU8462@tucnak
State New
Headers show
Series match.pd: A ^ ((A ^ B) & -(C cmp D)) -> (C cmp D) ? B : A simplification [PR94786] | expand

Commit Message

Jakub Jelinek May 8, 2020, 7:40 a.m. UTC
Hi!

We already have x - ((x - y) & -(z < w)) and
x + ((y - x) & -(z < w)) simplifications, this one adds
x ^ ((x ^ y) & -(z < w)) (not merged using for because of the
:c that can be present on bit_xor and can't on minus).

Bootstrapped/regtested on x86_64-linux and i686-linux, ok for trunk?

2020-05-08  Jakub Jelinek  <jakub@redhat.com>

	PR tree-optimization/94786
	* match.pd (A ^ ((A ^ B) & -(C cmp D)) -> (C cmp D) ? B : A): New
	simplification.

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


	Jakub

Comments

Richard Biener May 8, 2020, 8:34 a.m. UTC | #1
On Fri, 8 May 2020, Jakub Jelinek wrote:

> Hi!
> 
> We already have x - ((x - y) & -(z < w)) and
> x + ((y - x) & -(z < w)) simplifications, this one adds
> x ^ ((x ^ y) & -(z < w)) (not merged using for because of the
> :c that can be present on bit_xor and can't on minus).
> 
> Bootstrapped/regtested on x86_64-linux and i686-linux, ok for trunk?

OK.

Thanks,
Richard.

> 2020-05-08  Jakub Jelinek  <jakub@redhat.com>
> 
> 	PR tree-optimization/94786
> 	* match.pd (A ^ ((A ^ B) & -(C cmp D)) -> (C cmp D) ? B : A): New
> 	simplification.
> 
> 	* gcc.dg/tree-ssa/pr94786.c: New test.
> 
> --- gcc/match.pd.jj	2020-05-07 16:37:22.377391704 +0200
> +++ gcc/match.pd	2020-05-07 18:28:19.037182220 +0200
> @@ -2791,6 +2791,18 @@ (define_operator_list COND_TERNARY
>         && (TYPE_PRECISION (TREE_TYPE (@4)) >= TYPE_PRECISION (type)
>  	   || !TYPE_UNSIGNED (TREE_TYPE (@4)))
>         && (GIMPLE || !TREE_SIDE_EFFECTS (@1)))
> +   (cond (cmp @2 @3) @1 @0)))
> + /* Similarly with ^ instead of - though in that case with :c.  */
> + (simplify
> +  (bit_xor:c @0 (bit_and:c (bit_xor:c @0 @1)
> +			   (convert? (negate@4 (convert? (cmp@5 @2 @3))))))
> +  (if (INTEGRAL_TYPE_P (type)
> +       && INTEGRAL_TYPE_P (TREE_TYPE (@4))
> +       && TREE_CODE (TREE_TYPE (@4)) != BOOLEAN_TYPE
> +       && INTEGRAL_TYPE_P (TREE_TYPE (@5))
> +       && (TYPE_PRECISION (TREE_TYPE (@4)) >= TYPE_PRECISION (type)
> +	   || !TYPE_UNSIGNED (TREE_TYPE (@4)))
> +       && (GIMPLE || !TREE_SIDE_EFFECTS (@1)))
>     (cond (cmp @2 @3) @1 @0))))
>  
>  /* Simplifications of shift and rotates.  */
> --- gcc/testsuite/gcc.dg/tree-ssa/pr94786.c.jj	2020-05-07 18:37:29.243891187 +0200
> +++ gcc/testsuite/gcc.dg/tree-ssa/pr94786.c	2020-05-07 18:33:23.001601189 +0200
> @@ -0,0 +1,66 @@
> +/* PR tree-optimization/94786 */
> +/* { dg-do compile } */
> +/* { dg-options "-O2 -fdump-tree-optimized" } */
> +/* { dg-final { scan-tree-dump-times "MIN_EXPR <" 4 "optimized" } } */
> +/* { dg-final { scan-tree-dump-times "MAX_EXPR <" 4 "optimized" } } */
> +
> +static inline unsigned
> +umax1 (unsigned a, unsigned b)
> +{
> +  return a ^ ((a ^ b) & -(a < b));
> +}
> +
> +static inline unsigned
> +umin1 (unsigned a, unsigned b)
> +{
> +  return a ^ ((a ^ b) & -(a > b));
> +}
> +
> +static inline int
> +smax1 (int a, int b)
> +{
> +  return a ^ ((a ^ b) & -(a < b));
> +}
> +
> +static inline int
> +smin1 (int a, int b)
> +{
> +  return a ^ ((a ^ b) & -(a > b));
> +}
> +
> +static inline unsigned long long
> +umax2 (unsigned long long a, unsigned long long b)
> +{
> +  return a ^ ((a ^ b) & -(a <= b));
> +}
> +
> +static inline unsigned long long
> +umin2 (unsigned long long a, unsigned long long b)
> +{
> +  return a ^ ((a ^ b) & -(a >= b));
> +}
> +
> +static inline long long
> +smax2 (long long a, long long b)
> +{
> +  return a ^ ((a ^ b) & -(a <= b));
> +}
> +
> +static inline long long
> +smin2 (long long a, long long b)
> +{
> +  return a ^ ((a ^ b) & -(a >= b));
> +}
> +
> +void
> +test (unsigned *x, int *y, unsigned long long *z, long long *w)
> +{
> +  x[2] = umax1 (x[0], x[1]);
> +  x[5] = umin1 (x[2], x[3]);
> +  y[2] = smax1 (y[0], y[1]);
> +  y[5] = smin1 (y[2], y[3]);
> +  z[2] = umax2 (z[0], z[1]);
> +  z[5] = umin2 (z[2], z[3]);
> +  w[2] = smax2 (w[0], w[1]);
> +  w[5] = smin2 (w[2], w[3]);
> +}
> 
> 	Jakub
> 
>
diff mbox series

Patch

--- gcc/match.pd.jj	2020-05-07 16:37:22.377391704 +0200
+++ gcc/match.pd	2020-05-07 18:28:19.037182220 +0200
@@ -2791,6 +2791,18 @@  (define_operator_list COND_TERNARY
        && (TYPE_PRECISION (TREE_TYPE (@4)) >= TYPE_PRECISION (type)
 	   || !TYPE_UNSIGNED (TREE_TYPE (@4)))
        && (GIMPLE || !TREE_SIDE_EFFECTS (@1)))
+   (cond (cmp @2 @3) @1 @0)))
+ /* Similarly with ^ instead of - though in that case with :c.  */
+ (simplify
+  (bit_xor:c @0 (bit_and:c (bit_xor:c @0 @1)
+			   (convert? (negate@4 (convert? (cmp@5 @2 @3))))))
+  (if (INTEGRAL_TYPE_P (type)
+       && INTEGRAL_TYPE_P (TREE_TYPE (@4))
+       && TREE_CODE (TREE_TYPE (@4)) != BOOLEAN_TYPE
+       && INTEGRAL_TYPE_P (TREE_TYPE (@5))
+       && (TYPE_PRECISION (TREE_TYPE (@4)) >= TYPE_PRECISION (type)
+	   || !TYPE_UNSIGNED (TREE_TYPE (@4)))
+       && (GIMPLE || !TREE_SIDE_EFFECTS (@1)))
    (cond (cmp @2 @3) @1 @0))))
 
 /* Simplifications of shift and rotates.  */
--- gcc/testsuite/gcc.dg/tree-ssa/pr94786.c.jj	2020-05-07 18:37:29.243891187 +0200
+++ gcc/testsuite/gcc.dg/tree-ssa/pr94786.c	2020-05-07 18:33:23.001601189 +0200
@@ -0,0 +1,66 @@ 
+/* PR tree-optimization/94786 */
+/* { dg-do compile } */
+/* { dg-options "-O2 -fdump-tree-optimized" } */
+/* { dg-final { scan-tree-dump-times "MIN_EXPR <" 4 "optimized" } } */
+/* { dg-final { scan-tree-dump-times "MAX_EXPR <" 4 "optimized" } } */
+
+static inline unsigned
+umax1 (unsigned a, unsigned b)
+{
+  return a ^ ((a ^ b) & -(a < b));
+}
+
+static inline unsigned
+umin1 (unsigned a, unsigned b)
+{
+  return a ^ ((a ^ b) & -(a > b));
+}
+
+static inline int
+smax1 (int a, int b)
+{
+  return a ^ ((a ^ b) & -(a < b));
+}
+
+static inline int
+smin1 (int a, int b)
+{
+  return a ^ ((a ^ b) & -(a > b));
+}
+
+static inline unsigned long long
+umax2 (unsigned long long a, unsigned long long b)
+{
+  return a ^ ((a ^ b) & -(a <= b));
+}
+
+static inline unsigned long long
+umin2 (unsigned long long a, unsigned long long b)
+{
+  return a ^ ((a ^ b) & -(a >= b));
+}
+
+static inline long long
+smax2 (long long a, long long b)
+{
+  return a ^ ((a ^ b) & -(a <= b));
+}
+
+static inline long long
+smin2 (long long a, long long b)
+{
+  return a ^ ((a ^ b) & -(a >= b));
+}
+
+void
+test (unsigned *x, int *y, unsigned long long *z, long long *w)
+{
+  x[2] = umax1 (x[0], x[1]);
+  x[5] = umin1 (x[2], x[3]);
+  y[2] = smax1 (y[0], y[1]);
+  y[5] = smin1 (y[2], y[3]);
+  z[2] = umax2 (z[0], z[1]);
+  z[5] = umin2 (z[2], z[3]);
+  w[2] = smax2 (w[0], w[1]);
+  w[5] = smin2 (w[2], w[3]);
+}