00001
00002
00003
00004
00005
00006
00007
00008
00009
00010
00011
00012
00013
00014
00015
00016
00017
00018
00019
00020
00021
00022
00023
00024
00025
00026
00027
00028
00029
00030
00031
00032
00033
00034
00035
00036
00037
00038
00039
00040
00041
00042
00043
00044
00045
00046
00047
00048
00049
00050 #include "config.h"
00051 #include "system.h"
00052 #include "coretypes.h"
00053 #include "tm.h"
00054 #include "flags.h"
00055 #include "tree.h"
00056 #include "real.h"
00057 #include "rtl.h"
00058 #include "expr.h"
00059 #include "tm_p.h"
00060 #include "toplev.h"
00061 #include "ggc.h"
00062 #include "hashtab.h"
00063 #include "langhooks.h"
00064 #include "md5.h"
00065
00066
00067
00068
00069 enum comparison_code {
00070 COMPCODE_FALSE = 0,
00071 COMPCODE_LT = 1,
00072 COMPCODE_EQ = 2,
00073 COMPCODE_LE = 3,
00074 COMPCODE_GT = 4,
00075 COMPCODE_LTGT = 5,
00076 COMPCODE_GE = 6,
00077 COMPCODE_ORD = 7,
00078 COMPCODE_UNORD = 8,
00079 COMPCODE_UNLT = 9,
00080 COMPCODE_UNEQ = 10,
00081 COMPCODE_UNLE = 11,
00082 COMPCODE_UNGT = 12,
00083 COMPCODE_NE = 13,
00084 COMPCODE_UNGE = 14,
00085 COMPCODE_TRUE = 15
00086 };
00087
00088 static void encode (HOST_WIDE_INT *, unsigned HOST_WIDE_INT, HOST_WIDE_INT);
00089 static void decode (HOST_WIDE_INT *, unsigned HOST_WIDE_INT *, HOST_WIDE_INT *);
00090 static bool negate_mathfn_p (enum built_in_function);
00091 static bool negate_expr_p (tree);
00092 static tree negate_expr (tree);
00093 static tree split_tree (tree, enum tree_code, tree *, tree *, tree *, int);
00094 static tree associate_trees (tree, tree, enum tree_code, tree);
00095 static tree const_binop (enum tree_code, tree, tree, int);
00096 static enum tree_code invert_tree_comparison (enum tree_code, bool);
00097 static enum comparison_code comparison_to_compcode (enum tree_code);
00098 static enum tree_code compcode_to_comparison (enum comparison_code);
00099 static tree combine_comparisons (enum tree_code, enum tree_code,
00100 enum tree_code, tree, tree, tree);
00101 static int truth_value_p (enum tree_code);
00102 static int operand_equal_for_comparison_p (tree, tree, tree);
00103 static int twoval_comparison_p (tree, tree *, tree *, int *);
00104 static tree eval_subst (tree, tree, tree, tree, tree);
00105 static tree pedantic_omit_one_operand (tree, tree, tree);
00106 static tree distribute_bit_expr (enum tree_code, tree, tree, tree);
00107 static tree make_bit_field_ref (tree, tree, int, int, int);
00108 static tree optimize_bit_field_compare (enum tree_code, tree, tree, tree);
00109 static tree decode_field_reference (tree, HOST_WIDE_INT *, HOST_WIDE_INT *,
00110 enum machine_mode *, int *, int *,
00111 tree *, tree *);
00112 static int all_ones_mask_p (tree, int);
00113 static tree sign_bit_p (tree, tree);
00114 static int simple_operand_p (tree);
00115 static tree range_binop (enum tree_code, tree, tree, int, tree, int);
00116 static tree make_range (tree, int *, tree *, tree *);
00117 static tree build_range_check (tree, tree, int, tree, tree);
00118 static int merge_ranges (int *, tree *, tree *, int, tree, tree, int, tree,
00119 tree);
00120 static tree fold_range_test (tree);
00121 static tree fold_cond_expr_with_comparison (tree, tree, tree, tree);
00122 static tree unextend (tree, int, int, tree);
00123 static tree fold_truthop (enum tree_code, tree, tree, tree);
00124 static tree optimize_minmax_comparison (tree);
00125 static tree extract_muldiv (tree, tree, enum tree_code, tree);
00126 static tree extract_muldiv_1 (tree, tree, enum tree_code, tree);
00127 static int multiple_of_p (tree, tree, tree);
00128 static tree fold_binary_op_with_conditional_arg (tree, enum tree_code,
00129 tree, tree, int);
00130 static bool fold_real_zero_addition_p (tree, tree, int);
00131 static tree fold_mathfn_compare (enum built_in_function, enum tree_code,
00132 tree, tree, tree);
00133 static tree fold_inf_compare (enum tree_code, tree, tree, tree);
00134 static tree fold_div_compare (enum tree_code, tree, tree, tree);
00135 static bool reorder_operands_p (tree, tree);
00136 static tree fold_negate_const (tree, tree);
00137 static tree fold_not_const (tree, tree);
00138 static tree fold_relational_const (enum tree_code, tree, tree, tree);
00139 static tree fold_relational_hi_lo (enum tree_code *, const tree,
00140 tree *, tree *);
00141 static bool tree_expr_nonzero_p (tree);
00142
00143
00144
00145
00146
00147
00148
00149
00150
00151 #define OVERFLOW_SUM_SIGN(a, b, sum) ((~((a) ^ (b)) & ((a) ^ (sum))) < 0)
00152
00153
00154
00155
00156
00157
00158 #define LOWPART(x) \
00159 ((x) & (((unsigned HOST_WIDE_INT) 1 << (HOST_BITS_PER_WIDE_INT / 2)) - 1))
00160 #define HIGHPART(x) \
00161 ((unsigned HOST_WIDE_INT) (x) >> HOST_BITS_PER_WIDE_INT / 2)
00162 #define BASE ((unsigned HOST_WIDE_INT) 1 << HOST_BITS_PER_WIDE_INT / 2)
00163
00164
00165
00166
00167
00168 static void
00169 encode (HOST_WIDE_INT *words, unsigned HOST_WIDE_INT low, HOST_WIDE_INT hi)
00170 {
00171 words[0] = LOWPART (low);
00172 words[1] = HIGHPART (low);
00173 words[2] = LOWPART (hi);
00174 words[3] = HIGHPART (hi);
00175 }
00176
00177
00178
00179
00180
00181 static void
00182 decode (HOST_WIDE_INT *words, unsigned HOST_WIDE_INT *low,
00183 HOST_WIDE_INT *hi)
00184 {
00185 *low = words[0] + words[1] * BASE;
00186 *hi = words[2] + words[3] * BASE;
00187 }
00188
00189
00190
00191
00192
00193
00194
00195
00196
00197
00198
00199
00200
00201
00202
00203
00204 tree
00205 force_fit_type (tree t, int overflowable,
00206 bool overflowed, bool overflowed_const)
00207 {
00208 unsigned HOST_WIDE_INT low;
00209 HOST_WIDE_INT high;
00210 unsigned int prec;
00211 int sign_extended_type;
00212
00213 gcc_assert (TREE_CODE (t) == INTEGER_CST);
00214
00215 low = TREE_INT_CST_LOW (t);
00216 high = TREE_INT_CST_HIGH (t);
00217
00218 if (POINTER_TYPE_P (TREE_TYPE (t))
00219 || TREE_CODE (TREE_TYPE (t)) == OFFSET_TYPE)
00220 prec = POINTER_SIZE;
00221 else
00222 prec = TYPE_PRECISION (TREE_TYPE (t));
00223
00224 sign_extended_type = (!TYPE_UNSIGNED (TREE_TYPE (t))
00225 || (TREE_CODE (TREE_TYPE (t)) == INTEGER_TYPE
00226 && TYPE_IS_SIZETYPE (TREE_TYPE (t))));
00227
00228
00229
00230 if (prec >= 2 * HOST_BITS_PER_WIDE_INT)
00231 ;
00232 else if (prec > HOST_BITS_PER_WIDE_INT)
00233 high &= ~((HOST_WIDE_INT) (-1) << (prec - HOST_BITS_PER_WIDE_INT));
00234 else
00235 {
00236 high = 0;
00237 if (prec < HOST_BITS_PER_WIDE_INT)
00238 low &= ~((HOST_WIDE_INT) (-1) << prec);
00239 }
00240
00241 if (!sign_extended_type)
00242 ;
00243 else if (prec >= 2 * HOST_BITS_PER_WIDE_INT)
00244 ;
00245 else if (prec > HOST_BITS_PER_WIDE_INT)
00246 {
00247
00248 if (high & ((unsigned HOST_WIDE_INT)1
00249 << (prec - HOST_BITS_PER_WIDE_INT - 1)))
00250 high |= (HOST_WIDE_INT) (-1) << (prec - HOST_BITS_PER_WIDE_INT);
00251 }
00252 else if (prec == HOST_BITS_PER_WIDE_INT)
00253 {
00254 if ((HOST_WIDE_INT)low < 0)
00255 high = -1;
00256 }
00257 else
00258 {
00259
00260 if (low & ((unsigned HOST_WIDE_INT)1 << (prec - 1)))
00261 {
00262 high = -1;
00263 low |= (HOST_WIDE_INT)(-1) << prec;
00264 }
00265 }
00266
00267
00268 if (overflowed || overflowed_const
00269 || low != TREE_INT_CST_LOW (t) || high != TREE_INT_CST_HIGH (t))
00270 {
00271 t = build_int_cst_wide (TREE_TYPE (t), low, high);
00272
00273 if (overflowed
00274 || overflowable < 0
00275 || (overflowable > 0 && sign_extended_type))
00276 {
00277 t = copy_node (t);
00278 TREE_OVERFLOW (t) = 1;
00279 TREE_CONSTANT_OVERFLOW (t) = 1;
00280 }
00281 else if (overflowed_const)
00282 {
00283 t = copy_node (t);
00284 TREE_CONSTANT_OVERFLOW (t) = 1;
00285 }
00286 }
00287
00288 return t;
00289 }
00290
00291
00292
00293
00294
00295
00296 int
00297 add_double (unsigned HOST_WIDE_INT l1, HOST_WIDE_INT h1,
00298 unsigned HOST_WIDE_INT l2, HOST_WIDE_INT h2,
00299 unsigned HOST_WIDE_INT *lv, HOST_WIDE_INT *hv)
00300 {
00301 unsigned HOST_WIDE_INT l;
00302 HOST_WIDE_INT h;
00303
00304 l = l1 + l2;
00305 h = h1 + h2 + (l < l1);
00306
00307 *lv = l;
00308 *hv = h;
00309 return OVERFLOW_SUM_SIGN (h1, h2, h);
00310 }
00311
00312
00313
00314
00315
00316
00317 int
00318 neg_double (unsigned HOST_WIDE_INT l1, HOST_WIDE_INT h1,
00319 unsigned HOST_WIDE_INT *lv, HOST_WIDE_INT *hv)
00320 {
00321 if (l1 == 0)
00322 {
00323 *lv = 0;
00324 *hv = - h1;
00325 return (*hv & h1) < 0;
00326 }
00327 else
00328 {
00329 *lv = -l1;
00330 *hv = ~h1;
00331 return 0;
00332 }
00333 }
00334
00335
00336
00337
00338
00339
00340
00341 int
00342 mul_double (unsigned HOST_WIDE_INT l1, HOST_WIDE_INT h1,
00343 unsigned HOST_WIDE_INT l2, HOST_WIDE_INT h2,
00344 unsigned HOST_WIDE_INT *lv, HOST_WIDE_INT *hv)
00345 {
00346 HOST_WIDE_INT arg1[4];
00347 HOST_WIDE_INT arg2[4];
00348 HOST_WIDE_INT prod[4 * 2];
00349 unsigned HOST_WIDE_INT carry;
00350 int i, j, k;
00351 unsigned HOST_WIDE_INT toplow, neglow;
00352 HOST_WIDE_INT tophigh, neghigh;
00353
00354 encode (arg1, l1, h1);
00355 encode (arg2, l2, h2);
00356
00357 memset (prod, 0, sizeof prod);
00358
00359 for (i = 0; i < 4; i++)
00360 {
00361 carry = 0;
00362 for (j = 0; j < 4; j++)
00363 {
00364 k = i + j;
00365
00366 carry += arg1[i] * arg2[j];
00367 gcc_assert (arg1[i] * arg2[j] <= 0xFFFE0001);
00368 gcc_assert (carry <= 0xFFFF0000);
00369
00370 carry += prod[k];
00371 gcc_assert (carry <= 0xFFFFFFFF);
00372 prod[k] = LOWPART (carry);
00373 carry = HIGHPART (carry);
00374 }
00375 prod[i + 4] = carry;
00376 }
00377
00378 decode (prod, lv, hv);
00379
00380
00381
00382 decode (prod + 4, &toplow, &tophigh);
00383 if (h1 < 0)
00384 {
00385 neg_double (l2, h2, &neglow, &neghigh);
00386 add_double (neglow, neghigh, toplow, tophigh, &toplow, &tophigh);
00387 }
00388 if (h2 < 0)
00389 {
00390 neg_double (l1, h1, &neglow, &neghigh);
00391 add_double (neglow, neghigh, toplow, tophigh, &toplow, &tophigh);
00392 }
00393 return (*hv < 0 ? ~(toplow & tophigh) : toplow | tophigh) != 0;
00394 }
00395
00396
00397
00398
00399
00400
00401
00402 void
00403 lshift_double (unsigned HOST_WIDE_INT l1, HOST_WIDE_INT h1,
00404 HOST_WIDE_INT count, unsigned int prec,
00405 unsigned HOST_WIDE_INT *lv, HOST_WIDE_INT *hv, int arith)
00406 {
00407 unsigned HOST_WIDE_INT signmask;
00408
00409 if (count < 0)
00410 {
00411 rshift_double (l1, h1, -count, prec, lv, hv, arith);
00412 return;
00413 }
00414
00415 if (SHIFT_COUNT_TRUNCATED)
00416 count %= prec;
00417
00418 if (count >= 2 * HOST_BITS_PER_WIDE_INT)
00419 {
00420
00421
00422 *hv = 0;
00423 *lv = 0;
00424 }
00425 else if (count >= HOST_BITS_PER_WIDE_INT)
00426 {
00427 *hv = l1 << (count - HOST_BITS_PER_WIDE_INT);
00428 *lv = 0;
00429 }
00430 else
00431 {
00432 *hv = (((unsigned HOST_WIDE_INT) h1 << count)
00433 | (l1 >> (HOST_BITS_PER_WIDE_INT - count - 1) >> 1));
00434 *lv = l1 << count;
00435 }
00436
00437
00438
00439 signmask = -((prec > HOST_BITS_PER_WIDE_INT
00440 ? ((unsigned HOST_WIDE_INT) *hv
00441 >> (prec - HOST_BITS_PER_WIDE_INT - 1))
00442 : (*lv >> (prec - 1))) & 1);
00443
00444 if (prec >= 2 * HOST_BITS_PER_WIDE_INT)
00445 ;
00446 else if (prec >= HOST_BITS_PER_WIDE_INT)
00447 {
00448 *hv &= ~((HOST_WIDE_INT) (-1) << (prec - HOST_BITS_PER_WIDE_INT));
00449 *hv |= signmask << (prec - HOST_BITS_PER_WIDE_INT);
00450 }
00451 else
00452 {
00453 *hv = signmask;
00454 *lv &= ~((unsigned HOST_WIDE_INT) (-1) << prec);
00455 *lv |= signmask << prec;
00456 }
00457 }
00458
00459
00460
00461
00462
00463
00464 void
00465 rshift_double (unsigned HOST_WIDE_INT l1, HOST_WIDE_INT h1,
00466 HOST_WIDE_INT count, unsigned int prec,
00467 unsigned HOST_WIDE_INT *lv, HOST_WIDE_INT *hv,
00468 int arith)
00469 {
00470 unsigned HOST_WIDE_INT signmask;
00471
00472 signmask = (arith
00473 ? -((unsigned HOST_WIDE_INT) h1 >> (HOST_BITS_PER_WIDE_INT - 1))
00474 : 0);
00475
00476 if (SHIFT_COUNT_TRUNCATED)
00477 count %= prec;
00478
00479 if (count >= 2 * HOST_BITS_PER_WIDE_INT)
00480 {
00481
00482
00483 *hv = 0;
00484 *lv = 0;
00485 }
00486 else if (count >= HOST_BITS_PER_WIDE_INT)
00487 {
00488 *hv = 0;
00489 *lv = (unsigned HOST_WIDE_INT) h1 >> (count - HOST_BITS_PER_WIDE_INT);
00490 }
00491 else
00492 {
00493 *hv = (unsigned HOST_WIDE_INT) h1 >> count;
00494 *lv = ((l1 >> count)
00495 | ((unsigned HOST_WIDE_INT) h1 << (HOST_BITS_PER_WIDE_INT - count - 1) << 1));
00496 }
00497
00498
00499
00500 if (count >= (HOST_WIDE_INT)prec)
00501 {
00502 *hv = signmask;
00503 *lv = signmask;
00504 }
00505 else if ((prec - count) >= 2 * HOST_BITS_PER_WIDE_INT)
00506 ;
00507 else if ((prec - count) >= HOST_BITS_PER_WIDE_INT)
00508 {
00509 *hv &= ~((HOST_WIDE_INT) (-1) << (prec - count - HOST_BITS_PER_WIDE_INT));
00510 *hv |= signmask << (prec - count - HOST_BITS_PER_WIDE_INT);
00511 }
00512 else
00513 {
00514 *hv = signmask;
00515 *lv &= ~((unsigned HOST_WIDE_INT) (-1) << (prec - count));
00516 *lv |= signmask << (prec - count);
00517 }
00518 }
00519
00520
00521
00522
00523
00524
00525 void
00526 lrotate_double (unsigned HOST_WIDE_INT l1, HOST_WIDE_INT h1,
00527 HOST_WIDE_INT count, unsigned int prec,
00528 unsigned HOST_WIDE_INT *lv, HOST_WIDE_INT *hv)
00529 {
00530 unsigned HOST_WIDE_INT s1l, s2l;
00531 HOST_WIDE_INT s1h, s2h;
00532
00533 count %= prec;
00534 if (count < 0)
00535 count += prec;
00536
00537 lshift_double (l1, h1, count, prec, &s1l, &s1h, 0);
00538 rshift_double (l1, h1, prec - count, prec, &s2l, &s2h, 0);
00539 *lv = s1l | s2l;
00540 *hv = s1h | s2h;
00541 }
00542
00543
00544
00545
00546
00547 void
00548 rrotate_double (unsigned HOST_WIDE_INT l1, HOST_WIDE_INT h1,
00549 HOST_WIDE_INT count, unsigned int prec,
00550 unsigned HOST_WIDE_INT *lv, HOST_WIDE_INT *hv)
00551 {
00552 unsigned HOST_WIDE_INT s1l, s2l;
00553 HOST_WIDE_INT s1h, s2h;
00554
00555 count %= prec;
00556 if (count < 0)
00557 count += prec;
00558
00559 rshift_double (l1, h1, count, prec, &s1l, &s1h, 0);
00560 lshift_double (l1, h1, prec - count, prec, &s2l, &s2h, 0);
00561 *lv = s1l | s2l;
00562 *hv = s1h | s2h;
00563 }
00564
00565
00566
00567
00568
00569
00570
00571
00572
00573
00574 int
00575 div_and_round_double (enum tree_code code, int uns,
00576 unsigned HOST_WIDE_INT lnum_orig,
00577 HOST_WIDE_INT hnum_orig,
00578 unsigned HOST_WIDE_INT lden_orig,
00579 HOST_WIDE_INT hden_orig,
00580 unsigned HOST_WIDE_INT *lquo,
00581 HOST_WIDE_INT *hquo, unsigned HOST_WIDE_INT *lrem,
00582 HOST_WIDE_INT *hrem)
00583 {
00584 int quo_neg = 0;
00585 HOST_WIDE_INT num[4 + 1];
00586 HOST_WIDE_INT den[4], quo[4];
00587 int i, j;
00588 unsigned HOST_WIDE_INT work;
00589 unsigned HOST_WIDE_INT carry = 0;
00590 unsigned HOST_WIDE_INT lnum = lnum_orig;
00591 HOST_WIDE_INT hnum = hnum_orig;
00592 unsigned HOST_WIDE_INT lden = lden_orig;
00593 HOST_WIDE_INT hden = hden_orig;
00594 int overflow = 0;
00595
00596 if (hden == 0 && lden == 0)
00597 overflow = 1, lden = 1;
00598
00599
00600 if (!uns)
00601 {
00602 if (hnum < 0)
00603 {
00604 quo_neg = ~ quo_neg;
00605
00606 if (neg_double (lnum, hnum, &lnum, &hnum)
00607 && ((HOST_WIDE_INT) lden & hden) == -1)
00608 overflow = 1;
00609 }
00610 if (hden < 0)
00611 {
00612 quo_neg = ~ quo_neg;
00613 neg_double (lden, hden, &lden, &hden);
00614 }
00615 }
00616
00617 if (hnum == 0 && hden == 0)
00618 {
00619 *hquo = *hrem = 0;
00620
00621 *lquo = lnum / lden;
00622 goto finish_up;
00623 }
00624
00625 if (hnum == 0)
00626 {
00627
00628 *hquo = *lquo = 0;
00629 *hrem = hnum;
00630 *lrem = lnum;
00631 goto finish_up;
00632 }
00633
00634 memset (quo, 0, sizeof quo);
00635
00636 memset (num, 0, sizeof num);
00637 memset (den, 0, sizeof den);
00638
00639 encode (num, lnum, hnum);
00640 encode (den, lden, hden);
00641
00642
00643 if (hden == 0 && lden < (unsigned HOST_WIDE_INT) BASE)
00644 {
00645
00646 for (i = 4 - 1; i >= 0; i--)
00647 {
00648 work = num[i] + carry * BASE;
00649 quo[i] = work / lden;
00650 carry = work % lden;
00651 }
00652 }
00653 else
00654 {
00655
00656
00657 int num_hi_sig, den_hi_sig;
00658 unsigned HOST_WIDE_INT quo_est, scale;
00659
00660
00661 for (i = 4 - 1;; i--)
00662 if (den[i] != 0)
00663 {
00664 den_hi_sig = i;
00665 break;
00666 }
00667
00668
00669
00670
00671 scale = BASE / (den[den_hi_sig] + 1);
00672 if (scale > 1)
00673 {
00674 carry = 0;
00675 for (i = 0; i <= 4 - 1; i++)
00676 {
00677 work = (num[i] * scale) + carry;
00678 num[i] = LOWPART (work);
00679 carry = HIGHPART (work);
00680 }
00681
00682 num[4] = carry;
00683 carry = 0;
00684 for (i = 0; i <= 4 - 1; i++)
00685 {
00686 work = (den[i] * scale) + carry;
00687 den[i] = LOWPART (work);
00688 carry = HIGHPART (work);
00689 if (den[i] != 0) den_hi_sig = i;
00690 }
00691 }
00692
00693 num_hi_sig = 4;
00694
00695
00696 for (i = num_hi_sig - den_hi_sig - 1; i >= 0; i--)
00697 {
00698
00699
00700
00701 unsigned HOST_WIDE_INT tmp;
00702
00703 num_hi_sig = i + den_hi_sig + 1;
00704 work = num[num_hi_sig] * BASE + num[num_hi_sig - 1];
00705 if (num[num_hi_sig] != den[den_hi_sig])
00706 quo_est = work / den[den_hi_sig];
00707 else
00708 quo_est = BASE - 1;
00709
00710
00711 tmp = work - quo_est * den[den_hi_sig];
00712 if (tmp < BASE
00713 && (den[den_hi_sig - 1] * quo_est
00714 > (tmp * BASE + num[num_hi_sig - 2])))
00715 quo_est--;
00716
00717
00718
00719
00720
00721 carry = 0;
00722 for (j = 0; j <= den_hi_sig; j++)
00723 {
00724 work = quo_est * den[j] + carry;
00725 carry = HIGHPART (work);
00726 work = num[i + j] - LOWPART (work);
00727 num[i + j] = LOWPART (work);
00728 carry += HIGHPART (work) != 0;
00729 }
00730
00731
00732
00733 if (num[num_hi_sig] < (HOST_WIDE_INT) carry)
00734 {
00735 quo_est--;
00736 carry = 0;
00737 for (j = 0; j <= den_hi_sig; j++)
00738 {
00739 work = num[i + j] + den[j] + carry;
00740 carry = HIGHPART (work);
00741 num[i + j] = LOWPART (work);
00742 }
00743
00744 num [num_hi_sig] += carry;
00745 }
00746
00747
00748 quo[i] = quo_est;
00749 }
00750 }
00751
00752 decode (quo, lquo, hquo);
00753
00754 finish_up:
00755
00756 if (quo_neg)
00757 neg_double (*lquo, *hquo, lquo, hquo);
00758
00759
00760 mul_double (*lquo, *hquo, lden_orig, hden_orig, lrem, hrem);
00761 neg_double (*lrem, *hrem, lrem, hrem);
00762 add_double (lnum_orig, hnum_orig, *lrem, *hrem, lrem, hrem);
00763
00764 switch (code)
00765 {
00766 case TRUNC_DIV_EXPR:
00767 case TRUNC_MOD_EXPR:
00768 case EXACT_DIV_EXPR:
00769 return overflow;
00770
00771 case FLOOR_DIV_EXPR:
00772 case FLOOR_MOD_EXPR:
00773 if (quo_neg && (*lrem != 0 || *hrem != 0))
00774 {
00775
00776 add_double (*lquo, *hquo, (HOST_WIDE_INT) -1, (HOST_WIDE_INT) -1,
00777 lquo, hquo);
00778 }
00779 else
00780 return overflow;
00781 break;
00782
00783 case CEIL_DIV_EXPR:
00784 case CEIL_MOD_EXPR:
00785 if (!quo_neg && (*lrem != 0 || *hrem != 0))
00786 {
00787 add_double (*lquo, *hquo, (HOST_WIDE_INT) 1, (HOST_WIDE_INT) 0,
00788 lquo, hquo);
00789 }
00790 else
00791 return overflow;
00792 break;
00793
00794 case ROUND_DIV_EXPR:
00795 case ROUND_MOD_EXPR:
00796 {
00797 unsigned HOST_WIDE_INT labs_rem = *lrem;
00798 HOST_WIDE_INT habs_rem = *hrem;
00799 unsigned HOST_WIDE_INT labs_den = lden, ltwice;
00800 HOST_WIDE_INT habs_den = hden, htwice;
00801
00802
00803 if (*hrem < 0)
00804 neg_double (*lrem, *hrem, &labs_rem, &habs_rem);
00805 if (hden < 0)
00806 neg_double (lden, hden, &labs_den, &habs_den);
00807
00808
00809 mul_double ((HOST_WIDE_INT) 2, (HOST_WIDE_INT) 0,
00810 labs_rem, habs_rem, <wice, &htwice);
00811
00812 if (((unsigned HOST_WIDE_INT) habs_den
00813 < (unsigned HOST_WIDE_INT) htwice)
00814 || (((unsigned HOST_WIDE_INT) habs_den
00815 == (unsigned HOST_WIDE_INT) htwice)
00816 && (labs_den < ltwice)))
00817 {
00818 if (*hquo < 0)
00819
00820 add_double (*lquo, *hquo,
00821 (HOST_WIDE_INT) -1, (HOST_WIDE_INT) -1, lquo, hquo);
00822 else
00823
00824 add_double (*lquo, *hquo, (HOST_WIDE_INT) 1, (HOST_WIDE_INT) 0,
00825 lquo, hquo);
00826 }
00827 else
00828 return overflow;
00829 }
00830 break;
00831
00832 default:
00833 gcc_unreachable ();
00834 }
00835
00836
00837 mul_double (*lquo, *hquo, lden_orig, hden_orig, lrem, hrem);
00838 neg_double (*lrem, *hrem, lrem, hrem);
00839 add_double (lnum_orig, hnum_orig, *lrem, *hrem, lrem, hrem);
00840 return overflow;
00841 }
00842
00843
00844
00845
00846 static bool
00847 negate_mathfn_p (enum built_in_function code)
00848 {
00849 switch (code)
00850 {
00851 case BUILT_IN_ASIN:
00852 case BUILT_IN_ASINF:
00853 case BUILT_IN_ASINL:
00854 case BUILT_IN_ATAN:
00855 case BUILT_IN_ATANF:
00856 case BUILT_IN_ATANL:
00857 case BUILT_IN_SIN:
00858 case BUILT_IN_SINF:
00859 case BUILT_IN_SINL:
00860 case BUILT_IN_TAN:
00861 case BUILT_IN_TANF:
00862 case BUILT_IN_TANL:
00863 return true;
00864
00865 default:
00866 break;
00867 }
00868 return false;
00869 }
00870
00871
00872
00873
00874 bool
00875 may_negate_without_overflow_p (tree t)
00876 {
00877 unsigned HOST_WIDE_INT val;
00878 unsigned int prec;
00879 tree type;
00880
00881 gcc_assert (TREE_CODE (t) == INTEGER_CST);
00882
00883 type = TREE_TYPE (t);
00884 if (TYPE_UNSIGNED (type))
00885 return false;
00886
00887 prec = TYPE_PRECISION (type);
00888 if (prec > HOST_BITS_PER_WIDE_INT)
00889 {
00890 if (TREE_INT_CST_LOW (t) != 0)
00891 return true;
00892 prec -= HOST_BITS_PER_WIDE_INT;
00893 val = TREE_INT_CST_HIGH (t);
00894 }
00895 else
00896 val = TREE_INT_CST_LOW (t);
00897 if (prec < HOST_BITS_PER_WIDE_INT)
00898 val &= ((unsigned HOST_WIDE_INT) 1 << prec) - 1;
00899 return val != ((unsigned HOST_WIDE_INT) 1 << (prec - 1));
00900 }
00901
00902
00903
00904
00905 static bool
00906 negate_expr_p (tree t)
00907 {
00908 tree type;
00909
00910 if (t == 0)
00911 return false;
00912
00913 type = TREE_TYPE (t);
00914
00915 STRIP_SIGN_NOPS (t);
00916 switch (TREE_CODE (t))
00917 {
00918 case INTEGER_CST:
00919 if (TYPE_UNSIGNED (type) || ! flag_trapv)
00920 return true;
00921
00922
00923 return may_negate_without_overflow_p (t);
00924
00925 case REAL_CST:
00926 case NEGATE_EXPR:
00927 return true;
00928
00929 case COMPLEX_CST:
00930 return negate_expr_p (TREE_REALPART (t))
00931 && negate_expr_p (TREE_IMAGPART (t));
00932
00933 case PLUS_EXPR:
00934 if (FLOAT_TYPE_P (type) && !flag_unsafe_math_optimizations)
00935 return false;
00936
00937 if (negate_expr_p (TREE_OPERAND (t, 1))
00938 && reorder_operands_p (TREE_OPERAND (t, 0),
00939 TREE_OPERAND (t, 1)))
00940 return true;
00941
00942 return negate_expr_p (TREE_OPERAND (t, 0));
00943
00944 case MINUS_EXPR:
00945
00946 return (! FLOAT_TYPE_P (type) || flag_unsafe_math_optimizations)
00947 && reorder_operands_p (TREE_OPERAND (t, 0),
00948 TREE_OPERAND (t, 1));
00949
00950 case MULT_EXPR:
00951 if (TYPE_UNSIGNED (TREE_TYPE (t)))
00952 break;
00953
00954
00955
00956 case RDIV_EXPR:
00957 if (! HONOR_SIGN_DEPENDENT_ROUNDING (TYPE_MODE (TREE_TYPE (t))))
00958 return negate_expr_p (TREE_OPERAND (t, 1))
00959 || negate_expr_p (TREE_OPERAND (t, 0));
00960 break;
00961
00962 case NOP_EXPR:
00963
00964 if (TREE_CODE (type) == REAL_TYPE)
00965 {
00966 tree tem = strip_float_extensions (t);
00967 if (tem != t)
00968 return negate_expr_p (tem);
00969 }
00970 break;
00971
00972 case CALL_EXPR:
00973
00974 if (negate_mathfn_p (builtin_mathfn_code (t)))
00975 return negate_expr_p (TREE_VALUE (TREE_OPERAND (t, 1)));
00976 break;
00977
00978 case RSHIFT_EXPR:
00979
00980 if (TREE_CODE (TREE_OPERAND (t, 1)) == INTEGER_CST)
00981 {
00982 tree op1 = TREE_OPERAND (t, 1);
00983 if (TREE_INT_CST_HIGH (op1) == 0
00984 && (unsigned HOST_WIDE_INT) (TYPE_PRECISION (type) - 1)
00985 == TREE_INT_CST_LOW (op1))
00986 return true;
00987 }
00988 break;
00989
00990 default:
00991 break;
00992 }
00993 return false;
00994 }
00995
00996
00997
00998
00999 static tree
01000 negate_expr (tree t)
01001 {
01002 tree type;
01003 tree tem;
01004
01005 if (t == 0)
01006 return 0;
01007
01008 type = TREE_TYPE (t);
01009 STRIP_SIGN_NOPS (t);
01010
01011 switch (TREE_CODE (t))
01012 {
01013 case INTEGER_CST:
01014 tem = fold_negate_const (t, type);
01015 if (! TREE_OVERFLOW (tem)
01016 || TYPE_UNSIGNED (type)
01017 || ! flag_trapv)
01018 return tem;
01019 break;
01020
01021 case REAL_CST:
01022 tem = fold_negate_const (t, type);
01023
01024 if (! TREE_OVERFLOW (tem) || ! flag_trapping_math)
01025 return fold_convert (type, tem);
01026 break;
01027
01028 case COMPLEX_CST:
01029 {
01030 tree rpart = negate_expr (TREE_REALPART (t));
01031 tree ipart = negate_expr (TREE_IMAGPART (t));
01032
01033 if ((TREE_CODE (rpart) == REAL_CST
01034 && TREE_CODE (ipart) == REAL_CST)
01035 || (TREE_CODE (rpart) == INTEGER_CST
01036 && TREE_CODE (ipart) == INTEGER_CST))
01037 return build_complex (type, rpart, ipart);
01038 }
01039 break;
01040
01041 case NEGATE_EXPR:
01042 return fold_convert (type, TREE_OPERAND (t, 0));
01043
01044 case PLUS_EXPR:
01045 if (! FLOAT_TYPE_P (type) || flag_unsafe_math_optimizations)
01046 {
01047
01048 if (negate_expr_p (TREE_OPERAND (t, 1))
01049 && reorder_operands_p (TREE_OPERAND (t, 0),
01050 TREE_OPERAND (t, 1)))
01051 {
01052 tem = negate_expr (TREE_OPERAND (t, 1));
01053 tem = fold (build2 (MINUS_EXPR, TREE_TYPE (t),
01054 tem, TREE_OPERAND (t, 0)));
01055 return fold_convert (type, tem);
01056 }
01057
01058
01059 if (negate_expr_p (TREE_OPERAND (t, 0)))
01060 {
01061 tem = negate_expr (TREE_OPERAND (t, 0));
01062 tem = fold (build2 (MINUS_EXPR, TREE_TYPE (t),
01063 tem, TREE_OPERAND (t, 1)));
01064 return fold_convert (type, tem);
01065 }
01066 }
01067 break;
01068
01069 case MINUS_EXPR:
01070
01071 if ((! FLOAT_TYPE_P (type) || flag_unsafe_math_optimizations)
01072 && reorder_operands_p (TREE_OPERAND (t, 0), TREE_OPERAND (t, 1)))
01073 return fold_convert (type,
01074 fold (build2 (MINUS_EXPR, TREE_TYPE (t),
01075 TREE_OPERAND (t, 1),
01076 TREE_OPERAND (t, 0))));
01077 break;
01078
01079 case MULT_EXPR:
01080 if (TYPE_UNSIGNED (TREE_TYPE (t)))
01081 break;
01082
01083
01084
01085 case RDIV_EXPR:
01086 if (! HONOR_SIGN_DEPENDENT_ROUNDING (TYPE_MODE (TREE_TYPE (t))))
01087 {
01088 tem = TREE_OPERAND (t, 1);
01089 if (negate_expr_p (tem))
01090 return fold_convert (type,
01091 fold (build2 (TREE_CODE (t), TREE_TYPE (t),
01092 TREE_OPERAND (t, 0),
01093 negate_expr (tem))));
01094 tem = TREE_OPERAND (t, 0);
01095 if (negate_expr_p (tem))
01096 return fold_convert (type,
01097 fold (build2 (TREE_CODE (t), TREE_TYPE (t),
01098 negate_expr (tem),
01099 TREE_OPERAND (t, 1))));
01100 }
01101 break;
01102
01103 case NOP_EXPR:
01104
01105 if (TREE_CODE (type) == REAL_TYPE)
01106 {
01107 tem = strip_float_extensions (t);
01108 if (tem != t && negate_expr_p (tem))
01109 return fold_convert (type, negate_expr (tem));
01110 }
01111 break;
01112
01113 case CALL_EXPR:
01114
01115 if (negate_mathfn_p (builtin_mathfn_code (t))
01116 && negate_expr_p (TREE_VALUE (TREE_OPERAND (t, 1))))
01117 {
01118 tree fndecl, arg, arglist;
01119
01120 fndecl = get_callee_fndecl (t);
01121 arg = negate_expr (TREE_VALUE (TREE_OPERAND (t, 1)));
01122 arglist = build_tree_list (NULL_TREE, arg);
01123 return build_function_call_expr (fndecl, arglist);
01124 }
01125 break;
01126
01127 case RSHIFT_EXPR:
01128
01129 if (TREE_CODE (TREE_OPERAND (t, 1)) == INTEGER_CST)
01130 {
01131 tree op1 = TREE_OPERAND (t, 1);
01132 if (TREE_INT_CST_HIGH (op1) == 0
01133 && (unsigned HOST_WIDE_INT) (TYPE_PRECISION (type) - 1)
01134 == TREE_INT_CST_LOW (op1))
01135 {
01136 tree ntype = TYPE_UNSIGNED (type)
01137 ? lang_hooks.types.signed_type (type)
01138 : lang_hooks.types.unsigned_type (type);
01139 tree temp = fold_convert (ntype, TREE_OPERAND (t, 0));
01140 temp = fold (build2 (RSHIFT_EXPR, ntype, temp, op1));
01141 return fold_convert (type, temp);
01142 }
01143 }
01144 break;
01145
01146 default:
01147 break;
01148 }
01149
01150 tem = fold (build1 (NEGATE_EXPR, TREE_TYPE (t), t));
01151 return fold_convert (type, tem);
01152 }
01153
01154
01155
01156
01157
01158
01159
01160
01161
01162
01163
01164
01165
01166
01167
01168
01169
01170
01171
01172
01173
01174 static tree
01175 split_tree (tree in, enum tree_code code, tree *conp, tree *litp,
01176 tree *minus_litp, int negate_p)
01177 {
01178 tree var = 0;
01179
01180 *conp = 0;
01181 *litp = 0;
01182 *minus_litp = 0;
01183
01184
01185 STRIP_SIGN_NOPS (in);
01186
01187 if (TREE_CODE (in) == INTEGER_CST || TREE_CODE (in) == REAL_CST)
01188 *litp = in;
01189 else if (TREE_CODE (in) == code
01190 || (! FLOAT_TYPE_P (TREE_TYPE (in))
01191
01192
01193
01194
01195 && ((code == PLUS_EXPR && TREE_CODE (in) == MINUS_EXPR)
01196 || (code == MINUS_EXPR && TREE_CODE (in) == PLUS_EXPR))))
01197 {
01198 tree op0 = TREE_OPERAND (in, 0);
01199 tree op1 = TREE_OPERAND (in, 1);
01200 int neg1_p = TREE_CODE (in) == MINUS_EXPR;
01201 int neg_litp_p = 0, neg_conp_p = 0, neg_var_p = 0;
01202
01203
01204 if (TREE_CODE (op0) == INTEGER_CST || TREE_CODE (op0) == REAL_CST)
01205 *litp = op0, op0 = 0;
01206 else if (TREE_CODE (op1) == INTEGER_CST || TREE_CODE (op1) == REAL_CST)
01207 *litp = op1, neg_litp_p = neg1_p, op1 = 0;
01208
01209 if (op0 != 0 && TREE_CONSTANT (op0))
01210 *conp = op0, op0 = 0;
01211 else if (op1 != 0 && TREE_CONSTANT (op1))
01212 *conp = op1, neg_conp_p = neg1_p, op1 = 0;
01213
01214
01215
01216 if (op0 != 0 && op1 != 0)
01217 var = in;
01218 else if (op0 != 0)
01219 var = op0;
01220 else
01221 var = op1, neg_var_p = neg1_p;
01222
01223
01224 if (neg_litp_p)
01225 *minus_litp = *litp, *litp = 0;
01226 if (neg_conp_p)
01227 *conp = negate_expr (*conp);
01228 if (neg_var_p)
01229 var = negate_expr (var);
01230 }
01231 else if (TREE_CONSTANT (in))
01232 *conp = in;
01233 else
01234 var = in;
01235
01236 if (negate_p)
01237 {
01238 if (*litp)
01239 *minus_litp = *litp, *litp = 0;
01240 else if (*minus_litp)
01241 *litp = *minus_litp, *minus_litp = 0;
01242 *conp = negate_expr (*conp);
01243 var = negate_expr (var);
01244 }
01245
01246 return var;
01247 }
01248
01249
01250
01251
01252
01253 static tree
01254 associate_trees (tree t1, tree t2, enum tree_code code, tree type)
01255 {
01256 if (t1 == 0)
01257 return t2;
01258 else if (t2 == 0)
01259 return t1;
01260
01261
01262
01263
01264 if (TREE_CODE (t1) == code || TREE_CODE (t2) == code
01265 || TREE_CODE (t1) == MINUS_EXPR || TREE_CODE (t2) == MINUS_EXPR)
01266 {
01267 if (code == PLUS_EXPR)
01268 {
01269 if (TREE_CODE (t1) == NEGATE_EXPR)
01270 return build2 (MINUS_EXPR, type, fold_convert (type, t2),
01271 fold_convert (type, TREE_OPERAND (t1, 0)));
01272 else if (TREE_CODE (t2) == NEGATE_EXPR)
01273 return build2 (MINUS_EXPR, type, fold_convert (type, t1),
01274 fold_convert (type, TREE_OPERAND (t2, 0)));
01275 else if (integer_zerop (t2))
01276 return fold_convert (type, t1);
01277 }
01278 else if (code == MINUS_EXPR)
01279 {
01280 if (integer_zerop (t2))
01281 return fold_convert (type, t1);
01282 }
01283
01284 return build2 (code, type, fold_convert (type, t1),
01285 fold_convert (type, t2));
01286 }
01287
01288 return fold (build2 (code, type, fold_convert (type, t1),
01289 fold_convert (type, t2)));
01290 }
01291
01292
01293
01294
01295
01296
01297 tree
01298 int_const_binop (enum tree_code code, tree arg1, tree arg2, int notrunc)
01299 {
01300 unsigned HOST_WIDE_INT int1l, int2l;
01301 HOST_WIDE_INT int1h, int2h;
01302 unsigned HOST_WIDE_INT low;
01303 HOST_WIDE_INT hi;
01304 unsigned HOST_WIDE_INT garbagel;
01305 HOST_WIDE_INT garbageh;
01306 tree t;
01307 tree type = TREE_TYPE (arg1);
01308 int uns = TYPE_UNSIGNED (type);
01309 int is_sizetype
01310 = (TREE_CODE (type) == INTEGER_TYPE && TYPE_IS_SIZETYPE (type));
01311 int overflow = 0;
01312 int no_overflow = 0;
01313
01314 int1l = TREE_INT_CST_LOW (arg1);
01315 int1h = TREE_INT_CST_HIGH (arg1);
01316 int2l = TREE_INT_CST_LOW (arg2);
01317 int2h = TREE_INT_CST_HIGH (arg2);
01318
01319 switch (code)
01320 {
01321 case BIT_IOR_EXPR:
01322 low = int1l | int2l, hi = int1h | int2h;
01323 break;
01324
01325 case BIT_XOR_EXPR:
01326 low = int1l ^ int2l, hi = int1h ^ int2h;
01327 break;
01328
01329 case BIT_AND_EXPR:
01330 low = int1l & int2l, hi = int1h & int2h;
01331 break;
01332
01333 case RSHIFT_EXPR:
01334 int2l = -int2l;
01335 case LSHIFT_EXPR:
01336
01337
01338
01339 lshift_double (int1l, int1h, int2l, TYPE_PRECISION (type),
01340 &low, &hi, !uns);
01341 no_overflow = 1;
01342 break;
01343
01344 case RROTATE_EXPR:
01345 int2l = - int2l;
01346 case LROTATE_EXPR:
01347 lrotate_double (int1l, int1h, int2l, TYPE_PRECISION (type),
01348 &low, &hi);
01349 break;
01350
01351 case PLUS_EXPR:
01352 overflow = add_double (int1l, int1h, int2l, int2h, &low, &hi);
01353 break;
01354
01355 case MINUS_EXPR:
01356 neg_double (int2l, int2h, &low, &hi);
01357 add_double (int1l, int1h, low, hi, &low, &hi);
01358 overflow = OVERFLOW_SUM_SIGN (hi, int2h, int1h);
01359 break;
01360
01361 case MULT_EXPR:
01362 overflow = mul_double (int1l, int1h, int2l, int2h, &low, &hi);
01363 break;
01364
01365 case TRUNC_DIV_EXPR:
01366 case FLOOR_DIV_EXPR: case CEIL_DIV_EXPR:
01367 case EXACT_DIV_EXPR:
01368
01369 if (int2h == 0 && (HOST_WIDE_INT) int2l > 0
01370 && ! TREE_CONSTANT_OVERFLOW (arg1)
01371 && ! TREE_CONSTANT_OVERFLOW (arg2)
01372 && int1h == 0 && (HOST_WIDE_INT) int1l >= 0)
01373 {
01374 if (code == CEIL_DIV_EXPR)
01375 int1l += int2l - 1;
01376
01377 low = int1l / int2l, hi = 0;
01378 break;
01379 }
01380
01381
01382
01383 case ROUND_DIV_EXPR:
01384 if (int2h == 0 && int2l == 1)
01385 {
01386 low = int1l, hi = int1h;
01387 break;
01388 }
01389 if (int1l == int2l && int1h == int2h
01390 && ! (int1l == 0 && int1h == 0))
01391 {
01392 low = 1, hi = 0;
01393 break;
01394 }
01395 overflow = div_and_round_double (code, uns, int1l, int1h, int2l, int2h,
01396 &low, &hi, &garbagel, &garbageh);
01397 break;
01398
01399 case TRUNC_MOD_EXPR:
01400 case FLOOR_MOD_EXPR: case CEIL_MOD_EXPR:
01401
01402 if (int2h == 0 && (HOST_WIDE_INT) int2l > 0
01403 && ! TREE_CONSTANT_OVERFLOW (arg1)
01404 && ! TREE_CONSTANT_OVERFLOW (arg2)
01405 && int1h == 0 && (HOST_WIDE_INT) int1l >= 0)
01406 {
01407 if (code == CEIL_MOD_EXPR)
01408 int1l += int2l - 1;
01409 low = int1l % int2l, hi = 0;
01410 break;
01411 }
01412
01413
01414
01415 case ROUND_MOD_EXPR:
01416 overflow = div_and_round_double (code, uns,
01417 int1l, int1h, int2l, int2h,
01418 &garbagel, &garbageh, &low, &hi);
01419 break;
01420
01421 case MIN_EXPR:
01422 case MAX_EXPR:
01423 if (uns)
01424 low = (((unsigned HOST_WIDE_INT) int1h
01425 < (unsigned HOST_WIDE_INT) int2h)
01426 || (((unsigned HOST_WIDE_INT) int1h
01427 == (unsigned HOST_WIDE_INT) int2h)
01428 && int1l < int2l));
01429 else
01430 low = (int1h < int2h
01431 || (int1h == int2h && int1l < int2l));
01432
01433 if (low == (code == MIN_EXPR))
01434 low = int1l, hi = int1h;
01435 else
01436 low = int2l, hi = int2h;
01437 break;
01438
01439 default:
01440 gcc_unreachable ();
01441 }
01442
01443 t = build_int_cst_wide (TREE_TYPE (arg1), low, hi);
01444
01445 if (notrunc)
01446 {
01447
01448 if (((!uns || is_sizetype) && overflow)
01449 | TREE_OVERFLOW (arg1) | TREE_OVERFLOW (arg2))
01450 {
01451 t = copy_node (t);
01452 TREE_OVERFLOW (t) = 1;
01453 TREE_CONSTANT_OVERFLOW (t) = 1;
01454 }
01455 else if (TREE_CONSTANT_OVERFLOW (arg1) | TREE_CONSTANT_OVERFLOW (arg2))
01456 {
01457 t = copy_node (t);
01458 TREE_CONSTANT_OVERFLOW (t) = 1;
01459 }
01460 }
01461 else
01462 t = force_fit_type (t, 1,
01463 ((!uns || is_sizetype) && overflow)
01464 | TREE_OVERFLOW (arg1) | TREE_OVERFLOW (arg2),
01465 TREE_CONSTANT_OVERFLOW (arg1)
01466 | TREE_CONSTANT_OVERFLOW (arg2));
01467
01468 return t;
01469 }
01470
01471
01472
01473
01474
01475
01476
01477 static tree
01478 const_binop (enum tree_code code, tree arg1, tree arg2, int notrunc)
01479 {
01480 STRIP_NOPS (arg1);
01481 STRIP_NOPS (arg2);
01482
01483 if (TREE_CODE (arg1) == INTEGER_CST)
01484 return int_const_binop (code, arg1, arg2, notrunc);
01485
01486 if (TREE_CODE (arg1) == REAL_CST)
01487 {
01488 enum machine_mode mode;
01489 REAL_VALUE_TYPE d1;
01490 REAL_VALUE_TYPE d2;
01491 REAL_VALUE_TYPE value;
01492 REAL_VALUE_TYPE result;
01493 bool inexact;
01494 tree t, type;
01495
01496 d1 = TREE_REAL_CST (arg1);
01497 d2 = TREE_REAL_CST (arg2);
01498
01499 type = TREE_TYPE (arg1);
01500 mode = TYPE_MODE (type);
01501
01502
01503
01504 if (HONOR_SNANS (mode)
01505 && (REAL_VALUE_ISNAN (d1) || REAL_VALUE_ISNAN (d2)))
01506 return NULL_TREE;
01507
01508
01509
01510 if (code == RDIV_EXPR
01511 && REAL_VALUES_EQUAL (d2, dconst0)
01512 && (flag_trapping_math || ! MODE_HAS_INFINITIES (mode)))
01513 return NULL_TREE;
01514
01515
01516
01517 if (REAL_VALUE_ISNAN (d1))
01518 return arg1;
01519 else if (REAL_VALUE_ISNAN (d2))
01520 return arg2;
01521
01522 inexact = real_arithmetic (&value, code, &d1, &d2);
01523 real_convert (&result, mode, &value);
01524
01525
01526
01527
01528
01529
01530 if ((flag_rounding_math
01531 || (REAL_MODE_FORMAT_COMPOSITE_P (mode)
01532 && !flag_unsafe_math_optimizations))
01533 && (inexact || !real_identical (&result, &value)))
01534 return NULL_TREE;
01535
01536 t = build_real (type, result);
01537
01538 TREE_OVERFLOW (t) = TREE_OVERFLOW (arg1) | TREE_OVERFLOW (arg2);
01539 TREE_CONSTANT_OVERFLOW (t)
01540 = TREE_OVERFLOW (t)
01541 | TREE_CONSTANT_OVERFLOW (arg1)
01542 | TREE_CONSTANT_OVERFLOW (arg2);
01543 return t;
01544 }
01545 if (TREE_CODE (arg1) == COMPLEX_CST)
01546 {
01547 tree type = TREE_TYPE (arg1);
01548 tree r1 = TREE_REALPART (arg1);
01549 tree i1 = TREE_IMAGPART (arg1);
01550 tree r2 = TREE_REALPART (arg2);
01551 tree i2 = TREE_IMAGPART (arg2);
01552 tree t;
01553
01554 switch (code)
01555 {
01556 case PLUS_EXPR:
01557 t = build_complex (type,
01558 const_binop (PLUS_EXPR, r1, r2, notrunc),
01559 const_binop (PLUS_EXPR, i1, i2, notrunc));
01560 break;
01561
01562 case MINUS_EXPR:
01563 t = build_complex (type,
01564 const_binop (MINUS_EXPR, r1, r2, notrunc),
01565 const_binop (MINUS_EXPR, i1, i2, notrunc));
01566 break;
01567
01568 case MULT_EXPR:
01569 t = build_complex (type,
01570 const_binop (MINUS_EXPR,
01571 const_binop (MULT_EXPR,
01572 r1, r2, notrunc),
01573 const_binop (MULT_EXPR,
01574 i1, i2, notrunc),
01575 notrunc),
01576 const_binop (PLUS_EXPR,
01577 const_binop (MULT_EXPR,
01578 r1, i2, notrunc),
01579 const_binop (MULT_EXPR,
01580 i1, r2, notrunc),
01581 notrunc));
01582 break;
01583
01584 case RDIV_EXPR:
01585 {
01586 tree magsquared
01587 = const_binop (PLUS_EXPR,
01588 const_binop (MULT_EXPR, r2, r2, notrunc),
01589 const_binop (MULT_EXPR, i2, i2, notrunc),
01590 notrunc);
01591
01592 t = build_complex (type,
01593 const_binop
01594 (INTEGRAL_TYPE_P (TREE_TYPE (r1))
01595 ? TRUNC_DIV_EXPR : RDIV_EXPR,
01596 const_binop (PLUS_EXPR,
01597 const_binop (MULT_EXPR, r1, r2,
01598 notrunc),
01599 const_binop (MULT_EXPR, i1, i2,
01600 notrunc),
01601 notrunc),
01602 magsquared, notrunc),
01603 const_binop
01604 (INTEGRAL_TYPE_P (TREE_TYPE (r1))
01605 ? TRUNC_DIV_EXPR : RDIV_EXPR,
01606 const_binop (MINUS_EXPR,
01607 const_binop (MULT_EXPR, i1, r2,
01608 notrunc),
01609 const_binop (MULT_EXPR, r1, i2,
01610 notrunc),
01611 notrunc),
01612 magsquared, notrunc));
01613 }
01614 break;
01615
01616 default:
01617 gcc_unreachable ();
01618 }
01619 return t;
01620 }
01621 return 0;
01622 }
01623
01624
01625
01626
01627 tree
01628 size_int_kind (HOST_WIDE_INT number, enum size_type_kind kind)
01629 {
01630 return build_int_cst (sizetype_tab[(int) kind], number);
01631 }
01632
01633
01634
01635
01636
01637
01638 tree
01639 size_binop (enum tree_code code, tree arg0, tree arg1)
01640 {
01641 tree type = TREE_TYPE (arg0);
01642
01643 gcc_assert (TREE_CODE (type) == INTEGER_TYPE && TYPE_IS_SIZETYPE (type)
01644 && type == TREE_TYPE (arg1));
01645
01646
01647 if (TREE_CODE (arg0) == INTEGER_CST && TREE_CODE (arg1) == INTEGER_CST)
01648 {
01649
01650 if (code == PLUS_EXPR && integer_zerop (arg0))
01651 return arg1;
01652 else if ((code == MINUS_EXPR || code == PLUS_EXPR)
01653 && integer_zerop (arg1))
01654 return arg0;
01655 else if (code == MULT_EXPR && integer_onep (arg0))
01656 return arg1;
01657
01658
01659 return int_const_binop (code, arg0, arg1, 0);
01660 }
01661
01662 if (arg0 == error_mark_node || arg1 == error_mark_node)
01663 return error_mark_node;
01664
01665 return fold (build2 (code, type, arg0, arg1));
01666 }
01667
01668
01669
01670
01671
01672 tree
01673 size_diffop (tree arg0, tree arg1)
01674 {
01675 tree type = TREE_TYPE (arg0);
01676 tree ctype;
01677
01678 gcc_assert (TREE_CODE (type) == INTEGER_TYPE && TYPE_IS_SIZETYPE (type)
01679 && type == TREE_TYPE (arg1));
01680
01681
01682 if (!TYPE_UNSIGNED (type))
01683 return size_binop (MINUS_EXPR, arg0, arg1);
01684
01685 ctype = type == bitsizetype ? sbitsizetype : ssizetype;
01686
01687
01688
01689
01690 if (TREE_CODE (arg0) != INTEGER_CST || TREE_CODE (arg1) != INTEGER_CST)
01691 return size_binop (MINUS_EXPR, fold_convert (ctype, arg0),
01692 fold_convert (ctype, arg1));
01693
01694
01695
01696
01697
01698 if (tree_int_cst_equal (arg0, arg1))
01699 return fold_convert (ctype, integer_zero_node);
01700 else if (tree_int_cst_lt (arg1, arg0))
01701 return fold_convert (ctype, size_binop (MINUS_EXPR, arg0, arg1));
01702 else
01703 return size_binop (MINUS_EXPR, fold_convert (ctype, integer_zero_node),
01704 fold_convert (ctype, size_binop (MINUS_EXPR,
01705 arg1, arg0)));
01706 }
01707
01708
01709
01710
01711 static tree
01712 fold_convert_const_int_from_int (tree type, tree arg1)
01713 {
01714 tree t;
01715
01716
01717
01718 t = build_int_cst_wide (type, TREE_INT_CST_LOW (arg1),
01719 TREE_INT_CST_HIGH (arg1));
01720
01721 t = force_fit_type (t,
01722
01723
01724 !POINTER_TYPE_P (TREE_TYPE (arg1)),
01725 (TREE_INT_CST_HIGH (arg1) < 0
01726 && (TYPE_UNSIGNED (type)
01727 < TYPE_UNSIGNED (TREE_TYPE (arg1))))
01728 | TREE_OVERFLOW (arg1),
01729 TREE_CONSTANT_OVERFLOW (arg1));
01730
01731 return t;
01732 }
01733
01734
01735
01736
01737 static tree
01738 fold_convert_const_int_from_real (enum tree_code code, tree type, tree arg1)
01739 {
01740 int overflow = 0;
01741 tree t;
01742
01743
01744
01745
01746
01747
01748
01749
01750
01751
01752 HOST_WIDE_INT high, low;
01753 REAL_VALUE_TYPE r;
01754 REAL_VALUE_TYPE x = TREE_REAL_CST (arg1);
01755
01756 switch (code)
01757 {
01758 case FIX_TRUNC_EXPR:
01759 real_trunc (&r, VOIDmode, &x);
01760 break;
01761
01762 case FIX_CEIL_EXPR:
01763 real_ceil (&r, VOIDmode, &x);
01764 break;
01765
01766 case FIX_FLOOR_EXPR:
01767 real_floor (&r, VOIDmode, &x);
01768 break;
01769
01770 case FIX_ROUND_EXPR:
01771 real_round (&r, VOIDmode, &x);
01772 break;
01773
01774 default:
01775 gcc_unreachable ();
01776 }
01777
01778
01779 if (REAL_VALUE_ISNAN (r))
01780 {
01781 overflow = 1;
01782 high = 0;
01783 low = 0;
01784 }
01785
01786
01787
01788
01789 if (! overflow)
01790 {
01791 tree lt = TYPE_MIN_VALUE (type);
01792 REAL_VALUE_TYPE l = real_value_from_int_cst (NULL_TREE, lt);
01793 if (REAL_VALUES_LESS (r, l))
01794 {
01795 overflow = 1;
01796 high = TREE_INT_CST_HIGH (lt);
01797 low = TREE_INT_CST_LOW (lt);
01798 }
01799 }
01800
01801 if (! overflow)
01802 {
01803 tree ut = TYPE_MAX_VALUE (type);
01804 if (ut)
01805 {
01806 REAL_VALUE_TYPE u = real_value_from_int_cst (NULL_TREE, ut);
01807 if (REAL_VALUES_LESS (u, r))
01808 {
01809 overflow = 1;
01810 high = TREE_INT_CST_HIGH (ut);
01811 low = TREE_INT_CST_LOW (ut);
01812 }
01813 }
01814 }
01815
01816 if (! overflow)
01817 REAL_VALUE_TO_INT (&low, &high, r);
01818
01819 t = build_int_cst_wide (type, low, high);
01820
01821 t = force_fit_type (t, -1, overflow | TREE_OVERFLOW (arg1),
01822 TREE_CONSTANT_OVERFLOW (arg1));
01823 return t;
01824 }
01825
01826
01827
01828
01829 static tree
01830 fold_convert_const_real_from_real (tree type, tree arg1)
01831 {
01832 REAL_VALUE_TYPE value;
01833 tree t;
01834
01835 real_convert (&value, TYPE_MODE (type), &TREE_REAL_CST (arg1));
01836 t = build_real (type, value);
01837
01838 TREE_OVERFLOW (t) = TREE_OVERFLOW (arg1);
01839 TREE_CONSTANT_OVERFLOW (t)
01840 = TREE_OVERFLOW (t) | TREE_CONSTANT_OVERFLOW (arg1);
01841 return t;
01842 }
01843
01844
01845
01846
01847 static tree
01848 fold_convert_const (enum tree_code code, tree type, tree arg1)
01849 {
01850 if (TREE_TYPE (arg1) == type)
01851 return arg1;
01852
01853 if (POINTER_TYPE_P (type) || INTEGRAL_TYPE_P (type))
01854 {
01855 if (TREE_CODE (arg1) == INTEGER_CST)
01856 return fold_convert_const_int_from_int (type, arg1);
01857 else if (TREE_CODE (arg1) == REAL_CST)
01858 return fold_convert_const_int_from_real (code, type, arg1);
01859 }
01860 else if (TREE_CODE (type) == REAL_TYPE)
01861 {
01862 if (TREE_CODE (arg1) == INTEGER_CST)
01863 return build_real_from_int_cst (type, arg1);
01864 if (TREE_CODE (arg1) == REAL_CST)
01865 return fold_convert_const_real_from_real (type, arg1);
01866 }
01867 return NULL_TREE;
01868 }
01869
01870
01871
01872 static tree
01873 build_zero_vector (tree type)
01874 {
01875 tree elem, list;
01876 int i, units;
01877
01878 elem = fold_convert_const (NOP_EXPR, TREE_TYPE (type), integer_zero_node);
01879 units = TYPE_VECTOR_SUBPARTS (type);
01880
01881 list = NULL_TREE;
01882 for (i = 0; i < units; i++)
01883 list = tree_cons (NULL_TREE, elem, list);
01884 return build_vector (type, list);
01885 }
01886
01887
01888
01889
01890 tree
01891 fold_convert (tree type, tree arg)
01892 {
01893 tree orig = TREE_TYPE (arg);
01894 tree tem;
01895
01896 if (type == orig)
01897 return arg;
01898
01899 if (TREE_CODE (arg) == ERROR_MARK
01900 || TREE_CODE (type) == ERROR_MARK
01901 || TREE_CODE (orig) == ERROR_MARK)
01902 return error_mark_node;
01903
01904 if (TYPE_MAIN_VARIANT (type) == TYPE_MAIN_VARIANT (orig)
01905 || lang_hooks.types_compatible_p (TYPE_MAIN_VARIANT (type),
01906 TYPE_MAIN_VARIANT (orig)))
01907 return fold (build1 (NOP_EXPR, type, arg));
01908
01909 switch (TREE_CODE (type))
01910 {
01911 case INTEGER_TYPE: case CHAR_TYPE: case ENUMERAL_TYPE: case BOOLEAN_TYPE:
01912 case POINTER_TYPE: case REFERENCE_TYPE:
01913 case OFFSET_TYPE:
01914 if (TREE_CODE (arg) == INTEGER_CST)
01915 {
01916 tem = fold_convert_const (NOP_EXPR, type, arg);
01917 if (tem != NULL_TREE)
01918 return tem;
01919 }
01920 if (INTEGRAL_TYPE_P (orig) || POINTER_TYPE_P (orig)
01921 || TREE_CODE (orig) == OFFSET_TYPE)
01922 return fold (build1 (NOP_EXPR, type, arg));
01923 if (TREE_CODE (orig) == COMPLEX_TYPE)
01924 {
01925 tem = fold (build1 (REALPART_EXPR, TREE_TYPE (orig), arg));
01926 return fold_convert (type, tem);
01927 }
01928 gcc_assert (TREE_CODE (orig) == VECTOR_TYPE
01929 && tree_int_cst_equal (TYPE_SIZE (type), TYPE_SIZE (orig)));
01930 return fold (build1 (NOP_EXPR, type, arg));
01931
01932 case REAL_TYPE:
01933 if (TREE_CODE (arg) == INTEGER_CST)
01934 {
01935 tem = fold_convert_const (FLOAT_EXPR, type, arg);
01936 if (tem != NULL_TREE)
01937 return tem;
01938 }
01939 else if (TREE_CODE (arg) == REAL_CST)
01940 {
01941 tem = fold_convert_const (NOP_EXPR, type, arg);
01942 if (tem != NULL_TREE)
01943 return tem;
01944 }
01945
01946 switch (TREE_CODE (orig))
01947 {
01948 case INTEGER_TYPE: case CHAR_TYPE:
01949 case BOOLEAN_TYPE: case ENUMERAL_TYPE:
01950 case POINTER_TYPE: case REFERENCE_TYPE:
01951 return fold (build1 (FLOAT_EXPR, type, arg));
01952
01953 case REAL_TYPE:
01954 return fold (build1 (flag_float_store ? CONVERT_EXPR : NOP_EXPR,
01955 type, arg));
01956
01957 case COMPLEX_TYPE:
01958 tem = fold (build1 (REALPART_EXPR, TREE_TYPE (orig), arg));
01959 return fold_convert (type, tem);
01960
01961 default:
01962 gcc_unreachable ();
01963 }
01964
01965 case COMPLEX_TYPE:
01966 switch (TREE_CODE (orig))
01967 {
01968 case INTEGER_TYPE: case CHAR_TYPE:
01969 case BOOLEAN_TYPE: case ENUMERAL_TYPE:
01970 case POINTER_TYPE: case REFERENCE_TYPE:
01971 case REAL_TYPE:
01972 return build2 (COMPLEX_EXPR, type,
01973 fold_convert (TREE_TYPE (type), arg),
01974 fold_convert (TREE_TYPE (type), integer_zero_node));
01975 case COMPLEX_TYPE:
01976 {
01977 tree rpart, ipart;
01978
01979 if (TREE_CODE (arg) == COMPLEX_EXPR)
01980 {
01981 rpart = fold_convert (TREE_TYPE (type), TREE_OPERAND (arg, 0));
01982 ipart = fold_convert (TREE_TYPE (type), TREE_OPERAND (arg, 1));
01983 return fold (build2 (COMPLEX_EXPR, type, rpart, ipart));
01984 }
01985
01986 arg = save_expr (arg);
01987 rpart = fold (build1 (REALPART_EXPR, TREE_TYPE (orig), arg));
01988 ipart = fold (build1 (IMAGPART_EXPR, TREE_TYPE (orig), arg));
01989 rpart = fold_convert (TREE_TYPE (type), rpart);
01990 ipart = fold_convert (TREE_TYPE (type), ipart);
01991 return fold (build2 (COMPLEX_EXPR, type, rpart, ipart));
01992 }
01993
01994 default:
01995 gcc_unreachable ();
01996 }
01997
01998 case VECTOR_TYPE:
01999 if (integer_zerop (arg))
02000 return build_zero_vector (type);
02001 gcc_assert (tree_int_cst_equal (TYPE_SIZE (type), TYPE_SIZE (orig)));
02002 gcc_assert (INTEGRAL_TYPE_P (orig) || POINTER_TYPE_P (orig)
02003 || TREE_CODE (orig) == VECTOR_TYPE);
02004 return fold (build1 (VIEW_CONVERT_EXPR, type, arg));
02005
02006 case VOID_TYPE:
02007 return fold (build1 (CONVERT_EXPR, type, fold_ignored_result (arg)));
02008
02009 default:
02010 gcc_unreachable ();
02011 }
02012 }
02013
02014
02015
02016
02017 static bool
02018 maybe_lvalue_p (tree x)
02019 {
02020
02021 switch (TREE_CODE (x))
02022 {
02023 case VAR_DECL:
02024 case PARM_DECL:
02025 case RESULT_DECL:
02026 case LABEL_DECL:
02027 case FUNCTION_DECL:
02028 case SSA_NAME:
02029
02030 case COMPONENT_REF:
02031 case INDIRECT_REF:
02032 case ALIGN_INDIRECT_REF:
02033 case MISALIGNED_INDIRECT_REF:
02034 case ARRAY_REF:
02035 case ARRAY_RANGE_REF:
02036 case BIT_FIELD_REF:
02037 case OBJ_TYPE_REF:
02038
02039 case REALPART_EXPR:
02040 case IMAGPART_EXPR:
02041 case PREINCREMENT_EXPR:
02042 case PREDECREMENT_EXPR:
02043 case SAVE_EXPR:
02044 case TRY_CATCH_EXPR:
02045 case WITH_CLEANUP_EXPR:
02046 case COMPOUND_EXPR:
02047 case MODIFY_EXPR:
02048 case TARGET_EXPR:
02049 case COND_EXPR:
02050 case BIND_EXPR:
02051 case MIN_EXPR:
02052 case MAX_EXPR:
02053 break;
02054
02055 default:
02056
02057 if ((int)TREE_CODE (x) >= NUM_TREE_CODES)
02058 break;
02059 return false;
02060 }
02061
02062 return true;
02063 }
02064
02065
02066
02067 tree
02068 non_lvalue (tree x)
02069 {
02070
02071
02072 if (in_gimple_form)
02073 return x;
02074
02075 if (! maybe_lvalue_p (x))
02076 return x;
02077 return build1 (NON_LVALUE_EXPR, TREE_TYPE (x), x);
02078 }
02079
02080
02081
02082
02083 int pedantic_lvalues;
02084
02085
02086
02087
02088 static tree
02089 pedantic_non_lvalue (tree x)
02090 {
02091 if (pedantic_lvalues)
02092 return non_lvalue (x);
02093 else
02094 return x;
02095 }
02096
02097
02098
02099
02100
02101
02102 static enum tree_code
02103 invert_tree_comparison (enum tree_code code, bool honor_nans)
02104 {
02105 if (honor_nans && flag_trapping_math)
02106 return ERROR_MARK;
02107
02108 switch (code)
02109 {
02110 case EQ_EXPR:
02111 return NE_EXPR;
02112 case NE_EXPR:
02113 return EQ_EXPR;
02114 case GT_EXPR:
02115 return honor_nans ? UNLE_EXPR : LE_EXPR;
02116 case GE_EXPR:
02117 return honor_nans ? UNLT_EXPR : LT_EXPR;
02118 case LT_EXPR:
02119 return honor_nans ? UNGE_EXPR : GE_EXPR;
02120 case LE_EXPR:
02121 return honor_nans ? UNGT_EXPR : GT_EXPR;
02122 case LTGT_EXPR:
02123 return UNEQ_EXPR;
02124 case UNEQ_EXPR:
02125 return LTGT_EXPR;
02126 case UNGT_EXPR:
02127 return LE_EXPR;
02128 case UNGE_EXPR:
02129 return LT_EXPR;
02130 case UNLT_EXPR:
02131 return GE_EXPR;
02132 case UNLE_EXPR:
02133 return GT_EXPR;
02134 case ORDERED_EXPR:
02135 return UNORDERED_EXPR;
02136 case UNORDERED_EXPR:
02137 return ORDERED_EXPR;
02138 default:
02139 gcc_unreachable ();
02140 }
02141 }
02142
02143
02144
02145
02146 enum tree_code
02147 swap_tree_comparison (enum tree_code code)
02148 {
02149 switch (code)
02150 {
02151 case EQ_EXPR:
02152 case NE_EXPR:
02153 return code;
02154 case GT_EXPR:
02155 return LT_EXPR;
02156 case GE_EXPR:
02157 return LE_EXPR;
02158 case LT_EXPR:
02159 return GT_EXPR;
02160 case LE_EXPR:
02161 return GE_EXPR;
02162 default:
02163 gcc_unreachable ();
02164 }
02165 }
02166
02167
02168
02169
02170
02171
02172 static enum comparison_code
02173 comparison_to_compcode (enum tree_code code)
02174 {
02175 switch (code)
02176 {
02177 case LT_EXPR:
02178 return COMPCODE_LT;
02179 case EQ_EXPR:
02180 return COMPCODE_EQ;
02181 case LE_EXPR:
02182 return COMPCODE_LE;
02183 case GT_EXPR:
02184 return COMPCODE_GT;
02185 case NE_EXPR:
02186 return COMPCODE_NE;
02187 case GE_EXPR:
02188 return COMPCODE_GE;
02189 case ORDERED_EXPR:
02190 return COMPCODE_ORD;
02191 case UNORDERED_EXPR:
02192 return COMPCODE_UNORD;
02193 case UNLT_EXPR:
02194 return COMPCODE_UNLT;
02195 case UNEQ_EXPR:
02196 return COMPCODE_UNEQ;
02197 case UNLE_EXPR:
02198 return COMPCODE_UNLE;
02199 case UNGT_EXPR:
02200 return COMPCODE_UNGT;
02201 case LTGT_EXPR:
02202 return COMPCODE_LTGT;
02203 case UNGE_EXPR:
02204 return COMPCODE_UNGE;
02205 default:
02206 gcc_unreachable ();
02207 }
02208 }
02209
02210
02211
02212
02213
02214 static enum tree_code
02215 compcode_to_comparison (enum comparison_code code)
02216 {
02217 switch (code)
02218 {
02219 case COMPCODE_LT:
02220 return LT_EXPR;
02221 case COMPCODE_EQ:
02222 return EQ_EXPR;
02223 case COMPCODE_LE:
02224 return LE_EXPR;
02225 case COMPCODE_GT:
02226 return GT_EXPR;
02227 case COMPCODE_NE:
02228 return NE_EXPR;
02229 case COMPCODE_GE:
02230 return GE_EXPR;
02231 case COMPCODE_ORD:
02232 return ORDERED_EXPR;
02233 case COMPCODE_UNORD:
02234 return UNORDERED_EXPR;
02235 case COMPCODE_UNLT:
02236 return UNLT_EXPR;
02237 case COMPCODE_UNEQ:
02238 return UNEQ_EXPR;
02239 case COMPCODE_UNLE:
02240 return UNLE_EXPR;
02241 case COMPCODE_UNGT:
02242 return UNGT_EXPR;
02243 case COMPCODE_LTGT:
02244 return LTGT_EXPR;
02245 case COMPCODE_UNGE:
02246 return UNGE_EXPR;
02247 default:
02248 gcc_unreachable ();
02249 }
02250 }
02251
02252
02253
02254
02255
02256
02257
02258 tree
02259 combine_comparisons (enum tree_code code, enum tree_code lcode,
02260 enum tree_code rcode, tree truth_type,
02261 tree ll_arg, tree lr_arg)
02262 {
02263 bool honor_nans = HONOR_NANS (TYPE_MODE (TREE_TYPE (ll_arg)));
02264 enum comparison_code lcompcode = comparison_to_compcode (lcode);
02265 enum comparison_code rcompcode = comparison_to_compcode (rcode);
02266 enum comparison_code compcode;
02267
02268 switch (code)
02269 {
02270 case TRUTH_AND_EXPR: case TRUTH_ANDIF_EXPR:
02271 compcode = lcompcode & rcompcode;
02272 break;
02273
02274 case TRUTH_OR_EXPR: case TRUTH_ORIF_EXPR:
02275 compcode = lcompcode | rcompcode;
02276 break;
02277
02278 default:
02279 return NULL_TREE;
02280 }
02281
02282 if (!honor_nans)
02283 {
02284
02285
02286 compcode &= ~COMPCODE_UNORD;
02287 if (compcode == COMPCODE_LTGT)
02288 compcode = COMPCODE_NE;
02289 else if (compcode == COMPCODE_ORD)
02290 compcode = COMPCODE_TRUE;
02291 }
02292 else if (flag_trapping_math)
02293 {
02294
02295
02296 bool ltrap = (lcompcode & COMPCODE_UNORD) == 0
02297 && (lcompcode != COMPCODE_EQ)
02298 && (lcompcode != COMPCODE_ORD);
02299 bool rtrap = (rcompcode & COMPCODE_UNORD) == 0
02300 && (rcompcode != COMPCODE_EQ)
02301 && (rcompcode != COMPCODE_ORD);
02302 bool trap = (compcode & COMPCODE_UNORD) == 0
02303 && (compcode != COMPCODE_EQ)
02304 && (compcode != COMPCODE_ORD);
02305
02306
02307
02308
02309
02310
02311
02312 if ((code == TRUTH_ORIF_EXPR && (lcompcode & COMPCODE_UNORD))
02313 || (code == TRUTH_ANDIF_EXPR && !(lcompcode & COMPCODE_UNORD)))
02314 rtrap = false;
02315
02316
02317
02318 if (rtrap && !ltrap
02319 && (code == TRUTH_ANDIF_EXPR || code == TRUTH_ORIF_EXPR))
02320 return NULL_TREE;
02321
02322
02323 if ((ltrap || rtrap) != trap)
02324 return NULL_TREE;
02325 }
02326
02327 if (compcode == COMPCODE_TRUE)
02328 return constant_boolean_node (true, truth_type);
02329 else if (compcode == COMPCODE_FALSE)
02330 return constant_boolean_node (false, truth_type);
02331 else
02332 return fold (build2 (compcode_to_comparison (compcode),
02333 truth_type, ll_arg, lr_arg));
02334 }
02335
02336
02337
02338 static int
02339 truth_value_p (enum tree_code code)
02340 {
02341 return (TREE_CODE_CLASS (code) == tcc_comparison
02342 || code == TRUTH_AND_EXPR || code == TRUTH_ANDIF_EXPR
02343 || code == TRUTH_OR_EXPR || code == TRUTH_ORIF_EXPR
02344 || code == TRUTH_XOR_EXPR || code == TRUTH_NOT_EXPR);
02345 }
02346
02347
02348
02349
02350
02351
02352
02353
02354
02355
02356
02357
02358
02359
02360
02361
02362
02363
02364
02365
02366
02367
02368
02369
02370
02371
02372
02373 int
02374 operand_equal_p (tree arg0, tree arg1, unsigned int flags)
02375 {
02376
02377 if (TREE_CODE (arg0) == ERROR_MARK || TREE_CODE (arg1) == ERROR_MARK)
02378 return 0;
02379
02380
02381
02382
02383 if (TYPE_UNSIGNED (TREE_TYPE (arg0)) != TYPE_UNSIGNED (TREE_TYPE (arg1)))
02384 return 0;
02385
02386 STRIP_NOPS (arg0);
02387 STRIP_NOPS (arg1);
02388
02389 if (TREE_CODE (arg0) != TREE_CODE (arg1)
02390
02391
02392 || TREE_CODE (TREE_TYPE (arg0)) == ERROR_MARK
02393 || TREE_CODE (TREE_TYPE (arg1)) == ERROR_MARK
02394 || TYPE_MODE (TREE_TYPE (arg0)) != TYPE_MODE (TREE_TYPE (arg1)))
02395 return 0;
02396
02397
02398
02399
02400
02401
02402
02403
02404 if (arg0 == arg1 && ! (flags & OEP_ONLY_CONST)
02405 && (TREE_CODE (arg0) == SAVE_EXPR
02406 || (! TREE_SIDE_EFFECTS (arg0) && ! TREE_SIDE_EFFECTS (arg1))))
02407 return 1;
02408
02409
02410
02411 if (TREE_CONSTANT (arg0) && TREE_CONSTANT (arg1))
02412 switch (TREE_CODE (arg0))
02413 {
02414 case INTEGER_CST:
02415 return (! TREE_CONSTANT_OVERFLOW (arg0)
02416 && ! TREE_CONSTANT_OVERFLOW (arg1)
02417 && tree_int_cst_equal (arg0, arg1));
02418
02419 case REAL_CST:
02420 return (! TREE_CONSTANT_OVERFLOW (arg0)
02421 && ! TREE_CONSTANT_OVERFLOW (arg1)
02422 && REAL_VALUES_IDENTICAL (TREE_REAL_CST (arg0),
02423 TREE_REAL_CST (arg1)));
02424
02425 case VECTOR_CST:
02426 {
02427 tree v1, v2;
02428
02429 if (TREE_CONSTANT_OVERFLOW (arg0)
02430 || TREE_CONSTANT_OVERFLOW (arg1))
02431 return 0;
02432
02433 v1 = TREE_VECTOR_CST_ELTS (arg0);
02434 v2 = TREE_VECTOR_CST_ELTS (arg1);
02435 while (v1 && v2)
02436 {
02437 if (!operand_equal_p (TREE_VALUE (v1), TREE_VALUE (v2),
02438 flags))
02439 return 0;
02440 v1 = TREE_CHAIN (v1);
02441 v2 = TREE_CHAIN (v2);
02442 }
02443
02444 return 1;
02445 }
02446
02447 case COMPLEX_CST:
02448 return (operand_equal_p (TREE_REALPART (arg0), TREE_REALPART (arg1),
02449 flags)
02450 && operand_equal_p (TREE_IMAGPART (arg0), TREE_IMAGPART (arg1),
02451 flags));
02452
02453 case STRING_CST:
02454 return (TREE_STRING_LENGTH (arg0) == TREE_STRING_LENGTH (arg1)
02455 && ! memcmp (TREE_STRING_POINTER (arg0),
02456 TREE_STRING_POINTER (arg1),
02457 TREE_STRING_LENGTH (arg0)));
02458
02459 case ADDR_EXPR:
02460 return operand_equal_p (TREE_OPERAND (arg0, 0), TREE_OPERAND (arg1, 0),
02461 0);
02462 default:
02463 break;
02464 }
02465
02466 if (flags & OEP_ONLY_CONST)
02467 return 0;
02468
02469
02470
02471
02472
02473 #define OP_SAME(N) operand_equal_p (TREE_OPERAND (arg0, N), \
02474 TREE_OPERAND (arg1, N), flags)
02475
02476 #define OP_SAME_WITH_NULL(N) \
02477 ((!TREE_OPERAND (arg0, N) || !TREE_OPERAND (arg1, N)) \
02478 ? TREE_OPERAND (arg0, N) == TREE_OPERAND (arg1, N) : OP_SAME (N))
02479
02480 switch (TREE_CODE_CLASS (TREE_CODE (arg0)))
02481 {
02482 case tcc_unary:
02483
02484 switch (TREE_CODE (arg0))
02485 {
02486 case NOP_EXPR:
02487 case CONVERT_EXPR:
02488 case FIX_CEIL_EXPR:
02489 case FIX_TRUNC_EXPR:
02490 case FIX_FLOOR_EXPR:
02491 case FIX_ROUND_EXPR:
02492 if (TYPE_UNSIGNED (TREE_TYPE (arg0))
02493 != TYPE_UNSIGNED (TREE_TYPE (arg1)))
02494 return 0;
02495 break;
02496 default:
02497 break;
02498 }
02499
02500 return OP_SAME (0);
02501
02502
02503 case tcc_comparison:
02504 case tcc_binary:
02505 if (OP_SAME (0) && OP_SAME (1))
02506 return 1;
02507
02508
02509 return (commutative_tree_code (TREE_CODE (arg0))
02510 && operand_equal_p (TREE_OPERAND (arg0, 0),
02511 TREE_OPERAND (arg1, 1), flags)
02512 && operand_equal_p (TREE_OPERAND (arg0, 1),
02513 TREE_OPERAND (arg1, 0), flags));
02514
02515 case tcc_reference:
02516
02517
02518 if (TREE_SIDE_EFFECTS (arg0)
02519 || TREE_SIDE_EFFECTS (arg1))
02520 return 0;
02521
02522 switch (TREE_CODE (arg0))
02523 {
02524 case INDIRECT_REF:
02525 case ALIGN_INDIRECT_REF:
02526 case MISALIGNED_INDIRECT_REF:
02527 case REALPART_EXPR:
02528 case IMAGPART_EXPR:
02529 return OP_SAME (0);
02530
02531 case ARRAY_REF:
02532 case ARRAY_RANGE_REF:
02533
02534 return (OP_SAME (0)
02535 && OP_SAME (1)
02536 && OP_SAME_WITH_NULL (2)
02537 && OP_SAME_WITH_NULL (3));
02538
02539 case COMPONENT_REF:
02540
02541 return OP_SAME (0) && OP_SAME (1) && OP_SAME_WITH_NULL (2);
02542
02543 case BIT_FIELD_REF:
02544 return OP_SAME (0) && OP_SAME (1) && OP_SAME (2);
02545
02546 default:
02547 return 0;
02548 }
02549
02550 case tcc_expression:
02551 switch (TREE_CODE (arg0))
02552 {
02553 case ADDR_EXPR:
02554 case TRUTH_NOT_EXPR:
02555 return OP_SAME (0);
02556
02557 case TRUTH_ANDIF_EXPR:
02558 case TRUTH_ORIF_EXPR:
02559 return OP_SAME (0) && OP_SAME (1);
02560
02561 case TRUTH_AND_EXPR:
02562 case TRUTH_OR_EXPR:
02563 case TRUTH_XOR_EXPR:
02564 if (OP_SAME (0) && OP_SAME (1))
02565 return 1;
02566
02567
02568 return (operand_equal_p (TREE_OPERAND (arg0, 0),
02569 TREE_OPERAND (arg1, 1), flags)
02570 && operand_equal_p (TREE_OPERAND (arg0, 1),
02571 TREE_OPERAND (arg1, 0), flags));
02572
02573 case CALL_EXPR:
02574
02575
02576 if (!OP_SAME (0))
02577 return 0;
02578
02579 {
02580 unsigned int cef = call_expr_flags (arg0);
02581 if (flags & OEP_PURE_SAME)
02582 cef &= ECF_CONST | ECF_PURE;
02583 else
02584 cef &= ECF_CONST;
02585 if (!cef)
02586 return 0;
02587 }
02588
02589
02590
02591
02592 arg0 = TREE_OPERAND (arg0, 1);
02593 arg1 = TREE_OPERAND (arg1, 1);
02594 while (arg0 && arg1)
02595 {
02596 if (! operand_equal_p (TREE_VALUE (arg0), TREE_VALUE (arg1),
02597 flags))
02598 return 0;
02599
02600 arg0 = TREE_CHAIN (arg0);
02601 arg1 = TREE_CHAIN (arg1);
02602 }
02603
02604
02605
02606 return ! (arg0 || arg1);
02607
02608 default:
02609 return 0;
02610 }
02611
02612 case tcc_declaration:
02613
02614 return (TREE_CODE (arg0) == FUNCTION_DECL
02615 && DECL_BUILT_IN (arg0) && DECL_BUILT_IN (arg1)
02616 && DECL_BUILT_IN_CLASS (arg0) == DECL_BUILT_IN_CLASS (arg1)
02617 && DECL_FUNCTION_CODE (arg0) == DECL_FUNCTION_CODE (arg1));
02618
02619 default:
02620 return 0;
02621 }
02622
02623 #undef OP_SAME
02624 #undef OP_SAME_WITH_NULL
02625 }
02626
02627
02628
02629
02630
02631
02632 static int
02633 operand_equal_for_comparison_p (tree arg0, tree arg1, tree other)
02634 {
02635 int unsignedp1, unsignedpo;
02636 tree primarg0, primarg1, primother;
02637 unsigned int correct_width;
02638
02639 if (operand_equal_p (arg0, arg1, 0))
02640 return 1;
02641
02642 if (! INTEGRAL_TYPE_P (TREE_TYPE (arg0))
02643 || ! INTEGRAL_TYPE_P (TREE_TYPE (arg1)))
02644 return 0;
02645
02646
02647
02648
02649 primarg0 = arg0, primarg1 = arg1;
02650 STRIP_NOPS (primarg0);
02651 STRIP_NOPS (primarg1);
02652 if (operand_equal_p (primarg0, primarg1, 0))
02653 return 1;
02654
02655
02656
02657
02658
02659
02660
02661 primarg1 = get_narrower (arg1, &unsignedp1);
02662 primother = get_narrower (other, &unsignedpo);
02663
02664 correct_width = TYPE_PRECISION (TREE_TYPE (arg1));
02665 if (unsignedp1 == unsignedpo
02666 && TYPE_PRECISION (TREE_TYPE (primarg1)) < correct_width
02667 && TYPE_PRECISION (TREE_TYPE (primother)) < correct_width)
02668 {
02669 tree type = TREE_TYPE (arg0);
02670
02671
02672
02673 primarg1 = fold_convert (lang_hooks.types.signed_or_unsigned_type
02674 (unsignedp1, TREE_TYPE (primarg1)), primarg1);
02675
02676 if (operand_equal_p (arg0, fold_convert (type, primarg1), 0))
02677 return 1;
02678 }
02679
02680 return 0;
02681 }
02682
02683
02684
02685
02686
02687
02688
02689
02690
02691
02692
02693 static int
02694 twoval_comparison_p (tree arg, tree *cval1, tree *cval2, int *save_p)
02695 {
02696 enum tree_code code = TREE_CODE (arg);
02697 enum tree_code_class class = TREE_CODE_CLASS (code);
02698
02699
02700 if (class == tcc_expression && code == TRUTH_NOT_EXPR)
02701 class = tcc_unary;
02702 else if (class == tcc_expression
02703 && (code == TRUTH_ANDIF_EXPR || code == TRUTH_ORIF_EXPR
02704 || code == COMPOUND_EXPR))
02705 class = tcc_binary;
02706
02707 else if (class == tcc_expression && code == SAVE_EXPR
02708 && ! TREE_SIDE_EFFECTS (TREE_OPERAND (arg, 0)))
02709 {
02710
02711
02712 if (*cval1 || *cval2)
02713 return 0;
02714
02715 class = tcc_unary;
02716 *save_p = 1;
02717 }
02718
02719 switch (class)
02720 {
02721 case tcc_unary:
02722 return twoval_comparison_p (TREE_OPERAND (arg, 0), cval1, cval2, save_p);
02723
02724 case tcc_binary:
02725 return (twoval_comparison_p (TREE_OPERAND (arg, 0), cval1, cval2, save_p)
02726 && twoval_comparison_p (TREE_OPERAND (arg, 1),
02727 cval1, cval2, save_p));
02728
02729 case tcc_constant:
02730 return 1;
02731
02732 case tcc_expression:
02733 if (code == COND_EXPR)
02734 return (twoval_comparison_p (TREE_OPERAND (arg, 0),
02735 cval1, cval2, save_p)
02736 && twoval_comparison_p (TREE_OPERAND (arg, 1),
02737 cval1, cval2, save_p)
02738 && twoval_comparison_p (TREE_OPERAND (arg, 2),
02739 cval1, cval2, save_p));
02740 return 0;
02741
02742 case tcc_comparison:
02743
02744
02745
02746
02747
02748
02749 if (operand_equal_p (TREE_OPERAND (arg, 0),
02750 TREE_OPERAND (arg, 1), 0))
02751 return 0;
02752
02753 if (*cval1 == 0)
02754 *cval1 = TREE_OPERAND (arg, 0);
02755 else if (operand_equal_p (*cval1, TREE_OPERAND (arg, 0), 0))
02756 ;
02757 else if (*cval2 == 0)
02758 *cval2 = TREE_OPERAND (arg, 0);
02759 else if (operand_equal_p (*cval2, TREE_OPERAND (arg, 0), 0))
02760 ;
02761 else
02762 return 0;
02763
02764 if (operand_equal_p (*cval1, TREE_OPERAND (arg, 1), 0))
02765 ;
02766 else if (*cval2 == 0)
02767 *cval2 = TREE_OPERAND (arg, 1);
02768 else if (operand_equal_p (*cval2, TREE_OPERAND (arg, 1), 0))
02769 ;
02770 else
02771 return 0;
02772
02773 return 1;
02774
02775 default:
02776 return 0;
02777 }
02778 }
02779
02780
02781
02782
02783
02784
02785 static tree
02786 eval_subst (tree arg, tree old0, tree new0, tree old1, tree new1)
02787 {
02788 tree type = TREE_TYPE (arg);
02789 enum tree_code code = TREE_CODE (arg);
02790 enum tree_code_class class = TREE_CODE_CLASS (code);
02791
02792
02793 if (class == tcc_expression && code == TRUTH_NOT_EXPR)
02794 class = tcc_unary;
02795 else if (class == tcc_expression
02796 && (code == TRUTH_ANDIF_EXPR || code == TRUTH_ORIF_EXPR))
02797 class = tcc_binary;
02798
02799 switch (class)
02800 {
02801 case tcc_unary:
02802 return fold (build1 (code, type,
02803 eval_subst (TREE_OPERAND (arg, 0),
02804 old0, new0, old1, new1)));
02805
02806 case tcc_binary:
02807 return fold (build2 (code, type,
02808 eval_subst (TREE_OPERAND (arg, 0),
02809 old0, new0, old1, new1),
02810 eval_subst (TREE_OPERAND (arg, 1),
02811 old0, new0, old1, new1)));
02812
02813 case tcc_expression:
02814 switch (code)
02815 {
02816 case SAVE_EXPR:
02817 return eval_subst (TREE_OPERAND (arg, 0), old0, new0, old1, new1);
02818
02819 case COMPOUND_EXPR:
02820 return eval_subst (TREE_OPERAND (arg, 1), old0, new0, old1, new1);
02821
02822 case COND_EXPR:
02823 return fold (build3 (code, type,
02824 eval_subst (TREE_OPERAND (arg, 0),
02825 old0, new0, old1, new1),
02826 eval_subst (TREE_OPERAND (arg, 1),
02827 old0, new0, old1, new1),
02828 eval_subst (TREE_OPERAND (arg, 2),
02829 old0, new0, old1, new1)));
02830 default:
02831 break;
02832 }
02833
02834
02835 case tcc_comparison:
02836 {
02837 tree arg0 = TREE_OPERAND (arg, 0);
02838 tree arg1 = TREE_OPERAND (arg, 1);
02839
02840
02841
02842
02843
02844 if (arg0 == old0 || operand_equal_p (arg0, old0, 0))
02845 arg0 = new0;
02846 else if (arg0 == old1 || operand_equal_p (arg0, old1, 0))
02847 arg0 = new1;
02848
02849 if (arg1 == old0 || operand_equal_p (arg1, old0, 0))
02850 arg1 = new0;
02851 else if (arg1 == old1 || operand_equal_p (arg1, old1, 0))
02852 arg1 = new1;
02853
02854 return fold (build2 (code, type, arg0, arg1));
02855 }
02856
02857 default:
02858 return arg;
02859 }
02860 }
02861
02862
02863
02864
02865
02866
02867
02868
02869 tree
02870 omit_one_operand (tree type, tree result, tree omitted)
02871 {
02872 tree t = fold_convert (type, result);
02873
02874 if (TREE_SIDE_EFFECTS (omitted))
02875 return build2 (COMPOUND_EXPR, type, fold_ignored_result (omitted), t);
02876
02877 return non_lvalue (t);
02878 }
02879
02880
02881
02882 static tree
02883 pedantic_omit_one_operand (tree type, tree result, tree omitted)
02884 {
02885 tree t = fold_convert (type, result);
02886
02887 if (TREE_SIDE_EFFECTS (omitted))
02888 return build2 (COMPOUND_EXPR, type, fold_ignored_result (omitted), t);
02889
02890 return pedantic_non_lvalue (t);
02891 }
02892
02893
02894
02895
02896
02897
02898
02899
02900
02901
02902 tree
02903 omit_two_operands (tree type, tree result, tree omitted1, tree omitted2)
02904 {
02905 tree t = fold_convert (type, result);
02906
02907 if (TREE_SIDE_EFFECTS (omitted2))
02908 t = build2 (COMPOUND_EXPR, type, omitted2, t);
02909 if (TREE_SIDE_EFFECTS (omitted1))
02910 t = build2 (COMPOUND_EXPR, type, omitted1, t);
02911
02912 return TREE_CODE (t) != COMPOUND_EXPR ? non_lvalue (t) : t;
02913 }
02914
02915
02916
02917
02918
02919
02920
02921
02922 tree
02923 invert_truthvalue (tree arg)
02924 {
02925 tree type = TREE_TYPE (arg);
02926 enum tree_code code = TREE_CODE (arg);
02927
02928 if (code == ERROR_MARK)
02929 return arg;
02930
02931
02932
02933
02934
02935 if (TREE_CODE_CLASS (code) == tcc_comparison)
02936 {
02937 tree op_type = TREE_TYPE (TREE_OPERAND (arg, 0));
02938 if (FLOAT_TYPE_P (op_type)
02939 && flag_trapping_math
02940 && code != ORDERED_EXPR && code != UNORDERED_EXPR
02941 && code != NE_EXPR && code != EQ_EXPR)
02942 return build1 (TRUTH_NOT_EXPR, type, arg);
02943 else
02944 {
02945 code = invert_tree_comparison (code,
02946 HONOR_NANS (TYPE_MODE (op_type)));
02947 if (code == ERROR_MARK)
02948 return build1 (TRUTH_NOT_EXPR, type, arg);
02949 else
02950 return build2 (code, type,
02951 TREE_OPERAND (arg, 0), TREE_OPERAND (arg, 1));
02952 }
02953 }
02954
02955 switch (code)
02956 {
02957 case INTEGER_CST:
02958 return constant_boolean_node (integer_zerop (arg), type);
02959
02960 case TRUTH_AND_EXPR:
02961 return build2 (TRUTH_OR_EXPR, type,
02962 invert_truthvalue (TREE_OPERAND (arg, 0)),
02963 invert_truthvalue (TREE_OPERAND (arg, 1)));
02964
02965 case TRUTH_OR_EXPR:
02966 return build2 (TRUTH_AND_EXPR, type,
02967 invert_truthvalue (TREE_OPERAND (arg, 0)),
02968 invert_truthvalue (TREE_OPERAND (arg, 1)));
02969
02970 case TRUTH_XOR_EXPR:
02971
02972
02973
02974
02975
02976 if (TREE_CODE (TREE_OPERAND (arg, 1)) == TRUTH_NOT_EXPR)
02977 return build2 (TRUTH_XOR_EXPR, type, TREE_OPERAND (arg, 0),
02978 TREE_OPERAND (TREE_OPERAND (arg, 1), 0));
02979 else
02980 return build2 (TRUTH_XOR_EXPR, type,
02981 invert_truthvalue (TREE_OPERAND (arg, 0)),
02982 TREE_OPERAND (arg, 1));
02983
02984 case TRUTH_ANDIF_EXPR:
02985 return build2 (TRUTH_ORIF_EXPR, type,
02986 invert_truthvalue (TREE_OPERAND (arg, 0)),
02987 invert_truthvalue (TREE_OPERAND (arg, 1)));
02988
02989 case TRUTH_ORIF_EXPR:
02990 return build2 (TRUTH_ANDIF_EXPR, type,
02991 invert_truthvalue (TREE_OPERAND (arg, 0)),
02992 invert_truthvalue (TREE_OPERAND (arg, 1)));
02993
02994 case TRUTH_NOT_EXPR:
02995 return TREE_OPERAND (arg, 0);
02996
02997 case COND_EXPR:
02998 return build3 (COND_EXPR, type, TREE_OPERAND (arg, 0),
02999 invert_truthvalue (TREE_OPERAND (arg, 1)),
03000 invert_truthvalue (TREE_OPERAND (arg, 2)));
03001
03002 case COMPOUND_EXPR:
03003 return build2 (COMPOUND_EXPR, type, TREE_OPERAND (arg, 0),
03004 invert_truthvalue (TREE_OPERAND (arg, 1)));
03005
03006 case NON_LVALUE_EXPR:
03007 return invert_truthvalue (TREE_OPERAND (arg, 0));
03008
03009 case NOP_EXPR:
03010 if (TREE_CODE (TREE_TYPE (arg)) == BOOLEAN_TYPE)
03011 break;
03012
03013 case CONVERT_EXPR:
03014 case FLOAT_EXPR:
03015 return build1 (TREE_CODE (arg), type,
03016 invert_truthvalue (TREE_OPERAND (arg, 0)));
03017
03018 case BIT_AND_EXPR:
03019 if (!integer_onep (TREE_OPERAND (arg, 1)))
03020 break;
03021 return build2 (EQ_EXPR, type, arg,
03022 fold_convert (type, integer_zero_node));
03023
03024 case SAVE_EXPR:
03025 return build1 (TRUTH_NOT_EXPR, type, arg);
03026
03027 case CLEANUP_POINT_EXPR:
03028 return build1 (CLEANUP_POINT_EXPR, type,
03029 invert_truthvalue (TREE_OPERAND (arg, 0)));
03030
03031 default:
03032 break;
03033 }
03034 gcc_assert (TREE_CODE (TREE_TYPE (arg)) == BOOLEAN_TYPE);
03035 return build1 (TRUTH_NOT_EXPR, type, arg);
03036 }
03037
03038
03039
03040
03041
03042
03043
03044
03045
03046
03047 static tree
03048 distribute_bit_expr (enum tree_code code, tree type, tree arg0, tree arg1)
03049 {
03050 tree common;
03051 tree left, right;
03052
03053 if (TREE_CODE (arg0) != TREE_CODE (arg1)
03054 || TREE_CODE (arg0) == code
03055 || (TREE_CODE (arg0) != BIT_AND_EXPR
03056 && TREE_CODE (arg0) != BIT_IOR_EXPR))
03057 return 0;
03058
03059 if (operand_equal_p (TREE_OPERAND (arg0, 0), TREE_OPERAND (arg1, 0), 0))
03060 {
03061 common = TREE_OPERAND (arg0, 0);
03062 left = TREE_OPERAND (arg0, 1);
03063 right = TREE_OPERAND (arg1, 1);
03064 }
03065 else if (operand_equal_p (TREE_OPERAND (arg0, 0), TREE_OPERAND (arg1, 1), 0))
03066 {
03067 common = TREE_OPERAND (arg0, 0);
03068 left = TREE_OPERAND (arg0, 1);
03069 right = TREE_OPERAND (arg1, 0);
03070 }
03071 else if (operand_equal_p (TREE_OPERAND (arg0, 1), TREE_OPERAND (arg1, 0), 0))
03072 {
03073 common = TREE_OPERAND (arg0, 1);
03074 left = TREE_OPERAND (arg0, 0);
03075 right = TREE_OPERAND (arg1, 1);
03076 }
03077 else if (operand_equal_p (TREE_OPERAND (arg0, 1), TREE_OPERAND (arg1, 1), 0))
03078 {
03079 common = TREE_OPERAND (arg0, 1);
03080 left = TREE_OPERAND (arg0, 0);
03081 right = TREE_OPERAND (arg1, 0);
03082 }
03083 else
03084 return 0;
03085
03086 return fold (build2 (TREE_CODE (arg0), type, common,
03087 fold (build2 (code, type, left, right))));
03088 }
03089
03090
03091
03092
03093 static tree
03094 make_bit_field_ref (tree inner, tree type, int bitsize, int bitpos,
03095 int unsignedp)
03096 {
03097 tree result;
03098
03099 if (bitpos == 0)
03100 {
03101 tree size = TYPE_SIZE (TREE_TYPE (inner));
03102 if ((INTEGRAL_TYPE_P (TREE_TYPE (inner))
03103 || POINTER_TYPE_P (TREE_TYPE (inner)))
03104 && host_integerp (size, 0)
03105 && tree_low_cst (size, 0) == bitsize)
03106 return fold_convert (type, inner);
03107 }
03108
03109 result = build3 (BIT_FIELD_REF, type, inner,
03110 size_int (bitsize), bitsize_int (bitpos));
03111
03112 BIT_FIELD_REF_UNSIGNED (result) = unsignedp;
03113
03114 return result;
03115 }
03116
03117
03118
03119
03120
03121
03122
03123
03124
03125
03126
03127
03128
03129
03130
03131
03132
03133
03134
03135
03136
03137 static tree
03138 optimize_bit_field_compare (enum tree_code code, tree compare_type,
03139 tree lhs, tree rhs)
03140 {
03141 HOST_WIDE_INT lbitpos, lbitsize, rbitpos, rbitsize, nbitpos, nbitsize;
03142 tree type = TREE_TYPE (lhs);
03143 tree signed_type, unsigned_type;
03144 int const_p = TREE_CODE (rhs) == INTEGER_CST;
03145 enum machine_mode lmode, rmode, nmode;
03146 int lunsignedp, runsignedp;
03147 int lvolatilep = 0, rvolatilep = 0;
03148 tree linner, rinner = NULL_TREE;
03149 tree mask;
03150 tree offset;
03151
03152
03153
03154
03155
03156
03157 linner = get_inner_reference (lhs, &lbitsize, &lbitpos, &offset, &lmode,
03158 &lunsignedp, &lvolatilep, false);
03159 if (linner == lhs || lbitsize == GET_MODE_BITSIZE (lmode) || lbitsize < 0
03160 || offset != 0 || TREE_CODE (linner) == PLACEHOLDER_EXPR)
03161 return 0;
03162
03163 if (!const_p)
03164 {
03165
03166
03167 rinner = get_inner_reference (rhs, &rbitsize, &rbitpos, &offset, &rmode,
03168 &runsignedp, &rvolatilep, false);
03169
03170 if (rinner == rhs || lbitpos != rbitpos || lbitsize != rbitsize
03171 || lunsignedp != runsignedp || offset != 0
03172 || TREE_CODE (rinner) == PLACEHOLDER_EXPR)
03173 return 0;
03174 }
03175
03176
03177
03178 nmode = get_best_mode (lbitsize, lbitpos,
03179 const_p ? TYPE_ALIGN (TREE_TYPE (linner))
03180 : MIN (TYPE_ALIGN (TREE_TYPE (linner)),
03181 TYPE_ALIGN (TREE_TYPE (rinner))),
03182 word_mode, lvolatilep || rvolatilep);
03183 if (nmode == VOIDmode)
03184 return 0;
03185
03186
03187
03188 signed_type = lang_hooks.types.type_for_mode (nmode, 0);
03189 unsigned_type = lang_hooks.types.type_for_mode (nmode, 1);
03190
03191
03192
03193
03194 nbitsize = GET_MODE_BITSIZE (nmode);
03195 nbitpos = lbitpos & ~ (nbitsize - 1);
03196 lbitpos -= nbitpos;
03197 if (nbitsize == lbitsize)
03198 return 0;
03199
03200 if (BYTES_BIG_ENDIAN)
03201 lbitpos = nbitsize - lbitsize - lbitpos;
03202
03203
03204 mask = build_int_cst (unsigned_type, -1);
03205 mask = force_fit_type (mask, 0, false, false);
03206 mask = fold_convert (unsigned_type, mask);
03207 mask = const_binop (LSHIFT_EXPR, mask, size_int (nbitsize - lbitsize), 0);
03208 mask = const_binop (RSHIFT_EXPR, mask,
03209 size_int (nbitsize - lbitsize - lbitpos), 0);
03210
03211 if (! const_p)
03212
03213
03214 return build2 (code, compare_type,
03215 build2 (BIT_AND_EXPR, unsigned_type,
03216 make_bit_field_ref (linner, unsigned_type,
03217 nbitsize, nbitpos, 1),
03218 mask),
03219 build2 (BIT_AND_EXPR, unsigned_type,
03220 make_bit_field_ref (rinner, unsigned_type,
03221 nbitsize, nbitpos, 1),
03222 mask));
03223
03224
03225
03226
03227
03228
03229
03230
03231
03232
03233 if (lunsignedp)
03234 {
03235 if (! integer_zerop (const_binop (RSHIFT_EXPR,
03236 fold_convert (unsigned_type, rhs),
03237 size_int (lbitsize), 0)))
03238 {
03239 warning ("comparison is always %d due to width of bit-field",
03240 code == NE_EXPR);
03241 return constant_boolean_node (code == NE_EXPR, compare_type);
03242 }
03243 }
03244 else
03245 {
03246 tree tem = const_binop (RSHIFT_EXPR, fold_convert (signed_type, rhs),
03247 size_int (lbitsize - 1), 0);
03248 if (! integer_zerop (tem) && ! integer_all_onesp (tem))
03249 {
03250 warning ("comparison is always %d due to width of bit-field",
03251 code == NE_EXPR);
03252 return constant_boolean_node (code == NE_EXPR, compare_type);
03253 }
03254 }
03255
03256
03257 if (lbitsize == 1 && ! integer_zerop (rhs))
03258 {
03259 code = code == EQ_EXPR ? NE_EXPR : EQ_EXPR;
03260 rhs = fold_convert (type, integer_zero_node);
03261 }
03262
03263
03264
03265
03266 lhs = make_bit_field_ref (linner, unsigned_type, nbitsize, nbitpos, 1);
03267 if (lvolatilep)
03268 {
03269 TREE_SIDE_EFFECTS (lhs) = 1;
03270 TREE_THIS_VOLATILE (lhs) = 1;
03271 }
03272
03273 rhs = fold (const_binop (BIT_AND_EXPR,
03274 const_binop (LSHIFT_EXPR,
03275 fold_convert (unsigned_type, rhs),
03276 size_int (lbitpos), 0),
03277 mask, 0));
03278
03279 return build2 (code, compare_type,
03280 build2 (BIT_AND_EXPR, unsigned_type, lhs, mask),
03281 rhs);
03282 }
03283
03284
03285
03286
03287
03288
03289
03290
03291
03292
03293
03294
03295
03296
03297
03298
03299
03300
03301
03302
03303
03304
03305
03306
03307 static tree
03308 decode_field_reference (tree exp, HOST_WIDE_INT *pbitsize,
03309 HOST_WIDE_INT *pbitpos, enum machine_mode *pmode,
03310 int *punsignedp, int *pvolatilep,
03311 tree *pmask, tree *pand_mask)
03312 {
03313 tree outer_type = 0;
03314 tree and_mask = 0;
03315 tree mask, inner, offset;
03316 tree unsigned_type;
03317 unsigned int precision;
03318
03319
03320
03321
03322 if (! INTEGRAL_TYPE_P (TREE_TYPE (exp)))
03323 return 0;
03324
03325
03326
03327
03328 if (TREE_CODE (exp) == NOP_EXPR
03329 || TREE_CODE (exp) == CONVERT_EXPR
03330 || TREE_CODE (exp) == NON_LVALUE_EXPR)
03331 outer_type = TREE_TYPE (exp);
03332 STRIP_NOPS (exp);
03333
03334 if (TREE_CODE (exp) == BIT_AND_EXPR)
03335 {
03336 and_mask = TREE_OPERAND (exp, 1);
03337 exp = TREE_OPERAND (exp, 0);
03338 STRIP_NOPS (exp); STRIP_NOPS (and_mask);
03339 if (TREE_CODE (and_mask) != INTEGER_CST)
03340 return 0;
03341 }
03342
03343 inner = get_inner_reference (exp, pbitsize, pbitpos, &offset, pmode,
03344 punsignedp, pvolatilep, false);
03345 if ((inner == exp && and_mask == 0)
03346 || *pbitsize < 0 || offset != 0
03347 || TREE_CODE (inner) == PLACEHOLDER_EXPR)
03348 return 0;
03349
03350
03351
03352
03353 if (outer_type && *pbitsize == TYPE_PRECISION (outer_type))
03354 *punsignedp = TYPE_UNSIGNED (outer_type);
03355
03356
03357 unsigned_type = lang_hooks.types.type_for_size (*pbitsize, 1);
03358 precision = TYPE_PRECISION (unsigned_type);
03359
03360 mask = build_int_cst (unsigned_type, -1);
03361 mask = force_fit_type (mask, 0, false, false);
03362
03363 mask = const_binop (LSHIFT_EXPR, mask, size_int (precision - *pbitsize), 0);
03364 mask = const_binop (RSHIFT_EXPR, mask, size_int (precision - *pbitsize), 0);
03365
03366
03367 if (and_mask != 0)
03368 mask = fold (build2 (BIT_AND_EXPR, unsigned_type,
03369 fold_convert (unsigned_type, and_mask), mask));
03370
03371 *pmask = mask;
03372 *pand_mask = and_mask;
03373 return inner;
03374 }
03375
03376
03377
03378
03379 static int
03380 all_ones_mask_p (tree mask, int size)
03381 {
03382 tree type = TREE_TYPE (mask);
03383 unsigned int precision = TYPE_PRECISION (type);
03384 tree tmask;
03385
03386 tmask = build_int_cst (lang_hooks.types.signed_type (type), -1);
03387 tmask = force_fit_type (tmask, 0, false, false);
03388
03389 return
03390 tree_int_cst_equal (mask,
03391 const_binop (RSHIFT_EXPR,
03392 const_binop (LSHIFT_EXPR, tmask,
03393 size_int (precision - size),
03394 0),
03395 size_int (precision - size), 0));
03396 }
03397
03398
03399
03400
03401
03402
03403
03404 static tree
03405 sign_bit_p (tree exp, tree val)
03406 {
03407 unsigned HOST_WIDE_INT mask_lo, lo;
03408 HOST_WIDE_INT mask_hi, hi;
03409 int width;
03410 tree t;
03411
03412
03413 t = TREE_TYPE (exp);
03414 if (! INTEGRAL_TYPE_P (t))
03415 return NULL_TREE;
03416
03417
03418 if (TREE_CODE (val) != INTEGER_CST
03419 || TREE_CONSTANT_OVERFLOW (val))
03420 return NULL_TREE;
03421
03422 width = TYPE_PRECISION (t);
03423 if (width > HOST_BITS_PER_WIDE_INT)
03424 {
03425 hi = (unsigned HOST_WIDE_INT) 1 << (width - HOST_BITS_PER_WIDE_INT - 1);
03426 lo = 0;
03427
03428 mask_hi = ((unsigned HOST_WIDE_INT) -1
03429 >> (2 * HOST_BITS_PER_WIDE_INT - width));
03430 mask_lo = -1;
03431 }
03432 else
03433 {
03434 hi = 0;
03435 lo = (unsigned HOST_WIDE_INT) 1 << (width - 1);
03436
03437 mask_hi = 0;
03438 mask_lo = ((unsigned HOST_WIDE_INT) -1
03439 >> (HOST_BITS_PER_WIDE_INT - width));
03440 }
03441
03442
03443
03444 if ((TREE_INT_CST_HIGH (val) & mask_hi) == hi
03445 && (TREE_INT_CST_LOW (val) & mask_lo) == lo)
03446 return exp;
03447
03448
03449 if (TREE_CODE (exp) == NOP_EXPR
03450 && TYPE_PRECISION (TREE_TYPE (TREE_OPERAND (exp, 0))) < width)
03451 return sign_bit_p (TREE_OPERAND (exp, 0), val);
03452
03453 return NULL_TREE;
03454 }
03455
03456
03457
03458
03459 static int
03460 simple_operand_p (tree exp)
03461 {
03462
03463 STRIP_NOPS (exp);
03464
03465 return (CONSTANT_CLASS_P (exp)
03466 || TREE_CODE (exp) == SSA_NAME
03467 || (DECL_P (exp)
03468 && ! TREE_ADDRESSABLE (exp)
03469 && ! TREE_THIS_VOLATILE (exp)
03470 && ! DECL_NONLOCAL (exp)
03471
03472
03473
03474 && ! TREE_PUBLIC (exp)
03475 && ! DECL_EXTERNAL (exp)
03476
03477
03478 && (! TREE_STATIC (exp) || DECL_REGISTER (exp))));
03479 }
03480
03481
03482
03483
03484
03485
03486
03487
03488
03489
03490
03491
03492
03493
03494
03495
03496
03497
03498
03499
03500
03501
03502
03503
03504
03505
03506
03507
03508
03509
03510
03511
03512
03513
03514
03515
03516 static tree
03517 range_binop (enum tree_code code, tree type, tree arg0, int upper0_p,
03518 tree arg1, int upper1_p)
03519 {
03520 tree tem;
03521 int result;
03522 int sgn0, sgn1;
03523
03524
03525
03526
03527
03528
03529 if (arg0 != 0 && arg1 != 0)
03530 {
03531 tem = fold (build2 (code, type != 0 ? type : TREE_TYPE (arg0),
03532 arg0, fold_convert (TREE_TYPE (arg0), arg1)));
03533 STRIP_NOPS (tem);
03534 return TREE_CODE (tem) == INTEGER_CST ? tem : 0;
03535 }
03536
03537 if (TREE_CODE_CLASS (code) != tcc_comparison)
03538 return 0;
03539
03540
03541
03542
03543
03544
03545
03546 sgn0 = arg0 != 0 ? 0 : (upper0_p ? 1 : -1);
03547 sgn1 = arg1 != 0 ? 0 : (upper1_p ? 1 : -1);
03548 switch (code)
03549 {
03550 case EQ_EXPR:
03551 result = sgn0 == sgn1;
03552 break;
03553 case NE_EXPR:
03554 result = sgn0 != sgn1;
03555 break;
03556 case LT_EXPR:
03557 result = sgn0 < sgn1;
03558 break;
03559 case LE_EXPR:
03560 result = sgn0 <= sgn1;
03561 break;
03562 case GT_EXPR:
03563 result = sgn0 > sgn1;
03564 break;
03565 case GE_EXPR:
03566 result = sgn0 >= sgn1;
03567 break;
03568 default:
03569 gcc_unreachable ();
03570 }
03571
03572 return constant_boolean_node (result, type);
03573 }
03574
03575
03576
03577
03578
03579
03580
03581 static tree
03582 make_range (tree exp, int *pin_p, tree *plow, tree *phigh)
03583 {
03584 enum tree_code code;
03585 tree arg0 = NULL_TREE, arg1 = NULL_TREE;
03586 tree exp_type = NULL_TREE, arg0_type = NULL_TREE;
03587 int in_p, n_in_p;
03588 tree low, high, n_low, n_high;
03589
03590
03591
03592
03593
03594
03595
03596 in_p = 0;
03597 low = high = fold_convert (TREE_TYPE (exp), integer_zero_node);
03598
03599 while (1)
03600 {
03601 code = TREE_CODE (exp);
03602 exp_type = TREE_TYPE (exp);
03603
03604 if (IS_EXPR_CODE_CLASS (TREE_CODE_CLASS (code)))
03605 {
03606 if (TREE_CODE_LENGTH (code) > 0)
03607 arg0 = TREE_OPERAND (exp, 0);
03608 if (TREE_CODE_CLASS (code) == tcc_comparison
03609 || TREE_CODE_CLASS (code) == tcc_unary
03610 || TREE_CODE_CLASS (code) == tcc_binary)
03611 arg0_type = TREE_TYPE (arg0);
03612 if (TREE_CODE_CLASS (code) == tcc_binary
03613 || TREE_CODE_CLASS (code) == tcc_comparison
03614 || (TREE_CODE_CLASS (code) == tcc_expression
03615 && TREE_CODE_LENGTH (code) > 1))
03616 arg1 = TREE_OPERAND (exp, 1);
03617 }
03618
03619 switch (code)
03620 {
03621 case TRUTH_NOT_EXPR:
03622 in_p = ! in_p, exp = arg0;
03623 continue;
03624
03625 case EQ_EXPR: case NE_EXPR:
03626 case LT_EXPR: case LE_EXPR: case GE_EXPR: case GT_EXPR:
03627
03628
03629
03630
03631
03632 if (low == 0 || high == 0
03633 || ! integer_zerop (low) || ! integer_zerop (high)
03634 || TREE_CODE (arg1) != INTEGER_CST)
03635 break;
03636
03637 switch (code)
03638 {
03639 case NE_EXPR:
03640 low = high = arg1;
03641 break;
03642 case EQ_EXPR:
03643 in_p = ! in_p, low = high = arg1;
03644 break;
03645 case GT_EXPR:
03646 low = 0, high = arg1;
03647 break;
03648 case GE_EXPR:
03649 in_p = ! in_p, low = arg1, high = 0;
03650 break;
03651 case LT_EXPR:
03652 low = arg1, high = 0;
03653 break;
03654 case LE_EXPR:
03655 in_p = ! in_p, low = 0, high = arg1;
03656 break;
03657 default:
03658 gcc_unreachable ();
03659 }
03660
03661
03662
03663
03664
03665
03666 if (TYPE_UNSIGNED (arg0_type) && (low == 0 || high == 0))
03667 {
03668 if (! merge_ranges (&n_in_p, &n_low, &n_high,
03669 in_p, low, high, 1,
03670 fold_convert (arg0_type, integer_zero_node),
03671 NULL_TREE))
03672 break;
03673
03674 in_p = n_in_p, low = n_low, high = n_high;
03675
03676
03677
03678
03679 if (high == 0 && low && ! integer_zerop (low))
03680 {
03681 in_p = ! in_p;
03682 high = range_binop (MINUS_EXPR, NULL_TREE, low, 0,
03683 integer_one_node, 0);
03684 low = fold_convert (arg0_type, integer_zero_node);
03685 }
03686 }
03687
03688 exp = arg0;
03689 continue;
03690
03691 case NEGATE_EXPR:
03692
03693 n_low = range_binop (MINUS_EXPR, exp_type,
03694 fold_convert (exp_type, integer_zero_node),
03695 0, high, 1);
03696 n_high = range_binop (MINUS_EXPR, exp_type,
03697 fold_convert (exp_type, integer_zero_node),
03698 0, low, 0);
03699 low = n_low, high = n_high;
03700 exp = arg0;
03701 continue;
03702
03703 case BIT_NOT_EXPR:
03704
03705 exp = build2 (MINUS_EXPR, exp_type, negate_expr (arg0),
03706 fold_convert (exp_type, integer_one_node));
03707 continue;
03708
03709 case PLUS_EXPR: case MINUS_EXPR:
03710 if (TREE_CODE (arg1) != INTEGER_CST)
03711 break;
03712
03713
03714
03715
03716
03717 n_low = range_binop (code == MINUS_EXPR ? PLUS_EXPR : MINUS_EXPR,
03718 arg0_type, low, 0, arg1, 0);
03719 n_high = range_binop (code == MINUS_EXPR ? PLUS_EXPR : MINUS_EXPR,
03720 arg0_type, high, 1, arg1, 0);
03721 if ((n_low != 0 && TREE_OVERFLOW (n_low))
03722 || (n_high != 0 && TREE_OVERFLOW (n_high)))
03723 break;
03724
03725
03726
03727 if (n_low && n_high && tree_int_cst_lt (n_high, n_low))
03728 {
03729 low = range_binop (PLUS_EXPR, arg0_type, n_high, 0,
03730 integer_one_node, 0);
03731 high = range_binop (MINUS_EXPR, arg0_type, n_low, 0,
03732 integer_one_node, 0);
03733
03734
03735
03736
03737
03738 if (tree_int_cst_equal (n_low, low)
03739 && tree_int_cst_equal (n_high, high))
03740 low = high = 0;
03741 else
03742 in_p = ! in_p;
03743 }
03744 else
03745 low = n_low, high = n_high;
03746
03747 exp = arg0;
03748 continue;
03749
03750 case NOP_EXPR: case NON_LVALUE_EXPR: case CONVERT_EXPR:
03751 if (TYPE_PRECISION (arg0_type) > TYPE_PRECISION (exp_type))
03752 break;
03753
03754 if (! INTEGRAL_TYPE_P (arg0_type)
03755 || (low != 0 && ! int_fits_type_p (low, arg0_type))
03756 || (high != 0 && ! int_fits_type_p (high, arg0_type)))
03757 break;
03758
03759 n_low = low, n_high = high;
03760
03761 if (n_low != 0)
03762 n_low = fold_convert (arg0_type, n_low);
03763
03764 if (n_high != 0)
03765 n_high = fold_convert (arg0_type, n_high);
03766
03767
03768
03769
03770
03771
03772
03773
03774
03775
03776
03777 if (!TYPE_UNSIGNED (exp_type) && TYPE_UNSIGNED (arg0_type))
03778 {
03779 tree high_positive;
03780 tree equiv_type = lang_hooks.types.type_for_mode
03781 (TYPE_MODE (arg0_type), 1);
03782
03783
03784
03785
03786 high_positive
03787 = TYPE_MAX_VALUE (equiv_type) ? TYPE_MAX_VALUE (equiv_type)
03788 : TYPE_MAX_VALUE (arg0_type);
03789
03790 if (TYPE_PRECISION (exp_type) == TYPE_PRECISION (arg0_type))
03791 high_positive = fold (build2 (RSHIFT_EXPR, arg0_type,
03792 fold_convert (arg0_type,
03793 high_positive),
03794 fold_convert (arg0_type,
03795 integer_one_node)));
03796
03797
03798
03799
03800 if (low != 0)
03801 {
03802 if (! merge_ranges (&n_in_p, &n_low, &n_high,
03803 1, n_low, n_high, 1,
03804 fold_convert (arg0_type,
03805 integer_zero_node),
03806 high_positive))
03807 break;
03808
03809 in_p = (n_in_p == in_p);
03810 }
03811 else
03812 {
03813
03814
03815 if (! merge_ranges (&n_in_p, &n_low, &n_high,
03816 0, n_low, n_high, 1,
03817 fold_convert (arg0_type,
03818 integer_zero_node),
03819 high_positive))
03820 break;
03821
03822 in_p = (in_p != n_in_p);
03823 }
03824 }
03825
03826 exp = arg0;
03827 low = n_low, high = n_high;
03828 continue;
03829
03830 default:
03831 break;
03832 }
03833
03834 break;
03835 }
03836
03837
03838 if (TREE_CODE (exp) == INTEGER_CST)
03839 {
03840 in_p = in_p == (integer_onep (range_binop (GE_EXPR, integer_type_node,
03841 exp, 0, low, 0))
03842 && integer_onep (range_binop (LE_EXPR, integer_type_node,
03843 exp, 1, high, 1)));
03844 low = high = 0;
03845 exp = 0;
03846 }
03847
03848 *pin_p = in_p, *plow = low, *phigh = high;
03849 return exp;
03850 }
03851
03852
03853
03854
03855
03856 static tree
03857 build_range_check (tree type, tree exp, int in_p, tree low, tree high)
03858 {
03859 tree etype = TREE_TYPE (exp);
03860 tree value;
03861
03862 #ifdef HAVE_canonicalize_funcptr_for_compare
03863
03864
03865 if (HAVE_canonicalize_funcptr_for_compare
03866 && TREE_CODE (etype) == POINTER_TYPE
03867 && TREE_CODE (TREE_TYPE (etype)) == FUNCTION_TYPE)
03868 return NULL_TREE;
03869 #endif
03870
03871 if (! in_p)
03872 {
03873 value = build_range_check (type, exp, 1, low, high);
03874 if (value != 0)
03875 return invert_truthvalue (value);
03876
03877 return 0;
03878 }
03879
03880 if (low == 0 && high == 0)
03881 return fold_convert (type, integer_one_node);
03882
03883 if (low == 0)
03884 return fold (build2 (LE_EXPR, type, exp, high));
03885
03886 if (high == 0)
03887 return fold (build2 (GE_EXPR, type, exp, low));
03888
03889 if (operand_equal_p (low, high, 0))
03890 return fold (build2 (EQ_EXPR, type, exp, low));
03891
03892 if (integer_zerop (low))
03893 {
03894 if (! TYPE_UNSIGNED (etype))
03895 {
03896 etype = lang_hooks.types.unsigned_type (etype);
03897 high = fold_convert (etype, high);
03898 exp = fold_convert (etype, exp);
03899 }
03900 return build_range_check (type, exp, 1, 0, high);
03901 }
03902
03903
03904 if (integer_onep (low) && TREE_CODE (high) == INTEGER_CST)
03905 {
03906 unsigned HOST_WIDE_INT lo;
03907 HOST_WIDE_INT hi;
03908 int prec;
03909
03910 prec = TYPE_PRECISION (etype);
03911 if (prec <= HOST_BITS_PER_WIDE_INT)
03912 {
03913 hi = 0;
03914 lo = ((unsigned HOST_WIDE_INT) 1 << (prec - 1)) - 1;
03915 }
03916 else
03917 {
03918 hi = ((HOST_WIDE_INT) 1 << (prec - HOST_BITS_PER_WIDE_INT - 1)) - 1;
03919 lo = (unsigned HOST_WIDE_INT) -1;
03920 }
03921
03922 if (TREE_INT_CST_HIGH (high) == hi && TREE_INT_CST_LOW (high) == lo)
03923 {
03924 if (TYPE_UNSIGNED (etype))
03925 {
03926 etype = lang_hooks.types.signed_type (etype);
03927 exp = fold_convert (etype, exp);
03928 }
03929 return fold (build2 (GT_EXPR, type, exp,
03930 fold_convert (etype, integer_zero_node)));
03931 }
03932 }
03933
03934 value = const_binop (MINUS_EXPR, high, low, 0);
03935 if (value != 0 && TREE_OVERFLOW (value) && ! TYPE_UNSIGNED (etype))
03936 {
03937 tree utype, minv, maxv;
03938
03939
03940
03941 switch (TREE_CODE (etype))
03942 {
03943 case INTEGER_TYPE:
03944 case ENUMERAL_TYPE:
03945 case CHAR_TYPE:
03946 utype = lang_hooks.types.unsigned_type (etype);
03947 maxv = fold_convert (utype, TYPE_MAX_VALUE (etype));
03948 maxv = range_binop (PLUS_EXPR, NULL_TREE, maxv, 1,
03949 integer_one_node, 1);
03950 minv = fold_convert (utype, TYPE_MIN_VALUE (etype));
03951 if (integer_zerop (range_binop (NE_EXPR, integer_type_node,
03952 minv, 1, maxv, 1)))
03953 {
03954 etype = utype;
03955 high = fold_convert (etype, high);
03956 low = fold_convert (etype, low);
03957 exp = fold_convert (etype, exp);
03958 value = const_binop (MINUS_EXPR, high, low, 0);
03959 }
03960 break;
03961 default:
03962 break;
03963 }
03964 }
03965
03966 if (value != 0 && ! TREE_OVERFLOW (value))
03967 return build_range_check (type,
03968 fold (build2 (MINUS_EXPR, etype, exp, low)),
03969 1, fold_convert (etype, integer_zero_node),
03970 value);
03971
03972 return 0;
03973 }
03974
03975
03976
03977
03978 static int
03979 merge_ranges (int *pin_p, tree *plow, tree *phigh, int in0_p, tree low0,
03980 tree high0, int in1_p, tree low1, tree high1)
03981 {
03982 int no_overlap;
03983 int subset;
03984 int temp;
03985 tree tem;
03986 int in_p;
03987 tree low, high;
03988 int lowequal = ((low0 == 0 && low1 == 0)
03989 || integer_onep (range_binop (EQ_EXPR, integer_type_node,
03990 low0, 0, low1, 0)));
03991 int highequal = ((high0 == 0 && high1 == 0)
03992 || integer_onep (range_binop (EQ_EXPR, integer_type_node,
03993 high0, 1, high1, 1)));
03994
03995
03996
03997 if (integer_onep (range_binop (GT_EXPR, integer_type_node,
03998 low0, 0, low1, 0))
03999 || (lowequal
04000 && integer_onep (range_binop (GT_EXPR, integer_type_node,
04001 high1, 1, high0, 1))))
04002 {
04003 temp = in0_p, in0_p = in1_p, in1_p = temp;
04004 tem = low0, low0 = low1, low1 = tem;
04005 tem = high0, high0 = high1, high1 = tem;
04006 }
04007
04008
04009
04010
04011 no_overlap = integer_onep (range_binop (LT_EXPR, integer_type_node,
04012 high0, 1, low1, 0));
04013 subset = integer_onep (range_binop (LE_EXPR, integer_type_node,
04014 high1, 1, high0, 1));
04015
04016
04017
04018 if (in0_p && in1_p)
04019 {
04020
04021
04022
04023 if (no_overlap)
04024 in_p = 0, low = high = 0;
04025 else if (subset)
04026 in_p = 1, low = low1, high = high1;
04027 else
04028 in_p = 1, low = low1, high = high0;
04029 }
04030
04031 else if (in0_p && ! in1_p)
04032 {
04033
04034
04035
04036
04037
04038
04039
04040
04041 if (no_overlap)
04042 in_p = 1, low = low0, high = high0;
04043 else if (lowequal && highequal)
04044 in_p = 0, low = high = 0;
04045 else if (subset && lowequal)
04046 {
04047 in_p = 1, high = high0;
04048 low = range_binop (PLUS_EXPR, NULL_TREE, high1, 0,
04049 integer_one_node, 0);
04050 }
04051 else if (! subset || highequal)
04052 {
04053 in_p = 1, low = low0;
04054 high = range_binop (MINUS_EXPR, NULL_TREE, low1, 0,
04055 integer_one_node, 0);
04056 }
04057 else
04058 return 0;
04059 }
04060
04061 else if (! in0_p && in1_p)
04062 {
04063
04064
04065
04066
04067 if (no_overlap)
04068 in_p = 1, low = low1, high = high1;
04069 else if (subset || highequal)
04070 in_p = 0, low = high = 0;
04071 else
04072 {
04073 in_p = 1, high = high1;
04074 low = range_binop (PLUS_EXPR, NULL_TREE, high0, 1,
04075 integer_one_node, 0);
04076 }
04077 }
04078
04079 else
04080 {
04081
04082
04083
04084
04085
04086
04087 if (no_overlap)
04088 {
04089 if (integer_onep (range_binop (EQ_EXPR, integer_type_node,
04090 range_binop (PLUS_EXPR, NULL_TREE,
04091 high0, 1,
04092 integer_one_node, 1),
04093 1, low1, 0)))
04094 in_p = 0, low = low0, high = high1;
04095 else
04096 {
04097
04098 if (low0 && TREE_CODE (low0) == INTEGER_CST)
04099 switch (TREE_CODE (TREE_TYPE (low0)))
04100 {
04101 case ENUMERAL_TYPE:
04102 if (TYPE_PRECISION (TREE_TYPE (low0))
04103 != GET_MODE_BITSIZE (TYPE_MODE (TREE_TYPE (low0))))
04104 break;
04105
04106 case INTEGER_TYPE:
04107 case CHAR_TYPE:
04108 if (tree_int_cst_equal (low0,
04109 TYPE_MIN_VALUE (TREE_TYPE (low0))))
04110 low0 = 0;
04111 break;
04112 case POINTER_TYPE:
04113 if (TYPE_UNSIGNED (TREE_TYPE (low0))
04114 && integer_zerop (low0))
04115 low0 = 0;
04116 break;
04117 default:
04118 break;
04119 }
04120
04121
04122 if (high1 && TREE_CODE (high1) == INTEGER_CST)
04123 switch (TREE_CODE (TREE_TYPE (high1)))
04124 {
04125 case ENUMERAL_TYPE:
04126 if (TYPE_PRECISION (TREE_TYPE (high1))
04127 != GET_MODE_BITSIZE (TYPE_MODE (TREE_TYPE (high1))))
04128 break;
04129
04130 case INTEGER_TYPE:
04131 case CHAR_TYPE:
04132 if (tree_int_cst_equal (high1,
04133 TYPE_MAX_VALUE (TREE_TYPE (high1))))
04134 high1 = 0;
04135 break;
04136 case POINTER_TYPE:
04137 if (TYPE_UNSIGNED (TREE_TYPE (high1))
04138 && integer_zerop (range_binop (PLUS_EXPR, NULL_TREE,
04139 high1, 1,
04140 integer_one_node, 1)))
04141 high1 = 0;
04142 break;
04143 default:
04144 break;
04145 }
04146
04147
04148
04149
04150
04151 if (low0 == 0 && high1 == 0)
04152 {
04153 low = range_binop (PLUS_EXPR, NULL_TREE, high0, 1,
04154 integer_one_node, 1);
04155 high = range_binop (MINUS_EXPR, NULL_TREE, low1, 0,
04156 integer_one_node, 0);
04157 if (low == 0 || high == 0)
04158 return 0;
04159
04160 in_p = 1;
04161 }
04162 else
04163 return 0;
04164 }
04165 }
04166 else if (subset)
04167 in_p = 0, low = low0, high = high0;
04168 else
04169 in_p = 0, low = low0, high = high1;
04170 }
04171
04172 *pin_p = in_p, *plow = low, *phigh = high;
04173 return 1;
04174 }
04175
04176
04177
04178
04179
04180
04181
04182
04183
04184
04185 static tree
04186 fold_cond_expr_with_comparison (tree type, tree arg0, tree arg1, tree arg2)
04187 {
04188 enum tree_code comp_code = TREE_CODE (arg0);
04189 tree arg00 = TREE_OPERAND (arg0, 0);
04190 tree arg01 = TREE_OPERAND (arg0, 1);
04191 tree arg1_type = TREE_TYPE (arg1);
04192 tree tem;
04193
04194 STRIP_NOPS (arg1);
04195 STRIP_NOPS (arg2);
04196
04197
04198
04199
04200
04201
04202
04203
04204
04205
04206
04207
04208
04209
04210
04211
04212
04213
04214
04215
04216 if ((FLOAT_TYPE_P (TREE_TYPE (arg01))
04217 ? real_zerop (arg01)
04218 : integer_zerop (arg01))
04219 && TREE_CODE (arg2) == NEGATE_EXPR
04220 && operand_equal_p (TREE_OPERAND (arg2, 0), arg1, 0))
04221 switch (comp_code)
04222 {
04223 case EQ_EXPR:
04224 case UNEQ_EXPR:
04225 tem = fold_convert (arg1_type, arg1);
04226 return pedantic_non_lvalue (fold_convert (type, negate_expr (tem)));
04227 case NE_EXPR:
04228 case LTGT_EXPR:
04229 return pedantic_non_lvalue (fold_convert (type, arg1));
04230 case UNGE_EXPR:
04231 case UNGT_EXPR:
04232 if (flag_trapping_math)
04233 break;
04234
04235 case GE_EXPR:
04236 case GT_EXPR:
04237 if (TYPE_UNSIGNED (TREE_TYPE (arg1)))
04238 arg1 = fold_convert (lang_hooks.types.signed_type
04239 (TREE_TYPE (arg1)), arg1);
04240 tem = fold (build1 (ABS_EXPR, TREE_TYPE (arg1), arg1));
04241 return pedantic_non_lvalue (fold_convert (type, tem));
04242 case UNLE_EXPR:
04243 case UNLT_EXPR:
04244 if (flag_trapping_math)
04245 break;
04246 case LE_EXPR:
04247 case LT_EXPR:
04248 if (TYPE_UNSIGNED (TREE_TYPE (arg1)))
04249 arg1 = fold_convert (lang_hooks.types.signed_type
04250 (TREE_TYPE (arg1)), arg1);
04251 tem = fold (build1 (ABS_EXPR, TREE_TYPE (arg1), arg1));
04252 return negate_expr (fold_convert (type, tem));
04253 default:
04254 gcc_assert (TREE_CODE_CLASS (comp_code) == tcc_comparison);
04255 break;
04256 }
04257
04258
04259
04260
04261
04262
04263 if (integer_zerop (arg01) && integer_zerop (arg2))
04264 {
04265 if (comp_code == NE_EXPR)
04266 return pedantic_non_lvalue (fold_convert (type, arg1));
04267 else if (comp_code == EQ_EXPR)
04268 return fold_convert (type, integer_zero_node);
04269 }
04270
04271
04272
04273
04274
04275
04276
04277
04278
04279
04280
04281
04282
04283
04284
04285
04286
04287
04288
04289
04290
04291
04292
04293
04294
04295
04296
04297 if (operand_equal_for_comparison_p (arg01, arg2, arg00)
04298
04299
04300 && (in_gimple_form
04301 || strcmp (lang_hooks.name, "GNU C++") != 0
04302 || ! maybe_lvalue_p (arg1)
04303 || ! maybe_lvalue_p (arg2)))
04304 {
04305 tree comp_op0 = arg00;
04306 tree comp_op1 = arg01;
04307 tree comp_type = TREE_TYPE (comp_op0);
04308
04309
04310 if (TYPE_MAIN_VARIANT (comp_type) == TYPE_MAIN_VARIANT (type))
04311 {
04312 comp_type = type;
04313 comp_op0 = arg1;
04314 comp_op1 = arg2;
04315 }
04316
04317 switch (comp_code)
04318 {
04319 case EQ_EXPR:
04320 return pedantic_non_lvalue (fold_convert (type, arg2));
04321 case NE_EXPR:
04322 return pedantic_non_lvalue (fold_convert (type, arg1));
04323 case LE_EXPR:
04324 case LT_EXPR:
04325 case UNLE_EXPR:
04326 case UNLT_EXPR:
04327
04328
04329
04330
04331 if (!HONOR_NANS (TYPE_MODE (TREE_TYPE (arg1))))
04332 {
04333 comp_op0 = fold_convert (comp_type, comp_op0);
04334 comp_op1 = fold_convert (comp_type, comp_op1);
04335 tem = (comp_code == LE_EXPR || comp_code == UNLE_EXPR)
04336 ? fold (build2 (MIN_EXPR, comp_type, comp_op0, comp_op1))
04337 : fold (build2 (MIN_EXPR, comp_type, comp_op1, comp_op0));
04338 return pedantic_non_lvalue (fold_convert (type, tem));
04339 }
04340 break;
04341 case GE_EXPR:
04342 case GT_EXPR:
04343 case UNGE_EXPR:
04344 case UNGT_EXPR:
04345 if (!HONOR_NANS (TYPE_MODE (TREE_TYPE (arg1))))
04346 {
04347 comp_op0 = fold_convert (comp_type, comp_op0);
04348 comp_op1 = fold_convert (comp_type, comp_op1);
04349 tem = (comp_code == GE_EXPR || comp_code == UNGE_EXPR)
04350 ? fold (build2 (MAX_EXPR, comp_type, comp_op0, comp_op1))
04351 : fold (build2 (MAX_EXPR, comp_type, comp_op1, comp_op0));
04352 return pedantic_non_lvalue (fold_convert (type, tem));
04353 }
04354 break;
04355 case UNEQ_EXPR:
04356 if (!HONOR_NANS (TYPE_MODE (TREE_TYPE (arg1))))
04357 return pedantic_non_lvalue (fold_convert (type, arg2));
04358 break;
04359 case LTGT_EXPR:
04360 if (!HONOR_NANS (TYPE_MODE (TREE_TYPE (arg1))))
04361 return pedantic_non_lvalue (fold_convert (type, arg1));
04362 break;
04363 default:
04364 gcc_assert (TREE_CODE_CLASS (comp_code) == tcc_comparison);
04365 break;
04366 }
04367 }
04368
04369
04370
04371
04372
04373
04374
04375 if (INTEGRAL_TYPE_P (type)
04376 && TREE_CODE (arg01) == INTEGER_CST
04377 && TREE_CODE (arg2) == INTEGER_CST)
04378 switch (comp_code)
04379 {
04380 case EQ_EXPR:
04381
04382 arg1 = fold_convert (type, arg01);
04383 return fold (build3 (COND_EXPR, type, arg0, arg1, arg2));
04384
04385 case LT_EXPR:
04386
04387 if (! operand_equal_p (arg2, TYPE_MAX_VALUE (type),
04388 OEP_ONLY_CONST)
04389 && operand_equal_p (arg01,
04390 const_binop (PLUS_EXPR, arg2,
04391 integer_one_node, 0),
04392 OEP_ONLY_CONST))
04393 return pedantic_non_lvalue (fold (build2 (MIN_EXPR,
04394 type, arg1, arg2)));
04395 break;
04396
04397 case LE_EXPR:
04398
04399 if (! operand_equal_p (arg2, TYPE_MIN_VALUE (type),
04400 OEP_ONLY_CONST)
04401 && operand_equal_p (arg01,
04402 const_binop (MINUS_EXPR, arg2,
04403 integer_one_node, 0),
04404 OEP_ONLY_CONST))
04405 return pedantic_non_lvalue (fold (build2 (MIN_EXPR,
04406 type, arg1, arg2)));
04407 break;
04408
04409 case GT_EXPR:
04410
04411 if (! operand_equal_p (arg2, TYPE_MIN_VALUE (type),
04412 OEP_ONLY_CONST)
04413 && operand_equal_p (arg01,
04414 const_binop (MINUS_EXPR, arg2,
04415 integer_one_node, 0),
04416 OEP_ONLY_CONST))
04417 return pedantic_non_lvalue (fold (build2 (MAX_EXPR,
04418 type, arg1, arg2)));
04419 break;
04420
04421 case GE_EXPR:
04422
04423 if (! operand_equal_p (arg2, TYPE_MAX_VALUE (type),
04424 OEP_ONLY_CONST)
04425 && operand_equal_p (arg01,
04426 const_binop (PLUS_EXPR, arg2,
04427 integer_one_node, 0),
04428 OEP_ONLY_CONST))
04429 return pedantic_non_lvalue (fold (build2 (MAX_EXPR,
04430 type, arg1, arg2)));
04431 break;
04432 case NE_EXPR:
04433 break;
04434 default:
04435 gcc_unreachable ();
04436 }
04437
04438 return NULL_TREE;
04439 }
04440
04441
04442
04443 #ifndef LOGICAL_OP_NON_SHORT_CIRCUIT
04444 #ifdef KEY // bug 11517
04445 #define LOGICAL_OP_NON_SHORT_CIRCUIT (!flag_spin_file && BRANCH_COST >= 2)
04446 #else
04447 #define LOGICAL_OP_NON_SHORT_CIRCUIT (BRANCH_COST >= 2)
04448 #endif
04449 #endif
04450
04451
04452
04453
04454 static tree
04455 fold_range_test (tree exp)
04456 {
04457 int or_op = (TREE_CODE (exp) == TRUTH_ORIF_EXPR
04458 || TREE_CODE (exp) == TRUTH_OR_EXPR);
04459 int in0_p, in1_p, in_p;
04460 tree low0, low1, low, high0, high1, high;
04461 tree lhs = make_range (TREE_OPERAND (exp, 0), &in0_p, &low0, &high0);
04462 tree rhs = make_range (TREE_OPERAND (exp, 1), &in1_p, &low1, &high1);
04463 tree tem;
04464
04465
04466
04467 if (or_op)
04468 in0_p = ! in0_p, in1_p = ! in1_p;
04469
04470
04471
04472
04473
04474 if ((lhs == 0 || rhs == 0 || operand_equal_p (lhs, rhs, 0))
04475 && merge_ranges (&in_p, &low, &high, in0_p, low0, high0,
04476 in1_p, low1, high1)
04477 && 0 != (tem = (build_range_check (TREE_TYPE (exp),
04478 lhs != 0 ? lhs
04479 : rhs != 0 ? rhs : integer_zero_node,
04480 in_p, low, high))))
04481 return or_op ? invert_truthvalue (tem) : tem;
04482
04483
04484
04485
04486 else if (LOGICAL_OP_NON_SHORT_CIRCUIT
04487 && lhs != 0 && rhs != 0
04488 && (TREE_CODE (exp) == TRUTH_ANDIF_EXPR
04489 || TREE_CODE (exp) == TRUTH_ORIF_EXPR)
04490 && operand_equal_p (lhs, rhs, 0))
04491 {
04492
04493
04494
04495 if (simple_operand_p (lhs))
04496 return build2 (TREE_CODE (exp) == TRUTH_ANDIF_EXPR
04497 ? TRUTH_AND_EXPR : TRUTH_OR_EXPR,
04498 TREE_TYPE (exp), TREE_OPERAND (exp, 0),
04499 TREE_OPERAND (exp, 1));
04500
04501 else if (lang_hooks.decls.global_bindings_p () == 0
04502 && ! CONTAINS_PLACEHOLDER_P (lhs))
04503 {
04504 tree common = save_expr (lhs);
04505
04506 if (0 != (lhs = build_range_check (TREE_TYPE (exp), common,
04507 or_op ? ! in0_p : in0_p,
04508 low0, high0))
04509 && (0 != (rhs = build_range_check (TREE_TYPE (exp), common,
04510 or_op ? ! in1_p : in1_p,
04511 low1, high1))))
04512 return build2 (TREE_CODE (exp) == TRUTH_ANDIF_EXPR
04513 ? TRUTH_AND_EXPR : TRUTH_OR_EXPR,
04514 TREE_TYPE (exp), lhs, rhs);
04515 }
04516 }
04517
04518 return 0;
04519 }
04520
04521
04522
04523
04524
04525
04526 static tree
04527 unextend (tree c, int p, int unsignedp, tree mask)
04528 {
04529 tree type = TREE_TYPE (c);
04530 int modesize = GET_MODE_BITSIZE (TYPE_MODE (type));
04531 tree temp;
04532
04533 if (p == modesize || unsignedp)
04534 return c;
04535
04536
04537
04538
04539 temp = const_binop (RSHIFT_EXPR, c, size_int (p - 1), 0);
04540 temp = const_binop (BIT_AND_EXPR, temp, size_int (1), 0);
04541
04542
04543
04544
04545
04546
04547
04548 if (TYPE_UNSIGNED (type))
04549 temp = fold_convert (lang_hooks.types.signed_type (type), temp);
04550
04551 temp = const_binop (LSHIFT_EXPR, temp, size_int (modesize - 1), 0);
04552 temp = const_binop (RSHIFT_EXPR, temp, size_int (modesize - p - 1), 0);
04553 if (mask != 0)
04554 temp = const_binop (BIT_AND_EXPR, temp,
04555 fold_convert (TREE_TYPE (c), mask), 0);
04556
04557 if (TYPE_UNSIGNED (type))
04558 temp = fold_convert (type, temp);
04559
04560 return fold_convert (type, const_binop (BIT_XOR_EXPR, c, temp, 0));
04561 }
04562
04563
04564
04565
04566
04567
04568
04569
04570
04571
04572
04573
04574
04575
04576
04577
04578
04579
04580
04581
04582
04583
04584
04585
04586
04587 static tree
04588 fold_truthop (enum tree_code code, tree truth_type, tree lhs, tree rhs)
04589 {
04590
04591
04592
04593
04594
04595
04596
04597
04598
04599 enum tree_code wanted_code;
04600 enum tree_code lcode, rcode;
04601 tree ll_arg, lr_arg, rl_arg, rr_arg;
04602 tree ll_inner, lr_inner, rl_inner, rr_inner;
04603 HOST_WIDE_INT ll_bitsize, ll_bitpos, lr_bitsize, lr_bitpos;
04604 HOST_WIDE_INT rl_bitsize, rl_bitpos, rr_bitsize, rr_bitpos;
04605 HOST_WIDE_INT xll_bitpos, xlr_bitpos, xrl_bitpos, xrr_bitpos;
04606 HOST_WIDE_INT lnbitsize, lnbitpos, rnbitsize, rnbitpos;
04607 int ll_unsignedp, lr_unsignedp, rl_unsignedp, rr_unsignedp;
04608 enum machine_mode ll_mode, lr_mode, rl_mode, rr_mode;
04609 enum machine_mode lnmode, rnmode;
04610 tree ll_mask, lr_mask, rl_mask, rr_mask;
04611 tree ll_and_mask, lr_and_mask, rl_and_mask, rr_and_mask;
04612 tree l_const, r_const;
04613 tree lntype, rntype, result;
04614 int first_bit, end_bit;
04615 int volatilep;
04616
04617
04618
04619
04620
04621 if (TREE_SIDE_EFFECTS (lhs) || TREE_SIDE_EFFECTS (rhs))
04622 return 0;
04623
04624 lcode = TREE_CODE (lhs);
04625 rcode = TREE_CODE (rhs);
04626
04627 if (lcode == BIT_AND_EXPR && integer_onep (TREE_OPERAND (lhs, 1)))
04628 {
04629 lhs = build2 (NE_EXPR, truth_type, lhs,
04630 fold_convert (TREE_TYPE (lhs), integer_zero_node));
04631 lcode = NE_EXPR;
04632 }
04633
04634 if (rcode == BIT_AND_EXPR && integer_onep (TREE_OPERAND (rhs, 1)))
04635 {
04636 rhs = build2 (NE_EXPR, truth_type, rhs,
04637 fold_convert (TREE_TYPE (rhs), integer_zero_node));
04638 rcode = NE_EXPR;
04639 }
04640
04641 if (TREE_CODE_CLASS (lcode) != tcc_comparison
04642 || TREE_CODE_CLASS (rcode) != tcc_comparison)
04643 return 0;
04644
04645 ll_arg = TREE_OPERAND (lhs, 0);
04646 lr_arg = TREE_OPERAND (lhs, 1);
04647 rl_arg = TREE_OPERAND (rhs, 0);
04648 rr_arg = TREE_OPERAND (rhs, 1);
04649
04650
04651 if (simple_operand_p (ll_arg)
04652 && simple_operand_p (lr_arg))
04653 {
04654 tree result;
04655 if (operand_equal_p (ll_arg, rl_arg, 0)
04656 && operand_equal_p (lr_arg, rr_arg, 0))
04657 {
04658 result = combine_comparisons (code, lcode, rcode,
04659 truth_type, ll_arg, lr_arg);
04660 if (result)
04661 return result;
04662 }
04663 else if (operand_equal_p (ll_arg, rr_arg, 0)
04664 && operand_equal_p (lr_arg, rl_arg, 0))
04665 {
04666 result = combine_comparisons (code, lcode,
04667 swap_tree_comparison (rcode),
04668 truth_type, ll_arg, lr_arg);
04669 if (result)
04670 return result;
04671 }
04672 }
04673
04674 code = ((code == TRUTH_AND_EXPR || code == TRUTH_ANDIF_EXPR)
04675 ? TRUTH_AND_EXPR : TRUTH_OR_EXPR);
04676
04677
04678
04679
04680
04681
04682
04683 if (BRANCH_COST >= 2
04684 && ! FLOAT_TYPE_P (TREE_TYPE (rl_arg))
04685 && simple_operand_p (rl_arg)
04686 && simple_operand_p (rr_arg))
04687 {
04688
04689 if (code == TRUTH_OR_EXPR
04690 && lcode == NE_EXPR && integer_zerop (lr_arg)
04691 && rcode == NE_EXPR && integer_zerop (rr_arg)
04692 && TREE_TYPE (ll_arg) == TREE_TYPE (rl_arg))
04693 return build2 (NE_EXPR, truth_type,
04694 build2 (BIT_IOR_EXPR, TREE_TYPE (ll_arg),
04695 ll_arg, rl_arg),
04696 fold_convert (TREE_TYPE (ll_arg), integer_zero_node));
04697
04698
04699 if (code == TRUTH_AND_EXPR
04700 && lcode == EQ_EXPR && integer_zerop (lr_arg)
04701 && rcode == EQ_EXPR && integer_zerop (rr_arg)
04702 && TREE_TYPE (ll_arg) == TREE_TYPE (rl_arg))
04703 return build2 (EQ_EXPR, truth_type,
04704 build2 (BIT_IOR_EXPR, TREE_TYPE (ll_arg),
04705 ll_arg, rl_arg),
04706 fold_convert (TREE_TYPE (ll_arg), integer_zero_node));
04707
04708 if (LOGICAL_OP_NON_SHORT_CIRCUIT)
04709 return build2 (code, truth_type, lhs, rhs);
04710 }
04711
04712
04713
04714
04715 if ((lcode != EQ_EXPR && lcode != NE_EXPR)
04716 || (rcode != EQ_EXPR && rcode != NE_EXPR))
04717 return 0;
04718
04719 volatilep = 0;
04720 ll_inner = decode_field_reference (ll_arg,
04721 &ll_bitsize, &ll_bitpos, &ll_mode,
04722 &ll_unsignedp, &volatilep, &ll_mask,
04723 &ll_and_mask);
04724 lr_inner = decode_field_reference (lr_arg,
04725 &lr_bitsize, &lr_bitpos, &lr_mode,
04726 &lr_unsignedp, &volatilep, &lr_mask,
04727 &lr_and_mask);
04728 rl_inner = decode_field_reference (rl_arg,
04729 &rl_bitsize, &rl_bitpos, &rl_mode,
04730 &rl_unsignedp, &volatilep, &rl_mask,
04731 &rl_and_mask);
04732 rr_inner = decode_field_reference (rr_arg,
04733 &rr_bitsize, &rr_bitpos, &rr_mode,
04734 &rr_unsignedp, &volatilep, &rr_mask,
04735 &rr_and_mask);
04736
04737
04738
04739
04740
04741 if (volatilep || ll_inner == 0 || rl_inner == 0
04742 || ! operand_equal_p (ll_inner, rl_inner, 0))
04743 return 0;
04744
04745 if (TREE_CODE (lr_arg) == INTEGER_CST
04746 && TREE_CODE (rr_arg) == INTEGER_CST)
04747 l_const = lr_arg, r_const = rr_arg;
04748 else if (lr_inner == 0 || rr_inner == 0
04749 || ! operand_equal_p (lr_inner, rr_inner, 0))
04750 return 0;
04751 else
04752 l_const = r_const = 0;
04753
04754
04755
04756
04757
04758 wanted_code = (code == TRUTH_AND_EXPR ? EQ_EXPR : NE_EXPR);
04759 if (lcode != wanted_code)
04760 {
04761 if (l_const && integer_zerop (l_const) && integer_pow2p (ll_mask))
04762 {
04763
04764
04765
04766 ll_unsignedp = 1;
04767 l_const = ll_mask;
04768 }
04769 else
04770 return 0;
04771 }
04772
04773
04774 if (rcode != wanted_code)
04775 {
04776 if (r_const && integer_zerop (r_const) && integer_pow2p (rl_mask))
04777 {
04778 rl_unsignedp = 1;
04779 r_const = rl_mask;
04780 }
04781 else
04782 return 0;
04783 }
04784
04785
04786
04787 if (! lang_hooks.can_use_bit_fields_p ())
04788 return 0;
04789
04790
04791
04792
04793 first_bit = MIN (ll_bitpos, rl_bitpos);
04794 end_bit = MAX (ll_bitpos + ll_bitsize, rl_bitpos + rl_bitsize);
04795 lnmode = get_best_mode (end_bit - first_bit, first_bit,
04796 TYPE_ALIGN (TREE_TYPE (ll_inner)), word_mode,
04797 volatilep);
04798 if (lnmode == VOIDmode)
04799 return 0;
04800
04801 lnbitsize = GET_MODE_BITSIZE (lnmode);
04802 lnbitpos = first_bit & ~ (lnbitsize - 1);
04803 lntype = lang_hooks.types.type_for_size (lnbitsize, 1);
04804 xll_bitpos = ll_bitpos - lnbitpos, xrl_bitpos = rl_bitpos - lnbitpos;
04805
04806 if (BYTES_BIG_ENDIAN)
04807 {
04808 xll_bitpos = lnbitsize - xll_bitpos - ll_bitsize;
04809 xrl_bitpos = lnbitsize - xrl_bitpos - rl_bitsize;
04810 }
04811
04812 ll_mask = const_binop (LSHIFT_EXPR, fold_convert (lntype, ll_mask),
04813 size_int (xll_bitpos), 0);
04814 rl_mask = const_binop (LSHIFT_EXPR, fold_convert (lntype, rl_mask),
04815 size_int (xrl_bitpos), 0);
04816
04817 if (l_const)
04818 {
04819 l_const = fold_convert (lntype, l_const);
04820 l_const = unextend (l_const, ll_bitsize, ll_unsignedp, ll_and_mask);
04821 l_const = const_binop (LSHIFT_EXPR, l_const, size_int (xll_bitpos), 0);
04822 if (! integer_zerop (const_binop (BIT_AND_EXPR, l_const,
04823 fold (build1 (BIT_NOT_EXPR,
04824 lntype, ll_mask)),
04825 0)))
04826 {
04827 warning ("comparison is always %d", wanted_code == NE_EXPR);
04828
04829 return constant_boolean_node (wanted_code == NE_EXPR, truth_type);
04830 }
04831 }
04832 if (r_const)
04833 {
04834 r_const = fold_convert (lntype, r_const);
04835 r_const = unextend (r_const, rl_bitsize, rl_unsignedp, rl_and_mask);
04836 r_const = const_binop (LSHIFT_EXPR, r_const, size_int (xrl_bitpos), 0);
04837 if (! integer_zerop (const_binop (BIT_AND_EXPR, r_const,
04838 fold (build1 (BIT_NOT_EXPR,
04839 lntype, rl_mask)),
04840 0)))
04841 {
04842 warning ("comparison is always %d", wanted_code == NE_EXPR);
04843
04844 return constant_boolean_node (wanted_code == NE_EXPR, truth_type);
04845 }
04846 }
04847
04848
04849
04850
04851 if (l_const == 0)
04852 {
04853 if (ll_bitsize != lr_bitsize || rl_bitsize != rr_bitsize
04854 || ll_unsignedp != lr_unsignedp || rl_unsignedp != rr_unsignedp
04855
04856
04857 || ll_bitpos - rl_bitpos != lr_bitpos - rr_bitpos)
04858 return 0;
04859
04860 first_bit = MIN (lr_bitpos, rr_bitpos);
04861 end_bit = MAX (lr_bitpos + lr_bitsize, rr_bitpos + rr_bitsize);
04862 rnmode = get_best_mode (end_bit - first_bit, first_bit,
04863 TYPE_ALIGN (TREE_TYPE (lr_inner)), word_mode,
04864 volatilep);
04865 if (rnmode == VOIDmode)
04866 return 0;
04867
04868 rnbitsize = GET_MODE_BITSIZE (rnmode);
04869 rnbitpos = first_bit & ~ (rnbitsize - 1);
04870 rntype = lang_hooks.types.type_for_size (rnbitsize, 1);
04871 xlr_bitpos = lr_bitpos - rnbitpos, xrr_bitpos = rr_bitpos - rnbitpos;
04872
04873 if (BYTES_BIG_ENDIAN)
04874 {
04875 xlr_bitpos = rnbitsize - xlr_bitpos - lr_bitsize;
04876 xrr_bitpos = rnbitsize - xrr_bitpos - rr_bitsize;
04877 }
04878
04879 lr_mask = const_binop (LSHIFT_EXPR, fold_convert (rntype, lr_mask),
04880 size_int (xlr_bitpos), 0);
04881 rr_mask = const_binop (LSHIFT_EXPR, fold_convert (rntype, rr_mask),
04882 size_int (xrr_bitpos), 0);
04883
04884
04885
04886
04887
04888
04889 ll_mask = const_binop (BIT_IOR_EXPR, ll_mask, rl_mask, 0);
04890 lr_mask = const_binop (BIT_IOR_EXPR, lr_mask, rr_mask, 0);
04891 if (lnbitsize == rnbitsize && xll_bitpos == xlr_bitpos)
04892 {
04893 lhs = make_bit_field_ref (ll_inner, lntype, lnbitsize, lnbitpos,
04894 ll_unsignedp || rl_unsignedp);
04895 if (! all_ones_mask_p (ll_mask, lnbitsize))
04896 lhs = build2 (BIT_AND_EXPR, lntype, lhs, ll_mask);
04897
04898 rhs = make_bit_field_ref (lr_inner, rntype, rnbitsize, rnbitpos,
04899 lr_unsignedp || rr_unsignedp);
04900 if (! all_ones_mask_p (lr_mask, rnbitsize))
04901 rhs = build2 (BIT_AND_EXPR, rntype, rhs, lr_mask);
04902
04903 return build2 (wanted_code, truth_type, lhs, rhs);
04904 }
04905
04906
04907
04908
04909
04910
04911
04912
04913 if ((ll_bitsize + ll_bitpos == rl_bitpos
04914 && lr_bitsize + lr_bitpos == rr_bitpos)
04915 || (ll_bitpos == rl_bitpos + rl_bitsize
04916 && lr_bitpos == rr_bitpos + rr_bitsize))
04917 {
04918 tree type;
04919
04920 lhs = make_bit_field_ref (ll_inner, lntype, ll_bitsize + rl_bitsize,
04921 MIN (ll_bitpos, rl_bitpos), ll_unsignedp);
04922 rhs = make_bit_field_ref (lr_inner, rntype, lr_bitsize + rr_bitsize,
04923 MIN (lr_bitpos, rr_bitpos), lr_unsignedp);
04924
04925 ll_mask = const_binop (RSHIFT_EXPR, ll_mask,
04926 size_int (MIN (xll_bitpos, xrl_bitpos)), 0);
04927 lr_mask = const_binop (RSHIFT_EXPR, lr_mask,
04928 size_int (MIN (xlr_bitpos, xrr_bitpos)), 0);
04929
04930
04931 type = lntype;
04932 if (lntype != rntype)
04933 {
04934 if (lnbitsize > rnbitsize)
04935 {
04936 lhs = fold_convert (rntype, lhs);
04937 ll_mask = fold_convert (rntype, ll_mask);
04938 type = rntype;
04939 }
04940 else if (lnbitsize < rnbitsize)
04941 {
04942 rhs = fold_convert (lntype, rhs);
04943 lr_mask = fold_convert (lntype, lr_mask);
04944 type = lntype;
04945 }
04946 }
04947
04948 if (! all_ones_mask_p (ll_mask, ll_bitsize + rl_bitsize))
04949 lhs = build2 (BIT_AND_EXPR, type, lhs, ll_mask);
04950
04951 if (! all_ones_mask_p (lr_mask, lr_bitsize + rr_bitsize))
04952 rhs = build2 (BIT_AND_EXPR, type, rhs, lr_mask);
04953
04954 return build2 (wanted_code, truth_type, lhs, rhs);
04955 }
04956
04957 return 0;
04958 }
04959
04960
04961
04962
04963
04964 result = const_binop (BIT_AND_EXPR, ll_mask, rl_mask, 0);
04965 if (! integer_zerop (result)
04966 && simple_cst_equal (const_binop (BIT_AND_EXPR, result, l_const, 0),
04967 const_binop (BIT_AND_EXPR, result, r_const, 0)) != 1)
04968 {
04969 if (wanted_code == NE_EXPR)
04970 {
04971 warning ("%<or%> of unmatched not-equal tests is always 1");
04972 return constant_boolean_node (true, truth_type);
04973 }
04974 else
04975 {
04976 warning ("%<and%> of mutually exclusive equal-tests is always 0");
04977 return constant_boolean_node (false, truth_type);
04978 }
04979 }
04980
04981
04982
04983
04984
04985 result = make_bit_field_ref (ll_inner, lntype, lnbitsize, lnbitpos,
04986 ll_unsignedp || rl_unsignedp);
04987
04988 ll_mask = const_binop (BIT_IOR_EXPR, ll_mask, rl_mask, 0);
04989 if (! all_ones_mask_p (ll_mask, lnbitsize))
04990 result = build2 (BIT_AND_EXPR, lntype, result, ll_mask);
04991
04992 return build2 (wanted_code, truth_type, result,
04993 const_binop (BIT_IOR_EXPR, l_const, r_const, 0));
04994 }
04995
04996
04997
04998
04999 static tree
05000 optimize_minmax_comparison (tree t)
05001 {
05002 tree type = TREE_TYPE (t);
05003 tree arg0 = TREE_OPERAND (t, 0);
05004 enum tree_code op_code;
05005 tree comp_const = TREE_OPERAND (t, 1);
05006 tree minmax_const;
05007 int consts_equal, consts_lt;
05008 tree inner;
05009
05010 STRIP_SIGN_NOPS (arg0);
05011
05012 op_code = TREE_CODE (arg0);
05013 minmax_const = TREE_OPERAND (arg0, 1);
05014 consts_equal = tree_int_cst_equal (minmax_const, comp_const);
05015 consts_lt = tree_int_cst_lt (minmax_const, comp_const);
05016 inner = TREE_OPERAND (arg0, 0);
05017
05018
05019 if ((op_code != MIN_EXPR && op_code != MAX_EXPR)
05020 || TREE_CODE (comp_const) != INTEGER_CST
05021 || TREE_CONSTANT_OVERFLOW (comp_const)
05022 || TREE_CODE (minmax_const) != INTEGER_CST
05023 || TREE_CONSTANT_OVERFLOW (minmax_const))
05024 return t;
05025
05026
05027
05028
05029 switch (TREE_CODE (t))
05030 {
05031 case NE_EXPR: case LT_EXPR: case LE_EXPR:
05032 return
05033 invert_truthvalue (optimize_minmax_comparison (invert_truthvalue (t)));
05034
05035 case GE_EXPR:
05036 return
05037 fold (build2 (TRUTH_ORIF_EXPR, type,
05038 optimize_minmax_comparison
05039 (build2 (EQ_EXPR, type, arg0, comp_const)),
05040 optimize_minmax_comparison
05041 (build2 (GT_EXPR, type, arg0, comp_const))));
05042
05043 case EQ_EXPR:
05044 if (op_code == MAX_EXPR && consts_equal)
05045
05046 return fold (build2 (LE_EXPR, type, inner, comp_const));
05047
05048 else if (op_code == MAX_EXPR && consts_lt)
05049
05050 return fold (build2 (EQ_EXPR, type, inner, comp_const));
05051
05052 else if (op_code == MAX_EXPR)
05053
05054 return omit_one_operand (type, integer_zero_node, inner);
05055
05056 else if (consts_equal)
05057
05058 return fold (build2 (GE_EXPR, type, inner, comp_const));
05059
05060 else if (consts_lt)
05061
05062 return omit_one_operand (type, integer_zero_node, inner);
05063
05064 else
05065
05066 return fold (build2 (EQ_EXPR, type, inner, comp_const));
05067
05068 case GT_EXPR:
05069 if (op_code == MAX_EXPR && (consts_equal || consts_lt))
05070
05071
05072 return fold (build2 (GT_EXPR, type, inner, comp_const));
05073
05074 else if (op_code == MAX_EXPR)
05075
05076 return omit_one_operand (type, integer_one_node, inner);
05077
05078 else if (op_code == MIN_EXPR && (consts_equal || consts_lt))
05079
05080
05081 return omit_one_operand (type, integer_zero_node, inner);
05082
05083 else
05084
05085 return fold (build2 (GT_EXPR, type, inner, comp_const));
05086
05087 default:
05088 return t;
05089 }
05090 }
05091
05092
05093
05094
05095
05096
05097
05098
05099
05100
05101
05102
05103
05104
05105
05106
05107
05108
05109
05110 static tree
05111 extract_muldiv (tree t, tree c, enum tree_code code, tree wide_type)
05112 {
05113
05114
05115
05116
05117
05118 static int depth;
05119 tree ret;
05120
05121 if (depth > 3)
05122 return NULL;
05123
05124 depth++;
05125 ret = extract_muldiv_1 (t, c, code, wide_type);
05126 depth--;
05127
05128 return ret;
05129 }
05130
05131 static tree
05132 extract_muldiv_1 (tree t, tree c, enum tree_code code, tree wide_type)
05133 {
05134 tree type = TREE_TYPE (t);
05135 enum tree_code tcode = TREE_CODE (t);
05136 tree ctype = (wide_type != 0 && (GET_MODE_SIZE (TYPE_MODE (wide_type))
05137 > GET_MODE_SIZE (TYPE_MODE (type)))
05138 ? wide_type : type);
05139 tree t1, t2;
05140 int same_p = tcode == code;
05141 tree op0 = NULL_TREE, op1 = NULL_TREE;
05142
05143
05144 if (integer_zerop (c))
05145 return NULL_TREE;
05146
05147 if (TREE_CODE_CLASS (tcode) == tcc_unary)
05148 op0 = TREE_OPERAND (t, 0);
05149
05150 if (TREE_CODE_CLASS (tcode) == tcc_binary)
05151 op0 = TREE_OPERAND (t, 0), op1 = TREE_OPERAND (t, 1);
05152
05153
05154
05155 switch (tcode)
05156 {
05157 case INTEGER_CST:
05158
05159
05160 if (code == MULT_EXPR
05161 || integer_zerop (const_binop (TRUNC_MOD_EXPR, t, c, 0)))
05162 return const_binop (code, fold_convert (ctype, t),
05163 fold_convert (ctype, c), 0);
05164 break;
05165
05166 case CONVERT_EXPR: case NON_LVALUE_EXPR: case NOP_EXPR:
05167
05168 if ((COMPARISON_CLASS_P (op0)
05169 || UNARY_CLASS_P (op0)
05170 || BINARY_CLASS_P (op0)
05171 || EXPRESSION_CLASS_P (op0))
05172
05173
05174 && ((TYPE_UNSIGNED (TREE_TYPE (op0))
05175 && ! (TREE_CODE (TREE_TYPE (op0)) == INTEGER_TYPE
05176 && TYPE_IS_SIZETYPE (TREE_TYPE (op0)))
05177 && (GET_MODE_SIZE (TYPE_MODE (ctype))
05178 > GET_MODE_SIZE (TYPE_MODE (TREE_TYPE (op0)))))
05179
05180
05181 || (GET_MODE_SIZE (TYPE_MODE (type))
05182 < GET_MODE_SIZE (TYPE_MODE (TREE_TYPE (op0))))
05183
05184
05185 || (code != MULT_EXPR
05186 && (TYPE_UNSIGNED (ctype)
05187 != TYPE_UNSIGNED (TREE_TYPE (op0))))))
05188 break;
05189
05190
05191
05192
05193 if ((t2 = fold_convert (TREE_TYPE (op0), c)) != 0
05194 && TREE_CODE (t2) == INTEGER_CST
05195 && ! TREE_CONSTANT_OVERFLOW (t2)
05196 && (0 != (t1 = extract_muldiv (op0, t2, code,
05197 code == MULT_EXPR
05198 ? ctype : NULL_TREE))))
05199 return t1;
05200 break;
05201
05202 case ABS_EXPR:
05203
05204
05205 if (TYPE_UNSIGNED (ctype) && !TYPE_UNSIGNED (type))
05206 {
05207 tree cstype = (*lang_hooks.types.signed_type) (ctype);
05208 if ((t1 = extract_muldiv (op0, c, code, cstype)) != 0)
05209 {
05210 t1 = fold (build1 (tcode, cstype, fold_convert (cstype, t1)));
05211 return fold_convert (ctype, t1);
05212 }
05213 break;
05214 }
05215
05216 if (tree_int_cst_sgn (c) == -1)
05217 break;
05218
05219 case NEGATE_EXPR:
05220 if ((t1 = extract_muldiv (op0, c, code, wide_type)) != 0)
05221 return fold (build1 (tcode, ctype, fold_convert (ctype, t1)));
05222 break;
05223
05224 case MIN_EXPR: case MAX_EXPR:
05225
05226
05227 if (TYPE_UNSIGNED (ctype) != TYPE_UNSIGNED (type))
05228 break;
05229
05230
05231 if ((t1 = extract_muldiv (op0, c, code, wide_type)) != 0
05232 && (t2 = extract_muldiv (op1, c, code, wide_type)) != 0)
05233 {
05234 if (tree_int_cst_sgn (c) < 0)
05235 tcode = (tcode == MIN_EXPR ? MAX_EXPR : MIN_EXPR);
05236
05237 return fold (build2 (tcode, ctype, fold_convert (ctype, t1),
05238 fold_convert (ctype, t2)));
05239 }
05240 break;
05241
05242 case LSHIFT_EXPR: case RSHIFT_EXPR:
05243
05244
05245
05246
05247
05248
05249 if (TREE_CODE (op1) == INTEGER_CST
05250 && (tcode == RSHIFT_EXPR || TYPE_UNSIGNED (TREE_TYPE (op0)))
05251
05252
05253 && TYPE_PRECISION (TREE_TYPE (size_one_node)) > TREE_INT_CST_LOW (op1)
05254 && TREE_INT_CST_HIGH (op1) == 0
05255 && 0 != (t1 = fold_convert (ctype,
05256 const_binop (LSHIFT_EXPR,
05257 size_one_node,
05258 op1, 0)))
05259 && ! TREE_OVERFLOW (t1))
05260 return extract_muldiv (build2 (tcode == LSHIFT_EXPR
05261 ? MULT_EXPR : FLOOR_DIV_EXPR,
05262 ctype, fold_convert (ctype, op0), t1),
05263 c, code, wide_type);
05264 break;
05265
05266 case PLUS_EXPR: case MINUS_EXPR:
05267
05268
05269
05270
05271 t1 = extract_muldiv (op0, c, code, wide_type);
05272 t2 = extract_muldiv (op1, c, code, wide_type);
05273 if (t1 != 0 && t2 != 0
05274 && (code == MULT_EXPR
05275
05276
05277 || (multiple_of_p (ctype, op0, c)
05278 && multiple_of_p (ctype, op1, c))))
05279 return fold (build2 (tcode, ctype, fold_convert (ctype, t1),
05280 fold_convert (ctype, t2)));
05281
05282
05283
05284 if (tcode == MINUS_EXPR)
05285 tcode = PLUS_EXPR, op1 = negate_expr (op1);
05286
05287 if (TREE_CODE (op1) != INTEGER_CST)
05288 break;
05289
05290
05291
05292
05293 if (tree_int_cst_sgn (op1) < 0 || tree_int_cst_sgn (c) < 0)
05294 {
05295 if (code == CEIL_DIV_EXPR)
05296 code = FLOOR_DIV_EXPR;
05297 else if (code == FLOOR_DIV_EXPR)
05298 code = CEIL_DIV_EXPR;
05299 else if (code != MULT_EXPR
05300 && code != CEIL_MOD_EXPR && code != FLOOR_MOD_EXPR)
05301 break;
05302 }
05303
05304
05305
05306 if (code == MULT_EXPR
05307 || integer_zerop (const_binop (TRUNC_MOD_EXPR, op1, c, 0)))
05308 {
05309 op1 = const_binop (code, fold_convert (ctype, op1),
05310 fold_convert (ctype, c), 0);
05311
05312 if (op1 == 0
05313 || (TREE_OVERFLOW (op1) && ! flag_wrapv))
05314 break;
05315 }
05316 else
05317 break;
05318
05319
05320
05321
05322 if (TYPE_UNSIGNED (ctype)
05323 && ! (TREE_CODE (ctype) == INTEGER_TYPE && TYPE_IS_SIZETYPE (ctype))
05324 && ctype != type)
05325 break;
05326
05327
05328
05329 if (t1 != 0 && (TREE_CODE (t1) != code || code == MULT_EXPR))
05330 return fold (build2 (tcode, ctype, fold_convert (ctype, t1), op1));
05331
05332
05333
05334
05335 if (code == MULT_EXPR)
05336 return fold (build2 (tcode, ctype,
05337 fold (build2 (code, ctype,
05338 fold_convert (ctype, op0),
05339 fold_convert (ctype, c))),
05340 op1));
05341
05342 break;
05343
05344 case MULT_EXPR:
05345
05346
05347 if ((code == TRUNC_MOD_EXPR || code == CEIL_MOD_EXPR
05348 || code == FLOOR_MOD_EXPR || code == ROUND_MOD_EXPR)
05349 && TREE_CODE (TREE_OPERAND (t, 1)) == INTEGER_CST
05350 && integer_zerop (const_binop (TRUNC_MOD_EXPR, op1, c, 0)))
05351 return omit_one_operand (type, integer_zero_node, op0);
05352
05353
05354
05355 case TRUNC_DIV_EXPR: case CEIL_DIV_EXPR: case FLOOR_DIV_EXPR:
05356 case ROUND_DIV_EXPR: case EXACT_DIV_EXPR:
05357
05358
05359
05360 if (same_p
05361 && (t1 = extract_muldiv (op0, c, code, wide_type)) != 0)
05362 return fold (build2 (tcode, ctype, fold_convert (ctype, t1),
05363 fold_convert (ctype, op1)));
05364 else if (tcode == MULT_EXPR && code == MULT_EXPR
05365 && (t1 = extract_muldiv (op1, c, code, wide_type)) != 0)
05366 return fold (build2 (tcode, ctype, fold_convert (ctype, op0),
05367 fold_convert (ctype, t1)));
05368 else if (TREE_CODE (op1) != INTEGER_CST)
05369 return 0;
05370
05371
05372
05373 if (tcode == code
05374 && 0 != (t1 = const_binop (MULT_EXPR, fold_convert (ctype, op1),
05375 fold_convert (ctype, c), 0))
05376 && ! TREE_OVERFLOW (t1))
05377 return fold (build2 (tcode, ctype, fold_convert (ctype, op0), t1));
05378
05379
05380
05381
05382
05383
05384
05385
05386
05387 if ((! TYPE_UNSIGNED (ctype)
05388 || (TREE_CODE (ctype) == INTEGER_TYPE && TYPE_IS_SIZETYPE (ctype)))
05389 && ! flag_wrapv
05390 && ((code == MULT_EXPR && tcode == EXACT_DIV_EXPR)
05391 || (tcode == MULT_EXPR
05392 && code != TRUNC_MOD_EXPR && code != CEIL_MOD_EXPR
05393 && code != FLOOR_MOD_EXPR && code != ROUND_MOD_EXPR)))
05394 {
05395 if (integer_zerop (const_binop (TRUNC_MOD_EXPR, op1, c, 0)))
05396 return fold (build2 (tcode, ctype, fold_convert (ctype, op0),
05397 fold_convert (ctype,
05398 const_binop (TRUNC_DIV_EXPR,
05399 op1, c, 0))));
05400 else if (integer_zerop (const_binop (TRUNC_MOD_EXPR, c, op1, 0)))
05401 return fold (build2 (code, ctype, fold_convert (ctype, op0),
05402 fold_convert (ctype,
05403 const_binop (TRUNC_DIV_EXPR,
05404 c, op1, 0))));
05405 }
05406 break;
05407
05408 default:
05409 break;
05410 }
05411
05412 return 0;
05413 }
05414
05415
05416
05417
05418 tree
05419 constant_boolean_node (int value, tree type)
05420 {
05421 if (type == integer_type_node)
05422 return value ? integer_one_node : integer_zero_node;
05423 else if (type == boolean_type_node)
05424 return value ? boolean_true_node : boolean_false_node;
05425 else
05426 return build_int_cst (type, value);
05427 }
05428
05429
05430
05431
05432
05433
05434 static bool
05435 extract_array_ref (tree expr, tree *base, tree *offset)
05436 {
05437
05438
05439 tree inner_expr = expr;
05440 STRIP_NOPS (inner_expr);
05441
05442
05443
05444 if (TREE_CODE (expr) == PLUS_EXPR)
05445 {
05446 tree op0 = TREE_OPERAND (expr, 0);
05447 STRIP_NOPS (op0);
05448 if (TREE_CODE (op0) == ADDR_EXPR)
05449 {
05450 *base = TREE_OPERAND (expr, 0);
05451 *offset = TREE_OPERAND (expr, 1);
05452 return true;
05453 }
05454 }
05455
05456
05457
05458
05459
05460 else if (TREE_CODE (inner_expr) == ADDR_EXPR)
05461 {
05462 tree op0 = TREE_OPERAND (inner_expr, 0);
05463 if (TREE_CODE (op0) == ARRAY_REF)
05464 {
05465 *base = build_fold_addr_expr (TREE_OPERAND (op0, 0));
05466 *offset = TREE_OPERAND (op0, 1);
05467 }
05468 else
05469 {
05470 *base = inner_expr;
05471 *offset = NULL_TREE;
05472 }
05473 return true;
05474 }
05475
05476 return false;
05477 }
05478
05479
05480
05481
05482
05483
05484
05485
05486
05487
05488
05489 static tree
05490 fold_binary_op_with_conditional_arg (tree t, enum tree_code code, tree cond,
05491 tree arg, int cond_first_p)
05492 {
05493 const tree type = TREE_TYPE (t);
05494 tree cond_type = cond_first_p ? TREE_TYPE (TREE_OPERAND (t, 0))
05495 : TREE_TYPE (TREE_OPERAND (t, 1));
05496 tree arg_type = cond_first_p ? TREE_TYPE (TREE_OPERAND (t, 1))
05497 : TREE_TYPE (TREE_OPERAND (t, 0));
05498 tree test, true_value, false_value;
05499 tree lhs = NULL_TREE;
05500 tree rhs = NULL_TREE;
05501
05502
05503
05504
05505 if (!TREE_CONSTANT (arg))
05506 return NULL_TREE;
05507
05508 if (TREE_CODE (cond) == COND_EXPR)
05509 {
05510 test = TREE_OPERAND (cond, 0);
05511 true_value = TREE_OPERAND (cond, 1);
05512 false_value = TREE_OPERAND (cond, 2);
05513
05514
05515
05516 if (VOID_TYPE_P (TREE_TYPE (true_value)))
05517 lhs = true_value;
05518 if (VOID_TYPE_P (TREE_TYPE (false_value)))
05519 rhs = false_value;
05520 }
05521 else
05522 {
05523 tree testtype = TREE_TYPE (cond);
05524 test = cond;
05525 true_value = constant_boolean_node (true, testtype);
05526 false_value = constant_boolean_node (false, testtype);
05527 }
05528
05529 arg = fold_convert (arg_type, arg);
05530 if (lhs == 0)
05531 {
05532 true_value = fold_convert (cond_type, true_value);
05533 lhs = fold (cond_first_p ? build2 (code, type, true_value, arg)
05534 : build2 (code, type, arg, true_value));
05535 }
05536 if (rhs == 0)
05537 {
05538 false_value = fold_convert (cond_type, false_value);
05539 rhs = fold (cond_first_p ? build2 (code, type, false_value, arg)
05540 : build2 (code, type, arg, false_value));
05541 }
05542
05543 test = fold (build3 (COND_EXPR, type, test, lhs, rhs));
05544 return fold_convert (type, test);
05545 }
05546
05547
05548
05549
05550
05551
05552
05553
05554
05555
05556
05557
05558
05559
05560 static bool
05561 fold_real_zero_addition_p (tree type, tree addend, int negate)
05562 {
05563 if (!real_zerop (addend))
05564 return false;
05565
05566
05567 if (HONOR_SNANS (TYPE_MODE (type)))
05568 return false;
05569
05570
05571 if (!HONOR_SIGNED_ZEROS (TYPE_MODE (type)))
05572 return true;
05573
05574
05575 if (TREE_CODE (addend) == REAL_CST
05576 && REAL_VALUE_MINUS_ZERO (TREE_REAL_CST (addend)))
05577 negate = !negate;
05578
05579
05580
05581
05582
05583 return negate && !HONOR_SIGN_DEPENDENT_ROUNDING (TYPE_MODE (type));
05584 }
05585
05586
05587
05588
05589
05590
05591
05592
05593
05594
05595
05596
05597 static tree
05598 fold_mathfn_compare (enum built_in_function fcode, enum tree_code code,
05599 tree type, tree arg0, tree arg1)
05600 {
05601 REAL_VALUE_TYPE c;
05602
05603 if (BUILTIN_SQRT_P (fcode))
05604 {
05605 tree arg = TREE_VALUE (TREE_OPERAND (arg0, 1));
05606 enum machine_mode mode = TYPE_MODE (TREE_TYPE (arg0));
05607
05608 c = TREE_REAL_CST (arg1);
05609 if (REAL_VALUE_NEGATIVE (c))
05610 {
05611
05612 if (code == EQ_EXPR || code == LT_EXPR || code == LE_EXPR)
05613 return omit_one_operand (type, integer_zero_node, arg);
05614
05615
05616
05617 if (code == NE_EXPR || !HONOR_NANS (mode))
05618 return omit_one_operand (type, integer_one_node, arg);
05619
05620
05621 return fold (build2 (GE_EXPR, type, arg,
05622 build_real (TREE_TYPE (arg), dconst0)));
05623 }
05624 else if (code == GT_EXPR || code == GE_EXPR)
05625 {
05626 REAL_VALUE_TYPE c2;
05627
05628 REAL_ARITHMETIC (c2, MULT_EXPR, c, c);
05629 real_convert (&c2, mode, &c2);
05630
05631 if (REAL_VALUE_ISINF (c2))
05632 {
05633
05634 if (HONOR_INFINITIES (mode))
05635 return fold (build2 (EQ_EXPR, type, arg,
05636 build_real (TREE_TYPE (arg), c2)));
05637
05638
05639
05640 return omit_one_operand (type, integer_zero_node, arg);
05641 }
05642
05643
05644 return fold (build2 (code, type, arg,
05645 build_real (TREE_TYPE (arg), c2)));
05646 }
05647 else if (code == LT_EXPR || code == LE_EXPR)
05648 {
05649 REAL_VALUE_TYPE c2;
05650
05651 REAL_ARITHMETIC (c2, MULT_EXPR, c, c);
05652 real_convert (&c2, mode, &c2);
05653
05654 if (REAL_VALUE_ISINF (c2))
05655 {
05656
05657
05658 if (! HONOR_NANS (mode) && ! HONOR_INFINITIES (mode))
05659 return omit_one_operand (type, integer_one_node, arg);
05660
05661
05662
05663 if (! HONOR_NANS (mode))
05664 return fold (build2 (NE_EXPR, type, arg,
05665 build_real (TREE_TYPE (arg), c2)));
05666
05667
05668
05669 if (! HONOR_INFINITIES (mode))
05670 return fold (build2 (GE_EXPR, type, arg,
05671 build_real (TREE_TYPE (arg), dconst0)));
05672
05673
05674 if (lang_hooks.decls.global_bindings_p () != 0
05675 || CONTAINS_PLACEHOLDER_P (arg))
05676 return NULL_TREE;
05677
05678 arg = save_expr (arg);
05679 return fold (build2 (TRUTH_ANDIF_EXPR, type,
05680 fold (build2 (GE_EXPR, type, arg,
05681 build_real (TREE_TYPE (arg),
05682 dconst0))),
05683 fold (build2 (NE_EXPR, type, arg,
05684 build_real (TREE_TYPE (arg),
05685 c2)))));
05686 }
05687
05688
05689 if (! HONOR_NANS (mode))
05690 return fold (build2 (code, type, arg,
05691 build_real (TREE_TYPE (arg), c2)));
05692
05693
05694 if (lang_hooks.decls.global_bindings_p () == 0
05695 && ! CONTAINS_PLACEHOLDER_P (arg))
05696 {
05697 arg = save_expr (arg);
05698 return fold (build2 (TRUTH_ANDIF_EXPR, type,
05699 fold (build2 (GE_EXPR, type, arg,
05700 build_real (TREE_TYPE (arg),
05701 dconst0))),
05702 fold (build2 (code, type, arg,
05703 build_real (TREE_TYPE (arg),
05704 c2)))));
05705 }
05706 }
05707 }
05708
05709 return NULL_TREE;
05710 }
05711
05712
05713
05714
05715
05716
05717
05718
05719
05720
05721
05722 static tree
05723 fold_inf_compare (enum tree_code code, tree type, tree arg0, tree arg1)
05724 {
05725 enum machine_mode mode;
05726 REAL_VALUE_TYPE max;
05727 tree temp;
05728 bool neg;
05729
05730 mode = TYPE_MODE (TREE_TYPE (arg0));
05731
05732
05733 neg = REAL_VALUE_NEGATIVE (TREE_REAL_CST (arg1));
05734 if (neg)
05735 code = swap_tree_comparison (code);
05736
05737 switch (code)
05738 {
05739 case GT_EXPR:
05740
05741 if (HONOR_SNANS (mode))
05742 return NULL_TREE;
05743 return omit_one_operand (type, integer_zero_node, arg0);
05744
05745 case LE_EXPR:
05746
05747 if (! HONOR_NANS (mode))
05748 return omit_one_operand (type, integer_one_node, arg0);
05749
05750
05751 if (lang_hooks.decls.global_bindings_p () == 0
05752 && ! CONTAINS_PLACEHOLDER_P (arg0))
05753 {
05754 arg0 = save_expr (arg0);
05755 return fold (build2 (EQ_EXPR, type, arg0, arg0));
05756 }
05757 break;
05758
05759 case EQ_EXPR:
05760 case GE_EXPR:
05761
05762 real_maxval (&max, neg, mode);
05763 return fold (build2 (neg ? LT_EXPR : GT_EXPR, type,
05764 arg0, build_real (TREE_TYPE (arg0), max)));
05765
05766 case LT_EXPR:
05767
05768 real_maxval (&max, neg, mode);
05769 return fold (build2 (neg ? GE_EXPR : LE_EXPR, type,
05770 arg0, build_real (TREE_TYPE (arg0), max)));
05771
05772 case NE_EXPR:
05773
05774 real_maxval (&max, neg, mode);
05775 if (! HONOR_NANS (mode))
05776 return fold (build2 (neg ? GE_EXPR : LE_EXPR, type,
05777 arg0, build_real (TREE_TYPE (arg0), max)));
05778
05779
05780
05781 if (in_gimple_form)
05782 return NULL_TREE;
05783
05784 temp = fold (build2 (neg ? LT_EXPR : GT_EXPR, type,
05785 arg0, build_real (TREE_TYPE (arg0), max)));
05786 return fold (build1 (TRUTH_NOT_EXPR, type, temp));
05787
05788 default:
05789 break;
05790 }
05791
05792 return NULL_TREE;
05793 }
05794
05795
05796
05797
05798
05799
05800
05801
05802
05803
05804
05805
05806 static tree
05807 fold_div_compare (enum tree_code code, tree type, tree arg0, tree arg1)
05808 {
05809 tree prod, tmp, hi, lo;
05810 tree arg00 = TREE_OPERAND (arg0, 0);
05811 tree arg01 = TREE_OPERAND (arg0, 1);
05812 unsigned HOST_WIDE_INT lpart;
05813 HOST_WIDE_INT hpart;
05814 int overflow;
05815
05816
05817
05818 overflow = mul_double (TREE_INT_CST_LOW (arg01),
05819 TREE_INT_CST_HIGH (arg01),
05820 TREE_INT_CST_LOW (arg1),
05821 TREE_INT_CST_HIGH (arg1), &lpart, &hpart);
05822 prod = build_int_cst_wide (TREE_TYPE (arg00), lpart, hpart);
05823 prod = force_fit_type (prod, -1, overflow, false);
05824
05825 if (TYPE_UNSIGNED (TREE_TYPE (arg0)))
05826 {
05827 tmp = int_const_binop (MINUS_EXPR, arg01, integer_one_node, 0);
05828 lo = prod;
05829
05830
05831 overflow = add_double (TREE_INT_CST_LOW (prod),
05832 TREE_INT_CST_HIGH (prod),
05833 TREE_INT_CST_LOW (tmp),
05834 TREE_INT_CST_HIGH (tmp),
05835 &lpart, &hpart);
05836 hi = build_int_cst_wide (TREE_TYPE (arg00), lpart, hpart);
05837 hi = force_fit_type (hi, -1, overflow | TREE_OVERFLOW (prod),
05838 TREE_CONSTANT_OVERFLOW (prod));
05839 }
05840 else if (tree_int_cst_sgn (arg01) >= 0)
05841 {
05842 tmp = int_const_binop (MINUS_EXPR, arg01, integer_one_node, 0);
05843 switch (tree_int_cst_sgn (arg1))
05844 {
05845 case -1:
05846 lo = int_const_binop (MINUS_EXPR, prod, tmp, 0);
05847 hi = prod;
05848 break;
05849
05850 case 0:
05851 lo = fold_negate_const (tmp, TREE_TYPE (arg0));
05852 hi = tmp;
05853 break;
05854
05855 case 1:
05856 hi = int_const_binop (PLUS_EXPR, prod, tmp, 0);
05857 lo = prod;
05858 break;
05859
05860 default:
05861 gcc_unreachable ();
05862 }
05863 }
05864 else
05865 {
05866
05867 code = swap_tree_comparison (code);
05868
05869 tmp = int_const_binop (PLUS_EXPR, arg01, integer_one_node, 0);
05870 switch (tree_int_cst_sgn (arg1))
05871 {
05872 case -1:
05873 hi = int_const_binop (MINUS_EXPR, prod, tmp, 0);
05874 lo = prod;
05875 break;
05876
05877 case 0:
05878 hi = fold_negate_const (tmp, TREE_TYPE (arg0));
05879 lo = tmp;
05880 break;
05881
05882 case 1:
05883 lo = int_const_binop (PLUS_EXPR, prod, tmp, 0);
05884 hi = prod;
05885 break;
05886
05887 default:
05888 gcc_unreachable ();
05889 }
05890 }
05891
05892 switch (code)
05893 {
05894 case EQ_EXPR:
05895 if (TREE_OVERFLOW (lo) && TREE_OVERFLOW (hi))
05896 return omit_one_operand (type, integer_zero_node, arg00);
05897 if (TREE_OVERFLOW (hi))
05898 return fold (build2 (GE_EXPR, type, arg00, lo));
05899 if (TREE_OVERFLOW (lo))
05900 return fold (build2 (LE_EXPR, type, arg00, hi));
05901 return build_range_check (type, arg00, 1, lo, hi);
05902
05903 case NE_EXPR:
05904 if (TREE_OVERFLOW (lo) && TREE_OVERFLOW (hi))
05905 return omit_one_operand (type, integer_one_node, arg00);
05906 if (TREE_OVERFLOW (hi))
05907 return fold (build2 (LT_EXPR, type, arg00, lo));
05908 if (TREE_OVERFLOW (lo))
05909 return fold (build2 (GT_EXPR, type, arg00, hi));
05910 return build_range_check (type, arg00, 0, lo, hi);
05911
05912 case LT_EXPR:
05913 if (TREE_OVERFLOW (lo))
05914 return omit_one_operand (type, integer_zero_node, arg00);
05915 return fold (build2 (LT_EXPR, type, arg00, lo));
05916
05917 case LE_EXPR:
05918 if (TREE_OVERFLOW (hi))
05919 return omit_one_operand (type, integer_one_node, arg00);
05920 return fold (build2 (LE_EXPR, type, arg00, hi));
05921
05922 case GT_EXPR:
05923 if (TREE_OVERFLOW (hi))
05924 return omit_one_operand (type, integer_zero_node, arg00);
05925 return fold (build2 (GT_EXPR, type, arg00, hi));
05926
05927 case GE_EXPR:
05928 if (TREE_OVERFLOW (lo))
05929 return omit_one_operand (type, integer_one_node, arg00);
05930 return fold (build2 (GE_EXPR, type, arg00, lo));
05931
05932 default:
05933 break;
05934 }
05935
05936 return NULL_TREE;
05937 }
05938
05939
05940
05941
05942
05943
05944
05945 tree
05946 fold_single_bit_test (enum tree_code code, tree arg0, tree arg1,
05947 tree result_type)
05948 {
05949
05950 if ((code == NE_EXPR || code == EQ_EXPR)
05951 && TREE_CODE (arg0) == BIT_AND_EXPR && integer_zerop (arg1)
05952 && integer_pow2p (TREE_OPERAND (arg0, 1)))
05953 {
05954 tree inner = TREE_OPERAND (arg0, 0);
05955 tree type = TREE_TYPE (arg0);
05956 int bitnum = tree_log2 (TREE_OPERAND (arg0, 1));
05957 enum machine_mode operand_mode = TYPE_MODE (type);
05958 int ops_unsigned;
05959 tree signed_type, unsigned_type, intermediate_type;
05960 tree arg00;
05961
05962
05963
05964 arg00 = sign_bit_p (TREE_OPERAND (arg0, 0), TREE_OPERAND (arg0, 1));
05965 if (arg00 != NULL_TREE
05966
05967
05968 && TYPE_PRECISION (TREE_TYPE (arg00))
05969 == GET_MODE_BITSIZE (TYPE_MODE (TREE_TYPE (arg00))))
05970 {
05971 tree stype = lang_hooks.types.signed_type (TREE_TYPE (arg00));
05972 return fold (build2 (code == EQ_EXPR ? GE_EXPR : LT_EXPR,
05973 result_type, fold_convert (stype, arg00),
05974 fold_convert (stype, integer_zero_node)));
05975 }
05976
05977
05978
05979
05980
05981
05982
05983 if (TREE_CODE (inner) == RSHIFT_EXPR
05984 && TREE_CODE (TREE_OPERAND (inner, 1)) == INTEGER_CST
05985 && TREE_INT_CST_HIGH (TREE_OPERAND (inner, 1)) == 0
05986 && bitnum < TYPE_PRECISION (type)
05987 && 0 > compare_tree_int (TREE_OPERAND (inner, 1),
05988 bitnum - TYPE_PRECISION (type)))
05989 {
05990 bitnum += TREE_INT_CST_LOW (TREE_OPERAND (inner, 1));
05991 inner = TREE_OPERAND (inner, 0);
05992 }
05993
05994
05995
05996
05997 #ifdef LOAD_EXTEND_OP
05998 ops_unsigned = (LOAD_EXTEND_OP (operand_mode) == SIGN_EXTEND
05999 && !flag_syntax_only) ? 0 : 1;
06000 #else
06001 ops_unsigned = 1;
06002 #endif
06003
06004 signed_type = lang_hooks.types.type_for_mode (operand_mode, 0);
06005 unsigned_type = lang_hooks.types.type_for_mode (operand_mode, 1);
06006 intermediate_type = ops_unsigned ? unsigned_type : signed_type;
06007 inner = fold_convert (intermediate_type, inner);
06008
06009 if (bitnum != 0)
06010 inner = build2 (RSHIFT_EXPR, intermediate_type,
06011 inner, size_int (bitnum));
06012
06013 if (code == EQ_EXPR)
06014 inner = fold (build2 (BIT_XOR_EXPR, intermediate_type,
06015 inner, integer_one_node));
06016
06017
06018 inner = build2 (BIT_AND_EXPR, intermediate_type,
06019 inner, integer_one_node);
06020
06021
06022 inner = fold_convert (result_type, inner);
06023
06024 return inner;
06025 }
06026 return NULL_TREE;
06027 }
06028
06029
06030
06031
06032 static bool
06033 reorder_operands_p (tree arg0, tree arg1)
06034 {
06035 if (! flag_evaluation_order)
06036 return true;
06037 if (TREE_CONSTANT (arg0) || TREE_CONSTANT (arg1))
06038 return true;
06039 return ! TREE_SIDE_EFFECTS (arg0)
06040 && ! TREE_SIDE_EFFECTS (arg1);
06041 }
06042
06043
06044
06045
06046
06047
06048 bool
06049 tree_swap_operands_p (tree arg0, tree arg1, bool reorder)
06050 {
06051 STRIP_SIGN_NOPS (arg0);
06052 STRIP_SIGN_NOPS (arg1);
06053
06054 if (TREE_CODE (arg1) == INTEGER_CST)
06055 return 0;
06056 if (TREE_CODE (arg0) == INTEGER_CST)
06057 return 1;
06058
06059 if (TREE_CODE (arg1) == REAL_CST)
06060 return 0;
06061 if (TREE_CODE (arg0) == REAL_CST)
06062 return 1;
06063
06064 if (TREE_CODE (arg1) == COMPLEX_CST)
06065 return 0;
06066 if (TREE_CODE (arg0) == COMPLEX_CST)
06067 return 1;
06068
06069 if (TREE_CONSTANT (arg1))
06070 return 0;
06071 if (TREE_CONSTANT (arg0))
06072 return 1;
06073
06074 if (optimize_size)
06075 return 0;
06076
06077 if (reorder && flag_evaluation_order
06078 && (TREE_SIDE_EFFECTS (arg0) || TREE_SIDE_EFFECTS (arg1)))
06079 return 0;
06080
06081 if (DECL_P (arg1))
06082 return 0;
06083 if (DECL_P (arg0))
06084 return 1;
06085
06086
06087
06088
06089
06090 if (TREE_CODE (arg0) == SSA_NAME
06091 && TREE_CODE (arg1) == SSA_NAME
06092 && SSA_NAME_VERSION (arg0) > SSA_NAME_VERSION (arg1))
06093 return 1;
06094
06095 return 0;
06096 }
06097
06098
06099
06100
06101 static tree
06102 fold_widened_comparison (enum tree_code code, tree type, tree arg0, tree arg1)
06103 {
06104 tree arg0_unw = get_unwidened (arg0, NULL_TREE);
06105 tree arg1_unw;
06106 tree shorter_type, outer_type;
06107 tree min, max;
06108 bool above, below;
06109
06110 if (arg0_unw == arg0)
06111 return NULL_TREE;
06112 shorter_type = TREE_TYPE (arg0_unw);
06113
06114 #ifdef HAVE_canonicalize_funcptr_for_compare
06115
06116
06117 if (HAVE_canonicalize_funcptr_for_compare
06118 && TREE_CODE (shorter_type) == POINTER_TYPE
06119 && TREE_CODE (TREE_TYPE (shorter_type)) == FUNCTION_TYPE)
06120 return NULL_TREE;
06121 #endif
06122
06123 if (TYPE_PRECISION (TREE_TYPE (arg0)) <= TYPE_PRECISION (shorter_type))
06124 return NULL_TREE;
06125
06126 arg1_unw = get_unwidened (arg1, shorter_type);
06127 if (!arg1_unw)
06128 return NULL_TREE;
06129
06130
06131 if ((code == EQ_EXPR || code == NE_EXPR
06132 || TYPE_UNSIGNED (TREE_TYPE (arg0)) == TYPE_UNSIGNED (shorter_type))
06133 && (TREE_TYPE (arg1_unw) == shorter_type
06134 || (TREE_CODE (arg1_unw) == INTEGER_CST
06135 && TREE_CODE (shorter_type) == INTEGER_TYPE
06136 && int_fits_type_p (arg1_unw, shorter_type))))
06137 return fold (build (code, type, arg0_unw,
06138 fold_convert (shorter_type, arg1_unw)));
06139
06140 if (TREE_CODE (arg1_unw) != INTEGER_CST)
06141 return NULL_TREE;
06142
06143
06144
06145 outer_type = TREE_TYPE (arg1_unw);
06146 min = lower_bound_in_type (outer_type, shorter_type);
06147 max = upper_bound_in_type (outer_type, shorter_type);
06148
06149 above = integer_nonzerop (fold_relational_const (LT_EXPR, type,
06150 max, arg1_unw));
06151 below = integer_nonzerop (fold_relational_const (LT_EXPR, type,
06152 arg1_unw, min));
06153
06154 switch (code)
06155 {
06156 case EQ_EXPR:
06157 if (above || below)
06158 return omit_one_operand (type, integer_zero_node, arg0);
06159 break;
06160
06161 case NE_EXPR:
06162 if (above || below)
06163 return omit_one_operand (type, integer_one_node, arg0);
06164 break;
06165
06166 case LT_EXPR:
06167 case LE_EXPR:
06168 if (above)
06169 return omit_one_operand (type, integer_one_node, arg0);
06170 else if (below)
06171 return omit_one_operand (type, integer_zero_node, arg0);
06172
06173 case GT_EXPR:
06174 case GE_EXPR:
06175 if (above)
06176 return omit_one_operand (type, integer_zero_node, arg0);
06177 else if (below)
06178 return omit_one_operand (type, integer_one_node, arg0);
06179
06180 default:
06181 break;
06182 }
06183
06184 return NULL_TREE;
06185 }
06186
06187
06188
06189
06190 static tree
06191 fold_sign_changed_comparison (enum tree_code code, tree type,
06192 tree arg0, tree arg1)
06193 {
06194 tree arg0_inner, tmp;
06195 tree inner_type, outer_type;
06196
06197 if (TREE_CODE (arg0) != NOP_EXPR
06198 && TREE_CODE (arg0) != CONVERT_EXPR)
06199 return NULL_TREE;
06200
06201 outer_type = TREE_TYPE (arg0);
06202 arg0_inner = TREE_OPERAND (arg0, 0);
06203 inner_type = TREE_TYPE (arg0_inner);
06204
06205 #ifdef HAVE_canonicalize_funcptr_for_compare
06206
06207
06208 if (HAVE_canonicalize_funcptr_for_compare
06209 && TREE_CODE (inner_type) == POINTER_TYPE
06210 && TREE_CODE (TREE_TYPE (inner_type)) == FUNCTION_TYPE)
06211 return NULL_TREE;
06212 #endif
06213
06214 if (TYPE_PRECISION (inner_type) != TYPE_PRECISION (outer_type))
06215 return NULL_TREE;
06216
06217 if (TREE_CODE (arg1) != INTEGER_CST
06218 && !((TREE_CODE (arg1) == NOP_EXPR
06219 || TREE_CODE (arg1) == CONVERT_EXPR)
06220 && TREE_TYPE (TREE_OPERAND (arg1, 0)) == inner_type))
06221 return NULL_TREE;
06222
06223 if (TYPE_UNSIGNED (inner_type) != TYPE_UNSIGNED (outer_type)
06224 && code != NE_EXPR
06225 && code != EQ_EXPR)
06226 return NULL_TREE;
06227
06228 if (TREE_CODE (arg1) == INTEGER_CST)
06229 {
06230 tmp = build_int_cst_wide (inner_type,
06231 TREE_INT_CST_LOW (arg1),
06232 TREE_INT_CST_HIGH (arg1));
06233 arg1 = force_fit_type (tmp, 0,
06234 TREE_OVERFLOW (arg1),
06235 TREE_CONSTANT_OVERFLOW (arg1));
06236 }
06237 else
06238 arg1 = fold_convert (inner_type, arg1);
06239
06240 return fold (build2 (code, type, arg0_inner, arg1));
06241 }
06242
06243
06244
06245
06246
06247
06248 static tree
06249 try_move_mult_to_index (enum tree_code code, tree addr, tree mult)
06250 {
06251 tree s, delta, step;
06252 tree arg0 = TREE_OPERAND (mult, 0), arg1 = TREE_OPERAND (mult, 1);
06253 tree ref = TREE_OPERAND (addr, 0), pref;
06254 tree ret, pos;
06255 tree itype;
06256
06257 STRIP_NOPS (arg0);
06258 STRIP_NOPS (arg1);
06259
06260 if (TREE_CODE (arg0) == INTEGER_CST)
06261 {
06262 s = arg0;
06263 delta = arg1;
06264 }
06265 else if (TREE_CODE (arg1) == INTEGER_CST)
06266 {
06267 s = arg1;
06268 delta = arg0;
06269 }
06270 else
06271 return NULL_TREE;
06272
06273 for (;; ref = TREE_OPERAND (ref, 0))
06274 {
06275 if (TREE_CODE (ref) == ARRAY_REF)
06276 {
06277 step = array_ref_element_size (ref);
06278
06279 if (TREE_CODE (step) != INTEGER_CST)
06280 continue;
06281
06282 itype = TREE_TYPE (step);
06283
06284
06285
06286 if (TYPE_PRECISION (itype) != TYPE_PRECISION (TREE_TYPE (s)))
06287 continue;
06288
06289 if (!operand_equal_p (step, fold_convert (itype, s), 0))
06290 continue;
06291
06292 delta = fold_convert (itype, delta);
06293 break;
06294 }
06295
06296 if (!handled_component_p (ref))
06297 return NULL_TREE;
06298 }
06299
06300
06301
06302
06303 pref = TREE_OPERAND (addr, 0);
06304 ret = copy_node (pref);
06305 pos = ret;
06306
06307 while (pref != ref)
06308 {
06309 pref = TREE_OPERAND (pref, 0);
06310 TREE_OPERAND (pos, 0) = copy_node (pref);
06311 pos = TREE_OPERAND (pos, 0);
06312 }
06313
06314 TREE_OPERAND (pos, 1) = fold (build2 (code, itype,
06315 TREE_OPERAND (pos, 1),
06316 delta));
06317
06318 return build1 (ADDR_EXPR, TREE_TYPE (addr), ret);
06319 }
06320
06321
06322
06323
06324
06325
06326 static tree
06327 fold_to_nonsharp_ineq_using_bound (tree ineq, tree bound)
06328 {
06329 tree a, typea, type = TREE_TYPE (ineq), a1, diff, y;
06330
06331 if (TREE_CODE (bound) == LT_EXPR)
06332 a = TREE_OPERAND (bound, 0);
06333 else if (TREE_CODE (bound) == GT_EXPR)
06334 a = TREE_OPERAND (bound, 1);
06335 else
06336 return NULL_TREE;
06337
06338 typea = TREE_TYPE (a);
06339 if (!INTEGRAL_TYPE_P (typea)
06340 && !POINTER_TYPE_P (typea))
06341 return NULL_TREE;
06342
06343 if (TREE_CODE (ineq) == LT_EXPR)
06344 {
06345 a1 = TREE_OPERAND (ineq, 1);
06346 y = TREE_OPERAND (ineq, 0);
06347 }
06348 else if (TREE_CODE (ineq) == GT_EXPR)
06349 {
06350 a1 = TREE_OPERAND (ineq, 0);
06351 y = TREE_OPERAND (ineq, 1);
06352 }
06353 else
06354 return NULL_TREE;
06355
06356 if (TREE_TYPE (a1) != typea)
06357 return NULL_TREE;
06358
06359 diff = fold (build2 (MINUS_EXPR, typea, a1, a));
06360 if (!integer_onep (diff))
06361 return NULL_TREE;
06362
06363 return fold (build2 (GE_EXPR, type, a, y));
06364 }
06365
06366
06367
06368
06369
06370 static tree
06371 fold_complex_add (tree type, tree ac, tree bc, enum tree_code code)
06372 {
06373 tree ar, ai, br, bi, rr, ri, inner_type;
06374
06375 if (TREE_CODE (ac) == COMPLEX_EXPR)
06376 ar = TREE_OPERAND (ac, 0), ai = TREE_OPERAND (ac, 1);
06377 else if (TREE_CODE (ac) == COMPLEX_CST)
06378 ar = TREE_REALPART (ac), ai = TREE_IMAGPART (ac);
06379 else
06380 return NULL;
06381
06382 if (TREE_CODE (bc) == COMPLEX_EXPR)
06383 br = TREE_OPERAND (bc, 0), bi = TREE_OPERAND (bc, 1);
06384 else if (TREE_CODE (bc) == COMPLEX_CST)
06385 br = TREE_REALPART (bc), bi = TREE_IMAGPART (bc);
06386 else
06387 return NULL;
06388
06389 inner_type = TREE_TYPE (type);
06390
06391 rr = fold (build2 (code, inner_type, ar, br));
06392 ri = fold (build2 (code, inner_type, ai, bi));
06393
06394 return fold (build2 (COMPLEX_EXPR, type, rr, ri));
06395 }
06396
06397
06398
06399
06400 tree
06401 fold_complex_mult_parts (tree type, tree ar, tree ai, tree br, tree bi)
06402 {
06403 tree rr, ri, inner_type, zero;
06404 bool ar0, ai0, br0, bi0, bi1;
06405
06406 inner_type = TREE_TYPE (type);
06407 zero = NULL;
06408
06409 if (SCALAR_FLOAT_TYPE_P (inner_type))
06410 {
06411 ar0 = ai0 = br0 = bi0 = bi1 = false;
06412
06413
06414
06415 if (TREE_CODE (ar) == REAL_CST
06416 && REAL_VALUES_IDENTICAL (TREE_REAL_CST (ar), dconst0))
06417 ar0 = true, zero = ar;
06418
06419 if (TREE_CODE (ai) == REAL_CST
06420 && REAL_VALUES_IDENTICAL (TREE_REAL_CST (ai), dconst0))
06421 ai0 = true, zero = ai;
06422
06423 if (TREE_CODE (br) == REAL_CST
06424 && REAL_VALUES_IDENTICAL (TREE_REAL_CST (br), dconst0))
06425 br0 = true, zero = br;
06426
06427 if (TREE_CODE (bi) == REAL_CST)
06428 {
06429 if (REAL_VALUES_IDENTICAL (TREE_REAL_CST (bi), dconst0))
06430 bi0 = true, zero = bi;
06431 else if (REAL_VALUES_IDENTICAL (TREE_REAL_CST (bi), dconst1))
06432 bi1 = true;
06433 }
06434 }
06435 else
06436 {
06437 ar0 = integer_zerop (ar);
06438 if (ar0)
06439 zero = ar;
06440 ai0 = integer_zerop (ai);
06441 if (ai0)
06442 zero = ai;
06443 br0 = integer_zerop (br);
06444 if (br0)
06445 zero = br;
06446 bi0 = integer_zerop (bi);
06447 if (bi0)
06448 {
06449 zero = bi;
06450 bi1 = false;
06451 }
06452 else
06453 bi1 = integer_onep (bi);
06454 }
06455
06456
06457 if (zero == NULL)
06458 return NULL;
06459
06460 if (ai0 && br0 && bi1)
06461 {
06462 rr = zero;
06463 ri = ar;
06464 }
06465 else if (ai0 && bi0)
06466 {
06467 rr = fold (build2 (MULT_EXPR, inner_type, ar, br));
06468 ri = zero;
06469 }
06470 else if (ai0 && br0)
06471 {
06472 rr = zero;
06473 ri = fold (build2 (MULT_EXPR, inner_type, ar, bi));
06474 }
06475 else if (ar0 && bi0)
06476 {
06477 rr = zero;
06478 ri = fold (build2 (MULT_EXPR, inner_type, ai, br));
06479 }
06480 else if (ar0 && br0)
06481 {
06482 rr = fold (build2 (MULT_EXPR, inner_type, ai, bi));
06483 rr = fold (build1 (NEGATE_EXPR, inner_type, rr));
06484 ri = zero;
06485 }
06486 else if (bi0)
06487 {
06488 rr = fold (build2 (MULT_EXPR, inner_type, ar, br));
06489 ri = fold (build2 (MULT_EXPR, inner_type, ai, br));
06490 }
06491 else if (ai0)
06492 {
06493 rr = fold (build2 (MULT_EXPR, inner_type, ar, br));
06494 ri = fold (build2 (MULT_EXPR, inner_type, ar, bi));
06495 }
06496 else if (br0)
06497 {
06498 rr = fold (build2 (MULT_EXPR, inner_type, ai, bi));
06499 rr = fold (build1 (NEGATE_EXPR, inner_type, rr));
06500 ri = fold (build2 (MULT_EXPR, inner_type, ar, bi));
06501 }
06502 else if (ar0)
06503 {
06504 rr = fold (build2 (MULT_EXPR, inner_type, ai, bi));
06505 rr = fold (build1 (NEGATE_EXPR, inner_type, rr));
06506 ri = fold (build2 (MULT_EXPR, inner_type, ai, br));
06507 }
06508 else
06509 return NULL;
06510
06511 return fold (build2 (COMPLEX_EXPR, type, rr, ri));
06512 }
06513
06514 static tree
06515 fold_complex_mult (tree type, tree ac, tree bc)
06516 {
06517 tree ar, ai, br, bi;
06518
06519 if (TREE_CODE (ac) == COMPLEX_EXPR)
06520 ar = TREE_OPERAND (ac, 0), ai = TREE_OPERAND (ac, 1);
06521 else if (TREE_CODE (ac) == COMPLEX_CST)
06522 ar = TREE_REALPART (ac), ai = TREE_IMAGPART (ac);
06523 else
06524 return NULL;
06525
06526 if (TREE_CODE (bc) == COMPLEX_EXPR)
06527 br = TREE_OPERAND (bc, 0), bi = TREE_OPERAND (bc, 1);
06528 else if (TREE_CODE (bc) == COMPLEX_CST)
06529 br = TREE_REALPART (bc), bi = TREE_IMAGPART (bc);
06530 else
06531 return NULL;
06532
06533 return fold_complex_mult_parts (type, ar, ai, br, bi);
06534 }
06535
06536
06537
06538
06539 tree
06540 fold_complex_div_parts (tree type, tree ar, tree ai, tree br, tree bi,
06541 enum tree_code code)
06542 {
06543 tree rr, ri, inner_type, zero;
06544 bool ar0, ai0, br0, bi0, bi1;
06545
06546 inner_type = TREE_TYPE (type);
06547 zero = NULL;
06548
06549 if (SCALAR_FLOAT_TYPE_P (inner_type))
06550 {
06551 ar0 = ai0 = br0 = bi0 = bi1 = false;
06552
06553
06554
06555 if (TREE_CODE (ar) == REAL_CST
06556 && REAL_VALUES_IDENTICAL (TREE_REAL_CST (ar), dconst0))
06557 ar0 = true, zero = ar;
06558
06559 if (TREE_CODE (ai) == REAL_CST
06560 && REAL_VALUES_IDENTICAL (TREE_REAL_CST (ai), dconst0))
06561 ai0 = true, zero = ai;
06562
06563 if (TREE_CODE (br) == REAL_CST
06564 && REAL_VALUES_IDENTICAL (TREE_REAL_CST (br), dconst0))
06565 br0 = true, zero = br;
06566
06567 if (TREE_CODE (bi) == REAL_CST)
06568 {
06569 if (REAL_VALUES_IDENTICAL (TREE_REAL_CST (bi), dconst0))
06570 bi0 = true, zero = bi;
06571 else if (REAL_VALUES_IDENTICAL (TREE_REAL_CST (bi), dconst1))
06572 bi1 = true;
06573 }
06574 }
06575 else
06576 {
06577 ar0 = integer_zerop (ar);
06578 if (ar0)
06579 zero = ar;
06580 ai0 = integer_zerop (ai);
06581 if (ai0)
06582 zero = ai;
06583 br0 = integer_zerop (br);
06584 if (br0)
06585 zero = br;
06586 bi0 = integer_zerop (bi);
06587 if (bi0)
06588 {
06589 zero = bi;
06590 bi1 = false;
06591 }
06592 else
06593 bi1 = integer_onep (bi);
06594 }
06595
06596
06597 if (zero == NULL)
06598 return NULL;
06599
06600 if (ai0 && bi0)
06601 {
06602 rr = fold (build2 (code, inner_type, ar, br));
06603 ri = zero;
06604 }
06605 else if (ai0 && br0)
06606 {
06607 rr = zero;
06608 ri = fold (build2 (code, inner_type, ar, bi));
06609 ri = fold (build1 (NEGATE_EXPR, inner_type, ri));
06610 }
06611 else if (ar0 && bi0)
06612 {
06613 rr = zero;
06614 ri = fold (build2 (code, inner_type, ai, br));
06615 }
06616 else if (ar0 && br0)
06617 {
06618 rr = fold (build2 (code, inner_type, ai, bi));
06619 ri = zero;
06620 }
06621 else if (bi0)
06622 {
06623 rr = fold (build2 (code, inner_type, ar, br));
06624 ri = fold (build2 (code, inner_type, ai, br));
06625 }
06626 else if (br0)
06627 {
06628 rr = fold (build2 (code, inner_type, ai, bi));
06629 ri = fold (build2 (code, inner_type, ar, bi));
06630 ri = fold (build1 (NEGATE_EXPR, inner_type, ri));
06631 }
06632 else
06633 return NULL;
06634
06635 return fold (build2 (COMPLEX_EXPR, type, rr, ri));
06636 }
06637
06638 static tree
06639 fold_complex_div (tree type, tree ac, tree bc, enum tree_code code)
06640 {
06641 tree ar, ai, br, bi;
06642
06643 if (TREE_CODE (ac) == COMPLEX_EXPR)
06644 ar = TREE_OPERAND (ac, 0), ai = TREE_OPERAND (ac, 1);
06645 else if (TREE_CODE (ac) == COMPLEX_CST)
06646 ar = TREE_REALPART (ac), ai = TREE_IMAGPART (ac);
06647 else
06648 return NULL;
06649
06650 if (TREE_CODE (bc) == COMPLEX_EXPR)
06651 br = TREE_OPERAND (bc, 0), bi = TREE_OPERAND (bc, 1);
06652 else if (TREE_CODE (bc) == COMPLEX_CST)
06653 br = TREE_REALPART (bc), bi = TREE_IMAGPART (bc);
06654 else
06655 return NULL;
06656
06657 return fold_complex_div_parts (type, ar, ai, br, bi, code);
06658 }
06659
06660
06661
06662
06663
06664
06665
06666
06667
06668 #ifdef ENABLE_FOLD_CHECKING
06669 # define fold(x) fold_1 (x)
06670 static tree fold_1 (tree);
06671 static
06672 #endif
06673 tree
06674 fold (tree expr)
06675 {
06676 const tree t = expr;
06677 const tree type = TREE_TYPE (expr);
06678 tree t1 = NULL_TREE;
06679 tree tem;
06680 tree arg0 = NULL_TREE, arg1 = NULL_TREE;
06681 enum tree_code code = TREE_CODE (t);
06682 enum tree_code_class kind = TREE_CODE_CLASS (code);
06683
06684
06685
06686 int wins = 1;
06687
06688
06689 if (kind == tcc_constant)
06690 return t;
06691
06692 if (code == NOP_EXPR || code == FLOAT_EXPR || code == CONVERT_EXPR)
06693 {
06694 tree subop;
06695
06696
06697 arg0 = TREE_OPERAND (t, 0);
06698
06699
06700 if (arg0 != 0)
06701 STRIP_SIGN_NOPS (arg0);
06702
06703 if (arg0 != 0 && TREE_CODE (arg0) == COMPLEX_CST)
06704 subop = TREE_REALPART (arg0);
06705 else
06706 subop = arg0;
06707
06708 if (subop != 0 && TREE_CODE (subop) != INTEGER_CST
06709 && TREE_CODE (subop) != REAL_CST)
06710
06711
06712
06713 wins = 0;
06714 }
06715 else if (IS_EXPR_CODE_CLASS (kind))
06716 {
06717 int len = TREE_CODE_LENGTH (code);
06718 int i;
06719 for (i = 0; i < len; i++)
06720 {
06721 tree op = TREE_OPERAND (t, i);
06722 tree subop;
06723
06724 if (op == 0)
06725 continue;
06726
06727
06728
06729
06730
06731
06732
06733
06734
06735
06736
06737
06738 if (kind == tcc_comparison)
06739 STRIP_SIGN_NOPS (op);
06740 else
06741 STRIP_NOPS (op);
06742
06743 if (TREE_CODE (op) == COMPLEX_CST)
06744 subop = TREE_REALPART (op);
06745 else
06746 subop = op;
06747
06748 if (TREE_CODE (subop) != INTEGER_CST
06749 && TREE_CODE (subop) != REAL_CST)
06750
06751
06752
06753 wins = 0;
06754
06755 if (i == 0)
06756 arg0 = op;
06757 else if (i == 1)
06758 arg1 = op;
06759 }
06760 }
06761
06762
06763
06764 if (commutative_tree_code (code)
06765 && tree_swap_operands_p (arg0, arg1, true))
06766 return fold (build2 (code, type, TREE_OPERAND (t, 1),
06767 TREE_OPERAND (t, 0)));
06768
06769
06770
06771
06772
06773
06774
06775
06776
06777
06778
06779
06780
06781
06782
06783
06784
06785
06786
06787 if ((code == BIT_AND_EXPR || code == BIT_IOR_EXPR
06788 || code == EQ_EXPR || code == NE_EXPR)
06789 && ((truth_value_p (TREE_CODE (arg0))
06790 && (truth_value_p (TREE_CODE (arg1))
06791 || (TREE_CODE (arg1) == BIT_AND_EXPR
06792 && integer_onep (TREE_OPERAND (arg1, 1)))))
06793 || (truth_value_p (TREE_CODE (arg1))
06794 && (truth_value_p (TREE_CODE (arg0))
06795 || (TREE_CODE (arg0) == BIT_AND_EXPR
06796 && integer_onep (TREE_OPERAND (arg0, 1)))))))
06797 {
06798 tem = fold (build2 (code == BIT_AND_EXPR ? TRUTH_AND_EXPR
06799 : code == BIT_IOR_EXPR ? TRUTH_OR_EXPR
06800 : TRUTH_XOR_EXPR,
06801 boolean_type_node,
06802 fold_convert (boolean_type_node, arg0),
06803 fold_convert (boolean_type_node, arg1)));
06804
06805 if (code == EQ_EXPR)
06806 tem = invert_truthvalue (tem);
06807
06808 return fold_convert (type, tem);
06809 }
06810
06811 if (TREE_CODE_CLASS (code) == tcc_unary)
06812 {
06813 if (TREE_CODE (arg0) == COMPOUND_EXPR)
06814 return build2 (COMPOUND_EXPR, type, TREE_OPERAND (arg0, 0),
06815 fold (build1 (code, type, TREE_OPERAND (arg0, 1))));
06816 else if (TREE_CODE (arg0) == COND_EXPR)
06817 {
06818 tree arg01 = TREE_OPERAND (arg0, 1);
06819 tree arg02 = TREE_OPERAND (arg0, 2);
06820 if (! VOID_TYPE_P (TREE_TYPE (arg01)))
06821 arg01 = fold (build1 (code, type, arg01));
06822 if (! VOID_TYPE_P (TREE_TYPE (arg02)))
06823 arg02 = fold (build1 (code, type, arg02));
06824 tem = fold (build3 (COND_EXPR, type, TREE_OPERAND (arg0, 0),
06825 arg01, arg02));
06826
06827
06828
06829
06830
06831
06832
06833
06834
06835
06836 if ((code == NOP_EXPR || code == CONVERT_EXPR
06837 || code == NON_LVALUE_EXPR)
06838 && TREE_CODE (tem) == COND_EXPR
06839 && TREE_CODE (TREE_OPERAND (tem, 1)) == code
06840 && TREE_CODE (TREE_OPERAND (tem, 2)) == code
06841 && ! VOID_TYPE_P (TREE_OPERAND (tem, 1))
06842 && ! VOID_TYPE_P (TREE_OPERAND (tem, 2))
06843 && (TREE_TYPE (TREE_OPERAND (TREE_OPERAND (tem, 1), 0))
06844 == TREE_TYPE (TREE_OPERAND (TREE_OPERAND (tem, 2), 0)))
06845 && (! (INTEGRAL_TYPE_P (TREE_TYPE (tem))
06846 && (INTEGRAL_TYPE_P
06847 (TREE_TYPE (TREE_OPERAND (TREE_OPERAND (tem, 1), 0))))
06848 && TYPE_PRECISION (TREE_TYPE (tem)) <= BITS_PER_WORD)
06849 || flag_syntax_only))
06850 tem = build1 (code, type,
06851 build3 (COND_EXPR,
06852 TREE_TYPE (TREE_OPERAND
06853 (TREE_OPERAND (tem, 1), 0)),
06854 TREE_OPERAND (tem, 0),
06855 TREE_OPERAND (TREE_OPERAND (tem, 1), 0),
06856 TREE_OPERAND (TREE_OPERAND (tem, 2), 0)));
06857 return tem;
06858 }
06859 else if (COMPARISON_CLASS_P (arg0))
06860 {
06861 if (TREE_CODE (type) == BOOLEAN_TYPE)
06862 {
06863 arg0 = copy_node (arg0);
06864 TREE_TYPE (arg0) = type;
06865 return arg0;
06866 }
06867 else if (TREE_CODE (type) != INTEGER_TYPE)
06868 return fold (build3 (COND_EXPR, type, arg0,
06869 fold (build1 (code, type,
06870 integer_one_node)),
06871 fold (build1 (code, type,
06872 integer_zero_node))));
06873 }
06874 }
06875 else if (TREE_CODE_CLASS (code) == tcc_comparison
06876 && TREE_CODE (arg0) == COMPOUND_EXPR)
06877 return build2 (COMPOUND_EXPR, type, TREE_OPERAND (arg0, 0),
06878 fold (build2 (code, type, TREE_OPERAND (arg0, 1), arg1)));
06879 else if (TREE_CODE_CLASS (code) == tcc_comparison
06880 && TREE_CODE (arg1) == COMPOUND_EXPR)
06881 return build2 (COMPOUND_EXPR, type, TREE_OPERAND (arg1, 0),
06882 fold (build2 (code, type, arg0, TREE_OPERAND (arg1, 1))));
06883 else if (TREE_CODE_CLASS (code) == tcc_binary
06884 || TREE_CODE_CLASS (code) == tcc_comparison)
06885 {
06886 if (TREE_CODE (arg0) == COMPOUND_EXPR)
06887 return build2 (COMPOUND_EXPR, type, TREE_OPERAND (arg0, 0),
06888 fold (build2 (code, type, TREE_OPERAND (arg0, 1),
06889 arg1)));
06890 if (TREE_CODE (arg1) == COMPOUND_EXPR
06891 && reorder_operands_p (arg0, TREE_OPERAND (arg1, 0)))
06892 return build2 (COMPOUND_EXPR, type, TREE_OPERAND (arg1, 0),
06893 fold (build2 (code, type,
06894 arg0, TREE_OPERAND (arg1, 1))));
06895
06896 if (TREE_CODE (arg0) == COND_EXPR || COMPARISON_CLASS_P (arg0))
06897 {
06898 tem = fold_binary_op_with_conditional_arg (t, code, arg0, arg1,
06899 1);
06900 if (tem != NULL_TREE)
06901 return tem;
06902 }
06903
06904 if (TREE_CODE (arg1) == COND_EXPR || COMPARISON_CLASS_P (arg1))
06905 {
06906 tem = fold_binary_op_with_conditional_arg (t, code, arg1, arg0,
06907 0);
06908 if (tem != NULL_TREE)
06909 return tem;
06910 }
06911 }
06912
06913 switch (code)
06914 {
06915 case CONST_DECL:
06916 return fold (DECL_INITIAL (t));
06917
06918 case NOP_EXPR:
06919 case FLOAT_EXPR:
06920 case CONVERT_EXPR:
06921 case FIX_TRUNC_EXPR:
06922 case FIX_CEIL_EXPR:
06923 case FIX_FLOOR_EXPR:
06924 case FIX_ROUND_EXPR:
06925 if (TREE_TYPE (TREE_OPERAND (t, 0)) == type)
06926 return TREE_OPERAND (t, 0);
06927
06928
06929 if (TREE_CODE (TREE_OPERAND (t, 0)) == NOP_EXPR
06930 || TREE_CODE (TREE_OPERAND (t, 0)) == CONVERT_EXPR)
06931 {
06932 tree inside_type = TREE_TYPE (TREE_OPERAND (TREE_OPERAND (t, 0), 0));
06933 tree inter_type = TREE_TYPE (TREE_OPERAND (t, 0));
06934 int inside_int = INTEGRAL_TYPE_P (inside_type);
06935 int inside_ptr = POINTER_TYPE_P (inside_type);
06936 int inside_float = FLOAT_TYPE_P (inside_type);
06937 int inside_vec = TREE_CODE (inside_type) == VECTOR_TYPE;
06938 unsigned int inside_prec = TYPE_PRECISION (inside_type);
06939 int inside_unsignedp = TYPE_UNSIGNED (inside_type);
06940 int inter_int = INTEGRAL_TYPE_P (inter_type);
06941 int inter_ptr = POINTER_TYPE_P (inter_type);
06942 int inter_float = FLOAT_TYPE_P (inter_type);
06943 int inter_vec = TREE_CODE (inter_type) == VECTOR_TYPE;
06944 unsigned int inter_prec = TYPE_PRECISION (inter_type);
06945 int inter_unsignedp = TYPE_UNSIGNED (inter_type);
06946 int final_int = INTEGRAL_TYPE_P (type);
06947 int final_ptr = POINTER_TYPE_P (type);
06948 int final_float = FLOAT_TYPE_P (type);
06949 int final_vec = TREE_CODE (type) == VECTOR_TYPE;
06950 unsigned int final_prec = TYPE_PRECISION (type);
06951 int final_unsignedp = TYPE_UNSIGNED (type);
06952
06953
06954
06955
06956
06957 if (TYPE_MAIN_VARIANT (inside_type) == TYPE_MAIN_VARIANT (type)
06958 && ((inter_int && final_int) || (inter_float && final_float))
06959 && inter_prec >= final_prec)
06960 return fold (build1 (code, type,
06961 TREE_OPERAND (TREE_OPERAND (t, 0), 0)));
06962
06963
06964
06965
06966
06967
06968
06969 if ((((inter_int || inter_ptr) && (inside_int || inside_ptr))
06970 || (inter_float && inside_float)
06971 || (inter_vec && inside_vec))
06972 && inter_prec >= inside_prec
06973 && (inter_float || inter_vec
06974 || inter_unsignedp == inside_unsignedp)
06975 && ! (final_prec != GET_MODE_BITSIZE (TYPE_MODE (type))
06976 && TYPE_MODE (type) == TYPE_MODE (inter_type))
06977 && ! final_ptr
06978 && (! final_vec || inter_prec == inside_prec))
06979 return fold (build1 (code, type,
06980 TREE_OPERAND (TREE_OPERAND (t, 0), 0)));
06981
06982
06983
06984 if (inside_int && inter_int && final_int
06985 && inside_prec < inter_prec && inter_prec < final_prec
06986 && inside_unsignedp && !inter_unsignedp)
06987 return fold (build1 (code, type,
06988 TREE_OPERAND (TREE_OPERAND (t, 0), 0)));
06989
06990
06991
06992
06993
06994
06995
06996
06997
06998
06999
07000
07001 if (! inside_float && ! inter_float && ! final_float
07002 && ! inside_vec && ! inter_vec && ! final_vec
07003 && (inter_prec > inside_prec || inter_prec > final_prec)
07004 && ! (inside_int && inter_int
07005 && inter_unsignedp != inside_unsignedp
07006 && inter_prec < final_prec)
07007 && ((inter_unsignedp && inter_prec > inside_prec)
07008 == (final_unsignedp && final_prec > inter_prec))
07009 && ! (inside_ptr && inter_prec != final_prec)
07010 && ! (final_ptr && inside_prec != inter_prec)
07011 && ! (final_prec != GET_MODE_BITSIZE (TYPE_MODE (type))
07012 && TYPE_MODE (type) == TYPE_MODE (inter_type))
07013 && ! final_ptr)
07014 return fold (build1 (code, type,
07015 TREE_OPERAND (TREE_OPERAND (t, 0), 0)));
07016 }
07017
07018 if (TREE_CODE (TREE_OPERAND (t, 0)) == MODIFY_EXPR
07019 && TREE_CONSTANT (TREE_OPERAND (TREE_OPERAND (t, 0), 1))
07020
07021 && !(TREE_CODE (TREE_OPERAND (TREE_OPERAND (t, 0), 0)) == COMPONENT_REF
07022 && DECL_BIT_FIELD (TREE_OPERAND (TREE_OPERAND (TREE_OPERAND (t, 0), 0), 1))))
07023 {
07024
07025
07026 tree prev = TREE_OPERAND (t, 0);
07027 tem = copy_node (t);
07028 TREE_OPERAND (tem, 0) = TREE_OPERAND (prev, 1);
07029
07030 tem = build2 (COMPOUND_EXPR, TREE_TYPE (tem), prev, fold (tem));
07031 TREE_NO_WARNING (tem) = 1;
07032 TREE_USED (tem) = 1;
07033 return tem;
07034 }
07035
07036
07037
07038
07039 if (INTEGRAL_TYPE_P (type)
07040 && TREE_CODE (type) != BOOLEAN_TYPE
07041 && TREE_CODE (TREE_OPERAND (t, 0)) == BIT_AND_EXPR
07042 && TREE_CODE (TREE_OPERAND (TREE_OPERAND (t, 0), 1)) == INTEGER_CST)
07043 {
07044 tree and = TREE_OPERAND (t, 0);
07045 tree and0 = TREE_OPERAND (and, 0), and1 = TREE_OPERAND (and, 1);
07046 int change = 0;
07047
07048 if (TYPE_UNSIGNED (TREE_TYPE (and))
07049 || (TYPE_PRECISION (type)
07050 <= TYPE_PRECISION (TREE_TYPE (and))))
07051 change = 1;
07052 else if (TYPE_PRECISION (TREE_TYPE (and1))
07053 <= HOST_BITS_PER_WIDE_INT
07054 && host_integerp (and1, 1))
07055 {
07056 unsigned HOST_WIDE_INT cst;
07057
07058 cst = tree_low_cst (and1, 1);
07059 cst &= (HOST_WIDE_INT) -1
07060 << (TYPE_PRECISION (TREE_TYPE (and1)) - 1);
07061 change = (cst == 0);
07062 #ifdef LOAD_EXTEND_OP
07063 if (change
07064 && !flag_syntax_only
07065 && (LOAD_EXTEND_OP (TYPE_MODE (TREE_TYPE (and0)))
07066 == ZERO_EXTEND))
07067 {
07068 tree uns = lang_hooks.types.unsigned_type (TREE_TYPE (and0));
07069 and0 = fold_convert (uns, and0);
07070 and1 = fold_convert (uns, and1);
07071 }
07072 #endif
07073 }
07074 if (change)
07075 {
07076 tem = build_int_cst_wide (type, TREE_INT_CST_LOW (and1),
07077 TREE_INT_CST_HIGH (and1));
07078 tem = force_fit_type (tem, 0, TREE_OVERFLOW (and1),
07079 TREE_CONSTANT_OVERFLOW (and1));
07080 return fold (build2 (BIT_AND_EXPR, type,
07081 fold_convert (type, and0), tem));
07082 }
07083 }
07084
07085
07086
07087 if (POINTER_TYPE_P (TREE_TYPE (t))
07088 && BINARY_CLASS_P (arg0)
07089 && TREE_CODE (TREE_OPERAND (arg0, 0)) == NOP_EXPR
07090 && POINTER_TYPE_P (TREE_TYPE (TREE_OPERAND (arg0, 0))))
07091 {
07092 tree arg00 = TREE_OPERAND (arg0, 0);
07093 tree t0 = TREE_TYPE (t);
07094 tree t1 = TREE_TYPE (arg00);
07095 tree tt0 = TREE_TYPE (t0);
07096 tree tt1 = TREE_TYPE (t1);
07097 tree s0 = TYPE_SIZE (tt0);
07098 tree s1 = TYPE_SIZE (tt1);
07099
07100 if (s0 && s1 && operand_equal_p (s0, s1, OEP_ONLY_CONST))
07101 return build2 (TREE_CODE (arg0), t0, fold_convert (t0, arg00),
07102 TREE_OPERAND (arg0, 1));
07103 }
07104
07105 tem = fold_convert_const (code, type, arg0);
07106 return tem ? tem : t;
07107
07108 case VIEW_CONVERT_EXPR:
07109 if (TREE_CODE (TREE_OPERAND (t, 0)) == VIEW_CONVERT_EXPR)
07110 return build1 (VIEW_CONVERT_EXPR, type,
07111 TREE_OPERAND (TREE_OPERAND (t, 0), 0));
07112 return t;
07113
07114 case COMPONENT_REF:
07115 if (TREE_CODE (arg0) == CONSTRUCTOR
07116 && ! type_contains_placeholder_p (TREE_TYPE (arg0)))
07117 {
07118 tree m = purpose_member (arg1, CONSTRUCTOR_ELTS (arg0));
07119 if (m)
07120 return TREE_VALUE (m);
07121 }
07122 return t;
07123
07124 case RANGE_EXPR:
07125 if (TREE_CONSTANT (t) != wins)
07126 {
07127 tem = copy_node (t);
07128 TREE_CONSTANT (tem) = wins;
07129 TREE_INVARIANT (tem) = wins;
07130 return tem;
07131 }
07132 return t;
07133
07134 case NEGATE_EXPR:
07135 if (negate_expr_p (arg0))
07136 return fold_convert (type, negate_expr (arg0));
07137
07138 if (INTEGRAL_TYPE_P (type) && TREE_CODE (arg0) == BIT_NOT_EXPR)
07139 return fold (build2 (PLUS_EXPR, type, TREE_OPERAND (arg0, 0),
07140 build_int_cst (type, 1)));
07141 return t;
07142
07143 case ABS_EXPR:
07144 if (TREE_CODE (arg0) == INTEGER_CST || TREE_CODE (arg0) == REAL_CST)
07145 return fold_abs_const (arg0, type);
07146 else if (TREE_CODE (arg0) == NEGATE_EXPR)
07147 return fold (build1 (ABS_EXPR, type, TREE_OPERAND (arg0, 0)));
07148
07149 else if (TREE_CODE (arg0) == NOP_EXPR
07150 && TREE_CODE (type) == REAL_TYPE)
07151 {
07152 tree targ0 = strip_float_extensions (arg0);
07153 if (targ0 != arg0)
07154 return fold_convert (type, fold (build1 (ABS_EXPR,
07155 TREE_TYPE (targ0),
07156 targ0)));
07157 }
07158 else if (tree_expr_nonnegative_p (arg0))
07159 return arg0;
07160
07161
07162 if (TREE_CODE (type) == REAL_TYPE)
07163 {
07164 tem = fold_strip_sign_ops (arg0);
07165 if (tem)
07166 return fold (build1 (ABS_EXPR, type, fold_convert (type, tem)));
07167 }
07168 return t;
07169
07170 case CONJ_EXPR:
07171 if (TREE_CODE (TREE_TYPE (arg0)) != COMPLEX_TYPE)
07172 return fold_convert (type, arg0);
07173 else if (TREE_CODE (arg0) == COMPLEX_EXPR)
07174 return build2 (COMPLEX_EXPR, type,
07175 TREE_OPERAND (arg0, 0),
07176 negate_expr (TREE_OPERAND (arg0, 1)));
07177 else if (TREE_CODE (arg0) == COMPLEX_CST)
07178 return build_complex (type, TREE_REALPART (arg0),
07179 negate_expr (TREE_IMAGPART (arg0)));
07180 else if (TREE_CODE (arg0) == PLUS_EXPR || TREE_CODE (arg0) == MINUS_EXPR)
07181 return fold (build2 (TREE_CODE (arg0), type,
07182 fold (build1 (CONJ_EXPR, type,
07183 TREE_OPERAND (arg0, 0))),
07184 fold (build1 (CONJ_EXPR, type,
07185 TREE_OPERAND (arg0, 1)))));
07186 else if (TREE_CODE (arg0) == CONJ_EXPR)
07187 return TREE_OPERAND (arg0, 0);
07188 return t;
07189
07190 case BIT_NOT_EXPR:
07191 if (TREE_CODE (arg0) == INTEGER_CST)
07192 return fold_not_const (arg0, type);
07193 else if (TREE_CODE (arg0) == BIT_NOT_EXPR)
07194 return TREE_OPERAND (arg0, 0);
07195
07196 else if (INTEGRAL_TYPE_P (type) && TREE_CODE (arg0) == NEGATE_EXPR)
07197 return fold (build2 (MINUS_EXPR, type, TREE_OPERAND (arg0, 0),
07198 build_int_cst (type, 1)));
07199
07200 else if (INTEGRAL_TYPE_P (type)
07201 && ((TREE_CODE (arg0) == MINUS_EXPR
07202 && integer_onep (TREE_OPERAND (arg0, 1)))
07203 || (TREE_CODE (arg0) == PLUS_EXPR
07204 && integer_all_onesp (TREE_OPERAND (arg0, 1)))))
07205 return fold (build1 (NEGATE_EXPR, type, TREE_OPERAND (arg0, 0)));
07206 return t;
07207
07208 case PLUS_EXPR:
07209
07210 if (TREE_CODE (arg1) == NEGATE_EXPR)
07211 return fold (build2 (MINUS_EXPR, type, arg0, TREE_OPERAND (arg1, 0)));
07212
07213 if (TREE_CODE (arg0) == NEGATE_EXPR
07214 && reorder_operands_p (TREE_OPERAND (arg0, 0), arg1))
07215 return fold (build2 (MINUS_EXPR, type, arg1, TREE_OPERAND (arg0, 0)));
07216
07217 if (TREE_CODE (type) == COMPLEX_TYPE)
07218 {
07219 tem = fold_complex_add (type, arg0, arg1, PLUS_EXPR);
07220 if (tem)
07221 return tem;
07222 }
07223
07224 if (! FLOAT_TYPE_P (type))
07225 {
07226 if (integer_zerop (arg1))
07227 return non_lvalue (fold_convert (type, arg0));
07228
07229
07230
07231
07232
07233 if (TREE_CODE (arg0) == BIT_AND_EXPR
07234 && TREE_CODE (arg1) == BIT_AND_EXPR
07235 && TREE_CODE (TREE_OPERAND (arg0, 1)) == INTEGER_CST
07236 && TREE_CODE (TREE_OPERAND (arg1, 1)) == INTEGER_CST
07237 && integer_zerop (const_binop (BIT_AND_EXPR,
07238 TREE_OPERAND (arg0, 1),
07239 TREE_OPERAND (arg1, 1), 0)))
07240 {
07241 code = BIT_IOR_EXPR;
07242 goto bit_ior;
07243 }
07244
07245
07246
07247
07248 if (((TREE_CODE (arg0) == PLUS_EXPR
07249 || TREE_CODE (arg0) == MINUS_EXPR)
07250 && TREE_CODE (arg1) == MULT_EXPR)
07251 || ((TREE_CODE (arg1) == PLUS_EXPR
07252 || TREE_CODE (arg1) == MINUS_EXPR)
07253 && TREE_CODE (arg0) == MULT_EXPR))
07254 {
07255 tree parg0, parg1, parg, marg;
07256 enum tree_code pcode;
07257
07258 if (TREE_CODE (arg1) == MULT_EXPR)
07259 parg = arg0, marg = arg1;
07260 else
07261 parg = arg1, marg = arg0;
07262 pcode = TREE_CODE (parg);
07263 parg0 = TREE_OPERAND (parg, 0);
07264 parg1 = TREE_OPERAND (parg, 1);
07265 STRIP_NOPS (parg0);
07266 STRIP_NOPS (parg1);
07267
07268 if (TREE_CODE (parg0) == MULT_EXPR
07269 && TREE_CODE (parg1) != MULT_EXPR)
07270 return fold (build2 (pcode, type,
07271 fold (build2 (PLUS_EXPR, type,
07272 fold_convert (type, parg0),
07273 fold_convert (type, marg))),
07274 fold_convert (type, parg1)));
07275 if (TREE_CODE (parg0) != MULT_EXPR
07276 && TREE_CODE (parg1) == MULT_EXPR)
07277 return fold (build2 (PLUS_EXPR, type,
07278 fold_convert (type, parg0),
07279 fold (build2 (pcode, type,
07280 fold_convert (type, marg),
07281 fold_convert (type,
07282 parg1)))));
07283 }
07284
07285 if (TREE_CODE (arg0) == MULT_EXPR && TREE_CODE (arg1) == MULT_EXPR)
07286 {
07287 tree arg00, arg01, arg10, arg11;
07288 tree alt0 = NULL_TREE, alt1 = NULL_TREE, same;
07289
07290
07291
07292
07293
07294
07295 arg00 = TREE_OPERAND (arg0, 0);
07296 arg01 = TREE_OPERAND (arg0, 1);
07297 arg10 = TREE_OPERAND (arg1, 0);
07298 arg11 = TREE_OPERAND (arg1, 1);
07299 same = NULL_TREE;
07300
07301 if (operand_equal_p (arg01, arg11, 0))
07302 same = arg01, alt0 = arg00, alt1 = arg10;
07303 else if (operand_equal_p (arg00, arg10, 0))
07304 same = arg00, alt0 = arg01, alt1 = arg11;
07305 else if (operand_equal_p (arg00, arg11, 0))
07306 same = arg00, alt0 = arg01, alt1 = arg10;
07307 else if (operand_equal_p (arg01, arg10, 0))
07308 same = arg01, alt0 = arg00, alt1 = arg11;
07309
07310
07311
07312
07313 else if (TREE_CODE (arg01) == INTEGER_CST
07314 && TREE_CODE (arg11) == INTEGER_CST
07315 && TREE_INT_CST_HIGH (arg01) == 0
07316 && TREE_INT_CST_HIGH (arg11) == 0)
07317 {
07318 HOST_WIDE_INT int01, int11, tmp;
07319 int01 = TREE_INT_CST_LOW (arg01);
07320 int11 = TREE_INT_CST_LOW (arg11);
07321
07322
07323 if ((int01 >= 0 ? int01 : -int01)
07324 < (int11 >= 0 ? int11 : -int11))
07325 {
07326 tmp = int01, int01 = int11, int11 = tmp;
07327 alt0 = arg00, arg00 = arg10, arg10 = alt0;
07328 alt0 = arg01, arg01 = arg11, arg11 = alt0;
07329 }
07330
07331 if (exact_log2 (int11) > 0 && int01 % int11 == 0)
07332 {
07333 alt0 = fold (build2 (MULT_EXPR, type, arg00,
07334 build_int_cst (NULL_TREE,
07335 int01 / int11)));
07336 alt1 = arg10;
07337 same = arg11;
07338 }
07339 }
07340
07341 if (same)
07342 return fold (build2 (MULT_EXPR, type,
07343 fold (build2 (PLUS_EXPR, type,
07344 fold_convert (type, alt0),
07345 fold_convert (type, alt1))),
07346 same));
07347 }
07348
07349
07350
07351
07352 if (TREE_CODE (arg0) == ADDR_EXPR
07353 && TREE_CODE (arg1) == MULT_EXPR)
07354 {
07355 tem = try_move_mult_to_index (PLUS_EXPR, arg0, arg1);
07356 if (tem)
07357 return fold_convert (type, fold (tem));
07358 }
07359 else if (TREE_CODE (arg1) == ADDR_EXPR
07360 && TREE_CODE (arg0) == MULT_EXPR)
07361 {
07362 tem = try_move_mult_to_index (PLUS_EXPR, arg1, arg0);
07363 if (tem)
07364 return fold_convert (type, fold (tem));
07365 }
07366 }
07367 else
07368 {
07369
07370 if (fold_real_zero_addition_p (TREE_TYPE (arg0), arg1, 0))
07371 return non_lvalue (fold_convert (type, arg0));
07372
07373
07374 if (fold_real_zero_addition_p (TREE_TYPE (arg1), arg0, 0))
07375 return non_lvalue (fold_convert (type, arg1));
07376
07377
07378 if (TREE_CODE (arg1) == REAL_CST
07379 && REAL_VALUE_NEGATIVE (TREE_REAL_CST (arg1)))
07380 {
07381 tem = fold_negate_const (arg1, type);
07382 if (!TREE_OVERFLOW (arg1) || !flag_trapping_math)
07383 return fold (build2 (MINUS_EXPR, type,
07384 fold_convert (type, arg0),
07385 fold_convert (type, tem)));
07386 }
07387
07388
07389 if (operand_equal_p (arg0, arg1, 0)
07390 && SCALAR_FLOAT_TYPE_P (type))
07391 return fold (build2 (MULT_EXPR, type, arg0,
07392 build_real (type, dconst2)));
07393
07394
07395 if (flag_unsafe_math_optimizations
07396 && TREE_CODE (arg0) == MULT_EXPR
07397 && TREE_CODE (TREE_OPERAND (arg0, 1)) == REAL_CST
07398 && ! TREE_CONSTANT_OVERFLOW (TREE_OPERAND (arg0, 1))
07399 && operand_equal_p (TREE_OPERAND (arg0, 0), arg1, 0))
07400 {
07401 REAL_VALUE_TYPE c;
07402
07403 c = TREE_REAL_CST (TREE_OPERAND (arg0, 1));
07404 real_arithmetic (&c, PLUS_EXPR, &c, &dconst1);
07405 return fold (build2 (MULT_EXPR, type, arg1,
07406 build_real (type, c)));
07407 }
07408
07409
07410 if (flag_unsafe_math_optimizations
07411 && TREE_CODE (arg1) == MULT_EXPR
07412 && TREE_CODE (TREE_OPERAND (arg1, 1)) == REAL_CST
07413 && ! TREE_CONSTANT_OVERFLOW (TREE_OPERAND (arg1, 1))
07414 && operand_equal_p (TREE_OPERAND (arg1, 0), arg0, 0))
07415 {
07416 REAL_VALUE_TYPE c;
07417
07418 c = TREE_REAL_CST (TREE_OPERAND (arg1, 1));
07419 real_arithmetic (&c, PLUS_EXPR, &c, &dconst1);
07420 return fold (build2 (MULT_EXPR, type, arg0,
07421 build_real (type, c)));
07422 }
07423
07424
07425 if (flag_unsafe_math_optimizations
07426 && TREE_CODE (arg0) == MULT_EXPR
07427 && TREE_CODE (arg1) == MULT_EXPR
07428 && TREE_CODE (TREE_OPERAND (arg0, 1)) == REAL_CST
07429 && ! TREE_CONSTANT_OVERFLOW (TREE_OPERAND (arg0, 1))
07430 && TREE_CODE (TREE_OPERAND (arg1, 1)) == REAL_CST
07431 && ! TREE_CONSTANT_OVERFLOW (TREE_OPERAND (arg1, 1))
07432 && operand_equal_p (TREE_OPERAND (arg0, 0),
07433 TREE_OPERAND (arg1, 0), 0))
07434 {
07435 REAL_VALUE_TYPE c1, c2;
07436
07437 c1 = TREE_REAL_CST (TREE_OPERAND (arg0, 1));
07438 c2 = TREE_REAL_CST (TREE_OPERAND (arg1, 1));
07439 real_arithmetic (&c1, PLUS_EXPR, &c1, &c2);
07440 return fold (build2 (MULT_EXPR, type,
07441 TREE_OPERAND (arg0, 0),
07442 build_real (type, c1)));
07443 }
07444
07445 if (flag_unsafe_math_optimizations
07446 && TREE_CODE (arg1) == PLUS_EXPR
07447 && TREE_CODE (arg0) != MULT_EXPR)
07448 {
07449 tree tree10 = TREE_OPERAND (arg1, 0);
07450 tree tree11 = TREE_OPERAND (arg1, 1);
07451 if (TREE_CODE (tree11) == MULT_EXPR
07452 && TREE_CODE (tree10) == MULT_EXPR)
07453 {
07454 tree tree0;
07455 tree0 = fold (build2 (PLUS_EXPR, type, arg0, tree10));
07456 return fold (build2 (PLUS_EXPR, type, tree0, tree11));
07457 }
07458 }
07459
07460 if (flag_unsafe_math_optimizations
07461 && TREE_CODE (arg0) == PLUS_EXPR
07462 && TREE_CODE (arg1) != MULT_EXPR)
07463 {
07464 tree tree00 = TREE_OPERAND (arg0, 0);
07465 tree tree01 = TREE_OPERAND (arg0, 1);
07466 if (TREE_CODE (tree01) == MULT_EXPR
07467 && TREE_CODE (tree00) == MULT_EXPR)
07468 {
07469 tree tree0;
07470 tree0 = fold (build2 (PLUS_EXPR, type, tree01, arg1));
07471 return fold (build2 (PLUS_EXPR, type, tree00, tree0));
07472 }
07473 }
07474 }
07475
07476 bit_rotate:
07477
07478
07479
07480
07481 {
07482 enum tree_code code0, code1;
07483 code0 = TREE_CODE (arg0);
07484 code1 = TREE_CODE (arg1);
07485 if (((code0 == RSHIFT_EXPR && code1 == LSHIFT_EXPR)
07486 || (code1 == RSHIFT_EXPR && code0 == LSHIFT_EXPR))
07487 && operand_equal_p (TREE_OPERAND (arg0, 0),
07488