LCOV - code coverage report
Current view: top level - gcc - vr-values.cc (source / functions) Coverage Total Hit
Test: gcc.info Lines: 96.8 % 969 938
Test Date: 2026-02-28 14:20:25 Functions: 100.0 % 32 32
Legend: Lines:     hit not hit

            Line data    Source code
       1              : /* Support routines for Value Range Propagation (VRP).
       2              :    Copyright (C) 2005-2026 Free Software Foundation, Inc.
       3              : 
       4              : This file is part of GCC.
       5              : 
       6              : GCC is free software; you can redistribute it and/or modify
       7              : it under the terms of the GNU General Public License as published by
       8              : the Free Software Foundation; either version 3, or (at your option)
       9              : any later version.
      10              : 
      11              : GCC is distributed in the hope that it will be useful,
      12              : but WITHOUT ANY WARRANTY; without even the implied warranty of
      13              : MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
      14              : GNU General Public License for more details.
      15              : 
      16              : You should have received a copy of the GNU General Public License
      17              : along with GCC; see the file COPYING3.  If not see
      18              : <http://www.gnu.org/licenses/>.  */
      19              : 
      20              : #include "config.h"
      21              : #include "system.h"
      22              : #include "coretypes.h"
      23              : #include "backend.h"
      24              : #include "insn-codes.h"
      25              : #include "tree.h"
      26              : #include "gimple.h"
      27              : #include "ssa.h"
      28              : #include "optabs-tree.h"
      29              : #include "gimple-pretty-print.h"
      30              : #include "diagnostic-core.h"
      31              : #include "flags.h"
      32              : #include "fold-const.h"
      33              : #include "calls.h"
      34              : #include "cfganal.h"
      35              : #include "gimple-iterator.h"
      36              : #include "gimple-fold.h"
      37              : #include "tree-cfg.h"
      38              : #include "tree-ssa-loop-niter.h"
      39              : #include "tree-ssa-loop.h"
      40              : #include "intl.h"
      41              : #include "cfgloop.h"
      42              : #include "tree-scalar-evolution.h"
      43              : #include "tree-ssa-propagate.h"
      44              : #include "tree-chrec.h"
      45              : #include "omp-general.h"
      46              : #include "case-cfn-macros.h"
      47              : #include "alloc-pool.h"
      48              : #include "attribs.h"
      49              : #include "range.h"
      50              : #include "vr-values.h"
      51              : #include "cfghooks.h"
      52              : #include "range-op.h"
      53              : #include "gimple-range.h"
      54              : 
      55              : /* Return true if op is in a boolean [0, 1] value-range.  */
      56              : 
      57              : bool
      58       462467 : simplify_using_ranges::op_with_boolean_value_range_p (tree op, gimple *s)
      59              : {
      60       462467 :   if (TYPE_PRECISION (TREE_TYPE (op)) == 1)
      61              :     return true;
      62              : 
      63       450367 :   if (integer_zerop (op)
      64       450367 :       || integer_onep (op))
      65         8548 :     return true;
      66              : 
      67       441819 :   if (TREE_CODE (op) != SSA_NAME)
      68              :     return false;
      69              : 
      70              :   /* ?? Errr, this should probably check for [0,0] and [1,1] as well
      71              :      as [0,1].  */
      72       441819 :   int_range_max vr;
      73       441819 :   return (query->range_of_expr (vr, op, s)
      74       441819 :           && vr == range_true_and_false (TREE_TYPE (op)));
      75       441819 : }
      76              : 
      77              : /* Helper function for simplify_internal_call_using_ranges and
      78              :    extract_range_basic.  Return true if OP0 SUBCODE OP1 for
      79              :    SUBCODE {PLUS,MINUS,MULT}_EXPR is known to never overflow or
      80              :    always overflow.  Set *OVF to true if it is known to always
      81              :    overflow.  */
      82              : 
      83              : static bool
      84       143406 : check_for_binary_op_overflow (range_query *query,
      85              :                               enum tree_code subcode, tree type,
      86              :                               tree op0, tree op1, bool *ovf, gimple *s = NULL)
      87              : {
      88       143406 :   relation_kind rel = VREL_VARYING;
      89              :   /* For subtraction see if relations could simplify it.  */
      90       143406 :   if (s
      91       143406 :       && subcode == MINUS_EXPR
      92       143406 :       && types_compatible_p (TREE_TYPE (op0), TREE_TYPE (op1)))
      93              :     {
      94        28915 :       rel = query->relation().query (s, op0, op1);
      95              :       /* The result of the infinite precision subtraction of
      96              :          the same values will be always 0.  That will fit into any result
      97              :          type.  */
      98        28915 :       if (rel == VREL_EQ)
      99              :         return true;
     100              :     }
     101              : 
     102       143405 :   int_range_max vr0, vr1;
     103       143405 :   if (!query->range_of_expr (vr0, op0, s) || vr0.undefined_p ())
     104           12 :     vr0.set_varying (TREE_TYPE (op0));
     105       143405 :   if (!query->range_of_expr (vr1, op1, s) || vr1.undefined_p ())
     106            0 :     vr1.set_varying (TREE_TYPE (op1));
     107              : 
     108       143405 :   tree vr0min = wide_int_to_tree (TREE_TYPE (op0), vr0.lower_bound ());
     109       143405 :   tree vr0max = wide_int_to_tree (TREE_TYPE (op0), vr0.upper_bound ());
     110       143405 :   tree vr1min = wide_int_to_tree (TREE_TYPE (op1), vr1.lower_bound ());
     111       143405 :   tree vr1max = wide_int_to_tree (TREE_TYPE (op1), vr1.upper_bound ());
     112              : 
     113              :   /* If op1 is not negative, op0 - op1 in infinite precision for op0 >= op1
     114              :      will be always in [0, op0] and so if vr0max - vr1min fits into type,
     115              :      there won't be any overflow.  */
     116       143405 :   if ((rel == VREL_GT || rel == VREL_GE)
     117           20 :       && tree_int_cst_sgn (vr1min) >= 0
     118       143422 :       && !arith_overflowed_p (MINUS_EXPR, type, vr0max, vr1min))
     119              :     return true;
     120              : 
     121              :   /* If op1 is not negative, op0 - op1 in infinite precision for op0 < op1
     122              :      will be always in [-inf, -1] and so will always overflow if type is
     123              :      unsigned.  */
     124       143388 :   if (rel == VREL_LT
     125            1 :       && tree_int_cst_sgn (vr1min) >= 0
     126       143389 :       && TYPE_UNSIGNED (type))
     127              :     {
     128            1 :       *ovf = true;
     129            1 :       return true;
     130              :     }
     131              : 
     132       235063 :   *ovf = arith_overflowed_p (subcode, type, vr0min,
     133              :                              subcode == MINUS_EXPR ? vr1max : vr1min);
     134       235063 :   if (arith_overflowed_p (subcode, type, vr0max,
     135       143387 :                           subcode == MINUS_EXPR ? vr1min : vr1max) != *ovf)
     136              :     return false;
     137        39156 :   if (subcode == MULT_EXPR)
     138              :     {
     139        23688 :       if (arith_overflowed_p (subcode, type, vr0min, vr1max) != *ovf
     140        23688 :           || arith_overflowed_p (subcode, type, vr0max, vr1min) != *ovf)
     141          376 :         return false;
     142              :     }
     143        38780 :   if (*ovf)
     144              :     {
     145              :       /* So far we found that there is an overflow on the boundaries.
     146              :          That doesn't prove that there is an overflow even for all values
     147              :          in between the boundaries.  For that compute widest2_int range
     148              :          of the result and see if it doesn't overlap the range of
     149              :          type.  */
     150        36786 :       widest2_int wmin, wmax;
     151       331112 :       widest2_int w[4];
     152        36786 :       int i;
     153        36786 :       signop sign0 = TYPE_SIGN (TREE_TYPE (op0));
     154        36786 :       signop sign1 = TYPE_SIGN (TREE_TYPE (op1));
     155        36800 :       w[0] = widest2_int::from (vr0.lower_bound (), sign0);
     156        36800 :       w[1] = widest2_int::from (vr0.upper_bound (), sign0);
     157        36791 :       w[2] = widest2_int::from (vr1.lower_bound (), sign1);
     158        36791 :       w[3] = widest2_int::from (vr1.upper_bound (), sign1);
     159       183930 :       for (i = 0; i < 4; i++)
     160              :         {
     161       147144 :           widest2_int wt;
     162       147144 :           switch (subcode)
     163              :             {
     164        26864 :             case PLUS_EXPR:
     165        26864 :               wt = wi::add (w[i & 1], w[2 + (i & 2) / 2]);
     166        26864 :               break;
     167        27680 :             case MINUS_EXPR:
     168        27680 :               wt = wi::sub (w[i & 1], w[2 + (i & 2) / 2]);
     169        27680 :               break;
     170        92600 :             case MULT_EXPR:
     171        92600 :               wt = wi::mul (w[i & 1], w[2 + (i & 2) / 2]);
     172        92600 :               break;
     173            0 :             default:
     174            0 :               gcc_unreachable ();
     175              :             }
     176       147144 :           if (i == 0)
     177              :             {
     178        36786 :               wmin = wt;
     179        36786 :               wmax = wt;
     180              :             }
     181              :           else
     182              :             {
     183       110358 :               wmin = wi::smin (wmin, wt);
     184       111014 :               wmax = wi::smax (wmax, wt);
     185              :             }
     186       147144 :         }
     187              :       /* The result of op0 CODE op1 is known to be in range
     188              :          [wmin, wmax].  */
     189        36786 :       widest2_int wtmin
     190        73572 :         = widest2_int::from (irange_val_min (type), TYPE_SIGN (type));
     191        36786 :       widest2_int wtmax
     192        73572 :         = widest2_int::from (irange_val_max (type), TYPE_SIGN (type));
     193              :       /* If all values in [wmin, wmax] are smaller than
     194              :          [wtmin, wtmax] or all are larger than [wtmin, wtmax],
     195              :          the arithmetic operation will always overflow.  */
     196        72562 :       if (wmax < wtmin || wmin > wtmax)
     197         1661 :         return true;
     198              :       return false;
     199       220926 :     }
     200              :   return true;
     201       143405 : }
     202              : 
     203              : /* Set INIT, STEP, and DIRECTION to the corresponding values of NAME
     204              :    within LOOP, and return TRUE.  Otherwise return FALSE, and set R to
     205              :    the conservative range of NAME within the loop.  */
     206              : 
     207              : static bool
     208      6671419 : get_scev_info (vrange &r, tree name, gimple *stmt, class loop *l,
     209              :                tree &init, tree &step, enum ev_direction &dir)
     210              : {
     211      6671419 :   tree ev = analyze_scalar_evolution (l, name);
     212      6671419 :   tree chrec = instantiate_parameters (l, ev);
     213      6671419 :   tree type = TREE_TYPE (name);
     214      6671419 :   if (TREE_CODE (chrec) != POLYNOMIAL_CHREC)
     215              :     {
     216      3178289 :       r.set_varying (type);
     217      3178289 :       return false;
     218              :     }
     219      3493130 :   if (is_gimple_min_invariant (chrec))
     220              :     {
     221            0 :       if (is_gimple_constant (chrec))
     222            0 :         r.set (chrec, chrec);
     223              :       else
     224            0 :         r.set_varying (type);
     225            0 :       return false;
     226              :     }
     227              : 
     228      3493130 :   init = initial_condition_in_loop_num (chrec, l->num);
     229      3493130 :   step = evolution_part_in_loop_num (chrec, l->num);
     230      3493130 :   if (!init || !step)
     231              :     {
     232            0 :       r.set_varying (type);
     233            0 :       return false;
     234              :     }
     235      3493130 :   dir = scev_direction (chrec);
     236      3493130 :   if (dir == EV_DIR_UNKNOWN
     237      3493130 :       || scev_probably_wraps_p (NULL, init, step, stmt,
     238              :                                 get_chrec_loop (chrec), true))
     239              :     {
     240       788557 :       r.set_varying (type);
     241       788557 :       return false;
     242              :     }
     243              :   return true;
     244              : }
     245              : 
     246              : /* Return TRUE if STEP * NIT may overflow when calculated in TYPE.  */
     247              : 
     248              : static bool
     249      2265471 : induction_variable_may_overflow_p (tree type,
     250              :                                    const wide_int &step, const widest_int &nit)
     251              : {
     252      2265471 :   wi::overflow_type ovf;
     253      2265471 :   signop sign = TYPE_SIGN (type);
     254      2265471 :   widest_int max_step = wi::mul (widest_int::from (step, sign),
     255      2265471 :                                  nit, sign, &ovf);
     256              : 
     257      2265471 :   if (ovf || !wi::fits_to_tree_p (max_step, type))
     258       112987 :     return true;
     259              : 
     260              :   /* For a signed type we have to check whether the result has the
     261              :      expected signedness which is that of the step as number of
     262              :      iterations is unsigned.  */
     263      2152484 :   return (sign == SIGNED
     264      4304390 :           && wi::gts_p (max_step, 0) != wi::gts_p (step, 0));
     265      2265471 : }
     266              : 
     267              : /* Set R to the range from BEGIN to END, assuming the direction of the
     268              :    loop is DIR.  */
     269              : 
     270              : static void
     271      2702109 : range_from_loop_direction (irange &r, tree type,
     272              :                            const irange &begin, const irange &end,
     273              :                            ev_direction dir)
     274              : {
     275      2702109 :   signop sign = TYPE_SIGN (type);
     276              : 
     277      2702109 :   if (begin.undefined_p () || end.undefined_p ())
     278         2887 :     r.set_varying (type);
     279      2699222 :   else if (dir == EV_DIR_GROWS)
     280              :     {
     281      2425488 :       if (wi::ge_p (begin.lower_bound (), end.upper_bound (), sign))
     282          470 :         r.set_varying (type);
     283              :       else
     284      2425018 :         r = int_range<1> (type, begin.lower_bound (), end.upper_bound ());
     285              :     }
     286              :   else
     287              :     {
     288       273746 :       if (wi::ge_p (end.lower_bound (), begin.upper_bound (), sign))
     289          259 :         r.set_varying (type);
     290              :       else
     291       273487 :         r = int_range<1> (type, end.lower_bound (), begin.upper_bound ());
     292              :     }
     293      2702109 : }
     294              : 
     295              : /* Set V to the range of NAME in STMT within LOOP.  Return TRUE if a
     296              :    range was found.  */
     297              : 
     298              : bool
     299      6671419 : range_of_var_in_loop (vrange &v, tree name, class loop *l, gimple *stmt,
     300              :                       range_query *query)
     301              : {
     302      6671419 :   tree init, step;
     303      6671419 :   enum ev_direction dir;
     304      6671419 :   if (!get_scev_info (v, name, stmt, l, init, step, dir))
     305              :     return true;
     306              : 
     307              :   // Calculate ranges for the values from SCEV.
     308      2704573 :   irange &r = as_a <irange> (v);
     309      2704573 :   tree type = TREE_TYPE (init);
     310      2704573 :   int_range<2> rinit (type), rstep (type), max_init (type);
     311      2704573 :   if (!query->range_of_expr (rinit, init, stmt)
     312      2704573 :       || !query->range_of_expr (rstep, step, stmt))
     313            0 :     return false;
     314              : 
     315              :   // Calculate the final range of NAME if possible.
     316      2704573 :   if (rinit.singleton_p () && rstep.singleton_p ())
     317              :     {
     318      2267935 :       widest_int nit;
     319      2267935 :       if (!max_loop_iterations (l, &nit))
     320              :         return false;
     321              : 
     322      2265471 :       if (!induction_variable_may_overflow_p (type, rstep.lower_bound (), nit))
     323              :         {
     324              :           // Calculate the max bounds for init (init + niter * step).
     325      2151906 :           wide_int w = wide_int::from (nit, TYPE_PRECISION (type), TYPE_SIGN (type));
     326      2151906 :           int_range<1> niter (type, w, w);
     327      2151906 :           int_range_max max_step;
     328      2151906 :           range_op_handler mult_handler (MULT_EXPR);
     329      2151906 :           range_op_handler plus_handler (PLUS_EXPR);
     330      2151906 :           if (!mult_handler.fold_range (max_step, type, niter, rstep)
     331      2151906 :               || !plus_handler.fold_range (max_init, type, rinit, max_step))
     332            0 :             return false;
     333      2151906 :         }
     334      2267935 :     }
     335      2702109 :   range_from_loop_direction (r, type, rinit, max_init, dir);
     336      2702109 :   return true;
     337      2704573 : }
     338              : 
     339              : /* Helper function for vrp_evaluate_conditional_warnv & other
     340              :    optimizers.  */
     341              : 
     342              : tree
     343     20539620 : simplify_using_ranges::fold_cond_with_ops (enum tree_code code,
     344              :                                            tree op0, tree op1, gimple *s)
     345              : {
     346     20539620 :   value_range r0 (TREE_TYPE (op0));
     347     20539620 :   value_range r1 (TREE_TYPE (op1));
     348     20539620 :   if (!query->range_of_expr (r0, op0, s)
     349     20539620 :       || !query->range_of_expr (r1, op1, s))
     350         6102 :     return NULL_TREE;
     351              : 
     352     20533518 :   int_range<1> res;
     353     20533518 :   range_op_handler handler (code);
     354              : 
     355              :   // Find any relation between op0 and op1 and pass it to fold_range.
     356     20533518 :   relation_kind rel = VREL_VARYING;
     357     20533518 :   if (gimple_range_ssa_p (op0) && gimple_range_ssa_p (op1))
     358      4598317 :     rel = query->relation ().query (s, op0, op1);
     359              : 
     360     20533518 :   if (handler && handler.fold_range (res, boolean_type_node, r0, r1,
     361              :                                      relation_trio::op1_op2 (rel)))
     362              :     {
     363     20533518 :       if (res == range_true ())
     364         9743 :         return boolean_true_node;
     365     20523775 :       if (res == range_false ())
     366         4903 :         return boolean_false_node;
     367              :     }
     368              :   return NULL;
     369     20539620 : }
     370              : 
     371              : /* Helper function for legacy_fold_cond.  */
     372              : 
     373              : tree
     374     20924303 : simplify_using_ranges::legacy_fold_cond_overflow (gimple *stmt)
     375              : {
     376     20924303 :   tree ret;
     377     20924303 :   tree_code code = gimple_cond_code (stmt);
     378     20924303 :   tree op0 = gimple_cond_lhs (stmt);
     379     20924303 :   tree op1 = gimple_cond_rhs (stmt);
     380              : 
     381              :   /* We only deal with integral and pointer types.  */
     382     41476933 :   if (!INTEGRAL_TYPE_P (TREE_TYPE (op0))
     383     25571351 :       && !POINTER_TYPE_P (TREE_TYPE (op0)))
     384              :     return NULL_TREE;
     385              : 
     386              :   /* If OP0 CODE OP1 is an overflow comparison, if it can be expressed
     387              :      as a simple equality test, then prefer that over its current form
     388              :      for evaluation.
     389              : 
     390              :      An overflow test which collapses to an equality test can always be
     391              :      expressed as a comparison of one argument against zero.  Overflow
     392              :      occurs when the chosen argument is zero and does not occur if the
     393              :      chosen argument is not zero.  */
     394     20086105 :   tree x;
     395     20086105 :   if (overflow_comparison_p (code, op0, op1, &x))
     396              :     {
     397         1364 :       wide_int max = wi::max_value (TYPE_PRECISION (TREE_TYPE (op0)), UNSIGNED);
     398              :       /* B = A - 1; if (A < B) -> B = A - 1; if (A == 0)
     399              :          B = A - 1; if (A > B) -> B = A - 1; if (A != 0)
     400              :          B = A + 1; if (B < A) -> B = A + 1; if (B == 0)
     401              :          B = A + 1; if (B > A) -> B = A + 1; if (B != 0) */
     402         1364 :       if (integer_zerop (x))
     403              :         {
     404          208 :           op1 = x;
     405          208 :           code = (code == LT_EXPR || code == LE_EXPR) ? EQ_EXPR : NE_EXPR;
     406              :         }
     407              :       /* B = A + 1; if (A > B) -> B = A + 1; if (B == 0)
     408              :          B = A + 1; if (A < B) -> B = A + 1; if (B != 0)
     409              :          B = A - 1; if (B > A) -> B = A - 1; if (A == 0)
     410              :          B = A - 1; if (B < A) -> B = A - 1; if (A != 0) */
     411         1156 :       else if (wi::to_wide (x) == max - 1)
     412              :         {
     413          815 :           op0 = op1;
     414          815 :           op1 = wide_int_to_tree (TREE_TYPE (op0), 0);
     415          815 :           code = (code == GT_EXPR || code == GE_EXPR) ? EQ_EXPR : NE_EXPR;
     416              :         }
     417              :       else
     418              :         {
     419          341 :           int_range_max vro, vri;
     420          341 :           tree type = TREE_TYPE (op0);
     421          341 :           if (code == GT_EXPR || code == GE_EXPR)
     422              :             {
     423          119 :               vro.set (type,
     424          238 :                        wi::to_wide (TYPE_MIN_VALUE (type)),
     425          119 :                        wi::to_wide (x), VR_ANTI_RANGE);
     426          119 :               vri.set (type,
     427          238 :                        wi::to_wide (TYPE_MIN_VALUE (type)),
     428          238 :                        wi::to_wide (x));
     429              :             }
     430          222 :           else if (code == LT_EXPR || code == LE_EXPR)
     431              :             {
     432          222 :               vro.set (type,
     433          444 :                        wi::to_wide (TYPE_MIN_VALUE (type)),
     434          222 :                        wi::to_wide (x));
     435          222 :               vri.set (type,
     436          444 :                        wi::to_wide (TYPE_MIN_VALUE (type)),
     437          444 :                        wi::to_wide (x),
     438              :                        VR_ANTI_RANGE);
     439              :             }
     440              :           else
     441            0 :             gcc_unreachable ();
     442          341 :           int_range_max vr0;
     443          341 :           if (!query->range_of_expr (vr0, op0, stmt))
     444            0 :             vr0.set_varying (TREE_TYPE (op0));
     445              :           /* If vro, the range for OP0 to pass the overflow test, has
     446              :              no intersection with *vr0, OP0's known range, then the
     447              :              overflow test can't pass, so return the node for false.
     448              :              If it is the inverted range, vri, that has no
     449              :              intersection, then the overflow test must pass, so return
     450              :              the node for true.  In other cases, we could proceed with
     451              :              a simplified condition comparing OP0 and X, with LE_EXPR
     452              :              for previously LE_ or LT_EXPR and GT_EXPR otherwise, but
     453              :              the comments next to the enclosing if suggest it's not
     454              :              generally profitable to do so.  */
     455          341 :           vro.intersect (vr0);
     456          341 :           if (vro.undefined_p ())
     457            8 :             return boolean_false_node;
     458          333 :           vri.intersect (vr0);
     459          333 :           if (vri.undefined_p ())
     460            0 :             return boolean_true_node;
     461          341 :         }
     462         1364 :     }
     463              : 
     464     20086097 :   if ((ret = fold_cond_with_ops (code, op0, op1, stmt)))
     465              :     return ret;
     466              :   return NULL_TREE;
     467              : }
     468              : 
     469              : /* Visit conditional statement STMT.  If we can determine which edge
     470              :    will be taken out of STMT's basic block, record it in
     471              :    *TAKEN_EDGE_P.  Otherwise, set *TAKEN_EDGE_P to NULL.  */
     472              : 
     473              : void
     474     20924303 : simplify_using_ranges::legacy_fold_cond (gcond *stmt, edge *taken_edge_p)
     475              : {
     476     20924303 :   tree val;
     477              : 
     478     20924303 :   *taken_edge_p = NULL;
     479              : 
     480     20924303 :   if (dump_file && (dump_flags & TDF_DETAILS))
     481              :     {
     482          383 :       tree use;
     483          383 :       ssa_op_iter i;
     484              : 
     485          383 :       fprintf (dump_file, "\nVisiting conditional with predicate: ");
     486          383 :       print_gimple_stmt (dump_file, stmt, 0);
     487          383 :       fprintf (dump_file, "\nWith known ranges\n");
     488              : 
     489          856 :       FOR_EACH_SSA_TREE_OPERAND (use, stmt, i, SSA_OP_USE)
     490              :         {
     491          473 :           fprintf (dump_file, "\t");
     492          473 :           print_generic_expr (dump_file, use);
     493          473 :           fprintf (dump_file, ": ");
     494          473 :           value_range r (TREE_TYPE (use));
     495          473 :           query->range_of_expr (r, use, stmt);
     496          473 :           r.dump (dump_file);
     497          473 :         }
     498              : 
     499          383 :       fprintf (dump_file, "\n");
     500              :     }
     501              : 
     502     20924303 :   val = legacy_fold_cond_overflow (stmt);
     503     20924303 :   if (val)
     504            8 :     *taken_edge_p = find_taken_edge (gimple_bb (stmt), val);
     505              : 
     506     20924303 :   if (dump_file && (dump_flags & TDF_DETAILS))
     507              :     {
     508          383 :       fprintf (dump_file, "\nPredicate evaluates to: ");
     509          383 :       if (val == NULL_TREE)
     510          383 :         fprintf (dump_file, "DON'T KNOW\n");
     511              :       else
     512            0 :         print_generic_stmt (dump_file, val);
     513              :     }
     514     20924303 : }
     515              : 
     516              : /* Simplify boolean operations if the source is known
     517              :    to be already a boolean.  */
     518              : bool
     519       447361 : simplify_using_ranges::simplify_truth_ops_using_ranges
     520              :                                         (gimple_stmt_iterator *gsi,
     521              :                                          gimple *stmt)
     522              : {
     523       447361 :   enum tree_code rhs_code = gimple_assign_rhs_code (stmt);
     524       447361 :   tree lhs, op0, op1;
     525       447361 :   bool need_conversion;
     526              : 
     527              :   /* We handle only !=/== case here.  */
     528       447361 :   gcc_assert (rhs_code == EQ_EXPR || rhs_code == NE_EXPR);
     529              : 
     530       447361 :   op0 = gimple_assign_rhs1 (stmt);
     531       447361 :   if (!op_with_boolean_value_range_p (op0, stmt))
     532              :     return false;
     533              : 
     534        15106 :   op1 = gimple_assign_rhs2 (stmt);
     535        15106 :   if (!op_with_boolean_value_range_p (op1, stmt))
     536              :     return false;
     537              : 
     538              :   /* Reduce number of cases to handle to NE_EXPR.  As there is no
     539              :      BIT_XNOR_EXPR we cannot replace A == B with a single statement.  */
     540        14667 :   if (rhs_code == EQ_EXPR)
     541              :     {
     542         6670 :       if (TREE_CODE (op1) == INTEGER_CST)
     543         2382 :         op1 = int_const_binop (BIT_XOR_EXPR, op1,
     544         4764 :                                build_int_cst (TREE_TYPE (op1), 1));
     545              :       else
     546              :         return false;
     547              :     }
     548              : 
     549        10379 :   lhs = gimple_assign_lhs (stmt);
     550        10379 :   need_conversion
     551        10379 :     = !useless_type_conversion_p (TREE_TYPE (lhs), TREE_TYPE (op0));
     552              : 
     553              :   /* Make sure to not sign-extend a 1-bit 1 when converting the result.  */
     554        10379 :   if (need_conversion
     555         9031 :       && !TYPE_UNSIGNED (TREE_TYPE (op0))
     556         3679 :       && TYPE_PRECISION (TREE_TYPE (op0)) == 1
     557        10402 :       && TYPE_PRECISION (TREE_TYPE (lhs)) > 1)
     558              :     return false;
     559              : 
     560              :   /* For A != 0 we can substitute A itself.  */
     561        10379 :   if (integer_zerop (op1))
     562         6945 :     gimple_assign_set_rhs_with_ops (gsi,
     563              :                                     need_conversion
     564            0 :                                     ? NOP_EXPR : TREE_CODE (op0), op0);
     565              :   /* For A != B we substitute A ^ B.  Either with conversion.  */
     566         3434 :   else if (need_conversion)
     567              :     {
     568         2086 :       tree tem = make_ssa_name (TREE_TYPE (op0));
     569         2086 :       gassign *newop
     570         2086 :         = gimple_build_assign (tem, BIT_XOR_EXPR, op0, op1);
     571         2086 :       gsi_insert_before (gsi, newop, GSI_SAME_STMT);
     572         4144 :       if (INTEGRAL_TYPE_P (TREE_TYPE (tem))
     573         4144 :           && TYPE_PRECISION (TREE_TYPE (tem)) > 1)
     574              :         {
     575         3988 :           int_range<1> vr (TREE_TYPE (tem),
     576         3988 :                            wi::zero (TYPE_PRECISION (TREE_TYPE (tem))),
     577         3988 :                            wi::one (TYPE_PRECISION (TREE_TYPE (tem))));
     578         1994 :           set_range_info (tem, vr);
     579         1994 :         }
     580         2086 :       gimple_assign_set_rhs_with_ops (gsi, NOP_EXPR, tem);
     581              :     }
     582              :   /* Or without.  */
     583              :   else
     584         1348 :     gimple_assign_set_rhs_with_ops (gsi, BIT_XOR_EXPR, op0, op1);
     585        10379 :   update_stmt (gsi_stmt (*gsi));
     586        10379 :   fold_stmt (gsi, follow_single_use_edges);
     587              : 
     588        10379 :   return true;
     589              : }
     590              : 
     591              : /* Simplify a division or modulo operator to a right shift or bitwise and
     592              :    if the first operand is unsigned or is greater than zero and the second
     593              :    operand is an exact power of two.  For TRUNC_MOD_EXPR op0 % op1 with
     594              :    constant op1 (op1min = op1) or with op1 in [op1min, op1max] range,
     595              :    optimize it into just op0 if op0's range is known to be a subset of
     596              :    [-op1min + 1, op1min - 1] for signed and [0, op1min - 1] for unsigned
     597              :    modulo.  */
     598              : 
     599              : bool
     600       315950 : simplify_using_ranges::simplify_div_or_mod_using_ranges
     601              :                                         (gimple_stmt_iterator *gsi,
     602              :                                          gimple *stmt)
     603              : {
     604       315950 :   enum tree_code rhs_code = gimple_assign_rhs_code (stmt);
     605       315950 :   tree val = NULL;
     606       315950 :   tree op0 = gimple_assign_rhs1 (stmt);
     607       315950 :   tree op1 = gimple_assign_rhs2 (stmt);
     608       315950 :   tree op0min = NULL_TREE, op0max = NULL_TREE;
     609       315950 :   tree op1min = op1;
     610       315950 :   int_range_max vr;
     611              : 
     612       315950 :   if (TREE_CODE (op0) == INTEGER_CST)
     613              :     {
     614              :       op0min = op0;
     615              :       op0max = op0;
     616              :     }
     617              :   else
     618              :     {
     619       291053 :       if (!query->range_of_expr (vr, op0, stmt))
     620            0 :         vr.set_varying (TREE_TYPE (op0));
     621       291053 :       if (!vr.varying_p () && !vr.undefined_p ())
     622              :         {
     623       138977 :           tree type = vr.type ();
     624       138977 :           op0min = wide_int_to_tree (type, vr.lower_bound ());
     625       138986 :           op0max = wide_int_to_tree (type, vr.upper_bound ());
     626              :         }
     627              :     }
     628              : 
     629       315950 :   if (rhs_code == TRUNC_MOD_EXPR
     630       146646 :       && TREE_CODE (op1) == SSA_NAME)
     631              :     {
     632        90632 :       int_range_max vr1;
     633        90632 :       if (!query->range_of_expr (vr1, op1, stmt))
     634            0 :         vr1.set_varying (TREE_TYPE (op1));
     635        90632 :       if (!vr1.varying_p () && !vr1.undefined_p ())
     636        26001 :         op1min = wide_int_to_tree (vr1.type (), vr1.lower_bound ());
     637        90632 :     }
     638       146646 :   if (rhs_code == TRUNC_MOD_EXPR
     639       146646 :       && TREE_CODE (op1min) == INTEGER_CST
     640        82011 :       && tree_int_cst_sgn (op1min) == 1
     641        61209 :       && op0max
     642        35442 :       && tree_int_cst_lt (op0max, op1min))
     643              :     {
     644         1221 :       if (TYPE_UNSIGNED (TREE_TYPE (op0))
     645          541 :           || tree_int_cst_sgn (op0min) >= 0
     646         1450 :           || tree_int_cst_lt (fold_unary (NEGATE_EXPR, TREE_TYPE (op1min), op1min),
     647              :                               op0min))
     648              :         {
     649              :           /* If op0 already has the range op0 % op1 has,
     650              :              then TRUNC_MOD_EXPR won't change anything.  */
     651         1188 :           gimple_assign_set_rhs_from_tree (gsi, op0);
     652         1188 :           return true;
     653              :         }
     654              :     }
     655              : 
     656       314762 :   if (TREE_CODE (op0) != SSA_NAME)
     657              :     return false;
     658              : 
     659       289878 :   if (!integer_pow2p (op1))
     660              :     {
     661              :       /* X % -Y can be only optimized into X % Y either if
     662              :          X is not INT_MIN, or Y is not -1.  Fold it now, as after
     663              :          remove_range_assertions the range info might be not available
     664              :          anymore.  */
     665       250660 :       if (rhs_code == TRUNC_MOD_EXPR
     666       250660 :           && fold_stmt (gsi, follow_single_use_edges))
     667              :         return true;
     668       250648 :       return false;
     669              :     }
     670              : 
     671        39218 :   if (TYPE_UNSIGNED (TREE_TYPE (op0)))
     672            0 :     val = integer_one_node;
     673              :   else
     674              :     {
     675        39218 :       tree zero = build_zero_cst (TREE_TYPE (op0));
     676        39218 :       val = fold_cond_with_ops (GE_EXPR, op0, zero, stmt);
     677              :     }
     678              : 
     679        39218 :   if (val && integer_onep (val))
     680              :     {
     681         6661 :       tree t;
     682              : 
     683         6661 :       if (rhs_code == TRUNC_DIV_EXPR)
     684              :         {
     685         4288 :           t = build_int_cst (integer_type_node, tree_log2 (op1));
     686         4288 :           gimple_assign_set_rhs_code (stmt, RSHIFT_EXPR);
     687         4288 :           gimple_assign_set_rhs1 (stmt, op0);
     688         4288 :           gimple_assign_set_rhs2 (stmt, t);
     689              :         }
     690              :       else
     691              :         {
     692         2373 :           t = build_int_cst (TREE_TYPE (op1), 1);
     693         2373 :           t = int_const_binop (MINUS_EXPR, op1, t);
     694         2373 :           t = fold_convert (TREE_TYPE (op0), t);
     695              : 
     696         2373 :           gimple_assign_set_rhs_code (stmt, BIT_AND_EXPR);
     697         2373 :           gimple_assign_set_rhs1 (stmt, op0);
     698         2373 :           gimple_assign_set_rhs2 (stmt, t);
     699              :         }
     700              : 
     701         6661 :       update_stmt (stmt);
     702         6661 :       fold_stmt (gsi, follow_single_use_edges);
     703         6661 :       return true;
     704              :     }
     705              : 
     706              :   return false;
     707       315950 : }
     708              : 
     709              : /* Simplify a min or max if the ranges of the two operands are
     710              :    disjoint.   Return true if we do simplify.  */
     711              : 
     712              : bool
     713       203189 : simplify_using_ranges::simplify_min_or_max_using_ranges
     714              :                                 (gimple_stmt_iterator *gsi,
     715              :                                  gimple *stmt)
     716              : {
     717       203189 :   tree op0 = gimple_assign_rhs1 (stmt);
     718       203189 :   tree op1 = gimple_assign_rhs2 (stmt);
     719       203189 :   tree val;
     720              : 
     721       203189 :   val = fold_cond_with_ops (LE_EXPR, op0, op1, stmt);
     722       203189 :   if (!val)
     723       196639 :     val = fold_cond_with_ops (LT_EXPR, op0, op1, stmt);
     724              : 
     725       196639 :   if (val)
     726              :     {
     727              :       /* VAL == TRUE -> OP0 < or <= op1
     728              :          VAL == FALSE -> OP0 > or >= op1.  */
     729         7550 :       tree res = ((gimple_assign_rhs_code (stmt) == MAX_EXPR)
     730         7550 :                   == integer_zerop (val)) ? op0 : op1;
     731         7550 :       gimple_assign_set_rhs_from_tree (gsi, res);
     732         7550 :       return true;
     733              :     }
     734              : 
     735              :   return false;
     736              : }
     737              : 
     738              : /* If the operand to an ABS_EXPR is >= 0, then eliminate the
     739              :    ABS_EXPR.  If the operand is <= 0, then simplify the
     740              :    ABS_EXPR into a NEGATE_EXPR.  */
     741              : 
     742              : bool
     743         7366 : simplify_using_ranges::simplify_abs_using_ranges (gimple_stmt_iterator *gsi,
     744              :                                                   gimple *stmt)
     745              : {
     746         7366 :   tree op = gimple_assign_rhs1 (stmt);
     747         7366 :   tree zero = build_zero_cst (TREE_TYPE (op));
     748         7366 :   tree val = fold_cond_with_ops (LE_EXPR, op, zero, stmt);
     749              : 
     750         7366 :   if (!val)
     751              :     {
     752              :       /* The range is neither <= 0 nor > 0.  Now see if it is
     753              :          either < 0 or >= 0.  */
     754         7111 :       val = fold_cond_with_ops (LT_EXPR, op, zero, stmt);
     755              :     }
     756         7111 :   if (val)
     757              :     {
     758          434 :       gimple_assign_set_rhs1 (stmt, op);
     759          434 :       if (integer_zerop (val))
     760          261 :         gimple_assign_set_rhs_code (stmt, SSA_NAME);
     761              :       else
     762          173 :         gimple_assign_set_rhs_code (stmt, NEGATE_EXPR);
     763          434 :       update_stmt (stmt);
     764          434 :       fold_stmt (gsi, follow_single_use_edges);
     765          434 :       return true;
     766              :     }
     767              :   return false;
     768              : }
     769              : 
     770              : /* irange wrapper for wi_set_zero_nonzero_bits.
     771              : 
     772              :    Return TRUE if VR was a constant range and we were able to compute
     773              :    the bit masks.  */
     774              : 
     775              : static bool
     776      1614628 : vr_set_zero_nonzero_bits (const tree expr_type,
     777              :                           const irange *vr,
     778              :                           wide_int *may_be_nonzero,
     779              :                           wide_int *must_be_nonzero)
     780              : {
     781      1614628 :   if (vr->varying_p () || vr->undefined_p ())
     782              :     {
     783       943763 :       *may_be_nonzero = wi::minus_one (TYPE_PRECISION (expr_type));
     784       943763 :       *must_be_nonzero = wi::zero (TYPE_PRECISION (expr_type));
     785       943763 :       return false;
     786              :     }
     787       670867 :   wi_set_zero_nonzero_bits (expr_type, vr->lower_bound (), vr->upper_bound (),
     788              :                             *may_be_nonzero, *must_be_nonzero);
     789       670865 :   return true;
     790              : }
     791              : 
     792              : /* Optimize away redundant BIT_AND_EXPR and BIT_IOR_EXPR.
     793              :    If all the bits that are being cleared by & are already
     794              :    known to be zero from VR, or all the bits that are being
     795              :    set by | are already known to be one from VR, the bit
     796              :    operation is redundant.  */
     797              : 
     798              : bool
     799      1258361 : simplify_using_ranges::simplify_bit_ops_using_ranges
     800              :                                 (gimple_stmt_iterator *gsi,
     801              :                                  gimple *stmt)
     802              : {
     803      1258361 :   tree op0 = gimple_assign_rhs1 (stmt);
     804      1258361 :   tree op1 = gimple_assign_rhs2 (stmt);
     805      1258361 :   tree op = NULL_TREE;
     806      1258361 :   int_range_max vr0, vr1;
     807      1258361 :   wide_int may_be_nonzero0, may_be_nonzero1;
     808      1258361 :   wide_int must_be_nonzero0, must_be_nonzero1;
     809      1258361 :   wide_int mask;
     810              : 
     811      1258361 :   if (!query->range_of_expr (vr0, op0, stmt)
     812      1258361 :       || vr0.undefined_p ())
     813              :     return false;
     814      1257669 :   if (!query->range_of_expr (vr1, op1, stmt)
     815      1257669 :       || vr1.undefined_p ())
     816              :     return false;
     817              : 
     818      1257322 :   if (!vr_set_zero_nonzero_bits (TREE_TYPE (op0), &vr0, &may_be_nonzero0,
     819              :                                  &must_be_nonzero0))
     820              :     return false;
     821       357306 :   if (!vr_set_zero_nonzero_bits (TREE_TYPE (op1), &vr1, &may_be_nonzero1,
     822              :                                  &must_be_nonzero1))
     823              :     return false;
     824              : 
     825       313559 :   switch (gimple_assign_rhs_code (stmt))
     826              :     {
     827       224094 :     case BIT_AND_EXPR:
     828       224094 :       mask = wi::bit_and_not (may_be_nonzero0, must_be_nonzero1);
     829       224094 :       if (mask == 0)
     830              :         {
     831              :           op = op0;
     832              :           break;
     833              :         }
     834       219668 :       mask = wi::bit_and_not (may_be_nonzero1, must_be_nonzero0);
     835       219668 :       if (mask == 0)
     836              :         {
     837              :           op = op1;
     838              :           break;
     839              :         }
     840              :       break;
     841        89465 :     case BIT_IOR_EXPR:
     842        89465 :       mask = wi::bit_and_not (may_be_nonzero0, must_be_nonzero1);
     843        89465 :       if (mask == 0)
     844              :         {
     845              :           op = op1;
     846              :           break;
     847              :         }
     848        89465 :       mask = wi::bit_and_not (may_be_nonzero1, must_be_nonzero0);
     849        89465 :       if (mask == 0)
     850              :         {
     851              :           op = op0;
     852              :           break;
     853              :         }
     854              :       break;
     855            0 :     default:
     856            0 :       gcc_unreachable ();
     857              :     }
     858              : 
     859         4626 :   if (op == NULL_TREE)
     860       308933 :     return false;
     861              : 
     862         4626 :   gimple_assign_set_rhs_with_ops (gsi, TREE_CODE (op), op);
     863         4626 :   update_stmt (gsi_stmt (*gsi));
     864         4626 :   return true;
     865      1258373 : }
     866              : 
     867              : /* We are comparing trees OP0 and OP1 using COND_CODE.  OP0 has
     868              :    a known value range VR.
     869              : 
     870              :    If there is one and only one value which will satisfy the
     871              :    conditional, then return that value.  Else return NULL.
     872              : 
     873              :    If signed overflow must be undefined for the value to satisfy
     874              :    the conditional, then set *STRICT_OVERFLOW_P to true.  */
     875              : 
     876              : static tree
     877      1580328 : test_for_singularity (enum tree_code cond_code, tree op0,
     878              :                       tree op1, const irange *vr)
     879              : {
     880      1580328 :   tree min = NULL;
     881      1580328 :   tree max = NULL;
     882              : 
     883              :   /* Extract minimum/maximum values which satisfy the conditional as it was
     884              :      written.  */
     885      1580328 :   if (cond_code == LE_EXPR || cond_code == LT_EXPR)
     886              :     {
     887       690504 :       min = TYPE_MIN_VALUE (TREE_TYPE (op0));
     888              : 
     889       690504 :       max = op1;
     890       690504 :       if (cond_code == LT_EXPR)
     891              :         {
     892        90707 :           tree one = build_int_cst (TREE_TYPE (op0), 1);
     893        90707 :           max = fold_build2 (MINUS_EXPR, TREE_TYPE (op0), max, one);
     894              :           /* Signal to compare_values_warnv this expr doesn't overflow.  */
     895        90707 :           if (EXPR_P (max))
     896            0 :             suppress_warning (max, OPT_Woverflow);
     897              :         }
     898              :     }
     899       889824 :   else if (cond_code == GE_EXPR || cond_code == GT_EXPR)
     900              :     {
     901       769125 :       max = TYPE_MAX_VALUE (TREE_TYPE (op0));
     902              : 
     903       769125 :       min = op1;
     904       769125 :       if (cond_code == GT_EXPR)
     905              :         {
     906       680068 :           tree one = build_int_cst (TREE_TYPE (op0), 1);
     907       680068 :           min = fold_build2 (PLUS_EXPR, TREE_TYPE (op0), min, one);
     908              :           /* Signal to compare_values_warnv this expr doesn't overflow.  */
     909       680068 :           if (EXPR_P (min))
     910            0 :             suppress_warning (min, OPT_Woverflow);
     911              :         }
     912              :     }
     913              : 
     914              :   /* Now refine the minimum and maximum values using any
     915              :      value range information we have for op0.  */
     916      1580328 :   if (min && max)
     917              :     {
     918      1459629 :       tree type = TREE_TYPE (op0);
     919      1459629 :       tree tmin = wide_int_to_tree (type, vr->lower_bound ());
     920      1459629 :       tree tmax = wide_int_to_tree (type, vr->upper_bound ());
     921      1459629 :       if (compare_values (tmin, min) == 1)
     922       443412 :         min = tmin;
     923      1459629 :       if (compare_values (tmax, max) == -1)
     924       559839 :         max = tmax;
     925              : 
     926              :       /* If the new min/max values have converged to a single value,
     927              :          then there is only one value which can satisfy the condition,
     928              :          return that value.  */
     929      1459629 :       if (operand_equal_p (min, max, 0) && is_gimple_min_invariant (min))
     930              :         return min;
     931              :     }
     932              :   return NULL;
     933              : }
     934              : 
     935              : /* Return whether the value range *VR fits in an integer type specified
     936              :    by PRECISION and UNSIGNED_P.  */
     937              : 
     938              : bool
     939       248913 : range_fits_type_p (const irange *vr,
     940              :                    unsigned dest_precision, signop dest_sgn)
     941              : {
     942       248913 :   tree src_type;
     943       248913 :   unsigned src_precision;
     944       248913 :   widest_int tem;
     945       248913 :   signop src_sgn;
     946              : 
     947              :   /* Now we can only handle ranges with constant bounds.  */
     948       248913 :   if (vr->undefined_p () || vr->varying_p ())
     949              :     return false;
     950              : 
     951              :   /* We can only handle integral and pointer types.  */
     952       190832 :   src_type = vr->type ();
     953       190832 :   if (!INTEGRAL_TYPE_P (src_type)
     954            0 :       && !POINTER_TYPE_P (src_type))
     955              :     return false;
     956              : 
     957              :   /* An extension is fine unless VR is SIGNED and dest_sgn is UNSIGNED,
     958              :      and so is an identity transform.  */
     959       190832 :   src_precision = TYPE_PRECISION (src_type);
     960       190832 :   src_sgn = TYPE_SIGN (src_type);
     961       190832 :   if ((src_precision < dest_precision
     962         7611 :        && !(dest_sgn == UNSIGNED && src_sgn == SIGNED))
     963       184383 :       || (src_precision == dest_precision && src_sgn == dest_sgn))
     964              :     return true;
     965              : 
     966       184259 :   wide_int vrmin = vr->lower_bound ();
     967       184259 :   wide_int vrmax = vr->upper_bound ();
     968              : 
     969              :   /* For sign changes, the MSB of the wide_int has to be clear.
     970              :      An unsigned value with its MSB set cannot be represented by
     971              :      a signed wide_int, while a negative value cannot be represented
     972              :      by an unsigned wide_int.  */
     973       184259 :   if (src_sgn != dest_sgn
     974       184259 :       && (wi::lts_p (vrmin, 0) || wi::lts_p (vrmax, 0)))
     975        65642 :     return false;
     976              : 
     977              :   /* Then we can perform the conversion on both ends and compare
     978              :      the result for equality.  */
     979       118617 :   signop sign = TYPE_SIGN (vr->type ());
     980       118617 :   tem = wi::ext (widest_int::from (vrmin, sign), dest_precision, dest_sgn);
     981       118617 :   if (tem != widest_int::from (vrmin, sign))
     982              :     return false;
     983       114368 :   tem = wi::ext (widest_int::from (vrmax, sign), dest_precision, dest_sgn);
     984       114368 :   if (tem != widest_int::from (vrmax, sign))
     985              :     return false;
     986              : 
     987              :   return true;
     988       184259 : }
     989              : 
     990              : // Clear edge E of EDGE_EXECUTABLE (it is unexecutable). If it wasn't
     991              : // previously clear, propagate to successor blocks if appropriate.
     992              : 
     993              : void
     994       319712 : simplify_using_ranges::set_and_propagate_unexecutable (edge e)
     995              : {
     996              :   // If not_executable is already set, we're done.
     997              :   // This works in the absence of a flag as well.
     998       319712 :   if ((e->flags & m_not_executable_flag) == m_not_executable_flag)
     999       221701 :     return;
    1000              : 
    1001       217585 :   e->flags |= m_not_executable_flag;
    1002       217585 :   m_flag_set_edges.safe_push (e);
    1003              : 
    1004              :   // Check if the destination block needs to propagate the property.
    1005       217585 :   basic_block bb = e->dest;
    1006              : 
    1007              :   // If any incoming edge is executable, we are done.
    1008       217585 :   edge_iterator ei;
    1009       357943 :   FOR_EACH_EDGE (e, ei, bb->preds)
    1010       259932 :     if ((e->flags & m_not_executable_flag) == 0)
    1011              :       return;
    1012              : 
    1013              :   // This block is also unexecutable, propagate to all exit edges as well.
    1014       172220 :   FOR_EACH_EDGE (e, ei, bb->succs)
    1015        74209 :     set_and_propagate_unexecutable (e);
    1016              : }
    1017              : 
    1018              : /* If COND can be folded entirely as TRUE or FALSE, rewrite the
    1019              :    conditional as such, and return TRUE.  */
    1020              : 
    1021              : bool
    1022     21244594 : simplify_using_ranges::fold_cond (gcond *cond)
    1023              : {
    1024     21244594 :   int_range_max r;
    1025     21244594 :   if (query->range_of_stmt (r, cond) && r.singleton_p ())
    1026              :     {
    1027              :       // COND has already been folded if arguments are constant.
    1028       320291 :       if (TREE_CODE (gimple_cond_lhs (cond)) != SSA_NAME
    1029       320291 :           && TREE_CODE (gimple_cond_rhs (cond)) != SSA_NAME)
    1030              :         return false;
    1031       238480 :       if (dump_file)
    1032              :         {
    1033          189 :           fprintf (dump_file, "Folding predicate ");
    1034          189 :           print_gimple_expr (dump_file, cond, 0);
    1035          189 :           fprintf (dump_file, " to ");
    1036              :         }
    1037       238480 :       edge e0 = EDGE_SUCC (gimple_bb (cond), 0);
    1038       238480 :       edge e1 = EDGE_SUCC (gimple_bb (cond), 1);
    1039       238480 :       if (r.zero_p ())
    1040              :         {
    1041       146280 :           if (dump_file)
    1042          132 :             fprintf (dump_file, "0\n");
    1043       146280 :           gimple_cond_make_false (cond);
    1044       146280 :           if (e0->flags & EDGE_TRUE_VALUE)
    1045       144363 :             set_and_propagate_unexecutable (e0);
    1046              :           else
    1047         1917 :             set_and_propagate_unexecutable (e1);
    1048              :         }
    1049              :       else
    1050              :         {
    1051        92200 :           if (dump_file)
    1052           57 :             fprintf (dump_file, "1\n");
    1053        92200 :           gimple_cond_make_true (cond);
    1054        92200 :           if (e0->flags & EDGE_FALSE_VALUE)
    1055          768 :             set_and_propagate_unexecutable (e0);
    1056              :           else
    1057        91432 :             set_and_propagate_unexecutable (e1);
    1058              :         }
    1059       238480 :       update_stmt (cond);
    1060       238480 :       return true;
    1061              :     }
    1062              : 
    1063              :   // FIXME: Audit the code below and make sure it never finds anything.
    1064     20924303 :   edge taken_edge;
    1065     20924303 :   legacy_fold_cond (cond, &taken_edge);
    1066              : 
    1067     20924303 :   if (taken_edge)
    1068              :     {
    1069            8 :       if (taken_edge->flags & EDGE_TRUE_VALUE)
    1070              :         {
    1071            0 :           if (dump_file && (dump_flags & TDF_DETAILS))
    1072            0 :             fprintf (dump_file, "\nVRP Predicate evaluates to: 1\n");
    1073            0 :           gimple_cond_make_true (cond);
    1074              :         }
    1075            8 :       else if (taken_edge->flags & EDGE_FALSE_VALUE)
    1076              :         {
    1077            8 :           if (dump_file && (dump_flags & TDF_DETAILS))
    1078            0 :             fprintf (dump_file, "\nVRP Predicate evaluates to: 0\n");
    1079            8 :           gimple_cond_make_false (cond);
    1080              :         }
    1081              :       else
    1082            0 :        gcc_unreachable ();
    1083            8 :       update_stmt (cond);
    1084            8 :       return true;
    1085              :     }
    1086              :   return false;
    1087     21244594 : }
    1088              : 
    1089              : /* Simplify a conditional using a relational operator to an equality
    1090              :    test if the range information indicates only one value can satisfy
    1091              :    the original conditional.  */
    1092              : 
    1093              : bool
    1094     12210676 : simplify_using_ranges::simplify_cond_using_ranges_1 (gcond *stmt)
    1095              : {
    1096     12210676 :   tree op0 = gimple_cond_lhs (stmt);
    1097     12210676 :   tree op1 = gimple_cond_rhs (stmt);
    1098     12210676 :   enum tree_code cond_code = gimple_cond_code (stmt);
    1099              : 
    1100     12210676 :   if (fold_cond (stmt))
    1101              :     return true;
    1102              : 
    1103     12073943 :   if (simplify_compare_using_ranges_1 (cond_code, op0, op1, stmt))
    1104              :     {
    1105       352684 :       if (dump_file)
    1106              :         {
    1107           26 :           fprintf (dump_file, "Simplified relational ");
    1108           26 :           print_gimple_stmt (dump_file, stmt, 0);
    1109           26 :           fprintf (dump_file, " into ");
    1110              :         }
    1111              : 
    1112       352684 :       gimple_cond_set_code (stmt, cond_code);
    1113       352684 :       gimple_cond_set_lhs (stmt, op0);
    1114       352684 :       gimple_cond_set_rhs (stmt, op1);
    1115              : 
    1116       352684 :       update_stmt (stmt);
    1117              : 
    1118       352684 :        if (dump_file)
    1119              :         {
    1120           26 :           print_gimple_stmt (dump_file, stmt, 0);
    1121           26 :           fprintf (dump_file, "\n");
    1122              :         }
    1123       352684 :       return true;
    1124              :     }
    1125              :   return false;
    1126              : }
    1127              : 
    1128              : /* Like simplify_cond_using_ranges_1 but for assignments rather
    1129              :    than GIMPLE_COND. */
    1130              : 
    1131              : bool
    1132      1200661 : simplify_using_ranges::simplify_compare_assign_using_ranges_1
    1133              :                                         (gimple_stmt_iterator *gsi,
    1134              :                                          gimple *stmt)
    1135              : {
    1136      1200661 :   enum tree_code code = gimple_assign_rhs_code (stmt);
    1137      1200661 :   tree op0 = gimple_assign_rhs1 (stmt);
    1138      1200661 :   tree op1 = gimple_assign_rhs2 (stmt);
    1139      1200661 :   gcc_assert (TREE_CODE_CLASS (code) == tcc_comparison);
    1140      1200661 :   bool happened = false;
    1141              : 
    1142      1200661 :   if (simplify_compare_using_ranges_1 (code, op0, op1, stmt))
    1143              :     {
    1144         7109 :       if (dump_file)
    1145              :         {
    1146            3 :           fprintf (dump_file, "Simplified relational ");
    1147            3 :           print_gimple_stmt (dump_file, stmt, 0);
    1148            3 :           fprintf (dump_file, " into ");
    1149              :         }
    1150              : 
    1151         7109 :       gimple_assign_set_rhs_code (stmt, code);
    1152         7109 :       gimple_assign_set_rhs1 (stmt, op0);
    1153         7109 :       gimple_assign_set_rhs2 (stmt, op1);
    1154              : 
    1155         7109 :       update_stmt (stmt);
    1156              : 
    1157         7109 :        if (dump_file)
    1158              :         {
    1159            3 :           print_gimple_stmt (dump_file, stmt, 0);
    1160            3 :           fprintf (dump_file, "\n");
    1161              :         }
    1162              :       happened = true;
    1163              :     }
    1164              : 
    1165              :   /* Transform EQ_EXPR, NE_EXPR into BIT_XOR_EXPR or identity
    1166              :      if the RHS is zero or one, and the LHS are known to be boolean
    1167              :      values.  */
    1168      1200661 :   if ((code == EQ_EXPR || code == NE_EXPR)
    1169       646935 :       && INTEGRAL_TYPE_P (TREE_TYPE (op0))
    1170      1648022 :       && simplify_truth_ops_using_ranges (gsi, stmt))
    1171              :     happened = true;
    1172              : 
    1173      1200661 :   return happened;
    1174              : }
    1175              : 
    1176              : /* Try to simplify OP0 COND_CODE OP1 using a relational operator to an
    1177              :    equality test if the range information indicates only one value can
    1178              :    satisfy the original conditional.   */
    1179              : 
    1180              : bool
    1181     13274604 : simplify_using_ranges::simplify_compare_using_ranges_1 (tree_code &cond_code, tree &op0, tree &op1, gimple *stmt)
    1182              : {
    1183     13274604 :   bool happened = false;
    1184     13274604 :   if (cond_code != NE_EXPR
    1185     13274604 :       && cond_code != EQ_EXPR
    1186      3466781 :       && TREE_CODE (op0) == SSA_NAME
    1187      3466328 :       && INTEGRAL_TYPE_P (TREE_TYPE (op0))
    1188     16403343 :       && is_gimple_min_invariant (op1))
    1189              :     {
    1190      1875107 :       int_range_max vr;
    1191              : 
    1192      1875107 :       if (!query->range_of_expr (vr, op0, stmt))
    1193            0 :         vr.set_undefined ();
    1194              : 
    1195              :       /* If we have range information for OP0, then we might be
    1196              :          able to simplify this conditional. */
    1197      1875107 :       if (!vr.undefined_p () && !vr.varying_p ())
    1198              :         {
    1199       790164 :           tree new_tree = test_for_singularity (cond_code, op0, op1, &vr);
    1200       790164 :           if (new_tree)
    1201              :             {
    1202       120699 :               cond_code = EQ_EXPR;
    1203       120699 :               op1 = new_tree;
    1204       120699 :               happened = true;
    1205              :             }
    1206              : 
    1207              :           /* Try again after inverting the condition.  We only deal
    1208              :              with integral types here, so no need to worry about
    1209              :              issues with inverting FP comparisons.  */
    1210       790164 :           new_tree = test_for_singularity
    1211       790164 :                        (invert_tree_comparison (cond_code, false),
    1212              :                         op0, op1, &vr);
    1213       790164 :           if (new_tree)
    1214              :             {
    1215       170385 :               cond_code = NE_EXPR;
    1216       170385 :               op1 = new_tree;
    1217       170385 :               happened = true;
    1218              :             }
    1219              :         }
    1220      1875107 :     }
    1221              :   // Try to simplify casted conditions.
    1222     13274604 :   if (simplify_casted_compare (cond_code, op0, op1))
    1223        76866 :     happened = true;
    1224     13274604 :   return happened;
    1225              : }
    1226              : 
    1227              : /* Simplify OP0 code OP1 when OP1 is a constant and OP0 was a SSA_NAME
    1228              :    defined by a type conversion. Replacing OP0 with RHS of the type conversion.
    1229              :    Doing so makes the conversion dead which helps subsequent passes.  */
    1230              : 
    1231              : bool
    1232     13274604 : simplify_using_ranges::simplify_casted_compare (tree_code &, tree &op0, tree &op1)
    1233              : {
    1234              : 
    1235              :   /* If we have a comparison of an SSA_NAME (OP0) against a constant,
    1236              :      see if OP0 was set by a type conversion where the source of
    1237              :      the conversion is another SSA_NAME with a range that fits
    1238              :      into the range of OP0's type.
    1239              : 
    1240              :      If so, the conversion is redundant as the earlier SSA_NAME can be
    1241              :      used for the comparison directly if we just massage the constant in the
    1242              :      comparison.  */
    1243     13274604 :   if (TREE_CODE (op0) == SSA_NAME
    1244     13191253 :       && TREE_CODE (op1) == INTEGER_CST)
    1245              :     {
    1246      9250889 :       gimple *def_stmt = SSA_NAME_DEF_STMT (op0);
    1247      9250889 :       tree innerop;
    1248              : 
    1249      9250889 :       if (!is_gimple_assign (def_stmt))
    1250              :         return false;
    1251              : 
    1252      5692576 :       switch (gimple_assign_rhs_code (def_stmt))
    1253              :         {
    1254       466738 :         CASE_CONVERT:
    1255       466738 :           innerop = gimple_assign_rhs1 (def_stmt);
    1256       466738 :           break;
    1257        49287 :         case VIEW_CONVERT_EXPR:
    1258        49287 :           innerop = TREE_OPERAND (gimple_assign_rhs1 (def_stmt), 0);
    1259        49287 :           if (!INTEGRAL_TYPE_P (TREE_TYPE (innerop)))
    1260              :             return false;
    1261              :           break;
    1262              :         default:
    1263              :           return false;
    1264              :         }
    1265              : 
    1266       513661 :       if (TREE_CODE (innerop) == SSA_NAME
    1267       513633 :           && !POINTER_TYPE_P (TREE_TYPE (innerop))
    1268       508052 :           && !SSA_NAME_OCCURS_IN_ABNORMAL_PHI (innerop)
    1269      1021700 :           && desired_pro_or_demotion_p (TREE_TYPE (innerop), TREE_TYPE (op0)))
    1270              :         {
    1271       478174 :           int_range_max vr;
    1272              : 
    1273       478174 :           if (query->range_of_expr (vr, innerop)
    1274       478171 :               && !vr.varying_p ()
    1275       157017 :               && !vr.undefined_p ()
    1276       156897 :               && range_fits_type_p (&vr,
    1277       156897 :                                     TYPE_PRECISION (TREE_TYPE (op0)),
    1278       156897 :                                     TYPE_SIGN (TREE_TYPE (op0)))
    1279       555040 :               && int_fits_type_p (op1, TREE_TYPE (innerop)))
    1280              :             {
    1281        76866 :               tree newconst = fold_convert (TREE_TYPE (innerop), op1);
    1282        76866 :               op0 = innerop;
    1283        76866 :               op1 = newconst;
    1284        76866 :               return true;
    1285              :             }
    1286       478174 :         }
    1287              :     }
    1288              :   return false;
    1289              : }
    1290              : 
    1291              : /* Simplify a switch statement using the value range of the switch
    1292              :    argument.  */
    1293              : 
    1294              : bool
    1295        63015 : simplify_using_ranges::simplify_switch_using_ranges (gswitch *stmt)
    1296              : {
    1297        63015 :   tree op = gimple_switch_index (stmt);
    1298        63015 :   tree type = TREE_TYPE (op);
    1299        63015 :   int_range_max op_range (type);
    1300        63015 :   int_range_max default_range (type);
    1301        63015 :   auto_vec<unsigned> cases;
    1302        63015 :   cases.truncate (0);
    1303        63015 :   edge e;
    1304        63015 :   switch_update su;
    1305              : 
    1306              :   // Abort if we don't have a useful range for the switch index.
    1307        63015 :   if (!query->range_of_expr (op_range, op, stmt)
    1308        63015 :       || op_range.varying_p () || op_range.undefined_p ())
    1309              :     return false;
    1310              : 
    1311              :   // Default range starts with full known range of op.
    1312        16045 :   default_range = op_range;
    1313        16045 :   edge default_edge = gimple_switch_default_edge (cfun, stmt);
    1314              : 
    1315        16045 :   unsigned x, lim = gimple_switch_num_labels (stmt);
    1316        96600 :   for (x = 1; x < lim; x++)
    1317              :     {
    1318        81399 :       e = gimple_switch_edge (cfun, stmt, x);
    1319        81399 :       tree label = gimple_switch_label (stmt, x);
    1320              : 
    1321              :       // If this edge is the same as the default edge, do nothing else.
    1322        81399 :       if (e == default_edge)
    1323         6133 :         continue;
    1324              :       // Ada sometimes has mismatched labels and index.  Just bail.
    1325        81393 :       if (TREE_TYPE (CASE_LOW (label)) != type)
    1326          844 :         return false;
    1327              : 
    1328        80549 :       wide_int low = wi::to_wide (CASE_LOW (label));
    1329        80549 :       wide_int high;
    1330              :       // Singleton cases have no CASE_HIGH.
    1331        80549 :       tree tree_high = CASE_HIGH (label);
    1332        80549 :       if (tree_high)
    1333         3329 :         high = wi::to_wide (tree_high);
    1334              :       else
    1335        77220 :         high = low;
    1336              : 
    1337              :       // If the case range is fully contained in op_range, leave the
    1338              :       // case as it is, otherwise adjust the labels.
    1339        80549 :       int_range_max case_range (type, low, high);
    1340        80549 :       if (case_range.intersect (op_range))
    1341              :         {
    1342              :           // If none of the label is in op_range, skip this label.
    1343        50466 :           if (case_range.undefined_p ())
    1344         6127 :             continue;
    1345              : 
    1346              :           // Part of the label is in op_range, but not all of it.  CASE_RANGE
    1347              :           // contains the part that is.   Adjust the case range to
    1348              :           // the new min/max.
    1349        44339 :           if (case_range.lower_bound () != low)
    1350           10 :             CASE_LOW (label) = wide_int_to_tree (type,
    1351           20 :                                                  case_range.lower_bound ());
    1352        44339 :           if (case_range.singleton_p ())
    1353        42883 :             CASE_HIGH (label) = NULL_TREE;
    1354              :           else
    1355         1456 :             if (case_range.upper_bound () != high)
    1356            7 :               CASE_HIGH (label) = wide_int_to_tree (type,
    1357           14 :                                                     case_range.upper_bound ());
    1358              :         }
    1359              :       // Add case label to the keep list.
    1360        74422 :       cases.safe_push (x);
    1361              :       // Remove case_range from needing to be handled by the default.
    1362        74422 :       case_range.invert ();
    1363        74422 :       default_range.intersect (case_range);
    1364        80549 :     }
    1365              : 
    1366              :   // An undefined DEFAULT range means the current default case is not needed.
    1367        15201 :   unsigned idx = default_range.undefined_p () ? 0 : 1;
    1368        15201 :   unsigned vec_size = cases.length () + idx;
    1369        15201 :   if (vec_size == lim)
    1370              :     return false;
    1371              : 
    1372         4109 :   tree vec2 = make_tree_vec (vec_size);
    1373              :   // Add default label if there is one.
    1374         4109 :   if (idx)
    1375              :     {
    1376         3080 :       TREE_VEC_ELT (vec2, 0) = gimple_switch_default_label (stmt);
    1377         3080 :       e = gimple_switch_edge (cfun, stmt, 0);
    1378         3080 :       e->aux =  (void *)-1;
    1379              :     }
    1380              : 
    1381        16610 :   for (x = 0; x < cases.length (); x++)
    1382              :     {
    1383        12501 :       unsigned swi = cases[x];
    1384        12501 :       TREE_VEC_ELT (vec2, idx++) = gimple_switch_label (stmt, swi);
    1385        12501 :       e = gimple_switch_edge (cfun, stmt, swi);
    1386        12501 :       e->aux =  (void *)-1;
    1387              :     }
    1388              : 
    1389              :   /* Queue not needed edges for later removal.  */
    1390         4109 :   edge_iterator ei;
    1391        25909 :   FOR_EACH_EDGE (e, ei, gimple_bb (stmt)->succs)
    1392              :     {
    1393        21800 :       if (e->aux == (void *)-1)
    1394              :         {
    1395        14777 :           e->aux = NULL;
    1396        14777 :           continue;
    1397              :         }
    1398              : 
    1399         7023 :       if (dump_file && (dump_flags & TDF_DETAILS))
    1400              :         {
    1401            0 :           fprintf (dump_file, "removing unreachable case label\n");
    1402              :         }
    1403         7023 :       to_remove_edges.safe_push (e);
    1404         7023 :       set_and_propagate_unexecutable (e);
    1405         7023 :       e->flags &= ~EDGE_EXECUTABLE;
    1406         7023 :       e->flags |= EDGE_IGNORE;
    1407              :     }
    1408              : 
    1409              :   /* And queue an update for the stmt.  */
    1410         4109 :   su.stmt = stmt;
    1411         4109 :   su.vec = vec2;
    1412         4109 :   to_update_switch_stmts.safe_push (su);
    1413         4109 :   return true;
    1414        63015 : }
    1415              : 
    1416              : void
    1417     13267644 : simplify_using_ranges::cleanup_edges_and_switches (void)
    1418              : {
    1419     13267644 :   int i;
    1420     13267644 :   edge e;
    1421     13267644 :   switch_update *su;
    1422              : 
    1423              :   /* Clear any edges marked as not executable.  */
    1424     13267644 :   if (m_not_executable_flag)
    1425              :     {
    1426      4451305 :       FOR_EACH_VEC_ELT (m_flag_set_edges, i, e)
    1427       217585 :         e->flags &= ~m_not_executable_flag;
    1428              :     }
    1429              :   /* Remove dead edges from SWITCH_EXPR optimization.  This leaves the
    1430              :      CFG in a broken state and requires a cfg_cleanup run.  */
    1431     13278495 :   FOR_EACH_VEC_ELT (to_remove_edges, i, e)
    1432         7023 :     remove_edge (e);
    1433              : 
    1434              :   /* Update SWITCH_EXPR case label vector.  */
    1435     13271753 :   FOR_EACH_VEC_ELT (to_update_switch_stmts, i, su)
    1436              :     {
    1437         4109 :       size_t j;
    1438         4109 :       size_t n = TREE_VEC_LENGTH (su->vec);
    1439         4109 :       tree label;
    1440         4109 :       gimple_switch_set_num_labels (su->stmt, n);
    1441        23799 :       for (j = 0; j < n; j++)
    1442        15581 :         gimple_switch_set_label (su->stmt, j, TREE_VEC_ELT (su->vec, j));
    1443              :       /* As we may have replaced the default label with a regular one
    1444              :          make sure to make it a real default label again.  This ensures
    1445              :          optimal expansion.  */
    1446         4109 :       label = gimple_switch_label (su->stmt, 0);
    1447         4109 :       CASE_LOW (label) = NULL_TREE;
    1448         4109 :       CASE_HIGH (label) = NULL_TREE;
    1449              :     }
    1450              : 
    1451     13267644 :   if (!to_remove_edges.is_empty ())
    1452              :     {
    1453         3828 :       free_dominance_info (CDI_DOMINATORS);
    1454         3828 :       loops_state_set (LOOPS_NEED_FIXUP);
    1455              :     }
    1456              : 
    1457     13267644 :   to_remove_edges.release ();
    1458     13267644 :   to_update_switch_stmts.release ();
    1459     13267644 : }
    1460              : 
    1461              : /* Simplify an integral conversion from an SSA name in STMT.  */
    1462              : 
    1463              : static bool
    1464      4746756 : simplify_conversion_using_ranges (gimple_stmt_iterator *gsi, gimple *stmt)
    1465              : {
    1466      4746756 :   tree innerop, middleop, finaltype;
    1467      4746756 :   gimple *def_stmt;
    1468      4746756 :   signop inner_sgn, middle_sgn, final_sgn;
    1469      4746756 :   unsigned inner_prec, middle_prec, final_prec;
    1470      4746756 :   widest_int innermin, innermed, innermax, middlemin, middlemed, middlemax;
    1471              : 
    1472      4746756 :   finaltype = TREE_TYPE (gimple_assign_lhs (stmt));
    1473      4746756 :   if (!INTEGRAL_TYPE_P (finaltype))
    1474              :     return false;
    1475      4364545 :   middleop = gimple_assign_rhs1 (stmt);
    1476      4364545 :   def_stmt = SSA_NAME_DEF_STMT (middleop);
    1477      4364545 :   if (!is_gimple_assign (def_stmt)
    1478      4364545 :       || !CONVERT_EXPR_CODE_P (gimple_assign_rhs_code (def_stmt)))
    1479              :     return false;
    1480       150103 :   innerop = gimple_assign_rhs1 (def_stmt);
    1481       150103 :   if (TREE_CODE (innerop) != SSA_NAME
    1482       150103 :       || SSA_NAME_OCCURS_IN_ABNORMAL_PHI (innerop))
    1483              :     return false;
    1484              : 
    1485              :   /* Get the value-range of the inner operand.  Use global ranges in
    1486              :      case innerop was created during substitute-and-fold.  */
    1487       146851 :   wide_int imin, imax;
    1488       146851 :   int_range_max vr;
    1489       146851 :   if (!INTEGRAL_TYPE_P (TREE_TYPE (innerop)))
    1490              :     return false;
    1491       246126 :   get_range_query (cfun)->range_of_expr (vr, innerop, stmt);
    1492       123063 :   if (vr.undefined_p () || vr.varying_p ())
    1493              :     return false;
    1494        69351 :   innermin = widest_int::from (vr.lower_bound (), TYPE_SIGN (TREE_TYPE (innerop)));
    1495        69351 :   innermax = widest_int::from (vr.upper_bound (), TYPE_SIGN (TREE_TYPE (innerop)));
    1496              : 
    1497              :   /* Simulate the conversion chain to check if the result is equal if
    1498              :      the middle conversion is removed.  */
    1499        69351 :   inner_prec = TYPE_PRECISION (TREE_TYPE (innerop));
    1500        69351 :   middle_prec = TYPE_PRECISION (TREE_TYPE (middleop));
    1501        69351 :   final_prec = TYPE_PRECISION (finaltype);
    1502              : 
    1503              :   /* If the first conversion is not injective, the second must not
    1504              :      be widening.  */
    1505        69351 :   if (wi::gtu_p (innermax - innermin,
    1506       138702 :                  wi::mask <widest_int> (middle_prec, false))
    1507        69351 :       && middle_prec < final_prec)
    1508              :     return false;
    1509              :   /* We also want a medium value so that we can track the effect that
    1510              :      narrowing conversions with sign change have.  */
    1511        58032 :   inner_sgn = TYPE_SIGN (TREE_TYPE (innerop));
    1512        58032 :   if (inner_sgn == UNSIGNED)
    1513        44135 :     innermed = wi::shifted_mask <widest_int> (1, inner_prec - 1, false);
    1514              :   else
    1515        13897 :     innermed = 0;
    1516        58032 :   if (wi::cmp (innermin, innermed, inner_sgn) >= 0
    1517        58032 :       || wi::cmp (innermed, innermax, inner_sgn) >= 0)
    1518        42461 :     innermed = innermin;
    1519              : 
    1520        58032 :   middle_sgn = TYPE_SIGN (TREE_TYPE (middleop));
    1521        58032 :   middlemin = wi::ext (innermin, middle_prec, middle_sgn);
    1522        58032 :   middlemed = wi::ext (innermed, middle_prec, middle_sgn);
    1523        58032 :   middlemax = wi::ext (innermax, middle_prec, middle_sgn);
    1524              : 
    1525              :   /* Require that the final conversion applied to both the original
    1526              :      and the intermediate range produces the same result.  */
    1527        58032 :   final_sgn = TYPE_SIGN (finaltype);
    1528       116064 :   if (wi::ext (middlemin, final_prec, final_sgn)
    1529       116064 :          != wi::ext (innermin, final_prec, final_sgn)
    1530       111076 :       || wi::ext (middlemed, final_prec, final_sgn)
    1531       224646 :          != wi::ext (innermed, final_prec, final_sgn)
    1532       152142 :       || wi::ext (middlemax, final_prec, final_sgn)
    1533       199197 :          != wi::ext (innermax, final_prec, final_sgn))
    1534              :     return false;
    1535              : 
    1536        45652 :   gimple_assign_set_rhs1 (stmt, innerop);
    1537        45652 :   fold_stmt (gsi, follow_single_use_edges);
    1538        45652 :   return true;
    1539      4893607 : }
    1540              : 
    1541              : /* Simplify a conversion from integral SSA name to float in STMT.  */
    1542              : 
    1543              : bool
    1544       254831 : simplify_using_ranges::simplify_float_conversion_using_ranges
    1545              :                                         (gimple_stmt_iterator *gsi,
    1546              :                                          gimple *stmt)
    1547              : {
    1548       254831 :   tree rhs1 = gimple_assign_rhs1 (stmt);
    1549       254831 :   int_range_max vr;
    1550       254831 :   scalar_float_mode fltmode
    1551       254831 :     = SCALAR_FLOAT_TYPE_MODE (TREE_TYPE (gimple_assign_lhs (stmt)));
    1552       254831 :   scalar_int_mode mode;
    1553       254831 :   tree tem;
    1554       254831 :   gassign *conv;
    1555              : 
    1556              :   /* We can only handle constant ranges.  */
    1557       254831 :   if (!query->range_of_expr (vr, rhs1, stmt)
    1558       254831 :       || vr.varying_p ()
    1559       356389 :       || vr.undefined_p ())
    1560              :     return false;
    1561              : 
    1562              :   /* The code below doesn't work for large/huge _BitInt, nor is really
    1563              :      needed for those, bitint lowering does use ranges already.  */
    1564       100888 :   if (TREE_CODE (TREE_TYPE (rhs1)) == BITINT_TYPE
    1565       100888 :       && TYPE_MODE (TREE_TYPE (rhs1)) == BLKmode)
    1566              :     return false;
    1567              :   /* First check if we can use a signed type in place of an unsigned.  */
    1568       100886 :   scalar_int_mode rhs_mode = SCALAR_INT_TYPE_MODE (TREE_TYPE (rhs1));
    1569       100886 :   if (TYPE_UNSIGNED (TREE_TYPE (rhs1))
    1570         5294 :       && can_float_p (fltmode, rhs_mode, 0) != CODE_FOR_nothing
    1571       104419 :       && range_fits_type_p (&vr, TYPE_PRECISION (TREE_TYPE (rhs1)), SIGNED))
    1572              :     mode = rhs_mode;
    1573              :   /* If we can do the conversion in the current input mode do nothing.  */
    1574        99351 :   else if (can_float_p (fltmode, rhs_mode,
    1575        99351 :                         TYPE_UNSIGNED (TREE_TYPE (rhs1))) != CODE_FOR_nothing)
    1576              :     return false;
    1577              :   /* Otherwise search for a mode we can use, starting from the narrowest
    1578              :      integer mode available.  */
    1579              :   else
    1580              :     {
    1581         4417 :       mode = NARROWEST_INT_MODE;
    1582        15936 :       for (;;)
    1583              :         {
    1584              :           /* If we cannot do a signed conversion to float from mode
    1585              :              or if the value-range does not fit in the signed type
    1586              :              try with a wider mode.  */
    1587        15936 :           if (can_float_p (fltmode, mode, 0) != CODE_FOR_nothing
    1588        15936 :               && range_fits_type_p (&vr, GET_MODE_PRECISION (mode), SIGNED))
    1589              :             break;
    1590              : 
    1591              :           /* But do not widen the input.  Instead leave that to the
    1592              :              optabs expansion code.  */
    1593        31612 :           if (!GET_MODE_WIDER_MODE (mode).exists (&mode)
    1594        15806 :               || GET_MODE_PRECISION (mode) > TYPE_PRECISION (TREE_TYPE (rhs1)))
    1595              :             return false;
    1596              :         }
    1597              :     }
    1598              : 
    1599              :   /* It works, insert a truncation or sign-change before the
    1600              :      float conversion.  */
    1601         1665 :   tem = make_ssa_name (build_nonstandard_integer_type
    1602         1665 :                           (GET_MODE_PRECISION (mode), 0));
    1603         1665 :   conv = gimple_build_assign (tem, NOP_EXPR, rhs1);
    1604         1665 :   gsi_insert_before (gsi, conv, GSI_SAME_STMT);
    1605         1665 :   gimple_assign_set_rhs1 (stmt, tem);
    1606         1665 :   fold_stmt (gsi, follow_single_use_edges);
    1607              : 
    1608         1665 :   return true;
    1609       254831 : }
    1610              : 
    1611              : /* Simplify an internal fn call using ranges if possible.  */
    1612              : 
    1613              : bool
    1614       522681 : simplify_using_ranges::simplify_internal_call_using_ranges
    1615              :                                         (gimple_stmt_iterator *gsi,
    1616              :                                          gimple *stmt)
    1617              : {
    1618       522681 :   enum tree_code subcode;
    1619       522681 :   bool is_ubsan = false;
    1620       522681 :   bool ovf = false;
    1621       522681 :   switch (gimple_call_internal_fn (stmt))
    1622              :     {
    1623              :     case IFN_UBSAN_CHECK_ADD:
    1624              :       subcode = PLUS_EXPR;
    1625              :       is_ubsan = true;
    1626              :       break;
    1627         2477 :     case IFN_UBSAN_CHECK_SUB:
    1628         2477 :       subcode = MINUS_EXPR;
    1629         2477 :       is_ubsan = true;
    1630         2477 :       break;
    1631         2123 :     case IFN_UBSAN_CHECK_MUL:
    1632         2123 :       subcode = MULT_EXPR;
    1633         2123 :       is_ubsan = true;
    1634         2123 :       break;
    1635        40677 :     case IFN_ADD_OVERFLOW:
    1636        40677 :       subcode = PLUS_EXPR;
    1637        40677 :       break;
    1638        49661 :     case IFN_SUB_OVERFLOW:
    1639        49661 :       subcode = MINUS_EXPR;
    1640        49661 :       break;
    1641        46759 :     case IFN_MUL_OVERFLOW:
    1642        46759 :       subcode = MULT_EXPR;
    1643        46759 :       break;
    1644              :     default:
    1645              :       return false;
    1646              :     }
    1647              : 
    1648       144276 :   tree op0 = gimple_call_arg (stmt, 0);
    1649       144276 :   tree op1 = gimple_call_arg (stmt, 1);
    1650       144276 :   tree type;
    1651       144276 :   if (is_ubsan)
    1652              :     {
    1653         7179 :       type = TREE_TYPE (op0);
    1654         7179 :       if (VECTOR_TYPE_P (type))
    1655              :         return false;
    1656              :     }
    1657       137097 :   else if (gimple_call_lhs (stmt) == NULL_TREE)
    1658              :     return false;
    1659              :   else
    1660       137097 :     type = TREE_TYPE (TREE_TYPE (gimple_call_lhs (stmt)));
    1661       143406 :   if (!check_for_binary_op_overflow (query, subcode, type, op0, op1, &ovf, stmt)
    1662       143406 :       || (is_ubsan && ovf))
    1663              :     return false;
    1664              : 
    1665         3501 :   gimple *g;
    1666         3501 :   location_t loc = gimple_location (stmt);
    1667         3501 :   if (is_ubsan)
    1668          573 :     g = gimple_build_assign (gimple_call_lhs (stmt), subcode, op0, op1);
    1669              :   else
    1670              :     {
    1671         2928 :       tree utype = type;
    1672         2928 :       if (ovf
    1673         1439 :           || !useless_type_conversion_p (type, TREE_TYPE (op0))
    1674         3643 :           || !useless_type_conversion_p (type, TREE_TYPE (op1)))
    1675         2502 :         utype = unsigned_type_for (type);
    1676         2928 :       if (TREE_CODE (op0) == INTEGER_CST)
    1677         1175 :         op0 = fold_convert (utype, op0);
    1678         1753 :       else if (!useless_type_conversion_p (utype, TREE_TYPE (op0)))
    1679              :         {
    1680          734 :           g = gimple_build_assign (make_ssa_name (utype), NOP_EXPR, op0);
    1681          734 :           gimple_set_location (g, loc);
    1682          734 :           gsi_insert_before (gsi, g, GSI_SAME_STMT);
    1683          734 :           op0 = gimple_assign_lhs (g);
    1684              :         }
    1685         2928 :       if (TREE_CODE (op1) == INTEGER_CST)
    1686         1698 :         op1 = fold_convert (utype, op1);
    1687         1230 :       else if (!useless_type_conversion_p (utype, TREE_TYPE (op1)))
    1688              :         {
    1689           21 :           g = gimple_build_assign (make_ssa_name (utype), NOP_EXPR, op1);
    1690           21 :           gimple_set_location (g, loc);
    1691           21 :           gsi_insert_before (gsi, g, GSI_SAME_STMT);
    1692           21 :           op1 = gimple_assign_lhs (g);
    1693              :         }
    1694         2928 :       g = gimple_build_assign (make_ssa_name (utype), subcode, op0, op1);
    1695         2928 :       gimple_set_location (g, loc);
    1696         2928 :       gsi_insert_before (gsi, g, GSI_SAME_STMT);
    1697         2928 :       if (utype != type)
    1698              :         {
    1699         1344 :           g = gimple_build_assign (make_ssa_name (type), NOP_EXPR,
    1700              :                                    gimple_assign_lhs (g));
    1701         1344 :           gimple_set_location (g, loc);
    1702         1344 :           gsi_insert_before (gsi, g, GSI_SAME_STMT);
    1703              :         }
    1704         2928 :       g = gimple_build_assign (gimple_call_lhs (stmt), COMPLEX_EXPR,
    1705              :                                gimple_assign_lhs (g),
    1706         2928 :                                build_int_cst (type, ovf));
    1707              :     }
    1708         3501 :   gimple_set_location (g, loc);
    1709         3501 :   gsi_replace (gsi, g, false);
    1710         3501 :   return true;
    1711              : }
    1712              : 
    1713              : /* Return true if VAR is a two-valued variable.  Set a and b with the
    1714              :    two-values when it is true.  Return false otherwise.  */
    1715              : 
    1716              : bool
    1717       496008 : simplify_using_ranges::two_valued_val_range_p (tree var, tree *a, tree *b,
    1718              :                                                gimple *s)
    1719              : {
    1720       496008 :   int_range_max vr;
    1721       496008 :   if (!query->range_of_expr (vr, var, s))
    1722              :     return false;
    1723       496008 :   if (vr.varying_p () || vr.undefined_p ())
    1724              :     return false;
    1725              : 
    1726       817310 :   if ((vr.num_pairs () == 1 && vr.upper_bound () - vr.lower_bound () == 1)
    1727       423059 :       || (vr.num_pairs () == 2
    1728       291362 :           && vr.lower_bound (0) == vr.upper_bound (0)
    1729       247678 :           && vr.lower_bound (1) == vr.upper_bound (1)))
    1730              :     {
    1731         7558 :       *a = wide_int_to_tree (TREE_TYPE (var), vr.lower_bound ());
    1732         7558 :       *b = wide_int_to_tree (TREE_TYPE (var), vr.upper_bound ());
    1733         7558 :       return true;
    1734              :     }
    1735              :   return false;
    1736       496008 : }
    1737              : 
    1738     13267644 : simplify_using_ranges::simplify_using_ranges (range_query *query,
    1739     13267644 :                                               int not_executable_flag)
    1740     13267644 :   : query (query)
    1741              : {
    1742     13267644 :   to_remove_edges = vNULL;
    1743     13267644 :   to_update_switch_stmts = vNULL;
    1744     13267644 :   m_not_executable_flag = not_executable_flag;
    1745     13267644 :   m_flag_set_edges = vNULL;
    1746     13267644 : }
    1747              : 
    1748     13267644 : simplify_using_ranges::~simplify_using_ranges ()
    1749              : {
    1750     13267644 :   cleanup_edges_and_switches ();
    1751     13267644 :   m_flag_set_edges.release ();
    1752     13267644 : }
    1753              : 
    1754              : /* Simplify STMT using ranges if possible.  */
    1755              : 
    1756              : bool
    1757    238248738 : simplify_using_ranges::simplify (gimple_stmt_iterator *gsi)
    1758              : {
    1759    238248738 :   gcc_checking_assert (query);
    1760              : 
    1761    238248738 :   gimple *stmt = gsi_stmt (*gsi);
    1762    238248738 :   if (is_gimple_assign (stmt))
    1763              :     {
    1764     66509162 :       enum tree_code rhs_code = gimple_assign_rhs_code (stmt);
    1765     66509162 :       tree rhs1 = gimple_assign_rhs1 (stmt);
    1766     66509162 :       tree rhs2 = gimple_assign_rhs2 (stmt);
    1767     66509162 :       tree lhs = gimple_assign_lhs (stmt);
    1768     66509162 :       tree val1 = NULL_TREE, val2 = NULL_TREE;
    1769     66509162 :       use_operand_p use_p;
    1770     66509162 :       gimple *use_stmt;
    1771              : 
    1772              :       /* Convert:
    1773              :          LHS = CST BINOP VAR
    1774              :          Where VAR is two-valued and LHS is used in GIMPLE_COND only
    1775              :          To:
    1776              :          LHS = VAR == VAL1 ? (CST BINOP VAL1) : (CST BINOP VAL2)
    1777              : 
    1778              :          Also handles:
    1779              :          LHS = VAR BINOP CST
    1780              :          Where VAR is two-valued and LHS is used in GIMPLE_COND only
    1781              :          To:
    1782              :          LHS = VAR == VAL1 ? (VAL1 BINOP CST) : (VAL2 BINOP CST) */
    1783              : 
    1784     66509162 :       if (TREE_CODE_CLASS (rhs_code) == tcc_binary
    1785     14336142 :           && INTEGRAL_TYPE_P (TREE_TYPE (rhs1))
    1786     10206018 :           && ((TREE_CODE (rhs1) == INTEGER_CST
    1787       180297 :                && TREE_CODE (rhs2) == SSA_NAME)
    1788     10026327 :               || (TREE_CODE (rhs2) == INTEGER_CST
    1789      6701353 :                   && TREE_CODE (rhs1) == SSA_NAME))
    1790      6880438 :           && single_imm_use (lhs, &use_p, &use_stmt)
    1791     71772978 :           && gimple_code (use_stmt) == GIMPLE_COND)
    1792              : 
    1793              :         {
    1794       496008 :           tree new_rhs1 = NULL_TREE;
    1795       496008 :           tree new_rhs2 = NULL_TREE;
    1796       496008 :           tree cmp_var = NULL_TREE;
    1797              : 
    1798       496008 :           if (TREE_CODE (rhs2) == SSA_NAME
    1799       496008 :               && two_valued_val_range_p (rhs2, &val1, &val2, stmt))
    1800              :             {
    1801              :               /* Optimize RHS1 OP [VAL1, VAL2].  */
    1802          239 :               new_rhs1 = int_const_binop (rhs_code, rhs1, val1);
    1803          239 :               new_rhs2 = int_const_binop (rhs_code, rhs1, val2);
    1804          239 :               cmp_var = rhs2;
    1805              :             }
    1806       495769 :           else if (TREE_CODE (rhs1) == SSA_NAME
    1807       495769 :                    && two_valued_val_range_p (rhs1, &val1, &val2, stmt))
    1808              :             {
    1809              :               /* Optimize [VAL1, VAL2] OP RHS2.  */
    1810         7319 :               new_rhs1 = int_const_binop (rhs_code, val1, rhs2);
    1811         7319 :               new_rhs2 = int_const_binop (rhs_code, val2, rhs2);
    1812         7319 :               cmp_var = rhs1;
    1813              :             }
    1814              : 
    1815              :           /* If we could not find two-vals or the optimzation is invalid as
    1816              :              in divide by zero, new_rhs1 / new_rhs will be NULL_TREE.  */
    1817       496008 :           if (new_rhs1 && new_rhs2)
    1818              :             {
    1819         7558 :               tree cond = gimple_build (gsi, true, GSI_SAME_STMT,
    1820              :                                         UNKNOWN_LOCATION,
    1821              :                                         EQ_EXPR, boolean_type_node,
    1822              :                                         cmp_var, val1);
    1823         7558 :               gimple_assign_set_rhs_with_ops (gsi,
    1824              :                                               COND_EXPR, cond,
    1825              :                                               new_rhs1,
    1826              :                                               new_rhs2);
    1827         7558 :               update_stmt (gsi_stmt (*gsi));
    1828         7558 :               fold_stmt (gsi, follow_single_use_edges);
    1829      8079266 :               return true;
    1830              :             }
    1831              :         }
    1832              : 
    1833     66501604 :       if (TREE_CODE_CLASS (rhs_code) == tcc_comparison)
    1834      1200661 :         return simplify_compare_assign_using_ranges_1 (gsi, stmt);
    1835              : 
    1836     65300943 :       switch (rhs_code)
    1837              :         {
    1838              : 
    1839              :       /* Transform TRUNC_DIV_EXPR and TRUNC_MOD_EXPR into RSHIFT_EXPR
    1840              :          and BIT_AND_EXPR respectively if the first operand is greater
    1841              :          than zero and the second operand is an exact power of two.
    1842              :          Also optimize TRUNC_MOD_EXPR away if the second operand is
    1843              :          constant and the first operand already has the right value
    1844              :          range.  */
    1845       317164 :         case TRUNC_DIV_EXPR:
    1846       317164 :         case TRUNC_MOD_EXPR:
    1847       317164 :           if ((TREE_CODE (rhs1) == SSA_NAME
    1848       317164 :                || TREE_CODE (rhs1) == INTEGER_CST)
    1849       317164 :               && INTEGRAL_TYPE_P (TREE_TYPE (rhs1)))
    1850       315950 :             return simplify_div_or_mod_using_ranges (gsi, stmt);
    1851              :           break;
    1852              : 
    1853              :       /* Transform ABS (X) into X or -X as appropriate.  */
    1854        54778 :         case ABS_EXPR:
    1855        54778 :           if (TREE_CODE (rhs1) == SSA_NAME
    1856        54778 :               && INTEGRAL_TYPE_P (TREE_TYPE (rhs1)))
    1857         7366 :             return simplify_abs_using_ranges (gsi, stmt);
    1858              :           break;
    1859              : 
    1860      1289874 :         case BIT_AND_EXPR:
    1861      1289874 :         case BIT_IOR_EXPR:
    1862              :           /* Optimize away BIT_AND_EXPR and BIT_IOR_EXPR if all the bits
    1863              :              being cleared are already cleared or all the bits being set
    1864              :              are already set.  Beware that boolean types must be handled
    1865              :              logically (see range-op.cc) unless they have precision 1.  */
    1866      2498889 :           if (INTEGRAL_TYPE_P (TREE_TYPE (rhs1))
    1867      2467376 :               && (TREE_CODE (TREE_TYPE (rhs1)) != BOOLEAN_TYPE
    1868       292118 :                   || TYPE_PRECISION (TREE_TYPE (rhs1)) == 1))
    1869      1258361 :             return simplify_bit_ops_using_ranges (gsi, stmt);
    1870              :           break;
    1871              : 
    1872      5842533 :         CASE_CONVERT:
    1873      5842533 :           if (TREE_CODE (rhs1) == SSA_NAME
    1874      5842533 :               && INTEGRAL_TYPE_P (TREE_TYPE (rhs1)))
    1875      4746756 :             return simplify_conversion_using_ranges (gsi, stmt);
    1876              :           break;
    1877              : 
    1878       257113 :         case FLOAT_EXPR:
    1879       257113 :           if (TREE_CODE (rhs1) == SSA_NAME
    1880       257113 :               && INTEGRAL_TYPE_P (TREE_TYPE (rhs1)))
    1881       254831 :             return simplify_float_conversion_using_ranges (gsi, stmt);
    1882              :           break;
    1883              : 
    1884       203189 :         case MIN_EXPR:
    1885       203189 :         case MAX_EXPR:
    1886       203189 :           return simplify_min_or_max_using_ranges (gsi, stmt);
    1887              : 
    1888       390595 :         case RSHIFT_EXPR:
    1889       390595 :           {
    1890       390595 :             tree op0 = gimple_assign_rhs1 (stmt);
    1891       390595 :             tree type = TREE_TYPE (op0);
    1892       390595 :             int_range_max range;
    1893       390595 :             if (TYPE_SIGN (type) == SIGNED
    1894       390595 :                 && query->range_of_expr (range, op0, stmt))
    1895              :               {
    1896        84594 :                 unsigned prec = TYPE_PRECISION (TREE_TYPE (op0));
    1897       169188 :                 int_range<2> nzm1 (type, wi::minus_one (prec), wi::zero (prec),
    1898        84594 :                                    VR_ANTI_RANGE);
    1899        84594 :                 range.intersect (nzm1);
    1900              :                 // If there are no ranges other than [-1, 0] remove the shift.
    1901        84594 :                 if (range.undefined_p ())
    1902              :                   {
    1903           61 :                     gimple_assign_set_rhs_from_tree (gsi, op0);
    1904           61 :                     return true;
    1905              :                   }
    1906              :                 return false;
    1907        84594 :               }
    1908       306001 :             break;
    1909       390595 :           }
    1910              :         default:
    1911              :           break;
    1912              :         }
    1913              :     }
    1914    171739576 :   else if (gimple_code (stmt) == GIMPLE_COND)
    1915     12210676 :     return simplify_cond_using_ranges_1 (as_a <gcond *> (stmt));
    1916    159528900 :   else if (gimple_code (stmt) == GIMPLE_SWITCH)
    1917        63015 :     return simplify_switch_using_ranges (as_a <gswitch *> (stmt));
    1918    159465885 :   else if (is_gimple_call (stmt)
    1919    159465885 :            && gimple_call_internal_p (stmt))
    1920       522681 :     return simplify_internal_call_using_ranges (gsi, stmt);
    1921              : 
    1922              :   return false;
    1923              : }
        

Generated by: LCOV version 2.4-beta

LCOV profile is generated on x86_64 machine using following configure options: configure --disable-bootstrap --enable-coverage=opt --enable-languages=c,c++,fortran,go,jit,lto,rust,m2 --enable-host-shared. GCC test suite is run with the built compiler.