Branch data Line data Source code
1 : : /* Support routines for Value Range Propagation (VRP).
2 : : Copyright (C) 2005-2024 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 : 460163 : simplify_using_ranges::op_with_boolean_value_range_p (tree op, gimple *s)
59 : : {
60 : 460163 : if (TYPE_PRECISION (TREE_TYPE (op)) == 1)
61 : : return true;
62 : :
63 : 447339 : if (integer_zerop (op)
64 : 447339 : || integer_onep (op))
65 : 9269 : return true;
66 : :
67 : 438070 : 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 : 438070 : int_range_max vr;
73 : 438070 : return (query->range_of_expr (vr, op, s)
74 : 438070 : && vr == range_true_and_false (TREE_TYPE (op)));
75 : 438070 : }
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 : 142565 : 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 : 142565 : int_range_max vr0, vr1;
89 : 142565 : if (!query->range_of_expr (vr0, op0, s) || vr0.undefined_p ())
90 : 12 : vr0.set_varying (TREE_TYPE (op0));
91 : 142565 : if (!query->range_of_expr (vr1, op1, s) || vr1.undefined_p ())
92 : 4 : vr1.set_varying (TREE_TYPE (op1));
93 : :
94 : 142565 : tree vr0min = wide_int_to_tree (TREE_TYPE (op0), vr0.lower_bound ());
95 : 142565 : tree vr0max = wide_int_to_tree (TREE_TYPE (op0), vr0.upper_bound ());
96 : 142565 : tree vr1min = wide_int_to_tree (TREE_TYPE (op1), vr1.lower_bound ());
97 : 142565 : tree vr1max = wide_int_to_tree (TREE_TYPE (op1), vr1.upper_bound ());
98 : :
99 : 233578 : *ovf = arith_overflowed_p (subcode, type, vr0min,
100 : : subcode == MINUS_EXPR ? vr1max : vr1min);
101 : 233578 : if (arith_overflowed_p (subcode, type, vr0max,
102 : 142565 : subcode == MINUS_EXPR ? vr1min : vr1max) != *ovf)
103 : : return false;
104 : 39227 : if (subcode == MULT_EXPR)
105 : : {
106 : 23860 : if (arith_overflowed_p (subcode, type, vr0min, vr1max) != *ovf
107 : 23860 : || arith_overflowed_p (subcode, type, vr0max, vr1min) != *ovf)
108 : 376 : return false;
109 : : }
110 : 38851 : if (*ovf)
111 : : {
112 : : /* So far we found that there is an overflow on the boundaries.
113 : : That doesn't prove that there is an overflow even for all values
114 : : in between the boundaries. For that compute widest2_int range
115 : : of the result and see if it doesn't overlap the range of
116 : : type. */
117 : 36919 : widest2_int wmin, wmax;
118 : 332309 : widest2_int w[4];
119 : 36919 : int i;
120 : 36919 : signop sign0 = TYPE_SIGN (TREE_TYPE (op0));
121 : 36919 : signop sign1 = TYPE_SIGN (TREE_TYPE (op1));
122 : 36933 : w[0] = widest2_int::from (vr0.lower_bound (), sign0);
123 : 36933 : w[1] = widest2_int::from (vr0.upper_bound (), sign0);
124 : 36924 : w[2] = widest2_int::from (vr1.lower_bound (), sign1);
125 : 36924 : w[3] = widest2_int::from (vr1.upper_bound (), sign1);
126 : 184595 : for (i = 0; i < 4; i++)
127 : : {
128 : 147676 : widest2_int wt;
129 : 147676 : switch (subcode)
130 : : {
131 : 26724 : case PLUS_EXPR:
132 : 26724 : wt = wi::add (w[i & 1], w[2 + (i & 2) / 2]);
133 : 26724 : break;
134 : 27620 : case MINUS_EXPR:
135 : 27620 : wt = wi::sub (w[i & 1], w[2 + (i & 2) / 2]);
136 : 27620 : break;
137 : 93332 : case MULT_EXPR:
138 : 93332 : wt = wi::mul (w[i & 1], w[2 + (i & 2) / 2]);
139 : 93332 : break;
140 : 0 : default:
141 : 0 : gcc_unreachable ();
142 : : }
143 : 147676 : if (i == 0)
144 : : {
145 : 36919 : wmin = wt;
146 : 36919 : wmax = wt;
147 : : }
148 : : else
149 : : {
150 : 110757 : wmin = wi::smin (wmin, wt);
151 : 111413 : wmax = wi::smax (wmax, wt);
152 : : }
153 : 147676 : }
154 : : /* The result of op0 CODE op1 is known to be in range
155 : : [wmin, wmax]. */
156 : 36919 : widest2_int wtmin
157 : 73838 : = widest2_int::from (irange_val_min (type), TYPE_SIGN (type));
158 : 36919 : widest2_int wtmax
159 : 73838 : = widest2_int::from (irange_val_max (type), TYPE_SIGN (type));
160 : : /* If all values in [wmin, wmax] are smaller than
161 : : [wtmin, wtmax] or all are larger than [wtmin, wtmax],
162 : : the arithmetic operation will always overflow. */
163 : 72828 : if (wmax < wtmin || wmin > wtmax)
164 : 1652 : return true;
165 : : return false;
166 : 221724 : }
167 : : return true;
168 : 142565 : }
169 : :
170 : : /* Set INIT, STEP, and DIRECTION to the corresponding values of NAME
171 : : within LOOP, and return TRUE. Otherwise return FALSE, and set R to
172 : : the conservative range of NAME within the loop. */
173 : :
174 : : static bool
175 : 5943359 : get_scev_info (vrange &r, tree name, gimple *stmt, class loop *l,
176 : : tree &init, tree &step, enum ev_direction &dir)
177 : : {
178 : 5943359 : tree ev = analyze_scalar_evolution (l, name);
179 : 5943359 : tree chrec = instantiate_parameters (l, ev);
180 : 5943359 : tree type = TREE_TYPE (name);
181 : 5943359 : if (TREE_CODE (chrec) != POLYNOMIAL_CHREC)
182 : : {
183 : 2947713 : r.set_varying (type);
184 : 2947713 : return false;
185 : : }
186 : 2995646 : if (is_gimple_min_invariant (chrec))
187 : : {
188 : 0 : if (is_gimple_constant (chrec))
189 : 0 : r.set (chrec, chrec);
190 : : else
191 : 0 : r.set_varying (type);
192 : 0 : return false;
193 : : }
194 : :
195 : 2995646 : init = initial_condition_in_loop_num (chrec, l->num);
196 : 2995646 : step = evolution_part_in_loop_num (chrec, l->num);
197 : 2995646 : if (!init || !step)
198 : : {
199 : 0 : r.set_varying (type);
200 : 0 : return false;
201 : : }
202 : 2995646 : dir = scev_direction (chrec);
203 : 2995646 : if (dir == EV_DIR_UNKNOWN
204 : 2995646 : || scev_probably_wraps_p (NULL, init, step, stmt,
205 : : get_chrec_loop (chrec), true))
206 : : {
207 : 691015 : r.set_varying (type);
208 : 691015 : return false;
209 : : }
210 : : return true;
211 : : }
212 : :
213 : : /* Return TRUE if STEP * NIT may overflow when calculated in TYPE. */
214 : :
215 : : static bool
216 : 1977470 : induction_variable_may_overflow_p (tree type,
217 : : const wide_int &step, const widest_int &nit)
218 : : {
219 : 1977470 : wi::overflow_type ovf;
220 : 1977470 : signop sign = TYPE_SIGN (type);
221 : 1977470 : widest_int max_step = wi::mul (widest_int::from (step, sign),
222 : 1977470 : nit, sign, &ovf);
223 : :
224 : 1977470 : if (ovf || !wi::fits_to_tree_p (max_step, type))
225 : 20547 : return true;
226 : :
227 : : /* For a signed type we have to check whether the result has the
228 : : expected signedness which is that of the step as number of
229 : : iterations is unsigned. */
230 : 1956923 : return (sign == SIGNED
231 : 3913536 : && wi::gts_p (max_step, 0) != wi::gts_p (step, 0));
232 : 1977470 : }
233 : :
234 : : /* Set R to the range from BEGIN to END, assuming the direction of the
235 : : loop is DIR. */
236 : :
237 : : static void
238 : 2304274 : range_from_loop_direction (irange &r, tree type,
239 : : const irange &begin, const irange &end,
240 : : ev_direction dir)
241 : : {
242 : 2304274 : signop sign = TYPE_SIGN (type);
243 : :
244 : 2304274 : if (begin.undefined_p () || end.undefined_p ())
245 : 2953 : r.set_varying (type);
246 : 2301321 : else if (dir == EV_DIR_GROWS)
247 : : {
248 : 2155994 : if (wi::gt_p (begin.lower_bound (), end.upper_bound (), sign))
249 : 243 : r.set_varying (type);
250 : : else
251 : 2155751 : r = int_range<1> (type, begin.lower_bound (), end.upper_bound ());
252 : : }
253 : : else
254 : : {
255 : 145335 : if (wi::gt_p (end.lower_bound (), begin.upper_bound (), sign))
256 : 80 : r.set_varying (type);
257 : : else
258 : 145255 : r = int_range<1> (type, end.lower_bound (), begin.upper_bound ());
259 : : }
260 : 2304274 : }
261 : :
262 : : /* Set V to the range of NAME in STMT within LOOP. Return TRUE if a
263 : : range was found. */
264 : :
265 : : bool
266 : 5943359 : range_of_var_in_loop (vrange &v, tree name, class loop *l, gimple *stmt,
267 : : range_query *query)
268 : : {
269 : 5943359 : tree init, step;
270 : 5943359 : enum ev_direction dir;
271 : 5943359 : if (!get_scev_info (v, name, stmt, l, init, step, dir))
272 : : return true;
273 : :
274 : : // Calculate ranges for the values from SCEV.
275 : 2304631 : irange &r = as_a <irange> (v);
276 : 2304631 : tree type = TREE_TYPE (init);
277 : 2304631 : int_range<2> rinit (type), rstep (type), max_init (type);
278 : 2304631 : if (!query->range_of_expr (rinit, init, stmt)
279 : 2304631 : || !query->range_of_expr (rstep, step, stmt))
280 : 0 : return false;
281 : :
282 : : // Calculate the final range of NAME if possible.
283 : 2304631 : if (rinit.singleton_p () && rstep.singleton_p ())
284 : : {
285 : 1977827 : widest_int nit;
286 : 1977827 : if (!max_loop_iterations (l, &nit))
287 : : return false;
288 : :
289 : 1977470 : if (!induction_variable_may_overflow_p (type, rstep.lower_bound (), nit))
290 : : {
291 : : // Calculate the max bounds for init (init + niter * step).
292 : 1956613 : wide_int w = wide_int::from (nit, TYPE_PRECISION (type), TYPE_SIGN (type));
293 : 1956613 : int_range<1> niter (type, w, w);
294 : 1956613 : int_range_max max_step;
295 : 1956613 : range_op_handler mult_handler (MULT_EXPR);
296 : 1956613 : range_op_handler plus_handler (PLUS_EXPR);
297 : 1956613 : if (!mult_handler.fold_range (max_step, type, niter, rstep)
298 : 1956613 : || !plus_handler.fold_range (max_init, type, rinit, max_step))
299 : 0 : return false;
300 : 1956613 : }
301 : 1977827 : }
302 : 2304274 : range_from_loop_direction (r, type, rinit, max_init, dir);
303 : 2304274 : return true;
304 : 2304631 : }
305 : :
306 : : /* Helper function for vrp_evaluate_conditional_warnv & other
307 : : optimizers. */
308 : :
309 : : tree
310 : 18485203 : simplify_using_ranges::fold_cond_with_ops (enum tree_code code,
311 : : tree op0, tree op1, gimple *s)
312 : : {
313 : 18485203 : value_range r0 (TREE_TYPE (op0));
314 : 18485203 : value_range r1 (TREE_TYPE (op1));
315 : 18485203 : if (!query->range_of_expr (r0, op0, s)
316 : 18485203 : || !query->range_of_expr (r1, op1, s))
317 : 0 : return NULL_TREE;
318 : :
319 : 18485203 : int_range<1> res;
320 : 18485203 : range_op_handler handler (code);
321 : 18485203 : if (handler && handler.fold_range (res, boolean_type_node, r0, r1))
322 : : {
323 : 18485203 : if (res == range_true ())
324 : 5729 : return boolean_true_node;
325 : 18479474 : if (res == range_false ())
326 : 4059 : return boolean_false_node;
327 : : }
328 : : return NULL;
329 : 18485203 : }
330 : :
331 : : /* Helper function for legacy_fold_cond. */
332 : :
333 : : tree
334 : 18924675 : simplify_using_ranges::legacy_fold_cond_overflow (gimple *stmt)
335 : : {
336 : 18924675 : tree ret;
337 : 18924675 : tree_code code = gimple_cond_code (stmt);
338 : 18924675 : tree op0 = gimple_cond_lhs (stmt);
339 : 18924675 : tree op1 = gimple_cond_rhs (stmt);
340 : :
341 : : /* We only deal with integral and pointer types. */
342 : 37494920 : if (!INTEGRAL_TYPE_P (TREE_TYPE (op0))
343 : 22909447 : && !POINTER_TYPE_P (TREE_TYPE (op0)))
344 : : return NULL_TREE;
345 : :
346 : : /* If OP0 CODE OP1 is an overflow comparison, if it can be expressed
347 : : as a simple equality test, then prefer that over its current form
348 : : for evaluation.
349 : :
350 : : An overflow test which collapses to an equality test can always be
351 : : expressed as a comparison of one argument against zero. Overflow
352 : : occurs when the chosen argument is zero and does not occur if the
353 : : chosen argument is not zero. */
354 : 18107488 : tree x;
355 : 18107488 : if (overflow_comparison_p (code, op0, op1, &x))
356 : : {
357 : 1147 : wide_int max = wi::max_value (TYPE_PRECISION (TREE_TYPE (op0)), UNSIGNED);
358 : : /* B = A - 1; if (A < B) -> B = A - 1; if (A == 0)
359 : : B = A - 1; if (A > B) -> B = A - 1; if (A != 0)
360 : : B = A + 1; if (B < A) -> B = A + 1; if (B == 0)
361 : : B = A + 1; if (B > A) -> B = A + 1; if (B != 0) */
362 : 1147 : if (integer_zerop (x))
363 : : {
364 : 162 : op1 = x;
365 : 162 : code = (code == LT_EXPR || code == LE_EXPR) ? EQ_EXPR : NE_EXPR;
366 : : }
367 : : /* B = A + 1; if (A > B) -> B = A + 1; if (B == 0)
368 : : B = A + 1; if (A < B) -> B = A + 1; if (B != 0)
369 : : B = A - 1; if (B > A) -> B = A - 1; if (A == 0)
370 : : B = A - 1; if (B < A) -> B = A - 1; if (A != 0) */
371 : 985 : else if (wi::to_wide (x) == max - 1)
372 : : {
373 : 667 : op0 = op1;
374 : 667 : op1 = wide_int_to_tree (TREE_TYPE (op0), 0);
375 : 667 : code = (code == GT_EXPR || code == GE_EXPR) ? EQ_EXPR : NE_EXPR;
376 : : }
377 : : else
378 : : {
379 : 318 : int_range_max vro, vri;
380 : 318 : tree type = TREE_TYPE (op0);
381 : 318 : if (code == GT_EXPR || code == GE_EXPR)
382 : : {
383 : 118 : vro.set (type,
384 : 236 : wi::to_wide (TYPE_MIN_VALUE (type)),
385 : 118 : wi::to_wide (x), VR_ANTI_RANGE);
386 : 118 : vri.set (type,
387 : 236 : wi::to_wide (TYPE_MIN_VALUE (type)),
388 : 236 : wi::to_wide (x));
389 : : }
390 : 200 : else if (code == LT_EXPR || code == LE_EXPR)
391 : : {
392 : 200 : vro.set (type,
393 : 400 : wi::to_wide (TYPE_MIN_VALUE (type)),
394 : 200 : wi::to_wide (x));
395 : 200 : vri.set (type,
396 : 400 : wi::to_wide (TYPE_MIN_VALUE (type)),
397 : 400 : wi::to_wide (x),
398 : : VR_ANTI_RANGE);
399 : : }
400 : : else
401 : 0 : gcc_unreachable ();
402 : 318 : int_range_max vr0;
403 : 318 : if (!query->range_of_expr (vr0, op0, stmt))
404 : 0 : vr0.set_varying (TREE_TYPE (op0));
405 : : /* If vro, the range for OP0 to pass the overflow test, has
406 : : no intersection with *vr0, OP0's known range, then the
407 : : overflow test can't pass, so return the node for false.
408 : : If it is the inverted range, vri, that has no
409 : : intersection, then the overflow test must pass, so return
410 : : the node for true. In other cases, we could proceed with
411 : : a simplified condition comparing OP0 and X, with LE_EXPR
412 : : for previously LE_ or LT_EXPR and GT_EXPR otherwise, but
413 : : the comments next to the enclosing if suggest it's not
414 : : generally profitable to do so. */
415 : 318 : vro.intersect (vr0);
416 : 318 : if (vro.undefined_p ())
417 : 8 : return boolean_false_node;
418 : 310 : vri.intersect (vr0);
419 : 310 : if (vri.undefined_p ())
420 : 0 : return boolean_true_node;
421 : 318 : }
422 : 1147 : }
423 : :
424 : 18107480 : if ((ret = fold_cond_with_ops (code, op0, op1, stmt)))
425 : : return ret;
426 : : return NULL_TREE;
427 : : }
428 : :
429 : : /* Visit conditional statement STMT. If we can determine which edge
430 : : will be taken out of STMT's basic block, record it in
431 : : *TAKEN_EDGE_P. Otherwise, set *TAKEN_EDGE_P to NULL. */
432 : :
433 : : void
434 : 18924675 : simplify_using_ranges::legacy_fold_cond (gcond *stmt, edge *taken_edge_p)
435 : : {
436 : 18924675 : tree val;
437 : :
438 : 18924675 : *taken_edge_p = NULL;
439 : :
440 : 18924675 : if (dump_file && (dump_flags & TDF_DETAILS))
441 : : {
442 : 348 : tree use;
443 : 348 : ssa_op_iter i;
444 : :
445 : 348 : fprintf (dump_file, "\nVisiting conditional with predicate: ");
446 : 348 : print_gimple_stmt (dump_file, stmt, 0);
447 : 348 : fprintf (dump_file, "\nWith known ranges\n");
448 : :
449 : 786 : FOR_EACH_SSA_TREE_OPERAND (use, stmt, i, SSA_OP_USE)
450 : : {
451 : 438 : fprintf (dump_file, "\t");
452 : 438 : print_generic_expr (dump_file, use);
453 : 438 : fprintf (dump_file, ": ");
454 : 438 : value_range r (TREE_TYPE (use));
455 : 438 : query->range_of_expr (r, use, stmt);
456 : 438 : r.dump (dump_file);
457 : 438 : }
458 : :
459 : 348 : fprintf (dump_file, "\n");
460 : : }
461 : :
462 : 18924675 : val = legacy_fold_cond_overflow (stmt);
463 : 18924675 : if (val)
464 : 8 : *taken_edge_p = find_taken_edge (gimple_bb (stmt), val);
465 : :
466 : 18924675 : if (dump_file && (dump_flags & TDF_DETAILS))
467 : : {
468 : 348 : fprintf (dump_file, "\nPredicate evaluates to: ");
469 : 348 : if (val == NULL_TREE)
470 : 348 : fprintf (dump_file, "DON'T KNOW\n");
471 : : else
472 : 0 : print_generic_stmt (dump_file, val);
473 : : }
474 : 18924675 : }
475 : :
476 : : /* Searches the case label vector VEC for the ranges of CASE_LABELs that are
477 : : used in range VR. The indices are placed in MIN_IDX1, MAX_IDX, MIN_IDX2 and
478 : : MAX_IDX2. If the ranges of CASE_LABELs are empty then MAX_IDX1 < MIN_IDX1.
479 : : Returns true if the default label is not needed. */
480 : :
481 : : static bool
482 : 15498 : find_case_label_ranges (gswitch *stmt, const irange *vr,
483 : : size_t *min_idx1, size_t *max_idx1,
484 : : size_t *min_idx2, size_t *max_idx2)
485 : : {
486 : 15498 : size_t i, j, k, l;
487 : 15498 : unsigned int n = gimple_switch_num_labels (stmt);
488 : 15498 : bool take_default;
489 : 15498 : tree case_low, case_high;
490 : 15498 : tree min, max;
491 : 15498 : value_range_kind kind = get_legacy_range (*vr, min, max);
492 : :
493 : 15498 : gcc_checking_assert (!vr->varying_p () && !vr->undefined_p ());
494 : :
495 : 15498 : take_default = !find_case_label_range (stmt, min, max, &i, &j);
496 : :
497 : : /* Set second range to empty. */
498 : 15498 : *min_idx2 = 1;
499 : 15498 : *max_idx2 = 0;
500 : :
501 : 15498 : if (kind == VR_RANGE)
502 : : {
503 : 13190 : *min_idx1 = i;
504 : 13190 : *max_idx1 = j;
505 : 13190 : return !take_default;
506 : : }
507 : :
508 : : /* Set first range to all case labels. */
509 : 2308 : *min_idx1 = 1;
510 : 2308 : *max_idx1 = n - 1;
511 : :
512 : 2308 : if (i > j)
513 : : return false;
514 : :
515 : : /* Make sure all the values of case labels [i , j] are contained in
516 : : range [MIN, MAX]. */
517 : 113 : case_low = CASE_LOW (gimple_switch_label (stmt, i));
518 : 113 : case_high = CASE_HIGH (gimple_switch_label (stmt, j));
519 : 113 : if (tree_int_cst_compare (case_low, min) < 0)
520 : 4 : i += 1;
521 : 113 : if (case_high != NULL_TREE
522 : 113 : && tree_int_cst_compare (max, case_high) < 0)
523 : 6 : j -= 1;
524 : :
525 : 113 : if (i > j)
526 : : return false;
527 : :
528 : : /* If the range spans case labels [i, j], the corresponding anti-range spans
529 : : the labels [1, i - 1] and [j + 1, n - 1]. */
530 : 106 : k = j + 1;
531 : 106 : l = n - 1;
532 : 106 : if (k > l)
533 : : {
534 : 21 : k = 1;
535 : 21 : l = 0;
536 : : }
537 : :
538 : 106 : j = i - 1;
539 : 106 : i = 1;
540 : 106 : if (i > j)
541 : : {
542 : 56 : i = k;
543 : 56 : j = l;
544 : 56 : k = 1;
545 : 56 : l = 0;
546 : : }
547 : :
548 : 106 : *min_idx1 = i;
549 : 106 : *max_idx1 = j;
550 : 106 : *min_idx2 = k;
551 : 106 : *max_idx2 = l;
552 : 106 : return false;
553 : : }
554 : :
555 : : /* Simplify boolean operations if the source is known
556 : : to be already a boolean. */
557 : : bool
558 : 444049 : simplify_using_ranges::simplify_truth_ops_using_ranges
559 : : (gimple_stmt_iterator *gsi,
560 : : gimple *stmt)
561 : : {
562 : 444049 : enum tree_code rhs_code = gimple_assign_rhs_code (stmt);
563 : 444049 : tree lhs, op0, op1;
564 : 444049 : bool need_conversion;
565 : :
566 : : /* We handle only !=/== case here. */
567 : 444049 : gcc_assert (rhs_code == EQ_EXPR || rhs_code == NE_EXPR);
568 : :
569 : 444049 : op0 = gimple_assign_rhs1 (stmt);
570 : 444049 : if (!op_with_boolean_value_range_p (op0, stmt))
571 : : return false;
572 : :
573 : 16114 : op1 = gimple_assign_rhs2 (stmt);
574 : 16114 : if (!op_with_boolean_value_range_p (op1, stmt))
575 : : return false;
576 : :
577 : : /* Reduce number of cases to handle to NE_EXPR. As there is no
578 : : BIT_XNOR_EXPR we cannot replace A == B with a single statement. */
579 : 15722 : if (rhs_code == EQ_EXPR)
580 : : {
581 : 7495 : if (TREE_CODE (op1) == INTEGER_CST)
582 : 3017 : op1 = int_const_binop (BIT_XOR_EXPR, op1,
583 : 6034 : build_int_cst (TREE_TYPE (op1), 1));
584 : : else
585 : : return false;
586 : : }
587 : :
588 : 11244 : lhs = gimple_assign_lhs (stmt);
589 : 11244 : need_conversion
590 : 11244 : = !useless_type_conversion_p (TREE_TYPE (lhs), TREE_TYPE (op0));
591 : :
592 : : /* Make sure to not sign-extend a 1-bit 1 when converting the result. */
593 : 11244 : if (need_conversion
594 : 9737 : && !TYPE_UNSIGNED (TREE_TYPE (op0))
595 : 4337 : && TYPE_PRECISION (TREE_TYPE (op0)) == 1
596 : 11273 : && TYPE_PRECISION (TREE_TYPE (lhs)) > 1)
597 : : return false;
598 : :
599 : : /* For A != 0 we can substitute A itself. */
600 : 11244 : if (integer_zerop (op1))
601 : 6933 : gimple_assign_set_rhs_with_ops (gsi,
602 : : need_conversion
603 : 0 : ? NOP_EXPR : TREE_CODE (op0), op0);
604 : : /* For A != B we substitute A ^ B. Either with conversion. */
605 : 4311 : else if (need_conversion)
606 : : {
607 : 2804 : tree tem = make_ssa_name (TREE_TYPE (op0));
608 : 2804 : gassign *newop
609 : 2804 : = gimple_build_assign (tem, BIT_XOR_EXPR, op0, op1);
610 : 2804 : gsi_insert_before (gsi, newop, GSI_SAME_STMT);
611 : 5585 : if (INTEGRAL_TYPE_P (TREE_TYPE (tem))
612 : 5585 : && TYPE_PRECISION (TREE_TYPE (tem)) > 1)
613 : : {
614 : 5430 : int_range<1> vr (TREE_TYPE (tem),
615 : 2715 : wi::zero (TYPE_PRECISION (TREE_TYPE (tem))),
616 : 5430 : wi::one (TYPE_PRECISION (TREE_TYPE (tem))));
617 : 2715 : set_range_info (tem, vr);
618 : 2715 : }
619 : 2804 : gimple_assign_set_rhs_with_ops (gsi, NOP_EXPR, tem);
620 : : }
621 : : /* Or without. */
622 : : else
623 : 1507 : gimple_assign_set_rhs_with_ops (gsi, BIT_XOR_EXPR, op0, op1);
624 : 11244 : update_stmt (gsi_stmt (*gsi));
625 : 11244 : fold_stmt (gsi, follow_single_use_edges);
626 : :
627 : 11244 : return true;
628 : : }
629 : :
630 : : /* Simplify a division or modulo operator to a right shift or bitwise and
631 : : if the first operand is unsigned or is greater than zero and the second
632 : : operand is an exact power of two. For TRUNC_MOD_EXPR op0 % op1 with
633 : : constant op1 (op1min = op1) or with op1 in [op1min, op1max] range,
634 : : optimize it into just op0 if op0's range is known to be a subset of
635 : : [-op1min + 1, op1min - 1] for signed and [0, op1min - 1] for unsigned
636 : : modulo. */
637 : :
638 : : bool
639 : 317763 : simplify_using_ranges::simplify_div_or_mod_using_ranges
640 : : (gimple_stmt_iterator *gsi,
641 : : gimple *stmt)
642 : : {
643 : 317763 : enum tree_code rhs_code = gimple_assign_rhs_code (stmt);
644 : 317763 : tree val = NULL;
645 : 317763 : tree op0 = gimple_assign_rhs1 (stmt);
646 : 317763 : tree op1 = gimple_assign_rhs2 (stmt);
647 : 317763 : tree op0min = NULL_TREE, op0max = NULL_TREE;
648 : 317763 : tree op1min = op1;
649 : 317763 : int_range_max vr;
650 : :
651 : 317763 : if (TREE_CODE (op0) == INTEGER_CST)
652 : : {
653 : : op0min = op0;
654 : : op0max = op0;
655 : : }
656 : : else
657 : : {
658 : 294023 : if (!query->range_of_expr (vr, op0, stmt))
659 : 0 : vr.set_varying (TREE_TYPE (op0));
660 : 294023 : if (!vr.varying_p () && !vr.undefined_p ())
661 : : {
662 : 140216 : tree type = vr.type ();
663 : 140216 : op0min = wide_int_to_tree (type, vr.lower_bound ());
664 : 140225 : op0max = wide_int_to_tree (type, vr.upper_bound ());
665 : : }
666 : : }
667 : :
668 : 317763 : if (rhs_code == TRUNC_MOD_EXPR
669 : 140928 : && TREE_CODE (op1) == SSA_NAME)
670 : : {
671 : 81640 : int_range_max vr1;
672 : 81640 : if (!query->range_of_expr (vr1, op1, stmt))
673 : 0 : vr1.set_varying (TREE_TYPE (op1));
674 : 81640 : if (!vr1.varying_p () && !vr1.undefined_p ())
675 : 24228 : op1min = wide_int_to_tree (vr1.type (), vr1.lower_bound ());
676 : 81640 : }
677 : 140928 : if (rhs_code == TRUNC_MOD_EXPR
678 : 140928 : && TREE_CODE (op1min) == INTEGER_CST
679 : 83512 : && tree_int_cst_sgn (op1min) == 1
680 : 63807 : && op0max
681 : 36901 : && tree_int_cst_lt (op0max, op1min))
682 : : {
683 : 1138 : if (TYPE_UNSIGNED (TREE_TYPE (op0))
684 : 458 : || tree_int_cst_sgn (op0min) >= 0
685 : 1317 : || tree_int_cst_lt (fold_unary (NEGATE_EXPR, TREE_TYPE (op1min), op1min),
686 : : op0min))
687 : : {
688 : : /* If op0 already has the range op0 % op1 has,
689 : : then TRUNC_MOD_EXPR won't change anything. */
690 : 1104 : gimple_assign_set_rhs_from_tree (gsi, op0);
691 : 1104 : return true;
692 : : }
693 : : }
694 : :
695 : 316659 : if (TREE_CODE (op0) != SSA_NAME)
696 : : return false;
697 : :
698 : 292926 : if (!integer_pow2p (op1))
699 : : {
700 : : /* X % -Y can be only optimized into X % Y either if
701 : : X is not INT_MIN, or Y is not -1. Fold it now, as after
702 : : remove_range_assertions the range info might be not available
703 : : anymore. */
704 : 251745 : if (rhs_code == TRUNC_MOD_EXPR
705 : 251745 : && fold_stmt (gsi, follow_single_use_edges))
706 : : return true;
707 : 251745 : return false;
708 : : }
709 : :
710 : 41181 : if (TYPE_UNSIGNED (TREE_TYPE (op0)))
711 : 8346 : val = integer_one_node;
712 : : else
713 : : {
714 : 32835 : tree zero = build_zero_cst (TREE_TYPE (op0));
715 : 32835 : val = fold_cond_with_ops (GE_EXPR, op0, zero, stmt);
716 : : }
717 : :
718 : 41181 : if (val && integer_onep (val))
719 : : {
720 : 13558 : tree t;
721 : :
722 : 13558 : if (rhs_code == TRUNC_DIV_EXPR)
723 : : {
724 : 11205 : t = build_int_cst (integer_type_node, tree_log2 (op1));
725 : 11205 : gimple_assign_set_rhs_code (stmt, RSHIFT_EXPR);
726 : 11205 : gimple_assign_set_rhs1 (stmt, op0);
727 : 11205 : gimple_assign_set_rhs2 (stmt, t);
728 : : }
729 : : else
730 : : {
731 : 2353 : t = build_int_cst (TREE_TYPE (op1), 1);
732 : 2353 : t = int_const_binop (MINUS_EXPR, op1, t);
733 : 2353 : t = fold_convert (TREE_TYPE (op0), t);
734 : :
735 : 2353 : gimple_assign_set_rhs_code (stmt, BIT_AND_EXPR);
736 : 2353 : gimple_assign_set_rhs1 (stmt, op0);
737 : 2353 : gimple_assign_set_rhs2 (stmt, t);
738 : : }
739 : :
740 : 13558 : update_stmt (stmt);
741 : 13558 : fold_stmt (gsi, follow_single_use_edges);
742 : 13558 : return true;
743 : : }
744 : :
745 : : return false;
746 : 317763 : }
747 : :
748 : : /* Simplify a min or max if the ranges of the two operands are
749 : : disjoint. Return true if we do simplify. */
750 : :
751 : : bool
752 : 167816 : simplify_using_ranges::simplify_min_or_max_using_ranges
753 : : (gimple_stmt_iterator *gsi,
754 : : gimple *stmt)
755 : : {
756 : 167816 : tree op0 = gimple_assign_rhs1 (stmt);
757 : 167816 : tree op1 = gimple_assign_rhs2 (stmt);
758 : 167816 : tree val;
759 : :
760 : 167816 : val = fold_cond_with_ops (LE_EXPR, op0, op1, stmt);
761 : 167816 : if (!val)
762 : 164182 : val = fold_cond_with_ops (LT_EXPR, op0, op1, stmt);
763 : :
764 : 164182 : if (val)
765 : : {
766 : : /* VAL == TRUE -> OP0 < or <= op1
767 : : VAL == FALSE -> OP0 > or >= op1. */
768 : 4247 : tree res = ((gimple_assign_rhs_code (stmt) == MAX_EXPR)
769 : 4247 : == integer_zerop (val)) ? op0 : op1;
770 : 4247 : gimple_assign_set_rhs_from_tree (gsi, res);
771 : 4247 : return true;
772 : : }
773 : :
774 : : return false;
775 : : }
776 : :
777 : : /* If the operand to an ABS_EXPR is >= 0, then eliminate the
778 : : ABS_EXPR. If the operand is <= 0, then simplify the
779 : : ABS_EXPR into a NEGATE_EXPR. */
780 : :
781 : : bool
782 : 6556 : simplify_using_ranges::simplify_abs_using_ranges (gimple_stmt_iterator *gsi,
783 : : gimple *stmt)
784 : : {
785 : 6556 : tree op = gimple_assign_rhs1 (stmt);
786 : 6556 : tree zero = build_zero_cst (TREE_TYPE (op));
787 : 6556 : tree val = fold_cond_with_ops (LE_EXPR, op, zero, stmt);
788 : :
789 : 6556 : if (!val)
790 : : {
791 : : /* The range is neither <= 0 nor > 0. Now see if it is
792 : : either < 0 or >= 0. */
793 : 6334 : val = fold_cond_with_ops (LT_EXPR, op, zero, stmt);
794 : : }
795 : 6334 : if (val)
796 : : {
797 : 329 : gimple_assign_set_rhs1 (stmt, op);
798 : 329 : if (integer_zerop (val))
799 : 164 : gimple_assign_set_rhs_code (stmt, SSA_NAME);
800 : : else
801 : 165 : gimple_assign_set_rhs_code (stmt, NEGATE_EXPR);
802 : 329 : update_stmt (stmt);
803 : 329 : fold_stmt (gsi, follow_single_use_edges);
804 : 329 : return true;
805 : : }
806 : : return false;
807 : : }
808 : :
809 : : /* irange wrapper for wi_set_zero_nonzero_bits.
810 : :
811 : : Return TRUE if VR was a constant range and we were able to compute
812 : : the bit masks. */
813 : :
814 : : static bool
815 : 1598265 : vr_set_zero_nonzero_bits (const tree expr_type,
816 : : const irange *vr,
817 : : wide_int *may_be_nonzero,
818 : : wide_int *must_be_nonzero)
819 : : {
820 : 1598265 : if (vr->varying_p () || vr->undefined_p ())
821 : : {
822 : 945892 : *may_be_nonzero = wi::minus_one (TYPE_PRECISION (expr_type));
823 : 945892 : *must_be_nonzero = wi::zero (TYPE_PRECISION (expr_type));
824 : 945892 : return false;
825 : : }
826 : 652373 : wi_set_zero_nonzero_bits (expr_type, vr->lower_bound (), vr->upper_bound (),
827 : : *may_be_nonzero, *must_be_nonzero);
828 : 652373 : return true;
829 : : }
830 : :
831 : : /* Optimize away redundant BIT_AND_EXPR and BIT_IOR_EXPR.
832 : : If all the bits that are being cleared by & are already
833 : : known to be zero from VR, or all the bits that are being
834 : : set by | are already known to be one from VR, the bit
835 : : operation is redundant. */
836 : :
837 : : bool
838 : 1254834 : simplify_using_ranges::simplify_bit_ops_using_ranges
839 : : (gimple_stmt_iterator *gsi,
840 : : gimple *stmt)
841 : : {
842 : 1254834 : tree op0 = gimple_assign_rhs1 (stmt);
843 : 1254834 : tree op1 = gimple_assign_rhs2 (stmt);
844 : 1254834 : tree op = NULL_TREE;
845 : 1254834 : int_range_max vr0, vr1;
846 : 1254834 : wide_int may_be_nonzero0, may_be_nonzero1;
847 : 1254834 : wide_int must_be_nonzero0, must_be_nonzero1;
848 : 1254834 : wide_int mask;
849 : :
850 : 1254834 : if (!query->range_of_expr (vr0, op0, stmt)
851 : 1254834 : || vr0.undefined_p ())
852 : : return false;
853 : 1254163 : if (!query->range_of_expr (vr1, op1, stmt)
854 : 1254163 : || vr1.undefined_p ())
855 : : return false;
856 : :
857 : 1253837 : if (!vr_set_zero_nonzero_bits (TREE_TYPE (op0), &vr0, &may_be_nonzero0,
858 : : &must_be_nonzero0))
859 : : return false;
860 : 344428 : if (!vr_set_zero_nonzero_bits (TREE_TYPE (op1), &vr1, &may_be_nonzero1,
861 : : &must_be_nonzero1))
862 : : return false;
863 : :
864 : 307945 : switch (gimple_assign_rhs_code (stmt))
865 : : {
866 : 216098 : case BIT_AND_EXPR:
867 : 216098 : mask = wi::bit_and_not (may_be_nonzero0, must_be_nonzero1);
868 : 216098 : if (mask == 0)
869 : : {
870 : : op = op0;
871 : : break;
872 : : }
873 : 211607 : mask = wi::bit_and_not (may_be_nonzero1, must_be_nonzero0);
874 : 211607 : if (mask == 0)
875 : : {
876 : : op = op1;
877 : : break;
878 : : }
879 : : break;
880 : 91847 : case BIT_IOR_EXPR:
881 : 91847 : mask = wi::bit_and_not (may_be_nonzero0, must_be_nonzero1);
882 : 91847 : if (mask == 0)
883 : : {
884 : : op = op1;
885 : : break;
886 : : }
887 : 91846 : mask = wi::bit_and_not (may_be_nonzero1, must_be_nonzero0);
888 : 91846 : if (mask == 0)
889 : : {
890 : : op = op0;
891 : : break;
892 : : }
893 : : break;
894 : 0 : default:
895 : 0 : gcc_unreachable ();
896 : : }
897 : :
898 : 4705 : if (op == NULL_TREE)
899 : 303240 : return false;
900 : :
901 : 4705 : gimple_assign_set_rhs_with_ops (gsi, TREE_CODE (op), op);
902 : 4705 : update_stmt (gsi_stmt (*gsi));
903 : 4705 : return true;
904 : 1254838 : }
905 : :
906 : : /* We are comparing trees OP0 and OP1 using COND_CODE. OP0 has
907 : : a known value range VR.
908 : :
909 : : If there is one and only one value which will satisfy the
910 : : conditional, then return that value. Else return NULL.
911 : :
912 : : If signed overflow must be undefined for the value to satisfy
913 : : the conditional, then set *STRICT_OVERFLOW_P to true. */
914 : :
915 : : static tree
916 : 1342344 : test_for_singularity (enum tree_code cond_code, tree op0,
917 : : tree op1, const irange *vr)
918 : : {
919 : 1342344 : tree min = NULL;
920 : 1342344 : tree max = NULL;
921 : :
922 : : /* Extract minimum/maximum values which satisfy the conditional as it was
923 : : written. */
924 : 1342344 : if (cond_code == LE_EXPR || cond_code == LT_EXPR)
925 : : {
926 : 585458 : min = TYPE_MIN_VALUE (TREE_TYPE (op0));
927 : :
928 : 585458 : max = op1;
929 : 585458 : if (cond_code == LT_EXPR)
930 : : {
931 : 84107 : tree one = build_int_cst (TREE_TYPE (op0), 1);
932 : 84107 : max = fold_build2 (MINUS_EXPR, TREE_TYPE (op0), max, one);
933 : : /* Signal to compare_values_warnv this expr doesn't overflow. */
934 : 84107 : if (EXPR_P (max))
935 : 0 : suppress_warning (max, OPT_Woverflow);
936 : : }
937 : : }
938 : 756886 : else if (cond_code == GE_EXPR || cond_code == GT_EXPR)
939 : : {
940 : 648139 : max = TYPE_MAX_VALUE (TREE_TYPE (op0));
941 : :
942 : 648139 : min = op1;
943 : 648139 : if (cond_code == GT_EXPR)
944 : : {
945 : 565356 : tree one = build_int_cst (TREE_TYPE (op0), 1);
946 : 565356 : min = fold_build2 (PLUS_EXPR, TREE_TYPE (op0), min, one);
947 : : /* Signal to compare_values_warnv this expr doesn't overflow. */
948 : 565356 : if (EXPR_P (min))
949 : 0 : suppress_warning (min, OPT_Woverflow);
950 : : }
951 : : }
952 : :
953 : : /* Now refine the minimum and maximum values using any
954 : : value range information we have for op0. */
955 : 1342344 : if (min && max)
956 : : {
957 : 1233597 : tree type = TREE_TYPE (op0);
958 : 1233597 : tree tmin = wide_int_to_tree (type, vr->lower_bound ());
959 : 1233597 : tree tmax = wide_int_to_tree (type, vr->upper_bound ());
960 : 1233597 : if (compare_values (tmin, min) == 1)
961 : 364573 : min = tmin;
962 : 1233597 : if (compare_values (tmax, max) == -1)
963 : 452427 : max = tmax;
964 : :
965 : : /* If the new min/max values have converged to a single value,
966 : : then there is only one value which can satisfy the condition,
967 : : return that value. */
968 : 1233597 : if (operand_equal_p (min, max, 0) && is_gimple_min_invariant (min))
969 : : return min;
970 : : }
971 : : return NULL;
972 : : }
973 : :
974 : : /* Return whether the value range *VR fits in an integer type specified
975 : : by PRECISION and UNSIGNED_P. */
976 : :
977 : : bool
978 : 221190 : range_fits_type_p (const irange *vr,
979 : : unsigned dest_precision, signop dest_sgn)
980 : : {
981 : 221190 : tree src_type;
982 : 221190 : unsigned src_precision;
983 : 221190 : widest_int tem;
984 : 221190 : signop src_sgn;
985 : :
986 : : /* We can only handle integral and pointer types. */
987 : 221190 : src_type = vr->type ();
988 : 221190 : if (!INTEGRAL_TYPE_P (src_type)
989 : 0 : && !POINTER_TYPE_P (src_type))
990 : : return false;
991 : :
992 : : /* An extension is fine unless VR is SIGNED and dest_sgn is UNSIGNED,
993 : : and so is an identity transform. */
994 : 221190 : src_precision = TYPE_PRECISION (vr->type ());
995 : 221190 : src_sgn = TYPE_SIGN (src_type);
996 : 221190 : if ((src_precision < dest_precision
997 : 7431 : && !(dest_sgn == UNSIGNED && src_sgn == SIGNED))
998 : 215071 : || (src_precision == dest_precision && src_sgn == dest_sgn))
999 : : return true;
1000 : :
1001 : : /* Now we can only handle ranges with constant bounds. */
1002 : 212201 : if (vr->undefined_p () || vr->varying_p ())
1003 : : return false;
1004 : :
1005 : 164671 : wide_int vrmin = vr->lower_bound ();
1006 : 164671 : wide_int vrmax = vr->upper_bound ();
1007 : :
1008 : : /* For sign changes, the MSB of the wide_int has to be clear.
1009 : : An unsigned value with its MSB set cannot be represented by
1010 : : a signed wide_int, while a negative value cannot be represented
1011 : : by an unsigned wide_int. */
1012 : 164671 : if (src_sgn != dest_sgn
1013 : 164671 : && (wi::lts_p (vrmin, 0) || wi::lts_p (vrmax, 0)))
1014 : 50919 : return false;
1015 : :
1016 : : /* Then we can perform the conversion on both ends and compare
1017 : : the result for equality. */
1018 : 113752 : signop sign = TYPE_SIGN (vr->type ());
1019 : 113752 : tem = wi::ext (widest_int::from (vrmin, sign), dest_precision, dest_sgn);
1020 : 113752 : if (tem != widest_int::from (vrmin, sign))
1021 : : return false;
1022 : 108239 : tem = wi::ext (widest_int::from (vrmax, sign), dest_precision, dest_sgn);
1023 : 108239 : if (tem != widest_int::from (vrmax, sign))
1024 : : return false;
1025 : :
1026 : : return true;
1027 : 164671 : }
1028 : :
1029 : : // Clear edge E of EDGE_EXECUTABLE (it is unexecutable). If it wasn't
1030 : : // previously clear, propagate to successor blocks if appropriate.
1031 : :
1032 : : void
1033 : 283601 : simplify_using_ranges::set_and_propagate_unexecutable (edge e)
1034 : : {
1035 : : // If not_executable is already set, we're done.
1036 : : // This works in the absence of a flag as well.
1037 : 283601 : if ((e->flags & m_not_executable_flag) == m_not_executable_flag)
1038 : 196064 : return;
1039 : :
1040 : 186846 : e->flags |= m_not_executable_flag;
1041 : 186846 : m_flag_set_edges.safe_push (e);
1042 : :
1043 : : // Check if the destination block needs to propagate the property.
1044 : 186846 : basic_block bb = e->dest;
1045 : :
1046 : : // If any incoming edge is executable, we are done.
1047 : 186846 : edge_iterator ei;
1048 : 311248 : FOR_EACH_EDGE (e, ei, bb->preds)
1049 : 223711 : if ((e->flags & m_not_executable_flag) == 0)
1050 : : return;
1051 : :
1052 : : // This block is also unexecutable, propagate to all exit edges as well.
1053 : 153471 : FOR_EACH_EDGE (e, ei, bb->succs)
1054 : 65934 : set_and_propagate_unexecutable (e);
1055 : : }
1056 : :
1057 : : /* If COND can be folded entirely as TRUE or FALSE, rewrite the
1058 : : conditional as such, and return TRUE. */
1059 : :
1060 : : bool
1061 : 19205665 : simplify_using_ranges::fold_cond (gcond *cond)
1062 : : {
1063 : 19205665 : int_range_max r;
1064 : 19205665 : if (query->range_of_stmt (r, cond) && r.singleton_p ())
1065 : : {
1066 : : // COND has already been folded if arguments are constant.
1067 : 280990 : if (TREE_CODE (gimple_cond_lhs (cond)) != SSA_NAME
1068 : 280990 : && TREE_CODE (gimple_cond_rhs (cond)) != SSA_NAME)
1069 : : return false;
1070 : 211017 : if (dump_file)
1071 : : {
1072 : 174 : fprintf (dump_file, "Folding predicate ");
1073 : 174 : print_gimple_expr (dump_file, cond, 0);
1074 : 174 : fprintf (dump_file, " to ");
1075 : : }
1076 : 211017 : edge e0 = EDGE_SUCC (gimple_bb (cond), 0);
1077 : 211017 : edge e1 = EDGE_SUCC (gimple_bb (cond), 1);
1078 : 211017 : if (r.zero_p ())
1079 : : {
1080 : 132446 : if (dump_file)
1081 : 118 : fprintf (dump_file, "0\n");
1082 : 132446 : gimple_cond_make_false (cond);
1083 : 132446 : if (e0->flags & EDGE_TRUE_VALUE)
1084 : 130613 : set_and_propagate_unexecutable (e0);
1085 : : else
1086 : 1833 : set_and_propagate_unexecutable (e1);
1087 : : }
1088 : : else
1089 : : {
1090 : 78571 : if (dump_file)
1091 : 56 : fprintf (dump_file, "1\n");
1092 : 78571 : gimple_cond_make_true (cond);
1093 : 78571 : if (e0->flags & EDGE_FALSE_VALUE)
1094 : 580 : set_and_propagate_unexecutable (e0);
1095 : : else
1096 : 77991 : set_and_propagate_unexecutable (e1);
1097 : : }
1098 : 211017 : update_stmt (cond);
1099 : 211017 : return true;
1100 : : }
1101 : :
1102 : : // FIXME: Audit the code below and make sure it never finds anything.
1103 : 18924675 : edge taken_edge;
1104 : 18924675 : legacy_fold_cond (cond, &taken_edge);
1105 : :
1106 : 18924675 : if (taken_edge)
1107 : : {
1108 : 8 : if (taken_edge->flags & EDGE_TRUE_VALUE)
1109 : : {
1110 : 0 : if (dump_file && (dump_flags & TDF_DETAILS))
1111 : 0 : fprintf (dump_file, "\nVRP Predicate evaluates to: 1\n");
1112 : 0 : gimple_cond_make_true (cond);
1113 : : }
1114 : 8 : else if (taken_edge->flags & EDGE_FALSE_VALUE)
1115 : : {
1116 : 8 : if (dump_file && (dump_flags & TDF_DETAILS))
1117 : 0 : fprintf (dump_file, "\nVRP Predicate evaluates to: 0\n");
1118 : 8 : gimple_cond_make_false (cond);
1119 : : }
1120 : : else
1121 : 0 : gcc_unreachable ();
1122 : 8 : update_stmt (cond);
1123 : 8 : return true;
1124 : : }
1125 : : return false;
1126 : 19205665 : }
1127 : :
1128 : : /* Simplify a conditional using a relational operator to an equality
1129 : : test if the range information indicates only one value can satisfy
1130 : : the original conditional. */
1131 : :
1132 : : bool
1133 : 11144672 : simplify_using_ranges::simplify_cond_using_ranges_1 (gcond *stmt)
1134 : : {
1135 : 11144672 : tree op0 = gimple_cond_lhs (stmt);
1136 : 11144672 : tree op1 = gimple_cond_rhs (stmt);
1137 : 11144672 : enum tree_code cond_code = gimple_cond_code (stmt);
1138 : :
1139 : 11144672 : if (fold_cond (stmt))
1140 : : return true;
1141 : :
1142 : 11030025 : if (simplify_compare_using_ranges_1 (cond_code, op0, op1, stmt))
1143 : : {
1144 : 322958 : if (dump_file)
1145 : : {
1146 : 28 : fprintf (dump_file, "Simplified relational ");
1147 : 28 : print_gimple_stmt (dump_file, stmt, 0);
1148 : 28 : fprintf (dump_file, " into ");
1149 : : }
1150 : :
1151 : 322958 : gimple_cond_set_code (stmt, cond_code);
1152 : 322958 : gimple_cond_set_lhs (stmt, op0);
1153 : 322958 : gimple_cond_set_rhs (stmt, op1);
1154 : :
1155 : 322958 : update_stmt (stmt);
1156 : :
1157 : 322958 : if (dump_file)
1158 : : {
1159 : 28 : print_gimple_stmt (dump_file, stmt, 0);
1160 : 28 : fprintf (dump_file, "\n");
1161 : : }
1162 : 322958 : return true;
1163 : : }
1164 : : return false;
1165 : : }
1166 : :
1167 : : /* Like simplify_cond_using_ranges_1 but for assignments rather
1168 : : than GIMPLE_COND. */
1169 : :
1170 : : bool
1171 : 1174838 : simplify_using_ranges::simplify_compare_assign_using_ranges_1
1172 : : (gimple_stmt_iterator *gsi,
1173 : : gimple *stmt)
1174 : : {
1175 : 1174838 : enum tree_code code = gimple_assign_rhs_code (stmt);
1176 : 1174838 : tree op0 = gimple_assign_rhs1 (stmt);
1177 : 1174838 : tree op1 = gimple_assign_rhs2 (stmt);
1178 : 1174838 : gcc_assert (TREE_CODE_CLASS (code) == tcc_comparison);
1179 : 1174838 : bool happened = false;
1180 : :
1181 : 1174838 : if (simplify_compare_using_ranges_1 (code, op0, op1, stmt))
1182 : : {
1183 : 6129 : if (dump_file)
1184 : : {
1185 : 1 : fprintf (dump_file, "Simplified relational ");
1186 : 1 : print_gimple_stmt (dump_file, stmt, 0);
1187 : 1 : fprintf (dump_file, " into ");
1188 : : }
1189 : :
1190 : 6129 : gimple_assign_set_rhs_code (stmt, code);
1191 : 6129 : gimple_assign_set_rhs1 (stmt, op0);
1192 : 6129 : gimple_assign_set_rhs2 (stmt, op1);
1193 : :
1194 : 6129 : update_stmt (stmt);
1195 : :
1196 : 6129 : if (dump_file)
1197 : : {
1198 : 1 : print_gimple_stmt (dump_file, stmt, 0);
1199 : 1 : fprintf (dump_file, "\n");
1200 : : }
1201 : : happened = true;
1202 : : }
1203 : :
1204 : : /* Transform EQ_EXPR, NE_EXPR into BIT_XOR_EXPR or identity
1205 : : if the RHS is zero or one, and the LHS are known to be boolean
1206 : : values. */
1207 : 1174838 : if ((code == EQ_EXPR || code == NE_EXPR)
1208 : 630897 : && INTEGRAL_TYPE_P (TREE_TYPE (op0))
1209 : 1618887 : && simplify_truth_ops_using_ranges (gsi, stmt))
1210 : : happened = true;
1211 : :
1212 : 1174838 : return happened;
1213 : : }
1214 : :
1215 : : /* Try to simplify OP0 COND_CODE OP1 using a relational operator to an
1216 : : equality test if the range information indicates only one value can
1217 : : satisfy the original conditional. */
1218 : :
1219 : : bool
1220 : 12204863 : simplify_using_ranges::simplify_compare_using_ranges_1 (tree_code &cond_code, tree &op0, tree &op1, gimple *stmt)
1221 : : {
1222 : 12204863 : bool happened = false;
1223 : 12204863 : if (cond_code != NE_EXPR
1224 : 12204863 : && cond_code != EQ_EXPR
1225 : 3102308 : && TREE_CODE (op0) == SSA_NAME
1226 : 3097059 : && INTEGRAL_TYPE_P (TREE_TYPE (op0))
1227 : 14988044 : && is_gimple_min_invariant (op1))
1228 : : {
1229 : 1641051 : int_range_max vr;
1230 : :
1231 : 1641051 : if (!query->range_of_expr (vr, op0, stmt))
1232 : 0 : vr.set_undefined ();
1233 : :
1234 : : /* If we have range information for OP0, then we might be
1235 : : able to simplify this conditional. */
1236 : 1641051 : if (!vr.undefined_p () && !vr.varying_p ())
1237 : : {
1238 : 671172 : tree new_tree = test_for_singularity (cond_code, op0, op1, &vr);
1239 : 671172 : if (new_tree)
1240 : : {
1241 : 108747 : cond_code = EQ_EXPR;
1242 : 108747 : op1 = new_tree;
1243 : 108747 : happened = true;
1244 : : }
1245 : :
1246 : : /* Try again after inverting the condition. We only deal
1247 : : with integral types here, so no need to worry about
1248 : : issues with inverting FP comparisons. */
1249 : 671172 : new_tree = test_for_singularity
1250 : 671172 : (invert_tree_comparison (cond_code, false),
1251 : : op0, op1, &vr);
1252 : 671172 : if (new_tree)
1253 : : {
1254 : 154295 : cond_code = NE_EXPR;
1255 : 154295 : op1 = new_tree;
1256 : 154295 : happened = true;
1257 : : }
1258 : : }
1259 : 1641051 : }
1260 : : // Try to simplify casted conditions.
1261 : 12204863 : if (simplify_casted_compare (cond_code, op0, op1))
1262 : 72694 : happened = true;
1263 : 12204863 : return happened;
1264 : : }
1265 : :
1266 : : /* Simplify OP0 code OP1 when OP1 is a constant and OP0 was a SSA_NAME
1267 : : defined by a type conversion. Replacing OP0 with RHS of the type conversion.
1268 : : Doing so makes the conversion dead which helps subsequent passes. */
1269 : :
1270 : : bool
1271 : 12204863 : simplify_using_ranges::simplify_casted_compare (tree_code &, tree &op0, tree &op1)
1272 : : {
1273 : :
1274 : : /* If we have a comparison of an SSA_NAME (OP0) against a constant,
1275 : : see if OP0 was set by a type conversion where the source of
1276 : : the conversion is another SSA_NAME with a range that fits
1277 : : into the range of OP0's type.
1278 : :
1279 : : If so, the conversion is redundant as the earlier SSA_NAME can be
1280 : : used for the comparison directly if we just massage the constant in the
1281 : : comparison. */
1282 : 12204863 : if (TREE_CODE (op0) == SSA_NAME
1283 : 11975317 : && TREE_CODE (op1) == INTEGER_CST)
1284 : : {
1285 : 8573448 : gimple *def_stmt = SSA_NAME_DEF_STMT (op0);
1286 : 8573448 : tree innerop;
1287 : :
1288 : 8573448 : if (!is_gimple_assign (def_stmt))
1289 : : return false;
1290 : :
1291 : 5252011 : switch (gimple_assign_rhs_code (def_stmt))
1292 : : {
1293 : 432292 : CASE_CONVERT:
1294 : 432292 : innerop = gimple_assign_rhs1 (def_stmt);
1295 : 432292 : break;
1296 : 46776 : case VIEW_CONVERT_EXPR:
1297 : 46776 : innerop = TREE_OPERAND (gimple_assign_rhs1 (def_stmt), 0);
1298 : 46776 : if (!INTEGRAL_TYPE_P (TREE_TYPE (innerop)))
1299 : : return false;
1300 : : break;
1301 : : default:
1302 : : return false;
1303 : : }
1304 : :
1305 : 478113 : if (TREE_CODE (innerop) == SSA_NAME
1306 : 478063 : && !POINTER_TYPE_P (TREE_TYPE (innerop))
1307 : 472505 : && !SSA_NAME_OCCURS_IN_ABNORMAL_PHI (innerop)
1308 : 950605 : && desired_pro_or_demotion_p (TREE_TYPE (innerop), TREE_TYPE (op0)))
1309 : : {
1310 : 442267 : int_range_max vr;
1311 : :
1312 : 442267 : if (query->range_of_expr (vr, innerop)
1313 : 442264 : && !vr.varying_p ()
1314 : 142877 : && !vr.undefined_p ()
1315 : 142758 : && range_fits_type_p (&vr,
1316 : 142758 : TYPE_PRECISION (TREE_TYPE (op0)),
1317 : 142758 : TYPE_SIGN (TREE_TYPE (op0)))
1318 : 514961 : && int_fits_type_p (op1, TREE_TYPE (innerop)))
1319 : : {
1320 : 72694 : tree newconst = fold_convert (TREE_TYPE (innerop), op1);
1321 : 72694 : op0 = innerop;
1322 : 72694 : op1 = newconst;
1323 : 72694 : return true;
1324 : : }
1325 : 442267 : }
1326 : : }
1327 : : return false;
1328 : : }
1329 : :
1330 : : /* Simplify a switch statement using the value range of the switch
1331 : : argument. */
1332 : :
1333 : : bool
1334 : 57947 : simplify_using_ranges::simplify_switch_using_ranges (gswitch *stmt)
1335 : : {
1336 : 57947 : tree op = gimple_switch_index (stmt);
1337 : 57947 : int_range_max vr;
1338 : 57947 : bool take_default;
1339 : 57947 : edge e;
1340 : 57947 : edge_iterator ei;
1341 : 57947 : size_t i = 0, j = 0, n, n2;
1342 : 57947 : tree vec2;
1343 : 57947 : switch_update su;
1344 : 57947 : size_t k = 1, l = 0;
1345 : :
1346 : 57947 : if (TREE_CODE (op) == SSA_NAME)
1347 : : {
1348 : 57931 : if (!query->range_of_expr (vr, op, stmt)
1349 : 57931 : || vr.varying_p () || vr.undefined_p ())
1350 : : return false;
1351 : :
1352 : : /* Find case label for min/max of the value range. */
1353 : 15498 : take_default = !find_case_label_ranges (stmt, &vr, &i, &j, &k, &l);
1354 : : }
1355 : 16 : else if (TREE_CODE (op) == INTEGER_CST)
1356 : : {
1357 : 16 : take_default = !find_case_label_index (stmt, 1, op, &i);
1358 : 16 : if (take_default)
1359 : : {
1360 : 1 : i = 1;
1361 : 1 : j = 0;
1362 : : }
1363 : : else
1364 : : {
1365 : 15 : j = i;
1366 : : }
1367 : : }
1368 : : else
1369 : : return false;
1370 : :
1371 : 15514 : n = gimple_switch_num_labels (stmt);
1372 : :
1373 : : /* We can truncate the case label ranges that partially overlap with OP's
1374 : : value range. */
1375 : 15514 : size_t min_idx = 1, max_idx = 0;
1376 : 15514 : tree min, max;
1377 : 15514 : value_range_kind kind = get_legacy_range (vr, min, max);
1378 : 15514 : if (!vr.undefined_p ())
1379 : 15498 : find_case_label_range (stmt, min, max, &min_idx, &max_idx);
1380 : 15514 : if (min_idx <= max_idx)
1381 : : {
1382 : 13301 : tree min_label = gimple_switch_label (stmt, min_idx);
1383 : 13301 : tree max_label = gimple_switch_label (stmt, max_idx);
1384 : :
1385 : : /* Avoid changing the type of the case labels when truncating. */
1386 : 13301 : tree case_label_type = TREE_TYPE (CASE_LOW (min_label));
1387 : 13301 : tree vr_min = fold_convert (case_label_type, min);
1388 : 13301 : tree vr_max = fold_convert (case_label_type, max);
1389 : :
1390 : 13301 : if (kind == VR_RANGE)
1391 : : {
1392 : : /* If OP's value range is [2,8] and the low label range is
1393 : : 0 ... 3, truncate the label's range to 2 .. 3. */
1394 : 13188 : if (tree_int_cst_compare (CASE_LOW (min_label), vr_min) < 0
1395 : 7 : && CASE_HIGH (min_label) != NULL_TREE
1396 : 13195 : && tree_int_cst_compare (CASE_HIGH (min_label), vr_min) >= 0)
1397 : 7 : CASE_LOW (min_label) = vr_min;
1398 : :
1399 : : /* If OP's value range is [2,8] and the high label range is
1400 : : 7 ... 10, truncate the label's range to 7 .. 8. */
1401 : 13188 : if (tree_int_cst_compare (CASE_LOW (max_label), vr_max) <= 0
1402 : 13188 : && CASE_HIGH (max_label) != NULL_TREE
1403 : 13492 : && tree_int_cst_compare (CASE_HIGH (max_label), vr_max) > 0)
1404 : 6 : CASE_HIGH (max_label) = vr_max;
1405 : : }
1406 : 113 : else if (kind == VR_ANTI_RANGE)
1407 : : {
1408 : 113 : tree one_cst = build_one_cst (case_label_type);
1409 : :
1410 : 113 : if (min_label == max_label)
1411 : : {
1412 : : /* If OP's value range is ~[7,8] and the label's range is
1413 : : 7 ... 10, truncate the label's range to 9 ... 10. */
1414 : 107 : if (tree_int_cst_compare (CASE_LOW (min_label), vr_min) == 0
1415 : 104 : && CASE_HIGH (min_label) != NULL_TREE
1416 : 115 : && tree_int_cst_compare (CASE_HIGH (min_label), vr_max) > 0)
1417 : 3 : CASE_LOW (min_label)
1418 : 6 : = int_const_binop (PLUS_EXPR, vr_max, one_cst);
1419 : :
1420 : : /* If OP's value range is ~[7,8] and the label's range is
1421 : : 5 ... 8, truncate the label's range to 5 ... 6. */
1422 : 107 : if (tree_int_cst_compare (CASE_LOW (min_label), vr_min) < 0
1423 : 3 : && CASE_HIGH (min_label) != NULL_TREE
1424 : 110 : && tree_int_cst_compare (CASE_HIGH (min_label), vr_max) == 0)
1425 : 1 : CASE_HIGH (min_label)
1426 : 2 : = int_const_binop (MINUS_EXPR, vr_min, one_cst);
1427 : : }
1428 : : else
1429 : : {
1430 : : /* If OP's value range is ~[2,8] and the low label range is
1431 : : 0 ... 3, truncate the label's range to 0 ... 1. */
1432 : 6 : if (tree_int_cst_compare (CASE_LOW (min_label), vr_min) < 0
1433 : 1 : && CASE_HIGH (min_label) != NULL_TREE
1434 : 7 : && tree_int_cst_compare (CASE_HIGH (min_label), vr_min) >= 0)
1435 : 1 : CASE_HIGH (min_label)
1436 : 2 : = int_const_binop (MINUS_EXPR, vr_min, one_cst);
1437 : :
1438 : : /* If OP's value range is ~[2,8] and the high label range is
1439 : : 7 ... 10, truncate the label's range to 9 ... 10. */
1440 : 6 : if (tree_int_cst_compare (CASE_LOW (max_label), vr_max) <= 0
1441 : 6 : && CASE_HIGH (max_label) != NULL_TREE
1442 : 7 : && tree_int_cst_compare (CASE_HIGH (max_label), vr_max) > 0)
1443 : 1 : CASE_LOW (max_label)
1444 : 2 : = int_const_binop (PLUS_EXPR, vr_max, one_cst);
1445 : : }
1446 : : }
1447 : :
1448 : : /* Canonicalize singleton case ranges. */
1449 : 13301 : if (tree_int_cst_equal (CASE_LOW (min_label), CASE_HIGH (min_label)))
1450 : 4 : CASE_HIGH (min_label) = NULL_TREE;
1451 : 13301 : if (tree_int_cst_equal (CASE_LOW (max_label), CASE_HIGH (max_label)))
1452 : 1 : CASE_HIGH (max_label) = NULL_TREE;
1453 : : }
1454 : :
1455 : : /* We can also eliminate case labels that lie completely outside OP's value
1456 : : range. */
1457 : :
1458 : : /* Bail out if this is just all edges taken. */
1459 : 15514 : if (i == 1
1460 : 12603 : && j == n - 1
1461 : 12380 : && take_default)
1462 : : return false;
1463 : :
1464 : : /* Build a new vector of taken case labels. */
1465 : 3818 : vec2 = make_tree_vec (j - i + 1 + l - k + 1 + (int)take_default);
1466 : 3818 : n2 = 0;
1467 : :
1468 : : /* Add the default edge, if necessary. */
1469 : 3818 : if (take_default)
1470 : 3091 : TREE_VEC_ELT (vec2, n2++) = gimple_switch_default_label (stmt);
1471 : :
1472 : 14492 : for (; i <= j; ++i, ++n2)
1473 : 10674 : TREE_VEC_ELT (vec2, n2) = gimple_switch_label (stmt, i);
1474 : :
1475 : 3994 : for (; k <= l; ++k, ++n2)
1476 : 176 : TREE_VEC_ELT (vec2, n2) = gimple_switch_label (stmt, k);
1477 : :
1478 : : /* Mark needed edges. */
1479 : 17759 : for (i = 0; i < n2; ++i)
1480 : : {
1481 : 13941 : e = find_edge (gimple_bb (stmt),
1482 : : label_to_block (cfun,
1483 : 13941 : CASE_LABEL (TREE_VEC_ELT (vec2, i))));
1484 : 13941 : e->aux = (void *)-1;
1485 : : }
1486 : :
1487 : : /* Queue not needed edges for later removal. */
1488 : 24042 : FOR_EACH_EDGE (e, ei, gimple_bb (stmt)->succs)
1489 : : {
1490 : 20224 : if (e->aux == (void *)-1)
1491 : : {
1492 : 13574 : e->aux = NULL;
1493 : 13574 : continue;
1494 : : }
1495 : :
1496 : 6650 : if (dump_file && (dump_flags & TDF_DETAILS))
1497 : : {
1498 : 0 : fprintf (dump_file, "removing unreachable case label\n");
1499 : : }
1500 : 6650 : to_remove_edges.safe_push (e);
1501 : 6650 : set_and_propagate_unexecutable (e);
1502 : 6650 : e->flags &= ~EDGE_EXECUTABLE;
1503 : 6650 : e->flags |= EDGE_IGNORE;
1504 : : }
1505 : :
1506 : : /* And queue an update for the stmt. */
1507 : 3818 : su.stmt = stmt;
1508 : 3818 : su.vec = vec2;
1509 : 3818 : to_update_switch_stmts.safe_push (su);
1510 : 3818 : return true;
1511 : 57947 : }
1512 : :
1513 : : void
1514 : 12048193 : simplify_using_ranges::cleanup_edges_and_switches (void)
1515 : : {
1516 : 12048193 : int i;
1517 : 12048193 : edge e;
1518 : 12048193 : switch_update *su;
1519 : :
1520 : : /* Clear any edges marked as not executable. */
1521 : 12048193 : if (m_not_executable_flag)
1522 : : {
1523 : 4174040 : FOR_EACH_VEC_ELT (m_flag_set_edges, i, e)
1524 : 186846 : e->flags &= ~m_not_executable_flag;
1525 : : }
1526 : : /* Remove dead edges from SWITCH_EXPR optimization. This leaves the
1527 : : CFG in a broken state and requires a cfg_cleanup run. */
1528 : 12058401 : FOR_EACH_VEC_ELT (to_remove_edges, i, e)
1529 : 6650 : remove_edge (e);
1530 : :
1531 : : /* Update SWITCH_EXPR case label vector. */
1532 : 12052011 : FOR_EACH_VEC_ELT (to_update_switch_stmts, i, su)
1533 : : {
1534 : 3818 : size_t j;
1535 : 3818 : size_t n = TREE_VEC_LENGTH (su->vec);
1536 : 3818 : tree label;
1537 : 3818 : gimple_switch_set_num_labels (su->stmt, n);
1538 : 21577 : for (j = 0; j < n; j++)
1539 : 13941 : gimple_switch_set_label (su->stmt, j, TREE_VEC_ELT (su->vec, j));
1540 : : /* As we may have replaced the default label with a regular one
1541 : : make sure to make it a real default label again. This ensures
1542 : : optimal expansion. */
1543 : 3818 : label = gimple_switch_label (su->stmt, 0);
1544 : 3818 : CASE_LOW (label) = NULL_TREE;
1545 : 3818 : CASE_HIGH (label) = NULL_TREE;
1546 : : }
1547 : :
1548 : 12048193 : if (!to_remove_edges.is_empty ())
1549 : : {
1550 : 3558 : free_dominance_info (CDI_DOMINATORS);
1551 : 3558 : loops_state_set (LOOPS_NEED_FIXUP);
1552 : : }
1553 : :
1554 : 12048193 : to_remove_edges.release ();
1555 : 12048193 : to_update_switch_stmts.release ();
1556 : 12048193 : }
1557 : :
1558 : : /* Simplify an integral conversion from an SSA name in STMT. */
1559 : :
1560 : : static bool
1561 : 4640388 : simplify_conversion_using_ranges (gimple_stmt_iterator *gsi, gimple *stmt)
1562 : : {
1563 : 4640388 : tree innerop, middleop, finaltype;
1564 : 4640388 : gimple *def_stmt;
1565 : 4640388 : signop inner_sgn, middle_sgn, final_sgn;
1566 : 4640388 : unsigned inner_prec, middle_prec, final_prec;
1567 : 4640388 : widest_int innermin, innermed, innermax, middlemin, middlemed, middlemax;
1568 : :
1569 : 4640388 : finaltype = TREE_TYPE (gimple_assign_lhs (stmt));
1570 : 4640388 : if (!INTEGRAL_TYPE_P (finaltype))
1571 : : return false;
1572 : 4296975 : middleop = gimple_assign_rhs1 (stmt);
1573 : 4296975 : def_stmt = SSA_NAME_DEF_STMT (middleop);
1574 : 4296975 : if (!is_gimple_assign (def_stmt)
1575 : 4296975 : || !CONVERT_EXPR_CODE_P (gimple_assign_rhs_code (def_stmt)))
1576 : : return false;
1577 : 165993 : innerop = gimple_assign_rhs1 (def_stmt);
1578 : 165993 : if (TREE_CODE (innerop) != SSA_NAME
1579 : 165993 : || SSA_NAME_OCCURS_IN_ABNORMAL_PHI (innerop))
1580 : : return false;
1581 : :
1582 : : /* Get the value-range of the inner operand. Use global ranges in
1583 : : case innerop was created during substitute-and-fold. */
1584 : 162761 : wide_int imin, imax;
1585 : 162761 : int_range_max vr;
1586 : 162761 : if (!INTEGRAL_TYPE_P (TREE_TYPE (innerop)))
1587 : : return false;
1588 : 278584 : get_range_query (cfun)->range_of_expr (vr, innerop, stmt);
1589 : 139292 : if (vr.undefined_p () || vr.varying_p ())
1590 : : return false;
1591 : 71700 : innermin = widest_int::from (vr.lower_bound (), TYPE_SIGN (TREE_TYPE (innerop)));
1592 : 71700 : innermax = widest_int::from (vr.upper_bound (), TYPE_SIGN (TREE_TYPE (innerop)));
1593 : :
1594 : : /* Simulate the conversion chain to check if the result is equal if
1595 : : the middle conversion is removed. */
1596 : 71700 : inner_prec = TYPE_PRECISION (TREE_TYPE (innerop));
1597 : 71700 : middle_prec = TYPE_PRECISION (TREE_TYPE (middleop));
1598 : 71700 : final_prec = TYPE_PRECISION (finaltype);
1599 : :
1600 : : /* If the first conversion is not injective, the second must not
1601 : : be widening. */
1602 : 71700 : if (wi::gtu_p (innermax - innermin,
1603 : 143400 : wi::mask <widest_int> (middle_prec, false))
1604 : 71700 : && middle_prec < final_prec)
1605 : : return false;
1606 : : /* We also want a medium value so that we can track the effect that
1607 : : narrowing conversions with sign change have. */
1608 : 56602 : inner_sgn = TYPE_SIGN (TREE_TYPE (innerop));
1609 : 56602 : if (inner_sgn == UNSIGNED)
1610 : 42181 : innermed = wi::shifted_mask <widest_int> (1, inner_prec - 1, false);
1611 : : else
1612 : 14421 : innermed = 0;
1613 : 56602 : if (wi::cmp (innermin, innermed, inner_sgn) >= 0
1614 : 56602 : || wi::cmp (innermed, innermax, inner_sgn) >= 0)
1615 : 42911 : innermed = innermin;
1616 : :
1617 : 56602 : middle_sgn = TYPE_SIGN (TREE_TYPE (middleop));
1618 : 56602 : middlemin = wi::ext (innermin, middle_prec, middle_sgn);
1619 : 56602 : middlemed = wi::ext (innermed, middle_prec, middle_sgn);
1620 : 56602 : middlemax = wi::ext (innermax, middle_prec, middle_sgn);
1621 : :
1622 : : /* Require that the final conversion applied to both the original
1623 : : and the intermediate range produces the same result. */
1624 : 56602 : final_sgn = TYPE_SIGN (finaltype);
1625 : 113204 : if (wi::ext (middlemin, final_prec, final_sgn)
1626 : 113204 : != wi::ext (innermin, final_prec, final_sgn)
1627 : 108234 : || wi::ext (middlemed, final_prec, final_sgn)
1628 : 218953 : != wi::ext (innermed, final_prec, final_sgn)
1629 : 146108 : || wi::ext (middlemax, final_prec, final_sgn)
1630 : 190861 : != wi::ext (innermax, final_prec, final_sgn))
1631 : : return false;
1632 : :
1633 : 44147 : gimple_assign_set_rhs1 (stmt, innerop);
1634 : 44147 : fold_stmt (gsi, follow_single_use_edges);
1635 : 44147 : return true;
1636 : 4803149 : }
1637 : :
1638 : : /* Simplify a conversion from integral SSA name to float in STMT. */
1639 : :
1640 : : bool
1641 : 248846 : simplify_using_ranges::simplify_float_conversion_using_ranges
1642 : : (gimple_stmt_iterator *gsi,
1643 : : gimple *stmt)
1644 : : {
1645 : 248846 : tree rhs1 = gimple_assign_rhs1 (stmt);
1646 : 248846 : int_range_max vr;
1647 : 248846 : scalar_float_mode fltmode
1648 : 248846 : = SCALAR_FLOAT_TYPE_MODE (TREE_TYPE (gimple_assign_lhs (stmt)));
1649 : 248846 : scalar_int_mode mode;
1650 : 248846 : tree tem;
1651 : 248846 : gassign *conv;
1652 : :
1653 : : /* We can only handle constant ranges. */
1654 : 248846 : if (!query->range_of_expr (vr, rhs1, stmt)
1655 : 248846 : || vr.varying_p ()
1656 : 344417 : || vr.undefined_p ())
1657 : : return false;
1658 : :
1659 : : /* The code below doesn't work for large/huge _BitInt, nor is really
1660 : : needed for those, bitint lowering does use ranges already. */
1661 : 94906 : if (TREE_CODE (TREE_TYPE (rhs1)) == BITINT_TYPE
1662 : 94906 : && TYPE_MODE (TREE_TYPE (rhs1)) == BLKmode)
1663 : : return false;
1664 : : /* First check if we can use a signed type in place of an unsigned. */
1665 : 94904 : scalar_int_mode rhs_mode = SCALAR_INT_TYPE_MODE (TREE_TYPE (rhs1));
1666 : 94904 : if (TYPE_UNSIGNED (TREE_TYPE (rhs1))
1667 : 5495 : && can_float_p (fltmode, rhs_mode, 0) != CODE_FOR_nothing
1668 : 98676 : && range_fits_type_p (&vr, TYPE_PRECISION (TREE_TYPE (rhs1)), SIGNED))
1669 : : mode = rhs_mode;
1670 : : /* If we can do the conversion in the current input mode do nothing. */
1671 : 93441 : else if (can_float_p (fltmode, rhs_mode,
1672 : 93441 : TYPE_UNSIGNED (TREE_TYPE (rhs1))) != CODE_FOR_nothing)
1673 : : return false;
1674 : : /* Otherwise search for a mode we can use, starting from the narrowest
1675 : : integer mode available. */
1676 : : else
1677 : : {
1678 : 4313 : mode = NARROWEST_INT_MODE;
1679 : 15558 : for (;;)
1680 : : {
1681 : : /* If we cannot do a signed conversion to float from mode
1682 : : or if the value-range does not fit in the signed type
1683 : : try with a wider mode. */
1684 : 15558 : if (can_float_p (fltmode, mode, 0) != CODE_FOR_nothing
1685 : 15558 : && range_fits_type_p (&vr, GET_MODE_PRECISION (mode), SIGNED))
1686 : : break;
1687 : :
1688 : : /* But do not widen the input. Instead leave that to the
1689 : : optabs expansion code. */
1690 : 30884 : if (!GET_MODE_WIDER_MODE (mode).exists (&mode)
1691 : 15442 : || GET_MODE_PRECISION (mode) > TYPE_PRECISION (TREE_TYPE (rhs1)))
1692 : : return false;
1693 : : }
1694 : : }
1695 : :
1696 : : /* It works, insert a truncation or sign-change before the
1697 : : float conversion. */
1698 : 1579 : tem = make_ssa_name (build_nonstandard_integer_type
1699 : 1579 : (GET_MODE_PRECISION (mode), 0));
1700 : 1579 : conv = gimple_build_assign (tem, NOP_EXPR, rhs1);
1701 : 1579 : gsi_insert_before (gsi, conv, GSI_SAME_STMT);
1702 : 1579 : gimple_assign_set_rhs1 (stmt, tem);
1703 : 1579 : fold_stmt (gsi, follow_single_use_edges);
1704 : :
1705 : 1579 : return true;
1706 : 248846 : }
1707 : :
1708 : : /* Simplify an internal fn call using ranges if possible. */
1709 : :
1710 : : bool
1711 : 352460 : simplify_using_ranges::simplify_internal_call_using_ranges
1712 : : (gimple_stmt_iterator *gsi,
1713 : : gimple *stmt)
1714 : : {
1715 : 352460 : enum tree_code subcode;
1716 : 352460 : bool is_ubsan = false;
1717 : 352460 : bool ovf = false;
1718 : 352460 : switch (gimple_call_internal_fn (stmt))
1719 : : {
1720 : : case IFN_UBSAN_CHECK_ADD:
1721 : : subcode = PLUS_EXPR;
1722 : : is_ubsan = true;
1723 : : break;
1724 : 2461 : case IFN_UBSAN_CHECK_SUB:
1725 : 2461 : subcode = MINUS_EXPR;
1726 : 2461 : is_ubsan = true;
1727 : 2461 : break;
1728 : 2122 : case IFN_UBSAN_CHECK_MUL:
1729 : 2122 : subcode = MULT_EXPR;
1730 : 2122 : is_ubsan = true;
1731 : 2122 : break;
1732 : 40185 : case IFN_ADD_OVERFLOW:
1733 : 40185 : subcode = PLUS_EXPR;
1734 : 40185 : break;
1735 : 49499 : case IFN_SUB_OVERFLOW:
1736 : 49499 : subcode = MINUS_EXPR;
1737 : 49499 : break;
1738 : 46597 : case IFN_MUL_OVERFLOW:
1739 : 46597 : subcode = MULT_EXPR;
1740 : 46597 : break;
1741 : : default:
1742 : : return false;
1743 : : }
1744 : :
1745 : 143435 : tree op0 = gimple_call_arg (stmt, 0);
1746 : 143435 : tree op1 = gimple_call_arg (stmt, 1);
1747 : 143435 : tree type;
1748 : 143435 : if (is_ubsan)
1749 : : {
1750 : 7154 : type = TREE_TYPE (op0);
1751 : 7154 : if (VECTOR_TYPE_P (type))
1752 : : return false;
1753 : : }
1754 : 136281 : else if (gimple_call_lhs (stmt) == NULL_TREE)
1755 : : return false;
1756 : : else
1757 : 136281 : type = TREE_TYPE (TREE_TYPE (gimple_call_lhs (stmt)));
1758 : 142565 : if (!check_for_binary_op_overflow (query, subcode, type, op0, op1, &ovf, stmt)
1759 : 142565 : || (is_ubsan && ovf))
1760 : : return false;
1761 : :
1762 : 3415 : gimple *g;
1763 : 3415 : location_t loc = gimple_location (stmt);
1764 : 3415 : if (is_ubsan)
1765 : 565 : g = gimple_build_assign (gimple_call_lhs (stmt), subcode, op0, op1);
1766 : : else
1767 : : {
1768 : 2850 : tree utype = type;
1769 : 2850 : if (ovf
1770 : 1367 : || !useless_type_conversion_p (type, TREE_TYPE (op0))
1771 : 3499 : || !useless_type_conversion_p (type, TREE_TYPE (op1)))
1772 : 2485 : utype = unsigned_type_for (type);
1773 : 2850 : if (TREE_CODE (op0) == INTEGER_CST)
1774 : 1174 : op0 = fold_convert (utype, op0);
1775 : 1676 : else if (!useless_type_conversion_p (utype, TREE_TYPE (op0)))
1776 : : {
1777 : 718 : g = gimple_build_assign (make_ssa_name (utype), NOP_EXPR, op0);
1778 : 718 : gimple_set_location (g, loc);
1779 : 718 : gsi_insert_before (gsi, g, GSI_SAME_STMT);
1780 : 718 : op0 = gimple_assign_lhs (g);
1781 : : }
1782 : 2850 : if (TREE_CODE (op1) == INTEGER_CST)
1783 : 1641 : op1 = fold_convert (utype, op1);
1784 : 1209 : else if (!useless_type_conversion_p (utype, TREE_TYPE (op1)))
1785 : : {
1786 : 20 : g = gimple_build_assign (make_ssa_name (utype), NOP_EXPR, op1);
1787 : 20 : gimple_set_location (g, loc);
1788 : 20 : gsi_insert_before (gsi, g, GSI_SAME_STMT);
1789 : 20 : op1 = gimple_assign_lhs (g);
1790 : : }
1791 : 2850 : g = gimple_build_assign (make_ssa_name (utype), subcode, op0, op1);
1792 : 2850 : gimple_set_location (g, loc);
1793 : 2850 : gsi_insert_before (gsi, g, GSI_SAME_STMT);
1794 : 2850 : if (utype != type)
1795 : : {
1796 : 1333 : g = gimple_build_assign (make_ssa_name (type), NOP_EXPR,
1797 : : gimple_assign_lhs (g));
1798 : 1333 : gimple_set_location (g, loc);
1799 : 1333 : gsi_insert_before (gsi, g, GSI_SAME_STMT);
1800 : : }
1801 : 2850 : g = gimple_build_assign (gimple_call_lhs (stmt), COMPLEX_EXPR,
1802 : : gimple_assign_lhs (g),
1803 : 2850 : build_int_cst (type, ovf));
1804 : : }
1805 : 3415 : gimple_set_location (g, loc);
1806 : 3415 : gsi_replace (gsi, g, false);
1807 : 3415 : return true;
1808 : : }
1809 : :
1810 : : /* Return true if VAR is a two-valued variable. Set a and b with the
1811 : : two-values when it is true. Return false otherwise. */
1812 : :
1813 : : bool
1814 : 472157 : simplify_using_ranges::two_valued_val_range_p (tree var, tree *a, tree *b,
1815 : : gimple *s)
1816 : : {
1817 : 472157 : int_range_max vr;
1818 : 472157 : if (!query->range_of_expr (vr, var, s))
1819 : : return false;
1820 : 472157 : if (vr.varying_p () || vr.undefined_p ())
1821 : : return false;
1822 : :
1823 : 740725 : if ((vr.num_pairs () == 1 && vr.upper_bound () - vr.lower_bound () == 1)
1824 : 381489 : || (vr.num_pairs () == 2
1825 : 260739 : && vr.lower_bound (0) == vr.upper_bound (0)
1826 : 219601 : && vr.lower_bound (1) == vr.upper_bound (1)))
1827 : : {
1828 : 5992 : *a = wide_int_to_tree (TREE_TYPE (var), vr.lower_bound ());
1829 : 5992 : *b = wide_int_to_tree (TREE_TYPE (var), vr.upper_bound ());
1830 : 5992 : return true;
1831 : : }
1832 : : return false;
1833 : 472157 : }
1834 : :
1835 : 12048193 : simplify_using_ranges::simplify_using_ranges (range_query *query,
1836 : 12048193 : int not_executable_flag)
1837 : 12048193 : : query (query)
1838 : : {
1839 : 12048193 : to_remove_edges = vNULL;
1840 : 12048193 : to_update_switch_stmts = vNULL;
1841 : 12048193 : m_not_executable_flag = not_executable_flag;
1842 : 12048193 : m_flag_set_edges = vNULL;
1843 : 12048193 : }
1844 : :
1845 : 12048193 : simplify_using_ranges::~simplify_using_ranges ()
1846 : : {
1847 : 12048193 : cleanup_edges_and_switches ();
1848 : 12048193 : m_flag_set_edges.release ();
1849 : 12048193 : }
1850 : :
1851 : : /* Simplify STMT using ranges if possible. */
1852 : :
1853 : : bool
1854 : 207859248 : simplify_using_ranges::simplify (gimple_stmt_iterator *gsi)
1855 : : {
1856 : 207859248 : gcc_checking_assert (query);
1857 : :
1858 : 207859248 : gimple *stmt = gsi_stmt (*gsi);
1859 : 207859248 : if (is_gimple_assign (stmt))
1860 : : {
1861 : 62678767 : enum tree_code rhs_code = gimple_assign_rhs_code (stmt);
1862 : 62678767 : tree rhs1 = gimple_assign_rhs1 (stmt);
1863 : 62678767 : tree rhs2 = gimple_assign_rhs2 (stmt);
1864 : 62678767 : tree lhs = gimple_assign_lhs (stmt);
1865 : 62678767 : tree val1 = NULL_TREE, val2 = NULL_TREE;
1866 : 62678767 : use_operand_p use_p;
1867 : 62678767 : gimple *use_stmt;
1868 : :
1869 : : /* Convert:
1870 : : LHS = CST BINOP VAR
1871 : : Where VAR is two-valued and LHS is used in GIMPLE_COND only
1872 : : To:
1873 : : LHS = VAR == VAL1 ? (CST BINOP VAL1) : (CST BINOP VAL2)
1874 : :
1875 : : Also handles:
1876 : : LHS = VAR BINOP CST
1877 : : Where VAR is two-valued and LHS is used in GIMPLE_COND only
1878 : : To:
1879 : : LHS = VAR == VAL1 ? (VAL1 BINOP CST) : (VAL2 BINOP CST) */
1880 : :
1881 : 62678767 : if (TREE_CODE_CLASS (rhs_code) == tcc_binary
1882 : 13253297 : && INTEGRAL_TYPE_P (TREE_TYPE (rhs1))
1883 : 9422515 : && ((TREE_CODE (rhs1) == INTEGER_CST
1884 : 163973 : && TREE_CODE (rhs2) == SSA_NAME)
1885 : 9259141 : || (TREE_CODE (rhs2) == INTEGER_CST
1886 : 6157893 : && TREE_CODE (rhs1) == SSA_NAME))
1887 : 6320668 : && single_imm_use (lhs, &use_p, &use_stmt)
1888 : 67548420 : && gimple_code (use_stmt) == GIMPLE_COND)
1889 : :
1890 : : {
1891 : 472157 : tree new_rhs1 = NULL_TREE;
1892 : 472157 : tree new_rhs2 = NULL_TREE;
1893 : 472157 : tree cmp_var = NULL_TREE;
1894 : :
1895 : 472157 : if (TREE_CODE (rhs2) == SSA_NAME
1896 : 472157 : && two_valued_val_range_p (rhs2, &val1, &val2, stmt))
1897 : : {
1898 : : /* Optimize RHS1 OP [VAL1, VAL2]. */
1899 : 192 : new_rhs1 = int_const_binop (rhs_code, rhs1, val1);
1900 : 192 : new_rhs2 = int_const_binop (rhs_code, rhs1, val2);
1901 : 192 : cmp_var = rhs2;
1902 : : }
1903 : 471965 : else if (TREE_CODE (rhs1) == SSA_NAME
1904 : 471965 : && two_valued_val_range_p (rhs1, &val1, &val2, stmt))
1905 : : {
1906 : : /* Optimize [VAL1, VAL2] OP RHS2. */
1907 : 5800 : new_rhs1 = int_const_binop (rhs_code, val1, rhs2);
1908 : 5800 : new_rhs2 = int_const_binop (rhs_code, val2, rhs2);
1909 : 5800 : cmp_var = rhs1;
1910 : : }
1911 : :
1912 : : /* If we could not find two-vals or the optimzation is invalid as
1913 : : in divide by zero, new_rhs1 / new_rhs will be NULL_TREE. */
1914 : 472157 : if (new_rhs1 && new_rhs2)
1915 : : {
1916 : 5992 : tree cond = gimple_build (gsi, true, GSI_SAME_STMT,
1917 : : UNKNOWN_LOCATION,
1918 : : EQ_EXPR, boolean_type_node,
1919 : : cmp_var, val1);
1920 : 5992 : gimple_assign_set_rhs_with_ops (gsi,
1921 : : COND_EXPR, cond,
1922 : : new_rhs1,
1923 : : new_rhs2);
1924 : 5992 : update_stmt (gsi_stmt (*gsi));
1925 : 5992 : fold_stmt (gsi, follow_single_use_edges);
1926 : 7893246 : return true;
1927 : : }
1928 : : }
1929 : :
1930 : 62672775 : if (TREE_CODE_CLASS (rhs_code) == tcc_comparison)
1931 : 1174838 : return simplify_compare_assign_using_ranges_1 (gsi, stmt);
1932 : :
1933 : 61497937 : switch (rhs_code)
1934 : : {
1935 : :
1936 : : /* Transform TRUNC_DIV_EXPR and TRUNC_MOD_EXPR into RSHIFT_EXPR
1937 : : and BIT_AND_EXPR respectively if the first operand is greater
1938 : : than zero and the second operand is an exact power of two.
1939 : : Also optimize TRUNC_MOD_EXPR away if the second operand is
1940 : : constant and the first operand already has the right value
1941 : : range. */
1942 : 318977 : case TRUNC_DIV_EXPR:
1943 : 318977 : case TRUNC_MOD_EXPR:
1944 : 318977 : if ((TREE_CODE (rhs1) == SSA_NAME
1945 : 318977 : || TREE_CODE (rhs1) == INTEGER_CST)
1946 : 318977 : && INTEGRAL_TYPE_P (TREE_TYPE (rhs1)))
1947 : 317763 : return simplify_div_or_mod_using_ranges (gsi, stmt);
1948 : : break;
1949 : :
1950 : : /* Transform ABS (X) into X or -X as appropriate. */
1951 : 51297 : case ABS_EXPR:
1952 : 51297 : if (TREE_CODE (rhs1) == SSA_NAME
1953 : 51297 : && INTEGRAL_TYPE_P (TREE_TYPE (rhs1)))
1954 : 6556 : return simplify_abs_using_ranges (gsi, stmt);
1955 : : break;
1956 : :
1957 : 1284241 : case BIT_AND_EXPR:
1958 : 1284241 : case BIT_IOR_EXPR:
1959 : : /* Optimize away BIT_AND_EXPR and BIT_IOR_EXPR
1960 : : if all the bits being cleared are already cleared or
1961 : : all the bits being set are already set. */
1962 : 1284241 : if (INTEGRAL_TYPE_P (TREE_TYPE (rhs1)))
1963 : 1254834 : return simplify_bit_ops_using_ranges (gsi, stmt);
1964 : : break;
1965 : :
1966 : 5702420 : CASE_CONVERT:
1967 : 5702420 : if (TREE_CODE (rhs1) == SSA_NAME
1968 : 5702420 : && INTEGRAL_TYPE_P (TREE_TYPE (rhs1)))
1969 : 4640388 : return simplify_conversion_using_ranges (gsi, stmt);
1970 : : break;
1971 : :
1972 : 251044 : case FLOAT_EXPR:
1973 : 251044 : if (TREE_CODE (rhs1) == SSA_NAME
1974 : 251044 : && INTEGRAL_TYPE_P (TREE_TYPE (rhs1)))
1975 : 248846 : return simplify_float_conversion_using_ranges (gsi, stmt);
1976 : : break;
1977 : :
1978 : 173043 : case MIN_EXPR:
1979 : 173043 : case MAX_EXPR:
1980 : 173043 : if (INTEGRAL_TYPE_P (TREE_TYPE (rhs1)))
1981 : 167816 : return simplify_min_or_max_using_ranges (gsi, stmt);
1982 : : break;
1983 : :
1984 : 358443 : case RSHIFT_EXPR:
1985 : 358443 : {
1986 : 358443 : tree op0 = gimple_assign_rhs1 (stmt);
1987 : 358443 : tree type = TREE_TYPE (op0);
1988 : 358443 : int_range_max range;
1989 : 358443 : if (TYPE_SIGN (type) == SIGNED
1990 : 358443 : && query->range_of_expr (range, op0, stmt))
1991 : : {
1992 : 76213 : unsigned prec = TYPE_PRECISION (TREE_TYPE (op0));
1993 : 152426 : int_range<2> nzm1 (type, wi::minus_one (prec), wi::zero (prec),
1994 : 152434 : VR_ANTI_RANGE);
1995 : 76213 : range.intersect (nzm1);
1996 : : // If there are no ranges other than [-1, 0] remove the shift.
1997 : 76213 : if (range.undefined_p ())
1998 : : {
1999 : 42 : gimple_assign_set_rhs_from_tree (gsi, op0);
2000 : 42 : return true;
2001 : : }
2002 : : return false;
2003 : 76213 : }
2004 : 282230 : break;
2005 : 358443 : }
2006 : : default:
2007 : : break;
2008 : : }
2009 : : }
2010 : 145180481 : else if (gimple_code (stmt) == GIMPLE_COND)
2011 : 11144672 : return simplify_cond_using_ranges_1 (as_a <gcond *> (stmt));
2012 : 134035809 : else if (gimple_code (stmt) == GIMPLE_SWITCH)
2013 : 57947 : return simplify_switch_using_ranges (as_a <gswitch *> (stmt));
2014 : 133977862 : else if (is_gimple_call (stmt)
2015 : 133977862 : && gimple_call_internal_p (stmt))
2016 : 352460 : return simplify_internal_call_using_ranges (gsi, stmt);
2017 : :
2018 : : return false;
2019 : : }
|