2 Copyright (C) 2011-2018 Free Software Foundation, Inc.
4 This file is part of GCC.
6 GCC is free software; you can redistribute it and/or modify it under
7 the terms of the GNU General Public License as published by the Free
8 Software Foundation; either version 3, or (at your option) any later
11 GCC is distributed in the hope that it will be useful, but WITHOUT ANY
12 WARRANTY; without even the implied warranty of MERCHANTABILITY or
13 FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License
16 You should have received a copy of the GNU General Public License
17 along with GCC; see the file COPYING3. If not see
18 <http://www.gnu.org/licenses/>. */
22 #include "coretypes.h"
29 #include "stringpool.h"
31 #include "tree-ssanames.h"
36 #include "diagnostic-core.h"
37 #include "fold-const.h"
38 #include "internal-fn.h"
39 #include "stor-layout.h"
42 #include "stringpool.h"
48 #include "optabs-tree.h"
49 #include "gimple-ssa.h"
50 #include "tree-phinodes.h"
51 #include "ssa-iterators.h"
53 /* The names of each internal function, indexed by function number. */
54 const char *const internal_fn_name_array
[] = {
55 #define DEF_INTERNAL_FN(CODE, FLAGS, FNSPEC) #CODE,
56 #include "internal-fn.def"
60 /* The ECF_* flags of each internal function, indexed by function number. */
61 const int internal_fn_flags_array
[] = {
62 #define DEF_INTERNAL_FN(CODE, FLAGS, FNSPEC) FLAGS,
63 #include "internal-fn.def"
67 /* Fnspec of each internal function, indexed by function number. */
68 const_tree internal_fn_fnspec_array
[IFN_LAST
+ 1];
73 #define DEF_INTERNAL_FN(CODE, FLAGS, FNSPEC) \
74 if (FNSPEC) internal_fn_fnspec_array[IFN_##CODE] = \
75 build_string ((int) sizeof (FNSPEC), FNSPEC ? FNSPEC : "");
76 #include "internal-fn.def"
77 internal_fn_fnspec_array
[IFN_LAST
] = 0;
80 /* Create static initializers for the information returned by
81 direct_internal_fn. */
82 #define not_direct { -2, -2, false }
83 #define mask_load_direct { -1, 2, false }
84 #define load_lanes_direct { -1, -1, false }
85 #define mask_load_lanes_direct { -1, -1, false }
86 #define gather_load_direct { -1, -1, false }
87 #define mask_store_direct { 3, 2, false }
88 #define store_lanes_direct { 0, 0, false }
89 #define mask_store_lanes_direct { 0, 0, false }
90 #define unary_direct { 0, 0, true }
91 #define binary_direct { 0, 0, true }
92 #define cond_unary_direct { 1, 1, true }
93 #define cond_binary_direct { 1, 1, true }
94 #define while_direct { 0, 2, false }
95 #define fold_extract_direct { 2, 2, false }
96 #define fold_left_direct { 1, 1, false }
98 const direct_internal_fn_info direct_internal_fn_array
[IFN_LAST
+ 1] = {
99 #define DEF_INTERNAL_FN(CODE, FLAGS, FNSPEC) not_direct,
100 #define DEF_INTERNAL_OPTAB_FN(CODE, FLAGS, OPTAB, TYPE) TYPE##_direct,
101 #define DEF_INTERNAL_SIGNED_OPTAB_FN(CODE, FLAGS, SELECTOR, SIGNED_OPTAB, \
102 UNSIGNED_OPTAB, TYPE) TYPE##_direct,
103 #include "internal-fn.def"
107 /* ARRAY_TYPE is an array of vector modes. Return the associated insn
108 for load-lanes-style optab OPTAB, or CODE_FOR_nothing if none. */
110 static enum insn_code
111 get_multi_vector_move (tree array_type
, convert_optab optab
)
116 gcc_assert (TREE_CODE (array_type
) == ARRAY_TYPE
);
117 imode
= TYPE_MODE (array_type
);
118 vmode
= TYPE_MODE (TREE_TYPE (array_type
));
120 return convert_optab_handler (optab
, imode
, vmode
);
123 /* Expand LOAD_LANES call STMT using optab OPTAB. */
126 expand_load_lanes_optab_fn (internal_fn
, gcall
*stmt
, convert_optab optab
)
128 struct expand_operand ops
[2];
132 lhs
= gimple_call_lhs (stmt
);
133 rhs
= gimple_call_arg (stmt
, 0);
134 type
= TREE_TYPE (lhs
);
136 target
= expand_expr (lhs
, NULL_RTX
, VOIDmode
, EXPAND_WRITE
);
137 mem
= expand_normal (rhs
);
139 gcc_assert (MEM_P (mem
));
140 PUT_MODE (mem
, TYPE_MODE (type
));
142 create_output_operand (&ops
[0], target
, TYPE_MODE (type
));
143 create_fixed_operand (&ops
[1], mem
);
144 expand_insn (get_multi_vector_move (type
, optab
), 2, ops
);
147 /* Expand STORE_LANES call STMT using optab OPTAB. */
150 expand_store_lanes_optab_fn (internal_fn
, gcall
*stmt
, convert_optab optab
)
152 struct expand_operand ops
[2];
156 lhs
= gimple_call_lhs (stmt
);
157 rhs
= gimple_call_arg (stmt
, 0);
158 type
= TREE_TYPE (rhs
);
160 target
= expand_expr (lhs
, NULL_RTX
, VOIDmode
, EXPAND_WRITE
);
161 reg
= expand_normal (rhs
);
163 gcc_assert (MEM_P (target
));
164 PUT_MODE (target
, TYPE_MODE (type
));
166 create_fixed_operand (&ops
[0], target
);
167 create_input_operand (&ops
[1], reg
, TYPE_MODE (type
));
168 expand_insn (get_multi_vector_move (type
, optab
), 2, ops
);
172 expand_ANNOTATE (internal_fn
, gcall
*)
177 /* This should get expanded in omp_device_lower pass. */
180 expand_GOMP_USE_SIMT (internal_fn
, gcall
*)
185 /* This should get expanded in omp_device_lower pass. */
188 expand_GOMP_SIMT_ENTER (internal_fn
, gcall
*)
193 /* Allocate per-lane storage and begin non-uniform execution region. */
196 expand_GOMP_SIMT_ENTER_ALLOC (internal_fn
, gcall
*stmt
)
199 tree lhs
= gimple_call_lhs (stmt
);
201 target
= expand_expr (lhs
, NULL_RTX
, VOIDmode
, EXPAND_WRITE
);
203 target
= gen_reg_rtx (Pmode
);
204 rtx size
= expand_normal (gimple_call_arg (stmt
, 0));
205 rtx align
= expand_normal (gimple_call_arg (stmt
, 1));
206 struct expand_operand ops
[3];
207 create_output_operand (&ops
[0], target
, Pmode
);
208 create_input_operand (&ops
[1], size
, Pmode
);
209 create_input_operand (&ops
[2], align
, Pmode
);
210 gcc_assert (targetm
.have_omp_simt_enter ());
211 expand_insn (targetm
.code_for_omp_simt_enter
, 3, ops
);
214 /* Deallocate per-lane storage and leave non-uniform execution region. */
217 expand_GOMP_SIMT_EXIT (internal_fn
, gcall
*stmt
)
219 gcc_checking_assert (!gimple_call_lhs (stmt
));
220 rtx arg
= expand_normal (gimple_call_arg (stmt
, 0));
221 struct expand_operand ops
[1];
222 create_input_operand (&ops
[0], arg
, Pmode
);
223 gcc_assert (targetm
.have_omp_simt_exit ());
224 expand_insn (targetm
.code_for_omp_simt_exit
, 1, ops
);
227 /* Lane index on SIMT targets: thread index in the warp on NVPTX. On targets
228 without SIMT execution this should be expanded in omp_device_lower pass. */
231 expand_GOMP_SIMT_LANE (internal_fn
, gcall
*stmt
)
233 tree lhs
= gimple_call_lhs (stmt
);
237 rtx target
= expand_expr (lhs
, NULL_RTX
, VOIDmode
, EXPAND_WRITE
);
238 gcc_assert (targetm
.have_omp_simt_lane ());
239 emit_insn (targetm
.gen_omp_simt_lane (target
));
242 /* This should get expanded in omp_device_lower pass. */
245 expand_GOMP_SIMT_VF (internal_fn
, gcall
*)
250 /* Lane index of the first SIMT lane that supplies a non-zero argument.
251 This is a SIMT counterpart to GOMP_SIMD_LAST_LANE, used to represent the
252 lane that executed the last iteration for handling OpenMP lastprivate. */
255 expand_GOMP_SIMT_LAST_LANE (internal_fn
, gcall
*stmt
)
257 tree lhs
= gimple_call_lhs (stmt
);
261 rtx target
= expand_expr (lhs
, NULL_RTX
, VOIDmode
, EXPAND_WRITE
);
262 rtx cond
= expand_normal (gimple_call_arg (stmt
, 0));
263 machine_mode mode
= TYPE_MODE (TREE_TYPE (lhs
));
264 struct expand_operand ops
[2];
265 create_output_operand (&ops
[0], target
, mode
);
266 create_input_operand (&ops
[1], cond
, mode
);
267 gcc_assert (targetm
.have_omp_simt_last_lane ());
268 expand_insn (targetm
.code_for_omp_simt_last_lane
, 2, ops
);
271 /* Non-transparent predicate used in SIMT lowering of OpenMP "ordered". */
274 expand_GOMP_SIMT_ORDERED_PRED (internal_fn
, gcall
*stmt
)
276 tree lhs
= gimple_call_lhs (stmt
);
280 rtx target
= expand_expr (lhs
, NULL_RTX
, VOIDmode
, EXPAND_WRITE
);
281 rtx ctr
= expand_normal (gimple_call_arg (stmt
, 0));
282 machine_mode mode
= TYPE_MODE (TREE_TYPE (lhs
));
283 struct expand_operand ops
[2];
284 create_output_operand (&ops
[0], target
, mode
);
285 create_input_operand (&ops
[1], ctr
, mode
);
286 gcc_assert (targetm
.have_omp_simt_ordered ());
287 expand_insn (targetm
.code_for_omp_simt_ordered
, 2, ops
);
290 /* "Or" boolean reduction across SIMT lanes: return non-zero in all lanes if
291 any lane supplies a non-zero argument. */
294 expand_GOMP_SIMT_VOTE_ANY (internal_fn
, gcall
*stmt
)
296 tree lhs
= gimple_call_lhs (stmt
);
300 rtx target
= expand_expr (lhs
, NULL_RTX
, VOIDmode
, EXPAND_WRITE
);
301 rtx cond
= expand_normal (gimple_call_arg (stmt
, 0));
302 machine_mode mode
= TYPE_MODE (TREE_TYPE (lhs
));
303 struct expand_operand ops
[2];
304 create_output_operand (&ops
[0], target
, mode
);
305 create_input_operand (&ops
[1], cond
, mode
);
306 gcc_assert (targetm
.have_omp_simt_vote_any ());
307 expand_insn (targetm
.code_for_omp_simt_vote_any
, 2, ops
);
310 /* Exchange between SIMT lanes with a "butterfly" pattern: source lane index
311 is destination lane index XOR given offset. */
314 expand_GOMP_SIMT_XCHG_BFLY (internal_fn
, gcall
*stmt
)
316 tree lhs
= gimple_call_lhs (stmt
);
320 rtx target
= expand_expr (lhs
, NULL_RTX
, VOIDmode
, EXPAND_WRITE
);
321 rtx src
= expand_normal (gimple_call_arg (stmt
, 0));
322 rtx idx
= expand_normal (gimple_call_arg (stmt
, 1));
323 machine_mode mode
= TYPE_MODE (TREE_TYPE (lhs
));
324 struct expand_operand ops
[3];
325 create_output_operand (&ops
[0], target
, mode
);
326 create_input_operand (&ops
[1], src
, mode
);
327 create_input_operand (&ops
[2], idx
, SImode
);
328 gcc_assert (targetm
.have_omp_simt_xchg_bfly ());
329 expand_insn (targetm
.code_for_omp_simt_xchg_bfly
, 3, ops
);
332 /* Exchange between SIMT lanes according to given source lane index. */
335 expand_GOMP_SIMT_XCHG_IDX (internal_fn
, gcall
*stmt
)
337 tree lhs
= gimple_call_lhs (stmt
);
341 rtx target
= expand_expr (lhs
, NULL_RTX
, VOIDmode
, EXPAND_WRITE
);
342 rtx src
= expand_normal (gimple_call_arg (stmt
, 0));
343 rtx idx
= expand_normal (gimple_call_arg (stmt
, 1));
344 machine_mode mode
= TYPE_MODE (TREE_TYPE (lhs
));
345 struct expand_operand ops
[3];
346 create_output_operand (&ops
[0], target
, mode
);
347 create_input_operand (&ops
[1], src
, mode
);
348 create_input_operand (&ops
[2], idx
, SImode
);
349 gcc_assert (targetm
.have_omp_simt_xchg_idx ());
350 expand_insn (targetm
.code_for_omp_simt_xchg_idx
, 3, ops
);
353 /* This should get expanded in adjust_simduid_builtins. */
356 expand_GOMP_SIMD_LANE (internal_fn
, gcall
*)
361 /* This should get expanded in adjust_simduid_builtins. */
364 expand_GOMP_SIMD_VF (internal_fn
, gcall
*)
369 /* This should get expanded in adjust_simduid_builtins. */
372 expand_GOMP_SIMD_LAST_LANE (internal_fn
, gcall
*)
377 /* This should get expanded in adjust_simduid_builtins. */
380 expand_GOMP_SIMD_ORDERED_START (internal_fn
, gcall
*)
385 /* This should get expanded in adjust_simduid_builtins. */
388 expand_GOMP_SIMD_ORDERED_END (internal_fn
, gcall
*)
393 /* This should get expanded in the sanopt pass. */
396 expand_UBSAN_NULL (internal_fn
, gcall
*)
401 /* This should get expanded in the sanopt pass. */
404 expand_UBSAN_BOUNDS (internal_fn
, gcall
*)
409 /* This should get expanded in the sanopt pass. */
412 expand_UBSAN_VPTR (internal_fn
, gcall
*)
417 /* This should get expanded in the sanopt pass. */
420 expand_UBSAN_PTR (internal_fn
, gcall
*)
425 /* This should get expanded in the sanopt pass. */
428 expand_UBSAN_OBJECT_SIZE (internal_fn
, gcall
*)
433 /* This should get expanded in the sanopt pass. */
436 expand_ASAN_CHECK (internal_fn
, gcall
*)
441 /* This should get expanded in the sanopt pass. */
444 expand_ASAN_MARK (internal_fn
, gcall
*)
449 /* This should get expanded in the sanopt pass. */
452 expand_ASAN_POISON (internal_fn
, gcall
*)
457 /* This should get expanded in the sanopt pass. */
460 expand_ASAN_POISON_USE (internal_fn
, gcall
*)
465 /* This should get expanded in the tsan pass. */
468 expand_TSAN_FUNC_EXIT (internal_fn
, gcall
*)
473 /* This should get expanded in the lower pass. */
476 expand_FALLTHROUGH (internal_fn
, gcall
*call
)
478 error_at (gimple_location (call
),
479 "invalid use of attribute %<fallthrough%>");
482 /* Return minimum precision needed to represent all values
483 of ARG in SIGNed integral type. */
486 get_min_precision (tree arg
, signop sign
)
488 int prec
= TYPE_PRECISION (TREE_TYPE (arg
));
490 signop orig_sign
= sign
;
491 if (TREE_CODE (arg
) == INTEGER_CST
)
494 if (TYPE_SIGN (TREE_TYPE (arg
)) != sign
)
496 widest_int w
= wi::to_widest (arg
);
497 w
= wi::ext (w
, prec
, sign
);
498 p
= wi::min_precision (w
, sign
);
501 p
= wi::min_precision (wi::to_wide (arg
), sign
);
502 return MIN (p
, prec
);
504 while (CONVERT_EXPR_P (arg
)
505 && INTEGRAL_TYPE_P (TREE_TYPE (TREE_OPERAND (arg
, 0)))
506 && TYPE_PRECISION (TREE_TYPE (TREE_OPERAND (arg
, 0))) <= prec
)
508 arg
= TREE_OPERAND (arg
, 0);
509 if (TYPE_PRECISION (TREE_TYPE (arg
)) < prec
)
511 if (TYPE_UNSIGNED (TREE_TYPE (arg
)))
513 else if (sign
== UNSIGNED
&& get_range_pos_neg (arg
) != 1)
514 return prec
+ (orig_sign
!= sign
);
515 prec
= TYPE_PRECISION (TREE_TYPE (arg
));
518 return prec
+ (orig_sign
!= sign
);
520 if (TREE_CODE (arg
) != SSA_NAME
)
521 return prec
+ (orig_sign
!= sign
);
522 wide_int arg_min
, arg_max
;
523 while (get_range_info (arg
, &arg_min
, &arg_max
) != VR_RANGE
)
525 gimple
*g
= SSA_NAME_DEF_STMT (arg
);
526 if (is_gimple_assign (g
)
527 && CONVERT_EXPR_CODE_P (gimple_assign_rhs_code (g
)))
529 tree t
= gimple_assign_rhs1 (g
);
530 if (INTEGRAL_TYPE_P (TREE_TYPE (t
))
531 && TYPE_PRECISION (TREE_TYPE (t
)) <= prec
)
534 if (TYPE_PRECISION (TREE_TYPE (arg
)) < prec
)
536 if (TYPE_UNSIGNED (TREE_TYPE (arg
)))
538 else if (sign
== UNSIGNED
&& get_range_pos_neg (arg
) != 1)
539 return prec
+ (orig_sign
!= sign
);
540 prec
= TYPE_PRECISION (TREE_TYPE (arg
));
543 return prec
+ (orig_sign
!= sign
);
547 return prec
+ (orig_sign
!= sign
);
549 if (sign
== TYPE_SIGN (TREE_TYPE (arg
)))
551 int p1
= wi::min_precision (arg_min
, sign
);
552 int p2
= wi::min_precision (arg_max
, sign
);
554 prec
= MIN (prec
, p1
);
556 else if (sign
== UNSIGNED
&& !wi::neg_p (arg_min
, SIGNED
))
558 int p
= wi::min_precision (arg_max
, UNSIGNED
);
559 prec
= MIN (prec
, p
);
561 return prec
+ (orig_sign
!= sign
);
564 /* Helper for expand_*_overflow. Set the __imag__ part to true
565 (1 except for signed:1 type, in which case store -1). */
568 expand_arith_set_overflow (tree lhs
, rtx target
)
570 if (TYPE_PRECISION (TREE_TYPE (TREE_TYPE (lhs
))) == 1
571 && !TYPE_UNSIGNED (TREE_TYPE (TREE_TYPE (lhs
))))
572 write_complex_part (target
, constm1_rtx
, true);
574 write_complex_part (target
, const1_rtx
, true);
577 /* Helper for expand_*_overflow. Store RES into the __real__ part
578 of TARGET. If RES has larger MODE than __real__ part of TARGET,
579 set the __imag__ part to 1 if RES doesn't fit into it. Similarly
580 if LHS has smaller precision than its mode. */
583 expand_arith_overflow_result_store (tree lhs
, rtx target
,
584 scalar_int_mode mode
, rtx res
)
586 scalar_int_mode tgtmode
587 = as_a
<scalar_int_mode
> (GET_MODE_INNER (GET_MODE (target
)));
591 rtx_code_label
*done_label
= gen_label_rtx ();
592 int uns
= TYPE_UNSIGNED (TREE_TYPE (TREE_TYPE (lhs
)));
593 lres
= convert_modes (tgtmode
, mode
, res
, uns
);
594 gcc_assert (GET_MODE_PRECISION (tgtmode
) < GET_MODE_PRECISION (mode
));
595 do_compare_rtx_and_jump (res
, convert_modes (mode
, tgtmode
, lres
, uns
),
596 EQ
, true, mode
, NULL_RTX
, NULL
, done_label
,
597 profile_probability::very_likely ());
598 expand_arith_set_overflow (lhs
, target
);
599 emit_label (done_label
);
601 int prec
= TYPE_PRECISION (TREE_TYPE (TREE_TYPE (lhs
)));
602 int tgtprec
= GET_MODE_PRECISION (tgtmode
);
605 rtx_code_label
*done_label
= gen_label_rtx ();
606 int uns
= TYPE_UNSIGNED (TREE_TYPE (TREE_TYPE (lhs
)));
611 = immed_wide_int_const (wi::shifted_mask (0, prec
, false, tgtprec
),
613 lres
= expand_simple_binop (tgtmode
, AND
, res
, mask
, NULL_RTX
,
614 true, OPTAB_LIB_WIDEN
);
618 lres
= expand_shift (LSHIFT_EXPR
, tgtmode
, res
, tgtprec
- prec
,
620 lres
= expand_shift (RSHIFT_EXPR
, tgtmode
, lres
, tgtprec
- prec
,
623 do_compare_rtx_and_jump (res
, lres
,
624 EQ
, true, tgtmode
, NULL_RTX
, NULL
, done_label
,
625 profile_probability::very_likely ());
626 expand_arith_set_overflow (lhs
, target
);
627 emit_label (done_label
);
629 write_complex_part (target
, lres
, false);
632 /* Helper for expand_*_overflow. Store RES into TARGET. */
635 expand_ubsan_result_store (rtx target
, rtx res
)
637 if (GET_CODE (target
) == SUBREG
&& SUBREG_PROMOTED_VAR_P (target
))
638 /* If this is a scalar in a register that is stored in a wider mode
639 than the declared mode, compute the result into its declared mode
640 and then convert to the wider mode. Our value is the computed
642 convert_move (SUBREG_REG (target
), res
, SUBREG_PROMOTED_SIGN (target
));
644 emit_move_insn (target
, res
);
647 /* Add sub/add overflow checking to the statement STMT.
648 CODE says whether the operation is +, or -. */
651 expand_addsub_overflow (location_t loc
, tree_code code
, tree lhs
,
652 tree arg0
, tree arg1
, bool unsr_p
, bool uns0_p
,
653 bool uns1_p
, bool is_ubsan
, tree
*datap
)
655 rtx res
, target
= NULL_RTX
;
657 rtx_code_label
*done_label
= gen_label_rtx ();
658 rtx_code_label
*do_error
= gen_label_rtx ();
659 do_pending_stack_adjust ();
660 rtx op0
= expand_normal (arg0
);
661 rtx op1
= expand_normal (arg1
);
662 scalar_int_mode mode
= SCALAR_INT_TYPE_MODE (TREE_TYPE (arg0
));
663 int prec
= GET_MODE_PRECISION (mode
);
664 rtx sgn
= immed_wide_int_const (wi::min_value (prec
, SIGNED
), mode
);
668 gcc_assert (!unsr_p
&& !uns0_p
&& !uns1_p
);
672 target
= expand_expr (lhs
, NULL_RTX
, VOIDmode
, EXPAND_WRITE
);
674 write_complex_part (target
, const0_rtx
, true);
677 /* We assume both operands and result have the same precision
678 here (GET_MODE_BITSIZE (mode)), S stands for signed type
679 with that precision, U for unsigned type with that precision,
680 sgn for unsigned most significant bit in that precision.
681 s1 is signed first operand, u1 is unsigned first operand,
682 s2 is signed second operand, u2 is unsigned second operand,
683 sr is signed result, ur is unsigned result and the following
684 rules say how to compute result (which is always result of
685 the operands as if both were unsigned, cast to the right
686 signedness) and how to compute whether operation overflowed.
689 res = (S) ((U) s1 + (U) s2)
690 ovf = s2 < 0 ? res > s1 : res < s1 (or jump on overflow)
692 res = (S) ((U) s1 - (U) s2)
693 ovf = s2 < 0 ? res < s1 : res > s2 (or jump on overflow)
696 ovf = res < u1 (or jump on carry, but RTL opts will handle it)
699 ovf = res > u1 (or jump on carry, but RTL opts will handle it)
701 res = (S) ((U) s1 + u2)
702 ovf = ((U) res ^ sgn) < u2
707 ovf = t1 < 0 ? t2 > s1 : t2 < s1 (or jump on overflow)
709 res = (S) ((U) s1 - u2)
710 ovf = u2 > ((U) s1 ^ sgn)
713 ovf = s1 < 0 || u2 > (U) s1
716 ovf = u1 >= ((U) s2 ^ sgn)
721 ovf = s2 < 0 ? (S) t2 < (S) t1 : (S) t2 > (S) t1 (or jump on overflow)
723 res = (U) s1 + (U) s2
724 ovf = s2 < 0 ? (s1 | (S) res) < 0) : (s1 & (S) res) < 0)
727 ovf = (U) res < u2 || res < 0
730 ovf = u1 >= u2 ? res < 0 : res >= 0
732 res = (U) s1 - (U) s2
733 ovf = s2 >= 0 ? ((s1 | (S) res) < 0) : ((s1 & (S) res) < 0) */
735 if (code
== PLUS_EXPR
&& uns0_p
&& !uns1_p
)
737 /* PLUS_EXPR is commutative, if operand signedness differs,
738 canonicalize to the first operand being signed and second
739 unsigned to simplify following code. */
740 std::swap (op0
, op1
);
741 std::swap (arg0
, arg1
);
747 if (uns0_p
&& uns1_p
&& unsr_p
)
749 insn_code icode
= optab_handler (code
== PLUS_EXPR
? uaddv4_optab
750 : usubv4_optab
, mode
);
751 if (icode
!= CODE_FOR_nothing
)
753 struct expand_operand ops
[4];
754 rtx_insn
*last
= get_last_insn ();
756 res
= gen_reg_rtx (mode
);
757 create_output_operand (&ops
[0], res
, mode
);
758 create_input_operand (&ops
[1], op0
, mode
);
759 create_input_operand (&ops
[2], op1
, mode
);
760 create_fixed_operand (&ops
[3], do_error
);
761 if (maybe_expand_insn (icode
, 4, ops
))
763 last
= get_last_insn ();
764 if (profile_status_for_fn (cfun
) != PROFILE_ABSENT
766 && any_condjump_p (last
)
767 && !find_reg_note (last
, REG_BR_PROB
, 0))
768 add_reg_br_prob_note (last
,
769 profile_probability::very_unlikely ());
770 emit_jump (done_label
);
774 delete_insns_since (last
);
777 /* Compute the operation. On RTL level, the addition is always
779 res
= expand_binop (mode
, code
== PLUS_EXPR
? add_optab
: sub_optab
,
780 op0
, op1
, NULL_RTX
, false, OPTAB_LIB_WIDEN
);
782 /* For PLUS_EXPR, the operation is commutative, so we can pick
783 operand to compare against. For prec <= BITS_PER_WORD, I think
784 preferring REG operand is better over CONST_INT, because
785 the CONST_INT might enlarge the instruction or CSE would need
786 to figure out we'd already loaded it into a register before.
787 For prec > BITS_PER_WORD, I think CONST_INT might be more beneficial,
788 as then the multi-word comparison can be perhaps simplified. */
789 if (code
== PLUS_EXPR
790 && (prec
<= BITS_PER_WORD
791 ? (CONST_SCALAR_INT_P (op0
) && REG_P (op1
))
792 : CONST_SCALAR_INT_P (op1
)))
794 do_compare_rtx_and_jump (res
, tem
, code
== PLUS_EXPR
? GEU
: LEU
,
795 true, mode
, NULL_RTX
, NULL
, done_label
,
796 profile_probability::very_likely ());
801 if (!uns0_p
&& uns1_p
&& !unsr_p
)
803 /* Compute the operation. On RTL level, the addition is always
805 res
= expand_binop (mode
, code
== PLUS_EXPR
? add_optab
: sub_optab
,
806 op0
, op1
, NULL_RTX
, false, OPTAB_LIB_WIDEN
);
807 rtx tem
= expand_binop (mode
, add_optab
,
808 code
== PLUS_EXPR
? res
: op0
, sgn
,
809 NULL_RTX
, false, OPTAB_LIB_WIDEN
);
810 do_compare_rtx_and_jump (tem
, op1
, GEU
, true, mode
, NULL_RTX
, NULL
,
811 done_label
, profile_probability::very_likely ());
816 if (code
== PLUS_EXPR
&& !uns0_p
&& uns1_p
&& unsr_p
)
818 op1
= expand_binop (mode
, add_optab
, op1
, sgn
, NULL_RTX
, false,
820 /* As we've changed op1, we have to avoid using the value range
821 for the original argument. */
822 arg1
= error_mark_node
;
828 if (code
== MINUS_EXPR
&& uns0_p
&& !uns1_p
&& unsr_p
)
830 op0
= expand_binop (mode
, add_optab
, op0
, sgn
, NULL_RTX
, false,
832 /* As we've changed op0, we have to avoid using the value range
833 for the original argument. */
834 arg0
= error_mark_node
;
840 if (code
== MINUS_EXPR
&& !uns0_p
&& uns1_p
&& unsr_p
)
842 /* Compute the operation. On RTL level, the addition is always
844 res
= expand_binop (mode
, sub_optab
, op0
, op1
, NULL_RTX
, false,
846 int pos_neg
= get_range_pos_neg (arg0
);
848 /* If ARG0 is known to be always negative, this is always overflow. */
849 emit_jump (do_error
);
850 else if (pos_neg
== 3)
851 /* If ARG0 is not known to be always positive, check at runtime. */
852 do_compare_rtx_and_jump (op0
, const0_rtx
, LT
, false, mode
, NULL_RTX
,
853 NULL
, do_error
, profile_probability::very_unlikely ());
854 do_compare_rtx_and_jump (op1
, op0
, LEU
, true, mode
, NULL_RTX
, NULL
,
855 done_label
, profile_probability::very_likely ());
860 if (code
== MINUS_EXPR
&& uns0_p
&& !uns1_p
&& !unsr_p
)
862 /* Compute the operation. On RTL level, the addition is always
864 res
= expand_binop (mode
, sub_optab
, op0
, op1
, NULL_RTX
, false,
866 rtx tem
= expand_binop (mode
, add_optab
, op1
, sgn
, NULL_RTX
, false,
868 do_compare_rtx_and_jump (op0
, tem
, LTU
, true, mode
, NULL_RTX
, NULL
,
869 done_label
, profile_probability::very_likely ());
874 if (code
== PLUS_EXPR
&& uns0_p
&& uns1_p
&& !unsr_p
)
876 /* Compute the operation. On RTL level, the addition is always
878 res
= expand_binop (mode
, add_optab
, op0
, op1
, NULL_RTX
, false,
880 do_compare_rtx_and_jump (res
, const0_rtx
, LT
, false, mode
, NULL_RTX
,
881 NULL
, do_error
, profile_probability::very_unlikely ());
883 /* The operation is commutative, so we can pick operand to compare
884 against. For prec <= BITS_PER_WORD, I think preferring REG operand
885 is better over CONST_INT, because the CONST_INT might enlarge the
886 instruction or CSE would need to figure out we'd already loaded it
887 into a register before. For prec > BITS_PER_WORD, I think CONST_INT
888 might be more beneficial, as then the multi-word comparison can be
889 perhaps simplified. */
890 if (prec
<= BITS_PER_WORD
891 ? (CONST_SCALAR_INT_P (op1
) && REG_P (op0
))
892 : CONST_SCALAR_INT_P (op0
))
894 do_compare_rtx_and_jump (res
, tem
, GEU
, true, mode
, NULL_RTX
, NULL
,
895 done_label
, profile_probability::very_likely ());
900 if (!uns0_p
&& !uns1_p
&& unsr_p
)
902 /* Compute the operation. On RTL level, the addition is always
904 res
= expand_binop (mode
, code
== PLUS_EXPR
? add_optab
: sub_optab
,
905 op0
, op1
, NULL_RTX
, false, OPTAB_LIB_WIDEN
);
906 int pos_neg
= get_range_pos_neg (arg1
);
907 if (code
== PLUS_EXPR
)
909 int pos_neg0
= get_range_pos_neg (arg0
);
910 if (pos_neg0
!= 3 && pos_neg
== 3)
912 std::swap (op0
, op1
);
919 tem
= expand_binop (mode
, ((pos_neg
== 1) ^ (code
== MINUS_EXPR
))
920 ? and_optab
: ior_optab
,
921 op0
, res
, NULL_RTX
, false, OPTAB_LIB_WIDEN
);
922 do_compare_rtx_and_jump (tem
, const0_rtx
, GE
, false, mode
, NULL
,
923 NULL
, done_label
, profile_probability::very_likely ());
927 rtx_code_label
*do_ior_label
= gen_label_rtx ();
928 do_compare_rtx_and_jump (op1
, const0_rtx
,
929 code
== MINUS_EXPR
? GE
: LT
, false, mode
,
930 NULL_RTX
, NULL
, do_ior_label
,
931 profile_probability::even ());
932 tem
= expand_binop (mode
, and_optab
, op0
, res
, NULL_RTX
, false,
934 do_compare_rtx_and_jump (tem
, const0_rtx
, GE
, false, mode
, NULL_RTX
,
935 NULL
, done_label
, profile_probability::very_likely ());
936 emit_jump (do_error
);
937 emit_label (do_ior_label
);
938 tem
= expand_binop (mode
, ior_optab
, op0
, res
, NULL_RTX
, false,
940 do_compare_rtx_and_jump (tem
, const0_rtx
, GE
, false, mode
, NULL_RTX
,
941 NULL
, done_label
, profile_probability::very_likely ());
947 if (code
== MINUS_EXPR
&& uns0_p
&& uns1_p
&& !unsr_p
)
949 /* Compute the operation. On RTL level, the addition is always
951 res
= expand_binop (mode
, sub_optab
, op0
, op1
, NULL_RTX
, false,
953 rtx_code_label
*op0_geu_op1
= gen_label_rtx ();
954 do_compare_rtx_and_jump (op0
, op1
, GEU
, true, mode
, NULL_RTX
, NULL
,
955 op0_geu_op1
, profile_probability::even ());
956 do_compare_rtx_and_jump (res
, const0_rtx
, LT
, false, mode
, NULL_RTX
,
957 NULL
, done_label
, profile_probability::very_likely ());
958 emit_jump (do_error
);
959 emit_label (op0_geu_op1
);
960 do_compare_rtx_and_jump (res
, const0_rtx
, GE
, false, mode
, NULL_RTX
,
961 NULL
, done_label
, profile_probability::very_likely ());
965 gcc_assert (!uns0_p
&& !uns1_p
&& !unsr_p
);
970 insn_code icode
= optab_handler (code
== PLUS_EXPR
? addv4_optab
971 : subv4_optab
, mode
);
972 if (icode
!= CODE_FOR_nothing
)
974 struct expand_operand ops
[4];
975 rtx_insn
*last
= get_last_insn ();
977 res
= gen_reg_rtx (mode
);
978 create_output_operand (&ops
[0], res
, mode
);
979 create_input_operand (&ops
[1], op0
, mode
);
980 create_input_operand (&ops
[2], op1
, mode
);
981 create_fixed_operand (&ops
[3], do_error
);
982 if (maybe_expand_insn (icode
, 4, ops
))
984 last
= get_last_insn ();
985 if (profile_status_for_fn (cfun
) != PROFILE_ABSENT
987 && any_condjump_p (last
)
988 && !find_reg_note (last
, REG_BR_PROB
, 0))
989 add_reg_br_prob_note (last
,
990 profile_probability::very_unlikely ());
991 emit_jump (done_label
);
995 delete_insns_since (last
);
998 /* Compute the operation. On RTL level, the addition is always
1000 res
= expand_binop (mode
, code
== PLUS_EXPR
? add_optab
: sub_optab
,
1001 op0
, op1
, NULL_RTX
, false, OPTAB_LIB_WIDEN
);
1003 /* If we can prove that one of the arguments (for MINUS_EXPR only
1004 the second operand, as subtraction is not commutative) is always
1005 non-negative or always negative, we can do just one comparison
1006 and conditional jump. */
1007 int pos_neg
= get_range_pos_neg (arg1
);
1008 if (code
== PLUS_EXPR
)
1010 int pos_neg0
= get_range_pos_neg (arg0
);
1011 if (pos_neg0
!= 3 && pos_neg
== 3)
1013 std::swap (op0
, op1
);
1018 /* Addition overflows if and only if the two operands have the same sign,
1019 and the result has the opposite sign. Subtraction overflows if and
1020 only if the two operands have opposite sign, and the subtrahend has
1021 the same sign as the result. Here 0 is counted as positive. */
1024 /* Compute op0 ^ op1 (operands have opposite sign). */
1025 rtx op_xor
= expand_binop (mode
, xor_optab
, op0
, op1
, NULL_RTX
, false,
1028 /* Compute res ^ op1 (result and 2nd operand have opposite sign). */
1029 rtx res_xor
= expand_binop (mode
, xor_optab
, res
, op1
, NULL_RTX
, false,
1033 if (code
== PLUS_EXPR
)
1035 /* Compute (res ^ op1) & ~(op0 ^ op1). */
1036 tem
= expand_unop (mode
, one_cmpl_optab
, op_xor
, NULL_RTX
, false);
1037 tem
= expand_binop (mode
, and_optab
, res_xor
, tem
, NULL_RTX
, false,
1042 /* Compute (op0 ^ op1) & ~(res ^ op1). */
1043 tem
= expand_unop (mode
, one_cmpl_optab
, res_xor
, NULL_RTX
, false);
1044 tem
= expand_binop (mode
, and_optab
, op_xor
, tem
, NULL_RTX
, false,
1048 /* No overflow if the result has bit sign cleared. */
1049 do_compare_rtx_and_jump (tem
, const0_rtx
, GE
, false, mode
, NULL_RTX
,
1050 NULL
, done_label
, profile_probability::very_likely ());
1053 /* Compare the result of the operation with the first operand.
1054 No overflow for addition if second operand is positive and result
1055 is larger or second operand is negative and result is smaller.
1056 Likewise for subtraction with sign of second operand flipped. */
1058 do_compare_rtx_and_jump (res
, op0
,
1059 (pos_neg
== 1) ^ (code
== MINUS_EXPR
) ? GE
: LE
,
1060 false, mode
, NULL_RTX
, NULL
, done_label
,
1061 profile_probability::very_likely ());
1065 emit_label (do_error
);
1068 /* Expand the ubsan builtin call. */
1070 fn
= ubsan_build_overflow_builtin (code
, loc
, TREE_TYPE (arg0
),
1074 do_pending_stack_adjust ();
1077 expand_arith_set_overflow (lhs
, target
);
1080 emit_label (done_label
);
1085 expand_ubsan_result_store (target
, res
);
1089 res
= expand_binop (mode
, add_optab
, res
, sgn
, NULL_RTX
, false,
1092 expand_arith_overflow_result_store (lhs
, target
, mode
, res
);
1097 /* Add negate overflow checking to the statement STMT. */
1100 expand_neg_overflow (location_t loc
, tree lhs
, tree arg1
, bool is_ubsan
,
1105 rtx_code_label
*done_label
, *do_error
;
1106 rtx target
= NULL_RTX
;
1108 done_label
= gen_label_rtx ();
1109 do_error
= gen_label_rtx ();
1111 do_pending_stack_adjust ();
1112 op1
= expand_normal (arg1
);
1114 scalar_int_mode mode
= SCALAR_INT_TYPE_MODE (TREE_TYPE (arg1
));
1117 target
= expand_expr (lhs
, NULL_RTX
, VOIDmode
, EXPAND_WRITE
);
1119 write_complex_part (target
, const0_rtx
, true);
1122 enum insn_code icode
= optab_handler (negv3_optab
, mode
);
1123 if (icode
!= CODE_FOR_nothing
)
1125 struct expand_operand ops
[3];
1126 rtx_insn
*last
= get_last_insn ();
1128 res
= gen_reg_rtx (mode
);
1129 create_output_operand (&ops
[0], res
, mode
);
1130 create_input_operand (&ops
[1], op1
, mode
);
1131 create_fixed_operand (&ops
[2], do_error
);
1132 if (maybe_expand_insn (icode
, 3, ops
))
1134 last
= get_last_insn ();
1135 if (profile_status_for_fn (cfun
) != PROFILE_ABSENT
1137 && any_condjump_p (last
)
1138 && !find_reg_note (last
, REG_BR_PROB
, 0))
1139 add_reg_br_prob_note (last
,
1140 profile_probability::very_unlikely ());
1141 emit_jump (done_label
);
1145 delete_insns_since (last
);
1146 icode
= CODE_FOR_nothing
;
1150 if (icode
== CODE_FOR_nothing
)
1152 /* Compute the operation. On RTL level, the addition is always
1154 res
= expand_unop (mode
, neg_optab
, op1
, NULL_RTX
, false);
1156 /* Compare the operand with the most negative value. */
1157 rtx minv
= expand_normal (TYPE_MIN_VALUE (TREE_TYPE (arg1
)));
1158 do_compare_rtx_and_jump (op1
, minv
, NE
, true, mode
, NULL_RTX
, NULL
,
1159 done_label
, profile_probability::very_likely ());
1162 emit_label (do_error
);
1165 /* Expand the ubsan builtin call. */
1167 fn
= ubsan_build_overflow_builtin (NEGATE_EXPR
, loc
, TREE_TYPE (arg1
),
1168 arg1
, NULL_TREE
, datap
);
1171 do_pending_stack_adjust ();
1174 expand_arith_set_overflow (lhs
, target
);
1177 emit_label (done_label
);
1182 expand_ubsan_result_store (target
, res
);
1184 expand_arith_overflow_result_store (lhs
, target
, mode
, res
);
1188 /* Return true if UNS WIDEN_MULT_EXPR with result mode WMODE and operand
1189 mode MODE can be expanded without using a libcall. */
1192 can_widen_mult_without_libcall (scalar_int_mode wmode
, scalar_int_mode mode
,
1193 rtx op0
, rtx op1
, bool uns
)
1195 if (find_widening_optab_handler (umul_widen_optab
, wmode
, mode
)
1196 != CODE_FOR_nothing
)
1199 if (find_widening_optab_handler (smul_widen_optab
, wmode
, mode
)
1200 != CODE_FOR_nothing
)
1203 rtx_insn
*last
= get_last_insn ();
1204 if (CONSTANT_P (op0
))
1205 op0
= convert_modes (wmode
, mode
, op0
, uns
);
1207 op0
= gen_raw_REG (wmode
, LAST_VIRTUAL_REGISTER
+ 1);
1208 if (CONSTANT_P (op1
))
1209 op1
= convert_modes (wmode
, mode
, op1
, uns
);
1211 op1
= gen_raw_REG (wmode
, LAST_VIRTUAL_REGISTER
+ 2);
1212 rtx ret
= expand_mult (wmode
, op0
, op1
, NULL_RTX
, uns
, true);
1213 delete_insns_since (last
);
1214 return ret
!= NULL_RTX
;
1217 /* Add mul overflow checking to the statement STMT. */
1220 expand_mul_overflow (location_t loc
, tree lhs
, tree arg0
, tree arg1
,
1221 bool unsr_p
, bool uns0_p
, bool uns1_p
, bool is_ubsan
,
1226 rtx_code_label
*done_label
, *do_error
;
1227 rtx target
= NULL_RTX
;
1229 enum insn_code icode
;
1231 done_label
= gen_label_rtx ();
1232 do_error
= gen_label_rtx ();
1234 do_pending_stack_adjust ();
1235 op0
= expand_normal (arg0
);
1236 op1
= expand_normal (arg1
);
1238 scalar_int_mode mode
= SCALAR_INT_TYPE_MODE (TREE_TYPE (arg0
));
1242 target
= expand_expr (lhs
, NULL_RTX
, VOIDmode
, EXPAND_WRITE
);
1244 write_complex_part (target
, const0_rtx
, true);
1248 gcc_assert (!unsr_p
&& !uns0_p
&& !uns1_p
);
1250 /* We assume both operands and result have the same precision
1251 here (GET_MODE_BITSIZE (mode)), S stands for signed type
1252 with that precision, U for unsigned type with that precision,
1253 sgn for unsigned most significant bit in that precision.
1254 s1 is signed first operand, u1 is unsigned first operand,
1255 s2 is signed second operand, u2 is unsigned second operand,
1256 sr is signed result, ur is unsigned result and the following
1257 rules say how to compute result (which is always result of
1258 the operands as if both were unsigned, cast to the right
1259 signedness) and how to compute whether operation overflowed.
1260 main_ovf (false) stands for jump on signed multiplication
1261 overflow or the main algorithm with uns == false.
1262 main_ovf (true) stands for jump on unsigned multiplication
1263 overflow or the main algorithm with uns == true.
1266 res = (S) ((U) s1 * (U) s2)
1267 ovf = main_ovf (false)
1270 ovf = main_ovf (true)
1273 ovf = (s1 < 0 && u2) || main_ovf (true)
1276 ovf = res < 0 || main_ovf (true)
1278 res = (S) ((U) s1 * u2)
1279 ovf = (S) u2 >= 0 ? main_ovf (false)
1280 : (s1 != 0 && (s1 != -1 || u2 != (U) res))
1282 t1 = (s1 & s2) < 0 ? (-(U) s1) : ((U) s1)
1283 t2 = (s1 & s2) < 0 ? (-(U) s2) : ((U) s2)
1285 ovf = (s1 ^ s2) < 0 ? (s1 && s2) : main_ovf (true) */
1287 if (uns0_p
&& !uns1_p
)
1289 /* Multiplication is commutative, if operand signedness differs,
1290 canonicalize to the first operand being signed and second
1291 unsigned to simplify following code. */
1292 std::swap (op0
, op1
);
1293 std::swap (arg0
, arg1
);
1298 int pos_neg0
= get_range_pos_neg (arg0
);
1299 int pos_neg1
= get_range_pos_neg (arg1
);
1302 if (!uns0_p
&& uns1_p
&& unsr_p
)
1307 /* If s1 is non-negative, just perform normal u1 * u2 -> ur. */
1310 /* If s1 is negative, avoid the main code, just multiply and
1311 signal overflow if op1 is not 0. */
1312 struct separate_ops ops
;
1313 ops
.code
= MULT_EXPR
;
1314 ops
.type
= TREE_TYPE (arg1
);
1315 ops
.op0
= make_tree (ops
.type
, op0
);
1316 ops
.op1
= make_tree (ops
.type
, op1
);
1317 ops
.op2
= NULL_TREE
;
1319 res
= expand_expr_real_2 (&ops
, NULL_RTX
, mode
, EXPAND_NORMAL
);
1320 do_compare_rtx_and_jump (op1
, const0_rtx
, EQ
, true, mode
, NULL_RTX
,
1321 NULL
, done_label
, profile_probability::very_likely ());
1322 goto do_error_label
;
1324 rtx_code_label
*do_main_label
;
1325 do_main_label
= gen_label_rtx ();
1326 do_compare_rtx_and_jump (op0
, const0_rtx
, GE
, false, mode
, NULL_RTX
,
1327 NULL
, do_main_label
, profile_probability::very_likely ());
1328 do_compare_rtx_and_jump (op1
, const0_rtx
, EQ
, true, mode
, NULL_RTX
,
1329 NULL
, do_main_label
, profile_probability::very_likely ());
1330 expand_arith_set_overflow (lhs
, target
);
1331 emit_label (do_main_label
);
1339 if (uns0_p
&& uns1_p
&& !unsr_p
)
1342 /* Rest of handling of this case after res is computed. */
1347 if (!uns0_p
&& uns1_p
&& !unsr_p
)
1354 /* If (S) u2 is negative (i.e. u2 is larger than maximum of S,
1355 avoid the main code, just multiply and signal overflow
1356 unless 0 * u2 or -1 * ((U) Smin). */
1357 struct separate_ops ops
;
1358 ops
.code
= MULT_EXPR
;
1359 ops
.type
= TREE_TYPE (arg1
);
1360 ops
.op0
= make_tree (ops
.type
, op0
);
1361 ops
.op1
= make_tree (ops
.type
, op1
);
1362 ops
.op2
= NULL_TREE
;
1364 res
= expand_expr_real_2 (&ops
, NULL_RTX
, mode
, EXPAND_NORMAL
);
1365 do_compare_rtx_and_jump (op0
, const0_rtx
, EQ
, true, mode
, NULL_RTX
,
1366 NULL
, done_label
, profile_probability::very_likely ());
1367 do_compare_rtx_and_jump (op0
, constm1_rtx
, NE
, true, mode
, NULL_RTX
,
1368 NULL
, do_error
, profile_probability::very_unlikely ());
1370 prec
= GET_MODE_PRECISION (mode
);
1372 sgn
= immed_wide_int_const (wi::min_value (prec
, SIGNED
), mode
);
1373 do_compare_rtx_and_jump (op1
, sgn
, EQ
, true, mode
, NULL_RTX
,
1374 NULL
, done_label
, profile_probability::very_likely ());
1375 goto do_error_label
;
1377 /* Rest of handling of this case after res is computed. */
1385 if (!uns0_p
&& !uns1_p
&& unsr_p
)
1388 switch (pos_neg0
| pos_neg1
)
1390 case 1: /* Both operands known to be non-negative. */
1392 case 2: /* Both operands known to be negative. */
1393 op0
= expand_unop (mode
, neg_optab
, op0
, NULL_RTX
, false);
1394 op1
= expand_unop (mode
, neg_optab
, op1
, NULL_RTX
, false);
1395 /* Avoid looking at arg0/arg1 ranges, as we've changed
1397 arg0
= error_mark_node
;
1398 arg1
= error_mark_node
;
1401 if ((pos_neg0
^ pos_neg1
) == 3)
1403 /* If one operand is known to be negative and the other
1404 non-negative, this overflows always, unless the non-negative
1405 one is 0. Just do normal multiply and set overflow
1406 unless one of the operands is 0. */
1407 struct separate_ops ops
;
1408 ops
.code
= MULT_EXPR
;
1410 = build_nonstandard_integer_type (GET_MODE_PRECISION (mode
),
1412 ops
.op0
= make_tree (ops
.type
, op0
);
1413 ops
.op1
= make_tree (ops
.type
, op1
);
1414 ops
.op2
= NULL_TREE
;
1416 res
= expand_expr_real_2 (&ops
, NULL_RTX
, mode
, EXPAND_NORMAL
);
1417 tem
= expand_binop (mode
, and_optab
, op0
, op1
, NULL_RTX
, false,
1419 do_compare_rtx_and_jump (tem
, const0_rtx
, EQ
, true, mode
,
1420 NULL_RTX
, NULL
, done_label
,
1421 profile_probability::very_likely ());
1422 goto do_error_label
;
1424 /* The general case, do all the needed comparisons at runtime. */
1425 rtx_code_label
*do_main_label
, *after_negate_label
;
1427 rop0
= gen_reg_rtx (mode
);
1428 rop1
= gen_reg_rtx (mode
);
1429 emit_move_insn (rop0
, op0
);
1430 emit_move_insn (rop1
, op1
);
1433 do_main_label
= gen_label_rtx ();
1434 after_negate_label
= gen_label_rtx ();
1435 tem
= expand_binop (mode
, and_optab
, op0
, op1
, NULL_RTX
, false,
1437 do_compare_rtx_and_jump (tem
, const0_rtx
, GE
, false, mode
, NULL_RTX
,
1438 NULL
, after_negate_label
, profile_probability::very_likely ());
1439 /* Both arguments negative here, negate them and continue with
1440 normal unsigned overflow checking multiplication. */
1441 emit_move_insn (op0
, expand_unop (mode
, neg_optab
, op0
,
1443 emit_move_insn (op1
, expand_unop (mode
, neg_optab
, op1
,
1445 /* Avoid looking at arg0/arg1 ranges, as we might have changed
1447 arg0
= error_mark_node
;
1448 arg1
= error_mark_node
;
1449 emit_jump (do_main_label
);
1450 emit_label (after_negate_label
);
1451 tem2
= expand_binop (mode
, xor_optab
, op0
, op1
, NULL_RTX
, false,
1453 do_compare_rtx_and_jump (tem2
, const0_rtx
, GE
, false, mode
, NULL_RTX
,
1454 NULL
, do_main_label
, profile_probability::very_likely ());
1455 /* One argument is negative here, the other positive. This
1456 overflows always, unless one of the arguments is 0. But
1457 if e.g. s2 is 0, (U) s1 * 0 doesn't overflow, whatever s1
1458 is, thus we can keep do_main code oring in overflow as is. */
1459 do_compare_rtx_and_jump (tem
, const0_rtx
, EQ
, true, mode
, NULL_RTX
,
1460 NULL
, do_main_label
, profile_probability::very_likely ());
1461 expand_arith_set_overflow (lhs
, target
);
1462 emit_label (do_main_label
);
1470 type
= build_nonstandard_integer_type (GET_MODE_PRECISION (mode
), uns
);
1471 sign
= uns
? UNSIGNED
: SIGNED
;
1472 icode
= optab_handler (uns
? umulv4_optab
: mulv4_optab
, mode
);
1474 && (integer_pow2p (arg0
) || integer_pow2p (arg1
))
1475 && (optimize_insn_for_speed_p () || icode
== CODE_FOR_nothing
))
1477 /* Optimize unsigned multiplication by power of 2 constant
1478 using 2 shifts, one for result, one to extract the shifted
1479 out bits to see if they are all zero.
1480 Don't do this if optimizing for size and we have umulv4_optab,
1481 in that case assume multiplication will be shorter.
1482 This is heuristics based on the single target that provides
1483 umulv4 right now (i?86/x86_64), if further targets add it, this
1484 might need to be revisited.
1485 Cases where both operands are constant should be folded already
1486 during GIMPLE, and cases where one operand is constant but not
1487 power of 2 are questionable, either the WIDEN_MULT_EXPR case
1488 below can be done without multiplication, just by shifts and adds,
1489 or we'd need to divide the result (and hope it actually doesn't
1490 really divide nor multiply) and compare the result of the division
1491 with the original operand. */
1496 if (integer_pow2p (arg0
))
1498 std::swap (opn0
, opn1
);
1499 std::swap (argn0
, argn1
);
1501 int cnt
= tree_log2 (argn1
);
1502 if (cnt
>= 0 && cnt
< GET_MODE_PRECISION (mode
))
1504 rtx upper
= const0_rtx
;
1505 res
= expand_shift (LSHIFT_EXPR
, mode
, opn0
, cnt
, NULL_RTX
, uns
);
1507 upper
= expand_shift (RSHIFT_EXPR
, mode
, opn0
,
1508 GET_MODE_PRECISION (mode
) - cnt
,
1510 do_compare_rtx_and_jump (upper
, const0_rtx
, EQ
, true, mode
,
1511 NULL_RTX
, NULL
, done_label
,
1512 profile_probability::very_likely ());
1513 goto do_error_label
;
1516 if (icode
!= CODE_FOR_nothing
)
1518 struct expand_operand ops
[4];
1519 rtx_insn
*last
= get_last_insn ();
1521 res
= gen_reg_rtx (mode
);
1522 create_output_operand (&ops
[0], res
, mode
);
1523 create_input_operand (&ops
[1], op0
, mode
);
1524 create_input_operand (&ops
[2], op1
, mode
);
1525 create_fixed_operand (&ops
[3], do_error
);
1526 if (maybe_expand_insn (icode
, 4, ops
))
1528 last
= get_last_insn ();
1529 if (profile_status_for_fn (cfun
) != PROFILE_ABSENT
1531 && any_condjump_p (last
)
1532 && !find_reg_note (last
, REG_BR_PROB
, 0))
1533 add_reg_br_prob_note (last
,
1534 profile_probability::very_unlikely ());
1535 emit_jump (done_label
);
1539 delete_insns_since (last
);
1540 icode
= CODE_FOR_nothing
;
1544 if (icode
== CODE_FOR_nothing
)
1546 struct separate_ops ops
;
1547 int prec
= GET_MODE_PRECISION (mode
);
1548 scalar_int_mode hmode
, wmode
;
1549 ops
.op0
= make_tree (type
, op0
);
1550 ops
.op1
= make_tree (type
, op1
);
1551 ops
.op2
= NULL_TREE
;
1554 /* Optimize unsigned overflow check where we don't use the
1555 multiplication result, just whether overflow happened.
1556 If we can do MULT_HIGHPART_EXPR, that followed by
1557 comparison of the result against zero is cheapest.
1558 We'll still compute res, but it should be DCEd later. */
1564 && !(uns0_p
&& uns1_p
&& !unsr_p
)
1565 && can_mult_highpart_p (mode
, uns
) == 1
1566 && single_imm_use (lhs
, &use
, &use_stmt
)
1567 && is_gimple_assign (use_stmt
)
1568 && gimple_assign_rhs_code (use_stmt
) == IMAGPART_EXPR
)
1571 if (GET_MODE_2XWIDER_MODE (mode
).exists (&wmode
)
1572 && targetm
.scalar_mode_supported_p (wmode
)
1573 && can_widen_mult_without_libcall (wmode
, mode
, op0
, op1
, uns
))
1576 ops
.code
= WIDEN_MULT_EXPR
;
1578 = build_nonstandard_integer_type (GET_MODE_PRECISION (wmode
), uns
);
1580 res
= expand_expr_real_2 (&ops
, NULL_RTX
, wmode
, EXPAND_NORMAL
);
1581 rtx hipart
= expand_shift (RSHIFT_EXPR
, wmode
, res
, prec
,
1583 hipart
= convert_modes (mode
, wmode
, hipart
, uns
);
1584 res
= convert_modes (mode
, wmode
, res
, uns
);
1586 /* For the unsigned multiplication, there was overflow if
1587 HIPART is non-zero. */
1588 do_compare_rtx_and_jump (hipart
, const0_rtx
, EQ
, true, mode
,
1589 NULL_RTX
, NULL
, done_label
,
1590 profile_probability::very_likely ());
1593 rtx signbit
= expand_shift (RSHIFT_EXPR
, mode
, res
, prec
- 1,
1595 /* RES is low half of the double width result, HIPART
1596 the high half. There was overflow if
1597 HIPART is different from RES < 0 ? -1 : 0. */
1598 do_compare_rtx_and_jump (signbit
, hipart
, EQ
, true, mode
,
1599 NULL_RTX
, NULL
, done_label
,
1600 profile_probability::very_likely ());
1603 else if (can_mult_highpart_p (mode
, uns
) == 1)
1606 ops
.code
= MULT_HIGHPART_EXPR
;
1609 rtx hipart
= expand_expr_real_2 (&ops
, NULL_RTX
, mode
,
1611 ops
.code
= MULT_EXPR
;
1612 res
= expand_expr_real_2 (&ops
, NULL_RTX
, mode
, EXPAND_NORMAL
);
1614 /* For the unsigned multiplication, there was overflow if
1615 HIPART is non-zero. */
1616 do_compare_rtx_and_jump (hipart
, const0_rtx
, EQ
, true, mode
,
1617 NULL_RTX
, NULL
, done_label
,
1618 profile_probability::very_likely ());
1621 rtx signbit
= expand_shift (RSHIFT_EXPR
, mode
, res
, prec
- 1,
1623 /* RES is low half of the double width result, HIPART
1624 the high half. There was overflow if
1625 HIPART is different from RES < 0 ? -1 : 0. */
1626 do_compare_rtx_and_jump (signbit
, hipart
, EQ
, true, mode
,
1627 NULL_RTX
, NULL
, done_label
,
1628 profile_probability::very_likely ());
1632 else if (int_mode_for_size (prec
/ 2, 1).exists (&hmode
)
1633 && 2 * GET_MODE_PRECISION (hmode
) == prec
)
1635 rtx_code_label
*large_op0
= gen_label_rtx ();
1636 rtx_code_label
*small_op0_large_op1
= gen_label_rtx ();
1637 rtx_code_label
*one_small_one_large
= gen_label_rtx ();
1638 rtx_code_label
*both_ops_large
= gen_label_rtx ();
1639 rtx_code_label
*after_hipart_neg
= uns
? NULL
: gen_label_rtx ();
1640 rtx_code_label
*after_lopart_neg
= uns
? NULL
: gen_label_rtx ();
1641 rtx_code_label
*do_overflow
= gen_label_rtx ();
1642 rtx_code_label
*hipart_different
= uns
? NULL
: gen_label_rtx ();
1644 unsigned int hprec
= GET_MODE_PRECISION (hmode
);
1645 rtx hipart0
= expand_shift (RSHIFT_EXPR
, mode
, op0
, hprec
,
1647 hipart0
= convert_modes (hmode
, mode
, hipart0
, uns
);
1648 rtx lopart0
= convert_modes (hmode
, mode
, op0
, uns
);
1649 rtx signbit0
= const0_rtx
;
1651 signbit0
= expand_shift (RSHIFT_EXPR
, hmode
, lopart0
, hprec
- 1,
1653 rtx hipart1
= expand_shift (RSHIFT_EXPR
, mode
, op1
, hprec
,
1655 hipart1
= convert_modes (hmode
, mode
, hipart1
, uns
);
1656 rtx lopart1
= convert_modes (hmode
, mode
, op1
, uns
);
1657 rtx signbit1
= const0_rtx
;
1659 signbit1
= expand_shift (RSHIFT_EXPR
, hmode
, lopart1
, hprec
- 1,
1662 res
= gen_reg_rtx (mode
);
1664 /* True if op0 resp. op1 are known to be in the range of
1666 bool op0_small_p
= false;
1667 bool op1_small_p
= false;
1668 /* True if op0 resp. op1 are known to have all zeros or all ones
1669 in the upper half of bits, but are not known to be
1671 bool op0_medium_p
= false;
1672 bool op1_medium_p
= false;
1673 /* -1 if op{0,1} is known to be negative, 0 if it is known to be
1674 nonnegative, 1 if unknown. */
1680 else if (pos_neg0
== 2)
1684 else if (pos_neg1
== 2)
1687 unsigned int mprec0
= prec
;
1688 if (arg0
!= error_mark_node
)
1689 mprec0
= get_min_precision (arg0
, sign
);
1690 if (mprec0
<= hprec
)
1692 else if (!uns
&& mprec0
<= hprec
+ 1)
1693 op0_medium_p
= true;
1694 unsigned int mprec1
= prec
;
1695 if (arg1
!= error_mark_node
)
1696 mprec1
= get_min_precision (arg1
, sign
);
1697 if (mprec1
<= hprec
)
1699 else if (!uns
&& mprec1
<= hprec
+ 1)
1700 op1_medium_p
= true;
1702 int smaller_sign
= 1;
1703 int larger_sign
= 1;
1706 smaller_sign
= op0_sign
;
1707 larger_sign
= op1_sign
;
1709 else if (op1_small_p
)
1711 smaller_sign
= op1_sign
;
1712 larger_sign
= op0_sign
;
1714 else if (op0_sign
== op1_sign
)
1716 smaller_sign
= op0_sign
;
1717 larger_sign
= op0_sign
;
1721 do_compare_rtx_and_jump (signbit0
, hipart0
, NE
, true, hmode
,
1722 NULL_RTX
, NULL
, large_op0
,
1723 profile_probability::unlikely ());
1726 do_compare_rtx_and_jump (signbit1
, hipart1
, NE
, true, hmode
,
1727 NULL_RTX
, NULL
, small_op0_large_op1
,
1728 profile_probability::unlikely ());
1730 /* If both op0 and op1 are sign (!uns) or zero (uns) extended from
1731 hmode to mode, the multiplication will never overflow. We can
1732 do just one hmode x hmode => mode widening multiplication. */
1733 rtx lopart0s
= lopart0
, lopart1s
= lopart1
;
1734 if (GET_CODE (lopart0
) == SUBREG
)
1736 lopart0s
= shallow_copy_rtx (lopart0
);
1737 SUBREG_PROMOTED_VAR_P (lopart0s
) = 1;
1738 SUBREG_PROMOTED_SET (lopart0s
, uns
? SRP_UNSIGNED
: SRP_SIGNED
);
1740 if (GET_CODE (lopart1
) == SUBREG
)
1742 lopart1s
= shallow_copy_rtx (lopart1
);
1743 SUBREG_PROMOTED_VAR_P (lopart1s
) = 1;
1744 SUBREG_PROMOTED_SET (lopart1s
, uns
? SRP_UNSIGNED
: SRP_SIGNED
);
1746 tree halfstype
= build_nonstandard_integer_type (hprec
, uns
);
1747 ops
.op0
= make_tree (halfstype
, lopart0s
);
1748 ops
.op1
= make_tree (halfstype
, lopart1s
);
1749 ops
.code
= WIDEN_MULT_EXPR
;
1752 = expand_expr_real_2 (&ops
, NULL_RTX
, mode
, EXPAND_NORMAL
);
1753 emit_move_insn (res
, thisres
);
1754 emit_jump (done_label
);
1756 emit_label (small_op0_large_op1
);
1758 /* If op0 is sign (!uns) or zero (uns) extended from hmode to mode,
1759 but op1 is not, just swap the arguments and handle it as op1
1760 sign/zero extended, op0 not. */
1761 rtx larger
= gen_reg_rtx (mode
);
1762 rtx hipart
= gen_reg_rtx (hmode
);
1763 rtx lopart
= gen_reg_rtx (hmode
);
1764 emit_move_insn (larger
, op1
);
1765 emit_move_insn (hipart
, hipart1
);
1766 emit_move_insn (lopart
, lopart0
);
1767 emit_jump (one_small_one_large
);
1769 emit_label (large_op0
);
1772 do_compare_rtx_and_jump (signbit1
, hipart1
, NE
, true, hmode
,
1773 NULL_RTX
, NULL
, both_ops_large
,
1774 profile_probability::unlikely ());
1776 /* If op1 is sign (!uns) or zero (uns) extended from hmode to mode,
1777 but op0 is not, prepare larger, hipart and lopart pseudos and
1778 handle it together with small_op0_large_op1. */
1779 emit_move_insn (larger
, op0
);
1780 emit_move_insn (hipart
, hipart0
);
1781 emit_move_insn (lopart
, lopart1
);
1783 emit_label (one_small_one_large
);
1785 /* lopart is the low part of the operand that is sign extended
1786 to mode, larger is the other operand, hipart is the
1787 high part of larger and lopart0 and lopart1 are the low parts
1789 We perform lopart0 * lopart1 and lopart * hipart widening
1791 tree halfutype
= build_nonstandard_integer_type (hprec
, 1);
1792 ops
.op0
= make_tree (halfutype
, lopart0
);
1793 ops
.op1
= make_tree (halfutype
, lopart1
);
1795 = expand_expr_real_2 (&ops
, NULL_RTX
, mode
, EXPAND_NORMAL
);
1797 ops
.op0
= make_tree (halfutype
, lopart
);
1798 ops
.op1
= make_tree (halfutype
, hipart
);
1799 rtx loxhi
= gen_reg_rtx (mode
);
1800 rtx tem
= expand_expr_real_2 (&ops
, NULL_RTX
, mode
, EXPAND_NORMAL
);
1801 emit_move_insn (loxhi
, tem
);
1805 /* if (hipart < 0) loxhi -= lopart << (bitsize / 2); */
1806 if (larger_sign
== 0)
1807 emit_jump (after_hipart_neg
);
1808 else if (larger_sign
!= -1)
1809 do_compare_rtx_and_jump (hipart
, const0_rtx
, GE
, false, hmode
,
1810 NULL_RTX
, NULL
, after_hipart_neg
,
1811 profile_probability::even ());
1813 tem
= convert_modes (mode
, hmode
, lopart
, 1);
1814 tem
= expand_shift (LSHIFT_EXPR
, mode
, tem
, hprec
, NULL_RTX
, 1);
1815 tem
= expand_simple_binop (mode
, MINUS
, loxhi
, tem
, NULL_RTX
,
1817 emit_move_insn (loxhi
, tem
);
1819 emit_label (after_hipart_neg
);
1821 /* if (lopart < 0) loxhi -= larger; */
1822 if (smaller_sign
== 0)
1823 emit_jump (after_lopart_neg
);
1824 else if (smaller_sign
!= -1)
1825 do_compare_rtx_and_jump (lopart
, const0_rtx
, GE
, false, hmode
,
1826 NULL_RTX
, NULL
, after_lopart_neg
,
1827 profile_probability::even ());
1829 tem
= expand_simple_binop (mode
, MINUS
, loxhi
, larger
, NULL_RTX
,
1831 emit_move_insn (loxhi
, tem
);
1833 emit_label (after_lopart_neg
);
1836 /* loxhi += (uns) lo0xlo1 >> (bitsize / 2); */
1837 tem
= expand_shift (RSHIFT_EXPR
, mode
, lo0xlo1
, hprec
, NULL_RTX
, 1);
1838 tem
= expand_simple_binop (mode
, PLUS
, loxhi
, tem
, NULL_RTX
,
1840 emit_move_insn (loxhi
, tem
);
1842 /* if (loxhi >> (bitsize / 2)
1843 == (hmode) loxhi >> (bitsize / 2 - 1)) (if !uns)
1844 if (loxhi >> (bitsize / 2) == 0 (if uns). */
1845 rtx hipartloxhi
= expand_shift (RSHIFT_EXPR
, mode
, loxhi
, hprec
,
1847 hipartloxhi
= convert_modes (hmode
, mode
, hipartloxhi
, 0);
1848 rtx signbitloxhi
= const0_rtx
;
1850 signbitloxhi
= expand_shift (RSHIFT_EXPR
, hmode
,
1851 convert_modes (hmode
, mode
,
1853 hprec
- 1, NULL_RTX
, 0);
1855 do_compare_rtx_and_jump (signbitloxhi
, hipartloxhi
, NE
, true, hmode
,
1856 NULL_RTX
, NULL
, do_overflow
,
1857 profile_probability::very_unlikely ());
1859 /* res = (loxhi << (bitsize / 2)) | (hmode) lo0xlo1; */
1860 rtx loxhishifted
= expand_shift (LSHIFT_EXPR
, mode
, loxhi
, hprec
,
1862 tem
= convert_modes (mode
, hmode
,
1863 convert_modes (hmode
, mode
, lo0xlo1
, 1), 1);
1865 tem
= expand_simple_binop (mode
, IOR
, loxhishifted
, tem
, res
,
1868 emit_move_insn (res
, tem
);
1869 emit_jump (done_label
);
1871 emit_label (both_ops_large
);
1873 /* If both operands are large (not sign (!uns) or zero (uns)
1874 extended from hmode), then perform the full multiplication
1875 which will be the result of the operation.
1876 The only cases which don't overflow are for signed multiplication
1877 some cases where both hipart0 and highpart1 are 0 or -1.
1878 For unsigned multiplication when high parts are both non-zero
1879 this overflows always. */
1880 ops
.code
= MULT_EXPR
;
1881 ops
.op0
= make_tree (type
, op0
);
1882 ops
.op1
= make_tree (type
, op1
);
1883 tem
= expand_expr_real_2 (&ops
, NULL_RTX
, mode
, EXPAND_NORMAL
);
1884 emit_move_insn (res
, tem
);
1890 tem
= expand_simple_binop (hmode
, PLUS
, hipart0
, const1_rtx
,
1891 NULL_RTX
, 1, OPTAB_WIDEN
);
1892 do_compare_rtx_and_jump (tem
, const1_rtx
, GTU
, true, hmode
,
1893 NULL_RTX
, NULL
, do_error
,
1894 profile_probability::very_unlikely ());
1899 tem
= expand_simple_binop (hmode
, PLUS
, hipart1
, const1_rtx
,
1900 NULL_RTX
, 1, OPTAB_WIDEN
);
1901 do_compare_rtx_and_jump (tem
, const1_rtx
, GTU
, true, hmode
,
1902 NULL_RTX
, NULL
, do_error
,
1903 profile_probability::very_unlikely ());
1906 /* At this point hipart{0,1} are both in [-1, 0]. If they are
1907 the same, overflow happened if res is non-positive, if they
1908 are different, overflow happened if res is positive. */
1909 if (op0_sign
!= 1 && op1_sign
!= 1 && op0_sign
!= op1_sign
)
1910 emit_jump (hipart_different
);
1911 else if (op0_sign
== 1 || op1_sign
== 1)
1912 do_compare_rtx_and_jump (hipart0
, hipart1
, NE
, true, hmode
,
1913 NULL_RTX
, NULL
, hipart_different
,
1914 profile_probability::even ());
1916 do_compare_rtx_and_jump (res
, const0_rtx
, LE
, false, mode
,
1917 NULL_RTX
, NULL
, do_error
,
1918 profile_probability::very_unlikely ());
1919 emit_jump (done_label
);
1921 emit_label (hipart_different
);
1923 do_compare_rtx_and_jump (res
, const0_rtx
, GE
, false, mode
,
1924 NULL_RTX
, NULL
, do_error
,
1925 profile_probability::very_unlikely ());
1926 emit_jump (done_label
);
1929 emit_label (do_overflow
);
1931 /* Overflow, do full multiplication and fallthru into do_error. */
1932 ops
.op0
= make_tree (type
, op0
);
1933 ops
.op1
= make_tree (type
, op1
);
1934 tem
= expand_expr_real_2 (&ops
, NULL_RTX
, mode
, EXPAND_NORMAL
);
1935 emit_move_insn (res
, tem
);
1937 else if (GET_MODE_2XWIDER_MODE (mode
).exists (&wmode
)
1938 && targetm
.scalar_mode_supported_p (wmode
))
1939 /* Even emitting a libcall is better than not detecting overflow
1944 gcc_assert (!is_ubsan
);
1945 ops
.code
= MULT_EXPR
;
1947 res
= expand_expr_real_2 (&ops
, NULL_RTX
, mode
, EXPAND_NORMAL
);
1948 emit_jump (done_label
);
1953 emit_label (do_error
);
1956 /* Expand the ubsan builtin call. */
1958 fn
= ubsan_build_overflow_builtin (MULT_EXPR
, loc
, TREE_TYPE (arg0
),
1962 do_pending_stack_adjust ();
1965 expand_arith_set_overflow (lhs
, target
);
1968 emit_label (done_label
);
1971 if (uns0_p
&& uns1_p
&& !unsr_p
)
1973 rtx_code_label
*all_done_label
= gen_label_rtx ();
1974 do_compare_rtx_and_jump (res
, const0_rtx
, GE
, false, mode
, NULL_RTX
,
1975 NULL
, all_done_label
, profile_probability::very_likely ());
1976 expand_arith_set_overflow (lhs
, target
);
1977 emit_label (all_done_label
);
1981 if (!uns0_p
&& uns1_p
&& !unsr_p
&& pos_neg1
== 3)
1983 rtx_code_label
*all_done_label
= gen_label_rtx ();
1984 rtx_code_label
*set_noovf
= gen_label_rtx ();
1985 do_compare_rtx_and_jump (op1
, const0_rtx
, GE
, false, mode
, NULL_RTX
,
1986 NULL
, all_done_label
, profile_probability::very_likely ());
1987 expand_arith_set_overflow (lhs
, target
);
1988 do_compare_rtx_and_jump (op0
, const0_rtx
, EQ
, true, mode
, NULL_RTX
,
1989 NULL
, set_noovf
, profile_probability::very_likely ());
1990 do_compare_rtx_and_jump (op0
, constm1_rtx
, NE
, true, mode
, NULL_RTX
,
1991 NULL
, all_done_label
, profile_probability::very_unlikely ());
1992 do_compare_rtx_and_jump (op1
, res
, NE
, true, mode
, NULL_RTX
, NULL
,
1993 all_done_label
, profile_probability::very_unlikely ());
1994 emit_label (set_noovf
);
1995 write_complex_part (target
, const0_rtx
, true);
1996 emit_label (all_done_label
);
2002 expand_ubsan_result_store (target
, res
);
2004 expand_arith_overflow_result_store (lhs
, target
, mode
, res
);
2008 /* Expand UBSAN_CHECK_* internal function if it has vector operands. */
2011 expand_vector_ubsan_overflow (location_t loc
, enum tree_code code
, tree lhs
,
2012 tree arg0
, tree arg1
)
2014 poly_uint64 cnt
= TYPE_VECTOR_SUBPARTS (TREE_TYPE (arg0
));
2015 rtx_code_label
*loop_lab
= NULL
;
2016 rtx cntvar
= NULL_RTX
;
2017 tree cntv
= NULL_TREE
;
2018 tree eltype
= TREE_TYPE (TREE_TYPE (arg0
));
2019 tree sz
= TYPE_SIZE (eltype
);
2020 tree data
= NULL_TREE
;
2021 tree resv
= NULL_TREE
;
2022 rtx lhsr
= NULL_RTX
;
2023 rtx resvr
= NULL_RTX
;
2024 unsigned HOST_WIDE_INT const_cnt
= 0;
2025 bool use_loop_p
= (!cnt
.is_constant (&const_cnt
) || const_cnt
> 4);
2030 lhsr
= expand_expr (lhs
, NULL_RTX
, VOIDmode
, EXPAND_WRITE
);
2031 if (!VECTOR_MODE_P (GET_MODE (lhsr
))
2032 || (op
= optab_for_tree_code (code
, TREE_TYPE (arg0
),
2033 optab_default
)) == unknown_optab
2034 || (optab_handler (op
, TYPE_MODE (TREE_TYPE (arg0
)))
2035 == CODE_FOR_nothing
))
2038 resv
= make_tree (TREE_TYPE (lhs
), lhsr
);
2041 resvr
= assign_temp (TREE_TYPE (lhs
), 1, 1);
2042 resv
= make_tree (TREE_TYPE (lhs
), resvr
);
2048 do_pending_stack_adjust ();
2049 loop_lab
= gen_label_rtx ();
2050 cntvar
= gen_reg_rtx (TYPE_MODE (sizetype
));
2051 cntv
= make_tree (sizetype
, cntvar
);
2052 emit_move_insn (cntvar
, const0_rtx
);
2053 emit_label (loop_lab
);
2055 if (TREE_CODE (arg0
) != VECTOR_CST
)
2057 rtx arg0r
= expand_normal (arg0
);
2058 arg0
= make_tree (TREE_TYPE (arg0
), arg0r
);
2060 if (TREE_CODE (arg1
) != VECTOR_CST
)
2062 rtx arg1r
= expand_normal (arg1
);
2063 arg1
= make_tree (TREE_TYPE (arg1
), arg1r
);
2065 for (unsigned int i
= 0; i
< (use_loop_p
? 1 : const_cnt
); i
++)
2067 tree op0
, op1
, res
= NULL_TREE
;
2070 tree atype
= build_array_type_nelts (eltype
, cnt
);
2071 op0
= uniform_vector_p (arg0
);
2072 if (op0
== NULL_TREE
)
2074 op0
= fold_build1_loc (loc
, VIEW_CONVERT_EXPR
, atype
, arg0
);
2075 op0
= build4_loc (loc
, ARRAY_REF
, eltype
, op0
, cntv
,
2076 NULL_TREE
, NULL_TREE
);
2078 op1
= uniform_vector_p (arg1
);
2079 if (op1
== NULL_TREE
)
2081 op1
= fold_build1_loc (loc
, VIEW_CONVERT_EXPR
, atype
, arg1
);
2082 op1
= build4_loc (loc
, ARRAY_REF
, eltype
, op1
, cntv
,
2083 NULL_TREE
, NULL_TREE
);
2087 res
= fold_build1_loc (loc
, VIEW_CONVERT_EXPR
, atype
, resv
);
2088 res
= build4_loc (loc
, ARRAY_REF
, eltype
, res
, cntv
,
2089 NULL_TREE
, NULL_TREE
);
2094 tree bitpos
= bitsize_int (tree_to_uhwi (sz
) * i
);
2095 op0
= fold_build3_loc (loc
, BIT_FIELD_REF
, eltype
, arg0
, sz
, bitpos
);
2096 op1
= fold_build3_loc (loc
, BIT_FIELD_REF
, eltype
, arg1
, sz
, bitpos
);
2098 res
= fold_build3_loc (loc
, BIT_FIELD_REF
, eltype
, resv
, sz
,
2104 expand_addsub_overflow (loc
, PLUS_EXPR
, res
, op0
, op1
,
2105 false, false, false, true, &data
);
2108 if (use_loop_p
? integer_zerop (arg0
) : integer_zerop (op0
))
2109 expand_neg_overflow (loc
, res
, op1
, true, &data
);
2111 expand_addsub_overflow (loc
, MINUS_EXPR
, res
, op0
, op1
,
2112 false, false, false, true, &data
);
2115 expand_mul_overflow (loc
, res
, op0
, op1
, false, false, false,
2124 struct separate_ops ops
;
2125 ops
.code
= PLUS_EXPR
;
2126 ops
.type
= TREE_TYPE (cntv
);
2128 ops
.op1
= build_int_cst (TREE_TYPE (cntv
), 1);
2129 ops
.op2
= NULL_TREE
;
2131 rtx ret
= expand_expr_real_2 (&ops
, cntvar
, TYPE_MODE (sizetype
),
2134 emit_move_insn (cntvar
, ret
);
2135 rtx cntrtx
= gen_int_mode (cnt
, TYPE_MODE (sizetype
));
2136 do_compare_rtx_and_jump (cntvar
, cntrtx
, NE
, false,
2137 TYPE_MODE (sizetype
), NULL_RTX
, NULL
, loop_lab
,
2138 profile_probability::very_likely ());
2140 if (lhs
&& resv
== NULL_TREE
)
2142 struct separate_ops ops
;
2144 ops
.type
= TREE_TYPE (arg0
);
2147 ops
.op2
= NULL_TREE
;
2149 rtx ret
= expand_expr_real_2 (&ops
, lhsr
, TYPE_MODE (TREE_TYPE (arg0
)),
2152 emit_move_insn (lhsr
, ret
);
2155 emit_move_insn (lhsr
, resvr
);
2158 /* Expand UBSAN_CHECK_ADD call STMT. */
2161 expand_UBSAN_CHECK_ADD (internal_fn
, gcall
*stmt
)
2163 location_t loc
= gimple_location (stmt
);
2164 tree lhs
= gimple_call_lhs (stmt
);
2165 tree arg0
= gimple_call_arg (stmt
, 0);
2166 tree arg1
= gimple_call_arg (stmt
, 1);
2167 if (VECTOR_TYPE_P (TREE_TYPE (arg0
)))
2168 expand_vector_ubsan_overflow (loc
, PLUS_EXPR
, lhs
, arg0
, arg1
);
2170 expand_addsub_overflow (loc
, PLUS_EXPR
, lhs
, arg0
, arg1
,
2171 false, false, false, true, NULL
);
2174 /* Expand UBSAN_CHECK_SUB call STMT. */
2177 expand_UBSAN_CHECK_SUB (internal_fn
, gcall
*stmt
)
2179 location_t loc
= gimple_location (stmt
);
2180 tree lhs
= gimple_call_lhs (stmt
);
2181 tree arg0
= gimple_call_arg (stmt
, 0);
2182 tree arg1
= gimple_call_arg (stmt
, 1);
2183 if (VECTOR_TYPE_P (TREE_TYPE (arg0
)))
2184 expand_vector_ubsan_overflow (loc
, MINUS_EXPR
, lhs
, arg0
, arg1
);
2185 else if (integer_zerop (arg0
))
2186 expand_neg_overflow (loc
, lhs
, arg1
, true, NULL
);
2188 expand_addsub_overflow (loc
, MINUS_EXPR
, lhs
, arg0
, arg1
,
2189 false, false, false, true, NULL
);
2192 /* Expand UBSAN_CHECK_MUL call STMT. */
2195 expand_UBSAN_CHECK_MUL (internal_fn
, gcall
*stmt
)
2197 location_t loc
= gimple_location (stmt
);
2198 tree lhs
= gimple_call_lhs (stmt
);
2199 tree arg0
= gimple_call_arg (stmt
, 0);
2200 tree arg1
= gimple_call_arg (stmt
, 1);
2201 if (VECTOR_TYPE_P (TREE_TYPE (arg0
)))
2202 expand_vector_ubsan_overflow (loc
, MULT_EXPR
, lhs
, arg0
, arg1
);
2204 expand_mul_overflow (loc
, lhs
, arg0
, arg1
, false, false, false, true,
2208 /* Helper function for {ADD,SUB,MUL}_OVERFLOW call stmt expansion. */
2211 expand_arith_overflow (enum tree_code code
, gimple
*stmt
)
2213 tree lhs
= gimple_call_lhs (stmt
);
2214 if (lhs
== NULL_TREE
)
2216 tree arg0
= gimple_call_arg (stmt
, 0);
2217 tree arg1
= gimple_call_arg (stmt
, 1);
2218 tree type
= TREE_TYPE (TREE_TYPE (lhs
));
2219 int uns0_p
= TYPE_UNSIGNED (TREE_TYPE (arg0
));
2220 int uns1_p
= TYPE_UNSIGNED (TREE_TYPE (arg1
));
2221 int unsr_p
= TYPE_UNSIGNED (type
);
2222 int prec0
= TYPE_PRECISION (TREE_TYPE (arg0
));
2223 int prec1
= TYPE_PRECISION (TREE_TYPE (arg1
));
2224 int precres
= TYPE_PRECISION (type
);
2225 location_t loc
= gimple_location (stmt
);
2226 if (!uns0_p
&& get_range_pos_neg (arg0
) == 1)
2228 if (!uns1_p
&& get_range_pos_neg (arg1
) == 1)
2230 int pr
= get_min_precision (arg0
, uns0_p
? UNSIGNED
: SIGNED
);
2231 prec0
= MIN (prec0
, pr
);
2232 pr
= get_min_precision (arg1
, uns1_p
? UNSIGNED
: SIGNED
);
2233 prec1
= MIN (prec1
, pr
);
2235 /* If uns0_p && uns1_p, precop is minimum needed precision
2236 of unsigned type to hold the exact result, otherwise
2237 precop is minimum needed precision of signed type to
2238 hold the exact result. */
2240 if (code
== MULT_EXPR
)
2241 precop
= prec0
+ prec1
+ (uns0_p
!= uns1_p
);
2244 if (uns0_p
== uns1_p
)
2245 precop
= MAX (prec0
, prec1
) + 1;
2247 precop
= MAX (prec0
+ 1, prec1
) + 1;
2249 precop
= MAX (prec0
, prec1
+ 1) + 1;
2251 int orig_precres
= precres
;
2255 if ((uns0_p
&& uns1_p
)
2256 ? ((precop
+ !unsr_p
) <= precres
2257 /* u1 - u2 -> ur can overflow, no matter what precision
2259 && (code
!= MINUS_EXPR
|| !unsr_p
))
2260 : (!unsr_p
&& precop
<= precres
))
2262 /* The infinity precision result will always fit into result. */
2263 rtx target
= expand_expr (lhs
, NULL_RTX
, VOIDmode
, EXPAND_WRITE
);
2264 write_complex_part (target
, const0_rtx
, true);
2265 scalar_int_mode mode
= SCALAR_INT_TYPE_MODE (type
);
2266 struct separate_ops ops
;
2269 ops
.op0
= fold_convert_loc (loc
, type
, arg0
);
2270 ops
.op1
= fold_convert_loc (loc
, type
, arg1
);
2271 ops
.op2
= NULL_TREE
;
2273 rtx tem
= expand_expr_real_2 (&ops
, NULL_RTX
, mode
, EXPAND_NORMAL
);
2274 expand_arith_overflow_result_store (lhs
, target
, mode
, tem
);
2278 /* For operations with low precision, if target doesn't have them, start
2279 with precres widening right away, otherwise do it only if the most
2280 simple cases can't be used. */
2281 const int min_precision
= targetm
.min_arithmetic_precision ();
2282 if (orig_precres
== precres
&& precres
< min_precision
)
2284 else if ((uns0_p
&& uns1_p
&& unsr_p
&& prec0
<= precres
2285 && prec1
<= precres
)
2286 || ((!uns0_p
|| !uns1_p
) && !unsr_p
2287 && prec0
+ uns0_p
<= precres
2288 && prec1
+ uns1_p
<= precres
))
2290 arg0
= fold_convert_loc (loc
, type
, arg0
);
2291 arg1
= fold_convert_loc (loc
, type
, arg1
);
2295 if (integer_zerop (arg0
) && !unsr_p
)
2297 expand_neg_overflow (loc
, lhs
, arg1
, false, NULL
);
2302 expand_addsub_overflow (loc
, code
, lhs
, arg0
, arg1
, unsr_p
,
2303 unsr_p
, unsr_p
, false, NULL
);
2306 expand_mul_overflow (loc
, lhs
, arg0
, arg1
, unsr_p
,
2307 unsr_p
, unsr_p
, false, NULL
);
2314 /* For sub-word operations, retry with a wider type first. */
2315 if (orig_precres
== precres
&& precop
<= BITS_PER_WORD
)
2317 int p
= MAX (min_precision
, precop
);
2318 scalar_int_mode m
= smallest_int_mode_for_size (p
);
2319 tree optype
= build_nonstandard_integer_type (GET_MODE_PRECISION (m
),
2322 p
= TYPE_PRECISION (optype
);
2326 unsr_p
= TYPE_UNSIGNED (optype
);
2332 if (prec0
<= precres
&& prec1
<= precres
)
2337 types
[0] = build_nonstandard_integer_type (precres
, 0);
2343 types
[1] = build_nonstandard_integer_type (precres
, 1);
2345 arg0
= fold_convert_loc (loc
, types
[uns0_p
], arg0
);
2346 arg1
= fold_convert_loc (loc
, types
[uns1_p
], arg1
);
2347 if (code
!= MULT_EXPR
)
2348 expand_addsub_overflow (loc
, code
, lhs
, arg0
, arg1
, unsr_p
,
2349 uns0_p
, uns1_p
, false, NULL
);
2351 expand_mul_overflow (loc
, lhs
, arg0
, arg1
, unsr_p
,
2352 uns0_p
, uns1_p
, false, NULL
);
2356 /* Retry with a wider type. */
2357 if (orig_precres
== precres
)
2359 int p
= MAX (prec0
, prec1
);
2360 scalar_int_mode m
= smallest_int_mode_for_size (p
);
2361 tree optype
= build_nonstandard_integer_type (GET_MODE_PRECISION (m
),
2364 p
= TYPE_PRECISION (optype
);
2368 unsr_p
= TYPE_UNSIGNED (optype
);
2379 /* Expand ADD_OVERFLOW STMT. */
2382 expand_ADD_OVERFLOW (internal_fn
, gcall
*stmt
)
2384 expand_arith_overflow (PLUS_EXPR
, stmt
);
2387 /* Expand SUB_OVERFLOW STMT. */
2390 expand_SUB_OVERFLOW (internal_fn
, gcall
*stmt
)
2392 expand_arith_overflow (MINUS_EXPR
, stmt
);
2395 /* Expand MUL_OVERFLOW STMT. */
2398 expand_MUL_OVERFLOW (internal_fn
, gcall
*stmt
)
2400 expand_arith_overflow (MULT_EXPR
, stmt
);
2403 /* This should get folded in tree-vectorizer.c. */
2406 expand_LOOP_VECTORIZED (internal_fn
, gcall
*)
2411 /* This should get folded in tree-vectorizer.c. */
2414 expand_LOOP_DIST_ALIAS (internal_fn
, gcall
*)
2419 /* Return a memory reference of type TYPE for argument INDEX of STMT.
2420 Use argument INDEX + 1 to derive the second (TBAA) operand. */
2423 expand_call_mem_ref (tree type
, gcall
*stmt
, int index
)
2425 tree addr
= gimple_call_arg (stmt
, index
);
2426 tree alias_ptr_type
= TREE_TYPE (gimple_call_arg (stmt
, index
+ 1));
2427 unsigned int align
= tree_to_shwi (gimple_call_arg (stmt
, index
+ 1));
2428 if (TYPE_ALIGN (type
) != align
)
2429 type
= build_aligned_type (type
, align
);
2432 if (TREE_CODE (tmp
) == SSA_NAME
)
2434 gimple
*def
= SSA_NAME_DEF_STMT (tmp
);
2435 if (gimple_assign_single_p (def
))
2436 tmp
= gimple_assign_rhs1 (def
);
2439 if (TREE_CODE (tmp
) == ADDR_EXPR
)
2441 tree mem
= TREE_OPERAND (tmp
, 0);
2442 if (TREE_CODE (mem
) == TARGET_MEM_REF
2443 && types_compatible_p (TREE_TYPE (mem
), type
))
2445 tree offset
= TMR_OFFSET (mem
);
2446 if (alias_ptr_type
!= TREE_TYPE (offset
) || !integer_zerop (offset
))
2448 mem
= copy_node (mem
);
2449 TMR_OFFSET (mem
) = wide_int_to_tree (alias_ptr_type
,
2450 wi::to_poly_wide (offset
));
2456 return fold_build2 (MEM_REF
, type
, addr
, build_int_cst (alias_ptr_type
, 0));
2459 /* Expand MASK_LOAD{,_LANES} call STMT using optab OPTAB. */
2462 expand_mask_load_optab_fn (internal_fn
, gcall
*stmt
, convert_optab optab
)
2464 struct expand_operand ops
[3];
2465 tree type
, lhs
, rhs
, maskt
;
2466 rtx mem
, target
, mask
;
2469 maskt
= gimple_call_arg (stmt
, 2);
2470 lhs
= gimple_call_lhs (stmt
);
2471 if (lhs
== NULL_TREE
)
2473 type
= TREE_TYPE (lhs
);
2474 rhs
= expand_call_mem_ref (type
, stmt
, 0);
2476 if (optab
== vec_mask_load_lanes_optab
)
2477 icode
= get_multi_vector_move (type
, optab
);
2479 icode
= convert_optab_handler (optab
, TYPE_MODE (type
),
2480 TYPE_MODE (TREE_TYPE (maskt
)));
2482 mem
= expand_expr (rhs
, NULL_RTX
, VOIDmode
, EXPAND_WRITE
);
2483 gcc_assert (MEM_P (mem
));
2484 mask
= expand_normal (maskt
);
2485 target
= expand_expr (lhs
, NULL_RTX
, VOIDmode
, EXPAND_WRITE
);
2486 create_output_operand (&ops
[0], target
, TYPE_MODE (type
));
2487 create_fixed_operand (&ops
[1], mem
);
2488 create_input_operand (&ops
[2], mask
, TYPE_MODE (TREE_TYPE (maskt
)));
2489 expand_insn (icode
, 3, ops
);
2492 #define expand_mask_load_lanes_optab_fn expand_mask_load_optab_fn
2494 /* Expand MASK_STORE{,_LANES} call STMT using optab OPTAB. */
2497 expand_mask_store_optab_fn (internal_fn
, gcall
*stmt
, convert_optab optab
)
2499 struct expand_operand ops
[3];
2500 tree type
, lhs
, rhs
, maskt
;
2504 maskt
= gimple_call_arg (stmt
, 2);
2505 rhs
= gimple_call_arg (stmt
, 3);
2506 type
= TREE_TYPE (rhs
);
2507 lhs
= expand_call_mem_ref (type
, stmt
, 0);
2509 if (optab
== vec_mask_store_lanes_optab
)
2510 icode
= get_multi_vector_move (type
, optab
);
2512 icode
= convert_optab_handler (optab
, TYPE_MODE (type
),
2513 TYPE_MODE (TREE_TYPE (maskt
)));
2515 mem
= expand_expr (lhs
, NULL_RTX
, VOIDmode
, EXPAND_WRITE
);
2516 gcc_assert (MEM_P (mem
));
2517 mask
= expand_normal (maskt
);
2518 reg
= expand_normal (rhs
);
2519 create_fixed_operand (&ops
[0], mem
);
2520 create_input_operand (&ops
[1], reg
, TYPE_MODE (type
));
2521 create_input_operand (&ops
[2], mask
, TYPE_MODE (TREE_TYPE (maskt
)));
2522 expand_insn (icode
, 3, ops
);
2525 #define expand_mask_store_lanes_optab_fn expand_mask_store_optab_fn
2528 expand_ABNORMAL_DISPATCHER (internal_fn
, gcall
*)
2533 expand_BUILTIN_EXPECT (internal_fn
, gcall
*stmt
)
2535 /* When guessing was done, the hints should be already stripped away. */
2536 gcc_assert (!flag_guess_branch_prob
|| optimize
== 0 || seen_error ());
2539 tree lhs
= gimple_call_lhs (stmt
);
2541 target
= expand_expr (lhs
, NULL_RTX
, VOIDmode
, EXPAND_WRITE
);
2543 target
= const0_rtx
;
2544 rtx val
= expand_expr (gimple_call_arg (stmt
, 0), target
, VOIDmode
, EXPAND_NORMAL
);
2545 if (lhs
&& val
!= target
)
2546 emit_move_insn (target
, val
);
2549 /* IFN_VA_ARG is supposed to be expanded at pass_stdarg. So this dummy function
2550 should never be called. */
2553 expand_VA_ARG (internal_fn
, gcall
*)
2558 /* Expand the IFN_UNIQUE function according to its first argument. */
2561 expand_UNIQUE (internal_fn
, gcall
*stmt
)
2563 rtx pattern
= NULL_RTX
;
2564 enum ifn_unique_kind kind
2565 = (enum ifn_unique_kind
) TREE_INT_CST_LOW (gimple_call_arg (stmt
, 0));
2572 case IFN_UNIQUE_UNSPEC
:
2573 if (targetm
.have_unique ())
2574 pattern
= targetm
.gen_unique ();
2577 case IFN_UNIQUE_OACC_FORK
:
2578 case IFN_UNIQUE_OACC_JOIN
:
2579 if (targetm
.have_oacc_fork () && targetm
.have_oacc_join ())
2581 tree lhs
= gimple_call_lhs (stmt
);
2582 rtx target
= const0_rtx
;
2585 target
= expand_expr (lhs
, NULL_RTX
, VOIDmode
, EXPAND_WRITE
);
2587 rtx data_dep
= expand_normal (gimple_call_arg (stmt
, 1));
2588 rtx axis
= expand_normal (gimple_call_arg (stmt
, 2));
2590 if (kind
== IFN_UNIQUE_OACC_FORK
)
2591 pattern
= targetm
.gen_oacc_fork (target
, data_dep
, axis
);
2593 pattern
= targetm
.gen_oacc_join (target
, data_dep
, axis
);
2601 emit_insn (pattern
);
2604 /* The size of an OpenACC compute dimension. */
2607 expand_GOACC_DIM_SIZE (internal_fn
, gcall
*stmt
)
2609 tree lhs
= gimple_call_lhs (stmt
);
2614 rtx target
= expand_expr (lhs
, NULL_RTX
, VOIDmode
, EXPAND_WRITE
);
2615 if (targetm
.have_oacc_dim_size ())
2617 rtx dim
= expand_expr (gimple_call_arg (stmt
, 0), NULL_RTX
,
2618 VOIDmode
, EXPAND_NORMAL
);
2619 emit_insn (targetm
.gen_oacc_dim_size (target
, dim
));
2622 emit_move_insn (target
, GEN_INT (1));
2625 /* The position of an OpenACC execution engine along one compute axis. */
2628 expand_GOACC_DIM_POS (internal_fn
, gcall
*stmt
)
2630 tree lhs
= gimple_call_lhs (stmt
);
2635 rtx target
= expand_expr (lhs
, NULL_RTX
, VOIDmode
, EXPAND_WRITE
);
2636 if (targetm
.have_oacc_dim_pos ())
2638 rtx dim
= expand_expr (gimple_call_arg (stmt
, 0), NULL_RTX
,
2639 VOIDmode
, EXPAND_NORMAL
);
2640 emit_insn (targetm
.gen_oacc_dim_pos (target
, dim
));
2643 emit_move_insn (target
, const0_rtx
);
2646 /* This is expanded by oacc_device_lower pass. */
2649 expand_GOACC_LOOP (internal_fn
, gcall
*)
2654 /* This is expanded by oacc_device_lower pass. */
2657 expand_GOACC_REDUCTION (internal_fn
, gcall
*)
2662 /* This is expanded by oacc_device_lower pass. */
2665 expand_GOACC_TILE (internal_fn
, gcall
*)
2670 /* Set errno to EDOM. */
2673 expand_SET_EDOM (internal_fn
, gcall
*)
2676 #ifdef GEN_ERRNO_RTX
2677 rtx errno_rtx
= GEN_ERRNO_RTX
;
2679 rtx errno_rtx
= gen_rtx_MEM (word_mode
, gen_rtx_SYMBOL_REF (Pmode
, "errno"));
2681 emit_move_insn (errno_rtx
,
2682 gen_int_mode (TARGET_EDOM
, GET_MODE (errno_rtx
)));
2688 /* Expand atomic bit test and set. */
2691 expand_ATOMIC_BIT_TEST_AND_SET (internal_fn
, gcall
*call
)
2693 expand_ifn_atomic_bit_test_and (call
);
2696 /* Expand atomic bit test and complement. */
2699 expand_ATOMIC_BIT_TEST_AND_COMPLEMENT (internal_fn
, gcall
*call
)
2701 expand_ifn_atomic_bit_test_and (call
);
2704 /* Expand atomic bit test and reset. */
2707 expand_ATOMIC_BIT_TEST_AND_RESET (internal_fn
, gcall
*call
)
2709 expand_ifn_atomic_bit_test_and (call
);
2712 /* Expand atomic bit test and set. */
2715 expand_ATOMIC_COMPARE_EXCHANGE (internal_fn
, gcall
*call
)
2717 expand_ifn_atomic_compare_exchange (call
);
2720 /* Expand LAUNDER to assignment, lhs = arg0. */
2723 expand_LAUNDER (internal_fn
, gcall
*call
)
2725 tree lhs
= gimple_call_lhs (call
);
2730 expand_assignment (lhs
, gimple_call_arg (call
, 0), false);
2733 /* Expand {MASK_,}GATHER_LOAD call CALL using optab OPTAB. */
2736 expand_gather_load_optab_fn (internal_fn
, gcall
*stmt
, direct_optab optab
)
2738 tree lhs
= gimple_call_lhs (stmt
);
2739 tree base
= gimple_call_arg (stmt
, 0);
2740 tree offset
= gimple_call_arg (stmt
, 1);
2741 tree scale
= gimple_call_arg (stmt
, 2);
2743 rtx lhs_rtx
= expand_expr (lhs
, NULL_RTX
, VOIDmode
, EXPAND_WRITE
);
2744 rtx base_rtx
= expand_normal (base
);
2745 rtx offset_rtx
= expand_normal (offset
);
2746 HOST_WIDE_INT scale_int
= tree_to_shwi (scale
);
2749 struct expand_operand ops
[6];
2750 create_output_operand (&ops
[i
++], lhs_rtx
, TYPE_MODE (TREE_TYPE (lhs
)));
2751 create_address_operand (&ops
[i
++], base_rtx
);
2752 create_input_operand (&ops
[i
++], offset_rtx
, TYPE_MODE (TREE_TYPE (offset
)));
2753 create_integer_operand (&ops
[i
++], TYPE_UNSIGNED (TREE_TYPE (offset
)));
2754 create_integer_operand (&ops
[i
++], scale_int
);
2755 if (optab
== mask_gather_load_optab
)
2757 tree mask
= gimple_call_arg (stmt
, 3);
2758 rtx mask_rtx
= expand_normal (mask
);
2759 create_input_operand (&ops
[i
++], mask_rtx
, TYPE_MODE (TREE_TYPE (mask
)));
2761 insn_code icode
= direct_optab_handler (optab
, TYPE_MODE (TREE_TYPE (lhs
)));
2762 expand_insn (icode
, i
, ops
);
2765 /* Expand DIVMOD() using:
2766 a) optab handler for udivmod/sdivmod if it is available.
2767 b) If optab_handler doesn't exist, generate call to
2768 target-specific divmod libfunc. */
2771 expand_DIVMOD (internal_fn
, gcall
*call_stmt
)
2773 tree lhs
= gimple_call_lhs (call_stmt
);
2774 tree arg0
= gimple_call_arg (call_stmt
, 0);
2775 tree arg1
= gimple_call_arg (call_stmt
, 1);
2777 gcc_assert (TREE_CODE (TREE_TYPE (lhs
)) == COMPLEX_TYPE
);
2778 tree type
= TREE_TYPE (TREE_TYPE (lhs
));
2779 machine_mode mode
= TYPE_MODE (type
);
2780 bool unsignedp
= TYPE_UNSIGNED (type
);
2781 optab tab
= (unsignedp
) ? udivmod_optab
: sdivmod_optab
;
2783 rtx op0
= expand_normal (arg0
);
2784 rtx op1
= expand_normal (arg1
);
2785 rtx target
= expand_expr (lhs
, NULL_RTX
, VOIDmode
, EXPAND_WRITE
);
2787 rtx quotient
, remainder
, libfunc
;
2789 /* Check if optab_handler exists for divmod_optab for given mode. */
2790 if (optab_handler (tab
, mode
) != CODE_FOR_nothing
)
2792 quotient
= gen_reg_rtx (mode
);
2793 remainder
= gen_reg_rtx (mode
);
2794 expand_twoval_binop (tab
, op0
, op1
, quotient
, remainder
, unsignedp
);
2797 /* Generate call to divmod libfunc if it exists. */
2798 else if ((libfunc
= optab_libfunc (tab
, mode
)) != NULL_RTX
)
2799 targetm
.expand_divmod_libfunc (libfunc
, mode
, op0
, op1
,
2800 "ient
, &remainder
);
2805 /* Wrap the return value (quotient, remainder) within COMPLEX_EXPR. */
2806 expand_expr (build2 (COMPLEX_EXPR
, TREE_TYPE (lhs
),
2807 make_tree (TREE_TYPE (arg0
), quotient
),
2808 make_tree (TREE_TYPE (arg1
), remainder
)),
2809 target
, VOIDmode
, EXPAND_NORMAL
);
2815 expand_NOP (internal_fn
, gcall
*)
2817 /* Nothing. But it shouldn't really prevail. */
2820 /* Expand a call to FN using the operands in STMT. FN has a single
2821 output operand and NARGS input operands. */
2824 expand_direct_optab_fn (internal_fn fn
, gcall
*stmt
, direct_optab optab
,
2827 expand_operand
*ops
= XALLOCAVEC (expand_operand
, nargs
+ 1);
2829 tree_pair types
= direct_internal_fn_types (fn
, stmt
);
2830 insn_code icode
= direct_optab_handler (optab
, TYPE_MODE (types
.first
));
2832 tree lhs
= gimple_call_lhs (stmt
);
2833 tree lhs_type
= TREE_TYPE (lhs
);
2834 rtx lhs_rtx
= expand_expr (lhs
, NULL_RTX
, VOIDmode
, EXPAND_WRITE
);
2836 /* Do not assign directly to a promoted subreg, since there is no
2837 guarantee that the instruction will leave the upper bits of the
2838 register in the state required by SUBREG_PROMOTED_SIGN. */
2840 if (GET_CODE (dest
) == SUBREG
&& SUBREG_PROMOTED_VAR_P (dest
))
2843 create_output_operand (&ops
[0], dest
, insn_data
[icode
].operand
[0].mode
);
2845 for (unsigned int i
= 0; i
< nargs
; ++i
)
2847 tree rhs
= gimple_call_arg (stmt
, i
);
2848 tree rhs_type
= TREE_TYPE (rhs
);
2849 rtx rhs_rtx
= expand_normal (rhs
);
2850 if (INTEGRAL_TYPE_P (rhs_type
))
2851 create_convert_operand_from (&ops
[i
+ 1], rhs_rtx
,
2852 TYPE_MODE (rhs_type
),
2853 TYPE_UNSIGNED (rhs_type
));
2855 create_input_operand (&ops
[i
+ 1], rhs_rtx
, TYPE_MODE (rhs_type
));
2858 expand_insn (icode
, nargs
+ 1, ops
);
2859 if (!rtx_equal_p (lhs_rtx
, ops
[0].value
))
2861 /* If the return value has an integral type, convert the instruction
2862 result to that type. This is useful for things that return an
2863 int regardless of the size of the input. If the instruction result
2864 is smaller than required, assume that it is signed.
2866 If the return value has a nonintegral type, its mode must match
2867 the instruction result. */
2868 if (GET_CODE (lhs_rtx
) == SUBREG
&& SUBREG_PROMOTED_VAR_P (lhs_rtx
))
2870 /* If this is a scalar in a register that is stored in a wider
2871 mode than the declared mode, compute the result into its
2872 declared mode and then convert to the wider mode. */
2873 gcc_checking_assert (INTEGRAL_TYPE_P (lhs_type
));
2874 rtx tmp
= convert_to_mode (GET_MODE (lhs_rtx
), ops
[0].value
, 0);
2875 convert_move (SUBREG_REG (lhs_rtx
), tmp
,
2876 SUBREG_PROMOTED_SIGN (lhs_rtx
));
2878 else if (GET_MODE (lhs_rtx
) == GET_MODE (ops
[0].value
))
2879 emit_move_insn (lhs_rtx
, ops
[0].value
);
2882 gcc_checking_assert (INTEGRAL_TYPE_P (lhs_type
));
2883 convert_move (lhs_rtx
, ops
[0].value
, 0);
2888 /* Expand WHILE_ULT call STMT using optab OPTAB. */
2891 expand_while_optab_fn (internal_fn
, gcall
*stmt
, convert_optab optab
)
2893 expand_operand ops
[3];
2896 tree lhs
= gimple_call_lhs (stmt
);
2897 tree lhs_type
= TREE_TYPE (lhs
);
2898 rtx lhs_rtx
= expand_expr (lhs
, NULL_RTX
, VOIDmode
, EXPAND_WRITE
);
2899 create_output_operand (&ops
[0], lhs_rtx
, TYPE_MODE (lhs_type
));
2901 for (unsigned int i
= 0; i
< 2; ++i
)
2903 tree rhs
= gimple_call_arg (stmt
, i
);
2904 rhs_type
[i
] = TREE_TYPE (rhs
);
2905 rtx rhs_rtx
= expand_normal (rhs
);
2906 create_input_operand (&ops
[i
+ 1], rhs_rtx
, TYPE_MODE (rhs_type
[i
]));
2909 insn_code icode
= convert_optab_handler (optab
, TYPE_MODE (rhs_type
[0]),
2910 TYPE_MODE (lhs_type
));
2912 expand_insn (icode
, 3, ops
);
2913 if (!rtx_equal_p (lhs_rtx
, ops
[0].value
))
2914 emit_move_insn (lhs_rtx
, ops
[0].value
);
2917 /* Expanders for optabs that can use expand_direct_optab_fn. */
2919 #define expand_unary_optab_fn(FN, STMT, OPTAB) \
2920 expand_direct_optab_fn (FN, STMT, OPTAB, 1)
2922 #define expand_binary_optab_fn(FN, STMT, OPTAB) \
2923 expand_direct_optab_fn (FN, STMT, OPTAB, 2)
2925 #define expand_cond_unary_optab_fn(FN, STMT, OPTAB) \
2926 expand_direct_optab_fn (FN, STMT, OPTAB, 2)
2928 #define expand_cond_binary_optab_fn(FN, STMT, OPTAB) \
2929 expand_direct_optab_fn (FN, STMT, OPTAB, 3)
2931 #define expand_fold_extract_optab_fn(FN, STMT, OPTAB) \
2932 expand_direct_optab_fn (FN, STMT, OPTAB, 3)
2934 #define expand_fold_left_optab_fn(FN, STMT, OPTAB) \
2935 expand_direct_optab_fn (FN, STMT, OPTAB, 2)
2937 /* RETURN_TYPE and ARGS are a return type and argument list that are
2938 in principle compatible with FN (which satisfies direct_internal_fn_p).
2939 Return the types that should be used to determine whether the
2940 target supports FN. */
2943 direct_internal_fn_types (internal_fn fn
, tree return_type
, tree
*args
)
2945 const direct_internal_fn_info
&info
= direct_internal_fn (fn
);
2946 tree type0
= (info
.type0
< 0 ? return_type
: TREE_TYPE (args
[info
.type0
]));
2947 tree type1
= (info
.type1
< 0 ? return_type
: TREE_TYPE (args
[info
.type1
]));
2948 return tree_pair (type0
, type1
);
2951 /* CALL is a call whose return type and arguments are in principle
2952 compatible with FN (which satisfies direct_internal_fn_p). Return the
2953 types that should be used to determine whether the target supports FN. */
2956 direct_internal_fn_types (internal_fn fn
, gcall
*call
)
2958 const direct_internal_fn_info
&info
= direct_internal_fn (fn
);
2959 tree op0
= (info
.type0
< 0
2960 ? gimple_call_lhs (call
)
2961 : gimple_call_arg (call
, info
.type0
));
2962 tree op1
= (info
.type1
< 0
2963 ? gimple_call_lhs (call
)
2964 : gimple_call_arg (call
, info
.type1
));
2965 return tree_pair (TREE_TYPE (op0
), TREE_TYPE (op1
));
2968 /* Return true if OPTAB is supported for TYPES (whose modes should be
2969 the same) when the optimization type is OPT_TYPE. Used for simple
2973 direct_optab_supported_p (direct_optab optab
, tree_pair types
,
2974 optimization_type opt_type
)
2976 machine_mode mode
= TYPE_MODE (types
.first
);
2977 gcc_checking_assert (mode
== TYPE_MODE (types
.second
));
2978 return direct_optab_handler (optab
, mode
, opt_type
) != CODE_FOR_nothing
;
2981 /* Return true if OPTAB is supported for TYPES, where the first type
2982 is the destination and the second type is the source. Used for
2986 convert_optab_supported_p (convert_optab optab
, tree_pair types
,
2987 optimization_type opt_type
)
2989 return (convert_optab_handler (optab
, TYPE_MODE (types
.first
),
2990 TYPE_MODE (types
.second
), opt_type
)
2991 != CODE_FOR_nothing
);
2994 /* Return true if load/store lanes optab OPTAB is supported for
2995 array type TYPES.first when the optimization type is OPT_TYPE. */
2998 multi_vector_optab_supported_p (convert_optab optab
, tree_pair types
,
2999 optimization_type opt_type
)
3001 gcc_assert (TREE_CODE (types
.first
) == ARRAY_TYPE
);
3002 machine_mode imode
= TYPE_MODE (types
.first
);
3003 machine_mode vmode
= TYPE_MODE (TREE_TYPE (types
.first
));
3004 return (convert_optab_handler (optab
, imode
, vmode
, opt_type
)
3005 != CODE_FOR_nothing
);
3008 #define direct_unary_optab_supported_p direct_optab_supported_p
3009 #define direct_binary_optab_supported_p direct_optab_supported_p
3010 #define direct_cond_unary_optab_supported_p direct_optab_supported_p
3011 #define direct_cond_binary_optab_supported_p direct_optab_supported_p
3012 #define direct_mask_load_optab_supported_p direct_optab_supported_p
3013 #define direct_load_lanes_optab_supported_p multi_vector_optab_supported_p
3014 #define direct_mask_load_lanes_optab_supported_p multi_vector_optab_supported_p
3015 #define direct_gather_load_optab_supported_p direct_optab_supported_p
3016 #define direct_mask_store_optab_supported_p direct_optab_supported_p
3017 #define direct_store_lanes_optab_supported_p multi_vector_optab_supported_p
3018 #define direct_mask_store_lanes_optab_supported_p multi_vector_optab_supported_p
3019 #define direct_while_optab_supported_p convert_optab_supported_p
3020 #define direct_fold_extract_optab_supported_p direct_optab_supported_p
3021 #define direct_fold_left_optab_supported_p direct_optab_supported_p
3023 /* Return the optab used by internal function FN. */
3026 direct_internal_fn_optab (internal_fn fn
, tree_pair types
)
3030 #define DEF_INTERNAL_FN(CODE, FLAGS, FNSPEC) \
3031 case IFN_##CODE: break;
3032 #define DEF_INTERNAL_OPTAB_FN(CODE, FLAGS, OPTAB, TYPE) \
3033 case IFN_##CODE: return OPTAB##_optab;
3034 #define DEF_INTERNAL_SIGNED_OPTAB_FN(CODE, FLAGS, SELECTOR, SIGNED_OPTAB, \
3035 UNSIGNED_OPTAB, TYPE) \
3036 case IFN_##CODE: return (TYPE_UNSIGNED (types.SELECTOR) \
3037 ? UNSIGNED_OPTAB ## _optab \
3038 : SIGNED_OPTAB ## _optab);
3039 #include "internal-fn.def"
3047 /* Return the optab used by internal function FN. */
3050 direct_internal_fn_optab (internal_fn fn
)
3054 #define DEF_INTERNAL_FN(CODE, FLAGS, FNSPEC) \
3055 case IFN_##CODE: break;
3056 #define DEF_INTERNAL_OPTAB_FN(CODE, FLAGS, OPTAB, TYPE) \
3057 case IFN_##CODE: return OPTAB##_optab;
3058 #include "internal-fn.def"
3066 /* Return true if FN is supported for the types in TYPES when the
3067 optimization type is OPT_TYPE. The types are those associated with
3068 the "type0" and "type1" fields of FN's direct_internal_fn_info
3072 direct_internal_fn_supported_p (internal_fn fn
, tree_pair types
,
3073 optimization_type opt_type
)
3077 #define DEF_INTERNAL_FN(CODE, FLAGS, FNSPEC) \
3078 case IFN_##CODE: break;
3079 #define DEF_INTERNAL_OPTAB_FN(CODE, FLAGS, OPTAB, TYPE) \
3081 return direct_##TYPE##_optab_supported_p (OPTAB##_optab, types, \
3083 #define DEF_INTERNAL_SIGNED_OPTAB_FN(CODE, FLAGS, SELECTOR, SIGNED_OPTAB, \
3084 UNSIGNED_OPTAB, TYPE) \
3087 optab which_optab = (TYPE_UNSIGNED (types.SELECTOR) \
3088 ? UNSIGNED_OPTAB ## _optab \
3089 : SIGNED_OPTAB ## _optab); \
3090 return direct_##TYPE##_optab_supported_p (which_optab, types, \
3093 #include "internal-fn.def"
3101 /* Return true if FN is supported for type TYPE when the optimization
3102 type is OPT_TYPE. The caller knows that the "type0" and "type1"
3103 fields of FN's direct_internal_fn_info structure are the same. */
3106 direct_internal_fn_supported_p (internal_fn fn
, tree type
,
3107 optimization_type opt_type
)
3109 const direct_internal_fn_info
&info
= direct_internal_fn (fn
);
3110 gcc_checking_assert (info
.type0
== info
.type1
);
3111 return direct_internal_fn_supported_p (fn
, tree_pair (type
, type
), opt_type
);
3114 /* Return true if IFN_SET_EDOM is supported. */
3117 set_edom_supported_p (void)
3126 #define DEF_INTERNAL_OPTAB_FN(CODE, FLAGS, OPTAB, TYPE) \
3128 expand_##CODE (internal_fn fn, gcall *stmt) \
3130 expand_##TYPE##_optab_fn (fn, stmt, OPTAB##_optab); \
3132 #define DEF_INTERNAL_SIGNED_OPTAB_FN(CODE, FLAGS, SELECTOR, SIGNED_OPTAB, \
3133 UNSIGNED_OPTAB, TYPE) \
3135 expand_##CODE (internal_fn fn, gcall *stmt) \
3137 tree_pair types = direct_internal_fn_types (fn, stmt); \
3138 optab which_optab = direct_internal_fn_optab (fn, types); \
3139 expand_##TYPE##_optab_fn (fn, stmt, which_optab); \
3141 #include "internal-fn.def"
3143 /* Routines to expand each internal function, indexed by function number.
3144 Each routine has the prototype:
3146 expand_<NAME> (gcall *stmt)
3148 where STMT is the statement that performs the call. */
3149 static void (*const internal_fn_expanders
[]) (internal_fn
, gcall
*) = {
3150 #define DEF_INTERNAL_FN(CODE, FLAGS, FNSPEC) expand_##CODE,
3151 #include "internal-fn.def"
3155 /* Return a function that performs the conditional form of CODE, i.e.:
3157 LHS = RHS1 ? RHS2 CODE RHS3 : RHS2
3159 (operating elementwise if the operands are vectors). Return IFN_LAST
3160 if no such function exists. */
3163 get_conditional_internal_fn (tree_code code
)
3168 return IFN_COND_ADD
;
3170 return IFN_COND_SUB
;
3172 return IFN_COND_MIN
;
3174 return IFN_COND_MAX
;
3176 return IFN_COND_AND
;
3178 return IFN_COND_IOR
;
3180 return IFN_COND_XOR
;
3186 /* Return true if IFN is some form of load from memory. */
3189 internal_load_fn_p (internal_fn fn
)
3194 case IFN_LOAD_LANES
:
3195 case IFN_MASK_LOAD_LANES
:
3196 case IFN_GATHER_LOAD
:
3197 case IFN_MASK_GATHER_LOAD
:
3205 /* Return true if IFN is some form of gather load or scatter store. */
3208 internal_gather_scatter_fn_p (internal_fn fn
)
3212 case IFN_GATHER_LOAD
:
3213 case IFN_MASK_GATHER_LOAD
:
3221 /* If FN takes a vector mask argument, return the index of that argument,
3222 otherwise return -1. */
3225 internal_fn_mask_index (internal_fn fn
)
3230 case IFN_MASK_LOAD_LANES
:
3231 case IFN_MASK_STORE
:
3232 case IFN_MASK_STORE_LANES
:
3235 case IFN_MASK_GATHER_LOAD
:
3243 /* Return true if the target supports gather load or scatter store function
3244 IFN. For loads, VECTOR_TYPE is the vector type of the load result,
3245 while for stores it is the vector type of the stored data argument.
3246 MEMORY_ELEMENT_TYPE is the type of the memory elements being loaded
3247 or stored. OFFSET_SIGN is the sign of the offset argument, which is
3248 only relevant when the offset is narrower than an address. SCALE is
3249 the amount by which the offset should be multiplied *after* it has
3250 been extended to address width. */
3253 internal_gather_scatter_fn_supported_p (internal_fn ifn
, tree vector_type
,
3254 tree memory_element_type
,
3255 signop offset_sign
, int scale
)
3257 if (!tree_int_cst_equal (TYPE_SIZE (TREE_TYPE (vector_type
)),
3258 TYPE_SIZE (memory_element_type
)))
3260 optab optab
= direct_internal_fn_optab (ifn
);
3261 insn_code icode
= direct_optab_handler (optab
, TYPE_MODE (vector_type
));
3262 return (icode
!= CODE_FOR_nothing
3263 && insn_operand_matches (icode
, 3, GEN_INT (offset_sign
== UNSIGNED
))
3264 && insn_operand_matches (icode
, 4, GEN_INT (scale
)));
3267 /* Expand STMT as though it were a call to internal function FN. */
3270 expand_internal_call (internal_fn fn
, gcall
*stmt
)
3272 internal_fn_expanders
[fn
] (fn
, stmt
);
3275 /* Expand STMT, which is a call to internal function FN. */
3278 expand_internal_call (gcall
*stmt
)
3280 expand_internal_call (gimple_call_internal_fn (stmt
), stmt
);
3284 expand_PHI (internal_fn
, gcall
*)