libcpp, c, middle-end: Optimize initializers using #embed in C
[official-gcc.git] / gcc / gimple-range-op.cc
blob68a7df8d01bca9c5fce25ec4c5d56c24af002bba
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>.
6 This file is part of GCC.
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.
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.
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/>. */
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"
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.
53 unsigned
54 gimple_range_ssa_names (tree *vec, unsigned vec_size, gimple *stmt)
56 tree ssa;
57 int count = 0;
59 gimple_range_op_handler handler (stmt);
60 if (handler)
62 gcc_checking_assert (vec_size >= 2);
63 if ((ssa = gimple_range_ssa_p (handler.operand1 ())))
64 vec[count++] = ssa;
65 if ((ssa = gimple_range_ssa_p (handler.operand2 ())))
66 vec[count++] = ssa;
68 else if (is_a<gassign *> (stmt)
69 && gimple_assign_rhs_code (stmt) == COND_EXPR)
71 gcc_checking_assert (vec_size >= 3);
72 gassign *st = as_a<gassign *> (stmt);
73 if ((ssa = gimple_range_ssa_p (gimple_assign_rhs1 (st))))
74 vec[count++] = ssa;
75 if ((ssa = gimple_range_ssa_p (gimple_assign_rhs2 (st))))
76 vec[count++] = ssa;
77 if ((ssa = gimple_range_ssa_p (gimple_assign_rhs3 (st))))
78 vec[count++] = ssa;
80 return count;
83 // Return the base of the RHS of an assignment.
85 static tree
86 gimple_range_base_of_assignment (const gimple *stmt)
88 gcc_checking_assert (gimple_code (stmt) == GIMPLE_ASSIGN);
89 tree op1 = gimple_assign_rhs1 (stmt);
90 if (gimple_assign_rhs_code (stmt) == ADDR_EXPR)
91 return get_base_address (TREE_OPERAND (op1, 0));
92 return op1;
95 // If statement is supported by range-ops, set the CODE and return the TYPE.
97 static inline enum tree_code
98 get_code (gimple *s)
100 if (const gassign *ass = dyn_cast<const gassign *> (s))
101 return gimple_assign_rhs_code (ass);
102 if (const gcond *cond = dyn_cast<const gcond *> (s))
103 return gimple_cond_code (cond);
104 return ERROR_MARK;
107 // If statement S has a supported range_op handler return TRUE.
109 bool
110 gimple_range_op_handler::supported_p (gimple *s)
112 enum tree_code code = get_code (s);
113 if (range_op_handler (code))
114 return true;
115 if (is_a <gcall *> (s) && gimple_range_op_handler (s))
116 return true;
117 return false;
120 // Construct a handler object for statement S.
122 gimple_range_op_handler::gimple_range_op_handler (gimple *s)
124 range_op_handler oper (get_code (s));
125 m_stmt = s;
126 m_op1 = NULL_TREE;
127 m_op2 = NULL_TREE;
129 if (oper)
130 switch (gimple_code (m_stmt))
132 case GIMPLE_COND:
133 m_op1 = gimple_cond_lhs (m_stmt);
134 m_op2 = gimple_cond_rhs (m_stmt);
135 // Check that operands are supported types. One check is enough.
136 if (value_range::supports_type_p (TREE_TYPE (m_op1)))
137 m_operator = oper.range_op ();
138 gcc_checking_assert (m_operator);
139 return;
140 case GIMPLE_ASSIGN:
141 m_op1 = gimple_range_base_of_assignment (m_stmt);
142 if (m_op1 && TREE_CODE (m_op1) == MEM_REF)
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 tree ssa = TREE_OPERAND (m_op1, 0);
150 if (TREE_CODE (ssa) == SSA_NAME)
151 m_op1 = ssa;
153 if (gimple_num_ops (m_stmt) >= 3)
154 m_op2 = gimple_assign_rhs2 (m_stmt);
155 // Check that operands are supported types. One check is enough.
156 if ((m_op1 && !value_range::supports_type_p (TREE_TYPE (m_op1))))
157 return;
158 m_operator = oper.range_op ();
159 gcc_checking_assert (m_operator);
160 return;
161 default:
162 gcc_unreachable ();
163 return;
165 // If no range-op table entry handled this stmt, check for other supported
166 // statements.
167 if (is_a <gcall *> (m_stmt))
168 maybe_builtin_call ();
169 else
170 maybe_non_standard ();
171 gcc_checking_assert (m_operator);
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.
178 bool
179 gimple_range_op_handler::calc_op1 (vrange &r, const vrange &lhs_range)
181 // Give up on empty ranges.
182 if (lhs_range.undefined_p ())
183 return false;
185 // Unary operations require the type of the first operand in the
186 // second range position.
187 tree type = TREE_TYPE (operand1 ());
188 value_range type_range (type);
189 type_range.set_varying (type);
190 return op1_range (r, type, lhs_range, type_range);
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.
198 bool
199 gimple_range_op_handler::calc_op1 (vrange &r, const vrange &lhs_range,
200 const vrange &op2_range, relation_trio k)
202 // Give up on empty ranges.
203 if (lhs_range.undefined_p ())
204 return false;
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 tree type = TREE_TYPE (operand1 ());
210 // If op2 is undefined, solve as if it is varying.
211 if (op2_range.undefined_p ())
213 if (gimple_num_ops (m_stmt) < 3)
214 return false;
215 tree op2_type;
216 // This is sometimes invoked on single operand stmts.
217 if (operand2 ())
218 op2_type = TREE_TYPE (operand2 ());
219 else
220 op2_type = TREE_TYPE (operand1 ());
221 value_range trange (op2_type);
222 trange.set_varying (op2_type);
223 return op1_range (r, type, lhs_range, trange, k);
225 return op1_range (r, type, lhs_range, op2_range, k);
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.
233 bool
234 gimple_range_op_handler::calc_op2 (vrange &r, const vrange &lhs_range,
235 const vrange &op1_range, relation_trio k)
237 // Give up on empty ranges.
238 if (lhs_range.undefined_p ())
239 return false;
241 tree type = TREE_TYPE (operand2 ());
242 // If op1 is undefined, solve as if it is varying.
243 if (op1_range.undefined_p ())
245 tree op1_type = TREE_TYPE (operand1 ());
246 value_range trange (op1_type);
247 trange.set_varying (op1_type);
248 return op2_range (r, type, lhs_range, trange, k);
250 return op2_range (r, type, lhs_range, op1_range, k);
253 // --------------------------------------------------------------------
255 // Implement range operator for float CFN_BUILT_IN_CONSTANT_P.
256 class cfn_constant_float_p : public range_operator
258 public:
259 using range_operator::fold_range;
260 virtual bool fold_range (irange &r, tree type, const frange &lh,
261 const irange &, relation_trio) const
263 if (lh.singleton_p ())
265 wide_int one = wi::one (TYPE_PRECISION (type));
266 r.set (type, one, one);
267 return true;
269 if (cfun->after_inlining)
271 r.set_zero (type);
272 return true;
274 return false;
276 } op_cfn_constant_float_p;
278 // Implement range operator for integral CFN_BUILT_IN_CONSTANT_P.
279 class cfn_constant_p : public range_operator
281 public:
282 using range_operator::fold_range;
283 virtual bool fold_range (irange &r, tree type, const irange &lh,
284 const irange &, relation_trio) const
286 if (lh.singleton_p ())
288 wide_int one = wi::one (TYPE_PRECISION (type));
289 r.set (type, one, one);
290 return true;
292 if (cfun->after_inlining)
294 r.set_zero (type);
295 return true;
297 return false;
299 } op_cfn_constant_p;
301 // Implement range operator for integral/pointer functions returning
302 // the first argument.
303 class cfn_pass_through_arg1 : public range_operator
305 public:
306 using range_operator::fold_range;
307 using range_operator::op1_range;
308 virtual bool fold_range (irange &r, tree, const irange &lh,
309 const irange &, relation_trio) const
311 r = lh;
312 return true;
314 virtual bool fold_range (prange &r, tree, const prange &lh,
315 const prange &, relation_trio) const
317 r = lh;
318 return true;
320 virtual bool op1_range (irange &r, tree, const irange &lhs,
321 const irange &, relation_trio) const
323 r = lhs;
324 return true;
326 virtual bool op1_range (prange &r, tree, const prange &lhs,
327 const prange &, relation_trio) const
329 r = lhs;
330 return true;
332 } op_cfn_pass_through_arg1;
334 // Implement range operator for CFN_BUILT_IN_SIGNBIT.
335 class cfn_signbit : public range_operator
337 public:
338 using range_operator::fold_range;
339 using range_operator::op1_range;
340 virtual bool fold_range (irange &r, tree type, const frange &lh,
341 const irange &, relation_trio) const override
343 bool signbit;
344 if (lh.signbit_p (signbit))
346 if (signbit)
347 r.set_nonzero (type);
348 else
349 r.set_zero (type);
350 return true;
352 return false;
354 virtual bool op1_range (frange &r, tree type, const irange &lhs,
355 const frange &, relation_trio) const override
357 if (lhs.zero_p ())
359 r.set (type, dconst0, frange_val_max (type));
360 r.update_nan (false);
361 return true;
363 if (!lhs.contains_p (wi::zero (TYPE_PRECISION (lhs.type ()))))
365 r.set (type, frange_val_min (type), dconstm0);
366 r.update_nan (true);
367 return true;
369 return false;
371 } op_cfn_signbit;
373 // Implement range operator for CFN_BUILT_IN_COPYSIGN
374 class cfn_copysign : public range_operator
376 public:
377 using range_operator::fold_range;
378 virtual bool fold_range (frange &r, tree type, const frange &lh,
379 const frange &rh, relation_trio) const override
381 frange neg;
382 if (!range_op_handler (ABS_EXPR).fold_range (r, type, lh, frange (type)))
383 return false;
384 if (!range_op_handler (NEGATE_EXPR).fold_range (neg, type, r,
385 frange (type)))
386 return false;
388 bool signbit;
389 if (rh.signbit_p (signbit))
391 // If the sign is negative, flip the result from ABS,
392 // otherwise leave things positive.
393 if (signbit)
394 r = neg;
396 else
397 // If the sign is unknown, keep the positive and negative
398 // alternatives.
399 r.union_ (neg);
400 return true;
402 } op_cfn_copysign;
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. */
409 static bool
410 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)
414 if (ulps == ~0U || !real_isfinite (&arg))
415 return false;
416 machine_mode mode = TYPE_MODE (type);
417 const real_format *format = REAL_MODE_FORMAT (mode);
418 auto_mpfr m (format->p);
419 mpfr_from_real (m, &arg, MPFR_RNDN);
420 mpfr_clear_flags ();
421 bool inexact = func (m, m, MPFR_RNDN);
422 if (!mpfr_number_p (m) || mpfr_overflow_p () || mpfr_underflow_p ())
423 return false;
425 REAL_VALUE_TYPE value, result;
426 real_from_mpfr (&value, m, format, MPFR_RNDN);
427 if (!real_isfinite (&value))
428 return false;
429 if ((value.cl == rvc_zero) != (mpfr_zero_p (m) != 0))
430 inexact = true;
432 real_convert (&result, format, &value);
433 if (!real_isfinite (&result))
434 return false;
435 bool round_low = false;
436 bool round_high = false;
437 if (!ulps && flag_rounding_math)
438 ++ulps;
439 if (inexact || !real_identical (&result, &value))
441 if (MODE_COMPOSITE_P (mode))
442 round_low = round_high = true;
443 else
445 round_low = !real_less (&result, &value);
446 round_high = !real_less (&value, &result);
449 if (res_low)
451 *res_low = result;
452 for (unsigned int i = 0; i < ulps + round_low; ++i)
453 frange_nextafter (mode, *res_low, dconstninf);
455 if (res_high)
457 *res_high = result;
458 for (unsigned int i = 0; i < ulps + round_high; ++i)
459 frange_nextafter (mode, *res_high, dconstinf);
461 return true;
464 class cfn_sqrt : public range_operator
466 public:
467 using range_operator::fold_range;
468 using range_operator::op1_range;
469 virtual bool fold_range (frange &r, tree type,
470 const frange &lh, const frange &,
471 relation_trio) const final override
473 if (lh.undefined_p ())
474 return false;
475 if (lh.known_isnan () || real_less (&lh.upper_bound (), &dconstm0))
477 r.set_nan (type);
478 return true;
480 unsigned bulps
481 = targetm.libm_function_max_error (CFN_SQRT, TYPE_MODE (type), true);
482 if (bulps == ~0U)
483 r.set_varying (type);
484 else if (bulps == 0)
485 r.set (type, dconstm0, dconstinf);
486 else
488 REAL_VALUE_TYPE boundmin = dconstm0;
489 while (bulps--)
490 frange_nextafter (TYPE_MODE (type), boundmin, dconstninf);
491 r.set (type, boundmin, dconstinf);
493 if (!lh.maybe_isnan () && !real_less (&lh.lower_bound (), &dconst0))
494 r.clear_nan ();
496 unsigned ulps
497 = targetm.libm_function_max_error (CFN_SQRT, TYPE_MODE (type), false);
498 if (ulps == ~0U)
499 return true;
500 REAL_VALUE_TYPE lb = lh.lower_bound ();
501 REAL_VALUE_TYPE ub = lh.upper_bound ();
502 if (!frange_mpfr_arg1 (&lb, NULL, mpfr_sqrt, lb, type, ulps))
503 lb = dconstninf;
504 if (!frange_mpfr_arg1 (NULL, &ub, mpfr_sqrt, ub, type, ulps))
505 ub = dconstinf;
506 frange r2;
507 r2.set (type, lb, ub);
508 r2.flush_denormals_to_zero ();
509 r.intersect (r2);
510 return true;
512 virtual bool op1_range (frange &r, tree type,
513 const frange &lhs, const frange &,
514 relation_trio) const final override
516 if (lhs.undefined_p ())
517 return false;
519 // A known NAN means the input is [-INF,-0.) U +-NAN.
520 if (lhs.known_isnan ())
522 known_nan:
523 REAL_VALUE_TYPE ub = dconstm0;
524 frange_nextafter (TYPE_MODE (type), ub, dconstninf);
525 r.set (type, dconstninf, ub);
526 // No r.flush_denormals_to_zero (); here - it is a reverse op.
527 return true;
530 // Results outside of [-0.0, +Inf] are impossible.
531 unsigned bulps
532 = targetm.libm_function_max_error (CFN_SQRT, TYPE_MODE (type), true);
533 if (bulps != ~0U)
535 const REAL_VALUE_TYPE &ub = lhs.upper_bound ();
536 REAL_VALUE_TYPE m0 = dconstm0;
537 while (bulps--)
538 frange_nextafter (TYPE_MODE (type), m0, dconstninf);
539 if (real_less (&ub, &m0))
541 if (!lhs.maybe_isnan ())
542 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 goto known_nan;
547 return true;
551 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 r.set (type, dconstm0, dconstinf, nan_state (false, false));
555 else
556 r.set_varying (type);
558 unsigned ulps
559 = targetm.libm_function_max_error (CFN_SQRT, TYPE_MODE (type), false);
560 if (ulps == ~0U)
561 return true;
562 REAL_VALUE_TYPE lb = lhs.lower_bound ();
563 REAL_VALUE_TYPE ub = lhs.upper_bound ();
564 if (!lhs.maybe_isnan () && real_less (&dconst0, &lb))
566 for (unsigned i = 0; i < ulps; ++i)
567 frange_nextafter (TYPE_MODE (type), lb, dconstninf);
568 if (real_less (&dconst0, &lb))
570 REAL_VALUE_TYPE op = lb;
571 frange_arithmetic (MULT_EXPR, type, lb, op, op, dconstninf);
573 else
574 lb = dconstninf;
576 else
577 lb = dconstninf;
578 if (real_isfinite (&ub) && real_less (&dconst0, &ub))
580 for (unsigned i = 0; i < ulps; ++i)
581 frange_nextafter (TYPE_MODE (type), ub, dconstinf);
582 if (real_isfinite (&ub))
584 REAL_VALUE_TYPE op = ub;
585 frange_arithmetic (MULT_EXPR, type, ub, op, op, dconstinf);
587 else
588 ub = dconstinf;
590 else
591 ub = dconstinf;
592 frange r2;
593 r2.set (type, lb, ub);
594 r.intersect (r2);
595 return true;
597 } op_cfn_sqrt;
599 class cfn_sincos : public range_operator
601 public:
602 using range_operator::fold_range;
603 using range_operator::op1_range;
604 cfn_sincos (combined_fn cfn) { m_cfn = cfn; }
605 virtual bool fold_range (frange &r, tree type,
606 const frange &lh, const frange &,
607 relation_trio) const final override
609 if (lh.undefined_p ())
610 return false;
611 if (lh.known_isnan () || lh.known_isinf ())
613 r.set_nan (type);
614 return true;
616 unsigned bulps = targetm.libm_function_max_error (m_cfn, TYPE_MODE (type),
617 true);
618 if (bulps == ~0U)
619 r.set_varying (type);
620 else if (bulps == 0)
621 r.set (type, dconstm1, dconst1);
622 else
624 REAL_VALUE_TYPE boundmin, boundmax;
625 boundmax = dconst1;
626 while (bulps--)
627 frange_nextafter (TYPE_MODE (type), boundmax, dconstinf);
628 real_arithmetic (&boundmin, NEGATE_EXPR, &boundmax, NULL);
629 r.set (type, boundmin, boundmax);
631 if (!lh.maybe_isnan () && !lh.maybe_isinf ())
632 r.clear_nan ();
634 unsigned ulps
635 = targetm.libm_function_max_error (m_cfn, TYPE_MODE (type), false);
636 if (ulps == ~0U)
637 return true;
638 REAL_VALUE_TYPE lb = lh.lower_bound ();
639 REAL_VALUE_TYPE ub = lh.upper_bound ();
640 REAL_VALUE_TYPE diff;
641 real_arithmetic (&diff, MINUS_EXPR, &ub, &lb);
642 if (!real_isfinite (&diff))
643 return true;
644 REAL_VALUE_TYPE pi = dconst_pi ();
645 REAL_VALUE_TYPE pix2;
646 real_arithmetic (&pix2, PLUS_EXPR, &pi, &pi);
647 // We can only try to narrow the range further if ub-lb < 2*pi.
648 if (!real_less (&diff, &pix2))
649 return true;
650 REAL_VALUE_TYPE lb_lo, lb_hi, ub_lo, ub_hi;
651 REAL_VALUE_TYPE lb_deriv_lo, lb_deriv_hi, ub_deriv_lo, ub_deriv_hi;
652 if (!frange_mpfr_arg1 (&lb_lo, &lb_hi,
653 m_cfn == CFN_SIN ? mpfr_sin : mpfr_cos, lb,
654 type, ulps)
655 || !frange_mpfr_arg1 (&ub_lo, &ub_hi,
656 m_cfn == CFN_SIN ? mpfr_sin : mpfr_cos, ub,
657 type, ulps)
658 || !frange_mpfr_arg1 (&lb_deriv_lo, &lb_deriv_hi,
659 m_cfn == CFN_SIN ? mpfr_cos : mpfr_sin, lb,
660 type, 0)
661 || !frange_mpfr_arg1 (&ub_deriv_lo, &ub_deriv_hi,
662 m_cfn == CFN_SIN ? mpfr_cos : mpfr_sin, ub,
663 type, 0))
664 return true;
665 if (m_cfn == CFN_COS)
667 // Derivative of cos is -sin, so negate.
668 lb_deriv_lo.sign ^= 1;
669 lb_deriv_hi.sign ^= 1;
670 ub_deriv_lo.sign ^= 1;
671 ub_deriv_hi.sign ^= 1;
674 if (real_less (&lb_lo, &ub_lo))
675 lb = lb_lo;
676 else
677 lb = ub_lo;
678 if (real_less (&lb_hi, &ub_hi))
679 ub = ub_hi;
680 else
681 ub = lb_hi;
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).
687 // First handle special case, where the derivative has different signs,
688 // so the bound must be roughly -1 or +1.
689 if (real_isneg (&lb_deriv_lo) != real_isneg (&lb_deriv_hi))
691 if (real_isneg (&lb_lo))
692 lb = dconstninf;
693 else
694 ub = dconstinf;
696 if (real_isneg (&ub_deriv_lo) != real_isneg (&ub_deriv_hi))
698 if (real_isneg (&ub_lo))
699 lb = dconstninf;
700 else
701 ub = dconstinf;
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 if (real_isneg (&lb_deriv_lo) == real_isneg (&ub_deriv_lo))
710 if (!real_less (&diff, &pi))
711 return true;
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 else if (real_isneg (&lb_deriv_lo))
716 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 ub = dconstinf;
721 frange r2;
722 r2.set (type, lb, ub);
723 r2.flush_denormals_to_zero ();
724 r.intersect (r2);
725 return true;
727 virtual bool op1_range (frange &r, tree type,
728 const frange &lhs, const frange &,
729 relation_trio) const final override
731 if (lhs.undefined_p ())
732 return false;
734 // A known NAN means the input is [-INF,-INF][+INF,+INF] U +-NAN,
735 // which we can't currently represent.
736 if (lhs.known_isnan ())
738 r.set_varying (type);
739 return true;
742 // Results outside of [-1.0, +1.0] are impossible.
743 unsigned bulps
744 = targetm.libm_function_max_error (m_cfn, TYPE_MODE (type), true);
745 if (bulps != ~0U)
747 const REAL_VALUE_TYPE &lb = lhs.lower_bound ();
748 const REAL_VALUE_TYPE &ub = lhs.upper_bound ();
749 REAL_VALUE_TYPE m1 = dconstm1;
750 REAL_VALUE_TYPE p1 = dconst1;
751 while (bulps--)
753 frange_nextafter (TYPE_MODE (type), m1, dconstninf);
754 frange_nextafter (TYPE_MODE (type), p1, dconstinf);
756 if (real_less (&ub, &m1) || real_less (&p1, &lb))
758 if (!lhs.maybe_isnan ())
759 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 r.set_varying (type);
765 return true;
769 if (!lhs.maybe_isnan ())
771 // If NAN is not valid result, the input cannot include either
772 // a NAN nor a +-INF.
773 REAL_VALUE_TYPE lb = real_min_representable (type);
774 REAL_VALUE_TYPE ub = real_max_representable (type);
775 r.set (type, lb, ub, nan_state (false, false));
777 else
778 r.set_varying (type);
779 return true;
781 private:
782 combined_fn m_cfn;
783 } op_cfn_sin (CFN_SIN), op_cfn_cos (CFN_COS);
785 // Implement range operator for CFN_BUILT_IN_TOUPPER and CFN_BUILT_IN_TOLOWER.
786 class cfn_toupper_tolower : public range_operator
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);
798 // Return TRUE if we recognize the target character set and return the
799 // range for lower case and upper case letters.
801 bool
802 cfn_toupper_tolower::get_letter_range (tree type, irange &lowers,
803 irange &uppers) const
805 // ASCII
806 int a = lang_hooks.to_target_charset ('a');
807 int z = lang_hooks.to_target_charset ('z');
808 int A = lang_hooks.to_target_charset ('A');
809 int Z = lang_hooks.to_target_charset ('Z');
811 if ((z - a == 25) && (Z - A == 25))
813 lowers = int_range<2> (type,
814 wi::shwi (a, TYPE_PRECISION (type)),
815 wi::shwi (z, TYPE_PRECISION (type)));
816 uppers = int_range<2> (type,
817 wi::shwi (A, TYPE_PRECISION (type)),
818 wi::shwi (Z, TYPE_PRECISION (type)));
819 return true;
821 // Unknown character set.
822 return false;
825 bool
826 cfn_toupper_tolower::fold_range (irange &r, tree type, const irange &lh,
827 const irange &, relation_trio) const
829 int_range<3> lowers;
830 int_range<3> uppers;
831 if (!get_letter_range (type, lowers, uppers))
832 return false;
834 r = lh;
835 if (m_toupper)
837 // Return the range passed in without any lower case characters,
838 // but including all the upper case ones.
839 lowers.invert ();
840 r.intersect (lowers);
841 r.union_ (uppers);
843 else
845 // Return the range passed in without any lower case characters,
846 // but including all the upper case ones.
847 uppers.invert ();
848 r.intersect (uppers);
849 r.union_ (lowers);
851 return true;
854 // Implement range operator for CFN_BUILT_IN_FFS.
855 class cfn_ffs : public range_operator
857 public:
858 using range_operator::fold_range;
859 virtual bool fold_range (irange &r, tree type, const irange &lh,
860 const irange &, relation_trio) const
862 if (lh.undefined_p ())
863 return false;
864 // __builtin_ffs* and __builtin_popcount* return [0, prec].
865 int prec = TYPE_PRECISION (lh.type ());
866 // If arg is non-zero, then ffs or popcount are non-zero.
867 int mini = range_includes_zero_p (lh) ? 0 : 1;
868 int maxi = prec;
870 // If some high bits are known to be zero, decrease the maximum.
871 int_range_max tmp = lh;
872 if (TYPE_SIGN (tmp.type ()) == SIGNED)
873 range_cast (tmp, unsigned_type_for (tmp.type ()));
874 wide_int max = tmp.upper_bound ();
875 maxi = wi::floor_log2 (max) + 1;
876 r.set (type,
877 wi::shwi (mini, TYPE_PRECISION (type)),
878 wi::shwi (maxi, TYPE_PRECISION (type)));
879 return true;
881 } op_cfn_ffs;
883 // Implement range operator for CFN_BUILT_IN_POPCOUNT.
884 class cfn_popcount : public cfn_ffs
886 public:
887 using range_operator::fold_range;
888 virtual bool fold_range (irange &r, tree type, const irange &lh,
889 const irange &rh, relation_trio rel) const
891 if (lh.undefined_p ())
892 return false;
893 unsigned prec = TYPE_PRECISION (type);
894 irange_bitmask bm = lh.get_bitmask ();
895 wide_int nz = bm.get_nonzero_bits ();
896 wide_int high = wi::shwi (wi::popcount (nz), prec);
897 // Calculating the popcount of a singleton is trivial.
898 if (lh.singleton_p ())
900 r.set (type, high, high);
901 return true;
903 if (cfn_ffs::fold_range (r, type, lh, rh, rel))
905 wide_int known_ones = ~bm.mask () & bm.value ();
906 wide_int low = wi::shwi (wi::popcount (known_ones), prec);
907 int_range<2> tmp (type, low, high);
908 r.intersect (tmp);
909 return true;
911 return false;
913 } op_cfn_popcount;
915 // Implement range operator for CFN_BUILT_IN_CLZ
916 class cfn_clz : public range_operator
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);
927 bool
928 cfn_clz::fold_range (irange &r, tree type, const irange &lh,
929 const irange &rh, relation_trio) const
931 // __builtin_c[lt]z* return [0, prec-1], except when the
932 // argument is 0, but that is undefined behavior.
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 if (lh.undefined_p ())
938 return false;
939 int prec = TYPE_PRECISION (lh.type ());
940 int mini = 0;
941 int maxi = prec - 1;
942 if (m_gimple_call_internal_p)
944 // Handle only the two common values.
945 if (rh.lower_bound () == -1)
946 mini = -1;
947 else if (rh.lower_bound () == prec)
948 maxi = prec;
949 else
950 // Magic value to give up, unless we can prove arg is non-zero.
951 mini = -2;
954 // From clz of minimum we can compute result maximum.
955 if (wi::gt_p (lh.lower_bound (), 0, TYPE_SIGN (lh.type ())))
957 maxi = prec - 1 - wi::floor_log2 (lh.lower_bound ());
958 if (mini < 0)
959 mini = 0;
961 else if (!range_includes_zero_p (lh))
963 mini = 0;
964 maxi = prec - 1;
966 if (mini == -2)
967 return false;
968 // From clz of maximum we can compute result minimum.
969 wide_int max = lh.upper_bound ();
970 int newmini = prec - 1 - wi::floor_log2 (max);
971 if (max == 0)
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 if (maxi == prec)
976 mini = prec;
977 else if (mini == -1)
978 maxi = -1;
980 else if (mini >= 0)
981 mini = newmini;
983 if (mini == -2)
984 return false;
985 r.set (type,
986 wi::shwi (mini, TYPE_PRECISION (type)),
987 wi::shwi (maxi, TYPE_PRECISION (type)));
988 return true;
991 // Implement range operator for CFN_BUILT_IN_CTZ
992 class cfn_ctz : public range_operator
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);
1003 bool
1004 cfn_ctz::fold_range (irange &r, tree type, const irange &lh,
1005 const irange &rh, relation_trio) const
1007 if (lh.undefined_p ())
1008 return false;
1009 int prec = TYPE_PRECISION (lh.type ());
1010 int mini = 0;
1011 int maxi = prec - 1;
1013 if (m_gimple_call_internal_p)
1015 // Handle only the two common values.
1016 if (rh.lower_bound () == -1)
1017 mini = -1;
1018 else if (rh.lower_bound () == prec)
1019 maxi = prec;
1020 else
1021 // Magic value to give up, unless we can prove arg is non-zero.
1022 mini = -2;
1024 // If arg is non-zero, then use [0, prec - 1].
1025 if (!range_includes_zero_p (lh))
1027 mini = 0;
1028 maxi = prec - 1;
1030 // If some high bits are known to be zero, we can decrease
1031 // the maximum.
1032 wide_int max = lh.upper_bound ();
1033 if (max == 0)
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 if (mini == -1)
1039 maxi = -1;
1040 else if (maxi == prec)
1041 mini = prec;
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 else if (maxi != prec)
1047 maxi = wi::floor_log2 (max);
1049 if (mini == -2)
1050 return false;
1051 r.set (type,
1052 wi::shwi (mini, TYPE_PRECISION (type)),
1053 wi::shwi (maxi, TYPE_PRECISION (type)));
1054 return true;
1058 // Implement range operator for CFN_BUILT_IN_
1059 class cfn_clrsb : public range_operator
1061 public:
1062 using range_operator::fold_range;
1063 virtual bool fold_range (irange &r, tree type, const irange &lh,
1064 const irange &, relation_trio) const
1066 if (lh.undefined_p ())
1067 return false;
1068 int prec = TYPE_PRECISION (lh.type ());
1069 r.set (type,
1070 wi::zero (TYPE_PRECISION (type)),
1071 wi::shwi (prec - 1, TYPE_PRECISION (type)));
1072 return true;
1074 } op_cfn_clrsb;
1077 // Implement range operator for CFN_BUILT_IN_
1078 class cfn_ubsan : public range_operator
1080 public:
1081 cfn_ubsan (enum tree_code code) { m_code = code; }
1082 using range_operator::fold_range;
1083 virtual bool fold_range (irange &r, tree type, const irange &lh,
1084 const irange &rh, relation_trio rel) const
1086 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 flag_wrapv = 1;
1090 bool result = range_op_handler (m_code).fold_range (r, type, lh, rh, rel);
1091 flag_wrapv = saved_flag_wrapv;
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 if (result && r.singleton_p ())
1097 r.set_varying (type);
1098 return result;
1100 private:
1101 enum tree_code m_code;
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);
1109 // Implement range operator for CFN_BUILT_IN_STRLEN
1110 class cfn_strlen : public range_operator
1112 public:
1113 using range_operator::fold_range;
1114 virtual bool fold_range (irange &r, tree type, const prange &,
1115 const irange &, relation_trio) const
1117 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 r.set (type, wi::zero (TYPE_PRECISION (type)), max - 2);
1124 return true;
1126 } op_cfn_strlen;
1129 // Implement range operator for CFN_BUILT_IN_GOACC_DIM
1130 class cfn_goacc_dim : public range_operator
1132 public:
1133 cfn_goacc_dim (bool is_pos) { m_is_pos = is_pos; }
1134 using range_operator::fold_range;
1135 virtual bool fold_range (irange &r, tree type, const irange &lh,
1136 const irange &, relation_trio) const
1138 tree axis_tree;
1139 if (!lh.singleton_p (&axis_tree))
1140 return false;
1141 HOST_WIDE_INT axis = TREE_INT_CST_LOW (axis_tree);
1142 int size = oacc_get_fn_dim_size (current_function_decl, axis);
1143 if (!size)
1144 // If it's dynamic, the backend might know a hardware limitation.
1145 size = targetm.goacc.dim_limit (axis);
1147 r.set (type,
1148 wi::shwi (m_is_pos ? 0 : 1, TYPE_PRECISION (type)),
1149 size
1150 ? wi::shwi (size - m_is_pos, TYPE_PRECISION (type))
1151 : irange_val_max (type));
1152 return true;
1154 private:
1155 bool m_is_pos;
1156 } op_cfn_goacc_dim_size (false), op_cfn_goacc_dim_pos (true);
1158 // Implement range operator for CFN_BUILT_IN_ISINF
1159 class cfn_isinf : public range_operator
1161 public:
1162 using range_operator::fold_range;
1163 using range_operator::op1_range;
1164 virtual bool fold_range (irange &r, tree type, const frange &op1,
1165 const irange &, relation_trio) const override
1167 if (op1.undefined_p ())
1168 return false;
1170 if (op1.known_isinf ())
1172 wide_int one = wi::one (TYPE_PRECISION (type));
1173 r.set (type, one, one);
1174 return true;
1177 if (op1.known_isnan ()
1178 || (!real_isinf (&op1.lower_bound ())
1179 && !real_isinf (&op1.upper_bound ())))
1181 r.set_zero (type);
1182 return true;
1185 r.set_varying (type);
1186 return true;
1188 virtual bool op1_range (frange &r, tree type, const irange &lhs,
1189 const frange &, relation_trio) const override
1191 if (lhs.undefined_p ())
1192 return false;
1194 if (lhs.zero_p ())
1196 nan_state nan (true);
1197 r.set (type, real_min_representable (type),
1198 real_max_representable (type), nan);
1199 return true;
1202 if (!range_includes_zero_p (lhs))
1204 // The range is [-INF,-INF][+INF,+INF], but it can't be represented.
1205 // Set range to [-INF,+INF]
1206 r.set_varying (type);
1207 r.clear_nan ();
1208 return true;
1211 r.set_varying (type);
1212 return true;
1214 } op_cfn_isinf;
1216 //Implement range operator for CFN_BUILT_IN_ISFINITE
1217 class cfn_isfinite : public range_operator
1219 public:
1220 using range_operator::fold_range;
1221 using range_operator::op1_range;
1222 virtual bool fold_range (irange &r, tree type, const frange &op1,
1223 const irange &, relation_trio) const override
1225 if (op1.undefined_p ())
1226 return false;
1228 if (op1.known_isfinite ())
1230 wide_int one = wi::one (TYPE_PRECISION (type));
1231 r.set (type, one, one);
1232 return true;
1235 if (op1.known_isnan ()
1236 || op1.known_isinf ())
1238 r.set_zero (type);
1239 return true;
1242 r.set_varying (type);
1243 return true;
1245 virtual bool op1_range (frange &r, tree type, const irange &lhs,
1246 const frange &, relation_trio) const override
1248 if (lhs.undefined_p ())
1249 return false;
1251 if (lhs.zero_p ())
1253 // The range is [-INF,-INF][+INF,+INF] NAN, but it can't be represented.
1254 // Set range to varying
1255 r.set_varying (type);
1256 return true;
1259 if (!range_includes_zero_p (lhs))
1261 nan_state nan (false);
1262 r.set (type, real_min_representable (type),
1263 real_max_representable (type), nan);
1264 return true;
1267 r.set_varying (type);
1268 return true;
1270 } op_cfn_isfinite;
1272 //Implement range operator for CFN_BUILT_IN_ISNORMAL
1273 class cfn_isnormal : public range_operator
1275 public:
1276 using range_operator::fold_range;
1277 using range_operator::op1_range;
1278 virtual bool fold_range (irange &r, tree type, const frange &op1,
1279 const irange &, relation_trio) const override
1281 if (op1.undefined_p ())
1282 return false;
1284 if (op1.known_isnormal ())
1286 wide_int one = wi::one (TYPE_PRECISION (type));
1287 r.set (type, one, one);
1288 return true;
1291 if (op1.known_isnan ()
1292 || op1.known_isinf ()
1293 || op1.known_isdenormal_or_zero ())
1295 r.set_zero (type);
1296 return true;
1299 r.set_varying (type);
1300 return true;
1302 virtual bool op1_range (frange &r, tree type, const irange &lhs,
1303 const frange &, relation_trio) const override
1305 if (lhs.undefined_p ())
1306 return false;
1308 if (lhs.zero_p ())
1310 r.set_varying (type);
1311 return true;
1314 if (!range_includes_zero_p (lhs))
1316 nan_state nan (false);
1317 r.set (type, real_min_representable (type),
1318 real_max_representable (type), nan);
1319 return true;
1322 r.set_varying (type);
1323 return true;
1325 } op_cfn_isnormal;
1327 // Implement range operator for CFN_BUILT_IN_
1328 class cfn_parity : public range_operator
1330 public:
1331 using range_operator::fold_range;
1332 virtual bool fold_range (irange &r, tree type, const irange &,
1333 const irange &, relation_trio) const
1335 r = range_true_and_false (type);
1336 return true;
1338 } op_cfn_parity;
1340 // Set up a gimple_range_op_handler for any nonstandard function which can be
1341 // supported via range-ops.
1343 void
1344 gimple_range_op_handler::maybe_non_standard ()
1346 range_op_handler signed_op (OP_WIDEN_MULT_SIGNED);
1347 gcc_checking_assert (signed_op);
1348 range_op_handler unsigned_op (OP_WIDEN_MULT_UNSIGNED);
1349 gcc_checking_assert (unsigned_op);
1351 if (gimple_code (m_stmt) == GIMPLE_ASSIGN)
1352 switch (gimple_assign_rhs_code (m_stmt))
1354 case WIDEN_MULT_EXPR:
1356 m_op1 = gimple_assign_rhs1 (m_stmt);
1357 m_op2 = gimple_assign_rhs2 (m_stmt);
1358 tree ret = gimple_assign_lhs (m_stmt);
1359 bool signed1 = TYPE_SIGN (TREE_TYPE (m_op1)) == SIGNED;
1360 bool signed2 = TYPE_SIGN (TREE_TYPE (m_op2)) == SIGNED;
1361 bool signed_ret = TYPE_SIGN (TREE_TYPE (ret)) == SIGNED;
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 if ((signed1 ^ signed2) && signed_ret)
1370 return;
1372 if (signed2 && !signed1)
1373 std::swap (m_op1, m_op2);
1375 if (signed1 || signed2)
1376 m_operator = signed_op.range_op ();
1377 else
1378 m_operator = unsigned_op.range_op ();
1379 break;
1381 default:
1382 break;
1386 // Set up a gimple_range_op_handler for any built in function which can be
1387 // supported via range-ops.
1389 void
1390 gimple_range_op_handler::maybe_builtin_call ()
1392 gcc_checking_assert (is_a <gcall *> (m_stmt));
1394 gcall *call = as_a <gcall *> (m_stmt);
1395 combined_fn func = gimple_call_combined_fn (call);
1396 if (func == CFN_LAST)
1397 return;
1398 tree type = gimple_range_type (call);
1399 if (!type)
1400 return;
1401 if (!value_range::supports_type_p (type))
1402 return;
1404 switch (func)
1406 case CFN_BUILT_IN_CONSTANT_P:
1407 m_op1 = gimple_call_arg (call, 0);
1408 if (irange::supports_p (TREE_TYPE (m_op1)))
1409 m_operator = &op_cfn_constant_p;
1410 else if (frange::supports_p (TREE_TYPE (m_op1)))
1411 m_operator = &op_cfn_constant_float_p;
1412 break;
1414 CASE_FLT_FN (CFN_BUILT_IN_SIGNBIT):
1415 m_op1 = gimple_call_arg (call, 0);
1416 m_operator = &op_cfn_signbit;
1417 break;
1419 CASE_FLT_FN (BUILT_IN_ISINF):
1420 m_op1 = gimple_call_arg (call, 0);
1421 m_operator = &op_cfn_isinf;
1422 break;
1424 case CFN_BUILT_IN_ISFINITE:
1425 m_op1 = gimple_call_arg (call, 0);
1426 m_operator = &op_cfn_isfinite;
1427 break;
1429 case CFN_BUILT_IN_ISNORMAL:
1430 m_op1 = gimple_call_arg (call, 0);
1431 m_operator = &op_cfn_isnormal;
1432 break;
1434 CASE_CFN_COPYSIGN_ALL:
1435 m_op1 = gimple_call_arg (call, 0);
1436 m_op2 = gimple_call_arg (call, 1);
1437 m_operator = &op_cfn_copysign;
1438 break;
1440 CASE_CFN_SQRT:
1441 CASE_CFN_SQRT_FN:
1442 m_op1 = gimple_call_arg (call, 0);
1443 m_operator = &op_cfn_sqrt;
1444 break;
1446 CASE_CFN_SIN:
1447 CASE_CFN_SIN_FN:
1448 m_op1 = gimple_call_arg (call, 0);
1449 m_operator = &op_cfn_sin;
1450 break;
1452 CASE_CFN_COS:
1453 CASE_CFN_COS_FN:
1454 m_op1 = gimple_call_arg (call, 0);
1455 m_operator = &op_cfn_cos;
1456 break;
1458 case CFN_BUILT_IN_TOUPPER:
1459 case CFN_BUILT_IN_TOLOWER:
1460 // Only proceed If the argument is compatible with the LHS.
1461 m_op1 = gimple_call_arg (call, 0);
1462 if (range_compatible_p (type, TREE_TYPE (m_op1)))
1463 m_operator = (func == CFN_BUILT_IN_TOLOWER) ? &op_cfn_tolower
1464 : &op_cfn_toupper;
1465 break;
1467 CASE_CFN_FFS:
1468 m_op1 = gimple_call_arg (call, 0);
1469 m_operator = &op_cfn_ffs;
1470 break;
1472 CASE_CFN_POPCOUNT:
1473 m_op1 = gimple_call_arg (call, 0);
1474 m_operator = &op_cfn_popcount;
1475 break;
1477 CASE_CFN_CLZ:
1478 m_op1 = gimple_call_arg (call, 0);
1479 if (gimple_call_internal_p (call)
1480 && gimple_call_num_args (call) == 2)
1482 m_op2 = gimple_call_arg (call, 1);
1483 m_operator = &op_cfn_clz_internal;
1485 else
1486 m_operator = &op_cfn_clz;
1487 break;
1489 CASE_CFN_CTZ:
1490 m_op1 = gimple_call_arg (call, 0);
1491 if (gimple_call_internal_p (call)
1492 && gimple_call_num_args (call) == 2)
1494 m_op2 = gimple_call_arg (call, 1);
1495 m_operator = &op_cfn_ctz_internal;
1497 else
1498 m_operator = &op_cfn_ctz;
1499 break;
1501 CASE_CFN_CLRSB:
1502 m_op1 = gimple_call_arg (call, 0);
1503 m_operator = &op_cfn_clrsb;
1504 break;
1506 case CFN_UBSAN_CHECK_ADD:
1507 m_op1 = gimple_call_arg (call, 0);
1508 m_op2 = gimple_call_arg (call, 1);
1509 m_operator = &op_cfn_ubsan_add;
1510 break;
1512 case CFN_UBSAN_CHECK_SUB:
1513 m_op1 = gimple_call_arg (call, 0);
1514 m_op2 = gimple_call_arg (call, 1);
1515 m_operator = &op_cfn_ubsan_sub;
1516 break;
1518 case CFN_UBSAN_CHECK_MUL:
1519 m_op1 = gimple_call_arg (call, 0);
1520 m_op2 = gimple_call_arg (call, 1);
1521 m_operator = &op_cfn_ubsan_mul;
1522 break;
1524 case CFN_BUILT_IN_STRLEN:
1526 tree lhs = gimple_call_lhs (call);
1527 if (lhs && ptrdiff_type_node && (TYPE_PRECISION (ptrdiff_type_node)
1528 == TYPE_PRECISION (TREE_TYPE (lhs))))
1530 m_op1 = gimple_call_arg (call, 0);
1531 m_operator = &op_cfn_strlen;
1533 break;
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 case CFN_GOACC_DIM_SIZE:
1540 // This call will ensure all the asserts are triggered.
1541 oacc_get_ifn_dim_arg (call);
1542 m_op1 = gimple_call_arg (call, 0);
1543 m_operator = &op_cfn_goacc_dim_size;
1544 break;
1546 case CFN_GOACC_DIM_POS:
1547 // This call will ensure all the asserts are triggered.
1548 oacc_get_ifn_dim_arg (call);
1549 m_op1 = gimple_call_arg (call, 0);
1550 m_operator = &op_cfn_goacc_dim_pos;
1551 break;
1553 CASE_CFN_PARITY:
1554 m_operator = &op_cfn_parity;
1555 break;
1557 default:
1559 unsigned arg;
1560 if (gimple_call_fnspec (call).returns_arg (&arg) && arg == 0)
1562 m_op1 = gimple_call_arg (call, 0);
1563 m_operator = &op_cfn_pass_through_arg1;
1565 break;