Line data Source code
1 : /* Code for GIMPLE range op related routines.
2 : Copyright (C) 2019-2026 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 326881435 : gimple_range_ssa_names (tree *vec, unsigned vec_size, gimple *stmt)
55 : {
56 326881435 : tree ssa;
57 326881435 : int count = 0;
58 :
59 326881435 : gimple_range_op_handler handler (stmt);
60 326881435 : if (handler)
61 : {
62 87696802 : gcc_checking_assert (vec_size >= 2);
63 87696802 : if ((ssa = gimple_range_ssa_p (handler.operand1 ())))
64 74536691 : vec[count++] = ssa;
65 87696802 : if ((ssa = gimple_range_ssa_p (handler.operand2 ())))
66 20385187 : vec[count++] = ssa;
67 : }
68 239184633 : else if (is_a<gassign *> (stmt)
69 239184633 : && gimple_assign_rhs_code (stmt) == COND_EXPR)
70 : {
71 106801 : gcc_checking_assert (vec_size >= 3);
72 106801 : gassign *st = as_a<gassign *> (stmt);
73 106801 : if ((ssa = gimple_range_ssa_p (gimple_assign_rhs1 (st))))
74 106801 : vec[count++] = ssa;
75 213602 : if ((ssa = gimple_range_ssa_p (gimple_assign_rhs2 (st))))
76 98577 : vec[count++] = ssa;
77 213602 : if ((ssa = gimple_range_ssa_p (gimple_assign_rhs3 (st))))
78 37986 : vec[count++] = ssa;
79 : }
80 326881435 : return count;
81 : }
82 :
83 : // Return the base of the RHS of an assignment.
84 :
85 : static tree
86 919318268 : gimple_range_base_of_assignment (const gimple *stmt)
87 : {
88 919318268 : gcc_checking_assert (gimple_code (stmt) == GIMPLE_ASSIGN);
89 919318268 : tree op1 = gimple_assign_rhs1 (stmt);
90 919318268 : if (gimple_assign_rhs_code (stmt) == ADDR_EXPR)
91 12883308 : 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 2321746786 : get_code (gimple *s)
99 : {
100 2321746786 : if (const gassign *ass = dyn_cast<const gassign *> (s))
101 1279890032 : return gimple_assign_rhs_code (ass);
102 1041856754 : if (const gcond *cond = dyn_cast<const gcond *> (s))
103 429051821 : 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 403347605 : gimple_range_op_handler::supported_p (gimple *s)
111 : {
112 403347605 : enum tree_code code = get_code (s);
113 403347605 : if (range_op_handler (code))
114 : return true;
115 103901816 : if (is_a <gcall *> (s) && gimple_range_op_handler (s))
116 742036 : return true;
117 : return false;
118 : }
119 :
120 : // Construct a handler object for statement S.
121 :
122 1918399181 : gimple_range_op_handler::gimple_range_op_handler (gimple *s)
123 : {
124 1918399181 : range_op_handler oper (get_code (s));
125 1918399181 : m_stmt = s;
126 1918399181 : m_op1 = NULL_TREE;
127 1918399181 : m_op2 = NULL_TREE;
128 : // Recomputation defaults to TRUE.
129 1918399181 : m_recomputable = true;
130 :
131 1918399181 : if (oper)
132 1133496942 : switch (gimple_code (m_stmt))
133 : {
134 214178674 : case GIMPLE_COND:
135 214178674 : m_op1 = gimple_cond_lhs (m_stmt);
136 214178674 : m_op2 = gimple_cond_rhs (m_stmt);
137 : // Check that operands are supported types. One check is enough.
138 214178674 : if (value_range::supports_type_p (TREE_TYPE (m_op1)))
139 214117374 : m_operator = oper.range_op ();
140 214178674 : gcc_checking_assert (m_operator);
141 1133496942 : return;
142 919318268 : case GIMPLE_ASSIGN:
143 919318268 : m_op1 = gimple_range_base_of_assignment (m_stmt);
144 919318268 : if (m_op1 && TREE_CODE (m_op1) == MEM_REF)
145 : {
146 : // If the base address is an SSA_NAME, we return it
147 : // here. This allows processing of the range of that
148 : // name, while the rest of the expression is simply
149 : // ignored. The code in range_ops will see the
150 : // ADDR_EXPR and do the right thing.
151 12507865 : tree ssa = TREE_OPERAND (m_op1, 0);
152 12507865 : if (TREE_CODE (ssa) == SSA_NAME)
153 12507760 : m_op1 = ssa;
154 : }
155 : // VIEW_CONVERT_EXPR needs to descend one level deeper to pick
156 : // up the symbolic operand.
157 919318268 : if (TREE_CODE (m_op1) == VIEW_CONVERT_EXPR)
158 2550621 : m_op1 = TREE_OPERAND (m_op1, 0);
159 919318268 : if (gimple_num_ops (m_stmt) >= 3)
160 715260075 : m_op2 = gimple_assign_rhs2 (m_stmt);
161 : // Check that operands are supported types. One check is enough.
162 919318268 : if ((m_op1 && !value_range::supports_type_p (TREE_TYPE (m_op1))))
163 : return;
164 918785603 : m_operator = oper.range_op ();
165 918785603 : gcc_checking_assert (m_operator);
166 : return;
167 0 : default:
168 0 : gcc_unreachable ();
169 : return;
170 : }
171 : // If no range-op table entry handled this stmt, check for other supported
172 : // statements.
173 784902239 : if (is_a <gcall *> (m_stmt))
174 69063266 : maybe_builtin_call ();
175 : else
176 715838973 : maybe_non_standard ();
177 784902239 : gcc_checking_assert (m_operator);
178 : }
179 :
180 : // Calculate what we can determine of the range of this unary
181 : // statement's operand if the lhs of the expression has the range
182 : // LHS_RANGE. Return false if nothing can be determined.
183 :
184 : bool
185 17903 : gimple_range_op_handler::calc_op1 (vrange &r, const vrange &lhs_range)
186 : {
187 : // Give up on empty ranges.
188 17903 : if (lhs_range.undefined_p ())
189 : return false;
190 :
191 : // Unary operations require the type of the first operand in the
192 : // second range position.
193 17903 : tree type = TREE_TYPE (operand1 ());
194 17903 : value_range type_range (type);
195 17903 : type_range.set_varying (type);
196 17903 : return op1_range (r, type, lhs_range, type_range);
197 17903 : }
198 :
199 : // Calculate what we can determine of the range of this statement's
200 : // first operand if the lhs of the expression has the range LHS_RANGE
201 : // and the second operand has the range OP2_RANGE. Return false if
202 : // nothing can be determined.
203 :
204 : bool
205 95131147 : gimple_range_op_handler::calc_op1 (vrange &r, const vrange &lhs_range,
206 : const vrange &op2_range, relation_trio k)
207 : {
208 : // Give up on empty ranges.
209 95131147 : if (lhs_range.undefined_p ())
210 : return false;
211 :
212 : // Unary operation are allowed to pass a range in for second operand
213 : // as there are often additional restrictions beyond the type which
214 : // can be imposed. See operator_cast::op1_range().
215 95131147 : tree type = TREE_TYPE (operand1 ());
216 : // If op2 is undefined, solve as if it is varying.
217 95131147 : if (op2_range.undefined_p ())
218 : {
219 47940 : if (gimple_num_ops (m_stmt) < 3)
220 : return false;
221 12643 : tree op2_type;
222 : // This is sometimes invoked on single operand stmts.
223 12643 : if (operand2 ())
224 10712 : op2_type = TREE_TYPE (operand2 ());
225 : else
226 1931 : op2_type = TREE_TYPE (operand1 ());
227 12643 : value_range trange (op2_type);
228 12643 : trange.set_varying (op2_type);
229 12643 : return op1_range (r, type, lhs_range, trange, k);
230 12643 : }
231 95083207 : return op1_range (r, type, lhs_range, op2_range, k);
232 : }
233 :
234 : // Calculate what we can determine of the range of this statement's
235 : // second operand if the lhs of the expression has the range LHS_RANGE
236 : // and the first operand has the range OP1_RANGE. Return false if
237 : // nothing can be determined.
238 :
239 : bool
240 26068744 : gimple_range_op_handler::calc_op2 (vrange &r, const vrange &lhs_range,
241 : const vrange &op1_range, relation_trio k)
242 : {
243 : // Give up on empty ranges.
244 26068744 : if (lhs_range.undefined_p ())
245 : return false;
246 :
247 26068744 : tree type = TREE_TYPE (operand2 ());
248 : // If op1 is undefined, solve as if it is varying.
249 26068744 : if (op1_range.undefined_p ())
250 : {
251 8829 : tree op1_type = TREE_TYPE (operand1 ());
252 8829 : value_range trange (op1_type);
253 8829 : trange.set_varying (op1_type);
254 8829 : return op2_range (r, type, lhs_range, trange, k);
255 8829 : }
256 26059915 : return op2_range (r, type, lhs_range, op1_range, k);
257 : }
258 :
259 : // --------------------------------------------------------------------
260 :
261 : // Implement range operator for float CFN_BUILT_IN_CONSTANT_P.
262 : class cfn_constant_float_p : public range_operator
263 : {
264 : public:
265 : using range_operator::fold_range;
266 174 : virtual bool fold_range (irange &r, tree type, const frange &lh,
267 : const irange &, relation_trio) const
268 : {
269 174 : if (lh.singleton_p ())
270 : {
271 0 : wide_int one = wi::one (TYPE_PRECISION (type));
272 0 : r.set (type, one, one);
273 0 : return true;
274 0 : }
275 174 : if (cfun->after_inlining)
276 : {
277 56 : r.set_zero (type);
278 56 : return true;
279 : }
280 : return false;
281 : }
282 : } op_cfn_constant_float_p;
283 :
284 : // Implement range operator for integral CFN_BUILT_IN_CONSTANT_P.
285 : class cfn_constant_p : public range_operator
286 : {
287 : public:
288 : using range_operator::fold_range;
289 161329 : virtual bool fold_range (irange &r, tree type, const irange &lh,
290 : const irange &, relation_trio) const
291 : {
292 161329 : if (lh.singleton_p ())
293 : {
294 926 : wide_int one = wi::one (TYPE_PRECISION (type));
295 926 : r.set (type, one, one);
296 926 : return true;
297 926 : }
298 160403 : if (cfun->after_inlining)
299 : {
300 80587 : r.set_zero (type);
301 80587 : return true;
302 : }
303 : return false;
304 : }
305 : } op_cfn_constant_p;
306 :
307 : // Implement range operator for integral/pointer functions returning
308 : // the first argument.
309 : class cfn_pass_through_arg1 : public range_operator
310 : {
311 : public:
312 : using range_operator::fold_range;
313 : using range_operator::op1_range;
314 218551 : virtual bool fold_range (irange &r, tree, const irange &lh,
315 : const irange &, relation_trio) const
316 : {
317 218551 : r = lh;
318 218551 : return true;
319 : }
320 81266 : virtual bool fold_range (prange &r, tree, const prange &lh,
321 : const prange &, relation_trio) const
322 : {
323 81266 : r = lh;
324 81266 : return true;
325 : }
326 296420 : virtual bool op1_range (irange &r, tree, const irange &lhs,
327 : const irange &, relation_trio) const
328 : {
329 296420 : r = lhs;
330 296420 : return true;
331 : }
332 10319 : virtual bool op1_range (prange &r, tree, const prange &lhs,
333 : const prange &, relation_trio) const
334 : {
335 10319 : r = lhs;
336 10319 : return true;
337 : }
338 : } op_cfn_pass_through_arg1;
339 :
340 : // Implement range operator for CFN_BUILT_IN_SIGNBIT.
341 : class cfn_signbit : public range_operator
342 : {
343 : public:
344 : using range_operator::fold_range;
345 : using range_operator::op1_range;
346 54844 : virtual bool fold_range (irange &r, tree type, const frange &lh,
347 : const irange &, relation_trio) const override
348 : {
349 54844 : bool signbit;
350 54844 : if (lh.signbit_p (signbit))
351 : {
352 2798 : if (signbit)
353 1429 : r.set_nonzero (type);
354 : else
355 1369 : r.set_zero (type);
356 : return true;
357 : }
358 : return false;
359 : }
360 10797 : virtual bool op1_range (frange &r, tree type, const irange &lhs,
361 : const frange &, relation_trio) const override
362 : {
363 10797 : if (lhs.zero_p ())
364 : {
365 5076 : r.set (type, dconst0, frange_val_max (type));
366 5076 : r.update_nan (false);
367 5076 : return true;
368 : }
369 5721 : if (!lhs.contains_p (wi::zero (TYPE_PRECISION (lhs.type ()))))
370 : {
371 5721 : r.set (type, frange_val_min (type), dconstm0);
372 5721 : r.update_nan (true);
373 5721 : return true;
374 : }
375 : return false;
376 : }
377 : } op_cfn_signbit;
378 :
379 : // Implement range operator for CFN_BUILT_IN_COPYSIGN
380 : class cfn_copysign : public range_operator
381 : {
382 : public:
383 : using range_operator::fold_range;
384 157049 : virtual bool fold_range (frange &r, tree type, const frange &lh,
385 : const frange &rh, relation_trio) const override
386 : {
387 157049 : frange neg;
388 157049 : if (!range_op_handler (ABS_EXPR).fold_range (r, type, lh, frange (type)))
389 : return false;
390 314098 : if (!range_op_handler (NEGATE_EXPR).fold_range (neg, type, r,
391 157049 : frange (type)))
392 : return false;
393 :
394 157049 : bool signbit;
395 157049 : if (rh.signbit_p (signbit))
396 : {
397 : // If the sign is negative, flip the result from ABS,
398 : // otherwise leave things positive.
399 385 : if (signbit)
400 381 : r = neg;
401 : }
402 : else
403 : // If the sign is unknown, keep the positive and negative
404 : // alternatives.
405 156664 : r.union_ (neg);
406 : return true;
407 157049 : }
408 : } op_cfn_copysign;
409 :
410 : /* Compute FUNC (ARG) where FUNC is a mpfr function. If RES_LOW is non-NULL,
411 : set it to low bound of possible range if the function is expected to have
412 : ULPS precision and similarly if RES_HIGH is non-NULL, set it to high bound.
413 : If the function returns false, the results weren't set. */
414 :
415 : static bool
416 49904 : frange_mpfr_arg1 (REAL_VALUE_TYPE *res_low, REAL_VALUE_TYPE *res_high,
417 : int (*func) (mpfr_ptr, mpfr_srcptr, mpfr_rnd_t),
418 : const REAL_VALUE_TYPE &arg, tree type, unsigned ulps)
419 : {
420 49904 : if (ulps == ~0U || !real_isfinite (&arg))
421 : return false;
422 23223 : machine_mode mode = TYPE_MODE (type);
423 23223 : const real_format *format = REAL_MODE_FORMAT (mode);
424 23223 : auto_mpfr m (format->p);
425 23223 : mpfr_from_real (m, &arg, MPFR_RNDN);
426 23223 : mpfr_clear_flags ();
427 23223 : bool inexact = func (m, m, MPFR_RNDN);
428 23223 : if (!mpfr_number_p (m) || mpfr_overflow_p () || mpfr_underflow_p ())
429 : return false;
430 :
431 21724 : REAL_VALUE_TYPE value, result;
432 21724 : real_from_mpfr (&value, m, format, MPFR_RNDN);
433 21724 : if (!real_isfinite (&value))
434 : return false;
435 21724 : if ((value.cl == rvc_zero) != (mpfr_zero_p (m) != 0))
436 0 : inexact = true;
437 :
438 21724 : real_convert (&result, format, &value);
439 21724 : if (!real_isfinite (&result))
440 : return false;
441 21724 : bool round_low = false;
442 21724 : bool round_high = false;
443 21724 : if (!ulps && flag_rounding_math)
444 0 : ++ulps;
445 21724 : if (inexact || !real_identical (&result, &value))
446 : {
447 48062 : if (MODE_COMPOSITE_P (mode))
448 : round_low = round_high = true;
449 : else
450 : {
451 6866 : round_low = !real_less (&result, &value);
452 6866 : round_high = !real_less (&value, &result);
453 : }
454 : }
455 21724 : if (res_low)
456 : {
457 15379 : *res_low = result;
458 17781 : for (unsigned int i = 0; i < ulps + round_low; ++i)
459 2402 : frange_nextafter (mode, *res_low, dconstninf);
460 : }
461 21724 : if (res_high)
462 : {
463 7401 : *res_high = result;
464 14139 : for (unsigned int i = 0; i < ulps + round_high; ++i)
465 6738 : frange_nextafter (mode, *res_high, dconstinf);
466 : }
467 : return true;
468 23223 : }
469 :
470 : class cfn_sqrt : public range_operator
471 : {
472 : public:
473 : using range_operator::fold_range;
474 : using range_operator::op1_range;
475 32638 : virtual bool fold_range (frange &r, tree type,
476 : const frange &lh, const frange &,
477 : relation_trio) const final override
478 : {
479 32638 : if (lh.undefined_p ())
480 : return false;
481 32379 : if (lh.known_isnan () || real_less (&lh.upper_bound (), &dconstm0))
482 : {
483 7837 : r.set_nan (type);
484 7837 : return true;
485 : }
486 24542 : unsigned bulps
487 24542 : = targetm.libm_function_max_error (CFN_SQRT, TYPE_MODE (type), true);
488 24542 : if (bulps == ~0U)
489 0 : r.set_varying (type);
490 24542 : else if (bulps == 0)
491 24542 : r.set (type, dconstm0, dconstinf);
492 : else
493 : {
494 0 : REAL_VALUE_TYPE boundmin = dconstm0;
495 0 : while (bulps--)
496 0 : frange_nextafter (TYPE_MODE (type), boundmin, dconstninf);
497 0 : r.set (type, boundmin, dconstinf);
498 : }
499 31299 : if (!lh.maybe_isnan () && !real_less (&lh.lower_bound (), &dconst0))
500 4981 : r.clear_nan ();
501 :
502 24542 : unsigned ulps
503 24542 : = targetm.libm_function_max_error (CFN_SQRT, TYPE_MODE (type), false);
504 24542 : if (ulps == ~0U)
505 : return true;
506 24424 : REAL_VALUE_TYPE lb = lh.lower_bound ();
507 24424 : REAL_VALUE_TYPE ub = lh.upper_bound ();
508 24424 : if (!frange_mpfr_arg1 (&lb, NULL, mpfr_sqrt, lb, type, ulps))
509 10101 : lb = dconstninf;
510 24424 : if (!frange_mpfr_arg1 (NULL, &ub, mpfr_sqrt, ub, type, ulps))
511 18079 : ub = dconstinf;
512 24424 : frange r2;
513 24424 : r2.set (type, lb, ub);
514 24424 : r2.flush_denormals_to_zero ();
515 24424 : r.intersect (r2);
516 24424 : return true;
517 24424 : }
518 1114 : virtual bool op1_range (frange &r, tree type,
519 : const frange &lhs, const frange &,
520 : relation_trio) const final override
521 : {
522 1114 : if (lhs.undefined_p ())
523 : return false;
524 :
525 : // A known NAN means the input is [-INF,-0.) U +-NAN.
526 1114 : if (lhs.known_isnan ())
527 : {
528 0 : known_nan:
529 0 : REAL_VALUE_TYPE ub = dconstm0;
530 0 : frange_nextafter (TYPE_MODE (type), ub, dconstninf);
531 0 : r.set (type, dconstninf, ub);
532 : // No r.flush_denormals_to_zero (); here - it is a reverse op.
533 0 : return true;
534 : }
535 :
536 : // Results outside of [-0.0, +Inf] are impossible.
537 1114 : unsigned bulps
538 1114 : = targetm.libm_function_max_error (CFN_SQRT, TYPE_MODE (type), true);
539 1114 : if (bulps != ~0U)
540 : {
541 1114 : const REAL_VALUE_TYPE &ub = lhs.upper_bound ();
542 1114 : REAL_VALUE_TYPE m0 = dconstm0;
543 1114 : while (bulps--)
544 0 : frange_nextafter (TYPE_MODE (type), m0, dconstninf);
545 1114 : if (real_less (&ub, &m0))
546 : {
547 0 : if (!lhs.maybe_isnan ())
548 0 : r.set_undefined ();
549 : else
550 : // If lhs could be NAN and finite result is impossible,
551 : // the range is like lhs.known_isnan () above.
552 0 : goto known_nan;
553 0 : return true;
554 : }
555 : }
556 :
557 1724 : if (!lhs.maybe_isnan ())
558 : // If NAN is not valid result, the input cannot include either
559 : // a NAN nor values smaller than -0.
560 610 : r.set (type, dconstm0, dconstinf, nan_state (false, false));
561 : else
562 504 : r.set_varying (type);
563 :
564 1114 : unsigned ulps
565 1114 : = targetm.libm_function_max_error (CFN_SQRT, TYPE_MODE (type), false);
566 1114 : if (ulps == ~0U)
567 : return true;
568 1114 : REAL_VALUE_TYPE lb = lhs.lower_bound ();
569 1114 : REAL_VALUE_TYPE ub = lhs.upper_bound ();
570 1724 : if (!lhs.maybe_isnan () && real_less (&dconst0, &lb))
571 : {
572 146 : for (unsigned i = 0; i < ulps; ++i)
573 0 : frange_nextafter (TYPE_MODE (type), lb, dconstninf);
574 146 : if (real_less (&dconst0, &lb))
575 : {
576 146 : frange wlhs (type, lb, dconstinf);
577 146 : wlhs.clear_nan ();
578 146 : wlhs.widen (type);
579 146 : REAL_VALUE_TYPE op = wlhs.lower_bound ();
580 146 : frange_arithmetic (MULT_EXPR, type, lb, op, op, dconstninf);
581 146 : }
582 : else
583 0 : lb = dconstninf;
584 : }
585 : else
586 968 : lb = dconstninf;
587 1114 : if (real_isfinite (&ub) && real_less (&dconst0, &ub))
588 : {
589 278 : for (unsigned i = 0; i < ulps; ++i)
590 0 : frange_nextafter (TYPE_MODE (type), ub, dconstinf);
591 278 : if (real_isfinite (&ub))
592 : {
593 278 : frange wlhs (type, dconstninf, ub);
594 278 : wlhs.clear_nan ();
595 278 : wlhs.widen (type);
596 278 : REAL_VALUE_TYPE op = wlhs.upper_bound ();
597 278 : frange_arithmetic (MULT_EXPR, type, ub, op, op, dconstinf);
598 278 : }
599 : else
600 0 : ub = dconstinf;
601 : }
602 : else
603 836 : ub = dconstinf;
604 2228 : frange r2;
605 1114 : r2.set (type, lb, ub);
606 1114 : r.intersect (r2);
607 1114 : return true;
608 : }
609 : } op_cfn_sqrt;
610 :
611 : class cfn_sincos : public range_operator
612 : {
613 : public:
614 : using range_operator::fold_range;
615 : using range_operator::op1_range;
616 : cfn_sincos (combined_fn cfn) { m_cfn = cfn; }
617 12927 : virtual bool fold_range (frange &r, tree type,
618 : const frange &lh, const frange &,
619 : relation_trio) const final override
620 : {
621 12927 : if (lh.undefined_p ())
622 : return false;
623 12911 : if (lh.known_isnan () || lh.known_isinf ())
624 : {
625 0 : r.set_nan (type);
626 0 : return true;
627 : }
628 12911 : unsigned bulps = targetm.libm_function_max_error (m_cfn, TYPE_MODE (type),
629 : true);
630 12911 : if (bulps == ~0U)
631 0 : r.set_varying (type);
632 12911 : else if (bulps == 0)
633 12859 : r.set (type, dconstm1, dconst1);
634 : else
635 : {
636 52 : REAL_VALUE_TYPE boundmin, boundmax;
637 52 : boundmax = dconst1;
638 104 : while (bulps--)
639 52 : frange_nextafter (TYPE_MODE (type), boundmax, dconstinf);
640 52 : real_arithmetic (&boundmin, NEGATE_EXPR, &boundmax, NULL);
641 52 : r.set (type, boundmin, boundmax);
642 : }
643 16258 : if (!lh.maybe_isnan () && !lh.maybe_isinf ())
644 1223 : r.clear_nan ();
645 :
646 12911 : unsigned ulps
647 12911 : = targetm.libm_function_max_error (m_cfn, TYPE_MODE (type), false);
648 12911 : if (ulps == ~0U)
649 : return true;
650 12911 : REAL_VALUE_TYPE lb = lh.lower_bound ();
651 12911 : REAL_VALUE_TYPE ub = lh.upper_bound ();
652 12911 : REAL_VALUE_TYPE diff;
653 12911 : real_arithmetic (&diff, MINUS_EXPR, &ub, &lb);
654 12911 : if (!real_isfinite (&diff))
655 : return true;
656 1835 : REAL_VALUE_TYPE pi = dconst_pi ();
657 1835 : REAL_VALUE_TYPE pix2;
658 1835 : real_arithmetic (&pix2, PLUS_EXPR, &pi, &pi);
659 : // We can only try to narrow the range further if ub-lb < 2*pi.
660 1835 : if (!real_less (&diff, &pix2))
661 : return true;
662 264 : REAL_VALUE_TYPE lb_lo, lb_hi, ub_lo, ub_hi;
663 264 : REAL_VALUE_TYPE lb_deriv_lo, lb_deriv_hi, ub_deriv_lo, ub_deriv_hi;
664 264 : if (!frange_mpfr_arg1 (&lb_lo, &lb_hi,
665 264 : m_cfn == CFN_SIN ? mpfr_sin : mpfr_cos, lb,
666 : type, ulps)
667 264 : || !frange_mpfr_arg1 (&ub_lo, &ub_hi,
668 264 : m_cfn == CFN_SIN ? mpfr_sin : mpfr_cos, ub,
669 : type, ulps)
670 264 : || !frange_mpfr_arg1 (&lb_deriv_lo, &lb_deriv_hi,
671 264 : m_cfn == CFN_SIN ? mpfr_cos : mpfr_sin, lb,
672 : type, 0)
673 528 : || !frange_mpfr_arg1 (&ub_deriv_lo, &ub_deriv_hi,
674 264 : m_cfn == CFN_SIN ? mpfr_cos : mpfr_sin, ub,
675 : type, 0))
676 : return true;
677 264 : if (m_cfn == CFN_COS)
678 : {
679 : // Derivative of cos is -sin, so negate.
680 77 : lb_deriv_lo.sign ^= 1;
681 77 : lb_deriv_hi.sign ^= 1;
682 77 : ub_deriv_lo.sign ^= 1;
683 77 : ub_deriv_hi.sign ^= 1;
684 : }
685 :
686 264 : if (real_less (&lb_lo, &ub_lo))
687 127 : lb = lb_lo;
688 : else
689 137 : lb = ub_lo;
690 264 : if (real_less (&lb_hi, &ub_hi))
691 127 : ub = ub_hi;
692 : else
693 137 : ub = lb_hi;
694 :
695 : // The range between the function result on the boundaries may need
696 : // to be extended to +1 (+Inf) or -1 (-Inf) or both depending on the
697 : // derivative or length of the argument range (diff).
698 :
699 : // First handle special case, where the derivative has different signs,
700 : // so the bound must be roughly -1 or +1.
701 264 : if (real_isneg (&lb_deriv_lo) != real_isneg (&lb_deriv_hi))
702 : {
703 0 : if (real_isneg (&lb_lo))
704 0 : lb = dconstninf;
705 : else
706 0 : ub = dconstinf;
707 : }
708 264 : if (real_isneg (&ub_deriv_lo) != real_isneg (&ub_deriv_hi))
709 : {
710 0 : if (real_isneg (&ub_lo))
711 0 : lb = dconstninf;
712 : else
713 0 : ub = dconstinf;
714 : }
715 :
716 : // If derivative at lower_bound and upper_bound have the same sign,
717 : // the function grows or declines on the whole range if diff < pi, so
718 : // [lb, ub] is correct, and if diff >= pi the result range must include
719 : // both the minimum and maximum.
720 264 : if (real_isneg (&lb_deriv_lo) == real_isneg (&ub_deriv_lo))
721 : {
722 160 : if (!real_less (&diff, &pi))
723 : return true;
724 : }
725 : // If function declines at lower_bound and grows at upper_bound,
726 : // the result range must include the minimum, so set lb to -Inf.
727 104 : else if (real_isneg (&lb_deriv_lo))
728 23 : lb = dconstninf;
729 : // If function grows at lower_bound and declines at upper_bound,
730 : // the result range must include the maximum, so set ub to +Inf.
731 : else
732 81 : ub = dconstinf;
733 244 : frange r2;
734 244 : r2.set (type, lb, ub);
735 244 : r2.flush_denormals_to_zero ();
736 244 : r.intersect (r2);
737 244 : return true;
738 244 : }
739 2733 : virtual bool op1_range (frange &r, tree type,
740 : const frange &lhs, const frange &,
741 : relation_trio) const final override
742 : {
743 2733 : if (lhs.undefined_p ())
744 : return false;
745 :
746 : // A known NAN means the input is [-INF,-INF][+INF,+INF] U +-NAN,
747 : // which we can't currently represent.
748 2733 : if (lhs.known_isnan ())
749 : {
750 0 : r.set_varying (type);
751 0 : return true;
752 : }
753 :
754 : // Results outside of [-1.0, +1.0] are impossible.
755 2733 : unsigned bulps
756 2733 : = targetm.libm_function_max_error (m_cfn, TYPE_MODE (type), true);
757 2733 : if (bulps != ~0U)
758 : {
759 2733 : const REAL_VALUE_TYPE &lb = lhs.lower_bound ();
760 2733 : const REAL_VALUE_TYPE &ub = lhs.upper_bound ();
761 2733 : REAL_VALUE_TYPE m1 = dconstm1;
762 2733 : REAL_VALUE_TYPE p1 = dconst1;
763 2733 : while (bulps--)
764 : {
765 0 : frange_nextafter (TYPE_MODE (type), m1, dconstninf);
766 0 : frange_nextafter (TYPE_MODE (type), p1, dconstinf);
767 : }
768 2733 : if (real_less (&ub, &m1) || real_less (&p1, &lb))
769 : {
770 0 : if (!lhs.maybe_isnan ())
771 0 : r.set_undefined ();
772 : else
773 : /* If lhs could be NAN and finite result is impossible,
774 : the range is like lhs.known_isnan () above,
775 : [-INF,-INF][+INF,+INF] U +-NAN. */
776 0 : r.set_varying (type);
777 0 : return true;
778 : }
779 : }
780 :
781 3836 : if (!lhs.maybe_isnan ())
782 : {
783 : // If NAN is not valid result, the input cannot include either
784 : // a NAN nor a +-INF.
785 1103 : REAL_VALUE_TYPE lb = real_min_representable (type);
786 1103 : REAL_VALUE_TYPE ub = real_max_representable (type);
787 1103 : r.set (type, lb, ub, nan_state (false, false));
788 : }
789 : else
790 1630 : r.set_varying (type);
791 : return true;
792 : }
793 : private:
794 : combined_fn m_cfn;
795 : } op_cfn_sin (CFN_SIN), op_cfn_cos (CFN_COS);
796 :
797 :
798 : // FP functions which are nonnegative independent of the arguments.
799 : class cfn_fp_nonnegative : public range_operator
800 : {
801 : public:
802 : using range_operator::fold_range;
803 22166 : virtual bool fold_range (frange &r, tree type,
804 : const frange &, const frange &,
805 : relation_trio) const final override
806 : {
807 22166 : r.set_nonnegative (type);
808 22166 : return true;
809 : }
810 : } op_cfn_fp_nonegative;
811 :
812 : // FP functions which are nonnegative if arg0 is nonnegative.
813 : // Also handles pass through of if non-nan
814 : class cfn_fp_nonnegative_arg0 : public range_operator
815 : {
816 : public:
817 : using range_operator::fold_range;
818 : cfn_fp_nonnegative_arg0(bool nan) : arg_nan (nan) {}
819 40873 : virtual bool fold_range (frange &r, tree type,
820 : const frange &op1, const frange &,
821 : relation_trio) const final override
822 : {
823 40873 : if (op1.undefined_p ())
824 : return false;
825 40831 : bool changed = false;
826 40831 : bool sign = false;
827 40831 : if (op1.signbit_p (sign) && !sign)
828 : {
829 9067 : r.set_nonnegative (type);
830 9067 : changed = true;
831 : }
832 49377 : if (arg_nan && !op1.maybe_isnan ())
833 : {
834 8546 : if (r.undefined_p ())
835 5780 : r.set_varying (type);
836 8546 : r.clear_nan ();
837 8546 : changed = true;
838 : }
839 : return changed;
840 : }
841 : private:
842 : bool arg_nan;
843 : } op_cfn_fp_nonegative_arg0(false), op_cfn_fp_nonegative_nan_arg0(true);
844 :
845 : // Implement range operator for CFN_BUILT_IN_TOUPPER and CFN_BUILT_IN_TOLOWER.
846 : class cfn_toupper_tolower : public range_operator
847 : {
848 : public:
849 : using range_operator::fold_range;
850 : cfn_toupper_tolower (bool toupper) { m_toupper = toupper; }
851 : virtual bool fold_range (irange &r, tree type, const irange &lh,
852 : const irange &, relation_trio) const;
853 : private:
854 : bool get_letter_range (tree type, irange &lowers, irange &uppers) const;
855 : bool m_toupper;
856 : } op_cfn_toupper (true), op_cfn_tolower (false);
857 :
858 : // Return TRUE if we recognize the target character set and return the
859 : // range for lower case and upper case letters.
860 :
861 : bool
862 217 : cfn_toupper_tolower::get_letter_range (tree type, irange &lowers,
863 : irange &uppers) const
864 : {
865 : // ASCII
866 217 : int a = lang_hooks.to_target_charset ('a');
867 217 : int z = lang_hooks.to_target_charset ('z');
868 217 : int A = lang_hooks.to_target_charset ('A');
869 217 : int Z = lang_hooks.to_target_charset ('Z');
870 :
871 217 : if ((z - a == 25) && (Z - A == 25))
872 : {
873 217 : lowers = int_range<2> (type,
874 434 : wi::shwi (a, TYPE_PRECISION (type)),
875 434 : wi::shwi (z, TYPE_PRECISION (type)));
876 217 : uppers = int_range<2> (type,
877 434 : wi::shwi (A, TYPE_PRECISION (type)),
878 434 : wi::shwi (Z, TYPE_PRECISION (type)));
879 217 : return true;
880 : }
881 : // Unknown character set.
882 : return false;
883 : }
884 :
885 : bool
886 217 : cfn_toupper_tolower::fold_range (irange &r, tree type, const irange &lh,
887 : const irange &, relation_trio) const
888 : {
889 217 : int_range<3> lowers;
890 217 : int_range<3> uppers;
891 217 : if (!get_letter_range (type, lowers, uppers))
892 : return false;
893 :
894 217 : r = lh;
895 217 : if (m_toupper)
896 : {
897 : // Return the range passed in without any lower case characters,
898 : // but including all the upper case ones.
899 117 : bool res = lowers.invert ();
900 117 : gcc_checking_assert (res);
901 117 : r.intersect (lowers);
902 117 : r.union_ (uppers);
903 : }
904 : else
905 : {
906 : // Return the range passed in without any lower case characters,
907 : // but including all the upper case ones.
908 100 : bool res = uppers.invert ();
909 100 : gcc_checking_assert (res);
910 100 : r.intersect (uppers);
911 100 : r.union_ (lowers);
912 : }
913 : return true;
914 217 : }
915 :
916 : // Implement range operator for CFN_BUILT_IN_FFS.
917 : class cfn_ffs : public range_operator
918 : {
919 : public:
920 : using range_operator::fold_range;
921 6558 : virtual bool fold_range (irange &r, tree type, const irange &lh,
922 : const irange &, relation_trio) const
923 : {
924 6558 : if (lh.undefined_p ())
925 : return false;
926 : // __builtin_ffs* and __builtin_popcount* return [0, prec].
927 6558 : int prec = TYPE_PRECISION (lh.type ());
928 : // If arg is non-zero, then ffs or popcount are non-zero.
929 6558 : int mini = range_includes_zero_p (lh) ? 0 : 1;
930 6558 : int maxi = prec;
931 :
932 : // If some high bits are known to be zero, decrease the maximum.
933 6558 : int_range_max tmp = lh;
934 6558 : if (TYPE_SIGN (tmp.type ()) == SIGNED)
935 1841 : range_cast (tmp, unsigned_type_for (tmp.type ()));
936 6558 : wide_int max = tmp.upper_bound ();
937 6558 : maxi = wi::floor_log2 (max) + 1;
938 6558 : r.set (type,
939 13116 : wi::shwi (mini, TYPE_PRECISION (type)),
940 6558 : wi::shwi (maxi, TYPE_PRECISION (type)));
941 6558 : return true;
942 6558 : }
943 : } op_cfn_ffs;
944 :
945 : // Implement range operator for CFN_BUILT_IN_POPCOUNT.
946 : class cfn_popcount : public cfn_ffs
947 : {
948 : public:
949 : using range_operator::fold_range;
950 4664 : virtual bool fold_range (irange &r, tree type, const irange &lh,
951 : const irange &rh, relation_trio rel) const
952 : {
953 4664 : if (lh.undefined_p ())
954 : return false;
955 4656 : unsigned prec = TYPE_PRECISION (type);
956 4656 : irange_bitmask bm = lh.get_bitmask ();
957 4656 : wide_int nz = bm.get_nonzero_bits ();
958 4656 : wide_int high = wi::shwi (wi::popcount (nz), prec);
959 : // Calculating the popcount of a singleton is trivial.
960 4656 : if (lh.singleton_p ())
961 : {
962 6 : r.set (type, high, high);
963 6 : return true;
964 : }
965 4650 : if (cfn_ffs::fold_range (r, type, lh, rh, rel))
966 : {
967 4650 : wide_int known_ones = ~bm.mask () & bm.value ();
968 4650 : wide_int low = wi::shwi (wi::popcount (known_ones), prec);
969 4650 : int_range<2> tmp (type, low, high);
970 4650 : r.intersect (tmp);
971 4650 : return true;
972 4650 : }
973 : return false;
974 4656 : }
975 : } op_cfn_popcount;
976 :
977 : // Implement range operator for CFN_BUILT_IN_CLZ
978 : class cfn_clz : public range_operator
979 : {
980 : public:
981 : cfn_clz (bool internal) { m_gimple_call_internal_p = internal; }
982 : using range_operator::fold_range;
983 : virtual bool fold_range (irange &r, tree type, const irange &lh,
984 : const irange &rh, relation_trio) const;
985 : private:
986 : bool m_gimple_call_internal_p;
987 : } op_cfn_clz (false), op_cfn_clz_internal (true);
988 :
989 : bool
990 129235 : cfn_clz::fold_range (irange &r, tree type, const irange &lh,
991 : const irange &rh, relation_trio) const
992 : {
993 : // __builtin_c[lt]z* return [0, prec-1], except when the
994 : // argument is 0, but that is undefined behavior.
995 : //
996 : // For __builtin_c[lt]z* consider argument of 0 always undefined
997 : // behavior, for internal fns likewise, unless it has 2 arguments,
998 : // then the second argument is the value at zero.
999 129235 : if (lh.undefined_p ())
1000 : return false;
1001 129150 : int prec = TYPE_PRECISION (lh.type ());
1002 129150 : int mini = 0;
1003 129150 : int maxi = prec - 1;
1004 129150 : if (m_gimple_call_internal_p)
1005 : {
1006 : // Handle only the two common values.
1007 124 : if (rh.lower_bound () == -1)
1008 : mini = -1;
1009 118 : else if (rh.lower_bound () == prec)
1010 118 : maxi = prec;
1011 : else
1012 : // Magic value to give up, unless we can prove arg is non-zero.
1013 : mini = -2;
1014 : }
1015 :
1016 : // From clz of minimum we can compute result maximum.
1017 129150 : if (wi::gt_p (lh.lower_bound (), 0, TYPE_SIGN (lh.type ())))
1018 : {
1019 111639 : maxi = prec - 1 - wi::floor_log2 (lh.lower_bound ());
1020 111639 : if (mini < 0)
1021 : mini = 0;
1022 : }
1023 17511 : else if (!range_includes_zero_p (lh))
1024 : {
1025 : mini = 0;
1026 : maxi = prec - 1;
1027 : }
1028 17510 : if (mini == -2)
1029 : return false;
1030 : // From clz of maximum we can compute result minimum.
1031 129150 : wide_int max = lh.upper_bound ();
1032 129150 : int newmini = prec - 1 - wi::floor_log2 (max);
1033 129150 : if (max == 0)
1034 : {
1035 : // If CLZ_DEFINED_VALUE_AT_ZERO is 2 with VALUE of prec,
1036 : // return [prec, prec] or [-1, -1], otherwise ignore the range.
1037 11 : if (maxi == prec)
1038 : mini = prec;
1039 11 : else if (mini == -1)
1040 : maxi = -1;
1041 : }
1042 129139 : else if (mini >= 0)
1043 129134 : mini = newmini;
1044 :
1045 129149 : if (mini == -2)
1046 : return false;
1047 129150 : r.set (type,
1048 258300 : wi::shwi (mini, TYPE_PRECISION (type)),
1049 129150 : wi::shwi (maxi, TYPE_PRECISION (type)));
1050 129150 : return true;
1051 129150 : }
1052 :
1053 : // Implement range operator for CFN_BUILT_IN_CTZ
1054 : class cfn_ctz : public range_operator
1055 : {
1056 : public:
1057 : cfn_ctz (bool internal) { m_gimple_call_internal_p = internal; }
1058 : using range_operator::fold_range;
1059 : virtual bool fold_range (irange &r, tree type, const irange &lh,
1060 : const irange &rh, relation_trio) const;
1061 : private:
1062 : bool m_gimple_call_internal_p;
1063 : } op_cfn_ctz (false), op_cfn_ctz_internal (true);
1064 :
1065 : bool
1066 16550 : cfn_ctz::fold_range (irange &r, tree type, const irange &lh,
1067 : const irange &rh, relation_trio) const
1068 : {
1069 16550 : if (lh.undefined_p ())
1070 : return false;
1071 16523 : int prec = TYPE_PRECISION (lh.type ());
1072 16523 : int mini = 0;
1073 16523 : int maxi = prec - 1;
1074 :
1075 16523 : if (m_gimple_call_internal_p)
1076 : {
1077 : // Handle only the two common values.
1078 97 : if (rh.lower_bound () == -1)
1079 : mini = -1;
1080 97 : else if (rh.lower_bound () == prec)
1081 97 : maxi = prec;
1082 : else
1083 : // Magic value to give up, unless we can prove arg is non-zero.
1084 : mini = -2;
1085 : }
1086 : // If arg is non-zero, then use [0, prec - 1].
1087 16523 : if (!range_includes_zero_p (lh))
1088 : {
1089 11822 : mini = 0;
1090 11822 : maxi = prec - 1;
1091 : }
1092 : // If some high bits are known to be zero, we can decrease
1093 : // the maximum.
1094 16523 : wide_int max = lh.upper_bound ();
1095 16523 : if (max == 0)
1096 : {
1097 : // Argument is [0, 0]. If CTZ_DEFINED_VALUE_AT_ZERO
1098 : // is 2 with value -1 or prec, return [-1, -1] or [prec, prec].
1099 : // Otherwise ignore the range.
1100 7 : if (mini == -1)
1101 : maxi = -1;
1102 7 : else if (maxi == prec)
1103 16523 : mini = prec;
1104 : }
1105 : // If value at zero is prec and 0 is in the range, we can't lower
1106 : // the upper bound. We could create two separate ranges though,
1107 : // [0,floor_log2(max)][prec,prec] though.
1108 16516 : else if (maxi != prec)
1109 16419 : maxi = wi::floor_log2 (max);
1110 :
1111 16523 : if (mini == -2)
1112 : return false;
1113 16523 : r.set (type,
1114 33046 : wi::shwi (mini, TYPE_PRECISION (type)),
1115 16523 : wi::shwi (maxi, TYPE_PRECISION (type)));
1116 16523 : return true;
1117 16523 : }
1118 :
1119 :
1120 : // Implement range operator for CFN_BUILT_IN_
1121 : class cfn_clrsb : public range_operator
1122 : {
1123 : public:
1124 : using range_operator::fold_range;
1125 804 : virtual bool fold_range (irange &r, tree type, const irange &lh,
1126 : const irange &, relation_trio) const
1127 : {
1128 804 : if (lh.undefined_p ())
1129 : return false;
1130 804 : int prec = TYPE_PRECISION (lh.type ());
1131 804 : r.set (type,
1132 1608 : wi::zero (TYPE_PRECISION (type)),
1133 804 : wi::shwi (prec - 1, TYPE_PRECISION (type)));
1134 804 : return true;
1135 : }
1136 : } op_cfn_clrsb;
1137 :
1138 :
1139 : // Implement range operator for CFN_BUILT_IN_
1140 : class cfn_ubsan : public range_operator
1141 : {
1142 : public:
1143 : cfn_ubsan (enum tree_code code) { m_code = code; }
1144 : using range_operator::fold_range;
1145 15454 : virtual bool fold_range (irange &r, tree type, const irange &lh,
1146 : const irange &rh, relation_trio rel) const
1147 : {
1148 15454 : bool saved_flag_wrapv = flag_wrapv;
1149 : // Pretend the arithmetic is wrapping. If there is any overflow,
1150 : // we'll complain, but will actually do wrapping operation.
1151 15454 : flag_wrapv = 1;
1152 15454 : bool result = range_op_handler (m_code).fold_range (r, type, lh, rh, rel);
1153 15454 : flag_wrapv = saved_flag_wrapv;
1154 :
1155 : // If for both arguments vrp_valueize returned non-NULL, this should
1156 : // have been already folded and if not, it wasn't folded because of
1157 : // overflow. Avoid removing the UBSAN_CHECK_* calls in that case.
1158 15454 : if (result && r.singleton_p ())
1159 480 : r.set_varying (type);
1160 15454 : return result;
1161 : }
1162 : private:
1163 : enum tree_code m_code;
1164 : };
1165 :
1166 : cfn_ubsan op_cfn_ubsan_add (PLUS_EXPR);
1167 : cfn_ubsan op_cfn_ubsan_sub (MINUS_EXPR);
1168 : cfn_ubsan op_cfn_ubsan_mul (MULT_EXPR);
1169 :
1170 :
1171 : // Implement range operator for CFN_BUILT_IN_STRLEN
1172 : class cfn_strlen : public range_operator
1173 : {
1174 : public:
1175 : using range_operator::fold_range;
1176 297774 : virtual bool fold_range (irange &r, tree type, const prange &,
1177 : const irange &, relation_trio) const
1178 : {
1179 297774 : wide_int max = irange_val_max (ptrdiff_type_node);
1180 : // To account for the terminating NULL, the maximum length
1181 : // is one less than the maximum array size, which in turn
1182 : // is one less than PTRDIFF_MAX (or SIZE_MAX where it's
1183 : // smaller than the former type).
1184 : // FIXME: Use max_object_size() - 1 here.
1185 297774 : r.set (type, wi::zero (TYPE_PRECISION (type)), max - 2);
1186 297774 : return true;
1187 297774 : }
1188 : } op_cfn_strlen;
1189 :
1190 :
1191 : // Implement range operator for CFN_BUILT_IN_GOACC_DIM
1192 : class cfn_goacc_dim : public range_operator
1193 : {
1194 : public:
1195 : cfn_goacc_dim (bool is_pos) { m_is_pos = is_pos; }
1196 : using range_operator::fold_range;
1197 12348 : virtual bool fold_range (irange &r, tree type, const irange &lh,
1198 : const irange &, relation_trio) const
1199 : {
1200 12348 : tree axis_tree;
1201 12348 : if (!lh.singleton_p (&axis_tree))
1202 : return false;
1203 12348 : HOST_WIDE_INT axis = TREE_INT_CST_LOW (axis_tree);
1204 12348 : int size = oacc_get_fn_dim_size (current_function_decl, axis);
1205 12348 : if (!size)
1206 : // If it's dynamic, the backend might know a hardware limitation.
1207 0 : size = targetm.goacc.dim_limit (axis);
1208 :
1209 12348 : r.set (type,
1210 31826 : wi::shwi (m_is_pos ? 0 : 1, TYPE_PRECISION (type)),
1211 : size
1212 12348 : ? wi::shwi (size - m_is_pos, TYPE_PRECISION (type))
1213 : : irange_val_max (type));
1214 12348 : return true;
1215 : }
1216 : private:
1217 : bool m_is_pos;
1218 : } op_cfn_goacc_dim_size (false), op_cfn_goacc_dim_pos (true);
1219 :
1220 : // Implement range operator for CFN_BUILT_IN_ISINF
1221 : class cfn_isinf : 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_isinf ())
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 : || (!real_isinf (&op1.lower_bound ())
1241 0 : && !real_isinf (&op1.upper_bound ())))
1242 : {
1243 0 : r.set_zero (type);
1244 0 : return true;
1245 : }
1246 :
1247 0 : r.set_varying (type);
1248 0 : return true;
1249 : }
1250 0 : virtual bool op1_range (frange &r, tree type, const irange &lhs,
1251 : const frange &, relation_trio) const override
1252 : {
1253 0 : if (lhs.undefined_p ())
1254 : return false;
1255 :
1256 0 : if (lhs.zero_p ())
1257 : {
1258 0 : nan_state nan (true);
1259 0 : r.set (type, real_min_representable (type),
1260 0 : real_max_representable (type), nan);
1261 0 : return true;
1262 : }
1263 :
1264 0 : if (!range_includes_zero_p (lhs))
1265 : {
1266 : // The range is [-INF,-INF][+INF,+INF], but it can't be represented.
1267 : // Set range to [-INF,+INF]
1268 0 : r.set_varying (type);
1269 0 : r.clear_nan ();
1270 0 : return true;
1271 : }
1272 :
1273 0 : r.set_varying (type);
1274 0 : return true;
1275 : }
1276 : } op_cfn_isinf;
1277 :
1278 : //Implement range operator for CFN_BUILT_IN_ISFINITE
1279 : class cfn_isfinite : public range_operator
1280 : {
1281 : public:
1282 : using range_operator::fold_range;
1283 : using range_operator::op1_range;
1284 0 : virtual bool fold_range (irange &r, tree type, const frange &op1,
1285 : const irange &, relation_trio) const override
1286 : {
1287 0 : if (op1.undefined_p ())
1288 : return false;
1289 :
1290 0 : if (op1.known_isfinite ())
1291 : {
1292 0 : wide_int one = wi::one (TYPE_PRECISION (type));
1293 0 : r.set (type, one, one);
1294 0 : return true;
1295 0 : }
1296 :
1297 0 : if (op1.known_isnan ()
1298 0 : || op1.known_isinf ())
1299 : {
1300 0 : r.set_zero (type);
1301 0 : return true;
1302 : }
1303 :
1304 0 : r.set_varying (type);
1305 0 : return true;
1306 : }
1307 0 : virtual bool op1_range (frange &r, tree type, const irange &lhs,
1308 : const frange &, relation_trio) const override
1309 : {
1310 0 : if (lhs.undefined_p ())
1311 : return false;
1312 :
1313 0 : if (lhs.zero_p ())
1314 : {
1315 : // The range is [-INF,-INF][+INF,+INF] NAN, but it can't be represented.
1316 : // Set range to varying
1317 0 : r.set_varying (type);
1318 0 : return true;
1319 : }
1320 :
1321 0 : if (!range_includes_zero_p (lhs))
1322 : {
1323 0 : nan_state nan (false);
1324 0 : r.set (type, real_min_representable (type),
1325 0 : real_max_representable (type), nan);
1326 0 : return true;
1327 : }
1328 :
1329 0 : r.set_varying (type);
1330 0 : return true;
1331 : }
1332 : } op_cfn_isfinite;
1333 :
1334 : //Implement range operator for CFN_BUILT_IN_ISNORMAL
1335 : class cfn_isnormal : public range_operator
1336 : {
1337 : public:
1338 : using range_operator::fold_range;
1339 : using range_operator::op1_range;
1340 0 : virtual bool fold_range (irange &r, tree type, const frange &op1,
1341 : const irange &, relation_trio) const override
1342 : {
1343 0 : if (op1.undefined_p ())
1344 : return false;
1345 :
1346 0 : if (op1.known_isnormal ())
1347 : {
1348 0 : wide_int one = wi::one (TYPE_PRECISION (type));
1349 0 : r.set (type, one, one);
1350 0 : return true;
1351 0 : }
1352 :
1353 0 : if (op1.known_isnan ()
1354 0 : || op1.known_isinf ()
1355 0 : || op1.known_isdenormal_or_zero ())
1356 : {
1357 0 : r.set_zero (type);
1358 0 : return true;
1359 : }
1360 :
1361 0 : r.set_varying (type);
1362 0 : return true;
1363 : }
1364 0 : virtual bool op1_range (frange &r, tree type, const irange &lhs,
1365 : const frange &, relation_trio) const override
1366 : {
1367 0 : if (lhs.undefined_p ())
1368 : return false;
1369 :
1370 0 : if (lhs.zero_p ())
1371 : {
1372 0 : r.set_varying (type);
1373 0 : return true;
1374 : }
1375 :
1376 0 : if (!range_includes_zero_p (lhs))
1377 : {
1378 0 : nan_state nan (false);
1379 0 : r.set (type, real_min_representable (type),
1380 0 : real_max_representable (type), nan);
1381 0 : return true;
1382 : }
1383 :
1384 0 : r.set_varying (type);
1385 0 : return true;
1386 : }
1387 : } op_cfn_isnormal;
1388 :
1389 : // Implement range operator for CFN_BUILT_IN_
1390 : class cfn_parity : public range_operator
1391 : {
1392 : public:
1393 : using range_operator::fold_range;
1394 1148 : virtual bool fold_range (irange &r, tree type, const irange &,
1395 : const irange &, relation_trio) const
1396 : {
1397 1148 : r = range_true_and_false (type);
1398 1148 : return true;
1399 : }
1400 : } op_cfn_parity;
1401 :
1402 : // Set up a gimple_range_op_handler for any nonstandard function which can be
1403 : // supported via range-ops.
1404 :
1405 : void
1406 715838973 : gimple_range_op_handler::maybe_non_standard ()
1407 : {
1408 715838973 : range_op_handler signed_op (OP_WIDEN_MULT_SIGNED);
1409 715838973 : gcc_checking_assert (signed_op);
1410 715838973 : range_op_handler unsigned_op (OP_WIDEN_MULT_UNSIGNED);
1411 715838973 : gcc_checking_assert (unsigned_op);
1412 715838973 : range_op_handler signed_unsigned_op (OP_WIDEN_MULT_SIGNED_UNSIGNED);
1413 715838973 : gcc_checking_assert (signed_unsigned_op);
1414 715838973 : bool signed1, signed2;
1415 :
1416 715838973 : if (gimple_code (m_stmt) == GIMPLE_ASSIGN)
1417 221818044 : switch (gimple_assign_rhs_code (m_stmt))
1418 : {
1419 22528 : case WIDEN_MULT_EXPR:
1420 22528 : m_op1 = gimple_assign_rhs1 (m_stmt);
1421 22528 : m_op2 = gimple_assign_rhs2 (m_stmt);
1422 22528 : signed1 = TYPE_SIGN (TREE_TYPE (m_op1)) == SIGNED;
1423 22528 : signed2 = TYPE_SIGN (TREE_TYPE (m_op2)) == SIGNED;
1424 :
1425 22528 : if (signed1 != signed2)
1426 : {
1427 0 : if (signed2 && !signed1)
1428 0 : std::swap (m_op1, m_op2);
1429 0 : m_operator = signed_unsigned_op.range_op ();
1430 : }
1431 22528 : else if (signed1)
1432 2062 : m_operator = signed_op.range_op ();
1433 : else
1434 20466 : m_operator = unsigned_op.range_op ();
1435 : break;
1436 :
1437 : default:
1438 : break;
1439 : }
1440 715838973 : }
1441 :
1442 : // Set up a gimple_range_op_handler for any built in function which can be
1443 : // supported via range-ops.
1444 :
1445 : void
1446 69063266 : gimple_range_op_handler::maybe_builtin_call ()
1447 : {
1448 69063266 : gcc_checking_assert (is_a <gcall *> (m_stmt));
1449 :
1450 69063266 : gcall *call = as_a <gcall *> (m_stmt);
1451 69063266 : combined_fn func = gimple_call_combined_fn (call);
1452 69063266 : if (func == CFN_LAST)
1453 : return;
1454 30562695 : tree type = gimple_range_type (call);
1455 30562695 : if (!type)
1456 : return;
1457 30562695 : if (!value_range::supports_type_p (type))
1458 : return;
1459 :
1460 30562695 : switch (func)
1461 : {
1462 773685 : case CFN_BUILT_IN_CONSTANT_P:
1463 773685 : if (gimple_call_num_args (call) != 1)
1464 : return;
1465 773657 : m_op1 = gimple_call_arg (call, 0);
1466 773657 : if (irange::supports_p (TREE_TYPE (m_op1)))
1467 639268 : m_operator = &op_cfn_constant_p;
1468 134389 : else if (frange::supports_p (TREE_TYPE (m_op1)))
1469 1081 : m_operator = &op_cfn_constant_float_p;
1470 : // builtin_constant_p should not be recomputed. See PR 123205.
1471 773657 : m_recomputable = false;
1472 773657 : break;
1473 :
1474 155907 : CASE_FLT_FN (CFN_BUILT_IN_SIGNBIT):
1475 155907 : if (gimple_call_num_args (call) != 1)
1476 : return;
1477 155907 : m_op1 = gimple_call_arg (call, 0);
1478 155907 : m_operator = &op_cfn_signbit;
1479 155907 : break;
1480 :
1481 0 : CASE_FLT_FN (CFN_BUILT_IN_ISINF):
1482 0 : if (gimple_call_num_args (call) != 1)
1483 : return;
1484 0 : m_op1 = gimple_call_arg (call, 0);
1485 0 : m_operator = &op_cfn_isinf;
1486 0 : break;
1487 :
1488 0 : case CFN_BUILT_IN_ISFINITE:
1489 0 : if (gimple_call_num_args (call) != 1)
1490 : return;
1491 0 : m_op1 = gimple_call_arg (call, 0);
1492 0 : m_operator = &op_cfn_isfinite;
1493 0 : break;
1494 :
1495 0 : case CFN_BUILT_IN_ISNORMAL:
1496 0 : if (gimple_call_num_args (call) != 1)
1497 : return;
1498 0 : m_op1 = gimple_call_arg (call, 0);
1499 0 : m_operator = &op_cfn_isnormal;
1500 0 : break;
1501 :
1502 1153057 : CASE_CFN_COPYSIGN_ALL:
1503 1153057 : m_op1 = gimple_call_arg (call, 0);
1504 1153057 : m_op2 = gimple_call_arg (call, 1);
1505 1153057 : m_operator = &op_cfn_copysign;
1506 1153057 : break;
1507 :
1508 165985 : CASE_CFN_SQRT:
1509 165985 : CASE_CFN_SQRT_FN:
1510 165985 : m_op1 = gimple_call_arg (call, 0);
1511 165985 : m_operator = &op_cfn_sqrt;
1512 165985 : break;
1513 :
1514 40883 : CASE_CFN_SIN:
1515 40883 : CASE_CFN_SIN_FN:
1516 40883 : m_op1 = gimple_call_arg (call, 0);
1517 40883 : m_operator = &op_cfn_sin;
1518 40883 : break;
1519 :
1520 22542 : CASE_CFN_COS:
1521 22542 : CASE_CFN_COS_FN:
1522 22542 : m_op1 = gimple_call_arg (call, 0);
1523 22542 : m_operator = &op_cfn_cos;
1524 22542 : break;
1525 :
1526 775 : case CFN_BUILT_IN_TOUPPER:
1527 775 : case CFN_BUILT_IN_TOLOWER:
1528 : // Only proceed If the argument is compatible with the LHS.
1529 775 : m_op1 = gimple_call_arg (call, 0);
1530 775 : if (range_compatible_p (type, TREE_TYPE (m_op1)))
1531 1267 : m_operator = (func == CFN_BUILT_IN_TOLOWER) ? &op_cfn_tolower
1532 : : &op_cfn_toupper;
1533 : break;
1534 :
1535 8903 : CASE_CFN_FFS:
1536 8903 : m_op1 = gimple_call_arg (call, 0);
1537 8903 : m_operator = &op_cfn_ffs;
1538 8903 : break;
1539 :
1540 22920 : CASE_CFN_POPCOUNT:
1541 22920 : m_op1 = gimple_call_arg (call, 0);
1542 22920 : m_operator = &op_cfn_popcount;
1543 22920 : break;
1544 :
1545 850660 : CASE_CFN_CLZ:
1546 850660 : m_op1 = gimple_call_arg (call, 0);
1547 850660 : if (gimple_call_internal_p (call)
1548 850660 : && gimple_call_num_args (call) == 2)
1549 : {
1550 515 : m_op2 = gimple_call_arg (call, 1);
1551 515 : m_operator = &op_cfn_clz_internal;
1552 : }
1553 : else
1554 850145 : m_operator = &op_cfn_clz;
1555 : break;
1556 :
1557 89179 : CASE_CFN_CTZ:
1558 89179 : m_op1 = gimple_call_arg (call, 0);
1559 89179 : if (gimple_call_internal_p (call)
1560 89179 : && gimple_call_num_args (call) == 2)
1561 : {
1562 479 : m_op2 = gimple_call_arg (call, 1);
1563 479 : m_operator = &op_cfn_ctz_internal;
1564 : }
1565 : else
1566 88700 : m_operator = &op_cfn_ctz;
1567 : break;
1568 :
1569 4883 : CASE_CFN_CLRSB:
1570 4883 : m_op1 = gimple_call_arg (call, 0);
1571 4883 : m_operator = &op_cfn_clrsb;
1572 4883 : break;
1573 :
1574 25751 : case CFN_UBSAN_CHECK_ADD:
1575 25751 : m_op1 = gimple_call_arg (call, 0);
1576 25751 : m_op2 = gimple_call_arg (call, 1);
1577 25751 : m_operator = &op_cfn_ubsan_add;
1578 25751 : break;
1579 :
1580 23251 : case CFN_UBSAN_CHECK_SUB:
1581 23251 : m_op1 = gimple_call_arg (call, 0);
1582 23251 : m_op2 = gimple_call_arg (call, 1);
1583 23251 : m_operator = &op_cfn_ubsan_sub;
1584 23251 : break;
1585 :
1586 20219 : case CFN_UBSAN_CHECK_MUL:
1587 20219 : m_op1 = gimple_call_arg (call, 0);
1588 20219 : m_op2 = gimple_call_arg (call, 1);
1589 20219 : m_operator = &op_cfn_ubsan_mul;
1590 20219 : break;
1591 :
1592 1403226 : case CFN_BUILT_IN_STRLEN:
1593 1403226 : {
1594 1403226 : tree lhs = gimple_call_lhs (call);
1595 1403226 : if (lhs && ptrdiff_type_node && (TYPE_PRECISION (ptrdiff_type_node)
1596 1403226 : == TYPE_PRECISION (TREE_TYPE (lhs))))
1597 : {
1598 1403226 : m_op1 = gimple_call_arg (call, 0);
1599 1403226 : m_operator = &op_cfn_strlen;
1600 : }
1601 : break;
1602 : }
1603 :
1604 : // Optimizing these two internal functions helps the loop
1605 : // optimizer eliminate outer comparisons. Size is [1,N]
1606 : // and pos is [0,N-1].
1607 29662 : case CFN_GOACC_DIM_SIZE:
1608 : // This call will ensure all the asserts are triggered.
1609 29662 : oacc_get_ifn_dim_arg (call);
1610 29662 : m_op1 = gimple_call_arg (call, 0);
1611 29662 : m_operator = &op_cfn_goacc_dim_size;
1612 29662 : break;
1613 :
1614 43718 : case CFN_GOACC_DIM_POS:
1615 : // This call will ensure all the asserts are triggered.
1616 43718 : oacc_get_ifn_dim_arg (call);
1617 43718 : m_op1 = gimple_call_arg (call, 0);
1618 43718 : m_operator = &op_cfn_goacc_dim_pos;
1619 43718 : break;
1620 :
1621 6122 : CASE_CFN_PARITY:
1622 6122 : m_operator = &op_cfn_parity;
1623 6122 : break;
1624 :
1625 125561 : CASE_CFN_ACOS:
1626 125561 : CASE_CFN_ACOS_FN:
1627 125561 : CASE_CFN_ACOSH:
1628 125561 : CASE_CFN_ACOSH_FN:
1629 125561 : CASE_CFN_ACOSPI:
1630 125561 : CASE_CFN_ACOSPI_FN:
1631 125561 : CASE_CFN_CABS:
1632 125561 : CASE_CFN_CABS_FN:
1633 125561 : CASE_CFN_COSH:
1634 125561 : CASE_CFN_COSH_FN:
1635 125561 : CASE_CFN_ERFC:
1636 125561 : CASE_CFN_ERFC_FN:
1637 125561 : CASE_CFN_EXP:
1638 125561 : CASE_CFN_EXP_FN:
1639 125561 : CASE_CFN_EXP10:
1640 125561 : CASE_CFN_EXP2:
1641 125561 : CASE_CFN_EXP2_FN:
1642 125561 : CASE_CFN_FABS:
1643 125561 : CASE_CFN_FABS_FN:
1644 125561 : CASE_CFN_FDIM:
1645 125561 : CASE_CFN_FDIM_FN:
1646 125561 : CASE_CFN_HYPOT:
1647 125561 : CASE_CFN_HYPOT_FN:
1648 125561 : CASE_CFN_POW10:
1649 125561 : m_operator = &op_cfn_fp_nonegative;
1650 125561 : break;
1651 :
1652 : // FIXME: some of these can do better than just nonnegative.
1653 87177 : CASE_CFN_ASINH:
1654 87177 : CASE_CFN_ASINH_FN:
1655 87177 : CASE_CFN_ASINPI:
1656 87177 : CASE_CFN_ASINPI_FN:
1657 87177 : CASE_CFN_ATAN:
1658 87177 : CASE_CFN_ATAN_FN:
1659 87177 : CASE_CFN_ATANH:
1660 87177 : CASE_CFN_ATANH_FN:
1661 87177 : CASE_CFN_ATANPI:
1662 87177 : CASE_CFN_ATANPI_FN:
1663 87177 : CASE_CFN_CBRT:
1664 87177 : CASE_CFN_CBRT_FN:
1665 87177 : CASE_CFN_ERF:
1666 87177 : CASE_CFN_ERF_FN:
1667 87177 : CASE_CFN_EXPM1:
1668 87177 : CASE_CFN_EXPM1_FN:
1669 87177 : CASE_CFN_FMOD:
1670 87177 : CASE_CFN_FMOD_FN:
1671 87177 : CASE_CFN_FREXP:
1672 87177 : CASE_CFN_FREXP_FN:
1673 87177 : CASE_CFN_MODF:
1674 87177 : CASE_CFN_MODF_FN:
1675 87177 : CASE_CFN_SCALB:
1676 87177 : CASE_CFN_SCALBLN:
1677 87177 : CASE_CFN_SCALBLN_FN:
1678 87177 : CASE_CFN_SCALBN:
1679 87177 : CASE_CFN_SCALBN_FN:
1680 87177 : CASE_CFN_SIGNIFICAND:
1681 87177 : CASE_CFN_SINH:
1682 87177 : CASE_CFN_SINH_FN:
1683 87177 : CASE_CFN_TANH:
1684 87177 : CASE_CFN_TANH_FN:
1685 87177 : CASE_CFN_LDEXP:
1686 87177 : m_operator = &op_cfn_fp_nonegative_arg0;
1687 87177 : m_op1 = gimple_call_arg (call, 0);
1688 87177 : break;
1689 :
1690 :
1691 : // FIXME: these can be improved for the rounding builtins.
1692 : // Currently just sets non-negative and update nan.
1693 101805 : CASE_CFN_FLOOR:
1694 101805 : CASE_CFN_FLOOR_FN:
1695 101805 : CASE_CFN_CEIL:
1696 101805 : CASE_CFN_CEIL_FN:
1697 101805 : CASE_CFN_NEARBYINT:
1698 101805 : CASE_CFN_NEARBYINT_FN:
1699 101805 : CASE_CFN_RINT:
1700 101805 : CASE_CFN_RINT_FN:
1701 101805 : CASE_CFN_ROUND:
1702 101805 : CASE_CFN_ROUND_FN:
1703 101805 : CASE_CFN_ROUNDEVEN:
1704 101805 : CASE_CFN_ROUNDEVEN_FN:
1705 101805 : CASE_CFN_TRUNC:
1706 101805 : CASE_CFN_TRUNC_FN:
1707 101805 : m_operator = &op_cfn_fp_nonegative_nan_arg0;
1708 101805 : m_op1 = gimple_call_arg (call, 0);
1709 101805 : break;
1710 :
1711 25406824 : default:
1712 25406824 : {
1713 25406824 : unsigned arg;
1714 25406824 : if (gimple_call_fnspec (call).returns_arg (&arg)
1715 1538738 : && arg == 0
1716 1538738 : && gimple_call_num_args (call) > 0)
1717 : {
1718 1538738 : m_op1 = gimple_call_arg (call, 0);
1719 1538738 : m_operator = &op_cfn_pass_through_arg1;
1720 : }
1721 : break;
1722 : }
1723 : }
1724 : }
|