diff mbox

match.pd patch: max(int_min, x)->x

Message ID alpine.DEB.2.02.1604202020440.19060@laptop-mg.saclay.inria.fr
State New
Headers show

Commit Message

Marc Glisse April 20, 2016, 6:44 p.m. UTC
Hello,

this simple transformation is currently done in RTL, sometimes also 
in VRP if we have any kind of range information (even on the wrong side, 
but not with VR_VARYING). It seems more natural to complete the match.pd 
pattern than make VRP understand this case.

Bootstrap+regtest on powerpc64le-unknown-linux-gnu (some noise in libgomp 
testcases).

2016-04-21  Marc Glisse  <marc.glisse@inria.fr>

gcc/
 	* match.pd (min(int_max, x), max(int_min, x)): New transformations.

gcc/testsuite/
 	* gcc.dg/tree-ssa/minmax-1.c: New testcase.

Comments

Richard Biener April 21, 2016, 9:07 a.m. UTC | #1
On Wed, Apr 20, 2016 at 8:44 PM, Marc Glisse <marc.glisse@inria.fr> wrote:
> Hello,
>
> this simple transformation is currently done in RTL, sometimes also in VRP
> if we have any kind of range information (even on the wrong side, but not
> with VR_VARYING). It seems more natural to complete the match.pd pattern
> than make VRP understand this case.
>
> Bootstrap+regtest on powerpc64le-unknown-linux-gnu (some noise in libgomp
> testcases).

Ok.

Thanks,
Richard.

> 2016-04-21  Marc Glisse  <marc.glisse@inria.fr>
>
> gcc/
>         * match.pd (min(int_max, x), max(int_min, x)): New transformations.
>
> gcc/testsuite/
>         * gcc.dg/tree-ssa/minmax-1.c: New testcase.
>
> --
> Marc Glisse
> Index: gcc/match.pd
> ===================================================================
> --- gcc/match.pd        (revision 235292)
> +++ gcc/match.pd        (working copy)
> @@ -1185,30 +1185,40 @@ DEFINE_INT_AND_FLOAT_ROUND_FN (RINT)
>  /* min(max(x,y),y) -> y.  */
>  (simplify
>   (min:c (max:c @0 @1) @1)
>   @1)
>  /* max(min(x,y),y) -> y.  */
>  (simplify
>   (max:c (min:c @0 @1) @1)
>   @1)
>  (simplify
>   (min @0 @1)
> - (if (INTEGRAL_TYPE_P (type)
> -      && TYPE_MIN_VALUE (type)
> -      && operand_equal_p (@1, TYPE_MIN_VALUE (type), OEP_ONLY_CONST))
> -  @1))
> + (switch
> +  (if (INTEGRAL_TYPE_P (type)
> +       && TYPE_MIN_VALUE (type)
> +       && operand_equal_p (@1, TYPE_MIN_VALUE (type), OEP_ONLY_CONST))
> +   @1)
> +  (if (INTEGRAL_TYPE_P (type)
> +       && TYPE_MAX_VALUE (type)
> +       && operand_equal_p (@1, TYPE_MAX_VALUE (type), OEP_ONLY_CONST))
> +   @0)))
>  (simplify
>   (max @0 @1)
> - (if (INTEGRAL_TYPE_P (type)
> -      && TYPE_MAX_VALUE (type)
> -      && operand_equal_p (@1, TYPE_MAX_VALUE (type), OEP_ONLY_CONST))
> -  @1))
> + (switch
> +  (if (INTEGRAL_TYPE_P (type)
> +       && TYPE_MAX_VALUE (type)
> +       && operand_equal_p (@1, TYPE_MAX_VALUE (type), OEP_ONLY_CONST))
> +   @1)
> +  (if (INTEGRAL_TYPE_P (type)
> +       && TYPE_MIN_VALUE (type)
> +       && operand_equal_p (@1, TYPE_MIN_VALUE (type), OEP_ONLY_CONST))
> +   @0)))
>  (for minmax (FMIN FMAX)
>   /* If either argument is NaN, return the other one.  Avoid the
>      transformation if we get (and honor) a signalling NaN.  */
>   (simplify
>    (minmax:c @0 REAL_CST@1)
>    (if (real_isnan (TREE_REAL_CST_PTR (@1))
>         && (!HONOR_SNANS (@1) || !TREE_REAL_CST (@1).signalling))
>     @0)))
>  /* Convert fmin/fmax to MIN_EXPR/MAX_EXPR.  C99 requires these
>     functions to return the numeric arg if the other one is NaN.
> Index: gcc/testsuite/gcc.dg/tree-ssa/minmax-1.c
> ===================================================================
> --- gcc/testsuite/gcc.dg/tree-ssa/minmax-1.c    (revision 0)
> +++ gcc/testsuite/gcc.dg/tree-ssa/minmax-1.c    (working copy)
> @@ -0,0 +1,9 @@
> +/* { dg-do compile } */
> +/* { dg-options "-O -fdump-tree-optimized" } */
> +
> +static int min(int a,int b){return (a<b)?a:b;}
> +static int max(int a,int b){return (a<b)?b:a;}
> +int f(int x){return max(x,-__INT_MAX__-1);}
> +int g(int x){return min(x,__INT_MAX__);}
> +
> +/* { dg-final { scan-tree-dump-times "return x_\[0-9\]+.D.;" 2 "optimized"
> } } */
>
diff mbox

