X-Git-Url: http://git.sourceforge.jp/view?a=blobdiff_plain;f=gcc%2Ffold-const.c;h=991ad2e9e6fa38f4923ecbc376f0f37ac2c04910;hb=b1dd8e8795cedd1e45deff9e4d7bac5f5d73e248;hp=24bf6f1af4adbc0f46bcee6f426ccc3d5f22b248;hpb=902de8edca4830967feab9a330a7a312d0d9dce7;p=pf3gnuchains%2Fgcc-fork.git diff --git a/gcc/fold-const.c b/gcc/fold-const.c index 24bf6f1af4a..991ad2e9e6f 100644 --- a/gcc/fold-const.c +++ b/gcc/fold-const.c @@ -54,13 +54,10 @@ Boston, MA 02111-1307, USA. */ #include "ggc.h" static void encode PARAMS ((HOST_WIDE_INT *, - HOST_WIDE_INT, HOST_WIDE_INT)); + unsigned HOST_WIDE_INT, + HOST_WIDE_INT)); static void decode PARAMS ((HOST_WIDE_INT *, - HOST_WIDE_INT *, HOST_WIDE_INT *)); -int div_and_round_double PARAMS ((enum tree_code, int, HOST_WIDE_INT, - HOST_WIDE_INT, HOST_WIDE_INT, - HOST_WIDE_INT, HOST_WIDE_INT *, - HOST_WIDE_INT *, HOST_WIDE_INT *, + unsigned HOST_WIDE_INT *, HOST_WIDE_INT *)); static tree negate_expr PARAMS ((tree)); static tree split_tree PARAMS ((tree, enum tree_code, tree *, tree *, @@ -83,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)); @@ -108,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 @@ -136,7 +142,8 @@ static int count_cond PARAMS ((tree, int)); static void encode (words, low, hi) HOST_WIDE_INT *words; - HOST_WIDE_INT low, hi; + unsigned HOST_WIDE_INT low; + HOST_WIDE_INT hi; { words[0] = LOWPART (low); words[1] = HIGHPART (low); @@ -151,7 +158,8 @@ encode (words, low, hi) static void decode (words, low, hi) HOST_WIDE_INT *words; - HOST_WIDE_INT *low, *hi; + unsigned HOST_WIDE_INT *low; + HOST_WIDE_INT *hi; { *low = words[0] + words[1] * BASE; *hi = words[2] + words[3] * BASE; @@ -172,8 +180,9 @@ force_fit_type (t, overflow) tree t; int overflow; { - HOST_WIDE_INT low, high; - register int prec; + unsigned HOST_WIDE_INT low; + HOST_WIDE_INT high; + unsigned int prec; if (TREE_CODE (t) == REAL_CST) { @@ -206,7 +215,7 @@ force_fit_type (t, overflow) { TREE_INT_CST_HIGH (t) = 0; if (prec < HOST_BITS_PER_WIDE_INT) - TREE_INT_CST_LOW (t) &= ~((HOST_WIDE_INT) (-1) << prec); + TREE_INT_CST_LOW (t) &= ~((unsigned HOST_WIDE_INT) (-1) << prec); } /* Unsigned types do not suffer sign extension or overflow. */ @@ -216,9 +225,11 @@ force_fit_type (t, overflow) /* If the value's sign bit is set, extend the sign. */ if (prec != 2 * HOST_BITS_PER_WIDE_INT && (prec > HOST_BITS_PER_WIDE_INT - ? (TREE_INT_CST_HIGH (t) - & ((HOST_WIDE_INT) 1 << (prec - HOST_BITS_PER_WIDE_INT - 1))) - : TREE_INT_CST_LOW (t) & ((HOST_WIDE_INT) 1 << (prec - 1)))) + ? 0 != (TREE_INT_CST_HIGH (t) + & ((HOST_WIDE_INT) 1 + << (prec - HOST_BITS_PER_WIDE_INT - 1))) + : 0 != (TREE_INT_CST_LOW (t) + & ((unsigned HOST_WIDE_INT) 1 << (prec - 1))))) { /* Value is negative: set to 1 all the bits that are outside this type's precision. */ @@ -229,7 +240,7 @@ force_fit_type (t, overflow) { TREE_INT_CST_HIGH (t) = -1; if (prec < HOST_BITS_PER_WIDE_INT) - TREE_INT_CST_LOW (t) |= ((HOST_WIDE_INT) (-1) << prec); + TREE_INT_CST_LOW (t) |= ((unsigned HOST_WIDE_INT) (-1) << prec); } } @@ -246,13 +257,16 @@ force_fit_type (t, overflow) int add_double (l1, h1, l2, h2, lv, hv) - HOST_WIDE_INT l1, h1, l2, h2; - HOST_WIDE_INT *lv, *hv; + unsigned HOST_WIDE_INT l1, l2; + HOST_WIDE_INT h1, h2; + unsigned HOST_WIDE_INT *lv; + HOST_WIDE_INT *hv; { - HOST_WIDE_INT l, h; + unsigned HOST_WIDE_INT l; + HOST_WIDE_INT h; l = l1 + l2; - h = h1 + h2 + ((unsigned HOST_WIDE_INT) l < (unsigned HOST_WIDE_INT) l1); + h = h1 + h2 + (l < l1); *lv = l; *hv = h; @@ -266,8 +280,10 @@ add_double (l1, h1, l2, h2, lv, hv) int neg_double (l1, h1, lv, hv) - HOST_WIDE_INT l1, h1; - HOST_WIDE_INT *lv, *hv; + unsigned HOST_WIDE_INT l1; + HOST_WIDE_INT h1; + unsigned HOST_WIDE_INT *lv; + HOST_WIDE_INT *hv; { if (l1 == 0) { @@ -291,15 +307,18 @@ neg_double (l1, h1, lv, hv) int mul_double (l1, h1, l2, h2, lv, hv) - HOST_WIDE_INT l1, h1, l2, h2; - HOST_WIDE_INT *lv, *hv; + unsigned HOST_WIDE_INT l1, l2; + HOST_WIDE_INT h1, h2; + unsigned HOST_WIDE_INT *lv; + HOST_WIDE_INT *hv; { HOST_WIDE_INT arg1[4]; HOST_WIDE_INT arg2[4]; HOST_WIDE_INT prod[4 * 2]; register unsigned HOST_WIDE_INT carry; register int i, j, k; - HOST_WIDE_INT toplow, tophigh, neglow, neghigh; + unsigned HOST_WIDE_INT toplow, neglow; + HOST_WIDE_INT tophigh, neghigh; encode (arg1, l1, h1); encode (arg2, l2, h2); @@ -348,9 +367,11 @@ mul_double (l1, h1, l2, h2, lv, hv) void lshift_double (l1, h1, count, prec, lv, hv, arith) - HOST_WIDE_INT l1, h1, count; - int prec; - HOST_WIDE_INT *lv, *hv; + unsigned HOST_WIDE_INT l1; + HOST_WIDE_INT h1, count; + unsigned int prec; + unsigned HOST_WIDE_INT *lv; + HOST_WIDE_INT *hv; int arith; { if (count < 0) @@ -373,14 +394,14 @@ lshift_double (l1, h1, count, prec, lv, hv, arith) } else if (count >= HOST_BITS_PER_WIDE_INT) { - *hv = (unsigned HOST_WIDE_INT) l1 << (count - HOST_BITS_PER_WIDE_INT); + *hv = l1 << (count - HOST_BITS_PER_WIDE_INT); *lv = 0; } else { *hv = (((unsigned HOST_WIDE_INT) h1 << count) - | ((unsigned HOST_WIDE_INT) l1 >> (HOST_BITS_PER_WIDE_INT - count - 1) >> 1)); - *lv = (unsigned HOST_WIDE_INT) l1 << count; + | (l1 >> (HOST_BITS_PER_WIDE_INT - count - 1) >> 1)); + *lv = l1 << count; } } @@ -391,12 +412,15 @@ lshift_double (l1, h1, count, prec, lv, hv, arith) void rshift_double (l1, h1, count, prec, lv, hv, arith) - HOST_WIDE_INT l1, h1, count; - int prec ATTRIBUTE_UNUSED; - HOST_WIDE_INT *lv, *hv; + unsigned HOST_WIDE_INT l1; + HOST_WIDE_INT h1, count; + unsigned int prec ATTRIBUTE_UNUSED; + unsigned HOST_WIDE_INT *lv; + HOST_WIDE_INT *hv; int arith; { unsigned HOST_WIDE_INT signmask; + signmask = (arith ? -((unsigned HOST_WIDE_INT) h1 >> (HOST_BITS_PER_WIDE_INT - 1)) : 0); @@ -421,7 +445,7 @@ rshift_double (l1, h1, count, prec, lv, hv, arith) } else { - *lv = (((unsigned HOST_WIDE_INT) l1 >> count) + *lv = ((l1 >> count) | ((unsigned HOST_WIDE_INT) h1 << (HOST_BITS_PER_WIDE_INT - count - 1) << 1)); *hv = ((signmask << (HOST_BITS_PER_WIDE_INT - count)) | ((unsigned HOST_WIDE_INT) h1 >> count)); @@ -435,11 +459,14 @@ rshift_double (l1, h1, count, prec, lv, hv, arith) void lrotate_double (l1, h1, count, prec, lv, hv) - HOST_WIDE_INT l1, h1, count; - int prec; - HOST_WIDE_INT *lv, *hv; + unsigned HOST_WIDE_INT l1; + HOST_WIDE_INT h1, count; + unsigned int prec; + unsigned HOST_WIDE_INT *lv; + HOST_WIDE_INT *hv; { - HOST_WIDE_INT s1l, s1h, s2l, s2h; + unsigned HOST_WIDE_INT s1l, s2l; + HOST_WIDE_INT s1h, s2h; count %= prec; if (count < 0) @@ -457,11 +484,14 @@ lrotate_double (l1, h1, count, prec, lv, hv) void rrotate_double (l1, h1, count, prec, lv, hv) - HOST_WIDE_INT l1, h1, count; - int prec; - HOST_WIDE_INT *lv, *hv; + unsigned HOST_WIDE_INT l1; + HOST_WIDE_INT h1, count; + unsigned int prec; + unsigned HOST_WIDE_INT *lv; + HOST_WIDE_INT *hv; { - HOST_WIDE_INT s1l, s1h, s2l, s2h; + unsigned HOST_WIDE_INT s1l, s2l; + HOST_WIDE_INT s1h, s2h; count %= prec; if (count < 0) @@ -488,23 +518,26 @@ div_and_round_double (code, uns, lquo, hquo, lrem, hrem) enum tree_code code; int uns; - HOST_WIDE_INT lnum_orig, hnum_orig; /* num == numerator == dividend */ - HOST_WIDE_INT lden_orig, hden_orig; /* den == denominator == divisor */ - HOST_WIDE_INT *lquo, *hquo, *lrem, *hrem; + unsigned HOST_WIDE_INT lnum_orig; /* num == numerator == dividend */ + HOST_WIDE_INT hnum_orig; + unsigned HOST_WIDE_INT lden_orig; /* den == denominator == divisor */ + HOST_WIDE_INT hden_orig; + unsigned HOST_WIDE_INT *lquo, *lrem; + HOST_WIDE_INT *hquo, *hrem; { int quo_neg = 0; HOST_WIDE_INT num[4 + 1]; /* extra element for scaling. */ HOST_WIDE_INT den[4], quo[4]; register int i, j; unsigned HOST_WIDE_INT work; - register unsigned HOST_WIDE_INT carry = 0; - HOST_WIDE_INT lnum = lnum_orig; + unsigned HOST_WIDE_INT carry = 0; + unsigned HOST_WIDE_INT lnum = lnum_orig; HOST_WIDE_INT hnum = hnum_orig; - HOST_WIDE_INT lden = lden_orig; + unsigned HOST_WIDE_INT lden = lden_orig; HOST_WIDE_INT hden = hden_orig; int overflow = 0; - if ((hden == 0) && (lden == 0)) + if (hden == 0 && lden == 0) overflow = 1, lden = 1; /* calculate quotient sign and convert operands to unsigned. */ @@ -514,7 +547,8 @@ div_and_round_double (code, uns, { quo_neg = ~ quo_neg; /* (minimum integer) / (-1) is the only overflow case. */ - if (neg_double (lnum, hnum, &lnum, &hnum) && (lden & hden) == -1) + if (neg_double (lnum, hnum, &lnum, &hnum) + && ((HOST_WIDE_INT) lden & hden) == -1) overflow = 1; } if (hden < 0) @@ -528,7 +562,7 @@ div_and_round_double (code, uns, { /* single precision */ *hquo = *hrem = 0; /* This unsigned division rounds toward zero. */ - *lquo = lnum / (unsigned HOST_WIDE_INT) lden; + *lquo = lnum / lden; goto finish_up; } @@ -550,106 +584,113 @@ div_and_round_double (code, uns, encode (den, lden, hden); /* Special code for when the divisor < BASE. */ - if (hden == 0 && lden < (HOST_WIDE_INT) BASE) + if (hden == 0 && lden < (unsigned HOST_WIDE_INT) BASE) { /* hnum != 0 already checked. */ for (i = 4 - 1; i >= 0; i--) { work = num[i] + carry * BASE; - quo[i] = work / (unsigned HOST_WIDE_INT) lden; - carry = work % (unsigned HOST_WIDE_INT) lden; + quo[i] = work / lden; + carry = work % lden; } } else { /* Full double precision division, with thanks to Don Knuth's "Seminumerical Algorithms". */ - int num_hi_sig, den_hi_sig; - unsigned HOST_WIDE_INT quo_est, scale; - - /* Find the highest non-zero divisor digit. */ - for (i = 4 - 1; ; i--) - if (den[i] != 0) { - den_hi_sig = i; - break; - } - - /* Insure that the first digit of the divisor is at least BASE/2. - This is required by the quotient digit estimation algorithm. */ - - scale = BASE / (den[den_hi_sig] + 1); - if (scale > 1) { /* scale divisor and dividend */ - carry = 0; - for (i = 0; i <= 4 - 1; i++) { - work = (num[i] * scale) + carry; - num[i] = LOWPART (work); - carry = HIGHPART (work); - } num[4] = carry; - carry = 0; - for (i = 0; i <= 4 - 1; i++) { - work = (den[i] * scale) + carry; - den[i] = LOWPART (work); - carry = HIGHPART (work); - if (den[i] != 0) den_hi_sig = i; - } - } + int num_hi_sig, den_hi_sig; + unsigned HOST_WIDE_INT quo_est, scale; - num_hi_sig = 4; + /* Find the highest non-zero divisor digit. */ + for (i = 4 - 1; ; i--) + if (den[i] != 0) { + den_hi_sig = i; + break; + } - /* Main loop */ - for (i = num_hi_sig - den_hi_sig - 1; i >= 0; i--) { - /* guess the next quotient digit, quo_est, by dividing the first - two remaining dividend digits by the high order quotient digit. - quo_est is never low and is at most 2 high. */ - unsigned HOST_WIDE_INT tmp; + /* Insure that the first digit of the divisor is at least BASE/2. + This is required by the quotient digit estimation algorithm. */ - num_hi_sig = i + den_hi_sig + 1; - work = num[num_hi_sig] * BASE + num[num_hi_sig - 1]; - if (num[num_hi_sig] != den[den_hi_sig]) - quo_est = work / den[den_hi_sig]; - else - quo_est = BASE - 1; + scale = BASE / (den[den_hi_sig] + 1); + if (scale > 1) + { /* scale divisor and dividend */ + carry = 0; + for (i = 0; i <= 4 - 1; i++) + { + work = (num[i] * scale) + carry; + num[i] = LOWPART (work); + carry = HIGHPART (work); + } - /* refine quo_est so it's usually correct, and at most one high. */ - tmp = work - quo_est * den[den_hi_sig]; - if (tmp < BASE - && den[den_hi_sig - 1] * quo_est > (tmp * BASE + num[num_hi_sig - 2])) - quo_est--; + num[4] = carry; + carry = 0; + for (i = 0; i <= 4 - 1; i++) + { + work = (den[i] * scale) + carry; + den[i] = LOWPART (work); + carry = HIGHPART (work); + if (den[i] != 0) den_hi_sig = i; + } + } - /* Try QUO_EST as the quotient digit, by multiplying the - divisor by QUO_EST and subtracting from the remaining dividend. - Keep in mind that QUO_EST is the I - 1st digit. */ + num_hi_sig = 4; - carry = 0; - for (j = 0; j <= den_hi_sig; j++) + /* Main loop */ + for (i = num_hi_sig - den_hi_sig - 1; i >= 0; i--) { - work = quo_est * den[j] + carry; - carry = HIGHPART (work); - work = num[i + j] - LOWPART (work); - num[i + j] = LOWPART (work); - carry += HIGHPART (work) != 0; - } + /* Guess the next quotient digit, quo_est, by dividing the first + two remaining dividend digits by the high order quotient digit. + quo_est is never low and is at most 2 high. */ + unsigned HOST_WIDE_INT tmp; + + num_hi_sig = i + den_hi_sig + 1; + work = num[num_hi_sig] * BASE + num[num_hi_sig - 1]; + if (num[num_hi_sig] != den[den_hi_sig]) + quo_est = work / den[den_hi_sig]; + else + quo_est = BASE - 1; - /* if quo_est was high by one, then num[i] went negative and - we need to correct things. */ + /* Refine quo_est so it's usually correct, and at most one high. */ + tmp = work - quo_est * den[den_hi_sig]; + if (tmp < BASE + && (den[den_hi_sig - 1] * quo_est + > (tmp * BASE + num[num_hi_sig - 2]))) + quo_est--; - if (num[num_hi_sig] < carry) - { - quo_est--; - carry = 0; /* add divisor back in */ + /* Try QUO_EST as the quotient digit, by multiplying the + divisor by QUO_EST and subtracting from the remaining dividend. + Keep in mind that QUO_EST is the I - 1st digit. */ + + carry = 0; for (j = 0; j <= den_hi_sig; j++) { - work = num[i + j] + den[j] + carry; + work = quo_est * den[j] + carry; carry = HIGHPART (work); + work = num[i + j] - LOWPART (work); num[i + j] = LOWPART (work); + carry += HIGHPART (work) != 0; } - num [num_hi_sig] += carry; - } - /* store the quotient digit. */ - quo[i] = quo_est; + /* If quo_est was high by one, then num[i] went negative and + we need to correct things. */ + if (num[num_hi_sig] < carry) + { + quo_est--; + carry = 0; /* add divisor back in */ + for (j = 0; j <= den_hi_sig; j++) + { + work = num[i + j] + den[j] + carry; + carry = HIGHPART (work); + num[i + j] = LOWPART (work); + } + + num [num_hi_sig] += carry; + } + + /* Store the quotient digit. */ + quo[i] = quo_est; + } } - } decode (quo, lquo, hquo); @@ -678,7 +719,8 @@ div_and_round_double (code, uns, add_double (*lquo, *hquo, (HOST_WIDE_INT) -1, (HOST_WIDE_INT) -1, lquo, hquo); } - else return overflow; + else + return overflow; break; case CEIL_DIV_EXPR: @@ -688,28 +730,33 @@ div_and_round_double (code, uns, add_double (*lquo, *hquo, (HOST_WIDE_INT) 1, (HOST_WIDE_INT) 0, lquo, hquo); } - else return overflow; + else + return overflow; break; case ROUND_DIV_EXPR: case ROUND_MOD_EXPR: /* round to closest integer */ { - HOST_WIDE_INT labs_rem = *lrem, habs_rem = *hrem; - HOST_WIDE_INT labs_den = lden, habs_den = hden, ltwice, htwice; - - /* get absolute values */ - if (*hrem < 0) neg_double (*lrem, *hrem, &labs_rem, &habs_rem); - if (hden < 0) neg_double (lden, hden, &labs_den, &habs_den); - - /* if (2 * abs (lrem) >= abs (lden)) */ + unsigned HOST_WIDE_INT labs_rem = *lrem; + HOST_WIDE_INT habs_rem = *hrem; + unsigned HOST_WIDE_INT labs_den = lden, ltwice; + HOST_WIDE_INT habs_den = hden, htwice; + + /* Get absolute values */ + if (*hrem < 0) + neg_double (*lrem, *hrem, &labs_rem, &habs_rem); + if (hden < 0) + neg_double (lden, hden, &labs_den, &habs_den); + + /* If (2 * abs (lrem) >= abs (lden)) */ mul_double ((HOST_WIDE_INT) 2, (HOST_WIDE_INT) 0, labs_rem, habs_rem, <wice, &htwice); + if (((unsigned HOST_WIDE_INT) habs_den < (unsigned HOST_WIDE_INT) htwice) || (((unsigned HOST_WIDE_INT) habs_den == (unsigned HOST_WIDE_INT) htwice) - && ((HOST_WIDE_INT unsigned) labs_den - < (unsigned HOST_WIDE_INT) ltwice))) + && (labs_den < ltwice))) { if (*hquo < 0) /* quo = quo - 1; */ @@ -720,7 +767,8 @@ div_and_round_double (code, uns, add_double (*lquo, *hquo, (HOST_WIDE_INT) 1, (HOST_WIDE_INT) 0, lquo, hquo); } - else return overflow; + else + return overflow; } break; @@ -1051,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; @@ -1097,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; } @@ -1412,9 +1460,12 @@ int_const_binop (code, arg1, arg2, notrunc, forsize) register tree arg1, arg2; int notrunc, forsize; { - HOST_WIDE_INT int1l, int1h, int2l, int2h; - HOST_WIDE_INT low, hi; - HOST_WIDE_INT garbagel, garbageh; + unsigned HOST_WIDE_INT int1l, int2l; + HOST_WIDE_INT int1h, int2h; + unsigned HOST_WIDE_INT low; + HOST_WIDE_INT hi; + unsigned HOST_WIDE_INT garbagel; + HOST_WIDE_INT garbageh; register tree t; int uns = TREE_UNSIGNED (TREE_TYPE (arg1)); int overflow = 0; @@ -1449,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; @@ -1482,13 +1530,14 @@ int_const_binop (code, arg1, arg2, notrunc, forsize) case FLOOR_DIV_EXPR: case CEIL_DIV_EXPR: case EXACT_DIV_EXPR: /* This is a shortcut for a common special case. */ - if (int2h == 0 && int2l > 0 + if (int2h == 0 && (HOST_WIDE_INT) int2l > 0 && ! TREE_CONSTANT_OVERFLOW (arg1) && ! TREE_CONSTANT_OVERFLOW (arg2) - && int1h == 0 && int1l >= 0) + && int1h == 0 && (HOST_WIDE_INT) int1l >= 0) { if (code == CEIL_DIV_EXPR) int1l += int2l - 1; + low = int1l / int2l, hi = 0; break; } @@ -1515,10 +1564,10 @@ int_const_binop (code, arg1, arg2, notrunc, forsize) case TRUNC_MOD_EXPR: case FLOOR_MOD_EXPR: case CEIL_MOD_EXPR: /* This is a shortcut for a common special case. */ - if (int2h == 0 && int2l > 0 + if (int2h == 0 && (HOST_WIDE_INT) int2l > 0 && ! TREE_CONSTANT_OVERFLOW (arg1) && ! TREE_CONSTANT_OVERFLOW (arg2) - && int1h == 0 && int1l >= 0) + && int1h == 0 && (HOST_WIDE_INT) int1l >= 0) { if (code == CEIL_MOD_EXPR) int1l += int2l - 1; @@ -1541,13 +1590,10 @@ int_const_binop (code, arg1, arg2, notrunc, forsize) < (unsigned HOST_WIDE_INT) int2h) || (((unsigned HOST_WIDE_INT) int1h == (unsigned HOST_WIDE_INT) int2h) - && ((unsigned HOST_WIDE_INT) int1l - < (unsigned HOST_WIDE_INT) int2l))); + && int1l < int2l)); else - low = ((int1h < int2h) - || ((int1h == int2h) - && ((unsigned HOST_WIDE_INT) int1l - < (unsigned HOST_WIDE_INT) int2l))); + low = (int1h < int2h + || (int1h == int2h && int1l < int2l)); if (low == (code == MIN_EXPR)) low = int1l, hi = int1h; @@ -1559,7 +1605,7 @@ int_const_binop (code, arg1, arg2, notrunc, forsize) abort (); } - if (forsize && hi == 0 && low >= 0 && low < 1000) + if (forsize && hi == 0 && low < 10000) return size_int_type_wide (low, TREE_TYPE (arg1)); else { @@ -1810,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; @@ -1824,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)) @@ -1868,8 +1913,8 @@ size_binop (code, arg0, arg1) { tree type = TREE_TYPE (arg0); - if (type != TREE_TYPE (arg1) - || TREE_CODE (type) != INTEGER_TYPE || ! TYPE_IS_SIZETYPE (type)) + if (TREE_CODE (type) != INTEGER_TYPE || ! TYPE_IS_SIZETYPE (type) + || type != TREE_TYPE (arg1)) abort (); /* Handle the special case of two integer constants faster. */ @@ -1905,8 +1950,8 @@ size_diffop (arg0, arg1) tree type = TREE_TYPE (arg0); tree ctype; - if (TREE_TYPE (arg1) != type || TREE_CODE (type) != INTEGER_TYPE - || ! TYPE_IS_SIZETYPE (type)) + if (TREE_CODE (type) != INTEGER_TYPE || ! TYPE_IS_SIZETYPE (type) + || type != TREE_TYPE (arg1)) abort (); /* If the type is already signed, just do the simple thing. */ @@ -1981,9 +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) - && TREE_INT_CST_HIGH (arg1) == 0 - && TREE_INT_CST_LOW (arg1) >= 0 - && TREE_INT_CST_LOW (arg1) < 1000) + && 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, @@ -2280,8 +2323,7 @@ operand_equal_p (arg0, arg1, only_const) case INTEGER_CST: return (! TREE_CONSTANT_OVERFLOW (arg0) && ! TREE_CONSTANT_OVERFLOW (arg1) - && TREE_INT_CST_LOW (arg0) == TREE_INT_CST_LOW (arg1) - && TREE_INT_CST_HIGH (arg0) == TREE_INT_CST_HIGH (arg1)); + && tree_int_cst_equal (arg0, arg1)); case REAL_CST: return (! TREE_CONSTANT_OVERFLOW (arg0) @@ -2395,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; @@ -2691,8 +2733,7 @@ invert_truthvalue (arg) switch (code) { case INTEGER_CST: - return convert (type, build_int_2 (TREE_INT_CST_LOW (arg) == 0 - && TREE_INT_CST_HIGH (arg) == 0, 0)); + return convert (type, build_int_2 (integer_zerop (arg), 0)); case TRUTH_AND_EXPR: return build (TRUTH_OR_EXPR, type, @@ -2873,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; @@ -3049,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; @@ -3058,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 @@ -3115,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); @@ -3145,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) @@ -3163,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 @@ -3258,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. */ @@ -3296,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); } @@ -3414,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; @@ -3844,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). @@ -3857,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; @@ -4297,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. */ @@ -4322,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); @@ -4343,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 @@ -4358,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) @@ -4393,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))) @@ -4439,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, @@ -4498,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), @@ -4676,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++) { @@ -4696,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); @@ -4747,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 @@ -5001,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 @@ -5100,10 +5187,9 @@ fold (expr) /* Fold an expression like: "foo"[2] */ if (TREE_CODE (arg0) == STRING_CST && TREE_CODE (arg1) == INTEGER_CST - && !TREE_INT_CST_HIGH (arg1) - && (i = TREE_INT_CST_LOW (arg1)) < TREE_STRING_LENGTH (arg0)) + && compare_tree_int (arg1, TREE_STRING_LENGTH (arg0)) < 0) { - t = build_int_2 (TREE_STRING_POINTER (arg0)[i], 0); + t = build_int_2 (TREE_STRING_POINTER (arg0)[TREE_INT_CST_LOW (arg))], 0); TREE_TYPE (t) = TREE_TYPE (TREE_TYPE (arg0)); force_fit_type (t, 0); } @@ -5129,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); @@ -5163,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); @@ -5189,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) @@ -5391,9 +5479,10 @@ fold (expr) STRIP_NOPS (tree110); STRIP_NOPS (tree111); if (TREE_CODE (tree110) == INTEGER_CST - && TREE_INT_CST_HIGH (tree110) == 0 - && (TREE_INT_CST_LOW (tree110) - == TYPE_PRECISION (TREE_TYPE (TREE_OPERAND (arg0, 0)))) + && 0 == compare_tree_int (tree110, + TYPE_PRECISION + (TREE_TYPE (TREE_OPERAND + (arg0, 0)))) && operand_equal_p (tree01, tree111, 0)) return build ((code0 == LSHIFT_EXPR ? LROTATE_EXPR @@ -5408,9 +5497,10 @@ fold (expr) STRIP_NOPS (tree010); STRIP_NOPS (tree011); if (TREE_CODE (tree010) == INTEGER_CST - && TREE_INT_CST_HIGH (tree010) == 0 - && (TREE_INT_CST_LOW (tree010) - == TYPE_PRECISION (TREE_TYPE (TREE_OPERAND (arg0, 0)))) + && 0 == compare_tree_int (tree010, + TYPE_PRECISION + (TREE_TYPE (TREE_OPERAND + (arg0, 0)))) && operand_equal_p (tree11, tree011, 0)) return build ((code0 != LSHIFT_EXPR ? LROTATE_EXPR @@ -5488,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)); @@ -5511,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)); @@ -5648,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) @@ -5657,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) @@ -5831,14 +5925,14 @@ fold (expr) && TREE_INT_CST_HIGH (TREE_OPERAND (arg0, 1)) == 0 && ((TREE_INT_CST_LOW (arg1) + TREE_INT_CST_LOW (TREE_OPERAND (arg0, 1))) - == GET_MODE_BITSIZE (TYPE_MODE (type)))) + == (unsigned int) GET_MODE_BITSIZE (TYPE_MODE (type)))) return TREE_OPERAND (arg0, 0); goto binary; 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); @@ -5846,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)) @@ -5870,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)) @@ -5956,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)) @@ -5976,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: @@ -6053,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. */ @@ -6066,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 @@ -6097,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; } } @@ -6112,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 @@ -6123,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) @@ -6151,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; } } @@ -6414,7 +6524,7 @@ fold (expr) { if (TREE_INT_CST_HIGH (arg1) == 0 && (TREE_INT_CST_LOW (arg1) - == ((HOST_WIDE_INT) 1 << (width - 1)) - 1) + == ((unsigned HOST_WIDE_INT) 1 << (width - 1)) - 1) && ! TREE_UNSIGNED (TREE_TYPE (arg1))) switch (TREE_CODE (t)) { @@ -6440,7 +6550,7 @@ fold (expr) else if (TREE_INT_CST_HIGH (arg1) == -1 && (- TREE_INT_CST_LOW (arg1) - == ((HOST_WIDE_INT) 1 << (width - 1))) + == ((unsigned HOST_WIDE_INT) 1 << (width - 1))) && ! TREE_UNSIGNED (TREE_TYPE (arg1))) switch (TREE_CODE (t)) { @@ -6466,7 +6576,7 @@ fold (expr) else if (TREE_INT_CST_HIGH (arg1) == 0 && (TREE_INT_CST_LOW (arg1) - == ((HOST_WIDE_INT) 1 << (width - 1)) - 1) + == ((unsigned HOST_WIDE_INT) 1 << (width - 1)) - 1) && TREE_UNSIGNED (TREE_TYPE (arg1))) switch (TREE_CODE (t)) @@ -6663,11 +6773,7 @@ fold (expr) if (TREE_CODE (arg0) == INTEGER_CST && TREE_CODE (arg1) == INTEGER_CST) { if (code == EQ_EXPR) - t1 = build_int_2 ((TREE_INT_CST_LOW (arg0) - == TREE_INT_CST_LOW (arg1)) - && (TREE_INT_CST_HIGH (arg0) - == TREE_INT_CST_HIGH (arg1)), - 0); + t1 = build_int_2 (tree_int_cst_equal (arg0, arg1), 0); else t1 = build_int_2 ((TREE_UNSIGNED (TREE_TYPE (arg0)) ? INT_CST_LT_UNSIGNED (arg0, arg1) @@ -6786,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: @@ -6830,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: @@ -6843,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: @@ -6929,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 @@ -6982,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)