Commit d1822754 by Eric Christopher Committed by Eric Christopher

fold-const.c (make_range): Cleanup type checking through function.

2004-06-23  Eric Christopher  <echristo@redhat.com>

	* fold-const.c (make_range): Cleanup type checking through function.
	Remove orig_type. Replace with checks to exp_type and arg0_type.
	Clarify comment when converting from unsigned to signed.

From-SVN: r83576
parent 2ac23d05
2004-06-23 Eric Christopher <echristo@redhat.com>
* fold-const.c (make_range): Cleanup type checking through function.
Remove orig_type. Replace with checks to exp_type and arg0_type.
Clarify comment when converting from unsigned to signed.
2004-06-23 Eric Christopher <echristo@redhat.com>
* config/mips/mips.c (mips_use_dfa_pipeline_interface): Add R3000.
* config/mips/mips.md: Remove R3000 scheduling description.
* config/mips/3000.md: New file.
......
......@@ -3532,8 +3532,8 @@ static tree
make_range (tree exp, int *pin_p, tree *plow, tree *phigh)
{
enum tree_code code;
tree arg0 = NULL_TREE, arg1 = NULL_TREE, type = NULL_TREE;
tree orig_type = NULL_TREE;
tree arg0 = NULL_TREE, arg1 = NULL_TREE;
tree exp_type = NULL_TREE, arg0_type = NULL_TREE;
int in_p, n_in_p;
tree low, high, n_low, n_high;
......@@ -3549,6 +3549,7 @@ make_range (tree exp, int *pin_p, tree *plow, tree *phigh)
while (1)
{
code = TREE_CODE (exp);
exp_type = TREE_TYPE (exp);
if (IS_EXPR_CODE_CLASS (TREE_CODE_CLASS (code)))
{
......@@ -3557,7 +3558,7 @@ make_range (tree exp, int *pin_p, tree *plow, tree *phigh)
if (TREE_CODE_CLASS (code) == '<'
|| TREE_CODE_CLASS (code) == '1'
|| TREE_CODE_CLASS (code) == '2')
type = TREE_TYPE (arg0);
arg0_type = TREE_TYPE (arg0);
if (TREE_CODE_CLASS (code) == '2'
|| TREE_CODE_CLASS (code) == '<'
|| (TREE_CODE_CLASS (code) == 'e'
......@@ -3565,11 +3566,6 @@ make_range (tree exp, int *pin_p, tree *plow, tree *phigh)
arg1 = TREE_OPERAND (exp, 1);
}
/* Set ORIG_TYPE as soon as TYPE is non-null so that we do not
lose a cast by accident. */
if (type != NULL_TREE && orig_type == NULL_TREE)
orig_type = type;
switch (code)
{
case TRUTH_NOT_EXPR:
......@@ -3612,16 +3608,15 @@ make_range (tree exp, int *pin_p, tree *plow, tree *phigh)
abort ();
}
exp = arg0;
/* If this is an unsigned comparison, we also know that EXP is
greater than or equal to zero. We base the range tests we make
on that fact, so we record it here so we can parse existing
range tests. */
if (TYPE_UNSIGNED (type) && (low == 0 || high == 0))
range tests. We test arg0_type since often the return type
of, e.g. EQ_EXPR, is boolean. */
if (TYPE_UNSIGNED (arg0_type) && (low == 0 || high == 0))
{
if (! merge_ranges (&n_in_p, &n_low, &n_high, in_p, low, high,
1, fold_convert (type, integer_zero_node),
1, fold_convert (arg0_type, integer_zero_node),
NULL_TREE))
break;
......@@ -3635,18 +3630,20 @@ make_range (tree exp, int *pin_p, tree *plow, tree *phigh)
in_p = ! in_p;
high = range_binop (MINUS_EXPR, NULL_TREE, low, 0,
integer_one_node, 0);
low = fold_convert (type, integer_zero_node);
low = fold_convert (arg0_type, integer_zero_node);
}
}
exp = arg0;
continue;
case NEGATE_EXPR:
/* (-x) IN [a,b] -> x in [-b, -a] */
n_low = range_binop (MINUS_EXPR, type,
fold_convert (type, integer_zero_node),
n_low = range_binop (MINUS_EXPR, exp_type,
fold_convert (exp_type, integer_zero_node),
0, high, 1);
n_high = range_binop (MINUS_EXPR, type,
fold_convert (type, integer_zero_node),
n_high = range_binop (MINUS_EXPR, exp_type,
fold_convert (exp_type, integer_zero_node),
0, low, 0);
low = n_low, high = n_high;
exp = arg0;
......@@ -3654,8 +3651,8 @@ make_range (tree exp, int *pin_p, tree *plow, tree *phigh)
case BIT_NOT_EXPR:
/* ~ X -> -X - 1 */
exp = build2 (MINUS_EXPR, type, negate_expr (arg0),
fold_convert (type, integer_one_node));
exp = build2 (MINUS_EXPR, exp_type, negate_expr (arg0),
fold_convert (exp_type, integer_one_node));
continue;
case PLUS_EXPR: case MINUS_EXPR:
......@@ -3667,9 +3664,9 @@ make_range (tree exp, int *pin_p, tree *plow, tree *phigh)
the bounds don't overflow. For unsigned, overflow is defined
and this is exactly the right thing. */
n_low = range_binop (code == MINUS_EXPR ? PLUS_EXPR : MINUS_EXPR,
type, low, 0, arg1, 0);
arg0_type, low, 0, arg1, 0);
n_high = range_binop (code == MINUS_EXPR ? PLUS_EXPR : MINUS_EXPR,
type, high, 1, arg1, 0);
arg0_type, high, 1, arg1, 0);
if ((n_low != 0 && TREE_OVERFLOW (n_low))
|| (n_high != 0 && TREE_OVERFLOW (n_high)))
break;
......@@ -3678,9 +3675,9 @@ make_range (tree exp, int *pin_p, tree *plow, tree *phigh)
value thus making n_high < n_low, and normalize it. */
if (n_low && n_high && tree_int_cst_lt (n_high, n_low))
{
low = range_binop (PLUS_EXPR, type, n_high, 0,
low = range_binop (PLUS_EXPR, arg0_type, n_high, 0,
integer_one_node, 0);
high = range_binop (MINUS_EXPR, type, n_low, 0,
high = range_binop (MINUS_EXPR, arg0_type, n_low, 0,
integer_one_node, 0);
/* If the range is of the form +/- [ x+1, x ], we won't
......@@ -3700,46 +3697,50 @@ make_range (tree exp, int *pin_p, tree *plow, tree *phigh)
continue;
case NOP_EXPR: case NON_LVALUE_EXPR: case CONVERT_EXPR:
if (TYPE_PRECISION (type) > TYPE_PRECISION (orig_type))
if (TYPE_PRECISION (arg0_type) > TYPE_PRECISION (exp_type))
break;
if (! INTEGRAL_TYPE_P (type)
|| (low != 0 && ! int_fits_type_p (low, type))
|| (high != 0 && ! int_fits_type_p (high, type)))
if (! INTEGRAL_TYPE_P (arg0_type)
|| (low != 0 && ! int_fits_type_p (low, arg0_type))
|| (high != 0 && ! int_fits_type_p (high, arg0_type)))
break;
n_low = low, n_high = high;
if (n_low != 0)
n_low = fold_convert (type, n_low);
n_low = fold_convert (arg0_type, n_low);
if (n_high != 0)
n_high = fold_convert (type, n_high);
n_high = fold_convert (arg0_type, n_high);
/* If we're converting arg0 from an unsigned type, to exp,
a signed type, we will be doing the compairson as unsigned.
The tests above have already verified that LOW and HIGH
are both positive.
/* If we're converting from an unsigned to a signed type,
we will be doing the comparison as unsigned. The tests above
have already verified that LOW and HIGH are both positive.
So we have to ensure that we will handle large unsigned
values the same way that the current signed bounds treat
negative values. */
So we have to make sure that the original unsigned value will
be interpreted as positive. */
if (TYPE_UNSIGNED (type) && ! TYPE_UNSIGNED (TREE_TYPE (exp)))
if (!TYPE_UNSIGNED (exp_type) && TYPE_UNSIGNED (arg0_type))
{
tree equiv_type = lang_hooks.types.type_for_mode
(TYPE_MODE (type), 1);
tree high_positive;
tree equiv_type = lang_hooks.types.type_for_mode
(TYPE_MODE (arg0_type), 1);
/* A range without an upper bound is, naturally, unbounded.
Since convert would have cropped a very large value, use
the max value for the destination type. */
high_positive
= TYPE_MAX_VALUE (equiv_type) ? TYPE_MAX_VALUE (equiv_type)
: TYPE_MAX_VALUE (type);
: TYPE_MAX_VALUE (arg0_type);
if (TYPE_PRECISION (type) == TYPE_PRECISION (TREE_TYPE (exp)))
high_positive = fold (build2 (RSHIFT_EXPR, type,
fold_convert (type,
if (TYPE_PRECISION (exp_type) == TYPE_PRECISION (arg0_type))
high_positive = fold (build2 (RSHIFT_EXPR, arg0_type,
fold_convert (arg0_type,
high_positive),
fold_convert (type,
fold_convert (arg0_type,
integer_one_node)));
/* If the low bound is specified, "and" the range with the
......@@ -3749,7 +3750,7 @@ make_range (tree exp, int *pin_p, tree *plow, tree *phigh)
{
if (! merge_ranges (&n_in_p, &n_low, &n_high,
1, n_low, n_high, 1,
fold_convert (type, integer_zero_node),
fold_convert (arg0_type, integer_zero_node),
high_positive))
break;
......@@ -3761,7 +3762,7 @@ make_range (tree exp, int *pin_p, tree *plow, tree *phigh)
that will be interpreted as negative. */
if (! merge_ranges (&n_in_p, &n_low, &n_high,
0, n_low, n_high, 1,
fold_convert (type, integer_zero_node),
fold_convert (arg0_type, integer_zero_node),
high_positive))
break;
......
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