2 Copyright (C) 2011-2019 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 /* Return the internal function called NAME, or IFN_LAST if there's
71 lookup_internal_fn (const char *name
)
73 typedef hash_map
<nofree_string_hash
, internal_fn
> name_to_fn_map_type
;
74 static name_to_fn_map_type
*name_to_fn_map
;
78 name_to_fn_map
= new name_to_fn_map_type (IFN_LAST
);
79 for (unsigned int i
= 0; i
< IFN_LAST
; ++i
)
80 name_to_fn_map
->put (internal_fn_name (internal_fn (i
)),
83 internal_fn
*entry
= name_to_fn_map
->get (name
);
84 return entry
? *entry
: IFN_LAST
;
87 /* Fnspec of each internal function, indexed by function number. */
88 const_tree internal_fn_fnspec_array
[IFN_LAST
+ 1];
93 #define DEF_INTERNAL_FN(CODE, FLAGS, FNSPEC) \
94 if (FNSPEC) internal_fn_fnspec_array[IFN_##CODE] = \
95 build_string ((int) sizeof (FNSPEC), FNSPEC ? FNSPEC : "");
96 #include "internal-fn.def"
97 internal_fn_fnspec_array
[IFN_LAST
] = 0;
100 /* Create static initializers for the information returned by
101 direct_internal_fn. */
102 #define not_direct { -2, -2, false }
103 #define mask_load_direct { -1, 2, false }
104 #define load_lanes_direct { -1, -1, false }
105 #define mask_load_lanes_direct { -1, -1, false }
106 #define gather_load_direct { -1, -1, false }
107 #define mask_store_direct { 3, 2, false }
108 #define store_lanes_direct { 0, 0, false }
109 #define mask_store_lanes_direct { 0, 0, false }
110 #define scatter_store_direct { 3, 3, false }
111 #define unary_direct { 0, 0, true }
112 #define binary_direct { 0, 0, true }
113 #define ternary_direct { 0, 0, true }
114 #define cond_unary_direct { 1, 1, true }
115 #define cond_binary_direct { 1, 1, true }
116 #define cond_ternary_direct { 1, 1, true }
117 #define while_direct { 0, 2, false }
118 #define fold_extract_direct { 2, 2, false }
119 #define fold_left_direct { 1, 1, false }
121 const direct_internal_fn_info direct_internal_fn_array
[IFN_LAST
+ 1] = {
122 #define DEF_INTERNAL_FN(CODE, FLAGS, FNSPEC) not_direct,
123 #define DEF_INTERNAL_OPTAB_FN(CODE, FLAGS, OPTAB, TYPE) TYPE##_direct,
124 #define DEF_INTERNAL_SIGNED_OPTAB_FN(CODE, FLAGS, SELECTOR, SIGNED_OPTAB, \
125 UNSIGNED_OPTAB, TYPE) TYPE##_direct,
126 #include "internal-fn.def"
130 /* ARRAY_TYPE is an array of vector modes. Return the associated insn
131 for load-lanes-style optab OPTAB, or CODE_FOR_nothing if none. */
133 static enum insn_code
134 get_multi_vector_move (tree array_type
, convert_optab optab
)
139 gcc_assert (TREE_CODE (array_type
) == ARRAY_TYPE
);
140 imode
= TYPE_MODE (array_type
);
141 vmode
= TYPE_MODE (TREE_TYPE (array_type
));
143 return convert_optab_handler (optab
, imode
, vmode
);
146 /* Expand LOAD_LANES call STMT using optab OPTAB. */
149 expand_load_lanes_optab_fn (internal_fn
, gcall
*stmt
, convert_optab optab
)
151 struct expand_operand ops
[2];
155 lhs
= gimple_call_lhs (stmt
);
156 rhs
= gimple_call_arg (stmt
, 0);
157 type
= TREE_TYPE (lhs
);
159 target
= expand_expr (lhs
, NULL_RTX
, VOIDmode
, EXPAND_WRITE
);
160 mem
= expand_normal (rhs
);
162 gcc_assert (MEM_P (mem
));
163 PUT_MODE (mem
, TYPE_MODE (type
));
165 create_output_operand (&ops
[0], target
, TYPE_MODE (type
));
166 create_fixed_operand (&ops
[1], mem
);
167 expand_insn (get_multi_vector_move (type
, optab
), 2, ops
);
170 /* Expand STORE_LANES call STMT using optab OPTAB. */
173 expand_store_lanes_optab_fn (internal_fn
, gcall
*stmt
, convert_optab optab
)
175 struct expand_operand ops
[2];
179 lhs
= gimple_call_lhs (stmt
);
180 rhs
= gimple_call_arg (stmt
, 0);
181 type
= TREE_TYPE (rhs
);
183 target
= expand_expr (lhs
, NULL_RTX
, VOIDmode
, EXPAND_WRITE
);
184 reg
= expand_normal (rhs
);
186 gcc_assert (MEM_P (target
));
187 PUT_MODE (target
, TYPE_MODE (type
));
189 create_fixed_operand (&ops
[0], target
);
190 create_input_operand (&ops
[1], reg
, TYPE_MODE (type
));
191 expand_insn (get_multi_vector_move (type
, optab
), 2, ops
);
195 expand_ANNOTATE (internal_fn
, gcall
*)
200 /* This should get expanded in omp_device_lower pass. */
203 expand_GOMP_USE_SIMT (internal_fn
, gcall
*)
208 /* This should get expanded in omp_device_lower pass. */
211 expand_GOMP_SIMT_ENTER (internal_fn
, gcall
*)
216 /* Allocate per-lane storage and begin non-uniform execution region. */
219 expand_GOMP_SIMT_ENTER_ALLOC (internal_fn
, gcall
*stmt
)
222 tree lhs
= gimple_call_lhs (stmt
);
224 target
= expand_expr (lhs
, NULL_RTX
, VOIDmode
, EXPAND_WRITE
);
226 target
= gen_reg_rtx (Pmode
);
227 rtx size
= expand_normal (gimple_call_arg (stmt
, 0));
228 rtx align
= expand_normal (gimple_call_arg (stmt
, 1));
229 struct expand_operand ops
[3];
230 create_output_operand (&ops
[0], target
, Pmode
);
231 create_input_operand (&ops
[1], size
, Pmode
);
232 create_input_operand (&ops
[2], align
, Pmode
);
233 gcc_assert (targetm
.have_omp_simt_enter ());
234 expand_insn (targetm
.code_for_omp_simt_enter
, 3, ops
);
237 /* Deallocate per-lane storage and leave non-uniform execution region. */
240 expand_GOMP_SIMT_EXIT (internal_fn
, gcall
*stmt
)
242 gcc_checking_assert (!gimple_call_lhs (stmt
));
243 rtx arg
= expand_normal (gimple_call_arg (stmt
, 0));
244 struct expand_operand ops
[1];
245 create_input_operand (&ops
[0], arg
, Pmode
);
246 gcc_assert (targetm
.have_omp_simt_exit ());
247 expand_insn (targetm
.code_for_omp_simt_exit
, 1, ops
);
250 /* Lane index on SIMT targets: thread index in the warp on NVPTX. On targets
251 without SIMT execution this should be expanded in omp_device_lower pass. */
254 expand_GOMP_SIMT_LANE (internal_fn
, gcall
*stmt
)
256 tree lhs
= gimple_call_lhs (stmt
);
260 rtx target
= expand_expr (lhs
, NULL_RTX
, VOIDmode
, EXPAND_WRITE
);
261 gcc_assert (targetm
.have_omp_simt_lane ());
262 emit_insn (targetm
.gen_omp_simt_lane (target
));
265 /* This should get expanded in omp_device_lower pass. */
268 expand_GOMP_SIMT_VF (internal_fn
, gcall
*)
273 /* Lane index of the first SIMT lane that supplies a non-zero argument.
274 This is a SIMT counterpart to GOMP_SIMD_LAST_LANE, used to represent the
275 lane that executed the last iteration for handling OpenMP lastprivate. */
278 expand_GOMP_SIMT_LAST_LANE (internal_fn
, gcall
*stmt
)
280 tree lhs
= gimple_call_lhs (stmt
);
284 rtx target
= expand_expr (lhs
, NULL_RTX
, VOIDmode
, EXPAND_WRITE
);
285 rtx cond
= expand_normal (gimple_call_arg (stmt
, 0));
286 machine_mode mode
= TYPE_MODE (TREE_TYPE (lhs
));
287 struct expand_operand ops
[2];
288 create_output_operand (&ops
[0], target
, mode
);
289 create_input_operand (&ops
[1], cond
, mode
);
290 gcc_assert (targetm
.have_omp_simt_last_lane ());
291 expand_insn (targetm
.code_for_omp_simt_last_lane
, 2, ops
);
294 /* Non-transparent predicate used in SIMT lowering of OpenMP "ordered". */
297 expand_GOMP_SIMT_ORDERED_PRED (internal_fn
, gcall
*stmt
)
299 tree lhs
= gimple_call_lhs (stmt
);
303 rtx target
= expand_expr (lhs
, NULL_RTX
, VOIDmode
, EXPAND_WRITE
);
304 rtx ctr
= expand_normal (gimple_call_arg (stmt
, 0));
305 machine_mode mode
= TYPE_MODE (TREE_TYPE (lhs
));
306 struct expand_operand ops
[2];
307 create_output_operand (&ops
[0], target
, mode
);
308 create_input_operand (&ops
[1], ctr
, mode
);
309 gcc_assert (targetm
.have_omp_simt_ordered ());
310 expand_insn (targetm
.code_for_omp_simt_ordered
, 2, ops
);
313 /* "Or" boolean reduction across SIMT lanes: return non-zero in all lanes if
314 any lane supplies a non-zero argument. */
317 expand_GOMP_SIMT_VOTE_ANY (internal_fn
, gcall
*stmt
)
319 tree lhs
= gimple_call_lhs (stmt
);
323 rtx target
= expand_expr (lhs
, NULL_RTX
, VOIDmode
, EXPAND_WRITE
);
324 rtx cond
= expand_normal (gimple_call_arg (stmt
, 0));
325 machine_mode mode
= TYPE_MODE (TREE_TYPE (lhs
));
326 struct expand_operand ops
[2];
327 create_output_operand (&ops
[0], target
, mode
);
328 create_input_operand (&ops
[1], cond
, mode
);
329 gcc_assert (targetm
.have_omp_simt_vote_any ());
330 expand_insn (targetm
.code_for_omp_simt_vote_any
, 2, ops
);
333 /* Exchange between SIMT lanes with a "butterfly" pattern: source lane index
334 is destination lane index XOR given offset. */
337 expand_GOMP_SIMT_XCHG_BFLY (internal_fn
, gcall
*stmt
)
339 tree lhs
= gimple_call_lhs (stmt
);
343 rtx target
= expand_expr (lhs
, NULL_RTX
, VOIDmode
, EXPAND_WRITE
);
344 rtx src
= expand_normal (gimple_call_arg (stmt
, 0));
345 rtx idx
= expand_normal (gimple_call_arg (stmt
, 1));
346 machine_mode mode
= TYPE_MODE (TREE_TYPE (lhs
));
347 struct expand_operand ops
[3];
348 create_output_operand (&ops
[0], target
, mode
);
349 create_input_operand (&ops
[1], src
, mode
);
350 create_input_operand (&ops
[2], idx
, SImode
);
351 gcc_assert (targetm
.have_omp_simt_xchg_bfly ());
352 expand_insn (targetm
.code_for_omp_simt_xchg_bfly
, 3, ops
);
355 /* Exchange between SIMT lanes according to given source lane index. */
358 expand_GOMP_SIMT_XCHG_IDX (internal_fn
, gcall
*stmt
)
360 tree lhs
= gimple_call_lhs (stmt
);
364 rtx target
= expand_expr (lhs
, NULL_RTX
, VOIDmode
, EXPAND_WRITE
);
365 rtx src
= expand_normal (gimple_call_arg (stmt
, 0));
366 rtx idx
= expand_normal (gimple_call_arg (stmt
, 1));
367 machine_mode mode
= TYPE_MODE (TREE_TYPE (lhs
));
368 struct expand_operand ops
[3];
369 create_output_operand (&ops
[0], target
, mode
);
370 create_input_operand (&ops
[1], src
, mode
);
371 create_input_operand (&ops
[2], idx
, SImode
);
372 gcc_assert (targetm
.have_omp_simt_xchg_idx ());
373 expand_insn (targetm
.code_for_omp_simt_xchg_idx
, 3, ops
);
376 /* This should get expanded in adjust_simduid_builtins. */
379 expand_GOMP_SIMD_LANE (internal_fn
, gcall
*)
384 /* This should get expanded in adjust_simduid_builtins. */
387 expand_GOMP_SIMD_VF (internal_fn
, gcall
*)
392 /* This should get expanded in adjust_simduid_builtins. */
395 expand_GOMP_SIMD_LAST_LANE (internal_fn
, gcall
*)
400 /* This should get expanded in adjust_simduid_builtins. */
403 expand_GOMP_SIMD_ORDERED_START (internal_fn
, gcall
*)
408 /* This should get expanded in adjust_simduid_builtins. */
411 expand_GOMP_SIMD_ORDERED_END (internal_fn
, gcall
*)
416 /* This should get expanded in the sanopt pass. */
419 expand_UBSAN_NULL (internal_fn
, gcall
*)
424 /* This should get expanded in the sanopt pass. */
427 expand_UBSAN_BOUNDS (internal_fn
, gcall
*)
432 /* This should get expanded in the sanopt pass. */
435 expand_UBSAN_VPTR (internal_fn
, gcall
*)
440 /* This should get expanded in the sanopt pass. */
443 expand_UBSAN_PTR (internal_fn
, gcall
*)
448 /* This should get expanded in the sanopt pass. */
451 expand_UBSAN_OBJECT_SIZE (internal_fn
, gcall
*)
456 /* This should get expanded in the sanopt pass. */
459 expand_ASAN_CHECK (internal_fn
, gcall
*)
464 /* This should get expanded in the sanopt pass. */
467 expand_ASAN_MARK (internal_fn
, gcall
*)
472 /* This should get expanded in the sanopt pass. */
475 expand_ASAN_POISON (internal_fn
, gcall
*)
480 /* This should get expanded in the sanopt pass. */
483 expand_ASAN_POISON_USE (internal_fn
, gcall
*)
488 /* This should get expanded in the tsan pass. */
491 expand_TSAN_FUNC_EXIT (internal_fn
, gcall
*)
496 /* This should get expanded in the lower pass. */
499 expand_FALLTHROUGH (internal_fn
, gcall
*call
)
501 error_at (gimple_location (call
),
502 "invalid use of attribute %<fallthrough%>");
505 /* Return minimum precision needed to represent all values
506 of ARG in SIGNed integral type. */
509 get_min_precision (tree arg
, signop sign
)
511 int prec
= TYPE_PRECISION (TREE_TYPE (arg
));
513 signop orig_sign
= sign
;
514 if (TREE_CODE (arg
) == INTEGER_CST
)
517 if (TYPE_SIGN (TREE_TYPE (arg
)) != sign
)
519 widest_int w
= wi::to_widest (arg
);
520 w
= wi::ext (w
, prec
, sign
);
521 p
= wi::min_precision (w
, sign
);
524 p
= wi::min_precision (wi::to_wide (arg
), sign
);
525 return MIN (p
, prec
);
527 while (CONVERT_EXPR_P (arg
)
528 && INTEGRAL_TYPE_P (TREE_TYPE (TREE_OPERAND (arg
, 0)))
529 && TYPE_PRECISION (TREE_TYPE (TREE_OPERAND (arg
, 0))) <= prec
)
531 arg
= TREE_OPERAND (arg
, 0);
532 if (TYPE_PRECISION (TREE_TYPE (arg
)) < prec
)
534 if (TYPE_UNSIGNED (TREE_TYPE (arg
)))
536 else if (sign
== UNSIGNED
&& get_range_pos_neg (arg
) != 1)
537 return prec
+ (orig_sign
!= sign
);
538 prec
= TYPE_PRECISION (TREE_TYPE (arg
));
541 return prec
+ (orig_sign
!= sign
);
543 if (TREE_CODE (arg
) != SSA_NAME
)
544 return prec
+ (orig_sign
!= sign
);
545 wide_int arg_min
, arg_max
;
546 while (get_range_info (arg
, &arg_min
, &arg_max
) != VR_RANGE
)
548 gimple
*g
= SSA_NAME_DEF_STMT (arg
);
549 if (is_gimple_assign (g
)
550 && CONVERT_EXPR_CODE_P (gimple_assign_rhs_code (g
)))
552 tree t
= gimple_assign_rhs1 (g
);
553 if (INTEGRAL_TYPE_P (TREE_TYPE (t
))
554 && TYPE_PRECISION (TREE_TYPE (t
)) <= prec
)
557 if (TYPE_PRECISION (TREE_TYPE (arg
)) < prec
)
559 if (TYPE_UNSIGNED (TREE_TYPE (arg
)))
561 else if (sign
== UNSIGNED
&& get_range_pos_neg (arg
) != 1)
562 return prec
+ (orig_sign
!= sign
);
563 prec
= TYPE_PRECISION (TREE_TYPE (arg
));
566 return prec
+ (orig_sign
!= sign
);
570 return prec
+ (orig_sign
!= sign
);
572 if (sign
== TYPE_SIGN (TREE_TYPE (arg
)))
574 int p1
= wi::min_precision (arg_min
, sign
);
575 int p2
= wi::min_precision (arg_max
, sign
);
577 prec
= MIN (prec
, p1
);
579 else if (sign
== UNSIGNED
&& !wi::neg_p (arg_min
, SIGNED
))
581 int p
= wi::min_precision (arg_max
, UNSIGNED
);
582 prec
= MIN (prec
, p
);
584 return prec
+ (orig_sign
!= sign
);
587 /* Helper for expand_*_overflow. Set the __imag__ part to true
588 (1 except for signed:1 type, in which case store -1). */
591 expand_arith_set_overflow (tree lhs
, rtx target
)
593 if (TYPE_PRECISION (TREE_TYPE (TREE_TYPE (lhs
))) == 1
594 && !TYPE_UNSIGNED (TREE_TYPE (TREE_TYPE (lhs
))))
595 write_complex_part (target
, constm1_rtx
, true);
597 write_complex_part (target
, const1_rtx
, true);
600 /* Helper for expand_*_overflow. Store RES into the __real__ part
601 of TARGET. If RES has larger MODE than __real__ part of TARGET,
602 set the __imag__ part to 1 if RES doesn't fit into it. Similarly
603 if LHS has smaller precision than its mode. */
606 expand_arith_overflow_result_store (tree lhs
, rtx target
,
607 scalar_int_mode mode
, rtx res
)
609 scalar_int_mode tgtmode
610 = as_a
<scalar_int_mode
> (GET_MODE_INNER (GET_MODE (target
)));
614 rtx_code_label
*done_label
= gen_label_rtx ();
615 int uns
= TYPE_UNSIGNED (TREE_TYPE (TREE_TYPE (lhs
)));
616 lres
= convert_modes (tgtmode
, mode
, res
, uns
);
617 gcc_assert (GET_MODE_PRECISION (tgtmode
) < GET_MODE_PRECISION (mode
));
618 do_compare_rtx_and_jump (res
, convert_modes (mode
, tgtmode
, lres
, uns
),
619 EQ
, true, mode
, NULL_RTX
, NULL
, done_label
,
620 profile_probability::very_likely ());
621 expand_arith_set_overflow (lhs
, target
);
622 emit_label (done_label
);
624 int prec
= TYPE_PRECISION (TREE_TYPE (TREE_TYPE (lhs
)));
625 int tgtprec
= GET_MODE_PRECISION (tgtmode
);
628 rtx_code_label
*done_label
= gen_label_rtx ();
629 int uns
= TYPE_UNSIGNED (TREE_TYPE (TREE_TYPE (lhs
)));
634 = immed_wide_int_const (wi::shifted_mask (0, prec
, false, tgtprec
),
636 lres
= expand_simple_binop (tgtmode
, AND
, res
, mask
, NULL_RTX
,
637 true, OPTAB_LIB_WIDEN
);
641 lres
= expand_shift (LSHIFT_EXPR
, tgtmode
, res
, tgtprec
- prec
,
643 lres
= expand_shift (RSHIFT_EXPR
, tgtmode
, lres
, tgtprec
- prec
,
646 do_compare_rtx_and_jump (res
, lres
,
647 EQ
, true, tgtmode
, NULL_RTX
, NULL
, done_label
,
648 profile_probability::very_likely ());
649 expand_arith_set_overflow (lhs
, target
);
650 emit_label (done_label
);
652 write_complex_part (target
, lres
, false);
655 /* Helper for expand_*_overflow. Store RES into TARGET. */
658 expand_ubsan_result_store (rtx target
, rtx res
)
660 if (GET_CODE (target
) == SUBREG
&& SUBREG_PROMOTED_VAR_P (target
))
661 /* If this is a scalar in a register that is stored in a wider mode
662 than the declared mode, compute the result into its declared mode
663 and then convert to the wider mode. Our value is the computed
665 convert_move (SUBREG_REG (target
), res
, SUBREG_PROMOTED_SIGN (target
));
667 emit_move_insn (target
, res
);
670 /* Add sub/add overflow checking to the statement STMT.
671 CODE says whether the operation is +, or -. */
674 expand_addsub_overflow (location_t loc
, tree_code code
, tree lhs
,
675 tree arg0
, tree arg1
, bool unsr_p
, bool uns0_p
,
676 bool uns1_p
, bool is_ubsan
, tree
*datap
)
678 rtx res
, target
= NULL_RTX
;
680 rtx_code_label
*done_label
= gen_label_rtx ();
681 rtx_code_label
*do_error
= gen_label_rtx ();
682 do_pending_stack_adjust ();
683 rtx op0
= expand_normal (arg0
);
684 rtx op1
= expand_normal (arg1
);
685 scalar_int_mode mode
= SCALAR_INT_TYPE_MODE (TREE_TYPE (arg0
));
686 int prec
= GET_MODE_PRECISION (mode
);
687 rtx sgn
= immed_wide_int_const (wi::min_value (prec
, SIGNED
), mode
);
691 gcc_assert (!unsr_p
&& !uns0_p
&& !uns1_p
);
695 target
= expand_expr (lhs
, NULL_RTX
, VOIDmode
, EXPAND_WRITE
);
697 write_complex_part (target
, const0_rtx
, true);
700 /* We assume both operands and result have the same precision
701 here (GET_MODE_BITSIZE (mode)), S stands for signed type
702 with that precision, U for unsigned type with that precision,
703 sgn for unsigned most significant bit in that precision.
704 s1 is signed first operand, u1 is unsigned first operand,
705 s2 is signed second operand, u2 is unsigned second operand,
706 sr is signed result, ur is unsigned result and the following
707 rules say how to compute result (which is always result of
708 the operands as if both were unsigned, cast to the right
709 signedness) and how to compute whether operation overflowed.
712 res = (S) ((U) s1 + (U) s2)
713 ovf = s2 < 0 ? res > s1 : res < s1 (or jump on overflow)
715 res = (S) ((U) s1 - (U) s2)
716 ovf = s2 < 0 ? res < s1 : res > s2 (or jump on overflow)
719 ovf = res < u1 (or jump on carry, but RTL opts will handle it)
722 ovf = res > u1 (or jump on carry, but RTL opts will handle it)
724 res = (S) ((U) s1 + u2)
725 ovf = ((U) res ^ sgn) < u2
730 ovf = t1 < 0 ? t2 > s1 : t2 < s1 (or jump on overflow)
732 res = (S) ((U) s1 - u2)
733 ovf = u2 > ((U) s1 ^ sgn)
736 ovf = s1 < 0 || u2 > (U) s1
739 ovf = u1 >= ((U) s2 ^ sgn)
744 ovf = s2 < 0 ? (S) t2 < (S) t1 : (S) t2 > (S) t1 (or jump on overflow)
746 res = (U) s1 + (U) s2
747 ovf = s2 < 0 ? (s1 | (S) res) < 0) : (s1 & (S) res) < 0)
750 ovf = (U) res < u2 || res < 0
753 ovf = u1 >= u2 ? res < 0 : res >= 0
755 res = (U) s1 - (U) s2
756 ovf = s2 >= 0 ? ((s1 | (S) res) < 0) : ((s1 & (S) res) < 0) */
758 if (code
== PLUS_EXPR
&& uns0_p
&& !uns1_p
)
760 /* PLUS_EXPR is commutative, if operand signedness differs,
761 canonicalize to the first operand being signed and second
762 unsigned to simplify following code. */
763 std::swap (op0
, op1
);
764 std::swap (arg0
, arg1
);
770 if (uns0_p
&& uns1_p
&& unsr_p
)
772 insn_code icode
= optab_handler (code
== PLUS_EXPR
? uaddv4_optab
773 : usubv4_optab
, mode
);
774 if (icode
!= CODE_FOR_nothing
)
776 struct expand_operand ops
[4];
777 rtx_insn
*last
= get_last_insn ();
779 res
= gen_reg_rtx (mode
);
780 create_output_operand (&ops
[0], res
, mode
);
781 create_input_operand (&ops
[1], op0
, mode
);
782 create_input_operand (&ops
[2], op1
, mode
);
783 create_fixed_operand (&ops
[3], do_error
);
784 if (maybe_expand_insn (icode
, 4, ops
))
786 last
= get_last_insn ();
787 if (profile_status_for_fn (cfun
) != PROFILE_ABSENT
789 && any_condjump_p (last
)
790 && !find_reg_note (last
, REG_BR_PROB
, 0))
791 add_reg_br_prob_note (last
,
792 profile_probability::very_unlikely ());
793 emit_jump (done_label
);
797 delete_insns_since (last
);
800 /* Compute the operation. On RTL level, the addition is always
802 res
= expand_binop (mode
, code
== PLUS_EXPR
? add_optab
: sub_optab
,
803 op0
, op1
, NULL_RTX
, false, OPTAB_LIB_WIDEN
);
805 /* For PLUS_EXPR, the operation is commutative, so we can pick
806 operand to compare against. For prec <= BITS_PER_WORD, I think
807 preferring REG operand is better over CONST_INT, because
808 the CONST_INT might enlarge the instruction or CSE would need
809 to figure out we'd already loaded it into a register before.
810 For prec > BITS_PER_WORD, I think CONST_INT might be more beneficial,
811 as then the multi-word comparison can be perhaps simplified. */
812 if (code
== PLUS_EXPR
813 && (prec
<= BITS_PER_WORD
814 ? (CONST_SCALAR_INT_P (op0
) && REG_P (op1
))
815 : CONST_SCALAR_INT_P (op1
)))
817 do_compare_rtx_and_jump (res
, tem
, code
== PLUS_EXPR
? GEU
: LEU
,
818 true, mode
, NULL_RTX
, NULL
, done_label
,
819 profile_probability::very_likely ());
824 if (!uns0_p
&& uns1_p
&& !unsr_p
)
826 /* Compute the operation. On RTL level, the addition is always
828 res
= expand_binop (mode
, code
== PLUS_EXPR
? add_optab
: sub_optab
,
829 op0
, op1
, NULL_RTX
, false, OPTAB_LIB_WIDEN
);
830 rtx tem
= expand_binop (mode
, add_optab
,
831 code
== PLUS_EXPR
? res
: op0
, sgn
,
832 NULL_RTX
, false, OPTAB_LIB_WIDEN
);
833 do_compare_rtx_and_jump (tem
, op1
, GEU
, true, mode
, NULL_RTX
, NULL
,
834 done_label
, profile_probability::very_likely ());
839 if (code
== PLUS_EXPR
&& !uns0_p
&& uns1_p
&& unsr_p
)
841 op1
= expand_binop (mode
, add_optab
, op1
, sgn
, NULL_RTX
, false,
843 /* As we've changed op1, we have to avoid using the value range
844 for the original argument. */
845 arg1
= error_mark_node
;
851 if (code
== MINUS_EXPR
&& uns0_p
&& !uns1_p
&& unsr_p
)
853 op0
= expand_binop (mode
, add_optab
, op0
, sgn
, NULL_RTX
, false,
855 /* As we've changed op0, we have to avoid using the value range
856 for the original argument. */
857 arg0
= error_mark_node
;
863 if (code
== MINUS_EXPR
&& !uns0_p
&& uns1_p
&& unsr_p
)
865 /* Compute the operation. On RTL level, the addition is always
867 res
= expand_binop (mode
, sub_optab
, op0
, op1
, NULL_RTX
, false,
869 int pos_neg
= get_range_pos_neg (arg0
);
871 /* If ARG0 is known to be always negative, this is always overflow. */
872 emit_jump (do_error
);
873 else if (pos_neg
== 3)
874 /* If ARG0 is not known to be always positive, check at runtime. */
875 do_compare_rtx_and_jump (op0
, const0_rtx
, LT
, false, mode
, NULL_RTX
,
876 NULL
, do_error
, profile_probability::very_unlikely ());
877 do_compare_rtx_and_jump (op1
, op0
, LEU
, true, mode
, NULL_RTX
, NULL
,
878 done_label
, profile_probability::very_likely ());
883 if (code
== MINUS_EXPR
&& uns0_p
&& !uns1_p
&& !unsr_p
)
885 /* Compute the operation. On RTL level, the addition is always
887 res
= expand_binop (mode
, sub_optab
, op0
, op1
, NULL_RTX
, false,
889 rtx tem
= expand_binop (mode
, add_optab
, op1
, sgn
, NULL_RTX
, false,
891 do_compare_rtx_and_jump (op0
, tem
, LTU
, true, mode
, NULL_RTX
, NULL
,
892 done_label
, profile_probability::very_likely ());
897 if (code
== PLUS_EXPR
&& uns0_p
&& uns1_p
&& !unsr_p
)
899 /* Compute the operation. On RTL level, the addition is always
901 res
= expand_binop (mode
, add_optab
, op0
, op1
, NULL_RTX
, false,
903 do_compare_rtx_and_jump (res
, const0_rtx
, LT
, false, mode
, NULL_RTX
,
904 NULL
, do_error
, profile_probability::very_unlikely ());
906 /* The operation is commutative, so we can pick operand to compare
907 against. For prec <= BITS_PER_WORD, I think preferring REG operand
908 is better over CONST_INT, because the CONST_INT might enlarge the
909 instruction or CSE would need to figure out we'd already loaded it
910 into a register before. For prec > BITS_PER_WORD, I think CONST_INT
911 might be more beneficial, as then the multi-word comparison can be
912 perhaps simplified. */
913 if (prec
<= BITS_PER_WORD
914 ? (CONST_SCALAR_INT_P (op1
) && REG_P (op0
))
915 : CONST_SCALAR_INT_P (op0
))
917 do_compare_rtx_and_jump (res
, tem
, GEU
, true, mode
, NULL_RTX
, NULL
,
918 done_label
, profile_probability::very_likely ());
923 if (!uns0_p
&& !uns1_p
&& unsr_p
)
925 /* Compute the operation. On RTL level, the addition is always
927 res
= expand_binop (mode
, code
== PLUS_EXPR
? add_optab
: sub_optab
,
928 op0
, op1
, NULL_RTX
, false, OPTAB_LIB_WIDEN
);
929 int pos_neg
= get_range_pos_neg (arg1
);
930 if (code
== PLUS_EXPR
)
932 int pos_neg0
= get_range_pos_neg (arg0
);
933 if (pos_neg0
!= 3 && pos_neg
== 3)
935 std::swap (op0
, op1
);
942 tem
= expand_binop (mode
, ((pos_neg
== 1) ^ (code
== MINUS_EXPR
))
943 ? and_optab
: ior_optab
,
944 op0
, res
, NULL_RTX
, false, OPTAB_LIB_WIDEN
);
945 do_compare_rtx_and_jump (tem
, const0_rtx
, GE
, false, mode
, NULL
,
946 NULL
, done_label
, profile_probability::very_likely ());
950 rtx_code_label
*do_ior_label
= gen_label_rtx ();
951 do_compare_rtx_and_jump (op1
, const0_rtx
,
952 code
== MINUS_EXPR
? GE
: LT
, false, mode
,
953 NULL_RTX
, NULL
, do_ior_label
,
954 profile_probability::even ());
955 tem
= expand_binop (mode
, and_optab
, op0
, res
, NULL_RTX
, false,
957 do_compare_rtx_and_jump (tem
, const0_rtx
, GE
, false, mode
, NULL_RTX
,
958 NULL
, done_label
, profile_probability::very_likely ());
959 emit_jump (do_error
);
960 emit_label (do_ior_label
);
961 tem
= expand_binop (mode
, ior_optab
, op0
, res
, NULL_RTX
, false,
963 do_compare_rtx_and_jump (tem
, const0_rtx
, GE
, false, mode
, NULL_RTX
,
964 NULL
, done_label
, profile_probability::very_likely ());
970 if (code
== MINUS_EXPR
&& uns0_p
&& uns1_p
&& !unsr_p
)
972 /* Compute the operation. On RTL level, the addition is always
974 res
= expand_binop (mode
, sub_optab
, op0
, op1
, NULL_RTX
, false,
976 rtx_code_label
*op0_geu_op1
= gen_label_rtx ();
977 do_compare_rtx_and_jump (op0
, op1
, GEU
, true, mode
, NULL_RTX
, NULL
,
978 op0_geu_op1
, profile_probability::even ());
979 do_compare_rtx_and_jump (res
, const0_rtx
, LT
, false, mode
, NULL_RTX
,
980 NULL
, done_label
, profile_probability::very_likely ());
981 emit_jump (do_error
);
982 emit_label (op0_geu_op1
);
983 do_compare_rtx_and_jump (res
, const0_rtx
, GE
, false, mode
, NULL_RTX
,
984 NULL
, done_label
, profile_probability::very_likely ());
988 gcc_assert (!uns0_p
&& !uns1_p
&& !unsr_p
);
993 insn_code icode
= optab_handler (code
== PLUS_EXPR
? addv4_optab
994 : subv4_optab
, mode
);
995 if (icode
!= CODE_FOR_nothing
)
997 struct expand_operand ops
[4];
998 rtx_insn
*last
= get_last_insn ();
1000 res
= gen_reg_rtx (mode
);
1001 create_output_operand (&ops
[0], res
, mode
);
1002 create_input_operand (&ops
[1], op0
, mode
);
1003 create_input_operand (&ops
[2], op1
, mode
);
1004 create_fixed_operand (&ops
[3], do_error
);
1005 if (maybe_expand_insn (icode
, 4, ops
))
1007 last
= get_last_insn ();
1008 if (profile_status_for_fn (cfun
) != PROFILE_ABSENT
1010 && any_condjump_p (last
)
1011 && !find_reg_note (last
, REG_BR_PROB
, 0))
1012 add_reg_br_prob_note (last
,
1013 profile_probability::very_unlikely ());
1014 emit_jump (done_label
);
1015 goto do_error_label
;
1018 delete_insns_since (last
);
1021 /* Compute the operation. On RTL level, the addition is always
1023 res
= expand_binop (mode
, code
== PLUS_EXPR
? add_optab
: sub_optab
,
1024 op0
, op1
, NULL_RTX
, false, OPTAB_LIB_WIDEN
);
1026 /* If we can prove that one of the arguments (for MINUS_EXPR only
1027 the second operand, as subtraction is not commutative) is always
1028 non-negative or always negative, we can do just one comparison
1029 and conditional jump. */
1030 int pos_neg
= get_range_pos_neg (arg1
);
1031 if (code
== PLUS_EXPR
)
1033 int pos_neg0
= get_range_pos_neg (arg0
);
1034 if (pos_neg0
!= 3 && pos_neg
== 3)
1036 std::swap (op0
, op1
);
1041 /* Addition overflows if and only if the two operands have the same sign,
1042 and the result has the opposite sign. Subtraction overflows if and
1043 only if the two operands have opposite sign, and the subtrahend has
1044 the same sign as the result. Here 0 is counted as positive. */
1047 /* Compute op0 ^ op1 (operands have opposite sign). */
1048 rtx op_xor
= expand_binop (mode
, xor_optab
, op0
, op1
, NULL_RTX
, false,
1051 /* Compute res ^ op1 (result and 2nd operand have opposite sign). */
1052 rtx res_xor
= expand_binop (mode
, xor_optab
, res
, op1
, NULL_RTX
, false,
1056 if (code
== PLUS_EXPR
)
1058 /* Compute (res ^ op1) & ~(op0 ^ op1). */
1059 tem
= expand_unop (mode
, one_cmpl_optab
, op_xor
, NULL_RTX
, false);
1060 tem
= expand_binop (mode
, and_optab
, res_xor
, tem
, NULL_RTX
, false,
1065 /* Compute (op0 ^ op1) & ~(res ^ op1). */
1066 tem
= expand_unop (mode
, one_cmpl_optab
, res_xor
, NULL_RTX
, false);
1067 tem
= expand_binop (mode
, and_optab
, op_xor
, tem
, NULL_RTX
, false,
1071 /* No overflow if the result has bit sign cleared. */
1072 do_compare_rtx_and_jump (tem
, const0_rtx
, GE
, false, mode
, NULL_RTX
,
1073 NULL
, done_label
, profile_probability::very_likely ());
1076 /* Compare the result of the operation with the first operand.
1077 No overflow for addition if second operand is positive and result
1078 is larger or second operand is negative and result is smaller.
1079 Likewise for subtraction with sign of second operand flipped. */
1081 do_compare_rtx_and_jump (res
, op0
,
1082 (pos_neg
== 1) ^ (code
== MINUS_EXPR
) ? GE
: LE
,
1083 false, mode
, NULL_RTX
, NULL
, done_label
,
1084 profile_probability::very_likely ());
1088 emit_label (do_error
);
1091 /* Expand the ubsan builtin call. */
1093 fn
= ubsan_build_overflow_builtin (code
, loc
, TREE_TYPE (arg0
),
1097 do_pending_stack_adjust ();
1100 expand_arith_set_overflow (lhs
, target
);
1103 emit_label (done_label
);
1108 expand_ubsan_result_store (target
, res
);
1112 res
= expand_binop (mode
, add_optab
, res
, sgn
, NULL_RTX
, false,
1115 expand_arith_overflow_result_store (lhs
, target
, mode
, res
);
1120 /* Add negate overflow checking to the statement STMT. */
1123 expand_neg_overflow (location_t loc
, tree lhs
, tree arg1
, bool is_ubsan
,
1128 rtx_code_label
*done_label
, *do_error
;
1129 rtx target
= NULL_RTX
;
1131 done_label
= gen_label_rtx ();
1132 do_error
= gen_label_rtx ();
1134 do_pending_stack_adjust ();
1135 op1
= expand_normal (arg1
);
1137 scalar_int_mode mode
= SCALAR_INT_TYPE_MODE (TREE_TYPE (arg1
));
1140 target
= expand_expr (lhs
, NULL_RTX
, VOIDmode
, EXPAND_WRITE
);
1142 write_complex_part (target
, const0_rtx
, true);
1145 enum insn_code icode
= optab_handler (negv3_optab
, mode
);
1146 if (icode
!= CODE_FOR_nothing
)
1148 struct expand_operand ops
[3];
1149 rtx_insn
*last
= get_last_insn ();
1151 res
= gen_reg_rtx (mode
);
1152 create_output_operand (&ops
[0], res
, mode
);
1153 create_input_operand (&ops
[1], op1
, mode
);
1154 create_fixed_operand (&ops
[2], do_error
);
1155 if (maybe_expand_insn (icode
, 3, ops
))
1157 last
= get_last_insn ();
1158 if (profile_status_for_fn (cfun
) != PROFILE_ABSENT
1160 && any_condjump_p (last
)
1161 && !find_reg_note (last
, REG_BR_PROB
, 0))
1162 add_reg_br_prob_note (last
,
1163 profile_probability::very_unlikely ());
1164 emit_jump (done_label
);
1168 delete_insns_since (last
);
1169 icode
= CODE_FOR_nothing
;
1173 if (icode
== CODE_FOR_nothing
)
1175 /* Compute the operation. On RTL level, the addition is always
1177 res
= expand_unop (mode
, neg_optab
, op1
, NULL_RTX
, false);
1179 /* Compare the operand with the most negative value. */
1180 rtx minv
= expand_normal (TYPE_MIN_VALUE (TREE_TYPE (arg1
)));
1181 do_compare_rtx_and_jump (op1
, minv
, NE
, true, mode
, NULL_RTX
, NULL
,
1182 done_label
, profile_probability::very_likely ());
1185 emit_label (do_error
);
1188 /* Expand the ubsan builtin call. */
1190 fn
= ubsan_build_overflow_builtin (NEGATE_EXPR
, loc
, TREE_TYPE (arg1
),
1191 arg1
, NULL_TREE
, datap
);
1194 do_pending_stack_adjust ();
1197 expand_arith_set_overflow (lhs
, target
);
1200 emit_label (done_label
);
1205 expand_ubsan_result_store (target
, res
);
1207 expand_arith_overflow_result_store (lhs
, target
, mode
, res
);
1211 /* Return true if UNS WIDEN_MULT_EXPR with result mode WMODE and operand
1212 mode MODE can be expanded without using a libcall. */
1215 can_widen_mult_without_libcall (scalar_int_mode wmode
, scalar_int_mode mode
,
1216 rtx op0
, rtx op1
, bool uns
)
1218 if (find_widening_optab_handler (umul_widen_optab
, wmode
, mode
)
1219 != CODE_FOR_nothing
)
1222 if (find_widening_optab_handler (smul_widen_optab
, wmode
, mode
)
1223 != CODE_FOR_nothing
)
1226 rtx_insn
*last
= get_last_insn ();
1227 if (CONSTANT_P (op0
))
1228 op0
= convert_modes (wmode
, mode
, op0
, uns
);
1230 op0
= gen_raw_REG (wmode
, LAST_VIRTUAL_REGISTER
+ 1);
1231 if (CONSTANT_P (op1
))
1232 op1
= convert_modes (wmode
, mode
, op1
, uns
);
1234 op1
= gen_raw_REG (wmode
, LAST_VIRTUAL_REGISTER
+ 2);
1235 rtx ret
= expand_mult (wmode
, op0
, op1
, NULL_RTX
, uns
, true);
1236 delete_insns_since (last
);
1237 return ret
!= NULL_RTX
;
1240 /* Add mul overflow checking to the statement STMT. */
1243 expand_mul_overflow (location_t loc
, tree lhs
, tree arg0
, tree arg1
,
1244 bool unsr_p
, bool uns0_p
, bool uns1_p
, bool is_ubsan
,
1249 rtx_code_label
*done_label
, *do_error
;
1250 rtx target
= NULL_RTX
;
1252 enum insn_code icode
;
1254 done_label
= gen_label_rtx ();
1255 do_error
= gen_label_rtx ();
1257 do_pending_stack_adjust ();
1258 op0
= expand_normal (arg0
);
1259 op1
= expand_normal (arg1
);
1261 scalar_int_mode mode
= SCALAR_INT_TYPE_MODE (TREE_TYPE (arg0
));
1265 target
= expand_expr (lhs
, NULL_RTX
, VOIDmode
, EXPAND_WRITE
);
1267 write_complex_part (target
, const0_rtx
, true);
1271 gcc_assert (!unsr_p
&& !uns0_p
&& !uns1_p
);
1273 /* We assume both operands and result have the same precision
1274 here (GET_MODE_BITSIZE (mode)), S stands for signed type
1275 with that precision, U for unsigned type with that precision,
1276 sgn for unsigned most significant bit in that precision.
1277 s1 is signed first operand, u1 is unsigned first operand,
1278 s2 is signed second operand, u2 is unsigned second operand,
1279 sr is signed result, ur is unsigned result and the following
1280 rules say how to compute result (which is always result of
1281 the operands as if both were unsigned, cast to the right
1282 signedness) and how to compute whether operation overflowed.
1283 main_ovf (false) stands for jump on signed multiplication
1284 overflow or the main algorithm with uns == false.
1285 main_ovf (true) stands for jump on unsigned multiplication
1286 overflow or the main algorithm with uns == true.
1289 res = (S) ((U) s1 * (U) s2)
1290 ovf = main_ovf (false)
1293 ovf = main_ovf (true)
1296 ovf = (s1 < 0 && u2) || main_ovf (true)
1299 ovf = res < 0 || main_ovf (true)
1301 res = (S) ((U) s1 * u2)
1302 ovf = (S) u2 >= 0 ? main_ovf (false)
1303 : (s1 != 0 && (s1 != -1 || u2 != (U) res))
1305 t1 = (s1 & s2) < 0 ? (-(U) s1) : ((U) s1)
1306 t2 = (s1 & s2) < 0 ? (-(U) s2) : ((U) s2)
1308 ovf = (s1 ^ s2) < 0 ? (s1 && s2) : main_ovf (true) */
1310 if (uns0_p
&& !uns1_p
)
1312 /* Multiplication is commutative, if operand signedness differs,
1313 canonicalize to the first operand being signed and second
1314 unsigned to simplify following code. */
1315 std::swap (op0
, op1
);
1316 std::swap (arg0
, arg1
);
1321 int pos_neg0
= get_range_pos_neg (arg0
);
1322 int pos_neg1
= get_range_pos_neg (arg1
);
1325 if (!uns0_p
&& uns1_p
&& unsr_p
)
1330 /* If s1 is non-negative, just perform normal u1 * u2 -> ur. */
1333 /* If s1 is negative, avoid the main code, just multiply and
1334 signal overflow if op1 is not 0. */
1335 struct separate_ops ops
;
1336 ops
.code
= MULT_EXPR
;
1337 ops
.type
= TREE_TYPE (arg1
);
1338 ops
.op0
= make_tree (ops
.type
, op0
);
1339 ops
.op1
= make_tree (ops
.type
, op1
);
1340 ops
.op2
= NULL_TREE
;
1342 res
= expand_expr_real_2 (&ops
, NULL_RTX
, mode
, EXPAND_NORMAL
);
1343 do_compare_rtx_and_jump (op1
, const0_rtx
, EQ
, true, mode
, NULL_RTX
,
1344 NULL
, done_label
, profile_probability::very_likely ());
1345 goto do_error_label
;
1347 rtx_code_label
*do_main_label
;
1348 do_main_label
= gen_label_rtx ();
1349 do_compare_rtx_and_jump (op0
, const0_rtx
, GE
, false, mode
, NULL_RTX
,
1350 NULL
, do_main_label
, profile_probability::very_likely ());
1351 do_compare_rtx_and_jump (op1
, const0_rtx
, EQ
, true, mode
, NULL_RTX
,
1352 NULL
, do_main_label
, profile_probability::very_likely ());
1353 expand_arith_set_overflow (lhs
, target
);
1354 emit_label (do_main_label
);
1362 if (uns0_p
&& uns1_p
&& !unsr_p
)
1365 /* Rest of handling of this case after res is computed. */
1370 if (!uns0_p
&& uns1_p
&& !unsr_p
)
1377 /* If (S) u2 is negative (i.e. u2 is larger than maximum of S,
1378 avoid the main code, just multiply and signal overflow
1379 unless 0 * u2 or -1 * ((U) Smin). */
1380 struct separate_ops ops
;
1381 ops
.code
= MULT_EXPR
;
1382 ops
.type
= TREE_TYPE (arg1
);
1383 ops
.op0
= make_tree (ops
.type
, op0
);
1384 ops
.op1
= make_tree (ops
.type
, op1
);
1385 ops
.op2
= NULL_TREE
;
1387 res
= expand_expr_real_2 (&ops
, NULL_RTX
, mode
, EXPAND_NORMAL
);
1388 do_compare_rtx_and_jump (op0
, const0_rtx
, EQ
, true, mode
, NULL_RTX
,
1389 NULL
, done_label
, profile_probability::very_likely ());
1390 do_compare_rtx_and_jump (op0
, constm1_rtx
, NE
, true, mode
, NULL_RTX
,
1391 NULL
, do_error
, profile_probability::very_unlikely ());
1393 prec
= GET_MODE_PRECISION (mode
);
1395 sgn
= immed_wide_int_const (wi::min_value (prec
, SIGNED
), mode
);
1396 do_compare_rtx_and_jump (op1
, sgn
, EQ
, true, mode
, NULL_RTX
,
1397 NULL
, done_label
, profile_probability::very_likely ());
1398 goto do_error_label
;
1400 /* Rest of handling of this case after res is computed. */
1408 if (!uns0_p
&& !uns1_p
&& unsr_p
)
1411 switch (pos_neg0
| pos_neg1
)
1413 case 1: /* Both operands known to be non-negative. */
1415 case 2: /* Both operands known to be negative. */
1416 op0
= expand_unop (mode
, neg_optab
, op0
, NULL_RTX
, false);
1417 op1
= expand_unop (mode
, neg_optab
, op1
, NULL_RTX
, false);
1418 /* Avoid looking at arg0/arg1 ranges, as we've changed
1420 arg0
= error_mark_node
;
1421 arg1
= error_mark_node
;
1424 if ((pos_neg0
^ pos_neg1
) == 3)
1426 /* If one operand is known to be negative and the other
1427 non-negative, this overflows always, unless the non-negative
1428 one is 0. Just do normal multiply and set overflow
1429 unless one of the operands is 0. */
1430 struct separate_ops ops
;
1431 ops
.code
= MULT_EXPR
;
1433 = build_nonstandard_integer_type (GET_MODE_PRECISION (mode
),
1435 ops
.op0
= make_tree (ops
.type
, op0
);
1436 ops
.op1
= make_tree (ops
.type
, op1
);
1437 ops
.op2
= NULL_TREE
;
1439 res
= expand_expr_real_2 (&ops
, NULL_RTX
, mode
, EXPAND_NORMAL
);
1440 tem
= expand_binop (mode
, and_optab
, op0
, op1
, NULL_RTX
, false,
1442 do_compare_rtx_and_jump (tem
, const0_rtx
, EQ
, true, mode
,
1443 NULL_RTX
, NULL
, done_label
,
1444 profile_probability::very_likely ());
1445 goto do_error_label
;
1447 /* The general case, do all the needed comparisons at runtime. */
1448 rtx_code_label
*do_main_label
, *after_negate_label
;
1450 rop0
= gen_reg_rtx (mode
);
1451 rop1
= gen_reg_rtx (mode
);
1452 emit_move_insn (rop0
, op0
);
1453 emit_move_insn (rop1
, op1
);
1456 do_main_label
= gen_label_rtx ();
1457 after_negate_label
= gen_label_rtx ();
1458 tem
= expand_binop (mode
, and_optab
, op0
, op1
, NULL_RTX
, false,
1460 do_compare_rtx_and_jump (tem
, const0_rtx
, GE
, false, mode
, NULL_RTX
,
1461 NULL
, after_negate_label
, profile_probability::very_likely ());
1462 /* Both arguments negative here, negate them and continue with
1463 normal unsigned overflow checking multiplication. */
1464 emit_move_insn (op0
, expand_unop (mode
, neg_optab
, op0
,
1466 emit_move_insn (op1
, expand_unop (mode
, neg_optab
, op1
,
1468 /* Avoid looking at arg0/arg1 ranges, as we might have changed
1470 arg0
= error_mark_node
;
1471 arg1
= error_mark_node
;
1472 emit_jump (do_main_label
);
1473 emit_label (after_negate_label
);
1474 tem2
= expand_binop (mode
, xor_optab
, op0
, op1
, NULL_RTX
, false,
1476 do_compare_rtx_and_jump (tem2
, const0_rtx
, GE
, false, mode
, NULL_RTX
,
1477 NULL
, do_main_label
, profile_probability::very_likely ());
1478 /* One argument is negative here, the other positive. This
1479 overflows always, unless one of the arguments is 0. But
1480 if e.g. s2 is 0, (U) s1 * 0 doesn't overflow, whatever s1
1481 is, thus we can keep do_main code oring in overflow as is. */
1482 do_compare_rtx_and_jump (tem
, const0_rtx
, EQ
, true, mode
, NULL_RTX
,
1483 NULL
, do_main_label
, profile_probability::very_likely ());
1484 expand_arith_set_overflow (lhs
, target
);
1485 emit_label (do_main_label
);
1493 type
= build_nonstandard_integer_type (GET_MODE_PRECISION (mode
), uns
);
1494 sign
= uns
? UNSIGNED
: SIGNED
;
1495 icode
= optab_handler (uns
? umulv4_optab
: mulv4_optab
, mode
);
1497 && (integer_pow2p (arg0
) || integer_pow2p (arg1
))
1498 && (optimize_insn_for_speed_p () || icode
== CODE_FOR_nothing
))
1500 /* Optimize unsigned multiplication by power of 2 constant
1501 using 2 shifts, one for result, one to extract the shifted
1502 out bits to see if they are all zero.
1503 Don't do this if optimizing for size and we have umulv4_optab,
1504 in that case assume multiplication will be shorter.
1505 This is heuristics based on the single target that provides
1506 umulv4 right now (i?86/x86_64), if further targets add it, this
1507 might need to be revisited.
1508 Cases where both operands are constant should be folded already
1509 during GIMPLE, and cases where one operand is constant but not
1510 power of 2 are questionable, either the WIDEN_MULT_EXPR case
1511 below can be done without multiplication, just by shifts and adds,
1512 or we'd need to divide the result (and hope it actually doesn't
1513 really divide nor multiply) and compare the result of the division
1514 with the original operand. */
1519 if (integer_pow2p (arg0
))
1521 std::swap (opn0
, opn1
);
1522 std::swap (argn0
, argn1
);
1524 int cnt
= tree_log2 (argn1
);
1525 if (cnt
>= 0 && cnt
< GET_MODE_PRECISION (mode
))
1527 rtx upper
= const0_rtx
;
1528 res
= expand_shift (LSHIFT_EXPR
, mode
, opn0
, cnt
, NULL_RTX
, uns
);
1530 upper
= expand_shift (RSHIFT_EXPR
, mode
, opn0
,
1531 GET_MODE_PRECISION (mode
) - cnt
,
1533 do_compare_rtx_and_jump (upper
, const0_rtx
, EQ
, true, mode
,
1534 NULL_RTX
, NULL
, done_label
,
1535 profile_probability::very_likely ());
1536 goto do_error_label
;
1539 if (icode
!= CODE_FOR_nothing
)
1541 struct expand_operand ops
[4];
1542 rtx_insn
*last
= get_last_insn ();
1544 res
= gen_reg_rtx (mode
);
1545 create_output_operand (&ops
[0], res
, mode
);
1546 create_input_operand (&ops
[1], op0
, mode
);
1547 create_input_operand (&ops
[2], op1
, mode
);
1548 create_fixed_operand (&ops
[3], do_error
);
1549 if (maybe_expand_insn (icode
, 4, ops
))
1551 last
= get_last_insn ();
1552 if (profile_status_for_fn (cfun
) != PROFILE_ABSENT
1554 && any_condjump_p (last
)
1555 && !find_reg_note (last
, REG_BR_PROB
, 0))
1556 add_reg_br_prob_note (last
,
1557 profile_probability::very_unlikely ());
1558 emit_jump (done_label
);
1562 delete_insns_since (last
);
1563 icode
= CODE_FOR_nothing
;
1567 if (icode
== CODE_FOR_nothing
)
1569 struct separate_ops ops
;
1570 int prec
= GET_MODE_PRECISION (mode
);
1571 scalar_int_mode hmode
, wmode
;
1572 ops
.op0
= make_tree (type
, op0
);
1573 ops
.op1
= make_tree (type
, op1
);
1574 ops
.op2
= NULL_TREE
;
1577 /* Optimize unsigned overflow check where we don't use the
1578 multiplication result, just whether overflow happened.
1579 If we can do MULT_HIGHPART_EXPR, that followed by
1580 comparison of the result against zero is cheapest.
1581 We'll still compute res, but it should be DCEd later. */
1587 && !(uns0_p
&& uns1_p
&& !unsr_p
)
1588 && can_mult_highpart_p (mode
, uns
) == 1
1589 && single_imm_use (lhs
, &use
, &use_stmt
)
1590 && is_gimple_assign (use_stmt
)
1591 && gimple_assign_rhs_code (use_stmt
) == IMAGPART_EXPR
)
1594 if (GET_MODE_2XWIDER_MODE (mode
).exists (&wmode
)
1595 && targetm
.scalar_mode_supported_p (wmode
)
1596 && can_widen_mult_without_libcall (wmode
, mode
, op0
, op1
, uns
))
1599 ops
.code
= WIDEN_MULT_EXPR
;
1601 = build_nonstandard_integer_type (GET_MODE_PRECISION (wmode
), uns
);
1603 res
= expand_expr_real_2 (&ops
, NULL_RTX
, wmode
, EXPAND_NORMAL
);
1604 rtx hipart
= expand_shift (RSHIFT_EXPR
, wmode
, res
, prec
,
1606 hipart
= convert_modes (mode
, wmode
, hipart
, uns
);
1607 res
= convert_modes (mode
, wmode
, res
, uns
);
1609 /* For the unsigned multiplication, there was overflow if
1610 HIPART is non-zero. */
1611 do_compare_rtx_and_jump (hipart
, const0_rtx
, EQ
, true, mode
,
1612 NULL_RTX
, NULL
, done_label
,
1613 profile_probability::very_likely ());
1616 rtx signbit
= expand_shift (RSHIFT_EXPR
, mode
, res
, prec
- 1,
1618 /* RES is low half of the double width result, HIPART
1619 the high half. There was overflow if
1620 HIPART is different from RES < 0 ? -1 : 0. */
1621 do_compare_rtx_and_jump (signbit
, hipart
, EQ
, true, mode
,
1622 NULL_RTX
, NULL
, done_label
,
1623 profile_probability::very_likely ());
1626 else if (can_mult_highpart_p (mode
, uns
) == 1)
1629 ops
.code
= MULT_HIGHPART_EXPR
;
1632 rtx hipart
= expand_expr_real_2 (&ops
, NULL_RTX
, mode
,
1634 ops
.code
= MULT_EXPR
;
1635 res
= expand_expr_real_2 (&ops
, NULL_RTX
, mode
, EXPAND_NORMAL
);
1637 /* For the unsigned multiplication, there was overflow if
1638 HIPART is non-zero. */
1639 do_compare_rtx_and_jump (hipart
, const0_rtx
, EQ
, true, mode
,
1640 NULL_RTX
, NULL
, done_label
,
1641 profile_probability::very_likely ());
1644 rtx signbit
= expand_shift (RSHIFT_EXPR
, mode
, res
, prec
- 1,
1646 /* RES is low half of the double width result, HIPART
1647 the high half. There was overflow if
1648 HIPART is different from RES < 0 ? -1 : 0. */
1649 do_compare_rtx_and_jump (signbit
, hipart
, EQ
, true, mode
,
1650 NULL_RTX
, NULL
, done_label
,
1651 profile_probability::very_likely ());
1655 else if (int_mode_for_size (prec
/ 2, 1).exists (&hmode
)
1656 && 2 * GET_MODE_PRECISION (hmode
) == prec
)
1658 rtx_code_label
*large_op0
= gen_label_rtx ();
1659 rtx_code_label
*small_op0_large_op1
= gen_label_rtx ();
1660 rtx_code_label
*one_small_one_large
= gen_label_rtx ();
1661 rtx_code_label
*both_ops_large
= gen_label_rtx ();
1662 rtx_code_label
*after_hipart_neg
= uns
? NULL
: gen_label_rtx ();
1663 rtx_code_label
*after_lopart_neg
= uns
? NULL
: gen_label_rtx ();
1664 rtx_code_label
*do_overflow
= gen_label_rtx ();
1665 rtx_code_label
*hipart_different
= uns
? NULL
: gen_label_rtx ();
1667 unsigned int hprec
= GET_MODE_PRECISION (hmode
);
1668 rtx hipart0
= expand_shift (RSHIFT_EXPR
, mode
, op0
, hprec
,
1670 hipart0
= convert_modes (hmode
, mode
, hipart0
, uns
);
1671 rtx lopart0
= convert_modes (hmode
, mode
, op0
, uns
);
1672 rtx signbit0
= const0_rtx
;
1674 signbit0
= expand_shift (RSHIFT_EXPR
, hmode
, lopart0
, hprec
- 1,
1676 rtx hipart1
= expand_shift (RSHIFT_EXPR
, mode
, op1
, hprec
,
1678 hipart1
= convert_modes (hmode
, mode
, hipart1
, uns
);
1679 rtx lopart1
= convert_modes (hmode
, mode
, op1
, uns
);
1680 rtx signbit1
= const0_rtx
;
1682 signbit1
= expand_shift (RSHIFT_EXPR
, hmode
, lopart1
, hprec
- 1,
1685 res
= gen_reg_rtx (mode
);
1687 /* True if op0 resp. op1 are known to be in the range of
1689 bool op0_small_p
= false;
1690 bool op1_small_p
= false;
1691 /* True if op0 resp. op1 are known to have all zeros or all ones
1692 in the upper half of bits, but are not known to be
1694 bool op0_medium_p
= false;
1695 bool op1_medium_p
= false;
1696 /* -1 if op{0,1} is known to be negative, 0 if it is known to be
1697 nonnegative, 1 if unknown. */
1703 else if (pos_neg0
== 2)
1707 else if (pos_neg1
== 2)
1710 unsigned int mprec0
= prec
;
1711 if (arg0
!= error_mark_node
)
1712 mprec0
= get_min_precision (arg0
, sign
);
1713 if (mprec0
<= hprec
)
1715 else if (!uns
&& mprec0
<= hprec
+ 1)
1716 op0_medium_p
= true;
1717 unsigned int mprec1
= prec
;
1718 if (arg1
!= error_mark_node
)
1719 mprec1
= get_min_precision (arg1
, sign
);
1720 if (mprec1
<= hprec
)
1722 else if (!uns
&& mprec1
<= hprec
+ 1)
1723 op1_medium_p
= true;
1725 int smaller_sign
= 1;
1726 int larger_sign
= 1;
1729 smaller_sign
= op0_sign
;
1730 larger_sign
= op1_sign
;
1732 else if (op1_small_p
)
1734 smaller_sign
= op1_sign
;
1735 larger_sign
= op0_sign
;
1737 else if (op0_sign
== op1_sign
)
1739 smaller_sign
= op0_sign
;
1740 larger_sign
= op0_sign
;
1744 do_compare_rtx_and_jump (signbit0
, hipart0
, NE
, true, hmode
,
1745 NULL_RTX
, NULL
, large_op0
,
1746 profile_probability::unlikely ());
1749 do_compare_rtx_and_jump (signbit1
, hipart1
, NE
, true, hmode
,
1750 NULL_RTX
, NULL
, small_op0_large_op1
,
1751 profile_probability::unlikely ());
1753 /* If both op0 and op1 are sign (!uns) or zero (uns) extended from
1754 hmode to mode, the multiplication will never overflow. We can
1755 do just one hmode x hmode => mode widening multiplication. */
1756 tree halfstype
= build_nonstandard_integer_type (hprec
, uns
);
1757 ops
.op0
= make_tree (halfstype
, lopart0
);
1758 ops
.op1
= make_tree (halfstype
, lopart1
);
1759 ops
.code
= WIDEN_MULT_EXPR
;
1762 = expand_expr_real_2 (&ops
, NULL_RTX
, mode
, EXPAND_NORMAL
);
1763 emit_move_insn (res
, thisres
);
1764 emit_jump (done_label
);
1766 emit_label (small_op0_large_op1
);
1768 /* If op0 is sign (!uns) or zero (uns) extended from hmode to mode,
1769 but op1 is not, just swap the arguments and handle it as op1
1770 sign/zero extended, op0 not. */
1771 rtx larger
= gen_reg_rtx (mode
);
1772 rtx hipart
= gen_reg_rtx (hmode
);
1773 rtx lopart
= gen_reg_rtx (hmode
);
1774 emit_move_insn (larger
, op1
);
1775 emit_move_insn (hipart
, hipart1
);
1776 emit_move_insn (lopart
, lopart0
);
1777 emit_jump (one_small_one_large
);
1779 emit_label (large_op0
);
1782 do_compare_rtx_and_jump (signbit1
, hipart1
, NE
, true, hmode
,
1783 NULL_RTX
, NULL
, both_ops_large
,
1784 profile_probability::unlikely ());
1786 /* If op1 is sign (!uns) or zero (uns) extended from hmode to mode,
1787 but op0 is not, prepare larger, hipart and lopart pseudos and
1788 handle it together with small_op0_large_op1. */
1789 emit_move_insn (larger
, op0
);
1790 emit_move_insn (hipart
, hipart0
);
1791 emit_move_insn (lopart
, lopart1
);
1793 emit_label (one_small_one_large
);
1795 /* lopart is the low part of the operand that is sign extended
1796 to mode, larger is the other operand, hipart is the
1797 high part of larger and lopart0 and lopart1 are the low parts
1799 We perform lopart0 * lopart1 and lopart * hipart widening
1801 tree halfutype
= build_nonstandard_integer_type (hprec
, 1);
1802 ops
.op0
= make_tree (halfutype
, lopart0
);
1803 ops
.op1
= make_tree (halfutype
, lopart1
);
1805 = expand_expr_real_2 (&ops
, NULL_RTX
, mode
, EXPAND_NORMAL
);
1807 ops
.op0
= make_tree (halfutype
, lopart
);
1808 ops
.op1
= make_tree (halfutype
, hipart
);
1809 rtx loxhi
= gen_reg_rtx (mode
);
1810 rtx tem
= expand_expr_real_2 (&ops
, NULL_RTX
, mode
, EXPAND_NORMAL
);
1811 emit_move_insn (loxhi
, tem
);
1815 /* if (hipart < 0) loxhi -= lopart << (bitsize / 2); */
1816 if (larger_sign
== 0)
1817 emit_jump (after_hipart_neg
);
1818 else if (larger_sign
!= -1)
1819 do_compare_rtx_and_jump (hipart
, const0_rtx
, GE
, false, hmode
,
1820 NULL_RTX
, NULL
, after_hipart_neg
,
1821 profile_probability::even ());
1823 tem
= convert_modes (mode
, hmode
, lopart
, 1);
1824 tem
= expand_shift (LSHIFT_EXPR
, mode
, tem
, hprec
, NULL_RTX
, 1);
1825 tem
= expand_simple_binop (mode
, MINUS
, loxhi
, tem
, NULL_RTX
,
1827 emit_move_insn (loxhi
, tem
);
1829 emit_label (after_hipart_neg
);
1831 /* if (lopart < 0) loxhi -= larger; */
1832 if (smaller_sign
== 0)
1833 emit_jump (after_lopart_neg
);
1834 else if (smaller_sign
!= -1)
1835 do_compare_rtx_and_jump (lopart
, const0_rtx
, GE
, false, hmode
,
1836 NULL_RTX
, NULL
, after_lopart_neg
,
1837 profile_probability::even ());
1839 tem
= expand_simple_binop (mode
, MINUS
, loxhi
, larger
, NULL_RTX
,
1841 emit_move_insn (loxhi
, tem
);
1843 emit_label (after_lopart_neg
);
1846 /* loxhi += (uns) lo0xlo1 >> (bitsize / 2); */
1847 tem
= expand_shift (RSHIFT_EXPR
, mode
, lo0xlo1
, hprec
, NULL_RTX
, 1);
1848 tem
= expand_simple_binop (mode
, PLUS
, loxhi
, tem
, NULL_RTX
,
1850 emit_move_insn (loxhi
, tem
);
1852 /* if (loxhi >> (bitsize / 2)
1853 == (hmode) loxhi >> (bitsize / 2 - 1)) (if !uns)
1854 if (loxhi >> (bitsize / 2) == 0 (if uns). */
1855 rtx hipartloxhi
= expand_shift (RSHIFT_EXPR
, mode
, loxhi
, hprec
,
1857 hipartloxhi
= convert_modes (hmode
, mode
, hipartloxhi
, 0);
1858 rtx signbitloxhi
= const0_rtx
;
1860 signbitloxhi
= expand_shift (RSHIFT_EXPR
, hmode
,
1861 convert_modes (hmode
, mode
,
1863 hprec
- 1, NULL_RTX
, 0);
1865 do_compare_rtx_and_jump (signbitloxhi
, hipartloxhi
, NE
, true, hmode
,
1866 NULL_RTX
, NULL
, do_overflow
,
1867 profile_probability::very_unlikely ());
1869 /* res = (loxhi << (bitsize / 2)) | (hmode) lo0xlo1; */
1870 rtx loxhishifted
= expand_shift (LSHIFT_EXPR
, mode
, loxhi
, hprec
,
1872 tem
= convert_modes (mode
, hmode
,
1873 convert_modes (hmode
, mode
, lo0xlo1
, 1), 1);
1875 tem
= expand_simple_binop (mode
, IOR
, loxhishifted
, tem
, res
,
1878 emit_move_insn (res
, tem
);
1879 emit_jump (done_label
);
1881 emit_label (both_ops_large
);
1883 /* If both operands are large (not sign (!uns) or zero (uns)
1884 extended from hmode), then perform the full multiplication
1885 which will be the result of the operation.
1886 The only cases which don't overflow are for signed multiplication
1887 some cases where both hipart0 and highpart1 are 0 or -1.
1888 For unsigned multiplication when high parts are both non-zero
1889 this overflows always. */
1890 ops
.code
= MULT_EXPR
;
1891 ops
.op0
= make_tree (type
, op0
);
1892 ops
.op1
= make_tree (type
, op1
);
1893 tem
= expand_expr_real_2 (&ops
, NULL_RTX
, mode
, EXPAND_NORMAL
);
1894 emit_move_insn (res
, tem
);
1900 tem
= expand_simple_binop (hmode
, PLUS
, hipart0
, const1_rtx
,
1901 NULL_RTX
, 1, OPTAB_WIDEN
);
1902 do_compare_rtx_and_jump (tem
, const1_rtx
, GTU
, true, hmode
,
1903 NULL_RTX
, NULL
, do_error
,
1904 profile_probability::very_unlikely ());
1909 tem
= expand_simple_binop (hmode
, PLUS
, hipart1
, const1_rtx
,
1910 NULL_RTX
, 1, OPTAB_WIDEN
);
1911 do_compare_rtx_and_jump (tem
, const1_rtx
, GTU
, true, hmode
,
1912 NULL_RTX
, NULL
, do_error
,
1913 profile_probability::very_unlikely ());
1916 /* At this point hipart{0,1} are both in [-1, 0]. If they are
1917 the same, overflow happened if res is non-positive, if they
1918 are different, overflow happened if res is positive. */
1919 if (op0_sign
!= 1 && op1_sign
!= 1 && op0_sign
!= op1_sign
)
1920 emit_jump (hipart_different
);
1921 else if (op0_sign
== 1 || op1_sign
== 1)
1922 do_compare_rtx_and_jump (hipart0
, hipart1
, NE
, true, hmode
,
1923 NULL_RTX
, NULL
, hipart_different
,
1924 profile_probability::even ());
1926 do_compare_rtx_and_jump (res
, const0_rtx
, LE
, false, mode
,
1927 NULL_RTX
, NULL
, do_error
,
1928 profile_probability::very_unlikely ());
1929 emit_jump (done_label
);
1931 emit_label (hipart_different
);
1933 do_compare_rtx_and_jump (res
, const0_rtx
, GE
, false, mode
,
1934 NULL_RTX
, NULL
, do_error
,
1935 profile_probability::very_unlikely ());
1936 emit_jump (done_label
);
1939 emit_label (do_overflow
);
1941 /* Overflow, do full multiplication and fallthru into do_error. */
1942 ops
.op0
= make_tree (type
, op0
);
1943 ops
.op1
= make_tree (type
, op1
);
1944 tem
= expand_expr_real_2 (&ops
, NULL_RTX
, mode
, EXPAND_NORMAL
);
1945 emit_move_insn (res
, tem
);
1947 else if (GET_MODE_2XWIDER_MODE (mode
).exists (&wmode
)
1948 && targetm
.scalar_mode_supported_p (wmode
))
1949 /* Even emitting a libcall is better than not detecting overflow
1954 gcc_assert (!is_ubsan
);
1955 ops
.code
= MULT_EXPR
;
1957 res
= expand_expr_real_2 (&ops
, NULL_RTX
, mode
, EXPAND_NORMAL
);
1958 emit_jump (done_label
);
1963 emit_label (do_error
);
1966 /* Expand the ubsan builtin call. */
1968 fn
= ubsan_build_overflow_builtin (MULT_EXPR
, loc
, TREE_TYPE (arg0
),
1972 do_pending_stack_adjust ();
1975 expand_arith_set_overflow (lhs
, target
);
1978 emit_label (done_label
);
1981 if (uns0_p
&& uns1_p
&& !unsr_p
)
1983 rtx_code_label
*all_done_label
= gen_label_rtx ();
1984 do_compare_rtx_and_jump (res
, const0_rtx
, GE
, false, mode
, NULL_RTX
,
1985 NULL
, all_done_label
, profile_probability::very_likely ());
1986 expand_arith_set_overflow (lhs
, target
);
1987 emit_label (all_done_label
);
1991 if (!uns0_p
&& uns1_p
&& !unsr_p
&& pos_neg1
== 3)
1993 rtx_code_label
*all_done_label
= gen_label_rtx ();
1994 rtx_code_label
*set_noovf
= gen_label_rtx ();
1995 do_compare_rtx_and_jump (op1
, const0_rtx
, GE
, false, mode
, NULL_RTX
,
1996 NULL
, all_done_label
, profile_probability::very_likely ());
1997 expand_arith_set_overflow (lhs
, target
);
1998 do_compare_rtx_and_jump (op0
, const0_rtx
, EQ
, true, mode
, NULL_RTX
,
1999 NULL
, set_noovf
, profile_probability::very_likely ());
2000 do_compare_rtx_and_jump (op0
, constm1_rtx
, NE
, true, mode
, NULL_RTX
,
2001 NULL
, all_done_label
, profile_probability::very_unlikely ());
2002 do_compare_rtx_and_jump (op1
, res
, NE
, true, mode
, NULL_RTX
, NULL
,
2003 all_done_label
, profile_probability::very_unlikely ());
2004 emit_label (set_noovf
);
2005 write_complex_part (target
, const0_rtx
, true);
2006 emit_label (all_done_label
);
2012 expand_ubsan_result_store (target
, res
);
2014 expand_arith_overflow_result_store (lhs
, target
, mode
, res
);
2018 /* Expand UBSAN_CHECK_* internal function if it has vector operands. */
2021 expand_vector_ubsan_overflow (location_t loc
, enum tree_code code
, tree lhs
,
2022 tree arg0
, tree arg1
)
2024 poly_uint64 cnt
= TYPE_VECTOR_SUBPARTS (TREE_TYPE (arg0
));
2025 rtx_code_label
*loop_lab
= NULL
;
2026 rtx cntvar
= NULL_RTX
;
2027 tree cntv
= NULL_TREE
;
2028 tree eltype
= TREE_TYPE (TREE_TYPE (arg0
));
2029 tree sz
= TYPE_SIZE (eltype
);
2030 tree data
= NULL_TREE
;
2031 tree resv
= NULL_TREE
;
2032 rtx lhsr
= NULL_RTX
;
2033 rtx resvr
= NULL_RTX
;
2034 unsigned HOST_WIDE_INT const_cnt
= 0;
2035 bool use_loop_p
= (!cnt
.is_constant (&const_cnt
) || const_cnt
> 4);
2040 lhsr
= expand_expr (lhs
, NULL_RTX
, VOIDmode
, EXPAND_WRITE
);
2041 if (!VECTOR_MODE_P (GET_MODE (lhsr
))
2042 || (op
= optab_for_tree_code (code
, TREE_TYPE (arg0
),
2043 optab_default
)) == unknown_optab
2044 || (optab_handler (op
, TYPE_MODE (TREE_TYPE (arg0
)))
2045 == CODE_FOR_nothing
))
2048 resv
= make_tree (TREE_TYPE (lhs
), lhsr
);
2051 resvr
= assign_temp (TREE_TYPE (lhs
), 1, 1);
2052 resv
= make_tree (TREE_TYPE (lhs
), resvr
);
2058 do_pending_stack_adjust ();
2059 loop_lab
= gen_label_rtx ();
2060 cntvar
= gen_reg_rtx (TYPE_MODE (sizetype
));
2061 cntv
= make_tree (sizetype
, cntvar
);
2062 emit_move_insn (cntvar
, const0_rtx
);
2063 emit_label (loop_lab
);
2065 if (TREE_CODE (arg0
) != VECTOR_CST
)
2067 rtx arg0r
= expand_normal (arg0
);
2068 arg0
= make_tree (TREE_TYPE (arg0
), arg0r
);
2070 if (TREE_CODE (arg1
) != VECTOR_CST
)
2072 rtx arg1r
= expand_normal (arg1
);
2073 arg1
= make_tree (TREE_TYPE (arg1
), arg1r
);
2075 for (unsigned int i
= 0; i
< (use_loop_p
? 1 : const_cnt
); i
++)
2077 tree op0
, op1
, res
= NULL_TREE
;
2080 tree atype
= build_array_type_nelts (eltype
, cnt
);
2081 op0
= uniform_vector_p (arg0
);
2082 if (op0
== NULL_TREE
)
2084 op0
= fold_build1_loc (loc
, VIEW_CONVERT_EXPR
, atype
, arg0
);
2085 op0
= build4_loc (loc
, ARRAY_REF
, eltype
, op0
, cntv
,
2086 NULL_TREE
, NULL_TREE
);
2088 op1
= uniform_vector_p (arg1
);
2089 if (op1
== NULL_TREE
)
2091 op1
= fold_build1_loc (loc
, VIEW_CONVERT_EXPR
, atype
, arg1
);
2092 op1
= build4_loc (loc
, ARRAY_REF
, eltype
, op1
, cntv
,
2093 NULL_TREE
, NULL_TREE
);
2097 res
= fold_build1_loc (loc
, VIEW_CONVERT_EXPR
, atype
, resv
);
2098 res
= build4_loc (loc
, ARRAY_REF
, eltype
, res
, cntv
,
2099 NULL_TREE
, NULL_TREE
);
2104 tree bitpos
= bitsize_int (tree_to_uhwi (sz
) * i
);
2105 op0
= fold_build3_loc (loc
, BIT_FIELD_REF
, eltype
, arg0
, sz
, bitpos
);
2106 op1
= fold_build3_loc (loc
, BIT_FIELD_REF
, eltype
, arg1
, sz
, bitpos
);
2108 res
= fold_build3_loc (loc
, BIT_FIELD_REF
, eltype
, resv
, sz
,
2114 expand_addsub_overflow (loc
, PLUS_EXPR
, res
, op0
, op1
,
2115 false, false, false, true, &data
);
2118 if (use_loop_p
? integer_zerop (arg0
) : integer_zerop (op0
))
2119 expand_neg_overflow (loc
, res
, op1
, true, &data
);
2121 expand_addsub_overflow (loc
, MINUS_EXPR
, res
, op0
, op1
,
2122 false, false, false, true, &data
);
2125 expand_mul_overflow (loc
, res
, op0
, op1
, false, false, false,
2134 struct separate_ops ops
;
2135 ops
.code
= PLUS_EXPR
;
2136 ops
.type
= TREE_TYPE (cntv
);
2138 ops
.op1
= build_int_cst (TREE_TYPE (cntv
), 1);
2139 ops
.op2
= NULL_TREE
;
2141 rtx ret
= expand_expr_real_2 (&ops
, cntvar
, TYPE_MODE (sizetype
),
2144 emit_move_insn (cntvar
, ret
);
2145 rtx cntrtx
= gen_int_mode (cnt
, TYPE_MODE (sizetype
));
2146 do_compare_rtx_and_jump (cntvar
, cntrtx
, NE
, false,
2147 TYPE_MODE (sizetype
), NULL_RTX
, NULL
, loop_lab
,
2148 profile_probability::very_likely ());
2150 if (lhs
&& resv
== NULL_TREE
)
2152 struct separate_ops ops
;
2154 ops
.type
= TREE_TYPE (arg0
);
2157 ops
.op2
= NULL_TREE
;
2159 rtx ret
= expand_expr_real_2 (&ops
, lhsr
, TYPE_MODE (TREE_TYPE (arg0
)),
2162 emit_move_insn (lhsr
, ret
);
2165 emit_move_insn (lhsr
, resvr
);
2168 /* Expand UBSAN_CHECK_ADD call STMT. */
2171 expand_UBSAN_CHECK_ADD (internal_fn
, gcall
*stmt
)
2173 location_t loc
= gimple_location (stmt
);
2174 tree lhs
= gimple_call_lhs (stmt
);
2175 tree arg0
= gimple_call_arg (stmt
, 0);
2176 tree arg1
= gimple_call_arg (stmt
, 1);
2177 if (VECTOR_TYPE_P (TREE_TYPE (arg0
)))
2178 expand_vector_ubsan_overflow (loc
, PLUS_EXPR
, lhs
, arg0
, arg1
);
2180 expand_addsub_overflow (loc
, PLUS_EXPR
, lhs
, arg0
, arg1
,
2181 false, false, false, true, NULL
);
2184 /* Expand UBSAN_CHECK_SUB call STMT. */
2187 expand_UBSAN_CHECK_SUB (internal_fn
, gcall
*stmt
)
2189 location_t loc
= gimple_location (stmt
);
2190 tree lhs
= gimple_call_lhs (stmt
);
2191 tree arg0
= gimple_call_arg (stmt
, 0);
2192 tree arg1
= gimple_call_arg (stmt
, 1);
2193 if (VECTOR_TYPE_P (TREE_TYPE (arg0
)))
2194 expand_vector_ubsan_overflow (loc
, MINUS_EXPR
, lhs
, arg0
, arg1
);
2195 else if (integer_zerop (arg0
))
2196 expand_neg_overflow (loc
, lhs
, arg1
, true, NULL
);
2198 expand_addsub_overflow (loc
, MINUS_EXPR
, lhs
, arg0
, arg1
,
2199 false, false, false, true, NULL
);
2202 /* Expand UBSAN_CHECK_MUL call STMT. */
2205 expand_UBSAN_CHECK_MUL (internal_fn
, gcall
*stmt
)
2207 location_t loc
= gimple_location (stmt
);
2208 tree lhs
= gimple_call_lhs (stmt
);
2209 tree arg0
= gimple_call_arg (stmt
, 0);
2210 tree arg1
= gimple_call_arg (stmt
, 1);
2211 if (VECTOR_TYPE_P (TREE_TYPE (arg0
)))
2212 expand_vector_ubsan_overflow (loc
, MULT_EXPR
, lhs
, arg0
, arg1
);
2214 expand_mul_overflow (loc
, lhs
, arg0
, arg1
, false, false, false, true,
2218 /* Helper function for {ADD,SUB,MUL}_OVERFLOW call stmt expansion. */
2221 expand_arith_overflow (enum tree_code code
, gimple
*stmt
)
2223 tree lhs
= gimple_call_lhs (stmt
);
2224 if (lhs
== NULL_TREE
)
2226 tree arg0
= gimple_call_arg (stmt
, 0);
2227 tree arg1
= gimple_call_arg (stmt
, 1);
2228 tree type
= TREE_TYPE (TREE_TYPE (lhs
));
2229 int uns0_p
= TYPE_UNSIGNED (TREE_TYPE (arg0
));
2230 int uns1_p
= TYPE_UNSIGNED (TREE_TYPE (arg1
));
2231 int unsr_p
= TYPE_UNSIGNED (type
);
2232 int prec0
= TYPE_PRECISION (TREE_TYPE (arg0
));
2233 int prec1
= TYPE_PRECISION (TREE_TYPE (arg1
));
2234 int precres
= TYPE_PRECISION (type
);
2235 location_t loc
= gimple_location (stmt
);
2236 if (!uns0_p
&& get_range_pos_neg (arg0
) == 1)
2238 if (!uns1_p
&& get_range_pos_neg (arg1
) == 1)
2240 int pr
= get_min_precision (arg0
, uns0_p
? UNSIGNED
: SIGNED
);
2241 prec0
= MIN (prec0
, pr
);
2242 pr
= get_min_precision (arg1
, uns1_p
? UNSIGNED
: SIGNED
);
2243 prec1
= MIN (prec1
, pr
);
2245 /* If uns0_p && uns1_p, precop is minimum needed precision
2246 of unsigned type to hold the exact result, otherwise
2247 precop is minimum needed precision of signed type to
2248 hold the exact result. */
2250 if (code
== MULT_EXPR
)
2251 precop
= prec0
+ prec1
+ (uns0_p
!= uns1_p
);
2254 if (uns0_p
== uns1_p
)
2255 precop
= MAX (prec0
, prec1
) + 1;
2257 precop
= MAX (prec0
+ 1, prec1
) + 1;
2259 precop
= MAX (prec0
, prec1
+ 1) + 1;
2261 int orig_precres
= precres
;
2265 if ((uns0_p
&& uns1_p
)
2266 ? ((precop
+ !unsr_p
) <= precres
2267 /* u1 - u2 -> ur can overflow, no matter what precision
2269 && (code
!= MINUS_EXPR
|| !unsr_p
))
2270 : (!unsr_p
&& precop
<= precres
))
2272 /* The infinity precision result will always fit into result. */
2273 rtx target
= expand_expr (lhs
, NULL_RTX
, VOIDmode
, EXPAND_WRITE
);
2274 write_complex_part (target
, const0_rtx
, true);
2275 scalar_int_mode mode
= SCALAR_INT_TYPE_MODE (type
);
2276 struct separate_ops ops
;
2279 ops
.op0
= fold_convert_loc (loc
, type
, arg0
);
2280 ops
.op1
= fold_convert_loc (loc
, type
, arg1
);
2281 ops
.op2
= NULL_TREE
;
2283 rtx tem
= expand_expr_real_2 (&ops
, NULL_RTX
, mode
, EXPAND_NORMAL
);
2284 expand_arith_overflow_result_store (lhs
, target
, mode
, tem
);
2288 /* For operations with low precision, if target doesn't have them, start
2289 with precres widening right away, otherwise do it only if the most
2290 simple cases can't be used. */
2291 const int min_precision
= targetm
.min_arithmetic_precision ();
2292 if (orig_precres
== precres
&& precres
< min_precision
)
2294 else if ((uns0_p
&& uns1_p
&& unsr_p
&& prec0
<= precres
2295 && prec1
<= precres
)
2296 || ((!uns0_p
|| !uns1_p
) && !unsr_p
2297 && prec0
+ uns0_p
<= precres
2298 && prec1
+ uns1_p
<= precres
))
2300 arg0
= fold_convert_loc (loc
, type
, arg0
);
2301 arg1
= fold_convert_loc (loc
, type
, arg1
);
2305 if (integer_zerop (arg0
) && !unsr_p
)
2307 expand_neg_overflow (loc
, lhs
, arg1
, false, NULL
);
2312 expand_addsub_overflow (loc
, code
, lhs
, arg0
, arg1
, unsr_p
,
2313 unsr_p
, unsr_p
, false, NULL
);
2316 expand_mul_overflow (loc
, lhs
, arg0
, arg1
, unsr_p
,
2317 unsr_p
, unsr_p
, false, NULL
);
2324 /* For sub-word operations, retry with a wider type first. */
2325 if (orig_precres
== precres
&& precop
<= BITS_PER_WORD
)
2327 int p
= MAX (min_precision
, precop
);
2328 scalar_int_mode m
= smallest_int_mode_for_size (p
);
2329 tree optype
= build_nonstandard_integer_type (GET_MODE_PRECISION (m
),
2332 p
= TYPE_PRECISION (optype
);
2336 unsr_p
= TYPE_UNSIGNED (optype
);
2342 if (prec0
<= precres
&& prec1
<= precres
)
2347 types
[0] = build_nonstandard_integer_type (precres
, 0);
2353 types
[1] = build_nonstandard_integer_type (precres
, 1);
2355 arg0
= fold_convert_loc (loc
, types
[uns0_p
], arg0
);
2356 arg1
= fold_convert_loc (loc
, types
[uns1_p
], arg1
);
2357 if (code
!= MULT_EXPR
)
2358 expand_addsub_overflow (loc
, code
, lhs
, arg0
, arg1
, unsr_p
,
2359 uns0_p
, uns1_p
, false, NULL
);
2361 expand_mul_overflow (loc
, lhs
, arg0
, arg1
, unsr_p
,
2362 uns0_p
, uns1_p
, false, NULL
);
2366 /* Retry with a wider type. */
2367 if (orig_precres
== precres
)
2369 int p
= MAX (prec0
, prec1
);
2370 scalar_int_mode m
= smallest_int_mode_for_size (p
);
2371 tree optype
= build_nonstandard_integer_type (GET_MODE_PRECISION (m
),
2374 p
= TYPE_PRECISION (optype
);
2378 unsr_p
= TYPE_UNSIGNED (optype
);
2389 /* Expand ADD_OVERFLOW STMT. */
2392 expand_ADD_OVERFLOW (internal_fn
, gcall
*stmt
)
2394 expand_arith_overflow (PLUS_EXPR
, stmt
);
2397 /* Expand SUB_OVERFLOW STMT. */
2400 expand_SUB_OVERFLOW (internal_fn
, gcall
*stmt
)
2402 expand_arith_overflow (MINUS_EXPR
, stmt
);
2405 /* Expand MUL_OVERFLOW STMT. */
2408 expand_MUL_OVERFLOW (internal_fn
, gcall
*stmt
)
2410 expand_arith_overflow (MULT_EXPR
, stmt
);
2413 /* This should get folded in tree-vectorizer.c. */
2416 expand_LOOP_VECTORIZED (internal_fn
, gcall
*)
2421 /* This should get folded in tree-vectorizer.c. */
2424 expand_LOOP_DIST_ALIAS (internal_fn
, gcall
*)
2429 /* Return a memory reference of type TYPE for argument INDEX of STMT.
2430 Use argument INDEX + 1 to derive the second (TBAA) operand. */
2433 expand_call_mem_ref (tree type
, gcall
*stmt
, int index
)
2435 tree addr
= gimple_call_arg (stmt
, index
);
2436 tree alias_ptr_type
= TREE_TYPE (gimple_call_arg (stmt
, index
+ 1));
2437 unsigned int align
= tree_to_shwi (gimple_call_arg (stmt
, index
+ 1));
2438 if (TYPE_ALIGN (type
) != align
)
2439 type
= build_aligned_type (type
, align
);
2442 if (TREE_CODE (tmp
) == SSA_NAME
)
2444 gimple
*def
= SSA_NAME_DEF_STMT (tmp
);
2445 if (gimple_assign_single_p (def
))
2446 tmp
= gimple_assign_rhs1 (def
);
2449 if (TREE_CODE (tmp
) == ADDR_EXPR
)
2451 tree mem
= TREE_OPERAND (tmp
, 0);
2452 if (TREE_CODE (mem
) == TARGET_MEM_REF
2453 && types_compatible_p (TREE_TYPE (mem
), type
))
2455 tree offset
= TMR_OFFSET (mem
);
2456 if (type
!= TREE_TYPE (mem
)
2457 || alias_ptr_type
!= TREE_TYPE (offset
)
2458 || !integer_zerop (offset
))
2460 mem
= copy_node (mem
);
2461 TMR_OFFSET (mem
) = wide_int_to_tree (alias_ptr_type
,
2462 wi::to_poly_wide (offset
));
2463 TREE_TYPE (mem
) = type
;
2469 return fold_build2 (MEM_REF
, type
, addr
, build_int_cst (alias_ptr_type
, 0));
2472 /* Expand MASK_LOAD{,_LANES} call STMT using optab OPTAB. */
2475 expand_mask_load_optab_fn (internal_fn
, gcall
*stmt
, convert_optab optab
)
2477 struct expand_operand ops
[3];
2478 tree type
, lhs
, rhs
, maskt
;
2479 rtx mem
, target
, mask
;
2482 maskt
= gimple_call_arg (stmt
, 2);
2483 lhs
= gimple_call_lhs (stmt
);
2484 if (lhs
== NULL_TREE
)
2486 type
= TREE_TYPE (lhs
);
2487 rhs
= expand_call_mem_ref (type
, stmt
, 0);
2489 if (optab
== vec_mask_load_lanes_optab
)
2490 icode
= get_multi_vector_move (type
, optab
);
2492 icode
= convert_optab_handler (optab
, TYPE_MODE (type
),
2493 TYPE_MODE (TREE_TYPE (maskt
)));
2495 mem
= expand_expr (rhs
, NULL_RTX
, VOIDmode
, EXPAND_WRITE
);
2496 gcc_assert (MEM_P (mem
));
2497 mask
= expand_normal (maskt
);
2498 target
= expand_expr (lhs
, NULL_RTX
, VOIDmode
, EXPAND_WRITE
);
2499 create_output_operand (&ops
[0], target
, TYPE_MODE (type
));
2500 create_fixed_operand (&ops
[1], mem
);
2501 create_input_operand (&ops
[2], mask
, TYPE_MODE (TREE_TYPE (maskt
)));
2502 expand_insn (icode
, 3, ops
);
2505 #define expand_mask_load_lanes_optab_fn expand_mask_load_optab_fn
2507 /* Expand MASK_STORE{,_LANES} call STMT using optab OPTAB. */
2510 expand_mask_store_optab_fn (internal_fn
, gcall
*stmt
, convert_optab optab
)
2512 struct expand_operand ops
[3];
2513 tree type
, lhs
, rhs
, maskt
;
2517 maskt
= gimple_call_arg (stmt
, 2);
2518 rhs
= gimple_call_arg (stmt
, 3);
2519 type
= TREE_TYPE (rhs
);
2520 lhs
= expand_call_mem_ref (type
, stmt
, 0);
2522 if (optab
== vec_mask_store_lanes_optab
)
2523 icode
= get_multi_vector_move (type
, optab
);
2525 icode
= convert_optab_handler (optab
, TYPE_MODE (type
),
2526 TYPE_MODE (TREE_TYPE (maskt
)));
2528 mem
= expand_expr (lhs
, NULL_RTX
, VOIDmode
, EXPAND_WRITE
);
2529 gcc_assert (MEM_P (mem
));
2530 mask
= expand_normal (maskt
);
2531 reg
= expand_normal (rhs
);
2532 create_fixed_operand (&ops
[0], mem
);
2533 create_input_operand (&ops
[1], reg
, TYPE_MODE (type
));
2534 create_input_operand (&ops
[2], mask
, TYPE_MODE (TREE_TYPE (maskt
)));
2535 expand_insn (icode
, 3, ops
);
2538 #define expand_mask_store_lanes_optab_fn expand_mask_store_optab_fn
2541 expand_ABNORMAL_DISPATCHER (internal_fn
, gcall
*)
2546 expand_BUILTIN_EXPECT (internal_fn
, gcall
*stmt
)
2548 /* When guessing was done, the hints should be already stripped away. */
2549 gcc_assert (!flag_guess_branch_prob
|| optimize
== 0 || seen_error ());
2552 tree lhs
= gimple_call_lhs (stmt
);
2554 target
= expand_expr (lhs
, NULL_RTX
, VOIDmode
, EXPAND_WRITE
);
2556 target
= const0_rtx
;
2557 rtx val
= expand_expr (gimple_call_arg (stmt
, 0), target
, VOIDmode
, EXPAND_NORMAL
);
2558 if (lhs
&& val
!= target
)
2559 emit_move_insn (target
, val
);
2562 /* IFN_VA_ARG is supposed to be expanded at pass_stdarg. So this dummy function
2563 should never be called. */
2566 expand_VA_ARG (internal_fn
, gcall
*)
2571 /* IFN_VEC_CONVERT is supposed to be expanded at pass_lower_vector. So this
2572 dummy function should never be called. */
2575 expand_VEC_CONVERT (internal_fn
, gcall
*)
2580 /* Expand the IFN_UNIQUE function according to its first argument. */
2583 expand_UNIQUE (internal_fn
, gcall
*stmt
)
2585 rtx pattern
= NULL_RTX
;
2586 enum ifn_unique_kind kind
2587 = (enum ifn_unique_kind
) TREE_INT_CST_LOW (gimple_call_arg (stmt
, 0));
2594 case IFN_UNIQUE_UNSPEC
:
2595 if (targetm
.have_unique ())
2596 pattern
= targetm
.gen_unique ();
2599 case IFN_UNIQUE_OACC_FORK
:
2600 case IFN_UNIQUE_OACC_JOIN
:
2601 if (targetm
.have_oacc_fork () && targetm
.have_oacc_join ())
2603 tree lhs
= gimple_call_lhs (stmt
);
2604 rtx target
= const0_rtx
;
2607 target
= expand_expr (lhs
, NULL_RTX
, VOIDmode
, EXPAND_WRITE
);
2609 rtx data_dep
= expand_normal (gimple_call_arg (stmt
, 1));
2610 rtx axis
= expand_normal (gimple_call_arg (stmt
, 2));
2612 if (kind
== IFN_UNIQUE_OACC_FORK
)
2613 pattern
= targetm
.gen_oacc_fork (target
, data_dep
, axis
);
2615 pattern
= targetm
.gen_oacc_join (target
, data_dep
, axis
);
2623 emit_insn (pattern
);
2626 /* The size of an OpenACC compute dimension. */
2629 expand_GOACC_DIM_SIZE (internal_fn
, gcall
*stmt
)
2631 tree lhs
= gimple_call_lhs (stmt
);
2636 rtx target
= expand_expr (lhs
, NULL_RTX
, VOIDmode
, EXPAND_WRITE
);
2637 if (targetm
.have_oacc_dim_size ())
2639 rtx dim
= expand_expr (gimple_call_arg (stmt
, 0), NULL_RTX
,
2640 VOIDmode
, EXPAND_NORMAL
);
2641 emit_insn (targetm
.gen_oacc_dim_size (target
, dim
));
2644 emit_move_insn (target
, GEN_INT (1));
2647 /* The position of an OpenACC execution engine along one compute axis. */
2650 expand_GOACC_DIM_POS (internal_fn
, gcall
*stmt
)
2652 tree lhs
= gimple_call_lhs (stmt
);
2657 rtx target
= expand_expr (lhs
, NULL_RTX
, VOIDmode
, EXPAND_WRITE
);
2658 if (targetm
.have_oacc_dim_pos ())
2660 rtx dim
= expand_expr (gimple_call_arg (stmt
, 0), NULL_RTX
,
2661 VOIDmode
, EXPAND_NORMAL
);
2662 emit_insn (targetm
.gen_oacc_dim_pos (target
, dim
));
2665 emit_move_insn (target
, const0_rtx
);
2668 /* This is expanded by oacc_device_lower pass. */
2671 expand_GOACC_LOOP (internal_fn
, gcall
*)
2676 /* This is expanded by oacc_device_lower pass. */
2679 expand_GOACC_REDUCTION (internal_fn
, gcall
*)
2684 /* This is expanded by oacc_device_lower pass. */
2687 expand_GOACC_TILE (internal_fn
, gcall
*)
2692 /* Set errno to EDOM. */
2695 expand_SET_EDOM (internal_fn
, gcall
*)
2698 #ifdef GEN_ERRNO_RTX
2699 rtx errno_rtx
= GEN_ERRNO_RTX
;
2701 rtx errno_rtx
= gen_rtx_MEM (word_mode
, gen_rtx_SYMBOL_REF (Pmode
, "errno"));
2703 emit_move_insn (errno_rtx
,
2704 gen_int_mode (TARGET_EDOM
, GET_MODE (errno_rtx
)));
2710 /* Expand atomic bit test and set. */
2713 expand_ATOMIC_BIT_TEST_AND_SET (internal_fn
, gcall
*call
)
2715 expand_ifn_atomic_bit_test_and (call
);
2718 /* Expand atomic bit test and complement. */
2721 expand_ATOMIC_BIT_TEST_AND_COMPLEMENT (internal_fn
, gcall
*call
)
2723 expand_ifn_atomic_bit_test_and (call
);
2726 /* Expand atomic bit test and reset. */
2729 expand_ATOMIC_BIT_TEST_AND_RESET (internal_fn
, gcall
*call
)
2731 expand_ifn_atomic_bit_test_and (call
);
2734 /* Expand atomic bit test and set. */
2737 expand_ATOMIC_COMPARE_EXCHANGE (internal_fn
, gcall
*call
)
2739 expand_ifn_atomic_compare_exchange (call
);
2742 /* Expand LAUNDER to assignment, lhs = arg0. */
2745 expand_LAUNDER (internal_fn
, gcall
*call
)
2747 tree lhs
= gimple_call_lhs (call
);
2752 expand_assignment (lhs
, gimple_call_arg (call
, 0), false);
2755 /* Expand {MASK_,}SCATTER_STORE{S,U} call CALL using optab OPTAB. */
2758 expand_scatter_store_optab_fn (internal_fn
, gcall
*stmt
, direct_optab optab
)
2760 internal_fn ifn
= gimple_call_internal_fn (stmt
);
2761 int rhs_index
= internal_fn_stored_value_index (ifn
);
2762 int mask_index
= internal_fn_mask_index (ifn
);
2763 tree base
= gimple_call_arg (stmt
, 0);
2764 tree offset
= gimple_call_arg (stmt
, 1);
2765 tree scale
= gimple_call_arg (stmt
, 2);
2766 tree rhs
= gimple_call_arg (stmt
, rhs_index
);
2768 rtx base_rtx
= expand_normal (base
);
2769 rtx offset_rtx
= expand_normal (offset
);
2770 HOST_WIDE_INT scale_int
= tree_to_shwi (scale
);
2771 rtx rhs_rtx
= expand_normal (rhs
);
2773 struct expand_operand ops
[6];
2775 create_address_operand (&ops
[i
++], base_rtx
);
2776 create_input_operand (&ops
[i
++], offset_rtx
, TYPE_MODE (TREE_TYPE (offset
)));
2777 create_integer_operand (&ops
[i
++], TYPE_UNSIGNED (TREE_TYPE (offset
)));
2778 create_integer_operand (&ops
[i
++], scale_int
);
2779 create_input_operand (&ops
[i
++], rhs_rtx
, TYPE_MODE (TREE_TYPE (rhs
)));
2780 if (mask_index
>= 0)
2782 tree mask
= gimple_call_arg (stmt
, mask_index
);
2783 rtx mask_rtx
= expand_normal (mask
);
2784 create_input_operand (&ops
[i
++], mask_rtx
, TYPE_MODE (TREE_TYPE (mask
)));
2787 insn_code icode
= direct_optab_handler (optab
, TYPE_MODE (TREE_TYPE (rhs
)));
2788 expand_insn (icode
, i
, ops
);
2791 /* Expand {MASK_,}GATHER_LOAD call CALL using optab OPTAB. */
2794 expand_gather_load_optab_fn (internal_fn
, gcall
*stmt
, direct_optab optab
)
2796 tree lhs
= gimple_call_lhs (stmt
);
2797 tree base
= gimple_call_arg (stmt
, 0);
2798 tree offset
= gimple_call_arg (stmt
, 1);
2799 tree scale
= gimple_call_arg (stmt
, 2);
2801 rtx lhs_rtx
= expand_expr (lhs
, NULL_RTX
, VOIDmode
, EXPAND_WRITE
);
2802 rtx base_rtx
= expand_normal (base
);
2803 rtx offset_rtx
= expand_normal (offset
);
2804 HOST_WIDE_INT scale_int
= tree_to_shwi (scale
);
2807 struct expand_operand ops
[6];
2808 create_output_operand (&ops
[i
++], lhs_rtx
, TYPE_MODE (TREE_TYPE (lhs
)));
2809 create_address_operand (&ops
[i
++], base_rtx
);
2810 create_input_operand (&ops
[i
++], offset_rtx
, TYPE_MODE (TREE_TYPE (offset
)));
2811 create_integer_operand (&ops
[i
++], TYPE_UNSIGNED (TREE_TYPE (offset
)));
2812 create_integer_operand (&ops
[i
++], scale_int
);
2813 if (optab
== mask_gather_load_optab
)
2815 tree mask
= gimple_call_arg (stmt
, 3);
2816 rtx mask_rtx
= expand_normal (mask
);
2817 create_input_operand (&ops
[i
++], mask_rtx
, TYPE_MODE (TREE_TYPE (mask
)));
2819 insn_code icode
= direct_optab_handler (optab
, TYPE_MODE (TREE_TYPE (lhs
)));
2820 expand_insn (icode
, i
, ops
);
2823 /* Expand DIVMOD() using:
2824 a) optab handler for udivmod/sdivmod if it is available.
2825 b) If optab_handler doesn't exist, generate call to
2826 target-specific divmod libfunc. */
2829 expand_DIVMOD (internal_fn
, gcall
*call_stmt
)
2831 tree lhs
= gimple_call_lhs (call_stmt
);
2832 tree arg0
= gimple_call_arg (call_stmt
, 0);
2833 tree arg1
= gimple_call_arg (call_stmt
, 1);
2835 gcc_assert (TREE_CODE (TREE_TYPE (lhs
)) == COMPLEX_TYPE
);
2836 tree type
= TREE_TYPE (TREE_TYPE (lhs
));
2837 machine_mode mode
= TYPE_MODE (type
);
2838 bool unsignedp
= TYPE_UNSIGNED (type
);
2839 optab tab
= (unsignedp
) ? udivmod_optab
: sdivmod_optab
;
2841 rtx op0
= expand_normal (arg0
);
2842 rtx op1
= expand_normal (arg1
);
2843 rtx target
= expand_expr (lhs
, NULL_RTX
, VOIDmode
, EXPAND_WRITE
);
2845 rtx quotient
, remainder
, libfunc
;
2847 /* Check if optab_handler exists for divmod_optab for given mode. */
2848 if (optab_handler (tab
, mode
) != CODE_FOR_nothing
)
2850 quotient
= gen_reg_rtx (mode
);
2851 remainder
= gen_reg_rtx (mode
);
2852 expand_twoval_binop (tab
, op0
, op1
, quotient
, remainder
, unsignedp
);
2855 /* Generate call to divmod libfunc if it exists. */
2856 else if ((libfunc
= optab_libfunc (tab
, mode
)) != NULL_RTX
)
2857 targetm
.expand_divmod_libfunc (libfunc
, mode
, op0
, op1
,
2858 "ient
, &remainder
);
2863 /* Wrap the return value (quotient, remainder) within COMPLEX_EXPR. */
2864 expand_expr (build2 (COMPLEX_EXPR
, TREE_TYPE (lhs
),
2865 make_tree (TREE_TYPE (arg0
), quotient
),
2866 make_tree (TREE_TYPE (arg1
), remainder
)),
2867 target
, VOIDmode
, EXPAND_NORMAL
);
2873 expand_NOP (internal_fn
, gcall
*)
2875 /* Nothing. But it shouldn't really prevail. */
2878 /* Expand a call to FN using the operands in STMT. FN has a single
2879 output operand and NARGS input operands. */
2882 expand_direct_optab_fn (internal_fn fn
, gcall
*stmt
, direct_optab optab
,
2885 expand_operand
*ops
= XALLOCAVEC (expand_operand
, nargs
+ 1);
2887 tree_pair types
= direct_internal_fn_types (fn
, stmt
);
2888 insn_code icode
= direct_optab_handler (optab
, TYPE_MODE (types
.first
));
2889 gcc_assert (icode
!= CODE_FOR_nothing
);
2891 tree lhs
= gimple_call_lhs (stmt
);
2892 rtx lhs_rtx
= NULL_RTX
;
2894 lhs_rtx
= expand_expr (lhs
, NULL_RTX
, VOIDmode
, EXPAND_WRITE
);
2896 /* Do not assign directly to a promoted subreg, since there is no
2897 guarantee that the instruction will leave the upper bits of the
2898 register in the state required by SUBREG_PROMOTED_SIGN. */
2900 if (dest
&& GET_CODE (dest
) == SUBREG
&& SUBREG_PROMOTED_VAR_P (dest
))
2903 create_output_operand (&ops
[0], dest
, insn_data
[icode
].operand
[0].mode
);
2905 for (unsigned int i
= 0; i
< nargs
; ++i
)
2907 tree rhs
= gimple_call_arg (stmt
, i
);
2908 tree rhs_type
= TREE_TYPE (rhs
);
2909 rtx rhs_rtx
= expand_normal (rhs
);
2910 if (INTEGRAL_TYPE_P (rhs_type
))
2911 create_convert_operand_from (&ops
[i
+ 1], rhs_rtx
,
2912 TYPE_MODE (rhs_type
),
2913 TYPE_UNSIGNED (rhs_type
));
2915 create_input_operand (&ops
[i
+ 1], rhs_rtx
, TYPE_MODE (rhs_type
));
2918 expand_insn (icode
, nargs
+ 1, ops
);
2919 if (lhs_rtx
&& !rtx_equal_p (lhs_rtx
, ops
[0].value
))
2921 /* If the return value has an integral type, convert the instruction
2922 result to that type. This is useful for things that return an
2923 int regardless of the size of the input. If the instruction result
2924 is smaller than required, assume that it is signed.
2926 If the return value has a nonintegral type, its mode must match
2927 the instruction result. */
2928 if (GET_CODE (lhs_rtx
) == SUBREG
&& SUBREG_PROMOTED_VAR_P (lhs_rtx
))
2930 /* If this is a scalar in a register that is stored in a wider
2931 mode than the declared mode, compute the result into its
2932 declared mode and then convert to the wider mode. */
2933 gcc_checking_assert (INTEGRAL_TYPE_P (TREE_TYPE (lhs
)));
2934 rtx tmp
= convert_to_mode (GET_MODE (lhs_rtx
), ops
[0].value
, 0);
2935 convert_move (SUBREG_REG (lhs_rtx
), tmp
,
2936 SUBREG_PROMOTED_SIGN (lhs_rtx
));
2938 else if (GET_MODE (lhs_rtx
) == GET_MODE (ops
[0].value
))
2939 emit_move_insn (lhs_rtx
, ops
[0].value
);
2942 gcc_checking_assert (INTEGRAL_TYPE_P (TREE_TYPE (lhs
)));
2943 convert_move (lhs_rtx
, ops
[0].value
, 0);
2948 /* Expand WHILE_ULT call STMT using optab OPTAB. */
2951 expand_while_optab_fn (internal_fn
, gcall
*stmt
, convert_optab optab
)
2953 expand_operand ops
[3];
2956 tree lhs
= gimple_call_lhs (stmt
);
2957 tree lhs_type
= TREE_TYPE (lhs
);
2958 rtx lhs_rtx
= expand_expr (lhs
, NULL_RTX
, VOIDmode
, EXPAND_WRITE
);
2959 create_output_operand (&ops
[0], lhs_rtx
, TYPE_MODE (lhs_type
));
2961 for (unsigned int i
= 0; i
< 2; ++i
)
2963 tree rhs
= gimple_call_arg (stmt
, i
);
2964 rhs_type
[i
] = TREE_TYPE (rhs
);
2965 rtx rhs_rtx
= expand_normal (rhs
);
2966 create_input_operand (&ops
[i
+ 1], rhs_rtx
, TYPE_MODE (rhs_type
[i
]));
2969 insn_code icode
= convert_optab_handler (optab
, TYPE_MODE (rhs_type
[0]),
2970 TYPE_MODE (lhs_type
));
2972 expand_insn (icode
, 3, ops
);
2973 if (!rtx_equal_p (lhs_rtx
, ops
[0].value
))
2974 emit_move_insn (lhs_rtx
, ops
[0].value
);
2977 /* Expanders for optabs that can use expand_direct_optab_fn. */
2979 #define expand_unary_optab_fn(FN, STMT, OPTAB) \
2980 expand_direct_optab_fn (FN, STMT, OPTAB, 1)
2982 #define expand_binary_optab_fn(FN, STMT, OPTAB) \
2983 expand_direct_optab_fn (FN, STMT, OPTAB, 2)
2985 #define expand_ternary_optab_fn(FN, STMT, OPTAB) \
2986 expand_direct_optab_fn (FN, STMT, OPTAB, 3)
2988 #define expand_cond_unary_optab_fn(FN, STMT, OPTAB) \
2989 expand_direct_optab_fn (FN, STMT, OPTAB, 3)
2991 #define expand_cond_binary_optab_fn(FN, STMT, OPTAB) \
2992 expand_direct_optab_fn (FN, STMT, OPTAB, 4)
2994 #define expand_cond_ternary_optab_fn(FN, STMT, OPTAB) \
2995 expand_direct_optab_fn (FN, STMT, OPTAB, 5)
2997 #define expand_fold_extract_optab_fn(FN, STMT, OPTAB) \
2998 expand_direct_optab_fn (FN, STMT, OPTAB, 3)
3000 #define expand_fold_left_optab_fn(FN, STMT, OPTAB) \
3001 expand_direct_optab_fn (FN, STMT, OPTAB, 2)
3003 /* RETURN_TYPE and ARGS are a return type and argument list that are
3004 in principle compatible with FN (which satisfies direct_internal_fn_p).
3005 Return the types that should be used to determine whether the
3006 target supports FN. */
3009 direct_internal_fn_types (internal_fn fn
, tree return_type
, tree
*args
)
3011 const direct_internal_fn_info
&info
= direct_internal_fn (fn
);
3012 tree type0
= (info
.type0
< 0 ? return_type
: TREE_TYPE (args
[info
.type0
]));
3013 tree type1
= (info
.type1
< 0 ? return_type
: TREE_TYPE (args
[info
.type1
]));
3014 return tree_pair (type0
, type1
);
3017 /* CALL is a call whose return type and arguments are in principle
3018 compatible with FN (which satisfies direct_internal_fn_p). Return the
3019 types that should be used to determine whether the target supports FN. */
3022 direct_internal_fn_types (internal_fn fn
, gcall
*call
)
3024 const direct_internal_fn_info
&info
= direct_internal_fn (fn
);
3025 tree op0
= (info
.type0
< 0
3026 ? gimple_call_lhs (call
)
3027 : gimple_call_arg (call
, info
.type0
));
3028 tree op1
= (info
.type1
< 0
3029 ? gimple_call_lhs (call
)
3030 : gimple_call_arg (call
, info
.type1
));
3031 return tree_pair (TREE_TYPE (op0
), TREE_TYPE (op1
));
3034 /* Return true if OPTAB is supported for TYPES (whose modes should be
3035 the same) when the optimization type is OPT_TYPE. Used for simple
3039 direct_optab_supported_p (direct_optab optab
, tree_pair types
,
3040 optimization_type opt_type
)
3042 machine_mode mode
= TYPE_MODE (types
.first
);
3043 gcc_checking_assert (mode
== TYPE_MODE (types
.second
));
3044 return direct_optab_handler (optab
, mode
, opt_type
) != CODE_FOR_nothing
;
3047 /* Return true if OPTAB is supported for TYPES, where the first type
3048 is the destination and the second type is the source. Used for
3052 convert_optab_supported_p (convert_optab optab
, tree_pair types
,
3053 optimization_type opt_type
)
3055 return (convert_optab_handler (optab
, TYPE_MODE (types
.first
),
3056 TYPE_MODE (types
.second
), opt_type
)
3057 != CODE_FOR_nothing
);
3060 /* Return true if load/store lanes optab OPTAB is supported for
3061 array type TYPES.first when the optimization type is OPT_TYPE. */
3064 multi_vector_optab_supported_p (convert_optab optab
, tree_pair types
,
3065 optimization_type opt_type
)
3067 gcc_assert (TREE_CODE (types
.first
) == ARRAY_TYPE
);
3068 machine_mode imode
= TYPE_MODE (types
.first
);
3069 machine_mode vmode
= TYPE_MODE (TREE_TYPE (types
.first
));
3070 return (convert_optab_handler (optab
, imode
, vmode
, opt_type
)
3071 != CODE_FOR_nothing
);
3074 #define direct_unary_optab_supported_p direct_optab_supported_p
3075 #define direct_binary_optab_supported_p direct_optab_supported_p
3076 #define direct_ternary_optab_supported_p direct_optab_supported_p
3077 #define direct_cond_unary_optab_supported_p direct_optab_supported_p
3078 #define direct_cond_binary_optab_supported_p direct_optab_supported_p
3079 #define direct_cond_ternary_optab_supported_p direct_optab_supported_p
3080 #define direct_mask_load_optab_supported_p direct_optab_supported_p
3081 #define direct_load_lanes_optab_supported_p multi_vector_optab_supported_p
3082 #define direct_mask_load_lanes_optab_supported_p multi_vector_optab_supported_p
3083 #define direct_gather_load_optab_supported_p direct_optab_supported_p
3084 #define direct_mask_store_optab_supported_p direct_optab_supported_p
3085 #define direct_store_lanes_optab_supported_p multi_vector_optab_supported_p
3086 #define direct_mask_store_lanes_optab_supported_p multi_vector_optab_supported_p
3087 #define direct_scatter_store_optab_supported_p direct_optab_supported_p
3088 #define direct_while_optab_supported_p convert_optab_supported_p
3089 #define direct_fold_extract_optab_supported_p direct_optab_supported_p
3090 #define direct_fold_left_optab_supported_p direct_optab_supported_p
3092 /* Return the optab used by internal function FN. */
3095 direct_internal_fn_optab (internal_fn fn
, tree_pair types
)
3099 #define DEF_INTERNAL_FN(CODE, FLAGS, FNSPEC) \
3100 case IFN_##CODE: break;
3101 #define DEF_INTERNAL_OPTAB_FN(CODE, FLAGS, OPTAB, TYPE) \
3102 case IFN_##CODE: return OPTAB##_optab;
3103 #define DEF_INTERNAL_SIGNED_OPTAB_FN(CODE, FLAGS, SELECTOR, SIGNED_OPTAB, \
3104 UNSIGNED_OPTAB, TYPE) \
3105 case IFN_##CODE: return (TYPE_UNSIGNED (types.SELECTOR) \
3106 ? UNSIGNED_OPTAB ## _optab \
3107 : SIGNED_OPTAB ## _optab);
3108 #include "internal-fn.def"
3116 /* Return the optab used by internal function FN. */
3119 direct_internal_fn_optab (internal_fn fn
)
3123 #define DEF_INTERNAL_FN(CODE, FLAGS, FNSPEC) \
3124 case IFN_##CODE: break;
3125 #define DEF_INTERNAL_OPTAB_FN(CODE, FLAGS, OPTAB, TYPE) \
3126 case IFN_##CODE: return OPTAB##_optab;
3127 #include "internal-fn.def"
3135 /* Return true if FN is supported for the types in TYPES when the
3136 optimization type is OPT_TYPE. The types are those associated with
3137 the "type0" and "type1" fields of FN's direct_internal_fn_info
3141 direct_internal_fn_supported_p (internal_fn fn
, tree_pair types
,
3142 optimization_type opt_type
)
3146 #define DEF_INTERNAL_FN(CODE, FLAGS, FNSPEC) \
3147 case IFN_##CODE: break;
3148 #define DEF_INTERNAL_OPTAB_FN(CODE, FLAGS, OPTAB, TYPE) \
3150 return direct_##TYPE##_optab_supported_p (OPTAB##_optab, types, \
3152 #define DEF_INTERNAL_SIGNED_OPTAB_FN(CODE, FLAGS, SELECTOR, SIGNED_OPTAB, \
3153 UNSIGNED_OPTAB, TYPE) \
3156 optab which_optab = (TYPE_UNSIGNED (types.SELECTOR) \
3157 ? UNSIGNED_OPTAB ## _optab \
3158 : SIGNED_OPTAB ## _optab); \
3159 return direct_##TYPE##_optab_supported_p (which_optab, types, \
3162 #include "internal-fn.def"
3170 /* Return true if FN is supported for type TYPE when the optimization
3171 type is OPT_TYPE. The caller knows that the "type0" and "type1"
3172 fields of FN's direct_internal_fn_info structure are the same. */
3175 direct_internal_fn_supported_p (internal_fn fn
, tree type
,
3176 optimization_type opt_type
)
3178 const direct_internal_fn_info
&info
= direct_internal_fn (fn
);
3179 gcc_checking_assert (info
.type0
== info
.type1
);
3180 return direct_internal_fn_supported_p (fn
, tree_pair (type
, type
), opt_type
);
3183 /* Return true if the STMT is supported when the optimization type is OPT_TYPE,
3184 given that STMT is a call to a direct internal function. */
3187 direct_internal_fn_supported_p (gcall
*stmt
, optimization_type opt_type
)
3189 internal_fn fn
= gimple_call_internal_fn (stmt
);
3190 tree_pair types
= direct_internal_fn_types (fn
, stmt
);
3191 return direct_internal_fn_supported_p (fn
, types
, opt_type
);
3194 /* If FN is commutative in two consecutive arguments, return the
3195 index of the first, otherwise return -1. */
3198 first_commutative_argument (internal_fn fn
)
3230 /* Return true if IFN_SET_EDOM is supported. */
3233 set_edom_supported_p (void)
3242 #define DEF_INTERNAL_OPTAB_FN(CODE, FLAGS, OPTAB, TYPE) \
3244 expand_##CODE (internal_fn fn, gcall *stmt) \
3246 expand_##TYPE##_optab_fn (fn, stmt, OPTAB##_optab); \
3248 #define DEF_INTERNAL_SIGNED_OPTAB_FN(CODE, FLAGS, SELECTOR, SIGNED_OPTAB, \
3249 UNSIGNED_OPTAB, TYPE) \
3251 expand_##CODE (internal_fn fn, gcall *stmt) \
3253 tree_pair types = direct_internal_fn_types (fn, stmt); \
3254 optab which_optab = direct_internal_fn_optab (fn, types); \
3255 expand_##TYPE##_optab_fn (fn, stmt, which_optab); \
3257 #include "internal-fn.def"
3259 /* Routines to expand each internal function, indexed by function number.
3260 Each routine has the prototype:
3262 expand_<NAME> (gcall *stmt)
3264 where STMT is the statement that performs the call. */
3265 static void (*const internal_fn_expanders
[]) (internal_fn
, gcall
*) = {
3266 #define DEF_INTERNAL_FN(CODE, FLAGS, FNSPEC) expand_##CODE,
3267 #include "internal-fn.def"
3271 /* Invoke T(CODE, IFN) for each conditional function IFN that maps to a
3273 #define FOR_EACH_CODE_MAPPING(T) \
3274 T (PLUS_EXPR, IFN_COND_ADD) \
3275 T (MINUS_EXPR, IFN_COND_SUB) \
3276 T (MULT_EXPR, IFN_COND_MUL) \
3277 T (TRUNC_DIV_EXPR, IFN_COND_DIV) \
3278 T (TRUNC_MOD_EXPR, IFN_COND_MOD) \
3279 T (RDIV_EXPR, IFN_COND_RDIV) \
3280 T (MIN_EXPR, IFN_COND_MIN) \
3281 T (MAX_EXPR, IFN_COND_MAX) \
3282 T (BIT_AND_EXPR, IFN_COND_AND) \
3283 T (BIT_IOR_EXPR, IFN_COND_IOR) \
3284 T (BIT_XOR_EXPR, IFN_COND_XOR)
3286 /* Return a function that only performs CODE when a certain condition is met
3287 and that uses a given fallback value otherwise. For example, if CODE is
3288 a binary operation associated with conditional function FN:
3290 LHS = FN (COND, A, B, ELSE)
3292 is equivalent to the C expression:
3294 LHS = COND ? A CODE B : ELSE;
3296 operating elementwise if the operands are vectors.
3298 Return IFN_LAST if no such function exists. */
3301 get_conditional_internal_fn (tree_code code
)
3305 #define CASE(CODE, IFN) case CODE: return IFN;
3306 FOR_EACH_CODE_MAPPING(CASE
)
3313 /* If IFN implements the conditional form of a tree code, return that
3314 tree code, otherwise return ERROR_MARK. */
3317 conditional_internal_fn_code (internal_fn ifn
)
3321 #define CASE(CODE, IFN) case IFN: return CODE;
3322 FOR_EACH_CODE_MAPPING(CASE
)
3329 /* Invoke T(IFN) for each internal function IFN that also has an
3331 #define FOR_EACH_COND_FN_PAIR(T) \
3337 /* Return a function that only performs internal function FN when a
3338 certain condition is met and that uses a given fallback value otherwise.
3339 In other words, the returned function FN' is such that:
3341 LHS = FN' (COND, A1, ... An, ELSE)
3343 is equivalent to the C expression:
3345 LHS = COND ? FN (A1, ..., An) : ELSE;
3347 operating elementwise if the operands are vectors.
3349 Return IFN_LAST if no such function exists. */
3352 get_conditional_internal_fn (internal_fn fn
)
3356 #define CASE(NAME) case IFN_##NAME: return IFN_COND_##NAME;
3357 FOR_EACH_COND_FN_PAIR(CASE
)
3364 /* If IFN implements the conditional form of an unconditional internal
3365 function, return that unconditional function, otherwise return IFN_LAST. */
3368 get_unconditional_internal_fn (internal_fn ifn
)
3372 #define CASE(NAME) case IFN_COND_##NAME: return IFN_##NAME;
3373 FOR_EACH_COND_FN_PAIR(CASE
)
3380 /* Return true if STMT can be interpreted as a conditional tree code
3381 operation of the form:
3383 LHS = COND ? OP (RHS1, ...) : ELSE;
3385 operating elementwise if the operands are vectors. This includes
3386 the case of an all-true COND, so that the operation always happens.
3388 When returning true, set:
3390 - *COND_OUT to the condition COND, or to NULL_TREE if the condition
3391 is known to be all-true
3392 - *CODE_OUT to the tree code
3393 - OPS[I] to operand I of *CODE_OUT
3394 - *ELSE_OUT to the fallback value ELSE, or to NULL_TREE if the
3395 condition is known to be all true. */
3398 can_interpret_as_conditional_op_p (gimple
*stmt
, tree
*cond_out
,
3399 tree_code
*code_out
,
3400 tree (&ops
)[3], tree
*else_out
)
3402 if (gassign
*assign
= dyn_cast
<gassign
*> (stmt
))
3404 *cond_out
= NULL_TREE
;
3405 *code_out
= gimple_assign_rhs_code (assign
);
3406 ops
[0] = gimple_assign_rhs1 (assign
);
3407 ops
[1] = gimple_assign_rhs2 (assign
);
3408 ops
[2] = gimple_assign_rhs3 (assign
);
3409 *else_out
= NULL_TREE
;
3412 if (gcall
*call
= dyn_cast
<gcall
*> (stmt
))
3413 if (gimple_call_internal_p (call
))
3415 internal_fn ifn
= gimple_call_internal_fn (call
);
3416 tree_code code
= conditional_internal_fn_code (ifn
);
3417 if (code
!= ERROR_MARK
)
3419 *cond_out
= gimple_call_arg (call
, 0);
3421 unsigned int nops
= gimple_call_num_args (call
) - 2;
3422 for (unsigned int i
= 0; i
< 3; ++i
)
3423 ops
[i
] = i
< nops
? gimple_call_arg (call
, i
+ 1) : NULL_TREE
;
3424 *else_out
= gimple_call_arg (call
, nops
+ 1);
3425 if (integer_truep (*cond_out
))
3427 *cond_out
= NULL_TREE
;
3428 *else_out
= NULL_TREE
;
3436 /* Return true if IFN is some form of load from memory. */
3439 internal_load_fn_p (internal_fn fn
)
3444 case IFN_LOAD_LANES
:
3445 case IFN_MASK_LOAD_LANES
:
3446 case IFN_GATHER_LOAD
:
3447 case IFN_MASK_GATHER_LOAD
:
3455 /* Return true if IFN is some form of store to memory. */
3458 internal_store_fn_p (internal_fn fn
)
3462 case IFN_MASK_STORE
:
3463 case IFN_STORE_LANES
:
3464 case IFN_MASK_STORE_LANES
:
3465 case IFN_SCATTER_STORE
:
3466 case IFN_MASK_SCATTER_STORE
:
3474 /* Return true if IFN is some form of gather load or scatter store. */
3477 internal_gather_scatter_fn_p (internal_fn fn
)
3481 case IFN_GATHER_LOAD
:
3482 case IFN_MASK_GATHER_LOAD
:
3483 case IFN_SCATTER_STORE
:
3484 case IFN_MASK_SCATTER_STORE
:
3492 /* If FN takes a vector mask argument, return the index of that argument,
3493 otherwise return -1. */
3496 internal_fn_mask_index (internal_fn fn
)
3501 case IFN_MASK_LOAD_LANES
:
3502 case IFN_MASK_STORE
:
3503 case IFN_MASK_STORE_LANES
:
3506 case IFN_MASK_GATHER_LOAD
:
3509 case IFN_MASK_SCATTER_STORE
:
3513 return (conditional_internal_fn_code (fn
) != ERROR_MARK
3514 || get_unconditional_internal_fn (fn
) != IFN_LAST
? 0 : -1);
3518 /* If FN takes a value that should be stored to memory, return the index
3519 of that argument, otherwise return -1. */
3522 internal_fn_stored_value_index (internal_fn fn
)
3526 case IFN_MASK_STORE
:
3527 case IFN_SCATTER_STORE
:
3528 case IFN_MASK_SCATTER_STORE
:
3536 /* Return true if the target supports gather load or scatter store function
3537 IFN. For loads, VECTOR_TYPE is the vector type of the load result,
3538 while for stores it is the vector type of the stored data argument.
3539 MEMORY_ELEMENT_TYPE is the type of the memory elements being loaded
3540 or stored. OFFSET_SIGN is the sign of the offset argument, which is
3541 only relevant when the offset is narrower than an address. SCALE is
3542 the amount by which the offset should be multiplied *after* it has
3543 been extended to address width. */
3546 internal_gather_scatter_fn_supported_p (internal_fn ifn
, tree vector_type
,
3547 tree memory_element_type
,
3548 signop offset_sign
, int scale
)
3550 if (!tree_int_cst_equal (TYPE_SIZE (TREE_TYPE (vector_type
)),
3551 TYPE_SIZE (memory_element_type
)))
3553 optab optab
= direct_internal_fn_optab (ifn
);
3554 insn_code icode
= direct_optab_handler (optab
, TYPE_MODE (vector_type
));
3555 int output_ops
= internal_load_fn_p (ifn
) ? 1 : 0;
3556 return (icode
!= CODE_FOR_nothing
3557 && insn_operand_matches (icode
, 2 + output_ops
,
3558 GEN_INT (offset_sign
== UNSIGNED
))
3559 && insn_operand_matches (icode
, 3 + output_ops
,
3563 /* Expand STMT as though it were a call to internal function FN. */
3566 expand_internal_call (internal_fn fn
, gcall
*stmt
)
3568 internal_fn_expanders
[fn
] (fn
, stmt
);
3571 /* Expand STMT, which is a call to internal function FN. */
3574 expand_internal_call (gcall
*stmt
)
3576 expand_internal_call (gimple_call_internal_fn (stmt
), stmt
);
3579 /* If TYPE is a vector type, return true if IFN is a direct internal
3580 function that is supported for that type. If TYPE is a scalar type,
3581 return true if IFN is a direct internal function that is supported for
3582 the target's preferred vector version of TYPE. */
3585 vectorized_internal_fn_supported_p (internal_fn ifn
, tree type
)
3588 if (!VECTOR_TYPE_P (type
) && is_a
<scalar_mode
> (TYPE_MODE (type
), &smode
))
3590 machine_mode vmode
= targetm
.vectorize
.preferred_simd_mode (smode
);
3591 if (VECTOR_MODE_P (vmode
))
3592 type
= build_vector_type_for_mode (type
, vmode
);
3595 return (VECTOR_MODE_P (TYPE_MODE (type
))
3596 && direct_internal_fn_supported_p (ifn
, type
, OPTIMIZE_FOR_SPEED
));
3600 expand_PHI (internal_fn
, gcall
*)