Daily bump.
[official-gcc.git] / gcc / internal-fn.c
blobdf7b930e801f1ab63e207f237b3e5851f9a09837
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 "ubsan.h"
43 #include "recog.h"
44 #include "builtins.h"
45 #include "optabs-tree.h"
47 /* The names of each internal function, indexed by function number. */
48 const char *const internal_fn_name_array[] = {
49 #define DEF_INTERNAL_FN(CODE, FLAGS, FNSPEC) #CODE,
50 #include "internal-fn.def"
51 "<invalid-fn>"
54 /* The ECF_* flags of each internal function, indexed by function number. */
55 const int internal_fn_flags_array[] = {
56 #define DEF_INTERNAL_FN(CODE, FLAGS, FNSPEC) FLAGS,
57 #include "internal-fn.def"
61 /* Fnspec of each internal function, indexed by function number. */
62 const_tree internal_fn_fnspec_array[IFN_LAST + 1];
64 void
65 init_internal_fns ()
67 #define DEF_INTERNAL_FN(CODE, FLAGS, FNSPEC) \
68 if (FNSPEC) internal_fn_fnspec_array[IFN_##CODE] = \
69 build_string ((int) sizeof (FNSPEC), FNSPEC ? FNSPEC : "");
70 #include "internal-fn.def"
71 internal_fn_fnspec_array[IFN_LAST] = 0;
74 /* Create static initializers for the information returned by
75 direct_internal_fn. */
76 #define not_direct { -2, -2, false }
77 #define mask_load_direct { -1, 2, false }
78 #define load_lanes_direct { -1, -1, false }
79 #define mask_store_direct { 3, 2, false }
80 #define store_lanes_direct { 0, 0, false }
81 #define unary_direct { 0, 0, true }
82 #define binary_direct { 0, 0, true }
84 const direct_internal_fn_info direct_internal_fn_array[IFN_LAST + 1] = {
85 #define DEF_INTERNAL_FN(CODE, FLAGS, FNSPEC) not_direct,
86 #define DEF_INTERNAL_OPTAB_FN(CODE, FLAGS, OPTAB, TYPE) TYPE##_direct,
87 #include "internal-fn.def"
88 not_direct
91 /* ARRAY_TYPE is an array of vector modes. Return the associated insn
92 for load-lanes-style optab OPTAB, or CODE_FOR_nothing if none. */
94 static enum insn_code
95 get_multi_vector_move (tree array_type, convert_optab optab)
97 machine_mode imode;
98 machine_mode vmode;
100 gcc_assert (TREE_CODE (array_type) == ARRAY_TYPE);
101 imode = TYPE_MODE (array_type);
102 vmode = TYPE_MODE (TREE_TYPE (array_type));
104 return convert_optab_handler (optab, imode, vmode);
107 /* Expand LOAD_LANES call STMT using optab OPTAB. */
109 static void
110 expand_load_lanes_optab_fn (internal_fn, gcall *stmt, convert_optab optab)
112 struct expand_operand ops[2];
113 tree type, lhs, rhs;
114 rtx target, mem;
116 lhs = gimple_call_lhs (stmt);
117 rhs = gimple_call_arg (stmt, 0);
118 type = TREE_TYPE (lhs);
120 target = expand_expr (lhs, NULL_RTX, VOIDmode, EXPAND_WRITE);
121 mem = expand_normal (rhs);
123 gcc_assert (MEM_P (mem));
124 PUT_MODE (mem, TYPE_MODE (type));
126 create_output_operand (&ops[0], target, TYPE_MODE (type));
127 create_fixed_operand (&ops[1], mem);
128 expand_insn (get_multi_vector_move (type, optab), 2, ops);
131 /* Expand STORE_LANES call STMT using optab OPTAB. */
133 static void
134 expand_store_lanes_optab_fn (internal_fn, gcall *stmt, convert_optab optab)
136 struct expand_operand ops[2];
137 tree type, lhs, rhs;
138 rtx target, reg;
140 lhs = gimple_call_lhs (stmt);
141 rhs = gimple_call_arg (stmt, 0);
142 type = TREE_TYPE (rhs);
144 target = expand_expr (lhs, NULL_RTX, VOIDmode, EXPAND_WRITE);
145 reg = expand_normal (rhs);
147 gcc_assert (MEM_P (target));
148 PUT_MODE (target, TYPE_MODE (type));
150 create_fixed_operand (&ops[0], target);
151 create_input_operand (&ops[1], reg, TYPE_MODE (type));
152 expand_insn (get_multi_vector_move (type, optab), 2, ops);
155 static void
156 expand_ANNOTATE (internal_fn, gcall *)
158 gcc_unreachable ();
161 /* This should get expanded in omp_device_lower pass. */
163 static void
164 expand_GOMP_USE_SIMT (internal_fn, gcall *)
166 gcc_unreachable ();
169 /* Lane index on SIMT targets: thread index in the warp on NVPTX. On targets
170 without SIMT execution this should be expanded in omp_device_lower pass. */
172 static void
173 expand_GOMP_SIMT_LANE (internal_fn, gcall *stmt)
175 tree lhs = gimple_call_lhs (stmt);
176 if (!lhs)
177 return;
179 rtx target = expand_expr (lhs, NULL_RTX, VOIDmode, EXPAND_WRITE);
180 gcc_assert (targetm.have_omp_simt_lane ());
181 emit_insn (targetm.gen_omp_simt_lane (target));
184 /* This should get expanded in omp_device_lower pass. */
186 static void
187 expand_GOMP_SIMT_VF (internal_fn, gcall *)
189 gcc_unreachable ();
192 /* Lane index of the first SIMT lane that supplies a non-zero argument.
193 This is a SIMT counterpart to GOMP_SIMD_LAST_LANE, used to represent the
194 lane that executed the last iteration for handling OpenMP lastprivate. */
196 static void
197 expand_GOMP_SIMT_LAST_LANE (internal_fn, gcall *stmt)
199 tree lhs = gimple_call_lhs (stmt);
200 if (!lhs)
201 return;
203 rtx target = expand_expr (lhs, NULL_RTX, VOIDmode, EXPAND_WRITE);
204 rtx cond = expand_normal (gimple_call_arg (stmt, 0));
205 machine_mode mode = TYPE_MODE (TREE_TYPE (lhs));
206 struct expand_operand ops[2];
207 create_output_operand (&ops[0], target, mode);
208 create_input_operand (&ops[1], cond, mode);
209 gcc_assert (targetm.have_omp_simt_last_lane ());
210 expand_insn (targetm.code_for_omp_simt_last_lane, 2, ops);
213 /* Non-transparent predicate used in SIMT lowering of OpenMP "ordered". */
215 static void
216 expand_GOMP_SIMT_ORDERED_PRED (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 rtx ctr = expand_normal (gimple_call_arg (stmt, 0));
224 machine_mode mode = TYPE_MODE (TREE_TYPE (lhs));
225 struct expand_operand ops[2];
226 create_output_operand (&ops[0], target, mode);
227 create_input_operand (&ops[1], ctr, mode);
228 gcc_assert (targetm.have_omp_simt_ordered ());
229 expand_insn (targetm.code_for_omp_simt_ordered, 2, ops);
232 /* "Or" boolean reduction across SIMT lanes: return non-zero in all lanes if
233 any lane supplies a non-zero argument. */
235 static void
236 expand_GOMP_SIMT_VOTE_ANY (internal_fn, gcall *stmt)
238 tree lhs = gimple_call_lhs (stmt);
239 if (!lhs)
240 return;
242 rtx target = expand_expr (lhs, NULL_RTX, VOIDmode, EXPAND_WRITE);
243 rtx cond = expand_normal (gimple_call_arg (stmt, 0));
244 machine_mode mode = TYPE_MODE (TREE_TYPE (lhs));
245 struct expand_operand ops[2];
246 create_output_operand (&ops[0], target, mode);
247 create_input_operand (&ops[1], cond, mode);
248 gcc_assert (targetm.have_omp_simt_vote_any ());
249 expand_insn (targetm.code_for_omp_simt_vote_any, 2, ops);
252 /* Exchange between SIMT lanes with a "butterfly" pattern: source lane index
253 is destination lane index XOR given offset. */
255 static void
256 expand_GOMP_SIMT_XCHG_BFLY (internal_fn, gcall *stmt)
258 tree lhs = gimple_call_lhs (stmt);
259 if (!lhs)
260 return;
262 rtx target = expand_expr (lhs, NULL_RTX, VOIDmode, EXPAND_WRITE);
263 rtx src = expand_normal (gimple_call_arg (stmt, 0));
264 rtx idx = expand_normal (gimple_call_arg (stmt, 1));
265 machine_mode mode = TYPE_MODE (TREE_TYPE (lhs));
266 struct expand_operand ops[3];
267 create_output_operand (&ops[0], target, mode);
268 create_input_operand (&ops[1], src, mode);
269 create_input_operand (&ops[2], idx, SImode);
270 gcc_assert (targetm.have_omp_simt_xchg_bfly ());
271 expand_insn (targetm.code_for_omp_simt_xchg_bfly, 3, ops);
274 /* Exchange between SIMT lanes according to given source lane index. */
276 static void
277 expand_GOMP_SIMT_XCHG_IDX (internal_fn, gcall *stmt)
279 tree lhs = gimple_call_lhs (stmt);
280 if (!lhs)
281 return;
283 rtx target = expand_expr (lhs, NULL_RTX, VOIDmode, EXPAND_WRITE);
284 rtx src = expand_normal (gimple_call_arg (stmt, 0));
285 rtx idx = expand_normal (gimple_call_arg (stmt, 1));
286 machine_mode mode = TYPE_MODE (TREE_TYPE (lhs));
287 struct expand_operand ops[3];
288 create_output_operand (&ops[0], target, mode);
289 create_input_operand (&ops[1], src, mode);
290 create_input_operand (&ops[2], idx, SImode);
291 gcc_assert (targetm.have_omp_simt_xchg_idx ());
292 expand_insn (targetm.code_for_omp_simt_xchg_idx, 3, ops);
295 /* This should get expanded in adjust_simduid_builtins. */
297 static void
298 expand_GOMP_SIMD_LANE (internal_fn, gcall *)
300 gcc_unreachable ();
303 /* This should get expanded in adjust_simduid_builtins. */
305 static void
306 expand_GOMP_SIMD_VF (internal_fn, gcall *)
308 gcc_unreachable ();
311 /* This should get expanded in adjust_simduid_builtins. */
313 static void
314 expand_GOMP_SIMD_LAST_LANE (internal_fn, gcall *)
316 gcc_unreachable ();
319 /* This should get expanded in adjust_simduid_builtins. */
321 static void
322 expand_GOMP_SIMD_ORDERED_START (internal_fn, gcall *)
324 gcc_unreachable ();
327 /* This should get expanded in adjust_simduid_builtins. */
329 static void
330 expand_GOMP_SIMD_ORDERED_END (internal_fn, gcall *)
332 gcc_unreachable ();
335 /* This should get expanded in the sanopt pass. */
337 static void
338 expand_UBSAN_NULL (internal_fn, gcall *)
340 gcc_unreachable ();
343 /* This should get expanded in the sanopt pass. */
345 static void
346 expand_UBSAN_BOUNDS (internal_fn, gcall *)
348 gcc_unreachable ();
351 /* This should get expanded in the sanopt pass. */
353 static void
354 expand_UBSAN_VPTR (internal_fn, gcall *)
356 gcc_unreachable ();
359 /* This should get expanded in the sanopt pass. */
361 static void
362 expand_UBSAN_OBJECT_SIZE (internal_fn, gcall *)
364 gcc_unreachable ();
367 /* This should get expanded in the sanopt pass. */
369 static void
370 expand_ASAN_CHECK (internal_fn, gcall *)
372 gcc_unreachable ();
375 /* This should get expanded in the sanopt pass. */
377 static void
378 expand_ASAN_MARK (internal_fn, gcall *)
380 gcc_unreachable ();
383 /* This should get expanded in the sanopt pass. */
385 static void
386 expand_ASAN_POISON (internal_fn, gcall *)
388 gcc_unreachable ();
391 /* This should get expanded in the sanopt pass. */
393 static void
394 expand_ASAN_POISON_USE (internal_fn, gcall *)
396 gcc_unreachable ();
399 /* This should get expanded in the tsan pass. */
401 static void
402 expand_TSAN_FUNC_EXIT (internal_fn, gcall *)
404 gcc_unreachable ();
407 /* This should get expanded in the lower pass. */
409 static void
410 expand_FALLTHROUGH (internal_fn, gcall *call)
412 error_at (gimple_location (call),
413 "invalid use of attribute %<fallthrough%>");
416 /* Return minimum precision needed to represent all values
417 of ARG in SIGNed integral type. */
419 static int
420 get_min_precision (tree arg, signop sign)
422 int prec = TYPE_PRECISION (TREE_TYPE (arg));
423 int cnt = 0;
424 signop orig_sign = sign;
425 if (TREE_CODE (arg) == INTEGER_CST)
427 int p;
428 if (TYPE_SIGN (TREE_TYPE (arg)) != sign)
430 widest_int w = wi::to_widest (arg);
431 w = wi::ext (w, prec, sign);
432 p = wi::min_precision (w, sign);
434 else
435 p = wi::min_precision (arg, sign);
436 return MIN (p, prec);
438 while (CONVERT_EXPR_P (arg)
439 && INTEGRAL_TYPE_P (TREE_TYPE (TREE_OPERAND (arg, 0)))
440 && TYPE_PRECISION (TREE_TYPE (TREE_OPERAND (arg, 0))) <= prec)
442 arg = TREE_OPERAND (arg, 0);
443 if (TYPE_PRECISION (TREE_TYPE (arg)) < prec)
445 if (TYPE_UNSIGNED (TREE_TYPE (arg)))
446 sign = UNSIGNED;
447 else if (sign == UNSIGNED && get_range_pos_neg (arg) != 1)
448 return prec + (orig_sign != sign);
449 prec = TYPE_PRECISION (TREE_TYPE (arg));
451 if (++cnt > 30)
452 return prec + (orig_sign != sign);
454 if (TREE_CODE (arg) != SSA_NAME)
455 return prec + (orig_sign != sign);
456 wide_int arg_min, arg_max;
457 while (get_range_info (arg, &arg_min, &arg_max) != VR_RANGE)
459 gimple *g = SSA_NAME_DEF_STMT (arg);
460 if (is_gimple_assign (g)
461 && CONVERT_EXPR_CODE_P (gimple_assign_rhs_code (g)))
463 tree t = gimple_assign_rhs1 (g);
464 if (INTEGRAL_TYPE_P (TREE_TYPE (t))
465 && TYPE_PRECISION (TREE_TYPE (t)) <= prec)
467 arg = t;
468 if (TYPE_PRECISION (TREE_TYPE (arg)) < prec)
470 if (TYPE_UNSIGNED (TREE_TYPE (arg)))
471 sign = UNSIGNED;
472 else if (sign == UNSIGNED && get_range_pos_neg (arg) != 1)
473 return prec + (orig_sign != sign);
474 prec = TYPE_PRECISION (TREE_TYPE (arg));
476 if (++cnt > 30)
477 return prec + (orig_sign != sign);
478 continue;
481 return prec + (orig_sign != sign);
483 if (sign == TYPE_SIGN (TREE_TYPE (arg)))
485 int p1 = wi::min_precision (arg_min, sign);
486 int p2 = wi::min_precision (arg_max, sign);
487 p1 = MAX (p1, p2);
488 prec = MIN (prec, p1);
490 else if (sign == UNSIGNED && !wi::neg_p (arg_min, SIGNED))
492 int p = wi::min_precision (arg_max, UNSIGNED);
493 prec = MIN (prec, p);
495 return prec + (orig_sign != sign);
498 /* Helper for expand_*_overflow. Set the __imag__ part to true
499 (1 except for signed:1 type, in which case store -1). */
501 static void
502 expand_arith_set_overflow (tree lhs, rtx target)
504 if (TYPE_PRECISION (TREE_TYPE (TREE_TYPE (lhs))) == 1
505 && !TYPE_UNSIGNED (TREE_TYPE (TREE_TYPE (lhs))))
506 write_complex_part (target, constm1_rtx, true);
507 else
508 write_complex_part (target, const1_rtx, true);
511 /* Helper for expand_*_overflow. Store RES into the __real__ part
512 of TARGET. If RES has larger MODE than __real__ part of TARGET,
513 set the __imag__ part to 1 if RES doesn't fit into it. Similarly
514 if LHS has smaller precision than its mode. */
516 static void
517 expand_arith_overflow_result_store (tree lhs, rtx target,
518 machine_mode mode, rtx res)
520 machine_mode tgtmode = GET_MODE_INNER (GET_MODE (target));
521 rtx lres = res;
522 if (tgtmode != mode)
524 rtx_code_label *done_label = gen_label_rtx ();
525 int uns = TYPE_UNSIGNED (TREE_TYPE (TREE_TYPE (lhs)));
526 lres = convert_modes (tgtmode, mode, res, uns);
527 gcc_assert (GET_MODE_PRECISION (tgtmode) < GET_MODE_PRECISION (mode));
528 do_compare_rtx_and_jump (res, convert_modes (mode, tgtmode, lres, uns),
529 EQ, true, mode, NULL_RTX, NULL, done_label,
530 PROB_VERY_LIKELY);
531 expand_arith_set_overflow (lhs, target);
532 emit_label (done_label);
534 int prec = TYPE_PRECISION (TREE_TYPE (TREE_TYPE (lhs)));
535 int tgtprec = GET_MODE_PRECISION (tgtmode);
536 if (prec < tgtprec)
538 rtx_code_label *done_label = gen_label_rtx ();
539 int uns = TYPE_UNSIGNED (TREE_TYPE (TREE_TYPE (lhs)));
540 res = lres;
541 if (uns)
543 rtx mask
544 = immed_wide_int_const (wi::shifted_mask (0, prec, false, tgtprec),
545 tgtmode);
546 lres = expand_simple_binop (tgtmode, AND, res, mask, NULL_RTX,
547 true, OPTAB_LIB_WIDEN);
549 else
551 lres = expand_shift (LSHIFT_EXPR, tgtmode, res, tgtprec - prec,
552 NULL_RTX, 1);
553 lres = expand_shift (RSHIFT_EXPR, tgtmode, lres, tgtprec - prec,
554 NULL_RTX, 0);
556 do_compare_rtx_and_jump (res, lres,
557 EQ, true, tgtmode, NULL_RTX, NULL, done_label,
558 PROB_VERY_LIKELY);
559 expand_arith_set_overflow (lhs, target);
560 emit_label (done_label);
562 write_complex_part (target, lres, false);
565 /* Helper for expand_*_overflow. Store RES into TARGET. */
567 static void
568 expand_ubsan_result_store (rtx target, rtx res)
570 if (GET_CODE (target) == SUBREG && SUBREG_PROMOTED_VAR_P (target))
571 /* If this is a scalar in a register that is stored in a wider mode
572 than the declared mode, compute the result into its declared mode
573 and then convert to the wider mode. Our value is the computed
574 expression. */
575 convert_move (SUBREG_REG (target), res, SUBREG_PROMOTED_SIGN (target));
576 else
577 emit_move_insn (target, res);
580 /* Add sub/add overflow checking to the statement STMT.
581 CODE says whether the operation is +, or -. */
583 static void
584 expand_addsub_overflow (location_t loc, tree_code code, tree lhs,
585 tree arg0, tree arg1, bool unsr_p, bool uns0_p,
586 bool uns1_p, bool is_ubsan, tree *datap)
588 rtx res, target = NULL_RTX;
589 tree fn;
590 rtx_code_label *done_label = gen_label_rtx ();
591 rtx_code_label *do_error = gen_label_rtx ();
592 do_pending_stack_adjust ();
593 rtx op0 = expand_normal (arg0);
594 rtx op1 = expand_normal (arg1);
595 machine_mode mode = TYPE_MODE (TREE_TYPE (arg0));
596 int prec = GET_MODE_PRECISION (mode);
597 rtx sgn = immed_wide_int_const (wi::min_value (prec, SIGNED), mode);
598 bool do_xor = false;
600 if (is_ubsan)
601 gcc_assert (!unsr_p && !uns0_p && !uns1_p);
603 if (lhs)
605 target = expand_expr (lhs, NULL_RTX, VOIDmode, EXPAND_WRITE);
606 if (!is_ubsan)
607 write_complex_part (target, const0_rtx, true);
610 /* We assume both operands and result have the same precision
611 here (GET_MODE_BITSIZE (mode)), S stands for signed type
612 with that precision, U for unsigned type with that precision,
613 sgn for unsigned most significant bit in that precision.
614 s1 is signed first operand, u1 is unsigned first operand,
615 s2 is signed second operand, u2 is unsigned second operand,
616 sr is signed result, ur is unsigned result and the following
617 rules say how to compute result (which is always result of
618 the operands as if both were unsigned, cast to the right
619 signedness) and how to compute whether operation overflowed.
621 s1 + s2 -> sr
622 res = (S) ((U) s1 + (U) s2)
623 ovf = s2 < 0 ? res > s1 : res < s1 (or jump on overflow)
624 s1 - s2 -> sr
625 res = (S) ((U) s1 - (U) s2)
626 ovf = s2 < 0 ? res < s1 : res > s2 (or jump on overflow)
627 u1 + u2 -> ur
628 res = u1 + u2
629 ovf = res < u1 (or jump on carry, but RTL opts will handle it)
630 u1 - u2 -> ur
631 res = u1 - u2
632 ovf = res > u1 (or jump on carry, but RTL opts will handle it)
633 s1 + u2 -> sr
634 res = (S) ((U) s1 + u2)
635 ovf = ((U) res ^ sgn) < u2
636 s1 + u2 -> ur
637 t1 = (S) (u2 ^ sgn)
638 t2 = s1 + t1
639 res = (U) t2 ^ sgn
640 ovf = t1 < 0 ? t2 > s1 : t2 < s1 (or jump on overflow)
641 s1 - u2 -> sr
642 res = (S) ((U) s1 - u2)
643 ovf = u2 > ((U) s1 ^ sgn)
644 s1 - u2 -> ur
645 res = (U) s1 - u2
646 ovf = s1 < 0 || u2 > (U) s1
647 u1 - s2 -> sr
648 res = u1 - (U) s2
649 ovf = u1 >= ((U) s2 ^ sgn)
650 u1 - s2 -> ur
651 t1 = u1 ^ sgn
652 t2 = t1 - (U) s2
653 res = t2 ^ sgn
654 ovf = s2 < 0 ? (S) t2 < (S) t1 : (S) t2 > (S) t1 (or jump on overflow)
655 s1 + s2 -> ur
656 res = (U) s1 + (U) s2
657 ovf = s2 < 0 ? (s1 | (S) res) < 0) : (s1 & (S) res) < 0)
658 u1 + u2 -> sr
659 res = (S) (u1 + u2)
660 ovf = (U) res < u2 || res < 0
661 u1 - u2 -> sr
662 res = (S) (u1 - u2)
663 ovf = u1 >= u2 ? res < 0 : res >= 0
664 s1 - s2 -> ur
665 res = (U) s1 - (U) s2
666 ovf = s2 >= 0 ? ((s1 | (S) res) < 0) : ((s1 & (S) res) < 0) */
668 if (code == PLUS_EXPR && uns0_p && !uns1_p)
670 /* PLUS_EXPR is commutative, if operand signedness differs,
671 canonicalize to the first operand being signed and second
672 unsigned to simplify following code. */
673 std::swap (op0, op1);
674 std::swap (arg0, arg1);
675 uns0_p = false;
676 uns1_p = true;
679 /* u1 +- u2 -> ur */
680 if (uns0_p && uns1_p && unsr_p)
682 insn_code icode = optab_handler (code == PLUS_EXPR ? uaddv4_optab
683 : usubv4_optab, mode);
684 if (icode != CODE_FOR_nothing)
686 struct expand_operand ops[4];
687 rtx_insn *last = get_last_insn ();
689 res = gen_reg_rtx (mode);
690 create_output_operand (&ops[0], res, mode);
691 create_input_operand (&ops[1], op0, mode);
692 create_input_operand (&ops[2], op1, mode);
693 create_fixed_operand (&ops[3], do_error);
694 if (maybe_expand_insn (icode, 4, ops))
696 last = get_last_insn ();
697 if (profile_status_for_fn (cfun) != PROFILE_ABSENT
698 && JUMP_P (last)
699 && any_condjump_p (last)
700 && !find_reg_note (last, REG_BR_PROB, 0))
701 add_int_reg_note (last, REG_BR_PROB, PROB_VERY_UNLIKELY);
702 emit_jump (done_label);
703 goto do_error_label;
706 delete_insns_since (last);
709 /* Compute the operation. On RTL level, the addition is always
710 unsigned. */
711 res = expand_binop (mode, code == PLUS_EXPR ? add_optab : sub_optab,
712 op0, op1, NULL_RTX, false, OPTAB_LIB_WIDEN);
713 rtx tem = op0;
714 /* For PLUS_EXPR, the operation is commutative, so we can pick
715 operand to compare against. For prec <= BITS_PER_WORD, I think
716 preferring REG operand is better over CONST_INT, because
717 the CONST_INT might enlarge the instruction or CSE would need
718 to figure out we'd already loaded it into a register before.
719 For prec > BITS_PER_WORD, I think CONST_INT might be more beneficial,
720 as then the multi-word comparison can be perhaps simplified. */
721 if (code == PLUS_EXPR
722 && (prec <= BITS_PER_WORD
723 ? (CONST_SCALAR_INT_P (op0) && REG_P (op1))
724 : CONST_SCALAR_INT_P (op1)))
725 tem = op1;
726 do_compare_rtx_and_jump (res, tem, code == PLUS_EXPR ? GEU : LEU,
727 true, mode, NULL_RTX, NULL, done_label,
728 PROB_VERY_LIKELY);
729 goto do_error_label;
732 /* s1 +- u2 -> sr */
733 if (!uns0_p && uns1_p && !unsr_p)
735 /* Compute the operation. On RTL level, the addition is always
736 unsigned. */
737 res = expand_binop (mode, code == PLUS_EXPR ? add_optab : sub_optab,
738 op0, op1, NULL_RTX, false, OPTAB_LIB_WIDEN);
739 rtx tem = expand_binop (mode, add_optab,
740 code == PLUS_EXPR ? res : op0, sgn,
741 NULL_RTX, false, OPTAB_LIB_WIDEN);
742 do_compare_rtx_and_jump (tem, op1, GEU, true, mode, NULL_RTX, NULL,
743 done_label, PROB_VERY_LIKELY);
744 goto do_error_label;
747 /* s1 + u2 -> ur */
748 if (code == PLUS_EXPR && !uns0_p && uns1_p && unsr_p)
750 op1 = expand_binop (mode, add_optab, op1, sgn, NULL_RTX, false,
751 OPTAB_LIB_WIDEN);
752 /* As we've changed op1, we have to avoid using the value range
753 for the original argument. */
754 arg1 = error_mark_node;
755 do_xor = true;
756 goto do_signed;
759 /* u1 - s2 -> ur */
760 if (code == MINUS_EXPR && uns0_p && !uns1_p && unsr_p)
762 op0 = expand_binop (mode, add_optab, op0, sgn, NULL_RTX, false,
763 OPTAB_LIB_WIDEN);
764 /* As we've changed op0, we have to avoid using the value range
765 for the original argument. */
766 arg0 = error_mark_node;
767 do_xor = true;
768 goto do_signed;
771 /* s1 - u2 -> ur */
772 if (code == MINUS_EXPR && !uns0_p && uns1_p && unsr_p)
774 /* Compute the operation. On RTL level, the addition is always
775 unsigned. */
776 res = expand_binop (mode, sub_optab, op0, op1, NULL_RTX, false,
777 OPTAB_LIB_WIDEN);
778 int pos_neg = get_range_pos_neg (arg0);
779 if (pos_neg == 2)
780 /* If ARG0 is known to be always negative, this is always overflow. */
781 emit_jump (do_error);
782 else if (pos_neg == 3)
783 /* If ARG0 is not known to be always positive, check at runtime. */
784 do_compare_rtx_and_jump (op0, const0_rtx, LT, false, mode, NULL_RTX,
785 NULL, do_error, PROB_VERY_UNLIKELY);
786 do_compare_rtx_and_jump (op1, op0, LEU, true, mode, NULL_RTX, NULL,
787 done_label, PROB_VERY_LIKELY);
788 goto do_error_label;
791 /* u1 - s2 -> sr */
792 if (code == MINUS_EXPR && uns0_p && !uns1_p && !unsr_p)
794 /* Compute the operation. On RTL level, the addition is always
795 unsigned. */
796 res = expand_binop (mode, sub_optab, op0, op1, NULL_RTX, false,
797 OPTAB_LIB_WIDEN);
798 rtx tem = expand_binop (mode, add_optab, op1, sgn, NULL_RTX, false,
799 OPTAB_LIB_WIDEN);
800 do_compare_rtx_and_jump (op0, tem, LTU, true, mode, NULL_RTX, NULL,
801 done_label, PROB_VERY_LIKELY);
802 goto do_error_label;
805 /* u1 + u2 -> sr */
806 if (code == PLUS_EXPR && uns0_p && uns1_p && !unsr_p)
808 /* Compute the operation. On RTL level, the addition is always
809 unsigned. */
810 res = expand_binop (mode, add_optab, op0, op1, NULL_RTX, false,
811 OPTAB_LIB_WIDEN);
812 do_compare_rtx_and_jump (res, const0_rtx, LT, false, mode, NULL_RTX,
813 NULL, do_error, PROB_VERY_UNLIKELY);
814 rtx tem = op1;
815 /* The operation is commutative, so we can pick operand to compare
816 against. For prec <= BITS_PER_WORD, I think preferring REG operand
817 is better over CONST_INT, because the CONST_INT might enlarge the
818 instruction or CSE would need to figure out we'd already loaded it
819 into a register before. For prec > BITS_PER_WORD, I think CONST_INT
820 might be more beneficial, as then the multi-word comparison can be
821 perhaps simplified. */
822 if (prec <= BITS_PER_WORD
823 ? (CONST_SCALAR_INT_P (op1) && REG_P (op0))
824 : CONST_SCALAR_INT_P (op0))
825 tem = op0;
826 do_compare_rtx_and_jump (res, tem, GEU, true, mode, NULL_RTX, NULL,
827 done_label, PROB_VERY_LIKELY);
828 goto do_error_label;
831 /* s1 +- s2 -> ur */
832 if (!uns0_p && !uns1_p && unsr_p)
834 /* Compute the operation. On RTL level, the addition is always
835 unsigned. */
836 res = expand_binop (mode, code == PLUS_EXPR ? add_optab : sub_optab,
837 op0, op1, NULL_RTX, false, OPTAB_LIB_WIDEN);
838 int pos_neg = get_range_pos_neg (arg1);
839 if (code == PLUS_EXPR)
841 int pos_neg0 = get_range_pos_neg (arg0);
842 if (pos_neg0 != 3 && pos_neg == 3)
844 std::swap (op0, op1);
845 pos_neg = pos_neg0;
848 rtx tem;
849 if (pos_neg != 3)
851 tem = expand_binop (mode, ((pos_neg == 1) ^ (code == MINUS_EXPR))
852 ? and_optab : ior_optab,
853 op0, res, NULL_RTX, false, OPTAB_LIB_WIDEN);
854 do_compare_rtx_and_jump (tem, const0_rtx, GE, false, mode, NULL,
855 NULL, done_label, PROB_VERY_LIKELY);
857 else
859 rtx_code_label *do_ior_label = gen_label_rtx ();
860 do_compare_rtx_and_jump (op1, const0_rtx,
861 code == MINUS_EXPR ? GE : LT, false, mode,
862 NULL_RTX, NULL, do_ior_label,
863 PROB_EVEN);
864 tem = expand_binop (mode, and_optab, op0, res, NULL_RTX, false,
865 OPTAB_LIB_WIDEN);
866 do_compare_rtx_and_jump (tem, const0_rtx, GE, false, mode, NULL_RTX,
867 NULL, done_label, PROB_VERY_LIKELY);
868 emit_jump (do_error);
869 emit_label (do_ior_label);
870 tem = expand_binop (mode, ior_optab, op0, res, NULL_RTX, false,
871 OPTAB_LIB_WIDEN);
872 do_compare_rtx_and_jump (tem, const0_rtx, GE, false, mode, NULL_RTX,
873 NULL, done_label, PROB_VERY_LIKELY);
875 goto do_error_label;
878 /* u1 - u2 -> sr */
879 if (code == MINUS_EXPR && uns0_p && uns1_p && !unsr_p)
881 /* Compute the operation. On RTL level, the addition is always
882 unsigned. */
883 res = expand_binop (mode, sub_optab, op0, op1, NULL_RTX, false,
884 OPTAB_LIB_WIDEN);
885 rtx_code_label *op0_geu_op1 = gen_label_rtx ();
886 do_compare_rtx_and_jump (op0, op1, GEU, true, mode, NULL_RTX, NULL,
887 op0_geu_op1, PROB_EVEN);
888 do_compare_rtx_and_jump (res, const0_rtx, LT, false, mode, NULL_RTX,
889 NULL, done_label, PROB_VERY_LIKELY);
890 emit_jump (do_error);
891 emit_label (op0_geu_op1);
892 do_compare_rtx_and_jump (res, const0_rtx, GE, false, mode, NULL_RTX,
893 NULL, done_label, PROB_VERY_LIKELY);
894 goto do_error_label;
897 gcc_assert (!uns0_p && !uns1_p && !unsr_p);
899 /* s1 +- s2 -> sr */
900 do_signed:
902 insn_code icode = optab_handler (code == PLUS_EXPR ? addv4_optab
903 : subv4_optab, mode);
904 if (icode != CODE_FOR_nothing)
906 struct expand_operand ops[4];
907 rtx_insn *last = get_last_insn ();
909 res = gen_reg_rtx (mode);
910 create_output_operand (&ops[0], res, mode);
911 create_input_operand (&ops[1], op0, mode);
912 create_input_operand (&ops[2], op1, mode);
913 create_fixed_operand (&ops[3], do_error);
914 if (maybe_expand_insn (icode, 4, ops))
916 last = get_last_insn ();
917 if (profile_status_for_fn (cfun) != PROFILE_ABSENT
918 && JUMP_P (last)
919 && any_condjump_p (last)
920 && !find_reg_note (last, REG_BR_PROB, 0))
921 add_int_reg_note (last, REG_BR_PROB, PROB_VERY_UNLIKELY);
922 emit_jump (done_label);
923 goto do_error_label;
926 delete_insns_since (last);
929 /* Compute the operation. On RTL level, the addition is always
930 unsigned. */
931 res = expand_binop (mode, code == PLUS_EXPR ? add_optab : sub_optab,
932 op0, op1, NULL_RTX, false, OPTAB_LIB_WIDEN);
934 /* If we can prove that one of the arguments (for MINUS_EXPR only
935 the second operand, as subtraction is not commutative) is always
936 non-negative or always negative, we can do just one comparison
937 and conditional jump. */
938 int pos_neg = get_range_pos_neg (arg1);
939 if (code == PLUS_EXPR)
941 int pos_neg0 = get_range_pos_neg (arg0);
942 if (pos_neg0 != 3 && pos_neg == 3)
944 std::swap (op0, op1);
945 pos_neg = pos_neg0;
949 /* Addition overflows if and only if the two operands have the same sign,
950 and the result has the opposite sign. Subtraction overflows if and
951 only if the two operands have opposite sign, and the subtrahend has
952 the same sign as the result. Here 0 is counted as positive. */
953 if (pos_neg == 3)
955 /* Compute op0 ^ op1 (operands have opposite sign). */
956 rtx op_xor = expand_binop (mode, xor_optab, op0, op1, NULL_RTX, false,
957 OPTAB_LIB_WIDEN);
959 /* Compute res ^ op1 (result and 2nd operand have opposite sign). */
960 rtx res_xor = expand_binop (mode, xor_optab, res, op1, NULL_RTX, false,
961 OPTAB_LIB_WIDEN);
963 rtx tem;
964 if (code == PLUS_EXPR)
966 /* Compute (res ^ op1) & ~(op0 ^ op1). */
967 tem = expand_unop (mode, one_cmpl_optab, op_xor, NULL_RTX, false);
968 tem = expand_binop (mode, and_optab, res_xor, tem, NULL_RTX, false,
969 OPTAB_LIB_WIDEN);
971 else
973 /* Compute (op0 ^ op1) & ~(res ^ op1). */
974 tem = expand_unop (mode, one_cmpl_optab, res_xor, NULL_RTX, false);
975 tem = expand_binop (mode, and_optab, op_xor, tem, NULL_RTX, false,
976 OPTAB_LIB_WIDEN);
979 /* No overflow if the result has bit sign cleared. */
980 do_compare_rtx_and_jump (tem, const0_rtx, GE, false, mode, NULL_RTX,
981 NULL, done_label, PROB_VERY_LIKELY);
984 /* Compare the result of the operation with the first operand.
985 No overflow for addition if second operand is positive and result
986 is larger or second operand is negative and result is smaller.
987 Likewise for subtraction with sign of second operand flipped. */
988 else
989 do_compare_rtx_and_jump (res, op0,
990 (pos_neg == 1) ^ (code == MINUS_EXPR) ? GE : LE,
991 false, mode, NULL_RTX, NULL, done_label,
992 PROB_VERY_LIKELY);
995 do_error_label:
996 emit_label (do_error);
997 if (is_ubsan)
999 /* Expand the ubsan builtin call. */
1000 push_temp_slots ();
1001 fn = ubsan_build_overflow_builtin (code, loc, TREE_TYPE (arg0),
1002 arg0, arg1, datap);
1003 expand_normal (fn);
1004 pop_temp_slots ();
1005 do_pending_stack_adjust ();
1007 else if (lhs)
1008 expand_arith_set_overflow (lhs, target);
1010 /* We're done. */
1011 emit_label (done_label);
1013 if (lhs)
1015 if (is_ubsan)
1016 expand_ubsan_result_store (target, res);
1017 else
1019 if (do_xor)
1020 res = expand_binop (mode, add_optab, res, sgn, NULL_RTX, false,
1021 OPTAB_LIB_WIDEN);
1023 expand_arith_overflow_result_store (lhs, target, mode, res);
1028 /* Add negate overflow checking to the statement STMT. */
1030 static void
1031 expand_neg_overflow (location_t loc, tree lhs, tree arg1, bool is_ubsan,
1032 tree *datap)
1034 rtx res, op1;
1035 tree fn;
1036 rtx_code_label *done_label, *do_error;
1037 rtx target = NULL_RTX;
1039 done_label = gen_label_rtx ();
1040 do_error = gen_label_rtx ();
1042 do_pending_stack_adjust ();
1043 op1 = expand_normal (arg1);
1045 machine_mode mode = TYPE_MODE (TREE_TYPE (arg1));
1046 if (lhs)
1048 target = expand_expr (lhs, NULL_RTX, VOIDmode, EXPAND_WRITE);
1049 if (!is_ubsan)
1050 write_complex_part (target, const0_rtx, true);
1053 enum insn_code icode = optab_handler (negv3_optab, mode);
1054 if (icode != CODE_FOR_nothing)
1056 struct expand_operand ops[3];
1057 rtx_insn *last = get_last_insn ();
1059 res = gen_reg_rtx (mode);
1060 create_output_operand (&ops[0], res, mode);
1061 create_input_operand (&ops[1], op1, mode);
1062 create_fixed_operand (&ops[2], do_error);
1063 if (maybe_expand_insn (icode, 3, ops))
1065 last = get_last_insn ();
1066 if (profile_status_for_fn (cfun) != PROFILE_ABSENT
1067 && JUMP_P (last)
1068 && any_condjump_p (last)
1069 && !find_reg_note (last, REG_BR_PROB, 0))
1070 add_int_reg_note (last, REG_BR_PROB, PROB_VERY_UNLIKELY);
1071 emit_jump (done_label);
1073 else
1075 delete_insns_since (last);
1076 icode = CODE_FOR_nothing;
1080 if (icode == CODE_FOR_nothing)
1082 /* Compute the operation. On RTL level, the addition is always
1083 unsigned. */
1084 res = expand_unop (mode, neg_optab, op1, NULL_RTX, false);
1086 /* Compare the operand with the most negative value. */
1087 rtx minv = expand_normal (TYPE_MIN_VALUE (TREE_TYPE (arg1)));
1088 do_compare_rtx_and_jump (op1, minv, NE, true, mode, NULL_RTX, NULL,
1089 done_label, PROB_VERY_LIKELY);
1092 emit_label (do_error);
1093 if (is_ubsan)
1095 /* Expand the ubsan builtin call. */
1096 push_temp_slots ();
1097 fn = ubsan_build_overflow_builtin (NEGATE_EXPR, loc, TREE_TYPE (arg1),
1098 arg1, NULL_TREE, datap);
1099 expand_normal (fn);
1100 pop_temp_slots ();
1101 do_pending_stack_adjust ();
1103 else if (lhs)
1104 expand_arith_set_overflow (lhs, target);
1106 /* We're done. */
1107 emit_label (done_label);
1109 if (lhs)
1111 if (is_ubsan)
1112 expand_ubsan_result_store (target, res);
1113 else
1114 expand_arith_overflow_result_store (lhs, target, mode, res);
1118 /* Add mul overflow checking to the statement STMT. */
1120 static void
1121 expand_mul_overflow (location_t loc, tree lhs, tree arg0, tree arg1,
1122 bool unsr_p, bool uns0_p, bool uns1_p, bool is_ubsan,
1123 tree *datap)
1125 rtx res, op0, op1;
1126 tree fn, type;
1127 rtx_code_label *done_label, *do_error;
1128 rtx target = NULL_RTX;
1129 signop sign;
1130 enum insn_code icode;
1132 done_label = gen_label_rtx ();
1133 do_error = gen_label_rtx ();
1135 do_pending_stack_adjust ();
1136 op0 = expand_normal (arg0);
1137 op1 = expand_normal (arg1);
1139 machine_mode mode = TYPE_MODE (TREE_TYPE (arg0));
1140 bool uns = unsr_p;
1141 if (lhs)
1143 target = expand_expr (lhs, NULL_RTX, VOIDmode, EXPAND_WRITE);
1144 if (!is_ubsan)
1145 write_complex_part (target, const0_rtx, true);
1148 if (is_ubsan)
1149 gcc_assert (!unsr_p && !uns0_p && !uns1_p);
1151 /* We assume both operands and result have the same precision
1152 here (GET_MODE_BITSIZE (mode)), S stands for signed type
1153 with that precision, U for unsigned type with that precision,
1154 sgn for unsigned most significant bit in that precision.
1155 s1 is signed first operand, u1 is unsigned first operand,
1156 s2 is signed second operand, u2 is unsigned second operand,
1157 sr is signed result, ur is unsigned result and the following
1158 rules say how to compute result (which is always result of
1159 the operands as if both were unsigned, cast to the right
1160 signedness) and how to compute whether operation overflowed.
1161 main_ovf (false) stands for jump on signed multiplication
1162 overflow or the main algorithm with uns == false.
1163 main_ovf (true) stands for jump on unsigned multiplication
1164 overflow or the main algorithm with uns == true.
1166 s1 * s2 -> sr
1167 res = (S) ((U) s1 * (U) s2)
1168 ovf = main_ovf (false)
1169 u1 * u2 -> ur
1170 res = u1 * u2
1171 ovf = main_ovf (true)
1172 s1 * u2 -> ur
1173 res = (U) s1 * u2
1174 ovf = (s1 < 0 && u2) || main_ovf (true)
1175 u1 * u2 -> sr
1176 res = (S) (u1 * u2)
1177 ovf = res < 0 || main_ovf (true)
1178 s1 * u2 -> sr
1179 res = (S) ((U) s1 * u2)
1180 ovf = (S) u2 >= 0 ? main_ovf (false)
1181 : (s1 != 0 && (s1 != -1 || u2 != (U) res))
1182 s1 * s2 -> ur
1183 t1 = (s1 & s2) < 0 ? (-(U) s1) : ((U) s1)
1184 t2 = (s1 & s2) < 0 ? (-(U) s2) : ((U) s2)
1185 res = t1 * t2
1186 ovf = (s1 ^ s2) < 0 ? (s1 && s2) : main_ovf (true) */
1188 if (uns0_p && !uns1_p)
1190 /* Multiplication is commutative, if operand signedness differs,
1191 canonicalize to the first operand being signed and second
1192 unsigned to simplify following code. */
1193 std::swap (op0, op1);
1194 std::swap (arg0, arg1);
1195 uns0_p = false;
1196 uns1_p = true;
1199 int pos_neg0 = get_range_pos_neg (arg0);
1200 int pos_neg1 = get_range_pos_neg (arg1);
1202 /* s1 * u2 -> ur */
1203 if (!uns0_p && uns1_p && unsr_p)
1205 switch (pos_neg0)
1207 case 1:
1208 /* If s1 is non-negative, just perform normal u1 * u2 -> ur. */
1209 goto do_main;
1210 case 2:
1211 /* If s1 is negative, avoid the main code, just multiply and
1212 signal overflow if op1 is not 0. */
1213 struct separate_ops ops;
1214 ops.code = MULT_EXPR;
1215 ops.type = TREE_TYPE (arg1);
1216 ops.op0 = make_tree (ops.type, op0);
1217 ops.op1 = make_tree (ops.type, op1);
1218 ops.op2 = NULL_TREE;
1219 ops.location = loc;
1220 res = expand_expr_real_2 (&ops, NULL_RTX, mode, EXPAND_NORMAL);
1221 do_compare_rtx_and_jump (op1, const0_rtx, EQ, true, mode, NULL_RTX,
1222 NULL, done_label, PROB_VERY_LIKELY);
1223 goto do_error_label;
1224 case 3:
1225 rtx_code_label *do_main_label;
1226 do_main_label = gen_label_rtx ();
1227 do_compare_rtx_and_jump (op0, const0_rtx, GE, false, mode, NULL_RTX,
1228 NULL, do_main_label, PROB_VERY_LIKELY);
1229 do_compare_rtx_and_jump (op1, const0_rtx, EQ, true, mode, NULL_RTX,
1230 NULL, do_main_label, PROB_VERY_LIKELY);
1231 expand_arith_set_overflow (lhs, target);
1232 emit_label (do_main_label);
1233 goto do_main;
1234 default:
1235 gcc_unreachable ();
1239 /* u1 * u2 -> sr */
1240 if (uns0_p && uns1_p && !unsr_p)
1242 uns = true;
1243 /* Rest of handling of this case after res is computed. */
1244 goto do_main;
1247 /* s1 * u2 -> sr */
1248 if (!uns0_p && uns1_p && !unsr_p)
1250 switch (pos_neg1)
1252 case 1:
1253 goto do_main;
1254 case 2:
1255 /* If (S) u2 is negative (i.e. u2 is larger than maximum of S,
1256 avoid the main code, just multiply and signal overflow
1257 unless 0 * u2 or -1 * ((U) Smin). */
1258 struct separate_ops ops;
1259 ops.code = MULT_EXPR;
1260 ops.type = TREE_TYPE (arg1);
1261 ops.op0 = make_tree (ops.type, op0);
1262 ops.op1 = make_tree (ops.type, op1);
1263 ops.op2 = NULL_TREE;
1264 ops.location = loc;
1265 res = expand_expr_real_2 (&ops, NULL_RTX, mode, EXPAND_NORMAL);
1266 do_compare_rtx_and_jump (op0, const0_rtx, EQ, true, mode, NULL_RTX,
1267 NULL, done_label, PROB_VERY_LIKELY);
1268 do_compare_rtx_and_jump (op0, constm1_rtx, NE, true, mode, NULL_RTX,
1269 NULL, do_error, PROB_VERY_UNLIKELY);
1270 int prec;
1271 prec = GET_MODE_PRECISION (mode);
1272 rtx sgn;
1273 sgn = immed_wide_int_const (wi::min_value (prec, SIGNED), mode);
1274 do_compare_rtx_and_jump (op1, sgn, EQ, true, mode, NULL_RTX,
1275 NULL, done_label, PROB_VERY_LIKELY);
1276 goto do_error_label;
1277 case 3:
1278 /* Rest of handling of this case after res is computed. */
1279 goto do_main;
1280 default:
1281 gcc_unreachable ();
1285 /* s1 * s2 -> ur */
1286 if (!uns0_p && !uns1_p && unsr_p)
1288 rtx tem, tem2;
1289 switch (pos_neg0 | pos_neg1)
1291 case 1: /* Both operands known to be non-negative. */
1292 goto do_main;
1293 case 2: /* Both operands known to be negative. */
1294 op0 = expand_unop (mode, neg_optab, op0, NULL_RTX, false);
1295 op1 = expand_unop (mode, neg_optab, op1, NULL_RTX, false);
1296 /* Avoid looking at arg0/arg1 ranges, as we've changed
1297 the arguments. */
1298 arg0 = error_mark_node;
1299 arg1 = error_mark_node;
1300 goto do_main;
1301 case 3:
1302 if ((pos_neg0 ^ pos_neg1) == 3)
1304 /* If one operand is known to be negative and the other
1305 non-negative, this overflows always, unless the non-negative
1306 one is 0. Just do normal multiply and set overflow
1307 unless one of the operands is 0. */
1308 struct separate_ops ops;
1309 ops.code = MULT_EXPR;
1310 ops.type
1311 = build_nonstandard_integer_type (GET_MODE_PRECISION (mode),
1313 ops.op0 = make_tree (ops.type, op0);
1314 ops.op1 = make_tree (ops.type, op1);
1315 ops.op2 = NULL_TREE;
1316 ops.location = loc;
1317 res = expand_expr_real_2 (&ops, NULL_RTX, mode, EXPAND_NORMAL);
1318 tem = expand_binop (mode, and_optab, op0, op1, NULL_RTX, false,
1319 OPTAB_LIB_WIDEN);
1320 do_compare_rtx_and_jump (tem, const0_rtx, EQ, true, mode,
1321 NULL_RTX, NULL, done_label,
1322 PROB_VERY_LIKELY);
1323 goto do_error_label;
1325 /* The general case, do all the needed comparisons at runtime. */
1326 rtx_code_label *do_main_label, *after_negate_label;
1327 rtx rop0, rop1;
1328 rop0 = gen_reg_rtx (mode);
1329 rop1 = gen_reg_rtx (mode);
1330 emit_move_insn (rop0, op0);
1331 emit_move_insn (rop1, op1);
1332 op0 = rop0;
1333 op1 = rop1;
1334 do_main_label = gen_label_rtx ();
1335 after_negate_label = gen_label_rtx ();
1336 tem = expand_binop (mode, and_optab, op0, op1, NULL_RTX, false,
1337 OPTAB_LIB_WIDEN);
1338 do_compare_rtx_and_jump (tem, const0_rtx, GE, false, mode, NULL_RTX,
1339 NULL, after_negate_label, PROB_VERY_LIKELY);
1340 /* Both arguments negative here, negate them and continue with
1341 normal unsigned overflow checking multiplication. */
1342 emit_move_insn (op0, expand_unop (mode, neg_optab, op0,
1343 NULL_RTX, false));
1344 emit_move_insn (op1, expand_unop (mode, neg_optab, op1,
1345 NULL_RTX, false));
1346 /* Avoid looking at arg0/arg1 ranges, as we might have changed
1347 the arguments. */
1348 arg0 = error_mark_node;
1349 arg1 = error_mark_node;
1350 emit_jump (do_main_label);
1351 emit_label (after_negate_label);
1352 tem2 = expand_binop (mode, xor_optab, op0, op1, NULL_RTX, false,
1353 OPTAB_LIB_WIDEN);
1354 do_compare_rtx_and_jump (tem2, const0_rtx, GE, false, mode, NULL_RTX,
1355 NULL, do_main_label, PROB_VERY_LIKELY);
1356 /* One argument is negative here, the other positive. This
1357 overflows always, unless one of the arguments is 0. But
1358 if e.g. s2 is 0, (U) s1 * 0 doesn't overflow, whatever s1
1359 is, thus we can keep do_main code oring in overflow as is. */
1360 do_compare_rtx_and_jump (tem, const0_rtx, EQ, true, mode, NULL_RTX,
1361 NULL, do_main_label, PROB_VERY_LIKELY);
1362 expand_arith_set_overflow (lhs, target);
1363 emit_label (do_main_label);
1364 goto do_main;
1365 default:
1366 gcc_unreachable ();
1370 do_main:
1371 type = build_nonstandard_integer_type (GET_MODE_PRECISION (mode), uns);
1372 sign = uns ? UNSIGNED : SIGNED;
1373 icode = optab_handler (uns ? umulv4_optab : mulv4_optab, mode);
1374 if (icode != CODE_FOR_nothing)
1376 struct expand_operand ops[4];
1377 rtx_insn *last = get_last_insn ();
1379 res = gen_reg_rtx (mode);
1380 create_output_operand (&ops[0], res, mode);
1381 create_input_operand (&ops[1], op0, mode);
1382 create_input_operand (&ops[2], op1, mode);
1383 create_fixed_operand (&ops[3], do_error);
1384 if (maybe_expand_insn (icode, 4, ops))
1386 last = get_last_insn ();
1387 if (profile_status_for_fn (cfun) != PROFILE_ABSENT
1388 && JUMP_P (last)
1389 && any_condjump_p (last)
1390 && !find_reg_note (last, REG_BR_PROB, 0))
1391 add_int_reg_note (last, REG_BR_PROB, PROB_VERY_UNLIKELY);
1392 emit_jump (done_label);
1394 else
1396 delete_insns_since (last);
1397 icode = CODE_FOR_nothing;
1401 if (icode == CODE_FOR_nothing)
1403 struct separate_ops ops;
1404 int prec = GET_MODE_PRECISION (mode);
1405 machine_mode hmode = mode_for_size (prec / 2, MODE_INT, 1);
1406 ops.op0 = make_tree (type, op0);
1407 ops.op1 = make_tree (type, op1);
1408 ops.op2 = NULL_TREE;
1409 ops.location = loc;
1410 if (GET_MODE_2XWIDER_MODE (mode) != VOIDmode
1411 && targetm.scalar_mode_supported_p (GET_MODE_2XWIDER_MODE (mode)))
1413 machine_mode wmode = GET_MODE_2XWIDER_MODE (mode);
1414 ops.code = WIDEN_MULT_EXPR;
1415 ops.type
1416 = build_nonstandard_integer_type (GET_MODE_PRECISION (wmode), uns);
1418 res = expand_expr_real_2 (&ops, NULL_RTX, wmode, EXPAND_NORMAL);
1419 rtx hipart = expand_shift (RSHIFT_EXPR, wmode, res, prec,
1420 NULL_RTX, uns);
1421 hipart = convert_modes (mode, wmode, hipart, uns);
1422 res = convert_modes (mode, wmode, res, uns);
1423 if (uns)
1424 /* For the unsigned multiplication, there was overflow if
1425 HIPART is non-zero. */
1426 do_compare_rtx_and_jump (hipart, const0_rtx, EQ, true, mode,
1427 NULL_RTX, NULL, done_label,
1428 PROB_VERY_LIKELY);
1429 else
1431 rtx signbit = expand_shift (RSHIFT_EXPR, mode, res, prec - 1,
1432 NULL_RTX, 0);
1433 /* RES is low half of the double width result, HIPART
1434 the high half. There was overflow if
1435 HIPART is different from RES < 0 ? -1 : 0. */
1436 do_compare_rtx_and_jump (signbit, hipart, EQ, true, mode,
1437 NULL_RTX, NULL, done_label,
1438 PROB_VERY_LIKELY);
1441 else if (hmode != BLKmode && 2 * GET_MODE_PRECISION (hmode) == prec)
1443 rtx_code_label *large_op0 = gen_label_rtx ();
1444 rtx_code_label *small_op0_large_op1 = gen_label_rtx ();
1445 rtx_code_label *one_small_one_large = gen_label_rtx ();
1446 rtx_code_label *both_ops_large = gen_label_rtx ();
1447 rtx_code_label *after_hipart_neg = uns ? NULL : gen_label_rtx ();
1448 rtx_code_label *after_lopart_neg = uns ? NULL : gen_label_rtx ();
1449 rtx_code_label *do_overflow = gen_label_rtx ();
1450 rtx_code_label *hipart_different = uns ? NULL : gen_label_rtx ();
1452 unsigned int hprec = GET_MODE_PRECISION (hmode);
1453 rtx hipart0 = expand_shift (RSHIFT_EXPR, mode, op0, hprec,
1454 NULL_RTX, uns);
1455 hipart0 = convert_modes (hmode, mode, hipart0, uns);
1456 rtx lopart0 = convert_modes (hmode, mode, op0, uns);
1457 rtx signbit0 = const0_rtx;
1458 if (!uns)
1459 signbit0 = expand_shift (RSHIFT_EXPR, hmode, lopart0, hprec - 1,
1460 NULL_RTX, 0);
1461 rtx hipart1 = expand_shift (RSHIFT_EXPR, mode, op1, hprec,
1462 NULL_RTX, uns);
1463 hipart1 = convert_modes (hmode, mode, hipart1, uns);
1464 rtx lopart1 = convert_modes (hmode, mode, op1, uns);
1465 rtx signbit1 = const0_rtx;
1466 if (!uns)
1467 signbit1 = expand_shift (RSHIFT_EXPR, hmode, lopart1, hprec - 1,
1468 NULL_RTX, 0);
1470 res = gen_reg_rtx (mode);
1472 /* True if op0 resp. op1 are known to be in the range of
1473 halfstype. */
1474 bool op0_small_p = false;
1475 bool op1_small_p = false;
1476 /* True if op0 resp. op1 are known to have all zeros or all ones
1477 in the upper half of bits, but are not known to be
1478 op{0,1}_small_p. */
1479 bool op0_medium_p = false;
1480 bool op1_medium_p = false;
1481 /* -1 if op{0,1} is known to be negative, 0 if it is known to be
1482 nonnegative, 1 if unknown. */
1483 int op0_sign = 1;
1484 int op1_sign = 1;
1486 if (pos_neg0 == 1)
1487 op0_sign = 0;
1488 else if (pos_neg0 == 2)
1489 op0_sign = -1;
1490 if (pos_neg1 == 1)
1491 op1_sign = 0;
1492 else if (pos_neg1 == 2)
1493 op1_sign = -1;
1495 unsigned int mprec0 = prec;
1496 if (arg0 != error_mark_node)
1497 mprec0 = get_min_precision (arg0, sign);
1498 if (mprec0 <= hprec)
1499 op0_small_p = true;
1500 else if (!uns && mprec0 <= hprec + 1)
1501 op0_medium_p = true;
1502 unsigned int mprec1 = prec;
1503 if (arg1 != error_mark_node)
1504 mprec1 = get_min_precision (arg1, sign);
1505 if (mprec1 <= hprec)
1506 op1_small_p = true;
1507 else if (!uns && mprec1 <= hprec + 1)
1508 op1_medium_p = true;
1510 int smaller_sign = 1;
1511 int larger_sign = 1;
1512 if (op0_small_p)
1514 smaller_sign = op0_sign;
1515 larger_sign = op1_sign;
1517 else if (op1_small_p)
1519 smaller_sign = op1_sign;
1520 larger_sign = op0_sign;
1522 else if (op0_sign == op1_sign)
1524 smaller_sign = op0_sign;
1525 larger_sign = op0_sign;
1528 if (!op0_small_p)
1529 do_compare_rtx_and_jump (signbit0, hipart0, NE, true, hmode,
1530 NULL_RTX, NULL, large_op0,
1531 PROB_UNLIKELY);
1533 if (!op1_small_p)
1534 do_compare_rtx_and_jump (signbit1, hipart1, NE, true, hmode,
1535 NULL_RTX, NULL, small_op0_large_op1,
1536 PROB_UNLIKELY);
1538 /* If both op0 and op1 are sign (!uns) or zero (uns) extended from
1539 hmode to mode, the multiplication will never overflow. We can
1540 do just one hmode x hmode => mode widening multiplication. */
1541 rtx lopart0s = lopart0, lopart1s = lopart1;
1542 if (GET_CODE (lopart0) == SUBREG)
1544 lopart0s = shallow_copy_rtx (lopart0);
1545 SUBREG_PROMOTED_VAR_P (lopart0s) = 1;
1546 SUBREG_PROMOTED_SET (lopart0s, uns ? SRP_UNSIGNED : SRP_SIGNED);
1548 if (GET_CODE (lopart1) == SUBREG)
1550 lopart1s = shallow_copy_rtx (lopart1);
1551 SUBREG_PROMOTED_VAR_P (lopart1s) = 1;
1552 SUBREG_PROMOTED_SET (lopart1s, uns ? SRP_UNSIGNED : SRP_SIGNED);
1554 tree halfstype = build_nonstandard_integer_type (hprec, uns);
1555 ops.op0 = make_tree (halfstype, lopart0s);
1556 ops.op1 = make_tree (halfstype, lopart1s);
1557 ops.code = WIDEN_MULT_EXPR;
1558 ops.type = type;
1559 rtx thisres
1560 = expand_expr_real_2 (&ops, NULL_RTX, mode, EXPAND_NORMAL);
1561 emit_move_insn (res, thisres);
1562 emit_jump (done_label);
1564 emit_label (small_op0_large_op1);
1566 /* If op0 is sign (!uns) or zero (uns) extended from hmode to mode,
1567 but op1 is not, just swap the arguments and handle it as op1
1568 sign/zero extended, op0 not. */
1569 rtx larger = gen_reg_rtx (mode);
1570 rtx hipart = gen_reg_rtx (hmode);
1571 rtx lopart = gen_reg_rtx (hmode);
1572 emit_move_insn (larger, op1);
1573 emit_move_insn (hipart, hipart1);
1574 emit_move_insn (lopart, lopart0);
1575 emit_jump (one_small_one_large);
1577 emit_label (large_op0);
1579 if (!op1_small_p)
1580 do_compare_rtx_and_jump (signbit1, hipart1, NE, true, hmode,
1581 NULL_RTX, NULL, both_ops_large,
1582 PROB_UNLIKELY);
1584 /* If op1 is sign (!uns) or zero (uns) extended from hmode to mode,
1585 but op0 is not, prepare larger, hipart and lopart pseudos and
1586 handle it together with small_op0_large_op1. */
1587 emit_move_insn (larger, op0);
1588 emit_move_insn (hipart, hipart0);
1589 emit_move_insn (lopart, lopart1);
1591 emit_label (one_small_one_large);
1593 /* lopart is the low part of the operand that is sign extended
1594 to mode, larger is the other operand, hipart is the
1595 high part of larger and lopart0 and lopart1 are the low parts
1596 of both operands.
1597 We perform lopart0 * lopart1 and lopart * hipart widening
1598 multiplications. */
1599 tree halfutype = build_nonstandard_integer_type (hprec, 1);
1600 ops.op0 = make_tree (halfutype, lopart0);
1601 ops.op1 = make_tree (halfutype, lopart1);
1602 rtx lo0xlo1
1603 = expand_expr_real_2 (&ops, NULL_RTX, mode, EXPAND_NORMAL);
1605 ops.op0 = make_tree (halfutype, lopart);
1606 ops.op1 = make_tree (halfutype, hipart);
1607 rtx loxhi = gen_reg_rtx (mode);
1608 rtx tem = expand_expr_real_2 (&ops, NULL_RTX, mode, EXPAND_NORMAL);
1609 emit_move_insn (loxhi, tem);
1611 if (!uns)
1613 /* if (hipart < 0) loxhi -= lopart << (bitsize / 2); */
1614 if (larger_sign == 0)
1615 emit_jump (after_hipart_neg);
1616 else if (larger_sign != -1)
1617 do_compare_rtx_and_jump (hipart, const0_rtx, GE, false, hmode,
1618 NULL_RTX, NULL, after_hipart_neg,
1619 PROB_EVEN);
1621 tem = convert_modes (mode, hmode, lopart, 1);
1622 tem = expand_shift (LSHIFT_EXPR, mode, tem, hprec, NULL_RTX, 1);
1623 tem = expand_simple_binop (mode, MINUS, loxhi, tem, NULL_RTX,
1624 1, OPTAB_DIRECT);
1625 emit_move_insn (loxhi, tem);
1627 emit_label (after_hipart_neg);
1629 /* if (lopart < 0) loxhi -= larger; */
1630 if (smaller_sign == 0)
1631 emit_jump (after_lopart_neg);
1632 else if (smaller_sign != -1)
1633 do_compare_rtx_and_jump (lopart, const0_rtx, GE, false, hmode,
1634 NULL_RTX, NULL, after_lopart_neg,
1635 PROB_EVEN);
1637 tem = expand_simple_binop (mode, MINUS, loxhi, larger, NULL_RTX,
1638 1, OPTAB_DIRECT);
1639 emit_move_insn (loxhi, tem);
1641 emit_label (after_lopart_neg);
1644 /* loxhi += (uns) lo0xlo1 >> (bitsize / 2); */
1645 tem = expand_shift (RSHIFT_EXPR, mode, lo0xlo1, hprec, NULL_RTX, 1);
1646 tem = expand_simple_binop (mode, PLUS, loxhi, tem, NULL_RTX,
1647 1, OPTAB_DIRECT);
1648 emit_move_insn (loxhi, tem);
1650 /* if (loxhi >> (bitsize / 2)
1651 == (hmode) loxhi >> (bitsize / 2 - 1)) (if !uns)
1652 if (loxhi >> (bitsize / 2) == 0 (if uns). */
1653 rtx hipartloxhi = expand_shift (RSHIFT_EXPR, mode, loxhi, hprec,
1654 NULL_RTX, 0);
1655 hipartloxhi = convert_modes (hmode, mode, hipartloxhi, 0);
1656 rtx signbitloxhi = const0_rtx;
1657 if (!uns)
1658 signbitloxhi = expand_shift (RSHIFT_EXPR, hmode,
1659 convert_modes (hmode, mode,
1660 loxhi, 0),
1661 hprec - 1, NULL_RTX, 0);
1663 do_compare_rtx_and_jump (signbitloxhi, hipartloxhi, NE, true, hmode,
1664 NULL_RTX, NULL, do_overflow,
1665 PROB_VERY_UNLIKELY);
1667 /* res = (loxhi << (bitsize / 2)) | (hmode) lo0xlo1; */
1668 rtx loxhishifted = expand_shift (LSHIFT_EXPR, mode, loxhi, hprec,
1669 NULL_RTX, 1);
1670 tem = convert_modes (mode, hmode,
1671 convert_modes (hmode, mode, lo0xlo1, 1), 1);
1673 tem = expand_simple_binop (mode, IOR, loxhishifted, tem, res,
1674 1, OPTAB_DIRECT);
1675 if (tem != res)
1676 emit_move_insn (res, tem);
1677 emit_jump (done_label);
1679 emit_label (both_ops_large);
1681 /* If both operands are large (not sign (!uns) or zero (uns)
1682 extended from hmode), then perform the full multiplication
1683 which will be the result of the operation.
1684 The only cases which don't overflow are for signed multiplication
1685 some cases where both hipart0 and highpart1 are 0 or -1.
1686 For unsigned multiplication when high parts are both non-zero
1687 this overflows always. */
1688 ops.code = MULT_EXPR;
1689 ops.op0 = make_tree (type, op0);
1690 ops.op1 = make_tree (type, op1);
1691 tem = expand_expr_real_2 (&ops, NULL_RTX, mode, EXPAND_NORMAL);
1692 emit_move_insn (res, tem);
1694 if (!uns)
1696 if (!op0_medium_p)
1698 tem = expand_simple_binop (hmode, PLUS, hipart0, const1_rtx,
1699 NULL_RTX, 1, OPTAB_DIRECT);
1700 do_compare_rtx_and_jump (tem, const1_rtx, GTU, true, hmode,
1701 NULL_RTX, NULL, do_error,
1702 PROB_VERY_UNLIKELY);
1705 if (!op1_medium_p)
1707 tem = expand_simple_binop (hmode, PLUS, hipart1, const1_rtx,
1708 NULL_RTX, 1, OPTAB_DIRECT);
1709 do_compare_rtx_and_jump (tem, const1_rtx, GTU, true, hmode,
1710 NULL_RTX, NULL, do_error,
1711 PROB_VERY_UNLIKELY);
1714 /* At this point hipart{0,1} are both in [-1, 0]. If they are
1715 the same, overflow happened if res is negative, if they are
1716 different, overflow happened if res is positive. */
1717 if (op0_sign != 1 && op1_sign != 1 && op0_sign != op1_sign)
1718 emit_jump (hipart_different);
1719 else if (op0_sign == 1 || op1_sign == 1)
1720 do_compare_rtx_and_jump (hipart0, hipart1, NE, true, hmode,
1721 NULL_RTX, NULL, hipart_different,
1722 PROB_EVEN);
1724 do_compare_rtx_and_jump (res, const0_rtx, LT, false, mode,
1725 NULL_RTX, NULL, do_error,
1726 PROB_VERY_UNLIKELY);
1727 emit_jump (done_label);
1729 emit_label (hipart_different);
1731 do_compare_rtx_and_jump (res, const0_rtx, GE, false, mode,
1732 NULL_RTX, NULL, do_error,
1733 PROB_VERY_UNLIKELY);
1734 emit_jump (done_label);
1737 emit_label (do_overflow);
1739 /* Overflow, do full multiplication and fallthru into do_error. */
1740 ops.op0 = make_tree (type, op0);
1741 ops.op1 = make_tree (type, op1);
1742 tem = expand_expr_real_2 (&ops, NULL_RTX, mode, EXPAND_NORMAL);
1743 emit_move_insn (res, tem);
1745 else
1747 gcc_assert (!is_ubsan);
1748 ops.code = MULT_EXPR;
1749 ops.type = type;
1750 res = expand_expr_real_2 (&ops, NULL_RTX, mode, EXPAND_NORMAL);
1751 emit_jump (done_label);
1755 do_error_label:
1756 emit_label (do_error);
1757 if (is_ubsan)
1759 /* Expand the ubsan builtin call. */
1760 push_temp_slots ();
1761 fn = ubsan_build_overflow_builtin (MULT_EXPR, loc, TREE_TYPE (arg0),
1762 arg0, arg1, datap);
1763 expand_normal (fn);
1764 pop_temp_slots ();
1765 do_pending_stack_adjust ();
1767 else if (lhs)
1768 expand_arith_set_overflow (lhs, target);
1770 /* We're done. */
1771 emit_label (done_label);
1773 /* u1 * u2 -> sr */
1774 if (uns0_p && uns1_p && !unsr_p)
1776 rtx_code_label *all_done_label = gen_label_rtx ();
1777 do_compare_rtx_and_jump (res, const0_rtx, GE, false, mode, NULL_RTX,
1778 NULL, all_done_label, PROB_VERY_LIKELY);
1779 expand_arith_set_overflow (lhs, target);
1780 emit_label (all_done_label);
1783 /* s1 * u2 -> sr */
1784 if (!uns0_p && uns1_p && !unsr_p && pos_neg1 == 3)
1786 rtx_code_label *all_done_label = gen_label_rtx ();
1787 rtx_code_label *set_noovf = gen_label_rtx ();
1788 do_compare_rtx_and_jump (op1, const0_rtx, GE, false, mode, NULL_RTX,
1789 NULL, all_done_label, PROB_VERY_LIKELY);
1790 expand_arith_set_overflow (lhs, target);
1791 do_compare_rtx_and_jump (op0, const0_rtx, EQ, true, mode, NULL_RTX,
1792 NULL, set_noovf, PROB_VERY_LIKELY);
1793 do_compare_rtx_and_jump (op0, constm1_rtx, NE, true, mode, NULL_RTX,
1794 NULL, all_done_label, PROB_VERY_UNLIKELY);
1795 do_compare_rtx_and_jump (op1, res, NE, true, mode, NULL_RTX, NULL,
1796 all_done_label, PROB_VERY_UNLIKELY);
1797 emit_label (set_noovf);
1798 write_complex_part (target, const0_rtx, true);
1799 emit_label (all_done_label);
1802 if (lhs)
1804 if (is_ubsan)
1805 expand_ubsan_result_store (target, res);
1806 else
1807 expand_arith_overflow_result_store (lhs, target, mode, res);
1811 /* Expand UBSAN_CHECK_* internal function if it has vector operands. */
1813 static void
1814 expand_vector_ubsan_overflow (location_t loc, enum tree_code code, tree lhs,
1815 tree arg0, tree arg1)
1817 int cnt = TYPE_VECTOR_SUBPARTS (TREE_TYPE (arg0));
1818 rtx_code_label *loop_lab = NULL;
1819 rtx cntvar = NULL_RTX;
1820 tree cntv = NULL_TREE;
1821 tree eltype = TREE_TYPE (TREE_TYPE (arg0));
1822 tree sz = TYPE_SIZE (eltype);
1823 tree data = NULL_TREE;
1824 tree resv = NULL_TREE;
1825 rtx lhsr = NULL_RTX;
1826 rtx resvr = NULL_RTX;
1828 if (lhs)
1830 optab op;
1831 lhsr = expand_expr (lhs, NULL_RTX, VOIDmode, EXPAND_WRITE);
1832 if (!VECTOR_MODE_P (GET_MODE (lhsr))
1833 || (op = optab_for_tree_code (code, TREE_TYPE (arg0),
1834 optab_default)) == unknown_optab
1835 || (optab_handler (op, TYPE_MODE (TREE_TYPE (arg0)))
1836 == CODE_FOR_nothing))
1838 if (MEM_P (lhsr))
1839 resv = make_tree (TREE_TYPE (lhs), lhsr);
1840 else
1842 resvr = assign_temp (TREE_TYPE (lhs), 1, 1);
1843 resv = make_tree (TREE_TYPE (lhs), resvr);
1847 if (cnt > 4)
1849 do_pending_stack_adjust ();
1850 loop_lab = gen_label_rtx ();
1851 cntvar = gen_reg_rtx (TYPE_MODE (sizetype));
1852 cntv = make_tree (sizetype, cntvar);
1853 emit_move_insn (cntvar, const0_rtx);
1854 emit_label (loop_lab);
1856 if (TREE_CODE (arg0) != VECTOR_CST)
1858 rtx arg0r = expand_normal (arg0);
1859 arg0 = make_tree (TREE_TYPE (arg0), arg0r);
1861 if (TREE_CODE (arg1) != VECTOR_CST)
1863 rtx arg1r = expand_normal (arg1);
1864 arg1 = make_tree (TREE_TYPE (arg1), arg1r);
1866 for (int i = 0; i < (cnt > 4 ? 1 : cnt); i++)
1868 tree op0, op1, res = NULL_TREE;
1869 if (cnt > 4)
1871 tree atype = build_array_type_nelts (eltype, cnt);
1872 op0 = uniform_vector_p (arg0);
1873 if (op0 == NULL_TREE)
1875 op0 = fold_build1_loc (loc, VIEW_CONVERT_EXPR, atype, arg0);
1876 op0 = build4_loc (loc, ARRAY_REF, eltype, op0, cntv,
1877 NULL_TREE, NULL_TREE);
1879 op1 = uniform_vector_p (arg1);
1880 if (op1 == NULL_TREE)
1882 op1 = fold_build1_loc (loc, VIEW_CONVERT_EXPR, atype, arg1);
1883 op1 = build4_loc (loc, ARRAY_REF, eltype, op1, cntv,
1884 NULL_TREE, NULL_TREE);
1886 if (resv)
1888 res = fold_build1_loc (loc, VIEW_CONVERT_EXPR, atype, resv);
1889 res = build4_loc (loc, ARRAY_REF, eltype, res, cntv,
1890 NULL_TREE, NULL_TREE);
1893 else
1895 tree bitpos = bitsize_int (tree_to_uhwi (sz) * i);
1896 op0 = fold_build3_loc (loc, BIT_FIELD_REF, eltype, arg0, sz, bitpos);
1897 op1 = fold_build3_loc (loc, BIT_FIELD_REF, eltype, arg1, sz, bitpos);
1898 if (resv)
1899 res = fold_build3_loc (loc, BIT_FIELD_REF, eltype, resv, sz,
1900 bitpos);
1902 switch (code)
1904 case PLUS_EXPR:
1905 expand_addsub_overflow (loc, PLUS_EXPR, res, op0, op1,
1906 false, false, false, true, &data);
1907 break;
1908 case MINUS_EXPR:
1909 if (cnt > 4 ? integer_zerop (arg0) : integer_zerop (op0))
1910 expand_neg_overflow (loc, res, op1, true, &data);
1911 else
1912 expand_addsub_overflow (loc, MINUS_EXPR, res, op0, op1,
1913 false, false, false, true, &data);
1914 break;
1915 case MULT_EXPR:
1916 expand_mul_overflow (loc, res, op0, op1, false, false, false,
1917 true, &data);
1918 break;
1919 default:
1920 gcc_unreachable ();
1923 if (cnt > 4)
1925 struct separate_ops ops;
1926 ops.code = PLUS_EXPR;
1927 ops.type = TREE_TYPE (cntv);
1928 ops.op0 = cntv;
1929 ops.op1 = build_int_cst (TREE_TYPE (cntv), 1);
1930 ops.op2 = NULL_TREE;
1931 ops.location = loc;
1932 rtx ret = expand_expr_real_2 (&ops, cntvar, TYPE_MODE (sizetype),
1933 EXPAND_NORMAL);
1934 if (ret != cntvar)
1935 emit_move_insn (cntvar, ret);
1936 do_compare_rtx_and_jump (cntvar, GEN_INT (cnt), NE, false,
1937 TYPE_MODE (sizetype), NULL_RTX, NULL, loop_lab,
1938 PROB_VERY_LIKELY);
1940 if (lhs && resv == NULL_TREE)
1942 struct separate_ops ops;
1943 ops.code = code;
1944 ops.type = TREE_TYPE (arg0);
1945 ops.op0 = arg0;
1946 ops.op1 = arg1;
1947 ops.op2 = NULL_TREE;
1948 ops.location = loc;
1949 rtx ret = expand_expr_real_2 (&ops, lhsr, TYPE_MODE (TREE_TYPE (arg0)),
1950 EXPAND_NORMAL);
1951 if (ret != lhsr)
1952 emit_move_insn (lhsr, ret);
1954 else if (resvr)
1955 emit_move_insn (lhsr, resvr);
1958 /* Expand UBSAN_CHECK_ADD call STMT. */
1960 static void
1961 expand_UBSAN_CHECK_ADD (internal_fn, gcall *stmt)
1963 location_t loc = gimple_location (stmt);
1964 tree lhs = gimple_call_lhs (stmt);
1965 tree arg0 = gimple_call_arg (stmt, 0);
1966 tree arg1 = gimple_call_arg (stmt, 1);
1967 if (VECTOR_TYPE_P (TREE_TYPE (arg0)))
1968 expand_vector_ubsan_overflow (loc, PLUS_EXPR, lhs, arg0, arg1);
1969 else
1970 expand_addsub_overflow (loc, PLUS_EXPR, lhs, arg0, arg1,
1971 false, false, false, true, NULL);
1974 /* Expand UBSAN_CHECK_SUB call STMT. */
1976 static void
1977 expand_UBSAN_CHECK_SUB (internal_fn, gcall *stmt)
1979 location_t loc = gimple_location (stmt);
1980 tree lhs = gimple_call_lhs (stmt);
1981 tree arg0 = gimple_call_arg (stmt, 0);
1982 tree arg1 = gimple_call_arg (stmt, 1);
1983 if (VECTOR_TYPE_P (TREE_TYPE (arg0)))
1984 expand_vector_ubsan_overflow (loc, MINUS_EXPR, lhs, arg0, arg1);
1985 else if (integer_zerop (arg0))
1986 expand_neg_overflow (loc, lhs, arg1, true, NULL);
1987 else
1988 expand_addsub_overflow (loc, MINUS_EXPR, lhs, arg0, arg1,
1989 false, false, false, true, NULL);
1992 /* Expand UBSAN_CHECK_MUL call STMT. */
1994 static void
1995 expand_UBSAN_CHECK_MUL (internal_fn, gcall *stmt)
1997 location_t loc = gimple_location (stmt);
1998 tree lhs = gimple_call_lhs (stmt);
1999 tree arg0 = gimple_call_arg (stmt, 0);
2000 tree arg1 = gimple_call_arg (stmt, 1);
2001 if (VECTOR_TYPE_P (TREE_TYPE (arg0)))
2002 expand_vector_ubsan_overflow (loc, MULT_EXPR, lhs, arg0, arg1);
2003 else
2004 expand_mul_overflow (loc, lhs, arg0, arg1, false, false, false, true,
2005 NULL);
2008 /* Helper function for {ADD,SUB,MUL}_OVERFLOW call stmt expansion. */
2010 static void
2011 expand_arith_overflow (enum tree_code code, gimple *stmt)
2013 tree lhs = gimple_call_lhs (stmt);
2014 if (lhs == NULL_TREE)
2015 return;
2016 tree arg0 = gimple_call_arg (stmt, 0);
2017 tree arg1 = gimple_call_arg (stmt, 1);
2018 tree type = TREE_TYPE (TREE_TYPE (lhs));
2019 int uns0_p = TYPE_UNSIGNED (TREE_TYPE (arg0));
2020 int uns1_p = TYPE_UNSIGNED (TREE_TYPE (arg1));
2021 int unsr_p = TYPE_UNSIGNED (type);
2022 int prec0 = TYPE_PRECISION (TREE_TYPE (arg0));
2023 int prec1 = TYPE_PRECISION (TREE_TYPE (arg1));
2024 int precres = TYPE_PRECISION (type);
2025 location_t loc = gimple_location (stmt);
2026 if (!uns0_p && get_range_pos_neg (arg0) == 1)
2027 uns0_p = true;
2028 if (!uns1_p && get_range_pos_neg (arg1) == 1)
2029 uns1_p = true;
2030 int pr = get_min_precision (arg0, uns0_p ? UNSIGNED : SIGNED);
2031 prec0 = MIN (prec0, pr);
2032 pr = get_min_precision (arg1, uns1_p ? UNSIGNED : SIGNED);
2033 prec1 = MIN (prec1, pr);
2035 /* If uns0_p && uns1_p, precop is minimum needed precision
2036 of unsigned type to hold the exact result, otherwise
2037 precop is minimum needed precision of signed type to
2038 hold the exact result. */
2039 int precop;
2040 if (code == MULT_EXPR)
2041 precop = prec0 + prec1 + (uns0_p != uns1_p);
2042 else
2044 if (uns0_p == uns1_p)
2045 precop = MAX (prec0, prec1) + 1;
2046 else if (uns0_p)
2047 precop = MAX (prec0 + 1, prec1) + 1;
2048 else
2049 precop = MAX (prec0, prec1 + 1) + 1;
2051 int orig_precres = precres;
2055 if ((uns0_p && uns1_p)
2056 ? ((precop + !unsr_p) <= precres
2057 /* u1 - u2 -> ur can overflow, no matter what precision
2058 the result has. */
2059 && (code != MINUS_EXPR || !unsr_p))
2060 : (!unsr_p && precop <= precres))
2062 /* The infinity precision result will always fit into result. */
2063 rtx target = expand_expr (lhs, NULL_RTX, VOIDmode, EXPAND_WRITE);
2064 write_complex_part (target, const0_rtx, true);
2065 enum machine_mode mode = TYPE_MODE (type);
2066 struct separate_ops ops;
2067 ops.code = code;
2068 ops.type = type;
2069 ops.op0 = fold_convert_loc (loc, type, arg0);
2070 ops.op1 = fold_convert_loc (loc, type, arg1);
2071 ops.op2 = NULL_TREE;
2072 ops.location = loc;
2073 rtx tem = expand_expr_real_2 (&ops, NULL_RTX, mode, EXPAND_NORMAL);
2074 expand_arith_overflow_result_store (lhs, target, mode, tem);
2075 return;
2078 /* For operations with low precision, if target doesn't have them, start
2079 with precres widening right away, otherwise do it only if the most
2080 simple cases can't be used. */
2081 const int min_precision = targetm.min_arithmetic_precision ();
2082 if (orig_precres == precres && precres < min_precision)
2084 else if ((uns0_p && uns1_p && unsr_p && prec0 <= precres
2085 && prec1 <= precres)
2086 || ((!uns0_p || !uns1_p) && !unsr_p
2087 && prec0 + uns0_p <= precres
2088 && prec1 + uns1_p <= precres))
2090 arg0 = fold_convert_loc (loc, type, arg0);
2091 arg1 = fold_convert_loc (loc, type, arg1);
2092 switch (code)
2094 case MINUS_EXPR:
2095 if (integer_zerop (arg0) && !unsr_p)
2097 expand_neg_overflow (loc, lhs, arg1, false, NULL);
2098 return;
2100 /* FALLTHRU */
2101 case PLUS_EXPR:
2102 expand_addsub_overflow (loc, code, lhs, arg0, arg1, unsr_p,
2103 unsr_p, unsr_p, false, NULL);
2104 return;
2105 case MULT_EXPR:
2106 expand_mul_overflow (loc, lhs, arg0, arg1, unsr_p,
2107 unsr_p, unsr_p, false, NULL);
2108 return;
2109 default:
2110 gcc_unreachable ();
2114 /* For sub-word operations, retry with a wider type first. */
2115 if (orig_precres == precres && precop <= BITS_PER_WORD)
2117 int p = MAX (min_precision, precop);
2118 enum machine_mode m = smallest_mode_for_size (p, MODE_INT);
2119 tree optype = build_nonstandard_integer_type (GET_MODE_PRECISION (m),
2120 uns0_p && uns1_p
2121 && unsr_p);
2122 p = TYPE_PRECISION (optype);
2123 if (p > precres)
2125 precres = p;
2126 unsr_p = TYPE_UNSIGNED (optype);
2127 type = optype;
2128 continue;
2132 if (prec0 <= precres && prec1 <= precres)
2134 tree types[2];
2135 if (unsr_p)
2137 types[0] = build_nonstandard_integer_type (precres, 0);
2138 types[1] = type;
2140 else
2142 types[0] = type;
2143 types[1] = build_nonstandard_integer_type (precres, 1);
2145 arg0 = fold_convert_loc (loc, types[uns0_p], arg0);
2146 arg1 = fold_convert_loc (loc, types[uns1_p], arg1);
2147 if (code != MULT_EXPR)
2148 expand_addsub_overflow (loc, code, lhs, arg0, arg1, unsr_p,
2149 uns0_p, uns1_p, false, NULL);
2150 else
2151 expand_mul_overflow (loc, lhs, arg0, arg1, unsr_p,
2152 uns0_p, uns1_p, false, NULL);
2153 return;
2156 /* Retry with a wider type. */
2157 if (orig_precres == precres)
2159 int p = MAX (prec0, prec1);
2160 enum machine_mode m = smallest_mode_for_size (p, MODE_INT);
2161 tree optype = build_nonstandard_integer_type (GET_MODE_PRECISION (m),
2162 uns0_p && uns1_p
2163 && unsr_p);
2164 p = TYPE_PRECISION (optype);
2165 if (p > precres)
2167 precres = p;
2168 unsr_p = TYPE_UNSIGNED (optype);
2169 type = optype;
2170 continue;
2174 gcc_unreachable ();
2176 while (1);
2179 /* Expand ADD_OVERFLOW STMT. */
2181 static void
2182 expand_ADD_OVERFLOW (internal_fn, gcall *stmt)
2184 expand_arith_overflow (PLUS_EXPR, stmt);
2187 /* Expand SUB_OVERFLOW STMT. */
2189 static void
2190 expand_SUB_OVERFLOW (internal_fn, gcall *stmt)
2192 expand_arith_overflow (MINUS_EXPR, stmt);
2195 /* Expand MUL_OVERFLOW STMT. */
2197 static void
2198 expand_MUL_OVERFLOW (internal_fn, gcall *stmt)
2200 expand_arith_overflow (MULT_EXPR, stmt);
2203 /* This should get folded in tree-vectorizer.c. */
2205 static void
2206 expand_LOOP_VECTORIZED (internal_fn, gcall *)
2208 gcc_unreachable ();
2211 /* Expand MASK_LOAD call STMT using optab OPTAB. */
2213 static void
2214 expand_mask_load_optab_fn (internal_fn, gcall *stmt, convert_optab optab)
2216 struct expand_operand ops[3];
2217 tree type, lhs, rhs, maskt, ptr;
2218 rtx mem, target, mask;
2219 unsigned align;
2221 maskt = gimple_call_arg (stmt, 2);
2222 lhs = gimple_call_lhs (stmt);
2223 if (lhs == NULL_TREE)
2224 return;
2225 type = TREE_TYPE (lhs);
2226 ptr = build_int_cst (TREE_TYPE (gimple_call_arg (stmt, 1)), 0);
2227 align = tree_to_shwi (gimple_call_arg (stmt, 1));
2228 if (TYPE_ALIGN (type) != align)
2229 type = build_aligned_type (type, align);
2230 rhs = fold_build2 (MEM_REF, type, gimple_call_arg (stmt, 0), ptr);
2232 mem = expand_expr (rhs, NULL_RTX, VOIDmode, EXPAND_WRITE);
2233 gcc_assert (MEM_P (mem));
2234 mask = expand_normal (maskt);
2235 target = expand_expr (lhs, NULL_RTX, VOIDmode, EXPAND_WRITE);
2236 create_output_operand (&ops[0], target, TYPE_MODE (type));
2237 create_fixed_operand (&ops[1], mem);
2238 create_input_operand (&ops[2], mask, TYPE_MODE (TREE_TYPE (maskt)));
2239 expand_insn (convert_optab_handler (optab, TYPE_MODE (type),
2240 TYPE_MODE (TREE_TYPE (maskt))),
2241 3, ops);
2244 /* Expand MASK_STORE call STMT using optab OPTAB. */
2246 static void
2247 expand_mask_store_optab_fn (internal_fn, gcall *stmt, convert_optab optab)
2249 struct expand_operand ops[3];
2250 tree type, lhs, rhs, maskt, ptr;
2251 rtx mem, reg, mask;
2252 unsigned align;
2254 maskt = gimple_call_arg (stmt, 2);
2255 rhs = gimple_call_arg (stmt, 3);
2256 type = TREE_TYPE (rhs);
2257 ptr = build_int_cst (TREE_TYPE (gimple_call_arg (stmt, 1)), 0);
2258 align = tree_to_shwi (gimple_call_arg (stmt, 1));
2259 if (TYPE_ALIGN (type) != align)
2260 type = build_aligned_type (type, align);
2261 lhs = fold_build2 (MEM_REF, type, gimple_call_arg (stmt, 0), ptr);
2263 mem = expand_expr (lhs, NULL_RTX, VOIDmode, EXPAND_WRITE);
2264 gcc_assert (MEM_P (mem));
2265 mask = expand_normal (maskt);
2266 reg = expand_normal (rhs);
2267 create_fixed_operand (&ops[0], mem);
2268 create_input_operand (&ops[1], reg, TYPE_MODE (type));
2269 create_input_operand (&ops[2], mask, TYPE_MODE (TREE_TYPE (maskt)));
2270 expand_insn (convert_optab_handler (optab, TYPE_MODE (type),
2271 TYPE_MODE (TREE_TYPE (maskt))),
2272 3, ops);
2275 static void
2276 expand_ABNORMAL_DISPATCHER (internal_fn, gcall *)
2280 static void
2281 expand_BUILTIN_EXPECT (internal_fn, gcall *stmt)
2283 /* When guessing was done, the hints should be already stripped away. */
2284 gcc_assert (!flag_guess_branch_prob || optimize == 0 || seen_error ());
2286 rtx target;
2287 tree lhs = gimple_call_lhs (stmt);
2288 if (lhs)
2289 target = expand_expr (lhs, NULL_RTX, VOIDmode, EXPAND_WRITE);
2290 else
2291 target = const0_rtx;
2292 rtx val = expand_expr (gimple_call_arg (stmt, 0), target, VOIDmode, EXPAND_NORMAL);
2293 if (lhs && val != target)
2294 emit_move_insn (target, val);
2297 /* IFN_VA_ARG is supposed to be expanded at pass_stdarg. So this dummy function
2298 should never be called. */
2300 static void
2301 expand_VA_ARG (internal_fn, gcall *)
2303 gcc_unreachable ();
2306 /* Expand the IFN_UNIQUE function according to its first argument. */
2308 static void
2309 expand_UNIQUE (internal_fn, gcall *stmt)
2311 rtx pattern = NULL_RTX;
2312 enum ifn_unique_kind kind
2313 = (enum ifn_unique_kind) TREE_INT_CST_LOW (gimple_call_arg (stmt, 0));
2315 switch (kind)
2317 default:
2318 gcc_unreachable ();
2320 case IFN_UNIQUE_UNSPEC:
2321 if (targetm.have_unique ())
2322 pattern = targetm.gen_unique ();
2323 break;
2325 case IFN_UNIQUE_OACC_FORK:
2326 case IFN_UNIQUE_OACC_JOIN:
2327 if (targetm.have_oacc_fork () && targetm.have_oacc_join ())
2329 tree lhs = gimple_call_lhs (stmt);
2330 rtx target = const0_rtx;
2332 if (lhs)
2333 target = expand_expr (lhs, NULL_RTX, VOIDmode, EXPAND_WRITE);
2335 rtx data_dep = expand_normal (gimple_call_arg (stmt, 1));
2336 rtx axis = expand_normal (gimple_call_arg (stmt, 2));
2338 if (kind == IFN_UNIQUE_OACC_FORK)
2339 pattern = targetm.gen_oacc_fork (target, data_dep, axis);
2340 else
2341 pattern = targetm.gen_oacc_join (target, data_dep, axis);
2343 else
2344 gcc_unreachable ();
2345 break;
2348 if (pattern)
2349 emit_insn (pattern);
2352 /* The size of an OpenACC compute dimension. */
2354 static void
2355 expand_GOACC_DIM_SIZE (internal_fn, gcall *stmt)
2357 tree lhs = gimple_call_lhs (stmt);
2359 if (!lhs)
2360 return;
2362 rtx target = expand_expr (lhs, NULL_RTX, VOIDmode, EXPAND_WRITE);
2363 if (targetm.have_oacc_dim_size ())
2365 rtx dim = expand_expr (gimple_call_arg (stmt, 0), NULL_RTX,
2366 VOIDmode, EXPAND_NORMAL);
2367 emit_insn (targetm.gen_oacc_dim_size (target, dim));
2369 else
2370 emit_move_insn (target, GEN_INT (1));
2373 /* The position of an OpenACC execution engine along one compute axis. */
2375 static void
2376 expand_GOACC_DIM_POS (internal_fn, gcall *stmt)
2378 tree lhs = gimple_call_lhs (stmt);
2380 if (!lhs)
2381 return;
2383 rtx target = expand_expr (lhs, NULL_RTX, VOIDmode, EXPAND_WRITE);
2384 if (targetm.have_oacc_dim_pos ())
2386 rtx dim = expand_expr (gimple_call_arg (stmt, 0), NULL_RTX,
2387 VOIDmode, EXPAND_NORMAL);
2388 emit_insn (targetm.gen_oacc_dim_pos (target, dim));
2390 else
2391 emit_move_insn (target, const0_rtx);
2394 /* This is expanded by oacc_device_lower pass. */
2396 static void
2397 expand_GOACC_LOOP (internal_fn, gcall *)
2399 gcc_unreachable ();
2402 /* This is expanded by oacc_device_lower pass. */
2404 static void
2405 expand_GOACC_REDUCTION (internal_fn, gcall *)
2407 gcc_unreachable ();
2410 /* This is expanded by oacc_device_lower pass. */
2412 static void
2413 expand_GOACC_TILE (internal_fn, gcall *)
2415 gcc_unreachable ();
2418 /* Set errno to EDOM. */
2420 static void
2421 expand_SET_EDOM (internal_fn, gcall *)
2423 #ifdef TARGET_EDOM
2424 #ifdef GEN_ERRNO_RTX
2425 rtx errno_rtx = GEN_ERRNO_RTX;
2426 #else
2427 rtx errno_rtx = gen_rtx_MEM (word_mode, gen_rtx_SYMBOL_REF (Pmode, "errno"));
2428 #endif
2429 emit_move_insn (errno_rtx,
2430 gen_int_mode (TARGET_EDOM, GET_MODE (errno_rtx)));
2431 #else
2432 gcc_unreachable ();
2433 #endif
2436 /* Expand atomic bit test and set. */
2438 static void
2439 expand_ATOMIC_BIT_TEST_AND_SET (internal_fn, gcall *call)
2441 expand_ifn_atomic_bit_test_and (call);
2444 /* Expand atomic bit test and complement. */
2446 static void
2447 expand_ATOMIC_BIT_TEST_AND_COMPLEMENT (internal_fn, gcall *call)
2449 expand_ifn_atomic_bit_test_and (call);
2452 /* Expand atomic bit test and reset. */
2454 static void
2455 expand_ATOMIC_BIT_TEST_AND_RESET (internal_fn, gcall *call)
2457 expand_ifn_atomic_bit_test_and (call);
2460 /* Expand atomic bit test and set. */
2462 static void
2463 expand_ATOMIC_COMPARE_EXCHANGE (internal_fn, gcall *call)
2465 expand_ifn_atomic_compare_exchange (call);
2468 /* Expand LAUNDER to assignment, lhs = arg0. */
2470 static void
2471 expand_LAUNDER (internal_fn, gcall *call)
2473 tree lhs = gimple_call_lhs (call);
2475 if (!lhs)
2476 return;
2478 expand_assignment (lhs, gimple_call_arg (call, 0), false);
2481 /* Expand DIVMOD() using:
2482 a) optab handler for udivmod/sdivmod if it is available.
2483 b) If optab_handler doesn't exist, generate call to
2484 target-specific divmod libfunc. */
2486 static void
2487 expand_DIVMOD (internal_fn, gcall *call_stmt)
2489 tree lhs = gimple_call_lhs (call_stmt);
2490 tree arg0 = gimple_call_arg (call_stmt, 0);
2491 tree arg1 = gimple_call_arg (call_stmt, 1);
2493 gcc_assert (TREE_CODE (TREE_TYPE (lhs)) == COMPLEX_TYPE);
2494 tree type = TREE_TYPE (TREE_TYPE (lhs));
2495 machine_mode mode = TYPE_MODE (type);
2496 bool unsignedp = TYPE_UNSIGNED (type);
2497 optab tab = (unsignedp) ? udivmod_optab : sdivmod_optab;
2499 rtx op0 = expand_normal (arg0);
2500 rtx op1 = expand_normal (arg1);
2501 rtx target = expand_expr (lhs, NULL_RTX, VOIDmode, EXPAND_WRITE);
2503 rtx quotient, remainder, libfunc;
2505 /* Check if optab_handler exists for divmod_optab for given mode. */
2506 if (optab_handler (tab, mode) != CODE_FOR_nothing)
2508 quotient = gen_reg_rtx (mode);
2509 remainder = gen_reg_rtx (mode);
2510 expand_twoval_binop (tab, op0, op1, quotient, remainder, unsignedp);
2513 /* Generate call to divmod libfunc if it exists. */
2514 else if ((libfunc = optab_libfunc (tab, mode)) != NULL_RTX)
2515 targetm.expand_divmod_libfunc (libfunc, mode, op0, op1,
2516 &quotient, &remainder);
2518 else
2519 gcc_unreachable ();
2521 /* Wrap the return value (quotient, remainder) within COMPLEX_EXPR. */
2522 expand_expr (build2 (COMPLEX_EXPR, TREE_TYPE (lhs),
2523 make_tree (TREE_TYPE (arg0), quotient),
2524 make_tree (TREE_TYPE (arg1), remainder)),
2525 target, VOIDmode, EXPAND_NORMAL);
2528 /* Expand a call to FN using the operands in STMT. FN has a single
2529 output operand and NARGS input operands. */
2531 static void
2532 expand_direct_optab_fn (internal_fn fn, gcall *stmt, direct_optab optab,
2533 unsigned int nargs)
2535 expand_operand *ops = XALLOCAVEC (expand_operand, nargs + 1);
2537 tree_pair types = direct_internal_fn_types (fn, stmt);
2538 insn_code icode = direct_optab_handler (optab, TYPE_MODE (types.first));
2540 tree lhs = gimple_call_lhs (stmt);
2541 tree lhs_type = TREE_TYPE (lhs);
2542 rtx lhs_rtx = expand_expr (lhs, NULL_RTX, VOIDmode, EXPAND_WRITE);
2543 create_output_operand (&ops[0], lhs_rtx, insn_data[icode].operand[0].mode);
2545 for (unsigned int i = 0; i < nargs; ++i)
2547 tree rhs = gimple_call_arg (stmt, i);
2548 tree rhs_type = TREE_TYPE (rhs);
2549 rtx rhs_rtx = expand_normal (rhs);
2550 if (INTEGRAL_TYPE_P (rhs_type))
2551 create_convert_operand_from (&ops[i + 1], rhs_rtx,
2552 TYPE_MODE (rhs_type),
2553 TYPE_UNSIGNED (rhs_type));
2554 else
2555 create_input_operand (&ops[i + 1], rhs_rtx, TYPE_MODE (rhs_type));
2558 expand_insn (icode, nargs + 1, ops);
2559 if (!rtx_equal_p (lhs_rtx, ops[0].value))
2561 /* If the return value has an integral type, convert the instruction
2562 result to that type. This is useful for things that return an
2563 int regardless of the size of the input. If the instruction result
2564 is smaller than required, assume that it is signed.
2566 If the return value has a nonintegral type, its mode must match
2567 the instruction result. */
2568 if (GET_CODE (lhs_rtx) == SUBREG && SUBREG_PROMOTED_VAR_P (lhs_rtx))
2570 /* If this is a scalar in a register that is stored in a wider
2571 mode than the declared mode, compute the result into its
2572 declared mode and then convert to the wider mode. */
2573 gcc_checking_assert (INTEGRAL_TYPE_P (lhs_type));
2574 rtx tmp = convert_to_mode (GET_MODE (lhs_rtx), ops[0].value, 0);
2575 convert_move (SUBREG_REG (lhs_rtx), tmp,
2576 SUBREG_PROMOTED_SIGN (lhs_rtx));
2578 else if (GET_MODE (lhs_rtx) == GET_MODE (ops[0].value))
2579 emit_move_insn (lhs_rtx, ops[0].value);
2580 else
2582 gcc_checking_assert (INTEGRAL_TYPE_P (lhs_type));
2583 convert_move (lhs_rtx, ops[0].value, 0);
2588 /* Expanders for optabs that can use expand_direct_optab_fn. */
2590 #define expand_unary_optab_fn(FN, STMT, OPTAB) \
2591 expand_direct_optab_fn (FN, STMT, OPTAB, 1)
2593 #define expand_binary_optab_fn(FN, STMT, OPTAB) \
2594 expand_direct_optab_fn (FN, STMT, OPTAB, 2)
2596 /* RETURN_TYPE and ARGS are a return type and argument list that are
2597 in principle compatible with FN (which satisfies direct_internal_fn_p).
2598 Return the types that should be used to determine whether the
2599 target supports FN. */
2601 tree_pair
2602 direct_internal_fn_types (internal_fn fn, tree return_type, tree *args)
2604 const direct_internal_fn_info &info = direct_internal_fn (fn);
2605 tree type0 = (info.type0 < 0 ? return_type : TREE_TYPE (args[info.type0]));
2606 tree type1 = (info.type1 < 0 ? return_type : TREE_TYPE (args[info.type1]));
2607 return tree_pair (type0, type1);
2610 /* CALL is a call whose return type and arguments are in principle
2611 compatible with FN (which satisfies direct_internal_fn_p). Return the
2612 types that should be used to determine whether the target supports FN. */
2614 tree_pair
2615 direct_internal_fn_types (internal_fn fn, gcall *call)
2617 const direct_internal_fn_info &info = direct_internal_fn (fn);
2618 tree op0 = (info.type0 < 0
2619 ? gimple_call_lhs (call)
2620 : gimple_call_arg (call, info.type0));
2621 tree op1 = (info.type1 < 0
2622 ? gimple_call_lhs (call)
2623 : gimple_call_arg (call, info.type1));
2624 return tree_pair (TREE_TYPE (op0), TREE_TYPE (op1));
2627 /* Return true if OPTAB is supported for TYPES (whose modes should be
2628 the same) when the optimization type is OPT_TYPE. Used for simple
2629 direct optabs. */
2631 static bool
2632 direct_optab_supported_p (direct_optab optab, tree_pair types,
2633 optimization_type opt_type)
2635 machine_mode mode = TYPE_MODE (types.first);
2636 gcc_checking_assert (mode == TYPE_MODE (types.second));
2637 return direct_optab_handler (optab, mode, opt_type) != CODE_FOR_nothing;
2640 /* Return true if load/store lanes optab OPTAB is supported for
2641 array type TYPES.first when the optimization type is OPT_TYPE. */
2643 static bool
2644 multi_vector_optab_supported_p (convert_optab optab, tree_pair types,
2645 optimization_type opt_type)
2647 gcc_assert (TREE_CODE (types.first) == ARRAY_TYPE);
2648 machine_mode imode = TYPE_MODE (types.first);
2649 machine_mode vmode = TYPE_MODE (TREE_TYPE (types.first));
2650 return (convert_optab_handler (optab, imode, vmode, opt_type)
2651 != CODE_FOR_nothing);
2654 #define direct_unary_optab_supported_p direct_optab_supported_p
2655 #define direct_binary_optab_supported_p direct_optab_supported_p
2656 #define direct_mask_load_optab_supported_p direct_optab_supported_p
2657 #define direct_load_lanes_optab_supported_p multi_vector_optab_supported_p
2658 #define direct_mask_store_optab_supported_p direct_optab_supported_p
2659 #define direct_store_lanes_optab_supported_p multi_vector_optab_supported_p
2661 /* Return true if FN is supported for the types in TYPES when the
2662 optimization type is OPT_TYPE. The types are those associated with
2663 the "type0" and "type1" fields of FN's direct_internal_fn_info
2664 structure. */
2666 bool
2667 direct_internal_fn_supported_p (internal_fn fn, tree_pair types,
2668 optimization_type opt_type)
2670 switch (fn)
2672 #define DEF_INTERNAL_FN(CODE, FLAGS, FNSPEC) \
2673 case IFN_##CODE: break;
2674 #define DEF_INTERNAL_OPTAB_FN(CODE, FLAGS, OPTAB, TYPE) \
2675 case IFN_##CODE: \
2676 return direct_##TYPE##_optab_supported_p (OPTAB##_optab, types, \
2677 opt_type);
2678 #include "internal-fn.def"
2680 case IFN_LAST:
2681 break;
2683 gcc_unreachable ();
2686 /* Return true if FN is supported for type TYPE when the optimization
2687 type is OPT_TYPE. The caller knows that the "type0" and "type1"
2688 fields of FN's direct_internal_fn_info structure are the same. */
2690 bool
2691 direct_internal_fn_supported_p (internal_fn fn, tree type,
2692 optimization_type opt_type)
2694 const direct_internal_fn_info &info = direct_internal_fn (fn);
2695 gcc_checking_assert (info.type0 == info.type1);
2696 return direct_internal_fn_supported_p (fn, tree_pair (type, type), opt_type);
2699 /* Return true if IFN_SET_EDOM is supported. */
2701 bool
2702 set_edom_supported_p (void)
2704 #ifdef TARGET_EDOM
2705 return true;
2706 #else
2707 return false;
2708 #endif
2711 #define DEF_INTERNAL_OPTAB_FN(CODE, FLAGS, OPTAB, TYPE) \
2712 static void \
2713 expand_##CODE (internal_fn fn, gcall *stmt) \
2715 expand_##TYPE##_optab_fn (fn, stmt, OPTAB##_optab); \
2717 #include "internal-fn.def"
2719 /* Routines to expand each internal function, indexed by function number.
2720 Each routine has the prototype:
2722 expand_<NAME> (gcall *stmt)
2724 where STMT is the statement that performs the call. */
2725 static void (*const internal_fn_expanders[]) (internal_fn, gcall *) = {
2726 #define DEF_INTERNAL_FN(CODE, FLAGS, FNSPEC) expand_##CODE,
2727 #include "internal-fn.def"
2731 /* Expand STMT as though it were a call to internal function FN. */
2733 void
2734 expand_internal_call (internal_fn fn, gcall *stmt)
2736 internal_fn_expanders[fn] (fn, stmt);
2739 /* Expand STMT, which is a call to internal function FN. */
2741 void
2742 expand_internal_call (gcall *stmt)
2744 expand_internal_call (gimple_call_internal_fn (stmt), stmt);
2747 void
2748 expand_PHI (internal_fn, gcall *)
2750 gcc_unreachable ();