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"
42 #include "stringpool.h"
48 #include "optabs-tree.h"
49 #include "gimple-ssa.h"
50 #include "tree-phinodes.h"
51 #include "ssa-iterators.h"
53 /* The names of each internal function, indexed by function number. */
54 const char *const internal_fn_name_array[] = {
55 #define DEF_INTERNAL_FN(CODE, FLAGS, FNSPEC) #CODE,
56 #include "internal-fn.def"
60 /* The ECF_* flags of each internal function, indexed by function number. */
61 const int internal_fn_flags_array[] = {
62 #define DEF_INTERNAL_FN(CODE, FLAGS, FNSPEC) FLAGS,
63 #include "internal-fn.def"
67 /* Fnspec of each internal function, indexed by function number. */
68 const_tree internal_fn_fnspec_array[IFN_LAST + 1];
73 #define DEF_INTERNAL_FN(CODE, FLAGS, FNSPEC) \
74 if (FNSPEC) internal_fn_fnspec_array[IFN_##CODE] = \
75 build_string ((int) sizeof (FNSPEC), FNSPEC ? FNSPEC : "");
76 #include "internal-fn.def"
77 internal_fn_fnspec_array[IFN_LAST] = 0;
80 /* Create static initializers for the information returned by
81 direct_internal_fn. */
82 #define not_direct { -2, -2, false }
83 #define mask_load_direct { -1, 2, false }
84 #define load_lanes_direct { -1, -1, false }
85 #define mask_store_direct { 3, 2, false }
86 #define store_lanes_direct { 0, 0, false }
87 #define unary_direct { 0, 0, true }
88 #define binary_direct { 0, 0, true }
90 const direct_internal_fn_info direct_internal_fn_array[IFN_LAST + 1] = {
91 #define DEF_INTERNAL_FN(CODE, FLAGS, FNSPEC) not_direct,
92 #define DEF_INTERNAL_OPTAB_FN(CODE, FLAGS, OPTAB, TYPE) TYPE##_direct,
93 #define DEF_INTERNAL_SIGNED_OPTAB_FN(CODE, FLAGS, SELECTOR, SIGNED_OPTAB, \
94 UNSIGNED_OPTAB, TYPE) TYPE##_direct,
95 #include "internal-fn.def"
99 /* ARRAY_TYPE is an array of vector modes. Return the associated insn
100 for load-lanes-style optab OPTAB, or CODE_FOR_nothing if none. */
102 static enum insn_code
103 get_multi_vector_move (tree array_type, convert_optab optab)
108 gcc_assert (TREE_CODE (array_type) == ARRAY_TYPE);
109 imode = TYPE_MODE (array_type);
110 vmode = TYPE_MODE (TREE_TYPE (array_type));
112 return convert_optab_handler (optab, imode, vmode);
115 /* Expand LOAD_LANES call STMT using optab OPTAB. */
118 expand_load_lanes_optab_fn (internal_fn, gcall *stmt, convert_optab optab)
120 struct expand_operand ops[2];
124 lhs = gimple_call_lhs (stmt);
125 rhs = gimple_call_arg (stmt, 0);
126 type = TREE_TYPE (lhs);
128 target = expand_expr (lhs, NULL_RTX, VOIDmode, EXPAND_WRITE);
129 mem = expand_normal (rhs);
131 gcc_assert (MEM_P (mem));
132 PUT_MODE (mem, TYPE_MODE (type));
134 create_output_operand (&ops[0], target, TYPE_MODE (type));
135 create_fixed_operand (&ops[1], mem);
136 expand_insn (get_multi_vector_move (type, optab), 2, ops);
139 /* Expand STORE_LANES call STMT using optab OPTAB. */
142 expand_store_lanes_optab_fn (internal_fn, gcall *stmt, convert_optab optab)
144 struct expand_operand ops[2];
148 lhs = gimple_call_lhs (stmt);
149 rhs = gimple_call_arg (stmt, 0);
150 type = TREE_TYPE (rhs);
152 target = expand_expr (lhs, NULL_RTX, VOIDmode, EXPAND_WRITE);
153 reg = expand_normal (rhs);
155 gcc_assert (MEM_P (target));
156 PUT_MODE (target, TYPE_MODE (type));
158 create_fixed_operand (&ops[0], target);
159 create_input_operand (&ops[1], reg, TYPE_MODE (type));
160 expand_insn (get_multi_vector_move (type, optab), 2, ops);
164 expand_ANNOTATE (internal_fn, gcall *)
169 /* This should get expanded in omp_device_lower pass. */
172 expand_GOMP_USE_SIMT (internal_fn, gcall *)
177 /* This should get expanded in omp_device_lower pass. */
180 expand_GOMP_SIMT_ENTER (internal_fn, gcall *)
185 /* Allocate per-lane storage and begin non-uniform execution region. */
188 expand_GOMP_SIMT_ENTER_ALLOC (internal_fn, gcall *stmt)
191 tree lhs = gimple_call_lhs (stmt);
193 target = expand_expr (lhs, NULL_RTX, VOIDmode, EXPAND_WRITE);
195 target = gen_reg_rtx (Pmode);
196 rtx size = expand_normal (gimple_call_arg (stmt, 0));
197 rtx align = expand_normal (gimple_call_arg (stmt, 1));
198 struct expand_operand ops[3];
199 create_output_operand (&ops[0], target, Pmode);
200 create_input_operand (&ops[1], size, Pmode);
201 create_input_operand (&ops[2], align, Pmode);
202 gcc_assert (targetm.have_omp_simt_enter ());
203 expand_insn (targetm.code_for_omp_simt_enter, 3, ops);
206 /* Deallocate per-lane storage and leave non-uniform execution region. */
209 expand_GOMP_SIMT_EXIT (internal_fn, gcall *stmt)
211 gcc_checking_assert (!gimple_call_lhs (stmt));
212 rtx arg = expand_normal (gimple_call_arg (stmt, 0));
213 struct expand_operand ops[1];
214 create_input_operand (&ops[0], arg, Pmode);
215 gcc_assert (targetm.have_omp_simt_exit ());
216 expand_insn (targetm.code_for_omp_simt_exit, 1, ops);
219 /* Lane index on SIMT targets: thread index in the warp on NVPTX. On targets
220 without SIMT execution this should be expanded in omp_device_lower pass. */
223 expand_GOMP_SIMT_LANE (internal_fn, gcall *stmt)
225 tree lhs = gimple_call_lhs (stmt);
229 rtx target = expand_expr (lhs, NULL_RTX, VOIDmode, EXPAND_WRITE);
230 gcc_assert (targetm.have_omp_simt_lane ());
231 emit_insn (targetm.gen_omp_simt_lane (target));
234 /* This should get expanded in omp_device_lower pass. */
237 expand_GOMP_SIMT_VF (internal_fn, gcall *)
242 /* Lane index of the first SIMT lane that supplies a non-zero argument.
243 This is a SIMT counterpart to GOMP_SIMD_LAST_LANE, used to represent the
244 lane that executed the last iteration for handling OpenMP lastprivate. */
247 expand_GOMP_SIMT_LAST_LANE (internal_fn, gcall *stmt)
249 tree lhs = gimple_call_lhs (stmt);
253 rtx target = expand_expr (lhs, NULL_RTX, VOIDmode, EXPAND_WRITE);
254 rtx cond = expand_normal (gimple_call_arg (stmt, 0));
255 machine_mode mode = TYPE_MODE (TREE_TYPE (lhs));
256 struct expand_operand ops[2];
257 create_output_operand (&ops[0], target, mode);
258 create_input_operand (&ops[1], cond, mode);
259 gcc_assert (targetm.have_omp_simt_last_lane ());
260 expand_insn (targetm.code_for_omp_simt_last_lane, 2, ops);
263 /* Non-transparent predicate used in SIMT lowering of OpenMP "ordered". */
266 expand_GOMP_SIMT_ORDERED_PRED (internal_fn, gcall *stmt)
268 tree lhs = gimple_call_lhs (stmt);
272 rtx target = expand_expr (lhs, NULL_RTX, VOIDmode, EXPAND_WRITE);
273 rtx ctr = expand_normal (gimple_call_arg (stmt, 0));
274 machine_mode mode = TYPE_MODE (TREE_TYPE (lhs));
275 struct expand_operand ops[2];
276 create_output_operand (&ops[0], target, mode);
277 create_input_operand (&ops[1], ctr, mode);
278 gcc_assert (targetm.have_omp_simt_ordered ());
279 expand_insn (targetm.code_for_omp_simt_ordered, 2, ops);
282 /* "Or" boolean reduction across SIMT lanes: return non-zero in all lanes if
283 any lane supplies a non-zero argument. */
286 expand_GOMP_SIMT_VOTE_ANY (internal_fn, gcall *stmt)
288 tree lhs = gimple_call_lhs (stmt);
292 rtx target = expand_expr (lhs, NULL_RTX, VOIDmode, EXPAND_WRITE);
293 rtx cond = expand_normal (gimple_call_arg (stmt, 0));
294 machine_mode mode = TYPE_MODE (TREE_TYPE (lhs));
295 struct expand_operand ops[2];
296 create_output_operand (&ops[0], target, mode);
297 create_input_operand (&ops[1], cond, mode);
298 gcc_assert (targetm.have_omp_simt_vote_any ());
299 expand_insn (targetm.code_for_omp_simt_vote_any, 2, ops);
302 /* Exchange between SIMT lanes with a "butterfly" pattern: source lane index
303 is destination lane index XOR given offset. */
306 expand_GOMP_SIMT_XCHG_BFLY (internal_fn, gcall *stmt)
308 tree lhs = gimple_call_lhs (stmt);
312 rtx target = expand_expr (lhs, NULL_RTX, VOIDmode, EXPAND_WRITE);
313 rtx src = expand_normal (gimple_call_arg (stmt, 0));
314 rtx idx = expand_normal (gimple_call_arg (stmt, 1));
315 machine_mode mode = TYPE_MODE (TREE_TYPE (lhs));
316 struct expand_operand ops[3];
317 create_output_operand (&ops[0], target, mode);
318 create_input_operand (&ops[1], src, mode);
319 create_input_operand (&ops[2], idx, SImode);
320 gcc_assert (targetm.have_omp_simt_xchg_bfly ());
321 expand_insn (targetm.code_for_omp_simt_xchg_bfly, 3, ops);
324 /* Exchange between SIMT lanes according to given source lane index. */
327 expand_GOMP_SIMT_XCHG_IDX (internal_fn, gcall *stmt)
329 tree lhs = gimple_call_lhs (stmt);
333 rtx target = expand_expr (lhs, NULL_RTX, VOIDmode, EXPAND_WRITE);
334 rtx src = expand_normal (gimple_call_arg (stmt, 0));
335 rtx idx = expand_normal (gimple_call_arg (stmt, 1));
336 machine_mode mode = TYPE_MODE (TREE_TYPE (lhs));
337 struct expand_operand ops[3];
338 create_output_operand (&ops[0], target, mode);
339 create_input_operand (&ops[1], src, mode);
340 create_input_operand (&ops[2], idx, SImode);
341 gcc_assert (targetm.have_omp_simt_xchg_idx ());
342 expand_insn (targetm.code_for_omp_simt_xchg_idx, 3, ops);
345 /* This should get expanded in adjust_simduid_builtins. */
348 expand_GOMP_SIMD_LANE (internal_fn, gcall *)
353 /* This should get expanded in adjust_simduid_builtins. */
356 expand_GOMP_SIMD_VF (internal_fn, gcall *)
361 /* This should get expanded in adjust_simduid_builtins. */
364 expand_GOMP_SIMD_LAST_LANE (internal_fn, gcall *)
369 /* This should get expanded in adjust_simduid_builtins. */
372 expand_GOMP_SIMD_ORDERED_START (internal_fn, gcall *)
377 /* This should get expanded in adjust_simduid_builtins. */
380 expand_GOMP_SIMD_ORDERED_END (internal_fn, gcall *)
385 /* This should get expanded in the sanopt pass. */
388 expand_UBSAN_NULL (internal_fn, gcall *)
393 /* This should get expanded in the sanopt pass. */
396 expand_UBSAN_BOUNDS (internal_fn, gcall *)
401 /* This should get expanded in the sanopt pass. */
404 expand_UBSAN_VPTR (internal_fn, gcall *)
409 /* This should get expanded in the sanopt pass. */
412 expand_UBSAN_PTR (internal_fn, gcall *)
417 /* This should get expanded in the sanopt pass. */
420 expand_UBSAN_OBJECT_SIZE (internal_fn, gcall *)
425 /* This should get expanded in the sanopt pass. */
428 expand_ASAN_CHECK (internal_fn, gcall *)
433 /* This should get expanded in the sanopt pass. */
436 expand_ASAN_MARK (internal_fn, gcall *)
441 /* This should get expanded in the sanopt pass. */
444 expand_ASAN_POISON (internal_fn, gcall *)
449 /* This should get expanded in the sanopt pass. */
452 expand_ASAN_POISON_USE (internal_fn, gcall *)
457 /* This should get expanded in the tsan pass. */
460 expand_TSAN_FUNC_EXIT (internal_fn, gcall *)
465 /* This should get expanded in the lower pass. */
468 expand_FALLTHROUGH (internal_fn, gcall *call)
470 error_at (gimple_location (call),
471 "invalid use of attribute %<fallthrough%>");
474 /* Return minimum precision needed to represent all values
475 of ARG in SIGNed integral type. */
478 get_min_precision (tree arg, signop sign)
480 int prec = TYPE_PRECISION (TREE_TYPE (arg));
482 signop orig_sign = sign;
483 if (TREE_CODE (arg) == INTEGER_CST)
486 if (TYPE_SIGN (TREE_TYPE (arg)) != sign)
488 widest_int w = wi::to_widest (arg);
489 w = wi::ext (w, prec, sign);
490 p = wi::min_precision (w, sign);
493 p = wi::min_precision (wi::to_wide (arg), sign);
494 return MIN (p, prec);
496 while (CONVERT_EXPR_P (arg)
497 && INTEGRAL_TYPE_P (TREE_TYPE (TREE_OPERAND (arg, 0)))
498 && TYPE_PRECISION (TREE_TYPE (TREE_OPERAND (arg, 0))) <= prec)
500 arg = TREE_OPERAND (arg, 0);
501 if (TYPE_PRECISION (TREE_TYPE (arg)) < prec)
503 if (TYPE_UNSIGNED (TREE_TYPE (arg)))
505 else if (sign == UNSIGNED && get_range_pos_neg (arg) != 1)
506 return prec + (orig_sign != sign);
507 prec = TYPE_PRECISION (TREE_TYPE (arg));
510 return prec + (orig_sign != sign);
512 if (TREE_CODE (arg) != SSA_NAME)
513 return prec + (orig_sign != sign);
514 wide_int arg_min, arg_max;
515 while (get_range_info (arg, &arg_min, &arg_max) != VR_RANGE)
517 gimple *g = SSA_NAME_DEF_STMT (arg);
518 if (is_gimple_assign (g)
519 && CONVERT_EXPR_CODE_P (gimple_assign_rhs_code (g)))
521 tree t = gimple_assign_rhs1 (g);
522 if (INTEGRAL_TYPE_P (TREE_TYPE (t))
523 && TYPE_PRECISION (TREE_TYPE (t)) <= prec)
526 if (TYPE_PRECISION (TREE_TYPE (arg)) < prec)
528 if (TYPE_UNSIGNED (TREE_TYPE (arg)))
530 else if (sign == UNSIGNED && get_range_pos_neg (arg) != 1)
531 return prec + (orig_sign != sign);
532 prec = TYPE_PRECISION (TREE_TYPE (arg));
535 return prec + (orig_sign != sign);
539 return prec + (orig_sign != sign);
541 if (sign == TYPE_SIGN (TREE_TYPE (arg)))
543 int p1 = wi::min_precision (arg_min, sign);
544 int p2 = wi::min_precision (arg_max, sign);
546 prec = MIN (prec, p1);
548 else if (sign == UNSIGNED && !wi::neg_p (arg_min, SIGNED))
550 int p = wi::min_precision (arg_max, UNSIGNED);
551 prec = MIN (prec, p);
553 return prec + (orig_sign != sign);
556 /* Helper for expand_*_overflow. Set the __imag__ part to true
557 (1 except for signed:1 type, in which case store -1). */
560 expand_arith_set_overflow (tree lhs, rtx target)
562 if (TYPE_PRECISION (TREE_TYPE (TREE_TYPE (lhs))) == 1
563 && !TYPE_UNSIGNED (TREE_TYPE (TREE_TYPE (lhs))))
564 write_complex_part (target, constm1_rtx, true);
566 write_complex_part (target, const1_rtx, true);
569 /* Helper for expand_*_overflow. Store RES into the __real__ part
570 of TARGET. If RES has larger MODE than __real__ part of TARGET,
571 set the __imag__ part to 1 if RES doesn't fit into it. Similarly
572 if LHS has smaller precision than its mode. */
575 expand_arith_overflow_result_store (tree lhs, rtx target,
576 scalar_int_mode mode, rtx res)
578 scalar_int_mode tgtmode
579 = as_a <scalar_int_mode> (GET_MODE_INNER (GET_MODE (target)));
583 rtx_code_label *done_label = gen_label_rtx ();
584 int uns = TYPE_UNSIGNED (TREE_TYPE (TREE_TYPE (lhs)));
585 lres = convert_modes (tgtmode, mode, res, uns);
586 gcc_assert (GET_MODE_PRECISION (tgtmode) < GET_MODE_PRECISION (mode));
587 do_compare_rtx_and_jump (res, convert_modes (mode, tgtmode, lres, uns),
588 EQ, true, mode, NULL_RTX, NULL, done_label,
589 profile_probability::very_likely ());
590 expand_arith_set_overflow (lhs, target);
591 emit_label (done_label);
593 int prec = TYPE_PRECISION (TREE_TYPE (TREE_TYPE (lhs)));
594 int tgtprec = GET_MODE_PRECISION (tgtmode);
597 rtx_code_label *done_label = gen_label_rtx ();
598 int uns = TYPE_UNSIGNED (TREE_TYPE (TREE_TYPE (lhs)));
603 = immed_wide_int_const (wi::shifted_mask (0, prec, false, tgtprec),
605 lres = expand_simple_binop (tgtmode, AND, res, mask, NULL_RTX,
606 true, OPTAB_LIB_WIDEN);
610 lres = expand_shift (LSHIFT_EXPR, tgtmode, res, tgtprec - prec,
612 lres = expand_shift (RSHIFT_EXPR, tgtmode, lres, tgtprec - prec,
615 do_compare_rtx_and_jump (res, lres,
616 EQ, true, tgtmode, NULL_RTX, NULL, done_label,
617 profile_probability::very_likely ());
618 expand_arith_set_overflow (lhs, target);
619 emit_label (done_label);
621 write_complex_part (target, lres, false);
624 /* Helper for expand_*_overflow. Store RES into TARGET. */
627 expand_ubsan_result_store (rtx target, rtx res)
629 if (GET_CODE (target) == SUBREG && SUBREG_PROMOTED_VAR_P (target))
630 /* If this is a scalar in a register that is stored in a wider mode
631 than the declared mode, compute the result into its declared mode
632 and then convert to the wider mode. Our value is the computed
634 convert_move (SUBREG_REG (target), res, SUBREG_PROMOTED_SIGN (target));
636 emit_move_insn (target, res);
639 /* Add sub/add overflow checking to the statement STMT.
640 CODE says whether the operation is +, or -. */
643 expand_addsub_overflow (location_t loc, tree_code code, tree lhs,
644 tree arg0, tree arg1, bool unsr_p, bool uns0_p,
645 bool uns1_p, bool is_ubsan, tree *datap)
647 rtx res, target = NULL_RTX;
649 rtx_code_label *done_label = gen_label_rtx ();
650 rtx_code_label *do_error = gen_label_rtx ();
651 do_pending_stack_adjust ();
652 rtx op0 = expand_normal (arg0);
653 rtx op1 = expand_normal (arg1);
654 scalar_int_mode mode = SCALAR_INT_TYPE_MODE (TREE_TYPE (arg0));
655 int prec = GET_MODE_PRECISION (mode);
656 rtx sgn = immed_wide_int_const (wi::min_value (prec, SIGNED), mode);
660 gcc_assert (!unsr_p && !uns0_p && !uns1_p);
664 target = expand_expr (lhs, NULL_RTX, VOIDmode, EXPAND_WRITE);
666 write_complex_part (target, const0_rtx, true);
669 /* We assume both operands and result have the same precision
670 here (GET_MODE_BITSIZE (mode)), S stands for signed type
671 with that precision, U for unsigned type with that precision,
672 sgn for unsigned most significant bit in that precision.
673 s1 is signed first operand, u1 is unsigned first operand,
674 s2 is signed second operand, u2 is unsigned second operand,
675 sr is signed result, ur is unsigned result and the following
676 rules say how to compute result (which is always result of
677 the operands as if both were unsigned, cast to the right
678 signedness) and how to compute whether operation overflowed.
681 res = (S) ((U) s1 + (U) s2)
682 ovf = s2 < 0 ? res > s1 : res < s1 (or jump on overflow)
684 res = (S) ((U) s1 - (U) s2)
685 ovf = s2 < 0 ? res < s1 : res > s2 (or jump on overflow)
688 ovf = res < u1 (or jump on carry, but RTL opts will handle it)
691 ovf = res > u1 (or jump on carry, but RTL opts will handle it)
693 res = (S) ((U) s1 + u2)
694 ovf = ((U) res ^ sgn) < u2
699 ovf = t1 < 0 ? t2 > s1 : t2 < s1 (or jump on overflow)
701 res = (S) ((U) s1 - u2)
702 ovf = u2 > ((U) s1 ^ sgn)
705 ovf = s1 < 0 || u2 > (U) s1
708 ovf = u1 >= ((U) s2 ^ sgn)
713 ovf = s2 < 0 ? (S) t2 < (S) t1 : (S) t2 > (S) t1 (or jump on overflow)
715 res = (U) s1 + (U) s2
716 ovf = s2 < 0 ? (s1 | (S) res) < 0) : (s1 & (S) res) < 0)
719 ovf = (U) res < u2 || res < 0
722 ovf = u1 >= u2 ? res < 0 : res >= 0
724 res = (U) s1 - (U) s2
725 ovf = s2 >= 0 ? ((s1 | (S) res) < 0) : ((s1 & (S) res) < 0) */
727 if (code == PLUS_EXPR && uns0_p && !uns1_p)
729 /* PLUS_EXPR is commutative, if operand signedness differs,
730 canonicalize to the first operand being signed and second
731 unsigned to simplify following code. */
732 std::swap (op0, op1);
733 std::swap (arg0, arg1);
739 if (uns0_p && uns1_p && unsr_p)
741 insn_code icode = optab_handler (code == PLUS_EXPR ? uaddv4_optab
742 : usubv4_optab, mode);
743 if (icode != CODE_FOR_nothing)
745 struct expand_operand ops[4];
746 rtx_insn *last = get_last_insn ();
748 res = gen_reg_rtx (mode);
749 create_output_operand (&ops[0], res, mode);
750 create_input_operand (&ops[1], op0, mode);
751 create_input_operand (&ops[2], op1, mode);
752 create_fixed_operand (&ops[3], do_error);
753 if (maybe_expand_insn (icode, 4, ops))
755 last = get_last_insn ();
756 if (profile_status_for_fn (cfun) != PROFILE_ABSENT
758 && any_condjump_p (last)
759 && !find_reg_note (last, REG_BR_PROB, 0))
760 add_reg_br_prob_note (last,
761 profile_probability::very_unlikely ());
762 emit_jump (done_label);
766 delete_insns_since (last);
769 /* Compute the operation. On RTL level, the addition is always
771 res = expand_binop (mode, code == PLUS_EXPR ? add_optab : sub_optab,
772 op0, op1, NULL_RTX, false, OPTAB_LIB_WIDEN);
774 /* For PLUS_EXPR, the operation is commutative, so we can pick
775 operand to compare against. For prec <= BITS_PER_WORD, I think
776 preferring REG operand is better over CONST_INT, because
777 the CONST_INT might enlarge the instruction or CSE would need
778 to figure out we'd already loaded it into a register before.
779 For prec > BITS_PER_WORD, I think CONST_INT might be more beneficial,
780 as then the multi-word comparison can be perhaps simplified. */
781 if (code == PLUS_EXPR
782 && (prec <= BITS_PER_WORD
783 ? (CONST_SCALAR_INT_P (op0) && REG_P (op1))
784 : CONST_SCALAR_INT_P (op1)))
786 do_compare_rtx_and_jump (res, tem, code == PLUS_EXPR ? GEU : LEU,
787 true, mode, NULL_RTX, NULL, done_label,
788 profile_probability::very_likely ());
793 if (!uns0_p && uns1_p && !unsr_p)
795 /* Compute the operation. On RTL level, the addition is always
797 res = expand_binop (mode, code == PLUS_EXPR ? add_optab : sub_optab,
798 op0, op1, NULL_RTX, false, OPTAB_LIB_WIDEN);
799 rtx tem = expand_binop (mode, add_optab,
800 code == PLUS_EXPR ? res : op0, sgn,
801 NULL_RTX, false, OPTAB_LIB_WIDEN);
802 do_compare_rtx_and_jump (tem, op1, GEU, true, mode, NULL_RTX, NULL,
803 done_label, profile_probability::very_likely ());
808 if (code == PLUS_EXPR && !uns0_p && uns1_p && unsr_p)
810 op1 = expand_binop (mode, add_optab, op1, sgn, NULL_RTX, false,
812 /* As we've changed op1, we have to avoid using the value range
813 for the original argument. */
814 arg1 = error_mark_node;
820 if (code == MINUS_EXPR && uns0_p && !uns1_p && unsr_p)
822 op0 = expand_binop (mode, add_optab, op0, sgn, NULL_RTX, false,
824 /* As we've changed op0, we have to avoid using the value range
825 for the original argument. */
826 arg0 = error_mark_node;
832 if (code == MINUS_EXPR && !uns0_p && uns1_p && unsr_p)
834 /* Compute the operation. On RTL level, the addition is always
836 res = expand_binop (mode, sub_optab, op0, op1, NULL_RTX, false,
838 int pos_neg = get_range_pos_neg (arg0);
840 /* If ARG0 is known to be always negative, this is always overflow. */
841 emit_jump (do_error);
842 else if (pos_neg == 3)
843 /* If ARG0 is not known to be always positive, check at runtime. */
844 do_compare_rtx_and_jump (op0, const0_rtx, LT, false, mode, NULL_RTX,
845 NULL, do_error, profile_probability::very_unlikely ());
846 do_compare_rtx_and_jump (op1, op0, LEU, true, mode, NULL_RTX, NULL,
847 done_label, profile_probability::very_likely ());
852 if (code == MINUS_EXPR && uns0_p && !uns1_p && !unsr_p)
854 /* Compute the operation. On RTL level, the addition is always
856 res = expand_binop (mode, sub_optab, op0, op1, NULL_RTX, false,
858 rtx tem = expand_binop (mode, add_optab, op1, sgn, NULL_RTX, false,
860 do_compare_rtx_and_jump (op0, tem, LTU, true, mode, NULL_RTX, NULL,
861 done_label, profile_probability::very_likely ());
866 if (code == PLUS_EXPR && uns0_p && uns1_p && !unsr_p)
868 /* Compute the operation. On RTL level, the addition is always
870 res = expand_binop (mode, add_optab, op0, op1, NULL_RTX, false,
872 do_compare_rtx_and_jump (res, const0_rtx, LT, false, mode, NULL_RTX,
873 NULL, do_error, profile_probability::very_unlikely ());
875 /* The operation is commutative, so we can pick operand to compare
876 against. For prec <= BITS_PER_WORD, I think preferring REG operand
877 is better over CONST_INT, because the CONST_INT might enlarge the
878 instruction or CSE would need to figure out we'd already loaded it
879 into a register before. For prec > BITS_PER_WORD, I think CONST_INT
880 might be more beneficial, as then the multi-word comparison can be
881 perhaps simplified. */
882 if (prec <= BITS_PER_WORD
883 ? (CONST_SCALAR_INT_P (op1) && REG_P (op0))
884 : CONST_SCALAR_INT_P (op0))
886 do_compare_rtx_and_jump (res, tem, GEU, true, mode, NULL_RTX, NULL,
887 done_label, profile_probability::very_likely ());
892 if (!uns0_p && !uns1_p && unsr_p)
894 /* Compute the operation. On RTL level, the addition is always
896 res = expand_binop (mode, code == PLUS_EXPR ? add_optab : sub_optab,
897 op0, op1, NULL_RTX, false, OPTAB_LIB_WIDEN);
898 int pos_neg = get_range_pos_neg (arg1);
899 if (code == PLUS_EXPR)
901 int pos_neg0 = get_range_pos_neg (arg0);
902 if (pos_neg0 != 3 && pos_neg == 3)
904 std::swap (op0, op1);
911 tem = expand_binop (mode, ((pos_neg == 1) ^ (code == MINUS_EXPR))
912 ? and_optab : ior_optab,
913 op0, res, NULL_RTX, false, OPTAB_LIB_WIDEN);
914 do_compare_rtx_and_jump (tem, const0_rtx, GE, false, mode, NULL,
915 NULL, done_label, profile_probability::very_likely ());
919 rtx_code_label *do_ior_label = gen_label_rtx ();
920 do_compare_rtx_and_jump (op1, const0_rtx,
921 code == MINUS_EXPR ? GE : LT, false, mode,
922 NULL_RTX, NULL, do_ior_label,
923 profile_probability::even ());
924 tem = expand_binop (mode, and_optab, op0, res, NULL_RTX, false,
926 do_compare_rtx_and_jump (tem, const0_rtx, GE, false, mode, NULL_RTX,
927 NULL, done_label, profile_probability::very_likely ());
928 emit_jump (do_error);
929 emit_label (do_ior_label);
930 tem = expand_binop (mode, ior_optab, op0, res, NULL_RTX, false,
932 do_compare_rtx_and_jump (tem, const0_rtx, GE, false, mode, NULL_RTX,
933 NULL, done_label, profile_probability::very_likely ());
939 if (code == MINUS_EXPR && uns0_p && uns1_p && !unsr_p)
941 /* Compute the operation. On RTL level, the addition is always
943 res = expand_binop (mode, sub_optab, op0, op1, NULL_RTX, false,
945 rtx_code_label *op0_geu_op1 = gen_label_rtx ();
946 do_compare_rtx_and_jump (op0, op1, GEU, true, mode, NULL_RTX, NULL,
947 op0_geu_op1, profile_probability::even ());
948 do_compare_rtx_and_jump (res, const0_rtx, LT, false, mode, NULL_RTX,
949 NULL, done_label, profile_probability::very_likely ());
950 emit_jump (do_error);
951 emit_label (op0_geu_op1);
952 do_compare_rtx_and_jump (res, const0_rtx, GE, false, mode, NULL_RTX,
953 NULL, done_label, profile_probability::very_likely ());
957 gcc_assert (!uns0_p && !uns1_p && !unsr_p);
962 insn_code icode = optab_handler (code == PLUS_EXPR ? addv4_optab
963 : subv4_optab, mode);
964 if (icode != CODE_FOR_nothing)
966 struct expand_operand ops[4];
967 rtx_insn *last = get_last_insn ();
969 res = gen_reg_rtx (mode);
970 create_output_operand (&ops[0], res, mode);
971 create_input_operand (&ops[1], op0, mode);
972 create_input_operand (&ops[2], op1, mode);
973 create_fixed_operand (&ops[3], do_error);
974 if (maybe_expand_insn (icode, 4, ops))
976 last = get_last_insn ();
977 if (profile_status_for_fn (cfun) != PROFILE_ABSENT
979 && any_condjump_p (last)
980 && !find_reg_note (last, REG_BR_PROB, 0))
981 add_reg_br_prob_note (last,
982 profile_probability::very_unlikely ());
983 emit_jump (done_label);
987 delete_insns_since (last);
990 /* Compute the operation. On RTL level, the addition is always
992 res = expand_binop (mode, code == PLUS_EXPR ? add_optab : sub_optab,
993 op0, op1, NULL_RTX, false, OPTAB_LIB_WIDEN);
995 /* If we can prove that one of the arguments (for MINUS_EXPR only
996 the second operand, as subtraction is not commutative) is always
997 non-negative or always negative, we can do just one comparison
998 and conditional jump. */
999 int pos_neg = get_range_pos_neg (arg1);
1000 if (code == PLUS_EXPR)
1002 int pos_neg0 = get_range_pos_neg (arg0);
1003 if (pos_neg0 != 3 && pos_neg == 3)
1005 std::swap (op0, op1);
1010 /* Addition overflows if and only if the two operands have the same sign,
1011 and the result has the opposite sign. Subtraction overflows if and
1012 only if the two operands have opposite sign, and the subtrahend has
1013 the same sign as the result. Here 0 is counted as positive. */
1016 /* Compute op0 ^ op1 (operands have opposite sign). */
1017 rtx op_xor = expand_binop (mode, xor_optab, op0, op1, NULL_RTX, false,
1020 /* Compute res ^ op1 (result and 2nd operand have opposite sign). */
1021 rtx res_xor = expand_binop (mode, xor_optab, res, op1, NULL_RTX, false,
1025 if (code == PLUS_EXPR)
1027 /* Compute (res ^ op1) & ~(op0 ^ op1). */
1028 tem = expand_unop (mode, one_cmpl_optab, op_xor, NULL_RTX, false);
1029 tem = expand_binop (mode, and_optab, res_xor, tem, NULL_RTX, false,
1034 /* Compute (op0 ^ op1) & ~(res ^ op1). */
1035 tem = expand_unop (mode, one_cmpl_optab, res_xor, NULL_RTX, false);
1036 tem = expand_binop (mode, and_optab, op_xor, tem, NULL_RTX, false,
1040 /* No overflow if the result has bit sign cleared. */
1041 do_compare_rtx_and_jump (tem, const0_rtx, GE, false, mode, NULL_RTX,
1042 NULL, done_label, profile_probability::very_likely ());
1045 /* Compare the result of the operation with the first operand.
1046 No overflow for addition if second operand is positive and result
1047 is larger or second operand is negative and result is smaller.
1048 Likewise for subtraction with sign of second operand flipped. */
1050 do_compare_rtx_and_jump (res, op0,
1051 (pos_neg == 1) ^ (code == MINUS_EXPR) ? GE : LE,
1052 false, mode, NULL_RTX, NULL, done_label,
1053 profile_probability::very_likely ());
1057 emit_label (do_error);
1060 /* Expand the ubsan builtin call. */
1062 fn = ubsan_build_overflow_builtin (code, loc, TREE_TYPE (arg0),
1066 do_pending_stack_adjust ();
1069 expand_arith_set_overflow (lhs, target);
1072 emit_label (done_label);
1077 expand_ubsan_result_store (target, res);
1081 res = expand_binop (mode, add_optab, res, sgn, NULL_RTX, false,
1084 expand_arith_overflow_result_store (lhs, target, mode, res);
1089 /* Add negate overflow checking to the statement STMT. */
1092 expand_neg_overflow (location_t loc, tree lhs, tree arg1, bool is_ubsan,
1097 rtx_code_label *done_label, *do_error;
1098 rtx target = NULL_RTX;
1100 done_label = gen_label_rtx ();
1101 do_error = gen_label_rtx ();
1103 do_pending_stack_adjust ();
1104 op1 = expand_normal (arg1);
1106 scalar_int_mode mode = SCALAR_INT_TYPE_MODE (TREE_TYPE (arg1));
1109 target = expand_expr (lhs, NULL_RTX, VOIDmode, EXPAND_WRITE);
1111 write_complex_part (target, const0_rtx, true);
1114 enum insn_code icode = optab_handler (negv3_optab, mode);
1115 if (icode != CODE_FOR_nothing)
1117 struct expand_operand ops[3];
1118 rtx_insn *last = get_last_insn ();
1120 res = gen_reg_rtx (mode);
1121 create_output_operand (&ops[0], res, mode);
1122 create_input_operand (&ops[1], op1, mode);
1123 create_fixed_operand (&ops[2], do_error);
1124 if (maybe_expand_insn (icode, 3, ops))
1126 last = get_last_insn ();
1127 if (profile_status_for_fn (cfun) != PROFILE_ABSENT
1129 && any_condjump_p (last)
1130 && !find_reg_note (last, REG_BR_PROB, 0))
1131 add_reg_br_prob_note (last,
1132 profile_probability::very_unlikely ());
1133 emit_jump (done_label);
1137 delete_insns_since (last);
1138 icode = CODE_FOR_nothing;
1142 if (icode == CODE_FOR_nothing)
1144 /* Compute the operation. On RTL level, the addition is always
1146 res = expand_unop (mode, neg_optab, op1, NULL_RTX, false);
1148 /* Compare the operand with the most negative value. */
1149 rtx minv = expand_normal (TYPE_MIN_VALUE (TREE_TYPE (arg1)));
1150 do_compare_rtx_and_jump (op1, minv, NE, true, mode, NULL_RTX, NULL,
1151 done_label, profile_probability::very_likely ());
1154 emit_label (do_error);
1157 /* Expand the ubsan builtin call. */
1159 fn = ubsan_build_overflow_builtin (NEGATE_EXPR, loc, TREE_TYPE (arg1),
1160 arg1, NULL_TREE, datap);
1163 do_pending_stack_adjust ();
1166 expand_arith_set_overflow (lhs, target);
1169 emit_label (done_label);
1174 expand_ubsan_result_store (target, res);
1176 expand_arith_overflow_result_store (lhs, target, mode, res);
1180 /* Return true if UNS WIDEN_MULT_EXPR with result mode WMODE and operand
1181 mode MODE can be expanded without using a libcall. */
1184 can_widen_mult_without_libcall (scalar_int_mode wmode, scalar_int_mode mode,
1185 rtx op0, rtx op1, bool uns)
1187 if (find_widening_optab_handler (umul_widen_optab, wmode, mode)
1188 != CODE_FOR_nothing)
1191 if (find_widening_optab_handler (smul_widen_optab, wmode, mode)
1192 != CODE_FOR_nothing)
1195 rtx_insn *last = get_last_insn ();
1196 if (CONSTANT_P (op0))
1197 op0 = convert_modes (wmode, mode, op0, uns);
1199 op0 = gen_raw_REG (wmode, LAST_VIRTUAL_REGISTER + 1);
1200 if (CONSTANT_P (op1))
1201 op1 = convert_modes (wmode, mode, op1, uns);
1203 op1 = gen_raw_REG (wmode, LAST_VIRTUAL_REGISTER + 2);
1204 rtx ret = expand_mult (wmode, op0, op1, NULL_RTX, uns, true);
1205 delete_insns_since (last);
1206 return ret != NULL_RTX;
1209 /* Add mul overflow checking to the statement STMT. */
1212 expand_mul_overflow (location_t loc, tree lhs, tree arg0, tree arg1,
1213 bool unsr_p, bool uns0_p, bool uns1_p, bool is_ubsan,
1218 rtx_code_label *done_label, *do_error;
1219 rtx target = NULL_RTX;
1221 enum insn_code icode;
1223 done_label = gen_label_rtx ();
1224 do_error = gen_label_rtx ();
1226 do_pending_stack_adjust ();
1227 op0 = expand_normal (arg0);
1228 op1 = expand_normal (arg1);
1230 scalar_int_mode mode = SCALAR_INT_TYPE_MODE (TREE_TYPE (arg0));
1234 target = expand_expr (lhs, NULL_RTX, VOIDmode, EXPAND_WRITE);
1236 write_complex_part (target, const0_rtx, true);
1240 gcc_assert (!unsr_p && !uns0_p && !uns1_p);
1242 /* We assume both operands and result have the same precision
1243 here (GET_MODE_BITSIZE (mode)), S stands for signed type
1244 with that precision, U for unsigned type with that precision,
1245 sgn for unsigned most significant bit in that precision.
1246 s1 is signed first operand, u1 is unsigned first operand,
1247 s2 is signed second operand, u2 is unsigned second operand,
1248 sr is signed result, ur is unsigned result and the following
1249 rules say how to compute result (which is always result of
1250 the operands as if both were unsigned, cast to the right
1251 signedness) and how to compute whether operation overflowed.
1252 main_ovf (false) stands for jump on signed multiplication
1253 overflow or the main algorithm with uns == false.
1254 main_ovf (true) stands for jump on unsigned multiplication
1255 overflow or the main algorithm with uns == true.
1258 res = (S) ((U) s1 * (U) s2)
1259 ovf = main_ovf (false)
1262 ovf = main_ovf (true)
1265 ovf = (s1 < 0 && u2) || main_ovf (true)
1268 ovf = res < 0 || main_ovf (true)
1270 res = (S) ((U) s1 * u2)
1271 ovf = (S) u2 >= 0 ? main_ovf (false)
1272 : (s1 != 0 && (s1 != -1 || u2 != (U) res))
1274 t1 = (s1 & s2) < 0 ? (-(U) s1) : ((U) s1)
1275 t2 = (s1 & s2) < 0 ? (-(U) s2) : ((U) s2)
1277 ovf = (s1 ^ s2) < 0 ? (s1 && s2) : main_ovf (true) */
1279 if (uns0_p && !uns1_p)
1281 /* Multiplication is commutative, if operand signedness differs,
1282 canonicalize to the first operand being signed and second
1283 unsigned to simplify following code. */
1284 std::swap (op0, op1);
1285 std::swap (arg0, arg1);
1290 int pos_neg0 = get_range_pos_neg (arg0);
1291 int pos_neg1 = get_range_pos_neg (arg1);
1294 if (!uns0_p && uns1_p && unsr_p)
1299 /* If s1 is non-negative, just perform normal u1 * u2 -> ur. */
1302 /* If s1 is negative, avoid the main code, just multiply and
1303 signal overflow if op1 is not 0. */
1304 struct separate_ops ops;
1305 ops.code = MULT_EXPR;
1306 ops.type = TREE_TYPE (arg1);
1307 ops.op0 = make_tree (ops.type, op0);
1308 ops.op1 = make_tree (ops.type, op1);
1309 ops.op2 = NULL_TREE;
1311 res = expand_expr_real_2 (&ops, NULL_RTX, mode, EXPAND_NORMAL);
1312 do_compare_rtx_and_jump (op1, const0_rtx, EQ, true, mode, NULL_RTX,
1313 NULL, done_label, profile_probability::very_likely ());
1314 goto do_error_label;
1316 rtx_code_label *do_main_label;
1317 do_main_label = gen_label_rtx ();
1318 do_compare_rtx_and_jump (op0, const0_rtx, GE, false, mode, NULL_RTX,
1319 NULL, do_main_label, profile_probability::very_likely ());
1320 do_compare_rtx_and_jump (op1, const0_rtx, EQ, true, mode, NULL_RTX,
1321 NULL, do_main_label, profile_probability::very_likely ());
1322 expand_arith_set_overflow (lhs, target);
1323 emit_label (do_main_label);
1331 if (uns0_p && uns1_p && !unsr_p)
1334 /* Rest of handling of this case after res is computed. */
1339 if (!uns0_p && uns1_p && !unsr_p)
1346 /* If (S) u2 is negative (i.e. u2 is larger than maximum of S,
1347 avoid the main code, just multiply and signal overflow
1348 unless 0 * u2 or -1 * ((U) Smin). */
1349 struct separate_ops ops;
1350 ops.code = MULT_EXPR;
1351 ops.type = TREE_TYPE (arg1);
1352 ops.op0 = make_tree (ops.type, op0);
1353 ops.op1 = make_tree (ops.type, op1);
1354 ops.op2 = NULL_TREE;
1356 res = expand_expr_real_2 (&ops, NULL_RTX, mode, EXPAND_NORMAL);
1357 do_compare_rtx_and_jump (op0, const0_rtx, EQ, true, mode, NULL_RTX,
1358 NULL, done_label, profile_probability::very_likely ());
1359 do_compare_rtx_and_jump (op0, constm1_rtx, NE, true, mode, NULL_RTX,
1360 NULL, do_error, profile_probability::very_unlikely ());
1362 prec = GET_MODE_PRECISION (mode);
1364 sgn = immed_wide_int_const (wi::min_value (prec, SIGNED), mode);
1365 do_compare_rtx_and_jump (op1, sgn, EQ, true, mode, NULL_RTX,
1366 NULL, done_label, profile_probability::very_likely ());
1367 goto do_error_label;
1369 /* Rest of handling of this case after res is computed. */
1377 if (!uns0_p && !uns1_p && unsr_p)
1380 switch (pos_neg0 | pos_neg1)
1382 case 1: /* Both operands known to be non-negative. */
1384 case 2: /* Both operands known to be negative. */
1385 op0 = expand_unop (mode, neg_optab, op0, NULL_RTX, false);
1386 op1 = expand_unop (mode, neg_optab, op1, NULL_RTX, false);
1387 /* Avoid looking at arg0/arg1 ranges, as we've changed
1389 arg0 = error_mark_node;
1390 arg1 = error_mark_node;
1393 if ((pos_neg0 ^ pos_neg1) == 3)
1395 /* If one operand is known to be negative and the other
1396 non-negative, this overflows always, unless the non-negative
1397 one is 0. Just do normal multiply and set overflow
1398 unless one of the operands is 0. */
1399 struct separate_ops ops;
1400 ops.code = MULT_EXPR;
1402 = build_nonstandard_integer_type (GET_MODE_PRECISION (mode),
1404 ops.op0 = make_tree (ops.type, op0);
1405 ops.op1 = make_tree (ops.type, op1);
1406 ops.op2 = NULL_TREE;
1408 res = expand_expr_real_2 (&ops, NULL_RTX, mode, EXPAND_NORMAL);
1409 tem = expand_binop (mode, and_optab, op0, op1, NULL_RTX, false,
1411 do_compare_rtx_and_jump (tem, const0_rtx, EQ, true, mode,
1412 NULL_RTX, NULL, done_label,
1413 profile_probability::very_likely ());
1414 goto do_error_label;
1416 /* The general case, do all the needed comparisons at runtime. */
1417 rtx_code_label *do_main_label, *after_negate_label;
1419 rop0 = gen_reg_rtx (mode);
1420 rop1 = gen_reg_rtx (mode);
1421 emit_move_insn (rop0, op0);
1422 emit_move_insn (rop1, op1);
1425 do_main_label = gen_label_rtx ();
1426 after_negate_label = gen_label_rtx ();
1427 tem = expand_binop (mode, and_optab, op0, op1, NULL_RTX, false,
1429 do_compare_rtx_and_jump (tem, const0_rtx, GE, false, mode, NULL_RTX,
1430 NULL, after_negate_label, profile_probability::very_likely ());
1431 /* Both arguments negative here, negate them and continue with
1432 normal unsigned overflow checking multiplication. */
1433 emit_move_insn (op0, expand_unop (mode, neg_optab, op0,
1435 emit_move_insn (op1, expand_unop (mode, neg_optab, op1,
1437 /* Avoid looking at arg0/arg1 ranges, as we might have changed
1439 arg0 = error_mark_node;
1440 arg1 = error_mark_node;
1441 emit_jump (do_main_label);
1442 emit_label (after_negate_label);
1443 tem2 = expand_binop (mode, xor_optab, op0, op1, NULL_RTX, false,
1445 do_compare_rtx_and_jump (tem2, const0_rtx, GE, false, mode, NULL_RTX,
1446 NULL, do_main_label, profile_probability::very_likely ());
1447 /* One argument is negative here, the other positive. This
1448 overflows always, unless one of the arguments is 0. But
1449 if e.g. s2 is 0, (U) s1 * 0 doesn't overflow, whatever s1
1450 is, thus we can keep do_main code oring in overflow as is. */
1451 do_compare_rtx_and_jump (tem, const0_rtx, EQ, true, mode, NULL_RTX,
1452 NULL, do_main_label, profile_probability::very_likely ());
1453 expand_arith_set_overflow (lhs, target);
1454 emit_label (do_main_label);
1462 type = build_nonstandard_integer_type (GET_MODE_PRECISION (mode), uns);
1463 sign = uns ? UNSIGNED : SIGNED;
1464 icode = optab_handler (uns ? umulv4_optab : mulv4_optab, mode);
1465 if (icode != CODE_FOR_nothing)
1467 struct expand_operand ops[4];
1468 rtx_insn *last = get_last_insn ();
1470 res = gen_reg_rtx (mode);
1471 create_output_operand (&ops[0], res, mode);
1472 create_input_operand (&ops[1], op0, mode);
1473 create_input_operand (&ops[2], op1, mode);
1474 create_fixed_operand (&ops[3], do_error);
1475 if (maybe_expand_insn (icode, 4, ops))
1477 last = get_last_insn ();
1478 if (profile_status_for_fn (cfun) != PROFILE_ABSENT
1480 && any_condjump_p (last)
1481 && !find_reg_note (last, REG_BR_PROB, 0))
1482 add_reg_br_prob_note (last,
1483 profile_probability::very_unlikely ());
1484 emit_jump (done_label);
1488 delete_insns_since (last);
1489 icode = CODE_FOR_nothing;
1493 if (icode == CODE_FOR_nothing)
1495 struct separate_ops ops;
1496 int prec = GET_MODE_PRECISION (mode);
1497 scalar_int_mode hmode, wmode;
1498 ops.op0 = make_tree (type, op0);
1499 ops.op1 = make_tree (type, op1);
1500 ops.op2 = NULL_TREE;
1503 /* Optimize unsigned overflow check where we don't use the
1504 multiplication result, just whether overflow happened.
1505 If we can do MULT_HIGHPART_EXPR, that followed by
1506 comparison of the result against zero is cheapest.
1507 We'll still compute res, but it should be DCEd later. */
1513 && !(uns0_p && uns1_p && !unsr_p)
1514 && can_mult_highpart_p (mode, uns) == 1
1515 && single_imm_use (lhs, &use, &use_stmt)
1516 && is_gimple_assign (use_stmt)
1517 && gimple_assign_rhs_code (use_stmt) == IMAGPART_EXPR)
1520 if (GET_MODE_2XWIDER_MODE (mode).exists (&wmode)
1521 && targetm.scalar_mode_supported_p (wmode)
1522 && can_widen_mult_without_libcall (wmode, mode, op0, op1, uns))
1525 ops.code = WIDEN_MULT_EXPR;
1527 = build_nonstandard_integer_type (GET_MODE_PRECISION (wmode), uns);
1529 res = expand_expr_real_2 (&ops, NULL_RTX, wmode, EXPAND_NORMAL);
1530 rtx hipart = expand_shift (RSHIFT_EXPR, wmode, res, prec,
1532 hipart = convert_modes (mode, wmode, hipart, uns);
1533 res = convert_modes (mode, wmode, res, uns);
1535 /* For the unsigned multiplication, there was overflow if
1536 HIPART is non-zero. */
1537 do_compare_rtx_and_jump (hipart, const0_rtx, EQ, true, mode,
1538 NULL_RTX, NULL, done_label,
1539 profile_probability::very_likely ());
1542 rtx signbit = expand_shift (RSHIFT_EXPR, mode, res, prec - 1,
1544 /* RES is low half of the double width result, HIPART
1545 the high half. There was overflow if
1546 HIPART is different from RES < 0 ? -1 : 0. */
1547 do_compare_rtx_and_jump (signbit, hipart, EQ, true, mode,
1548 NULL_RTX, NULL, done_label,
1549 profile_probability::very_likely ());
1552 else if (can_mult_highpart_p (mode, uns) == 1)
1555 ops.code = MULT_HIGHPART_EXPR;
1558 rtx hipart = expand_expr_real_2 (&ops, NULL_RTX, mode,
1560 ops.code = MULT_EXPR;
1561 res = expand_expr_real_2 (&ops, NULL_RTX, mode, EXPAND_NORMAL);
1563 /* For the unsigned multiplication, there was overflow if
1564 HIPART is non-zero. */
1565 do_compare_rtx_and_jump (hipart, const0_rtx, EQ, true, mode,
1566 NULL_RTX, NULL, done_label,
1567 profile_probability::very_likely ());
1570 rtx signbit = expand_shift (RSHIFT_EXPR, mode, res, prec - 1,
1572 /* RES is low half of the double width result, HIPART
1573 the high half. There was overflow if
1574 HIPART is different from RES < 0 ? -1 : 0. */
1575 do_compare_rtx_and_jump (signbit, hipart, EQ, true, mode,
1576 NULL_RTX, NULL, done_label,
1577 profile_probability::very_likely ());
1581 else if (int_mode_for_size (prec / 2, 1).exists (&hmode)
1582 && 2 * GET_MODE_PRECISION (hmode) == prec)
1584 rtx_code_label *large_op0 = gen_label_rtx ();
1585 rtx_code_label *small_op0_large_op1 = gen_label_rtx ();
1586 rtx_code_label *one_small_one_large = gen_label_rtx ();
1587 rtx_code_label *both_ops_large = gen_label_rtx ();
1588 rtx_code_label *after_hipart_neg = uns ? NULL : gen_label_rtx ();
1589 rtx_code_label *after_lopart_neg = uns ? NULL : gen_label_rtx ();
1590 rtx_code_label *do_overflow = gen_label_rtx ();
1591 rtx_code_label *hipart_different = uns ? NULL : gen_label_rtx ();
1593 unsigned int hprec = GET_MODE_PRECISION (hmode);
1594 rtx hipart0 = expand_shift (RSHIFT_EXPR, mode, op0, hprec,
1596 hipart0 = convert_modes (hmode, mode, hipart0, uns);
1597 rtx lopart0 = convert_modes (hmode, mode, op0, uns);
1598 rtx signbit0 = const0_rtx;
1600 signbit0 = expand_shift (RSHIFT_EXPR, hmode, lopart0, hprec - 1,
1602 rtx hipart1 = expand_shift (RSHIFT_EXPR, mode, op1, hprec,
1604 hipart1 = convert_modes (hmode, mode, hipart1, uns);
1605 rtx lopart1 = convert_modes (hmode, mode, op1, uns);
1606 rtx signbit1 = const0_rtx;
1608 signbit1 = expand_shift (RSHIFT_EXPR, hmode, lopart1, hprec - 1,
1611 res = gen_reg_rtx (mode);
1613 /* True if op0 resp. op1 are known to be in the range of
1615 bool op0_small_p = false;
1616 bool op1_small_p = false;
1617 /* True if op0 resp. op1 are known to have all zeros or all ones
1618 in the upper half of bits, but are not known to be
1620 bool op0_medium_p = false;
1621 bool op1_medium_p = false;
1622 /* -1 if op{0,1} is known to be negative, 0 if it is known to be
1623 nonnegative, 1 if unknown. */
1629 else if (pos_neg0 == 2)
1633 else if (pos_neg1 == 2)
1636 unsigned int mprec0 = prec;
1637 if (arg0 != error_mark_node)
1638 mprec0 = get_min_precision (arg0, sign);
1639 if (mprec0 <= hprec)
1641 else if (!uns && mprec0 <= hprec + 1)
1642 op0_medium_p = true;
1643 unsigned int mprec1 = prec;
1644 if (arg1 != error_mark_node)
1645 mprec1 = get_min_precision (arg1, sign);
1646 if (mprec1 <= hprec)
1648 else if (!uns && mprec1 <= hprec + 1)
1649 op1_medium_p = true;
1651 int smaller_sign = 1;
1652 int larger_sign = 1;
1655 smaller_sign = op0_sign;
1656 larger_sign = op1_sign;
1658 else if (op1_small_p)
1660 smaller_sign = op1_sign;
1661 larger_sign = op0_sign;
1663 else if (op0_sign == op1_sign)
1665 smaller_sign = op0_sign;
1666 larger_sign = op0_sign;
1670 do_compare_rtx_and_jump (signbit0, hipart0, NE, true, hmode,
1671 NULL_RTX, NULL, large_op0,
1672 profile_probability::unlikely ());
1675 do_compare_rtx_and_jump (signbit1, hipart1, NE, true, hmode,
1676 NULL_RTX, NULL, small_op0_large_op1,
1677 profile_probability::unlikely ());
1679 /* If both op0 and op1 are sign (!uns) or zero (uns) extended from
1680 hmode to mode, the multiplication will never overflow. We can
1681 do just one hmode x hmode => mode widening multiplication. */
1682 rtx lopart0s = lopart0, lopart1s = lopart1;
1683 if (GET_CODE (lopart0) == SUBREG)
1685 lopart0s = shallow_copy_rtx (lopart0);
1686 SUBREG_PROMOTED_VAR_P (lopart0s) = 1;
1687 SUBREG_PROMOTED_SET (lopart0s, uns ? SRP_UNSIGNED : SRP_SIGNED);
1689 if (GET_CODE (lopart1) == SUBREG)
1691 lopart1s = shallow_copy_rtx (lopart1);
1692 SUBREG_PROMOTED_VAR_P (lopart1s) = 1;
1693 SUBREG_PROMOTED_SET (lopart1s, uns ? SRP_UNSIGNED : SRP_SIGNED);
1695 tree halfstype = build_nonstandard_integer_type (hprec, uns);
1696 ops.op0 = make_tree (halfstype, lopart0s);
1697 ops.op1 = make_tree (halfstype, lopart1s);
1698 ops.code = WIDEN_MULT_EXPR;
1701 = expand_expr_real_2 (&ops, NULL_RTX, mode, EXPAND_NORMAL);
1702 emit_move_insn (res, thisres);
1703 emit_jump (done_label);
1705 emit_label (small_op0_large_op1);
1707 /* If op0 is sign (!uns) or zero (uns) extended from hmode to mode,
1708 but op1 is not, just swap the arguments and handle it as op1
1709 sign/zero extended, op0 not. */
1710 rtx larger = gen_reg_rtx (mode);
1711 rtx hipart = gen_reg_rtx (hmode);
1712 rtx lopart = gen_reg_rtx (hmode);
1713 emit_move_insn (larger, op1);
1714 emit_move_insn (hipart, hipart1);
1715 emit_move_insn (lopart, lopart0);
1716 emit_jump (one_small_one_large);
1718 emit_label (large_op0);
1721 do_compare_rtx_and_jump (signbit1, hipart1, NE, true, hmode,
1722 NULL_RTX, NULL, both_ops_large,
1723 profile_probability::unlikely ());
1725 /* If op1 is sign (!uns) or zero (uns) extended from hmode to mode,
1726 but op0 is not, prepare larger, hipart and lopart pseudos and
1727 handle it together with small_op0_large_op1. */
1728 emit_move_insn (larger, op0);
1729 emit_move_insn (hipart, hipart0);
1730 emit_move_insn (lopart, lopart1);
1732 emit_label (one_small_one_large);
1734 /* lopart is the low part of the operand that is sign extended
1735 to mode, larger is the other operand, hipart is the
1736 high part of larger and lopart0 and lopart1 are the low parts
1738 We perform lopart0 * lopart1 and lopart * hipart widening
1740 tree halfutype = build_nonstandard_integer_type (hprec, 1);
1741 ops.op0 = make_tree (halfutype, lopart0);
1742 ops.op1 = make_tree (halfutype, lopart1);
1744 = expand_expr_real_2 (&ops, NULL_RTX, mode, EXPAND_NORMAL);
1746 ops.op0 = make_tree (halfutype, lopart);
1747 ops.op1 = make_tree (halfutype, hipart);
1748 rtx loxhi = gen_reg_rtx (mode);
1749 rtx tem = expand_expr_real_2 (&ops, NULL_RTX, mode, EXPAND_NORMAL);
1750 emit_move_insn (loxhi, tem);
1754 /* if (hipart < 0) loxhi -= lopart << (bitsize / 2); */
1755 if (larger_sign == 0)
1756 emit_jump (after_hipart_neg);
1757 else if (larger_sign != -1)
1758 do_compare_rtx_and_jump (hipart, const0_rtx, GE, false, hmode,
1759 NULL_RTX, NULL, after_hipart_neg,
1760 profile_probability::even ());
1762 tem = convert_modes (mode, hmode, lopart, 1);
1763 tem = expand_shift (LSHIFT_EXPR, mode, tem, hprec, NULL_RTX, 1);
1764 tem = expand_simple_binop (mode, MINUS, loxhi, tem, NULL_RTX,
1766 emit_move_insn (loxhi, tem);
1768 emit_label (after_hipart_neg);
1770 /* if (lopart < 0) loxhi -= larger; */
1771 if (smaller_sign == 0)
1772 emit_jump (after_lopart_neg);
1773 else if (smaller_sign != -1)
1774 do_compare_rtx_and_jump (lopart, const0_rtx, GE, false, hmode,
1775 NULL_RTX, NULL, after_lopart_neg,
1776 profile_probability::even ());
1778 tem = expand_simple_binop (mode, MINUS, loxhi, larger, NULL_RTX,
1780 emit_move_insn (loxhi, tem);
1782 emit_label (after_lopart_neg);
1785 /* loxhi += (uns) lo0xlo1 >> (bitsize / 2); */
1786 tem = expand_shift (RSHIFT_EXPR, mode, lo0xlo1, hprec, NULL_RTX, 1);
1787 tem = expand_simple_binop (mode, PLUS, loxhi, tem, NULL_RTX,
1789 emit_move_insn (loxhi, tem);
1791 /* if (loxhi >> (bitsize / 2)
1792 == (hmode) loxhi >> (bitsize / 2 - 1)) (if !uns)
1793 if (loxhi >> (bitsize / 2) == 0 (if uns). */
1794 rtx hipartloxhi = expand_shift (RSHIFT_EXPR, mode, loxhi, hprec,
1796 hipartloxhi = convert_modes (hmode, mode, hipartloxhi, 0);
1797 rtx signbitloxhi = const0_rtx;
1799 signbitloxhi = expand_shift (RSHIFT_EXPR, hmode,
1800 convert_modes (hmode, mode,
1802 hprec - 1, NULL_RTX, 0);
1804 do_compare_rtx_and_jump (signbitloxhi, hipartloxhi, NE, true, hmode,
1805 NULL_RTX, NULL, do_overflow,
1806 profile_probability::very_unlikely ());
1808 /* res = (loxhi << (bitsize / 2)) | (hmode) lo0xlo1; */
1809 rtx loxhishifted = expand_shift (LSHIFT_EXPR, mode, loxhi, hprec,
1811 tem = convert_modes (mode, hmode,
1812 convert_modes (hmode, mode, lo0xlo1, 1), 1);
1814 tem = expand_simple_binop (mode, IOR, loxhishifted, tem, res,
1817 emit_move_insn (res, tem);
1818 emit_jump (done_label);
1820 emit_label (both_ops_large);
1822 /* If both operands are large (not sign (!uns) or zero (uns)
1823 extended from hmode), then perform the full multiplication
1824 which will be the result of the operation.
1825 The only cases which don't overflow are for signed multiplication
1826 some cases where both hipart0 and highpart1 are 0 or -1.
1827 For unsigned multiplication when high parts are both non-zero
1828 this overflows always. */
1829 ops.code = MULT_EXPR;
1830 ops.op0 = make_tree (type, op0);
1831 ops.op1 = make_tree (type, op1);
1832 tem = expand_expr_real_2 (&ops, NULL_RTX, mode, EXPAND_NORMAL);
1833 emit_move_insn (res, tem);
1839 tem = expand_simple_binop (hmode, PLUS, hipart0, const1_rtx,
1840 NULL_RTX, 1, OPTAB_WIDEN);
1841 do_compare_rtx_and_jump (tem, const1_rtx, GTU, true, hmode,
1842 NULL_RTX, NULL, do_error,
1843 profile_probability::very_unlikely ());
1848 tem = expand_simple_binop (hmode, PLUS, hipart1, const1_rtx,
1849 NULL_RTX, 1, OPTAB_WIDEN);
1850 do_compare_rtx_and_jump (tem, const1_rtx, GTU, true, hmode,
1851 NULL_RTX, NULL, do_error,
1852 profile_probability::very_unlikely ());
1855 /* At this point hipart{0,1} are both in [-1, 0]. If they are
1856 the same, overflow happened if res is non-positive, if they
1857 are different, overflow happened if res is positive. */
1858 if (op0_sign != 1 && op1_sign != 1 && op0_sign != op1_sign)
1859 emit_jump (hipart_different);
1860 else if (op0_sign == 1 || op1_sign == 1)
1861 do_compare_rtx_and_jump (hipart0, hipart1, NE, true, hmode,
1862 NULL_RTX, NULL, hipart_different,
1863 profile_probability::even ());
1865 do_compare_rtx_and_jump (res, const0_rtx, LE, false, mode,
1866 NULL_RTX, NULL, do_error,
1867 profile_probability::very_unlikely ());
1868 emit_jump (done_label);
1870 emit_label (hipart_different);
1872 do_compare_rtx_and_jump (res, const0_rtx, GE, false, mode,
1873 NULL_RTX, NULL, do_error,
1874 profile_probability::very_unlikely ());
1875 emit_jump (done_label);
1878 emit_label (do_overflow);
1880 /* Overflow, do full multiplication and fallthru into do_error. */
1881 ops.op0 = make_tree (type, op0);
1882 ops.op1 = make_tree (type, op1);
1883 tem = expand_expr_real_2 (&ops, NULL_RTX, mode, EXPAND_NORMAL);
1884 emit_move_insn (res, tem);
1886 else if (GET_MODE_2XWIDER_MODE (mode).exists (&wmode)
1887 && targetm.scalar_mode_supported_p (wmode))
1888 /* Even emitting a libcall is better than not detecting overflow
1893 gcc_assert (!is_ubsan);
1894 ops.code = MULT_EXPR;
1896 res = expand_expr_real_2 (&ops, NULL_RTX, mode, EXPAND_NORMAL);
1897 emit_jump (done_label);
1902 emit_label (do_error);
1905 /* Expand the ubsan builtin call. */
1907 fn = ubsan_build_overflow_builtin (MULT_EXPR, loc, TREE_TYPE (arg0),
1911 do_pending_stack_adjust ();
1914 expand_arith_set_overflow (lhs, target);
1917 emit_label (done_label);
1920 if (uns0_p && uns1_p && !unsr_p)
1922 rtx_code_label *all_done_label = gen_label_rtx ();
1923 do_compare_rtx_and_jump (res, const0_rtx, GE, false, mode, NULL_RTX,
1924 NULL, all_done_label, profile_probability::very_likely ());
1925 expand_arith_set_overflow (lhs, target);
1926 emit_label (all_done_label);
1930 if (!uns0_p && uns1_p && !unsr_p && pos_neg1 == 3)
1932 rtx_code_label *all_done_label = gen_label_rtx ();
1933 rtx_code_label *set_noovf = gen_label_rtx ();
1934 do_compare_rtx_and_jump (op1, const0_rtx, GE, false, mode, NULL_RTX,
1935 NULL, all_done_label, profile_probability::very_likely ());
1936 expand_arith_set_overflow (lhs, target);
1937 do_compare_rtx_and_jump (op0, const0_rtx, EQ, true, mode, NULL_RTX,
1938 NULL, set_noovf, profile_probability::very_likely ());
1939 do_compare_rtx_and_jump (op0, constm1_rtx, NE, true, mode, NULL_RTX,
1940 NULL, all_done_label, profile_probability::very_unlikely ());
1941 do_compare_rtx_and_jump (op1, res, NE, true, mode, NULL_RTX, NULL,
1942 all_done_label, profile_probability::very_unlikely ());
1943 emit_label (set_noovf);
1944 write_complex_part (target, const0_rtx, true);
1945 emit_label (all_done_label);
1951 expand_ubsan_result_store (target, res);
1953 expand_arith_overflow_result_store (lhs, target, mode, res);
1957 /* Expand UBSAN_CHECK_* internal function if it has vector operands. */
1960 expand_vector_ubsan_overflow (location_t loc, enum tree_code code, tree lhs,
1961 tree arg0, tree arg1)
1963 int cnt = TYPE_VECTOR_SUBPARTS (TREE_TYPE (arg0));
1964 rtx_code_label *loop_lab = NULL;
1965 rtx cntvar = NULL_RTX;
1966 tree cntv = NULL_TREE;
1967 tree eltype = TREE_TYPE (TREE_TYPE (arg0));
1968 tree sz = TYPE_SIZE (eltype);
1969 tree data = NULL_TREE;
1970 tree resv = NULL_TREE;
1971 rtx lhsr = NULL_RTX;
1972 rtx resvr = NULL_RTX;
1977 lhsr = expand_expr (lhs, NULL_RTX, VOIDmode, EXPAND_WRITE);
1978 if (!VECTOR_MODE_P (GET_MODE (lhsr))
1979 || (op = optab_for_tree_code (code, TREE_TYPE (arg0),
1980 optab_default)) == unknown_optab
1981 || (optab_handler (op, TYPE_MODE (TREE_TYPE (arg0)))
1982 == CODE_FOR_nothing))
1985 resv = make_tree (TREE_TYPE (lhs), lhsr);
1988 resvr = assign_temp (TREE_TYPE (lhs), 1, 1);
1989 resv = make_tree (TREE_TYPE (lhs), resvr);
1995 do_pending_stack_adjust ();
1996 loop_lab = gen_label_rtx ();
1997 cntvar = gen_reg_rtx (TYPE_MODE (sizetype));
1998 cntv = make_tree (sizetype, cntvar);
1999 emit_move_insn (cntvar, const0_rtx);
2000 emit_label (loop_lab);
2002 if (TREE_CODE (arg0) != VECTOR_CST)
2004 rtx arg0r = expand_normal (arg0);
2005 arg0 = make_tree (TREE_TYPE (arg0), arg0r);
2007 if (TREE_CODE (arg1) != VECTOR_CST)
2009 rtx arg1r = expand_normal (arg1);
2010 arg1 = make_tree (TREE_TYPE (arg1), arg1r);
2012 for (int i = 0; i < (cnt > 4 ? 1 : cnt); i++)
2014 tree op0, op1, res = NULL_TREE;
2017 tree atype = build_array_type_nelts (eltype, cnt);
2018 op0 = uniform_vector_p (arg0);
2019 if (op0 == NULL_TREE)
2021 op0 = fold_build1_loc (loc, VIEW_CONVERT_EXPR, atype, arg0);
2022 op0 = build4_loc (loc, ARRAY_REF, eltype, op0, cntv,
2023 NULL_TREE, NULL_TREE);
2025 op1 = uniform_vector_p (arg1);
2026 if (op1 == NULL_TREE)
2028 op1 = fold_build1_loc (loc, VIEW_CONVERT_EXPR, atype, arg1);
2029 op1 = build4_loc (loc, ARRAY_REF, eltype, op1, cntv,
2030 NULL_TREE, NULL_TREE);
2034 res = fold_build1_loc (loc, VIEW_CONVERT_EXPR, atype, resv);
2035 res = build4_loc (loc, ARRAY_REF, eltype, res, cntv,
2036 NULL_TREE, NULL_TREE);
2041 tree bitpos = bitsize_int (tree_to_uhwi (sz) * i);
2042 op0 = fold_build3_loc (loc, BIT_FIELD_REF, eltype, arg0, sz, bitpos);
2043 op1 = fold_build3_loc (loc, BIT_FIELD_REF, eltype, arg1, sz, bitpos);
2045 res = fold_build3_loc (loc, BIT_FIELD_REF, eltype, resv, sz,
2051 expand_addsub_overflow (loc, PLUS_EXPR, res, op0, op1,
2052 false, false, false, true, &data);
2055 if (cnt > 4 ? integer_zerop (arg0) : integer_zerop (op0))
2056 expand_neg_overflow (loc, res, op1, true, &data);
2058 expand_addsub_overflow (loc, MINUS_EXPR, res, op0, op1,
2059 false, false, false, true, &data);
2062 expand_mul_overflow (loc, res, op0, op1, false, false, false,
2071 struct separate_ops ops;
2072 ops.code = PLUS_EXPR;
2073 ops.type = TREE_TYPE (cntv);
2075 ops.op1 = build_int_cst (TREE_TYPE (cntv), 1);
2076 ops.op2 = NULL_TREE;
2078 rtx ret = expand_expr_real_2 (&ops, cntvar, TYPE_MODE (sizetype),
2081 emit_move_insn (cntvar, ret);
2082 do_compare_rtx_and_jump (cntvar, GEN_INT (cnt), NE, false,
2083 TYPE_MODE (sizetype), NULL_RTX, NULL, loop_lab,
2084 profile_probability::very_likely ());
2086 if (lhs && resv == NULL_TREE)
2088 struct separate_ops ops;
2090 ops.type = TREE_TYPE (arg0);
2093 ops.op2 = NULL_TREE;
2095 rtx ret = expand_expr_real_2 (&ops, lhsr, TYPE_MODE (TREE_TYPE (arg0)),
2098 emit_move_insn (lhsr, ret);
2101 emit_move_insn (lhsr, resvr);
2104 /* Expand UBSAN_CHECK_ADD call STMT. */
2107 expand_UBSAN_CHECK_ADD (internal_fn, gcall *stmt)
2109 location_t loc = gimple_location (stmt);
2110 tree lhs = gimple_call_lhs (stmt);
2111 tree arg0 = gimple_call_arg (stmt, 0);
2112 tree arg1 = gimple_call_arg (stmt, 1);
2113 if (VECTOR_TYPE_P (TREE_TYPE (arg0)))
2114 expand_vector_ubsan_overflow (loc, PLUS_EXPR, lhs, arg0, arg1);
2116 expand_addsub_overflow (loc, PLUS_EXPR, lhs, arg0, arg1,
2117 false, false, false, true, NULL);
2120 /* Expand UBSAN_CHECK_SUB call STMT. */
2123 expand_UBSAN_CHECK_SUB (internal_fn, gcall *stmt)
2125 location_t loc = gimple_location (stmt);
2126 tree lhs = gimple_call_lhs (stmt);
2127 tree arg0 = gimple_call_arg (stmt, 0);
2128 tree arg1 = gimple_call_arg (stmt, 1);
2129 if (VECTOR_TYPE_P (TREE_TYPE (arg0)))
2130 expand_vector_ubsan_overflow (loc, MINUS_EXPR, lhs, arg0, arg1);
2131 else if (integer_zerop (arg0))
2132 expand_neg_overflow (loc, lhs, arg1, true, NULL);
2134 expand_addsub_overflow (loc, MINUS_EXPR, lhs, arg0, arg1,
2135 false, false, false, true, NULL);
2138 /* Expand UBSAN_CHECK_MUL call STMT. */
2141 expand_UBSAN_CHECK_MUL (internal_fn, gcall *stmt)
2143 location_t loc = gimple_location (stmt);
2144 tree lhs = gimple_call_lhs (stmt);
2145 tree arg0 = gimple_call_arg (stmt, 0);
2146 tree arg1 = gimple_call_arg (stmt, 1);
2147 if (VECTOR_TYPE_P (TREE_TYPE (arg0)))
2148 expand_vector_ubsan_overflow (loc, MULT_EXPR, lhs, arg0, arg1);
2150 expand_mul_overflow (loc, lhs, arg0, arg1, false, false, false, true,
2154 /* Helper function for {ADD,SUB,MUL}_OVERFLOW call stmt expansion. */
2157 expand_arith_overflow (enum tree_code code, gimple *stmt)
2159 tree lhs = gimple_call_lhs (stmt);
2160 if (lhs == NULL_TREE)
2162 tree arg0 = gimple_call_arg (stmt, 0);
2163 tree arg1 = gimple_call_arg (stmt, 1);
2164 tree type = TREE_TYPE (TREE_TYPE (lhs));
2165 int uns0_p = TYPE_UNSIGNED (TREE_TYPE (arg0));
2166 int uns1_p = TYPE_UNSIGNED (TREE_TYPE (arg1));
2167 int unsr_p = TYPE_UNSIGNED (type);
2168 int prec0 = TYPE_PRECISION (TREE_TYPE (arg0));
2169 int prec1 = TYPE_PRECISION (TREE_TYPE (arg1));
2170 int precres = TYPE_PRECISION (type);
2171 location_t loc = gimple_location (stmt);
2172 if (!uns0_p && get_range_pos_neg (arg0) == 1)
2174 if (!uns1_p && get_range_pos_neg (arg1) == 1)
2176 int pr = get_min_precision (arg0, uns0_p ? UNSIGNED : SIGNED);
2177 prec0 = MIN (prec0, pr);
2178 pr = get_min_precision (arg1, uns1_p ? UNSIGNED : SIGNED);
2179 prec1 = MIN (prec1, pr);
2181 /* If uns0_p && uns1_p, precop is minimum needed precision
2182 of unsigned type to hold the exact result, otherwise
2183 precop is minimum needed precision of signed type to
2184 hold the exact result. */
2186 if (code == MULT_EXPR)
2187 precop = prec0 + prec1 + (uns0_p != uns1_p);
2190 if (uns0_p == uns1_p)
2191 precop = MAX (prec0, prec1) + 1;
2193 precop = MAX (prec0 + 1, prec1) + 1;
2195 precop = MAX (prec0, prec1 + 1) + 1;
2197 int orig_precres = precres;
2201 if ((uns0_p && uns1_p)
2202 ? ((precop + !unsr_p) <= precres
2203 /* u1 - u2 -> ur can overflow, no matter what precision
2205 && (code != MINUS_EXPR || !unsr_p))
2206 : (!unsr_p && precop <= precres))
2208 /* The infinity precision result will always fit into result. */
2209 rtx target = expand_expr (lhs, NULL_RTX, VOIDmode, EXPAND_WRITE);
2210 write_complex_part (target, const0_rtx, true);
2211 scalar_int_mode mode = SCALAR_INT_TYPE_MODE (type);
2212 struct separate_ops ops;
2215 ops.op0 = fold_convert_loc (loc, type, arg0);
2216 ops.op1 = fold_convert_loc (loc, type, arg1);
2217 ops.op2 = NULL_TREE;
2219 rtx tem = expand_expr_real_2 (&ops, NULL_RTX, mode, EXPAND_NORMAL);
2220 expand_arith_overflow_result_store (lhs, target, mode, tem);
2224 /* For operations with low precision, if target doesn't have them, start
2225 with precres widening right away, otherwise do it only if the most
2226 simple cases can't be used. */
2227 const int min_precision = targetm.min_arithmetic_precision ();
2228 if (orig_precres == precres && precres < min_precision)
2230 else if ((uns0_p && uns1_p && unsr_p && prec0 <= precres
2231 && prec1 <= precres)
2232 || ((!uns0_p || !uns1_p) && !unsr_p
2233 && prec0 + uns0_p <= precres
2234 && prec1 + uns1_p <= precres))
2236 arg0 = fold_convert_loc (loc, type, arg0);
2237 arg1 = fold_convert_loc (loc, type, arg1);
2241 if (integer_zerop (arg0) && !unsr_p)
2243 expand_neg_overflow (loc, lhs, arg1, false, NULL);
2248 expand_addsub_overflow (loc, code, lhs, arg0, arg1, unsr_p,
2249 unsr_p, unsr_p, false, NULL);
2252 expand_mul_overflow (loc, lhs, arg0, arg1, unsr_p,
2253 unsr_p, unsr_p, false, NULL);
2260 /* For sub-word operations, retry with a wider type first. */
2261 if (orig_precres == precres && precop <= BITS_PER_WORD)
2263 int p = MAX (min_precision, precop);
2264 scalar_int_mode m = smallest_int_mode_for_size (p);
2265 tree optype = build_nonstandard_integer_type (GET_MODE_PRECISION (m),
2268 p = TYPE_PRECISION (optype);
2272 unsr_p = TYPE_UNSIGNED (optype);
2278 if (prec0 <= precres && prec1 <= precres)
2283 types[0] = build_nonstandard_integer_type (precres, 0);
2289 types[1] = build_nonstandard_integer_type (precres, 1);
2291 arg0 = fold_convert_loc (loc, types[uns0_p], arg0);
2292 arg1 = fold_convert_loc (loc, types[uns1_p], arg1);
2293 if (code != MULT_EXPR)
2294 expand_addsub_overflow (loc, code, lhs, arg0, arg1, unsr_p,
2295 uns0_p, uns1_p, false, NULL);
2297 expand_mul_overflow (loc, lhs, arg0, arg1, unsr_p,
2298 uns0_p, uns1_p, false, NULL);
2302 /* Retry with a wider type. */
2303 if (orig_precres == precres)
2305 int p = MAX (prec0, prec1);
2306 scalar_int_mode m = smallest_int_mode_for_size (p);
2307 tree optype = build_nonstandard_integer_type (GET_MODE_PRECISION (m),
2310 p = TYPE_PRECISION (optype);
2314 unsr_p = TYPE_UNSIGNED (optype);
2325 /* Expand ADD_OVERFLOW STMT. */
2328 expand_ADD_OVERFLOW (internal_fn, gcall *stmt)
2330 expand_arith_overflow (PLUS_EXPR, stmt);
2333 /* Expand SUB_OVERFLOW STMT. */
2336 expand_SUB_OVERFLOW (internal_fn, gcall *stmt)
2338 expand_arith_overflow (MINUS_EXPR, stmt);
2341 /* Expand MUL_OVERFLOW STMT. */
2344 expand_MUL_OVERFLOW (internal_fn, gcall *stmt)
2346 expand_arith_overflow (MULT_EXPR, stmt);
2349 /* This should get folded in tree-vectorizer.c. */
2352 expand_LOOP_VECTORIZED (internal_fn, gcall *)
2357 /* This should get folded in tree-vectorizer.c. */
2360 expand_LOOP_DIST_ALIAS (internal_fn, gcall *)
2365 /* Expand MASK_LOAD call STMT using optab OPTAB. */
2368 expand_mask_load_optab_fn (internal_fn, gcall *stmt, convert_optab optab)
2370 struct expand_operand ops[3];
2371 tree type, lhs, rhs, maskt, ptr;
2372 rtx mem, target, mask;
2375 maskt = gimple_call_arg (stmt, 2);
2376 lhs = gimple_call_lhs (stmt);
2377 if (lhs == NULL_TREE)
2379 type = TREE_TYPE (lhs);
2380 ptr = build_int_cst (TREE_TYPE (gimple_call_arg (stmt, 1)), 0);
2381 align = tree_to_shwi (gimple_call_arg (stmt, 1));
2382 if (TYPE_ALIGN (type) != align)
2383 type = build_aligned_type (type, align);
2384 rhs = fold_build2 (MEM_REF, type, gimple_call_arg (stmt, 0), ptr);
2386 mem = expand_expr (rhs, NULL_RTX, VOIDmode, EXPAND_WRITE);
2387 gcc_assert (MEM_P (mem));
2388 mask = expand_normal (maskt);
2389 target = expand_expr (lhs, NULL_RTX, VOIDmode, EXPAND_WRITE);
2390 create_output_operand (&ops[0], target, TYPE_MODE (type));
2391 create_fixed_operand (&ops[1], mem);
2392 create_input_operand (&ops[2], mask, TYPE_MODE (TREE_TYPE (maskt)));
2393 expand_insn (convert_optab_handler (optab, TYPE_MODE (type),
2394 TYPE_MODE (TREE_TYPE (maskt))),
2398 /* Expand MASK_STORE call STMT using optab OPTAB. */
2401 expand_mask_store_optab_fn (internal_fn, gcall *stmt, convert_optab optab)
2403 struct expand_operand ops[3];
2404 tree type, lhs, rhs, maskt, ptr;
2408 maskt = gimple_call_arg (stmt, 2);
2409 rhs = gimple_call_arg (stmt, 3);
2410 type = TREE_TYPE (rhs);
2411 ptr = build_int_cst (TREE_TYPE (gimple_call_arg (stmt, 1)), 0);
2412 align = tree_to_shwi (gimple_call_arg (stmt, 1));
2413 if (TYPE_ALIGN (type) != align)
2414 type = build_aligned_type (type, align);
2415 lhs = fold_build2 (MEM_REF, type, gimple_call_arg (stmt, 0), ptr);
2417 mem = expand_expr (lhs, NULL_RTX, VOIDmode, EXPAND_WRITE);
2418 gcc_assert (MEM_P (mem));
2419 mask = expand_normal (maskt);
2420 reg = expand_normal (rhs);
2421 create_fixed_operand (&ops[0], mem);
2422 create_input_operand (&ops[1], reg, TYPE_MODE (type));
2423 create_input_operand (&ops[2], mask, TYPE_MODE (TREE_TYPE (maskt)));
2424 expand_insn (convert_optab_handler (optab, TYPE_MODE (type),
2425 TYPE_MODE (TREE_TYPE (maskt))),
2430 expand_ABNORMAL_DISPATCHER (internal_fn, gcall *)
2435 expand_BUILTIN_EXPECT (internal_fn, gcall *stmt)
2437 /* When guessing was done, the hints should be already stripped away. */
2438 gcc_assert (!flag_guess_branch_prob || optimize == 0 || seen_error ());
2441 tree lhs = gimple_call_lhs (stmt);
2443 target = expand_expr (lhs, NULL_RTX, VOIDmode, EXPAND_WRITE);
2445 target = const0_rtx;
2446 rtx val = expand_expr (gimple_call_arg (stmt, 0), target, VOIDmode, EXPAND_NORMAL);
2447 if (lhs && val != target)
2448 emit_move_insn (target, val);
2451 /* IFN_VA_ARG is supposed to be expanded at pass_stdarg. So this dummy function
2452 should never be called. */
2455 expand_VA_ARG (internal_fn, gcall *)
2460 /* Expand the IFN_UNIQUE function according to its first argument. */
2463 expand_UNIQUE (internal_fn, gcall *stmt)
2465 rtx pattern = NULL_RTX;
2466 enum ifn_unique_kind kind
2467 = (enum ifn_unique_kind) TREE_INT_CST_LOW (gimple_call_arg (stmt, 0));
2474 case IFN_UNIQUE_UNSPEC:
2475 if (targetm.have_unique ())
2476 pattern = targetm.gen_unique ();
2479 case IFN_UNIQUE_OACC_FORK:
2480 case IFN_UNIQUE_OACC_JOIN:
2481 if (targetm.have_oacc_fork () && targetm.have_oacc_join ())
2483 tree lhs = gimple_call_lhs (stmt);
2484 rtx target = const0_rtx;
2487 target = expand_expr (lhs, NULL_RTX, VOIDmode, EXPAND_WRITE);
2489 rtx data_dep = expand_normal (gimple_call_arg (stmt, 1));
2490 rtx axis = expand_normal (gimple_call_arg (stmt, 2));
2492 if (kind == IFN_UNIQUE_OACC_FORK)
2493 pattern = targetm.gen_oacc_fork (target, data_dep, axis);
2495 pattern = targetm.gen_oacc_join (target, data_dep, axis);
2503 emit_insn (pattern);
2506 /* The size of an OpenACC compute dimension. */
2509 expand_GOACC_DIM_SIZE (internal_fn, gcall *stmt)
2511 tree lhs = gimple_call_lhs (stmt);
2516 rtx target = expand_expr (lhs, NULL_RTX, VOIDmode, EXPAND_WRITE);
2517 if (targetm.have_oacc_dim_size ())
2519 rtx dim = expand_expr (gimple_call_arg (stmt, 0), NULL_RTX,
2520 VOIDmode, EXPAND_NORMAL);
2521 emit_insn (targetm.gen_oacc_dim_size (target, dim));
2524 emit_move_insn (target, GEN_INT (1));
2527 /* The position of an OpenACC execution engine along one compute axis. */
2530 expand_GOACC_DIM_POS (internal_fn, gcall *stmt)
2532 tree lhs = gimple_call_lhs (stmt);
2537 rtx target = expand_expr (lhs, NULL_RTX, VOIDmode, EXPAND_WRITE);
2538 if (targetm.have_oacc_dim_pos ())
2540 rtx dim = expand_expr (gimple_call_arg (stmt, 0), NULL_RTX,
2541 VOIDmode, EXPAND_NORMAL);
2542 emit_insn (targetm.gen_oacc_dim_pos (target, dim));
2545 emit_move_insn (target, const0_rtx);
2548 /* This is expanded by oacc_device_lower pass. */
2551 expand_GOACC_LOOP (internal_fn, gcall *)
2556 /* This is expanded by oacc_device_lower pass. */
2559 expand_GOACC_REDUCTION (internal_fn, gcall *)
2564 /* This is expanded by oacc_device_lower pass. */
2567 expand_GOACC_TILE (internal_fn, gcall *)
2572 /* Set errno to EDOM. */
2575 expand_SET_EDOM (internal_fn, gcall *)
2578 #ifdef GEN_ERRNO_RTX
2579 rtx errno_rtx = GEN_ERRNO_RTX;
2581 rtx errno_rtx = gen_rtx_MEM (word_mode, gen_rtx_SYMBOL_REF (Pmode, "errno"));
2583 emit_move_insn (errno_rtx,
2584 gen_int_mode (TARGET_EDOM, GET_MODE (errno_rtx)));
2590 /* Expand atomic bit test and set. */
2593 expand_ATOMIC_BIT_TEST_AND_SET (internal_fn, gcall *call)
2595 expand_ifn_atomic_bit_test_and (call);
2598 /* Expand atomic bit test and complement. */
2601 expand_ATOMIC_BIT_TEST_AND_COMPLEMENT (internal_fn, gcall *call)
2603 expand_ifn_atomic_bit_test_and (call);
2606 /* Expand atomic bit test and reset. */
2609 expand_ATOMIC_BIT_TEST_AND_RESET (internal_fn, gcall *call)
2611 expand_ifn_atomic_bit_test_and (call);
2614 /* Expand atomic bit test and set. */
2617 expand_ATOMIC_COMPARE_EXCHANGE (internal_fn, gcall *call)
2619 expand_ifn_atomic_compare_exchange (call);
2622 /* Expand LAUNDER to assignment, lhs = arg0. */
2625 expand_LAUNDER (internal_fn, gcall *call)
2627 tree lhs = gimple_call_lhs (call);
2632 expand_assignment (lhs, gimple_call_arg (call, 0), false);
2635 /* Expand DIVMOD() using:
2636 a) optab handler for udivmod/sdivmod if it is available.
2637 b) If optab_handler doesn't exist, generate call to
2638 target-specific divmod libfunc. */
2641 expand_DIVMOD (internal_fn, gcall *call_stmt)
2643 tree lhs = gimple_call_lhs (call_stmt);
2644 tree arg0 = gimple_call_arg (call_stmt, 0);
2645 tree arg1 = gimple_call_arg (call_stmt, 1);
2647 gcc_assert (TREE_CODE (TREE_TYPE (lhs)) == COMPLEX_TYPE);
2648 tree type = TREE_TYPE (TREE_TYPE (lhs));
2649 machine_mode mode = TYPE_MODE (type);
2650 bool unsignedp = TYPE_UNSIGNED (type);
2651 optab tab = (unsignedp) ? udivmod_optab : sdivmod_optab;
2653 rtx op0 = expand_normal (arg0);
2654 rtx op1 = expand_normal (arg1);
2655 rtx target = expand_expr (lhs, NULL_RTX, VOIDmode, EXPAND_WRITE);
2657 rtx quotient, remainder, libfunc;
2659 /* Check if optab_handler exists for divmod_optab for given mode. */
2660 if (optab_handler (tab, mode) != CODE_FOR_nothing)
2662 quotient = gen_reg_rtx (mode);
2663 remainder = gen_reg_rtx (mode);
2664 expand_twoval_binop (tab, op0, op1, quotient, remainder, unsignedp);
2667 /* Generate call to divmod libfunc if it exists. */
2668 else if ((libfunc = optab_libfunc (tab, mode)) != NULL_RTX)
2669 targetm.expand_divmod_libfunc (libfunc, mode, op0, op1,
2670 "ient, &remainder);
2675 /* Wrap the return value (quotient, remainder) within COMPLEX_EXPR. */
2676 expand_expr (build2 (COMPLEX_EXPR, TREE_TYPE (lhs),
2677 make_tree (TREE_TYPE (arg0), quotient),
2678 make_tree (TREE_TYPE (arg1), remainder)),
2679 target, VOIDmode, EXPAND_NORMAL);
2682 /* Expand a call to FN using the operands in STMT. FN has a single
2683 output operand and NARGS input operands. */
2686 expand_direct_optab_fn (internal_fn fn, gcall *stmt, direct_optab optab,
2689 expand_operand *ops = XALLOCAVEC (expand_operand, nargs + 1);
2691 tree_pair types = direct_internal_fn_types (fn, stmt);
2692 insn_code icode = direct_optab_handler (optab, TYPE_MODE (types.first));
2694 tree lhs = gimple_call_lhs (stmt);
2695 tree lhs_type = TREE_TYPE (lhs);
2696 rtx lhs_rtx = expand_expr (lhs, NULL_RTX, VOIDmode, EXPAND_WRITE);
2698 /* Do not assign directly to a promoted subreg, since there is no
2699 guarantee that the instruction will leave the upper bits of the
2700 register in the state required by SUBREG_PROMOTED_SIGN. */
2702 if (GET_CODE (dest) == SUBREG && SUBREG_PROMOTED_VAR_P (dest))
2705 create_output_operand (&ops[0], dest, insn_data[icode].operand[0].mode);
2707 for (unsigned int i = 0; i < nargs; ++i)
2709 tree rhs = gimple_call_arg (stmt, i);
2710 tree rhs_type = TREE_TYPE (rhs);
2711 rtx rhs_rtx = expand_normal (rhs);
2712 if (INTEGRAL_TYPE_P (rhs_type))
2713 create_convert_operand_from (&ops[i + 1], rhs_rtx,
2714 TYPE_MODE (rhs_type),
2715 TYPE_UNSIGNED (rhs_type));
2717 create_input_operand (&ops[i + 1], rhs_rtx, TYPE_MODE (rhs_type));
2720 expand_insn (icode, nargs + 1, ops);
2721 if (!rtx_equal_p (lhs_rtx, ops[0].value))
2723 /* If the return value has an integral type, convert the instruction
2724 result to that type. This is useful for things that return an
2725 int regardless of the size of the input. If the instruction result
2726 is smaller than required, assume that it is signed.
2728 If the return value has a nonintegral type, its mode must match
2729 the instruction result. */
2730 if (GET_CODE (lhs_rtx) == SUBREG && SUBREG_PROMOTED_VAR_P (lhs_rtx))
2732 /* If this is a scalar in a register that is stored in a wider
2733 mode than the declared mode, compute the result into its
2734 declared mode and then convert to the wider mode. */
2735 gcc_checking_assert (INTEGRAL_TYPE_P (lhs_type));
2736 rtx tmp = convert_to_mode (GET_MODE (lhs_rtx), ops[0].value, 0);
2737 convert_move (SUBREG_REG (lhs_rtx), tmp,
2738 SUBREG_PROMOTED_SIGN (lhs_rtx));
2740 else if (GET_MODE (lhs_rtx) == GET_MODE (ops[0].value))
2741 emit_move_insn (lhs_rtx, ops[0].value);
2744 gcc_checking_assert (INTEGRAL_TYPE_P (lhs_type));
2745 convert_move (lhs_rtx, ops[0].value, 0);
2750 /* Expanders for optabs that can use expand_direct_optab_fn. */
2752 #define expand_unary_optab_fn(FN, STMT, OPTAB) \
2753 expand_direct_optab_fn (FN, STMT, OPTAB, 1)
2755 #define expand_binary_optab_fn(FN, STMT, OPTAB) \
2756 expand_direct_optab_fn (FN, STMT, OPTAB, 2)
2758 /* RETURN_TYPE and ARGS are a return type and argument list that are
2759 in principle compatible with FN (which satisfies direct_internal_fn_p).
2760 Return the types that should be used to determine whether the
2761 target supports FN. */
2764 direct_internal_fn_types (internal_fn fn, tree return_type, tree *args)
2766 const direct_internal_fn_info &info = direct_internal_fn (fn);
2767 tree type0 = (info.type0 < 0 ? return_type : TREE_TYPE (args[info.type0]));
2768 tree type1 = (info.type1 < 0 ? return_type : TREE_TYPE (args[info.type1]));
2769 return tree_pair (type0, type1);
2772 /* CALL is a call whose return type and arguments are in principle
2773 compatible with FN (which satisfies direct_internal_fn_p). Return the
2774 types that should be used to determine whether the target supports FN. */
2777 direct_internal_fn_types (internal_fn fn, gcall *call)
2779 const direct_internal_fn_info &info = direct_internal_fn (fn);
2780 tree op0 = (info.type0 < 0
2781 ? gimple_call_lhs (call)
2782 : gimple_call_arg (call, info.type0));
2783 tree op1 = (info.type1 < 0
2784 ? gimple_call_lhs (call)
2785 : gimple_call_arg (call, info.type1));
2786 return tree_pair (TREE_TYPE (op0), TREE_TYPE (op1));
2789 /* Return true if OPTAB is supported for TYPES (whose modes should be
2790 the same) when the optimization type is OPT_TYPE. Used for simple
2794 direct_optab_supported_p (direct_optab optab, tree_pair types,
2795 optimization_type opt_type)
2797 machine_mode mode = TYPE_MODE (types.first);
2798 gcc_checking_assert (mode == TYPE_MODE (types.second));
2799 return direct_optab_handler (optab, mode, opt_type) != CODE_FOR_nothing;
2802 /* Return true if load/store lanes optab OPTAB is supported for
2803 array type TYPES.first when the optimization type is OPT_TYPE. */
2806 multi_vector_optab_supported_p (convert_optab optab, tree_pair types,
2807 optimization_type opt_type)
2809 gcc_assert (TREE_CODE (types.first) == ARRAY_TYPE);
2810 machine_mode imode = TYPE_MODE (types.first);
2811 machine_mode vmode = TYPE_MODE (TREE_TYPE (types.first));
2812 return (convert_optab_handler (optab, imode, vmode, opt_type)
2813 != CODE_FOR_nothing);
2816 #define direct_unary_optab_supported_p direct_optab_supported_p
2817 #define direct_binary_optab_supported_p direct_optab_supported_p
2818 #define direct_mask_load_optab_supported_p direct_optab_supported_p
2819 #define direct_load_lanes_optab_supported_p multi_vector_optab_supported_p
2820 #define direct_mask_store_optab_supported_p direct_optab_supported_p
2821 #define direct_store_lanes_optab_supported_p multi_vector_optab_supported_p
2823 /* Return the optab used by internal function FN. */
2826 direct_internal_fn_optab (internal_fn fn, tree_pair types)
2830 #define DEF_INTERNAL_FN(CODE, FLAGS, FNSPEC) \
2831 case IFN_##CODE: break;
2832 #define DEF_INTERNAL_OPTAB_FN(CODE, FLAGS, OPTAB, TYPE) \
2833 case IFN_##CODE: return OPTAB##_optab;
2834 #define DEF_INTERNAL_SIGNED_OPTAB_FN(CODE, FLAGS, SELECTOR, SIGNED_OPTAB, \
2835 UNSIGNED_OPTAB, TYPE) \
2836 case IFN_##CODE: return (TYPE_UNSIGNED (types.SELECTOR) \
2837 ? UNSIGNED_OPTAB ## _optab \
2838 : SIGNED_OPTAB ## _optab);
2839 #include "internal-fn.def"
2847 /* Return true if FN is supported for the types in TYPES when the
2848 optimization type is OPT_TYPE. The types are those associated with
2849 the "type0" and "type1" fields of FN's direct_internal_fn_info
2853 direct_internal_fn_supported_p (internal_fn fn, tree_pair types,
2854 optimization_type opt_type)
2858 #define DEF_INTERNAL_FN(CODE, FLAGS, FNSPEC) \
2859 case IFN_##CODE: break;
2860 #define DEF_INTERNAL_OPTAB_FN(CODE, FLAGS, OPTAB, TYPE) \
2862 return direct_##TYPE##_optab_supported_p (OPTAB##_optab, types, \
2864 #define DEF_INTERNAL_SIGNED_OPTAB_FN(CODE, FLAGS, SELECTOR, SIGNED_OPTAB, \
2865 UNSIGNED_OPTAB, TYPE) \
2868 optab which_optab = (TYPE_UNSIGNED (types.SELECTOR) \
2869 ? UNSIGNED_OPTAB ## _optab \
2870 : SIGNED_OPTAB ## _optab); \
2871 return direct_##TYPE##_optab_supported_p (which_optab, types, \
2874 #include "internal-fn.def"
2882 /* Return true if FN is supported for type TYPE when the optimization
2883 type is OPT_TYPE. The caller knows that the "type0" and "type1"
2884 fields of FN's direct_internal_fn_info structure are the same. */
2887 direct_internal_fn_supported_p (internal_fn fn, tree type,
2888 optimization_type opt_type)
2890 const direct_internal_fn_info &info = direct_internal_fn (fn);
2891 gcc_checking_assert (info.type0 == info.type1);
2892 return direct_internal_fn_supported_p (fn, tree_pair (type, type), opt_type);
2895 /* Return true if IFN_SET_EDOM is supported. */
2898 set_edom_supported_p (void)
2907 #define DEF_INTERNAL_OPTAB_FN(CODE, FLAGS, OPTAB, TYPE) \
2909 expand_##CODE (internal_fn fn, gcall *stmt) \
2911 expand_##TYPE##_optab_fn (fn, stmt, OPTAB##_optab); \
2913 #define DEF_INTERNAL_SIGNED_OPTAB_FN(CODE, FLAGS, SELECTOR, SIGNED_OPTAB, \
2914 UNSIGNED_OPTAB, TYPE) \
2916 expand_##CODE (internal_fn fn, gcall *stmt) \
2918 tree_pair types = direct_internal_fn_types (fn, stmt); \
2919 optab which_optab = direct_internal_fn_optab (fn, types); \
2920 expand_##TYPE##_optab_fn (fn, stmt, which_optab); \
2922 #include "internal-fn.def"
2924 /* Routines to expand each internal function, indexed by function number.
2925 Each routine has the prototype:
2927 expand_<NAME> (gcall *stmt)
2929 where STMT is the statement that performs the call. */
2930 static void (*const internal_fn_expanders[]) (internal_fn, gcall *) = {
2931 #define DEF_INTERNAL_FN(CODE, FLAGS, FNSPEC) expand_##CODE,
2932 #include "internal-fn.def"
2936 /* Expand STMT as though it were a call to internal function FN. */
2939 expand_internal_call (internal_fn fn, gcall *stmt)
2941 internal_fn_expanders[fn] (fn, stmt);
2944 /* Expand STMT, which is a call to internal function FN. */
2947 expand_internal_call (gcall *stmt)
2949 expand_internal_call (gimple_call_internal_fn (stmt), stmt);
2953 expand_PHI (internal_fn, gcall *)