2 Copyright (C) 2011-2016 Free Software Foundation, Inc.
4 This file is part of GCC.
6 GCC is free software; you can redistribute it and/or modify it under
7 the terms of the GNU General Public License as published by the Free
8 Software Foundation; either version 3, or (at your option) any later
11 GCC is distributed in the hope that it will be useful, but WITHOUT ANY
12 WARRANTY; without even the implied warranty of MERCHANTABILITY or
13 FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License
16 You should have received a copy of the GNU General Public License
17 along with GCC; see the file COPYING3. If not see
18 <http://www.gnu.org/licenses/>. */
22 #include "coretypes.h"
29 #include "stringpool.h"
31 #include "tree-ssanames.h"
36 #include "diagnostic-core.h"
37 #include "fold-const.h"
38 #include "internal-fn.h"
39 #include "stor-layout.h"
45 #include "optabs-tree.h"
47 /* The names of each internal function, indexed by function number. */
48 const char *const internal_fn_name_array[] = {
49 #define DEF_INTERNAL_FN(CODE, FLAGS, FNSPEC) #CODE,
50 #include "internal-fn.def"
54 /* The ECF_* flags of each internal function, indexed by function number. */
55 const int internal_fn_flags_array[] = {
56 #define DEF_INTERNAL_FN(CODE, FLAGS, FNSPEC) FLAGS,
57 #include "internal-fn.def"
61 /* Fnspec of each internal function, indexed by function number. */
62 const_tree internal_fn_fnspec_array[IFN_LAST + 1];
67 #define DEF_INTERNAL_FN(CODE, FLAGS, FNSPEC) \
68 if (FNSPEC) internal_fn_fnspec_array[IFN_##CODE] = \
69 build_string ((int) sizeof (FNSPEC), FNSPEC ? FNSPEC : "");
70 #include "internal-fn.def"
71 internal_fn_fnspec_array[IFN_LAST] = 0;
74 /* Create static initializers for the information returned by
75 direct_internal_fn. */
76 #define not_direct { -2, -2, false }
77 #define mask_load_direct { -1, 2, false }
78 #define load_lanes_direct { -1, -1, false }
79 #define mask_store_direct { 3, 2, false }
80 #define store_lanes_direct { 0, 0, false }
81 #define unary_direct { 0, 0, true }
82 #define binary_direct { 0, 0, true }
84 const direct_internal_fn_info direct_internal_fn_array[IFN_LAST + 1] = {
85 #define DEF_INTERNAL_FN(CODE, FLAGS, FNSPEC) not_direct,
86 #define DEF_INTERNAL_OPTAB_FN(CODE, FLAGS, OPTAB, TYPE) TYPE##_direct,
87 #include "internal-fn.def"
91 /* ARRAY_TYPE is an array of vector modes. Return the associated insn
92 for load-lanes-style optab OPTAB, or CODE_FOR_nothing if none. */
95 get_multi_vector_move (tree array_type, convert_optab optab)
100 gcc_assert (TREE_CODE (array_type) == ARRAY_TYPE);
101 imode = TYPE_MODE (array_type);
102 vmode = TYPE_MODE (TREE_TYPE (array_type));
104 return convert_optab_handler (optab, imode, vmode);
107 /* Expand LOAD_LANES call STMT using optab OPTAB. */
110 expand_load_lanes_optab_fn (internal_fn, gcall *stmt, convert_optab optab)
112 struct expand_operand ops[2];
116 lhs = gimple_call_lhs (stmt);
117 rhs = gimple_call_arg (stmt, 0);
118 type = TREE_TYPE (lhs);
120 target = expand_expr (lhs, NULL_RTX, VOIDmode, EXPAND_WRITE);
121 mem = expand_normal (rhs);
123 gcc_assert (MEM_P (mem));
124 PUT_MODE (mem, TYPE_MODE (type));
126 create_output_operand (&ops[0], target, TYPE_MODE (type));
127 create_fixed_operand (&ops[1], mem);
128 expand_insn (get_multi_vector_move (type, optab), 2, ops);
131 /* Expand STORE_LANES call STMT using optab OPTAB. */
134 expand_store_lanes_optab_fn (internal_fn, gcall *stmt, convert_optab optab)
136 struct expand_operand ops[2];
140 lhs = gimple_call_lhs (stmt);
141 rhs = gimple_call_arg (stmt, 0);
142 type = TREE_TYPE (rhs);
144 target = expand_expr (lhs, NULL_RTX, VOIDmode, EXPAND_WRITE);
145 reg = expand_normal (rhs);
147 gcc_assert (MEM_P (target));
148 PUT_MODE (target, TYPE_MODE (type));
150 create_fixed_operand (&ops[0], target);
151 create_input_operand (&ops[1], reg, TYPE_MODE (type));
152 expand_insn (get_multi_vector_move (type, optab), 2, ops);
156 expand_ANNOTATE (internal_fn, gcall *)
161 /* This should get expanded in adjust_simduid_builtins. */
164 expand_GOMP_SIMD_LANE (internal_fn, gcall *)
169 /* This should get expanded in adjust_simduid_builtins. */
172 expand_GOMP_SIMD_VF (internal_fn, gcall *)
177 /* This should get expanded in adjust_simduid_builtins. */
180 expand_GOMP_SIMD_LAST_LANE (internal_fn, gcall *)
185 /* This should get expanded in adjust_simduid_builtins. */
188 expand_GOMP_SIMD_ORDERED_START (internal_fn, gcall *)
193 /* This should get expanded in adjust_simduid_builtins. */
196 expand_GOMP_SIMD_ORDERED_END (internal_fn, gcall *)
201 /* This should get expanded in the sanopt pass. */
204 expand_UBSAN_NULL (internal_fn, gcall *)
209 /* This should get expanded in the sanopt pass. */
212 expand_UBSAN_BOUNDS (internal_fn, gcall *)
217 /* This should get expanded in the sanopt pass. */
220 expand_UBSAN_VPTR (internal_fn, gcall *)
225 /* This should get expanded in the sanopt pass. */
228 expand_UBSAN_OBJECT_SIZE (internal_fn, gcall *)
233 /* This should get expanded in the sanopt pass. */
236 expand_ASAN_CHECK (internal_fn, gcall *)
241 /* This should get expanded in the sanopt pass. */
244 expand_ASAN_MARK (internal_fn, gcall *)
250 /* This should get expanded in the tsan pass. */
253 expand_TSAN_FUNC_EXIT (internal_fn, gcall *)
258 /* This should get expanded in the lower pass. */
261 expand_FALLTHROUGH (internal_fn, gcall *call)
263 error_at (gimple_location (call),
264 "invalid use of attribute %<fallthrough%>");
267 /* Helper function for expand_addsub_overflow. Return 1
268 if ARG interpreted as signed in its precision is known to be always
269 positive or 2 if ARG is known to be always negative, or 3 if ARG may
270 be positive or negative. */
273 get_range_pos_neg (tree arg)
275 if (arg == error_mark_node)
278 int prec = TYPE_PRECISION (TREE_TYPE (arg));
280 if (TREE_CODE (arg) == INTEGER_CST)
282 wide_int w = wi::sext (arg, prec);
288 while (CONVERT_EXPR_P (arg)
289 && INTEGRAL_TYPE_P (TREE_TYPE (TREE_OPERAND (arg, 0)))
290 && TYPE_PRECISION (TREE_TYPE (TREE_OPERAND (arg, 0))) <= prec)
292 arg = TREE_OPERAND (arg, 0);
293 /* Narrower value zero extended into wider type
294 will always result in positive values. */
295 if (TYPE_UNSIGNED (TREE_TYPE (arg))
296 && TYPE_PRECISION (TREE_TYPE (arg)) < prec)
298 prec = TYPE_PRECISION (TREE_TYPE (arg));
303 if (TREE_CODE (arg) != SSA_NAME)
305 wide_int arg_min, arg_max;
306 while (get_range_info (arg, &arg_min, &arg_max) != VR_RANGE)
308 gimple *g = SSA_NAME_DEF_STMT (arg);
309 if (is_gimple_assign (g)
310 && CONVERT_EXPR_CODE_P (gimple_assign_rhs_code (g)))
312 tree t = gimple_assign_rhs1 (g);
313 if (INTEGRAL_TYPE_P (TREE_TYPE (t))
314 && TYPE_PRECISION (TREE_TYPE (t)) <= prec)
316 if (TYPE_UNSIGNED (TREE_TYPE (t))
317 && TYPE_PRECISION (TREE_TYPE (t)) < prec)
319 prec = TYPE_PRECISION (TREE_TYPE (t));
328 if (TYPE_UNSIGNED (TREE_TYPE (arg)))
330 /* For unsigned values, the "positive" range comes
331 below the "negative" range. */
332 if (!wi::neg_p (wi::sext (arg_max, prec), SIGNED))
334 if (wi::neg_p (wi::sext (arg_min, prec), SIGNED))
339 if (!wi::neg_p (wi::sext (arg_min, prec), SIGNED))
341 if (wi::neg_p (wi::sext (arg_max, prec), SIGNED))
347 /* Return minimum precision needed to represent all values
348 of ARG in SIGNed integral type. */
351 get_min_precision (tree arg, signop sign)
353 int prec = TYPE_PRECISION (TREE_TYPE (arg));
355 signop orig_sign = sign;
356 if (TREE_CODE (arg) == INTEGER_CST)
359 if (TYPE_SIGN (TREE_TYPE (arg)) != sign)
361 widest_int w = wi::to_widest (arg);
362 w = wi::ext (w, prec, sign);
363 p = wi::min_precision (w, sign);
366 p = wi::min_precision (arg, sign);
367 return MIN (p, prec);
369 while (CONVERT_EXPR_P (arg)
370 && INTEGRAL_TYPE_P (TREE_TYPE (TREE_OPERAND (arg, 0)))
371 && TYPE_PRECISION (TREE_TYPE (TREE_OPERAND (arg, 0))) <= prec)
373 arg = TREE_OPERAND (arg, 0);
374 if (TYPE_PRECISION (TREE_TYPE (arg)) < prec)
376 if (TYPE_UNSIGNED (TREE_TYPE (arg)))
378 else if (sign == UNSIGNED && get_range_pos_neg (arg) != 1)
379 return prec + (orig_sign != sign);
380 prec = TYPE_PRECISION (TREE_TYPE (arg));
383 return prec + (orig_sign != sign);
385 if (TREE_CODE (arg) != SSA_NAME)
386 return prec + (orig_sign != sign);
387 wide_int arg_min, arg_max;
388 while (get_range_info (arg, &arg_min, &arg_max) != VR_RANGE)
390 gimple *g = SSA_NAME_DEF_STMT (arg);
391 if (is_gimple_assign (g)
392 && CONVERT_EXPR_CODE_P (gimple_assign_rhs_code (g)))
394 tree t = gimple_assign_rhs1 (g);
395 if (INTEGRAL_TYPE_P (TREE_TYPE (t))
396 && TYPE_PRECISION (TREE_TYPE (t)) <= prec)
399 if (TYPE_PRECISION (TREE_TYPE (arg)) < prec)
401 if (TYPE_UNSIGNED (TREE_TYPE (arg)))
403 else if (sign == UNSIGNED && get_range_pos_neg (arg) != 1)
404 return prec + (orig_sign != sign);
405 prec = TYPE_PRECISION (TREE_TYPE (arg));
408 return prec + (orig_sign != sign);
412 return prec + (orig_sign != sign);
414 if (sign == TYPE_SIGN (TREE_TYPE (arg)))
416 int p1 = wi::min_precision (arg_min, sign);
417 int p2 = wi::min_precision (arg_max, sign);
419 prec = MIN (prec, p1);
421 else if (sign == UNSIGNED && !wi::neg_p (arg_min, SIGNED))
423 int p = wi::min_precision (arg_max, UNSIGNED);
424 prec = MIN (prec, p);
426 return prec + (orig_sign != sign);
429 /* Helper for expand_*_overflow. Set the __imag__ part to true
430 (1 except for signed:1 type, in which case store -1). */
433 expand_arith_set_overflow (tree lhs, rtx target)
435 if (TYPE_PRECISION (TREE_TYPE (TREE_TYPE (lhs))) == 1
436 && !TYPE_UNSIGNED (TREE_TYPE (TREE_TYPE (lhs))))
437 write_complex_part (target, constm1_rtx, true);
439 write_complex_part (target, const1_rtx, true);
442 /* Helper for expand_*_overflow. Store RES into the __real__ part
443 of TARGET. If RES has larger MODE than __real__ part of TARGET,
444 set the __imag__ part to 1 if RES doesn't fit into it. Similarly
445 if LHS has smaller precision than its mode. */
448 expand_arith_overflow_result_store (tree lhs, rtx target,
449 machine_mode mode, rtx res)
451 machine_mode tgtmode = GET_MODE_INNER (GET_MODE (target));
455 rtx_code_label *done_label = gen_label_rtx ();
456 int uns = TYPE_UNSIGNED (TREE_TYPE (TREE_TYPE (lhs)));
457 lres = convert_modes (tgtmode, mode, res, uns);
458 gcc_assert (GET_MODE_PRECISION (tgtmode) < GET_MODE_PRECISION (mode));
459 do_compare_rtx_and_jump (res, convert_modes (mode, tgtmode, lres, uns),
460 EQ, true, mode, NULL_RTX, NULL, done_label,
462 expand_arith_set_overflow (lhs, target);
463 emit_label (done_label);
465 int prec = TYPE_PRECISION (TREE_TYPE (TREE_TYPE (lhs)));
466 int tgtprec = GET_MODE_PRECISION (tgtmode);
469 rtx_code_label *done_label = gen_label_rtx ();
470 int uns = TYPE_UNSIGNED (TREE_TYPE (TREE_TYPE (lhs)));
475 = immed_wide_int_const (wi::shifted_mask (0, prec, false, tgtprec),
477 lres = expand_simple_binop (tgtmode, AND, res, mask, NULL_RTX,
478 true, OPTAB_LIB_WIDEN);
482 lres = expand_shift (LSHIFT_EXPR, tgtmode, res, tgtprec - prec,
484 lres = expand_shift (RSHIFT_EXPR, tgtmode, lres, tgtprec - prec,
487 do_compare_rtx_and_jump (res, lres,
488 EQ, true, tgtmode, NULL_RTX, NULL, done_label,
490 expand_arith_set_overflow (lhs, target);
491 emit_label (done_label);
493 write_complex_part (target, lres, false);
496 /* Helper for expand_*_overflow. Store RES into TARGET. */
499 expand_ubsan_result_store (rtx target, rtx res)
501 if (GET_CODE (target) == SUBREG && SUBREG_PROMOTED_VAR_P (target))
502 /* If this is a scalar in a register that is stored in a wider mode
503 than the declared mode, compute the result into its declared mode
504 and then convert to the wider mode. Our value is the computed
506 convert_move (SUBREG_REG (target), res, SUBREG_PROMOTED_SIGN (target));
508 emit_move_insn (target, res);
511 /* Add sub/add overflow checking to the statement STMT.
512 CODE says whether the operation is +, or -. */
515 expand_addsub_overflow (location_t loc, tree_code code, tree lhs,
516 tree arg0, tree arg1, bool unsr_p, bool uns0_p,
517 bool uns1_p, bool is_ubsan, tree *datap)
519 rtx res, target = NULL_RTX;
521 rtx_code_label *done_label = gen_label_rtx ();
522 rtx_code_label *do_error = gen_label_rtx ();
523 do_pending_stack_adjust ();
524 rtx op0 = expand_normal (arg0);
525 rtx op1 = expand_normal (arg1);
526 machine_mode mode = TYPE_MODE (TREE_TYPE (arg0));
527 int prec = GET_MODE_PRECISION (mode);
528 rtx sgn = immed_wide_int_const (wi::min_value (prec, SIGNED), mode);
532 gcc_assert (!unsr_p && !uns0_p && !uns1_p);
536 target = expand_expr (lhs, NULL_RTX, VOIDmode, EXPAND_WRITE);
538 write_complex_part (target, const0_rtx, true);
541 /* We assume both operands and result have the same precision
542 here (GET_MODE_BITSIZE (mode)), S stands for signed type
543 with that precision, U for unsigned type with that precision,
544 sgn for unsigned most significant bit in that precision.
545 s1 is signed first operand, u1 is unsigned first operand,
546 s2 is signed second operand, u2 is unsigned second operand,
547 sr is signed result, ur is unsigned result and the following
548 rules say how to compute result (which is always result of
549 the operands as if both were unsigned, cast to the right
550 signedness) and how to compute whether operation overflowed.
553 res = (S) ((U) s1 + (U) s2)
554 ovf = s2 < 0 ? res > s1 : res < s1 (or jump on overflow)
556 res = (S) ((U) s1 - (U) s2)
557 ovf = s2 < 0 ? res < s1 : res > s2 (or jump on overflow)
560 ovf = res < u1 (or jump on carry, but RTL opts will handle it)
563 ovf = res > u1 (or jump on carry, but RTL opts will handle it)
565 res = (S) ((U) s1 + u2)
566 ovf = ((U) res ^ sgn) < u2
571 ovf = t1 < 0 ? t2 > s1 : t2 < s1 (or jump on overflow)
573 res = (S) ((U) s1 - u2)
574 ovf = u2 > ((U) s1 ^ sgn)
577 ovf = s1 < 0 || u2 > (U) s1
580 ovf = u1 >= ((U) s2 ^ sgn)
585 ovf = s2 < 0 ? (S) t2 < (S) t1 : (S) t2 > (S) t1 (or jump on overflow)
587 res = (U) s1 + (U) s2
588 ovf = s2 < 0 ? (s1 | (S) res) < 0) : (s1 & (S) res) < 0)
591 ovf = (U) res < u2 || res < 0
594 ovf = u1 >= u2 ? res < 0 : res >= 0
596 res = (U) s1 - (U) s2
597 ovf = s2 >= 0 ? ((s1 | (S) res) < 0) : ((s1 & (S) res) < 0) */
599 if (code == PLUS_EXPR && uns0_p && !uns1_p)
601 /* PLUS_EXPR is commutative, if operand signedness differs,
602 canonicalize to the first operand being signed and second
603 unsigned to simplify following code. */
604 std::swap (op0, op1);
605 std::swap (arg0, arg1);
611 if (uns0_p && uns1_p && unsr_p)
613 insn_code icode = optab_handler (code == PLUS_EXPR ? uaddv4_optab
614 : usubv4_optab, mode);
615 if (icode != CODE_FOR_nothing)
617 struct expand_operand ops[4];
618 rtx_insn *last = get_last_insn ();
620 res = gen_reg_rtx (mode);
621 create_output_operand (&ops[0], res, mode);
622 create_input_operand (&ops[1], op0, mode);
623 create_input_operand (&ops[2], op1, mode);
624 create_fixed_operand (&ops[3], do_error);
625 if (maybe_expand_insn (icode, 4, ops))
627 last = get_last_insn ();
628 if (profile_status_for_fn (cfun) != PROFILE_ABSENT
630 && any_condjump_p (last)
631 && !find_reg_note (last, REG_BR_PROB, 0))
632 add_int_reg_note (last, REG_BR_PROB, PROB_VERY_UNLIKELY);
633 emit_jump (done_label);
637 delete_insns_since (last);
640 /* Compute the operation. On RTL level, the addition is always
642 res = expand_binop (mode, code == PLUS_EXPR ? add_optab : sub_optab,
643 op0, op1, NULL_RTX, false, OPTAB_LIB_WIDEN);
645 /* For PLUS_EXPR, the operation is commutative, so we can pick
646 operand to compare against. For prec <= BITS_PER_WORD, I think
647 preferring REG operand is better over CONST_INT, because
648 the CONST_INT might enlarge the instruction or CSE would need
649 to figure out we'd already loaded it into a register before.
650 For prec > BITS_PER_WORD, I think CONST_INT might be more beneficial,
651 as then the multi-word comparison can be perhaps simplified. */
652 if (code == PLUS_EXPR
653 && (prec <= BITS_PER_WORD
654 ? (CONST_SCALAR_INT_P (op0) && REG_P (op1))
655 : CONST_SCALAR_INT_P (op1)))
657 do_compare_rtx_and_jump (res, tem, code == PLUS_EXPR ? GEU : LEU,
658 true, mode, NULL_RTX, NULL, done_label,
664 if (!uns0_p && uns1_p && !unsr_p)
666 /* Compute the operation. On RTL level, the addition is always
668 res = expand_binop (mode, code == PLUS_EXPR ? add_optab : sub_optab,
669 op0, op1, NULL_RTX, false, OPTAB_LIB_WIDEN);
670 rtx tem = expand_binop (mode, add_optab,
671 code == PLUS_EXPR ? res : op0, sgn,
672 NULL_RTX, false, OPTAB_LIB_WIDEN);
673 do_compare_rtx_and_jump (tem, op1, GEU, true, mode, NULL_RTX, NULL,
674 done_label, PROB_VERY_LIKELY);
679 if (code == PLUS_EXPR && !uns0_p && uns1_p && unsr_p)
681 op1 = expand_binop (mode, add_optab, op1, sgn, NULL_RTX, false,
683 /* As we've changed op1, we have to avoid using the value range
684 for the original argument. */
685 arg1 = error_mark_node;
691 if (code == MINUS_EXPR && uns0_p && !uns1_p && unsr_p)
693 op0 = expand_binop (mode, add_optab, op0, sgn, NULL_RTX, false,
695 /* As we've changed op0, we have to avoid using the value range
696 for the original argument. */
697 arg0 = error_mark_node;
703 if (code == MINUS_EXPR && !uns0_p && uns1_p && unsr_p)
705 /* Compute the operation. On RTL level, the addition is always
707 res = expand_binop (mode, sub_optab, op0, op1, NULL_RTX, false,
709 int pos_neg = get_range_pos_neg (arg0);
711 /* If ARG0 is known to be always negative, this is always overflow. */
712 emit_jump (do_error);
713 else if (pos_neg == 3)
714 /* If ARG0 is not known to be always positive, check at runtime. */
715 do_compare_rtx_and_jump (op0, const0_rtx, LT, false, mode, NULL_RTX,
716 NULL, do_error, PROB_VERY_UNLIKELY);
717 do_compare_rtx_and_jump (op1, op0, LEU, true, mode, NULL_RTX, NULL,
718 done_label, PROB_VERY_LIKELY);
723 if (code == MINUS_EXPR && uns0_p && !uns1_p && !unsr_p)
725 /* Compute the operation. On RTL level, the addition is always
727 res = expand_binop (mode, sub_optab, op0, op1, NULL_RTX, false,
729 rtx tem = expand_binop (mode, add_optab, op1, sgn, NULL_RTX, false,
731 do_compare_rtx_and_jump (op0, tem, LTU, true, mode, NULL_RTX, NULL,
732 done_label, PROB_VERY_LIKELY);
737 if (code == PLUS_EXPR && uns0_p && uns1_p && !unsr_p)
739 /* Compute the operation. On RTL level, the addition is always
741 res = expand_binop (mode, add_optab, op0, op1, NULL_RTX, false,
743 do_compare_rtx_and_jump (res, const0_rtx, LT, false, mode, NULL_RTX,
744 NULL, do_error, PROB_VERY_UNLIKELY);
746 /* The operation is commutative, so we can pick operand to compare
747 against. For prec <= BITS_PER_WORD, I think preferring REG operand
748 is better over CONST_INT, because the CONST_INT might enlarge the
749 instruction or CSE would need to figure out we'd already loaded it
750 into a register before. For prec > BITS_PER_WORD, I think CONST_INT
751 might be more beneficial, as then the multi-word comparison can be
752 perhaps simplified. */
753 if (prec <= BITS_PER_WORD
754 ? (CONST_SCALAR_INT_P (op1) && REG_P (op0))
755 : CONST_SCALAR_INT_P (op0))
757 do_compare_rtx_and_jump (res, tem, GEU, true, mode, NULL_RTX, NULL,
758 done_label, PROB_VERY_LIKELY);
763 if (!uns0_p && !uns1_p && unsr_p)
765 /* Compute the operation. On RTL level, the addition is always
767 res = expand_binop (mode, code == PLUS_EXPR ? add_optab : sub_optab,
768 op0, op1, NULL_RTX, false, OPTAB_LIB_WIDEN);
769 int pos_neg = get_range_pos_neg (arg1);
770 if (code == PLUS_EXPR)
772 int pos_neg0 = get_range_pos_neg (arg0);
773 if (pos_neg0 != 3 && pos_neg == 3)
775 std::swap (op0, op1);
782 tem = expand_binop (mode, ((pos_neg == 1) ^ (code == MINUS_EXPR))
783 ? and_optab : ior_optab,
784 op0, res, NULL_RTX, false, OPTAB_LIB_WIDEN);
785 do_compare_rtx_and_jump (tem, const0_rtx, GE, false, mode, NULL,
786 NULL, done_label, PROB_VERY_LIKELY);
790 rtx_code_label *do_ior_label = gen_label_rtx ();
791 do_compare_rtx_and_jump (op1, const0_rtx,
792 code == MINUS_EXPR ? GE : LT, false, mode,
793 NULL_RTX, NULL, do_ior_label,
795 tem = expand_binop (mode, and_optab, op0, res, NULL_RTX, false,
797 do_compare_rtx_and_jump (tem, const0_rtx, GE, false, mode, NULL_RTX,
798 NULL, done_label, PROB_VERY_LIKELY);
799 emit_jump (do_error);
800 emit_label (do_ior_label);
801 tem = expand_binop (mode, ior_optab, op0, res, NULL_RTX, false,
803 do_compare_rtx_and_jump (tem, const0_rtx, GE, false, mode, NULL_RTX,
804 NULL, done_label, PROB_VERY_LIKELY);
810 if (code == MINUS_EXPR && uns0_p && uns1_p && !unsr_p)
812 /* Compute the operation. On RTL level, the addition is always
814 res = expand_binop (mode, sub_optab, op0, op1, NULL_RTX, false,
816 rtx_code_label *op0_geu_op1 = gen_label_rtx ();
817 do_compare_rtx_and_jump (op0, op1, GEU, true, mode, NULL_RTX, NULL,
818 op0_geu_op1, PROB_EVEN);
819 do_compare_rtx_and_jump (res, const0_rtx, LT, false, mode, NULL_RTX,
820 NULL, done_label, PROB_VERY_LIKELY);
821 emit_jump (do_error);
822 emit_label (op0_geu_op1);
823 do_compare_rtx_and_jump (res, const0_rtx, GE, false, mode, NULL_RTX,
824 NULL, done_label, PROB_VERY_LIKELY);
828 gcc_assert (!uns0_p && !uns1_p && !unsr_p);
833 insn_code icode = optab_handler (code == PLUS_EXPR ? addv4_optab
834 : subv4_optab, mode);
835 if (icode != CODE_FOR_nothing)
837 struct expand_operand ops[4];
838 rtx_insn *last = get_last_insn ();
840 res = gen_reg_rtx (mode);
841 create_output_operand (&ops[0], res, mode);
842 create_input_operand (&ops[1], op0, mode);
843 create_input_operand (&ops[2], op1, mode);
844 create_fixed_operand (&ops[3], do_error);
845 if (maybe_expand_insn (icode, 4, ops))
847 last = get_last_insn ();
848 if (profile_status_for_fn (cfun) != PROFILE_ABSENT
850 && any_condjump_p (last)
851 && !find_reg_note (last, REG_BR_PROB, 0))
852 add_int_reg_note (last, REG_BR_PROB, PROB_VERY_UNLIKELY);
853 emit_jump (done_label);
857 delete_insns_since (last);
860 /* Compute the operation. On RTL level, the addition is always
862 res = expand_binop (mode, code == PLUS_EXPR ? add_optab : sub_optab,
863 op0, op1, NULL_RTX, false, OPTAB_LIB_WIDEN);
865 /* If we can prove that one of the arguments (for MINUS_EXPR only
866 the second operand, as subtraction is not commutative) is always
867 non-negative or always negative, we can do just one comparison
868 and conditional jump. */
869 int pos_neg = get_range_pos_neg (arg1);
870 if (code == PLUS_EXPR)
872 int pos_neg0 = get_range_pos_neg (arg0);
873 if (pos_neg0 != 3 && pos_neg == 3)
875 std::swap (op0, op1);
880 /* Addition overflows if and only if the two operands have the same sign,
881 and the result has the opposite sign. Subtraction overflows if and
882 only if the two operands have opposite sign, and the subtrahend has
883 the same sign as the result. Here 0 is counted as positive. */
886 /* Compute op0 ^ op1 (operands have opposite sign). */
887 rtx op_xor = expand_binop (mode, xor_optab, op0, op1, NULL_RTX, false,
890 /* Compute res ^ op1 (result and 2nd operand have opposite sign). */
891 rtx res_xor = expand_binop (mode, xor_optab, res, op1, NULL_RTX, false,
895 if (code == PLUS_EXPR)
897 /* Compute (res ^ op1) & ~(op0 ^ op1). */
898 tem = expand_unop (mode, one_cmpl_optab, op_xor, NULL_RTX, false);
899 tem = expand_binop (mode, and_optab, res_xor, tem, NULL_RTX, false,
904 /* Compute (op0 ^ op1) & ~(res ^ op1). */
905 tem = expand_unop (mode, one_cmpl_optab, res_xor, NULL_RTX, false);
906 tem = expand_binop (mode, and_optab, op_xor, tem, NULL_RTX, false,
910 /* No overflow if the result has bit sign cleared. */
911 do_compare_rtx_and_jump (tem, const0_rtx, GE, false, mode, NULL_RTX,
912 NULL, done_label, PROB_VERY_LIKELY);
915 /* Compare the result of the operation with the first operand.
916 No overflow for addition if second operand is positive and result
917 is larger or second operand is negative and result is smaller.
918 Likewise for subtraction with sign of second operand flipped. */
920 do_compare_rtx_and_jump (res, op0,
921 (pos_neg == 1) ^ (code == MINUS_EXPR) ? GE : LE,
922 false, mode, NULL_RTX, NULL, done_label,
927 emit_label (do_error);
930 /* Expand the ubsan builtin call. */
932 fn = ubsan_build_overflow_builtin (code, loc, TREE_TYPE (arg0),
936 do_pending_stack_adjust ();
939 expand_arith_set_overflow (lhs, target);
942 emit_label (done_label);
947 expand_ubsan_result_store (target, res);
951 res = expand_binop (mode, add_optab, res, sgn, NULL_RTX, false,
954 expand_arith_overflow_result_store (lhs, target, mode, res);
959 /* Add negate overflow checking to the statement STMT. */
962 expand_neg_overflow (location_t loc, tree lhs, tree arg1, bool is_ubsan,
967 rtx_code_label *done_label, *do_error;
968 rtx target = NULL_RTX;
970 done_label = gen_label_rtx ();
971 do_error = gen_label_rtx ();
973 do_pending_stack_adjust ();
974 op1 = expand_normal (arg1);
976 machine_mode mode = TYPE_MODE (TREE_TYPE (arg1));
979 target = expand_expr (lhs, NULL_RTX, VOIDmode, EXPAND_WRITE);
981 write_complex_part (target, const0_rtx, true);
984 enum insn_code icode = optab_handler (negv3_optab, mode);
985 if (icode != CODE_FOR_nothing)
987 struct expand_operand ops[3];
988 rtx_insn *last = get_last_insn ();
990 res = gen_reg_rtx (mode);
991 create_output_operand (&ops[0], res, mode);
992 create_input_operand (&ops[1], op1, mode);
993 create_fixed_operand (&ops[2], do_error);
994 if (maybe_expand_insn (icode, 3, ops))
996 last = get_last_insn ();
997 if (profile_status_for_fn (cfun) != PROFILE_ABSENT
999 && any_condjump_p (last)
1000 && !find_reg_note (last, REG_BR_PROB, 0))
1001 add_int_reg_note (last, REG_BR_PROB, PROB_VERY_UNLIKELY);
1002 emit_jump (done_label);
1006 delete_insns_since (last);
1007 icode = CODE_FOR_nothing;
1011 if (icode == CODE_FOR_nothing)
1013 /* Compute the operation. On RTL level, the addition is always
1015 res = expand_unop (mode, neg_optab, op1, NULL_RTX, false);
1017 /* Compare the operand with the most negative value. */
1018 rtx minv = expand_normal (TYPE_MIN_VALUE (TREE_TYPE (arg1)));
1019 do_compare_rtx_and_jump (op1, minv, NE, true, mode, NULL_RTX, NULL,
1020 done_label, PROB_VERY_LIKELY);
1023 emit_label (do_error);
1026 /* Expand the ubsan builtin call. */
1028 fn = ubsan_build_overflow_builtin (NEGATE_EXPR, loc, TREE_TYPE (arg1),
1029 arg1, NULL_TREE, datap);
1032 do_pending_stack_adjust ();
1035 expand_arith_set_overflow (lhs, target);
1038 emit_label (done_label);
1043 expand_ubsan_result_store (target, res);
1045 expand_arith_overflow_result_store (lhs, target, mode, res);
1049 /* Add mul overflow checking to the statement STMT. */
1052 expand_mul_overflow (location_t loc, tree lhs, tree arg0, tree arg1,
1053 bool unsr_p, bool uns0_p, bool uns1_p, bool is_ubsan,
1058 rtx_code_label *done_label, *do_error;
1059 rtx target = NULL_RTX;
1061 enum insn_code icode;
1063 done_label = gen_label_rtx ();
1064 do_error = gen_label_rtx ();
1066 do_pending_stack_adjust ();
1067 op0 = expand_normal (arg0);
1068 op1 = expand_normal (arg1);
1070 machine_mode mode = TYPE_MODE (TREE_TYPE (arg0));
1074 target = expand_expr (lhs, NULL_RTX, VOIDmode, EXPAND_WRITE);
1076 write_complex_part (target, const0_rtx, true);
1080 gcc_assert (!unsr_p && !uns0_p && !uns1_p);
1082 /* We assume both operands and result have the same precision
1083 here (GET_MODE_BITSIZE (mode)), S stands for signed type
1084 with that precision, U for unsigned type with that precision,
1085 sgn for unsigned most significant bit in that precision.
1086 s1 is signed first operand, u1 is unsigned first operand,
1087 s2 is signed second operand, u2 is unsigned second operand,
1088 sr is signed result, ur is unsigned result and the following
1089 rules say how to compute result (which is always result of
1090 the operands as if both were unsigned, cast to the right
1091 signedness) and how to compute whether operation overflowed.
1092 main_ovf (false) stands for jump on signed multiplication
1093 overflow or the main algorithm with uns == false.
1094 main_ovf (true) stands for jump on unsigned multiplication
1095 overflow or the main algorithm with uns == true.
1098 res = (S) ((U) s1 * (U) s2)
1099 ovf = main_ovf (false)
1102 ovf = main_ovf (true)
1105 ovf = (s1 < 0 && u2) || main_ovf (true)
1108 ovf = res < 0 || main_ovf (true)
1110 res = (S) ((U) s1 * u2)
1111 ovf = (S) u2 >= 0 ? main_ovf (false)
1112 : (s1 != 0 && (s1 != -1 || u2 != (U) res))
1114 t1 = (s1 & s2) < 0 ? (-(U) s1) : ((U) s1)
1115 t2 = (s1 & s2) < 0 ? (-(U) s2) : ((U) s2)
1117 ovf = (s1 ^ s2) < 0 ? (s1 && s2) : main_ovf (true) */
1119 if (uns0_p && !uns1_p)
1121 /* Multiplication is commutative, if operand signedness differs,
1122 canonicalize to the first operand being signed and second
1123 unsigned to simplify following code. */
1124 std::swap (op0, op1);
1125 std::swap (arg0, arg1);
1130 int pos_neg0 = get_range_pos_neg (arg0);
1131 int pos_neg1 = get_range_pos_neg (arg1);
1134 if (!uns0_p && uns1_p && unsr_p)
1139 /* If s1 is non-negative, just perform normal u1 * u2 -> ur. */
1142 /* If s1 is negative, avoid the main code, just multiply and
1143 signal overflow if op1 is not 0. */
1144 struct separate_ops ops;
1145 ops.code = MULT_EXPR;
1146 ops.type = TREE_TYPE (arg1);
1147 ops.op0 = make_tree (ops.type, op0);
1148 ops.op1 = make_tree (ops.type, op1);
1149 ops.op2 = NULL_TREE;
1151 res = expand_expr_real_2 (&ops, NULL_RTX, mode, EXPAND_NORMAL);
1152 do_compare_rtx_and_jump (op1, const0_rtx, EQ, true, mode, NULL_RTX,
1153 NULL, done_label, PROB_VERY_LIKELY);
1154 goto do_error_label;
1156 rtx_code_label *do_main_label;
1157 do_main_label = gen_label_rtx ();
1158 do_compare_rtx_and_jump (op0, const0_rtx, GE, false, mode, NULL_RTX,
1159 NULL, do_main_label, PROB_VERY_LIKELY);
1160 do_compare_rtx_and_jump (op1, const0_rtx, EQ, true, mode, NULL_RTX,
1161 NULL, do_main_label, PROB_VERY_LIKELY);
1162 expand_arith_set_overflow (lhs, target);
1163 emit_label (do_main_label);
1171 if (uns0_p && uns1_p && !unsr_p)
1174 /* Rest of handling of this case after res is computed. */
1179 if (!uns0_p && uns1_p && !unsr_p)
1186 /* If (S) u2 is negative (i.e. u2 is larger than maximum of S,
1187 avoid the main code, just multiply and signal overflow
1188 unless 0 * u2 or -1 * ((U) Smin). */
1189 struct separate_ops ops;
1190 ops.code = MULT_EXPR;
1191 ops.type = TREE_TYPE (arg1);
1192 ops.op0 = make_tree (ops.type, op0);
1193 ops.op1 = make_tree (ops.type, op1);
1194 ops.op2 = NULL_TREE;
1196 res = expand_expr_real_2 (&ops, NULL_RTX, mode, EXPAND_NORMAL);
1197 do_compare_rtx_and_jump (op0, const0_rtx, EQ, true, mode, NULL_RTX,
1198 NULL, done_label, PROB_VERY_LIKELY);
1199 do_compare_rtx_and_jump (op0, constm1_rtx, NE, true, mode, NULL_RTX,
1200 NULL, do_error, PROB_VERY_UNLIKELY);
1202 prec = GET_MODE_PRECISION (mode);
1204 sgn = immed_wide_int_const (wi::min_value (prec, SIGNED), mode);
1205 do_compare_rtx_and_jump (op1, sgn, EQ, true, mode, NULL_RTX,
1206 NULL, done_label, PROB_VERY_LIKELY);
1207 goto do_error_label;
1209 /* Rest of handling of this case after res is computed. */
1217 if (!uns0_p && !uns1_p && unsr_p)
1220 switch (pos_neg0 | pos_neg1)
1222 case 1: /* Both operands known to be non-negative. */
1224 case 2: /* Both operands known to be negative. */
1225 op0 = expand_unop (mode, neg_optab, op0, NULL_RTX, false);
1226 op1 = expand_unop (mode, neg_optab, op1, NULL_RTX, false);
1227 /* Avoid looking at arg0/arg1 ranges, as we've changed
1229 arg0 = error_mark_node;
1230 arg1 = error_mark_node;
1233 if ((pos_neg0 ^ pos_neg1) == 3)
1235 /* If one operand is known to be negative and the other
1236 non-negative, this overflows always, unless the non-negative
1237 one is 0. Just do normal multiply and set overflow
1238 unless one of the operands is 0. */
1239 struct separate_ops ops;
1240 ops.code = MULT_EXPR;
1242 = build_nonstandard_integer_type (GET_MODE_PRECISION (mode),
1244 ops.op0 = make_tree (ops.type, op0);
1245 ops.op1 = make_tree (ops.type, op1);
1246 ops.op2 = NULL_TREE;
1248 res = expand_expr_real_2 (&ops, NULL_RTX, mode, EXPAND_NORMAL);
1249 tem = expand_binop (mode, and_optab, op0, op1, NULL_RTX, false,
1251 do_compare_rtx_and_jump (tem, const0_rtx, EQ, true, mode,
1252 NULL_RTX, NULL, done_label,
1254 goto do_error_label;
1256 /* The general case, do all the needed comparisons at runtime. */
1257 rtx_code_label *do_main_label, *after_negate_label;
1259 rop0 = gen_reg_rtx (mode);
1260 rop1 = gen_reg_rtx (mode);
1261 emit_move_insn (rop0, op0);
1262 emit_move_insn (rop1, op1);
1265 do_main_label = gen_label_rtx ();
1266 after_negate_label = gen_label_rtx ();
1267 tem = expand_binop (mode, and_optab, op0, op1, NULL_RTX, false,
1269 do_compare_rtx_and_jump (tem, const0_rtx, GE, false, mode, NULL_RTX,
1270 NULL, after_negate_label, PROB_VERY_LIKELY);
1271 /* Both arguments negative here, negate them and continue with
1272 normal unsigned overflow checking multiplication. */
1273 emit_move_insn (op0, expand_unop (mode, neg_optab, op0,
1275 emit_move_insn (op1, expand_unop (mode, neg_optab, op1,
1277 /* Avoid looking at arg0/arg1 ranges, as we might have changed
1279 arg0 = error_mark_node;
1280 arg1 = error_mark_node;
1281 emit_jump (do_main_label);
1282 emit_label (after_negate_label);
1283 tem2 = expand_binop (mode, xor_optab, op0, op1, NULL_RTX, false,
1285 do_compare_rtx_and_jump (tem2, const0_rtx, GE, false, mode, NULL_RTX,
1286 NULL, do_main_label, PROB_VERY_LIKELY);
1287 /* One argument is negative here, the other positive. This
1288 overflows always, unless one of the arguments is 0. But
1289 if e.g. s2 is 0, (U) s1 * 0 doesn't overflow, whatever s1
1290 is, thus we can keep do_main code oring in overflow as is. */
1291 do_compare_rtx_and_jump (tem, const0_rtx, EQ, true, mode, NULL_RTX,
1292 NULL, do_main_label, PROB_VERY_LIKELY);
1293 expand_arith_set_overflow (lhs, target);
1294 emit_label (do_main_label);
1302 type = build_nonstandard_integer_type (GET_MODE_PRECISION (mode), uns);
1303 sign = uns ? UNSIGNED : SIGNED;
1304 icode = optab_handler (uns ? umulv4_optab : mulv4_optab, mode);
1305 if (icode != CODE_FOR_nothing)
1307 struct expand_operand ops[4];
1308 rtx_insn *last = get_last_insn ();
1310 res = gen_reg_rtx (mode);
1311 create_output_operand (&ops[0], res, mode);
1312 create_input_operand (&ops[1], op0, mode);
1313 create_input_operand (&ops[2], op1, mode);
1314 create_fixed_operand (&ops[3], do_error);
1315 if (maybe_expand_insn (icode, 4, ops))
1317 last = get_last_insn ();
1318 if (profile_status_for_fn (cfun) != PROFILE_ABSENT
1320 && any_condjump_p (last)
1321 && !find_reg_note (last, REG_BR_PROB, 0))
1322 add_int_reg_note (last, REG_BR_PROB, PROB_VERY_UNLIKELY);
1323 emit_jump (done_label);
1327 delete_insns_since (last);
1328 icode = CODE_FOR_nothing;
1332 if (icode == CODE_FOR_nothing)
1334 struct separate_ops ops;
1335 int prec = GET_MODE_PRECISION (mode);
1336 machine_mode hmode = mode_for_size (prec / 2, MODE_INT, 1);
1337 ops.op0 = make_tree (type, op0);
1338 ops.op1 = make_tree (type, op1);
1339 ops.op2 = NULL_TREE;
1341 if (GET_MODE_2XWIDER_MODE (mode) != VOIDmode
1342 && targetm.scalar_mode_supported_p (GET_MODE_2XWIDER_MODE (mode)))
1344 machine_mode wmode = GET_MODE_2XWIDER_MODE (mode);
1345 ops.code = WIDEN_MULT_EXPR;
1347 = build_nonstandard_integer_type (GET_MODE_PRECISION (wmode), uns);
1349 res = expand_expr_real_2 (&ops, NULL_RTX, wmode, EXPAND_NORMAL);
1350 rtx hipart = expand_shift (RSHIFT_EXPR, wmode, res, prec,
1352 hipart = gen_lowpart (mode, hipart);
1353 res = gen_lowpart (mode, res);
1355 /* For the unsigned multiplication, there was overflow if
1356 HIPART is non-zero. */
1357 do_compare_rtx_and_jump (hipart, const0_rtx, EQ, true, mode,
1358 NULL_RTX, NULL, done_label,
1362 rtx signbit = expand_shift (RSHIFT_EXPR, mode, res, prec - 1,
1364 /* RES is low half of the double width result, HIPART
1365 the high half. There was overflow if
1366 HIPART is different from RES < 0 ? -1 : 0. */
1367 do_compare_rtx_and_jump (signbit, hipart, EQ, true, mode,
1368 NULL_RTX, NULL, done_label,
1372 else if (hmode != BLKmode && 2 * GET_MODE_PRECISION (hmode) == prec)
1374 rtx_code_label *large_op0 = gen_label_rtx ();
1375 rtx_code_label *small_op0_large_op1 = gen_label_rtx ();
1376 rtx_code_label *one_small_one_large = gen_label_rtx ();
1377 rtx_code_label *both_ops_large = gen_label_rtx ();
1378 rtx_code_label *after_hipart_neg = uns ? NULL : gen_label_rtx ();
1379 rtx_code_label *after_lopart_neg = uns ? NULL : gen_label_rtx ();
1380 rtx_code_label *do_overflow = gen_label_rtx ();
1381 rtx_code_label *hipart_different = uns ? NULL : gen_label_rtx ();
1383 unsigned int hprec = GET_MODE_PRECISION (hmode);
1384 rtx hipart0 = expand_shift (RSHIFT_EXPR, mode, op0, hprec,
1386 hipart0 = gen_lowpart (hmode, hipart0);
1387 rtx lopart0 = gen_lowpart (hmode, op0);
1388 rtx signbit0 = const0_rtx;
1390 signbit0 = expand_shift (RSHIFT_EXPR, hmode, lopart0, hprec - 1,
1392 rtx hipart1 = expand_shift (RSHIFT_EXPR, mode, op1, hprec,
1394 hipart1 = gen_lowpart (hmode, hipart1);
1395 rtx lopart1 = gen_lowpart (hmode, op1);
1396 rtx signbit1 = const0_rtx;
1398 signbit1 = expand_shift (RSHIFT_EXPR, hmode, lopart1, hprec - 1,
1401 res = gen_reg_rtx (mode);
1403 /* True if op0 resp. op1 are known to be in the range of
1405 bool op0_small_p = false;
1406 bool op1_small_p = false;
1407 /* True if op0 resp. op1 are known to have all zeros or all ones
1408 in the upper half of bits, but are not known to be
1410 bool op0_medium_p = false;
1411 bool op1_medium_p = false;
1412 /* -1 if op{0,1} is known to be negative, 0 if it is known to be
1413 nonnegative, 1 if unknown. */
1419 else if (pos_neg0 == 2)
1423 else if (pos_neg1 == 2)
1426 unsigned int mprec0 = prec;
1427 if (arg0 != error_mark_node)
1428 mprec0 = get_min_precision (arg0, sign);
1429 if (mprec0 <= hprec)
1431 else if (!uns && mprec0 <= hprec + 1)
1432 op0_medium_p = true;
1433 unsigned int mprec1 = prec;
1434 if (arg1 != error_mark_node)
1435 mprec1 = get_min_precision (arg1, sign);
1436 if (mprec1 <= hprec)
1438 else if (!uns && mprec1 <= hprec + 1)
1439 op1_medium_p = true;
1441 int smaller_sign = 1;
1442 int larger_sign = 1;
1445 smaller_sign = op0_sign;
1446 larger_sign = op1_sign;
1448 else if (op1_small_p)
1450 smaller_sign = op1_sign;
1451 larger_sign = op0_sign;
1453 else if (op0_sign == op1_sign)
1455 smaller_sign = op0_sign;
1456 larger_sign = op0_sign;
1460 do_compare_rtx_and_jump (signbit0, hipart0, NE, true, hmode,
1461 NULL_RTX, NULL, large_op0,
1465 do_compare_rtx_and_jump (signbit1, hipart1, NE, true, hmode,
1466 NULL_RTX, NULL, small_op0_large_op1,
1469 /* If both op0 and op1 are sign (!uns) or zero (uns) extended from
1470 hmode to mode, the multiplication will never overflow. We can
1471 do just one hmode x hmode => mode widening multiplication. */
1472 rtx lopart0s = lopart0, lopart1s = lopart1;
1473 if (GET_CODE (lopart0) == SUBREG)
1475 lopart0s = shallow_copy_rtx (lopart0);
1476 SUBREG_PROMOTED_VAR_P (lopart0s) = 1;
1477 SUBREG_PROMOTED_SET (lopart0s, uns ? SRP_UNSIGNED : SRP_SIGNED);
1479 if (GET_CODE (lopart1) == SUBREG)
1481 lopart1s = shallow_copy_rtx (lopart1);
1482 SUBREG_PROMOTED_VAR_P (lopart1s) = 1;
1483 SUBREG_PROMOTED_SET (lopart1s, uns ? SRP_UNSIGNED : SRP_SIGNED);
1485 tree halfstype = build_nonstandard_integer_type (hprec, uns);
1486 ops.op0 = make_tree (halfstype, lopart0s);
1487 ops.op1 = make_tree (halfstype, lopart1s);
1488 ops.code = WIDEN_MULT_EXPR;
1491 = expand_expr_real_2 (&ops, NULL_RTX, mode, EXPAND_NORMAL);
1492 emit_move_insn (res, thisres);
1493 emit_jump (done_label);
1495 emit_label (small_op0_large_op1);
1497 /* If op0 is sign (!uns) or zero (uns) extended from hmode to mode,
1498 but op1 is not, just swap the arguments and handle it as op1
1499 sign/zero extended, op0 not. */
1500 rtx larger = gen_reg_rtx (mode);
1501 rtx hipart = gen_reg_rtx (hmode);
1502 rtx lopart = gen_reg_rtx (hmode);
1503 emit_move_insn (larger, op1);
1504 emit_move_insn (hipart, hipart1);
1505 emit_move_insn (lopart, lopart0);
1506 emit_jump (one_small_one_large);
1508 emit_label (large_op0);
1511 do_compare_rtx_and_jump (signbit1, hipart1, NE, true, hmode,
1512 NULL_RTX, NULL, both_ops_large,
1515 /* If op1 is sign (!uns) or zero (uns) extended from hmode to mode,
1516 but op0 is not, prepare larger, hipart and lopart pseudos and
1517 handle it together with small_op0_large_op1. */
1518 emit_move_insn (larger, op0);
1519 emit_move_insn (hipart, hipart0);
1520 emit_move_insn (lopart, lopart1);
1522 emit_label (one_small_one_large);
1524 /* lopart is the low part of the operand that is sign extended
1525 to mode, larger is the other operand, hipart is the
1526 high part of larger and lopart0 and lopart1 are the low parts
1528 We perform lopart0 * lopart1 and lopart * hipart widening
1530 tree halfutype = build_nonstandard_integer_type (hprec, 1);
1531 ops.op0 = make_tree (halfutype, lopart0);
1532 ops.op1 = make_tree (halfutype, lopart1);
1534 = expand_expr_real_2 (&ops, NULL_RTX, mode, EXPAND_NORMAL);
1536 ops.op0 = make_tree (halfutype, lopart);
1537 ops.op1 = make_tree (halfutype, hipart);
1538 rtx loxhi = gen_reg_rtx (mode);
1539 rtx tem = expand_expr_real_2 (&ops, NULL_RTX, mode, EXPAND_NORMAL);
1540 emit_move_insn (loxhi, tem);
1544 /* if (hipart < 0) loxhi -= lopart << (bitsize / 2); */
1545 if (larger_sign == 0)
1546 emit_jump (after_hipart_neg);
1547 else if (larger_sign != -1)
1548 do_compare_rtx_and_jump (hipart, const0_rtx, GE, false, hmode,
1549 NULL_RTX, NULL, after_hipart_neg,
1552 tem = convert_modes (mode, hmode, lopart, 1);
1553 tem = expand_shift (LSHIFT_EXPR, mode, tem, hprec, NULL_RTX, 1);
1554 tem = expand_simple_binop (mode, MINUS, loxhi, tem, NULL_RTX,
1556 emit_move_insn (loxhi, tem);
1558 emit_label (after_hipart_neg);
1560 /* if (lopart < 0) loxhi -= larger; */
1561 if (smaller_sign == 0)
1562 emit_jump (after_lopart_neg);
1563 else if (smaller_sign != -1)
1564 do_compare_rtx_and_jump (lopart, const0_rtx, GE, false, hmode,
1565 NULL_RTX, NULL, after_lopart_neg,
1568 tem = expand_simple_binop (mode, MINUS, loxhi, larger, NULL_RTX,
1570 emit_move_insn (loxhi, tem);
1572 emit_label (after_lopart_neg);
1575 /* loxhi += (uns) lo0xlo1 >> (bitsize / 2); */
1576 tem = expand_shift (RSHIFT_EXPR, mode, lo0xlo1, hprec, NULL_RTX, 1);
1577 tem = expand_simple_binop (mode, PLUS, loxhi, tem, NULL_RTX,
1579 emit_move_insn (loxhi, tem);
1581 /* if (loxhi >> (bitsize / 2)
1582 == (hmode) loxhi >> (bitsize / 2 - 1)) (if !uns)
1583 if (loxhi >> (bitsize / 2) == 0 (if uns). */
1584 rtx hipartloxhi = expand_shift (RSHIFT_EXPR, mode, loxhi, hprec,
1586 hipartloxhi = gen_lowpart (hmode, hipartloxhi);
1587 rtx signbitloxhi = const0_rtx;
1589 signbitloxhi = expand_shift (RSHIFT_EXPR, hmode,
1590 gen_lowpart (hmode, loxhi),
1591 hprec - 1, NULL_RTX, 0);
1593 do_compare_rtx_and_jump (signbitloxhi, hipartloxhi, NE, true, hmode,
1594 NULL_RTX, NULL, do_overflow,
1595 PROB_VERY_UNLIKELY);
1597 /* res = (loxhi << (bitsize / 2)) | (hmode) lo0xlo1; */
1598 rtx loxhishifted = expand_shift (LSHIFT_EXPR, mode, loxhi, hprec,
1600 tem = convert_modes (mode, hmode, gen_lowpart (hmode, lo0xlo1), 1);
1602 tem = expand_simple_binop (mode, IOR, loxhishifted, tem, res,
1605 emit_move_insn (res, tem);
1606 emit_jump (done_label);
1608 emit_label (both_ops_large);
1610 /* If both operands are large (not sign (!uns) or zero (uns)
1611 extended from hmode), then perform the full multiplication
1612 which will be the result of the operation.
1613 The only cases which don't overflow are for signed multiplication
1614 some cases where both hipart0 and highpart1 are 0 or -1.
1615 For unsigned multiplication when high parts are both non-zero
1616 this overflows always. */
1617 ops.code = MULT_EXPR;
1618 ops.op0 = make_tree (type, op0);
1619 ops.op1 = make_tree (type, op1);
1620 tem = expand_expr_real_2 (&ops, NULL_RTX, mode, EXPAND_NORMAL);
1621 emit_move_insn (res, tem);
1627 tem = expand_simple_binop (hmode, PLUS, hipart0, const1_rtx,
1628 NULL_RTX, 1, OPTAB_DIRECT);
1629 do_compare_rtx_and_jump (tem, const1_rtx, GTU, true, hmode,
1630 NULL_RTX, NULL, do_error,
1631 PROB_VERY_UNLIKELY);
1636 tem = expand_simple_binop (hmode, PLUS, hipart1, const1_rtx,
1637 NULL_RTX, 1, OPTAB_DIRECT);
1638 do_compare_rtx_and_jump (tem, const1_rtx, GTU, true, hmode,
1639 NULL_RTX, NULL, do_error,
1640 PROB_VERY_UNLIKELY);
1643 /* At this point hipart{0,1} are both in [-1, 0]. If they are
1644 the same, overflow happened if res is negative, if they are
1645 different, overflow happened if res is positive. */
1646 if (op0_sign != 1 && op1_sign != 1 && op0_sign != op1_sign)
1647 emit_jump (hipart_different);
1648 else if (op0_sign == 1 || op1_sign == 1)
1649 do_compare_rtx_and_jump (hipart0, hipart1, NE, true, hmode,
1650 NULL_RTX, NULL, hipart_different,
1653 do_compare_rtx_and_jump (res, const0_rtx, LT, false, mode,
1654 NULL_RTX, NULL, do_error,
1655 PROB_VERY_UNLIKELY);
1656 emit_jump (done_label);
1658 emit_label (hipart_different);
1660 do_compare_rtx_and_jump (res, const0_rtx, GE, false, mode,
1661 NULL_RTX, NULL, do_error,
1662 PROB_VERY_UNLIKELY);
1663 emit_jump (done_label);
1666 emit_label (do_overflow);
1668 /* Overflow, do full multiplication and fallthru into do_error. */
1669 ops.op0 = make_tree (type, op0);
1670 ops.op1 = make_tree (type, op1);
1671 tem = expand_expr_real_2 (&ops, NULL_RTX, mode, EXPAND_NORMAL);
1672 emit_move_insn (res, tem);
1676 gcc_assert (!is_ubsan);
1677 ops.code = MULT_EXPR;
1679 res = expand_expr_real_2 (&ops, NULL_RTX, mode, EXPAND_NORMAL);
1680 emit_jump (done_label);
1685 emit_label (do_error);
1688 /* Expand the ubsan builtin call. */
1690 fn = ubsan_build_overflow_builtin (MULT_EXPR, loc, TREE_TYPE (arg0),
1694 do_pending_stack_adjust ();
1697 expand_arith_set_overflow (lhs, target);
1700 emit_label (done_label);
1703 if (uns0_p && uns1_p && !unsr_p)
1705 rtx_code_label *all_done_label = gen_label_rtx ();
1706 do_compare_rtx_and_jump (res, const0_rtx, GE, false, mode, NULL_RTX,
1707 NULL, all_done_label, PROB_VERY_LIKELY);
1708 expand_arith_set_overflow (lhs, target);
1709 emit_label (all_done_label);
1713 if (!uns0_p && uns1_p && !unsr_p && pos_neg1 == 3)
1715 rtx_code_label *all_done_label = gen_label_rtx ();
1716 rtx_code_label *set_noovf = gen_label_rtx ();
1717 do_compare_rtx_and_jump (op1, const0_rtx, GE, false, mode, NULL_RTX,
1718 NULL, all_done_label, PROB_VERY_LIKELY);
1719 expand_arith_set_overflow (lhs, target);
1720 do_compare_rtx_and_jump (op0, const0_rtx, EQ, true, mode, NULL_RTX,
1721 NULL, set_noovf, PROB_VERY_LIKELY);
1722 do_compare_rtx_and_jump (op0, constm1_rtx, NE, true, mode, NULL_RTX,
1723 NULL, all_done_label, PROB_VERY_UNLIKELY);
1724 do_compare_rtx_and_jump (op1, res, NE, true, mode, NULL_RTX, NULL,
1725 all_done_label, PROB_VERY_UNLIKELY);
1726 emit_label (set_noovf);
1727 write_complex_part (target, const0_rtx, true);
1728 emit_label (all_done_label);
1734 expand_ubsan_result_store (target, res);
1736 expand_arith_overflow_result_store (lhs, target, mode, res);
1740 /* Expand UBSAN_CHECK_* internal function if it has vector operands. */
1743 expand_vector_ubsan_overflow (location_t loc, enum tree_code code, tree lhs,
1744 tree arg0, tree arg1)
1746 int cnt = TYPE_VECTOR_SUBPARTS (TREE_TYPE (arg0));
1747 rtx_code_label *loop_lab = NULL;
1748 rtx cntvar = NULL_RTX;
1749 tree cntv = NULL_TREE;
1750 tree eltype = TREE_TYPE (TREE_TYPE (arg0));
1751 tree sz = TYPE_SIZE (eltype);
1752 tree data = NULL_TREE;
1753 tree resv = NULL_TREE;
1754 rtx lhsr = NULL_RTX;
1755 rtx resvr = NULL_RTX;
1760 lhsr = expand_expr (lhs, NULL_RTX, VOIDmode, EXPAND_WRITE);
1761 if (GET_MODE (lhsr) == BLKmode
1762 || (op = optab_for_tree_code (code, TREE_TYPE (arg0),
1763 optab_default)) == unknown_optab
1764 || (optab_handler (op, TYPE_MODE (TREE_TYPE (arg0)))
1765 == CODE_FOR_nothing))
1768 resv = make_tree (TREE_TYPE (lhs), lhsr);
1771 resvr = assign_temp (TREE_TYPE (lhs), 1, 1);
1772 resv = make_tree (TREE_TYPE (lhs), resvr);
1778 do_pending_stack_adjust ();
1779 loop_lab = gen_label_rtx ();
1780 cntvar = gen_reg_rtx (TYPE_MODE (sizetype));
1781 cntv = make_tree (sizetype, cntvar);
1782 emit_move_insn (cntvar, const0_rtx);
1783 emit_label (loop_lab);
1785 if (TREE_CODE (arg0) != VECTOR_CST)
1787 rtx arg0r = expand_normal (arg0);
1788 arg0 = make_tree (TREE_TYPE (arg0), arg0r);
1790 if (TREE_CODE (arg1) != VECTOR_CST)
1792 rtx arg1r = expand_normal (arg1);
1793 arg1 = make_tree (TREE_TYPE (arg1), arg1r);
1795 for (int i = 0; i < (cnt > 4 ? 1 : cnt); i++)
1797 tree op0, op1, res = NULL_TREE;
1800 tree atype = build_array_type_nelts (eltype, cnt);
1801 op0 = fold_build1_loc (loc, VIEW_CONVERT_EXPR, atype, arg0);
1802 op0 = build4_loc (loc, ARRAY_REF, eltype, op0, cntv,
1803 NULL_TREE, NULL_TREE);
1804 op1 = fold_build1_loc (loc, VIEW_CONVERT_EXPR, atype, arg1);
1805 op1 = build4_loc (loc, ARRAY_REF, eltype, op1, cntv,
1806 NULL_TREE, NULL_TREE);
1809 res = fold_build1_loc (loc, VIEW_CONVERT_EXPR, atype, resv);
1810 res = build4_loc (loc, ARRAY_REF, eltype, res, cntv,
1811 NULL_TREE, NULL_TREE);
1816 tree bitpos = bitsize_int (tree_to_uhwi (sz) * i);
1817 op0 = fold_build3_loc (loc, BIT_FIELD_REF, eltype, arg0, sz, bitpos);
1818 op1 = fold_build3_loc (loc, BIT_FIELD_REF, eltype, arg1, sz, bitpos);
1820 res = fold_build3_loc (loc, BIT_FIELD_REF, eltype, resv, sz,
1826 expand_addsub_overflow (loc, PLUS_EXPR, res, op0, op1,
1827 false, false, false, true, &data);
1830 if (cnt > 4 ? integer_zerop (arg0) : integer_zerop (op0))
1831 expand_neg_overflow (loc, res, op1, true, &data);
1833 expand_addsub_overflow (loc, MINUS_EXPR, res, op0, op1,
1834 false, false, false, true, &data);
1837 expand_mul_overflow (loc, res, op0, op1, false, false, false,
1846 struct separate_ops ops;
1847 ops.code = PLUS_EXPR;
1848 ops.type = TREE_TYPE (cntv);
1850 ops.op1 = build_int_cst (TREE_TYPE (cntv), 1);
1851 ops.op2 = NULL_TREE;
1853 rtx ret = expand_expr_real_2 (&ops, cntvar, TYPE_MODE (sizetype),
1856 emit_move_insn (cntvar, ret);
1857 do_compare_rtx_and_jump (cntvar, GEN_INT (cnt), NE, false,
1858 TYPE_MODE (sizetype), NULL_RTX, NULL, loop_lab,
1861 if (lhs && resv == NULL_TREE)
1863 struct separate_ops ops;
1865 ops.type = TREE_TYPE (arg0);
1868 ops.op2 = NULL_TREE;
1870 rtx ret = expand_expr_real_2 (&ops, lhsr, TYPE_MODE (TREE_TYPE (arg0)),
1873 emit_move_insn (lhsr, ret);
1876 emit_move_insn (lhsr, resvr);
1879 /* Expand UBSAN_CHECK_ADD call STMT. */
1882 expand_UBSAN_CHECK_ADD (internal_fn, gcall *stmt)
1884 location_t loc = gimple_location (stmt);
1885 tree lhs = gimple_call_lhs (stmt);
1886 tree arg0 = gimple_call_arg (stmt, 0);
1887 tree arg1 = gimple_call_arg (stmt, 1);
1888 if (VECTOR_TYPE_P (TREE_TYPE (arg0)))
1889 expand_vector_ubsan_overflow (loc, PLUS_EXPR, lhs, arg0, arg1);
1891 expand_addsub_overflow (loc, PLUS_EXPR, lhs, arg0, arg1,
1892 false, false, false, true, NULL);
1895 /* Expand UBSAN_CHECK_SUB call STMT. */
1898 expand_UBSAN_CHECK_SUB (internal_fn, gcall *stmt)
1900 location_t loc = gimple_location (stmt);
1901 tree lhs = gimple_call_lhs (stmt);
1902 tree arg0 = gimple_call_arg (stmt, 0);
1903 tree arg1 = gimple_call_arg (stmt, 1);
1904 if (VECTOR_TYPE_P (TREE_TYPE (arg0)))
1905 expand_vector_ubsan_overflow (loc, MINUS_EXPR, lhs, arg0, arg1);
1906 else if (integer_zerop (arg0))
1907 expand_neg_overflow (loc, lhs, arg1, true, NULL);
1909 expand_addsub_overflow (loc, MINUS_EXPR, lhs, arg0, arg1,
1910 false, false, false, true, NULL);
1913 /* Expand UBSAN_CHECK_MUL call STMT. */
1916 expand_UBSAN_CHECK_MUL (internal_fn, gcall *stmt)
1918 location_t loc = gimple_location (stmt);
1919 tree lhs = gimple_call_lhs (stmt);
1920 tree arg0 = gimple_call_arg (stmt, 0);
1921 tree arg1 = gimple_call_arg (stmt, 1);
1922 if (VECTOR_TYPE_P (TREE_TYPE (arg0)))
1923 expand_vector_ubsan_overflow (loc, MULT_EXPR, lhs, arg0, arg1);
1925 expand_mul_overflow (loc, lhs, arg0, arg1, false, false, false, true,
1929 /* Helper function for {ADD,SUB,MUL}_OVERFLOW call stmt expansion. */
1932 expand_arith_overflow (enum tree_code code, gimple *stmt)
1934 tree lhs = gimple_call_lhs (stmt);
1935 if (lhs == NULL_TREE)
1937 tree arg0 = gimple_call_arg (stmt, 0);
1938 tree arg1 = gimple_call_arg (stmt, 1);
1939 tree type = TREE_TYPE (TREE_TYPE (lhs));
1940 int uns0_p = TYPE_UNSIGNED (TREE_TYPE (arg0));
1941 int uns1_p = TYPE_UNSIGNED (TREE_TYPE (arg1));
1942 int unsr_p = TYPE_UNSIGNED (type);
1943 int prec0 = TYPE_PRECISION (TREE_TYPE (arg0));
1944 int prec1 = TYPE_PRECISION (TREE_TYPE (arg1));
1945 int precres = TYPE_PRECISION (type);
1946 location_t loc = gimple_location (stmt);
1947 if (!uns0_p && get_range_pos_neg (arg0) == 1)
1949 if (!uns1_p && get_range_pos_neg (arg1) == 1)
1951 int pr = get_min_precision (arg0, uns0_p ? UNSIGNED : SIGNED);
1952 prec0 = MIN (prec0, pr);
1953 pr = get_min_precision (arg1, uns1_p ? UNSIGNED : SIGNED);
1954 prec1 = MIN (prec1, pr);
1956 /* If uns0_p && uns1_p, precop is minimum needed precision
1957 of unsigned type to hold the exact result, otherwise
1958 precop is minimum needed precision of signed type to
1959 hold the exact result. */
1961 if (code == MULT_EXPR)
1962 precop = prec0 + prec1 + (uns0_p != uns1_p);
1965 if (uns0_p == uns1_p)
1966 precop = MAX (prec0, prec1) + 1;
1968 precop = MAX (prec0 + 1, prec1) + 1;
1970 precop = MAX (prec0, prec1 + 1) + 1;
1972 int orig_precres = precres;
1976 if ((uns0_p && uns1_p)
1977 ? ((precop + !unsr_p) <= precres
1978 /* u1 - u2 -> ur can overflow, no matter what precision
1980 && (code != MINUS_EXPR || !unsr_p))
1981 : (!unsr_p && precop <= precres))
1983 /* The infinity precision result will always fit into result. */
1984 rtx target = expand_expr (lhs, NULL_RTX, VOIDmode, EXPAND_WRITE);
1985 write_complex_part (target, const0_rtx, true);
1986 enum machine_mode mode = TYPE_MODE (type);
1987 struct separate_ops ops;
1990 ops.op0 = fold_convert_loc (loc, type, arg0);
1991 ops.op1 = fold_convert_loc (loc, type, arg1);
1992 ops.op2 = NULL_TREE;
1994 rtx tem = expand_expr_real_2 (&ops, NULL_RTX, mode, EXPAND_NORMAL);
1995 expand_arith_overflow_result_store (lhs, target, mode, tem);
1999 /* For operations with low precision, if target doesn't have them, start
2000 with precres widening right away, otherwise do it only if the most
2001 simple cases can't be used. */
2002 const int min_precision = targetm.min_arithmetic_precision ();
2003 if (orig_precres == precres && precres < min_precision)
2005 else if ((uns0_p && uns1_p && unsr_p && prec0 <= precres
2006 && prec1 <= precres)
2007 || ((!uns0_p || !uns1_p) && !unsr_p
2008 && prec0 + uns0_p <= precres
2009 && prec1 + uns1_p <= precres))
2011 arg0 = fold_convert_loc (loc, type, arg0);
2012 arg1 = fold_convert_loc (loc, type, arg1);
2016 if (integer_zerop (arg0) && !unsr_p)
2018 expand_neg_overflow (loc, lhs, arg1, false, NULL);
2023 expand_addsub_overflow (loc, code, lhs, arg0, arg1, unsr_p,
2024 unsr_p, unsr_p, false, NULL);
2027 expand_mul_overflow (loc, lhs, arg0, arg1, unsr_p,
2028 unsr_p, unsr_p, false, NULL);
2035 /* For sub-word operations, retry with a wider type first. */
2036 if (orig_precres == precres && precop <= BITS_PER_WORD)
2038 int p = MAX (min_precision, precop);
2039 enum machine_mode m = smallest_mode_for_size (p, MODE_INT);
2040 tree optype = build_nonstandard_integer_type (GET_MODE_PRECISION (m),
2043 p = TYPE_PRECISION (optype);
2047 unsr_p = TYPE_UNSIGNED (optype);
2053 if (prec0 <= precres && prec1 <= precres)
2058 types[0] = build_nonstandard_integer_type (precres, 0);
2064 types[1] = build_nonstandard_integer_type (precres, 1);
2066 arg0 = fold_convert_loc (loc, types[uns0_p], arg0);
2067 arg1 = fold_convert_loc (loc, types[uns1_p], arg1);
2068 if (code != MULT_EXPR)
2069 expand_addsub_overflow (loc, code, lhs, arg0, arg1, unsr_p,
2070 uns0_p, uns1_p, false, NULL);
2072 expand_mul_overflow (loc, lhs, arg0, arg1, unsr_p,
2073 uns0_p, uns1_p, false, NULL);
2077 /* Retry with a wider type. */
2078 if (orig_precres == precres)
2080 int p = MAX (prec0, prec1);
2081 enum machine_mode m = smallest_mode_for_size (p, MODE_INT);
2082 tree optype = build_nonstandard_integer_type (GET_MODE_PRECISION (m),
2085 p = TYPE_PRECISION (optype);
2089 unsr_p = TYPE_UNSIGNED (optype);
2100 /* Expand ADD_OVERFLOW STMT. */
2103 expand_ADD_OVERFLOW (internal_fn, gcall *stmt)
2105 expand_arith_overflow (PLUS_EXPR, stmt);
2108 /* Expand SUB_OVERFLOW STMT. */
2111 expand_SUB_OVERFLOW (internal_fn, gcall *stmt)
2113 expand_arith_overflow (MINUS_EXPR, stmt);
2116 /* Expand MUL_OVERFLOW STMT. */
2119 expand_MUL_OVERFLOW (internal_fn, gcall *stmt)
2121 expand_arith_overflow (MULT_EXPR, stmt);
2124 /* This should get folded in tree-vectorizer.c. */
2127 expand_LOOP_VECTORIZED (internal_fn, gcall *)
2132 /* Expand MASK_LOAD call STMT using optab OPTAB. */
2135 expand_mask_load_optab_fn (internal_fn, gcall *stmt, convert_optab optab)
2137 struct expand_operand ops[3];
2138 tree type, lhs, rhs, maskt, ptr;
2139 rtx mem, target, mask;
2142 maskt = gimple_call_arg (stmt, 2);
2143 lhs = gimple_call_lhs (stmt);
2144 if (lhs == NULL_TREE)
2146 type = TREE_TYPE (lhs);
2147 ptr = build_int_cst (TREE_TYPE (gimple_call_arg (stmt, 1)), 0);
2148 align = tree_to_shwi (gimple_call_arg (stmt, 1));
2149 if (TYPE_ALIGN (type) != align)
2150 type = build_aligned_type (type, align);
2151 rhs = fold_build2 (MEM_REF, type, gimple_call_arg (stmt, 0), ptr);
2153 mem = expand_expr (rhs, NULL_RTX, VOIDmode, EXPAND_WRITE);
2154 gcc_assert (MEM_P (mem));
2155 mask = expand_normal (maskt);
2156 target = expand_expr (lhs, NULL_RTX, VOIDmode, EXPAND_WRITE);
2157 create_output_operand (&ops[0], target, TYPE_MODE (type));
2158 create_fixed_operand (&ops[1], mem);
2159 create_input_operand (&ops[2], mask, TYPE_MODE (TREE_TYPE (maskt)));
2160 expand_insn (convert_optab_handler (optab, TYPE_MODE (type),
2161 TYPE_MODE (TREE_TYPE (maskt))),
2165 /* Expand MASK_STORE call STMT using optab OPTAB. */
2168 expand_mask_store_optab_fn (internal_fn, gcall *stmt, convert_optab optab)
2170 struct expand_operand ops[3];
2171 tree type, lhs, rhs, maskt, ptr;
2175 maskt = gimple_call_arg (stmt, 2);
2176 rhs = gimple_call_arg (stmt, 3);
2177 type = TREE_TYPE (rhs);
2178 ptr = build_int_cst (TREE_TYPE (gimple_call_arg (stmt, 1)), 0);
2179 align = tree_to_shwi (gimple_call_arg (stmt, 1));
2180 if (TYPE_ALIGN (type) != align)
2181 type = build_aligned_type (type, align);
2182 lhs = fold_build2 (MEM_REF, type, gimple_call_arg (stmt, 0), ptr);
2184 mem = expand_expr (lhs, NULL_RTX, VOIDmode, EXPAND_WRITE);
2185 gcc_assert (MEM_P (mem));
2186 mask = expand_normal (maskt);
2187 reg = expand_normal (rhs);
2188 create_fixed_operand (&ops[0], mem);
2189 create_input_operand (&ops[1], reg, TYPE_MODE (type));
2190 create_input_operand (&ops[2], mask, TYPE_MODE (TREE_TYPE (maskt)));
2191 expand_insn (convert_optab_handler (optab, TYPE_MODE (type),
2192 TYPE_MODE (TREE_TYPE (maskt))),
2197 expand_ABNORMAL_DISPATCHER (internal_fn, gcall *)
2202 expand_BUILTIN_EXPECT (internal_fn, gcall *stmt)
2204 /* When guessing was done, the hints should be already stripped away. */
2205 gcc_assert (!flag_guess_branch_prob || optimize == 0 || seen_error ());
2208 tree lhs = gimple_call_lhs (stmt);
2210 target = expand_expr (lhs, NULL_RTX, VOIDmode, EXPAND_WRITE);
2212 target = const0_rtx;
2213 rtx val = expand_expr (gimple_call_arg (stmt, 0), target, VOIDmode, EXPAND_NORMAL);
2214 if (lhs && val != target)
2215 emit_move_insn (target, val);
2218 /* IFN_VA_ARG is supposed to be expanded at pass_stdarg. So this dummy function
2219 should never be called. */
2222 expand_VA_ARG (internal_fn, gcall *)
2227 /* Expand the IFN_UNIQUE function according to its first argument. */
2230 expand_UNIQUE (internal_fn, gcall *stmt)
2232 rtx pattern = NULL_RTX;
2233 enum ifn_unique_kind kind
2234 = (enum ifn_unique_kind) TREE_INT_CST_LOW (gimple_call_arg (stmt, 0));
2241 case IFN_UNIQUE_UNSPEC:
2242 if (targetm.have_unique ())
2243 pattern = targetm.gen_unique ();
2246 case IFN_UNIQUE_OACC_FORK:
2247 case IFN_UNIQUE_OACC_JOIN:
2248 if (targetm.have_oacc_fork () && targetm.have_oacc_join ())
2250 tree lhs = gimple_call_lhs (stmt);
2251 rtx target = const0_rtx;
2254 target = expand_expr (lhs, NULL_RTX, VOIDmode, EXPAND_WRITE);
2256 rtx data_dep = expand_normal (gimple_call_arg (stmt, 1));
2257 rtx axis = expand_normal (gimple_call_arg (stmt, 2));
2259 if (kind == IFN_UNIQUE_OACC_FORK)
2260 pattern = targetm.gen_oacc_fork (target, data_dep, axis);
2262 pattern = targetm.gen_oacc_join (target, data_dep, axis);
2270 emit_insn (pattern);
2273 /* The size of an OpenACC compute dimension. */
2276 expand_GOACC_DIM_SIZE (internal_fn, gcall *stmt)
2278 tree lhs = gimple_call_lhs (stmt);
2283 rtx target = expand_expr (lhs, NULL_RTX, VOIDmode, EXPAND_WRITE);
2284 if (targetm.have_oacc_dim_size ())
2286 rtx dim = expand_expr (gimple_call_arg (stmt, 0), NULL_RTX,
2287 VOIDmode, EXPAND_NORMAL);
2288 emit_insn (targetm.gen_oacc_dim_size (target, dim));
2291 emit_move_insn (target, GEN_INT (1));
2294 /* The position of an OpenACC execution engine along one compute axis. */
2297 expand_GOACC_DIM_POS (internal_fn, gcall *stmt)
2299 tree lhs = gimple_call_lhs (stmt);
2304 rtx target = expand_expr (lhs, NULL_RTX, VOIDmode, EXPAND_WRITE);
2305 if (targetm.have_oacc_dim_pos ())
2307 rtx dim = expand_expr (gimple_call_arg (stmt, 0), NULL_RTX,
2308 VOIDmode, EXPAND_NORMAL);
2309 emit_insn (targetm.gen_oacc_dim_pos (target, dim));
2312 emit_move_insn (target, const0_rtx);
2315 /* This is expanded by oacc_device_lower pass. */
2318 expand_GOACC_LOOP (internal_fn, gcall *)
2323 /* This is expanded by oacc_device_lower pass. */
2326 expand_GOACC_REDUCTION (internal_fn, gcall *)
2331 /* Set errno to EDOM. */
2334 expand_SET_EDOM (internal_fn, gcall *)
2337 #ifdef GEN_ERRNO_RTX
2338 rtx errno_rtx = GEN_ERRNO_RTX;
2340 rtx errno_rtx = gen_rtx_MEM (word_mode, gen_rtx_SYMBOL_REF (Pmode, "errno"));
2342 emit_move_insn (errno_rtx,
2343 gen_int_mode (TARGET_EDOM, GET_MODE (errno_rtx)));
2349 /* Expand atomic bit test and set. */
2352 expand_ATOMIC_BIT_TEST_AND_SET (internal_fn, gcall *call)
2354 expand_ifn_atomic_bit_test_and (call);
2357 /* Expand atomic bit test and complement. */
2360 expand_ATOMIC_BIT_TEST_AND_COMPLEMENT (internal_fn, gcall *call)
2362 expand_ifn_atomic_bit_test_and (call);
2365 /* Expand atomic bit test and reset. */
2368 expand_ATOMIC_BIT_TEST_AND_RESET (internal_fn, gcall *call)
2370 expand_ifn_atomic_bit_test_and (call);
2373 /* Expand atomic bit test and set. */
2376 expand_ATOMIC_COMPARE_EXCHANGE (internal_fn, gcall *call)
2378 expand_ifn_atomic_compare_exchange (call);
2381 /* Expand LAUNDER to assignment, lhs = arg0. */
2384 expand_LAUNDER (internal_fn, gcall *call)
2386 tree lhs = gimple_call_lhs (call);
2391 expand_assignment (lhs, gimple_call_arg (call, 0), false);
2394 /* Expand DIVMOD() using:
2395 a) optab handler for udivmod/sdivmod if it is available.
2396 b) If optab_handler doesn't exist, generate call to
2397 target-specific divmod libfunc. */
2400 expand_DIVMOD (internal_fn, gcall *call_stmt)
2402 tree lhs = gimple_call_lhs (call_stmt);
2403 tree arg0 = gimple_call_arg (call_stmt, 0);
2404 tree arg1 = gimple_call_arg (call_stmt, 1);
2406 gcc_assert (TREE_CODE (TREE_TYPE (lhs)) == COMPLEX_TYPE);
2407 tree type = TREE_TYPE (TREE_TYPE (lhs));
2408 machine_mode mode = TYPE_MODE (type);
2409 bool unsignedp = TYPE_UNSIGNED (type);
2410 optab tab = (unsignedp) ? udivmod_optab : sdivmod_optab;
2412 rtx op0 = expand_normal (arg0);
2413 rtx op1 = expand_normal (arg1);
2414 rtx target = expand_expr (lhs, NULL_RTX, VOIDmode, EXPAND_WRITE);
2416 rtx quotient, remainder, libfunc;
2418 /* Check if optab_handler exists for divmod_optab for given mode. */
2419 if (optab_handler (tab, mode) != CODE_FOR_nothing)
2421 quotient = gen_reg_rtx (mode);
2422 remainder = gen_reg_rtx (mode);
2423 expand_twoval_binop (tab, op0, op1, quotient, remainder, unsignedp);
2426 /* Generate call to divmod libfunc if it exists. */
2427 else if ((libfunc = optab_libfunc (tab, mode)) != NULL_RTX)
2428 targetm.expand_divmod_libfunc (libfunc, mode, op0, op1,
2429 "ient, &remainder);
2434 /* Wrap the return value (quotient, remainder) within COMPLEX_EXPR. */
2435 expand_expr (build2 (COMPLEX_EXPR, TREE_TYPE (lhs),
2436 make_tree (TREE_TYPE (arg0), quotient),
2437 make_tree (TREE_TYPE (arg1), remainder)),
2438 target, VOIDmode, EXPAND_NORMAL);
2441 /* Expand a call to FN using the operands in STMT. FN has a single
2442 output operand and NARGS input operands. */
2445 expand_direct_optab_fn (internal_fn fn, gcall *stmt, direct_optab optab,
2448 expand_operand *ops = XALLOCAVEC (expand_operand, nargs + 1);
2450 tree_pair types = direct_internal_fn_types (fn, stmt);
2451 insn_code icode = direct_optab_handler (optab, TYPE_MODE (types.first));
2453 tree lhs = gimple_call_lhs (stmt);
2454 tree lhs_type = TREE_TYPE (lhs);
2455 rtx lhs_rtx = expand_expr (lhs, NULL_RTX, VOIDmode, EXPAND_WRITE);
2456 create_output_operand (&ops[0], lhs_rtx, insn_data[icode].operand[0].mode);
2458 for (unsigned int i = 0; i < nargs; ++i)
2460 tree rhs = gimple_call_arg (stmt, i);
2461 tree rhs_type = TREE_TYPE (rhs);
2462 rtx rhs_rtx = expand_normal (rhs);
2463 if (INTEGRAL_TYPE_P (rhs_type))
2464 create_convert_operand_from (&ops[i + 1], rhs_rtx,
2465 TYPE_MODE (rhs_type),
2466 TYPE_UNSIGNED (rhs_type));
2468 create_input_operand (&ops[i + 1], rhs_rtx, TYPE_MODE (rhs_type));
2471 expand_insn (icode, nargs + 1, ops);
2472 if (!rtx_equal_p (lhs_rtx, ops[0].value))
2474 /* If the return value has an integral type, convert the instruction
2475 result to that type. This is useful for things that return an
2476 int regardless of the size of the input. If the instruction result
2477 is smaller than required, assume that it is signed.
2479 If the return value has a nonintegral type, its mode must match
2480 the instruction result. */
2481 if (GET_CODE (lhs_rtx) == SUBREG && SUBREG_PROMOTED_VAR_P (lhs_rtx))
2483 /* If this is a scalar in a register that is stored in a wider
2484 mode than the declared mode, compute the result into its
2485 declared mode and then convert to the wider mode. */
2486 gcc_checking_assert (INTEGRAL_TYPE_P (lhs_type));
2487 rtx tmp = convert_to_mode (GET_MODE (lhs_rtx), ops[0].value, 0);
2488 convert_move (SUBREG_REG (lhs_rtx), tmp,
2489 SUBREG_PROMOTED_SIGN (lhs_rtx));
2491 else if (GET_MODE (lhs_rtx) == GET_MODE (ops[0].value))
2492 emit_move_insn (lhs_rtx, ops[0].value);
2495 gcc_checking_assert (INTEGRAL_TYPE_P (lhs_type));
2496 convert_move (lhs_rtx, ops[0].value, 0);
2501 /* Expanders for optabs that can use expand_direct_optab_fn. */
2503 #define expand_unary_optab_fn(FN, STMT, OPTAB) \
2504 expand_direct_optab_fn (FN, STMT, OPTAB, 1)
2506 #define expand_binary_optab_fn(FN, STMT, OPTAB) \
2507 expand_direct_optab_fn (FN, STMT, OPTAB, 2)
2509 /* RETURN_TYPE and ARGS are a return type and argument list that are
2510 in principle compatible with FN (which satisfies direct_internal_fn_p).
2511 Return the types that should be used to determine whether the
2512 target supports FN. */
2515 direct_internal_fn_types (internal_fn fn, tree return_type, tree *args)
2517 const direct_internal_fn_info &info = direct_internal_fn (fn);
2518 tree type0 = (info.type0 < 0 ? return_type : TREE_TYPE (args[info.type0]));
2519 tree type1 = (info.type1 < 0 ? return_type : TREE_TYPE (args[info.type1]));
2520 return tree_pair (type0, type1);
2523 /* CALL is a call whose return type and arguments are in principle
2524 compatible with FN (which satisfies direct_internal_fn_p). Return the
2525 types that should be used to determine whether the target supports FN. */
2528 direct_internal_fn_types (internal_fn fn, gcall *call)
2530 const direct_internal_fn_info &info = direct_internal_fn (fn);
2531 tree op0 = (info.type0 < 0
2532 ? gimple_call_lhs (call)
2533 : gimple_call_arg (call, info.type0));
2534 tree op1 = (info.type1 < 0
2535 ? gimple_call_lhs (call)
2536 : gimple_call_arg (call, info.type1));
2537 return tree_pair (TREE_TYPE (op0), TREE_TYPE (op1));
2540 /* Return true if OPTAB is supported for TYPES (whose modes should be
2541 the same) when the optimization type is OPT_TYPE. Used for simple
2545 direct_optab_supported_p (direct_optab optab, tree_pair types,
2546 optimization_type opt_type)
2548 machine_mode mode = TYPE_MODE (types.first);
2549 gcc_checking_assert (mode == TYPE_MODE (types.second));
2550 return direct_optab_handler (optab, mode, opt_type) != CODE_FOR_nothing;
2553 /* Return true if load/store lanes optab OPTAB is supported for
2554 array type TYPES.first when the optimization type is OPT_TYPE. */
2557 multi_vector_optab_supported_p (convert_optab optab, tree_pair types,
2558 optimization_type opt_type)
2560 gcc_assert (TREE_CODE (types.first) == ARRAY_TYPE);
2561 machine_mode imode = TYPE_MODE (types.first);
2562 machine_mode vmode = TYPE_MODE (TREE_TYPE (types.first));
2563 return (convert_optab_handler (optab, imode, vmode, opt_type)
2564 != CODE_FOR_nothing);
2567 #define direct_unary_optab_supported_p direct_optab_supported_p
2568 #define direct_binary_optab_supported_p direct_optab_supported_p
2569 #define direct_mask_load_optab_supported_p direct_optab_supported_p
2570 #define direct_load_lanes_optab_supported_p multi_vector_optab_supported_p
2571 #define direct_mask_store_optab_supported_p direct_optab_supported_p
2572 #define direct_store_lanes_optab_supported_p multi_vector_optab_supported_p
2574 /* Return true if FN is supported for the types in TYPES when the
2575 optimization type is OPT_TYPE. The types are those associated with
2576 the "type0" and "type1" fields of FN's direct_internal_fn_info
2580 direct_internal_fn_supported_p (internal_fn fn, tree_pair types,
2581 optimization_type opt_type)
2585 #define DEF_INTERNAL_FN(CODE, FLAGS, FNSPEC) \
2586 case IFN_##CODE: break;
2587 #define DEF_INTERNAL_OPTAB_FN(CODE, FLAGS, OPTAB, TYPE) \
2589 return direct_##TYPE##_optab_supported_p (OPTAB##_optab, types, \
2591 #include "internal-fn.def"
2599 /* Return true if FN is supported for type TYPE when the optimization
2600 type is OPT_TYPE. The caller knows that the "type0" and "type1"
2601 fields of FN's direct_internal_fn_info structure are the same. */
2604 direct_internal_fn_supported_p (internal_fn fn, tree type,
2605 optimization_type opt_type)
2607 const direct_internal_fn_info &info = direct_internal_fn (fn);
2608 gcc_checking_assert (info.type0 == info.type1);
2609 return direct_internal_fn_supported_p (fn, tree_pair (type, type), opt_type);
2612 /* Return true if IFN_SET_EDOM is supported. */
2615 set_edom_supported_p (void)
2624 #define DEF_INTERNAL_OPTAB_FN(CODE, FLAGS, OPTAB, TYPE) \
2626 expand_##CODE (internal_fn fn, gcall *stmt) \
2628 expand_##TYPE##_optab_fn (fn, stmt, OPTAB##_optab); \
2630 #include "internal-fn.def"
2632 /* Routines to expand each internal function, indexed by function number.
2633 Each routine has the prototype:
2635 expand_<NAME> (gcall *stmt)
2637 where STMT is the statement that performs the call. */
2638 static void (*const internal_fn_expanders[]) (internal_fn, gcall *) = {
2639 #define DEF_INTERNAL_FN(CODE, FLAGS, FNSPEC) expand_##CODE,
2640 #include "internal-fn.def"
2644 /* Expand STMT as though it were a call to internal function FN. */
2647 expand_internal_call (internal_fn fn, gcall *stmt)
2649 internal_fn_expanders[fn] (fn, stmt);
2652 /* Expand STMT, which is a call to internal function FN. */
2655 expand_internal_call (gcall *stmt)
2657 expand_internal_call (gimple_call_internal_fn (stmt), stmt);
2661 expand_PHI (internal_fn, gcall *)