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