Branch data Line data Source code
1 : : /* Code for GIMPLE range op related routines.
2 : : Copyright (C) 2019-2025 Free Software Foundation, Inc.
3 : : Contributed by Andrew MacLeod <amacleod@redhat.com>
4 : : and Aldy Hernandez <aldyh@redhat.com>.
5 : :
6 : : This file is part of GCC.
7 : :
8 : : GCC is free software; you can redistribute it and/or modify
9 : : it under the terms of the GNU General Public License as published by
10 : : the Free Software Foundation; either version 3, or (at your option)
11 : : any later version.
12 : :
13 : : GCC is distributed in the hope that it will be useful,
14 : : but WITHOUT ANY WARRANTY; without even the implied warranty of
15 : : MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
16 : : GNU General Public License for more details.
17 : :
18 : : You should have received a copy of the GNU General Public License
19 : : along with GCC; see the file COPYING3. If not see
20 : : <http://www.gnu.org/licenses/>. */
21 : :
22 : : #include "config.h"
23 : : #include "system.h"
24 : : #include "coretypes.h"
25 : : #include "backend.h"
26 : : #include "insn-codes.h"
27 : : #include "tree.h"
28 : : #include "gimple.h"
29 : : #include "ssa.h"
30 : : #include "gimple-pretty-print.h"
31 : : #include "optabs-tree.h"
32 : : #include "gimple-iterator.h"
33 : : #include "gimple-fold.h"
34 : : #include "wide-int.h"
35 : : #include "fold-const.h"
36 : : #include "case-cfn-macros.h"
37 : : #include "omp-general.h"
38 : : #include "cfgloop.h"
39 : : #include "tree-ssa-loop.h"
40 : : #include "tree-scalar-evolution.h"
41 : : #include "langhooks.h"
42 : : #include "vr-values.h"
43 : : #include "range.h"
44 : : #include "value-query.h"
45 : : #include "gimple-range.h"
46 : : #include "attr-fnspec.h"
47 : : #include "realmpfr.h"
48 : :
49 : : // Given stmt S, fill VEC, up to VEC_SIZE elements, with relevant ssa-names
50 : : // on the statement. For efficiency, it is an error to not pass in enough
51 : : // elements for the vector. Return the number of ssa-names.
52 : :
53 : : unsigned
54 : 313391280 : gimple_range_ssa_names (tree *vec, unsigned vec_size, gimple *stmt)
55 : : {
56 : 313391280 : tree ssa;
57 : 313391280 : int count = 0;
58 : :
59 : 313391280 : gimple_range_op_handler handler (stmt);
60 : 313391280 : if (handler)
61 : : {
62 : 81109368 : gcc_checking_assert (vec_size >= 2);
63 : 81109368 : if ((ssa = gimple_range_ssa_p (handler.operand1 ())))
64 : 70417598 : vec[count++] = ssa;
65 : 81109368 : if ((ssa = gimple_range_ssa_p (handler.operand2 ())))
66 : 19634345 : vec[count++] = ssa;
67 : : }
68 : 232281912 : else if (is_a<gassign *> (stmt)
69 : 232281912 : && gimple_assign_rhs_code (stmt) == COND_EXPR)
70 : : {
71 : 86286 : gcc_checking_assert (vec_size >= 3);
72 : 86286 : gassign *st = as_a<gassign *> (stmt);
73 : 86286 : if ((ssa = gimple_range_ssa_p (gimple_assign_rhs1 (st))))
74 : 86286 : vec[count++] = ssa;
75 : 172572 : if ((ssa = gimple_range_ssa_p (gimple_assign_rhs2 (st))))
76 : 77391 : vec[count++] = ssa;
77 : 172572 : if ((ssa = gimple_range_ssa_p (gimple_assign_rhs3 (st))))
78 : 29659 : vec[count++] = ssa;
79 : : }
80 : 313391280 : return count;
81 : : }
82 : :
83 : : // Return the base of the RHS of an assignment.
84 : :
85 : : static tree
86 : 333642099 : gimple_range_base_of_assignment (const gimple *stmt)
87 : : {
88 : 333642099 : gcc_checking_assert (gimple_code (stmt) == GIMPLE_ASSIGN);
89 : 333642099 : tree op1 = gimple_assign_rhs1 (stmt);
90 : 333642099 : if (gimple_assign_rhs_code (stmt) == ADDR_EXPR)
91 : 3509010 : return get_base_address (TREE_OPERAND (op1, 0));
92 : : return op1;
93 : : }
94 : :
95 : : // If statement is supported by range-ops, set the CODE and return the TYPE.
96 : :
97 : : static inline enum tree_code
98 : 1303180083 : get_code (gimple *s)
99 : : {
100 : 1303180083 : if (const gassign *ass = dyn_cast<const gassign *> (s))
101 : 684916743 : return gimple_assign_rhs_code (ass);
102 : 618263340 : if (const gcond *cond = dyn_cast<const gcond *> (s))
103 : 410999158 : return gimple_cond_code (cond);
104 : : return ERROR_MARK;
105 : : }
106 : :
107 : : // If statement S has a supported range_op handler return TRUE.
108 : :
109 : : bool
110 : 402234829 : gimple_range_op_handler::supported_p (gimple *s)
111 : : {
112 : 402234829 : enum tree_code code = get_code (s);
113 : 402234829 : if (range_op_handler (code))
114 : : return true;
115 : 110616044 : if (is_a <gcall *> (s) && gimple_range_op_handler (s))
116 : 652658 : return true;
117 : : return false;
118 : : }
119 : :
120 : : // Construct a handler object for statement S.
121 : :
122 : 900945254 : gimple_range_op_handler::gimple_range_op_handler (gimple *s)
123 : : {
124 : 900945254 : range_op_handler oper (get_code (s));
125 : 900945254 : m_stmt = s;
126 : 900945254 : m_op1 = NULL_TREE;
127 : 900945254 : m_op2 = NULL_TREE;
128 : :
129 : 900945254 : if (oper)
130 : 537911918 : switch (gimple_code (m_stmt))
131 : : {
132 : 204269819 : case GIMPLE_COND:
133 : 204269819 : m_op1 = gimple_cond_lhs (m_stmt);
134 : 204269819 : m_op2 = gimple_cond_rhs (m_stmt);
135 : : // Check that operands are supported types. One check is enough.
136 : 204269819 : if (value_range::supports_type_p (TREE_TYPE (m_op1)))
137 : 204208062 : m_operator = oper.range_op ();
138 : 204269819 : gcc_checking_assert (m_operator);
139 : 537911918 : return;
140 : 333642099 : case GIMPLE_ASSIGN:
141 : 333642099 : m_op1 = gimple_range_base_of_assignment (m_stmt);
142 : 333642099 : if (m_op1 && TREE_CODE (m_op1) == MEM_REF)
143 : : {
144 : : // If the base address is an SSA_NAME, we return it
145 : : // here. This allows processing of the range of that
146 : : // name, while the rest of the expression is simply
147 : : // ignored. The code in range_ops will see the
148 : : // ADDR_EXPR and do the right thing.
149 : 3296264 : tree ssa = TREE_OPERAND (m_op1, 0);
150 : 3296264 : if (TREE_CODE (ssa) == SSA_NAME)
151 : 3296231 : m_op1 = ssa;
152 : : }
153 : : // VIEW_CONVERT_EXPR needs to descend one level deeper to pick
154 : : // up the symbolic operand.
155 : 333642099 : if (TREE_CODE (m_op1) == VIEW_CONVERT_EXPR)
156 : 2124239 : m_op1 = TREE_OPERAND (m_op1, 0);
157 : 333642099 : if (gimple_num_ops (m_stmt) >= 3)
158 : 236272587 : m_op2 = gimple_assign_rhs2 (m_stmt);
159 : : // Check that operands are supported types. One check is enough.
160 : 333642099 : if ((m_op1 && !value_range::supports_type_p (TREE_TYPE (m_op1))))
161 : : return;
162 : 333276407 : m_operator = oper.range_op ();
163 : 333276407 : gcc_checking_assert (m_operator);
164 : : return;
165 : 0 : default:
166 : 0 : gcc_unreachable ();
167 : : return;
168 : : }
169 : : // If no range-op table entry handled this stmt, check for other supported
170 : : // statements.
171 : 363033336 : if (is_a <gcall *> (m_stmt))
172 : 66396771 : maybe_builtin_call ();
173 : : else
174 : 296636565 : maybe_non_standard ();
175 : 363033336 : gcc_checking_assert (m_operator);
176 : : }
177 : :
178 : : // Calculate what we can determine of the range of this unary
179 : : // statement's operand if the lhs of the expression has the range
180 : : // LHS_RANGE. Return false if nothing can be determined.
181 : :
182 : : bool
183 : 0 : gimple_range_op_handler::calc_op1 (vrange &r, const vrange &lhs_range)
184 : : {
185 : : // Give up on empty ranges.
186 : 0 : if (lhs_range.undefined_p ())
187 : : return false;
188 : :
189 : : // Unary operations require the type of the first operand in the
190 : : // second range position.
191 : 0 : tree type = TREE_TYPE (operand1 ());
192 : 0 : value_range type_range (type);
193 : 0 : type_range.set_varying (type);
194 : 0 : return op1_range (r, type, lhs_range, type_range);
195 : 0 : }
196 : :
197 : : // Calculate what we can determine of the range of this statement's
198 : : // first operand if the lhs of the expression has the range LHS_RANGE
199 : : // and the second operand has the range OP2_RANGE. Return false if
200 : : // nothing can be determined.
201 : :
202 : : bool
203 : 90820342 : gimple_range_op_handler::calc_op1 (vrange &r, const vrange &lhs_range,
204 : : const vrange &op2_range, relation_trio k)
205 : : {
206 : : // Give up on empty ranges.
207 : 90820342 : if (lhs_range.undefined_p ())
208 : : return false;
209 : :
210 : : // Unary operation are allowed to pass a range in for second operand
211 : : // as there are often additional restrictions beyond the type which
212 : : // can be imposed. See operator_cast::op1_range().
213 : 90820342 : tree type = TREE_TYPE (operand1 ());
214 : : // If op2 is undefined, solve as if it is varying.
215 : 90820342 : if (op2_range.undefined_p ())
216 : : {
217 : 38893 : if (gimple_num_ops (m_stmt) < 3)
218 : : return false;
219 : 9275 : tree op2_type;
220 : : // This is sometimes invoked on single operand stmts.
221 : 9275 : if (operand2 ())
222 : 9226 : op2_type = TREE_TYPE (operand2 ());
223 : : else
224 : 49 : op2_type = TREE_TYPE (operand1 ());
225 : 9275 : value_range trange (op2_type);
226 : 9275 : trange.set_varying (op2_type);
227 : 9275 : return op1_range (r, type, lhs_range, trange, k);
228 : 9275 : }
229 : 90781449 : return op1_range (r, type, lhs_range, op2_range, k);
230 : : }
231 : :
232 : : // Calculate what we can determine of the range of this statement's
233 : : // second operand if the lhs of the expression has the range LHS_RANGE
234 : : // and the first operand has the range OP1_RANGE. Return false if
235 : : // nothing can be determined.
236 : :
237 : : bool
238 : 25501497 : gimple_range_op_handler::calc_op2 (vrange &r, const vrange &lhs_range,
239 : : const vrange &op1_range, relation_trio k)
240 : : {
241 : : // Give up on empty ranges.
242 : 25501497 : if (lhs_range.undefined_p ())
243 : : return false;
244 : :
245 : 25501497 : tree type = TREE_TYPE (operand2 ());
246 : : // If op1 is undefined, solve as if it is varying.
247 : 25501497 : if (op1_range.undefined_p ())
248 : : {
249 : 8755 : tree op1_type = TREE_TYPE (operand1 ());
250 : 8755 : value_range trange (op1_type);
251 : 8755 : trange.set_varying (op1_type);
252 : 8755 : return op2_range (r, type, lhs_range, trange, k);
253 : 8755 : }
254 : 25492742 : return op2_range (r, type, lhs_range, op1_range, k);
255 : : }
256 : :
257 : : // --------------------------------------------------------------------
258 : :
259 : : // Implement range operator for float CFN_BUILT_IN_CONSTANT_P.
260 : : class cfn_constant_float_p : public range_operator
261 : : {
262 : : public:
263 : : using range_operator::fold_range;
264 : 144 : virtual bool fold_range (irange &r, tree type, const frange &lh,
265 : : const irange &, relation_trio) const
266 : : {
267 : 144 : if (lh.singleton_p ())
268 : : {
269 : 0 : wide_int one = wi::one (TYPE_PRECISION (type));
270 : 0 : r.set (type, one, one);
271 : 0 : return true;
272 : 0 : }
273 : 144 : if (cfun->after_inlining)
274 : : {
275 : 54 : r.set_zero (type);
276 : 54 : return true;
277 : : }
278 : : return false;
279 : : }
280 : : } op_cfn_constant_float_p;
281 : :
282 : : // Implement range operator for integral CFN_BUILT_IN_CONSTANT_P.
283 : : class cfn_constant_p : public range_operator
284 : : {
285 : : public:
286 : : using range_operator::fold_range;
287 : 92966 : virtual bool fold_range (irange &r, tree type, const irange &lh,
288 : : const irange &, relation_trio) const
289 : : {
290 : 92966 : if (lh.singleton_p ())
291 : : {
292 : 61 : wide_int one = wi::one (TYPE_PRECISION (type));
293 : 61 : r.set (type, one, one);
294 : 61 : return true;
295 : 61 : }
296 : 92905 : if (cfun->after_inlining)
297 : : {
298 : 74500 : r.set_zero (type);
299 : 74500 : return true;
300 : : }
301 : : return false;
302 : : }
303 : : } op_cfn_constant_p;
304 : :
305 : : // Implement range operator for integral/pointer functions returning
306 : : // the first argument.
307 : : class cfn_pass_through_arg1 : public range_operator
308 : : {
309 : : public:
310 : : using range_operator::fold_range;
311 : : using range_operator::op1_range;
312 : 180002 : virtual bool fold_range (irange &r, tree, const irange &lh,
313 : : const irange &, relation_trio) const
314 : : {
315 : 180002 : r = lh;
316 : 180002 : return true;
317 : : }
318 : 76139 : virtual bool fold_range (prange &r, tree, const prange &lh,
319 : : const prange &, relation_trio) const
320 : : {
321 : 76139 : r = lh;
322 : 76139 : return true;
323 : : }
324 : 248715 : virtual bool op1_range (irange &r, tree, const irange &lhs,
325 : : const irange &, relation_trio) const
326 : : {
327 : 248715 : r = lhs;
328 : 248715 : return true;
329 : : }
330 : 11360 : virtual bool op1_range (prange &r, tree, const prange &lhs,
331 : : const prange &, relation_trio) const
332 : : {
333 : 11360 : r = lhs;
334 : 11360 : return true;
335 : : }
336 : : } op_cfn_pass_through_arg1;
337 : :
338 : : // Implement range operator for CFN_BUILT_IN_SIGNBIT.
339 : : class cfn_signbit : public range_operator
340 : : {
341 : : public:
342 : : using range_operator::fold_range;
343 : : using range_operator::op1_range;
344 : 57181 : virtual bool fold_range (irange &r, tree type, const frange &lh,
345 : : const irange &, relation_trio) const override
346 : : {
347 : 57181 : bool signbit;
348 : 57181 : if (lh.signbit_p (signbit))
349 : : {
350 : 252 : if (signbit)
351 : 157 : r.set_nonzero (type);
352 : : else
353 : 95 : r.set_zero (type);
354 : 252 : return true;
355 : : }
356 : : return false;
357 : : }
358 : 19923 : virtual bool op1_range (frange &r, tree type, const irange &lhs,
359 : : const frange &, relation_trio) const override
360 : : {
361 : 19923 : if (lhs.zero_p ())
362 : : {
363 : 12879 : r.set (type, dconst0, frange_val_max (type));
364 : 12879 : r.update_nan (false);
365 : 12879 : return true;
366 : : }
367 : 7044 : if (!lhs.contains_p (wi::zero (TYPE_PRECISION (lhs.type ()))))
368 : : {
369 : 7044 : r.set (type, frange_val_min (type), dconstm0);
370 : 7044 : r.update_nan (true);
371 : 7044 : return true;
372 : : }
373 : : return false;
374 : : }
375 : : } op_cfn_signbit;
376 : :
377 : : // Implement range operator for CFN_BUILT_IN_COPYSIGN
378 : : class cfn_copysign : public range_operator
379 : : {
380 : : public:
381 : : using range_operator::fold_range;
382 : 156841 : virtual bool fold_range (frange &r, tree type, const frange &lh,
383 : : const frange &rh, relation_trio) const override
384 : : {
385 : 156841 : frange neg;
386 : 156841 : if (!range_op_handler (ABS_EXPR).fold_range (r, type, lh, frange (type)))
387 : : return false;
388 : 313682 : if (!range_op_handler (NEGATE_EXPR).fold_range (neg, type, r,
389 : 156841 : frange (type)))
390 : : return false;
391 : :
392 : 156841 : bool signbit;
393 : 156841 : if (rh.signbit_p (signbit))
394 : : {
395 : : // If the sign is negative, flip the result from ABS,
396 : : // otherwise leave things positive.
397 : 369 : if (signbit)
398 : 365 : r = neg;
399 : : }
400 : : else
401 : : // If the sign is unknown, keep the positive and negative
402 : : // alternatives.
403 : 156472 : r.union_ (neg);
404 : : return true;
405 : 156841 : }
406 : : } op_cfn_copysign;
407 : :
408 : : /* Compute FUNC (ARG) where FUNC is a mpfr function. If RES_LOW is non-NULL,
409 : : set it to low bound of possible range if the function is expected to have
410 : : ULPS precision and similarly if RES_HIGH is non-NULL, set it to high bound.
411 : : If the function returns false, the results weren't set. */
412 : :
413 : : static bool
414 : 50038 : frange_mpfr_arg1 (REAL_VALUE_TYPE *res_low, REAL_VALUE_TYPE *res_high,
415 : : int (*func) (mpfr_ptr, mpfr_srcptr, mpfr_rnd_t),
416 : : const REAL_VALUE_TYPE &arg, tree type, unsigned ulps)
417 : : {
418 : 50038 : if (ulps == ~0U || !real_isfinite (&arg))
419 : 27783 : return false;
420 : 22255 : machine_mode mode = TYPE_MODE (type);
421 : 22255 : const real_format *format = REAL_MODE_FORMAT (mode);
422 : 22255 : auto_mpfr m (format->p);
423 : 22255 : mpfr_from_real (m, &arg, MPFR_RNDN);
424 : 22255 : mpfr_clear_flags ();
425 : 22255 : bool inexact = func (m, m, MPFR_RNDN);
426 : 22255 : if (!mpfr_number_p (m) || mpfr_overflow_p () || mpfr_underflow_p ())
427 : 1250 : return false;
428 : :
429 : 21005 : REAL_VALUE_TYPE value, result;
430 : 21005 : real_from_mpfr (&value, m, format, MPFR_RNDN);
431 : 21005 : if (!real_isfinite (&value))
432 : : return false;
433 : 21005 : if ((value.cl == rvc_zero) != (mpfr_zero_p (m) != 0))
434 : 0 : inexact = true;
435 : :
436 : 21005 : real_convert (&result, format, &value);
437 : 21005 : if (!real_isfinite (&result))
438 : : return false;
439 : 21005 : bool round_low = false;
440 : 21005 : bool round_high = false;
441 : 21005 : if (!ulps && flag_rounding_math)
442 : 0 : ++ulps;
443 : 21005 : if (inexact || !real_identical (&result, &value))
444 : : {
445 : 44870 : if (MODE_COMPOSITE_P (mode))
446 : : round_low = round_high = true;
447 : : else
448 : : {
449 : 6410 : round_low = !real_less (&result, &value);
450 : 6410 : round_high = !real_less (&value, &result);
451 : : }
452 : : }
453 : 21005 : if (res_low)
454 : : {
455 : 15272 : *res_low = result;
456 : 17662 : for (unsigned int i = 0; i < ulps + round_low; ++i)
457 : 2390 : frange_nextafter (mode, *res_low, dconstninf);
458 : : }
459 : 21005 : if (res_high)
460 : : {
461 : 6789 : *res_high = result;
462 : 13079 : for (unsigned int i = 0; i < ulps + round_high; ++i)
463 : 6290 : frange_nextafter (mode, *res_high, dconstinf);
464 : : }
465 : : return true;
466 : 22255 : }
467 : :
468 : : class cfn_sqrt : public range_operator
469 : : {
470 : : public:
471 : : using range_operator::fold_range;
472 : : using range_operator::op1_range;
473 : 32853 : virtual bool fold_range (frange &r, tree type,
474 : : const frange &lh, const frange &,
475 : : relation_trio) const final override
476 : : {
477 : 32853 : if (lh.undefined_p ())
478 : : return false;
479 : 32600 : if (lh.known_isnan () || real_less (&lh.upper_bound (), &dconstm0))
480 : : {
481 : 7975 : r.set_nan (type);
482 : 7975 : return true;
483 : : }
484 : 24625 : unsigned bulps
485 : 24625 : = targetm.libm_function_max_error (CFN_SQRT, TYPE_MODE (type), true);
486 : 24625 : if (bulps == ~0U)
487 : 0 : r.set_varying (type);
488 : 24625 : else if (bulps == 0)
489 : 24625 : r.set (type, dconstm0, dconstinf);
490 : : else
491 : : {
492 : 0 : REAL_VALUE_TYPE boundmin = dconstm0;
493 : 0 : while (bulps--)
494 : 0 : frange_nextafter (TYPE_MODE (type), boundmin, dconstninf);
495 : 0 : r.set (type, boundmin, dconstinf);
496 : : }
497 : 30321 : if (!lh.maybe_isnan () && !real_less (&lh.lower_bound (), &dconst0))
498 : 4157 : r.clear_nan ();
499 : :
500 : 24625 : unsigned ulps
501 : 24625 : = targetm.libm_function_max_error (CFN_SQRT, TYPE_MODE (type), false);
502 : 24625 : if (ulps == ~0U)
503 : : return true;
504 : 24491 : REAL_VALUE_TYPE lb = lh.lower_bound ();
505 : 24491 : REAL_VALUE_TYPE ub = lh.upper_bound ();
506 : 24491 : if (!frange_mpfr_arg1 (&lb, NULL, mpfr_sqrt, lb, type, ulps))
507 : 10275 : lb = dconstninf;
508 : 24491 : if (!frange_mpfr_arg1 (NULL, &ub, mpfr_sqrt, ub, type, ulps))
509 : 18758 : ub = dconstinf;
510 : 24491 : frange r2;
511 : 24491 : r2.set (type, lb, ub);
512 : 24491 : r2.flush_denormals_to_zero ();
513 : 24491 : r.intersect (r2);
514 : 24491 : return true;
515 : 24491 : }
516 : 800 : virtual bool op1_range (frange &r, tree type,
517 : : const frange &lhs, const frange &,
518 : : relation_trio) const final override
519 : : {
520 : 800 : if (lhs.undefined_p ())
521 : : return false;
522 : :
523 : : // A known NAN means the input is [-INF,-0.) U +-NAN.
524 : 800 : if (lhs.known_isnan ())
525 : : {
526 : 2 : known_nan:
527 : 2 : REAL_VALUE_TYPE ub = dconstm0;
528 : 2 : frange_nextafter (TYPE_MODE (type), ub, dconstninf);
529 : 2 : r.set (type, dconstninf, ub);
530 : : // No r.flush_denormals_to_zero (); here - it is a reverse op.
531 : 2 : return true;
532 : : }
533 : :
534 : : // Results outside of [-0.0, +Inf] are impossible.
535 : 798 : unsigned bulps
536 : 798 : = targetm.libm_function_max_error (CFN_SQRT, TYPE_MODE (type), true);
537 : 798 : if (bulps != ~0U)
538 : : {
539 : 798 : const REAL_VALUE_TYPE &ub = lhs.upper_bound ();
540 : 798 : REAL_VALUE_TYPE m0 = dconstm0;
541 : 798 : while (bulps--)
542 : 0 : frange_nextafter (TYPE_MODE (type), m0, dconstninf);
543 : 798 : if (real_less (&ub, &m0))
544 : : {
545 : 0 : if (!lhs.maybe_isnan ())
546 : 0 : r.set_undefined ();
547 : : else
548 : : // If lhs could be NAN and finite result is impossible,
549 : : // the range is like lhs.known_isnan () above.
550 : 0 : goto known_nan;
551 : 0 : return true;
552 : : }
553 : : }
554 : :
555 : 1084 : if (!lhs.maybe_isnan ())
556 : : // If NAN is not valid result, the input cannot include either
557 : : // a NAN nor values smaller than -0.
558 : 286 : r.set (type, dconstm0, dconstinf, nan_state (false, false));
559 : : else
560 : 512 : r.set_varying (type);
561 : :
562 : 798 : unsigned ulps
563 : 798 : = targetm.libm_function_max_error (CFN_SQRT, TYPE_MODE (type), false);
564 : 798 : if (ulps == ~0U)
565 : : return true;
566 : 798 : REAL_VALUE_TYPE lb = lhs.lower_bound ();
567 : 798 : REAL_VALUE_TYPE ub = lhs.upper_bound ();
568 : 1084 : if (!lhs.maybe_isnan () && real_less (&dconst0, &lb))
569 : : {
570 : 129 : for (unsigned i = 0; i < ulps; ++i)
571 : 0 : frange_nextafter (TYPE_MODE (type), lb, dconstninf);
572 : 129 : if (real_less (&dconst0, &lb))
573 : : {
574 : 129 : REAL_VALUE_TYPE op = lb;
575 : 129 : frange_arithmetic (MULT_EXPR, type, lb, op, op, dconstninf);
576 : : }
577 : : else
578 : 0 : lb = dconstninf;
579 : : }
580 : : else
581 : 669 : lb = dconstninf;
582 : 798 : if (real_isfinite (&ub) && real_less (&dconst0, &ub))
583 : : {
584 : 283 : for (unsigned i = 0; i < ulps; ++i)
585 : 0 : frange_nextafter (TYPE_MODE (type), ub, dconstinf);
586 : 283 : if (real_isfinite (&ub))
587 : : {
588 : 283 : REAL_VALUE_TYPE op = ub;
589 : 283 : frange_arithmetic (MULT_EXPR, type, ub, op, op, dconstinf);
590 : : }
591 : : else
592 : 0 : ub = dconstinf;
593 : : }
594 : : else
595 : 515 : ub = dconstinf;
596 : 1596 : frange r2;
597 : 798 : r2.set (type, lb, ub);
598 : 798 : r.intersect (r2);
599 : 798 : return true;
600 : : }
601 : : } op_cfn_sqrt;
602 : :
603 : : class cfn_sincos : public range_operator
604 : : {
605 : : public:
606 : : using range_operator::fold_range;
607 : : using range_operator::op1_range;
608 : : cfn_sincos (combined_fn cfn) { m_cfn = cfn; }
609 : 12337 : virtual bool fold_range (frange &r, tree type,
610 : : const frange &lh, const frange &,
611 : : relation_trio) const final override
612 : : {
613 : 12337 : if (lh.undefined_p ())
614 : : return false;
615 : 12321 : if (lh.known_isnan () || lh.known_isinf ())
616 : : {
617 : 0 : r.set_nan (type);
618 : 0 : return true;
619 : : }
620 : 12321 : unsigned bulps = targetm.libm_function_max_error (m_cfn, TYPE_MODE (type),
621 : : true);
622 : 12321 : if (bulps == ~0U)
623 : 0 : r.set_varying (type);
624 : 12321 : else if (bulps == 0)
625 : 12269 : r.set (type, dconstm1, dconst1);
626 : : else
627 : : {
628 : 52 : REAL_VALUE_TYPE boundmin, boundmax;
629 : 52 : boundmax = dconst1;
630 : 104 : while (bulps--)
631 : 52 : frange_nextafter (TYPE_MODE (type), boundmax, dconstinf);
632 : 52 : real_arithmetic (&boundmin, NEGATE_EXPR, &boundmax, NULL);
633 : 52 : r.set (type, boundmin, boundmax);
634 : : }
635 : 15630 : if (!lh.maybe_isnan () && !lh.maybe_isinf ())
636 : 1175 : r.clear_nan ();
637 : :
638 : 12321 : unsigned ulps
639 : 12321 : = targetm.libm_function_max_error (m_cfn, TYPE_MODE (type), false);
640 : 12321 : if (ulps == ~0U)
641 : : return true;
642 : 12321 : REAL_VALUE_TYPE lb = lh.lower_bound ();
643 : 12321 : REAL_VALUE_TYPE ub = lh.upper_bound ();
644 : 12321 : REAL_VALUE_TYPE diff;
645 : 12321 : real_arithmetic (&diff, MINUS_EXPR, &ub, &lb);
646 : 12321 : if (!real_isfinite (&diff))
647 : : return true;
648 : 1791 : REAL_VALUE_TYPE pi = dconst_pi ();
649 : 1791 : REAL_VALUE_TYPE pix2;
650 : 1791 : real_arithmetic (&pix2, PLUS_EXPR, &pi, &pi);
651 : : // We can only try to narrow the range further if ub-lb < 2*pi.
652 : 1791 : if (!real_less (&diff, &pix2))
653 : : return true;
654 : 264 : REAL_VALUE_TYPE lb_lo, lb_hi, ub_lo, ub_hi;
655 : 264 : REAL_VALUE_TYPE lb_deriv_lo, lb_deriv_hi, ub_deriv_lo, ub_deriv_hi;
656 : 264 : if (!frange_mpfr_arg1 (&lb_lo, &lb_hi,
657 : 264 : m_cfn == CFN_SIN ? mpfr_sin : mpfr_cos, lb,
658 : : type, ulps)
659 : 264 : || !frange_mpfr_arg1 (&ub_lo, &ub_hi,
660 : 264 : m_cfn == CFN_SIN ? mpfr_sin : mpfr_cos, ub,
661 : : type, ulps)
662 : 264 : || !frange_mpfr_arg1 (&lb_deriv_lo, &lb_deriv_hi,
663 : 264 : m_cfn == CFN_SIN ? mpfr_cos : mpfr_sin, lb,
664 : : type, 0)
665 : 528 : || !frange_mpfr_arg1 (&ub_deriv_lo, &ub_deriv_hi,
666 : 264 : m_cfn == CFN_SIN ? mpfr_cos : mpfr_sin, ub,
667 : : type, 0))
668 : 0 : return true;
669 : 264 : if (m_cfn == CFN_COS)
670 : : {
671 : : // Derivative of cos is -sin, so negate.
672 : 75 : lb_deriv_lo.sign ^= 1;
673 : 75 : lb_deriv_hi.sign ^= 1;
674 : 75 : ub_deriv_lo.sign ^= 1;
675 : 75 : ub_deriv_hi.sign ^= 1;
676 : : }
677 : :
678 : 264 : if (real_less (&lb_lo, &ub_lo))
679 : 127 : lb = lb_lo;
680 : : else
681 : 137 : lb = ub_lo;
682 : 264 : if (real_less (&lb_hi, &ub_hi))
683 : 127 : ub = ub_hi;
684 : : else
685 : 137 : ub = lb_hi;
686 : :
687 : : // The range between the function result on the boundaries may need
688 : : // to be extended to +1 (+Inf) or -1 (-Inf) or both depending on the
689 : : // derivative or length of the argument range (diff).
690 : :
691 : : // First handle special case, where the derivative has different signs,
692 : : // so the bound must be roughly -1 or +1.
693 : 264 : if (real_isneg (&lb_deriv_lo) != real_isneg (&lb_deriv_hi))
694 : : {
695 : 0 : if (real_isneg (&lb_lo))
696 : 0 : lb = dconstninf;
697 : : else
698 : 0 : ub = dconstinf;
699 : : }
700 : 264 : if (real_isneg (&ub_deriv_lo) != real_isneg (&ub_deriv_hi))
701 : : {
702 : 0 : if (real_isneg (&ub_lo))
703 : 0 : lb = dconstninf;
704 : : else
705 : 0 : ub = dconstinf;
706 : : }
707 : :
708 : : // If derivative at lower_bound and upper_bound have the same sign,
709 : : // the function grows or declines on the whole range if diff < pi, so
710 : : // [lb, ub] is correct, and if diff >= pi the result range must include
711 : : // both the minimum and maximum.
712 : 264 : if (real_isneg (&lb_deriv_lo) == real_isneg (&ub_deriv_lo))
713 : : {
714 : 160 : if (!real_less (&diff, &pi))
715 : : return true;
716 : : }
717 : : // If function declines at lower_bound and grows at upper_bound,
718 : : // the result range must include the minimum, so set lb to -Inf.
719 : 104 : else if (real_isneg (&lb_deriv_lo))
720 : 23 : lb = dconstninf;
721 : : // If function grows at lower_bound and declines at upper_bound,
722 : : // the result range must include the maximum, so set ub to +Inf.
723 : : else
724 : 81 : ub = dconstinf;
725 : 242 : frange r2;
726 : 242 : r2.set (type, lb, ub);
727 : 242 : r2.flush_denormals_to_zero ();
728 : 242 : r.intersect (r2);
729 : 242 : return true;
730 : 242 : }
731 : 2736 : virtual bool op1_range (frange &r, tree type,
732 : : const frange &lhs, const frange &,
733 : : relation_trio) const final override
734 : : {
735 : 2736 : if (lhs.undefined_p ())
736 : : return false;
737 : :
738 : : // A known NAN means the input is [-INF,-INF][+INF,+INF] U +-NAN,
739 : : // which we can't currently represent.
740 : 2736 : if (lhs.known_isnan ())
741 : : {
742 : 0 : r.set_varying (type);
743 : 0 : return true;
744 : : }
745 : :
746 : : // Results outside of [-1.0, +1.0] are impossible.
747 : 2736 : unsigned bulps
748 : 2736 : = targetm.libm_function_max_error (m_cfn, TYPE_MODE (type), true);
749 : 2736 : if (bulps != ~0U)
750 : : {
751 : 2736 : const REAL_VALUE_TYPE &lb = lhs.lower_bound ();
752 : 2736 : const REAL_VALUE_TYPE &ub = lhs.upper_bound ();
753 : 2736 : REAL_VALUE_TYPE m1 = dconstm1;
754 : 2736 : REAL_VALUE_TYPE p1 = dconst1;
755 : 2736 : while (bulps--)
756 : : {
757 : 0 : frange_nextafter (TYPE_MODE (type), m1, dconstninf);
758 : 0 : frange_nextafter (TYPE_MODE (type), p1, dconstinf);
759 : : }
760 : 2736 : if (real_less (&ub, &m1) || real_less (&p1, &lb))
761 : : {
762 : 0 : if (!lhs.maybe_isnan ())
763 : 0 : r.set_undefined ();
764 : : else
765 : : /* If lhs could be NAN and finite result is impossible,
766 : : the range is like lhs.known_isnan () above,
767 : : [-INF,-INF][+INF,+INF] U +-NAN. */
768 : 0 : r.set_varying (type);
769 : 0 : return true;
770 : : }
771 : : }
772 : :
773 : 3842 : if (!lhs.maybe_isnan ())
774 : : {
775 : : // If NAN is not valid result, the input cannot include either
776 : : // a NAN nor a +-INF.
777 : 1106 : REAL_VALUE_TYPE lb = real_min_representable (type);
778 : 1106 : REAL_VALUE_TYPE ub = real_max_representable (type);
779 : 1106 : r.set (type, lb, ub, nan_state (false, false));
780 : : }
781 : : else
782 : 1630 : r.set_varying (type);
783 : : return true;
784 : : }
785 : : private:
786 : : combined_fn m_cfn;
787 : : } op_cfn_sin (CFN_SIN), op_cfn_cos (CFN_COS);
788 : :
789 : : // Implement range operator for CFN_BUILT_IN_TOUPPER and CFN_BUILT_IN_TOLOWER.
790 : : class cfn_toupper_tolower : public range_operator
791 : : {
792 : : public:
793 : : using range_operator::fold_range;
794 : : cfn_toupper_tolower (bool toupper) { m_toupper = toupper; }
795 : : virtual bool fold_range (irange &r, tree type, const irange &lh,
796 : : const irange &, relation_trio) const;
797 : : private:
798 : : bool get_letter_range (tree type, irange &lowers, irange &uppers) const;
799 : : bool m_toupper;
800 : : } op_cfn_toupper (true), op_cfn_tolower (false);
801 : :
802 : : // Return TRUE if we recognize the target character set and return the
803 : : // range for lower case and upper case letters.
804 : :
805 : : bool
806 : 17182 : cfn_toupper_tolower::get_letter_range (tree type, irange &lowers,
807 : : irange &uppers) const
808 : : {
809 : : // ASCII
810 : 17182 : int a = lang_hooks.to_target_charset ('a');
811 : 17182 : int z = lang_hooks.to_target_charset ('z');
812 : 17182 : int A = lang_hooks.to_target_charset ('A');
813 : 17182 : int Z = lang_hooks.to_target_charset ('Z');
814 : :
815 : 17182 : if ((z - a == 25) && (Z - A == 25))
816 : : {
817 : 17182 : lowers = int_range<2> (type,
818 : 34364 : wi::shwi (a, TYPE_PRECISION (type)),
819 : 34364 : wi::shwi (z, TYPE_PRECISION (type)));
820 : 17182 : uppers = int_range<2> (type,
821 : 34364 : wi::shwi (A, TYPE_PRECISION (type)),
822 : 34364 : wi::shwi (Z, TYPE_PRECISION (type)));
823 : 17182 : return true;
824 : : }
825 : : // Unknown character set.
826 : : return false;
827 : : }
828 : :
829 : : bool
830 : 17182 : cfn_toupper_tolower::fold_range (irange &r, tree type, const irange &lh,
831 : : const irange &, relation_trio) const
832 : : {
833 : 17182 : int_range<3> lowers;
834 : 17182 : int_range<3> uppers;
835 : 17182 : if (!get_letter_range (type, lowers, uppers))
836 : : return false;
837 : :
838 : 17182 : r = lh;
839 : 17182 : if (m_toupper)
840 : : {
841 : : // Return the range passed in without any lower case characters,
842 : : // but including all the upper case ones.
843 : 17082 : lowers.invert ();
844 : 17082 : r.intersect (lowers);
845 : 17082 : r.union_ (uppers);
846 : : }
847 : : else
848 : : {
849 : : // Return the range passed in without any lower case characters,
850 : : // but including all the upper case ones.
851 : 100 : uppers.invert ();
852 : 100 : r.intersect (uppers);
853 : 100 : r.union_ (lowers);
854 : : }
855 : : return true;
856 : 17182 : }
857 : :
858 : : // Implement range operator for CFN_BUILT_IN_FFS.
859 : : class cfn_ffs : public range_operator
860 : : {
861 : : public:
862 : : using range_operator::fold_range;
863 : 5973 : virtual bool fold_range (irange &r, tree type, const irange &lh,
864 : : const irange &, relation_trio) const
865 : : {
866 : 5973 : if (lh.undefined_p ())
867 : : return false;
868 : : // __builtin_ffs* and __builtin_popcount* return [0, prec].
869 : 5973 : int prec = TYPE_PRECISION (lh.type ());
870 : : // If arg is non-zero, then ffs or popcount are non-zero.
871 : 5973 : int mini = range_includes_zero_p (lh) ? 0 : 1;
872 : 5973 : int maxi = prec;
873 : :
874 : : // If some high bits are known to be zero, decrease the maximum.
875 : 5973 : int_range_max tmp = lh;
876 : 5973 : if (TYPE_SIGN (tmp.type ()) == SIGNED)
877 : 1865 : range_cast (tmp, unsigned_type_for (tmp.type ()));
878 : 5973 : wide_int max = tmp.upper_bound ();
879 : 5973 : maxi = wi::floor_log2 (max) + 1;
880 : 5973 : r.set (type,
881 : 11946 : wi::shwi (mini, TYPE_PRECISION (type)),
882 : 5973 : wi::shwi (maxi, TYPE_PRECISION (type)));
883 : 5973 : return true;
884 : 5973 : }
885 : : } op_cfn_ffs;
886 : :
887 : : // Implement range operator for CFN_BUILT_IN_POPCOUNT.
888 : : class cfn_popcount : public cfn_ffs
889 : : {
890 : : public:
891 : : using range_operator::fold_range;
892 : 4034 : virtual bool fold_range (irange &r, tree type, const irange &lh,
893 : : const irange &rh, relation_trio rel) const
894 : : {
895 : 4034 : if (lh.undefined_p ())
896 : : return false;
897 : 4026 : unsigned prec = TYPE_PRECISION (type);
898 : 4026 : irange_bitmask bm = lh.get_bitmask ();
899 : 4026 : wide_int nz = bm.get_nonzero_bits ();
900 : 4026 : wide_int high = wi::shwi (wi::popcount (nz), prec);
901 : : // Calculating the popcount of a singleton is trivial.
902 : 4026 : if (lh.singleton_p ())
903 : : {
904 : 1 : r.set (type, high, high);
905 : 1 : return true;
906 : : }
907 : 4025 : if (cfn_ffs::fold_range (r, type, lh, rh, rel))
908 : : {
909 : 4025 : wide_int known_ones = ~bm.mask () & bm.value ();
910 : 4025 : wide_int low = wi::shwi (wi::popcount (known_ones), prec);
911 : 4025 : int_range<2> tmp (type, low, high);
912 : 4025 : r.intersect (tmp);
913 : 4025 : return true;
914 : 4025 : }
915 : : return false;
916 : 4026 : }
917 : : } op_cfn_popcount;
918 : :
919 : : // Implement range operator for CFN_BUILT_IN_CLZ
920 : : class cfn_clz : public range_operator
921 : : {
922 : : public:
923 : : cfn_clz (bool internal) { m_gimple_call_internal_p = internal; }
924 : : using range_operator::fold_range;
925 : : virtual bool fold_range (irange &r, tree type, const irange &lh,
926 : : const irange &rh, relation_trio) const;
927 : : private:
928 : : bool m_gimple_call_internal_p;
929 : : } op_cfn_clz (false), op_cfn_clz_internal (true);
930 : :
931 : : bool
932 : 183609 : cfn_clz::fold_range (irange &r, tree type, const irange &lh,
933 : : const irange &rh, relation_trio) const
934 : : {
935 : : // __builtin_c[lt]z* return [0, prec-1], except when the
936 : : // argument is 0, but that is undefined behavior.
937 : : //
938 : : // For __builtin_c[lt]z* consider argument of 0 always undefined
939 : : // behavior, for internal fns likewise, unless it has 2 arguments,
940 : : // then the second argument is the value at zero.
941 : 183609 : if (lh.undefined_p ())
942 : : return false;
943 : 183543 : int prec = TYPE_PRECISION (lh.type ());
944 : 183543 : int mini = 0;
945 : 183543 : int maxi = prec - 1;
946 : 183543 : if (m_gimple_call_internal_p)
947 : : {
948 : : // Handle only the two common values.
949 : 102 : if (rh.lower_bound () == -1)
950 : : mini = -1;
951 : 96 : else if (rh.lower_bound () == prec)
952 : 96 : maxi = prec;
953 : : else
954 : : // Magic value to give up, unless we can prove arg is non-zero.
955 : : mini = -2;
956 : : }
957 : :
958 : : // From clz of minimum we can compute result maximum.
959 : 183543 : if (wi::gt_p (lh.lower_bound (), 0, TYPE_SIGN (lh.type ())))
960 : : {
961 : 166185 : maxi = prec - 1 - wi::floor_log2 (lh.lower_bound ());
962 : 166185 : if (mini < 0)
963 : : mini = 0;
964 : : }
965 : 17358 : else if (!range_includes_zero_p (lh))
966 : : {
967 : : mini = 0;
968 : : maxi = prec - 1;
969 : : }
970 : 17357 : if (mini == -2)
971 : : return false;
972 : : // From clz of maximum we can compute result minimum.
973 : 183543 : wide_int max = lh.upper_bound ();
974 : 183543 : int newmini = prec - 1 - wi::floor_log2 (max);
975 : 183543 : if (max == 0)
976 : : {
977 : : // If CLZ_DEFINED_VALUE_AT_ZERO is 2 with VALUE of prec,
978 : : // return [prec, prec] or [-1, -1], otherwise ignore the range.
979 : 11 : if (maxi == prec)
980 : : mini = prec;
981 : 11 : else if (mini == -1)
982 : : maxi = -1;
983 : : }
984 : 183532 : else if (mini >= 0)
985 : 183527 : mini = newmini;
986 : :
987 : 183542 : if (mini == -2)
988 : : return false;
989 : 183543 : r.set (type,
990 : 367086 : wi::shwi (mini, TYPE_PRECISION (type)),
991 : 183543 : wi::shwi (maxi, TYPE_PRECISION (type)));
992 : 183543 : return true;
993 : 183543 : }
994 : :
995 : : // Implement range operator for CFN_BUILT_IN_CTZ
996 : : class cfn_ctz : public range_operator
997 : : {
998 : : public:
999 : : cfn_ctz (bool internal) { m_gimple_call_internal_p = internal; }
1000 : : using range_operator::fold_range;
1001 : : virtual bool fold_range (irange &r, tree type, const irange &lh,
1002 : : const irange &rh, relation_trio) const;
1003 : : private:
1004 : : bool m_gimple_call_internal_p;
1005 : : } op_cfn_ctz (false), op_cfn_ctz_internal (true);
1006 : :
1007 : : bool
1008 : 11625 : cfn_ctz::fold_range (irange &r, tree type, const irange &lh,
1009 : : const irange &rh, relation_trio) const
1010 : : {
1011 : 11625 : if (lh.undefined_p ())
1012 : : return false;
1013 : 11598 : int prec = TYPE_PRECISION (lh.type ());
1014 : 11598 : int mini = 0;
1015 : 11598 : int maxi = prec - 1;
1016 : :
1017 : 11598 : if (m_gimple_call_internal_p)
1018 : : {
1019 : : // Handle only the two common values.
1020 : 79 : if (rh.lower_bound () == -1)
1021 : : mini = -1;
1022 : 79 : else if (rh.lower_bound () == prec)
1023 : 79 : maxi = prec;
1024 : : else
1025 : : // Magic value to give up, unless we can prove arg is non-zero.
1026 : : mini = -2;
1027 : : }
1028 : : // If arg is non-zero, then use [0, prec - 1].
1029 : 11598 : if (!range_includes_zero_p (lh))
1030 : : {
1031 : 8204 : mini = 0;
1032 : 8204 : maxi = prec - 1;
1033 : : }
1034 : : // If some high bits are known to be zero, we can decrease
1035 : : // the maximum.
1036 : 11598 : wide_int max = lh.upper_bound ();
1037 : 11598 : if (max == 0)
1038 : : {
1039 : : // Argument is [0, 0]. If CTZ_DEFINED_VALUE_AT_ZERO
1040 : : // is 2 with value -1 or prec, return [-1, -1] or [prec, prec].
1041 : : // Otherwise ignore the range.
1042 : 7 : if (mini == -1)
1043 : : maxi = -1;
1044 : 7 : else if (maxi == prec)
1045 : 11598 : mini = prec;
1046 : : }
1047 : : // If value at zero is prec and 0 is in the range, we can't lower
1048 : : // the upper bound. We could create two separate ranges though,
1049 : : // [0,floor_log2(max)][prec,prec] though.
1050 : 11591 : else if (maxi != prec)
1051 : 11512 : maxi = wi::floor_log2 (max);
1052 : :
1053 : 11598 : if (mini == -2)
1054 : : return false;
1055 : 11598 : r.set (type,
1056 : 23196 : wi::shwi (mini, TYPE_PRECISION (type)),
1057 : 11598 : wi::shwi (maxi, TYPE_PRECISION (type)));
1058 : 11598 : return true;
1059 : 11598 : }
1060 : :
1061 : :
1062 : : // Implement range operator for CFN_BUILT_IN_
1063 : : class cfn_clrsb : public range_operator
1064 : : {
1065 : : public:
1066 : : using range_operator::fold_range;
1067 : 916 : virtual bool fold_range (irange &r, tree type, const irange &lh,
1068 : : const irange &, relation_trio) const
1069 : : {
1070 : 916 : if (lh.undefined_p ())
1071 : : return false;
1072 : 916 : int prec = TYPE_PRECISION (lh.type ());
1073 : 916 : r.set (type,
1074 : 1832 : wi::zero (TYPE_PRECISION (type)),
1075 : 916 : wi::shwi (prec - 1, TYPE_PRECISION (type)));
1076 : 916 : return true;
1077 : : }
1078 : : } op_cfn_clrsb;
1079 : :
1080 : :
1081 : : // Implement range operator for CFN_BUILT_IN_
1082 : : class cfn_ubsan : public range_operator
1083 : : {
1084 : : public:
1085 : : cfn_ubsan (enum tree_code code) { m_code = code; }
1086 : : using range_operator::fold_range;
1087 : 15392 : virtual bool fold_range (irange &r, tree type, const irange &lh,
1088 : : const irange &rh, relation_trio rel) const
1089 : : {
1090 : 15392 : bool saved_flag_wrapv = flag_wrapv;
1091 : : // Pretend the arithmetic is wrapping. If there is any overflow,
1092 : : // we'll complain, but will actually do wrapping operation.
1093 : 15392 : flag_wrapv = 1;
1094 : 15392 : bool result = range_op_handler (m_code).fold_range (r, type, lh, rh, rel);
1095 : 15392 : flag_wrapv = saved_flag_wrapv;
1096 : :
1097 : : // If for both arguments vrp_valueize returned non-NULL, this should
1098 : : // have been already folded and if not, it wasn't folded because of
1099 : : // overflow. Avoid removing the UBSAN_CHECK_* calls in that case.
1100 : 15392 : if (result && r.singleton_p ())
1101 : 361 : r.set_varying (type);
1102 : 15392 : return result;
1103 : : }
1104 : : private:
1105 : : enum tree_code m_code;
1106 : : };
1107 : :
1108 : : cfn_ubsan op_cfn_ubsan_add (PLUS_EXPR);
1109 : : cfn_ubsan op_cfn_ubsan_sub (MINUS_EXPR);
1110 : : cfn_ubsan op_cfn_ubsan_mul (MULT_EXPR);
1111 : :
1112 : :
1113 : : // Implement range operator for CFN_BUILT_IN_STRLEN
1114 : : class cfn_strlen : public range_operator
1115 : : {
1116 : : public:
1117 : : using range_operator::fold_range;
1118 : 234051 : virtual bool fold_range (irange &r, tree type, const prange &,
1119 : : const irange &, relation_trio) const
1120 : : {
1121 : 234051 : wide_int max = irange_val_max (ptrdiff_type_node);
1122 : : // To account for the terminating NULL, the maximum length
1123 : : // is one less than the maximum array size, which in turn
1124 : : // is one less than PTRDIFF_MAX (or SIZE_MAX where it's
1125 : : // smaller than the former type).
1126 : : // FIXME: Use max_object_size() - 1 here.
1127 : 234051 : r.set (type, wi::zero (TYPE_PRECISION (type)), max - 2);
1128 : 234051 : return true;
1129 : 234051 : }
1130 : : } op_cfn_strlen;
1131 : :
1132 : :
1133 : : // Implement range operator for CFN_BUILT_IN_GOACC_DIM
1134 : : class cfn_goacc_dim : public range_operator
1135 : : {
1136 : : public:
1137 : : cfn_goacc_dim (bool is_pos) { m_is_pos = is_pos; }
1138 : : using range_operator::fold_range;
1139 : 16327 : virtual bool fold_range (irange &r, tree type, const irange &lh,
1140 : : const irange &, relation_trio) const
1141 : : {
1142 : 16327 : tree axis_tree;
1143 : 16327 : if (!lh.singleton_p (&axis_tree))
1144 : : return false;
1145 : 16327 : HOST_WIDE_INT axis = TREE_INT_CST_LOW (axis_tree);
1146 : 16327 : int size = oacc_get_fn_dim_size (current_function_decl, axis);
1147 : 16327 : if (!size)
1148 : : // If it's dynamic, the backend might know a hardware limitation.
1149 : 0 : size = targetm.goacc.dim_limit (axis);
1150 : :
1151 : 16327 : r.set (type,
1152 : 42648 : wi::shwi (m_is_pos ? 0 : 1, TYPE_PRECISION (type)),
1153 : : size
1154 : 16327 : ? wi::shwi (size - m_is_pos, TYPE_PRECISION (type))
1155 : : : irange_val_max (type));
1156 : 16327 : return true;
1157 : : }
1158 : : private:
1159 : : bool m_is_pos;
1160 : : } op_cfn_goacc_dim_size (false), op_cfn_goacc_dim_pos (true);
1161 : :
1162 : : // Implement range operator for CFN_BUILT_IN_ISINF
1163 : : class cfn_isinf : public range_operator
1164 : : {
1165 : : public:
1166 : : using range_operator::fold_range;
1167 : : using range_operator::op1_range;
1168 : 0 : virtual bool fold_range (irange &r, tree type, const frange &op1,
1169 : : const irange &, relation_trio) const override
1170 : : {
1171 : 0 : if (op1.undefined_p ())
1172 : : return false;
1173 : :
1174 : 0 : if (op1.known_isinf ())
1175 : : {
1176 : 0 : wide_int one = wi::one (TYPE_PRECISION (type));
1177 : 0 : r.set (type, one, one);
1178 : 0 : return true;
1179 : 0 : }
1180 : :
1181 : 0 : if (op1.known_isnan ()
1182 : 0 : || (!real_isinf (&op1.lower_bound ())
1183 : 0 : && !real_isinf (&op1.upper_bound ())))
1184 : : {
1185 : 0 : r.set_zero (type);
1186 : 0 : return true;
1187 : : }
1188 : :
1189 : 0 : r.set_varying (type);
1190 : 0 : return true;
1191 : : }
1192 : 0 : virtual bool op1_range (frange &r, tree type, const irange &lhs,
1193 : : const frange &, relation_trio) const override
1194 : : {
1195 : 0 : if (lhs.undefined_p ())
1196 : : return false;
1197 : :
1198 : 0 : if (lhs.zero_p ())
1199 : : {
1200 : 0 : nan_state nan (true);
1201 : 0 : r.set (type, real_min_representable (type),
1202 : 0 : real_max_representable (type), nan);
1203 : 0 : return true;
1204 : : }
1205 : :
1206 : 0 : if (!range_includes_zero_p (lhs))
1207 : : {
1208 : : // The range is [-INF,-INF][+INF,+INF], but it can't be represented.
1209 : : // Set range to [-INF,+INF]
1210 : 0 : r.set_varying (type);
1211 : 0 : r.clear_nan ();
1212 : 0 : return true;
1213 : : }
1214 : :
1215 : 0 : r.set_varying (type);
1216 : 0 : return true;
1217 : : }
1218 : : } op_cfn_isinf;
1219 : :
1220 : : //Implement range operator for CFN_BUILT_IN_ISFINITE
1221 : : class cfn_isfinite : public range_operator
1222 : : {
1223 : : public:
1224 : : using range_operator::fold_range;
1225 : : using range_operator::op1_range;
1226 : 0 : virtual bool fold_range (irange &r, tree type, const frange &op1,
1227 : : const irange &, relation_trio) const override
1228 : : {
1229 : 0 : if (op1.undefined_p ())
1230 : : return false;
1231 : :
1232 : 0 : if (op1.known_isfinite ())
1233 : : {
1234 : 0 : wide_int one = wi::one (TYPE_PRECISION (type));
1235 : 0 : r.set (type, one, one);
1236 : 0 : return true;
1237 : 0 : }
1238 : :
1239 : 0 : if (op1.known_isnan ()
1240 : 0 : || op1.known_isinf ())
1241 : : {
1242 : 0 : r.set_zero (type);
1243 : 0 : return true;
1244 : : }
1245 : :
1246 : 0 : r.set_varying (type);
1247 : 0 : return true;
1248 : : }
1249 : 0 : virtual bool op1_range (frange &r, tree type, const irange &lhs,
1250 : : const frange &, relation_trio) const override
1251 : : {
1252 : 0 : if (lhs.undefined_p ())
1253 : : return false;
1254 : :
1255 : 0 : if (lhs.zero_p ())
1256 : : {
1257 : : // The range is [-INF,-INF][+INF,+INF] NAN, but it can't be represented.
1258 : : // Set range to varying
1259 : 0 : r.set_varying (type);
1260 : 0 : return true;
1261 : : }
1262 : :
1263 : 0 : if (!range_includes_zero_p (lhs))
1264 : : {
1265 : 0 : nan_state nan (false);
1266 : 0 : r.set (type, real_min_representable (type),
1267 : 0 : real_max_representable (type), nan);
1268 : 0 : return true;
1269 : : }
1270 : :
1271 : 0 : r.set_varying (type);
1272 : 0 : return true;
1273 : : }
1274 : : } op_cfn_isfinite;
1275 : :
1276 : : //Implement range operator for CFN_BUILT_IN_ISNORMAL
1277 : : class cfn_isnormal : public range_operator
1278 : : {
1279 : : public:
1280 : : using range_operator::fold_range;
1281 : : using range_operator::op1_range;
1282 : 0 : virtual bool fold_range (irange &r, tree type, const frange &op1,
1283 : : const irange &, relation_trio) const override
1284 : : {
1285 : 0 : if (op1.undefined_p ())
1286 : : return false;
1287 : :
1288 : 0 : if (op1.known_isnormal ())
1289 : : {
1290 : 0 : wide_int one = wi::one (TYPE_PRECISION (type));
1291 : 0 : r.set (type, one, one);
1292 : 0 : return true;
1293 : 0 : }
1294 : :
1295 : 0 : if (op1.known_isnan ()
1296 : 0 : || op1.known_isinf ()
1297 : 0 : || op1.known_isdenormal_or_zero ())
1298 : : {
1299 : 0 : r.set_zero (type);
1300 : 0 : return true;
1301 : : }
1302 : :
1303 : 0 : r.set_varying (type);
1304 : 0 : return true;
1305 : : }
1306 : 0 : virtual bool op1_range (frange &r, tree type, const irange &lhs,
1307 : : const frange &, relation_trio) const override
1308 : : {
1309 : 0 : if (lhs.undefined_p ())
1310 : : return false;
1311 : :
1312 : 0 : if (lhs.zero_p ())
1313 : : {
1314 : 0 : r.set_varying (type);
1315 : 0 : return true;
1316 : : }
1317 : :
1318 : 0 : if (!range_includes_zero_p (lhs))
1319 : : {
1320 : 0 : nan_state nan (false);
1321 : 0 : r.set (type, real_min_representable (type),
1322 : 0 : real_max_representable (type), nan);
1323 : 0 : return true;
1324 : : }
1325 : :
1326 : 0 : r.set_varying (type);
1327 : 0 : return true;
1328 : : }
1329 : : } op_cfn_isnormal;
1330 : :
1331 : : // Implement range operator for CFN_BUILT_IN_
1332 : : class cfn_parity : public range_operator
1333 : : {
1334 : : public:
1335 : : using range_operator::fold_range;
1336 : 1116 : virtual bool fold_range (irange &r, tree type, const irange &,
1337 : : const irange &, relation_trio) const
1338 : : {
1339 : 1116 : r = range_true_and_false (type);
1340 : 1116 : return true;
1341 : : }
1342 : : } op_cfn_parity;
1343 : :
1344 : : // Set up a gimple_range_op_handler for any nonstandard function which can be
1345 : : // supported via range-ops.
1346 : :
1347 : : void
1348 : 296636565 : gimple_range_op_handler::maybe_non_standard ()
1349 : : {
1350 : 296636565 : range_op_handler signed_op (OP_WIDEN_MULT_SIGNED);
1351 : 296636565 : gcc_checking_assert (signed_op);
1352 : 296636565 : range_op_handler unsigned_op (OP_WIDEN_MULT_UNSIGNED);
1353 : 296636565 : gcc_checking_assert (unsigned_op);
1354 : :
1355 : 296636565 : if (gimple_code (m_stmt) == GIMPLE_ASSIGN)
1356 : 213042979 : switch (gimple_assign_rhs_code (m_stmt))
1357 : : {
1358 : 9322 : case WIDEN_MULT_EXPR:
1359 : 9322 : {
1360 : 9322 : m_op1 = gimple_assign_rhs1 (m_stmt);
1361 : 9322 : m_op2 = gimple_assign_rhs2 (m_stmt);
1362 : 9322 : tree ret = gimple_assign_lhs (m_stmt);
1363 : 9322 : bool signed1 = TYPE_SIGN (TREE_TYPE (m_op1)) == SIGNED;
1364 : 9322 : bool signed2 = TYPE_SIGN (TREE_TYPE (m_op2)) == SIGNED;
1365 : 9322 : bool signed_ret = TYPE_SIGN (TREE_TYPE (ret)) == SIGNED;
1366 : :
1367 : : /* Normally these operands should all have the same sign, but
1368 : : some passes and violate this by taking mismatched sign args. At
1369 : : the moment the only one that's possible is mismatch inputs and
1370 : : unsigned output. Once ranger supports signs for the operands we
1371 : : can properly fix it, for now only accept the case we can do
1372 : : correctly. */
1373 : 9322 : if ((signed1 ^ signed2) && signed_ret)
1374 : 0 : return;
1375 : :
1376 : 9322 : if (signed2 && !signed1)
1377 : 0 : std::swap (m_op1, m_op2);
1378 : :
1379 : 9322 : if (signed1 || signed2)
1380 : 1217 : m_operator = signed_op.range_op ();
1381 : : else
1382 : 8105 : m_operator = unsigned_op.range_op ();
1383 : : break;
1384 : : }
1385 : : default:
1386 : : break;
1387 : : }
1388 : : }
1389 : :
1390 : : // Set up a gimple_range_op_handler for any built in function which can be
1391 : : // supported via range-ops.
1392 : :
1393 : : void
1394 : 66396771 : gimple_range_op_handler::maybe_builtin_call ()
1395 : : {
1396 : 66396771 : gcc_checking_assert (is_a <gcall *> (m_stmt));
1397 : :
1398 : 66396771 : gcall *call = as_a <gcall *> (m_stmt);
1399 : 66396771 : combined_fn func = gimple_call_combined_fn (call);
1400 : 66396771 : if (func == CFN_LAST)
1401 : : return;
1402 : 30291499 : tree type = gimple_range_type (call);
1403 : 30291499 : if (!type)
1404 : : return;
1405 : 30291499 : if (!value_range::supports_type_p (type))
1406 : : return;
1407 : :
1408 : 30291499 : switch (func)
1409 : : {
1410 : 215072 : case CFN_BUILT_IN_CONSTANT_P:
1411 : 215072 : m_op1 = gimple_call_arg (call, 0);
1412 : 215072 : if (irange::supports_p (TREE_TYPE (m_op1)))
1413 : 213855 : m_operator = &op_cfn_constant_p;
1414 : 1217 : else if (frange::supports_p (TREE_TYPE (m_op1)))
1415 : 893 : m_operator = &op_cfn_constant_float_p;
1416 : : break;
1417 : :
1418 : 149924 : CASE_FLT_FN (CFN_BUILT_IN_SIGNBIT):
1419 : 149924 : m_op1 = gimple_call_arg (call, 0);
1420 : 149924 : m_operator = &op_cfn_signbit;
1421 : 149924 : break;
1422 : :
1423 : 0 : CASE_FLT_FN (CFN_BUILT_IN_ISINF):
1424 : 0 : m_op1 = gimple_call_arg (call, 0);
1425 : 0 : m_operator = &op_cfn_isinf;
1426 : 0 : break;
1427 : :
1428 : 0 : case CFN_BUILT_IN_ISFINITE:
1429 : 0 : m_op1 = gimple_call_arg (call, 0);
1430 : 0 : m_operator = &op_cfn_isfinite;
1431 : 0 : break;
1432 : :
1433 : 0 : case CFN_BUILT_IN_ISNORMAL:
1434 : 0 : m_op1 = gimple_call_arg (call, 0);
1435 : 0 : m_operator = &op_cfn_isnormal;
1436 : 0 : break;
1437 : :
1438 : 1090727 : CASE_CFN_COPYSIGN_ALL:
1439 : 1090727 : m_op1 = gimple_call_arg (call, 0);
1440 : 1090727 : m_op2 = gimple_call_arg (call, 1);
1441 : 1090727 : m_operator = &op_cfn_copysign;
1442 : 1090727 : break;
1443 : :
1444 : 106250 : CASE_CFN_SQRT:
1445 : 106250 : CASE_CFN_SQRT_FN:
1446 : 106250 : m_op1 = gimple_call_arg (call, 0);
1447 : 106250 : m_operator = &op_cfn_sqrt;
1448 : 106250 : break;
1449 : :
1450 : 26249 : CASE_CFN_SIN:
1451 : 26249 : CASE_CFN_SIN_FN:
1452 : 26249 : m_op1 = gimple_call_arg (call, 0);
1453 : 26249 : m_operator = &op_cfn_sin;
1454 : 26249 : break;
1455 : :
1456 : 14276 : CASE_CFN_COS:
1457 : 14276 : CASE_CFN_COS_FN:
1458 : 14276 : m_op1 = gimple_call_arg (call, 0);
1459 : 14276 : m_operator = &op_cfn_cos;
1460 : 14276 : break;
1461 : :
1462 : 58809 : case CFN_BUILT_IN_TOUPPER:
1463 : 58809 : case CFN_BUILT_IN_TOLOWER:
1464 : : // Only proceed If the argument is compatible with the LHS.
1465 : 58809 : m_op1 = gimple_call_arg (call, 0);
1466 : 58809 : if (range_compatible_p (type, TREE_TYPE (m_op1)))
1467 : 117340 : m_operator = (func == CFN_BUILT_IN_TOLOWER) ? &op_cfn_tolower
1468 : : : &op_cfn_toupper;
1469 : : break;
1470 : :
1471 : 6993 : CASE_CFN_FFS:
1472 : 6993 : m_op1 = gimple_call_arg (call, 0);
1473 : 6993 : m_operator = &op_cfn_ffs;
1474 : 6993 : break;
1475 : :
1476 : 13637 : CASE_CFN_POPCOUNT:
1477 : 13637 : m_op1 = gimple_call_arg (call, 0);
1478 : 13637 : m_operator = &op_cfn_popcount;
1479 : 13637 : break;
1480 : :
1481 : 459980 : CASE_CFN_CLZ:
1482 : 459980 : m_op1 = gimple_call_arg (call, 0);
1483 : 459980 : if (gimple_call_internal_p (call)
1484 : 459980 : && gimple_call_num_args (call) == 2)
1485 : : {
1486 : 310 : m_op2 = gimple_call_arg (call, 1);
1487 : 310 : m_operator = &op_cfn_clz_internal;
1488 : : }
1489 : : else
1490 : 459670 : m_operator = &op_cfn_clz;
1491 : : break;
1492 : :
1493 : 32503 : CASE_CFN_CTZ:
1494 : 32503 : m_op1 = gimple_call_arg (call, 0);
1495 : 32503 : if (gimple_call_internal_p (call)
1496 : 32503 : && gimple_call_num_args (call) == 2)
1497 : : {
1498 : 258 : m_op2 = gimple_call_arg (call, 1);
1499 : 258 : m_operator = &op_cfn_ctz_internal;
1500 : : }
1501 : : else
1502 : 32245 : m_operator = &op_cfn_ctz;
1503 : : break;
1504 : :
1505 : 3336 : CASE_CFN_CLRSB:
1506 : 3336 : m_op1 = gimple_call_arg (call, 0);
1507 : 3336 : m_operator = &op_cfn_clrsb;
1508 : 3336 : break;
1509 : :
1510 : 21439 : case CFN_UBSAN_CHECK_ADD:
1511 : 21439 : m_op1 = gimple_call_arg (call, 0);
1512 : 21439 : m_op2 = gimple_call_arg (call, 1);
1513 : 21439 : m_operator = &op_cfn_ubsan_add;
1514 : 21439 : break;
1515 : :
1516 : 19489 : case CFN_UBSAN_CHECK_SUB:
1517 : 19489 : m_op1 = gimple_call_arg (call, 0);
1518 : 19489 : m_op2 = gimple_call_arg (call, 1);
1519 : 19489 : m_operator = &op_cfn_ubsan_sub;
1520 : 19489 : break;
1521 : :
1522 : 17257 : case CFN_UBSAN_CHECK_MUL:
1523 : 17257 : m_op1 = gimple_call_arg (call, 0);
1524 : 17257 : m_op2 = gimple_call_arg (call, 1);
1525 : 17257 : m_operator = &op_cfn_ubsan_mul;
1526 : 17257 : break;
1527 : :
1528 : 827246 : case CFN_BUILT_IN_STRLEN:
1529 : 827246 : {
1530 : 827246 : tree lhs = gimple_call_lhs (call);
1531 : 827246 : if (lhs && ptrdiff_type_node && (TYPE_PRECISION (ptrdiff_type_node)
1532 : 827246 : == TYPE_PRECISION (TREE_TYPE (lhs))))
1533 : : {
1534 : 827246 : m_op1 = gimple_call_arg (call, 0);
1535 : 827246 : m_operator = &op_cfn_strlen;
1536 : : }
1537 : : break;
1538 : : }
1539 : :
1540 : : // Optimizing these two internal functions helps the loop
1541 : : // optimizer eliminate outer comparisons. Size is [1,N]
1542 : : // and pos is [0,N-1].
1543 : 40999 : case CFN_GOACC_DIM_SIZE:
1544 : : // This call will ensure all the asserts are triggered.
1545 : 40999 : oacc_get_ifn_dim_arg (call);
1546 : 40999 : m_op1 = gimple_call_arg (call, 0);
1547 : 40999 : m_operator = &op_cfn_goacc_dim_size;
1548 : 40999 : break;
1549 : :
1550 : 55672 : case CFN_GOACC_DIM_POS:
1551 : : // This call will ensure all the asserts are triggered.
1552 : 55672 : oacc_get_ifn_dim_arg (call);
1553 : 55672 : m_op1 = gimple_call_arg (call, 0);
1554 : 55672 : m_operator = &op_cfn_goacc_dim_pos;
1555 : 55672 : break;
1556 : :
1557 : 5893 : CASE_CFN_PARITY:
1558 : 5893 : m_operator = &op_cfn_parity;
1559 : 5893 : break;
1560 : :
1561 : 27125748 : default:
1562 : 27125748 : {
1563 : 27125748 : unsigned arg;
1564 : 27125748 : if (gimple_call_fnspec (call).returns_arg (&arg) && arg == 0)
1565 : : {
1566 : 1222482 : m_op1 = gimple_call_arg (call, 0);
1567 : 1222482 : m_operator = &op_cfn_pass_through_arg1;
1568 : : }
1569 : : break;
1570 : : }
1571 : : }
1572 : : }
|