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 327899289 : gimple_range_ssa_names (tree *vec, unsigned vec_size, gimple *stmt)
55 : {
56 327899289 : tree ssa;
57 327899289 : int count = 0;
58 :
59 327899289 : gimple_range_op_handler handler (stmt);
60 327899289 : if (handler)
61 : {
62 88385984 : gcc_checking_assert (vec_size >= 2);
63 88385984 : if ((ssa = gimple_range_ssa_p (handler.operand1 ())))
64 75264967 : vec[count++] = ssa;
65 88385984 : if ((ssa = gimple_range_ssa_p (handler.operand2 ())))
66 20784596 : vec[count++] = ssa;
67 : }
68 239513305 : else if (is_a<gassign *> (stmt)
69 239513305 : && gimple_assign_rhs_code (stmt) == COND_EXPR)
70 : {
71 104385 : gcc_checking_assert (vec_size >= 3);
72 104385 : gassign *st = as_a<gassign *> (stmt);
73 104385 : if ((ssa = gimple_range_ssa_p (gimple_assign_rhs1 (st))))
74 104385 : vec[count++] = ssa;
75 208770 : if ((ssa = gimple_range_ssa_p (gimple_assign_rhs2 (st))))
76 96024 : vec[count++] = ssa;
77 208770 : if ((ssa = gimple_range_ssa_p (gimple_assign_rhs3 (st))))
78 35462 : vec[count++] = ssa;
79 : }
80 327899289 : return count;
81 : }
82 :
83 : // Return the base of the RHS of an assignment.
84 :
85 : static tree
86 912160546 : gimple_range_base_of_assignment (const gimple *stmt)
87 : {
88 912160546 : gcc_checking_assert (gimple_code (stmt) == GIMPLE_ASSIGN);
89 912160546 : tree op1 = gimple_assign_rhs1 (stmt);
90 912160546 : if (gimple_assign_rhs_code (stmt) == ADDR_EXPR)
91 12891988 : 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 2315268286 : get_code (gimple *s)
99 : {
100 2315268286 : if (const gassign *ass = dyn_cast<const gassign *> (s))
101 1273003158 : return gimple_assign_rhs_code (ass);
102 1042265128 : if (const gcond *cond = dyn_cast<const gcond *> (s))
103 429502081 : 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 403138055 : gimple_range_op_handler::supported_p (gimple *s)
111 : {
112 403138055 : enum tree_code code = get_code (s);
113 403138055 : if (range_op_handler (code))
114 : return true;
115 103939567 : if (is_a <gcall *> (s) && gimple_range_op_handler (s))
116 680471 : return true;
117 : return false;
118 : }
119 :
120 : // Construct a handler object for statement S.
121 :
122 1912130231 : gimple_range_op_handler::gimple_range_op_handler (gimple *s)
123 : {
124 1912130231 : range_op_handler oper (get_code (s));
125 1912130231 : m_stmt = s;
126 1912130231 : m_op1 = NULL_TREE;
127 1912130231 : m_op2 = NULL_TREE;
128 : // Recomputation defaults to TRUE.
129 1912130231 : m_recomputable = true;
130 :
131 1912130231 : if (oper)
132 1127257097 : switch (gimple_code (m_stmt))
133 : {
134 215096551 : case GIMPLE_COND:
135 215096551 : m_op1 = gimple_cond_lhs (m_stmt);
136 215096551 : m_op2 = gimple_cond_rhs (m_stmt);
137 : // Check that operands are supported types. One check is enough.
138 215096551 : if (value_range::supports_type_p (TREE_TYPE (m_op1)))
139 215035646 : m_operator = oper.range_op ();
140 215096551 : gcc_checking_assert (m_operator);
141 1127257097 : return;
142 912160546 : case GIMPLE_ASSIGN:
143 912160546 : m_op1 = gimple_range_base_of_assignment (m_stmt);
144 912160546 : 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 12516682 : tree ssa = TREE_OPERAND (m_op1, 0);
152 12516682 : if (TREE_CODE (ssa) == SSA_NAME)
153 12516577 : m_op1 = ssa;
154 : }
155 : // VIEW_CONVERT_EXPR needs to descend one level deeper to pick
156 : // up the symbolic operand.
157 912160546 : if (TREE_CODE (m_op1) == VIEW_CONVERT_EXPR)
158 2543562 : m_op1 = TREE_OPERAND (m_op1, 0);
159 912160546 : if (gimple_num_ops (m_stmt) >= 3)
160 709846221 : m_op2 = gimple_assign_rhs2 (m_stmt);
161 : // Check that operands are supported types. One check is enough.
162 912160546 : if ((m_op1 && !value_range::supports_type_p (TREE_TYPE (m_op1))))
163 : return;
164 911628094 : m_operator = oper.range_op ();
165 911628094 : 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 784873134 : if (is_a <gcall *> (m_stmt))
174 68868263 : maybe_builtin_call ();
175 : else
176 716004871 : maybe_non_standard ();
177 784873134 : 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 22262 : gimple_range_op_handler::calc_op1 (vrange &r, const vrange &lhs_range)
186 : {
187 : // Give up on empty ranges.
188 22262 : 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 22262 : tree type = TREE_TYPE (operand1 ());
194 22262 : value_range type_range (type);
195 22262 : type_range.set_varying (type);
196 22262 : return op1_range (r, type, lhs_range, type_range);
197 22262 : }
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 95276460 : 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 95276460 : 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 95276460 : tree type = TREE_TYPE (operand1 ());
216 : // If op2 is undefined, solve as if it is varying.
217 95276460 : if (op2_range.undefined_p ())
218 : {
219 49509 : if (gimple_num_ops (m_stmt) < 3)
220 : return false;
221 12625 : tree op2_type;
222 : // This is sometimes invoked on single operand stmts.
223 12625 : if (operand2 ())
224 10714 : op2_type = TREE_TYPE (operand2 ());
225 : else
226 1911 : op2_type = TREE_TYPE (operand1 ());
227 12625 : value_range trange (op2_type);
228 12625 : trange.set_varying (op2_type);
229 12625 : return op1_range (r, type, lhs_range, trange, k);
230 12625 : }
231 95226951 : 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 26114523 : 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 26114523 : if (lhs_range.undefined_p ())
245 : return false;
246 :
247 26114523 : tree type = TREE_TYPE (operand2 ());
248 : // If op1 is undefined, solve as if it is varying.
249 26114523 : if (op1_range.undefined_p ())
250 : {
251 9213 : tree op1_type = TREE_TYPE (operand1 ());
252 9213 : value_range trange (op1_type);
253 9213 : trange.set_varying (op1_type);
254 9213 : return op2_range (r, type, lhs_range, trange, k);
255 9213 : }
256 26105310 : 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 161308 : virtual bool fold_range (irange &r, tree type, const irange &lh,
290 : const irange &, relation_trio) const
291 : {
292 161308 : 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 160382 : if (cfun->after_inlining)
299 : {
300 80650 : r.set_zero (type);
301 80650 : 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 218312 : virtual bool fold_range (irange &r, tree, const irange &lh,
315 : const irange &, relation_trio) const
316 : {
317 218312 : r = lh;
318 218312 : return true;
319 : }
320 81314 : virtual bool fold_range (prange &r, tree, const prange &lh,
321 : const prange &, relation_trio) const
322 : {
323 81314 : r = lh;
324 81314 : return true;
325 : }
326 296227 : virtual bool op1_range (irange &r, tree, const irange &lhs,
327 : const irange &, relation_trio) const
328 : {
329 296227 : r = lhs;
330 296227 : 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 54700 : virtual bool fold_range (irange &r, tree type, const frange &lh,
347 : const irange &, relation_trio) const override
348 : {
349 54700 : bool signbit;
350 54700 : 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 49276 : 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 49276 : if (ulps == ~0U || !real_isfinite (&arg))
421 : return false;
422 22832 : machine_mode mode = TYPE_MODE (type);
423 22832 : const real_format *format = REAL_MODE_FORMAT (mode);
424 22832 : auto_mpfr m (format->p);
425 22832 : mpfr_from_real (m, &arg, MPFR_RNDN);
426 22832 : mpfr_clear_flags ();
427 22832 : bool inexact = func (m, m, MPFR_RNDN);
428 22832 : if (!mpfr_number_p (m) || mpfr_overflow_p () || mpfr_underflow_p ())
429 : return false;
430 :
431 21338 : REAL_VALUE_TYPE value, result;
432 21338 : real_from_mpfr (&value, m, format, MPFR_RNDN);
433 21338 : if (!real_isfinite (&value))
434 : return false;
435 21338 : if ((value.cl == rvc_zero) != (mpfr_zero_p (m) != 0))
436 0 : inexact = true;
437 :
438 21338 : real_convert (&result, format, &value);
439 21338 : if (!real_isfinite (&result))
440 : return false;
441 21338 : bool round_low = false;
442 21338 : bool round_high = false;
443 21338 : if (!ulps && flag_rounding_math)
444 0 : ++ulps;
445 21338 : if (inexact || !real_identical (&result, &value))
446 : {
447 47866 : if (MODE_COMPOSITE_P (mode))
448 : round_low = round_high = true;
449 : else
450 : {
451 6838 : round_low = !real_less (&result, &value);
452 6838 : round_high = !real_less (&value, &result);
453 : }
454 : }
455 21338 : if (res_low)
456 : {
457 15023 : *res_low = result;
458 17427 : for (unsigned int i = 0; i < ulps + round_low; ++i)
459 2404 : frange_nextafter (mode, *res_low, dconstninf);
460 : }
461 21338 : if (res_high)
462 : {
463 7379 : *res_high = result;
464 14103 : for (unsigned int i = 0; i < ulps + round_high; ++i)
465 6724 : frange_nextafter (mode, *res_high, dconstinf);
466 : }
467 : return true;
468 22832 : }
469 :
470 : class cfn_sqrt : public range_operator
471 : {
472 : public:
473 : using range_operator::fold_range;
474 : using range_operator::op1_range;
475 32299 : virtual bool fold_range (frange &r, tree type,
476 : const frange &lh, const frange &,
477 : relation_trio) const final override
478 : {
479 32299 : if (lh.undefined_p ())
480 : return false;
481 32040 : if (lh.known_isnan () || real_less (&lh.upper_bound (), &dconstm0))
482 : {
483 7816 : r.set_nan (type);
484 7816 : return true;
485 : }
486 24224 : unsigned bulps
487 24224 : = targetm.libm_function_max_error (CFN_SQRT, TYPE_MODE (type), true);
488 24224 : if (bulps == ~0U)
489 0 : r.set_varying (type);
490 24224 : else if (bulps == 0)
491 24224 : 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 30631 : if (!lh.maybe_isnan () && !real_less (&lh.lower_bound (), &dconst0))
500 4640 : r.clear_nan ();
501 :
502 24224 : unsigned ulps
503 24224 : = targetm.libm_function_max_error (CFN_SQRT, TYPE_MODE (type), false);
504 24224 : if (ulps == ~0U)
505 : return true;
506 24106 : REAL_VALUE_TYPE lb = lh.lower_bound ();
507 24106 : REAL_VALUE_TYPE ub = lh.upper_bound ();
508 24106 : if (!frange_mpfr_arg1 (&lb, NULL, mpfr_sqrt, lb, type, ulps))
509 10147 : lb = dconstninf;
510 24106 : if (!frange_mpfr_arg1 (NULL, &ub, mpfr_sqrt, ub, type, ulps))
511 17791 : ub = dconstinf;
512 24106 : frange r2;
513 24106 : r2.set (type, lb, ub);
514 24106 : r2.flush_denormals_to_zero ();
515 24106 : r.intersect (r2);
516 24106 : return true;
517 24106 : }
518 784 : virtual bool op1_range (frange &r, tree type,
519 : const frange &lhs, const frange &,
520 : relation_trio) const final override
521 : {
522 784 : if (lhs.undefined_p ())
523 : return false;
524 :
525 : // A known NAN means the input is [-INF,-0.) U +-NAN.
526 784 : 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 784 : unsigned bulps
538 784 : = targetm.libm_function_max_error (CFN_SQRT, TYPE_MODE (type), true);
539 784 : if (bulps != ~0U)
540 : {
541 784 : const REAL_VALUE_TYPE &ub = lhs.upper_bound ();
542 784 : REAL_VALUE_TYPE m0 = dconstm0;
543 784 : while (bulps--)
544 0 : frange_nextafter (TYPE_MODE (type), m0, dconstninf);
545 784 : 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 1071 : 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 287 : r.set (type, dconstm0, dconstinf, nan_state (false, false));
561 : else
562 497 : r.set_varying (type);
563 :
564 784 : unsigned ulps
565 784 : = targetm.libm_function_max_error (CFN_SQRT, TYPE_MODE (type), false);
566 784 : if (ulps == ~0U)
567 : return true;
568 784 : REAL_VALUE_TYPE lb = lhs.lower_bound ();
569 784 : REAL_VALUE_TYPE ub = lhs.upper_bound ();
570 1071 : if (!lhs.maybe_isnan () && real_less (&dconst0, &lb))
571 : {
572 140 : for (unsigned i = 0; i < ulps; ++i)
573 0 : frange_nextafter (TYPE_MODE (type), lb, dconstninf);
574 140 : if (real_less (&dconst0, &lb))
575 : {
576 140 : frange wlhs (type, lb, dconstinf);
577 140 : wlhs.clear_nan ();
578 140 : wlhs.widen (type);
579 140 : REAL_VALUE_TYPE op = wlhs.lower_bound ();
580 140 : frange_arithmetic (MULT_EXPR, type, lb, op, op, dconstninf);
581 140 : }
582 : else
583 0 : lb = dconstninf;
584 : }
585 : else
586 644 : lb = dconstninf;
587 784 : if (real_isfinite (&ub) && real_less (&dconst0, &ub))
588 : {
589 267 : for (unsigned i = 0; i < ulps; ++i)
590 0 : frange_nextafter (TYPE_MODE (type), ub, dconstinf);
591 267 : if (real_isfinite (&ub))
592 : {
593 267 : frange wlhs (type, dconstninf, ub);
594 267 : wlhs.clear_nan ();
595 267 : wlhs.widen (type);
596 267 : REAL_VALUE_TYPE op = wlhs.upper_bound ();
597 267 : frange_arithmetic (MULT_EXPR, type, ub, op, op, dconstinf);
598 267 : }
599 : else
600 0 : ub = dconstinf;
601 : }
602 : else
603 517 : ub = dconstinf;
604 1568 : frange r2;
605 784 : r2.set (type, lb, ub);
606 784 : r.intersect (r2);
607 784 : 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 12921 : virtual bool fold_range (frange &r, tree type,
618 : const frange &lh, const frange &,
619 : relation_trio) const final override
620 : {
621 12921 : if (lh.undefined_p ())
622 : return false;
623 12905 : if (lh.known_isnan () || lh.known_isinf ())
624 : {
625 0 : r.set_nan (type);
626 0 : return true;
627 : }
628 12905 : unsigned bulps = targetm.libm_function_max_error (m_cfn, TYPE_MODE (type),
629 : true);
630 12905 : if (bulps == ~0U)
631 0 : r.set_varying (type);
632 12905 : else if (bulps == 0)
633 12853 : 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 16208 : if (!lh.maybe_isnan () && !lh.maybe_isinf ())
644 1185 : r.clear_nan ();
645 :
646 12905 : unsigned ulps
647 12905 : = targetm.libm_function_max_error (m_cfn, TYPE_MODE (type), false);
648 12905 : if (ulps == ~0U)
649 : return true;
650 12905 : REAL_VALUE_TYPE lb = lh.lower_bound ();
651 12905 : REAL_VALUE_TYPE ub = lh.upper_bound ();
652 12905 : REAL_VALUE_TYPE diff;
653 12905 : real_arithmetic (&diff, MINUS_EXPR, &ub, &lb);
654 12905 : if (!real_isfinite (&diff))
655 : return true;
656 1797 : REAL_VALUE_TYPE pi = dconst_pi ();
657 1797 : REAL_VALUE_TYPE pix2;
658 1797 : real_arithmetic (&pix2, PLUS_EXPR, &pi, &pi);
659 : // We can only try to narrow the range further if ub-lb < 2*pi.
660 1797 : if (!real_less (&diff, &pix2))
661 : return true;
662 266 : REAL_VALUE_TYPE lb_lo, lb_hi, ub_lo, ub_hi;
663 266 : REAL_VALUE_TYPE lb_deriv_lo, lb_deriv_hi, ub_deriv_lo, ub_deriv_hi;
664 266 : if (!frange_mpfr_arg1 (&lb_lo, &lb_hi,
665 266 : m_cfn == CFN_SIN ? mpfr_sin : mpfr_cos, lb,
666 : type, ulps)
667 266 : || !frange_mpfr_arg1 (&ub_lo, &ub_hi,
668 266 : m_cfn == CFN_SIN ? mpfr_sin : mpfr_cos, ub,
669 : type, ulps)
670 266 : || !frange_mpfr_arg1 (&lb_deriv_lo, &lb_deriv_hi,
671 266 : m_cfn == CFN_SIN ? mpfr_cos : mpfr_sin, lb,
672 : type, 0)
673 532 : || !frange_mpfr_arg1 (&ub_deriv_lo, &ub_deriv_hi,
674 266 : m_cfn == CFN_SIN ? mpfr_cos : mpfr_sin, ub,
675 : type, 0))
676 : return true;
677 266 : 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 266 : if (real_less (&lb_lo, &ub_lo))
687 127 : lb = lb_lo;
688 : else
689 139 : lb = ub_lo;
690 266 : if (real_less (&lb_hi, &ub_hi))
691 127 : ub = ub_hi;
692 : else
693 139 : 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 266 : 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 266 : 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 266 : if (real_isneg (&lb_deriv_lo) == real_isneg (&ub_deriv_lo))
721 : {
722 162 : 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 : // Implement range operator for CFN_BUILT_IN_TOUPPER and CFN_BUILT_IN_TOLOWER.
798 : class cfn_toupper_tolower : public range_operator
799 : {
800 : public:
801 : using range_operator::fold_range;
802 : cfn_toupper_tolower (bool toupper) { m_toupper = toupper; }
803 : virtual bool fold_range (irange &r, tree type, const irange &lh,
804 : const irange &, relation_trio) const;
805 : private:
806 : bool get_letter_range (tree type, irange &lowers, irange &uppers) const;
807 : bool m_toupper;
808 : } op_cfn_toupper (true), op_cfn_tolower (false);
809 :
810 : // Return TRUE if we recognize the target character set and return the
811 : // range for lower case and upper case letters.
812 :
813 : bool
814 203 : cfn_toupper_tolower::get_letter_range (tree type, irange &lowers,
815 : irange &uppers) const
816 : {
817 : // ASCII
818 203 : int a = lang_hooks.to_target_charset ('a');
819 203 : int z = lang_hooks.to_target_charset ('z');
820 203 : int A = lang_hooks.to_target_charset ('A');
821 203 : int Z = lang_hooks.to_target_charset ('Z');
822 :
823 203 : if ((z - a == 25) && (Z - A == 25))
824 : {
825 203 : lowers = int_range<2> (type,
826 406 : wi::shwi (a, TYPE_PRECISION (type)),
827 406 : wi::shwi (z, TYPE_PRECISION (type)));
828 203 : uppers = int_range<2> (type,
829 406 : wi::shwi (A, TYPE_PRECISION (type)),
830 406 : wi::shwi (Z, TYPE_PRECISION (type)));
831 203 : return true;
832 : }
833 : // Unknown character set.
834 : return false;
835 : }
836 :
837 : bool
838 203 : cfn_toupper_tolower::fold_range (irange &r, tree type, const irange &lh,
839 : const irange &, relation_trio) const
840 : {
841 203 : int_range<3> lowers;
842 203 : int_range<3> uppers;
843 203 : if (!get_letter_range (type, lowers, uppers))
844 : return false;
845 :
846 203 : r = lh;
847 203 : if (m_toupper)
848 : {
849 : // Return the range passed in without any lower case characters,
850 : // but including all the upper case ones.
851 103 : bool res = lowers.invert ();
852 103 : gcc_checking_assert (res);
853 103 : r.intersect (lowers);
854 103 : r.union_ (uppers);
855 : }
856 : else
857 : {
858 : // Return the range passed in without any lower case characters,
859 : // but including all the upper case ones.
860 100 : bool res = uppers.invert ();
861 100 : gcc_checking_assert (res);
862 100 : r.intersect (uppers);
863 100 : r.union_ (lowers);
864 : }
865 : return true;
866 203 : }
867 :
868 : // Implement range operator for CFN_BUILT_IN_FFS.
869 : class cfn_ffs : public range_operator
870 : {
871 : public:
872 : using range_operator::fold_range;
873 6539 : virtual bool fold_range (irange &r, tree type, const irange &lh,
874 : const irange &, relation_trio) const
875 : {
876 6539 : if (lh.undefined_p ())
877 : return false;
878 : // __builtin_ffs* and __builtin_popcount* return [0, prec].
879 6539 : int prec = TYPE_PRECISION (lh.type ());
880 : // If arg is non-zero, then ffs or popcount are non-zero.
881 6539 : int mini = range_includes_zero_p (lh) ? 0 : 1;
882 6539 : int maxi = prec;
883 :
884 : // If some high bits are known to be zero, decrease the maximum.
885 6539 : int_range_max tmp = lh;
886 6539 : if (TYPE_SIGN (tmp.type ()) == SIGNED)
887 1841 : range_cast (tmp, unsigned_type_for (tmp.type ()));
888 6539 : wide_int max = tmp.upper_bound ();
889 6539 : maxi = wi::floor_log2 (max) + 1;
890 6539 : r.set (type,
891 13078 : wi::shwi (mini, TYPE_PRECISION (type)),
892 6539 : wi::shwi (maxi, TYPE_PRECISION (type)));
893 6539 : return true;
894 6539 : }
895 : } op_cfn_ffs;
896 :
897 : // Implement range operator for CFN_BUILT_IN_POPCOUNT.
898 : class cfn_popcount : public cfn_ffs
899 : {
900 : public:
901 : using range_operator::fold_range;
902 4645 : virtual bool fold_range (irange &r, tree type, const irange &lh,
903 : const irange &rh, relation_trio rel) const
904 : {
905 4645 : if (lh.undefined_p ())
906 : return false;
907 4637 : unsigned prec = TYPE_PRECISION (type);
908 4637 : irange_bitmask bm = lh.get_bitmask ();
909 4637 : wide_int nz = bm.get_nonzero_bits ();
910 4637 : wide_int high = wi::shwi (wi::popcount (nz), prec);
911 : // Calculating the popcount of a singleton is trivial.
912 4637 : if (lh.singleton_p ())
913 : {
914 6 : r.set (type, high, high);
915 6 : return true;
916 : }
917 4631 : if (cfn_ffs::fold_range (r, type, lh, rh, rel))
918 : {
919 4631 : wide_int known_ones = ~bm.mask () & bm.value ();
920 4631 : wide_int low = wi::shwi (wi::popcount (known_ones), prec);
921 4631 : int_range<2> tmp (type, low, high);
922 4631 : r.intersect (tmp);
923 4631 : return true;
924 4631 : }
925 : return false;
926 4637 : }
927 : } op_cfn_popcount;
928 :
929 : // Implement range operator for CFN_BUILT_IN_CLZ
930 : class cfn_clz : public range_operator
931 : {
932 : public:
933 : cfn_clz (bool internal) { m_gimple_call_internal_p = internal; }
934 : using range_operator::fold_range;
935 : virtual bool fold_range (irange &r, tree type, const irange &lh,
936 : const irange &rh, relation_trio) const;
937 : private:
938 : bool m_gimple_call_internal_p;
939 : } op_cfn_clz (false), op_cfn_clz_internal (true);
940 :
941 : bool
942 129316 : cfn_clz::fold_range (irange &r, tree type, const irange &lh,
943 : const irange &rh, relation_trio) const
944 : {
945 : // __builtin_c[lt]z* return [0, prec-1], except when the
946 : // argument is 0, but that is undefined behavior.
947 : //
948 : // For __builtin_c[lt]z* consider argument of 0 always undefined
949 : // behavior, for internal fns likewise, unless it has 2 arguments,
950 : // then the second argument is the value at zero.
951 129316 : if (lh.undefined_p ())
952 : return false;
953 129231 : int prec = TYPE_PRECISION (lh.type ());
954 129231 : int mini = 0;
955 129231 : int maxi = prec - 1;
956 129231 : if (m_gimple_call_internal_p)
957 : {
958 : // Handle only the two common values.
959 124 : if (rh.lower_bound () == -1)
960 : mini = -1;
961 118 : else if (rh.lower_bound () == prec)
962 118 : maxi = prec;
963 : else
964 : // Magic value to give up, unless we can prove arg is non-zero.
965 : mini = -2;
966 : }
967 :
968 : // From clz of minimum we can compute result maximum.
969 129231 : if (wi::gt_p (lh.lower_bound (), 0, TYPE_SIGN (lh.type ())))
970 : {
971 111741 : maxi = prec - 1 - wi::floor_log2 (lh.lower_bound ());
972 111741 : if (mini < 0)
973 : mini = 0;
974 : }
975 17490 : else if (!range_includes_zero_p (lh))
976 : {
977 : mini = 0;
978 : maxi = prec - 1;
979 : }
980 17489 : if (mini == -2)
981 : return false;
982 : // From clz of maximum we can compute result minimum.
983 129231 : wide_int max = lh.upper_bound ();
984 129231 : int newmini = prec - 1 - wi::floor_log2 (max);
985 129231 : if (max == 0)
986 : {
987 : // If CLZ_DEFINED_VALUE_AT_ZERO is 2 with VALUE of prec,
988 : // return [prec, prec] or [-1, -1], otherwise ignore the range.
989 11 : if (maxi == prec)
990 : mini = prec;
991 11 : else if (mini == -1)
992 : maxi = -1;
993 : }
994 129220 : else if (mini >= 0)
995 129215 : mini = newmini;
996 :
997 129230 : if (mini == -2)
998 : return false;
999 129231 : r.set (type,
1000 258462 : wi::shwi (mini, TYPE_PRECISION (type)),
1001 129231 : wi::shwi (maxi, TYPE_PRECISION (type)));
1002 129231 : return true;
1003 129231 : }
1004 :
1005 : // Implement range operator for CFN_BUILT_IN_CTZ
1006 : class cfn_ctz : public range_operator
1007 : {
1008 : public:
1009 : cfn_ctz (bool internal) { m_gimple_call_internal_p = internal; }
1010 : using range_operator::fold_range;
1011 : virtual bool fold_range (irange &r, tree type, const irange &lh,
1012 : const irange &rh, relation_trio) const;
1013 : private:
1014 : bool m_gimple_call_internal_p;
1015 : } op_cfn_ctz (false), op_cfn_ctz_internal (true);
1016 :
1017 : bool
1018 16541 : cfn_ctz::fold_range (irange &r, tree type, const irange &lh,
1019 : const irange &rh, relation_trio) const
1020 : {
1021 16541 : if (lh.undefined_p ())
1022 : return false;
1023 16514 : int prec = TYPE_PRECISION (lh.type ());
1024 16514 : int mini = 0;
1025 16514 : int maxi = prec - 1;
1026 :
1027 16514 : if (m_gimple_call_internal_p)
1028 : {
1029 : // Handle only the two common values.
1030 97 : if (rh.lower_bound () == -1)
1031 : mini = -1;
1032 97 : else if (rh.lower_bound () == prec)
1033 97 : maxi = prec;
1034 : else
1035 : // Magic value to give up, unless we can prove arg is non-zero.
1036 : mini = -2;
1037 : }
1038 : // If arg is non-zero, then use [0, prec - 1].
1039 16514 : if (!range_includes_zero_p (lh))
1040 : {
1041 11776 : mini = 0;
1042 11776 : maxi = prec - 1;
1043 : }
1044 : // If some high bits are known to be zero, we can decrease
1045 : // the maximum.
1046 16514 : wide_int max = lh.upper_bound ();
1047 16514 : if (max == 0)
1048 : {
1049 : // Argument is [0, 0]. If CTZ_DEFINED_VALUE_AT_ZERO
1050 : // is 2 with value -1 or prec, return [-1, -1] or [prec, prec].
1051 : // Otherwise ignore the range.
1052 7 : if (mini == -1)
1053 : maxi = -1;
1054 7 : else if (maxi == prec)
1055 16514 : mini = prec;
1056 : }
1057 : // If value at zero is prec and 0 is in the range, we can't lower
1058 : // the upper bound. We could create two separate ranges though,
1059 : // [0,floor_log2(max)][prec,prec] though.
1060 16507 : else if (maxi != prec)
1061 16410 : maxi = wi::floor_log2 (max);
1062 :
1063 16514 : if (mini == -2)
1064 : return false;
1065 16514 : r.set (type,
1066 33028 : wi::shwi (mini, TYPE_PRECISION (type)),
1067 16514 : wi::shwi (maxi, TYPE_PRECISION (type)));
1068 16514 : return true;
1069 16514 : }
1070 :
1071 :
1072 : // Implement range operator for CFN_BUILT_IN_
1073 : class cfn_clrsb : public range_operator
1074 : {
1075 : public:
1076 : using range_operator::fold_range;
1077 804 : virtual bool fold_range (irange &r, tree type, const irange &lh,
1078 : const irange &, relation_trio) const
1079 : {
1080 804 : if (lh.undefined_p ())
1081 : return false;
1082 804 : int prec = TYPE_PRECISION (lh.type ());
1083 804 : r.set (type,
1084 1608 : wi::zero (TYPE_PRECISION (type)),
1085 804 : wi::shwi (prec - 1, TYPE_PRECISION (type)));
1086 804 : return true;
1087 : }
1088 : } op_cfn_clrsb;
1089 :
1090 :
1091 : // Implement range operator for CFN_BUILT_IN_
1092 : class cfn_ubsan : public range_operator
1093 : {
1094 : public:
1095 : cfn_ubsan (enum tree_code code) { m_code = code; }
1096 : using range_operator::fold_range;
1097 15448 : virtual bool fold_range (irange &r, tree type, const irange &lh,
1098 : const irange &rh, relation_trio rel) const
1099 : {
1100 15448 : bool saved_flag_wrapv = flag_wrapv;
1101 : // Pretend the arithmetic is wrapping. If there is any overflow,
1102 : // we'll complain, but will actually do wrapping operation.
1103 15448 : flag_wrapv = 1;
1104 15448 : bool result = range_op_handler (m_code).fold_range (r, type, lh, rh, rel);
1105 15448 : flag_wrapv = saved_flag_wrapv;
1106 :
1107 : // If for both arguments vrp_valueize returned non-NULL, this should
1108 : // have been already folded and if not, it wasn't folded because of
1109 : // overflow. Avoid removing the UBSAN_CHECK_* calls in that case.
1110 15448 : if (result && r.singleton_p ())
1111 480 : r.set_varying (type);
1112 15448 : return result;
1113 : }
1114 : private:
1115 : enum tree_code m_code;
1116 : };
1117 :
1118 : cfn_ubsan op_cfn_ubsan_add (PLUS_EXPR);
1119 : cfn_ubsan op_cfn_ubsan_sub (MINUS_EXPR);
1120 : cfn_ubsan op_cfn_ubsan_mul (MULT_EXPR);
1121 :
1122 :
1123 : // Implement range operator for CFN_BUILT_IN_STRLEN
1124 : class cfn_strlen : public range_operator
1125 : {
1126 : public:
1127 : using range_operator::fold_range;
1128 297504 : virtual bool fold_range (irange &r, tree type, const prange &,
1129 : const irange &, relation_trio) const
1130 : {
1131 297504 : wide_int max = irange_val_max (ptrdiff_type_node);
1132 : // To account for the terminating NULL, the maximum length
1133 : // is one less than the maximum array size, which in turn
1134 : // is one less than PTRDIFF_MAX (or SIZE_MAX where it's
1135 : // smaller than the former type).
1136 : // FIXME: Use max_object_size() - 1 here.
1137 297504 : r.set (type, wi::zero (TYPE_PRECISION (type)), max - 2);
1138 297504 : return true;
1139 297504 : }
1140 : } op_cfn_strlen;
1141 :
1142 :
1143 : // Implement range operator for CFN_BUILT_IN_GOACC_DIM
1144 : class cfn_goacc_dim : public range_operator
1145 : {
1146 : public:
1147 : cfn_goacc_dim (bool is_pos) { m_is_pos = is_pos; }
1148 : using range_operator::fold_range;
1149 12348 : virtual bool fold_range (irange &r, tree type, const irange &lh,
1150 : const irange &, relation_trio) const
1151 : {
1152 12348 : tree axis_tree;
1153 12348 : if (!lh.singleton_p (&axis_tree))
1154 : return false;
1155 12348 : HOST_WIDE_INT axis = TREE_INT_CST_LOW (axis_tree);
1156 12348 : int size = oacc_get_fn_dim_size (current_function_decl, axis);
1157 12348 : if (!size)
1158 : // If it's dynamic, the backend might know a hardware limitation.
1159 0 : size = targetm.goacc.dim_limit (axis);
1160 :
1161 12348 : r.set (type,
1162 31826 : wi::shwi (m_is_pos ? 0 : 1, TYPE_PRECISION (type)),
1163 : size
1164 12348 : ? wi::shwi (size - m_is_pos, TYPE_PRECISION (type))
1165 : : irange_val_max (type));
1166 12348 : return true;
1167 : }
1168 : private:
1169 : bool m_is_pos;
1170 : } op_cfn_goacc_dim_size (false), op_cfn_goacc_dim_pos (true);
1171 :
1172 : // Implement range operator for CFN_BUILT_IN_ISINF
1173 : class cfn_isinf : public range_operator
1174 : {
1175 : public:
1176 : using range_operator::fold_range;
1177 : using range_operator::op1_range;
1178 0 : virtual bool fold_range (irange &r, tree type, const frange &op1,
1179 : const irange &, relation_trio) const override
1180 : {
1181 0 : if (op1.undefined_p ())
1182 : return false;
1183 :
1184 0 : if (op1.known_isinf ())
1185 : {
1186 0 : wide_int one = wi::one (TYPE_PRECISION (type));
1187 0 : r.set (type, one, one);
1188 0 : return true;
1189 0 : }
1190 :
1191 0 : if (op1.known_isnan ()
1192 0 : || (!real_isinf (&op1.lower_bound ())
1193 0 : && !real_isinf (&op1.upper_bound ())))
1194 : {
1195 0 : r.set_zero (type);
1196 0 : return true;
1197 : }
1198 :
1199 0 : r.set_varying (type);
1200 0 : return true;
1201 : }
1202 0 : virtual bool op1_range (frange &r, tree type, const irange &lhs,
1203 : const frange &, relation_trio) const override
1204 : {
1205 0 : if (lhs.undefined_p ())
1206 : return false;
1207 :
1208 0 : if (lhs.zero_p ())
1209 : {
1210 0 : nan_state nan (true);
1211 0 : r.set (type, real_min_representable (type),
1212 0 : real_max_representable (type), nan);
1213 0 : return true;
1214 : }
1215 :
1216 0 : if (!range_includes_zero_p (lhs))
1217 : {
1218 : // The range is [-INF,-INF][+INF,+INF], but it can't be represented.
1219 : // Set range to [-INF,+INF]
1220 0 : r.set_varying (type);
1221 0 : r.clear_nan ();
1222 0 : return true;
1223 : }
1224 :
1225 0 : r.set_varying (type);
1226 0 : return true;
1227 : }
1228 : } op_cfn_isinf;
1229 :
1230 : //Implement range operator for CFN_BUILT_IN_ISFINITE
1231 : class cfn_isfinite : public range_operator
1232 : {
1233 : public:
1234 : using range_operator::fold_range;
1235 : using range_operator::op1_range;
1236 0 : virtual bool fold_range (irange &r, tree type, const frange &op1,
1237 : const irange &, relation_trio) const override
1238 : {
1239 0 : if (op1.undefined_p ())
1240 : return false;
1241 :
1242 0 : if (op1.known_isfinite ())
1243 : {
1244 0 : wide_int one = wi::one (TYPE_PRECISION (type));
1245 0 : r.set (type, one, one);
1246 0 : return true;
1247 0 : }
1248 :
1249 0 : if (op1.known_isnan ()
1250 0 : || op1.known_isinf ())
1251 : {
1252 0 : r.set_zero (type);
1253 0 : return true;
1254 : }
1255 :
1256 0 : r.set_varying (type);
1257 0 : return true;
1258 : }
1259 0 : virtual bool op1_range (frange &r, tree type, const irange &lhs,
1260 : const frange &, relation_trio) const override
1261 : {
1262 0 : if (lhs.undefined_p ())
1263 : return false;
1264 :
1265 0 : if (lhs.zero_p ())
1266 : {
1267 : // The range is [-INF,-INF][+INF,+INF] NAN, but it can't be represented.
1268 : // Set range to varying
1269 0 : r.set_varying (type);
1270 0 : return true;
1271 : }
1272 :
1273 0 : if (!range_includes_zero_p (lhs))
1274 : {
1275 0 : nan_state nan (false);
1276 0 : r.set (type, real_min_representable (type),
1277 0 : real_max_representable (type), nan);
1278 0 : return true;
1279 : }
1280 :
1281 0 : r.set_varying (type);
1282 0 : return true;
1283 : }
1284 : } op_cfn_isfinite;
1285 :
1286 : //Implement range operator for CFN_BUILT_IN_ISNORMAL
1287 : class cfn_isnormal : public range_operator
1288 : {
1289 : public:
1290 : using range_operator::fold_range;
1291 : using range_operator::op1_range;
1292 0 : virtual bool fold_range (irange &r, tree type, const frange &op1,
1293 : const irange &, relation_trio) const override
1294 : {
1295 0 : if (op1.undefined_p ())
1296 : return false;
1297 :
1298 0 : if (op1.known_isnormal ())
1299 : {
1300 0 : wide_int one = wi::one (TYPE_PRECISION (type));
1301 0 : r.set (type, one, one);
1302 0 : return true;
1303 0 : }
1304 :
1305 0 : if (op1.known_isnan ()
1306 0 : || op1.known_isinf ()
1307 0 : || op1.known_isdenormal_or_zero ())
1308 : {
1309 0 : r.set_zero (type);
1310 0 : return true;
1311 : }
1312 :
1313 0 : r.set_varying (type);
1314 0 : return true;
1315 : }
1316 0 : virtual bool op1_range (frange &r, tree type, const irange &lhs,
1317 : const frange &, relation_trio) const override
1318 : {
1319 0 : if (lhs.undefined_p ())
1320 : return false;
1321 :
1322 0 : if (lhs.zero_p ())
1323 : {
1324 0 : r.set_varying (type);
1325 0 : return true;
1326 : }
1327 :
1328 0 : if (!range_includes_zero_p (lhs))
1329 : {
1330 0 : nan_state nan (false);
1331 0 : r.set (type, real_min_representable (type),
1332 0 : real_max_representable (type), nan);
1333 0 : return true;
1334 : }
1335 :
1336 0 : r.set_varying (type);
1337 0 : return true;
1338 : }
1339 : } op_cfn_isnormal;
1340 :
1341 : // Implement range operator for CFN_BUILT_IN_
1342 : class cfn_parity : public range_operator
1343 : {
1344 : public:
1345 : using range_operator::fold_range;
1346 1148 : virtual bool fold_range (irange &r, tree type, const irange &,
1347 : const irange &, relation_trio) const
1348 : {
1349 1148 : r = range_true_and_false (type);
1350 1148 : return true;
1351 : }
1352 : } op_cfn_parity;
1353 :
1354 : // Set up a gimple_range_op_handler for any nonstandard function which can be
1355 : // supported via range-ops.
1356 :
1357 : void
1358 716004871 : gimple_range_op_handler::maybe_non_standard ()
1359 : {
1360 716004871 : range_op_handler signed_op (OP_WIDEN_MULT_SIGNED);
1361 716004871 : gcc_checking_assert (signed_op);
1362 716004871 : range_op_handler unsigned_op (OP_WIDEN_MULT_UNSIGNED);
1363 716004871 : gcc_checking_assert (unsigned_op);
1364 716004871 : range_op_handler signed_unsigned_op (OP_WIDEN_MULT_SIGNED_UNSIGNED);
1365 716004871 : gcc_checking_assert (signed_unsigned_op);
1366 716004871 : bool signed1, signed2;
1367 :
1368 716004871 : if (gimple_code (m_stmt) == GIMPLE_ASSIGN)
1369 221828958 : switch (gimple_assign_rhs_code (m_stmt))
1370 : {
1371 22213 : case WIDEN_MULT_EXPR:
1372 22213 : m_op1 = gimple_assign_rhs1 (m_stmt);
1373 22213 : m_op2 = gimple_assign_rhs2 (m_stmt);
1374 22213 : signed1 = TYPE_SIGN (TREE_TYPE (m_op1)) == SIGNED;
1375 22213 : signed2 = TYPE_SIGN (TREE_TYPE (m_op2)) == SIGNED;
1376 :
1377 22213 : if (signed1 != signed2)
1378 : {
1379 0 : if (signed2 && !signed1)
1380 0 : std::swap (m_op1, m_op2);
1381 0 : m_operator = signed_unsigned_op.range_op ();
1382 : }
1383 22213 : else if (signed1)
1384 1917 : m_operator = signed_op.range_op ();
1385 : else
1386 20296 : m_operator = unsigned_op.range_op ();
1387 : break;
1388 :
1389 : default:
1390 : break;
1391 : }
1392 716004871 : }
1393 :
1394 : // Set up a gimple_range_op_handler for any built in function which can be
1395 : // supported via range-ops.
1396 :
1397 : void
1398 68868263 : gimple_range_op_handler::maybe_builtin_call ()
1399 : {
1400 68868263 : gcc_checking_assert (is_a <gcall *> (m_stmt));
1401 :
1402 68868263 : gcall *call = as_a <gcall *> (m_stmt);
1403 68868263 : combined_fn func = gimple_call_combined_fn (call);
1404 68868263 : if (func == CFN_LAST)
1405 : return;
1406 30483010 : tree type = gimple_range_type (call);
1407 30483010 : if (!type)
1408 : return;
1409 30483010 : if (!value_range::supports_type_p (type))
1410 : return;
1411 :
1412 30483010 : switch (func)
1413 : {
1414 773583 : case CFN_BUILT_IN_CONSTANT_P:
1415 773583 : if (gimple_call_num_args (call) != 1)
1416 : return;
1417 773555 : m_op1 = gimple_call_arg (call, 0);
1418 773555 : if (irange::supports_p (TREE_TYPE (m_op1)))
1419 638918 : m_operator = &op_cfn_constant_p;
1420 134637 : else if (frange::supports_p (TREE_TYPE (m_op1)))
1421 1081 : m_operator = &op_cfn_constant_float_p;
1422 : // builtin_constant_p should not be recomputed. See PR 123205.
1423 773555 : m_recomputable = false;
1424 773555 : break;
1425 :
1426 155571 : CASE_FLT_FN (CFN_BUILT_IN_SIGNBIT):
1427 155571 : if (gimple_call_num_args (call) != 1)
1428 : return;
1429 155571 : m_op1 = gimple_call_arg (call, 0);
1430 155571 : m_operator = &op_cfn_signbit;
1431 155571 : break;
1432 :
1433 0 : CASE_FLT_FN (CFN_BUILT_IN_ISINF):
1434 0 : if (gimple_call_num_args (call) != 1)
1435 : return;
1436 0 : m_op1 = gimple_call_arg (call, 0);
1437 0 : m_operator = &op_cfn_isinf;
1438 0 : break;
1439 :
1440 0 : case CFN_BUILT_IN_ISFINITE:
1441 0 : if (gimple_call_num_args (call) != 1)
1442 : return;
1443 0 : m_op1 = gimple_call_arg (call, 0);
1444 0 : m_operator = &op_cfn_isfinite;
1445 0 : break;
1446 :
1447 0 : case CFN_BUILT_IN_ISNORMAL:
1448 0 : if (gimple_call_num_args (call) != 1)
1449 : return;
1450 0 : m_op1 = gimple_call_arg (call, 0);
1451 0 : m_operator = &op_cfn_isnormal;
1452 0 : break;
1453 :
1454 1153057 : CASE_CFN_COPYSIGN_ALL:
1455 1153057 : m_op1 = gimple_call_arg (call, 0);
1456 1153057 : m_op2 = gimple_call_arg (call, 1);
1457 1153057 : m_operator = &op_cfn_copysign;
1458 1153057 : break;
1459 :
1460 164094 : CASE_CFN_SQRT:
1461 164094 : CASE_CFN_SQRT_FN:
1462 164094 : m_op1 = gimple_call_arg (call, 0);
1463 164094 : m_operator = &op_cfn_sqrt;
1464 164094 : break;
1465 :
1466 40896 : CASE_CFN_SIN:
1467 40896 : CASE_CFN_SIN_FN:
1468 40896 : m_op1 = gimple_call_arg (call, 0);
1469 40896 : m_operator = &op_cfn_sin;
1470 40896 : break;
1471 :
1472 22553 : CASE_CFN_COS:
1473 22553 : CASE_CFN_COS_FN:
1474 22553 : m_op1 = gimple_call_arg (call, 0);
1475 22553 : m_operator = &op_cfn_cos;
1476 22553 : break;
1477 :
1478 701 : case CFN_BUILT_IN_TOUPPER:
1479 701 : case CFN_BUILT_IN_TOLOWER:
1480 : // Only proceed If the argument is compatible with the LHS.
1481 701 : m_op1 = gimple_call_arg (call, 0);
1482 701 : if (range_compatible_p (type, TREE_TYPE (m_op1)))
1483 1119 : m_operator = (func == CFN_BUILT_IN_TOLOWER) ? &op_cfn_tolower
1484 : : &op_cfn_toupper;
1485 : break;
1486 :
1487 8903 : CASE_CFN_FFS:
1488 8903 : m_op1 = gimple_call_arg (call, 0);
1489 8903 : m_operator = &op_cfn_ffs;
1490 8903 : break;
1491 :
1492 22726 : CASE_CFN_POPCOUNT:
1493 22726 : m_op1 = gimple_call_arg (call, 0);
1494 22726 : m_operator = &op_cfn_popcount;
1495 22726 : break;
1496 :
1497 853651 : CASE_CFN_CLZ:
1498 853651 : m_op1 = gimple_call_arg (call, 0);
1499 853651 : if (gimple_call_internal_p (call)
1500 853651 : && gimple_call_num_args (call) == 2)
1501 : {
1502 515 : m_op2 = gimple_call_arg (call, 1);
1503 515 : m_operator = &op_cfn_clz_internal;
1504 : }
1505 : else
1506 853136 : m_operator = &op_cfn_clz;
1507 : break;
1508 :
1509 88905 : CASE_CFN_CTZ:
1510 88905 : m_op1 = gimple_call_arg (call, 0);
1511 88905 : if (gimple_call_internal_p (call)
1512 88905 : && gimple_call_num_args (call) == 2)
1513 : {
1514 479 : m_op2 = gimple_call_arg (call, 1);
1515 479 : m_operator = &op_cfn_ctz_internal;
1516 : }
1517 : else
1518 88426 : m_operator = &op_cfn_ctz;
1519 : break;
1520 :
1521 4883 : CASE_CFN_CLRSB:
1522 4883 : m_op1 = gimple_call_arg (call, 0);
1523 4883 : m_operator = &op_cfn_clrsb;
1524 4883 : break;
1525 :
1526 25751 : case CFN_UBSAN_CHECK_ADD:
1527 25751 : m_op1 = gimple_call_arg (call, 0);
1528 25751 : m_op2 = gimple_call_arg (call, 1);
1529 25751 : m_operator = &op_cfn_ubsan_add;
1530 25751 : break;
1531 :
1532 23203 : case CFN_UBSAN_CHECK_SUB:
1533 23203 : m_op1 = gimple_call_arg (call, 0);
1534 23203 : m_op2 = gimple_call_arg (call, 1);
1535 23203 : m_operator = &op_cfn_ubsan_sub;
1536 23203 : break;
1537 :
1538 20219 : case CFN_UBSAN_CHECK_MUL:
1539 20219 : m_op1 = gimple_call_arg (call, 0);
1540 20219 : m_op2 = gimple_call_arg (call, 1);
1541 20219 : m_operator = &op_cfn_ubsan_mul;
1542 20219 : break;
1543 :
1544 1408415 : case CFN_BUILT_IN_STRLEN:
1545 1408415 : {
1546 1408415 : tree lhs = gimple_call_lhs (call);
1547 1408415 : if (lhs && ptrdiff_type_node && (TYPE_PRECISION (ptrdiff_type_node)
1548 1408415 : == TYPE_PRECISION (TREE_TYPE (lhs))))
1549 : {
1550 1408415 : m_op1 = gimple_call_arg (call, 0);
1551 1408415 : m_operator = &op_cfn_strlen;
1552 : }
1553 : break;
1554 : }
1555 :
1556 : // Optimizing these two internal functions helps the loop
1557 : // optimizer eliminate outer comparisons. Size is [1,N]
1558 : // and pos is [0,N-1].
1559 29662 : case CFN_GOACC_DIM_SIZE:
1560 : // This call will ensure all the asserts are triggered.
1561 29662 : oacc_get_ifn_dim_arg (call);
1562 29662 : m_op1 = gimple_call_arg (call, 0);
1563 29662 : m_operator = &op_cfn_goacc_dim_size;
1564 29662 : break;
1565 :
1566 43718 : case CFN_GOACC_DIM_POS:
1567 : // This call will ensure all the asserts are triggered.
1568 43718 : oacc_get_ifn_dim_arg (call);
1569 43718 : m_op1 = gimple_call_arg (call, 0);
1570 43718 : m_operator = &op_cfn_goacc_dim_pos;
1571 43718 : break;
1572 :
1573 6122 : CASE_CFN_PARITY:
1574 6122 : m_operator = &op_cfn_parity;
1575 6122 : break;
1576 :
1577 25636397 : default:
1578 25636397 : {
1579 25636397 : unsigned arg;
1580 25636397 : if (gimple_call_fnspec (call).returns_arg (&arg)
1581 1537689 : && arg == 0
1582 1537689 : && gimple_call_num_args (call) > 0)
1583 : {
1584 1537689 : m_op1 = gimple_call_arg (call, 0);
1585 1537689 : m_operator = &op_cfn_pass_through_arg1;
1586 : }
1587 : break;
1588 : }
1589 : }
1590 : }
|