Commit b4817bd6 by Marc Glisse Committed by Marc Glisse

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.

From-SVN: r237376
parent 915794eb
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> 2016-06-13 Alan Hayward <alan.hayward@arm.com>
PR tree-optimization/71416 PR tree-optimization/71416
......
...@@ -128,8 +128,6 @@ static tree range_successor (tree); ...@@ -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_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 fold_cond_expr_with_comparison (location_t, tree, tree, tree, tree);
static tree unextend (tree, int, int, 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 (tree, tree, enum tree_code, tree, bool *);
static tree extract_muldiv_1 (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, 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, ...@@ -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)); 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 /* 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 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 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, ...@@ -8721,18 +8615,6 @@ fold_comparison (location_t loc, enum tree_code code, tree type,
if (tem) if (tem)
return 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 /* If we are comparing an expression that just has comparisons
of two integer values, arithmetic expressions of those comparisons, of two integer values, arithmetic expressions of those comparisons,
and constants, we can simplify it. There are only three cases and constants, we can simplify it. There are only three cases
......
...@@ -1312,6 +1312,38 @@ DEFINE_INT_AND_FLOAT_ROUND_FN (RINT) ...@@ -1312,6 +1312,38 @@ DEFINE_INT_AND_FLOAT_ROUND_FN (RINT)
(minmax (bit_not:s@2 @0) (bit_not:s@3 @1)) (minmax (bit_not:s@2 @0) (bit_not:s@3 @1))
(bit_not (maxmin @0 @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. */ /* Simplifications of shift and rotates. */
(for rotate (lrotate rrotate) (for rotate (lrotate rrotate)
......
Markdown is supported
0% or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment