summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorglisse <glisse@138bc75d-0d04-0410-961f-82ee72b054a4>2016-06-13 11:21:45 +0000
committerglisse <glisse@138bc75d-0d04-0410-961f-82ee72b054a4>2016-06-13 11:21:45 +0000
commit8178780887fcf62e20077636934114094adb654d (patch)
tree75eb715e32ceaf45a547f7361431eb2526795c04
parent29b68e500feaed8e21850154ae6122e723842b4d (diff)
downloadgcc-8178780887fcf62e20077636934114094adb654d.tar.gz
Move optimize_minmax_comparison to match.pd
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. git-svn-id: svn+ssh://gcc.gnu.org/svn/gcc/trunk@237376 138bc75d-0d04-0410-961f-82ee72b054a4
-rw-r--r--gcc/ChangeLog7
-rw-r--r--gcc/fold-const.c118
-rw-r--r--gcc/match.pd32
3 files changed, 39 insertions, 118 deletions
diff --git a/gcc/ChangeLog b/gcc/ChangeLog
index e8ad4c85a2d..9c02bea3dd2 100644
--- a/gcc/ChangeLog
+++ b/gcc/ChangeLog
@@ -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
diff --git a/gcc/fold-const.c b/gcc/fold-const.c
index 1a464ec8366..26c1435ed0c 100644
--- a/gcc/fold-const.c
+++ b/gcc/fold-const.c
@@ -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));
}
-/* 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;
- }
-}
-
/* 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
diff --git a/gcc/match.pd b/gcc/match.pd
index 7d4beeaa4ed..980b73b9a19 100644
--- a/gcc/match.pd
+++ b/gcc/match.pd
@@ -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)