Move optimize_minmax_comparison to match.pd
authorMarc Glisse <marc.glisse@inria.fr>
Mon, 13 Jun 2016 11:21:45 +0000 (13:21 +0200)
committerMarc Glisse <glisse@gcc.gnu.org>
Mon, 13 Jun 2016 11:21:45 +0000 (11:21 +0000)
2016-06-13  Marc Glisse  <marc.glisse@inria.fr>

* fold-const.c (optimize_minmax_comparison): Remove.
(fold_comparison): Remove call to the above.
* match.pd (MIN (X, Y) == X, MIN (X, 5) == 0, MIN (X, C1) < C2):
New transformations.

From-SVN: r237376

gcc/ChangeLog
gcc/fold-const.c
gcc/match.pd

index e8ad4c85a2dbfc0f53b72a6f5f455d1f58610a31..9c02bea3dd29784fad2e6f2d0858f8c430df0d53 100644 (file)
@@ -1,3 +1,10 @@
+2016-06-13  Marc Glisse  <marc.glisse@inria.fr>
+
+       * fold-const.c (optimize_minmax_comparison): Remove.
+       (fold_comparison): Remove call to the above.
+       * match.pd (MIN (X, Y) == X, MIN (X, 5) == 0, MIN (X, C1) < C2):
+       New transformations.
+
 2016-06-13  Alan Hayward  <alan.hayward@arm.com>
 
        PR tree-optimization/71416
index 1a464ec8366126939b3e4fa65c2b5b701eaddd41..26c1435ed0c50b2d2f21844ac92fe07295ad9a55 100644 (file)
@@ -128,8 +128,6 @@ static tree range_successor (tree);
 static tree fold_range_test (location_t, enum tree_code, tree, tree, tree);
 static tree fold_cond_expr_with_comparison (location_t, tree, tree, tree, tree);
 static tree unextend (tree, int, int, tree);
-static tree optimize_minmax_comparison (location_t, enum tree_code,
-                                       tree, tree, tree);
 static tree extract_muldiv (tree, tree, enum tree_code, tree, bool *);
 static tree extract_muldiv_1 (tree, tree, enum tree_code, tree, bool *);
 static tree fold_binary_op_with_conditional_arg (location_t,
@@ -5979,110 +5977,6 @@ fold_truth_andor_1 (location_t loc, enum tree_code code, tree truth_type,
                     const_binop (BIT_IOR_EXPR, l_const, r_const));
 }
 \f
