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 "intl.h"
00062 #include "ggc.h"
00063 #include "hashtab.h"
00064 #include "langhooks.h"
00065 #include "md5.h"
00066
00067
00068
00069 int folding_initializer = 0;
00070
00071
00072
00073
00074 enum comparison_code {
00075 COMPCODE_FALSE = 0,
00076 COMPCODE_LT = 1,
00077 COMPCODE_EQ = 2,
00078 COMPCODE_LE = 3,
00079 COMPCODE_GT = 4,
00080 COMPCODE_LTGT = 5,
00081 COMPCODE_GE = 6,
00082 COMPCODE_ORD = 7,
00083 COMPCODE_UNORD = 8,
00084 COMPCODE_UNLT = 9,
00085 COMPCODE_UNEQ = 10,
00086 COMPCODE_UNLE = 11,
00087 COMPCODE_UNGT = 12,
00088 COMPCODE_NE = 13,
00089 COMPCODE_UNGE = 14,
00090 COMPCODE_TRUE = 15
00091 };
00092
00093 static void encode (HOST_WIDE_INT *, unsigned HOST_WIDE_INT, HOST_WIDE_INT);
00094 static void decode (HOST_WIDE_INT *, unsigned HOST_WIDE_INT *, HOST_WIDE_INT *);
00095 static bool negate_mathfn_p (enum built_in_function);
00096 static bool negate_expr_p (tree);
00097 static tree negate_expr (tree);
00098 static tree split_tree (tree, enum tree_code, tree *, tree *, tree *, int);
00099 static tree associate_trees (tree, tree, enum tree_code, tree);
00100 static tree const_binop (enum tree_code, tree, tree, int);
00101 static enum comparison_code comparison_to_compcode (enum tree_code);
00102 static enum tree_code compcode_to_comparison (enum comparison_code);
00103 static tree combine_comparisons (enum tree_code, enum tree_code,
00104 enum tree_code, tree, tree, tree);
00105 static int truth_value_p (enum tree_code);
00106 static int operand_equal_for_comparison_p (tree, tree, tree);
00107 static int twoval_comparison_p (tree, tree *, tree *, int *);
00108 static tree eval_subst (tree, tree, tree, tree, tree);
00109 static tree pedantic_omit_one_operand (tree, tree, tree);
00110 static tree distribute_bit_expr (enum tree_code, tree, tree, tree);
00111 static tree make_bit_field_ref (tree, tree, int, int, int);
00112 static tree optimize_bit_field_compare (enum tree_code, tree, tree, tree);
00113 static tree decode_field_reference (tree, HOST_WIDE_INT *, HOST_WIDE_INT *,
00114 enum machine_mode *, int *, int *,
00115 tree *, tree *);
00116 static int all_ones_mask_p (tree, int);
00117 static tree sign_bit_p (tree, tree);
00118 static int simple_operand_p (tree);
00119 static tree range_binop (enum tree_code, tree, tree, int, tree, int);
00120 static tree range_predecessor (tree);
00121 static tree range_successor (tree);
00122 static tree make_range (tree, int *, tree *, tree *, bool *);
00123 static tree build_range_check (tree, tree, int, tree, tree);
00124 static int merge_ranges (int *, tree *, tree *, int, tree, tree, int, tree,
00125 tree);
00126 static tree fold_range_test (enum tree_code, tree, tree, tree);
00127 static tree fold_cond_expr_with_comparison (tree, tree, tree, tree);
00128 static tree unextend (tree, int, int, tree);
00129 static tree fold_truthop (enum tree_code, tree, tree, tree);
00130 static tree optimize_minmax_comparison (enum tree_code, tree, tree, tree);
00131 static tree extract_muldiv (tree, tree, enum tree_code, tree, bool *);
00132 static tree extract_muldiv_1 (tree, tree, enum tree_code, tree, bool *);
00133 static int multiple_of_p (tree, tree, tree);
00134 static tree fold_binary_op_with_conditional_arg (enum tree_code, tree,
00135 tree, tree,
00136 tree, tree, int);
00137 static bool fold_real_zero_addition_p (tree, tree, int);
00138 static tree fold_mathfn_compare (enum built_in_function, enum tree_code,
00139 tree, tree, tree);
00140 static tree fold_inf_compare (enum tree_code, tree, tree, tree);
00141 static tree fold_div_compare (enum tree_code, tree, tree, tree);
00142 static bool reorder_operands_p (tree, tree);
00143 static tree fold_negate_const (tree, tree);
00144 static tree fold_not_const (tree, tree);
00145 static tree fold_relational_const (enum tree_code, tree, tree, tree);
00146 static int native_encode_expr (tree, unsigned char *, int);
00147 static tree native_interpret_expr (tree, unsigned char *, int);
00148
00149
00150
00151
00152
00153
00154
00155
00156
00157
00158 #define OVERFLOW_SUM_SIGN(a, b, sum) ((~((a) ^ (b)) & ((a) ^ (sum))) < 0)
00159
00160
00161
00162
00163
00164
00165 #define LOWPART(x) \
00166 ((x) & (((unsigned HOST_WIDE_INT) 1 << (HOST_BITS_PER_WIDE_INT / 2)) - 1))
00167 #define HIGHPART(x) \
00168 ((unsigned HOST_WIDE_INT) (x) >> HOST_BITS_PER_WIDE_INT / 2)
00169 #define BASE ((unsigned HOST_WIDE_INT) 1 << HOST_BITS_PER_WIDE_INT / 2)
00170
00171
00172
00173
00174
00175 static void
00176 encode (HOST_WIDE_INT *words, unsigned HOST_WIDE_INT low, HOST_WIDE_INT hi)
00177 {
00178 words[0] = LOWPART (low);
00179 words[1] = HIGHPART (low);
00180 words[2] = LOWPART (hi);
00181 words[3] = HIGHPART (hi);
00182 }
00183
00184
00185
00186
00187
00188 static void
00189 decode (HOST_WIDE_INT *words, unsigned HOST_WIDE_INT *low,
00190 HOST_WIDE_INT *hi)
00191 {
00192 *low = words[0] + words[1] * BASE;
00193 *hi = words[2] + words[3] * BASE;
00194 }
00195
00196
00197
00198
00199
00200
00201
00202
00203
00204
00205
00206
00207
00208
00209
00210
00211 tree
00212 force_fit_type (tree t, int overflowable,
00213 bool overflowed, bool overflowed_const)
00214 {
00215 unsigned HOST_WIDE_INT low;
00216 HOST_WIDE_INT high;
00217 unsigned int prec;
00218 int sign_extended_type;
00219
00220 gcc_assert (TREE_CODE (t) == INTEGER_CST);
00221
00222 low = TREE_INT_CST_LOW (t);
00223 high = TREE_INT_CST_HIGH (t);
00224
00225 if (POINTER_TYPE_P (TREE_TYPE (t))
00226 || TREE_CODE (TREE_TYPE (t)) == OFFSET_TYPE)
00227 prec = POINTER_SIZE;
00228 else
00229 prec = TYPE_PRECISION (TREE_TYPE (t));
00230
00231 sign_extended_type = (!TYPE_UNSIGNED (TREE_TYPE (t))
00232 || (TREE_CODE (TREE_TYPE (t)) == INTEGER_TYPE
00233 && TYPE_IS_SIZETYPE (TREE_TYPE (t))));
00234
00235
00236
00237 if (prec >= 2 * HOST_BITS_PER_WIDE_INT)
00238 ;
00239 else if (prec > HOST_BITS_PER_WIDE_INT)
00240 high &= ~((HOST_WIDE_INT) (-1) << (prec - HOST_BITS_PER_WIDE_INT));
00241 else
00242 {
00243 high = 0;
00244 if (prec < HOST_BITS_PER_WIDE_INT)
00245 low &= ~((HOST_WIDE_INT) (-1) << prec);
00246 }
00247
00248 if (!sign_extended_type)
00249 ;
00250 else if (prec >= 2 * HOST_BITS_PER_WIDE_INT)
00251 ;
00252 else if (prec > HOST_BITS_PER_WIDE_INT)
00253 {
00254
00255 if (high & ((unsigned HOST_WIDE_INT)1
00256 << (prec - HOST_BITS_PER_WIDE_INT - 1)))
00257 high |= (HOST_WIDE_INT) (-1) << (prec - HOST_BITS_PER_WIDE_INT);
00258 }
00259 else if (prec == HOST_BITS_PER_WIDE_INT)
00260 {
00261 if ((HOST_WIDE_INT)low < 0)
00262 high = -1;
00263 }
00264 else
00265 {
00266
00267 if (low & ((unsigned HOST_WIDE_INT)1 << (prec - 1)))
00268 {
00269 high = -1;
00270 low |= (HOST_WIDE_INT)(-1) << prec;
00271 }
00272 }
00273
00274
00275 if (overflowed || overflowed_const
00276 || low != TREE_INT_CST_LOW (t) || high != TREE_INT_CST_HIGH (t))
00277 {
00278 t = build_int_cst_wide (TREE_TYPE (t), low, high);
00279
00280 if (overflowed
00281 || overflowable < 0
00282 || (overflowable > 0 && sign_extended_type))
00283 {
00284 t = copy_node (t);
00285 TREE_OVERFLOW (t) = 1;
00286 TREE_CONSTANT_OVERFLOW (t) = 1;
00287 }
00288 else if (overflowed_const)
00289 {
00290 t = copy_node (t);
00291 TREE_CONSTANT_OVERFLOW (t) = 1;
00292 }
00293 }
00294
00295 return t;
00296 }
00297
00298
00299
00300
00301
00302
00303
00304 int
00305 add_double_with_sign (unsigned HOST_WIDE_INT l1, HOST_WIDE_INT h1,
00306 unsigned HOST_WIDE_INT l2, HOST_WIDE_INT h2,
00307 unsigned HOST_WIDE_INT *lv, HOST_WIDE_INT *hv,
00308 bool unsigned_p)
00309 {
00310 unsigned HOST_WIDE_INT l;
00311 HOST_WIDE_INT h;
00312
00313 l = l1 + l2;
00314 h = h1 + h2 + (l < l1);
00315
00316 *lv = l;
00317 *hv = h;
00318
00319 if (unsigned_p)
00320 return (unsigned HOST_WIDE_INT) h < (unsigned HOST_WIDE_INT) h1;
00321 else
00322 return OVERFLOW_SUM_SIGN (h1, h2, h);
00323 }
00324
00325
00326
00327
00328
00329
00330 int
00331 neg_double (unsigned HOST_WIDE_INT l1, HOST_WIDE_INT h1,
00332 unsigned HOST_WIDE_INT *lv, HOST_WIDE_INT *hv)
00333 {
00334 if (l1 == 0)
00335 {
00336 *lv = 0;
00337 *hv = - h1;
00338 return (*hv & h1) < 0;
00339 }
00340 else
00341 {
00342 *lv = -l1;
00343 *hv = ~h1;
00344 return 0;
00345 }
00346 }
00347
00348
00349
00350
00351
00352
00353
00354 int
00355 mul_double_with_sign (unsigned HOST_WIDE_INT l1, HOST_WIDE_INT h1,
00356 unsigned HOST_WIDE_INT l2, HOST_WIDE_INT h2,
00357 unsigned HOST_WIDE_INT *lv, HOST_WIDE_INT *hv,
00358 bool unsigned_p)
00359 {
00360 HOST_WIDE_INT arg1[4];
00361 HOST_WIDE_INT arg2[4];
00362 HOST_WIDE_INT prod[4 * 2];
00363 unsigned HOST_WIDE_INT carry;
00364 int i, j, k;
00365 unsigned HOST_WIDE_INT toplow, neglow;
00366 HOST_WIDE_INT tophigh, neghigh;
00367
00368 encode (arg1, l1, h1);
00369 encode (arg2, l2, h2);
00370
00371 memset (prod, 0, sizeof prod);
00372
00373 for (i = 0; i < 4; i++)
00374 {
00375 carry = 0;
00376 for (j = 0; j < 4; j++)
00377 {
00378 k = i + j;
00379
00380 carry += arg1[i] * arg2[j];
00381
00382 carry += prod[k];
00383 prod[k] = LOWPART (carry);
00384 carry = HIGHPART (carry);
00385 }
00386 prod[i + 4] = carry;
00387 }
00388
00389 decode (prod, lv, hv);
00390 decode (prod + 4, &toplow, &tophigh);
00391
00392
00393 if (unsigned_p)
00394 return (toplow | tophigh) != 0;
00395
00396
00397
00398 if (h1 < 0)
00399 {
00400 neg_double (l2, h2, &neglow, &neghigh);
00401 add_double (neglow, neghigh, toplow, tophigh, &toplow, &tophigh);
00402 }
00403 if (h2 < 0)
00404 {
00405 neg_double (l1, h1, &neglow, &neghigh);
00406 add_double (neglow, neghigh, toplow, tophigh, &toplow, &tophigh);
00407 }
00408 return (*hv < 0 ? ~(toplow & tophigh) : toplow | tophigh) != 0;
00409 }
00410
00411
00412
00413
00414
00415
00416
00417 void
00418 lshift_double (unsigned HOST_WIDE_INT l1, HOST_WIDE_INT h1,
00419 HOST_WIDE_INT count, unsigned int prec,
00420 unsigned HOST_WIDE_INT *lv, HOST_WIDE_INT *hv, int arith)
00421 {
00422 unsigned HOST_WIDE_INT signmask;
00423
00424 if (count < 0)
00425 {
00426 rshift_double (l1, h1, -count, prec, lv, hv, arith);
00427 return;
00428 }
00429
00430 if (SHIFT_COUNT_TRUNCATED)
00431 count %= prec;
00432
00433 if (count >= 2 * HOST_BITS_PER_WIDE_INT)
00434 {
00435
00436
00437 *hv = 0;
00438 *lv = 0;
00439 }
00440 else if (count >= HOST_BITS_PER_WIDE_INT)
00441 {
00442 *hv = l1 << (count - HOST_BITS_PER_WIDE_INT);
00443 *lv = 0;
00444 }
00445 else
00446 {
00447 *hv = (((unsigned HOST_WIDE_INT) h1 << count)
00448 | (l1 >> (HOST_BITS_PER_WIDE_INT - count - 1) >> 1));
00449 *lv = l1 << count;
00450 }
00451
00452
00453
00454 signmask = -((prec > HOST_BITS_PER_WIDE_INT
00455 ? ((unsigned HOST_WIDE_INT) *hv
00456 >> (prec - HOST_BITS_PER_WIDE_INT - 1))
00457 : (*lv >> (prec - 1))) & 1);
00458
00459 if (prec >= 2 * HOST_BITS_PER_WIDE_INT)
00460 ;
00461 else if (prec >= HOST_BITS_PER_WIDE_INT)
00462 {
00463 *hv &= ~((HOST_WIDE_INT) (-1) << (prec - HOST_BITS_PER_WIDE_INT));
00464 *hv |= signmask << (prec - HOST_BITS_PER_WIDE_INT);
00465 }
00466 else
00467 {
00468 *hv = signmask;
00469 *lv &= ~((unsigned HOST_WIDE_INT) (-1) << prec);
00470 *lv |= signmask << prec;
00471 }
00472 }
00473
00474
00475
00476
00477
00478
00479 void
00480 rshift_double (unsigned HOST_WIDE_INT l1, HOST_WIDE_INT h1,
00481 HOST_WIDE_INT count, unsigned int prec,
00482 unsigned HOST_WIDE_INT *lv, HOST_WIDE_INT *hv,
00483 int arith)
00484 {
00485 unsigned HOST_WIDE_INT signmask;
00486
00487 signmask = (arith
00488 ? -((unsigned HOST_WIDE_INT) h1 >> (HOST_BITS_PER_WIDE_INT - 1))
00489 : 0);
00490
00491 if (SHIFT_COUNT_TRUNCATED)
00492 count %= prec;
00493
00494 if (count >= 2 * HOST_BITS_PER_WIDE_INT)
00495 {
00496
00497
00498 *hv = 0;
00499 *lv = 0;
00500 }
00501 else if (count >= HOST_BITS_PER_WIDE_INT)
00502 {
00503 *hv = 0;
00504 *lv = (unsigned HOST_WIDE_INT) h1 >> (count - HOST_BITS_PER_WIDE_INT);
00505 }
00506 else
00507 {
00508 *hv = (unsigned HOST_WIDE_INT) h1 >> count;
00509 *lv = ((l1 >> count)
00510 | ((unsigned HOST_WIDE_INT) h1 << (HOST_BITS_PER_WIDE_INT - count - 1) << 1));
00511 }
00512
00513
00514
00515 if (count >= (HOST_WIDE_INT)prec)
00516 {
00517 *hv = signmask;
00518 *lv = signmask;
00519 }
00520 else if ((prec - count) >= 2 * HOST_BITS_PER_WIDE_INT)
00521 ;
00522 else if ((prec - count) >= HOST_BITS_PER_WIDE_INT)
00523 {
00524 *hv &= ~((HOST_WIDE_INT) (-1) << (prec - count - HOST_BITS_PER_WIDE_INT));
00525 *hv |= signmask << (prec - count - HOST_BITS_PER_WIDE_INT);
00526 }
00527 else
00528 {
00529 *hv = signmask;
00530 *lv &= ~((unsigned HOST_WIDE_INT) (-1) << (prec - count));
00531 *lv |= signmask << (prec - count);
00532 }
00533 }
00534
00535
00536
00537
00538
00539
00540 void
00541 lrotate_double (unsigned HOST_WIDE_INT l1, HOST_WIDE_INT h1,
00542 HOST_WIDE_INT count, unsigned int prec,
00543 unsigned HOST_WIDE_INT *lv, HOST_WIDE_INT *hv)
00544 {
00545 unsigned HOST_WIDE_INT s1l, s2l;
00546 HOST_WIDE_INT s1h, s2h;
00547
00548 count %= prec;
00549 if (count < 0)
00550 count += prec;
00551
00552 lshift_double (l1, h1, count, prec, &s1l, &s1h, 0);
00553 rshift_double (l1, h1, prec - count, prec, &s2l, &s2h, 0);
00554 *lv = s1l | s2l;
00555 *hv = s1h | s2h;
00556 }
00557
00558
00559
00560
00561
00562 void
00563 rrotate_double (unsigned HOST_WIDE_INT l1, HOST_WIDE_INT h1,
00564 HOST_WIDE_INT count, unsigned int prec,
00565 unsigned HOST_WIDE_INT *lv, HOST_WIDE_INT *hv)
00566 {
00567 unsigned HOST_WIDE_INT s1l, s2l;
00568 HOST_WIDE_INT s1h, s2h;
00569
00570 count %= prec;
00571 if (count < 0)
00572 count += prec;
00573
00574 rshift_double (l1, h1, count, prec, &s1l, &s1h, 0);
00575 lshift_double (l1, h1, prec - count, prec, &s2l, &s2h, 0);
00576 *lv = s1l | s2l;
00577 *hv = s1h | s2h;
00578 }
00579
00580
00581
00582
00583
00584
00585
00586
00587
00588
00589 int
00590 div_and_round_double (enum tree_code code, int uns,
00591 unsigned HOST_WIDE_INT lnum_orig,
00592 HOST_WIDE_INT hnum_orig,
00593 unsigned HOST_WIDE_INT lden_orig,
00594 HOST_WIDE_INT hden_orig,
00595 unsigned HOST_WIDE_INT *lquo,
00596 HOST_WIDE_INT *hquo, unsigned HOST_WIDE_INT *lrem,
00597 HOST_WIDE_INT *hrem)
00598 {
00599 int quo_neg = 0;
00600 HOST_WIDE_INT num[4 + 1];
00601 HOST_WIDE_INT den[4], quo[4];
00602 int i, j;
00603 unsigned HOST_WIDE_INT work;
00604 unsigned HOST_WIDE_INT carry = 0;
00605 unsigned HOST_WIDE_INT lnum = lnum_orig;
00606 HOST_WIDE_INT hnum = hnum_orig;
00607 unsigned HOST_WIDE_INT lden = lden_orig;
00608 HOST_WIDE_INT hden = hden_orig;
00609 int overflow = 0;
00610
00611 if (hden == 0 && lden == 0)
00612 overflow = 1, lden = 1;
00613
00614
00615 if (!uns)
00616 {
00617 if (hnum < 0)
00618 {
00619 quo_neg = ~ quo_neg;
00620
00621 if (neg_double (lnum, hnum, &lnum, &hnum)
00622 && ((HOST_WIDE_INT) lden & hden) == -1)
00623 overflow = 1;
00624 }
00625 if (hden < 0)
00626 {
00627 quo_neg = ~ quo_neg;
00628 neg_double (lden, hden, &lden, &hden);
00629 }
00630 }
00631
00632 if (hnum == 0 && hden == 0)
00633 {
00634 *hquo = *hrem = 0;
00635
00636 *lquo = lnum / lden;
00637 goto finish_up;
00638 }
00639
00640 if (hnum == 0)
00641 {
00642
00643 *hquo = *lquo = 0;
00644 *hrem = hnum;
00645 *lrem = lnum;
00646 goto finish_up;
00647 }
00648
00649 memset (quo, 0, sizeof quo);
00650
00651 memset (num, 0, sizeof num);
00652 memset (den, 0, sizeof den);
00653
00654 encode (num, lnum, hnum);
00655 encode (den, lden, hden);
00656
00657
00658 if (hden == 0 && lden < (unsigned HOST_WIDE_INT) BASE)
00659 {
00660
00661 for (i = 4 - 1; i >= 0; i--)
00662 {
00663 work = num[i] + carry * BASE;
00664 quo[i] = work / lden;
00665 carry = work % lden;
00666 }
00667 }
00668 else
00669 {
00670
00671
00672 int num_hi_sig, den_hi_sig;
00673 unsigned HOST_WIDE_INT quo_est, scale;
00674
00675
00676 for (i = 4 - 1;; i--)
00677 if (den[i] != 0)
00678 {
00679 den_hi_sig = i;
00680 break;
00681 }
00682
00683
00684
00685
00686 scale = BASE / (den[den_hi_sig] + 1);
00687 if (scale > 1)
00688 {
00689 carry = 0;
00690 for (i = 0; i <= 4 - 1; i++)
00691 {
00692 work = (num[i] * scale) + carry;
00693 num[i] = LOWPART (work);
00694 carry = HIGHPART (work);
00695 }
00696
00697 num[4] = carry;
00698 carry = 0;
00699 for (i = 0; i <= 4 - 1; i++)
00700 {
00701 work = (den[i] * scale) + carry;
00702 den[i] = LOWPART (work);
00703 carry = HIGHPART (work);
00704 if (den[i] != 0) den_hi_sig = i;
00705 }
00706 }
00707
00708 num_hi_sig = 4;
00709
00710
00711 for (i = num_hi_sig - den_hi_sig - 1; i >= 0; i--)
00712 {
00713
00714
00715
00716 unsigned HOST_WIDE_INT tmp;
00717
00718 num_hi_sig = i + den_hi_sig + 1;
00719 work = num[num_hi_sig] * BASE + num[num_hi_sig - 1];
00720 if (num[num_hi_sig] != den[den_hi_sig])
00721 quo_est = work / den[den_hi_sig];
00722 else
00723 quo_est = BASE - 1;
00724
00725
00726 tmp = work - quo_est * den[den_hi_sig];
00727 if (tmp < BASE
00728 && (den[den_hi_sig - 1] * quo_est
00729 > (tmp * BASE + num[num_hi_sig - 2])))
00730 quo_est--;
00731
00732
00733
00734
00735
00736 carry = 0;
00737 for (j = 0; j <= den_hi_sig; j++)
00738 {
00739 work = quo_est * den[j] + carry;
00740 carry = HIGHPART (work);
00741 work = num[i + j] - LOWPART (work);
00742 num[i + j] = LOWPART (work);
00743 carry += HIGHPART (work) != 0;
00744 }
00745
00746
00747
00748 if (num[num_hi_sig] < (HOST_WIDE_INT) carry)
00749 {
00750 quo_est--;
00751 carry = 0;
00752 for (j = 0; j <= den_hi_sig; j++)
00753 {
00754 work = num[i + j] + den[j] + carry;
00755 carry = HIGHPART (work);
00756 num[i + j] = LOWPART (work);
00757 }
00758
00759 num [num_hi_sig] += carry;
00760 }
00761
00762
00763 quo[i] = quo_est;
00764 }
00765 }
00766
00767 decode (quo, lquo, hquo);
00768
00769 finish_up:
00770
00771 if (quo_neg)
00772 neg_double (*lquo, *hquo, lquo, hquo);
00773
00774
00775 mul_double (*lquo, *hquo, lden_orig, hden_orig, lrem, hrem);
00776 neg_double (*lrem, *hrem, lrem, hrem);
00777 add_double (lnum_orig, hnum_orig, *lrem, *hrem, lrem, hrem);
00778
00779 switch (code)
00780 {
00781 case TRUNC_DIV_EXPR:
00782 case TRUNC_MOD_EXPR:
00783 case EXACT_DIV_EXPR:
00784 return overflow;
00785
00786 case FLOOR_DIV_EXPR:
00787 case FLOOR_MOD_EXPR:
00788 if (quo_neg && (*lrem != 0 || *hrem != 0))
00789 {
00790
00791 add_double (*lquo, *hquo, (HOST_WIDE_INT) -1, (HOST_WIDE_INT) -1,
00792 lquo, hquo);
00793 }
00794 else
00795 return overflow;
00796 break;
00797
00798 case CEIL_DIV_EXPR:
00799 case CEIL_MOD_EXPR:
00800 if (!quo_neg && (*lrem != 0 || *hrem != 0))
00801 {
00802 add_double (*lquo, *hquo, (HOST_WIDE_INT) 1, (HOST_WIDE_INT) 0,
00803 lquo, hquo);
00804 }
00805 else
00806 return overflow;
00807 break;
00808
00809 case ROUND_DIV_EXPR:
00810 case ROUND_MOD_EXPR:
00811 {
00812 unsigned HOST_WIDE_INT labs_rem = *lrem;
00813 HOST_WIDE_INT habs_rem = *hrem;
00814 unsigned HOST_WIDE_INT labs_den = lden, ltwice;
00815 HOST_WIDE_INT habs_den = hden, htwice;
00816
00817
00818 if (*hrem < 0)
00819 neg_double (*lrem, *hrem, &labs_rem, &habs_rem);
00820 if (hden < 0)
00821 neg_double (lden, hden, &labs_den, &habs_den);
00822
00823
00824 mul_double ((HOST_WIDE_INT) 2, (HOST_WIDE_INT) 0,
00825 labs_rem, habs_rem, <wice, &htwice);
00826
00827 if (((unsigned HOST_WIDE_INT) habs_den
00828 < (unsigned HOST_WIDE_INT) htwice)
00829 || (((unsigned HOST_WIDE_INT) habs_den
00830 == (unsigned HOST_WIDE_INT) htwice)
00831 && (labs_den < ltwice)))
00832 {
00833 if (*hquo < 0)
00834
00835 add_double (*lquo, *hquo,
00836 (HOST_WIDE_INT) -1, (HOST_WIDE_INT) -1, lquo, hquo);
00837 else
00838
00839 add_double (*lquo, *hquo, (HOST_WIDE_INT) 1, (HOST_WIDE_INT) 0,
00840 lquo, hquo);
00841 }
00842 else
00843 return overflow;
00844 }
00845 break;
00846
00847 default:
00848 gcc_unreachable ();
00849 }
00850
00851
00852 mul_double (*lquo, *hquo, lden_orig, hden_orig, lrem, hrem);
00853 neg_double (*lrem, *hrem, lrem, hrem);
00854 add_double (lnum_orig, hnum_orig, *lrem, *hrem, lrem, hrem);
00855 return overflow;
00856 }
00857
00858
00859
00860
00861
00862 static tree
00863 div_if_zero_remainder (enum tree_code code, tree arg1, tree arg2)
00864 {
00865 unsigned HOST_WIDE_INT int1l, int2l;
00866 HOST_WIDE_INT int1h, int2h;
00867 unsigned HOST_WIDE_INT quol, reml;
00868 HOST_WIDE_INT quoh, remh;
00869 tree type = TREE_TYPE (arg1);
00870 int uns = TYPE_UNSIGNED (type);
00871
00872 int1l = TREE_INT_CST_LOW (arg1);
00873 int1h = TREE_INT_CST_HIGH (arg1);
00874 int2l = TREE_INT_CST_LOW (arg2);
00875 int2h = TREE_INT_CST_HIGH (arg2);
00876
00877 div_and_round_double (code, uns, int1l, int1h, int2l, int2h,
00878 &quol, &quoh, &reml, &remh);
00879 if (remh != 0 || reml != 0)
00880 return NULL_TREE;
00881
00882 return build_int_cst_wide (type, quol, quoh);
00883 }
00884
00885
00886
00887
00888
00889
00890
00891
00892
00893
00894 static int fold_deferring_overflow_warnings;
00895
00896
00897
00898
00899
00900
00901 static const char* fold_deferred_overflow_warning;
00902
00903
00904
00905
00906 static enum warn_strict_overflow_code fold_deferred_overflow_code;
00907
00908
00909
00910
00911 void
00912 fold_defer_overflow_warnings (void)
00913 {
00914 ++fold_deferring_overflow_warnings;
00915 }
00916
00917
00918
00919
00920
00921
00922
00923
00924
00925
00926 void
00927 fold_undefer_overflow_warnings (bool issue, tree stmt, int code)
00928 {
00929 const char *warnmsg;
00930 location_t locus;
00931
00932 gcc_assert (fold_deferring_overflow_warnings > 0);
00933 --fold_deferring_overflow_warnings;
00934 if (fold_deferring_overflow_warnings > 0)
00935 {
00936 if (fold_deferred_overflow_warning != NULL
00937 && code != 0
00938 && code < (int) fold_deferred_overflow_code)
00939 fold_deferred_overflow_code = code;
00940 return;
00941 }
00942
00943 warnmsg = fold_deferred_overflow_warning;
00944 fold_deferred_overflow_warning = NULL;
00945
00946 if (!issue || warnmsg == NULL)
00947 return;
00948
00949
00950
00951 if (code == 0 || code > (int) fold_deferred_overflow_code)
00952 code = fold_deferred_overflow_code;
00953
00954 if (!issue_strict_overflow_warning (code))
00955 return;
00956
00957 if (stmt == NULL_TREE || !EXPR_HAS_LOCATION (stmt))
00958 locus = input_location;
00959 else
00960 locus = EXPR_LOCATION (stmt);
00961 warning (OPT_Wstrict_overflow, "%H%s", &locus, warnmsg);
00962 }
00963
00964
00965
00966
00967 void
00968 fold_undefer_and_ignore_overflow_warnings (void)
00969 {
00970 fold_undefer_overflow_warnings (false, NULL_TREE, 0);
00971 }
00972
00973
00974
00975 bool
00976 fold_deferring_overflow_warnings_p (void)
00977 {
00978 return fold_deferring_overflow_warnings > 0;
00979 }
00980
00981
00982
00983
00984 static void
00985 fold_overflow_warning (const char* gmsgid, enum warn_strict_overflow_code wc)
00986 {
00987 gcc_assert (!flag_wrapv && !flag_trapv);
00988 if (fold_deferring_overflow_warnings > 0)
00989 {
00990 if (fold_deferred_overflow_warning == NULL
00991 || wc < fold_deferred_overflow_code)
00992 {
00993 fold_deferred_overflow_warning = gmsgid;
00994 fold_deferred_overflow_code = wc;
00995 }
00996 }
00997 else if (issue_strict_overflow_warning (wc))
00998 warning (OPT_Wstrict_overflow, gmsgid);
00999 }
01000
01001
01002
01003
01004 static bool
01005 negate_mathfn_p (enum built_in_function code)
01006 {
01007 switch (code)
01008 {
01009 CASE_FLT_FN (BUILT_IN_ASIN):
01010 CASE_FLT_FN (BUILT_IN_ASINH):
01011 CASE_FLT_FN (BUILT_IN_ATAN):
01012 CASE_FLT_FN (BUILT_IN_ATANH):
01013 CASE_FLT_FN (BUILT_IN_CBRT):
01014 CASE_FLT_FN (BUILT_IN_SIN):
01015 CASE_FLT_FN (BUILT_IN_SINH):
01016 CASE_FLT_FN (BUILT_IN_TAN):
01017 CASE_FLT_FN (BUILT_IN_TANH):
01018 return true;
01019
01020 default:
01021 break;
01022 }
01023 return false;
01024 }
01025
01026
01027
01028
01029 bool
01030 may_negate_without_overflow_p (tree t)
01031 {
01032 unsigned HOST_WIDE_INT val;
01033 unsigned int prec;
01034 tree type;
01035
01036 gcc_assert (TREE_CODE (t) == INTEGER_CST);
01037
01038 type = TREE_TYPE (t);
01039 if (TYPE_UNSIGNED (type))
01040 return false;
01041
01042 prec = TYPE_PRECISION (type);
01043 if (prec > HOST_BITS_PER_WIDE_INT)
01044 {
01045 if (TREE_INT_CST_LOW (t) != 0)
01046 return true;
01047 prec -= HOST_BITS_PER_WIDE_INT;
01048 val = TREE_INT_CST_HIGH (t);
01049 }
01050 else
01051 val = TREE_INT_CST_LOW (t);
01052 if (prec < HOST_BITS_PER_WIDE_INT)
01053 val &= ((unsigned HOST_WIDE_INT) 1 << prec) - 1;
01054 return val != ((unsigned HOST_WIDE_INT) 1 << (prec - 1));
01055 }
01056
01057
01058
01059
01060 static bool
01061 negate_expr_p (tree t)
01062 {
01063 tree type;
01064
01065 if (t == 0)
01066 return false;
01067
01068 type = TREE_TYPE (t);
01069
01070 STRIP_SIGN_NOPS (t);
01071 switch (TREE_CODE (t))
01072 {
01073 case INTEGER_CST:
01074 if (TYPE_OVERFLOW_WRAPS (type))
01075 return true;
01076
01077
01078 return may_negate_without_overflow_p (t);
01079 case BIT_NOT_EXPR:
01080 return (INTEGRAL_TYPE_P (type)
01081 && TYPE_OVERFLOW_WRAPS (type));
01082
01083 case REAL_CST:
01084 case NEGATE_EXPR:
01085 return true;
01086
01087 case COMPLEX_CST:
01088 return negate_expr_p (TREE_REALPART (t))
01089 && negate_expr_p (TREE_IMAGPART (t));
01090
01091 case PLUS_EXPR:
01092 if (FLOAT_TYPE_P (type) && !flag_unsafe_math_optimizations)
01093 return false;
01094
01095 if (negate_expr_p (TREE_OPERAND (t, 1))
01096 && reorder_operands_p (TREE_OPERAND (t, 0),
01097 TREE_OPERAND (t, 1)))
01098 return true;
01099
01100 return negate_expr_p (TREE_OPERAND (t, 0));
01101
01102 case MINUS_EXPR:
01103
01104 return (! FLOAT_TYPE_P (type) || flag_unsafe_math_optimizations)
01105 && reorder_operands_p (TREE_OPERAND (t, 0),
01106 TREE_OPERAND (t, 1));
01107
01108 case MULT_EXPR:
01109 if (TYPE_UNSIGNED (TREE_TYPE (t)))
01110 break;
01111
01112
01113
01114 case RDIV_EXPR:
01115 if (! HONOR_SIGN_DEPENDENT_ROUNDING (TYPE_MODE (TREE_TYPE (t))))
01116 return negate_expr_p (TREE_OPERAND (t, 1))
01117 || negate_expr_p (TREE_OPERAND (t, 0));
01118 break;
01119
01120 case TRUNC_DIV_EXPR:
01121 case ROUND_DIV_EXPR:
01122 case FLOOR_DIV_EXPR:
01123 case CEIL_DIV_EXPR:
01124 case EXACT_DIV_EXPR:
01125
01126
01127
01128
01129
01130 if (INTEGRAL_TYPE_P (TREE_TYPE (t))
01131 && !TYPE_OVERFLOW_UNDEFINED (TREE_TYPE (t)))
01132 break;
01133 return negate_expr_p (TREE_OPERAND (t, 1))
01134 || negate_expr_p (TREE_OPERAND (t, 0));
01135
01136 case NOP_EXPR:
01137
01138 if (TREE_CODE (type) == REAL_TYPE)
01139 {
01140 tree tem = strip_float_extensions (t);
01141 if (tem != t)
01142 return negate_expr_p (tem);
01143 }
01144 break;
01145
01146 case CALL_EXPR:
01147
01148 if (negate_mathfn_p (builtin_mathfn_code (t)))
01149 return negate_expr_p (TREE_VALUE (TREE_OPERAND (t, 1)));
01150 break;
01151
01152 case RSHIFT_EXPR:
01153
01154 if (TREE_CODE (TREE_OPERAND (t, 1)) == INTEGER_CST)
01155 {
01156 tree op1 = TREE_OPERAND (t, 1);
01157 if (TREE_INT_CST_HIGH (op1) == 0
01158 && (unsigned HOST_WIDE_INT) (TYPE_PRECISION (type) - 1)
01159 == TREE_INT_CST_LOW (op1))
01160 return true;
01161 }
01162 break;
01163
01164 default:
01165 break;
01166 }
01167 return false;
01168 }
01169
01170
01171
01172
01173
01174
01175 static tree
01176 fold_negate_expr (tree t)
01177 {
01178 tree type = TREE_TYPE (t);
01179 tree tem;
01180
01181 switch (TREE_CODE (t))
01182 {
01183
01184 case BIT_NOT_EXPR:
01185 if (INTEGRAL_TYPE_P (type))
01186 return fold_build2 (PLUS_EXPR, type, TREE_OPERAND (t, 0),
01187 build_int_cst (type, 1));
01188 break;
01189
01190 case INTEGER_CST:
01191 tem = fold_negate_const (t, type);
01192 if (!TREE_OVERFLOW (tem)
01193 || !TYPE_OVERFLOW_TRAPS (type))
01194 return tem;
01195 break;
01196
01197 case REAL_CST:
01198 tem = fold_negate_const (t, type);
01199
01200 if (! TREE_OVERFLOW (tem) || ! flag_trapping_math)
01201 return tem;
01202 break;
01203
01204 case COMPLEX_CST:
01205 {
01206 tree rpart = negate_expr (TREE_REALPART (t));
01207 tree ipart = negate_expr (TREE_IMAGPART (t));
01208
01209 if ((TREE_CODE (rpart) == REAL_CST
01210 && TREE_CODE (ipart) == REAL_CST)
01211 || (TREE_CODE (rpart) == INTEGER_CST
01212 && TREE_CODE (ipart) == INTEGER_CST))
01213 return build_complex (type, rpart, ipart);
01214 }
01215 break;
01216
01217 case NEGATE_EXPR:
01218 return TREE_OPERAND (t, 0);
01219
01220 case PLUS_EXPR:
01221 if (! FLOAT_TYPE_P (type) || flag_unsafe_math_optimizations)
01222 {
01223
01224 if (negate_expr_p (TREE_OPERAND (t, 1))
01225 && reorder_operands_p (TREE_OPERAND (t, 0),
01226 TREE_OPERAND (t, 1)))
01227 {
01228 tem = negate_expr (TREE_OPERAND (t, 1));
01229 return fold_build2 (MINUS_EXPR, type,
01230 tem, TREE_OPERAND (t, 0));
01231 }
01232
01233
01234 if (negate_expr_p (TREE_OPERAND (t, 0)))
01235 {
01236 tem = negate_expr (TREE_OPERAND (t, 0));
01237 return fold_build2 (MINUS_EXPR, type,
01238 tem, TREE_OPERAND (t, 1));
01239 }
01240 }
01241 break;
01242
01243 case MINUS_EXPR:
01244
01245 if ((! FLOAT_TYPE_P (type) || flag_unsafe_math_optimizations)
01246 && reorder_operands_p (TREE_OPERAND (t, 0), TREE_OPERAND (t, 1)))
01247 return fold_build2 (MINUS_EXPR, type,
01248 TREE_OPERAND (t, 1), TREE_OPERAND (t, 0));
01249 break;
01250
01251 case MULT_EXPR:
01252 if (TYPE_UNSIGNED (type))
01253 break;
01254
01255
01256
01257 case RDIV_EXPR:
01258 if (! HONOR_SIGN_DEPENDENT_ROUNDING (TYPE_MODE (type)))
01259 {
01260 tem = TREE_OPERAND (t, 1);
01261 if (negate_expr_p (tem))
01262 return fold_build2 (TREE_CODE (t), type,
01263 TREE_OPERAND (t, 0), negate_expr (tem));
01264 tem = TREE_OPERAND (t, 0);
01265 if (negate_expr_p (tem))
01266 return fold_build2 (TREE_CODE (t), type,
01267 negate_expr (tem), TREE_OPERAND (t, 1));
01268 }
01269 break;
01270
01271 case TRUNC_DIV_EXPR:
01272 case ROUND_DIV_EXPR:
01273 case FLOOR_DIV_EXPR:
01274 case CEIL_DIV_EXPR:
01275 case EXACT_DIV_EXPR:
01276
01277
01278
01279
01280
01281 if (!INTEGRAL_TYPE_P (type) || TYPE_OVERFLOW_UNDEFINED (type))
01282 {
01283 const char * const warnmsg = G_("assuming signed overflow does not "
01284 "occur when negating a division");
01285 tem = TREE_OPERAND (t, 1);
01286 if (negate_expr_p (tem))
01287 {
01288 if (INTEGRAL_TYPE_P (type)
01289 && (TREE_CODE (tem) != INTEGER_CST
01290 || integer_onep (tem)))
01291 fold_overflow_warning (warnmsg, WARN_STRICT_OVERFLOW_MISC);
01292 return fold_build2 (TREE_CODE (t), type,
01293 TREE_OPERAND (t, 0), negate_expr (tem));
01294 }
01295 tem = TREE_OPERAND (t, 0);
01296 if (negate_expr_p (tem))
01297 {
01298 if (INTEGRAL_TYPE_P (type)
01299 && (TREE_CODE (tem) != INTEGER_CST
01300 || tree_int_cst_equal (tem, TYPE_MIN_VALUE (type))))
01301 fold_overflow_warning (warnmsg, WARN_STRICT_OVERFLOW_MISC);
01302 return fold_build2 (TREE_CODE (t), type,
01303 negate_expr (tem), TREE_OPERAND (t, 1));
01304 }
01305 }
01306 break;
01307
01308 case NOP_EXPR:
01309
01310 if (TREE_CODE (type) == REAL_TYPE)
01311 {
01312 tem = strip_float_extensions (t);
01313 if (tem != t && negate_expr_p (tem))
01314 return negate_expr (tem);
01315 }
01316 break;
01317
01318 case CALL_EXPR:
01319
01320 if (negate_mathfn_p (builtin_mathfn_code (t))
01321 && negate_expr_p (TREE_VALUE (TREE_OPERAND (t, 1))))
01322 {
01323 tree fndecl, arg, arglist;
01324
01325 fndecl = get_callee_fndecl (t);
01326 arg = negate_expr (TREE_VALUE (TREE_OPERAND (t, 1)));
01327 arglist = build_tree_list (NULL_TREE, arg);
01328 return build_function_call_expr (fndecl, arglist);
01329 }
01330 break;
01331
01332 case RSHIFT_EXPR:
01333
01334 if (TREE_CODE (TREE_OPERAND (t, 1)) == INTEGER_CST)
01335 {
01336 tree op1 = TREE_OPERAND (t, 1);
01337 if (TREE_INT_CST_HIGH (op1) == 0
01338 && (unsigned HOST_WIDE_INT) (TYPE_PRECISION (type) - 1)
01339 == TREE_INT_CST_LOW (op1))
01340 {
01341 tree ntype = TYPE_UNSIGNED (type)
01342 ? lang_hooks.types.signed_type (type)
01343 : lang_hooks.types.unsigned_type (type);
01344 tree temp = fold_convert (ntype, TREE_OPERAND (t, 0));
01345 temp = fold_build2 (RSHIFT_EXPR, ntype, temp, op1);
01346 return fold_convert (type, temp);
01347 }
01348 }
01349 break;
01350
01351 default:
01352 break;
01353 }
01354
01355 return NULL_TREE;
01356 }
01357
01358
01359
01360
01361
01362 static tree
01363 negate_expr (tree t)
01364 {
01365 tree type, tem;
01366
01367 if (t == NULL_TREE)
01368 return NULL_TREE;
01369
01370 type = TREE_TYPE (t);
01371 STRIP_SIGN_NOPS (t);
01372
01373 tem = fold_negate_expr (t);
01374 if (!tem)
01375 tem = build1 (NEGATE_EXPR, TREE_TYPE (t), t);
01376 return fold_convert (type, tem);
01377 }
01378
01379
01380
01381
01382
01383
01384
01385
01386
01387
01388
01389
01390
01391
01392
01393
01394
01395
01396
01397
01398
01399 static tree
01400 split_tree (tree in, enum tree_code code, tree *conp, tree *litp,
01401 tree *minus_litp, int negate_p)
01402 {
01403 tree var = 0;
01404
01405 *conp = 0;
01406 *litp = 0;
01407 *minus_litp = 0;
01408
01409
01410 STRIP_SIGN_NOPS (in);
01411
01412 if (TREE_CODE (in) == INTEGER_CST || TREE_CODE (in) == REAL_CST)
01413 *litp = in;
01414 else if (TREE_CODE (in) == code
01415 || (! FLOAT_TYPE_P (TREE_TYPE (in))
01416
01417
01418
01419
01420 && ((code == PLUS_EXPR && TREE_CODE (in) == MINUS_EXPR)
01421 || (code == MINUS_EXPR && TREE_CODE (in) == PLUS_EXPR))))
01422 {
01423 tree op0 = TREE_OPERAND (in, 0);
01424 tree op1 = TREE_OPERAND (in, 1);
01425 int neg1_p = TREE_CODE (in) == MINUS_EXPR;
01426 int neg_litp_p = 0, neg_conp_p = 0, neg_var_p = 0;
01427
01428
01429 if (TREE_CODE (op0) == INTEGER_CST || TREE_CODE (op0) == REAL_CST)
01430 *litp = op0, op0 = 0;
01431 else if (TREE_CODE (op1) == INTEGER_CST || TREE_CODE (op1) == REAL_CST)
01432 *litp = op1, neg_litp_p = neg1_p, op1 = 0;
01433
01434 if (op0 != 0 && TREE_CONSTANT (op0))
01435 *conp = op0, op0 = 0;
01436 else if (op1 != 0 && TREE_CONSTANT (op1))
01437 *conp = op1, neg_conp_p = neg1_p, op1 = 0;
01438
01439
01440
01441 if (op0 != 0 && op1 != 0)
01442 var = in;
01443 else if (op0 != 0)
01444 var = op0;
01445 else
01446 var = op1, neg_var_p = neg1_p;
01447
01448
01449 if (neg_litp_p)
01450 *minus_litp = *litp, *litp = 0;
01451 if (neg_conp_p)
01452 *conp = negate_expr (*conp);
01453 if (neg_var_p)
01454 var = negate_expr (var);
01455 }
01456 else if (TREE_CONSTANT (in))
01457 *conp = in;
01458 else
01459 var = in;
01460
01461 if (negate_p)
01462 {
01463 if (*litp)
01464 *minus_litp = *litp, *litp = 0;
01465 else if (*minus_litp)
01466 *litp = *minus_litp, *minus_litp = 0;
01467 *conp = negate_expr (*conp);
01468 var = negate_expr (var);
01469 }
01470
01471 return var;
01472 }
01473
01474
01475
01476
01477
01478 static tree
01479 associate_trees (tree t1, tree t2, enum tree_code code, tree type)
01480 {
01481 if (t1 == 0)
01482 return t2;
01483 else if (t2 == 0)
01484 return t1;
01485
01486
01487
01488
01489 if (TREE_CODE (t1) == code || TREE_CODE (t2) == code
01490 || TREE_CODE (t1) == MINUS_EXPR || TREE_CODE (t2) == MINUS_EXPR)
01491 {
01492 if (code == PLUS_EXPR)
01493 {
01494 if (TREE_CODE (t1) == NEGATE_EXPR)
01495 return build2 (MINUS_EXPR, type, fold_convert (type, t2),
01496 fold_convert (type, TREE_OPERAND (t1, 0)));
01497 else if (TREE_CODE (t2) == NEGATE_EXPR)
01498 return build2 (MINUS_EXPR, type, fold_convert (type, t1),
01499 fold_convert (type, TREE_OPERAND (t2, 0)));
01500 else if (integer_zerop (t2))
01501 return fold_convert (type, t1);
01502 }
01503 else if (code == MINUS_EXPR)
01504 {
01505 if (integer_zerop (t2))
01506 return fold_convert (type, t1);
01507 }
01508
01509 return build2 (code, type, fold_convert (type, t1),
01510 fold_convert (type, t2));
01511 }
01512
01513 return fold_build2 (code, type, fold_convert (type, t1),
01514 fold_convert (type, t2));
01515 }
01516
01517
01518
01519
01520
01521
01522
01523 tree
01524 int_const_binop (enum tree_code code, tree arg1, tree arg2, int notrunc)
01525 {
01526 unsigned HOST_WIDE_INT int1l, int2l;
01527 HOST_WIDE_INT int1h, int2h;
01528 unsigned HOST_WIDE_INT low;
01529 HOST_WIDE_INT hi;
01530 unsigned HOST_WIDE_INT garbagel;
01531 HOST_WIDE_INT garbageh;
01532 tree t;
01533 tree type = TREE_TYPE (arg1);
01534 int uns = TYPE_UNSIGNED (type);
01535 int is_sizetype
01536 = (TREE_CODE (type) == INTEGER_TYPE && TYPE_IS_SIZETYPE (type));
01537 int overflow = 0;
01538
01539 int1l = TREE_INT_CST_LOW (arg1);
01540 int1h = TREE_INT_CST_HIGH (arg1);
01541 int2l = TREE_INT_CST_LOW (arg2);
01542 int2h = TREE_INT_CST_HIGH (arg2);
01543
01544 switch (code)
01545 {
01546 case BIT_IOR_EXPR:
01547 low = int1l | int2l, hi = int1h | int2h;
01548 break;
01549
01550 case BIT_XOR_EXPR:
01551 low = int1l ^ int2l, hi = int1h ^ int2h;
01552 break;
01553
01554 case BIT_AND_EXPR:
01555 low = int1l & int2l, hi = int1h & int2h;
01556 break;
01557
01558 case RSHIFT_EXPR:
01559 int2l = -int2l;
01560 case LSHIFT_EXPR:
01561
01562
01563
01564 lshift_double (int1l, int1h, int2l, TYPE_PRECISION (type),
01565 &low, &hi, !uns);
01566 break;
01567
01568 case RROTATE_EXPR:
01569 int2l = - int2l;
01570 case LROTATE_EXPR:
01571 lrotate_double (int1l, int1h, int2l, TYPE_PRECISION (type),
01572 &low, &hi);
01573 break;
01574
01575 case PLUS_EXPR:
01576 overflow = add_double (int1l, int1h, int2l, int2h, &low, &hi);
01577 break;
01578
01579 case MINUS_EXPR:
01580 neg_double (int2l, int2h, &low, &hi);
01581 add_double (int1l, int1h, low, hi, &low, &hi);
01582 overflow = OVERFLOW_SUM_SIGN (hi, int2h, int1h);
01583 break;
01584
01585 case MULT_EXPR:
01586 overflow = mul_double (int1l, int1h, int2l, int2h, &low, &hi);
01587 break;
01588
01589 case TRUNC_DIV_EXPR:
01590 case FLOOR_DIV_EXPR: case CEIL_DIV_EXPR:
01591 case EXACT_DIV_EXPR:
01592
01593 if (int2h == 0 && (HOST_WIDE_INT) int2l > 0
01594 && ! TREE_CONSTANT_OVERFLOW (arg1)
01595 && ! TREE_CONSTANT_OVERFLOW (arg2)
01596 && int1h == 0 && (HOST_WIDE_INT) int1l >= 0)
01597 {
01598 if (code == CEIL_DIV_EXPR)
01599 int1l += int2l - 1;
01600
01601 low = int1l / int2l, hi = 0;
01602 break;
01603 }
01604
01605
01606
01607 case ROUND_DIV_EXPR:
01608 if (int2h == 0 && int2l == 0)
01609 return NULL_TREE;
01610 if (int2h == 0 && int2l == 1)
01611 {
01612 low = int1l, hi = int1h;
01613 break;
01614 }
01615 if (int1l == int2l && int1h == int2h
01616 && ! (int1l == 0 && int1h == 0))
01617 {
01618 low = 1, hi = 0;
01619 break;
01620 }
01621 overflow = div_and_round_double (code, uns, int1l, int1h, int2l, int2h,
01622 &low, &hi, &garbagel, &garbageh);
01623 break;
01624
01625 case TRUNC_MOD_EXPR:
01626 case FLOOR_MOD_EXPR: case CEIL_MOD_EXPR:
01627
01628 if (int2h == 0 && (HOST_WIDE_INT) int2l > 0
01629 && ! TREE_CONSTANT_OVERFLOW (arg1)
01630 && ! TREE_CONSTANT_OVERFLOW (arg2)
01631 && int1h == 0 && (HOST_WIDE_INT) int1l >= 0)
01632 {
01633 if (code == CEIL_MOD_EXPR)
01634 int1l += int2l - 1;
01635 low = int1l % int2l, hi = 0;
01636 break;
01637 }
01638
01639
01640
01641 case ROUND_MOD_EXPR:
01642 if (int2h == 0 && int2l == 0)
01643 return NULL_TREE;
01644 overflow = div_and_round_double (code, uns,
01645 int1l, int1h, int2l, int2h,
01646 &garbagel, &garbageh, &low, &hi);
01647 break;
01648
01649 case MIN_EXPR:
01650 case MAX_EXPR:
01651 if (uns)
01652 low = (((unsigned HOST_WIDE_INT) int1h
01653 < (unsigned HOST_WIDE_INT) int2h)
01654 || (((unsigned HOST_WIDE_INT) int1h
01655 == (unsigned HOST_WIDE_INT) int2h)
01656 && int1l < int2l));
01657 else
01658 low = (int1h < int2h
01659 || (int1h == int2h && int1l < int2l));
01660
01661 if (low == (code == MIN_EXPR))
01662 low = int1l, hi = int1h;
01663 else
01664 low = int2l, hi = int2h;
01665 break;
01666
01667 default:
01668 return NULL_TREE;
01669 }
01670
01671 t = build_int_cst_wide (TREE_TYPE (arg1), low, hi);
01672
01673 if (notrunc)
01674 {
01675
01676 if (((!uns || is_sizetype) && overflow)
01677 | TREE_OVERFLOW (arg1) | TREE_OVERFLOW (arg2))
01678 {
01679 t = copy_node (t);
01680 TREE_OVERFLOW (t) = 1;
01681 TREE_CONSTANT_OVERFLOW (t) = 1;
01682 }
01683 else if (TREE_CONSTANT_OVERFLOW (arg1) | TREE_CONSTANT_OVERFLOW (arg2))
01684 {
01685 t = copy_node (t);
01686 TREE_CONSTANT_OVERFLOW (t) = 1;
01687 }
01688 }
01689 else
01690 t = force_fit_type (t, 1,
01691 ((!uns || is_sizetype) && overflow)
01692 | TREE_OVERFLOW (arg1) | TREE_OVERFLOW (arg2),
01693 TREE_CONSTANT_OVERFLOW (arg1)
01694 | TREE_CONSTANT_OVERFLOW (arg2));
01695
01696 return t;
01697 }
01698
01699
01700
01701
01702
01703
01704
01705
01706 static tree
01707 const_binop (enum tree_code code, tree arg1, tree arg2, int notrunc)
01708 {
01709
01710 if (!arg1 || !arg2)
01711 return NULL_TREE;
01712
01713 STRIP_NOPS (arg1);
01714 STRIP_NOPS (arg2);
01715
01716 if (TREE_CODE (arg1) == INTEGER_CST)
01717 return int_const_binop (code, arg1, arg2, notrunc);
01718
01719 if (TREE_CODE (arg1) == REAL_CST)
01720 {
01721 enum machine_mode mode;
01722 REAL_VALUE_TYPE d1;
01723 REAL_VALUE_TYPE d2;
01724 REAL_VALUE_TYPE value;
01725 REAL_VALUE_TYPE result;
01726 bool inexact;
01727 tree t, type;
01728
01729
01730 switch (code)
01731 {
01732 case PLUS_EXPR:
01733 case MINUS_EXPR:
01734 case MULT_EXPR:
01735 case RDIV_EXPR:
01736 case MIN_EXPR:
01737 case MAX_EXPR:
01738 break;
01739
01740 default:
01741 return NULL_TREE;
01742 }
01743
01744 d1 = TREE_REAL_CST (arg1);
01745 d2 = TREE_REAL_CST (arg2);
01746
01747 type = TREE_TYPE (arg1);
01748 mode = TYPE_MODE (type);
01749
01750
01751
01752 if (HONOR_SNANS (mode)
01753 && (REAL_VALUE_ISNAN (d1) || REAL_VALUE_ISNAN (d2)))
01754 return NULL_TREE;
01755
01756
01757
01758 if (code == RDIV_EXPR
01759 && REAL_VALUES_EQUAL (d2, dconst0)
01760 && (flag_trapping_math || ! MODE_HAS_INFINITIES (mode)))
01761 return NULL_TREE;
01762
01763
01764
01765 if (REAL_VALUE_ISNAN (d1))
01766 return arg1;
01767 else if (REAL_VALUE_ISNAN (d2))
01768 return arg2;
01769
01770 inexact = real_arithmetic (&value, code, &d1, &d2);
01771 real_convert (&result, mode, &value);
01772
01773
01774
01775 if (flag_trapping_math
01776 && MODE_HAS_INFINITIES (mode)
01777 && REAL_VALUE_ISINF (result)
01778 && !REAL_VALUE_ISINF (d1)
01779 && !REAL_VALUE_ISINF (d2))
01780 return NULL_TREE;
01781
01782
01783
01784
01785
01786 if ((flag_rounding_math
01787 || (REAL_MODE_FORMAT_COMPOSITE_P (mode)
01788 && !flag_unsafe_math_optimizations))
01789 && (inexact || !real_identical (&result, &value)))
01790 return NULL_TREE;
01791
01792 t = build_real (type, result);
01793
01794 TREE_OVERFLOW (t) = TREE_OVERFLOW (arg1) | TREE_OVERFLOW (arg2);
01795 TREE_CONSTANT_OVERFLOW (t)
01796 = TREE_OVERFLOW (t)
01797 | TREE_CONSTANT_OVERFLOW (arg1)
01798 | TREE_CONSTANT_OVERFLOW (arg2);
01799 return t;
01800 }
01801
01802 if (TREE_CODE (arg1) == COMPLEX_CST)
01803 {
01804 tree type = TREE_TYPE (arg1);
01805 tree r1 = TREE_REALPART (arg1);
01806 tree i1 = TREE_IMAGPART (arg1);
01807 tree r2 = TREE_REALPART (arg2);
01808 tree i2 = TREE_IMAGPART (arg2);
01809 tree real, imag;
01810
01811 switch (code)
01812 {
01813 case PLUS_EXPR:
01814 case MINUS_EXPR:
01815 real = const_binop (code, r1, r2, notrunc);
01816 imag = const_binop (code, i1, i2, notrunc);
01817 break;
01818
01819 case MULT_EXPR:
01820 real = const_binop (MINUS_EXPR,
01821 const_binop (MULT_EXPR, r1, r2, notrunc),
01822 const_binop (MULT_EXPR, i1, i2, notrunc),
01823 notrunc);
01824 imag = const_binop (PLUS_EXPR,
01825 const_binop (MULT_EXPR, r1, i2, notrunc),
01826 const_binop (MULT_EXPR, i1, r2, notrunc),
01827 notrunc);
01828 break;
01829
01830 case RDIV_EXPR:
01831 {
01832 tree magsquared
01833 = const_binop (PLUS_EXPR,
01834 const_binop (MULT_EXPR, r2, r2, notrunc),
01835 const_binop (MULT_EXPR, i2, i2, notrunc),
01836 notrunc);
01837 tree t1
01838 = const_binop (PLUS_EXPR,
01839 const_binop (MULT_EXPR, r1, r2, notrunc),
01840 const_binop (MULT_EXPR, i1, i2, notrunc),
01841 notrunc);
01842 tree t2
01843 = const_binop (MINUS_EXPR,
01844 const_binop (MULT_EXPR, i1, r2, notrunc),
01845 const_binop (MULT_EXPR, r1, i2, notrunc),
01846 notrunc);
01847
01848 if (INTEGRAL_TYPE_P (TREE_TYPE (r1)))
01849 code = TRUNC_DIV_EXPR;
01850
01851 real = const_binop (code, t1, magsquared, notrunc);
01852 imag = const_binop (code, t2, magsquared, notrunc);
01853 }
01854 break;
01855
01856 default:
01857 return NULL_TREE;
01858 }
01859
01860 if (real && imag)
01861 return build_complex (type, real, imag);
01862 }
01863
01864 return NULL_TREE;
01865 }
01866
01867
01868
01869
01870 tree
01871 size_int_kind (HOST_WIDE_INT number, enum size_type_kind kind)
01872 {
01873 return build_int_cst (sizetype_tab[(int) kind], number);
01874 }
01875
01876
01877
01878
01879
01880
01881 tree
01882 size_binop (enum tree_code code, tree arg0, tree arg1)
01883 {
01884 tree type = TREE_TYPE (arg0);
01885
01886 if (arg0 == error_mark_node || arg1 == error_mark_node)
01887 return error_mark_node;
01888
01889 gcc_assert (TREE_CODE (type) == INTEGER_TYPE && TYPE_IS_SIZETYPE (type)
01890 && type == TREE_TYPE (arg1));
01891
01892
01893 if (TREE_CODE (arg0) == INTEGER_CST && TREE_CODE (arg1) == INTEGER_CST)
01894 {
01895
01896 if (code == PLUS_EXPR && integer_zerop (arg0))
01897 return arg1;
01898 else if ((code == MINUS_EXPR || code == PLUS_EXPR)
01899 && integer_zerop (arg1))
01900 return arg0;
01901 else if (code == MULT_EXPR && integer_onep (arg0))
01902 return arg1;
01903
01904
01905 return int_const_binop (code, arg0, arg1, 0);
01906 }
01907
01908 return fold_build2 (code, type, arg0, arg1);
01909 }
01910
01911
01912
01913
01914
01915 tree
01916 size_diffop (tree arg0, tree arg1)
01917 {
01918 tree type = TREE_TYPE (arg0);
01919 tree ctype;
01920
01921 gcc_assert (TREE_CODE (type) == INTEGER_TYPE && TYPE_IS_SIZETYPE (type)
01922 && type == TREE_TYPE (arg1));
01923
01924
01925 if (!TYPE_UNSIGNED (type))
01926 return size_binop (MINUS_EXPR, arg0, arg1);
01927
01928 ctype = type == bitsizetype ? sbitsizetype : ssizetype;
01929
01930
01931
01932
01933 if (TREE_CODE (arg0) != INTEGER_CST || TREE_CODE (arg1) != INTEGER_CST)
01934 return size_binop (MINUS_EXPR, fold_convert (ctype, arg0),
01935 fold_convert (ctype, arg1));
01936
01937
01938
01939
01940
01941 if (tree_int_cst_equal (arg0, arg1))
01942 return build_int_cst (ctype, 0);
01943 else if (tree_int_cst_lt (arg1, arg0))
01944 return fold_convert (ctype, size_binop (MINUS_EXPR, arg0, arg1));
01945 else
01946 return size_binop (MINUS_EXPR, build_int_cst (ctype, 0),
01947 fold_convert (ctype, size_binop (MINUS_EXPR,
01948 arg1, arg0)));
01949 }
01950
01951
01952
01953
01954 static tree
01955 fold_convert_const_int_from_int (tree type, tree arg1)
01956 {
01957 tree t;
01958
01959
01960
01961 t = build_int_cst_wide (type, TREE_INT_CST_LOW (arg1),
01962 TREE_INT_CST_HIGH (arg1));
01963
01964 t = force_fit_type (t,
01965
01966
01967 !POINTER_TYPE_P (TREE_TYPE (arg1)),
01968 (TREE_INT_CST_HIGH (arg1) < 0
01969 && (TYPE_UNSIGNED (type)
01970 < TYPE_UNSIGNED (TREE_TYPE (arg1))))
01971 | TREE_OVERFLOW (arg1),
01972 TREE_CONSTANT_OVERFLOW (arg1));
01973
01974 return t;
01975 }
01976
01977
01978
01979
01980 static tree
01981 fold_convert_const_int_from_real (enum tree_code code, tree type, tree arg1)
01982 {
01983 int overflow = 0;
01984 tree t;
01985
01986
01987
01988
01989
01990
01991
01992
01993
01994
01995 HOST_WIDE_INT high, low;
01996 REAL_VALUE_TYPE r;
01997 REAL_VALUE_TYPE x = TREE_REAL_CST (arg1);
01998
01999 switch (code)
02000 {
02001 case FIX_TRUNC_EXPR:
02002 real_trunc (&r, VOIDmode, &x);
02003 break;
02004
02005 case FIX_CEIL_EXPR:
02006 real_ceil (&r, VOIDmode, &x);
02007 break;
02008
02009 case FIX_FLOOR_EXPR:
02010 real_floor (&r, VOIDmode, &x);
02011 break;
02012
02013 case FIX_ROUND_EXPR:
02014 real_round (&r, VOIDmode, &x);
02015 break;
02016
02017 default:
02018 gcc_unreachable ();
02019 }
02020
02021
02022 if (REAL_VALUE_ISNAN (r))
02023 {
02024 overflow = 1;
02025 high = 0;
02026 low = 0;
02027 }
02028
02029
02030
02031
02032 if (! overflow)
02033 {
02034 tree lt = TYPE_MIN_VALUE (type);
02035 REAL_VALUE_TYPE l = real_value_from_int_cst (NULL_TREE, lt);
02036 if (REAL_VALUES_LESS (r, l))
02037 {
02038 overflow = 1;
02039 high = TREE_INT_CST_HIGH (lt);
02040 low = TREE_INT_CST_LOW (lt);
02041 }
02042 }
02043
02044 if (! overflow)
02045 {
02046 tree ut = TYPE_MAX_VALUE (type);
02047 if (ut)
02048 {
02049 REAL_VALUE_TYPE u = real_value_from_int_cst (NULL_TREE, ut);
02050 if (REAL_VALUES_LESS (u, r))
02051 {
02052 overflow = 1;
02053 high = TREE_INT_CST_HIGH (ut);
02054 low = TREE_INT_CST_LOW (ut);
02055 }
02056 }
02057 }
02058
02059 if (! overflow)
02060 REAL_VALUE_TO_INT (&low, &high, r);
02061
02062 t = build_int_cst_wide (type, low, high);
02063
02064 t = force_fit_type (t, -1, overflow | TREE_OVERFLOW (arg1),
02065 TREE_CONSTANT_OVERFLOW (arg1));
02066 return t;
02067 }
02068
02069
02070
02071
02072 static tree
02073 fold_convert_const_real_from_real (tree type, tree arg1)
02074 {
02075 REAL_VALUE_TYPE value;
02076 tree t;
02077
02078 real_convert (&value, TYPE_MODE (type), &TREE_REAL_CST (arg1));
02079 t = build_real (type, value);
02080
02081 TREE_OVERFLOW (t) = TREE_OVERFLOW (arg1);
02082 TREE_CONSTANT_OVERFLOW (t)
02083 = TREE_OVERFLOW (t) | TREE_CONSTANT_OVERFLOW (arg1);
02084 return t;
02085 }
02086
02087
02088
02089
02090 static tree
02091 fold_convert_const (enum tree_code code, tree type, tree arg1)
02092 {
02093 if (TREE_TYPE (arg1) == type)
02094 return arg1;
02095
02096 if (POINTER_TYPE_P (type) || INTEGRAL_TYPE_P (type))
02097 {
02098 if (TREE_CODE (arg1) == INTEGER_CST)
02099 return fold_convert_const_int_from_int (type, arg1);
02100 else if (TREE_CODE (arg1) == REAL_CST)
02101 return fold_convert_const_int_from_real (code, type, arg1);
02102 }
02103 else if (TREE_CODE (type) == REAL_TYPE)
02104 {
02105 if (TREE_CODE (arg1) == INTEGER_CST)
02106 return build_real_from_int_cst (type, arg1);
02107 if (TREE_CODE (arg1) == REAL_CST)
02108 return fold_convert_const_real_from_real (type, arg1);
02109 }
02110 return NULL_TREE;
02111 }
02112
02113
02114
02115 static tree
02116 build_zero_vector (tree type)
02117 {
02118 tree elem, list;
02119 int i, units;
02120
02121 elem = fold_convert_const (NOP_EXPR, TREE_TYPE (type), integer_zero_node);
02122 units = TYPE_VECTOR_SUBPARTS (type);
02123
02124 list = NULL_TREE;
02125 for (i = 0; i < units; i++)
02126 list = tree_cons (NULL_TREE, elem, list);
02127 return build_vector (type, list);
02128 }
02129
02130
02131
02132
02133 tree
02134 fold_convert (tree type, tree arg)
02135 {
02136 tree orig = TREE_TYPE (arg);
02137 tree tem;
02138
02139 if (type == orig)
02140 return arg;
02141
02142 if (TREE_CODE (arg) == ERROR_MARK
02143 || TREE_CODE (type) == ERROR_MARK
02144 || TREE_CODE (orig) == ERROR_MARK)
02145 return error_mark_node;
02146
02147 if (TYPE_MAIN_VARIANT (type) == TYPE_MAIN_VARIANT (orig)
02148 || lang_hooks.types_compatible_p (TYPE_MAIN_VARIANT (type),
02149 TYPE_MAIN_VARIANT (orig)))
02150 return fold_build1 (NOP_EXPR, type, arg);
02151
02152 switch (TREE_CODE (type))
02153 {
02154 case INTEGER_TYPE: case ENUMERAL_TYPE: case BOOLEAN_TYPE:
02155 case POINTER_TYPE: case REFERENCE_TYPE:
02156 case OFFSET_TYPE:
02157 if (TREE_CODE (arg) == INTEGER_CST)
02158 {
02159 tem = fold_convert_const (NOP_EXPR, type, arg);
02160 if (tem != NULL_TREE)
02161 return tem;
02162 }
02163 if (INTEGRAL_TYPE_P (orig) || POINTER_TYPE_P (orig)
02164 || TREE_CODE (orig) == OFFSET_TYPE)
02165 return fold_build1 (NOP_EXPR, type, arg);
02166 if (TREE_CODE (orig) == COMPLEX_TYPE)
02167 {
02168 tem = fold_build1 (REALPART_EXPR, TREE_TYPE (orig), arg);
02169 return fold_convert (type, tem);
02170 }
02171 gcc_assert (TREE_CODE (orig) == VECTOR_TYPE
02172 && tree_int_cst_equal (TYPE_SIZE (type), TYPE_SIZE (orig)));
02173 return fold_build1 (NOP_EXPR, type, arg);
02174
02175 case REAL_TYPE:
02176 if (TREE_CODE (arg) == INTEGER_CST)
02177 {
02178 tem = fold_convert_const (FLOAT_EXPR, type, arg);
02179 if (tem != NULL_TREE)
02180 return tem;
02181 }
02182 else if (TREE_CODE (arg) == REAL_CST)
02183 {
02184 tem = fold_convert_const (NOP_EXPR, type, arg);
02185 if (tem != NULL_TREE)
02186 return tem;
02187 }
02188
02189 switch (TREE_CODE (orig))
02190 {
02191 case INTEGER_TYPE:
02192 case BOOLEAN_TYPE: case ENUMERAL_TYPE:
02193 case POINTER_TYPE: case REFERENCE_TYPE:
02194 return fold_build1 (FLOAT_EXPR, type, arg);
02195
02196 case REAL_TYPE:
02197 return fold_build1 (NOP_EXPR, type, arg);
02198
02199 case COMPLEX_TYPE:
02200 tem = fold_build1 (REALPART_EXPR, TREE_TYPE (orig), arg);
02201 return fold_convert (type, tem);
02202
02203 default:
02204 gcc_unreachable ();
02205 }
02206
02207 case COMPLEX_TYPE:
02208 switch (TREE_CODE (orig))
02209 {
02210 case INTEGER_TYPE:
02211 case BOOLEAN_TYPE: case ENUMERAL_TYPE:
02212 case POINTER_TYPE: case REFERENCE_TYPE:
02213 case REAL_TYPE:
02214 return build2 (COMPLEX_EXPR, type,
02215 fold_convert (TREE_TYPE (type), arg),
02216 fold_convert (TREE_TYPE (type), integer_zero_node));
02217 case COMPLEX_TYPE:
02218 {
02219 tree rpart, ipart;
02220
02221 if (TREE_CODE (arg) == COMPLEX_EXPR)
02222 {
02223 rpart = fold_convert (TREE_TYPE (type), TREE_OPERAND (arg, 0));
02224 ipart = fold_convert (TREE_TYPE (type), TREE_OPERAND (arg, 1));
02225 return fold_build2 (COMPLEX_EXPR, type, rpart, ipart);
02226 }
02227
02228 arg = save_expr (arg);
02229 rpart = fold_build1 (REALPART_EXPR, TREE_TYPE (orig), arg);
02230 ipart = fold_build1 (IMAGPART_EXPR, TREE_TYPE (orig), arg);
02231 rpart = fold_convert (TREE_TYPE (type), rpart);
02232 ipart = fold_convert (TREE_TYPE (type), ipart);
02233 return fold_build2 (COMPLEX_EXPR, type, rpart, ipart);
02234 }
02235
02236 default:
02237 gcc_unreachable ();
02238 }
02239
02240 case VECTOR_TYPE:
02241 if (integer_zerop (arg))
02242 return build_zero_vector (type);
02243 gcc_assert (tree_int_cst_equal (TYPE_SIZE (type), TYPE_SIZE (orig)));
02244 gcc_assert (INTEGRAL_TYPE_P (orig) || POINTER_TYPE_P (orig)
02245 || TREE_CODE (orig) == VECTOR_TYPE);
02246 return fold_build1 (VIEW_CONVERT_EXPR, type, arg);
02247
02248 case VOID_TYPE:
02249 return fold_build1 (NOP_EXPR, type, fold_ignored_result (arg));
02250
02251 default:
02252 gcc_unreachable ();
02253 }
02254 }
02255
02256
02257
02258
02259 static bool
02260 maybe_lvalue_p (tree x)
02261 {
02262
02263 switch (TREE_CODE (x))
02264 {
02265 case VAR_DECL:
02266 case PARM_DECL:
02267 case RESULT_DECL:
02268 case LABEL_DECL:
02269 case FUNCTION_DECL:
02270 case SSA_NAME:
02271
02272 case COMPONENT_REF:
02273 case INDIRECT_REF:
02274 case ALIGN_INDIRECT_REF:
02275 case MISALIGNED_INDIRECT_REF:
02276 case ARRAY_REF:
02277 case ARRAY_RANGE_REF:
02278 case BIT_FIELD_REF:
02279 case OBJ_TYPE_REF:
02280
02281 case REALPART_EXPR:
02282 case IMAGPART_EXPR:
02283 case PREINCREMENT_EXPR:
02284 case PREDECREMENT_EXPR:
02285 case SAVE_EXPR:
02286 case TRY_CATCH_EXPR:
02287 case WITH_CLEANUP_EXPR:
02288 case COMPOUND_EXPR:
02289 case MODIFY_EXPR:
02290 case TARGET_EXPR:
02291 case COND_EXPR:
02292 case BIND_EXPR:
02293 case MIN_EXPR:
02294 case MAX_EXPR:
02295 break;
02296
02297 default:
02298
02299 if ((int)TREE_CODE (x) >= NUM_TREE_CODES)
02300 break;
02301 return false;
02302 }
02303
02304 return true;
02305 }
02306
02307
02308
02309 tree
02310 non_lvalue (tree x)
02311 {
02312
02313
02314 if (in_gimple_form)
02315 return x;
02316
02317 if (! maybe_lvalue_p (x))
02318 return x;
02319 return build1 (NON_LVALUE_EXPR, TREE_TYPE (x), x);
02320 }
02321
02322
02323
02324
02325 int pedantic_lvalues;
02326
02327
02328
02329
02330 static tree
02331 pedantic_non_lvalue (tree x)
02332 {
02333 if (pedantic_lvalues)
02334 return non_lvalue (x);
02335 else
02336 return x;
02337 }
02338
02339
02340
02341
02342
02343
02344 enum tree_code
02345 invert_tree_comparison (enum tree_code code, bool honor_nans)
02346 {
02347 if (honor_nans && flag_trapping_math)
02348 return ERROR_MARK;
02349
02350 switch (code)
02351 {
02352 case EQ_EXPR:
02353 return NE_EXPR;
02354 case NE_EXPR:
02355 return EQ_EXPR;
02356 case GT_EXPR:
02357 return honor_nans ? UNLE_EXPR : LE_EXPR;
02358 case GE_EXPR:
02359 return honor_nans ? UNLT_EXPR : LT_EXPR;
02360 case LT_EXPR:
02361 return honor_nans ? UNGE_EXPR : GE_EXPR;
02362 case LE_EXPR:
02363 return honor_nans ? UNGT_EXPR : GT_EXPR;
02364 case LTGT_EXPR:
02365 return UNEQ_EXPR;
02366 case UNEQ_EXPR:
02367 return LTGT_EXPR;
02368 case UNGT_EXPR:
02369 return LE_EXPR;
02370 case UNGE_EXPR:
02371 return LT_EXPR;
02372 case UNLT_EXPR:
02373 return GE_EXPR;
02374 case UNLE_EXPR:
02375 return GT_EXPR;
02376 case ORDERED_EXPR:
02377 return UNORDERED_EXPR;
02378 case UNORDERED_EXPR:
02379 return ORDERED_EXPR;
02380 default:
02381 gcc_unreachable ();
02382 }
02383 }
02384
02385
02386
02387
02388 enum tree_code
02389 swap_tree_comparison (enum tree_code code)
02390 {
02391 switch (code)
02392 {
02393 case EQ_EXPR:
02394 case NE_EXPR:
02395 case ORDERED_EXPR:
02396 case UNORDERED_EXPR:
02397 case LTGT_EXPR:
02398 case UNEQ_EXPR:
02399 return code;
02400 case GT_EXPR:
02401 return LT_EXPR;
02402 case GE_EXPR:
02403 return LE_EXPR;
02404 case LT_EXPR:
02405 return GT_EXPR;
02406 case LE_EXPR:
02407 return GE_EXPR;
02408 case UNGT_EXPR:
02409 return UNLT_EXPR;
02410 case UNGE_EXPR:
02411 return UNLE_EXPR;
02412 case UNLT_EXPR:
02413 return UNGT_EXPR;
02414 case UNLE_EXPR:
02415 return UNGE_EXPR;
02416 default:
02417 gcc_unreachable ();
02418 }
02419 }
02420
02421
02422
02423
02424
02425
02426 static enum comparison_code
02427 comparison_to_compcode (enum tree_code code)
02428 {
02429 switch (code)
02430 {
02431 case LT_EXPR:
02432 return COMPCODE_LT;
02433 case EQ_EXPR:
02434 return COMPCODE_EQ;
02435 case LE_EXPR:
02436 return COMPCODE_LE;
02437 case GT_EXPR:
02438 return COMPCODE_GT;
02439 case NE_EXPR:
02440 return COMPCODE_NE;
02441 case GE_EXPR:
02442 return COMPCODE_GE;
02443 case ORDERED_EXPR:
02444 return COMPCODE_ORD;
02445 case UNORDERED_EXPR:
02446 return COMPCODE_UNORD;
02447 case UNLT_EXPR:
02448 return COMPCODE_UNLT;
02449 case UNEQ_EXPR:
02450 return COMPCODE_UNEQ;
02451 case UNLE_EXPR:
02452 return COMPCODE_UNLE;
02453 case UNGT_EXPR:
02454 return COMPCODE_UNGT;
02455 case LTGT_EXPR:
02456 return COMPCODE_LTGT;
02457 case UNGE_EXPR:
02458 return COMPCODE_UNGE;
02459 default:
02460 gcc_unreachable ();
02461 }
02462 }
02463
02464
02465
02466
02467
02468 static enum tree_code
02469 compcode_to_comparison (enum comparison_code code)
02470 {
02471 switch (code)
02472 {
02473 case COMPCODE_LT:
02474 return LT_EXPR;
02475 case COMPCODE_EQ:
02476 return EQ_EXPR;
02477 case COMPCODE_LE:
02478 return LE_EXPR;
02479 case COMPCODE_GT:
02480 return GT_EXPR;
02481 case COMPCODE_NE:
02482 return NE_EXPR;
02483 case COMPCODE_GE:
02484 return GE_EXPR;
02485 case COMPCODE_ORD:
02486 return ORDERED_EXPR;
02487 case COMPCODE_UNORD:
02488 return UNORDERED_EXPR;
02489 case COMPCODE_UNLT:
02490 return UNLT_EXPR;
02491 case COMPCODE_UNEQ:
02492 return UNEQ_EXPR;
02493 case COMPCODE_UNLE:
02494 return UNLE_EXPR;
02495 case COMPCODE_UNGT:
02496 return UNGT_EXPR;
02497 case COMPCODE_LTGT:
02498 return LTGT_EXPR;
02499 case COMPCODE_UNGE:
02500 return UNGE_EXPR;
02501 default:
02502 gcc_unreachable ();
02503 }
02504 }
02505
02506
02507
02508
02509
02510
02511
02512 tree
02513 combine_comparisons (enum tree_code code, enum tree_code lcode,
02514 enum tree_code rcode, tree truth_type,
02515 tree ll_arg, tree lr_arg)
02516 {
02517 bool honor_nans = HONOR_NANS (TYPE_MODE (TREE_TYPE (ll_arg)));
02518 enum comparison_code lcompcode = comparison_to_compcode (lcode);
02519 enum comparison_code rcompcode = comparison_to_compcode (rcode);
02520 enum comparison_code compcode;
02521
02522 switch (code)
02523 {
02524 case TRUTH_AND_EXPR: case TRUTH_ANDIF_EXPR:
02525 compcode = lcompcode & rcompcode;
02526 break;
02527
02528 case TRUTH_OR_EXPR: case TRUTH_ORIF_EXPR:
02529 compcode = lcompcode | rcompcode;
02530 break;
02531
02532 default:
02533 return NULL_TREE;
02534 }
02535
02536 if (!honor_nans)
02537 {
02538
02539
02540 compcode &= ~COMPCODE_UNORD;
02541 if (compcode == COMPCODE_LTGT)
02542 compcode = COMPCODE_NE;
02543 else if (compcode == COMPCODE_ORD)
02544 compcode = COMPCODE_TRUE;
02545 }
02546 else if (flag_trapping_math)
02547 {
02548
02549
02550 bool ltrap = (lcompcode & COMPCODE_UNORD) == 0
02551 && (lcompcode != COMPCODE_EQ)
02552 && (lcompcode != COMPCODE_ORD);
02553 bool rtrap = (rcompcode & COMPCODE_UNORD) == 0
02554 && (rcompcode != COMPCODE_EQ)
02555 && (rcompcode != COMPCODE_ORD);
02556 bool trap = (compcode & COMPCODE_UNORD) == 0
02557 && (compcode != COMPCODE_EQ)
02558 && (compcode != COMPCODE_ORD);
02559
02560
02561
02562
02563
02564
02565
02566 if ((code == TRUTH_ORIF_EXPR && (lcompcode & COMPCODE_UNORD))
02567 || (code == TRUTH_ANDIF_EXPR && !(lcompcode & COMPCODE_UNORD)))
02568 rtrap = false;
02569
02570
02571
02572 if (rtrap && !ltrap
02573 && (code == TRUTH_ANDIF_EXPR || code == TRUTH_ORIF_EXPR))
02574 return NULL_TREE;
02575
02576
02577 if ((ltrap || rtrap) != trap)
02578 return NULL_TREE;
02579 }
02580
02581 if (compcode == COMPCODE_TRUE)
02582 return constant_boolean_node (true, truth_type);
02583 else if (compcode == COMPCODE_FALSE)
02584 return constant_boolean_node (false, truth_type);
02585 else
02586 return fold_build2 (compcode_to_comparison (compcode),
02587 truth_type, ll_arg, lr_arg);
02588 }
02589
02590
02591
02592 static int
02593 truth_value_p (enum tree_code code)
02594 {
02595 return (TREE_CODE_CLASS (code) == tcc_comparison
02596 || code == TRUTH_AND_EXPR || code == TRUTH_ANDIF_EXPR
02597 || code == TRUTH_OR_EXPR || code == TRUTH_ORIF_EXPR
02598 || code == TRUTH_XOR_EXPR || code == TRUTH_NOT_EXPR);
02599 }
02600
02601
02602
02603
02604
02605
02606
02607
02608
02609
02610
02611
02612
02613
02614
02615
02616
02617
02618
02619
02620
02621
02622
02623
02624
02625
02626
02627 int
02628 operand_equal_p (tree arg0, tree arg1, unsigned int flags)
02629 {
02630
02631 if (TREE_CODE (arg0) == ERROR_MARK || TREE_CODE (arg1) == ERROR_MARK)
02632 return 0;
02633
02634
02635
02636
02637 if (TYPE_UNSIGNED (TREE_TYPE (arg0)) != TYPE_UNSIGNED (TREE_TYPE (arg1)))
02638 return 0;
02639
02640
02641
02642 if (TYPE_PRECISION (TREE_TYPE (arg0)) != TYPE_PRECISION (TREE_TYPE (arg1)))
02643 return 0;
02644
02645 STRIP_NOPS (arg0);
02646 STRIP_NOPS (arg1);
02647
02648
02649
02650
02651 if (TREE_CODE (arg0) != TREE_CODE (arg1)
02652 && COMPARISON_CLASS_P (arg0)
02653 && COMPARISON_CLASS_P (arg1))
02654 {
02655 enum tree_code swap_code = swap_tree_comparison (TREE_CODE (arg1));
02656
02657 if (TREE_CODE (arg0) == swap_code)
02658 return operand_equal_p (TREE_OPERAND (arg0, 0),
02659 TREE_OPERAND (arg1, 1), flags)
02660 && operand_equal_p (TREE_OPERAND (arg0, 1),
02661 TREE_OPERAND (arg1, 0), flags);
02662 }
02663
02664 if (TREE_CODE (arg0) != TREE_CODE (arg1)
02665
02666
02667 || TREE_CODE (TREE_TYPE (arg0)) == ERROR_MARK
02668 || TREE_CODE (TREE_TYPE (arg1)) == ERROR_MARK
02669 || TYPE_MODE (TREE_TYPE (arg0)) != TYPE_MODE (TREE_TYPE (arg1)))
02670 return 0;
02671
02672
02673
02674
02675
02676
02677
02678
02679 if (arg0 == arg1 && ! (flags & OEP_ONLY_CONST)
02680 && (TREE_CODE (arg0) == SAVE_EXPR
02681 || (! TREE_SIDE_EFFECTS (arg0) && ! TREE_SIDE_EFFECTS (arg1))))
02682 return 1;
02683
02684
02685
02686 if (TREE_CONSTANT (arg0) && TREE_CONSTANT (arg1))
02687 switch (TREE_CODE (arg0))
02688 {
02689 case INTEGER_CST:
02690 return (! TREE_CONSTANT_OVERFLOW (arg0)
02691 && ! TREE_CONSTANT_OVERFLOW (arg1)
02692 && tree_int_cst_equal (arg0, arg1));
02693
02694 case REAL_CST:
02695 return (! TREE_CONSTANT_OVERFLOW (arg0)
02696 && ! TREE_CONSTANT_OVERFLOW (arg1)
02697 && REAL_VALUES_IDENTICAL (TREE_REAL_CST (arg0),
02698 TREE_REAL_CST (arg1)));
02699
02700 case VECTOR_CST:
02701 {
02702 tree v1, v2;
02703
02704 if (TREE_CONSTANT_OVERFLOW (arg0)
02705 || TREE_CONSTANT_OVERFLOW (arg1))
02706 return 0;
02707
02708 v1 = TREE_VECTOR_CST_ELTS (arg0);
02709 v2 = TREE_VECTOR_CST_ELTS (arg1);
02710 while (v1 && v2)
02711 {
02712 if (!operand_equal_p (TREE_VALUE (v1), TREE_VALUE (v2),
02713 flags))
02714 return 0;
02715 v1 = TREE_CHAIN (v1);
02716 v2 = TREE_CHAIN (v2);
02717 }
02718
02719 return v1 == v2;
02720 }
02721
02722 case COMPLEX_CST:
02723 return (operand_equal_p (TREE_REALPART (arg0), TREE_REALPART (arg1),
02724 flags)
02725 && operand_equal_p (TREE_IMAGPART (arg0), TREE_IMAGPART (arg1),
02726 flags));
02727
02728 case STRING_CST:
02729 return (TREE_STRING_LENGTH (arg0) == TREE_STRING_LENGTH (arg1)
02730 && ! memcmp (TREE_STRING_POINTER (arg0),
02731 TREE_STRING_POINTER (arg1),
02732 TREE_STRING_LENGTH (arg0)));
02733
02734 case ADDR_EXPR:
02735 return operand_equal_p (TREE_OPERAND (arg0, 0), TREE_OPERAND (arg1, 0),
02736 0);
02737 default:
02738 break;
02739 }
02740
02741 if (flags & OEP_ONLY_CONST)
02742 return 0;
02743
02744
02745
02746
02747
02748 #define OP_SAME(N) operand_equal_p (TREE_OPERAND (arg0, N), \
02749 TREE_OPERAND (arg1, N), flags)
02750
02751 #define OP_SAME_WITH_NULL(N) \
02752 ((!TREE_OPERAND (arg0, N) || !TREE_OPERAND (arg1, N)) \
02753 ? TREE_OPERAND (arg0, N) == TREE_OPERAND (arg1, N) : OP_SAME (N))
02754
02755 switch (TREE_CODE_CLASS (TREE_CODE (arg0)))
02756 {
02757 case tcc_unary:
02758
02759 switch (TREE_CODE (arg0))
02760 {
02761 case NOP_EXPR:
02762 case CONVERT_EXPR:
02763 case FIX_CEIL_EXPR:
02764 case FIX_TRUNC_EXPR:
02765 case FIX_FLOOR_EXPR:
02766 case FIX_ROUND_EXPR:
02767 if (TYPE_UNSIGNED (TREE_TYPE (arg0))
02768 != TYPE_UNSIGNED (TREE_TYPE (arg1)))
02769 return 0;
02770 break;
02771 default:
02772 break;
02773 }
02774
02775 return OP_SAME (0);
02776
02777
02778 case tcc_comparison:
02779 case tcc_binary:
02780 if (OP_SAME (0) && OP_SAME (1))
02781 return 1;
02782
02783
02784 return (commutative_tree_code (TREE_CODE (arg0))
02785 && operand_equal_p (TREE_OPERAND (arg0, 0),
02786 TREE_OPERAND (arg1, 1), flags)
02787 && operand_equal_p (TREE_OPERAND (arg0, 1),
02788 TREE_OPERAND (arg1, 0), flags));
02789
02790 case tcc_reference:
02791
02792
02793 if (TREE_SIDE_EFFECTS (arg0)
02794 || TREE_SIDE_EFFECTS (arg1))
02795 return 0;
02796
02797 switch (TREE_CODE (arg0))
02798 {
02799 case INDIRECT_REF:
02800 case ALIGN_INDIRECT_REF:
02801 case MISALIGNED_INDIRECT_REF:
02802 case REALPART_EXPR:
02803 case IMAGPART_EXPR:
02804 return OP_SAME (0);
02805
02806 case ARRAY_REF:
02807 case ARRAY_RANGE_REF:
02808
02809 return (OP_SAME (0)
02810 && OP_SAME (1)
02811 && OP_SAME_WITH_NULL (2)
02812 && OP_SAME_WITH_NULL (3));
02813
02814 case COMPONENT_REF:
02815
02816
02817 return OP_SAME_WITH_NULL (0)
02818 && OP_SAME (1)
02819 && OP_SAME_WITH_NULL (2);
02820
02821 case BIT_FIELD_REF:
02822 return OP_SAME (0) && OP_SAME (1) && OP_SAME (2);
02823
02824 default:
02825 return 0;
02826 }
02827
02828 case tcc_expression:
02829 switch (TREE_CODE (arg0))
02830 {
02831 case ADDR_EXPR:
02832 case TRUTH_NOT_EXPR:
02833 return OP_SAME (0);
02834
02835 case TRUTH_ANDIF_EXPR:
02836 case TRUTH_ORIF_EXPR:
02837 return OP_SAME (0) && OP_SAME (1);
02838
02839 case TRUTH_AND_EXPR:
02840 case TRUTH_OR_EXPR:
02841 case TRUTH_XOR_EXPR:
02842 if (OP_SAME (0) && OP_SAME (1))
02843 return 1;
02844
02845
02846 return (operand_equal_p (TREE_OPERAND (arg0, 0),
02847 TREE_OPERAND (arg1, 1), flags)
02848 && operand_equal_p (TREE_OPERAND (arg0, 1),
02849 TREE_OPERAND (arg1, 0), flags));
02850
02851 case CALL_EXPR:
02852
02853
02854 if (!OP_SAME (0))
02855 return 0;
02856
02857 {
02858 unsigned int cef = call_expr_flags (arg0);
02859 if (flags & OEP_PURE_SAME)
02860 cef &= ECF_CONST | ECF_PURE;
02861 else
02862 cef &= ECF_CONST;
02863 if (!cef)
02864 return 0;
02865 }
02866
02867
02868
02869
02870 arg0 = TREE_OPERAND (arg0, 1);
02871 arg1 = TREE_OPERAND (arg1, 1);
02872 while (arg0 && arg1)
02873 {
02874 if (! operand_equal_p (TREE_VALUE (arg0), TREE_VALUE (arg1),
02875 flags))
02876 return 0;
02877
02878 arg0 = TREE_CHAIN (arg0);
02879 arg1 = TREE_CHAIN (arg1);
02880 }
02881
02882
02883
02884 return ! (arg0 || arg1);
02885
02886 default:
02887 return 0;
02888 }
02889
02890 case tcc_declaration:
02891
02892 return (TREE_CODE (arg0) == FUNCTION_DECL
02893 && DECL_BUILT_IN (arg0) && DECL_BUILT_IN (arg1)
02894 && DECL_BUILT_IN_CLASS (arg0) == DECL_BUILT_IN_CLASS (arg1)
02895 && DECL_FUNCTION_CODE (arg0) == DECL_FUNCTION_CODE (arg1));
02896
02897 default:
02898 return 0;
02899 }
02900
02901 #undef OP_SAME
02902 #undef OP_SAME_WITH_NULL
02903 }
02904
02905
02906
02907
02908
02909
02910 static int
02911 operand_equal_for_comparison_p (tree arg0, tree arg1, tree other)
02912 {
02913 int unsignedp1, unsignedpo;
02914 tree primarg0, primarg1, primother;
02915 unsigned int correct_width;
02916
02917 if (operand_equal_p (arg0, arg1, 0))
02918 return 1;
02919
02920 if (! INTEGRAL_TYPE_P (TREE_TYPE (arg0))
02921 || ! INTEGRAL_TYPE_P (TREE_TYPE (arg1)))
02922 return 0;
02923
02924
02925
02926
02927 primarg0 = arg0, primarg1 = arg1;
02928 STRIP_NOPS (primarg0);
02929 STRIP_NOPS (primarg1);
02930 if (operand_equal_p (primarg0, primarg1, 0))
02931 return 1;
02932
02933
02934
02935
02936
02937
02938
02939 primarg1 = get_narrower (arg1, &unsignedp1);
02940 primother = get_narrower (other, &unsignedpo);
02941
02942 correct_width = TYPE_PRECISION (TREE_TYPE (arg1));
02943 if (unsignedp1 == unsignedpo
02944 && TYPE_PRECISION (TREE_TYPE (primarg1)) < correct_width
02945 && TYPE_PRECISION (TREE_TYPE (primother)) < correct_width)
02946 {
02947 tree type = TREE_TYPE (arg0);
02948
02949
02950
02951 primarg1 = fold_convert (lang_hooks.types.signed_or_unsigned_type
02952 (unsignedp1, TREE_TYPE (primarg1)), primarg1);
02953
02954 if (operand_equal_p (arg0, fold_convert (type, primarg1), 0))
02955 return 1;
02956 }
02957
02958 return 0;
02959 }
02960
02961
02962
02963
02964
02965
02966
02967
02968
02969
02970
02971 static int
02972 twoval_comparison_p (tree arg, tree *cval1, tree *cval2, int *save_p)
02973 {
02974 enum tree_code code = TREE_CODE (arg);
02975 enum tree_code_class class = TREE_CODE_CLASS (code);
02976
02977
02978 if (class == tcc_expression && code == TRUTH_NOT_EXPR)
02979 class = tcc_unary;
02980 else if (class == tcc_expression
02981 && (code == TRUTH_ANDIF_EXPR || code == TRUTH_ORIF_EXPR
02982 || code == COMPOUND_EXPR))
02983 class = tcc_binary;
02984
02985 else if (class == tcc_expression && code == SAVE_EXPR
02986 && ! TREE_SIDE_EFFECTS (TREE_OPERAND (arg, 0)))
02987 {
02988
02989
02990 if (*cval1 || *cval2)
02991 return 0;
02992
02993 class = tcc_unary;
02994 *save_p = 1;
02995 }
02996
02997 switch (class)
02998 {
02999 case tcc_unary:
03000 return twoval_comparison_p (TREE_OPERAND (arg, 0), cval1, cval2, save_p);
03001
03002 case tcc_binary:
03003 return (twoval_comparison_p (TREE_OPERAND (arg, 0), cval1, cval2, save_p)
03004 && twoval_comparison_p (TREE_OPERAND (arg, 1),
03005 cval1, cval2, save_p));
03006
03007 case tcc_constant:
03008 return 1;
03009
03010 case tcc_expression:
03011 if (code == COND_EXPR)
03012 return (twoval_comparison_p (TREE_OPERAND (arg, 0),
03013 cval1, cval2, save_p)
03014 && twoval_comparison_p (TREE_OPERAND (arg, 1),
03015 cval1, cval2, save_p)
03016 && twoval_comparison_p (TREE_OPERAND (arg, 2),
03017 cval1, cval2, save_p));
03018 return 0;
03019
03020 case tcc_comparison:
03021
03022
03023
03024
03025
03026
03027 if (operand_equal_p (TREE_OPERAND (arg, 0),
03028 TREE_OPERAND (arg, 1), 0))
03029 return 0;
03030
03031 if (*cval1 == 0)
03032 *cval1 = TREE_OPERAND (arg, 0);
03033 else if (operand_equal_p (*cval1, TREE_OPERAND (arg, 0), 0))
03034 ;
03035 else if (*cval2 == 0)
03036 *cval2 = TREE_OPERAND (arg, 0);
03037 else if (operand_equal_p (*cval2, TREE_OPERAND (arg, 0), 0))
03038 ;
03039 else
03040 return 0;
03041
03042 if (operand_equal_p (*cval1, TREE_OPERAND (arg, 1), 0))
03043 ;
03044 else if (*cval2 == 0)
03045 *cval2 = TREE_OPERAND (arg, 1);
03046 else if (operand_equal_p (*cval2, TREE_OPERAND (arg, 1), 0))
03047 ;
03048 else
03049 return 0;
03050
03051 return 1;
03052
03053 default:
03054 return 0;
03055 }
03056 }
03057
03058
03059
03060
03061
03062
03063 static tree
03064 eval_subst (tree arg, tree old0, tree new0, tree old1, tree new1)
03065 {
03066 tree type = TREE_TYPE (arg);
03067 enum tree_code code = TREE_CODE (arg);
03068 enum tree_code_class class = TREE_CODE_CLASS (code);
03069
03070
03071 if (class == tcc_expression && code == TRUTH_NOT_EXPR)
03072 class = tcc_unary;
03073 else if (class == tcc_expression
03074 && (code == TRUTH_ANDIF_EXPR || code == TRUTH_ORIF_EXPR))
03075 class = tcc_binary;
03076
03077 switch (class)
03078 {
03079 case tcc_unary:
03080 return fold_build1 (code, type,
03081 eval_subst (TREE_OPERAND (arg, 0),
03082 old0, new0, old1, new1));
03083
03084 case tcc_binary:
03085 return fold_build2 (code, type,
03086 eval_subst (TREE_OPERAND (arg, 0),
03087 old0, new0, old1, new1),
03088 eval_subst (TREE_OPERAND (arg, 1),
03089 old0, new0, old1, new1));
03090
03091 case tcc_expression:
03092 switch (code)
03093 {
03094 case SAVE_EXPR:
03095 return eval_subst (TREE_OPERAND (arg, 0), old0, new0, old1, new1);
03096
03097 case COMPOUND_EXPR:
03098 return eval_subst (TREE_OPERAND (arg, 1), old0, new0, old1, new1);
03099
03100 case COND_EXPR:
03101 return fold_build3 (code, type,
03102 eval_subst (TREE_OPERAND (arg, 0),
03103 old0, new0, old1, new1),
03104 eval_subst (TREE_OPERAND (arg, 1),
03105 old0, new0, old1, new1),
03106 eval_subst (TREE_OPERAND (arg, 2),
03107 old0, new0, old1, new1));
03108 default:
03109 break;
03110 }
03111
03112
03113 case tcc_comparison:
03114 {
03115 tree arg0 = TREE_OPERAND (arg, 0);
03116 tree arg1 = TREE_OPERAND (arg, 1);
03117
03118
03119
03120
03121
03122 if (arg0 == old0 || operand_equal_p (arg0, old0, 0))
03123 arg0 = new0;
03124 else if (arg0 == old1 || operand_equal_p (arg0, old1, 0))
03125 arg0 = new1;
03126
03127 if (arg1 == old0 || operand_equal_p (arg1, old0, 0))
03128 arg1 = new0;
03129 else if (arg1 == old1 || operand_equal_p (arg1, old1, 0))
03130 arg1 = new1;
03131
03132 return fold_build2 (code, type, arg0, arg1);
03133 }
03134
03135 default:
03136 return arg;
03137 }
03138 }
03139
03140
03141
03142
03143
03144
03145
03146
03147 tree
03148 omit_one_operand (tree type, tree result, tree omitted)
03149 {
03150 tree t = fold_convert (type, result);
03151
03152 if (TREE_SIDE_EFFECTS (omitted))
03153 return build2 (COMPOUND_EXPR, type, fold_ignored_result (omitted), t);
03154
03155 return non_lvalue (t);
03156 }
03157
03158
03159
03160 static tree
03161 pedantic_omit_one_operand (tree type, tree result, tree omitted)
03162 {
03163 tree t = fold_convert (type, result);
03164
03165 if (TREE_SIDE_EFFECTS (omitted))
03166 return build2 (COMPOUND_EXPR, type, fold_ignored_result (omitted), t);
03167
03168 return pedantic_non_lvalue (t);
03169 }
03170
03171
03172
03173
03174
03175
03176
03177
03178
03179
03180 tree
03181 omit_two_operands (tree type, tree result, tree omitted1, tree omitted2)
03182 {
03183 tree t = fold_convert (type, result);
03184
03185 if (TREE_SIDE_EFFECTS (omitted2))
03186 t = build2 (COMPOUND_EXPR, type, omitted2, t);
03187 if (TREE_SIDE_EFFECTS (omitted1))
03188 t = build2 (COMPOUND_EXPR, type, omitted1, t);
03189
03190 return TREE_CODE (t) != COMPOUND_EXPR ? non_lvalue (t) : t;
03191 }
03192
03193
03194
03195
03196
03197
03198
03199
03200
03201 tree
03202 fold_truth_not_expr (tree arg)
03203 {
03204 tree type = TREE_TYPE (arg);
03205 enum tree_code code = TREE_CODE (arg);
03206
03207
03208
03209
03210
03211 if (TREE_CODE_CLASS (code) == tcc_comparison)
03212 {
03213 tree op_type = TREE_TYPE (TREE_OPERAND (arg, 0));
03214 if (FLOAT_TYPE_P (op_type)
03215 && flag_trapping_math
03216 && code != ORDERED_EXPR && code != UNORDERED_EXPR
03217 && code != NE_EXPR && code != EQ_EXPR)
03218 return NULL_TREE;
03219 else
03220 {
03221 code = invert_tree_comparison (code,
03222 HONOR_NANS (TYPE_MODE (op_type)));
03223 if (code == ERROR_MARK)
03224 return NULL_TREE;
03225 else
03226 return build2 (code, type,
03227 TREE_OPERAND (arg, 0), TREE_OPERAND (arg, 1));
03228 }
03229 }
03230
03231 switch (code)
03232 {
03233 case INTEGER_CST:
03234 return constant_boolean_node (integer_zerop (arg), type);
03235
03236 case TRUTH_AND_EXPR:
03237 return build2 (TRUTH_OR_EXPR, type,
03238 invert_truthvalue (TREE_OPERAND (arg, 0)),
03239 invert_truthvalue (TREE_OPERAND (arg, 1)));
03240
03241 case TRUTH_OR_EXPR:
03242 return build2 (TRUTH_AND_EXPR, type,
03243 invert_truthvalue (TREE_OPERAND (arg, 0)),
03244 invert_truthvalue (TREE_OPERAND (arg, 1)));
03245
03246 case TRUTH_XOR_EXPR:
03247
03248
03249
03250
03251
03252 if (TREE_CODE (TREE_OPERAND (arg, 1)) == TRUTH_NOT_EXPR)
03253 return build2 (TRUTH_XOR_EXPR, type, TREE_OPERAND (arg, 0),
03254 TREE_OPERAND (TREE_OPERAND (arg, 1), 0));
03255 else
03256 return build2 (TRUTH_XOR_EXPR, type,
03257 invert_truthvalue (TREE_OPERAND (arg, 0)),
03258 TREE_OPERAND (arg, 1));
03259
03260 case TRUTH_ANDIF_EXPR:
03261 return build2 (TRUTH_ORIF_EXPR, type,
03262 invert_truthvalue (TREE_OPERAND (arg, 0)),
03263 invert_truthvalue (TREE_OPERAND (arg, 1)));
03264
03265 case TRUTH_ORIF_EXPR:
03266 return build2 (TRUTH_ANDIF_EXPR, type,
03267 invert_truthvalue (TREE_OPERAND (arg, 0)),
03268 invert_truthvalue (TREE_OPERAND (arg, 1)));
03269
03270 case TRUTH_NOT_EXPR:
03271 return TREE_OPERAND (arg, 0);
03272
03273 case COND_EXPR:
03274 {
03275 tree arg1 = TREE_OPERAND (arg, 1);
03276 tree arg2 = TREE_OPERAND (arg, 2);
03277
03278
03279
03280 return build3 (COND_EXPR, type, TREE_OPERAND (arg, 0),
03281 VOID_TYPE_P (TREE_TYPE (arg1))
03282 ? arg1 : invert_truthvalue (arg1),
03283 VOID_TYPE_P (TREE_TYPE (arg2))
03284 ? arg2 : invert_truthvalue (arg2));
03285 }
03286
03287 case COMPOUND_EXPR:
03288 return build2 (COMPOUND_EXPR, type, TREE_OPERAND (arg, 0),
03289 invert_truthvalue (TREE_OPERAND (arg, 1)));
03290
03291 case NON_LVALUE_EXPR:
03292 return invert_truthvalue (TREE_OPERAND (arg, 0));
03293
03294 case NOP_EXPR:
03295 if (TREE_CODE (TREE_TYPE (arg)) == BOOLEAN_TYPE)
03296 return build1 (TRUTH_NOT_EXPR, type, arg);
03297
03298 case CONVERT_EXPR:
03299 case FLOAT_EXPR:
03300 return build1 (TREE_CODE (arg), type,
03301 invert_truthvalue (TREE_OPERAND (arg, 0)));
03302
03303 case BIT_AND_EXPR:
03304 if (!integer_onep (TREE_OPERAND (arg, 1)))
03305 break;
03306 return build2 (EQ_EXPR, type, arg,
03307 build_int_cst (type, 0));
03308
03309 case SAVE_EXPR:
03310 return build1 (TRUTH_NOT_EXPR, type, arg);
03311
03312 case CLEANUP_POINT_EXPR:
03313 return build1 (CLEANUP_POINT_EXPR, type,
03314 invert_truthvalue (TREE_OPERAND (arg, 0)));
03315
03316 default:
03317 break;
03318 }
03319
03320 return NULL_TREE;
03321 }
03322
03323
03324
03325
03326
03327
03328
03329
03330 tree
03331 invert_truthvalue (tree arg)
03332 {
03333 tree tem;
03334
03335 if (TREE_CODE (arg) == ERROR_MARK)
03336 return arg;
03337
03338 tem = fold_truth_not_expr (arg);
03339 if (!tem)
03340 tem = build1 (TRUTH_NOT_EXPR, TREE_TYPE (arg), arg);
03341
03342 return tem;
03343 }
03344
03345
03346
03347
03348
03349
03350
03351
03352
03353
03354 static tree
03355 distribute_bit_expr (enum tree_code code, tree type, tree arg0, tree arg1)
03356 {
03357 tree common;
03358 tree left, right;
03359
03360 if (TREE_CODE (arg0) != TREE_CODE (arg1)
03361 || TREE_CODE (arg0) == code
03362 || (TREE_CODE (arg0) != BIT_AND_EXPR
03363 && TREE_CODE (arg0) != BIT_IOR_EXPR))
03364 return 0;
03365
03366 if (operand_equal_p (TREE_OPERAND (arg0, 0), TREE_OPERAND (arg1, 0), 0))
03367 {
03368 common = TREE_OPERAND (arg0, 0);
03369 left = TREE_OPERAND (arg0, 1);
03370 right = TREE_OPERAND (arg1, 1);
03371 }
03372 else if (operand_equal_p (TREE_OPERAND (arg0, 0), TREE_OPERAND (arg1, 1), 0))
03373 {
03374 common = TREE_OPERAND (arg0, 0);
03375 left = TREE_OPERAND (arg0, 1);
03376 right = TREE_OPERAND (arg1, 0);
03377 }
03378 else if (operand_equal_p (TREE_OPERAND (arg0, 1), TREE_OPERAND (arg1, 0), 0))
03379 {
03380 common = TREE_OPERAND (arg0, 1);
03381 left = TREE_OPERAND (arg0, 0);
03382 right = TREE_OPERAND (arg1, 1);
03383 }
03384 else if (operand_equal_p (TREE_OPERAND (arg0, 1), TREE_OPERAND (arg1, 1), 0))
03385 {
03386 common = TREE_OPERAND (arg0, 1);
03387 left = TREE_OPERAND (arg0, 0);
03388 right = TREE_OPERAND (arg1, 0);
03389 }
03390 else
03391 return 0;
03392
03393 return fold_build2 (TREE_CODE (arg0), type, common,
03394 fold_build2 (code, type, left, right));
03395 }
03396
03397
03398
03399 static tree
03400 distribute_real_division (enum tree_code code, tree type, tree arg0, tree arg1)
03401 {
03402 bool mul0 = TREE_CODE (arg0) == MULT_EXPR;
03403 bool mul1 = TREE_CODE (arg1) == MULT_EXPR;
03404
03405
03406 if (mul0 == mul1
03407 && operand_equal_p (TREE_OPERAND (arg0, 1),
03408 TREE_OPERAND (arg1, 1), 0))
03409 return fold_build2 (mul0 ? MULT_EXPR : RDIV_EXPR, type,
03410 fold_build2 (code, type,
03411 TREE_OPERAND (arg0, 0),
03412 TREE_OPERAND (arg1, 0)),
03413 TREE_OPERAND (arg0, 1));
03414
03415
03416 if (operand_equal_p (TREE_OPERAND (arg0, 0),
03417 TREE_OPERAND (arg1, 0), 0)
03418 && TREE_CODE (TREE_OPERAND (arg0, 1)) == REAL_CST
03419 && TREE_CODE (TREE_OPERAND (arg1, 1)) == REAL_CST)
03420 {
03421 REAL_VALUE_TYPE r0, r1;
03422 r0 = TREE_REAL_CST (TREE_OPERAND (arg0, 1));
03423 r1 = TREE_REAL_CST (TREE_OPERAND (arg1, 1));
03424 if (!mul0)
03425 real_arithmetic (&r0, RDIV_EXPR, &dconst1, &r0);
03426 if (!mul1)
03427 real_arithmetic (&r1, RDIV_EXPR, &dconst1, &r1);
03428 real_arithmetic (&r0, code, &r0, &r1);
03429 return fold_build2 (MULT_EXPR, type,
03430 TREE_OPERAND (arg0, 0),
03431 build_real (type, r0));
03432 }
03433
03434 return NULL_TREE;
03435 }
03436
03437
03438
03439
03440 static tree
03441 make_bit_field_ref (tree inner, tree type, int bitsize, int bitpos,
03442 int unsignedp)
03443 {
03444 tree result;
03445
03446 if (bitpos == 0)
03447 {
03448 tree size = TYPE_SIZE (TREE_TYPE (inner));
03449 if ((INTEGRAL_TYPE_P (TREE_TYPE (inner))
03450 || POINTER_TYPE_P (TREE_TYPE (inner)))
03451 && host_integerp (size, 0)
03452 && tree_low_cst (size, 0) == bitsize)
03453 return fold_convert (type, inner);
03454 }
03455
03456 result = build3 (BIT_FIELD_REF, type, inner,
03457 size_int (bitsize), bitsize_int (bitpos));
03458
03459 BIT_FIELD_REF_UNSIGNED (result) = unsignedp;
03460
03461 return result;
03462 }
03463
03464
03465
03466
03467
03468
03469
03470
03471
03472
03473
03474
03475
03476
03477
03478
03479
03480
03481
03482
03483
03484 static tree
03485 optimize_bit_field_compare (enum tree_code code, tree compare_type,
03486 tree lhs, tree rhs)
03487 {
03488 HOST_WIDE_INT lbitpos, lbitsize, rbitpos, rbitsize, nbitpos, nbitsize;
03489 tree type = TREE_TYPE (lhs);
03490 tree signed_type, unsigned_type;
03491 int const_p = TREE_CODE (rhs) == INTEGER_CST;
03492 enum machine_mode lmode, rmode, nmode;
03493 int lunsignedp, runsignedp;
03494 int lvolatilep = 0, rvolatilep = 0;
03495 tree linner, rinner = NULL_TREE;
03496 tree mask;
03497 tree offset;
03498
03499
03500
03501
03502
03503
03504 linner = get_inner_reference (lhs, &lbitsize, &lbitpos, &offset, &lmode,
03505 &lunsignedp, &lvolatilep, false);
03506 if (linner == lhs || lbitsize == GET_MODE_BITSIZE (lmode) || lbitsize < 0
03507 || offset != 0 || TREE_CODE (linner) == PLACEHOLDER_EXPR)
03508 return 0;
03509
03510 if (!const_p)
03511 {
03512
03513
03514 rinner = get_inner_reference (rhs, &rbitsize, &rbitpos, &offset, &rmode,
03515 &runsignedp, &rvolatilep, false);
03516
03517 if (rinner == rhs || lbitpos != rbitpos || lbitsize != rbitsize
03518 || lunsignedp != runsignedp || offset != 0
03519 || TREE_CODE (rinner) == PLACEHOLDER_EXPR)
03520 return 0;
03521 }
03522
03523
03524
03525 nmode = get_best_mode (lbitsize, lbitpos,
03526 const_p ? TYPE_ALIGN (TREE_TYPE (linner))
03527 : MIN (TYPE_ALIGN (TREE_TYPE (linner)),
03528 TYPE_ALIGN (TREE_TYPE (rinner))),
03529 word_mode, lvolatilep || rvolatilep);
03530 if (nmode == VOIDmode)
03531 return 0;
03532
03533
03534
03535 signed_type = lang_hooks.types.type_for_mode (nmode, 0);
03536 unsigned_type = lang_hooks.types.type_for_mode (nmode, 1);
03537
03538
03539
03540
03541 nbitsize = GET_MODE_BITSIZE (nmode);
03542 nbitpos = lbitpos & ~ (nbitsize - 1);
03543 lbitpos -= nbitpos;
03544 if (nbitsize == lbitsize)
03545 return 0;
03546
03547 if (BYTES_BIG_ENDIAN)
03548 lbitpos = nbitsize - lbitsize - lbitpos;
03549
03550
03551 mask = build_int_cst (unsigned_type, -1);
03552 mask = force_fit_type (mask, 0, false, false);
03553 mask = fold_convert (unsigned_type, mask);
03554 mask = const_binop (LSHIFT_EXPR, mask, size_int (nbitsize - lbitsize), 0);
03555 mask = const_binop (RSHIFT_EXPR, mask,
03556 size_int (nbitsize - lbitsize - lbitpos), 0);
03557
03558 if (! const_p)
03559
03560
03561 return build2 (code, compare_type,
03562 build2 (BIT_AND_EXPR, unsigned_type,
03563 make_bit_field_ref (linner, unsigned_type,
03564 nbitsize, nbitpos, 1),
03565 mask),
03566 build2 (BIT_AND_EXPR, unsigned_type,
03567 make_bit_field_ref (rinner, unsigned_type,
03568 nbitsize, nbitpos, 1),
03569 mask));
03570
03571
03572
03573
03574
03575
03576
03577
03578
03579
03580 if (lunsignedp)
03581 {
03582 if (! integer_zerop (const_binop (RSHIFT_EXPR,
03583 fold_convert (unsigned_type, rhs),
03584 size_int (lbitsize), 0)))
03585 {
03586 warning (0, "comparison is always %d due to width of bit-field",
03587 code == NE_EXPR);
03588 return constant_boolean_node (code == NE_EXPR, compare_type);
03589 }
03590 }
03591 else
03592 {
03593 tree tem = const_binop (RSHIFT_EXPR, fold_convert (signed_type, rhs),
03594 size_int (lbitsize - 1), 0);
03595 if (! integer_zerop (tem) && ! integer_all_onesp (tem))
03596 {
03597 warning (0, "comparison is always %d due to width of bit-field",
03598 code == NE_EXPR);
03599 return constant_boolean_node (code == NE_EXPR, compare_type);
03600 }
03601 }
03602
03603
03604 if (lbitsize == 1 && ! integer_zerop (rhs))
03605 {
03606 code = code == EQ_EXPR ? NE_EXPR : EQ_EXPR;
03607 rhs = build_int_cst (type, 0);
03608 }
03609
03610
03611
03612
03613 lhs = make_bit_field_ref (linner, unsigned_type, nbitsize, nbitpos, 1);
03614 if (lvolatilep)
03615 {
03616 TREE_SIDE_EFFECTS (lhs) = 1;
03617 TREE_THIS_VOLATILE (lhs) = 1;
03618 }
03619
03620 rhs = const_binop (BIT_AND_EXPR,
03621 const_binop (LSHIFT_EXPR,
03622 fold_convert (unsigned_type, rhs),
03623 size_int (lbitpos), 0),
03624 mask, 0);
03625
03626 return build2 (code, compare_type,
03627 build2 (BIT_AND_EXPR, unsigned_type, lhs, mask),
03628 rhs);
03629 }
03630
03631
03632
03633
03634
03635
03636
03637
03638
03639
03640
03641
03642
03643
03644
03645
03646
03647
03648
03649
03650
03651
03652
03653
03654 static tree
03655 decode_field_reference (tree exp, HOST_WIDE_INT *pbitsize,
03656 HOST_WIDE_INT *pbitpos, enum machine_mode *pmode,
03657 int *punsignedp, int *pvolatilep,
03658 tree *pmask, tree *pand_mask)
03659 {
03660 tree outer_type = 0;
03661 tree and_mask = 0;
03662 tree mask, inner, offset;
03663 tree unsigned_type;
03664 unsigned int precision;
03665
03666
03667
03668
03669 if (! INTEGRAL_TYPE_P (TREE_TYPE (exp)))
03670 return 0;
03671
03672
03673
03674
03675 if (TREE_CODE (exp) == NOP_EXPR
03676 || TREE_CODE (exp) == CONVERT_EXPR
03677 || TREE_CODE (exp) == NON_LVALUE_EXPR)
03678 outer_type = TREE_TYPE (exp);
03679 STRIP_NOPS (exp);
03680
03681 if (TREE_CODE (exp) == BIT_AND_EXPR)
03682 {
03683 and_mask = TREE_OPERAND (exp, 1);
03684 exp = TREE_OPERAND (exp, 0);
03685 STRIP_NOPS (exp); STRIP_NOPS (and_mask);
03686 if (TREE_CODE (and_mask) != INTEGER_CST)
03687 return 0;
03688 }
03689
03690 inner = get_inner_reference (exp, pbitsize, pbitpos, &offset, pmode,
03691 punsignedp, pvolatilep, false);
03692 if ((inner == exp && and_mask == 0)
03693 || *pbitsize < 0 || offset != 0
03694 || TREE_CODE (inner) == PLACEHOLDER_EXPR)
03695 return 0;
03696
03697
03698
03699
03700 if (outer_type && *pbitsize == TYPE_PRECISION (outer_type))
03701 *punsignedp = TYPE_UNSIGNED (outer_type);
03702
03703
03704 unsigned_type = lang_hooks.types.type_for_size (*pbitsize, 1);
03705 precision = TYPE_PRECISION (unsigned_type);
03706
03707 mask = build_int_cst (unsigned_type, -1);
03708 mask = force_fit_type (mask, 0, false, false);
03709
03710 mask = const_binop (LSHIFT_EXPR, mask, size_int (precision - *pbitsize), 0);
03711 mask = const_binop (RSHIFT_EXPR, mask, size_int (precision - *pbitsize), 0);
03712
03713
03714 if (and_mask != 0)
03715 mask = fold_build2 (BIT_AND_EXPR, unsigned_type,
03716 fold_convert (unsigned_type, and_mask), mask);
03717
03718 *pmask = mask;
03719 *pand_mask = and_mask;
03720 return inner;
03721 }
03722
03723
03724
03725
03726 static int
03727 all_ones_mask_p (tree mask, int size)
03728 {
03729 tree type = TREE_TYPE (mask);
03730 unsigned int precision = TYPE_PRECISION (type);
03731 tree tmask;
03732
03733 tmask = build_int_cst (lang_hooks.types.signed_type (type), -1);
03734 tmask = force_fit_type (tmask, 0, false, false);
03735
03736 return
03737 tree_int_cst_equal (mask,
03738 const_binop (RSHIFT_EXPR,
03739 const_binop (LSHIFT_EXPR, tmask,
03740 size_int (precision - size),
03741 0),
03742 size_int (precision - size), 0));
03743 }
03744
03745
03746
03747
03748
03749
03750
03751 static tree
03752 sign_bit_p (tree exp, tree val)
03753 {
03754 unsigned HOST_WIDE_INT mask_lo, lo;
03755 HOST_WIDE_INT mask_hi, hi;
03756 int width;
03757 tree t;
03758
03759
03760 t = TREE_TYPE (exp);
03761 if (! INTEGRAL_TYPE_P (t))
03762 return NULL_TREE;
03763
03764
03765 if (TREE_CODE (val) != INTEGER_CST
03766 || TREE_CONSTANT_OVERFLOW (val))
03767 return NULL_TREE;
03768
03769 width = TYPE_PRECISION (t);
03770 if (width > HOST_BITS_PER_WIDE_INT)
03771 {
03772 hi = (unsigned HOST_WIDE_INT) 1 << (width - HOST_BITS_PER_WIDE_INT - 1);
03773 lo = 0;
03774
03775 mask_hi = ((unsigned HOST_WIDE_INT) -1
03776 >> (2 * HOST_BITS_PER_WIDE_INT - width));
03777 mask_lo = -1;
03778 }
03779 else
03780 {
03781 hi = 0;
03782 lo = (unsigned HOST_WIDE_INT) 1 << (width - 1);
03783
03784 mask_hi = 0;
03785 mask_lo = ((unsigned HOST_WIDE_INT) -1
03786 >> (HOST_BITS_PER_WIDE_INT - width));
03787 }
03788
03789
03790
03791 if ((TREE_INT_CST_HIGH (val) & mask_hi) == hi
03792 && (TREE_INT_CST_LOW (val) & mask_lo) == lo)
03793 return exp;
03794
03795
03796 if (TREE_CODE (exp) == NOP_EXPR
03797 && TYPE_PRECISION (TREE_TYPE (TREE_OPERAND (exp, 0))) < width)
03798 return sign_bit_p (TREE_OPERAND (exp, 0), val);
03799
03800 return NULL_TREE;
03801 }
03802
03803
03804
03805
03806 static int
03807 simple_operand_p (tree exp)
03808 {
03809
03810 STRIP_NOPS (exp);
03811
03812 return (CONSTANT_CLASS_P (exp)
03813 || TREE_CODE (exp) == SSA_NAME
03814 || (DECL_P (exp)
03815 && ! TREE_ADDRESSABLE (exp)
03816 && ! TREE_THIS_VOLATILE (exp)
03817 && ! DECL_NONLOCAL (exp)
03818
03819
03820
03821 && ! TREE_PUBLIC (exp)
03822 && ! DECL_EXTERNAL (exp)
03823
03824
03825 && (! TREE_STATIC (exp) || DECL_REGISTER (exp))));
03826 }
03827
03828
03829
03830
03831
03832
03833
03834
03835
03836
03837
03838
03839
03840
03841
03842
03843
03844
03845
03846
03847
03848
03849
03850
03851
03852
03853
03854
03855
03856
03857
03858
03859
03860
03861
03862
03863 static tree
03864 range_binop (enum tree_code code, tree type, tree arg0, int upper0_p,
03865 tree arg1, int upper1_p)
03866 {
03867 tree tem;
03868 int result;
03869 int sgn0, sgn1;
03870
03871
03872
03873
03874
03875
03876 if (arg0 != 0 && arg1 != 0)
03877 {
03878 tem = fold_build2 (code, type != 0 ? type : TREE_TYPE (arg0),
03879 arg0, fold_convert (TREE_TYPE (arg0), arg1));
03880 STRIP_NOPS (tem);
03881 return TREE_CODE (tem) == INTEGER_CST ? tem : 0;
03882 }
03883
03884 if (TREE_CODE_CLASS (code) != tcc_comparison)
03885 return 0;
03886
03887
03888
03889
03890
03891
03892
03893 sgn0 = arg0 != 0 ? 0 : (upper0_p ? 1 : -1);
03894 sgn1 = arg1 != 0 ? 0 : (upper1_p ? 1 : -1);
03895 switch (code)
03896 {
03897 case EQ_EXPR:
03898 result = sgn0 == sgn1;
03899 break;
03900 case NE_EXPR:
03901 result = sgn0 != sgn1;
03902 break;
03903 case LT_EXPR:
03904 result = sgn0 < sgn1;
03905 break;
03906 case LE_EXPR:
03907 result = sgn0 <= sgn1;
03908 break;
03909 case GT_EXPR:
03910 result = sgn0 > sgn1;
03911 break;
03912 case GE_EXPR:
03913 result = sgn0 >= sgn1;
03914 break;
03915 default:
03916 gcc_unreachable ();
03917 }
03918
03919 return constant_boolean_node (result, type);
03920 }
03921
03922
03923
03924
03925
03926
03927
03928
03929
03930
03931 static tree
03932 make_range (tree exp, int *pin_p, tree *plow, tree *phigh,
03933 bool *strict_overflow_p)
03934 {
03935 enum tree_code code;
03936 tree arg0 = NULL_TREE, arg1 = NULL_TREE;
03937 tree exp_type = NULL_TREE, arg0_type = NULL_TREE;
03938 int in_p, n_in_p;
03939 tree low, high, n_low, n_high;
03940
03941
03942
03943
03944
03945
03946
03947 in_p = 0;
03948 low = high = build_int_cst (TREE_TYPE (exp), 0);
03949
03950 while (1)
03951 {
03952 code = TREE_CODE (exp);
03953 exp_type = TREE_TYPE (exp);
03954
03955 if (IS_EXPR_CODE_CLASS (TREE_CODE_CLASS (code)))
03956 {
03957 if (TREE_CODE_LENGTH (code) > 0)
03958 arg0 = TREE_OPERAND (exp, 0);
03959 if (TREE_CODE_CLASS (code) == tcc_comparison
03960 || TREE_CODE_CLASS (code) == tcc_unary
03961 || TREE_CODE_CLASS (code) == tcc_binary)
03962 arg0_type = TREE_TYPE (arg0);
03963 if (TREE_CODE_CLASS (code) == tcc_binary
03964 || TREE_CODE_CLASS (code) == tcc_comparison
03965 || (TREE_CODE_CLASS (code) == tcc_expression
03966 && TREE_CODE_LENGTH (code) > 1))
03967 arg1 = TREE_OPERAND (exp, 1);
03968 }
03969
03970 switch (code)
03971 {
03972 case TRUTH_NOT_EXPR:
03973 in_p = ! in_p, exp = arg0;
03974 continue;
03975
03976 case EQ_EXPR: case NE_EXPR:
03977 case LT_EXPR: case LE_EXPR: case GE_EXPR: case GT_EXPR:
03978
03979
03980
03981
03982
03983 if (low == 0 || high == 0
03984 || ! integer_zerop (low) || ! integer_zerop (high)
03985 || TREE_CODE (arg1) != INTEGER_CST)
03986 break;
03987
03988 switch (code)
03989 {
03990 case NE_EXPR:
03991 low = high = arg1;
03992 break;
03993 case EQ_EXPR:
03994 in_p = ! in_p, low = high = arg1;
03995 break;
03996 case GT_EXPR:
03997 low = 0, high = arg1;
03998 break;
03999 case GE_EXPR:
04000 in_p = ! in_p, low = arg1, high = 0;
04001 break;
04002 case LT_EXPR:
04003 low = arg1, high = 0;
04004 break;
04005 case LE_EXPR:
04006 in_p = ! in_p, low = 0, high = arg1;
04007 break;
04008 default:
04009 gcc_unreachable ();
04010 }
04011
04012
04013
04014
04015
04016
04017 if (TYPE_UNSIGNED (arg0_type) && (low == 0 || high == 0))
04018 {
04019 if (! merge_ranges (&n_in_p, &n_low, &n_high,
04020 in_p, low, high, 1,
04021 build_int_cst (arg0_type, 0),
04022 NULL_TREE))
04023 break;
04024
04025 in_p = n_in_p, low = n_low, high = n_high;
04026
04027
04028
04029
04030 if (high == 0 && low && ! integer_zerop (low))
04031 {
04032 in_p = ! in_p;
04033 high = range_binop (MINUS_EXPR, NULL_TREE, low, 0,
04034 integer_one_node, 0);
04035 low = build_int_cst (arg0_type, 0);
04036 }
04037 }
04038
04039 exp = arg0;
04040 continue;
04041
04042 case NEGATE_EXPR:
04043
04044 n_low = range_binop (MINUS_EXPR, exp_type,
04045 build_int_cst (exp_type, 0),
04046 0, high, 1);
04047 n_high = range_binop (MINUS_EXPR, exp_type,
04048 build_int_cst (exp_type, 0),
04049 0, low, 0);
04050 low = n_low, high = n_high;
04051 exp = arg0;
04052 continue;
04053
04054 case BIT_NOT_EXPR:
04055
04056 exp = build2 (MINUS_EXPR, exp_type, negate_expr (arg0),
04057 build_int_cst (exp_type, 1));
04058 continue;
04059
04060 case PLUS_EXPR: case MINUS_EXPR:
04061 if (TREE_CODE (arg1) != INTEGER_CST)
04062 break;
04063
04064
04065
04066 if (!TYPE_UNSIGNED (arg0_type)
04067 && !TYPE_OVERFLOW_UNDEFINED (arg0_type))
04068 break;
04069
04070
04071
04072
04073
04074 n_low = range_binop (code == MINUS_EXPR ? PLUS_EXPR : MINUS_EXPR,
04075 arg0_type, low, 0, arg1, 0);
04076 n_high = range_binop (code == MINUS_EXPR ? PLUS_EXPR : MINUS_EXPR,
04077 arg0_type, high, 1, arg1, 0);
04078 if ((n_low != 0 && TREE_OVERFLOW (n_low))
04079 || (n_high != 0 && TREE_OVERFLOW (n_high)))
04080 break;
04081
04082 if (TYPE_OVERFLOW_UNDEFINED (arg0_type))
04083 *strict_overflow_p = true;
04084
04085
04086
04087 if (n_low && n_high && tree_int_cst_lt (n_high, n_low))
04088 {
04089 low = range_binop (PLUS_EXPR, arg0_type, n_high, 0,
04090 integer_one_node, 0);
04091 high = range_binop (MINUS_EXPR, arg0_type, n_low, 0,
04092 integer_one_node, 0);
04093
04094
04095
04096
04097
04098 if (tree_int_cst_equal (n_low, low)
04099 && tree_int_cst_equal (n_high, high))
04100 low = high = 0;
04101 else
04102 in_p = ! in_p;
04103 }
04104 else
04105 low = n_low, high = n_high;
04106
04107 exp = arg0;
04108 continue;
04109
04110 case NOP_EXPR: case NON_LVALUE_EXPR: case CONVERT_EXPR:
04111 if (TYPE_PRECISION (arg0_type) > TYPE_PRECISION (exp_type))
04112 break;
04113
04114 if (! INTEGRAL_TYPE_P (arg0_type)
04115 || (low != 0 && ! int_fits_type_p (low, arg0_type))
04116 || (high != 0 && ! int_fits_type_p (high, arg0_type)))
04117 break;
04118
04119 n_low = low, n_high = high;
04120
04121 if (n_low != 0)
04122 n_low = fold_convert (arg0_type, n_low);
04123
04124 if (n_high != 0)
04125 n_high = fold_convert (arg0_type, n_high);
04126
04127
04128
04129
04130
04131
04132
04133
04134
04135
04136
04137 if (!TYPE_UNSIGNED (exp_type) && TYPE_UNSIGNED (arg0_type))
04138 {
04139 tree high_positive;
04140 tree equiv_type = lang_hooks.types.type_for_mode
04141 (TYPE_MODE (arg0_type), 1);
04142
04143
04144
04145
04146 high_positive
04147 = TYPE_MAX_VALUE (equiv_type) ? TYPE_MAX_VALUE (equiv_type)
04148 : TYPE_MAX_VALUE (arg0_type);
04149
04150 if (TYPE_PRECISION (exp_type) == TYPE_PRECISION (arg0_type))
04151 high_positive = fold_build2 (RSHIFT_EXPR, arg0_type,
04152 fold_convert (arg0_type,
04153 high_positive),
04154 fold_convert (arg0_type,
04155 integer_one_node));
04156
04157
04158
04159
04160 if (low != 0)
04161 {
04162 if (! merge_ranges (&n_in_p, &n_low, &n_high,
04163 1, n_low, n_high, 1,
04164 fold_convert (arg0_type,
04165 integer_zero_node),
04166 high_positive))
04167 break;
04168
04169 in_p = (n_in_p == in_p);
04170 }
04171 else
04172 {
04173
04174
04175 if (! merge_ranges (&n_in_p, &n_low, &n_high,
04176 0, n_low, n_high, 1,
04177 fold_convert (arg0_type,
04178 integer_zero_node),
04179 high_positive))
04180 break;
04181
04182 in_p = (in_p != n_in_p);
04183 }
04184 }
04185
04186 exp = arg0;
04187 low = n_low, high = n_high;
04188 continue;
04189
04190 default:
04191 break;
04192 }
04193
04194 break;
04195 }
04196
04197
04198 if (TREE_CODE (exp) == INTEGER_CST)
04199 {
04200 in_p = in_p == (integer_onep (range_binop (GE_EXPR, integer_type_node,
04201 exp, 0, low, 0))
04202 && integer_onep (range_binop (LE_EXPR, integer_type_node,
04203 exp, 1, high, 1)));
04204 low = high = 0;
04205 exp = 0;
04206 }
04207
04208 *pin_p = in_p, *plow = low, *phigh = high;
04209 return exp;
04210 }
04211
04212
04213
04214
04215
04216 static tree
04217 build_range_check (tree type, tree exp, int in_p, tree low, tree high)
04218 {
04219 tree etype = TREE_TYPE (exp);
04220 tree value;
04221
04222 #ifdef HAVE_canonicalize_funcptr_for_compare
04223
04224
04225 if (HAVE_canonicalize_funcptr_for_compare
04226 && TREE_CODE (etype) == POINTER_TYPE
04227 && TREE_CODE (TREE_TYPE (etype)) == FUNCTION_TYPE)
04228 return NULL_TREE;
04229 #endif
04230
04231 if (! in_p)
04232 {
04233 value = build_range_check (type, exp, 1, low, high);
04234 if (value != 0)
04235 return invert_truthvalue (value);
04236
04237 return 0;
04238 }
04239
04240 if (low == 0 && high == 0)
04241 return build_int_cst (type, 1);
04242
04243 if (low == 0)
04244 return fold_build2 (LE_EXPR, type, exp,
04245 fold_convert (etype, high));
04246
04247 if (high == 0)
04248 return fold_build2 (GE_EXPR, type, exp,
04249 fold_convert (etype, low));
04250
04251 if (operand_equal_p (low, high, 0))
04252 return fold_build2 (EQ_EXPR, type, exp,
04253 fold_convert (etype, low));
04254
04255 if (integer_zerop (low))
04256 {
04257 if (! TYPE_UNSIGNED (etype))
04258 {
04259 etype = lang_hooks.types.unsigned_type (etype);
04260 high = fold_convert (etype, high);
04261 exp = fold_convert (etype, exp);
04262 }
04263 return build_range_check (type, exp, 1, 0, high);
04264 }
04265
04266
04267 if (integer_onep (low) && TREE_CODE (high) == INTEGER_CST)
04268 {
04269 unsigned HOST_WIDE_INT lo;
04270 HOST_WIDE_INT hi;
04271 int prec;
04272
04273 prec = TYPE_PRECISION (etype);
04274 if (prec <= HOST_BITS_PER_WIDE_INT)
04275 {
04276 hi = 0;
04277 lo = ((unsigned HOST_WIDE_INT) 1 << (prec - 1)) - 1;
04278 }
04279 else
04280 {
04281 hi = ((HOST_WIDE_INT) 1 << (prec - HOST_BITS_PER_WIDE_INT - 1)) - 1;
04282 lo = (unsigned HOST_WIDE_INT) -1;
04283 }
04284
04285 if (TREE_INT_CST_HIGH (high) == hi && TREE_INT_CST_LOW (high) == lo)
04286 {
04287 if (TYPE_UNSIGNED (etype))
04288 {
04289 etype = lang_hooks.types.signed_type (etype);
04290 exp = fold_convert (etype, exp);
04291 }
04292 return fold_build2 (GT_EXPR, type, exp,
04293 build_int_cst (etype, 0));
04294 }
04295 }
04296
04297
04298
04299 switch (TREE_CODE (etype))
04300 {
04301 case INTEGER_TYPE:
04302
04303
04304
04305 if (TREE_TYPE (etype))
04306 etype = TREE_TYPE (etype);
04307 break;
04308
04309 case ENUMERAL_TYPE:
04310 case BOOLEAN_TYPE:
04311 etype = lang_hooks.types.type_for_size (TYPE_PRECISION (etype),
04312 TYPE_UNSIGNED (etype));
04313 break;
04314
04315 default:
04316 break;
04317 }
04318
04319
04320 if (TREE_CODE (etype) == INTEGER_TYPE
04321 && !TYPE_OVERFLOW_WRAPS (etype))
04322 {
04323 tree utype, minv, maxv;
04324
04325
04326
04327 utype = lang_hooks.types.unsigned_type (etype);
04328 maxv = fold_convert (utype, TYPE_MAX_VALUE (etype));
04329 maxv = range_binop (PLUS_EXPR, NULL_TREE, maxv, 1,
04330 integer_one_node, 1);
04331 minv = fold_convert (utype, TYPE_MIN_VALUE (etype));
04332
04333 if (integer_zerop (range_binop (NE_EXPR, integer_type_node,
04334 minv, 1, maxv, 1)))
04335 etype = utype;
04336 else
04337 return 0;
04338 }
04339
04340 high = fold_convert (etype, high);
04341 low = fold_convert (etype, low);
04342 exp = fold_convert (etype, exp);
04343
04344 value = const_binop (MINUS_EXPR, high, low, 0);
04345
04346 if (value != 0 && !TREE_OVERFLOW (value))
04347 return build_range_check (type,
04348 fold_build2 (MINUS_EXPR, etype, exp, low),
04349 1, build_int_cst (etype, 0), value);
04350
04351 return 0;
04352 }
04353
04354
04355
04356 static tree
04357 range_predecessor (tree val)
04358 {
04359 tree type = TREE_TYPE (val);
04360
04361 if (INTEGRAL_TYPE_P (type)
04362 && operand_equal_p (val, TYPE_MIN_VALUE (type), 0))
04363 return 0;
04364 else
04365 return range_binop (MINUS_EXPR, NULL_TREE, val, 0, integer_one_node, 0);
04366 }
04367
04368
04369
04370 static tree
04371 range_successor (tree val)
04372 {
04373 tree type = TREE_TYPE (val);
04374
04375 if (INTEGRAL_TYPE_P (type)
04376 && operand_equal_p (val, TYPE_MAX_VALUE (type), 0))
04377 return 0;
04378 else
04379 return range_binop (PLUS_EXPR, NULL_TREE, val, 0, integer_one_node, 0);
04380 }
04381
04382
04383
04384
04385 static int
04386 merge_ranges (int *pin_p, tree *plow, tree *phigh, int in0_p, tree low0,
04387 tree high0, int in1_p, tree low1, tree high1)
04388 {
04389 int no_overlap;
04390 int subset;
04391 int temp;
04392 tree tem;
04393 int in_p;
04394 tree low, high;
04395 int lowequal = ((low0 == 0 && low1 == 0)
04396 || integer_onep (range_binop (EQ_EXPR, integer_type_node,
04397 low0, 0, low1, 0)));
04398 int highequal = ((high0 == 0 && high1 == 0)
04399 || integer_onep (range_binop (EQ_EXPR, integer_type_node,
04400 high0, 1, high1, 1)));
04401
04402
04403
04404 if (integer_onep (range_binop (GT_EXPR, integer_type_node,
04405 low0, 0, low1, 0))
04406 || (lowequal
04407 && integer_onep (range_binop (GT_EXPR, integer_type_node,
04408 high1, 1, high0, 1))))
04409 {
04410 temp = in0_p, in0_p = in1_p, in1_p = temp;
04411 tem = low0, low0 = low1, low1 = tem;
04412 tem = high0, high0 = high1, high1 = tem;
04413 }
04414
04415
04416
04417
04418 no_overlap = integer_onep (range_binop (LT_EXPR, integer_type_node,
04419 high0, 1, low1, 0));
04420 subset = integer_onep (range_binop (LE_EXPR, integer_type_node,
04421 high1, 1, high0, 1));
04422
04423
04424
04425 if (in0_p && in1_p)
04426 {
04427
04428
04429
04430 if (no_overlap)
04431 in_p = 0, low = high = 0;
04432 else if (subset)
04433 in_p = 1, low = low1, high = high1;
04434 else
04435 in_p = 1, low = low1, high = high0;
04436 }
04437
04438 else if (in0_p && ! in1_p)
04439 {
04440
04441
04442
04443
04444
04445
04446
04447
04448 if (no_overlap)
04449 in_p = 1, low = low0, high = high0;
04450 else if (lowequal && highequal)
04451 in_p = 0, low = high = 0;
04452 else if (subset && lowequal)
04453 {
04454 low = range_successor (high1);
04455 high = high0;
04456 in_p = (low != 0);
04457 }
04458 else if (! subset || highequal)
04459 {
04460 low = low0;
04461 high = range_predecessor (low1);
04462 in_p = (high != 0);
04463 }
04464 else
04465 return 0;
04466 }
04467
04468 else if (! in0_p && in1_p)
04469 {
04470
04471
04472
04473
04474 if (no_overlap)
04475 in_p = 1, low = low1, high = high1;
04476 else if (subset || highequal)
04477 in_p = 0, low = high = 0;
04478 else
04479 {
04480 low = range_successor (high0);
04481 high = high1;
04482 in_p = (low != 0);
04483 }
04484 }
04485
04486 else
04487 {
04488
04489
04490
04491
04492
04493
04494 if (no_overlap)
04495 {
04496 if (integer_onep (range_binop (EQ_EXPR, integer_type_node,
04497 range_successor (high0),
04498 1, low1, 0)))
04499 in_p = 0, low = low0, high = high1;
04500 else
04501 {
04502
04503 if (low0 && TREE_CODE (low0) == INTEGER_CST)
04504 switch (TREE_CODE (TREE_TYPE (low0)))
04505 {
04506 case ENUMERAL_TYPE:
04507 if (TYPE_PRECISION (TREE_TYPE (low0))
04508 != GET_MODE_BITSIZE (TYPE_MODE (TREE_TYPE (low0))))
04509 break;
04510
04511 case INTEGER_TYPE:
04512 if (tree_int_cst_equal (low0,
04513 TYPE_MIN_VALUE (TREE_TYPE (low0))))
04514 low0 = 0;
04515 break;
04516 case POINTER_TYPE:
04517 if (TYPE_UNSIGNED (TREE_TYPE (low0))
04518 && integer_zerop (low0))
04519 low0 = 0;
04520 break;
04521 default:
04522 break;
04523 }
04524
04525
04526 if (high1 && TREE_CODE (high1) == INTEGER_CST)
04527 switch (TREE_CODE (TREE_TYPE (high1)))
04528 {
04529 case ENUMERAL_TYPE:
04530 if (TYPE_PRECISION (TREE_TYPE (high1))
04531 != GET_MODE_BITSIZE (TYPE_MODE (TREE_TYPE (high1))))
04532 break;
04533
04534 case INTEGER_TYPE:
04535 if (tree_int_cst_equal (high1,
04536 TYPE_MAX_VALUE (TREE_TYPE (high1))))
04537 high1 = 0;
04538 break;
04539 case POINTER_TYPE:
04540 if (TYPE_UNSIGNED (TREE_TYPE (high1))
04541 && integer_zerop (range_binop (PLUS_EXPR, NULL_TREE,
04542 high1, 1,
04543 integer_one_node, 1)))
04544 high1 = 0;
04545 break;
04546 default:
04547 break;
04548 }
04549
04550
04551
04552
04553
04554 if (low0 == 0 && high1 == 0)
04555 {
04556 low = range_successor (high0);
04557 high = range_predecessor (low1);
04558 if (low == 0 || high == 0)
04559 return 0;
04560
04561 in_p = 1;
04562 }
04563 else
04564 return 0;
04565 }
04566 }
04567 else if (subset)
04568 in_p = 0, low = low0, high = high0;
04569 else
04570 in_p = 0, low = low0, high = high1;
04571 }
04572
04573 *pin_p = in_p, *plow = low, *phigh = high;
04574 return 1;
04575 }
04576
04577
04578
04579
04580
04581
04582
04583
04584
04585
04586 static tree
04587 fold_cond_expr_with_comparison (tree type, tree arg0, tree arg1, tree arg2)
04588 {
04589 enum tree_code comp_code = TREE_CODE (arg0);
04590 tree arg00 = TREE_OPERAND (arg0, 0);
04591 tree arg01 = TREE_OPERAND (arg0, 1);
04592 tree arg1_type = TREE_TYPE (arg1);
04593 tree tem;
04594
04595 STRIP_NOPS (arg1);
04596 STRIP_NOPS (arg2);
04597
04598
04599
04600
04601
04602
04603
04604
04605
04606
04607
04608
04609
04610
04611
04612
04613
04614
04615
04616
04617 if ((FLOAT_TYPE_P (TREE_TYPE (arg01))
04618 ? real_zerop (arg01)
04619 : integer_zerop (arg01))
04620 && ((TREE_CODE (arg2) == NEGATE_EXPR
04621 && operand_equal_p (TREE_OPERAND (arg2, 0), arg1, 0))
04622
04623
04624 || (TREE_CODE (arg1) == MINUS_EXPR
04625 && TREE_CODE (arg2) == MINUS_EXPR
04626 && operand_equal_p (TREE_OPERAND (arg1, 0),
04627 TREE_OPERAND (arg2, 1), 0)
04628 && operand_equal_p (TREE_OPERAND (arg1, 1),
04629 TREE_OPERAND (arg2, 0), 0))))
04630 switch (comp_code)
04631 {
04632 case EQ_EXPR:
04633 case UNEQ_EXPR:
04634 tem = fold_convert (arg1_type, arg1);
04635 return pedantic_non_lvalue (fold_convert (type, negate_expr (tem)));
04636 case NE_EXPR:
04637 case LTGT_EXPR:
04638 return pedantic_non_lvalue (fold_convert (type, arg1));
04639 case UNGE_EXPR:
04640 case UNGT_EXPR:
04641 if (flag_trapping_math)
04642 break;
04643
04644 case GE_EXPR:
04645 case GT_EXPR:
04646 if (TYPE_UNSIGNED (TREE_TYPE (arg1)))
04647 arg1 = fold_convert (lang_hooks.types.signed_type
04648 (TREE_TYPE (arg1)), arg1);
04649 tem = fold_build1 (ABS_EXPR, TREE_TYPE (arg1), arg1);
04650 return pedantic_non_lvalue (fold_convert (type, tem));
04651 case UNLE_EXPR:
04652 case UNLT_EXPR:
04653 if (flag_trapping_math)
04654 break;
04655 case LE_EXPR:
04656 case LT_EXPR:
04657 if (TYPE_UNSIGNED (TREE_TYPE (arg1)))
04658 arg1 = fold_convert (lang_hooks.types.signed_type
04659 (TREE_TYPE (arg1)), arg1);
04660 tem = fold_build1 (ABS_EXPR, TREE_TYPE (arg1), arg1);
04661 return negate_expr (fold_convert (type, tem));
04662 default:
04663 gcc_assert (TREE_CODE_CLASS (comp_code) == tcc_comparison);
04664 break;
04665 }
04666
04667
04668
04669
04670
04671
04672 if (integer_zerop (arg01) && integer_zerop (arg2))
04673 {
04674 if (comp_code == NE_EXPR)
04675 return pedantic_non_lvalue (fold_convert (type, arg1));
04676 else if (comp_code == EQ_EXPR)
04677 return build_int_cst (type, 0);
04678 }
04679
04680
04681
04682
04683
04684
04685
04686
04687
04688
04689
04690
04691
04692
04693
04694
04695
04696
04697
04698
04699
04700
04701
04702
04703
04704
04705
04706 if (operand_equal_for_comparison_p (arg01, arg2, arg00)
04707
04708
04709 && (in_gimple_form
04710 || (strcmp (lang_hooks.name, "GNU C++") != 0
04711 && strcmp (lang_hooks.name, "GNU Objective-C++") != 0)
04712 || ! maybe_lvalue_p (arg1)
04713 || ! maybe_lvalue_p (arg2)))
04714 {
04715 tree comp_op0 = arg00;
04716 tree comp_op1 = arg01;
04717 tree comp_type = TREE_TYPE (comp_op0);
04718
04719
04720 if (TYPE_MAIN_VARIANT (comp_type) == TYPE_MAIN_VARIANT (type))
04721 {
04722 comp_type = type;
04723 comp_op0 = arg1;
04724 comp_op1 = arg2;
04725 }
04726
04727 switch (comp_code)
04728 {
04729 case EQ_EXPR:
04730 return pedantic_non_lvalue (fold_convert (type, arg2));
04731 case NE_EXPR:
04732 return pedantic_non_lvalue (fold_convert (type, arg1));
04733 case LE_EXPR:
04734 case LT_EXPR:
04735 case UNLE_EXPR:
04736 case UNLT_EXPR:
04737
04738
04739
04740
04741 if (!HONOR_NANS (TYPE_MODE (TREE_TYPE (arg1))))
04742 {
04743 comp_op0 = fold_convert (comp_type, comp_op0);
04744 comp_op1 = fold_convert (comp_type, comp_op1);
04745 tem = (comp_code == LE_EXPR || comp_code == UNLE_EXPR)
04746 ? fold_build2 (MIN_EXPR, comp_type, comp_op0, comp_op1)
04747 : fold_build2 (MIN_EXPR, comp_type, comp_op1, comp_op0);
04748 return pedantic_non_lvalue (fold_convert (type, tem));
04749 }
04750 break;
04751 case GE_EXPR:
04752 case GT_EXPR:
04753 case UNGE_EXPR:
04754 case UNGT_EXPR:
04755 if (!HONOR_NANS (TYPE_MODE (TREE_TYPE (arg1))))
04756 {
04757 comp_op0 = fold_convert (comp_type, comp_op0);
04758 comp_op1 = fold_convert (comp_type, comp_op1);
04759 tem = (comp_code == GE_EXPR || comp_code == UNGE_EXPR)
04760 ? fold_build2 (MAX_EXPR, comp_type, comp_op0, comp_op1)
04761 : fold_build2 (MAX_EXPR, comp_type, comp_op1, comp_op0);
04762 return pedantic_non_lvalue (fold_convert (type, tem));
04763 }
04764 break;
04765 case UNEQ_EXPR:
04766 if (!HONOR_NANS (TYPE_MODE (TREE_TYPE (arg1))))
04767 return pedantic_non_lvalue (fold_convert (type, arg2));
04768 break;
04769 case LTGT_EXPR:
04770 if (!HONOR_NANS (TYPE_MODE (TREE_TYPE (arg1))))
04771 return pedantic_non_lvalue (fold_convert (type, arg1));
04772 break;
04773 default:
04774 gcc_assert (TREE_CODE_CLASS (comp_code) == tcc_comparison);
04775 break;
04776 }
04777 }
04778
04779
04780
04781
04782
04783
04784
04785 if (INTEGRAL_TYPE_P (type)
04786 && TREE_CODE (arg01) == INTEGER_CST
04787 && TREE_CODE (arg2) == INTEGER_CST)
04788 switch (comp_code)
04789 {
04790 case EQ_EXPR:
04791
04792 arg1 = fold_convert (type, arg01);
04793 return fold_build3 (COND_EXPR, type, arg0, arg1, arg2);
04794
04795 case LT_EXPR:
04796
04797 if (! operand_equal_p (arg2, TYPE_MAX_VALUE (type),
04798 OEP_ONLY_CONST)
04799 && operand_equal_p (arg01,
04800 const_binop (PLUS_EXPR, arg2,
04801 integer_one_node, 0),
04802 OEP_ONLY_CONST))
04803 return pedantic_non_lvalue (fold_build2 (MIN_EXPR,
04804 type, arg1, arg2));
04805 break;
04806
04807 case LE_EXPR:
04808
04809 if (! operand_equal_p (arg2, TYPE_MIN_VALUE (type),
04810 OEP_ONLY_CONST)
04811 && operand_equal_p (arg01,
04812 const_binop (MINUS_EXPR, arg2,
04813 integer_one_node, 0),
04814 OEP_ONLY_CONST))
04815 return pedantic_non_lvalue (fold_build2 (MIN_EXPR,
04816 type, arg1, arg2));
04817 break;
04818
04819 case GT_EXPR:
04820
04821 if (! operand_equal_p (arg2, TYPE_MIN_VALUE (type),
04822 OEP_ONLY_CONST)
04823 && operand_equal_p (arg01,
04824 const_binop (MINUS_EXPR, arg2,
04825 integer_one_node, 0),
04826 OEP_ONLY_CONST))
04827 return pedantic_non_lvalue (fold_build2 (MAX_EXPR,
04828 type, arg1, arg2));
04829 break;
04830
04831 case GE_EXPR:
04832
04833 if (! operand_equal_p (arg2, TYPE_MAX_VALUE (type),
04834 OEP_ONLY_CONST)
04835 && operand_equal_p (arg01,
04836 const_binop (PLUS_EXPR, arg2,
04837 integer_one_node, 0),
04838 OEP_ONLY_CONST))
04839 return pedantic_non_lvalue (fold_build2 (MAX_EXPR,
04840 type, arg1, arg2));
04841 break;
04842 case NE_EXPR:
04843 break;
04844 default:
04845 gcc_unreachable ();
04846 }
04847
04848 return NULL_TREE;
04849 }
04850
04851
04852
04853 #ifndef LOGICAL_OP_NON_SHORT_CIRCUIT
04854 #ifdef KEY // bug 11517
04855 #define LOGICAL_OP_NON_SHORT_CIRCUIT (!flag_spin_file && BRANCH_COST >= 2)
04856 #else
04857 #define LOGICAL_OP_NON_SHORT_CIRCUIT (BRANCH_COST >= 2)
04858 #endif
04859 #endif
04860
04861
04862
04863
04864 static tree
04865 fold_range_test (enum tree_code code, tree type, tree op0, tree op1)
04866 {
04867 int or_op = (code == TRUTH_ORIF_EXPR
04868 || code == TRUTH_OR_EXPR);
04869 int in0_p, in1_p, in_p;
04870 tree low0, low1, low, high0, high1, high;
04871 bool strict_overflow_p = false;
04872 tree lhs = make_range (op0, &in0_p, &low0, &high0, &strict_overflow_p);
04873 tree rhs = make_range (op1, &in1_p, &low1, &high1, &strict_overflow_p);
04874 tree tem;
04875 const char * const warnmsg = G_("assuming signed overflow does not occur "
04876 "when simplifying range test");
04877
04878
04879
04880 if (or_op)
04881 in0_p = ! in0_p, in1_p = ! in1_p;
04882
04883
04884
04885
04886
04887 if ((lhs == 0 || rhs == 0 || operand_equal_p (lhs, rhs, 0))
04888 && merge_ranges (&in_p, &low, &high, in0_p, low0, high0,
04889 in1_p, low1, high1)
04890 && 0 != (tem = (build_range_check (type,
04891 lhs != 0 ? lhs
04892 : rhs != 0 ? rhs : integer_zero_node,
04893 in_p, low, high))))
04894 {
04895 if (strict_overflow_p)
04896 fold_overflow_warning (warnmsg, WARN_STRICT_OVERFLOW_COMPARISON);
04897 return or_op ? invert_truthvalue (tem) : tem;
04898 }
04899
04900
04901
04902
04903 else if (LOGICAL_OP_NON_SHORT_CIRCUIT
04904 && lhs != 0 && rhs != 0
04905 && (code == TRUTH_ANDIF_EXPR
04906 || code == TRUTH_ORIF_EXPR)
04907 && operand_equal_p (lhs, rhs, 0))
04908 {
04909
04910
04911
04912 if (simple_operand_p (lhs))
04913 return build2 (code == TRUTH_ANDIF_EXPR
04914 ? TRUTH_AND_EXPR : TRUTH_OR_EXPR,
04915 type, op0, op1);
04916
04917 else if (lang_hooks.decls.global_bindings_p () == 0
04918 && ! CONTAINS_PLACEHOLDER_P (lhs))
04919 {
04920 tree common = save_expr (lhs);
04921
04922 if (0 != (lhs = build_range_check (type, common,
04923 or_op ? ! in0_p : in0_p,
04924 low0, high0))
04925 && (0 != (rhs = build_range_check (type, common,
04926 or_op ? ! in1_p : in1_p,
04927 low1, high1))))
04928 {
04929 if (strict_overflow_p)
04930 fold_overflow_warning (warnmsg,
04931 WARN_STRICT_OVERFLOW_COMPARISON);
04932 return build2 (code == TRUTH_ANDIF_EXPR
04933 ? TRUTH_AND_EXPR : TRUTH_OR_EXPR,
04934 type, lhs, rhs);
04935 }
04936 }
04937 }
04938
04939 return 0;
04940 }
04941
04942
04943
04944
04945
04946
04947 static tree
04948 unextend (tree c, int p, int unsignedp, tree mask)
04949 {
04950 tree type = TREE_TYPE (c);
04951 int modesize = GET_MODE_BITSIZE (TYPE_MODE (type));
04952 tree temp;
04953
04954 if (p == modesize || unsignedp)
04955 return c;
04956
04957
04958
04959
04960 temp = const_binop (RSHIFT_EXPR, c, size_int (p - 1), 0);
04961 temp = const_binop (BIT_AND_EXPR, temp, size_int (1), 0);
04962
04963
04964
04965
04966
04967
04968
04969 if (TYPE_UNSIGNED (type))
04970 temp = fold_convert (lang_hooks.types.signed_type (type), temp);
04971
04972 temp = const_binop (LSHIFT_EXPR, temp, size_int (modesize - 1), 0);
04973 temp = const_binop (RSHIFT_EXPR, temp, size_int (modesize - p - 1), 0);
04974 if (mask != 0)
04975 temp = const_binop (BIT_AND_EXPR, temp,
04976 fold_convert (TREE_TYPE (c), mask), 0);
04977
04978 if (TYPE_UNSIGNED (type))
04979 temp = fold_convert (type, temp);
04980
04981 return fold_convert (type, const_binop (BIT_XOR_EXPR, c, temp, 0));
04982 }
04983
04984
04985
04986
04987
04988
04989
04990
04991
04992
04993
04994
04995
04996
04997
04998
04999
05000
05001
05002
05003
05004
05005
05006
05007
05008 static tree
05009 fold_truthop (enum tree_code code, tree truth_type, tree lhs, tree rhs)
05010 {
05011
05012
05013
05014
05015
05016
05017
05018
05019
05020 enum tree_code wanted_code;
05021 enum tree_code lcode, rcode;
05022 tree ll_arg, lr_arg, rl_arg, rr_arg;
05023 tree ll_inner, lr_inner, rl_inner, rr_inner;
05024 HOST_WIDE_INT ll_bitsize, ll_bitpos, lr_bitsize, lr_bitpos;
05025 HOST_WIDE_INT rl_bitsize, rl_bitpos, rr_bitsize, rr_bitpos;
05026 HOST_WIDE_INT xll_bitpos, xlr_bitpos, xrl_bitpos, xrr_bitpos;
05027 HOST_WIDE_INT lnbitsize, lnbitpos, rnbitsize, rnbitpos;
05028 int ll_unsignedp, lr_unsignedp, rl_unsignedp, rr_unsignedp;
05029 enum machine_mode ll_mode, lr_mode, rl_mode, rr_mode;
05030 enum machine_mode lnmode, rnmode;
05031 tree ll_mask, lr_mask, rl_mask, rr_mask;
05032 tree ll_and_mask, lr_and_mask, rl_and_mask, rr_and_mask;
05033 tree l_const, r_const;
05034 tree lntype, rntype, result;
05035 int first_bit, end_bit;
05036 int volatilep;
05037 tree orig_lhs = lhs, orig_rhs = rhs;
05038 enum tree_code orig_code = code;
05039
05040
05041
05042
05043
05044 if (TREE_SIDE_EFFECTS (lhs) || TREE_SIDE_EFFECTS (rhs))
05045 return 0;
05046
05047 lcode = TREE_CODE (lhs);
05048 rcode = TREE_CODE (rhs);
05049
05050 if (lcode == BIT_AND_EXPR && integer_onep (TREE_OPERAND (lhs, 1)))
05051 {
05052 lhs = build2 (NE_EXPR, truth_type, lhs,
05053 build_int_cst (TREE_TYPE (lhs), 0));
05054 lcode = NE_EXPR;
05055 }
05056
05057 if (rcode == BIT_AND_EXPR && integer_onep (TREE_OPERAND (rhs, 1)))
05058 {
05059 rhs = build2 (NE_EXPR, truth_type, rhs,
05060 build_int_cst (TREE_TYPE (rhs), 0));
05061 rcode = NE_EXPR;
05062 }
05063
05064 if (TREE_CODE_CLASS (lcode) != tcc_comparison
05065 || TREE_CODE_CLASS (rcode) != tcc_comparison)
05066 return 0;
05067
05068 ll_arg = TREE_OPERAND (lhs, 0);
05069 lr_arg = TREE_OPERAND (lhs, 1);
05070 rl_arg = TREE_OPERAND (rhs, 0);
05071 rr_arg = TREE_OPERAND (rhs, 1);
05072
05073
05074 if (simple_operand_p (ll_arg)
05075 && simple_operand_p (lr_arg))
05076 {
05077 tree result;
05078 if (operand_equal_p (ll_arg, rl_arg, 0)
05079 && operand_equal_p (lr_arg, rr_arg, 0))
05080 {
05081 result = combine_comparisons (code, lcode, rcode,
05082 truth_type, ll_arg, lr_arg);
05083 if (result)
05084 return result;
05085 }
05086 else if (operand_equal_p (ll_arg, rr_arg, 0)
05087 && operand_equal_p (lr_arg, rl_arg, 0))
05088 {
05089 result = combine_comparisons (code, lcode,
05090 swap_tree_comparison (rcode),
05091 truth_type, ll_arg, lr_arg);
05092 if (result)
05093 return result;
05094 }
05095 }
05096
05097 code = ((code == TRUTH_AND_EXPR || code == TRUTH_ANDIF_EXPR)
05098 ? TRUTH_AND_EXPR : TRUTH_OR_EXPR);
05099
05100
05101
05102
05103
05104
05105
05106 if (BRANCH_COST >= 2
05107 && ! FLOAT_TYPE_P (TREE_TYPE (rl_arg))
05108 && simple_operand_p (rl_arg)
05109 && simple_operand_p (rr_arg))
05110 {
05111
05112 if (code == TRUTH_OR_EXPR
05113 && lcode == NE_EXPR && integer_zerop (lr_arg)
05114 && rcode == NE_EXPR && integer_zerop (rr_arg)
05115 && TREE_TYPE (ll_arg) == TREE_TYPE (rl_arg))
05116 return build2 (NE_EXPR, truth_type,
05117 build2 (BIT_IOR_EXPR, TREE_TYPE (ll_arg),
05118 ll_arg, rl_arg),
05119 build_int_cst (TREE_TYPE (ll_arg), 0));
05120
05121
05122 if (code == TRUTH_AND_EXPR
05123 && lcode == EQ_EXPR && integer_zerop (lr_arg)
05124 && rcode == EQ_EXPR && integer_zerop (rr_arg)
05125 && TREE_TYPE (ll_arg) == TREE_TYPE (rl_arg))
05126 return build2 (EQ_EXPR, truth_type,
05127 build2 (BIT_IOR_EXPR, TREE_TYPE (ll_arg),
05128 ll_arg, rl_arg),
05129 build_int_cst (TREE_TYPE (ll_arg), 0));
05130
05131 if (LOGICAL_OP_NON_SHORT_CIRCUIT)
05132 {
05133 if (code != orig_code || lhs != orig_lhs || rhs != orig_rhs)
05134 return build2 (code, truth_type, lhs, rhs);
05135 return NULL_TREE;
05136 }
05137 }
05138
05139
05140
05141
05142 if ((lcode != EQ_EXPR && lcode != NE_EXPR)
05143 || (rcode != EQ_EXPR && rcode != NE_EXPR))
05144 return 0;
05145
05146 volatilep = 0;
05147 ll_inner = decode_field_reference (ll_arg,
05148 &ll_bitsize, &ll_bitpos, &ll_mode,
05149 &ll_unsignedp, &volatilep, &ll_mask,
05150 &ll_and_mask);
05151 lr_inner = decode_field_reference (lr_arg,
05152 &lr_bitsize, &lr_bitpos, &lr_mode,
05153 &lr_unsignedp, &volatilep, &lr_mask,
05154 &lr_and_mask);
05155 rl_inner = decode_field_reference (rl_arg,
05156 &rl_bitsize, &rl_bitpos, &rl_mode,
05157 &rl_unsignedp, &volatilep, &rl_mask,
05158 &rl_and_mask);
05159 rr_inner = decode_field_reference (rr_arg,
05160 &rr_bitsize, &rr_bitpos, &rr_mode,
05161 &rr_unsignedp, &volatilep, &rr_mask,
05162 &rr_and_mask);
05163
05164
05165
05166
05167
05168 if (volatilep || ll_inner == 0 || rl_inner == 0
05169 || ! operand_equal_p (ll_inner, rl_inner, 0))
05170 return 0;
05171
05172 if (TREE_CODE (lr_arg) == INTEGER_CST
05173 && TREE_CODE (rr_arg) == INTEGER_CST)
05174 l_const = lr_arg, r_const = rr_arg;
05175 else if (lr_inner == 0 || rr_inner == 0
05176 || ! operand_equal_p (lr_inner, rr_inner, 0))
05177 return 0;
05178 else
05179 l_const = r_const = 0;
05180
05181
05182
05183
05184
05185 wanted_code = (code == TRUTH_AND_EXPR ? EQ_EXPR : NE_EXPR);
05186 if (lcode != wanted_code)
05187 {
05188 if (l_const && integer_zerop (l_const) && integer_pow2p (ll_mask))
05189 {
05190
05191
05192
05193 ll_unsignedp = 1;
05194 l_const = ll_mask;
05195 }
05196 else
05197 return 0;
05198 }
05199
05200
05201 if (rcode != wanted_code)
05202 {
05203 if (r_const && integer_zerop (r_const) && integer_pow2p (rl_mask))
05204 {
05205 rl_unsignedp = 1;
05206 r_const = rl_mask;
05207 }
05208 else
05209 return 0;
05210 }
05211
05212
05213
05214 if (! lang_hooks.can_use_bit_fields_p ())
05215 return 0;
05216
05217
05218
05219
05220 first_bit = MIN (ll_bitpos, rl_bitpos);
05221 end_bit = MAX (ll_bitpos + ll_bitsize, rl_bitpos + rl_bitsize);
05222 lnmode = get_best_mode (end_bit - first_bit, first_bit,
05223 TYPE_ALIGN (TREE_TYPE (ll_inner)), word_mode,
05224 volatilep);
05225 if (lnmode == VOIDmode)
05226 return 0;
05227
05228 lnbitsize = GET_MODE_BITSIZE (lnmode);
05229 lnbitpos = first_bit & ~ (lnbitsize - 1);
05230 lntype = lang_hooks.types.type_for_size (lnbitsize, 1);
05231 xll_bitpos = ll_bitpos - lnbitpos, xrl_bitpos = rl_bitpos - lnbitpos;
05232
05233 if (BYTES_BIG_ENDIAN)
05234 {
05235 xll_bitpos = lnbitsize - xll_bitpos - ll_bitsize;
05236 xrl_bitpos = lnbitsize - xrl_bitpos - rl_bitsize;
05237 }
05238
05239 ll_mask = const_binop (LSHIFT_EXPR, fold_convert (lntype, ll_mask),
05240 size_int (xll_bitpos), 0);
05241 rl_mask = const_binop (LSHIFT_EXPR, fold_convert (lntype, rl_mask),
05242 size_int (xrl_bitpos), 0);
05243
05244 if (l_const)
05245 {
05246 l_const = fold_convert (lntype, l_const);
05247 l_const = unextend (l_const, ll_bitsize, ll_unsignedp, ll_and_mask);
05248 l_const = const_binop (LSHIFT_EXPR, l_const, size_int (xll_bitpos), 0);
05249 if (! integer_zerop (const_binop (BIT_AND_EXPR, l_const,
05250 fold_build1 (BIT_NOT_EXPR,
05251 lntype, ll_mask),
05252 0)))
05253 {
05254 warning (0, "comparison is always %d", wanted_code == NE_EXPR);
05255
05256 return constant_boolean_node (wanted_code == NE_EXPR, truth_type);
05257 }
05258 }
05259 if (r_const)
05260 {
05261 r_const = fold_convert (lntype, r_const);
05262 r_const = unextend (r_const, rl_bitsize, rl_unsignedp, rl_and_mask);
05263 r_const = const_binop (LSHIFT_EXPR, r_const, size_int (xrl_bitpos), 0);
05264 if (! integer_zerop (const_binop (BIT_AND_EXPR, r_const,
05265 fold_build1 (BIT_NOT_EXPR,
05266 lntype, rl_mask),
05267 0)))
05268 {
05269 warning (0, "comparison is always %d", wanted_code == NE_EXPR);
05270
05271 return constant_boolean_node (wanted_code == NE_EXPR, truth_type);
05272 }
05273 }
05274
05275
05276
05277
05278 if (l_const == 0)
05279 {
05280 if (ll_bitsize != lr_bitsize || rl_bitsize != rr_bitsize
05281 || ll_unsignedp != lr_unsignedp || rl_unsignedp != rr_unsignedp
05282
05283
05284 || ll_bitpos - rl_bitpos != lr_bitpos - rr_bitpos)
05285 return 0;
05286
05287 first_bit = MIN (lr_bitpos, rr_bitpos);
05288 end_bit = MAX (lr_bitpos + lr_bitsize, rr_bitpos + rr_bitsize);
05289 rnmode = get_best_mode (end_bit - first_bit, first_bit,
05290 TYPE_ALIGN (TREE_TYPE (lr_inner)), word_mode,
05291 volatilep);
05292 if (rnmode == VOIDmode)
05293 return 0;
05294
05295 rnbitsize = GET_MODE_BITSIZE (rnmode);
05296 rnbitpos = first_bit & ~ (rnbitsize - 1);
05297 rntype = lang_hooks.types.type_for_size (rnbitsize, 1);
05298 xlr_bitpos = lr_bitpos - rnbitpos, xrr_bitpos = rr_bitpos - rnbitpos;
05299
05300 if (BYTES_BIG_ENDIAN)
05301 {
05302 xlr_bitpos = rnbitsize - xlr_bitpos - lr_bitsize;
05303 xrr_bitpos = rnbitsize - xrr_bitpos - rr_bitsize;
05304 }
05305
05306 lr_mask = const_binop (LSHIFT_EXPR, fold_convert (rntype, lr_mask),
05307 size_int (xlr_bitpos), 0);
05308 rr_mask = const_binop (LSHIFT_EXPR, fold_convert (rntype, rr_mask),
05309 size_int (xrr_bitpos), 0);
05310
05311
05312
05313
05314
05315
05316 ll_mask = const_binop (BIT_IOR_EXPR, ll_mask, rl_mask, 0);
05317 lr_mask = const_binop (BIT_IOR_EXPR, lr_mask, rr_mask, 0);
05318 if (lnbitsize == rnbitsize && xll_bitpos == xlr_bitpos)
05319 {
05320 lhs = make_bit_field_ref (ll_inner, lntype, lnbitsize, lnbitpos,
05321 ll_unsignedp || rl_unsignedp);
05322 if (! all_ones_mask_p (ll_mask, lnbitsize))
05323 lhs = build2 (BIT_AND_EXPR, lntype, lhs, ll_mask);
05324
05325 rhs = make_bit_field_ref (lr_inner, rntype, rnbitsize, rnbitpos,
05326 lr_unsignedp || rr_unsignedp);
05327 if (! all_ones_mask_p (lr_mask, rnbitsize))
05328 rhs = build2 (BIT_AND_EXPR, rntype, rhs, lr_mask);
05329
05330 return build2 (wanted_code, truth_type, lhs, rhs);
05331 }
05332
05333
05334
05335
05336
05337
05338
05339
05340 if ((ll_bitsize + ll_bitpos == rl_bitpos
05341 && lr_bitsize + lr_bitpos == rr_bitpos)
05342 || (ll_bitpos == rl_bitpos + rl_bitsize
05343 && lr_bitpos == rr_bitpos + rr_bitsize))
05344 {
05345 tree type;
05346
05347 lhs = make_bit_field_ref (ll_inner, lntype, ll_bitsize + rl_bitsize,
05348 MIN (ll_bitpos, rl_bitpos), ll_unsignedp);
05349 rhs = make_bit_field_ref (lr_inner, rntype, lr_bitsize + rr_bitsize,
05350 MIN (lr_bitpos, rr_bitpos), lr_unsignedp);
05351
05352 ll_mask = const_binop (RSHIFT_EXPR, ll_mask,
05353 size_int (MIN (xll_bitpos, xrl_bitpos)), 0);
05354 lr_mask = const_binop (RSHIFT_EXPR, lr_mask,
05355 size_int (MIN (xlr_bitpos, xrr_bitpos)), 0);
05356
05357
05358 type = lntype;
05359 if (lntype != rntype)
05360 {
05361 if (lnbitsize > rnbitsize)
05362 {
05363 lhs = fold_convert (rntype, lhs);
05364 ll_mask = fold_convert (rntype, ll_mask);
05365 type = rntype;
05366 }
05367 else if (lnbitsize < rnbitsize)
05368 {
05369 rhs = fold_convert (lntype, rhs);
05370 lr_mask = fold_convert (lntype, lr_mask);
05371 type = lntype;
05372 }
05373 }
05374
05375 if (! all_ones_mask_p (ll_mask, ll_bitsize + rl_bitsize))
05376 lhs = build2 (BIT_AND_EXPR, type, lhs, ll_mask);
05377
05378 if (! all_ones_mask_p (lr_mask, lr_bitsize + rr_bitsize))
05379 rhs = build2 (BIT_AND_EXPR, type, rhs, lr_mask);
05380
05381 return build2 (wanted_code, truth_type, lhs, rhs);
05382 }
05383
05384 return 0;
05385 }
05386
05387
05388
05389
05390
05391 result = const_binop (BIT_AND_EXPR, ll_mask, rl_mask, 0);
05392 if (! integer_zerop (result)
05393 && simple_cst_equal (const_binop (BIT_AND_EXPR, result, l_const, 0),
05394 const_binop (BIT_AND_EXPR, result, r_const, 0)) != 1)
05395 {
05396 if (wanted_code == NE_EXPR)
05397 {
05398 warning (0, "%<or%> of unmatched not-equal tests is always 1");
05399 return constant_boolean_node (true, truth_type);
05400 }
05401 else
05402 {
05403 warning (0, "%<and%> of mutually exclusive equal-tests is always 0");
05404 return constant_boolean_node (false, truth_type);
05405 }
05406 }
05407
05408
05409
05410
05411
05412 result = make_bit_field_ref (ll_inner, lntype, lnbitsize, lnbitpos,
05413 ll_unsignedp || rl_unsignedp);
05414
05415 ll_mask = const_binop (BIT_IOR_EXPR, ll_mask, rl_mask, 0);
05416 if (! all_ones_mask_p (ll_mask, lnbitsize))
05417 result = build2 (BIT_AND_EXPR, lntype, result, ll_mask);
05418
05419 return build2 (wanted_code, truth_type, result,
05420 const_binop (BIT_IOR_EXPR, l_const, r_const, 0));
05421 }
05422
05423
05424
05425
05426 static tree
05427 optimize_minmax_comparison (enum tree_code code, tree type, tree op0, tree op1)
05428 {
05429 tree arg0 = op0;
05430 enum tree_code op_code;
05431 tree comp_const = op1;
05432 tree minmax_const;
05433 int consts_equal, consts_lt;
05434 tree inner;
05435
05436 STRIP_SIGN_NOPS (arg0);
05437
05438 op_code = TREE_CODE (arg0);
05439 minmax_const = TREE_OPERAND (arg0, 1);
05440 consts_equal = tree_int_cst_equal (minmax_const, comp_const);
05441 consts_lt = tree_int_cst_lt (minmax_const, comp_const);
05442 inner = TREE_OPERAND (arg0, 0);
05443
05444
05445 if ((op_code != MIN_EXPR && op_code != MAX_EXPR)
05446 || TREE_CODE (comp_const) != INTEGER_CST
05447 || TREE_CONSTANT_OVERFLOW (comp_const)
05448 || TREE_CODE (minmax_const) != INTEGER_CST
05449 || TREE_CONSTANT_OVERFLOW (minmax_const))
05450 return NULL_TREE;
05451
05452
05453
05454
05455 switch (code)
05456 {
05457 case NE_EXPR: case LT_EXPR: case LE_EXPR:
05458 {
05459 tree tem = optimize_minmax_comparison (invert_tree_comparison (code, false),
05460 type, op0, op1);
05461 if (tem)
05462 return invert_truthvalue (tem);
05463 return NULL_TREE;
05464 }
05465
05466 case GE_EXPR:
05467 return
05468 fold_build2 (TRUTH_ORIF_EXPR, type,
05469 optimize_minmax_comparison
05470 (EQ_EXPR, type, arg0, comp_const),
05471 optimize_minmax_comparison
05472 (GT_EXPR, type, arg0, comp_const));
05473
05474 case EQ_EXPR:
05475 if (op_code == MAX_EXPR && consts_equal)
05476
05477 return fold_build2 (LE_EXPR, type, inner, comp_const);
05478
05479 else if (op_code == MAX_EXPR && consts_lt)
05480
05481 return fold_build2 (EQ_EXPR, type, inner, comp_const);
05482
05483 else if (op_code == MAX_EXPR)
05484
05485 return omit_one_operand (type, integer_zero_node, inner);
05486
05487 else if (consts_equal)
05488
05489 return fold_build2 (GE_EXPR, type, inner, comp_const);
05490
05491 else if (consts_lt)
05492
05493 return omit_one_operand (type, integer_zero_node, inner);
05494
05495 else
05496
05497 return fold_build2 (EQ_EXPR, type, inner, comp_const);
05498
05499 case GT_EXPR:
05500 if (op_code == MAX_EXPR && (consts_equal || consts_lt))
05501
05502
05503 return fold_build2 (GT_EXPR, type, inner, comp_const);
05504
05505 else if (op_code == MAX_EXPR)
05506
05507 return omit_one_operand (type, integer_one_node, inner);
05508
05509 else if (op_code == MIN_EXPR && (consts_equal || consts_lt))
05510
05511
05512 return omit_one_operand (type, integer_zero_node, inner);
05513
05514 else
05515
05516 return fold_build2 (GT_EXPR, type, inner, comp_const);
05517
05518 default:
05519 return NULL_TREE;
05520 }
05521 }
05522
05523
05524
05525
05526
05527
05528
05529
05530
05531
05532
05533
05534
05535
05536
05537
05538
05539
05540
05541
05542
05543
05544
05545 static tree
05546 extract_muldiv (tree t, tree c, enum tree_code code, tree wide_type,
05547 bool *strict_overflow_p)
05548 {
05549
05550
05551
05552
05553
05554 static int depth;
05555 tree ret;
05556
05557 if (depth > 3)
05558 return NULL;
05559
05560 depth++;
05561 ret = extract_muldiv_1 (t, c, code, wide_type, strict_overflow_p);
05562 depth--;
05563
05564 return ret;
05565 }
05566
05567 static tree
05568 extract_muldiv_1 (tree t, tree c, enum tree_code code, tree wide_type,
05569 bool *strict_overflow_p)
05570 {
05571 tree type = TREE_TYPE (t);
05572 enum tree_code tcode = TREE_CODE (t);
05573 tree ctype = (wide_type != 0 && (GET_MODE_SIZE (TYPE_MODE (wide_type))
05574 > GET_MODE_SIZE (TYPE_MODE (type)))
05575 ? wide_type : type);
05576 tree t1, t2;
05577 int same_p = tcode == code;
05578 tree op0 = NULL_TREE, op1 = NULL_TREE;
05579 bool sub_strict_overflow_p;
05580
05581
05582 if (integer_zerop (c))
05583 return NULL_TREE;
05584
05585 if (TREE_CODE_CLASS (tcode) == tcc_unary)
05586 op0 = TREE_OPERAND (t, 0);
05587
05588 if (TREE_CODE_CLASS (tcode) == tcc_binary)
05589 op0 = TREE_OPERAND (t, 0), op1 = TREE_OPERAND (t, 1);
05590
05591
05592
05593 switch (tcode)
05594 {
05595 case INTEGER_CST:
05596
05597
05598 if (code == MULT_EXPR
05599 || integer_zerop (const_binop (TRUNC_MOD_EXPR, t, c, 0)))
05600 return const_binop (code, fold_convert (ctype, t),
05601 fold_convert (ctype, c), 0);
05602 break;
05603
05604 case CONVERT_EXPR: case NON_LVALUE_EXPR: case NOP_EXPR:
05605
05606 if ((COMPARISON_CLASS_P (op0)
05607 || UNARY_CLASS_P (op0)
05608 || BINARY_CLASS_P (op0)
05609 || EXPRESSION_CLASS_P (op0))
05610
05611
05612 && ((TYPE_UNSIGNED (TREE_TYPE (op0))
05613 && ! (TREE_CODE (TREE_TYPE (op0)) == INTEGER_TYPE
05614 && TYPE_IS_SIZETYPE (TREE_TYPE (op0)))
05615 && (GET_MODE_SIZE (TYPE_MODE (ctype))
05616 > GET_MODE_SIZE (TYPE_MODE (TREE_TYPE (op0)))))
05617
05618
05619 || (GET_MODE_SIZE (TYPE_MODE (type))
05620 < GET_MODE_SIZE (TYPE_MODE (TREE_TYPE (op0))))
05621
05622
05623 || (code != MULT_EXPR
05624 && (TYPE_UNSIGNED (ctype)
05625 != TYPE_UNSIGNED (TREE_TYPE (op0))))))
05626 break;
05627
05628
05629
05630
05631 if ((t2 = fold_convert (TREE_TYPE (op0), c)) != 0
05632 && TREE_CODE (t2) == INTEGER_CST
05633 && ! TREE_CONSTANT_OVERFLOW (t2)
05634 && (0 != (t1 = extract_muldiv (op0, t2, code,
05635 code == MULT_EXPR
05636 ? ctype : NULL_TREE,
05637 strict_overflow_p))))
05638 return t1;
05639 break;
05640
05641 case ABS_EXPR:
05642
05643
05644 if (TYPE_UNSIGNED (ctype) && !TYPE_UNSIGNED (type))
05645 {
05646 tree cstype = (*lang_hooks.types.signed_type) (ctype);
05647 if ((t1 = extract_muldiv (op0, c, code, cstype, strict_overflow_p))
05648 != 0)
05649 {
05650 t1 = fold_build1 (tcode, cstype, fold_convert (cstype, t1));
05651 return fold_convert (ctype, t1);
05652 }
05653 break;
05654 }
05655
05656 case NEGATE_EXPR:
05657 if ((t1 = extract_muldiv (op0, c, code, wide_type, strict_overflow_p))
05658 != 0)
05659 return fold_build1 (tcode, ctype, fold_convert (ctype, t1));
05660 break;
05661
05662 case MIN_EXPR: case MAX_EXPR:
05663
05664
05665 if (TYPE_UNSIGNED (ctype) != TYPE_UNSIGNED (type))
05666 break;
05667
05668
05669 sub_strict_overflow_p = false;
05670 if ((t1 = extract_muldiv (op0, c, code, wide_type,
05671 &sub_strict_overflow_p)) != 0
05672 && (t2 = extract_muldiv (op1, c, code, wide_type,
05673 &sub_strict_overflow_p)) != 0)
05674 {
05675 if (tree_int_cst_sgn (c) < 0)
05676 tcode = (tcode == MIN_EXPR ? MAX_EXPR : MIN_EXPR);
05677 if (sub_strict_overflow_p)
05678 *strict_overflow_p = true;
05679 return fold_build2 (tcode, ctype, fold_convert (ctype, t1),
05680 fold_convert (ctype, t2));
05681 }
05682 break;
05683
05684 case LSHIFT_EXPR: case RSHIFT_EXPR:
05685
05686
05687
05688
05689
05690
05691 if (TREE_CODE (op1) == INTEGER_CST
05692 && (tcode == RSHIFT_EXPR || TYPE_UNSIGNED (TREE_TYPE (op0)))
05693
05694
05695 && TYPE_PRECISION (TREE_TYPE (size_one_node)) > TREE_INT_CST_LOW (op1)
05696 && TREE_INT_CST_HIGH (op1) == 0
05697 && 0 != (t1 = fold_convert (ctype,
05698 const_binop (LSHIFT_EXPR,
05699 size_one_node,
05700 op1, 0)))
05701 && ! TREE_OVERFLOW (t1))
05702 return extract_muldiv (build2 (tcode == LSHIFT_EXPR
05703 ? MULT_EXPR : FLOOR_DIV_EXPR,
05704 ctype, fold_convert (ctype, op0), t1),
05705 c, code, wide_type, strict_overflow_p);
05706 break;
05707
05708 case PLUS_EXPR: case MINUS_EXPR:
05709
05710
05711
05712
05713 sub_strict_overflow_p = false;
05714 t1 = extract_muldiv (op0, c, code, wide_type, &sub_strict_overflow_p);
05715 t2 = extract_muldiv (op1, c, code, wide_type, &sub_strict_overflow_p);
05716 if (t1 != 0 && t2 != 0
05717 && (code == MULT_EXPR
05718
05719
05720 || (multiple_of_p (ctype, op0, c)
05721 && multiple_of_p (ctype, op1, c))))
05722 {
05723 if (sub_strict_overflow_p)
05724 *strict_overflow_p = true;
05725 return fold_build2 (tcode, ctype, fold_convert (ctype, t1),
05726 fold_convert (ctype, t2));
05727 }
05728
05729
05730
05731 if (tcode == MINUS_EXPR)
05732 tcode = PLUS_EXPR, op1 = negate_expr (op1);
05733
05734 if (TREE_CODE (op1) != INTEGER_CST)
05735 break;
05736
05737
05738
05739
05740 if (tree_int_cst_sgn (op1) < 0 || tree_int_cst_sgn (c) < 0)
05741 {
05742 if (code == CEIL_DIV_EXPR)
05743 code = FLOOR_DIV_EXPR;
05744 else if (code == FLOOR_DIV_EXPR)
05745 code = CEIL_DIV_EXPR;
05746 else if (code != MULT_EXPR
05747 && code != CEIL_MOD_EXPR && code != FLOOR_MOD_EXPR)
05748 break;
05749 }
05750
05751
05752
05753 if (code == MULT_EXPR
05754 || integer_zerop (const_binop (TRUNC_MOD_EXPR, op1, c, 0)))
05755 {
05756 op1 = const_binop (code, fold_convert (ctype, op1),
05757 fold_convert (ctype, c), 0);
05758
05759 if (op1 == 0
05760 || (TREE_OVERFLOW (op1) && !TYPE_OVERFLOW_WRAPS (ctype)))
05761 break;
05762 }
05763 else
05764 break;
05765
05766
05767
05768
05769 if (TYPE_UNSIGNED (ctype)
05770 && ! (TREE_CODE (ctype) == INTEGER_TYPE && TYPE_IS_SIZETYPE (ctype))
05771 && ctype != type)
05772 break;
05773
05774
05775
05776 if (t1 != 0 && (TREE_CODE (t1) != code || code == MULT_EXPR))
05777 return fold_build2 (tcode, ctype, fold_convert (ctype, t1), op1);
05778
05779
05780
05781
05782 if (code == MULT_EXPR)
05783 return fold_build2 (tcode, ctype,
05784 fold_build2 (code, ctype,
05785 fold_convert (ctype, op0),
05786 fold_convert (ctype, c)),
05787 op1);
05788
05789 break;
05790
05791 case MULT_EXPR:
05792
05793
05794 if ((code == TRUNC_MOD_EXPR || code == CEIL_MOD_EXPR
05795 || code == FLOOR_MOD_EXPR || code == ROUND_MOD_EXPR)
05796 && TREE_CODE (TREE_OPERAND (t, 1)) == INTEGER_CST
05797 && integer_zerop (const_binop (TRUNC_MOD_EXPR, op1, c, 0)))
05798 return omit_one_operand (type, integer_zero_node, op0);
05799
05800
05801
05802 case TRUNC_DIV_EXPR: case CEIL_DIV_EXPR: case FLOOR_DIV_EXPR:
05803 case ROUND_DIV_EXPR: case EXACT_DIV_EXPR:
05804
05805
05806
05807 if (same_p
05808 && (t1 = extract_muldiv (op0, c, code, wide_type,
05809 strict_overflow_p)) != 0)
05810 return fold_build2 (tcode, ctype, fold_convert (ctype, t1),
05811 fold_convert (ctype, op1));
05812 else if (tcode == MULT_EXPR && code == MULT_EXPR
05813 && (t1 = extract_muldiv (op1, c, code, wide_type,
05814 strict_overflow_p)) != 0)
05815 return fold_build2 (tcode, ctype, fold_convert (ctype, op0),
05816 fold_convert (ctype, t1));
05817 else if (TREE_CODE (op1) != INTEGER_CST)
05818 return 0;
05819
05820
05821
05822 if (tcode == code
05823 && 0 != (t1 = const_binop (MULT_EXPR, fold_convert (ctype, op1),
05824 fold_convert (ctype, c), 0))
05825 && ! TREE_OVERFLOW (t1))
05826 return fold_build2 (tcode, ctype, fold_convert (ctype, op0), t1);
05827
05828
05829
05830
05831
05832
05833
05834
05835
05836 if ((TYPE_OVERFLOW_UNDEFINED (ctype)
05837 || (TREE_CODE (ctype) == INTEGER_TYPE && TYPE_IS_SIZETYPE (ctype)))
05838 && ((code == MULT_EXPR && tcode == EXACT_DIV_EXPR)
05839 || (tcode == MULT_EXPR
05840 && code != TRUNC_MOD_EXPR && code != CEIL_MOD_EXPR
05841 && code != FLOOR_MOD_EXPR && code != ROUND_MOD_EXPR)))
05842 {
05843 if (integer_zerop (const_binop (TRUNC_MOD_EXPR, op1, c, 0)))
05844 {
05845 if (TYPE_OVERFLOW_UNDEFINED (ctype))
05846 *strict_overflow_p = true;
05847 return fold_build2 (tcode, ctype, fold_convert (ctype, op0),
05848 fold_convert (ctype,
05849 const_binop (TRUNC_DIV_EXPR,
05850 op1, c, 0)));
05851 }
05852 else if (integer_zerop (const_binop (TRUNC_MOD_EXPR, c, op1, 0)))
05853 {
05854 if (TYPE_OVERFLOW_UNDEFINED (ctype))
05855 *strict_overflow_p = true;
05856 return fold_build2 (code, ctype, fold_convert (ctype, op0),
05857 fold_convert (ctype,
05858 const_binop (TRUNC_DIV_EXPR,
05859 c, op1, 0)));
05860 }
05861 }
05862 break;
05863
05864 default:
05865 break;
05866 }
05867
05868 return 0;
05869 }
05870
05871
05872
05873
05874 tree
05875 constant_boolean_node (int value, tree type)
05876 {
05877 if (type == integer_type_node)
05878 return value ? integer_one_node : integer_zero_node;
05879 else if (type == boolean_type_node)
05880 return value ? boolean_true_node : boolean_false_node;
05881 else
05882 return build_int_cst (type, value);
05883 }
05884
05885
05886
05887
05888
05889
05890
05891
05892
05893 static bool
05894 extract_array_ref (tree expr, tree *base, tree *offset)
05895 {
05896
05897
05898
05899 if (TREE_CODE (expr) == PLUS_EXPR)
05900 {
05901 tree op0 = TREE_OPERAND (expr, 0);
05902 tree inner_base, dummy1;
05903
05904
05905 STRIP_NOPS (op0);
05906 if (extract_array_ref (op0, &inner_base, &dummy1))
05907 {
05908 *base = inner_base;
05909 if (dummy1 == NULL_TREE)
05910 *offset = TREE_OPERAND (expr, 1);
05911 else
05912 *offset = fold_build2 (PLUS_EXPR, TREE_TYPE (expr),
05913 dummy1, TREE_OPERAND (expr, 1));
05914 return true;
05915 }
05916 }
05917
05918
05919
05920
05921
05922 else if (TREE_CODE (expr) == ADDR_EXPR)
05923 {
05924 tree op0 = TREE_OPERAND (expr, 0);
05925 if (TREE_CODE (op0) == ARRAY_REF)
05926 {
05927 tree idx = TREE_OPERAND (op0, 1);
05928 *base = TREE_OPERAND (op0, 0);
05929 *offset = fold_build2 (MULT_EXPR, TREE_TYPE (idx), idx,
05930 array_ref_element_size (op0));
05931 }
05932 else
05933 {
05934
05935 if (TREE_CODE (TREE_TYPE (op0)) == ARRAY_TYPE)
05936 *base = TREE_OPERAND (expr, 0);
05937 else
05938 *base = expr;
05939 *offset = NULL_TREE;
05940 }
05941 return true;
05942 }
05943
05944 else if (SSA_VAR_P (expr)
05945 && TREE_CODE (TREE_TYPE (expr)) == POINTER_TYPE)
05946 {
05947 *base = expr;
05948 *offset = NULL_TREE;
05949 return true;
05950 }
05951
05952 return false;
05953 }
05954
05955
05956
05957
05958
05959
05960
05961
05962
05963
05964
05965 static tree
05966 fold_binary_op_with_conditional_arg (enum tree_code code,
05967 tree type, tree op0, tree op1,
05968 tree cond, tree arg, int cond_first_p)
05969 {
05970 tree cond_type = cond_first_p ? TREE_TYPE (op0) : TREE_TYPE (op1);
05971 tree arg_type = cond_first_p ? TREE_TYPE (op1) : TREE_TYPE (op0);
05972 tree test, true_value, false_value;
05973 tree lhs = NULL_TREE;
05974 tree rhs = NULL_TREE;
05975
05976
05977
05978
05979 if (!TREE_CONSTANT (arg))
05980 return NULL_TREE;
05981
05982 if (TREE_CODE (cond) == COND_EXPR)
05983 {
05984 test = TREE_OPERAND (cond, 0);
05985 true_value = TREE_OPERAND (cond, 1);
05986 false_value = TREE_OPERAND (cond, 2);
05987
05988
05989
05990 if (VOID_TYPE_P (TREE_TYPE (true_value)))
05991 lhs = true_value;
05992 if (VOID_TYPE_P (TREE_TYPE (false_value)))
05993 rhs = false_value;
05994 }
05995 else
05996 {
05997 tree testtype = TREE_TYPE (cond);
05998 test = cond;
05999 true_value = constant_boolean_node (true, testtype);
06000 false_value = constant_boolean_node (false, testtype);
06001 }
06002
06003 arg = fold_convert (arg_type, arg);
06004 if (lhs == 0)
06005 {
06006 true_value = fold_convert (cond_type, true_value);
06007 if (cond_first_p)
06008 lhs = fold_build2 (code, type, true_value, arg);
06009 else
06010 lhs = fold_build2 (code, type, arg, true_value);
06011 }
06012 if (rhs == 0)
06013 {
06014 false_value = fold_convert (cond_type, false_value);
06015 if (cond_first_p)
06016 rhs = fold_build2 (code, type, false_value, arg);
06017 else
06018 rhs = fold_build2 (code, type, arg, false_value);
06019 }
06020
06021 test = fold_build3 (COND_EXPR, type, test, lhs, rhs);
06022 return fold_convert (type, test);
06023 }
06024
06025
06026
06027
06028
06029
06030
06031
06032
06033
06034
06035
06036
06037
06038 static bool
06039 fold_real_zero_addition_p (tree type, tree addend, int negate)
06040 {
06041 if (!real_zerop (addend))
06042 return false;
06043
06044
06045 if (HONOR_SNANS (TYPE_MODE (type)))
06046 return false;
06047
06048
06049 if (!HONOR_SIGNED_ZEROS (TYPE_MODE (type)))
06050 return true;
06051
06052
06053 if (TREE_CODE (addend) == REAL_CST
06054 && REAL_VALUE_MINUS_ZERO (TREE_REAL_CST (addend)))
06055 negate = !negate;
06056
06057
06058
06059
06060
06061 return negate && !HONOR_SIGN_DEPENDENT_ROUNDING (TYPE_MODE (type));
06062 }
06063
06064
06065
06066
06067
06068
06069
06070
06071
06072
06073
06074
06075 static tree
06076 fold_mathfn_compare (enum built_in_function fcode, enum tree_code code,
06077 tree type, tree arg0, tree arg1)
06078 {
06079 REAL_VALUE_TYPE c;
06080
06081 if (BUILTIN_SQRT_P (fcode))
06082 {
06083 tree arg = TREE_VALUE (TREE_OPERAND (arg0, 1));
06084 enum machine_mode mode = TYPE_MODE (TREE_TYPE (arg0));
06085
06086 c = TREE_REAL_CST (arg1);
06087 if (REAL_VALUE_NEGATIVE (c))
06088 {
06089
06090 if (code == EQ_EXPR || code == LT_EXPR || code == LE_EXPR)
06091 return omit_one_operand (type, integer_zero_node, arg);
06092
06093
06094
06095 if (code == NE_EXPR || !HONOR_NANS (mode))
06096 return omit_one_operand (type, integer_one_node, arg);
06097
06098
06099 return fold_build2 (GE_EXPR, type, arg,
06100 build_real (TREE_TYPE (arg), dconst0));
06101 }
06102 else if (code == GT_EXPR || code == GE_EXPR)
06103 {
06104 REAL_VALUE_TYPE c2;
06105
06106 REAL_ARITHMETIC (c2, MULT_EXPR, c, c);
06107 real_convert (&c2, mode, &c2);
06108
06109 if (REAL_VALUE_ISINF (c2))
06110 {
06111
06112 if (HONOR_INFINITIES (mode))
06113 return fold_build2 (EQ_EXPR, type, arg,
06114 build_real (TREE_TYPE (arg), c2));
06115
06116
06117
06118 return omit_one_operand (type, integer_zero_node, arg);
06119 }
06120
06121
06122 return fold_build2 (code, type, arg,
06123 build_real (TREE_TYPE (arg), c2));
06124 }
06125 else if (code == LT_EXPR || code == LE_EXPR)
06126 {
06127 REAL_VALUE_TYPE c2;
06128
06129 REAL_ARITHMETIC (c2, MULT_EXPR, c, c);
06130 real_convert (&c2, mode, &c2);
06131
06132 if (REAL_VALUE_ISINF (c2))
06133 {
06134
06135
06136 if (! HONOR_NANS (mode) && ! HONOR_INFINITIES (mode))
06137 return omit_one_operand (type, integer_one_node, arg);
06138
06139
06140
06141 if (! HONOR_NANS (mode))
06142 return fold_build2 (NE_EXPR, type, arg,
06143 build_real (TREE_TYPE (arg), c2));
06144
06145
06146
06147 if (! HONOR_INFINITIES (mode))
06148 return fold_build2 (GE_EXPR, type, arg,
06149 build_real (TREE_TYPE (arg), dconst0));
06150
06151
06152 if (lang_hooks.decls.global_bindings_p () != 0
06153 || CONTAINS_PLACEHOLDER_P (arg))
06154 return NULL_TREE;
06155
06156 arg = save_expr (arg);
06157 return fold_build2 (TRUTH_ANDIF_EXPR, type,
06158 fold_build2 (GE_EXPR, type, arg,
06159 build_real (TREE_TYPE (arg),
06160 dconst0)),
06161 fold_build2 (NE_EXPR, type, arg,
06162 build_real (TREE_TYPE (arg),
06163 c2)));
06164 }
06165
06166
06167 if (! HONOR_NANS (mode))
06168 return fold_build2 (code, type, arg,
06169 build_real (TREE_TYPE (arg), c2));
06170
06171
06172 if (lang_hooks.decls.global_bindings_p () == 0
06173 && ! CONTAINS_PLACEHOLDER_P (arg))
06174 {
06175 arg = save_expr (arg);
06176 return fold_build2 (TRUTH_ANDIF_EXPR, type,
06177 fold_build2 (GE_EXPR, type, arg,
06178 build_real (TREE_TYPE (arg),
06179 dconst0)),
06180 fold_build2 (code, type, arg,
06181 build_real (TREE_TYPE (arg),
06182 c2)));
06183 }
06184 }
06185 }
06186
06187 return NULL_TREE;
06188 }
06189
06190
06191
06192
06193
06194
06195
06196
06197
06198
06199
06200 static tree
06201 fold_inf_compare (enum tree_code code, tree type, tree arg0, tree arg1)
06202 {
06203 enum machine_mode mode;
06204 REAL_VALUE_TYPE max;
06205 tree temp;
06206 bool neg;
06207
06208 mode = TYPE_MODE (TREE_TYPE (arg0));
06209
06210
06211 neg = REAL_VALUE_NEGATIVE (TREE_REAL_CST (arg1));
06212 if (neg)
06213 code = swap_tree_comparison (code);
06214
06215 switch (code)
06216 {
06217 case GT_EXPR:
06218
06219 if (HONOR_SNANS (mode))
06220 return NULL_TREE;
06221 return omit_one_operand (type, integer_zero_node, arg0);
06222
06223 case LE_EXPR:
06224
06225 if (! HONOR_NANS (mode))
06226 return omit_one_operand (type, integer_one_node, arg0);
06227
06228
06229 if (lang_hooks.decls.global_bindings_p () == 0
06230 && ! CONTAINS_PLACEHOLDER_P (arg0))
06231 {
06232 arg0 = save_expr (arg0);
06233 return fold_build2 (EQ_EXPR, type, arg0, arg0);
06234 }
06235 break;
06236
06237 case EQ_EXPR:
06238 case GE_EXPR:
06239
06240 real_maxval (&max, neg, mode);
06241 return fold_build2 (neg ? LT_EXPR : GT_EXPR, type,
06242 arg0, build_real (TREE_TYPE (arg0), max));
06243
06244 case LT_EXPR:
06245
06246 real_maxval (&max, neg, mode);
06247 return fold_build2 (neg ? GE_EXPR : LE_EXPR, type,
06248 arg0, build_real (TREE_TYPE (arg0), max));
06249
06250 case NE_EXPR:
06251
06252 real_maxval (&max, neg, mode);
06253 if (! HONOR_NANS (mode))
06254 return fold_build2 (neg ? GE_EXPR : LE_EXPR, type,
06255 arg0, build_real (TREE_TYPE (arg0), max));
06256
06257
06258
06259 if (in_gimple_form)
06260 return NULL_TREE;
06261
06262 temp = fold_build2 (neg ? LT_EXPR : GT_EXPR, type,
06263 arg0, build_real (TREE_TYPE (arg0), max));
06264 return fold_build1 (TRUTH_NOT_EXPR, type, temp);
06265
06266 default:
06267 break;
06268 }
06269
06270 return NULL_TREE;
06271 }
06272
06273
06274
06275
06276
06277
06278
06279
06280
06281
06282
06283
06284 static tree
06285 fold_div_compare (enum tree_code code, tree type, tree arg0, tree arg1)
06286 {
06287 tree prod, tmp, hi, lo;
06288 tree arg00 = TREE_OPERAND (arg0, 0);
06289 tree arg01 = TREE_OPERAND (arg0, 1);
06290 unsigned HOST_WIDE_INT lpart;
06291 HOST_WIDE_INT hpart;
06292 bool unsigned_p = TYPE_UNSIGNED (TREE_TYPE (arg0));
06293 bool neg_overflow;
06294 int overflow;
06295
06296
06297
06298 overflow = mul_double_with_sign (TREE_INT_CST_LOW (arg01),
06299 TREE_INT_CST_HIGH (arg01),
06300 TREE_INT_CST_LOW (arg1),
06301 TREE_INT_CST_HIGH (arg1),
06302 &lpart, &hpart, unsigned_p);
06303 prod = build_int_cst_wide (TREE_TYPE (arg00), lpart, hpart);
06304 prod = force_fit_type (prod, -1, overflow, false);
06305 neg_overflow = false;
06306
06307 if (unsigned_p)
06308 {
06309 tmp = int_const_binop (MINUS_EXPR, arg01, integer_one_node, 0);
06310 lo = prod;
06311
06312
06313 overflow = add_double_with_sign (TREE_INT_CST_LOW (prod),
06314 TREE_INT_CST_HIGH (prod),
06315 TREE_INT_CST_LOW (tmp),
06316 TREE_INT_CST_HIGH (tmp),
06317 &lpart, &hpart, unsigned_p);
06318 hi = build_int_cst_wide (TREE_TYPE (arg00), lpart, hpart);
06319 hi = force_fit_type (hi, -1, overflow | TREE_OVERFLOW (prod),
06320 TREE_CONSTANT_OVERFLOW (prod));
06321 }
06322 else if (tree_int_cst_sgn (arg01) >= 0)
06323 {
06324 tmp = int_const_binop (MINUS_EXPR, arg01, integer_one_node, 0);
06325 switch (tree_int_cst_sgn (arg1))
06326 {
06327 case -1:
06328 neg_overflow = true;
06329 lo = int_const_binop (MINUS_EXPR, prod, tmp, 0);
06330 hi = prod;
06331 break;
06332
06333 case 0:
06334 lo = fold_negate_const (tmp, TREE_TYPE (arg0));
06335 hi = tmp;
06336 break;
06337
06338 case 1:
06339 hi = int_const_binop (PLUS_EXPR, prod, tmp, 0);
06340 lo = prod;
06341 break;
06342
06343 default:
06344 gcc_unreachable ();
06345 }
06346 }
06347 else
06348 {
06349
06350 code = swap_tree_comparison (code);
06351
06352 tmp = int_const_binop (PLUS_EXPR, arg01, integer_one_node, 0);
06353 switch (tree_int_cst_sgn (arg1))
06354 {
06355 case -1:
06356 hi = int_const_binop (MINUS_EXPR, prod, tmp, 0);
06357 lo = prod;
06358 break;
06359
06360 case 0:
06361 hi = fold_negate_const (tmp, TREE_TYPE (arg0));
06362 lo = tmp;
06363 break;
06364
06365 case 1:
06366 neg_overflow = true;
06367 lo = int_const_binop (PLUS_EXPR, prod, tmp, 0);
06368 hi = prod;
06369 break;
06370
06371 default:
06372 gcc_unreachable ();
06373 }
06374 }
06375
06376 switch (code)
06377 {
06378 case EQ_EXPR:
06379 if (TREE_OVERFLOW (lo) && TREE_OVERFLOW (hi))
06380 return omit_one_operand (type, integer_zero_node, arg00);
06381 if (TREE_OVERFLOW (hi))
06382 return fold_build2 (GE_EXPR, type, arg00, lo);
06383 if (TREE_OVERFLOW (lo))
06384 return fold_build2 (LE_EXPR, type, arg00, hi);
06385 return build_range_check (type, arg00, 1, lo, hi);
06386
06387 case NE_EXPR:
06388 if (TREE_OVERFLOW (lo) && TREE_OVERFLOW (hi))
06389 return omit_one_operand (type, integer_one_node, arg00);
06390 if (TREE_OVERFLOW (hi))
06391 return fold_build2 (LT_EXPR, type, arg00, lo);
06392 if (TREE_OVERFLOW (lo))
06393 return fold_build2 (GT_EXPR, type, arg00, hi);
06394 return build_range_check (type, arg00, 0, lo, hi);
06395
06396 case LT_EXPR:
06397 if (TREE_OVERFLOW (lo))
06398 {
06399 tmp = neg_overflow ? integer_zero_node : integer_one_node;
06400 return omit_one_operand (type, tmp, arg00);
06401 }
06402 return fold_build2 (LT_EXPR, type, arg00, lo);
06403
06404 case LE_EXPR:
06405 if (TREE_OVERFLOW (hi))
06406 {
06407 tmp = neg_overflow ? integer_zero_node : integer_one_node;
06408 return omit_one_operand (type, tmp, arg00);
06409 }
06410 return fold_build2 (LE_EXPR, type, arg00, hi);
06411
06412 case GT_EXPR:
06413 if (TREE_OVERFLOW (hi))
06414 {
06415 tmp = neg_overflow ? integer_one_node : integer_zero_node;
06416 return omit_one_operand (type, tmp, arg00);
06417 }
06418 return fold_build2 (GT_EXPR, type, arg00, hi);
06419
06420 case GE_EXPR:
06421 if (TREE_OVERFLOW (lo))
06422 {
06423 tmp = neg_overflow ? integer_one_node : integer_zero_node;
06424 return omit_one_operand (type, tmp, arg00);
06425 }
06426 return fold_build2 (GE_EXPR, type, arg00, lo);
06427
06428 default:
06429 break;
06430 }
06431
06432 return NULL_TREE;
06433 }
06434
06435
06436
06437
06438
06439
06440
06441 static tree
06442 fold_single_bit_test_into_sign_test (enum tree_code code, tree arg0, tree arg1,
06443 tree result_type)
06444 {
06445
06446 if ((code == NE_EXPR || code == EQ_EXPR)
06447 && TREE_CODE (arg0) == BIT_AND_EXPR && integer_zerop (arg1)
06448 && integer_pow2p (TREE_OPERAND (arg0, 1)))
06449 {
06450
06451
06452 tree arg00 = sign_bit_p (TREE_OPERAND (arg0, 0), TREE_OPERAND (arg0, 1));
06453
06454 if (arg00 != NULL_TREE
06455
06456
06457 && TYPE_PRECISION (TREE_TYPE (arg00))
06458 == GET_MODE_BITSIZE (TYPE_MODE (TREE_TYPE (arg00))))
06459 {
06460 tree stype = lang_hooks.types.signed_type (TREE_TYPE (arg00));
06461 return fold_build2 (code == EQ_EXPR ? GE_EXPR : LT_EXPR,
06462 result_type, fold_convert (stype, arg00),
06463 build_int_cst (stype, 0));
06464 }
06465 }
06466
06467 return NULL_TREE;
06468 }
06469
06470
06471
06472
06473
06474
06475 tree
06476 fold_single_bit_test (enum tree_code code, tree arg0, tree arg1,
06477 tree result_type)
06478 {
06479
06480 if ((code == NE_EXPR || code == EQ_EXPR)
06481 && TREE_CODE (arg0) == BIT_AND_EXPR && integer_zerop (arg1)
06482 && integer_pow2p (TREE_OPERAND (arg0, 1)))
06483 {
06484 tree inner = TREE_OPERAND (arg0, 0);
06485 tree type = TREE_TYPE (arg0);
06486 int bitnum = tree_log2 (TREE_OPERAND (arg0, 1));
06487 enum machine_mode operand_mode = TYPE_MODE (type);
06488 int ops_unsigned;
06489 tree signed_type, unsigned_type, intermediate_type;
06490 tree tem;
06491
06492
06493
06494 tem = fold_single_bit_test_into_sign_test (code, arg0, arg1,
06495 result_type);
06496 if (tem)
06497 return tem;
06498
06499
06500
06501
06502
06503
06504
06505 if (TREE_CODE (inner) == RSHIFT_EXPR
06506 && TREE_CODE (TREE_OPERAND (inner, 1)) == INTEGER_CST
06507 && TREE_INT_CST_HIGH (TREE_OPERAND (inner, 1)) == 0
06508 && bitnum < TYPE_PRECISION (type)
06509 && 0 > compare_tree_int (TREE_OPERAND (inner, 1),
06510 bitnum - TYPE_PRECISION (type)))
06511 {
06512 bitnum += TREE_INT_CST_LOW (TREE_OPERAND (inner, 1));
06513 inner = TREE_OPERAND (inner, 0);
06514 }
06515
06516
06517
06518
06519 #ifdef LOAD_EXTEND_OP
06520 ops_unsigned = (LOAD_EXTEND_OP (operand_mode) == SIGN_EXTEND
06521 && !flag_syntax_only) ? 0 : 1;
06522 #else
06523 ops_unsigned = 1;
06524 #endif
06525
06526 signed_type = lang_hooks.types.type_for_mode (operand_mode, 0);
06527 unsigned_type = lang_hooks.types.type_for_mode (operand_mode, 1);
06528 intermediate_type = ops_unsigned ? unsigned_type : signed_type;
06529 inner = fold_convert (intermediate_type, inner);
06530
06531 if (bitnum != 0)
06532 inner = build2 (RSHIFT_EXPR, intermediate_type,
06533 inner, size_int (bitnum));
06534
06535 if (code == EQ_EXPR)
06536 inner = fold_build2 (BIT_XOR_EXPR, intermediate_type,
06537 inner, integer_one_node);
06538
06539
06540 inner = build2 (BIT_AND_EXPR, intermediate_type,
06541 inner, integer_one_node);
06542
06543
06544 inner = fold_convert (result_type, inner);
06545
06546 return inner;
06547 }
06548 return NULL_TREE;
06549 }
06550
06551
06552
06553
06554 static bool
06555 reorder_operands_p (tree arg0, tree arg1)
06556 {
06557 if (! flag_evaluation_order)
06558 return true;
06559 if (TREE_CONSTANT (arg0) || TREE_CONSTANT (arg1))
06560 return true;
06561 return ! TREE_SIDE_EFFECTS (arg0)
06562 && ! TREE_SIDE_EFFECTS (arg1);
06563 }
06564
06565
06566
06567
06568
06569
06570 bool
06571 tree_swap_operands_p (tree arg0, tree arg1, bool reorder)
06572 {
06573 STRIP_SIGN_NOPS (arg0);
06574 STRIP_SIGN_NOPS (arg1);
06575
06576 if (TREE_CODE (arg1) == INTEGER_CST)
06577 return 0;
06578 if (TREE_CODE (arg0) == INTEGER_CST)
06579 return 1;
06580
06581 if (TREE_CODE (arg1) == REAL_CST)
06582 return 0;
06583 if (TREE_CODE (arg0) == REAL_CST)
06584 return 1;
06585
06586 if (TREE_CODE (arg1) == COMPLEX_CST)
06587 return 0;
06588 if (TREE_CODE (arg0) == COMPLEX_CST)
06589 return 1;
06590
06591 if (TREE_CONSTANT (arg1))
06592 return 0;
06593 if (TREE_CONSTANT (arg0))
06594 return 1;
06595
06596 if (optimize_size)
06597 return 0;
06598
06599 if (reorder && flag_evaluation_order
06600 && (TREE_SIDE_EFFECTS (arg0) || TREE_SIDE_EFFECTS (arg1)))
06601 return 0;
06602
06603 if (DECL_P (arg1))
06604 return 0;
06605 if (DECL_P (arg0))
06606 return 1;
06607
06608
06609
06610
06611
06612 if (TREE_CODE (arg0) == SSA_NAME
06613 && TREE_CODE (arg1) == SSA_NAME
06614 && SSA_NAME_VERSION (arg0) > SSA_NAME_VERSION (arg1))
06615 return 1;
06616
06617 return 0;
06618 }
06619
06620
06621
06622
06623 static tree
06624 fold_widened_comparison (enum tree_code code, tree type, tree arg0, tree arg1)
06625 {
06626 tree arg0_unw = get_unwidened (arg0, NULL_TREE);
06627 tree arg1_unw;
06628 tree shorter_type, outer_type;
06629 tree min, max;
06630 bool above, below;
06631
06632 if (arg0_unw == arg0)
06633 return NULL_TREE;
06634 shorter_type = TREE_TYPE (arg0_unw);
06635
06636 #ifdef HAVE_canonicalize_funcptr_for_compare
06637
06638
06639 if (HAVE_canonicalize_funcptr_for_compare
06640 && TREE_CODE (shorter_type) == POINTER_TYPE
06641 && TREE_CODE (TREE_TYPE (shorter_type)) == FUNCTION_TYPE)
06642 return NULL_TREE;
06643 #endif
06644
06645 if (TYPE_PRECISION (TREE_TYPE (arg0)) <= TYPE_PRECISION (shorter_type))
06646 return NULL_TREE;
06647
06648 arg1_unw = get_unwidened (arg1, shorter_type);
06649
06650
06651 if ((code == EQ_EXPR || code == NE_EXPR
06652 || TYPE_UNSIGNED (TREE_TYPE (arg0)) == TYPE_UNSIGNED (shorter_type))
06653 && (TREE_TYPE (arg1_unw) == shorter_type
06654 || (TREE_CODE (arg1_unw) == INTEGER_CST
06655 && (TREE_CODE (shorter_type) == INTEGER_TYPE
06656 || TREE_CODE (shorter_type) == BOOLEAN_TYPE)
06657 && int_fits_type_p (arg1_unw, shorter_type))))
06658 return fold_build2 (code, type, arg0_unw,
06659 fold_convert (shorter_type, arg1_unw));
06660
06661 if (TREE_CODE (arg1_unw) != INTEGER_CST
06662 || TREE_CODE (shorter_type) != INTEGER_TYPE
06663 || !int_fits_type_p (arg1_unw, shorter_type))
06664 return NULL_TREE;
06665
06666
06667
06668 outer_type = TREE_TYPE (arg1_unw);
06669 min = lower_bound_in_type (outer_type, shorter_type);
06670 max = upper_bound_in_type (outer_type, shorter_type);
06671
06672 above = integer_nonzerop (fold_relational_const (LT_EXPR, type,
06673 max, arg1_unw));
06674 below = integer_nonzerop (fold_relational_const (LT_EXPR, type,
06675 arg1_unw, min));
06676
06677 switch (code)
06678 {
06679 case EQ_EXPR:
06680 if (above || below)
06681 return omit_one_operand (type, integer_zero_node, arg0);
06682 break;
06683
06684 case NE_EXPR:
06685 if (above || below)
06686 return omit_one_operand (type, integer_one_node, arg0);
06687 break;
06688
06689 case LT_EXPR:
06690 case LE_EXPR:
06691 if (above)
06692 return omit_one_operand (type, integer_one_node, arg0);
06693 else if (below)
06694 return omit_one_operand (type, integer_zero_node, arg0);
06695
06696 case GT_EXPR:
06697 case GE_EXPR:
06698 if (above)
06699 return omit_one_operand (type, integer_zero_node, arg0);
06700 else if (below)
06701 return omit_one_operand (type, integer_one_node, arg0);
06702
06703 default:
06704 break;
06705 }
06706
06707 return NULL_TREE;
06708 }
06709
06710
06711
06712
06713 static tree
06714 fold_sign_changed_comparison (enum tree_code code, tree type,
06715 tree arg0, tree arg1)
06716 {
06717 tree arg0_inner, tmp;
06718 tree inner_type, outer_type;
06719
06720 if (TREE_CODE (arg0) != NOP_EXPR
06721 && TREE_CODE (arg0) != CONVERT_EXPR)
06722 return NULL_TREE;
06723
06724 outer_type = TREE_TYPE (arg0);
06725 arg0_inner = TREE_OPERAND (arg0, 0);
06726 inner_type = TREE_TYPE (arg0_inner);
06727
06728 #ifdef HAVE_canonicalize_funcptr_for_compare
06729
06730
06731 if (HAVE_canonicalize_funcptr_for_compare
06732 && TREE_CODE (inner_type) == POINTER_TYPE
06733 && TREE_CODE (TREE_TYPE (inner_type)) == FUNCTION_TYPE)
06734 return NULL_TREE;
06735 #endif
06736
06737 if (TYPE_PRECISION (inner_type) != TYPE_PRECISION (outer_type))
06738 return NULL_TREE;
06739
06740 if (TREE_CODE (arg1) != INTEGER_CST
06741 && !((TREE_CODE (arg1) == NOP_EXPR
06742 || TREE_CODE (arg1) == CONVERT_EXPR)
06743 && TREE_TYPE (TREE_OPERAND (arg1, 0)) == inner_type))
06744 return NULL_TREE;
06745
06746 if (TYPE_UNSIGNED (inner_type) != TYPE_UNSIGNED (outer_type)
06747 && code != NE_EXPR
06748 && code != EQ_EXPR)
06749 return NULL_TREE;
06750
06751 if (TREE_CODE (arg1) == INTEGER_CST)
06752 {
06753 tmp = build_int_cst_wide (inner_type,
06754 TREE_INT_CST_LOW (arg1),
06755 TREE_INT_CST_HIGH (arg1));
06756 arg1 = force_fit_type (tmp, 0,
06757 TREE_OVERFLOW (arg1),
06758 TREE_CONSTANT_OVERFLOW (arg1));
06759 }
06760 else
06761 arg1 = fold_convert (inner_type, arg1);
06762
06763 return fold_build2 (code, type, arg0_inner, arg1);
06764 }
06765
06766
06767
06768
06769
06770
06771
06772
06773 static tree
06774 try_move_mult_to_index (enum tree_code code, tree addr, tree op1)
06775 {
06776 tree s, delta, step;
06777 tree ref = TREE_OPERAND (addr, 0), pref;
06778 tree ret, pos;
06779 tree itype;
06780
06781
06782
06783 if (TREE_CODE (op1) == MULT_EXPR)
06784 {
06785 tree arg0 = TREE_OPERAND (op1, 0), arg1 = TREE_OPERAND (op1, 1);
06786
06787 STRIP_NOPS (arg0);
06788 STRIP_NOPS (arg1);
06789
06790 if (TREE_CODE (arg0) == INTEGER_CST)
06791 {
06792 s = arg0;
06793 delta = arg1;
06794 }
06795 else if (TREE_CODE (arg1) == INTEGER_CST)
06796 {
06797 s = arg1;
06798 delta = arg0;
06799 }
06800 else
06801 return NULL_TREE;
06802 }
06803 else if (TREE_CODE (op1) == INTEGER_CST)
06804 {
06805 delta = op1;
06806 s = NULL_TREE;
06807 }
06808 else
06809 {
06810
06811 delta = op1;
06812 s = integer_one_node;
06813 }
06814
06815 for (;; ref = TREE_OPERAND (ref, 0))
06816 {
06817 if (TREE_CODE (ref) == ARRAY_REF)
06818 {
06819 itype = TYPE_DOMAIN (TREE_TYPE (TREE_OPERAND (ref, 0)));
06820 if (! itype)
06821 continue;
06822
06823 step = array_ref_element_size (ref);
06824 if (TREE_CODE (step) != INTEGER_CST)
06825 continue;
06826
06827 if (s)
06828 {
06829 if (! tree_int_cst_equal (step, s))
06830 continue;
06831 }
06832 else
06833 {
06834
06835 tree tmp = div_if_zero_remainder (EXACT_DIV_EXPR, delta, step);
06836 if (! tmp)
06837 continue;
06838 delta = tmp;
06839 }
06840
06841 break;
06842 }
06843
06844 if (!handled_component_p (ref))
06845 return NULL_TREE;
06846 }
06847
06848
06849
06850
06851 pref = TREE_OPERAND (addr, 0);
06852 ret = copy_node (pref);
06853 pos = ret;
06854
06855 while (pref != ref)
06856 {
06857 pref = TREE_OPERAND (pref, 0);
06858 TREE_OPERAND (pos, 0) = copy_node (pref);
06859 pos = TREE_OPERAND (pos, 0);
06860 }
06861
06862 TREE_OPERAND (pos, 1) = fold_build2 (code, itype,
06863 fold_convert (itype,
06864 TREE_OPERAND (pos, 1)),
06865 fold_convert (itype, delta));
06866
06867 return fold_build1 (ADDR_EXPR, TREE_TYPE (addr), ret);
06868 }
06869
06870
06871
06872
06873
06874
06875 static tree
06876 fold_to_nonsharp_ineq_using_bound (tree ineq, tree bound)
06877 {
06878 tree a, typea, type = TREE_TYPE (ineq), a1, diff, y;
06879
06880 if (TREE_CODE (bound) == LT_EXPR)
06881 a = TREE_OPERAND (bound, 0);
06882 else if (TREE_CODE (bound) == GT_EXPR)
06883 a = TREE_OPERAND (bound, 1);
06884 else
06885 return NULL_TREE;
06886
06887 typea = TREE_TYPE (a);
06888 if (!INTEGRAL_TYPE_P (typea)
06889 && !POINTER_TYPE_P (typea))
06890 return NULL_TREE;
06891
06892 if (TREE_CODE (ineq) == LT_EXPR)
06893 {
06894 a1 = TREE_OPERAND (ineq, 1);
06895 y = TREE_OPERAND (ineq, 0);
06896 }
06897 else if (TREE_CODE (ineq) == GT_EXPR)
06898 {
06899 a1 = TREE_OPERAND (ineq, 0);
06900 y = TREE_OPERAND (ineq, 1);
06901 }
06902 else
06903 return NULL_TREE;
06904
06905 if (TREE_TYPE (a1) != typea)
06906 return NULL_TREE;
06907
06908 diff = fold_build2 (MINUS_EXPR, typea, a1, a);
06909 if (!integer_onep (diff))
06910 return NULL_TREE;
06911
06912 return fold_build2 (GE_EXPR, type, a, y);
06913 }
06914
06915
06916
06917
06918 static tree
06919 fold_plusminus_mult_expr (enum tree_code code, tree type, tree arg0, tree arg1)
06920 {
06921 tree arg00, arg01, arg10, arg11;
06922 tree alt0 = NULL_TREE, alt1 = NULL_TREE, same;
06923
06924
06925
06926
06927
06928
06929
06930 if (TREE_CODE (arg0) == MULT_EXPR)
06931 {
06932 arg00 = TREE_OPERAND (arg0, 0);
06933 arg01 = TREE_OPERAND (arg0, 1);
06934 }
06935 else
06936 {
06937 arg00 = arg0;
06938 arg01 = build_one_cst (type);
06939 }
06940 if (TREE_CODE (arg1) == MULT_EXPR)
06941 {
06942 arg10 = TREE_OPERAND (arg1, 0);
06943 arg11 = TREE_OPERAND (arg1, 1);
06944 }
06945 else
06946 {
06947 arg10 = arg1;
06948 arg11 = build_one_cst (type);
06949 }
06950 same = NULL_TREE;
06951
06952 if (operand_equal_p (arg01, arg11, 0))
06953 same = arg01, alt0 = arg00, alt1 = arg10;
06954 else if (operand_equal_p (arg00, arg10, 0))
06955 same = arg00, alt0 = arg01, alt1 = arg11;
06956 else if (operand_equal_p (arg00, arg11, 0))
06957 same = arg00, alt0 = arg01, alt1 = arg10;
06958 else if (operand_equal_p (arg01, arg10, 0))
06959 same = arg01, alt0 = arg00, alt1 = arg11;
06960
06961
06962
06963
06964 else if (host_integerp (arg01, 0)
06965 && host_integerp (arg11, 0))
06966 {
06967 HOST_WIDE_INT int01, int11, tmp;
06968 bool swap = false;
06969 tree maybe_same;
06970 int01 = TREE_INT_CST_LOW (arg01);
06971 int11 = TREE_INT_CST_LOW (arg11);
06972
06973
06974 if ((int01 >= 0 ? int01 : -int01)
06975 < (int11 >= 0 ? int11 : -int11))
06976 {
06977 tmp = int01, int01 = int11, int11 = tmp;
06978 alt0 = arg00, arg00 = arg10, arg10 = alt0;
06979 maybe_same = arg01;
06980 swap = true;
06981 }
06982 else
06983 maybe_same = arg11;
06984
06985 if (exact_log2 (int11) > 0 && int01 % int11 == 0)
06986 {
06987 alt0 = fold_build2 (MULT_EXPR, TREE_TYPE (arg00), arg00,
06988 build_int_cst (TREE_TYPE (arg00),
06989 int01 / int11));
06990 alt1 = arg10;
06991 same = maybe_same;
06992 if (swap)
06993 maybe_same = alt0, alt0 = alt1, alt1 = maybe_same;
06994 }
06995 }
06996
06997 if (same)
06998 return fold_build2 (MULT_EXPR, type,
06999 fold_build2 (code, type,
07000 fold_convert (type, alt0),
07001 fold_convert (type, alt1)),
07002 fold_convert (type, same));
07003
07004 return NULL_TREE;
07005 }
07006
07007
07008
07009
07010
07011
07012 static int
07013 native_encode_int (tree expr, unsigned char *ptr, int len)
07014 {
07015 tree type = TREE_TYPE (expr);
07016 int total_bytes = GET_MODE_SIZE (TYPE_MODE (type));
07017 int byte, offset, word, words;
07018 unsigned char value;
07019
07020 if (total_bytes > len)
07021 return 0;
07022 words = total_bytes / UNITS_PER_WORD;
07023
07024 for (byte = 0; byte < total_bytes; byte++)
07025 {
07026 int bitpos = byte * BITS_PER_UNIT;
07027 if (bitpos < HOST_BITS_PER_WIDE_INT)
07028 value = (unsigned char) (TREE_INT_CST_LOW (expr) >> bitpos);
07029 else
07030 value = (unsigned char) (TREE_INT_CST_HIGH (expr)
07031 >> (bitpos - HOST_BITS_PER_WIDE_INT));
07032
07033 if (total_bytes > UNITS_PER_WORD)
07034 {
07035 word = byte / UNITS_PER_WORD;
07036 if (WORDS_BIG_ENDIAN)
07037 word = (words - 1) - word;
07038 offset = word * UNITS_PER_WORD;
07039 if (BYTES_BIG_ENDIAN)
07040 offset += (UNITS_PER_WORD - 1) - (byte % UNITS_PER_WORD);
07041 else
07042 offset += byte % UNITS_PER_WORD;
07043 }
07044 else
07045 offset = BYTES_BIG_ENDIAN ? (total_bytes - 1) - byte : byte;
07046 ptr[offset] = value;
07047 }
07048 return total_bytes;
07049 }
07050
07051
07052
07053
07054
07055
07056
07057 static int
07058 native_encode_real (tree expr, unsigned char *ptr, int len)
07059 {
07060 tree type = TREE_TYPE (expr);
07061 int total_bytes = GET_MODE_SIZE (TYPE_MODE (type));
07062 int byte, offset, word, words, bitpos;
07063 unsigned char value;
07064
07065
07066
07067
07068 long tmp[6];
07069
07070 if (total_bytes > len)
07071 return 0;
07072 words = 32 / UNITS_PER_WORD;
07073
07074 real_to_target (tmp, TREE_REAL_CST_PTR (expr), TYPE_MODE (type));
07075
07076 for (bitpos = 0; bitpos < total_bytes * BITS_PER_UNIT;
07077 bitpos += BITS_PER_UNIT)
07078 {
07079 byte = (bitpos / BITS_PER_UNIT) & 3;
07080 value = (unsigned char) (tmp[bitpos / 32] >> (bitpos & 31));
07081
07082 if (UNITS_PER_WORD < 4)
07083 {
07084 word = byte / UNITS_PER_WORD;
07085 if (WORDS_BIG_ENDIAN)
07086 word = (words - 1) - word;
07087 offset = word * UNITS_PER_WORD;
07088 if (BYTES_BIG_ENDIAN)
07089 offset += (UNITS_PER_WORD - 1) - (byte % UNITS_PER_WORD);
07090 else
07091 offset += byte % UNITS_PER_WORD;
07092 }
07093 else
07094 offset = BYTES_BIG_ENDIAN ? 3 - byte : byte;
07095 ptr[offset + ((bitpos / BITS_PER_UNIT) & ~3)] = value;
07096 }
07097 return total_bytes;
07098 }
07099
07100
07101
07102
07103
07104
07105 static int
07106 native_encode_complex (tree expr, unsigned char *ptr, int len)
07107 {
07108 int rsize, isize;
07109 tree part;
07110
07111 part = TREE_REALPART (expr);
07112 rsize = native_encode_expr (part, ptr, len);
07113 if (rsize == 0)
07114 return 0;
07115 part = TREE_IMAGPART (expr);
07116 isize = native_encode_expr (part, ptr+rsize, len-rsize);
07117 if (isize != rsize)
07118 return 0;
07119 return rsize + isize;
07120 }
07121
07122
07123
07124
07125
07126
07127
07128 static int
07129 native_encode_vector (tree expr, unsigned char *ptr, int len)
07130 {
07131 int i, size, offset, count;
07132 tree itype, elem, elements;
07133
07134 offset = 0;
07135 elements = TREE_VECTOR_CST_ELTS (expr);
07136 count = TYPE_VECTOR_SUBPARTS (TREE_TYPE (expr));
07137 itype = TREE_TYPE (TREE_TYPE (expr));
07138 size = GET_MODE_SIZE (TYPE_MODE (itype));
07139 for (i = 0; i < count; i++)
07140 {
07141 if (elements)
07142 {
07143 elem = TREE_VALUE (elements);
07144 elements = TREE_CHAIN (elements);
07145 }
07146 else
07147 elem = NULL_TREE;
07148
07149 if (elem)
07150 {
07151 if (native_encode_expr (elem, ptr+offset, len-offset) != size)
07152 return 0;
07153 }
07154 else
07155 {
07156 if (offset + size > len)
07157 return 0;
07158 memset (ptr+offset, 0, size);
07159 }
07160 offset += size;
07161 }
07162 return offset;
07163 }
07164
07165
07166
07167
07168
07169
07170
07171 static int
07172 native_encode_expr (tree expr, unsigned char *ptr, int len)
07173 {
07174 switch (TREE_CODE (expr))
07175 {
07176 case INTEGER_CST:
07177 return native_encode_int (expr, ptr, len);
07178
07179 case REAL_CST:
07180 return native_encode_real (expr, ptr, len);
07181
07182 case COMPLEX_CST:
07183 return native_encode_complex (expr, ptr, len);
07184
07185 case VECTOR_CST:
07186 return native_encode_vector (expr, ptr, len);
07187
07188 default:
07189 return 0;
07190 }
07191 }
07192
07193
07194
07195
07196
07197
07198 static tree
07199 native_interpret_int (tree type, unsigned char *ptr, int len)
07200 {
07201 int total_bytes = GET_MODE_SIZE (TYPE_MODE (type));
07202 int byte, offset, word, words;
07203 unsigned char value;
07204 unsigned int HOST_WIDE_INT lo = 0;
07205 HOST_WIDE_INT hi = 0;
07206
07207 if (total_bytes > len)
07208 return NULL_TREE;
07209 if (total_bytes * BITS_PER_UNIT > 2 * HOST_BITS_PER_WIDE_INT)
07210 return NULL_TREE;
07211 words = total_bytes / UNITS_PER_WORD;
07212
07213 for (byte = 0; byte < total_bytes; byte++)
07214 {
07215 int bitpos = byte * BITS_PER_UNIT;
07216 if (total_bytes > UNITS_PER_WORD)
07217 {
07218 word = byte / UNITS_PER_WORD;
07219 if (WORDS_BIG_ENDIAN)
07220 word = (words - 1) - word;
07221 offset = word * UNITS_PER_WORD;
07222 if (BYTES_BIG_ENDIAN)
07223 offset += (UNITS_PER_WORD - 1) - (byte % UNITS_PER_WORD);
07224 else
07225 offset += byte % UNITS_PER_WORD;
07226 }
07227 else
07228 offset = BYTES_BIG_ENDIAN ? (total_bytes - 1) - byte : byte;
07229 value = ptr[offset];
07230
07231 if (bitpos < HOST_BITS_PER_WIDE_INT)
07232 lo |= (unsigned HOST_WIDE_INT) value << bitpos;
07233 else
07234 hi |= (unsigned HOST_WIDE_INT) value
07235 << (bitpos - HOST_BITS_PER_WIDE_INT);
07236 }
07237
07238 return force_fit_type (build_int_cst_wide (type, lo, hi),
07239 0, false, false);
07240 }
07241
07242
07243
07244
07245
07246
07247 static tree
07248 native_interpret_real (tree type, unsigned char *ptr, int len)
07249 {
07250 enum machine_mode mode = TYPE_MODE (type);
07251 int total_bytes = GET_MODE_SIZE (mode);
07252 int byte, offset, word, words, bitpos;
07253 unsigned char value;
07254
07255
07256
07257 REAL_VALUE_TYPE r;
07258 long tmp[6];
07259
07260 total_bytes = GET_MODE_SIZE (TYPE_MODE (type));
07261 if (total_bytes > len || total_bytes > 24)
07262 return NULL_TREE;
07263 words = 32 / UNITS_PER_WORD;
07264
07265 memset (tmp, 0, sizeof (tmp));
07266 for (bitpos = 0; bitpos < total_bytes * BITS_PER_UNIT;
07267 bitpos += BITS_PER_UNIT)
07268 {
07269 byte = (bitpos / BITS_PER_UNIT) & 3;
07270 if (UNITS_PER_WORD < 4)
07271 {
07272 word = byte / UNITS_PER_WORD;
07273 if (WORDS_BIG_ENDIAN)
07274 word = (words - 1) - word;
07275 offset = word * UNITS_PER_WORD;
07276 if (BYTES_BIG_ENDIAN)
07277 offset += (UNITS_PER_WORD - 1) - (byte % UNITS_PER_WORD);
07278 else
07279 offset += byte % UNITS_PER_WORD;
07280 }
07281 else
07282 offset = BYTES_BIG_ENDIAN ? 3 - byte : byte;
07283 value = ptr[offset + ((bitpos / BITS_PER_UNIT) & ~3)];
07284
07285 tmp[bitpos / 32] |= (unsigned long)value << (bitpos & 31);
07286 }
07287
07288 real_from_target (&r, tmp, mode);
07289 return build_real (type, r);
07290 }
07291
07292
07293
07294
07295
07296
07297 static tree
07298 native_interpret_complex (tree type, unsigned char *ptr, int len)
07299 {
07300 tree etype, rpart, ipart;
07301 int size;
07302
07303 etype = TREE_TYPE (type);
07304 size = GET_MODE_SIZE (TYPE_MODE (etype));
07305 if (size * 2 > len)
07306 return NULL_TREE;
07307 rpart = native_interpret_expr (etype, ptr, size);
07308 if (!rpart)
07309 return NULL_TREE;
07310 ipart = native_interpret_expr (etype, ptr+size, size);
07311 if (!ipart)
07312 return NULL_TREE;
07313 return build_complex (type, rpart, ipart);
07314 }
07315
07316
07317
07318
07319
07320
07321 static tree
07322 native_interpret_vector (tree type, unsigned char *ptr, int len)
07323 {
07324 tree etype, elem, elements;
07325 int i, size, count;
07326
07327 etype = TREE_TYPE (type);
07328 size = GET_MODE_SIZE (TYPE_MODE (etype));
07329 count = TYPE_VECTOR_SUBPARTS (type);
07330 if (size * count > len)
07331 return NULL_TREE;
07332
07333 elements = NULL_TREE;
07334 for (i = count - 1; i >= 0; i--)
07335 {
07336 elem = native_interpret_expr (etype, ptr+(i*size), size);
07337 if (!elem)
07338 return NULL_TREE;
07339 elements = tree_cons (NULL_TREE, elem, elements);
07340 }
07341 return build_vector (type, elements);
07342 }
07343
07344
07345
07346
07347
07348
07349
07350
07351 static tree
07352 native_interpret_expr (tree type, unsigned char *ptr, int len)
07353 {
07354 switch (TREE_CODE (type))
07355 {
07356 case INTEGER_TYPE:
07357 case ENUMERAL_TYPE:
07358 case BOOLEAN_TYPE:
07359 return native_interpret_int (type, ptr, len);
07360
07361 case REAL_TYPE:
07362 return native_interpret_real (type, ptr, len);
07363
07364 case COMPLEX_TYPE:
07365 return native_interpret_complex (type, ptr, len);
07366
07367 case VECTOR_TYPE:
07368 return native_interpret_vector (type, ptr, len);
07369
07370 default:
07371 return NULL_TREE;
07372 }
07373 }
07374
07375
07376
07377
07378
07379
07380 static tree
07381 fold_view_convert_expr (tree type, tree expr)
07382 {
07383
07384 unsigned char buffer[64];
07385 int len;
07386
07387
07388 if (CHAR_BIT != 8 || BITS_PER_UNIT != 8)
07389 return NULL_TREE;
07390
07391 len = native_encode_expr (expr, buffer, sizeof (buffer));
07392 if (len == 0)
07393 return NULL_TREE;
07394
07395 return native_interpret_expr (type, buffer, len);
07396 }
07397
07398
07399
07400
07401
07402
07403 tree
07404 fold_unary (enum tree_code code, tree type, tree op0)
07405 {
07406 tree tem;
07407 tree arg0;
07408 enum tree_code_class kind = TREE_CODE_CLASS (code);
07409
07410 gcc_assert (IS_EXPR_CODE_CLASS (kind)
07411 && TREE_CODE_LENGTH (code) == 1);
07412
07413 arg0 = op0;
07414 if (arg0)
07415 {
07416 if (code == NOP_EXPR || code == CONVERT_EXPR
07417 || code == FLOAT_EXPR || code == ABS_EXPR)
07418 {
07419
07420
07421 STRIP_SIGN_NOPS (arg0);
07422 }
07423 else
07424 {
07425
07426
07427
07428
07429
07430
07431
07432
07433
07434
07435
07436 STRIP_NOPS (arg0);
07437 }
07438 }
07439
07440 if (TREE_CODE_CLASS (code) == tcc_unary)
07441 {
07442 if (TREE_CODE (arg0) == COMPOUND_EXPR)
07443 return build2 (COMPOUND_EXPR, type, TREE_OPERAND (arg0, 0),
07444 fold_build1 (code, type, TREE_OPERAND (arg0, 1)));
07445 else if (TREE_CODE (arg0) == COND_EXPR)
07446 {
07447 tree arg01 = TREE_OPERAND (arg0, 1);
07448 tree arg02 = TREE_OPERAND (arg0, 2);
07449 if (! VOID_TYPE_P (TREE_TYPE (arg01)))
07450 arg01 = fold_build1 (code, type, arg01);
07451 if (! VOID_TYPE_P (TREE_TYPE (arg02)))
07452 arg02 = fold_build1 (code, type, arg02);
07453 tem = fold_build3 (COND_EXPR, type, TREE_OPERAND (arg0, 0),
07454 arg01, arg02);
07455
07456
07457
07458
07459
07460
07461
07462
07463
07464
07465 if ((code == NOP_EXPR || code == CONVERT_EXPR
07466 || code == NON_LVALUE_EXPR)
07467 && TREE_CODE (tem) == COND_EXPR
07468 && TREE_CODE (TREE_OPERAND (tem, 1)) == code
07469 && TREE_CODE (TREE_OPERAND (tem, 2)) == code
07470 && ! VOID_TYPE_P (TREE_OPERAND (tem, 1))
07471 && ! VOID_TYPE_P (TREE_OPERAND (tem, 2))
07472 && (TREE_TYPE (TREE_OPERAND (TREE_OPERAND (tem, 1), 0))
07473 == TREE_TYPE (TREE_OPERAND (TREE_OPERAND (tem, 2), 0)))
07474 && (! (INTEGRAL_TYPE_P (TREE_TYPE (tem))
07475 && (INTEGRAL_TYPE_P
07476 (TREE_TYPE (TREE_OPERAND (TREE_OPERAND (tem, 1), 0))))
07477 && TYPE_PRECISION (TREE_TYPE (tem)) <= BITS_PER_WORD)
07478 || flag_syntax_only))
07479 tem = build1 (code, type,
07480 build3 (COND_EXPR,
07481 TREE_TYPE (TREE_OPERAND
07482 (TREE_OPERAND (tem, 1), 0)),
07483 TREE_OPERAND (tem, 0),
07484 TREE_OPERAND (TREE_OPERAND (tem, 1), 0),
07485 TREE_OPERAND (TREE_OPERAND (tem, 2), 0)));
07486 return tem;
07487 }
07488 else if (COMPARISON_CLASS_P (arg0))
07489 {
07490 if (TREE_CODE (type) == BOOLEAN_TYPE)
07491 {
07492 arg0 = copy_node (arg0);
07493 TREE_TYPE (arg0) = type;
07494 return arg0;
07495 }
07496 else if (TREE_CODE (type) != INTEGER_TYPE)
07497 return fold_build3 (COND_EXPR, type, arg0,
07498 fold_build1 (code, type,
07499 integer_one_node),
07500 fold_build1 (code, type,
07501 integer_zero_node));
07502 }
07503 }
07504
07505 switch (code)
07506 {
07507 case NOP_EXPR:
07508 case FLOAT_EXPR:
07509 case CONVERT_EXPR:
07510 case FIX_TRUNC_EXPR:
07511 case FIX_CEIL_EXPR:
07512 case FIX_FLOOR_EXPR:
07513 case FIX_ROUND_EXPR:
07514 if (TREE_TYPE (op0) == type)
07515 return op0;
07516
07517
07518
07519 if (COMPARISON_CLASS_P (op0) && INTEGRAL_TYPE_P (type))
07520 return fold_build2 (TREE_CODE (op0), type, TREE_OPERAND (op0, 0),
07521 TREE_OPERAND (op0, 1));
07522
07523
07524 if (TREE_CODE (op0) == NOP_EXPR
07525 || TREE_CODE (op0) == CONVERT_EXPR)
07526 {
07527 tree inside_type = TREE_TYPE (TREE_OPERAND (op0, 0));
07528 tree inter_type = TREE_TYPE (op0);
07529 int inside_int = INTEGRAL_TYPE_P (inside_type);
07530 int inside_ptr = POINTER_TYPE_P (inside_type);
07531 int inside_float = FLOAT_TYPE_P (inside_type);
07532 int inside_vec = TREE_CODE (inside_type) == VECTOR_TYPE;
07533 unsigned int inside_prec = TYPE_PRECISION (inside_type);
07534 int inside_unsignedp = TYPE_UNSIGNED (inside_type);
07535 int inter_int = INTEGRAL_TYPE_P (inter_type);
07536 int inter_ptr = POINTER_TYPE_P (inter_type);
07537 int inter_float = FLOAT_TYPE_P (inter_type);
07538 int inter_vec = TREE_CODE (inter_type) == VECTOR_TYPE;
07539 unsigned int inter_prec = TYPE_PRECISION (inter_type);
07540 int inter_unsignedp = TYPE_UNSIGNED (inter_type);
07541 int final_int = INTEGRAL_TYPE_P (type);
07542 int final_ptr = POINTER_TYPE_P (type);
07543 int final_float = FLOAT_TYPE_P (type);
07544 int final_vec = TREE_CODE (type) == VECTOR_TYPE;
07545 unsigned int final_prec = TYPE_PRECISION (type);
07546 int final_unsignedp = TYPE_UNSIGNED (type);
07547
07548
07549
07550
07551
07552 if (TYPE_MAIN_VARIANT (inside_type) == TYPE_MAIN_VARIANT (type)
07553 && (((inter_int || inter_ptr) && final_int)
07554 || (inter_float && final_float))
07555 && inter_prec >= final_prec)
07556 return fold_build1 (code, type, TREE_OPERAND (op0, 0));
07557
07558
07559
07560
07561
07562
07563
07564 if ((((inter_int || inter_ptr) && (inside_int || inside_ptr))
07565 || (inter_float && inside_float)
07566 || (inter_vec && inside_vec))
07567 && inter_prec >= inside_prec
07568 && (inter_float || inter_vec
07569 || inter_unsignedp == inside_unsignedp)
07570 && ! (final_prec != GET_MODE_BITSIZE (TYPE_MODE (type))
07571 && TYPE_MODE (type) == TYPE_MODE (inter_type))
07572 && ! final_ptr
07573 && (! final_vec || inter_prec == inside_prec))
07574 return fold_build1 (code, type, TREE_OPERAND (op0, 0));
07575
07576
07577
07578 if (inside_int && inter_int && final_int
07579 && inside_prec < inter_prec && inter_prec < final_prec
07580 && inside_unsignedp && !inter_unsignedp)
07581 return fold_build1 (code, type, TREE_OPERAND (op0, 0));
07582
07583
07584
07585
07586
07587
07588
07589
07590
07591
07592
07593
07594
07595
07596
07597
07598
07599 if (! inside_float && ! inter_float && ! final_float
07600 && ! inside_vec && ! inter_vec && ! final_vec
07601 && (inter_prec >= inside_prec || inter_prec >= final_prec)
07602 && ! (inside_int && inter_int
07603 && inter_unsignedp != inside_unsignedp
07604 && inter_prec < final_prec)
07605 && ((inter_unsignedp && inter_prec > inside_prec)
07606 == (final_unsignedp && final_prec > inter_prec))
07607 && ! (inside_ptr && inter_prec != final_prec)
07608 && ! (final_ptr && inside_prec != inter_prec)
07609 && ! (final_prec != GET_MODE_BITSIZE (TYPE_MODE (type))
07610 && TYPE_MODE (type) == TYPE_MODE (inter_type))
07611 && final_ptr == inside_ptr
07612 && ! (inside_ptr
07613 && TREE_CODE (TREE_TYPE (inside_type)) == ARRAY_TYPE
07614 && TREE_CODE (TREE_TYPE (type)) != ARRAY_TYPE)
07615 && ! ((strcmp (lang_hooks.name, "GNU Java") == 0)
07616 && final_ptr))
07617 return fold_build1 (code, type, TREE_OPERAND (op0, 0));
07618 }
07619
07620
07621
07622
07623 if (TREE_CODE (op0) == ADDR_EXPR
07624 && POINTER_TYPE_P (type)
07625 && handled_component_p (TREE_OPERAND (op0, 0)))
07626 {
07627 HOST_WIDE_INT bitsize, bitpos;
07628 tree offset;
07629 enum machine_mode mode;
07630 int unsignedp, volatilep;
07631 tree base = TREE_OPERAND (op0, 0);
07632 base = get_inner_reference (base, &bitsize, &bitpos, &offset,
07633 &mode, &unsignedp, &volatilep, false);
07634
07635
07636
07637 if (! offset && bitpos == 0
07638 && TYPE_MAIN_VARIANT (TREE_TYPE (type))
07639 == TYPE_MAIN_VARIANT (TREE_TYPE (base)))
07640 return fold_convert (type, build_fold_addr_expr (base));
07641 }
07642
07643 if (TREE_CODE (op0) == MODIFY_EXPR
07644 && TREE_CONSTANT (TREE_OPERAND (op0, 1))
07645
07646 && !(TREE_CODE (TREE_OPERAND (op0, 0)) == COMPONENT_REF
07647 && DECL_BIT_FIELD (TREE_OPERAND (TREE_OPERAND (op0, 0), 1))))
07648 {
07649
07650
07651 tem = fold_build1 (code, type, TREE_OPERAND (op0, 1));
07652
07653 tem = build2 (COMPOUND_EXPR, TREE_TYPE (tem), op0, tem);
07654 TREE_NO_WARNING (tem) = 1;
07655 TREE_USED (tem) = 1;
07656 return tem;
07657 }
07658
07659
07660
07661
07662 if (INTEGRAL_TYPE_P (type)
07663 && TREE_CODE (type) != BOOLEAN_TYPE
07664 && TREE_CODE (op0) == BIT_AND_EXPR
07665 && TREE_CODE (TREE_OPERAND (op0, 1)) == INTEGER_CST)
07666 {
07667 tree and = op0;
07668 tree and0 = TREE_OPERAND (and, 0), and1 = TREE_OPERAND (and, 1);
07669 int change = 0;
07670
07671 if (TYPE_UNSIGNED (TREE_TYPE (and))
07672 || (TYPE_PRECISION (type)
07673 <= TYPE_PRECISION (TREE_TYPE (and))))
07674 change = 1;
07675 else if (TYPE_PRECISION (TREE_TYPE (and1))
07676 <= HOST_BITS_PER_WIDE_INT
07677 && host_integerp (and1, 1))
07678 {
07679 unsigned HOST_WIDE_INT cst;
07680
07681 cst = tree_low_cst (and1, 1);
07682 cst &= (HOST_WIDE_INT) -1
07683 << (TYPE_PRECISION (TREE_TYPE (and1)) - 1);
07684 change = (cst == 0);
07685 #ifdef LOAD_EXTEND_OP
07686 if (change
07687 && !flag_syntax_only
07688 && (LOAD_EXTEND_OP (TYPE_MODE (TREE_TYPE (and0)))
07689 == ZERO_EXTEND))
07690 {
07691 tree uns = lang_hooks.types.unsigned_type (TREE_TYPE (and0));
07692 and0 = fold_convert (uns, and0);
07693 and1 = fold_convert (uns, and1);
07694 }
07695 #endif
07696 }
07697 if (change)
07698 {
07699 tem = build_int_cst_wide (type, TREE_INT_CST_LOW (and1),
07700 TREE_INT_CST_HIGH (and1));
07701 tem = force_fit_type (tem, 0, TREE_OVERFLOW (and1),
07702 TREE_CONSTANT_OVERFLOW (and1));
07703 return fold_build2 (BIT_AND_EXPR, type,
07704 fold_convert (type, and0), tem);
07705 }
07706 }
07707
07708
07709
07710 if (POINTER_TYPE_P (type)
07711 && BINARY_CLASS_P (arg0)
07712 && TREE_CODE (TREE_OPERAND (arg0, 0)) == NOP_EXPR
07713 && POINTER_TYPE_P (TREE_TYPE (TREE_OPERAND (arg0, 0))))
07714 {
07715 tree arg00 = TREE_OPERAND (arg0, 0);
07716 tree t0 = type;
07717 tree t1 = TREE_TYPE (arg00);
07718 tree tt0 = TREE_TYPE (t0);
07719 tree tt1 = TREE_TYPE (t1);
07720 tree s0 = TYPE_SIZE (tt0);
07721 tree s1 = TYPE_SIZE (tt1);
07722
07723 if (s0 && s1 && operand_equal_p (s0, s1, OEP_ONLY_CONST))
07724 return build2 (TREE_CODE (arg0), t0, fold_convert (t0, arg00),
07725 TREE_OPERAND (arg0, 1));
07726 }
07727
07728
07729
07730
07731 if (INTEGRAL_TYPE_P (type)
07732 && TREE_CODE (op0) == BIT_NOT_EXPR
07733 && INTEGRAL_TYPE_P (TREE_TYPE (op0))
07734 && (TREE_CODE (TREE_OPERAND (op0, 0)) == NOP_EXPR
07735 || TREE_CODE (TREE_OPERAND (op0, 0)) == CONVERT_EXPR)
07736 && TYPE_PRECISION (type) == TYPE_PRECISION (TREE_TYPE (op0)))
07737 {
07738 tem = TREE_OPERAND (TREE_OPERAND (op0, 0), 0);
07739 if (INTEGRAL_TYPE_P (TREE_TYPE (tem))
07740 && TYPE_PRECISION (type) <= TYPE_PRECISION (TREE_TYPE (tem)))
07741 return fold_build1 (BIT_NOT_EXPR, type, fold_convert (type, tem));
07742 }
07743
07744 tem = fold_convert_const (code, type, op0);
07745 return tem ? tem : NULL_TREE;
07746
07747 case VIEW_CONVERT_EXPR:
07748 if (TREE_CODE (op0) == VIEW_CONVERT_EXPR)
07749 return fold_build1 (VIEW_CONVERT_EXPR, type, TREE_OPERAND (op0, 0));
07750 return fold_view_convert_expr (type, op0);
07751
07752 case NEGATE_EXPR:
07753 tem = fold_negate_expr (arg0);
07754 if (tem)
07755 return fold_convert (type, tem);
07756 return NULL_TREE;
07757
07758 case ABS_EXPR:
07759 if (TREE_CODE (arg0) == INTEGER_CST || TREE_CODE (arg0) == REAL_CST)
07760 return fold_abs_const (arg0, type);
07761 else if (TREE_CODE (arg0) == NEGATE_EXPR)
07762 return fold_build1 (ABS_EXPR, type, TREE_OPERAND (arg0, 0));
07763
07764 else if (TREE_CODE (arg0) == NOP_EXPR
07765 && TREE_CODE (type) == REAL_TYPE)
07766 {
07767 tree targ0 = strip_float_extensions (arg0);
07768 if (targ0 != arg0)
07769 return fold_convert (type, fold_build1 (ABS_EXPR,
07770 TREE_TYPE (targ0),
07771 targ0));
07772 }
07773
07774 else if (TREE_CODE (arg0) == ABS_EXPR)
07775 return arg0;
07776 else if (tree_expr_nonnegative_p (arg0))
07777 return arg0;
07778
07779
07780 if (TREE_CODE (type) == REAL_TYPE)
07781 {
07782 tem = fold_strip_sign_ops (arg0);
07783 if (tem)
07784 return fold_build1 (ABS_EXPR, type, fold_convert (type, tem));
07785 }
07786 return NULL_TREE;
07787
07788 case CONJ_EXPR:
07789 if (TREE_CODE (TREE_TYPE (arg0)) != COMPLEX_TYPE)
07790 return fold_convert (type, arg0);
07791 if (TREE_CODE (arg0) == COMPLEX_EXPR)
07792 {
07793 tree itype = TREE_TYPE (type);
07794 tree rpart = fold_convert (itype, TREE_OPERAND (arg0, 0));
07795 tree ipart = fold_convert (itype, TREE_OPERAND (arg0, 1));
07796 return fold_build2 (COMPLEX_EXPR, type, rpart, negate_expr (ipart));
07797 }
07798 if (TREE_CODE (arg0) == COMPLEX_CST)
07799 {
07800 tree itype = TREE_TYPE (type);
07801 tree rpart = fold_convert (itype, TREE_REALPART (arg0));
07802 tree ipart = fold_convert (itype, TREE_IMAGPART (arg0));
07803 return build_complex (type, rpart, negate_expr (ipart));
07804 }
07805 if (TREE_CODE (arg0) == CONJ_EXPR)
07806 return fold_convert (type, TREE_OPERAND (arg0, 0));
07807 return NULL_TREE;
07808
07809 case BIT_NOT_EXPR:
07810 if (TREE_CODE (arg0) == INTEGER_CST)
07811 return fold_not_const (arg0, type);
07812 else if (TREE_CODE (arg0) == BIT_NOT_EXPR)
07813 return TREE_OPERAND (arg0, 0);
07814
07815 else if (INTEGRAL_TYPE_P (type) && TREE_CODE (arg0) == NEGATE_EXPR)
07816 return fold_build2 (MINUS_EXPR, type, TREE_OPERAND (arg0, 0),
07817 build_int_cst (type, 1));
07818
07819 else if (INTEGRAL_TYPE_P (type)
07820 && ((TREE_CODE (arg0) == MINUS_EXPR
07821 && integer_onep (TREE_OPERAND (arg0, 1)))
07822 || (TREE_CODE (arg0) == PLUS_EXPR
07823 && integer_all_onesp (TREE_OPERAND (arg0, 1)))))
07824 return fold_build1 (NEGATE_EXPR, type, TREE_OPERAND (arg0, 0));
07825
07826 else if (TREE_CODE (arg0) == BIT_XOR_EXPR
07827 && (tem = fold_unary (BIT_NOT_EXPR, type,
07828 fold_convert (type,
07829 TREE_OPERAND (arg0, 0)))))
07830 return fold_build2 (BIT_XOR_EXPR, type, tem,
07831 fold_convert (type, TREE_OPERAND (arg0, 1)));
07832 else if (TREE_CODE (arg0) == BIT_XOR_EXPR
07833 && (tem = fold_unary (BIT_NOT_EXPR, type,
07834 fold_convert (type,
07835 TREE_OPERAND (arg0, 1)))))
07836 return fold_build2 (BIT_XOR_EXPR, type,
07837 fold_convert (type, TREE_OPERAND (arg0, 0)), tem);
07838
07839 return NULL_TREE;
07840
07841 case TRUTH_NOT_EXPR:
07842
07843 if (TREE_CODE (TREE_TYPE (arg0)) != BOOLEAN_TYPE)
07844 arg0 = fold_convert (boolean_type_node, arg0);
07845
07846
07847
07848
07849
07850 tem = fold_truth_not_expr (arg0);
07851 if (!tem)
07852 return NULL_TREE;
07853 return fold_convert (type, tem);
07854
07855 case REALPART_EXPR:
07856 if (TREE_CODE (TREE_TYPE (arg0)) != COMPLEX_TYPE)
07857 return fold_convert (type, arg0);
07858 if (TREE_CODE (arg0) == COMPLEX_EXPR)
07859 return omit_one_operand (type, TREE_OPERAND (arg0, 0),
07860 TREE_OPERAND (arg0, 1));
07861 if (TREE_CODE (arg0) == COMPLEX_CST)
07862 return fold_convert (type, TREE_REALPART (arg0));
07863 if (TREE_CODE (arg0) == PLUS_EXPR || TREE_CODE (arg0) == MINUS_EXPR)
07864 {
07865 tree itype = TREE_TYPE (TREE_TYPE (arg0));
07866 tem = fold_build2 (TREE_CODE (arg0), itype,
07867 fold_build1 (REALPART_EXPR, itype,
07868 TREE_OPERAND (arg0, 0)),
07869 fold_build1 (REALPART_EXPR, itype,
07870 TREE_OPERAND (arg0, 1)));
07871 return fold_convert (type, tem);
07872 }
07873 if (TREE_CODE (arg0) == CONJ_EXPR)
07874 {
07875 tree itype = TREE_TYPE (TREE_TYPE (arg0));
07876 tem = fold_build1 (REALPART_EXPR, itype, TREE_OPERAND (arg0, 0));
07877 return fold_convert (type, tem);
07878 }
07879 return NULL_TREE;
07880
07881 case IMAGPART_EXPR:
07882 if (TREE_CODE (TREE_TYPE (arg0)) != COMPLEX_TYPE)
07883 return fold_convert (type, integer_zero_node);
07884 if (TREE_CODE (arg0) == COMPLEX_EXPR)
07885 return omit_one_operand (type, TREE_OPERAND (arg0, 1),
07886 TREE_OPERAND (arg0, 0));
07887 if (TREE_CODE (arg0) == COMPLEX_CST)
07888 return fold_convert (type, TREE_IMAGPART (arg0));
07889 if (TREE_CODE (arg0) == PLUS_EXPR || TREE_CODE (arg0) == MINUS_EXPR)
07890 {
07891 tree itype = TREE_TYPE (TREE_TYPE (arg0));
07892 tem = fold_build2 (TREE_CODE (arg0), itype,
07893 fold_build1 (IMAGPART_EXPR, itype,
07894 TREE_OPERAND (arg0, 0)),
07895 fold_build1 (IMAGPART_EXPR, itype,
07896 TREE_OPERAND (arg0, 1)));
07897 return fold_convert (type, tem);
07898 }
07899 if (TREE_CODE (arg0) == CONJ_EXPR)
07900 {
07901 tree itype = TREE_TYPE (TREE_TYPE (arg0));
07902 tem = fold_build1 (IMAGPART_EXPR, itype, TREE_OPERAND (arg0, 0));
07903 return fold_convert (type, negate_expr (tem));
07904 }
07905 return NULL_TREE;
07906
07907 default:
07908 return NULL_TREE;
07909 }
07910 }
07911
07912
07913
07914
07915
07916
07917 static tree
07918 fold_minmax (enum tree_code code, tree type, tree op0, tree op1)
07919 {
07920 enum tree_code compl_code;
07921
07922 if (code == MIN_EXPR)
07923 compl_code = MAX_EXPR;
07924 else if (code == MAX_EXPR)
07925 compl_code = MIN_EXPR;
07926 else
07927 gcc_unreachable ();
07928
07929
07930 if (TREE_CODE (op0) == compl_code
07931 && operand_equal_p (TREE_OPERAND (op0, 1), op1, 0))
07932 return omit_one_operand (type, op1, TREE_OPERAND (op0, 0));
07933
07934
07935 if (TREE_CODE (op0) == compl_code
07936 && operand_equal_p (TREE_OPERAND (op0, 0), op1, 0)
07937 && reorder_operands_p (TREE_OPERAND (op0, 1), op1))
07938 return omit_one_operand (type, op1, TREE_OPERAND (op0, 1));
07939
07940
07941 if (TREE_CODE (op1) == compl_code
07942 && operand_equal_p (op0, TREE_OPERAND (op1, 0), 0)
07943 && reorder_operands_p (op0, TREE_OPERAND (op1, 1)))
07944 return omit_one_operand (type, op0, TREE_OPERAND (op1, 1));
07945
07946
07947 if (TREE_CODE (op1) == compl_code
07948 && operand_equal_p (op0, TREE_OPERAND (op1, 1), 0)
07949 && reorder_operands_p (op0, TREE_OPERAND (op1, 0)))
07950 return omit_one_operand (type, op0, TREE_OPERAND (op1, 0));
07951
07952 return NULL_TREE;
07953 }
07954
07955
07956
07957
07958
07959
07960
07961
07962
07963 static tree
07964 fold_comparison (enum tree_code code, tree type, tree op0, tree op1)
07965 {
07966 tree arg0, arg1, tem;
07967
07968 arg0 = op0;
07969 arg1 = op1;
07970
07971 STRIP_SIGN_NOPS (arg0);
07972 STRIP_SIGN_NOPS (arg1);
07973
07974 tem = fold_relational_const (code, type, arg0, arg1);
07975 if (tem != NULL_TREE)
07976 return tem;
07977
07978
07979 if (tree_swap_operands_p (arg0, arg1, true))
07980 return fold_build2 (swap_tree_comparison (code), type, op1, op0);
07981
07982
07983 if ((TREE_CODE (arg0) == PLUS_EXPR || TREE_CODE (arg0) == MINUS_EXPR)
07984 && (TREE_CODE (TREE_OPERAND (arg0, 1)) == INTEGER_CST
07985 && !TREE_OVERFLOW (TREE_OPERAND (arg0, 1))
07986 && TYPE_OVERFLOW_UNDEFINED (TREE_TYPE (arg1)))
07987 && (TREE_CODE (arg1) == INTEGER_CST
07988 && !TREE_OVERFLOW (arg1)))
07989 {
07990 tree const1 = TREE_OPERAND (arg0, 1);
07991 tree const2 = arg1;
07992 tree variable = TREE_OPERAND (arg0, 0);
07993 tree lhs;
07994 int lhs_add;
07995 lhs_add = TREE_CODE (arg0) != PLUS_EXPR;
07996
07997 lhs = fold_build2 (lhs_add ? PLUS_EXPR : MINUS_EXPR,
07998 TREE_TYPE (arg1), const2, const1);
07999 if (TREE_CODE (lhs) == TREE_CODE (arg1)
08000 && (TREE_CODE (lhs) != INTEGER_CST
08001 || !TREE_OVERFLOW (lhs)))
08002 {
08003 fold_overflow_warning (("assuming signed overflow does not occur "
08004 "when changing X +- C1 cmp C2 to "
08005 "X cmp C1 +- C2"),
08006 WARN_STRICT_OVERFLOW_COMPARISON);
08007 return fold_build2 (code, type, variable, lhs);
08008 }
08009 }
08010
08011
08012
08013
08014
08015
08016
08017
08018
08019
08020
08021 if (POINTER_TYPE_P (TREE_TYPE (arg0))
08022 && !flag_wrapv
08023 && !TYPE_OVERFLOW_TRAPS (TREE_TYPE (arg0)))
08024 {
08025 tree base0, offset0, base1, offset1;
08026
08027 if (extract_array_ref (arg0, &base0, &offset0)
08028 && extract_array_ref (arg1, &base1, &offset1)
08029 && operand_equal_p (base0, base1, 0))
08030 {
08031 tree signed_size_type_node;
08032 signed_size_type_node = signed_type_for (size_type_node);
08033
08034
08035
08036
08037
08038
08039 if (offset0 == NULL_TREE)
08040 offset0 = build_int_cst (signed_size_type_node, 0);
08041 else
08042 offset0 = fold_convert (signed_size_type_node, offset0);
08043 if (offset1 == NULL_TREE)
08044 offset1 = build_int_cst (signed_size_type_node, 0);
08045 else
08046 offset1 = fold_convert (signed_size_type_node, offset1);
08047
08048 return fold_build2 (code, type, offset0, offset1);
08049 }
08050 }
08051
08052 if (FLOAT_TYPE_P (TREE_TYPE (arg0)))
08053 {
08054 tree targ0 = strip_float_extensions (arg0);
08055 tree targ1 = strip_float_extensions (arg1);
08056 tree newtype = TREE_TYPE (targ0);
08057
08058 if (TYPE_PRECISION (TREE_TYPE (targ1)) > TYPE_PRECISION (newtype))
08059 newtype = TREE_TYPE (targ1);
08060
08061
08062 if (TYPE_PRECISION (newtype) < TYPE_PRECISION (TREE_TYPE (arg0)))
08063 return fold_build2 (code, type, fold_convert (newtype, targ0),
08064 fold_convert (newtype, targ1));
08065
08066
08067 if (TREE_CODE (arg0) == NEGATE_EXPR
08068 && TREE_CODE (arg1) == NEGATE_EXPR)
08069 return fold_build2 (code, type, TREE_OPERAND (arg1, 0),
08070 TREE_OPERAND (arg0, 0));
08071
08072 if (TREE_CODE (arg1) == REAL_CST)
08073 {
08074 REAL_VALUE_TYPE cst;
08075 cst = TREE_REAL_CST (arg1);
08076
08077
08078 if (TREE_CODE (arg0) == NEGATE_EXPR)
08079 return fold_build2 (swap_tree_comparison (code), type,
08080 TREE_OPERAND (arg0, 0),
08081 build_real (TREE_TYPE (arg1),
08082 REAL_VALUE_NEGATE (cst)));
08083
08084
08085
08086 if (REAL_VALUE_MINUS_ZERO (cst))
08087 return fold_build2 (code, type, arg0,
08088 build_real (TREE_TYPE (arg1), dconst0));
08089
08090
08091 if (REAL_VALUE_ISNAN (cst)
08092 && ! HONOR_SNANS (TYPE_MODE (TREE_TYPE (arg1))))
08093 {
08094 tem = (code == NE_EXPR) ? integer_one_node : integer_zero_node;
08095 return omit_one_operand (type, tem, arg0);
08096 }
08097
08098
08099 if (REAL_VALUE_ISINF (cst))
08100 {
08101 tem = fold_inf_compare (code, type, arg0, arg1);
08102 if (tem != NULL_TREE)
08103 return tem;
08104 }
08105 }
08106
08107
08108
08109
08110
08111 if (flag_unsafe_math_optimizations
08112 && TREE_CODE (arg1) == REAL_CST
08113 && (TREE_CODE (arg0) == PLUS_EXPR
08114 || TREE_CODE (arg0) == MINUS_EXPR)
08115 && TREE_CODE (TREE_OPERAND (arg0, 1)) == REAL_CST
08116 && 0 != (tem = const_binop (TREE_CODE (arg0) == PLUS_EXPR
08117 ? MINUS_EXPR : PLUS_EXPR,
08118 arg1, TREE_OPERAND (arg0, 1), 0))
08119 && ! TREE_CONSTANT_OVERFLOW (tem))
08120 return fold_build2 (code, type, TREE_OPERAND (arg0, 0), tem);
08121
08122
08123
08124
08125 if (flag_unsafe_math_optimizations
08126 && TREE_CODE (arg1) == REAL_CST
08127 && TREE_CODE (arg0) == MINUS_EXPR
08128 && TREE_CODE (TREE_OPERAND (arg0, 0)) == REAL_CST
08129 && 0 != (tem = const_binop (MINUS_EXPR, TREE_OPERAND (arg0, 0),
08130 arg1, 0))
08131 && ! TREE_CONSTANT_OVERFLOW (tem))
08132 return fold_build2 (swap_tree_comparison (code), type,
08133 TREE_OPERAND (arg0, 1), tem);
08134
08135
08136 if (TREE_CODE (arg1) == REAL_CST
08137 && flag_unsafe_math_optimizations
08138 && ! flag_errno_math)
08139 {
08140 enum built_in_function fcode = builtin_mathfn_code (arg0);
08141
08142 if (fcode != END_BUILTINS)
08143 {
08144 tem = fold_mathfn_compare (fcode, code, type, arg0, arg1);
08145 if (tem != NULL_TREE)
08146 return tem;
08147 }
08148 }
08149 }
08150
08151
08152 if (TREE_CONSTANT (arg1)
08153 && (TREE_CODE (arg0) == POSTINCREMENT_EXPR
08154 || TREE_CODE (arg0) == POSTDECREMENT_EXPR)
08155
08156
08157
08158
08159 && (POINTER_TYPE_P (TREE_TYPE (arg0))
08160 || (INTEGRAL_TYPE_P (TREE_TYPE (arg0))
08161 && (code == EQ_EXPR || code == NE_EXPR))))
08162 {
08163 tree varop, newconst;
08164
08165 if (TREE_CODE (arg0) == POSTINCREMENT_EXPR)
08166 {
08167 newconst = fold_build2 (PLUS_EXPR, TREE_TYPE (arg0),
08168 arg1, TREE_OPERAND (arg0, 1));
08169 varop = build2 (PREINCREMENT_EXPR, TREE_TYPE (arg0),
08170 TREE_OPERAND (arg0, 0),
08171 TREE_OPERAND (arg0, 1));
08172 }
08173 else
08174 {
08175 newconst = fold_build2 (MINUS_EXPR, TREE_TYPE (arg0),
08176 arg1, TREE_OPERAND (arg0, 1));
08177 varop = build2 (PREDECREMENT_EXPR, TREE_TYPE (arg0),
08178 TREE_OPERAND (arg0, 0),
08179 TREE_OPERAND (arg0, 1));
08180 }
08181
08182
08183
08184
08185 if (TREE_CODE (TREE_OPERAND (varop, 0)) == COMPONENT_REF
08186 && DECL_BIT_FIELD (TREE_OPERAND (TREE_OPERAND (varop, 0), 1))
08187 && host_integerp (DECL_SIZE (TREE_OPERAND
08188 (TREE_OPERAND (varop, 0), 1)), 1))
08189 {
08190 tree fielddecl = TREE_OPERAND (TREE_OPERAND (varop, 0), 1);
08191 HOST_WIDE_INT size = tree_low_cst (DECL_SIZE (fielddecl), 1);
08192 tree folded_compare, shift;
08193
08194
08195
08196
08197 folded_compare = fold_build2 (code, type,
08198 TREE_OPERAND (varop, 0), arg1);
08199 if (TREE_CODE (folded_compare) == INTEGER_CST)
08200 return omit_one_operand (type, folded_compare, varop);
08201
08202 shift = build_int_cst (NULL_TREE,
08203 TYPE_PRECISION (TREE_TYPE (varop)) - size);
08204 shift = fold_convert (TREE_TYPE (varop), shift);
08205 newconst = fold_build2 (LSHIFT_EXPR, TREE_TYPE (varop),
08206 newconst, shift);
08207 newconst = fold_build2 (RSHIFT_EXPR, TREE_TYPE (varop),
08208 newconst, shift);
08209 }
08210
08211 return fold_build2 (code, type, varop, newconst);
08212 }
08213
08214 if (TREE_CODE (TREE_TYPE (arg0)) == INTEGER_TYPE
08215 && (TREE_CODE (arg0) == NOP_EXPR
08216 || TREE_CODE (arg0) == CONVERT_EXPR))
08217 {
08218
08219
08220
08221 tem = fold_widened_comparison (code, type, arg0, arg1);
08222 if (tem)
08223 return tem;
08224
08225
08226 tem = fold_sign_changed_comparison (code, type, arg0, arg1);
08227 if (tem)
08228 return tem;
08229 }
08230
08231
08232
08233 if (TREE_CODE (arg1) == INTEGER_CST
08234 && (TREE_CODE (arg0) == MIN_EXPR
08235 || TREE_CODE (arg0) == MAX_EXPR)
08236 && TREE_CODE (TREE_OPERAND (arg0, 1)) == INTEGER_CST)
08237 {
08238 tem = optimize_minmax_comparison (code, type, op0, op1);
08239 if (tem)
08240 return tem;
08241 }
08242
08243
08244
08245 if (operand_equal_p (arg0, arg1, 0))
08246 {
08247 switch (code)
08248 {
08249 case EQ_EXPR:
08250 if (! FLOAT_TYPE_P (TREE_TYPE (arg0))
08251 || ! HONOR_NANS (TYPE_MODE (TREE_TYPE (arg0))))
08252 return constant_boolean_node (1, type);
08253 break;
08254
08255 case GE_EXPR:
08256 case LE_EXPR:
08257 if (! FLOAT_TYPE_P (TREE_TYPE (arg0))
08258 || ! HONOR_NANS (TYPE_MODE (TREE_TYPE (arg0))))
08259 return constant_boolean_node (1, type);
08260 return fold_build2 (EQ_EXPR, type, arg0, arg1);
08261
08262 case NE_EXPR:
08263
08264
08265 if (FLOAT_TYPE_P (TREE_TYPE (arg0))
08266 && HONOR_NANS (TYPE_MODE (TREE_TYPE (arg0))))
08267 break;
08268
08269 case GT_EXPR:
08270 case LT_EXPR:
08271 return constant_boolean_node (0, type);
08272 default:
08273 gcc_unreachable ();
08274 }
08275 }
08276
08277
08278
08279
08280
08281
08282
08283
08284
08285
08286
08287
08288
08289
08290 if (TREE_CODE (arg1) == INTEGER_CST && TREE_CODE (arg0) != INTEGER_CST)
08291 {
08292 tree cval1 = 0, cval2 = 0;
08293 int save_p = 0;
08294
08295 if (twoval_comparison_p (arg0, &cval1, &cval2, &save_p)
08296
08297
08298 && cval1 != 0 && cval2 != 0
08299 && ! (TREE_CONSTANT (cval1) && TREE_CONSTANT (cval2))
08300 && TREE_TYPE (cval1) == TREE_TYPE (cval2)
08301 && INTEGRAL_TYPE_P (TREE_TYPE (cval1))
08302 && TYPE_MAX_VALUE (TREE_TYPE (cval1))
08303 && TYPE_MAX_VALUE (TREE_TYPE (cval2))
08304 && ! operand_equal_p (TYPE_MIN_VALUE (TREE_TYPE (cval1)),
08305 TYPE_MAX_VALUE (TREE_TYPE (cval2)), 0))
08306 {
08307 tree maxval = TYPE_MAX_VALUE (TREE_TYPE (cval1));
08308 tree minval = TYPE_MIN_VALUE (TREE_TYPE (cval1));
08309
08310
08311
08312
08313 tree high_result
08314 = fold_build2 (code, type,
08315 eval_subst (arg0, cval1, maxval,
08316 cval2, minval),
08317 arg1);
08318 tree equal_result
08319 = fold_build2 (code, type,
08320 eval_subst (arg0, cval1, maxval,
08321 cval2, maxval),
08322 arg1);
08323 tree low_result
08324 = fold_build2 (code, type,
08325 eval_subst (arg0, cval1, minval,
08326 cval2, maxval),
08327 arg1);
08328
08329
08330
08331
08332 if (TREE_CODE (high_result) == INTEGER_CST
08333 && TREE_CODE (equal_result) == INTEGER_CST
08334 && TREE_CODE (low_result) == INTEGER_CST)
08335 {
08336
08337
08338 switch ((integer_onep (high_result) * 4)
08339 + (integer_onep (equal_result) * 2)
08340 + integer_onep (low_result))
08341 {
08342 case 0:
08343
08344 return omit_one_operand (type, integer_zero_node, arg0);
08345 case 1:
08346 code = LT_EXPR;
08347 break;
08348 case 2:
08349 code = EQ_EXPR;
08350 break;
08351 case 3:
08352 code = LE_EXPR;
08353 break;
08354 case 4:
08355 code = GT_EXPR;
08356 break;
08357 case 5:
08358 code = NE_EXPR;
08359 break;
08360 case 6:
08361 code = GE_EXPR;
08362 break;
08363 case 7:
08364
08365 return omit_one_operand (type, integer_one_node, arg0);
08366 }
08367
08368 if (save_p)
08369 return save_expr (build2 (code, type, cval1, cval2));
08370 return fold_build2 (code, type, cval1, cval2);
08371 }
08372 }
08373 }
08374
08375
08376
08377
08378
08379 if (TREE_CODE (arg0) == ADDR_EXPR
08380 && TREE_CODE (TREE_OPERAND (arg0, 0)) == COMPONENT_REF
08381 && TREE_CODE (arg1) == ADDR_EXPR
08382 && TREE_CODE (TREE_OPERAND (arg1, 0)) == COMPONENT_REF)
08383 {
08384 tree cref0 = TREE_OPERAND (arg0, 0);
08385 tree cref1 = TREE_OPERAND (arg1, 0);
08386 if (TREE_OPERAND (cref0, 1) == TREE_OPERAND (cref1, 1))
08387 {
08388 tree op0 = TREE_OPERAND (cref0, 0);
08389 tree op1 = TREE_OPERAND (cref1, 0);
08390 return fold_build2 (code, type,
08391 build_fold_addr_expr (op0),
08392 build_fold_addr_expr (op1));
08393 }
08394 }
08395
08396
08397
08398 if ((TREE_CODE (arg0) == TRUNC_DIV_EXPR
08399 || TREE_CODE (arg0) == EXACT_DIV_EXPR)
08400 && TREE_CODE (arg1) == INTEGER_CST
08401 && TREE_CODE (TREE_OPERAND (arg0, 1)) == INTEGER_CST
08402 && !integer_zerop (TREE_OPERAND (arg0, 1))
08403 && !TREE_OVERFLOW (TREE_OPERAND (arg0, 1))
08404 && !TREE_OVERFLOW (arg1))
08405 {
08406 tem = fold_div_compare (code, type, arg0, arg1);
08407 if (tem != NULL_TREE)
08408 return tem;
08409 }
08410
08411 return NULL_TREE;
08412 }
08413
08414
08415
08416
08417
08418
08419 static tree
08420 fold_mult_zconjz (tree type, tree expr)
08421 {
08422 tree itype = TREE_TYPE (type);
08423 tree rpart, ipart, tem;
08424
08425 if (TREE_CODE (expr) == COMPLEX_EXPR)
08426 {
08427 rpart = TREE_OPERAND (expr, 0);
08428 ipart = TREE_OPERAND (expr, 1);
08429 }
08430 else if (TREE_CODE (expr) == COMPLEX_CST)
08431 {
08432 rpart = TREE_REALPART (expr);
08433 ipart = TREE_IMAGPART (expr);
08434 }
08435 else
08436 {
08437 expr = save_expr (expr);
08438 rpart = fold_build1 (REALPART_EXPR, itype, expr);
08439 ipart = fold_build1 (IMAGPART_EXPR, itype, expr);
08440 }
08441
08442 rpart = save_expr (rpart);
08443 ipart = save_expr (ipart);
08444 tem = fold_build2 (PLUS_EXPR, itype,
08445 fold_build2 (MULT_EXPR, itype, rpart, rpart),
08446 fold_build2 (MULT_EXPR, itype, ipart, ipart));
08447 return fold_build2 (COMPLEX_EXPR, type, tem,
08448 fold_convert (itype, integer_zero_node));
08449 }
08450
08451
08452
08453
08454
08455
08456 tree
08457 fold_binary (enum tree_code code, tree type, tree op0, tree op1)
08458 {
08459 enum tree_code_class kind = TREE_CODE_CLASS (code);
08460 tree arg0, arg1, tem;
08461 tree t1 = NULL_TREE;
08462 bool strict_overflow_p;
08463
08464 gcc_assert (IS_EXPR_CODE_CLASS (kind)
08465 && TREE_CODE_LENGTH (code) == 2
08466 && op0 != NULL_TREE
08467 && op1 != NULL_TREE);
08468
08469 arg0 = op0;
08470 arg1 = op1;
08471
08472
08473
08474
08475
08476
08477
08478
08479
08480
08481
08482
08483
08484 if (kind == tcc_comparison)
08485 {
08486 STRIP_SIGN_NOPS (arg0);
08487 STRIP_SIGN_NOPS (arg1);
08488 }
08489 else
08490 {
08491 STRIP_NOPS (arg0);
08492 STRIP_NOPS (arg1);
08493 }
08494
08495
08496
08497 if ((TREE_CODE (arg0) == INTEGER_CST && TREE_CODE (arg1) == INTEGER_CST)
08498 || (TREE_CODE (arg0) == REAL_CST && TREE_CODE (arg1) == REAL_CST)
08499 || (TREE_CODE (arg0) == COMPLEX_CST && TREE_CODE (arg1) == COMPLEX_CST)
08500 || (TREE_CODE (arg0) == VECTOR_CST && TREE_CODE (arg1) == VECTOR_CST))
08501 {
08502 if (kind == tcc_binary)
08503 tem = const_binop (code, arg0, arg1, 0);
08504 else if (kind == tcc_comparison)
08505 tem = fold_relational_const (code, type, arg0, arg1);
08506 else
08507 tem = NULL_TREE;
08508
08509 if (tem != NULL_TREE)
08510 {
08511 if (TREE_TYPE (tem) != type)
08512 tem = fold_convert (type, tem);
08513 return tem;
08514 }
08515 }
08516
08517
08518
08519 if (commutative_tree_code (code)
08520 && tree_swap_operands_p (arg0, arg1, true))
08521 return fold_build2 (code, type, op1, op0);
08522
08523
08524
08525
08526
08527
08528
08529
08530
08531
08532
08533
08534
08535
08536
08537
08538
08539 if ((code == BIT_AND_EXPR || code == BIT_IOR_EXPR
08540 || code == EQ_EXPR || code == NE_EXPR)
08541 && ((truth_value_p (TREE_CODE (arg0))
08542 && (truth_value_p (TREE_CODE (arg1))
08543 || (TREE_CODE (arg1) == BIT_AND_EXPR
08544 && integer_onep (TREE_OPERAND (arg1, 1)))))
08545 || (truth_value_p (TREE_CODE (arg1))
08546 && (truth_value_p (TREE_CODE (arg0))
08547 || (TREE_CODE (arg0) == BIT_AND_EXPR
08548 && integer_onep (TREE_OPERAND (arg0, 1)))))))
08549 {
08550 tem = fold_build2 (code == BIT_AND_EXPR ? TRUTH_AND_EXPR
08551 : code == BIT_IOR_EXPR ? TRUTH_OR_EXPR
08552 : TRUTH_XOR_EXPR,
08553 boolean_type_node,
08554 fold_convert (boolean_type_node, arg0),
08555 fold_convert (boolean_type_node, arg1));
08556
08557 if (code == EQ_EXPR)
08558 tem = invert_truthvalue (tem);
08559
08560 return fold_convert (type, tem);
08561 }
08562
08563 if (TREE_CODE_CLASS (code) == tcc_binary
08564 || TREE_CODE_CLASS (code) == tcc_comparison)
08565 {
08566 if (TREE_CODE (arg0) == COMPOUND_EXPR)
08567 return build2 (COMPOUND_EXPR, type, TREE_OPERAND (arg0, 0),
08568 fold_build2 (code, type,
08569 TREE_OPERAND (arg0, 1), op1));
08570 if (TREE_CODE (arg1) == COMPOUND_EXPR
08571 && reorder_operands_p (arg0, TREE_OPERAND (arg1, 0)))
08572 return build2 (COMPOUND_EXPR, type, TREE_OPERAND (arg1, 0),
08573 fold_build2 (code, type,
08574 op0, TREE_OPERAND (arg1, 1)));
08575
08576 if (TREE_CODE (arg0) == COND_EXPR || COMPARISON_CLASS_P (arg0))
08577 {
08578 tem = fold_binary_op_with_conditional_arg (code, type, op0, op1,
08579 arg0, arg1,
08580 1);
08581 if (tem != NULL_TREE)
08582 return tem;
08583 }
08584
08585 if (TREE_CODE (arg1) == COND_EXPR || COMPARISON_CLASS_P (arg1))
08586 {
08587 tem = fold_binary_op_with_conditional_arg (code, type, op0, op1,
08588 arg1, arg0,
08589 0);
08590 if (tem != NULL_TREE)
08591 return tem;
08592 }
08593 }
08594
08595 switch (code)
08596 {
08597 case PLUS_EXPR:
08598
08599 if (TREE_CODE (arg1) == NEGATE_EXPR)
08600 return fold_build2 (MINUS_EXPR, type,
08601 fold_convert (type, arg0),
08602 fold_convert (type, TREE_OPERAND (arg1, 0)));
08603
08604 if (TREE_CODE (arg0) == NEGATE_EXPR
08605 && reorder_operands_p (TREE_OPERAND (arg0, 0), arg1))
08606 return fold_build2 (MINUS_EXPR, type,
08607 fold_convert (type, arg1),
08608 fold_convert (type, TREE_OPERAND (arg0, 0)));
08609
08610 if (INTEGRAL_TYPE_P (type)
08611 && TREE_CODE (arg0) == BIT_NOT_EXPR
08612 && integer_onep (arg1))
08613 return fold_build1 (NEGATE_EXPR, type, TREE_OPERAND (arg0, 0));
08614
08615
08616
08617 if ((TREE_CODE (arg0) == MULT_EXPR
08618 || TREE_CODE (arg1) == MULT_EXPR)
08619 && (!FLOAT_TYPE_P (type) || flag_unsafe_math_optimizations))
08620 {
08621 tree tem = fold_plusminus_mult_expr (code, type, arg0, arg1);
08622 if (tem)
08623 return tem;
08624 }
08625
08626 if (! FLOAT_TYPE_P (type))
08627 {
08628 if (integer_zerop (arg1))
08629 return non_lvalue (fold_convert (type, arg0));
08630
08631
08632
08633
08634
08635 if (TREE_CODE (arg0) == BIT_AND_EXPR
08636 && TREE_CODE (arg1) == BIT_AND_EXPR
08637 && TREE_CODE (TREE_OPERAND (arg0, 1)) == INTEGER_CST
08638 && TREE_CODE (TREE_OPERAND (arg1, 1)) == INTEGER_CST
08639 && integer_zerop (const_binop (BIT_AND_EXPR,
08640 TREE_OPERAND (arg0, 1),
08641 TREE_OPERAND (arg1, 1), 0)))
08642 {
08643 code = BIT_IOR_EXPR;
08644 goto bit_ior;
08645 }
08646
08647
08648
08649
08650 if (((TREE_CODE (arg0) == PLUS_EXPR
08651 || TREE_CODE (arg0) == MINUS_EXPR)
08652 && TREE_CODE (arg1) == MULT_EXPR)
08653 || ((TREE_CODE (arg1) == PLUS_EXPR
08654 || TREE_CODE (arg1) == MINUS_EXPR)
08655 && TREE_CODE (arg0) == MULT_EXPR))
08656 {
08657 tree parg0, parg1, parg, marg;
08658 enum tree_code pcode;
08659
08660 if (TREE_CODE (arg1) == MULT_EXPR)
08661 parg = arg0, marg = arg1;
08662 else
08663 parg = arg1, marg = arg0;
08664 pcode = TREE_CODE (parg);
08665 parg0 = TREE_OPERAND (parg, 0);
08666 parg1 = TREE_OPERAND (parg, 1);
08667 STRIP_NOPS (parg0);
08668 STRIP_NOPS (parg1);
08669
08670 if (TREE_CODE (parg0) == MULT_EXPR
08671 && TREE_CODE (parg1) != MULT_EXPR)
08672 return fold_build2 (pcode, type,
08673 fold_build2 (PLUS_EXPR, type,
08674 fold_convert (type, parg0),
08675 fold_convert (type, marg)),
08676 fold_convert (type, parg1));
08677 if (TREE_CODE (parg0) != MULT_EXPR
08678 && TREE_CODE (parg1) == MULT_EXPR)
08679 return fold_build2 (PLUS_EXPR, type,
08680 fold_convert (type, parg0),
08681 fold_build2 (pcode, type,
08682 fold_convert (type, marg),
08683 fold_convert (type,
08684 parg1)));
08685 }
08686
08687
08688
08689
08690 if (TREE_CODE (arg0) == ADDR_EXPR)
08691 {
08692 tem = try_move_mult_to_index (PLUS_EXPR, arg0, arg1);
08693 if (tem)
08694 return fold_convert (type, tem);
08695 }
08696 else if (TREE_CODE (arg1) == ADDR_EXPR)
08697 {
08698 tem = try_move_mult_to_index (PLUS_EXPR, arg1, arg0);
08699 if (tem)
08700 return fold_convert (type, tem);
08701 }
08702 }
08703 else
08704 {
08705
08706 if (fold_real_zero_addition_p (TREE_TYPE (arg0), arg1, 0))
08707 return non_lvalue (fold_convert (type, arg0));
08708
08709
08710 if (fold_real_zero_addition_p (TREE_TYPE (arg1), arg0, 0))
08711 return non_lvalue (fold_convert (type, arg1));
08712
08713
08714 if (TREE_CODE (arg1) == REAL_CST
08715 && REAL_VALUE_NEGATIVE (TREE_REAL_CST (arg1)))
08716 {
08717 tem = fold_negate_const (arg1, type);
08718 if (!TREE_OVERFLOW (arg1) || !flag_trapping_math)
08719 return fold_build2 (MINUS_EXPR, type,
08720 fold_convert (type, arg0),
08721 fold_convert (type, tem));
08722 }
08723
08724 if (flag_unsafe_math_optimizations
08725 && (TREE_CODE (arg0) == RDIV_EXPR || TREE_CODE (arg0) == MULT_EXPR)
08726 && (TREE_CODE (arg1) == RDIV_EXPR || TREE_CODE (arg1) == MULT_EXPR)
08727 && (tem = distribute_real_division (code, type, arg0, arg1)))
08728 return tem;
08729
08730
08731 if (operand_equal_p (arg0, arg1, 0)
08732 && SCALAR_FLOAT_TYPE_P (type))
08733 return fold_build2 (MULT_EXPR, type, arg0,
08734 build_real (type, dconst2));
08735
08736
08737 if (flag_unsafe_math_optimizations
08738 && TREE_CODE (arg1) == PLUS_EXPR
08739 && TREE_CODE (arg0) != MULT_EXPR)
08740 {
08741 tree tree10 = TREE_OPERAND (arg1, 0);
08742 tree tree11 = TREE_OPERAND (arg1, 1);
08743 if (TREE_CODE (tree11) == MULT_EXPR
08744 && TREE_CODE (tree10) == MULT_EXPR)
08745 {
08746 tree tree0;
08747 tree0 = fold_build2 (PLUS_EXPR, type, arg0, tree10);
08748 return fold_build2 (PLUS_EXPR, type, tree0, tree11);
08749 }
08750 }
08751
08752 if (flag_unsafe_math_optimizations
08753 && TREE_CODE (arg0) == PLUS_EXPR
08754 && TREE_CODE (arg1) != MULT_EXPR)
08755 {
08756 tree tree00 = TREE_OPERAND (arg0, 0);
08757 tree tree01 = TREE_OPERAND (arg0, 1);
08758 if (TREE_CODE (tree01) == MULT_EXPR
08759 && TREE_CODE (tree00) == MULT_EXPR)
08760 {
08761 tree tree0;
08762 tree0 = fold_build2 (PLUS_EXPR, type, tree01, arg1);
08763 return fold_build2 (PLUS_EXPR, type, tree00, tree0);
08764 }
08765 }
08766 }
08767
08768 bit_rotate:
08769
08770
08771
08772
08773 {
08774 enum tree_code code0, code1;
08775 code0 = TREE_CODE (arg0);
08776 code1 = TREE_CODE (arg1);
08777 if (((code0 == RSHIFT_EXPR && code1 == LSHIFT_EXPR)
08778 || (code1 == RSHIFT_EXPR && code0 == LSHIFT_EXPR))
08779 && operand_equal_p (TREE_OPERAND (arg0, 0),
08780 TREE_OPERAND (arg1, 0), 0)
08781 && TYPE_UNSIGNED (TREE_TYPE (TREE_OPERAND (arg0, 0))))
08782 {
08783 tree tree01, tree11;
08784 enum tree_code code01, code11;
08785
08786 tree01 = TREE_OPERAND (arg0, 1);
08787 tree11 = TREE_OPERAND (arg1, 1);
08788 STRIP_NOPS (tree01);
08789 STRIP_NOPS (tree11);
08790 code01 = TREE_CODE (tree01);
08791 code11 = TREE_CODE (tree11);
08792 if (code01 == INTEGER_CST
08793 && code11 == INTEGER_CST
08794 && TREE_INT_CST_HIGH (tree01) == 0
08795 && TREE_INT_CST_HIGH (tree11) == 0
08796 && ((TREE_INT_CST_LOW (tree01) + TREE_INT_CST_LOW (tree11))
08797 == TYPE_PRECISION (TREE_TYPE (TREE_OPERAND (arg0, 0)))))
08798 return build2 (LROTATE_EXPR, type, TREE_OPERAND (arg0, 0),
08799 code0 == LSHIFT_EXPR ? tree01 : tree11);
08800 else if (code11 == MINUS_EXPR)
08801 {
08802 tree tree110, tree111;
08803 tree110 = TREE_OPERAND (tree11, 0);
08804 tree111 = TREE_OPERAND (tree11, 1);
08805 STRIP_NOPS (tree110);
08806 STRIP_NOPS (tree111);
08807 if (TREE_CODE (tree110) == INTEGER_CST
08808 && 0 == compare_tree_int (tree110,
08809 TYPE_PRECISION
08810 (TREE_TYPE (TREE_OPERAND
08811 (arg0, 0))))
08812 && operand_equal_p (tree01, tree111, 0))
08813 return build2 ((code0 == LSHIFT_EXPR
08814 ? LROTATE_EXPR
08815 : RROTATE_EXPR),
08816 type, TREE_OPERAND (arg0, 0), tree01);
08817 }
08818 else if (code01 == MINUS_EXPR)
08819 {
08820 tree tree010, tree011;
08821 tree010 = TREE_OPERAND (tree01, 0);
08822 tree011 = TREE_OPERAND (tree01, 1);
08823 STRIP_NOPS (tree010);
08824 STRIP_NOPS (tree011);
08825 if (TREE_CODE (tree010) == INTEGER_CST
08826 && 0 == compare_tree_int (tree010,
08827 TYPE_PRECISION
08828 (TREE_TYPE (TREE_OPERAND
08829 (arg0, 0))))
08830 && operand_equal_p (tree11, tree011, 0))
08831 return build2 ((code0 != LSHIFT_EXPR
08832 ? LROTATE_EXPR
08833 : RROTATE_EXPR),
08834 type, TREE_OPERAND (arg0, 0), tree11);
08835 }
08836 }
08837 }
08838
08839 associate:
08840
08841
08842
08843
08844
08845 if (! FLOAT_TYPE_P (type) || flag_unsafe_math_optimizations)
08846 {
08847 tree var0, con0, lit0, minus_lit0;
08848 tree var1, con1, lit1, minus_lit1;
08849 bool ok = true;
08850
08851
08852
08853
08854
08855
08856 var0 = split_tree (arg0, code, &con0, &lit0, &minus_lit0, 0);
08857 var1 = split_tree (arg1, code, &con1, &lit1, &minus_lit1,
08858 code == MINUS_EXPR);
08859
08860
08861
08862 if ((POINTER_TYPE_P (type)
08863 || (INTEGRAL_TYPE_P (type)
08864 && !(TYPE_UNSIGNED (type) || flag_wrapv)))
08865 && var0 && var1)
08866 {
08867 tree tmp0 = var0;
08868 tree tmp1 = var1;
08869
08870 if (TREE_CODE (tmp0) == NEGATE_EXPR)
08871 tmp0 = TREE_OPERAND (tmp0, 0);
08872 if (TREE_CODE (tmp1) == NEGATE_EXPR)
08873 tmp1 = TREE_OPERAND (tmp1, 0);
08874
08875
08876 if (!operand_equal_p (tmp0, tmp1, 0))
08877 ok = false;
08878 }
08879
08880
08881
08882 if (ok
08883 && (2 < ((var0 != 0) + (var1 != 0)
08884 + (con0 != 0) + (con1 != 0)
08885 + (lit0 != 0) + (lit1 != 0)
08886 + (minus_lit0 != 0) + (minus_lit1 != 0))))
08887 {
08888
08889 if (code == MINUS_EXPR)
08890 code = PLUS_EXPR;
08891
08892 var0 = associate_trees (var0, var1, code, type);
08893 con0 = associate_trees (con0, con1, code, type);
08894 lit0 = associate_trees (lit0, lit1, code, type);
08895 minus_lit0 = associate_trees (minus_lit0, minus_lit1, code, type);
08896
08897
08898
08899
08900
08901
08902 if (minus_lit0 && lit0)
08903 {
08904 if (TREE_CODE (lit0) == INTEGER_CST
08905 && TREE_CODE (minus_lit0) == INTEGER_CST
08906 && tree_int_cst_lt (lit0, minus_lit0))
08907 {
08908 minus_lit0 = associate_trees (minus_lit0, lit0,
08909 MINUS_EXPR, type);
08910 lit0 = 0;
08911 }
08912 else
08913 {
08914 lit0 = associate_trees (lit0, minus_lit0,
08915 MINUS_EXPR, type);
08916 minus_lit0 = 0;
08917 }
08918 }
08919 if (minus_lit0)
08920 {
08921 if (con0 == 0)
08922 return fold_convert (type,
08923 associate_trees (var0, minus_lit0,
08924 MINUS_EXPR, type));
08925 else
08926 {
08927 con0 = associate_trees (con0, minus_lit0,
08928 MINUS_EXPR, type);
08929 return fold_convert (type,
08930 associate_trees (var0, con0,
08931 PLUS_EXPR, type));
08932 }
08933 }
08934
08935 con0 = associate_trees (con0, lit0, code, type);
08936 return fold_convert (type, associate_trees (var0, con0,
08937 code, type));
08938 }
08939 }
08940
08941 return NULL_TREE;
08942
08943 case MINUS_EXPR:
08944
08945 if (TREE_CODE (arg1) == NEGATE_EXPR)
08946 return fold_build2 (PLUS_EXPR, type, arg0, TREE_OPERAND (arg1, 0));
08947
08948 if (TREE_CODE (arg0) == NEGATE_EXPR
08949 && (FLOAT_TYPE_P (type)
08950 || (INTEGRAL_TYPE_P (type) && flag_wrapv && !flag_trapv))
08951 && negate_expr_p (arg1)
08952 && reorder_operands_p (arg0, arg1))
08953 return fold_build2 (MINUS_EXPR, type, negate_expr (arg1),
08954 TREE_OPERAND (arg0, 0));
08955
08956 if (INTEGRAL_TYPE_P (type)
08957 && TREE_CODE (arg0) == NEGATE_EXPR
08958 && integer_onep (arg1))
08959 return fold_build1 (BIT_NOT_EXPR, type,
08960 fold_convert (type, TREE_OPERAND (arg0, 0)));
08961
08962
08963 if (INTEGRAL_TYPE_P (type)
08964 && integer_all_onesp (arg0))
08965 return fold_build1 (BIT_NOT_EXPR, type, arg1);
08966
08967 if (! FLOAT_TYPE_P (type))
08968 {
08969 if (integer_zerop (arg0))
08970 return negate_expr (fold_convert (type, arg1));
08971 if (integer_zerop (arg1))
08972 return non_lvalue (fold_convert (type, arg0));
08973
08974
08975 if (!TREE_SIDE_EFFECTS (arg0)
08976 && TREE_CODE (arg1) == BIT_AND_EXPR)
08977 {
08978 if (operand_equal_p (arg0, TREE_OPERAND (arg1, 1), 0))
08979 return fold_build2 (BIT_AND_EXPR, type,
08980 fold_build1 (BIT_NOT_EXPR, type,
08981 TREE_OPERAND (arg1, 0)),
08982 arg0);
08983 if (operand_equal_p (arg0, TREE_OPERAND (arg1, 0), 0))
08984 return fold_build2 (BIT_AND_EXPR, type,
08985 fold_build1 (BIT_NOT_EXPR, type,
08986 TREE_OPERAND (arg1, 1)),
08987 arg0);
08988 }
08989
08990
08991
08992 if (TREE_CODE (arg0) == BIT_AND_EXPR
08993 && TREE_CODE (arg1) == BIT_AND_EXPR
08994 && operand_equal_p (TREE_OPERAND (arg0, 0),
08995 TREE_OPERAND (arg1, 0), 0))
08996 {
08997 tree mask0 = TREE_OPERAND (arg0, 1);
08998 tree mask1 = TREE_OPERAND (arg1, 1);
08999 tree tem = fold_build1 (BIT_NOT_EXPR, type, mask0);
09000
09001 if (operand_equal_p (tem, mask1, 0))
09002 {
09003 tem = fold_build2 (BIT_XOR_EXPR, type,
09004 TREE_OPERAND (arg0, 0), mask1);
09005 return fold_build2 (MINUS_EXPR, type, tem, mask1);
09006 }
09007 }
09008 }
09009
09010
09011 else if (fold_real_zero_addition_p (TREE_TYPE (arg0), arg1, 1))
09012 return non_lvalue (fold_convert (type, arg0));
09013
09014
09015
09016
09017 else if (fold_real_zero_addition_p (TREE_TYPE (arg1), arg0, 0))
09018 return negate_expr (fold_convert (type, arg1));
09019
09020
09021
09022
09023
09024
09025
09026 if ((! FLOAT_TYPE_P (type) || flag_unsafe_math_optimizations)
09027 && operand_equal_p (arg0, arg1, 0))
09028 return fold_convert (type, integer_zero_node);
09029
09030
09031 if (negate_expr_p (arg1)
09032 && ((FLOAT_TYPE_P (type)
09033
09034 && (TREE_CODE (arg1) != REAL_CST
09035 || REAL_VALUE_NEGATIVE (TREE_REAL_CST (arg1))))
09036 || (INTEGRAL_TYPE_P (type) && flag_wrapv && !flag_trapv)))
09037 return fold_build2 (PLUS_EXPR, type,
09038 fold_convert (type, arg0),
09039 fold_convert (type, negate_expr (arg1)));
09040
09041
09042 {
09043 HOST_WIDE_INT diff;
09044
09045 if ((TREE_CODE (arg0) == ADDR_EXPR
09046 || TREE_CODE (arg1) == ADDR_EXPR)
09047 && ptr_difference_const (arg0, arg1, &diff))
09048 return build_int_cst_type (type, diff);
09049 }
09050
09051
09052 if (TREE_CODE (arg0) == ADDR_EXPR
09053 && TREE_CODE (TREE_OPERAND (arg0, 0)) == ARRAY_REF
09054 && TREE_CODE (arg1) == ADDR_EXPR
09055 && TREE_CODE (TREE_OPERAND (arg1, 0)) == ARRAY_REF)
09056 {
09057 tree aref0 = TREE_OPERAND (arg0, 0);
09058 tree aref1 = TREE_OPERAND (arg1, 0);
09059 if (operand_equal_p (TREE_OPERAND (aref0, 0),
09060 TREE_OPERAND (aref1, 0), 0))
09061 {
09062 tree op0 = fold_convert (type, TREE_OPERAND (aref0, 1));
09063 tree op1 = fold_convert (type, TREE_OPERAND (aref1, 1));
09064 tree esz = array_ref_element_size (aref0);
09065 tree diff = build2 (MINUS_EXPR, type, op0, op1);
09066 return fold_build2 (MULT_EXPR, type, diff,
09067 fold_convert (type, esz));
09068
09069 }
09070 }
09071
09072
09073
09074
09075 if (TREE_CODE (arg0) == ADDR_EXPR)
09076 {
09077 tem = try_move_mult_to_index (MINUS_EXPR, arg0, arg1);
09078 if (tem)
09079 return fold_convert (type, tem);
09080 }
09081
09082 if (flag_unsafe_math_optimizations
09083 && (TREE_CODE (arg0) == RDIV_EXPR || TREE_CODE (arg0) == MULT_EXPR)
09084 && (TREE_CODE (arg1) == RDIV_EXPR || TREE_CODE (arg1) == MULT_EXPR)
09085 && (tem = distribute_real_division (code, type, arg0, arg1)))
09086 return tem;
09087
09088
09089
09090 if ((TREE_CODE (arg0) == MULT_EXPR
09091 || TREE_CODE (arg1) == MULT_EXPR)
09092 && (!FLOAT_TYPE_P (type) || flag_unsafe_math_optimizations))
09093 {
09094 tree tem = fold_plusminus_mult_expr (code, type, arg0, arg1);
09095 if (tem)
09096 return tem;
09097 }
09098
09099 goto associate;
09100
09101 case MULT_EXPR:
09102
09103 #ifdef KEY // bug 11662: (-A) * const -> A * (-const) causes str reduction bug,
09104
09105 if (flag_spin_file) {
09106 if (TREE_CODE (arg0) == NEGATE_EXPR && TREE_CODE (arg1) == NEGATE_EXPR)
09107 return fold (build2(MULT_EXPR, type, TREE_OPERAND (arg0, 0),
09108 TREE_OPERAND (arg1, 0)));
09109 }
09110 else {
09111 #endif
09112 if (TREE_CODE (arg0) == NEGATE_EXPR && negate_expr_p (arg1))
09113 return fold_build2 (MULT_EXPR, type,
09114 fold_convert (type, TREE_OPERAND (arg0, 0)),
09115 fold_convert (type, negate_expr (arg1)));
09116 if (TREE_CODE (arg1) == NEGATE_EXPR && negate_expr_p (arg0))
09117 return fold_build2 (MULT_EXPR, type,
09118 fold_convert (type, negate_expr (arg0)),
09119 fold_convert (type, TREE_OPERAND (arg1, 0)));
09120 #ifdef KEY // bug 11662
09121 }
09122 #endif
09123
09124 if (! FLOAT_TYPE_P (type))
09125 {
09126 if (integer_zerop (arg1))
09127 return omit_one_operand (type, arg1, arg0);
09128 if (integer_onep (arg1))
09129 return non_lvalue (fold_convert (type, arg0));
09130
09131 if (integer_all_onesp (arg1))
09132 return fold_convert (type, negate_expr (arg0));
09133
09134
09135 if (TREE_CODE (arg1) == LSHIFT_EXPR
09136 && integer_onep (TREE_OPERAND (arg1, 0)))
09137 return fold_build2 (LSHIFT_EXPR, type, arg0,
09138 TREE_OPERAND (arg1, 1));
09139 if (TREE_CODE (arg0) == LSHIFT_EXPR
09140 && integer_onep (TREE_OPERAND (arg0, 0)))
09141 return fold_build2 (LSHIFT_EXPR, type, arg1,
09142 TREE_OPERAND (arg0, 1));
09143
09144 strict_overflow_p = false;
09145 if (TREE_CODE (arg1) == INTEGER_CST
09146 && 0 != (tem = extract_muldiv (op0,
09147 fold_convert (type, arg1),
09148 code, NULL_TREE,
09149 &strict_overflow_p)))
09150 {
09151 if (strict_overflow_p)
09152 fold_overflow_warning (("assuming signed overflow does not "
09153 "occur when simplifying "
09154 "multiplication"),
09155 WARN_STRICT_OVERFLOW_MISC);
09156 return fold_convert (type, tem);
09157 }
09158
09159
09160 if (TREE_CODE (arg0) == CONJ_EXPR
09161 && operand_equal_p (TREE_OPERAND (arg0, 0), arg1, 0))
09162 return fold_mult_zconjz (type, arg1);
09163 if (TREE_CODE (arg1) == CONJ_EXPR
09164 && operand_equal_p (arg0, TREE_OPERAND (arg1, 0), 0))
09165 return fold_mult_zconjz (type, arg0);
09166 }
09167 else
09168 {
09169
09170
09171
09172
09173 if (!HONOR_NANS (TYPE_MODE (TREE_TYPE (arg0)))
09174 && !HONOR_SIGNED_ZEROS (TYPE_MODE (TREE_TYPE (arg0)))
09175 && real_zerop (arg1))
09176 return omit_one_operand (type, arg1, arg0);
09177
09178 if (!HONOR_SNANS (TYPE_MODE (TREE_TYPE (arg0)))
09179 && real_onep (arg1))
09180 return non_lvalue (fold_convert (type, arg0));
09181
09182
09183 if (!HONOR_SNANS (TYPE_MODE (TREE_TYPE (arg0)))
09184 && real_minus_onep (arg1))
09185 return fold_convert (type, negate_expr (arg0));
09186
09187
09188 if (flag_unsafe_math_optimizations
09189 && TREE_CODE (arg0) == RDIV_EXPR
09190 && TREE_CODE (arg1) == REAL_CST
09191 && TREE_CODE (TREE_OPERAND (arg0, 0)) == REAL_CST)
09192 {
09193 tree tem = const_binop (MULT_EXPR, TREE_OPERAND (arg0, 0),
09194 arg1, 0);
09195 if (tem)
09196 return fold_build2 (RDIV_EXPR, type, tem,
09197 TREE_OPERAND (arg0, 1));
09198 }
09199
09200
09201 if (operand_equal_p (arg0, arg1, 0))
09202 {
09203 tree tem = fold_strip_sign_ops (arg0);
09204 if (tem != NULL_TREE)
09205 {
09206 tem = fold_convert (type, tem);
09207 return fold_build2 (MULT_EXPR, type, tem, tem);
09208 }
09209 }
09210
09211
09212
09213
09214 if (flag_unsafe_math_optimizations
09215 && TREE_CODE (arg0) == CONJ_EXPR
09216 && operand_equal_p (TREE_OPERAND (arg0, 0), arg1, 0))
09217 return fold_mult_zconjz (type, arg1);
09218 if (flag_unsafe_math_optimizations
09219 && TREE_CODE (arg1) == CONJ_EXPR
09220 && operand_equal_p (arg0, TREE_OPERAND (arg1, 0), 0))
09221 return fold_mult_zconjz (type, arg0);
09222
09223 if (flag_unsafe_math_optimizations)
09224 {
09225 enum built_in_function fcode0 = builtin_mathfn_code (arg0);
09226 enum built_in_function fcode1 = builtin_mathfn_code (arg1);
09227
09228
09229 if (fcode0 == fcode1 && BUILTIN_ROOT_P (fcode0))
09230 {
09231 tree rootfn, arg, arglist;
09232 tree arg00 = TREE_VALUE (TREE_OPERAND (arg0, 1));
09233 tree arg10 = TREE_VALUE (TREE_OPERAND (arg1, 1));
09234
09235
09236 if (BUILTIN_SQRT_P (fcode0)
09237 && operand_equal_p (arg00, arg10, 0)
09238 && ! HONOR_SNANS (TYPE_MODE (type)))
09239 return arg00;
09240
09241
09242 rootfn = TREE_OPERAND (TREE_OPERAND (arg0, 0), 0);
09243 arg = fold_build2 (MULT_EXPR, type, arg00, arg10);
09244 arglist = build_tree_list (NULL_TREE, arg);
09245 return build_function_call_expr (rootfn, arglist);
09246 }
09247
09248
09249 if (fcode0 == fcode1 && BUILTIN_EXPONENT_P (fcode0))
09250 {
09251 tree expfn = TREE_OPERAND (TREE_OPERAND (arg0, 0), 0);
09252 tree arg = fold_build2 (PLUS_EXPR, type,
09253 TREE_VALUE (TREE_OPERAND (arg0, 1)),
09254 TREE_VALUE (TREE_OPERAND (arg1, 1)));
09255 tree arglist = build_tree_list (NULL_TREE, arg);
09256 return build_function_call_expr (expfn, arglist);
09257 }
09258
09259
09260 if ((fcode0 == BUILT_IN_POW && fcode1 == BUILT_IN_POW)
09261 || (fcode0 == BUILT_IN_POWF && fcode1 == BUILT_IN_POWF)
09262 || (fcode0 == BUILT_IN_POWL && fcode1 == BUILT_IN_POWL))
09263 {
09264 tree arg00 = TREE_VALUE (TREE_OPERAND (arg0, 1));
09265 tree arg01 = TREE_VALUE (TREE_CHAIN (TREE_OPERAND (arg0,
09266 1)));
09267 tree arg10 = TREE_VALUE (TREE_OPERAND (arg1, 1));
09268 tree arg11 = TREE_VALUE (TREE_CHAIN (TREE_OPERAND (arg1,
09269 1)));
09270
09271
09272 if (operand_equal_p (arg01, arg11, 0))
09273 {
09274 tree powfn = TREE_OPERAND (TREE_OPERAND (arg0, 0), 0);
09275 tree arg = fold_build2 (MULT_EXPR, type, arg00, arg10);
09276 tree arglist = tree_cons (NULL_TREE, arg,
09277 build_tree_list (NULL_TREE,
09278 arg01));
09279 return build_function_call_expr (powfn, arglist);
09280 }
09281
09282
09283 if (operand_equal_p (arg00, arg10, 0))
09284 {
09285 tree powfn = TREE_OPERAND (TREE_OPERAND (arg0, 0), 0);
09286 tree arg = fold_build2 (PLUS_EXPR, type, arg01, arg11);
09287 tree arglist = tree_cons (NULL_TREE, arg00,
09288 build_tree_list (NULL_TREE,
09289 arg));
09290 return build_function_call_expr (powfn, arglist);
09291 }
09292 }
09293
09294
09295 if (((fcode0 == BUILT_IN_TAN && fcode1 == BUILT_IN_COS)
09296 || (fcode0 == BUILT_IN_TANF && fcode1 == BUILT_IN_COSF)
09297 || (fcode0 == BUILT_IN_TANL && fcode1 == BUILT_IN_COSL)
09298 || (fcode0 == BUILT_IN_COS && fcode1 == BUILT_IN_TAN)
09299 || (fcode0 == BUILT_IN_COSF && fcode1 == BUILT_IN_TANF)
09300 || (fcode0 == BUILT_IN_COSL && fcode1 == BUILT_IN_TANL))
09301 && operand_equal_p (TREE_VALUE (TREE_OPERAND (arg0, 1)),
09302 TREE_VALUE (TREE_OPERAND (arg1, 1)), 0))
09303 {
09304 tree sinfn = mathfn_built_in (type, BUILT_IN_SIN);
09305
09306 if (sinfn != NULL_TREE)
09307 return build_function_call_expr (sinfn,
09308 TREE_OPERAND (arg0, 1));
09309 }
09310
09311
09312 if (fcode1 == BUILT_IN_POW
09313 || fcode1 == BUILT_IN_POWF
09314 || fcode1 == BUILT_IN_POWL)
09315 {
09316 tree arg10 = TREE_VALUE (TREE_OPERAND (arg1, 1));
09317 tree arg11 = TREE_VALUE (TREE_CHAIN (TREE_OPERAND (arg1,
09318 1)));
09319 if (TREE_CODE (arg11) == REAL_CST
09320 && ! TREE_CONSTANT_OVERFLOW (arg11)
09321 && operand_equal_p (arg0, arg10, 0))
09322 {
09323 tree powfn = TREE_OPERAND (TREE_OPERAND (arg1, 0), 0);
09324 REAL_VALUE_TYPE c;
09325 tree arg, arglist;
09326
09327 c = TREE_REAL_CST (arg11);
09328 real_arithmetic (&c, PLUS_EXPR, &c, &dconst1);
09329 arg = build_real (type, c);
09330 arglist = build_tree_list (NULL_TREE, arg);
09331 arglist = tree_cons (NULL_TREE, arg0, arglist);
09332 return build_function_call_expr (powfn, arglist);
09333 }
09334 }
09335
09336
09337 if (fcode0 == BUILT_IN_POW
09338 || fcode0 == BUILT_IN_POWF
09339 || fcode0 == BUILT_IN_POWL)
09340 {
09341 tree arg00 = TREE_VALUE (TREE_OPERAND (arg0, 1));
09342 tree arg01 = TREE_VALUE (TREE_CHAIN (TREE_OPERAND (arg0,
09343 1)));
09344 if (TREE_CODE (arg01) == REAL_CST
09345 && ! TREE_CONSTANT_OVERFLOW (arg01)
09346 && operand_equal_p (arg1, arg00, 0))
09347 {
09348 tree powfn = TREE_OPERAND (TREE_OPERAND (arg0, 0), 0);
09349 REAL_VALUE_TYPE c;
09350 tree arg, arglist;
09351
09352 c = TREE_REAL_CST (arg01);
09353 real_arithmetic (&c, PLUS_EXPR, &c, &dconst1);
09354 arg = build_real (type, c);
09355 arglist = build_tree_list (NULL_TREE, arg);
09356 arglist = tree_cons (NULL_TREE, arg1, arglist);
09357 return build_function_call_expr (powfn, arglist);
09358 }
09359 }
09360
09361 #ifdef KEY
09362
09363
09364
09365
09366
09367
09368
09369 if (!flag_spin_file)
09370 #endif
09371
09372 if (! optimize_size
09373 && operand_equal_p (arg0, arg1, 0))
09374 {
09375 tree powfn = mathfn_built_in (type, BUILT_IN_POW);
09376
09377 if (powfn)
09378 {
09379 tree arg = build_real (type, dconst2);
09380 tree arglist = build_tree_list (NULL_TREE, arg);
09381 arglist = tree_cons (NULL_TREE, arg0, arglist);
09382 return build_function_call_expr (powfn, arglist);
09383 }
09384 }
09385 }
09386 }
09387 goto associate;
09388
09389 case BIT_IOR_EXPR:
09390 bit_ior:
09391 if (integer_all_onesp (arg1))
09392 return omit_one_operand (type, arg1, arg0);
09393 if (integer_zerop (arg1))
09394 return non_lvalue (fold_convert (type, arg0));
09395 if (operand_equal_p (arg0, arg1, 0))
09396 return non_lvalue (fold_convert (type, arg0));
09397
09398
09399 if (TREE_CODE (arg0) == BIT_NOT_EXPR
09400 && operand_equal_p (TREE_OPERAND (arg0, 0), arg1, 0))
09401 {
09402 t1 = build_int_cst (type, -1);
09403 t1 = force_fit_type (t1, 0, false, false);
09404 return omit_one_operand (type, t1, arg1);
09405 }
09406
09407
09408 if (TREE_CODE (arg1) == BIT_NOT_EXPR
09409 && operand_equal_p (arg0, TREE_OPERAND (arg1, 0), 0))
09410 {
09411 t1 = build_int_cst (type, -1);
09412 t1 = force_fit_type (t1, 0, false, false);
09413 return omit_one_operand (type, t1, arg0);
09414 }
09415
09416
09417 if (TREE_CODE (arg0) == BIT_AND_EXPR
09418 && TREE_CODE (arg1) == INTEGER_CST
09419 && TREE_CODE (TREE_OPERAND (arg0, 1)) == INTEGER_CST)
09420 {
09421 unsigned HOST_WIDE_INT hi1, lo1, hi2, lo2, mlo, mhi;
09422 int width = TYPE_PRECISION (type);
09423 hi1 = TREE_INT_CST_HIGH (TREE_OPERAND (arg0, 1));
09424 lo1 = TREE_INT_CST_LOW (TREE_OPERAND (arg0, 1));
09425 hi2 = TREE_INT_CST_HIGH (arg1);
09426 lo2 = TREE_INT_CST_LOW (arg1);
09427
09428
09429 if ((hi1 & hi2) == hi1 && (lo1 & lo2) == lo1)
09430 return omit_one_operand (type, arg1, TREE_OPERAND (arg0, 0));
09431
09432 if (width > HOST_BITS_PER_WIDE_INT)
09433 {
09434 mhi = (unsigned HOST_WIDE_INT) -1
09435 >> (2 * HOST_BITS_PER_WIDE_INT - width);
09436 mlo = -1;
09437 }
09438 else
09439 {
09440 mhi = 0;
09441 mlo = (unsigned HOST_WIDE_INT) -1
09442 >> (HOST_BITS_PER_WIDE_INT - width);
09443 }
09444
09445
09446 if ((~(hi1 | hi2) & mhi) == 0 && (~(lo1 | lo2) & mlo) == 0)
09447 return fold_build2 (BIT_IOR_EXPR, type,
09448 TREE_OPERAND (arg0, 0), arg1);
09449
09450
09451 hi1 &= mhi;
09452 lo1 &= mlo;
09453 if ((hi1 & ~hi2) != hi1 || (lo1 & ~lo2) != lo1)
09454 return fold_build2 (BIT_IOR_EXPR, type,
09455 fold_build2 (BIT_AND_EXPR, type,
09456 TREE_OPERAND (arg0, 0),
09457 build_int_cst_wide (type,
09458 lo1 & ~lo2,
09459 hi1 & ~hi2)),
09460 arg1);
09461 }
09462
09463
09464 if (TREE_CODE (arg0) == BIT_AND_EXPR
09465 && operand_equal_p (TREE_OPERAND (arg0, 1), arg1, 0))
09466 return omit_one_operand (type, arg1, TREE_OPERAND (arg0, 0));
09467
09468 if (TREE_CODE (arg0) == BIT_AND_EXPR
09469 && operand_equal_p (TREE_OPERAND (arg0, 0), arg1, 0)
09470 && reorder_operands_p (TREE_OPERAND (arg0, 1), arg1))
09471 return omit_one_operand (type, arg1, TREE_OPERAND (arg0, 1));
09472
09473 if (TREE_CODE (arg1) == BIT_AND_EXPR
09474 && operand_equal_p (arg0, TREE_OPERAND (arg1, 0), 0)
09475 && reorder_operands_p (arg0, TREE_OPERAND (arg1, 1)))
09476 return omit_one_operand (type, arg0, TREE_OPERAND (arg1, 1));
09477
09478 if (TREE_CODE (arg1) == BIT_AND_EXPR
09479 && operand_equal_p (arg0, TREE_OPERAND (arg1, 1), 0)
09480 && reorder_operands_p (arg0, TREE_OPERAND (arg1, 0)))
09481 return omit_one_operand (type, arg0, TREE_OPERAND (arg1, 0));
09482
09483 t1 = distribute_bit_expr (code, type, arg0, arg1);
09484 if (t1 != NULL_TREE)
09485 return t1;
09486
09487
09488
09489
09490
09491
09492
09493 if (TREE_CODE (arg0) == BIT_NOT_EXPR
09494 && TREE_CODE (arg1) == BIT_NOT_EXPR)
09495 {
09496 return fold_build1 (BIT_NOT_EXPR, type,
09497 build2 (BIT_AND_EXPR, type,
09498 TREE_OPERAND (arg0, 0),
09499 TREE_OPERAND (arg1, 0)));
09500 }
09501
09502
09503
09504 goto bit_rotate;
09505
09506 case BIT_XOR_EXPR:
09507 if (integer_zerop (arg1))
09508 return non_lvalue (fold_convert (type, arg0));
09509 if (integer_all_onesp (arg1))
09510 return fold_build1 (BIT_NOT_EXPR, type, arg0);
09511 if (operand_equal_p (arg0, arg1, 0))
09512 return omit_one_operand (type, integer_zero_node, arg0);
09513
09514
09515 if (TREE_CODE (arg0) == BIT_NOT_EXPR
09516 && operand_equal_p (TREE_OPERAND (arg0, 0), arg1, 0))
09517 {
09518 t1 = build_int_cst (type, -1);
09519 t1 = force_fit_type (t1, 0, false, false);
09520 return omit_one_operand (type, t1, arg1);
09521 }
09522
09523
09524 if (TREE_CODE (arg1) == BIT_NOT_EXPR
09525 && operand_equal_p (arg0, TREE_OPERAND (arg1, 0), 0))
09526 {
09527 t1 = build_int_cst (type, -1);
09528 t1 = force_fit_type (t1, 0, false, false);
09529 return omit_one_operand (type, t1, arg0);
09530 }
09531
09532
09533
09534
09535
09536 if (TREE_CODE (arg0) == BIT_AND_EXPR
09537 && TREE_CODE (arg1) == BIT_AND_EXPR
09538 && TREE_CODE (TREE_OPERAND (arg0, 1)) == INTEGER_CST
09539 && TREE_CODE (TREE_OPERAND (arg1, 1)) == INTEGER_CST
09540 && integer_zerop (const_binop (BIT_AND_EXPR,
09541 TREE_OPERAND (arg0, 1),
09542 TREE_OPERAND (arg1, 1), 0)))
09543 {
09544 code = BIT_IOR_EXPR;
09545 goto bit_ior;
09546 }
09547
09548
09549 if (TREE_CODE (arg0) == BIT_IOR_EXPR
09550 && operand_equal_p (TREE_OPERAND (arg0, 0), arg1, 0))
09551 {
09552 tree t2 = TREE_OPERAND (arg0, 1);
09553 t1 = fold_build1 (BIT_NOT_EXPR, TREE_TYPE (arg1),
09554 arg1);
09555 t1 = fold_build2 (BIT_AND_EXPR, type, fold_convert (type, t2),
09556 fold_convert (type, t1));
09557 return t1;
09558 }
09559
09560
09561 if (TREE_CODE (arg0) == BIT_IOR_EXPR
09562 && operand_equal_p (TREE_OPERAND (arg0, 1), arg1, 0))
09563 {
09564 tree t2 = TREE_OPERAND (arg0, 0);
09565 t1 = fold_build1 (BIT_NOT_EXPR, TREE_TYPE (arg1),
09566 arg1);
09567 t1 = fold_build2 (BIT_AND_EXPR, type, fold_convert (type, t2),
09568 fold_convert (type, t1));
09569 return t1;
09570 }
09571
09572
09573 if (TREE_CODE (arg1) == BIT_IOR_EXPR
09574 && operand_equal_p (TREE_OPERAND (arg1, 0), arg0, 0))
09575 {
09576 tree t2 = TREE_OPERAND (arg1, 1);
09577 t1 = fold_build1 (BIT_NOT_EXPR, TREE_TYPE (arg0),
09578 arg0);
09579 t1 = fold_build2 (BIT_AND_EXPR, type, fold_convert (type, t2),
09580 fold_convert (type, t1));
09581 return t1;
09582 }
09583
09584
09585 if (TREE_CODE (arg1) == BIT_IOR_EXPR
09586 && operand_equal_p (TREE_OPERAND (arg1, 1), arg0, 0))
09587 {
09588 tree t2 = TREE_OPERAND (arg1, 0);
09589 t1 = fold_build1 (BIT_NOT_EXPR, TREE_TYPE (arg0),
09590 arg0);
09591 t1 = fold_build2 (BIT_AND_EXPR, type, fold_convert (type, t2),
09592 fold_convert (type, t1));
09593 return t1;
09594 }
09595
09596
09597 if (TREE_CODE (arg0) == BIT_NOT_EXPR
09598 && TREE_CODE (arg1) == BIT_NOT_EXPR)
09599 return fold_build2 (code, type,
09600 fold_convert (type, TREE_OPERAND (arg0, 0)),
09601 fold_convert (type, TREE_OPERAND (arg1, 0)));
09602
09603
09604 if (TREE_CODE (arg0) == BIT_AND_EXPR
09605 && integer_onep (TREE_OPERAND (arg0, 1))
09606 && integer_onep (arg1))
09607 return fold_build2 (EQ_EXPR, type, arg0,
09608 build_int_cst (TREE_TYPE (arg0), 0));
09609
09610
09611 if (TREE_CODE (arg0) == BIT_AND_EXPR
09612 && operand_equal_p (TREE_OPERAND (arg0, 1), arg1, 0))
09613 {
09614 tem = fold_convert (type, TREE_OPERAND (arg0, 0));
09615 return fold_build2 (BIT_AND_EXPR, type,
09616 fold_build1 (BIT_NOT_EXPR, type, tem),
09617 fold_convert (type, arg1));
09618 }
09619
09620 if (TREE_CODE (arg0) == BIT_AND_EXPR
09621 && operand_equal_p (TREE_OPERAND (arg0, 0), arg1, 0)
09622 && reorder_operands_p (TREE_OPERAND (arg0, 1), arg1))
09623 {
09624 tem = fold_convert (type, TREE_OPERAND (arg0, 1));
09625 return fold_build2 (BIT_AND_EXPR, type,
09626 fold_build1 (BIT_NOT_EXPR, type, tem),
09627 fold_convert (type, arg1));
09628 }
09629
09630 if (TREE_CODE (arg1) == BIT_AND_EXPR
09631 && operand_equal_p (arg0, TREE_OPERAND (arg1, 0), 0))
09632 {
09633 tem = fold_convert (type, TREE_OPERAND (arg1, 1));
09634 return fold_build2 (BIT_AND_EXPR, type,
09635 fold_convert (type, arg0),
09636 fold_build1 (BIT_NOT_EXPR, type, tem));
09637 }
09638
09639 if (TREE_CODE (arg1) == BIT_AND_EXPR
09640 && operand_equal_p (arg0, TREE_OPERAND (arg1, 1), 0)
09641 && reorder_operands_p (arg0, TREE_OPERAND (arg1, 0)))
09642 {
09643 tem = fold_convert (type, TREE_OPERAND (arg1, 0));
09644 return fold_build2 (BIT_AND_EXPR, type,
09645 fold_build1 (BIT_NOT_EXPR, type, tem),
09646 fold_convert (type, arg0));
09647 }
09648
09649
09650
09651 goto bit_rotate;
09652
09653 case BIT_AND_EXPR:
09654 if (integer_all_onesp (arg1))
09655 return non_lvalue (fold_convert (type, arg0));
09656 if (integer_zerop (arg1))
09657 return omit_one_operand (type, arg1, arg0);
09658 if (operand_equal_p (arg0, arg1, 0))
09659 return non_lvalue (fold_convert (type, arg0));
09660
09661
09662 if (TREE_CODE (arg0) == BIT_NOT_EXPR
09663 && operand_equal_p (TREE_OPERAND (arg0, 0), arg1, 0))
09664 return omit_one_operand (type, integer_zero_node, arg1);
09665
09666
09667 if (TREE_CODE (arg1) == BIT_NOT_EXPR
09668 && operand_equal_p (arg0, TREE_OPERAND (arg1, 0), 0))
09669 return omit_one_operand (type, integer_zero_node, arg0);
09670
09671
09672 if (TREE_CODE (arg0) == BIT_IOR_EXPR
09673 && TREE_CODE (arg1) == INTEGER_CST
09674 && TREE_CODE (TREE_OPERAND (arg0, 1)) == INTEGER_CST)
09675 return fold_build2 (BIT_IOR_EXPR, type,
09676 fold_build2 (BIT_AND_EXPR, type,
09677 TREE_OPERAND (arg0, 0), arg1),
09678 fold_build2 (BIT_AND_EXPR, type,
09679 TREE_OPERAND (arg0, 1), arg1));
09680
09681
09682 if (TREE_CODE (arg0) == BIT_IOR_EXPR
09683 && operand_equal_p (TREE_OPERAND (arg0, 1), arg1, 0))
09684 return omit_one_operand (type, arg1, TREE_OPERAND (arg0, 0));
09685
09686 if (TREE_CODE (arg0) == BIT_IOR_EXPR
09687 && operand_equal_p (TREE_OPERAND (arg0, 0), arg1, 0)
09688 && reorder_operands_p (TREE_OPERAND (arg0, 1), arg1))
09689 return omit_one_operand (type, arg1, TREE_OPERAND (arg0, 1));
09690
09691 if (TREE_CODE (arg1) == BIT_IOR_EXPR
09692 && operand_equal_p (arg0, TREE_OPERAND (arg1, 0), 0)
09693 && reorder_operands_p (arg0, TREE_OPERAND (arg1, 1)))
09694 return omit_one_operand (type, arg0, TREE_OPERAND (arg1, 1));
09695
09696 if (TREE_CODE (arg1) == BIT_IOR_EXPR
09697 && operand_equal_p (arg0, TREE_OPERAND (arg1, 1), 0)
09698 && reorder_operands_p (arg0, TREE_OPERAND (arg1, 0)))
09699 return omit_one_operand (type, arg0, TREE_OPERAND (arg1, 0));
09700
09701
09702 if (TREE_CODE (arg0) == BIT_XOR_EXPR
09703 && integer_onep (TREE_OPERAND (arg0, 1))
09704 && integer_onep (arg1))
09705 {
09706 tem = TREE_OPERAND (arg0, 0);
09707 return fold_build2 (EQ_EXPR, type,
09708 fold_build2 (BIT_AND_EXPR, TREE_TYPE (tem), tem,
09709 build_int_cst (TREE_TYPE (tem), 1)),
09710 build_int_cst (TREE_TYPE (tem), 0));
09711 }
09712
09713 if (TREE_CODE (arg0) == BIT_NOT_EXPR
09714 && integer_onep (arg1))
09715 {
09716 tem = TREE_OPERAND (arg0, 0);
09717 return fold_build2 (EQ_EXPR, type,
09718 fold_build2 (BIT_AND_EXPR, TREE_TYPE (tem), tem,
09719 build_int_cst (TREE_TYPE (tem), 1)),
09720 build_int_cst (TREE_TYPE (tem), 0));
09721 }
09722
09723
09724 if (TREE_CODE (arg0) == BIT_XOR_EXPR
09725 && operand_equal_p (TREE_OPERAND (arg0, 1), arg1, 0))
09726 {
09727 tem = fold_convert (type, TREE_OPERAND (arg0, 0));
09728 return fold_build2 (BIT_AND_EXPR, type,
09729 fold_build1 (BIT_NOT_EXPR, type, tem),
09730 fold_convert (type, arg1));
09731 }
09732
09733 if (TREE_CODE (arg0) == BIT_XOR_EXPR
09734 && operand_equal_p (TREE_OPERAND (arg0, 0), arg1, 0)
09735 && reorder_operands_p (TREE_OPERAND (arg0, 1), arg1))
09736 {
09737 tem = fold_convert (type, TREE_OPERAND (arg0, 1));
09738 return fold_build2 (BIT_AND_EXPR, type,
09739 fold_build1 (BIT_NOT_EXPR, type, tem),
09740 fold_convert (type, arg1));
09741 }
09742
09743 if (TREE_CODE (arg1) == BIT_XOR_EXPR
09744 && operand_equal_p (arg0, TREE_OPERAND (arg1, 0), 0))
09745 {
09746 tem = fold_convert (type, TREE_OPERAND (arg1, 1));
09747 return fold_build2 (BIT_AND_EXPR, type,
09748 fold_convert (type, arg0),
09749 fold_build1 (BIT_NOT_EXPR, type, tem));
09750 }
09751
09752 if (TREE_CODE (arg1) == BIT_XOR_EXPR
09753 && operand_equal_p (arg0, TREE_OPERAND (arg1, 1), 0)
09754 && reorder_operands_p (arg0, TREE_OPERAND (arg1, 0)))
09755 {
09756 tem = fold_convert (type, TREE_OPERAND (arg1, 0));
09757 return fold_build2 (BIT_AND_EXPR, type,
09758 fold_build1 (BIT_NOT_EXPR, type, tem),
09759 fold_convert (type, arg0));
09760 }
09761
09762 t1 = distribute_bit_expr (code, type, arg0, arg1);
09763 if (t1 != NULL_TREE)
09764 return t1;
09765
09766 if (TREE_CODE (arg1) == INTEGER_CST && TREE_CODE (arg0) == NOP_EXPR
09767 && TYPE_UNSIGNED (TREE_TYPE (TREE_OPERAND (arg0, 0))))
09768 {
09769 unsigned int prec
09770 = TYPE_PRECISION (TREE_TYPE (TREE_OPERAND (arg0, 0)));
09771
09772 if (prec < BITS_PER_WORD && prec < HOST_BITS_PER_WIDE_INT
09773 && (~TREE_INT_CST_LOW (arg1)
09774 & (((HOST_WIDE_INT) 1 << prec) - 1)) == 0)
09775 return fold_convert (type, TREE_OPERAND (arg0, 0));
09776 }
09777
09778
09779
09780
09781
09782
09783
09784 if (TREE_CODE (arg0) == BIT_NOT_EXPR
09785 && TREE_CODE (arg1) == BIT_NOT_EXPR)
09786 {
09787 return fold_build1 (BIT_NOT_EXPR, type,
09788 build2 (BIT_IOR_EXPR, type,
09789 TREE_OPERAND (arg0, 0),
09790 TREE_OPERAND (arg1, 0)));
09791 }
09792
09793 goto associate;
09794
09795 case RDIV_EXPR:
09796
09797
09798 if (TREE_CODE (arg1) == REAL_CST
09799 && !MODE_HAS_INFINITIES (TYPE_MODE (TREE_TYPE (arg1)))
09800 && real_zerop (arg1))
09801 return NULL_TREE;
09802
09803
09804
09805
09806 if (SCALAR_FLOAT_TYPE_P (TREE_TYPE (arg0))
09807 && ! HONOR_NANS (TYPE_MODE (TREE_TYPE (arg0)))
09808 && ! HONOR_INFINITIES (TYPE_MODE (TREE_TYPE (arg0)))
09809 && operand_equal_p (arg0, arg1, 0))
09810 {
09811 tree r = build_real (TREE_TYPE (arg0), dconst1);
09812
09813 return omit_two_operands (type, r, arg0, arg1);
09814 }
09815
09816
09817 if (COMPLEX_FLOAT_TYPE_P (TREE_TYPE (arg0))
09818 && operand_equal_p (arg0, arg1, 0))
09819 {
09820 tree elem_type = TREE_TYPE (TREE_TYPE (arg0));
09821 if (! HONOR_NANS (TYPE_MODE (elem_type))
09822 && ! HONOR_INFINITIES (TYPE_MODE (elem_type)))
09823 {
09824 tree r = build_real (elem_type, dconst1);
09825
09826 return omit_two_operands (type, r, arg0, arg1);
09827 }
09828 }
09829
09830
09831 if (TREE_CODE (arg0) == NEGATE_EXPR && negate_expr_p (arg1))
09832 return fold_build2 (RDIV_EXPR, type,
09833 TREE_OPERAND (arg0, 0),
09834 negate_expr (arg1));
09835 if (TREE_CODE (arg1) == NEGATE_EXPR && negate_expr_p (arg0))
09836 return fold_build2 (RDIV_EXPR, type,
09837 negate_expr (arg0),
09838 TREE_OPERAND (arg1, 0));
09839
09840
09841 if (!HONOR_SNANS (TYPE_MODE (TREE_TYPE (arg0)))
09842 && real_onep (arg1))
09843 return non_lvalue (fold_convert (type, arg0));
09844
09845
09846 if (!HONOR_SNANS (TYPE_MODE (TREE_TYPE (arg0)))
09847 && real_minus_onep (arg1))
09848 return non_lvalue (fold_convert (type, negate_expr (arg0)));
09849
09850
09851
09852
09853
09854
09855 if (TREE_CODE (arg1) == REAL_CST)
09856 {
09857 if (flag_unsafe_math_optimizations
09858 && 0 != (tem = const_binop (code, build_real (type, dconst1),
09859 arg1, 0)))
09860 return fold_build2 (MULT_EXPR, type, arg0, tem);
09861
09862 if (optimize)
09863 {
09864 REAL_VALUE_TYPE r;
09865 r = TREE_REAL_CST (arg1);
09866 if (exact_real_inverse (TYPE_MODE(TREE_TYPE(arg0)), &r))
09867 {
09868 tem = build_real (type, r);
09869 return fold_build2 (MULT_EXPR, type,
09870 fold_convert (type, arg0), tem);
09871 }
09872 }
09873 }
09874
09875 if (flag_unsafe_math_optimizations
09876 && TREE_CODE (arg0) == RDIV_EXPR)
09877 return fold_build2 (RDIV_EXPR, type, TREE_OPERAND (arg0, 0),
09878 fold_build2 (MULT_EXPR, type,
09879 TREE_OPERAND (arg0, 1), arg1));
09880
09881
09882 if (flag_unsafe_math_optimizations
09883 && TREE_CODE (arg1) == RDIV_EXPR)
09884 return fold_build2 (MULT_EXPR, type,
09885 fold_build2 (RDIV_EXPR, type, arg0,
09886 TREE_OPERAND (arg1, 0)),
09887 TREE_OPERAND (arg1, 1));
09888
09889
09890 if (flag_unsafe_math_optimizations
09891 && TREE_CODE (arg1) == MULT_EXPR
09892 && TREE_CODE (arg0) == REAL_CST
09893 && TREE_CODE (TREE_OPERAND (arg1, 1)) == REAL_CST)
09894 {
09895 tree tem = const_binop (RDIV_EXPR, arg0,
09896 TREE_OPERAND (arg1, 1), 0);
09897 if (tem)
09898 return fold_build2 (RDIV_EXPR, type, tem,
09899 TREE_OPERAND (arg1, 0));
09900 }
09901
09902 if (flag_unsafe_math_optimizations)
09903 {
09904 enum built_in_function fcode0 = builtin_mathfn_code (arg0);
09905 enum built_in_function fcode1 = builtin_mathfn_code (arg1);
09906
09907
09908 if (((fcode0 == BUILT_IN_SIN && fcode1 == BUILT_IN_COS)
09909 || (fcode0 == BUILT_IN_SINF && fcode1 == BUILT_IN_COSF)
09910 || (fcode0 == BUILT_IN_SINL && fcode1 == BUILT_IN_COSL))
09911 && operand_equal_p (TREE_VALUE (TREE_OPERAND (arg0, 1)),
09912 TREE_VALUE (TREE_OPERAND (arg1, 1)), 0))
09913 {
09914 tree tanfn = mathfn_built_in (type, BUILT_IN_TAN);
09915
09916 if (tanfn != NULL_TREE)
09917 return build_function_call_expr (tanfn,
09918 TREE_OPERAND (arg0, 1));
09919 }
09920
09921
09922 if (((fcode0 == BUILT_IN_COS && fcode1 == BUILT_IN_SIN)
09923 || (fcode0 == BUILT_IN_COSF && fcode1 == BUILT_IN_SINF)
09924 || (fcode0 == BUILT_IN_COSL && fcode1 == BUILT_IN_SINL))
09925 && operand_equal_p (TREE_VALUE (TREE_OPERAND (arg0, 1)),
09926 TREE_VALUE (TREE_OPERAND (arg1, 1)), 0))
09927 {
09928 tree tanfn = mathfn_built_in (type, BUILT_IN_TAN);
09929
09930 if (tanfn != NULL_TREE)
09931 {
09932 tree tmp = TREE_OPERAND (arg0, 1);
09933 tmp = build_function_call_expr (tanfn, tmp);
09934 return fold_build2 (RDIV_EXPR, type,
09935 build_real (type, dconst1), tmp);
09936 }
09937 }
09938
09939
09940
09941 if (((fcode0 == BUILT_IN_SIN && fcode1 == BUILT_IN_TAN)
09942 || (fcode0 == BUILT_IN_SINF && fcode1 == BUILT_IN_TANF)
09943 || (fcode0 == BUILT_IN_SINL && fcode1 == BUILT_IN_TANL)))
09944 {
09945 tree arg00 = TREE_VALUE (TREE_OPERAND (arg0, 1));
09946 tree arg01 = TREE_VALUE (TREE_OPERAND (arg1, 1));
09947
09948 if (! HONOR_NANS (TYPE_MODE (TREE_TYPE (arg00)))
09949 && ! HONOR_INFINITIES (TYPE_MODE (TREE_TYPE (arg00)))
09950 && operand_equal_p (arg00, arg01, 0))
09951 {
09952 tree cosfn = mathfn_built_in (type, BUILT_IN_COS);
09953
09954 if (cosfn != NULL_TREE)
09955 return build_function_call_expr (cosfn,
09956 TREE_OPERAND (arg0, 1));
09957 }
09958 }
09959
09960
09961
09962 if (((fcode0 == BUILT_IN_TAN && fcode1 == BUILT_IN_SIN)
09963 || (fcode0 == BUILT_IN_TANF && fcode1 == BUILT_IN_SINF)
09964 || (fcode0 == BUILT_IN_TANL && fcode1 == BUILT_IN_SINL)))
09965 {
09966 tree arg00 = TREE_VALUE (TREE_OPERAND (arg0, 1));
09967 tree arg01 = TREE_VALUE (TREE_OPERAND (arg1, 1));
09968
09969 if (! HONOR_NANS (TYPE_MODE (TREE_TYPE (arg00)))
09970 && ! HONOR_INFINITIES (TYPE_MODE (TREE_TYPE (arg00)))
09971 && operand_equal_p (arg00, arg01, 0))
09972 {
09973 tree cosfn = mathfn_built_in (type, BUILT_IN_COS);
09974
09975 if (cosfn != NULL_TREE)
09976 {
09977 tree tmp = TREE_OPERAND (arg0, 1);
09978 tmp = build_function_call_expr (cosfn, tmp);
09979 return fold_build2 (RDIV_EXPR, type,
09980 build_real (type, dconst1),
09981 tmp);
09982 }
09983 }
09984 }
09985
09986
09987 if (fcode0 == BUILT_IN_POW
09988 || fcode0 == BUILT_IN_POWF
09989 || fcode0 == BUILT_IN_POWL)
09990 {
09991 tree arg00 = TREE_VALUE (TREE_OPERAND (arg0, 1));
09992 tree arg01 = TREE_VALUE (TREE_CHAIN (TREE_OPERAND (arg0, 1)));
09993 if (TREE_CODE (arg01) == REAL_CST
09994 && ! TREE_CONSTANT_OVERFLOW (arg01)
09995 && operand_equal_p (arg1, arg00, 0))
09996 {
09997 tree powfn = TREE_OPERAND (TREE_OPERAND (arg0, 0), 0);
09998 REAL_VALUE_TYPE c;
09999 tree arg, arglist;
10000
10001 c = TREE_REAL_CST (arg01);
10002 real_arithmetic (&c, MINUS_EXPR, &c, &dconst1);
10003 arg = build_real (type, c);
10004 arglist = build_tree_list (NULL_TREE, arg);
10005 arglist = tree_cons (NULL_TREE, arg1, arglist);
10006 return build_function_call_expr (powfn, arglist);
10007 }
10008 }
10009
10010
10011 if (BUILTIN_EXPONENT_P (fcode1))
10012 {
10013 tree expfn = TREE_OPERAND (TREE_OPERAND (arg1, 0), 0);
10014 tree arg = negate_expr (TREE_VALUE (TREE_OPERAND (arg1, 1)));
10015 tree arglist = build_tree_list (NULL_TREE,
10016 fold_convert (type, arg));
10017 arg1 = build_function_call_expr (expfn, arglist);
10018 return fold_build2 (MULT_EXPR, type, arg0, arg1);
10019 }
10020
10021
10022 if (fcode1 == BUILT_IN_POW
10023 || fcode1 == BUILT_IN_POWF
10024 || fcode1 == BUILT_IN_POWL)
10025 {
10026 tree powfn = TREE_OPERAND (TREE_OPERAND (arg1, 0), 0);
10027 tree arg10 = TREE_VALUE (TREE_OPERAND (arg1, 1));
10028 tree arg11 = TREE_VALUE (TREE_CHAIN (TREE_OPERAND (arg1, 1)));
10029 tree neg11 = fold_convert (type, negate_expr (arg11));
10030 tree arglist = tree_cons(NULL_TREE, arg10,
10031 build_tree_list (NULL_TREE, neg11));
10032 arg1 = build_function_call_expr (powfn, arglist);
10033 return fold_build2 (MULT_EXPR, type, arg0, arg1);
10034 }
10035 }
10036 return NULL_TREE;
10037
10038 case TRUNC_DIV_EXPR:
10039 case FLOOR_DIV_EXPR:
10040
10041
10042 strict_overflow_p = false;
10043 if (TREE_CODE (arg1) == LSHIFT_EXPR
10044 && (TYPE_UNSIGNED (type)
10045 || tree_expr_nonnegative_warnv_p (arg0, &strict_overflow_p)))
10046 {
10047 tree sval = TREE_OPERAND (arg1, 0);
10048 if (integer_pow2p (sval) && tree_int_cst_sgn (sval) > 0)
10049 {
10050 tree sh_cnt = TREE_OPERAND (arg1, 1);
10051 unsigned long pow2 = exact_log2 (TREE_INT_CST_LOW (sval));
10052
10053 if (strict_overflow_p)
10054 fold_overflow_warning (("assuming signed overflow does not "
10055 "occur when simplifying A / (B << N)"),
10056 WARN_STRICT_OVERFLOW_MISC);
10057
10058 sh_cnt = fold_build2 (PLUS_EXPR, TREE_TYPE (sh_cnt),
10059 sh_cnt, build_int_cst (NULL_TREE, pow2));
10060 return fold_build2 (RSHIFT_EXPR, type,
10061 fold_convert (type, arg0), sh_cnt);
10062 }
10063 }
10064
10065
10066 case ROUND_DIV_EXPR:
10067 case CEIL_DIV_EXPR:
10068 case EXACT_DIV_EXPR:
10069 if (integer_onep (arg1))
10070 return non_lvalue (fold_convert (type, arg0));
10071 if (integer_zerop (arg1))
10072 return NULL_TREE;
10073
10074 if (!TYPE_UNSIGNED (type)
10075 && TREE_CODE (arg1) == INTEGER_CST
10076 && TREE_INT_CST_LOW (arg1) == (unsigned HOST_WIDE_INT) -1
10077 && TREE_INT_CST_HIGH (arg1) == -1)
10078 return fold_convert (type, negate_expr (arg0));
10079
10080
10081
10082 if ((!INTEGRAL_TYPE_P (type) || TYPE_OVERFLOW_UNDEFINED (type))
10083 && TREE_CODE (arg0) == NEGATE_EXPR
10084 && negate_expr_p (arg1))
10085 {
10086 if (INTEGRAL_TYPE_P (type))
10087 fold_overflow_warning (("assuming signed overflow does not occur "
10088 "when distributing negation across "
10089 "division"),
10090 WARN_STRICT_OVERFLOW_MISC);
10091 return fold_build2 (code, type, TREE_OPERAND (arg0, 0),
10092 negate_expr (arg1));
10093 }
10094 if ((!INTEGRAL_TYPE_P (type) || TYPE_OVERFLOW_UNDEFINED (type))
10095 && TREE_CODE (arg1) == NEGATE_EXPR
10096 && negate_expr_p (arg0))
10097 {
10098 if (INTEGRAL_TYPE_P (type))
10099 fold_overflow_warning (("assuming signed overflow does not occur "
10100 "when distributing negation across "
10101 "division"),
10102 WARN_STRICT_OVERFLOW_MISC);
10103 return fold_build2 (code, type, negate_expr (arg0),
10104 TREE_OPERAND (arg1, 0));
10105 }
10106
10107
10108
10109
10110
10111
10112
10113 if ((code == CEIL_DIV_EXPR || code == FLOOR_DIV_EXPR)
10114 && multiple_of_p (type, arg0, arg1))
10115 return fold_build2 (EXACT_DIV_EXPR, type, arg0, arg1);
10116
10117 strict_overflow_p = false;
10118 if (TREE_CODE (arg1) == INTEGER_CST
10119 && 0 != (tem = extract_muldiv (op0, arg1, code, NULL_TREE,
10120 &strict_overflow_p)))
10121 {
10122 if (strict_overflow_p)
10123 fold_overflow_warning (("assuming signed overflow does not occur "
10124 "when simplifying division"),
10125 WARN_STRICT_OVERFLOW_MISC);
10126 return fold_convert (type, tem);
10127 }
10128
10129 return NULL_TREE;
10130
10131 case CEIL_MOD_EXPR:
10132 case FLOOR_MOD_EXPR:
10133 case ROUND_MOD_EXPR:
10134 case TRUNC_MOD_EXPR:
10135
10136
10137 if (integer_onep (arg1))
10138 return omit_one_operand (type, integer_zero_node, arg0);
10139
10140
10141
10142 if (integer_zerop (arg1))
10143 return NULL_TREE;
10144
10145
10146
10147 if (integer_zerop (arg0))
10148 return omit_one_operand (type, integer_zero_node, arg1);
10149
10150
10151 if (!TYPE_UNSIGNED (type)
10152 && TREE_CODE (arg1) == INTEGER_CST
10153 && TREE_INT_CST_LOW (arg1) == (unsigned HOST_WIDE_INT) -1
10154 && TREE_INT_CST_HIGH (arg1) == -1)
10155 return omit_one_operand (type, integer_zero_node, arg0);
10156
10157
10158
10159 strict_overflow_p = false;
10160 if ((code == TRUNC_MOD_EXPR || code == FLOOR_MOD_EXPR)
10161 && (TYPE_UNSIGNED (type)
10162 || tree_expr_nonnegative_warnv_p (arg0, &strict_overflow_p)))
10163 {
10164 tree c = arg1;
10165
10166
10167 if (TREE_CODE (arg1) == LSHIFT_EXPR)
10168 c = TREE_OPERAND (arg1, 0);
10169
10170 if (integer_pow2p (c) && tree_int_cst_sgn (c) > 0)
10171 {
10172 tree mask = fold_build2 (MINUS_EXPR, TREE_TYPE (arg1),
10173 arg1, integer_one_node);
10174 if (strict_overflow_p)
10175 fold_overflow_warning (("assuming signed overflow does not "
10176 "occur when simplifying "
10177 "X % (power of two)"),
10178 WARN_STRICT_OVERFLOW_MISC);
10179 return fold_build2 (BIT_AND_EXPR, type,
10180 fold_convert (type, arg0),
10181 fold_convert (type, mask));
10182 }
10183 }
10184
10185
10186 if (code == TRUNC_MOD_EXPR
10187 && !TYPE_UNSIGNED (type)
10188 && TREE_CODE (arg1) == INTEGER_CST
10189 && !TREE_CONSTANT_OVERFLOW (arg1)
10190 && TREE_INT_CST_HIGH (arg1) < 0
10191 && !TYPE_OVERFLOW_TRAPS (type)
10192
10193 && !sign_bit_p (arg1, arg1))
10194 return fold_build2 (code, type, fold_convert (type, arg0),
10195 fold_convert (type, negate_expr (arg1)));
10196
10197
10198 if (code == TRUNC_MOD_EXPR
10199 && !TYPE_UNSIGNED (type)
10200 && TREE_CODE (arg1) == NEGATE_EXPR
10201 && !TYPE_OVERFLOW_TRAPS (type))
10202 return fold_build2 (code, type, fold_convert (type, arg0),
10203 fold_convert (type, TREE_OPERAND (arg1, 0)));
10204
10205 if (TREE_CODE (arg1) == INTEGER_CST
10206 && 0 != (tem = extract_muldiv (op0, arg1, code, NULL_TREE,
10207 &strict_overflow_p)))
10208 {
10209 if (strict_overflow_p)
10210 fold_overflow_warning (("assuming signed overflow does not occur "
10211 "when simplifying modulos"),
10212 WARN_STRICT_OVERFLOW_MISC);
10213 return fold_convert (type, tem);
10214 }
10215
10216 return NULL_TREE;
10217
10218 case LROTATE_EXPR:
10219 case RROTATE_EXPR:
10220 if (integer_all_onesp (arg0))
10221 return omit_one_operand (type, arg0, arg1);
10222 goto shift;
10223
10224 case RSHIFT_EXPR:
10225
10226 if (integer_all_onesp (arg0) && !TYPE_UNSIGNED (type))
10227 return omit_one_operand (type, arg0, arg1);
10228
10229
10230 case LSHIFT_EXPR:
10231 shift:
10232 if (integer_zerop (arg1))
10233 return non_lvalue (fold_convert (type, arg0));
10234 if (integer_zerop (arg0))
10235 return omit_one_operand (type, arg0, arg1);
10236
10237
10238
10239 if (TREE_CODE (arg1) == INTEGER_CST && tree_int_cst_sgn (arg1) < 0)
10240 return NULL_TREE;
10241
10242
10243 if (TREE_CODE (op0) == code && host_integerp (arg1, false)
10244 && TREE_INT_CST_LOW (arg1) < TYPE_PRECISION (type)
10245 && host_integerp (TREE_OPERAND (arg0, 1), false)
10246 && TREE_INT_CST_LOW (TREE_OPERAND (arg0, 1)) < TYPE_PRECISION (type))
10247 {
10248 HOST_WIDE_INT low = (TREE_INT_CST_LOW (TREE_OPERAND (arg0, 1))
10249 + TREE_INT_CST_LOW (arg1));
10250
10251
10252
10253 if (low >= TYPE_PRECISION (type))
10254 {
10255 if (code == LROTATE_EXPR || code == RROTATE_EXPR)
10256 low = low % TYPE_PRECISION (type);
10257 else if (TYPE_UNSIGNED (type) || code == LSHIFT_EXPR)
10258 return build_int_cst (type, 0);
10259 else
10260 low = TYPE_PRECISION (type) - 1;
10261 }
10262
10263 return fold_build2 (code, type, TREE_OPERAND (arg0, 0),
10264 build_int_cst (type, low));
10265 }
10266
10267
10268
10269 if (((code == LSHIFT_EXPR && TREE_CODE (arg0) == RSHIFT_EXPR)
10270 || (TYPE_UNSIGNED (type)
10271 && code == RSHIFT_EXPR && TREE_CODE (arg0) == LSHIFT_EXPR))
10272 && host_integerp (arg1, false)
10273 && TREE_INT_CST_LOW (arg1) < TYPE_PRECISION (type)
10274 && host_integerp (TREE_OPERAND (arg0, 1), false)
10275 && TREE_INT_CST_LOW (TREE_OPERAND (arg0, 1)) < TYPE_PRECISION (type))
10276 {
10277 HOST_WIDE_INT low0 = TREE_INT_CST_LOW (TREE_OPERAND (arg0, 1));
10278 HOST_WIDE_INT low1 = TREE_INT_CST_LOW (arg1);
10279 tree lshift;
10280 tree arg00;
10281
10282 if (low0 == low1)
10283 {
10284 arg00 = fold_convert (type, TREE_OPERAND (arg0, 0));
10285
10286 lshift = build_int_cst (type, -1);
10287 lshift = int_const_binop (code, lshift, arg1, 0);
10288
10289 return fold_build2 (BIT_AND_EXPR, type, arg00, lshift);
10290 }
10291 }
10292
10293
10294
10295 if (code == LROTATE_EXPR && TREE_CODE (arg1) == INTEGER_CST)
10296 {
10297 tree tem = build_int_cst (NULL_TREE,
10298 GET_MODE_BITSIZE (TYPE_MODE (type)));
10299 tem = fold_convert (TREE_TYPE (arg1), tem);
10300 tem = const_binop (MINUS_EXPR, tem, arg1, 0);
10301 return fold_build2 (RROTATE_EXPR, type, arg0, tem);
10302 }
10303
10304
10305
10306
10307 if (code == RROTATE_EXPR && TREE_CODE (arg1) == INTEGER_CST
10308 && (TREE_CODE (arg0) == BIT_AND_EXPR
10309 || TREE_CODE (arg0) == BIT_IOR_EXPR
10310 || TREE_CODE (arg0) == BIT_XOR_EXPR)
10311 && TREE_CODE (TREE_OPERAND (arg0, 1)) == INTEGER_CST)
10312 return fold_build2 (TREE_CODE (arg0), type,
10313 fold_build2 (code, type,
10314 TREE_OPERAND (arg0, 0), arg1),
10315 fold_build2 (code, type,
10316 TREE_OPERAND (arg0, 1), arg1));
10317
10318
10319
10320 if (code == RROTATE_EXPR && TREE_CODE (arg1) == INTEGER_CST
10321 && TREE_CODE (arg0) == RROTATE_EXPR
10322 && TREE_CODE (TREE_OPERAND (arg0, 1)) == INTEGER_CST
10323 && TREE_INT_CST_HIGH (arg1) == 0
10324 && TREE_INT_CST_HIGH (TREE_OPERAND (arg0, 1)) == 0
10325 && ((TREE_INT_CST_LOW (arg1)
10326 + TREE_INT_CST_LOW (TREE_OPERAND (arg0, 1)))
10327 == (unsigned int) GET_MODE_BITSIZE (TYPE_MODE (type))))
10328 return TREE_OPERAND (arg0, 0);
10329
10330 return NULL_TREE;
10331
10332 case MIN_EXPR:
10333 if (operand_equal_p (arg0, arg1, 0))
10334 return omit_one_operand (type, arg0, arg1);
10335 if (INTEGRAL_TYPE_P (type)
10336 && operand_equal_p (arg1, TYPE_MIN_VALUE (type), OEP_ONLY_CONST))
10337 return omit_one_operand (type, arg1, arg0);
10338 tem = fold_minmax (MIN_EXPR, type, arg0, arg1);
10339 if (tem)
10340 return tem;
10341 goto associate;
10342
10343 case MAX_EXPR:
10344 if (operand_equal_p (arg0, arg1, 0))
10345 return omit_one_operand (type, arg0, arg1);
10346 if (INTEGRAL_TYPE_P (type)
10347 && TYPE_MAX_VALUE (type)
10348 && operand_equal_p (arg1, TYPE_MAX_VALUE (type), OEP_ONLY_CONST))
10349 return omit_one_operand (type, arg1, arg0);
10350 tem = fold_minmax (MAX_EXPR, type, arg0, arg1);
10351 if (tem)
10352 return tem;
10353 goto associate;
10354
10355 case TRUTH_ANDIF_EXPR:
10356
10357
10358
10359
10360 if (integer_zerop (arg0))
10361 return fold_convert (type, arg0);
10362 case TRUTH_AND_EXPR:
10363
10364 if (TREE_CODE (arg0) == INTEGER_CST && ! integer_zerop (arg0))
10365 return non_lvalue (fold_convert (type, arg1));
10366 if (TREE_CODE (arg1) == INTEGER_CST && ! integer_zerop (arg1)
10367
10368 && (code != TRUTH_ANDIF_EXPR || ! TREE_SIDE_EFFECTS (arg0)))
10369 return non_lvalue (fold_convert (type, arg0));
10370
10371
10372 if (integer_zerop (arg1))
10373 return omit_one_operand (type, arg1, arg0);
10374
10375
10376 if (integer_zerop (arg0))
10377 return omit_one_operand (type, arg0, arg1);
10378
10379
10380 if (TREE_CODE (arg0) == TRUTH_NOT_EXPR
10381 && operand_equal_p (TREE_OPERAND (arg0, 0), arg1, 0))
10382 return omit_one_operand (type, integer_zero_node, arg1);
10383
10384 if (TREE_CODE (arg1) == TRUTH_NOT_EXPR
10385 && operand_equal_p (arg0, TREE_OPERAND (arg1, 0), 0))
10386 return omit_one_operand (type, integer_zero_node, arg0);
10387
10388
10389
10390
10391
10392 if (!TREE_SIDE_EFFECTS (arg0)
10393 && !TREE_SIDE_EFFECTS (arg1))
10394 {
10395 tem = fold_to_nonsharp_ineq_using_bound (arg0, arg1);
10396 if (tem && !operand_equal_p (tem, arg0, 0))
10397 return fold_build2 (code, type, tem, arg1);
10398
10399 tem = fold_to_nonsharp_ineq_using_bound (arg1, arg0);
10400 if (tem && !operand_equal_p (tem, arg1, 0))
10401 return fold_build2 (code, type, arg0, tem);
10402 }
10403
10404 truth_andor:
10405
10406 if (!optimize)
10407 return NULL_TREE;
10408
10409
10410
10411
10412
10413
10414
10415 if (TREE_CODE (arg0) == TREE_CODE (arg1)
10416 && (TREE_CODE (arg0) == TRUTH_ANDIF_EXPR
10417 || TREE_CODE (arg0) == TRUTH_ORIF_EXPR
10418 || TREE_CODE (arg0) == TRUTH_AND_EXPR
10419 || TREE_CODE (arg0) == TRUTH_OR_EXPR)
10420 && ! TREE_SIDE_EFFECTS (TREE_OPERAND (arg0, 1)))
10421 {
10422 tree a00 = TREE_OPERAND (arg0, 0);
10423 tree a01 = TREE_OPERAND (arg0, 1);
10424 tree a10 = TREE_OPERAND (arg1, 0);
10425 tree a11 = TREE_OPERAND (arg1, 1);
10426 int commutative = ((TREE_CODE (arg0) == TRUTH_OR_EXPR
10427 || TREE_CODE (arg0) == TRUTH_AND_EXPR)
10428 && (code == TRUTH_AND_EXPR
10429 || code == TRUTH_OR_EXPR));
10430
10431 if (operand_equal_p (a00, a10, 0))
10432 return fold_build2 (TREE_CODE (arg0), type, a00,
10433 fold_build2 (code, type, a01, a11));
10434 else if (commutative && operand_equal_p (a00, a11, 0))
10435 return fold_build2 (TREE_CODE (arg0), type, a00,
10436 fold_build2 (code, type, a01, a10));
10437 else if (commutative && operand_equal_p (a01, a10, 0))
10438 return fold_build2 (TREE_CODE (arg0), type, a01,
10439 fold_build2 (code, type, a00, a11));
10440
10441
10442
10443
10444 else if ((commutative || ! TREE_SIDE_EFFECTS (a10))
10445 && operand_equal_p (a01, a11, 0))
10446 return fold_build2 (TREE_CODE (arg0), type,
10447 fold_build2 (code, type, a00, a10),
10448 a01);
10449 }
10450
10451
10452 if (0 != (tem = fold_range_test (code, type, op0, op1)))
10453 return tem;
10454
10455
10456
10457
10458 if (TREE_CODE (arg0) == code
10459 && 0 != (tem = fold_truthop (code, type,
10460 TREE_OPERAND (arg0, 1), arg1)))
10461 return fold_build2 (code, type, TREE_OPERAND (arg0, 0), tem);
10462
10463 if ((tem = fold_truthop (code, type, arg0, arg1)) != 0)
10464 return tem;
10465
10466 return NULL_TREE;
10467
10468 case TRUTH_ORIF_EXPR:
10469
10470
10471
10472
10473 if (TREE_CODE (arg0) == INTEGER_CST && ! integer_zerop (arg0))
10474 return fold_convert (type, arg0);
10475 case TRUTH_OR_EXPR:
10476
10477 if (TREE_CODE (arg0) == INTEGER_CST && integer_zerop (arg0))
10478 return non_lvalue (fold_convert (type, arg1));
10479 if (TREE_CODE (arg1) == INTEGER_CST && integer_zerop (arg1)
10480
10481 && (code != TRUTH_ORIF_EXPR || ! TREE_SIDE_EFFECTS (arg0)))
10482 return non_lvalue (fold_convert (type, arg0));
10483
10484
10485 if (TREE_CODE (arg1) == INTEGER_CST && ! integer_zerop (arg1))
10486 return omit_one_operand (type, arg1, arg0);
10487
10488
10489 if (TREE_CODE (arg0) == INTEGER_CST && ! integer_zerop (arg0))
10490 return omit_one_operand (type, arg0, arg1);
10491
10492
10493 if (TREE_CODE (arg0) == TRUTH_NOT_EXPR
10494 && operand_equal_p (TREE_OPERAND (arg0, 0), arg1, 0))
10495 return omit_one_operand (type, integer_one_node, arg1);
10496
10497 if (TREE_CODE (arg1) == TRUTH_NOT_EXPR
10498 && operand_equal_p (arg0, TREE_OPERAND (arg1, 0), 0))
10499 return omit_one_operand (type, integer_one_node, arg0);
10500
10501 goto truth_andor;
10502
10503 case TRUTH_XOR_EXPR:
10504
10505 if (integer_zerop (arg1))
10506 return non_lvalue (fold_convert (type, arg0));
10507
10508 if (integer_onep (arg1))
10509 {
10510
10511 if (TREE_CODE (TREE_TYPE (arg0)) != BOOLEAN_TYPE)
10512 tem = fold_build1 (TRUTH_NOT_EXPR, TREE_TYPE (arg0), arg0);
10513 else
10514 tem = invert_truthvalue (arg0);
10515 return non_lvalue (fold_convert (type, tem));
10516 }
10517
10518 if (operand_equal_p (arg0, arg1, 0))
10519 return omit_one_operand (type, integer_zero_node, arg0);
10520
10521
10522 if (TREE_CODE (arg0) == TRUTH_NOT_EXPR
10523 && operand_equal_p (TREE_OPERAND (arg0, 0), arg1, 0))
10524 return omit_one_operand (type, integer_one_node, arg1);
10525
10526
10527 if (TREE_CODE (arg1) == TRUTH_NOT_EXPR
10528 && operand_equal_p (arg0, TREE_OPERAND (arg1, 0), 0))
10529 return omit_one_operand (type, integer_one_node, arg0);
10530
10531 return NULL_TREE;
10532
10533 case EQ_EXPR:
10534 case NE_EXPR:
10535 tem = fold_comparison (code, type, op0, op1);
10536 if (tem != NULL_TREE)
10537 return tem;
10538
10539
10540 if (TREE_CODE (TREE_TYPE (arg0)) == BOOLEAN_TYPE && integer_zerop (arg1)
10541 && code == NE_EXPR)
10542 return non_lvalue (fold_convert (type, arg0));
10543
10544
10545 if (TREE_CODE (TREE_TYPE (arg0)) == BOOLEAN_TYPE && integer_onep (arg1)
10546 && code == EQ_EXPR)
10547 return non_lvalue (fold_convert (type, arg0));
10548
10549
10550 if (TREE_CODE (TREE_TYPE (arg0)) == BOOLEAN_TYPE && integer_onep (arg1)
10551 && code == NE_EXPR)
10552 return fold_build1 (TRUTH_NOT_EXPR, type, arg0);
10553
10554
10555 if (TREE_CODE (TREE_TYPE (arg0)) == BOOLEAN_TYPE && integer_zerop (arg1)
10556 && code == EQ_EXPR)
10557 return fold_build1 (TRUTH_NOT_EXPR, type, arg0);
10558
10559
10560 if (TREE_CODE (arg0) == BIT_NOT_EXPR
10561 && TREE_CODE (arg1) == INTEGER_CST)
10562 {
10563 tree cmp_type = TREE_TYPE (TREE_OPERAND (arg0, 0));
10564 return fold_build2 (code, type, TREE_OPERAND (arg0, 0),
10565 fold_build1 (BIT_NOT_EXPR, cmp_type,
10566 fold_convert (cmp_type, arg1)));
10567 }
10568
10569
10570
10571 if (TREE_CODE (arg0) == ADDR_EXPR
10572 && VAR_OR_FUNCTION_DECL_P (TREE_OPERAND (arg0, 0))
10573 && ! DECL_WEAK (TREE_OPERAND (arg0, 0))
10574 && integer_zerop (arg1))
10575 return constant_boolean_node (code != EQ_EXPR, type);
10576
10577
10578
10579
10580 if (TREE_CODE (arg0) == ADDR_EXPR
10581 && VAR_OR_FUNCTION_DECL_P (TREE_OPERAND (arg0, 0))
10582 && ! DECL_WEAK (TREE_OPERAND (arg0, 0))
10583 && ! lookup_attribute ("alias",
10584 DECL_ATTRIBUTES (TREE_OPERAND (arg0, 0)))
10585 && ! DECL_EXTERNAL (TREE_OPERAND (arg0, 0))
10586 && TREE_CODE (arg1) == ADDR_EXPR
10587 && VAR_OR_FUNCTION_DECL_P (TREE_OPERAND (arg1, 0))
10588 && ! DECL_WEAK (TREE_OPERAND (arg1, 0))
10589 && ! lookup_attribute ("alias",
10590 DECL_ATTRIBUTES (TREE_OPERAND (arg1, 0)))
10591 && ! DECL_EXTERNAL (TREE_OPERAND (arg1, 0)))
10592 {
10593
10594
10595
10596
10597
10598
10599
10600
10601
10602
10603
10604 bool equal = TREE_OPERAND (arg0, 0) == TREE_OPERAND (arg1, 0);
10605 return constant_boolean_node (equal
10606 ? code == EQ_EXPR : code != EQ_EXPR,
10607 type);
10608 }
10609
10610
10611
10612
10613 if (TREE_CODE (arg1) == INTEGER_CST
10614 && (TREE_CODE (arg0) == PLUS_EXPR
10615 || TREE_CODE (arg0) == MINUS_EXPR)
10616 && TREE_CODE (TREE_OPERAND (arg0, 1)) == INTEGER_CST
10617 && 0 != (tem = const_binop (TREE_CODE (arg0) == PLUS_EXPR
10618 ? MINUS_EXPR : PLUS_EXPR,
10619 fold_convert (TREE_TYPE (arg0), arg1),
10620 TREE_OPERAND (arg0, 1), 0))
10621 && ! TREE_CONSTANT_OVERFLOW (tem))
10622 return fold_build2 (code, type, TREE_OPERAND (arg0, 0), tem);
10623
10624
10625 if (TREE_CODE (arg0) == NEGATE_EXPR
10626 && TREE_CODE (arg1) == INTEGER_CST
10627 && 0 != (tem = negate_expr (arg1))
10628 && TREE_CODE (tem) == INTEGER_CST
10629 && ! TREE_CONSTANT_OVERFLOW (tem))
10630 return fold_build2 (code, type, TREE_OPERAND (arg0, 0), tem);
10631
10632
10633
10634 if (TREE_CODE (arg0) == MINUS_EXPR
10635 && integer_zerop (arg1))
10636 return fold_build2 (code, type,
10637 TREE_OPERAND (arg0, 0), TREE_OPERAND (arg0, 1));
10638
10639
10640 if (TREE_CODE (arg0) == ABS_EXPR
10641 && (integer_zerop (arg1) || real_zerop (arg1)))
10642 return fold_build2 (code, type, TREE_OPERAND (arg0, 0), arg1);
10643
10644
10645
10646
10647
10648
10649 if (
10650 #ifdef KEY
10651
10652
10653 (!flag_spin_file || !flag_honor_shift) &&
10654 #endif
10655 TREE_CODE (arg0) == BIT_AND_EXPR
10656 && integer_zerop (arg1))
10657 {
10658 tree arg00 = TREE_OPERAND (arg0, 0);
10659 tree arg01 = TREE_OPERAND (arg0, 1);
10660 if (TREE_CODE (arg00) == LSHIFT_EXPR
10661 && integer_onep (TREE_OPERAND (arg00, 0)))
10662 return
10663 fold_build2 (code, type,
10664 build2 (BIT_AND_EXPR, TREE_TYPE (arg0),
10665 build2 (RSHIFT_EXPR, TREE_TYPE (arg00),
10666 arg01, TREE_OPERAND (arg00, 1)),
10667 fold_convert (TREE_TYPE (arg0),
10668 integer_one_node)),
10669 arg1);
10670 else if (TREE_CODE (TREE_OPERAND (arg0, 1)) == LSHIFT_EXPR
10671 && integer_onep (TREE_OPERAND (TREE_OPERAND (arg0, 1), 0)))
10672 return
10673 fold_build2 (code, type,
10674 build2 (BIT_AND_EXPR, TREE_TYPE (arg0),
10675 build2 (RSHIFT_EXPR, TREE_TYPE (arg01),
10676 arg00, TREE_OPERAND (arg01, 1)),
10677 fold_convert (TREE_TYPE (arg0),
10678 integer_one_node)),
10679 arg1);
10680 }
10681
10682
10683
10684
10685 if (integer_zerop (arg1)
10686 && !TYPE_UNSIGNED (TREE_TYPE (arg0))
10687 && (TREE_CODE (arg0) == TRUNC_MOD_EXPR
10688 || TREE_CODE (arg0) == CEIL_MOD_EXPR
10689 || TREE_CODE (arg0) == FLOOR_MOD_EXPR
10690 || TREE_CODE (arg0) == ROUND_MOD_EXPR)
10691 && integer_pow2p (TREE_OPERAND (arg0, 1)))
10692 {
10693 tree newtype = lang_hooks.types.unsigned_type (TREE_TYPE (arg0));
10694 tree newmod = fold_build2 (TREE_CODE (arg0), newtype,
10695 fold_convert (newtype,
10696 TREE_OPERAND (arg0, 0)),
10697 fold_convert (newtype,
10698 TREE_OPERAND (arg0, 1)));
10699
10700 return fold_build2 (code, type, newmod,
10701 fold_convert (newtype, arg1));
10702 }
10703
10704
10705
10706
10707 if (TREE_CODE (arg0) == BIT_AND_EXPR
10708 && TREE_CODE (TREE_OPERAND (arg0, 0)) == RSHIFT_EXPR
10709 && TREE_CODE (TREE_OPERAND (TREE_OPERAND (arg0, 0), 1))
10710 == INTEGER_CST
10711 && integer_pow2p (TREE_OPERAND (arg0, 1))
10712 && integer_zerop (arg1))
10713 {
10714 tree itype = TREE_TYPE (arg0);
10715 unsigned HOST_WIDE_INT prec = TYPE_PRECISION (itype);
10716 tree arg001 = TREE_OPERAND (TREE_OPERAND (arg0, 0), 1);
10717
10718
10719 if (TREE_INT_CST_HIGH (arg001) == 0
10720 && TREE_INT_CST_LOW (arg001) < prec)
10721 {
10722 tree arg01 = TREE_OPERAND (arg0, 1);
10723 tree arg000 = TREE_OPERAND (TREE_OPERAND (arg0, 0), 0);
10724 unsigned HOST_WIDE_INT log2 = tree_log2 (arg01);
10725
10726
10727 if ((log2 + TREE_INT_CST_LOW (arg001)) < prec)
10728 {
10729 tem = fold_build2 (LSHIFT_EXPR, itype, arg01, arg001);
10730 tem = fold_build2 (BIT_AND_EXPR, itype, arg000, tem);
10731 return fold_build2 (code, type, tem, arg1);
10732 }
10733
10734
10735
10736 else if (!TYPE_UNSIGNED (itype))
10737 return fold_build2 (code == EQ_EXPR ? GE_EXPR : LT_EXPR, type,
10738 arg000, build_int_cst (itype, 0));
10739
10740
10741
10742 else
10743 return omit_one_operand (type,
10744 code == EQ_EXPR ? integer_one_node
10745 : integer_zero_node,
10746 arg000);
10747 }
10748 }
10749
10750
10751
10752 if (code == NE_EXPR
10753 && integer_zerop (arg1)
10754 && TREE_CODE (arg0) == BIT_AND_EXPR
10755 && integer_onep (TREE_OPERAND (arg0, 1)))
10756 return fold_convert (type, arg0);
10757
10758
10759
10760 if (TREE_CODE (arg0) == BIT_AND_EXPR
10761 && integer_pow2p (TREE_OPERAND (arg0, 1))
10762 && operand_equal_p (TREE_OPERAND (arg0, 1), arg1, 0))
10763 return fold_build2 (code == EQ_EXPR ? NE_EXPR : EQ_EXPR, type,
10764 arg0, fold_convert (TREE_TYPE (arg0),
10765 integer_zero_node));
10766
10767
10768
10769 tem = fold_single_bit_test_into_sign_test (code, arg0, arg1, type);
10770 if (tem)
10771 return tem;
10772
10773
10774
10775 if (TREE_CODE (arg0) == BIT_AND_EXPR
10776 && TREE_CODE (arg1) == INTEGER_CST
10777 && TREE_CODE (TREE_OPERAND (arg0, 1)) == INTEGER_CST)
10778 {
10779 tree notc = fold_build1 (BIT_NOT_EXPR,
10780 TREE_TYPE (TREE_OPERAND (arg0, 1)),
10781 TREE_OPERAND (arg0, 1));
10782 tree dandnotc = fold_build2 (BIT_AND_EXPR, TREE_TYPE (arg0),
10783 arg1, notc);
10784 tree rslt = code == EQ_EXPR ? integer_zero_node : integer_one_node;
10785 if (integer_nonzerop (dandnotc))
10786 return omit_one_operand (type, rslt, arg0);
10787 }
10788
10789
10790
10791 if (TREE_CODE (arg0) == BIT_IOR_EXPR
10792 && TREE_CODE (arg1) == INTEGER_CST
10793 && TREE_CODE (TREE_OPERAND (arg0, 1)) == INTEGER_CST)
10794 {
10795 tree notd = fold_build1 (BIT_NOT_EXPR, TREE_TYPE (arg1), arg1);
10796 tree candnotd = fold_build2 (BIT_AND_EXPR, TREE_TYPE (arg0),
10797 TREE_OPERAND (arg0, 1), notd);
10798 tree rslt = code == EQ_EXPR ? integer_zero_node : integer_one_node;
10799 if (integer_nonzerop (candnotd))
10800 return omit_one_operand (type, rslt, arg0);
10801 }
10802
10803
10804 if (((TREE_CODE (arg0) == COMPONENT_REF
10805 && lang_hooks.can_use_bit_fields_p ())
10806 || TREE_CODE (arg0) == BIT_FIELD_REF)
10807
10808
10809 && (optimize || TREE_CODE (arg1) == INTEGER_CST))
10810 {
10811 t1 = optimize_bit_field_compare (code, type, arg0, arg1);
10812 if (t1)
10813 return t1;
10814 }
10815
10816
10817
10818
10819
10820
10821
10822 if (TREE_CODE (arg0) == CALL_EXPR
10823 && integer_zerop (arg1))
10824 {
10825 tree fndecl = get_callee_fndecl (arg0);
10826 tree arglist;
10827
10828 if (fndecl
10829 && DECL_BUILT_IN_CLASS (fndecl) == BUILT_IN_NORMAL
10830 && DECL_FUNCTION_CODE (fndecl) == BUILT_IN_STRLEN
10831 && (arglist = TREE_OPERAND (arg0, 1))
10832 && TREE_CODE (TREE_TYPE (TREE_VALUE (arglist))) == POINTER_TYPE
10833 && ! TREE_CHAIN (arglist))
10834 {
10835 tree iref = build_fold_indirect_ref (TREE_VALUE (arglist));
10836 return fold_build2 (code, type, iref,
10837 build_int_cst (TREE_TYPE (iref), 0));
10838 }
10839 }
10840
10841
10842
10843 if (TREE_CODE (arg0) == RSHIFT_EXPR
10844 && integer_zerop (arg1)
10845 && TREE_CODE (TREE_OPERAND (arg0, 1)) == INTEGER_CST)
10846 {
10847 tree arg00 = TREE_OPERAND (arg0, 0);
10848 tree arg01 = TREE_OPERAND (arg0, 1);
10849 tree itype = TREE_TYPE (arg00);
10850 if (TREE_INT_CST_HIGH (arg01) == 0
10851 && TREE_INT_CST_LOW (arg01)
10852 == (unsigned HOST_WIDE_INT) (TYPE_PRECISION (itype) - 1))
10853 {
10854 if (TYPE_UNSIGNED (itype))
10855 {
10856 itype = lang_hooks.types.signed_type (itype);
10857 arg00 = fold_convert (itype, arg00);
10858 }
10859 return fold_build2 (code == EQ_EXPR ? GE_EXPR : LT_EXPR,
10860 type, arg00, build_int_cst (itype, 0));
10861 }
10862 }
10863
10864
10865 if (integer_zerop (arg1)
10866 && TREE_CODE (arg0) == BIT_XOR_EXPR)
10867 return fold_build2 (code, type, TREE_OPERAND (arg0, 0),
10868 TREE_OPERAND (arg0, 1));
10869
10870
10871 if (TREE_CODE (arg0) == BIT_XOR_EXPR
10872 && operand_equal_p (TREE_OPERAND (arg0, 1), arg1, 0))
10873 return fold_build2 (code, type, TREE_OPERAND (arg0, 0),
10874 build_int_cst (TREE_TYPE (arg1), 0));
10875
10876 if (TREE_CODE (arg0) == BIT_XOR_EXPR
10877 && operand_equal_p (TREE_OPERAND (arg0, 0), arg1, 0)
10878 && reorder_operands_p (TREE_OPERAND (arg0, 1), arg1))
10879 return fold_build2 (code, type, TREE_OPERAND (arg0, 1),
10880 build_int_cst (TREE_TYPE (arg1), 0));
10881
10882
10883 if (TREE_CODE (arg0) == BIT_XOR_EXPR
10884 && TREE_CODE (arg1) == INTEGER_CST
10885 && TREE_CODE (TREE_OPERAND (arg0, 1)) == INTEGER_CST)
10886 return fold_build2 (code, type, TREE_OPERAND (arg0, 0),
10887 fold_build2 (BIT_XOR_EXPR, TREE_TYPE (arg1),
10888 TREE_OPERAND (arg0, 1), arg1));
10889
10890
10891
10892 if (TREE_CODE (arg0) == BIT_AND_EXPR
10893 && TREE_CODE (TREE_OPERAND (arg0, 0)) == BIT_NOT_EXPR
10894 && integer_zerop (arg1)
10895 && integer_pow2p (TREE_OPERAND (arg0, 1)))
10896 {
10897 tem = fold_build2 (BIT_AND_EXPR, TREE_TYPE (arg0),
10898 TREE_OPERAND (TREE_OPERAND (arg0, 0), 0),
10899 TREE_OPERAND (arg0, 1));
10900 return fold_build2 (code == EQ_EXPR ? NE_EXPR : EQ_EXPR,
10901 type, tem, arg1);
10902 }
10903
10904
10905
10906 if (TREE_CODE (arg0) == BIT_XOR_EXPR
10907 && TREE_CODE (TREE_OPERAND (arg0, 0)) == BIT_AND_EXPR
10908 && integer_zerop (arg1)
10909 && integer_pow2p (TREE_OPERAND (arg0, 1))
10910 && operand_equal_p (TREE_OPERAND (TREE_OPERAND (arg0, 0), 1),
10911 TREE_OPERAND (arg0, 1), OEP_ONLY_CONST))
10912 {
10913 tree arg00 = TREE_OPERAND (arg0, 0);
10914 return fold_build2 (code == EQ_EXPR ? NE_EXPR : EQ_EXPR, type,
10915 arg00, build_int_cst (TREE_TYPE (arg00), 0));
10916 }
10917
10918
10919
10920 if (TREE_CODE (arg0) == BIT_AND_EXPR
10921 && TREE_CODE (TREE_OPERAND (arg0, 0)) == BIT_XOR_EXPR
10922 && integer_zerop (arg1)
10923 && integer_pow2p (TREE_OPERAND (arg0, 1))
10924 && operand_equal_p (TREE_OPERAND (TREE_OPERAND (arg0, 0), 1),
10925 TREE_OPERAND (arg0, 1), OEP_ONLY_CONST))
10926 {
10927 tree arg000 = TREE_OPERAND (TREE_OPERAND (arg0, 0), 0);
10928 tem = fold_build2 (BIT_AND_EXPR, TREE_TYPE (arg000),
10929 arg000, TREE_OPERAND (arg0, 1));
10930 return fold_build2 (code == EQ_EXPR ? NE_EXPR : EQ_EXPR, type,
10931 tem, build_int_cst (TREE_TYPE (tem), 0));
10932 }
10933
10934 if (integer_zerop (arg1)
10935 && tree_expr_nonzero_p (arg0))
10936 {
10937 tree res = constant_boolean_node (code==NE_EXPR, type);
10938 return omit_one_operand (type, res, arg0);
10939 }
10940 return NULL_TREE;
10941
10942 case LT_EXPR:
10943 case GT_EXPR:
10944 case LE_EXPR:
10945 case GE_EXPR:
10946 tem = fold_comparison (code, type, op0, op1);
10947 if (tem != NULL_TREE)
10948 return tem;
10949
10950
10951 if ((TREE_CODE (arg0) == PLUS_EXPR || TREE_CODE (arg0) == MINUS_EXPR)
10952 && operand_equal_p (TREE_OPERAND (arg0, 0), arg1, 0)
10953 && ((TREE_CODE (TREE_OPERAND (arg0, 1)) == REAL_CST
10954 && !HONOR_SNANS (TYPE_MODE (TREE_TYPE (arg0))))
10955 || (TREE_CODE (TREE_OPERAND (arg0, 1)) == INTEGER_CST
10956 && TYPE_OVERFLOW_UNDEFINED (TREE_TYPE (arg1)))))
10957 {
10958 tree arg01 = TREE_OPERAND (arg0, 1);
10959 enum tree_code code0 = TREE_CODE (arg0);
10960 int is_positive;
10961
10962 if (TREE_CODE (arg01) == REAL_CST)
10963 is_positive = REAL_VALUE_NEGATIVE (TREE_REAL_CST (arg01)) ? -1 : 1;
10964 else
10965 is_positive = tree_int_cst_sgn (arg01);
10966
10967
10968 if (code == GT_EXPR
10969 && ((code0 == MINUS_EXPR && is_positive >= 0)
10970 || (code0 == PLUS_EXPR && is_positive <= 0)))
10971 {
10972 if (TREE_CODE (arg01) == INTEGER_CST
10973 && TYPE_OVERFLOW_UNDEFINED (TREE_TYPE (arg1)))
10974 fold_overflow_warning (("assuming signed overflow does not "
10975 "occur when assuming that (X - c) > X "
10976 "is always false"),
10977 WARN_STRICT_OVERFLOW_ALL);
10978 return constant_boolean_node (0, type);
10979 }
10980
10981
10982 if (code == LT_EXPR
10983 && ((code0 == PLUS_EXPR && is_positive >= 0)
10984 || (code0 == MINUS_EXPR && is_positive <= 0)))
10985 {
10986 if (TREE_CODE (arg01) == INTEGER_CST
10987 && TYPE_OVERFLOW_UNDEFINED (TREE_TYPE (arg1)))
10988 fold_overflow_warning (("assuming signed overflow does not "
10989 "occur when assuming that "
10990 "(X + c) < X is always false"),
10991 WARN_STRICT_OVERFLOW_ALL);
10992 return constant_boolean_node (0, type);
10993 }
10994
10995
10996 if (!HONOR_NANS (TYPE_MODE (TREE_TYPE (arg1)))
10997 && code == LE_EXPR
10998 && ((code0 == MINUS_EXPR && is_positive >= 0)
10999 || (code0 == PLUS_EXPR && is_positive <= 0)))
11000 {
11001 if (TREE_CODE (arg01) == INTEGER_CST
11002 && TYPE_OVERFLOW_UNDEFINED (TREE_TYPE (arg1)))
11003 fold_overflow_warning (("assuming signed overflow does not "
11004 "occur when assuming that "
11005 "(X - c) <= X is always true"),
11006 WARN_STRICT_OVERFLOW_ALL);
11007 return constant_boolean_node (1, type);
11008 }
11009
11010
11011 if (!HONOR_NANS (TYPE_MODE (TREE_TYPE (arg1)))
11012 && code == GE_EXPR
11013 && ((code0 == PLUS_EXPR && is_positive >= 0)
11014 || (code0 == MINUS_EXPR && is_positive <= 0)))
11015 {
11016 if (TREE_CODE (arg01) == INTEGER_CST
11017 && TYPE_OVERFLOW_UNDEFINED (TREE_TYPE (arg1)))
11018 fold_overflow_warning (("assuming signed overflow does not "
11019 "occur when assuming that "
11020 "(X + c) >= X is always true"),
11021 WARN_STRICT_OVERFLOW_ALL);
11022 return constant_boolean_node (1, type);
11023 }
11024
11025 if (TREE_CODE (arg01) == INTEGER_CST)
11026 {
11027
11028 if (code == GT_EXPR
11029 && ((code0 == PLUS_EXPR && is_positive > 0)
11030 || (code0 == MINUS_EXPR && is_positive < 0)))
11031 {
11032 if (TYPE_OVERFLOW_UNDEFINED (TREE_TYPE (arg1)))
11033 fold_overflow_warning (("assuming signed overflow does "
11034 "not occur when assuming that "
11035 "(X + c) > X is always true"),
11036 WARN_STRICT_OVERFLOW_ALL);
11037 return constant_boolean_node (1, type);
11038 }
11039
11040 if (code == LT_EXPR
11041 && ((code0 == MINUS_EXPR && is_positive > 0)
11042 || (code0 == PLUS_EXPR && is_positive < 0)))
11043 {
11044 if (TYPE_OVERFLOW_UNDEFINED (TREE_TYPE (arg1)))
11045 fold_overflow_warning (("assuming signed overflow does "
11046 "not occur when assuming that "
11047 "(X - c) < X is always true"),
11048 WARN_STRICT_OVERFLOW_ALL);
11049 return constant_boolean_node (1, type);
11050 }
11051
11052
11053 if (code == LE_EXPR
11054 && ((code0 == PLUS_EXPR && is_positive > 0)
11055 || (code0 == MINUS_EXPR && is_positive < 0)))
11056 {
11057 if (TYPE_OVERFLOW_UNDEFINED (TREE_TYPE (arg1)))
11058 fold_overflow_warning (("assuming signed overflow does "
11059 "not occur when assuming that "
11060 "(X + c) <= X is always false"),
11061 WARN_STRICT_OVERFLOW_ALL);
11062 return constant_boolean_node (0, type);
11063 }
11064
11065 if (code == GE_EXPR
11066 && ((code0 == MINUS_EXPR && is_positive > 0)
11067 || (code0 == PLUS_EXPR && is_positive < 0)))
11068 {
11069 if (TYPE_OVERFLOW_UNDEFINED (TREE_TYPE (arg1)))
11070 fold_overflow_warning (("assuming signed overflow does "
11071 "not occur when assuming that "
11072 "(X - c) >= X is always true"),
11073 WARN_STRICT_OVERFLOW_ALL);
11074 return constant_boolean_node (0, type);
11075 }
11076 }
11077 }
11078
11079
11080
11081
11082 if (TREE_CODE (arg1) == INTEGER_CST
11083 && TREE_CODE (arg0) != INTEGER_CST
11084 && tree_int_cst_sgn (arg1) > 0)
11085 {
11086 if (code == GE_EXPR)
11087 {
11088 arg1 = const_binop (MINUS_EXPR, arg1,
11089 build_int_cst (TREE_TYPE (arg1), 1), 0);
11090 return fold_build2 (GT_EXPR, type, arg0,
11091 fold_convert (TREE_TYPE (arg0), arg1));
11092 }
11093 if (code == LT_EXPR)
11094 {
11095 arg1 = const_binop (MINUS_EXPR, arg1,
11096 build_int_cst (TREE_TYPE (arg1), 1), 0);
11097 return fold_build2 (LE_EXPR, type, arg0,
11098 fold_convert (TREE_TYPE (arg0), arg1));
11099 }
11100 }
11101
11102
11103
11104 {
11105 int width = GET_MODE_BITSIZE (TYPE_MODE (TREE_TYPE (arg1)));
11106
11107 if (TREE_CODE (arg1) == INTEGER_CST
11108 && ! TREE_CONSTANT_OVERFLOW (arg1)
11109 && width <= 2 * HOST_BITS_PER_WIDE_INT
11110 && (INTEGRAL_TYPE_P (TREE_TYPE (arg1))
11111 || POINTER_TYPE_P (TREE_TYPE (arg1))))
11112 {
11113 HOST_WIDE_INT signed_max_hi;
11114 unsigned HOST_WIDE_INT signed_max_lo;
11115 unsigned HOST_WIDE_INT max_hi, max_lo, min_hi, min_lo;
11116
11117 if (width <= HOST_BITS_PER_WIDE_INT)
11118 {
11119 signed_max_lo = ((unsigned HOST_WIDE_INT) 1 << (width - 1))
11120 - 1;
11121 signed_max_hi = 0;
11122 max_hi = 0;
11123
11124 if (TYPE_UNSIGNED (TREE_TYPE (arg1)))
11125 {
11126 max_lo = ((unsigned HOST_WIDE_INT) 2 << (width - 1)) - 1;
11127 min_lo = 0;
11128 min_hi = 0;
11129 }
11130 else
11131 {
11132 max_lo = signed_max_lo;
11133 min_lo = ((unsigned HOST_WIDE_INT) -1 << (width - 1));
11134 min_hi = -1;
11135 }
11136 }
11137 else
11138 {
11139 width -= HOST_BITS_PER_WIDE_INT;
11140 signed_max_lo = -1;
11141 signed_max_hi = ((unsigned HOST_WIDE_INT) 1 << (width - 1))
11142 - 1;
11143 max_lo = -1;
11144 min_lo = 0;
11145
11146 if (TYPE_UNSIGNED (TREE_TYPE (arg1)))
11147 {
11148 max_hi = ((unsigned HOST_WIDE_INT) 2 << (width - 1)) - 1;
11149 min_hi = 0;
11150 }
11151 else
11152 {
11153 max_hi = signed_max_hi;
11154 min_hi = ((unsigned HOST_WIDE_INT) -1 << (width - 1));
11155 }
11156 }
11157
11158 if ((unsigned HOST_WIDE_INT) TREE_INT_CST_HIGH (arg1) == max_hi
11159 && TREE_INT_CST_LOW (arg1) == max_lo)
11160 switch (code)
11161 {
11162 case GT_EXPR:
11163 return omit_one_operand (type, integer_zero_node, arg0);
11164
11165 case GE_EXPR:
11166 return fold_build2 (EQ_EXPR, type, op0, op1);
11167
11168 case LE_EXPR:
11169 return omit_one_operand (type, integer_one_node, arg0);
11170
11171 case LT_EXPR:
11172 return fold_build2 (NE_EXPR, type, op0, op1);
11173
11174
11175
11176
11177 default:
11178 break;
11179 }
11180 else if ((unsigned HOST_WIDE_INT) TREE_INT_CST_HIGH (arg1)
11181 == max_hi
11182 && TREE_INT_CST_LOW (arg1) == max_lo - 1)
11183 switch (code)
11184 {
11185 case GT_EXPR:
11186 arg1 = const_binop (PLUS_EXPR, arg1, integer_one_node, 0);
11187 return fold_build2 (EQ_EXPR, type,
11188 fold_convert (TREE_TYPE (arg1), arg0),
11189 arg1);
11190 case LE_EXPR:
11191 arg1 = const_binop (PLUS_EXPR, arg1, integer_one_node, 0);
11192 return fold_build2 (NE_EXPR, type,
11193 fold_convert (TREE_TYPE (arg1), arg0),
11194 arg1);
11195 default:
11196 break;
11197 }
11198 else if ((unsigned HOST_WIDE_INT) TREE_INT_CST_HIGH (arg1)
11199 == min_hi
11200 && TREE_INT_CST_LOW (arg1) == min_lo)
11201 switch (code)
11202 {
11203 case LT_EXPR:
11204 return omit_one_operand (type, integer_zero_node, arg0);
11205
11206 case LE_EXPR:
11207 return fold_build2 (EQ_EXPR, type, op0, op1);
11208
11209 case GE_EXPR:
11210 return omit_one_operand (type, integer_one_node, arg0);
11211
11212 case GT_EXPR:
11213 return fold_build2 (NE_EXPR, type, op0, op1);
11214
11215 default:
11216 break;
11217 }
11218 else if ((unsigned HOST_WIDE_INT) TREE_INT_CST_HIGH (arg1)
11219 == min_hi
11220 && TREE_INT_CST_LOW (arg1) == min_lo + 1)
11221 switch (code)
11222 {
11223 case GE_EXPR:
11224 arg1 = const_binop (MINUS_EXPR, arg1, integer_one_node, 0);
11225 return fold_build2 (NE_EXPR, type,
11226 fold_convert (TREE_TYPE (arg1), arg0),
11227 arg1);
11228 case LT_EXPR:
11229 arg1 = const_binop (MINUS_EXPR, arg1, integer_one_node, 0);
11230 return fold_build2 (EQ_EXPR, type,
11231 fold_convert (TREE_TYPE (arg1), arg0),
11232 arg1);
11233 default:
11234 break;
11235 }
11236
11237 else if (!in_gimple_form
11238 && TREE_INT_CST_HIGH (arg1) == signed_max_hi
11239 && TREE_INT_CST_LOW (arg1) == signed_max_lo
11240 && TYPE_UNSIGNED (TREE_TYPE (arg1))
11241
11242 && INTEGRAL_TYPE_P (TREE_TYPE (arg1)))
11243 {
11244
11245
11246 if (code == LE_EXPR || code == GT_EXPR)
11247 {
11248 tree st;
11249 st = lang_hooks.types.signed_type (TREE_TYPE (arg1));
11250 return fold_build2 (code == LE_EXPR ? GE_EXPR : LT_EXPR,
11251 type, fold_convert (st, arg0),
11252 build_int_cst (st, 0));
11253 }
11254 }
11255 }
11256 }
11257
11258
11259
11260
11261
11262
11263 if (code == LE_EXPR
11264 && TREE_CODE (arg1) == INTEGER_CST
11265 && TREE_CODE (arg0) == ABS_EXPR
11266 && ! TREE_SIDE_EFFECTS (arg0)
11267 && (0 != (tem = negate_expr (arg1)))
11268 && TREE_CODE (tem) == INTEGER_CST
11269 && ! TREE_CONSTANT_OVERFLOW (tem))
11270 return fold_build2 (TRUTH_ANDIF_EXPR, type,
11271 build2 (GE_EXPR, type,
11272 TREE_OPERAND (arg0, 0), tem),
11273 build2 (LE_EXPR, type,
11274 TREE_OPERAND (arg0, 0), arg1));
11275
11276
11277 strict_overflow_p = false;
11278 if (code == GE_EXPR
11279 && (integer_zerop (arg1)
11280 || (! HONOR_NANS (TYPE_MODE (TREE_TYPE (arg0)))
11281 && real_zerop (arg1)))
11282 && tree_expr_nonnegative_warnv_p (arg0, &strict_overflow_p))
11283 {
11284 if (strict_overflow_p)
11285 fold_overflow_warning (("assuming signed overflow does not occur "
11286 "when simplifying comparison of "
11287 "absolute value and zero"),
11288 WARN_STRICT_OVERFLOW_CONDITIONAL);
11289 return omit_one_operand (type, integer_one_node, arg0);
11290 }
11291
11292
11293 strict_overflow_p = false;
11294 if (code == LT_EXPR
11295 && (integer_zerop (arg1) || real_zerop (arg1))
11296 && tree_expr_nonnegative_warnv_p (arg0, &strict_overflow_p))
11297 {
11298 if (strict_overflow_p)
11299 fold_overflow_warning (("assuming signed overflow does not occur "
11300 "when simplifying comparison of "
11301 "absolute value and zero"),
11302 WARN_STRICT_OVERFLOW_CONDITIONAL);
11303 return omit_one_operand (type, integer_zero_node, arg0);
11304 }
11305
11306
11307
11308 if ((code == LT_EXPR || code == GE_EXPR)
11309 && TYPE_UNSIGNED (TREE_TYPE (arg0))
11310 && TREE_CODE (arg1) == LSHIFT_EXPR
11311 && integer_onep (TREE_OPERAND (arg1, 0)))
11312 return build2 (code == LT_EXPR ? EQ_EXPR : NE_EXPR, type,
11313 build2 (RSHIFT_EXPR, TREE_TYPE (arg0), arg0,
11314 TREE_OPERAND (arg1, 1)),
11315 build_int_cst (TREE_TYPE (arg0), 0));
11316
11317 if ((code == LT_EXPR || code == GE_EXPR)
11318 && TYPE_UNSIGNED (TREE_TYPE (arg0))
11319 && (TREE_CODE (arg1) == NOP_EXPR
11320 || TREE_CODE (arg1) == CONVERT_EXPR)
11321 && TREE_CODE (TREE_OPERAND (arg1, 0)) == LSHIFT_EXPR
11322 && integer_onep (TREE_OPERAND (TREE_OPERAND (arg1, 0), 0)))
11323 return
11324 build2 (code == LT_EXPR ? EQ_EXPR : NE_EXPR, type,
11325 fold_convert (TREE_TYPE (arg0),
11326 build2 (RSHIFT_EXPR, TREE_TYPE (arg0), arg0,
11327 TREE_OPERAND (TREE_OPERAND (arg1, 0),
11328 1))),
11329 build_int_cst (TREE_TYPE (arg0), 0));
11330
11331 return NULL_TREE;
11332
11333 case UNORDERED_EXPR:
11334 case ORDERED_EXPR:
11335 case UNLT_EXPR:
11336 case UNLE_EXPR:
11337 case UNGT_EXPR:
11338 case UNGE_EXPR:
11339 case UNEQ_EXPR:
11340 case LTGT_EXPR:
11341 if (TREE_CODE (arg0) == REAL_CST && TREE_CODE (arg1) == REAL_CST)
11342 {
11343 t1 = fold_relational_const (code, type, arg0, arg1);
11344 if (t1 != NULL_TREE)
11345 return t1;
11346 }
11347
11348
11349 if (TREE_CODE (arg0) == REAL_CST
11350 && REAL_VALUE_ISNAN (TREE_REAL_CST (arg0))
11351 && (code != LTGT_EXPR || ! flag_trapping_math))
11352 {
11353 t1 = (code == ORDERED_EXPR || code == LTGT_EXPR)
11354 ? integer_zero_node
11355 : integer_one_node;
11356 return omit_one_operand (type, t1, arg1);
11357 }
11358
11359
11360 if (TREE_CODE (arg1) == REAL_CST
11361 && REAL_VALUE_ISNAN (TREE_REAL_CST (arg1))
11362 && (code != LTGT_EXPR || ! flag_trapping_math))
11363 {
11364 t1 = (code == ORDERED_EXPR || code == LTGT_EXPR)
11365 ? integer_zero_node
11366 : integer_one_node;
11367 return omit_one_operand (type, t1, arg0);
11368 }
11369
11370
11371 if ((code == UNLE_EXPR || code == UNGE_EXPR || code == UNEQ_EXPR)
11372 && operand_equal_p (arg0, arg1, 0))
11373 return constant_boolean_node (1, type);
11374
11375 if (code == LTGT_EXPR
11376 && !flag_trapping_math
11377 && operand_equal_p (arg0, arg1, 0))
11378 return constant_boolean_node (0, type);
11379
11380
11381 {
11382 tree targ0 = strip_float_extensions (arg0);
11383 tree targ1 = strip_float_extensions (arg1);
11384 tree newtype = TREE_TYPE (targ0);
11385
11386 if (TYPE_PRECISION (TREE_TYPE (targ1)) > TYPE_PRECISION (newtype))
11387 newtype = TREE_TYPE (targ1);
11388
11389 if (TYPE_PRECISION (newtype) < TYPE_PRECISION (TREE_TYPE (arg0)))
11390 return fold_build2 (code, type, fold_convert (newtype, targ0),
11391 fold_convert (newtype, targ1));
11392 }
11393
11394 return NULL_TREE;
11395
11396 case COMPOUND_EXPR:
11397
11398
11399 if (TREE_SIDE_EFFECTS (arg0) || TREE_CONSTANT (arg1))
11400 return NULL_TREE;
11401
11402 tem = integer_zerop (arg1) ? build1 (NOP_EXPR, type, arg1)
11403 : fold_convert (type, arg1);
11404 return pedantic_non_lvalue (tem);
11405
11406 case COMPLEX_EXPR:
11407 if ((TREE_CODE (arg0) == REAL_CST
11408 && TREE_CODE (arg1) == REAL_CST)
11409 || (TREE_CODE (arg0) == INTEGER_CST
11410 && TREE_CODE (arg1) == INTEGER_CST))
11411 return build_complex (type, arg0, arg1);
11412 return NULL_TREE;
11413
11414 case ASSERT_EXPR:
11415
11416 gcc_unreachable ();
11417
11418 default:
11419 return NULL_TREE;
11420 }
11421 }
11422
11423
11424
11425
11426
11427 static tree
11428 contains_label_1 (tree *tp,
11429 int *walk_subtrees,
11430 void *data ATTRIBUTE_UNUSED)
11431 {
11432 switch (TREE_CODE (*tp))
11433 {
11434 case LABEL_EXPR:
11435 return *tp;
11436 case GOTO_EXPR:
11437 *walk_subtrees = 0;
11438
11439 default:
11440 return NULL_TREE;
11441 }
11442 }
11443
11444
11445
11446
11447
11448 static bool
11449 contains_label_p (tree st)
11450 {
11451 return (walk_tree (&st, contains_label_1 , NULL, NULL) != NULL_TREE);
11452 }
11453
11454
11455
11456
11457
11458 tree
11459 fold_ternary (enum tree_code code, tree type, tree op0, tree op1, tree op2)
11460 {
11461 tree tem;
11462 tree arg0 = NULL_TREE, arg1 = NULL_TREE;
11463 enum tree_code_class kind = TREE_CODE_CLASS (code);
11464
11465 gcc_assert (IS_EXPR_CODE_CLASS (kind)
11466 && TREE_CODE_LENGTH (code) == 3);
11467
11468
11469
11470
11471
11472
11473
11474
11475
11476
11477
11478 if (op0)
11479 {
11480 arg0 = op0;
11481 STRIP_NOPS (arg0);
11482 }
11483
11484 if (op1)
11485 {
11486 arg1 = op1;
11487 STRIP_NOPS (arg1);
11488 }
11489
11490 switch (code)
11491 {
11492 case COMPONENT_REF:
11493 if (TREE_CODE (arg0) == CONSTRUCTOR
11494 && ! type_contains_placeholder_p (TREE_TYPE (arg0)))
11495 {
11496 unsigned HOST_WIDE_INT idx;
11497 tree field, value;
11498 FOR_EACH_CONSTRUCTOR_ELT (CONSTRUCTOR_ELTS (arg0), idx, field, value)
11499 if (field == arg1)
11500 return value;
11501 }
11502 return NULL_TREE;
11503
11504 case COND_EXPR:
11505
11506
11507 if (TREE_CODE (arg0) == INTEGER_CST)
11508 {
11509 tree unused_op = integer_zerop (arg0) ? op1 : op2;
11510 tem = integer_zerop (arg0) ? op2 : op1;
11511
11512
11513
11514
11515 if ((!TREE_SIDE_EFFECTS (unused_op)
11516 || !contains_label_p (unused_op))
11517 && (! VOID_TYPE_P (TREE_TYPE (tem))
11518 || VOID_TYPE_P (type)))
11519 return pedantic_non_lvalue (tem);
11520 return NULL_TREE;
11521 }
11522 if (operand_equal_p (arg1, op2, 0))
11523 return pedantic_omit_one_operand (type, arg1, arg0);
11524
11525
11526
11527
11528
11529
11530
11531 if (COMPARISON_CLASS_P (arg0)
11532 && operand_equal_for_comparison_p (TREE_OPERAND (arg0, 0),
11533 arg1, TREE_OPERAND (arg0, 1))
11534 && !HONOR_SIGNED_ZEROS (TYPE_MODE (TREE_TYPE (arg1))))
11535 {
11536 tem = fold_cond_expr_with_comparison (type, arg0, op1, op2);
11537 if (tem)
11538 return tem;
11539 }
11540
11541 if (COMPARISON_CLASS_P (arg0)
11542 && operand_equal_for_comparison_p (TREE_OPERAND (arg0, 0),
11543 op2,
11544 TREE_OPERAND (arg0, 1))
11545 && !HONOR_SIGNED_ZEROS (TYPE_MODE (TREE_TYPE (op2))))
11546 {
11547 tem = fold_truth_not_expr (arg0);
11548 if (tem && COMPARISON_CLASS_P (tem))
11549 {
11550 tem = fold_cond_expr_with_comparison (type, tem, op2, op1);
11551 if (tem)
11552 return tem;
11553 }
11554 }
11555
11556
11557
11558 if (truth_value_p (TREE_CODE (arg0))
11559 && tree_swap_operands_p (op1, op2, false))
11560 {
11561
11562
11563
11564 tem = fold_truth_not_expr (arg0);
11565 if (tem)
11566 return fold_build3 (code, type, tem, op2, op1);
11567 }
11568
11569
11570 if (integer_onep (op1)
11571 && integer_zerop (op2)
11572
11573
11574
11575
11576 && type == TREE_TYPE (arg0))
11577 return pedantic_non_lvalue (arg0);
11578
11579
11580
11581 if (integer_zerop (op1)
11582 && integer_onep (op2)
11583 && truth_value_p (TREE_CODE (arg0)))
11584 return pedantic_non_lvalue (fold_convert (type,
11585 invert_truthvalue (arg0)));
11586
11587
11588 if (TREE_CODE (arg0) == LT_EXPR
11589 && integer_zerop (TREE_OPERAND (arg0, 1))
11590 && integer_zerop (op2)
11591 && (tem = sign_bit_p (TREE_OPERAND (arg0, 0), arg1)))
11592 {
11593
11594
11595
11596
11597
11598
11599 if (TYPE_PRECISION (TREE_TYPE (tem))
11600 < TYPE_PRECISION (TREE_TYPE (arg1))
11601 && TYPE_PRECISION (TREE_TYPE (tem))
11602 < TYPE_PRECISION (type))
11603 {
11604 unsigned HOST_WIDE_INT mask_lo;
11605 HOST_WIDE_INT mask_hi;
11606 int inner_width, outer_width;
11607 tree tem_type;
11608
11609 inner_width = TYPE_PRECISION (TREE_TYPE (tem));
11610 outer_width = TYPE_PRECISION (TREE_TYPE (arg1));
11611 if (outer_width > TYPE_PRECISION (type))
11612 outer_width = TYPE_PRECISION (type);
11613
11614 if (outer_width > HOST_BITS_PER_WIDE_INT)
11615 {
11616 mask_hi = ((unsigned HOST_WIDE_INT) -1
11617 >> (2 * HOST_BITS_PER_WIDE_INT - outer_width));
11618 mask_lo = -1;
11619 }
11620 else
11621 {
11622 mask_hi = 0;
11623 mask_lo = ((unsigned HOST_WIDE_INT) -1
11624 >> (HOST_BITS_PER_WIDE_INT - outer_width));
11625 }
11626 if (inner_width > HOST_BITS_PER_WIDE_INT)
11627 {
11628 mask_hi &= ~((unsigned HOST_WIDE_INT) -1
11629 >> (HOST_BITS_PER_WIDE_INT - inner_width));
11630 mask_lo = 0;
11631 }
11632 else
11633 mask_lo &= ~((unsigned HOST_WIDE_INT) -1
11634 >> (HOST_BITS_PER_WIDE_INT - inner_width));
11635
11636 if ((TREE_INT_CST_HIGH (arg1) & mask_hi) == mask_hi
11637 && (TREE_INT_CST_LOW (arg1) & mask_lo) == mask_lo)
11638 {
11639 tem_type = lang_hooks.types.signed_type (TREE_TYPE (tem));
11640 tem = fold_convert (tem_type, tem);
11641 }
11642 else if ((TREE_INT_CST_HIGH (arg1) & mask_hi) == 0
11643 && (TREE_INT_CST_LOW (arg1) & mask_lo) == 0)
11644 {
11645 tem_type = lang_hooks.types.unsigned_type (TREE_TYPE (tem));
11646 tem = fold_convert (tem_type, tem);
11647 }
11648 else
11649 tem = NULL;
11650 }
11651
11652 if (tem)
11653 return fold_convert (type,
11654 fold_build2 (BIT_AND_EXPR,
11655 TREE_TYPE (tem), tem,
11656 fold_convert (TREE_TYPE (tem),
11657 arg1)));
11658 }
11659
11660
11661
11662 if (TREE_CODE (arg0) == BIT_AND_EXPR
11663 && integer_onep (TREE_OPERAND (arg0, 1))
11664 && integer_zerop (op2)
11665 && integer_pow2p (arg1))
11666 {
11667 tree tem = TREE_OPERAND (arg0, 0);
11668 STRIP_NOPS (tem);
11669 if (TREE_CODE (tem) == RSHIFT_EXPR
11670 && TREE_CODE (TREE_OPERAND (tem, 1)) == INTEGER_CST
11671 && (unsigned HOST_WIDE_INT) tree_log2 (arg1) ==
11672 TREE_INT_CST_LOW (TREE_OPERAND (tem, 1)))
11673 return fold_build2 (BIT_AND_EXPR, type,
11674 TREE_OPERAND (tem, 0), arg1);
11675 }
11676
11677
11678
11679
11680
11681 if (integer_zerop (op2)
11682 && TREE_CODE (arg0) == NE_EXPR
11683 && integer_zerop (TREE_OPERAND (arg0, 1))
11684 && integer_pow2p (arg1)
11685 && TREE_CODE (TREE_OPERAND (arg0, 0)) == BIT_AND_EXPR
11686 && operand_equal_p (TREE_OPERAND (TREE_OPERAND (arg0, 0), 1),
11687 arg1, OEP_ONLY_CONST))
11688 return pedantic_non_lvalue (fold_convert (type,
11689 TREE_OPERAND (arg0, 0)));
11690
11691
11692 if (integer_zerop (op2)
11693 && truth_value_p (TREE_CODE (arg0))
11694 && truth_value_p (TREE_CODE (arg1)))
11695 return fold_build2 (TRUTH_ANDIF_EXPR, type,
11696 fold_convert (type, arg0),
11697 arg1);
11698
11699
11700 if (integer_onep (op2)
11701 && truth_value_p (TREE_CODE (arg0))
11702 && truth_value_p (TREE_CODE (arg1)))
11703 {
11704
11705 tem = fold_truth_not_expr (arg0);
11706 if (tem)
11707 return fold_build2 (TRUTH_ORIF_EXPR, type,
11708 fold_convert (type, tem),
11709 arg1);
11710 }
11711
11712
11713 if (integer_zerop (arg1)
11714 && truth_value_p (TREE_CODE (arg0))
11715 && truth_value_p (TREE_CODE (op2)))
11716 {
11717
11718 tem = fold_truth_not_expr (arg0);
11719 if (tem)
11720 return fold_build2 (TRUTH_ANDIF_EXPR, type,
11721 fold_convert (type, tem),
11722 op2);
11723 }
11724
11725
11726 if (integer_onep (arg1)
11727 && truth_value_p (TREE_CODE (arg0))
11728 && truth_value_p (TREE_CODE (op2)))
11729 return fold_build2 (TRUTH_ORIF_EXPR, type,
11730 fold_convert (type, arg0),
11731 op2);
11732
11733 return NULL_TREE;
11734
11735 case CALL_EXPR:
11736
11737 if (TREE_CODE (op0) == ADDR_EXPR
11738 && TREE_CODE (TREE_OPERAND (op0, 0)) == FUNCTION_DECL
11739 && DECL_BUILT_IN (TREE_OPERAND (op0, 0)))
11740 return fold_builtin (TREE_OPERAND (op0, 0), op1, false);
11741 return NULL_TREE;
11742
11743 case BIT_FIELD_REF:
11744 if (TREE_CODE (arg0) == VECTOR_CST
11745 && type == TREE_TYPE (TREE_TYPE (arg0))
11746 && host_integerp (arg1, 1)
11747 && host_integerp (op2, 1))
11748 {
11749 unsigned HOST_WIDE_INT width = tree_low_cst (arg1, 1);
11750 unsigned HOST_WIDE_INT idx = tree_low_cst (op2, 1);
11751
11752 if (width != 0
11753 && simple_cst_equal (arg1, TYPE_SIZE (type)) == 1
11754 && (idx % width) == 0
11755 && (idx = idx / width)
11756 < TYPE_VECTOR_SUBPARTS (TREE_TYPE (arg0)))
11757 {
11758 tree elements = TREE_VECTOR_CST_ELTS (arg0);
11759 while (idx-- > 0 && elements)
11760 elements = TREE_CHAIN (elements);
11761 if (elements)
11762 return TREE_VALUE (elements);
11763 else
11764 return fold_convert (type, integer_zero_node);
11765 }
11766 }
11767 return NULL_TREE;
11768
11769 default:
11770 return NULL_TREE;
11771 }
11772 }
11773
11774
11775
11776
11777
11778
11779
11780
11781
11782 #ifdef ENABLE_FOLD_CHECKING
11783 # define fold(x) fold_1 (x)
11784 static tree fold_1 (tree);
11785 static
11786 #endif
11787 tree
11788 fold (tree expr)
11789 {
11790 const tree t = expr;
11791 enum tree_code code = TREE_CODE (t);
11792 enum tree_code_class kind = TREE_CODE_CLASS (code);
11793 tree tem;
11794
11795
11796 if (kind == tcc_constant)
11797 return t;
11798
11799 if (IS_EXPR_CODE_CLASS (kind))
11800 {
11801 tree type = TREE_TYPE (t);
11802 tree op0, op1, op2;
11803
11804 switch (TREE_CODE_LENGTH (code))
11805 {
11806 case 1:
11807 op0 = TREE_OPERAND (t, 0);
11808 tem = fold_unary (code, type, op0);
11809 return tem ? tem : expr;
11810 case 2:
11811 op0 = TREE_OPERAND (t, 0);
11812 op1 = TREE_OPERAND (t, 1);
11813 tem = fold_binary (code, type, op0, op1);
11814 return tem ? tem : expr;
11815 case 3:
11816 op0 = TREE_OPERAND (t, 0);
11817 op1 = TREE_OPERAND (t, 1);
11818 op2 = TREE_OPERAND (t, 2);
11819 tem = fold_ternary (code, type, op0, op1, op2);
11820 return tem ? tem : expr;
11821 default:
11822 break;
11823 }
11824 }
11825
11826 switch (code)
11827 {
11828 case CONST_DECL:
11829 return fold (DECL_INITIAL (t));
11830
11831 default:
11832 return t;
11833 }
11834 }
11835
11836 #ifdef ENABLE_FOLD_CHECKING
11837 #undef fold
11838
11839 static void fold_checksum_tree (tree, struct md5_ctx *, htab_t);
11840 static void fold_check_failed (tree, tree);
11841 void print_fold_checksum (tree);
11842
11843
11844
11845
11846
11847 tree
11848 fold (tree expr)
11849 {
11850 tree ret;
11851 struct md5_ctx ctx;
11852 unsigned char checksum_before[16], checksum_after[16];
11853 htab_t ht;
11854
11855 ht = htab_create (32, htab_hash_pointer, htab_eq_pointer, NULL);
11856 md5_init_ctx (&ctx);
11857 fold_checksum_tree (expr, &ctx, ht);
11858 md5_finish_ctx (&ctx, checksum_before);
11859 htab_empty (ht);
11860
11861 ret = fold_1 (expr);
11862
11863 md5_init_ctx (&ctx);
11864 fold_checksum_tree (expr, &ctx, ht);
11865 md5_finish_ctx (&ctx, checksum_after);
11866 htab_delete (ht);
11867
11868 if (memcmp (checksum_before, checksum_after, 16))
11869 fold_check_failed (expr, ret);
11870
11871 return ret;
11872 }
11873
11874 void
11875 print_fold_checksum (tree expr)
11876 {
11877 struct md5_ctx ctx;
11878 unsigned char checksum[16], cnt;
11879 htab_t ht;
11880
11881 ht = htab_create (32, htab_hash_pointer, htab_eq_pointer, NULL);
11882 md5_init_ctx (&ctx);
11883 fold_checksum_tree (expr, &ctx, ht);
11884 md5_finish_ctx (&ctx, checksum);
11885 htab_delete (ht);
11886 for (cnt = 0; cnt < 16; ++cnt)
11887 fprintf (stderr, "%02x", checksum[cnt]);
11888 putc ('\n', stderr);
11889 }
11890
11891 static void
11892 fold_check_failed (tree expr ATTRIBUTE_UNUSED, tree ret ATTRIBUTE_UNUSED)
11893 {
11894 internal_error ("fold check: original tree changed by fold");
11895 }
11896
11897 static void
11898 fold_checksum_tree (tree expr, struct md5_ctx *ctx, htab_t ht)
11899 {
11900 void **slot;
11901 enum tree_code code;
11902 struct tree_function_decl buf;
11903 int i, len;
11904
11905 recursive_label:
11906
11907 gcc_assert ((sizeof (struct tree_exp) + 5 * sizeof (tree)
11908 <= sizeof (struct tree_function_decl))
11909 && sizeof (struct tree_type) <= sizeof (struct tree_function_decl));
11910 if (expr == NULL)
11911 return;
11912 slot = htab_find_slot (ht, expr, INSERT);
11913 if (*slot != NULL)
11914 return;
11915 *slot = expr;
11916 code = TREE_CODE (expr);
11917 if (TREE_CODE_CLASS (code) == tcc_declaration
11918 && DECL_ASSEMBLER_NAME_SET_P (expr))
11919 {
11920
11921 memcpy ((char *) &buf, expr, tree_size (expr));
11922 expr = (tree) &buf;
11923 SET_DECL_ASSEMBLER_NAME (expr, NULL);
11924 }
11925 else if (TREE_CODE_CLASS (code) == tcc_type
11926 && (TYPE_POINTER_TO (expr) || TYPE_REFERENCE_TO (expr)
11927 || TYPE_CACHED_VALUES_P (expr)
11928 || TYPE_CONTAINS_PLACEHOLDER_INTERNAL (expr)))
11929 {
11930
11931 memcpy ((char *) &buf, expr, tree_size (expr));
11932 expr = (tree) &buf;
11933 TYPE_CONTAINS_PLACEHOLDER_INTERNAL (expr) = 0;
11934 TYPE_POINTER_TO (expr) = NULL;
11935 TYPE_REFERENCE_TO (expr) = NULL;
11936 if (TYPE_CACHED_VALUES_P (expr))
11937 {
11938 TYPE_CACHED_VALUES_P (expr) = 0;
11939 TYPE_CACHED_VALUES (expr) = NULL;
11940 }
11941 }
11942 md5_process_bytes (expr, tree_size (expr), ctx);
11943 fold_checksum_tree (TREE_TYPE (expr), ctx, ht);
11944 if (TREE_CODE_CLASS (code) != tcc_type
11945 && TREE_CODE_CLASS (code) != tcc_declaration
11946 && code != TREE_LIST)
11947 fold_checksum_tree (TREE_CHAIN (expr), ctx, ht);
11948 switch (TREE_CODE_CLASS (code))
11949 {
11950 case tcc_constant:
11951 switch (code)
11952 {
11953 case STRING_CST:
11954 md5_process_bytes (TREE_STRING_POINTER (expr),
11955 TREE_STRING_LENGTH (expr), ctx);
11956 break;
11957 case COMPLEX_CST:
11958 fold_checksum_tree (TREE_REALPART (expr), ctx, ht);
11959 fold_checksum_tree (TREE_IMAGPART (expr), ctx, ht);
11960 break;
11961 case VECTOR_CST:
11962 fold_checksum_tree (TREE_VECTOR_CST_ELTS (expr), ctx, ht);
11963 break;
11964 default:
11965 break;
11966 }
11967 break;
11968 case tcc_exceptional:
11969 switch (code)
11970 {
11971 case TREE_LIST:
11972 fold_checksum_tree (TREE_PURPOSE (expr), ctx, ht);
11973 fold_checksum_tree (TREE_VALUE (expr), ctx, ht);
11974 expr = TREE_CHAIN (expr);
11975 goto recursive_label;
11976 break;
11977 case TREE_VEC:
11978 for (i = 0; i < TREE_VEC_LENGTH (expr); ++i)
11979 fold_checksum_tree (TREE_VEC_ELT (expr, i), ctx, ht);
11980 break;
11981 default:
11982 break;
11983 }
11984 break;
11985 case tcc_expression:
11986 case tcc_reference:
11987 case tcc_comparison:
11988 case tcc_unary:
11989 case tcc_binary:
11990 case tcc_statement:
11991 len = TREE_CODE_LENGTH (code);
11992 for (i = 0; i < len; ++i)
11993 fold_checksum_tree (TREE_OPERAND (expr, i), ctx, ht);
11994 break;
11995 case tcc_declaration:
11996 fold_checksum_tree (DECL_NAME (expr), ctx, ht);
11997 fold_checksum_tree (DECL_CONTEXT (expr), ctx, ht);
11998 if (CODE_CONTAINS_STRUCT (TREE_CODE (expr), TS_DECL_COMMON))
11999 {
12000 fold_checksum_tree (DECL_SIZE (expr), ctx, ht);
12001 fold_checksum_tree (DECL_SIZE_UNIT (expr), ctx, ht);
12002 fold_checksum_tree (DECL_INITIAL (expr), ctx, ht);
12003 fold_checksum_tree (DECL_ABSTRACT_ORIGIN (expr), ctx, ht);
12004 fold_checksum_tree (DECL_ATTRIBUTES (expr), ctx, ht);
12005 }
12006 if (CODE_CONTAINS_STRUCT (TREE_CODE (expr), TS_DECL_WITH_VIS))
12007 fold_checksum_tree (DECL_SECTION_NAME (expr), ctx, ht);
12008
12009 if (CODE_CONTAINS_STRUCT (TREE_CODE (expr), TS_DECL_NON_COMMON))
12010 {
12011 fold_checksum_tree (DECL_VINDEX (expr), ctx, ht);
12012 fold_checksum_tree (DECL_RESULT_FLD (expr), ctx, ht);
12013 fold_checksum_tree (DECL_ARGUMENT_FLD (expr), ctx, ht);
12014 }
12015 break;
12016 case tcc_type:
12017 if (TREE_CODE (expr) == ENUMERAL_TYPE)
12018 fold_checksum_tree (TYPE_VALUES (expr), ctx, ht);
12019 fold_checksum_tree (TYPE_SIZE (expr), ctx, ht);
12020 fold_checksum_tree (TYPE_SIZE_UNIT (expr), ctx, ht);
12021 fold_checksum_tree (TYPE_ATTRIBUTES (expr), ctx, ht);
12022 fold_checksum_tree (TYPE_NAME (expr), ctx, ht);
12023 if (INTEGRAL_TYPE_P (expr)
12024 || SCALAR_FLOAT_TYPE_P (expr))
12025 {
12026 fold_checksum_tree (TYPE_MIN_VALUE (expr), ctx, ht);
12027 fold_checksum_tree (TYPE_MAX_VALUE (expr), ctx, ht);
12028 }
12029 fold_checksum_tree (TYPE_MAIN_VARIANT (expr), ctx, ht);
12030 if (TREE_CODE (expr) == RECORD_TYPE
12031 || TREE_CODE (expr) == UNION_TYPE
12032 || TREE_CODE (expr) == QUAL_UNION_TYPE)
12033 fold_checksum_tree (TYPE_BINFO (expr), ctx, ht);
12034 fold_checksum_tree (TYPE_CONTEXT (expr), ctx, ht);
12035 break;
12036 default:
12037 break;
12038 }
12039 }
12040
12041 #endif
12042
12043
12044
12045
12046
12047
12048 tree
12049 fold_build1_stat (enum tree_code code, tree type, tree op0 MEM_STAT_DECL)
12050 {
12051 tree tem;
12052 #ifdef ENABLE_FOLD_CHECKING
12053 unsigned char checksum_before[16], checksum_after[16];
12054 struct md5_ctx ctx;
12055 htab_t ht;
12056
12057 ht = htab_create (32, htab_hash_pointer, htab_eq_pointer, NULL);
12058 md5_init_ctx (&ctx);
12059 fold_checksum_tree (op0, &ctx, ht);
12060 md5_finish_ctx (&ctx, checksum_before);
12061 htab_empty (ht);
12062 #endif
12063
12064 tem = fold_unary (code, type, op0);
12065 if (!tem)
12066 tem = build1_stat (code, type, op0 PASS_MEM_STAT);
12067
12068 #ifdef ENABLE_FOLD_CHECKING
12069 md5_init_ctx (&ctx);
12070 fold_checksum_tree (op0, &ctx, ht);
12071 md5_finish_ctx (&ctx, checksum_after);
12072 htab_delete (ht);
12073
12074 if (memcmp (checksum_before, checksum_after, 16))
12075 fold_check_failed (op0, tem);
12076 #endif
12077 return tem;
12078 }
12079
12080
12081
12082
12083
12084
12085 tree
12086 fold_build2_stat (enum tree_code code, tree type, tree op0, tree op1
12087 MEM_STAT_DECL)
12088 {
12089 tree tem;
12090 #ifdef ENABLE_FOLD_CHECKING
12091 unsigned char checksum_before_op0[16],
12092 checksum_before_op1[16],
12093 checksum_after_op0[16],
12094 checksum_after_op1[16];
12095 struct md5_ctx ctx;
12096 htab_t ht;
12097
12098 ht = htab_create (32, htab_hash_pointer, htab_eq_pointer, NULL);
12099 md5_init_ctx (&ctx);
12100 fold_checksum_tree (op0, &ctx, ht);
12101 md5_finish_ctx (&ctx, checksum_before_op0);
12102 htab_empty (ht);
12103
12104 md5_init_ctx (&ctx);
12105 fold_checksum_tree (op1, &ctx, ht);
12106 md5_finish_ctx (&ctx, checksum_before_op1);
12107 htab_empty (ht);
12108 #endif
12109
12110 tem = fold_binary (code, type, op0, op1);
12111 if (!tem)
12112 tem = build2_stat (code, type, op0, op1 PASS_MEM_STAT);
12113
12114 #ifdef ENABLE_FOLD_CHECKING
12115 md5_init_ctx (&ctx);
12116 fold_checksum_tree (op0, &ctx, ht);
12117 md5_finish_ctx (&ctx, checksum_after_op0);
12118 htab_empty (ht);
12119
12120 if (memcmp (checksum_before_op0, checksum_after_op0, 16))
12121 fold_check_failed (op0, tem);
12122
12123 md5_init_ctx (&ctx);
12124 fold_checksum_tree (op1, &ctx, ht);
12125 md5_finish_ctx (&ctx, checksum_after_op1);
12126 htab_delete (ht);
12127
12128 if (memcmp (checksum_before_op1, checksum_after_op1, 16))
12129 fold_check_failed (op1, tem);
12130 #endif
12131 return tem;
12132 }
12133
12134
12135
12136
12137
12138
12139 tree
12140 fold_build3_stat (enum tree_code code, tree type, tree op0, tree op1, tree op2
12141 MEM_STAT_DECL)
12142 {
12143 tree tem;
12144 #ifdef ENABLE_FOLD_CHECKING
12145 unsigned char checksum_before_op0[16],
12146 checksum_before_op1[16],
12147 checksum_before_op2[16],
12148 checksum_after_op0[16],
12149 checksum_after_op1[16],
12150 checksum_after_op2[16];
12151 struct md5_ctx ctx;
12152 htab_t ht;
12153
12154 ht = htab_create (32, htab_hash_pointer, htab_eq_pointer, NULL);
12155 md5_init_ctx (&ctx);
12156 fold_checksum_tree (op0, &ctx, ht);
12157 md5_finish_ctx (&ctx, checksum_before_op0);
12158 htab_empty (ht);
12159
12160 md5_init_ctx (&ctx);
12161 fold_checksum_tree (op1, &ctx, ht);
12162 md5_finish_ctx (&ctx, checksum_before_op1);
12163 htab_empty (ht);
12164
12165 md5_init_ctx (&ctx);
12166 fold_checksum_tree (op2, &ctx, ht);
12167 md5_finish_ctx (&ctx, checksum_before_op2);
12168 htab_empty (ht);
12169 #endif
12170
12171 tem = fold_ternary (code, type, op0, op1, op2);
12172 if (!tem)
12173 tem = build3_stat (code, type, op0, op1, op2 PASS_MEM_STAT);
12174
12175 #ifdef ENABLE_FOLD_CHECKING
12176 md5_init_ctx (&ctx);
12177 fold_checksum_tree (op0, &ctx, ht);
12178 md5_finish_ctx (&ctx, checksum_after_op0);
12179 htab_empty (ht);
12180
12181 if (memcmp (checksum_before_op0, checksum_after_op0, 16))
12182 fold_check_failed (op0, tem);
12183
12184 md5_init_ctx (&ctx);
12185 fold_checksum_tree (op1, &ctx, ht);
12186 md5_finish_ctx (&ctx, checksum_after_op1);
12187 htab_empty (ht);
12188
12189 if (memcmp (checksum_before_op1, checksum_after_op1, 16))
12190 fold_check_failed (op1, tem);
12191
12192 md5_init_ctx (&ctx);
12193 fold_checksum_tree (op2, &ctx, ht);
12194 md5_finish_ctx (&ctx, checksum_after_op2);
12195 htab_delete (ht);
12196
12197 if (memcmp (checksum_before_op2, checksum_after_op2, 16))
12198 fold_check_failed (op2, tem);
12199 #endif
12200 return tem;
12201 }
12202
12203
12204
12205
12206
12207 #define START_FOLD_INIT \
12208 int saved_signaling_nans = flag_signaling_nans;\
12209 int saved_trapping_math = flag_trapping_math;\
12210 int saved_rounding_math = flag_rounding_math;\
12211 int saved_trapv = flag_trapv;\
12212 int saved_folding_initializer = folding_initializer;\
12213 flag_signaling_nans = 0;\
12214 flag_trapping_math = 0;\
12215 flag_rounding_math = 0;\
12216 flag_trapv = 0;\
12217 folding_initializer = 1;
12218
12219 #define END_FOLD_INIT \
12220 flag_signaling_nans = saved_signaling_nans;\
12221 flag_trapping_math = saved_trapping_math;\
12222 flag_rounding_math = saved_rounding_math;\
12223 flag_trapv = saved_trapv;\
12224 folding_initializer = saved_folding_initializer;
12225
12226 tree
12227 fold_build1_initializer (enum tree_code code, tree type, tree op)
12228 {
12229 tree result;
12230 START_FOLD_INIT;
12231
12232 result = fold_build1 (code, type, op);
12233
12234 END_FOLD_INIT;
12235 return result;
12236 }
12237
12238 tree
12239 fold_build2_initializer (enum tree_code code, tree type, tree op0, tree op1)
12240 {
12241 tree result;
12242 START_FOLD_INIT;
12243
12244 result = fold_build2 (code, type, op0, op1);
12245
12246 END_FOLD_INIT;
12247 return result;
12248 }
12249
12250 tree
12251 fold_build3_initializer (enum tree_code code, tree type, tree op0, tree op1,
12252 tree op2)
12253 {
12254 tree result;
12255 START_FOLD_INIT;
12256
12257 result = fold_build3 (code, type, op0, op1, op2);
12258
12259 END_FOLD_INIT;
12260 return result;
12261 }
12262
12263 #undef START_FOLD_INIT
12264 #undef END_FOLD_INIT
12265
12266
12267
12268
12269
12270
12271
12272
12273
12274
12275
12276
12277
12278
12279
12280
12281
12282
12283
12284
12285
12286
12287
12288
12289
12290
12291
12292
12293
12294
12295
12296
12297
12298
12299
12300
12301
12302
12303
12304
12305
12306 static int
12307 multiple_of_p (tree type, tree top, tree bottom)
12308 {
12309 if (operand_equal_p (top, bottom, 0))
12310 return 1;
12311
12312 if (TREE_CODE (type) != INTEGER_TYPE)
12313 return 0;
12314
12315 switch (TREE_CODE (top))
12316 {
12317 case BIT_AND_EXPR:
12318
12319
12320 if (!integer_pow2p (bottom))
12321 return 0;
12322
12323
12324 case MULT_EXPR:
12325 return (multiple_of_p (type, TREE_OPERAND (top, 0), bottom)
12326 || multiple_of_p (type, TREE_OPERAND (top, 1), bottom));
12327
12328 case PLUS_EXPR:
12329 case MINUS_EXPR:
12330 return (multiple_of_p (type, TREE_OPERAND (top, 0), bottom)
12331 && multiple_of_p (type, TREE_OPERAND (top, 1), bottom));
12332
12333 case LSHIFT_EXPR:
12334 if (TREE_CODE (TREE_OPERAND (top, 1)) == INTEGER_CST)
12335 {
12336 tree op1, t1;
12337
12338 op1 = TREE_OPERAND (top, 1);
12339
12340
12341 if (TYPE_PRECISION (TREE_TYPE (size_one_node))
12342 > TREE_INT_CST_LOW (op1)
12343 && TREE_INT_CST_HIGH (op1) == 0
12344 && 0 != (t1 = fold_convert (type,
12345 const_binop (LSHIFT_EXPR,
12346 size_one_node,
12347 op1, 0)))
12348 && ! TREE_OVERFLOW (t1))
12349 return multiple_of_p (type, t1, bottom);
12350 }
12351 return 0;
12352
12353 case NOP_EXPR:
12354
12355 if ((TREE_CODE (TREE_TYPE (TREE_OPERAND (top, 0))) != INTEGER_TYPE)
12356 || (TYPE_PRECISION (type)
12357 < TYPE_PRECISION (TREE_TYPE (TREE_OPERAND (top, 0)))))
12358 return 0;
12359
12360
12361
12362 case SAVE_EXPR:
12363 return multiple_of_p (type, TREE_OPERAND (top, 0), bottom);
12364
12365 case INTEGER_CST:
12366 if (TREE_CODE (bottom) != INTEGER_CST
12367 || (TYPE_UNSIGNED (type)
12368 && (tree_int_cst_sgn (top) < 0
12369 || tree_int_cst_sgn (bottom) < 0)))
12370 return 0;
12371 return integer_zerop (const_binop (TRUNC_MOD_EXPR,
12372 top, bottom, 0));
12373
12374 default:
12375 return 0;
12376 }
12377 }
12378
12379
12380
12381
12382
12383
12384 int
12385 tree_expr_nonnegative_warnv_p (tree t, bool *strict_overflow_p)
12386 {
12387 if (t == error_mark_node)
12388 return 0;
12389
12390 if (TYPE_UNSIGNED (TREE_TYPE (t)))
12391 return 1;
12392
12393 switch (TREE_CODE (t))
12394 {
12395 case SSA_NAME:
12396
12397
12398 return ssa_name_nonnegative_p (t);
12399
12400 case ABS_EXPR:
12401
12402
12403 if (!INTEGRAL_TYPE_P (TREE_TYPE (t)))
12404 return 1;
12405 if (TYPE_OVERFLOW_UNDEFINED (TREE_TYPE (t)))
12406 {
12407 *strict_overflow_p = true;
12408 return 1;
12409 }
12410 break;
12411
12412 case INTEGER_CST:
12413 return tree_int_cst_sgn (t) >= 0;
12414
12415 case REAL_CST:
12416 return ! REAL_VALUE_NEGATIVE (TREE_REAL_CST (t));
12417
12418 case PLUS_EXPR:
12419 if (FLOAT_TYPE_P (TREE_TYPE (t)))
12420 return (tree_expr_nonnegative_warnv_p (TREE_OPERAND (t, 0),
12421 strict_overflow_p)
12422 && tree_expr_nonnegative_warnv_p (TREE_OPERAND (t, 1),
12423 strict_overflow_p));
12424
12425
12426
12427 if (TREE_CODE (TREE_TYPE (t)) == INTEGER_TYPE
12428 && TREE_CODE (TREE_OPERAND (t, 0)) == NOP_EXPR
12429 && TREE_CODE (TREE_OPERAND (t, 1)) == NOP_EXPR)
12430 {
12431 tree inner1 = TREE_TYPE (TREE_OPERAND (TREE_OPERAND (t, 0), 0));
12432 tree inner2 = TREE_TYPE (TREE_OPERAND (TREE_OPERAND (t, 1), 0));
12433 if (TREE_CODE (inner1) == INTEGER_TYPE && TYPE_UNSIGNED (inner1)
12434 && TREE_CODE (inner2) == INTEGER_TYPE && TYPE_UNSIGNED (inner2))
12435 {
12436 unsigned int prec = MAX (TYPE_PRECISION (inner1),
12437 TYPE_PRECISION (inner2)) + 1;
12438 return prec < TYPE_PRECISION (TREE_TYPE (t));
12439 }
12440 }
12441 break;
12442
12443 case MULT_EXPR:
12444 if (FLOAT_TYPE_P (TREE_TYPE (t)))
12445 {
12446
12447 if (operand_equal_p (TREE_OPERAND (t, 0), TREE_OPERAND (t, 1), 0))
12448 return 1;
12449 return (tree_expr_nonnegative_warnv_p (TREE_OPERAND (t, 0),
12450 strict_overflow_p)
12451 && tree_expr_nonnegative_warnv_p (TREE_OPERAND (t, 1),
12452 strict_overflow_p));
12453 }
12454
12455
12456
12457 if (TREE_CODE (TREE_TYPE (t)) == INTEGER_TYPE
12458 && TREE_CODE (TREE_OPERAND (t, 0)) == NOP_EXPR
12459 && TREE_CODE (TREE_OPERAND (t, 1)) == NOP_EXPR)
12460 {
12461 tree inner1 = TREE_TYPE (TREE_OPERAND (TREE_OPERAND (t, 0), 0));
12462 tree inner2 = TREE_TYPE (TREE_OPERAND (TREE_OPERAND (t, 1), 0));
12463 if (TREE_CODE (inner1) == INTEGER_TYPE && TYPE_UNSIGNED (inner1)
12464 && TREE_CODE (inner2) == INTEGER_TYPE && TYPE_UNSIGNED (inner2))
12465 return TYPE_PRECISION (inner1) + TYPE_PRECISION (inner2)
12466 < TYPE_PRECISION (TREE_TYPE (t));
12467 }
12468 return 0;
12469
12470 case BIT_AND_EXPR:
12471 case MAX_EXPR:
12472 return (tree_expr_nonnegative_warnv_p (TREE_OPERAND (t, 0),
12473 strict_overflow_p)
12474 || tree_expr_nonnegative_warnv_p (TREE_OPERAND (t, 1),
12475 strict_overflow_p));
12476
12477 case BIT_IOR_EXPR:
12478 case BIT_XOR_EXPR:
12479 case MIN_EXPR:
12480 case RDIV_EXPR:
12481 case TRUNC_DIV_EXPR:
12482 case CEIL_DIV_EXPR:
12483 case FLOOR_DIV_EXPR:
12484 case ROUND_DIV_EXPR:
12485 return (tree_expr_nonnegative_warnv_p (TREE_OPERAND (t, 0),
12486 strict_overflow_p)
12487 && tree_expr_nonnegative_warnv_p (TREE_OPERAND (t, 1),
12488 strict_overflow_p));
12489
12490 case TRUNC_MOD_EXPR:
12491 case CEIL_MOD_EXPR:
12492 case FLOOR_MOD_EXPR:
12493 case ROUND_MOD_EXPR:
12494 case SAVE_EXPR:
12495 case NON_LVALUE_EXPR:
12496 case FLOAT_EXPR:
12497 case FIX_TRUNC_EXPR:
12498 return tree_expr_nonnegative_warnv_p (TREE_OPERAND (t, 0),
12499 strict_overflow_p);
12500
12501 case COMPOUND_EXPR:
12502 case MODIFY_EXPR:
12503 return tree_expr_nonnegative_warnv_p (TREE_OPERAND (t, 1),
12504 strict_overflow_p);
12505
12506 case BIND_EXPR:
12507 return tree_expr_nonnegative_warnv_p (expr_last (TREE_OPERAND (t, 1)),
12508 strict_overflow_p);
12509
12510 case COND_EXPR:
12511 return (tree_expr_nonnegative_warnv_p (TREE_OPERAND (t, 1),
12512 strict_overflow_p)
12513 && tree_expr_nonnegative_warnv_p (TREE_OPERAND (t, 2),
12514 strict_overflow_p));
12515
12516 case NOP_EXPR:
12517 {
12518 tree inner_type = TREE_TYPE (TREE_OPERAND (t, 0));
12519 tree outer_type = TREE_TYPE (t);
12520
12521 if (TREE_CODE (outer_type) == REAL_TYPE)
12522 {
12523 if (TREE_CODE (inner_type) == REAL_TYPE)
12524 return tree_expr_nonnegative_warnv_p (TREE_OPERAND (t, 0),
12525 strict_overflow_p);
12526 if (TREE_CODE (inner_type) == INTEGER_TYPE)
12527 {
12528 if (TYPE_UNSIGNED (inner_type))
12529 return 1;
12530 return tree_expr_nonnegative_warnv_p (TREE_OPERAND (t, 0),
12531 strict_overflow_p);
12532 }
12533 }
12534 else if (TREE_CODE (outer_type) == INTEGER_TYPE)
12535 {
12536 if (TREE_CODE (inner_type) == REAL_TYPE)
12537 return tree_expr_nonnegative_warnv_p (TREE_OPERAND (t,0),
12538 strict_overflow_p);
12539 if (TREE_CODE (inner_type) == INTEGER_TYPE)
12540 return TYPE_PRECISION (inner_type) < TYPE_PRECISION (outer_type)
12541 && TYPE_UNSIGNED (inner_type);
12542 }
12543 }
12544 break;
12545
12546 case TARGET_EXPR:
12547 {
12548 tree temp = TARGET_EXPR_SLOT (t);
12549 t = TARGET_EXPR_INITIAL (t);
12550
12551
12552
12553 if (!VOID_TYPE_P (t))
12554 return tree_expr_nonnegative_warnv_p (t, strict_overflow_p);
12555
12556
12557
12558 while (1)
12559 {
12560 if (TREE_CODE (t) == BIND_EXPR)
12561 t = expr_last (BIND_EXPR_BODY (t));
12562 else if (TREE_CODE (t) == TRY_FINALLY_EXPR
12563 || TREE_CODE (t) == TRY_CATCH_EXPR)
12564 t = expr_last (TREE_OPERAND (t, 0));
12565 else if (TREE_CODE (t) == STATEMENT_LIST)
12566 t = expr_last (t);
12567 else
12568 break;
12569 }
12570 if (TREE_CODE (t) == MODIFY_EXPR
12571 && TREE_OPERAND (t, 0) == temp)
12572 return tree_expr_nonnegative_warnv_p (TREE_OPERAND (t, 1),
12573 strict_overflow_p);
12574
12575 return 0;
12576 }
12577
12578 case CALL_EXPR:
12579 {
12580 tree fndecl = get_callee_fndecl (t);
12581 tree arglist = TREE_OPERAND (t, 1);
12582 if (fndecl && DECL_BUILT_IN_CLASS (fndecl) == BUILT_IN_NORMAL)
12583 switch (DECL_FUNCTION_CODE (fndecl))
12584 {
12585 CASE_FLT_FN (BUILT_IN_ACOS):
12586 CASE_FLT_FN (BUILT_IN_ACOSH):
12587 CASE_FLT_FN (BUILT_IN_CABS):
12588 CASE_FLT_FN (BUILT_IN_COSH):
12589 CASE_FLT_FN (BUILT_IN_ERFC):
12590 CASE_FLT_FN (BUILT_IN_EXP):
12591 CASE_FLT_FN (BUILT_IN_EXP10):
12592 CASE_FLT_FN (BUILT_IN_EXP2):
12593 CASE_FLT_FN (BUILT_IN_FABS):
12594 CASE_FLT_FN (BUILT_IN_FDIM):
12595 CASE_FLT_FN (BUILT_IN_HYPOT):
12596 CASE_FLT_FN (BUILT_IN_POW10):
12597 CASE_INT_FN (BUILT_IN_FFS):
12598 CASE_INT_FN (BUILT_IN_PARITY):
12599 CASE_INT_FN (BUILT_IN_POPCOUNT):
12600
12601 return 1;
12602
12603 CASE_FLT_FN (BUILT_IN_SQRT):
12604
12605 if (!HONOR_SIGNED_ZEROS (TYPE_MODE (TREE_TYPE (t))))
12606 return 1;
12607 return tree_expr_nonnegative_warnv_p (TREE_VALUE (arglist),
12608 strict_overflow_p);
12609
12610 CASE_FLT_FN (BUILT_IN_ASINH):
12611 CASE_FLT_FN (BUILT_IN_ATAN):
12612 CASE_FLT_FN (BUILT_IN_ATANH):
12613 CASE_FLT_FN (BUILT_IN_CBRT):
12614 CASE_FLT_FN (BUILT_IN_CEIL):
12615 CASE_FLT_FN (BUILT_IN_ERF):
12616 CASE_FLT_FN (BUILT_IN_EXPM1):
12617 CASE_FLT_FN (BUILT_IN_FLOOR):
12618 CASE_FLT_FN (BUILT_IN_FMOD):
12619 CASE_FLT_FN (BUILT_IN_FREXP):
12620 CASE_FLT_FN (BUILT_IN_LCEIL):
12621 CASE_FLT_FN (BUILT_IN_LDEXP):
12622 CASE_FLT_FN (BUILT_IN_LFLOOR):
12623 CASE_FLT_FN (BUILT_IN_LLCEIL):
12624 CASE_FLT_FN (BUILT_IN_LLFLOOR):
12625 CASE_FLT_FN (BUILT_IN_LLRINT):
12626 CASE_FLT_FN (BUILT_IN_LLROUND):
12627 CASE_FLT_FN (BUILT_IN_LRINT):
12628 CASE_FLT_FN (BUILT_IN_LROUND):
12629 CASE_FLT_FN (BUILT_IN_MODF):
12630 CASE_FLT_FN (BUILT_IN_NEARBYINT):
12631 CASE_FLT_FN (BUILT_IN_POW):
12632 CASE_FLT_FN (BUILT_IN_RINT):
12633 CASE_FLT_FN (BUILT_IN_ROUND):
12634 CASE_FLT_FN (BUILT_IN_SIGNBIT):
12635 CASE_FLT_FN (BUILT_IN_SINH):
12636 CASE_FLT_FN (BUILT_IN_TANH):
12637 CASE_FLT_FN (BUILT_IN_TRUNC):
12638
12639 return tree_expr_nonnegative_warnv_p (TREE_VALUE (arglist),
12640 strict_overflow_p);
12641
12642 CASE_FLT_FN (BUILT_IN_FMAX):
12643
12644 return (tree_expr_nonnegative_warnv_p (TREE_VALUE (arglist),
12645 strict_overflow_p)
12646 || (tree_expr_nonnegative_warnv_p
12647 (TREE_VALUE (TREE_CHAIN (arglist)),
12648 strict_overflow_p)));
12649
12650 CASE_FLT_FN (BUILT_IN_FMIN):
12651
12652 return (tree_expr_nonnegative_warnv_p (TREE_VALUE (arglist),
12653 strict_overflow_p)
12654 && (tree_expr_nonnegative_warnv_p
12655 (TREE_VALUE (TREE_CHAIN (arglist)),
12656 strict_overflow_p)));
12657
12658 CASE_FLT_FN (BUILT_IN_COPYSIGN):
12659
12660 return (tree_expr_nonnegative_warnv_p
12661 (TREE_VALUE (TREE_CHAIN (arglist)),
12662 strict_overflow_p));
12663
12664 default:
12665 break;
12666 }
12667 }
12668
12669
12670
12671 default:
12672 if (truth_value_p (TREE_CODE (t)))
12673
12674 return 1;
12675 }
12676
12677
12678 return 0;
12679 }
12680
12681
12682
12683
12684 int
12685 tree_expr_nonnegative_p (tree t)
12686 {
12687 int ret;
12688 bool strict_overflow_p;
12689
12690 strict_overflow_p = false;
12691 ret = tree_expr_nonnegative_warnv_p (t, &strict_overflow_p);
12692 if (strict_overflow_p)
12693 fold_overflow_warning (("assuming signed overflow does not occur when "
12694 "determining that expression is always "
12695 "non-negative"),
12696 WARN_STRICT_OVERFLOW_MISC);
12697 return ret;
12698 }
12699
12700
12701
12702
12703
12704
12705
12706
12707
12708 bool
12709 tree_expr_nonzero_warnv_p (tree t, bool *strict_overflow_p)
12710 {
12711 tree type = TREE_TYPE (t);
12712 bool sub_strict_overflow_p;
12713
12714
12715 if (!INTEGRAL_TYPE_P (type) && !POINTER_TYPE_P (type))
12716 return false;
12717
12718 switch (TREE_CODE (t))
12719 {
12720 case SSA_NAME:
12721
12722
12723 return ssa_name_nonzero_p (t);
12724
12725 case ABS_EXPR:
12726 return tree_expr_nonzero_warnv_p (TREE_OPERAND (t, 0),
12727 strict_overflow_p);
12728
12729 case INTEGER_CST:
12730
12731
12732 return (TREE_INT_CST_LOW (t) != 0
12733 || TREE_INT_CST_HIGH (t) != 0);
12734
12735 case PLUS_EXPR:
12736 if (TYPE_OVERFLOW_UNDEFINED (type))
12737 {
12738
12739
12740 sub_strict_overflow_p = false;
12741 if (!tree_expr_nonnegative_warnv_p (TREE_OPERAND (t, 0),
12742 &sub_strict_overflow_p)
12743 || !tree_expr_nonnegative_warnv_p (TREE_OPERAND (t, 1),
12744 &sub_strict_overflow_p))
12745 return false;
12746
12747
12748
12749
12750 return (tree_expr_nonzero_warnv_p (TREE_OPERAND (t, 0),
12751 strict_overflow_p)
12752 || tree_expr_nonzero_warnv_p (TREE_OPERAND (t, 1),
12753 strict_overflow_p));
12754 }
12755 break;
12756
12757 case MULT_EXPR:
12758 if (TYPE_OVERFLOW_UNDEFINED (type))
12759 {
12760 if (tree_expr_nonzero_warnv_p (TREE_OPERAND (t, 0),
12761 strict_overflow_p)
12762 && tree_expr_nonzero_warnv_p (TREE_OPERAND (t, 1),
12763 strict_overflow_p))
12764 {
12765 *strict_overflow_p = true;
12766 return true;
12767 }
12768 }
12769 break;
12770
12771 case NOP_EXPR:
12772 {
12773 tree inner_type = TREE_TYPE (TREE_OPERAND (t, 0));
12774 tree outer_type = TREE_TYPE (t);
12775
12776 return (TYPE_PRECISION (outer_type) >= TYPE_PRECISION (inner_type)
12777 && tree_expr_nonzero_warnv_p (TREE_OPERAND (t, 0),
12778 strict_overflow_p));
12779 }
12780 break;
12781
12782 case ADDR_EXPR:
12783 {
12784 tree base = get_base_address (TREE_OPERAND (t, 0));
12785
12786 if (!base)
12787 return false;
12788
12789
12790 if (VAR_OR_FUNCTION_DECL_P (base))
12791 return !DECL_WEAK (base);
12792
12793
12794 if (CONSTANT_CLASS_P (base))
12795 return true;
12796
12797 return false;
12798 }
12799
12800 case COND_EXPR:
12801 sub_strict_overflow_p = false;
12802 if (tree_expr_nonzero_warnv_p (TREE_OPERAND (t, 1),
12803 &sub_strict_overflow_p)
12804 && tree_expr_nonzero_warnv_p (TREE_OPERAND (t, 2),
12805 &sub_strict_overflow_p))
12806 {
12807 if (sub_strict_overflow_p)
12808 *strict_overflow_p = true;
12809 return true;
12810 }
12811 break;
12812
12813 case MIN_EXPR:
12814 sub_strict_overflow_p = false;
12815 if (tree_expr_nonzero_warnv_p (TREE_OPERAND (t, 0),
12816 &sub_strict_overflow_p)
12817 && tree_expr_nonzero_warnv_p (TREE_OPERAND (t, 1),
12818 &sub_strict_overflow_p))
12819 {
12820 if (sub_strict_overflow_p)
12821 *strict_overflow_p = true;
12822 }
12823 break;
12824
12825 case MAX_EXPR:
12826 sub_strict_overflow_p = false;
12827 if (tree_expr_nonzero_warnv_p (TREE_OPERAND (t, 0),
12828 &sub_strict_overflow_p))
12829 {
12830 if (sub_strict_overflow_p)
12831 *strict_overflow_p = true;
12832
12833
12834 if (tree_expr_nonzero_warnv_p (TREE_OPERAND (t, 1),
12835 strict_overflow_p))
12836 return true;
12837
12838
12839 return tree_expr_nonnegative_warnv_p (TREE_OPERAND (t, 0),
12840 strict_overflow_p);
12841 }
12842
12843 else if (tree_expr_nonzero_warnv_p (TREE_OPERAND (t, 1),
12844 &sub_strict_overflow_p)
12845 && tree_expr_nonnegative_warnv_p (TREE_OPERAND (t, 1),
12846 &sub_strict_overflow_p))
12847 {
12848 if (sub_strict_overflow_p)
12849 *strict_overflow_p = true;
12850 return true;
12851 }
12852 break;
12853
12854 case COMPOUND_EXPR:
12855 case MODIFY_EXPR:
12856 case BIND_EXPR:
12857 return tree_expr_nonzero_warnv_p (TREE_OPERAND (t, 1),
12858 strict_overflow_p);
12859
12860 case SAVE_EXPR:
12861 case NON_LVALUE_EXPR:
12862 return tree_expr_nonzero_warnv_p (TREE_OPERAND (t, 0),
12863 strict_overflow_p);
12864
12865 case BIT_IOR_EXPR:
12866 return (tree_expr_nonzero_warnv_p (TREE_OPERAND (t, 1),
12867 strict_overflow_p)
12868 || tree_expr_nonzero_warnv_p (TREE_OPERAND (t, 0),
12869 strict_overflow_p));
12870
12871 case CALL_EXPR:
12872 return alloca_call_p (t);
12873
12874 default:
12875 break;
12876 }
12877 return false;
12878 }
12879
12880
12881
12882
12883 bool
12884 tree_expr_nonzero_p (tree t)
12885 {
12886 bool ret, strict_overflow_p;
12887
12888 strict_overflow_p = false;
12889 ret = tree_expr_nonzero_warnv_p (t, &strict_overflow_p);
12890 if (strict_overflow_p)
12891 fold_overflow_warning (("assuming signed overflow does not occur when "
12892 "determining that expression is always "
12893 "non-zero"),
12894 WARN_STRICT_OVERFLOW_MISC);
12895 return ret;
12896 }
12897
12898
12899
12900
12901
12902
12903
12904
12905
12906 tree
12907 fold_binary_to_constant (enum tree_code code, tree type, tree op0, tree op1)
12908 {
12909 tree tem = fold_binary (code, type, op0, op1);
12910 return (tem && TREE_CONSTANT (tem)) ? tem : NULL_TREE;
12911 }
12912
12913
12914
12915
12916
12917
12918
12919
12920
12921 tree
12922 fold_unary_to_constant (enum tree_code code, tree type, tree op0)
12923 {
12924 tree tem = fold_unary (code, type, op0);
12925 return (tem && TREE_CONSTANT (tem)) ? tem : NULL_TREE;
12926 }
12927
12928
12929
12930
12931
12932 tree
12933 fold_read_from_constant_string (tree exp)
12934 {
12935 if ((TREE_CODE (exp) == INDIRECT_REF
12936 || TREE_CODE (exp) == ARRAY_REF)
12937 && TREE_CODE (TREE_TYPE (exp)) == INTEGER_TYPE)
12938 {
12939 tree exp1 = TREE_OPERAND (exp, 0);
12940 tree index;
12941 tree string;
12942
12943 if (TREE_CODE (exp) == INDIRECT_REF)
12944 string = string_constant (exp1, &index);
12945 else
12946 {
12947 tree low_bound = array_ref_low_bound (exp);
12948 index = fold_convert (sizetype, TREE_OPERAND (exp, 1));
12949
12950
12951
12952
12953
12954
12955
12956
12957 if (! integer_zerop (low_bound))
12958 index = size_diffop (index, fold_convert (sizetype, low_bound));
12959
12960 string = exp1;
12961 }
12962
12963 if (string
12964 && TYPE_MODE (TREE_TYPE (exp)) == TYPE_MODE (TREE_TYPE (TREE_TYPE (string)))
12965 && TREE_CODE (string) == STRING_CST
12966 && TREE_CODE (index) == INTEGER_CST
12967 && compare_tree_int (index, TREE_STRING_LENGTH (string)) < 0
12968 && (GET_MODE_CLASS (TYPE_MODE (TREE_TYPE (TREE_TYPE (string))))
12969 == MODE_INT)
12970 && (GET_MODE_SIZE (TYPE_MODE (TREE_TYPE (TREE_TYPE (string)))) == 1))
12971 return fold_convert (TREE_TYPE (exp),
12972 build_int_cst (NULL_TREE,
12973 (TREE_STRING_POINTER (string)
12974 [TREE_INT_CST_LOW (index)])));
12975 }
12976 return NULL;
12977 }
12978
12979
12980
12981
12982
12983
12984 static tree
12985 fold_negate_const (tree arg0, tree type)
12986 {
12987 tree t = NULL_TREE;
12988
12989 switch (TREE_CODE (arg0))
12990 {
12991 case INTEGER_CST:
12992 {
12993 unsigned HOST_WIDE_INT low;
12994 HOST_WIDE_INT high;
12995 int overflow = neg_double (TREE_INT_CST_LOW (arg0),
12996 TREE_INT_CST_HIGH (arg0),
12997 &low, &high);
12998 t = build_int_cst_wide (type, low, high);
12999 t = force_fit_type (t, 1,
13000 (overflow | TREE_OVERFLOW (arg0))
13001 && !TYPE_UNSIGNED (type),
13002 TREE_CONSTANT_OVERFLOW (arg0));
13003 break;
13004 }
13005
13006 case REAL_CST:
13007 t = build_real (type, REAL_VALUE_NEGATE (TREE_REAL_CST (arg0)));
13008 break;
13009
13010 default:
13011 gcc_unreachable ();
13012 }
13013
13014 return t;
13015 }
13016
13017
13018
13019
13020
13021
13022 tree
13023 fold_abs_const (tree arg0, tree type)
13024 {
13025 tree t = NULL_TREE;
13026
13027 switch (TREE_CODE (arg0))
13028 {
13029 case INTEGER_CST:
13030
13031
13032 if (TYPE_UNSIGNED (type))
13033 t = arg0;
13034
13035 else if (INT_CST_LT (integer_minus_one_node, arg0))
13036 t = arg0;
13037
13038
13039 else
13040 {
13041 unsigned HOST_WIDE_INT low;
13042 HOST_WIDE_INT high;
13043 int overflow = neg_double (TREE_INT_CST_LOW (arg0),
13044 TREE_INT_CST_HIGH (arg0),
13045 &low, &high);
13046 t = build_int_cst_wide (type, low, high);
13047 t = force_fit_type (t, -1, overflow | TREE_OVERFLOW (arg0),
13048 TREE_CONSTANT_OVERFLOW (arg0));
13049 }
13050 break;
13051
13052 case REAL_CST:
13053 if (REAL_VALUE_NEGATIVE (TREE_REAL_CST (arg0)))
13054 t = build_real (type, REAL_VALUE_NEGATE (TREE_REAL_CST (arg0)));
13055 else
13056 t = arg0;
13057 break;
13058
13059 default:
13060 gcc_unreachable ();
13061 }
13062
13063 return t;
13064 }
13065
13066
13067
13068
13069 static tree
13070 fold_not_const (tree arg0, tree type)
13071 {
13072 tree t = NULL_TREE;
13073
13074 gcc_assert (TREE_CODE (arg0) == INTEGER_CST);
13075
13076 t = build_int_cst_wide (type,
13077 ~ TREE_INT_CST_LOW (arg0),
13078 ~ TREE_INT_CST_HIGH (arg0));
13079 t = force_fit_type (t, 0, TREE_OVERFLOW (arg0),
13080 TREE_CONSTANT_OVERFLOW (arg0));
13081
13082 return t;
13083 }
13084
13085
13086
13087
13088
13089
13090 static tree
13091 fold_relational_const (enum tree_code code, tree type, tree op0, tree op1)
13092 {
13093 int result, invert;
13094
13095
13096
13097
13098 if (TREE_CODE (op0) == REAL_CST && TREE_CODE (op1) == REAL_CST)
13099 {
13100 const REAL_VALUE_TYPE *c0 = TREE_REAL_CST_PTR (op0);
13101 const REAL_VALUE_TYPE *c1 = TREE_REAL_CST_PTR (op1);
13102
13103
13104 if (real_isnan (c0) || real_isnan (c1))
13105 {
13106 switch (code)
13107 {
13108 case EQ_EXPR:
13109 case ORDERED_EXPR:
13110 result = 0;
13111 break;
13112
13113 case NE_EXPR:
13114 case UNORDERED_EXPR:
13115 case UNLT_EXPR:
13116 case UNLE_EXPR:
13117 case UNGT_EXPR:
13118 case UNGE_EXPR:
13119 case UNEQ_EXPR:
13120 result = 1;
13121 break;
13122
13123 case LT_EXPR:
13124 case LE_EXPR:
13125 case GT_EXPR:
13126 case GE_EXPR:
13127 case LTGT_EXPR:
13128 if (flag_trapping_math)
13129 return NULL_TREE;
13130 result = 0;
13131 break;
13132
13133 default:
13134 gcc_unreachable ();
13135 }
13136
13137 return constant_boolean_node (result, type);
13138 }
13139
13140 return constant_boolean_node (real_compare (code, c0, c1), type);
13141 }
13142
13143
13144 if (TREE_CODE (op0) == COMPLEX_CST && TREE_CODE (op1) == COMPLEX_CST)
13145 {
13146 tree rcond = fold_relational_const (code, type,
13147 TREE_REALPART (op0),
13148 TREE_REALPART (op1));
13149 tree icond = fold_relational_const (code, type,
13150 TREE_IMAGPART (op0),
13151 TREE_IMAGPART (op1));
13152 if (code == EQ_EXPR)
13153 return fold_build2 (TRUTH_ANDIF_EXPR, type, rcond, icond);
13154 else if (code == NE_EXPR)
13155 return fold_build2 (TRUTH_ORIF_EXPR, type, rcond, icond);
13156 else
13157 return NULL_TREE;
13158 }
13159
13160
13161
13162
13163
13164
13165
13166
13167
13168
13169 if (code == LE_EXPR || code == GT_EXPR)
13170 {
13171 tree tem = op0;
13172 op0 = op1;
13173 op1 = tem;
13174 code = swap_tree_comparison (code);
13175 }
13176
13177
13178
13179
13180 invert = 0;
13181 if (code == NE_EXPR || code == GE_EXPR)
13182 {
13183 invert = 1;
13184 code = invert_tree_comparison (code, false);
13185 }
13186
13187
13188
13189 if (TREE_CODE (op0) == INTEGER_CST && TREE_CODE (op1) == INTEGER_CST)
13190 {
13191 if (code == EQ_EXPR)
13192 result = tree_int_cst_equal (op0, op1);
13193 else if (TYPE_UNSIGNED (TREE_TYPE (op0)))
13194 result = INT_CST_LT_UNSIGNED (op0, op1);
13195 else
13196 result = INT_CST_LT (op0, op1);
13197 }
13198 else
13199 return NULL_TREE;
13200
13201 if (invert)
13202 result ^= 1;
13203 return constant_boolean_node (result, type);
13204 }
13205
13206
13207
13208
13209
13210 tree
13211 fold_build_cleanup_point_expr (tree type, tree expr)
13212 {
13213
13214
13215 if (!TREE_SIDE_EFFECTS (expr))
13216 return expr;
13217
13218
13219
13220
13221
13222
13223 if (TREE_CODE (expr) == RETURN_EXPR)
13224 {
13225 tree op = TREE_OPERAND (expr, 0);
13226 if (!op || !TREE_SIDE_EFFECTS (op))
13227 return expr;
13228 op = TREE_OPERAND (op, 1);
13229 if (!TREE_SIDE_EFFECTS (op))
13230 return expr;
13231 }
13232
13233 return build1 (CLEANUP_POINT_EXPR, type, expr);
13234 }
13235
13236
13237
13238
13239 tree
13240 build_fold_addr_expr_with_type (tree t, tree ptrtype)
13241 {
13242
13243 if (TREE_CODE (t) == WITH_SIZE_EXPR)
13244 t = TREE_OPERAND (t, 0);
13245
13246
13247 if (TREE_CODE (t) == INDIRECT_REF
13248 || TREE_CODE (t) == MISALIGNED_INDIRECT_REF)
13249 {
13250 t = TREE_OPERAND (t, 0);
13251 if (TREE_TYPE (t) != ptrtype)
13252 t = build1 (NOP_EXPR, ptrtype, t);
13253 }
13254 else
13255 {
13256 tree base = t;
13257
13258 while (handled_component_p (base))
13259 base = TREE_OPERAND (base, 0);
13260 if (DECL_P (base))
13261 TREE_ADDRESSABLE (base) = 1;
13262
13263 t = build1 (ADDR_EXPR, ptrtype, t);
13264 }
13265
13266 return t;
13267 }
13268
13269 tree
13270 build_fold_addr_expr (tree t)
13271 {
13272 return build_fold_addr_expr_with_type (t, build_pointer_type (TREE_TYPE (t)));
13273 }
13274
13275
13276
13277
13278
13279 tree
13280 fold_indirect_ref_1 (tree type, tree op0)
13281 {
13282 tree sub = op0;
13283 tree subtype;
13284
13285 STRIP_NOPS (sub);
13286 subtype = TREE_TYPE (sub);
13287 if (!POINTER_TYPE_P (subtype))
13288 return NULL_TREE;
13289
13290 if (TREE_CODE (sub) == ADDR_EXPR)
13291 {
13292 tree op = TREE_OPERAND (sub, 0);
13293 tree optype = TREE_TYPE (op);
13294
13295 if (TREE_CODE (op) == CONST_DECL)
13296 return DECL_INITIAL (op);
13297
13298 if (type == optype)
13299 {
13300 tree fop = fold_read_from_constant_string (op);
13301 if (fop)
13302 return fop;
13303 else
13304 return op;
13305 }
13306
13307 else if (TREE_CODE (optype) == ARRAY_TYPE
13308 && type == TREE_TYPE (optype))
13309 {
13310 tree type_domain = TYPE_DOMAIN (optype);
13311 tree min_val = size_zero_node;
13312 if (type_domain && TYPE_MIN_VALUE (type_domain))
13313 min_val = TYPE_MIN_VALUE (type_domain);
13314 return build4 (ARRAY_REF, type, op, min_val, NULL_TREE, NULL_TREE);
13315 }
13316
13317 else if (TREE_CODE (optype) == COMPLEX_TYPE
13318 && type == TREE_TYPE (optype))
13319 return fold_build1 (REALPART_EXPR, type, op);
13320 }
13321
13322
13323 if (TREE_CODE (sub) == PLUS_EXPR
13324 && TREE_CODE (TREE_OPERAND (sub, 1)) == INTEGER_CST)
13325 {
13326 tree op00 = TREE_OPERAND (sub, 0);
13327 tree op01 = TREE_OPERAND (sub, 1);
13328 tree op00type;
13329
13330 STRIP_NOPS (op00);
13331 op00type = TREE_TYPE (op00);
13332 if (TREE_CODE (op00) == ADDR_EXPR
13333 && TREE_CODE (TREE_TYPE (op00type)) == COMPLEX_TYPE
13334 && type == TREE_TYPE (TREE_TYPE (op00type)))
13335 {
13336 tree size = TYPE_SIZE_UNIT (type);
13337 if (tree_int_cst_equal (size, op01))
13338 return fold_build1 (IMAGPART_EXPR, type, TREE_OPERAND (op00, 0));
13339 }
13340 }
13341
13342
13343 if (TREE_CODE (TREE_TYPE (subtype)) == ARRAY_TYPE
13344 && type == TREE_TYPE (TREE_TYPE (subtype)))
13345 {
13346 tree type_domain;
13347 tree min_val = size_zero_node;
13348 sub = build_fold_indirect_ref (sub);
13349 type_domain = TYPE_DOMAIN (TREE_TYPE (sub));
13350 if (type_domain && TYPE_MIN_VALUE (type_domain))
13351 min_val = TYPE_MIN_VALUE (type_domain);
13352 return build4 (ARRAY_REF, type, sub, min_val, NULL_TREE, NULL_TREE);
13353 }
13354
13355 return NULL_TREE;
13356 }
13357
13358
13359
13360
13361 tree
13362 build_fold_indirect_ref (tree t)
13363 {
13364 tree type = TREE_TYPE (TREE_TYPE (t));
13365 tree sub = fold_indirect_ref_1 (type, t);
13366
13367 if (sub)
13368 return sub;
13369 else
13370 return build1 (INDIRECT_REF, type, t);
13371 }
13372
13373
13374
13375 tree
13376 fold_indirect_ref (tree t)
13377 {
13378 tree sub = fold_indirect_ref_1 (TREE_TYPE (t), TREE_OPERAND (t, 0));
13379
13380 if (sub)
13381 return sub;
13382 else
13383 return t;
13384 }
13385
13386
13387
13388
13389
13390 tree
13391 fold_ignored_result (tree t)
13392 {
13393 if (!TREE_SIDE_EFFECTS (t))
13394 return integer_zero_node;
13395
13396 for (;;)
13397 switch (TREE_CODE_CLASS (TREE_CODE (t)))
13398 {
13399 case tcc_unary:
13400 t = TREE_OPERAND (t, 0);
13401 break;
13402
13403 case tcc_binary:
13404 case tcc_comparison:
13405 if (!TREE_SIDE_EFFECTS (TREE_OPERAND (t, 1)))
13406 t = TREE_OPERAND (t, 0);
13407 else if (!TREE_SIDE_EFFECTS (TREE_OPERAND (t, 0)))
13408 t = TREE_OPERAND (t, 1);
13409 else
13410 return t;
13411 break;
13412
13413 case tcc_expression:
13414 switch (TREE_CODE (t))
13415 {
13416 case COMPOUND_EXPR:
13417 if (TREE_SIDE_EFFECTS (TREE_OPERAND (t, 1)))
13418 return t;
13419 t = TREE_OPERAND (t, 0);
13420 break;
13421
13422 case COND_EXPR:
13423 if (TREE_SIDE_EFFECTS (TREE_OPERAND (t, 1))
13424 || TREE_SIDE_EFFECTS (TREE_OPERAND (t, 2)))
13425 return t;
13426 t = TREE_OPERAND (t, 0);
13427 break;
13428
13429 default:
13430 return t;
13431 }
13432 break;
13433
13434 default:
13435 return t;
13436 }
13437 }
13438
13439
13440
13441
13442 tree
13443 round_up (tree value, int divisor)
13444 {
13445 tree div = NULL_TREE;
13446
13447 gcc_assert (divisor > 0);
13448 if (divisor == 1)
13449 return value;
13450
13451
13452
13453
13454
13455 if (TREE_CODE (value) != INTEGER_CST)
13456 {
13457 div = build_int_cst (TREE_TYPE (value), divisor);
13458
13459 if (multiple_of_p (TREE_TYPE (value), value, div))
13460 return value;
13461 }
13462
13463
13464 if (divisor == (divisor & -divisor))
13465 {
13466 tree t;
13467
13468 t = build_int_cst (TREE_TYPE (value), divisor - 1);
13469 value = size_binop (PLUS_EXPR, value, t);
13470 t = build_int_cst (TREE_TYPE (value), -divisor);
13471 value = size_binop (BIT_AND_EXPR, value, t);
13472 }
13473 else
13474 {
13475 if (!div)
13476 div = build_int_cst (TREE_TYPE (value), divisor);
13477 value = size_binop (CEIL_DIV_EXPR, value, div);
13478 value = size_binop (MULT_EXPR, value, div);
13479 }
13480
13481 return value;
13482 }
13483
13484
13485
13486 tree
13487 round_down (tree value, int divisor)
13488 {
13489 tree div = NULL_TREE;
13490
13491 gcc_assert (divisor > 0);
13492 if (divisor == 1)
13493 return value;
13494
13495
13496
13497
13498
13499 if (TREE_CODE (value) != INTEGER_CST)
13500 {
13501 div = build_int_cst (TREE_TYPE (value), divisor);
13502
13503 if (multiple_of_p (TREE_TYPE (value), value, div))
13504 return value;
13505 }
13506
13507
13508 if (divisor == (divisor & -divisor))
13509 {
13510 tree t;
13511
13512 t = build_int_cst (TREE_TYPE (value), -divisor);
13513 value = size_binop (BIT_AND_EXPR, value, t);
13514 }
13515 else
13516 {
13517 if (!div)
13518 div = build_int_cst (TREE_TYPE (value), divisor);
13519 value = size_binop (FLOOR_DIV_EXPR, value, div);
13520 value = size_binop (MULT_EXPR, value, div);
13521 }
13522
13523 return value;
13524 }
13525
13526
13527
13528
13529
13530 static tree
13531 split_address_to_core_and_offset (tree exp,
13532 HOST_WIDE_INT *pbitpos, tree *poffset)
13533 {
13534 tree core;
13535 enum machine_mode mode;
13536 int unsignedp, volatilep;
13537 HOST_WIDE_INT bitsize;
13538
13539 if (TREE_CODE (exp) == ADDR_EXPR)
13540 {
13541 core = get_inner_reference (TREE_OPERAND (exp, 0), &bitsize, pbitpos,
13542 poffset, &mode, &unsignedp, &volatilep,
13543 false);
13544 core = build_fold_addr_expr (core);
13545 }
13546 else
13547 {
13548 core = exp;
13549 *pbitpos = 0;
13550 *poffset = NULL_TREE;
13551 }
13552
13553 return core;
13554 }
13555
13556
13557
13558
13559 bool
13560 ptr_difference_const (tree e1, tree e2, HOST_WIDE_INT *diff)
13561 {
13562 tree core1, core2;
13563 HOST_WIDE_INT bitpos1, bitpos2;
13564 tree toffset1, toffset2, tdiff, type;
13565
13566 core1 = split_address_to_core_and_offset (e1, &bitpos1, &toffset1);
13567 core2 = split_address_to_core_and_offset (e2, &bitpos2, &toffset2);
13568
13569 if (bitpos1 % BITS_PER_UNIT != 0
13570 || bitpos2 % BITS_PER_UNIT != 0
13571 || !operand_equal_p (core1, core2, 0))
13572 return false;
13573
13574 if (toffset1 && toffset2)
13575 {
13576 type = TREE_TYPE (toffset1);
13577 if (type != TREE_TYPE (toffset2))
13578 toffset2 = fold_convert (type, toffset2);
13579
13580 tdiff = fold_build2 (MINUS_EXPR, type, toffset1, toffset2);
13581 if (!cst_and_fits_in_hwi (tdiff))
13582 return false;
13583
13584 *diff = int_cst_value (tdiff);
13585 }
13586 else if (toffset1 || toffset2)
13587 {
13588
13589
13590 return false;
13591 }
13592 else
13593 *diff = 0;
13594
13595 *diff += (bitpos1 - bitpos2) / BITS_PER_UNIT;
13596 return true;
13597 }
13598
13599
13600
13601
13602
13603 tree
13604 fold_strip_sign_ops (tree exp)
13605 {
13606 tree arg0, arg1;
13607
13608 switch (TREE_CODE (exp))
13609 {
13610 case ABS_EXPR:
13611 case NEGATE_EXPR:
13612 arg0 = fold_strip_sign_ops (TREE_OPERAND (exp, 0));
13613 return arg0 ? arg0 : TREE_OPERAND (exp, 0);
13614
13615 case MULT_EXPR:
13616 case RDIV_EXPR:
13617 if (HONOR_SIGN_DEPENDENT_ROUNDING (TYPE_MODE (TREE_TYPE (exp))))
13618 return NULL_TREE;
13619 arg0 = fold_strip_sign_ops (TREE_OPERAND (exp, 0));
13620 arg1 = fold_strip_sign_ops (TREE_OPERAND (exp, 1));
13621 if (arg0 != NULL_TREE || arg1 != NULL_TREE)
13622 return fold_build2 (TREE_CODE (exp), TREE_TYPE (exp),
13623 arg0 ? arg0 : TREE_OPERAND (exp, 0),
13624 arg1 ? arg1 : TREE_OPERAND (exp, 1));
13625 break;
13626
13627 default:
13628 break;
13629 }
13630 return NULL_TREE;
13631 }
13632