Make vect_model_store_cost take a vec_load_store_type
[official-gcc.git] / gcc / internal-fn.c
blob6483fe694257d8b2b0208341b4ed2c55e230b4d8
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 /* Fnspec of each internal function, indexed by function number. */
68 const_tree internal_fn_fnspec_array[IFN_LAST + 1];
70 void
71 init_internal_fns ()
73 #define DEF_INTERNAL_FN(CODE, FLAGS, FNSPEC) \
74 if (FNSPEC) internal_fn_fnspec_array[IFN_##CODE] = \
75 build_string ((int) sizeof (FNSPEC), FNSPEC ? FNSPEC : "");
76 #include "internal-fn.def"
77 internal_fn_fnspec_array[IFN_LAST] = 0;
80 /* Create static initializers for the information returned by
81 direct_internal_fn. */
82 #define not_direct { -2, -2, false }
83 #define mask_load_direct { -1, 2, false }
84 #define load_lanes_direct { -1, -1, false }
85 #define mask_store_direct { 3, 2, false }
86 #define store_lanes_direct { 0, 0, false }
87 #define unary_direct { 0, 0, true }
88 #define binary_direct { 0, 0, true }
90 const direct_internal_fn_info direct_internal_fn_array[IFN_LAST + 1] = {
91 #define DEF_INTERNAL_FN(CODE, FLAGS, FNSPEC) not_direct,
92 #define DEF_INTERNAL_OPTAB_FN(CODE, FLAGS, OPTAB, TYPE) TYPE##_direct,
93 #define DEF_INTERNAL_SIGNED_OPTAB_FN(CODE, FLAGS, SELECTOR, SIGNED_OPTAB, \
94 UNSIGNED_OPTAB, TYPE) TYPE##_direct,
95 #include "internal-fn.def"
96 not_direct
99 /* ARRAY_TYPE is an array of vector modes. Return the associated insn
100 for load-lanes-style optab OPTAB, or CODE_FOR_nothing if none. */
102 static enum insn_code
103 get_multi_vector_move (tree array_type, convert_optab optab)
105 machine_mode imode;
106 machine_mode vmode;
108 gcc_assert (TREE_CODE (array_type) == ARRAY_TYPE);
109 imode = TYPE_MODE (array_type);
110 vmode = TYPE_MODE (TREE_TYPE (array_type));
112 return convert_optab_handler (optab, imode, vmode);
115 /* Expand LOAD_LANES call STMT using optab OPTAB. */
117 static void
118 expand_load_lanes_optab_fn (internal_fn, gcall *stmt, convert_optab optab)
120 struct expand_operand ops[2];
121 tree type, lhs, rhs;
122 rtx target, mem;
124 lhs = gimple_call_lhs (stmt);
125 rhs = gimple_call_arg (stmt, 0);
126 type = TREE_TYPE (lhs);
128 target = expand_expr (lhs, NULL_RTX, VOIDmode, EXPAND_WRITE);
129 mem = expand_normal (rhs);
131 gcc_assert (MEM_P (mem));
132 PUT_MODE (mem, TYPE_MODE (type));
134 create_output_operand (&ops[0], target, TYPE_MODE (type));
135 create_fixed_operand (&ops[1], mem);
136 expand_insn (get_multi_vector_move (type, optab), 2, ops);
139 /* Expand STORE_LANES call STMT using optab OPTAB. */
141 static void
142 expand_store_lanes_optab_fn (internal_fn, gcall *stmt, convert_optab optab)
144 struct expand_operand ops[2];
145 tree type, lhs, rhs;
146 rtx target, reg;
148 lhs = gimple_call_lhs (stmt);
149 rhs = gimple_call_arg (stmt, 0);
150 type = TREE_TYPE (rhs);
152 target = expand_expr (lhs, NULL_RTX, VOIDmode, EXPAND_WRITE);
153 reg = expand_normal (rhs);
155 gcc_assert (MEM_P (target));
156 PUT_MODE (target, TYPE_MODE (type));
158 create_fixed_operand (&ops[0], target);
159 create_input_operand (&ops[1], reg, TYPE_MODE (type));
160 expand_insn (get_multi_vector_move (type, optab), 2, ops);
163 static void
164 expand_ANNOTATE (internal_fn, gcall *)
166 gcc_unreachable ();
169 /* This should get expanded in omp_device_lower pass. */
171 static void
172 expand_GOMP_USE_SIMT (internal_fn, gcall *)
174 gcc_unreachable ();
177 /* This should get expanded in omp_device_lower pass. */
179 static void
180 expand_GOMP_SIMT_ENTER (internal_fn, gcall *)
182 gcc_unreachable ();
185 /* Allocate per-lane storage and begin non-uniform execution region. */
187 static void
188 expand_GOMP_SIMT_ENTER_ALLOC (internal_fn, gcall *stmt)
190 rtx target;
191 tree lhs = gimple_call_lhs (stmt);
192 if (lhs)
193 target = expand_expr (lhs, NULL_RTX, VOIDmode, EXPAND_WRITE);
194 else
195 target = gen_reg_rtx (Pmode);
196 rtx size = expand_normal (gimple_call_arg (stmt, 0));
197 rtx align = expand_normal (gimple_call_arg (stmt, 1));
198 struct expand_operand ops[3];
199 create_output_operand (&ops[0], target, Pmode);
200 create_input_operand (&ops[1], size, Pmode);
201 create_input_operand (&ops[2], align, Pmode);
202 gcc_assert (targetm.have_omp_simt_enter ());
203 expand_insn (targetm.code_for_omp_simt_enter, 3, ops);
206 /* Deallocate per-lane storage and leave non-uniform execution region. */
208 static void
209 expand_GOMP_SIMT_EXIT (internal_fn, gcall *stmt)
211 gcc_checking_assert (!gimple_call_lhs (stmt));
212 rtx arg = expand_normal (gimple_call_arg (stmt, 0));
213 struct expand_operand ops[1];
214 create_input_operand (&ops[0], arg, Pmode);
215 gcc_assert (targetm.have_omp_simt_exit ());
216 expand_insn (targetm.code_for_omp_simt_exit, 1, ops);
219 /* Lane index on SIMT targets: thread index in the warp on NVPTX. On targets
220 without SIMT execution this should be expanded in omp_device_lower pass. */
222 static void
223 expand_GOMP_SIMT_LANE (internal_fn, gcall *stmt)
225 tree lhs = gimple_call_lhs (stmt);
226 if (!lhs)
227 return;
229 rtx target = expand_expr (lhs, NULL_RTX, VOIDmode, EXPAND_WRITE);
230 gcc_assert (targetm.have_omp_simt_lane ());
231 emit_insn (targetm.gen_omp_simt_lane (target));
234 /* This should get expanded in omp_device_lower pass. */
236 static void
237 expand_GOMP_SIMT_VF (internal_fn, gcall *)
239 gcc_unreachable ();
242 /* Lane index of the first SIMT lane that supplies a non-zero argument.
243 This is a SIMT counterpart to GOMP_SIMD_LAST_LANE, used to represent the
244 lane that executed the last iteration for handling OpenMP lastprivate. */
246 static void
247 expand_GOMP_SIMT_LAST_LANE (internal_fn, gcall *stmt)
249 tree lhs = gimple_call_lhs (stmt);
250 if (!lhs)
251 return;
253 rtx target = expand_expr (lhs, NULL_RTX, VOIDmode, EXPAND_WRITE);
254 rtx cond = expand_normal (gimple_call_arg (stmt, 0));
255 machine_mode mode = TYPE_MODE (TREE_TYPE (lhs));
256 struct expand_operand ops[2];
257 create_output_operand (&ops[0], target, mode);
258 create_input_operand (&ops[1], cond, mode);
259 gcc_assert (targetm.have_omp_simt_last_lane ());
260 expand_insn (targetm.code_for_omp_simt_last_lane, 2, ops);
263 /* Non-transparent predicate used in SIMT lowering of OpenMP "ordered". */
265 static void
266 expand_GOMP_SIMT_ORDERED_PRED (internal_fn, gcall *stmt)
268 tree lhs = gimple_call_lhs (stmt);
269 if (!lhs)
270 return;
272 rtx target = expand_expr (lhs, NULL_RTX, VOIDmode, EXPAND_WRITE);
273 rtx ctr = expand_normal (gimple_call_arg (stmt, 0));
274 machine_mode mode = TYPE_MODE (TREE_TYPE (lhs));
275 struct expand_operand ops[2];
276 create_output_operand (&ops[0], target, mode);
277 create_input_operand (&ops[1], ctr, mode);
278 gcc_assert (targetm.have_omp_simt_ordered ());
279 expand_insn (targetm.code_for_omp_simt_ordered, 2, ops);
282 /* "Or" boolean reduction across SIMT lanes: return non-zero in all lanes if
283 any lane supplies a non-zero argument. */
285 static void
286 expand_GOMP_SIMT_VOTE_ANY (internal_fn, gcall *stmt)
288 tree lhs = gimple_call_lhs (stmt);
289 if (!lhs)
290 return;
292 rtx target = expand_expr (lhs, NULL_RTX, VOIDmode, EXPAND_WRITE);
293 rtx cond = expand_normal (gimple_call_arg (stmt, 0));
294 machine_mode mode = TYPE_MODE (TREE_TYPE (lhs));
295 struct expand_operand ops[2];
296 create_output_operand (&ops[0], target, mode);
297 create_input_operand (&ops[1], cond, mode);
298 gcc_assert (targetm.have_omp_simt_vote_any ());
299 expand_insn (targetm.code_for_omp_simt_vote_any, 2, ops);
302 /* Exchange between SIMT lanes with a "butterfly" pattern: source lane index
303 is destination lane index XOR given offset. */
305 static void
306 expand_GOMP_SIMT_XCHG_BFLY (internal_fn, gcall *stmt)
308 tree lhs = gimple_call_lhs (stmt);
309 if (!lhs)
310 return;
312 rtx target = expand_expr (lhs, NULL_RTX, VOIDmode, EXPAND_WRITE);
313 rtx src = expand_normal (gimple_call_arg (stmt, 0));
314 rtx idx = expand_normal (gimple_call_arg (stmt, 1));
315 machine_mode mode = TYPE_MODE (TREE_TYPE (lhs));
316 struct expand_operand ops[3];
317 create_output_operand (&ops[0], target, mode);
318 create_input_operand (&ops[1], src, mode);
319 create_input_operand (&ops[2], idx, SImode);
320 gcc_assert (targetm.have_omp_simt_xchg_bfly ());
321 expand_insn (targetm.code_for_omp_simt_xchg_bfly, 3, ops);
324 /* Exchange between SIMT lanes according to given source lane index. */
326 static void
327 expand_GOMP_SIMT_XCHG_IDX (internal_fn, gcall *stmt)
329 tree lhs = gimple_call_lhs (stmt);
330 if (!lhs)
331 return;
333 rtx target = expand_expr (lhs, NULL_RTX, VOIDmode, EXPAND_WRITE);
334 rtx src = expand_normal (gimple_call_arg (stmt, 0));
335 rtx idx = expand_normal (gimple_call_arg (stmt, 1));
336 machine_mode mode = TYPE_MODE (TREE_TYPE (lhs));
337 struct expand_operand ops[3];
338 create_output_operand (&ops[0], target, mode);
339 create_input_operand (&ops[1], src, mode);
340 create_input_operand (&ops[2], idx, SImode);
341 gcc_assert (targetm.have_omp_simt_xchg_idx ());
342 expand_insn (targetm.code_for_omp_simt_xchg_idx, 3, ops);
345 /* This should get expanded in adjust_simduid_builtins. */
347 static void
348 expand_GOMP_SIMD_LANE (internal_fn, gcall *)
350 gcc_unreachable ();
353 /* This should get expanded in adjust_simduid_builtins. */
355 static void
356 expand_GOMP_SIMD_VF (internal_fn, gcall *)
358 gcc_unreachable ();
361 /* This should get expanded in adjust_simduid_builtins. */
363 static void
364 expand_GOMP_SIMD_LAST_LANE (internal_fn, gcall *)
366 gcc_unreachable ();
369 /* This should get expanded in adjust_simduid_builtins. */
371 static void
372 expand_GOMP_SIMD_ORDERED_START (internal_fn, gcall *)
374 gcc_unreachable ();
377 /* This should get expanded in adjust_simduid_builtins. */
379 static void
380 expand_GOMP_SIMD_ORDERED_END (internal_fn, gcall *)
382 gcc_unreachable ();
385 /* This should get expanded in the sanopt pass. */
387 static void
388 expand_UBSAN_NULL (internal_fn, gcall *)
390 gcc_unreachable ();
393 /* This should get expanded in the sanopt pass. */
395 static void
396 expand_UBSAN_BOUNDS (internal_fn, gcall *)
398 gcc_unreachable ();
401 /* This should get expanded in the sanopt pass. */
403 static void
404 expand_UBSAN_VPTR (internal_fn, gcall *)
406 gcc_unreachable ();
409 /* This should get expanded in the sanopt pass. */
411 static void
412 expand_UBSAN_PTR (internal_fn, gcall *)
414 gcc_unreachable ();
417 /* This should get expanded in the sanopt pass. */
419 static void
420 expand_UBSAN_OBJECT_SIZE (internal_fn, gcall *)
422 gcc_unreachable ();
425 /* This should get expanded in the sanopt pass. */
427 static void
428 expand_ASAN_CHECK (internal_fn, gcall *)
430 gcc_unreachable ();
433 /* This should get expanded in the sanopt pass. */
435 static void
436 expand_ASAN_MARK (internal_fn, gcall *)
438 gcc_unreachable ();
441 /* This should get expanded in the sanopt pass. */
443 static void
444 expand_ASAN_POISON (internal_fn, gcall *)
446 gcc_unreachable ();
449 /* This should get expanded in the sanopt pass. */
451 static void
452 expand_ASAN_POISON_USE (internal_fn, gcall *)
454 gcc_unreachable ();
457 /* This should get expanded in the tsan pass. */
459 static void
460 expand_TSAN_FUNC_EXIT (internal_fn, gcall *)
462 gcc_unreachable ();
465 /* This should get expanded in the lower pass. */
467 static void
468 expand_FALLTHROUGH (internal_fn, gcall *call)
470 error_at (gimple_location (call),
471 "invalid use of attribute %<fallthrough%>");
474 /* Return minimum precision needed to represent all values
475 of ARG in SIGNed integral type. */
477 static int
478 get_min_precision (tree arg, signop sign)
480 int prec = TYPE_PRECISION (TREE_TYPE (arg));
481 int cnt = 0;
482 signop orig_sign = sign;
483 if (TREE_CODE (arg) == INTEGER_CST)
485 int p;
486 if (TYPE_SIGN (TREE_TYPE (arg)) != sign)
488 widest_int w = wi::to_widest (arg);
489 w = wi::ext (w, prec, sign);
490 p = wi::min_precision (w, sign);
492 else
493 p = wi::min_precision (wi::to_wide (arg), sign);
494 return MIN (p, prec);
496 while (CONVERT_EXPR_P (arg)
497 && INTEGRAL_TYPE_P (TREE_TYPE (TREE_OPERAND (arg, 0)))
498 && TYPE_PRECISION (TREE_TYPE (TREE_OPERAND (arg, 0))) <= prec)
500 arg = TREE_OPERAND (arg, 0);
501 if (TYPE_PRECISION (TREE_TYPE (arg)) < prec)
503 if (TYPE_UNSIGNED (TREE_TYPE (arg)))
504 sign = UNSIGNED;
505 else if (sign == UNSIGNED && get_range_pos_neg (arg) != 1)
506 return prec + (orig_sign != sign);
507 prec = TYPE_PRECISION (TREE_TYPE (arg));
509 if (++cnt > 30)
510 return prec + (orig_sign != sign);
512 if (TREE_CODE (arg) != SSA_NAME)
513 return prec + (orig_sign != sign);
514 wide_int arg_min, arg_max;
515 while (get_range_info (arg, &arg_min, &arg_max) != VR_RANGE)
517 gimple *g = SSA_NAME_DEF_STMT (arg);
518 if (is_gimple_assign (g)
519 && CONVERT_EXPR_CODE_P (gimple_assign_rhs_code (g)))
521 tree t = gimple_assign_rhs1 (g);
522 if (INTEGRAL_TYPE_P (TREE_TYPE (t))
523 && TYPE_PRECISION (TREE_TYPE (t)) <= prec)
525 arg = t;
526 if (TYPE_PRECISION (TREE_TYPE (arg)) < prec)
528 if (TYPE_UNSIGNED (TREE_TYPE (arg)))
529 sign = UNSIGNED;
530 else if (sign == UNSIGNED && get_range_pos_neg (arg) != 1)
531 return prec + (orig_sign != sign);
532 prec = TYPE_PRECISION (TREE_TYPE (arg));
534 if (++cnt > 30)
535 return prec + (orig_sign != sign);
536 continue;
539 return prec + (orig_sign != sign);
541 if (sign == TYPE_SIGN (TREE_TYPE (arg)))
543 int p1 = wi::min_precision (arg_min, sign);
544 int p2 = wi::min_precision (arg_max, sign);
545 p1 = MAX (p1, p2);
546 prec = MIN (prec, p1);
548 else if (sign == UNSIGNED && !wi::neg_p (arg_min, SIGNED))
550 int p = wi::min_precision (arg_max, UNSIGNED);
551 prec = MIN (prec, p);
553 return prec + (orig_sign != sign);
556 /* Helper for expand_*_overflow. Set the __imag__ part to true
557 (1 except for signed:1 type, in which case store -1). */
559 static void
560 expand_arith_set_overflow (tree lhs, rtx target)
562 if (TYPE_PRECISION (TREE_TYPE (TREE_TYPE (lhs))) == 1
563 && !TYPE_UNSIGNED (TREE_TYPE (TREE_TYPE (lhs))))
564 write_complex_part (target, constm1_rtx, true);
565 else
566 write_complex_part (target, const1_rtx, true);
569 /* Helper for expand_*_overflow. Store RES into the __real__ part
570 of TARGET. If RES has larger MODE than __real__ part of TARGET,
571 set the __imag__ part to 1 if RES doesn't fit into it. Similarly
572 if LHS has smaller precision than its mode. */
574 static void
575 expand_arith_overflow_result_store (tree lhs, rtx target,
576 scalar_int_mode mode, rtx res)
578 scalar_int_mode tgtmode
579 = as_a <scalar_int_mode> (GET_MODE_INNER (GET_MODE (target)));
580 rtx lres = res;
581 if (tgtmode != mode)
583 rtx_code_label *done_label = gen_label_rtx ();
584 int uns = TYPE_UNSIGNED (TREE_TYPE (TREE_TYPE (lhs)));
585 lres = convert_modes (tgtmode, mode, res, uns);
586 gcc_assert (GET_MODE_PRECISION (tgtmode) < GET_MODE_PRECISION (mode));
587 do_compare_rtx_and_jump (res, convert_modes (mode, tgtmode, lres, uns),
588 EQ, true, mode, NULL_RTX, NULL, done_label,
589 profile_probability::very_likely ());
590 expand_arith_set_overflow (lhs, target);
591 emit_label (done_label);
593 int prec = TYPE_PRECISION (TREE_TYPE (TREE_TYPE (lhs)));
594 int tgtprec = GET_MODE_PRECISION (tgtmode);
595 if (prec < tgtprec)
597 rtx_code_label *done_label = gen_label_rtx ();
598 int uns = TYPE_UNSIGNED (TREE_TYPE (TREE_TYPE (lhs)));
599 res = lres;
600 if (uns)
602 rtx mask
603 = immed_wide_int_const (wi::shifted_mask (0, prec, false, tgtprec),
604 tgtmode);
605 lres = expand_simple_binop (tgtmode, AND, res, mask, NULL_RTX,
606 true, OPTAB_LIB_WIDEN);
608 else
610 lres = expand_shift (LSHIFT_EXPR, tgtmode, res, tgtprec - prec,
611 NULL_RTX, 1);
612 lres = expand_shift (RSHIFT_EXPR, tgtmode, lres, tgtprec - prec,
613 NULL_RTX, 0);
615 do_compare_rtx_and_jump (res, lres,
616 EQ, true, tgtmode, NULL_RTX, NULL, done_label,
617 profile_probability::very_likely ());
618 expand_arith_set_overflow (lhs, target);
619 emit_label (done_label);
621 write_complex_part (target, lres, false);
624 /* Helper for expand_*_overflow. Store RES into TARGET. */
626 static void
627 expand_ubsan_result_store (rtx target, rtx res)
629 if (GET_CODE (target) == SUBREG && SUBREG_PROMOTED_VAR_P (target))
630 /* If this is a scalar in a register that is stored in a wider mode
631 than the declared mode, compute the result into its declared mode
632 and then convert to the wider mode. Our value is the computed
633 expression. */
634 convert_move (SUBREG_REG (target), res, SUBREG_PROMOTED_SIGN (target));
635 else
636 emit_move_insn (target, res);
639 /* Add sub/add overflow checking to the statement STMT.
640 CODE says whether the operation is +, or -. */
642 static void
643 expand_addsub_overflow (location_t loc, tree_code code, tree lhs,
644 tree arg0, tree arg1, bool unsr_p, bool uns0_p,
645 bool uns1_p, bool is_ubsan, tree *datap)
647 rtx res, target = NULL_RTX;
648 tree fn;
649 rtx_code_label *done_label = gen_label_rtx ();
650 rtx_code_label *do_error = gen_label_rtx ();
651 do_pending_stack_adjust ();
652 rtx op0 = expand_normal (arg0);
653 rtx op1 = expand_normal (arg1);
654 scalar_int_mode mode = SCALAR_INT_TYPE_MODE (TREE_TYPE (arg0));
655 int prec = GET_MODE_PRECISION (mode);
656 rtx sgn = immed_wide_int_const (wi::min_value (prec, SIGNED), mode);
657 bool do_xor = false;
659 if (is_ubsan)
660 gcc_assert (!unsr_p && !uns0_p && !uns1_p);
662 if (lhs)
664 target = expand_expr (lhs, NULL_RTX, VOIDmode, EXPAND_WRITE);
665 if (!is_ubsan)
666 write_complex_part (target, const0_rtx, true);
669 /* We assume both operands and result have the same precision
670 here (GET_MODE_BITSIZE (mode)), S stands for signed type
671 with that precision, U for unsigned type with that precision,
672 sgn for unsigned most significant bit in that precision.
673 s1 is signed first operand, u1 is unsigned first operand,
674 s2 is signed second operand, u2 is unsigned second operand,
675 sr is signed result, ur is unsigned result and the following
676 rules say how to compute result (which is always result of
677 the operands as if both were unsigned, cast to the right
678 signedness) and how to compute whether operation overflowed.
680 s1 + s2 -> sr
681 res = (S) ((U) s1 + (U) s2)
682 ovf = s2 < 0 ? res > s1 : res < s1 (or jump on overflow)
683 s1 - s2 -> sr
684 res = (S) ((U) s1 - (U) s2)
685 ovf = s2 < 0 ? res < s1 : res > s2 (or jump on overflow)
686 u1 + u2 -> ur
687 res = u1 + u2
688 ovf = res < u1 (or jump on carry, but RTL opts will handle it)
689 u1 - u2 -> ur
690 res = u1 - u2
691 ovf = res > u1 (or jump on carry, but RTL opts will handle it)
692 s1 + u2 -> sr
693 res = (S) ((U) s1 + u2)
694 ovf = ((U) res ^ sgn) < u2
695 s1 + u2 -> ur
696 t1 = (S) (u2 ^ sgn)
697 t2 = s1 + t1
698 res = (U) t2 ^ sgn
699 ovf = t1 < 0 ? t2 > s1 : t2 < s1 (or jump on overflow)
700 s1 - u2 -> sr
701 res = (S) ((U) s1 - u2)
702 ovf = u2 > ((U) s1 ^ sgn)
703 s1 - u2 -> ur
704 res = (U) s1 - u2
705 ovf = s1 < 0 || u2 > (U) s1
706 u1 - s2 -> sr
707 res = u1 - (U) s2
708 ovf = u1 >= ((U) s2 ^ sgn)
709 u1 - s2 -> ur
710 t1 = u1 ^ sgn
711 t2 = t1 - (U) s2
712 res = t2 ^ sgn
713 ovf = s2 < 0 ? (S) t2 < (S) t1 : (S) t2 > (S) t1 (or jump on overflow)
714 s1 + s2 -> ur
715 res = (U) s1 + (U) s2
716 ovf = s2 < 0 ? (s1 | (S) res) < 0) : (s1 & (S) res) < 0)
717 u1 + u2 -> sr
718 res = (S) (u1 + u2)
719 ovf = (U) res < u2 || res < 0
720 u1 - u2 -> sr
721 res = (S) (u1 - u2)
722 ovf = u1 >= u2 ? res < 0 : res >= 0
723 s1 - s2 -> ur
724 res = (U) s1 - (U) s2
725 ovf = s2 >= 0 ? ((s1 | (S) res) < 0) : ((s1 & (S) res) < 0) */
727 if (code == PLUS_EXPR && uns0_p && !uns1_p)
729 /* PLUS_EXPR is commutative, if operand signedness differs,
730 canonicalize to the first operand being signed and second
731 unsigned to simplify following code. */
732 std::swap (op0, op1);
733 std::swap (arg0, arg1);
734 uns0_p = false;
735 uns1_p = true;
738 /* u1 +- u2 -> ur */
739 if (uns0_p && uns1_p && unsr_p)
741 insn_code icode = optab_handler (code == PLUS_EXPR ? uaddv4_optab
742 : usubv4_optab, mode);
743 if (icode != CODE_FOR_nothing)
745 struct expand_operand ops[4];
746 rtx_insn *last = get_last_insn ();
748 res = gen_reg_rtx (mode);
749 create_output_operand (&ops[0], res, mode);
750 create_input_operand (&ops[1], op0, mode);
751 create_input_operand (&ops[2], op1, mode);
752 create_fixed_operand (&ops[3], do_error);
753 if (maybe_expand_insn (icode, 4, ops))
755 last = get_last_insn ();
756 if (profile_status_for_fn (cfun) != PROFILE_ABSENT
757 && JUMP_P (last)
758 && any_condjump_p (last)
759 && !find_reg_note (last, REG_BR_PROB, 0))
760 add_reg_br_prob_note (last,
761 profile_probability::very_unlikely ());
762 emit_jump (done_label);
763 goto do_error_label;
766 delete_insns_since (last);
769 /* Compute the operation. On RTL level, the addition is always
770 unsigned. */
771 res = expand_binop (mode, code == PLUS_EXPR ? add_optab : sub_optab,
772 op0, op1, NULL_RTX, false, OPTAB_LIB_WIDEN);
773 rtx tem = op0;
774 /* For PLUS_EXPR, the operation is commutative, so we can pick
775 operand to compare against. For prec <= BITS_PER_WORD, I think
776 preferring REG operand is better over CONST_INT, because
777 the CONST_INT might enlarge the instruction or CSE would need
778 to figure out we'd already loaded it into a register before.
779 For prec > BITS_PER_WORD, I think CONST_INT might be more beneficial,
780 as then the multi-word comparison can be perhaps simplified. */
781 if (code == PLUS_EXPR
782 && (prec <= BITS_PER_WORD
783 ? (CONST_SCALAR_INT_P (op0) && REG_P (op1))
784 : CONST_SCALAR_INT_P (op1)))
785 tem = op1;
786 do_compare_rtx_and_jump (res, tem, code == PLUS_EXPR ? GEU : LEU,
787 true, mode, NULL_RTX, NULL, done_label,
788 profile_probability::very_likely ());
789 goto do_error_label;
792 /* s1 +- u2 -> sr */
793 if (!uns0_p && uns1_p && !unsr_p)
795 /* Compute the operation. On RTL level, the addition is always
796 unsigned. */
797 res = expand_binop (mode, code == PLUS_EXPR ? add_optab : sub_optab,
798 op0, op1, NULL_RTX, false, OPTAB_LIB_WIDEN);
799 rtx tem = expand_binop (mode, add_optab,
800 code == PLUS_EXPR ? res : op0, sgn,
801 NULL_RTX, false, OPTAB_LIB_WIDEN);
802 do_compare_rtx_and_jump (tem, op1, GEU, true, mode, NULL_RTX, NULL,
803 done_label, profile_probability::very_likely ());
804 goto do_error_label;
807 /* s1 + u2 -> ur */
808 if (code == PLUS_EXPR && !uns0_p && uns1_p && unsr_p)
810 op1 = expand_binop (mode, add_optab, op1, sgn, NULL_RTX, false,
811 OPTAB_LIB_WIDEN);
812 /* As we've changed op1, we have to avoid using the value range
813 for the original argument. */
814 arg1 = error_mark_node;
815 do_xor = true;
816 goto do_signed;
819 /* u1 - s2 -> ur */
820 if (code == MINUS_EXPR && uns0_p && !uns1_p && unsr_p)
822 op0 = expand_binop (mode, add_optab, op0, sgn, NULL_RTX, false,
823 OPTAB_LIB_WIDEN);
824 /* As we've changed op0, we have to avoid using the value range
825 for the original argument. */
826 arg0 = error_mark_node;
827 do_xor = true;
828 goto do_signed;
831 /* s1 - u2 -> ur */
832 if (code == MINUS_EXPR && !uns0_p && uns1_p && unsr_p)
834 /* Compute the operation. On RTL level, the addition is always
835 unsigned. */
836 res = expand_binop (mode, sub_optab, op0, op1, NULL_RTX, false,
837 OPTAB_LIB_WIDEN);
838 int pos_neg = get_range_pos_neg (arg0);
839 if (pos_neg == 2)
840 /* If ARG0 is known to be always negative, this is always overflow. */
841 emit_jump (do_error);
842 else if (pos_neg == 3)
843 /* If ARG0 is not known to be always positive, check at runtime. */
844 do_compare_rtx_and_jump (op0, const0_rtx, LT, false, mode, NULL_RTX,
845 NULL, do_error, profile_probability::very_unlikely ());
846 do_compare_rtx_and_jump (op1, op0, LEU, true, mode, NULL_RTX, NULL,
847 done_label, profile_probability::very_likely ());
848 goto do_error_label;
851 /* u1 - s2 -> sr */
852 if (code == MINUS_EXPR && uns0_p && !uns1_p && !unsr_p)
854 /* Compute the operation. On RTL level, the addition is always
855 unsigned. */
856 res = expand_binop (mode, sub_optab, op0, op1, NULL_RTX, false,
857 OPTAB_LIB_WIDEN);
858 rtx tem = expand_binop (mode, add_optab, op1, sgn, NULL_RTX, false,
859 OPTAB_LIB_WIDEN);
860 do_compare_rtx_and_jump (op0, tem, LTU, true, mode, NULL_RTX, NULL,
861 done_label, profile_probability::very_likely ());
862 goto do_error_label;
865 /* u1 + u2 -> sr */
866 if (code == PLUS_EXPR && uns0_p && uns1_p && !unsr_p)
868 /* Compute the operation. On RTL level, the addition is always
869 unsigned. */
870 res = expand_binop (mode, add_optab, op0, op1, NULL_RTX, false,
871 OPTAB_LIB_WIDEN);
872 do_compare_rtx_and_jump (res, const0_rtx, LT, false, mode, NULL_RTX,
873 NULL, do_error, profile_probability::very_unlikely ());
874 rtx tem = op1;
875 /* The operation is commutative, so we can pick operand to compare
876 against. For prec <= BITS_PER_WORD, I think preferring REG operand
877 is better over CONST_INT, because the CONST_INT might enlarge the
878 instruction or CSE would need to figure out we'd already loaded it
879 into a register before. For prec > BITS_PER_WORD, I think CONST_INT
880 might be more beneficial, as then the multi-word comparison can be
881 perhaps simplified. */
882 if (prec <= BITS_PER_WORD
883 ? (CONST_SCALAR_INT_P (op1) && REG_P (op0))
884 : CONST_SCALAR_INT_P (op0))
885 tem = op0;
886 do_compare_rtx_and_jump (res, tem, GEU, true, mode, NULL_RTX, NULL,
887 done_label, profile_probability::very_likely ());
888 goto do_error_label;
891 /* s1 +- s2 -> ur */
892 if (!uns0_p && !uns1_p && unsr_p)
894 /* Compute the operation. On RTL level, the addition is always
895 unsigned. */
896 res = expand_binop (mode, code == PLUS_EXPR ? add_optab : sub_optab,
897 op0, op1, NULL_RTX, false, OPTAB_LIB_WIDEN);
898 int pos_neg = get_range_pos_neg (arg1);
899 if (code == PLUS_EXPR)
901 int pos_neg0 = get_range_pos_neg (arg0);
902 if (pos_neg0 != 3 && pos_neg == 3)
904 std::swap (op0, op1);
905 pos_neg = pos_neg0;
908 rtx tem;
909 if (pos_neg != 3)
911 tem = expand_binop (mode, ((pos_neg == 1) ^ (code == MINUS_EXPR))
912 ? and_optab : ior_optab,
913 op0, res, NULL_RTX, false, OPTAB_LIB_WIDEN);
914 do_compare_rtx_and_jump (tem, const0_rtx, GE, false, mode, NULL,
915 NULL, done_label, profile_probability::very_likely ());
917 else
919 rtx_code_label *do_ior_label = gen_label_rtx ();
920 do_compare_rtx_and_jump (op1, const0_rtx,
921 code == MINUS_EXPR ? GE : LT, false, mode,
922 NULL_RTX, NULL, do_ior_label,
923 profile_probability::even ());
924 tem = expand_binop (mode, and_optab, op0, res, NULL_RTX, false,
925 OPTAB_LIB_WIDEN);
926 do_compare_rtx_and_jump (tem, const0_rtx, GE, false, mode, NULL_RTX,
927 NULL, done_label, profile_probability::very_likely ());
928 emit_jump (do_error);
929 emit_label (do_ior_label);
930 tem = expand_binop (mode, ior_optab, op0, res, NULL_RTX, false,
931 OPTAB_LIB_WIDEN);
932 do_compare_rtx_and_jump (tem, const0_rtx, GE, false, mode, NULL_RTX,
933 NULL, done_label, profile_probability::very_likely ());
935 goto do_error_label;
938 /* u1 - u2 -> sr */
939 if (code == MINUS_EXPR && uns0_p && uns1_p && !unsr_p)
941 /* Compute the operation. On RTL level, the addition is always
942 unsigned. */
943 res = expand_binop (mode, sub_optab, op0, op1, NULL_RTX, false,
944 OPTAB_LIB_WIDEN);
945 rtx_code_label *op0_geu_op1 = gen_label_rtx ();
946 do_compare_rtx_and_jump (op0, op1, GEU, true, mode, NULL_RTX, NULL,
947 op0_geu_op1, profile_probability::even ());
948 do_compare_rtx_and_jump (res, const0_rtx, LT, false, mode, NULL_RTX,
949 NULL, done_label, profile_probability::very_likely ());
950 emit_jump (do_error);
951 emit_label (op0_geu_op1);
952 do_compare_rtx_and_jump (res, const0_rtx, GE, false, mode, NULL_RTX,
953 NULL, done_label, profile_probability::very_likely ());
954 goto do_error_label;
957 gcc_assert (!uns0_p && !uns1_p && !unsr_p);
959 /* s1 +- s2 -> sr */
960 do_signed:
962 insn_code icode = optab_handler (code == PLUS_EXPR ? addv4_optab
963 : subv4_optab, mode);
964 if (icode != CODE_FOR_nothing)
966 struct expand_operand ops[4];
967 rtx_insn *last = get_last_insn ();
969 res = gen_reg_rtx (mode);
970 create_output_operand (&ops[0], res, mode);
971 create_input_operand (&ops[1], op0, mode);
972 create_input_operand (&ops[2], op1, mode);
973 create_fixed_operand (&ops[3], do_error);
974 if (maybe_expand_insn (icode, 4, ops))
976 last = get_last_insn ();
977 if (profile_status_for_fn (cfun) != PROFILE_ABSENT
978 && JUMP_P (last)
979 && any_condjump_p (last)
980 && !find_reg_note (last, REG_BR_PROB, 0))
981 add_reg_br_prob_note (last,
982 profile_probability::very_unlikely ());
983 emit_jump (done_label);
984 goto do_error_label;
987 delete_insns_since (last);
990 /* Compute the operation. On RTL level, the addition is always
991 unsigned. */
992 res = expand_binop (mode, code == PLUS_EXPR ? add_optab : sub_optab,
993 op0, op1, NULL_RTX, false, OPTAB_LIB_WIDEN);
995 /* If we can prove that one of the arguments (for MINUS_EXPR only
996 the second operand, as subtraction is not commutative) is always
997 non-negative or always negative, we can do just one comparison
998 and conditional jump. */
999 int pos_neg = get_range_pos_neg (arg1);
1000 if (code == PLUS_EXPR)
1002 int pos_neg0 = get_range_pos_neg (arg0);
1003 if (pos_neg0 != 3 && pos_neg == 3)
1005 std::swap (op0, op1);
1006 pos_neg = pos_neg0;
1010 /* Addition overflows if and only if the two operands have the same sign,
1011 and the result has the opposite sign. Subtraction overflows if and
1012 only if the two operands have opposite sign, and the subtrahend has
1013 the same sign as the result. Here 0 is counted as positive. */
1014 if (pos_neg == 3)
1016 /* Compute op0 ^ op1 (operands have opposite sign). */
1017 rtx op_xor = expand_binop (mode, xor_optab, op0, op1, NULL_RTX, false,
1018 OPTAB_LIB_WIDEN);
1020 /* Compute res ^ op1 (result and 2nd operand have opposite sign). */
1021 rtx res_xor = expand_binop (mode, xor_optab, res, op1, NULL_RTX, false,
1022 OPTAB_LIB_WIDEN);
1024 rtx tem;
1025 if (code == PLUS_EXPR)
1027 /* Compute (res ^ op1) & ~(op0 ^ op1). */
1028 tem = expand_unop (mode, one_cmpl_optab, op_xor, NULL_RTX, false);
1029 tem = expand_binop (mode, and_optab, res_xor, tem, NULL_RTX, false,
1030 OPTAB_LIB_WIDEN);
1032 else
1034 /* Compute (op0 ^ op1) & ~(res ^ op1). */
1035 tem = expand_unop (mode, one_cmpl_optab, res_xor, NULL_RTX, false);
1036 tem = expand_binop (mode, and_optab, op_xor, tem, NULL_RTX, false,
1037 OPTAB_LIB_WIDEN);
1040 /* No overflow if the result has bit sign cleared. */
1041 do_compare_rtx_and_jump (tem, const0_rtx, GE, false, mode, NULL_RTX,
1042 NULL, done_label, profile_probability::very_likely ());
1045 /* Compare the result of the operation with the first operand.
1046 No overflow for addition if second operand is positive and result
1047 is larger or second operand is negative and result is smaller.
1048 Likewise for subtraction with sign of second operand flipped. */
1049 else
1050 do_compare_rtx_and_jump (res, op0,
1051 (pos_neg == 1) ^ (code == MINUS_EXPR) ? GE : LE,
1052 false, mode, NULL_RTX, NULL, done_label,
1053 profile_probability::very_likely ());
1056 do_error_label:
1057 emit_label (do_error);
1058 if (is_ubsan)
1060 /* Expand the ubsan builtin call. */
1061 push_temp_slots ();
1062 fn = ubsan_build_overflow_builtin (code, loc, TREE_TYPE (arg0),
1063 arg0, arg1, datap);
1064 expand_normal (fn);
1065 pop_temp_slots ();
1066 do_pending_stack_adjust ();
1068 else if (lhs)
1069 expand_arith_set_overflow (lhs, target);
1071 /* We're done. */
1072 emit_label (done_label);
1074 if (lhs)
1076 if (is_ubsan)
1077 expand_ubsan_result_store (target, res);
1078 else
1080 if (do_xor)
1081 res = expand_binop (mode, add_optab, res, sgn, NULL_RTX, false,
1082 OPTAB_LIB_WIDEN);
1084 expand_arith_overflow_result_store (lhs, target, mode, res);
1089 /* Add negate overflow checking to the statement STMT. */
1091 static void
1092 expand_neg_overflow (location_t loc, tree lhs, tree arg1, bool is_ubsan,
1093 tree *datap)
1095 rtx res, op1;
1096 tree fn;
1097 rtx_code_label *done_label, *do_error;
1098 rtx target = NULL_RTX;
1100 done_label = gen_label_rtx ();
1101 do_error = gen_label_rtx ();
1103 do_pending_stack_adjust ();
1104 op1 = expand_normal (arg1);
1106 scalar_int_mode mode = SCALAR_INT_TYPE_MODE (TREE_TYPE (arg1));
1107 if (lhs)
1109 target = expand_expr (lhs, NULL_RTX, VOIDmode, EXPAND_WRITE);
1110 if (!is_ubsan)
1111 write_complex_part (target, const0_rtx, true);
1114 enum insn_code icode = optab_handler (negv3_optab, mode);
1115 if (icode != CODE_FOR_nothing)
1117 struct expand_operand ops[3];
1118 rtx_insn *last = get_last_insn ();
1120 res = gen_reg_rtx (mode);
1121 create_output_operand (&ops[0], res, mode);
1122 create_input_operand (&ops[1], op1, mode);
1123 create_fixed_operand (&ops[2], do_error);
1124 if (maybe_expand_insn (icode, 3, ops))
1126 last = get_last_insn ();
1127 if (profile_status_for_fn (cfun) != PROFILE_ABSENT
1128 && JUMP_P (last)
1129 && any_condjump_p (last)
1130 && !find_reg_note (last, REG_BR_PROB, 0))
1131 add_reg_br_prob_note (last,
1132 profile_probability::very_unlikely ());
1133 emit_jump (done_label);
1135 else
1137 delete_insns_since (last);
1138 icode = CODE_FOR_nothing;
1142 if (icode == CODE_FOR_nothing)
1144 /* Compute the operation. On RTL level, the addition is always
1145 unsigned. */
1146 res = expand_unop (mode, neg_optab, op1, NULL_RTX, false);
1148 /* Compare the operand with the most negative value. */
1149 rtx minv = expand_normal (TYPE_MIN_VALUE (TREE_TYPE (arg1)));
1150 do_compare_rtx_and_jump (op1, minv, NE, true, mode, NULL_RTX, NULL,
1151 done_label, profile_probability::very_likely ());
1154 emit_label (do_error);
1155 if (is_ubsan)
1157 /* Expand the ubsan builtin call. */
1158 push_temp_slots ();
1159 fn = ubsan_build_overflow_builtin (NEGATE_EXPR, loc, TREE_TYPE (arg1),
1160 arg1, NULL_TREE, datap);
1161 expand_normal (fn);
1162 pop_temp_slots ();
1163 do_pending_stack_adjust ();
1165 else if (lhs)
1166 expand_arith_set_overflow (lhs, target);
1168 /* We're done. */
1169 emit_label (done_label);
1171 if (lhs)
1173 if (is_ubsan)
1174 expand_ubsan_result_store (target, res);
1175 else
1176 expand_arith_overflow_result_store (lhs, target, mode, res);
1180 /* Return true if UNS WIDEN_MULT_EXPR with result mode WMODE and operand
1181 mode MODE can be expanded without using a libcall. */
1183 static bool
1184 can_widen_mult_without_libcall (scalar_int_mode wmode, scalar_int_mode mode,
1185 rtx op0, rtx op1, bool uns)
1187 if (find_widening_optab_handler (umul_widen_optab, wmode, mode)
1188 != CODE_FOR_nothing)
1189 return true;
1191 if (find_widening_optab_handler (smul_widen_optab, wmode, mode)
1192 != CODE_FOR_nothing)
1193 return true;
1195 rtx_insn *last = get_last_insn ();
1196 if (CONSTANT_P (op0))
1197 op0 = convert_modes (wmode, mode, op0, uns);
1198 else
1199 op0 = gen_raw_REG (wmode, LAST_VIRTUAL_REGISTER + 1);
1200 if (CONSTANT_P (op1))
1201 op1 = convert_modes (wmode, mode, op1, uns);
1202 else
1203 op1 = gen_raw_REG (wmode, LAST_VIRTUAL_REGISTER + 2);
1204 rtx ret = expand_mult (wmode, op0, op1, NULL_RTX, uns, true);
1205 delete_insns_since (last);
1206 return ret != NULL_RTX;
1209 /* Add mul overflow checking to the statement STMT. */
1211 static void
1212 expand_mul_overflow (location_t loc, tree lhs, tree arg0, tree arg1,
1213 bool unsr_p, bool uns0_p, bool uns1_p, bool is_ubsan,
1214 tree *datap)
1216 rtx res, op0, op1;
1217 tree fn, type;
1218 rtx_code_label *done_label, *do_error;
1219 rtx target = NULL_RTX;
1220 signop sign;
1221 enum insn_code icode;
1223 done_label = gen_label_rtx ();
1224 do_error = gen_label_rtx ();
1226 do_pending_stack_adjust ();
1227 op0 = expand_normal (arg0);
1228 op1 = expand_normal (arg1);
1230 scalar_int_mode mode = SCALAR_INT_TYPE_MODE (TREE_TYPE (arg0));
1231 bool uns = unsr_p;
1232 if (lhs)
1234 target = expand_expr (lhs, NULL_RTX, VOIDmode, EXPAND_WRITE);
1235 if (!is_ubsan)
1236 write_complex_part (target, const0_rtx, true);
1239 if (is_ubsan)
1240 gcc_assert (!unsr_p && !uns0_p && !uns1_p);
1242 /* We assume both operands and result have the same precision
1243 here (GET_MODE_BITSIZE (mode)), S stands for signed type
1244 with that precision, U for unsigned type with that precision,
1245 sgn for unsigned most significant bit in that precision.
1246 s1 is signed first operand, u1 is unsigned first operand,
1247 s2 is signed second operand, u2 is unsigned second operand,
1248 sr is signed result, ur is unsigned result and the following
1249 rules say how to compute result (which is always result of
1250 the operands as if both were unsigned, cast to the right
1251 signedness) and how to compute whether operation overflowed.
1252 main_ovf (false) stands for jump on signed multiplication
1253 overflow or the main algorithm with uns == false.
1254 main_ovf (true) stands for jump on unsigned multiplication
1255 overflow or the main algorithm with uns == true.
1257 s1 * s2 -> sr
1258 res = (S) ((U) s1 * (U) s2)
1259 ovf = main_ovf (false)
1260 u1 * u2 -> ur
1261 res = u1 * u2
1262 ovf = main_ovf (true)
1263 s1 * u2 -> ur
1264 res = (U) s1 * u2
1265 ovf = (s1 < 0 && u2) || main_ovf (true)
1266 u1 * u2 -> sr
1267 res = (S) (u1 * u2)
1268 ovf = res < 0 || main_ovf (true)
1269 s1 * u2 -> sr
1270 res = (S) ((U) s1 * u2)
1271 ovf = (S) u2 >= 0 ? main_ovf (false)
1272 : (s1 != 0 && (s1 != -1 || u2 != (U) res))
1273 s1 * s2 -> ur
1274 t1 = (s1 & s2) < 0 ? (-(U) s1) : ((U) s1)
1275 t2 = (s1 & s2) < 0 ? (-(U) s2) : ((U) s2)
1276 res = t1 * t2
1277 ovf = (s1 ^ s2) < 0 ? (s1 && s2) : main_ovf (true) */
1279 if (uns0_p && !uns1_p)
1281 /* Multiplication is commutative, if operand signedness differs,
1282 canonicalize to the first operand being signed and second
1283 unsigned to simplify following code. */
1284 std::swap (op0, op1);
1285 std::swap (arg0, arg1);
1286 uns0_p = false;
1287 uns1_p = true;
1290 int pos_neg0 = get_range_pos_neg (arg0);
1291 int pos_neg1 = get_range_pos_neg (arg1);
1293 /* s1 * u2 -> ur */
1294 if (!uns0_p && uns1_p && unsr_p)
1296 switch (pos_neg0)
1298 case 1:
1299 /* If s1 is non-negative, just perform normal u1 * u2 -> ur. */
1300 goto do_main;
1301 case 2:
1302 /* If s1 is negative, avoid the main code, just multiply and
1303 signal overflow if op1 is not 0. */
1304 struct separate_ops ops;
1305 ops.code = MULT_EXPR;
1306 ops.type = TREE_TYPE (arg1);
1307 ops.op0 = make_tree (ops.type, op0);
1308 ops.op1 = make_tree (ops.type, op1);
1309 ops.op2 = NULL_TREE;
1310 ops.location = loc;
1311 res = expand_expr_real_2 (&ops, NULL_RTX, mode, EXPAND_NORMAL);
1312 do_compare_rtx_and_jump (op1, const0_rtx, EQ, true, mode, NULL_RTX,
1313 NULL, done_label, profile_probability::very_likely ());
1314 goto do_error_label;
1315 case 3:
1316 rtx_code_label *do_main_label;
1317 do_main_label = gen_label_rtx ();
1318 do_compare_rtx_and_jump (op0, const0_rtx, GE, false, mode, NULL_RTX,
1319 NULL, do_main_label, profile_probability::very_likely ());
1320 do_compare_rtx_and_jump (op1, const0_rtx, EQ, true, mode, NULL_RTX,
1321 NULL, do_main_label, profile_probability::very_likely ());
1322 expand_arith_set_overflow (lhs, target);
1323 emit_label (do_main_label);
1324 goto do_main;
1325 default:
1326 gcc_unreachable ();
1330 /* u1 * u2 -> sr */
1331 if (uns0_p && uns1_p && !unsr_p)
1333 uns = true;
1334 /* Rest of handling of this case after res is computed. */
1335 goto do_main;
1338 /* s1 * u2 -> sr */
1339 if (!uns0_p && uns1_p && !unsr_p)
1341 switch (pos_neg1)
1343 case 1:
1344 goto do_main;
1345 case 2:
1346 /* If (S) u2 is negative (i.e. u2 is larger than maximum of S,
1347 avoid the main code, just multiply and signal overflow
1348 unless 0 * u2 or -1 * ((U) Smin). */
1349 struct separate_ops ops;
1350 ops.code = MULT_EXPR;
1351 ops.type = TREE_TYPE (arg1);
1352 ops.op0 = make_tree (ops.type, op0);
1353 ops.op1 = make_tree (ops.type, op1);
1354 ops.op2 = NULL_TREE;
1355 ops.location = loc;
1356 res = expand_expr_real_2 (&ops, NULL_RTX, mode, EXPAND_NORMAL);
1357 do_compare_rtx_and_jump (op0, const0_rtx, EQ, true, mode, NULL_RTX,
1358 NULL, done_label, profile_probability::very_likely ());
1359 do_compare_rtx_and_jump (op0, constm1_rtx, NE, true, mode, NULL_RTX,
1360 NULL, do_error, profile_probability::very_unlikely ());
1361 int prec;
1362 prec = GET_MODE_PRECISION (mode);
1363 rtx sgn;
1364 sgn = immed_wide_int_const (wi::min_value (prec, SIGNED), mode);
1365 do_compare_rtx_and_jump (op1, sgn, EQ, true, mode, NULL_RTX,
1366 NULL, done_label, profile_probability::very_likely ());
1367 goto do_error_label;
1368 case 3:
1369 /* Rest of handling of this case after res is computed. */
1370 goto do_main;
1371 default:
1372 gcc_unreachable ();
1376 /* s1 * s2 -> ur */
1377 if (!uns0_p && !uns1_p && unsr_p)
1379 rtx tem, tem2;
1380 switch (pos_neg0 | pos_neg1)
1382 case 1: /* Both operands known to be non-negative. */
1383 goto do_main;
1384 case 2: /* Both operands known to be negative. */
1385 op0 = expand_unop (mode, neg_optab, op0, NULL_RTX, false);
1386 op1 = expand_unop (mode, neg_optab, op1, NULL_RTX, false);
1387 /* Avoid looking at arg0/arg1 ranges, as we've changed
1388 the arguments. */
1389 arg0 = error_mark_node;
1390 arg1 = error_mark_node;
1391 goto do_main;
1392 case 3:
1393 if ((pos_neg0 ^ pos_neg1) == 3)
1395 /* If one operand is known to be negative and the other
1396 non-negative, this overflows always, unless the non-negative
1397 one is 0. Just do normal multiply and set overflow
1398 unless one of the operands is 0. */
1399 struct separate_ops ops;
1400 ops.code = MULT_EXPR;
1401 ops.type
1402 = build_nonstandard_integer_type (GET_MODE_PRECISION (mode),
1404 ops.op0 = make_tree (ops.type, op0);
1405 ops.op1 = make_tree (ops.type, op1);
1406 ops.op2 = NULL_TREE;
1407 ops.location = loc;
1408 res = expand_expr_real_2 (&ops, NULL_RTX, mode, EXPAND_NORMAL);
1409 tem = expand_binop (mode, and_optab, op0, op1, NULL_RTX, false,
1410 OPTAB_LIB_WIDEN);
1411 do_compare_rtx_and_jump (tem, const0_rtx, EQ, true, mode,
1412 NULL_RTX, NULL, done_label,
1413 profile_probability::very_likely ());
1414 goto do_error_label;
1416 /* The general case, do all the needed comparisons at runtime. */
1417 rtx_code_label *do_main_label, *after_negate_label;
1418 rtx rop0, rop1;
1419 rop0 = gen_reg_rtx (mode);
1420 rop1 = gen_reg_rtx (mode);
1421 emit_move_insn (rop0, op0);
1422 emit_move_insn (rop1, op1);
1423 op0 = rop0;
1424 op1 = rop1;
1425 do_main_label = gen_label_rtx ();
1426 after_negate_label = gen_label_rtx ();
1427 tem = expand_binop (mode, and_optab, op0, op1, NULL_RTX, false,
1428 OPTAB_LIB_WIDEN);
1429 do_compare_rtx_and_jump (tem, const0_rtx, GE, false, mode, NULL_RTX,
1430 NULL, after_negate_label, profile_probability::very_likely ());
1431 /* Both arguments negative here, negate them and continue with
1432 normal unsigned overflow checking multiplication. */
1433 emit_move_insn (op0, expand_unop (mode, neg_optab, op0,
1434 NULL_RTX, false));
1435 emit_move_insn (op1, expand_unop (mode, neg_optab, op1,
1436 NULL_RTX, false));
1437 /* Avoid looking at arg0/arg1 ranges, as we might have changed
1438 the arguments. */
1439 arg0 = error_mark_node;
1440 arg1 = error_mark_node;
1441 emit_jump (do_main_label);
1442 emit_label (after_negate_label);
1443 tem2 = expand_binop (mode, xor_optab, op0, op1, NULL_RTX, false,
1444 OPTAB_LIB_WIDEN);
1445 do_compare_rtx_and_jump (tem2, const0_rtx, GE, false, mode, NULL_RTX,
1446 NULL, do_main_label, profile_probability::very_likely ());
1447 /* One argument is negative here, the other positive. This
1448 overflows always, unless one of the arguments is 0. But
1449 if e.g. s2 is 0, (U) s1 * 0 doesn't overflow, whatever s1
1450 is, thus we can keep do_main code oring in overflow as is. */
1451 do_compare_rtx_and_jump (tem, const0_rtx, EQ, true, mode, NULL_RTX,
1452 NULL, do_main_label, profile_probability::very_likely ());
1453 expand_arith_set_overflow (lhs, target);
1454 emit_label (do_main_label);
1455 goto do_main;
1456 default:
1457 gcc_unreachable ();
1461 do_main:
1462 type = build_nonstandard_integer_type (GET_MODE_PRECISION (mode), uns);
1463 sign = uns ? UNSIGNED : SIGNED;
1464 icode = optab_handler (uns ? umulv4_optab : mulv4_optab, mode);
1465 if (uns
1466 && (integer_pow2p (arg0) || integer_pow2p (arg1))
1467 && (optimize_insn_for_speed_p () || icode == CODE_FOR_nothing))
1469 /* Optimize unsigned multiplication by power of 2 constant
1470 using 2 shifts, one for result, one to extract the shifted
1471 out bits to see if they are all zero.
1472 Don't do this if optimizing for size and we have umulv4_optab,
1473 in that case assume multiplication will be shorter.
1474 This is heuristics based on the single target that provides
1475 umulv4 right now (i?86/x86_64), if further targets add it, this
1476 might need to be revisited.
1477 Cases where both operands are constant should be folded already
1478 during GIMPLE, and cases where one operand is constant but not
1479 power of 2 are questionable, either the WIDEN_MULT_EXPR case
1480 below can be done without multiplication, just by shifts and adds,
1481 or we'd need to divide the result (and hope it actually doesn't
1482 really divide nor multiply) and compare the result of the division
1483 with the original operand. */
1484 rtx opn0 = op0;
1485 rtx opn1 = op1;
1486 tree argn0 = arg0;
1487 tree argn1 = arg1;
1488 if (integer_pow2p (arg0))
1490 std::swap (opn0, opn1);
1491 std::swap (argn0, argn1);
1493 int cnt = tree_log2 (argn1);
1494 if (cnt >= 0 && cnt < GET_MODE_PRECISION (mode))
1496 rtx upper = const0_rtx;
1497 res = expand_shift (LSHIFT_EXPR, mode, opn0, cnt, NULL_RTX, uns);
1498 if (cnt != 0)
1499 upper = expand_shift (RSHIFT_EXPR, mode, opn0,
1500 GET_MODE_PRECISION (mode) - cnt,
1501 NULL_RTX, uns);
1502 do_compare_rtx_and_jump (upper, const0_rtx, EQ, true, mode,
1503 NULL_RTX, NULL, done_label,
1504 profile_probability::very_likely ());
1505 goto do_error_label;
1508 if (icode != CODE_FOR_nothing)
1510 struct expand_operand ops[4];
1511 rtx_insn *last = get_last_insn ();
1513 res = gen_reg_rtx (mode);
1514 create_output_operand (&ops[0], res, mode);
1515 create_input_operand (&ops[1], op0, mode);
1516 create_input_operand (&ops[2], op1, mode);
1517 create_fixed_operand (&ops[3], do_error);
1518 if (maybe_expand_insn (icode, 4, ops))
1520 last = get_last_insn ();
1521 if (profile_status_for_fn (cfun) != PROFILE_ABSENT
1522 && JUMP_P (last)
1523 && any_condjump_p (last)
1524 && !find_reg_note (last, REG_BR_PROB, 0))
1525 add_reg_br_prob_note (last,
1526 profile_probability::very_unlikely ());
1527 emit_jump (done_label);
1529 else
1531 delete_insns_since (last);
1532 icode = CODE_FOR_nothing;
1536 if (icode == CODE_FOR_nothing)
1538 struct separate_ops ops;
1539 int prec = GET_MODE_PRECISION (mode);
1540 scalar_int_mode hmode, wmode;
1541 ops.op0 = make_tree (type, op0);
1542 ops.op1 = make_tree (type, op1);
1543 ops.op2 = NULL_TREE;
1544 ops.location = loc;
1546 /* Optimize unsigned overflow check where we don't use the
1547 multiplication result, just whether overflow happened.
1548 If we can do MULT_HIGHPART_EXPR, that followed by
1549 comparison of the result against zero is cheapest.
1550 We'll still compute res, but it should be DCEd later. */
1551 use_operand_p use;
1552 gimple *use_stmt;
1553 if (!is_ubsan
1554 && lhs
1555 && uns
1556 && !(uns0_p && uns1_p && !unsr_p)
1557 && can_mult_highpart_p (mode, uns) == 1
1558 && single_imm_use (lhs, &use, &use_stmt)
1559 && is_gimple_assign (use_stmt)
1560 && gimple_assign_rhs_code (use_stmt) == IMAGPART_EXPR)
1561 goto highpart;
1563 if (GET_MODE_2XWIDER_MODE (mode).exists (&wmode)
1564 && targetm.scalar_mode_supported_p (wmode)
1565 && can_widen_mult_without_libcall (wmode, mode, op0, op1, uns))
1567 twoxwider:
1568 ops.code = WIDEN_MULT_EXPR;
1569 ops.type
1570 = build_nonstandard_integer_type (GET_MODE_PRECISION (wmode), uns);
1572 res = expand_expr_real_2 (&ops, NULL_RTX, wmode, EXPAND_NORMAL);
1573 rtx hipart = expand_shift (RSHIFT_EXPR, wmode, res, prec,
1574 NULL_RTX, uns);
1575 hipart = convert_modes (mode, wmode, hipart, uns);
1576 res = convert_modes (mode, wmode, res, uns);
1577 if (uns)
1578 /* For the unsigned multiplication, there was overflow if
1579 HIPART is non-zero. */
1580 do_compare_rtx_and_jump (hipart, const0_rtx, EQ, true, mode,
1581 NULL_RTX, NULL, done_label,
1582 profile_probability::very_likely ());
1583 else
1585 rtx signbit = expand_shift (RSHIFT_EXPR, mode, res, prec - 1,
1586 NULL_RTX, 0);
1587 /* RES is low half of the double width result, HIPART
1588 the high half. There was overflow if
1589 HIPART is different from RES < 0 ? -1 : 0. */
1590 do_compare_rtx_and_jump (signbit, hipart, EQ, true, mode,
1591 NULL_RTX, NULL, done_label,
1592 profile_probability::very_likely ());
1595 else if (can_mult_highpart_p (mode, uns) == 1)
1597 highpart:
1598 ops.code = MULT_HIGHPART_EXPR;
1599 ops.type = type;
1601 rtx hipart = expand_expr_real_2 (&ops, NULL_RTX, mode,
1602 EXPAND_NORMAL);
1603 ops.code = MULT_EXPR;
1604 res = expand_expr_real_2 (&ops, NULL_RTX, mode, EXPAND_NORMAL);
1605 if (uns)
1606 /* For the unsigned multiplication, there was overflow if
1607 HIPART is non-zero. */
1608 do_compare_rtx_and_jump (hipart, const0_rtx, EQ, true, mode,
1609 NULL_RTX, NULL, done_label,
1610 profile_probability::very_likely ());
1611 else
1613 rtx signbit = expand_shift (RSHIFT_EXPR, mode, res, prec - 1,
1614 NULL_RTX, 0);
1615 /* RES is low half of the double width result, HIPART
1616 the high half. There was overflow if
1617 HIPART is different from RES < 0 ? -1 : 0. */
1618 do_compare_rtx_and_jump (signbit, hipart, EQ, true, mode,
1619 NULL_RTX, NULL, done_label,
1620 profile_probability::very_likely ());
1624 else if (int_mode_for_size (prec / 2, 1).exists (&hmode)
1625 && 2 * GET_MODE_PRECISION (hmode) == prec)
1627 rtx_code_label *large_op0 = gen_label_rtx ();
1628 rtx_code_label *small_op0_large_op1 = gen_label_rtx ();
1629 rtx_code_label *one_small_one_large = gen_label_rtx ();
1630 rtx_code_label *both_ops_large = gen_label_rtx ();
1631 rtx_code_label *after_hipart_neg = uns ? NULL : gen_label_rtx ();
1632 rtx_code_label *after_lopart_neg = uns ? NULL : gen_label_rtx ();
1633 rtx_code_label *do_overflow = gen_label_rtx ();
1634 rtx_code_label *hipart_different = uns ? NULL : gen_label_rtx ();
1636 unsigned int hprec = GET_MODE_PRECISION (hmode);
1637 rtx hipart0 = expand_shift (RSHIFT_EXPR, mode, op0, hprec,
1638 NULL_RTX, uns);
1639 hipart0 = convert_modes (hmode, mode, hipart0, uns);
1640 rtx lopart0 = convert_modes (hmode, mode, op0, uns);
1641 rtx signbit0 = const0_rtx;
1642 if (!uns)
1643 signbit0 = expand_shift (RSHIFT_EXPR, hmode, lopart0, hprec - 1,
1644 NULL_RTX, 0);
1645 rtx hipart1 = expand_shift (RSHIFT_EXPR, mode, op1, hprec,
1646 NULL_RTX, uns);
1647 hipart1 = convert_modes (hmode, mode, hipart1, uns);
1648 rtx lopart1 = convert_modes (hmode, mode, op1, uns);
1649 rtx signbit1 = const0_rtx;
1650 if (!uns)
1651 signbit1 = expand_shift (RSHIFT_EXPR, hmode, lopart1, hprec - 1,
1652 NULL_RTX, 0);
1654 res = gen_reg_rtx (mode);
1656 /* True if op0 resp. op1 are known to be in the range of
1657 halfstype. */
1658 bool op0_small_p = false;
1659 bool op1_small_p = false;
1660 /* True if op0 resp. op1 are known to have all zeros or all ones
1661 in the upper half of bits, but are not known to be
1662 op{0,1}_small_p. */
1663 bool op0_medium_p = false;
1664 bool op1_medium_p = false;
1665 /* -1 if op{0,1} is known to be negative, 0 if it is known to be
1666 nonnegative, 1 if unknown. */
1667 int op0_sign = 1;
1668 int op1_sign = 1;
1670 if (pos_neg0 == 1)
1671 op0_sign = 0;
1672 else if (pos_neg0 == 2)
1673 op0_sign = -1;
1674 if (pos_neg1 == 1)
1675 op1_sign = 0;
1676 else if (pos_neg1 == 2)
1677 op1_sign = -1;
1679 unsigned int mprec0 = prec;
1680 if (arg0 != error_mark_node)
1681 mprec0 = get_min_precision (arg0, sign);
1682 if (mprec0 <= hprec)
1683 op0_small_p = true;
1684 else if (!uns && mprec0 <= hprec + 1)
1685 op0_medium_p = true;
1686 unsigned int mprec1 = prec;
1687 if (arg1 != error_mark_node)
1688 mprec1 = get_min_precision (arg1, sign);
1689 if (mprec1 <= hprec)
1690 op1_small_p = true;
1691 else if (!uns && mprec1 <= hprec + 1)
1692 op1_medium_p = true;
1694 int smaller_sign = 1;
1695 int larger_sign = 1;
1696 if (op0_small_p)
1698 smaller_sign = op0_sign;
1699 larger_sign = op1_sign;
1701 else if (op1_small_p)
1703 smaller_sign = op1_sign;
1704 larger_sign = op0_sign;
1706 else if (op0_sign == op1_sign)
1708 smaller_sign = op0_sign;
1709 larger_sign = op0_sign;
1712 if (!op0_small_p)
1713 do_compare_rtx_and_jump (signbit0, hipart0, NE, true, hmode,
1714 NULL_RTX, NULL, large_op0,
1715 profile_probability::unlikely ());
1717 if (!op1_small_p)
1718 do_compare_rtx_and_jump (signbit1, hipart1, NE, true, hmode,
1719 NULL_RTX, NULL, small_op0_large_op1,
1720 profile_probability::unlikely ());
1722 /* If both op0 and op1 are sign (!uns) or zero (uns) extended from
1723 hmode to mode, the multiplication will never overflow. We can
1724 do just one hmode x hmode => mode widening multiplication. */
1725 rtx lopart0s = lopart0, lopart1s = lopart1;
1726 if (GET_CODE (lopart0) == SUBREG)
1728 lopart0s = shallow_copy_rtx (lopart0);
1729 SUBREG_PROMOTED_VAR_P (lopart0s) = 1;
1730 SUBREG_PROMOTED_SET (lopart0s, uns ? SRP_UNSIGNED : SRP_SIGNED);
1732 if (GET_CODE (lopart1) == SUBREG)
1734 lopart1s = shallow_copy_rtx (lopart1);
1735 SUBREG_PROMOTED_VAR_P (lopart1s) = 1;
1736 SUBREG_PROMOTED_SET (lopart1s, uns ? SRP_UNSIGNED : SRP_SIGNED);
1738 tree halfstype = build_nonstandard_integer_type (hprec, uns);
1739 ops.op0 = make_tree (halfstype, lopart0s);
1740 ops.op1 = make_tree (halfstype, lopart1s);
1741 ops.code = WIDEN_MULT_EXPR;
1742 ops.type = type;
1743 rtx thisres
1744 = expand_expr_real_2 (&ops, NULL_RTX, mode, EXPAND_NORMAL);
1745 emit_move_insn (res, thisres);
1746 emit_jump (done_label);
1748 emit_label (small_op0_large_op1);
1750 /* If op0 is sign (!uns) or zero (uns) extended from hmode to mode,
1751 but op1 is not, just swap the arguments and handle it as op1
1752 sign/zero extended, op0 not. */
1753 rtx larger = gen_reg_rtx (mode);
1754 rtx hipart = gen_reg_rtx (hmode);
1755 rtx lopart = gen_reg_rtx (hmode);
1756 emit_move_insn (larger, op1);
1757 emit_move_insn (hipart, hipart1);
1758 emit_move_insn (lopart, lopart0);
1759 emit_jump (one_small_one_large);
1761 emit_label (large_op0);
1763 if (!op1_small_p)
1764 do_compare_rtx_and_jump (signbit1, hipart1, NE, true, hmode,
1765 NULL_RTX, NULL, both_ops_large,
1766 profile_probability::unlikely ());
1768 /* If op1 is sign (!uns) or zero (uns) extended from hmode to mode,
1769 but op0 is not, prepare larger, hipart and lopart pseudos and
1770 handle it together with small_op0_large_op1. */
1771 emit_move_insn (larger, op0);
1772 emit_move_insn (hipart, hipart0);
1773 emit_move_insn (lopart, lopart1);
1775 emit_label (one_small_one_large);
1777 /* lopart is the low part of the operand that is sign extended
1778 to mode, larger is the other operand, hipart is the
1779 high part of larger and lopart0 and lopart1 are the low parts
1780 of both operands.
1781 We perform lopart0 * lopart1 and lopart * hipart widening
1782 multiplications. */
1783 tree halfutype = build_nonstandard_integer_type (hprec, 1);
1784 ops.op0 = make_tree (halfutype, lopart0);
1785 ops.op1 = make_tree (halfutype, lopart1);
1786 rtx lo0xlo1
1787 = expand_expr_real_2 (&ops, NULL_RTX, mode, EXPAND_NORMAL);
1789 ops.op0 = make_tree (halfutype, lopart);
1790 ops.op1 = make_tree (halfutype, hipart);
1791 rtx loxhi = gen_reg_rtx (mode);
1792 rtx tem = expand_expr_real_2 (&ops, NULL_RTX, mode, EXPAND_NORMAL);
1793 emit_move_insn (loxhi, tem);
1795 if (!uns)
1797 /* if (hipart < 0) loxhi -= lopart << (bitsize / 2); */
1798 if (larger_sign == 0)
1799 emit_jump (after_hipart_neg);
1800 else if (larger_sign != -1)
1801 do_compare_rtx_and_jump (hipart, const0_rtx, GE, false, hmode,
1802 NULL_RTX, NULL, after_hipart_neg,
1803 profile_probability::even ());
1805 tem = convert_modes (mode, hmode, lopart, 1);
1806 tem = expand_shift (LSHIFT_EXPR, mode, tem, hprec, NULL_RTX, 1);
1807 tem = expand_simple_binop (mode, MINUS, loxhi, tem, NULL_RTX,
1808 1, OPTAB_WIDEN);
1809 emit_move_insn (loxhi, tem);
1811 emit_label (after_hipart_neg);
1813 /* if (lopart < 0) loxhi -= larger; */
1814 if (smaller_sign == 0)
1815 emit_jump (after_lopart_neg);
1816 else if (smaller_sign != -1)
1817 do_compare_rtx_and_jump (lopart, const0_rtx, GE, false, hmode,
1818 NULL_RTX, NULL, after_lopart_neg,
1819 profile_probability::even ());
1821 tem = expand_simple_binop (mode, MINUS, loxhi, larger, NULL_RTX,
1822 1, OPTAB_WIDEN);
1823 emit_move_insn (loxhi, tem);
1825 emit_label (after_lopart_neg);
1828 /* loxhi += (uns) lo0xlo1 >> (bitsize / 2); */
1829 tem = expand_shift (RSHIFT_EXPR, mode, lo0xlo1, hprec, NULL_RTX, 1);
1830 tem = expand_simple_binop (mode, PLUS, loxhi, tem, NULL_RTX,
1831 1, OPTAB_WIDEN);
1832 emit_move_insn (loxhi, tem);
1834 /* if (loxhi >> (bitsize / 2)
1835 == (hmode) loxhi >> (bitsize / 2 - 1)) (if !uns)
1836 if (loxhi >> (bitsize / 2) == 0 (if uns). */
1837 rtx hipartloxhi = expand_shift (RSHIFT_EXPR, mode, loxhi, hprec,
1838 NULL_RTX, 0);
1839 hipartloxhi = convert_modes (hmode, mode, hipartloxhi, 0);
1840 rtx signbitloxhi = const0_rtx;
1841 if (!uns)
1842 signbitloxhi = expand_shift (RSHIFT_EXPR, hmode,
1843 convert_modes (hmode, mode,
1844 loxhi, 0),
1845 hprec - 1, NULL_RTX, 0);
1847 do_compare_rtx_and_jump (signbitloxhi, hipartloxhi, NE, true, hmode,
1848 NULL_RTX, NULL, do_overflow,
1849 profile_probability::very_unlikely ());
1851 /* res = (loxhi << (bitsize / 2)) | (hmode) lo0xlo1; */
1852 rtx loxhishifted = expand_shift (LSHIFT_EXPR, mode, loxhi, hprec,
1853 NULL_RTX, 1);
1854 tem = convert_modes (mode, hmode,
1855 convert_modes (hmode, mode, lo0xlo1, 1), 1);
1857 tem = expand_simple_binop (mode, IOR, loxhishifted, tem, res,
1858 1, OPTAB_WIDEN);
1859 if (tem != res)
1860 emit_move_insn (res, tem);
1861 emit_jump (done_label);
1863 emit_label (both_ops_large);
1865 /* If both operands are large (not sign (!uns) or zero (uns)
1866 extended from hmode), then perform the full multiplication
1867 which will be the result of the operation.
1868 The only cases which don't overflow are for signed multiplication
1869 some cases where both hipart0 and highpart1 are 0 or -1.
1870 For unsigned multiplication when high parts are both non-zero
1871 this overflows always. */
1872 ops.code = MULT_EXPR;
1873 ops.op0 = make_tree (type, op0);
1874 ops.op1 = make_tree (type, op1);
1875 tem = expand_expr_real_2 (&ops, NULL_RTX, mode, EXPAND_NORMAL);
1876 emit_move_insn (res, tem);
1878 if (!uns)
1880 if (!op0_medium_p)
1882 tem = expand_simple_binop (hmode, PLUS, hipart0, const1_rtx,
1883 NULL_RTX, 1, OPTAB_WIDEN);
1884 do_compare_rtx_and_jump (tem, const1_rtx, GTU, true, hmode,
1885 NULL_RTX, NULL, do_error,
1886 profile_probability::very_unlikely ());
1889 if (!op1_medium_p)
1891 tem = expand_simple_binop (hmode, PLUS, hipart1, const1_rtx,
1892 NULL_RTX, 1, OPTAB_WIDEN);
1893 do_compare_rtx_and_jump (tem, const1_rtx, GTU, true, hmode,
1894 NULL_RTX, NULL, do_error,
1895 profile_probability::very_unlikely ());
1898 /* At this point hipart{0,1} are both in [-1, 0]. If they are
1899 the same, overflow happened if res is non-positive, if they
1900 are different, overflow happened if res is positive. */
1901 if (op0_sign != 1 && op1_sign != 1 && op0_sign != op1_sign)
1902 emit_jump (hipart_different);
1903 else if (op0_sign == 1 || op1_sign == 1)
1904 do_compare_rtx_and_jump (hipart0, hipart1, NE, true, hmode,
1905 NULL_RTX, NULL, hipart_different,
1906 profile_probability::even ());
1908 do_compare_rtx_and_jump (res, const0_rtx, LE, false, mode,
1909 NULL_RTX, NULL, do_error,
1910 profile_probability::very_unlikely ());
1911 emit_jump (done_label);
1913 emit_label (hipart_different);
1915 do_compare_rtx_and_jump (res, const0_rtx, GE, false, mode,
1916 NULL_RTX, NULL, do_error,
1917 profile_probability::very_unlikely ());
1918 emit_jump (done_label);
1921 emit_label (do_overflow);
1923 /* Overflow, do full multiplication and fallthru into do_error. */
1924 ops.op0 = make_tree (type, op0);
1925 ops.op1 = make_tree (type, op1);
1926 tem = expand_expr_real_2 (&ops, NULL_RTX, mode, EXPAND_NORMAL);
1927 emit_move_insn (res, tem);
1929 else if (GET_MODE_2XWIDER_MODE (mode).exists (&wmode)
1930 && targetm.scalar_mode_supported_p (wmode))
1931 /* Even emitting a libcall is better than not detecting overflow
1932 at all. */
1933 goto twoxwider;
1934 else
1936 gcc_assert (!is_ubsan);
1937 ops.code = MULT_EXPR;
1938 ops.type = type;
1939 res = expand_expr_real_2 (&ops, NULL_RTX, mode, EXPAND_NORMAL);
1940 emit_jump (done_label);
1944 do_error_label:
1945 emit_label (do_error);
1946 if (is_ubsan)
1948 /* Expand the ubsan builtin call. */
1949 push_temp_slots ();
1950 fn = ubsan_build_overflow_builtin (MULT_EXPR, loc, TREE_TYPE (arg0),
1951 arg0, arg1, datap);
1952 expand_normal (fn);
1953 pop_temp_slots ();
1954 do_pending_stack_adjust ();
1956 else if (lhs)
1957 expand_arith_set_overflow (lhs, target);
1959 /* We're done. */
1960 emit_label (done_label);
1962 /* u1 * u2 -> sr */
1963 if (uns0_p && uns1_p && !unsr_p)
1965 rtx_code_label *all_done_label = gen_label_rtx ();
1966 do_compare_rtx_and_jump (res, const0_rtx, GE, false, mode, NULL_RTX,
1967 NULL, all_done_label, profile_probability::very_likely ());
1968 expand_arith_set_overflow (lhs, target);
1969 emit_label (all_done_label);
1972 /* s1 * u2 -> sr */
1973 if (!uns0_p && uns1_p && !unsr_p && pos_neg1 == 3)
1975 rtx_code_label *all_done_label = gen_label_rtx ();
1976 rtx_code_label *set_noovf = gen_label_rtx ();
1977 do_compare_rtx_and_jump (op1, const0_rtx, GE, false, mode, NULL_RTX,
1978 NULL, all_done_label, profile_probability::very_likely ());
1979 expand_arith_set_overflow (lhs, target);
1980 do_compare_rtx_and_jump (op0, const0_rtx, EQ, true, mode, NULL_RTX,
1981 NULL, set_noovf, profile_probability::very_likely ());
1982 do_compare_rtx_and_jump (op0, constm1_rtx, NE, true, mode, NULL_RTX,
1983 NULL, all_done_label, profile_probability::very_unlikely ());
1984 do_compare_rtx_and_jump (op1, res, NE, true, mode, NULL_RTX, NULL,
1985 all_done_label, profile_probability::very_unlikely ());
1986 emit_label (set_noovf);
1987 write_complex_part (target, const0_rtx, true);
1988 emit_label (all_done_label);
1991 if (lhs)
1993 if (is_ubsan)
1994 expand_ubsan_result_store (target, res);
1995 else
1996 expand_arith_overflow_result_store (lhs, target, mode, res);
2000 /* Expand UBSAN_CHECK_* internal function if it has vector operands. */
2002 static void
2003 expand_vector_ubsan_overflow (location_t loc, enum tree_code code, tree lhs,
2004 tree arg0, tree arg1)
2006 poly_uint64 cnt = TYPE_VECTOR_SUBPARTS (TREE_TYPE (arg0));
2007 rtx_code_label *loop_lab = NULL;
2008 rtx cntvar = NULL_RTX;
2009 tree cntv = NULL_TREE;
2010 tree eltype = TREE_TYPE (TREE_TYPE (arg0));
2011 tree sz = TYPE_SIZE (eltype);
2012 tree data = NULL_TREE;
2013 tree resv = NULL_TREE;
2014 rtx lhsr = NULL_RTX;
2015 rtx resvr = NULL_RTX;
2016 unsigned HOST_WIDE_INT const_cnt = 0;
2017 bool use_loop_p = (!cnt.is_constant (&const_cnt) || const_cnt > 4);
2019 if (lhs)
2021 optab op;
2022 lhsr = expand_expr (lhs, NULL_RTX, VOIDmode, EXPAND_WRITE);
2023 if (!VECTOR_MODE_P (GET_MODE (lhsr))
2024 || (op = optab_for_tree_code (code, TREE_TYPE (arg0),
2025 optab_default)) == unknown_optab
2026 || (optab_handler (op, TYPE_MODE (TREE_TYPE (arg0)))
2027 == CODE_FOR_nothing))
2029 if (MEM_P (lhsr))
2030 resv = make_tree (TREE_TYPE (lhs), lhsr);
2031 else
2033 resvr = assign_temp (TREE_TYPE (lhs), 1, 1);
2034 resv = make_tree (TREE_TYPE (lhs), resvr);
2038 if (use_loop_p)
2040 do_pending_stack_adjust ();
2041 loop_lab = gen_label_rtx ();
2042 cntvar = gen_reg_rtx (TYPE_MODE (sizetype));
2043 cntv = make_tree (sizetype, cntvar);
2044 emit_move_insn (cntvar, const0_rtx);
2045 emit_label (loop_lab);
2047 if (TREE_CODE (arg0) != VECTOR_CST)
2049 rtx arg0r = expand_normal (arg0);
2050 arg0 = make_tree (TREE_TYPE (arg0), arg0r);
2052 if (TREE_CODE (arg1) != VECTOR_CST)
2054 rtx arg1r = expand_normal (arg1);
2055 arg1 = make_tree (TREE_TYPE (arg1), arg1r);
2057 for (unsigned int i = 0; i < (use_loop_p ? 1 : const_cnt); i++)
2059 tree op0, op1, res = NULL_TREE;
2060 if (use_loop_p)
2062 tree atype = build_array_type_nelts (eltype, cnt);
2063 op0 = uniform_vector_p (arg0);
2064 if (op0 == NULL_TREE)
2066 op0 = fold_build1_loc (loc, VIEW_CONVERT_EXPR, atype, arg0);
2067 op0 = build4_loc (loc, ARRAY_REF, eltype, op0, cntv,
2068 NULL_TREE, NULL_TREE);
2070 op1 = uniform_vector_p (arg1);
2071 if (op1 == NULL_TREE)
2073 op1 = fold_build1_loc (loc, VIEW_CONVERT_EXPR, atype, arg1);
2074 op1 = build4_loc (loc, ARRAY_REF, eltype, op1, cntv,
2075 NULL_TREE, NULL_TREE);
2077 if (resv)
2079 res = fold_build1_loc (loc, VIEW_CONVERT_EXPR, atype, resv);
2080 res = build4_loc (loc, ARRAY_REF, eltype, res, cntv,
2081 NULL_TREE, NULL_TREE);
2084 else
2086 tree bitpos = bitsize_int (tree_to_uhwi (sz) * i);
2087 op0 = fold_build3_loc (loc, BIT_FIELD_REF, eltype, arg0, sz, bitpos);
2088 op1 = fold_build3_loc (loc, BIT_FIELD_REF, eltype, arg1, sz, bitpos);
2089 if (resv)
2090 res = fold_build3_loc (loc, BIT_FIELD_REF, eltype, resv, sz,
2091 bitpos);
2093 switch (code)
2095 case PLUS_EXPR:
2096 expand_addsub_overflow (loc, PLUS_EXPR, res, op0, op1,
2097 false, false, false, true, &data);
2098 break;
2099 case MINUS_EXPR:
2100 if (use_loop_p ? integer_zerop (arg0) : integer_zerop (op0))
2101 expand_neg_overflow (loc, res, op1, true, &data);
2102 else
2103 expand_addsub_overflow (loc, MINUS_EXPR, res, op0, op1,
2104 false, false, false, true, &data);
2105 break;
2106 case MULT_EXPR:
2107 expand_mul_overflow (loc, res, op0, op1, false, false, false,
2108 true, &data);
2109 break;
2110 default:
2111 gcc_unreachable ();
2114 if (use_loop_p)
2116 struct separate_ops ops;
2117 ops.code = PLUS_EXPR;
2118 ops.type = TREE_TYPE (cntv);
2119 ops.op0 = cntv;
2120 ops.op1 = build_int_cst (TREE_TYPE (cntv), 1);
2121 ops.op2 = NULL_TREE;
2122 ops.location = loc;
2123 rtx ret = expand_expr_real_2 (&ops, cntvar, TYPE_MODE (sizetype),
2124 EXPAND_NORMAL);
2125 if (ret != cntvar)
2126 emit_move_insn (cntvar, ret);
2127 rtx cntrtx = gen_int_mode (cnt, TYPE_MODE (sizetype));
2128 do_compare_rtx_and_jump (cntvar, cntrtx, NE, false,
2129 TYPE_MODE (sizetype), NULL_RTX, NULL, loop_lab,
2130 profile_probability::very_likely ());
2132 if (lhs && resv == NULL_TREE)
2134 struct separate_ops ops;
2135 ops.code = code;
2136 ops.type = TREE_TYPE (arg0);
2137 ops.op0 = arg0;
2138 ops.op1 = arg1;
2139 ops.op2 = NULL_TREE;
2140 ops.location = loc;
2141 rtx ret = expand_expr_real_2 (&ops, lhsr, TYPE_MODE (TREE_TYPE (arg0)),
2142 EXPAND_NORMAL);
2143 if (ret != lhsr)
2144 emit_move_insn (lhsr, ret);
2146 else if (resvr)
2147 emit_move_insn (lhsr, resvr);
2150 /* Expand UBSAN_CHECK_ADD call STMT. */
2152 static void
2153 expand_UBSAN_CHECK_ADD (internal_fn, gcall *stmt)
2155 location_t loc = gimple_location (stmt);
2156 tree lhs = gimple_call_lhs (stmt);
2157 tree arg0 = gimple_call_arg (stmt, 0);
2158 tree arg1 = gimple_call_arg (stmt, 1);
2159 if (VECTOR_TYPE_P (TREE_TYPE (arg0)))
2160 expand_vector_ubsan_overflow (loc, PLUS_EXPR, lhs, arg0, arg1);
2161 else
2162 expand_addsub_overflow (loc, PLUS_EXPR, lhs, arg0, arg1,
2163 false, false, false, true, NULL);
2166 /* Expand UBSAN_CHECK_SUB call STMT. */
2168 static void
2169 expand_UBSAN_CHECK_SUB (internal_fn, gcall *stmt)
2171 location_t loc = gimple_location (stmt);
2172 tree lhs = gimple_call_lhs (stmt);
2173 tree arg0 = gimple_call_arg (stmt, 0);
2174 tree arg1 = gimple_call_arg (stmt, 1);
2175 if (VECTOR_TYPE_P (TREE_TYPE (arg0)))
2176 expand_vector_ubsan_overflow (loc, MINUS_EXPR, lhs, arg0, arg1);
2177 else if (integer_zerop (arg0))
2178 expand_neg_overflow (loc, lhs, arg1, true, NULL);
2179 else
2180 expand_addsub_overflow (loc, MINUS_EXPR, lhs, arg0, arg1,
2181 false, false, false, true, NULL);
2184 /* Expand UBSAN_CHECK_MUL call STMT. */
2186 static void
2187 expand_UBSAN_CHECK_MUL (internal_fn, gcall *stmt)
2189 location_t loc = gimple_location (stmt);
2190 tree lhs = gimple_call_lhs (stmt);
2191 tree arg0 = gimple_call_arg (stmt, 0);
2192 tree arg1 = gimple_call_arg (stmt, 1);
2193 if (VECTOR_TYPE_P (TREE_TYPE (arg0)))
2194 expand_vector_ubsan_overflow (loc, MULT_EXPR, lhs, arg0, arg1);
2195 else
2196 expand_mul_overflow (loc, lhs, arg0, arg1, false, false, false, true,
2197 NULL);
2200 /* Helper function for {ADD,SUB,MUL}_OVERFLOW call stmt expansion. */
2202 static void
2203 expand_arith_overflow (enum tree_code code, gimple *stmt)
2205 tree lhs = gimple_call_lhs (stmt);
2206 if (lhs == NULL_TREE)
2207 return;
2208 tree arg0 = gimple_call_arg (stmt, 0);
2209 tree arg1 = gimple_call_arg (stmt, 1);
2210 tree type = TREE_TYPE (TREE_TYPE (lhs));
2211 int uns0_p = TYPE_UNSIGNED (TREE_TYPE (arg0));
2212 int uns1_p = TYPE_UNSIGNED (TREE_TYPE (arg1));
2213 int unsr_p = TYPE_UNSIGNED (type);
2214 int prec0 = TYPE_PRECISION (TREE_TYPE (arg0));
2215 int prec1 = TYPE_PRECISION (TREE_TYPE (arg1));
2216 int precres = TYPE_PRECISION (type);
2217 location_t loc = gimple_location (stmt);
2218 if (!uns0_p && get_range_pos_neg (arg0) == 1)
2219 uns0_p = true;
2220 if (!uns1_p && get_range_pos_neg (arg1) == 1)
2221 uns1_p = true;
2222 int pr = get_min_precision (arg0, uns0_p ? UNSIGNED : SIGNED);
2223 prec0 = MIN (prec0, pr);
2224 pr = get_min_precision (arg1, uns1_p ? UNSIGNED : SIGNED);
2225 prec1 = MIN (prec1, pr);
2227 /* If uns0_p && uns1_p, precop is minimum needed precision
2228 of unsigned type to hold the exact result, otherwise
2229 precop is minimum needed precision of signed type to
2230 hold the exact result. */
2231 int precop;
2232 if (code == MULT_EXPR)
2233 precop = prec0 + prec1 + (uns0_p != uns1_p);
2234 else
2236 if (uns0_p == uns1_p)
2237 precop = MAX (prec0, prec1) + 1;
2238 else if (uns0_p)
2239 precop = MAX (prec0 + 1, prec1) + 1;
2240 else
2241 precop = MAX (prec0, prec1 + 1) + 1;
2243 int orig_precres = precres;
2247 if ((uns0_p && uns1_p)
2248 ? ((precop + !unsr_p) <= precres
2249 /* u1 - u2 -> ur can overflow, no matter what precision
2250 the result has. */
2251 && (code != MINUS_EXPR || !unsr_p))
2252 : (!unsr_p && precop <= precres))
2254 /* The infinity precision result will always fit into result. */
2255 rtx target = expand_expr (lhs, NULL_RTX, VOIDmode, EXPAND_WRITE);
2256 write_complex_part (target, const0_rtx, true);
2257 scalar_int_mode mode = SCALAR_INT_TYPE_MODE (type);
2258 struct separate_ops ops;
2259 ops.code = code;
2260 ops.type = type;
2261 ops.op0 = fold_convert_loc (loc, type, arg0);
2262 ops.op1 = fold_convert_loc (loc, type, arg1);
2263 ops.op2 = NULL_TREE;
2264 ops.location = loc;
2265 rtx tem = expand_expr_real_2 (&ops, NULL_RTX, mode, EXPAND_NORMAL);
2266 expand_arith_overflow_result_store (lhs, target, mode, tem);
2267 return;
2270 /* For operations with low precision, if target doesn't have them, start
2271 with precres widening right away, otherwise do it only if the most
2272 simple cases can't be used. */
2273 const int min_precision = targetm.min_arithmetic_precision ();
2274 if (orig_precres == precres && precres < min_precision)
2276 else if ((uns0_p && uns1_p && unsr_p && prec0 <= precres
2277 && prec1 <= precres)
2278 || ((!uns0_p || !uns1_p) && !unsr_p
2279 && prec0 + uns0_p <= precres
2280 && prec1 + uns1_p <= precres))
2282 arg0 = fold_convert_loc (loc, type, arg0);
2283 arg1 = fold_convert_loc (loc, type, arg1);
2284 switch (code)
2286 case MINUS_EXPR:
2287 if (integer_zerop (arg0) && !unsr_p)
2289 expand_neg_overflow (loc, lhs, arg1, false, NULL);
2290 return;
2292 /* FALLTHRU */
2293 case PLUS_EXPR:
2294 expand_addsub_overflow (loc, code, lhs, arg0, arg1, unsr_p,
2295 unsr_p, unsr_p, false, NULL);
2296 return;
2297 case MULT_EXPR:
2298 expand_mul_overflow (loc, lhs, arg0, arg1, unsr_p,
2299 unsr_p, unsr_p, false, NULL);
2300 return;
2301 default:
2302 gcc_unreachable ();
2306 /* For sub-word operations, retry with a wider type first. */
2307 if (orig_precres == precres && precop <= BITS_PER_WORD)
2309 int p = MAX (min_precision, precop);
2310 scalar_int_mode m = smallest_int_mode_for_size (p);
2311 tree optype = build_nonstandard_integer_type (GET_MODE_PRECISION (m),
2312 uns0_p && uns1_p
2313 && unsr_p);
2314 p = TYPE_PRECISION (optype);
2315 if (p > precres)
2317 precres = p;
2318 unsr_p = TYPE_UNSIGNED (optype);
2319 type = optype;
2320 continue;
2324 if (prec0 <= precres && prec1 <= precres)
2326 tree types[2];
2327 if (unsr_p)
2329 types[0] = build_nonstandard_integer_type (precres, 0);
2330 types[1] = type;
2332 else
2334 types[0] = type;
2335 types[1] = build_nonstandard_integer_type (precres, 1);
2337 arg0 = fold_convert_loc (loc, types[uns0_p], arg0);
2338 arg1 = fold_convert_loc (loc, types[uns1_p], arg1);
2339 if (code != MULT_EXPR)
2340 expand_addsub_overflow (loc, code, lhs, arg0, arg1, unsr_p,
2341 uns0_p, uns1_p, false, NULL);
2342 else
2343 expand_mul_overflow (loc, lhs, arg0, arg1, unsr_p,
2344 uns0_p, uns1_p, false, NULL);
2345 return;
2348 /* Retry with a wider type. */
2349 if (orig_precres == precres)
2351 int p = MAX (prec0, prec1);
2352 scalar_int_mode m = smallest_int_mode_for_size (p);
2353 tree optype = build_nonstandard_integer_type (GET_MODE_PRECISION (m),
2354 uns0_p && uns1_p
2355 && unsr_p);
2356 p = TYPE_PRECISION (optype);
2357 if (p > precres)
2359 precres = p;
2360 unsr_p = TYPE_UNSIGNED (optype);
2361 type = optype;
2362 continue;
2366 gcc_unreachable ();
2368 while (1);
2371 /* Expand ADD_OVERFLOW STMT. */
2373 static void
2374 expand_ADD_OVERFLOW (internal_fn, gcall *stmt)
2376 expand_arith_overflow (PLUS_EXPR, stmt);
2379 /* Expand SUB_OVERFLOW STMT. */
2381 static void
2382 expand_SUB_OVERFLOW (internal_fn, gcall *stmt)
2384 expand_arith_overflow (MINUS_EXPR, stmt);
2387 /* Expand MUL_OVERFLOW STMT. */
2389 static void
2390 expand_MUL_OVERFLOW (internal_fn, gcall *stmt)
2392 expand_arith_overflow (MULT_EXPR, stmt);
2395 /* This should get folded in tree-vectorizer.c. */
2397 static void
2398 expand_LOOP_VECTORIZED (internal_fn, gcall *)
2400 gcc_unreachable ();
2403 /* This should get folded in tree-vectorizer.c. */
2405 static void
2406 expand_LOOP_DIST_ALIAS (internal_fn, gcall *)
2408 gcc_unreachable ();
2411 /* Expand MASK_LOAD call STMT using optab OPTAB. */
2413 static void
2414 expand_mask_load_optab_fn (internal_fn, gcall *stmt, convert_optab optab)
2416 struct expand_operand ops[3];
2417 tree type, lhs, rhs, maskt, ptr;
2418 rtx mem, target, mask;
2419 unsigned align;
2421 maskt = gimple_call_arg (stmt, 2);
2422 lhs = gimple_call_lhs (stmt);
2423 if (lhs == NULL_TREE)
2424 return;
2425 type = TREE_TYPE (lhs);
2426 ptr = build_int_cst (TREE_TYPE (gimple_call_arg (stmt, 1)), 0);
2427 align = tree_to_shwi (gimple_call_arg (stmt, 1));
2428 if (TYPE_ALIGN (type) != align)
2429 type = build_aligned_type (type, align);
2430 rhs = fold_build2 (MEM_REF, type, gimple_call_arg (stmt, 0), ptr);
2432 mem = expand_expr (rhs, NULL_RTX, VOIDmode, EXPAND_WRITE);
2433 gcc_assert (MEM_P (mem));
2434 mask = expand_normal (maskt);
2435 target = expand_expr (lhs, NULL_RTX, VOIDmode, EXPAND_WRITE);
2436 create_output_operand (&ops[0], target, TYPE_MODE (type));
2437 create_fixed_operand (&ops[1], mem);
2438 create_input_operand (&ops[2], mask, TYPE_MODE (TREE_TYPE (maskt)));
2439 expand_insn (convert_optab_handler (optab, TYPE_MODE (type),
2440 TYPE_MODE (TREE_TYPE (maskt))),
2441 3, ops);
2444 /* Expand MASK_STORE call STMT using optab OPTAB. */
2446 static void
2447 expand_mask_store_optab_fn (internal_fn, gcall *stmt, convert_optab optab)
2449 struct expand_operand ops[3];
2450 tree type, lhs, rhs, maskt, ptr;
2451 rtx mem, reg, mask;
2452 unsigned align;
2454 maskt = gimple_call_arg (stmt, 2);
2455 rhs = gimple_call_arg (stmt, 3);
2456 type = TREE_TYPE (rhs);
2457 ptr = build_int_cst (TREE_TYPE (gimple_call_arg (stmt, 1)), 0);
2458 align = tree_to_shwi (gimple_call_arg (stmt, 1));
2459 if (TYPE_ALIGN (type) != align)
2460 type = build_aligned_type (type, align);
2461 lhs = fold_build2 (MEM_REF, type, gimple_call_arg (stmt, 0), ptr);
2463 mem = expand_expr (lhs, NULL_RTX, VOIDmode, EXPAND_WRITE);
2464 gcc_assert (MEM_P (mem));
2465 mask = expand_normal (maskt);
2466 reg = expand_normal (rhs);
2467 create_fixed_operand (&ops[0], mem);
2468 create_input_operand (&ops[1], reg, TYPE_MODE (type));
2469 create_input_operand (&ops[2], mask, TYPE_MODE (TREE_TYPE (maskt)));
2470 expand_insn (convert_optab_handler (optab, TYPE_MODE (type),
2471 TYPE_MODE (TREE_TYPE (maskt))),
2472 3, ops);
2475 static void
2476 expand_ABNORMAL_DISPATCHER (internal_fn, gcall *)
2480 static void
2481 expand_BUILTIN_EXPECT (internal_fn, gcall *stmt)
2483 /* When guessing was done, the hints should be already stripped away. */
2484 gcc_assert (!flag_guess_branch_prob || optimize == 0 || seen_error ());
2486 rtx target;
2487 tree lhs = gimple_call_lhs (stmt);
2488 if (lhs)
2489 target = expand_expr (lhs, NULL_RTX, VOIDmode, EXPAND_WRITE);
2490 else
2491 target = const0_rtx;
2492 rtx val = expand_expr (gimple_call_arg (stmt, 0), target, VOIDmode, EXPAND_NORMAL);
2493 if (lhs && val != target)
2494 emit_move_insn (target, val);
2497 /* IFN_VA_ARG is supposed to be expanded at pass_stdarg. So this dummy function
2498 should never be called. */
2500 static void
2501 expand_VA_ARG (internal_fn, gcall *)
2503 gcc_unreachable ();
2506 /* Expand the IFN_UNIQUE function according to its first argument. */
2508 static void
2509 expand_UNIQUE (internal_fn, gcall *stmt)
2511 rtx pattern = NULL_RTX;
2512 enum ifn_unique_kind kind
2513 = (enum ifn_unique_kind) TREE_INT_CST_LOW (gimple_call_arg (stmt, 0));
2515 switch (kind)
2517 default:
2518 gcc_unreachable ();
2520 case IFN_UNIQUE_UNSPEC:
2521 if (targetm.have_unique ())
2522 pattern = targetm.gen_unique ();
2523 break;
2525 case IFN_UNIQUE_OACC_FORK:
2526 case IFN_UNIQUE_OACC_JOIN:
2527 if (targetm.have_oacc_fork () && targetm.have_oacc_join ())
2529 tree lhs = gimple_call_lhs (stmt);
2530 rtx target = const0_rtx;
2532 if (lhs)
2533 target = expand_expr (lhs, NULL_RTX, VOIDmode, EXPAND_WRITE);
2535 rtx data_dep = expand_normal (gimple_call_arg (stmt, 1));
2536 rtx axis = expand_normal (gimple_call_arg (stmt, 2));
2538 if (kind == IFN_UNIQUE_OACC_FORK)
2539 pattern = targetm.gen_oacc_fork (target, data_dep, axis);
2540 else
2541 pattern = targetm.gen_oacc_join (target, data_dep, axis);
2543 else
2544 gcc_unreachable ();
2545 break;
2548 if (pattern)
2549 emit_insn (pattern);
2552 /* The size of an OpenACC compute dimension. */
2554 static void
2555 expand_GOACC_DIM_SIZE (internal_fn, gcall *stmt)
2557 tree lhs = gimple_call_lhs (stmt);
2559 if (!lhs)
2560 return;
2562 rtx target = expand_expr (lhs, NULL_RTX, VOIDmode, EXPAND_WRITE);
2563 if (targetm.have_oacc_dim_size ())
2565 rtx dim = expand_expr (gimple_call_arg (stmt, 0), NULL_RTX,
2566 VOIDmode, EXPAND_NORMAL);
2567 emit_insn (targetm.gen_oacc_dim_size (target, dim));
2569 else
2570 emit_move_insn (target, GEN_INT (1));
2573 /* The position of an OpenACC execution engine along one compute axis. */
2575 static void
2576 expand_GOACC_DIM_POS (internal_fn, gcall *stmt)
2578 tree lhs = gimple_call_lhs (stmt);
2580 if (!lhs)
2581 return;
2583 rtx target = expand_expr (lhs, NULL_RTX, VOIDmode, EXPAND_WRITE);
2584 if (targetm.have_oacc_dim_pos ())
2586 rtx dim = expand_expr (gimple_call_arg (stmt, 0), NULL_RTX,
2587 VOIDmode, EXPAND_NORMAL);
2588 emit_insn (targetm.gen_oacc_dim_pos (target, dim));
2590 else
2591 emit_move_insn (target, const0_rtx);
2594 /* This is expanded by oacc_device_lower pass. */
2596 static void
2597 expand_GOACC_LOOP (internal_fn, gcall *)
2599 gcc_unreachable ();
2602 /* This is expanded by oacc_device_lower pass. */
2604 static void
2605 expand_GOACC_REDUCTION (internal_fn, gcall *)
2607 gcc_unreachable ();
2610 /* This is expanded by oacc_device_lower pass. */
2612 static void
2613 expand_GOACC_TILE (internal_fn, gcall *)
2615 gcc_unreachable ();
2618 /* Set errno to EDOM. */
2620 static void
2621 expand_SET_EDOM (internal_fn, gcall *)
2623 #ifdef TARGET_EDOM
2624 #ifdef GEN_ERRNO_RTX
2625 rtx errno_rtx = GEN_ERRNO_RTX;
2626 #else
2627 rtx errno_rtx = gen_rtx_MEM (word_mode, gen_rtx_SYMBOL_REF (Pmode, "errno"));
2628 #endif
2629 emit_move_insn (errno_rtx,
2630 gen_int_mode (TARGET_EDOM, GET_MODE (errno_rtx)));
2631 #else
2632 gcc_unreachable ();
2633 #endif
2636 /* Expand atomic bit test and set. */
2638 static void
2639 expand_ATOMIC_BIT_TEST_AND_SET (internal_fn, gcall *call)
2641 expand_ifn_atomic_bit_test_and (call);
2644 /* Expand atomic bit test and complement. */
2646 static void
2647 expand_ATOMIC_BIT_TEST_AND_COMPLEMENT (internal_fn, gcall *call)
2649 expand_ifn_atomic_bit_test_and (call);
2652 /* Expand atomic bit test and reset. */
2654 static void
2655 expand_ATOMIC_BIT_TEST_AND_RESET (internal_fn, gcall *call)
2657 expand_ifn_atomic_bit_test_and (call);
2660 /* Expand atomic bit test and set. */
2662 static void
2663 expand_ATOMIC_COMPARE_EXCHANGE (internal_fn, gcall *call)
2665 expand_ifn_atomic_compare_exchange (call);
2668 /* Expand LAUNDER to assignment, lhs = arg0. */
2670 static void
2671 expand_LAUNDER (internal_fn, gcall *call)
2673 tree lhs = gimple_call_lhs (call);
2675 if (!lhs)
2676 return;
2678 expand_assignment (lhs, gimple_call_arg (call, 0), false);
2681 /* Expand DIVMOD() using:
2682 a) optab handler for udivmod/sdivmod if it is available.
2683 b) If optab_handler doesn't exist, generate call to
2684 target-specific divmod libfunc. */
2686 static void
2687 expand_DIVMOD (internal_fn, gcall *call_stmt)
2689 tree lhs = gimple_call_lhs (call_stmt);
2690 tree arg0 = gimple_call_arg (call_stmt, 0);
2691 tree arg1 = gimple_call_arg (call_stmt, 1);
2693 gcc_assert (TREE_CODE (TREE_TYPE (lhs)) == COMPLEX_TYPE);
2694 tree type = TREE_TYPE (TREE_TYPE (lhs));
2695 machine_mode mode = TYPE_MODE (type);
2696 bool unsignedp = TYPE_UNSIGNED (type);
2697 optab tab = (unsignedp) ? udivmod_optab : sdivmod_optab;
2699 rtx op0 = expand_normal (arg0);
2700 rtx op1 = expand_normal (arg1);
2701 rtx target = expand_expr (lhs, NULL_RTX, VOIDmode, EXPAND_WRITE);
2703 rtx quotient, remainder, libfunc;
2705 /* Check if optab_handler exists for divmod_optab for given mode. */
2706 if (optab_handler (tab, mode) != CODE_FOR_nothing)
2708 quotient = gen_reg_rtx (mode);
2709 remainder = gen_reg_rtx (mode);
2710 expand_twoval_binop (tab, op0, op1, quotient, remainder, unsignedp);
2713 /* Generate call to divmod libfunc if it exists. */
2714 else if ((libfunc = optab_libfunc (tab, mode)) != NULL_RTX)
2715 targetm.expand_divmod_libfunc (libfunc, mode, op0, op1,
2716 &quotient, &remainder);
2718 else
2719 gcc_unreachable ();
2721 /* Wrap the return value (quotient, remainder) within COMPLEX_EXPR. */
2722 expand_expr (build2 (COMPLEX_EXPR, TREE_TYPE (lhs),
2723 make_tree (TREE_TYPE (arg0), quotient),
2724 make_tree (TREE_TYPE (arg1), remainder)),
2725 target, VOIDmode, EXPAND_NORMAL);
2728 /* Expand a NOP. */
2730 static void
2731 expand_NOP (internal_fn, gcall *)
2733 /* Nothing. But it shouldn't really prevail. */
2736 /* Expand a call to FN using the operands in STMT. FN has a single
2737 output operand and NARGS input operands. */
2739 static void
2740 expand_direct_optab_fn (internal_fn fn, gcall *stmt, direct_optab optab,
2741 unsigned int nargs)
2743 expand_operand *ops = XALLOCAVEC (expand_operand, nargs + 1);
2745 tree_pair types = direct_internal_fn_types (fn, stmt);
2746 insn_code icode = direct_optab_handler (optab, TYPE_MODE (types.first));
2748 tree lhs = gimple_call_lhs (stmt);
2749 tree lhs_type = TREE_TYPE (lhs);
2750 rtx lhs_rtx = expand_expr (lhs, NULL_RTX, VOIDmode, EXPAND_WRITE);
2752 /* Do not assign directly to a promoted subreg, since there is no
2753 guarantee that the instruction will leave the upper bits of the
2754 register in the state required by SUBREG_PROMOTED_SIGN. */
2755 rtx dest = lhs_rtx;
2756 if (GET_CODE (dest) == SUBREG && SUBREG_PROMOTED_VAR_P (dest))
2757 dest = NULL_RTX;
2759 create_output_operand (&ops[0], dest, insn_data[icode].operand[0].mode);
2761 for (unsigned int i = 0; i < nargs; ++i)
2763 tree rhs = gimple_call_arg (stmt, i);
2764 tree rhs_type = TREE_TYPE (rhs);
2765 rtx rhs_rtx = expand_normal (rhs);
2766 if (INTEGRAL_TYPE_P (rhs_type))
2767 create_convert_operand_from (&ops[i + 1], rhs_rtx,
2768 TYPE_MODE (rhs_type),
2769 TYPE_UNSIGNED (rhs_type));
2770 else
2771 create_input_operand (&ops[i + 1], rhs_rtx, TYPE_MODE (rhs_type));
2774 expand_insn (icode, nargs + 1, ops);
2775 if (!rtx_equal_p (lhs_rtx, ops[0].value))
2777 /* If the return value has an integral type, convert the instruction
2778 result to that type. This is useful for things that return an
2779 int regardless of the size of the input. If the instruction result
2780 is smaller than required, assume that it is signed.
2782 If the return value has a nonintegral type, its mode must match
2783 the instruction result. */
2784 if (GET_CODE (lhs_rtx) == SUBREG && SUBREG_PROMOTED_VAR_P (lhs_rtx))
2786 /* If this is a scalar in a register that is stored in a wider
2787 mode than the declared mode, compute the result into its
2788 declared mode and then convert to the wider mode. */
2789 gcc_checking_assert (INTEGRAL_TYPE_P (lhs_type));
2790 rtx tmp = convert_to_mode (GET_MODE (lhs_rtx), ops[0].value, 0);
2791 convert_move (SUBREG_REG (lhs_rtx), tmp,
2792 SUBREG_PROMOTED_SIGN (lhs_rtx));
2794 else if (GET_MODE (lhs_rtx) == GET_MODE (ops[0].value))
2795 emit_move_insn (lhs_rtx, ops[0].value);
2796 else
2798 gcc_checking_assert (INTEGRAL_TYPE_P (lhs_type));
2799 convert_move (lhs_rtx, ops[0].value, 0);
2804 /* Expanders for optabs that can use expand_direct_optab_fn. */
2806 #define expand_unary_optab_fn(FN, STMT, OPTAB) \
2807 expand_direct_optab_fn (FN, STMT, OPTAB, 1)
2809 #define expand_binary_optab_fn(FN, STMT, OPTAB) \
2810 expand_direct_optab_fn (FN, STMT, OPTAB, 2)
2812 /* RETURN_TYPE and ARGS are a return type and argument list that are
2813 in principle compatible with FN (which satisfies direct_internal_fn_p).
2814 Return the types that should be used to determine whether the
2815 target supports FN. */
2817 tree_pair
2818 direct_internal_fn_types (internal_fn fn, tree return_type, tree *args)
2820 const direct_internal_fn_info &info = direct_internal_fn (fn);
2821 tree type0 = (info.type0 < 0 ? return_type : TREE_TYPE (args[info.type0]));
2822 tree type1 = (info.type1 < 0 ? return_type : TREE_TYPE (args[info.type1]));
2823 return tree_pair (type0, type1);
2826 /* CALL is a call whose return type and arguments are in principle
2827 compatible with FN (which satisfies direct_internal_fn_p). Return the
2828 types that should be used to determine whether the target supports FN. */
2830 tree_pair
2831 direct_internal_fn_types (internal_fn fn, gcall *call)
2833 const direct_internal_fn_info &info = direct_internal_fn (fn);
2834 tree op0 = (info.type0 < 0
2835 ? gimple_call_lhs (call)
2836 : gimple_call_arg (call, info.type0));
2837 tree op1 = (info.type1 < 0
2838 ? gimple_call_lhs (call)
2839 : gimple_call_arg (call, info.type1));
2840 return tree_pair (TREE_TYPE (op0), TREE_TYPE (op1));
2843 /* Return true if OPTAB is supported for TYPES (whose modes should be
2844 the same) when the optimization type is OPT_TYPE. Used for simple
2845 direct optabs. */
2847 static bool
2848 direct_optab_supported_p (direct_optab optab, tree_pair types,
2849 optimization_type opt_type)
2851 machine_mode mode = TYPE_MODE (types.first);
2852 gcc_checking_assert (mode == TYPE_MODE (types.second));
2853 return direct_optab_handler (optab, mode, opt_type) != CODE_FOR_nothing;
2856 /* Return true if load/store lanes optab OPTAB is supported for
2857 array type TYPES.first when the optimization type is OPT_TYPE. */
2859 static bool
2860 multi_vector_optab_supported_p (convert_optab optab, tree_pair types,
2861 optimization_type opt_type)
2863 gcc_assert (TREE_CODE (types.first) == ARRAY_TYPE);
2864 machine_mode imode = TYPE_MODE (types.first);
2865 machine_mode vmode = TYPE_MODE (TREE_TYPE (types.first));
2866 return (convert_optab_handler (optab, imode, vmode, opt_type)
2867 != CODE_FOR_nothing);
2870 #define direct_unary_optab_supported_p direct_optab_supported_p
2871 #define direct_binary_optab_supported_p direct_optab_supported_p
2872 #define direct_mask_load_optab_supported_p direct_optab_supported_p
2873 #define direct_load_lanes_optab_supported_p multi_vector_optab_supported_p
2874 #define direct_mask_store_optab_supported_p direct_optab_supported_p
2875 #define direct_store_lanes_optab_supported_p multi_vector_optab_supported_p
2877 /* Return the optab used by internal function FN. */
2879 static optab
2880 direct_internal_fn_optab (internal_fn fn, tree_pair types)
2882 switch (fn)
2884 #define DEF_INTERNAL_FN(CODE, FLAGS, FNSPEC) \
2885 case IFN_##CODE: break;
2886 #define DEF_INTERNAL_OPTAB_FN(CODE, FLAGS, OPTAB, TYPE) \
2887 case IFN_##CODE: return OPTAB##_optab;
2888 #define DEF_INTERNAL_SIGNED_OPTAB_FN(CODE, FLAGS, SELECTOR, SIGNED_OPTAB, \
2889 UNSIGNED_OPTAB, TYPE) \
2890 case IFN_##CODE: return (TYPE_UNSIGNED (types.SELECTOR) \
2891 ? UNSIGNED_OPTAB ## _optab \
2892 : SIGNED_OPTAB ## _optab);
2893 #include "internal-fn.def"
2895 case IFN_LAST:
2896 break;
2898 gcc_unreachable ();
2901 /* Return true if FN is supported for the types in TYPES when the
2902 optimization type is OPT_TYPE. The types are those associated with
2903 the "type0" and "type1" fields of FN's direct_internal_fn_info
2904 structure. */
2906 bool
2907 direct_internal_fn_supported_p (internal_fn fn, tree_pair types,
2908 optimization_type opt_type)
2910 switch (fn)
2912 #define DEF_INTERNAL_FN(CODE, FLAGS, FNSPEC) \
2913 case IFN_##CODE: break;
2914 #define DEF_INTERNAL_OPTAB_FN(CODE, FLAGS, OPTAB, TYPE) \
2915 case IFN_##CODE: \
2916 return direct_##TYPE##_optab_supported_p (OPTAB##_optab, types, \
2917 opt_type);
2918 #define DEF_INTERNAL_SIGNED_OPTAB_FN(CODE, FLAGS, SELECTOR, SIGNED_OPTAB, \
2919 UNSIGNED_OPTAB, TYPE) \
2920 case IFN_##CODE: \
2922 optab which_optab = (TYPE_UNSIGNED (types.SELECTOR) \
2923 ? UNSIGNED_OPTAB ## _optab \
2924 : SIGNED_OPTAB ## _optab); \
2925 return direct_##TYPE##_optab_supported_p (which_optab, types, \
2926 opt_type); \
2928 #include "internal-fn.def"
2930 case IFN_LAST:
2931 break;
2933 gcc_unreachable ();
2936 /* Return true if FN is supported for type TYPE when the optimization
2937 type is OPT_TYPE. The caller knows that the "type0" and "type1"
2938 fields of FN's direct_internal_fn_info structure are the same. */
2940 bool
2941 direct_internal_fn_supported_p (internal_fn fn, tree type,
2942 optimization_type opt_type)
2944 const direct_internal_fn_info &info = direct_internal_fn (fn);
2945 gcc_checking_assert (info.type0 == info.type1);
2946 return direct_internal_fn_supported_p (fn, tree_pair (type, type), opt_type);
2949 /* Return true if IFN_SET_EDOM is supported. */
2951 bool
2952 set_edom_supported_p (void)
2954 #ifdef TARGET_EDOM
2955 return true;
2956 #else
2957 return false;
2958 #endif
2961 #define DEF_INTERNAL_OPTAB_FN(CODE, FLAGS, OPTAB, TYPE) \
2962 static void \
2963 expand_##CODE (internal_fn fn, gcall *stmt) \
2965 expand_##TYPE##_optab_fn (fn, stmt, OPTAB##_optab); \
2967 #define DEF_INTERNAL_SIGNED_OPTAB_FN(CODE, FLAGS, SELECTOR, SIGNED_OPTAB, \
2968 UNSIGNED_OPTAB, TYPE) \
2969 static void \
2970 expand_##CODE (internal_fn fn, gcall *stmt) \
2972 tree_pair types = direct_internal_fn_types (fn, stmt); \
2973 optab which_optab = direct_internal_fn_optab (fn, types); \
2974 expand_##TYPE##_optab_fn (fn, stmt, which_optab); \
2976 #include "internal-fn.def"
2978 /* Routines to expand each internal function, indexed by function number.
2979 Each routine has the prototype:
2981 expand_<NAME> (gcall *stmt)
2983 where STMT is the statement that performs the call. */
2984 static void (*const internal_fn_expanders[]) (internal_fn, gcall *) = {
2985 #define DEF_INTERNAL_FN(CODE, FLAGS, FNSPEC) expand_##CODE,
2986 #include "internal-fn.def"
2990 /* Expand STMT as though it were a call to internal function FN. */
2992 void
2993 expand_internal_call (internal_fn fn, gcall *stmt)
2995 internal_fn_expanders[fn] (fn, stmt);
2998 /* Expand STMT, which is a call to internal function FN. */
3000 void
3001 expand_internal_call (gcall *stmt)
3003 expand_internal_call (gimple_call_internal_fn (stmt), stmt);
3006 void
3007 expand_PHI (internal_fn, gcall *)
3009 gcc_unreachable ();