On Thu, Apr 21, 2016 at 12:32 PM, Marc Glisse <marc.gli...@inria.fr> wrote: > Hello, > > another simple transformation. > > Instead of the ":s", I had single_use (@2) || single_use (@3), but changed > it for simplicity. There may be some patterns in match.pd where we want > something like that though, as requiring single_use on many expressions may > be stricter than we need. > > We could generalize to cases where overflow is not undefined if we know > (VRP) that the variables are not TYPE_MIN_VALUE, but that didn't look like a > priority. > > Bootstrap+regtest on powerpc64le-unknown-linux-gnu.
Ok. I thought about using negate_expr_p but min(-x,5) -> -max(x, -5) doesn't look like an obvious win. Thanks, Richard. > 2016-04-21 Marc Glisse <marc.gli...@inria.fr> > > gcc/ > * match.pd (min(-x, -y), max(-x, -y), min(~x, ~y), max(~x, ~y)): > New transformations. > > gcc/testsuite/ > * gcc.dg/tree-ssa/minmax-2.c: New testcase. > > > -- > Marc Glisse > Index: gcc/match.pd > =================================================================== > --- gcc/match.pd (revision 235292) > +++ gcc/match.pd (working copy) > @@ -1215,20 +1215,36 @@ DEFINE_INT_AND_FLOAT_ROUND_FN (RINT) > MIN and MAX don't honor that, so only transform if -ffinite-math-only > is set. C99 doesn't require -0.0 to be handled, so we don't have to > worry about it either. */ > (if (flag_finite_math_only) > (simplify > (FMIN @0 @1) > (min @0 @1)) > (simplify > (FMAX @0 @1) > (max @0 @1))) > +/* min (-A, -B) -> -max (A, B) */ > +(for minmax (min max FMIN FMAX) > + maxmin (max min FMAX FMIN) > + (simplify > + (minmax (negate:s@2 @0) (negate:s@3 @1)) > + (if (FLOAT_TYPE_P (TREE_TYPE (@0)) > + || (ANY_INTEGRAL_TYPE_P (TREE_TYPE (@0)) > + && TYPE_OVERFLOW_UNDEFINED (TREE_TYPE (@0)))) > + (negate (maxmin @0 @1))))) > +/* MIN (~X, ~Y) -> ~MAX (X, Y) > + MAX (~X, ~Y) -> ~MIN (X, Y) */ > +(for minmax (min max) > + maxmin (max min) > + (simplify > + (minmax (bit_not:s@2 @0) (bit_not:s@3 @1)) > + (bit_not (maxmin @0 @1)))) > > /* Simplifications of shift and rotates. */ > > (for rotate (lrotate rrotate) > (simplify > (rotate integer_all_onesp@0 @1) > @0)) > > /* Optimize -1 >> x for arithmetic right shifts. */ > (simplify > Index: gcc/testsuite/gcc.dg/tree-ssa/minmax-2.c > =================================================================== > --- gcc/testsuite/gcc.dg/tree-ssa/minmax-2.c (revision 0) > +++ gcc/testsuite/gcc.dg/tree-ssa/minmax-2.c (working copy) > @@ -0,0 +1,10 @@ > +/* { dg-do compile } */ > +/* { dg-options "-O -fstrict-overflow -fdump-tree-optimized" } */ > + > +static int max(int a,int b){return (a<b)?b:a;} > +int f(int x,int y){return max(-x,-y);} > +int g(int x,int y){return max(~x,~y);} > +double h(double x,double y){return __builtin_fmax(-x,-y);} > + > +/* { dg-final { scan-tree-dump-times "MIN_EXPR" 2 "optimized" } } */ > +/* { dg-final { scan-tree-dump "__builtin_fmin" "optimized" } } */ >