Commit 21aacde4 by Richard Biener Committed by Richard Biener

fold-const.c (fold_binary_loc): Move simplifying of comparisons against the…

fold-const.c (fold_binary_loc): Move simplifying of comparisons against the highest or lowest possible integer ...

2015-07-24  Richard Biener  <rguenther@suse.de>

	* fold-const.c (fold_binary_loc): Move simplifying of comparisons
	against the highest or lowest possible integer ...
	* match.pd: ... as patterns here.

From-SVN: r226153
parent fa138f6e
2015-07-24 Richard Biener <rguenther@suse.de>
* fold-const.c (fold_binary_loc): Move simplifying of comparisons
against the highest or lowest possible integer ...
* match.pd: ... as patterns here.
2015-07-24 Richard Biener <rguenther@suse.de>
* genmatch.c (struct capture_info): Add same_as field.
(capture_info::capture_info): Initialize same_as.
(capture_info::walk_match): Compute same_as.
......
......@@ -11617,123 +11617,6 @@ fold_binary_loc (location_t loc,
}
}
/* Comparisons with the highest or lowest possible integer of
the specified precision will have known values. */
{
tree arg1_type = TREE_TYPE (arg1);
unsigned int prec = TYPE_PRECISION (arg1_type);
if (TREE_CODE (arg1) == INTEGER_CST
&& (INTEGRAL_TYPE_P (arg1_type) || POINTER_TYPE_P (arg1_type)))
{
wide_int max = wi::max_value (arg1_type);
wide_int signed_max = wi::max_value (prec, SIGNED);
wide_int min = wi::min_value (arg1_type);
if (wi::eq_p (arg1, max))
switch (code)
{
case GT_EXPR:
return omit_one_operand_loc (loc, type, integer_zero_node, arg0);
case GE_EXPR:
return fold_build2_loc (loc, EQ_EXPR, type, op0, op1);
case LE_EXPR:
return omit_one_operand_loc (loc, type, integer_one_node, arg0);
case LT_EXPR:
return fold_build2_loc (loc, NE_EXPR, type, op0, op1);
/* The GE_EXPR and LT_EXPR cases above are not normally
reached because of previous transformations. */
default:
break;
}
else if (wi::eq_p (arg1, max - 1))
switch (code)
{
case GT_EXPR:
arg1 = const_binop (PLUS_EXPR, arg1,
build_int_cst (TREE_TYPE (arg1), 1));
return fold_build2_loc (loc, EQ_EXPR, type,
fold_convert_loc (loc,
TREE_TYPE (arg1), arg0),
arg1);
case LE_EXPR:
arg1 = const_binop (PLUS_EXPR, arg1,
build_int_cst (TREE_TYPE (arg1), 1));
return fold_build2_loc (loc, NE_EXPR, type,
fold_convert_loc (loc, TREE_TYPE (arg1),
arg0),
arg1);
default:
break;
}
else if (wi::eq_p (arg1, min))
switch (code)
{
case LT_EXPR:
return omit_one_operand_loc (loc, type, integer_zero_node, arg0);
case LE_EXPR:
return fold_build2_loc (loc, EQ_EXPR, type, op0, op1);
case GE_EXPR:
return omit_one_operand_loc (loc, type, integer_one_node, arg0);
case GT_EXPR:
return fold_build2_loc (loc, NE_EXPR, type, op0, op1);
default:
break;
}
else if (wi::eq_p (arg1, min + 1))
switch (code)
{
case GE_EXPR:
arg1 = const_binop (MINUS_EXPR, arg1,
build_int_cst (TREE_TYPE (arg1), 1));
return fold_build2_loc (loc, NE_EXPR, type,
fold_convert_loc (loc,
TREE_TYPE (arg1), arg0),
arg1);
case LT_EXPR:
arg1 = const_binop (MINUS_EXPR, arg1,
build_int_cst (TREE_TYPE (arg1), 1));
return fold_build2_loc (loc, EQ_EXPR, type,
fold_convert_loc (loc, TREE_TYPE (arg1),
arg0),
arg1);
default:
break;
}
else if (wi::eq_p (arg1, signed_max)
&& TYPE_UNSIGNED (arg1_type)
/* We will flip the signedness of the comparison operator
associated with the mode of arg1, so the sign bit is
specified by this mode. Check that arg1 is the signed
max associated with this sign bit. */
&& prec == GET_MODE_PRECISION (TYPE_MODE (arg1_type))
/* signed_type does not work on pointer types. */
&& INTEGRAL_TYPE_P (arg1_type))
{
/* The following case also applies to X < signed_max+1
and X >= signed_max+1 because previous transformations. */
if (code == LE_EXPR || code == GT_EXPR)
{
tree st = signed_type_for (arg1_type);
return fold_build2_loc (loc,
code == LE_EXPR ? GE_EXPR : LT_EXPR,
type, fold_convert_loc (loc, st, arg0),
build_int_cst (st, 0));
}
}
}
}
/* If we are comparing an ABS_EXPR with a constant, we can
convert all the cases into explicit comparisons, but they may
well not be faster than doing the ABS and one comparison.
......
......@@ -1824,6 +1824,73 @@ along with GCC; see the file COPYING3. If not see
{ constant_boolean_node (cmp == NE_EXPR, type); })))
/* Non-equality compare simplifications from fold_binary */
(for cmp (lt gt le ge)
/* Comparisons with the highest or lowest possible integer of
the specified precision will have known values. */
(simplify
(cmp (convert?@2 @0) INTEGER_CST@1)
(if ((INTEGRAL_TYPE_P (TREE_TYPE (@1)) || POINTER_TYPE_P (TREE_TYPE (@1)))
&& tree_nop_conversion_p (TREE_TYPE (@2), TREE_TYPE (@0)))
(with
{
tree arg1_type = TREE_TYPE (@1);
unsigned int prec = TYPE_PRECISION (arg1_type);
wide_int max = wi::max_value (arg1_type);
wide_int signed_max = wi::max_value (prec, SIGNED);
wide_int min = wi::min_value (arg1_type);
}
(switch
(if (wi::eq_p (@1, max))
(switch
(if (cmp == GT_EXPR)
{ constant_boolean_node (false, type); })
(if (cmp == GE_EXPR)
(eq @2 @1))
(if (cmp == LE_EXPR)
{ constant_boolean_node (true, type); })
(if (cmp == LT_EXPR)
(ne @2 @1))))
(if (wi::eq_p (@1, max - 1))
(switch
(if (cmp == GT_EXPR)
(eq @2 { wide_int_to_tree (TREE_TYPE (@1), wi::add (@1, 1)); }))
(if (cmp == LE_EXPR)
(ne @2 { wide_int_to_tree (TREE_TYPE (@1), wi::add (@1, 1)); }))))
(if (wi::eq_p (@1, min))
(switch
(if (cmp == LT_EXPR)
{ constant_boolean_node (false, type); })
(if (cmp == LE_EXPR)
(eq @2 @1))
(if (cmp == GE_EXPR)
{ constant_boolean_node (true, type); })
(if (cmp == GT_EXPR)
(ne @2 @1))))
(if (wi::eq_p (@1, min + 1))
(switch
(if (cmp == GE_EXPR)
(ne @2 { wide_int_to_tree (TREE_TYPE (@1), wi::sub (@1, 1)); }))
(if (cmp == LT_EXPR)
(eq @2 { wide_int_to_tree (TREE_TYPE (@1), wi::sub (@1, 1)); }))))
(if (wi::eq_p (@1, signed_max)
&& TYPE_UNSIGNED (arg1_type)
/* We will flip the signedness of the comparison operator
associated with the mode of @1, so the sign bit is
specified by this mode. Check that @1 is the signed
max associated with this sign bit. */
&& prec == GET_MODE_PRECISION (TYPE_MODE (arg1_type))
/* signed_type does not work on pointer types. */
&& INTEGRAL_TYPE_P (arg1_type))
/* The following case also applies to X < signed_max+1
and X >= signed_max+1 because previous transformations. */
(if (cmp == LE_EXPR || cmp == GT_EXPR)
(with { tree st = signed_type_for (arg1_type); }
(if (cmp == LE_EXPR)
(ge (convert:st @0) { build_zero_cst (st); })
(lt (convert:st @0) { build_zero_cst (st); }))))))))))
/* bool_var != 0 becomes bool_var. */
(simplify
(ne @0 integer_zerop@1)
......
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