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.
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" } } */