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

Reply via email to