1 /* Code for GIMPLE range op related routines.
2 Copyright (C) 2019-2022 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
);
153 m_op1
= gimple_range_base_of_assignment (m_stmt
);
154 if (m_op1
&& TREE_CODE (m_op1
) == MEM_REF
)
156 // If the base address is an SSA_NAME, we return it
157 // here. This allows processing of the range of that
158 // name, while the rest of the expression is simply
159 // ignored. The code in range_ops will see the
160 // ADDR_EXPR and do the right thing.
161 tree ssa
= TREE_OPERAND (m_op1
, 0);
162 if (TREE_CODE (ssa
) == SSA_NAME
)
165 if (gimple_num_ops (m_stmt
) >= 3)
166 m_op2
= gimple_assign_rhs2 (m_stmt
);
172 // If no range-op table entry handled this stmt, check for other supported
174 if (is_a
<gcall
*> (m_stmt
))
175 maybe_builtin_call ();
178 // Calculate what we can determine of the range of this unary
179 // statement's operand if the lhs of the expression has the range
180 // LHS_RANGE. Return false if nothing can be determined.
183 gimple_range_op_handler::calc_op1 (vrange
&r
, const vrange
&lhs_range
)
185 gcc_checking_assert (gimple_num_ops (m_stmt
) < 3);
186 // Give up on empty ranges.
187 if (lhs_range
.undefined_p ())
190 // Unary operations require the type of the first operand in the
191 // second range position.
192 tree type
= TREE_TYPE (operand1 ());
193 Value_Range
type_range (type
);
194 type_range
.set_varying (type
);
195 return op1_range (r
, type
, lhs_range
, type_range
);
198 // Calculate what we can determine of the range of this statement's
199 // first operand if the lhs of the expression has the range LHS_RANGE
200 // and the second operand has the range OP2_RANGE. Return false if
201 // nothing can be determined.
204 gimple_range_op_handler::calc_op1 (vrange
&r
, const vrange
&lhs_range
,
205 const vrange
&op2_range
, relation_trio k
)
207 // Give up on empty ranges.
208 if (lhs_range
.undefined_p ())
211 // Unary operation are allowed to pass a range in for second operand
212 // as there are often additional restrictions beyond the type which
213 // can be imposed. See operator_cast::op1_range().
214 tree type
= TREE_TYPE (operand1 ());
215 // If op2 is undefined, solve as if it is varying.
216 if (op2_range
.undefined_p ())
218 if (gimple_num_ops (m_stmt
) < 3)
221 // This is sometimes invoked on single operand stmts.
223 op2_type
= TREE_TYPE (operand2 ());
225 op2_type
= TREE_TYPE (operand1 ());
226 Value_Range
trange (op2_type
);
227 trange
.set_varying (op2_type
);
228 return op1_range (r
, type
, lhs_range
, trange
, k
);
230 return op1_range (r
, type
, lhs_range
, op2_range
, k
);
233 // Calculate what we can determine of the range of this statement's
234 // second operand if the lhs of the expression has the range LHS_RANGE
235 // and the first operand has the range OP1_RANGE. Return false if
236 // nothing can be determined.
239 gimple_range_op_handler::calc_op2 (vrange
&r
, const vrange
&lhs_range
,
240 const vrange
&op1_range
, relation_trio k
)
242 // Give up on empty ranges.
243 if (lhs_range
.undefined_p ())
246 tree type
= TREE_TYPE (operand2 ());
247 // If op1 is undefined, solve as if it is varying.
248 if (op1_range
.undefined_p ())
250 tree op1_type
= TREE_TYPE (operand1 ());
251 Value_Range
trange (op1_type
);
252 trange
.set_varying (op1_type
);
253 return op2_range (r
, type
, lhs_range
, trange
, k
);
255 return op2_range (r
, type
, lhs_range
, op1_range
, k
);
258 // --------------------------------------------------------------------
260 // Implement range operator for float CFN_BUILT_IN_CONSTANT_P.
261 class cfn_constant_float_p
: public range_operator_float
264 using range_operator_float::fold_range
;
265 virtual bool fold_range (irange
&r
, tree type
, const frange
&lh
,
266 const irange
&, relation_trio
) const
268 if (lh
.singleton_p ())
270 r
.set (build_one_cst (type
), build_one_cst (type
));
273 if (cfun
->after_inlining
)
280 } op_cfn_constant_float_p
;
282 // Implement range operator for integral CFN_BUILT_IN_CONSTANT_P.
283 class cfn_constant_p
: public range_operator
286 using range_operator::fold_range
;
287 virtual bool fold_range (irange
&r
, tree type
, const irange
&lh
,
288 const irange
&, relation_trio
) const
290 if (lh
.singleton_p ())
292 r
.set (build_one_cst (type
), build_one_cst (type
));
295 if (cfun
->after_inlining
)
304 // Implement range operator for CFN_BUILT_IN_SIGNBIT.
305 class cfn_signbit
: public range_operator_float
308 using range_operator_float::fold_range
;
309 using range_operator_float::op1_range
;
310 virtual bool fold_range (irange
&r
, tree type
, const frange
&lh
,
311 const irange
&, relation_trio
) const override
314 if (lh
.signbit_p (signbit
))
317 r
.set_nonzero (type
);
324 virtual bool op1_range (frange
&r
, tree type
, const irange
&lhs
,
325 const frange
&, relation_trio
) const override
329 r
.set (type
, dconst0
, frange_val_max (type
));
330 r
.update_nan (false);
333 if (!lhs
.contains_p (build_zero_cst (lhs
.type ())))
335 REAL_VALUE_TYPE dconstm0
= dconst0
;
337 r
.set (type
, frange_val_min (type
), dconstm0
);
345 // Implement range operator for CFN_BUILT_IN_COPYSIGN
346 class cfn_copysign
: public range_operator_float
349 using range_operator_float::fold_range
;
350 virtual bool fold_range (frange
&r
, tree type
, const frange
&lh
,
351 const frange
&rh
, relation_trio
) const override
354 range_op_handler
abs_op (ABS_EXPR
, type
);
355 range_op_handler
neg_op (NEGATE_EXPR
, type
);
356 if (!abs_op
|| !abs_op
.fold_range (r
, type
, lh
, frange (type
)))
358 if (!neg_op
|| !neg_op
.fold_range (neg
, type
, r
, frange (type
)))
362 if (rh
.signbit_p (signbit
))
364 // If the sign is negative, flip the result from ABS,
365 // otherwise leave things positive.
370 // If the sign is unknown, keep the positive and negative
377 // Implement range operator for CFN_BUILT_IN_TOUPPER and CFN_BUILT_IN_TOLOWER.
378 class cfn_toupper_tolower
: public range_operator
381 using range_operator::fold_range
;
382 cfn_toupper_tolower (bool toupper
) { m_toupper
= toupper
; }
383 virtual bool fold_range (irange
&r
, tree type
, const irange
&lh
,
384 const irange
&, relation_trio
) const;
386 bool get_letter_range (tree type
, irange
&lowers
, irange
&uppers
) const;
388 } op_cfn_toupper (true), op_cfn_tolower (false);
390 // Return TRUE if we recognize the target character set and return the
391 // range for lower case and upper case letters.
394 cfn_toupper_tolower::get_letter_range (tree type
, irange
&lowers
,
395 irange
&uppers
) const
398 int a
= lang_hooks
.to_target_charset ('a');
399 int z
= lang_hooks
.to_target_charset ('z');
400 int A
= lang_hooks
.to_target_charset ('A');
401 int Z
= lang_hooks
.to_target_charset ('Z');
403 if ((z
- a
== 25) && (Z
- A
== 25))
405 lowers
= int_range
<2> (build_int_cst (type
, a
), build_int_cst (type
, z
));
406 uppers
= int_range
<2> (build_int_cst (type
, A
), build_int_cst (type
, Z
));
409 // Unknown character set.
414 cfn_toupper_tolower::fold_range (irange
&r
, tree type
, const irange
&lh
,
415 const irange
&, relation_trio
) const
419 if (!get_letter_range (type
, lowers
, uppers
))
425 // Return the range passed in without any lower case characters,
426 // but including all the upper case ones.
428 r
.intersect (lowers
);
433 // Return the range passed in without any lower case characters,
434 // but including all the upper case ones.
436 r
.intersect (uppers
);
442 // Implement range operator for CFN_BUILT_IN_FFS.
443 class cfn_ffs
: public range_operator
446 using range_operator::fold_range
;
447 virtual bool fold_range (irange
&r
, tree type
, const irange
&lh
,
448 const irange
&, relation_trio
) const
450 if (lh
.undefined_p ())
452 // __builtin_ffs* and __builtin_popcount* return [0, prec].
453 int prec
= TYPE_PRECISION (lh
.type ());
454 // If arg is non-zero, then ffs or popcount are non-zero.
455 int mini
= range_includes_zero_p (&lh
) ? 0 : 1;
458 // If some high bits are known to be zero, decrease the maximum.
459 int_range_max tmp
= lh
;
460 if (TYPE_SIGN (tmp
.type ()) == SIGNED
)
461 range_cast (tmp
, unsigned_type_for (tmp
.type ()));
462 wide_int max
= tmp
.upper_bound ();
463 maxi
= wi::floor_log2 (max
) + 1;
464 r
.set (build_int_cst (type
, mini
), build_int_cst (type
, maxi
));
469 // Implement range operator for CFN_BUILT_IN_POPCOUNT.
470 class cfn_popcount
: public cfn_ffs
473 using range_operator::fold_range
;
474 virtual bool fold_range (irange
&r
, tree type
, const irange
&lh
,
475 const irange
&rh
, relation_trio rel
) const
477 if (lh
.undefined_p ())
479 unsigned prec
= TYPE_PRECISION (type
);
480 wide_int nz
= lh
.get_nonzero_bits ();
481 wide_int pop
= wi::shwi (wi::popcount (nz
), prec
);
482 // Calculating the popcount of a singleton is trivial.
483 if (lh
.singleton_p ())
485 r
.set (type
, pop
, pop
);
488 if (cfn_ffs::fold_range (r
, type
, lh
, rh
, rel
))
490 int_range
<2> tmp (type
, wi::zero (prec
), pop
);
498 // Implement range operator for CFN_BUILT_IN_CLZ
499 class cfn_clz
: public range_operator
502 cfn_clz (bool internal
) { m_gimple_call_internal_p
= internal
; }
503 using range_operator::fold_range
;
504 virtual bool fold_range (irange
&r
, tree type
, const irange
&lh
,
505 const irange
&, relation_trio
) const;
507 bool m_gimple_call_internal_p
;
508 } op_cfn_clz (false), op_cfn_clz_internal (true);
511 cfn_clz::fold_range (irange
&r
, tree type
, const irange
&lh
,
512 const irange
&, relation_trio
) const
514 // __builtin_c[lt]z* return [0, prec-1], except when the
515 // argument is 0, but that is undefined behavior.
517 // For __builtin_c[lt]z* consider argument of 0 always undefined
518 // behavior, for internal fns depending on C?Z_DEFINED_ALUE_AT_ZERO.
519 if (lh
.undefined_p ())
521 int prec
= TYPE_PRECISION (lh
.type ());
525 scalar_int_mode mode
= SCALAR_INT_TYPE_MODE (lh
.type ());
526 if (m_gimple_call_internal_p
)
528 if (optab_handler (clz_optab
, mode
) != CODE_FOR_nothing
529 && CLZ_DEFINED_VALUE_AT_ZERO (mode
, zerov
) == 2)
531 // Only handle the single common value.
535 // Magic value to give up, unless we can prove arg is non-zero.
540 // From clz of minimum we can compute result maximum.
541 if (wi::gt_p (lh
.lower_bound (), 0, TYPE_SIGN (lh
.type ())))
543 maxi
= prec
- 1 - wi::floor_log2 (lh
.lower_bound ());
547 else if (!range_includes_zero_p (&lh
))
554 // From clz of maximum we can compute result minimum.
555 wide_int max
= lh
.upper_bound ();
556 int newmini
= prec
- 1 - wi::floor_log2 (max
);
559 // If CLZ_DEFINED_VALUE_AT_ZERO is 2 with VALUE of prec,
560 // return [prec, prec], otherwise ignore the range.
569 r
.set (build_int_cst (type
, mini
), build_int_cst (type
, maxi
));
573 // Implement range operator for CFN_BUILT_IN_CTZ
574 class cfn_ctz
: public range_operator
577 cfn_ctz (bool internal
) { m_gimple_call_internal_p
= internal
; }
578 using range_operator::fold_range
;
579 virtual bool fold_range (irange
&r
, tree type
, const irange
&lh
,
580 const irange
&, relation_trio
) const;
582 bool m_gimple_call_internal_p
;
583 } op_cfn_ctz (false), op_cfn_ctz_internal (true);
586 cfn_ctz::fold_range (irange
&r
, tree type
, const irange
&lh
,
587 const irange
&, relation_trio
) const
589 if (lh
.undefined_p ())
591 int prec
= TYPE_PRECISION (lh
.type ());
595 scalar_int_mode mode
= SCALAR_INT_TYPE_MODE (lh
.type ());
597 if (m_gimple_call_internal_p
)
599 if (optab_handler (ctz_optab
, mode
) != CODE_FOR_nothing
600 && CTZ_DEFINED_VALUE_AT_ZERO (mode
, zerov
) == 2)
602 // Handle only the two common values.
605 else if (zerov
== prec
)
608 // Magic value to give up, unless we can prove arg is non-zero.
612 // If arg is non-zero, then use [0, prec - 1].
613 if (!range_includes_zero_p (&lh
))
618 // If some high bits are known to be zero, we can decrease
620 wide_int max
= lh
.upper_bound ();
623 // Argument is [0, 0]. If CTZ_DEFINED_VALUE_AT_ZERO
624 // is 2 with value -1 or prec, return [-1, -1] or [prec, prec].
625 // Otherwise ignore the range.
628 else if (maxi
== prec
)
631 // If value at zero is prec and 0 is in the range, we can't lower
632 // the upper bound. We could create two separate ranges though,
633 // [0,floor_log2(max)][prec,prec] though.
634 else if (maxi
!= prec
)
635 maxi
= wi::floor_log2 (max
);
639 r
.set (build_int_cst (type
, mini
), build_int_cst (type
, maxi
));
644 // Implement range operator for CFN_BUILT_IN_
645 class cfn_clrsb
: public range_operator
648 using range_operator::fold_range
;
649 virtual bool fold_range (irange
&r
, tree type
, const irange
&lh
,
650 const irange
&, relation_trio
) const
652 if (lh
.undefined_p ())
654 int prec
= TYPE_PRECISION (lh
.type ());
655 r
.set (build_int_cst (type
, 0), build_int_cst (type
, prec
- 1));
661 // Implement range operator for CFN_BUILT_IN_
662 class cfn_ubsan
: public range_operator
665 cfn_ubsan (enum tree_code code
) { m_code
= code
; }
666 using range_operator::fold_range
;
667 virtual bool fold_range (irange
&r
, tree type
, const irange
&lh
,
668 const irange
&rh
, relation_trio rel
) const
670 range_op_handler
handler (m_code
, type
);
671 gcc_checking_assert (handler
);
673 bool saved_flag_wrapv
= flag_wrapv
;
674 // Pretend the arithmetic is wrapping. If there is any overflow,
675 // we'll complain, but will actually do wrapping operation.
677 bool result
= handler
.fold_range (r
, type
, lh
, rh
, rel
);
678 flag_wrapv
= saved_flag_wrapv
;
680 // If for both arguments vrp_valueize returned non-NULL, this should
681 // have been already folded and if not, it wasn't folded because of
682 // overflow. Avoid removing the UBSAN_CHECK_* calls in that case.
683 if (result
&& r
.singleton_p ())
684 r
.set_varying (type
);
688 enum tree_code m_code
;
691 cfn_ubsan
op_cfn_ubsan_add (PLUS_EXPR
);
692 cfn_ubsan
op_cfn_ubsan_sub (MINUS_EXPR
);
693 cfn_ubsan
op_cfn_ubsan_mul (MULT_EXPR
);
696 // Implement range operator for CFN_BUILT_IN_STRLEN
697 class cfn_strlen
: public range_operator
700 using range_operator::fold_range
;
701 virtual bool fold_range (irange
&r
, tree type
, const irange
&,
702 const irange
&, relation_trio
) const
704 tree max
= vrp_val_max (ptrdiff_type_node
);
706 = wi::to_wide (max
, TYPE_PRECISION (TREE_TYPE (max
)));
707 tree range_min
= build_zero_cst (type
);
708 // To account for the terminating NULL, the maximum length
709 // is one less than the maximum array size, which in turn
710 // is one less than PTRDIFF_MAX (or SIZE_MAX where it's
711 // smaller than the former type).
712 // FIXME: Use max_object_size() - 1 here.
713 tree range_max
= wide_int_to_tree (type
, wmax
- 2);
714 r
.set (range_min
, range_max
);
720 // Implement range operator for CFN_BUILT_IN_GOACC_DIM
721 class cfn_goacc_dim
: public range_operator
724 cfn_goacc_dim (bool is_pos
) { m_is_pos
= is_pos
; }
725 using range_operator::fold_range
;
726 virtual bool fold_range (irange
&r
, tree type
, const irange
&lh
,
727 const irange
&, relation_trio
) const
730 if (!lh
.singleton_p (&axis_tree
))
732 HOST_WIDE_INT axis
= TREE_INT_CST_LOW (axis_tree
);
733 int size
= oacc_get_fn_dim_size (current_function_decl
, axis
);
735 // If it's dynamic, the backend might know a hardware limitation.
736 size
= targetm
.goacc
.dim_limit (axis
);
738 r
.set (build_int_cst (type
, m_is_pos
? 0 : 1),
740 ? build_int_cst (type
, size
- m_is_pos
) : vrp_val_max (type
));
745 } op_cfn_goacc_dim_size (false), op_cfn_goacc_dim_pos (true);
748 // Implement range operator for CFN_BUILT_IN_
749 class cfn_parity
: public range_operator
752 using range_operator::fold_range
;
753 virtual bool fold_range (irange
&r
, tree type
, const irange
&,
754 const irange
&, relation_trio
) const
756 r
.set (build_zero_cst (type
), build_one_cst (type
));
761 // Set up a gimple_range_op_handler for any built in function which can be
762 // supported via range-ops.
765 gimple_range_op_handler::maybe_builtin_call ()
767 gcc_checking_assert (is_a
<gcall
*> (m_stmt
));
769 gcall
*call
= as_a
<gcall
*> (m_stmt
);
770 combined_fn func
= gimple_call_combined_fn (call
);
771 if (func
== CFN_LAST
)
773 tree type
= gimple_range_type (call
);
774 gcc_checking_assert (type
);
775 if (!Value_Range::supports_type_p (type
))
780 case CFN_BUILT_IN_CONSTANT_P
:
781 m_op1
= gimple_call_arg (call
, 0);
783 if (irange::supports_p (TREE_TYPE (m_op1
)))
784 m_int
= &op_cfn_constant_p
;
785 else if (frange::supports_p (TREE_TYPE (m_op1
)))
786 m_float
= &op_cfn_constant_float_p
;
791 CASE_FLT_FN (CFN_BUILT_IN_SIGNBIT
):
792 m_op1
= gimple_call_arg (call
, 0);
793 m_float
= &op_cfn_signbit
;
797 CASE_CFN_COPYSIGN_ALL
:
798 m_op1
= gimple_call_arg (call
, 0);
799 m_op2
= gimple_call_arg (call
, 1);
800 m_float
= &op_cfn_copysign
;
804 case CFN_BUILT_IN_TOUPPER
:
805 case CFN_BUILT_IN_TOLOWER
:
806 // Only proceed If the argument is compatible with the LHS.
807 m_op1
= gimple_call_arg (call
, 0);
808 if (range_compatible_p (type
, TREE_TYPE (m_op1
)))
811 m_int
= (func
== CFN_BUILT_IN_TOLOWER
) ? &op_cfn_tolower
817 m_op1
= gimple_call_arg (call
, 0);
823 m_op1
= gimple_call_arg (call
, 0);
824 m_int
= &op_cfn_popcount
;
829 m_op1
= gimple_call_arg (call
, 0);
831 if (gimple_call_internal_p (call
))
832 m_int
= &op_cfn_clz_internal
;
838 m_op1
= gimple_call_arg (call
, 0);
840 if (gimple_call_internal_p (call
))
841 m_int
= &op_cfn_ctz_internal
;
847 m_op1
= gimple_call_arg (call
, 0);
849 m_int
= &op_cfn_clrsb
;
852 case CFN_UBSAN_CHECK_ADD
:
853 m_op1
= gimple_call_arg (call
, 0);
854 m_op2
= gimple_call_arg (call
, 1);
856 m_int
= &op_cfn_ubsan_add
;
859 case CFN_UBSAN_CHECK_SUB
:
860 m_op1
= gimple_call_arg (call
, 0);
861 m_op2
= gimple_call_arg (call
, 1);
863 m_int
= &op_cfn_ubsan_sub
;
866 case CFN_UBSAN_CHECK_MUL
:
867 m_op1
= gimple_call_arg (call
, 0);
868 m_op2
= gimple_call_arg (call
, 1);
870 m_int
= &op_cfn_ubsan_mul
;
873 case CFN_BUILT_IN_STRLEN
:
875 tree lhs
= gimple_call_lhs (call
);
876 if (lhs
&& ptrdiff_type_node
&& (TYPE_PRECISION (ptrdiff_type_node
)
877 == TYPE_PRECISION (TREE_TYPE (lhs
))))
879 m_op1
= gimple_call_arg (call
, 0);
881 m_int
= &op_cfn_strlen
;
886 // Optimizing these two internal functions helps the loop
887 // optimizer eliminate outer comparisons. Size is [1,N]
888 // and pos is [0,N-1].
889 case CFN_GOACC_DIM_SIZE
:
890 // This call will ensure all the asserts are triggered.
891 oacc_get_ifn_dim_arg (call
);
892 m_op1
= gimple_call_arg (call
, 0);
894 m_int
= &op_cfn_goacc_dim_size
;
897 case CFN_GOACC_DIM_POS
:
898 // This call will ensure all the asserts are triggered.
899 oacc_get_ifn_dim_arg (call
);
900 m_op1
= gimple_call_arg (call
, 0);
902 m_int
= &op_cfn_goacc_dim_pos
;
907 m_int
= &op_cfn_parity
;