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"
46 /* The names of each internal function, indexed by function number. */
47 const char *const internal_fn_name_array
[] = {
48 #define DEF_INTERNAL_FN(CODE, FLAGS, FNSPEC) #CODE,
49 #include "internal-fn.def"
53 /* The ECF_* flags of each internal function, indexed by function number. */
54 const int internal_fn_flags_array
[] = {
55 #define DEF_INTERNAL_FN(CODE, FLAGS, FNSPEC) FLAGS,
56 #include "internal-fn.def"
60 /* Fnspec of each internal function, indexed by function number. */
61 const_tree internal_fn_fnspec_array
[IFN_LAST
+ 1];
66 #define DEF_INTERNAL_FN(CODE, FLAGS, FNSPEC) \
67 if (FNSPEC) internal_fn_fnspec_array[IFN_##CODE] = \
68 build_string ((int) sizeof (FNSPEC), FNSPEC ? FNSPEC : "");
69 #include "internal-fn.def"
70 internal_fn_fnspec_array
[IFN_LAST
] = 0;
73 /* Create static initializers for the information returned by
74 direct_internal_fn. */
75 #define not_direct { -2, -2, false }
76 #define mask_load_direct { -1, 2, false }
77 #define load_lanes_direct { -1, -1, false }
78 #define mask_store_direct { 3, 2, false }
79 #define store_lanes_direct { 0, 0, false }
80 #define unary_direct { 0, 0, true }
81 #define binary_direct { 0, 0, true }
83 const direct_internal_fn_info direct_internal_fn_array
[IFN_LAST
+ 1] = {
84 #define DEF_INTERNAL_FN(CODE, FLAGS, FNSPEC) not_direct,
85 #define DEF_INTERNAL_OPTAB_FN(CODE, FLAGS, OPTAB, TYPE) TYPE##_direct,
86 #include "internal-fn.def"
90 /* ARRAY_TYPE is an array of vector modes. Return the associated insn
91 for load-lanes-style optab OPTAB, or CODE_FOR_nothing if none. */
94 get_multi_vector_move (tree array_type
, convert_optab optab
)
99 gcc_assert (TREE_CODE (array_type
) == ARRAY_TYPE
);
100 imode
= TYPE_MODE (array_type
);
101 vmode
= TYPE_MODE (TREE_TYPE (array_type
));
103 return convert_optab_handler (optab
, imode
, vmode
);
106 /* Expand LOAD_LANES call STMT using optab OPTAB. */
109 expand_load_lanes_optab_fn (internal_fn
, gcall
*stmt
, convert_optab optab
)
111 struct expand_operand ops
[2];
115 lhs
= gimple_call_lhs (stmt
);
116 rhs
= gimple_call_arg (stmt
, 0);
117 type
= TREE_TYPE (lhs
);
119 target
= expand_expr (lhs
, NULL_RTX
, VOIDmode
, EXPAND_WRITE
);
120 mem
= expand_normal (rhs
);
122 gcc_assert (MEM_P (mem
));
123 PUT_MODE (mem
, TYPE_MODE (type
));
125 create_output_operand (&ops
[0], target
, TYPE_MODE (type
));
126 create_fixed_operand (&ops
[1], mem
);
127 expand_insn (get_multi_vector_move (type
, optab
), 2, ops
);
130 /* Expand STORE_LANES call STMT using optab OPTAB. */
133 expand_store_lanes_optab_fn (internal_fn
, gcall
*stmt
, convert_optab optab
)
135 struct expand_operand ops
[2];
139 lhs
= gimple_call_lhs (stmt
);
140 rhs
= gimple_call_arg (stmt
, 0);
141 type
= TREE_TYPE (rhs
);
143 target
= expand_expr (lhs
, NULL_RTX
, VOIDmode
, EXPAND_WRITE
);
144 reg
= expand_normal (rhs
);
146 gcc_assert (MEM_P (target
));
147 PUT_MODE (target
, TYPE_MODE (type
));
149 create_fixed_operand (&ops
[0], target
);
150 create_input_operand (&ops
[1], reg
, TYPE_MODE (type
));
151 expand_insn (get_multi_vector_move (type
, optab
), 2, ops
);
155 expand_ANNOTATE (internal_fn
, gcall
*)
160 /* This should get expanded in adjust_simduid_builtins. */
163 expand_GOMP_SIMD_LANE (internal_fn
, gcall
*)
168 /* This should get expanded in adjust_simduid_builtins. */
171 expand_GOMP_SIMD_VF (internal_fn
, gcall
*)
176 /* This should get expanded in adjust_simduid_builtins. */
179 expand_GOMP_SIMD_LAST_LANE (internal_fn
, gcall
*)
184 /* This should get expanded in adjust_simduid_builtins. */
187 expand_GOMP_SIMD_ORDERED_START (internal_fn
, gcall
*)
192 /* This should get expanded in adjust_simduid_builtins. */
195 expand_GOMP_SIMD_ORDERED_END (internal_fn
, gcall
*)
200 /* This should get expanded in the sanopt pass. */
203 expand_UBSAN_NULL (internal_fn
, gcall
*)
208 /* This should get expanded in the sanopt pass. */
211 expand_UBSAN_BOUNDS (internal_fn
, gcall
*)
216 /* This should get expanded in the sanopt pass. */
219 expand_UBSAN_VPTR (internal_fn
, gcall
*)
224 /* This should get expanded in the sanopt pass. */
227 expand_UBSAN_OBJECT_SIZE (internal_fn
, gcall
*)
232 /* This should get expanded in the sanopt pass. */
235 expand_ASAN_CHECK (internal_fn
, gcall
*)
240 /* This should get expanded in the tsan pass. */
243 expand_TSAN_FUNC_EXIT (internal_fn
, gcall
*)
248 /* This should get expanded in the lower pass. */
251 expand_FALLTHROUGH (internal_fn
, gcall
*call
)
253 error_at (gimple_location (call
),
254 "invalid use of attribute %<fallthrough%>");
257 /* Helper function for expand_addsub_overflow. Return 1
258 if ARG interpreted as signed in its precision is known to be always
259 positive or 2 if ARG is known to be always negative, or 3 if ARG may
260 be positive or negative. */
263 get_range_pos_neg (tree arg
)
265 if (arg
== error_mark_node
)
268 int prec
= TYPE_PRECISION (TREE_TYPE (arg
));
270 if (TREE_CODE (arg
) == INTEGER_CST
)
272 wide_int w
= wi::sext (arg
, prec
);
278 while (CONVERT_EXPR_P (arg
)
279 && INTEGRAL_TYPE_P (TREE_TYPE (TREE_OPERAND (arg
, 0)))
280 && TYPE_PRECISION (TREE_TYPE (TREE_OPERAND (arg
, 0))) <= prec
)
282 arg
= TREE_OPERAND (arg
, 0);
283 /* Narrower value zero extended into wider type
284 will always result in positive values. */
285 if (TYPE_UNSIGNED (TREE_TYPE (arg
))
286 && TYPE_PRECISION (TREE_TYPE (arg
)) < prec
)
288 prec
= TYPE_PRECISION (TREE_TYPE (arg
));
293 if (TREE_CODE (arg
) != SSA_NAME
)
295 wide_int arg_min
, arg_max
;
296 while (get_range_info (arg
, &arg_min
, &arg_max
) != VR_RANGE
)
298 gimple
*g
= SSA_NAME_DEF_STMT (arg
);
299 if (is_gimple_assign (g
)
300 && CONVERT_EXPR_CODE_P (gimple_assign_rhs_code (g
)))
302 tree t
= gimple_assign_rhs1 (g
);
303 if (INTEGRAL_TYPE_P (TREE_TYPE (t
))
304 && TYPE_PRECISION (TREE_TYPE (t
)) <= prec
)
306 if (TYPE_UNSIGNED (TREE_TYPE (t
))
307 && TYPE_PRECISION (TREE_TYPE (t
)) < prec
)
309 prec
= TYPE_PRECISION (TREE_TYPE (t
));
318 if (TYPE_UNSIGNED (TREE_TYPE (arg
)))
320 /* For unsigned values, the "positive" range comes
321 below the "negative" range. */
322 if (!wi::neg_p (wi::sext (arg_max
, prec
), SIGNED
))
324 if (wi::neg_p (wi::sext (arg_min
, prec
), SIGNED
))
329 if (!wi::neg_p (wi::sext (arg_min
, prec
), SIGNED
))
331 if (wi::neg_p (wi::sext (arg_max
, prec
), SIGNED
))
337 /* Return minimum precision needed to represent all values
338 of ARG in SIGNed integral type. */
341 get_min_precision (tree arg
, signop sign
)
343 int prec
= TYPE_PRECISION (TREE_TYPE (arg
));
345 signop orig_sign
= sign
;
346 if (TREE_CODE (arg
) == INTEGER_CST
)
349 if (TYPE_SIGN (TREE_TYPE (arg
)) != sign
)
351 widest_int w
= wi::to_widest (arg
);
352 w
= wi::ext (w
, prec
, sign
);
353 p
= wi::min_precision (w
, sign
);
356 p
= wi::min_precision (arg
, sign
);
357 return MIN (p
, prec
);
359 while (CONVERT_EXPR_P (arg
)
360 && INTEGRAL_TYPE_P (TREE_TYPE (TREE_OPERAND (arg
, 0)))
361 && TYPE_PRECISION (TREE_TYPE (TREE_OPERAND (arg
, 0))) <= prec
)
363 arg
= TREE_OPERAND (arg
, 0);
364 if (TYPE_PRECISION (TREE_TYPE (arg
)) < prec
)
366 if (TYPE_UNSIGNED (TREE_TYPE (arg
)))
368 else if (sign
== UNSIGNED
&& get_range_pos_neg (arg
) != 1)
369 return prec
+ (orig_sign
!= sign
);
370 prec
= TYPE_PRECISION (TREE_TYPE (arg
));
373 return prec
+ (orig_sign
!= sign
);
375 if (TREE_CODE (arg
) != SSA_NAME
)
376 return prec
+ (orig_sign
!= sign
);
377 wide_int arg_min
, arg_max
;
378 while (get_range_info (arg
, &arg_min
, &arg_max
) != VR_RANGE
)
380 gimple
*g
= SSA_NAME_DEF_STMT (arg
);
381 if (is_gimple_assign (g
)
382 && CONVERT_EXPR_CODE_P (gimple_assign_rhs_code (g
)))
384 tree t
= gimple_assign_rhs1 (g
);
385 if (INTEGRAL_TYPE_P (TREE_TYPE (t
))
386 && TYPE_PRECISION (TREE_TYPE (t
)) <= prec
)
389 if (TYPE_PRECISION (TREE_TYPE (arg
)) < prec
)
391 if (TYPE_UNSIGNED (TREE_TYPE (arg
)))
393 else if (sign
== UNSIGNED
&& get_range_pos_neg (arg
) != 1)
394 return prec
+ (orig_sign
!= sign
);
395 prec
= TYPE_PRECISION (TREE_TYPE (arg
));
398 return prec
+ (orig_sign
!= sign
);
402 return prec
+ (orig_sign
!= sign
);
404 if (sign
== TYPE_SIGN (TREE_TYPE (arg
)))
406 int p1
= wi::min_precision (arg_min
, sign
);
407 int p2
= wi::min_precision (arg_max
, sign
);
409 prec
= MIN (prec
, p1
);
411 else if (sign
== UNSIGNED
&& !wi::neg_p (arg_min
, SIGNED
))
413 int p
= wi::min_precision (arg_max
, UNSIGNED
);
414 prec
= MIN (prec
, p
);
416 return prec
+ (orig_sign
!= sign
);
419 /* Helper for expand_*_overflow. Set the __imag__ part to true
420 (1 except for signed:1 type, in which case store -1). */
423 expand_arith_set_overflow (tree lhs
, rtx target
)
425 if (TYPE_PRECISION (TREE_TYPE (TREE_TYPE (lhs
))) == 1
426 && !TYPE_UNSIGNED (TREE_TYPE (TREE_TYPE (lhs
))))
427 write_complex_part (target
, constm1_rtx
, true);
429 write_complex_part (target
, const1_rtx
, true);
432 /* Helper for expand_*_overflow. Store RES into the __real__ part
433 of TARGET. If RES has larger MODE than __real__ part of TARGET,
434 set the __imag__ part to 1 if RES doesn't fit into it. Similarly
435 if LHS has smaller precision than its mode. */
438 expand_arith_overflow_result_store (tree lhs
, rtx target
,
439 machine_mode mode
, rtx res
)
441 machine_mode tgtmode
= GET_MODE_INNER (GET_MODE (target
));
445 rtx_code_label
*done_label
= gen_label_rtx ();
446 int uns
= TYPE_UNSIGNED (TREE_TYPE (TREE_TYPE (lhs
)));
447 lres
= convert_modes (tgtmode
, mode
, res
, uns
);
448 gcc_assert (GET_MODE_PRECISION (tgtmode
) < GET_MODE_PRECISION (mode
));
449 do_compare_rtx_and_jump (res
, convert_modes (mode
, tgtmode
, lres
, uns
),
450 EQ
, true, mode
, NULL_RTX
, NULL
, done_label
,
452 expand_arith_set_overflow (lhs
, target
);
453 emit_label (done_label
);
455 int prec
= TYPE_PRECISION (TREE_TYPE (TREE_TYPE (lhs
)));
456 int tgtprec
= GET_MODE_PRECISION (tgtmode
);
459 rtx_code_label
*done_label
= gen_label_rtx ();
460 int uns
= TYPE_UNSIGNED (TREE_TYPE (TREE_TYPE (lhs
)));
465 = immed_wide_int_const (wi::shifted_mask (0, prec
, false, tgtprec
),
467 lres
= expand_simple_binop (tgtmode
, AND
, res
, mask
, NULL_RTX
,
468 true, OPTAB_LIB_WIDEN
);
472 lres
= expand_shift (LSHIFT_EXPR
, tgtmode
, res
, tgtprec
- prec
,
474 lres
= expand_shift (RSHIFT_EXPR
, tgtmode
, lres
, tgtprec
- prec
,
477 do_compare_rtx_and_jump (res
, lres
,
478 EQ
, true, tgtmode
, NULL_RTX
, NULL
, done_label
,
480 expand_arith_set_overflow (lhs
, target
);
481 emit_label (done_label
);
483 write_complex_part (target
, lres
, false);
486 /* Helper for expand_*_overflow. Store RES into TARGET. */
489 expand_ubsan_result_store (rtx target
, rtx res
)
491 if (GET_CODE (target
) == SUBREG
&& SUBREG_PROMOTED_VAR_P (target
))
492 /* If this is a scalar in a register that is stored in a wider mode
493 than the declared mode, compute the result into its declared mode
494 and then convert to the wider mode. Our value is the computed
496 convert_move (SUBREG_REG (target
), res
, SUBREG_PROMOTED_SIGN (target
));
498 emit_move_insn (target
, res
);
501 /* Add sub/add overflow checking to the statement STMT.
502 CODE says whether the operation is +, or -. */
505 expand_addsub_overflow (location_t loc
, tree_code code
, tree lhs
,
506 tree arg0
, tree arg1
, bool unsr_p
, bool uns0_p
,
507 bool uns1_p
, bool is_ubsan
)
509 rtx res
, target
= NULL_RTX
;
511 rtx_code_label
*done_label
= gen_label_rtx ();
512 rtx_code_label
*do_error
= gen_label_rtx ();
513 do_pending_stack_adjust ();
514 rtx op0
= expand_normal (arg0
);
515 rtx op1
= expand_normal (arg1
);
516 machine_mode mode
= TYPE_MODE (TREE_TYPE (arg0
));
517 int prec
= GET_MODE_PRECISION (mode
);
518 rtx sgn
= immed_wide_int_const (wi::min_value (prec
, SIGNED
), mode
);
522 gcc_assert (!unsr_p
&& !uns0_p
&& !uns1_p
);
526 target
= expand_expr (lhs
, NULL_RTX
, VOIDmode
, EXPAND_WRITE
);
528 write_complex_part (target
, const0_rtx
, true);
531 /* We assume both operands and result have the same precision
532 here (GET_MODE_BITSIZE (mode)), S stands for signed type
533 with that precision, U for unsigned type with that precision,
534 sgn for unsigned most significant bit in that precision.
535 s1 is signed first operand, u1 is unsigned first operand,
536 s2 is signed second operand, u2 is unsigned second operand,
537 sr is signed result, ur is unsigned result and the following
538 rules say how to compute result (which is always result of
539 the operands as if both were unsigned, cast to the right
540 signedness) and how to compute whether operation overflowed.
543 res = (S) ((U) s1 + (U) s2)
544 ovf = s2 < 0 ? res > s1 : res < s1 (or jump on overflow)
546 res = (S) ((U) s1 - (U) s2)
547 ovf = s2 < 0 ? res < s1 : res > s2 (or jump on overflow)
550 ovf = res < u1 (or jump on carry, but RTL opts will handle it)
553 ovf = res > u1 (or jump on carry, but RTL opts will handle it)
555 res = (S) ((U) s1 + u2)
556 ovf = ((U) res ^ sgn) < u2
561 ovf = t1 < 0 ? t2 > s1 : t2 < s1 (or jump on overflow)
563 res = (S) ((U) s1 - u2)
564 ovf = u2 > ((U) s1 ^ sgn)
567 ovf = s1 < 0 || u2 > (U) s1
570 ovf = u1 >= ((U) s2 ^ sgn)
575 ovf = s2 < 0 ? (S) t2 < (S) t1 : (S) t2 > (S) t1 (or jump on overflow)
577 res = (U) s1 + (U) s2
578 ovf = s2 < 0 ? (s1 | (S) res) < 0) : (s1 & (S) res) < 0)
581 ovf = (U) res < u2 || res < 0
584 ovf = u1 >= u2 ? res < 0 : res >= 0
586 res = (U) s1 - (U) s2
587 ovf = s2 >= 0 ? ((s1 | (S) res) < 0) : ((s1 & (S) res) < 0) */
589 if (code
== PLUS_EXPR
&& uns0_p
&& !uns1_p
)
591 /* PLUS_EXPR is commutative, if operand signedness differs,
592 canonicalize to the first operand being signed and second
593 unsigned to simplify following code. */
594 std::swap (op0
, op1
);
595 std::swap (arg0
, arg1
);
601 if (uns0_p
&& uns1_p
&& unsr_p
)
603 insn_code icode
= optab_handler (code
== PLUS_EXPR
? uaddv4_optab
604 : usubv4_optab
, mode
);
605 if (icode
!= CODE_FOR_nothing
)
607 struct expand_operand ops
[4];
608 rtx_insn
*last
= get_last_insn ();
610 res
= gen_reg_rtx (mode
);
611 create_output_operand (&ops
[0], res
, mode
);
612 create_input_operand (&ops
[1], op0
, mode
);
613 create_input_operand (&ops
[2], op1
, mode
);
614 create_fixed_operand (&ops
[3], do_error
);
615 if (maybe_expand_insn (icode
, 4, ops
))
617 last
= get_last_insn ();
618 if (profile_status_for_fn (cfun
) != PROFILE_ABSENT
620 && any_condjump_p (last
)
621 && !find_reg_note (last
, REG_BR_PROB
, 0))
622 add_int_reg_note (last
, REG_BR_PROB
, PROB_VERY_UNLIKELY
);
623 emit_jump (done_label
);
627 delete_insns_since (last
);
630 /* Compute the operation. On RTL level, the addition is always
632 res
= expand_binop (mode
, code
== PLUS_EXPR
? add_optab
: sub_optab
,
633 op0
, op1
, NULL_RTX
, false, OPTAB_LIB_WIDEN
);
635 /* For PLUS_EXPR, the operation is commutative, so we can pick
636 operand to compare against. For prec <= BITS_PER_WORD, I think
637 preferring REG operand is better over CONST_INT, because
638 the CONST_INT might enlarge the instruction or CSE would need
639 to figure out we'd already loaded it into a register before.
640 For prec > BITS_PER_WORD, I think CONST_INT might be more beneficial,
641 as then the multi-word comparison can be perhaps simplified. */
642 if (code
== PLUS_EXPR
643 && (prec
<= BITS_PER_WORD
644 ? (CONST_SCALAR_INT_P (op0
) && REG_P (op1
))
645 : CONST_SCALAR_INT_P (op1
)))
647 do_compare_rtx_and_jump (res
, tem
, code
== PLUS_EXPR
? GEU
: LEU
,
648 true, mode
, NULL_RTX
, NULL
, done_label
,
654 if (!uns0_p
&& uns1_p
&& !unsr_p
)
656 /* Compute the operation. On RTL level, the addition is always
658 res
= expand_binop (mode
, code
== PLUS_EXPR
? add_optab
: sub_optab
,
659 op0
, op1
, NULL_RTX
, false, OPTAB_LIB_WIDEN
);
660 rtx tem
= expand_binop (mode
, add_optab
,
661 code
== PLUS_EXPR
? res
: op0
, sgn
,
662 NULL_RTX
, false, OPTAB_LIB_WIDEN
);
663 do_compare_rtx_and_jump (tem
, op1
, GEU
, true, mode
, NULL_RTX
, NULL
,
664 done_label
, PROB_VERY_LIKELY
);
669 if (code
== PLUS_EXPR
&& !uns0_p
&& uns1_p
&& unsr_p
)
671 op1
= expand_binop (mode
, add_optab
, op1
, sgn
, NULL_RTX
, false,
673 /* As we've changed op1, we have to avoid using the value range
674 for the original argument. */
675 arg1
= error_mark_node
;
681 if (code
== MINUS_EXPR
&& uns0_p
&& !uns1_p
&& unsr_p
)
683 op0
= expand_binop (mode
, add_optab
, op0
, sgn
, NULL_RTX
, false,
685 /* As we've changed op0, we have to avoid using the value range
686 for the original argument. */
687 arg0
= error_mark_node
;
693 if (code
== MINUS_EXPR
&& !uns0_p
&& uns1_p
&& unsr_p
)
695 /* Compute the operation. On RTL level, the addition is always
697 res
= expand_binop (mode
, sub_optab
, op0
, op1
, NULL_RTX
, false,
699 int pos_neg
= get_range_pos_neg (arg0
);
701 /* If ARG0 is known to be always negative, this is always overflow. */
702 emit_jump (do_error
);
703 else if (pos_neg
== 3)
704 /* If ARG0 is not known to be always positive, check at runtime. */
705 do_compare_rtx_and_jump (op0
, const0_rtx
, LT
, false, mode
, NULL_RTX
,
706 NULL
, do_error
, PROB_VERY_UNLIKELY
);
707 do_compare_rtx_and_jump (op1
, op0
, LEU
, true, mode
, NULL_RTX
, NULL
,
708 done_label
, PROB_VERY_LIKELY
);
713 if (code
== MINUS_EXPR
&& uns0_p
&& !uns1_p
&& !unsr_p
)
715 /* Compute the operation. On RTL level, the addition is always
717 res
= expand_binop (mode
, sub_optab
, op0
, op1
, NULL_RTX
, false,
719 rtx tem
= expand_binop (mode
, add_optab
, op1
, sgn
, NULL_RTX
, false,
721 do_compare_rtx_and_jump (op0
, tem
, LTU
, true, mode
, NULL_RTX
, NULL
,
722 done_label
, PROB_VERY_LIKELY
);
727 if (code
== PLUS_EXPR
&& uns0_p
&& uns1_p
&& !unsr_p
)
729 /* Compute the operation. On RTL level, the addition is always
731 res
= expand_binop (mode
, add_optab
, op0
, op1
, NULL_RTX
, false,
733 do_compare_rtx_and_jump (res
, const0_rtx
, LT
, false, mode
, NULL_RTX
,
734 NULL
, do_error
, PROB_VERY_UNLIKELY
);
736 /* The operation is commutative, so we can pick operand to compare
737 against. For prec <= BITS_PER_WORD, I think preferring REG operand
738 is better over CONST_INT, because the CONST_INT might enlarge the
739 instruction or CSE would need to figure out we'd already loaded it
740 into a register before. For prec > BITS_PER_WORD, I think CONST_INT
741 might be more beneficial, as then the multi-word comparison can be
742 perhaps simplified. */
743 if (prec
<= BITS_PER_WORD
744 ? (CONST_SCALAR_INT_P (op1
) && REG_P (op0
))
745 : CONST_SCALAR_INT_P (op0
))
747 do_compare_rtx_and_jump (res
, tem
, GEU
, true, mode
, NULL_RTX
, NULL
,
748 done_label
, PROB_VERY_LIKELY
);
753 if (!uns0_p
&& !uns1_p
&& unsr_p
)
755 /* Compute the operation. On RTL level, the addition is always
757 res
= expand_binop (mode
, code
== PLUS_EXPR
? add_optab
: sub_optab
,
758 op0
, op1
, NULL_RTX
, false, OPTAB_LIB_WIDEN
);
759 int pos_neg
= get_range_pos_neg (arg1
);
760 if (code
== PLUS_EXPR
)
762 int pos_neg0
= get_range_pos_neg (arg0
);
763 if (pos_neg0
!= 3 && pos_neg
== 3)
765 std::swap (op0
, op1
);
772 tem
= expand_binop (mode
, ((pos_neg
== 1) ^ (code
== MINUS_EXPR
))
773 ? and_optab
: ior_optab
,
774 op0
, res
, NULL_RTX
, false, OPTAB_LIB_WIDEN
);
775 do_compare_rtx_and_jump (tem
, const0_rtx
, GE
, false, mode
, NULL
,
776 NULL
, done_label
, PROB_VERY_LIKELY
);
780 rtx_code_label
*do_ior_label
= gen_label_rtx ();
781 do_compare_rtx_and_jump (op1
, const0_rtx
,
782 code
== MINUS_EXPR
? GE
: LT
, false, mode
,
783 NULL_RTX
, NULL
, do_ior_label
,
785 tem
= expand_binop (mode
, and_optab
, op0
, res
, NULL_RTX
, false,
787 do_compare_rtx_and_jump (tem
, const0_rtx
, GE
, false, mode
, NULL_RTX
,
788 NULL
, done_label
, PROB_VERY_LIKELY
);
789 emit_jump (do_error
);
790 emit_label (do_ior_label
);
791 tem
= expand_binop (mode
, ior_optab
, op0
, res
, NULL_RTX
, false,
793 do_compare_rtx_and_jump (tem
, const0_rtx
, GE
, false, mode
, NULL_RTX
,
794 NULL
, done_label
, PROB_VERY_LIKELY
);
800 if (code
== MINUS_EXPR
&& uns0_p
&& uns1_p
&& !unsr_p
)
802 /* Compute the operation. On RTL level, the addition is always
804 res
= expand_binop (mode
, sub_optab
, op0
, op1
, NULL_RTX
, false,
806 rtx_code_label
*op0_geu_op1
= gen_label_rtx ();
807 do_compare_rtx_and_jump (op0
, op1
, GEU
, true, mode
, NULL_RTX
, NULL
,
808 op0_geu_op1
, PROB_EVEN
);
809 do_compare_rtx_and_jump (res
, const0_rtx
, LT
, false, mode
, NULL_RTX
,
810 NULL
, done_label
, PROB_VERY_LIKELY
);
811 emit_jump (do_error
);
812 emit_label (op0_geu_op1
);
813 do_compare_rtx_and_jump (res
, const0_rtx
, GE
, false, mode
, NULL_RTX
,
814 NULL
, done_label
, PROB_VERY_LIKELY
);
818 gcc_assert (!uns0_p
&& !uns1_p
&& !unsr_p
);
823 insn_code icode
= optab_handler (code
== PLUS_EXPR
? addv4_optab
824 : subv4_optab
, mode
);
825 if (icode
!= CODE_FOR_nothing
)
827 struct expand_operand ops
[4];
828 rtx_insn
*last
= get_last_insn ();
830 res
= gen_reg_rtx (mode
);
831 create_output_operand (&ops
[0], res
, mode
);
832 create_input_operand (&ops
[1], op0
, mode
);
833 create_input_operand (&ops
[2], op1
, mode
);
834 create_fixed_operand (&ops
[3], do_error
);
835 if (maybe_expand_insn (icode
, 4, ops
))
837 last
= get_last_insn ();
838 if (profile_status_for_fn (cfun
) != PROFILE_ABSENT
840 && any_condjump_p (last
)
841 && !find_reg_note (last
, REG_BR_PROB
, 0))
842 add_int_reg_note (last
, REG_BR_PROB
, PROB_VERY_UNLIKELY
);
843 emit_jump (done_label
);
847 delete_insns_since (last
);
850 rtx_code_label
*sub_check
= gen_label_rtx ();
853 /* Compute the operation. On RTL level, the addition is always
855 res
= expand_binop (mode
, code
== PLUS_EXPR
? add_optab
: sub_optab
,
856 op0
, op1
, NULL_RTX
, false, OPTAB_LIB_WIDEN
);
858 /* If we can prove one of the arguments (for MINUS_EXPR only
859 the second operand, as subtraction is not commutative) is always
860 non-negative or always negative, we can do just one comparison
861 and conditional jump instead of 2 at runtime, 3 present in the
862 emitted code. If one of the arguments is CONST_INT, all we
863 need is to make sure it is op1, then the first
864 do_compare_rtx_and_jump will be just folded. Otherwise try
865 to use range info if available. */
866 if (code
== PLUS_EXPR
&& CONST_INT_P (op0
))
867 std::swap (op0
, op1
);
868 else if (CONST_INT_P (op1
))
870 else if (code
== PLUS_EXPR
&& TREE_CODE (arg0
) == SSA_NAME
)
872 pos_neg
= get_range_pos_neg (arg0
);
874 std::swap (op0
, op1
);
876 if (pos_neg
== 3 && !CONST_INT_P (op1
) && TREE_CODE (arg1
) == SSA_NAME
)
877 pos_neg
= get_range_pos_neg (arg1
);
879 /* If the op1 is negative, we have to use a different check. */
881 do_compare_rtx_and_jump (op1
, const0_rtx
, LT
, false, mode
, NULL_RTX
,
882 NULL
, sub_check
, PROB_EVEN
);
884 /* Compare the result of the operation with one of the operands. */
886 do_compare_rtx_and_jump (res
, op0
, code
== PLUS_EXPR
? GE
: LE
,
887 false, mode
, NULL_RTX
, NULL
, done_label
,
890 /* If we get here, we have to print the error. */
893 emit_jump (do_error
);
894 emit_label (sub_check
);
897 /* We have k = a + b for b < 0 here. k <= a must hold. */
899 do_compare_rtx_and_jump (res
, op0
, code
== PLUS_EXPR
? LE
: GE
,
900 false, mode
, NULL_RTX
, NULL
, done_label
,
905 emit_label (do_error
);
908 /* Expand the ubsan builtin call. */
910 fn
= ubsan_build_overflow_builtin (code
, loc
, TREE_TYPE (arg0
),
914 do_pending_stack_adjust ();
917 expand_arith_set_overflow (lhs
, target
);
920 emit_label (done_label
);
925 expand_ubsan_result_store (target
, res
);
929 res
= expand_binop (mode
, add_optab
, res
, sgn
, NULL_RTX
, false,
932 expand_arith_overflow_result_store (lhs
, target
, mode
, res
);
937 /* Add negate overflow checking to the statement STMT. */
940 expand_neg_overflow (location_t loc
, tree lhs
, tree arg1
, bool is_ubsan
)
944 rtx_code_label
*done_label
, *do_error
;
945 rtx target
= NULL_RTX
;
947 done_label
= gen_label_rtx ();
948 do_error
= gen_label_rtx ();
950 do_pending_stack_adjust ();
951 op1
= expand_normal (arg1
);
953 machine_mode mode
= TYPE_MODE (TREE_TYPE (arg1
));
956 target
= expand_expr (lhs
, NULL_RTX
, VOIDmode
, EXPAND_WRITE
);
958 write_complex_part (target
, const0_rtx
, true);
961 enum insn_code icode
= optab_handler (negv3_optab
, mode
);
962 if (icode
!= CODE_FOR_nothing
)
964 struct expand_operand ops
[3];
965 rtx_insn
*last
= get_last_insn ();
967 res
= gen_reg_rtx (mode
);
968 create_output_operand (&ops
[0], res
, mode
);
969 create_input_operand (&ops
[1], op1
, mode
);
970 create_fixed_operand (&ops
[2], do_error
);
971 if (maybe_expand_insn (icode
, 3, ops
))
973 last
= get_last_insn ();
974 if (profile_status_for_fn (cfun
) != PROFILE_ABSENT
976 && any_condjump_p (last
)
977 && !find_reg_note (last
, REG_BR_PROB
, 0))
978 add_int_reg_note (last
, REG_BR_PROB
, PROB_VERY_UNLIKELY
);
979 emit_jump (done_label
);
983 delete_insns_since (last
);
984 icode
= CODE_FOR_nothing
;
988 if (icode
== CODE_FOR_nothing
)
990 /* Compute the operation. On RTL level, the addition is always
992 res
= expand_unop (mode
, neg_optab
, op1
, NULL_RTX
, false);
994 /* Compare the operand with the most negative value. */
995 rtx minv
= expand_normal (TYPE_MIN_VALUE (TREE_TYPE (arg1
)));
996 do_compare_rtx_and_jump (op1
, minv
, NE
, true, mode
, NULL_RTX
, NULL
,
997 done_label
, PROB_VERY_LIKELY
);
1000 emit_label (do_error
);
1003 /* Expand the ubsan builtin call. */
1005 fn
= ubsan_build_overflow_builtin (NEGATE_EXPR
, loc
, TREE_TYPE (arg1
),
1009 do_pending_stack_adjust ();
1012 expand_arith_set_overflow (lhs
, target
);
1015 emit_label (done_label
);
1020 expand_ubsan_result_store (target
, res
);
1022 expand_arith_overflow_result_store (lhs
, target
, mode
, res
);
1026 /* Add mul overflow checking to the statement STMT. */
1029 expand_mul_overflow (location_t loc
, tree lhs
, tree arg0
, tree arg1
,
1030 bool unsr_p
, bool uns0_p
, bool uns1_p
, bool is_ubsan
)
1034 rtx_code_label
*done_label
, *do_error
;
1035 rtx target
= NULL_RTX
;
1037 enum insn_code icode
;
1039 done_label
= gen_label_rtx ();
1040 do_error
= gen_label_rtx ();
1042 do_pending_stack_adjust ();
1043 op0
= expand_normal (arg0
);
1044 op1
= expand_normal (arg1
);
1046 machine_mode mode
= TYPE_MODE (TREE_TYPE (arg0
));
1050 target
= expand_expr (lhs
, NULL_RTX
, VOIDmode
, EXPAND_WRITE
);
1052 write_complex_part (target
, const0_rtx
, true);
1056 gcc_assert (!unsr_p
&& !uns0_p
&& !uns1_p
);
1058 /* We assume both operands and result have the same precision
1059 here (GET_MODE_BITSIZE (mode)), S stands for signed type
1060 with that precision, U for unsigned type with that precision,
1061 sgn for unsigned most significant bit in that precision.
1062 s1 is signed first operand, u1 is unsigned first operand,
1063 s2 is signed second operand, u2 is unsigned second operand,
1064 sr is signed result, ur is unsigned result and the following
1065 rules say how to compute result (which is always result of
1066 the operands as if both were unsigned, cast to the right
1067 signedness) and how to compute whether operation overflowed.
1068 main_ovf (false) stands for jump on signed multiplication
1069 overflow or the main algorithm with uns == false.
1070 main_ovf (true) stands for jump on unsigned multiplication
1071 overflow or the main algorithm with uns == true.
1074 res = (S) ((U) s1 * (U) s2)
1075 ovf = main_ovf (false)
1078 ovf = main_ovf (true)
1081 ovf = (s1 < 0 && u2) || main_ovf (true)
1084 ovf = res < 0 || main_ovf (true)
1086 res = (S) ((U) s1 * u2)
1087 ovf = (S) u2 >= 0 ? main_ovf (false)
1088 : (s1 != 0 && (s1 != -1 || u2 != (U) res))
1090 t1 = (s1 & s2) < 0 ? (-(U) s1) : ((U) s1)
1091 t2 = (s1 & s2) < 0 ? (-(U) s2) : ((U) s2)
1093 ovf = (s1 ^ s2) < 0 ? (s1 && s2) : main_ovf (true) */
1095 if (uns0_p
&& !uns1_p
)
1097 /* Multiplication is commutative, if operand signedness differs,
1098 canonicalize to the first operand being signed and second
1099 unsigned to simplify following code. */
1100 std::swap (op0
, op1
);
1101 std::swap (arg0
, arg1
);
1106 int pos_neg0
= get_range_pos_neg (arg0
);
1107 int pos_neg1
= get_range_pos_neg (arg1
);
1110 if (!uns0_p
&& uns1_p
&& unsr_p
)
1115 /* If s1 is non-negative, just perform normal u1 * u2 -> ur. */
1118 /* If s1 is negative, avoid the main code, just multiply and
1119 signal overflow if op1 is not 0. */
1120 struct separate_ops ops
;
1121 ops
.code
= MULT_EXPR
;
1122 ops
.type
= TREE_TYPE (arg1
);
1123 ops
.op0
= make_tree (ops
.type
, op0
);
1124 ops
.op1
= make_tree (ops
.type
, op1
);
1125 ops
.op2
= NULL_TREE
;
1127 res
= expand_expr_real_2 (&ops
, NULL_RTX
, mode
, EXPAND_NORMAL
);
1128 do_compare_rtx_and_jump (op1
, const0_rtx
, EQ
, true, mode
, NULL_RTX
,
1129 NULL
, done_label
, PROB_VERY_LIKELY
);
1130 goto do_error_label
;
1132 rtx_code_label
*do_main_label
;
1133 do_main_label
= gen_label_rtx ();
1134 do_compare_rtx_and_jump (op0
, const0_rtx
, GE
, false, mode
, NULL_RTX
,
1135 NULL
, do_main_label
, PROB_VERY_LIKELY
);
1136 do_compare_rtx_and_jump (op1
, const0_rtx
, EQ
, true, mode
, NULL_RTX
,
1137 NULL
, do_main_label
, PROB_VERY_LIKELY
);
1138 expand_arith_set_overflow (lhs
, target
);
1139 emit_label (do_main_label
);
1147 if (uns0_p
&& uns1_p
&& !unsr_p
)
1150 /* Rest of handling of this case after res is computed. */
1155 if (!uns0_p
&& uns1_p
&& !unsr_p
)
1162 /* If (S) u2 is negative (i.e. u2 is larger than maximum of S,
1163 avoid the main code, just multiply and signal overflow
1164 unless 0 * u2 or -1 * ((U) Smin). */
1165 struct separate_ops ops
;
1166 ops
.code
= MULT_EXPR
;
1167 ops
.type
= TREE_TYPE (arg1
);
1168 ops
.op0
= make_tree (ops
.type
, op0
);
1169 ops
.op1
= make_tree (ops
.type
, op1
);
1170 ops
.op2
= NULL_TREE
;
1172 res
= expand_expr_real_2 (&ops
, NULL_RTX
, mode
, EXPAND_NORMAL
);
1173 do_compare_rtx_and_jump (op0
, const0_rtx
, EQ
, true, mode
, NULL_RTX
,
1174 NULL
, done_label
, PROB_VERY_LIKELY
);
1175 do_compare_rtx_and_jump (op0
, constm1_rtx
, NE
, true, mode
, NULL_RTX
,
1176 NULL
, do_error
, PROB_VERY_UNLIKELY
);
1178 prec
= GET_MODE_PRECISION (mode
);
1180 sgn
= immed_wide_int_const (wi::min_value (prec
, SIGNED
), mode
);
1181 do_compare_rtx_and_jump (op1
, sgn
, EQ
, true, mode
, NULL_RTX
,
1182 NULL
, done_label
, PROB_VERY_LIKELY
);
1183 goto do_error_label
;
1185 /* Rest of handling of this case after res is computed. */
1193 if (!uns0_p
&& !uns1_p
&& unsr_p
)
1196 switch (pos_neg0
| pos_neg1
)
1198 case 1: /* Both operands known to be non-negative. */
1200 case 2: /* Both operands known to be negative. */
1201 op0
= expand_unop (mode
, neg_optab
, op0
, NULL_RTX
, false);
1202 op1
= expand_unop (mode
, neg_optab
, op1
, NULL_RTX
, false);
1203 /* Avoid looking at arg0/arg1 ranges, as we've changed
1205 arg0
= error_mark_node
;
1206 arg1
= error_mark_node
;
1209 if ((pos_neg0
^ pos_neg1
) == 3)
1211 /* If one operand is known to be negative and the other
1212 non-negative, this overflows always, unless the non-negative
1213 one is 0. Just do normal multiply and set overflow
1214 unless one of the operands is 0. */
1215 struct separate_ops ops
;
1216 ops
.code
= MULT_EXPR
;
1218 = build_nonstandard_integer_type (GET_MODE_PRECISION (mode
),
1220 ops
.op0
= make_tree (ops
.type
, op0
);
1221 ops
.op1
= make_tree (ops
.type
, op1
);
1222 ops
.op2
= NULL_TREE
;
1224 res
= expand_expr_real_2 (&ops
, NULL_RTX
, mode
, EXPAND_NORMAL
);
1225 tem
= expand_binop (mode
, and_optab
, op0
, op1
, NULL_RTX
, false,
1227 do_compare_rtx_and_jump (tem
, const0_rtx
, EQ
, true, mode
,
1228 NULL_RTX
, NULL
, done_label
,
1230 goto do_error_label
;
1232 /* The general case, do all the needed comparisons at runtime. */
1233 rtx_code_label
*do_main_label
, *after_negate_label
;
1235 rop0
= gen_reg_rtx (mode
);
1236 rop1
= gen_reg_rtx (mode
);
1237 emit_move_insn (rop0
, op0
);
1238 emit_move_insn (rop1
, op1
);
1241 do_main_label
= gen_label_rtx ();
1242 after_negate_label
= gen_label_rtx ();
1243 tem
= expand_binop (mode
, and_optab
, op0
, op1
, NULL_RTX
, false,
1245 do_compare_rtx_and_jump (tem
, const0_rtx
, GE
, false, mode
, NULL_RTX
,
1246 NULL
, after_negate_label
, PROB_VERY_LIKELY
);
1247 /* Both arguments negative here, negate them and continue with
1248 normal unsigned overflow checking multiplication. */
1249 emit_move_insn (op0
, expand_unop (mode
, neg_optab
, op0
,
1251 emit_move_insn (op1
, expand_unop (mode
, neg_optab
, op1
,
1253 /* Avoid looking at arg0/arg1 ranges, as we might have changed
1255 arg0
= error_mark_node
;
1256 arg1
= error_mark_node
;
1257 emit_jump (do_main_label
);
1258 emit_label (after_negate_label
);
1259 tem2
= expand_binop (mode
, xor_optab
, op0
, op1
, NULL_RTX
, false,
1261 do_compare_rtx_and_jump (tem2
, const0_rtx
, GE
, false, mode
, NULL_RTX
,
1262 NULL
, do_main_label
, PROB_VERY_LIKELY
);
1263 /* One argument is negative here, the other positive. This
1264 overflows always, unless one of the arguments is 0. But
1265 if e.g. s2 is 0, (U) s1 * 0 doesn't overflow, whatever s1
1266 is, thus we can keep do_main code oring in overflow as is. */
1267 do_compare_rtx_and_jump (tem
, const0_rtx
, EQ
, true, mode
, NULL_RTX
,
1268 NULL
, do_main_label
, PROB_VERY_LIKELY
);
1269 expand_arith_set_overflow (lhs
, target
);
1270 emit_label (do_main_label
);
1278 type
= build_nonstandard_integer_type (GET_MODE_PRECISION (mode
), uns
);
1279 sign
= uns
? UNSIGNED
: SIGNED
;
1280 icode
= optab_handler (uns
? umulv4_optab
: mulv4_optab
, mode
);
1281 if (icode
!= CODE_FOR_nothing
)
1283 struct expand_operand ops
[4];
1284 rtx_insn
*last
= get_last_insn ();
1286 res
= gen_reg_rtx (mode
);
1287 create_output_operand (&ops
[0], res
, mode
);
1288 create_input_operand (&ops
[1], op0
, mode
);
1289 create_input_operand (&ops
[2], op1
, mode
);
1290 create_fixed_operand (&ops
[3], do_error
);
1291 if (maybe_expand_insn (icode
, 4, ops
))
1293 last
= get_last_insn ();
1294 if (profile_status_for_fn (cfun
) != PROFILE_ABSENT
1296 && any_condjump_p (last
)
1297 && !find_reg_note (last
, REG_BR_PROB
, 0))
1298 add_int_reg_note (last
, REG_BR_PROB
, PROB_VERY_UNLIKELY
);
1299 emit_jump (done_label
);
1303 delete_insns_since (last
);
1304 icode
= CODE_FOR_nothing
;
1308 if (icode
== CODE_FOR_nothing
)
1310 struct separate_ops ops
;
1311 int prec
= GET_MODE_PRECISION (mode
);
1312 machine_mode hmode
= mode_for_size (prec
/ 2, MODE_INT
, 1);
1313 ops
.op0
= make_tree (type
, op0
);
1314 ops
.op1
= make_tree (type
, op1
);
1315 ops
.op2
= NULL_TREE
;
1317 if (GET_MODE_2XWIDER_MODE (mode
) != VOIDmode
1318 && targetm
.scalar_mode_supported_p (GET_MODE_2XWIDER_MODE (mode
)))
1320 machine_mode wmode
= GET_MODE_2XWIDER_MODE (mode
);
1321 ops
.code
= WIDEN_MULT_EXPR
;
1323 = build_nonstandard_integer_type (GET_MODE_PRECISION (wmode
), uns
);
1325 res
= expand_expr_real_2 (&ops
, NULL_RTX
, wmode
, EXPAND_NORMAL
);
1326 rtx hipart
= expand_shift (RSHIFT_EXPR
, wmode
, res
, prec
,
1328 hipart
= gen_lowpart (mode
, hipart
);
1329 res
= gen_lowpart (mode
, res
);
1331 /* For the unsigned multiplication, there was overflow if
1332 HIPART is non-zero. */
1333 do_compare_rtx_and_jump (hipart
, const0_rtx
, EQ
, true, mode
,
1334 NULL_RTX
, NULL
, done_label
,
1338 rtx signbit
= expand_shift (RSHIFT_EXPR
, mode
, res
, prec
- 1,
1340 /* RES is low half of the double width result, HIPART
1341 the high half. There was overflow if
1342 HIPART is different from RES < 0 ? -1 : 0. */
1343 do_compare_rtx_and_jump (signbit
, hipart
, EQ
, true, mode
,
1344 NULL_RTX
, NULL
, done_label
,
1348 else if (hmode
!= BLKmode
&& 2 * GET_MODE_PRECISION (hmode
) == prec
)
1350 rtx_code_label
*large_op0
= gen_label_rtx ();
1351 rtx_code_label
*small_op0_large_op1
= gen_label_rtx ();
1352 rtx_code_label
*one_small_one_large
= gen_label_rtx ();
1353 rtx_code_label
*both_ops_large
= gen_label_rtx ();
1354 rtx_code_label
*after_hipart_neg
= uns
? NULL
: gen_label_rtx ();
1355 rtx_code_label
*after_lopart_neg
= uns
? NULL
: gen_label_rtx ();
1356 rtx_code_label
*do_overflow
= gen_label_rtx ();
1357 rtx_code_label
*hipart_different
= uns
? NULL
: gen_label_rtx ();
1359 unsigned int hprec
= GET_MODE_PRECISION (hmode
);
1360 rtx hipart0
= expand_shift (RSHIFT_EXPR
, mode
, op0
, hprec
,
1362 hipart0
= gen_lowpart (hmode
, hipart0
);
1363 rtx lopart0
= gen_lowpart (hmode
, op0
);
1364 rtx signbit0
= const0_rtx
;
1366 signbit0
= expand_shift (RSHIFT_EXPR
, hmode
, lopart0
, hprec
- 1,
1368 rtx hipart1
= expand_shift (RSHIFT_EXPR
, mode
, op1
, hprec
,
1370 hipart1
= gen_lowpart (hmode
, hipart1
);
1371 rtx lopart1
= gen_lowpart (hmode
, op1
);
1372 rtx signbit1
= const0_rtx
;
1374 signbit1
= expand_shift (RSHIFT_EXPR
, hmode
, lopart1
, hprec
- 1,
1377 res
= gen_reg_rtx (mode
);
1379 /* True if op0 resp. op1 are known to be in the range of
1381 bool op0_small_p
= false;
1382 bool op1_small_p
= false;
1383 /* True if op0 resp. op1 are known to have all zeros or all ones
1384 in the upper half of bits, but are not known to be
1386 bool op0_medium_p
= false;
1387 bool op1_medium_p
= false;
1388 /* -1 if op{0,1} is known to be negative, 0 if it is known to be
1389 nonnegative, 1 if unknown. */
1395 else if (pos_neg0
== 2)
1399 else if (pos_neg1
== 2)
1402 unsigned int mprec0
= prec
;
1403 if (arg0
!= error_mark_node
)
1404 mprec0
= get_min_precision (arg0
, sign
);
1405 if (mprec0
<= hprec
)
1407 else if (!uns
&& mprec0
<= hprec
+ 1)
1408 op0_medium_p
= true;
1409 unsigned int mprec1
= prec
;
1410 if (arg1
!= error_mark_node
)
1411 mprec1
= get_min_precision (arg1
, sign
);
1412 if (mprec1
<= hprec
)
1414 else if (!uns
&& mprec1
<= hprec
+ 1)
1415 op1_medium_p
= true;
1417 int smaller_sign
= 1;
1418 int larger_sign
= 1;
1421 smaller_sign
= op0_sign
;
1422 larger_sign
= op1_sign
;
1424 else if (op1_small_p
)
1426 smaller_sign
= op1_sign
;
1427 larger_sign
= op0_sign
;
1429 else if (op0_sign
== op1_sign
)
1431 smaller_sign
= op0_sign
;
1432 larger_sign
= op0_sign
;
1436 do_compare_rtx_and_jump (signbit0
, hipart0
, NE
, true, hmode
,
1437 NULL_RTX
, NULL
, large_op0
,
1441 do_compare_rtx_and_jump (signbit1
, hipart1
, NE
, true, hmode
,
1442 NULL_RTX
, NULL
, small_op0_large_op1
,
1445 /* If both op0 and op1 are sign (!uns) or zero (uns) extended from
1446 hmode to mode, the multiplication will never overflow. We can
1447 do just one hmode x hmode => mode widening multiplication. */
1448 rtx lopart0s
= lopart0
, lopart1s
= lopart1
;
1449 if (GET_CODE (lopart0
) == SUBREG
)
1451 lopart0s
= shallow_copy_rtx (lopart0
);
1452 SUBREG_PROMOTED_VAR_P (lopart0s
) = 1;
1453 SUBREG_PROMOTED_SET (lopart0s
, uns
? SRP_UNSIGNED
: SRP_SIGNED
);
1455 if (GET_CODE (lopart1
) == SUBREG
)
1457 lopart1s
= shallow_copy_rtx (lopart1
);
1458 SUBREG_PROMOTED_VAR_P (lopart1s
) = 1;
1459 SUBREG_PROMOTED_SET (lopart1s
, uns
? SRP_UNSIGNED
: SRP_SIGNED
);
1461 tree halfstype
= build_nonstandard_integer_type (hprec
, uns
);
1462 ops
.op0
= make_tree (halfstype
, lopart0s
);
1463 ops
.op1
= make_tree (halfstype
, lopart1s
);
1464 ops
.code
= WIDEN_MULT_EXPR
;
1467 = expand_expr_real_2 (&ops
, NULL_RTX
, mode
, EXPAND_NORMAL
);
1468 emit_move_insn (res
, thisres
);
1469 emit_jump (done_label
);
1471 emit_label (small_op0_large_op1
);
1473 /* If op0 is sign (!uns) or zero (uns) extended from hmode to mode,
1474 but op1 is not, just swap the arguments and handle it as op1
1475 sign/zero extended, op0 not. */
1476 rtx larger
= gen_reg_rtx (mode
);
1477 rtx hipart
= gen_reg_rtx (hmode
);
1478 rtx lopart
= gen_reg_rtx (hmode
);
1479 emit_move_insn (larger
, op1
);
1480 emit_move_insn (hipart
, hipart1
);
1481 emit_move_insn (lopart
, lopart0
);
1482 emit_jump (one_small_one_large
);
1484 emit_label (large_op0
);
1487 do_compare_rtx_and_jump (signbit1
, hipart1
, NE
, true, hmode
,
1488 NULL_RTX
, NULL
, both_ops_large
,
1491 /* If op1 is sign (!uns) or zero (uns) extended from hmode to mode,
1492 but op0 is not, prepare larger, hipart and lopart pseudos and
1493 handle it together with small_op0_large_op1. */
1494 emit_move_insn (larger
, op0
);
1495 emit_move_insn (hipart
, hipart0
);
1496 emit_move_insn (lopart
, lopart1
);
1498 emit_label (one_small_one_large
);
1500 /* lopart is the low part of the operand that is sign extended
1501 to mode, larger is the other operand, hipart is the
1502 high part of larger and lopart0 and lopart1 are the low parts
1504 We perform lopart0 * lopart1 and lopart * hipart widening
1506 tree halfutype
= build_nonstandard_integer_type (hprec
, 1);
1507 ops
.op0
= make_tree (halfutype
, lopart0
);
1508 ops
.op1
= make_tree (halfutype
, lopart1
);
1510 = expand_expr_real_2 (&ops
, NULL_RTX
, mode
, EXPAND_NORMAL
);
1512 ops
.op0
= make_tree (halfutype
, lopart
);
1513 ops
.op1
= make_tree (halfutype
, hipart
);
1514 rtx loxhi
= gen_reg_rtx (mode
);
1515 rtx tem
= expand_expr_real_2 (&ops
, NULL_RTX
, mode
, EXPAND_NORMAL
);
1516 emit_move_insn (loxhi
, tem
);
1520 /* if (hipart < 0) loxhi -= lopart << (bitsize / 2); */
1521 if (larger_sign
== 0)
1522 emit_jump (after_hipart_neg
);
1523 else if (larger_sign
!= -1)
1524 do_compare_rtx_and_jump (hipart
, const0_rtx
, GE
, false, hmode
,
1525 NULL_RTX
, NULL
, after_hipart_neg
,
1528 tem
= convert_modes (mode
, hmode
, lopart
, 1);
1529 tem
= expand_shift (LSHIFT_EXPR
, mode
, tem
, hprec
, NULL_RTX
, 1);
1530 tem
= expand_simple_binop (mode
, MINUS
, loxhi
, tem
, NULL_RTX
,
1532 emit_move_insn (loxhi
, tem
);
1534 emit_label (after_hipart_neg
);
1536 /* if (lopart < 0) loxhi -= larger; */
1537 if (smaller_sign
== 0)
1538 emit_jump (after_lopart_neg
);
1539 else if (smaller_sign
!= -1)
1540 do_compare_rtx_and_jump (lopart
, const0_rtx
, GE
, false, hmode
,
1541 NULL_RTX
, NULL
, after_lopart_neg
,
1544 tem
= expand_simple_binop (mode
, MINUS
, loxhi
, larger
, NULL_RTX
,
1546 emit_move_insn (loxhi
, tem
);
1548 emit_label (after_lopart_neg
);
1551 /* loxhi += (uns) lo0xlo1 >> (bitsize / 2); */
1552 tem
= expand_shift (RSHIFT_EXPR
, mode
, lo0xlo1
, hprec
, NULL_RTX
, 1);
1553 tem
= expand_simple_binop (mode
, PLUS
, loxhi
, tem
, NULL_RTX
,
1555 emit_move_insn (loxhi
, tem
);
1557 /* if (loxhi >> (bitsize / 2)
1558 == (hmode) loxhi >> (bitsize / 2 - 1)) (if !uns)
1559 if (loxhi >> (bitsize / 2) == 0 (if uns). */
1560 rtx hipartloxhi
= expand_shift (RSHIFT_EXPR
, mode
, loxhi
, hprec
,
1562 hipartloxhi
= gen_lowpart (hmode
, hipartloxhi
);
1563 rtx signbitloxhi
= const0_rtx
;
1565 signbitloxhi
= expand_shift (RSHIFT_EXPR
, hmode
,
1566 gen_lowpart (hmode
, loxhi
),
1567 hprec
- 1, NULL_RTX
, 0);
1569 do_compare_rtx_and_jump (signbitloxhi
, hipartloxhi
, NE
, true, hmode
,
1570 NULL_RTX
, NULL
, do_overflow
,
1571 PROB_VERY_UNLIKELY
);
1573 /* res = (loxhi << (bitsize / 2)) | (hmode) lo0xlo1; */
1574 rtx loxhishifted
= expand_shift (LSHIFT_EXPR
, mode
, loxhi
, hprec
,
1576 tem
= convert_modes (mode
, hmode
, gen_lowpart (hmode
, lo0xlo1
), 1);
1578 tem
= expand_simple_binop (mode
, IOR
, loxhishifted
, tem
, res
,
1581 emit_move_insn (res
, tem
);
1582 emit_jump (done_label
);
1584 emit_label (both_ops_large
);
1586 /* If both operands are large (not sign (!uns) or zero (uns)
1587 extended from hmode), then perform the full multiplication
1588 which will be the result of the operation.
1589 The only cases which don't overflow are for signed multiplication
1590 some cases where both hipart0 and highpart1 are 0 or -1.
1591 For unsigned multiplication when high parts are both non-zero
1592 this overflows always. */
1593 ops
.code
= MULT_EXPR
;
1594 ops
.op0
= make_tree (type
, op0
);
1595 ops
.op1
= make_tree (type
, op1
);
1596 tem
= expand_expr_real_2 (&ops
, NULL_RTX
, mode
, EXPAND_NORMAL
);
1597 emit_move_insn (res
, tem
);
1603 tem
= expand_simple_binop (hmode
, PLUS
, hipart0
, const1_rtx
,
1604 NULL_RTX
, 1, OPTAB_DIRECT
);
1605 do_compare_rtx_and_jump (tem
, const1_rtx
, GTU
, true, hmode
,
1606 NULL_RTX
, NULL
, do_error
,
1607 PROB_VERY_UNLIKELY
);
1612 tem
= expand_simple_binop (hmode
, PLUS
, hipart1
, const1_rtx
,
1613 NULL_RTX
, 1, OPTAB_DIRECT
);
1614 do_compare_rtx_and_jump (tem
, const1_rtx
, GTU
, true, hmode
,
1615 NULL_RTX
, NULL
, do_error
,
1616 PROB_VERY_UNLIKELY
);
1619 /* At this point hipart{0,1} are both in [-1, 0]. If they are
1620 the same, overflow happened if res is negative, if they are
1621 different, overflow happened if res is positive. */
1622 if (op0_sign
!= 1 && op1_sign
!= 1 && op0_sign
!= op1_sign
)
1623 emit_jump (hipart_different
);
1624 else if (op0_sign
== 1 || op1_sign
== 1)
1625 do_compare_rtx_and_jump (hipart0
, hipart1
, NE
, true, hmode
,
1626 NULL_RTX
, NULL
, hipart_different
,
1629 do_compare_rtx_and_jump (res
, const0_rtx
, LT
, false, mode
,
1630 NULL_RTX
, NULL
, do_error
,
1631 PROB_VERY_UNLIKELY
);
1632 emit_jump (done_label
);
1634 emit_label (hipart_different
);
1636 do_compare_rtx_and_jump (res
, const0_rtx
, GE
, false, mode
,
1637 NULL_RTX
, NULL
, do_error
,
1638 PROB_VERY_UNLIKELY
);
1639 emit_jump (done_label
);
1642 emit_label (do_overflow
);
1644 /* Overflow, do full multiplication and fallthru into do_error. */
1645 ops
.op0
= make_tree (type
, op0
);
1646 ops
.op1
= make_tree (type
, op1
);
1647 tem
= expand_expr_real_2 (&ops
, NULL_RTX
, mode
, EXPAND_NORMAL
);
1648 emit_move_insn (res
, tem
);
1652 gcc_assert (!is_ubsan
);
1653 ops
.code
= MULT_EXPR
;
1655 res
= expand_expr_real_2 (&ops
, NULL_RTX
, mode
, EXPAND_NORMAL
);
1656 emit_jump (done_label
);
1661 emit_label (do_error
);
1664 /* Expand the ubsan builtin call. */
1666 fn
= ubsan_build_overflow_builtin (MULT_EXPR
, loc
, TREE_TYPE (arg0
),
1670 do_pending_stack_adjust ();
1673 expand_arith_set_overflow (lhs
, target
);
1676 emit_label (done_label
);
1679 if (uns0_p
&& uns1_p
&& !unsr_p
)
1681 rtx_code_label
*all_done_label
= gen_label_rtx ();
1682 do_compare_rtx_and_jump (res
, const0_rtx
, GE
, false, mode
, NULL_RTX
,
1683 NULL
, all_done_label
, PROB_VERY_LIKELY
);
1684 expand_arith_set_overflow (lhs
, target
);
1685 emit_label (all_done_label
);
1689 if (!uns0_p
&& uns1_p
&& !unsr_p
&& pos_neg1
== 3)
1691 rtx_code_label
*all_done_label
= gen_label_rtx ();
1692 rtx_code_label
*set_noovf
= gen_label_rtx ();
1693 do_compare_rtx_and_jump (op1
, const0_rtx
, GE
, false, mode
, NULL_RTX
,
1694 NULL
, all_done_label
, PROB_VERY_LIKELY
);
1695 expand_arith_set_overflow (lhs
, target
);
1696 do_compare_rtx_and_jump (op0
, const0_rtx
, EQ
, true, mode
, NULL_RTX
,
1697 NULL
, set_noovf
, PROB_VERY_LIKELY
);
1698 do_compare_rtx_and_jump (op0
, constm1_rtx
, NE
, true, mode
, NULL_RTX
,
1699 NULL
, all_done_label
, PROB_VERY_UNLIKELY
);
1700 do_compare_rtx_and_jump (op1
, res
, NE
, true, mode
, NULL_RTX
, NULL
,
1701 all_done_label
, PROB_VERY_UNLIKELY
);
1702 emit_label (set_noovf
);
1703 write_complex_part (target
, const0_rtx
, true);
1704 emit_label (all_done_label
);
1710 expand_ubsan_result_store (target
, res
);
1712 expand_arith_overflow_result_store (lhs
, target
, mode
, res
);
1716 /* Expand UBSAN_CHECK_ADD call STMT. */
1719 expand_UBSAN_CHECK_ADD (internal_fn
, gcall
*stmt
)
1721 location_t loc
= gimple_location (stmt
);
1722 tree lhs
= gimple_call_lhs (stmt
);
1723 tree arg0
= gimple_call_arg (stmt
, 0);
1724 tree arg1
= gimple_call_arg (stmt
, 1);
1725 expand_addsub_overflow (loc
, PLUS_EXPR
, lhs
, arg0
, arg1
,
1726 false, false, false, true);
1729 /* Expand UBSAN_CHECK_SUB call STMT. */
1732 expand_UBSAN_CHECK_SUB (internal_fn
, gcall
*stmt
)
1734 location_t loc
= gimple_location (stmt
);
1735 tree lhs
= gimple_call_lhs (stmt
);
1736 tree arg0
= gimple_call_arg (stmt
, 0);
1737 tree arg1
= gimple_call_arg (stmt
, 1);
1738 if (integer_zerop (arg0
))
1739 expand_neg_overflow (loc
, lhs
, arg1
, true);
1741 expand_addsub_overflow (loc
, MINUS_EXPR
, lhs
, arg0
, arg1
,
1742 false, false, false, true);
1745 /* Expand UBSAN_CHECK_MUL call STMT. */
1748 expand_UBSAN_CHECK_MUL (internal_fn
, gcall
*stmt
)
1750 location_t loc
= gimple_location (stmt
);
1751 tree lhs
= gimple_call_lhs (stmt
);
1752 tree arg0
= gimple_call_arg (stmt
, 0);
1753 tree arg1
= gimple_call_arg (stmt
, 1);
1754 expand_mul_overflow (loc
, lhs
, arg0
, arg1
, false, false, false, true);
1757 /* Helper function for {ADD,SUB,MUL}_OVERFLOW call stmt expansion. */
1760 expand_arith_overflow (enum tree_code code
, gimple
*stmt
)
1762 tree lhs
= gimple_call_lhs (stmt
);
1763 if (lhs
== NULL_TREE
)
1765 tree arg0
= gimple_call_arg (stmt
, 0);
1766 tree arg1
= gimple_call_arg (stmt
, 1);
1767 tree type
= TREE_TYPE (TREE_TYPE (lhs
));
1768 int uns0_p
= TYPE_UNSIGNED (TREE_TYPE (arg0
));
1769 int uns1_p
= TYPE_UNSIGNED (TREE_TYPE (arg1
));
1770 int unsr_p
= TYPE_UNSIGNED (type
);
1771 int prec0
= TYPE_PRECISION (TREE_TYPE (arg0
));
1772 int prec1
= TYPE_PRECISION (TREE_TYPE (arg1
));
1773 int precres
= TYPE_PRECISION (type
);
1774 location_t loc
= gimple_location (stmt
);
1775 if (!uns0_p
&& get_range_pos_neg (arg0
) == 1)
1777 if (!uns1_p
&& get_range_pos_neg (arg1
) == 1)
1779 int pr
= get_min_precision (arg0
, uns0_p
? UNSIGNED
: SIGNED
);
1780 prec0
= MIN (prec0
, pr
);
1781 pr
= get_min_precision (arg1
, uns1_p
? UNSIGNED
: SIGNED
);
1782 prec1
= MIN (prec1
, pr
);
1784 /* If uns0_p && uns1_p, precop is minimum needed precision
1785 of unsigned type to hold the exact result, otherwise
1786 precop is minimum needed precision of signed type to
1787 hold the exact result. */
1789 if (code
== MULT_EXPR
)
1790 precop
= prec0
+ prec1
+ (uns0_p
!= uns1_p
);
1793 if (uns0_p
== uns1_p
)
1794 precop
= MAX (prec0
, prec1
) + 1;
1796 precop
= MAX (prec0
+ 1, prec1
) + 1;
1798 precop
= MAX (prec0
, prec1
+ 1) + 1;
1800 int orig_precres
= precres
;
1804 if ((uns0_p
&& uns1_p
)
1805 ? ((precop
+ !unsr_p
) <= precres
1806 /* u1 - u2 -> ur can overflow, no matter what precision
1808 && (code
!= MINUS_EXPR
|| !unsr_p
))
1809 : (!unsr_p
&& precop
<= precres
))
1811 /* The infinity precision result will always fit into result. */
1812 rtx target
= expand_expr (lhs
, NULL_RTX
, VOIDmode
, EXPAND_WRITE
);
1813 write_complex_part (target
, const0_rtx
, true);
1814 enum machine_mode mode
= TYPE_MODE (type
);
1815 struct separate_ops ops
;
1818 ops
.op0
= fold_convert_loc (loc
, type
, arg0
);
1819 ops
.op1
= fold_convert_loc (loc
, type
, arg1
);
1820 ops
.op2
= NULL_TREE
;
1822 rtx tem
= expand_expr_real_2 (&ops
, NULL_RTX
, mode
, EXPAND_NORMAL
);
1823 expand_arith_overflow_result_store (lhs
, target
, mode
, tem
);
1827 /* For sub-word operations, if target doesn't have them, start
1828 with precres widening right away, otherwise do it only
1829 if the most simple cases can't be used. */
1830 if (WORD_REGISTER_OPERATIONS
1831 && orig_precres
== precres
1832 && precres
< BITS_PER_WORD
)
1834 else if ((uns0_p
&& uns1_p
&& unsr_p
&& prec0
<= precres
1835 && prec1
<= precres
)
1836 || ((!uns0_p
|| !uns1_p
) && !unsr_p
1837 && prec0
+ uns0_p
<= precres
1838 && prec1
+ uns1_p
<= precres
))
1840 arg0
= fold_convert_loc (loc
, type
, arg0
);
1841 arg1
= fold_convert_loc (loc
, type
, arg1
);
1845 if (integer_zerop (arg0
) && !unsr_p
)
1847 expand_neg_overflow (loc
, lhs
, arg1
, false);
1852 expand_addsub_overflow (loc
, code
, lhs
, arg0
, arg1
,
1853 unsr_p
, unsr_p
, unsr_p
, false);
1856 expand_mul_overflow (loc
, lhs
, arg0
, arg1
,
1857 unsr_p
, unsr_p
, unsr_p
, false);
1864 /* For sub-word operations, retry with a wider type first. */
1865 if (orig_precres
== precres
&& precop
<= BITS_PER_WORD
)
1867 int p
= WORD_REGISTER_OPERATIONS
? BITS_PER_WORD
: precop
;
1868 enum machine_mode m
= smallest_mode_for_size (p
, MODE_INT
);
1869 tree optype
= build_nonstandard_integer_type (GET_MODE_PRECISION (m
),
1872 p
= TYPE_PRECISION (optype
);
1876 unsr_p
= TYPE_UNSIGNED (optype
);
1882 if (prec0
<= precres
&& prec1
<= precres
)
1887 types
[0] = build_nonstandard_integer_type (precres
, 0);
1893 types
[1] = build_nonstandard_integer_type (precres
, 1);
1895 arg0
= fold_convert_loc (loc
, types
[uns0_p
], arg0
);
1896 arg1
= fold_convert_loc (loc
, types
[uns1_p
], arg1
);
1897 if (code
!= MULT_EXPR
)
1898 expand_addsub_overflow (loc
, code
, lhs
, arg0
, arg1
, unsr_p
,
1899 uns0_p
, uns1_p
, false);
1901 expand_mul_overflow (loc
, lhs
, arg0
, arg1
, unsr_p
,
1902 uns0_p
, uns1_p
, false);
1906 /* Retry with a wider type. */
1907 if (orig_precres
== precres
)
1909 int p
= MAX (prec0
, prec1
);
1910 enum machine_mode m
= smallest_mode_for_size (p
, MODE_INT
);
1911 tree optype
= build_nonstandard_integer_type (GET_MODE_PRECISION (m
),
1914 p
= TYPE_PRECISION (optype
);
1918 unsr_p
= TYPE_UNSIGNED (optype
);
1929 /* Expand ADD_OVERFLOW STMT. */
1932 expand_ADD_OVERFLOW (internal_fn
, gcall
*stmt
)
1934 expand_arith_overflow (PLUS_EXPR
, stmt
);
1937 /* Expand SUB_OVERFLOW STMT. */
1940 expand_SUB_OVERFLOW (internal_fn
, gcall
*stmt
)
1942 expand_arith_overflow (MINUS_EXPR
, stmt
);
1945 /* Expand MUL_OVERFLOW STMT. */
1948 expand_MUL_OVERFLOW (internal_fn
, gcall
*stmt
)
1950 expand_arith_overflow (MULT_EXPR
, stmt
);
1953 /* This should get folded in tree-vectorizer.c. */
1956 expand_LOOP_VECTORIZED (internal_fn
, gcall
*)
1961 /* Expand MASK_LOAD call STMT using optab OPTAB. */
1964 expand_mask_load_optab_fn (internal_fn
, gcall
*stmt
, convert_optab optab
)
1966 struct expand_operand ops
[3];
1967 tree type
, lhs
, rhs
, maskt
, ptr
;
1968 rtx mem
, target
, mask
;
1971 maskt
= gimple_call_arg (stmt
, 2);
1972 lhs
= gimple_call_lhs (stmt
);
1973 if (lhs
== NULL_TREE
)
1975 type
= TREE_TYPE (lhs
);
1976 ptr
= build_int_cst (TREE_TYPE (gimple_call_arg (stmt
, 1)), 0);
1977 align
= tree_to_shwi (gimple_call_arg (stmt
, 1));
1978 if (TYPE_ALIGN (type
) != align
)
1979 type
= build_aligned_type (type
, align
);
1980 rhs
= fold_build2 (MEM_REF
, type
, gimple_call_arg (stmt
, 0), ptr
);
1982 mem
= expand_expr (rhs
, NULL_RTX
, VOIDmode
, EXPAND_WRITE
);
1983 gcc_assert (MEM_P (mem
));
1984 mask
= expand_normal (maskt
);
1985 target
= expand_expr (lhs
, NULL_RTX
, VOIDmode
, EXPAND_WRITE
);
1986 create_output_operand (&ops
[0], target
, TYPE_MODE (type
));
1987 create_fixed_operand (&ops
[1], mem
);
1988 create_input_operand (&ops
[2], mask
, TYPE_MODE (TREE_TYPE (maskt
)));
1989 expand_insn (convert_optab_handler (optab
, TYPE_MODE (type
),
1990 TYPE_MODE (TREE_TYPE (maskt
))),
1994 /* Expand MASK_STORE call STMT using optab OPTAB. */
1997 expand_mask_store_optab_fn (internal_fn
, gcall
*stmt
, convert_optab optab
)
1999 struct expand_operand ops
[3];
2000 tree type
, lhs
, rhs
, maskt
, ptr
;
2004 maskt
= gimple_call_arg (stmt
, 2);
2005 rhs
= gimple_call_arg (stmt
, 3);
2006 type
= TREE_TYPE (rhs
);
2007 ptr
= build_int_cst (TREE_TYPE (gimple_call_arg (stmt
, 1)), 0);
2008 align
= tree_to_shwi (gimple_call_arg (stmt
, 1));
2009 if (TYPE_ALIGN (type
) != align
)
2010 type
= build_aligned_type (type
, align
);
2011 lhs
= fold_build2 (MEM_REF
, type
, gimple_call_arg (stmt
, 0), ptr
);
2013 mem
= expand_expr (lhs
, NULL_RTX
, VOIDmode
, EXPAND_WRITE
);
2014 gcc_assert (MEM_P (mem
));
2015 mask
= expand_normal (maskt
);
2016 reg
= expand_normal (rhs
);
2017 create_fixed_operand (&ops
[0], mem
);
2018 create_input_operand (&ops
[1], reg
, TYPE_MODE (type
));
2019 create_input_operand (&ops
[2], mask
, TYPE_MODE (TREE_TYPE (maskt
)));
2020 expand_insn (convert_optab_handler (optab
, TYPE_MODE (type
),
2021 TYPE_MODE (TREE_TYPE (maskt
))),
2026 expand_ABNORMAL_DISPATCHER (internal_fn
, gcall
*)
2031 expand_BUILTIN_EXPECT (internal_fn
, gcall
*stmt
)
2033 /* When guessing was done, the hints should be already stripped away. */
2034 gcc_assert (!flag_guess_branch_prob
|| optimize
== 0 || seen_error ());
2037 tree lhs
= gimple_call_lhs (stmt
);
2039 target
= expand_expr (lhs
, NULL_RTX
, VOIDmode
, EXPAND_WRITE
);
2041 target
= const0_rtx
;
2042 rtx val
= expand_expr (gimple_call_arg (stmt
, 0), target
, VOIDmode
, EXPAND_NORMAL
);
2043 if (lhs
&& val
!= target
)
2044 emit_move_insn (target
, val
);
2047 /* IFN_VA_ARG is supposed to be expanded at pass_stdarg. So this dummy function
2048 should never be called. */
2051 expand_VA_ARG (internal_fn
, gcall
*)
2056 /* Expand the IFN_UNIQUE function according to its first argument. */
2059 expand_UNIQUE (internal_fn
, gcall
*stmt
)
2061 rtx pattern
= NULL_RTX
;
2062 enum ifn_unique_kind kind
2063 = (enum ifn_unique_kind
) TREE_INT_CST_LOW (gimple_call_arg (stmt
, 0));
2070 case IFN_UNIQUE_UNSPEC
:
2071 if (targetm
.have_unique ())
2072 pattern
= targetm
.gen_unique ();
2075 case IFN_UNIQUE_OACC_FORK
:
2076 case IFN_UNIQUE_OACC_JOIN
:
2077 if (targetm
.have_oacc_fork () && targetm
.have_oacc_join ())
2079 tree lhs
= gimple_call_lhs (stmt
);
2080 rtx target
= const0_rtx
;
2083 target
= expand_expr (lhs
, NULL_RTX
, VOIDmode
, EXPAND_WRITE
);
2085 rtx data_dep
= expand_normal (gimple_call_arg (stmt
, 1));
2086 rtx axis
= expand_normal (gimple_call_arg (stmt
, 2));
2088 if (kind
== IFN_UNIQUE_OACC_FORK
)
2089 pattern
= targetm
.gen_oacc_fork (target
, data_dep
, axis
);
2091 pattern
= targetm
.gen_oacc_join (target
, data_dep
, axis
);
2099 emit_insn (pattern
);
2102 /* The size of an OpenACC compute dimension. */
2105 expand_GOACC_DIM_SIZE (internal_fn
, gcall
*stmt
)
2107 tree lhs
= gimple_call_lhs (stmt
);
2112 rtx target
= expand_expr (lhs
, NULL_RTX
, VOIDmode
, EXPAND_WRITE
);
2113 if (targetm
.have_oacc_dim_size ())
2115 rtx dim
= expand_expr (gimple_call_arg (stmt
, 0), NULL_RTX
,
2116 VOIDmode
, EXPAND_NORMAL
);
2117 emit_insn (targetm
.gen_oacc_dim_size (target
, dim
));
2120 emit_move_insn (target
, GEN_INT (1));
2123 /* The position of an OpenACC execution engine along one compute axis. */
2126 expand_GOACC_DIM_POS (internal_fn
, gcall
*stmt
)
2128 tree lhs
= gimple_call_lhs (stmt
);
2133 rtx target
= expand_expr (lhs
, NULL_RTX
, VOIDmode
, EXPAND_WRITE
);
2134 if (targetm
.have_oacc_dim_pos ())
2136 rtx dim
= expand_expr (gimple_call_arg (stmt
, 0), NULL_RTX
,
2137 VOIDmode
, EXPAND_NORMAL
);
2138 emit_insn (targetm
.gen_oacc_dim_pos (target
, dim
));
2141 emit_move_insn (target
, const0_rtx
);
2144 /* This is expanded by oacc_device_lower pass. */
2147 expand_GOACC_LOOP (internal_fn
, gcall
*)
2152 /* This is expanded by oacc_device_lower pass. */
2155 expand_GOACC_REDUCTION (internal_fn
, gcall
*)
2160 /* Set errno to EDOM. */
2163 expand_SET_EDOM (internal_fn
, gcall
*)
2166 #ifdef GEN_ERRNO_RTX
2167 rtx errno_rtx
= GEN_ERRNO_RTX
;
2169 rtx errno_rtx
= gen_rtx_MEM (word_mode
, gen_rtx_SYMBOL_REF (Pmode
, "errno"));
2171 emit_move_insn (errno_rtx
,
2172 gen_int_mode (TARGET_EDOM
, GET_MODE (errno_rtx
)));
2178 /* Expand atomic bit test and set. */
2181 expand_ATOMIC_BIT_TEST_AND_SET (internal_fn
, gcall
*call
)
2183 expand_ifn_atomic_bit_test_and (call
);
2186 /* Expand atomic bit test and complement. */
2189 expand_ATOMIC_BIT_TEST_AND_COMPLEMENT (internal_fn
, gcall
*call
)
2191 expand_ifn_atomic_bit_test_and (call
);
2194 /* Expand atomic bit test and reset. */
2197 expand_ATOMIC_BIT_TEST_AND_RESET (internal_fn
, gcall
*call
)
2199 expand_ifn_atomic_bit_test_and (call
);
2202 /* Expand atomic bit test and set. */
2205 expand_ATOMIC_COMPARE_EXCHANGE (internal_fn
, gcall
*call
)
2207 expand_ifn_atomic_compare_exchange (call
);
2210 /* Expand a call to FN using the operands in STMT. FN has a single
2211 output operand and NARGS input operands. */
2214 expand_direct_optab_fn (internal_fn fn
, gcall
*stmt
, direct_optab optab
,
2217 expand_operand
*ops
= XALLOCAVEC (expand_operand
, nargs
+ 1);
2219 tree_pair types
= direct_internal_fn_types (fn
, stmt
);
2220 insn_code icode
= direct_optab_handler (optab
, TYPE_MODE (types
.first
));
2222 tree lhs
= gimple_call_lhs (stmt
);
2223 tree lhs_type
= TREE_TYPE (lhs
);
2224 rtx lhs_rtx
= expand_expr (lhs
, NULL_RTX
, VOIDmode
, EXPAND_WRITE
);
2225 create_output_operand (&ops
[0], lhs_rtx
, insn_data
[icode
].operand
[0].mode
);
2227 for (unsigned int i
= 0; i
< nargs
; ++i
)
2229 tree rhs
= gimple_call_arg (stmt
, i
);
2230 tree rhs_type
= TREE_TYPE (rhs
);
2231 rtx rhs_rtx
= expand_normal (rhs
);
2232 if (INTEGRAL_TYPE_P (rhs_type
))
2233 create_convert_operand_from (&ops
[i
+ 1], rhs_rtx
,
2234 TYPE_MODE (rhs_type
),
2235 TYPE_UNSIGNED (rhs_type
));
2237 create_input_operand (&ops
[i
+ 1], rhs_rtx
, TYPE_MODE (rhs_type
));
2240 expand_insn (icode
, nargs
+ 1, ops
);
2241 if (!rtx_equal_p (lhs_rtx
, ops
[0].value
))
2243 /* If the return value has an integral type, convert the instruction
2244 result to that type. This is useful for things that return an
2245 int regardless of the size of the input. If the instruction result
2246 is smaller than required, assume that it is signed.
2248 If the return value has a nonintegral type, its mode must match
2249 the instruction result. */
2250 if (GET_CODE (lhs_rtx
) == SUBREG
&& SUBREG_PROMOTED_VAR_P (lhs_rtx
))
2252 /* If this is a scalar in a register that is stored in a wider
2253 mode than the declared mode, compute the result into its
2254 declared mode and then convert to the wider mode. */
2255 gcc_checking_assert (INTEGRAL_TYPE_P (lhs_type
));
2256 rtx tmp
= convert_to_mode (GET_MODE (lhs_rtx
), ops
[0].value
, 0);
2257 convert_move (SUBREG_REG (lhs_rtx
), tmp
,
2258 SUBREG_PROMOTED_SIGN (lhs_rtx
));
2260 else if (GET_MODE (lhs_rtx
) == GET_MODE (ops
[0].value
))
2261 emit_move_insn (lhs_rtx
, ops
[0].value
);
2264 gcc_checking_assert (INTEGRAL_TYPE_P (lhs_type
));
2265 convert_move (lhs_rtx
, ops
[0].value
, 0);
2270 /* Expanders for optabs that can use expand_direct_optab_fn. */
2272 #define expand_unary_optab_fn(FN, STMT, OPTAB) \
2273 expand_direct_optab_fn (FN, STMT, OPTAB, 1)
2275 #define expand_binary_optab_fn(FN, STMT, OPTAB) \
2276 expand_direct_optab_fn (FN, STMT, OPTAB, 2)
2278 /* RETURN_TYPE and ARGS are a return type and argument list that are
2279 in principle compatible with FN (which satisfies direct_internal_fn_p).
2280 Return the types that should be used to determine whether the
2281 target supports FN. */
2284 direct_internal_fn_types (internal_fn fn
, tree return_type
, tree
*args
)
2286 const direct_internal_fn_info
&info
= direct_internal_fn (fn
);
2287 tree type0
= (info
.type0
< 0 ? return_type
: TREE_TYPE (args
[info
.type0
]));
2288 tree type1
= (info
.type1
< 0 ? return_type
: TREE_TYPE (args
[info
.type1
]));
2289 return tree_pair (type0
, type1
);
2292 /* CALL is a call whose return type and arguments are in principle
2293 compatible with FN (which satisfies direct_internal_fn_p). Return the
2294 types that should be used to determine whether the target supports FN. */
2297 direct_internal_fn_types (internal_fn fn
, gcall
*call
)
2299 const direct_internal_fn_info
&info
= direct_internal_fn (fn
);
2300 tree op0
= (info
.type0
< 0
2301 ? gimple_call_lhs (call
)
2302 : gimple_call_arg (call
, info
.type0
));
2303 tree op1
= (info
.type1
< 0
2304 ? gimple_call_lhs (call
)
2305 : gimple_call_arg (call
, info
.type1
));
2306 return tree_pair (TREE_TYPE (op0
), TREE_TYPE (op1
));
2309 /* Return true if OPTAB is supported for TYPES (whose modes should be
2310 the same) when the optimization type is OPT_TYPE. Used for simple
2314 direct_optab_supported_p (direct_optab optab
, tree_pair types
,
2315 optimization_type opt_type
)
2317 machine_mode mode
= TYPE_MODE (types
.first
);
2318 gcc_checking_assert (mode
== TYPE_MODE (types
.second
));
2319 return direct_optab_handler (optab
, mode
, opt_type
) != CODE_FOR_nothing
;
2322 /* Return true if load/store lanes optab OPTAB is supported for
2323 array type TYPES.first when the optimization type is OPT_TYPE. */
2326 multi_vector_optab_supported_p (convert_optab optab
, tree_pair types
,
2327 optimization_type opt_type
)
2329 gcc_assert (TREE_CODE (types
.first
) == ARRAY_TYPE
);
2330 machine_mode imode
= TYPE_MODE (types
.first
);
2331 machine_mode vmode
= TYPE_MODE (TREE_TYPE (types
.first
));
2332 return (convert_optab_handler (optab
, imode
, vmode
, opt_type
)
2333 != CODE_FOR_nothing
);
2336 #define direct_unary_optab_supported_p direct_optab_supported_p
2337 #define direct_binary_optab_supported_p direct_optab_supported_p
2338 #define direct_mask_load_optab_supported_p direct_optab_supported_p
2339 #define direct_load_lanes_optab_supported_p multi_vector_optab_supported_p
2340 #define direct_mask_store_optab_supported_p direct_optab_supported_p
2341 #define direct_store_lanes_optab_supported_p multi_vector_optab_supported_p
2343 /* Return true if FN is supported for the types in TYPES when the
2344 optimization type is OPT_TYPE. The types are those associated with
2345 the "type0" and "type1" fields of FN's direct_internal_fn_info
2349 direct_internal_fn_supported_p (internal_fn fn
, tree_pair types
,
2350 optimization_type opt_type
)
2354 #define DEF_INTERNAL_FN(CODE, FLAGS, FNSPEC) \
2355 case IFN_##CODE: break;
2356 #define DEF_INTERNAL_OPTAB_FN(CODE, FLAGS, OPTAB, TYPE) \
2358 return direct_##TYPE##_optab_supported_p (OPTAB##_optab, types, \
2360 #include "internal-fn.def"
2368 /* Return true if FN is supported for type TYPE when the optimization
2369 type is OPT_TYPE. The caller knows that the "type0" and "type1"
2370 fields of FN's direct_internal_fn_info structure are the same. */
2373 direct_internal_fn_supported_p (internal_fn fn
, tree type
,
2374 optimization_type opt_type
)
2376 const direct_internal_fn_info
&info
= direct_internal_fn (fn
);
2377 gcc_checking_assert (info
.type0
== info
.type1
);
2378 return direct_internal_fn_supported_p (fn
, tree_pair (type
, type
), opt_type
);
2381 /* Return true if IFN_SET_EDOM is supported. */
2384 set_edom_supported_p (void)
2393 #define DEF_INTERNAL_OPTAB_FN(CODE, FLAGS, OPTAB, TYPE) \
2395 expand_##CODE (internal_fn fn, gcall *stmt) \
2397 expand_##TYPE##_optab_fn (fn, stmt, OPTAB##_optab); \
2399 #include "internal-fn.def"
2401 /* Routines to expand each internal function, indexed by function number.
2402 Each routine has the prototype:
2404 expand_<NAME> (gcall *stmt)
2406 where STMT is the statement that performs the call. */
2407 static void (*const internal_fn_expanders
[]) (internal_fn
, gcall
*) = {
2408 #define DEF_INTERNAL_FN(CODE, FLAGS, FNSPEC) expand_##CODE,
2409 #include "internal-fn.def"
2413 /* Expand STMT as though it were a call to internal function FN. */
2416 expand_internal_call (internal_fn fn
, gcall
*stmt
)
2418 internal_fn_expanders
[fn
] (fn
, stmt
);
2421 /* Expand STMT, which is a call to internal function FN. */
2424 expand_internal_call (gcall
*stmt
)
2426 expand_internal_call (gimple_call_internal_fn (stmt
), stmt
);