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"
35 #include "diagnostic-core.h"
36 #include "fold-const.h"
37 #include "internal-fn.h"
38 #include "stor-layout.h"
45 /* The names of each internal function, indexed by function number. */
46 const char *const internal_fn_name_array
[] = {
47 #define DEF_INTERNAL_FN(CODE, FLAGS, FNSPEC) #CODE,
48 #include "internal-fn.def"
52 /* The ECF_* flags of each internal function, indexed by function number. */
53 const int internal_fn_flags_array
[] = {
54 #define DEF_INTERNAL_FN(CODE, FLAGS, FNSPEC) FLAGS,
55 #include "internal-fn.def"
59 /* Fnspec of each internal function, indexed by function number. */
60 const_tree internal_fn_fnspec_array
[IFN_LAST
+ 1];
65 #define DEF_INTERNAL_FN(CODE, FLAGS, FNSPEC) \
66 if (FNSPEC) internal_fn_fnspec_array[IFN_##CODE] = \
67 build_string ((int) sizeof (FNSPEC), FNSPEC ? FNSPEC : "");
68 #include "internal-fn.def"
69 internal_fn_fnspec_array
[IFN_LAST
] = 0;
72 /* Create static initializers for the information returned by
73 direct_internal_fn. */
74 #define not_direct { -2, -2, false }
75 #define mask_load_direct { -1, 2, false }
76 #define load_lanes_direct { -1, -1, false }
77 #define mask_store_direct { 3, 2, false }
78 #define store_lanes_direct { 0, 0, false }
79 #define unary_direct { 0, 0, true }
80 #define binary_direct { 0, 0, true }
82 const direct_internal_fn_info direct_internal_fn_array
[IFN_LAST
+ 1] = {
83 #define DEF_INTERNAL_FN(CODE, FLAGS, FNSPEC) not_direct,
84 #define DEF_INTERNAL_OPTAB_FN(CODE, FLAGS, OPTAB, TYPE) TYPE##_direct,
85 #include "internal-fn.def"
89 /* ARRAY_TYPE is an array of vector modes. Return the associated insn
90 for load-lanes-style optab OPTAB, or CODE_FOR_nothing if none. */
93 get_multi_vector_move (tree array_type
, convert_optab optab
)
98 gcc_assert (TREE_CODE (array_type
) == ARRAY_TYPE
);
99 imode
= TYPE_MODE (array_type
);
100 vmode
= TYPE_MODE (TREE_TYPE (array_type
));
102 return convert_optab_handler (optab
, imode
, vmode
);
105 /* Expand LOAD_LANES call STMT using optab OPTAB. */
108 expand_load_lanes_optab_fn (internal_fn
, gcall
*stmt
, convert_optab optab
)
110 struct expand_operand ops
[2];
114 lhs
= gimple_call_lhs (stmt
);
115 rhs
= gimple_call_arg (stmt
, 0);
116 type
= TREE_TYPE (lhs
);
118 target
= expand_expr (lhs
, NULL_RTX
, VOIDmode
, EXPAND_WRITE
);
119 mem
= expand_normal (rhs
);
121 gcc_assert (MEM_P (mem
));
122 PUT_MODE (mem
, TYPE_MODE (type
));
124 create_output_operand (&ops
[0], target
, TYPE_MODE (type
));
125 create_fixed_operand (&ops
[1], mem
);
126 expand_insn (get_multi_vector_move (type
, optab
), 2, ops
);
129 /* Expand STORE_LANES call STMT using optab OPTAB. */
132 expand_store_lanes_optab_fn (internal_fn
, gcall
*stmt
, convert_optab optab
)
134 struct expand_operand ops
[2];
138 lhs
= gimple_call_lhs (stmt
);
139 rhs
= gimple_call_arg (stmt
, 0);
140 type
= TREE_TYPE (rhs
);
142 target
= expand_expr (lhs
, NULL_RTX
, VOIDmode
, EXPAND_WRITE
);
143 reg
= expand_normal (rhs
);
145 gcc_assert (MEM_P (target
));
146 PUT_MODE (target
, TYPE_MODE (type
));
148 create_fixed_operand (&ops
[0], target
);
149 create_input_operand (&ops
[1], reg
, TYPE_MODE (type
));
150 expand_insn (get_multi_vector_move (type
, optab
), 2, ops
);
154 expand_ANNOTATE (internal_fn
, gcall
*)
159 /* This should get expanded in adjust_simduid_builtins. */
162 expand_GOMP_SIMD_LANE (internal_fn
, gcall
*)
167 /* This should get expanded in adjust_simduid_builtins. */
170 expand_GOMP_SIMD_VF (internal_fn
, gcall
*)
175 /* This should get expanded in adjust_simduid_builtins. */
178 expand_GOMP_SIMD_LAST_LANE (internal_fn
, gcall
*)
183 /* This should get expanded in adjust_simduid_builtins. */
186 expand_GOMP_SIMD_ORDERED_START (internal_fn
, gcall
*)
191 /* This should get expanded in adjust_simduid_builtins. */
194 expand_GOMP_SIMD_ORDERED_END (internal_fn
, gcall
*)
199 /* This should get expanded in the sanopt pass. */
202 expand_UBSAN_NULL (internal_fn
, gcall
*)
207 /* This should get expanded in the sanopt pass. */
210 expand_UBSAN_BOUNDS (internal_fn
, gcall
*)
215 /* This should get expanded in the sanopt pass. */
218 expand_UBSAN_VPTR (internal_fn
, gcall
*)
223 /* This should get expanded in the sanopt pass. */
226 expand_UBSAN_OBJECT_SIZE (internal_fn
, gcall
*)
231 /* This should get expanded in the sanopt pass. */
234 expand_ASAN_CHECK (internal_fn
, gcall
*)
239 /* This should get expanded in the tsan pass. */
242 expand_TSAN_FUNC_EXIT (internal_fn
, gcall
*)
247 /* This should get expanded in the lower pass. */
250 expand_FALLTHROUGH (internal_fn
, gcall
*call
)
252 error_at (gimple_location (call
),
253 "invalid use of attribute %<fallthrough%>");
256 /* Helper function for expand_addsub_overflow. Return 1
257 if ARG interpreted as signed in its precision is known to be always
258 positive or 2 if ARG is known to be always negative, or 3 if ARG may
259 be positive or negative. */
262 get_range_pos_neg (tree arg
)
264 if (arg
== error_mark_node
)
267 int prec
= TYPE_PRECISION (TREE_TYPE (arg
));
269 if (TREE_CODE (arg
) == INTEGER_CST
)
271 wide_int w
= wi::sext (arg
, prec
);
277 while (CONVERT_EXPR_P (arg
)
278 && INTEGRAL_TYPE_P (TREE_TYPE (TREE_OPERAND (arg
, 0)))
279 && TYPE_PRECISION (TREE_TYPE (TREE_OPERAND (arg
, 0))) <= prec
)
281 arg
= TREE_OPERAND (arg
, 0);
282 /* Narrower value zero extended into wider type
283 will always result in positive values. */
284 if (TYPE_UNSIGNED (TREE_TYPE (arg
))
285 && TYPE_PRECISION (TREE_TYPE (arg
)) < prec
)
287 prec
= TYPE_PRECISION (TREE_TYPE (arg
));
292 if (TREE_CODE (arg
) != SSA_NAME
)
294 wide_int arg_min
, arg_max
;
295 while (get_range_info (arg
, &arg_min
, &arg_max
) != VR_RANGE
)
297 gimple
*g
= SSA_NAME_DEF_STMT (arg
);
298 if (is_gimple_assign (g
)
299 && CONVERT_EXPR_CODE_P (gimple_assign_rhs_code (g
)))
301 tree t
= gimple_assign_rhs1 (g
);
302 if (INTEGRAL_TYPE_P (TREE_TYPE (t
))
303 && TYPE_PRECISION (TREE_TYPE (t
)) <= prec
)
305 if (TYPE_UNSIGNED (TREE_TYPE (t
))
306 && TYPE_PRECISION (TREE_TYPE (t
)) < prec
)
308 prec
= TYPE_PRECISION (TREE_TYPE (t
));
317 if (TYPE_UNSIGNED (TREE_TYPE (arg
)))
319 /* For unsigned values, the "positive" range comes
320 below the "negative" range. */
321 if (!wi::neg_p (wi::sext (arg_max
, prec
), SIGNED
))
323 if (wi::neg_p (wi::sext (arg_min
, prec
), SIGNED
))
328 if (!wi::neg_p (wi::sext (arg_min
, prec
), SIGNED
))
330 if (wi::neg_p (wi::sext (arg_max
, prec
), SIGNED
))
336 /* Return minimum precision needed to represent all values
337 of ARG in SIGNed integral type. */
340 get_min_precision (tree arg
, signop sign
)
342 int prec
= TYPE_PRECISION (TREE_TYPE (arg
));
344 signop orig_sign
= sign
;
345 if (TREE_CODE (arg
) == INTEGER_CST
)
348 if (TYPE_SIGN (TREE_TYPE (arg
)) != sign
)
350 widest_int w
= wi::to_widest (arg
);
351 w
= wi::ext (w
, prec
, sign
);
352 p
= wi::min_precision (w
, sign
);
355 p
= wi::min_precision (arg
, sign
);
356 return MIN (p
, prec
);
358 while (CONVERT_EXPR_P (arg
)
359 && INTEGRAL_TYPE_P (TREE_TYPE (TREE_OPERAND (arg
, 0)))
360 && TYPE_PRECISION (TREE_TYPE (TREE_OPERAND (arg
, 0))) <= prec
)
362 arg
= TREE_OPERAND (arg
, 0);
363 if (TYPE_PRECISION (TREE_TYPE (arg
)) < prec
)
365 if (TYPE_UNSIGNED (TREE_TYPE (arg
)))
367 else if (sign
== UNSIGNED
&& get_range_pos_neg (arg
) != 1)
368 return prec
+ (orig_sign
!= sign
);
369 prec
= TYPE_PRECISION (TREE_TYPE (arg
));
372 return prec
+ (orig_sign
!= sign
);
374 if (TREE_CODE (arg
) != SSA_NAME
)
375 return prec
+ (orig_sign
!= sign
);
376 wide_int arg_min
, arg_max
;
377 while (get_range_info (arg
, &arg_min
, &arg_max
) != VR_RANGE
)
379 gimple
*g
= SSA_NAME_DEF_STMT (arg
);
380 if (is_gimple_assign (g
)
381 && CONVERT_EXPR_CODE_P (gimple_assign_rhs_code (g
)))
383 tree t
= gimple_assign_rhs1 (g
);
384 if (INTEGRAL_TYPE_P (TREE_TYPE (t
))
385 && TYPE_PRECISION (TREE_TYPE (t
)) <= prec
)
388 if (TYPE_PRECISION (TREE_TYPE (arg
)) < prec
)
390 if (TYPE_UNSIGNED (TREE_TYPE (arg
)))
392 else if (sign
== UNSIGNED
&& get_range_pos_neg (arg
) != 1)
393 return prec
+ (orig_sign
!= sign
);
394 prec
= TYPE_PRECISION (TREE_TYPE (arg
));
397 return prec
+ (orig_sign
!= sign
);
401 return prec
+ (orig_sign
!= sign
);
403 if (sign
== TYPE_SIGN (TREE_TYPE (arg
)))
405 int p1
= wi::min_precision (arg_min
, sign
);
406 int p2
= wi::min_precision (arg_max
, sign
);
408 prec
= MIN (prec
, p1
);
410 else if (sign
== UNSIGNED
&& !wi::neg_p (arg_min
, SIGNED
))
412 int p
= wi::min_precision (arg_max
, UNSIGNED
);
413 prec
= MIN (prec
, p
);
415 return prec
+ (orig_sign
!= sign
);
418 /* Helper for expand_*_overflow. Set the __imag__ part to true
419 (1 except for signed:1 type, in which case store -1). */
422 expand_arith_set_overflow (tree lhs
, rtx target
)
424 if (TYPE_PRECISION (TREE_TYPE (TREE_TYPE (lhs
))) == 1
425 && !TYPE_UNSIGNED (TREE_TYPE (TREE_TYPE (lhs
))))
426 write_complex_part (target
, constm1_rtx
, true);
428 write_complex_part (target
, const1_rtx
, true);
431 /* Helper for expand_*_overflow. Store RES into the __real__ part
432 of TARGET. If RES has larger MODE than __real__ part of TARGET,
433 set the __imag__ part to 1 if RES doesn't fit into it. Similarly
434 if LHS has smaller precision than its mode. */
437 expand_arith_overflow_result_store (tree lhs
, rtx target
,
438 machine_mode mode
, rtx res
)
440 machine_mode tgtmode
= GET_MODE_INNER (GET_MODE (target
));
444 rtx_code_label
*done_label
= gen_label_rtx ();
445 int uns
= TYPE_UNSIGNED (TREE_TYPE (TREE_TYPE (lhs
)));
446 lres
= convert_modes (tgtmode
, mode
, res
, uns
);
447 gcc_assert (GET_MODE_PRECISION (tgtmode
) < GET_MODE_PRECISION (mode
));
448 do_compare_rtx_and_jump (res
, convert_modes (mode
, tgtmode
, lres
, uns
),
449 EQ
, true, mode
, NULL_RTX
, NULL
, done_label
,
451 expand_arith_set_overflow (lhs
, target
);
452 emit_label (done_label
);
454 int prec
= TYPE_PRECISION (TREE_TYPE (TREE_TYPE (lhs
)));
455 int tgtprec
= GET_MODE_PRECISION (tgtmode
);
458 rtx_code_label
*done_label
= gen_label_rtx ();
459 int uns
= TYPE_UNSIGNED (TREE_TYPE (TREE_TYPE (lhs
)));
464 = immed_wide_int_const (wi::shifted_mask (0, prec
, false, tgtprec
),
466 lres
= expand_simple_binop (tgtmode
, AND
, res
, mask
, NULL_RTX
,
467 true, OPTAB_LIB_WIDEN
);
471 lres
= expand_shift (LSHIFT_EXPR
, tgtmode
, res
, tgtprec
- prec
,
473 lres
= expand_shift (RSHIFT_EXPR
, tgtmode
, lres
, tgtprec
- prec
,
476 do_compare_rtx_and_jump (res
, lres
,
477 EQ
, true, tgtmode
, NULL_RTX
, NULL
, done_label
,
479 expand_arith_set_overflow (lhs
, target
);
480 emit_label (done_label
);
482 write_complex_part (target
, lres
, false);
485 /* Helper for expand_*_overflow. Store RES into TARGET. */
488 expand_ubsan_result_store (rtx target
, rtx res
)
490 if (GET_CODE (target
) == SUBREG
&& SUBREG_PROMOTED_VAR_P (target
))
491 /* If this is a scalar in a register that is stored in a wider mode
492 than the declared mode, compute the result into its declared mode
493 and then convert to the wider mode. Our value is the computed
495 convert_move (SUBREG_REG (target
), res
, SUBREG_PROMOTED_SIGN (target
));
497 emit_move_insn (target
, res
);
500 /* Add sub/add overflow checking to the statement STMT.
501 CODE says whether the operation is +, or -. */
504 expand_addsub_overflow (location_t loc
, tree_code code
, tree lhs
,
505 tree arg0
, tree arg1
, bool unsr_p
, bool uns0_p
,
506 bool uns1_p
, bool is_ubsan
)
508 rtx res
, target
= NULL_RTX
;
510 rtx_code_label
*done_label
= gen_label_rtx ();
511 rtx_code_label
*do_error
= gen_label_rtx ();
512 do_pending_stack_adjust ();
513 rtx op0
= expand_normal (arg0
);
514 rtx op1
= expand_normal (arg1
);
515 machine_mode mode
= TYPE_MODE (TREE_TYPE (arg0
));
516 int prec
= GET_MODE_PRECISION (mode
);
517 rtx sgn
= immed_wide_int_const (wi::min_value (prec
, SIGNED
), mode
);
521 gcc_assert (!unsr_p
&& !uns0_p
&& !uns1_p
);
525 target
= expand_expr (lhs
, NULL_RTX
, VOIDmode
, EXPAND_WRITE
);
527 write_complex_part (target
, const0_rtx
, true);
530 /* We assume both operands and result have the same precision
531 here (GET_MODE_BITSIZE (mode)), S stands for signed type
532 with that precision, U for unsigned type with that precision,
533 sgn for unsigned most significant bit in that precision.
534 s1 is signed first operand, u1 is unsigned first operand,
535 s2 is signed second operand, u2 is unsigned second operand,
536 sr is signed result, ur is unsigned result and the following
537 rules say how to compute result (which is always result of
538 the operands as if both were unsigned, cast to the right
539 signedness) and how to compute whether operation overflowed.
542 res = (S) ((U) s1 + (U) s2)
543 ovf = s2 < 0 ? res > s1 : res < s1 (or jump on overflow)
545 res = (S) ((U) s1 - (U) s2)
546 ovf = s2 < 0 ? res < s1 : res > s2 (or jump on overflow)
549 ovf = res < u1 (or jump on carry, but RTL opts will handle it)
552 ovf = res > u1 (or jump on carry, but RTL opts will handle it)
554 res = (S) ((U) s1 + u2)
555 ovf = ((U) res ^ sgn) < u2
560 ovf = t1 < 0 ? t2 > s1 : t2 < s1 (or jump on overflow)
562 res = (S) ((U) s1 - u2)
563 ovf = u2 > ((U) s1 ^ sgn)
566 ovf = s1 < 0 || u2 > (U) s1
569 ovf = u1 >= ((U) s2 ^ sgn)
574 ovf = s2 < 0 ? (S) t2 < (S) t1 : (S) t2 > (S) t1 (or jump on overflow)
576 res = (U) s1 + (U) s2
577 ovf = s2 < 0 ? (s1 | (S) res) < 0) : (s1 & (S) res) < 0)
580 ovf = (U) res < u2 || res < 0
583 ovf = u1 >= u2 ? res < 0 : res >= 0
585 res = (U) s1 - (U) s2
586 ovf = s2 >= 0 ? ((s1 | (S) res) < 0) : ((s1 & (S) res) < 0) */
588 if (code
== PLUS_EXPR
&& uns0_p
&& !uns1_p
)
590 /* PLUS_EXPR is commutative, if operand signedness differs,
591 canonicalize to the first operand being signed and second
592 unsigned to simplify following code. */
593 std::swap (op0
, op1
);
594 std::swap (arg0
, arg1
);
600 if (uns0_p
&& uns1_p
&& unsr_p
)
602 insn_code icode
= optab_handler (code
== PLUS_EXPR
? uaddv4_optab
603 : usubv4_optab
, mode
);
604 if (icode
!= CODE_FOR_nothing
)
606 struct expand_operand ops
[4];
607 rtx_insn
*last
= get_last_insn ();
609 res
= gen_reg_rtx (mode
);
610 create_output_operand (&ops
[0], res
, mode
);
611 create_input_operand (&ops
[1], op0
, mode
);
612 create_input_operand (&ops
[2], op1
, mode
);
613 create_fixed_operand (&ops
[3], do_error
);
614 if (maybe_expand_insn (icode
, 4, ops
))
616 last
= get_last_insn ();
617 if (profile_status_for_fn (cfun
) != PROFILE_ABSENT
619 && any_condjump_p (last
)
620 && !find_reg_note (last
, REG_BR_PROB
, 0))
621 add_int_reg_note (last
, REG_BR_PROB
, PROB_VERY_UNLIKELY
);
622 emit_jump (done_label
);
626 delete_insns_since (last
);
629 /* Compute the operation. On RTL level, the addition is always
631 res
= expand_binop (mode
, code
== PLUS_EXPR
? add_optab
: sub_optab
,
632 op0
, op1
, NULL_RTX
, false, OPTAB_LIB_WIDEN
);
634 /* For PLUS_EXPR, the operation is commutative, so we can pick
635 operand to compare against. For prec <= BITS_PER_WORD, I think
636 preferring REG operand is better over CONST_INT, because
637 the CONST_INT might enlarge the instruction or CSE would need
638 to figure out we'd already loaded it into a register before.
639 For prec > BITS_PER_WORD, I think CONST_INT might be more beneficial,
640 as then the multi-word comparison can be perhaps simplified. */
641 if (code
== PLUS_EXPR
642 && (prec
<= BITS_PER_WORD
643 ? (CONST_SCALAR_INT_P (op0
) && REG_P (op1
))
644 : CONST_SCALAR_INT_P (op1
)))
646 do_compare_rtx_and_jump (res
, tem
, code
== PLUS_EXPR
? GEU
: LEU
,
647 true, mode
, NULL_RTX
, NULL
, done_label
,
653 if (!uns0_p
&& uns1_p
&& !unsr_p
)
655 /* Compute the operation. On RTL level, the addition is always
657 res
= expand_binop (mode
, code
== PLUS_EXPR
? add_optab
: sub_optab
,
658 op0
, op1
, NULL_RTX
, false, OPTAB_LIB_WIDEN
);
659 rtx tem
= expand_binop (mode
, add_optab
,
660 code
== PLUS_EXPR
? res
: op0
, sgn
,
661 NULL_RTX
, false, OPTAB_LIB_WIDEN
);
662 do_compare_rtx_and_jump (tem
, op1
, GEU
, true, mode
, NULL_RTX
, NULL
,
663 done_label
, PROB_VERY_LIKELY
);
668 if (code
== PLUS_EXPR
&& !uns0_p
&& uns1_p
&& unsr_p
)
670 op1
= expand_binop (mode
, add_optab
, op1
, sgn
, NULL_RTX
, false,
672 /* As we've changed op1, we have to avoid using the value range
673 for the original argument. */
674 arg1
= error_mark_node
;
680 if (code
== MINUS_EXPR
&& uns0_p
&& !uns1_p
&& unsr_p
)
682 op0
= expand_binop (mode
, add_optab
, op0
, sgn
, NULL_RTX
, false,
684 /* As we've changed op0, we have to avoid using the value range
685 for the original argument. */
686 arg0
= error_mark_node
;
692 if (code
== MINUS_EXPR
&& !uns0_p
&& uns1_p
&& unsr_p
)
694 /* Compute the operation. On RTL level, the addition is always
696 res
= expand_binop (mode
, sub_optab
, op0
, op1
, NULL_RTX
, false,
698 int pos_neg
= get_range_pos_neg (arg0
);
700 /* If ARG0 is known to be always negative, this is always overflow. */
701 emit_jump (do_error
);
702 else if (pos_neg
== 3)
703 /* If ARG0 is not known to be always positive, check at runtime. */
704 do_compare_rtx_and_jump (op0
, const0_rtx
, LT
, false, mode
, NULL_RTX
,
705 NULL
, do_error
, PROB_VERY_UNLIKELY
);
706 do_compare_rtx_and_jump (op1
, op0
, LEU
, true, mode
, NULL_RTX
, NULL
,
707 done_label
, PROB_VERY_LIKELY
);
712 if (code
== MINUS_EXPR
&& uns0_p
&& !uns1_p
&& !unsr_p
)
714 /* Compute the operation. On RTL level, the addition is always
716 res
= expand_binop (mode
, sub_optab
, op0
, op1
, NULL_RTX
, false,
718 rtx tem
= expand_binop (mode
, add_optab
, op1
, sgn
, NULL_RTX
, false,
720 do_compare_rtx_and_jump (op0
, tem
, LTU
, true, mode
, NULL_RTX
, NULL
,
721 done_label
, PROB_VERY_LIKELY
);
726 if (code
== PLUS_EXPR
&& uns0_p
&& uns1_p
&& !unsr_p
)
728 /* Compute the operation. On RTL level, the addition is always
730 res
= expand_binop (mode
, add_optab
, op0
, op1
, NULL_RTX
, false,
732 do_compare_rtx_and_jump (res
, const0_rtx
, LT
, false, mode
, NULL_RTX
,
733 NULL
, do_error
, PROB_VERY_UNLIKELY
);
735 /* The operation is commutative, so we can pick operand to compare
736 against. For prec <= BITS_PER_WORD, I think preferring REG operand
737 is better over CONST_INT, because the CONST_INT might enlarge the
738 instruction or CSE would need to figure out we'd already loaded it
739 into a register before. For prec > BITS_PER_WORD, I think CONST_INT
740 might be more beneficial, as then the multi-word comparison can be
741 perhaps simplified. */
742 if (prec
<= BITS_PER_WORD
743 ? (CONST_SCALAR_INT_P (op1
) && REG_P (op0
))
744 : CONST_SCALAR_INT_P (op0
))
746 do_compare_rtx_and_jump (res
, tem
, GEU
, true, mode
, NULL_RTX
, NULL
,
747 done_label
, PROB_VERY_LIKELY
);
752 if (!uns0_p
&& !uns1_p
&& unsr_p
)
754 /* Compute the operation. On RTL level, the addition is always
756 res
= expand_binop (mode
, code
== PLUS_EXPR
? add_optab
: sub_optab
,
757 op0
, op1
, NULL_RTX
, false, OPTAB_LIB_WIDEN
);
758 int pos_neg
= get_range_pos_neg (arg1
);
759 if (code
== PLUS_EXPR
)
761 int pos_neg0
= get_range_pos_neg (arg0
);
762 if (pos_neg0
!= 3 && pos_neg
== 3)
764 std::swap (op0
, op1
);
771 tem
= expand_binop (mode
, ((pos_neg
== 1) ^ (code
== MINUS_EXPR
))
772 ? and_optab
: ior_optab
,
773 op0
, res
, NULL_RTX
, false, OPTAB_LIB_WIDEN
);
774 do_compare_rtx_and_jump (tem
, const0_rtx
, GE
, false, mode
, NULL
,
775 NULL
, done_label
, PROB_VERY_LIKELY
);
779 rtx_code_label
*do_ior_label
= gen_label_rtx ();
780 do_compare_rtx_and_jump (op1
, const0_rtx
,
781 code
== MINUS_EXPR
? GE
: LT
, false, mode
,
782 NULL_RTX
, NULL
, do_ior_label
,
784 tem
= expand_binop (mode
, and_optab
, op0
, res
, NULL_RTX
, false,
786 do_compare_rtx_and_jump (tem
, const0_rtx
, GE
, false, mode
, NULL_RTX
,
787 NULL
, done_label
, PROB_VERY_LIKELY
);
788 emit_jump (do_error
);
789 emit_label (do_ior_label
);
790 tem
= expand_binop (mode
, ior_optab
, op0
, res
, NULL_RTX
, false,
792 do_compare_rtx_and_jump (tem
, const0_rtx
, GE
, false, mode
, NULL_RTX
,
793 NULL
, done_label
, PROB_VERY_LIKELY
);
799 if (code
== MINUS_EXPR
&& uns0_p
&& uns1_p
&& !unsr_p
)
801 /* Compute the operation. On RTL level, the addition is always
803 res
= expand_binop (mode
, sub_optab
, op0
, op1
, NULL_RTX
, false,
805 rtx_code_label
*op0_geu_op1
= gen_label_rtx ();
806 do_compare_rtx_and_jump (op0
, op1
, GEU
, true, mode
, NULL_RTX
, NULL
,
807 op0_geu_op1
, PROB_EVEN
);
808 do_compare_rtx_and_jump (res
, const0_rtx
, LT
, false, mode
, NULL_RTX
,
809 NULL
, done_label
, PROB_VERY_LIKELY
);
810 emit_jump (do_error
);
811 emit_label (op0_geu_op1
);
812 do_compare_rtx_and_jump (res
, const0_rtx
, GE
, false, mode
, NULL_RTX
,
813 NULL
, done_label
, PROB_VERY_LIKELY
);
817 gcc_assert (!uns0_p
&& !uns1_p
&& !unsr_p
);
822 insn_code icode
= optab_handler (code
== PLUS_EXPR
? addv4_optab
823 : subv4_optab
, mode
);
824 if (icode
!= CODE_FOR_nothing
)
826 struct expand_operand ops
[4];
827 rtx_insn
*last
= get_last_insn ();
829 res
= gen_reg_rtx (mode
);
830 create_output_operand (&ops
[0], res
, mode
);
831 create_input_operand (&ops
[1], op0
, mode
);
832 create_input_operand (&ops
[2], op1
, mode
);
833 create_fixed_operand (&ops
[3], do_error
);
834 if (maybe_expand_insn (icode
, 4, ops
))
836 last
= get_last_insn ();
837 if (profile_status_for_fn (cfun
) != PROFILE_ABSENT
839 && any_condjump_p (last
)
840 && !find_reg_note (last
, REG_BR_PROB
, 0))
841 add_int_reg_note (last
, REG_BR_PROB
, PROB_VERY_UNLIKELY
);
842 emit_jump (done_label
);
846 delete_insns_since (last
);
849 rtx_code_label
*sub_check
= gen_label_rtx ();
852 /* Compute the operation. On RTL level, the addition is always
854 res
= expand_binop (mode
, code
== PLUS_EXPR
? add_optab
: sub_optab
,
855 op0
, op1
, NULL_RTX
, false, OPTAB_LIB_WIDEN
);
857 /* If we can prove one of the arguments (for MINUS_EXPR only
858 the second operand, as subtraction is not commutative) is always
859 non-negative or always negative, we can do just one comparison
860 and conditional jump instead of 2 at runtime, 3 present in the
861 emitted code. If one of the arguments is CONST_INT, all we
862 need is to make sure it is op1, then the first
863 do_compare_rtx_and_jump will be just folded. Otherwise try
864 to use range info if available. */
865 if (code
== PLUS_EXPR
&& CONST_INT_P (op0
))
866 std::swap (op0
, op1
);
867 else if (CONST_INT_P (op1
))
869 else if (code
== PLUS_EXPR
&& TREE_CODE (arg0
) == SSA_NAME
)
871 pos_neg
= get_range_pos_neg (arg0
);
873 std::swap (op0
, op1
);
875 if (pos_neg
== 3 && !CONST_INT_P (op1
) && TREE_CODE (arg1
) == SSA_NAME
)
876 pos_neg
= get_range_pos_neg (arg1
);
878 /* If the op1 is negative, we have to use a different check. */
880 do_compare_rtx_and_jump (op1
, const0_rtx
, LT
, false, mode
, NULL_RTX
,
881 NULL
, sub_check
, PROB_EVEN
);
883 /* Compare the result of the operation with one of the operands. */
885 do_compare_rtx_and_jump (res
, op0
, code
== PLUS_EXPR
? GE
: LE
,
886 false, mode
, NULL_RTX
, NULL
, done_label
,
889 /* If we get here, we have to print the error. */
892 emit_jump (do_error
);
893 emit_label (sub_check
);
896 /* We have k = a + b for b < 0 here. k <= a must hold. */
898 do_compare_rtx_and_jump (res
, op0
, code
== PLUS_EXPR
? LE
: GE
,
899 false, mode
, NULL_RTX
, NULL
, done_label
,
904 emit_label (do_error
);
907 /* Expand the ubsan builtin call. */
909 fn
= ubsan_build_overflow_builtin (code
, loc
, TREE_TYPE (arg0
),
913 do_pending_stack_adjust ();
916 expand_arith_set_overflow (lhs
, target
);
919 emit_label (done_label
);
924 expand_ubsan_result_store (target
, res
);
928 res
= expand_binop (mode
, add_optab
, res
, sgn
, NULL_RTX
, false,
931 expand_arith_overflow_result_store (lhs
, target
, mode
, res
);
936 /* Add negate overflow checking to the statement STMT. */
939 expand_neg_overflow (location_t loc
, tree lhs
, tree arg1
, bool is_ubsan
)
943 rtx_code_label
*done_label
, *do_error
;
944 rtx target
= NULL_RTX
;
946 done_label
= gen_label_rtx ();
947 do_error
= gen_label_rtx ();
949 do_pending_stack_adjust ();
950 op1
= expand_normal (arg1
);
952 machine_mode mode
= TYPE_MODE (TREE_TYPE (arg1
));
955 target
= expand_expr (lhs
, NULL_RTX
, VOIDmode
, EXPAND_WRITE
);
957 write_complex_part (target
, const0_rtx
, true);
960 enum insn_code icode
= optab_handler (negv3_optab
, mode
);
961 if (icode
!= CODE_FOR_nothing
)
963 struct expand_operand ops
[3];
964 rtx_insn
*last
= get_last_insn ();
966 res
= gen_reg_rtx (mode
);
967 create_output_operand (&ops
[0], res
, mode
);
968 create_input_operand (&ops
[1], op1
, mode
);
969 create_fixed_operand (&ops
[2], do_error
);
970 if (maybe_expand_insn (icode
, 3, ops
))
972 last
= get_last_insn ();
973 if (profile_status_for_fn (cfun
) != PROFILE_ABSENT
975 && any_condjump_p (last
)
976 && !find_reg_note (last
, REG_BR_PROB
, 0))
977 add_int_reg_note (last
, REG_BR_PROB
, PROB_VERY_UNLIKELY
);
978 emit_jump (done_label
);
982 delete_insns_since (last
);
983 icode
= CODE_FOR_nothing
;
987 if (icode
== CODE_FOR_nothing
)
989 /* Compute the operation. On RTL level, the addition is always
991 res
= expand_unop (mode
, neg_optab
, op1
, NULL_RTX
, false);
993 /* Compare the operand with the most negative value. */
994 rtx minv
= expand_normal (TYPE_MIN_VALUE (TREE_TYPE (arg1
)));
995 do_compare_rtx_and_jump (op1
, minv
, NE
, true, mode
, NULL_RTX
, NULL
,
996 done_label
, PROB_VERY_LIKELY
);
999 emit_label (do_error
);
1002 /* Expand the ubsan builtin call. */
1004 fn
= ubsan_build_overflow_builtin (NEGATE_EXPR
, loc
, TREE_TYPE (arg1
),
1008 do_pending_stack_adjust ();
1011 expand_arith_set_overflow (lhs
, target
);
1014 emit_label (done_label
);
1019 expand_ubsan_result_store (target
, res
);
1021 expand_arith_overflow_result_store (lhs
, target
, mode
, res
);
1025 /* Add mul overflow checking to the statement STMT. */
1028 expand_mul_overflow (location_t loc
, tree lhs
, tree arg0
, tree arg1
,
1029 bool unsr_p
, bool uns0_p
, bool uns1_p
, bool is_ubsan
)
1033 rtx_code_label
*done_label
, *do_error
;
1034 rtx target
= NULL_RTX
;
1036 enum insn_code icode
;
1038 done_label
= gen_label_rtx ();
1039 do_error
= gen_label_rtx ();
1041 do_pending_stack_adjust ();
1042 op0
= expand_normal (arg0
);
1043 op1
= expand_normal (arg1
);
1045 machine_mode mode
= TYPE_MODE (TREE_TYPE (arg0
));
1049 target
= expand_expr (lhs
, NULL_RTX
, VOIDmode
, EXPAND_WRITE
);
1051 write_complex_part (target
, const0_rtx
, true);
1055 gcc_assert (!unsr_p
&& !uns0_p
&& !uns1_p
);
1057 /* We assume both operands and result have the same precision
1058 here (GET_MODE_BITSIZE (mode)), S stands for signed type
1059 with that precision, U for unsigned type with that precision,
1060 sgn for unsigned most significant bit in that precision.
1061 s1 is signed first operand, u1 is unsigned first operand,
1062 s2 is signed second operand, u2 is unsigned second operand,
1063 sr is signed result, ur is unsigned result and the following
1064 rules say how to compute result (which is always result of
1065 the operands as if both were unsigned, cast to the right
1066 signedness) and how to compute whether operation overflowed.
1067 main_ovf (false) stands for jump on signed multiplication
1068 overflow or the main algorithm with uns == false.
1069 main_ovf (true) stands for jump on unsigned multiplication
1070 overflow or the main algorithm with uns == true.
1073 res = (S) ((U) s1 * (U) s2)
1074 ovf = main_ovf (false)
1077 ovf = main_ovf (true)
1080 ovf = (s1 < 0 && u2) || main_ovf (true)
1083 ovf = res < 0 || main_ovf (true)
1085 res = (S) ((U) s1 * u2)
1086 ovf = (S) u2 >= 0 ? main_ovf (false)
1087 : (s1 != 0 && (s1 != -1 || u2 != (U) res))
1089 t1 = (s1 & s2) < 0 ? (-(U) s1) : ((U) s1)
1090 t2 = (s1 & s2) < 0 ? (-(U) s2) : ((U) s2)
1092 ovf = (s1 ^ s2) < 0 ? (s1 && s2) : main_ovf (true) */
1094 if (uns0_p
&& !uns1_p
)
1096 /* Multiplication is commutative, if operand signedness differs,
1097 canonicalize to the first operand being signed and second
1098 unsigned to simplify following code. */
1099 std::swap (op0
, op1
);
1100 std::swap (arg0
, arg1
);
1105 int pos_neg0
= get_range_pos_neg (arg0
);
1106 int pos_neg1
= get_range_pos_neg (arg1
);
1109 if (!uns0_p
&& uns1_p
&& unsr_p
)
1114 /* If s1 is non-negative, just perform normal u1 * u2 -> ur. */
1117 /* If s1 is negative, avoid the main code, just multiply and
1118 signal overflow if op1 is not 0. */
1119 struct separate_ops ops
;
1120 ops
.code
= MULT_EXPR
;
1121 ops
.type
= TREE_TYPE (arg1
);
1122 ops
.op0
= make_tree (ops
.type
, op0
);
1123 ops
.op1
= make_tree (ops
.type
, op1
);
1124 ops
.op2
= NULL_TREE
;
1126 res
= expand_expr_real_2 (&ops
, NULL_RTX
, mode
, EXPAND_NORMAL
);
1127 do_compare_rtx_and_jump (op1
, const0_rtx
, EQ
, true, mode
, NULL_RTX
,
1128 NULL
, done_label
, PROB_VERY_LIKELY
);
1129 goto do_error_label
;
1131 rtx_code_label
*do_main_label
;
1132 do_main_label
= gen_label_rtx ();
1133 do_compare_rtx_and_jump (op0
, const0_rtx
, GE
, false, mode
, NULL_RTX
,
1134 NULL
, do_main_label
, PROB_VERY_LIKELY
);
1135 do_compare_rtx_and_jump (op1
, const0_rtx
, EQ
, true, mode
, NULL_RTX
,
1136 NULL
, do_main_label
, PROB_VERY_LIKELY
);
1137 expand_arith_set_overflow (lhs
, target
);
1138 emit_label (do_main_label
);
1146 if (uns0_p
&& uns1_p
&& !unsr_p
)
1149 /* Rest of handling of this case after res is computed. */
1154 if (!uns0_p
&& uns1_p
&& !unsr_p
)
1161 /* If (S) u2 is negative (i.e. u2 is larger than maximum of S,
1162 avoid the main code, just multiply and signal overflow
1163 unless 0 * u2 or -1 * ((U) Smin). */
1164 struct separate_ops ops
;
1165 ops
.code
= MULT_EXPR
;
1166 ops
.type
= TREE_TYPE (arg1
);
1167 ops
.op0
= make_tree (ops
.type
, op0
);
1168 ops
.op1
= make_tree (ops
.type
, op1
);
1169 ops
.op2
= NULL_TREE
;
1171 res
= expand_expr_real_2 (&ops
, NULL_RTX
, mode
, EXPAND_NORMAL
);
1172 do_compare_rtx_and_jump (op0
, const0_rtx
, EQ
, true, mode
, NULL_RTX
,
1173 NULL
, done_label
, PROB_VERY_LIKELY
);
1174 do_compare_rtx_and_jump (op0
, constm1_rtx
, NE
, true, mode
, NULL_RTX
,
1175 NULL
, do_error
, PROB_VERY_UNLIKELY
);
1177 prec
= GET_MODE_PRECISION (mode
);
1179 sgn
= immed_wide_int_const (wi::min_value (prec
, SIGNED
), mode
);
1180 do_compare_rtx_and_jump (op1
, sgn
, EQ
, true, mode
, NULL_RTX
,
1181 NULL
, done_label
, PROB_VERY_LIKELY
);
1182 goto do_error_label
;
1184 /* Rest of handling of this case after res is computed. */
1192 if (!uns0_p
&& !uns1_p
&& unsr_p
)
1195 switch (pos_neg0
| pos_neg1
)
1197 case 1: /* Both operands known to be non-negative. */
1199 case 2: /* Both operands known to be negative. */
1200 op0
= expand_unop (mode
, neg_optab
, op0
, NULL_RTX
, false);
1201 op1
= expand_unop (mode
, neg_optab
, op1
, NULL_RTX
, false);
1202 /* Avoid looking at arg0/arg1 ranges, as we've changed
1204 arg0
= error_mark_node
;
1205 arg1
= error_mark_node
;
1208 if ((pos_neg0
^ pos_neg1
) == 3)
1210 /* If one operand is known to be negative and the other
1211 non-negative, this overflows always, unless the non-negative
1212 one is 0. Just do normal multiply and set overflow
1213 unless one of the operands is 0. */
1214 struct separate_ops ops
;
1215 ops
.code
= MULT_EXPR
;
1217 = build_nonstandard_integer_type (GET_MODE_PRECISION (mode
),
1219 ops
.op0
= make_tree (ops
.type
, op0
);
1220 ops
.op1
= make_tree (ops
.type
, op1
);
1221 ops
.op2
= NULL_TREE
;
1223 res
= expand_expr_real_2 (&ops
, NULL_RTX
, mode
, EXPAND_NORMAL
);
1224 tem
= expand_binop (mode
, and_optab
, op0
, op1
, NULL_RTX
, false,
1226 do_compare_rtx_and_jump (tem
, const0_rtx
, EQ
, true, mode
,
1227 NULL_RTX
, NULL
, done_label
,
1229 goto do_error_label
;
1231 /* The general case, do all the needed comparisons at runtime. */
1232 rtx_code_label
*do_main_label
, *after_negate_label
;
1234 rop0
= gen_reg_rtx (mode
);
1235 rop1
= gen_reg_rtx (mode
);
1236 emit_move_insn (rop0
, op0
);
1237 emit_move_insn (rop1
, op1
);
1240 do_main_label
= gen_label_rtx ();
1241 after_negate_label
= gen_label_rtx ();
1242 tem
= expand_binop (mode
, and_optab
, op0
, op1
, NULL_RTX
, false,
1244 do_compare_rtx_and_jump (tem
, const0_rtx
, GE
, false, mode
, NULL_RTX
,
1245 NULL
, after_negate_label
, PROB_VERY_LIKELY
);
1246 /* Both arguments negative here, negate them and continue with
1247 normal unsigned overflow checking multiplication. */
1248 emit_move_insn (op0
, expand_unop (mode
, neg_optab
, op0
,
1250 emit_move_insn (op1
, expand_unop (mode
, neg_optab
, op1
,
1252 /* Avoid looking at arg0/arg1 ranges, as we might have changed
1254 arg0
= error_mark_node
;
1255 arg1
= error_mark_node
;
1256 emit_jump (do_main_label
);
1257 emit_label (after_negate_label
);
1258 tem2
= expand_binop (mode
, xor_optab
, op0
, op1
, NULL_RTX
, false,
1260 do_compare_rtx_and_jump (tem2
, const0_rtx
, GE
, false, mode
, NULL_RTX
,
1261 NULL
, do_main_label
, PROB_VERY_LIKELY
);
1262 /* One argument is negative here, the other positive. This
1263 overflows always, unless one of the arguments is 0. But
1264 if e.g. s2 is 0, (U) s1 * 0 doesn't overflow, whatever s1
1265 is, thus we can keep do_main code oring in overflow as is. */
1266 do_compare_rtx_and_jump (tem
, const0_rtx
, EQ
, true, mode
, NULL_RTX
,
1267 NULL
, do_main_label
, PROB_VERY_LIKELY
);
1268 expand_arith_set_overflow (lhs
, target
);
1269 emit_label (do_main_label
);
1277 type
= build_nonstandard_integer_type (GET_MODE_PRECISION (mode
), uns
);
1278 sign
= uns
? UNSIGNED
: SIGNED
;
1279 icode
= optab_handler (uns
? umulv4_optab
: mulv4_optab
, mode
);
1280 if (icode
!= CODE_FOR_nothing
)
1282 struct expand_operand ops
[4];
1283 rtx_insn
*last
= get_last_insn ();
1285 res
= gen_reg_rtx (mode
);
1286 create_output_operand (&ops
[0], res
, mode
);
1287 create_input_operand (&ops
[1], op0
, mode
);
1288 create_input_operand (&ops
[2], op1
, mode
);
1289 create_fixed_operand (&ops
[3], do_error
);
1290 if (maybe_expand_insn (icode
, 4, ops
))
1292 last
= get_last_insn ();
1293 if (profile_status_for_fn (cfun
) != PROFILE_ABSENT
1295 && any_condjump_p (last
)
1296 && !find_reg_note (last
, REG_BR_PROB
, 0))
1297 add_int_reg_note (last
, REG_BR_PROB
, PROB_VERY_UNLIKELY
);
1298 emit_jump (done_label
);
1302 delete_insns_since (last
);
1303 icode
= CODE_FOR_nothing
;
1307 if (icode
== CODE_FOR_nothing
)
1309 struct separate_ops ops
;
1310 int prec
= GET_MODE_PRECISION (mode
);
1311 machine_mode hmode
= mode_for_size (prec
/ 2, MODE_INT
, 1);
1312 ops
.op0
= make_tree (type
, op0
);
1313 ops
.op1
= make_tree (type
, op1
);
1314 ops
.op2
= NULL_TREE
;
1316 if (GET_MODE_2XWIDER_MODE (mode
) != VOIDmode
1317 && targetm
.scalar_mode_supported_p (GET_MODE_2XWIDER_MODE (mode
)))
1319 machine_mode wmode
= GET_MODE_2XWIDER_MODE (mode
);
1320 ops
.code
= WIDEN_MULT_EXPR
;
1322 = build_nonstandard_integer_type (GET_MODE_PRECISION (wmode
), uns
);
1324 res
= expand_expr_real_2 (&ops
, NULL_RTX
, wmode
, EXPAND_NORMAL
);
1325 rtx hipart
= expand_shift (RSHIFT_EXPR
, wmode
, res
, prec
,
1327 hipart
= gen_lowpart (mode
, hipart
);
1328 res
= gen_lowpart (mode
, res
);
1330 /* For the unsigned multiplication, there was overflow if
1331 HIPART is non-zero. */
1332 do_compare_rtx_and_jump (hipart
, const0_rtx
, EQ
, true, mode
,
1333 NULL_RTX
, NULL
, done_label
,
1337 rtx signbit
= expand_shift (RSHIFT_EXPR
, mode
, res
, prec
- 1,
1339 /* RES is low half of the double width result, HIPART
1340 the high half. There was overflow if
1341 HIPART is different from RES < 0 ? -1 : 0. */
1342 do_compare_rtx_and_jump (signbit
, hipart
, EQ
, true, mode
,
1343 NULL_RTX
, NULL
, done_label
,
1347 else if (hmode
!= BLKmode
&& 2 * GET_MODE_PRECISION (hmode
) == prec
)
1349 rtx_code_label
*large_op0
= gen_label_rtx ();
1350 rtx_code_label
*small_op0_large_op1
= gen_label_rtx ();
1351 rtx_code_label
*one_small_one_large
= gen_label_rtx ();
1352 rtx_code_label
*both_ops_large
= gen_label_rtx ();
1353 rtx_code_label
*after_hipart_neg
= uns
? NULL
: gen_label_rtx ();
1354 rtx_code_label
*after_lopart_neg
= uns
? NULL
: gen_label_rtx ();
1355 rtx_code_label
*do_overflow
= gen_label_rtx ();
1356 rtx_code_label
*hipart_different
= uns
? NULL
: gen_label_rtx ();
1358 unsigned int hprec
= GET_MODE_PRECISION (hmode
);
1359 rtx hipart0
= expand_shift (RSHIFT_EXPR
, mode
, op0
, hprec
,
1361 hipart0
= gen_lowpart (hmode
, hipart0
);
1362 rtx lopart0
= gen_lowpart (hmode
, op0
);
1363 rtx signbit0
= const0_rtx
;
1365 signbit0
= expand_shift (RSHIFT_EXPR
, hmode
, lopart0
, hprec
- 1,
1367 rtx hipart1
= expand_shift (RSHIFT_EXPR
, mode
, op1
, hprec
,
1369 hipart1
= gen_lowpart (hmode
, hipart1
);
1370 rtx lopart1
= gen_lowpart (hmode
, op1
);
1371 rtx signbit1
= const0_rtx
;
1373 signbit1
= expand_shift (RSHIFT_EXPR
, hmode
, lopart1
, hprec
- 1,
1376 res
= gen_reg_rtx (mode
);
1378 /* True if op0 resp. op1 are known to be in the range of
1380 bool op0_small_p
= false;
1381 bool op1_small_p
= false;
1382 /* True if op0 resp. op1 are known to have all zeros or all ones
1383 in the upper half of bits, but are not known to be
1385 bool op0_medium_p
= false;
1386 bool op1_medium_p
= false;
1387 /* -1 if op{0,1} is known to be negative, 0 if it is known to be
1388 nonnegative, 1 if unknown. */
1394 else if (pos_neg0
== 2)
1398 else if (pos_neg1
== 2)
1401 unsigned int mprec0
= prec
;
1402 if (arg0
!= error_mark_node
)
1403 mprec0
= get_min_precision (arg0
, sign
);
1404 if (mprec0
<= hprec
)
1406 else if (!uns
&& mprec0
<= hprec
+ 1)
1407 op0_medium_p
= true;
1408 unsigned int mprec1
= prec
;
1409 if (arg1
!= error_mark_node
)
1410 mprec1
= get_min_precision (arg1
, sign
);
1411 if (mprec1
<= hprec
)
1413 else if (!uns
&& mprec1
<= hprec
+ 1)
1414 op1_medium_p
= true;
1416 int smaller_sign
= 1;
1417 int larger_sign
= 1;
1420 smaller_sign
= op0_sign
;
1421 larger_sign
= op1_sign
;
1423 else if (op1_small_p
)
1425 smaller_sign
= op1_sign
;
1426 larger_sign
= op0_sign
;
1428 else if (op0_sign
== op1_sign
)
1430 smaller_sign
= op0_sign
;
1431 larger_sign
= op0_sign
;
1435 do_compare_rtx_and_jump (signbit0
, hipart0
, NE
, true, hmode
,
1436 NULL_RTX
, NULL
, large_op0
,
1440 do_compare_rtx_and_jump (signbit1
, hipart1
, NE
, true, hmode
,
1441 NULL_RTX
, NULL
, small_op0_large_op1
,
1444 /* If both op0 and op1 are sign (!uns) or zero (uns) extended from
1445 hmode to mode, the multiplication will never overflow. We can
1446 do just one hmode x hmode => mode widening multiplication. */
1447 rtx lopart0s
= lopart0
, lopart1s
= lopart1
;
1448 if (GET_CODE (lopart0
) == SUBREG
)
1450 lopart0s
= shallow_copy_rtx (lopart0
);
1451 SUBREG_PROMOTED_VAR_P (lopart0s
) = 1;
1452 SUBREG_PROMOTED_SET (lopart0s
, uns
? SRP_UNSIGNED
: SRP_SIGNED
);
1454 if (GET_CODE (lopart1
) == SUBREG
)
1456 lopart1s
= shallow_copy_rtx (lopart1
);
1457 SUBREG_PROMOTED_VAR_P (lopart1s
) = 1;
1458 SUBREG_PROMOTED_SET (lopart1s
, uns
? SRP_UNSIGNED
: SRP_SIGNED
);
1460 tree halfstype
= build_nonstandard_integer_type (hprec
, uns
);
1461 ops
.op0
= make_tree (halfstype
, lopart0s
);
1462 ops
.op1
= make_tree (halfstype
, lopart1s
);
1463 ops
.code
= WIDEN_MULT_EXPR
;
1466 = expand_expr_real_2 (&ops
, NULL_RTX
, mode
, EXPAND_NORMAL
);
1467 emit_move_insn (res
, thisres
);
1468 emit_jump (done_label
);
1470 emit_label (small_op0_large_op1
);
1472 /* If op0 is sign (!uns) or zero (uns) extended from hmode to mode,
1473 but op1 is not, just swap the arguments and handle it as op1
1474 sign/zero extended, op0 not. */
1475 rtx larger
= gen_reg_rtx (mode
);
1476 rtx hipart
= gen_reg_rtx (hmode
);
1477 rtx lopart
= gen_reg_rtx (hmode
);
1478 emit_move_insn (larger
, op1
);
1479 emit_move_insn (hipart
, hipart1
);
1480 emit_move_insn (lopart
, lopart0
);
1481 emit_jump (one_small_one_large
);
1483 emit_label (large_op0
);
1486 do_compare_rtx_and_jump (signbit1
, hipart1
, NE
, true, hmode
,
1487 NULL_RTX
, NULL
, both_ops_large
,
1490 /* If op1 is sign (!uns) or zero (uns) extended from hmode to mode,
1491 but op0 is not, prepare larger, hipart and lopart pseudos and
1492 handle it together with small_op0_large_op1. */
1493 emit_move_insn (larger
, op0
);
1494 emit_move_insn (hipart
, hipart0
);
1495 emit_move_insn (lopart
, lopart1
);
1497 emit_label (one_small_one_large
);
1499 /* lopart is the low part of the operand that is sign extended
1500 to mode, larger is the other operand, hipart is the
1501 high part of larger and lopart0 and lopart1 are the low parts
1503 We perform lopart0 * lopart1 and lopart * hipart widening
1505 tree halfutype
= build_nonstandard_integer_type (hprec
, 1);
1506 ops
.op0
= make_tree (halfutype
, lopart0
);
1507 ops
.op1
= make_tree (halfutype
, lopart1
);
1509 = expand_expr_real_2 (&ops
, NULL_RTX
, mode
, EXPAND_NORMAL
);
1511 ops
.op0
= make_tree (halfutype
, lopart
);
1512 ops
.op1
= make_tree (halfutype
, hipart
);
1513 rtx loxhi
= gen_reg_rtx (mode
);
1514 rtx tem
= expand_expr_real_2 (&ops
, NULL_RTX
, mode
, EXPAND_NORMAL
);
1515 emit_move_insn (loxhi
, tem
);
1519 /* if (hipart < 0) loxhi -= lopart << (bitsize / 2); */
1520 if (larger_sign
== 0)
1521 emit_jump (after_hipart_neg
);
1522 else if (larger_sign
!= -1)
1523 do_compare_rtx_and_jump (hipart
, const0_rtx
, GE
, false, hmode
,
1524 NULL_RTX
, NULL
, after_hipart_neg
,
1527 tem
= convert_modes (mode
, hmode
, lopart
, 1);
1528 tem
= expand_shift (LSHIFT_EXPR
, mode
, tem
, hprec
, NULL_RTX
, 1);
1529 tem
= expand_simple_binop (mode
, MINUS
, loxhi
, tem
, NULL_RTX
,
1531 emit_move_insn (loxhi
, tem
);
1533 emit_label (after_hipart_neg
);
1535 /* if (lopart < 0) loxhi -= larger; */
1536 if (smaller_sign
== 0)
1537 emit_jump (after_lopart_neg
);
1538 else if (smaller_sign
!= -1)
1539 do_compare_rtx_and_jump (lopart
, const0_rtx
, GE
, false, hmode
,
1540 NULL_RTX
, NULL
, after_lopart_neg
,
1543 tem
= expand_simple_binop (mode
, MINUS
, loxhi
, larger
, NULL_RTX
,
1545 emit_move_insn (loxhi
, tem
);
1547 emit_label (after_lopart_neg
);
1550 /* loxhi += (uns) lo0xlo1 >> (bitsize / 2); */
1551 tem
= expand_shift (RSHIFT_EXPR
, mode
, lo0xlo1
, hprec
, NULL_RTX
, 1);
1552 tem
= expand_simple_binop (mode
, PLUS
, loxhi
, tem
, NULL_RTX
,
1554 emit_move_insn (loxhi
, tem
);
1556 /* if (loxhi >> (bitsize / 2)
1557 == (hmode) loxhi >> (bitsize / 2 - 1)) (if !uns)
1558 if (loxhi >> (bitsize / 2) == 0 (if uns). */
1559 rtx hipartloxhi
= expand_shift (RSHIFT_EXPR
, mode
, loxhi
, hprec
,
1561 hipartloxhi
= gen_lowpart (hmode
, hipartloxhi
);
1562 rtx signbitloxhi
= const0_rtx
;
1564 signbitloxhi
= expand_shift (RSHIFT_EXPR
, hmode
,
1565 gen_lowpart (hmode
, loxhi
),
1566 hprec
- 1, NULL_RTX
, 0);
1568 do_compare_rtx_and_jump (signbitloxhi
, hipartloxhi
, NE
, true, hmode
,
1569 NULL_RTX
, NULL
, do_overflow
,
1570 PROB_VERY_UNLIKELY
);
1572 /* res = (loxhi << (bitsize / 2)) | (hmode) lo0xlo1; */
1573 rtx loxhishifted
= expand_shift (LSHIFT_EXPR
, mode
, loxhi
, hprec
,
1575 tem
= convert_modes (mode
, hmode
, gen_lowpart (hmode
, lo0xlo1
), 1);
1577 tem
= expand_simple_binop (mode
, IOR
, loxhishifted
, tem
, res
,
1580 emit_move_insn (res
, tem
);
1581 emit_jump (done_label
);
1583 emit_label (both_ops_large
);
1585 /* If both operands are large (not sign (!uns) or zero (uns)
1586 extended from hmode), then perform the full multiplication
1587 which will be the result of the operation.
1588 The only cases which don't overflow are for signed multiplication
1589 some cases where both hipart0 and highpart1 are 0 or -1.
1590 For unsigned multiplication when high parts are both non-zero
1591 this overflows always. */
1592 ops
.code
= MULT_EXPR
;
1593 ops
.op0
= make_tree (type
, op0
);
1594 ops
.op1
= make_tree (type
, op1
);
1595 tem
= expand_expr_real_2 (&ops
, NULL_RTX
, mode
, EXPAND_NORMAL
);
1596 emit_move_insn (res
, tem
);
1602 tem
= expand_simple_binop (hmode
, PLUS
, hipart0
, const1_rtx
,
1603 NULL_RTX
, 1, OPTAB_DIRECT
);
1604 do_compare_rtx_and_jump (tem
, const1_rtx
, GTU
, true, hmode
,
1605 NULL_RTX
, NULL
, do_error
,
1606 PROB_VERY_UNLIKELY
);
1611 tem
= expand_simple_binop (hmode
, PLUS
, hipart1
, const1_rtx
,
1612 NULL_RTX
, 1, OPTAB_DIRECT
);
1613 do_compare_rtx_and_jump (tem
, const1_rtx
, GTU
, true, hmode
,
1614 NULL_RTX
, NULL
, do_error
,
1615 PROB_VERY_UNLIKELY
);
1618 /* At this point hipart{0,1} are both in [-1, 0]. If they are
1619 the same, overflow happened if res is negative, if they are
1620 different, overflow happened if res is positive. */
1621 if (op0_sign
!= 1 && op1_sign
!= 1 && op0_sign
!= op1_sign
)
1622 emit_jump (hipart_different
);
1623 else if (op0_sign
== 1 || op1_sign
== 1)
1624 do_compare_rtx_and_jump (hipart0
, hipart1
, NE
, true, hmode
,
1625 NULL_RTX
, NULL
, hipart_different
,
1628 do_compare_rtx_and_jump (res
, const0_rtx
, LT
, false, mode
,
1629 NULL_RTX
, NULL
, do_error
,
1630 PROB_VERY_UNLIKELY
);
1631 emit_jump (done_label
);
1633 emit_label (hipart_different
);
1635 do_compare_rtx_and_jump (res
, const0_rtx
, GE
, false, mode
,
1636 NULL_RTX
, NULL
, do_error
,
1637 PROB_VERY_UNLIKELY
);
1638 emit_jump (done_label
);
1641 emit_label (do_overflow
);
1643 /* Overflow, do full multiplication and fallthru into do_error. */
1644 ops
.op0
= make_tree (type
, op0
);
1645 ops
.op1
= make_tree (type
, op1
);
1646 tem
= expand_expr_real_2 (&ops
, NULL_RTX
, mode
, EXPAND_NORMAL
);
1647 emit_move_insn (res
, tem
);
1651 gcc_assert (!is_ubsan
);
1652 ops
.code
= MULT_EXPR
;
1654 res
= expand_expr_real_2 (&ops
, NULL_RTX
, mode
, EXPAND_NORMAL
);
1655 emit_jump (done_label
);
1660 emit_label (do_error
);
1663 /* Expand the ubsan builtin call. */
1665 fn
= ubsan_build_overflow_builtin (MULT_EXPR
, loc
, TREE_TYPE (arg0
),
1669 do_pending_stack_adjust ();
1672 expand_arith_set_overflow (lhs
, target
);
1675 emit_label (done_label
);
1678 if (uns0_p
&& uns1_p
&& !unsr_p
)
1680 rtx_code_label
*all_done_label
= gen_label_rtx ();
1681 do_compare_rtx_and_jump (res
, const0_rtx
, GE
, false, mode
, NULL_RTX
,
1682 NULL
, all_done_label
, PROB_VERY_LIKELY
);
1683 expand_arith_set_overflow (lhs
, target
);
1684 emit_label (all_done_label
);
1688 if (!uns0_p
&& uns1_p
&& !unsr_p
&& pos_neg1
== 3)
1690 rtx_code_label
*all_done_label
= gen_label_rtx ();
1691 rtx_code_label
*set_noovf
= gen_label_rtx ();
1692 do_compare_rtx_and_jump (op1
, const0_rtx
, GE
, false, mode
, NULL_RTX
,
1693 NULL
, all_done_label
, PROB_VERY_LIKELY
);
1694 expand_arith_set_overflow (lhs
, target
);
1695 do_compare_rtx_and_jump (op0
, const0_rtx
, EQ
, true, mode
, NULL_RTX
,
1696 NULL
, set_noovf
, PROB_VERY_LIKELY
);
1697 do_compare_rtx_and_jump (op0
, constm1_rtx
, NE
, true, mode
, NULL_RTX
,
1698 NULL
, all_done_label
, PROB_VERY_UNLIKELY
);
1699 do_compare_rtx_and_jump (op1
, res
, NE
, true, mode
, NULL_RTX
, NULL
,
1700 all_done_label
, PROB_VERY_UNLIKELY
);
1701 emit_label (set_noovf
);
1702 write_complex_part (target
, const0_rtx
, true);
1703 emit_label (all_done_label
);
1709 expand_ubsan_result_store (target
, res
);
1711 expand_arith_overflow_result_store (lhs
, target
, mode
, res
);
1715 /* Expand UBSAN_CHECK_ADD call STMT. */
1718 expand_UBSAN_CHECK_ADD (internal_fn
, gcall
*stmt
)
1720 location_t loc
= gimple_location (stmt
);
1721 tree lhs
= gimple_call_lhs (stmt
);
1722 tree arg0
= gimple_call_arg (stmt
, 0);
1723 tree arg1
= gimple_call_arg (stmt
, 1);
1724 expand_addsub_overflow (loc
, PLUS_EXPR
, lhs
, arg0
, arg1
,
1725 false, false, false, true);
1728 /* Expand UBSAN_CHECK_SUB call STMT. */
1731 expand_UBSAN_CHECK_SUB (internal_fn
, gcall
*stmt
)
1733 location_t loc
= gimple_location (stmt
);
1734 tree lhs
= gimple_call_lhs (stmt
);
1735 tree arg0
= gimple_call_arg (stmt
, 0);
1736 tree arg1
= gimple_call_arg (stmt
, 1);
1737 if (integer_zerop (arg0
))
1738 expand_neg_overflow (loc
, lhs
, arg1
, true);
1740 expand_addsub_overflow (loc
, MINUS_EXPR
, lhs
, arg0
, arg1
,
1741 false, false, false, true);
1744 /* Expand UBSAN_CHECK_MUL call STMT. */
1747 expand_UBSAN_CHECK_MUL (internal_fn
, gcall
*stmt
)
1749 location_t loc
= gimple_location (stmt
);
1750 tree lhs
= gimple_call_lhs (stmt
);
1751 tree arg0
= gimple_call_arg (stmt
, 0);
1752 tree arg1
= gimple_call_arg (stmt
, 1);
1753 expand_mul_overflow (loc
, lhs
, arg0
, arg1
, false, false, false, true);
1756 /* Helper function for {ADD,SUB,MUL}_OVERFLOW call stmt expansion. */
1759 expand_arith_overflow (enum tree_code code
, gimple
*stmt
)
1761 tree lhs
= gimple_call_lhs (stmt
);
1762 if (lhs
== NULL_TREE
)
1764 tree arg0
= gimple_call_arg (stmt
, 0);
1765 tree arg1
= gimple_call_arg (stmt
, 1);
1766 tree type
= TREE_TYPE (TREE_TYPE (lhs
));
1767 int uns0_p
= TYPE_UNSIGNED (TREE_TYPE (arg0
));
1768 int uns1_p
= TYPE_UNSIGNED (TREE_TYPE (arg1
));
1769 int unsr_p
= TYPE_UNSIGNED (type
);
1770 int prec0
= TYPE_PRECISION (TREE_TYPE (arg0
));
1771 int prec1
= TYPE_PRECISION (TREE_TYPE (arg1
));
1772 int precres
= TYPE_PRECISION (type
);
1773 location_t loc
= gimple_location (stmt
);
1774 if (!uns0_p
&& get_range_pos_neg (arg0
) == 1)
1776 if (!uns1_p
&& get_range_pos_neg (arg1
) == 1)
1778 int pr
= get_min_precision (arg0
, uns0_p
? UNSIGNED
: SIGNED
);
1779 prec0
= MIN (prec0
, pr
);
1780 pr
= get_min_precision (arg1
, uns1_p
? UNSIGNED
: SIGNED
);
1781 prec1
= MIN (prec1
, pr
);
1783 /* If uns0_p && uns1_p, precop is minimum needed precision
1784 of unsigned type to hold the exact result, otherwise
1785 precop is minimum needed precision of signed type to
1786 hold the exact result. */
1788 if (code
== MULT_EXPR
)
1789 precop
= prec0
+ prec1
+ (uns0_p
!= uns1_p
);
1792 if (uns0_p
== uns1_p
)
1793 precop
= MAX (prec0
, prec1
) + 1;
1795 precop
= MAX (prec0
+ 1, prec1
) + 1;
1797 precop
= MAX (prec0
, prec1
+ 1) + 1;
1799 int orig_precres
= precres
;
1803 if ((uns0_p
&& uns1_p
)
1804 ? ((precop
+ !unsr_p
) <= precres
1805 /* u1 - u2 -> ur can overflow, no matter what precision
1807 && (code
!= MINUS_EXPR
|| !unsr_p
))
1808 : (!unsr_p
&& precop
<= precres
))
1810 /* The infinity precision result will always fit into result. */
1811 rtx target
= expand_expr (lhs
, NULL_RTX
, VOIDmode
, EXPAND_WRITE
);
1812 write_complex_part (target
, const0_rtx
, true);
1813 enum machine_mode mode
= TYPE_MODE (type
);
1814 struct separate_ops ops
;
1817 ops
.op0
= fold_convert_loc (loc
, type
, arg0
);
1818 ops
.op1
= fold_convert_loc (loc
, type
, arg1
);
1819 ops
.op2
= NULL_TREE
;
1821 rtx tem
= expand_expr_real_2 (&ops
, NULL_RTX
, mode
, EXPAND_NORMAL
);
1822 expand_arith_overflow_result_store (lhs
, target
, mode
, tem
);
1826 /* For sub-word operations, if target doesn't have them, start
1827 with precres widening right away, otherwise do it only
1828 if the most simple cases can't be used. */
1829 if (WORD_REGISTER_OPERATIONS
1830 && orig_precres
== precres
1831 && precres
< BITS_PER_WORD
)
1833 else if ((uns0_p
&& uns1_p
&& unsr_p
&& prec0
<= precres
1834 && prec1
<= precres
)
1835 || ((!uns0_p
|| !uns1_p
) && !unsr_p
1836 && prec0
+ uns0_p
<= precres
1837 && prec1
+ uns1_p
<= precres
))
1839 arg0
= fold_convert_loc (loc
, type
, arg0
);
1840 arg1
= fold_convert_loc (loc
, type
, arg1
);
1844 if (integer_zerop (arg0
) && !unsr_p
)
1846 expand_neg_overflow (loc
, lhs
, arg1
, false);
1851 expand_addsub_overflow (loc
, code
, lhs
, arg0
, arg1
,
1852 unsr_p
, unsr_p
, unsr_p
, false);
1855 expand_mul_overflow (loc
, lhs
, arg0
, arg1
,
1856 unsr_p
, unsr_p
, unsr_p
, false);
1863 /* For sub-word operations, retry with a wider type first. */
1864 if (orig_precres
== precres
&& precop
<= BITS_PER_WORD
)
1866 int p
= WORD_REGISTER_OPERATIONS
? BITS_PER_WORD
: precop
;
1867 enum machine_mode m
= smallest_mode_for_size (p
, MODE_INT
);
1868 tree optype
= build_nonstandard_integer_type (GET_MODE_PRECISION (m
),
1871 p
= TYPE_PRECISION (optype
);
1875 unsr_p
= TYPE_UNSIGNED (optype
);
1881 if (prec0
<= precres
&& prec1
<= precres
)
1886 types
[0] = build_nonstandard_integer_type (precres
, 0);
1892 types
[1] = build_nonstandard_integer_type (precres
, 1);
1894 arg0
= fold_convert_loc (loc
, types
[uns0_p
], arg0
);
1895 arg1
= fold_convert_loc (loc
, types
[uns1_p
], arg1
);
1896 if (code
!= MULT_EXPR
)
1897 expand_addsub_overflow (loc
, code
, lhs
, arg0
, arg1
, unsr_p
,
1898 uns0_p
, uns1_p
, false);
1900 expand_mul_overflow (loc
, lhs
, arg0
, arg1
, unsr_p
,
1901 uns0_p
, uns1_p
, false);
1905 /* Retry with a wider type. */
1906 if (orig_precres
== precres
)
1908 int p
= MAX (prec0
, prec1
);
1909 enum machine_mode m
= smallest_mode_for_size (p
, MODE_INT
);
1910 tree optype
= build_nonstandard_integer_type (GET_MODE_PRECISION (m
),
1913 p
= TYPE_PRECISION (optype
);
1917 unsr_p
= TYPE_UNSIGNED (optype
);
1928 /* Expand ADD_OVERFLOW STMT. */
1931 expand_ADD_OVERFLOW (internal_fn
, gcall
*stmt
)
1933 expand_arith_overflow (PLUS_EXPR
, stmt
);
1936 /* Expand SUB_OVERFLOW STMT. */
1939 expand_SUB_OVERFLOW (internal_fn
, gcall
*stmt
)
1941 expand_arith_overflow (MINUS_EXPR
, stmt
);
1944 /* Expand MUL_OVERFLOW STMT. */
1947 expand_MUL_OVERFLOW (internal_fn
, gcall
*stmt
)
1949 expand_arith_overflow (MULT_EXPR
, stmt
);
1952 /* This should get folded in tree-vectorizer.c. */
1955 expand_LOOP_VECTORIZED (internal_fn
, gcall
*)
1960 /* Expand MASK_LOAD call STMT using optab OPTAB. */
1963 expand_mask_load_optab_fn (internal_fn
, gcall
*stmt
, convert_optab optab
)
1965 struct expand_operand ops
[3];
1966 tree type
, lhs
, rhs
, maskt
, ptr
;
1967 rtx mem
, target
, mask
;
1970 maskt
= gimple_call_arg (stmt
, 2);
1971 lhs
= gimple_call_lhs (stmt
);
1972 if (lhs
== NULL_TREE
)
1974 type
= TREE_TYPE (lhs
);
1975 ptr
= build_int_cst (TREE_TYPE (gimple_call_arg (stmt
, 1)), 0);
1976 align
= tree_to_shwi (gimple_call_arg (stmt
, 1));
1977 if (TYPE_ALIGN (type
) != align
)
1978 type
= build_aligned_type (type
, align
);
1979 rhs
= fold_build2 (MEM_REF
, type
, gimple_call_arg (stmt
, 0), ptr
);
1981 mem
= expand_expr (rhs
, NULL_RTX
, VOIDmode
, EXPAND_WRITE
);
1982 gcc_assert (MEM_P (mem
));
1983 mask
= expand_normal (maskt
);
1984 target
= expand_expr (lhs
, NULL_RTX
, VOIDmode
, EXPAND_WRITE
);
1985 create_output_operand (&ops
[0], target
, TYPE_MODE (type
));
1986 create_fixed_operand (&ops
[1], mem
);
1987 create_input_operand (&ops
[2], mask
, TYPE_MODE (TREE_TYPE (maskt
)));
1988 expand_insn (convert_optab_handler (optab
, TYPE_MODE (type
),
1989 TYPE_MODE (TREE_TYPE (maskt
))),
1993 /* Expand MASK_STORE call STMT using optab OPTAB. */
1996 expand_mask_store_optab_fn (internal_fn
, gcall
*stmt
, convert_optab optab
)
1998 struct expand_operand ops
[3];
1999 tree type
, lhs
, rhs
, maskt
, ptr
;
2003 maskt
= gimple_call_arg (stmt
, 2);
2004 rhs
= gimple_call_arg (stmt
, 3);
2005 type
= TREE_TYPE (rhs
);
2006 ptr
= build_int_cst (TREE_TYPE (gimple_call_arg (stmt
, 1)), 0);
2007 align
= tree_to_shwi (gimple_call_arg (stmt
, 1));
2008 if (TYPE_ALIGN (type
) != align
)
2009 type
= build_aligned_type (type
, align
);
2010 lhs
= fold_build2 (MEM_REF
, type
, gimple_call_arg (stmt
, 0), ptr
);
2012 mem
= expand_expr (lhs
, NULL_RTX
, VOIDmode
, EXPAND_WRITE
);
2013 gcc_assert (MEM_P (mem
));
2014 mask
= expand_normal (maskt
);
2015 reg
= expand_normal (rhs
);
2016 create_fixed_operand (&ops
[0], mem
);
2017 create_input_operand (&ops
[1], reg
, TYPE_MODE (type
));
2018 create_input_operand (&ops
[2], mask
, TYPE_MODE (TREE_TYPE (maskt
)));
2019 expand_insn (convert_optab_handler (optab
, TYPE_MODE (type
),
2020 TYPE_MODE (TREE_TYPE (maskt
))),
2025 expand_ABNORMAL_DISPATCHER (internal_fn
, gcall
*)
2030 expand_BUILTIN_EXPECT (internal_fn
, gcall
*stmt
)
2032 /* When guessing was done, the hints should be already stripped away. */
2033 gcc_assert (!flag_guess_branch_prob
|| optimize
== 0 || seen_error ());
2036 tree lhs
= gimple_call_lhs (stmt
);
2038 target
= expand_expr (lhs
, NULL_RTX
, VOIDmode
, EXPAND_WRITE
);
2040 target
= const0_rtx
;
2041 rtx val
= expand_expr (gimple_call_arg (stmt
, 0), target
, VOIDmode
, EXPAND_NORMAL
);
2042 if (lhs
&& val
!= target
)
2043 emit_move_insn (target
, val
);
2046 /* IFN_VA_ARG is supposed to be expanded at pass_stdarg. So this dummy function
2047 should never be called. */
2050 expand_VA_ARG (internal_fn
, gcall
*)
2055 /* Expand the IFN_UNIQUE function according to its first argument. */
2058 expand_UNIQUE (internal_fn
, gcall
*stmt
)
2060 rtx pattern
= NULL_RTX
;
2061 enum ifn_unique_kind kind
2062 = (enum ifn_unique_kind
) TREE_INT_CST_LOW (gimple_call_arg (stmt
, 0));
2069 case IFN_UNIQUE_UNSPEC
:
2070 if (targetm
.have_unique ())
2071 pattern
= targetm
.gen_unique ();
2074 case IFN_UNIQUE_OACC_FORK
:
2075 case IFN_UNIQUE_OACC_JOIN
:
2076 if (targetm
.have_oacc_fork () && targetm
.have_oacc_join ())
2078 tree lhs
= gimple_call_lhs (stmt
);
2079 rtx target
= const0_rtx
;
2082 target
= expand_expr (lhs
, NULL_RTX
, VOIDmode
, EXPAND_WRITE
);
2084 rtx data_dep
= expand_normal (gimple_call_arg (stmt
, 1));
2085 rtx axis
= expand_normal (gimple_call_arg (stmt
, 2));
2087 if (kind
== IFN_UNIQUE_OACC_FORK
)
2088 pattern
= targetm
.gen_oacc_fork (target
, data_dep
, axis
);
2090 pattern
= targetm
.gen_oacc_join (target
, data_dep
, axis
);
2098 emit_insn (pattern
);
2101 /* The size of an OpenACC compute dimension. */
2104 expand_GOACC_DIM_SIZE (internal_fn
, gcall
*stmt
)
2106 tree lhs
= gimple_call_lhs (stmt
);
2111 rtx target
= expand_expr (lhs
, NULL_RTX
, VOIDmode
, EXPAND_WRITE
);
2112 if (targetm
.have_oacc_dim_size ())
2114 rtx dim
= expand_expr (gimple_call_arg (stmt
, 0), NULL_RTX
,
2115 VOIDmode
, EXPAND_NORMAL
);
2116 emit_insn (targetm
.gen_oacc_dim_size (target
, dim
));
2119 emit_move_insn (target
, GEN_INT (1));
2122 /* The position of an OpenACC execution engine along one compute axis. */
2125 expand_GOACC_DIM_POS (internal_fn
, gcall
*stmt
)
2127 tree lhs
= gimple_call_lhs (stmt
);
2132 rtx target
= expand_expr (lhs
, NULL_RTX
, VOIDmode
, EXPAND_WRITE
);
2133 if (targetm
.have_oacc_dim_pos ())
2135 rtx dim
= expand_expr (gimple_call_arg (stmt
, 0), NULL_RTX
,
2136 VOIDmode
, EXPAND_NORMAL
);
2137 emit_insn (targetm
.gen_oacc_dim_pos (target
, dim
));
2140 emit_move_insn (target
, const0_rtx
);
2143 /* This is expanded by oacc_device_lower pass. */
2146 expand_GOACC_LOOP (internal_fn
, gcall
*)
2151 /* This is expanded by oacc_device_lower pass. */
2154 expand_GOACC_REDUCTION (internal_fn
, gcall
*)
2159 /* Set errno to EDOM. */
2162 expand_SET_EDOM (internal_fn
, gcall
*)
2165 #ifdef GEN_ERRNO_RTX
2166 rtx errno_rtx
= GEN_ERRNO_RTX
;
2168 rtx errno_rtx
= gen_rtx_MEM (word_mode
, gen_rtx_SYMBOL_REF (Pmode
, "errno"));
2170 emit_move_insn (errno_rtx
,
2171 gen_int_mode (TARGET_EDOM
, GET_MODE (errno_rtx
)));
2177 /* Expand atomic bit test and set. */
2180 expand_ATOMIC_BIT_TEST_AND_SET (internal_fn
, gcall
*call
)
2182 expand_ifn_atomic_bit_test_and (call
);
2185 /* Expand atomic bit test and complement. */
2188 expand_ATOMIC_BIT_TEST_AND_COMPLEMENT (internal_fn
, gcall
*call
)
2190 expand_ifn_atomic_bit_test_and (call
);
2193 /* Expand atomic bit test and reset. */
2196 expand_ATOMIC_BIT_TEST_AND_RESET (internal_fn
, gcall
*call
)
2198 expand_ifn_atomic_bit_test_and (call
);
2201 /* Expand atomic bit test and set. */
2204 expand_ATOMIC_COMPARE_EXCHANGE (internal_fn
, gcall
*call
)
2206 expand_ifn_atomic_compare_exchange (call
);
2209 /* Expand a call to FN using the operands in STMT. FN has a single
2210 output operand and NARGS input operands. */
2213 expand_direct_optab_fn (internal_fn fn
, gcall
*stmt
, direct_optab optab
,
2216 expand_operand
*ops
= XALLOCAVEC (expand_operand
, nargs
+ 1);
2218 tree_pair types
= direct_internal_fn_types (fn
, stmt
);
2219 insn_code icode
= direct_optab_handler (optab
, TYPE_MODE (types
.first
));
2221 tree lhs
= gimple_call_lhs (stmt
);
2222 tree lhs_type
= TREE_TYPE (lhs
);
2223 rtx lhs_rtx
= expand_expr (lhs
, NULL_RTX
, VOIDmode
, EXPAND_WRITE
);
2224 create_output_operand (&ops
[0], lhs_rtx
, insn_data
[icode
].operand
[0].mode
);
2226 for (unsigned int i
= 0; i
< nargs
; ++i
)
2228 tree rhs
= gimple_call_arg (stmt
, i
);
2229 tree rhs_type
= TREE_TYPE (rhs
);
2230 rtx rhs_rtx
= expand_normal (rhs
);
2231 if (INTEGRAL_TYPE_P (rhs_type
))
2232 create_convert_operand_from (&ops
[i
+ 1], rhs_rtx
,
2233 TYPE_MODE (rhs_type
),
2234 TYPE_UNSIGNED (rhs_type
));
2236 create_input_operand (&ops
[i
+ 1], rhs_rtx
, TYPE_MODE (rhs_type
));
2239 expand_insn (icode
, nargs
+ 1, ops
);
2240 if (!rtx_equal_p (lhs_rtx
, ops
[0].value
))
2242 /* If the return value has an integral type, convert the instruction
2243 result to that type. This is useful for things that return an
2244 int regardless of the size of the input. If the instruction result
2245 is smaller than required, assume that it is signed.
2247 If the return value has a nonintegral type, its mode must match
2248 the instruction result. */
2249 if (GET_CODE (lhs_rtx
) == SUBREG
&& SUBREG_PROMOTED_VAR_P (lhs_rtx
))
2251 /* If this is a scalar in a register that is stored in a wider
2252 mode than the declared mode, compute the result into its
2253 declared mode and then convert to the wider mode. */
2254 gcc_checking_assert (INTEGRAL_TYPE_P (lhs_type
));
2255 rtx tmp
= convert_to_mode (GET_MODE (lhs_rtx
), ops
[0].value
, 0);
2256 convert_move (SUBREG_REG (lhs_rtx
), tmp
,
2257 SUBREG_PROMOTED_SIGN (lhs_rtx
));
2259 else if (GET_MODE (lhs_rtx
) == GET_MODE (ops
[0].value
))
2260 emit_move_insn (lhs_rtx
, ops
[0].value
);
2263 gcc_checking_assert (INTEGRAL_TYPE_P (lhs_type
));
2264 convert_move (lhs_rtx
, ops
[0].value
, 0);
2269 /* Expanders for optabs that can use expand_direct_optab_fn. */
2271 #define expand_unary_optab_fn(FN, STMT, OPTAB) \
2272 expand_direct_optab_fn (FN, STMT, OPTAB, 1)
2274 #define expand_binary_optab_fn(FN, STMT, OPTAB) \
2275 expand_direct_optab_fn (FN, STMT, OPTAB, 2)
2277 /* RETURN_TYPE and ARGS are a return type and argument list that are
2278 in principle compatible with FN (which satisfies direct_internal_fn_p).
2279 Return the types that should be used to determine whether the
2280 target supports FN. */
2283 direct_internal_fn_types (internal_fn fn
, tree return_type
, tree
*args
)
2285 const direct_internal_fn_info
&info
= direct_internal_fn (fn
);
2286 tree type0
= (info
.type0
< 0 ? return_type
: TREE_TYPE (args
[info
.type0
]));
2287 tree type1
= (info
.type1
< 0 ? return_type
: TREE_TYPE (args
[info
.type1
]));
2288 return tree_pair (type0
, type1
);
2291 /* CALL is a call whose return type and arguments are in principle
2292 compatible with FN (which satisfies direct_internal_fn_p). Return the
2293 types that should be used to determine whether the target supports FN. */
2296 direct_internal_fn_types (internal_fn fn
, gcall
*call
)
2298 const direct_internal_fn_info
&info
= direct_internal_fn (fn
);
2299 tree op0
= (info
.type0
< 0
2300 ? gimple_call_lhs (call
)
2301 : gimple_call_arg (call
, info
.type0
));
2302 tree op1
= (info
.type1
< 0
2303 ? gimple_call_lhs (call
)
2304 : gimple_call_arg (call
, info
.type1
));
2305 return tree_pair (TREE_TYPE (op0
), TREE_TYPE (op1
));
2308 /* Return true if OPTAB is supported for TYPES (whose modes should be
2309 the same) when the optimization type is OPT_TYPE. Used for simple
2313 direct_optab_supported_p (direct_optab optab
, tree_pair types
,
2314 optimization_type opt_type
)
2316 machine_mode mode
= TYPE_MODE (types
.first
);
2317 gcc_checking_assert (mode
== TYPE_MODE (types
.second
));
2318 return direct_optab_handler (optab
, mode
, opt_type
) != CODE_FOR_nothing
;
2321 /* Return true if load/store lanes optab OPTAB is supported for
2322 array type TYPES.first when the optimization type is OPT_TYPE. */
2325 multi_vector_optab_supported_p (convert_optab optab
, tree_pair types
,
2326 optimization_type opt_type
)
2328 gcc_assert (TREE_CODE (types
.first
) == ARRAY_TYPE
);
2329 machine_mode imode
= TYPE_MODE (types
.first
);
2330 machine_mode vmode
= TYPE_MODE (TREE_TYPE (types
.first
));
2331 return (convert_optab_handler (optab
, imode
, vmode
, opt_type
)
2332 != CODE_FOR_nothing
);
2335 #define direct_unary_optab_supported_p direct_optab_supported_p
2336 #define direct_binary_optab_supported_p direct_optab_supported_p
2337 #define direct_mask_load_optab_supported_p direct_optab_supported_p
2338 #define direct_load_lanes_optab_supported_p multi_vector_optab_supported_p
2339 #define direct_mask_store_optab_supported_p direct_optab_supported_p
2340 #define direct_store_lanes_optab_supported_p multi_vector_optab_supported_p
2342 /* Return true if FN is supported for the types in TYPES when the
2343 optimization type is OPT_TYPE. The types are those associated with
2344 the "type0" and "type1" fields of FN's direct_internal_fn_info
2348 direct_internal_fn_supported_p (internal_fn fn
, tree_pair types
,
2349 optimization_type opt_type
)
2353 #define DEF_INTERNAL_FN(CODE, FLAGS, FNSPEC) \
2354 case IFN_##CODE: break;
2355 #define DEF_INTERNAL_OPTAB_FN(CODE, FLAGS, OPTAB, TYPE) \
2357 return direct_##TYPE##_optab_supported_p (OPTAB##_optab, types, \
2359 #include "internal-fn.def"
2367 /* Return true if FN is supported for type TYPE when the optimization
2368 type is OPT_TYPE. The caller knows that the "type0" and "type1"
2369 fields of FN's direct_internal_fn_info structure are the same. */
2372 direct_internal_fn_supported_p (internal_fn fn
, tree type
,
2373 optimization_type opt_type
)
2375 const direct_internal_fn_info
&info
= direct_internal_fn (fn
);
2376 gcc_checking_assert (info
.type0
== info
.type1
);
2377 return direct_internal_fn_supported_p (fn
, tree_pair (type
, type
), opt_type
);
2380 /* Return true if IFN_SET_EDOM is supported. */
2383 set_edom_supported_p (void)
2392 #define DEF_INTERNAL_OPTAB_FN(CODE, FLAGS, OPTAB, TYPE) \
2394 expand_##CODE (internal_fn fn, gcall *stmt) \
2396 expand_##TYPE##_optab_fn (fn, stmt, OPTAB##_optab); \
2398 #include "internal-fn.def"
2400 /* Routines to expand each internal function, indexed by function number.
2401 Each routine has the prototype:
2403 expand_<NAME> (gcall *stmt)
2405 where STMT is the statement that performs the call. */
2406 static void (*const internal_fn_expanders
[]) (internal_fn
, gcall
*) = {
2407 #define DEF_INTERNAL_FN(CODE, FLAGS, FNSPEC) expand_##CODE,
2408 #include "internal-fn.def"
2412 /* Expand STMT as though it were a call to internal function FN. */
2415 expand_internal_call (internal_fn fn
, gcall
*stmt
)
2417 internal_fn_expanders
[fn
] (fn
, stmt
);
2420 /* Expand STMT, which is a call to internal function FN. */
2423 expand_internal_call (gcall
*stmt
)
2425 expand_internal_call (gimple_call_internal_fn (stmt
), stmt
);