2 Copyright (C) 2011-2015 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"
30 #include "tree-ssanames.h"
34 #include "diagnostic-core.h"
35 #include "fold-const.h"
36 #include "internal-fn.h"
37 #include "stor-layout.h"
43 /* The names of each internal function, indexed by function number. */
44 const char *const internal_fn_name_array[] = {
45 #define DEF_INTERNAL_FN(CODE, FLAGS, FNSPEC) #CODE,
46 #include "internal-fn.def"
50 /* The ECF_* flags of each internal function, indexed by function number. */
51 const int internal_fn_flags_array[] = {
52 #define DEF_INTERNAL_FN(CODE, FLAGS, FNSPEC) FLAGS,
53 #include "internal-fn.def"
57 /* Fnspec of each internal function, indexed by function number. */
58 const_tree internal_fn_fnspec_array[IFN_LAST + 1];
63 #define DEF_INTERNAL_FN(CODE, FLAGS, FNSPEC) \
64 if (FNSPEC) internal_fn_fnspec_array[IFN_##CODE] = \
65 build_string ((int) sizeof (FNSPEC), FNSPEC ? FNSPEC : "");
66 #include "internal-fn.def"
67 internal_fn_fnspec_array[IFN_LAST] = 0;
70 /* Create static initializers for the information returned by
71 direct_internal_fn. */
72 #define not_direct { -2, -2, false }
73 #define mask_load_direct { -1, 2, false }
74 #define load_lanes_direct { -1, -1, false }
75 #define mask_store_direct { 3, 2, false }
76 #define store_lanes_direct { 0, 0, false }
77 #define unary_direct { 0, 0, true }
78 #define binary_direct { 0, 0, true }
80 const direct_internal_fn_info direct_internal_fn_array[IFN_LAST + 1] = {
81 #define DEF_INTERNAL_FN(CODE, FLAGS, FNSPEC) not_direct,
82 #define DEF_INTERNAL_OPTAB_FN(CODE, FLAGS, OPTAB, TYPE) TYPE##_direct,
83 #include "internal-fn.def"
87 /* ARRAY_TYPE is an array of vector modes. Return the associated insn
88 for load-lanes-style optab OPTAB, or CODE_FOR_nothing if none. */
91 get_multi_vector_move (tree array_type, convert_optab optab)
96 gcc_assert (TREE_CODE (array_type) == ARRAY_TYPE);
97 imode = TYPE_MODE (array_type);
98 vmode = TYPE_MODE (TREE_TYPE (array_type));
100 return convert_optab_handler (optab, imode, vmode);
103 /* Expand LOAD_LANES call STMT using optab OPTAB. */
106 expand_load_lanes_optab_fn (internal_fn, gcall *stmt, convert_optab optab)
108 struct expand_operand ops[2];
112 lhs = gimple_call_lhs (stmt);
113 rhs = gimple_call_arg (stmt, 0);
114 type = TREE_TYPE (lhs);
116 target = expand_expr (lhs, NULL_RTX, VOIDmode, EXPAND_WRITE);
117 mem = expand_normal (rhs);
119 gcc_assert (MEM_P (mem));
120 PUT_MODE (mem, TYPE_MODE (type));
122 create_output_operand (&ops[0], target, TYPE_MODE (type));
123 create_fixed_operand (&ops[1], mem);
124 expand_insn (get_multi_vector_move (type, optab), 2, ops);
127 /* Expand STORE_LANES call STMT using optab OPTAB. */
130 expand_store_lanes_optab_fn (internal_fn, gcall *stmt, convert_optab optab)
132 struct expand_operand ops[2];
136 lhs = gimple_call_lhs (stmt);
137 rhs = gimple_call_arg (stmt, 0);
138 type = TREE_TYPE (rhs);
140 target = expand_expr (lhs, NULL_RTX, VOIDmode, EXPAND_WRITE);
141 reg = expand_normal (rhs);
143 gcc_assert (MEM_P (target));
144 PUT_MODE (target, TYPE_MODE (type));
146 create_fixed_operand (&ops[0], target);
147 create_input_operand (&ops[1], reg, TYPE_MODE (type));
148 expand_insn (get_multi_vector_move (type, optab), 2, ops);
152 expand_ANNOTATE (internal_fn, gcall *)
157 /* This should get expanded in adjust_simduid_builtins. */
160 expand_GOMP_SIMD_LANE (internal_fn, gcall *)
165 /* This should get expanded in adjust_simduid_builtins. */
168 expand_GOMP_SIMD_VF (internal_fn, gcall *)
173 /* This should get expanded in adjust_simduid_builtins. */
176 expand_GOMP_SIMD_LAST_LANE (internal_fn, gcall *)
181 /* This should get expanded in adjust_simduid_builtins. */
184 expand_GOMP_SIMD_ORDERED_START (internal_fn, gcall *)
189 /* This should get expanded in adjust_simduid_builtins. */
192 expand_GOMP_SIMD_ORDERED_END (internal_fn, gcall *)
197 /* This should get expanded in the sanopt pass. */
200 expand_UBSAN_NULL (internal_fn, gcall *)
205 /* This should get expanded in the sanopt pass. */
208 expand_UBSAN_BOUNDS (internal_fn, gcall *)
213 /* This should get expanded in the sanopt pass. */
216 expand_UBSAN_VPTR (internal_fn, gcall *)
221 /* This should get expanded in the sanopt pass. */
224 expand_UBSAN_OBJECT_SIZE (internal_fn, gcall *)
229 /* This should get expanded in the sanopt pass. */
232 expand_ASAN_CHECK (internal_fn, gcall *)
237 /* This should get expanded in the tsan pass. */
240 expand_TSAN_FUNC_EXIT (internal_fn, gcall *)
245 /* Helper function for expand_addsub_overflow. Return 1
246 if ARG interpreted as signed in its precision is known to be always
247 positive or 2 if ARG is known to be always negative, or 3 if ARG may
248 be positive or negative. */
251 get_range_pos_neg (tree arg)
253 if (arg == error_mark_node)
256 int prec = TYPE_PRECISION (TREE_TYPE (arg));
258 if (TREE_CODE (arg) == INTEGER_CST)
260 wide_int w = wi::sext (arg, prec);
266 while (CONVERT_EXPR_P (arg)
267 && INTEGRAL_TYPE_P (TREE_TYPE (TREE_OPERAND (arg, 0)))
268 && TYPE_PRECISION (TREE_TYPE (TREE_OPERAND (arg, 0))) <= prec)
270 arg = TREE_OPERAND (arg, 0);
271 /* Narrower value zero extended into wider type
272 will always result in positive values. */
273 if (TYPE_UNSIGNED (TREE_TYPE (arg))
274 && TYPE_PRECISION (TREE_TYPE (arg)) < prec)
276 prec = TYPE_PRECISION (TREE_TYPE (arg));
281 if (TREE_CODE (arg) != SSA_NAME)
283 wide_int arg_min, arg_max;
284 while (get_range_info (arg, &arg_min, &arg_max) != VR_RANGE)
286 gimple *g = SSA_NAME_DEF_STMT (arg);
287 if (is_gimple_assign (g)
288 && CONVERT_EXPR_CODE_P (gimple_assign_rhs_code (g)))
290 tree t = gimple_assign_rhs1 (g);
291 if (INTEGRAL_TYPE_P (TREE_TYPE (t))
292 && TYPE_PRECISION (TREE_TYPE (t)) <= prec)
294 if (TYPE_UNSIGNED (TREE_TYPE (t))
295 && TYPE_PRECISION (TREE_TYPE (t)) < prec)
297 prec = TYPE_PRECISION (TREE_TYPE (t));
306 if (TYPE_UNSIGNED (TREE_TYPE (arg)))
308 /* For unsigned values, the "positive" range comes
309 below the "negative" range. */
310 if (!wi::neg_p (wi::sext (arg_max, prec), SIGNED))
312 if (wi::neg_p (wi::sext (arg_min, prec), SIGNED))
317 if (!wi::neg_p (wi::sext (arg_min, prec), SIGNED))
319 if (wi::neg_p (wi::sext (arg_max, prec), SIGNED))
325 /* Return minimum precision needed to represent all values
326 of ARG in SIGNed integral type. */
329 get_min_precision (tree arg, signop sign)
331 int prec = TYPE_PRECISION (TREE_TYPE (arg));
333 signop orig_sign = sign;
334 if (TREE_CODE (arg) == INTEGER_CST)
337 if (TYPE_SIGN (TREE_TYPE (arg)) != sign)
339 widest_int w = wi::to_widest (arg);
340 w = wi::ext (w, prec, sign);
341 p = wi::min_precision (w, sign);
344 p = wi::min_precision (arg, sign);
345 return MIN (p, prec);
347 while (CONVERT_EXPR_P (arg)
348 && INTEGRAL_TYPE_P (TREE_TYPE (TREE_OPERAND (arg, 0)))
349 && TYPE_PRECISION (TREE_TYPE (TREE_OPERAND (arg, 0))) <= prec)
351 arg = TREE_OPERAND (arg, 0);
352 if (TYPE_PRECISION (TREE_TYPE (arg)) < prec)
354 if (TYPE_UNSIGNED (TREE_TYPE (arg)))
356 else if (sign == UNSIGNED && get_range_pos_neg (arg) != 1)
357 return prec + (orig_sign != sign);
358 prec = TYPE_PRECISION (TREE_TYPE (arg));
361 return prec + (orig_sign != sign);
363 if (TREE_CODE (arg) != SSA_NAME)
364 return prec + (orig_sign != sign);
365 wide_int arg_min, arg_max;
366 while (get_range_info (arg, &arg_min, &arg_max) != VR_RANGE)
368 gimple *g = SSA_NAME_DEF_STMT (arg);
369 if (is_gimple_assign (g)
370 && CONVERT_EXPR_CODE_P (gimple_assign_rhs_code (g)))
372 tree t = gimple_assign_rhs1 (g);
373 if (INTEGRAL_TYPE_P (TREE_TYPE (t))
374 && TYPE_PRECISION (TREE_TYPE (t)) <= prec)
377 if (TYPE_PRECISION (TREE_TYPE (arg)) < prec)
379 if (TYPE_UNSIGNED (TREE_TYPE (arg)))
381 else if (sign == UNSIGNED && get_range_pos_neg (arg) != 1)
382 return prec + (orig_sign != sign);
383 prec = TYPE_PRECISION (TREE_TYPE (arg));
386 return prec + (orig_sign != sign);
390 return prec + (orig_sign != sign);
392 if (sign == TYPE_SIGN (TREE_TYPE (arg)))
394 int p1 = wi::min_precision (arg_min, sign);
395 int p2 = wi::min_precision (arg_max, sign);
397 prec = MIN (prec, p1);
399 else if (sign == UNSIGNED && !wi::neg_p (arg_min, SIGNED))
401 int p = wi::min_precision (arg_max, UNSIGNED);
402 prec = MIN (prec, p);
404 return prec + (orig_sign != sign);
407 /* Helper for expand_*_overflow. Store RES into the __real__ part
408 of TARGET. If RES has larger MODE than __real__ part of TARGET,
409 set the __imag__ part to 1 if RES doesn't fit into it. */
412 expand_arith_overflow_result_store (tree lhs, rtx target,
413 machine_mode mode, rtx res)
415 machine_mode tgtmode = GET_MODE_INNER (GET_MODE (target));
419 rtx_code_label *done_label = gen_label_rtx ();
420 int uns = TYPE_UNSIGNED (TREE_TYPE (TREE_TYPE (lhs)));
421 lres = convert_modes (tgtmode, mode, res, uns);
422 gcc_assert (GET_MODE_PRECISION (tgtmode) < GET_MODE_PRECISION (mode));
423 do_compare_rtx_and_jump (res, convert_modes (mode, tgtmode, lres, uns),
424 EQ, true, mode, NULL_RTX, NULL, done_label,
426 write_complex_part (target, const1_rtx, true);
427 emit_label (done_label);
429 write_complex_part (target, lres, false);
432 /* Helper for expand_*_overflow. Store RES into TARGET. */
435 expand_ubsan_result_store (rtx target, rtx res)
437 if (GET_CODE (target) == SUBREG && SUBREG_PROMOTED_VAR_P (target))
438 /* If this is a scalar in a register that is stored in a wider mode
439 than the declared mode, compute the result into its declared mode
440 and then convert to the wider mode. Our value is the computed
442 convert_move (SUBREG_REG (target), res, SUBREG_PROMOTED_SIGN (target));
444 emit_move_insn (target, res);
447 /* Add sub/add overflow checking to the statement STMT.
448 CODE says whether the operation is +, or -. */
451 expand_addsub_overflow (location_t loc, tree_code code, tree lhs,
452 tree arg0, tree arg1, bool unsr_p, bool uns0_p,
453 bool uns1_p, bool is_ubsan)
455 rtx res, target = NULL_RTX;
457 rtx_code_label *done_label = gen_label_rtx ();
458 rtx_code_label *do_error = gen_label_rtx ();
459 do_pending_stack_adjust ();
460 rtx op0 = expand_normal (arg0);
461 rtx op1 = expand_normal (arg1);
462 machine_mode mode = TYPE_MODE (TREE_TYPE (arg0));
463 int prec = GET_MODE_PRECISION (mode);
464 rtx sgn = immed_wide_int_const (wi::min_value (prec, SIGNED), mode);
468 gcc_assert (!unsr_p && !uns0_p && !uns1_p);
472 target = expand_expr (lhs, NULL_RTX, VOIDmode, EXPAND_WRITE);
474 write_complex_part (target, const0_rtx, true);
477 /* We assume both operands and result have the same precision
478 here (GET_MODE_BITSIZE (mode)), S stands for signed type
479 with that precision, U for unsigned type with that precision,
480 sgn for unsigned most significant bit in that precision.
481 s1 is signed first operand, u1 is unsigned first operand,
482 s2 is signed second operand, u2 is unsigned second operand,
483 sr is signed result, ur is unsigned result and the following
484 rules say how to compute result (which is always result of
485 the operands as if both were unsigned, cast to the right
486 signedness) and how to compute whether operation overflowed.
489 res = (S) ((U) s1 + (U) s2)
490 ovf = s2 < 0 ? res > s1 : res < s1 (or jump on overflow)
492 res = (S) ((U) s1 - (U) s2)
493 ovf = s2 < 0 ? res < s1 : res > s2 (or jump on overflow)
496 ovf = res < u1 (or jump on carry, but RTL opts will handle it)
499 ovf = res > u1 (or jump on carry, but RTL opts will handle it)
501 res = (S) ((U) s1 + u2)
502 ovf = ((U) res ^ sgn) < u2
507 ovf = t1 < 0 ? t2 > s1 : t2 < s1 (or jump on overflow)
509 res = (S) ((U) s1 - u2)
510 ovf = u2 > ((U) s1 ^ sgn)
513 ovf = s1 < 0 || u2 > (U) s1
516 ovf = u1 >= ((U) s2 ^ sgn)
521 ovf = s2 < 0 ? (S) t2 < (S) t1 : (S) t2 > (S) t1 (or jump on overflow)
523 res = (U) s1 + (U) s2
524 ovf = s2 < 0 ? (s1 | (S) res) < 0) : (s1 & (S) res) < 0)
527 ovf = (U) res < u2 || res < 0
530 ovf = u1 >= u2 ? res < 0 : res >= 0
532 res = (U) s1 - (U) s2
533 ovf = s2 >= 0 ? ((s1 | (S) res) < 0) : ((s1 & (S) res) < 0) */
535 if (code == PLUS_EXPR && uns0_p && !uns1_p)
537 /* PLUS_EXPR is commutative, if operand signedness differs,
538 canonicalize to the first operand being signed and second
539 unsigned to simplify following code. */
540 std::swap (op0, op1);
541 std::swap (arg0, arg1);
547 if (uns0_p && uns1_p && unsr_p)
549 /* Compute the operation. On RTL level, the addition is always
551 res = expand_binop (mode, code == PLUS_EXPR ? add_optab : sub_optab,
552 op0, op1, NULL_RTX, false, OPTAB_LIB_WIDEN);
554 /* For PLUS_EXPR, the operation is commutative, so we can pick
555 operand to compare against. For prec <= BITS_PER_WORD, I think
556 preferring REG operand is better over CONST_INT, because
557 the CONST_INT might enlarge the instruction or CSE would need
558 to figure out we'd already loaded it into a register before.
559 For prec > BITS_PER_WORD, I think CONST_INT might be more beneficial,
560 as then the multi-word comparison can be perhaps simplified. */
561 if (code == PLUS_EXPR
562 && (prec <= BITS_PER_WORD
563 ? (CONST_SCALAR_INT_P (op0) && REG_P (op1))
564 : CONST_SCALAR_INT_P (op1)))
566 do_compare_rtx_and_jump (res, tem, code == PLUS_EXPR ? GEU : LEU,
567 true, mode, NULL_RTX, NULL, done_label,
573 if (!uns0_p && uns1_p && !unsr_p)
575 /* Compute the operation. On RTL level, the addition is always
577 res = expand_binop (mode, code == PLUS_EXPR ? add_optab : sub_optab,
578 op0, op1, NULL_RTX, false, OPTAB_LIB_WIDEN);
579 rtx tem = expand_binop (mode, add_optab,
580 code == PLUS_EXPR ? res : op0, sgn,
581 NULL_RTX, false, OPTAB_LIB_WIDEN);
582 do_compare_rtx_and_jump (tem, op1, GEU, true, mode, NULL_RTX, NULL,
583 done_label, PROB_VERY_LIKELY);
588 if (code == PLUS_EXPR && !uns0_p && uns1_p && unsr_p)
590 op1 = expand_binop (mode, add_optab, op1, sgn, NULL_RTX, false,
592 /* As we've changed op1, we have to avoid using the value range
593 for the original argument. */
594 arg1 = error_mark_node;
600 if (code == MINUS_EXPR && uns0_p && !uns1_p && unsr_p)
602 op0 = expand_binop (mode, add_optab, op0, sgn, NULL_RTX, false,
604 /* As we've changed op0, we have to avoid using the value range
605 for the original argument. */
606 arg0 = error_mark_node;
612 if (code == MINUS_EXPR && !uns0_p && uns1_p && unsr_p)
614 /* Compute the operation. On RTL level, the addition is always
616 res = expand_binop (mode, sub_optab, op0, op1, NULL_RTX, false,
618 int pos_neg = get_range_pos_neg (arg0);
620 /* If ARG0 is known to be always negative, this is always overflow. */
621 emit_jump (do_error);
622 else if (pos_neg == 3)
623 /* If ARG0 is not known to be always positive, check at runtime. */
624 do_compare_rtx_and_jump (op0, const0_rtx, LT, false, mode, NULL_RTX,
625 NULL, do_error, PROB_VERY_UNLIKELY);
626 do_compare_rtx_and_jump (op1, op0, LEU, true, mode, NULL_RTX, NULL,
627 done_label, PROB_VERY_LIKELY);
632 if (code == MINUS_EXPR && uns0_p && !uns1_p && !unsr_p)
634 /* Compute the operation. On RTL level, the addition is always
636 res = expand_binop (mode, sub_optab, op0, op1, NULL_RTX, false,
638 rtx tem = expand_binop (mode, add_optab, op1, sgn, NULL_RTX, false,
640 do_compare_rtx_and_jump (op0, tem, LTU, true, mode, NULL_RTX, NULL,
641 done_label, PROB_VERY_LIKELY);
646 if (code == PLUS_EXPR && uns0_p && uns1_p && !unsr_p)
648 /* Compute the operation. On RTL level, the addition is always
650 res = expand_binop (mode, add_optab, op0, op1, NULL_RTX, false,
652 do_compare_rtx_and_jump (res, const0_rtx, LT, false, mode, NULL_RTX,
653 NULL, do_error, PROB_VERY_UNLIKELY);
655 /* The operation is commutative, so we can pick operand to compare
656 against. For prec <= BITS_PER_WORD, I think preferring REG operand
657 is better over CONST_INT, because the CONST_INT might enlarge the
658 instruction or CSE would need to figure out we'd already loaded it
659 into a register before. For prec > BITS_PER_WORD, I think CONST_INT
660 might be more beneficial, as then the multi-word comparison can be
661 perhaps simplified. */
662 if (prec <= BITS_PER_WORD
663 ? (CONST_SCALAR_INT_P (op1) && REG_P (op0))
664 : CONST_SCALAR_INT_P (op0))
666 do_compare_rtx_and_jump (res, tem, GEU, true, mode, NULL_RTX, NULL,
667 done_label, PROB_VERY_LIKELY);
672 if (!uns0_p && !uns1_p && unsr_p)
674 /* Compute the operation. On RTL level, the addition is always
676 res = expand_binop (mode, code == PLUS_EXPR ? add_optab : sub_optab,
677 op0, op1, NULL_RTX, false, OPTAB_LIB_WIDEN);
678 int pos_neg = get_range_pos_neg (arg1);
679 if (code == PLUS_EXPR)
681 int pos_neg0 = get_range_pos_neg (arg0);
682 if (pos_neg0 != 3 && pos_neg == 3)
684 std::swap (op0, op1);
691 tem = expand_binop (mode, ((pos_neg == 1) ^ (code == MINUS_EXPR))
692 ? and_optab : ior_optab,
693 op0, res, NULL_RTX, false, OPTAB_LIB_WIDEN);
694 do_compare_rtx_and_jump (tem, const0_rtx, GE, false, mode, NULL,
695 NULL, done_label, PROB_VERY_LIKELY);
699 rtx_code_label *do_ior_label = gen_label_rtx ();
700 do_compare_rtx_and_jump (op1, const0_rtx,
701 code == MINUS_EXPR ? GE : LT, false, mode,
702 NULL_RTX, NULL, do_ior_label,
704 tem = expand_binop (mode, and_optab, op0, res, NULL_RTX, false,
706 do_compare_rtx_and_jump (tem, const0_rtx, GE, false, mode, NULL_RTX,
707 NULL, done_label, PROB_VERY_LIKELY);
708 emit_jump (do_error);
709 emit_label (do_ior_label);
710 tem = expand_binop (mode, ior_optab, op0, res, NULL_RTX, false,
712 do_compare_rtx_and_jump (tem, const0_rtx, GE, false, mode, NULL_RTX,
713 NULL, done_label, PROB_VERY_LIKELY);
719 if (code == MINUS_EXPR && uns0_p && uns1_p && !unsr_p)
721 /* Compute the operation. On RTL level, the addition is always
723 res = expand_binop (mode, sub_optab, op0, op1, NULL_RTX, false,
725 rtx_code_label *op0_geu_op1 = gen_label_rtx ();
726 do_compare_rtx_and_jump (op0, op1, GEU, true, mode, NULL_RTX, NULL,
727 op0_geu_op1, PROB_EVEN);
728 do_compare_rtx_and_jump (res, const0_rtx, LT, false, mode, NULL_RTX,
729 NULL, done_label, PROB_VERY_LIKELY);
730 emit_jump (do_error);
731 emit_label (op0_geu_op1);
732 do_compare_rtx_and_jump (res, const0_rtx, GE, false, mode, NULL_RTX,
733 NULL, done_label, PROB_VERY_LIKELY);
737 gcc_assert (!uns0_p && !uns1_p && !unsr_p);
741 enum insn_code icode;
742 icode = optab_handler (code == PLUS_EXPR ? addv4_optab : subv4_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_int_reg_note (last, REG_BR_PROB, PROB_VERY_UNLIKELY);
761 emit_jump (done_label);
765 delete_insns_since (last);
766 icode = CODE_FOR_nothing;
770 if (icode == CODE_FOR_nothing)
772 rtx_code_label *sub_check = gen_label_rtx ();
775 /* Compute the operation. On RTL level, the addition is always
777 res = expand_binop (mode, code == PLUS_EXPR ? add_optab : sub_optab,
778 op0, op1, NULL_RTX, false, OPTAB_LIB_WIDEN);
780 /* If we can prove one of the arguments (for MINUS_EXPR only
781 the second operand, as subtraction is not commutative) is always
782 non-negative or always negative, we can do just one comparison
783 and conditional jump instead of 2 at runtime, 3 present in the
784 emitted code. If one of the arguments is CONST_INT, all we
785 need is to make sure it is op1, then the first
786 do_compare_rtx_and_jump will be just folded. Otherwise try
787 to use range info if available. */
788 if (code == PLUS_EXPR && CONST_INT_P (op0))
789 std::swap (op0, op1);
790 else if (CONST_INT_P (op1))
792 else if (code == PLUS_EXPR && TREE_CODE (arg0) == SSA_NAME)
794 pos_neg = get_range_pos_neg (arg0);
796 std::swap (op0, op1);
798 if (pos_neg == 3 && !CONST_INT_P (op1) && TREE_CODE (arg1) == SSA_NAME)
799 pos_neg = get_range_pos_neg (arg1);
801 /* If the op1 is negative, we have to use a different check. */
803 do_compare_rtx_and_jump (op1, const0_rtx, LT, false, mode, NULL_RTX,
804 NULL, sub_check, PROB_EVEN);
806 /* Compare the result of the operation with one of the operands. */
808 do_compare_rtx_and_jump (res, op0, code == PLUS_EXPR ? GE : LE,
809 false, mode, NULL_RTX, NULL, done_label,
812 /* If we get here, we have to print the error. */
815 emit_jump (do_error);
817 emit_label (sub_check);
820 /* We have k = a + b for b < 0 here. k <= a must hold. */
822 do_compare_rtx_and_jump (res, op0, code == PLUS_EXPR ? LE : GE,
823 false, mode, NULL_RTX, NULL, done_label,
828 emit_label (do_error);
831 /* Expand the ubsan builtin call. */
833 fn = ubsan_build_overflow_builtin (code, loc, TREE_TYPE (arg0),
837 do_pending_stack_adjust ();
840 write_complex_part (target, const1_rtx, true);
843 emit_label (done_label);
848 expand_ubsan_result_store (target, res);
852 res = expand_binop (mode, add_optab, res, sgn, NULL_RTX, false,
855 expand_arith_overflow_result_store (lhs, target, mode, res);
860 /* Add negate overflow checking to the statement STMT. */
863 expand_neg_overflow (location_t loc, tree lhs, tree arg1, bool is_ubsan)
867 rtx_code_label *done_label, *do_error;
868 rtx target = NULL_RTX;
870 done_label = gen_label_rtx ();
871 do_error = gen_label_rtx ();
873 do_pending_stack_adjust ();
874 op1 = expand_normal (arg1);
876 machine_mode mode = TYPE_MODE (TREE_TYPE (arg1));
879 target = expand_expr (lhs, NULL_RTX, VOIDmode, EXPAND_WRITE);
881 write_complex_part (target, const0_rtx, true);
884 enum insn_code icode = optab_handler (negv3_optab, mode);
885 if (icode != CODE_FOR_nothing)
887 struct expand_operand ops[3];
888 rtx_insn *last = get_last_insn ();
890 res = gen_reg_rtx (mode);
891 create_output_operand (&ops[0], res, mode);
892 create_input_operand (&ops[1], op1, mode);
893 create_fixed_operand (&ops[2], do_error);
894 if (maybe_expand_insn (icode, 3, ops))
896 last = get_last_insn ();
897 if (profile_status_for_fn (cfun) != PROFILE_ABSENT
899 && any_condjump_p (last)
900 && !find_reg_note (last, REG_BR_PROB, 0))
901 add_int_reg_note (last, REG_BR_PROB, PROB_VERY_UNLIKELY);
902 emit_jump (done_label);
906 delete_insns_since (last);
907 icode = CODE_FOR_nothing;
911 if (icode == CODE_FOR_nothing)
913 /* Compute the operation. On RTL level, the addition is always
915 res = expand_unop (mode, neg_optab, op1, NULL_RTX, false);
917 /* Compare the operand with the most negative value. */
918 rtx minv = expand_normal (TYPE_MIN_VALUE (TREE_TYPE (arg1)));
919 do_compare_rtx_and_jump (op1, minv, NE, true, mode, NULL_RTX, NULL,
920 done_label, PROB_VERY_LIKELY);
923 emit_label (do_error);
926 /* Expand the ubsan builtin call. */
928 fn = ubsan_build_overflow_builtin (NEGATE_EXPR, loc, TREE_TYPE (arg1),
932 do_pending_stack_adjust ();
935 write_complex_part (target, const1_rtx, true);
938 emit_label (done_label);
943 expand_ubsan_result_store (target, res);
945 expand_arith_overflow_result_store (lhs, target, mode, res);
949 /* Add mul overflow checking to the statement STMT. */
952 expand_mul_overflow (location_t loc, tree lhs, tree arg0, tree arg1,
953 bool unsr_p, bool uns0_p, bool uns1_p, bool is_ubsan)
957 rtx_code_label *done_label, *do_error;
958 rtx target = NULL_RTX;
960 enum insn_code icode;
962 done_label = gen_label_rtx ();
963 do_error = gen_label_rtx ();
965 do_pending_stack_adjust ();
966 op0 = expand_normal (arg0);
967 op1 = expand_normal (arg1);
969 machine_mode mode = TYPE_MODE (TREE_TYPE (arg0));
973 target = expand_expr (lhs, NULL_RTX, VOIDmode, EXPAND_WRITE);
975 write_complex_part (target, const0_rtx, true);
979 gcc_assert (!unsr_p && !uns0_p && !uns1_p);
981 /* We assume both operands and result have the same precision
982 here (GET_MODE_BITSIZE (mode)), S stands for signed type
983 with that precision, U for unsigned type with that precision,
984 sgn for unsigned most significant bit in that precision.
985 s1 is signed first operand, u1 is unsigned first operand,
986 s2 is signed second operand, u2 is unsigned second operand,
987 sr is signed result, ur is unsigned result and the following
988 rules say how to compute result (which is always result of
989 the operands as if both were unsigned, cast to the right
990 signedness) and how to compute whether operation overflowed.
991 main_ovf (false) stands for jump on signed multiplication
992 overflow or the main algorithm with uns == false.
993 main_ovf (true) stands for jump on unsigned multiplication
994 overflow or the main algorithm with uns == true.
997 res = (S) ((U) s1 * (U) s2)
998 ovf = main_ovf (false)
1001 ovf = main_ovf (true)
1004 ovf = (s1 < 0 && u2) || main_ovf (true)
1007 ovf = res < 0 || main_ovf (true)
1009 res = (S) ((U) s1 * u2)
1010 ovf = (S) u2 >= 0 ? main_ovf (false)
1011 : (s1 != 0 && (s1 != -1 || u2 != (U) res))
1013 t1 = (s1 & s2) < 0 ? (-(U) s1) : ((U) s1)
1014 t2 = (s1 & s2) < 0 ? (-(U) s2) : ((U) s2)
1016 ovf = (s1 ^ s2) < 0 ? (s1 && s2) : main_ovf (true) */
1018 if (uns0_p && !uns1_p)
1020 /* Multiplication is commutative, if operand signedness differs,
1021 canonicalize to the first operand being signed and second
1022 unsigned to simplify following code. */
1023 std::swap (op0, op1);
1024 std::swap (arg0, arg1);
1029 int pos_neg0 = get_range_pos_neg (arg0);
1030 int pos_neg1 = get_range_pos_neg (arg1);
1033 if (!uns0_p && uns1_p && unsr_p)
1038 /* If s1 is non-negative, just perform normal u1 * u2 -> ur. */
1041 /* If s1 is negative, avoid the main code, just multiply and
1042 signal overflow if op1 is not 0. */
1043 struct separate_ops ops;
1044 ops.code = MULT_EXPR;
1045 ops.type = TREE_TYPE (arg1);
1046 ops.op0 = make_tree (ops.type, op0);
1047 ops.op1 = make_tree (ops.type, op1);
1048 ops.op2 = NULL_TREE;
1050 res = expand_expr_real_2 (&ops, NULL_RTX, mode, EXPAND_NORMAL);
1051 do_compare_rtx_and_jump (op1, const0_rtx, EQ, true, mode, NULL_RTX,
1052 NULL, done_label, PROB_VERY_LIKELY);
1053 goto do_error_label;
1055 rtx_code_label *do_main_label;
1056 do_main_label = gen_label_rtx ();
1057 do_compare_rtx_and_jump (op0, const0_rtx, GE, false, mode, NULL_RTX,
1058 NULL, do_main_label, PROB_VERY_LIKELY);
1059 do_compare_rtx_and_jump (op1, const0_rtx, EQ, true, mode, NULL_RTX,
1060 NULL, do_main_label, PROB_VERY_LIKELY);
1061 write_complex_part (target, const1_rtx, true);
1062 emit_label (do_main_label);
1070 if (uns0_p && uns1_p && !unsr_p)
1073 /* Rest of handling of this case after res is computed. */
1078 if (!uns0_p && uns1_p && !unsr_p)
1085 /* If (S) u2 is negative (i.e. u2 is larger than maximum of S,
1086 avoid the main code, just multiply and signal overflow
1087 unless 0 * u2 or -1 * ((U) Smin). */
1088 struct separate_ops ops;
1089 ops.code = MULT_EXPR;
1090 ops.type = TREE_TYPE (arg1);
1091 ops.op0 = make_tree (ops.type, op0);
1092 ops.op1 = make_tree (ops.type, op1);
1093 ops.op2 = NULL_TREE;
1095 res = expand_expr_real_2 (&ops, NULL_RTX, mode, EXPAND_NORMAL);
1096 do_compare_rtx_and_jump (op0, const0_rtx, EQ, true, mode, NULL_RTX,
1097 NULL, done_label, PROB_VERY_LIKELY);
1098 do_compare_rtx_and_jump (op0, constm1_rtx, NE, true, mode, NULL_RTX,
1099 NULL, do_error, PROB_VERY_UNLIKELY);
1101 prec = GET_MODE_PRECISION (mode);
1103 sgn = immed_wide_int_const (wi::min_value (prec, SIGNED), mode);
1104 do_compare_rtx_and_jump (op1, sgn, EQ, true, mode, NULL_RTX,
1105 NULL, done_label, PROB_VERY_LIKELY);
1106 goto do_error_label;
1108 /* Rest of handling of this case after res is computed. */
1116 if (!uns0_p && !uns1_p && unsr_p)
1119 switch (pos_neg0 | pos_neg1)
1121 case 1: /* Both operands known to be non-negative. */
1123 case 2: /* Both operands known to be negative. */
1124 op0 = expand_unop (mode, neg_optab, op0, NULL_RTX, false);
1125 op1 = expand_unop (mode, neg_optab, op1, NULL_RTX, false);
1126 /* Avoid looking at arg0/arg1 ranges, as we've changed
1128 arg0 = error_mark_node;
1129 arg1 = error_mark_node;
1132 if ((pos_neg0 ^ pos_neg1) == 3)
1134 /* If one operand is known to be negative and the other
1135 non-negative, this overflows always, unless the non-negative
1136 one is 0. Just do normal multiply and set overflow
1137 unless one of the operands is 0. */
1138 struct separate_ops ops;
1139 ops.code = MULT_EXPR;
1141 = build_nonstandard_integer_type (GET_MODE_PRECISION (mode),
1143 ops.op0 = make_tree (ops.type, op0);
1144 ops.op1 = make_tree (ops.type, op1);
1145 ops.op2 = NULL_TREE;
1147 res = expand_expr_real_2 (&ops, NULL_RTX, mode, EXPAND_NORMAL);
1148 tem = expand_binop (mode, and_optab, op0, op1, NULL_RTX, false,
1150 do_compare_rtx_and_jump (tem, const0_rtx, EQ, true, mode,
1151 NULL_RTX, NULL, done_label,
1153 goto do_error_label;
1155 /* The general case, do all the needed comparisons at runtime. */
1156 rtx_code_label *do_main_label, *after_negate_label;
1158 rop0 = gen_reg_rtx (mode);
1159 rop1 = gen_reg_rtx (mode);
1160 emit_move_insn (rop0, op0);
1161 emit_move_insn (rop1, op1);
1164 do_main_label = gen_label_rtx ();
1165 after_negate_label = gen_label_rtx ();
1166 tem = expand_binop (mode, and_optab, op0, op1, NULL_RTX, false,
1168 do_compare_rtx_and_jump (tem, const0_rtx, GE, false, mode, NULL_RTX,
1169 NULL, after_negate_label, PROB_VERY_LIKELY);
1170 /* Both arguments negative here, negate them and continue with
1171 normal unsigned overflow checking multiplication. */
1172 emit_move_insn (op0, expand_unop (mode, neg_optab, op0,
1174 emit_move_insn (op1, expand_unop (mode, neg_optab, op1,
1176 /* Avoid looking at arg0/arg1 ranges, as we might have changed
1178 arg0 = error_mark_node;
1179 arg1 = error_mark_node;
1180 emit_jump (do_main_label);
1181 emit_label (after_negate_label);
1182 tem2 = expand_binop (mode, xor_optab, op0, op1, NULL_RTX, false,
1184 do_compare_rtx_and_jump (tem2, const0_rtx, GE, false, mode, NULL_RTX,
1185 NULL, do_main_label, PROB_VERY_LIKELY);
1186 /* One argument is negative here, the other positive. This
1187 overflows always, unless one of the arguments is 0. But
1188 if e.g. s2 is 0, (U) s1 * 0 doesn't overflow, whatever s1
1189 is, thus we can keep do_main code oring in overflow as is. */
1190 do_compare_rtx_and_jump (tem, const0_rtx, EQ, true, mode, NULL_RTX,
1191 NULL, do_main_label, PROB_VERY_LIKELY);
1192 write_complex_part (target, const1_rtx, true);
1193 emit_label (do_main_label);
1201 type = build_nonstandard_integer_type (GET_MODE_PRECISION (mode), uns);
1202 sign = uns ? UNSIGNED : SIGNED;
1203 icode = optab_handler (uns ? umulv4_optab : mulv4_optab, mode);
1204 if (icode != CODE_FOR_nothing)
1206 struct expand_operand ops[4];
1207 rtx_insn *last = get_last_insn ();
1209 res = gen_reg_rtx (mode);
1210 create_output_operand (&ops[0], res, mode);
1211 create_input_operand (&ops[1], op0, mode);
1212 create_input_operand (&ops[2], op1, mode);
1213 create_fixed_operand (&ops[3], do_error);
1214 if (maybe_expand_insn (icode, 4, ops))
1216 last = get_last_insn ();
1217 if (profile_status_for_fn (cfun) != PROFILE_ABSENT
1219 && any_condjump_p (last)
1220 && !find_reg_note (last, REG_BR_PROB, 0))
1221 add_int_reg_note (last, REG_BR_PROB, PROB_VERY_UNLIKELY);
1222 emit_jump (done_label);
1226 delete_insns_since (last);
1227 icode = CODE_FOR_nothing;
1231 if (icode == CODE_FOR_nothing)
1233 struct separate_ops ops;
1234 int prec = GET_MODE_PRECISION (mode);
1235 machine_mode hmode = mode_for_size (prec / 2, MODE_INT, 1);
1236 ops.op0 = make_tree (type, op0);
1237 ops.op1 = make_tree (type, op1);
1238 ops.op2 = NULL_TREE;
1240 if (GET_MODE_2XWIDER_MODE (mode) != VOIDmode
1241 && targetm.scalar_mode_supported_p (GET_MODE_2XWIDER_MODE (mode)))
1243 machine_mode wmode = GET_MODE_2XWIDER_MODE (mode);
1244 ops.code = WIDEN_MULT_EXPR;
1246 = build_nonstandard_integer_type (GET_MODE_PRECISION (wmode), uns);
1248 res = expand_expr_real_2 (&ops, NULL_RTX, wmode, EXPAND_NORMAL);
1249 rtx hipart = expand_shift (RSHIFT_EXPR, wmode, res, prec,
1251 hipart = gen_lowpart (mode, hipart);
1252 res = gen_lowpart (mode, res);
1254 /* For the unsigned multiplication, there was overflow if
1255 HIPART is non-zero. */
1256 do_compare_rtx_and_jump (hipart, const0_rtx, EQ, true, mode,
1257 NULL_RTX, NULL, done_label,
1261 rtx signbit = expand_shift (RSHIFT_EXPR, mode, res, prec - 1,
1263 /* RES is low half of the double width result, HIPART
1264 the high half. There was overflow if
1265 HIPART is different from RES < 0 ? -1 : 0. */
1266 do_compare_rtx_and_jump (signbit, hipart, EQ, true, mode,
1267 NULL_RTX, NULL, done_label,
1271 else if (hmode != BLKmode && 2 * GET_MODE_PRECISION (hmode) == prec)
1273 rtx_code_label *large_op0 = gen_label_rtx ();
1274 rtx_code_label *small_op0_large_op1 = gen_label_rtx ();
1275 rtx_code_label *one_small_one_large = gen_label_rtx ();
1276 rtx_code_label *both_ops_large = gen_label_rtx ();
1277 rtx_code_label *after_hipart_neg = uns ? NULL : gen_label_rtx ();
1278 rtx_code_label *after_lopart_neg = uns ? NULL : gen_label_rtx ();
1279 rtx_code_label *do_overflow = gen_label_rtx ();
1280 rtx_code_label *hipart_different = uns ? NULL : gen_label_rtx ();
1282 unsigned int hprec = GET_MODE_PRECISION (hmode);
1283 rtx hipart0 = expand_shift (RSHIFT_EXPR, mode, op0, hprec,
1285 hipart0 = gen_lowpart (hmode, hipart0);
1286 rtx lopart0 = gen_lowpart (hmode, op0);
1287 rtx signbit0 = const0_rtx;
1289 signbit0 = expand_shift (RSHIFT_EXPR, hmode, lopart0, hprec - 1,
1291 rtx hipart1 = expand_shift (RSHIFT_EXPR, mode, op1, hprec,
1293 hipart1 = gen_lowpart (hmode, hipart1);
1294 rtx lopart1 = gen_lowpart (hmode, op1);
1295 rtx signbit1 = const0_rtx;
1297 signbit1 = expand_shift (RSHIFT_EXPR, hmode, lopart1, hprec - 1,
1300 res = gen_reg_rtx (mode);
1302 /* True if op0 resp. op1 are known to be in the range of
1304 bool op0_small_p = false;
1305 bool op1_small_p = false;
1306 /* True if op0 resp. op1 are known to have all zeros or all ones
1307 in the upper half of bits, but are not known to be
1309 bool op0_medium_p = false;
1310 bool op1_medium_p = false;
1311 /* -1 if op{0,1} is known to be negative, 0 if it is known to be
1312 nonnegative, 1 if unknown. */
1318 else if (pos_neg0 == 2)
1322 else if (pos_neg1 == 2)
1325 unsigned int mprec0 = prec;
1326 if (arg0 != error_mark_node)
1327 mprec0 = get_min_precision (arg0, sign);
1328 if (mprec0 <= hprec)
1330 else if (!uns && mprec0 <= hprec + 1)
1331 op0_medium_p = true;
1332 unsigned int mprec1 = prec;
1333 if (arg1 != error_mark_node)
1334 mprec1 = get_min_precision (arg1, sign);
1335 if (mprec1 <= hprec)
1337 else if (!uns && mprec1 <= hprec + 1)
1338 op1_medium_p = true;
1340 int smaller_sign = 1;
1341 int larger_sign = 1;
1344 smaller_sign = op0_sign;
1345 larger_sign = op1_sign;
1347 else if (op1_small_p)
1349 smaller_sign = op1_sign;
1350 larger_sign = op0_sign;
1352 else if (op0_sign == op1_sign)
1354 smaller_sign = op0_sign;
1355 larger_sign = op0_sign;
1359 do_compare_rtx_and_jump (signbit0, hipart0, NE, true, hmode,
1360 NULL_RTX, NULL, large_op0,
1364 do_compare_rtx_and_jump (signbit1, hipart1, NE, true, hmode,
1365 NULL_RTX, NULL, small_op0_large_op1,
1368 /* If both op0 and op1 are sign (!uns) or zero (uns) extended from
1369 hmode to mode, the multiplication will never overflow. We can
1370 do just one hmode x hmode => mode widening multiplication. */
1371 rtx lopart0s = lopart0, lopart1s = lopart1;
1372 if (GET_CODE (lopart0) == SUBREG)
1374 lopart0s = shallow_copy_rtx (lopart0);
1375 SUBREG_PROMOTED_VAR_P (lopart0s) = 1;
1376 SUBREG_PROMOTED_SET (lopart0s, uns ? SRP_UNSIGNED : SRP_SIGNED);
1378 if (GET_CODE (lopart1) == SUBREG)
1380 lopart1s = shallow_copy_rtx (lopart1);
1381 SUBREG_PROMOTED_VAR_P (lopart1s) = 1;
1382 SUBREG_PROMOTED_SET (lopart1s, uns ? SRP_UNSIGNED : SRP_SIGNED);
1384 tree halfstype = build_nonstandard_integer_type (hprec, uns);
1385 ops.op0 = make_tree (halfstype, lopart0s);
1386 ops.op1 = make_tree (halfstype, lopart1s);
1387 ops.code = WIDEN_MULT_EXPR;
1390 = expand_expr_real_2 (&ops, NULL_RTX, mode, EXPAND_NORMAL);
1391 emit_move_insn (res, thisres);
1392 emit_jump (done_label);
1394 emit_label (small_op0_large_op1);
1396 /* If op0 is sign (!uns) or zero (uns) extended from hmode to mode,
1397 but op1 is not, just swap the arguments and handle it as op1
1398 sign/zero extended, op0 not. */
1399 rtx larger = gen_reg_rtx (mode);
1400 rtx hipart = gen_reg_rtx (hmode);
1401 rtx lopart = gen_reg_rtx (hmode);
1402 emit_move_insn (larger, op1);
1403 emit_move_insn (hipart, hipart1);
1404 emit_move_insn (lopart, lopart0);
1405 emit_jump (one_small_one_large);
1407 emit_label (large_op0);
1410 do_compare_rtx_and_jump (signbit1, hipart1, NE, true, hmode,
1411 NULL_RTX, NULL, both_ops_large,
1414 /* If op1 is sign (!uns) or zero (uns) extended from hmode to mode,
1415 but op0 is not, prepare larger, hipart and lopart pseudos and
1416 handle it together with small_op0_large_op1. */
1417 emit_move_insn (larger, op0);
1418 emit_move_insn (hipart, hipart0);
1419 emit_move_insn (lopart, lopart1);
1421 emit_label (one_small_one_large);
1423 /* lopart is the low part of the operand that is sign extended
1424 to mode, larger is the other operand, hipart is the
1425 high part of larger and lopart0 and lopart1 are the low parts
1427 We perform lopart0 * lopart1 and lopart * hipart widening
1429 tree halfutype = build_nonstandard_integer_type (hprec, 1);
1430 ops.op0 = make_tree (halfutype, lopart0);
1431 ops.op1 = make_tree (halfutype, lopart1);
1433 = expand_expr_real_2 (&ops, NULL_RTX, mode, EXPAND_NORMAL);
1435 ops.op0 = make_tree (halfutype, lopart);
1436 ops.op1 = make_tree (halfutype, hipart);
1437 rtx loxhi = gen_reg_rtx (mode);
1438 rtx tem = expand_expr_real_2 (&ops, NULL_RTX, mode, EXPAND_NORMAL);
1439 emit_move_insn (loxhi, tem);
1443 /* if (hipart < 0) loxhi -= lopart << (bitsize / 2); */
1444 if (larger_sign == 0)
1445 emit_jump (after_hipart_neg);
1446 else if (larger_sign != -1)
1447 do_compare_rtx_and_jump (hipart, const0_rtx, GE, false, hmode,
1448 NULL_RTX, NULL, after_hipart_neg,
1451 tem = convert_modes (mode, hmode, lopart, 1);
1452 tem = expand_shift (LSHIFT_EXPR, mode, tem, hprec, NULL_RTX, 1);
1453 tem = expand_simple_binop (mode, MINUS, loxhi, tem, NULL_RTX,
1455 emit_move_insn (loxhi, tem);
1457 emit_label (after_hipart_neg);
1459 /* if (lopart < 0) loxhi -= larger; */
1460 if (smaller_sign == 0)
1461 emit_jump (after_lopart_neg);
1462 else if (smaller_sign != -1)
1463 do_compare_rtx_and_jump (lopart, const0_rtx, GE, false, hmode,
1464 NULL_RTX, NULL, after_lopart_neg,
1467 tem = expand_simple_binop (mode, MINUS, loxhi, larger, NULL_RTX,
1469 emit_move_insn (loxhi, tem);
1471 emit_label (after_lopart_neg);
1474 /* loxhi += (uns) lo0xlo1 >> (bitsize / 2); */
1475 tem = expand_shift (RSHIFT_EXPR, mode, lo0xlo1, hprec, NULL_RTX, 1);
1476 tem = expand_simple_binop (mode, PLUS, loxhi, tem, NULL_RTX,
1478 emit_move_insn (loxhi, tem);
1480 /* if (loxhi >> (bitsize / 2)
1481 == (hmode) loxhi >> (bitsize / 2 - 1)) (if !uns)
1482 if (loxhi >> (bitsize / 2) == 0 (if uns). */
1483 rtx hipartloxhi = expand_shift (RSHIFT_EXPR, mode, loxhi, hprec,
1485 hipartloxhi = gen_lowpart (hmode, hipartloxhi);
1486 rtx signbitloxhi = const0_rtx;
1488 signbitloxhi = expand_shift (RSHIFT_EXPR, hmode,
1489 gen_lowpart (hmode, loxhi),
1490 hprec - 1, NULL_RTX, 0);
1492 do_compare_rtx_and_jump (signbitloxhi, hipartloxhi, NE, true, hmode,
1493 NULL_RTX, NULL, do_overflow,
1494 PROB_VERY_UNLIKELY);
1496 /* res = (loxhi << (bitsize / 2)) | (hmode) lo0xlo1; */
1497 rtx loxhishifted = expand_shift (LSHIFT_EXPR, mode, loxhi, hprec,
1499 tem = convert_modes (mode, hmode, gen_lowpart (hmode, lo0xlo1), 1);
1501 tem = expand_simple_binop (mode, IOR, loxhishifted, tem, res,
1504 emit_move_insn (res, tem);
1505 emit_jump (done_label);
1507 emit_label (both_ops_large);
1509 /* If both operands are large (not sign (!uns) or zero (uns)
1510 extended from hmode), then perform the full multiplication
1511 which will be the result of the operation.
1512 The only cases which don't overflow are for signed multiplication
1513 some cases where both hipart0 and highpart1 are 0 or -1.
1514 For unsigned multiplication when high parts are both non-zero
1515 this overflows always. */
1516 ops.code = MULT_EXPR;
1517 ops.op0 = make_tree (type, op0);
1518 ops.op1 = make_tree (type, op1);
1519 tem = expand_expr_real_2 (&ops, NULL_RTX, mode, EXPAND_NORMAL);
1520 emit_move_insn (res, tem);
1526 tem = expand_simple_binop (hmode, PLUS, hipart0, const1_rtx,
1527 NULL_RTX, 1, OPTAB_DIRECT);
1528 do_compare_rtx_and_jump (tem, const1_rtx, GTU, true, hmode,
1529 NULL_RTX, NULL, do_error,
1530 PROB_VERY_UNLIKELY);
1535 tem = expand_simple_binop (hmode, PLUS, hipart1, const1_rtx,
1536 NULL_RTX, 1, OPTAB_DIRECT);
1537 do_compare_rtx_and_jump (tem, const1_rtx, GTU, true, hmode,
1538 NULL_RTX, NULL, do_error,
1539 PROB_VERY_UNLIKELY);
1542 /* At this point hipart{0,1} are both in [-1, 0]. If they are
1543 the same, overflow happened if res is negative, if they are
1544 different, overflow happened if res is positive. */
1545 if (op0_sign != 1 && op1_sign != 1 && op0_sign != op1_sign)
1546 emit_jump (hipart_different);
1547 else if (op0_sign == 1 || op1_sign == 1)
1548 do_compare_rtx_and_jump (hipart0, hipart1, NE, true, hmode,
1549 NULL_RTX, NULL, hipart_different,
1552 do_compare_rtx_and_jump (res, const0_rtx, LT, false, mode,
1553 NULL_RTX, NULL, do_error,
1554 PROB_VERY_UNLIKELY);
1555 emit_jump (done_label);
1557 emit_label (hipart_different);
1559 do_compare_rtx_and_jump (res, const0_rtx, GE, false, mode,
1560 NULL_RTX, NULL, do_error,
1561 PROB_VERY_UNLIKELY);
1562 emit_jump (done_label);
1565 emit_label (do_overflow);
1567 /* Overflow, do full multiplication and fallthru into do_error. */
1568 ops.op0 = make_tree (type, op0);
1569 ops.op1 = make_tree (type, op1);
1570 tem = expand_expr_real_2 (&ops, NULL_RTX, mode, EXPAND_NORMAL);
1571 emit_move_insn (res, tem);
1575 gcc_assert (!is_ubsan);
1576 ops.code = MULT_EXPR;
1578 res = expand_expr_real_2 (&ops, NULL_RTX, mode, EXPAND_NORMAL);
1579 emit_jump (done_label);
1584 emit_label (do_error);
1587 /* Expand the ubsan builtin call. */
1589 fn = ubsan_build_overflow_builtin (MULT_EXPR, loc, TREE_TYPE (arg0),
1593 do_pending_stack_adjust ();
1596 write_complex_part (target, const1_rtx, true);
1599 emit_label (done_label);
1602 if (uns0_p && uns1_p && !unsr_p)
1604 rtx_code_label *all_done_label = gen_label_rtx ();
1605 do_compare_rtx_and_jump (res, const0_rtx, GE, false, mode, NULL_RTX,
1606 NULL, all_done_label, PROB_VERY_LIKELY);
1607 write_complex_part (target, const1_rtx, true);
1608 emit_label (all_done_label);
1612 if (!uns0_p && uns1_p && !unsr_p && pos_neg1 == 3)
1614 rtx_code_label *all_done_label = gen_label_rtx ();
1615 rtx_code_label *set_noovf = gen_label_rtx ();
1616 do_compare_rtx_and_jump (op1, const0_rtx, GE, false, mode, NULL_RTX,
1617 NULL, all_done_label, PROB_VERY_LIKELY);
1618 write_complex_part (target, const1_rtx, true);
1619 do_compare_rtx_and_jump (op0, const0_rtx, EQ, true, mode, NULL_RTX,
1620 NULL, set_noovf, PROB_VERY_LIKELY);
1621 do_compare_rtx_and_jump (op0, constm1_rtx, NE, true, mode, NULL_RTX,
1622 NULL, all_done_label, PROB_VERY_UNLIKELY);
1623 do_compare_rtx_and_jump (op1, res, NE, true, mode, NULL_RTX, NULL,
1624 all_done_label, PROB_VERY_UNLIKELY);
1625 emit_label (set_noovf);
1626 write_complex_part (target, const0_rtx, true);
1627 emit_label (all_done_label);
1633 expand_ubsan_result_store (target, res);
1635 expand_arith_overflow_result_store (lhs, target, mode, res);
1639 /* Expand UBSAN_CHECK_ADD call STMT. */
1642 expand_UBSAN_CHECK_ADD (internal_fn, gcall *stmt)
1644 location_t loc = gimple_location (stmt);
1645 tree lhs = gimple_call_lhs (stmt);
1646 tree arg0 = gimple_call_arg (stmt, 0);
1647 tree arg1 = gimple_call_arg (stmt, 1);
1648 expand_addsub_overflow (loc, PLUS_EXPR, lhs, arg0, arg1,
1649 false, false, false, true);
1652 /* Expand UBSAN_CHECK_SUB call STMT. */
1655 expand_UBSAN_CHECK_SUB (internal_fn, gcall *stmt)
1657 location_t loc = gimple_location (stmt);
1658 tree lhs = gimple_call_lhs (stmt);
1659 tree arg0 = gimple_call_arg (stmt, 0);
1660 tree arg1 = gimple_call_arg (stmt, 1);
1661 if (integer_zerop (arg0))
1662 expand_neg_overflow (loc, lhs, arg1, true);
1664 expand_addsub_overflow (loc, MINUS_EXPR, lhs, arg0, arg1,
1665 false, false, false, true);
1668 /* Expand UBSAN_CHECK_MUL call STMT. */
1671 expand_UBSAN_CHECK_MUL (internal_fn, gcall *stmt)
1673 location_t loc = gimple_location (stmt);
1674 tree lhs = gimple_call_lhs (stmt);
1675 tree arg0 = gimple_call_arg (stmt, 0);
1676 tree arg1 = gimple_call_arg (stmt, 1);
1677 expand_mul_overflow (loc, lhs, arg0, arg1, false, false, false, true);
1680 /* Helper function for {ADD,SUB,MUL}_OVERFLOW call stmt expansion. */
1683 expand_arith_overflow (enum tree_code code, gimple *stmt)
1685 tree lhs = gimple_call_lhs (stmt);
1686 if (lhs == NULL_TREE)
1688 tree arg0 = gimple_call_arg (stmt, 0);
1689 tree arg1 = gimple_call_arg (stmt, 1);
1690 tree type = TREE_TYPE (TREE_TYPE (lhs));
1691 int uns0_p = TYPE_UNSIGNED (TREE_TYPE (arg0));
1692 int uns1_p = TYPE_UNSIGNED (TREE_TYPE (arg1));
1693 int unsr_p = TYPE_UNSIGNED (type);
1694 int prec0 = TYPE_PRECISION (TREE_TYPE (arg0));
1695 int prec1 = TYPE_PRECISION (TREE_TYPE (arg1));
1696 int precres = TYPE_PRECISION (type);
1697 location_t loc = gimple_location (stmt);
1698 if (!uns0_p && get_range_pos_neg (arg0) == 1)
1700 if (!uns1_p && get_range_pos_neg (arg1) == 1)
1702 int pr = get_min_precision (arg0, uns0_p ? UNSIGNED : SIGNED);
1703 prec0 = MIN (prec0, pr);
1704 pr = get_min_precision (arg1, uns1_p ? UNSIGNED : SIGNED);
1705 prec1 = MIN (prec1, pr);
1707 /* If uns0_p && uns1_p, precop is minimum needed precision
1708 of unsigned type to hold the exact result, otherwise
1709 precop is minimum needed precision of signed type to
1710 hold the exact result. */
1712 if (code == MULT_EXPR)
1713 precop = prec0 + prec1 + (uns0_p != uns1_p);
1716 if (uns0_p == uns1_p)
1717 precop = MAX (prec0, prec1) + 1;
1719 precop = MAX (prec0 + 1, prec1) + 1;
1721 precop = MAX (prec0, prec1 + 1) + 1;
1723 int orig_precres = precres;
1727 if ((uns0_p && uns1_p)
1728 ? ((precop + !unsr_p) <= precres
1729 /* u1 - u2 -> ur can overflow, no matter what precision
1731 && (code != MINUS_EXPR || !unsr_p))
1732 : (!unsr_p && precop <= precres))
1734 /* The infinity precision result will always fit into result. */
1735 rtx target = expand_expr (lhs, NULL_RTX, VOIDmode, EXPAND_WRITE);
1736 write_complex_part (target, const0_rtx, true);
1737 enum machine_mode mode = TYPE_MODE (type);
1738 struct separate_ops ops;
1741 ops.op0 = fold_convert_loc (loc, type, arg0);
1742 ops.op1 = fold_convert_loc (loc, type, arg1);
1743 ops.op2 = NULL_TREE;
1745 rtx tem = expand_expr_real_2 (&ops, NULL_RTX, mode, EXPAND_NORMAL);
1746 expand_arith_overflow_result_store (lhs, target, mode, tem);
1750 /* For sub-word operations, if target doesn't have them, start
1751 with precres widening right away, otherwise do it only
1752 if the most simple cases can't be used. */
1753 if (WORD_REGISTER_OPERATIONS
1754 && orig_precres == precres
1755 && precres < BITS_PER_WORD)
1757 else if ((uns0_p && uns1_p && unsr_p && prec0 <= precres
1758 && prec1 <= precres)
1759 || ((!uns0_p || !uns1_p) && !unsr_p
1760 && prec0 + uns0_p <= precres
1761 && prec1 + uns1_p <= precres))
1763 arg0 = fold_convert_loc (loc, type, arg0);
1764 arg1 = fold_convert_loc (loc, type, arg1);
1768 if (integer_zerop (arg0) && !unsr_p)
1769 expand_neg_overflow (loc, lhs, arg1, false);
1772 expand_addsub_overflow (loc, code, lhs, arg0, arg1,
1773 unsr_p, unsr_p, unsr_p, false);
1776 expand_mul_overflow (loc, lhs, arg0, arg1,
1777 unsr_p, unsr_p, unsr_p, false);
1784 /* For sub-word operations, retry with a wider type first. */
1785 if (orig_precres == precres && precop <= BITS_PER_WORD)
1787 #if WORD_REGISTER_OPERATIONS
1788 int p = BITS_PER_WORD;
1792 enum machine_mode m = smallest_mode_for_size (p, MODE_INT);
1793 tree optype = build_nonstandard_integer_type (GET_MODE_PRECISION (m),
1796 p = TYPE_PRECISION (optype);
1800 unsr_p = TYPE_UNSIGNED (optype);
1806 if (prec0 <= precres && prec1 <= precres)
1811 types[0] = build_nonstandard_integer_type (precres, 0);
1817 types[1] = build_nonstandard_integer_type (precres, 1);
1819 arg0 = fold_convert_loc (loc, types[uns0_p], arg0);
1820 arg1 = fold_convert_loc (loc, types[uns1_p], arg1);
1821 if (code != MULT_EXPR)
1822 expand_addsub_overflow (loc, code, lhs, arg0, arg1, unsr_p,
1823 uns0_p, uns1_p, false);
1825 expand_mul_overflow (loc, lhs, arg0, arg1, unsr_p,
1826 uns0_p, uns1_p, false);
1830 /* Retry with a wider type. */
1831 if (orig_precres == precres)
1833 int p = MAX (prec0, prec1);
1834 enum machine_mode m = smallest_mode_for_size (p, MODE_INT);
1835 tree optype = build_nonstandard_integer_type (GET_MODE_PRECISION (m),
1838 p = TYPE_PRECISION (optype);
1842 unsr_p = TYPE_UNSIGNED (optype);
1853 /* Expand ADD_OVERFLOW STMT. */
1856 expand_ADD_OVERFLOW (internal_fn, gcall *stmt)
1858 expand_arith_overflow (PLUS_EXPR, stmt);
1861 /* Expand SUB_OVERFLOW STMT. */
1864 expand_SUB_OVERFLOW (internal_fn, gcall *stmt)
1866 expand_arith_overflow (MINUS_EXPR, stmt);
1869 /* Expand MUL_OVERFLOW STMT. */
1872 expand_MUL_OVERFLOW (internal_fn, gcall *stmt)
1874 expand_arith_overflow (MULT_EXPR, stmt);
1877 /* This should get folded in tree-vectorizer.c. */
1880 expand_LOOP_VECTORIZED (internal_fn, gcall *)
1885 /* Expand MASK_LOAD call STMT using optab OPTAB. */
1888 expand_mask_load_optab_fn (internal_fn, gcall *stmt, convert_optab optab)
1890 struct expand_operand ops[3];
1891 tree type, lhs, rhs, maskt;
1892 rtx mem, target, mask;
1894 maskt = gimple_call_arg (stmt, 2);
1895 lhs = gimple_call_lhs (stmt);
1896 if (lhs == NULL_TREE)
1898 type = TREE_TYPE (lhs);
1899 rhs = fold_build2 (MEM_REF, type, gimple_call_arg (stmt, 0),
1900 gimple_call_arg (stmt, 1));
1902 mem = expand_expr (rhs, NULL_RTX, VOIDmode, EXPAND_WRITE);
1903 gcc_assert (MEM_P (mem));
1904 mask = expand_normal (maskt);
1905 target = expand_expr (lhs, NULL_RTX, VOIDmode, EXPAND_WRITE);
1906 create_output_operand (&ops[0], target, TYPE_MODE (type));
1907 create_fixed_operand (&ops[1], mem);
1908 create_input_operand (&ops[2], mask, TYPE_MODE (TREE_TYPE (maskt)));
1909 expand_insn (convert_optab_handler (optab, TYPE_MODE (type),
1910 TYPE_MODE (TREE_TYPE (maskt))),
1914 /* Expand MASK_STORE call STMT using optab OPTAB. */
1917 expand_mask_store_optab_fn (internal_fn, gcall *stmt, convert_optab optab)
1919 struct expand_operand ops[3];
1920 tree type, lhs, rhs, maskt;
1923 maskt = gimple_call_arg (stmt, 2);
1924 rhs = gimple_call_arg (stmt, 3);
1925 type = TREE_TYPE (rhs);
1926 lhs = fold_build2 (MEM_REF, type, gimple_call_arg (stmt, 0),
1927 gimple_call_arg (stmt, 1));
1929 mem = expand_expr (lhs, NULL_RTX, VOIDmode, EXPAND_WRITE);
1930 gcc_assert (MEM_P (mem));
1931 mask = expand_normal (maskt);
1932 reg = expand_normal (rhs);
1933 create_fixed_operand (&ops[0], mem);
1934 create_input_operand (&ops[1], reg, TYPE_MODE (type));
1935 create_input_operand (&ops[2], mask, TYPE_MODE (TREE_TYPE (maskt)));
1936 expand_insn (convert_optab_handler (optab, TYPE_MODE (type),
1937 TYPE_MODE (TREE_TYPE (maskt))),
1942 expand_ABNORMAL_DISPATCHER (internal_fn, gcall *)
1947 expand_BUILTIN_EXPECT (internal_fn, gcall *stmt)
1949 /* When guessing was done, the hints should be already stripped away. */
1950 gcc_assert (!flag_guess_branch_prob || optimize == 0 || seen_error ());
1953 tree lhs = gimple_call_lhs (stmt);
1955 target = expand_expr (lhs, NULL_RTX, VOIDmode, EXPAND_WRITE);
1957 target = const0_rtx;
1958 rtx val = expand_expr (gimple_call_arg (stmt, 0), target, VOIDmode, EXPAND_NORMAL);
1959 if (lhs && val != target)
1960 emit_move_insn (target, val);
1963 /* IFN_VA_ARG is supposed to be expanded at pass_stdarg. So this dummy function
1964 should never be called. */
1967 expand_VA_ARG (internal_fn, gcall *)
1972 /* Expand the IFN_UNIQUE function according to its first argument. */
1975 expand_UNIQUE (internal_fn, gcall *stmt)
1977 rtx pattern = NULL_RTX;
1978 enum ifn_unique_kind kind
1979 = (enum ifn_unique_kind) TREE_INT_CST_LOW (gimple_call_arg (stmt, 0));
1986 case IFN_UNIQUE_UNSPEC:
1987 if (targetm.have_unique ())
1988 pattern = targetm.gen_unique ();
1991 case IFN_UNIQUE_OACC_FORK:
1992 case IFN_UNIQUE_OACC_JOIN:
1993 if (targetm.have_oacc_fork () && targetm.have_oacc_join ())
1995 tree lhs = gimple_call_lhs (stmt);
1996 rtx target = const0_rtx;
1999 target = expand_expr (lhs, NULL_RTX, VOIDmode, EXPAND_WRITE);
2001 rtx data_dep = expand_normal (gimple_call_arg (stmt, 1));
2002 rtx axis = expand_normal (gimple_call_arg (stmt, 2));
2004 if (kind == IFN_UNIQUE_OACC_FORK)
2005 pattern = targetm.gen_oacc_fork (target, data_dep, axis);
2007 pattern = targetm.gen_oacc_join (target, data_dep, axis);
2015 emit_insn (pattern);
2018 /* The size of an OpenACC compute dimension. */
2021 expand_GOACC_DIM_SIZE (internal_fn, gcall *stmt)
2023 tree lhs = gimple_call_lhs (stmt);
2028 rtx target = expand_expr (lhs, NULL_RTX, VOIDmode, EXPAND_WRITE);
2029 if (targetm.have_oacc_dim_size ())
2031 rtx dim = expand_expr (gimple_call_arg (stmt, 0), NULL_RTX,
2032 VOIDmode, EXPAND_NORMAL);
2033 emit_insn (targetm.gen_oacc_dim_size (target, dim));
2036 emit_move_insn (target, GEN_INT (1));
2039 /* The position of an OpenACC execution engine along one compute axis. */
2042 expand_GOACC_DIM_POS (internal_fn, gcall *stmt)
2044 tree lhs = gimple_call_lhs (stmt);
2049 rtx target = expand_expr (lhs, NULL_RTX, VOIDmode, EXPAND_WRITE);
2050 if (targetm.have_oacc_dim_pos ())
2052 rtx dim = expand_expr (gimple_call_arg (stmt, 0), NULL_RTX,
2053 VOIDmode, EXPAND_NORMAL);
2054 emit_insn (targetm.gen_oacc_dim_pos (target, dim));
2057 emit_move_insn (target, const0_rtx);
2060 /* This is expanded by oacc_device_lower pass. */
2063 expand_GOACC_LOOP (internal_fn, gcall *)
2068 /* This is expanded by oacc_device_lower pass. */
2071 expand_GOACC_REDUCTION (internal_fn, gcall *)
2076 /* Set errno to EDOM. */
2079 expand_SET_EDOM (internal_fn, gcall *)
2082 #ifdef GEN_ERRNO_RTX
2083 rtx errno_rtx = GEN_ERRNO_RTX;
2085 rtx errno_rtx = gen_rtx_MEM (word_mode, gen_rtx_SYMBOL_REF (Pmode, "errno"));
2087 emit_move_insn (errno_rtx,
2088 gen_int_mode (TARGET_EDOM, GET_MODE (errno_rtx)));
2094 /* Expand a call to FN using the operands in STMT. FN has a single
2095 output operand and NARGS input operands. */
2098 expand_direct_optab_fn (internal_fn fn, gcall *stmt, direct_optab optab,
2101 expand_operand *ops = XALLOCAVEC (expand_operand, nargs + 1);
2103 tree_pair types = direct_internal_fn_types (fn, stmt);
2104 insn_code icode = direct_optab_handler (optab, TYPE_MODE (types.first));
2106 tree lhs = gimple_call_lhs (stmt);
2107 tree lhs_type = TREE_TYPE (lhs);
2108 rtx lhs_rtx = expand_expr (lhs, NULL_RTX, VOIDmode, EXPAND_WRITE);
2109 create_output_operand (&ops[0], lhs_rtx, insn_data[icode].operand[0].mode);
2111 for (unsigned int i = 0; i < nargs; ++i)
2113 tree rhs = gimple_call_arg (stmt, i);
2114 tree rhs_type = TREE_TYPE (rhs);
2115 rtx rhs_rtx = expand_normal (rhs);
2116 if (INTEGRAL_TYPE_P (rhs_type))
2117 create_convert_operand_from (&ops[i + 1], rhs_rtx,
2118 TYPE_MODE (rhs_type),
2119 TYPE_UNSIGNED (rhs_type));
2121 create_input_operand (&ops[i + 1], rhs_rtx, TYPE_MODE (rhs_type));
2124 expand_insn (icode, nargs + 1, ops);
2125 if (!rtx_equal_p (lhs_rtx, ops[0].value))
2127 /* If the return value has an integral type, convert the instruction
2128 result to that type. This is useful for things that return an
2129 int regardless of the size of the input. If the instruction result
2130 is smaller than required, assume that it is signed.
2132 If the return value has a nonintegral type, its mode must match
2133 the instruction result. */
2134 if (GET_CODE (lhs_rtx) == SUBREG && SUBREG_PROMOTED_VAR_P (lhs_rtx))
2136 /* If this is a scalar in a register that is stored in a wider
2137 mode than the declared mode, compute the result into its
2138 declared mode and then convert to the wider mode. */
2139 gcc_checking_assert (INTEGRAL_TYPE_P (lhs_type));
2140 rtx tmp = convert_to_mode (GET_MODE (lhs_rtx), ops[0].value, 0);
2141 convert_move (SUBREG_REG (lhs_rtx), tmp,
2142 SUBREG_PROMOTED_SIGN (lhs_rtx));
2144 else if (GET_MODE (lhs_rtx) == GET_MODE (ops[0].value))
2145 emit_move_insn (lhs_rtx, ops[0].value);
2148 gcc_checking_assert (INTEGRAL_TYPE_P (lhs_type));
2149 convert_move (lhs_rtx, ops[0].value, 0);
2154 /* Expanders for optabs that can use expand_direct_optab_fn. */
2156 #define expand_unary_optab_fn(FN, STMT, OPTAB) \
2157 expand_direct_optab_fn (FN, STMT, OPTAB, 1)
2159 #define expand_binary_optab_fn(FN, STMT, OPTAB) \
2160 expand_direct_optab_fn (FN, STMT, OPTAB, 2)
2162 /* RETURN_TYPE and ARGS are a return type and argument list that are
2163 in principle compatible with FN (which satisfies direct_internal_fn_p).
2164 Return the types that should be used to determine whether the
2165 target supports FN. */
2168 direct_internal_fn_types (internal_fn fn, tree return_type, tree *args)
2170 const direct_internal_fn_info &info = direct_internal_fn (fn);
2171 tree type0 = (info.type0 < 0 ? return_type : TREE_TYPE (args[info.type0]));
2172 tree type1 = (info.type1 < 0 ? return_type : TREE_TYPE (args[info.type1]));
2173 return tree_pair (type0, type1);
2176 /* CALL is a call whose return type and arguments are in principle
2177 compatible with FN (which satisfies direct_internal_fn_p). Return the
2178 types that should be used to determine whether the target supports FN. */
2181 direct_internal_fn_types (internal_fn fn, gcall *call)
2183 const direct_internal_fn_info &info = direct_internal_fn (fn);
2184 tree op0 = (info.type0 < 0
2185 ? gimple_call_lhs (call)
2186 : gimple_call_arg (call, info.type0));
2187 tree op1 = (info.type1 < 0
2188 ? gimple_call_lhs (call)
2189 : gimple_call_arg (call, info.type1));
2190 return tree_pair (TREE_TYPE (op0), TREE_TYPE (op1));
2193 /* Return true if OPTAB is supported for TYPES (whose modes should be
2194 the same). Used for simple direct optabs. */
2197 direct_optab_supported_p (direct_optab optab, tree_pair types)
2199 machine_mode mode = TYPE_MODE (types.first);
2200 gcc_checking_assert (mode == TYPE_MODE (types.second));
2201 return direct_optab_handler (optab, mode) != CODE_FOR_nothing;
2204 /* Return true if load/store lanes optab OPTAB is supported for
2205 array type TYPES.first. */
2208 multi_vector_optab_supported_p (convert_optab optab, tree_pair types)
2210 return get_multi_vector_move (types.first, optab) != CODE_FOR_nothing;
2213 #define direct_unary_optab_supported_p direct_optab_supported_p
2214 #define direct_binary_optab_supported_p direct_optab_supported_p
2215 #define direct_mask_load_optab_supported_p direct_optab_supported_p
2216 #define direct_load_lanes_optab_supported_p multi_vector_optab_supported_p
2217 #define direct_mask_store_optab_supported_p direct_optab_supported_p
2218 #define direct_store_lanes_optab_supported_p multi_vector_optab_supported_p
2220 /* Return true if FN is supported for the types in TYPES. The types
2221 are those associated with the "type0" and "type1" fields of FN's
2222 direct_internal_fn_info structure. */
2225 direct_internal_fn_supported_p (internal_fn fn, tree_pair types)
2229 #define DEF_INTERNAL_FN(CODE, FLAGS, FNSPEC) \
2230 case IFN_##CODE: break;
2231 #define DEF_INTERNAL_OPTAB_FN(CODE, FLAGS, OPTAB, TYPE) \
2233 return direct_##TYPE##_optab_supported_p (OPTAB##_optab, types);
2234 #include "internal-fn.def"
2242 /* Return true if FN is supported for type TYPE. The caller knows that
2243 the "type0" and "type1" fields of FN's direct_internal_fn_info
2244 structure are the same. */
2247 direct_internal_fn_supported_p (internal_fn fn, tree type)
2249 const direct_internal_fn_info &info = direct_internal_fn (fn);
2250 gcc_checking_assert (info.type0 == info.type1);
2251 return direct_internal_fn_supported_p (fn, tree_pair (type, type));
2254 /* Return true if IFN_SET_EDOM is supported. */
2257 set_edom_supported_p (void)
2266 #define DEF_INTERNAL_OPTAB_FN(CODE, FLAGS, OPTAB, TYPE) \
2268 expand_##CODE (internal_fn fn, gcall *stmt) \
2270 expand_##TYPE##_optab_fn (fn, stmt, OPTAB##_optab); \
2272 #include "internal-fn.def"
2274 /* Routines to expand each internal function, indexed by function number.
2275 Each routine has the prototype:
2277 expand_<NAME> (gcall *stmt)
2279 where STMT is the statement that performs the call. */
2280 static void (*const internal_fn_expanders[]) (internal_fn, gcall *) = {
2281 #define DEF_INTERNAL_FN(CODE, FLAGS, FNSPEC) expand_##CODE,
2282 #include "internal-fn.def"
2286 /* Expand STMT as though it were a call to internal function FN. */
2289 expand_internal_call (internal_fn fn, gcall *stmt)
2291 internal_fn_expanders[fn] (fn, stmt);
2294 /* Expand STMT, which is a call to internal function FN. */
2297 expand_internal_call (gcall *stmt)
2299 expand_internal_call (gimple_call_internal_fn (stmt), stmt);