Patch

Index: gcc/match.pd
===================================================================
--- gcc/match.pd	(revision 235292)
+++ gcc/match.pd	(working copy)
@@ -1185,30 +1185,40 @@  DEFINE_INT_AND_FLOAT_ROUND_FN (RINT)
 /* min(max(x,y),y) -> y.  */
 (simplify
  (min:c (max:c @0 @1) @1)
  @1)
 /* max(min(x,y),y) -> y.  */
 (simplify
  (max:c (min:c @0 @1) @1)
  @1)
 (simplify
  (min @0 @1)
- (if (INTEGRAL_TYPE_P (type)
-      && TYPE_MIN_VALUE (type)
-      && operand_equal_p (@1, TYPE_MIN_VALUE (type), OEP_ONLY_CONST))
-  @1))
+ (switch
+  (if (INTEGRAL_TYPE_P (type)
+       && TYPE_MIN_VALUE (type)
+       && operand_equal_p (@1, TYPE_MIN_VALUE (type), OEP_ONLY_CONST))
+   @1)
+  (if (INTEGRAL_TYPE_P (type)
+       && TYPE_MAX_VALUE (type)
+       && operand_equal_p (@1, TYPE_MAX_VALUE (type), OEP_ONLY_CONST))
+   @0)))
 (simplify
  (max @0 @1)
- (if (INTEGRAL_TYPE_P (type)
-      && TYPE_MAX_VALUE (type)
-      && operand_equal_p (@1, TYPE_MAX_VALUE (type), OEP_ONLY_CONST))
-  @1))
+ (switch
+  (if (INTEGRAL_TYPE_P (type)
+       && TYPE_MAX_VALUE (type)
+       && operand_equal_p (@1, TYPE_MAX_VALUE (type), OEP_ONLY_CONST))
+   @1)
+  (if (INTEGRAL_TYPE_P (type)
+       && TYPE_MIN_VALUE (type)
+       && operand_equal_p (@1, TYPE_MIN_VALUE (type), OEP_ONLY_CONST))
+   @0)))
 (for minmax (FMIN FMAX)
  /* If either argument is NaN, return the other one.  Avoid the
     transformation if we get (and honor) a signalling NaN.  */
  (simplify
   (minmax:c @0 REAL_CST@1)
   (if (real_isnan (TREE_REAL_CST_PTR (@1))
        && (!HONOR_SNANS (@1) || !TREE_REAL_CST (@1).signalling))
    @0)))
 /* Convert fmin/fmax to MIN_EXPR/MAX_EXPR.  C99 requires these
    functions to return the numeric arg if the other one is NaN.
Index: gcc/testsuite/gcc.dg/tree-ssa/minmax-1.c
===================================================================
--- gcc/testsuite/gcc.dg/tree-ssa/minmax-1.c	(revision 0)
+++ gcc/testsuite/gcc.dg/tree-ssa/minmax-1.c	(working copy)
@@ -0,0 +1,9 @@ 
+/* { dg-do compile } */
+/* { dg-options "-O -fdump-tree-optimized" } */
+
+static int min(int a,int b){return (a<b)?a:b;}
+static int max(int a,int b){return (a<b)?b:a;}
+int f(int x){return max(x,-__INT_MAX__-1);}
+int g(int x){return min(x,__INT_MAX__);}
+
+/* { dg-final { scan-tree-dump-times "return x_\[0-9\]+.D.;" 2 "optimized" } } */