2 Copyright (C) 2011-2017 Free Software Foundation, Inc.
4 This file is part of GCC.
6 GCC is free software; you can redistribute it and/or modify it under
7 the terms of the GNU General Public License as published by the Free
8 Software Foundation; either version 3, or (at your option) any later
11 GCC is distributed in the hope that it will be useful, but WITHOUT ANY
12 WARRANTY; without even the implied warranty of MERCHANTABILITY or
13 FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License
16 You should have received a copy of the GNU General Public License
17 along with GCC; see the file COPYING3. If not see
18 <http://www.gnu.org/licenses/>. */
22 #include "coretypes.h"
29 #include "stringpool.h"
31 #include "tree-ssanames.h"
36 #include "diagnostic-core.h"
37 #include "fold-const.h"
38 #include "internal-fn.h"
39 #include "stor-layout.h"
45 #include "optabs-tree.h"
47 /* The names of each internal function, indexed by function number. */
48 const char *const internal_fn_name_array
[] = {
49 #define DEF_INTERNAL_FN(CODE, FLAGS, FNSPEC) #CODE,
50 #include "internal-fn.def"
54 /* The ECF_* flags of each internal function, indexed by function number. */
55 const int internal_fn_flags_array
[] = {
56 #define DEF_INTERNAL_FN(CODE, FLAGS, FNSPEC) FLAGS,
57 #include "internal-fn.def"
61 /* Fnspec of each internal function, indexed by function number. */
62 const_tree internal_fn_fnspec_array
[IFN_LAST
+ 1];
67 #define DEF_INTERNAL_FN(CODE, FLAGS, FNSPEC) \
68 if (FNSPEC) internal_fn_fnspec_array[IFN_##CODE] = \
69 build_string ((int) sizeof (FNSPEC), FNSPEC ? FNSPEC : "");
70 #include "internal-fn.def"
71 internal_fn_fnspec_array
[IFN_LAST
] = 0;
74 /* Create static initializers for the information returned by
75 direct_internal_fn. */
76 #define not_direct { -2, -2, false }
77 #define mask_load_direct { -1, 2, false }
78 #define load_lanes_direct { -1, -1, false }
79 #define mask_store_direct { 3, 2, false }
80 #define store_lanes_direct { 0, 0, false }
81 #define unary_direct { 0, 0, true }
82 #define binary_direct { 0, 0, true }
84 const direct_internal_fn_info direct_internal_fn_array
[IFN_LAST
+ 1] = {
85 #define DEF_INTERNAL_FN(CODE, FLAGS, FNSPEC) not_direct,
86 #define DEF_INTERNAL_OPTAB_FN(CODE, FLAGS, OPTAB, TYPE) TYPE##_direct,
87 #include "internal-fn.def"
91 /* ARRAY_TYPE is an array of vector modes. Return the associated insn
92 for load-lanes-style optab OPTAB, or CODE_FOR_nothing if none. */
95 get_multi_vector_move (tree array_type
, convert_optab optab
)
100 gcc_assert (TREE_CODE (array_type
) == ARRAY_TYPE
);
101 imode
= TYPE_MODE (array_type
);
102 vmode
= TYPE_MODE (TREE_TYPE (array_type
));
104 return convert_optab_handler (optab
, imode
, vmode
);
107 /* Expand LOAD_LANES call STMT using optab OPTAB. */
110 expand_load_lanes_optab_fn (internal_fn
, gcall
*stmt
, convert_optab optab
)
112 struct expand_operand ops
[2];
116 lhs
= gimple_call_lhs (stmt
);
117 rhs
= gimple_call_arg (stmt
, 0);
118 type
= TREE_TYPE (lhs
);
120 target
= expand_expr (lhs
, NULL_RTX
, VOIDmode
, EXPAND_WRITE
);
121 mem
= expand_normal (rhs
);
123 gcc_assert (MEM_P (mem
));
124 PUT_MODE (mem
, TYPE_MODE (type
));
126 create_output_operand (&ops
[0], target
, TYPE_MODE (type
));
127 create_fixed_operand (&ops
[1], mem
);
128 expand_insn (get_multi_vector_move (type
, optab
), 2, ops
);
131 /* Expand STORE_LANES call STMT using optab OPTAB. */
134 expand_store_lanes_optab_fn (internal_fn
, gcall
*stmt
, convert_optab optab
)
136 struct expand_operand ops
[2];
140 lhs
= gimple_call_lhs (stmt
);
141 rhs
= gimple_call_arg (stmt
, 0);
142 type
= TREE_TYPE (rhs
);
144 target
= expand_expr (lhs
, NULL_RTX
, VOIDmode
, EXPAND_WRITE
);
145 reg
= expand_normal (rhs
);
147 gcc_assert (MEM_P (target
));
148 PUT_MODE (target
, TYPE_MODE (type
));
150 create_fixed_operand (&ops
[0], target
);
151 create_input_operand (&ops
[1], reg
, TYPE_MODE (type
));
152 expand_insn (get_multi_vector_move (type
, optab
), 2, ops
);
156 expand_ANNOTATE (internal_fn
, gcall
*)
161 /* This should get expanded in omp_device_lower pass. */
164 expand_GOMP_USE_SIMT (internal_fn
, gcall
*)
169 /* Lane index on SIMT targets: thread index in the warp on NVPTX. On targets
170 without SIMT execution this should be expanded in omp_device_lower pass. */
173 expand_GOMP_SIMT_LANE (internal_fn
, gcall
*stmt
)
175 tree lhs
= gimple_call_lhs (stmt
);
179 rtx target
= expand_expr (lhs
, NULL_RTX
, VOIDmode
, EXPAND_WRITE
);
180 gcc_assert (targetm
.have_omp_simt_lane ());
181 emit_insn (targetm
.gen_omp_simt_lane (target
));
184 /* This should get expanded in omp_device_lower pass. */
187 expand_GOMP_SIMT_VF (internal_fn
, gcall
*)
192 /* Lane index of the first SIMT lane that supplies a non-zero argument.
193 This is a SIMT counterpart to GOMP_SIMD_LAST_LANE, used to represent the
194 lane that executed the last iteration for handling OpenMP lastprivate. */
197 expand_GOMP_SIMT_LAST_LANE (internal_fn
, gcall
*stmt
)
199 tree lhs
= gimple_call_lhs (stmt
);
203 rtx target
= expand_expr (lhs
, NULL_RTX
, VOIDmode
, EXPAND_WRITE
);
204 rtx cond
= expand_normal (gimple_call_arg (stmt
, 0));
205 machine_mode mode
= TYPE_MODE (TREE_TYPE (lhs
));
206 struct expand_operand ops
[2];
207 create_output_operand (&ops
[0], target
, mode
);
208 create_input_operand (&ops
[1], cond
, mode
);
209 gcc_assert (targetm
.have_omp_simt_last_lane ());
210 expand_insn (targetm
.code_for_omp_simt_last_lane
, 2, ops
);
213 /* Non-transparent predicate used in SIMT lowering of OpenMP "ordered". */
216 expand_GOMP_SIMT_ORDERED_PRED (internal_fn
, gcall
*stmt
)
218 tree lhs
= gimple_call_lhs (stmt
);
222 rtx target
= expand_expr (lhs
, NULL_RTX
, VOIDmode
, EXPAND_WRITE
);
223 rtx ctr
= expand_normal (gimple_call_arg (stmt
, 0));
224 machine_mode mode
= TYPE_MODE (TREE_TYPE (lhs
));
225 struct expand_operand ops
[2];
226 create_output_operand (&ops
[0], target
, mode
);
227 create_input_operand (&ops
[1], ctr
, mode
);
228 gcc_assert (targetm
.have_omp_simt_ordered ());
229 expand_insn (targetm
.code_for_omp_simt_ordered
, 2, ops
);
232 /* "Or" boolean reduction across SIMT lanes: return non-zero in all lanes if
233 any lane supplies a non-zero argument. */
236 expand_GOMP_SIMT_VOTE_ANY (internal_fn
, gcall
*stmt
)
238 tree lhs
= gimple_call_lhs (stmt
);
242 rtx target
= expand_expr (lhs
, NULL_RTX
, VOIDmode
, EXPAND_WRITE
);
243 rtx cond
= expand_normal (gimple_call_arg (stmt
, 0));
244 machine_mode mode
= TYPE_MODE (TREE_TYPE (lhs
));
245 struct expand_operand ops
[2];
246 create_output_operand (&ops
[0], target
, mode
);
247 create_input_operand (&ops
[1], cond
, mode
);
248 gcc_assert (targetm
.have_omp_simt_vote_any ());
249 expand_insn (targetm
.code_for_omp_simt_vote_any
, 2, ops
);
252 /* Exchange between SIMT lanes with a "butterfly" pattern: source lane index
253 is destination lane index XOR given offset. */
256 expand_GOMP_SIMT_XCHG_BFLY (internal_fn
, gcall
*stmt
)
258 tree lhs
= gimple_call_lhs (stmt
);
262 rtx target
= expand_expr (lhs
, NULL_RTX
, VOIDmode
, EXPAND_WRITE
);
263 rtx src
= expand_normal (gimple_call_arg (stmt
, 0));
264 rtx idx
= expand_normal (gimple_call_arg (stmt
, 1));
265 machine_mode mode
= TYPE_MODE (TREE_TYPE (lhs
));
266 struct expand_operand ops
[3];
267 create_output_operand (&ops
[0], target
, mode
);
268 create_input_operand (&ops
[1], src
, mode
);
269 create_input_operand (&ops
[2], idx
, SImode
);
270 gcc_assert (targetm
.have_omp_simt_xchg_bfly ());
271 expand_insn (targetm
.code_for_omp_simt_xchg_bfly
, 3, ops
);
274 /* Exchange between SIMT lanes according to given source lane index. */
277 expand_GOMP_SIMT_XCHG_IDX (internal_fn
, gcall
*stmt
)
279 tree lhs
= gimple_call_lhs (stmt
);
283 rtx target
= expand_expr (lhs
, NULL_RTX
, VOIDmode
, EXPAND_WRITE
);
284 rtx src
= expand_normal (gimple_call_arg (stmt
, 0));
285 rtx idx
= expand_normal (gimple_call_arg (stmt
, 1));
286 machine_mode mode
= TYPE_MODE (TREE_TYPE (lhs
));
287 struct expand_operand ops
[3];
288 create_output_operand (&ops
[0], target
, mode
);
289 create_input_operand (&ops
[1], src
, mode
);
290 create_input_operand (&ops
[2], idx
, SImode
);
291 gcc_assert (targetm
.have_omp_simt_xchg_idx ());
292 expand_insn (targetm
.code_for_omp_simt_xchg_idx
, 3, ops
);
295 /* This should get expanded in adjust_simduid_builtins. */
298 expand_GOMP_SIMD_LANE (internal_fn
, gcall
*)
303 /* This should get expanded in adjust_simduid_builtins. */
306 expand_GOMP_SIMD_VF (internal_fn
, gcall
*)
311 /* This should get expanded in adjust_simduid_builtins. */
314 expand_GOMP_SIMD_LAST_LANE (internal_fn
, gcall
*)
319 /* This should get expanded in adjust_simduid_builtins. */
322 expand_GOMP_SIMD_ORDERED_START (internal_fn
, gcall
*)
327 /* This should get expanded in adjust_simduid_builtins. */
330 expand_GOMP_SIMD_ORDERED_END (internal_fn
, gcall
*)
335 /* This should get expanded in the sanopt pass. */
338 expand_UBSAN_NULL (internal_fn
, gcall
*)
343 /* This should get expanded in the sanopt pass. */
346 expand_UBSAN_BOUNDS (internal_fn
, gcall
*)
351 /* This should get expanded in the sanopt pass. */
354 expand_UBSAN_VPTR (internal_fn
, gcall
*)
359 /* This should get expanded in the sanopt pass. */
362 expand_UBSAN_OBJECT_SIZE (internal_fn
, gcall
*)
367 /* This should get expanded in the sanopt pass. */
370 expand_ASAN_CHECK (internal_fn
, gcall
*)
375 /* This should get expanded in the sanopt pass. */
378 expand_ASAN_MARK (internal_fn
, gcall
*)
383 /* This should get expanded in the sanopt pass. */
386 expand_ASAN_POISON (internal_fn
, gcall
*)
391 /* This should get expanded in the sanopt pass. */
394 expand_ASAN_POISON_USE (internal_fn
, gcall
*)
399 /* This should get expanded in the tsan pass. */
402 expand_TSAN_FUNC_EXIT (internal_fn
, gcall
*)
407 /* This should get expanded in the lower pass. */
410 expand_FALLTHROUGH (internal_fn
, gcall
*call
)
412 error_at (gimple_location (call
),
413 "invalid use of attribute %<fallthrough%>");
416 /* Return minimum precision needed to represent all values
417 of ARG in SIGNed integral type. */
420 get_min_precision (tree arg
, signop sign
)
422 int prec
= TYPE_PRECISION (TREE_TYPE (arg
));
424 signop orig_sign
= sign
;
425 if (TREE_CODE (arg
) == INTEGER_CST
)
428 if (TYPE_SIGN (TREE_TYPE (arg
)) != sign
)
430 widest_int w
= wi::to_widest (arg
);
431 w
= wi::ext (w
, prec
, sign
);
432 p
= wi::min_precision (w
, sign
);
435 p
= wi::min_precision (arg
, sign
);
436 return MIN (p
, prec
);
438 while (CONVERT_EXPR_P (arg
)
439 && INTEGRAL_TYPE_P (TREE_TYPE (TREE_OPERAND (arg
, 0)))
440 && TYPE_PRECISION (TREE_TYPE (TREE_OPERAND (arg
, 0))) <= prec
)
442 arg
= TREE_OPERAND (arg
, 0);
443 if (TYPE_PRECISION (TREE_TYPE (arg
)) < prec
)
445 if (TYPE_UNSIGNED (TREE_TYPE (arg
)))
447 else if (sign
== UNSIGNED
&& get_range_pos_neg (arg
) != 1)
448 return prec
+ (orig_sign
!= sign
);
449 prec
= TYPE_PRECISION (TREE_TYPE (arg
));
452 return prec
+ (orig_sign
!= sign
);
454 if (TREE_CODE (arg
) != SSA_NAME
)
455 return prec
+ (orig_sign
!= sign
);
456 wide_int arg_min
, arg_max
;
457 while (get_range_info (arg
, &arg_min
, &arg_max
) != VR_RANGE
)
459 gimple
*g
= SSA_NAME_DEF_STMT (arg
);
460 if (is_gimple_assign (g
)
461 && CONVERT_EXPR_CODE_P (gimple_assign_rhs_code (g
)))
463 tree t
= gimple_assign_rhs1 (g
);
464 if (INTEGRAL_TYPE_P (TREE_TYPE (t
))
465 && TYPE_PRECISION (TREE_TYPE (t
)) <= prec
)
468 if (TYPE_PRECISION (TREE_TYPE (arg
)) < prec
)
470 if (TYPE_UNSIGNED (TREE_TYPE (arg
)))
472 else if (sign
== UNSIGNED
&& get_range_pos_neg (arg
) != 1)
473 return prec
+ (orig_sign
!= sign
);
474 prec
= TYPE_PRECISION (TREE_TYPE (arg
));
477 return prec
+ (orig_sign
!= sign
);
481 return prec
+ (orig_sign
!= sign
);
483 if (sign
== TYPE_SIGN (TREE_TYPE (arg
)))
485 int p1
= wi::min_precision (arg_min
, sign
);
486 int p2
= wi::min_precision (arg_max
, sign
);
488 prec
= MIN (prec
, p1
);
490 else if (sign
== UNSIGNED
&& !wi::neg_p (arg_min
, SIGNED
))
492 int p
= wi::min_precision (arg_max
, UNSIGNED
);
493 prec
= MIN (prec
, p
);
495 return prec
+ (orig_sign
!= sign
);
498 /* Helper for expand_*_overflow. Set the __imag__ part to true
499 (1 except for signed:1 type, in which case store -1). */
502 expand_arith_set_overflow (tree lhs
, rtx target
)
504 if (TYPE_PRECISION (TREE_TYPE (TREE_TYPE (lhs
))) == 1
505 && !TYPE_UNSIGNED (TREE_TYPE (TREE_TYPE (lhs
))))
506 write_complex_part (target
, constm1_rtx
, true);
508 write_complex_part (target
, const1_rtx
, true);
511 /* Helper for expand_*_overflow. Store RES into the __real__ part
512 of TARGET. If RES has larger MODE than __real__ part of TARGET,
513 set the __imag__ part to 1 if RES doesn't fit into it. Similarly
514 if LHS has smaller precision than its mode. */
517 expand_arith_overflow_result_store (tree lhs
, rtx target
,
518 machine_mode mode
, rtx res
)
520 machine_mode tgtmode
= GET_MODE_INNER (GET_MODE (target
));
524 rtx_code_label
*done_label
= gen_label_rtx ();
525 int uns
= TYPE_UNSIGNED (TREE_TYPE (TREE_TYPE (lhs
)));
526 lres
= convert_modes (tgtmode
, mode
, res
, uns
);
527 gcc_assert (GET_MODE_PRECISION (tgtmode
) < GET_MODE_PRECISION (mode
));
528 do_compare_rtx_and_jump (res
, convert_modes (mode
, tgtmode
, lres
, uns
),
529 EQ
, true, mode
, NULL_RTX
, NULL
, done_label
,
531 expand_arith_set_overflow (lhs
, target
);
532 emit_label (done_label
);
534 int prec
= TYPE_PRECISION (TREE_TYPE (TREE_TYPE (lhs
)));
535 int tgtprec
= GET_MODE_PRECISION (tgtmode
);
538 rtx_code_label
*done_label
= gen_label_rtx ();
539 int uns
= TYPE_UNSIGNED (TREE_TYPE (TREE_TYPE (lhs
)));
544 = immed_wide_int_const (wi::shifted_mask (0, prec
, false, tgtprec
),
546 lres
= expand_simple_binop (tgtmode
, AND
, res
, mask
, NULL_RTX
,
547 true, OPTAB_LIB_WIDEN
);
551 lres
= expand_shift (LSHIFT_EXPR
, tgtmode
, res
, tgtprec
- prec
,
553 lres
= expand_shift (RSHIFT_EXPR
, tgtmode
, lres
, tgtprec
- prec
,
556 do_compare_rtx_and_jump (res
, lres
,
557 EQ
, true, tgtmode
, NULL_RTX
, NULL
, done_label
,
559 expand_arith_set_overflow (lhs
, target
);
560 emit_label (done_label
);
562 write_complex_part (target
, lres
, false);
565 /* Helper for expand_*_overflow. Store RES into TARGET. */
568 expand_ubsan_result_store (rtx target
, rtx res
)
570 if (GET_CODE (target
) == SUBREG
&& SUBREG_PROMOTED_VAR_P (target
))
571 /* If this is a scalar in a register that is stored in a wider mode
572 than the declared mode, compute the result into its declared mode
573 and then convert to the wider mode. Our value is the computed
575 convert_move (SUBREG_REG (target
), res
, SUBREG_PROMOTED_SIGN (target
));
577 emit_move_insn (target
, res
);
580 /* Add sub/add overflow checking to the statement STMT.
581 CODE says whether the operation is +, or -. */
584 expand_addsub_overflow (location_t loc
, tree_code code
, tree lhs
,
585 tree arg0
, tree arg1
, bool unsr_p
, bool uns0_p
,
586 bool uns1_p
, bool is_ubsan
, tree
*datap
)
588 rtx res
, target
= NULL_RTX
;
590 rtx_code_label
*done_label
= gen_label_rtx ();
591 rtx_code_label
*do_error
= gen_label_rtx ();
592 do_pending_stack_adjust ();
593 rtx op0
= expand_normal (arg0
);
594 rtx op1
= expand_normal (arg1
);
595 machine_mode mode
= TYPE_MODE (TREE_TYPE (arg0
));
596 int prec
= GET_MODE_PRECISION (mode
);
597 rtx sgn
= immed_wide_int_const (wi::min_value (prec
, SIGNED
), mode
);
601 gcc_assert (!unsr_p
&& !uns0_p
&& !uns1_p
);
605 target
= expand_expr (lhs
, NULL_RTX
, VOIDmode
, EXPAND_WRITE
);
607 write_complex_part (target
, const0_rtx
, true);
610 /* We assume both operands and result have the same precision
611 here (GET_MODE_BITSIZE (mode)), S stands for signed type
612 with that precision, U for unsigned type with that precision,
613 sgn for unsigned most significant bit in that precision.
614 s1 is signed first operand, u1 is unsigned first operand,
615 s2 is signed second operand, u2 is unsigned second operand,
616 sr is signed result, ur is unsigned result and the following
617 rules say how to compute result (which is always result of
618 the operands as if both were unsigned, cast to the right
619 signedness) and how to compute whether operation overflowed.
622 res = (S) ((U) s1 + (U) s2)
623 ovf = s2 < 0 ? res > s1 : res < s1 (or jump on overflow)
625 res = (S) ((U) s1 - (U) s2)
626 ovf = s2 < 0 ? res < s1 : res > s2 (or jump on overflow)
629 ovf = res < u1 (or jump on carry, but RTL opts will handle it)
632 ovf = res > u1 (or jump on carry, but RTL opts will handle it)
634 res = (S) ((U) s1 + u2)
635 ovf = ((U) res ^ sgn) < u2
640 ovf = t1 < 0 ? t2 > s1 : t2 < s1 (or jump on overflow)
642 res = (S) ((U) s1 - u2)
643 ovf = u2 > ((U) s1 ^ sgn)
646 ovf = s1 < 0 || u2 > (U) s1
649 ovf = u1 >= ((U) s2 ^ sgn)
654 ovf = s2 < 0 ? (S) t2 < (S) t1 : (S) t2 > (S) t1 (or jump on overflow)
656 res = (U) s1 + (U) s2
657 ovf = s2 < 0 ? (s1 | (S) res) < 0) : (s1 & (S) res) < 0)
660 ovf = (U) res < u2 || res < 0
663 ovf = u1 >= u2 ? res < 0 : res >= 0
665 res = (U) s1 - (U) s2
666 ovf = s2 >= 0 ? ((s1 | (S) res) < 0) : ((s1 & (S) res) < 0) */
668 if (code
== PLUS_EXPR
&& uns0_p
&& !uns1_p
)
670 /* PLUS_EXPR is commutative, if operand signedness differs,
671 canonicalize to the first operand being signed and second
672 unsigned to simplify following code. */
673 std::swap (op0
, op1
);
674 std::swap (arg0
, arg1
);
680 if (uns0_p
&& uns1_p
&& unsr_p
)
682 insn_code icode
= optab_handler (code
== PLUS_EXPR
? uaddv4_optab
683 : usubv4_optab
, mode
);
684 if (icode
!= CODE_FOR_nothing
)
686 struct expand_operand ops
[4];
687 rtx_insn
*last
= get_last_insn ();
689 res
= gen_reg_rtx (mode
);
690 create_output_operand (&ops
[0], res
, mode
);
691 create_input_operand (&ops
[1], op0
, mode
);
692 create_input_operand (&ops
[2], op1
, mode
);
693 create_fixed_operand (&ops
[3], do_error
);
694 if (maybe_expand_insn (icode
, 4, ops
))
696 last
= get_last_insn ();
697 if (profile_status_for_fn (cfun
) != PROFILE_ABSENT
699 && any_condjump_p (last
)
700 && !find_reg_note (last
, REG_BR_PROB
, 0))
701 add_int_reg_note (last
, REG_BR_PROB
, PROB_VERY_UNLIKELY
);
702 emit_jump (done_label
);
706 delete_insns_since (last
);
709 /* Compute the operation. On RTL level, the addition is always
711 res
= expand_binop (mode
, code
== PLUS_EXPR
? add_optab
: sub_optab
,
712 op0
, op1
, NULL_RTX
, false, OPTAB_LIB_WIDEN
);
714 /* For PLUS_EXPR, the operation is commutative, so we can pick
715 operand to compare against. For prec <= BITS_PER_WORD, I think
716 preferring REG operand is better over CONST_INT, because
717 the CONST_INT might enlarge the instruction or CSE would need
718 to figure out we'd already loaded it into a register before.
719 For prec > BITS_PER_WORD, I think CONST_INT might be more beneficial,
720 as then the multi-word comparison can be perhaps simplified. */
721 if (code
== PLUS_EXPR
722 && (prec
<= BITS_PER_WORD
723 ? (CONST_SCALAR_INT_P (op0
) && REG_P (op1
))
724 : CONST_SCALAR_INT_P (op1
)))
726 do_compare_rtx_and_jump (res
, tem
, code
== PLUS_EXPR
? GEU
: LEU
,
727 true, mode
, NULL_RTX
, NULL
, done_label
,
733 if (!uns0_p
&& uns1_p
&& !unsr_p
)
735 /* Compute the operation. On RTL level, the addition is always
737 res
= expand_binop (mode
, code
== PLUS_EXPR
? add_optab
: sub_optab
,
738 op0
, op1
, NULL_RTX
, false, OPTAB_LIB_WIDEN
);
739 rtx tem
= expand_binop (mode
, add_optab
,
740 code
== PLUS_EXPR
? res
: op0
, sgn
,
741 NULL_RTX
, false, OPTAB_LIB_WIDEN
);
742 do_compare_rtx_and_jump (tem
, op1
, GEU
, true, mode
, NULL_RTX
, NULL
,
743 done_label
, PROB_VERY_LIKELY
);
748 if (code
== PLUS_EXPR
&& !uns0_p
&& uns1_p
&& unsr_p
)
750 op1
= expand_binop (mode
, add_optab
, op1
, sgn
, NULL_RTX
, false,
752 /* As we've changed op1, we have to avoid using the value range
753 for the original argument. */
754 arg1
= error_mark_node
;
760 if (code
== MINUS_EXPR
&& uns0_p
&& !uns1_p
&& unsr_p
)
762 op0
= expand_binop (mode
, add_optab
, op0
, sgn
, NULL_RTX
, false,
764 /* As we've changed op0, we have to avoid using the value range
765 for the original argument. */
766 arg0
= error_mark_node
;
772 if (code
== MINUS_EXPR
&& !uns0_p
&& uns1_p
&& unsr_p
)
774 /* Compute the operation. On RTL level, the addition is always
776 res
= expand_binop (mode
, sub_optab
, op0
, op1
, NULL_RTX
, false,
778 int pos_neg
= get_range_pos_neg (arg0
);
780 /* If ARG0 is known to be always negative, this is always overflow. */
781 emit_jump (do_error
);
782 else if (pos_neg
== 3)
783 /* If ARG0 is not known to be always positive, check at runtime. */
784 do_compare_rtx_and_jump (op0
, const0_rtx
, LT
, false, mode
, NULL_RTX
,
785 NULL
, do_error
, PROB_VERY_UNLIKELY
);
786 do_compare_rtx_and_jump (op1
, op0
, LEU
, true, mode
, NULL_RTX
, NULL
,
787 done_label
, PROB_VERY_LIKELY
);
792 if (code
== MINUS_EXPR
&& uns0_p
&& !uns1_p
&& !unsr_p
)
794 /* Compute the operation. On RTL level, the addition is always
796 res
= expand_binop (mode
, sub_optab
, op0
, op1
, NULL_RTX
, false,
798 rtx tem
= expand_binop (mode
, add_optab
, op1
, sgn
, NULL_RTX
, false,
800 do_compare_rtx_and_jump (op0
, tem
, LTU
, true, mode
, NULL_RTX
, NULL
,
801 done_label
, PROB_VERY_LIKELY
);
806 if (code
== PLUS_EXPR
&& uns0_p
&& uns1_p
&& !unsr_p
)
808 /* Compute the operation. On RTL level, the addition is always
810 res
= expand_binop (mode
, add_optab
, op0
, op1
, NULL_RTX
, false,
812 do_compare_rtx_and_jump (res
, const0_rtx
, LT
, false, mode
, NULL_RTX
,
813 NULL
, do_error
, PROB_VERY_UNLIKELY
);
815 /* The operation is commutative, so we can pick operand to compare
816 against. For prec <= BITS_PER_WORD, I think preferring REG operand
817 is better over CONST_INT, because the CONST_INT might enlarge the
818 instruction or CSE would need to figure out we'd already loaded it
819 into a register before. For prec > BITS_PER_WORD, I think CONST_INT
820 might be more beneficial, as then the multi-word comparison can be
821 perhaps simplified. */
822 if (prec
<= BITS_PER_WORD
823 ? (CONST_SCALAR_INT_P (op1
) && REG_P (op0
))
824 : CONST_SCALAR_INT_P (op0
))
826 do_compare_rtx_and_jump (res
, tem
, GEU
, true, mode
, NULL_RTX
, NULL
,
827 done_label
, PROB_VERY_LIKELY
);
832 if (!uns0_p
&& !uns1_p
&& unsr_p
)
834 /* Compute the operation. On RTL level, the addition is always
836 res
= expand_binop (mode
, code
== PLUS_EXPR
? add_optab
: sub_optab
,
837 op0
, op1
, NULL_RTX
, false, OPTAB_LIB_WIDEN
);
838 int pos_neg
= get_range_pos_neg (arg1
);
839 if (code
== PLUS_EXPR
)
841 int pos_neg0
= get_range_pos_neg (arg0
);
842 if (pos_neg0
!= 3 && pos_neg
== 3)
844 std::swap (op0
, op1
);
851 tem
= expand_binop (mode
, ((pos_neg
== 1) ^ (code
== MINUS_EXPR
))
852 ? and_optab
: ior_optab
,
853 op0
, res
, NULL_RTX
, false, OPTAB_LIB_WIDEN
);
854 do_compare_rtx_and_jump (tem
, const0_rtx
, GE
, false, mode
, NULL
,
855 NULL
, done_label
, PROB_VERY_LIKELY
);
859 rtx_code_label
*do_ior_label
= gen_label_rtx ();
860 do_compare_rtx_and_jump (op1
, const0_rtx
,
861 code
== MINUS_EXPR
? GE
: LT
, false, mode
,
862 NULL_RTX
, NULL
, do_ior_label
,
864 tem
= expand_binop (mode
, and_optab
, op0
, res
, NULL_RTX
, false,
866 do_compare_rtx_and_jump (tem
, const0_rtx
, GE
, false, mode
, NULL_RTX
,
867 NULL
, done_label
, PROB_VERY_LIKELY
);
868 emit_jump (do_error
);
869 emit_label (do_ior_label
);
870 tem
= expand_binop (mode
, ior_optab
, op0
, res
, NULL_RTX
, false,
872 do_compare_rtx_and_jump (tem
, const0_rtx
, GE
, false, mode
, NULL_RTX
,
873 NULL
, done_label
, PROB_VERY_LIKELY
);
879 if (code
== MINUS_EXPR
&& uns0_p
&& uns1_p
&& !unsr_p
)
881 /* Compute the operation. On RTL level, the addition is always
883 res
= expand_binop (mode
, sub_optab
, op0
, op1
, NULL_RTX
, false,
885 rtx_code_label
*op0_geu_op1
= gen_label_rtx ();
886 do_compare_rtx_and_jump (op0
, op1
, GEU
, true, mode
, NULL_RTX
, NULL
,
887 op0_geu_op1
, PROB_EVEN
);
888 do_compare_rtx_and_jump (res
, const0_rtx
, LT
, false, mode
, NULL_RTX
,
889 NULL
, done_label
, PROB_VERY_LIKELY
);
890 emit_jump (do_error
);
891 emit_label (op0_geu_op1
);
892 do_compare_rtx_and_jump (res
, const0_rtx
, GE
, false, mode
, NULL_RTX
,
893 NULL
, done_label
, PROB_VERY_LIKELY
);
897 gcc_assert (!uns0_p
&& !uns1_p
&& !unsr_p
);
902 insn_code icode
= optab_handler (code
== PLUS_EXPR
? addv4_optab
903 : subv4_optab
, mode
);
904 if (icode
!= CODE_FOR_nothing
)
906 struct expand_operand ops
[4];
907 rtx_insn
*last
= get_last_insn ();
909 res
= gen_reg_rtx (mode
);
910 create_output_operand (&ops
[0], res
, mode
);
911 create_input_operand (&ops
[1], op0
, mode
);
912 create_input_operand (&ops
[2], op1
, mode
);
913 create_fixed_operand (&ops
[3], do_error
);
914 if (maybe_expand_insn (icode
, 4, ops
))
916 last
= get_last_insn ();
917 if (profile_status_for_fn (cfun
) != PROFILE_ABSENT
919 && any_condjump_p (last
)
920 && !find_reg_note (last
, REG_BR_PROB
, 0))
921 add_int_reg_note (last
, REG_BR_PROB
, PROB_VERY_UNLIKELY
);
922 emit_jump (done_label
);
926 delete_insns_since (last
);
929 /* Compute the operation. On RTL level, the addition is always
931 res
= expand_binop (mode
, code
== PLUS_EXPR
? add_optab
: sub_optab
,
932 op0
, op1
, NULL_RTX
, false, OPTAB_LIB_WIDEN
);
934 /* If we can prove that one of the arguments (for MINUS_EXPR only
935 the second operand, as subtraction is not commutative) is always
936 non-negative or always negative, we can do just one comparison
937 and conditional jump. */
938 int pos_neg
= get_range_pos_neg (arg1
);
939 if (code
== PLUS_EXPR
)
941 int pos_neg0
= get_range_pos_neg (arg0
);
942 if (pos_neg0
!= 3 && pos_neg
== 3)
944 std::swap (op0
, op1
);
949 /* Addition overflows if and only if the two operands have the same sign,
950 and the result has the opposite sign. Subtraction overflows if and
951 only if the two operands have opposite sign, and the subtrahend has
952 the same sign as the result. Here 0 is counted as positive. */
955 /* Compute op0 ^ op1 (operands have opposite sign). */
956 rtx op_xor
= expand_binop (mode
, xor_optab
, op0
, op1
, NULL_RTX
, false,
959 /* Compute res ^ op1 (result and 2nd operand have opposite sign). */
960 rtx res_xor
= expand_binop (mode
, xor_optab
, res
, op1
, NULL_RTX
, false,
964 if (code
== PLUS_EXPR
)
966 /* Compute (res ^ op1) & ~(op0 ^ op1). */
967 tem
= expand_unop (mode
, one_cmpl_optab
, op_xor
, NULL_RTX
, false);
968 tem
= expand_binop (mode
, and_optab
, res_xor
, tem
, NULL_RTX
, false,
973 /* Compute (op0 ^ op1) & ~(res ^ op1). */
974 tem
= expand_unop (mode
, one_cmpl_optab
, res_xor
, NULL_RTX
, false);
975 tem
= expand_binop (mode
, and_optab
, op_xor
, tem
, NULL_RTX
, false,
979 /* No overflow if the result has bit sign cleared. */
980 do_compare_rtx_and_jump (tem
, const0_rtx
, GE
, false, mode
, NULL_RTX
,
981 NULL
, done_label
, PROB_VERY_LIKELY
);
984 /* Compare the result of the operation with the first operand.
985 No overflow for addition if second operand is positive and result
986 is larger or second operand is negative and result is smaller.
987 Likewise for subtraction with sign of second operand flipped. */
989 do_compare_rtx_and_jump (res
, op0
,
990 (pos_neg
== 1) ^ (code
== MINUS_EXPR
) ? GE
: LE
,
991 false, mode
, NULL_RTX
, NULL
, done_label
,
996 emit_label (do_error
);
999 /* Expand the ubsan builtin call. */
1001 fn
= ubsan_build_overflow_builtin (code
, loc
, TREE_TYPE (arg0
),
1005 do_pending_stack_adjust ();
1008 expand_arith_set_overflow (lhs
, target
);
1011 emit_label (done_label
);
1016 expand_ubsan_result_store (target
, res
);
1020 res
= expand_binop (mode
, add_optab
, res
, sgn
, NULL_RTX
, false,
1023 expand_arith_overflow_result_store (lhs
, target
, mode
, res
);
1028 /* Add negate overflow checking to the statement STMT. */
1031 expand_neg_overflow (location_t loc
, tree lhs
, tree arg1
, bool is_ubsan
,
1036 rtx_code_label
*done_label
, *do_error
;
1037 rtx target
= NULL_RTX
;
1039 done_label
= gen_label_rtx ();
1040 do_error
= gen_label_rtx ();
1042 do_pending_stack_adjust ();
1043 op1
= expand_normal (arg1
);
1045 machine_mode mode
= TYPE_MODE (TREE_TYPE (arg1
));
1048 target
= expand_expr (lhs
, NULL_RTX
, VOIDmode
, EXPAND_WRITE
);
1050 write_complex_part (target
, const0_rtx
, true);
1053 enum insn_code icode
= optab_handler (negv3_optab
, mode
);
1054 if (icode
!= CODE_FOR_nothing
)
1056 struct expand_operand ops
[3];
1057 rtx_insn
*last
= get_last_insn ();
1059 res
= gen_reg_rtx (mode
);
1060 create_output_operand (&ops
[0], res
, mode
);
1061 create_input_operand (&ops
[1], op1
, mode
);
1062 create_fixed_operand (&ops
[2], do_error
);
1063 if (maybe_expand_insn (icode
, 3, ops
))
1065 last
= get_last_insn ();
1066 if (profile_status_for_fn (cfun
) != PROFILE_ABSENT
1068 && any_condjump_p (last
)
1069 && !find_reg_note (last
, REG_BR_PROB
, 0))
1070 add_int_reg_note (last
, REG_BR_PROB
, PROB_VERY_UNLIKELY
);
1071 emit_jump (done_label
);
1075 delete_insns_since (last
);
1076 icode
= CODE_FOR_nothing
;
1080 if (icode
== CODE_FOR_nothing
)
1082 /* Compute the operation. On RTL level, the addition is always
1084 res
= expand_unop (mode
, neg_optab
, op1
, NULL_RTX
, false);
1086 /* Compare the operand with the most negative value. */
1087 rtx minv
= expand_normal (TYPE_MIN_VALUE (TREE_TYPE (arg1
)));
1088 do_compare_rtx_and_jump (op1
, minv
, NE
, true, mode
, NULL_RTX
, NULL
,
1089 done_label
, PROB_VERY_LIKELY
);
1092 emit_label (do_error
);
1095 /* Expand the ubsan builtin call. */
1097 fn
= ubsan_build_overflow_builtin (NEGATE_EXPR
, loc
, TREE_TYPE (arg1
),
1098 arg1
, NULL_TREE
, datap
);
1101 do_pending_stack_adjust ();
1104 expand_arith_set_overflow (lhs
, target
);
1107 emit_label (done_label
);
1112 expand_ubsan_result_store (target
, res
);
1114 expand_arith_overflow_result_store (lhs
, target
, mode
, res
);
1118 /* Add mul overflow checking to the statement STMT. */
1121 expand_mul_overflow (location_t loc
, tree lhs
, tree arg0
, tree arg1
,
1122 bool unsr_p
, bool uns0_p
, bool uns1_p
, bool is_ubsan
,
1127 rtx_code_label
*done_label
, *do_error
;
1128 rtx target
= NULL_RTX
;
1130 enum insn_code icode
;
1132 done_label
= gen_label_rtx ();
1133 do_error
= gen_label_rtx ();
1135 do_pending_stack_adjust ();
1136 op0
= expand_normal (arg0
);
1137 op1
= expand_normal (arg1
);
1139 machine_mode mode
= TYPE_MODE (TREE_TYPE (arg0
));
1143 target
= expand_expr (lhs
, NULL_RTX
, VOIDmode
, EXPAND_WRITE
);
1145 write_complex_part (target
, const0_rtx
, true);
1149 gcc_assert (!unsr_p
&& !uns0_p
&& !uns1_p
);
1151 /* We assume both operands and result have the same precision
1152 here (GET_MODE_BITSIZE (mode)), S stands for signed type
1153 with that precision, U for unsigned type with that precision,
1154 sgn for unsigned most significant bit in that precision.
1155 s1 is signed first operand, u1 is unsigned first operand,
1156 s2 is signed second operand, u2 is unsigned second operand,
1157 sr is signed result, ur is unsigned result and the following
1158 rules say how to compute result (which is always result of
1159 the operands as if both were unsigned, cast to the right
1160 signedness) and how to compute whether operation overflowed.
1161 main_ovf (false) stands for jump on signed multiplication
1162 overflow or the main algorithm with uns == false.
1163 main_ovf (true) stands for jump on unsigned multiplication
1164 overflow or the main algorithm with uns == true.
1167 res = (S) ((U) s1 * (U) s2)
1168 ovf = main_ovf (false)
1171 ovf = main_ovf (true)
1174 ovf = (s1 < 0 && u2) || main_ovf (true)
1177 ovf = res < 0 || main_ovf (true)
1179 res = (S) ((U) s1 * u2)
1180 ovf = (S) u2 >= 0 ? main_ovf (false)
1181 : (s1 != 0 && (s1 != -1 || u2 != (U) res))
1183 t1 = (s1 & s2) < 0 ? (-(U) s1) : ((U) s1)
1184 t2 = (s1 & s2) < 0 ? (-(U) s2) : ((U) s2)
1186 ovf = (s1 ^ s2) < 0 ? (s1 && s2) : main_ovf (true) */
1188 if (uns0_p
&& !uns1_p
)
1190 /* Multiplication is commutative, if operand signedness differs,
1191 canonicalize to the first operand being signed and second
1192 unsigned to simplify following code. */
1193 std::swap (op0
, op1
);
1194 std::swap (arg0
, arg1
);
1199 int pos_neg0
= get_range_pos_neg (arg0
);
1200 int pos_neg1
= get_range_pos_neg (arg1
);
1203 if (!uns0_p
&& uns1_p
&& unsr_p
)
1208 /* If s1 is non-negative, just perform normal u1 * u2 -> ur. */
1211 /* If s1 is negative, avoid the main code, just multiply and
1212 signal overflow if op1 is not 0. */
1213 struct separate_ops ops
;
1214 ops
.code
= MULT_EXPR
;
1215 ops
.type
= TREE_TYPE (arg1
);
1216 ops
.op0
= make_tree (ops
.type
, op0
);
1217 ops
.op1
= make_tree (ops
.type
, op1
);
1218 ops
.op2
= NULL_TREE
;
1220 res
= expand_expr_real_2 (&ops
, NULL_RTX
, mode
, EXPAND_NORMAL
);
1221 do_compare_rtx_and_jump (op1
, const0_rtx
, EQ
, true, mode
, NULL_RTX
,
1222 NULL
, done_label
, PROB_VERY_LIKELY
);
1223 goto do_error_label
;
1225 rtx_code_label
*do_main_label
;
1226 do_main_label
= gen_label_rtx ();
1227 do_compare_rtx_and_jump (op0
, const0_rtx
, GE
, false, mode
, NULL_RTX
,
1228 NULL
, do_main_label
, PROB_VERY_LIKELY
);
1229 do_compare_rtx_and_jump (op1
, const0_rtx
, EQ
, true, mode
, NULL_RTX
,
1230 NULL
, do_main_label
, PROB_VERY_LIKELY
);
1231 expand_arith_set_overflow (lhs
, target
);
1232 emit_label (do_main_label
);
1240 if (uns0_p
&& uns1_p
&& !unsr_p
)
1243 /* Rest of handling of this case after res is computed. */
1248 if (!uns0_p
&& uns1_p
&& !unsr_p
)
1255 /* If (S) u2 is negative (i.e. u2 is larger than maximum of S,
1256 avoid the main code, just multiply and signal overflow
1257 unless 0 * u2 or -1 * ((U) Smin). */
1258 struct separate_ops ops
;
1259 ops
.code
= MULT_EXPR
;
1260 ops
.type
= TREE_TYPE (arg1
);
1261 ops
.op0
= make_tree (ops
.type
, op0
);
1262 ops
.op1
= make_tree (ops
.type
, op1
);
1263 ops
.op2
= NULL_TREE
;
1265 res
= expand_expr_real_2 (&ops
, NULL_RTX
, mode
, EXPAND_NORMAL
);
1266 do_compare_rtx_and_jump (op0
, const0_rtx
, EQ
, true, mode
, NULL_RTX
,
1267 NULL
, done_label
, PROB_VERY_LIKELY
);
1268 do_compare_rtx_and_jump (op0
, constm1_rtx
, NE
, true, mode
, NULL_RTX
,
1269 NULL
, do_error
, PROB_VERY_UNLIKELY
);
1271 prec
= GET_MODE_PRECISION (mode
);
1273 sgn
= immed_wide_int_const (wi::min_value (prec
, SIGNED
), mode
);
1274 do_compare_rtx_and_jump (op1
, sgn
, EQ
, true, mode
, NULL_RTX
,
1275 NULL
, done_label
, PROB_VERY_LIKELY
);
1276 goto do_error_label
;
1278 /* Rest of handling of this case after res is computed. */
1286 if (!uns0_p
&& !uns1_p
&& unsr_p
)
1289 switch (pos_neg0
| pos_neg1
)
1291 case 1: /* Both operands known to be non-negative. */
1293 case 2: /* Both operands known to be negative. */
1294 op0
= expand_unop (mode
, neg_optab
, op0
, NULL_RTX
, false);
1295 op1
= expand_unop (mode
, neg_optab
, op1
, NULL_RTX
, false);
1296 /* Avoid looking at arg0/arg1 ranges, as we've changed
1298 arg0
= error_mark_node
;
1299 arg1
= error_mark_node
;
1302 if ((pos_neg0
^ pos_neg1
) == 3)
1304 /* If one operand is known to be negative and the other
1305 non-negative, this overflows always, unless the non-negative
1306 one is 0. Just do normal multiply and set overflow
1307 unless one of the operands is 0. */
1308 struct separate_ops ops
;
1309 ops
.code
= MULT_EXPR
;
1311 = build_nonstandard_integer_type (GET_MODE_PRECISION (mode
),
1313 ops
.op0
= make_tree (ops
.type
, op0
);
1314 ops
.op1
= make_tree (ops
.type
, op1
);
1315 ops
.op2
= NULL_TREE
;
1317 res
= expand_expr_real_2 (&ops
, NULL_RTX
, mode
, EXPAND_NORMAL
);
1318 tem
= expand_binop (mode
, and_optab
, op0
, op1
, NULL_RTX
, false,
1320 do_compare_rtx_and_jump (tem
, const0_rtx
, EQ
, true, mode
,
1321 NULL_RTX
, NULL
, done_label
,
1323 goto do_error_label
;
1325 /* The general case, do all the needed comparisons at runtime. */
1326 rtx_code_label
*do_main_label
, *after_negate_label
;
1328 rop0
= gen_reg_rtx (mode
);
1329 rop1
= gen_reg_rtx (mode
);
1330 emit_move_insn (rop0
, op0
);
1331 emit_move_insn (rop1
, op1
);
1334 do_main_label
= gen_label_rtx ();
1335 after_negate_label
= gen_label_rtx ();
1336 tem
= expand_binop (mode
, and_optab
, op0
, op1
, NULL_RTX
, false,
1338 do_compare_rtx_and_jump (tem
, const0_rtx
, GE
, false, mode
, NULL_RTX
,
1339 NULL
, after_negate_label
, PROB_VERY_LIKELY
);
1340 /* Both arguments negative here, negate them and continue with
1341 normal unsigned overflow checking multiplication. */
1342 emit_move_insn (op0
, expand_unop (mode
, neg_optab
, op0
,
1344 emit_move_insn (op1
, expand_unop (mode
, neg_optab
, op1
,
1346 /* Avoid looking at arg0/arg1 ranges, as we might have changed
1348 arg0
= error_mark_node
;
1349 arg1
= error_mark_node
;
1350 emit_jump (do_main_label
);
1351 emit_label (after_negate_label
);
1352 tem2
= expand_binop (mode
, xor_optab
, op0
, op1
, NULL_RTX
, false,
1354 do_compare_rtx_and_jump (tem2
, const0_rtx
, GE
, false, mode
, NULL_RTX
,
1355 NULL
, do_main_label
, PROB_VERY_LIKELY
);
1356 /* One argument is negative here, the other positive. This
1357 overflows always, unless one of the arguments is 0. But
1358 if e.g. s2 is 0, (U) s1 * 0 doesn't overflow, whatever s1
1359 is, thus we can keep do_main code oring in overflow as is. */
1360 do_compare_rtx_and_jump (tem
, const0_rtx
, EQ
, true, mode
, NULL_RTX
,
1361 NULL
, do_main_label
, PROB_VERY_LIKELY
);
1362 expand_arith_set_overflow (lhs
, target
);
1363 emit_label (do_main_label
);
1371 type
= build_nonstandard_integer_type (GET_MODE_PRECISION (mode
), uns
);
1372 sign
= uns
? UNSIGNED
: SIGNED
;
1373 icode
= optab_handler (uns
? umulv4_optab
: mulv4_optab
, mode
);
1374 if (icode
!= CODE_FOR_nothing
)
1376 struct expand_operand ops
[4];
1377 rtx_insn
*last
= get_last_insn ();
1379 res
= gen_reg_rtx (mode
);
1380 create_output_operand (&ops
[0], res
, mode
);
1381 create_input_operand (&ops
[1], op0
, mode
);
1382 create_input_operand (&ops
[2], op1
, mode
);
1383 create_fixed_operand (&ops
[3], do_error
);
1384 if (maybe_expand_insn (icode
, 4, ops
))
1386 last
= get_last_insn ();
1387 if (profile_status_for_fn (cfun
) != PROFILE_ABSENT
1389 && any_condjump_p (last
)
1390 && !find_reg_note (last
, REG_BR_PROB
, 0))
1391 add_int_reg_note (last
, REG_BR_PROB
, PROB_VERY_UNLIKELY
);
1392 emit_jump (done_label
);
1396 delete_insns_since (last
);
1397 icode
= CODE_FOR_nothing
;
1401 if (icode
== CODE_FOR_nothing
)
1403 struct separate_ops ops
;
1404 int prec
= GET_MODE_PRECISION (mode
);
1405 machine_mode hmode
= mode_for_size (prec
/ 2, MODE_INT
, 1);
1406 ops
.op0
= make_tree (type
, op0
);
1407 ops
.op1
= make_tree (type
, op1
);
1408 ops
.op2
= NULL_TREE
;
1410 if (GET_MODE_2XWIDER_MODE (mode
) != VOIDmode
1411 && targetm
.scalar_mode_supported_p (GET_MODE_2XWIDER_MODE (mode
)))
1413 machine_mode wmode
= GET_MODE_2XWIDER_MODE (mode
);
1414 ops
.code
= WIDEN_MULT_EXPR
;
1416 = build_nonstandard_integer_type (GET_MODE_PRECISION (wmode
), uns
);
1418 res
= expand_expr_real_2 (&ops
, NULL_RTX
, wmode
, EXPAND_NORMAL
);
1419 rtx hipart
= expand_shift (RSHIFT_EXPR
, wmode
, res
, prec
,
1421 hipart
= convert_modes (mode
, wmode
, hipart
, uns
);
1422 res
= convert_modes (mode
, wmode
, res
, uns
);
1424 /* For the unsigned multiplication, there was overflow if
1425 HIPART is non-zero. */
1426 do_compare_rtx_and_jump (hipart
, const0_rtx
, EQ
, true, mode
,
1427 NULL_RTX
, NULL
, done_label
,
1431 rtx signbit
= expand_shift (RSHIFT_EXPR
, mode
, res
, prec
- 1,
1433 /* RES is low half of the double width result, HIPART
1434 the high half. There was overflow if
1435 HIPART is different from RES < 0 ? -1 : 0. */
1436 do_compare_rtx_and_jump (signbit
, hipart
, EQ
, true, mode
,
1437 NULL_RTX
, NULL
, done_label
,
1441 else if (hmode
!= BLKmode
&& 2 * GET_MODE_PRECISION (hmode
) == prec
)
1443 rtx_code_label
*large_op0
= gen_label_rtx ();
1444 rtx_code_label
*small_op0_large_op1
= gen_label_rtx ();
1445 rtx_code_label
*one_small_one_large
= gen_label_rtx ();
1446 rtx_code_label
*both_ops_large
= gen_label_rtx ();
1447 rtx_code_label
*after_hipart_neg
= uns
? NULL
: gen_label_rtx ();
1448 rtx_code_label
*after_lopart_neg
= uns
? NULL
: gen_label_rtx ();
1449 rtx_code_label
*do_overflow
= gen_label_rtx ();
1450 rtx_code_label
*hipart_different
= uns
? NULL
: gen_label_rtx ();
1452 unsigned int hprec
= GET_MODE_PRECISION (hmode
);
1453 rtx hipart0
= expand_shift (RSHIFT_EXPR
, mode
, op0
, hprec
,
1455 hipart0
= convert_modes (hmode
, mode
, hipart0
, uns
);
1456 rtx lopart0
= convert_modes (hmode
, mode
, op0
, uns
);
1457 rtx signbit0
= const0_rtx
;
1459 signbit0
= expand_shift (RSHIFT_EXPR
, hmode
, lopart0
, hprec
- 1,
1461 rtx hipart1
= expand_shift (RSHIFT_EXPR
, mode
, op1
, hprec
,
1463 hipart1
= convert_modes (hmode
, mode
, hipart1
, uns
);
1464 rtx lopart1
= convert_modes (hmode
, mode
, op1
, uns
);
1465 rtx signbit1
= const0_rtx
;
1467 signbit1
= expand_shift (RSHIFT_EXPR
, hmode
, lopart1
, hprec
- 1,
1470 res
= gen_reg_rtx (mode
);
1472 /* True if op0 resp. op1 are known to be in the range of
1474 bool op0_small_p
= false;
1475 bool op1_small_p
= false;
1476 /* True if op0 resp. op1 are known to have all zeros or all ones
1477 in the upper half of bits, but are not known to be
1479 bool op0_medium_p
= false;
1480 bool op1_medium_p
= false;
1481 /* -1 if op{0,1} is known to be negative, 0 if it is known to be
1482 nonnegative, 1 if unknown. */
1488 else if (pos_neg0
== 2)
1492 else if (pos_neg1
== 2)
1495 unsigned int mprec0
= prec
;
1496 if (arg0
!= error_mark_node
)
1497 mprec0
= get_min_precision (arg0
, sign
);
1498 if (mprec0
<= hprec
)
1500 else if (!uns
&& mprec0
<= hprec
+ 1)
1501 op0_medium_p
= true;
1502 unsigned int mprec1
= prec
;
1503 if (arg1
!= error_mark_node
)
1504 mprec1
= get_min_precision (arg1
, sign
);
1505 if (mprec1
<= hprec
)
1507 else if (!uns
&& mprec1
<= hprec
+ 1)
1508 op1_medium_p
= true;
1510 int smaller_sign
= 1;
1511 int larger_sign
= 1;
1514 smaller_sign
= op0_sign
;
1515 larger_sign
= op1_sign
;
1517 else if (op1_small_p
)
1519 smaller_sign
= op1_sign
;
1520 larger_sign
= op0_sign
;
1522 else if (op0_sign
== op1_sign
)
1524 smaller_sign
= op0_sign
;
1525 larger_sign
= op0_sign
;
1529 do_compare_rtx_and_jump (signbit0
, hipart0
, NE
, true, hmode
,
1530 NULL_RTX
, NULL
, large_op0
,
1534 do_compare_rtx_and_jump (signbit1
, hipart1
, NE
, true, hmode
,
1535 NULL_RTX
, NULL
, small_op0_large_op1
,
1538 /* If both op0 and op1 are sign (!uns) or zero (uns) extended from
1539 hmode to mode, the multiplication will never overflow. We can
1540 do just one hmode x hmode => mode widening multiplication. */
1541 rtx lopart0s
= lopart0
, lopart1s
= lopart1
;
1542 if (GET_CODE (lopart0
) == SUBREG
)
1544 lopart0s
= shallow_copy_rtx (lopart0
);
1545 SUBREG_PROMOTED_VAR_P (lopart0s
) = 1;
1546 SUBREG_PROMOTED_SET (lopart0s
, uns
? SRP_UNSIGNED
: SRP_SIGNED
);
1548 if (GET_CODE (lopart1
) == SUBREG
)
1550 lopart1s
= shallow_copy_rtx (lopart1
);
1551 SUBREG_PROMOTED_VAR_P (lopart1s
) = 1;
1552 SUBREG_PROMOTED_SET (lopart1s
, uns
? SRP_UNSIGNED
: SRP_SIGNED
);
1554 tree halfstype
= build_nonstandard_integer_type (hprec
, uns
);
1555 ops
.op0
= make_tree (halfstype
, lopart0s
);
1556 ops
.op1
= make_tree (halfstype
, lopart1s
);
1557 ops
.code
= WIDEN_MULT_EXPR
;
1560 = expand_expr_real_2 (&ops
, NULL_RTX
, mode
, EXPAND_NORMAL
);
1561 emit_move_insn (res
, thisres
);
1562 emit_jump (done_label
);
1564 emit_label (small_op0_large_op1
);
1566 /* If op0 is sign (!uns) or zero (uns) extended from hmode to mode,
1567 but op1 is not, just swap the arguments and handle it as op1
1568 sign/zero extended, op0 not. */
1569 rtx larger
= gen_reg_rtx (mode
);
1570 rtx hipart
= gen_reg_rtx (hmode
);
1571 rtx lopart
= gen_reg_rtx (hmode
);
1572 emit_move_insn (larger
, op1
);
1573 emit_move_insn (hipart
, hipart1
);
1574 emit_move_insn (lopart
, lopart0
);
1575 emit_jump (one_small_one_large
);
1577 emit_label (large_op0
);
1580 do_compare_rtx_and_jump (signbit1
, hipart1
, NE
, true, hmode
,
1581 NULL_RTX
, NULL
, both_ops_large
,
1584 /* If op1 is sign (!uns) or zero (uns) extended from hmode to mode,
1585 but op0 is not, prepare larger, hipart and lopart pseudos and
1586 handle it together with small_op0_large_op1. */
1587 emit_move_insn (larger
, op0
);
1588 emit_move_insn (hipart
, hipart0
);
1589 emit_move_insn (lopart
, lopart1
);
1591 emit_label (one_small_one_large
);
1593 /* lopart is the low part of the operand that is sign extended
1594 to mode, larger is the other operand, hipart is the
1595 high part of larger and lopart0 and lopart1 are the low parts
1597 We perform lopart0 * lopart1 and lopart * hipart widening
1599 tree halfutype
= build_nonstandard_integer_type (hprec
, 1);
1600 ops
.op0
= make_tree (halfutype
, lopart0
);
1601 ops
.op1
= make_tree (halfutype
, lopart1
);
1603 = expand_expr_real_2 (&ops
, NULL_RTX
, mode
, EXPAND_NORMAL
);
1605 ops
.op0
= make_tree (halfutype
, lopart
);
1606 ops
.op1
= make_tree (halfutype
, hipart
);
1607 rtx loxhi
= gen_reg_rtx (mode
);
1608 rtx tem
= expand_expr_real_2 (&ops
, NULL_RTX
, mode
, EXPAND_NORMAL
);
1609 emit_move_insn (loxhi
, tem
);
1613 /* if (hipart < 0) loxhi -= lopart << (bitsize / 2); */
1614 if (larger_sign
== 0)
1615 emit_jump (after_hipart_neg
);
1616 else if (larger_sign
!= -1)
1617 do_compare_rtx_and_jump (hipart
, const0_rtx
, GE
, false, hmode
,
1618 NULL_RTX
, NULL
, after_hipart_neg
,
1621 tem
= convert_modes (mode
, hmode
, lopart
, 1);
1622 tem
= expand_shift (LSHIFT_EXPR
, mode
, tem
, hprec
, NULL_RTX
, 1);
1623 tem
= expand_simple_binop (mode
, MINUS
, loxhi
, tem
, NULL_RTX
,
1625 emit_move_insn (loxhi
, tem
);
1627 emit_label (after_hipart_neg
);
1629 /* if (lopart < 0) loxhi -= larger; */
1630 if (smaller_sign
== 0)
1631 emit_jump (after_lopart_neg
);
1632 else if (smaller_sign
!= -1)
1633 do_compare_rtx_and_jump (lopart
, const0_rtx
, GE
, false, hmode
,
1634 NULL_RTX
, NULL
, after_lopart_neg
,
1637 tem
= expand_simple_binop (mode
, MINUS
, loxhi
, larger
, NULL_RTX
,
1639 emit_move_insn (loxhi
, tem
);
1641 emit_label (after_lopart_neg
);
1644 /* loxhi += (uns) lo0xlo1 >> (bitsize / 2); */
1645 tem
= expand_shift (RSHIFT_EXPR
, mode
, lo0xlo1
, hprec
, NULL_RTX
, 1);
1646 tem
= expand_simple_binop (mode
, PLUS
, loxhi
, tem
, NULL_RTX
,
1648 emit_move_insn (loxhi
, tem
);
1650 /* if (loxhi >> (bitsize / 2)
1651 == (hmode) loxhi >> (bitsize / 2 - 1)) (if !uns)
1652 if (loxhi >> (bitsize / 2) == 0 (if uns). */
1653 rtx hipartloxhi
= expand_shift (RSHIFT_EXPR
, mode
, loxhi
, hprec
,
1655 hipartloxhi
= convert_modes (hmode
, mode
, hipartloxhi
, 0);
1656 rtx signbitloxhi
= const0_rtx
;
1658 signbitloxhi
= expand_shift (RSHIFT_EXPR
, hmode
,
1659 convert_modes (hmode
, mode
,
1661 hprec
- 1, NULL_RTX
, 0);
1663 do_compare_rtx_and_jump (signbitloxhi
, hipartloxhi
, NE
, true, hmode
,
1664 NULL_RTX
, NULL
, do_overflow
,
1665 PROB_VERY_UNLIKELY
);
1667 /* res = (loxhi << (bitsize / 2)) | (hmode) lo0xlo1; */
1668 rtx loxhishifted
= expand_shift (LSHIFT_EXPR
, mode
, loxhi
, hprec
,
1670 tem
= convert_modes (mode
, hmode
,
1671 convert_modes (hmode
, mode
, lo0xlo1
, 1), 1);
1673 tem
= expand_simple_binop (mode
, IOR
, loxhishifted
, tem
, res
,
1676 emit_move_insn (res
, tem
);
1677 emit_jump (done_label
);
1679 emit_label (both_ops_large
);
1681 /* If both operands are large (not sign (!uns) or zero (uns)
1682 extended from hmode), then perform the full multiplication
1683 which will be the result of the operation.
1684 The only cases which don't overflow are for signed multiplication
1685 some cases where both hipart0 and highpart1 are 0 or -1.
1686 For unsigned multiplication when high parts are both non-zero
1687 this overflows always. */
1688 ops
.code
= MULT_EXPR
;
1689 ops
.op0
= make_tree (type
, op0
);
1690 ops
.op1
= make_tree (type
, op1
);
1691 tem
= expand_expr_real_2 (&ops
, NULL_RTX
, mode
, EXPAND_NORMAL
);
1692 emit_move_insn (res
, tem
);
1698 tem
= expand_simple_binop (hmode
, PLUS
, hipart0
, const1_rtx
,
1699 NULL_RTX
, 1, OPTAB_DIRECT
);
1700 do_compare_rtx_and_jump (tem
, const1_rtx
, GTU
, true, hmode
,
1701 NULL_RTX
, NULL
, do_error
,
1702 PROB_VERY_UNLIKELY
);
1707 tem
= expand_simple_binop (hmode
, PLUS
, hipart1
, const1_rtx
,
1708 NULL_RTX
, 1, OPTAB_DIRECT
);
1709 do_compare_rtx_and_jump (tem
, const1_rtx
, GTU
, true, hmode
,
1710 NULL_RTX
, NULL
, do_error
,
1711 PROB_VERY_UNLIKELY
);
1714 /* At this point hipart{0,1} are both in [-1, 0]. If they are
1715 the same, overflow happened if res is negative, if they are
1716 different, overflow happened if res is positive. */
1717 if (op0_sign
!= 1 && op1_sign
!= 1 && op0_sign
!= op1_sign
)
1718 emit_jump (hipart_different
);
1719 else if (op0_sign
== 1 || op1_sign
== 1)
1720 do_compare_rtx_and_jump (hipart0
, hipart1
, NE
, true, hmode
,
1721 NULL_RTX
, NULL
, hipart_different
,
1724 do_compare_rtx_and_jump (res
, const0_rtx
, LT
, false, mode
,
1725 NULL_RTX
, NULL
, do_error
,
1726 PROB_VERY_UNLIKELY
);
1727 emit_jump (done_label
);
1729 emit_label (hipart_different
);
1731 do_compare_rtx_and_jump (res
, const0_rtx
, GE
, false, mode
,
1732 NULL_RTX
, NULL
, do_error
,
1733 PROB_VERY_UNLIKELY
);
1734 emit_jump (done_label
);
1737 emit_label (do_overflow
);
1739 /* Overflow, do full multiplication and fallthru into do_error. */
1740 ops
.op0
= make_tree (type
, op0
);
1741 ops
.op1
= make_tree (type
, op1
);
1742 tem
= expand_expr_real_2 (&ops
, NULL_RTX
, mode
, EXPAND_NORMAL
);
1743 emit_move_insn (res
, tem
);
1747 gcc_assert (!is_ubsan
);
1748 ops
.code
= MULT_EXPR
;
1750 res
= expand_expr_real_2 (&ops
, NULL_RTX
, mode
, EXPAND_NORMAL
);
1751 emit_jump (done_label
);
1756 emit_label (do_error
);
1759 /* Expand the ubsan builtin call. */
1761 fn
= ubsan_build_overflow_builtin (MULT_EXPR
, loc
, TREE_TYPE (arg0
),
1765 do_pending_stack_adjust ();
1768 expand_arith_set_overflow (lhs
, target
);
1771 emit_label (done_label
);
1774 if (uns0_p
&& uns1_p
&& !unsr_p
)
1776 rtx_code_label
*all_done_label
= gen_label_rtx ();
1777 do_compare_rtx_and_jump (res
, const0_rtx
, GE
, false, mode
, NULL_RTX
,
1778 NULL
, all_done_label
, PROB_VERY_LIKELY
);
1779 expand_arith_set_overflow (lhs
, target
);
1780 emit_label (all_done_label
);
1784 if (!uns0_p
&& uns1_p
&& !unsr_p
&& pos_neg1
== 3)
1786 rtx_code_label
*all_done_label
= gen_label_rtx ();
1787 rtx_code_label
*set_noovf
= gen_label_rtx ();
1788 do_compare_rtx_and_jump (op1
, const0_rtx
, GE
, false, mode
, NULL_RTX
,
1789 NULL
, all_done_label
, PROB_VERY_LIKELY
);
1790 expand_arith_set_overflow (lhs
, target
);
1791 do_compare_rtx_and_jump (op0
, const0_rtx
, EQ
, true, mode
, NULL_RTX
,
1792 NULL
, set_noovf
, PROB_VERY_LIKELY
);
1793 do_compare_rtx_and_jump (op0
, constm1_rtx
, NE
, true, mode
, NULL_RTX
,
1794 NULL
, all_done_label
, PROB_VERY_UNLIKELY
);
1795 do_compare_rtx_and_jump (op1
, res
, NE
, true, mode
, NULL_RTX
, NULL
,
1796 all_done_label
, PROB_VERY_UNLIKELY
);
1797 emit_label (set_noovf
);
1798 write_complex_part (target
, const0_rtx
, true);
1799 emit_label (all_done_label
);
1805 expand_ubsan_result_store (target
, res
);
1807 expand_arith_overflow_result_store (lhs
, target
, mode
, res
);
1811 /* Expand UBSAN_CHECK_* internal function if it has vector operands. */
1814 expand_vector_ubsan_overflow (location_t loc
, enum tree_code code
, tree lhs
,
1815 tree arg0
, tree arg1
)
1817 int cnt
= TYPE_VECTOR_SUBPARTS (TREE_TYPE (arg0
));
1818 rtx_code_label
*loop_lab
= NULL
;
1819 rtx cntvar
= NULL_RTX
;
1820 tree cntv
= NULL_TREE
;
1821 tree eltype
= TREE_TYPE (TREE_TYPE (arg0
));
1822 tree sz
= TYPE_SIZE (eltype
);
1823 tree data
= NULL_TREE
;
1824 tree resv
= NULL_TREE
;
1825 rtx lhsr
= NULL_RTX
;
1826 rtx resvr
= NULL_RTX
;
1831 lhsr
= expand_expr (lhs
, NULL_RTX
, VOIDmode
, EXPAND_WRITE
);
1832 if (!VECTOR_MODE_P (GET_MODE (lhsr
))
1833 || (op
= optab_for_tree_code (code
, TREE_TYPE (arg0
),
1834 optab_default
)) == unknown_optab
1835 || (optab_handler (op
, TYPE_MODE (TREE_TYPE (arg0
)))
1836 == CODE_FOR_nothing
))
1839 resv
= make_tree (TREE_TYPE (lhs
), lhsr
);
1842 resvr
= assign_temp (TREE_TYPE (lhs
), 1, 1);
1843 resv
= make_tree (TREE_TYPE (lhs
), resvr
);
1849 do_pending_stack_adjust ();
1850 loop_lab
= gen_label_rtx ();
1851 cntvar
= gen_reg_rtx (TYPE_MODE (sizetype
));
1852 cntv
= make_tree (sizetype
, cntvar
);
1853 emit_move_insn (cntvar
, const0_rtx
);
1854 emit_label (loop_lab
);
1856 if (TREE_CODE (arg0
) != VECTOR_CST
)
1858 rtx arg0r
= expand_normal (arg0
);
1859 arg0
= make_tree (TREE_TYPE (arg0
), arg0r
);
1861 if (TREE_CODE (arg1
) != VECTOR_CST
)
1863 rtx arg1r
= expand_normal (arg1
);
1864 arg1
= make_tree (TREE_TYPE (arg1
), arg1r
);
1866 for (int i
= 0; i
< (cnt
> 4 ? 1 : cnt
); i
++)
1868 tree op0
, op1
, res
= NULL_TREE
;
1871 tree atype
= build_array_type_nelts (eltype
, cnt
);
1872 op0
= uniform_vector_p (arg0
);
1873 if (op0
== NULL_TREE
)
1875 op0
= fold_build1_loc (loc
, VIEW_CONVERT_EXPR
, atype
, arg0
);
1876 op0
= build4_loc (loc
, ARRAY_REF
, eltype
, op0
, cntv
,
1877 NULL_TREE
, NULL_TREE
);
1879 op1
= uniform_vector_p (arg1
);
1880 if (op1
== NULL_TREE
)
1882 op1
= fold_build1_loc (loc
, VIEW_CONVERT_EXPR
, atype
, arg1
);
1883 op1
= build4_loc (loc
, ARRAY_REF
, eltype
, op1
, cntv
,
1884 NULL_TREE
, NULL_TREE
);
1888 res
= fold_build1_loc (loc
, VIEW_CONVERT_EXPR
, atype
, resv
);
1889 res
= build4_loc (loc
, ARRAY_REF
, eltype
, res
, cntv
,
1890 NULL_TREE
, NULL_TREE
);
1895 tree bitpos
= bitsize_int (tree_to_uhwi (sz
) * i
);
1896 op0
= fold_build3_loc (loc
, BIT_FIELD_REF
, eltype
, arg0
, sz
, bitpos
);
1897 op1
= fold_build3_loc (loc
, BIT_FIELD_REF
, eltype
, arg1
, sz
, bitpos
);
1899 res
= fold_build3_loc (loc
, BIT_FIELD_REF
, eltype
, resv
, sz
,
1905 expand_addsub_overflow (loc
, PLUS_EXPR
, res
, op0
, op1
,
1906 false, false, false, true, &data
);
1909 if (cnt
> 4 ? integer_zerop (arg0
) : integer_zerop (op0
))
1910 expand_neg_overflow (loc
, res
, op1
, true, &data
);
1912 expand_addsub_overflow (loc
, MINUS_EXPR
, res
, op0
, op1
,
1913 false, false, false, true, &data
);
1916 expand_mul_overflow (loc
, res
, op0
, op1
, false, false, false,
1925 struct separate_ops ops
;
1926 ops
.code
= PLUS_EXPR
;
1927 ops
.type
= TREE_TYPE (cntv
);
1929 ops
.op1
= build_int_cst (TREE_TYPE (cntv
), 1);
1930 ops
.op2
= NULL_TREE
;
1932 rtx ret
= expand_expr_real_2 (&ops
, cntvar
, TYPE_MODE (sizetype
),
1935 emit_move_insn (cntvar
, ret
);
1936 do_compare_rtx_and_jump (cntvar
, GEN_INT (cnt
), NE
, false,
1937 TYPE_MODE (sizetype
), NULL_RTX
, NULL
, loop_lab
,
1940 if (lhs
&& resv
== NULL_TREE
)
1942 struct separate_ops ops
;
1944 ops
.type
= TREE_TYPE (arg0
);
1947 ops
.op2
= NULL_TREE
;
1949 rtx ret
= expand_expr_real_2 (&ops
, lhsr
, TYPE_MODE (TREE_TYPE (arg0
)),
1952 emit_move_insn (lhsr
, ret
);
1955 emit_move_insn (lhsr
, resvr
);
1958 /* Expand UBSAN_CHECK_ADD call STMT. */
1961 expand_UBSAN_CHECK_ADD (internal_fn
, gcall
*stmt
)
1963 location_t loc
= gimple_location (stmt
);
1964 tree lhs
= gimple_call_lhs (stmt
);
1965 tree arg0
= gimple_call_arg (stmt
, 0);
1966 tree arg1
= gimple_call_arg (stmt
, 1);
1967 if (VECTOR_TYPE_P (TREE_TYPE (arg0
)))
1968 expand_vector_ubsan_overflow (loc
, PLUS_EXPR
, lhs
, arg0
, arg1
);
1970 expand_addsub_overflow (loc
, PLUS_EXPR
, lhs
, arg0
, arg1
,
1971 false, false, false, true, NULL
);
1974 /* Expand UBSAN_CHECK_SUB call STMT. */
1977 expand_UBSAN_CHECK_SUB (internal_fn
, gcall
*stmt
)
1979 location_t loc
= gimple_location (stmt
);
1980 tree lhs
= gimple_call_lhs (stmt
);
1981 tree arg0
= gimple_call_arg (stmt
, 0);
1982 tree arg1
= gimple_call_arg (stmt
, 1);
1983 if (VECTOR_TYPE_P (TREE_TYPE (arg0
)))
1984 expand_vector_ubsan_overflow (loc
, MINUS_EXPR
, lhs
, arg0
, arg1
);
1985 else if (integer_zerop (arg0
))
1986 expand_neg_overflow (loc
, lhs
, arg1
, true, NULL
);
1988 expand_addsub_overflow (loc
, MINUS_EXPR
, lhs
, arg0
, arg1
,
1989 false, false, false, true, NULL
);
1992 /* Expand UBSAN_CHECK_MUL call STMT. */
1995 expand_UBSAN_CHECK_MUL (internal_fn
, gcall
*stmt
)
1997 location_t loc
= gimple_location (stmt
);
1998 tree lhs
= gimple_call_lhs (stmt
);
1999 tree arg0
= gimple_call_arg (stmt
, 0);
2000 tree arg1
= gimple_call_arg (stmt
, 1);
2001 if (VECTOR_TYPE_P (TREE_TYPE (arg0
)))
2002 expand_vector_ubsan_overflow (loc
, MULT_EXPR
, lhs
, arg0
, arg1
);
2004 expand_mul_overflow (loc
, lhs
, arg0
, arg1
, false, false, false, true,
2008 /* Helper function for {ADD,SUB,MUL}_OVERFLOW call stmt expansion. */
2011 expand_arith_overflow (enum tree_code code
, gimple
*stmt
)
2013 tree lhs
= gimple_call_lhs (stmt
);
2014 if (lhs
== NULL_TREE
)
2016 tree arg0
= gimple_call_arg (stmt
, 0);
2017 tree arg1
= gimple_call_arg (stmt
, 1);
2018 tree type
= TREE_TYPE (TREE_TYPE (lhs
));
2019 int uns0_p
= TYPE_UNSIGNED (TREE_TYPE (arg0
));
2020 int uns1_p
= TYPE_UNSIGNED (TREE_TYPE (arg1
));
2021 int unsr_p
= TYPE_UNSIGNED (type
);
2022 int prec0
= TYPE_PRECISION (TREE_TYPE (arg0
));
2023 int prec1
= TYPE_PRECISION (TREE_TYPE (arg1
));
2024 int precres
= TYPE_PRECISION (type
);
2025 location_t loc
= gimple_location (stmt
);
2026 if (!uns0_p
&& get_range_pos_neg (arg0
) == 1)
2028 if (!uns1_p
&& get_range_pos_neg (arg1
) == 1)
2030 int pr
= get_min_precision (arg0
, uns0_p
? UNSIGNED
: SIGNED
);
2031 prec0
= MIN (prec0
, pr
);
2032 pr
= get_min_precision (arg1
, uns1_p
? UNSIGNED
: SIGNED
);
2033 prec1
= MIN (prec1
, pr
);
2035 /* If uns0_p && uns1_p, precop is minimum needed precision
2036 of unsigned type to hold the exact result, otherwise
2037 precop is minimum needed precision of signed type to
2038 hold the exact result. */
2040 if (code
== MULT_EXPR
)
2041 precop
= prec0
+ prec1
+ (uns0_p
!= uns1_p
);
2044 if (uns0_p
== uns1_p
)
2045 precop
= MAX (prec0
, prec1
) + 1;
2047 precop
= MAX (prec0
+ 1, prec1
) + 1;
2049 precop
= MAX (prec0
, prec1
+ 1) + 1;
2051 int orig_precres
= precres
;
2055 if ((uns0_p
&& uns1_p
)
2056 ? ((precop
+ !unsr_p
) <= precres
2057 /* u1 - u2 -> ur can overflow, no matter what precision
2059 && (code
!= MINUS_EXPR
|| !unsr_p
))
2060 : (!unsr_p
&& precop
<= precres
))
2062 /* The infinity precision result will always fit into result. */
2063 rtx target
= expand_expr (lhs
, NULL_RTX
, VOIDmode
, EXPAND_WRITE
);
2064 write_complex_part (target
, const0_rtx
, true);
2065 enum machine_mode mode
= TYPE_MODE (type
);
2066 struct separate_ops ops
;
2069 ops
.op0
= fold_convert_loc (loc
, type
, arg0
);
2070 ops
.op1
= fold_convert_loc (loc
, type
, arg1
);
2071 ops
.op2
= NULL_TREE
;
2073 rtx tem
= expand_expr_real_2 (&ops
, NULL_RTX
, mode
, EXPAND_NORMAL
);
2074 expand_arith_overflow_result_store (lhs
, target
, mode
, tem
);
2078 /* For operations with low precision, if target doesn't have them, start
2079 with precres widening right away, otherwise do it only if the most
2080 simple cases can't be used. */
2081 const int min_precision
= targetm
.min_arithmetic_precision ();
2082 if (orig_precres
== precres
&& precres
< min_precision
)
2084 else if ((uns0_p
&& uns1_p
&& unsr_p
&& prec0
<= precres
2085 && prec1
<= precres
)
2086 || ((!uns0_p
|| !uns1_p
) && !unsr_p
2087 && prec0
+ uns0_p
<= precres
2088 && prec1
+ uns1_p
<= precres
))
2090 arg0
= fold_convert_loc (loc
, type
, arg0
);
2091 arg1
= fold_convert_loc (loc
, type
, arg1
);
2095 if (integer_zerop (arg0
) && !unsr_p
)
2097 expand_neg_overflow (loc
, lhs
, arg1
, false, NULL
);
2102 expand_addsub_overflow (loc
, code
, lhs
, arg0
, arg1
, unsr_p
,
2103 unsr_p
, unsr_p
, false, NULL
);
2106 expand_mul_overflow (loc
, lhs
, arg0
, arg1
, unsr_p
,
2107 unsr_p
, unsr_p
, false, NULL
);
2114 /* For sub-word operations, retry with a wider type first. */
2115 if (orig_precres
== precres
&& precop
<= BITS_PER_WORD
)
2117 int p
= MAX (min_precision
, precop
);
2118 enum machine_mode m
= smallest_mode_for_size (p
, MODE_INT
);
2119 tree optype
= build_nonstandard_integer_type (GET_MODE_PRECISION (m
),
2122 p
= TYPE_PRECISION (optype
);
2126 unsr_p
= TYPE_UNSIGNED (optype
);
2132 if (prec0
<= precres
&& prec1
<= precres
)
2137 types
[0] = build_nonstandard_integer_type (precres
, 0);
2143 types
[1] = build_nonstandard_integer_type (precres
, 1);
2145 arg0
= fold_convert_loc (loc
, types
[uns0_p
], arg0
);
2146 arg1
= fold_convert_loc (loc
, types
[uns1_p
], arg1
);
2147 if (code
!= MULT_EXPR
)
2148 expand_addsub_overflow (loc
, code
, lhs
, arg0
, arg1
, unsr_p
,
2149 uns0_p
, uns1_p
, false, NULL
);
2151 expand_mul_overflow (loc
, lhs
, arg0
, arg1
, unsr_p
,
2152 uns0_p
, uns1_p
, false, NULL
);
2156 /* Retry with a wider type. */
2157 if (orig_precres
== precres
)
2159 int p
= MAX (prec0
, prec1
);
2160 enum machine_mode m
= smallest_mode_for_size (p
, MODE_INT
);
2161 tree optype
= build_nonstandard_integer_type (GET_MODE_PRECISION (m
),
2164 p
= TYPE_PRECISION (optype
);
2168 unsr_p
= TYPE_UNSIGNED (optype
);
2179 /* Expand ADD_OVERFLOW STMT. */
2182 expand_ADD_OVERFLOW (internal_fn
, gcall
*stmt
)
2184 expand_arith_overflow (PLUS_EXPR
, stmt
);
2187 /* Expand SUB_OVERFLOW STMT. */
2190 expand_SUB_OVERFLOW (internal_fn
, gcall
*stmt
)
2192 expand_arith_overflow (MINUS_EXPR
, stmt
);
2195 /* Expand MUL_OVERFLOW STMT. */
2198 expand_MUL_OVERFLOW (internal_fn
, gcall
*stmt
)
2200 expand_arith_overflow (MULT_EXPR
, stmt
);
2203 /* This should get folded in tree-vectorizer.c. */
2206 expand_LOOP_VECTORIZED (internal_fn
, gcall
*)
2211 /* Expand MASK_LOAD call STMT using optab OPTAB. */
2214 expand_mask_load_optab_fn (internal_fn
, gcall
*stmt
, convert_optab optab
)
2216 struct expand_operand ops
[3];
2217 tree type
, lhs
, rhs
, maskt
, ptr
;
2218 rtx mem
, target
, mask
;
2221 maskt
= gimple_call_arg (stmt
, 2);
2222 lhs
= gimple_call_lhs (stmt
);
2223 if (lhs
== NULL_TREE
)
2225 type
= TREE_TYPE (lhs
);
2226 ptr
= build_int_cst (TREE_TYPE (gimple_call_arg (stmt
, 1)), 0);
2227 align
= tree_to_shwi (gimple_call_arg (stmt
, 1));
2228 if (TYPE_ALIGN (type
) != align
)
2229 type
= build_aligned_type (type
, align
);
2230 rhs
= fold_build2 (MEM_REF
, type
, gimple_call_arg (stmt
, 0), ptr
);
2232 mem
= expand_expr (rhs
, NULL_RTX
, VOIDmode
, EXPAND_WRITE
);
2233 gcc_assert (MEM_P (mem
));
2234 mask
= expand_normal (maskt
);
2235 target
= expand_expr (lhs
, NULL_RTX
, VOIDmode
, EXPAND_WRITE
);
2236 create_output_operand (&ops
[0], target
, TYPE_MODE (type
));
2237 create_fixed_operand (&ops
[1], mem
);
2238 create_input_operand (&ops
[2], mask
, TYPE_MODE (TREE_TYPE (maskt
)));
2239 expand_insn (convert_optab_handler (optab
, TYPE_MODE (type
),
2240 TYPE_MODE (TREE_TYPE (maskt
))),
2244 /* Expand MASK_STORE call STMT using optab OPTAB. */
2247 expand_mask_store_optab_fn (internal_fn
, gcall
*stmt
, convert_optab optab
)
2249 struct expand_operand ops
[3];
2250 tree type
, lhs
, rhs
, maskt
, ptr
;
2254 maskt
= gimple_call_arg (stmt
, 2);
2255 rhs
= gimple_call_arg (stmt
, 3);
2256 type
= TREE_TYPE (rhs
);
2257 ptr
= build_int_cst (TREE_TYPE (gimple_call_arg (stmt
, 1)), 0);
2258 align
= tree_to_shwi (gimple_call_arg (stmt
, 1));
2259 if (TYPE_ALIGN (type
) != align
)
2260 type
= build_aligned_type (type
, align
);
2261 lhs
= fold_build2 (MEM_REF
, type
, gimple_call_arg (stmt
, 0), ptr
);
2263 mem
= expand_expr (lhs
, NULL_RTX
, VOIDmode
, EXPAND_WRITE
);
2264 gcc_assert (MEM_P (mem
));
2265 mask
= expand_normal (maskt
);
2266 reg
= expand_normal (rhs
);
2267 create_fixed_operand (&ops
[0], mem
);
2268 create_input_operand (&ops
[1], reg
, TYPE_MODE (type
));
2269 create_input_operand (&ops
[2], mask
, TYPE_MODE (TREE_TYPE (maskt
)));
2270 expand_insn (convert_optab_handler (optab
, TYPE_MODE (type
),
2271 TYPE_MODE (TREE_TYPE (maskt
))),
2276 expand_ABNORMAL_DISPATCHER (internal_fn
, gcall
*)
2281 expand_BUILTIN_EXPECT (internal_fn
, gcall
*stmt
)
2283 /* When guessing was done, the hints should be already stripped away. */
2284 gcc_assert (!flag_guess_branch_prob
|| optimize
== 0 || seen_error ());
2287 tree lhs
= gimple_call_lhs (stmt
);
2289 target
= expand_expr (lhs
, NULL_RTX
, VOIDmode
, EXPAND_WRITE
);
2291 target
= const0_rtx
;
2292 rtx val
= expand_expr (gimple_call_arg (stmt
, 0), target
, VOIDmode
, EXPAND_NORMAL
);
2293 if (lhs
&& val
!= target
)
2294 emit_move_insn (target
, val
);
2297 /* IFN_VA_ARG is supposed to be expanded at pass_stdarg. So this dummy function
2298 should never be called. */
2301 expand_VA_ARG (internal_fn
, gcall
*)
2306 /* Expand the IFN_UNIQUE function according to its first argument. */
2309 expand_UNIQUE (internal_fn
, gcall
*stmt
)
2311 rtx pattern
= NULL_RTX
;
2312 enum ifn_unique_kind kind
2313 = (enum ifn_unique_kind
) TREE_INT_CST_LOW (gimple_call_arg (stmt
, 0));
2320 case IFN_UNIQUE_UNSPEC
:
2321 if (targetm
.have_unique ())
2322 pattern
= targetm
.gen_unique ();
2325 case IFN_UNIQUE_OACC_FORK
:
2326 case IFN_UNIQUE_OACC_JOIN
:
2327 if (targetm
.have_oacc_fork () && targetm
.have_oacc_join ())
2329 tree lhs
= gimple_call_lhs (stmt
);
2330 rtx target
= const0_rtx
;
2333 target
= expand_expr (lhs
, NULL_RTX
, VOIDmode
, EXPAND_WRITE
);
2335 rtx data_dep
= expand_normal (gimple_call_arg (stmt
, 1));
2336 rtx axis
= expand_normal (gimple_call_arg (stmt
, 2));
2338 if (kind
== IFN_UNIQUE_OACC_FORK
)
2339 pattern
= targetm
.gen_oacc_fork (target
, data_dep
, axis
);
2341 pattern
= targetm
.gen_oacc_join (target
, data_dep
, axis
);
2349 emit_insn (pattern
);
2352 /* The size of an OpenACC compute dimension. */
2355 expand_GOACC_DIM_SIZE (internal_fn
, gcall
*stmt
)
2357 tree lhs
= gimple_call_lhs (stmt
);
2362 rtx target
= expand_expr (lhs
, NULL_RTX
, VOIDmode
, EXPAND_WRITE
);
2363 if (targetm
.have_oacc_dim_size ())
2365 rtx dim
= expand_expr (gimple_call_arg (stmt
, 0), NULL_RTX
,
2366 VOIDmode
, EXPAND_NORMAL
);
2367 emit_insn (targetm
.gen_oacc_dim_size (target
, dim
));
2370 emit_move_insn (target
, GEN_INT (1));
2373 /* The position of an OpenACC execution engine along one compute axis. */
2376 expand_GOACC_DIM_POS (internal_fn
, gcall
*stmt
)
2378 tree lhs
= gimple_call_lhs (stmt
);
2383 rtx target
= expand_expr (lhs
, NULL_RTX
, VOIDmode
, EXPAND_WRITE
);
2384 if (targetm
.have_oacc_dim_pos ())
2386 rtx dim
= expand_expr (gimple_call_arg (stmt
, 0), NULL_RTX
,
2387 VOIDmode
, EXPAND_NORMAL
);
2388 emit_insn (targetm
.gen_oacc_dim_pos (target
, dim
));
2391 emit_move_insn (target
, const0_rtx
);
2394 /* This is expanded by oacc_device_lower pass. */
2397 expand_GOACC_LOOP (internal_fn
, gcall
*)
2402 /* This is expanded by oacc_device_lower pass. */
2405 expand_GOACC_REDUCTION (internal_fn
, gcall
*)
2410 /* This is expanded by oacc_device_lower pass. */
2413 expand_GOACC_TILE (internal_fn
, gcall
*)
2418 /* Set errno to EDOM. */
2421 expand_SET_EDOM (internal_fn
, gcall
*)
2424 #ifdef GEN_ERRNO_RTX
2425 rtx errno_rtx
= GEN_ERRNO_RTX
;
2427 rtx errno_rtx
= gen_rtx_MEM (word_mode
, gen_rtx_SYMBOL_REF (Pmode
, "errno"));
2429 emit_move_insn (errno_rtx
,
2430 gen_int_mode (TARGET_EDOM
, GET_MODE (errno_rtx
)));
2436 /* Expand atomic bit test and set. */
2439 expand_ATOMIC_BIT_TEST_AND_SET (internal_fn
, gcall
*call
)
2441 expand_ifn_atomic_bit_test_and (call
);
2444 /* Expand atomic bit test and complement. */
2447 expand_ATOMIC_BIT_TEST_AND_COMPLEMENT (internal_fn
, gcall
*call
)
2449 expand_ifn_atomic_bit_test_and (call
);
2452 /* Expand atomic bit test and reset. */
2455 expand_ATOMIC_BIT_TEST_AND_RESET (internal_fn
, gcall
*call
)
2457 expand_ifn_atomic_bit_test_and (call
);
2460 /* Expand atomic bit test and set. */
2463 expand_ATOMIC_COMPARE_EXCHANGE (internal_fn
, gcall
*call
)
2465 expand_ifn_atomic_compare_exchange (call
);
2468 /* Expand LAUNDER to assignment, lhs = arg0. */
2471 expand_LAUNDER (internal_fn
, gcall
*call
)
2473 tree lhs
= gimple_call_lhs (call
);
2478 expand_assignment (lhs
, gimple_call_arg (call
, 0), false);
2481 /* Expand DIVMOD() using:
2482 a) optab handler for udivmod/sdivmod if it is available.
2483 b) If optab_handler doesn't exist, generate call to
2484 target-specific divmod libfunc. */
2487 expand_DIVMOD (internal_fn
, gcall
*call_stmt
)
2489 tree lhs
= gimple_call_lhs (call_stmt
);
2490 tree arg0
= gimple_call_arg (call_stmt
, 0);
2491 tree arg1
= gimple_call_arg (call_stmt
, 1);
2493 gcc_assert (TREE_CODE (TREE_TYPE (lhs
)) == COMPLEX_TYPE
);
2494 tree type
= TREE_TYPE (TREE_TYPE (lhs
));
2495 machine_mode mode
= TYPE_MODE (type
);
2496 bool unsignedp
= TYPE_UNSIGNED (type
);
2497 optab tab
= (unsignedp
) ? udivmod_optab
: sdivmod_optab
;
2499 rtx op0
= expand_normal (arg0
);
2500 rtx op1
= expand_normal (arg1
);
2501 rtx target
= expand_expr (lhs
, NULL_RTX
, VOIDmode
, EXPAND_WRITE
);
2503 rtx quotient
, remainder
, libfunc
;
2505 /* Check if optab_handler exists for divmod_optab for given mode. */
2506 if (optab_handler (tab
, mode
) != CODE_FOR_nothing
)
2508 quotient
= gen_reg_rtx (mode
);
2509 remainder
= gen_reg_rtx (mode
);
2510 expand_twoval_binop (tab
, op0
, op1
, quotient
, remainder
, unsignedp
);
2513 /* Generate call to divmod libfunc if it exists. */
2514 else if ((libfunc
= optab_libfunc (tab
, mode
)) != NULL_RTX
)
2515 targetm
.expand_divmod_libfunc (libfunc
, mode
, op0
, op1
,
2516 "ient
, &remainder
);
2521 /* Wrap the return value (quotient, remainder) within COMPLEX_EXPR. */
2522 expand_expr (build2 (COMPLEX_EXPR
, TREE_TYPE (lhs
),
2523 make_tree (TREE_TYPE (arg0
), quotient
),
2524 make_tree (TREE_TYPE (arg1
), remainder
)),
2525 target
, VOIDmode
, EXPAND_NORMAL
);
2528 /* Expand a call to FN using the operands in STMT. FN has a single
2529 output operand and NARGS input operands. */
2532 expand_direct_optab_fn (internal_fn fn
, gcall
*stmt
, direct_optab optab
,
2535 expand_operand
*ops
= XALLOCAVEC (expand_operand
, nargs
+ 1);
2537 tree_pair types
= direct_internal_fn_types (fn
, stmt
);
2538 insn_code icode
= direct_optab_handler (optab
, TYPE_MODE (types
.first
));
2540 tree lhs
= gimple_call_lhs (stmt
);
2541 tree lhs_type
= TREE_TYPE (lhs
);
2542 rtx lhs_rtx
= expand_expr (lhs
, NULL_RTX
, VOIDmode
, EXPAND_WRITE
);
2543 create_output_operand (&ops
[0], lhs_rtx
, insn_data
[icode
].operand
[0].mode
);
2545 for (unsigned int i
= 0; i
< nargs
; ++i
)
2547 tree rhs
= gimple_call_arg (stmt
, i
);
2548 tree rhs_type
= TREE_TYPE (rhs
);
2549 rtx rhs_rtx
= expand_normal (rhs
);
2550 if (INTEGRAL_TYPE_P (rhs_type
))
2551 create_convert_operand_from (&ops
[i
+ 1], rhs_rtx
,
2552 TYPE_MODE (rhs_type
),
2553 TYPE_UNSIGNED (rhs_type
));
2555 create_input_operand (&ops
[i
+ 1], rhs_rtx
, TYPE_MODE (rhs_type
));
2558 expand_insn (icode
, nargs
+ 1, ops
);
2559 if (!rtx_equal_p (lhs_rtx
, ops
[0].value
))
2561 /* If the return value has an integral type, convert the instruction
2562 result to that type. This is useful for things that return an
2563 int regardless of the size of the input. If the instruction result
2564 is smaller than required, assume that it is signed.
2566 If the return value has a nonintegral type, its mode must match
2567 the instruction result. */
2568 if (GET_CODE (lhs_rtx
) == SUBREG
&& SUBREG_PROMOTED_VAR_P (lhs_rtx
))
2570 /* If this is a scalar in a register that is stored in a wider
2571 mode than the declared mode, compute the result into its
2572 declared mode and then convert to the wider mode. */
2573 gcc_checking_assert (INTEGRAL_TYPE_P (lhs_type
));
2574 rtx tmp
= convert_to_mode (GET_MODE (lhs_rtx
), ops
[0].value
, 0);
2575 convert_move (SUBREG_REG (lhs_rtx
), tmp
,
2576 SUBREG_PROMOTED_SIGN (lhs_rtx
));
2578 else if (GET_MODE (lhs_rtx
) == GET_MODE (ops
[0].value
))
2579 emit_move_insn (lhs_rtx
, ops
[0].value
);
2582 gcc_checking_assert (INTEGRAL_TYPE_P (lhs_type
));
2583 convert_move (lhs_rtx
, ops
[0].value
, 0);
2588 /* Expanders for optabs that can use expand_direct_optab_fn. */
2590 #define expand_unary_optab_fn(FN, STMT, OPTAB) \
2591 expand_direct_optab_fn (FN, STMT, OPTAB, 1)
2593 #define expand_binary_optab_fn(FN, STMT, OPTAB) \
2594 expand_direct_optab_fn (FN, STMT, OPTAB, 2)
2596 /* RETURN_TYPE and ARGS are a return type and argument list that are
2597 in principle compatible with FN (which satisfies direct_internal_fn_p).
2598 Return the types that should be used to determine whether the
2599 target supports FN. */
2602 direct_internal_fn_types (internal_fn fn
, tree return_type
, tree
*args
)
2604 const direct_internal_fn_info
&info
= direct_internal_fn (fn
);
2605 tree type0
= (info
.type0
< 0 ? return_type
: TREE_TYPE (args
[info
.type0
]));
2606 tree type1
= (info
.type1
< 0 ? return_type
: TREE_TYPE (args
[info
.type1
]));
2607 return tree_pair (type0
, type1
);
2610 /* CALL is a call whose return type and arguments are in principle
2611 compatible with FN (which satisfies direct_internal_fn_p). Return the
2612 types that should be used to determine whether the target supports FN. */
2615 direct_internal_fn_types (internal_fn fn
, gcall
*call
)
2617 const direct_internal_fn_info
&info
= direct_internal_fn (fn
);
2618 tree op0
= (info
.type0
< 0
2619 ? gimple_call_lhs (call
)
2620 : gimple_call_arg (call
, info
.type0
));
2621 tree op1
= (info
.type1
< 0
2622 ? gimple_call_lhs (call
)
2623 : gimple_call_arg (call
, info
.type1
));
2624 return tree_pair (TREE_TYPE (op0
), TREE_TYPE (op1
));
2627 /* Return true if OPTAB is supported for TYPES (whose modes should be
2628 the same) when the optimization type is OPT_TYPE. Used for simple
2632 direct_optab_supported_p (direct_optab optab
, tree_pair types
,
2633 optimization_type opt_type
)
2635 machine_mode mode
= TYPE_MODE (types
.first
);
2636 gcc_checking_assert (mode
== TYPE_MODE (types
.second
));
2637 return direct_optab_handler (optab
, mode
, opt_type
) != CODE_FOR_nothing
;
2640 /* Return true if load/store lanes optab OPTAB is supported for
2641 array type TYPES.first when the optimization type is OPT_TYPE. */
2644 multi_vector_optab_supported_p (convert_optab optab
, tree_pair types
,
2645 optimization_type opt_type
)
2647 gcc_assert (TREE_CODE (types
.first
) == ARRAY_TYPE
);
2648 machine_mode imode
= TYPE_MODE (types
.first
);
2649 machine_mode vmode
= TYPE_MODE (TREE_TYPE (types
.first
));
2650 return (convert_optab_handler (optab
, imode
, vmode
, opt_type
)
2651 != CODE_FOR_nothing
);
2654 #define direct_unary_optab_supported_p direct_optab_supported_p
2655 #define direct_binary_optab_supported_p direct_optab_supported_p
2656 #define direct_mask_load_optab_supported_p direct_optab_supported_p
2657 #define direct_load_lanes_optab_supported_p multi_vector_optab_supported_p
2658 #define direct_mask_store_optab_supported_p direct_optab_supported_p
2659 #define direct_store_lanes_optab_supported_p multi_vector_optab_supported_p
2661 /* Return true if FN is supported for the types in TYPES when the
2662 optimization type is OPT_TYPE. The types are those associated with
2663 the "type0" and "type1" fields of FN's direct_internal_fn_info
2667 direct_internal_fn_supported_p (internal_fn fn
, tree_pair types
,
2668 optimization_type opt_type
)
2672 #define DEF_INTERNAL_FN(CODE, FLAGS, FNSPEC) \
2673 case IFN_##CODE: break;
2674 #define DEF_INTERNAL_OPTAB_FN(CODE, FLAGS, OPTAB, TYPE) \
2676 return direct_##TYPE##_optab_supported_p (OPTAB##_optab, types, \
2678 #include "internal-fn.def"
2686 /* Return true if FN is supported for type TYPE when the optimization
2687 type is OPT_TYPE. The caller knows that the "type0" and "type1"
2688 fields of FN's direct_internal_fn_info structure are the same. */
2691 direct_internal_fn_supported_p (internal_fn fn
, tree type
,
2692 optimization_type opt_type
)
2694 const direct_internal_fn_info
&info
= direct_internal_fn (fn
);
2695 gcc_checking_assert (info
.type0
== info
.type1
);
2696 return direct_internal_fn_supported_p (fn
, tree_pair (type
, type
), opt_type
);
2699 /* Return true if IFN_SET_EDOM is supported. */
2702 set_edom_supported_p (void)
2711 #define DEF_INTERNAL_OPTAB_FN(CODE, FLAGS, OPTAB, TYPE) \
2713 expand_##CODE (internal_fn fn, gcall *stmt) \
2715 expand_##TYPE##_optab_fn (fn, stmt, OPTAB##_optab); \
2717 #include "internal-fn.def"
2719 /* Routines to expand each internal function, indexed by function number.
2720 Each routine has the prototype:
2722 expand_<NAME> (gcall *stmt)
2724 where STMT is the statement that performs the call. */
2725 static void (*const internal_fn_expanders
[]) (internal_fn
, gcall
*) = {
2726 #define DEF_INTERNAL_FN(CODE, FLAGS, FNSPEC) expand_##CODE,
2727 #include "internal-fn.def"
2731 /* Expand STMT as though it were a call to internal function FN. */
2734 expand_internal_call (internal_fn fn
, gcall
*stmt
)
2736 internal_fn_expanders
[fn
] (fn
, stmt
);
2739 /* Expand STMT, which is a call to internal function FN. */
2742 expand_internal_call (gcall
*stmt
)
2744 expand_internal_call (gimple_call_internal_fn (stmt
), stmt
);
2748 expand_PHI (internal_fn
, gcall
*)