d: Add test for PR d/108167 to the testsuite [PR108167]
[official-gcc.git] / gcc / gimple-range-op.cc
blobd9dfdc56939bb62ade72726b15c3d5e87e4ddcd1
1 /* Code for GIMPLE range op related routines.
2 Copyright (C) 2019-2023 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"
47 // Given stmt S, fill VEC, up to VEC_SIZE elements, with relevant ssa-names
48 // on the statement. For efficiency, it is an error to not pass in enough
49 // elements for the vector. Return the number of ssa-names.
51 unsigned
52 gimple_range_ssa_names (tree *vec, unsigned vec_size, gimple *stmt)
54 tree ssa;
55 int count = 0;
57 gimple_range_op_handler handler (stmt);
58 if (handler)
60 gcc_checking_assert (vec_size >= 2);
61 if ((ssa = gimple_range_ssa_p (handler.operand1 ())))
62 vec[count++] = ssa;
63 if ((ssa = gimple_range_ssa_p (handler.operand2 ())))
64 vec[count++] = ssa;
66 else if (is_a<gassign *> (stmt)
67 && gimple_assign_rhs_code (stmt) == COND_EXPR)
69 gcc_checking_assert (vec_size >= 3);
70 gassign *st = as_a<gassign *> (stmt);
71 if ((ssa = gimple_range_ssa_p (gimple_assign_rhs1 (st))))
72 vec[count++] = ssa;
73 if ((ssa = gimple_range_ssa_p (gimple_assign_rhs2 (st))))
74 vec[count++] = ssa;
75 if ((ssa = gimple_range_ssa_p (gimple_assign_rhs3 (st))))
76 vec[count++] = ssa;
78 return count;
81 // Return the base of the RHS of an assignment.
83 static tree
84 gimple_range_base_of_assignment (const gimple *stmt)
86 gcc_checking_assert (gimple_code (stmt) == GIMPLE_ASSIGN);
87 tree op1 = gimple_assign_rhs1 (stmt);
88 if (gimple_assign_rhs_code (stmt) == ADDR_EXPR)
89 return get_base_address (TREE_OPERAND (op1, 0));
90 return op1;
93 // If statement is supported by range-ops, set the CODE and return the TYPE.
95 static tree
96 get_code_and_type (gimple *s, enum tree_code &code)
98 tree type = NULL_TREE;
99 code = NOP_EXPR;
101 if (const gassign *ass = dyn_cast<const gassign *> (s))
103 code = gimple_assign_rhs_code (ass);
104 // The LHS of a comparison is always an int, so we must look at
105 // the operands.
106 if (TREE_CODE_CLASS (code) == tcc_comparison)
107 type = TREE_TYPE (gimple_assign_rhs1 (ass));
108 else
109 type = TREE_TYPE (gimple_assign_lhs (ass));
111 else if (const gcond *cond = dyn_cast<const gcond *> (s))
113 code = gimple_cond_code (cond);
114 type = TREE_TYPE (gimple_cond_lhs (cond));
116 return type;
119 // If statement S has a supported range_op handler return TRUE.
121 bool
122 gimple_range_op_handler::supported_p (gimple *s)
124 enum tree_code code;
125 tree type = get_code_and_type (s, code);
126 if (type && range_op_handler (code, type))
127 return true;
128 if (is_a <gcall *> (s) && gimple_range_op_handler (s))
129 return true;
130 return false;
133 // Construct a handler object for statement S.
135 gimple_range_op_handler::gimple_range_op_handler (gimple *s)
137 enum tree_code code;
138 tree type = get_code_and_type (s, code);
139 m_stmt = s;
140 m_op1 = NULL_TREE;
141 m_op2 = NULL_TREE;
142 if (type)
143 set_op_handler (code, type);
145 if (m_valid)
146 switch (gimple_code (m_stmt))
148 case GIMPLE_COND:
149 m_op1 = gimple_cond_lhs (m_stmt);
150 m_op2 = gimple_cond_rhs (m_stmt);
151 // Check that operands are supported types. One check is enough.
152 if (!Value_Range::supports_type_p (TREE_TYPE (m_op1)))
153 m_valid = false;
154 return;
155 case GIMPLE_ASSIGN:
156 m_op1 = gimple_range_base_of_assignment (m_stmt);
157 if (m_op1 && TREE_CODE (m_op1) == MEM_REF)
159 // If the base address is an SSA_NAME, we return it
160 // here. This allows processing of the range of that
161 // name, while the rest of the expression is simply
162 // ignored. The code in range_ops will see the
163 // ADDR_EXPR and do the right thing.
164 tree ssa = TREE_OPERAND (m_op1, 0);
165 if (TREE_CODE (ssa) == SSA_NAME)
166 m_op1 = ssa;
168 if (gimple_num_ops (m_stmt) >= 3)
169 m_op2 = gimple_assign_rhs2 (m_stmt);
170 // Check that operands are supported types. One check is enough.
171 if ((m_op1 && !Value_Range::supports_type_p (TREE_TYPE (m_op1))))
172 m_valid = false;
173 return;
174 default:
175 gcc_unreachable ();
176 return;
178 // If no range-op table entry handled this stmt, check for other supported
179 // statements.
180 if (is_a <gcall *> (m_stmt))
181 maybe_builtin_call ();
184 // Calculate what we can determine of the range of this unary
185 // statement's operand if the lhs of the expression has the range
186 // LHS_RANGE. Return false if nothing can be determined.
188 bool
189 gimple_range_op_handler::calc_op1 (vrange &r, const vrange &lhs_range)
191 gcc_checking_assert (gimple_num_ops (m_stmt) < 3);
192 // Give up on empty ranges.
193 if (lhs_range.undefined_p ())
194 return false;
196 // Unary operations require the type of the first operand in the
197 // second range position.
198 tree type = TREE_TYPE (operand1 ());
199 Value_Range type_range (type);
200 type_range.set_varying (type);
201 return op1_range (r, type, lhs_range, type_range);
204 // Calculate what we can determine of the range of this statement's
205 // first operand if the lhs of the expression has the range LHS_RANGE
206 // and the second operand has the range OP2_RANGE. Return false if
207 // nothing can be determined.
209 bool
210 gimple_range_op_handler::calc_op1 (vrange &r, const vrange &lhs_range,
211 const vrange &op2_range, relation_trio k)
213 // Give up on empty ranges.
214 if (lhs_range.undefined_p ())
215 return false;
217 // Unary operation are allowed to pass a range in for second operand
218 // as there are often additional restrictions beyond the type which
219 // can be imposed. See operator_cast::op1_range().
220 tree type = TREE_TYPE (operand1 ());
221 // If op2 is undefined, solve as if it is varying.
222 if (op2_range.undefined_p ())
224 if (gimple_num_ops (m_stmt) < 3)
225 return false;
226 tree op2_type;
227 // This is sometimes invoked on single operand stmts.
228 if (operand2 ())
229 op2_type = TREE_TYPE (operand2 ());
230 else
231 op2_type = TREE_TYPE (operand1 ());
232 Value_Range trange (op2_type);
233 trange.set_varying (op2_type);
234 return op1_range (r, type, lhs_range, trange, k);
236 return op1_range (r, type, lhs_range, op2_range, k);
239 // Calculate what we can determine of the range of this statement's
240 // second operand if the lhs of the expression has the range LHS_RANGE
241 // and the first operand has the range OP1_RANGE. Return false if
242 // nothing can be determined.
244 bool
245 gimple_range_op_handler::calc_op2 (vrange &r, const vrange &lhs_range,
246 const vrange &op1_range, relation_trio k)
248 // Give up on empty ranges.
249 if (lhs_range.undefined_p ())
250 return false;
252 tree type = TREE_TYPE (operand2 ());
253 // If op1 is undefined, solve as if it is varying.
254 if (op1_range.undefined_p ())
256 tree op1_type = TREE_TYPE (operand1 ());
257 Value_Range trange (op1_type);
258 trange.set_varying (op1_type);
259 return op2_range (r, type, lhs_range, trange, k);
261 return op2_range (r, type, lhs_range, op1_range, k);
264 // --------------------------------------------------------------------
266 // Implement range operator for float CFN_BUILT_IN_CONSTANT_P.
267 class cfn_constant_float_p : public range_operator_float
269 public:
270 using range_operator_float::fold_range;
271 virtual bool fold_range (irange &r, tree type, const frange &lh,
272 const irange &, relation_trio) const
274 if (lh.singleton_p ())
276 r.set (build_one_cst (type), build_one_cst (type));
277 return true;
279 if (cfun->after_inlining)
281 r.set_zero (type);
282 return true;
284 return false;
286 } op_cfn_constant_float_p;
288 // Implement range operator for integral CFN_BUILT_IN_CONSTANT_P.
289 class cfn_constant_p : public range_operator
291 public:
292 using range_operator::fold_range;
293 virtual bool fold_range (irange &r, tree type, const irange &lh,
294 const irange &, relation_trio) const
296 if (lh.singleton_p ())
298 r.set (build_one_cst (type), build_one_cst (type));
299 return true;
301 if (cfun->after_inlining)
303 r.set_zero (type);
304 return true;
306 return false;
308 } op_cfn_constant_p;
310 // Implement range operator for CFN_BUILT_IN_SIGNBIT.
311 class cfn_signbit : public range_operator_float
313 public:
314 using range_operator_float::fold_range;
315 using range_operator_float::op1_range;
316 virtual bool fold_range (irange &r, tree type, const frange &lh,
317 const irange &, relation_trio) const override
319 bool signbit;
320 if (lh.signbit_p (signbit))
322 if (signbit)
323 r.set_nonzero (type);
324 else
325 r.set_zero (type);
326 return true;
328 return false;
330 virtual bool op1_range (frange &r, tree type, const irange &lhs,
331 const frange &, relation_trio) const override
333 if (lhs.zero_p ())
335 r.set (type, dconst0, frange_val_max (type));
336 r.update_nan (false);
337 return true;
339 if (!lhs.contains_p (build_zero_cst (lhs.type ())))
341 REAL_VALUE_TYPE dconstm0 = dconst0;
342 dconstm0.sign = 1;
343 r.set (type, frange_val_min (type), dconstm0);
344 r.update_nan (true);
345 return true;
347 return false;
349 } op_cfn_signbit;
351 // Implement range operator for CFN_BUILT_IN_COPYSIGN
352 class cfn_copysign : public range_operator_float
354 public:
355 using range_operator_float::fold_range;
356 virtual bool fold_range (frange &r, tree type, const frange &lh,
357 const frange &rh, relation_trio) const override
359 frange neg;
360 range_op_handler abs_op (ABS_EXPR, type);
361 range_op_handler neg_op (NEGATE_EXPR, type);
362 if (!abs_op || !abs_op.fold_range (r, type, lh, frange (type)))
363 return false;
364 if (!neg_op || !neg_op.fold_range (neg, type, r, frange (type)))
365 return false;
367 bool signbit;
368 if (rh.signbit_p (signbit))
370 // If the sign is negative, flip the result from ABS,
371 // otherwise leave things positive.
372 if (signbit)
373 r = neg;
375 else
376 // If the sign is unknown, keep the positive and negative
377 // alternatives.
378 r.union_ (neg);
379 return true;
381 } op_cfn_copysign;
383 // Implement range operator for CFN_BUILT_IN_TOUPPER and CFN_BUILT_IN_TOLOWER.
384 class cfn_toupper_tolower : public range_operator
386 public:
387 using range_operator::fold_range;
388 cfn_toupper_tolower (bool toupper) { m_toupper = toupper; }
389 virtual bool fold_range (irange &r, tree type, const irange &lh,
390 const irange &, relation_trio) const;
391 private:
392 bool get_letter_range (tree type, irange &lowers, irange &uppers) const;
393 bool m_toupper;
394 } op_cfn_toupper (true), op_cfn_tolower (false);
396 // Return TRUE if we recognize the target character set and return the
397 // range for lower case and upper case letters.
399 bool
400 cfn_toupper_tolower::get_letter_range (tree type, irange &lowers,
401 irange &uppers) const
403 // ASCII
404 int a = lang_hooks.to_target_charset ('a');
405 int z = lang_hooks.to_target_charset ('z');
406 int A = lang_hooks.to_target_charset ('A');
407 int Z = lang_hooks.to_target_charset ('Z');
409 if ((z - a == 25) && (Z - A == 25))
411 lowers = int_range<2> (build_int_cst (type, a), build_int_cst (type, z));
412 uppers = int_range<2> (build_int_cst (type, A), build_int_cst (type, Z));
413 return true;
415 // Unknown character set.
416 return false;
419 bool
420 cfn_toupper_tolower::fold_range (irange &r, tree type, const irange &lh,
421 const irange &, relation_trio) const
423 int_range<3> lowers;
424 int_range<3> uppers;
425 if (!get_letter_range (type, lowers, uppers))
426 return false;
428 r = lh;
429 if (m_toupper)
431 // Return the range passed in without any lower case characters,
432 // but including all the upper case ones.
433 lowers.invert ();
434 r.intersect (lowers);
435 r.union_ (uppers);
437 else
439 // Return the range passed in without any lower case characters,
440 // but including all the upper case ones.
441 uppers.invert ();
442 r.intersect (uppers);
443 r.union_ (lowers);
445 return true;
448 // Implement range operator for CFN_BUILT_IN_FFS.
449 class cfn_ffs : public range_operator
451 public:
452 using range_operator::fold_range;
453 virtual bool fold_range (irange &r, tree type, const irange &lh,
454 const irange &, relation_trio) const
456 if (lh.undefined_p ())
457 return false;
458 // __builtin_ffs* and __builtin_popcount* return [0, prec].
459 int prec = TYPE_PRECISION (lh.type ());
460 // If arg is non-zero, then ffs or popcount are non-zero.
461 int mini = range_includes_zero_p (&lh) ? 0 : 1;
462 int maxi = prec;
464 // If some high bits are known to be zero, decrease the maximum.
465 int_range_max tmp = lh;
466 if (TYPE_SIGN (tmp.type ()) == SIGNED)
467 range_cast (tmp, unsigned_type_for (tmp.type ()));
468 wide_int max = tmp.upper_bound ();
469 maxi = wi::floor_log2 (max) + 1;
470 r.set (build_int_cst (type, mini), build_int_cst (type, maxi));
471 return true;
473 } op_cfn_ffs;
475 // Implement range operator for CFN_BUILT_IN_POPCOUNT.
476 class cfn_popcount : public cfn_ffs
478 public:
479 using range_operator::fold_range;
480 virtual bool fold_range (irange &r, tree type, const irange &lh,
481 const irange &rh, relation_trio rel) const
483 if (lh.undefined_p ())
484 return false;
485 unsigned prec = TYPE_PRECISION (type);
486 wide_int nz = lh.get_nonzero_bits ();
487 wide_int pop = wi::shwi (wi::popcount (nz), prec);
488 // Calculating the popcount of a singleton is trivial.
489 if (lh.singleton_p ())
491 r.set (type, pop, pop);
492 return true;
494 if (cfn_ffs::fold_range (r, type, lh, rh, rel))
496 int_range<2> tmp (type, wi::zero (prec), pop);
497 r.intersect (tmp);
498 return true;
500 return false;
502 } op_cfn_popcount;
504 // Implement range operator for CFN_BUILT_IN_CLZ
505 class cfn_clz : public range_operator
507 public:
508 cfn_clz (bool internal) { m_gimple_call_internal_p = internal; }
509 using range_operator::fold_range;
510 virtual bool fold_range (irange &r, tree type, const irange &lh,
511 const irange &, relation_trio) const;
512 private:
513 bool m_gimple_call_internal_p;
514 } op_cfn_clz (false), op_cfn_clz_internal (true);
516 bool
517 cfn_clz::fold_range (irange &r, tree type, const irange &lh,
518 const irange &, relation_trio) const
520 // __builtin_c[lt]z* return [0, prec-1], except when the
521 // argument is 0, but that is undefined behavior.
523 // For __builtin_c[lt]z* consider argument of 0 always undefined
524 // behavior, for internal fns depending on C?Z_DEFINED_ALUE_AT_ZERO.
525 if (lh.undefined_p ())
526 return false;
527 int prec = TYPE_PRECISION (lh.type ());
528 int mini = 0;
529 int maxi = prec - 1;
530 int zerov = 0;
531 scalar_int_mode mode = SCALAR_INT_TYPE_MODE (lh.type ());
532 if (m_gimple_call_internal_p)
534 if (optab_handler (clz_optab, mode) != CODE_FOR_nothing
535 && CLZ_DEFINED_VALUE_AT_ZERO (mode, zerov) == 2)
537 // Only handle the single common value.
538 if (zerov == prec)
539 maxi = prec;
540 else
541 // Magic value to give up, unless we can prove arg is non-zero.
542 mini = -2;
546 // From clz of minimum we can compute result maximum.
547 if (wi::gt_p (lh.lower_bound (), 0, TYPE_SIGN (lh.type ())))
549 maxi = prec - 1 - wi::floor_log2 (lh.lower_bound ());
550 if (mini == -2)
551 mini = 0;
553 else if (!range_includes_zero_p (&lh))
555 mini = 0;
556 maxi = prec - 1;
558 if (mini == -2)
559 return false;
560 // From clz of maximum we can compute result minimum.
561 wide_int max = lh.upper_bound ();
562 int newmini = prec - 1 - wi::floor_log2 (max);
563 if (max == 0)
565 // If CLZ_DEFINED_VALUE_AT_ZERO is 2 with VALUE of prec,
566 // return [prec, prec], otherwise ignore the range.
567 if (maxi == prec)
568 mini = prec;
570 else
571 mini = newmini;
573 if (mini == -2)
574 return false;
575 r.set (build_int_cst (type, mini), build_int_cst (type, maxi));
576 return true;
579 // Implement range operator for CFN_BUILT_IN_CTZ
580 class cfn_ctz : public range_operator
582 public:
583 cfn_ctz (bool internal) { m_gimple_call_internal_p = internal; }
584 using range_operator::fold_range;
585 virtual bool fold_range (irange &r, tree type, const irange &lh,
586 const irange &, relation_trio) const;
587 private:
588 bool m_gimple_call_internal_p;
589 } op_cfn_ctz (false), op_cfn_ctz_internal (true);
591 bool
592 cfn_ctz::fold_range (irange &r, tree type, const irange &lh,
593 const irange &, relation_trio) const
595 if (lh.undefined_p ())
596 return false;
597 int prec = TYPE_PRECISION (lh.type ());
598 int mini = 0;
599 int maxi = prec - 1;
600 int zerov = 0;
601 scalar_int_mode mode = SCALAR_INT_TYPE_MODE (lh.type ());
603 if (m_gimple_call_internal_p)
605 if (optab_handler (ctz_optab, mode) != CODE_FOR_nothing
606 && CTZ_DEFINED_VALUE_AT_ZERO (mode, zerov) == 2)
608 // Handle only the two common values.
609 if (zerov == -1)
610 mini = -1;
611 else if (zerov == prec)
612 maxi = prec;
613 else
614 // Magic value to give up, unless we can prove arg is non-zero.
615 mini = -2;
618 // If arg is non-zero, then use [0, prec - 1].
619 if (!range_includes_zero_p (&lh))
621 mini = 0;
622 maxi = prec - 1;
624 // If some high bits are known to be zero, we can decrease
625 // the maximum.
626 wide_int max = lh.upper_bound ();
627 if (max == 0)
629 // Argument is [0, 0]. If CTZ_DEFINED_VALUE_AT_ZERO
630 // is 2 with value -1 or prec, return [-1, -1] or [prec, prec].
631 // Otherwise ignore the range.
632 if (mini == -1)
633 maxi = -1;
634 else if (maxi == prec)
635 mini = prec;
637 // If value at zero is prec and 0 is in the range, we can't lower
638 // the upper bound. We could create two separate ranges though,
639 // [0,floor_log2(max)][prec,prec] though.
640 else if (maxi != prec)
641 maxi = wi::floor_log2 (max);
643 if (mini == -2)
644 return false;
645 r.set (build_int_cst (type, mini), build_int_cst (type, maxi));
646 return true;
650 // Implement range operator for CFN_BUILT_IN_
651 class cfn_clrsb : public range_operator
653 public:
654 using range_operator::fold_range;
655 virtual bool fold_range (irange &r, tree type, const irange &lh,
656 const irange &, relation_trio) const
658 if (lh.undefined_p ())
659 return false;
660 int prec = TYPE_PRECISION (lh.type ());
661 r.set (build_int_cst (type, 0), build_int_cst (type, prec - 1));
662 return true;
664 } op_cfn_clrsb;
667 // Implement range operator for CFN_BUILT_IN_
668 class cfn_ubsan : public range_operator
670 public:
671 cfn_ubsan (enum tree_code code) { m_code = code; }
672 using range_operator::fold_range;
673 virtual bool fold_range (irange &r, tree type, const irange &lh,
674 const irange &rh, relation_trio rel) const
676 range_op_handler handler (m_code, type);
677 gcc_checking_assert (handler);
679 bool saved_flag_wrapv = flag_wrapv;
680 // Pretend the arithmetic is wrapping. If there is any overflow,
681 // we'll complain, but will actually do wrapping operation.
682 flag_wrapv = 1;
683 bool result = handler.fold_range (r, type, lh, rh, rel);
684 flag_wrapv = saved_flag_wrapv;
686 // If for both arguments vrp_valueize returned non-NULL, this should
687 // have been already folded and if not, it wasn't folded because of
688 // overflow. Avoid removing the UBSAN_CHECK_* calls in that case.
689 if (result && r.singleton_p ())
690 r.set_varying (type);
691 return result;
693 private:
694 enum tree_code m_code;
697 cfn_ubsan op_cfn_ubsan_add (PLUS_EXPR);
698 cfn_ubsan op_cfn_ubsan_sub (MINUS_EXPR);
699 cfn_ubsan op_cfn_ubsan_mul (MULT_EXPR);
702 // Implement range operator for CFN_BUILT_IN_STRLEN
703 class cfn_strlen : public range_operator
705 public:
706 using range_operator::fold_range;
707 virtual bool fold_range (irange &r, tree type, const irange &,
708 const irange &, relation_trio) const
710 tree max = vrp_val_max (ptrdiff_type_node);
711 wide_int wmax
712 = wi::to_wide (max, TYPE_PRECISION (TREE_TYPE (max)));
713 tree range_min = build_zero_cst (type);
714 // To account for the terminating NULL, the maximum length
715 // is one less than the maximum array size, which in turn
716 // is one less than PTRDIFF_MAX (or SIZE_MAX where it's
717 // smaller than the former type).
718 // FIXME: Use max_object_size() - 1 here.
719 tree range_max = wide_int_to_tree (type, wmax - 2);
720 r.set (range_min, range_max);
721 return true;
723 } op_cfn_strlen;
726 // Implement range operator for CFN_BUILT_IN_GOACC_DIM
727 class cfn_goacc_dim : public range_operator
729 public:
730 cfn_goacc_dim (bool is_pos) { m_is_pos = is_pos; }
731 using range_operator::fold_range;
732 virtual bool fold_range (irange &r, tree type, const irange &lh,
733 const irange &, relation_trio) const
735 tree axis_tree;
736 if (!lh.singleton_p (&axis_tree))
737 return false;
738 HOST_WIDE_INT axis = TREE_INT_CST_LOW (axis_tree);
739 int size = oacc_get_fn_dim_size (current_function_decl, axis);
740 if (!size)
741 // If it's dynamic, the backend might know a hardware limitation.
742 size = targetm.goacc.dim_limit (axis);
744 r.set (build_int_cst (type, m_is_pos ? 0 : 1),
745 size
746 ? build_int_cst (type, size - m_is_pos) : vrp_val_max (type));
747 return true;
749 private:
750 bool m_is_pos;
751 } op_cfn_goacc_dim_size (false), op_cfn_goacc_dim_pos (true);
754 // Implement range operator for CFN_BUILT_IN_
755 class cfn_parity : public range_operator
757 public:
758 using range_operator::fold_range;
759 virtual bool fold_range (irange &r, tree type, const irange &,
760 const irange &, relation_trio) const
762 r.set (build_zero_cst (type), build_one_cst (type));
763 return true;
765 } op_cfn_parity;
767 // Set up a gimple_range_op_handler for any built in function which can be
768 // supported via range-ops.
770 void
771 gimple_range_op_handler::maybe_builtin_call ()
773 gcc_checking_assert (is_a <gcall *> (m_stmt));
775 gcall *call = as_a <gcall *> (m_stmt);
776 combined_fn func = gimple_call_combined_fn (call);
777 if (func == CFN_LAST)
778 return;
779 tree type = gimple_range_type (call);
780 gcc_checking_assert (type);
781 if (!Value_Range::supports_type_p (type))
782 return;
784 switch (func)
786 case CFN_BUILT_IN_CONSTANT_P:
787 m_op1 = gimple_call_arg (call, 0);
788 m_valid = true;
789 if (irange::supports_p (TREE_TYPE (m_op1)))
790 m_int = &op_cfn_constant_p;
791 else if (frange::supports_p (TREE_TYPE (m_op1)))
792 m_float = &op_cfn_constant_float_p;
793 else
794 m_valid = false;
795 break;
797 CASE_FLT_FN (CFN_BUILT_IN_SIGNBIT):
798 m_op1 = gimple_call_arg (call, 0);
799 m_float = &op_cfn_signbit;
800 m_valid = true;
801 break;
803 CASE_CFN_COPYSIGN_ALL:
804 m_op1 = gimple_call_arg (call, 0);
805 m_op2 = gimple_call_arg (call, 1);
806 m_float = &op_cfn_copysign;
807 m_valid = true;
808 break;
810 case CFN_BUILT_IN_TOUPPER:
811 case CFN_BUILT_IN_TOLOWER:
812 // Only proceed If the argument is compatible with the LHS.
813 m_op1 = gimple_call_arg (call, 0);
814 if (range_compatible_p (type, TREE_TYPE (m_op1)))
816 m_valid = true;
817 m_int = (func == CFN_BUILT_IN_TOLOWER) ? &op_cfn_tolower
818 : &op_cfn_toupper;
820 break;
822 CASE_CFN_FFS:
823 m_op1 = gimple_call_arg (call, 0);
824 m_int = &op_cfn_ffs;
825 m_valid = true;
826 break;
828 CASE_CFN_POPCOUNT:
829 m_op1 = gimple_call_arg (call, 0);
830 m_int = &op_cfn_popcount;
831 m_valid = true;
832 break;
834 CASE_CFN_CLZ:
835 m_op1 = gimple_call_arg (call, 0);
836 m_valid = true;
837 if (gimple_call_internal_p (call))
838 m_int = &op_cfn_clz_internal;
839 else
840 m_int = &op_cfn_clz;
841 break;
843 CASE_CFN_CTZ:
844 m_op1 = gimple_call_arg (call, 0);
845 m_valid = true;
846 if (gimple_call_internal_p (call))
847 m_int = &op_cfn_ctz_internal;
848 else
849 m_int = &op_cfn_ctz;
850 break;
852 CASE_CFN_CLRSB:
853 m_op1 = gimple_call_arg (call, 0);
854 m_valid = true;
855 m_int = &op_cfn_clrsb;
856 break;
858 case CFN_UBSAN_CHECK_ADD:
859 m_op1 = gimple_call_arg (call, 0);
860 m_op2 = gimple_call_arg (call, 1);
861 m_valid = true;
862 m_int = &op_cfn_ubsan_add;
863 break;
865 case CFN_UBSAN_CHECK_SUB:
866 m_op1 = gimple_call_arg (call, 0);
867 m_op2 = gimple_call_arg (call, 1);
868 m_valid = true;
869 m_int = &op_cfn_ubsan_sub;
870 break;
872 case CFN_UBSAN_CHECK_MUL:
873 m_op1 = gimple_call_arg (call, 0);
874 m_op2 = gimple_call_arg (call, 1);
875 m_valid = true;
876 m_int = &op_cfn_ubsan_mul;
877 break;
879 case CFN_BUILT_IN_STRLEN:
881 tree lhs = gimple_call_lhs (call);
882 if (lhs && ptrdiff_type_node && (TYPE_PRECISION (ptrdiff_type_node)
883 == TYPE_PRECISION (TREE_TYPE (lhs))))
885 m_op1 = gimple_call_arg (call, 0);
886 m_valid = true;
887 m_int = &op_cfn_strlen;
889 break;
892 // Optimizing these two internal functions helps the loop
893 // optimizer eliminate outer comparisons. Size is [1,N]
894 // and pos is [0,N-1].
895 case CFN_GOACC_DIM_SIZE:
896 // This call will ensure all the asserts are triggered.
897 oacc_get_ifn_dim_arg (call);
898 m_op1 = gimple_call_arg (call, 0);
899 m_valid = true;
900 m_int = &op_cfn_goacc_dim_size;
901 break;
903 case CFN_GOACC_DIM_POS:
904 // This call will ensure all the asserts are triggered.
905 oacc_get_ifn_dim_arg (call);
906 m_op1 = gimple_call_arg (call, 0);
907 m_valid = true;
908 m_int = &op_cfn_goacc_dim_pos;
909 break;
911 CASE_CFN_PARITY:
912 m_valid = true;
913 m_int = &op_cfn_parity;
914 break;
916 default:
917 break;