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)
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/>. */
24 #include "coretypes.h"
26 #include "insn-codes.h"
30 #include "gimple-pretty-print.h"
31 #include "optabs-tree.h"
32 #include "gimple-iterator.h"
33 #include "gimple-fold.h"
35 #include "fold-const.h"
36 #include "case-cfn-macros.h"
37 #include "omp-general.h"
39 #include "tree-ssa-loop.h"
40 #include "tree-scalar-evolution.h"
41 #include "langhooks.h"
42 #include "vr-values.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.
52 gimple_range_ssa_names (tree
*vec
, unsigned vec_size
, gimple
*stmt
)
57 gimple_range_op_handler
handler (stmt
);
60 gcc_checking_assert (vec_size
>= 2);
61 if ((ssa
= gimple_range_ssa_p (handler
.operand1 ())))
63 if ((ssa
= gimple_range_ssa_p (handler
.operand2 ())))
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
))))
73 if ((ssa
= gimple_range_ssa_p (gimple_assign_rhs2 (st
))))
75 if ((ssa
= gimple_range_ssa_p (gimple_assign_rhs3 (st
))))
81 // Return the base of the RHS of an assignment.
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));
93 // If statement is supported by range-ops, set the CODE and return the TYPE.
96 get_code_and_type (gimple
*s
, enum tree_code
&code
)
98 tree type
= NULL_TREE
;
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
106 if (TREE_CODE_CLASS (code
) == tcc_comparison
)
107 type
= TREE_TYPE (gimple_assign_rhs1 (ass
));
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
));
119 // If statement S has a supported range_op handler return TRUE.
122 gimple_range_op_handler::supported_p (gimple
*s
)
125 tree type
= get_code_and_type (s
, code
);
126 if (type
&& range_op_handler (code
, type
))
128 if (is_a
<gcall
*> (s
) && gimple_range_op_handler (s
))
133 // Construct a handler object for statement S.
135 gimple_range_op_handler::gimple_range_op_handler (gimple
*s
)
138 tree type
= get_code_and_type (s
, code
);
143 set_op_handler (code
, type
);
146 switch (gimple_code (m_stmt
))
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
)))
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
)
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
))))
178 // If no range-op table entry handled this stmt, check for other supported
180 if (is_a
<gcall
*> (m_stmt
))
181 maybe_builtin_call ();
183 maybe_non_standard ();
186 // Calculate what we can determine of the range of this unary
187 // statement's operand if the lhs of the expression has the range
188 // LHS_RANGE. Return false if nothing can be determined.
191 gimple_range_op_handler::calc_op1 (vrange
&r
, const vrange
&lhs_range
)
193 gcc_checking_assert (gimple_num_ops (m_stmt
) < 3);
194 // Give up on empty ranges.
195 if (lhs_range
.undefined_p ())
198 // Unary operations require the type of the first operand in the
199 // second range position.
200 tree type
= TREE_TYPE (operand1 ());
201 Value_Range
type_range (type
);
202 type_range
.set_varying (type
);
203 return op1_range (r
, type
, lhs_range
, type_range
);
206 // Calculate what we can determine of the range of this statement's
207 // first operand if the lhs of the expression has the range LHS_RANGE
208 // and the second operand has the range OP2_RANGE. Return false if
209 // nothing can be determined.
212 gimple_range_op_handler::calc_op1 (vrange
&r
, const vrange
&lhs_range
,
213 const vrange
&op2_range
, relation_trio k
)
215 // Give up on empty ranges.
216 if (lhs_range
.undefined_p ())
219 // Unary operation are allowed to pass a range in for second operand
220 // as there are often additional restrictions beyond the type which
221 // can be imposed. See operator_cast::op1_range().
222 tree type
= TREE_TYPE (operand1 ());
223 // If op2 is undefined, solve as if it is varying.
224 if (op2_range
.undefined_p ())
226 if (gimple_num_ops (m_stmt
) < 3)
229 // This is sometimes invoked on single operand stmts.
231 op2_type
= TREE_TYPE (operand2 ());
233 op2_type
= TREE_TYPE (operand1 ());
234 Value_Range
trange (op2_type
);
235 trange
.set_varying (op2_type
);
236 return op1_range (r
, type
, lhs_range
, trange
, k
);
238 return op1_range (r
, type
, lhs_range
, op2_range
, k
);
241 // Calculate what we can determine of the range of this statement's
242 // second operand if the lhs of the expression has the range LHS_RANGE
243 // and the first operand has the range OP1_RANGE. Return false if
244 // nothing can be determined.
247 gimple_range_op_handler::calc_op2 (vrange
&r
, const vrange
&lhs_range
,
248 const vrange
&op1_range
, relation_trio k
)
250 // Give up on empty ranges.
251 if (lhs_range
.undefined_p ())
254 tree type
= TREE_TYPE (operand2 ());
255 // If op1 is undefined, solve as if it is varying.
256 if (op1_range
.undefined_p ())
258 tree op1_type
= TREE_TYPE (operand1 ());
259 Value_Range
trange (op1_type
);
260 trange
.set_varying (op1_type
);
261 return op2_range (r
, type
, lhs_range
, trange
, k
);
263 return op2_range (r
, type
, lhs_range
, op1_range
, k
);
266 // --------------------------------------------------------------------
268 // Implement range operator for float CFN_BUILT_IN_CONSTANT_P.
269 class cfn_constant_float_p
: public range_operator_float
272 using range_operator_float::fold_range
;
273 virtual bool fold_range (irange
&r
, tree type
, const frange
&lh
,
274 const irange
&, relation_trio
) const
276 if (lh
.singleton_p ())
278 r
.set (build_one_cst (type
), build_one_cst (type
));
281 if (cfun
->after_inlining
)
288 } op_cfn_constant_float_p
;
290 // Implement range operator for integral CFN_BUILT_IN_CONSTANT_P.
291 class cfn_constant_p
: public range_operator
294 using range_operator::fold_range
;
295 virtual bool fold_range (irange
&r
, tree type
, const irange
&lh
,
296 const irange
&, relation_trio
) const
298 if (lh
.singleton_p ())
300 r
.set (build_one_cst (type
), build_one_cst (type
));
303 if (cfun
->after_inlining
)
312 // Implement range operator for integral/pointer functions returning
313 // the first argument.
314 class cfn_pass_through_arg1
: public range_operator
317 using range_operator::fold_range
;
318 virtual bool fold_range (irange
&r
, tree
, const irange
&lh
,
319 const irange
&, relation_trio
) const
324 virtual bool op1_range (irange
&r
, tree
, const irange
&lhs
,
325 const irange
&, relation_trio
) const
330 } op_cfn_pass_through_arg1
;
332 // Implement range operator for CFN_BUILT_IN_SIGNBIT.
333 class cfn_signbit
: public range_operator_float
336 using range_operator_float::fold_range
;
337 using range_operator_float::op1_range
;
338 virtual bool fold_range (irange
&r
, tree type
, const frange
&lh
,
339 const irange
&, relation_trio
) const override
342 if (lh
.signbit_p (signbit
))
345 r
.set_nonzero (type
);
352 virtual bool op1_range (frange
&r
, tree type
, const irange
&lhs
,
353 const frange
&, relation_trio
) const override
357 r
.set (type
, dconst0
, frange_val_max (type
));
358 r
.update_nan (false);
361 if (!lhs
.contains_p (build_zero_cst (lhs
.type ())))
363 REAL_VALUE_TYPE dconstm0
= dconst0
;
365 r
.set (type
, frange_val_min (type
), dconstm0
);
373 // Implement range operator for CFN_BUILT_IN_COPYSIGN
374 class cfn_copysign
: public range_operator_float
377 using range_operator_float::fold_range
;
378 virtual bool fold_range (frange
&r
, tree type
, const frange
&lh
,
379 const frange
&rh
, relation_trio
) const override
382 range_op_handler
abs_op (ABS_EXPR
, type
);
383 range_op_handler
neg_op (NEGATE_EXPR
, type
);
384 if (!abs_op
|| !abs_op
.fold_range (r
, type
, lh
, frange (type
)))
386 if (!neg_op
|| !neg_op
.fold_range (neg
, type
, r
, frange (type
)))
390 if (rh
.signbit_p (signbit
))
392 // If the sign is negative, flip the result from ABS,
393 // otherwise leave things positive.
398 // If the sign is unknown, keep the positive and negative
405 // Implement range operator for CFN_BUILT_IN_TOUPPER and CFN_BUILT_IN_TOLOWER.
406 class cfn_toupper_tolower
: public range_operator
409 using range_operator::fold_range
;
410 cfn_toupper_tolower (bool toupper
) { m_toupper
= toupper
; }
411 virtual bool fold_range (irange
&r
, tree type
, const irange
&lh
,
412 const irange
&, relation_trio
) const;
414 bool get_letter_range (tree type
, irange
&lowers
, irange
&uppers
) const;
416 } op_cfn_toupper (true), op_cfn_tolower (false);
418 // Return TRUE if we recognize the target character set and return the
419 // range for lower case and upper case letters.
422 cfn_toupper_tolower::get_letter_range (tree type
, irange
&lowers
,
423 irange
&uppers
) const
426 int a
= lang_hooks
.to_target_charset ('a');
427 int z
= lang_hooks
.to_target_charset ('z');
428 int A
= lang_hooks
.to_target_charset ('A');
429 int Z
= lang_hooks
.to_target_charset ('Z');
431 if ((z
- a
== 25) && (Z
- A
== 25))
433 lowers
= int_range
<2> (build_int_cst (type
, a
), build_int_cst (type
, z
));
434 uppers
= int_range
<2> (build_int_cst (type
, A
), build_int_cst (type
, Z
));
437 // Unknown character set.
442 cfn_toupper_tolower::fold_range (irange
&r
, tree type
, const irange
&lh
,
443 const irange
&, relation_trio
) const
447 if (!get_letter_range (type
, lowers
, uppers
))
453 // Return the range passed in without any lower case characters,
454 // but including all the upper case ones.
456 r
.intersect (lowers
);
461 // Return the range passed in without any lower case characters,
462 // but including all the upper case ones.
464 r
.intersect (uppers
);
470 // Implement range operator for CFN_BUILT_IN_FFS.
471 class cfn_ffs
: public range_operator
474 using range_operator::fold_range
;
475 virtual bool fold_range (irange
&r
, tree type
, const irange
&lh
,
476 const irange
&, relation_trio
) const
478 if (lh
.undefined_p ())
480 // __builtin_ffs* and __builtin_popcount* return [0, prec].
481 int prec
= TYPE_PRECISION (lh
.type ());
482 // If arg is non-zero, then ffs or popcount are non-zero.
483 int mini
= range_includes_zero_p (&lh
) ? 0 : 1;
486 // If some high bits are known to be zero, decrease the maximum.
487 int_range_max tmp
= lh
;
488 if (TYPE_SIGN (tmp
.type ()) == SIGNED
)
489 range_cast (tmp
, unsigned_type_for (tmp
.type ()));
490 wide_int max
= tmp
.upper_bound ();
491 maxi
= wi::floor_log2 (max
) + 1;
492 r
.set (build_int_cst (type
, mini
), build_int_cst (type
, maxi
));
497 // Implement range operator for CFN_BUILT_IN_POPCOUNT.
498 class cfn_popcount
: public cfn_ffs
501 using range_operator::fold_range
;
502 virtual bool fold_range (irange
&r
, tree type
, const irange
&lh
,
503 const irange
&rh
, relation_trio rel
) const
505 if (lh
.undefined_p ())
507 unsigned prec
= TYPE_PRECISION (type
);
508 wide_int nz
= lh
.get_nonzero_bits ();
509 wide_int pop
= wi::shwi (wi::popcount (nz
), prec
);
510 // Calculating the popcount of a singleton is trivial.
511 if (lh
.singleton_p ())
513 r
.set (type
, pop
, pop
);
516 if (cfn_ffs::fold_range (r
, type
, lh
, rh
, rel
))
518 int_range
<2> tmp (type
, wi::zero (prec
), pop
);
526 // Implement range operator for CFN_BUILT_IN_CLZ
527 class cfn_clz
: public range_operator
530 cfn_clz (bool internal
) { m_gimple_call_internal_p
= internal
; }
531 using range_operator::fold_range
;
532 virtual bool fold_range (irange
&r
, tree type
, const irange
&lh
,
533 const irange
&, relation_trio
) const;
535 bool m_gimple_call_internal_p
;
536 } op_cfn_clz (false), op_cfn_clz_internal (true);
539 cfn_clz::fold_range (irange
&r
, tree type
, const irange
&lh
,
540 const irange
&, relation_trio
) const
542 // __builtin_c[lt]z* return [0, prec-1], except when the
543 // argument is 0, but that is undefined behavior.
545 // For __builtin_c[lt]z* consider argument of 0 always undefined
546 // behavior, for internal fns depending on C?Z_DEFINED_VALUE_AT_ZERO.
547 if (lh
.undefined_p ())
549 int prec
= TYPE_PRECISION (lh
.type ());
553 scalar_int_mode mode
= SCALAR_INT_TYPE_MODE (lh
.type ());
554 if (m_gimple_call_internal_p
)
556 if (optab_handler (clz_optab
, mode
) != CODE_FOR_nothing
557 && CLZ_DEFINED_VALUE_AT_ZERO (mode
, zerov
) == 2)
559 // Only handle the single common value.
563 // Magic value to give up, unless we can prove arg is non-zero.
568 // From clz of minimum we can compute result maximum.
569 if (wi::gt_p (lh
.lower_bound (), 0, TYPE_SIGN (lh
.type ())))
571 maxi
= prec
- 1 - wi::floor_log2 (lh
.lower_bound ());
575 else if (!range_includes_zero_p (&lh
))
582 // From clz of maximum we can compute result minimum.
583 wide_int max
= lh
.upper_bound ();
584 int newmini
= prec
- 1 - wi::floor_log2 (max
);
587 // If CLZ_DEFINED_VALUE_AT_ZERO is 2 with VALUE of prec,
588 // return [prec, prec], otherwise ignore the range.
597 r
.set (build_int_cst (type
, mini
), build_int_cst (type
, maxi
));
601 // Implement range operator for CFN_BUILT_IN_CTZ
602 class cfn_ctz
: public range_operator
605 cfn_ctz (bool internal
) { m_gimple_call_internal_p
= internal
; }
606 using range_operator::fold_range
;
607 virtual bool fold_range (irange
&r
, tree type
, const irange
&lh
,
608 const irange
&, relation_trio
) const;
610 bool m_gimple_call_internal_p
;
611 } op_cfn_ctz (false), op_cfn_ctz_internal (true);
614 cfn_ctz::fold_range (irange
&r
, tree type
, const irange
&lh
,
615 const irange
&, relation_trio
) const
617 if (lh
.undefined_p ())
619 int prec
= TYPE_PRECISION (lh
.type ());
623 scalar_int_mode mode
= SCALAR_INT_TYPE_MODE (lh
.type ());
625 if (m_gimple_call_internal_p
)
627 if (optab_handler (ctz_optab
, mode
) != CODE_FOR_nothing
628 && CTZ_DEFINED_VALUE_AT_ZERO (mode
, zerov
) == 2)
630 // Handle only the two common values.
633 else if (zerov
== prec
)
636 // Magic value to give up, unless we can prove arg is non-zero.
640 // If arg is non-zero, then use [0, prec - 1].
641 if (!range_includes_zero_p (&lh
))
646 // If some high bits are known to be zero, we can decrease
648 wide_int max
= lh
.upper_bound ();
651 // Argument is [0, 0]. If CTZ_DEFINED_VALUE_AT_ZERO
652 // is 2 with value -1 or prec, return [-1, -1] or [prec, prec].
653 // Otherwise ignore the range.
656 else if (maxi
== prec
)
659 // If value at zero is prec and 0 is in the range, we can't lower
660 // the upper bound. We could create two separate ranges though,
661 // [0,floor_log2(max)][prec,prec] though.
662 else if (maxi
!= prec
)
663 maxi
= wi::floor_log2 (max
);
667 r
.set (build_int_cst (type
, mini
), build_int_cst (type
, maxi
));
672 // Implement range operator for CFN_BUILT_IN_
673 class cfn_clrsb
: public range_operator
676 using range_operator::fold_range
;
677 virtual bool fold_range (irange
&r
, tree type
, const irange
&lh
,
678 const irange
&, relation_trio
) const
680 if (lh
.undefined_p ())
682 int prec
= TYPE_PRECISION (lh
.type ());
683 r
.set (build_int_cst (type
, 0), build_int_cst (type
, prec
- 1));
689 // Implement range operator for CFN_BUILT_IN_
690 class cfn_ubsan
: public range_operator
693 cfn_ubsan (enum tree_code code
) { m_code
= code
; }
694 using range_operator::fold_range
;
695 virtual bool fold_range (irange
&r
, tree type
, const irange
&lh
,
696 const irange
&rh
, relation_trio rel
) const
698 range_op_handler
handler (m_code
, type
);
699 gcc_checking_assert (handler
);
701 bool saved_flag_wrapv
= flag_wrapv
;
702 // Pretend the arithmetic is wrapping. If there is any overflow,
703 // we'll complain, but will actually do wrapping operation.
705 bool result
= handler
.fold_range (r
, type
, lh
, rh
, rel
);
706 flag_wrapv
= saved_flag_wrapv
;
708 // If for both arguments vrp_valueize returned non-NULL, this should
709 // have been already folded and if not, it wasn't folded because of
710 // overflow. Avoid removing the UBSAN_CHECK_* calls in that case.
711 if (result
&& r
.singleton_p ())
712 r
.set_varying (type
);
716 enum tree_code m_code
;
719 cfn_ubsan
op_cfn_ubsan_add (PLUS_EXPR
);
720 cfn_ubsan
op_cfn_ubsan_sub (MINUS_EXPR
);
721 cfn_ubsan
op_cfn_ubsan_mul (MULT_EXPR
);
724 // Implement range operator for CFN_BUILT_IN_STRLEN
725 class cfn_strlen
: public range_operator
728 using range_operator::fold_range
;
729 virtual bool fold_range (irange
&r
, tree type
, const irange
&,
730 const irange
&, relation_trio
) const
732 tree max
= vrp_val_max (ptrdiff_type_node
);
734 = wi::to_wide (max
, TYPE_PRECISION (TREE_TYPE (max
)));
735 tree range_min
= build_zero_cst (type
);
736 // To account for the terminating NULL, the maximum length
737 // is one less than the maximum array size, which in turn
738 // is one less than PTRDIFF_MAX (or SIZE_MAX where it's
739 // smaller than the former type).
740 // FIXME: Use max_object_size() - 1 here.
741 tree range_max
= wide_int_to_tree (type
, wmax
- 2);
742 r
.set (range_min
, range_max
);
748 // Implement range operator for CFN_BUILT_IN_GOACC_DIM
749 class cfn_goacc_dim
: public range_operator
752 cfn_goacc_dim (bool is_pos
) { m_is_pos
= is_pos
; }
753 using range_operator::fold_range
;
754 virtual bool fold_range (irange
&r
, tree type
, const irange
&lh
,
755 const irange
&, relation_trio
) const
758 if (!lh
.singleton_p (&axis_tree
))
760 HOST_WIDE_INT axis
= TREE_INT_CST_LOW (axis_tree
);
761 int size
= oacc_get_fn_dim_size (current_function_decl
, axis
);
763 // If it's dynamic, the backend might know a hardware limitation.
764 size
= targetm
.goacc
.dim_limit (axis
);
766 r
.set (build_int_cst (type
, m_is_pos
? 0 : 1),
768 ? build_int_cst (type
, size
- m_is_pos
) : vrp_val_max (type
));
773 } op_cfn_goacc_dim_size (false), op_cfn_goacc_dim_pos (true);
776 // Implement range operator for CFN_BUILT_IN_
777 class cfn_parity
: public range_operator
780 using range_operator::fold_range
;
781 virtual bool fold_range (irange
&r
, tree type
, const irange
&,
782 const irange
&, relation_trio
) const
784 r
.set (build_zero_cst (type
), build_one_cst (type
));
789 // Set up a gimple_range_op_handler for any nonstandard function which can be
790 // supported via range-ops.
793 gimple_range_op_handler::maybe_non_standard ()
795 range_operator
*signed_op
= ptr_op_widen_mult_signed
;
796 range_operator
*unsigned_op
= ptr_op_widen_mult_unsigned
;
797 if (gimple_code (m_stmt
) == GIMPLE_ASSIGN
)
798 switch (gimple_assign_rhs_code (m_stmt
))
800 case WIDEN_PLUS_EXPR
:
802 signed_op
= ptr_op_widen_plus_signed
;
803 unsigned_op
= ptr_op_widen_plus_unsigned
;
806 case WIDEN_MULT_EXPR
:
809 m_op1
= gimple_assign_rhs1 (m_stmt
);
810 m_op2
= gimple_assign_rhs2 (m_stmt
);
811 tree ret
= gimple_assign_lhs (m_stmt
);
812 bool signed1
= TYPE_SIGN (TREE_TYPE (m_op1
)) == SIGNED
;
813 bool signed2
= TYPE_SIGN (TREE_TYPE (m_op2
)) == SIGNED
;
814 bool signed_ret
= TYPE_SIGN (TREE_TYPE (ret
)) == SIGNED
;
816 /* Normally these operands should all have the same sign, but
817 some passes and violate this by taking mismatched sign args. At
818 the moment the only one that's possible is mismatch inputs and
819 unsigned output. Once ranger supports signs for the operands we
820 can properly fix it, for now only accept the case we can do
822 if ((signed1
^ signed2
) && signed_ret
)
826 if (signed2
&& !signed1
)
827 std::swap (m_op1
, m_op2
);
829 if (signed1
|| signed2
)
840 // Set up a gimple_range_op_handler for any built in function which can be
841 // supported via range-ops.
844 gimple_range_op_handler::maybe_builtin_call ()
846 gcc_checking_assert (is_a
<gcall
*> (m_stmt
));
848 gcall
*call
= as_a
<gcall
*> (m_stmt
);
849 combined_fn func
= gimple_call_combined_fn (call
);
850 if (func
== CFN_LAST
)
852 tree type
= gimple_range_type (call
);
853 gcc_checking_assert (type
);
854 if (!Value_Range::supports_type_p (type
))
859 case CFN_BUILT_IN_CONSTANT_P
:
860 m_op1
= gimple_call_arg (call
, 0);
862 if (irange::supports_p (TREE_TYPE (m_op1
)))
863 m_int
= &op_cfn_constant_p
;
864 else if (frange::supports_p (TREE_TYPE (m_op1
)))
865 m_float
= &op_cfn_constant_float_p
;
870 CASE_FLT_FN (CFN_BUILT_IN_SIGNBIT
):
871 m_op1
= gimple_call_arg (call
, 0);
872 m_float
= &op_cfn_signbit
;
876 CASE_CFN_COPYSIGN_ALL
:
877 m_op1
= gimple_call_arg (call
, 0);
878 m_op2
= gimple_call_arg (call
, 1);
879 m_float
= &op_cfn_copysign
;
883 case CFN_BUILT_IN_TOUPPER
:
884 case CFN_BUILT_IN_TOLOWER
:
885 // Only proceed If the argument is compatible with the LHS.
886 m_op1
= gimple_call_arg (call
, 0);
887 if (range_compatible_p (type
, TREE_TYPE (m_op1
)))
890 m_int
= (func
== CFN_BUILT_IN_TOLOWER
) ? &op_cfn_tolower
896 m_op1
= gimple_call_arg (call
, 0);
902 m_op1
= gimple_call_arg (call
, 0);
903 m_int
= &op_cfn_popcount
;
908 m_op1
= gimple_call_arg (call
, 0);
910 if (gimple_call_internal_p (call
))
911 m_int
= &op_cfn_clz_internal
;
917 m_op1
= gimple_call_arg (call
, 0);
919 if (gimple_call_internal_p (call
))
920 m_int
= &op_cfn_ctz_internal
;
926 m_op1
= gimple_call_arg (call
, 0);
928 m_int
= &op_cfn_clrsb
;
931 case CFN_UBSAN_CHECK_ADD
:
932 m_op1
= gimple_call_arg (call
, 0);
933 m_op2
= gimple_call_arg (call
, 1);
935 m_int
= &op_cfn_ubsan_add
;
938 case CFN_UBSAN_CHECK_SUB
:
939 m_op1
= gimple_call_arg (call
, 0);
940 m_op2
= gimple_call_arg (call
, 1);
942 m_int
= &op_cfn_ubsan_sub
;
945 case CFN_UBSAN_CHECK_MUL
:
946 m_op1
= gimple_call_arg (call
, 0);
947 m_op2
= gimple_call_arg (call
, 1);
949 m_int
= &op_cfn_ubsan_mul
;
952 case CFN_BUILT_IN_STRLEN
:
954 tree lhs
= gimple_call_lhs (call
);
955 if (lhs
&& ptrdiff_type_node
&& (TYPE_PRECISION (ptrdiff_type_node
)
956 == TYPE_PRECISION (TREE_TYPE (lhs
))))
958 m_op1
= gimple_call_arg (call
, 0);
960 m_int
= &op_cfn_strlen
;
965 // Optimizing these two internal functions helps the loop
966 // optimizer eliminate outer comparisons. Size is [1,N]
967 // and pos is [0,N-1].
968 case CFN_GOACC_DIM_SIZE
:
969 // This call will ensure all the asserts are triggered.
970 oacc_get_ifn_dim_arg (call
);
971 m_op1
= gimple_call_arg (call
, 0);
973 m_int
= &op_cfn_goacc_dim_size
;
976 case CFN_GOACC_DIM_POS
:
977 // This call will ensure all the asserts are triggered.
978 oacc_get_ifn_dim_arg (call
);
979 m_op1
= gimple_call_arg (call
, 0);
981 m_int
= &op_cfn_goacc_dim_pos
;
986 m_int
= &op_cfn_parity
;
989 case CFN_BUILT_IN_EXPECT
:
990 case CFN_BUILT_IN_EXPECT_WITH_PROBABILITY
:
992 m_op1
= gimple_call_arg (call
, 0);
993 m_int
= &op_cfn_pass_through_arg1
;