Support fused multiply-adds in fully-masked reductions
[official-gcc.git] / gcc / internal-fn.c
blob15755ea06fdaca14ebbfcbfb80e7ab18418f3a0d
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 cond_ternary_direct { 1, 1, true }
117 #define while_direct { 0, 2, false }
118 #define fold_extract_direct { 2, 2, false }
119 #define fold_left_direct { 1, 1, false }
121 const direct_internal_fn_info direct_internal_fn_array[IFN_LAST + 1] = {
122 #define DEF_INTERNAL_FN(CODE, FLAGS, FNSPEC) not_direct,
123 #define DEF_INTERNAL_OPTAB_FN(CODE, FLAGS, OPTAB, TYPE) TYPE##_direct,
124 #define DEF_INTERNAL_SIGNED_OPTAB_FN(CODE, FLAGS, SELECTOR, SIGNED_OPTAB, \
125 UNSIGNED_OPTAB, TYPE) TYPE##_direct,
126 #include "internal-fn.def"
127 not_direct
130 /* ARRAY_TYPE is an array of vector modes. Return the associated insn
131 for load-lanes-style optab OPTAB, or CODE_FOR_nothing if none. */
133 static enum insn_code
134 get_multi_vector_move (tree array_type, convert_optab optab)
136 machine_mode imode;
137 machine_mode vmode;
139 gcc_assert (TREE_CODE (array_type) == ARRAY_TYPE);
140 imode = TYPE_MODE (array_type);
141 vmode = TYPE_MODE (TREE_TYPE (array_type));
143 return convert_optab_handler (optab, imode, vmode);
146 /* Expand LOAD_LANES call STMT using optab OPTAB. */
148 static void
149 expand_load_lanes_optab_fn (internal_fn, gcall *stmt, convert_optab optab)
151 struct expand_operand ops[2];
152 tree type, lhs, rhs;
153 rtx target, mem;
155 lhs = gimple_call_lhs (stmt);
156 rhs = gimple_call_arg (stmt, 0);
157 type = TREE_TYPE (lhs);
159 target = expand_expr (lhs, NULL_RTX, VOIDmode, EXPAND_WRITE);
160 mem = expand_normal (rhs);
162 gcc_assert (MEM_P (mem));
163 PUT_MODE (mem, TYPE_MODE (type));
165 create_output_operand (&ops[0], target, TYPE_MODE (type));
166 create_fixed_operand (&ops[1], mem);
167 expand_insn (get_multi_vector_move (type, optab), 2, ops);
170 /* Expand STORE_LANES call STMT using optab OPTAB. */
172 static void
173 expand_store_lanes_optab_fn (internal_fn, gcall *stmt, convert_optab optab)
175 struct expand_operand ops[2];
176 tree type, lhs, rhs;
177 rtx target, reg;
179 lhs = gimple_call_lhs (stmt);
180 rhs = gimple_call_arg (stmt, 0);
181 type = TREE_TYPE (rhs);
183 target = expand_expr (lhs, NULL_RTX, VOIDmode, EXPAND_WRITE);
184 reg = expand_normal (rhs);
186 gcc_assert (MEM_P (target));
187 PUT_MODE (target, TYPE_MODE (type));
189 create_fixed_operand (&ops[0], target);
190 create_input_operand (&ops[1], reg, TYPE_MODE (type));
191 expand_insn (get_multi_vector_move (type, optab), 2, ops);
194 static void
195 expand_ANNOTATE (internal_fn, gcall *)
197 gcc_unreachable ();
200 /* This should get expanded in omp_device_lower pass. */
202 static void
203 expand_GOMP_USE_SIMT (internal_fn, gcall *)
205 gcc_unreachable ();
208 /* This should get expanded in omp_device_lower pass. */
210 static void
211 expand_GOMP_SIMT_ENTER (internal_fn, gcall *)
213 gcc_unreachable ();
216 /* Allocate per-lane storage and begin non-uniform execution region. */
218 static void
219 expand_GOMP_SIMT_ENTER_ALLOC (internal_fn, gcall *stmt)
221 rtx target;
222 tree lhs = gimple_call_lhs (stmt);
223 if (lhs)
224 target = expand_expr (lhs, NULL_RTX, VOIDmode, EXPAND_WRITE);
225 else
226 target = gen_reg_rtx (Pmode);
227 rtx size = expand_normal (gimple_call_arg (stmt, 0));
228 rtx align = expand_normal (gimple_call_arg (stmt, 1));
229 struct expand_operand ops[3];
230 create_output_operand (&ops[0], target, Pmode);
231 create_input_operand (&ops[1], size, Pmode);
232 create_input_operand (&ops[2], align, Pmode);
233 gcc_assert (targetm.have_omp_simt_enter ());
234 expand_insn (targetm.code_for_omp_simt_enter, 3, ops);
237 /* Deallocate per-lane storage and leave non-uniform execution region. */
239 static void
240 expand_GOMP_SIMT_EXIT (internal_fn, gcall *stmt)
242 gcc_checking_assert (!gimple_call_lhs (stmt));
243 rtx arg = expand_normal (gimple_call_arg (stmt, 0));
244 struct expand_operand ops[1];
245 create_input_operand (&ops[0], arg, Pmode);
246 gcc_assert (targetm.have_omp_simt_exit ());
247 expand_insn (targetm.code_for_omp_simt_exit, 1, ops);
250 /* Lane index on SIMT targets: thread index in the warp on NVPTX. On targets
251 without SIMT execution this should be expanded in omp_device_lower pass. */
253 static void
254 expand_GOMP_SIMT_LANE (internal_fn, gcall *stmt)
256 tree lhs = gimple_call_lhs (stmt);
257 if (!lhs)
258 return;
260 rtx target = expand_expr (lhs, NULL_RTX, VOIDmode, EXPAND_WRITE);
261 gcc_assert (targetm.have_omp_simt_lane ());
262 emit_insn (targetm.gen_omp_simt_lane (target));
265 /* This should get expanded in omp_device_lower pass. */
267 static void
268 expand_GOMP_SIMT_VF (internal_fn, gcall *)
270 gcc_unreachable ();
273 /* Lane index of the first SIMT lane that supplies a non-zero argument.
274 This is a SIMT counterpart to GOMP_SIMD_LAST_LANE, used to represent the
275 lane that executed the last iteration for handling OpenMP lastprivate. */
277 static void
278 expand_GOMP_SIMT_LAST_LANE (internal_fn, gcall *stmt)
280 tree lhs = gimple_call_lhs (stmt);
281 if (!lhs)
282 return;
284 rtx target = expand_expr (lhs, NULL_RTX, VOIDmode, EXPAND_WRITE);
285 rtx cond = expand_normal (gimple_call_arg (stmt, 0));
286 machine_mode mode = TYPE_MODE (TREE_TYPE (lhs));
287 struct expand_operand ops[2];
288 create_output_operand (&ops[0], target, mode);
289 create_input_operand (&ops[1], cond, mode);
290 gcc_assert (targetm.have_omp_simt_last_lane ());
291 expand_insn (targetm.code_for_omp_simt_last_lane, 2, ops);
294 /* Non-transparent predicate used in SIMT lowering of OpenMP "ordered". */
296 static void
297 expand_GOMP_SIMT_ORDERED_PRED (internal_fn, gcall *stmt)
299 tree lhs = gimple_call_lhs (stmt);
300 if (!lhs)
301 return;
303 rtx target = expand_expr (lhs, NULL_RTX, VOIDmode, EXPAND_WRITE);
304 rtx ctr = expand_normal (gimple_call_arg (stmt, 0));
305 machine_mode mode = TYPE_MODE (TREE_TYPE (lhs));
306 struct expand_operand ops[2];
307 create_output_operand (&ops[0], target, mode);
308 create_input_operand (&ops[1], ctr, mode);
309 gcc_assert (targetm.have_omp_simt_ordered ());
310 expand_insn (targetm.code_for_omp_simt_ordered, 2, ops);
313 /* "Or" boolean reduction across SIMT lanes: return non-zero in all lanes if
314 any lane supplies a non-zero argument. */
316 static void
317 expand_GOMP_SIMT_VOTE_ANY (internal_fn, gcall *stmt)
319 tree lhs = gimple_call_lhs (stmt);
320 if (!lhs)
321 return;
323 rtx target = expand_expr (lhs, NULL_RTX, VOIDmode, EXPAND_WRITE);
324 rtx cond = expand_normal (gimple_call_arg (stmt, 0));
325 machine_mode mode = TYPE_MODE (TREE_TYPE (lhs));
326 struct expand_operand ops[2];
327 create_output_operand (&ops[0], target, mode);
328 create_input_operand (&ops[1], cond, mode);
329 gcc_assert (targetm.have_omp_simt_vote_any ());
330 expand_insn (targetm.code_for_omp_simt_vote_any, 2, ops);
333 /* Exchange between SIMT lanes with a "butterfly" pattern: source lane index
334 is destination lane index XOR given offset. */
336 static void
337 expand_GOMP_SIMT_XCHG_BFLY (internal_fn, gcall *stmt)
339 tree lhs = gimple_call_lhs (stmt);
340 if (!lhs)
341 return;
343 rtx target = expand_expr (lhs, NULL_RTX, VOIDmode, EXPAND_WRITE);
344 rtx src = expand_normal (gimple_call_arg (stmt, 0));
345 rtx idx = expand_normal (gimple_call_arg (stmt, 1));
346 machine_mode mode = TYPE_MODE (TREE_TYPE (lhs));
347 struct expand_operand ops[3];
348 create_output_operand (&ops[0], target, mode);
349 create_input_operand (&ops[1], src, mode);
350 create_input_operand (&ops[2], idx, SImode);
351 gcc_assert (targetm.have_omp_simt_xchg_bfly ());
352 expand_insn (targetm.code_for_omp_simt_xchg_bfly, 3, ops);
355 /* Exchange between SIMT lanes according to given source lane index. */
357 static void
358 expand_GOMP_SIMT_XCHG_IDX (internal_fn, gcall *stmt)
360 tree lhs = gimple_call_lhs (stmt);
361 if (!lhs)
362 return;
364 rtx target = expand_expr (lhs, NULL_RTX, VOIDmode, EXPAND_WRITE);
365 rtx src = expand_normal (gimple_call_arg (stmt, 0));
366 rtx idx = expand_normal (gimple_call_arg (stmt, 1));
367 machine_mode mode = TYPE_MODE (TREE_TYPE (lhs));
368 struct expand_operand ops[3];
369 create_output_operand (&ops[0], target, mode);
370 create_input_operand (&ops[1], src, mode);
371 create_input_operand (&ops[2], idx, SImode);
372 gcc_assert (targetm.have_omp_simt_xchg_idx ());
373 expand_insn (targetm.code_for_omp_simt_xchg_idx, 3, ops);
376 /* This should get expanded in adjust_simduid_builtins. */
378 static void
379 expand_GOMP_SIMD_LANE (internal_fn, gcall *)
381 gcc_unreachable ();
384 /* This should get expanded in adjust_simduid_builtins. */
386 static void
387 expand_GOMP_SIMD_VF (internal_fn, gcall *)
389 gcc_unreachable ();
392 /* This should get expanded in adjust_simduid_builtins. */
394 static void
395 expand_GOMP_SIMD_LAST_LANE (internal_fn, gcall *)
397 gcc_unreachable ();
400 /* This should get expanded in adjust_simduid_builtins. */
402 static void
403 expand_GOMP_SIMD_ORDERED_START (internal_fn, gcall *)
405 gcc_unreachable ();
408 /* This should get expanded in adjust_simduid_builtins. */
410 static void
411 expand_GOMP_SIMD_ORDERED_END (internal_fn, gcall *)
413 gcc_unreachable ();
416 /* This should get expanded in the sanopt pass. */
418 static void
419 expand_UBSAN_NULL (internal_fn, gcall *)
421 gcc_unreachable ();
424 /* This should get expanded in the sanopt pass. */
426 static void
427 expand_UBSAN_BOUNDS (internal_fn, gcall *)
429 gcc_unreachable ();
432 /* This should get expanded in the sanopt pass. */
434 static void
435 expand_UBSAN_VPTR (internal_fn, gcall *)
437 gcc_unreachable ();
440 /* This should get expanded in the sanopt pass. */
442 static void
443 expand_UBSAN_PTR (internal_fn, gcall *)
445 gcc_unreachable ();
448 /* This should get expanded in the sanopt pass. */
450 static void
451 expand_UBSAN_OBJECT_SIZE (internal_fn, gcall *)
453 gcc_unreachable ();
456 /* This should get expanded in the sanopt pass. */
458 static void
459 expand_ASAN_CHECK (internal_fn, gcall *)
461 gcc_unreachable ();
464 /* This should get expanded in the sanopt pass. */
466 static void
467 expand_ASAN_MARK (internal_fn, gcall *)
469 gcc_unreachable ();
472 /* This should get expanded in the sanopt pass. */
474 static void
475 expand_ASAN_POISON (internal_fn, gcall *)
477 gcc_unreachable ();
480 /* This should get expanded in the sanopt pass. */
482 static void
483 expand_ASAN_POISON_USE (internal_fn, gcall *)
485 gcc_unreachable ();
488 /* This should get expanded in the tsan pass. */
490 static void
491 expand_TSAN_FUNC_EXIT (internal_fn, gcall *)
493 gcc_unreachable ();
496 /* This should get expanded in the lower pass. */
498 static void
499 expand_FALLTHROUGH (internal_fn, gcall *call)
501 error_at (gimple_location (call),
502 "invalid use of attribute %<fallthrough%>");
505 /* Return minimum precision needed to represent all values
506 of ARG in SIGNed integral type. */
508 static int
509 get_min_precision (tree arg, signop sign)
511 int prec = TYPE_PRECISION (TREE_TYPE (arg));
512 int cnt = 0;
513 signop orig_sign = sign;
514 if (TREE_CODE (arg) == INTEGER_CST)
516 int p;
517 if (TYPE_SIGN (TREE_TYPE (arg)) != sign)
519 widest_int w = wi::to_widest (arg);
520 w = wi::ext (w, prec, sign);
521 p = wi::min_precision (w, sign);
523 else
524 p = wi::min_precision (wi::to_wide (arg), sign);
525 return MIN (p, prec);
527 while (CONVERT_EXPR_P (arg)
528 && INTEGRAL_TYPE_P (TREE_TYPE (TREE_OPERAND (arg, 0)))
529 && TYPE_PRECISION (TREE_TYPE (TREE_OPERAND (arg, 0))) <= prec)
531 arg = TREE_OPERAND (arg, 0);
532 if (TYPE_PRECISION (TREE_TYPE (arg)) < prec)
534 if (TYPE_UNSIGNED (TREE_TYPE (arg)))
535 sign = UNSIGNED;
536 else if (sign == UNSIGNED && get_range_pos_neg (arg) != 1)
537 return prec + (orig_sign != sign);
538 prec = TYPE_PRECISION (TREE_TYPE (arg));
540 if (++cnt > 30)
541 return prec + (orig_sign != sign);
543 if (TREE_CODE (arg) != SSA_NAME)
544 return prec + (orig_sign != sign);
545 wide_int arg_min, arg_max;
546 while (get_range_info (arg, &arg_min, &arg_max) != VR_RANGE)
548 gimple *g = SSA_NAME_DEF_STMT (arg);
549 if (is_gimple_assign (g)
550 && CONVERT_EXPR_CODE_P (gimple_assign_rhs_code (g)))
552 tree t = gimple_assign_rhs1 (g);
553 if (INTEGRAL_TYPE_P (TREE_TYPE (t))
554 && TYPE_PRECISION (TREE_TYPE (t)) <= prec)
556 arg = t;
557 if (TYPE_PRECISION (TREE_TYPE (arg)) < prec)
559 if (TYPE_UNSIGNED (TREE_TYPE (arg)))
560 sign = UNSIGNED;
561 else if (sign == UNSIGNED && get_range_pos_neg (arg) != 1)
562 return prec + (orig_sign != sign);
563 prec = TYPE_PRECISION (TREE_TYPE (arg));
565 if (++cnt > 30)
566 return prec + (orig_sign != sign);
567 continue;
570 return prec + (orig_sign != sign);
572 if (sign == TYPE_SIGN (TREE_TYPE (arg)))
574 int p1 = wi::min_precision (arg_min, sign);
575 int p2 = wi::min_precision (arg_max, sign);
576 p1 = MAX (p1, p2);
577 prec = MIN (prec, p1);
579 else if (sign == UNSIGNED && !wi::neg_p (arg_min, SIGNED))
581 int p = wi::min_precision (arg_max, UNSIGNED);
582 prec = MIN (prec, p);
584 return prec + (orig_sign != sign);
587 /* Helper for expand_*_overflow. Set the __imag__ part to true
588 (1 except for signed:1 type, in which case store -1). */
590 static void
591 expand_arith_set_overflow (tree lhs, rtx target)
593 if (TYPE_PRECISION (TREE_TYPE (TREE_TYPE (lhs))) == 1
594 && !TYPE_UNSIGNED (TREE_TYPE (TREE_TYPE (lhs))))
595 write_complex_part (target, constm1_rtx, true);
596 else
597 write_complex_part (target, const1_rtx, true);
600 /* Helper for expand_*_overflow. Store RES into the __real__ part
601 of TARGET. If RES has larger MODE than __real__ part of TARGET,
602 set the __imag__ part to 1 if RES doesn't fit into it. Similarly
603 if LHS has smaller precision than its mode. */
605 static void
606 expand_arith_overflow_result_store (tree lhs, rtx target,
607 scalar_int_mode mode, rtx res)
609 scalar_int_mode tgtmode
610 = as_a <scalar_int_mode> (GET_MODE_INNER (GET_MODE (target)));
611 rtx lres = res;
612 if (tgtmode != mode)
614 rtx_code_label *done_label = gen_label_rtx ();
615 int uns = TYPE_UNSIGNED (TREE_TYPE (TREE_TYPE (lhs)));
616 lres = convert_modes (tgtmode, mode, res, uns);
617 gcc_assert (GET_MODE_PRECISION (tgtmode) < GET_MODE_PRECISION (mode));
618 do_compare_rtx_and_jump (res, convert_modes (mode, tgtmode, lres, uns),
619 EQ, true, mode, NULL_RTX, NULL, done_label,
620 profile_probability::very_likely ());
621 expand_arith_set_overflow (lhs, target);
622 emit_label (done_label);
624 int prec = TYPE_PRECISION (TREE_TYPE (TREE_TYPE (lhs)));
625 int tgtprec = GET_MODE_PRECISION (tgtmode);
626 if (prec < tgtprec)
628 rtx_code_label *done_label = gen_label_rtx ();
629 int uns = TYPE_UNSIGNED (TREE_TYPE (TREE_TYPE (lhs)));
630 res = lres;
631 if (uns)
633 rtx mask
634 = immed_wide_int_const (wi::shifted_mask (0, prec, false, tgtprec),
635 tgtmode);
636 lres = expand_simple_binop (tgtmode, AND, res, mask, NULL_RTX,
637 true, OPTAB_LIB_WIDEN);
639 else
641 lres = expand_shift (LSHIFT_EXPR, tgtmode, res, tgtprec - prec,
642 NULL_RTX, 1);
643 lres = expand_shift (RSHIFT_EXPR, tgtmode, lres, tgtprec - prec,
644 NULL_RTX, 0);
646 do_compare_rtx_and_jump (res, lres,
647 EQ, true, tgtmode, NULL_RTX, NULL, done_label,
648 profile_probability::very_likely ());
649 expand_arith_set_overflow (lhs, target);
650 emit_label (done_label);
652 write_complex_part (target, lres, false);
655 /* Helper for expand_*_overflow. Store RES into TARGET. */
657 static void
658 expand_ubsan_result_store (rtx target, rtx res)
660 if (GET_CODE (target) == SUBREG && SUBREG_PROMOTED_VAR_P (target))
661 /* If this is a scalar in a register that is stored in a wider mode
662 than the declared mode, compute the result into its declared mode
663 and then convert to the wider mode. Our value is the computed
664 expression. */
665 convert_move (SUBREG_REG (target), res, SUBREG_PROMOTED_SIGN (target));
666 else
667 emit_move_insn (target, res);
670 /* Add sub/add overflow checking to the statement STMT.
671 CODE says whether the operation is +, or -. */
673 static void
674 expand_addsub_overflow (location_t loc, tree_code code, tree lhs,
675 tree arg0, tree arg1, bool unsr_p, bool uns0_p,
676 bool uns1_p, bool is_ubsan, tree *datap)
678 rtx res, target = NULL_RTX;
679 tree fn;
680 rtx_code_label *done_label = gen_label_rtx ();
681 rtx_code_label *do_error = gen_label_rtx ();
682 do_pending_stack_adjust ();
683 rtx op0 = expand_normal (arg0);
684 rtx op1 = expand_normal (arg1);
685 scalar_int_mode mode = SCALAR_INT_TYPE_MODE (TREE_TYPE (arg0));
686 int prec = GET_MODE_PRECISION (mode);
687 rtx sgn = immed_wide_int_const (wi::min_value (prec, SIGNED), mode);
688 bool do_xor = false;
690 if (is_ubsan)
691 gcc_assert (!unsr_p && !uns0_p && !uns1_p);
693 if (lhs)
695 target = expand_expr (lhs, NULL_RTX, VOIDmode, EXPAND_WRITE);
696 if (!is_ubsan)
697 write_complex_part (target, const0_rtx, true);
700 /* We assume both operands and result have the same precision
701 here (GET_MODE_BITSIZE (mode)), S stands for signed type
702 with that precision, U for unsigned type with that precision,
703 sgn for unsigned most significant bit in that precision.
704 s1 is signed first operand, u1 is unsigned first operand,
705 s2 is signed second operand, u2 is unsigned second operand,
706 sr is signed result, ur is unsigned result and the following
707 rules say how to compute result (which is always result of
708 the operands as if both were unsigned, cast to the right
709 signedness) and how to compute whether operation overflowed.
711 s1 + s2 -> sr
712 res = (S) ((U) s1 + (U) s2)
713 ovf = s2 < 0 ? res > s1 : res < s1 (or jump on overflow)
714 s1 - s2 -> sr
715 res = (S) ((U) s1 - (U) s2)
716 ovf = s2 < 0 ? res < s1 : res > s2 (or jump on overflow)
717 u1 + u2 -> ur
718 res = u1 + u2
719 ovf = res < u1 (or jump on carry, but RTL opts will handle it)
720 u1 - u2 -> ur
721 res = u1 - u2
722 ovf = res > u1 (or jump on carry, but RTL opts will handle it)
723 s1 + u2 -> sr
724 res = (S) ((U) s1 + u2)
725 ovf = ((U) res ^ sgn) < u2
726 s1 + u2 -> ur
727 t1 = (S) (u2 ^ sgn)
728 t2 = s1 + t1
729 res = (U) t2 ^ sgn
730 ovf = t1 < 0 ? t2 > s1 : t2 < s1 (or jump on overflow)
731 s1 - u2 -> sr
732 res = (S) ((U) s1 - u2)
733 ovf = u2 > ((U) s1 ^ sgn)
734 s1 - u2 -> ur
735 res = (U) s1 - u2
736 ovf = s1 < 0 || u2 > (U) s1
737 u1 - s2 -> sr
738 res = u1 - (U) s2
739 ovf = u1 >= ((U) s2 ^ sgn)
740 u1 - s2 -> ur
741 t1 = u1 ^ sgn
742 t2 = t1 - (U) s2
743 res = t2 ^ sgn
744 ovf = s2 < 0 ? (S) t2 < (S) t1 : (S) t2 > (S) t1 (or jump on overflow)
745 s1 + s2 -> ur
746 res = (U) s1 + (U) s2
747 ovf = s2 < 0 ? (s1 | (S) res) < 0) : (s1 & (S) res) < 0)
748 u1 + u2 -> sr
749 res = (S) (u1 + u2)
750 ovf = (U) res < u2 || res < 0
751 u1 - u2 -> sr
752 res = (S) (u1 - u2)
753 ovf = u1 >= u2 ? res < 0 : res >= 0
754 s1 - s2 -> ur
755 res = (U) s1 - (U) s2
756 ovf = s2 >= 0 ? ((s1 | (S) res) < 0) : ((s1 & (S) res) < 0) */
758 if (code == PLUS_EXPR && uns0_p && !uns1_p)
760 /* PLUS_EXPR is commutative, if operand signedness differs,
761 canonicalize to the first operand being signed and second
762 unsigned to simplify following code. */
763 std::swap (op0, op1);
764 std::swap (arg0, arg1);
765 uns0_p = false;
766 uns1_p = true;
769 /* u1 +- u2 -> ur */
770 if (uns0_p && uns1_p && unsr_p)
772 insn_code icode = optab_handler (code == PLUS_EXPR ? uaddv4_optab
773 : usubv4_optab, mode);
774 if (icode != CODE_FOR_nothing)
776 struct expand_operand ops[4];
777 rtx_insn *last = get_last_insn ();
779 res = gen_reg_rtx (mode);
780 create_output_operand (&ops[0], res, mode);
781 create_input_operand (&ops[1], op0, mode);
782 create_input_operand (&ops[2], op1, mode);
783 create_fixed_operand (&ops[3], do_error);
784 if (maybe_expand_insn (icode, 4, ops))
786 last = get_last_insn ();
787 if (profile_status_for_fn (cfun) != PROFILE_ABSENT
788 && JUMP_P (last)
789 && any_condjump_p (last)
790 && !find_reg_note (last, REG_BR_PROB, 0))
791 add_reg_br_prob_note (last,
792 profile_probability::very_unlikely ());
793 emit_jump (done_label);
794 goto do_error_label;
797 delete_insns_since (last);
800 /* Compute the operation. On RTL level, the addition is always
801 unsigned. */
802 res = expand_binop (mode, code == PLUS_EXPR ? add_optab : sub_optab,
803 op0, op1, NULL_RTX, false, OPTAB_LIB_WIDEN);
804 rtx tem = op0;
805 /* For PLUS_EXPR, the operation is commutative, so we can pick
806 operand to compare against. For prec <= BITS_PER_WORD, I think
807 preferring REG operand is better over CONST_INT, because
808 the CONST_INT might enlarge the instruction or CSE would need
809 to figure out we'd already loaded it into a register before.
810 For prec > BITS_PER_WORD, I think CONST_INT might be more beneficial,
811 as then the multi-word comparison can be perhaps simplified. */
812 if (code == PLUS_EXPR
813 && (prec <= BITS_PER_WORD
814 ? (CONST_SCALAR_INT_P (op0) && REG_P (op1))
815 : CONST_SCALAR_INT_P (op1)))
816 tem = op1;
817 do_compare_rtx_and_jump (res, tem, code == PLUS_EXPR ? GEU : LEU,
818 true, mode, NULL_RTX, NULL, done_label,
819 profile_probability::very_likely ());
820 goto do_error_label;
823 /* s1 +- u2 -> sr */
824 if (!uns0_p && uns1_p && !unsr_p)
826 /* Compute the operation. On RTL level, the addition is always
827 unsigned. */
828 res = expand_binop (mode, code == PLUS_EXPR ? add_optab : sub_optab,
829 op0, op1, NULL_RTX, false, OPTAB_LIB_WIDEN);
830 rtx tem = expand_binop (mode, add_optab,
831 code == PLUS_EXPR ? res : op0, sgn,
832 NULL_RTX, false, OPTAB_LIB_WIDEN);
833 do_compare_rtx_and_jump (tem, op1, GEU, true, mode, NULL_RTX, NULL,
834 done_label, profile_probability::very_likely ());
835 goto do_error_label;
838 /* s1 + u2 -> ur */
839 if (code == PLUS_EXPR && !uns0_p && uns1_p && unsr_p)
841 op1 = expand_binop (mode, add_optab, op1, sgn, NULL_RTX, false,
842 OPTAB_LIB_WIDEN);
843 /* As we've changed op1, we have to avoid using the value range
844 for the original argument. */
845 arg1 = error_mark_node;
846 do_xor = true;
847 goto do_signed;
850 /* u1 - s2 -> ur */
851 if (code == MINUS_EXPR && uns0_p && !uns1_p && unsr_p)
853 op0 = expand_binop (mode, add_optab, op0, sgn, NULL_RTX, false,
854 OPTAB_LIB_WIDEN);
855 /* As we've changed op0, we have to avoid using the value range
856 for the original argument. */
857 arg0 = error_mark_node;
858 do_xor = true;
859 goto do_signed;
862 /* s1 - u2 -> ur */
863 if (code == MINUS_EXPR && !uns0_p && uns1_p && unsr_p)
865 /* Compute the operation. On RTL level, the addition is always
866 unsigned. */
867 res = expand_binop (mode, sub_optab, op0, op1, NULL_RTX, false,
868 OPTAB_LIB_WIDEN);
869 int pos_neg = get_range_pos_neg (arg0);
870 if (pos_neg == 2)
871 /* If ARG0 is known to be always negative, this is always overflow. */
872 emit_jump (do_error);
873 else if (pos_neg == 3)
874 /* If ARG0 is not known to be always positive, check at runtime. */
875 do_compare_rtx_and_jump (op0, const0_rtx, LT, false, mode, NULL_RTX,
876 NULL, do_error, profile_probability::very_unlikely ());
877 do_compare_rtx_and_jump (op1, op0, LEU, true, mode, NULL_RTX, NULL,
878 done_label, profile_probability::very_likely ());
879 goto do_error_label;
882 /* u1 - s2 -> sr */
883 if (code == MINUS_EXPR && uns0_p && !uns1_p && !unsr_p)
885 /* Compute the operation. On RTL level, the addition is always
886 unsigned. */
887 res = expand_binop (mode, sub_optab, op0, op1, NULL_RTX, false,
888 OPTAB_LIB_WIDEN);
889 rtx tem = expand_binop (mode, add_optab, op1, sgn, NULL_RTX, false,
890 OPTAB_LIB_WIDEN);
891 do_compare_rtx_and_jump (op0, tem, LTU, true, mode, NULL_RTX, NULL,
892 done_label, profile_probability::very_likely ());
893 goto do_error_label;
896 /* u1 + u2 -> sr */
897 if (code == PLUS_EXPR && uns0_p && uns1_p && !unsr_p)
899 /* Compute the operation. On RTL level, the addition is always
900 unsigned. */
901 res = expand_binop (mode, add_optab, op0, op1, NULL_RTX, false,
902 OPTAB_LIB_WIDEN);
903 do_compare_rtx_and_jump (res, const0_rtx, LT, false, mode, NULL_RTX,
904 NULL, do_error, profile_probability::very_unlikely ());
905 rtx tem = op1;
906 /* The operation is commutative, so we can pick operand to compare
907 against. For prec <= BITS_PER_WORD, I think preferring REG operand
908 is better over CONST_INT, because the CONST_INT might enlarge the
909 instruction or CSE would need to figure out we'd already loaded it
910 into a register before. For prec > BITS_PER_WORD, I think CONST_INT
911 might be more beneficial, as then the multi-word comparison can be
912 perhaps simplified. */
913 if (prec <= BITS_PER_WORD
914 ? (CONST_SCALAR_INT_P (op1) && REG_P (op0))
915 : CONST_SCALAR_INT_P (op0))
916 tem = op0;
917 do_compare_rtx_and_jump (res, tem, GEU, true, mode, NULL_RTX, NULL,
918 done_label, profile_probability::very_likely ());
919 goto do_error_label;
922 /* s1 +- s2 -> ur */
923 if (!uns0_p && !uns1_p && unsr_p)
925 /* Compute the operation. On RTL level, the addition is always
926 unsigned. */
927 res = expand_binop (mode, code == PLUS_EXPR ? add_optab : sub_optab,
928 op0, op1, NULL_RTX, false, OPTAB_LIB_WIDEN);
929 int pos_neg = get_range_pos_neg (arg1);
930 if (code == PLUS_EXPR)
932 int pos_neg0 = get_range_pos_neg (arg0);
933 if (pos_neg0 != 3 && pos_neg == 3)
935 std::swap (op0, op1);
936 pos_neg = pos_neg0;
939 rtx tem;
940 if (pos_neg != 3)
942 tem = expand_binop (mode, ((pos_neg == 1) ^ (code == MINUS_EXPR))
943 ? and_optab : ior_optab,
944 op0, res, NULL_RTX, false, OPTAB_LIB_WIDEN);
945 do_compare_rtx_and_jump (tem, const0_rtx, GE, false, mode, NULL,
946 NULL, done_label, profile_probability::very_likely ());
948 else
950 rtx_code_label *do_ior_label = gen_label_rtx ();
951 do_compare_rtx_and_jump (op1, const0_rtx,
952 code == MINUS_EXPR ? GE : LT, false, mode,
953 NULL_RTX, NULL, do_ior_label,
954 profile_probability::even ());
955 tem = expand_binop (mode, and_optab, op0, res, NULL_RTX, false,
956 OPTAB_LIB_WIDEN);
957 do_compare_rtx_and_jump (tem, const0_rtx, GE, false, mode, NULL_RTX,
958 NULL, done_label, profile_probability::very_likely ());
959 emit_jump (do_error);
960 emit_label (do_ior_label);
961 tem = expand_binop (mode, ior_optab, op0, res, NULL_RTX, false,
962 OPTAB_LIB_WIDEN);
963 do_compare_rtx_and_jump (tem, const0_rtx, GE, false, mode, NULL_RTX,
964 NULL, done_label, profile_probability::very_likely ());
966 goto do_error_label;
969 /* u1 - u2 -> sr */
970 if (code == MINUS_EXPR && uns0_p && uns1_p && !unsr_p)
972 /* Compute the operation. On RTL level, the addition is always
973 unsigned. */
974 res = expand_binop (mode, sub_optab, op0, op1, NULL_RTX, false,
975 OPTAB_LIB_WIDEN);
976 rtx_code_label *op0_geu_op1 = gen_label_rtx ();
977 do_compare_rtx_and_jump (op0, op1, GEU, true, mode, NULL_RTX, NULL,
978 op0_geu_op1, profile_probability::even ());
979 do_compare_rtx_and_jump (res, const0_rtx, LT, false, mode, NULL_RTX,
980 NULL, done_label, profile_probability::very_likely ());
981 emit_jump (do_error);
982 emit_label (op0_geu_op1);
983 do_compare_rtx_and_jump (res, const0_rtx, GE, false, mode, NULL_RTX,
984 NULL, done_label, profile_probability::very_likely ());
985 goto do_error_label;
988 gcc_assert (!uns0_p && !uns1_p && !unsr_p);
990 /* s1 +- s2 -> sr */
991 do_signed:
993 insn_code icode = optab_handler (code == PLUS_EXPR ? addv4_optab
994 : subv4_optab, mode);
995 if (icode != CODE_FOR_nothing)
997 struct expand_operand ops[4];
998 rtx_insn *last = get_last_insn ();
1000 res = gen_reg_rtx (mode);
1001 create_output_operand (&ops[0], res, mode);
1002 create_input_operand (&ops[1], op0, mode);
1003 create_input_operand (&ops[2], op1, mode);
1004 create_fixed_operand (&ops[3], do_error);
1005 if (maybe_expand_insn (icode, 4, ops))
1007 last = get_last_insn ();
1008 if (profile_status_for_fn (cfun) != PROFILE_ABSENT
1009 && JUMP_P (last)
1010 && any_condjump_p (last)
1011 && !find_reg_note (last, REG_BR_PROB, 0))
1012 add_reg_br_prob_note (last,
1013 profile_probability::very_unlikely ());
1014 emit_jump (done_label);
1015 goto do_error_label;
1018 delete_insns_since (last);
1021 /* Compute the operation. On RTL level, the addition is always
1022 unsigned. */
1023 res = expand_binop (mode, code == PLUS_EXPR ? add_optab : sub_optab,
1024 op0, op1, NULL_RTX, false, OPTAB_LIB_WIDEN);
1026 /* If we can prove that one of the arguments (for MINUS_EXPR only
1027 the second operand, as subtraction is not commutative) is always
1028 non-negative or always negative, we can do just one comparison
1029 and conditional jump. */
1030 int pos_neg = get_range_pos_neg (arg1);
1031 if (code == PLUS_EXPR)
1033 int pos_neg0 = get_range_pos_neg (arg0);
1034 if (pos_neg0 != 3 && pos_neg == 3)
1036 std::swap (op0, op1);
1037 pos_neg = pos_neg0;
1041 /* Addition overflows if and only if the two operands have the same sign,
1042 and the result has the opposite sign. Subtraction overflows if and
1043 only if the two operands have opposite sign, and the subtrahend has
1044 the same sign as the result. Here 0 is counted as positive. */
1045 if (pos_neg == 3)
1047 /* Compute op0 ^ op1 (operands have opposite sign). */
1048 rtx op_xor = expand_binop (mode, xor_optab, op0, op1, NULL_RTX, false,
1049 OPTAB_LIB_WIDEN);
1051 /* Compute res ^ op1 (result and 2nd operand have opposite sign). */
1052 rtx res_xor = expand_binop (mode, xor_optab, res, op1, NULL_RTX, false,
1053 OPTAB_LIB_WIDEN);
1055 rtx tem;
1056 if (code == PLUS_EXPR)
1058 /* Compute (res ^ op1) & ~(op0 ^ op1). */
1059 tem = expand_unop (mode, one_cmpl_optab, op_xor, NULL_RTX, false);
1060 tem = expand_binop (mode, and_optab, res_xor, tem, NULL_RTX, false,
1061 OPTAB_LIB_WIDEN);
1063 else
1065 /* Compute (op0 ^ op1) & ~(res ^ op1). */
1066 tem = expand_unop (mode, one_cmpl_optab, res_xor, NULL_RTX, false);
1067 tem = expand_binop (mode, and_optab, op_xor, tem, NULL_RTX, false,
1068 OPTAB_LIB_WIDEN);
1071 /* No overflow if the result has bit sign cleared. */
1072 do_compare_rtx_and_jump (tem, const0_rtx, GE, false, mode, NULL_RTX,
1073 NULL, done_label, profile_probability::very_likely ());
1076 /* Compare the result of the operation with the first operand.
1077 No overflow for addition if second operand is positive and result
1078 is larger or second operand is negative and result is smaller.
1079 Likewise for subtraction with sign of second operand flipped. */
1080 else
1081 do_compare_rtx_and_jump (res, op0,
1082 (pos_neg == 1) ^ (code == MINUS_EXPR) ? GE : LE,
1083 false, mode, NULL_RTX, NULL, done_label,
1084 profile_probability::very_likely ());
1087 do_error_label:
1088 emit_label (do_error);
1089 if (is_ubsan)
1091 /* Expand the ubsan builtin call. */
1092 push_temp_slots ();
1093 fn = ubsan_build_overflow_builtin (code, loc, TREE_TYPE (arg0),
1094 arg0, arg1, datap);
1095 expand_normal (fn);
1096 pop_temp_slots ();
1097 do_pending_stack_adjust ();
1099 else if (lhs)
1100 expand_arith_set_overflow (lhs, target);
1102 /* We're done. */
1103 emit_label (done_label);
1105 if (lhs)
1107 if (is_ubsan)
1108 expand_ubsan_result_store (target, res);
1109 else
1111 if (do_xor)
1112 res = expand_binop (mode, add_optab, res, sgn, NULL_RTX, false,
1113 OPTAB_LIB_WIDEN);
1115 expand_arith_overflow_result_store (lhs, target, mode, res);
1120 /* Add negate overflow checking to the statement STMT. */
1122 static void
1123 expand_neg_overflow (location_t loc, tree lhs, tree arg1, bool is_ubsan,
1124 tree *datap)
1126 rtx res, op1;
1127 tree fn;
1128 rtx_code_label *done_label, *do_error;
1129 rtx target = NULL_RTX;
1131 done_label = gen_label_rtx ();
1132 do_error = gen_label_rtx ();
1134 do_pending_stack_adjust ();
1135 op1 = expand_normal (arg1);
1137 scalar_int_mode mode = SCALAR_INT_TYPE_MODE (TREE_TYPE (arg1));
1138 if (lhs)
1140 target = expand_expr (lhs, NULL_RTX, VOIDmode, EXPAND_WRITE);
1141 if (!is_ubsan)
1142 write_complex_part (target, const0_rtx, true);
1145 enum insn_code icode = optab_handler (negv3_optab, mode);
1146 if (icode != CODE_FOR_nothing)
1148 struct expand_operand ops[3];
1149 rtx_insn *last = get_last_insn ();
1151 res = gen_reg_rtx (mode);
1152 create_output_operand (&ops[0], res, mode);
1153 create_input_operand (&ops[1], op1, mode);
1154 create_fixed_operand (&ops[2], do_error);
1155 if (maybe_expand_insn (icode, 3, ops))
1157 last = get_last_insn ();
1158 if (profile_status_for_fn (cfun) != PROFILE_ABSENT
1159 && JUMP_P (last)
1160 && any_condjump_p (last)
1161 && !find_reg_note (last, REG_BR_PROB, 0))
1162 add_reg_br_prob_note (last,
1163 profile_probability::very_unlikely ());
1164 emit_jump (done_label);
1166 else
1168 delete_insns_since (last);
1169 icode = CODE_FOR_nothing;
1173 if (icode == CODE_FOR_nothing)
1175 /* Compute the operation. On RTL level, the addition is always
1176 unsigned. */
1177 res = expand_unop (mode, neg_optab, op1, NULL_RTX, false);
1179 /* Compare the operand with the most negative value. */
1180 rtx minv = expand_normal (TYPE_MIN_VALUE (TREE_TYPE (arg1)));
1181 do_compare_rtx_and_jump (op1, minv, NE, true, mode, NULL_RTX, NULL,
1182 done_label, profile_probability::very_likely ());
1185 emit_label (do_error);
1186 if (is_ubsan)
1188 /* Expand the ubsan builtin call. */
1189 push_temp_slots ();
1190 fn = ubsan_build_overflow_builtin (NEGATE_EXPR, loc, TREE_TYPE (arg1),
1191 arg1, NULL_TREE, datap);
1192 expand_normal (fn);
1193 pop_temp_slots ();
1194 do_pending_stack_adjust ();
1196 else if (lhs)
1197 expand_arith_set_overflow (lhs, target);
1199 /* We're done. */
1200 emit_label (done_label);
1202 if (lhs)
1204 if (is_ubsan)
1205 expand_ubsan_result_store (target, res);
1206 else
1207 expand_arith_overflow_result_store (lhs, target, mode, res);
1211 /* Return true if UNS WIDEN_MULT_EXPR with result mode WMODE and operand
1212 mode MODE can be expanded without using a libcall. */
1214 static bool
1215 can_widen_mult_without_libcall (scalar_int_mode wmode, scalar_int_mode mode,
1216 rtx op0, rtx op1, bool uns)
1218 if (find_widening_optab_handler (umul_widen_optab, wmode, mode)
1219 != CODE_FOR_nothing)
1220 return true;
1222 if (find_widening_optab_handler (smul_widen_optab, wmode, mode)
1223 != CODE_FOR_nothing)
1224 return true;
1226 rtx_insn *last = get_last_insn ();
1227 if (CONSTANT_P (op0))
1228 op0 = convert_modes (wmode, mode, op0, uns);
1229 else
1230 op0 = gen_raw_REG (wmode, LAST_VIRTUAL_REGISTER + 1);
1231 if (CONSTANT_P (op1))
1232 op1 = convert_modes (wmode, mode, op1, uns);
1233 else
1234 op1 = gen_raw_REG (wmode, LAST_VIRTUAL_REGISTER + 2);
1235 rtx ret = expand_mult (wmode, op0, op1, NULL_RTX, uns, true);
1236 delete_insns_since (last);
1237 return ret != NULL_RTX;
1240 /* Add mul overflow checking to the statement STMT. */
1242 static void
1243 expand_mul_overflow (location_t loc, tree lhs, tree arg0, tree arg1,
1244 bool unsr_p, bool uns0_p, bool uns1_p, bool is_ubsan,
1245 tree *datap)
1247 rtx res, op0, op1;
1248 tree fn, type;
1249 rtx_code_label *done_label, *do_error;
1250 rtx target = NULL_RTX;
1251 signop sign;
1252 enum insn_code icode;
1254 done_label = gen_label_rtx ();
1255 do_error = gen_label_rtx ();
1257 do_pending_stack_adjust ();
1258 op0 = expand_normal (arg0);
1259 op1 = expand_normal (arg1);
1261 scalar_int_mode mode = SCALAR_INT_TYPE_MODE (TREE_TYPE (arg0));
1262 bool uns = unsr_p;
1263 if (lhs)
1265 target = expand_expr (lhs, NULL_RTX, VOIDmode, EXPAND_WRITE);
1266 if (!is_ubsan)
1267 write_complex_part (target, const0_rtx, true);
1270 if (is_ubsan)
1271 gcc_assert (!unsr_p && !uns0_p && !uns1_p);
1273 /* We assume both operands and result have the same precision
1274 here (GET_MODE_BITSIZE (mode)), S stands for signed type
1275 with that precision, U for unsigned type with that precision,
1276 sgn for unsigned most significant bit in that precision.
1277 s1 is signed first operand, u1 is unsigned first operand,
1278 s2 is signed second operand, u2 is unsigned second operand,
1279 sr is signed result, ur is unsigned result and the following
1280 rules say how to compute result (which is always result of
1281 the operands as if both were unsigned, cast to the right
1282 signedness) and how to compute whether operation overflowed.
1283 main_ovf (false) stands for jump on signed multiplication
1284 overflow or the main algorithm with uns == false.
1285 main_ovf (true) stands for jump on unsigned multiplication
1286 overflow or the main algorithm with uns == true.
1288 s1 * s2 -> sr
1289 res = (S) ((U) s1 * (U) s2)
1290 ovf = main_ovf (false)
1291 u1 * u2 -> ur
1292 res = u1 * u2
1293 ovf = main_ovf (true)
1294 s1 * u2 -> ur
1295 res = (U) s1 * u2
1296 ovf = (s1 < 0 && u2) || main_ovf (true)
1297 u1 * u2 -> sr
1298 res = (S) (u1 * u2)
1299 ovf = res < 0 || main_ovf (true)
1300 s1 * u2 -> sr
1301 res = (S) ((U) s1 * u2)
1302 ovf = (S) u2 >= 0 ? main_ovf (false)
1303 : (s1 != 0 && (s1 != -1 || u2 != (U) res))
1304 s1 * s2 -> ur
1305 t1 = (s1 & s2) < 0 ? (-(U) s1) : ((U) s1)
1306 t2 = (s1 & s2) < 0 ? (-(U) s2) : ((U) s2)
1307 res = t1 * t2
1308 ovf = (s1 ^ s2) < 0 ? (s1 && s2) : main_ovf (true) */
1310 if (uns0_p && !uns1_p)
1312 /* Multiplication is commutative, if operand signedness differs,
1313 canonicalize to the first operand being signed and second
1314 unsigned to simplify following code. */
1315 std::swap (op0, op1);
1316 std::swap (arg0, arg1);
1317 uns0_p = false;
1318 uns1_p = true;
1321 int pos_neg0 = get_range_pos_neg (arg0);
1322 int pos_neg1 = get_range_pos_neg (arg1);
1324 /* s1 * u2 -> ur */
1325 if (!uns0_p && uns1_p && unsr_p)
1327 switch (pos_neg0)
1329 case 1:
1330 /* If s1 is non-negative, just perform normal u1 * u2 -> ur. */
1331 goto do_main;
1332 case 2:
1333 /* If s1 is negative, avoid the main code, just multiply and
1334 signal overflow if op1 is not 0. */
1335 struct separate_ops ops;
1336 ops.code = MULT_EXPR;
1337 ops.type = TREE_TYPE (arg1);
1338 ops.op0 = make_tree (ops.type, op0);
1339 ops.op1 = make_tree (ops.type, op1);
1340 ops.op2 = NULL_TREE;
1341 ops.location = loc;
1342 res = expand_expr_real_2 (&ops, NULL_RTX, mode, EXPAND_NORMAL);
1343 do_compare_rtx_and_jump (op1, const0_rtx, EQ, true, mode, NULL_RTX,
1344 NULL, done_label, profile_probability::very_likely ());
1345 goto do_error_label;
1346 case 3:
1347 rtx_code_label *do_main_label;
1348 do_main_label = gen_label_rtx ();
1349 do_compare_rtx_and_jump (op0, const0_rtx, GE, false, mode, NULL_RTX,
1350 NULL, do_main_label, profile_probability::very_likely ());
1351 do_compare_rtx_and_jump (op1, const0_rtx, EQ, true, mode, NULL_RTX,
1352 NULL, do_main_label, profile_probability::very_likely ());
1353 expand_arith_set_overflow (lhs, target);
1354 emit_label (do_main_label);
1355 goto do_main;
1356 default:
1357 gcc_unreachable ();
1361 /* u1 * u2 -> sr */
1362 if (uns0_p && uns1_p && !unsr_p)
1364 uns = true;
1365 /* Rest of handling of this case after res is computed. */
1366 goto do_main;
1369 /* s1 * u2 -> sr */
1370 if (!uns0_p && uns1_p && !unsr_p)
1372 switch (pos_neg1)
1374 case 1:
1375 goto do_main;
1376 case 2:
1377 /* If (S) u2 is negative (i.e. u2 is larger than maximum of S,
1378 avoid the main code, just multiply and signal overflow
1379 unless 0 * u2 or -1 * ((U) Smin). */
1380 struct separate_ops ops;
1381 ops.code = MULT_EXPR;
1382 ops.type = TREE_TYPE (arg1);
1383 ops.op0 = make_tree (ops.type, op0);
1384 ops.op1 = make_tree (ops.type, op1);
1385 ops.op2 = NULL_TREE;
1386 ops.location = loc;
1387 res = expand_expr_real_2 (&ops, NULL_RTX, mode, EXPAND_NORMAL);
1388 do_compare_rtx_and_jump (op0, const0_rtx, EQ, true, mode, NULL_RTX,
1389 NULL, done_label, profile_probability::very_likely ());
1390 do_compare_rtx_and_jump (op0, constm1_rtx, NE, true, mode, NULL_RTX,
1391 NULL, do_error, profile_probability::very_unlikely ());
1392 int prec;
1393 prec = GET_MODE_PRECISION (mode);
1394 rtx sgn;
1395 sgn = immed_wide_int_const (wi::min_value (prec, SIGNED), mode);
1396 do_compare_rtx_and_jump (op1, sgn, EQ, true, mode, NULL_RTX,
1397 NULL, done_label, profile_probability::very_likely ());
1398 goto do_error_label;
1399 case 3:
1400 /* Rest of handling of this case after res is computed. */
1401 goto do_main;
1402 default:
1403 gcc_unreachable ();
1407 /* s1 * s2 -> ur */
1408 if (!uns0_p && !uns1_p && unsr_p)
1410 rtx tem, tem2;
1411 switch (pos_neg0 | pos_neg1)
1413 case 1: /* Both operands known to be non-negative. */
1414 goto do_main;
1415 case 2: /* Both operands known to be negative. */
1416 op0 = expand_unop (mode, neg_optab, op0, NULL_RTX, false);
1417 op1 = expand_unop (mode, neg_optab, op1, NULL_RTX, false);
1418 /* Avoid looking at arg0/arg1 ranges, as we've changed
1419 the arguments. */
1420 arg0 = error_mark_node;
1421 arg1 = error_mark_node;
1422 goto do_main;
1423 case 3:
1424 if ((pos_neg0 ^ pos_neg1) == 3)
1426 /* If one operand is known to be negative and the other
1427 non-negative, this overflows always, unless the non-negative
1428 one is 0. Just do normal multiply and set overflow
1429 unless one of the operands is 0. */
1430 struct separate_ops ops;
1431 ops.code = MULT_EXPR;
1432 ops.type
1433 = build_nonstandard_integer_type (GET_MODE_PRECISION (mode),
1435 ops.op0 = make_tree (ops.type, op0);
1436 ops.op1 = make_tree (ops.type, op1);
1437 ops.op2 = NULL_TREE;
1438 ops.location = loc;
1439 res = expand_expr_real_2 (&ops, NULL_RTX, mode, EXPAND_NORMAL);
1440 tem = expand_binop (mode, and_optab, op0, op1, NULL_RTX, false,
1441 OPTAB_LIB_WIDEN);
1442 do_compare_rtx_and_jump (tem, const0_rtx, EQ, true, mode,
1443 NULL_RTX, NULL, done_label,
1444 profile_probability::very_likely ());
1445 goto do_error_label;
1447 /* The general case, do all the needed comparisons at runtime. */
1448 rtx_code_label *do_main_label, *after_negate_label;
1449 rtx rop0, rop1;
1450 rop0 = gen_reg_rtx (mode);
1451 rop1 = gen_reg_rtx (mode);
1452 emit_move_insn (rop0, op0);
1453 emit_move_insn (rop1, op1);
1454 op0 = rop0;
1455 op1 = rop1;
1456 do_main_label = gen_label_rtx ();
1457 after_negate_label = gen_label_rtx ();
1458 tem = expand_binop (mode, and_optab, op0, op1, NULL_RTX, false,
1459 OPTAB_LIB_WIDEN);
1460 do_compare_rtx_and_jump (tem, const0_rtx, GE, false, mode, NULL_RTX,
1461 NULL, after_negate_label, profile_probability::very_likely ());
1462 /* Both arguments negative here, negate them and continue with
1463 normal unsigned overflow checking multiplication. */
1464 emit_move_insn (op0, expand_unop (mode, neg_optab, op0,
1465 NULL_RTX, false));
1466 emit_move_insn (op1, expand_unop (mode, neg_optab, op1,
1467 NULL_RTX, false));
1468 /* Avoid looking at arg0/arg1 ranges, as we might have changed
1469 the arguments. */
1470 arg0 = error_mark_node;
1471 arg1 = error_mark_node;
1472 emit_jump (do_main_label);
1473 emit_label (after_negate_label);
1474 tem2 = expand_binop (mode, xor_optab, op0, op1, NULL_RTX, false,
1475 OPTAB_LIB_WIDEN);
1476 do_compare_rtx_and_jump (tem2, const0_rtx, GE, false, mode, NULL_RTX,
1477 NULL, do_main_label, profile_probability::very_likely ());
1478 /* One argument is negative here, the other positive. This
1479 overflows always, unless one of the arguments is 0. But
1480 if e.g. s2 is 0, (U) s1 * 0 doesn't overflow, whatever s1
1481 is, thus we can keep do_main code oring in overflow as is. */
1482 do_compare_rtx_and_jump (tem, const0_rtx, EQ, true, mode, NULL_RTX,
1483 NULL, do_main_label, profile_probability::very_likely ());
1484 expand_arith_set_overflow (lhs, target);
1485 emit_label (do_main_label);
1486 goto do_main;
1487 default:
1488 gcc_unreachable ();
1492 do_main:
1493 type = build_nonstandard_integer_type (GET_MODE_PRECISION (mode), uns);
1494 sign = uns ? UNSIGNED : SIGNED;
1495 icode = optab_handler (uns ? umulv4_optab : mulv4_optab, mode);
1496 if (uns
1497 && (integer_pow2p (arg0) || integer_pow2p (arg1))
1498 && (optimize_insn_for_speed_p () || icode == CODE_FOR_nothing))
1500 /* Optimize unsigned multiplication by power of 2 constant
1501 using 2 shifts, one for result, one to extract the shifted
1502 out bits to see if they are all zero.
1503 Don't do this if optimizing for size and we have umulv4_optab,
1504 in that case assume multiplication will be shorter.
1505 This is heuristics based on the single target that provides
1506 umulv4 right now (i?86/x86_64), if further targets add it, this
1507 might need to be revisited.
1508 Cases where both operands are constant should be folded already
1509 during GIMPLE, and cases where one operand is constant but not
1510 power of 2 are questionable, either the WIDEN_MULT_EXPR case
1511 below can be done without multiplication, just by shifts and adds,
1512 or we'd need to divide the result (and hope it actually doesn't
1513 really divide nor multiply) and compare the result of the division
1514 with the original operand. */
1515 rtx opn0 = op0;
1516 rtx opn1 = op1;
1517 tree argn0 = arg0;
1518 tree argn1 = arg1;
1519 if (integer_pow2p (arg0))
1521 std::swap (opn0, opn1);
1522 std::swap (argn0, argn1);
1524 int cnt = tree_log2 (argn1);
1525 if (cnt >= 0 && cnt < GET_MODE_PRECISION (mode))
1527 rtx upper = const0_rtx;
1528 res = expand_shift (LSHIFT_EXPR, mode, opn0, cnt, NULL_RTX, uns);
1529 if (cnt != 0)
1530 upper = expand_shift (RSHIFT_EXPR, mode, opn0,
1531 GET_MODE_PRECISION (mode) - cnt,
1532 NULL_RTX, uns);
1533 do_compare_rtx_and_jump (upper, const0_rtx, EQ, true, mode,
1534 NULL_RTX, NULL, done_label,
1535 profile_probability::very_likely ());
1536 goto do_error_label;
1539 if (icode != CODE_FOR_nothing)
1541 struct expand_operand ops[4];
1542 rtx_insn *last = get_last_insn ();
1544 res = gen_reg_rtx (mode);
1545 create_output_operand (&ops[0], res, mode);
1546 create_input_operand (&ops[1], op0, mode);
1547 create_input_operand (&ops[2], op1, mode);
1548 create_fixed_operand (&ops[3], do_error);
1549 if (maybe_expand_insn (icode, 4, ops))
1551 last = get_last_insn ();
1552 if (profile_status_for_fn (cfun) != PROFILE_ABSENT
1553 && JUMP_P (last)
1554 && any_condjump_p (last)
1555 && !find_reg_note (last, REG_BR_PROB, 0))
1556 add_reg_br_prob_note (last,
1557 profile_probability::very_unlikely ());
1558 emit_jump (done_label);
1560 else
1562 delete_insns_since (last);
1563 icode = CODE_FOR_nothing;
1567 if (icode == CODE_FOR_nothing)
1569 struct separate_ops ops;
1570 int prec = GET_MODE_PRECISION (mode);
1571 scalar_int_mode hmode, wmode;
1572 ops.op0 = make_tree (type, op0);
1573 ops.op1 = make_tree (type, op1);
1574 ops.op2 = NULL_TREE;
1575 ops.location = loc;
1577 /* Optimize unsigned overflow check where we don't use the
1578 multiplication result, just whether overflow happened.
1579 If we can do MULT_HIGHPART_EXPR, that followed by
1580 comparison of the result against zero is cheapest.
1581 We'll still compute res, but it should be DCEd later. */
1582 use_operand_p use;
1583 gimple *use_stmt;
1584 if (!is_ubsan
1585 && lhs
1586 && uns
1587 && !(uns0_p && uns1_p && !unsr_p)
1588 && can_mult_highpart_p (mode, uns) == 1
1589 && single_imm_use (lhs, &use, &use_stmt)
1590 && is_gimple_assign (use_stmt)
1591 && gimple_assign_rhs_code (use_stmt) == IMAGPART_EXPR)
1592 goto highpart;
1594 if (GET_MODE_2XWIDER_MODE (mode).exists (&wmode)
1595 && targetm.scalar_mode_supported_p (wmode)
1596 && can_widen_mult_without_libcall (wmode, mode, op0, op1, uns))
1598 twoxwider:
1599 ops.code = WIDEN_MULT_EXPR;
1600 ops.type
1601 = build_nonstandard_integer_type (GET_MODE_PRECISION (wmode), uns);
1603 res = expand_expr_real_2 (&ops, NULL_RTX, wmode, EXPAND_NORMAL);
1604 rtx hipart = expand_shift (RSHIFT_EXPR, wmode, res, prec,
1605 NULL_RTX, uns);
1606 hipart = convert_modes (mode, wmode, hipart, uns);
1607 res = convert_modes (mode, wmode, res, uns);
1608 if (uns)
1609 /* For the unsigned multiplication, there was overflow if
1610 HIPART is non-zero. */
1611 do_compare_rtx_and_jump (hipart, const0_rtx, EQ, true, mode,
1612 NULL_RTX, NULL, done_label,
1613 profile_probability::very_likely ());
1614 else
1616 rtx signbit = expand_shift (RSHIFT_EXPR, mode, res, prec - 1,
1617 NULL_RTX, 0);
1618 /* RES is low half of the double width result, HIPART
1619 the high half. There was overflow if
1620 HIPART is different from RES < 0 ? -1 : 0. */
1621 do_compare_rtx_and_jump (signbit, hipart, EQ, true, mode,
1622 NULL_RTX, NULL, done_label,
1623 profile_probability::very_likely ());
1626 else if (can_mult_highpart_p (mode, uns) == 1)
1628 highpart:
1629 ops.code = MULT_HIGHPART_EXPR;
1630 ops.type = type;
1632 rtx hipart = expand_expr_real_2 (&ops, NULL_RTX, mode,
1633 EXPAND_NORMAL);
1634 ops.code = MULT_EXPR;
1635 res = expand_expr_real_2 (&ops, NULL_RTX, mode, EXPAND_NORMAL);
1636 if (uns)
1637 /* For the unsigned multiplication, there was overflow if
1638 HIPART is non-zero. */
1639 do_compare_rtx_and_jump (hipart, const0_rtx, EQ, true, mode,
1640 NULL_RTX, NULL, done_label,
1641 profile_probability::very_likely ());
1642 else
1644 rtx signbit = expand_shift (RSHIFT_EXPR, mode, res, prec - 1,
1645 NULL_RTX, 0);
1646 /* RES is low half of the double width result, HIPART
1647 the high half. There was overflow if
1648 HIPART is different from RES < 0 ? -1 : 0. */
1649 do_compare_rtx_and_jump (signbit, hipart, EQ, true, mode,
1650 NULL_RTX, NULL, done_label,
1651 profile_probability::very_likely ());
1655 else if (int_mode_for_size (prec / 2, 1).exists (&hmode)
1656 && 2 * GET_MODE_PRECISION (hmode) == prec)
1658 rtx_code_label *large_op0 = gen_label_rtx ();
1659 rtx_code_label *small_op0_large_op1 = gen_label_rtx ();
1660 rtx_code_label *one_small_one_large = gen_label_rtx ();
1661 rtx_code_label *both_ops_large = gen_label_rtx ();
1662 rtx_code_label *after_hipart_neg = uns ? NULL : gen_label_rtx ();
1663 rtx_code_label *after_lopart_neg = uns ? NULL : gen_label_rtx ();
1664 rtx_code_label *do_overflow = gen_label_rtx ();
1665 rtx_code_label *hipart_different = uns ? NULL : gen_label_rtx ();
1667 unsigned int hprec = GET_MODE_PRECISION (hmode);
1668 rtx hipart0 = expand_shift (RSHIFT_EXPR, mode, op0, hprec,
1669 NULL_RTX, uns);
1670 hipart0 = convert_modes (hmode, mode, hipart0, uns);
1671 rtx lopart0 = convert_modes (hmode, mode, op0, uns);
1672 rtx signbit0 = const0_rtx;
1673 if (!uns)
1674 signbit0 = expand_shift (RSHIFT_EXPR, hmode, lopart0, hprec - 1,
1675 NULL_RTX, 0);
1676 rtx hipart1 = expand_shift (RSHIFT_EXPR, mode, op1, hprec,
1677 NULL_RTX, uns);
1678 hipart1 = convert_modes (hmode, mode, hipart1, uns);
1679 rtx lopart1 = convert_modes (hmode, mode, op1, uns);
1680 rtx signbit1 = const0_rtx;
1681 if (!uns)
1682 signbit1 = expand_shift (RSHIFT_EXPR, hmode, lopart1, hprec - 1,
1683 NULL_RTX, 0);
1685 res = gen_reg_rtx (mode);
1687 /* True if op0 resp. op1 are known to be in the range of
1688 halfstype. */
1689 bool op0_small_p = false;
1690 bool op1_small_p = false;
1691 /* True if op0 resp. op1 are known to have all zeros or all ones
1692 in the upper half of bits, but are not known to be
1693 op{0,1}_small_p. */
1694 bool op0_medium_p = false;
1695 bool op1_medium_p = false;
1696 /* -1 if op{0,1} is known to be negative, 0 if it is known to be
1697 nonnegative, 1 if unknown. */
1698 int op0_sign = 1;
1699 int op1_sign = 1;
1701 if (pos_neg0 == 1)
1702 op0_sign = 0;
1703 else if (pos_neg0 == 2)
1704 op0_sign = -1;
1705 if (pos_neg1 == 1)
1706 op1_sign = 0;
1707 else if (pos_neg1 == 2)
1708 op1_sign = -1;
1710 unsigned int mprec0 = prec;
1711 if (arg0 != error_mark_node)
1712 mprec0 = get_min_precision (arg0, sign);
1713 if (mprec0 <= hprec)
1714 op0_small_p = true;
1715 else if (!uns && mprec0 <= hprec + 1)
1716 op0_medium_p = true;
1717 unsigned int mprec1 = prec;
1718 if (arg1 != error_mark_node)
1719 mprec1 = get_min_precision (arg1, sign);
1720 if (mprec1 <= hprec)
1721 op1_small_p = true;
1722 else if (!uns && mprec1 <= hprec + 1)
1723 op1_medium_p = true;
1725 int smaller_sign = 1;
1726 int larger_sign = 1;
1727 if (op0_small_p)
1729 smaller_sign = op0_sign;
1730 larger_sign = op1_sign;
1732 else if (op1_small_p)
1734 smaller_sign = op1_sign;
1735 larger_sign = op0_sign;
1737 else if (op0_sign == op1_sign)
1739 smaller_sign = op0_sign;
1740 larger_sign = op0_sign;
1743 if (!op0_small_p)
1744 do_compare_rtx_and_jump (signbit0, hipart0, NE, true, hmode,
1745 NULL_RTX, NULL, large_op0,
1746 profile_probability::unlikely ());
1748 if (!op1_small_p)
1749 do_compare_rtx_and_jump (signbit1, hipart1, NE, true, hmode,
1750 NULL_RTX, NULL, small_op0_large_op1,
1751 profile_probability::unlikely ());
1753 /* If both op0 and op1 are sign (!uns) or zero (uns) extended from
1754 hmode to mode, the multiplication will never overflow. We can
1755 do just one hmode x hmode => mode widening multiplication. */
1756 rtx lopart0s = lopart0, lopart1s = lopart1;
1757 if (GET_CODE (lopart0) == SUBREG)
1759 lopart0s = shallow_copy_rtx (lopart0);
1760 SUBREG_PROMOTED_VAR_P (lopart0s) = 1;
1761 SUBREG_PROMOTED_SET (lopart0s, uns ? SRP_UNSIGNED : SRP_SIGNED);
1763 if (GET_CODE (lopart1) == SUBREG)
1765 lopart1s = shallow_copy_rtx (lopart1);
1766 SUBREG_PROMOTED_VAR_P (lopart1s) = 1;
1767 SUBREG_PROMOTED_SET (lopart1s, uns ? SRP_UNSIGNED : SRP_SIGNED);
1769 tree halfstype = build_nonstandard_integer_type (hprec, uns);
1770 ops.op0 = make_tree (halfstype, lopart0s);
1771 ops.op1 = make_tree (halfstype, lopart1s);
1772 ops.code = WIDEN_MULT_EXPR;
1773 ops.type = type;
1774 rtx thisres
1775 = expand_expr_real_2 (&ops, NULL_RTX, mode, EXPAND_NORMAL);
1776 emit_move_insn (res, thisres);
1777 emit_jump (done_label);
1779 emit_label (small_op0_large_op1);
1781 /* If op0 is sign (!uns) or zero (uns) extended from hmode to mode,
1782 but op1 is not, just swap the arguments and handle it as op1
1783 sign/zero extended, op0 not. */
1784 rtx larger = gen_reg_rtx (mode);
1785 rtx hipart = gen_reg_rtx (hmode);
1786 rtx lopart = gen_reg_rtx (hmode);
1787 emit_move_insn (larger, op1);
1788 emit_move_insn (hipart, hipart1);
1789 emit_move_insn (lopart, lopart0);
1790 emit_jump (one_small_one_large);
1792 emit_label (large_op0);
1794 if (!op1_small_p)
1795 do_compare_rtx_and_jump (signbit1, hipart1, NE, true, hmode,
1796 NULL_RTX, NULL, both_ops_large,
1797 profile_probability::unlikely ());
1799 /* If op1 is sign (!uns) or zero (uns) extended from hmode to mode,
1800 but op0 is not, prepare larger, hipart and lopart pseudos and
1801 handle it together with small_op0_large_op1. */
1802 emit_move_insn (larger, op0);
1803 emit_move_insn (hipart, hipart0);
1804 emit_move_insn (lopart, lopart1);
1806 emit_label (one_small_one_large);
1808 /* lopart is the low part of the operand that is sign extended
1809 to mode, larger is the other operand, hipart is the
1810 high part of larger and lopart0 and lopart1 are the low parts
1811 of both operands.
1812 We perform lopart0 * lopart1 and lopart * hipart widening
1813 multiplications. */
1814 tree halfutype = build_nonstandard_integer_type (hprec, 1);
1815 ops.op0 = make_tree (halfutype, lopart0);
1816 ops.op1 = make_tree (halfutype, lopart1);
1817 rtx lo0xlo1
1818 = expand_expr_real_2 (&ops, NULL_RTX, mode, EXPAND_NORMAL);
1820 ops.op0 = make_tree (halfutype, lopart);
1821 ops.op1 = make_tree (halfutype, hipart);
1822 rtx loxhi = gen_reg_rtx (mode);
1823 rtx tem = expand_expr_real_2 (&ops, NULL_RTX, mode, EXPAND_NORMAL);
1824 emit_move_insn (loxhi, tem);
1826 if (!uns)
1828 /* if (hipart < 0) loxhi -= lopart << (bitsize / 2); */
1829 if (larger_sign == 0)
1830 emit_jump (after_hipart_neg);
1831 else if (larger_sign != -1)
1832 do_compare_rtx_and_jump (hipart, const0_rtx, GE, false, hmode,
1833 NULL_RTX, NULL, after_hipart_neg,
1834 profile_probability::even ());
1836 tem = convert_modes (mode, hmode, lopart, 1);
1837 tem = expand_shift (LSHIFT_EXPR, mode, tem, hprec, NULL_RTX, 1);
1838 tem = expand_simple_binop (mode, MINUS, loxhi, tem, NULL_RTX,
1839 1, OPTAB_WIDEN);
1840 emit_move_insn (loxhi, tem);
1842 emit_label (after_hipart_neg);
1844 /* if (lopart < 0) loxhi -= larger; */
1845 if (smaller_sign == 0)
1846 emit_jump (after_lopart_neg);
1847 else if (smaller_sign != -1)
1848 do_compare_rtx_and_jump (lopart, const0_rtx, GE, false, hmode,
1849 NULL_RTX, NULL, after_lopart_neg,
1850 profile_probability::even ());
1852 tem = expand_simple_binop (mode, MINUS, loxhi, larger, NULL_RTX,
1853 1, OPTAB_WIDEN);
1854 emit_move_insn (loxhi, tem);
1856 emit_label (after_lopart_neg);
1859 /* loxhi += (uns) lo0xlo1 >> (bitsize / 2); */
1860 tem = expand_shift (RSHIFT_EXPR, mode, lo0xlo1, hprec, NULL_RTX, 1);
1861 tem = expand_simple_binop (mode, PLUS, loxhi, tem, NULL_RTX,
1862 1, OPTAB_WIDEN);
1863 emit_move_insn (loxhi, tem);
1865 /* if (loxhi >> (bitsize / 2)
1866 == (hmode) loxhi >> (bitsize / 2 - 1)) (if !uns)
1867 if (loxhi >> (bitsize / 2) == 0 (if uns). */
1868 rtx hipartloxhi = expand_shift (RSHIFT_EXPR, mode, loxhi, hprec,
1869 NULL_RTX, 0);
1870 hipartloxhi = convert_modes (hmode, mode, hipartloxhi, 0);
1871 rtx signbitloxhi = const0_rtx;
1872 if (!uns)
1873 signbitloxhi = expand_shift (RSHIFT_EXPR, hmode,
1874 convert_modes (hmode, mode,
1875 loxhi, 0),
1876 hprec - 1, NULL_RTX, 0);
1878 do_compare_rtx_and_jump (signbitloxhi, hipartloxhi, NE, true, hmode,
1879 NULL_RTX, NULL, do_overflow,
1880 profile_probability::very_unlikely ());
1882 /* res = (loxhi << (bitsize / 2)) | (hmode) lo0xlo1; */
1883 rtx loxhishifted = expand_shift (LSHIFT_EXPR, mode, loxhi, hprec,
1884 NULL_RTX, 1);
1885 tem = convert_modes (mode, hmode,
1886 convert_modes (hmode, mode, lo0xlo1, 1), 1);
1888 tem = expand_simple_binop (mode, IOR, loxhishifted, tem, res,
1889 1, OPTAB_WIDEN);
1890 if (tem != res)
1891 emit_move_insn (res, tem);
1892 emit_jump (done_label);
1894 emit_label (both_ops_large);
1896 /* If both operands are large (not sign (!uns) or zero (uns)
1897 extended from hmode), then perform the full multiplication
1898 which will be the result of the operation.
1899 The only cases which don't overflow are for signed multiplication
1900 some cases where both hipart0 and highpart1 are 0 or -1.
1901 For unsigned multiplication when high parts are both non-zero
1902 this overflows always. */
1903 ops.code = MULT_EXPR;
1904 ops.op0 = make_tree (type, op0);
1905 ops.op1 = make_tree (type, op1);
1906 tem = expand_expr_real_2 (&ops, NULL_RTX, mode, EXPAND_NORMAL);
1907 emit_move_insn (res, tem);
1909 if (!uns)
1911 if (!op0_medium_p)
1913 tem = expand_simple_binop (hmode, PLUS, hipart0, const1_rtx,
1914 NULL_RTX, 1, OPTAB_WIDEN);
1915 do_compare_rtx_and_jump (tem, const1_rtx, GTU, true, hmode,
1916 NULL_RTX, NULL, do_error,
1917 profile_probability::very_unlikely ());
1920 if (!op1_medium_p)
1922 tem = expand_simple_binop (hmode, PLUS, hipart1, const1_rtx,
1923 NULL_RTX, 1, OPTAB_WIDEN);
1924 do_compare_rtx_and_jump (tem, const1_rtx, GTU, true, hmode,
1925 NULL_RTX, NULL, do_error,
1926 profile_probability::very_unlikely ());
1929 /* At this point hipart{0,1} are both in [-1, 0]. If they are
1930 the same, overflow happened if res is non-positive, if they
1931 are different, overflow happened if res is positive. */
1932 if (op0_sign != 1 && op1_sign != 1 && op0_sign != op1_sign)
1933 emit_jump (hipart_different);
1934 else if (op0_sign == 1 || op1_sign == 1)
1935 do_compare_rtx_and_jump (hipart0, hipart1, NE, true, hmode,
1936 NULL_RTX, NULL, hipart_different,
1937 profile_probability::even ());
1939 do_compare_rtx_and_jump (res, const0_rtx, LE, false, mode,
1940 NULL_RTX, NULL, do_error,
1941 profile_probability::very_unlikely ());
1942 emit_jump (done_label);
1944 emit_label (hipart_different);
1946 do_compare_rtx_and_jump (res, const0_rtx, GE, false, mode,
1947 NULL_RTX, NULL, do_error,
1948 profile_probability::very_unlikely ());
1949 emit_jump (done_label);
1952 emit_label (do_overflow);
1954 /* Overflow, do full multiplication and fallthru into do_error. */
1955 ops.op0 = make_tree (type, op0);
1956 ops.op1 = make_tree (type, op1);
1957 tem = expand_expr_real_2 (&ops, NULL_RTX, mode, EXPAND_NORMAL);
1958 emit_move_insn (res, tem);
1960 else if (GET_MODE_2XWIDER_MODE (mode).exists (&wmode)
1961 && targetm.scalar_mode_supported_p (wmode))
1962 /* Even emitting a libcall is better than not detecting overflow
1963 at all. */
1964 goto twoxwider;
1965 else
1967 gcc_assert (!is_ubsan);
1968 ops.code = MULT_EXPR;
1969 ops.type = type;
1970 res = expand_expr_real_2 (&ops, NULL_RTX, mode, EXPAND_NORMAL);
1971 emit_jump (done_label);
1975 do_error_label:
1976 emit_label (do_error);
1977 if (is_ubsan)
1979 /* Expand the ubsan builtin call. */
1980 push_temp_slots ();
1981 fn = ubsan_build_overflow_builtin (MULT_EXPR, loc, TREE_TYPE (arg0),
1982 arg0, arg1, datap);
1983 expand_normal (fn);
1984 pop_temp_slots ();
1985 do_pending_stack_adjust ();
1987 else if (lhs)
1988 expand_arith_set_overflow (lhs, target);
1990 /* We're done. */
1991 emit_label (done_label);
1993 /* u1 * u2 -> sr */
1994 if (uns0_p && uns1_p && !unsr_p)
1996 rtx_code_label *all_done_label = gen_label_rtx ();
1997 do_compare_rtx_and_jump (res, const0_rtx, GE, false, mode, NULL_RTX,
1998 NULL, all_done_label, profile_probability::very_likely ());
1999 expand_arith_set_overflow (lhs, target);
2000 emit_label (all_done_label);
2003 /* s1 * u2 -> sr */
2004 if (!uns0_p && uns1_p && !unsr_p && pos_neg1 == 3)
2006 rtx_code_label *all_done_label = gen_label_rtx ();
2007 rtx_code_label *set_noovf = gen_label_rtx ();
2008 do_compare_rtx_and_jump (op1, const0_rtx, GE, false, mode, NULL_RTX,
2009 NULL, all_done_label, profile_probability::very_likely ());
2010 expand_arith_set_overflow (lhs, target);
2011 do_compare_rtx_and_jump (op0, const0_rtx, EQ, true, mode, NULL_RTX,
2012 NULL, set_noovf, profile_probability::very_likely ());
2013 do_compare_rtx_and_jump (op0, constm1_rtx, NE, true, mode, NULL_RTX,
2014 NULL, all_done_label, profile_probability::very_unlikely ());
2015 do_compare_rtx_and_jump (op1, res, NE, true, mode, NULL_RTX, NULL,
2016 all_done_label, profile_probability::very_unlikely ());
2017 emit_label (set_noovf);
2018 write_complex_part (target, const0_rtx, true);
2019 emit_label (all_done_label);
2022 if (lhs)
2024 if (is_ubsan)
2025 expand_ubsan_result_store (target, res);
2026 else
2027 expand_arith_overflow_result_store (lhs, target, mode, res);
2031 /* Expand UBSAN_CHECK_* internal function if it has vector operands. */
2033 static void
2034 expand_vector_ubsan_overflow (location_t loc, enum tree_code code, tree lhs,
2035 tree arg0, tree arg1)
2037 poly_uint64 cnt = TYPE_VECTOR_SUBPARTS (TREE_TYPE (arg0));
2038 rtx_code_label *loop_lab = NULL;
2039 rtx cntvar = NULL_RTX;
2040 tree cntv = NULL_TREE;
2041 tree eltype = TREE_TYPE (TREE_TYPE (arg0));
2042 tree sz = TYPE_SIZE (eltype);
2043 tree data = NULL_TREE;
2044 tree resv = NULL_TREE;
2045 rtx lhsr = NULL_RTX;
2046 rtx resvr = NULL_RTX;
2047 unsigned HOST_WIDE_INT const_cnt = 0;
2048 bool use_loop_p = (!cnt.is_constant (&const_cnt) || const_cnt > 4);
2050 if (lhs)
2052 optab op;
2053 lhsr = expand_expr (lhs, NULL_RTX, VOIDmode, EXPAND_WRITE);
2054 if (!VECTOR_MODE_P (GET_MODE (lhsr))
2055 || (op = optab_for_tree_code (code, TREE_TYPE (arg0),
2056 optab_default)) == unknown_optab
2057 || (optab_handler (op, TYPE_MODE (TREE_TYPE (arg0)))
2058 == CODE_FOR_nothing))
2060 if (MEM_P (lhsr))
2061 resv = make_tree (TREE_TYPE (lhs), lhsr);
2062 else
2064 resvr = assign_temp (TREE_TYPE (lhs), 1, 1);
2065 resv = make_tree (TREE_TYPE (lhs), resvr);
2069 if (use_loop_p)
2071 do_pending_stack_adjust ();
2072 loop_lab = gen_label_rtx ();
2073 cntvar = gen_reg_rtx (TYPE_MODE (sizetype));
2074 cntv = make_tree (sizetype, cntvar);
2075 emit_move_insn (cntvar, const0_rtx);
2076 emit_label (loop_lab);
2078 if (TREE_CODE (arg0) != VECTOR_CST)
2080 rtx arg0r = expand_normal (arg0);
2081 arg0 = make_tree (TREE_TYPE (arg0), arg0r);
2083 if (TREE_CODE (arg1) != VECTOR_CST)
2085 rtx arg1r = expand_normal (arg1);
2086 arg1 = make_tree (TREE_TYPE (arg1), arg1r);
2088 for (unsigned int i = 0; i < (use_loop_p ? 1 : const_cnt); i++)
2090 tree op0, op1, res = NULL_TREE;
2091 if (use_loop_p)
2093 tree atype = build_array_type_nelts (eltype, cnt);
2094 op0 = uniform_vector_p (arg0);
2095 if (op0 == NULL_TREE)
2097 op0 = fold_build1_loc (loc, VIEW_CONVERT_EXPR, atype, arg0);
2098 op0 = build4_loc (loc, ARRAY_REF, eltype, op0, cntv,
2099 NULL_TREE, NULL_TREE);
2101 op1 = uniform_vector_p (arg1);
2102 if (op1 == NULL_TREE)
2104 op1 = fold_build1_loc (loc, VIEW_CONVERT_EXPR, atype, arg1);
2105 op1 = build4_loc (loc, ARRAY_REF, eltype, op1, cntv,
2106 NULL_TREE, NULL_TREE);
2108 if (resv)
2110 res = fold_build1_loc (loc, VIEW_CONVERT_EXPR, atype, resv);
2111 res = build4_loc (loc, ARRAY_REF, eltype, res, cntv,
2112 NULL_TREE, NULL_TREE);
2115 else
2117 tree bitpos = bitsize_int (tree_to_uhwi (sz) * i);
2118 op0 = fold_build3_loc (loc, BIT_FIELD_REF, eltype, arg0, sz, bitpos);
2119 op1 = fold_build3_loc (loc, BIT_FIELD_REF, eltype, arg1, sz, bitpos);
2120 if (resv)
2121 res = fold_build3_loc (loc, BIT_FIELD_REF, eltype, resv, sz,
2122 bitpos);
2124 switch (code)
2126 case PLUS_EXPR:
2127 expand_addsub_overflow (loc, PLUS_EXPR, res, op0, op1,
2128 false, false, false, true, &data);
2129 break;
2130 case MINUS_EXPR:
2131 if (use_loop_p ? integer_zerop (arg0) : integer_zerop (op0))
2132 expand_neg_overflow (loc, res, op1, true, &data);
2133 else
2134 expand_addsub_overflow (loc, MINUS_EXPR, res, op0, op1,
2135 false, false, false, true, &data);
2136 break;
2137 case MULT_EXPR:
2138 expand_mul_overflow (loc, res, op0, op1, false, false, false,
2139 true, &data);
2140 break;
2141 default:
2142 gcc_unreachable ();
2145 if (use_loop_p)
2147 struct separate_ops ops;
2148 ops.code = PLUS_EXPR;
2149 ops.type = TREE_TYPE (cntv);
2150 ops.op0 = cntv;
2151 ops.op1 = build_int_cst (TREE_TYPE (cntv), 1);
2152 ops.op2 = NULL_TREE;
2153 ops.location = loc;
2154 rtx ret = expand_expr_real_2 (&ops, cntvar, TYPE_MODE (sizetype),
2155 EXPAND_NORMAL);
2156 if (ret != cntvar)
2157 emit_move_insn (cntvar, ret);
2158 rtx cntrtx = gen_int_mode (cnt, TYPE_MODE (sizetype));
2159 do_compare_rtx_and_jump (cntvar, cntrtx, NE, false,
2160 TYPE_MODE (sizetype), NULL_RTX, NULL, loop_lab,
2161 profile_probability::very_likely ());
2163 if (lhs && resv == NULL_TREE)
2165 struct separate_ops ops;
2166 ops.code = code;
2167 ops.type = TREE_TYPE (arg0);
2168 ops.op0 = arg0;
2169 ops.op1 = arg1;
2170 ops.op2 = NULL_TREE;
2171 ops.location = loc;
2172 rtx ret = expand_expr_real_2 (&ops, lhsr, TYPE_MODE (TREE_TYPE (arg0)),
2173 EXPAND_NORMAL);
2174 if (ret != lhsr)
2175 emit_move_insn (lhsr, ret);
2177 else if (resvr)
2178 emit_move_insn (lhsr, resvr);
2181 /* Expand UBSAN_CHECK_ADD call STMT. */
2183 static void
2184 expand_UBSAN_CHECK_ADD (internal_fn, gcall *stmt)
2186 location_t loc = gimple_location (stmt);
2187 tree lhs = gimple_call_lhs (stmt);
2188 tree arg0 = gimple_call_arg (stmt, 0);
2189 tree arg1 = gimple_call_arg (stmt, 1);
2190 if (VECTOR_TYPE_P (TREE_TYPE (arg0)))
2191 expand_vector_ubsan_overflow (loc, PLUS_EXPR, lhs, arg0, arg1);
2192 else
2193 expand_addsub_overflow (loc, PLUS_EXPR, lhs, arg0, arg1,
2194 false, false, false, true, NULL);
2197 /* Expand UBSAN_CHECK_SUB call STMT. */
2199 static void
2200 expand_UBSAN_CHECK_SUB (internal_fn, gcall *stmt)
2202 location_t loc = gimple_location (stmt);
2203 tree lhs = gimple_call_lhs (stmt);
2204 tree arg0 = gimple_call_arg (stmt, 0);
2205 tree arg1 = gimple_call_arg (stmt, 1);
2206 if (VECTOR_TYPE_P (TREE_TYPE (arg0)))
2207 expand_vector_ubsan_overflow (loc, MINUS_EXPR, lhs, arg0, arg1);
2208 else if (integer_zerop (arg0))
2209 expand_neg_overflow (loc, lhs, arg1, true, NULL);
2210 else
2211 expand_addsub_overflow (loc, MINUS_EXPR, lhs, arg0, arg1,
2212 false, false, false, true, NULL);
2215 /* Expand UBSAN_CHECK_MUL call STMT. */
2217 static void
2218 expand_UBSAN_CHECK_MUL (internal_fn, gcall *stmt)
2220 location_t loc = gimple_location (stmt);
2221 tree lhs = gimple_call_lhs (stmt);
2222 tree arg0 = gimple_call_arg (stmt, 0);
2223 tree arg1 = gimple_call_arg (stmt, 1);
2224 if (VECTOR_TYPE_P (TREE_TYPE (arg0)))
2225 expand_vector_ubsan_overflow (loc, MULT_EXPR, lhs, arg0, arg1);
2226 else
2227 expand_mul_overflow (loc, lhs, arg0, arg1, false, false, false, true,
2228 NULL);
2231 /* Helper function for {ADD,SUB,MUL}_OVERFLOW call stmt expansion. */
2233 static void
2234 expand_arith_overflow (enum tree_code code, gimple *stmt)
2236 tree lhs = gimple_call_lhs (stmt);
2237 if (lhs == NULL_TREE)
2238 return;
2239 tree arg0 = gimple_call_arg (stmt, 0);
2240 tree arg1 = gimple_call_arg (stmt, 1);
2241 tree type = TREE_TYPE (TREE_TYPE (lhs));
2242 int uns0_p = TYPE_UNSIGNED (TREE_TYPE (arg0));
2243 int uns1_p = TYPE_UNSIGNED (TREE_TYPE (arg1));
2244 int unsr_p = TYPE_UNSIGNED (type);
2245 int prec0 = TYPE_PRECISION (TREE_TYPE (arg0));
2246 int prec1 = TYPE_PRECISION (TREE_TYPE (arg1));
2247 int precres = TYPE_PRECISION (type);
2248 location_t loc = gimple_location (stmt);
2249 if (!uns0_p && get_range_pos_neg (arg0) == 1)
2250 uns0_p = true;
2251 if (!uns1_p && get_range_pos_neg (arg1) == 1)
2252 uns1_p = true;
2253 int pr = get_min_precision (arg0, uns0_p ? UNSIGNED : SIGNED);
2254 prec0 = MIN (prec0, pr);
2255 pr = get_min_precision (arg1, uns1_p ? UNSIGNED : SIGNED);
2256 prec1 = MIN (prec1, pr);
2258 /* If uns0_p && uns1_p, precop is minimum needed precision
2259 of unsigned type to hold the exact result, otherwise
2260 precop is minimum needed precision of signed type to
2261 hold the exact result. */
2262 int precop;
2263 if (code == MULT_EXPR)
2264 precop = prec0 + prec1 + (uns0_p != uns1_p);
2265 else
2267 if (uns0_p == uns1_p)
2268 precop = MAX (prec0, prec1) + 1;
2269 else if (uns0_p)
2270 precop = MAX (prec0 + 1, prec1) + 1;
2271 else
2272 precop = MAX (prec0, prec1 + 1) + 1;
2274 int orig_precres = precres;
2278 if ((uns0_p && uns1_p)
2279 ? ((precop + !unsr_p) <= precres
2280 /* u1 - u2 -> ur can overflow, no matter what precision
2281 the result has. */
2282 && (code != MINUS_EXPR || !unsr_p))
2283 : (!unsr_p && precop <= precres))
2285 /* The infinity precision result will always fit into result. */
2286 rtx target = expand_expr (lhs, NULL_RTX, VOIDmode, EXPAND_WRITE);
2287 write_complex_part (target, const0_rtx, true);
2288 scalar_int_mode mode = SCALAR_INT_TYPE_MODE (type);
2289 struct separate_ops ops;
2290 ops.code = code;
2291 ops.type = type;
2292 ops.op0 = fold_convert_loc (loc, type, arg0);
2293 ops.op1 = fold_convert_loc (loc, type, arg1);
2294 ops.op2 = NULL_TREE;
2295 ops.location = loc;
2296 rtx tem = expand_expr_real_2 (&ops, NULL_RTX, mode, EXPAND_NORMAL);
2297 expand_arith_overflow_result_store (lhs, target, mode, tem);
2298 return;
2301 /* For operations with low precision, if target doesn't have them, start
2302 with precres widening right away, otherwise do it only if the most
2303 simple cases can't be used. */
2304 const int min_precision = targetm.min_arithmetic_precision ();
2305 if (orig_precres == precres && precres < min_precision)
2307 else if ((uns0_p && uns1_p && unsr_p && prec0 <= precres
2308 && prec1 <= precres)
2309 || ((!uns0_p || !uns1_p) && !unsr_p
2310 && prec0 + uns0_p <= precres
2311 && prec1 + uns1_p <= precres))
2313 arg0 = fold_convert_loc (loc, type, arg0);
2314 arg1 = fold_convert_loc (loc, type, arg1);
2315 switch (code)
2317 case MINUS_EXPR:
2318 if (integer_zerop (arg0) && !unsr_p)
2320 expand_neg_overflow (loc, lhs, arg1, false, NULL);
2321 return;
2323 /* FALLTHRU */
2324 case PLUS_EXPR:
2325 expand_addsub_overflow (loc, code, lhs, arg0, arg1, unsr_p,
2326 unsr_p, unsr_p, false, NULL);
2327 return;
2328 case MULT_EXPR:
2329 expand_mul_overflow (loc, lhs, arg0, arg1, unsr_p,
2330 unsr_p, unsr_p, false, NULL);
2331 return;
2332 default:
2333 gcc_unreachable ();
2337 /* For sub-word operations, retry with a wider type first. */
2338 if (orig_precres == precres && precop <= BITS_PER_WORD)
2340 int p = MAX (min_precision, precop);
2341 scalar_int_mode m = smallest_int_mode_for_size (p);
2342 tree optype = build_nonstandard_integer_type (GET_MODE_PRECISION (m),
2343 uns0_p && uns1_p
2344 && unsr_p);
2345 p = TYPE_PRECISION (optype);
2346 if (p > precres)
2348 precres = p;
2349 unsr_p = TYPE_UNSIGNED (optype);
2350 type = optype;
2351 continue;
2355 if (prec0 <= precres && prec1 <= precres)
2357 tree types[2];
2358 if (unsr_p)
2360 types[0] = build_nonstandard_integer_type (precres, 0);
2361 types[1] = type;
2363 else
2365 types[0] = type;
2366 types[1] = build_nonstandard_integer_type (precres, 1);
2368 arg0 = fold_convert_loc (loc, types[uns0_p], arg0);
2369 arg1 = fold_convert_loc (loc, types[uns1_p], arg1);
2370 if (code != MULT_EXPR)
2371 expand_addsub_overflow (loc, code, lhs, arg0, arg1, unsr_p,
2372 uns0_p, uns1_p, false, NULL);
2373 else
2374 expand_mul_overflow (loc, lhs, arg0, arg1, unsr_p,
2375 uns0_p, uns1_p, false, NULL);
2376 return;
2379 /* Retry with a wider type. */
2380 if (orig_precres == precres)
2382 int p = MAX (prec0, prec1);
2383 scalar_int_mode m = smallest_int_mode_for_size (p);
2384 tree optype = build_nonstandard_integer_type (GET_MODE_PRECISION (m),
2385 uns0_p && uns1_p
2386 && unsr_p);
2387 p = TYPE_PRECISION (optype);
2388 if (p > precres)
2390 precres = p;
2391 unsr_p = TYPE_UNSIGNED (optype);
2392 type = optype;
2393 continue;
2397 gcc_unreachable ();
2399 while (1);
2402 /* Expand ADD_OVERFLOW STMT. */
2404 static void
2405 expand_ADD_OVERFLOW (internal_fn, gcall *stmt)
2407 expand_arith_overflow (PLUS_EXPR, stmt);
2410 /* Expand SUB_OVERFLOW STMT. */
2412 static void
2413 expand_SUB_OVERFLOW (internal_fn, gcall *stmt)
2415 expand_arith_overflow (MINUS_EXPR, stmt);
2418 /* Expand MUL_OVERFLOW STMT. */
2420 static void
2421 expand_MUL_OVERFLOW (internal_fn, gcall *stmt)
2423 expand_arith_overflow (MULT_EXPR, stmt);
2426 /* This should get folded in tree-vectorizer.c. */
2428 static void
2429 expand_LOOP_VECTORIZED (internal_fn, gcall *)
2431 gcc_unreachable ();
2434 /* This should get folded in tree-vectorizer.c. */
2436 static void
2437 expand_LOOP_DIST_ALIAS (internal_fn, gcall *)
2439 gcc_unreachable ();
2442 /* Return a memory reference of type TYPE for argument INDEX of STMT.
2443 Use argument INDEX + 1 to derive the second (TBAA) operand. */
2445 static tree
2446 expand_call_mem_ref (tree type, gcall *stmt, int index)
2448 tree addr = gimple_call_arg (stmt, index);
2449 tree alias_ptr_type = TREE_TYPE (gimple_call_arg (stmt, index + 1));
2450 unsigned int align = tree_to_shwi (gimple_call_arg (stmt, index + 1));
2451 if (TYPE_ALIGN (type) != align)
2452 type = build_aligned_type (type, align);
2454 tree tmp = addr;
2455 if (TREE_CODE (tmp) == SSA_NAME)
2457 gimple *def = SSA_NAME_DEF_STMT (tmp);
2458 if (gimple_assign_single_p (def))
2459 tmp = gimple_assign_rhs1 (def);
2462 if (TREE_CODE (tmp) == ADDR_EXPR)
2464 tree mem = TREE_OPERAND (tmp, 0);
2465 if (TREE_CODE (mem) == TARGET_MEM_REF
2466 && types_compatible_p (TREE_TYPE (mem), type))
2468 tree offset = TMR_OFFSET (mem);
2469 if (type != TREE_TYPE (mem)
2470 || alias_ptr_type != TREE_TYPE (offset)
2471 || !integer_zerop (offset))
2473 mem = copy_node (mem);
2474 TMR_OFFSET (mem) = wide_int_to_tree (alias_ptr_type,
2475 wi::to_poly_wide (offset));
2476 TREE_TYPE (mem) = type;
2478 return mem;
2482 return fold_build2 (MEM_REF, type, addr, build_int_cst (alias_ptr_type, 0));
2485 /* Expand MASK_LOAD{,_LANES} call STMT using optab OPTAB. */
2487 static void
2488 expand_mask_load_optab_fn (internal_fn, gcall *stmt, convert_optab optab)
2490 struct expand_operand ops[3];
2491 tree type, lhs, rhs, maskt;
2492 rtx mem, target, mask;
2493 insn_code icode;
2495 maskt = gimple_call_arg (stmt, 2);
2496 lhs = gimple_call_lhs (stmt);
2497 if (lhs == NULL_TREE)
2498 return;
2499 type = TREE_TYPE (lhs);
2500 rhs = expand_call_mem_ref (type, stmt, 0);
2502 if (optab == vec_mask_load_lanes_optab)
2503 icode = get_multi_vector_move (type, optab);
2504 else
2505 icode = convert_optab_handler (optab, TYPE_MODE (type),
2506 TYPE_MODE (TREE_TYPE (maskt)));
2508 mem = expand_expr (rhs, NULL_RTX, VOIDmode, EXPAND_WRITE);
2509 gcc_assert (MEM_P (mem));
2510 mask = expand_normal (maskt);
2511 target = expand_expr (lhs, NULL_RTX, VOIDmode, EXPAND_WRITE);
2512 create_output_operand (&ops[0], target, TYPE_MODE (type));
2513 create_fixed_operand (&ops[1], mem);
2514 create_input_operand (&ops[2], mask, TYPE_MODE (TREE_TYPE (maskt)));
2515 expand_insn (icode, 3, ops);
2518 #define expand_mask_load_lanes_optab_fn expand_mask_load_optab_fn
2520 /* Expand MASK_STORE{,_LANES} call STMT using optab OPTAB. */
2522 static void
2523 expand_mask_store_optab_fn (internal_fn, gcall *stmt, convert_optab optab)
2525 struct expand_operand ops[3];
2526 tree type, lhs, rhs, maskt;
2527 rtx mem, reg, mask;
2528 insn_code icode;
2530 maskt = gimple_call_arg (stmt, 2);
2531 rhs = gimple_call_arg (stmt, 3);
2532 type = TREE_TYPE (rhs);
2533 lhs = expand_call_mem_ref (type, stmt, 0);
2535 if (optab == vec_mask_store_lanes_optab)
2536 icode = get_multi_vector_move (type, optab);
2537 else
2538 icode = convert_optab_handler (optab, TYPE_MODE (type),
2539 TYPE_MODE (TREE_TYPE (maskt)));
2541 mem = expand_expr (lhs, NULL_RTX, VOIDmode, EXPAND_WRITE);
2542 gcc_assert (MEM_P (mem));
2543 mask = expand_normal (maskt);
2544 reg = expand_normal (rhs);
2545 create_fixed_operand (&ops[0], mem);
2546 create_input_operand (&ops[1], reg, TYPE_MODE (type));
2547 create_input_operand (&ops[2], mask, TYPE_MODE (TREE_TYPE (maskt)));
2548 expand_insn (icode, 3, ops);
2551 #define expand_mask_store_lanes_optab_fn expand_mask_store_optab_fn
2553 static void
2554 expand_ABNORMAL_DISPATCHER (internal_fn, gcall *)
2558 static void
2559 expand_BUILTIN_EXPECT (internal_fn, gcall *stmt)
2561 /* When guessing was done, the hints should be already stripped away. */
2562 gcc_assert (!flag_guess_branch_prob || optimize == 0 || seen_error ());
2564 rtx target;
2565 tree lhs = gimple_call_lhs (stmt);
2566 if (lhs)
2567 target = expand_expr (lhs, NULL_RTX, VOIDmode, EXPAND_WRITE);
2568 else
2569 target = const0_rtx;
2570 rtx val = expand_expr (gimple_call_arg (stmt, 0), target, VOIDmode, EXPAND_NORMAL);
2571 if (lhs && val != target)
2572 emit_move_insn (target, val);
2575 /* IFN_VA_ARG is supposed to be expanded at pass_stdarg. So this dummy function
2576 should never be called. */
2578 static void
2579 expand_VA_ARG (internal_fn, gcall *)
2581 gcc_unreachable ();
2584 /* Expand the IFN_UNIQUE function according to its first argument. */
2586 static void
2587 expand_UNIQUE (internal_fn, gcall *stmt)
2589 rtx pattern = NULL_RTX;
2590 enum ifn_unique_kind kind
2591 = (enum ifn_unique_kind) TREE_INT_CST_LOW (gimple_call_arg (stmt, 0));
2593 switch (kind)
2595 default:
2596 gcc_unreachable ();
2598 case IFN_UNIQUE_UNSPEC:
2599 if (targetm.have_unique ())
2600 pattern = targetm.gen_unique ();
2601 break;
2603 case IFN_UNIQUE_OACC_FORK:
2604 case IFN_UNIQUE_OACC_JOIN:
2605 if (targetm.have_oacc_fork () && targetm.have_oacc_join ())
2607 tree lhs = gimple_call_lhs (stmt);
2608 rtx target = const0_rtx;
2610 if (lhs)
2611 target = expand_expr (lhs, NULL_RTX, VOIDmode, EXPAND_WRITE);
2613 rtx data_dep = expand_normal (gimple_call_arg (stmt, 1));
2614 rtx axis = expand_normal (gimple_call_arg (stmt, 2));
2616 if (kind == IFN_UNIQUE_OACC_FORK)
2617 pattern = targetm.gen_oacc_fork (target, data_dep, axis);
2618 else
2619 pattern = targetm.gen_oacc_join (target, data_dep, axis);
2621 else
2622 gcc_unreachable ();
2623 break;
2626 if (pattern)
2627 emit_insn (pattern);
2630 /* The size of an OpenACC compute dimension. */
2632 static void
2633 expand_GOACC_DIM_SIZE (internal_fn, gcall *stmt)
2635 tree lhs = gimple_call_lhs (stmt);
2637 if (!lhs)
2638 return;
2640 rtx target = expand_expr (lhs, NULL_RTX, VOIDmode, EXPAND_WRITE);
2641 if (targetm.have_oacc_dim_size ())
2643 rtx dim = expand_expr (gimple_call_arg (stmt, 0), NULL_RTX,
2644 VOIDmode, EXPAND_NORMAL);
2645 emit_insn (targetm.gen_oacc_dim_size (target, dim));
2647 else
2648 emit_move_insn (target, GEN_INT (1));
2651 /* The position of an OpenACC execution engine along one compute axis. */
2653 static void
2654 expand_GOACC_DIM_POS (internal_fn, gcall *stmt)
2656 tree lhs = gimple_call_lhs (stmt);
2658 if (!lhs)
2659 return;
2661 rtx target = expand_expr (lhs, NULL_RTX, VOIDmode, EXPAND_WRITE);
2662 if (targetm.have_oacc_dim_pos ())
2664 rtx dim = expand_expr (gimple_call_arg (stmt, 0), NULL_RTX,
2665 VOIDmode, EXPAND_NORMAL);
2666 emit_insn (targetm.gen_oacc_dim_pos (target, dim));
2668 else
2669 emit_move_insn (target, const0_rtx);
2672 /* This is expanded by oacc_device_lower pass. */
2674 static void
2675 expand_GOACC_LOOP (internal_fn, gcall *)
2677 gcc_unreachable ();
2680 /* This is expanded by oacc_device_lower pass. */
2682 static void
2683 expand_GOACC_REDUCTION (internal_fn, gcall *)
2685 gcc_unreachable ();
2688 /* This is expanded by oacc_device_lower pass. */
2690 static void
2691 expand_GOACC_TILE (internal_fn, gcall *)
2693 gcc_unreachable ();
2696 /* Set errno to EDOM. */
2698 static void
2699 expand_SET_EDOM (internal_fn, gcall *)
2701 #ifdef TARGET_EDOM
2702 #ifdef GEN_ERRNO_RTX
2703 rtx errno_rtx = GEN_ERRNO_RTX;
2704 #else
2705 rtx errno_rtx = gen_rtx_MEM (word_mode, gen_rtx_SYMBOL_REF (Pmode, "errno"));
2706 #endif
2707 emit_move_insn (errno_rtx,
2708 gen_int_mode (TARGET_EDOM, GET_MODE (errno_rtx)));
2709 #else
2710 gcc_unreachable ();
2711 #endif
2714 /* Expand atomic bit test and set. */
2716 static void
2717 expand_ATOMIC_BIT_TEST_AND_SET (internal_fn, gcall *call)
2719 expand_ifn_atomic_bit_test_and (call);
2722 /* Expand atomic bit test and complement. */
2724 static void
2725 expand_ATOMIC_BIT_TEST_AND_COMPLEMENT (internal_fn, gcall *call)
2727 expand_ifn_atomic_bit_test_and (call);
2730 /* Expand atomic bit test and reset. */
2732 static void
2733 expand_ATOMIC_BIT_TEST_AND_RESET (internal_fn, gcall *call)
2735 expand_ifn_atomic_bit_test_and (call);
2738 /* Expand atomic bit test and set. */
2740 static void
2741 expand_ATOMIC_COMPARE_EXCHANGE (internal_fn, gcall *call)
2743 expand_ifn_atomic_compare_exchange (call);
2746 /* Expand LAUNDER to assignment, lhs = arg0. */
2748 static void
2749 expand_LAUNDER (internal_fn, gcall *call)
2751 tree lhs = gimple_call_lhs (call);
2753 if (!lhs)
2754 return;
2756 expand_assignment (lhs, gimple_call_arg (call, 0), false);
2759 /* Expand {MASK_,}SCATTER_STORE{S,U} call CALL using optab OPTAB. */
2761 static void
2762 expand_scatter_store_optab_fn (internal_fn, gcall *stmt, direct_optab optab)
2764 internal_fn ifn = gimple_call_internal_fn (stmt);
2765 int rhs_index = internal_fn_stored_value_index (ifn);
2766 int mask_index = internal_fn_mask_index (ifn);
2767 tree base = gimple_call_arg (stmt, 0);
2768 tree offset = gimple_call_arg (stmt, 1);
2769 tree scale = gimple_call_arg (stmt, 2);
2770 tree rhs = gimple_call_arg (stmt, rhs_index);
2772 rtx base_rtx = expand_normal (base);
2773 rtx offset_rtx = expand_normal (offset);
2774 HOST_WIDE_INT scale_int = tree_to_shwi (scale);
2775 rtx rhs_rtx = expand_normal (rhs);
2777 struct expand_operand ops[6];
2778 int i = 0;
2779 create_address_operand (&ops[i++], base_rtx);
2780 create_input_operand (&ops[i++], offset_rtx, TYPE_MODE (TREE_TYPE (offset)));
2781 create_integer_operand (&ops[i++], TYPE_UNSIGNED (TREE_TYPE (offset)));
2782 create_integer_operand (&ops[i++], scale_int);
2783 create_input_operand (&ops[i++], rhs_rtx, TYPE_MODE (TREE_TYPE (rhs)));
2784 if (mask_index >= 0)
2786 tree mask = gimple_call_arg (stmt, mask_index);
2787 rtx mask_rtx = expand_normal (mask);
2788 create_input_operand (&ops[i++], mask_rtx, TYPE_MODE (TREE_TYPE (mask)));
2791 insn_code icode = direct_optab_handler (optab, TYPE_MODE (TREE_TYPE (rhs)));
2792 expand_insn (icode, i, ops);
2795 /* Expand {MASK_,}GATHER_LOAD call CALL using optab OPTAB. */
2797 static void
2798 expand_gather_load_optab_fn (internal_fn, gcall *stmt, direct_optab optab)
2800 tree lhs = gimple_call_lhs (stmt);
2801 tree base = gimple_call_arg (stmt, 0);
2802 tree offset = gimple_call_arg (stmt, 1);
2803 tree scale = gimple_call_arg (stmt, 2);
2805 rtx lhs_rtx = expand_expr (lhs, NULL_RTX, VOIDmode, EXPAND_WRITE);
2806 rtx base_rtx = expand_normal (base);
2807 rtx offset_rtx = expand_normal (offset);
2808 HOST_WIDE_INT scale_int = tree_to_shwi (scale);
2810 int i = 0;
2811 struct expand_operand ops[6];
2812 create_output_operand (&ops[i++], lhs_rtx, TYPE_MODE (TREE_TYPE (lhs)));
2813 create_address_operand (&ops[i++], base_rtx);
2814 create_input_operand (&ops[i++], offset_rtx, TYPE_MODE (TREE_TYPE (offset)));
2815 create_integer_operand (&ops[i++], TYPE_UNSIGNED (TREE_TYPE (offset)));
2816 create_integer_operand (&ops[i++], scale_int);
2817 if (optab == mask_gather_load_optab)
2819 tree mask = gimple_call_arg (stmt, 3);
2820 rtx mask_rtx = expand_normal (mask);
2821 create_input_operand (&ops[i++], mask_rtx, TYPE_MODE (TREE_TYPE (mask)));
2823 insn_code icode = direct_optab_handler (optab, TYPE_MODE (TREE_TYPE (lhs)));
2824 expand_insn (icode, i, ops);
2827 /* Expand DIVMOD() using:
2828 a) optab handler for udivmod/sdivmod if it is available.
2829 b) If optab_handler doesn't exist, generate call to
2830 target-specific divmod libfunc. */
2832 static void
2833 expand_DIVMOD (internal_fn, gcall *call_stmt)
2835 tree lhs = gimple_call_lhs (call_stmt);
2836 tree arg0 = gimple_call_arg (call_stmt, 0);
2837 tree arg1 = gimple_call_arg (call_stmt, 1);
2839 gcc_assert (TREE_CODE (TREE_TYPE (lhs)) == COMPLEX_TYPE);
2840 tree type = TREE_TYPE (TREE_TYPE (lhs));
2841 machine_mode mode = TYPE_MODE (type);
2842 bool unsignedp = TYPE_UNSIGNED (type);
2843 optab tab = (unsignedp) ? udivmod_optab : sdivmod_optab;
2845 rtx op0 = expand_normal (arg0);
2846 rtx op1 = expand_normal (arg1);
2847 rtx target = expand_expr (lhs, NULL_RTX, VOIDmode, EXPAND_WRITE);
2849 rtx quotient, remainder, libfunc;
2851 /* Check if optab_handler exists for divmod_optab for given mode. */
2852 if (optab_handler (tab, mode) != CODE_FOR_nothing)
2854 quotient = gen_reg_rtx (mode);
2855 remainder = gen_reg_rtx (mode);
2856 expand_twoval_binop (tab, op0, op1, quotient, remainder, unsignedp);
2859 /* Generate call to divmod libfunc if it exists. */
2860 else if ((libfunc = optab_libfunc (tab, mode)) != NULL_RTX)
2861 targetm.expand_divmod_libfunc (libfunc, mode, op0, op1,
2862 &quotient, &remainder);
2864 else
2865 gcc_unreachable ();
2867 /* Wrap the return value (quotient, remainder) within COMPLEX_EXPR. */
2868 expand_expr (build2 (COMPLEX_EXPR, TREE_TYPE (lhs),
2869 make_tree (TREE_TYPE (arg0), quotient),
2870 make_tree (TREE_TYPE (arg1), remainder)),
2871 target, VOIDmode, EXPAND_NORMAL);
2874 /* Expand a NOP. */
2876 static void
2877 expand_NOP (internal_fn, gcall *)
2879 /* Nothing. But it shouldn't really prevail. */
2882 /* Expand a call to FN using the operands in STMT. FN has a single
2883 output operand and NARGS input operands. */
2885 static void
2886 expand_direct_optab_fn (internal_fn fn, gcall *stmt, direct_optab optab,
2887 unsigned int nargs)
2889 expand_operand *ops = XALLOCAVEC (expand_operand, nargs + 1);
2891 tree_pair types = direct_internal_fn_types (fn, stmt);
2892 insn_code icode = direct_optab_handler (optab, TYPE_MODE (types.first));
2894 tree lhs = gimple_call_lhs (stmt);
2895 rtx lhs_rtx = NULL_RTX;
2896 if (lhs)
2897 lhs_rtx = expand_expr (lhs, NULL_RTX, VOIDmode, EXPAND_WRITE);
2899 /* Do not assign directly to a promoted subreg, since there is no
2900 guarantee that the instruction will leave the upper bits of the
2901 register in the state required by SUBREG_PROMOTED_SIGN. */
2902 rtx dest = lhs_rtx;
2903 if (dest && GET_CODE (dest) == SUBREG && SUBREG_PROMOTED_VAR_P (dest))
2904 dest = NULL_RTX;
2906 create_output_operand (&ops[0], dest, insn_data[icode].operand[0].mode);
2908 for (unsigned int i = 0; i < nargs; ++i)
2910 tree rhs = gimple_call_arg (stmt, i);
2911 tree rhs_type = TREE_TYPE (rhs);
2912 rtx rhs_rtx = expand_normal (rhs);
2913 if (INTEGRAL_TYPE_P (rhs_type))
2914 create_convert_operand_from (&ops[i + 1], rhs_rtx,
2915 TYPE_MODE (rhs_type),
2916 TYPE_UNSIGNED (rhs_type));
2917 else
2918 create_input_operand (&ops[i + 1], rhs_rtx, TYPE_MODE (rhs_type));
2921 expand_insn (icode, nargs + 1, ops);
2922 if (lhs_rtx && !rtx_equal_p (lhs_rtx, ops[0].value))
2924 /* If the return value has an integral type, convert the instruction
2925 result to that type. This is useful for things that return an
2926 int regardless of the size of the input. If the instruction result
2927 is smaller than required, assume that it is signed.
2929 If the return value has a nonintegral type, its mode must match
2930 the instruction result. */
2931 if (GET_CODE (lhs_rtx) == SUBREG && SUBREG_PROMOTED_VAR_P (lhs_rtx))
2933 /* If this is a scalar in a register that is stored in a wider
2934 mode than the declared mode, compute the result into its
2935 declared mode and then convert to the wider mode. */
2936 gcc_checking_assert (INTEGRAL_TYPE_P (TREE_TYPE (lhs)));
2937 rtx tmp = convert_to_mode (GET_MODE (lhs_rtx), ops[0].value, 0);
2938 convert_move (SUBREG_REG (lhs_rtx), tmp,
2939 SUBREG_PROMOTED_SIGN (lhs_rtx));
2941 else if (GET_MODE (lhs_rtx) == GET_MODE (ops[0].value))
2942 emit_move_insn (lhs_rtx, ops[0].value);
2943 else
2945 gcc_checking_assert (INTEGRAL_TYPE_P (TREE_TYPE (lhs)));
2946 convert_move (lhs_rtx, ops[0].value, 0);
2951 /* Expand WHILE_ULT call STMT using optab OPTAB. */
2953 static void
2954 expand_while_optab_fn (internal_fn, gcall *stmt, convert_optab optab)
2956 expand_operand ops[3];
2957 tree rhs_type[2];
2959 tree lhs = gimple_call_lhs (stmt);
2960 tree lhs_type = TREE_TYPE (lhs);
2961 rtx lhs_rtx = expand_expr (lhs, NULL_RTX, VOIDmode, EXPAND_WRITE);
2962 create_output_operand (&ops[0], lhs_rtx, TYPE_MODE (lhs_type));
2964 for (unsigned int i = 0; i < 2; ++i)
2966 tree rhs = gimple_call_arg (stmt, i);
2967 rhs_type[i] = TREE_TYPE (rhs);
2968 rtx rhs_rtx = expand_normal (rhs);
2969 create_input_operand (&ops[i + 1], rhs_rtx, TYPE_MODE (rhs_type[i]));
2972 insn_code icode = convert_optab_handler (optab, TYPE_MODE (rhs_type[0]),
2973 TYPE_MODE (lhs_type));
2975 expand_insn (icode, 3, ops);
2976 if (!rtx_equal_p (lhs_rtx, ops[0].value))
2977 emit_move_insn (lhs_rtx, ops[0].value);
2980 /* Expanders for optabs that can use expand_direct_optab_fn. */
2982 #define expand_unary_optab_fn(FN, STMT, OPTAB) \
2983 expand_direct_optab_fn (FN, STMT, OPTAB, 1)
2985 #define expand_binary_optab_fn(FN, STMT, OPTAB) \
2986 expand_direct_optab_fn (FN, STMT, OPTAB, 2)
2988 #define expand_ternary_optab_fn(FN, STMT, OPTAB) \
2989 expand_direct_optab_fn (FN, STMT, OPTAB, 3)
2991 #define expand_cond_unary_optab_fn(FN, STMT, OPTAB) \
2992 expand_direct_optab_fn (FN, STMT, OPTAB, 3)
2994 #define expand_cond_binary_optab_fn(FN, STMT, OPTAB) \
2995 expand_direct_optab_fn (FN, STMT, OPTAB, 4)
2997 #define expand_cond_ternary_optab_fn(FN, STMT, OPTAB) \
2998 expand_direct_optab_fn (FN, STMT, OPTAB, 5)
3000 #define expand_fold_extract_optab_fn(FN, STMT, OPTAB) \
3001 expand_direct_optab_fn (FN, STMT, OPTAB, 3)
3003 #define expand_fold_left_optab_fn(FN, STMT, OPTAB) \
3004 expand_direct_optab_fn (FN, STMT, OPTAB, 2)
3006 /* RETURN_TYPE and ARGS are a return type and argument list that are
3007 in principle compatible with FN (which satisfies direct_internal_fn_p).
3008 Return the types that should be used to determine whether the
3009 target supports FN. */
3011 tree_pair
3012 direct_internal_fn_types (internal_fn fn, tree return_type, tree *args)
3014 const direct_internal_fn_info &info = direct_internal_fn (fn);
3015 tree type0 = (info.type0 < 0 ? return_type : TREE_TYPE (args[info.type0]));
3016 tree type1 = (info.type1 < 0 ? return_type : TREE_TYPE (args[info.type1]));
3017 return tree_pair (type0, type1);
3020 /* CALL is a call whose return type and arguments are in principle
3021 compatible with FN (which satisfies direct_internal_fn_p). Return the
3022 types that should be used to determine whether the target supports FN. */
3024 tree_pair
3025 direct_internal_fn_types (internal_fn fn, gcall *call)
3027 const direct_internal_fn_info &info = direct_internal_fn (fn);
3028 tree op0 = (info.type0 < 0
3029 ? gimple_call_lhs (call)
3030 : gimple_call_arg (call, info.type0));
3031 tree op1 = (info.type1 < 0
3032 ? gimple_call_lhs (call)
3033 : gimple_call_arg (call, info.type1));
3034 return tree_pair (TREE_TYPE (op0), TREE_TYPE (op1));
3037 /* Return true if OPTAB is supported for TYPES (whose modes should be
3038 the same) when the optimization type is OPT_TYPE. Used for simple
3039 direct optabs. */
3041 static bool
3042 direct_optab_supported_p (direct_optab optab, tree_pair types,
3043 optimization_type opt_type)
3045 machine_mode mode = TYPE_MODE (types.first);
3046 gcc_checking_assert (mode == TYPE_MODE (types.second));
3047 return direct_optab_handler (optab, mode, opt_type) != CODE_FOR_nothing;
3050 /* Return true if OPTAB is supported for TYPES, where the first type
3051 is the destination and the second type is the source. Used for
3052 convert optabs. */
3054 static bool
3055 convert_optab_supported_p (convert_optab optab, tree_pair types,
3056 optimization_type opt_type)
3058 return (convert_optab_handler (optab, TYPE_MODE (types.first),
3059 TYPE_MODE (types.second), opt_type)
3060 != CODE_FOR_nothing);
3063 /* Return true if load/store lanes optab OPTAB is supported for
3064 array type TYPES.first when the optimization type is OPT_TYPE. */
3066 static bool
3067 multi_vector_optab_supported_p (convert_optab optab, tree_pair types,
3068 optimization_type opt_type)
3070 gcc_assert (TREE_CODE (types.first) == ARRAY_TYPE);
3071 machine_mode imode = TYPE_MODE (types.first);
3072 machine_mode vmode = TYPE_MODE (TREE_TYPE (types.first));
3073 return (convert_optab_handler (optab, imode, vmode, opt_type)
3074 != CODE_FOR_nothing);
3077 #define direct_unary_optab_supported_p direct_optab_supported_p
3078 #define direct_binary_optab_supported_p direct_optab_supported_p
3079 #define direct_ternary_optab_supported_p direct_optab_supported_p
3080 #define direct_cond_unary_optab_supported_p direct_optab_supported_p
3081 #define direct_cond_binary_optab_supported_p direct_optab_supported_p
3082 #define direct_cond_ternary_optab_supported_p direct_optab_supported_p
3083 #define direct_mask_load_optab_supported_p direct_optab_supported_p
3084 #define direct_load_lanes_optab_supported_p multi_vector_optab_supported_p
3085 #define direct_mask_load_lanes_optab_supported_p multi_vector_optab_supported_p
3086 #define direct_gather_load_optab_supported_p direct_optab_supported_p
3087 #define direct_mask_store_optab_supported_p direct_optab_supported_p
3088 #define direct_store_lanes_optab_supported_p multi_vector_optab_supported_p
3089 #define direct_mask_store_lanes_optab_supported_p multi_vector_optab_supported_p
3090 #define direct_scatter_store_optab_supported_p direct_optab_supported_p
3091 #define direct_while_optab_supported_p convert_optab_supported_p
3092 #define direct_fold_extract_optab_supported_p direct_optab_supported_p
3093 #define direct_fold_left_optab_supported_p direct_optab_supported_p
3095 /* Return the optab used by internal function FN. */
3097 static optab
3098 direct_internal_fn_optab (internal_fn fn, tree_pair types)
3100 switch (fn)
3102 #define DEF_INTERNAL_FN(CODE, FLAGS, FNSPEC) \
3103 case IFN_##CODE: break;
3104 #define DEF_INTERNAL_OPTAB_FN(CODE, FLAGS, OPTAB, TYPE) \
3105 case IFN_##CODE: return OPTAB##_optab;
3106 #define DEF_INTERNAL_SIGNED_OPTAB_FN(CODE, FLAGS, SELECTOR, SIGNED_OPTAB, \
3107 UNSIGNED_OPTAB, TYPE) \
3108 case IFN_##CODE: return (TYPE_UNSIGNED (types.SELECTOR) \
3109 ? UNSIGNED_OPTAB ## _optab \
3110 : SIGNED_OPTAB ## _optab);
3111 #include "internal-fn.def"
3113 case IFN_LAST:
3114 break;
3116 gcc_unreachable ();
3119 /* Return the optab used by internal function FN. */
3121 static optab
3122 direct_internal_fn_optab (internal_fn fn)
3124 switch (fn)
3126 #define DEF_INTERNAL_FN(CODE, FLAGS, FNSPEC) \
3127 case IFN_##CODE: break;
3128 #define DEF_INTERNAL_OPTAB_FN(CODE, FLAGS, OPTAB, TYPE) \
3129 case IFN_##CODE: return OPTAB##_optab;
3130 #include "internal-fn.def"
3132 case IFN_LAST:
3133 break;
3135 gcc_unreachable ();
3138 /* Return true if FN is supported for the types in TYPES when the
3139 optimization type is OPT_TYPE. The types are those associated with
3140 the "type0" and "type1" fields of FN's direct_internal_fn_info
3141 structure. */
3143 bool
3144 direct_internal_fn_supported_p (internal_fn fn, tree_pair types,
3145 optimization_type opt_type)
3147 switch (fn)
3149 #define DEF_INTERNAL_FN(CODE, FLAGS, FNSPEC) \
3150 case IFN_##CODE: break;
3151 #define DEF_INTERNAL_OPTAB_FN(CODE, FLAGS, OPTAB, TYPE) \
3152 case IFN_##CODE: \
3153 return direct_##TYPE##_optab_supported_p (OPTAB##_optab, types, \
3154 opt_type);
3155 #define DEF_INTERNAL_SIGNED_OPTAB_FN(CODE, FLAGS, SELECTOR, SIGNED_OPTAB, \
3156 UNSIGNED_OPTAB, TYPE) \
3157 case IFN_##CODE: \
3159 optab which_optab = (TYPE_UNSIGNED (types.SELECTOR) \
3160 ? UNSIGNED_OPTAB ## _optab \
3161 : SIGNED_OPTAB ## _optab); \
3162 return direct_##TYPE##_optab_supported_p (which_optab, types, \
3163 opt_type); \
3165 #include "internal-fn.def"
3167 case IFN_LAST:
3168 break;
3170 gcc_unreachable ();
3173 /* Return true if FN is supported for type TYPE when the optimization
3174 type is OPT_TYPE. The caller knows that the "type0" and "type1"
3175 fields of FN's direct_internal_fn_info structure are the same. */
3177 bool
3178 direct_internal_fn_supported_p (internal_fn fn, tree type,
3179 optimization_type opt_type)
3181 const direct_internal_fn_info &info = direct_internal_fn (fn);
3182 gcc_checking_assert (info.type0 == info.type1);
3183 return direct_internal_fn_supported_p (fn, tree_pair (type, type), opt_type);
3186 /* Return true if IFN_SET_EDOM is supported. */
3188 bool
3189 set_edom_supported_p (void)
3191 #ifdef TARGET_EDOM
3192 return true;
3193 #else
3194 return false;
3195 #endif
3198 #define DEF_INTERNAL_OPTAB_FN(CODE, FLAGS, OPTAB, TYPE) \
3199 static void \
3200 expand_##CODE (internal_fn fn, gcall *stmt) \
3202 expand_##TYPE##_optab_fn (fn, stmt, OPTAB##_optab); \
3204 #define DEF_INTERNAL_SIGNED_OPTAB_FN(CODE, FLAGS, SELECTOR, SIGNED_OPTAB, \
3205 UNSIGNED_OPTAB, TYPE) \
3206 static void \
3207 expand_##CODE (internal_fn fn, gcall *stmt) \
3209 tree_pair types = direct_internal_fn_types (fn, stmt); \
3210 optab which_optab = direct_internal_fn_optab (fn, types); \
3211 expand_##TYPE##_optab_fn (fn, stmt, which_optab); \
3213 #include "internal-fn.def"
3215 /* Routines to expand each internal function, indexed by function number.
3216 Each routine has the prototype:
3218 expand_<NAME> (gcall *stmt)
3220 where STMT is the statement that performs the call. */
3221 static void (*const internal_fn_expanders[]) (internal_fn, gcall *) = {
3222 #define DEF_INTERNAL_FN(CODE, FLAGS, FNSPEC) expand_##CODE,
3223 #include "internal-fn.def"
3227 /* Invoke T(CODE, IFN) for each conditional function IFN that maps to a
3228 tree code CODE. */
3229 #define FOR_EACH_CODE_MAPPING(T) \
3230 T (PLUS_EXPR, IFN_COND_ADD) \
3231 T (MINUS_EXPR, IFN_COND_SUB) \
3232 T (MULT_EXPR, IFN_COND_MUL) \
3233 T (TRUNC_DIV_EXPR, IFN_COND_DIV) \
3234 T (TRUNC_MOD_EXPR, IFN_COND_MOD) \
3235 T (RDIV_EXPR, IFN_COND_RDIV) \
3236 T (MIN_EXPR, IFN_COND_MIN) \
3237 T (MAX_EXPR, IFN_COND_MAX) \
3238 T (BIT_AND_EXPR, IFN_COND_AND) \
3239 T (BIT_IOR_EXPR, IFN_COND_IOR) \
3240 T (BIT_XOR_EXPR, IFN_COND_XOR)
3242 /* Return a function that only performs CODE when a certain condition is met
3243 and that uses a given fallback value otherwise. For example, if CODE is
3244 a binary operation associated with conditional function FN:
3246 LHS = FN (COND, A, B, ELSE)
3248 is equivalent to the C expression:
3250 LHS = COND ? A CODE B : ELSE;
3252 operating elementwise if the operands are vectors.
3254 Return IFN_LAST if no such function exists. */
3256 internal_fn
3257 get_conditional_internal_fn (tree_code code)
3259 switch (code)
3261 #define CASE(CODE, IFN) case CODE: return IFN;
3262 FOR_EACH_CODE_MAPPING(CASE)
3263 #undef CASE
3264 default:
3265 return IFN_LAST;
3269 /* If IFN implements the conditional form of a tree code, return that
3270 tree code, otherwise return ERROR_MARK. */
3272 tree_code
3273 conditional_internal_fn_code (internal_fn ifn)
3275 switch (ifn)
3277 #define CASE(CODE, IFN) case IFN: return CODE;
3278 FOR_EACH_CODE_MAPPING(CASE)
3279 #undef CASE
3280 default:
3281 return ERROR_MARK;
3285 /* Invoke T(IFN) for each internal function IFN that also has an
3286 IFN_COND_* form. */
3287 #define FOR_EACH_COND_FN_PAIR(T) \
3288 T (FMA) \
3289 T (FMS) \
3290 T (FNMA) \
3291 T (FNMS)
3293 /* Return a function that only performs internal function FN when a
3294 certain condition is met and that uses a given fallback value otherwise.
3295 In other words, the returned function FN' is such that:
3297 LHS = FN' (COND, A1, ... An, ELSE)
3299 is equivalent to the C expression:
3301 LHS = COND ? FN (A1, ..., An) : ELSE;
3303 operating elementwise if the operands are vectors.
3305 Return IFN_LAST if no such function exists. */
3307 internal_fn
3308 get_conditional_internal_fn (internal_fn fn)
3310 switch (fn)
3312 #define CASE(NAME) case IFN_##NAME: return IFN_COND_##NAME;
3313 FOR_EACH_COND_FN_PAIR(CASE)
3314 #undef CASE
3315 default:
3316 return IFN_LAST;
3320 /* If IFN implements the conditional form of an unconditional internal
3321 function, return that unconditional function, otherwise return IFN_LAST. */
3323 internal_fn
3324 get_unconditional_internal_fn (internal_fn ifn)
3326 switch (ifn)
3328 #define CASE(NAME) case IFN_COND_##NAME: return IFN_##NAME;
3329 FOR_EACH_COND_FN_PAIR(CASE)
3330 #undef CASE
3331 default:
3332 return IFN_LAST;
3336 /* Return true if STMT can be interpreted as a conditional tree code
3337 operation of the form:
3339 LHS = COND ? OP (RHS1, ...) : ELSE;
3341 operating elementwise if the operands are vectors. This includes
3342 the case of an all-true COND, so that the operation always happens.
3344 When returning true, set:
3346 - *COND_OUT to the condition COND, or to NULL_TREE if the condition
3347 is known to be all-true
3348 - *CODE_OUT to the tree code
3349 - OPS[I] to operand I of *CODE_OUT
3350 - *ELSE_OUT to the fallback value ELSE, or to NULL_TREE if the
3351 condition is known to be all true. */
3353 bool
3354 can_interpret_as_conditional_op_p (gimple *stmt, tree *cond_out,
3355 tree_code *code_out,
3356 tree (&ops)[3], tree *else_out)
3358 if (gassign *assign = dyn_cast <gassign *> (stmt))
3360 *cond_out = NULL_TREE;
3361 *code_out = gimple_assign_rhs_code (assign);
3362 ops[0] = gimple_assign_rhs1 (assign);
3363 ops[1] = gimple_assign_rhs2 (assign);
3364 ops[2] = gimple_assign_rhs3 (assign);
3365 *else_out = NULL_TREE;
3366 return true;
3368 if (gcall *call = dyn_cast <gcall *> (stmt))
3369 if (gimple_call_internal_p (call))
3371 internal_fn ifn = gimple_call_internal_fn (call);
3372 tree_code code = conditional_internal_fn_code (ifn);
3373 if (code != ERROR_MARK)
3375 *cond_out = gimple_call_arg (call, 0);
3376 *code_out = code;
3377 unsigned int nops = gimple_call_num_args (call) - 2;
3378 for (unsigned int i = 0; i < 3; ++i)
3379 ops[i] = i < nops ? gimple_call_arg (call, i + 1) : NULL_TREE;
3380 *else_out = gimple_call_arg (call, nops + 1);
3381 if (integer_truep (*cond_out))
3383 *cond_out = NULL_TREE;
3384 *else_out = NULL_TREE;
3386 return true;
3389 return false;
3392 /* Return true if IFN is some form of load from memory. */
3394 bool
3395 internal_load_fn_p (internal_fn fn)
3397 switch (fn)
3399 case IFN_MASK_LOAD:
3400 case IFN_LOAD_LANES:
3401 case IFN_MASK_LOAD_LANES:
3402 case IFN_GATHER_LOAD:
3403 case IFN_MASK_GATHER_LOAD:
3404 return true;
3406 default:
3407 return false;
3411 /* Return true if IFN is some form of store to memory. */
3413 bool
3414 internal_store_fn_p (internal_fn fn)
3416 switch (fn)
3418 case IFN_MASK_STORE:
3419 case IFN_STORE_LANES:
3420 case IFN_MASK_STORE_LANES:
3421 case IFN_SCATTER_STORE:
3422 case IFN_MASK_SCATTER_STORE:
3423 return true;
3425 default:
3426 return false;
3430 /* Return true if IFN is some form of gather load or scatter store. */
3432 bool
3433 internal_gather_scatter_fn_p (internal_fn fn)
3435 switch (fn)
3437 case IFN_GATHER_LOAD:
3438 case IFN_MASK_GATHER_LOAD:
3439 case IFN_SCATTER_STORE:
3440 case IFN_MASK_SCATTER_STORE:
3441 return true;
3443 default:
3444 return false;
3448 /* If FN takes a vector mask argument, return the index of that argument,
3449 otherwise return -1. */
3452 internal_fn_mask_index (internal_fn fn)
3454 switch (fn)
3456 case IFN_MASK_LOAD:
3457 case IFN_MASK_LOAD_LANES:
3458 case IFN_MASK_STORE:
3459 case IFN_MASK_STORE_LANES:
3460 return 2;
3462 case IFN_MASK_GATHER_LOAD:
3463 return 3;
3465 case IFN_MASK_SCATTER_STORE:
3466 return 4;
3468 default:
3469 return -1;
3473 /* If FN takes a value that should be stored to memory, return the index
3474 of that argument, otherwise return -1. */
3477 internal_fn_stored_value_index (internal_fn fn)
3479 switch (fn)
3481 case IFN_MASK_STORE:
3482 case IFN_SCATTER_STORE:
3483 case IFN_MASK_SCATTER_STORE:
3484 return 3;
3486 default:
3487 return -1;
3491 /* Return true if the target supports gather load or scatter store function
3492 IFN. For loads, VECTOR_TYPE is the vector type of the load result,
3493 while for stores it is the vector type of the stored data argument.
3494 MEMORY_ELEMENT_TYPE is the type of the memory elements being loaded
3495 or stored. OFFSET_SIGN is the sign of the offset argument, which is
3496 only relevant when the offset is narrower than an address. SCALE is
3497 the amount by which the offset should be multiplied *after* it has
3498 been extended to address width. */
3500 bool
3501 internal_gather_scatter_fn_supported_p (internal_fn ifn, tree vector_type,
3502 tree memory_element_type,
3503 signop offset_sign, int scale)
3505 if (!tree_int_cst_equal (TYPE_SIZE (TREE_TYPE (vector_type)),
3506 TYPE_SIZE (memory_element_type)))
3507 return false;
3508 optab optab = direct_internal_fn_optab (ifn);
3509 insn_code icode = direct_optab_handler (optab, TYPE_MODE (vector_type));
3510 int output_ops = internal_load_fn_p (ifn) ? 1 : 0;
3511 return (icode != CODE_FOR_nothing
3512 && insn_operand_matches (icode, 2 + output_ops,
3513 GEN_INT (offset_sign == UNSIGNED))
3514 && insn_operand_matches (icode, 3 + output_ops,
3515 GEN_INT (scale)));
3518 /* Expand STMT as though it were a call to internal function FN. */
3520 void
3521 expand_internal_call (internal_fn fn, gcall *stmt)
3523 internal_fn_expanders[fn] (fn, stmt);
3526 /* Expand STMT, which is a call to internal function FN. */
3528 void
3529 expand_internal_call (gcall *stmt)
3531 expand_internal_call (gimple_call_internal_fn (stmt), stmt);
3534 void
3535 expand_PHI (internal_fn, gcall *)
3537 gcc_unreachable ();