X-Git-Url: http://git.sourceforge.jp/view?a=blobdiff_plain;f=gcc%2Ffold-const.c;h=991ad2e9e6fa38f4923ecbc376f0f37ac2c04910;hb=b1dd8e8795cedd1e45deff9e4d7bac5f5d73e248;hp=d24a7d1435f1a8affe2c91170c8b5f49afb60751;hpb=a0c2c45b3ac59ff10ce28f817eb57b0777c3a01f;p=pf3gnuchains%2Fgcc-fork.git diff --git a/gcc/fold-const.c b/gcc/fold-const.c index d24a7d1435f..991ad2e9e6f 100644 --- a/gcc/fold-const.c +++ b/gcc/fold-const.c @@ -80,7 +80,8 @@ static tree distribute_bit_expr PARAMS ((enum tree_code, tree, tree, tree)); 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)); @@ -105,6 +106,14 @@ static int count_cond 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 @@ -1090,8 +1099,8 @@ real_hex_to_f (s, mode) 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; @@ -1136,7 +1145,7 @@ real_hex_to_f (s, mode) The exponent field is a decimal integer. */ while (ISDIGIT(*p)) { - k = (*p++ & 0x7f) - '0'; + k = (*p++ & CHARMASK) - '0'; expon = 10 * expon + k; } @@ -1491,18 +1500,15 @@ int_const_binop (code, arg1, arg2, notrunc, forsize) /* 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; @@ -1599,7 +1605,7 @@ int_const_binop (code, arg1, arg2, notrunc, forsize) abort (); } - if (forsize && hi == 0 && low < 1000) + if (forsize && hi == 0 && low < 10000) return size_int_type_wide (low, TREE_TYPE (arg1)); else { @@ -1850,7 +1856,7 @@ size_int_type_wide (number, type) 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; @@ -1864,8 +1870,7 @@ size_int_type_wide (number, type) /* 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)) @@ -2021,7 +2026,7 @@ fold_convert (t, arg1) /* 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, @@ -2432,7 +2437,7 @@ operand_equal_for_comparison_p (arg0, arg1, other) { int unsignedp1, unsignedpo; tree primarg0, primarg1, primother; - unsigned correct_width; + unsigned int correct_width; if (operand_equal_p (arg0, arg1, 0)) return 1; @@ -2909,14 +2914,14 @@ optimize_bit_field_compare (code, compare_type, lhs, rhs) 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; @@ -3085,7 +3090,7 @@ static tree 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; @@ -3094,8 +3099,8 @@ decode_field_reference (exp, pbitsize, pbitpos, pmode, punsignedp, 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 @@ -3151,7 +3156,7 @@ all_ones_mask_p (mask, size) 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); @@ -3181,7 +3186,7 @@ simple_operand_p (exp) 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) @@ -3199,7 +3204,7 @@ simple_operand_p (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 @@ -3294,7 +3299,7 @@ range_binop (code, type, arg0, upper0_p, arg1, upper1_p) /* 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. */ @@ -3332,7 +3337,7 @@ make_range (exp, pin_p, plow, phigh) 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); } @@ -3450,8 +3455,17 @@ make_range (exp, pin_p, plow, phigh) 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; @@ -3880,7 +3894,7 @@ fold_truthop (code, truth_type, lhs, rhs) 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). @@ -3893,10 +3907,10 @@ fold_truthop (code, truth_type, lhs, rhs) 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; @@ -4333,9 +4347,13 @@ optimize_minmax_comparison (t) 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. */ @@ -4358,7 +4376,7 @@ extract_muldiv (t, c, code, wide_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); @@ -4379,6 +4397,17 @@ extract_muldiv (t, c, code, wide_type) 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 @@ -4394,6 +4423,11 @@ extract_muldiv (t, c, code, wide_type) 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) @@ -4429,6 +4463,10 @@ extract_muldiv (t, c, code, wide_type) 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))) @@ -4475,9 +4513,24 @@ extract_muldiv (t, c, code, wide_type) 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, @@ -4534,16 +4587,17 @@ extract_muldiv (t, c, code, wide_type) /* 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), @@ -4712,10 +4766,9 @@ fold (expr) 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++) { @@ -4732,10 +4785,8 @@ fold (expr) 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); @@ -4783,7 +4834,7 @@ fold (expr) 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 @@ -5037,17 +5088,17 @@ fold (expr) 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 @@ -5164,7 +5215,8 @@ fold (expr) { 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); @@ -5198,7 +5250,8 @@ fold (expr) 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); @@ -5224,9 +5277,9 @@ fold (expr) 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) @@ -5525,7 +5578,7 @@ fold (expr) 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)); @@ -5548,7 +5601,7 @@ fold (expr) { /* 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)); @@ -5685,7 +5738,9 @@ fold (expr) 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) @@ -5694,7 +5749,9 @@ fold (expr) 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) @@ -5875,7 +5932,7 @@ fold (expr) 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); @@ -5883,7 +5940,7 @@ fold (expr) 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)) @@ -5907,13 +5964,13 @@ fold (expr) ("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)) @@ -5993,13 +6050,13 @@ fold (expr) ("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)) @@ -6013,14 +6070,14 @@ fold (expr) 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: @@ -6090,7 +6147,15 @@ fold (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. */ @@ -6103,7 +6168,7 @@ fold (expr) (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 @@ -6134,9 +6199,9 @@ fold (expr) } - 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; } } @@ -6149,7 +6214,15 @@ fold (expr) 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 @@ -6160,7 +6233,7 @@ fold (expr) (TREE_OPERAND (TREE_OPERAND (varop, 0), 1))); tree mask, unsigned_type; - int precision; + unsigned int precision; tree folded_compare; if (constopnum == 0) @@ -6188,9 +6261,9 @@ fold (expr) } - 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; } } @@ -6819,7 +6892,8 @@ fold (expr) 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: @@ -6863,6 +6937,10 @@ fold (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: @@ -6876,11 +6954,11 @@ fold (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: @@ -6962,10 +7040,10 @@ fold (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 @@ -7015,8 +7093,8 @@ fold (expr) 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)