This is the mail archive of the
gcc-patches@gcc.gnu.org
mailing list for the GCC project.
Re: match.pd patch: min(-x, -y), min(~x, ~y)
- From: Richard Biener <richard dot guenther at gmail dot com>
- To: Marc Glisse <marc dot glisse at inria dot fr>
- Cc: GCC Patches <gcc-patches at gcc dot gnu dot org>
- Date: Thu, 21 Apr 2016 12:38:21 +0200
- Subject: Re: match.pd patch: min(-x, -y), min(~x, ~y)
- Authentication-results: sourceware.org; auth=none
- References: <alpine dot DEB dot 2 dot 02 dot 1604211217410 dot 22599 at laptop-mg dot saclay dot inria dot fr>
On Thu, Apr 21, 2016 at 12:32 PM, Marc Glisse <marc.glisse@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.glisse@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" } } */
>