Branch data Line data Source code
1 : : /* Support routines for Value Range Propagation (VRP).
2 : : Copyright (C) 2005-2025 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 : 467756 : simplify_using_ranges::op_with_boolean_value_range_p (tree op, gimple *s)
59 : : {
60 : 467756 : if (TYPE_PRECISION (TREE_TYPE (op)) == 1)
61 : : return true;
62 : :
63 : 455330 : if (integer_zerop (op)
64 : 455330 : || integer_onep (op))
65 : 9305 : return true;
66 : :
67 : 446025 : 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 : 446025 : int_range_max vr;
73 : 446025 : return (query->range_of_expr (vr, op, s)
74 : 446025 : && vr == range_true_and_false (TREE_TYPE (op)));
75 : 446025 : }
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 : 142570 : 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 : 142570 : relation_kind rel = VREL_VARYING;
89 : : /* For subtraction see if relations could simplify it. */
90 : 142570 : if (s
91 : 142570 : && subcode == MINUS_EXPR
92 : 142570 : && types_compatible_p (TREE_TYPE (op0), TREE_TYPE (op1)))
93 : : {
94 : 28778 : 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 : 28778 : if (rel == VREL_EQ)
99 : : return true;
100 : : }
101 : :
102 : 142569 : int_range_max vr0, vr1;
103 : 142569 : if (!query->range_of_expr (vr0, op0, s) || vr0.undefined_p ())
104 : 12 : vr0.set_varying (TREE_TYPE (op0));
105 : 142569 : if (!query->range_of_expr (vr1, op1, s) || vr1.undefined_p ())
106 : 4 : vr1.set_varying (TREE_TYPE (op1));
107 : :
108 : 142569 : tree vr0min = wide_int_to_tree (TREE_TYPE (op0), vr0.lower_bound ());
109 : 142569 : tree vr0max = wide_int_to_tree (TREE_TYPE (op0), vr0.upper_bound ());
110 : 142569 : tree vr1min = wide_int_to_tree (TREE_TYPE (op1), vr1.lower_bound ());
111 : 142569 : 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 : 142569 : if ((rel == VREL_GT || rel == VREL_GE)
117 : 10 : && tree_int_cst_sgn (vr1min) >= 0
118 : 142576 : && !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 : 142562 : if (rel == VREL_LT
125 : 1 : && tree_int_cst_sgn (vr1min) >= 0
126 : 142563 : && TYPE_UNSIGNED (type))
127 : : {
128 : 1 : *ovf = true;
129 : 1 : return true;
130 : : }
131 : :
132 : 233574 : *ovf = arith_overflowed_p (subcode, type, vr0min,
133 : : subcode == MINUS_EXPR ? vr1max : vr1min);
134 : 233574 : if (arith_overflowed_p (subcode, type, vr0max,
135 : 142561 : subcode == MINUS_EXPR ? vr1min : vr1max) != *ovf)
136 : : return false;
137 : 39232 : if (subcode == MULT_EXPR)
138 : : {
139 : 23862 : if (arith_overflowed_p (subcode, type, vr0min, vr1max) != *ovf
140 : 23862 : || arith_overflowed_p (subcode, type, vr0max, vr1min) != *ovf)
141 : 376 : return false;
142 : : }
143 : 38856 : 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 : 36923 : widest2_int wmin, wmax;
151 : 332345 : widest2_int w[4];
152 : 36923 : int i;
153 : 36923 : signop sign0 = TYPE_SIGN (TREE_TYPE (op0));
154 : 36923 : signop sign1 = TYPE_SIGN (TREE_TYPE (op1));
155 : 36937 : w[0] = widest2_int::from (vr0.lower_bound (), sign0);
156 : 36937 : w[1] = widest2_int::from (vr0.upper_bound (), sign0);
157 : 36928 : w[2] = widest2_int::from (vr1.lower_bound (), sign1);
158 : 36928 : w[3] = widest2_int::from (vr1.upper_bound (), sign1);
159 : 184615 : for (i = 0; i < 4; i++)
160 : : {
161 : 147692 : widest2_int wt;
162 : 147692 : switch (subcode)
163 : : {
164 : 26732 : case PLUS_EXPR:
165 : 26732 : wt = wi::add (w[i & 1], w[2 + (i & 2) / 2]);
166 : 26732 : break;
167 : 27624 : case MINUS_EXPR:
168 : 27624 : wt = wi::sub (w[i & 1], w[2 + (i & 2) / 2]);
169 : 27624 : break;
170 : 93336 : case MULT_EXPR:
171 : 93336 : wt = wi::mul (w[i & 1], w[2 + (i & 2) / 2]);
172 : 93336 : break;
173 : 0 : default:
174 : 0 : gcc_unreachable ();
175 : : }
176 : 147692 : if (i == 0)
177 : : {
178 : 36923 : wmin = wt;
179 : 36923 : wmax = wt;
180 : : }
181 : : else
182 : : {
183 : 110769 : wmin = wi::smin (wmin, wt);
184 : 111425 : wmax = wi::smax (wmax, wt);
185 : : }
186 : 147692 : }
187 : : /* The result of op0 CODE op1 is known to be in range
188 : : [wmin, wmax]. */
189 : 36923 : widest2_int wtmin
190 : 73846 : = widest2_int::from (irange_val_min (type), TYPE_SIGN (type));
191 : 36923 : widest2_int wtmax
192 : 73846 : = 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 : 72836 : if (wmax < wtmin || wmin > wtmax)
197 : 1652 : return true;
198 : : return false;
199 : 221748 : }
200 : : return true;
201 : 142569 : }
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 : 5982047 : get_scev_info (vrange &r, tree name, gimple *stmt, class loop *l,
209 : : tree &init, tree &step, enum ev_direction &dir)
210 : : {
211 : 5982047 : tree ev = analyze_scalar_evolution (l, name);
212 : 5982047 : tree chrec = instantiate_parameters (l, ev);
213 : 5982047 : tree type = TREE_TYPE (name);
214 : 5982047 : if (TREE_CODE (chrec) != POLYNOMIAL_CHREC)
215 : : {
216 : 2962553 : r.set_varying (type);
217 : 2962553 : return false;
218 : : }
219 : 3019494 : 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 : 3019494 : init = initial_condition_in_loop_num (chrec, l->num);
229 : 3019494 : step = evolution_part_in_loop_num (chrec, l->num);
230 : 3019494 : if (!init || !step)
231 : : {
232 : 0 : r.set_varying (type);
233 : 0 : return false;
234 : : }
235 : 3019494 : dir = scev_direction (chrec);
236 : 3019494 : if (dir == EV_DIR_UNKNOWN
237 : 3019494 : || scev_probably_wraps_p (NULL, init, step, stmt,
238 : : get_chrec_loop (chrec), true))
239 : : {
240 : 696077 : r.set_varying (type);
241 : 696077 : 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 : 1991093 : induction_variable_may_overflow_p (tree type,
250 : : const wide_int &step, const widest_int &nit)
251 : : {
252 : 1991093 : wi::overflow_type ovf;
253 : 1991093 : signop sign = TYPE_SIGN (type);
254 : 1991093 : widest_int max_step = wi::mul (widest_int::from (step, sign),
255 : 1991093 : nit, sign, &ovf);
256 : :
257 : 1991093 : if (ovf || !wi::fits_to_tree_p (max_step, type))
258 : 21712 : 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 : 1969381 : return (sign == SIGNED
264 : 3938420 : && wi::gts_p (max_step, 0) != wi::gts_p (step, 0));
265 : 1991093 : }
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 : 2323078 : range_from_loop_direction (irange &r, tree type,
272 : : const irange &begin, const irange &end,
273 : : ev_direction dir)
274 : : {
275 : 2323078 : signop sign = TYPE_SIGN (type);
276 : :
277 : 2323078 : if (begin.undefined_p () || end.undefined_p ())
278 : 2976 : r.set_varying (type);
279 : 2320102 : else if (dir == EV_DIR_GROWS)
280 : : {
281 : 2170587 : if (wi::gt_p (begin.lower_bound (), end.upper_bound (), sign))
282 : 247 : r.set_varying (type);
283 : : else
284 : 2170340 : r = int_range<1> (type, begin.lower_bound (), end.upper_bound ());
285 : : }
286 : : else
287 : : {
288 : 149523 : if (wi::gt_p (end.lower_bound (), begin.upper_bound (), sign))
289 : 80 : r.set_varying (type);
290 : : else
291 : 149443 : r = int_range<1> (type, end.lower_bound (), begin.upper_bound ());
292 : : }
293 : 2323078 : }
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 : 5982047 : range_of_var_in_loop (vrange &v, tree name, class loop *l, gimple *stmt,
300 : : range_query *query)
301 : : {
302 : 5982047 : tree init, step;
303 : 5982047 : enum ev_direction dir;
304 : 5982047 : if (!get_scev_info (v, name, stmt, l, init, step, dir))
305 : : return true;
306 : :
307 : : // Calculate ranges for the values from SCEV.
308 : 2323417 : irange &r = as_a <irange> (v);
309 : 2323417 : tree type = TREE_TYPE (init);
310 : 2323417 : int_range<2> rinit (type), rstep (type), max_init (type);
311 : 2323417 : if (!query->range_of_expr (rinit, init, stmt)
312 : 2323417 : || !query->range_of_expr (rstep, step, stmt))
313 : 0 : return false;
314 : :
315 : : // Calculate the final range of NAME if possible.
316 : 2323417 : if (rinit.singleton_p () && rstep.singleton_p ())
317 : : {
318 : 1991432 : widest_int nit;
319 : 1991432 : if (!max_loop_iterations (l, &nit))
320 : : return false;
321 : :
322 : 1991093 : if (!induction_variable_may_overflow_p (type, rstep.lower_bound (), nit))
323 : : {
324 : : // Calculate the max bounds for init (init + niter * step).
325 : 1969039 : wide_int w = wide_int::from (nit, TYPE_PRECISION (type), TYPE_SIGN (type));
326 : 1969039 : int_range<1> niter (type, w, w);
327 : 1969039 : int_range_max max_step;
328 : 1969039 : range_op_handler mult_handler (MULT_EXPR);
329 : 1969039 : range_op_handler plus_handler (PLUS_EXPR);
330 : 1969039 : if (!mult_handler.fold_range (max_step, type, niter, rstep)
331 : 1969039 : || !plus_handler.fold_range (max_init, type, rinit, max_step))
332 : 0 : return false;
333 : 1969039 : }
334 : 1991432 : }
335 : 2323078 : range_from_loop_direction (r, type, rinit, max_init, dir);
336 : 2323078 : return true;
337 : 2323417 : }
338 : :
339 : : /* Helper function for vrp_evaluate_conditional_warnv & other
340 : : optimizers. */
341 : :
342 : : tree
343 : 18640441 : simplify_using_ranges::fold_cond_with_ops (enum tree_code code,
344 : : tree op0, tree op1, gimple *s)
345 : : {
346 : 18640441 : value_range r0 (TREE_TYPE (op0));
347 : 18640441 : value_range r1 (TREE_TYPE (op1));
348 : 18640441 : if (!query->range_of_expr (r0, op0, s)
349 : 18640441 : || !query->range_of_expr (r1, op1, s))
350 : 5826 : return NULL_TREE;
351 : :
352 : 18634615 : int_range<1> res;
353 : 18634615 : range_op_handler handler (code);
354 : :
355 : : // Find any relation between op0 and op1 and pass it to fold_range.
356 : 18634615 : relation_kind rel = VREL_VARYING;
357 : 18634615 : if (gimple_range_ssa_p (op0) && gimple_range_ssa_p (op1))
358 : 4038745 : rel = query->relation ().query (s, op0, op1);
359 : :
360 : 18634615 : if (handler && handler.fold_range (res, boolean_type_node, r0, r1,
361 : 18634615 : relation_trio::op1_op2 (rel)))
362 : : {
363 : 18634615 : if (res == range_true ())
364 : 7917 : return boolean_true_node;
365 : 18626698 : if (res == range_false ())
366 : 4188 : return boolean_false_node;
367 : : }
368 : : return NULL;
369 : 18640441 : }
370 : :
371 : : /* Helper function for legacy_fold_cond. */
372 : :
373 : : tree
374 : 19072602 : simplify_using_ranges::legacy_fold_cond_overflow (gimple *stmt)
375 : : {
376 : 19072602 : tree ret;
377 : 19072602 : tree_code code = gimple_cond_code (stmt);
378 : 19072602 : tree op0 = gimple_cond_lhs (stmt);
379 : 19072602 : tree op1 = gimple_cond_rhs (stmt);
380 : :
381 : : /* We only deal with integral and pointer types. */
382 : 37790657 : if (!INTEGRAL_TYPE_P (TREE_TYPE (op0))
383 : 23081618 : && !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 : 18253397 : tree x;
395 : 18253397 : if (overflow_comparison_p (code, op0, op1, &x))
396 : : {
397 : 1147 : 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 : 1147 : if (integer_zerop (x))
403 : : {
404 : 162 : op1 = x;
405 : 162 : 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 : 985 : else if (wi::to_wide (x) == max - 1)
412 : : {
413 : 667 : op0 = op1;
414 : 667 : op1 = wide_int_to_tree (TREE_TYPE (op0), 0);
415 : 667 : code = (code == GT_EXPR || code == GE_EXPR) ? EQ_EXPR : NE_EXPR;
416 : : }
417 : : else
418 : : {
419 : 318 : int_range_max vro, vri;
420 : 318 : tree type = TREE_TYPE (op0);
421 : 318 : if (code == GT_EXPR || code == GE_EXPR)
422 : : {
423 : 118 : vro.set (type,
424 : 236 : wi::to_wide (TYPE_MIN_VALUE (type)),
425 : 118 : wi::to_wide (x), VR_ANTI_RANGE);
426 : 118 : vri.set (type,
427 : 236 : wi::to_wide (TYPE_MIN_VALUE (type)),
428 : 236 : wi::to_wide (x));
429 : : }
430 : 200 : else if (code == LT_EXPR || code == LE_EXPR)
431 : : {
432 : 200 : vro.set (type,
433 : 400 : wi::to_wide (TYPE_MIN_VALUE (type)),
434 : 200 : wi::to_wide (x));
435 : 200 : vri.set (type,
436 : 400 : wi::to_wide (TYPE_MIN_VALUE (type)),
437 : 400 : wi::to_wide (x),
438 : : VR_ANTI_RANGE);
439 : : }
440 : : else
441 : 0 : gcc_unreachable ();
442 : 318 : int_range_max vr0;
443 : 318 : 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 : 318 : vro.intersect (vr0);
456 : 318 : if (vro.undefined_p ())
457 : 8 : return boolean_false_node;
458 : 310 : vri.intersect (vr0);
459 : 310 : if (vri.undefined_p ())
460 : 0 : return boolean_true_node;
461 : 318 : }
462 : 1147 : }
463 : :
464 : 18253389 : 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 : 19072602 : simplify_using_ranges::legacy_fold_cond (gcond *stmt, edge *taken_edge_p)
475 : : {
476 : 19072602 : tree val;
477 : :
478 : 19072602 : *taken_edge_p = NULL;
479 : :
480 : 19072602 : if (dump_file && (dump_flags & TDF_DETAILS))
481 : : {
482 : 348 : tree use;
483 : 348 : ssa_op_iter i;
484 : :
485 : 348 : fprintf (dump_file, "\nVisiting conditional with predicate: ");
486 : 348 : print_gimple_stmt (dump_file, stmt, 0);
487 : 348 : fprintf (dump_file, "\nWith known ranges\n");
488 : :
489 : 786 : FOR_EACH_SSA_TREE_OPERAND (use, stmt, i, SSA_OP_USE)
490 : : {
491 : 438 : fprintf (dump_file, "\t");
492 : 438 : print_generic_expr (dump_file, use);
493 : 438 : fprintf (dump_file, ": ");
494 : 438 : value_range r (TREE_TYPE (use));
495 : 438 : query->range_of_expr (r, use, stmt);
496 : 438 : r.dump (dump_file);
497 : 438 : }
498 : :
499 : 348 : fprintf (dump_file, "\n");
500 : : }
501 : :
502 : 19072602 : val = legacy_fold_cond_overflow (stmt);
503 : 19072602 : if (val)
504 : 8 : *taken_edge_p = find_taken_edge (gimple_bb (stmt), val);
505 : :
506 : 19072602 : if (dump_file && (dump_flags & TDF_DETAILS))
507 : : {
508 : 348 : fprintf (dump_file, "\nPredicate evaluates to: ");
509 : 348 : if (val == NULL_TREE)
510 : 348 : fprintf (dump_file, "DON'T KNOW\n");
511 : : else
512 : 0 : print_generic_stmt (dump_file, val);
513 : : }
514 : 19072602 : }
515 : :
516 : : /* Searches the case label vector VEC for the ranges of CASE_LABELs that are
517 : : used in range VR. The indices are placed in MIN_IDX1, MAX_IDX, MIN_IDX2 and
518 : : MAX_IDX2. If the ranges of CASE_LABELs are empty then MAX_IDX1 < MIN_IDX1.
519 : : Returns true if the default label is not needed. */
520 : :
521 : : static bool
522 : 15484 : find_case_label_ranges (gswitch *stmt, const irange *vr,
523 : : size_t *min_idx1, size_t *max_idx1,
524 : : size_t *min_idx2, size_t *max_idx2)
525 : : {
526 : 15484 : size_t i, j, k, l;
527 : 15484 : unsigned int n = gimple_switch_num_labels (stmt);
528 : 15484 : bool take_default;
529 : 15484 : tree case_low, case_high;
530 : 15484 : tree min, max;
531 : 15484 : value_range_kind kind = get_legacy_range (*vr, min, max);
532 : :
533 : 15484 : gcc_checking_assert (!vr->varying_p () && !vr->undefined_p ());
534 : :
535 : 15484 : take_default = !find_case_label_range (stmt, min, max, &i, &j);
536 : :
537 : : /* Set second range to empty. */
538 : 15484 : *min_idx2 = 1;
539 : 15484 : *max_idx2 = 0;
540 : :
541 : 15484 : if (kind == VR_RANGE)
542 : : {
543 : 13169 : *min_idx1 = i;
544 : 13169 : *max_idx1 = j;
545 : 13169 : return !take_default;
546 : : }
547 : :
548 : : /* Set first range to all case labels. */
549 : 2315 : *min_idx1 = 1;
550 : 2315 : *max_idx1 = n - 1;
551 : :
552 : 2315 : if (i > j)
553 : : return false;
554 : :
555 : : /* Make sure all the values of case labels [i , j] are contained in
556 : : range [MIN, MAX]. */
557 : 114 : case_low = CASE_LOW (gimple_switch_label (stmt, i));
558 : 114 : case_high = CASE_HIGH (gimple_switch_label (stmt, j));
559 : 114 : if (tree_int_cst_compare (case_low, min) < 0)
560 : 4 : i += 1;
561 : 114 : if (case_high != NULL_TREE
562 : 114 : && tree_int_cst_compare (max, case_high) < 0)
563 : 6 : j -= 1;
564 : :
565 : 114 : if (i > j)
566 : : return false;
567 : :
568 : : /* If the range spans case labels [i, j], the corresponding anti-range spans
569 : : the labels [1, i - 1] and [j + 1, n - 1]. */
570 : 107 : k = j + 1;
571 : 107 : l = n - 1;
572 : 107 : if (k > l)
573 : : {
574 : 22 : k = 1;
575 : 22 : l = 0;
576 : : }
577 : :
578 : 107 : j = i - 1;
579 : 107 : i = 1;
580 : 107 : if (i > j)
581 : : {
582 : 56 : i = k;
583 : 56 : j = l;
584 : 56 : k = 1;
585 : 56 : l = 0;
586 : : }
587 : :
588 : 107 : *min_idx1 = i;
589 : 107 : *max_idx1 = j;
590 : 107 : *min_idx2 = k;
591 : 107 : *max_idx2 = l;
592 : 107 : return false;
593 : : }
594 : :
595 : : /* Simplify boolean operations if the source is known
596 : : to be already a boolean. */
597 : : bool
598 : 451799 : simplify_using_ranges::simplify_truth_ops_using_ranges
599 : : (gimple_stmt_iterator *gsi,
600 : : gimple *stmt)
601 : : {
602 : 451799 : enum tree_code rhs_code = gimple_assign_rhs_code (stmt);
603 : 451799 : tree lhs, op0, op1;
604 : 451799 : bool need_conversion;
605 : :
606 : : /* We handle only !=/== case here. */
607 : 451799 : gcc_assert (rhs_code == EQ_EXPR || rhs_code == NE_EXPR);
608 : :
609 : 451799 : op0 = gimple_assign_rhs1 (stmt);
610 : 451799 : if (!op_with_boolean_value_range_p (op0, stmt))
611 : : return false;
612 : :
613 : 15957 : op1 = gimple_assign_rhs2 (stmt);
614 : 15957 : if (!op_with_boolean_value_range_p (op1, stmt))
615 : : return false;
616 : :
617 : : /* Reduce number of cases to handle to NE_EXPR. As there is no
618 : : BIT_XNOR_EXPR we cannot replace A == B with a single statement. */
619 : 15565 : if (rhs_code == EQ_EXPR)
620 : : {
621 : 7387 : if (TREE_CODE (op1) == INTEGER_CST)
622 : 3078 : op1 = int_const_binop (BIT_XOR_EXPR, op1,
623 : 6156 : build_int_cst (TREE_TYPE (op1), 1));
624 : : else
625 : : return false;
626 : : }
627 : :
628 : 11256 : lhs = gimple_assign_lhs (stmt);
629 : 11256 : need_conversion
630 : 11256 : = !useless_type_conversion_p (TREE_TYPE (lhs), TREE_TYPE (op0));
631 : :
632 : : /* Make sure to not sign-extend a 1-bit 1 when converting the result. */
633 : 11256 : if (need_conversion
634 : 9773 : && !TYPE_UNSIGNED (TREE_TYPE (op0))
635 : 4369 : && TYPE_PRECISION (TREE_TYPE (op0)) == 1
636 : 11285 : && TYPE_PRECISION (TREE_TYPE (lhs)) > 1)
637 : : return false;
638 : :
639 : : /* For A != 0 we can substitute A itself. */
640 : 11256 : if (integer_zerop (op1))
641 : 6972 : gimple_assign_set_rhs_with_ops (gsi,
642 : : need_conversion
643 : 0 : ? NOP_EXPR : TREE_CODE (op0), op0);
644 : : /* For A != B we substitute A ^ B. Either with conversion. */
645 : 4284 : else if (need_conversion)
646 : : {
647 : 2801 : tree tem = make_ssa_name (TREE_TYPE (op0));
648 : 2801 : gassign *newop
649 : 2801 : = gimple_build_assign (tem, BIT_XOR_EXPR, op0, op1);
650 : 2801 : gsi_insert_before (gsi, newop, GSI_SAME_STMT);
651 : 5579 : if (INTEGRAL_TYPE_P (TREE_TYPE (tem))
652 : 5579 : && TYPE_PRECISION (TREE_TYPE (tem)) > 1)
653 : : {
654 : 5424 : int_range<1> vr (TREE_TYPE (tem),
655 : 2712 : wi::zero (TYPE_PRECISION (TREE_TYPE (tem))),
656 : 5424 : wi::one (TYPE_PRECISION (TREE_TYPE (tem))));
657 : 2712 : set_range_info (tem, vr);
658 : 2712 : }
659 : 2801 : gimple_assign_set_rhs_with_ops (gsi, NOP_EXPR, tem);
660 : : }
661 : : /* Or without. */
662 : : else
663 : 1483 : gimple_assign_set_rhs_with_ops (gsi, BIT_XOR_EXPR, op0, op1);
664 : 11256 : update_stmt (gsi_stmt (*gsi));
665 : 11256 : fold_stmt (gsi, follow_single_use_edges);
666 : :
667 : 11256 : return true;
668 : : }
669 : :
670 : : /* Simplify a division or modulo operator to a right shift or bitwise and
671 : : if the first operand is unsigned or is greater than zero and the second
672 : : operand is an exact power of two. For TRUNC_MOD_EXPR op0 % op1 with
673 : : constant op1 (op1min = op1) or with op1 in [op1min, op1max] range,
674 : : optimize it into just op0 if op0's range is known to be a subset of
675 : : [-op1min + 1, op1min - 1] for signed and [0, op1min - 1] for unsigned
676 : : modulo. */
677 : :
678 : : bool
679 : 309745 : simplify_using_ranges::simplify_div_or_mod_using_ranges
680 : : (gimple_stmt_iterator *gsi,
681 : : gimple *stmt)
682 : : {
683 : 309745 : enum tree_code rhs_code = gimple_assign_rhs_code (stmt);
684 : 309745 : tree val = NULL;
685 : 309745 : tree op0 = gimple_assign_rhs1 (stmt);
686 : 309745 : tree op1 = gimple_assign_rhs2 (stmt);
687 : 309745 : tree op0min = NULL_TREE, op0max = NULL_TREE;
688 : 309745 : tree op1min = op1;
689 : 309745 : int_range_max vr;
690 : :
691 : 309745 : if (TREE_CODE (op0) == INTEGER_CST)
692 : : {
693 : : op0min = op0;
694 : : op0max = op0;
695 : : }
696 : : else
697 : : {
698 : 285745 : if (!query->range_of_expr (vr, op0, stmt))
699 : 0 : vr.set_varying (TREE_TYPE (op0));
700 : 285745 : if (!vr.varying_p () && !vr.undefined_p ())
701 : : {
702 : 136924 : tree type = vr.type ();
703 : 136924 : op0min = wide_int_to_tree (type, vr.lower_bound ());
704 : 136933 : op0max = wide_int_to_tree (type, vr.upper_bound ());
705 : : }
706 : : }
707 : :
708 : 309745 : if (rhs_code == TRUNC_MOD_EXPR
709 : 140937 : && TREE_CODE (op1) == SSA_NAME)
710 : : {
711 : 81790 : int_range_max vr1;
712 : 81790 : if (!query->range_of_expr (vr1, op1, stmt))
713 : 0 : vr1.set_varying (TREE_TYPE (op1));
714 : 81790 : if (!vr1.varying_p () && !vr1.undefined_p ())
715 : 24133 : op1min = wide_int_to_tree (vr1.type (), vr1.lower_bound ());
716 : 81790 : }
717 : 140937 : if (rhs_code == TRUNC_MOD_EXPR
718 : 140937 : && TREE_CODE (op1min) == INTEGER_CST
719 : 83276 : && tree_int_cst_sgn (op1min) == 1
720 : 63669 : && op0max
721 : 36797 : && tree_int_cst_lt (op0max, op1min))
722 : : {
723 : 1134 : if (TYPE_UNSIGNED (TREE_TYPE (op0))
724 : 452 : || tree_int_cst_sgn (op0min) >= 0
725 : 1313 : || tree_int_cst_lt (fold_unary (NEGATE_EXPR, TREE_TYPE (op1min), op1min),
726 : : op0min))
727 : : {
728 : : /* If op0 already has the range op0 % op1 has,
729 : : then TRUNC_MOD_EXPR won't change anything. */
730 : 1100 : gimple_assign_set_rhs_from_tree (gsi, op0);
731 : 1100 : return true;
732 : : }
733 : : }
734 : :
735 : 308645 : if (TREE_CODE (op0) != SSA_NAME)
736 : : return false;
737 : :
738 : 284652 : if (!integer_pow2p (op1))
739 : : {
740 : : /* X % -Y can be only optimized into X % Y either if
741 : : X is not INT_MIN, or Y is not -1. Fold it now, as after
742 : : remove_range_assertions the range info might be not available
743 : : anymore. */
744 : 250533 : if (rhs_code == TRUNC_MOD_EXPR
745 : 250533 : && fold_stmt (gsi, follow_single_use_edges))
746 : : return true;
747 : 250533 : return false;
748 : : }
749 : :
750 : 34119 : if (TYPE_UNSIGNED (TREE_TYPE (op0)))
751 : 0 : val = integer_one_node;
752 : : else
753 : : {
754 : 34119 : tree zero = build_zero_cst (TREE_TYPE (op0));
755 : 34119 : val = fold_cond_with_ops (GE_EXPR, op0, zero, stmt);
756 : : }
757 : :
758 : 34119 : if (val && integer_onep (val))
759 : : {
760 : 5282 : tree t;
761 : :
762 : 5282 : if (rhs_code == TRUNC_DIV_EXPR)
763 : : {
764 : 2922 : t = build_int_cst (integer_type_node, tree_log2 (op1));
765 : 2922 : gimple_assign_set_rhs_code (stmt, RSHIFT_EXPR);
766 : 2922 : gimple_assign_set_rhs1 (stmt, op0);
767 : 2922 : gimple_assign_set_rhs2 (stmt, t);
768 : : }
769 : : else
770 : : {
771 : 2360 : t = build_int_cst (TREE_TYPE (op1), 1);
772 : 2360 : t = int_const_binop (MINUS_EXPR, op1, t);
773 : 2360 : t = fold_convert (TREE_TYPE (op0), t);
774 : :
775 : 2360 : gimple_assign_set_rhs_code (stmt, BIT_AND_EXPR);
776 : 2360 : gimple_assign_set_rhs1 (stmt, op0);
777 : 2360 : gimple_assign_set_rhs2 (stmt, t);
778 : : }
779 : :
780 : 5282 : update_stmt (stmt);
781 : 5282 : fold_stmt (gsi, follow_single_use_edges);
782 : 5282 : return true;
783 : : }
784 : :
785 : : return false;
786 : 309745 : }
787 : :
788 : : /* Simplify a min or max if the ranges of the two operands are
789 : : disjoint. Return true if we do simplify. */
790 : :
791 : : bool
792 : 173146 : simplify_using_ranges::simplify_min_or_max_using_ranges
793 : : (gimple_stmt_iterator *gsi,
794 : : gimple *stmt)
795 : : {
796 : 173146 : tree op0 = gimple_assign_rhs1 (stmt);
797 : 173146 : tree op1 = gimple_assign_rhs2 (stmt);
798 : 173146 : tree val;
799 : :
800 : 173146 : val = fold_cond_with_ops (LE_EXPR, op0, op1, stmt);
801 : 173146 : if (!val)
802 : 167341 : val = fold_cond_with_ops (LT_EXPR, op0, op1, stmt);
803 : :
804 : 167341 : if (val)
805 : : {
806 : : /* VAL == TRUE -> OP0 < or <= op1
807 : : VAL == FALSE -> OP0 > or >= op1. */
808 : 6490 : tree res = ((gimple_assign_rhs_code (stmt) == MAX_EXPR)
809 : 6490 : == integer_zerop (val)) ? op0 : op1;
810 : 6490 : gimple_assign_set_rhs_from_tree (gsi, res);
811 : 6490 : return true;
812 : : }
813 : :
814 : : return false;
815 : : }
816 : :
817 : : /* If the operand to an ABS_EXPR is >= 0, then eliminate the
818 : : ABS_EXPR. If the operand is <= 0, then simplify the
819 : : ABS_EXPR into a NEGATE_EXPR. */
820 : :
821 : : bool
822 : 6336 : simplify_using_ranges::simplify_abs_using_ranges (gimple_stmt_iterator *gsi,
823 : : gimple *stmt)
824 : : {
825 : 6336 : tree op = gimple_assign_rhs1 (stmt);
826 : 6336 : tree zero = build_zero_cst (TREE_TYPE (op));
827 : 6336 : tree val = fold_cond_with_ops (LE_EXPR, op, zero, stmt);
828 : :
829 : 6336 : if (!val)
830 : : {
831 : : /* The range is neither <= 0 nor > 0. Now see if it is
832 : : either < 0 or >= 0. */
833 : 6110 : val = fold_cond_with_ops (LT_EXPR, op, zero, stmt);
834 : : }
835 : 6110 : if (val)
836 : : {
837 : 333 : gimple_assign_set_rhs1 (stmt, op);
838 : 333 : if (integer_zerop (val))
839 : 164 : gimple_assign_set_rhs_code (stmt, SSA_NAME);
840 : : else
841 : 169 : gimple_assign_set_rhs_code (stmt, NEGATE_EXPR);
842 : 333 : update_stmt (stmt);
843 : 333 : fold_stmt (gsi, follow_single_use_edges);
844 : 333 : return true;
845 : : }
846 : : return false;
847 : : }
848 : :
849 : : /* irange wrapper for wi_set_zero_nonzero_bits.
850 : :
851 : : Return TRUE if VR was a constant range and we were able to compute
852 : : the bit masks. */
853 : :
854 : : static bool
855 : 1600285 : vr_set_zero_nonzero_bits (const tree expr_type,
856 : : const irange *vr,
857 : : wide_int *may_be_nonzero,
858 : : wide_int *must_be_nonzero)
859 : : {
860 : 1600285 : if (vr->varying_p () || vr->undefined_p ())
861 : : {
862 : 947857 : *may_be_nonzero = wi::minus_one (TYPE_PRECISION (expr_type));
863 : 947857 : *must_be_nonzero = wi::zero (TYPE_PRECISION (expr_type));
864 : 947857 : return false;
865 : : }
866 : 652430 : wi_set_zero_nonzero_bits (expr_type, vr->lower_bound (), vr->upper_bound (),
867 : : *may_be_nonzero, *must_be_nonzero);
868 : 652428 : return true;
869 : : }
870 : :
871 : : /* Optimize away redundant BIT_AND_EXPR and BIT_IOR_EXPR.
872 : : If all the bits that are being cleared by & are already
873 : : known to be zero from VR, or all the bits that are being
874 : : set by | are already known to be one from VR, the bit
875 : : operation is redundant. */
876 : :
877 : : bool
878 : 1256595 : simplify_using_ranges::simplify_bit_ops_using_ranges
879 : : (gimple_stmt_iterator *gsi,
880 : : gimple *stmt)
881 : : {
882 : 1256595 : tree op0 = gimple_assign_rhs1 (stmt);
883 : 1256595 : tree op1 = gimple_assign_rhs2 (stmt);
884 : 1256595 : tree op = NULL_TREE;
885 : 1256595 : int_range_max vr0, vr1;
886 : 1256595 : wide_int may_be_nonzero0, may_be_nonzero1;
887 : 1256595 : wide_int must_be_nonzero0, must_be_nonzero1;
888 : 1256595 : wide_int mask;
889 : :
890 : 1256595 : if (!query->range_of_expr (vr0, op0, stmt)
891 : 1256595 : || vr0.undefined_p ())
892 : : return false;
893 : 1255926 : if (!query->range_of_expr (vr1, op1, stmt)
894 : 1255926 : || vr1.undefined_p ())
895 : : return false;
896 : :
897 : 1255593 : if (!vr_set_zero_nonzero_bits (TREE_TYPE (op0), &vr0, &may_be_nonzero0,
898 : : &must_be_nonzero0))
899 : : return false;
900 : 344692 : if (!vr_set_zero_nonzero_bits (TREE_TYPE (op1), &vr1, &may_be_nonzero1,
901 : : &must_be_nonzero1))
902 : : return false;
903 : :
904 : 307736 : switch (gimple_assign_rhs_code (stmt))
905 : : {
906 : 215737 : case BIT_AND_EXPR:
907 : 215737 : mask = wi::bit_and_not (may_be_nonzero0, must_be_nonzero1);
908 : 215737 : if (mask == 0)
909 : : {
910 : : op = op0;
911 : : break;
912 : : }
913 : 211133 : mask = wi::bit_and_not (may_be_nonzero1, must_be_nonzero0);
914 : 211133 : if (mask == 0)
915 : : {
916 : : op = op1;
917 : : break;
918 : : }
919 : : break;
920 : 91999 : case BIT_IOR_EXPR:
921 : 91999 : mask = wi::bit_and_not (may_be_nonzero0, must_be_nonzero1);
922 : 91999 : if (mask == 0)
923 : : {
924 : : op = op1;
925 : : break;
926 : : }
927 : 91998 : mask = wi::bit_and_not (may_be_nonzero1, must_be_nonzero0);
928 : 91998 : if (mask == 0)
929 : : {
930 : : op = op0;
931 : : break;
932 : : }
933 : : break;
934 : 0 : default:
935 : 0 : gcc_unreachable ();
936 : : }
937 : :
938 : 4818 : if (op == NULL_TREE)
939 : 302918 : return false;
940 : :
941 : 4818 : gimple_assign_set_rhs_with_ops (gsi, TREE_CODE (op), op);
942 : 4818 : update_stmt (gsi_stmt (*gsi));
943 : 4818 : return true;
944 : 1256607 : }
945 : :
946 : : /* We are comparing trees OP0 and OP1 using COND_CODE. OP0 has
947 : : a known value range VR.
948 : :
949 : : If there is one and only one value which will satisfy the
950 : : conditional, then return that value. Else return NULL.
951 : :
952 : : If signed overflow must be undefined for the value to satisfy
953 : : the conditional, then set *STRICT_OVERFLOW_P to true. */
954 : :
955 : : static tree
956 : 1347650 : test_for_singularity (enum tree_code cond_code, tree op0,
957 : : tree op1, const irange *vr)
958 : : {
959 : 1347650 : tree min = NULL;
960 : 1347650 : tree max = NULL;
961 : :
962 : : /* Extract minimum/maximum values which satisfy the conditional as it was
963 : : written. */
964 : 1347650 : if (cond_code == LE_EXPR || cond_code == LT_EXPR)
965 : : {
966 : 587036 : min = TYPE_MIN_VALUE (TREE_TYPE (op0));
967 : :
968 : 587036 : max = op1;
969 : 587036 : if (cond_code == LT_EXPR)
970 : : {
971 : 84250 : tree one = build_int_cst (TREE_TYPE (op0), 1);
972 : 84250 : max = fold_build2 (MINUS_EXPR, TREE_TYPE (op0), max, one);
973 : : /* Signal to compare_values_warnv this expr doesn't overflow. */
974 : 84250 : if (EXPR_P (max))
975 : 0 : suppress_warning (max, OPT_Woverflow);
976 : : }
977 : : }
978 : 760614 : else if (cond_code == GE_EXPR || cond_code == GT_EXPR)
979 : : {
980 : 650613 : max = TYPE_MAX_VALUE (TREE_TYPE (op0));
981 : :
982 : 650613 : min = op1;
983 : 650613 : if (cond_code == GT_EXPR)
984 : : {
985 : 567708 : tree one = build_int_cst (TREE_TYPE (op0), 1);
986 : 567708 : min = fold_build2 (PLUS_EXPR, TREE_TYPE (op0), min, one);
987 : : /* Signal to compare_values_warnv this expr doesn't overflow. */
988 : 567708 : if (EXPR_P (min))
989 : 0 : suppress_warning (min, OPT_Woverflow);
990 : : }
991 : : }
992 : :
993 : : /* Now refine the minimum and maximum values using any
994 : : value range information we have for op0. */
995 : 1347650 : if (min && max)
996 : : {
997 : 1237649 : tree type = TREE_TYPE (op0);
998 : 1237649 : tree tmin = wide_int_to_tree (type, vr->lower_bound ());
999 : 1237649 : tree tmax = wide_int_to_tree (type, vr->upper_bound ());
1000 : 1237649 : if (compare_values (tmin, min) == 1)
1001 : 366422 : min = tmin;
1002 : 1237649 : if (compare_values (tmax, max) == -1)
1003 : 454521 : max = tmax;
1004 : :
1005 : : /* If the new min/max values have converged to a single value,
1006 : : then there is only one value which can satisfy the condition,
1007 : : return that value. */
1008 : 1237649 : if (operand_equal_p (min, max, 0) && is_gimple_min_invariant (min))
1009 : : return min;
1010 : : }
1011 : : return NULL;
1012 : : }
1013 : :
1014 : : /* Return whether the value range *VR fits in an integer type specified
1015 : : by PRECISION and UNSIGNED_P. */
1016 : :
1017 : : bool
1018 : 218434 : range_fits_type_p (const irange *vr,
1019 : : unsigned dest_precision, signop dest_sgn)
1020 : : {
1021 : 218434 : tree src_type;
1022 : 218434 : unsigned src_precision;
1023 : 218434 : widest_int tem;
1024 : 218434 : signop src_sgn;
1025 : :
1026 : : /* We can only handle integral and pointer types. */
1027 : 218434 : src_type = vr->type ();
1028 : 218434 : if (!INTEGRAL_TYPE_P (src_type)
1029 : 0 : && !POINTER_TYPE_P (src_type))
1030 : : return false;
1031 : :
1032 : : /* An extension is fine unless VR is SIGNED and dest_sgn is UNSIGNED,
1033 : : and so is an identity transform. */
1034 : 218434 : src_precision = TYPE_PRECISION (vr->type ());
1035 : 218434 : src_sgn = TYPE_SIGN (src_type);
1036 : 218434 : if ((src_precision < dest_precision
1037 : 7377 : && !(dest_sgn == UNSIGNED && src_sgn == SIGNED))
1038 : 212374 : || (src_precision == dest_precision && src_sgn == dest_sgn))
1039 : : return true;
1040 : :
1041 : : /* Now we can only handle ranges with constant bounds. */
1042 : 209520 : if (vr->undefined_p () || vr->varying_p ())
1043 : : return false;
1044 : :
1045 : 164880 : wide_int vrmin = vr->lower_bound ();
1046 : 164880 : wide_int vrmax = vr->upper_bound ();
1047 : :
1048 : : /* For sign changes, the MSB of the wide_int has to be clear.
1049 : : An unsigned value with its MSB set cannot be represented by
1050 : : a signed wide_int, while a negative value cannot be represented
1051 : : by an unsigned wide_int. */
1052 : 164880 : if (src_sgn != dest_sgn
1053 : 164880 : && (wi::lts_p (vrmin, 0) || wi::lts_p (vrmax, 0)))
1054 : 50959 : return false;
1055 : :
1056 : : /* Then we can perform the conversion on both ends and compare
1057 : : the result for equality. */
1058 : 113921 : signop sign = TYPE_SIGN (vr->type ());
1059 : 113921 : tem = wi::ext (widest_int::from (vrmin, sign), dest_precision, dest_sgn);
1060 : 113921 : if (tem != widest_int::from (vrmin, sign))
1061 : : return false;
1062 : 108405 : tem = wi::ext (widest_int::from (vrmax, sign), dest_precision, dest_sgn);
1063 : 108405 : if (tem != widest_int::from (vrmax, sign))
1064 : : return false;
1065 : :
1066 : : return true;
1067 : 164880 : }
1068 : :
1069 : : // Clear edge E of EDGE_EXECUTABLE (it is unexecutable). If it wasn't
1070 : : // previously clear, propagate to successor blocks if appropriate.
1071 : :
1072 : : void
1073 : 283604 : simplify_using_ranges::set_and_propagate_unexecutable (edge e)
1074 : : {
1075 : : // If not_executable is already set, we're done.
1076 : : // This works in the absence of a flag as well.
1077 : 283604 : if ((e->flags & m_not_executable_flag) == m_not_executable_flag)
1078 : 196465 : return;
1079 : :
1080 : 186405 : e->flags |= m_not_executable_flag;
1081 : 186405 : m_flag_set_edges.safe_push (e);
1082 : :
1083 : : // Check if the destination block needs to propagate the property.
1084 : 186405 : basic_block bb = e->dest;
1085 : :
1086 : : // If any incoming edge is executable, we are done.
1087 : 186405 : edge_iterator ei;
1088 : 309851 : FOR_EACH_EDGE (e, ei, bb->preds)
1089 : 222712 : if ((e->flags & m_not_executable_flag) == 0)
1090 : : return;
1091 : :
1092 : : // This block is also unexecutable, propagate to all exit edges as well.
1093 : 153058 : FOR_EACH_EDGE (e, ei, bb->succs)
1094 : 65919 : set_and_propagate_unexecutable (e);
1095 : : }
1096 : :
1097 : : /* If COND can be folded entirely as TRUE or FALSE, rewrite the
1098 : : conditional as such, and return TRUE. */
1099 : :
1100 : : bool
1101 : 19353289 : simplify_using_ranges::fold_cond (gcond *cond)
1102 : : {
1103 : 19353289 : int_range_max r;
1104 : 19353289 : if (query->range_of_stmt (r, cond) && r.singleton_p ())
1105 : : {
1106 : : // COND has already been folded if arguments are constant.
1107 : 280687 : if (TREE_CODE (gimple_cond_lhs (cond)) != SSA_NAME
1108 : 280687 : && TREE_CODE (gimple_cond_rhs (cond)) != SSA_NAME)
1109 : : return false;
1110 : 210992 : if (dump_file)
1111 : : {
1112 : 176 : fprintf (dump_file, "Folding predicate ");
1113 : 176 : print_gimple_expr (dump_file, cond, 0);
1114 : 176 : fprintf (dump_file, " to ");
1115 : : }
1116 : 210992 : edge e0 = EDGE_SUCC (gimple_bb (cond), 0);
1117 : 210992 : edge e1 = EDGE_SUCC (gimple_bb (cond), 1);
1118 : 210992 : if (r.zero_p ())
1119 : : {
1120 : 131908 : if (dump_file)
1121 : 120 : fprintf (dump_file, "0\n");
1122 : 131908 : gimple_cond_make_false (cond);
1123 : 131908 : if (e0->flags & EDGE_TRUE_VALUE)
1124 : 129914 : set_and_propagate_unexecutable (e0);
1125 : : else
1126 : 1994 : set_and_propagate_unexecutable (e1);
1127 : : }
1128 : : else
1129 : : {
1130 : 79084 : if (dump_file)
1131 : 56 : fprintf (dump_file, "1\n");
1132 : 79084 : gimple_cond_make_true (cond);
1133 : 79084 : if (e0->flags & EDGE_FALSE_VALUE)
1134 : 589 : set_and_propagate_unexecutable (e0);
1135 : : else
1136 : 78495 : set_and_propagate_unexecutable (e1);
1137 : : }
1138 : 210992 : update_stmt (cond);
1139 : 210992 : return true;
1140 : : }
1141 : :
1142 : : // FIXME: Audit the code below and make sure it never finds anything.
1143 : 19072602 : edge taken_edge;
1144 : 19072602 : legacy_fold_cond (cond, &taken_edge);
1145 : :
1146 : 19072602 : if (taken_edge)
1147 : : {
1148 : 8 : if (taken_edge->flags & EDGE_TRUE_VALUE)
1149 : : {
1150 : 0 : if (dump_file && (dump_flags & TDF_DETAILS))
1151 : 0 : fprintf (dump_file, "\nVRP Predicate evaluates to: 1\n");
1152 : 0 : gimple_cond_make_true (cond);
1153 : : }
1154 : 8 : else if (taken_edge->flags & EDGE_FALSE_VALUE)
1155 : : {
1156 : 8 : if (dump_file && (dump_flags & TDF_DETAILS))
1157 : 0 : fprintf (dump_file, "\nVRP Predicate evaluates to: 0\n");
1158 : 8 : gimple_cond_make_false (cond);
1159 : : }
1160 : : else
1161 : 0 : gcc_unreachable ();
1162 : 8 : update_stmt (cond);
1163 : 8 : return true;
1164 : : }
1165 : : return false;
1166 : 19353289 : }
1167 : :
1168 : : /* Simplify a conditional using a relational operator to an equality
1169 : : test if the range information indicates only one value can satisfy
1170 : : the original conditional. */
1171 : :
1172 : : bool
1173 : 11226078 : simplify_using_ranges::simplify_cond_using_ranges_1 (gcond *stmt)
1174 : : {
1175 : 11226078 : tree op0 = gimple_cond_lhs (stmt);
1176 : 11226078 : tree op1 = gimple_cond_rhs (stmt);
1177 : 11226078 : enum tree_code cond_code = gimple_cond_code (stmt);
1178 : :
1179 : 11226078 : if (fold_cond (stmt))
1180 : : return true;
1181 : :
1182 : 11111894 : if (simplify_compare_using_ranges_1 (cond_code, op0, op1, stmt))
1183 : : {
1184 : 325335 : if (dump_file)
1185 : : {
1186 : 29 : fprintf (dump_file, "Simplified relational ");
1187 : 29 : print_gimple_stmt (dump_file, stmt, 0);
1188 : 29 : fprintf (dump_file, " into ");
1189 : : }
1190 : :
1191 : 325335 : gimple_cond_set_code (stmt, cond_code);
1192 : 325335 : gimple_cond_set_lhs (stmt, op0);
1193 : 325335 : gimple_cond_set_rhs (stmt, op1);
1194 : :
1195 : 325335 : update_stmt (stmt);
1196 : :
1197 : 325335 : if (dump_file)
1198 : : {
1199 : 29 : print_gimple_stmt (dump_file, stmt, 0);
1200 : 29 : fprintf (dump_file, "\n");
1201 : : }
1202 : 325335 : return true;
1203 : : }
1204 : : return false;
1205 : : }
1206 : :
1207 : : /* Like simplify_cond_using_ranges_1 but for assignments rather
1208 : : than GIMPLE_COND. */
1209 : :
1210 : : bool
1211 : 1185768 : simplify_using_ranges::simplify_compare_assign_using_ranges_1
1212 : : (gimple_stmt_iterator *gsi,
1213 : : gimple *stmt)
1214 : : {
1215 : 1185768 : enum tree_code code = gimple_assign_rhs_code (stmt);
1216 : 1185768 : tree op0 = gimple_assign_rhs1 (stmt);
1217 : 1185768 : tree op1 = gimple_assign_rhs2 (stmt);
1218 : 1185768 : gcc_assert (TREE_CODE_CLASS (code) == tcc_comparison);
1219 : 1185768 : bool happened = false;
1220 : :
1221 : 1185768 : if (simplify_compare_using_ranges_1 (code, op0, op1, stmt))
1222 : : {
1223 : 6064 : if (dump_file)
1224 : : {
1225 : 3 : fprintf (dump_file, "Simplified relational ");
1226 : 3 : print_gimple_stmt (dump_file, stmt, 0);
1227 : 3 : fprintf (dump_file, " into ");
1228 : : }
1229 : :
1230 : 6064 : gimple_assign_set_rhs_code (stmt, code);
1231 : 6064 : gimple_assign_set_rhs1 (stmt, op0);
1232 : 6064 : gimple_assign_set_rhs2 (stmt, op1);
1233 : :
1234 : 6064 : update_stmt (stmt);
1235 : :
1236 : 6064 : if (dump_file)
1237 : : {
1238 : 3 : print_gimple_stmt (dump_file, stmt, 0);
1239 : 3 : fprintf (dump_file, "\n");
1240 : : }
1241 : : happened = true;
1242 : : }
1243 : :
1244 : : /* Transform EQ_EXPR, NE_EXPR into BIT_XOR_EXPR or identity
1245 : : if the RHS is zero or one, and the LHS are known to be boolean
1246 : : values. */
1247 : 1185768 : if ((code == EQ_EXPR || code == NE_EXPR)
1248 : 641092 : && INTEGRAL_TYPE_P (TREE_TYPE (op0))
1249 : 1637567 : && simplify_truth_ops_using_ranges (gsi, stmt))
1250 : : happened = true;
1251 : :
1252 : 1185768 : return happened;
1253 : : }
1254 : :
1255 : : /* Try to simplify OP0 COND_CODE OP1 using a relational operator to an
1256 : : equality test if the range information indicates only one value can
1257 : : satisfy the original conditional. */
1258 : :
1259 : : bool
1260 : 12297662 : simplify_using_ranges::simplify_compare_using_ranges_1 (tree_code &cond_code, tree &op0, tree &op1, gimple *stmt)
1261 : : {
1262 : 12297662 : bool happened = false;
1263 : 12297662 : if (cond_code != NE_EXPR
1264 : 12297662 : && cond_code != EQ_EXPR
1265 : 3115890 : && TREE_CODE (op0) == SSA_NAME
1266 : 3110452 : && INTEGRAL_TYPE_P (TREE_TYPE (op0))
1267 : 15090561 : && is_gimple_min_invariant (op1))
1268 : : {
1269 : 1644594 : int_range_max vr;
1270 : :
1271 : 1644594 : if (!query->range_of_expr (vr, op0, stmt))
1272 : 0 : vr.set_undefined ();
1273 : :
1274 : : /* If we have range information for OP0, then we might be
1275 : : able to simplify this conditional. */
1276 : 1644594 : if (!vr.undefined_p () && !vr.varying_p ())
1277 : : {
1278 : 673825 : tree new_tree = test_for_singularity (cond_code, op0, op1, &vr);
1279 : 673825 : if (new_tree)
1280 : : {
1281 : 110001 : cond_code = EQ_EXPR;
1282 : 110001 : op1 = new_tree;
1283 : 110001 : happened = true;
1284 : : }
1285 : :
1286 : : /* Try again after inverting the condition. We only deal
1287 : : with integral types here, so no need to worry about
1288 : : issues with inverting FP comparisons. */
1289 : 673825 : new_tree = test_for_singularity
1290 : 673825 : (invert_tree_comparison (cond_code, false),
1291 : : op0, op1, &vr);
1292 : 673825 : if (new_tree)
1293 : : {
1294 : 155258 : cond_code = NE_EXPR;
1295 : 155258 : op1 = new_tree;
1296 : 155258 : happened = true;
1297 : : }
1298 : : }
1299 : 1644594 : }
1300 : : // Try to simplify casted conditions.
1301 : 12297662 : if (simplify_casted_compare (cond_code, op0, op1))
1302 : 73046 : happened = true;
1303 : 12297662 : return happened;
1304 : : }
1305 : :
1306 : : /* Simplify OP0 code OP1 when OP1 is a constant and OP0 was a SSA_NAME
1307 : : defined by a type conversion. Replacing OP0 with RHS of the type conversion.
1308 : : Doing so makes the conversion dead which helps subsequent passes. */
1309 : :
1310 : : bool
1311 : 12297662 : simplify_using_ranges::simplify_casted_compare (tree_code &, tree &op0, tree &op1)
1312 : : {
1313 : :
1314 : : /* If we have a comparison of an SSA_NAME (OP0) against a constant,
1315 : : see if OP0 was set by a type conversion where the source of
1316 : : the conversion is another SSA_NAME with a range that fits
1317 : : into the range of OP0's type.
1318 : :
1319 : : If so, the conversion is redundant as the earlier SSA_NAME can be
1320 : : used for the comparison directly if we just massage the constant in the
1321 : : comparison. */
1322 : 12297662 : if (TREE_CODE (op0) == SSA_NAME
1323 : 12067478 : && TREE_CODE (op1) == INTEGER_CST)
1324 : : {
1325 : 8642366 : gimple *def_stmt = SSA_NAME_DEF_STMT (op0);
1326 : 8642366 : tree innerop;
1327 : :
1328 : 8642366 : if (!is_gimple_assign (def_stmt))
1329 : : return false;
1330 : :
1331 : 5284324 : switch (gimple_assign_rhs_code (def_stmt))
1332 : : {
1333 : 434951 : CASE_CONVERT:
1334 : 434951 : innerop = gimple_assign_rhs1 (def_stmt);
1335 : 434951 : break;
1336 : 46781 : case VIEW_CONVERT_EXPR:
1337 : 46781 : innerop = TREE_OPERAND (gimple_assign_rhs1 (def_stmt), 0);
1338 : 46781 : if (!INTEGRAL_TYPE_P (TREE_TYPE (innerop)))
1339 : : return false;
1340 : : break;
1341 : : default:
1342 : : return false;
1343 : : }
1344 : :
1345 : 480777 : if (TREE_CODE (innerop) == SSA_NAME
1346 : 480727 : && !POINTER_TYPE_P (TREE_TYPE (innerop))
1347 : 475169 : && !SSA_NAME_OCCURS_IN_ABNORMAL_PHI (innerop)
1348 : 955933 : && desired_pro_or_demotion_p (TREE_TYPE (innerop), TREE_TYPE (op0)))
1349 : : {
1350 : 445319 : int_range_max vr;
1351 : :
1352 : 445319 : if (query->range_of_expr (vr, innerop)
1353 : 445316 : && !vr.varying_p ()
1354 : 142760 : && !vr.undefined_p ()
1355 : 142640 : && range_fits_type_p (&vr,
1356 : 142640 : TYPE_PRECISION (TREE_TYPE (op0)),
1357 : 142640 : TYPE_SIGN (TREE_TYPE (op0)))
1358 : 518365 : && int_fits_type_p (op1, TREE_TYPE (innerop)))
1359 : : {
1360 : 73046 : tree newconst = fold_convert (TREE_TYPE (innerop), op1);
1361 : 73046 : op0 = innerop;
1362 : 73046 : op1 = newconst;
1363 : 73046 : return true;
1364 : : }
1365 : 445319 : }
1366 : : }
1367 : : return false;
1368 : : }
1369 : :
1370 : : /* Simplify a switch statement using the value range of the switch
1371 : : argument. */
1372 : :
1373 : : bool
1374 : 57894 : simplify_using_ranges::simplify_switch_using_ranges (gswitch *stmt)
1375 : : {
1376 : 57894 : tree op = gimple_switch_index (stmt);
1377 : 57894 : int_range_max vr;
1378 : 57894 : bool take_default;
1379 : 57894 : edge e;
1380 : 57894 : edge_iterator ei;
1381 : 57894 : size_t i = 0, j = 0, n, n2;
1382 : 57894 : tree vec2;
1383 : 57894 : switch_update su;
1384 : 57894 : size_t k = 1, l = 0;
1385 : :
1386 : 57894 : if (TREE_CODE (op) == SSA_NAME)
1387 : : {
1388 : 57878 : if (!query->range_of_expr (vr, op, stmt)
1389 : 57878 : || vr.varying_p () || vr.undefined_p ())
1390 : : return false;
1391 : :
1392 : : /* Find case label for min/max of the value range. */
1393 : 15484 : take_default = !find_case_label_ranges (stmt, &vr, &i, &j, &k, &l);
1394 : : }
1395 : 16 : else if (TREE_CODE (op) == INTEGER_CST)
1396 : : {
1397 : 16 : take_default = !find_case_label_index (stmt, 1, op, &i);
1398 : 16 : if (take_default)
1399 : : {
1400 : 1 : i = 1;
1401 : 1 : j = 0;
1402 : : }
1403 : : else
1404 : : {
1405 : 15 : j = i;
1406 : : }
1407 : : }
1408 : : else
1409 : : return false;
1410 : :
1411 : 15500 : n = gimple_switch_num_labels (stmt);
1412 : :
1413 : : /* We can truncate the case label ranges that partially overlap with OP's
1414 : : value range. */
1415 : 15500 : size_t min_idx = 1, max_idx = 0;
1416 : 15500 : tree min, max;
1417 : 15500 : value_range_kind kind = get_legacy_range (vr, min, max);
1418 : 15500 : if (!vr.undefined_p ())
1419 : 15484 : find_case_label_range (stmt, min, max, &min_idx, &max_idx);
1420 : 15500 : if (min_idx <= max_idx)
1421 : : {
1422 : 13281 : tree min_label = gimple_switch_label (stmt, min_idx);
1423 : 13281 : tree max_label = gimple_switch_label (stmt, max_idx);
1424 : :
1425 : : /* Avoid changing the type of the case labels when truncating. */
1426 : 13281 : tree case_label_type = TREE_TYPE (CASE_LOW (min_label));
1427 : 13281 : tree vr_min = fold_convert (case_label_type, min);
1428 : 13281 : tree vr_max = fold_convert (case_label_type, max);
1429 : :
1430 : 13281 : if (kind == VR_RANGE)
1431 : : {
1432 : : /* If OP's value range is [2,8] and the low label range is
1433 : : 0 ... 3, truncate the label's range to 2 .. 3. */
1434 : 13167 : if (tree_int_cst_compare (CASE_LOW (min_label), vr_min) < 0
1435 : 7 : && CASE_HIGH (min_label) != NULL_TREE
1436 : 13174 : && tree_int_cst_compare (CASE_HIGH (min_label), vr_min) >= 0)
1437 : 7 : CASE_LOW (min_label) = vr_min;
1438 : :
1439 : : /* If OP's value range is [2,8] and the high label range is
1440 : : 7 ... 10, truncate the label's range to 7 .. 8. */
1441 : 13167 : if (tree_int_cst_compare (CASE_LOW (max_label), vr_max) <= 0
1442 : 13167 : && CASE_HIGH (max_label) != NULL_TREE
1443 : 13447 : && tree_int_cst_compare (CASE_HIGH (max_label), vr_max) > 0)
1444 : 6 : CASE_HIGH (max_label) = vr_max;
1445 : : }
1446 : 114 : else if (kind == VR_ANTI_RANGE)
1447 : : {
1448 : 114 : tree one_cst = build_one_cst (case_label_type);
1449 : :
1450 : 114 : if (min_label == max_label)
1451 : : {
1452 : : /* If OP's value range is ~[7,8] and the label's range is
1453 : : 7 ... 10, truncate the label's range to 9 ... 10. */
1454 : 108 : if (tree_int_cst_compare (CASE_LOW (min_label), vr_min) == 0
1455 : 105 : && CASE_HIGH (min_label) != NULL_TREE
1456 : 116 : && tree_int_cst_compare (CASE_HIGH (min_label), vr_max) > 0)
1457 : 3 : CASE_LOW (min_label)
1458 : 3 : = int_const_binop (PLUS_EXPR, vr_max, one_cst);
1459 : :
1460 : : /* If OP's value range is ~[7,8] and the label's range is
1461 : : 5 ... 8, truncate the label's range to 5 ... 6. */
1462 : 108 : if (tree_int_cst_compare (CASE_LOW (min_label), vr_min) < 0
1463 : 3 : && CASE_HIGH (min_label) != NULL_TREE
1464 : 111 : && tree_int_cst_compare (CASE_HIGH (min_label), vr_max) == 0)
1465 : 1 : CASE_HIGH (min_label)
1466 : 1 : = int_const_binop (MINUS_EXPR, vr_min, one_cst);
1467 : : }
1468 : : else
1469 : : {
1470 : : /* If OP's value range is ~[2,8] and the low label range is
1471 : : 0 ... 3, truncate the label's range to 0 ... 1. */
1472 : 6 : if (tree_int_cst_compare (CASE_LOW (min_label), vr_min) < 0
1473 : 1 : && CASE_HIGH (min_label) != NULL_TREE
1474 : 7 : && tree_int_cst_compare (CASE_HIGH (min_label), vr_min) >= 0)
1475 : 1 : CASE_HIGH (min_label)
1476 : 1 : = int_const_binop (MINUS_EXPR, vr_min, one_cst);
1477 : :
1478 : : /* If OP's value range is ~[2,8] and the high label range is
1479 : : 7 ... 10, truncate the label's range to 9 ... 10. */
1480 : 6 : if (tree_int_cst_compare (CASE_LOW (max_label), vr_max) <= 0
1481 : 6 : && CASE_HIGH (max_label) != NULL_TREE
1482 : 7 : && tree_int_cst_compare (CASE_HIGH (max_label), vr_max) > 0)
1483 : 1 : CASE_LOW (max_label)
1484 : 1 : = int_const_binop (PLUS_EXPR, vr_max, one_cst);
1485 : : }
1486 : : }
1487 : :
1488 : : /* Canonicalize singleton case ranges. */
1489 : 13281 : if (tree_int_cst_equal (CASE_LOW (min_label), CASE_HIGH (min_label)))
1490 : 4 : CASE_HIGH (min_label) = NULL_TREE;
1491 : 13281 : if (tree_int_cst_equal (CASE_LOW (max_label), CASE_HIGH (max_label)))
1492 : 1 : CASE_HIGH (max_label) = NULL_TREE;
1493 : : }
1494 : :
1495 : : /* We can also eliminate case labels that lie completely outside OP's value
1496 : : range. */
1497 : :
1498 : : /* Bail out if this is just all edges taken. */
1499 : 15500 : if (i == 1
1500 : 12570 : && j == n - 1
1501 : 12343 : && take_default)
1502 : : return false;
1503 : :
1504 : : /* Build a new vector of taken case labels. */
1505 : 3841 : vec2 = make_tree_vec (j - i + 1 + l - k + 1 + (int)take_default);
1506 : 3841 : n2 = 0;
1507 : :
1508 : : /* Add the default edge, if necessary. */
1509 : 3841 : if (take_default)
1510 : 3113 : TREE_VEC_ELT (vec2, n2++) = gimple_switch_default_label (stmt);
1511 : :
1512 : 14559 : for (; i <= j; ++i, ++n2)
1513 : 10718 : TREE_VEC_ELT (vec2, n2) = gimple_switch_label (stmt, i);
1514 : :
1515 : 4017 : for (; k <= l; ++k, ++n2)
1516 : 176 : TREE_VEC_ELT (vec2, n2) = gimple_switch_label (stmt, k);
1517 : :
1518 : : /* Mark needed edges. */
1519 : 17848 : for (i = 0; i < n2; ++i)
1520 : : {
1521 : 14007 : e = find_edge (gimple_bb (stmt),
1522 : : label_to_block (cfun,
1523 : 14007 : CASE_LABEL (TREE_VEC_ELT (vec2, i))));
1524 : 14007 : e->aux = (void *)-1;
1525 : : }
1526 : :
1527 : : /* Queue not needed edges for later removal. */
1528 : 24174 : FOR_EACH_EDGE (e, ei, gimple_bb (stmt)->succs)
1529 : : {
1530 : 20333 : if (e->aux == (void *)-1)
1531 : : {
1532 : 13640 : e->aux = NULL;
1533 : 13640 : continue;
1534 : : }
1535 : :
1536 : 6693 : if (dump_file && (dump_flags & TDF_DETAILS))
1537 : : {
1538 : 0 : fprintf (dump_file, "removing unreachable case label\n");
1539 : : }
1540 : 6693 : to_remove_edges.safe_push (e);
1541 : 6693 : set_and_propagate_unexecutable (e);
1542 : 6693 : e->flags &= ~EDGE_EXECUTABLE;
1543 : 6693 : e->flags |= EDGE_IGNORE;
1544 : : }
1545 : :
1546 : : /* And queue an update for the stmt. */
1547 : 3841 : su.stmt = stmt;
1548 : 3841 : su.vec = vec2;
1549 : 3841 : to_update_switch_stmts.safe_push (su);
1550 : 3841 : return true;
1551 : 57894 : }
1552 : :
1553 : : void
1554 : 12135537 : simplify_using_ranges::cleanup_edges_and_switches (void)
1555 : : {
1556 : 12135537 : int i;
1557 : 12135537 : edge e;
1558 : 12135537 : switch_update *su;
1559 : :
1560 : : /* Clear any edges marked as not executable. */
1561 : 12135537 : if (m_not_executable_flag)
1562 : : {
1563 : 4194725 : FOR_EACH_VEC_ELT (m_flag_set_edges, i, e)
1564 : 186405 : e->flags &= ~m_not_executable_flag;
1565 : : }
1566 : : /* Remove dead edges from SWITCH_EXPR optimization. This leaves the
1567 : : CFG in a broken state and requires a cfg_cleanup run. */
1568 : 12145810 : FOR_EACH_VEC_ELT (to_remove_edges, i, e)
1569 : 6693 : remove_edge (e);
1570 : :
1571 : : /* Update SWITCH_EXPR case label vector. */
1572 : 12139378 : FOR_EACH_VEC_ELT (to_update_switch_stmts, i, su)
1573 : : {
1574 : 3841 : size_t j;
1575 : 3841 : size_t n = TREE_VEC_LENGTH (su->vec);
1576 : 3841 : tree label;
1577 : 3841 : gimple_switch_set_num_labels (su->stmt, n);
1578 : 21689 : for (j = 0; j < n; j++)
1579 : 14007 : gimple_switch_set_label (su->stmt, j, TREE_VEC_ELT (su->vec, j));
1580 : : /* As we may have replaced the default label with a regular one
1581 : : make sure to make it a real default label again. This ensures
1582 : : optimal expansion. */
1583 : 3841 : label = gimple_switch_label (su->stmt, 0);
1584 : 3841 : CASE_LOW (label) = NULL_TREE;
1585 : 3841 : CASE_HIGH (label) = NULL_TREE;
1586 : : }
1587 : :
1588 : 12135537 : if (!to_remove_edges.is_empty ())
1589 : : {
1590 : 3580 : free_dominance_info (CDI_DOMINATORS);
1591 : 3580 : loops_state_set (LOOPS_NEED_FIXUP);
1592 : : }
1593 : :
1594 : 12135537 : to_remove_edges.release ();
1595 : 12135537 : to_update_switch_stmts.release ();
1596 : 12135537 : }
1597 : :
1598 : : /* Simplify an integral conversion from an SSA name in STMT. */
1599 : :
1600 : : static bool
1601 : 4658787 : simplify_conversion_using_ranges (gimple_stmt_iterator *gsi, gimple *stmt)
1602 : : {
1603 : 4658787 : tree innerop, middleop, finaltype;
1604 : 4658787 : gimple *def_stmt;
1605 : 4658787 : signop inner_sgn, middle_sgn, final_sgn;
1606 : 4658787 : unsigned inner_prec, middle_prec, final_prec;
1607 : 4658787 : widest_int innermin, innermed, innermax, middlemin, middlemed, middlemax;
1608 : :
1609 : 4658787 : finaltype = TREE_TYPE (gimple_assign_lhs (stmt));
1610 : 4658787 : if (!INTEGRAL_TYPE_P (finaltype))
1611 : : return false;
1612 : 4310574 : middleop = gimple_assign_rhs1 (stmt);
1613 : 4310574 : def_stmt = SSA_NAME_DEF_STMT (middleop);
1614 : 4310574 : if (!is_gimple_assign (def_stmt)
1615 : 4310574 : || !CONVERT_EXPR_CODE_P (gimple_assign_rhs_code (def_stmt)))
1616 : : return false;
1617 : 164907 : innerop = gimple_assign_rhs1 (def_stmt);
1618 : 164907 : if (TREE_CODE (innerop) != SSA_NAME
1619 : 164907 : || SSA_NAME_OCCURS_IN_ABNORMAL_PHI (innerop))
1620 : : return false;
1621 : :
1622 : : /* Get the value-range of the inner operand. Use global ranges in
1623 : : case innerop was created during substitute-and-fold. */
1624 : 161668 : wide_int imin, imax;
1625 : 161668 : int_range_max vr;
1626 : 161668 : if (!INTEGRAL_TYPE_P (TREE_TYPE (innerop)))
1627 : : return false;
1628 : 276342 : get_range_query (cfun)->range_of_expr (vr, innerop, stmt);
1629 : 138171 : if (vr.undefined_p () || vr.varying_p ())
1630 : : return false;
1631 : 70242 : innermin = widest_int::from (vr.lower_bound (), TYPE_SIGN (TREE_TYPE (innerop)));
1632 : 70242 : innermax = widest_int::from (vr.upper_bound (), TYPE_SIGN (TREE_TYPE (innerop)));
1633 : :
1634 : : /* Simulate the conversion chain to check if the result is equal if
1635 : : the middle conversion is removed. */
1636 : 70242 : inner_prec = TYPE_PRECISION (TREE_TYPE (innerop));
1637 : 70242 : middle_prec = TYPE_PRECISION (TREE_TYPE (middleop));
1638 : 70242 : final_prec = TYPE_PRECISION (finaltype);
1639 : :
1640 : : /* If the first conversion is not injective, the second must not
1641 : : be widening. */
1642 : 70242 : if (wi::gtu_p (innermax - innermin,
1643 : 140484 : wi::mask <widest_int> (middle_prec, false))
1644 : 70242 : && middle_prec < final_prec)
1645 : : return false;
1646 : : /* We also want a medium value so that we can track the effect that
1647 : : narrowing conversions with sign change have. */
1648 : 55232 : inner_sgn = TYPE_SIGN (TREE_TYPE (innerop));
1649 : 55232 : if (inner_sgn == UNSIGNED)
1650 : 41311 : innermed = wi::shifted_mask <widest_int> (1, inner_prec - 1, false);
1651 : : else
1652 : 13921 : innermed = 0;
1653 : 55232 : if (wi::cmp (innermin, innermed, inner_sgn) >= 0
1654 : 55232 : || wi::cmp (innermed, innermax, inner_sgn) >= 0)
1655 : 42436 : innermed = innermin;
1656 : :
1657 : 55232 : middle_sgn = TYPE_SIGN (TREE_TYPE (middleop));
1658 : 55232 : middlemin = wi::ext (innermin, middle_prec, middle_sgn);
1659 : 55232 : middlemed = wi::ext (innermed, middle_prec, middle_sgn);
1660 : 55232 : middlemax = wi::ext (innermax, middle_prec, middle_sgn);
1661 : :
1662 : : /* Require that the final conversion applied to both the original
1663 : : and the intermediate range produces the same result. */
1664 : 55232 : final_sgn = TYPE_SIGN (finaltype);
1665 : 110464 : if (wi::ext (middlemin, final_prec, final_sgn)
1666 : 110464 : != wi::ext (innermin, final_prec, final_sgn)
1667 : 105504 : || wi::ext (middlemed, final_prec, final_sgn)
1668 : 213488 : != wi::ext (innermed, final_prec, final_sgn)
1669 : 142788 : || wi::ext (middlemax, final_prec, final_sgn)
1670 : 186566 : != wi::ext (innermax, final_prec, final_sgn))
1671 : : return false;
1672 : :
1673 : 42941 : gimple_assign_set_rhs1 (stmt, innerop);
1674 : 42941 : fold_stmt (gsi, follow_single_use_edges);
1675 : 42941 : return true;
1676 : 4820455 : }
1677 : :
1678 : : /* Simplify a conversion from integral SSA name to float in STMT. */
1679 : :
1680 : : bool
1681 : 249603 : simplify_using_ranges::simplify_float_conversion_using_ranges
1682 : : (gimple_stmt_iterator *gsi,
1683 : : gimple *stmt)
1684 : : {
1685 : 249603 : tree rhs1 = gimple_assign_rhs1 (stmt);
1686 : 249603 : int_range_max vr;
1687 : 249603 : scalar_float_mode fltmode
1688 : 249603 : = SCALAR_FLOAT_TYPE_MODE (TREE_TYPE (gimple_assign_lhs (stmt)));
1689 : 249603 : scalar_int_mode mode;
1690 : 249603 : tree tem;
1691 : 249603 : gassign *conv;
1692 : :
1693 : : /* We can only handle constant ranges. */
1694 : 249603 : if (!query->range_of_expr (vr, rhs1, stmt)
1695 : 249603 : || vr.varying_p ()
1696 : 345241 : || vr.undefined_p ())
1697 : : return false;
1698 : :
1699 : : /* The code below doesn't work for large/huge _BitInt, nor is really
1700 : : needed for those, bitint lowering does use ranges already. */
1701 : 94973 : if (TREE_CODE (TREE_TYPE (rhs1)) == BITINT_TYPE
1702 : 94973 : && TYPE_MODE (TREE_TYPE (rhs1)) == BLKmode)
1703 : : return false;
1704 : : /* First check if we can use a signed type in place of an unsigned. */
1705 : 94971 : scalar_int_mode rhs_mode = SCALAR_INT_TYPE_MODE (TREE_TYPE (rhs1));
1706 : 94971 : if (TYPE_UNSIGNED (TREE_TYPE (rhs1))
1707 : 5495 : && can_float_p (fltmode, rhs_mode, 0) != CODE_FOR_nothing
1708 : 98743 : && range_fits_type_p (&vr, TYPE_PRECISION (TREE_TYPE (rhs1)), SIGNED))
1709 : : mode = rhs_mode;
1710 : : /* If we can do the conversion in the current input mode do nothing. */
1711 : 93508 : else if (can_float_p (fltmode, rhs_mode,
1712 : 93508 : TYPE_UNSIGNED (TREE_TYPE (rhs1))) != CODE_FOR_nothing)
1713 : : return false;
1714 : : /* Otherwise search for a mode we can use, starting from the narrowest
1715 : : integer mode available. */
1716 : : else
1717 : : {
1718 : 4313 : mode = NARROWEST_INT_MODE;
1719 : 15558 : for (;;)
1720 : : {
1721 : : /* If we cannot do a signed conversion to float from mode
1722 : : or if the value-range does not fit in the signed type
1723 : : try with a wider mode. */
1724 : 15558 : if (can_float_p (fltmode, mode, 0) != CODE_FOR_nothing
1725 : 15558 : && range_fits_type_p (&vr, GET_MODE_PRECISION (mode), SIGNED))
1726 : : break;
1727 : :
1728 : : /* But do not widen the input. Instead leave that to the
1729 : : optabs expansion code. */
1730 : 30884 : if (!GET_MODE_WIDER_MODE (mode).exists (&mode)
1731 : 15442 : || GET_MODE_PRECISION (mode) > TYPE_PRECISION (TREE_TYPE (rhs1)))
1732 : : return false;
1733 : : }
1734 : : }
1735 : :
1736 : : /* It works, insert a truncation or sign-change before the
1737 : : float conversion. */
1738 : 1579 : tem = make_ssa_name (build_nonstandard_integer_type
1739 : 1579 : (GET_MODE_PRECISION (mode), 0));
1740 : 1579 : conv = gimple_build_assign (tem, NOP_EXPR, rhs1);
1741 : 1579 : gsi_insert_before (gsi, conv, GSI_SAME_STMT);
1742 : 1579 : gimple_assign_set_rhs1 (stmt, tem);
1743 : 1579 : fold_stmt (gsi, follow_single_use_edges);
1744 : :
1745 : 1579 : return true;
1746 : 249603 : }
1747 : :
1748 : : /* Simplify an internal fn call using ranges if possible. */
1749 : :
1750 : : bool
1751 : 353629 : simplify_using_ranges::simplify_internal_call_using_ranges
1752 : : (gimple_stmt_iterator *gsi,
1753 : : gimple *stmt)
1754 : : {
1755 : 353629 : enum tree_code subcode;
1756 : 353629 : bool is_ubsan = false;
1757 : 353629 : bool ovf = false;
1758 : 353629 : switch (gimple_call_internal_fn (stmt))
1759 : : {
1760 : : case IFN_UBSAN_CHECK_ADD:
1761 : : subcode = PLUS_EXPR;
1762 : : is_ubsan = true;
1763 : : break;
1764 : 2461 : case IFN_UBSAN_CHECK_SUB:
1765 : 2461 : subcode = MINUS_EXPR;
1766 : 2461 : is_ubsan = true;
1767 : 2461 : break;
1768 : 2122 : case IFN_UBSAN_CHECK_MUL:
1769 : 2122 : subcode = MULT_EXPR;
1770 : 2122 : is_ubsan = true;
1771 : 2122 : break;
1772 : 40185 : case IFN_ADD_OVERFLOW:
1773 : 40185 : subcode = PLUS_EXPR;
1774 : 40185 : break;
1775 : 49504 : case IFN_SUB_OVERFLOW:
1776 : 49504 : subcode = MINUS_EXPR;
1777 : 49504 : break;
1778 : 46597 : case IFN_MUL_OVERFLOW:
1779 : 46597 : subcode = MULT_EXPR;
1780 : 46597 : break;
1781 : : default:
1782 : : return false;
1783 : : }
1784 : :
1785 : 143440 : tree op0 = gimple_call_arg (stmt, 0);
1786 : 143440 : tree op1 = gimple_call_arg (stmt, 1);
1787 : 143440 : tree type;
1788 : 143440 : if (is_ubsan)
1789 : : {
1790 : 7154 : type = TREE_TYPE (op0);
1791 : 7154 : if (VECTOR_TYPE_P (type))
1792 : : return false;
1793 : : }
1794 : 136286 : else if (gimple_call_lhs (stmt) == NULL_TREE)
1795 : : return false;
1796 : : else
1797 : 136286 : type = TREE_TYPE (TREE_TYPE (gimple_call_lhs (stmt)));
1798 : 142570 : if (!check_for_binary_op_overflow (query, subcode, type, op0, op1, &ovf, stmt)
1799 : 142570 : || (is_ubsan && ovf))
1800 : : return false;
1801 : :
1802 : 3425 : gimple *g;
1803 : 3425 : location_t loc = gimple_location (stmt);
1804 : 3425 : if (is_ubsan)
1805 : 565 : g = gimple_build_assign (gimple_call_lhs (stmt), subcode, op0, op1);
1806 : : else
1807 : : {
1808 : 2860 : tree utype = type;
1809 : 2860 : if (ovf
1810 : 1376 : || !useless_type_conversion_p (type, TREE_TYPE (op0))
1811 : 3517 : || !useless_type_conversion_p (type, TREE_TYPE (op1)))
1812 : 2487 : utype = unsigned_type_for (type);
1813 : 2860 : if (TREE_CODE (op0) == INTEGER_CST)
1814 : 1174 : op0 = fold_convert (utype, op0);
1815 : 1686 : else if (!useless_type_conversion_p (utype, TREE_TYPE (op0)))
1816 : : {
1817 : 719 : g = gimple_build_assign (make_ssa_name (utype), NOP_EXPR, op0);
1818 : 719 : gimple_set_location (g, loc);
1819 : 719 : gsi_insert_before (gsi, g, GSI_SAME_STMT);
1820 : 719 : op0 = gimple_assign_lhs (g);
1821 : : }
1822 : 2860 : if (TREE_CODE (op1) == INTEGER_CST)
1823 : 1641 : op1 = fold_convert (utype, op1);
1824 : 1219 : else if (!useless_type_conversion_p (utype, TREE_TYPE (op1)))
1825 : : {
1826 : 21 : g = gimple_build_assign (make_ssa_name (utype), NOP_EXPR, op1);
1827 : 21 : gimple_set_location (g, loc);
1828 : 21 : gsi_insert_before (gsi, g, GSI_SAME_STMT);
1829 : 21 : op1 = gimple_assign_lhs (g);
1830 : : }
1831 : 2860 : g = gimple_build_assign (make_ssa_name (utype), subcode, op0, op1);
1832 : 2860 : gimple_set_location (g, loc);
1833 : 2860 : gsi_insert_before (gsi, g, GSI_SAME_STMT);
1834 : 2860 : if (utype != type)
1835 : : {
1836 : 1334 : g = gimple_build_assign (make_ssa_name (type), NOP_EXPR,
1837 : : gimple_assign_lhs (g));
1838 : 1334 : gimple_set_location (g, loc);
1839 : 1334 : gsi_insert_before (gsi, g, GSI_SAME_STMT);
1840 : : }
1841 : 2860 : g = gimple_build_assign (gimple_call_lhs (stmt), COMPLEX_EXPR,
1842 : : gimple_assign_lhs (g),
1843 : 2860 : build_int_cst (type, ovf));
1844 : : }
1845 : 3425 : gimple_set_location (g, loc);
1846 : 3425 : gsi_replace (gsi, g, false);
1847 : 3425 : return true;
1848 : : }
1849 : :
1850 : : /* Return true if VAR is a two-valued variable. Set a and b with the
1851 : : two-values when it is true. Return false otherwise. */
1852 : :
1853 : : bool
1854 : 476542 : simplify_using_ranges::two_valued_val_range_p (tree var, tree *a, tree *b,
1855 : : gimple *s)
1856 : : {
1857 : 476542 : int_range_max vr;
1858 : 476542 : if (!query->range_of_expr (vr, var, s))
1859 : : return false;
1860 : 476542 : if (vr.varying_p () || vr.undefined_p ())
1861 : : return false;
1862 : :
1863 : 753196 : if ((vr.num_pairs () == 1 && vr.upper_bound () - vr.lower_bound () == 1)
1864 : 387200 : || (vr.num_pairs () == 2
1865 : 263675 : && vr.lower_bound (0) == vr.upper_bound (0)
1866 : 223008 : && vr.lower_bound (1) == vr.upper_bound (1)))
1867 : : {
1868 : 6557 : *a = wide_int_to_tree (TREE_TYPE (var), vr.lower_bound ());
1869 : 6557 : *b = wide_int_to_tree (TREE_TYPE (var), vr.upper_bound ());
1870 : 6557 : return true;
1871 : : }
1872 : : return false;
1873 : 476542 : }
1874 : :
1875 : 12135537 : simplify_using_ranges::simplify_using_ranges (range_query *query,
1876 : 12135537 : int not_executable_flag)
1877 : 12135537 : : query (query)
1878 : : {
1879 : 12135537 : to_remove_edges = vNULL;
1880 : 12135537 : to_update_switch_stmts = vNULL;
1881 : 12135537 : m_not_executable_flag = not_executable_flag;
1882 : 12135537 : m_flag_set_edges = vNULL;
1883 : 12135537 : }
1884 : :
1885 : 12135537 : simplify_using_ranges::~simplify_using_ranges ()
1886 : : {
1887 : 12135537 : cleanup_edges_and_switches ();
1888 : 12135537 : m_flag_set_edges.release ();
1889 : 12135537 : }
1890 : :
1891 : : /* Simplify STMT using ranges if possible. */
1892 : :
1893 : : bool
1894 : 209030506 : simplify_using_ranges::simplify (gimple_stmt_iterator *gsi)
1895 : : {
1896 : 209030506 : gcc_checking_assert (query);
1897 : :
1898 : 209030506 : gimple *stmt = gsi_stmt (*gsi);
1899 : 209030506 : if (is_gimple_assign (stmt))
1900 : : {
1901 : 62981580 : enum tree_code rhs_code = gimple_assign_rhs_code (stmt);
1902 : 62981580 : tree rhs1 = gimple_assign_rhs1 (stmt);
1903 : 62981580 : tree rhs2 = gimple_assign_rhs2 (stmt);
1904 : 62981580 : tree lhs = gimple_assign_lhs (stmt);
1905 : 62981580 : tree val1 = NULL_TREE, val2 = NULL_TREE;
1906 : 62981580 : use_operand_p use_p;
1907 : 62981580 : gimple *use_stmt;
1908 : :
1909 : : /* Convert:
1910 : : LHS = CST BINOP VAR
1911 : : Where VAR is two-valued and LHS is used in GIMPLE_COND only
1912 : : To:
1913 : : LHS = VAR == VAL1 ? (CST BINOP VAL1) : (CST BINOP VAL2)
1914 : :
1915 : : Also handles:
1916 : : LHS = VAR BINOP CST
1917 : : Where VAR is two-valued and LHS is used in GIMPLE_COND only
1918 : : To:
1919 : : LHS = VAR == VAL1 ? (VAL1 BINOP CST) : (VAL2 BINOP CST) */
1920 : :
1921 : 62981580 : if (TREE_CODE_CLASS (rhs_code) == tcc_binary
1922 : 13346948 : && INTEGRAL_TYPE_P (TREE_TYPE (rhs1))
1923 : 9525376 : && ((TREE_CODE (rhs1) == INTEGER_CST
1924 : 165344 : && TREE_CODE (rhs2) == SSA_NAME)
1925 : 9360635 : || (TREE_CODE (rhs2) == INTEGER_CST
1926 : 6228441 : && TREE_CODE (rhs1) == SSA_NAME))
1927 : 6392579 : && single_imm_use (lhs, &use_p, &use_stmt)
1928 : 67905957 : && gimple_code (use_stmt) == GIMPLE_COND)
1929 : :
1930 : : {
1931 : 476542 : tree new_rhs1 = NULL_TREE;
1932 : 476542 : tree new_rhs2 = NULL_TREE;
1933 : 476542 : tree cmp_var = NULL_TREE;
1934 : :
1935 : 476542 : if (TREE_CODE (rhs2) == SSA_NAME
1936 : 476542 : && two_valued_val_range_p (rhs2, &val1, &val2, stmt))
1937 : : {
1938 : : /* Optimize RHS1 OP [VAL1, VAL2]. */
1939 : 186 : new_rhs1 = int_const_binop (rhs_code, rhs1, val1);
1940 : 186 : new_rhs2 = int_const_binop (rhs_code, rhs1, val2);
1941 : 186 : cmp_var = rhs2;
1942 : : }
1943 : 476356 : else if (TREE_CODE (rhs1) == SSA_NAME
1944 : 476356 : && two_valued_val_range_p (rhs1, &val1, &val2, stmt))
1945 : : {
1946 : : /* Optimize [VAL1, VAL2] OP RHS2. */
1947 : 6371 : new_rhs1 = int_const_binop (rhs_code, val1, rhs2);
1948 : 6371 : new_rhs2 = int_const_binop (rhs_code, val2, rhs2);
1949 : 6371 : cmp_var = rhs1;
1950 : : }
1951 : :
1952 : : /* If we could not find two-vals or the optimzation is invalid as
1953 : : in divide by zero, new_rhs1 / new_rhs will be NULL_TREE. */
1954 : 476542 : if (new_rhs1 && new_rhs2)
1955 : : {
1956 : 6557 : tree cond = gimple_build (gsi, true, GSI_SAME_STMT,
1957 : : UNKNOWN_LOCATION,
1958 : : EQ_EXPR, boolean_type_node,
1959 : : cmp_var, val1);
1960 : 6557 : gimple_assign_set_rhs_with_ops (gsi,
1961 : : COND_EXPR, cond,
1962 : : new_rhs1,
1963 : : new_rhs2);
1964 : 6557 : update_stmt (gsi_stmt (*gsi));
1965 : 6557 : fold_stmt (gsi, follow_single_use_edges);
1966 : 7923053 : return true;
1967 : : }
1968 : : }
1969 : :
1970 : 62975023 : if (TREE_CODE_CLASS (rhs_code) == tcc_comparison)
1971 : 1185768 : return simplify_compare_assign_using_ranges_1 (gsi, stmt);
1972 : :
1973 : 61789255 : switch (rhs_code)
1974 : : {
1975 : :
1976 : : /* Transform TRUNC_DIV_EXPR and TRUNC_MOD_EXPR into RSHIFT_EXPR
1977 : : and BIT_AND_EXPR respectively if the first operand is greater
1978 : : than zero and the second operand is an exact power of two.
1979 : : Also optimize TRUNC_MOD_EXPR away if the second operand is
1980 : : constant and the first operand already has the right value
1981 : : range. */
1982 : 310959 : case TRUNC_DIV_EXPR:
1983 : 310959 : case TRUNC_MOD_EXPR:
1984 : 310959 : if ((TREE_CODE (rhs1) == SSA_NAME
1985 : 310959 : || TREE_CODE (rhs1) == INTEGER_CST)
1986 : 310959 : && INTEGRAL_TYPE_P (TREE_TYPE (rhs1)))
1987 : 309745 : return simplify_div_or_mod_using_ranges (gsi, stmt);
1988 : : break;
1989 : :
1990 : : /* Transform ABS (X) into X or -X as appropriate. */
1991 : 51476 : case ABS_EXPR:
1992 : 51476 : if (TREE_CODE (rhs1) == SSA_NAME
1993 : 51476 : && INTEGRAL_TYPE_P (TREE_TYPE (rhs1)))
1994 : 6336 : return simplify_abs_using_ranges (gsi, stmt);
1995 : : break;
1996 : :
1997 : 1286155 : case BIT_AND_EXPR:
1998 : 1286155 : case BIT_IOR_EXPR:
1999 : : /* Optimize away BIT_AND_EXPR and BIT_IOR_EXPR
2000 : : if all the bits being cleared are already cleared or
2001 : : all the bits being set are already set. */
2002 : 1286155 : if (INTEGRAL_TYPE_P (TREE_TYPE (rhs1)))
2003 : 1256595 : return simplify_bit_ops_using_ranges (gsi, stmt);
2004 : : break;
2005 : :
2006 : 5711339 : CASE_CONVERT:
2007 : 5711339 : if (TREE_CODE (rhs1) == SSA_NAME
2008 : 5711339 : && INTEGRAL_TYPE_P (TREE_TYPE (rhs1)))
2009 : 4658787 : return simplify_conversion_using_ranges (gsi, stmt);
2010 : : break;
2011 : :
2012 : 251814 : case FLOAT_EXPR:
2013 : 251814 : if (TREE_CODE (rhs1) == SSA_NAME
2014 : 251814 : && INTEGRAL_TYPE_P (TREE_TYPE (rhs1)))
2015 : 249603 : return simplify_float_conversion_using_ranges (gsi, stmt);
2016 : : break;
2017 : :
2018 : 173146 : case MIN_EXPR:
2019 : 173146 : case MAX_EXPR:
2020 : 173146 : return simplify_min_or_max_using_ranges (gsi, stmt);
2021 : :
2022 : 373185 : case RSHIFT_EXPR:
2023 : 373185 : {
2024 : 373185 : tree op0 = gimple_assign_rhs1 (stmt);
2025 : 373185 : tree type = TREE_TYPE (op0);
2026 : 373185 : int_range_max range;
2027 : 373185 : if (TYPE_SIGN (type) == SIGNED
2028 : 373185 : && query->range_of_expr (range, op0, stmt))
2029 : : {
2030 : 76516 : unsigned prec = TYPE_PRECISION (TREE_TYPE (op0));
2031 : 153032 : int_range<2> nzm1 (type, wi::minus_one (prec), wi::zero (prec),
2032 : 153040 : VR_ANTI_RANGE);
2033 : 76516 : range.intersect (nzm1);
2034 : : // If there are no ranges other than [-1, 0] remove the shift.
2035 : 76516 : if (range.undefined_p ())
2036 : : {
2037 : 42 : gimple_assign_set_rhs_from_tree (gsi, op0);
2038 : 42 : return true;
2039 : : }
2040 : : return false;
2041 : 76516 : }
2042 : 296669 : break;
2043 : 373185 : }
2044 : : default:
2045 : : break;
2046 : : }
2047 : : }
2048 : 146048926 : else if (gimple_code (stmt) == GIMPLE_COND)
2049 : 11226078 : return simplify_cond_using_ranges_1 (as_a <gcond *> (stmt));
2050 : 134822848 : else if (gimple_code (stmt) == GIMPLE_SWITCH)
2051 : 57894 : return simplify_switch_using_ranges (as_a <gswitch *> (stmt));
2052 : 134764954 : else if (is_gimple_call (stmt)
2053 : 134764954 : && gimple_call_internal_p (stmt))
2054 : 353629 : return simplify_internal_call_using_ranges (gsi, stmt);
2055 : :
2056 : : return false;
2057 : : }
|