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 |
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 > >
--- 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]); +}