* lto-streamer-out.c (tree_is_indexable): Make LABEL_DECL nonindexable
[official-gcc.git] / gcc / internal-fn.c
bloba7bb748b66e1e63c4d99081931d47cb6c18d3390
1 /* Internal functions.
2 Copyright (C) 2011-2018 Free Software Foundation, Inc.
4 This file is part of GCC.
6 GCC is free software; you can redistribute it and/or modify it under
7 the terms of the GNU General Public License as published by the Free
8 Software Foundation; either version 3, or (at your option) any later
9 version.
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
14 for more details.
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/>. */
20 #include "config.h"
21 #include "system.h"
22 #include "coretypes.h"
23 #include "backend.h"
24 #include "target.h"
25 #include "rtl.h"
26 #include "tree.h"
27 #include "gimple.h"
28 #include "predict.h"
29 #include "stringpool.h"
30 #include "tree-vrp.h"
31 #include "tree-ssanames.h"
32 #include "expmed.h"
33 #include "memmodel.h"
34 #include "optabs.h"
35 #include "emit-rtl.h"
36 #include "diagnostic-core.h"
37 #include "fold-const.h"
38 #include "internal-fn.h"
39 #include "stor-layout.h"
40 #include "dojump.h"
41 #include "expr.h"
42 #include "stringpool.h"
43 #include "attribs.h"
44 #include "asan.h"
45 #include "ubsan.h"
46 #include "recog.h"
47 #include "builtins.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"
57 "<invalid-fn>"
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
68 no such function. */
70 internal_fn
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;
76 if (!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)),
81 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];
90 void
91 init_internal_fns ()
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 while_direct { 0, 2, false }
117 #define fold_extract_direct { 2, 2, false }
118 #define fold_left_direct { 1, 1, false }
120 const direct_internal_fn_info direct_internal_fn_array[IFN_LAST + 1] = {
121 #define DEF_INTERNAL_FN(CODE, FLAGS, FNSPEC) not_direct,
122 #define DEF_INTERNAL_OPTAB_FN(CODE, FLAGS, OPTAB, TYPE) TYPE##_direct,
123 #define DEF_INTERNAL_SIGNED_OPTAB_FN(CODE, FLAGS, SELECTOR, SIGNED_OPTAB, \
124 UNSIGNED_OPTAB, TYPE) TYPE##_direct,
125 #include "internal-fn.def"
126 not_direct
129 /* ARRAY_TYPE is an array of vector modes. Return the associated insn
130 for load-lanes-style optab OPTAB, or CODE_FOR_nothing if none. */
132 static enum insn_code
133 get_multi_vector_move (tree array_type, convert_optab optab)
135 machine_mode imode;
136 machine_mode vmode;
138 gcc_assert (TREE_CODE (array_type) == ARRAY_TYPE);
139 imode = TYPE_MODE (array_type);
140 vmode = TYPE_MODE (TREE_TYPE (array_type));
142 return convert_optab_handler (optab, imode, vmode);
145 /* Expand LOAD_LANES call STMT using optab OPTAB. */
147 static void
148 expand_load_lanes_optab_fn (internal_fn, gcall *stmt, convert_optab optab)
150 struct expand_operand ops[2];
151 tree type, lhs, rhs;
152 rtx target, mem;
154 lhs = gimple_call_lhs (stmt);
155 rhs = gimple_call_arg (stmt, 0);
156 type = TREE_TYPE (lhs);
158 target = expand_expr (lhs, NULL_RTX, VOIDmode, EXPAND_WRITE);
159 mem = expand_normal (rhs);
161 gcc_assert (MEM_P (mem));
162 PUT_MODE (mem, TYPE_MODE (type));
164 create_output_operand (&ops[0], target, TYPE_MODE (type));
165 create_fixed_operand (&ops[1], mem);
166 expand_insn (get_multi_vector_move (type, optab), 2, ops);
169 /* Expand STORE_LANES call STMT using optab OPTAB. */
171 static void
172 expand_store_lanes_optab_fn (internal_fn, gcall *stmt, convert_optab optab)
174 struct expand_operand ops[2];
175 tree type, lhs, rhs;
176 rtx target, reg;
178 lhs = gimple_call_lhs (stmt);
179 rhs = gimple_call_arg (stmt, 0);
180 type = TREE_TYPE (rhs);
182 target = expand_expr (lhs, NULL_RTX, VOIDmode, EXPAND_WRITE);
183 reg = expand_normal (rhs);
185 gcc_assert (MEM_P (target));
186 PUT_MODE (target, TYPE_MODE (type));
188 create_fixed_operand (&ops[0], target);
189 create_input_operand (&ops[1], reg, TYPE_MODE (type));
190 expand_insn (get_multi_vector_move (type, optab), 2, ops);
193 static void
194 expand_ANNOTATE (internal_fn, gcall *)
196 gcc_unreachable ();
199 /* This should get expanded in omp_device_lower pass. */
201 static void
202 expand_GOMP_USE_SIMT (internal_fn, gcall *)
204 gcc_unreachable ();
207 /* This should get expanded in omp_device_lower pass. */
209 static void
210 expand_GOMP_SIMT_ENTER (internal_fn, gcall *)
212 gcc_unreachable ();
215 /* Allocate per-lane storage and begin non-uniform execution region. */
217 static void
218 expand_GOMP_SIMT_ENTER_ALLOC (internal_fn, gcall *stmt)
220 rtx target;
221 tree lhs = gimple_call_lhs (stmt);
222 if (lhs)
223 target = expand_expr (lhs, NULL_RTX, VOIDmode, EXPAND_WRITE);
224 else
225 target = gen_reg_rtx (Pmode);
226 rtx size = expand_normal (gimple_call_arg (stmt, 0));
227 rtx align = expand_normal (gimple_call_arg (stmt, 1));
228 struct expand_operand ops[3];
229 create_output_operand (&ops[0], target, Pmode);
230 create_input_operand (&ops[1], size, Pmode);
231 create_input_operand (&ops[2], align, Pmode);
232 gcc_assert (targetm.have_omp_simt_enter ());
233 expand_insn (targetm.code_for_omp_simt_enter, 3, ops);
236 /* Deallocate per-lane storage and leave non-uniform execution region. */
238 static void
239 expand_GOMP_SIMT_EXIT (internal_fn, gcall *stmt)
241 gcc_checking_assert (!gimple_call_lhs (stmt));
242 rtx arg = expand_normal (gimple_call_arg (stmt, 0));
243 struct expand_operand ops[1];
244 create_input_operand (&ops[0], arg, Pmode);
245 gcc_assert (targetm.have_omp_simt_exit ());
246 expand_insn (targetm.code_for_omp_simt_exit, 1, ops);
249 /* Lane index on SIMT targets: thread index in the warp on NVPTX. On targets
250 without SIMT execution this should be expanded in omp_device_lower pass. */
252 static void
253 expand_GOMP_SIMT_LANE (internal_fn, gcall *stmt)
255 tree lhs = gimple_call_lhs (stmt);
256 if (!lhs)
257 return;
259 rtx target = expand_expr (lhs, NULL_RTX, VOIDmode, EXPAND_WRITE);
260 gcc_assert (targetm.have_omp_simt_lane ());
261 emit_insn (targetm.gen_omp_simt_lane (target));
264 /* This should get expanded in omp_device_lower pass. */
266 static void
267 expand_GOMP_SIMT_VF (internal_fn, gcall *)
269 gcc_unreachable ();
272 /* Lane index of the first SIMT lane that supplies a non-zero argument.
273 This is a SIMT counterpart to GOMP_SIMD_LAST_LANE, used to represent the
274 lane that executed the last iteration for handling OpenMP lastprivate. */
276 static void
277 expand_GOMP_SIMT_LAST_LANE (internal_fn, gcall *stmt)
279 tree lhs = gimple_call_lhs (stmt);
280 if (!lhs)
281 return;
283 rtx target = expand_expr (lhs, NULL_RTX, VOIDmode, EXPAND_WRITE);
284 rtx cond = expand_normal (gimple_call_arg (stmt, 0));
285 machine_mode mode = TYPE_MODE (TREE_TYPE (lhs));
286 struct expand_operand ops[2];
287 create_output_operand (&ops[0], target, mode);
288 create_input_operand (&ops[1], cond, mode);
289 gcc_assert (targetm.have_omp_simt_last_lane ());
290 expand_insn (targetm.code_for_omp_simt_last_lane, 2, ops);
293 /* Non-transparent predicate used in SIMT lowering of OpenMP "ordered". */
295 static void
296 expand_GOMP_SIMT_ORDERED_PRED (internal_fn, gcall *stmt)
298 tree lhs = gimple_call_lhs (stmt);
299 if (!lhs)
300 return;
302 rtx target = expand_expr (lhs, NULL_RTX, VOIDmode, EXPAND_WRITE);
303 rtx ctr = expand_normal (gimple_call_arg (stmt, 0));
304 machine_mode mode = TYPE_MODE (TREE_TYPE (lhs));
305 struct expand_operand ops[2];
306 create_output_operand (&ops[0], target, mode);
307 create_input_operand (&ops[1], ctr, mode);
308 gcc_assert (targetm.have_omp_simt_ordered ());
309 expand_insn (targetm.code_for_omp_simt_ordered, 2, ops);
312 /* "Or" boolean reduction across SIMT lanes: return non-zero in all lanes if
313 any lane supplies a non-zero argument. */
315 static void
316 expand_GOMP_SIMT_VOTE_ANY (internal_fn, gcall *stmt)
318 tree lhs = gimple_call_lhs (stmt);
319 if (!lhs)
320 return;
322 rtx target = expand_expr (lhs, NULL_RTX, VOIDmode, EXPAND_WRITE);
323 rtx cond = expand_normal (gimple_call_arg (stmt, 0));
324 machine_mode mode = TYPE_MODE (TREE_TYPE (lhs));
325 struct expand_operand ops[2];
326 create_output_operand (&ops[0], target, mode);
327 create_input_operand (&ops[1], cond, mode);
328 gcc_assert (targetm.have_omp_simt_vote_any ());
329 expand_insn (targetm.code_for_omp_simt_vote_any, 2, ops);
332 /* Exchange between SIMT lanes with a "butterfly" pattern: source lane index
333 is destination lane index XOR given offset. */
335 static void
336 expand_GOMP_SIMT_XCHG_BFLY (internal_fn, gcall *stmt)
338 tree lhs = gimple_call_lhs (stmt);
339 if (!lhs)
340 return;
342 rtx target = expand_expr (lhs, NULL_RTX, VOIDmode, EXPAND_WRITE);
343 rtx src = expand_normal (gimple_call_arg (stmt, 0));
344 rtx idx = expand_normal (gimple_call_arg (stmt, 1));
345 machine_mode mode = TYPE_MODE (TREE_TYPE (lhs));
346 struct expand_operand ops[3];
347 create_output_operand (&ops[0], target, mode);
348 create_input_operand (&ops[1], src, mode);
349 create_input_operand (&ops[2], idx, SImode);
350 gcc_assert (targetm.have_omp_simt_xchg_bfly ());
351 expand_insn (targetm.code_for_omp_simt_xchg_bfly, 3, ops);
354 /* Exchange between SIMT lanes according to given source lane index. */
356 static void
357 expand_GOMP_SIMT_XCHG_IDX (internal_fn, gcall *stmt)
359 tree lhs = gimple_call_lhs (stmt);
360 if (!lhs)
361 return;
363 rtx target = expand_expr (lhs, NULL_RTX, VOIDmode, EXPAND_WRITE);
364 rtx src = expand_normal (gimple_call_arg (stmt, 0));
365 rtx idx = expand_normal (gimple_call_arg (stmt, 1));
366 machine_mode mode = TYPE_MODE (TREE_TYPE (lhs));
367 struct expand_operand ops[3];
368 create_output_operand (&ops[0], target, mode);
369 create_input_operand (&ops[1], src, mode);
370 create_input_operand (&ops[2], idx, SImode);
371 gcc_assert (targetm.have_omp_simt_xchg_idx ());
372 expand_insn (targetm.code_for_omp_simt_xchg_idx, 3, ops);
375 /* This should get expanded in adjust_simduid_builtins. */
377 static void
378 expand_GOMP_SIMD_LANE (internal_fn, gcall *)
380 gcc_unreachable ();
383 /* This should get expanded in adjust_simduid_builtins. */
385 static void
386 expand_GOMP_SIMD_VF (internal_fn, gcall *)
388 gcc_unreachable ();
391 /* This should get expanded in adjust_simduid_builtins. */
393 static void
394 expand_GOMP_SIMD_LAST_LANE (internal_fn, gcall *)
396 gcc_unreachable ();
399 /* This should get expanded in adjust_simduid_builtins. */
401 static void
402 expand_GOMP_SIMD_ORDERED_START (internal_fn, gcall *)
404 gcc_unreachable ();
407 /* This should get expanded in adjust_simduid_builtins. */
409 static void
410 expand_GOMP_SIMD_ORDERED_END (internal_fn, gcall *)
412 gcc_unreachable ();
415 /* This should get expanded in the sanopt pass. */
417 static void
418 expand_UBSAN_NULL (internal_fn, gcall *)
420 gcc_unreachable ();
423 /* This should get expanded in the sanopt pass. */
425 static void
426 expand_UBSAN_BOUNDS (internal_fn, gcall *)
428 gcc_unreachable ();
431 /* This should get expanded in the sanopt pass. */
433 static void
434 expand_UBSAN_VPTR (internal_fn, gcall *)
436 gcc_unreachable ();
439 /* This should get expanded in the sanopt pass. */
441 static void
442 expand_UBSAN_PTR (internal_fn, gcall *)
444 gcc_unreachable ();
447 /* This should get expanded in the sanopt pass. */
449 static void
450 expand_UBSAN_OBJECT_SIZE (internal_fn, gcall *)
452 gcc_unreachable ();
455 /* This should get expanded in the sanopt pass. */
457 static void
458 expand_ASAN_CHECK (internal_fn, gcall *)
460 gcc_unreachable ();
463 /* This should get expanded in the sanopt pass. */
465 static void
466 expand_ASAN_MARK (internal_fn, gcall *)
468 gcc_unreachable ();
471 /* This should get expanded in the sanopt pass. */
473 static void
474 expand_ASAN_POISON (internal_fn, gcall *)
476 gcc_unreachable ();
479 /* This should get expanded in the sanopt pass. */
481 static void
482 expand_ASAN_POISON_USE (internal_fn, gcall *)
484 gcc_unreachable ();
487 /* This should get expanded in the tsan pass. */
489 static void
490 expand_TSAN_FUNC_EXIT (internal_fn, gcall *)
492 gcc_unreachable ();
495 /* This should get expanded in the lower pass. */
497 static void
498 expand_FALLTHROUGH (internal_fn, gcall *call)
500 error_at (gimple_location (call),
501 "invalid use of attribute %<fallthrough%>");
504 /* Return minimum precision needed to represent all values
505 of ARG in SIGNed integral type. */
507 static int
508 get_min_precision (tree arg, signop sign)
510 int prec = TYPE_PRECISION (TREE_TYPE (arg));
511 int cnt = 0;
512 signop orig_sign = sign;
513 if (TREE_CODE (arg) == INTEGER_CST)
515 int p;
516 if (TYPE_SIGN (TREE_TYPE (arg)) != sign)
518 widest_int w = wi::to_widest (arg);
519 w = wi::ext (w, prec, sign);
520 p = wi::min_precision (w, sign);
522 else
523 p = wi::min_precision (wi::to_wide (arg), sign);
524 return MIN (p, prec);
526 while (CONVERT_EXPR_P (arg)
527 && INTEGRAL_TYPE_P (TREE_TYPE (TREE_OPERAND (arg, 0)))
528 && TYPE_PRECISION (TREE_TYPE (TREE_OPERAND (arg, 0))) <= prec)
530 arg = TREE_OPERAND (arg, 0);
531 if (TYPE_PRECISION (TREE_TYPE (arg)) < prec)
533 if (TYPE_UNSIGNED (TREE_TYPE (arg)))
534 sign = UNSIGNED;
535 else if (sign == UNSIGNED && get_range_pos_neg (arg) != 1)
536 return prec + (orig_sign != sign);
537 prec = TYPE_PRECISION (TREE_TYPE (arg));
539 if (++cnt > 30)
540 return prec + (orig_sign != sign);
542 if (TREE_CODE (arg) != SSA_NAME)
543 return prec + (orig_sign != sign);
544 wide_int arg_min, arg_max;
545 while (get_range_info (arg, &arg_min, &arg_max) != VR_RANGE)
547 gimple *g = SSA_NAME_DEF_STMT (arg);
548 if (is_gimple_assign (g)
549 && CONVERT_EXPR_CODE_P (gimple_assign_rhs_code (g)))
551 tree t = gimple_assign_rhs1 (g);
552 if (INTEGRAL_TYPE_P (TREE_TYPE (t))
553 && TYPE_PRECISION (TREE_TYPE (t)) <= prec)
555 arg = t;
556 if (TYPE_PRECISION (TREE_TYPE (arg)) < prec)
558 if (TYPE_UNSIGNED (TREE_TYPE (arg)))
559 sign = UNSIGNED;
560 else if (sign == UNSIGNED && get_range_pos_neg (arg) != 1)
561 return prec + (orig_sign != sign);
562 prec = TYPE_PRECISION (TREE_TYPE (arg));
564 if (++cnt > 30)
565 return prec + (orig_sign != sign);
566 continue;
569 return prec + (orig_sign != sign);
571 if (sign == TYPE_SIGN (TREE_TYPE (arg)))
573 int p1 = wi::min_precision (arg_min, sign);
574 int p2 = wi::min_precision (arg_max, sign);
575 p1 = MAX (p1, p2);
576 prec = MIN (prec, p1);
578 else if (sign == UNSIGNED && !wi::neg_p (arg_min, SIGNED))
580 int p = wi::min_precision (arg_max, UNSIGNED);
581 prec = MIN (prec, p);
583 return prec + (orig_sign != sign);
586 /* Helper for expand_*_overflow. Set the __imag__ part to true
587 (1 except for signed:1 type, in which case store -1). */
589 static void
590 expand_arith_set_overflow (tree lhs, rtx target)
592 if (TYPE_PRECISION (TREE_TYPE (TREE_TYPE (lhs))) == 1
593 && !TYPE_UNSIGNED (TREE_TYPE (TREE_TYPE (lhs))))
594 write_complex_part (target, constm1_rtx, true);
595 else
596 write_complex_part (target, const1_rtx, true);
599 /* Helper for expand_*_overflow. Store RES into the __real__ part
600 of TARGET. If RES has larger MODE than __real__ part of TARGET,
601 set the __imag__ part to 1 if RES doesn't fit into it. Similarly
602 if LHS has smaller precision than its mode. */
604 static void
605 expand_arith_overflow_result_store (tree lhs, rtx target,
606 scalar_int_mode mode, rtx res)
608 scalar_int_mode tgtmode
609 = as_a <scalar_int_mode> (GET_MODE_INNER (GET_MODE (target)));
610 rtx lres = res;
611 if (tgtmode != mode)
613 rtx_code_label *done_label = gen_label_rtx ();
614 int uns = TYPE_UNSIGNED (TREE_TYPE (TREE_TYPE (lhs)));
615 lres = convert_modes (tgtmode, mode, res, uns);
616 gcc_assert (GET_MODE_PRECISION (tgtmode) < GET_MODE_PRECISION (mode));
617 do_compare_rtx_and_jump (res, convert_modes (mode, tgtmode, lres, uns),
618 EQ, true, mode, NULL_RTX, NULL, done_label,
619 profile_probability::very_likely ());
620 expand_arith_set_overflow (lhs, target);
621 emit_label (done_label);
623 int prec = TYPE_PRECISION (TREE_TYPE (TREE_TYPE (lhs)));
624 int tgtprec = GET_MODE_PRECISION (tgtmode);
625 if (prec < tgtprec)
627 rtx_code_label *done_label = gen_label_rtx ();
628 int uns = TYPE_UNSIGNED (TREE_TYPE (TREE_TYPE (lhs)));
629 res = lres;
630 if (uns)
632 rtx mask
633 = immed_wide_int_const (wi::shifted_mask (0, prec, false, tgtprec),
634 tgtmode);
635 lres = expand_simple_binop (tgtmode, AND, res, mask, NULL_RTX,
636 true, OPTAB_LIB_WIDEN);
638 else
640 lres = expand_shift (LSHIFT_EXPR, tgtmode, res, tgtprec - prec,
641 NULL_RTX, 1);
642 lres = expand_shift (RSHIFT_EXPR, tgtmode, lres, tgtprec - prec,
643 NULL_RTX, 0);
645 do_compare_rtx_and_jump (res, lres,
646 EQ, true, tgtmode, NULL_RTX, NULL, done_label,
647 profile_probability::very_likely ());
648 expand_arith_set_overflow (lhs, target);
649 emit_label (done_label);
651 write_complex_part (target, lres, false);
654 /* Helper for expand_*_overflow. Store RES into TARGET. */
656 static void
657 expand_ubsan_result_store (rtx target, rtx res)
659 if (GET_CODE (target) == SUBREG && SUBREG_PROMOTED_VAR_P (target))
660 /* If this is a scalar in a register that is stored in a wider mode
661 than the declared mode, compute the result into its declared mode
662 and then convert to the wider mode. Our value is the computed
663 expression. */
664 convert_move (SUBREG_REG (target), res, SUBREG_PROMOTED_SIGN (target));
665 else
666 emit_move_insn (target, res);
669 /* Add sub/add overflow checking to the statement STMT.
670 CODE says whether the operation is +, or -. */
672 static void
673 expand_addsub_overflow (location_t loc, tree_code code, tree lhs,
674 tree arg0, tree arg1, bool unsr_p, bool uns0_p,
675 bool uns1_p, bool is_ubsan, tree *datap)
677 rtx res, target = NULL_RTX;
678 tree fn;
679 rtx_code_label *done_label = gen_label_rtx ();
680 rtx_code_label *do_error = gen_label_rtx ();
681 do_pending_stack_adjust ();
682 rtx op0 = expand_normal (arg0);
683 rtx op1 = expand_normal (arg1);
684 scalar_int_mode mode = SCALAR_INT_TYPE_MODE (TREE_TYPE (arg0));
685 int prec = GET_MODE_PRECISION (mode);
686 rtx sgn = immed_wide_int_const (wi::min_value (prec, SIGNED), mode);
687 bool do_xor = false;
689 if (is_ubsan)
690 gcc_assert (!unsr_p && !uns0_p && !uns1_p);
692 if (lhs)
694 target = expand_expr (lhs, NULL_RTX, VOIDmode, EXPAND_WRITE);
695 if (!is_ubsan)
696 write_complex_part (target, const0_rtx, true);
699 /* We assume both operands and result have the same precision
700 here (GET_MODE_BITSIZE (mode)), S stands for signed type
701 with that precision, U for unsigned type with that precision,
702 sgn for unsigned most significant bit in that precision.
703 s1 is signed first operand, u1 is unsigned first operand,
704 s2 is signed second operand, u2 is unsigned second operand,
705 sr is signed result, ur is unsigned result and the following
706 rules say how to compute result (which is always result of
707 the operands as if both were unsigned, cast to the right
708 signedness) and how to compute whether operation overflowed.
710 s1 + s2 -> sr
711 res = (S) ((U) s1 + (U) s2)
712 ovf = s2 < 0 ? res > s1 : res < s1 (or jump on overflow)
713 s1 - s2 -> sr
714 res = (S) ((U) s1 - (U) s2)
715 ovf = s2 < 0 ? res < s1 : res > s2 (or jump on overflow)
716 u1 + u2 -> ur
717 res = u1 + u2
718 ovf = res < u1 (or jump on carry, but RTL opts will handle it)
719 u1 - u2 -> ur
720 res = u1 - u2
721 ovf = res > u1 (or jump on carry, but RTL opts will handle it)
722 s1 + u2 -> sr
723 res = (S) ((U) s1 + u2)
724 ovf = ((U) res ^ sgn) < u2
725 s1 + u2 -> ur
726 t1 = (S) (u2 ^ sgn)
727 t2 = s1 + t1
728 res = (U) t2 ^ sgn
729 ovf = t1 < 0 ? t2 > s1 : t2 < s1 (or jump on overflow)
730 s1 - u2 -> sr
731 res = (S) ((U) s1 - u2)
732 ovf = u2 > ((U) s1 ^ sgn)
733 s1 - u2 -> ur
734 res = (U) s1 - u2
735 ovf = s1 < 0 || u2 > (U) s1
736 u1 - s2 -> sr
737 res = u1 - (U) s2
738 ovf = u1 >= ((U) s2 ^ sgn)
739 u1 - s2 -> ur
740 t1 = u1 ^ sgn
741 t2 = t1 - (U) s2
742 res = t2 ^ sgn
743 ovf = s2 < 0 ? (S) t2 < (S) t1 : (S) t2 > (S) t1 (or jump on overflow)
744 s1 + s2 -> ur
745 res = (U) s1 + (U) s2
746 ovf = s2 < 0 ? (s1 | (S) res) < 0) : (s1 & (S) res) < 0)
747 u1 + u2 -> sr
748 res = (S) (u1 + u2)
749 ovf = (U) res < u2 || res < 0
750 u1 - u2 -> sr
751 res = (S) (u1 - u2)
752 ovf = u1 >= u2 ? res < 0 : res >= 0
753 s1 - s2 -> ur
754 res = (U) s1 - (U) s2
755 ovf = s2 >= 0 ? ((s1 | (S) res) < 0) : ((s1 & (S) res) < 0) */
757 if (code == PLUS_EXPR && uns0_p && !uns1_p)
759 /* PLUS_EXPR is commutative, if operand signedness differs,
760 canonicalize to the first operand being signed and second
761 unsigned to simplify following code. */
762 std::swap (op0, op1);
763 std::swap (arg0, arg1);
764 uns0_p = false;
765 uns1_p = true;
768 /* u1 +- u2 -> ur */
769 if (uns0_p && uns1_p && unsr_p)
771 insn_code icode = optab_handler (code == PLUS_EXPR ? uaddv4_optab
772 : usubv4_optab, mode);
773 if (icode != CODE_FOR_nothing)
775 struct expand_operand ops[4];
776 rtx_insn *last = get_last_insn ();
778 res = gen_reg_rtx (mode);
779 create_output_operand (&ops[0], res, mode);
780 create_input_operand (&ops[1], op0, mode);
781 create_input_operand (&ops[2], op1, mode);
782 create_fixed_operand (&ops[3], do_error);
783 if (maybe_expand_insn (icode, 4, ops))
785 last = get_last_insn ();
786 if (profile_status_for_fn (cfun) != PROFILE_ABSENT
787 && JUMP_P (last)
788 && any_condjump_p (last)
789 && !find_reg_note (last, REG_BR_PROB, 0))
790 add_reg_br_prob_note (last,
791 profile_probability::very_unlikely ());
792 emit_jump (done_label);
793 goto do_error_label;
796 delete_insns_since (last);
799 /* Compute the operation. On RTL level, the addition is always
800 unsigned. */
801 res = expand_binop (mode, code == PLUS_EXPR ? add_optab : sub_optab,
802 op0, op1, NULL_RTX, false, OPTAB_LIB_WIDEN);
803 rtx tem = op0;
804 /* For PLUS_EXPR, the operation is commutative, so we can pick
805 operand to compare against. For prec <= BITS_PER_WORD, I think
806 preferring REG operand is better over CONST_INT, because
807 the CONST_INT might enlarge the instruction or CSE would need
808 to figure out we'd already loaded it into a register before.
809 For prec > BITS_PER_WORD, I think CONST_INT might be more beneficial,
810 as then the multi-word comparison can be perhaps simplified. */
811 if (code == PLUS_EXPR
812 && (prec <= BITS_PER_WORD
813 ? (CONST_SCALAR_INT_P (op0) && REG_P (op1))
814 : CONST_SCALAR_INT_P (op1)))
815 tem = op1;
816 do_compare_rtx_and_jump (res, tem, code == PLUS_EXPR ? GEU : LEU,
817 true, mode, NULL_RTX, NULL, done_label,
818 profile_probability::very_likely ());
819 goto do_error_label;
822 /* s1 +- u2 -> sr */
823 if (!uns0_p && uns1_p && !unsr_p)
825 /* Compute the operation. On RTL level, the addition is always
826 unsigned. */
827 res = expand_binop (mode, code == PLUS_EXPR ? add_optab : sub_optab,
828 op0, op1, NULL_RTX, false, OPTAB_LIB_WIDEN);
829 rtx tem = expand_binop (mode, add_optab,
830 code == PLUS_EXPR ? res : op0, sgn,
831 NULL_RTX, false, OPTAB_LIB_WIDEN);
832 do_compare_rtx_and_jump (tem, op1, GEU, true, mode, NULL_RTX, NULL,
833 done_label, profile_probability::very_likely ());
834 goto do_error_label;
837 /* s1 + u2 -> ur */
838 if (code == PLUS_EXPR && !uns0_p && uns1_p && unsr_p)
840 op1 = expand_binop (mode, add_optab, op1, sgn, NULL_RTX, false,
841 OPTAB_LIB_WIDEN);
842 /* As we've changed op1, we have to avoid using the value range
843 for the original argument. */
844 arg1 = error_mark_node;
845 do_xor = true;
846 goto do_signed;
849 /* u1 - s2 -> ur */
850 if (code == MINUS_EXPR && uns0_p && !uns1_p && unsr_p)
852 op0 = expand_binop (mode, add_optab, op0, sgn, NULL_RTX, false,
853 OPTAB_LIB_WIDEN);
854 /* As we've changed op0, we have to avoid using the value range
855 for the original argument. */
856 arg0 = error_mark_node;
857 do_xor = true;
858 goto do_signed;
861 /* s1 - u2 -> ur */
862 if (code == MINUS_EXPR && !uns0_p && uns1_p && unsr_p)
864 /* Compute the operation. On RTL level, the addition is always
865 unsigned. */
866 res = expand_binop (mode, sub_optab, op0, op1, NULL_RTX, false,
867 OPTAB_LIB_WIDEN);
868 int pos_neg = get_range_pos_neg (arg0);
869 if (pos_neg == 2)
870 /* If ARG0 is known to be always negative, this is always overflow. */
871 emit_jump (do_error);
872 else if (pos_neg == 3)
873 /* If ARG0 is not known to be always positive, check at runtime. */
874 do_compare_rtx_and_jump (op0, const0_rtx, LT, false, mode, NULL_RTX,
875 NULL, do_error, profile_probability::very_unlikely ());
876 do_compare_rtx_and_jump (op1, op0, LEU, true, mode, NULL_RTX, NULL,
877 done_label, profile_probability::very_likely ());
878 goto do_error_label;
881 /* u1 - s2 -> sr */
882 if (code == MINUS_EXPR && uns0_p && !uns1_p && !unsr_p)
884 /* Compute the operation. On RTL level, the addition is always
885 unsigned. */
886 res = expand_binop (mode, sub_optab, op0, op1, NULL_RTX, false,
887 OPTAB_LIB_WIDEN);
888 rtx tem = expand_binop (mode, add_optab, op1, sgn, NULL_RTX, false,
889 OPTAB_LIB_WIDEN);
890 do_compare_rtx_and_jump (op0, tem, LTU, true, mode, NULL_RTX, NULL,
891 done_label, profile_probability::very_likely ());
892 goto do_error_label;
895 /* u1 + u2 -> sr */
896 if (code == PLUS_EXPR && uns0_p && uns1_p && !unsr_p)
898 /* Compute the operation. On RTL level, the addition is always
899 unsigned. */
900 res = expand_binop (mode, add_optab, op0, op1, NULL_RTX, false,
901 OPTAB_LIB_WIDEN);
902 do_compare_rtx_and_jump (res, const0_rtx, LT, false, mode, NULL_RTX,
903 NULL, do_error, profile_probability::very_unlikely ());
904 rtx tem = op1;
905 /* The operation is commutative, so we can pick operand to compare
906 against. For prec <= BITS_PER_WORD, I think preferring REG operand
907 is better over CONST_INT, because the CONST_INT might enlarge the
908 instruction or CSE would need to figure out we'd already loaded it
909 into a register before. For prec > BITS_PER_WORD, I think CONST_INT
910 might be more beneficial, as then the multi-word comparison can be
911 perhaps simplified. */
912 if (prec <= BITS_PER_WORD
913 ? (CONST_SCALAR_INT_P (op1) && REG_P (op0))
914 : CONST_SCALAR_INT_P (op0))
915 tem = op0;
916 do_compare_rtx_and_jump (res, tem, GEU, true, mode, NULL_RTX, NULL,
917 done_label, profile_probability::very_likely ());
918 goto do_error_label;
921 /* s1 +- s2 -> ur */
922 if (!uns0_p && !uns1_p && unsr_p)
924 /* Compute the operation. On RTL level, the addition is always
925 unsigned. */
926 res = expand_binop (mode, code == PLUS_EXPR ? add_optab : sub_optab,
927 op0, op1, NULL_RTX, false, OPTAB_LIB_WIDEN);
928 int pos_neg = get_range_pos_neg (arg1);
929 if (code == PLUS_EXPR)
931 int pos_neg0 = get_range_pos_neg (arg0);
932 if (pos_neg0 != 3 && pos_neg == 3)
934 std::swap (op0, op1);
935 pos_neg = pos_neg0;
938 rtx tem;
939 if (pos_neg != 3)
941 tem = expand_binop (mode, ((pos_neg == 1) ^ (code == MINUS_EXPR))
942 ? and_optab : ior_optab,
943 op0, res, NULL_RTX, false, OPTAB_LIB_WIDEN);
944 do_compare_rtx_and_jump (tem, const0_rtx, GE, false, mode, NULL,
945 NULL, done_label, profile_probability::very_likely ());
947 else
949 rtx_code_label *do_ior_label = gen_label_rtx ();
950 do_compare_rtx_and_jump (op1, const0_rtx,
951 code == MINUS_EXPR ? GE : LT, false, mode,
952 NULL_RTX, NULL, do_ior_label,
953 profile_probability::even ());
954 tem = expand_binop (mode, and_optab, op0, res, NULL_RTX, false,
955 OPTAB_LIB_WIDEN);
956 do_compare_rtx_and_jump (tem, const0_rtx, GE, false, mode, NULL_RTX,
957 NULL, done_label, profile_probability::very_likely ());
958 emit_jump (do_error);
959 emit_label (do_ior_label);
960 tem = expand_binop (mode, ior_optab, op0, res, NULL_RTX, false,
961 OPTAB_LIB_WIDEN);
962 do_compare_rtx_and_jump (tem, const0_rtx, GE, false, mode, NULL_RTX,
963 NULL, done_label, profile_probability::very_likely ());
965 goto do_error_label;
968 /* u1 - u2 -> sr */
969 if (code == MINUS_EXPR && uns0_p && uns1_p && !unsr_p)
971 /* Compute the operation. On RTL level, the addition is always
972 unsigned. */
973 res = expand_binop (mode, sub_optab, op0, op1, NULL_RTX, false,
974 OPTAB_LIB_WIDEN);
975 rtx_code_label *op0_geu_op1 = gen_label_rtx ();
976 do_compare_rtx_and_jump (op0, op1, GEU, true, mode, NULL_RTX, NULL,
977 op0_geu_op1, profile_probability::even ());
978 do_compare_rtx_and_jump (res, const0_rtx, LT, false, mode, NULL_RTX,
979 NULL, done_label, profile_probability::very_likely ());
980 emit_jump (do_error);
981 emit_label (op0_geu_op1);
982 do_compare_rtx_and_jump (res, const0_rtx, GE, false, mode, NULL_RTX,
983 NULL, done_label, profile_probability::very_likely ());
984 goto do_error_label;
987 gcc_assert (!uns0_p && !uns1_p && !unsr_p);
989 /* s1 +- s2 -> sr */
990 do_signed:
992 insn_code icode = optab_handler (code == PLUS_EXPR ? addv4_optab
993 : subv4_optab, mode);
994 if (icode != CODE_FOR_nothing)
996 struct expand_operand ops[4];
997 rtx_insn *last = get_last_insn ();
999 res = gen_reg_rtx (mode);
1000 create_output_operand (&ops[0], res, mode);
1001 create_input_operand (&ops[1], op0, mode);
1002 create_input_operand (&ops[2], op1, mode);
1003 create_fixed_operand (&ops[3], do_error);
1004 if (maybe_expand_insn (icode, 4, ops))
1006 last = get_last_insn ();
1007 if (profile_status_for_fn (cfun) != PROFILE_ABSENT
1008 && JUMP_P (last)
1009 && any_condjump_p (last)
1010 && !find_reg_note (last, REG_BR_PROB, 0))
1011 add_reg_br_prob_note (last,
1012 profile_probability::very_unlikely ());
1013 emit_jump (done_label);
1014 goto do_error_label;
1017 delete_insns_since (last);
1020 /* Compute the operation. On RTL level, the addition is always
1021 unsigned. */
1022 res = expand_binop (mode, code == PLUS_EXPR ? add_optab : sub_optab,
1023 op0, op1, NULL_RTX, false, OPTAB_LIB_WIDEN);
1025 /* If we can prove that one of the arguments (for MINUS_EXPR only
1026 the second operand, as subtraction is not commutative) is always
1027 non-negative or always negative, we can do just one comparison
1028 and conditional jump. */
1029 int pos_neg = get_range_pos_neg (arg1);
1030 if (code == PLUS_EXPR)
1032 int pos_neg0 = get_range_pos_neg (arg0);
1033 if (pos_neg0 != 3 && pos_neg == 3)
1035 std::swap (op0, op1);
1036 pos_neg = pos_neg0;
1040 /* Addition overflows if and only if the two operands have the same sign,
1041 and the result has the opposite sign. Subtraction overflows if and
1042 only if the two operands have opposite sign, and the subtrahend has
1043 the same sign as the result. Here 0 is counted as positive. */
1044 if (pos_neg == 3)
1046 /* Compute op0 ^ op1 (operands have opposite sign). */
1047 rtx op_xor = expand_binop (mode, xor_optab, op0, op1, NULL_RTX, false,
1048 OPTAB_LIB_WIDEN);
1050 /* Compute res ^ op1 (result and 2nd operand have opposite sign). */
1051 rtx res_xor = expand_binop (mode, xor_optab, res, op1, NULL_RTX, false,
1052 OPTAB_LIB_WIDEN);
1054 rtx tem;
1055 if (code == PLUS_EXPR)
1057 /* Compute (res ^ op1) & ~(op0 ^ op1). */
1058 tem = expand_unop (mode, one_cmpl_optab, op_xor, NULL_RTX, false);
1059 tem = expand_binop (mode, and_optab, res_xor, tem, NULL_RTX, false,
1060 OPTAB_LIB_WIDEN);
1062 else
1064 /* Compute (op0 ^ op1) & ~(res ^ op1). */
1065 tem = expand_unop (mode, one_cmpl_optab, res_xor, NULL_RTX, false);
1066 tem = expand_binop (mode, and_optab, op_xor, tem, NULL_RTX, false,
1067 OPTAB_LIB_WIDEN);
1070 /* No overflow if the result has bit sign cleared. */
1071 do_compare_rtx_and_jump (tem, const0_rtx, GE, false, mode, NULL_RTX,
1072 NULL, done_label, profile_probability::very_likely ());
1075 /* Compare the result of the operation with the first operand.
1076 No overflow for addition if second operand is positive and result
1077 is larger or second operand is negative and result is smaller.
1078 Likewise for subtraction with sign of second operand flipped. */
1079 else
1080 do_compare_rtx_and_jump (res, op0,
1081 (pos_neg == 1) ^ (code == MINUS_EXPR) ? GE : LE,
1082 false, mode, NULL_RTX, NULL, done_label,
1083 profile_probability::very_likely ());
1086 do_error_label:
1087 emit_label (do_error);
1088 if (is_ubsan)
1090 /* Expand the ubsan builtin call. */
1091 push_temp_slots ();
1092 fn = ubsan_build_overflow_builtin (code, loc, TREE_TYPE (arg0),
1093 arg0, arg1, datap);
1094 expand_normal (fn);
1095 pop_temp_slots ();
1096 do_pending_stack_adjust ();
1098 else if (lhs)
1099 expand_arith_set_overflow (lhs, target);
1101 /* We're done. */
1102 emit_label (done_label);
1104 if (lhs)
1106 if (is_ubsan)
1107 expand_ubsan_result_store (target, res);
1108 else
1110 if (do_xor)
1111 res = expand_binop (mode, add_optab, res, sgn, NULL_RTX, false,
1112 OPTAB_LIB_WIDEN);
1114 expand_arith_overflow_result_store (lhs, target, mode, res);
1119 /* Add negate overflow checking to the statement STMT. */
1121 static void
1122 expand_neg_overflow (location_t loc, tree lhs, tree arg1, bool is_ubsan,
1123 tree *datap)
1125 rtx res, op1;
1126 tree fn;
1127 rtx_code_label *done_label, *do_error;
1128 rtx target = NULL_RTX;
1130 done_label = gen_label_rtx ();
1131 do_error = gen_label_rtx ();
1133 do_pending_stack_adjust ();
1134 op1 = expand_normal (arg1);
1136 scalar_int_mode mode = SCALAR_INT_TYPE_MODE (TREE_TYPE (arg1));
1137 if (lhs)
1139 target = expand_expr (lhs, NULL_RTX, VOIDmode, EXPAND_WRITE);
1140 if (!is_ubsan)
1141 write_complex_part (target, const0_rtx, true);
1144 enum insn_code icode = optab_handler (negv3_optab, mode);
1145 if (icode != CODE_FOR_nothing)
1147 struct expand_operand ops[3];
1148 rtx_insn *last = get_last_insn ();
1150 res = gen_reg_rtx (mode);
1151 create_output_operand (&ops[0], res, mode);
1152 create_input_operand (&ops[1], op1, mode);
1153 create_fixed_operand (&ops[2], do_error);
1154 if (maybe_expand_insn (icode, 3, ops))
1156 last = get_last_insn ();
1157 if (profile_status_for_fn (cfun) != PROFILE_ABSENT
1158 && JUMP_P (last)
1159 && any_condjump_p (last)
1160 && !find_reg_note (last, REG_BR_PROB, 0))
1161 add_reg_br_prob_note (last,
1162 profile_probability::very_unlikely ());
1163 emit_jump (done_label);
1165 else
1167 delete_insns_since (last);
1168 icode = CODE_FOR_nothing;
1172 if (icode == CODE_FOR_nothing)
1174 /* Compute the operation. On RTL level, the addition is always
1175 unsigned. */
1176 res = expand_unop (mode, neg_optab, op1, NULL_RTX, false);
1178 /* Compare the operand with the most negative value. */
1179 rtx minv = expand_normal (TYPE_MIN_VALUE (TREE_TYPE (arg1)));
1180 do_compare_rtx_and_jump (op1, minv, NE, true, mode, NULL_RTX, NULL,
1181 done_label, profile_probability::very_likely ());
1184 emit_label (do_error);
1185 if (is_ubsan)
1187 /* Expand the ubsan builtin call. */
1188 push_temp_slots ();
1189 fn = ubsan_build_overflow_builtin (NEGATE_EXPR, loc, TREE_TYPE (arg1),
1190 arg1, NULL_TREE, datap);
1191 expand_normal (fn);
1192 pop_temp_slots ();
1193 do_pending_stack_adjust ();
1195 else if (lhs)
1196 expand_arith_set_overflow (lhs, target);
1198 /* We're done. */
1199 emit_label (done_label);
1201 if (lhs)
1203 if (is_ubsan)
1204 expand_ubsan_result_store (target, res);
1205 else
1206 expand_arith_overflow_result_store (lhs, target, mode, res);
1210 /* Return true if UNS WIDEN_MULT_EXPR with result mode WMODE and operand
1211 mode MODE can be expanded without using a libcall. */
1213 static bool
1214 can_widen_mult_without_libcall (scalar_int_mode wmode, scalar_int_mode mode,
1215 rtx op0, rtx op1, bool uns)
1217 if (find_widening_optab_handler (umul_widen_optab, wmode, mode)
1218 != CODE_FOR_nothing)
1219 return true;
1221 if (find_widening_optab_handler (smul_widen_optab, wmode, mode)
1222 != CODE_FOR_nothing)
1223 return true;
1225 rtx_insn *last = get_last_insn ();
1226 if (CONSTANT_P (op0))
1227 op0 = convert_modes (wmode, mode, op0, uns);
1228 else
1229 op0 = gen_raw_REG (wmode, LAST_VIRTUAL_REGISTER + 1);
1230 if (CONSTANT_P (op1))
1231 op1 = convert_modes (wmode, mode, op1, uns);
1232 else
1233 op1 = gen_raw_REG (wmode, LAST_VIRTUAL_REGISTER + 2);
1234 rtx ret = expand_mult (wmode, op0, op1, NULL_RTX, uns, true);
1235 delete_insns_since (last);
1236 return ret != NULL_RTX;
1239 /* Add mul overflow checking to the statement STMT. */
1241 static void
1242 expand_mul_overflow (location_t loc, tree lhs, tree arg0, tree arg1,
1243 bool unsr_p, bool uns0_p, bool uns1_p, bool is_ubsan,
1244 tree *datap)
1246 rtx res, op0, op1;
1247 tree fn, type;
1248 rtx_code_label *done_label, *do_error;
1249 rtx target = NULL_RTX;
1250 signop sign;
1251 enum insn_code icode;
1253 done_label = gen_label_rtx ();
1254 do_error = gen_label_rtx ();
1256 do_pending_stack_adjust ();
1257 op0 = expand_normal (arg0);
1258 op1 = expand_normal (arg1);
1260 scalar_int_mode mode = SCALAR_INT_TYPE_MODE (TREE_TYPE (arg0));
1261 bool uns = unsr_p;
1262 if (lhs)
1264 target = expand_expr (lhs, NULL_RTX, VOIDmode, EXPAND_WRITE);
1265 if (!is_ubsan)
1266 write_complex_part (target, const0_rtx, true);
1269 if (is_ubsan)
1270 gcc_assert (!unsr_p && !uns0_p && !uns1_p);
1272 /* We assume both operands and result have the same precision
1273 here (GET_MODE_BITSIZE (mode)), S stands for signed type
1274 with that precision, U for unsigned type with that precision,
1275 sgn for unsigned most significant bit in that precision.
1276 s1 is signed first operand, u1 is unsigned first operand,
1277 s2 is signed second operand, u2 is unsigned second operand,
1278 sr is signed result, ur is unsigned result and the following
1279 rules say how to compute result (which is always result of
1280 the operands as if both were unsigned, cast to the right
1281 signedness) and how to compute whether operation overflowed.
1282 main_ovf (false) stands for jump on signed multiplication
1283 overflow or the main algorithm with uns == false.
1284 main_ovf (true) stands for jump on unsigned multiplication
1285 overflow or the main algorithm with uns == true.
1287 s1 * s2 -> sr
1288 res = (S) ((U) s1 * (U) s2)
1289 ovf = main_ovf (false)
1290 u1 * u2 -> ur
1291 res = u1 * u2
1292 ovf = main_ovf (true)
1293 s1 * u2 -> ur
1294 res = (U) s1 * u2
1295 ovf = (s1 < 0 && u2) || main_ovf (true)
1296 u1 * u2 -> sr
1297 res = (S) (u1 * u2)
1298 ovf = res < 0 || main_ovf (true)
1299 s1 * u2 -> sr
1300 res = (S) ((U) s1 * u2)
1301 ovf = (S) u2 >= 0 ? main_ovf (false)
1302 : (s1 != 0 && (s1 != -1 || u2 != (U) res))
1303 s1 * s2 -> ur
1304 t1 = (s1 & s2) < 0 ? (-(U) s1) : ((U) s1)
1305 t2 = (s1 & s2) < 0 ? (-(U) s2) : ((U) s2)
1306 res = t1 * t2
1307 ovf = (s1 ^ s2) < 0 ? (s1 && s2) : main_ovf (true) */
1309 if (uns0_p && !uns1_p)
1311 /* Multiplication is commutative, if operand signedness differs,
1312 canonicalize to the first operand being signed and second
1313 unsigned to simplify following code. */
1314 std::swap (op0, op1);
1315 std::swap (arg0, arg1);
1316 uns0_p = false;
1317 uns1_p = true;
1320 int pos_neg0 = get_range_pos_neg (arg0);
1321 int pos_neg1 = get_range_pos_neg (arg1);
1323 /* s1 * u2 -> ur */
1324 if (!uns0_p && uns1_p && unsr_p)
1326 switch (pos_neg0)
1328 case 1:
1329 /* If s1 is non-negative, just perform normal u1 * u2 -> ur. */
1330 goto do_main;
1331 case 2:
1332 /* If s1 is negative, avoid the main code, just multiply and
1333 signal overflow if op1 is not 0. */
1334 struct separate_ops ops;
1335 ops.code = MULT_EXPR;
1336 ops.type = TREE_TYPE (arg1);
1337 ops.op0 = make_tree (ops.type, op0);
1338 ops.op1 = make_tree (ops.type, op1);
1339 ops.op2 = NULL_TREE;
1340 ops.location = loc;
1341 res = expand_expr_real_2 (&ops, NULL_RTX, mode, EXPAND_NORMAL);
1342 do_compare_rtx_and_jump (op1, const0_rtx, EQ, true, mode, NULL_RTX,
1343 NULL, done_label, profile_probability::very_likely ());
1344 goto do_error_label;
1345 case 3:
1346 rtx_code_label *do_main_label;
1347 do_main_label = gen_label_rtx ();
1348 do_compare_rtx_and_jump (op0, const0_rtx, GE, false, mode, NULL_RTX,
1349 NULL, do_main_label, profile_probability::very_likely ());
1350 do_compare_rtx_and_jump (op1, const0_rtx, EQ, true, mode, NULL_RTX,
1351 NULL, do_main_label, profile_probability::very_likely ());
1352 expand_arith_set_overflow (lhs, target);
1353 emit_label (do_main_label);
1354 goto do_main;
1355 default:
1356 gcc_unreachable ();
1360 /* u1 * u2 -> sr */
1361 if (uns0_p && uns1_p && !unsr_p)
1363 uns = true;
1364 /* Rest of handling of this case after res is computed. */
1365 goto do_main;
1368 /* s1 * u2 -> sr */
1369 if (!uns0_p && uns1_p && !unsr_p)
1371 switch (pos_neg1)
1373 case 1:
1374 goto do_main;
1375 case 2:
1376 /* If (S) u2 is negative (i.e. u2 is larger than maximum of S,
1377 avoid the main code, just multiply and signal overflow
1378 unless 0 * u2 or -1 * ((U) Smin). */
1379 struct separate_ops ops;
1380 ops.code = MULT_EXPR;
1381 ops.type = TREE_TYPE (arg1);
1382 ops.op0 = make_tree (ops.type, op0);
1383 ops.op1 = make_tree (ops.type, op1);
1384 ops.op2 = NULL_TREE;
1385 ops.location = loc;
1386 res = expand_expr_real_2 (&ops, NULL_RTX, mode, EXPAND_NORMAL);
1387 do_compare_rtx_and_jump (op0, const0_rtx, EQ, true, mode, NULL_RTX,
1388 NULL, done_label, profile_probability::very_likely ());
1389 do_compare_rtx_and_jump (op0, constm1_rtx, NE, true, mode, NULL_RTX,
1390 NULL, do_error, profile_probability::very_unlikely ());
1391 int prec;
1392 prec = GET_MODE_PRECISION (mode);
1393 rtx sgn;
1394 sgn = immed_wide_int_const (wi::min_value (prec, SIGNED), mode);
1395 do_compare_rtx_and_jump (op1, sgn, EQ, true, mode, NULL_RTX,
1396 NULL, done_label, profile_probability::very_likely ());
1397 goto do_error_label;
1398 case 3:
1399 /* Rest of handling of this case after res is computed. */
1400 goto do_main;
1401 default:
1402 gcc_unreachable ();
1406 /* s1 * s2 -> ur */
1407 if (!uns0_p && !uns1_p && unsr_p)
1409 rtx tem, tem2;
1410 switch (pos_neg0 | pos_neg1)
1412 case 1: /* Both operands known to be non-negative. */
1413 goto do_main;
1414 case 2: /* Both operands known to be negative. */
1415 op0 = expand_unop (mode, neg_optab, op0, NULL_RTX, false);
1416 op1 = expand_unop (mode, neg_optab, op1, NULL_RTX, false);
1417 /* Avoid looking at arg0/arg1 ranges, as we've changed
1418 the arguments. */
1419 arg0 = error_mark_node;
1420 arg1 = error_mark_node;
1421 goto do_main;
1422 case 3:
1423 if ((pos_neg0 ^ pos_neg1) == 3)
1425 /* If one operand is known to be negative and the other
1426 non-negative, this overflows always, unless the non-negative
1427 one is 0. Just do normal multiply and set overflow
1428 unless one of the operands is 0. */
1429 struct separate_ops ops;
1430 ops.code = MULT_EXPR;
1431 ops.type
1432 = build_nonstandard_integer_type (GET_MODE_PRECISION (mode),
1434 ops.op0 = make_tree (ops.type, op0);
1435 ops.op1 = make_tree (ops.type, op1);
1436 ops.op2 = NULL_TREE;
1437 ops.location = loc;
1438 res = expand_expr_real_2 (&ops, NULL_RTX, mode, EXPAND_NORMAL);
1439 tem = expand_binop (mode, and_optab, op0, op1, NULL_RTX, false,
1440 OPTAB_LIB_WIDEN);
1441 do_compare_rtx_and_jump (tem, const0_rtx, EQ, true, mode,
1442 NULL_RTX, NULL, done_label,
1443 profile_probability::very_likely ());
1444 goto do_error_label;
1446 /* The general case, do all the needed comparisons at runtime. */
1447 rtx_code_label *do_main_label, *after_negate_label;
1448 rtx rop0, rop1;
1449 rop0 = gen_reg_rtx (mode);
1450 rop1 = gen_reg_rtx (mode);
1451 emit_move_insn (rop0, op0);
1452 emit_move_insn (rop1, op1);
1453 op0 = rop0;
1454 op1 = rop1;
1455 do_main_label = gen_label_rtx ();
1456 after_negate_label = gen_label_rtx ();
1457 tem = expand_binop (mode, and_optab, op0, op1, NULL_RTX, false,
1458 OPTAB_LIB_WIDEN);
1459 do_compare_rtx_and_jump (tem, const0_rtx, GE, false, mode, NULL_RTX,
1460 NULL, after_negate_label, profile_probability::very_likely ());
1461 /* Both arguments negative here, negate them and continue with
1462 normal unsigned overflow checking multiplication. */
1463 emit_move_insn (op0, expand_unop (mode, neg_optab, op0,
1464 NULL_RTX, false));
1465 emit_move_insn (op1, expand_unop (mode, neg_optab, op1,
1466 NULL_RTX, false));
1467 /* Avoid looking at arg0/arg1 ranges, as we might have changed
1468 the arguments. */
1469 arg0 = error_mark_node;
1470 arg1 = error_mark_node;
1471 emit_jump (do_main_label);
1472 emit_label (after_negate_label);
1473 tem2 = expand_binop (mode, xor_optab, op0, op1, NULL_RTX, false,
1474 OPTAB_LIB_WIDEN);
1475 do_compare_rtx_and_jump (tem2, const0_rtx, GE, false, mode, NULL_RTX,
1476 NULL, do_main_label, profile_probability::very_likely ());
1477 /* One argument is negative here, the other positive. This
1478 overflows always, unless one of the arguments is 0. But
1479 if e.g. s2 is 0, (U) s1 * 0 doesn't overflow, whatever s1
1480 is, thus we can keep do_main code oring in overflow as is. */
1481 do_compare_rtx_and_jump (tem, const0_rtx, EQ, true, mode, NULL_RTX,
1482 NULL, do_main_label, profile_probability::very_likely ());
1483 expand_arith_set_overflow (lhs, target);
1484 emit_label (do_main_label);
1485 goto do_main;
1486 default:
1487 gcc_unreachable ();
1491 do_main:
1492 type = build_nonstandard_integer_type (GET_MODE_PRECISION (mode), uns);
1493 sign = uns ? UNSIGNED : SIGNED;
1494 icode = optab_handler (uns ? umulv4_optab : mulv4_optab, mode);
1495 if (uns
1496 && (integer_pow2p (arg0) || integer_pow2p (arg1))
1497 && (optimize_insn_for_speed_p () || icode == CODE_FOR_nothing))
1499 /* Optimize unsigned multiplication by power of 2 constant
1500 using 2 shifts, one for result, one to extract the shifted
1501 out bits to see if they are all zero.
1502 Don't do this if optimizing for size and we have umulv4_optab,
1503 in that case assume multiplication will be shorter.
1504 This is heuristics based on the single target that provides
1505 umulv4 right now (i?86/x86_64), if further targets add it, this
1506 might need to be revisited.
1507 Cases where both operands are constant should be folded already
1508 during GIMPLE, and cases where one operand is constant but not
1509 power of 2 are questionable, either the WIDEN_MULT_EXPR case
1510 below can be done without multiplication, just by shifts and adds,
1511 or we'd need to divide the result (and hope it actually doesn't
1512 really divide nor multiply) and compare the result of the division
1513 with the original operand. */
1514 rtx opn0 = op0;
1515 rtx opn1 = op1;
1516 tree argn0 = arg0;
1517 tree argn1 = arg1;
1518 if (integer_pow2p (arg0))
1520 std::swap (opn0, opn1);
1521 std::swap (argn0, argn1);
1523 int cnt = tree_log2 (argn1);
1524 if (cnt >= 0 && cnt < GET_MODE_PRECISION (mode))
1526 rtx upper = const0_rtx;
1527 res = expand_shift (LSHIFT_EXPR, mode, opn0, cnt, NULL_RTX, uns);
1528 if (cnt != 0)
1529 upper = expand_shift (RSHIFT_EXPR, mode, opn0,
1530 GET_MODE_PRECISION (mode) - cnt,
1531 NULL_RTX, uns);
1532 do_compare_rtx_and_jump (upper, const0_rtx, EQ, true, mode,
1533 NULL_RTX, NULL, done_label,
1534 profile_probability::very_likely ());
1535 goto do_error_label;
1538 if (icode != CODE_FOR_nothing)
1540 struct expand_operand ops[4];
1541 rtx_insn *last = get_last_insn ();
1543 res = gen_reg_rtx (mode);
1544 create_output_operand (&ops[0], res, mode);
1545 create_input_operand (&ops[1], op0, mode);
1546 create_input_operand (&ops[2], op1, mode);
1547 create_fixed_operand (&ops[3], do_error);
1548 if (maybe_expand_insn (icode, 4, ops))
1550 last = get_last_insn ();
1551 if (profile_status_for_fn (cfun) != PROFILE_ABSENT
1552 && JUMP_P (last)
1553 && any_condjump_p (last)
1554 && !find_reg_note (last, REG_BR_PROB, 0))
1555 add_reg_br_prob_note (last,
1556 profile_probability::very_unlikely ());
1557 emit_jump (done_label);
1559 else
1561 delete_insns_since (last);
1562 icode = CODE_FOR_nothing;
1566 if (icode == CODE_FOR_nothing)
1568 struct separate_ops ops;
1569 int prec = GET_MODE_PRECISION (mode);
1570 scalar_int_mode hmode, wmode;
1571 ops.op0 = make_tree (type, op0);
1572 ops.op1 = make_tree (type, op1);
1573 ops.op2 = NULL_TREE;
1574 ops.location = loc;
1576 /* Optimize unsigned overflow check where we don't use the
1577 multiplication result, just whether overflow happened.
1578 If we can do MULT_HIGHPART_EXPR, that followed by
1579 comparison of the result against zero is cheapest.
1580 We'll still compute res, but it should be DCEd later. */
1581 use_operand_p use;
1582 gimple *use_stmt;
1583 if (!is_ubsan
1584 && lhs
1585 && uns
1586 && !(uns0_p && uns1_p && !unsr_p)
1587 && can_mult_highpart_p (mode, uns) == 1
1588 && single_imm_use (lhs, &use, &use_stmt)
1589 && is_gimple_assign (use_stmt)
1590 && gimple_assign_rhs_code (use_stmt) == IMAGPART_EXPR)
1591 goto highpart;
1593 if (GET_MODE_2XWIDER_MODE (mode).exists (&wmode)
1594 && targetm.scalar_mode_supported_p (wmode)
1595 && can_widen_mult_without_libcall (wmode, mode, op0, op1, uns))
1597 twoxwider:
1598 ops.code = WIDEN_MULT_EXPR;
1599 ops.type
1600 = build_nonstandard_integer_type (GET_MODE_PRECISION (wmode), uns);
1602 res = expand_expr_real_2 (&ops, NULL_RTX, wmode, EXPAND_NORMAL);
1603 rtx hipart = expand_shift (RSHIFT_EXPR, wmode, res, prec,
1604 NULL_RTX, uns);
1605 hipart = convert_modes (mode, wmode, hipart, uns);
1606 res = convert_modes (mode, wmode, res, uns);
1607 if (uns)
1608 /* For the unsigned multiplication, there was overflow if
1609 HIPART is non-zero. */
1610 do_compare_rtx_and_jump (hipart, const0_rtx, EQ, true, mode,
1611 NULL_RTX, NULL, done_label,
1612 profile_probability::very_likely ());
1613 else
1615 rtx signbit = expand_shift (RSHIFT_EXPR, mode, res, prec - 1,
1616 NULL_RTX, 0);
1617 /* RES is low half of the double width result, HIPART
1618 the high half. There was overflow if
1619 HIPART is different from RES < 0 ? -1 : 0. */
1620 do_compare_rtx_and_jump (signbit, hipart, EQ, true, mode,
1621 NULL_RTX, NULL, done_label,
1622 profile_probability::very_likely ());
1625 else if (can_mult_highpart_p (mode, uns) == 1)
1627 highpart:
1628 ops.code = MULT_HIGHPART_EXPR;
1629 ops.type = type;
1631 rtx hipart = expand_expr_real_2 (&ops, NULL_RTX, mode,
1632 EXPAND_NORMAL);
1633 ops.code = MULT_EXPR;
1634 res = expand_expr_real_2 (&ops, NULL_RTX, mode, EXPAND_NORMAL);
1635 if (uns)
1636 /* For the unsigned multiplication, there was overflow if
1637 HIPART is non-zero. */
1638 do_compare_rtx_and_jump (hipart, const0_rtx, EQ, true, mode,
1639 NULL_RTX, NULL, done_label,
1640 profile_probability::very_likely ());
1641 else
1643 rtx signbit = expand_shift (RSHIFT_EXPR, mode, res, prec - 1,
1644 NULL_RTX, 0);
1645 /* RES is low half of the double width result, HIPART
1646 the high half. There was overflow if
1647 HIPART is different from RES < 0 ? -1 : 0. */
1648 do_compare_rtx_and_jump (signbit, hipart, EQ, true, mode,
1649 NULL_RTX, NULL, done_label,
1650 profile_probability::very_likely ());
1654 else if (int_mode_for_size (prec / 2, 1).exists (&hmode)
1655 && 2 * GET_MODE_PRECISION (hmode) == prec)
1657 rtx_code_label *large_op0 = gen_label_rtx ();
1658 rtx_code_label *small_op0_large_op1 = gen_label_rtx ();
1659 rtx_code_label *one_small_one_large = gen_label_rtx ();
1660 rtx_code_label *both_ops_large = gen_label_rtx ();
1661 rtx_code_label *after_hipart_neg = uns ? NULL : gen_label_rtx ();
1662 rtx_code_label *after_lopart_neg = uns ? NULL : gen_label_rtx ();
1663 rtx_code_label *do_overflow = gen_label_rtx ();
1664 rtx_code_label *hipart_different = uns ? NULL : gen_label_rtx ();
1666 unsigned int hprec = GET_MODE_PRECISION (hmode);
1667 rtx hipart0 = expand_shift (RSHIFT_EXPR, mode, op0, hprec,
1668 NULL_RTX, uns);
1669 hipart0 = convert_modes (hmode, mode, hipart0, uns);
1670 rtx lopart0 = convert_modes (hmode, mode, op0, uns);
1671 rtx signbit0 = const0_rtx;
1672 if (!uns)
1673 signbit0 = expand_shift (RSHIFT_EXPR, hmode, lopart0, hprec - 1,
1674 NULL_RTX, 0);
1675 rtx hipart1 = expand_shift (RSHIFT_EXPR, mode, op1, hprec,
1676 NULL_RTX, uns);
1677 hipart1 = convert_modes (hmode, mode, hipart1, uns);
1678 rtx lopart1 = convert_modes (hmode, mode, op1, uns);
1679 rtx signbit1 = const0_rtx;
1680 if (!uns)
1681 signbit1 = expand_shift (RSHIFT_EXPR, hmode, lopart1, hprec - 1,
1682 NULL_RTX, 0);
1684 res = gen_reg_rtx (mode);
1686 /* True if op0 resp. op1 are known to be in the range of
1687 halfstype. */
1688 bool op0_small_p = false;
1689 bool op1_small_p = false;
1690 /* True if op0 resp. op1 are known to have all zeros or all ones
1691 in the upper half of bits, but are not known to be
1692 op{0,1}_small_p. */
1693 bool op0_medium_p = false;
1694 bool op1_medium_p = false;
1695 /* -1 if op{0,1} is known to be negative, 0 if it is known to be
1696 nonnegative, 1 if unknown. */
1697 int op0_sign = 1;
1698 int op1_sign = 1;
1700 if (pos_neg0 == 1)
1701 op0_sign = 0;
1702 else if (pos_neg0 == 2)
1703 op0_sign = -1;
1704 if (pos_neg1 == 1)
1705 op1_sign = 0;
1706 else if (pos_neg1 == 2)
1707 op1_sign = -1;
1709 unsigned int mprec0 = prec;
1710 if (arg0 != error_mark_node)
1711 mprec0 = get_min_precision (arg0, sign);
1712 if (mprec0 <= hprec)
1713 op0_small_p = true;
1714 else if (!uns && mprec0 <= hprec + 1)
1715 op0_medium_p = true;
1716 unsigned int mprec1 = prec;
1717 if (arg1 != error_mark_node)
1718 mprec1 = get_min_precision (arg1, sign);
1719 if (mprec1 <= hprec)
1720 op1_small_p = true;
1721 else if (!uns && mprec1 <= hprec + 1)
1722 op1_medium_p = true;
1724 int smaller_sign = 1;
1725 int larger_sign = 1;
1726 if (op0_small_p)
1728 smaller_sign = op0_sign;
1729 larger_sign = op1_sign;
1731 else if (op1_small_p)
1733 smaller_sign = op1_sign;
1734 larger_sign = op0_sign;
1736 else if (op0_sign == op1_sign)
1738 smaller_sign = op0_sign;
1739 larger_sign = op0_sign;
1742 if (!op0_small_p)
1743 do_compare_rtx_and_jump (signbit0, hipart0, NE, true, hmode,
1744 NULL_RTX, NULL, large_op0,
1745 profile_probability::unlikely ());
1747 if (!op1_small_p)
1748 do_compare_rtx_and_jump (signbit1, hipart1, NE, true, hmode,
1749 NULL_RTX, NULL, small_op0_large_op1,
1750 profile_probability::unlikely ());
1752 /* If both op0 and op1 are sign (!uns) or zero (uns) extended from
1753 hmode to mode, the multiplication will never overflow. We can
1754 do just one hmode x hmode => mode widening multiplication. */
1755 rtx lopart0s = lopart0, lopart1s = lopart1;
1756 if (GET_CODE (lopart0) == SUBREG)
1758 lopart0s = shallow_copy_rtx (lopart0);
1759 SUBREG_PROMOTED_VAR_P (lopart0s) = 1;
1760 SUBREG_PROMOTED_SET (lopart0s, uns ? SRP_UNSIGNED : SRP_SIGNED);
1762 if (GET_CODE (lopart1) == SUBREG)
1764 lopart1s = shallow_copy_rtx (lopart1);
1765 SUBREG_PROMOTED_VAR_P (lopart1s) = 1;
1766 SUBREG_PROMOTED_SET (lopart1s, uns ? SRP_UNSIGNED : SRP_SIGNED);
1768 tree halfstype = build_nonstandard_integer_type (hprec, uns);
1769 ops.op0 = make_tree (halfstype, lopart0s);
1770 ops.op1 = make_tree (halfstype, lopart1s);
1771 ops.code = WIDEN_MULT_EXPR;
1772 ops.type = type;
1773 rtx thisres
1774 = expand_expr_real_2 (&ops, NULL_RTX, mode, EXPAND_NORMAL);
1775 emit_move_insn (res, thisres);
1776 emit_jump (done_label);
1778 emit_label (small_op0_large_op1);
1780 /* If op0 is sign (!uns) or zero (uns) extended from hmode to mode,
1781 but op1 is not, just swap the arguments and handle it as op1
1782 sign/zero extended, op0 not. */
1783 rtx larger = gen_reg_rtx (mode);
1784 rtx hipart = gen_reg_rtx (hmode);
1785 rtx lopart = gen_reg_rtx (hmode);
1786 emit_move_insn (larger, op1);
1787 emit_move_insn (hipart, hipart1);
1788 emit_move_insn (lopart, lopart0);
1789 emit_jump (one_small_one_large);
1791 emit_label (large_op0);
1793 if (!op1_small_p)
1794 do_compare_rtx_and_jump (signbit1, hipart1, NE, true, hmode,
1795 NULL_RTX, NULL, both_ops_large,
1796 profile_probability::unlikely ());
1798 /* If op1 is sign (!uns) or zero (uns) extended from hmode to mode,
1799 but op0 is not, prepare larger, hipart and lopart pseudos and
1800 handle it together with small_op0_large_op1. */
1801 emit_move_insn (larger, op0);
1802 emit_move_insn (hipart, hipart0);
1803 emit_move_insn (lopart, lopart1);
1805 emit_label (one_small_one_large);
1807 /* lopart is the low part of the operand that is sign extended
1808 to mode, larger is the other operand, hipart is the
1809 high part of larger and lopart0 and lopart1 are the low parts
1810 of both operands.
1811 We perform lopart0 * lopart1 and lopart * hipart widening
1812 multiplications. */
1813 tree halfutype = build_nonstandard_integer_type (hprec, 1);
1814 ops.op0 = make_tree (halfutype, lopart0);
1815 ops.op1 = make_tree (halfutype, lopart1);
1816 rtx lo0xlo1
1817 = expand_expr_real_2 (&ops, NULL_RTX, mode, EXPAND_NORMAL);
1819 ops.op0 = make_tree (halfutype, lopart);
1820 ops.op1 = make_tree (halfutype, hipart);
1821 rtx loxhi = gen_reg_rtx (mode);
1822 rtx tem = expand_expr_real_2 (&ops, NULL_RTX, mode, EXPAND_NORMAL);
1823 emit_move_insn (loxhi, tem);
1825 if (!uns)
1827 /* if (hipart < 0) loxhi -= lopart << (bitsize / 2); */
1828 if (larger_sign == 0)
1829 emit_jump (after_hipart_neg);
1830 else if (larger_sign != -1)
1831 do_compare_rtx_and_jump (hipart, const0_rtx, GE, false, hmode,
1832 NULL_RTX, NULL, after_hipart_neg,
1833 profile_probability::even ());
1835 tem = convert_modes (mode, hmode, lopart, 1);
1836 tem = expand_shift (LSHIFT_EXPR, mode, tem, hprec, NULL_RTX, 1);
1837 tem = expand_simple_binop (mode, MINUS, loxhi, tem, NULL_RTX,
1838 1, OPTAB_WIDEN);
1839 emit_move_insn (loxhi, tem);
1841 emit_label (after_hipart_neg);
1843 /* if (lopart < 0) loxhi -= larger; */
1844 if (smaller_sign == 0)
1845 emit_jump (after_lopart_neg);
1846 else if (smaller_sign != -1)
1847 do_compare_rtx_and_jump (lopart, const0_rtx, GE, false, hmode,
1848 NULL_RTX, NULL, after_lopart_neg,
1849 profile_probability::even ());
1851 tem = expand_simple_binop (mode, MINUS, loxhi, larger, NULL_RTX,
1852 1, OPTAB_WIDEN);
1853 emit_move_insn (loxhi, tem);
1855 emit_label (after_lopart_neg);
1858 /* loxhi += (uns) lo0xlo1 >> (bitsize / 2); */
1859 tem = expand_shift (RSHIFT_EXPR, mode, lo0xlo1, hprec, NULL_RTX, 1);
1860 tem = expand_simple_binop (mode, PLUS, loxhi, tem, NULL_RTX,
1861 1, OPTAB_WIDEN);
1862 emit_move_insn (loxhi, tem);
1864 /* if (loxhi >> (bitsize / 2)
1865 == (hmode) loxhi >> (bitsize / 2 - 1)) (if !uns)
1866 if (loxhi >> (bitsize / 2) == 0 (if uns). */
1867 rtx hipartloxhi = expand_shift (RSHIFT_EXPR, mode, loxhi, hprec,
1868 NULL_RTX, 0);
1869 hipartloxhi = convert_modes (hmode, mode, hipartloxhi, 0);
1870 rtx signbitloxhi = const0_rtx;
1871 if (!uns)
1872 signbitloxhi = expand_shift (RSHIFT_EXPR, hmode,
1873 convert_modes (hmode, mode,
1874 loxhi, 0),
1875 hprec - 1, NULL_RTX, 0);
1877 do_compare_rtx_and_jump (signbitloxhi, hipartloxhi, NE, true, hmode,
1878 NULL_RTX, NULL, do_overflow,
1879 profile_probability::very_unlikely ());
1881 /* res = (loxhi << (bitsize / 2)) | (hmode) lo0xlo1; */
1882 rtx loxhishifted = expand_shift (LSHIFT_EXPR, mode, loxhi, hprec,
1883 NULL_RTX, 1);
1884 tem = convert_modes (mode, hmode,
1885 convert_modes (hmode, mode, lo0xlo1, 1), 1);
1887 tem = expand_simple_binop (mode, IOR, loxhishifted, tem, res,
1888 1, OPTAB_WIDEN);
1889 if (tem != res)
1890 emit_move_insn (res, tem);
1891 emit_jump (done_label);
1893 emit_label (both_ops_large);
1895 /* If both operands are large (not sign (!uns) or zero (uns)
1896 extended from hmode), then perform the full multiplication
1897 which will be the result of the operation.
1898 The only cases which don't overflow are for signed multiplication
1899 some cases where both hipart0 and highpart1 are 0 or -1.
1900 For unsigned multiplication when high parts are both non-zero
1901 this overflows always. */
1902 ops.code = MULT_EXPR;
1903 ops.op0 = make_tree (type, op0);
1904 ops.op1 = make_tree (type, op1);
1905 tem = expand_expr_real_2 (&ops, NULL_RTX, mode, EXPAND_NORMAL);
1906 emit_move_insn (res, tem);
1908 if (!uns)
1910 if (!op0_medium_p)
1912 tem = expand_simple_binop (hmode, PLUS, hipart0, const1_rtx,
1913 NULL_RTX, 1, OPTAB_WIDEN);
1914 do_compare_rtx_and_jump (tem, const1_rtx, GTU, true, hmode,
1915 NULL_RTX, NULL, do_error,
1916 profile_probability::very_unlikely ());
1919 if (!op1_medium_p)
1921 tem = expand_simple_binop (hmode, PLUS, hipart1, const1_rtx,
1922 NULL_RTX, 1, OPTAB_WIDEN);
1923 do_compare_rtx_and_jump (tem, const1_rtx, GTU, true, hmode,
1924 NULL_RTX, NULL, do_error,
1925 profile_probability::very_unlikely ());
1928 /* At this point hipart{0,1} are both in [-1, 0]. If they are
1929 the same, overflow happened if res is non-positive, if they
1930 are different, overflow happened if res is positive. */
1931 if (op0_sign != 1 && op1_sign != 1 && op0_sign != op1_sign)
1932 emit_jump (hipart_different);
1933 else if (op0_sign == 1 || op1_sign == 1)
1934 do_compare_rtx_and_jump (hipart0, hipart1, NE, true, hmode,
1935 NULL_RTX, NULL, hipart_different,
1936 profile_probability::even ());
1938 do_compare_rtx_and_jump (res, const0_rtx, LE, false, mode,
1939 NULL_RTX, NULL, do_error,
1940 profile_probability::very_unlikely ());
1941 emit_jump (done_label);
1943 emit_label (hipart_different);
1945 do_compare_rtx_and_jump (res, const0_rtx, GE, false, mode,
1946 NULL_RTX, NULL, do_error,
1947 profile_probability::very_unlikely ());
1948 emit_jump (done_label);
1951 emit_label (do_overflow);
1953 /* Overflow, do full multiplication and fallthru into do_error. */
1954 ops.op0 = make_tree (type, op0);
1955 ops.op1 = make_tree (type, op1);
1956 tem = expand_expr_real_2 (&ops, NULL_RTX, mode, EXPAND_NORMAL);
1957 emit_move_insn (res, tem);
1959 else if (GET_MODE_2XWIDER_MODE (mode).exists (&wmode)
1960 && targetm.scalar_mode_supported_p (wmode))
1961 /* Even emitting a libcall is better than not detecting overflow
1962 at all. */
1963 goto twoxwider;
1964 else
1966 gcc_assert (!is_ubsan);
1967 ops.code = MULT_EXPR;
1968 ops.type = type;
1969 res = expand_expr_real_2 (&ops, NULL_RTX, mode, EXPAND_NORMAL);
1970 emit_jump (done_label);
1974 do_error_label:
1975 emit_label (do_error);
1976 if (is_ubsan)
1978 /* Expand the ubsan builtin call. */
1979 push_temp_slots ();
1980 fn = ubsan_build_overflow_builtin (MULT_EXPR, loc, TREE_TYPE (arg0),
1981 arg0, arg1, datap);
1982 expand_normal (fn);
1983 pop_temp_slots ();
1984 do_pending_stack_adjust ();
1986 else if (lhs)
1987 expand_arith_set_overflow (lhs, target);
1989 /* We're done. */
1990 emit_label (done_label);
1992 /* u1 * u2 -> sr */
1993 if (uns0_p && uns1_p && !unsr_p)
1995 rtx_code_label *all_done_label = gen_label_rtx ();
1996 do_compare_rtx_and_jump (res, const0_rtx, GE, false, mode, NULL_RTX,
1997 NULL, all_done_label, profile_probability::very_likely ());
1998 expand_arith_set_overflow (lhs, target);
1999 emit_label (all_done_label);
2002 /* s1 * u2 -> sr */
2003 if (!uns0_p && uns1_p && !unsr_p && pos_neg1 == 3)
2005 rtx_code_label *all_done_label = gen_label_rtx ();
2006 rtx_code_label *set_noovf = gen_label_rtx ();
2007 do_compare_rtx_and_jump (op1, const0_rtx, GE, false, mode, NULL_RTX,
2008 NULL, all_done_label, profile_probability::very_likely ());
2009 expand_arith_set_overflow (lhs, target);
2010 do_compare_rtx_and_jump (op0, const0_rtx, EQ, true, mode, NULL_RTX,
2011 NULL, set_noovf, profile_probability::very_likely ());
2012 do_compare_rtx_and_jump (op0, constm1_rtx, NE, true, mode, NULL_RTX,
2013 NULL, all_done_label, profile_probability::very_unlikely ());
2014 do_compare_rtx_and_jump (op1, res, NE, true, mode, NULL_RTX, NULL,
2015 all_done_label, profile_probability::very_unlikely ());
2016 emit_label (set_noovf);
2017 write_complex_part (target, const0_rtx, true);
2018 emit_label (all_done_label);
2021 if (lhs)
2023 if (is_ubsan)
2024 expand_ubsan_result_store (target, res);
2025 else
2026 expand_arith_overflow_result_store (lhs, target, mode, res);
2030 /* Expand UBSAN_CHECK_* internal function if it has vector operands. */
2032 static void
2033 expand_vector_ubsan_overflow (location_t loc, enum tree_code code, tree lhs,
2034 tree arg0, tree arg1)
2036 poly_uint64 cnt = TYPE_VECTOR_SUBPARTS (TREE_TYPE (arg0));
2037 rtx_code_label *loop_lab = NULL;
2038 rtx cntvar = NULL_RTX;
2039 tree cntv = NULL_TREE;
2040 tree eltype = TREE_TYPE (TREE_TYPE (arg0));
2041 tree sz = TYPE_SIZE (eltype);
2042 tree data = NULL_TREE;
2043 tree resv = NULL_TREE;
2044 rtx lhsr = NULL_RTX;
2045 rtx resvr = NULL_RTX;
2046 unsigned HOST_WIDE_INT const_cnt = 0;
2047 bool use_loop_p = (!cnt.is_constant (&const_cnt) || const_cnt > 4);
2049 if (lhs)
2051 optab op;
2052 lhsr = expand_expr (lhs, NULL_RTX, VOIDmode, EXPAND_WRITE);
2053 if (!VECTOR_MODE_P (GET_MODE (lhsr))
2054 || (op = optab_for_tree_code (code, TREE_TYPE (arg0),
2055 optab_default)) == unknown_optab
2056 || (optab_handler (op, TYPE_MODE (TREE_TYPE (arg0)))
2057 == CODE_FOR_nothing))
2059 if (MEM_P (lhsr))
2060 resv = make_tree (TREE_TYPE (lhs), lhsr);
2061 else
2063 resvr = assign_temp (TREE_TYPE (lhs), 1, 1);
2064 resv = make_tree (TREE_TYPE (lhs), resvr);
2068 if (use_loop_p)
2070 do_pending_stack_adjust ();
2071 loop_lab = gen_label_rtx ();
2072 cntvar = gen_reg_rtx (TYPE_MODE (sizetype));
2073 cntv = make_tree (sizetype, cntvar);
2074 emit_move_insn (cntvar, const0_rtx);
2075 emit_label (loop_lab);
2077 if (TREE_CODE (arg0) != VECTOR_CST)
2079 rtx arg0r = expand_normal (arg0);
2080 arg0 = make_tree (TREE_TYPE (arg0), arg0r);
2082 if (TREE_CODE (arg1) != VECTOR_CST)
2084 rtx arg1r = expand_normal (arg1);
2085 arg1 = make_tree (TREE_TYPE (arg1), arg1r);
2087 for (unsigned int i = 0; i < (use_loop_p ? 1 : const_cnt); i++)
2089 tree op0, op1, res = NULL_TREE;
2090 if (use_loop_p)
2092 tree atype = build_array_type_nelts (eltype, cnt);
2093 op0 = uniform_vector_p (arg0);
2094 if (op0 == NULL_TREE)
2096 op0 = fold_build1_loc (loc, VIEW_CONVERT_EXPR, atype, arg0);
2097 op0 = build4_loc (loc, ARRAY_REF, eltype, op0, cntv,
2098 NULL_TREE, NULL_TREE);
2100 op1 = uniform_vector_p (arg1);
2101 if (op1 == NULL_TREE)
2103 op1 = fold_build1_loc (loc, VIEW_CONVERT_EXPR, atype, arg1);
2104 op1 = build4_loc (loc, ARRAY_REF, eltype, op1, cntv,
2105 NULL_TREE, NULL_TREE);
2107 if (resv)
2109 res = fold_build1_loc (loc, VIEW_CONVERT_EXPR, atype, resv);
2110 res = build4_loc (loc, ARRAY_REF, eltype, res, cntv,
2111 NULL_TREE, NULL_TREE);
2114 else
2116 tree bitpos = bitsize_int (tree_to_uhwi (sz) * i);
2117 op0 = fold_build3_loc (loc, BIT_FIELD_REF, eltype, arg0, sz, bitpos);
2118 op1 = fold_build3_loc (loc, BIT_FIELD_REF, eltype, arg1, sz, bitpos);
2119 if (resv)
2120 res = fold_build3_loc (loc, BIT_FIELD_REF, eltype, resv, sz,
2121 bitpos);
2123 switch (code)
2125 case PLUS_EXPR:
2126 expand_addsub_overflow (loc, PLUS_EXPR, res, op0, op1,
2127 false, false, false, true, &data);
2128 break;
2129 case MINUS_EXPR:
2130 if (use_loop_p ? integer_zerop (arg0) : integer_zerop (op0))
2131 expand_neg_overflow (loc, res, op1, true, &data);
2132 else
2133 expand_addsub_overflow (loc, MINUS_EXPR, res, op0, op1,
2134 false, false, false, true, &data);
2135 break;
2136 case MULT_EXPR:
2137 expand_mul_overflow (loc, res, op0, op1, false, false, false,
2138 true, &data);
2139 break;
2140 default:
2141 gcc_unreachable ();
2144 if (use_loop_p)
2146 struct separate_ops ops;
2147 ops.code = PLUS_EXPR;
2148 ops.type = TREE_TYPE (cntv);
2149 ops.op0 = cntv;
2150 ops.op1 = build_int_cst (TREE_TYPE (cntv), 1);
2151 ops.op2 = NULL_TREE;
2152 ops.location = loc;
2153 rtx ret = expand_expr_real_2 (&ops, cntvar, TYPE_MODE (sizetype),
2154 EXPAND_NORMAL);
2155 if (ret != cntvar)
2156 emit_move_insn (cntvar, ret);
2157 rtx cntrtx = gen_int_mode (cnt, TYPE_MODE (sizetype));
2158 do_compare_rtx_and_jump (cntvar, cntrtx, NE, false,
2159 TYPE_MODE (sizetype), NULL_RTX, NULL, loop_lab,
2160 profile_probability::very_likely ());
2162 if (lhs && resv == NULL_TREE)
2164 struct separate_ops ops;
2165 ops.code = code;
2166 ops.type = TREE_TYPE (arg0);
2167 ops.op0 = arg0;
2168 ops.op1 = arg1;
2169 ops.op2 = NULL_TREE;
2170 ops.location = loc;
2171 rtx ret = expand_expr_real_2 (&ops, lhsr, TYPE_MODE (TREE_TYPE (arg0)),
2172 EXPAND_NORMAL);
2173 if (ret != lhsr)
2174 emit_move_insn (lhsr, ret);
2176 else if (resvr)
2177 emit_move_insn (lhsr, resvr);
2180 /* Expand UBSAN_CHECK_ADD call STMT. */
2182 static void
2183 expand_UBSAN_CHECK_ADD (internal_fn, gcall *stmt)
2185 location_t loc = gimple_location (stmt);
2186 tree lhs = gimple_call_lhs (stmt);
2187 tree arg0 = gimple_call_arg (stmt, 0);
2188 tree arg1 = gimple_call_arg (stmt, 1);
2189 if (VECTOR_TYPE_P (TREE_TYPE (arg0)))
2190 expand_vector_ubsan_overflow (loc, PLUS_EXPR, lhs, arg0, arg1);
2191 else
2192 expand_addsub_overflow (loc, PLUS_EXPR, lhs, arg0, arg1,
2193 false, false, false, true, NULL);
2196 /* Expand UBSAN_CHECK_SUB call STMT. */
2198 static void
2199 expand_UBSAN_CHECK_SUB (internal_fn, gcall *stmt)
2201 location_t loc = gimple_location (stmt);
2202 tree lhs = gimple_call_lhs (stmt);
2203 tree arg0 = gimple_call_arg (stmt, 0);
2204 tree arg1 = gimple_call_arg (stmt, 1);
2205 if (VECTOR_TYPE_P (TREE_TYPE (arg0)))
2206 expand_vector_ubsan_overflow (loc, MINUS_EXPR, lhs, arg0, arg1);
2207 else if (integer_zerop (arg0))
2208 expand_neg_overflow (loc, lhs, arg1, true, NULL);
2209 else
2210 expand_addsub_overflow (loc, MINUS_EXPR, lhs, arg0, arg1,
2211 false, false, false, true, NULL);
2214 /* Expand UBSAN_CHECK_MUL call STMT. */
2216 static void
2217 expand_UBSAN_CHECK_MUL (internal_fn, gcall *stmt)
2219 location_t loc = gimple_location (stmt);
2220 tree lhs = gimple_call_lhs (stmt);
2221 tree arg0 = gimple_call_arg (stmt, 0);
2222 tree arg1 = gimple_call_arg (stmt, 1);
2223 if (VECTOR_TYPE_P (TREE_TYPE (arg0)))
2224 expand_vector_ubsan_overflow (loc, MULT_EXPR, lhs, arg0, arg1);
2225 else
2226 expand_mul_overflow (loc, lhs, arg0, arg1, false, false, false, true,
2227 NULL);
2230 /* Helper function for {ADD,SUB,MUL}_OVERFLOW call stmt expansion. */
2232 static void
2233 expand_arith_overflow (enum tree_code code, gimple *stmt)
2235 tree lhs = gimple_call_lhs (stmt);
2236 if (lhs == NULL_TREE)
2237 return;
2238 tree arg0 = gimple_call_arg (stmt, 0);
2239 tree arg1 = gimple_call_arg (stmt, 1);
2240 tree type = TREE_TYPE (TREE_TYPE (lhs));
2241 int uns0_p = TYPE_UNSIGNED (TREE_TYPE (arg0));
2242 int uns1_p = TYPE_UNSIGNED (TREE_TYPE (arg1));
2243 int unsr_p = TYPE_UNSIGNED (type);
2244 int prec0 = TYPE_PRECISION (TREE_TYPE (arg0));
2245 int prec1 = TYPE_PRECISION (TREE_TYPE (arg1));
2246 int precres = TYPE_PRECISION (type);
2247 location_t loc = gimple_location (stmt);
2248 if (!uns0_p && get_range_pos_neg (arg0) == 1)
2249 uns0_p = true;
2250 if (!uns1_p && get_range_pos_neg (arg1) == 1)
2251 uns1_p = true;
2252 int pr = get_min_precision (arg0, uns0_p ? UNSIGNED : SIGNED);
2253 prec0 = MIN (prec0, pr);
2254 pr = get_min_precision (arg1, uns1_p ? UNSIGNED : SIGNED);
2255 prec1 = MIN (prec1, pr);
2257 /* If uns0_p && uns1_p, precop is minimum needed precision
2258 of unsigned type to hold the exact result, otherwise
2259 precop is minimum needed precision of signed type to
2260 hold the exact result. */
2261 int precop;
2262 if (code == MULT_EXPR)
2263 precop = prec0 + prec1 + (uns0_p != uns1_p);
2264 else
2266 if (uns0_p == uns1_p)
2267 precop = MAX (prec0, prec1) + 1;
2268 else if (uns0_p)
2269 precop = MAX (prec0 + 1, prec1) + 1;
2270 else
2271 precop = MAX (prec0, prec1 + 1) + 1;
2273 int orig_precres = precres;
2277 if ((uns0_p && uns1_p)
2278 ? ((precop + !unsr_p) <= precres
2279 /* u1 - u2 -> ur can overflow, no matter what precision
2280 the result has. */
2281 && (code != MINUS_EXPR || !unsr_p))
2282 : (!unsr_p && precop <= precres))
2284 /* The infinity precision result will always fit into result. */
2285 rtx target = expand_expr (lhs, NULL_RTX, VOIDmode, EXPAND_WRITE);
2286 write_complex_part (target, const0_rtx, true);
2287 scalar_int_mode mode = SCALAR_INT_TYPE_MODE (type);
2288 struct separate_ops ops;
2289 ops.code = code;
2290 ops.type = type;
2291 ops.op0 = fold_convert_loc (loc, type, arg0);
2292 ops.op1 = fold_convert_loc (loc, type, arg1);
2293 ops.op2 = NULL_TREE;
2294 ops.location = loc;
2295 rtx tem = expand_expr_real_2 (&ops, NULL_RTX, mode, EXPAND_NORMAL);
2296 expand_arith_overflow_result_store (lhs, target, mode, tem);
2297 return;
2300 /* For operations with low precision, if target doesn't have them, start
2301 with precres widening right away, otherwise do it only if the most
2302 simple cases can't be used. */
2303 const int min_precision = targetm.min_arithmetic_precision ();
2304 if (orig_precres == precres && precres < min_precision)
2306 else if ((uns0_p && uns1_p && unsr_p && prec0 <= precres
2307 && prec1 <= precres)
2308 || ((!uns0_p || !uns1_p) && !unsr_p
2309 && prec0 + uns0_p <= precres
2310 && prec1 + uns1_p <= precres))
2312 arg0 = fold_convert_loc (loc, type, arg0);
2313 arg1 = fold_convert_loc (loc, type, arg1);
2314 switch (code)
2316 case MINUS_EXPR:
2317 if (integer_zerop (arg0) && !unsr_p)
2319 expand_neg_overflow (loc, lhs, arg1, false, NULL);
2320 return;
2322 /* FALLTHRU */
2323 case PLUS_EXPR:
2324 expand_addsub_overflow (loc, code, lhs, arg0, arg1, unsr_p,
2325 unsr_p, unsr_p, false, NULL);
2326 return;
2327 case MULT_EXPR:
2328 expand_mul_overflow (loc, lhs, arg0, arg1, unsr_p,
2329 unsr_p, unsr_p, false, NULL);
2330 return;
2331 default:
2332 gcc_unreachable ();
2336 /* For sub-word operations, retry with a wider type first. */
2337 if (orig_precres == precres && precop <= BITS_PER_WORD)
2339 int p = MAX (min_precision, precop);
2340 scalar_int_mode m = smallest_int_mode_for_size (p);
2341 tree optype = build_nonstandard_integer_type (GET_MODE_PRECISION (m),
2342 uns0_p && uns1_p
2343 && unsr_p);
2344 p = TYPE_PRECISION (optype);
2345 if (p > precres)
2347 precres = p;
2348 unsr_p = TYPE_UNSIGNED (optype);
2349 type = optype;
2350 continue;
2354 if (prec0 <= precres && prec1 <= precres)
2356 tree types[2];
2357 if (unsr_p)
2359 types[0] = build_nonstandard_integer_type (precres, 0);
2360 types[1] = type;
2362 else
2364 types[0] = type;
2365 types[1] = build_nonstandard_integer_type (precres, 1);
2367 arg0 = fold_convert_loc (loc, types[uns0_p], arg0);
2368 arg1 = fold_convert_loc (loc, types[uns1_p], arg1);
2369 if (code != MULT_EXPR)
2370 expand_addsub_overflow (loc, code, lhs, arg0, arg1, unsr_p,
2371 uns0_p, uns1_p, false, NULL);
2372 else
2373 expand_mul_overflow (loc, lhs, arg0, arg1, unsr_p,
2374 uns0_p, uns1_p, false, NULL);
2375 return;
2378 /* Retry with a wider type. */
2379 if (orig_precres == precres)
2381 int p = MAX (prec0, prec1);
2382 scalar_int_mode m = smallest_int_mode_for_size (p);
2383 tree optype = build_nonstandard_integer_type (GET_MODE_PRECISION (m),
2384 uns0_p && uns1_p
2385 && unsr_p);
2386 p = TYPE_PRECISION (optype);
2387 if (p > precres)
2389 precres = p;
2390 unsr_p = TYPE_UNSIGNED (optype);
2391 type = optype;
2392 continue;
2396 gcc_unreachable ();
2398 while (1);
2401 /* Expand ADD_OVERFLOW STMT. */
2403 static void
2404 expand_ADD_OVERFLOW (internal_fn, gcall *stmt)
2406 expand_arith_overflow (PLUS_EXPR, stmt);
2409 /* Expand SUB_OVERFLOW STMT. */
2411 static void
2412 expand_SUB_OVERFLOW (internal_fn, gcall *stmt)
2414 expand_arith_overflow (MINUS_EXPR, stmt);
2417 /* Expand MUL_OVERFLOW STMT. */
2419 static void
2420 expand_MUL_OVERFLOW (internal_fn, gcall *stmt)
2422 expand_arith_overflow (MULT_EXPR, stmt);
2425 /* This should get folded in tree-vectorizer.c. */
2427 static void
2428 expand_LOOP_VECTORIZED (internal_fn, gcall *)
2430 gcc_unreachable ();
2433 /* This should get folded in tree-vectorizer.c. */
2435 static void
2436 expand_LOOP_DIST_ALIAS (internal_fn, gcall *)
2438 gcc_unreachable ();
2441 /* Return a memory reference of type TYPE for argument INDEX of STMT.
2442 Use argument INDEX + 1 to derive the second (TBAA) operand. */
2444 static tree
2445 expand_call_mem_ref (tree type, gcall *stmt, int index)
2447 tree addr = gimple_call_arg (stmt, index);
2448 tree alias_ptr_type = TREE_TYPE (gimple_call_arg (stmt, index + 1));
2449 unsigned int align = tree_to_shwi (gimple_call_arg (stmt, index + 1));
2450 if (TYPE_ALIGN (type) != align)
2451 type = build_aligned_type (type, align);
2453 tree tmp = addr;
2454 if (TREE_CODE (tmp) == SSA_NAME)
2456 gimple *def = SSA_NAME_DEF_STMT (tmp);
2457 if (gimple_assign_single_p (def))
2458 tmp = gimple_assign_rhs1 (def);
2461 if (TREE_CODE (tmp) == ADDR_EXPR)
2463 tree mem = TREE_OPERAND (tmp, 0);
2464 if (TREE_CODE (mem) == TARGET_MEM_REF
2465 && types_compatible_p (TREE_TYPE (mem), type))
2467 tree offset = TMR_OFFSET (mem);
2468 if (type != TREE_TYPE (mem)
2469 || alias_ptr_type != TREE_TYPE (offset)
2470 || !integer_zerop (offset))
2472 mem = copy_node (mem);
2473 TMR_OFFSET (mem) = wide_int_to_tree (alias_ptr_type,
2474 wi::to_poly_wide (offset));
2475 TREE_TYPE (mem) = type;
2477 return mem;
2481 return fold_build2 (MEM_REF, type, addr, build_int_cst (alias_ptr_type, 0));
2484 /* Expand MASK_LOAD{,_LANES} call STMT using optab OPTAB. */
2486 static void
2487 expand_mask_load_optab_fn (internal_fn, gcall *stmt, convert_optab optab)
2489 struct expand_operand ops[3];
2490 tree type, lhs, rhs, maskt;
2491 rtx mem, target, mask;
2492 insn_code icode;
2494 maskt = gimple_call_arg (stmt, 2);
2495 lhs = gimple_call_lhs (stmt);
2496 if (lhs == NULL_TREE)
2497 return;
2498 type = TREE_TYPE (lhs);
2499 rhs = expand_call_mem_ref (type, stmt, 0);
2501 if (optab == vec_mask_load_lanes_optab)
2502 icode = get_multi_vector_move (type, optab);
2503 else
2504 icode = convert_optab_handler (optab, TYPE_MODE (type),
2505 TYPE_MODE (TREE_TYPE (maskt)));
2507 mem = expand_expr (rhs, NULL_RTX, VOIDmode, EXPAND_WRITE);
2508 gcc_assert (MEM_P (mem));
2509 mask = expand_normal (maskt);
2510 target = expand_expr (lhs, NULL_RTX, VOIDmode, EXPAND_WRITE);
2511 create_output_operand (&ops[0], target, TYPE_MODE (type));
2512 create_fixed_operand (&ops[1], mem);
2513 create_input_operand (&ops[2], mask, TYPE_MODE (TREE_TYPE (maskt)));
2514 expand_insn (icode, 3, ops);
2517 #define expand_mask_load_lanes_optab_fn expand_mask_load_optab_fn
2519 /* Expand MASK_STORE{,_LANES} call STMT using optab OPTAB. */
2521 static void
2522 expand_mask_store_optab_fn (internal_fn, gcall *stmt, convert_optab optab)
2524 struct expand_operand ops[3];
2525 tree type, lhs, rhs, maskt;
2526 rtx mem, reg, mask;
2527 insn_code icode;
2529 maskt = gimple_call_arg (stmt, 2);
2530 rhs = gimple_call_arg (stmt, 3);
2531 type = TREE_TYPE (rhs);
2532 lhs = expand_call_mem_ref (type, stmt, 0);
2534 if (optab == vec_mask_store_lanes_optab)
2535 icode = get_multi_vector_move (type, optab);
2536 else
2537 icode = convert_optab_handler (optab, TYPE_MODE (type),
2538 TYPE_MODE (TREE_TYPE (maskt)));
2540 mem = expand_expr (lhs, NULL_RTX, VOIDmode, EXPAND_WRITE);
2541 gcc_assert (MEM_P (mem));
2542 mask = expand_normal (maskt);
2543 reg = expand_normal (rhs);
2544 create_fixed_operand (&ops[0], mem);
2545 create_input_operand (&ops[1], reg, TYPE_MODE (type));
2546 create_input_operand (&ops[2], mask, TYPE_MODE (TREE_TYPE (maskt)));
2547 expand_insn (icode, 3, ops);
2550 #define expand_mask_store_lanes_optab_fn expand_mask_store_optab_fn
2552 static void
2553 expand_ABNORMAL_DISPATCHER (internal_fn, gcall *)
2557 static void
2558 expand_BUILTIN_EXPECT (internal_fn, gcall *stmt)
2560 /* When guessing was done, the hints should be already stripped away. */
2561 gcc_assert (!flag_guess_branch_prob || optimize == 0 || seen_error ());
2563 rtx target;
2564 tree lhs = gimple_call_lhs (stmt);
2565 if (lhs)
2566 target = expand_expr (lhs, NULL_RTX, VOIDmode, EXPAND_WRITE);
2567 else
2568 target = const0_rtx;
2569 rtx val = expand_expr (gimple_call_arg (stmt, 0), target, VOIDmode, EXPAND_NORMAL);
2570 if (lhs && val != target)
2571 emit_move_insn (target, val);
2574 /* IFN_VA_ARG is supposed to be expanded at pass_stdarg. So this dummy function
2575 should never be called. */
2577 static void
2578 expand_VA_ARG (internal_fn, gcall *)
2580 gcc_unreachable ();
2583 /* Expand the IFN_UNIQUE function according to its first argument. */
2585 static void
2586 expand_UNIQUE (internal_fn, gcall *stmt)
2588 rtx pattern = NULL_RTX;
2589 enum ifn_unique_kind kind
2590 = (enum ifn_unique_kind) TREE_INT_CST_LOW (gimple_call_arg (stmt, 0));
2592 switch (kind)
2594 default:
2595 gcc_unreachable ();
2597 case IFN_UNIQUE_UNSPEC:
2598 if (targetm.have_unique ())
2599 pattern = targetm.gen_unique ();
2600 break;
2602 case IFN_UNIQUE_OACC_FORK:
2603 case IFN_UNIQUE_OACC_JOIN:
2604 if (targetm.have_oacc_fork () && targetm.have_oacc_join ())
2606 tree lhs = gimple_call_lhs (stmt);
2607 rtx target = const0_rtx;
2609 if (lhs)
2610 target = expand_expr (lhs, NULL_RTX, VOIDmode, EXPAND_WRITE);
2612 rtx data_dep = expand_normal (gimple_call_arg (stmt, 1));
2613 rtx axis = expand_normal (gimple_call_arg (stmt, 2));
2615 if (kind == IFN_UNIQUE_OACC_FORK)
2616 pattern = targetm.gen_oacc_fork (target, data_dep, axis);
2617 else
2618 pattern = targetm.gen_oacc_join (target, data_dep, axis);
2620 else
2621 gcc_unreachable ();
2622 break;
2625 if (pattern)
2626 emit_insn (pattern);
2629 /* The size of an OpenACC compute dimension. */
2631 static void
2632 expand_GOACC_DIM_SIZE (internal_fn, gcall *stmt)
2634 tree lhs = gimple_call_lhs (stmt);
2636 if (!lhs)
2637 return;
2639 rtx target = expand_expr (lhs, NULL_RTX, VOIDmode, EXPAND_WRITE);
2640 if (targetm.have_oacc_dim_size ())
2642 rtx dim = expand_expr (gimple_call_arg (stmt, 0), NULL_RTX,
2643 VOIDmode, EXPAND_NORMAL);
2644 emit_insn (targetm.gen_oacc_dim_size (target, dim));
2646 else
2647 emit_move_insn (target, GEN_INT (1));
2650 /* The position of an OpenACC execution engine along one compute axis. */
2652 static void
2653 expand_GOACC_DIM_POS (internal_fn, gcall *stmt)
2655 tree lhs = gimple_call_lhs (stmt);
2657 if (!lhs)
2658 return;
2660 rtx target = expand_expr (lhs, NULL_RTX, VOIDmode, EXPAND_WRITE);
2661 if (targetm.have_oacc_dim_pos ())
2663 rtx dim = expand_expr (gimple_call_arg (stmt, 0), NULL_RTX,
2664 VOIDmode, EXPAND_NORMAL);
2665 emit_insn (targetm.gen_oacc_dim_pos (target, dim));
2667 else
2668 emit_move_insn (target, const0_rtx);
2671 /* This is expanded by oacc_device_lower pass. */
2673 static void
2674 expand_GOACC_LOOP (internal_fn, gcall *)
2676 gcc_unreachable ();
2679 /* This is expanded by oacc_device_lower pass. */
2681 static void
2682 expand_GOACC_REDUCTION (internal_fn, gcall *)
2684 gcc_unreachable ();
2687 /* This is expanded by oacc_device_lower pass. */
2689 static void
2690 expand_GOACC_TILE (internal_fn, gcall *)
2692 gcc_unreachable ();
2695 /* Set errno to EDOM. */
2697 static void
2698 expand_SET_EDOM (internal_fn, gcall *)
2700 #ifdef TARGET_EDOM
2701 #ifdef GEN_ERRNO_RTX
2702 rtx errno_rtx = GEN_ERRNO_RTX;
2703 #else
2704 rtx errno_rtx = gen_rtx_MEM (word_mode, gen_rtx_SYMBOL_REF (Pmode, "errno"));
2705 #endif
2706 emit_move_insn (errno_rtx,
2707 gen_int_mode (TARGET_EDOM, GET_MODE (errno_rtx)));
2708 #else
2709 gcc_unreachable ();
2710 #endif
2713 /* Expand atomic bit test and set. */
2715 static void
2716 expand_ATOMIC_BIT_TEST_AND_SET (internal_fn, gcall *call)
2718 expand_ifn_atomic_bit_test_and (call);
2721 /* Expand atomic bit test and complement. */
2723 static void
2724 expand_ATOMIC_BIT_TEST_AND_COMPLEMENT (internal_fn, gcall *call)
2726 expand_ifn_atomic_bit_test_and (call);
2729 /* Expand atomic bit test and reset. */
2731 static void
2732 expand_ATOMIC_BIT_TEST_AND_RESET (internal_fn, gcall *call)
2734 expand_ifn_atomic_bit_test_and (call);
2737 /* Expand atomic bit test and set. */
2739 static void
2740 expand_ATOMIC_COMPARE_EXCHANGE (internal_fn, gcall *call)
2742 expand_ifn_atomic_compare_exchange (call);
2745 /* Expand LAUNDER to assignment, lhs = arg0. */
2747 static void
2748 expand_LAUNDER (internal_fn, gcall *call)
2750 tree lhs = gimple_call_lhs (call);
2752 if (!lhs)
2753 return;
2755 expand_assignment (lhs, gimple_call_arg (call, 0), false);
2758 /* Expand {MASK_,}SCATTER_STORE{S,U} call CALL using optab OPTAB. */
2760 static void
2761 expand_scatter_store_optab_fn (internal_fn, gcall *stmt, direct_optab optab)
2763 internal_fn ifn = gimple_call_internal_fn (stmt);
2764 int rhs_index = internal_fn_stored_value_index (ifn);
2765 int mask_index = internal_fn_mask_index (ifn);
2766 tree base = gimple_call_arg (stmt, 0);
2767 tree offset = gimple_call_arg (stmt, 1);
2768 tree scale = gimple_call_arg (stmt, 2);
2769 tree rhs = gimple_call_arg (stmt, rhs_index);
2771 rtx base_rtx = expand_normal (base);
2772 rtx offset_rtx = expand_normal (offset);
2773 HOST_WIDE_INT scale_int = tree_to_shwi (scale);
2774 rtx rhs_rtx = expand_normal (rhs);
2776 struct expand_operand ops[6];
2777 int i = 0;
2778 create_address_operand (&ops[i++], base_rtx);
2779 create_input_operand (&ops[i++], offset_rtx, TYPE_MODE (TREE_TYPE (offset)));
2780 create_integer_operand (&ops[i++], TYPE_UNSIGNED (TREE_TYPE (offset)));
2781 create_integer_operand (&ops[i++], scale_int);
2782 create_input_operand (&ops[i++], rhs_rtx, TYPE_MODE (TREE_TYPE (rhs)));
2783 if (mask_index >= 0)
2785 tree mask = gimple_call_arg (stmt, mask_index);
2786 rtx mask_rtx = expand_normal (mask);
2787 create_input_operand (&ops[i++], mask_rtx, TYPE_MODE (TREE_TYPE (mask)));
2790 insn_code icode = direct_optab_handler (optab, TYPE_MODE (TREE_TYPE (rhs)));
2791 expand_insn (icode, i, ops);
2794 /* Expand {MASK_,}GATHER_LOAD call CALL using optab OPTAB. */
2796 static void
2797 expand_gather_load_optab_fn (internal_fn, gcall *stmt, direct_optab optab)
2799 tree lhs = gimple_call_lhs (stmt);
2800 tree base = gimple_call_arg (stmt, 0);
2801 tree offset = gimple_call_arg (stmt, 1);
2802 tree scale = gimple_call_arg (stmt, 2);
2804 rtx lhs_rtx = expand_expr (lhs, NULL_RTX, VOIDmode, EXPAND_WRITE);
2805 rtx base_rtx = expand_normal (base);
2806 rtx offset_rtx = expand_normal (offset);
2807 HOST_WIDE_INT scale_int = tree_to_shwi (scale);
2809 int i = 0;
2810 struct expand_operand ops[6];
2811 create_output_operand (&ops[i++], lhs_rtx, TYPE_MODE (TREE_TYPE (lhs)));
2812 create_address_operand (&ops[i++], base_rtx);
2813 create_input_operand (&ops[i++], offset_rtx, TYPE_MODE (TREE_TYPE (offset)));
2814 create_integer_operand (&ops[i++], TYPE_UNSIGNED (TREE_TYPE (offset)));
2815 create_integer_operand (&ops[i++], scale_int);
2816 if (optab == mask_gather_load_optab)
2818 tree mask = gimple_call_arg (stmt, 3);
2819 rtx mask_rtx = expand_normal (mask);
2820 create_input_operand (&ops[i++], mask_rtx, TYPE_MODE (TREE_TYPE (mask)));
2822 insn_code icode = direct_optab_handler (optab, TYPE_MODE (TREE_TYPE (lhs)));
2823 expand_insn (icode, i, ops);
2826 /* Expand DIVMOD() using:
2827 a) optab handler for udivmod/sdivmod if it is available.
2828 b) If optab_handler doesn't exist, generate call to
2829 target-specific divmod libfunc. */
2831 static void
2832 expand_DIVMOD (internal_fn, gcall *call_stmt)
2834 tree lhs = gimple_call_lhs (call_stmt);
2835 tree arg0 = gimple_call_arg (call_stmt, 0);
2836 tree arg1 = gimple_call_arg (call_stmt, 1);
2838 gcc_assert (TREE_CODE (TREE_TYPE (lhs)) == COMPLEX_TYPE);
2839 tree type = TREE_TYPE (TREE_TYPE (lhs));
2840 machine_mode mode = TYPE_MODE (type);
2841 bool unsignedp = TYPE_UNSIGNED (type);
2842 optab tab = (unsignedp) ? udivmod_optab : sdivmod_optab;
2844 rtx op0 = expand_normal (arg0);
2845 rtx op1 = expand_normal (arg1);
2846 rtx target = expand_expr (lhs, NULL_RTX, VOIDmode, EXPAND_WRITE);
2848 rtx quotient, remainder, libfunc;
2850 /* Check if optab_handler exists for divmod_optab for given mode. */
2851 if (optab_handler (tab, mode) != CODE_FOR_nothing)
2853 quotient = gen_reg_rtx (mode);
2854 remainder = gen_reg_rtx (mode);
2855 expand_twoval_binop (tab, op0, op1, quotient, remainder, unsignedp);
2858 /* Generate call to divmod libfunc if it exists. */
2859 else if ((libfunc = optab_libfunc (tab, mode)) != NULL_RTX)
2860 targetm.expand_divmod_libfunc (libfunc, mode, op0, op1,
2861 &quotient, &remainder);
2863 else
2864 gcc_unreachable ();
2866 /* Wrap the return value (quotient, remainder) within COMPLEX_EXPR. */
2867 expand_expr (build2 (COMPLEX_EXPR, TREE_TYPE (lhs),
2868 make_tree (TREE_TYPE (arg0), quotient),
2869 make_tree (TREE_TYPE (arg1), remainder)),
2870 target, VOIDmode, EXPAND_NORMAL);
2873 /* Expand a NOP. */
2875 static void
2876 expand_NOP (internal_fn, gcall *)
2878 /* Nothing. But it shouldn't really prevail. */
2881 /* Expand a call to FN using the operands in STMT. FN has a single
2882 output operand and NARGS input operands. */
2884 static void
2885 expand_direct_optab_fn (internal_fn fn, gcall *stmt, direct_optab optab,
2886 unsigned int nargs)
2888 expand_operand *ops = XALLOCAVEC (expand_operand, nargs + 1);
2890 tree_pair types = direct_internal_fn_types (fn, stmt);
2891 insn_code icode = direct_optab_handler (optab, TYPE_MODE (types.first));
2893 tree lhs = gimple_call_lhs (stmt);
2894 rtx lhs_rtx = NULL_RTX;
2895 if (lhs)
2896 lhs_rtx = expand_expr (lhs, NULL_RTX, VOIDmode, EXPAND_WRITE);
2898 /* Do not assign directly to a promoted subreg, since there is no
2899 guarantee that the instruction will leave the upper bits of the
2900 register in the state required by SUBREG_PROMOTED_SIGN. */
2901 rtx dest = lhs_rtx;
2902 if (dest && GET_CODE (dest) == SUBREG && SUBREG_PROMOTED_VAR_P (dest))
2903 dest = NULL_RTX;
2905 create_output_operand (&ops[0], dest, insn_data[icode].operand[0].mode);
2907 for (unsigned int i = 0; i < nargs; ++i)
2909 tree rhs = gimple_call_arg (stmt, i);
2910 tree rhs_type = TREE_TYPE (rhs);
2911 rtx rhs_rtx = expand_normal (rhs);
2912 if (INTEGRAL_TYPE_P (rhs_type))
2913 create_convert_operand_from (&ops[i + 1], rhs_rtx,
2914 TYPE_MODE (rhs_type),
2915 TYPE_UNSIGNED (rhs_type));
2916 else
2917 create_input_operand (&ops[i + 1], rhs_rtx, TYPE_MODE (rhs_type));
2920 expand_insn (icode, nargs + 1, ops);
2921 if (lhs_rtx && !rtx_equal_p (lhs_rtx, ops[0].value))
2923 /* If the return value has an integral type, convert the instruction
2924 result to that type. This is useful for things that return an
2925 int regardless of the size of the input. If the instruction result
2926 is smaller than required, assume that it is signed.
2928 If the return value has a nonintegral type, its mode must match
2929 the instruction result. */
2930 if (GET_CODE (lhs_rtx) == SUBREG && SUBREG_PROMOTED_VAR_P (lhs_rtx))
2932 /* If this is a scalar in a register that is stored in a wider
2933 mode than the declared mode, compute the result into its
2934 declared mode and then convert to the wider mode. */
2935 gcc_checking_assert (INTEGRAL_TYPE_P (TREE_TYPE (lhs)));
2936 rtx tmp = convert_to_mode (GET_MODE (lhs_rtx), ops[0].value, 0);
2937 convert_move (SUBREG_REG (lhs_rtx), tmp,
2938 SUBREG_PROMOTED_SIGN (lhs_rtx));
2940 else if (GET_MODE (lhs_rtx) == GET_MODE (ops[0].value))
2941 emit_move_insn (lhs_rtx, ops[0].value);
2942 else
2944 gcc_checking_assert (INTEGRAL_TYPE_P (TREE_TYPE (lhs)));
2945 convert_move (lhs_rtx, ops[0].value, 0);
2950 /* Expand WHILE_ULT call STMT using optab OPTAB. */
2952 static void
2953 expand_while_optab_fn (internal_fn, gcall *stmt, convert_optab optab)
2955 expand_operand ops[3];
2956 tree rhs_type[2];
2958 tree lhs = gimple_call_lhs (stmt);
2959 tree lhs_type = TREE_TYPE (lhs);
2960 rtx lhs_rtx = expand_expr (lhs, NULL_RTX, VOIDmode, EXPAND_WRITE);
2961 create_output_operand (&ops[0], lhs_rtx, TYPE_MODE (lhs_type));
2963 for (unsigned int i = 0; i < 2; ++i)
2965 tree rhs = gimple_call_arg (stmt, i);
2966 rhs_type[i] = TREE_TYPE (rhs);
2967 rtx rhs_rtx = expand_normal (rhs);
2968 create_input_operand (&ops[i + 1], rhs_rtx, TYPE_MODE (rhs_type[i]));
2971 insn_code icode = convert_optab_handler (optab, TYPE_MODE (rhs_type[0]),
2972 TYPE_MODE (lhs_type));
2974 expand_insn (icode, 3, ops);
2975 if (!rtx_equal_p (lhs_rtx, ops[0].value))
2976 emit_move_insn (lhs_rtx, ops[0].value);
2979 /* Expanders for optabs that can use expand_direct_optab_fn. */
2981 #define expand_unary_optab_fn(FN, STMT, OPTAB) \
2982 expand_direct_optab_fn (FN, STMT, OPTAB, 1)
2984 #define expand_binary_optab_fn(FN, STMT, OPTAB) \
2985 expand_direct_optab_fn (FN, STMT, OPTAB, 2)
2987 #define expand_ternary_optab_fn(FN, STMT, OPTAB) \
2988 expand_direct_optab_fn (FN, STMT, OPTAB, 3)
2990 #define expand_cond_unary_optab_fn(FN, STMT, OPTAB) \
2991 expand_direct_optab_fn (FN, STMT, OPTAB, 3)
2993 #define expand_cond_binary_optab_fn(FN, STMT, OPTAB) \
2994 expand_direct_optab_fn (FN, STMT, OPTAB, 4)
2996 #define expand_fold_extract_optab_fn(FN, STMT, OPTAB) \
2997 expand_direct_optab_fn (FN, STMT, OPTAB, 3)
2999 #define expand_fold_left_optab_fn(FN, STMT, OPTAB) \
3000 expand_direct_optab_fn (FN, STMT, OPTAB, 2)
3002 /* RETURN_TYPE and ARGS are a return type and argument list that are
3003 in principle compatible with FN (which satisfies direct_internal_fn_p).
3004 Return the types that should be used to determine whether the
3005 target supports FN. */
3007 tree_pair
3008 direct_internal_fn_types (internal_fn fn, tree return_type, tree *args)
3010 const direct_internal_fn_info &info = direct_internal_fn (fn);
3011 tree type0 = (info.type0 < 0 ? return_type : TREE_TYPE (args[info.type0]));
3012 tree type1 = (info.type1 < 0 ? return_type : TREE_TYPE (args[info.type1]));
3013 return tree_pair (type0, type1);
3016 /* CALL is a call whose return type and arguments are in principle
3017 compatible with FN (which satisfies direct_internal_fn_p). Return the
3018 types that should be used to determine whether the target supports FN. */
3020 tree_pair
3021 direct_internal_fn_types (internal_fn fn, gcall *call)
3023 const direct_internal_fn_info &info = direct_internal_fn (fn);
3024 tree op0 = (info.type0 < 0
3025 ? gimple_call_lhs (call)
3026 : gimple_call_arg (call, info.type0));
3027 tree op1 = (info.type1 < 0
3028 ? gimple_call_lhs (call)
3029 : gimple_call_arg (call, info.type1));
3030 return tree_pair (TREE_TYPE (op0), TREE_TYPE (op1));
3033 /* Return true if OPTAB is supported for TYPES (whose modes should be
3034 the same) when the optimization type is OPT_TYPE. Used for simple
3035 direct optabs. */
3037 static bool
3038 direct_optab_supported_p (direct_optab optab, tree_pair types,
3039 optimization_type opt_type)
3041 machine_mode mode = TYPE_MODE (types.first);
3042 gcc_checking_assert (mode == TYPE_MODE (types.second));
3043 return direct_optab_handler (optab, mode, opt_type) != CODE_FOR_nothing;
3046 /* Return true if OPTAB is supported for TYPES, where the first type
3047 is the destination and the second type is the source. Used for
3048 convert optabs. */
3050 static bool
3051 convert_optab_supported_p (convert_optab optab, tree_pair types,
3052 optimization_type opt_type)
3054 return (convert_optab_handler (optab, TYPE_MODE (types.first),
3055 TYPE_MODE (types.second), opt_type)
3056 != CODE_FOR_nothing);
3059 /* Return true if load/store lanes optab OPTAB is supported for
3060 array type TYPES.first when the optimization type is OPT_TYPE. */
3062 static bool
3063 multi_vector_optab_supported_p (convert_optab optab, tree_pair types,
3064 optimization_type opt_type)
3066 gcc_assert (TREE_CODE (types.first) == ARRAY_TYPE);
3067 machine_mode imode = TYPE_MODE (types.first);
3068 machine_mode vmode = TYPE_MODE (TREE_TYPE (types.first));
3069 return (convert_optab_handler (optab, imode, vmode, opt_type)
3070 != CODE_FOR_nothing);
3073 #define direct_unary_optab_supported_p direct_optab_supported_p
3074 #define direct_binary_optab_supported_p direct_optab_supported_p
3075 #define direct_ternary_optab_supported_p direct_optab_supported_p
3076 #define direct_cond_unary_optab_supported_p direct_optab_supported_p
3077 #define direct_cond_binary_optab_supported_p direct_optab_supported_p
3078 #define direct_mask_load_optab_supported_p direct_optab_supported_p
3079 #define direct_load_lanes_optab_supported_p multi_vector_optab_supported_p
3080 #define direct_mask_load_lanes_optab_supported_p multi_vector_optab_supported_p
3081 #define direct_gather_load_optab_supported_p direct_optab_supported_p
3082 #define direct_mask_store_optab_supported_p direct_optab_supported_p
3083 #define direct_store_lanes_optab_supported_p multi_vector_optab_supported_p
3084 #define direct_mask_store_lanes_optab_supported_p multi_vector_optab_supported_p
3085 #define direct_scatter_store_optab_supported_p direct_optab_supported_p
3086 #define direct_while_optab_supported_p convert_optab_supported_p
3087 #define direct_fold_extract_optab_supported_p direct_optab_supported_p
3088 #define direct_fold_left_optab_supported_p direct_optab_supported_p
3090 /* Return the optab used by internal function FN. */
3092 static optab
3093 direct_internal_fn_optab (internal_fn fn, tree_pair types)
3095 switch (fn)
3097 #define DEF_INTERNAL_FN(CODE, FLAGS, FNSPEC) \
3098 case IFN_##CODE: break;
3099 #define DEF_INTERNAL_OPTAB_FN(CODE, FLAGS, OPTAB, TYPE) \
3100 case IFN_##CODE: return OPTAB##_optab;
3101 #define DEF_INTERNAL_SIGNED_OPTAB_FN(CODE, FLAGS, SELECTOR, SIGNED_OPTAB, \
3102 UNSIGNED_OPTAB, TYPE) \
3103 case IFN_##CODE: return (TYPE_UNSIGNED (types.SELECTOR) \
3104 ? UNSIGNED_OPTAB ## _optab \
3105 : SIGNED_OPTAB ## _optab);
3106 #include "internal-fn.def"
3108 case IFN_LAST:
3109 break;
3111 gcc_unreachable ();
3114 /* Return the optab used by internal function FN. */
3116 static optab
3117 direct_internal_fn_optab (internal_fn fn)
3119 switch (fn)
3121 #define DEF_INTERNAL_FN(CODE, FLAGS, FNSPEC) \
3122 case IFN_##CODE: break;
3123 #define DEF_INTERNAL_OPTAB_FN(CODE, FLAGS, OPTAB, TYPE) \
3124 case IFN_##CODE: return OPTAB##_optab;
3125 #include "internal-fn.def"
3127 case IFN_LAST:
3128 break;
3130 gcc_unreachable ();
3133 /* Return true if FN is supported for the types in TYPES when the
3134 optimization type is OPT_TYPE. The types are those associated with
3135 the "type0" and "type1" fields of FN's direct_internal_fn_info
3136 structure. */
3138 bool
3139 direct_internal_fn_supported_p (internal_fn fn, tree_pair types,
3140 optimization_type opt_type)
3142 switch (fn)
3144 #define DEF_INTERNAL_FN(CODE, FLAGS, FNSPEC) \
3145 case IFN_##CODE: break;
3146 #define DEF_INTERNAL_OPTAB_FN(CODE, FLAGS, OPTAB, TYPE) \
3147 case IFN_##CODE: \
3148 return direct_##TYPE##_optab_supported_p (OPTAB##_optab, types, \
3149 opt_type);
3150 #define DEF_INTERNAL_SIGNED_OPTAB_FN(CODE, FLAGS, SELECTOR, SIGNED_OPTAB, \
3151 UNSIGNED_OPTAB, TYPE) \
3152 case IFN_##CODE: \
3154 optab which_optab = (TYPE_UNSIGNED (types.SELECTOR) \
3155 ? UNSIGNED_OPTAB ## _optab \
3156 : SIGNED_OPTAB ## _optab); \
3157 return direct_##TYPE##_optab_supported_p (which_optab, types, \
3158 opt_type); \
3160 #include "internal-fn.def"
3162 case IFN_LAST:
3163 break;
3165 gcc_unreachable ();
3168 /* Return true if FN is supported for type TYPE when the optimization
3169 type is OPT_TYPE. The caller knows that the "type0" and "type1"
3170 fields of FN's direct_internal_fn_info structure are the same. */
3172 bool
3173 direct_internal_fn_supported_p (internal_fn fn, tree type,
3174 optimization_type opt_type)
3176 const direct_internal_fn_info &info = direct_internal_fn (fn);
3177 gcc_checking_assert (info.type0 == info.type1);
3178 return direct_internal_fn_supported_p (fn, tree_pair (type, type), opt_type);
3181 /* Return true if IFN_SET_EDOM is supported. */
3183 bool
3184 set_edom_supported_p (void)
3186 #ifdef TARGET_EDOM
3187 return true;
3188 #else
3189 return false;
3190 #endif
3193 #define DEF_INTERNAL_OPTAB_FN(CODE, FLAGS, OPTAB, TYPE) \
3194 static void \
3195 expand_##CODE (internal_fn fn, gcall *stmt) \
3197 expand_##TYPE##_optab_fn (fn, stmt, OPTAB##_optab); \
3199 #define DEF_INTERNAL_SIGNED_OPTAB_FN(CODE, FLAGS, SELECTOR, SIGNED_OPTAB, \
3200 UNSIGNED_OPTAB, TYPE) \
3201 static void \
3202 expand_##CODE (internal_fn fn, gcall *stmt) \
3204 tree_pair types = direct_internal_fn_types (fn, stmt); \
3205 optab which_optab = direct_internal_fn_optab (fn, types); \
3206 expand_##TYPE##_optab_fn (fn, stmt, which_optab); \
3208 #include "internal-fn.def"
3210 /* Routines to expand each internal function, indexed by function number.
3211 Each routine has the prototype:
3213 expand_<NAME> (gcall *stmt)
3215 where STMT is the statement that performs the call. */
3216 static void (*const internal_fn_expanders[]) (internal_fn, gcall *) = {
3217 #define DEF_INTERNAL_FN(CODE, FLAGS, FNSPEC) expand_##CODE,
3218 #include "internal-fn.def"
3222 /* Return a function that only performs CODE when a certain condition is met
3223 and that uses a given fallback value otherwise. For example, if CODE is
3224 a binary operation associated with conditional function FN:
3226 LHS = FN (COND, A, B, ELSE)
3228 is equivalent to the C expression:
3230 LHS = COND ? A CODE B : ELSE;
3232 operating elementwise if the operands are vectors.
3234 Return IFN_LAST if no such function exists. */
3236 internal_fn
3237 get_conditional_internal_fn (tree_code code)
3239 switch (code)
3241 case PLUS_EXPR:
3242 return IFN_COND_ADD;
3243 case MINUS_EXPR:
3244 return IFN_COND_SUB;
3245 case MIN_EXPR:
3246 return IFN_COND_MIN;
3247 case MAX_EXPR:
3248 return IFN_COND_MAX;
3249 case TRUNC_DIV_EXPR:
3250 return IFN_COND_DIV;
3251 case TRUNC_MOD_EXPR:
3252 return IFN_COND_MOD;
3253 case RDIV_EXPR:
3254 return IFN_COND_RDIV;
3255 case BIT_AND_EXPR:
3256 return IFN_COND_AND;
3257 case BIT_IOR_EXPR:
3258 return IFN_COND_IOR;
3259 case BIT_XOR_EXPR:
3260 return IFN_COND_XOR;
3261 default:
3262 return IFN_LAST;
3266 /* Return true if IFN is some form of load from memory. */
3268 bool
3269 internal_load_fn_p (internal_fn fn)
3271 switch (fn)
3273 case IFN_MASK_LOAD:
3274 case IFN_LOAD_LANES:
3275 case IFN_MASK_LOAD_LANES:
3276 case IFN_GATHER_LOAD:
3277 case IFN_MASK_GATHER_LOAD:
3278 return true;
3280 default:
3281 return false;
3285 /* Return true if IFN is some form of store to memory. */
3287 bool
3288 internal_store_fn_p (internal_fn fn)
3290 switch (fn)
3292 case IFN_MASK_STORE:
3293 case IFN_STORE_LANES:
3294 case IFN_MASK_STORE_LANES:
3295 case IFN_SCATTER_STORE:
3296 case IFN_MASK_SCATTER_STORE:
3297 return true;
3299 default:
3300 return false;
3304 /* Return true if IFN is some form of gather load or scatter store. */
3306 bool
3307 internal_gather_scatter_fn_p (internal_fn fn)
3309 switch (fn)
3311 case IFN_GATHER_LOAD:
3312 case IFN_MASK_GATHER_LOAD:
3313 case IFN_SCATTER_STORE:
3314 case IFN_MASK_SCATTER_STORE:
3315 return true;
3317 default:
3318 return false;
3322 /* If FN takes a vector mask argument, return the index of that argument,
3323 otherwise return -1. */
3326 internal_fn_mask_index (internal_fn fn)
3328 switch (fn)
3330 case IFN_MASK_LOAD:
3331 case IFN_MASK_LOAD_LANES:
3332 case IFN_MASK_STORE:
3333 case IFN_MASK_STORE_LANES:
3334 return 2;
3336 case IFN_MASK_GATHER_LOAD:
3337 return 3;
3339 case IFN_MASK_SCATTER_STORE:
3340 return 4;
3342 default:
3343 return -1;
3347 /* If FN takes a value that should be stored to memory, return the index
3348 of that argument, otherwise return -1. */
3351 internal_fn_stored_value_index (internal_fn fn)
3353 switch (fn)
3355 case IFN_MASK_STORE:
3356 case IFN_SCATTER_STORE:
3357 case IFN_MASK_SCATTER_STORE:
3358 return 3;
3360 default:
3361 return -1;
3365 /* Return true if the target supports gather load or scatter store function
3366 IFN. For loads, VECTOR_TYPE is the vector type of the load result,
3367 while for stores it is the vector type of the stored data argument.
3368 MEMORY_ELEMENT_TYPE is the type of the memory elements being loaded
3369 or stored. OFFSET_SIGN is the sign of the offset argument, which is
3370 only relevant when the offset is narrower than an address. SCALE is
3371 the amount by which the offset should be multiplied *after* it has
3372 been extended to address width. */
3374 bool
3375 internal_gather_scatter_fn_supported_p (internal_fn ifn, tree vector_type,
3376 tree memory_element_type,
3377 signop offset_sign, int scale)
3379 if (!tree_int_cst_equal (TYPE_SIZE (TREE_TYPE (vector_type)),
3380 TYPE_SIZE (memory_element_type)))
3381 return false;
3382 optab optab = direct_internal_fn_optab (ifn);
3383 insn_code icode = direct_optab_handler (optab, TYPE_MODE (vector_type));
3384 int output_ops = internal_load_fn_p (ifn) ? 1 : 0;
3385 return (icode != CODE_FOR_nothing
3386 && insn_operand_matches (icode, 2 + output_ops,
3387 GEN_INT (offset_sign == UNSIGNED))
3388 && insn_operand_matches (icode, 3 + output_ops,
3389 GEN_INT (scale)));
3392 /* Expand STMT as though it were a call to internal function FN. */
3394 void
3395 expand_internal_call (internal_fn fn, gcall *stmt)
3397 internal_fn_expanders[fn] (fn, stmt);
3400 /* Expand STMT, which is a call to internal function FN. */
3402 void
3403 expand_internal_call (gcall *stmt)
3405 expand_internal_call (gimple_call_internal_fn (stmt), stmt);
3408 void
3409 expand_PHI (internal_fn, gcall *)
3411 gcc_unreachable ();