-/* Optimize T, which is a comparison of a MIN_EXPR or MAX_EXPR with a
-   constant.  */
-
-static tree
-optimize_minmax_comparison (location_t loc, enum tree_code code, tree type,
-                           tree op0, tree op1)
-{
-  tree arg0 = op0;
-  enum tree_code op_code;
-  tree comp_const;
-  tree minmax_const;
-  int consts_equal, consts_lt;
-  tree inner;
-
-  STRIP_SIGN_NOPS (arg0);
-
-  op_code = TREE_CODE (arg0);
-  minmax_const = TREE_OPERAND (arg0, 1);
-  comp_const = fold_convert_loc (loc, TREE_TYPE (arg0), op1);
-  consts_equal = tree_int_cst_equal (minmax_const, comp_const);
-  consts_lt = tree_int_cst_lt (minmax_const, comp_const);
-  inner = TREE_OPERAND (arg0, 0);
-
-  /* If something does not permit us to optimize, return the original tree.  */
-  if ((op_code != MIN_EXPR && op_code != MAX_EXPR)
-      || TREE_CODE (comp_const) != INTEGER_CST
-      || TREE_OVERFLOW (comp_const)
-      || TREE_CODE (minmax_const) != INTEGER_CST
-      || TREE_OVERFLOW (minmax_const))
-    return NULL_TREE;
-
-  /* Now handle all the various comparison codes.  We only handle EQ_EXPR
-     and GT_EXPR, doing the rest with recursive calls using logical
-     simplifications.  */
-  switch (code)
-    {
-    case NE_EXPR:  case LT_EXPR:  case LE_EXPR:
-      {
-       tree tem
-         = optimize_minmax_comparison (loc,
-                                       invert_tree_comparison (code, false),
-                                       type, op0, op1);
-       if (tem)
-         return invert_truthvalue_loc (loc, tem);
-       return NULL_TREE;
-      }
-
-    case GE_EXPR:
-      return
-       fold_build2_loc (loc, TRUTH_ORIF_EXPR, type,
-                    optimize_minmax_comparison
-                    (loc, EQ_EXPR, type, arg0, comp_const),
-                    optimize_minmax_comparison
-                    (loc, GT_EXPR, type, arg0, comp_const));
-
-    case EQ_EXPR:
-      if (op_code == MAX_EXPR && consts_equal)
-       /* MAX (X, 0) == 0  ->  X <= 0  */
-       return fold_build2_loc (loc, LE_EXPR, type, inner, comp_const);
-
-      else if (op_code == MAX_EXPR && consts_lt)
-       /* MAX (X, 0) == 5  ->  X == 5   */
-       return fold_build2_loc (loc, EQ_EXPR, type, inner, comp_const);
-
-      else if (op_code == MAX_EXPR)
-       /* MAX (X, 0) == -1  ->  false  */
-       return omit_one_operand_loc (loc, type, integer_zero_node, inner);
-
-      else if (consts_equal)
-       /* MIN (X, 0) == 0  ->  X >= 0  */
-       return fold_build2_loc (loc, GE_EXPR, type, inner, comp_const);
-
-      else if (consts_lt)
-       /* MIN (X, 0) == 5  ->  false  */
-       return omit_one_operand_loc (loc, type, integer_zero_node, inner);
-
-      else
-       /* MIN (X, 0) == -1  ->  X == -1  */
-       return fold_build2_loc (loc, EQ_EXPR, type, inner, comp_const);
-
-    case GT_EXPR:
-      if (op_code == MAX_EXPR && (consts_equal || consts_lt))
-       /* MAX (X, 0) > 0  ->  X > 0
-          MAX (X, 0) > 5  ->  X > 5  */
-       return fold_build2_loc (loc, GT_EXPR, type, inner, comp_const);
-
-      else if (op_code == MAX_EXPR)
-       /* MAX (X, 0) > -1  ->  true  */
-       return omit_one_operand_loc (loc, type, integer_one_node, inner);
-
-      else if (op_code == MIN_EXPR && (consts_equal || consts_lt))
-       /* MIN (X, 0) > 0  ->  false
-          MIN (X, 0) > 5  ->  false  */
-       return omit_one_operand_loc (loc, type, integer_zero_node, inner);
-
-      else
-       /* MIN (X, 0) > -1  ->  X > -1  */
-       return fold_build2_loc (loc, GT_EXPR, type, inner, comp_const);
-
-    default:
-      return NULL_TREE;
-    }
-}
-\f
 /* T is an integer expression that is being multiplied, divided, or taken a
    modulus (CODE says which and what kind of divide or modulus) by a
    constant C.  See if we can eliminate that operation by folding it with
@@ -8721,18 +8615,6 @@ fold_comparison (location_t loc, enum tree_code code, tree type,
   if (tem)
     return tem;
 
-  /* If this is comparing a constant with a MIN_EXPR or a MAX_EXPR of a
-     constant, we can simplify it.  */
-  if (TREE_CODE (arg1) == INTEGER_CST
-      && (TREE_CODE (arg0) == MIN_EXPR
-         || TREE_CODE (arg0) == MAX_EXPR)
-      && TREE_CODE (TREE_OPERAND (arg0, 1)) == INTEGER_CST)
-    {
-      tem = optimize_minmax_comparison (loc, code, type, op0, op1);
-      if (tem)
-       return tem;
-    }
-
   /* If we are comparing an expression that just has comparisons
      of two integer values, arithmetic expressions of those comparisons,
      and constants, we can simplify it.  There are only three cases
index 7d4beeaa4ed3c66db88a1e0bd282da766dadd52f..980b73b9a191469caf47504556ba2c0c80792a22 100644 (file)
@@ -1312,6 +1312,38 @@ DEFINE_INT_AND_FLOAT_ROUND_FN (RINT)
   (minmax (bit_not:s@2 @0) (bit_not:s@3 @1))
   (bit_not (maxmin @0 @1))))
 
+/* MIN (X, Y) == X -> X <= Y  */
+(for minmax (min min max max)
+     cmp    (eq  ne  eq  ne )
+     out    (le  gt  ge  lt )
+ (simplify
+  (cmp:c (minmax:c @0 @1) @0)
+  (if (ANY_INTEGRAL_TYPE_P (TREE_TYPE (@0)))
+   (out @0 @1))))
+/* MIN (X, 5) == 0 -> X == 0
+   MIN (X, 5) == 7 -> false  */
+(for cmp (eq ne)
+ (simplify
+  (cmp (min @0 INTEGER_CST@1) INTEGER_CST@2)
+  (if (wi::lt_p (@1, @2, TYPE_SIGN (TREE_TYPE (@0))))
+   { constant_boolean_node (cmp == NE_EXPR, type); }
+   (if (wi::gt_p (@1, @2, TYPE_SIGN (TREE_TYPE (@0))))
+    (cmp @0 @2)))))
+(for cmp (eq ne)
+ (simplify
+  (cmp (max @0 INTEGER_CST@1) INTEGER_CST@2)
+  (if (wi::gt_p (@1, @2, TYPE_SIGN (TREE_TYPE (@0))))
+   { constant_boolean_node (cmp == NE_EXPR, type); }
+   (if (wi::lt_p (@1, @2, TYPE_SIGN (TREE_TYPE (@0))))
+    (cmp @0 @2)))))
+/* MIN (X, C1) < C2 -> X < C2 || C1 < C2  */
+(for minmax (min     min     max     max     min     min     max     max    )
+     cmp    (lt      le      gt      ge      gt      ge      lt      le     )
+     comb   (bit_ior bit_ior bit_ior bit_ior bit_and bit_and bit_and bit_and)
+ (simplify
+  (cmp (minmax @0 INTEGER_CST@1) INTEGER_CST@2)
+  (comb (cmp @0 @2) (cmp @1 @2))))
+
 /* Simplifications of shift and rotates.  */
 
 (for rotate (lrotate rrotate)