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 TREE_OPERAND (arg1, 0), 0)
07489 && TYPE_UNSIGNED (TREE_TYPE (TREE_OPERAND (arg0, 0))))
07490 {
07491 tree tree01, tree11;
07492 enum tree_code code01, code11;
07493
07494 tree01 = TREE_OPERAND (arg0, 1);
07495 tree11 = TREE_OPERAND (arg1, 1);
07496 STRIP_NOPS (tree01);
07497 STRIP_NOPS (tree11);
07498 code01 = TREE_CODE (tree01);
07499 code11 = TREE_CODE (tree11);
07500 if (code01 == INTEGER_CST
07501 && code11 == INTEGER_CST
07502 && TREE_INT_CST_HIGH (tree01) == 0
07503 && TREE_INT_CST_HIGH (tree11) == 0
07504 && ((TREE_INT_CST_LOW (tree01) + TREE_INT_CST_LOW (tree11))
07505 == TYPE_PRECISION (TREE_TYPE (TREE_OPERAND (arg0, 0)))))
07506 return build2 (LROTATE_EXPR, type, TREE_OPERAND (arg0, 0),
07507 code0 == LSHIFT_EXPR ? tree01 : tree11);
07508 else if (code11 == MINUS_EXPR)
07509 {
07510 tree tree110, tree111;
07511 tree110 = TREE_OPERAND (tree11, 0);
07512 tree111 = TREE_OPERAND (tree11, 1);
07513 STRIP_NOPS (tree110);
07514 STRIP_NOPS (tree111);
07515 if (TREE_CODE (tree110) == INTEGER_CST
07516 && 0 == compare_tree_int (tree110,
07517 TYPE_PRECISION
07518 (TREE_TYPE (TREE_OPERAND
07519 (arg0, 0))))
07520 && operand_equal_p (tree01, tree111, 0))
07521 return build2 ((code0 == LSHIFT_EXPR
07522 ? LROTATE_EXPR
07523 : RROTATE_EXPR),
07524 type, TREE_OPERAND (arg0, 0), tree01);
07525 }
07526 else if (code01 == MINUS_EXPR)
07527 {
07528 tree tree010, tree011;
07529 tree010 = TREE_OPERAND (tree01, 0);
07530 tree011 = TREE_OPERAND (tree01, 1);
07531 STRIP_NOPS (tree010);
07532 STRIP_NOPS (tree011);
07533 if (TREE_CODE (tree010) == INTEGER_CST
07534 && 0 == compare_tree_int (tree010,
07535 TYPE_PRECISION
07536 (TREE_TYPE (TREE_OPERAND
07537 (arg0, 0))))
07538 && operand_equal_p (tree11, tree011, 0))
07539 return build2 ((code0 != LSHIFT_EXPR
07540 ? LROTATE_EXPR
07541 : RROTATE_EXPR),
07542 type, TREE_OPERAND (arg0, 0), tree11);
07543 }
07544 }
07545 }
07546
07547 associate:
07548
07549
07550
07551
07552
07553 if (! wins
07554 && (! FLOAT_TYPE_P (type) || flag_unsafe_math_optimizations))
07555 {
07556 tree var0, con0, lit0, minus_lit0;
07557 tree var1, con1, lit1, minus_lit1;
07558
07559
07560
07561
07562
07563
07564 var0 = split_tree (arg0, code, &con0, &lit0, &minus_lit0, 0);
07565 var1 = split_tree (arg1, code, &con1, &lit1, &minus_lit1,
07566 code == MINUS_EXPR);
07567
07568
07569
07570 if (2 < ((var0 != 0) + (var1 != 0)
07571 + (con0 != 0) + (con1 != 0)
07572 + (lit0 != 0) + (lit1 != 0)
07573 + (minus_lit0 != 0) + (minus_lit1 != 0)))
07574 {
07575
07576 if (code == MINUS_EXPR)
07577 code = PLUS_EXPR;
07578
07579 var0 = associate_trees (var0, var1, code, type);
07580 con0 = associate_trees (con0, con1, code, type);
07581 lit0 = associate_trees (lit0, lit1, code, type);
07582 minus_lit0 = associate_trees (minus_lit0, minus_lit1, code, type);
07583
07584
07585
07586
07587
07588
07589 if (minus_lit0 && lit0)
07590 {
07591 if (TREE_CODE (lit0) == INTEGER_CST
07592 && TREE_CODE (minus_lit0) == INTEGER_CST
07593 && tree_int_cst_lt (lit0, minus_lit0))
07594 {
07595 minus_lit0 = associate_trees (minus_lit0, lit0,
07596 MINUS_EXPR, type);
07597 lit0 = 0;
07598 }
07599 else
07600 {
07601 lit0 = associate_trees (lit0, minus_lit0,
07602 MINUS_EXPR, type);
07603 minus_lit0 = 0;
07604 }
07605 }
07606 if (minus_lit0)
07607 {
07608 if (con0 == 0)
07609 return fold_convert (type,
07610 associate_trees (var0, minus_lit0,
07611 MINUS_EXPR, type));
07612 else
07613 {
07614 con0 = associate_trees (con0, minus_lit0,
07615 MINUS_EXPR, type);
07616 return fold_convert (type,
07617 associate_trees (var0, con0,
07618 PLUS_EXPR, type));
07619 }
07620 }
07621
07622 con0 = associate_trees (con0, lit0, code, type);
07623 return fold_convert (type, associate_trees (var0, con0,
07624 code, type));
07625 }
07626 }
07627
07628 binary:
07629 if (wins)
07630 t1 = const_binop (code, arg0, arg1, 0);
07631 if (t1 != NULL_TREE)
07632 {
07633
07634
07635 if (TREE_TYPE (t1) != type)
07636 t1 = fold_convert (type, t1);
07637
07638 return t1;
07639 }
07640 return t;
07641
07642 case MINUS_EXPR:
07643
07644 if (TREE_CODE (arg1) == NEGATE_EXPR)
07645 return fold (build2 (PLUS_EXPR, type, arg0, TREE_OPERAND (arg1, 0)));
07646
07647 if (TREE_CODE (arg0) == NEGATE_EXPR
07648 && (FLOAT_TYPE_P (type)
07649 || (INTEGRAL_TYPE_P (type) && flag_wrapv && !flag_trapv))
07650 && negate_expr_p (arg1)
07651 && reorder_operands_p (arg0, arg1))
07652 return fold (build2 (MINUS_EXPR, type, negate_expr (arg1),
07653 TREE_OPERAND (arg0, 0)));
07654
07655 if (TREE_CODE (type) == COMPLEX_TYPE)
07656 {
07657 tem = fold_complex_add (type, arg0, arg1, MINUS_EXPR);
07658 if (tem)
07659 return tem;
07660 }
07661
07662 if (! FLOAT_TYPE_P (type))
07663 {
07664 if (! wins && integer_zerop (arg0))
07665 return negate_expr (fold_convert (type, arg1));
07666 if (integer_zerop (arg1))
07667 return non_lvalue (fold_convert (type, arg0));
07668
07669
07670 if (!TREE_SIDE_EFFECTS (arg0)
07671 && TREE_CODE (arg1) == BIT_AND_EXPR)
07672 {
07673 if (operand_equal_p (arg0, TREE_OPERAND (arg1, 1), 0))
07674 return fold (build2 (BIT_AND_EXPR, type,
07675 fold (build1 (BIT_NOT_EXPR, type,
07676 TREE_OPERAND (arg1, 0))),
07677 arg0));
07678 if (operand_equal_p (arg0, TREE_OPERAND (arg1, 0), 0))
07679 return fold (build2 (BIT_AND_EXPR, type,
07680 fold (build1 (BIT_NOT_EXPR, type,
07681 TREE_OPERAND (arg1, 1))),
07682 arg0));
07683 }
07684
07685
07686
07687 if (TREE_CODE (arg0) == BIT_AND_EXPR
07688 && TREE_CODE (arg1) == BIT_AND_EXPR
07689 && operand_equal_p (TREE_OPERAND (arg0, 0),
07690 TREE_OPERAND (arg1, 0), 0))
07691 {
07692 tree mask0 = TREE_OPERAND (arg0, 1);
07693 tree mask1 = TREE_OPERAND (arg1, 1);
07694 tree tem = fold (build1 (BIT_NOT_EXPR, type, mask0));
07695
07696 if (operand_equal_p (tem, mask1, 0))
07697 {
07698 tem = fold (build2 (BIT_XOR_EXPR, type,
07699 TREE_OPERAND (arg0, 0), mask1));
07700 return fold (build2 (MINUS_EXPR, type, tem, mask1));
07701 }
07702 }
07703 }
07704
07705
07706 else if (fold_real_zero_addition_p (TREE_TYPE (arg0), arg1, 1))
07707 return non_lvalue (fold_convert (type, arg0));
07708
07709
07710
07711
07712 else if (!wins && fold_real_zero_addition_p (TREE_TYPE (arg1), arg0, 0))
07713 return negate_expr (fold_convert (type, arg1));
07714
07715
07716
07717
07718
07719
07720
07721 if ((! FLOAT_TYPE_P (type) || flag_unsafe_math_optimizations)
07722 && operand_equal_p (arg0, arg1, 0))
07723 return fold_convert (type, integer_zero_node);
07724
07725
07726 if (!wins && negate_expr_p (arg1)
07727 && ((FLOAT_TYPE_P (type)
07728
07729 && (TREE_CODE (arg1) != REAL_CST
07730 || REAL_VALUE_NEGATIVE (TREE_REAL_CST (arg1))))
07731 || (INTEGRAL_TYPE_P (type) && flag_wrapv && !flag_trapv)))
07732 return fold (build2 (PLUS_EXPR, type, arg0, negate_expr (arg1)));
07733
07734
07735 {
07736 HOST_WIDE_INT diff;
07737
07738 if ((TREE_CODE (arg0) == ADDR_EXPR
07739 || TREE_CODE (arg1) == ADDR_EXPR)
07740 && ptr_difference_const (arg0, arg1, &diff))
07741 return build_int_cst_type (type, diff);
07742 }
07743
07744
07745
07746
07747 if (TREE_CODE (arg0) == ADDR_EXPR
07748 && TREE_CODE (arg1) == MULT_EXPR)
07749 {
07750 tem = try_move_mult_to_index (MINUS_EXPR, arg0, arg1);
07751 if (tem)
07752 return fold_convert (type, fold (tem));
07753 }
07754
07755 if (TREE_CODE (arg0) == MULT_EXPR
07756 && TREE_CODE (arg1) == MULT_EXPR
07757 && (!FLOAT_TYPE_P (type) || flag_unsafe_math_optimizations))
07758 {
07759
07760 if (operand_equal_p (TREE_OPERAND (arg0, 1),
07761 TREE_OPERAND (arg1, 1), 0))
07762 return fold (build2 (MULT_EXPR, type,
07763 fold (build2 (MINUS_EXPR, type,
07764 TREE_OPERAND (arg0, 0),
07765 TREE_OPERAND (arg1, 0))),
07766 TREE_OPERAND (arg0, 1)));
07767
07768 if (operand_equal_p (TREE_OPERAND (arg0, 0),
07769 TREE_OPERAND (arg1, 0), 0))
07770 return fold (build2 (MULT_EXPR, type,
07771 TREE_OPERAND (arg0, 0),
07772 fold (build2 (MINUS_EXPR, type,
07773 TREE_OPERAND (arg0, 1),
07774 TREE_OPERAND (arg1, 1)))));
07775 }
07776
07777 goto associate;
07778
07779 case MULT_EXPR:
07780
07781 #ifdef KEY // bug 11662: (-A) * const -> A * (-const) causes str reduction bug,
07782
07783 if (flag_spin_file) {
07784 if (TREE_CODE (arg0) == NEGATE_EXPR && TREE_CODE (arg1) == NEGATE_EXPR)
07785 return fold (build2(MULT_EXPR, type, TREE_OPERAND (arg0, 0),
07786 TREE_OPERAND (arg1, 0)));
07787 }
07788 else {
07789 #endif
07790 if (TREE_CODE (arg0) == NEGATE_EXPR && negate_expr_p (arg1))
07791 return fold (build2 (MULT_EXPR, type,
07792 TREE_OPERAND (arg0, 0),
07793 negate_expr (arg1)));
07794 if (TREE_CODE (arg1) == NEGATE_EXPR && negate_expr_p (arg0))
07795 return fold (build2 (MULT_EXPR, type,
07796 negate_expr (arg0),
07797 TREE_OPERAND (arg1, 0)));
07798 #ifdef KEY // bug 11662
07799 }
07800 #endif
07801
07802 if (TREE_CODE (type) == COMPLEX_TYPE)
07803 {
07804 tem = fold_complex_mult (type, arg0, arg1);
07805 if (tem)
07806 return tem;
07807 }
07808
07809 if (! FLOAT_TYPE_P (type))
07810 {
07811 if (integer_zerop (arg1))
07812 return omit_one_operand (type, arg1, arg0);
07813 if (integer_onep (arg1))
07814 return non_lvalue (fold_convert (type, arg0));
07815
07816
07817 if (TREE_CODE (arg1) == LSHIFT_EXPR
07818 && integer_onep (TREE_OPERAND (arg1, 0)))
07819 return fold (build2 (LSHIFT_EXPR, type, arg0,
07820 TREE_OPERAND (arg1, 1)));
07821 if (TREE_CODE (arg0) == LSHIFT_EXPR
07822 && integer_onep (TREE_OPERAND (arg0, 0)))
07823 return fold (build2 (LSHIFT_EXPR, type, arg1,
07824 TREE_OPERAND (arg0, 1)));
07825
07826 if (TREE_CODE (arg1) == INTEGER_CST
07827 && 0 != (tem = extract_muldiv (TREE_OPERAND (t, 0),
07828 fold_convert (type, arg1),
07829 code, NULL_TREE)))
07830 return fold_convert (type, tem);
07831
07832 }
07833 else
07834 {
07835
07836
07837
07838
07839 if (!HONOR_NANS (TYPE_MODE (TREE_TYPE (arg0)))
07840 && !HONOR_SIGNED_ZEROS (TYPE_MODE (TREE_TYPE (arg0)))
07841 && real_zerop (arg1))
07842 return omit_one_operand (type, arg1, arg0);
07843
07844 if (!HONOR_SNANS (TYPE_MODE (TREE_TYPE (arg0)))
07845 && real_onep (arg1))
07846 return non_lvalue (fold_convert (type, arg0));
07847
07848
07849 if (!HONOR_SNANS (TYPE_MODE (TREE_TYPE (arg0)))
07850 && real_minus_onep (arg1))
07851 return fold_convert (type, negate_expr (arg0));
07852
07853
07854 if (flag_unsafe_math_optimizations
07855 && TREE_CODE (arg0) == RDIV_EXPR
07856 && TREE_CODE (arg1) == REAL_CST
07857 && TREE_CODE (TREE_OPERAND (arg0, 0)) == REAL_CST)
07858 {
07859 tree tem = const_binop (MULT_EXPR, TREE_OPERAND (arg0, 0),
07860 arg1, 0);
07861 if (tem)
07862 return fold (build2 (RDIV_EXPR, type, tem,
07863 TREE_OPERAND (arg0, 1)));
07864 }
07865
07866
07867 if (operand_equal_p (arg0, arg1, 0))
07868 {
07869 tree tem = fold_strip_sign_ops (arg0);
07870 if (tem != NULL_TREE)
07871 {
07872 tem = fold_convert (type, tem);
07873 return fold (build2 (MULT_EXPR, type, tem, tem));
07874 }
07875 }
07876
07877 if (flag_unsafe_math_optimizations)
07878 {
07879 enum built_in_function fcode0 = builtin_mathfn_code (arg0);
07880 enum built_in_function fcode1 = builtin_mathfn_code (arg1);
07881
07882
07883 if (fcode0 == fcode1 && BUILTIN_ROOT_P (fcode0))
07884 {
07885 tree rootfn, arg, arglist;
07886 tree arg00 = TREE_VALUE (TREE_OPERAND (arg0, 1));
07887 tree arg10 = TREE_VALUE (TREE_OPERAND (arg1, 1));
07888
07889
07890 if (BUILTIN_SQRT_P (fcode0)
07891 && operand_equal_p (arg00, arg10, 0)
07892 && ! HONOR_SNANS (TYPE_MODE (type)))
07893 return arg00;
07894
07895
07896 rootfn = TREE_OPERAND (TREE_OPERAND (arg0, 0), 0);
07897 arg = fold (build2 (MULT_EXPR, type, arg00, arg10));
07898 arglist = build_tree_list (NULL_TREE, arg);
07899 return build_function_call_expr (rootfn, arglist);
07900 }
07901
07902
07903 if (fcode0 == fcode1 && BUILTIN_EXPONENT_P (fcode0))
07904 {
07905 tree expfn = TREE_OPERAND (TREE_OPERAND (arg0, 0), 0);
07906 tree arg = build2 (PLUS_EXPR, type,
07907 TREE_VALUE (TREE_OPERAND (arg0, 1)),
07908 TREE_VALUE (TREE_OPERAND (arg1, 1)));
07909 tree arglist = build_tree_list (NULL_TREE, fold (arg));
07910 return build_function_call_expr (expfn, arglist);
07911 }
07912
07913
07914 if ((fcode0 == BUILT_IN_POW && fcode1 == BUILT_IN_POW)
07915 || (fcode0 == BUILT_IN_POWF && fcode1 == BUILT_IN_POWF)
07916 || (fcode0 == BUILT_IN_POWL && fcode1 == BUILT_IN_POWL))
07917 {
07918 tree arg00 = TREE_VALUE (TREE_OPERAND (arg0, 1));
07919 tree arg01 = TREE_VALUE (TREE_CHAIN (TREE_OPERAND (arg0,
07920 1)));
07921 tree arg10 = TREE_VALUE (TREE_OPERAND (arg1, 1));
07922 tree arg11 = TREE_VALUE (TREE_CHAIN (TREE_OPERAND (arg1,
07923 1)));
07924
07925
07926 if (operand_equal_p (arg01, arg11, 0))
07927 {
07928 tree powfn = TREE_OPERAND (TREE_OPERAND (arg0, 0), 0);
07929 tree arg = build2 (MULT_EXPR, type, arg00, arg10);
07930 tree arglist = tree_cons (NULL_TREE, fold (arg),
07931 build_tree_list (NULL_TREE,
07932 arg01));
07933 return build_function_call_expr (powfn, arglist);
07934 }
07935
07936
07937 if (operand_equal_p (arg00, arg10, 0))
07938 {
07939 tree powfn = TREE_OPERAND (TREE_OPERAND (arg0, 0), 0);
07940 tree arg = fold (build2 (PLUS_EXPR, type, arg01, arg11));
07941 tree arglist = tree_cons (NULL_TREE, arg00,
07942 build_tree_list (NULL_TREE,
07943 arg));
07944 return build_function_call_expr (powfn, arglist);
07945 }
07946 }
07947
07948
07949 if (((fcode0 == BUILT_IN_TAN && fcode1 == BUILT_IN_COS)
07950 || (fcode0 == BUILT_IN_TANF && fcode1 == BUILT_IN_COSF)
07951 || (fcode0 == BUILT_IN_TANL && fcode1 == BUILT_IN_COSL)
07952 || (fcode0 == BUILT_IN_COS && fcode1 == BUILT_IN_TAN)
07953 || (fcode0 == BUILT_IN_COSF && fcode1 == BUILT_IN_TANF)
07954 || (fcode0 == BUILT_IN_COSL && fcode1 == BUILT_IN_TANL))
07955 && operand_equal_p (TREE_VALUE (TREE_OPERAND (arg0, 1)),
07956 TREE_VALUE (TREE_OPERAND (arg1, 1)), 0))
07957 {
07958 tree sinfn = mathfn_built_in (type, BUILT_IN_SIN);
07959
07960 if (sinfn != NULL_TREE)
07961 return build_function_call_expr (sinfn,
07962 TREE_OPERAND (arg0, 1));
07963 }
07964
07965
07966 if (fcode1 == BUILT_IN_POW
07967 || fcode1 == BUILT_IN_POWF
07968 || fcode1 == BUILT_IN_POWL)
07969 {
07970 tree arg10 = TREE_VALUE (TREE_OPERAND (arg1, 1));
07971 tree arg11 = TREE_VALUE (TREE_CHAIN (TREE_OPERAND (arg1,
07972 1)));
07973 if (TREE_CODE (arg11) == REAL_CST
07974 && ! TREE_CONSTANT_OVERFLOW (arg11)
07975 && operand_equal_p (arg0, arg10, 0))
07976 {
07977 tree powfn = TREE_OPERAND (TREE_OPERAND (arg1, 0), 0);
07978 REAL_VALUE_TYPE c;
07979 tree arg, arglist;
07980
07981 c = TREE_REAL_CST (arg11);
07982 real_arithmetic (&c, PLUS_EXPR, &c, &dconst1);
07983 arg = build_real (type, c);
07984 arglist = build_tree_list (NULL_TREE, arg);
07985 arglist = tree_cons (NULL_TREE, arg0, arglist);
07986 return build_function_call_expr (powfn, arglist);
07987 }
07988 }
07989
07990
07991 if (fcode0 == BUILT_IN_POW
07992 || fcode0 == BUILT_IN_POWF
07993 || fcode0 == BUILT_IN_POWL)
07994 {
07995 tree arg00 = TREE_VALUE (TREE_OPERAND (arg0, 1));
07996 tree arg01 = TREE_VALUE (TREE_CHAIN (TREE_OPERAND (arg0,
07997 1)));
07998 if (TREE_CODE (arg01) == REAL_CST
07999 && ! TREE_CONSTANT_OVERFLOW (arg01)
08000 && operand_equal_p (arg1, arg00, 0))
08001 {
08002 tree powfn = TREE_OPERAND (TREE_OPERAND (arg0, 0), 0);
08003 REAL_VALUE_TYPE c;
08004 tree arg, arglist;
08005
08006 c = TREE_REAL_CST (arg01);
08007 real_arithmetic (&c, PLUS_EXPR, &c, &dconst1);
08008 arg = build_real (type, c);
08009 arglist = build_tree_list (NULL_TREE, arg);
08010 arglist = tree_cons (NULL_TREE, arg1, arglist);
08011 return build_function_call_expr (powfn, arglist);
08012 }
08013 }
08014
08015 #ifdef KEY
08016
08017
08018
08019
08020
08021
08022
08023 if (!flag_spin_file)
08024 #endif
08025
08026 if (! optimize_size
08027 && operand_equal_p (arg0, arg1, 0))
08028 {
08029 tree powfn = mathfn_built_in (type, BUILT_IN_POW);
08030
08031 if (powfn)
08032 {
08033 tree arg = build_real (type, dconst2);
08034 tree arglist = build_tree_list (NULL_TREE, arg);
08035 arglist = tree_cons (NULL_TREE, arg0, arglist);
08036 return build_function_call_expr (powfn, arglist);
08037 }
08038 }
08039 }
08040 }
08041 goto associate;
08042
08043 case BIT_IOR_EXPR:
08044 bit_ior:
08045 if (integer_all_onesp (arg1))
08046 return omit_one_operand (type, arg1, arg0);
08047 if (integer_zerop (arg1))
08048 return non_lvalue (fold_convert (type, arg0));
08049 if (operand_equal_p (arg0, arg1, 0))
08050 return non_lvalue (fold_convert (type, arg0));
08051
08052
08053 if (TREE_CODE (arg0) == BIT_NOT_EXPR
08054 && operand_equal_p (TREE_OPERAND (arg0, 0), arg1, 0))
08055 {
08056 t1 = build_int_cst (type, -1);
08057 t1 = force_fit_type (t1, 0, false, false);
08058 return omit_one_operand (type, t1, arg1);
08059 }
08060
08061
08062 if (TREE_CODE (arg1) == BIT_NOT_EXPR
08063 && operand_equal_p (arg0, TREE_OPERAND (arg1, 0), 0))
08064 {
08065 t1 = build_int_cst (type, -1);
08066 t1 = force_fit_type (t1, 0, false, false);
08067 return omit_one_operand (type, t1, arg0);
08068 }
08069
08070 t1 = distribute_bit_expr (code, type, arg0, arg1);
08071 if (t1 != NULL_TREE)
08072 return t1;
08073
08074
08075
08076
08077
08078
08079
08080 if (TREE_CODE (arg0) == BIT_NOT_EXPR
08081 && TREE_CODE (arg1) == BIT_NOT_EXPR)
08082 {
08083 return fold (build1 (BIT_NOT_EXPR, type,
08084 build2 (BIT_AND_EXPR, type,
08085 TREE_OPERAND (arg0, 0),
08086 TREE_OPERAND (arg1, 0))));
08087 }
08088
08089
08090
08091 goto bit_rotate;
08092
08093 case BIT_XOR_EXPR:
08094 if (integer_zerop (arg1))
08095 return non_lvalue (fold_convert (type, arg0));
08096 if (integer_all_onesp (arg1))
08097 return fold (build1 (BIT_NOT_EXPR, type, arg0));
08098 if (operand_equal_p (arg0, arg1, 0))
08099 return omit_one_operand (type, integer_zero_node, arg0);
08100
08101
08102 if (TREE_CODE (arg0) == BIT_NOT_EXPR
08103 && operand_equal_p (TREE_OPERAND (arg0, 0), arg1, 0))
08104 {
08105 t1 = build_int_cst (type, -1);
08106 t1 = force_fit_type (t1, 0, false, false);
08107 return omit_one_operand (type, t1, arg1);
08108 }
08109
08110
08111 if (TREE_CODE (arg1) == BIT_NOT_EXPR
08112 && operand_equal_p (arg0, TREE_OPERAND (arg1, 0), 0))
08113 {
08114 t1 = build_int_cst (type, -1);
08115 t1 = force_fit_type (t1, 0, false, false);
08116 return omit_one_operand (type, t1, arg0);
08117 }
08118
08119
08120
08121
08122
08123 if (TREE_CODE (arg0) == BIT_AND_EXPR
08124 && TREE_CODE (arg1) == BIT_AND_EXPR
08125 && TREE_CODE (TREE_OPERAND (arg0, 1)) == INTEGER_CST
08126 && TREE_CODE (TREE_OPERAND (arg1, 1)) == INTEGER_CST
08127 && integer_zerop (const_binop (BIT_AND_EXPR,
08128 TREE_OPERAND (arg0, 1),
08129 TREE_OPERAND (arg1, 1), 0)))
08130 {
08131 code = BIT_IOR_EXPR;
08132 goto bit_ior;
08133 }
08134
08135
08136
08137 goto bit_rotate;
08138
08139 case BIT_AND_EXPR:
08140 if (integer_all_onesp (arg1))
08141 return non_lvalue (fold_convert (type, arg0));
08142 if (integer_zerop (arg1))
08143 return omit_one_operand (type, arg1, arg0);
08144 if (operand_equal_p (arg0, arg1, 0))
08145 return non_lvalue (fold_convert (type, arg0));
08146
08147
08148 if (TREE_CODE (arg0) == BIT_NOT_EXPR
08149 && operand_equal_p (TREE_OPERAND (arg0, 0), arg1, 0))
08150 return omit_one_operand (type, integer_zero_node, arg1);
08151
08152
08153 if (TREE_CODE (arg1) == BIT_NOT_EXPR
08154 && operand_equal_p (arg0, TREE_OPERAND (arg1, 0), 0))
08155 return omit_one_operand (type, integer_zero_node, arg0);
08156
08157 t1 = distribute_bit_expr (code, type, arg0, arg1);
08158 if (t1 != NULL_TREE)
08159 return t1;
08160
08161 if (TREE_CODE (arg1) == INTEGER_CST && TREE_CODE (arg0) == NOP_EXPR
08162 && TYPE_UNSIGNED (TREE_TYPE (TREE_OPERAND (arg0, 0))))
08163 {
08164 unsigned int prec
08165 = TYPE_PRECISION (TREE_TYPE (TREE_OPERAND (arg0, 0)));
08166
08167 if (prec < BITS_PER_WORD && prec < HOST_BITS_PER_WIDE_INT
08168 && (~TREE_INT_CST_LOW (arg1)
08169 & (((HOST_WIDE_INT) 1 << prec) - 1)) == 0)
08170 return fold_convert (type, TREE_OPERAND (arg0, 0));
08171 }
08172
08173
08174
08175
08176
08177
08178
08179 if (TREE_CODE (arg0) == BIT_NOT_EXPR
08180 && TREE_CODE (arg1) == BIT_NOT_EXPR)
08181 {
08182 return fold (build1 (BIT_NOT_EXPR, type,
08183 build2 (BIT_IOR_EXPR, type,
08184 TREE_OPERAND (arg0, 0),
08185 TREE_OPERAND (arg1, 0))));
08186 }
08187
08188 goto associate;
08189
08190 case RDIV_EXPR:
08191
08192
08193 if (TREE_CODE (arg1) == REAL_CST
08194 && !MODE_HAS_INFINITIES (TYPE_MODE (TREE_TYPE (arg1)))
08195 && real_zerop (arg1))
08196 return t;
08197
08198
08199 if (TREE_CODE (arg0) == NEGATE_EXPR && negate_expr_p (arg1))
08200 return fold (build2 (RDIV_EXPR, type,
08201 TREE_OPERAND (arg0, 0),
08202 negate_expr (arg1)));
08203 if (TREE_CODE (arg1) == NEGATE_EXPR && negate_expr_p (arg0))
08204 return fold (build2 (RDIV_EXPR, type,
08205 negate_expr (arg0),
08206 TREE_OPERAND (arg1, 0)));
08207
08208
08209 if (!HONOR_SNANS (TYPE_MODE (TREE_TYPE (arg0)))
08210 && real_onep (arg1))
08211 return non_lvalue (fold_convert (type, arg0));
08212
08213
08214 if (!HONOR_SNANS (TYPE_MODE (TREE_TYPE (arg0)))
08215 && real_minus_onep (arg1))
08216 return non_lvalue (fold_convert (type, negate_expr (arg0)));
08217
08218
08219
08220
08221
08222
08223 if (TREE_CODE (arg1) == REAL_CST)
08224 {
08225 if (flag_unsafe_math_optimizations
08226 && 0 != (tem = const_binop (code, build_real (type, dconst1),
08227 arg1, 0)))
08228 return fold (build2 (MULT_EXPR, type, arg0, tem));
08229
08230 if (optimize)
08231 {
08232 REAL_VALUE_TYPE r;
08233 r = TREE_REAL_CST (arg1);
08234 if (exact_real_inverse (TYPE_MODE(TREE_TYPE(arg0)), &r))
08235 {
08236 tem = build_real (type, r);
08237 return fold (build2 (MULT_EXPR, type, arg0, tem));
08238 }
08239 }
08240 }
08241
08242 if (flag_unsafe_math_optimizations
08243 && TREE_CODE (arg0) == RDIV_EXPR)
08244 return fold (build2 (RDIV_EXPR, type, TREE_OPERAND (arg0, 0),
08245 fold (build2 (MULT_EXPR, type,
08246 TREE_OPERAND (arg0, 1), arg1))));
08247
08248
08249 if (flag_unsafe_math_optimizations
08250 && TREE_CODE (arg1) == RDIV_EXPR)
08251 return fold (build2 (MULT_EXPR, type,
08252 fold (build2 (RDIV_EXPR, type, arg0,
08253 TREE_OPERAND (arg1, 0))),
08254 TREE_OPERAND (arg1, 1)));
08255
08256
08257 if (flag_unsafe_math_optimizations
08258 && TREE_CODE (arg1) == MULT_EXPR
08259 && TREE_CODE (arg0) == REAL_CST
08260 && TREE_CODE (TREE_OPERAND (arg1, 1)) == REAL_CST)
08261 {
08262 tree tem = const_binop (RDIV_EXPR, arg0,
08263 TREE_OPERAND (arg1, 1), 0);
08264 if (tem)
08265 return fold (build2 (RDIV_EXPR, type, tem,
08266 TREE_OPERAND (arg1, 0)));
08267 }
08268
08269 if (TREE_CODE (type) == COMPLEX_TYPE)
08270 {
08271 tem = fold_complex_div (type, arg0, arg1, code);
08272 if (tem)
08273 return tem;
08274 }
08275
08276 if (flag_unsafe_math_optimizations)
08277 {
08278 enum built_in_function fcode = builtin_mathfn_code (arg1);
08279
08280 if (BUILTIN_EXPONENT_P (fcode))
08281 {
08282 tree expfn = TREE_OPERAND (TREE_OPERAND (arg1, 0), 0);
08283 tree arg = negate_expr (TREE_VALUE (TREE_OPERAND (arg1, 1)));
08284 tree arglist = build_tree_list (NULL_TREE,
08285 fold_convert (type, arg));
08286 arg1 = build_function_call_expr (expfn, arglist);
08287 return fold (build2 (MULT_EXPR, type, arg0, arg1));
08288 }
08289
08290
08291 if (fcode == BUILT_IN_POW
08292 || fcode == BUILT_IN_POWF
08293 || fcode == BUILT_IN_POWL)
08294 {
08295 tree powfn = TREE_OPERAND (TREE_OPERAND (arg1, 0), 0);
08296 tree arg10 = TREE_VALUE (TREE_OPERAND (arg1, 1));
08297 tree arg11 = TREE_VALUE (TREE_CHAIN (TREE_OPERAND (arg1, 1)));
08298 tree neg11 = fold_convert (type, negate_expr (arg11));
08299 tree arglist = tree_cons(NULL_TREE, arg10,
08300 build_tree_list (NULL_TREE, neg11));
08301 arg1 = build_function_call_expr (powfn, arglist);
08302 return fold (build2 (MULT_EXPR, type, arg0, arg1));
08303 }
08304 }
08305
08306 if (flag_unsafe_math_optimizations)
08307 {
08308 enum built_in_function fcode0 = builtin_mathfn_code (arg0);
08309 enum built_in_function fcode1 = builtin_mathfn_code (arg1);
08310
08311
08312 if (((fcode0 == BUILT_IN_SIN && fcode1 == BUILT_IN_COS)
08313 || (fcode0 == BUILT_IN_SINF && fcode1 == BUILT_IN_COSF)
08314 || (fcode0 == BUILT_IN_SINL && fcode1 == BUILT_IN_COSL))
08315 && operand_equal_p (TREE_VALUE (TREE_OPERAND (arg0, 1)),
08316 TREE_VALUE (TREE_OPERAND (arg1, 1)), 0))
08317 {
08318 tree tanfn = mathfn_built_in (type, BUILT_IN_TAN);
08319
08320 if (tanfn != NULL_TREE)
08321 return build_function_call_expr (tanfn,
08322 TREE_OPERAND (arg0, 1));
08323 }
08324
08325
08326 if (((fcode0 == BUILT_IN_COS && fcode1 == BUILT_IN_SIN)
08327 || (fcode0 == BUILT_IN_COSF && fcode1 == BUILT_IN_SINF)
08328 || (fcode0 == BUILT_IN_COSL && fcode1 == BUILT_IN_SINL))
08329 && operand_equal_p (TREE_VALUE (TREE_OPERAND (arg0, 1)),
08330 TREE_VALUE (TREE_OPERAND (arg1, 1)), 0))
08331 {
08332 tree tanfn = mathfn_built_in (type, BUILT_IN_TAN);
08333
08334 if (tanfn != NULL_TREE)
08335 {
08336 tree tmp = TREE_OPERAND (arg0, 1);
08337 tmp = build_function_call_expr (tanfn, tmp);
08338 return fold (build2 (RDIV_EXPR, type,
08339 build_real (type, dconst1), tmp));
08340 }
08341 }
08342
08343
08344 if (fcode0 == BUILT_IN_POW
08345 || fcode0 == BUILT_IN_POWF
08346 || fcode0 == BUILT_IN_POWL)
08347 {
08348 tree arg00 = TREE_VALUE (TREE_OPERAND (arg0, 1));
08349 tree arg01 = TREE_VALUE (TREE_CHAIN (TREE_OPERAND (arg0, 1)));
08350 if (TREE_CODE (arg01) == REAL_CST
08351 && ! TREE_CONSTANT_OVERFLOW (arg01)
08352 && operand_equal_p (arg1, arg00, 0))
08353 {
08354 tree powfn = TREE_OPERAND (TREE_OPERAND (arg0, 0), 0);
08355 REAL_VALUE_TYPE c;
08356 tree arg, arglist;
08357
08358 c = TREE_REAL_CST (arg01);
08359 real_arithmetic (&c, MINUS_EXPR, &c, &dconst1);
08360 arg = build_real (type, c);
08361 arglist = build_tree_list (NULL_TREE, arg);
08362 arglist = tree_cons (NULL_TREE, arg1, arglist);
08363 return build_function_call_expr (powfn, arglist);
08364 }
08365 }
08366 }
08367 goto binary;
08368
08369 case TRUNC_DIV_EXPR:
08370 case ROUND_DIV_EXPR:
08371 case FLOOR_DIV_EXPR:
08372 case CEIL_DIV_EXPR:
08373 case EXACT_DIV_EXPR:
08374 if (integer_onep (arg1))
08375 return non_lvalue (fold_convert (type, arg0));
08376 if (integer_zerop (arg1))
08377 return t;
08378
08379 if (!TYPE_UNSIGNED (type)
08380 && TREE_CODE (arg1) == INTEGER_CST
08381 && TREE_INT_CST_LOW (arg1) == (unsigned HOST_WIDE_INT) -1
08382 && TREE_INT_CST_HIGH (arg1) == -1)
08383 return fold_convert (type, negate_expr (arg0));
08384
08385
08386
08387
08388
08389
08390
08391 if ((code == CEIL_DIV_EXPR || code == FLOOR_DIV_EXPR)
08392 && multiple_of_p (type, arg0, arg1))
08393 return fold (build2 (EXACT_DIV_EXPR, type, arg0, arg1));
08394
08395 if (TREE_CODE (arg1) == INTEGER_CST
08396 && 0 != (tem = extract_muldiv (TREE_OPERAND (t, 0), arg1,
08397 code, NULL_TREE)))
08398 return fold_convert (type, tem);
08399
08400 if (TREE_CODE (type) == COMPLEX_TYPE)
08401 {
08402 tem = fold_complex_div (type, arg0, arg1, code);
08403 if (tem)
08404 return tem;
08405 }
08406 goto binary;
08407
08408 case CEIL_MOD_EXPR:
08409 case FLOOR_MOD_EXPR:
08410 case ROUND_MOD_EXPR:
08411 case TRUNC_MOD_EXPR:
08412
08413
08414 if (integer_onep (arg1))
08415 return omit_one_operand (type, integer_zero_node, arg0);
08416
08417
08418
08419 if (integer_zerop (arg1))
08420 return t;
08421
08422
08423
08424 if (integer_zerop (arg0))
08425 return omit_one_operand (type, integer_zero_node, arg1);
08426
08427
08428 if (!TYPE_UNSIGNED (type)
08429 && TREE_CODE (arg1) == INTEGER_CST
08430 && TREE_INT_CST_LOW (arg1) == (unsigned HOST_WIDE_INT) -1
08431 && TREE_INT_CST_HIGH (arg1) == -1)
08432 return omit_one_operand (type, integer_zero_node, arg0);
08433
08434
08435
08436 if (code == TRUNC_MOD_EXPR
08437 && TYPE_UNSIGNED (type)
08438 && integer_pow2p (arg1))
08439 {
08440 unsigned HOST_WIDE_INT high, low;
08441 tree mask;
08442 int l;
08443
08444 l = tree_log2 (arg1);
08445 if (l >= HOST_BITS_PER_WIDE_INT)
08446 {
08447 high = ((unsigned HOST_WIDE_INT) 1
08448 << (l - HOST_BITS_PER_WIDE_INT)) - 1;
08449 low = -1;
08450 }
08451 else
08452 {
08453 high = 0;
08454 low = ((unsigned HOST_WIDE_INT) 1 << l) - 1;
08455 }
08456
08457 mask = build_int_cst_wide (type, low, high);
08458 return fold (build2 (BIT_AND_EXPR, type,
08459 fold_convert (type, arg0), mask));
08460 }
08461
08462
08463 if (code == TRUNC_MOD_EXPR
08464 && !TYPE_UNSIGNED (type)
08465 && TREE_CODE (arg1) == INTEGER_CST
08466 && !TREE_CONSTANT_OVERFLOW (arg1)
08467 && TREE_INT_CST_HIGH (arg1) < 0
08468 && !flag_trapv
08469
08470 && !sign_bit_p (arg1, arg1))
08471 return fold (build2 (code, type, fold_convert (type, arg0),
08472 fold_convert (type, negate_expr (arg1))));
08473
08474
08475 if (code == TRUNC_MOD_EXPR
08476 && !TYPE_UNSIGNED (type)
08477 && TREE_CODE (arg1) == NEGATE_EXPR
08478 && !flag_trapv)
08479 return fold (build2 (code, type, fold_convert (type, arg0),
08480 fold_convert (type, TREE_OPERAND (arg1, 0))));
08481
08482 if (TREE_CODE (arg1) == INTEGER_CST
08483 && 0 != (tem = extract_muldiv (TREE_OPERAND (t, 0), arg1,
08484 code, NULL_TREE)))
08485 return fold_convert (type, tem);
08486
08487 goto binary;
08488
08489 case LROTATE_EXPR:
08490 case RROTATE_EXPR:
08491 if (integer_all_onesp (arg0))
08492 return omit_one_operand (type, arg0, arg1);
08493 goto shift;
08494
08495 case RSHIFT_EXPR:
08496
08497 if (integer_all_onesp (arg0) && !TYPE_UNSIGNED (type))
08498 return omit_one_operand (type, arg0, arg1);
08499
08500
08501 case LSHIFT_EXPR:
08502 shift:
08503 if (integer_zerop (arg1))
08504 return non_lvalue (fold_convert (type, arg0));
08505 if (integer_zerop (arg0))
08506 return omit_one_operand (type, arg0, arg1);
08507
08508
08509
08510 if (TREE_CODE (arg1) == INTEGER_CST && tree_int_cst_sgn (arg1) < 0)
08511 return t;
08512
08513
08514 if (code == LROTATE_EXPR && TREE_CODE (arg1) == INTEGER_CST)
08515 {
08516 tree tem = build_int_cst (NULL_TREE,
08517 GET_MODE_BITSIZE (TYPE_MODE (type)));
08518 tem = fold_convert (TREE_TYPE (arg1), tem);
08519 tem = const_binop (MINUS_EXPR, tem, arg1, 0);
08520 return fold (build2 (RROTATE_EXPR, type, arg0, tem));
08521 }
08522
08523
08524
08525
08526 if (code == RROTATE_EXPR && TREE_CODE (arg1) == INTEGER_CST
08527 && (TREE_CODE (arg0) == BIT_AND_EXPR
08528 || TREE_CODE (arg0) == BIT_IOR_EXPR
08529 || TREE_CODE (arg0) == BIT_XOR_EXPR)
08530 && TREE_CODE (TREE_OPERAND (arg0, 1)) == INTEGER_CST)
08531 return fold (build2 (TREE_CODE (arg0), type,
08532 fold (build2 (code, type,
08533 TREE_OPERAND (arg0, 0), arg1)),
08534 fold (build2 (code, type,
08535 TREE_OPERAND (arg0, 1), arg1))));
08536
08537
08538
08539 if (code == RROTATE_EXPR && TREE_CODE (arg1) == INTEGER_CST
08540 && TREE_CODE (arg0) == RROTATE_EXPR
08541 && TREE_CODE (TREE_OPERAND (arg0, 1)) == INTEGER_CST
08542 && TREE_INT_CST_HIGH (arg1) == 0
08543 && TREE_INT_CST_HIGH (TREE_OPERAND (arg0, 1)) == 0
08544 && ((TREE_INT_CST_LOW (arg1)
08545 + TREE_INT_CST_LOW (TREE_OPERAND (arg0, 1)))
08546 == (unsigned int) GET_MODE_BITSIZE (TYPE_MODE (type))))
08547 return TREE_OPERAND (arg0, 0);
08548
08549 goto binary;
08550
08551 case MIN_EXPR:
08552 if (operand_equal_p (arg0, arg1, 0))
08553 return omit_one_operand (type, arg0, arg1);
08554 if (INTEGRAL_TYPE_P (type)
08555 && operand_equal_p (arg1, TYPE_MIN_VALUE (type), OEP_ONLY_CONST))
08556 return omit_one_operand (type, arg1, arg0);
08557 goto associate;
08558
08559 case MAX_EXPR:
08560 if (operand_equal_p (arg0, arg1, 0))
08561 return omit_one_operand (type, arg0, arg1);
08562 if (INTEGRAL_TYPE_P (type)
08563 && TYPE_MAX_VALUE (type)
08564 && operand_equal_p (arg1, TYPE_MAX_VALUE (type), OEP_ONLY_CONST))
08565 return omit_one_operand (type, arg1, arg0);
08566 goto associate;
08567
08568 case TRUTH_NOT_EXPR:
08569
08570 if (TREE_CODE (TREE_TYPE (arg0)) != BOOLEAN_TYPE)
08571 arg0 = fold_convert (boolean_type_node, arg0);
08572
08573
08574
08575
08576
08577 tem = invert_truthvalue (arg0);
08578
08579 if (TREE_CODE (tem) == TRUTH_NOT_EXPR)
08580 return t;
08581 return fold_convert (type, tem);
08582
08583 case TRUTH_ANDIF_EXPR:
08584
08585
08586
08587
08588 if (integer_zerop (arg0))
08589 return fold_convert (type, arg0);
08590 case TRUTH_AND_EXPR:
08591
08592 if (TREE_CODE (arg0) == INTEGER_CST && ! integer_zerop (arg0))
08593 return non_lvalue (fold_convert (type, arg1));
08594 if (TREE_CODE (arg1) == INTEGER_CST && ! integer_zerop (arg1)
08595
08596 && (code != TRUTH_ANDIF_EXPR || ! TREE_SIDE_EFFECTS (arg0)))
08597 return non_lvalue (fold_convert (type, arg0));
08598
08599
08600 if (integer_zerop (arg1))
08601 return omit_one_operand (type, arg1, arg0);
08602
08603
08604 if (integer_zerop (arg0))
08605 return omit_one_operand (type, arg0, arg1);
08606
08607
08608 if (TREE_CODE (arg0) == TRUTH_NOT_EXPR
08609 && operand_equal_p (TREE_OPERAND (arg0, 0), arg1, 0))
08610 return omit_one_operand (type, integer_zero_node, arg1);
08611
08612 if (TREE_CODE (arg1) == TRUTH_NOT_EXPR
08613 && operand_equal_p (arg0, TREE_OPERAND (arg1, 0), 0))
08614 return omit_one_operand (type, integer_zero_node, arg0);
08615
08616
08617
08618
08619
08620 if (!TREE_SIDE_EFFECTS (arg0)
08621 && !TREE_SIDE_EFFECTS (arg1))
08622 {
08623 tem = fold_to_nonsharp_ineq_using_bound (arg0, arg1);
08624 if (tem)
08625 return fold (build2 (code, type, tem, arg1));
08626
08627 tem = fold_to_nonsharp_ineq_using_bound (arg1, arg0);
08628 if (tem)
08629 return fold (build2 (code, type, arg0, tem));
08630 }
08631
08632 truth_andor:
08633
08634 if (!optimize)
08635 return t;
08636
08637
08638
08639
08640
08641
08642
08643 if (TREE_CODE (arg0) == TREE_CODE (arg1)
08644 && (TREE_CODE (arg0) == TRUTH_ANDIF_EXPR
08645 || TREE_CODE (arg0) == TRUTH_ORIF_EXPR
08646 || TREE_CODE (arg0) == TRUTH_AND_EXPR
08647 || TREE_CODE (arg0) == TRUTH_OR_EXPR)
08648 && ! TREE_SIDE_EFFECTS (TREE_OPERAND (arg0, 1)))
08649 {
08650 tree a00 = TREE_OPERAND (arg0, 0);
08651 tree a01 = TREE_OPERAND (arg0, 1);
08652 tree a10 = TREE_OPERAND (arg1, 0);
08653 tree a11 = TREE_OPERAND (arg1, 1);
08654 int commutative = ((TREE_CODE (arg0) == TRUTH_OR_EXPR
08655 || TREE_CODE (arg0) == TRUTH_AND_EXPR)
08656 && (code == TRUTH_AND_EXPR
08657 || code == TRUTH_OR_EXPR));
08658
08659 if (operand_equal_p (a00, a10, 0))
08660 return fold (build2 (TREE_CODE (arg0), type, a00,
08661 fold (build2 (code, type, a01, a11))));
08662 else if (commutative && operand_equal_p (a00, a11, 0))
08663 return fold (build2 (TREE_CODE (arg0), type, a00,
08664 fold (build2 (code, type, a01, a10))));
08665 else if (commutative && operand_equal_p (a01, a10, 0))
08666 return fold (build2 (TREE_CODE (arg0), type, a01,
08667 fold (build2 (code, type, a00, a11))));
08668
08669
08670
08671
08672 else if ((commutative || ! TREE_SIDE_EFFECTS (a10))
08673 && operand_equal_p (a01, a11, 0))
08674 return fold (build2 (TREE_CODE (arg0), type,
08675 fold (build2 (code, type, a00, a10)),
08676 a01));
08677 }
08678
08679
08680 if (0 != (tem = fold_range_test (t)))
08681 return tem;
08682
08683
08684
08685
08686 if (TREE_CODE (arg0) == code
08687 && 0 != (tem = fold_truthop (code, type,
08688 TREE_OPERAND (arg0, 1), arg1)))
08689 return fold (build2 (code, type, TREE_OPERAND (arg0, 0), tem));
08690
08691 if ((tem = fold_truthop (code, type, arg0, arg1)) != 0)
08692 return tem;
08693
08694 return t;
08695
08696 case TRUTH_ORIF_EXPR:
08697
08698
08699
08700
08701 if (TREE_CODE (arg0) == INTEGER_CST && ! integer_zerop (arg0))
08702 return fold_convert (type, arg0);
08703 case TRUTH_OR_EXPR:
08704
08705 if (TREE_CODE (arg0) == INTEGER_CST && integer_zerop (arg0))
08706 return non_lvalue (fold_convert (type, arg1));
08707 if (TREE_CODE (arg1) == INTEGER_CST && integer_zerop (arg1)
08708
08709 && (code != TRUTH_ORIF_EXPR || ! TREE_SIDE_EFFECTS (arg0)))
08710 return non_lvalue (fold_convert (type, arg0));
08711
08712
08713 if (TREE_CODE (arg1) == INTEGER_CST && ! integer_zerop (arg1))
08714 return omit_one_operand (type, arg1, arg0);
08715
08716
08717 if (TREE_CODE (arg0) == INTEGER_CST && ! integer_zerop (arg0))
08718 return omit_one_operand (type, arg0, arg1);
08719
08720
08721 if (TREE_CODE (arg0) == TRUTH_NOT_EXPR
08722 && operand_equal_p (TREE_OPERAND (arg0, 0), arg1, 0))
08723 return omit_one_operand (type, integer_one_node, arg1);
08724
08725 if (TREE_CODE (arg1) == TRUTH_NOT_EXPR
08726 && operand_equal_p (arg0, TREE_OPERAND (arg1, 0), 0))
08727 return omit_one_operand (type, integer_one_node, arg0);
08728
08729 goto truth_andor;
08730
08731 case TRUTH_XOR_EXPR:
08732
08733 if (integer_zerop (arg1))
08734 return non_lvalue (fold_convert (type, arg0));
08735
08736 if (integer_onep (arg1))
08737 {
08738
08739 if (TREE_CODE (TREE_TYPE (arg0)) != BOOLEAN_TYPE)
08740 tem = fold (build1 (TRUTH_NOT_EXPR, TREE_TYPE (arg0), arg0));
08741 else
08742 tem = invert_truthvalue (arg0);
08743 return non_lvalue (fold_convert (type, tem));
08744 }
08745
08746 if (operand_equal_p (arg0, arg1, 0))
08747 return omit_one_operand (type, integer_zero_node, arg0);
08748
08749
08750 if (TREE_CODE (arg0) == TRUTH_NOT_EXPR
08751 && operand_equal_p (TREE_OPERAND (arg0, 0), arg1, 0))
08752 return omit_one_operand (type, integer_one_node, arg1);
08753
08754
08755 if (TREE_CODE (arg1) == TRUTH_NOT_EXPR
08756 && operand_equal_p (arg0, TREE_OPERAND (arg1, 0), 0))
08757 return omit_one_operand (type, integer_one_node, arg0);
08758
08759 return t;
08760
08761 case EQ_EXPR:
08762 case NE_EXPR:
08763 case LT_EXPR:
08764 case GT_EXPR:
08765 case LE_EXPR:
08766 case GE_EXPR:
08767
08768 if (tree_swap_operands_p (arg0, arg1, true))
08769 return fold (build2 (swap_tree_comparison (code), type, arg1, arg0));
08770
08771
08772
08773 if ((code == EQ_EXPR || code == NE_EXPR)
08774 && TREE_CODE (arg0) == ADDR_EXPR
08775 && DECL_P (TREE_OPERAND (arg0, 0))
08776 && ! DECL_WEAK (TREE_OPERAND (arg0, 0))
08777 && integer_zerop (arg1))
08778 return constant_boolean_node (code != EQ_EXPR, type);
08779
08780
08781
08782
08783 if ((code == EQ_EXPR || code == NE_EXPR)
08784 && TREE_CODE (arg0) == ADDR_EXPR
08785 && DECL_P (TREE_OPERAND (arg0, 0))
08786 && ! DECL_WEAK (TREE_OPERAND (arg0, 0))
08787 && ! lookup_attribute ("alias",
08788 DECL_ATTRIBUTES (TREE_OPERAND (arg0, 0)))
08789 && ! DECL_EXTERNAL (TREE_OPERAND (arg0, 0))
08790 && TREE_CODE (arg1) == ADDR_EXPR
08791 && DECL_P (TREE_OPERAND (arg1, 0))
08792 && ! DECL_WEAK (TREE_OPERAND (arg1, 0))
08793 && ! lookup_attribute ("alias",
08794 DECL_ATTRIBUTES (TREE_OPERAND (arg1, 0)))
08795 && ! DECL_EXTERNAL (TREE_OPERAND (arg1, 0)))
08796 {
08797
08798
08799
08800
08801
08802
08803
08804
08805
08806
08807
08808 bool equal = TREE_OPERAND (arg0, 0) == TREE_OPERAND (arg1, 0);
08809 return constant_boolean_node (equal
08810 ? code == EQ_EXPR : code != EQ_EXPR,
08811 type);
08812 }
08813
08814
08815
08816
08817 if (COMPARISON_CLASS_P (t))
08818 {
08819 tree base0, offset0, base1, offset1;
08820
08821 if (extract_array_ref (arg0, &base0, &offset0)
08822 && extract_array_ref (arg1, &base1, &offset1)
08823 && operand_equal_p (base0, base1, 0))
08824 {
08825 if (offset0 == NULL_TREE
08826 && offset1 == NULL_TREE)
08827 {
08828 offset0 = integer_zero_node;
08829 offset1 = integer_zero_node;
08830 }
08831 else if (offset0 == NULL_TREE)
08832 offset0 = build_int_cst (TREE_TYPE (offset1), 0);
08833 else if (offset1 == NULL_TREE)
08834 offset1 = build_int_cst (TREE_TYPE (offset0), 0);
08835
08836 if (TREE_TYPE (offset0) == TREE_TYPE (offset1))
08837 return fold (build2 (code, type, offset0, offset1));
08838 }
08839 }
08840
08841 if (FLOAT_TYPE_P (TREE_TYPE (arg0)))
08842 {
08843 tree targ0 = strip_float_extensions (arg0);
08844 tree targ1 = strip_float_extensions (arg1);
08845 tree newtype = TREE_TYPE (targ0);
08846
08847 if (TYPE_PRECISION (TREE_TYPE (targ1)) > TYPE_PRECISION (newtype))
08848 newtype = TREE_TYPE (targ1);
08849
08850
08851 if (TYPE_PRECISION (newtype) < TYPE_PRECISION (TREE_TYPE (arg0)))
08852 return fold (build2 (code, type, fold_convert (newtype, targ0),
08853 fold_convert (newtype, targ1)));
08854
08855
08856 if (TREE_CODE (arg0) == NEGATE_EXPR
08857 && TREE_CODE (arg1) == NEGATE_EXPR)
08858 return fold (build2 (code, type, TREE_OPERAND (arg1, 0),
08859 TREE_OPERAND (arg0, 0)));
08860
08861 if (TREE_CODE (arg1) == REAL_CST)
08862 {
08863 REAL_VALUE_TYPE cst;
08864 cst = TREE_REAL_CST (arg1);
08865
08866
08867 if (TREE_CODE (arg0) == NEGATE_EXPR)
08868 return
08869 fold (build2 (swap_tree_comparison (code), type,
08870 TREE_OPERAND (arg0, 0),
08871 build_real (TREE_TYPE (arg1),
08872 REAL_VALUE_NEGATE (cst))));
08873
08874
08875
08876 if (REAL_VALUE_MINUS_ZERO (cst))
08877 return fold (build2 (code, type, arg0,
08878 build_real (TREE_TYPE (arg1), dconst0)));
08879
08880
08881 if (REAL_VALUE_ISNAN (cst)
08882 && ! HONOR_SNANS (TYPE_MODE (TREE_TYPE (arg1))))
08883 {
08884 tem = (code == NE_EXPR) ? integer_one_node : integer_zero_node;
08885 return omit_one_operand (type, tem, arg0);
08886 }
08887
08888
08889 if (REAL_VALUE_ISINF (cst))
08890 {
08891 tem = fold_inf_compare (code, type, arg0, arg1);
08892 if (tem != NULL_TREE)
08893 return tem;
08894 }
08895 }
08896
08897
08898
08899
08900
08901 if (flag_unsafe_math_optimizations
08902 && TREE_CODE (arg1) == REAL_CST
08903 && (TREE_CODE (arg0) == PLUS_EXPR
08904 || TREE_CODE (arg0) == MINUS_EXPR)
08905 && TREE_CODE (TREE_OPERAND (arg0, 1)) == REAL_CST
08906 && 0 != (tem = const_binop (TREE_CODE (arg0) == PLUS_EXPR
08907 ? MINUS_EXPR : PLUS_EXPR,
08908 arg1, TREE_OPERAND (arg0, 1), 0))
08909 && ! TREE_CONSTANT_OVERFLOW (tem))
08910 return fold (build2 (code, type, TREE_OPERAND (arg0, 0), tem));
08911
08912
08913
08914
08915 if (flag_unsafe_math_optimizations
08916 && TREE_CODE (arg1) == REAL_CST
08917 && TREE_CODE (arg0) == MINUS_EXPR
08918 && TREE_CODE (TREE_OPERAND (arg0, 0)) == REAL_CST
08919 && 0 != (tem = const_binop (MINUS_EXPR, TREE_OPERAND (arg0, 0),
08920 arg1, 0))
08921 && ! TREE_CONSTANT_OVERFLOW (tem))
08922 return fold (build2 (swap_tree_comparison (code), type,
08923 TREE_OPERAND (arg0, 1), tem));
08924
08925
08926 if (TREE_CODE (arg1) == REAL_CST
08927 && flag_unsafe_math_optimizations
08928 && ! flag_errno_math)
08929 {
08930 enum built_in_function fcode = builtin_mathfn_code (arg0);
08931
08932 if (fcode != END_BUILTINS)
08933 {
08934 tem = fold_mathfn_compare (fcode, code, type, arg0, arg1);
08935 if (tem != NULL_TREE)
08936 return tem;
08937 }
08938 }
08939 }
08940
08941
08942 if (TREE_CONSTANT (arg1)
08943 && (TREE_CODE (arg0) == POSTINCREMENT_EXPR
08944 || TREE_CODE (arg0) == POSTDECREMENT_EXPR)
08945
08946
08947
08948
08949 && (POINTER_TYPE_P (TREE_TYPE (arg0))
08950 || (INTEGRAL_TYPE_P (TREE_TYPE (arg0))
08951 && (code == EQ_EXPR || code == NE_EXPR))))
08952 {
08953 tree varop, newconst;
08954
08955 if (TREE_CODE (arg0) == POSTINCREMENT_EXPR)
08956 {
08957 newconst = fold (build2 (PLUS_EXPR, TREE_TYPE (arg0),
08958 arg1, TREE_OPERAND (arg0, 1)));
08959 varop = build2 (PREINCREMENT_EXPR, TREE_TYPE (arg0),
08960 TREE_OPERAND (arg0, 0),
08961 TREE_OPERAND (arg0, 1));
08962 }
08963 else
08964 {
08965 newconst = fold (build2 (MINUS_EXPR, TREE_TYPE (arg0),
08966 arg1, TREE_OPERAND (arg0, 1)));
08967 varop = build2 (PREDECREMENT_EXPR, TREE_TYPE (arg0),
08968 TREE_OPERAND (arg0, 0),
08969 TREE_OPERAND (arg0, 1));
08970 }
08971
08972
08973
08974
08975 if (TREE_CODE (TREE_OPERAND (varop, 0)) == COMPONENT_REF
08976 && DECL_BIT_FIELD (TREE_OPERAND (TREE_OPERAND (varop, 0), 1))
08977 && host_integerp (DECL_SIZE (TREE_OPERAND
08978 (TREE_OPERAND (varop, 0), 1)), 1))
08979 {
08980 tree fielddecl = TREE_OPERAND (TREE_OPERAND (varop, 0), 1);
08981 HOST_WIDE_INT size = tree_low_cst (DECL_SIZE (fielddecl), 1);
08982 tree folded_compare, shift;
08983
08984
08985
08986
08987 folded_compare = fold (build2 (code, type,
08988 TREE_OPERAND (varop, 0), arg1));
08989 if (integer_zerop (folded_compare)
08990 || integer_onep (folded_compare))
08991 return omit_one_operand (type, folded_compare, varop);
08992
08993 shift = build_int_cst (NULL_TREE,
08994 TYPE_PRECISION (TREE_TYPE (varop)) - size);
08995 shift = fold_convert (TREE_TYPE (varop), shift);
08996 newconst = fold (build2 (LSHIFT_EXPR, TREE_TYPE (varop),
08997 newconst, shift));
08998 newconst = fold (build2 (RSHIFT_EXPR, TREE_TYPE (varop),
08999 newconst, shift));
09000 }
09001
09002 return fold (build2 (code, type, varop, newconst));
09003 }
09004
09005
09006
09007
09008 if (TREE_CODE (arg1) == INTEGER_CST
09009 && TREE_CODE (arg0) != INTEGER_CST
09010 && tree_int_cst_sgn (arg1) > 0)
09011 {
09012 switch (code)
09013 {
09014 case GE_EXPR:
09015 arg1 = const_binop (MINUS_EXPR, arg1, integer_one_node, 0);
09016 return fold (build2 (GT_EXPR, type, arg0, arg1));
09017
09018 case LT_EXPR:
09019 arg1 = const_binop (MINUS_EXPR, arg1, integer_one_node, 0);
09020 return fold (build2 (LE_EXPR, type, arg0, arg1));
09021
09022 default:
09023 break;
09024 }
09025 }
09026
09027
09028
09029
09030
09031
09032 {
09033 int width = GET_MODE_BITSIZE (TYPE_MODE (TREE_TYPE (arg1)));
09034
09035 if (TREE_CODE (arg1) == INTEGER_CST
09036 && ! TREE_CONSTANT_OVERFLOW (arg1)
09037 && width <= 2 * HOST_BITS_PER_WIDE_INT
09038 && (INTEGRAL_TYPE_P (TREE_TYPE (arg1))
09039 || POINTER_TYPE_P (TREE_TYPE (arg1))))
09040 {
09041 HOST_WIDE_INT signed_max_hi;
09042 unsigned HOST_WIDE_INT signed_max_lo;
09043 unsigned HOST_WIDE_INT max_hi, max_lo, min_hi, min_lo;
09044
09045 if (width <= HOST_BITS_PER_WIDE_INT)
09046 {
09047 signed_max_lo = ((unsigned HOST_WIDE_INT) 1 << (width - 1))
09048 - 1;
09049 signed_max_hi = 0;
09050 max_hi = 0;
09051
09052 if (TYPE_UNSIGNED (TREE_TYPE (arg1)))
09053 {
09054 max_lo = ((unsigned HOST_WIDE_INT) 2 << (width - 1)) - 1;
09055 min_lo = 0;
09056 min_hi = 0;
09057 }
09058 else
09059 {
09060 max_lo = signed_max_lo;
09061 min_lo = ((unsigned HOST_WIDE_INT) -1 << (width - 1));
09062 min_hi = -1;
09063 }
09064 }
09065 else
09066 {
09067 width -= HOST_BITS_PER_WIDE_INT;
09068 signed_max_lo = -1;
09069 signed_max_hi = ((unsigned HOST_WIDE_INT) 1 << (width - 1))
09070 - 1;
09071 max_lo = -1;
09072 min_lo = 0;
09073
09074 if (TYPE_UNSIGNED (TREE_TYPE (arg1)))
09075 {
09076 max_hi = ((unsigned HOST_WIDE_INT) 2 << (width - 1)) - 1;
09077 min_hi = 0;
09078 }
09079 else
09080 {
09081 max_hi = signed_max_hi;
09082 min_hi = ((unsigned HOST_WIDE_INT) -1 << (width - 1));
09083 }
09084 }
09085
09086 if ((unsigned HOST_WIDE_INT) TREE_INT_CST_HIGH (arg1) == max_hi
09087 && TREE_INT_CST_LOW (arg1) == max_lo)
09088 switch (code)
09089 {
09090 case GT_EXPR:
09091 return omit_one_operand (type, integer_zero_node, arg0);
09092
09093 case GE_EXPR:
09094 return fold (build2 (EQ_EXPR, type, arg0, arg1));
09095
09096 case LE_EXPR:
09097 return omit_one_operand (type, integer_one_node, arg0);
09098
09099 case LT_EXPR:
09100 return fold (build2 (NE_EXPR, type, arg0, arg1));
09101
09102
09103
09104
09105 default:
09106 break;
09107 }
09108 else if ((unsigned HOST_WIDE_INT) TREE_INT_CST_HIGH (arg1)
09109 == max_hi
09110 && TREE_INT_CST_LOW (arg1) == max_lo - 1)
09111 switch (code)
09112 {
09113 case GT_EXPR:
09114 arg1 = const_binop (PLUS_EXPR, arg1, integer_one_node, 0);
09115 return fold (build2 (EQ_EXPR, type, arg0, arg1));
09116 case LE_EXPR:
09117 arg1 = const_binop (PLUS_EXPR, arg1, integer_one_node, 0);
09118 return fold (build2 (NE_EXPR, type, arg0, arg1));
09119 default:
09120 break;
09121 }
09122 else if ((unsigned HOST_WIDE_INT) TREE_INT_CST_HIGH (arg1)
09123 == min_hi
09124 && TREE_INT_CST_LOW (arg1) == min_lo)
09125 switch (code)
09126 {
09127 case LT_EXPR:
09128 return omit_one_operand (type, integer_zero_node, arg0);
09129
09130 case LE_EXPR:
09131 return fold (build2 (EQ_EXPR, type, arg0, arg1));
09132
09133 case GE_EXPR:
09134 return omit_one_operand (type, integer_one_node, arg0);
09135
09136 case GT_EXPR:
09137 return fold (build2 (NE_EXPR, type, arg0, arg1));
09138
09139 default:
09140 break;
09141 }
09142 else if ((unsigned HOST_WIDE_INT) TREE_INT_CST_HIGH (arg1)
09143 == min_hi
09144 && TREE_INT_CST_LOW (arg1) == min_lo + 1)
09145 switch (code)
09146 {
09147 case GE_EXPR:
09148 arg1 = const_binop (MINUS_EXPR, arg1, integer_one_node, 0);
09149 return fold (build2 (NE_EXPR, type, arg0, arg1));
09150 case LT_EXPR:
09151 arg1 = const_binop (MINUS_EXPR, arg1, integer_one_node, 0);
09152 return fold (build2 (EQ_EXPR, type, arg0, arg1));
09153 default:
09154 break;
09155 }
09156
09157 else if (!in_gimple_form
09158 && TREE_INT_CST_HIGH (arg1) == signed_max_hi
09159 && TREE_INT_CST_LOW (arg1) == signed_max_lo
09160 && TYPE_UNSIGNED (TREE_TYPE (arg1))
09161
09162 && INTEGRAL_TYPE_P (TREE_TYPE (arg1)))
09163 {
09164
09165
09166 if (code == LE_EXPR || code == GT_EXPR)
09167 {
09168 tree st0, st1;
09169 st0 = lang_hooks.types.signed_type (TREE_TYPE (arg0));
09170 st1 = lang_hooks.types.signed_type (TREE_TYPE (arg1));
09171 return fold
09172 (build2 (code == LE_EXPR ? GE_EXPR: LT_EXPR,
09173 type, fold_convert (st0, arg0),
09174 fold_convert (st1, integer_zero_node)));
09175 }
09176 }
09177 }
09178 }
09179
09180
09181
09182
09183 if ((code == EQ_EXPR || code == NE_EXPR)
09184 && TREE_CODE (arg1) == INTEGER_CST
09185 && (TREE_CODE (arg0) == PLUS_EXPR
09186 || TREE_CODE (arg0) == MINUS_EXPR)
09187 && TREE_CODE (TREE_OPERAND (arg0, 1)) == INTEGER_CST
09188 && 0 != (tem = const_binop (TREE_CODE (arg0) == PLUS_EXPR
09189 ? MINUS_EXPR : PLUS_EXPR,
09190 arg1, TREE_OPERAND (arg0, 1), 0))
09191 && ! TREE_CONSTANT_OVERFLOW (tem))
09192 return fold (build2 (code, type, TREE_OPERAND (arg0, 0), tem));
09193
09194
09195 else if ((code == EQ_EXPR || code == NE_EXPR)
09196 && TREE_CODE (arg0) == NEGATE_EXPR
09197 && TREE_CODE (arg1) == INTEGER_CST
09198 && 0 != (tem = negate_expr (arg1))
09199 && TREE_CODE (tem) == INTEGER_CST
09200 && ! TREE_CONSTANT_OVERFLOW (tem))
09201 return fold (build2 (code, type, TREE_OPERAND (arg0, 0), tem));
09202
09203
09204
09205 else if ((code == NE_EXPR || code == EQ_EXPR)
09206 && integer_zerop (arg1) && TREE_CODE (arg0) == MINUS_EXPR)
09207 return fold (build2 (code, type,
09208 TREE_OPERAND (arg0, 0), TREE_OPERAND (arg0, 1)));
09209
09210 else if (TREE_CODE (TREE_TYPE (arg0)) == INTEGER_TYPE
09211 && (TREE_CODE (arg0) == NOP_EXPR
09212 || TREE_CODE (arg0) == CONVERT_EXPR))
09213 {
09214
09215
09216
09217 tem = fold_widened_comparison (code, type, arg0, arg1);
09218 if (tem)
09219 return tem;
09220
09221
09222 tem = fold_sign_changed_comparison (code, type, arg0, arg1);
09223 if (tem)
09224 return tem;
09225 }
09226
09227
09228
09229 else if (TREE_CODE (arg1) == INTEGER_CST
09230 && (TREE_CODE (arg0) == MIN_EXPR
09231 || TREE_CODE (arg0) == MAX_EXPR)
09232 && TREE_CODE (TREE_OPERAND (arg0, 1)) == INTEGER_CST)
09233 return optimize_minmax_comparison (t);
09234
09235
09236
09237
09238
09239
09240 else if (code == LE_EXPR && TREE_CODE (arg1) == INTEGER_CST
09241 && TREE_CODE (arg0) == ABS_EXPR
09242 && ! TREE_SIDE_EFFECTS (arg0)
09243 && (0 != (tem = negate_expr (arg1)))
09244 && TREE_CODE (tem) == INTEGER_CST
09245 && ! TREE_CONSTANT_OVERFLOW (tem))
09246 return fold (build2 (TRUTH_ANDIF_EXPR, type,
09247 build2 (GE_EXPR, type,
09248 TREE_OPERAND (arg0, 0), tem),
09249 build2 (LE_EXPR, type,
09250 TREE_OPERAND (arg0, 0), arg1)));
09251
09252
09253 else if (code == GE_EXPR
09254 && tree_expr_nonnegative_p (arg0)
09255 && (integer_zerop (arg1)
09256 || (! HONOR_NANS (TYPE_MODE (TREE_TYPE (arg0)))
09257 && real_zerop (arg1))))
09258 return omit_one_operand (type, integer_one_node, arg0);
09259
09260
09261 else if (code == LT_EXPR
09262 && tree_expr_nonnegative_p (arg0)
09263 && (integer_zerop (arg1) || real_zerop (arg1)))
09264 return omit_one_operand (type, integer_zero_node, arg0);
09265
09266
09267 else if ((code == EQ_EXPR || code == NE_EXPR)
09268 && TREE_CODE (arg0) == ABS_EXPR
09269 && (integer_zerop (arg1) || real_zerop (arg1)))
09270 return fold (build2 (code, type, TREE_OPERAND (arg0, 0), arg1));
09271
09272
09273
09274
09275
09276
09277 if (
09278 #ifdef KEY
09279
09280
09281 (!flag_spin_file || !flag_honor_shift) &&
09282 #endif
09283 integer_zerop (arg1) && (code == EQ_EXPR || code == NE_EXPR)
09284 && TREE_CODE (arg0) == BIT_AND_EXPR)
09285 {
09286 tree arg00 = TREE_OPERAND (arg0, 0);
09287 tree arg01 = TREE_OPERAND (arg0, 1);
09288 if (TREE_CODE (arg00) == LSHIFT_EXPR
09289 && integer_onep (TREE_OPERAND (arg00, 0)))
09290 return
09291 fold (build2 (code, type,
09292 build2 (BIT_AND_EXPR, TREE_TYPE (arg0),
09293 build2 (RSHIFT_EXPR, TREE_TYPE (arg00),
09294 arg01, TREE_OPERAND (arg00, 1)),
09295 fold_convert (TREE_TYPE (arg0),
09296 integer_one_node)),
09297 arg1));
09298 else if (TREE_CODE (TREE_OPERAND (arg0, 1)) == LSHIFT_EXPR
09299 && integer_onep (TREE_OPERAND (TREE_OPERAND (arg0, 1), 0)))
09300 return
09301 fold (build2 (code, type,
09302 build2 (BIT_AND_EXPR, TREE_TYPE (arg0),
09303 build2 (RSHIFT_EXPR, TREE_TYPE (arg01),
09304 arg00, TREE_OPERAND (arg01, 1)),
09305 fold_convert (TREE_TYPE (arg0),
09306 integer_one_node)),
09307 arg1));
09308 }
09309
09310
09311
09312
09313 if ((code == NE_EXPR || code == EQ_EXPR)
09314 && integer_zerop (arg1)
09315 && !TYPE_UNSIGNED (TREE_TYPE (arg0))
09316 && (TREE_CODE (arg0) == TRUNC_MOD_EXPR
09317 || TREE_CODE (arg0) == CEIL_MOD_EXPR
09318 || TREE_CODE (arg0) == FLOOR_MOD_EXPR
09319 || TREE_CODE (arg0) == ROUND_MOD_EXPR)
09320 && integer_pow2p (TREE_OPERAND (arg0, 1)))
09321 {
09322 tree newtype = lang_hooks.types.unsigned_type (TREE_TYPE (arg0));
09323 tree newmod = fold (build2 (TREE_CODE (arg0), newtype,
09324 fold_convert (newtype,
09325 TREE_OPERAND (arg0, 0)),
09326 fold_convert (newtype,
09327 TREE_OPERAND (arg0, 1))));
09328
09329 return fold (build2 (code, type, newmod,
09330 fold_convert (newtype, arg1)));
09331 }
09332
09333
09334
09335 if (code == NE_EXPR && integer_zerop (arg1)
09336 && TREE_CODE (arg0) == BIT_AND_EXPR
09337 && integer_onep (TREE_OPERAND (arg0, 1)))
09338 return fold_convert (type, arg0);
09339
09340
09341
09342 if ((code == EQ_EXPR || code == NE_EXPR)
09343 && TREE_CODE (arg0) == BIT_AND_EXPR
09344 && integer_pow2p (TREE_OPERAND (arg0, 1))
09345 && operand_equal_p (TREE_OPERAND (arg0, 1), arg1, 0))
09346 return fold (build2 (code == EQ_EXPR ? NE_EXPR : EQ_EXPR, type,
09347 arg0, fold_convert (TREE_TYPE (arg0),
09348 integer_zero_node)));
09349
09350
09351
09352 tem = fold_single_bit_test (code, arg0, arg1, type);
09353 if (tem)
09354 return tem;
09355
09356
09357
09358 if ((code == EQ_EXPR || code == NE_EXPR)
09359 && TREE_CODE (arg0) == BIT_AND_EXPR
09360 && TREE_CODE (arg1) == INTEGER_CST
09361 && TREE_CODE (TREE_OPERAND (arg0, 1)) == INTEGER_CST)
09362 {
09363 tree notc = fold (build1 (BIT_NOT_EXPR,
09364 TREE_TYPE (TREE_OPERAND (arg0, 1)),
09365 TREE_OPERAND (arg0, 1)));
09366 tree dandnotc = fold (build2 (BIT_AND_EXPR, TREE_TYPE (arg0),
09367 arg1, notc));
09368 tree rslt = code == EQ_EXPR ? integer_zero_node : integer_one_node;
09369 if (integer_nonzerop (dandnotc))
09370 return omit_one_operand (type, rslt, arg0);
09371 }
09372
09373
09374
09375 if ((code == EQ_EXPR || code == NE_EXPR)
09376 && TREE_CODE (arg0) == BIT_IOR_EXPR
09377 && TREE_CODE (arg1) == INTEGER_CST
09378 && TREE_CODE (TREE_OPERAND (arg0, 1)) == INTEGER_CST)
09379 {
09380 tree notd = fold (build1 (BIT_NOT_EXPR, TREE_TYPE (arg1), arg1));
09381 tree candnotd = fold (build2 (BIT_AND_EXPR, TREE_TYPE (arg0),
09382 TREE_OPERAND (arg0, 1), notd));
09383 tree rslt = code == EQ_EXPR ? integer_zero_node : integer_one_node;
09384 if (integer_nonzerop (candnotd))
09385 return omit_one_operand (type, rslt, arg0);
09386 }
09387
09388
09389
09390 if ((code == LT_EXPR || code == GE_EXPR)
09391 && TYPE_UNSIGNED (TREE_TYPE (arg0))
09392 && TREE_CODE (arg1) == LSHIFT_EXPR
09393 && integer_onep (TREE_OPERAND (arg1, 0)))
09394 return build2 (code == LT_EXPR ? EQ_EXPR : NE_EXPR, type,
09395 build2 (RSHIFT_EXPR, TREE_TYPE (arg0), arg0,
09396 TREE_OPERAND (arg1, 1)),
09397 fold_convert (TREE_TYPE (arg0), integer_zero_node));
09398
09399 else if ((code == LT_EXPR || code == GE_EXPR)
09400 && TYPE_UNSIGNED (TREE_TYPE (arg0))
09401 && (TREE_CODE (arg1) == NOP_EXPR
09402 || TREE_CODE (arg1) == CONVERT_EXPR)
09403 && TREE_CODE (TREE_OPERAND (arg1, 0)) == LSHIFT_EXPR
09404 && integer_onep (TREE_OPERAND (TREE_OPERAND (arg1, 0), 0)))
09405 return
09406 build2 (code == LT_EXPR ? EQ_EXPR : NE_EXPR, type,
09407 fold_convert (TREE_TYPE (arg0),
09408 build2 (RSHIFT_EXPR, TREE_TYPE (arg0), arg0,
09409 TREE_OPERAND (TREE_OPERAND (arg1, 0),
09410 1))),
09411 fold_convert (TREE_TYPE (arg0), integer_zero_node));
09412
09413
09414
09415 if (operand_equal_p (arg0, arg1, 0))
09416 {
09417 switch (code)
09418 {
09419 case EQ_EXPR:
09420 if (! FLOAT_TYPE_P (TREE_TYPE (arg0))
09421 || ! HONOR_NANS (TYPE_MODE (TREE_TYPE (arg0))))
09422 return constant_boolean_node (1, type);
09423 break;
09424
09425 case GE_EXPR:
09426 case LE_EXPR:
09427 if (! FLOAT_TYPE_P (TREE_TYPE (arg0))
09428 || ! HONOR_NANS (TYPE_MODE (TREE_TYPE (arg0))))
09429 return constant_boolean_node (1, type);
09430 return fold (build2 (EQ_EXPR, type, arg0, arg1));
09431
09432 case NE_EXPR:
09433
09434
09435 if (FLOAT_TYPE_P (TREE_TYPE (arg0))
09436 && HONOR_NANS (TYPE_MODE (TREE_TYPE (arg0))))
09437 break;
09438
09439 case GT_EXPR:
09440 case LT_EXPR:
09441 return constant_boolean_node (0, type);
09442 default:
09443 gcc_unreachable ();
09444 }
09445 }
09446
09447
09448
09449
09450
09451
09452
09453
09454
09455
09456
09457
09458
09459
09460 if (TREE_CODE (arg1) == INTEGER_CST && TREE_CODE (arg0) != INTEGER_CST)
09461 {
09462 tree cval1 = 0, cval2 = 0;
09463 int save_p = 0;
09464
09465 if (twoval_comparison_p (arg0, &cval1, &cval2, &save_p)
09466
09467
09468 && cval1 != 0 && cval2 != 0
09469 && ! (TREE_CONSTANT (cval1) && TREE_CONSTANT (cval2))
09470 && TREE_TYPE (cval1) == TREE_TYPE (cval2)
09471 && INTEGRAL_TYPE_P (TREE_TYPE (cval1))
09472 && TYPE_MAX_VALUE (TREE_TYPE (cval1))
09473 && TYPE_MAX_VALUE (TREE_TYPE (cval2))
09474 && ! operand_equal_p (TYPE_MIN_VALUE (TREE_TYPE (cval1)),
09475 TYPE_MAX_VALUE (TREE_TYPE (cval2)), 0))
09476 {
09477 tree maxval = TYPE_MAX_VALUE (TREE_TYPE (cval1));
09478 tree minval = TYPE_MIN_VALUE (TREE_TYPE (cval1));
09479
09480
09481
09482
09483 tree high_result
09484 = fold (build2 (code, type,
09485 eval_subst (arg0, cval1, maxval,
09486 cval2, minval),
09487 arg1));
09488 tree equal_result
09489 = fold (build2 (code, type,
09490 eval_subst (arg0, cval1, maxval,
09491 cval2, maxval),
09492 arg1));
09493 tree low_result
09494 = fold (build2 (code, type,
09495 eval_subst (arg0, cval1, minval,
09496 cval2, maxval),
09497 arg1));
09498
09499
09500
09501
09502
09503 if ((integer_zerop (high_result)
09504 || integer_onep (high_result))
09505 && (integer_zerop (equal_result)
09506 || integer_onep (equal_result))
09507 && (integer_zerop (low_result)
09508 || integer_onep (low_result)))
09509 {
09510
09511
09512 switch ((integer_onep (high_result) * 4)
09513 + (integer_onep (equal_result) * 2)
09514 + integer_onep (low_result))
09515 {
09516 case 0:
09517
09518 return omit_one_operand (type, integer_zero_node, arg0);
09519 case 1:
09520 code = LT_EXPR;
09521 break;
09522 case 2:
09523 code = EQ_EXPR;
09524 break;
09525 case 3:
09526 code = LE_EXPR;
09527 break;
09528 case 4:
09529 code = GT_EXPR;
09530 break;
09531 case 5:
09532 code = NE_EXPR;
09533 break;
09534 case 6:
09535 code = GE_EXPR;
09536 break;
09537 case 7:
09538
09539 return omit_one_operand (type, integer_one_node, arg0);
09540 }
09541
09542 tem = build2 (code, type, cval1, cval2);
09543 if (save_p)
09544 return save_expr (tem);
09545 else
09546 return fold (tem);
09547 }
09548 }
09549 }
09550
09551
09552 if (((TREE_CODE (arg0) == COMPONENT_REF
09553 && lang_hooks.can_use_bit_fields_p ())
09554 || TREE_CODE (arg0) == BIT_FIELD_REF)
09555 && (code == EQ_EXPR || code == NE_EXPR)
09556
09557
09558 && (optimize || TREE_CODE (arg1) == INTEGER_CST))
09559 {
09560 t1 = optimize_bit_field_compare (code, type, arg0, arg1);
09561 if (t1)
09562 return t1;
09563 }
09564
09565
09566
09567
09568
09569 if ((code == EQ_EXPR || code == NE_EXPR)
09570 && TREE_CODE (TREE_TYPE (arg0)) == COMPLEX_TYPE
09571 && (TREE_CODE (arg0) == COMPLEX_EXPR
09572 || TREE_CODE (arg1) == COMPLEX_EXPR
09573 || TREE_CODE (arg0) == COMPLEX_CST
09574 || TREE_CODE (arg1) == COMPLEX_CST))
09575 {
09576 tree subtype = TREE_TYPE (TREE_TYPE (arg0));
09577 tree real0, imag0, real1, imag1;
09578
09579 arg0 = save_expr (arg0);
09580 arg1 = save_expr (arg1);
09581 real0 = fold (build1 (REALPART_EXPR, subtype, arg0));
09582 imag0 = fold (build1 (IMAGPART_EXPR, subtype, arg0));
09583 real1 = fold (build1 (REALPART_EXPR, subtype, arg1));
09584 imag1 = fold (build1 (IMAGPART_EXPR, subtype, arg1));
09585
09586 return fold (build2 ((code == EQ_EXPR ? TRUTH_ANDIF_EXPR
09587 : TRUTH_ORIF_EXPR),
09588 type,
09589 fold (build2 (code, type, real0, real1)),
09590 fold (build2 (code, type, imag0, imag1))));
09591 }
09592
09593
09594
09595
09596
09597
09598
09599 if ((code == EQ_EXPR || code == NE_EXPR)
09600 && integer_zerop (arg1)
09601 && TREE_CODE (arg0) == CALL_EXPR)
09602 {
09603 tree fndecl = get_callee_fndecl (arg0);
09604 tree arglist;
09605
09606 if (fndecl
09607 && DECL_BUILT_IN_CLASS (fndecl) == BUILT_IN_NORMAL
09608 && DECL_FUNCTION_CODE (fndecl) == BUILT_IN_STRLEN
09609 && (arglist = TREE_OPERAND (arg0, 1))
09610 && TREE_CODE (TREE_TYPE (TREE_VALUE (arglist))) == POINTER_TYPE
09611 && ! TREE_CHAIN (arglist))
09612 return fold (build2 (code, type,
09613 build1 (INDIRECT_REF, char_type_node,
09614 TREE_VALUE (arglist)),
09615 fold_convert (char_type_node,
09616 integer_zero_node)));
09617 }
09618
09619
09620
09621 if ((TREE_CODE (arg0) == TRUNC_DIV_EXPR
09622 || TREE_CODE (arg0) == EXACT_DIV_EXPR)
09623 && TREE_CODE (arg1) == INTEGER_CST
09624 && TREE_CODE (TREE_OPERAND (arg0, 1)) == INTEGER_CST
09625 && !integer_zerop (TREE_OPERAND (arg0, 1))
09626 && !TREE_OVERFLOW (TREE_OPERAND (arg0, 1))
09627 && !TREE_OVERFLOW (arg1))
09628 {
09629 t1 = fold_div_compare (code, type, arg0, arg1);
09630 if (t1 != NULL_TREE)
09631 return t1;
09632 }
09633
09634 if ((code == EQ_EXPR || code == NE_EXPR)
09635 && !TREE_SIDE_EFFECTS (arg0)
09636 && integer_zerop (arg1)
09637 && tree_expr_nonzero_p (arg0))
09638 return constant_boolean_node (code==NE_EXPR, type);
09639
09640 t1 = fold_relational_const (code, type, arg0, arg1);
09641 return t1 == NULL_TREE ? t : t1;
09642
09643 case UNORDERED_EXPR:
09644 case ORDERED_EXPR:
09645 case UNLT_EXPR:
09646 case UNLE_EXPR:
09647 case UNGT_EXPR:
09648 case UNGE_EXPR:
09649 case UNEQ_EXPR:
09650 case LTGT_EXPR:
09651 if (TREE_CODE (arg0) == REAL_CST && TREE_CODE (arg1) == REAL_CST)
09652 {
09653 t1 = fold_relational_const (code, type, arg0, arg1);
09654 if (t1 != NULL_TREE)
09655 return t1;
09656 }
09657
09658
09659 if (TREE_CODE (arg0) == REAL_CST
09660 && REAL_VALUE_ISNAN (TREE_REAL_CST (arg0))
09661 && (code != LTGT_EXPR || ! flag_trapping_math))
09662 {
09663 t1 = (code == ORDERED_EXPR || code == LTGT_EXPR)
09664 ? integer_zero_node
09665 : integer_one_node;
09666 return omit_one_operand (type, t1, arg1);
09667 }
09668
09669
09670 if (TREE_CODE (arg1) == REAL_CST
09671 && REAL_VALUE_ISNAN (TREE_REAL_CST (arg1))
09672 && (code != LTGT_EXPR || ! flag_trapping_math))
09673 {
09674 t1 = (code == ORDERED_EXPR || code == LTGT_EXPR)
09675 ? integer_zero_node
09676 : integer_one_node;
09677 return omit_one_operand (type, t1, arg0);
09678 }
09679
09680
09681 if ((code == UNLE_EXPR || code == UNGE_EXPR || code == UNEQ_EXPR)
09682 && operand_equal_p (arg0, arg1, 0))
09683 return constant_boolean_node (1, type);
09684
09685 if (code == LTGT_EXPR
09686 && !flag_trapping_math
09687 && operand_equal_p (arg0, arg1, 0))
09688 return constant_boolean_node (0, type);
09689
09690
09691 {
09692 tree targ0 = strip_float_extensions (arg0);
09693 tree targ1 = strip_float_extensions (arg1);
09694 tree newtype = TREE_TYPE (targ0);
09695
09696 if (TYPE_PRECISION (TREE_TYPE (targ1)) > TYPE_PRECISION (newtype))
09697 newtype = TREE_TYPE (targ1);
09698
09699 if (TYPE_PRECISION (newtype) < TYPE_PRECISION (TREE_TYPE (arg0)))
09700 return fold (build2 (code, type, fold_convert (newtype, targ0),
09701 fold_convert (newtype, targ1)));
09702 }
09703
09704 return t;
09705
09706 case COND_EXPR:
09707
09708
09709 if (TREE_CODE (arg0) == INTEGER_CST)
09710 {
09711 tem = TREE_OPERAND (t, (integer_zerop (arg0) ? 2 : 1));
09712
09713
09714
09715 if (! VOID_TYPE_P (TREE_TYPE (tem))
09716 || VOID_TYPE_P (type))
09717 return pedantic_non_lvalue (tem);
09718 return t;
09719 }
09720 if (operand_equal_p (arg1, TREE_OPERAND (t, 2), 0))
09721 return pedantic_omit_one_operand (type, arg1, arg0);
09722
09723
09724
09725
09726
09727
09728
09729 if (COMPARISON_CLASS_P (arg0)
09730 && operand_equal_for_comparison_p (TREE_OPERAND (arg0, 0),
09731 arg1, TREE_OPERAND (arg0, 1))
09732 && !HONOR_SIGNED_ZEROS (TYPE_MODE (TREE_TYPE (arg1))))
09733 {
09734 tem = fold_cond_expr_with_comparison (type, arg0,
09735 TREE_OPERAND (t, 1),
09736 TREE_OPERAND (t, 2));
09737 if (tem)
09738 return tem;
09739 }
09740
09741 if (COMPARISON_CLASS_P (arg0)
09742 && operand_equal_for_comparison_p (TREE_OPERAND (arg0, 0),
09743 TREE_OPERAND (t, 2),
09744 TREE_OPERAND (arg0, 1))
09745 && !HONOR_SIGNED_ZEROS (TYPE_MODE (TREE_TYPE (TREE_OPERAND (t, 2)))))
09746 {
09747 tem = invert_truthvalue (arg0);
09748 if (COMPARISON_CLASS_P (tem))
09749 {
09750 tem = fold_cond_expr_with_comparison (type, tem,
09751 TREE_OPERAND (t, 2),
09752 TREE_OPERAND (t, 1));
09753 if (tem)
09754 return tem;
09755 }
09756 }
09757
09758
09759
09760 if (truth_value_p (TREE_CODE (arg0))
09761 && tree_swap_operands_p (TREE_OPERAND (t, 1),
09762 TREE_OPERAND (t, 2), false))
09763 {
09764
09765
09766
09767 tem = invert_truthvalue (arg0);
09768
09769 if (TREE_CODE (tem) != TRUTH_NOT_EXPR)
09770 return fold (build3 (code, type, tem,
09771 TREE_OPERAND (t, 2), TREE_OPERAND (t, 1)));
09772 }
09773
09774
09775 if (integer_onep (TREE_OPERAND (t, 1))
09776 && integer_zerop (TREE_OPERAND (t, 2))
09777
09778
09779
09780
09781 && type == TREE_TYPE (arg0))
09782 return pedantic_non_lvalue (arg0);
09783
09784
09785
09786 if (integer_zerop (TREE_OPERAND (t, 1))
09787 && integer_onep (TREE_OPERAND (t, 2))
09788 && truth_value_p (TREE_CODE (arg0)))
09789 return pedantic_non_lvalue (fold_convert (type,
09790 invert_truthvalue (arg0)));
09791
09792
09793 if (TREE_CODE (arg0) == LT_EXPR
09794 && integer_zerop (TREE_OPERAND (arg0, 1))
09795 && integer_zerop (TREE_OPERAND (t, 2))
09796 && (tem = sign_bit_p (TREE_OPERAND (arg0, 0), arg1)))
09797 return fold_convert (type, fold (build2 (BIT_AND_EXPR,
09798 TREE_TYPE (tem), tem, arg1)));
09799
09800
09801
09802 if (TREE_CODE (arg0) == BIT_AND_EXPR
09803 && integer_onep (TREE_OPERAND (arg0, 1))
09804 && integer_zerop (TREE_OPERAND (t, 2))
09805 && integer_pow2p (arg1))
09806 {
09807 tree tem = TREE_OPERAND (arg0, 0);
09808 STRIP_NOPS (tem);
09809 if (TREE_CODE (tem) == RSHIFT_EXPR
09810 && TREE_CODE (TREE_OPERAND (tem, 1)) == INTEGER_CST
09811 && (unsigned HOST_WIDE_INT) tree_log2 (arg1) ==
09812 TREE_INT_CST_LOW (TREE_OPERAND (tem, 1)))
09813 return fold (build2 (BIT_AND_EXPR, type,
09814 TREE_OPERAND (tem, 0), arg1));
09815 }
09816
09817
09818
09819
09820
09821 if (integer_zerop (TREE_OPERAND (t, 2))
09822 && TREE_CODE (arg0) == NE_EXPR
09823 && integer_zerop (TREE_OPERAND (arg0, 1))
09824 && integer_pow2p (arg1)
09825 && TREE_CODE (TREE_OPERAND (arg0, 0)) == BIT_AND_EXPR
09826 && operand_equal_p (TREE_OPERAND (TREE_OPERAND (arg0, 0), 1),
09827 arg1, OEP_ONLY_CONST))
09828 return pedantic_non_lvalue (fold_convert (type,
09829 TREE_OPERAND (arg0, 0)));
09830
09831
09832 if (integer_zerop (TREE_OPERAND (t, 2))
09833 && truth_value_p (TREE_CODE (arg0))
09834 && truth_value_p (TREE_CODE (arg1)))
09835 return fold (build2 (TRUTH_ANDIF_EXPR, type, arg0, arg1));
09836
09837
09838 if (integer_onep (TREE_OPERAND (t, 2))
09839 && truth_value_p (TREE_CODE (arg0))
09840 && truth_value_p (TREE_CODE (arg1)))
09841 {
09842
09843 tem = invert_truthvalue (arg0);
09844 if (TREE_CODE (tem) != TRUTH_NOT_EXPR)
09845 return fold (build2 (TRUTH_ORIF_EXPR, type, tem, arg1));
09846 }
09847
09848
09849 if (integer_zerop (arg1)
09850 && truth_value_p (TREE_CODE (arg0))
09851 && truth_value_p (TREE_CODE (TREE_OPERAND (t, 2))))
09852 {
09853
09854 tem = invert_truthvalue (arg0);
09855 if (TREE_CODE (tem) != TRUTH_NOT_EXPR)
09856 return fold (build2 (TRUTH_ANDIF_EXPR, type, tem,
09857 TREE_OPERAND (t, 2)));
09858 }
09859
09860
09861 if (integer_onep (arg1)
09862 && truth_value_p (TREE_CODE (arg0))
09863 && truth_value_p (TREE_CODE (TREE_OPERAND (t, 2))))
09864 return fold (build2 (TRUTH_ORIF_EXPR, type, arg0,
09865 TREE_OPERAND (t, 2)));
09866
09867 return t;
09868
09869 case COMPOUND_EXPR:
09870
09871
09872 if (TREE_SIDE_EFFECTS (arg0) || TREE_CONSTANT (arg1))
09873 return t;
09874
09875 tem = integer_zerop (arg1) ? build1 (NOP_EXPR, type, arg1)
09876 : fold_convert (type, arg1);
09877 return pedantic_non_lvalue (tem);
09878
09879 case COMPLEX_EXPR:
09880 if (wins)
09881 return build_complex (type, arg0, arg1);
09882 return t;
09883
09884 case REALPART_EXPR:
09885 if (TREE_CODE (TREE_TYPE (arg0)) != COMPLEX_TYPE)
09886 return t;
09887 else if (TREE_CODE (arg0) == COMPLEX_EXPR)
09888 return omit_one_operand (type, TREE_OPERAND (arg0, 0),
09889 TREE_OPERAND (arg0, 1));
09890 else if (TREE_CODE (arg0) == COMPLEX_CST)
09891 return TREE_REALPART (arg0);
09892 else if (TREE_CODE (arg0) == PLUS_EXPR || TREE_CODE (arg0) == MINUS_EXPR)
09893 return fold (build2 (TREE_CODE (arg0), type,
09894 fold (build1 (REALPART_EXPR, type,
09895 TREE_OPERAND (arg0, 0))),
09896 fold (build1 (REALPART_EXPR, type,
09897 TREE_OPERAND (arg0, 1)))));
09898 return t;
09899
09900 case IMAGPART_EXPR:
09901 if (TREE_CODE (TREE_TYPE (arg0)) != COMPLEX_TYPE)
09902 return fold_convert (type, integer_zero_node);
09903 else if (TREE_CODE (arg0) == COMPLEX_EXPR)
09904 return omit_one_operand (type, TREE_OPERAND (arg0, 1),
09905 TREE_OPERAND (arg0, 0));
09906 else if (TREE_CODE (arg0) == COMPLEX_CST)
09907 return TREE_IMAGPART (arg0);
09908 else if (TREE_CODE (arg0) == PLUS_EXPR || TREE_CODE (arg0) == MINUS_EXPR)
09909 return fold (build2 (TREE_CODE (arg0), type,
09910 fold (build1 (IMAGPART_EXPR, type,
09911 TREE_OPERAND (arg0, 0))),
09912 fold (build1 (IMAGPART_EXPR, type,
09913 TREE_OPERAND (arg0, 1)))));
09914 return t;
09915
09916 case CALL_EXPR:
09917
09918 if (TREE_CODE (TREE_OPERAND (t, 0)) == ADDR_EXPR
09919 && (TREE_CODE (TREE_OPERAND (TREE_OPERAND (t, 0), 0))
09920 == FUNCTION_DECL)
09921 && DECL_BUILT_IN (TREE_OPERAND (TREE_OPERAND (t, 0), 0)))
09922 {
09923 tree tmp = fold_builtin (t, false);
09924 if (tmp)
09925 return tmp;
09926 }
09927 return t;
09928
09929 default:
09930 return t;
09931 }
09932 }
09933
09934 #ifdef ENABLE_FOLD_CHECKING
09935 #undef fold
09936
09937 static void fold_checksum_tree (tree, struct md5_ctx *, htab_t);
09938 static void fold_check_failed (tree, tree);
09939 void print_fold_checksum (tree);
09940
09941
09942
09943
09944
09945 tree
09946 fold (tree expr)
09947 {
09948 tree ret;
09949 struct md5_ctx ctx;
09950 unsigned char checksum_before[16], checksum_after[16];
09951 htab_t ht;
09952
09953 ht = htab_create (32, htab_hash_pointer, htab_eq_pointer, NULL);
09954 md5_init_ctx (&ctx);
09955 fold_checksum_tree (expr, &ctx, ht);
09956 md5_finish_ctx (&ctx, checksum_before);
09957 htab_empty (ht);
09958
09959 ret = fold_1 (expr);
09960
09961 md5_init_ctx (&ctx);
09962 fold_checksum_tree (expr, &ctx, ht);
09963 md5_finish_ctx (&ctx, checksum_after);
09964 htab_delete (ht);
09965
09966 if (memcmp (checksum_before, checksum_after, 16))
09967 fold_check_failed (expr, ret);
09968
09969 return ret;
09970 }
09971
09972 void
09973 print_fold_checksum (tree expr)
09974 {
09975 struct md5_ctx ctx;
09976 unsigned char checksum[16], cnt;
09977 htab_t ht;
09978
09979 ht = htab_create (32, htab_hash_pointer, htab_eq_pointer, NULL);
09980 md5_init_ctx (&ctx);
09981 fold_checksum_tree (expr, &ctx, ht);
09982 md5_finish_ctx (&ctx, checksum);
09983 htab_delete (ht);
09984 for (cnt = 0; cnt < 16; ++cnt)
09985 fprintf (stderr, "%02x", checksum[cnt]);
09986 putc ('\n', stderr);
09987 }
09988
09989 static void
09990 fold_check_failed (tree expr ATTRIBUTE_UNUSED, tree ret ATTRIBUTE_UNUSED)
09991 {
09992 internal_error ("fold check: original tree changed by fold");
09993 }
09994
09995 static void
09996 fold_checksum_tree (tree expr, struct md5_ctx *ctx, htab_t ht)
09997 {
09998 void **slot;
09999 enum tree_code code;
10000 char buf[sizeof (struct tree_decl)];
10001 int i, len;
10002
10003 recursive_label:
10004
10005 gcc_assert ((sizeof (struct tree_exp) + 5 * sizeof (tree)
10006 <= sizeof (struct tree_decl))
10007 && sizeof (struct tree_type) <= sizeof (struct tree_decl));
10008 if (expr == NULL)
10009 return;
10010 slot = htab_find_slot (ht, expr, INSERT);
10011 if (*slot != NULL)
10012 return;
10013 *slot = expr;
10014 code = TREE_CODE (expr);
10015 if (TREE_CODE_CLASS (code) == tcc_declaration
10016 && DECL_ASSEMBLER_NAME_SET_P (expr))
10017 {
10018
10019 memcpy (buf, expr, tree_size (expr));
10020 expr = (tree) buf;
10021 SET_DECL_ASSEMBLER_NAME (expr, NULL);
10022 }
10023 else if (TREE_CODE_CLASS (code) == tcc_type
10024 && (TYPE_POINTER_TO (expr) || TYPE_REFERENCE_TO (expr)
10025 || TYPE_CACHED_VALUES_P (expr)
10026 || TYPE_CONTAINS_PLACEHOLDER_INTERNAL (expr)))
10027 {
10028
10029 memcpy (buf, expr, tree_size (expr));
10030 expr = (tree) buf;
10031 TYPE_CONTAINS_PLACEHOLDER_INTERNAL (expr) = 0;
10032 TYPE_POINTER_TO (expr) = NULL;
10033 TYPE_REFERENCE_TO (expr) = NULL;
10034 if (TYPE_CACHED_VALUES_P (expr))
10035 {
10036 TYPE_CACHED_VALUES_P (expr) = 0;
10037 TYPE_CACHED_VALUES (expr) = NULL;
10038 }
10039 }
10040 md5_process_bytes (expr, tree_size (expr), ctx);
10041 fold_checksum_tree (TREE_TYPE (expr), ctx, ht);
10042 if (TREE_CODE_CLASS (code) != tcc_type
10043 && TREE_CODE_CLASS (code) != tcc_declaration
10044 && code != TREE_LIST)
10045 fold_checksum_tree (TREE_CHAIN (expr), ctx, ht);
10046 switch (TREE_CODE_CLASS (code))
10047 {
10048 case tcc_constant:
10049 switch (code)
10050 {
10051 case STRING_CST:
10052 md5_process_bytes (TREE_STRING_POINTER (expr),
10053 TREE_STRING_LENGTH (expr), ctx);
10054 break;
10055 case COMPLEX_CST:
10056 fold_checksum_tree (TREE_REALPART (expr), ctx, ht);
10057 fold_checksum_tree (TREE_IMAGPART (expr), ctx, ht);
10058 break;
10059 case VECTOR_CST:
10060 fold_checksum_tree (TREE_VECTOR_CST_ELTS (expr), ctx, ht);
10061 break;
10062 default:
10063 break;
10064 }
10065 break;
10066 case tcc_exceptional:
10067 switch (code)
10068 {
10069 case TREE_LIST:
10070 fold_checksum_tree (TREE_PURPOSE (expr), ctx, ht);
10071 fold_checksum_tree (TREE_VALUE (expr), ctx, ht);
10072 expr = TREE_CHAIN (expr);
10073 goto recursive_label;
10074 break;
10075 case TREE_VEC:
10076 for (i = 0; i < TREE_VEC_LENGTH (expr); ++i)
10077 fold_checksum_tree (TREE_VEC_ELT (expr, i), ctx, ht);
10078 break;
10079 default:
10080 break;
10081 }
10082 break;
10083 case tcc_expression:
10084 case tcc_reference:
10085 case tcc_comparison:
10086 case tcc_unary:
10087 case tcc_binary:
10088 case tcc_statement:
10089 len = TREE_CODE_LENGTH (code);
10090 for (i = 0; i < len; ++i)
10091 fold_checksum_tree (TREE_OPERAND (expr, i), ctx, ht);
10092 break;
10093 case tcc_declaration:
10094 fold_checksum_tree (DECL_SIZE (expr), ctx, ht);
10095 fold_checksum_tree (DECL_SIZE_UNIT (expr), ctx, ht);
10096 fold_checksum_tree (DECL_NAME (expr), ctx, ht);
10097 fold_checksum_tree (DECL_CONTEXT (expr), ctx, ht);
10098 fold_checksum_tree (DECL_ARGUMENTS (expr), ctx, ht);
10099 fold_checksum_tree (DECL_RESULT_FLD (expr), ctx, ht);
10100 fold_checksum_tree (DECL_INITIAL (expr), ctx, ht);
10101 fold_checksum_tree (DECL_ABSTRACT_ORIGIN (expr), ctx, ht);
10102 fold_checksum_tree (DECL_SECTION_NAME (expr), ctx, ht);
10103 fold_checksum_tree (DECL_ATTRIBUTES (expr), ctx, ht);
10104 fold_checksum_tree (DECL_VINDEX (expr), ctx, ht);
10105 break;
10106 case tcc_type:
10107 if (TREE_CODE (expr) == ENUMERAL_TYPE)
10108 fold_checksum_tree (TYPE_VALUES (expr), ctx, ht);
10109 fold_checksum_tree (TYPE_SIZE (expr), ctx, ht);
10110 fold_checksum_tree (TYPE_SIZE_UNIT (expr), ctx, ht);
10111 fold_checksum_tree (TYPE_ATTRIBUTES (expr), ctx, ht);
10112 fold_checksum_tree (TYPE_NAME (expr), ctx, ht);
10113 if (INTEGRAL_TYPE_P (expr)
10114 || SCALAR_FLOAT_TYPE_P (expr))
10115 {
10116 fold_checksum_tree (TYPE_MIN_VALUE (expr), ctx, ht);
10117 fold_checksum_tree (TYPE_MAX_VALUE (expr), ctx, ht);
10118 }
10119 fold_checksum_tree (TYPE_MAIN_VARIANT (expr), ctx, ht);
10120 if (TREE_CODE (expr) == RECORD_TYPE
10121 || TREE_CODE (expr) == UNION_TYPE
10122 || TREE_CODE (expr) == QUAL_UNION_TYPE)
10123 fold_checksum_tree (TYPE_BINFO (expr), ctx, ht);
10124 fold_checksum_tree (TYPE_CONTEXT (expr), ctx, ht);
10125 break;
10126 default:
10127 break;
10128 }
10129 }
10130
10131 #endif
10132
10133
10134
10135
10136
10137 tree
10138 fold_initializer (tree expr)
10139 {
10140 int saved_signaling_nans = flag_signaling_nans;
10141 int saved_trapping_math = flag_trapping_math;
10142 int saved_rounding_math = flag_rounding_math;
10143 int saved_trapv = flag_trapv;
10144 tree result;
10145
10146 flag_signaling_nans = 0;
10147 flag_trapping_math = 0;
10148 flag_rounding_math = 0;
10149 flag_trapv = 0;
10150
10151 result = fold (expr);
10152
10153 flag_signaling_nans = saved_signaling_nans;
10154 flag_trapping_math = saved_trapping_math;
10155 flag_rounding_math = saved_rounding_math;
10156 flag_trapv = saved_trapv;
10157
10158 return result;
10159 }
10160
10161
10162
10163
10164
10165
10166
10167
10168
10169
10170
10171
10172
10173
10174
10175
10176
10177
10178
10179
10180
10181
10182
10183
10184
10185
10186
10187
10188
10189
10190
10191
10192
10193
10194
10195
10196
10197
10198
10199
10200
10201 static int
10202 multiple_of_p (tree type, tree top, tree bottom)
10203 {
10204 if (operand_equal_p (top, bottom, 0))
10205 return 1;
10206
10207 if (TREE_CODE (type) != INTEGER_TYPE)
10208 return 0;
10209
10210 switch (TREE_CODE (top))
10211 {
10212 case BIT_AND_EXPR:
10213
10214
10215 if (!integer_pow2p (bottom))
10216 return 0;
10217
10218
10219 case MULT_EXPR:
10220 return (multiple_of_p (type, TREE_OPERAND (top, 0), bottom)
10221 || multiple_of_p (type, TREE_OPERAND (top, 1), bottom));
10222
10223 case PLUS_EXPR:
10224 case MINUS_EXPR:
10225 return (multiple_of_p (type, TREE_OPERAND (top, 0), bottom)
10226 && multiple_of_p (type, TREE_OPERAND (top, 1), bottom));
10227
10228 case LSHIFT_EXPR:
10229 if (TREE_CODE (TREE_OPERAND (top, 1)) == INTEGER_CST)
10230 {
10231 tree op1, t1;
10232
10233 op1 = TREE_OPERAND (top, 1);
10234
10235
10236 if (TYPE_PRECISION (TREE_TYPE (size_one_node))
10237 > TREE_INT_CST_LOW (op1)
10238 && TREE_INT_CST_HIGH (op1) == 0
10239 && 0 != (t1 = fold_convert (type,
10240 const_binop (LSHIFT_EXPR,
10241 size_one_node,
10242 op1, 0)))
10243 && ! TREE_OVERFLOW (t1))
10244 return multiple_of_p (type, t1, bottom);
10245 }
10246 return 0;
10247
10248 case NOP_EXPR:
10249
10250 if ((TREE_CODE (TREE_TYPE (TREE_OPERAND (top, 0))) != INTEGER_TYPE)
10251 || (TYPE_PRECISION (type)
10252 < TYPE_PRECISION (TREE_TYPE (TREE_OPERAND (top, 0)))))
10253 return 0;
10254
10255
10256
10257 case SAVE_EXPR:
10258 return multiple_of_p (type, TREE_OPERAND (top, 0), bottom);
10259
10260 case INTEGER_CST:
10261 if (TREE_CODE (bottom) != INTEGER_CST
10262 || (TYPE_UNSIGNED (type)
10263 && (tree_int_cst_sgn (top) < 0
10264 || tree_int_cst_sgn (bottom) < 0)))
10265 return 0;
10266 return integer_zerop (const_binop (TRUNC_MOD_EXPR,
10267 top, bottom, 0));
10268
10269 default:
10270 return 0;
10271 }
10272 }
10273
10274
10275
10276 int
10277 tree_expr_nonnegative_p (tree t)
10278 {
10279 switch (TREE_CODE (t))
10280 {
10281 case ABS_EXPR:
10282 return 1;
10283
10284 case INTEGER_CST:
10285 return tree_int_cst_sgn (t) >= 0;
10286
10287 case REAL_CST:
10288 return ! REAL_VALUE_NEGATIVE (TREE_REAL_CST (t));
10289
10290 case PLUS_EXPR:
10291 if (FLOAT_TYPE_P (TREE_TYPE (t)))
10292 return tree_expr_nonnegative_p (TREE_OPERAND (t, 0))
10293 && tree_expr_nonnegative_p (TREE_OPERAND (t, 1));
10294
10295
10296
10297 if (TREE_CODE (TREE_TYPE (t)) == INTEGER_TYPE
10298 && TREE_CODE (TREE_OPERAND (t, 0)) == NOP_EXPR
10299 && TREE_CODE (TREE_OPERAND (t, 1)) == NOP_EXPR)
10300 {
10301 tree inner1 = TREE_TYPE (TREE_OPERAND (TREE_OPERAND (t, 0), 0));
10302 tree inner2 = TREE_TYPE (TREE_OPERAND (TREE_OPERAND (t, 1), 0));
10303 if (TREE_CODE (inner1) == INTEGER_TYPE && TYPE_UNSIGNED (inner1)
10304 && TREE_CODE (inner2) == INTEGER_TYPE && TYPE_UNSIGNED (inner2))
10305 {
10306 unsigned int prec = MAX (TYPE_PRECISION (inner1),
10307 TYPE_PRECISION (inner2)) + 1;
10308 return prec < TYPE_PRECISION (TREE_TYPE (t));
10309 }
10310 }
10311 break;
10312
10313 case MULT_EXPR:
10314 if (FLOAT_TYPE_P (TREE_TYPE (t)))
10315 {
10316
10317 if (operand_equal_p (TREE_OPERAND (t, 0), TREE_OPERAND (t, 1), 0))
10318 return 1;
10319 return tree_expr_nonnegative_p (TREE_OPERAND (t, 0))
10320 && tree_expr_nonnegative_p (TREE_OPERAND (t, 1));
10321 }
10322
10323
10324
10325 if (TREE_CODE (TREE_TYPE (t)) == INTEGER_TYPE
10326 && TREE_CODE (TREE_OPERAND (t, 0)) == NOP_EXPR
10327 && TREE_CODE (TREE_OPERAND (t, 1)) == NOP_EXPR)
10328 {
10329 tree inner1 = TREE_TYPE (TREE_OPERAND (TREE_OPERAND (t, 0), 0));
10330 tree inner2 = TREE_TYPE (TREE_OPERAND (TREE_OPERAND (t, 1), 0));
10331 if (TREE_CODE (inner1) == INTEGER_TYPE && TYPE_UNSIGNED (inner1)
10332 && TREE_CODE (inner2) == INTEGER_TYPE && TYPE_UNSIGNED (inner2))
10333 return TYPE_PRECISION (inner1) + TYPE_PRECISION (inner2)
10334 < TYPE_PRECISION (TREE_TYPE (t));
10335 }
10336 return 0;
10337
10338 case TRUNC_DIV_EXPR:
10339 case CEIL_DIV_EXPR:
10340 case FLOOR_DIV_EXPR:
10341 case ROUND_DIV_EXPR:
10342 return tree_expr_nonnegative_p (TREE_OPERAND (t, 0))
10343 && tree_expr_nonnegative_p (TREE_OPERAND (t, 1));
10344
10345 case TRUNC_MOD_EXPR:
10346 case CEIL_MOD_EXPR:
10347 case FLOOR_MOD_EXPR:
10348 case ROUND_MOD_EXPR:
10349 return tree_expr_nonnegative_p (TREE_OPERAND (t, 0));
10350
10351 case RDIV_EXPR:
10352 return tree_expr_nonnegative_p (TREE_OPERAND (t, 0))
10353 && tree_expr_nonnegative_p (TREE_OPERAND (t, 1));
10354
10355 case BIT_AND_EXPR:
10356 return tree_expr_nonnegative_p (TREE_OPERAND (t, 1))
10357 || tree_expr_nonnegative_p (TREE_OPERAND (t, 0));
10358 case BIT_IOR_EXPR:
10359 case BIT_XOR_EXPR:
10360 return tree_expr_nonnegative_p (TREE_OPERAND (t, 0))
10361 && tree_expr_nonnegative_p (TREE_OPERAND (t, 1));
10362
10363 case NOP_EXPR:
10364 {
10365 tree inner_type = TREE_TYPE (TREE_OPERAND (t, 0));
10366 tree outer_type = TREE_TYPE (t);
10367
10368 if (TREE_CODE (outer_type) == REAL_TYPE)
10369 {
10370 if (TREE_CODE (inner_type) == REAL_TYPE)
10371 return tree_expr_nonnegative_p (TREE_OPERAND (t, 0));
10372 if (TREE_CODE (inner_type) == INTEGER_TYPE)
10373 {
10374 if (TYPE_UNSIGNED (inner_type))
10375 return 1;
10376 return tree_expr_nonnegative_p (TREE_OPERAND (t, 0));
10377 }
10378 }
10379 else if (TREE_CODE (outer_type) == INTEGER_TYPE)
10380 {
10381 if (TREE_CODE (inner_type) == REAL_TYPE)
10382 return tree_expr_nonnegative_p (TREE_OPERAND (t,0));
10383 if (TREE_CODE (inner_type) == INTEGER_TYPE)
10384 return TYPE_PRECISION (inner_type) < TYPE_PRECISION (outer_type)
10385 && TYPE_UNSIGNED (inner_type);
10386 }
10387 }
10388 break;
10389
10390 case COND_EXPR:
10391 return tree_expr_nonnegative_p (TREE_OPERAND (t, 1))
10392 && tree_expr_nonnegative_p (TREE_OPERAND (t, 2));
10393 case COMPOUND_EXPR:
10394 return tree_expr_nonnegative_p (TREE_OPERAND (t, 1));
10395 case MIN_EXPR:
10396 return tree_expr_nonnegative_p (TREE_OPERAND (t, 0))
10397 && tree_expr_nonnegative_p (TREE_OPERAND (t, 1));
10398 case MAX_EXPR:
10399 return tree_expr_nonnegative_p (TREE_OPERAND (t, 0))
10400 || tree_expr_nonnegative_p (TREE_OPERAND (t, 1));
10401 case MODIFY_EXPR:
10402 return tree_expr_nonnegative_p (TREE_OPERAND (t, 1));
10403 case BIND_EXPR:
10404 return tree_expr_nonnegative_p (expr_last (TREE_OPERAND (t, 1)));
10405 case SAVE_EXPR:
10406 return tree_expr_nonnegative_p (TREE_OPERAND (t, 0));
10407 case NON_LVALUE_EXPR:
10408 return tree_expr_nonnegative_p (TREE_OPERAND (t, 0));
10409 case FLOAT_EXPR:
10410 return tree_expr_nonnegative_p (TREE_OPERAND (t, 0));
10411
10412 case TARGET_EXPR:
10413 {
10414 tree temp = TARGET_EXPR_SLOT (t);
10415 t = TARGET_EXPR_INITIAL (t);
10416
10417
10418
10419 if (!VOID_TYPE_P (t))
10420 return tree_expr_nonnegative_p (t);
10421
10422
10423
10424 while (1)
10425 {
10426 if (TREE_CODE (t) == BIND_EXPR)
10427 t = expr_last (BIND_EXPR_BODY (t));
10428 else if (TREE_CODE (t) == TRY_FINALLY_EXPR
10429 || TREE_CODE (t) == TRY_CATCH_EXPR)
10430 t = expr_last (TREE_OPERAND (t, 0));
10431 else if (TREE_CODE (t) == STATEMENT_LIST)
10432 t = expr_last (t);
10433 else
10434 break;
10435 }
10436 if (TREE_CODE (t) == MODIFY_EXPR
10437 && TREE_OPERAND (t, 0) == temp)
10438 return tree_expr_nonnegative_p (TREE_OPERAND (t, 1));
10439
10440 return 0;
10441 }
10442
10443 case CALL_EXPR:
10444 {
10445 tree fndecl = get_callee_fndecl (t);
10446 tree arglist = TREE_OPERAND (t, 1);
10447 if (fndecl && DECL_BUILT_IN_CLASS (fndecl) == BUILT_IN_NORMAL)
10448 switch (DECL_FUNCTION_CODE (fndecl))
10449 {
10450 #define CASE_BUILTIN_F(BUILT_IN_FN) \
10451 case BUILT_IN_FN: case BUILT_IN_FN##F: case BUILT_IN_FN##L:
10452 #define CASE_BUILTIN_I(BUILT_IN_FN) \
10453 case BUILT_IN_FN: case BUILT_IN_FN##L: case BUILT_IN_FN##LL:
10454
10455 CASE_BUILTIN_F (BUILT_IN_ACOS)
10456 CASE_BUILTIN_F (BUILT_IN_ACOSH)
10457 CASE_BUILTIN_F (BUILT_IN_CABS)
10458 CASE_BUILTIN_F (BUILT_IN_COSH)
10459 CASE_BUILTIN_F (BUILT_IN_ERFC)
10460 CASE_BUILTIN_F (BUILT_IN_EXP)
10461 CASE_BUILTIN_F (BUILT_IN_EXP10)
10462 CASE_BUILTIN_F (BUILT_IN_EXP2)
10463 CASE_BUILTIN_F (BUILT_IN_FABS)
10464 CASE_BUILTIN_F (BUILT_IN_FDIM)
10465 CASE_BUILTIN_F (BUILT_IN_HYPOT)
10466 CASE_BUILTIN_F (BUILT_IN_POW10)
10467 CASE_BUILTIN_I (BUILT_IN_FFS)
10468 CASE_BUILTIN_I (BUILT_IN_PARITY)
10469 CASE_BUILTIN_I (BUILT_IN_POPCOUNT)
10470
10471 return 1;
10472
10473 CASE_BUILTIN_F (BUILT_IN_SQRT)
10474
10475 if (!HONOR_SIGNED_ZEROS (TYPE_MODE (TREE_TYPE (t))))
10476 return 1;
10477 return tree_expr_nonnegative_p (TREE_VALUE (arglist));
10478
10479 CASE_BUILTIN_F (BUILT_IN_ASINH)
10480 CASE_BUILTIN_F (BUILT_IN_ATAN)
10481 CASE_BUILTIN_F (BUILT_IN_ATANH)
10482 CASE_BUILTIN_F (BUILT_IN_CBRT)
10483 CASE_BUILTIN_F (BUILT_IN_CEIL)
10484 CASE_BUILTIN_F (BUILT_IN_ERF)
10485 CASE_BUILTIN_F (BUILT_IN_EXPM1)
10486 CASE_BUILTIN_F (BUILT_IN_FLOOR)
10487 CASE_BUILTIN_F (BUILT_IN_FMOD)
10488 CASE_BUILTIN_F (BUILT_IN_FREXP)
10489 CASE_BUILTIN_F (BUILT_IN_LDEXP)
10490 CASE_BUILTIN_F (BUILT_IN_LLRINT)
10491 CASE_BUILTIN_F (BUILT_IN_LLROUND)
10492 CASE_BUILTIN_F (BUILT_IN_LRINT)
10493 CASE_BUILTIN_F (BUILT_IN_LROUND)
10494 CASE_BUILTIN_F (BUILT_IN_MODF)
10495 CASE_BUILTIN_F (BUILT_IN_NEARBYINT)
10496 CASE_BUILTIN_F (BUILT_IN_POW)
10497 CASE_BUILTIN_F (BUILT_IN_RINT)
10498 CASE_BUILTIN_F (BUILT_IN_ROUND)
10499 CASE_BUILTIN_F (BUILT_IN_SIGNBIT)
10500 CASE_BUILTIN_F (BUILT_IN_SINH)
10501 CASE_BUILTIN_F (BUILT_IN_TANH)
10502 CASE_BUILTIN_F (BUILT_IN_TRUNC)
10503
10504 return tree_expr_nonnegative_p (TREE_VALUE (arglist));
10505
10506 CASE_BUILTIN_F (BUILT_IN_FMAX)
10507
10508 return tree_expr_nonnegative_p (TREE_VALUE (arglist))
10509 || tree_expr_nonnegative_p (TREE_VALUE (TREE_CHAIN (arglist)));
10510
10511 CASE_BUILTIN_F (BUILT_IN_FMIN)
10512
10513 return tree_expr_nonnegative_p (TREE_VALUE (arglist))
10514 && tree_expr_nonnegative_p (TREE_VALUE (TREE_CHAIN (arglist)));
10515
10516 CASE_BUILTIN_F (BUILT_IN_COPYSIGN)
10517
10518 return tree_expr_nonnegative_p (TREE_VALUE (TREE_CHAIN (arglist)));
10519
10520 default:
10521 break;
10522 #undef CASE_BUILTIN_F
10523 #undef CASE_BUILTIN_I
10524 }
10525 }
10526
10527
10528
10529 default:
10530 if (truth_value_p (TREE_CODE (t)))
10531
10532 return 1;
10533 }
10534
10535
10536 return 0;
10537 }
10538
10539
10540
10541
10542
10543 static bool
10544 tree_expr_nonzero_p (tree t)
10545 {
10546 tree type = TREE_TYPE (t);
10547
10548
10549 if (!INTEGRAL_TYPE_P (type) && !POINTER_TYPE_P (type))
10550 return false;
10551
10552 switch (TREE_CODE (t))
10553 {
10554 case ABS_EXPR:
10555 if (!TYPE_UNSIGNED (type) && !flag_wrapv)
10556 return tree_expr_nonzero_p (TREE_OPERAND (t, 0));
10557
10558 case INTEGER_CST:
10559
10560
10561 return (TREE_INT_CST_LOW (t) != 0
10562 || TREE_INT_CST_HIGH (t) != 0);
10563
10564 case PLUS_EXPR:
10565 if (!TYPE_UNSIGNED (type) && !flag_wrapv)
10566 {
10567
10568
10569 if (!tree_expr_nonnegative_p (TREE_OPERAND (t, 0))
10570 || !tree_expr_nonnegative_p (TREE_OPERAND (t, 1)))
10571 return false;
10572
10573 return (tree_expr_nonzero_p (TREE_OPERAND (t, 0))
10574 || tree_expr_nonzero_p (TREE_OPERAND (t, 1)));
10575 }
10576 break;
10577
10578 case MULT_EXPR:
10579 if (!TYPE_UNSIGNED (type) && !flag_wrapv)
10580 {
10581 return (tree_expr_nonzero_p (TREE_OPERAND (t, 0))
10582 && tree_expr_nonzero_p (TREE_OPERAND (t, 1)));
10583 }
10584 break;
10585
10586 case NOP_EXPR:
10587 {
10588 tree inner_type = TREE_TYPE (TREE_OPERAND (t, 0));
10589 tree outer_type = TREE_TYPE (t);
10590
10591 return (TYPE_PRECISION (inner_type) >= TYPE_PRECISION (outer_type)
10592 && tree_expr_nonzero_p (TREE_OPERAND (t, 0)));
10593 }
10594 break;
10595
10596 case ADDR_EXPR:
10597 {
10598 tree base = get_base_address (TREE_OPERAND (t, 0));
10599
10600 if (!base)
10601 return false;
10602
10603
10604 if (DECL_P (base))
10605 return !DECL_WEAK (base);
10606
10607
10608 if (CONSTANT_CLASS_P (base))
10609 return true;
10610
10611 return false;
10612 }
10613
10614 case COND_EXPR:
10615 return (tree_expr_nonzero_p (TREE_OPERAND (t, 1))
10616 && tree_expr_nonzero_p (TREE_OPERAND (t, 2)));
10617
10618 case MIN_EXPR:
10619 return (tree_expr_nonzero_p (TREE_OPERAND (t, 0))
10620 && tree_expr_nonzero_p (TREE_OPERAND (t, 1)));
10621
10622 case MAX_EXPR:
10623 if (tree_expr_nonzero_p (TREE_OPERAND (t, 0)))
10624 {
10625
10626 if (tree_expr_nonzero_p (TREE_OPERAND (t, 1)))
10627 return true;
10628
10629
10630 return tree_expr_nonnegative_p (TREE_OPERAND (t, 0));
10631 }
10632
10633 else if (tree_expr_nonzero_p (TREE_OPERAND (t, 1))
10634 && tree_expr_nonnegative_p (TREE_OPERAND (t, 1)))
10635 return true;
10636 break;
10637
10638 case COMPOUND_EXPR:
10639 case MODIFY_EXPR:
10640 case BIND_EXPR:
10641 return tree_expr_nonzero_p (TREE_OPERAND (t, 1));
10642
10643 case SAVE_EXPR:
10644 case NON_LVALUE_EXPR:
10645 return tree_expr_nonzero_p (TREE_OPERAND (t, 0));
10646
10647 case BIT_IOR_EXPR:
10648 return tree_expr_nonzero_p (TREE_OPERAND (t, 1))
10649 || tree_expr_nonzero_p (TREE_OPERAND (t, 0));
10650
10651 default:
10652 break;
10653 }
10654 return false;
10655 }
10656
10657
10658
10659
10660
10661 static tree
10662 fold_relational_hi_lo (enum tree_code *code_p, const tree type, tree *op0_p,
10663 tree *op1_p)
10664 {
10665 tree op0 = *op0_p;
10666 tree op1 = *op1_p;
10667 enum tree_code code = *code_p;
10668 int width = GET_MODE_BITSIZE (TYPE_MODE (TREE_TYPE (op1)));
10669
10670 if (TREE_CODE (op1) == INTEGER_CST
10671 && ! TREE_CONSTANT_OVERFLOW (op1)
10672 && width <= HOST_BITS_PER_WIDE_INT
10673 && (INTEGRAL_TYPE_P (TREE_TYPE (op1))
10674 || POINTER_TYPE_P (TREE_TYPE (op1))))
10675 {
10676 unsigned HOST_WIDE_INT signed_max;
10677 unsigned HOST_WIDE_INT max, min;
10678
10679 signed_max = ((unsigned HOST_WIDE_INT) 1 << (width - 1)) - 1;
10680
10681 if (TYPE_UNSIGNED (TREE_TYPE (op1)))
10682 {
10683 max = ((unsigned HOST_WIDE_INT) 2 << (width - 1)) - 1;
10684 min = 0;
10685 }
10686 else
10687 {
10688 max = signed_max;
10689 min = ((unsigned HOST_WIDE_INT) -1 << (width - 1));
10690 }
10691
10692 if (TREE_INT_CST_HIGH (op1) == 0
10693 && TREE_INT_CST_LOW (op1) == max)
10694 switch (code)
10695 {
10696 case GT_EXPR:
10697 return omit_one_operand (type, integer_zero_node, op0);
10698
10699 case GE_EXPR:
10700 *code_p = EQ_EXPR;
10701 break;
10702 case LE_EXPR:
10703 return omit_one_operand (type, integer_one_node, op0);
10704
10705 case LT_EXPR:
10706 *code_p = NE_EXPR;
10707 break;
10708
10709
10710
10711
10712 default:
10713 break;
10714 }
10715 else if (TREE_INT_CST_HIGH (op1) == 0
10716 && TREE_INT_CST_LOW (op1) == max - 1)
10717 switch (code)
10718 {
10719 case GT_EXPR:
10720 *code_p = EQ_EXPR;
10721 *op1_p = const_binop (PLUS_EXPR, op1, integer_one_node, 0);
10722 break;
10723 case LE_EXPR:
10724 *code_p = NE_EXPR;
10725 *op1_p = const_binop (PLUS_EXPR, op1, integer_one_node, 0);
10726 break;
10727 default:
10728 break;
10729 }
10730 else if (TREE_INT_CST_HIGH (op1) == (min ? -1 : 0)
10731 && TREE_INT_CST_LOW (op1) == min)
10732 switch (code)
10733 {
10734 case LT_EXPR:
10735 return omit_one_operand (type, integer_zero_node, op0);
10736
10737 case LE_EXPR:
10738 *code_p = EQ_EXPR;
10739 break;
10740
10741 case GE_EXPR:
10742 return omit_one_operand (type, integer_one_node, op0);
10743
10744 case GT_EXPR:
10745 *code_p = NE_EXPR;
10746 break;
10747
10748 default:
10749 break;
10750 }
10751 else if (TREE_INT_CST_HIGH (op1) == (min ? -1 : 0)
10752 && TREE_INT_CST_LOW (op1) == min + 1)
10753 switch (code)
10754 {
10755 case GE_EXPR:
10756 *code_p = NE_EXPR;
10757 *op1_p = const_binop (MINUS_EXPR, op1, integer_one_node, 0);
10758 break;
10759 case LT_EXPR:
10760 *code_p = EQ_EXPR;
10761 *op1_p = const_binop (MINUS_EXPR, op1, integer_one_node, 0);
10762 break;
10763 default:
10764 break;
10765 }
10766
10767 else if (TREE_INT_CST_HIGH (op1) == 0
10768 && TREE_INT_CST_LOW (op1) == signed_max
10769 && TYPE_UNSIGNED (TREE_TYPE (op1))
10770
10771 && INTEGRAL_TYPE_P (TREE_TYPE (op1)))
10772 {
10773
10774
10775 if (code == LE_EXPR || code == GT_EXPR)
10776 {
10777 tree st0, st1, exp, retval;
10778 st0 = lang_hooks.types.signed_type (TREE_TYPE (op0));
10779 st1 = lang_hooks.types.signed_type (TREE_TYPE (op1));
10780
10781 exp = build2 (code == LE_EXPR ? GE_EXPR: LT_EXPR,
10782 type,
10783 fold_convert (st0, op0),
10784 fold_convert (st1, integer_zero_node));
10785
10786 retval = fold_binary_to_constant (TREE_CODE (exp),
10787 TREE_TYPE (exp),
10788 TREE_OPERAND (exp, 0),
10789 TREE_OPERAND (exp, 1));
10790
10791
10792
10793
10794 if (in_gimple_form)
10795 exp = NULL;
10796
10797 return (retval ? retval : exp);
10798 }
10799 }
10800 }
10801
10802 return NULL_TREE;
10803 }
10804
10805
10806
10807
10808
10809
10810
10811
10812
10813
10814
10815
10816
10817
10818
10819 tree
10820 fold_binary_to_constant (enum tree_code code, tree type, tree op0, tree op1)
10821 {
10822 int wins = 1;
10823 tree subop0;
10824 tree subop1;
10825 tree tem;
10826
10827
10828
10829 if (commutative_tree_code (code)
10830 && (TREE_CODE (op0) == INTEGER_CST || TREE_CODE (op0) == REAL_CST))
10831 {
10832 tem = op0;
10833 op0 = op1;
10834 op1 = tem;
10835 }
10836
10837
10838 if (TREE_CODE (op0) == COMPLEX_CST)
10839 subop0 = TREE_REALPART (op0);
10840 else
10841 subop0 = op0;
10842
10843 if (TREE_CODE (op1) == COMPLEX_CST)
10844 subop1 = TREE_REALPART (op1);
10845 else
10846 subop1 = op1;
10847
10848
10849
10850
10851 if ((TREE_CODE (subop0) != INTEGER_CST
10852 && TREE_CODE (subop0) != REAL_CST)
10853 || (TREE_CODE (subop1) != INTEGER_CST
10854 && TREE_CODE (subop1) != REAL_CST))
10855 wins = 0;
10856
10857 switch (code)
10858 {
10859 case PLUS_EXPR:
10860
10861 if (TREE_CODE (op0) == PLUS_EXPR
10862 && TREE_CODE (op1) == INTEGER_CST
10863 && (TREE_CODE (TREE_OPERAND (op0, 0)) == ADDR_EXPR
10864 || (TREE_CODE (TREE_OPERAND (op0, 0)) == NOP_EXPR
10865 && (TREE_CODE (TREE_OPERAND (TREE_OPERAND (op0, 0), 0))
10866 == ADDR_EXPR)))
10867 && TREE_CODE (TREE_OPERAND (op0, 1)) == INTEGER_CST)
10868 {
10869 return build2 (PLUS_EXPR, type, TREE_OPERAND (op0, 0),
10870 const_binop (PLUS_EXPR, op1,
10871 TREE_OPERAND (op0, 1), 0));
10872 }
10873 case BIT_XOR_EXPR:
10874
10875 binary:
10876 if (!wins)
10877 return NULL_TREE;
10878
10879
10880 tem = const_binop (code, op0, op1, 0);
10881 if (tem != NULL_TREE)
10882 {
10883
10884
10885 if (TREE_TYPE (tem) != type)
10886 tem = fold_convert (type, tem);
10887
10888 return tem;
10889 }
10890 return NULL_TREE;
10891
10892 case MINUS_EXPR:
10893
10894
10895
10896
10897
10898 if (! FLOAT_TYPE_P (type) && operand_equal_p (op0, op1, 0))
10899 return fold_convert (type, integer_zero_node);
10900
10901 goto binary;
10902
10903 case MULT_EXPR:
10904 case BIT_AND_EXPR:
10905
10906
10907 if (! FLOAT_TYPE_P (type) && integer_zerop (op1))
10908 return omit_one_operand (type, op1, op0);
10909 else
10910 if (!HONOR_NANS (TYPE_MODE (TREE_TYPE (op0)))
10911 && !HONOR_SIGNED_ZEROS (TYPE_MODE (TREE_TYPE (op0)))
10912 && real_zerop (op1))
10913 return omit_one_operand (type, op1, op0);
10914
10915 goto binary;
10916
10917 case BIT_IOR_EXPR:
10918
10919 if (integer_all_onesp (op1))
10920 return omit_one_operand (type, op1, op0);
10921
10922 goto binary;
10923
10924 case TRUNC_DIV_EXPR:
10925 case ROUND_DIV_EXPR:
10926 case FLOOR_DIV_EXPR:
10927 case CEIL_DIV_EXPR:
10928 case EXACT_DIV_EXPR:
10929 case TRUNC_MOD_EXPR:
10930 case ROUND_MOD_EXPR:
10931 case FLOOR_MOD_EXPR:
10932 case CEIL_MOD_EXPR:
10933 case RDIV_EXPR:
10934
10935 if (integer_zerop (op1))
10936 return NULL_TREE;
10937
10938 if (TREE_CODE (op1) == REAL_CST
10939 && !MODE_HAS_INFINITIES (TYPE_MODE (TREE_TYPE (op1)))
10940 && real_zerop (op1))
10941 return NULL_TREE;
10942
10943 goto binary;
10944
10945 case MIN_EXPR:
10946 if (INTEGRAL_TYPE_P (type)
10947 && operand_equal_p (op1, TYPE_MIN_VALUE (type), OEP_ONLY_CONST))
10948 return omit_one_operand (type, op1, op0);
10949
10950 goto binary;
10951
10952 case MAX_EXPR:
10953 if (INTEGRAL_TYPE_P (type)
10954 && TYPE_MAX_VALUE (type)
10955 && operand_equal_p (op1, TYPE_MAX_VALUE (type), OEP_ONLY_CONST))
10956 return omit_one_operand (type, op1, op0);
10957
10958 goto binary;
10959
10960 case RSHIFT_EXPR:
10961
10962 if (integer_all_onesp (op0) && ! TYPE_UNSIGNED (type))
10963 return omit_one_operand (type, op0, op1);
10964
10965
10966 case LSHIFT_EXPR:
10967 if (integer_zerop (op0))
10968 return omit_one_operand (type, op0, op1);
10969
10970
10971
10972 if (TREE_CODE (op1) == INTEGER_CST && tree_int_cst_sgn (op1) < 0)
10973 return NULL_TREE;
10974
10975 goto binary;
10976
10977 case LROTATE_EXPR:
10978 case RROTATE_EXPR:
10979
10980 if (integer_all_onesp (op0))
10981 return omit_one_operand (type, op0, op1);
10982
10983
10984 if (integer_zerop (op0))
10985 return omit_one_operand (type, op0, op1);
10986
10987 goto binary;
10988
10989 case COMPLEX_EXPR:
10990 if (wins)
10991 return build_complex (type, op0, op1);
10992 return NULL_TREE;
10993
10994 case LT_EXPR:
10995 case LE_EXPR:
10996 case GT_EXPR:
10997 case GE_EXPR:
10998 case EQ_EXPR:
10999 case NE_EXPR:
11000
11001 if ((TREE_CODE (op0) == INTEGER_CST
11002 && TREE_CODE (op1) != INTEGER_CST)
11003 || (TREE_CODE (op0) == REAL_CST
11004 && TREE_CODE (op0) != REAL_CST))
11005 {
11006 tree temp;
11007
11008 temp = op0;
11009 op0 = op1;
11010 op1 = temp;
11011 code = swap_tree_comparison (code);
11012 }
11013
11014
11015
11016
11017 if (TREE_CODE (op1) == INTEGER_CST
11018 && TREE_CODE (op0) != INTEGER_CST
11019 && tree_int_cst_sgn (op1) > 0)
11020 {
11021 switch (code)
11022 {
11023 case GE_EXPR:
11024 code = GT_EXPR;
11025 op1 = const_binop (MINUS_EXPR, op1, integer_one_node, 0);
11026 break;
11027
11028 case LT_EXPR:
11029 code = LE_EXPR;
11030 op1 = const_binop (MINUS_EXPR, op1, integer_one_node, 0);
11031 break;
11032
11033 default:
11034 break;
11035 }
11036 }
11037
11038 tem = fold_relational_hi_lo (&code, type, &op0, &op1);
11039 if (tem)
11040 return tem;
11041
11042
11043
11044 case ORDERED_EXPR:
11045 case UNORDERED_EXPR:
11046 case UNLT_EXPR:
11047 case UNLE_EXPR:
11048 case UNGT_EXPR:
11049 case UNGE_EXPR:
11050 case UNEQ_EXPR:
11051 case LTGT_EXPR:
11052 if (!wins)
11053 return NULL_TREE;
11054
11055 return fold_relational_const (code, type, op0, op1);
11056
11057 case RANGE_EXPR:
11058
11059 return NULL_TREE;
11060
11061 case TRUTH_AND_EXPR:
11062
11063
11064 if (integer_zerop (op1))
11065 return omit_one_operand (type, op1, op0);
11066
11067
11068 if (integer_zerop (op0))
11069 return omit_one_operand (type, op0, op1);
11070 if (TREE_CODE (op0) == INTEGER_CST && TREE_CODE (op1) == INTEGER_CST)
11071 return constant_boolean_node (true, type);
11072 return NULL_TREE;
11073
11074 case TRUTH_OR_EXPR:
11075
11076
11077 if (TREE_CODE (op1) == INTEGER_CST && ! integer_zerop (op1))
11078 return omit_one_operand (type, op1, op0);
11079
11080
11081 if (TREE_CODE (op0) == INTEGER_CST && ! integer_zerop (op0))
11082 return omit_one_operand (type, op0, op1);
11083 if (TREE_CODE (op0) == INTEGER_CST && TREE_CODE (op1) == INTEGER_CST)
11084 return constant_boolean_node (false, type);
11085 return NULL_TREE;
11086
11087 case TRUTH_XOR_EXPR:
11088 if (TREE_CODE (op0) == INTEGER_CST && TREE_CODE (op1) == INTEGER_CST)
11089 {
11090 int x = ! integer_zerop (op0) ^ ! integer_zerop (op1);
11091 return constant_boolean_node (x, type);
11092 }
11093 return NULL_TREE;
11094
11095 default:
11096 return NULL_TREE;
11097 }
11098 }
11099
11100
11101
11102
11103
11104
11105
11106
11107
11108
11109
11110
11111
11112
11113 tree
11114 fold_unary_to_constant (enum tree_code code, tree type, tree op0)
11115 {
11116
11117 if (code == NOP_EXPR || code == FLOAT_EXPR || code == CONVERT_EXPR)
11118 {
11119 tree subop;
11120
11121 if (TREE_CODE (op0) == COMPLEX_CST)
11122 subop = TREE_REALPART (op0);
11123 else
11124 subop = op0;
11125
11126 if (TREE_CODE (subop) != INTEGER_CST && TREE_CODE (subop) != REAL_CST)
11127 return NULL_TREE;
11128 }
11129
11130 switch (code)
11131 {
11132 case NOP_EXPR:
11133 case FLOAT_EXPR:
11134 case CONVERT_EXPR:
11135 case FIX_TRUNC_EXPR:
11136 case FIX_FLOOR_EXPR:
11137 case FIX_CEIL_EXPR:
11138 return fold_convert_const (code, type, op0);
11139
11140 case NEGATE_EXPR:
11141 if (TREE_CODE (op0) == INTEGER_CST || TREE_CODE (op0) == REAL_CST)
11142 return fold_negate_const (op0, type);
11143 else
11144 return NULL_TREE;
11145
11146 case ABS_EXPR:
11147 if (TREE_CODE (op0) == INTEGER_CST || TREE_CODE (op0) == REAL_CST)
11148 return fold_abs_const (op0, type);
11149 else
11150 return NULL_TREE;
11151
11152 case BIT_NOT_EXPR:
11153 if (TREE_CODE (op0) == INTEGER_CST)
11154 return fold_not_const (op0, type);
11155 else
11156 return NULL_TREE;
11157
11158 case REALPART_EXPR:
11159 if (TREE_CODE (op0) == COMPLEX_CST)
11160 return TREE_REALPART (op0);
11161 else
11162 return NULL_TREE;
11163
11164 case IMAGPART_EXPR:
11165 if (TREE_CODE (op0) == COMPLEX_CST)
11166 return TREE_IMAGPART (op0);
11167 else
11168 return NULL_TREE;
11169
11170 case CONJ_EXPR:
11171 if (TREE_CODE (op0) == COMPLEX_CST
11172 && TREE_CODE (TREE_TYPE (op0)) == COMPLEX_TYPE)
11173 return build_complex (type, TREE_REALPART (op0),
11174 negate_expr (TREE_IMAGPART (op0)));
11175 return NULL_TREE;
11176
11177 default:
11178 return NULL_TREE;
11179 }
11180 }
11181
11182
11183
11184
11185
11186 tree
11187 fold_read_from_constant_string (tree exp)
11188 {
11189 if (TREE_CODE (exp) == INDIRECT_REF || TREE_CODE (exp) == ARRAY_REF)
11190 {
11191 tree exp1 = TREE_OPERAND (exp, 0);
11192 tree index;
11193 tree string;
11194
11195 if (TREE_CODE (exp) == INDIRECT_REF)
11196 string = string_constant (exp1, &index);
11197 else
11198 {
11199 tree low_bound = array_ref_low_bound (exp);
11200 index = fold_convert (sizetype, TREE_OPERAND (exp, 1));
11201
11202
11203
11204
11205
11206
11207
11208
11209 if (! integer_zerop (low_bound))
11210 index = size_diffop (index, fold_convert (sizetype, low_bound));
11211
11212 string = exp1;
11213 }
11214
11215 if (string
11216 && TREE_TYPE (exp) == TREE_TYPE (TREE_TYPE (string))
11217 && TREE_CODE (string) == STRING_CST
11218 && TREE_CODE (index) == INTEGER_CST
11219 && compare_tree_int (index, TREE_STRING_LENGTH (string)) < 0
11220 && (GET_MODE_CLASS (TYPE_MODE (TREE_TYPE (TREE_TYPE (string))))
11221 == MODE_INT)
11222 && (GET_MODE_SIZE (TYPE_MODE (TREE_TYPE (TREE_TYPE (string)))) == 1))
11223 return fold_convert (TREE_TYPE (exp),
11224 build_int_cst (NULL_TREE,
11225 (TREE_STRING_POINTER (string)
11226 [TREE_INT_CST_LOW (index)])));
11227 }
11228 return NULL;
11229 }
11230
11231
11232
11233
11234
11235
11236 static tree
11237 fold_negate_const (tree arg0, tree type)
11238 {
11239 tree t = NULL_TREE;
11240
11241 switch (TREE_CODE (arg0))
11242 {
11243 case INTEGER_CST:
11244 {
11245 unsigned HOST_WIDE_INT low;
11246 HOST_WIDE_INT high;
11247 int overflow = neg_double (TREE_INT_CST_LOW (arg0),
11248 TREE_INT_CST_HIGH (arg0),
11249 &low, &high);
11250 t = build_int_cst_wide (type, low, high);
11251 t = force_fit_type (t, 1,
11252 (overflow | TREE_OVERFLOW (arg0))
11253 && !TYPE_UNSIGNED (type),
11254 TREE_CONSTANT_OVERFLOW (arg0));
11255 break;
11256 }
11257
11258 case REAL_CST:
11259 t = build_real (type, REAL_VALUE_NEGATE (TREE_REAL_CST (arg0)));
11260 break;
11261
11262 default:
11263 gcc_unreachable ();
11264 }
11265
11266 return t;
11267 }
11268
11269
11270
11271
11272
11273
11274 tree
11275 fold_abs_const (tree arg0, tree type)
11276 {
11277 tree t = NULL_TREE;
11278
11279 switch (TREE_CODE (arg0))
11280 {
11281 case INTEGER_CST:
11282
11283
11284 if (TYPE_UNSIGNED (type))
11285 t = arg0;
11286
11287 else if (INT_CST_LT (integer_minus_one_node, arg0))
11288 t = arg0;
11289
11290
11291 else
11292 {
11293 unsigned HOST_WIDE_INT low;
11294 HOST_WIDE_INT high;
11295 int overflow = neg_double (TREE_INT_CST_LOW (arg0),
11296 TREE_INT_CST_HIGH (arg0),
11297 &low, &high);
11298 t = build_int_cst_wide (type, low, high);
11299 t = force_fit_type (t, -1, overflow | TREE_OVERFLOW (arg0),
11300 TREE_CONSTANT_OVERFLOW (arg0));
11301 }
11302 break;
11303
11304 case REAL_CST:
11305 if (REAL_VALUE_NEGATIVE (TREE_REAL_CST (arg0)))
11306 t = build_real (type, REAL_VALUE_NEGATE (TREE_REAL_CST (arg0)));
11307 else
11308 t = arg0;
11309 break;
11310
11311 default:
11312 gcc_unreachable ();
11313 }
11314
11315 return t;
11316 }
11317
11318
11319
11320
11321 static tree
11322 fold_not_const (tree arg0, tree type)
11323 {
11324 tree t = NULL_TREE;
11325
11326 gcc_assert (TREE_CODE (arg0) == INTEGER_CST);
11327
11328 t = build_int_cst_wide (type,
11329 ~ TREE_INT_CST_LOW (arg0),
11330 ~ TREE_INT_CST_HIGH (arg0));
11331 t = force_fit_type (t, 0, TREE_OVERFLOW (arg0),
11332 TREE_CONSTANT_OVERFLOW (arg0));
11333
11334 return t;
11335 }
11336
11337
11338
11339
11340
11341
11342 static tree
11343 fold_relational_const (enum tree_code code, tree type, tree op0, tree op1)
11344 {
11345 int result, invert;
11346
11347
11348
11349
11350 if (TREE_CODE (op0) == REAL_CST && TREE_CODE (op1) == REAL_CST)
11351 {
11352 const REAL_VALUE_TYPE *c0 = TREE_REAL_CST_PTR (op0);
11353 const REAL_VALUE_TYPE *c1 = TREE_REAL_CST_PTR (op1);
11354
11355
11356 if (real_isnan (c0) || real_isnan (c1))
11357 {
11358 switch (code)
11359 {
11360 case EQ_EXPR:
11361 case ORDERED_EXPR:
11362 result = 0;
11363 break;
11364
11365 case NE_EXPR:
11366 case UNORDERED_EXPR:
11367 case UNLT_EXPR:
11368 case UNLE_EXPR:
11369 case UNGT_EXPR:
11370 case UNGE_EXPR:
11371 case UNEQ_EXPR:
11372 result = 1;
11373 break;
11374
11375 case LT_EXPR:
11376 case LE_EXPR:
11377 case GT_EXPR:
11378 case GE_EXPR:
11379 case LTGT_EXPR:
11380 if (flag_trapping_math)
11381 return NULL_TREE;
11382 result = 0;
11383 break;
11384
11385 default:
11386 gcc_unreachable ();
11387 }
11388
11389 return constant_boolean_node (result, type);
11390 }
11391
11392 return constant_boolean_node (real_compare (code, c0, c1), type);
11393 }
11394
11395
11396
11397
11398
11399
11400
11401
11402
11403
11404 if (code == LE_EXPR || code == GT_EXPR)
11405 {
11406 tree tem = op0;
11407 op0 = op1;
11408 op1 = tem;
11409 code = swap_tree_comparison (code);
11410 }
11411
11412
11413
11414
11415 invert = 0;
11416 if (code == NE_EXPR || code == GE_EXPR)
11417 {
11418 invert = 1;
11419 code = invert_tree_comparison (code, false);
11420 }
11421
11422
11423
11424 if (TREE_CODE (op0) == INTEGER_CST && TREE_CODE (op1) == INTEGER_CST)
11425 {
11426 if (code == EQ_EXPR)
11427 result = tree_int_cst_equal (op0, op1);
11428 else if (TYPE_UNSIGNED (TREE_TYPE (op0)))
11429 result = INT_CST_LT_UNSIGNED (op0, op1);
11430 else
11431 result = INT_CST_LT (op0, op1);
11432 }
11433 else
11434 return NULL_TREE;
11435
11436 if (invert)
11437 result ^= 1;
11438 return constant_boolean_node (result, type);
11439 }
11440
11441
11442
11443
11444
11445 tree
11446 fold_build_cleanup_point_expr (tree type, tree expr)
11447 {
11448
11449
11450 if (!TREE_SIDE_EFFECTS (expr))
11451 return expr;
11452
11453
11454
11455
11456
11457
11458 if (TREE_CODE (expr) == RETURN_EXPR)
11459 {
11460 tree op = TREE_OPERAND (expr, 0);
11461 if (!op || !TREE_SIDE_EFFECTS (op))
11462 return expr;
11463 op = TREE_OPERAND (op, 1);
11464 if (!TREE_SIDE_EFFECTS (op))
11465 return expr;
11466 }
11467
11468 return build1 (CLEANUP_POINT_EXPR, type, expr);
11469 }
11470
11471
11472
11473
11474 tree
11475 build_fold_addr_expr_with_type (tree t, tree ptrtype)
11476 {
11477
11478 if (TREE_CODE (t) == WITH_SIZE_EXPR)
11479 t = TREE_OPERAND (t, 0);
11480
11481
11482 if (TREE_CODE (t) == INDIRECT_REF
11483 || TREE_CODE (t) == MISALIGNED_INDIRECT_REF)
11484 {
11485 t = TREE_OPERAND (t, 0);
11486 if (TREE_TYPE (t) != ptrtype)
11487 t = build1 (NOP_EXPR, ptrtype, t);
11488 }
11489 else
11490 {
11491 tree base = t;
11492
11493 while (handled_component_p (base))
11494 base = TREE_OPERAND (base, 0);
11495 if (DECL_P (base))
11496 TREE_ADDRESSABLE (base) = 1;
11497
11498 t = build1 (ADDR_EXPR, ptrtype, t);
11499 }
11500
11501 return t;
11502 }
11503
11504 tree
11505 build_fold_addr_expr (tree t)
11506 {
11507 return build_fold_addr_expr_with_type (t, build_pointer_type (TREE_TYPE (t)));
11508 }
11509
11510
11511
11512
11513 static tree
11514 fold_indirect_ref_1 (tree t)
11515 {
11516 tree type = TREE_TYPE (TREE_TYPE (t));
11517 tree sub = t;
11518 tree subtype;
11519
11520 STRIP_NOPS (sub);
11521 subtype = TREE_TYPE (sub);
11522 if (!POINTER_TYPE_P (subtype))
11523 return NULL_TREE;
11524
11525 if (TREE_CODE (sub) == ADDR_EXPR)
11526 {
11527 tree op = TREE_OPERAND (sub, 0);
11528 tree optype = TREE_TYPE (op);
11529
11530 if (lang_hooks.types_compatible_p (type, optype))
11531 return op;
11532
11533 else if (TREE_CODE (optype) == ARRAY_TYPE
11534 && lang_hooks.types_compatible_p (type, TREE_TYPE (optype)))
11535 {
11536 tree type_domain = TYPE_DOMAIN (optype);
11537 tree min_val = size_zero_node;
11538 if (type_domain && TYPE_MIN_VALUE (type_domain))
11539 min_val = TYPE_MIN_VALUE (type_domain);
11540 return build4 (ARRAY_REF, type, op, min_val, NULL_TREE, NULL_TREE);
11541 }
11542 }
11543
11544
11545 if (TREE_CODE (TREE_TYPE (subtype)) == ARRAY_TYPE
11546 && lang_hooks.types_compatible_p (type, TREE_TYPE (TREE_TYPE (subtype))))
11547 {
11548 tree type_domain;
11549 tree min_val = size_zero_node;
11550 sub = build_fold_indirect_ref (sub);
11551 type_domain = TYPE_DOMAIN (TREE_TYPE (sub));
11552 if (type_domain && TYPE_MIN_VALUE (type_domain))
11553 min_val = TYPE_MIN_VALUE (type_domain);
11554 return build4 (ARRAY_REF, type, sub, min_val, NULL_TREE, NULL_TREE);
11555 }
11556
11557 return NULL_TREE;
11558 }
11559
11560
11561
11562
11563 tree
11564 build_fold_indirect_ref (tree t)
11565 {
11566 tree sub = fold_indirect_ref_1 (t);
11567
11568 if (sub)
11569 return sub;
11570 else
11571 return build1 (INDIRECT_REF, TREE_TYPE (TREE_TYPE (t)), t);
11572 }
11573
11574
11575
11576 tree
11577 fold_indirect_ref (tree t)
11578 {
11579 tree sub = fold_indirect_ref_1 (TREE_OPERAND (t, 0));
11580
11581 if (sub)
11582 return sub;
11583 else
11584 return t;
11585 }
11586
11587
11588
11589
11590
11591 tree
11592 fold_ignored_result (tree t)
11593 {
11594 if (!TREE_SIDE_EFFECTS (t))
11595 return integer_zero_node;
11596
11597 for (;;)
11598 switch (TREE_CODE_CLASS (TREE_CODE (t)))
11599 {
11600 case tcc_unary:
11601 t = TREE_OPERAND (t, 0);
11602 break;
11603
11604 case tcc_binary:
11605 case tcc_comparison:
11606 if (!TREE_SIDE_EFFECTS (TREE_OPERAND (t, 1)))
11607 t = TREE_OPERAND (t, 0);
11608 else if (!TREE_SIDE_EFFECTS (TREE_OPERAND (t, 0)))
11609 t = TREE_OPERAND (t, 1);
11610 else
11611 return t;
11612 break;
11613
11614 case tcc_expression:
11615 switch (TREE_CODE (t))
11616 {
11617 case COMPOUND_EXPR:
11618 if (TREE_SIDE_EFFECTS (TREE_OPERAND (t, 1)))
11619 return t;
11620 t = TREE_OPERAND (t, 0);
11621 break;
11622
11623 case COND_EXPR:
11624 if (TREE_SIDE_EFFECTS (TREE_OPERAND (t, 1))
11625 || TREE_SIDE_EFFECTS (TREE_OPERAND (t, 2)))
11626 return t;
11627 t = TREE_OPERAND (t, 0);
11628 break;
11629
11630 default:
11631 return t;
11632 }
11633 break;
11634
11635 default:
11636 return t;
11637 }
11638 }
11639
11640
11641
11642
11643 tree
11644 round_up (tree value, int divisor)
11645 {
11646 tree div = NULL_TREE;
11647
11648 gcc_assert (divisor > 0);
11649 if (divisor == 1)
11650 return value;
11651
11652
11653
11654
11655
11656 if (TREE_CODE (value) != INTEGER_CST)
11657 {
11658 div = build_int_cst (TREE_TYPE (value), divisor);
11659
11660 if (multiple_of_p (TREE_TYPE (value), value, div))
11661 return value;
11662 }
11663
11664
11665 if (divisor == (divisor & -divisor))
11666 {
11667 tree t;
11668
11669 t = build_int_cst (TREE_TYPE (value), divisor - 1);
11670 value = size_binop (PLUS_EXPR, value, t);
11671 t = build_int_cst (TREE_TYPE (value), -divisor);
11672 value = size_binop (BIT_AND_EXPR, value, t);
11673 }
11674 else
11675 {
11676 if (!div)
11677 div = build_int_cst (TREE_TYPE (value), divisor);
11678 value = size_binop (CEIL_DIV_EXPR, value, div);
11679 value = size_binop (MULT_EXPR, value, div);
11680 }
11681
11682 return value;
11683 }
11684
11685
11686
11687 tree
11688 round_down (tree value, int divisor)
11689 {
11690 tree div = NULL_TREE;
11691
11692 gcc_assert (divisor > 0);
11693 if (divisor == 1)
11694 return value;
11695
11696
11697
11698
11699
11700 if (TREE_CODE (value) != INTEGER_CST)
11701 {
11702 div = build_int_cst (TREE_TYPE (value), divisor);
11703
11704 if (multiple_of_p (TREE_TYPE (value), value, div))
11705 return value;
11706 }
11707
11708
11709 if (divisor == (divisor & -divisor))
11710 {
11711 tree t;
11712
11713 t = build_int_cst (TREE_TYPE (value), -divisor);
11714 value = size_binop (BIT_AND_EXPR, value, t);
11715 }
11716 else
11717 {
11718 if (!div)
11719 div = build_int_cst (TREE_TYPE (value), divisor);
11720 value = size_binop (FLOOR_DIV_EXPR, value, div);
11721 value = size_binop (MULT_EXPR, value, div);
11722 }
11723
11724 return value;
11725 }
11726
11727
11728
11729
11730
11731 static tree
11732 split_address_to_core_and_offset (tree exp,
11733 HOST_WIDE_INT *pbitpos, tree *poffset)
11734 {
11735 tree core;
11736 enum machine_mode mode;
11737 int unsignedp, volatilep;
11738 HOST_WIDE_INT bitsize;
11739
11740 if (TREE_CODE (exp) == ADDR_EXPR)
11741 {
11742 core = get_inner_reference (TREE_OPERAND (exp, 0), &bitsize, pbitpos,
11743 poffset, &mode, &unsignedp, &volatilep,
11744 false);
11745 core = build_fold_addr_expr (core);
11746 }
11747 else
11748 {
11749 core = exp;
11750 *pbitpos = 0;
11751 *poffset = NULL_TREE;
11752 }
11753
11754 return core;
11755 }
11756
11757
11758
11759
11760 bool
11761 ptr_difference_const (tree e1, tree e2, HOST_WIDE_INT *diff)
11762 {
11763 tree core1, core2;
11764 HOST_WIDE_INT bitpos1, bitpos2;
11765 tree toffset1, toffset2, tdiff, type;
11766
11767 core1 = split_address_to_core_and_offset (e1, &bitpos1, &toffset1);
11768 core2 = split_address_to_core_and_offset (e2, &bitpos2, &toffset2);
11769
11770 if (bitpos1 % BITS_PER_UNIT != 0
11771 || bitpos2 % BITS_PER_UNIT != 0
11772 || !operand_equal_p (core1, core2, 0))
11773 return false;
11774
11775 if (toffset1 && toffset2)
11776 {
11777 type = TREE_TYPE (toffset1);
11778 if (type != TREE_TYPE (toffset2))
11779 toffset2 = fold_convert (type, toffset2);
11780
11781 tdiff = fold (build2 (MINUS_EXPR, type, toffset1, toffset2));
11782 if (!host_integerp (tdiff, 0))
11783 return false;
11784
11785 *diff = tree_low_cst (tdiff, 0);
11786 }
11787 else if (toffset1 || toffset2)
11788 {
11789
11790
11791 return false;
11792 }
11793 else
11794 *diff = 0;
11795
11796 *diff += (bitpos1 - bitpos2) / BITS_PER_UNIT;
11797 return true;
11798 }
11799
11800
11801
11802
11803
11804 tree
11805 fold_strip_sign_ops (tree exp)
11806 {
11807 tree arg0, arg1;
11808
11809 switch (TREE_CODE (exp))
11810 {
11811 case ABS_EXPR:
11812 case NEGATE_EXPR:
11813 arg0 = fold_strip_sign_ops (TREE_OPERAND (exp, 0));
11814 return arg0 ? arg0 : TREE_OPERAND (exp, 0);
11815
11816 case MULT_EXPR:
11817 case RDIV_EXPR:
11818 if (HONOR_SIGN_DEPENDENT_ROUNDING (TYPE_MODE (TREE_TYPE (exp))))
11819 return NULL_TREE;
11820 arg0 = fold_strip_sign_ops (TREE_OPERAND (exp, 0));
11821 arg1 = fold_strip_sign_ops (TREE_OPERAND (exp, 1));
11822 if (arg0 != NULL_TREE || arg1 != NULL_TREE)
11823 return fold (build2 (TREE_CODE (exp), TREE_TYPE (exp),
11824 arg0 ? arg0 : TREE_OPERAND (exp, 0),
11825 arg1 ? arg1 : TREE_OPERAND (exp, 1)));
11826 break;
11827
11828 default:
11829 break;
11830 }
11831 return NULL_TREE;
11832 }
11833