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 ();
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.
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 ())
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.
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 ())
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)
227 // This is sometimes invoked on single operand stmts.
229 op2_type
= TREE_TYPE (operand2 ());
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.
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 ())
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
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
));
279 if (cfun
->after_inlining
)
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
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
));
301 if (cfun
->after_inlining
)
310 // Implement range operator for CFN_BUILT_IN_SIGNBIT.
311 class cfn_signbit
: public range_operator_float
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
320 if (lh
.signbit_p (signbit
))
323 r
.set_nonzero (type
);
330 virtual bool op1_range (frange
&r
, tree type
, const irange
&lhs
,
331 const frange
&, relation_trio
) const override
335 r
.set (type
, dconst0
, frange_val_max (type
));
336 r
.update_nan (false);
339 if (!lhs
.contains_p (build_zero_cst (lhs
.type ())))
341 REAL_VALUE_TYPE dconstm0
= dconst0
;
343 r
.set (type
, frange_val_min (type
), dconstm0
);
351 // Implement range operator for CFN_BUILT_IN_COPYSIGN
352 class cfn_copysign
: public range_operator_float
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
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
)))
364 if (!neg_op
|| !neg_op
.fold_range (neg
, type
, r
, frange (type
)))
368 if (rh
.signbit_p (signbit
))
370 // If the sign is negative, flip the result from ABS,
371 // otherwise leave things positive.
376 // If the sign is unknown, keep the positive and negative
383 // Implement range operator for CFN_BUILT_IN_TOUPPER and CFN_BUILT_IN_TOLOWER.
384 class cfn_toupper_tolower
: public range_operator
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;
392 bool get_letter_range (tree type
, irange
&lowers
, irange
&uppers
) const;
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.
400 cfn_toupper_tolower::get_letter_range (tree type
, irange
&lowers
,
401 irange
&uppers
) const
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
));
415 // Unknown character set.
420 cfn_toupper_tolower::fold_range (irange
&r
, tree type
, const irange
&lh
,
421 const irange
&, relation_trio
) const
425 if (!get_letter_range (type
, lowers
, uppers
))
431 // Return the range passed in without any lower case characters,
432 // but including all the upper case ones.
434 r
.intersect (lowers
);
439 // Return the range passed in without any lower case characters,
440 // but including all the upper case ones.
442 r
.intersect (uppers
);
448 // Implement range operator for CFN_BUILT_IN_FFS.
449 class cfn_ffs
: public range_operator
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 ())
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;
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
));
475 // Implement range operator for CFN_BUILT_IN_POPCOUNT.
476 class cfn_popcount
: public cfn_ffs
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 ())
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
);
494 if (cfn_ffs::fold_range (r
, type
, lh
, rh
, rel
))
496 int_range
<2> tmp (type
, wi::zero (prec
), pop
);
504 // Implement range operator for CFN_BUILT_IN_CLZ
505 class cfn_clz
: public range_operator
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;
513 bool m_gimple_call_internal_p
;
514 } op_cfn_clz (false), op_cfn_clz_internal (true);
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 ())
527 int prec
= TYPE_PRECISION (lh
.type ());
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.
541 // Magic value to give up, unless we can prove arg is non-zero.
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 ());
553 else if (!range_includes_zero_p (&lh
))
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
);
565 // If CLZ_DEFINED_VALUE_AT_ZERO is 2 with VALUE of prec,
566 // return [prec, prec], otherwise ignore the range.
575 r
.set (build_int_cst (type
, mini
), build_int_cst (type
, maxi
));
579 // Implement range operator for CFN_BUILT_IN_CTZ
580 class cfn_ctz
: public range_operator
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;
588 bool m_gimple_call_internal_p
;
589 } op_cfn_ctz (false), op_cfn_ctz_internal (true);
592 cfn_ctz::fold_range (irange
&r
, tree type
, const irange
&lh
,
593 const irange
&, relation_trio
) const
595 if (lh
.undefined_p ())
597 int prec
= TYPE_PRECISION (lh
.type ());
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.
611 else if (zerov
== prec
)
614 // Magic value to give up, unless we can prove arg is non-zero.
618 // If arg is non-zero, then use [0, prec - 1].
619 if (!range_includes_zero_p (&lh
))
624 // If some high bits are known to be zero, we can decrease
626 wide_int max
= lh
.upper_bound ();
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.
634 else if (maxi
== 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
);
645 r
.set (build_int_cst (type
, mini
), build_int_cst (type
, maxi
));
650 // Implement range operator for CFN_BUILT_IN_
651 class cfn_clrsb
: public range_operator
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 ())
660 int prec
= TYPE_PRECISION (lh
.type ());
661 r
.set (build_int_cst (type
, 0), build_int_cst (type
, prec
- 1));
667 // Implement range operator for CFN_BUILT_IN_
668 class cfn_ubsan
: public range_operator
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.
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
);
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
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
);
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
);
726 // Implement range operator for CFN_BUILT_IN_GOACC_DIM
727 class cfn_goacc_dim
: public range_operator
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
736 if (!lh
.singleton_p (&axis_tree
))
738 HOST_WIDE_INT axis
= TREE_INT_CST_LOW (axis_tree
);
739 int size
= oacc_get_fn_dim_size (current_function_decl
, axis
);
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),
746 ? build_int_cst (type
, size
- m_is_pos
) : vrp_val_max (type
));
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
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
));
767 // Set up a gimple_range_op_handler for any built in function which can be
768 // supported via range-ops.
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
)
779 tree type
= gimple_range_type (call
);
780 gcc_checking_assert (type
);
781 if (!Value_Range::supports_type_p (type
))
786 case CFN_BUILT_IN_CONSTANT_P
:
787 m_op1
= gimple_call_arg (call
, 0);
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
;
797 CASE_FLT_FN (CFN_BUILT_IN_SIGNBIT
):
798 m_op1
= gimple_call_arg (call
, 0);
799 m_float
= &op_cfn_signbit
;
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
;
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
)))
817 m_int
= (func
== CFN_BUILT_IN_TOLOWER
) ? &op_cfn_tolower
823 m_op1
= gimple_call_arg (call
, 0);
829 m_op1
= gimple_call_arg (call
, 0);
830 m_int
= &op_cfn_popcount
;
835 m_op1
= gimple_call_arg (call
, 0);
837 if (gimple_call_internal_p (call
))
838 m_int
= &op_cfn_clz_internal
;
844 m_op1
= gimple_call_arg (call
, 0);
846 if (gimple_call_internal_p (call
))
847 m_int
= &op_cfn_ctz_internal
;
853 m_op1
= gimple_call_arg (call
, 0);
855 m_int
= &op_cfn_clrsb
;
858 case CFN_UBSAN_CHECK_ADD
:
859 m_op1
= gimple_call_arg (call
, 0);
860 m_op2
= gimple_call_arg (call
, 1);
862 m_int
= &op_cfn_ubsan_add
;
865 case CFN_UBSAN_CHECK_SUB
:
866 m_op1
= gimple_call_arg (call
, 0);
867 m_op2
= gimple_call_arg (call
, 1);
869 m_int
= &op_cfn_ubsan_sub
;
872 case CFN_UBSAN_CHECK_MUL
:
873 m_op1
= gimple_call_arg (call
, 0);
874 m_op2
= gimple_call_arg (call
, 1);
876 m_int
= &op_cfn_ubsan_mul
;
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);
887 m_int
= &op_cfn_strlen
;
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);
900 m_int
= &op_cfn_goacc_dim_size
;
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);
908 m_int
= &op_cfn_goacc_dim_pos
;
913 m_int
= &op_cfn_parity
;