* config/riscv/riscv.c: Remove unnecessary includes. Reorder
[official-gcc.git] / gcc / internal-fn.c
blob1dc754124843f044ee22a5e8a829d5a30fb520d4
1 /* Internal functions.
2 Copyright (C) 2011-2017 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 "asan.h"
43 #include "ubsan.h"
44 #include "recog.h"
45 #include "builtins.h"
46 #include "optabs-tree.h"
48 /* The names of each internal function, indexed by function number. */
49 const char *const internal_fn_name_array[] = {
50 #define DEF_INTERNAL_FN(CODE, FLAGS, FNSPEC) #CODE,
51 #include "internal-fn.def"
52 "<invalid-fn>"
55 /* The ECF_* flags of each internal function, indexed by function number. */
56 const int internal_fn_flags_array[] = {
57 #define DEF_INTERNAL_FN(CODE, FLAGS, FNSPEC) FLAGS,
58 #include "internal-fn.def"
62 /* Fnspec of each internal function, indexed by function number. */
63 const_tree internal_fn_fnspec_array[IFN_LAST + 1];
65 void
66 init_internal_fns ()
68 #define DEF_INTERNAL_FN(CODE, FLAGS, FNSPEC) \
69 if (FNSPEC) internal_fn_fnspec_array[IFN_##CODE] = \
70 build_string ((int) sizeof (FNSPEC), FNSPEC ? FNSPEC : "");
71 #include "internal-fn.def"
72 internal_fn_fnspec_array[IFN_LAST] = 0;
75 /* Create static initializers for the information returned by
76 direct_internal_fn. */
77 #define not_direct { -2, -2, false }
78 #define mask_load_direct { -1, 2, false }
79 #define load_lanes_direct { -1, -1, false }
80 #define mask_store_direct { 3, 2, false }
81 #define store_lanes_direct { 0, 0, false }
82 #define unary_direct { 0, 0, true }
83 #define binary_direct { 0, 0, true }
85 const direct_internal_fn_info direct_internal_fn_array[IFN_LAST + 1] = {
86 #define DEF_INTERNAL_FN(CODE, FLAGS, FNSPEC) not_direct,
87 #define DEF_INTERNAL_OPTAB_FN(CODE, FLAGS, OPTAB, TYPE) TYPE##_direct,
88 #include "internal-fn.def"
89 not_direct
92 /* ARRAY_TYPE is an array of vector modes. Return the associated insn
93 for load-lanes-style optab OPTAB, or CODE_FOR_nothing if none. */
95 static enum insn_code
96 get_multi_vector_move (tree array_type, convert_optab optab)
98 machine_mode imode;
99 machine_mode vmode;
101 gcc_assert (TREE_CODE (array_type) == ARRAY_TYPE);
102 imode = TYPE_MODE (array_type);
103 vmode = TYPE_MODE (TREE_TYPE (array_type));
105 return convert_optab_handler (optab, imode, vmode);
108 /* Expand LOAD_LANES call STMT using optab OPTAB. */
110 static void
111 expand_load_lanes_optab_fn (internal_fn, gcall *stmt, convert_optab optab)
113 struct expand_operand ops[2];
114 tree type, lhs, rhs;
115 rtx target, mem;
117 lhs = gimple_call_lhs (stmt);
118 rhs = gimple_call_arg (stmt, 0);
119 type = TREE_TYPE (lhs);
121 target = expand_expr (lhs, NULL_RTX, VOIDmode, EXPAND_WRITE);
122 mem = expand_normal (rhs);
124 gcc_assert (MEM_P (mem));
125 PUT_MODE (mem, TYPE_MODE (type));
127 create_output_operand (&ops[0], target, TYPE_MODE (type));
128 create_fixed_operand (&ops[1], mem);
129 expand_insn (get_multi_vector_move (type, optab), 2, ops);
132 /* Expand STORE_LANES call STMT using optab OPTAB. */
134 static void
135 expand_store_lanes_optab_fn (internal_fn, gcall *stmt, convert_optab optab)
137 struct expand_operand ops[2];
138 tree type, lhs, rhs;
139 rtx target, reg;
141 lhs = gimple_call_lhs (stmt);
142 rhs = gimple_call_arg (stmt, 0);
143 type = TREE_TYPE (rhs);
145 target = expand_expr (lhs, NULL_RTX, VOIDmode, EXPAND_WRITE);
146 reg = expand_normal (rhs);
148 gcc_assert (MEM_P (target));
149 PUT_MODE (target, TYPE_MODE (type));
151 create_fixed_operand (&ops[0], target);
152 create_input_operand (&ops[1], reg, TYPE_MODE (type));
153 expand_insn (get_multi_vector_move (type, optab), 2, ops);
156 static void
157 expand_ANNOTATE (internal_fn, gcall *)
159 gcc_unreachable ();
162 /* This should get expanded in omp_device_lower pass. */
164 static void
165 expand_GOMP_USE_SIMT (internal_fn, gcall *)
167 gcc_unreachable ();
170 /* This should get expanded in omp_device_lower pass. */
172 static void
173 expand_GOMP_SIMT_ENTER (internal_fn, gcall *)
175 gcc_unreachable ();
178 /* Allocate per-lane storage and begin non-uniform execution region. */
180 static void
181 expand_GOMP_SIMT_ENTER_ALLOC (internal_fn, gcall *stmt)
183 rtx target;
184 tree lhs = gimple_call_lhs (stmt);
185 if (lhs)
186 target = expand_expr (lhs, NULL_RTX, VOIDmode, EXPAND_WRITE);
187 else
188 target = gen_reg_rtx (Pmode);
189 rtx size = expand_normal (gimple_call_arg (stmt, 0));
190 rtx align = expand_normal (gimple_call_arg (stmt, 1));
191 struct expand_operand ops[3];
192 create_output_operand (&ops[0], target, Pmode);
193 create_input_operand (&ops[1], size, Pmode);
194 create_input_operand (&ops[2], align, Pmode);
195 gcc_assert (targetm.have_omp_simt_enter ());
196 expand_insn (targetm.code_for_omp_simt_enter, 3, ops);
199 /* Deallocate per-lane storage and leave non-uniform execution region. */
201 static void
202 expand_GOMP_SIMT_EXIT (internal_fn, gcall *stmt)
204 gcc_checking_assert (!gimple_call_lhs (stmt));
205 rtx arg = expand_normal (gimple_call_arg (stmt, 0));
206 struct expand_operand ops[1];
207 create_input_operand (&ops[0], arg, Pmode);
208 gcc_assert (targetm.have_omp_simt_exit ());
209 expand_insn (targetm.code_for_omp_simt_exit, 1, ops);
212 /* Lane index on SIMT targets: thread index in the warp on NVPTX. On targets
213 without SIMT execution this should be expanded in omp_device_lower pass. */
215 static void
216 expand_GOMP_SIMT_LANE (internal_fn, gcall *stmt)
218 tree lhs = gimple_call_lhs (stmt);
219 if (!lhs)
220 return;
222 rtx target = expand_expr (lhs, NULL_RTX, VOIDmode, EXPAND_WRITE);
223 gcc_assert (targetm.have_omp_simt_lane ());
224 emit_insn (targetm.gen_omp_simt_lane (target));
227 /* This should get expanded in omp_device_lower pass. */
229 static void
230 expand_GOMP_SIMT_VF (internal_fn, gcall *)
232 gcc_unreachable ();
235 /* Lane index of the first SIMT lane that supplies a non-zero argument.
236 This is a SIMT counterpart to GOMP_SIMD_LAST_LANE, used to represent the
237 lane that executed the last iteration for handling OpenMP lastprivate. */
239 static void
240 expand_GOMP_SIMT_LAST_LANE (internal_fn, gcall *stmt)
242 tree lhs = gimple_call_lhs (stmt);
243 if (!lhs)
244 return;
246 rtx target = expand_expr (lhs, NULL_RTX, VOIDmode, EXPAND_WRITE);
247 rtx cond = expand_normal (gimple_call_arg (stmt, 0));
248 machine_mode mode = TYPE_MODE (TREE_TYPE (lhs));
249 struct expand_operand ops[2];
250 create_output_operand (&ops[0], target, mode);
251 create_input_operand (&ops[1], cond, mode);
252 gcc_assert (targetm.have_omp_simt_last_lane ());
253 expand_insn (targetm.code_for_omp_simt_last_lane, 2, ops);
256 /* Non-transparent predicate used in SIMT lowering of OpenMP "ordered". */
258 static void
259 expand_GOMP_SIMT_ORDERED_PRED (internal_fn, gcall *stmt)
261 tree lhs = gimple_call_lhs (stmt);
262 if (!lhs)
263 return;
265 rtx target = expand_expr (lhs, NULL_RTX, VOIDmode, EXPAND_WRITE);
266 rtx ctr = expand_normal (gimple_call_arg (stmt, 0));
267 machine_mode mode = TYPE_MODE (TREE_TYPE (lhs));
268 struct expand_operand ops[2];
269 create_output_operand (&ops[0], target, mode);
270 create_input_operand (&ops[1], ctr, mode);
271 gcc_assert (targetm.have_omp_simt_ordered ());
272 expand_insn (targetm.code_for_omp_simt_ordered, 2, ops);
275 /* "Or" boolean reduction across SIMT lanes: return non-zero in all lanes if
276 any lane supplies a non-zero argument. */
278 static void
279 expand_GOMP_SIMT_VOTE_ANY (internal_fn, gcall *stmt)
281 tree lhs = gimple_call_lhs (stmt);
282 if (!lhs)
283 return;
285 rtx target = expand_expr (lhs, NULL_RTX, VOIDmode, EXPAND_WRITE);
286 rtx cond = expand_normal (gimple_call_arg (stmt, 0));
287 machine_mode mode = TYPE_MODE (TREE_TYPE (lhs));
288 struct expand_operand ops[2];
289 create_output_operand (&ops[0], target, mode);
290 create_input_operand (&ops[1], cond, mode);
291 gcc_assert (targetm.have_omp_simt_vote_any ());
292 expand_insn (targetm.code_for_omp_simt_vote_any, 2, ops);
295 /* Exchange between SIMT lanes with a "butterfly" pattern: source lane index
296 is destination lane index XOR given offset. */
298 static void
299 expand_GOMP_SIMT_XCHG_BFLY (internal_fn, gcall *stmt)
301 tree lhs = gimple_call_lhs (stmt);
302 if (!lhs)
303 return;
305 rtx target = expand_expr (lhs, NULL_RTX, VOIDmode, EXPAND_WRITE);
306 rtx src = expand_normal (gimple_call_arg (stmt, 0));
307 rtx idx = expand_normal (gimple_call_arg (stmt, 1));
308 machine_mode mode = TYPE_MODE (TREE_TYPE (lhs));
309 struct expand_operand ops[3];
310 create_output_operand (&ops[0], target, mode);
311 create_input_operand (&ops[1], src, mode);
312 create_input_operand (&ops[2], idx, SImode);
313 gcc_assert (targetm.have_omp_simt_xchg_bfly ());
314 expand_insn (targetm.code_for_omp_simt_xchg_bfly, 3, ops);
317 /* Exchange between SIMT lanes according to given source lane index. */
319 static void
320 expand_GOMP_SIMT_XCHG_IDX (internal_fn, gcall *stmt)
322 tree lhs = gimple_call_lhs (stmt);
323 if (!lhs)
324 return;
326 rtx target = expand_expr (lhs, NULL_RTX, VOIDmode, EXPAND_WRITE);
327 rtx src = expand_normal (gimple_call_arg (stmt, 0));
328 rtx idx = expand_normal (gimple_call_arg (stmt, 1));
329 machine_mode mode = TYPE_MODE (TREE_TYPE (lhs));
330 struct expand_operand ops[3];
331 create_output_operand (&ops[0], target, mode);
332 create_input_operand (&ops[1], src, mode);
333 create_input_operand (&ops[2], idx, SImode);
334 gcc_assert (targetm.have_omp_simt_xchg_idx ());
335 expand_insn (targetm.code_for_omp_simt_xchg_idx, 3, ops);
338 /* This should get expanded in adjust_simduid_builtins. */
340 static void
341 expand_GOMP_SIMD_LANE (internal_fn, gcall *)
343 gcc_unreachable ();
346 /* This should get expanded in adjust_simduid_builtins. */
348 static void
349 expand_GOMP_SIMD_VF (internal_fn, gcall *)
351 gcc_unreachable ();
354 /* This should get expanded in adjust_simduid_builtins. */
356 static void
357 expand_GOMP_SIMD_LAST_LANE (internal_fn, gcall *)
359 gcc_unreachable ();
362 /* This should get expanded in adjust_simduid_builtins. */
364 static void
365 expand_GOMP_SIMD_ORDERED_START (internal_fn, gcall *)
367 gcc_unreachable ();
370 /* This should get expanded in adjust_simduid_builtins. */
372 static void
373 expand_GOMP_SIMD_ORDERED_END (internal_fn, gcall *)
375 gcc_unreachable ();
378 /* This should get expanded in the sanopt pass. */
380 static void
381 expand_UBSAN_NULL (internal_fn, gcall *)
383 gcc_unreachable ();
386 /* This should get expanded in the sanopt pass. */
388 static void
389 expand_UBSAN_BOUNDS (internal_fn, gcall *)
391 gcc_unreachable ();
394 /* This should get expanded in the sanopt pass. */
396 static void
397 expand_UBSAN_VPTR (internal_fn, gcall *)
399 gcc_unreachable ();
402 /* This should get expanded in the sanopt pass. */
404 static void
405 expand_UBSAN_OBJECT_SIZE (internal_fn, gcall *)
407 gcc_unreachable ();
410 /* This should get expanded in the sanopt pass. */
412 static void
413 expand_ASAN_CHECK (internal_fn, gcall *)
415 gcc_unreachable ();
418 /* This should get expanded in the sanopt pass. */
420 static void
421 expand_ASAN_MARK (internal_fn, gcall *)
423 gcc_unreachable ();
426 /* This should get expanded in the sanopt pass. */
428 static void
429 expand_ASAN_POISON (internal_fn, gcall *)
431 gcc_unreachable ();
434 /* This should get expanded in the sanopt pass. */
436 static void
437 expand_ASAN_POISON_USE (internal_fn, gcall *)
439 gcc_unreachable ();
442 /* This should get expanded in the tsan pass. */
444 static void
445 expand_TSAN_FUNC_EXIT (internal_fn, gcall *)
447 gcc_unreachable ();
450 /* This should get expanded in the lower pass. */
452 static void
453 expand_FALLTHROUGH (internal_fn, gcall *call)
455 error_at (gimple_location (call),
456 "invalid use of attribute %<fallthrough%>");
459 /* Return minimum precision needed to represent all values
460 of ARG in SIGNed integral type. */
462 static int
463 get_min_precision (tree arg, signop sign)
465 int prec = TYPE_PRECISION (TREE_TYPE (arg));
466 int cnt = 0;
467 signop orig_sign = sign;
468 if (TREE_CODE (arg) == INTEGER_CST)
470 int p;
471 if (TYPE_SIGN (TREE_TYPE (arg)) != sign)
473 widest_int w = wi::to_widest (arg);
474 w = wi::ext (w, prec, sign);
475 p = wi::min_precision (w, sign);
477 else
478 p = wi::min_precision (arg, sign);
479 return MIN (p, prec);
481 while (CONVERT_EXPR_P (arg)
482 && INTEGRAL_TYPE_P (TREE_TYPE (TREE_OPERAND (arg, 0)))
483 && TYPE_PRECISION (TREE_TYPE (TREE_OPERAND (arg, 0))) <= prec)
485 arg = TREE_OPERAND (arg, 0);
486 if (TYPE_PRECISION (TREE_TYPE (arg)) < prec)
488 if (TYPE_UNSIGNED (TREE_TYPE (arg)))
489 sign = UNSIGNED;
490 else if (sign == UNSIGNED && get_range_pos_neg (arg) != 1)
491 return prec + (orig_sign != sign);
492 prec = TYPE_PRECISION (TREE_TYPE (arg));
494 if (++cnt > 30)
495 return prec + (orig_sign != sign);
497 if (TREE_CODE (arg) != SSA_NAME)
498 return prec + (orig_sign != sign);
499 wide_int arg_min, arg_max;
500 while (get_range_info (arg, &arg_min, &arg_max) != VR_RANGE)
502 gimple *g = SSA_NAME_DEF_STMT (arg);
503 if (is_gimple_assign (g)
504 && CONVERT_EXPR_CODE_P (gimple_assign_rhs_code (g)))
506 tree t = gimple_assign_rhs1 (g);
507 if (INTEGRAL_TYPE_P (TREE_TYPE (t))
508 && TYPE_PRECISION (TREE_TYPE (t)) <= prec)
510 arg = t;
511 if (TYPE_PRECISION (TREE_TYPE (arg)) < prec)
513 if (TYPE_UNSIGNED (TREE_TYPE (arg)))
514 sign = UNSIGNED;
515 else if (sign == UNSIGNED && get_range_pos_neg (arg) != 1)
516 return prec + (orig_sign != sign);
517 prec = TYPE_PRECISION (TREE_TYPE (arg));
519 if (++cnt > 30)
520 return prec + (orig_sign != sign);
521 continue;
524 return prec + (orig_sign != sign);
526 if (sign == TYPE_SIGN (TREE_TYPE (arg)))
528 int p1 = wi::min_precision (arg_min, sign);
529 int p2 = wi::min_precision (arg_max, sign);
530 p1 = MAX (p1, p2);
531 prec = MIN (prec, p1);
533 else if (sign == UNSIGNED && !wi::neg_p (arg_min, SIGNED))
535 int p = wi::min_precision (arg_max, UNSIGNED);
536 prec = MIN (prec, p);
538 return prec + (orig_sign != sign);
541 /* Helper for expand_*_overflow. Set the __imag__ part to true
542 (1 except for signed:1 type, in which case store -1). */
544 static void
545 expand_arith_set_overflow (tree lhs, rtx target)
547 if (TYPE_PRECISION (TREE_TYPE (TREE_TYPE (lhs))) == 1
548 && !TYPE_UNSIGNED (TREE_TYPE (TREE_TYPE (lhs))))
549 write_complex_part (target, constm1_rtx, true);
550 else
551 write_complex_part (target, const1_rtx, true);
554 /* Helper for expand_*_overflow. Store RES into the __real__ part
555 of TARGET. If RES has larger MODE than __real__ part of TARGET,
556 set the __imag__ part to 1 if RES doesn't fit into it. Similarly
557 if LHS has smaller precision than its mode. */
559 static void
560 expand_arith_overflow_result_store (tree lhs, rtx target,
561 machine_mode mode, rtx res)
563 machine_mode tgtmode = GET_MODE_INNER (GET_MODE (target));
564 rtx lres = res;
565 if (tgtmode != mode)
567 rtx_code_label *done_label = gen_label_rtx ();
568 int uns = TYPE_UNSIGNED (TREE_TYPE (TREE_TYPE (lhs)));
569 lres = convert_modes (tgtmode, mode, res, uns);
570 gcc_assert (GET_MODE_PRECISION (tgtmode) < GET_MODE_PRECISION (mode));
571 do_compare_rtx_and_jump (res, convert_modes (mode, tgtmode, lres, uns),
572 EQ, true, mode, NULL_RTX, NULL, done_label,
573 profile_probability::very_likely ());
574 expand_arith_set_overflow (lhs, target);
575 emit_label (done_label);
577 int prec = TYPE_PRECISION (TREE_TYPE (TREE_TYPE (lhs)));
578 int tgtprec = GET_MODE_PRECISION (tgtmode);
579 if (prec < tgtprec)
581 rtx_code_label *done_label = gen_label_rtx ();
582 int uns = TYPE_UNSIGNED (TREE_TYPE (TREE_TYPE (lhs)));
583 res = lres;
584 if (uns)
586 rtx mask
587 = immed_wide_int_const (wi::shifted_mask (0, prec, false, tgtprec),
588 tgtmode);
589 lres = expand_simple_binop (tgtmode, AND, res, mask, NULL_RTX,
590 true, OPTAB_LIB_WIDEN);
592 else
594 lres = expand_shift (LSHIFT_EXPR, tgtmode, res, tgtprec - prec,
595 NULL_RTX, 1);
596 lres = expand_shift (RSHIFT_EXPR, tgtmode, lres, tgtprec - prec,
597 NULL_RTX, 0);
599 do_compare_rtx_and_jump (res, lres,
600 EQ, true, tgtmode, NULL_RTX, NULL, done_label,
601 profile_probability::very_likely ());
602 expand_arith_set_overflow (lhs, target);
603 emit_label (done_label);
605 write_complex_part (target, lres, false);
608 /* Helper for expand_*_overflow. Store RES into TARGET. */
610 static void
611 expand_ubsan_result_store (rtx target, rtx res)
613 if (GET_CODE (target) == SUBREG && SUBREG_PROMOTED_VAR_P (target))
614 /* If this is a scalar in a register that is stored in a wider mode
615 than the declared mode, compute the result into its declared mode
616 and then convert to the wider mode. Our value is the computed
617 expression. */
618 convert_move (SUBREG_REG (target), res, SUBREG_PROMOTED_SIGN (target));
619 else
620 emit_move_insn (target, res);
623 /* Add sub/add overflow checking to the statement STMT.
624 CODE says whether the operation is +, or -. */
626 static void
627 expand_addsub_overflow (location_t loc, tree_code code, tree lhs,
628 tree arg0, tree arg1, bool unsr_p, bool uns0_p,
629 bool uns1_p, bool is_ubsan, tree *datap)
631 rtx res, target = NULL_RTX;
632 tree fn;
633 rtx_code_label *done_label = gen_label_rtx ();
634 rtx_code_label *do_error = gen_label_rtx ();
635 do_pending_stack_adjust ();
636 rtx op0 = expand_normal (arg0);
637 rtx op1 = expand_normal (arg1);
638 machine_mode mode = TYPE_MODE (TREE_TYPE (arg0));
639 int prec = GET_MODE_PRECISION (mode);
640 rtx sgn = immed_wide_int_const (wi::min_value (prec, SIGNED), mode);
641 bool do_xor = false;
643 if (is_ubsan)
644 gcc_assert (!unsr_p && !uns0_p && !uns1_p);
646 if (lhs)
648 target = expand_expr (lhs, NULL_RTX, VOIDmode, EXPAND_WRITE);
649 if (!is_ubsan)
650 write_complex_part (target, const0_rtx, true);
653 /* We assume both operands and result have the same precision
654 here (GET_MODE_BITSIZE (mode)), S stands for signed type
655 with that precision, U for unsigned type with that precision,
656 sgn for unsigned most significant bit in that precision.
657 s1 is signed first operand, u1 is unsigned first operand,
658 s2 is signed second operand, u2 is unsigned second operand,
659 sr is signed result, ur is unsigned result and the following
660 rules say how to compute result (which is always result of
661 the operands as if both were unsigned, cast to the right
662 signedness) and how to compute whether operation overflowed.
664 s1 + s2 -> sr
665 res = (S) ((U) s1 + (U) s2)
666 ovf = s2 < 0 ? res > s1 : res < s1 (or jump on overflow)
667 s1 - s2 -> sr
668 res = (S) ((U) s1 - (U) s2)
669 ovf = s2 < 0 ? res < s1 : res > s2 (or jump on overflow)
670 u1 + u2 -> ur
671 res = u1 + u2
672 ovf = res < u1 (or jump on carry, but RTL opts will handle it)
673 u1 - u2 -> ur
674 res = u1 - u2
675 ovf = res > u1 (or jump on carry, but RTL opts will handle it)
676 s1 + u2 -> sr
677 res = (S) ((U) s1 + u2)
678 ovf = ((U) res ^ sgn) < u2
679 s1 + u2 -> ur
680 t1 = (S) (u2 ^ sgn)
681 t2 = s1 + t1
682 res = (U) t2 ^ sgn
683 ovf = t1 < 0 ? t2 > s1 : t2 < s1 (or jump on overflow)
684 s1 - u2 -> sr
685 res = (S) ((U) s1 - u2)
686 ovf = u2 > ((U) s1 ^ sgn)
687 s1 - u2 -> ur
688 res = (U) s1 - u2
689 ovf = s1 < 0 || u2 > (U) s1
690 u1 - s2 -> sr
691 res = u1 - (U) s2
692 ovf = u1 >= ((U) s2 ^ sgn)
693 u1 - s2 -> ur
694 t1 = u1 ^ sgn
695 t2 = t1 - (U) s2
696 res = t2 ^ sgn
697 ovf = s2 < 0 ? (S) t2 < (S) t1 : (S) t2 > (S) t1 (or jump on overflow)
698 s1 + s2 -> ur
699 res = (U) s1 + (U) s2
700 ovf = s2 < 0 ? (s1 | (S) res) < 0) : (s1 & (S) res) < 0)
701 u1 + u2 -> sr
702 res = (S) (u1 + u2)
703 ovf = (U) res < u2 || res < 0
704 u1 - u2 -> sr
705 res = (S) (u1 - u2)
706 ovf = u1 >= u2 ? res < 0 : res >= 0
707 s1 - s2 -> ur
708 res = (U) s1 - (U) s2
709 ovf = s2 >= 0 ? ((s1 | (S) res) < 0) : ((s1 & (S) res) < 0) */
711 if (code == PLUS_EXPR && uns0_p && !uns1_p)
713 /* PLUS_EXPR is commutative, if operand signedness differs,
714 canonicalize to the first operand being signed and second
715 unsigned to simplify following code. */
716 std::swap (op0, op1);
717 std::swap (arg0, arg1);
718 uns0_p = false;
719 uns1_p = true;
722 /* u1 +- u2 -> ur */
723 if (uns0_p && uns1_p && unsr_p)
725 insn_code icode = optab_handler (code == PLUS_EXPR ? uaddv4_optab
726 : usubv4_optab, mode);
727 if (icode != CODE_FOR_nothing)
729 struct expand_operand ops[4];
730 rtx_insn *last = get_last_insn ();
732 res = gen_reg_rtx (mode);
733 create_output_operand (&ops[0], res, mode);
734 create_input_operand (&ops[1], op0, mode);
735 create_input_operand (&ops[2], op1, mode);
736 create_fixed_operand (&ops[3], do_error);
737 if (maybe_expand_insn (icode, 4, ops))
739 last = get_last_insn ();
740 if (profile_status_for_fn (cfun) != PROFILE_ABSENT
741 && JUMP_P (last)
742 && any_condjump_p (last)
743 && !find_reg_note (last, REG_BR_PROB, 0))
744 add_int_reg_note (last, REG_BR_PROB, PROB_VERY_UNLIKELY);
745 emit_jump (done_label);
746 goto do_error_label;
749 delete_insns_since (last);
752 /* Compute the operation. On RTL level, the addition is always
753 unsigned. */
754 res = expand_binop (mode, code == PLUS_EXPR ? add_optab : sub_optab,
755 op0, op1, NULL_RTX, false, OPTAB_LIB_WIDEN);
756 rtx tem = op0;
757 /* For PLUS_EXPR, the operation is commutative, so we can pick
758 operand to compare against. For prec <= BITS_PER_WORD, I think
759 preferring REG operand is better over CONST_INT, because
760 the CONST_INT might enlarge the instruction or CSE would need
761 to figure out we'd already loaded it into a register before.
762 For prec > BITS_PER_WORD, I think CONST_INT might be more beneficial,
763 as then the multi-word comparison can be perhaps simplified. */
764 if (code == PLUS_EXPR
765 && (prec <= BITS_PER_WORD
766 ? (CONST_SCALAR_INT_P (op0) && REG_P (op1))
767 : CONST_SCALAR_INT_P (op1)))
768 tem = op1;
769 do_compare_rtx_and_jump (res, tem, code == PLUS_EXPR ? GEU : LEU,
770 true, mode, NULL_RTX, NULL, done_label,
771 profile_probability::very_likely ());
772 goto do_error_label;
775 /* s1 +- u2 -> sr */
776 if (!uns0_p && uns1_p && !unsr_p)
778 /* Compute the operation. On RTL level, the addition is always
779 unsigned. */
780 res = expand_binop (mode, code == PLUS_EXPR ? add_optab : sub_optab,
781 op0, op1, NULL_RTX, false, OPTAB_LIB_WIDEN);
782 rtx tem = expand_binop (mode, add_optab,
783 code == PLUS_EXPR ? res : op0, sgn,
784 NULL_RTX, false, OPTAB_LIB_WIDEN);
785 do_compare_rtx_and_jump (tem, op1, GEU, true, mode, NULL_RTX, NULL,
786 done_label, profile_probability::very_likely ());
787 goto do_error_label;
790 /* s1 + u2 -> ur */
791 if (code == PLUS_EXPR && !uns0_p && uns1_p && unsr_p)
793 op1 = expand_binop (mode, add_optab, op1, sgn, NULL_RTX, false,
794 OPTAB_LIB_WIDEN);
795 /* As we've changed op1, we have to avoid using the value range
796 for the original argument. */
797 arg1 = error_mark_node;
798 do_xor = true;
799 goto do_signed;
802 /* u1 - s2 -> ur */
803 if (code == MINUS_EXPR && uns0_p && !uns1_p && unsr_p)
805 op0 = expand_binop (mode, add_optab, op0, sgn, NULL_RTX, false,
806 OPTAB_LIB_WIDEN);
807 /* As we've changed op0, we have to avoid using the value range
808 for the original argument. */
809 arg0 = error_mark_node;
810 do_xor = true;
811 goto do_signed;
814 /* s1 - u2 -> ur */
815 if (code == MINUS_EXPR && !uns0_p && uns1_p && unsr_p)
817 /* Compute the operation. On RTL level, the addition is always
818 unsigned. */
819 res = expand_binop (mode, sub_optab, op0, op1, NULL_RTX, false,
820 OPTAB_LIB_WIDEN);
821 int pos_neg = get_range_pos_neg (arg0);
822 if (pos_neg == 2)
823 /* If ARG0 is known to be always negative, this is always overflow. */
824 emit_jump (do_error);
825 else if (pos_neg == 3)
826 /* If ARG0 is not known to be always positive, check at runtime. */
827 do_compare_rtx_and_jump (op0, const0_rtx, LT, false, mode, NULL_RTX,
828 NULL, do_error, profile_probability::very_unlikely ());
829 do_compare_rtx_and_jump (op1, op0, LEU, true, mode, NULL_RTX, NULL,
830 done_label, profile_probability::very_likely ());
831 goto do_error_label;
834 /* u1 - s2 -> sr */
835 if (code == MINUS_EXPR && uns0_p && !uns1_p && !unsr_p)
837 /* Compute the operation. On RTL level, the addition is always
838 unsigned. */
839 res = expand_binop (mode, sub_optab, op0, op1, NULL_RTX, false,
840 OPTAB_LIB_WIDEN);
841 rtx tem = expand_binop (mode, add_optab, op1, sgn, NULL_RTX, false,
842 OPTAB_LIB_WIDEN);
843 do_compare_rtx_and_jump (op0, tem, LTU, true, mode, NULL_RTX, NULL,
844 done_label, profile_probability::very_likely ());
845 goto do_error_label;
848 /* u1 + u2 -> sr */
849 if (code == PLUS_EXPR && uns0_p && uns1_p && !unsr_p)
851 /* Compute the operation. On RTL level, the addition is always
852 unsigned. */
853 res = expand_binop (mode, add_optab, op0, op1, NULL_RTX, false,
854 OPTAB_LIB_WIDEN);
855 do_compare_rtx_and_jump (res, const0_rtx, LT, false, mode, NULL_RTX,
856 NULL, do_error, profile_probability::very_unlikely ());
857 rtx tem = op1;
858 /* The operation is commutative, so we can pick operand to compare
859 against. For prec <= BITS_PER_WORD, I think preferring REG operand
860 is better over CONST_INT, because the CONST_INT might enlarge the
861 instruction or CSE would need to figure out we'd already loaded it
862 into a register before. For prec > BITS_PER_WORD, I think CONST_INT
863 might be more beneficial, as then the multi-word comparison can be
864 perhaps simplified. */
865 if (prec <= BITS_PER_WORD
866 ? (CONST_SCALAR_INT_P (op1) && REG_P (op0))
867 : CONST_SCALAR_INT_P (op0))
868 tem = op0;
869 do_compare_rtx_and_jump (res, tem, GEU, true, mode, NULL_RTX, NULL,
870 done_label, profile_probability::very_likely ());
871 goto do_error_label;
874 /* s1 +- s2 -> ur */
875 if (!uns0_p && !uns1_p && unsr_p)
877 /* Compute the operation. On RTL level, the addition is always
878 unsigned. */
879 res = expand_binop (mode, code == PLUS_EXPR ? add_optab : sub_optab,
880 op0, op1, NULL_RTX, false, OPTAB_LIB_WIDEN);
881 int pos_neg = get_range_pos_neg (arg1);
882 if (code == PLUS_EXPR)
884 int pos_neg0 = get_range_pos_neg (arg0);
885 if (pos_neg0 != 3 && pos_neg == 3)
887 std::swap (op0, op1);
888 pos_neg = pos_neg0;
891 rtx tem;
892 if (pos_neg != 3)
894 tem = expand_binop (mode, ((pos_neg == 1) ^ (code == MINUS_EXPR))
895 ? and_optab : ior_optab,
896 op0, res, NULL_RTX, false, OPTAB_LIB_WIDEN);
897 do_compare_rtx_and_jump (tem, const0_rtx, GE, false, mode, NULL,
898 NULL, done_label, profile_probability::very_likely ());
900 else
902 rtx_code_label *do_ior_label = gen_label_rtx ();
903 do_compare_rtx_and_jump (op1, const0_rtx,
904 code == MINUS_EXPR ? GE : LT, false, mode,
905 NULL_RTX, NULL, do_ior_label,
906 profile_probability::even ());
907 tem = expand_binop (mode, and_optab, op0, res, NULL_RTX, false,
908 OPTAB_LIB_WIDEN);
909 do_compare_rtx_and_jump (tem, const0_rtx, GE, false, mode, NULL_RTX,
910 NULL, done_label, profile_probability::very_likely ());
911 emit_jump (do_error);
912 emit_label (do_ior_label);
913 tem = expand_binop (mode, ior_optab, op0, res, NULL_RTX, false,
914 OPTAB_LIB_WIDEN);
915 do_compare_rtx_and_jump (tem, const0_rtx, GE, false, mode, NULL_RTX,
916 NULL, done_label, profile_probability::very_likely ());
918 goto do_error_label;
921 /* u1 - u2 -> sr */
922 if (code == MINUS_EXPR && uns0_p && uns1_p && !unsr_p)
924 /* Compute the operation. On RTL level, the addition is always
925 unsigned. */
926 res = expand_binop (mode, sub_optab, op0, op1, NULL_RTX, false,
927 OPTAB_LIB_WIDEN);
928 rtx_code_label *op0_geu_op1 = gen_label_rtx ();
929 do_compare_rtx_and_jump (op0, op1, GEU, true, mode, NULL_RTX, NULL,
930 op0_geu_op1, profile_probability::even ());
931 do_compare_rtx_and_jump (res, const0_rtx, LT, false, mode, NULL_RTX,
932 NULL, done_label, profile_probability::very_likely ());
933 emit_jump (do_error);
934 emit_label (op0_geu_op1);
935 do_compare_rtx_and_jump (res, const0_rtx, GE, false, mode, NULL_RTX,
936 NULL, done_label, profile_probability::very_likely ());
937 goto do_error_label;
940 gcc_assert (!uns0_p && !uns1_p && !unsr_p);
942 /* s1 +- s2 -> sr */
943 do_signed:
945 insn_code icode = optab_handler (code == PLUS_EXPR ? addv4_optab
946 : subv4_optab, mode);
947 if (icode != CODE_FOR_nothing)
949 struct expand_operand ops[4];
950 rtx_insn *last = get_last_insn ();
952 res = gen_reg_rtx (mode);
953 create_output_operand (&ops[0], res, mode);
954 create_input_operand (&ops[1], op0, mode);
955 create_input_operand (&ops[2], op1, mode);
956 create_fixed_operand (&ops[3], do_error);
957 if (maybe_expand_insn (icode, 4, ops))
959 last = get_last_insn ();
960 if (profile_status_for_fn (cfun) != PROFILE_ABSENT
961 && JUMP_P (last)
962 && any_condjump_p (last)
963 && !find_reg_note (last, REG_BR_PROB, 0))
964 add_int_reg_note (last, REG_BR_PROB, PROB_UNLIKELY);
965 emit_jump (done_label);
966 goto do_error_label;
969 delete_insns_since (last);
972 /* Compute the operation. On RTL level, the addition is always
973 unsigned. */
974 res = expand_binop (mode, code == PLUS_EXPR ? add_optab : sub_optab,
975 op0, op1, NULL_RTX, false, OPTAB_LIB_WIDEN);
977 /* If we can prove that one of the arguments (for MINUS_EXPR only
978 the second operand, as subtraction is not commutative) is always
979 non-negative or always negative, we can do just one comparison
980 and conditional jump. */
981 int pos_neg = get_range_pos_neg (arg1);
982 if (code == PLUS_EXPR)
984 int pos_neg0 = get_range_pos_neg (arg0);
985 if (pos_neg0 != 3 && pos_neg == 3)
987 std::swap (op0, op1);
988 pos_neg = pos_neg0;
992 /* Addition overflows if and only if the two operands have the same sign,
993 and the result has the opposite sign. Subtraction overflows if and
994 only if the two operands have opposite sign, and the subtrahend has
995 the same sign as the result. Here 0 is counted as positive. */
996 if (pos_neg == 3)
998 /* Compute op0 ^ op1 (operands have opposite sign). */
999 rtx op_xor = expand_binop (mode, xor_optab, op0, op1, NULL_RTX, false,
1000 OPTAB_LIB_WIDEN);
1002 /* Compute res ^ op1 (result and 2nd operand have opposite sign). */
1003 rtx res_xor = expand_binop (mode, xor_optab, res, op1, NULL_RTX, false,
1004 OPTAB_LIB_WIDEN);
1006 rtx tem;
1007 if (code == PLUS_EXPR)
1009 /* Compute (res ^ op1) & ~(op0 ^ op1). */
1010 tem = expand_unop (mode, one_cmpl_optab, op_xor, NULL_RTX, false);
1011 tem = expand_binop (mode, and_optab, res_xor, tem, NULL_RTX, false,
1012 OPTAB_LIB_WIDEN);
1014 else
1016 /* Compute (op0 ^ op1) & ~(res ^ op1). */
1017 tem = expand_unop (mode, one_cmpl_optab, res_xor, NULL_RTX, false);
1018 tem = expand_binop (mode, and_optab, op_xor, tem, NULL_RTX, false,
1019 OPTAB_LIB_WIDEN);
1022 /* No overflow if the result has bit sign cleared. */
1023 do_compare_rtx_and_jump (tem, const0_rtx, GE, false, mode, NULL_RTX,
1024 NULL, done_label, profile_probability::very_likely ());
1027 /* Compare the result of the operation with the first operand.
1028 No overflow for addition if second operand is positive and result
1029 is larger or second operand is negative and result is smaller.
1030 Likewise for subtraction with sign of second operand flipped. */
1031 else
1032 do_compare_rtx_and_jump (res, op0,
1033 (pos_neg == 1) ^ (code == MINUS_EXPR) ? GE : LE,
1034 false, mode, NULL_RTX, NULL, done_label,
1035 profile_probability::very_likely ());
1038 do_error_label:
1039 emit_label (do_error);
1040 if (is_ubsan)
1042 /* Expand the ubsan builtin call. */
1043 push_temp_slots ();
1044 fn = ubsan_build_overflow_builtin (code, loc, TREE_TYPE (arg0),
1045 arg0, arg1, datap);
1046 expand_normal (fn);
1047 pop_temp_slots ();
1048 do_pending_stack_adjust ();
1050 else if (lhs)
1051 expand_arith_set_overflow (lhs, target);
1053 /* We're done. */
1054 emit_label (done_label);
1056 if (lhs)
1058 if (is_ubsan)
1059 expand_ubsan_result_store (target, res);
1060 else
1062 if (do_xor)
1063 res = expand_binop (mode, add_optab, res, sgn, NULL_RTX, false,
1064 OPTAB_LIB_WIDEN);
1066 expand_arith_overflow_result_store (lhs, target, mode, res);
1071 /* Add negate overflow checking to the statement STMT. */
1073 static void
1074 expand_neg_overflow (location_t loc, tree lhs, tree arg1, bool is_ubsan,
1075 tree *datap)
1077 rtx res, op1;
1078 tree fn;
1079 rtx_code_label *done_label, *do_error;
1080 rtx target = NULL_RTX;
1082 done_label = gen_label_rtx ();
1083 do_error = gen_label_rtx ();
1085 do_pending_stack_adjust ();
1086 op1 = expand_normal (arg1);
1088 machine_mode mode = TYPE_MODE (TREE_TYPE (arg1));
1089 if (lhs)
1091 target = expand_expr (lhs, NULL_RTX, VOIDmode, EXPAND_WRITE);
1092 if (!is_ubsan)
1093 write_complex_part (target, const0_rtx, true);
1096 enum insn_code icode = optab_handler (negv3_optab, mode);
1097 if (icode != CODE_FOR_nothing)
1099 struct expand_operand ops[3];
1100 rtx_insn *last = get_last_insn ();
1102 res = gen_reg_rtx (mode);
1103 create_output_operand (&ops[0], res, mode);
1104 create_input_operand (&ops[1], op1, mode);
1105 create_fixed_operand (&ops[2], do_error);
1106 if (maybe_expand_insn (icode, 3, ops))
1108 last = get_last_insn ();
1109 if (profile_status_for_fn (cfun) != PROFILE_ABSENT
1110 && JUMP_P (last)
1111 && any_condjump_p (last)
1112 && !find_reg_note (last, REG_BR_PROB, 0))
1113 add_int_reg_note (last, REG_BR_PROB, PROB_VERY_UNLIKELY);
1114 emit_jump (done_label);
1116 else
1118 delete_insns_since (last);
1119 icode = CODE_FOR_nothing;
1123 if (icode == CODE_FOR_nothing)
1125 /* Compute the operation. On RTL level, the addition is always
1126 unsigned. */
1127 res = expand_unop (mode, neg_optab, op1, NULL_RTX, false);
1129 /* Compare the operand with the most negative value. */
1130 rtx minv = expand_normal (TYPE_MIN_VALUE (TREE_TYPE (arg1)));
1131 do_compare_rtx_and_jump (op1, minv, NE, true, mode, NULL_RTX, NULL,
1132 done_label, profile_probability::very_likely ());
1135 emit_label (do_error);
1136 if (is_ubsan)
1138 /* Expand the ubsan builtin call. */
1139 push_temp_slots ();
1140 fn = ubsan_build_overflow_builtin (NEGATE_EXPR, loc, TREE_TYPE (arg1),
1141 arg1, NULL_TREE, datap);
1142 expand_normal (fn);
1143 pop_temp_slots ();
1144 do_pending_stack_adjust ();
1146 else if (lhs)
1147 expand_arith_set_overflow (lhs, target);
1149 /* We're done. */
1150 emit_label (done_label);
1152 if (lhs)
1154 if (is_ubsan)
1155 expand_ubsan_result_store (target, res);
1156 else
1157 expand_arith_overflow_result_store (lhs, target, mode, res);
1161 /* Add mul overflow checking to the statement STMT. */
1163 static void
1164 expand_mul_overflow (location_t loc, tree lhs, tree arg0, tree arg1,
1165 bool unsr_p, bool uns0_p, bool uns1_p, bool is_ubsan,
1166 tree *datap)
1168 rtx res, op0, op1;
1169 tree fn, type;
1170 rtx_code_label *done_label, *do_error;
1171 rtx target = NULL_RTX;
1172 signop sign;
1173 enum insn_code icode;
1175 done_label = gen_label_rtx ();
1176 do_error = gen_label_rtx ();
1178 do_pending_stack_adjust ();
1179 op0 = expand_normal (arg0);
1180 op1 = expand_normal (arg1);
1182 machine_mode mode = TYPE_MODE (TREE_TYPE (arg0));
1183 bool uns = unsr_p;
1184 if (lhs)
1186 target = expand_expr (lhs, NULL_RTX, VOIDmode, EXPAND_WRITE);
1187 if (!is_ubsan)
1188 write_complex_part (target, const0_rtx, true);
1191 if (is_ubsan)
1192 gcc_assert (!unsr_p && !uns0_p && !uns1_p);
1194 /* We assume both operands and result have the same precision
1195 here (GET_MODE_BITSIZE (mode)), S stands for signed type
1196 with that precision, U for unsigned type with that precision,
1197 sgn for unsigned most significant bit in that precision.
1198 s1 is signed first operand, u1 is unsigned first operand,
1199 s2 is signed second operand, u2 is unsigned second operand,
1200 sr is signed result, ur is unsigned result and the following
1201 rules say how to compute result (which is always result of
1202 the operands as if both were unsigned, cast to the right
1203 signedness) and how to compute whether operation overflowed.
1204 main_ovf (false) stands for jump on signed multiplication
1205 overflow or the main algorithm with uns == false.
1206 main_ovf (true) stands for jump on unsigned multiplication
1207 overflow or the main algorithm with uns == true.
1209 s1 * s2 -> sr
1210 res = (S) ((U) s1 * (U) s2)
1211 ovf = main_ovf (false)
1212 u1 * u2 -> ur
1213 res = u1 * u2
1214 ovf = main_ovf (true)
1215 s1 * u2 -> ur
1216 res = (U) s1 * u2
1217 ovf = (s1 < 0 && u2) || main_ovf (true)
1218 u1 * u2 -> sr
1219 res = (S) (u1 * u2)
1220 ovf = res < 0 || main_ovf (true)
1221 s1 * u2 -> sr
1222 res = (S) ((U) s1 * u2)
1223 ovf = (S) u2 >= 0 ? main_ovf (false)
1224 : (s1 != 0 && (s1 != -1 || u2 != (U) res))
1225 s1 * s2 -> ur
1226 t1 = (s1 & s2) < 0 ? (-(U) s1) : ((U) s1)
1227 t2 = (s1 & s2) < 0 ? (-(U) s2) : ((U) s2)
1228 res = t1 * t2
1229 ovf = (s1 ^ s2) < 0 ? (s1 && s2) : main_ovf (true) */
1231 if (uns0_p && !uns1_p)
1233 /* Multiplication is commutative, if operand signedness differs,
1234 canonicalize to the first operand being signed and second
1235 unsigned to simplify following code. */
1236 std::swap (op0, op1);
1237 std::swap (arg0, arg1);
1238 uns0_p = false;
1239 uns1_p = true;
1242 int pos_neg0 = get_range_pos_neg (arg0);
1243 int pos_neg1 = get_range_pos_neg (arg1);
1245 /* s1 * u2 -> ur */
1246 if (!uns0_p && uns1_p && unsr_p)
1248 switch (pos_neg0)
1250 case 1:
1251 /* If s1 is non-negative, just perform normal u1 * u2 -> ur. */
1252 goto do_main;
1253 case 2:
1254 /* If s1 is negative, avoid the main code, just multiply and
1255 signal overflow if op1 is not 0. */
1256 struct separate_ops ops;
1257 ops.code = MULT_EXPR;
1258 ops.type = TREE_TYPE (arg1);
1259 ops.op0 = make_tree (ops.type, op0);
1260 ops.op1 = make_tree (ops.type, op1);
1261 ops.op2 = NULL_TREE;
1262 ops.location = loc;
1263 res = expand_expr_real_2 (&ops, NULL_RTX, mode, EXPAND_NORMAL);
1264 do_compare_rtx_and_jump (op1, const0_rtx, EQ, true, mode, NULL_RTX,
1265 NULL, done_label, profile_probability::very_likely ());
1266 goto do_error_label;
1267 case 3:
1268 rtx_code_label *do_main_label;
1269 do_main_label = gen_label_rtx ();
1270 do_compare_rtx_and_jump (op0, const0_rtx, GE, false, mode, NULL_RTX,
1271 NULL, do_main_label, profile_probability::very_likely ());
1272 do_compare_rtx_and_jump (op1, const0_rtx, EQ, true, mode, NULL_RTX,
1273 NULL, do_main_label, profile_probability::very_likely ());
1274 expand_arith_set_overflow (lhs, target);
1275 emit_label (do_main_label);
1276 goto do_main;
1277 default:
1278 gcc_unreachable ();
1282 /* u1 * u2 -> sr */
1283 if (uns0_p && uns1_p && !unsr_p)
1285 uns = true;
1286 /* Rest of handling of this case after res is computed. */
1287 goto do_main;
1290 /* s1 * u2 -> sr */
1291 if (!uns0_p && uns1_p && !unsr_p)
1293 switch (pos_neg1)
1295 case 1:
1296 goto do_main;
1297 case 2:
1298 /* If (S) u2 is negative (i.e. u2 is larger than maximum of S,
1299 avoid the main code, just multiply and signal overflow
1300 unless 0 * u2 or -1 * ((U) Smin). */
1301 struct separate_ops ops;
1302 ops.code = MULT_EXPR;
1303 ops.type = TREE_TYPE (arg1);
1304 ops.op0 = make_tree (ops.type, op0);
1305 ops.op1 = make_tree (ops.type, op1);
1306 ops.op2 = NULL_TREE;
1307 ops.location = loc;
1308 res = expand_expr_real_2 (&ops, NULL_RTX, mode, EXPAND_NORMAL);
1309 do_compare_rtx_and_jump (op0, const0_rtx, EQ, true, mode, NULL_RTX,
1310 NULL, done_label, profile_probability::very_likely ());
1311 do_compare_rtx_and_jump (op0, constm1_rtx, NE, true, mode, NULL_RTX,
1312 NULL, do_error, profile_probability::very_unlikely ());
1313 int prec;
1314 prec = GET_MODE_PRECISION (mode);
1315 rtx sgn;
1316 sgn = immed_wide_int_const (wi::min_value (prec, SIGNED), mode);
1317 do_compare_rtx_and_jump (op1, sgn, EQ, true, mode, NULL_RTX,
1318 NULL, done_label, profile_probability::very_likely ());
1319 goto do_error_label;
1320 case 3:
1321 /* Rest of handling of this case after res is computed. */
1322 goto do_main;
1323 default:
1324 gcc_unreachable ();
1328 /* s1 * s2 -> ur */
1329 if (!uns0_p && !uns1_p && unsr_p)
1331 rtx tem, tem2;
1332 switch (pos_neg0 | pos_neg1)
1334 case 1: /* Both operands known to be non-negative. */
1335 goto do_main;
1336 case 2: /* Both operands known to be negative. */
1337 op0 = expand_unop (mode, neg_optab, op0, NULL_RTX, false);
1338 op1 = expand_unop (mode, neg_optab, op1, NULL_RTX, false);
1339 /* Avoid looking at arg0/arg1 ranges, as we've changed
1340 the arguments. */
1341 arg0 = error_mark_node;
1342 arg1 = error_mark_node;
1343 goto do_main;
1344 case 3:
1345 if ((pos_neg0 ^ pos_neg1) == 3)
1347 /* If one operand is known to be negative and the other
1348 non-negative, this overflows always, unless the non-negative
1349 one is 0. Just do normal multiply and set overflow
1350 unless one of the operands is 0. */
1351 struct separate_ops ops;
1352 ops.code = MULT_EXPR;
1353 ops.type
1354 = build_nonstandard_integer_type (GET_MODE_PRECISION (mode),
1356 ops.op0 = make_tree (ops.type, op0);
1357 ops.op1 = make_tree (ops.type, op1);
1358 ops.op2 = NULL_TREE;
1359 ops.location = loc;
1360 res = expand_expr_real_2 (&ops, NULL_RTX, mode, EXPAND_NORMAL);
1361 tem = expand_binop (mode, and_optab, op0, op1, NULL_RTX, false,
1362 OPTAB_LIB_WIDEN);
1363 do_compare_rtx_and_jump (tem, const0_rtx, EQ, true, mode,
1364 NULL_RTX, NULL, done_label,
1365 profile_probability::very_likely ());
1366 goto do_error_label;
1368 /* The general case, do all the needed comparisons at runtime. */
1369 rtx_code_label *do_main_label, *after_negate_label;
1370 rtx rop0, rop1;
1371 rop0 = gen_reg_rtx (mode);
1372 rop1 = gen_reg_rtx (mode);
1373 emit_move_insn (rop0, op0);
1374 emit_move_insn (rop1, op1);
1375 op0 = rop0;
1376 op1 = rop1;
1377 do_main_label = gen_label_rtx ();
1378 after_negate_label = gen_label_rtx ();
1379 tem = expand_binop (mode, and_optab, op0, op1, NULL_RTX, false,
1380 OPTAB_LIB_WIDEN);
1381 do_compare_rtx_and_jump (tem, const0_rtx, GE, false, mode, NULL_RTX,
1382 NULL, after_negate_label, profile_probability::very_likely ());
1383 /* Both arguments negative here, negate them and continue with
1384 normal unsigned overflow checking multiplication. */
1385 emit_move_insn (op0, expand_unop (mode, neg_optab, op0,
1386 NULL_RTX, false));
1387 emit_move_insn (op1, expand_unop (mode, neg_optab, op1,
1388 NULL_RTX, false));
1389 /* Avoid looking at arg0/arg1 ranges, as we might have changed
1390 the arguments. */
1391 arg0 = error_mark_node;
1392 arg1 = error_mark_node;
1393 emit_jump (do_main_label);
1394 emit_label (after_negate_label);
1395 tem2 = expand_binop (mode, xor_optab, op0, op1, NULL_RTX, false,
1396 OPTAB_LIB_WIDEN);
1397 do_compare_rtx_and_jump (tem2, const0_rtx, GE, false, mode, NULL_RTX,
1398 NULL, do_main_label, profile_probability::very_likely ());
1399 /* One argument is negative here, the other positive. This
1400 overflows always, unless one of the arguments is 0. But
1401 if e.g. s2 is 0, (U) s1 * 0 doesn't overflow, whatever s1
1402 is, thus we can keep do_main code oring in overflow as is. */
1403 do_compare_rtx_and_jump (tem, const0_rtx, EQ, true, mode, NULL_RTX,
1404 NULL, do_main_label, profile_probability::very_likely ());
1405 expand_arith_set_overflow (lhs, target);
1406 emit_label (do_main_label);
1407 goto do_main;
1408 default:
1409 gcc_unreachable ();
1413 do_main:
1414 type = build_nonstandard_integer_type (GET_MODE_PRECISION (mode), uns);
1415 sign = uns ? UNSIGNED : SIGNED;
1416 icode = optab_handler (uns ? umulv4_optab : mulv4_optab, mode);
1417 if (icode != CODE_FOR_nothing)
1419 struct expand_operand ops[4];
1420 rtx_insn *last = get_last_insn ();
1422 res = gen_reg_rtx (mode);
1423 create_output_operand (&ops[0], res, mode);
1424 create_input_operand (&ops[1], op0, mode);
1425 create_input_operand (&ops[2], op1, mode);
1426 create_fixed_operand (&ops[3], do_error);
1427 if (maybe_expand_insn (icode, 4, ops))
1429 last = get_last_insn ();
1430 if (profile_status_for_fn (cfun) != PROFILE_ABSENT
1431 && JUMP_P (last)
1432 && any_condjump_p (last)
1433 && !find_reg_note (last, REG_BR_PROB, 0))
1434 add_int_reg_note (last, REG_BR_PROB, PROB_VERY_UNLIKELY);
1435 emit_jump (done_label);
1437 else
1439 delete_insns_since (last);
1440 icode = CODE_FOR_nothing;
1444 if (icode == CODE_FOR_nothing)
1446 struct separate_ops ops;
1447 int prec = GET_MODE_PRECISION (mode);
1448 machine_mode hmode = mode_for_size (prec / 2, MODE_INT, 1);
1449 ops.op0 = make_tree (type, op0);
1450 ops.op1 = make_tree (type, op1);
1451 ops.op2 = NULL_TREE;
1452 ops.location = loc;
1453 if (GET_MODE_2XWIDER_MODE (mode) != VOIDmode
1454 && targetm.scalar_mode_supported_p (GET_MODE_2XWIDER_MODE (mode)))
1456 machine_mode wmode = GET_MODE_2XWIDER_MODE (mode);
1457 ops.code = WIDEN_MULT_EXPR;
1458 ops.type
1459 = build_nonstandard_integer_type (GET_MODE_PRECISION (wmode), uns);
1461 res = expand_expr_real_2 (&ops, NULL_RTX, wmode, EXPAND_NORMAL);
1462 rtx hipart = expand_shift (RSHIFT_EXPR, wmode, res, prec,
1463 NULL_RTX, uns);
1464 hipart = convert_modes (mode, wmode, hipart, uns);
1465 res = convert_modes (mode, wmode, res, uns);
1466 if (uns)
1467 /* For the unsigned multiplication, there was overflow if
1468 HIPART is non-zero. */
1469 do_compare_rtx_and_jump (hipart, const0_rtx, EQ, true, mode,
1470 NULL_RTX, NULL, done_label,
1471 profile_probability::very_likely ());
1472 else
1474 rtx signbit = expand_shift (RSHIFT_EXPR, mode, res, prec - 1,
1475 NULL_RTX, 0);
1476 /* RES is low half of the double width result, HIPART
1477 the high half. There was overflow if
1478 HIPART is different from RES < 0 ? -1 : 0. */
1479 do_compare_rtx_and_jump (signbit, hipart, EQ, true, mode,
1480 NULL_RTX, NULL, done_label,
1481 profile_probability::very_likely ());
1484 else if (hmode != BLKmode && 2 * GET_MODE_PRECISION (hmode) == prec)
1486 rtx_code_label *large_op0 = gen_label_rtx ();
1487 rtx_code_label *small_op0_large_op1 = gen_label_rtx ();
1488 rtx_code_label *one_small_one_large = gen_label_rtx ();
1489 rtx_code_label *both_ops_large = gen_label_rtx ();
1490 rtx_code_label *after_hipart_neg = uns ? NULL : gen_label_rtx ();
1491 rtx_code_label *after_lopart_neg = uns ? NULL : gen_label_rtx ();
1492 rtx_code_label *do_overflow = gen_label_rtx ();
1493 rtx_code_label *hipart_different = uns ? NULL : gen_label_rtx ();
1495 unsigned int hprec = GET_MODE_PRECISION (hmode);
1496 rtx hipart0 = expand_shift (RSHIFT_EXPR, mode, op0, hprec,
1497 NULL_RTX, uns);
1498 hipart0 = convert_modes (hmode, mode, hipart0, uns);
1499 rtx lopart0 = convert_modes (hmode, mode, op0, uns);
1500 rtx signbit0 = const0_rtx;
1501 if (!uns)
1502 signbit0 = expand_shift (RSHIFT_EXPR, hmode, lopart0, hprec - 1,
1503 NULL_RTX, 0);
1504 rtx hipart1 = expand_shift (RSHIFT_EXPR, mode, op1, hprec,
1505 NULL_RTX, uns);
1506 hipart1 = convert_modes (hmode, mode, hipart1, uns);
1507 rtx lopart1 = convert_modes (hmode, mode, op1, uns);
1508 rtx signbit1 = const0_rtx;
1509 if (!uns)
1510 signbit1 = expand_shift (RSHIFT_EXPR, hmode, lopart1, hprec - 1,
1511 NULL_RTX, 0);
1513 res = gen_reg_rtx (mode);
1515 /* True if op0 resp. op1 are known to be in the range of
1516 halfstype. */
1517 bool op0_small_p = false;
1518 bool op1_small_p = false;
1519 /* True if op0 resp. op1 are known to have all zeros or all ones
1520 in the upper half of bits, but are not known to be
1521 op{0,1}_small_p. */
1522 bool op0_medium_p = false;
1523 bool op1_medium_p = false;
1524 /* -1 if op{0,1} is known to be negative, 0 if it is known to be
1525 nonnegative, 1 if unknown. */
1526 int op0_sign = 1;
1527 int op1_sign = 1;
1529 if (pos_neg0 == 1)
1530 op0_sign = 0;
1531 else if (pos_neg0 == 2)
1532 op0_sign = -1;
1533 if (pos_neg1 == 1)
1534 op1_sign = 0;
1535 else if (pos_neg1 == 2)
1536 op1_sign = -1;
1538 unsigned int mprec0 = prec;
1539 if (arg0 != error_mark_node)
1540 mprec0 = get_min_precision (arg0, sign);
1541 if (mprec0 <= hprec)
1542 op0_small_p = true;
1543 else if (!uns && mprec0 <= hprec + 1)
1544 op0_medium_p = true;
1545 unsigned int mprec1 = prec;
1546 if (arg1 != error_mark_node)
1547 mprec1 = get_min_precision (arg1, sign);
1548 if (mprec1 <= hprec)
1549 op1_small_p = true;
1550 else if (!uns && mprec1 <= hprec + 1)
1551 op1_medium_p = true;
1553 int smaller_sign = 1;
1554 int larger_sign = 1;
1555 if (op0_small_p)
1557 smaller_sign = op0_sign;
1558 larger_sign = op1_sign;
1560 else if (op1_small_p)
1562 smaller_sign = op1_sign;
1563 larger_sign = op0_sign;
1565 else if (op0_sign == op1_sign)
1567 smaller_sign = op0_sign;
1568 larger_sign = op0_sign;
1571 if (!op0_small_p)
1572 do_compare_rtx_and_jump (signbit0, hipart0, NE, true, hmode,
1573 NULL_RTX, NULL, large_op0,
1574 profile_probability::unlikely ());
1576 if (!op1_small_p)
1577 do_compare_rtx_and_jump (signbit1, hipart1, NE, true, hmode,
1578 NULL_RTX, NULL, small_op0_large_op1,
1579 profile_probability::unlikely ());
1581 /* If both op0 and op1 are sign (!uns) or zero (uns) extended from
1582 hmode to mode, the multiplication will never overflow. We can
1583 do just one hmode x hmode => mode widening multiplication. */
1584 rtx lopart0s = lopart0, lopart1s = lopart1;
1585 if (GET_CODE (lopart0) == SUBREG)
1587 lopart0s = shallow_copy_rtx (lopart0);
1588 SUBREG_PROMOTED_VAR_P (lopart0s) = 1;
1589 SUBREG_PROMOTED_SET (lopart0s, uns ? SRP_UNSIGNED : SRP_SIGNED);
1591 if (GET_CODE (lopart1) == SUBREG)
1593 lopart1s = shallow_copy_rtx (lopart1);
1594 SUBREG_PROMOTED_VAR_P (lopart1s) = 1;
1595 SUBREG_PROMOTED_SET (lopart1s, uns ? SRP_UNSIGNED : SRP_SIGNED);
1597 tree halfstype = build_nonstandard_integer_type (hprec, uns);
1598 ops.op0 = make_tree (halfstype, lopart0s);
1599 ops.op1 = make_tree (halfstype, lopart1s);
1600 ops.code = WIDEN_MULT_EXPR;
1601 ops.type = type;
1602 rtx thisres
1603 = expand_expr_real_2 (&ops, NULL_RTX, mode, EXPAND_NORMAL);
1604 emit_move_insn (res, thisres);
1605 emit_jump (done_label);
1607 emit_label (small_op0_large_op1);
1609 /* If op0 is sign (!uns) or zero (uns) extended from hmode to mode,
1610 but op1 is not, just swap the arguments and handle it as op1
1611 sign/zero extended, op0 not. */
1612 rtx larger = gen_reg_rtx (mode);
1613 rtx hipart = gen_reg_rtx (hmode);
1614 rtx lopart = gen_reg_rtx (hmode);
1615 emit_move_insn (larger, op1);
1616 emit_move_insn (hipart, hipart1);
1617 emit_move_insn (lopart, lopart0);
1618 emit_jump (one_small_one_large);
1620 emit_label (large_op0);
1622 if (!op1_small_p)
1623 do_compare_rtx_and_jump (signbit1, hipart1, NE, true, hmode,
1624 NULL_RTX, NULL, both_ops_large,
1625 profile_probability::unlikely ());
1627 /* If op1 is sign (!uns) or zero (uns) extended from hmode to mode,
1628 but op0 is not, prepare larger, hipart and lopart pseudos and
1629 handle it together with small_op0_large_op1. */
1630 emit_move_insn (larger, op0);
1631 emit_move_insn (hipart, hipart0);
1632 emit_move_insn (lopart, lopart1);
1634 emit_label (one_small_one_large);
1636 /* lopart is the low part of the operand that is sign extended
1637 to mode, larger is the other operand, hipart is the
1638 high part of larger and lopart0 and lopart1 are the low parts
1639 of both operands.
1640 We perform lopart0 * lopart1 and lopart * hipart widening
1641 multiplications. */
1642 tree halfutype = build_nonstandard_integer_type (hprec, 1);
1643 ops.op0 = make_tree (halfutype, lopart0);
1644 ops.op1 = make_tree (halfutype, lopart1);
1645 rtx lo0xlo1
1646 = expand_expr_real_2 (&ops, NULL_RTX, mode, EXPAND_NORMAL);
1648 ops.op0 = make_tree (halfutype, lopart);
1649 ops.op1 = make_tree (halfutype, hipart);
1650 rtx loxhi = gen_reg_rtx (mode);
1651 rtx tem = expand_expr_real_2 (&ops, NULL_RTX, mode, EXPAND_NORMAL);
1652 emit_move_insn (loxhi, tem);
1654 if (!uns)
1656 /* if (hipart < 0) loxhi -= lopart << (bitsize / 2); */
1657 if (larger_sign == 0)
1658 emit_jump (after_hipart_neg);
1659 else if (larger_sign != -1)
1660 do_compare_rtx_and_jump (hipart, const0_rtx, GE, false, hmode,
1661 NULL_RTX, NULL, after_hipart_neg,
1662 profile_probability::even ());
1664 tem = convert_modes (mode, hmode, lopart, 1);
1665 tem = expand_shift (LSHIFT_EXPR, mode, tem, hprec, NULL_RTX, 1);
1666 tem = expand_simple_binop (mode, MINUS, loxhi, tem, NULL_RTX,
1667 1, OPTAB_DIRECT);
1668 emit_move_insn (loxhi, tem);
1670 emit_label (after_hipart_neg);
1672 /* if (lopart < 0) loxhi -= larger; */
1673 if (smaller_sign == 0)
1674 emit_jump (after_lopart_neg);
1675 else if (smaller_sign != -1)
1676 do_compare_rtx_and_jump (lopart, const0_rtx, GE, false, hmode,
1677 NULL_RTX, NULL, after_lopart_neg,
1678 profile_probability::even ());
1680 tem = expand_simple_binop (mode, MINUS, loxhi, larger, NULL_RTX,
1681 1, OPTAB_DIRECT);
1682 emit_move_insn (loxhi, tem);
1684 emit_label (after_lopart_neg);
1687 /* loxhi += (uns) lo0xlo1 >> (bitsize / 2); */
1688 tem = expand_shift (RSHIFT_EXPR, mode, lo0xlo1, hprec, NULL_RTX, 1);
1689 tem = expand_simple_binop (mode, PLUS, loxhi, tem, NULL_RTX,
1690 1, OPTAB_DIRECT);
1691 emit_move_insn (loxhi, tem);
1693 /* if (loxhi >> (bitsize / 2)
1694 == (hmode) loxhi >> (bitsize / 2 - 1)) (if !uns)
1695 if (loxhi >> (bitsize / 2) == 0 (if uns). */
1696 rtx hipartloxhi = expand_shift (RSHIFT_EXPR, mode, loxhi, hprec,
1697 NULL_RTX, 0);
1698 hipartloxhi = convert_modes (hmode, mode, hipartloxhi, 0);
1699 rtx signbitloxhi = const0_rtx;
1700 if (!uns)
1701 signbitloxhi = expand_shift (RSHIFT_EXPR, hmode,
1702 convert_modes (hmode, mode,
1703 loxhi, 0),
1704 hprec - 1, NULL_RTX, 0);
1706 do_compare_rtx_and_jump (signbitloxhi, hipartloxhi, NE, true, hmode,
1707 NULL_RTX, NULL, do_overflow,
1708 profile_probability::very_unlikely ());
1710 /* res = (loxhi << (bitsize / 2)) | (hmode) lo0xlo1; */
1711 rtx loxhishifted = expand_shift (LSHIFT_EXPR, mode, loxhi, hprec,
1712 NULL_RTX, 1);
1713 tem = convert_modes (mode, hmode,
1714 convert_modes (hmode, mode, lo0xlo1, 1), 1);
1716 tem = expand_simple_binop (mode, IOR, loxhishifted, tem, res,
1717 1, OPTAB_DIRECT);
1718 if (tem != res)
1719 emit_move_insn (res, tem);
1720 emit_jump (done_label);
1722 emit_label (both_ops_large);
1724 /* If both operands are large (not sign (!uns) or zero (uns)
1725 extended from hmode), then perform the full multiplication
1726 which will be the result of the operation.
1727 The only cases which don't overflow are for signed multiplication
1728 some cases where both hipart0 and highpart1 are 0 or -1.
1729 For unsigned multiplication when high parts are both non-zero
1730 this overflows always. */
1731 ops.code = MULT_EXPR;
1732 ops.op0 = make_tree (type, op0);
1733 ops.op1 = make_tree (type, op1);
1734 tem = expand_expr_real_2 (&ops, NULL_RTX, mode, EXPAND_NORMAL);
1735 emit_move_insn (res, tem);
1737 if (!uns)
1739 if (!op0_medium_p)
1741 tem = expand_simple_binop (hmode, PLUS, hipart0, const1_rtx,
1742 NULL_RTX, 1, OPTAB_DIRECT);
1743 do_compare_rtx_and_jump (tem, const1_rtx, GTU, true, hmode,
1744 NULL_RTX, NULL, do_error,
1745 profile_probability::very_unlikely ());
1748 if (!op1_medium_p)
1750 tem = expand_simple_binop (hmode, PLUS, hipart1, const1_rtx,
1751 NULL_RTX, 1, OPTAB_DIRECT);
1752 do_compare_rtx_and_jump (tem, const1_rtx, GTU, true, hmode,
1753 NULL_RTX, NULL, do_error,
1754 profile_probability::very_unlikely ());
1757 /* At this point hipart{0,1} are both in [-1, 0]. If they are
1758 the same, overflow happened if res is negative, if they are
1759 different, overflow happened if res is positive. */
1760 if (op0_sign != 1 && op1_sign != 1 && op0_sign != op1_sign)
1761 emit_jump (hipart_different);
1762 else if (op0_sign == 1 || op1_sign == 1)
1763 do_compare_rtx_and_jump (hipart0, hipart1, NE, true, hmode,
1764 NULL_RTX, NULL, hipart_different,
1765 profile_probability::even ());
1767 do_compare_rtx_and_jump (res, const0_rtx, LT, false, mode,
1768 NULL_RTX, NULL, do_error,
1769 profile_probability::very_unlikely ());
1770 emit_jump (done_label);
1772 emit_label (hipart_different);
1774 do_compare_rtx_and_jump (res, const0_rtx, GE, false, mode,
1775 NULL_RTX, NULL, do_error,
1776 profile_probability::very_unlikely ());
1777 emit_jump (done_label);
1780 emit_label (do_overflow);
1782 /* Overflow, do full multiplication and fallthru into do_error. */
1783 ops.op0 = make_tree (type, op0);
1784 ops.op1 = make_tree (type, op1);
1785 tem = expand_expr_real_2 (&ops, NULL_RTX, mode, EXPAND_NORMAL);
1786 emit_move_insn (res, tem);
1788 else
1790 gcc_assert (!is_ubsan);
1791 ops.code = MULT_EXPR;
1792 ops.type = type;
1793 res = expand_expr_real_2 (&ops, NULL_RTX, mode, EXPAND_NORMAL);
1794 emit_jump (done_label);
1798 do_error_label:
1799 emit_label (do_error);
1800 if (is_ubsan)
1802 /* Expand the ubsan builtin call. */
1803 push_temp_slots ();
1804 fn = ubsan_build_overflow_builtin (MULT_EXPR, loc, TREE_TYPE (arg0),
1805 arg0, arg1, datap);
1806 expand_normal (fn);
1807 pop_temp_slots ();
1808 do_pending_stack_adjust ();
1810 else if (lhs)
1811 expand_arith_set_overflow (lhs, target);
1813 /* We're done. */
1814 emit_label (done_label);
1816 /* u1 * u2 -> sr */
1817 if (uns0_p && uns1_p && !unsr_p)
1819 rtx_code_label *all_done_label = gen_label_rtx ();
1820 do_compare_rtx_and_jump (res, const0_rtx, GE, false, mode, NULL_RTX,
1821 NULL, all_done_label, profile_probability::very_likely ());
1822 expand_arith_set_overflow (lhs, target);
1823 emit_label (all_done_label);
1826 /* s1 * u2 -> sr */
1827 if (!uns0_p && uns1_p && !unsr_p && pos_neg1 == 3)
1829 rtx_code_label *all_done_label = gen_label_rtx ();
1830 rtx_code_label *set_noovf = gen_label_rtx ();
1831 do_compare_rtx_and_jump (op1, const0_rtx, GE, false, mode, NULL_RTX,
1832 NULL, all_done_label, profile_probability::very_likely ());
1833 expand_arith_set_overflow (lhs, target);
1834 do_compare_rtx_and_jump (op0, const0_rtx, EQ, true, mode, NULL_RTX,
1835 NULL, set_noovf, profile_probability::very_likely ());
1836 do_compare_rtx_and_jump (op0, constm1_rtx, NE, true, mode, NULL_RTX,
1837 NULL, all_done_label, profile_probability::very_unlikely ());
1838 do_compare_rtx_and_jump (op1, res, NE, true, mode, NULL_RTX, NULL,
1839 all_done_label, profile_probability::very_unlikely ());
1840 emit_label (set_noovf);
1841 write_complex_part (target, const0_rtx, true);
1842 emit_label (all_done_label);
1845 if (lhs)
1847 if (is_ubsan)
1848 expand_ubsan_result_store (target, res);
1849 else
1850 expand_arith_overflow_result_store (lhs, target, mode, res);
1854 /* Expand UBSAN_CHECK_* internal function if it has vector operands. */
1856 static void
1857 expand_vector_ubsan_overflow (location_t loc, enum tree_code code, tree lhs,
1858 tree arg0, tree arg1)
1860 int cnt = TYPE_VECTOR_SUBPARTS (TREE_TYPE (arg0));
1861 rtx_code_label *loop_lab = NULL;
1862 rtx cntvar = NULL_RTX;
1863 tree cntv = NULL_TREE;
1864 tree eltype = TREE_TYPE (TREE_TYPE (arg0));
1865 tree sz = TYPE_SIZE (eltype);
1866 tree data = NULL_TREE;
1867 tree resv = NULL_TREE;
1868 rtx lhsr = NULL_RTX;
1869 rtx resvr = NULL_RTX;
1871 if (lhs)
1873 optab op;
1874 lhsr = expand_expr (lhs, NULL_RTX, VOIDmode, EXPAND_WRITE);
1875 if (!VECTOR_MODE_P (GET_MODE (lhsr))
1876 || (op = optab_for_tree_code (code, TREE_TYPE (arg0),
1877 optab_default)) == unknown_optab
1878 || (optab_handler (op, TYPE_MODE (TREE_TYPE (arg0)))
1879 == CODE_FOR_nothing))
1881 if (MEM_P (lhsr))
1882 resv = make_tree (TREE_TYPE (lhs), lhsr);
1883 else
1885 resvr = assign_temp (TREE_TYPE (lhs), 1, 1);
1886 resv = make_tree (TREE_TYPE (lhs), resvr);
1890 if (cnt > 4)
1892 do_pending_stack_adjust ();
1893 loop_lab = gen_label_rtx ();
1894 cntvar = gen_reg_rtx (TYPE_MODE (sizetype));
1895 cntv = make_tree (sizetype, cntvar);
1896 emit_move_insn (cntvar, const0_rtx);
1897 emit_label (loop_lab);
1899 if (TREE_CODE (arg0) != VECTOR_CST)
1901 rtx arg0r = expand_normal (arg0);
1902 arg0 = make_tree (TREE_TYPE (arg0), arg0r);
1904 if (TREE_CODE (arg1) != VECTOR_CST)
1906 rtx arg1r = expand_normal (arg1);
1907 arg1 = make_tree (TREE_TYPE (arg1), arg1r);
1909 for (int i = 0; i < (cnt > 4 ? 1 : cnt); i++)
1911 tree op0, op1, res = NULL_TREE;
1912 if (cnt > 4)
1914 tree atype = build_array_type_nelts (eltype, cnt);
1915 op0 = uniform_vector_p (arg0);
1916 if (op0 == NULL_TREE)
1918 op0 = fold_build1_loc (loc, VIEW_CONVERT_EXPR, atype, arg0);
1919 op0 = build4_loc (loc, ARRAY_REF, eltype, op0, cntv,
1920 NULL_TREE, NULL_TREE);
1922 op1 = uniform_vector_p (arg1);
1923 if (op1 == NULL_TREE)
1925 op1 = fold_build1_loc (loc, VIEW_CONVERT_EXPR, atype, arg1);
1926 op1 = build4_loc (loc, ARRAY_REF, eltype, op1, cntv,
1927 NULL_TREE, NULL_TREE);
1929 if (resv)
1931 res = fold_build1_loc (loc, VIEW_CONVERT_EXPR, atype, resv);
1932 res = build4_loc (loc, ARRAY_REF, eltype, res, cntv,
1933 NULL_TREE, NULL_TREE);
1936 else
1938 tree bitpos = bitsize_int (tree_to_uhwi (sz) * i);
1939 op0 = fold_build3_loc (loc, BIT_FIELD_REF, eltype, arg0, sz, bitpos);
1940 op1 = fold_build3_loc (loc, BIT_FIELD_REF, eltype, arg1, sz, bitpos);
1941 if (resv)
1942 res = fold_build3_loc (loc, BIT_FIELD_REF, eltype, resv, sz,
1943 bitpos);
1945 switch (code)
1947 case PLUS_EXPR:
1948 expand_addsub_overflow (loc, PLUS_EXPR, res, op0, op1,
1949 false, false, false, true, &data);
1950 break;
1951 case MINUS_EXPR:
1952 if (cnt > 4 ? integer_zerop (arg0) : integer_zerop (op0))
1953 expand_neg_overflow (loc, res, op1, true, &data);
1954 else
1955 expand_addsub_overflow (loc, MINUS_EXPR, res, op0, op1,
1956 false, false, false, true, &data);
1957 break;
1958 case MULT_EXPR:
1959 expand_mul_overflow (loc, res, op0, op1, false, false, false,
1960 true, &data);
1961 break;
1962 default:
1963 gcc_unreachable ();
1966 if (cnt > 4)
1968 struct separate_ops ops;
1969 ops.code = PLUS_EXPR;
1970 ops.type = TREE_TYPE (cntv);
1971 ops.op0 = cntv;
1972 ops.op1 = build_int_cst (TREE_TYPE (cntv), 1);
1973 ops.op2 = NULL_TREE;
1974 ops.location = loc;
1975 rtx ret = expand_expr_real_2 (&ops, cntvar, TYPE_MODE (sizetype),
1976 EXPAND_NORMAL);
1977 if (ret != cntvar)
1978 emit_move_insn (cntvar, ret);
1979 do_compare_rtx_and_jump (cntvar, GEN_INT (cnt), NE, false,
1980 TYPE_MODE (sizetype), NULL_RTX, NULL, loop_lab,
1981 profile_probability::very_likely ());
1983 if (lhs && resv == NULL_TREE)
1985 struct separate_ops ops;
1986 ops.code = code;
1987 ops.type = TREE_TYPE (arg0);
1988 ops.op0 = arg0;
1989 ops.op1 = arg1;
1990 ops.op2 = NULL_TREE;
1991 ops.location = loc;
1992 rtx ret = expand_expr_real_2 (&ops, lhsr, TYPE_MODE (TREE_TYPE (arg0)),
1993 EXPAND_NORMAL);
1994 if (ret != lhsr)
1995 emit_move_insn (lhsr, ret);
1997 else if (resvr)
1998 emit_move_insn (lhsr, resvr);
2001 /* Expand UBSAN_CHECK_ADD call STMT. */
2003 static void
2004 expand_UBSAN_CHECK_ADD (internal_fn, gcall *stmt)
2006 location_t loc = gimple_location (stmt);
2007 tree lhs = gimple_call_lhs (stmt);
2008 tree arg0 = gimple_call_arg (stmt, 0);
2009 tree arg1 = gimple_call_arg (stmt, 1);
2010 if (VECTOR_TYPE_P (TREE_TYPE (arg0)))
2011 expand_vector_ubsan_overflow (loc, PLUS_EXPR, lhs, arg0, arg1);
2012 else
2013 expand_addsub_overflow (loc, PLUS_EXPR, lhs, arg0, arg1,
2014 false, false, false, true, NULL);
2017 /* Expand UBSAN_CHECK_SUB call STMT. */
2019 static void
2020 expand_UBSAN_CHECK_SUB (internal_fn, gcall *stmt)
2022 location_t loc = gimple_location (stmt);
2023 tree lhs = gimple_call_lhs (stmt);
2024 tree arg0 = gimple_call_arg (stmt, 0);
2025 tree arg1 = gimple_call_arg (stmt, 1);
2026 if (VECTOR_TYPE_P (TREE_TYPE (arg0)))
2027 expand_vector_ubsan_overflow (loc, MINUS_EXPR, lhs, arg0, arg1);
2028 else if (integer_zerop (arg0))
2029 expand_neg_overflow (loc, lhs, arg1, true, NULL);
2030 else
2031 expand_addsub_overflow (loc, MINUS_EXPR, lhs, arg0, arg1,
2032 false, false, false, true, NULL);
2035 /* Expand UBSAN_CHECK_MUL call STMT. */
2037 static void
2038 expand_UBSAN_CHECK_MUL (internal_fn, gcall *stmt)
2040 location_t loc = gimple_location (stmt);
2041 tree lhs = gimple_call_lhs (stmt);
2042 tree arg0 = gimple_call_arg (stmt, 0);
2043 tree arg1 = gimple_call_arg (stmt, 1);
2044 if (VECTOR_TYPE_P (TREE_TYPE (arg0)))
2045 expand_vector_ubsan_overflow (loc, MULT_EXPR, lhs, arg0, arg1);
2046 else
2047 expand_mul_overflow (loc, lhs, arg0, arg1, false, false, false, true,
2048 NULL);
2051 /* Helper function for {ADD,SUB,MUL}_OVERFLOW call stmt expansion. */
2053 static void
2054 expand_arith_overflow (enum tree_code code, gimple *stmt)
2056 tree lhs = gimple_call_lhs (stmt);
2057 if (lhs == NULL_TREE)
2058 return;
2059 tree arg0 = gimple_call_arg (stmt, 0);
2060 tree arg1 = gimple_call_arg (stmt, 1);
2061 tree type = TREE_TYPE (TREE_TYPE (lhs));
2062 int uns0_p = TYPE_UNSIGNED (TREE_TYPE (arg0));
2063 int uns1_p = TYPE_UNSIGNED (TREE_TYPE (arg1));
2064 int unsr_p = TYPE_UNSIGNED (type);
2065 int prec0 = TYPE_PRECISION (TREE_TYPE (arg0));
2066 int prec1 = TYPE_PRECISION (TREE_TYPE (arg1));
2067 int precres = TYPE_PRECISION (type);
2068 location_t loc = gimple_location (stmt);
2069 if (!uns0_p && get_range_pos_neg (arg0) == 1)
2070 uns0_p = true;
2071 if (!uns1_p && get_range_pos_neg (arg1) == 1)
2072 uns1_p = true;
2073 int pr = get_min_precision (arg0, uns0_p ? UNSIGNED : SIGNED);
2074 prec0 = MIN (prec0, pr);
2075 pr = get_min_precision (arg1, uns1_p ? UNSIGNED : SIGNED);
2076 prec1 = MIN (prec1, pr);
2078 /* If uns0_p && uns1_p, precop is minimum needed precision
2079 of unsigned type to hold the exact result, otherwise
2080 precop is minimum needed precision of signed type to
2081 hold the exact result. */
2082 int precop;
2083 if (code == MULT_EXPR)
2084 precop = prec0 + prec1 + (uns0_p != uns1_p);
2085 else
2087 if (uns0_p == uns1_p)
2088 precop = MAX (prec0, prec1) + 1;
2089 else if (uns0_p)
2090 precop = MAX (prec0 + 1, prec1) + 1;
2091 else
2092 precop = MAX (prec0, prec1 + 1) + 1;
2094 int orig_precres = precres;
2098 if ((uns0_p && uns1_p)
2099 ? ((precop + !unsr_p) <= precres
2100 /* u1 - u2 -> ur can overflow, no matter what precision
2101 the result has. */
2102 && (code != MINUS_EXPR || !unsr_p))
2103 : (!unsr_p && precop <= precres))
2105 /* The infinity precision result will always fit into result. */
2106 rtx target = expand_expr (lhs, NULL_RTX, VOIDmode, EXPAND_WRITE);
2107 write_complex_part (target, const0_rtx, true);
2108 machine_mode mode = TYPE_MODE (type);
2109 struct separate_ops ops;
2110 ops.code = code;
2111 ops.type = type;
2112 ops.op0 = fold_convert_loc (loc, type, arg0);
2113 ops.op1 = fold_convert_loc (loc, type, arg1);
2114 ops.op2 = NULL_TREE;
2115 ops.location = loc;
2116 rtx tem = expand_expr_real_2 (&ops, NULL_RTX, mode, EXPAND_NORMAL);
2117 expand_arith_overflow_result_store (lhs, target, mode, tem);
2118 return;
2121 /* For operations with low precision, if target doesn't have them, start
2122 with precres widening right away, otherwise do it only if the most
2123 simple cases can't be used. */
2124 const int min_precision = targetm.min_arithmetic_precision ();
2125 if (orig_precres == precres && precres < min_precision)
2127 else if ((uns0_p && uns1_p && unsr_p && prec0 <= precres
2128 && prec1 <= precres)
2129 || ((!uns0_p || !uns1_p) && !unsr_p
2130 && prec0 + uns0_p <= precres
2131 && prec1 + uns1_p <= precres))
2133 arg0 = fold_convert_loc (loc, type, arg0);
2134 arg1 = fold_convert_loc (loc, type, arg1);
2135 switch (code)
2137 case MINUS_EXPR:
2138 if (integer_zerop (arg0) && !unsr_p)
2140 expand_neg_overflow (loc, lhs, arg1, false, NULL);
2141 return;
2143 /* FALLTHRU */
2144 case PLUS_EXPR:
2145 expand_addsub_overflow (loc, code, lhs, arg0, arg1, unsr_p,
2146 unsr_p, unsr_p, false, NULL);
2147 return;
2148 case MULT_EXPR:
2149 expand_mul_overflow (loc, lhs, arg0, arg1, unsr_p,
2150 unsr_p, unsr_p, false, NULL);
2151 return;
2152 default:
2153 gcc_unreachable ();
2157 /* For sub-word operations, retry with a wider type first. */
2158 if (orig_precres == precres && precop <= BITS_PER_WORD)
2160 int p = MAX (min_precision, precop);
2161 machine_mode m = smallest_mode_for_size (p, MODE_INT);
2162 tree optype = build_nonstandard_integer_type (GET_MODE_PRECISION (m),
2163 uns0_p && uns1_p
2164 && unsr_p);
2165 p = TYPE_PRECISION (optype);
2166 if (p > precres)
2168 precres = p;
2169 unsr_p = TYPE_UNSIGNED (optype);
2170 type = optype;
2171 continue;
2175 if (prec0 <= precres && prec1 <= precres)
2177 tree types[2];
2178 if (unsr_p)
2180 types[0] = build_nonstandard_integer_type (precres, 0);
2181 types[1] = type;
2183 else
2185 types[0] = type;
2186 types[1] = build_nonstandard_integer_type (precres, 1);
2188 arg0 = fold_convert_loc (loc, types[uns0_p], arg0);
2189 arg1 = fold_convert_loc (loc, types[uns1_p], arg1);
2190 if (code != MULT_EXPR)
2191 expand_addsub_overflow (loc, code, lhs, arg0, arg1, unsr_p,
2192 uns0_p, uns1_p, false, NULL);
2193 else
2194 expand_mul_overflow (loc, lhs, arg0, arg1, unsr_p,
2195 uns0_p, uns1_p, false, NULL);
2196 return;
2199 /* Retry with a wider type. */
2200 if (orig_precres == precres)
2202 int p = MAX (prec0, prec1);
2203 machine_mode m = smallest_mode_for_size (p, MODE_INT);
2204 tree optype = build_nonstandard_integer_type (GET_MODE_PRECISION (m),
2205 uns0_p && uns1_p
2206 && unsr_p);
2207 p = TYPE_PRECISION (optype);
2208 if (p > precres)
2210 precres = p;
2211 unsr_p = TYPE_UNSIGNED (optype);
2212 type = optype;
2213 continue;
2217 gcc_unreachable ();
2219 while (1);
2222 /* Expand ADD_OVERFLOW STMT. */
2224 static void
2225 expand_ADD_OVERFLOW (internal_fn, gcall *stmt)
2227 expand_arith_overflow (PLUS_EXPR, stmt);
2230 /* Expand SUB_OVERFLOW STMT. */
2232 static void
2233 expand_SUB_OVERFLOW (internal_fn, gcall *stmt)
2235 expand_arith_overflow (MINUS_EXPR, stmt);
2238 /* Expand MUL_OVERFLOW STMT. */
2240 static void
2241 expand_MUL_OVERFLOW (internal_fn, gcall *stmt)
2243 expand_arith_overflow (MULT_EXPR, stmt);
2246 /* This should get folded in tree-vectorizer.c. */
2248 static void
2249 expand_LOOP_VECTORIZED (internal_fn, gcall *)
2251 gcc_unreachable ();
2254 /* This should get folded in tree-vectorizer.c. */
2256 static void
2257 expand_LOOP_DIST_ALIAS (internal_fn, gcall *)
2259 gcc_unreachable ();
2262 /* Expand MASK_LOAD call STMT using optab OPTAB. */
2264 static void
2265 expand_mask_load_optab_fn (internal_fn, gcall *stmt, convert_optab optab)
2267 struct expand_operand ops[3];
2268 tree type, lhs, rhs, maskt, ptr;
2269 rtx mem, target, mask;
2270 unsigned align;
2272 maskt = gimple_call_arg (stmt, 2);
2273 lhs = gimple_call_lhs (stmt);
2274 if (lhs == NULL_TREE)
2275 return;
2276 type = TREE_TYPE (lhs);
2277 ptr = build_int_cst (TREE_TYPE (gimple_call_arg (stmt, 1)), 0);
2278 align = tree_to_shwi (gimple_call_arg (stmt, 1));
2279 if (TYPE_ALIGN (type) != align)
2280 type = build_aligned_type (type, align);
2281 rhs = fold_build2 (MEM_REF, type, gimple_call_arg (stmt, 0), ptr);
2283 mem = expand_expr (rhs, NULL_RTX, VOIDmode, EXPAND_WRITE);
2284 gcc_assert (MEM_P (mem));
2285 mask = expand_normal (maskt);
2286 target = expand_expr (lhs, NULL_RTX, VOIDmode, EXPAND_WRITE);
2287 create_output_operand (&ops[0], target, TYPE_MODE (type));
2288 create_fixed_operand (&ops[1], mem);
2289 create_input_operand (&ops[2], mask, TYPE_MODE (TREE_TYPE (maskt)));
2290 expand_insn (convert_optab_handler (optab, TYPE_MODE (type),
2291 TYPE_MODE (TREE_TYPE (maskt))),
2292 3, ops);
2295 /* Expand MASK_STORE call STMT using optab OPTAB. */
2297 static void
2298 expand_mask_store_optab_fn (internal_fn, gcall *stmt, convert_optab optab)
2300 struct expand_operand ops[3];
2301 tree type, lhs, rhs, maskt, ptr;
2302 rtx mem, reg, mask;
2303 unsigned align;
2305 maskt = gimple_call_arg (stmt, 2);
2306 rhs = gimple_call_arg (stmt, 3);
2307 type = TREE_TYPE (rhs);
2308 ptr = build_int_cst (TREE_TYPE (gimple_call_arg (stmt, 1)), 0);
2309 align = tree_to_shwi (gimple_call_arg (stmt, 1));
2310 if (TYPE_ALIGN (type) != align)
2311 type = build_aligned_type (type, align);
2312 lhs = fold_build2 (MEM_REF, type, gimple_call_arg (stmt, 0), ptr);
2314 mem = expand_expr (lhs, NULL_RTX, VOIDmode, EXPAND_WRITE);
2315 gcc_assert (MEM_P (mem));
2316 mask = expand_normal (maskt);
2317 reg = expand_normal (rhs);
2318 create_fixed_operand (&ops[0], mem);
2319 create_input_operand (&ops[1], reg, TYPE_MODE (type));
2320 create_input_operand (&ops[2], mask, TYPE_MODE (TREE_TYPE (maskt)));
2321 expand_insn (convert_optab_handler (optab, TYPE_MODE (type),
2322 TYPE_MODE (TREE_TYPE (maskt))),
2323 3, ops);
2326 static void
2327 expand_ABNORMAL_DISPATCHER (internal_fn, gcall *)
2331 static void
2332 expand_BUILTIN_EXPECT (internal_fn, gcall *stmt)
2334 /* When guessing was done, the hints should be already stripped away. */
2335 gcc_assert (!flag_guess_branch_prob || optimize == 0 || seen_error ());
2337 rtx target;
2338 tree lhs = gimple_call_lhs (stmt);
2339 if (lhs)
2340 target = expand_expr (lhs, NULL_RTX, VOIDmode, EXPAND_WRITE);
2341 else
2342 target = const0_rtx;
2343 rtx val = expand_expr (gimple_call_arg (stmt, 0), target, VOIDmode, EXPAND_NORMAL);
2344 if (lhs && val != target)
2345 emit_move_insn (target, val);
2348 /* IFN_VA_ARG is supposed to be expanded at pass_stdarg. So this dummy function
2349 should never be called. */
2351 static void
2352 expand_VA_ARG (internal_fn, gcall *)
2354 gcc_unreachable ();
2357 /* Expand the IFN_UNIQUE function according to its first argument. */
2359 static void
2360 expand_UNIQUE (internal_fn, gcall *stmt)
2362 rtx pattern = NULL_RTX;
2363 enum ifn_unique_kind kind
2364 = (enum ifn_unique_kind) TREE_INT_CST_LOW (gimple_call_arg (stmt, 0));
2366 switch (kind)
2368 default:
2369 gcc_unreachable ();
2371 case IFN_UNIQUE_UNSPEC:
2372 if (targetm.have_unique ())
2373 pattern = targetm.gen_unique ();
2374 break;
2376 case IFN_UNIQUE_OACC_FORK:
2377 case IFN_UNIQUE_OACC_JOIN:
2378 if (targetm.have_oacc_fork () && targetm.have_oacc_join ())
2380 tree lhs = gimple_call_lhs (stmt);
2381 rtx target = const0_rtx;
2383 if (lhs)
2384 target = expand_expr (lhs, NULL_RTX, VOIDmode, EXPAND_WRITE);
2386 rtx data_dep = expand_normal (gimple_call_arg (stmt, 1));
2387 rtx axis = expand_normal (gimple_call_arg (stmt, 2));
2389 if (kind == IFN_UNIQUE_OACC_FORK)
2390 pattern = targetm.gen_oacc_fork (target, data_dep, axis);
2391 else
2392 pattern = targetm.gen_oacc_join (target, data_dep, axis);
2394 else
2395 gcc_unreachable ();
2396 break;
2399 if (pattern)
2400 emit_insn (pattern);
2403 /* The size of an OpenACC compute dimension. */
2405 static void
2406 expand_GOACC_DIM_SIZE (internal_fn, gcall *stmt)
2408 tree lhs = gimple_call_lhs (stmt);
2410 if (!lhs)
2411 return;
2413 rtx target = expand_expr (lhs, NULL_RTX, VOIDmode, EXPAND_WRITE);
2414 if (targetm.have_oacc_dim_size ())
2416 rtx dim = expand_expr (gimple_call_arg (stmt, 0), NULL_RTX,
2417 VOIDmode, EXPAND_NORMAL);
2418 emit_insn (targetm.gen_oacc_dim_size (target, dim));
2420 else
2421 emit_move_insn (target, GEN_INT (1));
2424 /* The position of an OpenACC execution engine along one compute axis. */
2426 static void
2427 expand_GOACC_DIM_POS (internal_fn, gcall *stmt)
2429 tree lhs = gimple_call_lhs (stmt);
2431 if (!lhs)
2432 return;
2434 rtx target = expand_expr (lhs, NULL_RTX, VOIDmode, EXPAND_WRITE);
2435 if (targetm.have_oacc_dim_pos ())
2437 rtx dim = expand_expr (gimple_call_arg (stmt, 0), NULL_RTX,
2438 VOIDmode, EXPAND_NORMAL);
2439 emit_insn (targetm.gen_oacc_dim_pos (target, dim));
2441 else
2442 emit_move_insn (target, const0_rtx);
2445 /* This is expanded by oacc_device_lower pass. */
2447 static void
2448 expand_GOACC_LOOP (internal_fn, gcall *)
2450 gcc_unreachable ();
2453 /* This is expanded by oacc_device_lower pass. */
2455 static void
2456 expand_GOACC_REDUCTION (internal_fn, gcall *)
2458 gcc_unreachable ();
2461 /* This is expanded by oacc_device_lower pass. */
2463 static void
2464 expand_GOACC_TILE (internal_fn, gcall *)
2466 gcc_unreachable ();
2469 /* Set errno to EDOM. */
2471 static void
2472 expand_SET_EDOM (internal_fn, gcall *)
2474 #ifdef TARGET_EDOM
2475 #ifdef GEN_ERRNO_RTX
2476 rtx errno_rtx = GEN_ERRNO_RTX;
2477 #else
2478 rtx errno_rtx = gen_rtx_MEM (word_mode, gen_rtx_SYMBOL_REF (Pmode, "errno"));
2479 #endif
2480 emit_move_insn (errno_rtx,
2481 gen_int_mode (TARGET_EDOM, GET_MODE (errno_rtx)));
2482 #else
2483 gcc_unreachable ();
2484 #endif
2487 /* Expand atomic bit test and set. */
2489 static void
2490 expand_ATOMIC_BIT_TEST_AND_SET (internal_fn, gcall *call)
2492 expand_ifn_atomic_bit_test_and (call);
2495 /* Expand atomic bit test and complement. */
2497 static void
2498 expand_ATOMIC_BIT_TEST_AND_COMPLEMENT (internal_fn, gcall *call)
2500 expand_ifn_atomic_bit_test_and (call);
2503 /* Expand atomic bit test and reset. */
2505 static void
2506 expand_ATOMIC_BIT_TEST_AND_RESET (internal_fn, gcall *call)
2508 expand_ifn_atomic_bit_test_and (call);
2511 /* Expand atomic bit test and set. */
2513 static void
2514 expand_ATOMIC_COMPARE_EXCHANGE (internal_fn, gcall *call)
2516 expand_ifn_atomic_compare_exchange (call);
2519 /* Expand LAUNDER to assignment, lhs = arg0. */
2521 static void
2522 expand_LAUNDER (internal_fn, gcall *call)
2524 tree lhs = gimple_call_lhs (call);
2526 if (!lhs)
2527 return;
2529 expand_assignment (lhs, gimple_call_arg (call, 0), false);
2532 /* Expand DIVMOD() using:
2533 a) optab handler for udivmod/sdivmod if it is available.
2534 b) If optab_handler doesn't exist, generate call to
2535 target-specific divmod libfunc. */
2537 static void
2538 expand_DIVMOD (internal_fn, gcall *call_stmt)
2540 tree lhs = gimple_call_lhs (call_stmt);
2541 tree arg0 = gimple_call_arg (call_stmt, 0);
2542 tree arg1 = gimple_call_arg (call_stmt, 1);
2544 gcc_assert (TREE_CODE (TREE_TYPE (lhs)) == COMPLEX_TYPE);
2545 tree type = TREE_TYPE (TREE_TYPE (lhs));
2546 machine_mode mode = TYPE_MODE (type);
2547 bool unsignedp = TYPE_UNSIGNED (type);
2548 optab tab = (unsignedp) ? udivmod_optab : sdivmod_optab;
2550 rtx op0 = expand_normal (arg0);
2551 rtx op1 = expand_normal (arg1);
2552 rtx target = expand_expr (lhs, NULL_RTX, VOIDmode, EXPAND_WRITE);
2554 rtx quotient, remainder, libfunc;
2556 /* Check if optab_handler exists for divmod_optab for given mode. */
2557 if (optab_handler (tab, mode) != CODE_FOR_nothing)
2559 quotient = gen_reg_rtx (mode);
2560 remainder = gen_reg_rtx (mode);
2561 expand_twoval_binop (tab, op0, op1, quotient, remainder, unsignedp);
2564 /* Generate call to divmod libfunc if it exists. */
2565 else if ((libfunc = optab_libfunc (tab, mode)) != NULL_RTX)
2566 targetm.expand_divmod_libfunc (libfunc, mode, op0, op1,
2567 &quotient, &remainder);
2569 else
2570 gcc_unreachable ();
2572 /* Wrap the return value (quotient, remainder) within COMPLEX_EXPR. */
2573 expand_expr (build2 (COMPLEX_EXPR, TREE_TYPE (lhs),
2574 make_tree (TREE_TYPE (arg0), quotient),
2575 make_tree (TREE_TYPE (arg1), remainder)),
2576 target, VOIDmode, EXPAND_NORMAL);
2579 /* Expand a call to FN using the operands in STMT. FN has a single
2580 output operand and NARGS input operands. */
2582 static void
2583 expand_direct_optab_fn (internal_fn fn, gcall *stmt, direct_optab optab,
2584 unsigned int nargs)
2586 expand_operand *ops = XALLOCAVEC (expand_operand, nargs + 1);
2588 tree_pair types = direct_internal_fn_types (fn, stmt);
2589 insn_code icode = direct_optab_handler (optab, TYPE_MODE (types.first));
2591 tree lhs = gimple_call_lhs (stmt);
2592 tree lhs_type = TREE_TYPE (lhs);
2593 rtx lhs_rtx = expand_expr (lhs, NULL_RTX, VOIDmode, EXPAND_WRITE);
2594 create_output_operand (&ops[0], lhs_rtx, insn_data[icode].operand[0].mode);
2596 for (unsigned int i = 0; i < nargs; ++i)
2598 tree rhs = gimple_call_arg (stmt, i);
2599 tree rhs_type = TREE_TYPE (rhs);
2600 rtx rhs_rtx = expand_normal (rhs);
2601 if (INTEGRAL_TYPE_P (rhs_type))
2602 create_convert_operand_from (&ops[i + 1], rhs_rtx,
2603 TYPE_MODE (rhs_type),
2604 TYPE_UNSIGNED (rhs_type));
2605 else
2606 create_input_operand (&ops[i + 1], rhs_rtx, TYPE_MODE (rhs_type));
2609 expand_insn (icode, nargs + 1, ops);
2610 if (!rtx_equal_p (lhs_rtx, ops[0].value))
2612 /* If the return value has an integral type, convert the instruction
2613 result to that type. This is useful for things that return an
2614 int regardless of the size of the input. If the instruction result
2615 is smaller than required, assume that it is signed.
2617 If the return value has a nonintegral type, its mode must match
2618 the instruction result. */
2619 if (GET_CODE (lhs_rtx) == SUBREG && SUBREG_PROMOTED_VAR_P (lhs_rtx))
2621 /* If this is a scalar in a register that is stored in a wider
2622 mode than the declared mode, compute the result into its
2623 declared mode and then convert to the wider mode. */
2624 gcc_checking_assert (INTEGRAL_TYPE_P (lhs_type));
2625 rtx tmp = convert_to_mode (GET_MODE (lhs_rtx), ops[0].value, 0);
2626 convert_move (SUBREG_REG (lhs_rtx), tmp,
2627 SUBREG_PROMOTED_SIGN (lhs_rtx));
2629 else if (GET_MODE (lhs_rtx) == GET_MODE (ops[0].value))
2630 emit_move_insn (lhs_rtx, ops[0].value);
2631 else
2633 gcc_checking_assert (INTEGRAL_TYPE_P (lhs_type));
2634 convert_move (lhs_rtx, ops[0].value, 0);
2639 /* Expanders for optabs that can use expand_direct_optab_fn. */
2641 #define expand_unary_optab_fn(FN, STMT, OPTAB) \
2642 expand_direct_optab_fn (FN, STMT, OPTAB, 1)
2644 #define expand_binary_optab_fn(FN, STMT, OPTAB) \
2645 expand_direct_optab_fn (FN, STMT, OPTAB, 2)
2647 /* RETURN_TYPE and ARGS are a return type and argument list that are
2648 in principle compatible with FN (which satisfies direct_internal_fn_p).
2649 Return the types that should be used to determine whether the
2650 target supports FN. */
2652 tree_pair
2653 direct_internal_fn_types (internal_fn fn, tree return_type, tree *args)
2655 const direct_internal_fn_info &info = direct_internal_fn (fn);
2656 tree type0 = (info.type0 < 0 ? return_type : TREE_TYPE (args[info.type0]));
2657 tree type1 = (info.type1 < 0 ? return_type : TREE_TYPE (args[info.type1]));
2658 return tree_pair (type0, type1);
2661 /* CALL is a call whose return type and arguments are in principle
2662 compatible with FN (which satisfies direct_internal_fn_p). Return the
2663 types that should be used to determine whether the target supports FN. */
2665 tree_pair
2666 direct_internal_fn_types (internal_fn fn, gcall *call)
2668 const direct_internal_fn_info &info = direct_internal_fn (fn);
2669 tree op0 = (info.type0 < 0
2670 ? gimple_call_lhs (call)
2671 : gimple_call_arg (call, info.type0));
2672 tree op1 = (info.type1 < 0
2673 ? gimple_call_lhs (call)
2674 : gimple_call_arg (call, info.type1));
2675 return tree_pair (TREE_TYPE (op0), TREE_TYPE (op1));
2678 /* Return true if OPTAB is supported for TYPES (whose modes should be
2679 the same) when the optimization type is OPT_TYPE. Used for simple
2680 direct optabs. */
2682 static bool
2683 direct_optab_supported_p (direct_optab optab, tree_pair types,
2684 optimization_type opt_type)
2686 machine_mode mode = TYPE_MODE (types.first);
2687 gcc_checking_assert (mode == TYPE_MODE (types.second));
2688 return direct_optab_handler (optab, mode, opt_type) != CODE_FOR_nothing;
2691 /* Return true if load/store lanes optab OPTAB is supported for
2692 array type TYPES.first when the optimization type is OPT_TYPE. */
2694 static bool
2695 multi_vector_optab_supported_p (convert_optab optab, tree_pair types,
2696 optimization_type opt_type)
2698 gcc_assert (TREE_CODE (types.first) == ARRAY_TYPE);
2699 machine_mode imode = TYPE_MODE (types.first);
2700 machine_mode vmode = TYPE_MODE (TREE_TYPE (types.first));
2701 return (convert_optab_handler (optab, imode, vmode, opt_type)
2702 != CODE_FOR_nothing);
2705 #define direct_unary_optab_supported_p direct_optab_supported_p
2706 #define direct_binary_optab_supported_p direct_optab_supported_p
2707 #define direct_mask_load_optab_supported_p direct_optab_supported_p
2708 #define direct_load_lanes_optab_supported_p multi_vector_optab_supported_p
2709 #define direct_mask_store_optab_supported_p direct_optab_supported_p
2710 #define direct_store_lanes_optab_supported_p multi_vector_optab_supported_p
2712 /* Return true if FN is supported for the types in TYPES when the
2713 optimization type is OPT_TYPE. The types are those associated with
2714 the "type0" and "type1" fields of FN's direct_internal_fn_info
2715 structure. */
2717 bool
2718 direct_internal_fn_supported_p (internal_fn fn, tree_pair types,
2719 optimization_type opt_type)
2721 switch (fn)
2723 #define DEF_INTERNAL_FN(CODE, FLAGS, FNSPEC) \
2724 case IFN_##CODE: break;
2725 #define DEF_INTERNAL_OPTAB_FN(CODE, FLAGS, OPTAB, TYPE) \
2726 case IFN_##CODE: \
2727 return direct_##TYPE##_optab_supported_p (OPTAB##_optab, types, \
2728 opt_type);
2729 #include "internal-fn.def"
2731 case IFN_LAST:
2732 break;
2734 gcc_unreachable ();
2737 /* Return true if FN is supported for type TYPE when the optimization
2738 type is OPT_TYPE. The caller knows that the "type0" and "type1"
2739 fields of FN's direct_internal_fn_info structure are the same. */
2741 bool
2742 direct_internal_fn_supported_p (internal_fn fn, tree type,
2743 optimization_type opt_type)
2745 const direct_internal_fn_info &info = direct_internal_fn (fn);
2746 gcc_checking_assert (info.type0 == info.type1);
2747 return direct_internal_fn_supported_p (fn, tree_pair (type, type), opt_type);
2750 /* Return true if IFN_SET_EDOM is supported. */
2752 bool
2753 set_edom_supported_p (void)
2755 #ifdef TARGET_EDOM
2756 return true;
2757 #else
2758 return false;
2759 #endif
2762 #define DEF_INTERNAL_OPTAB_FN(CODE, FLAGS, OPTAB, TYPE) \
2763 static void \
2764 expand_##CODE (internal_fn fn, gcall *stmt) \
2766 expand_##TYPE##_optab_fn (fn, stmt, OPTAB##_optab); \
2768 #include "internal-fn.def"
2770 /* Routines to expand each internal function, indexed by function number.
2771 Each routine has the prototype:
2773 expand_<NAME> (gcall *stmt)
2775 where STMT is the statement that performs the call. */
2776 static void (*const internal_fn_expanders[]) (internal_fn, gcall *) = {
2777 #define DEF_INTERNAL_FN(CODE, FLAGS, FNSPEC) expand_##CODE,
2778 #include "internal-fn.def"
2782 /* Expand STMT as though it were a call to internal function FN. */
2784 void
2785 expand_internal_call (internal_fn fn, gcall *stmt)
2787 internal_fn_expanders[fn] (fn, stmt);
2790 /* Expand STMT, which is a call to internal function FN. */
2792 void
2793 expand_internal_call (gcall *stmt)
2795 expand_internal_call (gimple_call_internal_fn (stmt), stmt);
2798 void
2799 expand_PHI (internal_fn, gcall *)
2801 gcc_unreachable ();