static tree make_bit_field_ref PARAMS ((tree, tree, int, int, int));
static tree optimize_bit_field_compare PARAMS ((enum tree_code, tree,
tree, tree));
-static tree decode_field_reference PARAMS ((tree, int *, int *,
+static tree decode_field_reference PARAMS ((tree, HOST_WIDE_INT *,
+ HOST_WIDE_INT *,
enum machine_mode *, int *,
int *, tree *, tree *));
static int all_ones_mask_p PARAMS ((tree, int));
#define BRANCH_COST 1
#endif
+#if defined(HOST_EBCDIC)
+/* bit 8 is significant in EBCDIC */
+#define CHARMASK 0xff
+#else
+#define CHARMASK 0x7f
+#endif
+
+
/* We know that A1 + B1 = SUM1, using 2's complement arithmetic and ignoring
overflow. Suppose A, B and SUM have the same respective signs as A1, B1,
and SUM1. Then this yields nonzero if overflow occurred during the
if ((c >= '0' && c <= '9') || (c >= 'A' && c <= 'F')
|| (c >= 'a' && c <= 'f'))
{
- k = c & 0x7f;
- if (k >= 'a')
+ k = c & CHARMASK;
+ if (k >= 'a' && k <= 'f')
k = k - 'a' + 10;
else if (k >= 'A')
k = k - 'A' + 10;
The exponent field is a decimal integer. */
while (ISDIGIT(*p))
{
- k = (*p++ & 0x7f) - '0';
+ k = (*p++ & CHARMASK) - '0';
expon = 10 * expon + k;
}
/* It's unclear from the C standard whether shifts can overflow.
The following code ignores overflow; perhaps a C standard
interpretation ruling is needed. */
- lshift_double (int1l, int1h, int2l,
- TYPE_PRECISION (TREE_TYPE (arg1)),
- &low, &hi,
- !uns);
+ lshift_double (int1l, int1h, int2l, TYPE_PRECISION (TREE_TYPE (arg1)),
+ &low, &hi, !uns);
no_overflow = 1;
break;
case RROTATE_EXPR:
int2l = - int2l;
case LROTATE_EXPR:
- lrotate_double (int1l, int1h, int2l,
- TYPE_PRECISION (TREE_TYPE (arg1)),
+ lrotate_double (int1l, int1h, int2l, TYPE_PRECISION (TREE_TYPE (arg1)),
&low, &hi);
break;
abort ();
}
- if (forsize && hi == 0 && low < 1000)
+ if (forsize && hi == 0 && low < 10000)
return size_int_type_wide (low, TREE_TYPE (arg1));
else
{
tree type;
{
/* Type-size nodes already made for small sizes. */
- static tree size_table[2 * HOST_BITS_PER_WIDE_INT + 1];
+ static tree size_table[2048 + 1];
static int init_p = 0;
tree t;
/* If this is a positive number that fits in the table we use to hold
cached entries, see if it is already in the table and put it there
if not. */
- if (number >= 0
- && number < (int) (sizeof size_table / sizeof size_table[0]) / 2)
+ if (number >= 0 && number < (int) (sizeof size_table / sizeof size_table[0]))
{
if (size_table[number] != 0)
for (t = size_table[number]; t != 0; t = TREE_CHAIN (t))
/* If we are trying to make a sizetype for a small integer, use
size_int to pick up cached types to reduce duplicate nodes. */
if (TREE_CODE (type) == INTEGER_CST && TYPE_IS_SIZETYPE (type)
- && compare_tree_int (arg1, 1000) < 0)
+ && compare_tree_int (arg1, 10000) < 0)
return size_int_type_wide (TREE_INT_CST_LOW (arg1), type);
/* Given an integer constant, make new constant with new type,
{
int unsignedp1, unsignedpo;
tree primarg0, primarg1, primother;
- unsigned correct_width;
+ unsigned int correct_width;
if (operand_equal_p (arg0, arg1, 0))
return 1;
tree compare_type;
tree lhs, rhs;
{
- int lbitpos, lbitsize, rbitpos, rbitsize, nbitpos, nbitsize;
+ HOST_WIDE_INT lbitpos, lbitsize, rbitpos, rbitsize, nbitpos, nbitsize;
tree type = TREE_TYPE (lhs);
tree signed_type, unsigned_type;
int const_p = TREE_CODE (rhs) == INTEGER_CST;
enum machine_mode lmode, rmode, nmode;
int lunsignedp, runsignedp;
int lvolatilep = 0, rvolatilep = 0;
- int alignment;
+ unsigned int alignment;
tree linner, rinner = NULL_TREE;
tree mask;
tree offset;
decode_field_reference (exp, pbitsize, pbitpos, pmode, punsignedp,
pvolatilep, pmask, pand_mask)
tree exp;
- int *pbitsize, *pbitpos;
+ HOST_WIDE_INT *pbitsize, *pbitpos;
enum machine_mode *pmode;
int *punsignedp, *pvolatilep;
tree *pmask;
tree and_mask = 0;
tree mask, inner, offset;
tree unsigned_type;
- int precision;
- int alignment;
+ unsigned int precision;
+ unsigned int alignment;
/* All the optimizations using this function assume integer fields.
There are problems with FP fields since the type_for_size call
int size;
{
tree type = TREE_TYPE (mask);
- int precision = TYPE_PRECISION (type);
+ unsigned int precision = TYPE_PRECISION (type);
tree tmask;
tmask = build_int_2 (~0, ~0);
exp = TREE_OPERAND (exp, 0);
return (TREE_CODE_CLASS (TREE_CODE (exp)) == 'c'
- || (TREE_CODE_CLASS (TREE_CODE (exp)) == 'd'
+ || (DECL_P (exp)
&& ! TREE_ADDRESSABLE (exp)
&& ! TREE_THIS_VOLATILE (exp)
&& ! DECL_NONLOCAL (exp)
try to change a logical combination of comparisons into a range test.
For example, both
- X == 2 && X == 3 && X == 4 && X == 5
+ X == 2 || X == 3 || X == 4 || X == 5
and
X >= 2 && X <= 5
are converted to
\f
/* Given EXP, a logical expression, set the range it is testing into
variables denoted by PIN_P, PLOW, and PHIGH. Return the expression
- actually being tested. *PLOW and *PHIGH will have be made the same type
+ actually being tested. *PLOW and *PHIGH will be made of the same type
as the returned expression. If EXP is not a comparison, we will most
likely not be returning a useful value and range. */
if (TREE_CODE_CLASS (code) == '2'
|| TREE_CODE_CLASS (code) == '<'
|| (TREE_CODE_CLASS (code) == 'e'
- && tree_code_length[(int) code] > 1))
+ && TREE_CODE_LENGTH (code) > 1))
arg1 = TREE_OPERAND (exp, 1);
}
low = range_binop (PLUS_EXPR, type, n_high, 0,
integer_one_node, 0);
high = range_binop (MINUS_EXPR, type, n_low, 0,
- integer_one_node, 0);
- in_p = ! in_p;
+ integer_one_node, 0);
+
+ /* If the range is of the form +/- [ x+1, x ], we won't
+ be able to normalize it. But then, it represents the
+ whole range or the empty set, so make it
+ +/- [ -, - ]. */
+ if (tree_int_cst_equal (n_low, low)
+ && tree_int_cst_equal (n_high, high))
+ low = high = 0;
+ else
+ in_p = ! in_p;
}
else
low = n_low, high = n_high;
enum tree_code code;
tree truth_type, lhs, rhs;
{
- /* If this is the "or" of two comparisons, we can do something if we
+ /* If this is the "or" of two comparisons, we can do something if
the comparisons are NE_EXPR. If this is the "and", we can do something
if the comparisons are EQ_EXPR. I.e.,
(a->b == 2 && a->c == 4) can become (a->new == NEW).
enum tree_code lcode, rcode;
tree ll_arg, lr_arg, rl_arg, rr_arg;
tree ll_inner, lr_inner, rl_inner, rr_inner;
- int ll_bitsize, ll_bitpos, lr_bitsize, lr_bitpos;
- int rl_bitsize, rl_bitpos, rr_bitsize, rr_bitpos;
- int xll_bitpos, xlr_bitpos, xrl_bitpos, xrr_bitpos;
- int lnbitsize, lnbitpos, rnbitsize, rnbitpos;
+ HOST_WIDE_INT ll_bitsize, ll_bitpos, lr_bitsize, lr_bitpos;
+ HOST_WIDE_INT rl_bitsize, rl_bitpos, rr_bitsize, rr_bitpos;
+ HOST_WIDE_INT xll_bitpos, xlr_bitpos, xrl_bitpos, xrr_bitpos;
+ HOST_WIDE_INT lnbitsize, lnbitpos, rnbitsize, rnbitpos;
int ll_unsignedp, lr_unsignedp, rl_unsignedp, rr_unsignedp;
enum machine_mode ll_mode, lr_mode, rl_mode, rr_mode;
enum machine_mode lnmode, rnmode;
should be used for the computation if wider than our type.
For example, if we are dividing (X * 8) + (Y + 16) by 4, we can return
- (X * 2) + (Y + 4). We also canonicalize (X + 7) * 4 into X * 4 + 28
- in the hope that either the machine has a multiply-accumulate insn
- or that this is part of an addressing calculation.
+ (X * 2) + (Y + 4). We must, however, be assured that either the original
+ expression would not overflow or that overflow is undefined for the type
+ in the language in question.
+
+ We also canonicalize (X + 7) * 4 into X * 4 + 28 in the hope that either
+ the machine has a multiply-accumulate insn or that this is part of an
+ addressing calculation.
If we return a non-null expression, it is an equivalent form of the
original computation, but need not be in the original type. */
/* Don't deal with constants of zero here; they confuse the code below. */
if (integer_zerop (c))
- return 0;
+ return NULL_TREE;
if (TREE_CODE_CLASS (tcode) == '1')
op0 = TREE_OPERAND (t, 0);
break;
case CONVERT_EXPR: case NON_LVALUE_EXPR: case NOP_EXPR:
+ /* If op0 is an expression, and is unsigned, and the type is
+ smaller than ctype, then we cannot widen the expression. */
+ if ((TREE_CODE_CLASS (TREE_CODE (op0)) == '<'
+ || TREE_CODE_CLASS (TREE_CODE (op0)) == '1'
+ || TREE_CODE_CLASS (TREE_CODE (op0)) == '2'
+ || TREE_CODE_CLASS (TREE_CODE (op0)) == 'e')
+ && TREE_UNSIGNED (TREE_TYPE (op0))
+ && ! TYPE_IS_SIZETYPE (TREE_TYPE (op0))
+ && (GET_MODE_SIZE (TYPE_MODE (ctype))
+ > GET_MODE_SIZE (TYPE_MODE (TREE_TYPE (op0)))))
+ break;
/* Pass the constant down and see if we can make a simplification. If
we can, replace this expression with the inner simplification for
break;
case MIN_EXPR: case MAX_EXPR:
+ /* If widening the type changes the signedness, then we can't perform
+ this optimization as that changes the result. */
+ if (TREE_UNSIGNED (ctype) != TREE_UNSIGNED (type))
+ break;
+
/* MIN (a, b) / 5 -> MIN (a / 5, b / 5) */
if ((t1 = extract_muldiv (op0, c, code, wide_type)) != 0
&& (t2 = extract_muldiv (op1, c, code, wide_type)) != 0)
or floor division, by a power of two, so we can treat it that
way unless the multiplier or divisor overflows. */
if (TREE_CODE (op1) == INTEGER_CST
+ /* const_binop may not detect overflow correctly,
+ so check for it explicitly here. */
+ && TYPE_PRECISION (TREE_TYPE (size_one_node)) > TREE_INT_CST_LOW (op1)
+ && TREE_INT_CST_HIGH (op1) == 0
&& 0 != (t1 = convert (ctype,
const_binop (LSHIFT_EXPR, size_one_node,
op1, 0)))
break;
}
- /* Now do the operation and verify it doesn't overflow. */
- op1 = const_binop (code, convert (ctype, op1), convert (ctype, c), 0);
- if (op1 == 0 || TREE_OVERFLOW (op1))
+ /* If it's a multiply or a division/modulus operation of a multiple
+ of our constant, do the operation and verify it doesn't overflow. */
+ if (code == MULT_EXPR
+ || integer_zerop (const_binop (TRUNC_MOD_EXPR, op1, c, 0)))
+ {
+ op1 = const_binop (code, convert (ctype, op1), convert (ctype, c), 0);
+ if (op1 == 0 || TREE_OVERFLOW (op1))
+ break;
+ }
+ else
+ break;
+
+ /* If we have an unsigned type is not a sizetype, we cannot widen
+ the operation since it will change the result if the original
+ computation overflowed. */
+ if (TREE_UNSIGNED (ctype)
+ && ! TYPE_IS_SIZETYPE (ctype)
+ && ctype != type)
break;
/* If we were able to eliminate our operation from the first side,
/* If these operations "cancel" each other, we have the main
optimizations of this pass, which occur when either constant is a
multiple of the other, in which case we replace this with either an
- operation or CODE or TCODE. If we have an unsigned type that is
- not a sizetype, we canot do this for division since it will change
- the result if the original computation overflowed. */
- if ((code == MULT_EXPR && tcode == EXACT_DIV_EXPR
- && (! TREE_UNSIGNED (ctype)
- || (TREE_CODE (ctype) == INTEGER_TYPE
- && TYPE_IS_SIZETYPE (ctype))))
- || (tcode == MULT_EXPR
- && code != TRUNC_MOD_EXPR && code != CEIL_MOD_EXPR
- && code != FLOOR_MOD_EXPR && code != ROUND_MOD_EXPR))
+ operation or CODE or TCODE.
+
+ If we have an unsigned type that is not a sizetype, we canot do
+ this since it will change the result if the original computation
+ overflowed. */
+ if ((! TREE_UNSIGNED (ctype)
+ || TYPE_IS_SIZETYPE (ctype))
+ && ((code == MULT_EXPR && tcode == EXACT_DIV_EXPR)
+ || (tcode == MULT_EXPR
+ && code != TRUNC_MOD_EXPR && code != CEIL_MOD_EXPR
+ && code != FLOOR_MOD_EXPR && code != ROUND_MOD_EXPR)))
{
if (integer_zerop (const_binop (TRUNC_MOD_EXPR, op1, c, 0)))
return fold (build (tcode, ctype, convert (ctype, op0),
do arithmetic on them. */
wins = 0;
}
- else if (kind == 'e' || kind == '<'
- || kind == '1' || kind == '2' || kind == 'r')
+ else if (IS_EXPR_CODE_CLASS (kind) || kind == 'r')
{
- register int len = tree_code_length[(int) code];
+ register int len = TREE_CODE_LENGTH (code);
register int i;
for (i = 0; i < len; i++)
{
STRIP_SIGN_NOPS (op);
}
else
- {
- /* Strip any conversions that don't change the mode. */
- STRIP_NOPS (op);
- }
+ /* Strip any conversions that don't change the mode. */
+ STRIP_NOPS (op);
if (TREE_CODE (op) == COMPLEX_CST)
subop = TREE_REALPART (op);
The also optimizes non-constant cases that used to be done in
expand_expr.
- Before we do that, see if this is a BIT_AND_EXPR or a BIT_OR_EXPR,
+ Before we do that, see if this is a BIT_AND_EXPR or a BIT_IOR_EXPR,
one of the operands is a comparison and the other is a comparison, a
BIT_AND_EXPR with the constant 1, or a truth value. In that case, the
code below would make the expression more complex. Change it to a
int inside_int = INTEGRAL_TYPE_P (inside_type);
int inside_ptr = POINTER_TYPE_P (inside_type);
int inside_float = FLOAT_TYPE_P (inside_type);
- int inside_prec = TYPE_PRECISION (inside_type);
+ unsigned int inside_prec = TYPE_PRECISION (inside_type);
int inside_unsignedp = TREE_UNSIGNED (inside_type);
int inter_int = INTEGRAL_TYPE_P (inter_type);
int inter_ptr = POINTER_TYPE_P (inter_type);
int inter_float = FLOAT_TYPE_P (inter_type);
- int inter_prec = TYPE_PRECISION (inter_type);
+ unsigned int inter_prec = TYPE_PRECISION (inter_type);
int inter_unsignedp = TREE_UNSIGNED (inter_type);
int final_int = INTEGRAL_TYPE_P (final_type);
int final_ptr = POINTER_TYPE_P (final_type);
int final_float = FLOAT_TYPE_P (final_type);
- int final_prec = TYPE_PRECISION (final_type);
+ unsigned int final_prec = TYPE_PRECISION (final_type);
int final_unsignedp = TREE_UNSIGNED (final_type);
/* In addition to the cases of two conversions in a row
{
if (TREE_CODE (arg0) == INTEGER_CST)
{
- HOST_WIDE_INT low, high;
+ unsigned HOST_WIDE_INT low;
+ HOST_WIDE_INT high;
int overflow = neg_double (TREE_INT_CST_LOW (arg0),
TREE_INT_CST_HIGH (arg0),
&low, &high);
if (! TREE_UNSIGNED (type)
&& TREE_INT_CST_HIGH (arg0) < 0)
{
- HOST_WIDE_INT low, high;
+ unsigned HOST_WIDE_INT low;
+ HOST_WIDE_INT high;
int overflow = neg_double (TREE_INT_CST_LOW (arg0),
TREE_INT_CST_HIGH (arg0),
&low, &high);
case CONJ_EXPR:
if (TREE_CODE (TREE_TYPE (arg0)) != COMPLEX_TYPE)
- return arg0;
+ return convert (type, arg0);
else if (TREE_CODE (arg0) == COMPLEX_EXPR)
- return build (COMPLEX_EXPR, TREE_TYPE (arg0),
+ return build (COMPLEX_EXPR, type,
TREE_OPERAND (arg0, 0),
negate_expr (TREE_OPERAND (arg0, 1)));
else if (TREE_CODE (arg0) == COMPLEX_CST)
if (! FLOAT_TYPE_P (type))
{
if (! wins && integer_zerop (arg0))
- return negate_expr (arg1);
+ return convert (type, negate_expr (arg1));
if (integer_zerop (arg1))
return non_lvalue (convert (type, arg0));
{
/* Except with IEEE floating point, 0-x equals -x. */
if (! wins && real_zerop (arg0))
- return negate_expr (arg1);
+ return convert (type, negate_expr (arg1));
/* Except with IEEE floating point, x-0 equals x. */
if (real_zerop (arg1))
return non_lvalue (convert (type, arg0));
if (TREE_CODE (arg0) == INTEGER_CST && TREE_CODE (arg1) == NOP_EXPR
&& TREE_UNSIGNED (TREE_TYPE (TREE_OPERAND (arg1, 0))))
{
- int prec = TYPE_PRECISION (TREE_TYPE (TREE_OPERAND (arg1, 0)));
+ unsigned int prec
+ = TYPE_PRECISION (TREE_TYPE (TREE_OPERAND (arg1, 0)));
+
if (prec < BITS_PER_WORD && prec < HOST_BITS_PER_WIDE_INT
&& (~TREE_INT_CST_LOW (arg0)
& (((HOST_WIDE_INT) 1 << prec) - 1)) == 0)
if (TREE_CODE (arg1) == INTEGER_CST && TREE_CODE (arg0) == NOP_EXPR
&& TREE_UNSIGNED (TREE_TYPE (TREE_OPERAND (arg0, 0))))
{
- int prec = TYPE_PRECISION (TREE_TYPE (TREE_OPERAND (arg0, 0)));
+ unsigned int prec
+ = TYPE_PRECISION (TREE_TYPE (TREE_OPERAND (arg0, 0)));
+
if (prec < BITS_PER_WORD && prec < HOST_BITS_PER_WIDE_INT
&& (~TREE_INT_CST_LOW (arg1)
& (((HOST_WIDE_INT) 1 << prec) - 1)) == 0)
case MIN_EXPR:
if (operand_equal_p (arg0, arg1, 0))
- return arg0;
+ return omit_one_operand (type, arg0, arg1);
if (INTEGRAL_TYPE_P (type)
&& operand_equal_p (arg1, TYPE_MIN_VALUE (type), 1))
return omit_one_operand (type, arg1, arg0);
case MAX_EXPR:
if (operand_equal_p (arg0, arg1, 0))
- return arg0;
+ return omit_one_operand (type, arg0, arg1);
if (INTEGRAL_TYPE_P (type)
&& TYPE_MAX_VALUE (type)
&& operand_equal_p (arg1, TYPE_MAX_VALUE (type), 1))
("true" is a fixed value perhaps depending on the language.) */
/* If first arg is constant zero, return it. */
if (integer_zerop (arg0))
- return arg0;
+ return convert (type, arg0);
case TRUTH_AND_EXPR:
/* If either arg is constant true, drop it. */
if (TREE_CODE (arg0) == INTEGER_CST && ! integer_zerop (arg0))
- return non_lvalue (arg1);
+ return non_lvalue (convert (type, arg1));
if (TREE_CODE (arg1) == INTEGER_CST && ! integer_zerop (arg1))
- return non_lvalue (arg0);
+ return non_lvalue (convert (type, arg0));
/* If second arg is constant zero, result is zero, but first arg
must be evaluated. */
if (integer_zerop (arg1))
("true" is a fixed value perhaps depending on the language.) */
/* If first arg is constant true, return it. */
if (TREE_CODE (arg0) == INTEGER_CST && ! integer_zerop (arg0))
- return arg0;
+ return convert (type, arg0);
case TRUTH_OR_EXPR:
/* If either arg is constant zero, drop it. */
if (TREE_CODE (arg0) == INTEGER_CST && integer_zerop (arg0))
- return non_lvalue (arg1);
+ return non_lvalue (convert (type, arg1));
if (TREE_CODE (arg1) == INTEGER_CST && integer_zerop (arg1))
- return non_lvalue (arg0);
+ return non_lvalue (convert (type, arg0));
/* If second arg is constant true, result is true, but we must
evaluate first arg. */
if (TREE_CODE (arg1) == INTEGER_CST && ! integer_zerop (arg1))
case TRUTH_XOR_EXPR:
/* If either arg is constant zero, drop it. */
if (integer_zerop (arg0))
- return non_lvalue (arg1);
+ return non_lvalue (convert (type, arg1));
if (integer_zerop (arg1))
- return non_lvalue (arg0);
+ return non_lvalue (convert (type, arg0));
/* If either arg is constant true, this is a logical inversion. */
if (integer_onep (arg0))
- return non_lvalue (invert_truthvalue (arg1));
+ return non_lvalue (convert (type, invert_truthvalue (arg1)));
if (integer_onep (arg1))
- return non_lvalue (invert_truthvalue (arg0));
+ return non_lvalue (convert (type, invert_truthvalue (arg0)));
return t;
case EQ_EXPR:
tree newconst
= fold (build (PLUS_EXPR, TREE_TYPE (varop),
constop, TREE_OPERAND (varop, 1)));
- TREE_SET_CODE (varop, PREINCREMENT_EXPR);
+
+ /* Do not overwrite the current varop to be a preincrement,
+ create a new node so that we won't confuse our caller who
+ might create trees and throw them away, reusing the
+ arguments that they passed to build. This shows up in
+ the THEN or ELSE parts of ?: being postincrements. */
+ varop = build (PREINCREMENT_EXPR, TREE_TYPE (varop),
+ TREE_OPERAND (varop, 0),
+ TREE_OPERAND (varop, 1));
/* If VAROP is a reference to a bitfield, we must mask
the constant by the width of the field. */
(TREE_OPERAND
(TREE_OPERAND (varop, 0), 1)));
tree mask, unsigned_type;
- int precision;
+ unsigned int precision;
tree folded_compare;
/* First check whether the comparison would come out
}
- t = build (code, type, TREE_OPERAND (t, 0),
- TREE_OPERAND (t, 1));
- TREE_OPERAND (t, constopnum) = newconst;
+ t = build (code, type,
+ (constopnum == 0) ? newconst : varop,
+ (constopnum == 1) ? newconst : varop);
return t;
}
}
tree newconst
= fold (build (MINUS_EXPR, TREE_TYPE (varop),
constop, TREE_OPERAND (varop, 1)));
- TREE_SET_CODE (varop, PREDECREMENT_EXPR);
+
+ /* Do not overwrite the current varop to be a predecrement,
+ create a new node so that we won't confuse our caller who
+ might create trees and throw them away, reusing the
+ arguments that they passed to build. This shows up in
+ the THEN or ELSE parts of ?: being postdecrements. */
+ varop = build (PREDECREMENT_EXPR, TREE_TYPE (varop),
+ TREE_OPERAND (varop, 0),
+ TREE_OPERAND (varop, 1));
if (TREE_CODE (TREE_OPERAND (varop, 0)) == COMPONENT_REF
&& DECL_BIT_FIELD(TREE_OPERAND
(TREE_OPERAND
(TREE_OPERAND (varop, 0), 1)));
tree mask, unsigned_type;
- int precision;
+ unsigned int precision;
tree folded_compare;
if (constopnum == 0)
}
- t = build (code, type, TREE_OPERAND (t, 0),
- TREE_OPERAND (t, 1));
- TREE_OPERAND (t, constopnum) = newconst;
+ t = build (code, type,
+ (constopnum == 0) ? newconst : varop,
+ (constopnum == 1) ? newconst : varop);
return t;
}
}
switch (comp_code)
{
case EQ_EXPR:
- return pedantic_non_lvalue (negate_expr (arg1));
+ return
+ pedantic_non_lvalue (convert (type, negate_expr (arg1)));
case NE_EXPR:
return pedantic_non_lvalue (convert (type, arg1));
case GE_EXPR:
tree comp_op1 = TREE_OPERAND (arg0, 1);
tree comp_type = TREE_TYPE (comp_op0);
+ /* Avoid adding NOP_EXPRs in case this is an lvalue. */
+ if (TYPE_MAIN_VARIANT (comp_type) == TYPE_MAIN_VARIANT (type))
+ comp_type = type;
+
switch (comp_code)
{
case EQ_EXPR:
so that we can convert this back to the
corresponding COND_EXPR. */
return pedantic_non_lvalue
- (convert (type, (fold (build (MIN_EXPR, comp_type,
- (comp_code == LE_EXPR
- ? comp_op0 : comp_op1),
- (comp_code == LE_EXPR
- ? comp_op1 : comp_op0))))));
+ (convert (type, fold (build (MIN_EXPR, comp_type,
+ (comp_code == LE_EXPR
+ ? comp_op0 : comp_op1),
+ (comp_code == LE_EXPR
+ ? comp_op1 : comp_op0)))));
break;
case GE_EXPR:
case GT_EXPR:
/* If the second operand is simpler than the third, swap them
since that produces better jump optimization results. */
- if ((TREE_CONSTANT (arg1) || TREE_CODE_CLASS (TREE_CODE (arg1)) == 'd'
+ if ((TREE_CONSTANT (arg1) || DECL_P (arg1)
|| TREE_CODE (arg1) == SAVE_EXPR)
&& ! (TREE_CONSTANT (TREE_OPERAND (t, 2))
- || TREE_CODE_CLASS (TREE_CODE (TREE_OPERAND (t, 2))) == 'd'
+ || DECL_P (TREE_OPERAND (t, 2))
|| TREE_CODE (TREE_OPERAND (t, 2)) == SAVE_EXPR))
{
/* See if this can be inverted. If it can't, possibly because
return t;
/* Don't let (0, 0) be null pointer constant. */
if (integer_zerop (arg1))
- return build1 (NOP_EXPR, TREE_TYPE (arg1), arg1);
- return arg1;
+ return build1 (NOP_EXPR, type, arg1);
+ return convert (type, arg1);
case COMPLEX_EXPR:
if (wins)