diagnostic-show-locus.c: remove unused field from class colorizer
[official-gcc.git] / gcc / internal-fn.c
blob2b72367a1d396ac5151c6142072231bb8ce76548
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 "stringpool.h"
43 #include "attribs.h"
44 #include "asan.h"
45 #include "ubsan.h"
46 #include "recog.h"
47 #include "builtins.h"
48 #include "optabs-tree.h"
50 /* The names of each internal function, indexed by function number. */
51 const char *const internal_fn_name_array[] = {
52 #define DEF_INTERNAL_FN(CODE, FLAGS, FNSPEC) #CODE,
53 #include "internal-fn.def"
54 "<invalid-fn>"
57 /* The ECF_* flags of each internal function, indexed by function number. */
58 const int internal_fn_flags_array[] = {
59 #define DEF_INTERNAL_FN(CODE, FLAGS, FNSPEC) FLAGS,
60 #include "internal-fn.def"
64 /* Fnspec of each internal function, indexed by function number. */
65 const_tree internal_fn_fnspec_array[IFN_LAST + 1];
67 void
68 init_internal_fns ()
70 #define DEF_INTERNAL_FN(CODE, FLAGS, FNSPEC) \
71 if (FNSPEC) internal_fn_fnspec_array[IFN_##CODE] = \
72 build_string ((int) sizeof (FNSPEC), FNSPEC ? FNSPEC : "");
73 #include "internal-fn.def"
74 internal_fn_fnspec_array[IFN_LAST] = 0;
77 /* Create static initializers for the information returned by
78 direct_internal_fn. */
79 #define not_direct { -2, -2, false }
80 #define mask_load_direct { -1, 2, false }
81 #define load_lanes_direct { -1, -1, false }
82 #define mask_store_direct { 3, 2, false }
83 #define store_lanes_direct { 0, 0, false }
84 #define unary_direct { 0, 0, true }
85 #define binary_direct { 0, 0, true }
87 const direct_internal_fn_info direct_internal_fn_array[IFN_LAST + 1] = {
88 #define DEF_INTERNAL_FN(CODE, FLAGS, FNSPEC) not_direct,
89 #define DEF_INTERNAL_OPTAB_FN(CODE, FLAGS, OPTAB, TYPE) TYPE##_direct,
90 #include "internal-fn.def"
91 not_direct
94 /* ARRAY_TYPE is an array of vector modes. Return the associated insn
95 for load-lanes-style optab OPTAB, or CODE_FOR_nothing if none. */
97 static enum insn_code
98 get_multi_vector_move (tree array_type, convert_optab optab)
100 machine_mode imode;
101 machine_mode vmode;
103 gcc_assert (TREE_CODE (array_type) == ARRAY_TYPE);
104 imode = TYPE_MODE (array_type);
105 vmode = TYPE_MODE (TREE_TYPE (array_type));
107 return convert_optab_handler (optab, imode, vmode);
110 /* Expand LOAD_LANES call STMT using optab OPTAB. */
112 static void
113 expand_load_lanes_optab_fn (internal_fn, gcall *stmt, convert_optab optab)
115 struct expand_operand ops[2];
116 tree type, lhs, rhs;
117 rtx target, mem;
119 lhs = gimple_call_lhs (stmt);
120 rhs = gimple_call_arg (stmt, 0);
121 type = TREE_TYPE (lhs);
123 target = expand_expr (lhs, NULL_RTX, VOIDmode, EXPAND_WRITE);
124 mem = expand_normal (rhs);
126 gcc_assert (MEM_P (mem));
127 PUT_MODE (mem, TYPE_MODE (type));
129 create_output_operand (&ops[0], target, TYPE_MODE (type));
130 create_fixed_operand (&ops[1], mem);
131 expand_insn (get_multi_vector_move (type, optab), 2, ops);
134 /* Expand STORE_LANES call STMT using optab OPTAB. */
136 static void
137 expand_store_lanes_optab_fn (internal_fn, gcall *stmt, convert_optab optab)
139 struct expand_operand ops[2];
140 tree type, lhs, rhs;
141 rtx target, reg;
143 lhs = gimple_call_lhs (stmt);
144 rhs = gimple_call_arg (stmt, 0);
145 type = TREE_TYPE (rhs);
147 target = expand_expr (lhs, NULL_RTX, VOIDmode, EXPAND_WRITE);
148 reg = expand_normal (rhs);
150 gcc_assert (MEM_P (target));
151 PUT_MODE (target, TYPE_MODE (type));
153 create_fixed_operand (&ops[0], target);
154 create_input_operand (&ops[1], reg, TYPE_MODE (type));
155 expand_insn (get_multi_vector_move (type, optab), 2, ops);
158 static void
159 expand_ANNOTATE (internal_fn, gcall *)
161 gcc_unreachable ();
164 /* This should get expanded in omp_device_lower pass. */
166 static void
167 expand_GOMP_USE_SIMT (internal_fn, gcall *)
169 gcc_unreachable ();
172 /* This should get expanded in omp_device_lower pass. */
174 static void
175 expand_GOMP_SIMT_ENTER (internal_fn, gcall *)
177 gcc_unreachable ();
180 /* Allocate per-lane storage and begin non-uniform execution region. */
182 static void
183 expand_GOMP_SIMT_ENTER_ALLOC (internal_fn, gcall *stmt)
185 rtx target;
186 tree lhs = gimple_call_lhs (stmt);
187 if (lhs)
188 target = expand_expr (lhs, NULL_RTX, VOIDmode, EXPAND_WRITE);
189 else
190 target = gen_reg_rtx (Pmode);
191 rtx size = expand_normal (gimple_call_arg (stmt, 0));
192 rtx align = expand_normal (gimple_call_arg (stmt, 1));
193 struct expand_operand ops[3];
194 create_output_operand (&ops[0], target, Pmode);
195 create_input_operand (&ops[1], size, Pmode);
196 create_input_operand (&ops[2], align, Pmode);
197 gcc_assert (targetm.have_omp_simt_enter ());
198 expand_insn (targetm.code_for_omp_simt_enter, 3, ops);
201 /* Deallocate per-lane storage and leave non-uniform execution region. */
203 static void
204 expand_GOMP_SIMT_EXIT (internal_fn, gcall *stmt)
206 gcc_checking_assert (!gimple_call_lhs (stmt));
207 rtx arg = expand_normal (gimple_call_arg (stmt, 0));
208 struct expand_operand ops[1];
209 create_input_operand (&ops[0], arg, Pmode);
210 gcc_assert (targetm.have_omp_simt_exit ());
211 expand_insn (targetm.code_for_omp_simt_exit, 1, ops);
214 /* Lane index on SIMT targets: thread index in the warp on NVPTX. On targets
215 without SIMT execution this should be expanded in omp_device_lower pass. */
217 static void
218 expand_GOMP_SIMT_LANE (internal_fn, gcall *stmt)
220 tree lhs = gimple_call_lhs (stmt);
221 if (!lhs)
222 return;
224 rtx target = expand_expr (lhs, NULL_RTX, VOIDmode, EXPAND_WRITE);
225 gcc_assert (targetm.have_omp_simt_lane ());
226 emit_insn (targetm.gen_omp_simt_lane (target));
229 /* This should get expanded in omp_device_lower pass. */
231 static void
232 expand_GOMP_SIMT_VF (internal_fn, gcall *)
234 gcc_unreachable ();
237 /* Lane index of the first SIMT lane that supplies a non-zero argument.
238 This is a SIMT counterpart to GOMP_SIMD_LAST_LANE, used to represent the
239 lane that executed the last iteration for handling OpenMP lastprivate. */
241 static void
242 expand_GOMP_SIMT_LAST_LANE (internal_fn, gcall *stmt)
244 tree lhs = gimple_call_lhs (stmt);
245 if (!lhs)
246 return;
248 rtx target = expand_expr (lhs, NULL_RTX, VOIDmode, EXPAND_WRITE);
249 rtx cond = expand_normal (gimple_call_arg (stmt, 0));
250 machine_mode mode = TYPE_MODE (TREE_TYPE (lhs));
251 struct expand_operand ops[2];
252 create_output_operand (&ops[0], target, mode);
253 create_input_operand (&ops[1], cond, mode);
254 gcc_assert (targetm.have_omp_simt_last_lane ());
255 expand_insn (targetm.code_for_omp_simt_last_lane, 2, ops);
258 /* Non-transparent predicate used in SIMT lowering of OpenMP "ordered". */
260 static void
261 expand_GOMP_SIMT_ORDERED_PRED (internal_fn, gcall *stmt)
263 tree lhs = gimple_call_lhs (stmt);
264 if (!lhs)
265 return;
267 rtx target = expand_expr (lhs, NULL_RTX, VOIDmode, EXPAND_WRITE);
268 rtx ctr = expand_normal (gimple_call_arg (stmt, 0));
269 machine_mode mode = TYPE_MODE (TREE_TYPE (lhs));
270 struct expand_operand ops[2];
271 create_output_operand (&ops[0], target, mode);
272 create_input_operand (&ops[1], ctr, mode);
273 gcc_assert (targetm.have_omp_simt_ordered ());
274 expand_insn (targetm.code_for_omp_simt_ordered, 2, ops);
277 /* "Or" boolean reduction across SIMT lanes: return non-zero in all lanes if
278 any lane supplies a non-zero argument. */
280 static void
281 expand_GOMP_SIMT_VOTE_ANY (internal_fn, gcall *stmt)
283 tree lhs = gimple_call_lhs (stmt);
284 if (!lhs)
285 return;
287 rtx target = expand_expr (lhs, NULL_RTX, VOIDmode, EXPAND_WRITE);
288 rtx cond = expand_normal (gimple_call_arg (stmt, 0));
289 machine_mode mode = TYPE_MODE (TREE_TYPE (lhs));
290 struct expand_operand ops[2];
291 create_output_operand (&ops[0], target, mode);
292 create_input_operand (&ops[1], cond, mode);
293 gcc_assert (targetm.have_omp_simt_vote_any ());
294 expand_insn (targetm.code_for_omp_simt_vote_any, 2, ops);
297 /* Exchange between SIMT lanes with a "butterfly" pattern: source lane index
298 is destination lane index XOR given offset. */
300 static void
301 expand_GOMP_SIMT_XCHG_BFLY (internal_fn, gcall *stmt)
303 tree lhs = gimple_call_lhs (stmt);
304 if (!lhs)
305 return;
307 rtx target = expand_expr (lhs, NULL_RTX, VOIDmode, EXPAND_WRITE);
308 rtx src = expand_normal (gimple_call_arg (stmt, 0));
309 rtx idx = expand_normal (gimple_call_arg (stmt, 1));
310 machine_mode mode = TYPE_MODE (TREE_TYPE (lhs));
311 struct expand_operand ops[3];
312 create_output_operand (&ops[0], target, mode);
313 create_input_operand (&ops[1], src, mode);
314 create_input_operand (&ops[2], idx, SImode);
315 gcc_assert (targetm.have_omp_simt_xchg_bfly ());
316 expand_insn (targetm.code_for_omp_simt_xchg_bfly, 3, ops);
319 /* Exchange between SIMT lanes according to given source lane index. */
321 static void
322 expand_GOMP_SIMT_XCHG_IDX (internal_fn, gcall *stmt)
324 tree lhs = gimple_call_lhs (stmt);
325 if (!lhs)
326 return;
328 rtx target = expand_expr (lhs, NULL_RTX, VOIDmode, EXPAND_WRITE);
329 rtx src = expand_normal (gimple_call_arg (stmt, 0));
330 rtx idx = expand_normal (gimple_call_arg (stmt, 1));
331 machine_mode mode = TYPE_MODE (TREE_TYPE (lhs));
332 struct expand_operand ops[3];
333 create_output_operand (&ops[0], target, mode);
334 create_input_operand (&ops[1], src, mode);
335 create_input_operand (&ops[2], idx, SImode);
336 gcc_assert (targetm.have_omp_simt_xchg_idx ());
337 expand_insn (targetm.code_for_omp_simt_xchg_idx, 3, ops);
340 /* This should get expanded in adjust_simduid_builtins. */
342 static void
343 expand_GOMP_SIMD_LANE (internal_fn, gcall *)
345 gcc_unreachable ();
348 /* This should get expanded in adjust_simduid_builtins. */
350 static void
351 expand_GOMP_SIMD_VF (internal_fn, gcall *)
353 gcc_unreachable ();
356 /* This should get expanded in adjust_simduid_builtins. */
358 static void
359 expand_GOMP_SIMD_LAST_LANE (internal_fn, gcall *)
361 gcc_unreachable ();
364 /* This should get expanded in adjust_simduid_builtins. */
366 static void
367 expand_GOMP_SIMD_ORDERED_START (internal_fn, gcall *)
369 gcc_unreachable ();
372 /* This should get expanded in adjust_simduid_builtins. */
374 static void
375 expand_GOMP_SIMD_ORDERED_END (internal_fn, gcall *)
377 gcc_unreachable ();
380 /* This should get expanded in the sanopt pass. */
382 static void
383 expand_UBSAN_NULL (internal_fn, gcall *)
385 gcc_unreachable ();
388 /* This should get expanded in the sanopt pass. */
390 static void
391 expand_UBSAN_BOUNDS (internal_fn, gcall *)
393 gcc_unreachable ();
396 /* This should get expanded in the sanopt pass. */
398 static void
399 expand_UBSAN_VPTR (internal_fn, gcall *)
401 gcc_unreachable ();
404 /* This should get expanded in the sanopt pass. */
406 static void
407 expand_UBSAN_PTR (internal_fn, gcall *)
409 gcc_unreachable ();
412 /* This should get expanded in the sanopt pass. */
414 static void
415 expand_UBSAN_OBJECT_SIZE (internal_fn, gcall *)
417 gcc_unreachable ();
420 /* This should get expanded in the sanopt pass. */
422 static void
423 expand_ASAN_CHECK (internal_fn, gcall *)
425 gcc_unreachable ();
428 /* This should get expanded in the sanopt pass. */
430 static void
431 expand_ASAN_MARK (internal_fn, gcall *)
433 gcc_unreachable ();
436 /* This should get expanded in the sanopt pass. */
438 static void
439 expand_ASAN_POISON (internal_fn, gcall *)
441 gcc_unreachable ();
444 /* This should get expanded in the sanopt pass. */
446 static void
447 expand_ASAN_POISON_USE (internal_fn, gcall *)
449 gcc_unreachable ();
452 /* This should get expanded in the tsan pass. */
454 static void
455 expand_TSAN_FUNC_EXIT (internal_fn, gcall *)
457 gcc_unreachable ();
460 /* This should get expanded in the lower pass. */
462 static void
463 expand_FALLTHROUGH (internal_fn, gcall *call)
465 error_at (gimple_location (call),
466 "invalid use of attribute %<fallthrough%>");
469 /* Return minimum precision needed to represent all values
470 of ARG in SIGNed integral type. */
472 static int
473 get_min_precision (tree arg, signop sign)
475 int prec = TYPE_PRECISION (TREE_TYPE (arg));
476 int cnt = 0;
477 signop orig_sign = sign;
478 if (TREE_CODE (arg) == INTEGER_CST)
480 int p;
481 if (TYPE_SIGN (TREE_TYPE (arg)) != sign)
483 widest_int w = wi::to_widest (arg);
484 w = wi::ext (w, prec, sign);
485 p = wi::min_precision (w, sign);
487 else
488 p = wi::min_precision (arg, sign);
489 return MIN (p, prec);
491 while (CONVERT_EXPR_P (arg)
492 && INTEGRAL_TYPE_P (TREE_TYPE (TREE_OPERAND (arg, 0)))
493 && TYPE_PRECISION (TREE_TYPE (TREE_OPERAND (arg, 0))) <= prec)
495 arg = TREE_OPERAND (arg, 0);
496 if (TYPE_PRECISION (TREE_TYPE (arg)) < prec)
498 if (TYPE_UNSIGNED (TREE_TYPE (arg)))
499 sign = UNSIGNED;
500 else if (sign == UNSIGNED && get_range_pos_neg (arg) != 1)
501 return prec + (orig_sign != sign);
502 prec = TYPE_PRECISION (TREE_TYPE (arg));
504 if (++cnt > 30)
505 return prec + (orig_sign != sign);
507 if (TREE_CODE (arg) != SSA_NAME)
508 return prec + (orig_sign != sign);
509 wide_int arg_min, arg_max;
510 while (get_range_info (arg, &arg_min, &arg_max) != VR_RANGE)
512 gimple *g = SSA_NAME_DEF_STMT (arg);
513 if (is_gimple_assign (g)
514 && CONVERT_EXPR_CODE_P (gimple_assign_rhs_code (g)))
516 tree t = gimple_assign_rhs1 (g);
517 if (INTEGRAL_TYPE_P (TREE_TYPE (t))
518 && TYPE_PRECISION (TREE_TYPE (t)) <= prec)
520 arg = t;
521 if (TYPE_PRECISION (TREE_TYPE (arg)) < prec)
523 if (TYPE_UNSIGNED (TREE_TYPE (arg)))
524 sign = UNSIGNED;
525 else if (sign == UNSIGNED && get_range_pos_neg (arg) != 1)
526 return prec + (orig_sign != sign);
527 prec = TYPE_PRECISION (TREE_TYPE (arg));
529 if (++cnt > 30)
530 return prec + (orig_sign != sign);
531 continue;
534 return prec + (orig_sign != sign);
536 if (sign == TYPE_SIGN (TREE_TYPE (arg)))
538 int p1 = wi::min_precision (arg_min, sign);
539 int p2 = wi::min_precision (arg_max, sign);
540 p1 = MAX (p1, p2);
541 prec = MIN (prec, p1);
543 else if (sign == UNSIGNED && !wi::neg_p (arg_min, SIGNED))
545 int p = wi::min_precision (arg_max, UNSIGNED);
546 prec = MIN (prec, p);
548 return prec + (orig_sign != sign);
551 /* Helper for expand_*_overflow. Set the __imag__ part to true
552 (1 except for signed:1 type, in which case store -1). */
554 static void
555 expand_arith_set_overflow (tree lhs, rtx target)
557 if (TYPE_PRECISION (TREE_TYPE (TREE_TYPE (lhs))) == 1
558 && !TYPE_UNSIGNED (TREE_TYPE (TREE_TYPE (lhs))))
559 write_complex_part (target, constm1_rtx, true);
560 else
561 write_complex_part (target, const1_rtx, true);
564 /* Helper for expand_*_overflow. Store RES into the __real__ part
565 of TARGET. If RES has larger MODE than __real__ part of TARGET,
566 set the __imag__ part to 1 if RES doesn't fit into it. Similarly
567 if LHS has smaller precision than its mode. */
569 static void
570 expand_arith_overflow_result_store (tree lhs, rtx target,
571 machine_mode mode, rtx res)
573 machine_mode tgtmode = GET_MODE_INNER (GET_MODE (target));
574 rtx lres = res;
575 if (tgtmode != mode)
577 rtx_code_label *done_label = gen_label_rtx ();
578 int uns = TYPE_UNSIGNED (TREE_TYPE (TREE_TYPE (lhs)));
579 lres = convert_modes (tgtmode, mode, res, uns);
580 gcc_assert (GET_MODE_PRECISION (tgtmode) < GET_MODE_PRECISION (mode));
581 do_compare_rtx_and_jump (res, convert_modes (mode, tgtmode, lres, uns),
582 EQ, true, mode, NULL_RTX, NULL, done_label,
583 profile_probability::very_likely ());
584 expand_arith_set_overflow (lhs, target);
585 emit_label (done_label);
587 int prec = TYPE_PRECISION (TREE_TYPE (TREE_TYPE (lhs)));
588 int tgtprec = GET_MODE_PRECISION (tgtmode);
589 if (prec < tgtprec)
591 rtx_code_label *done_label = gen_label_rtx ();
592 int uns = TYPE_UNSIGNED (TREE_TYPE (TREE_TYPE (lhs)));
593 res = lres;
594 if (uns)
596 rtx mask
597 = immed_wide_int_const (wi::shifted_mask (0, prec, false, tgtprec),
598 tgtmode);
599 lres = expand_simple_binop (tgtmode, AND, res, mask, NULL_RTX,
600 true, OPTAB_LIB_WIDEN);
602 else
604 lres = expand_shift (LSHIFT_EXPR, tgtmode, res, tgtprec - prec,
605 NULL_RTX, 1);
606 lres = expand_shift (RSHIFT_EXPR, tgtmode, lres, tgtprec - prec,
607 NULL_RTX, 0);
609 do_compare_rtx_and_jump (res, lres,
610 EQ, true, tgtmode, NULL_RTX, NULL, done_label,
611 profile_probability::very_likely ());
612 expand_arith_set_overflow (lhs, target);
613 emit_label (done_label);
615 write_complex_part (target, lres, false);
618 /* Helper for expand_*_overflow. Store RES into TARGET. */
620 static void
621 expand_ubsan_result_store (rtx target, rtx res)
623 if (GET_CODE (target) == SUBREG && SUBREG_PROMOTED_VAR_P (target))
624 /* If this is a scalar in a register that is stored in a wider mode
625 than the declared mode, compute the result into its declared mode
626 and then convert to the wider mode. Our value is the computed
627 expression. */
628 convert_move (SUBREG_REG (target), res, SUBREG_PROMOTED_SIGN (target));
629 else
630 emit_move_insn (target, res);
633 /* Add sub/add overflow checking to the statement STMT.
634 CODE says whether the operation is +, or -. */
636 static void
637 expand_addsub_overflow (location_t loc, tree_code code, tree lhs,
638 tree arg0, tree arg1, bool unsr_p, bool uns0_p,
639 bool uns1_p, bool is_ubsan, tree *datap)
641 rtx res, target = NULL_RTX;
642 tree fn;
643 rtx_code_label *done_label = gen_label_rtx ();
644 rtx_code_label *do_error = gen_label_rtx ();
645 do_pending_stack_adjust ();
646 rtx op0 = expand_normal (arg0);
647 rtx op1 = expand_normal (arg1);
648 machine_mode mode = TYPE_MODE (TREE_TYPE (arg0));
649 int prec = GET_MODE_PRECISION (mode);
650 rtx sgn = immed_wide_int_const (wi::min_value (prec, SIGNED), mode);
651 bool do_xor = false;
653 if (is_ubsan)
654 gcc_assert (!unsr_p && !uns0_p && !uns1_p);
656 if (lhs)
658 target = expand_expr (lhs, NULL_RTX, VOIDmode, EXPAND_WRITE);
659 if (!is_ubsan)
660 write_complex_part (target, const0_rtx, true);
663 /* We assume both operands and result have the same precision
664 here (GET_MODE_BITSIZE (mode)), S stands for signed type
665 with that precision, U for unsigned type with that precision,
666 sgn for unsigned most significant bit in that precision.
667 s1 is signed first operand, u1 is unsigned first operand,
668 s2 is signed second operand, u2 is unsigned second operand,
669 sr is signed result, ur is unsigned result and the following
670 rules say how to compute result (which is always result of
671 the operands as if both were unsigned, cast to the right
672 signedness) and how to compute whether operation overflowed.
674 s1 + s2 -> sr
675 res = (S) ((U) s1 + (U) s2)
676 ovf = s2 < 0 ? res > s1 : res < s1 (or jump on overflow)
677 s1 - s2 -> sr
678 res = (S) ((U) s1 - (U) s2)
679 ovf = s2 < 0 ? res < s1 : res > s2 (or jump on overflow)
680 u1 + u2 -> ur
681 res = u1 + u2
682 ovf = res < u1 (or jump on carry, but RTL opts will handle it)
683 u1 - u2 -> ur
684 res = u1 - u2
685 ovf = res > u1 (or jump on carry, but RTL opts will handle it)
686 s1 + u2 -> sr
687 res = (S) ((U) s1 + u2)
688 ovf = ((U) res ^ sgn) < u2
689 s1 + u2 -> ur
690 t1 = (S) (u2 ^ sgn)
691 t2 = s1 + t1
692 res = (U) t2 ^ sgn
693 ovf = t1 < 0 ? t2 > s1 : t2 < s1 (or jump on overflow)
694 s1 - u2 -> sr
695 res = (S) ((U) s1 - u2)
696 ovf = u2 > ((U) s1 ^ sgn)
697 s1 - u2 -> ur
698 res = (U) s1 - u2
699 ovf = s1 < 0 || u2 > (U) s1
700 u1 - s2 -> sr
701 res = u1 - (U) s2
702 ovf = u1 >= ((U) s2 ^ sgn)
703 u1 - s2 -> ur
704 t1 = u1 ^ sgn
705 t2 = t1 - (U) s2
706 res = t2 ^ sgn
707 ovf = s2 < 0 ? (S) t2 < (S) t1 : (S) t2 > (S) t1 (or jump on overflow)
708 s1 + s2 -> ur
709 res = (U) s1 + (U) s2
710 ovf = s2 < 0 ? (s1 | (S) res) < 0) : (s1 & (S) res) < 0)
711 u1 + u2 -> sr
712 res = (S) (u1 + u2)
713 ovf = (U) res < u2 || res < 0
714 u1 - u2 -> sr
715 res = (S) (u1 - u2)
716 ovf = u1 >= u2 ? res < 0 : res >= 0
717 s1 - s2 -> ur
718 res = (U) s1 - (U) s2
719 ovf = s2 >= 0 ? ((s1 | (S) res) < 0) : ((s1 & (S) res) < 0) */
721 if (code == PLUS_EXPR && uns0_p && !uns1_p)
723 /* PLUS_EXPR is commutative, if operand signedness differs,
724 canonicalize to the first operand being signed and second
725 unsigned to simplify following code. */
726 std::swap (op0, op1);
727 std::swap (arg0, arg1);
728 uns0_p = false;
729 uns1_p = true;
732 /* u1 +- u2 -> ur */
733 if (uns0_p && uns1_p && unsr_p)
735 insn_code icode = optab_handler (code == PLUS_EXPR ? uaddv4_optab
736 : usubv4_optab, mode);
737 if (icode != CODE_FOR_nothing)
739 struct expand_operand ops[4];
740 rtx_insn *last = get_last_insn ();
742 res = gen_reg_rtx (mode);
743 create_output_operand (&ops[0], res, mode);
744 create_input_operand (&ops[1], op0, mode);
745 create_input_operand (&ops[2], op1, mode);
746 create_fixed_operand (&ops[3], do_error);
747 if (maybe_expand_insn (icode, 4, ops))
749 last = get_last_insn ();
750 if (profile_status_for_fn (cfun) != PROFILE_ABSENT
751 && JUMP_P (last)
752 && any_condjump_p (last)
753 && !find_reg_note (last, REG_BR_PROB, 0))
754 add_reg_br_prob_note (last,
755 profile_probability::very_unlikely ());
756 emit_jump (done_label);
757 goto do_error_label;
760 delete_insns_since (last);
763 /* Compute the operation. On RTL level, the addition is always
764 unsigned. */
765 res = expand_binop (mode, code == PLUS_EXPR ? add_optab : sub_optab,
766 op0, op1, NULL_RTX, false, OPTAB_LIB_WIDEN);
767 rtx tem = op0;
768 /* For PLUS_EXPR, the operation is commutative, so we can pick
769 operand to compare against. For prec <= BITS_PER_WORD, I think
770 preferring REG operand is better over CONST_INT, because
771 the CONST_INT might enlarge the instruction or CSE would need
772 to figure out we'd already loaded it into a register before.
773 For prec > BITS_PER_WORD, I think CONST_INT might be more beneficial,
774 as then the multi-word comparison can be perhaps simplified. */
775 if (code == PLUS_EXPR
776 && (prec <= BITS_PER_WORD
777 ? (CONST_SCALAR_INT_P (op0) && REG_P (op1))
778 : CONST_SCALAR_INT_P (op1)))
779 tem = op1;
780 do_compare_rtx_and_jump (res, tem, code == PLUS_EXPR ? GEU : LEU,
781 true, mode, NULL_RTX, NULL, done_label,
782 profile_probability::very_likely ());
783 goto do_error_label;
786 /* s1 +- u2 -> sr */
787 if (!uns0_p && uns1_p && !unsr_p)
789 /* Compute the operation. On RTL level, the addition is always
790 unsigned. */
791 res = expand_binop (mode, code == PLUS_EXPR ? add_optab : sub_optab,
792 op0, op1, NULL_RTX, false, OPTAB_LIB_WIDEN);
793 rtx tem = expand_binop (mode, add_optab,
794 code == PLUS_EXPR ? res : op0, sgn,
795 NULL_RTX, false, OPTAB_LIB_WIDEN);
796 do_compare_rtx_and_jump (tem, op1, GEU, true, mode, NULL_RTX, NULL,
797 done_label, profile_probability::very_likely ());
798 goto do_error_label;
801 /* s1 + u2 -> ur */
802 if (code == PLUS_EXPR && !uns0_p && uns1_p && unsr_p)
804 op1 = expand_binop (mode, add_optab, op1, sgn, NULL_RTX, false,
805 OPTAB_LIB_WIDEN);
806 /* As we've changed op1, we have to avoid using the value range
807 for the original argument. */
808 arg1 = error_mark_node;
809 do_xor = true;
810 goto do_signed;
813 /* u1 - s2 -> ur */
814 if (code == MINUS_EXPR && uns0_p && !uns1_p && unsr_p)
816 op0 = expand_binop (mode, add_optab, op0, sgn, NULL_RTX, false,
817 OPTAB_LIB_WIDEN);
818 /* As we've changed op0, we have to avoid using the value range
819 for the original argument. */
820 arg0 = error_mark_node;
821 do_xor = true;
822 goto do_signed;
825 /* s1 - u2 -> ur */
826 if (code == MINUS_EXPR && !uns0_p && uns1_p && unsr_p)
828 /* Compute the operation. On RTL level, the addition is always
829 unsigned. */
830 res = expand_binop (mode, sub_optab, op0, op1, NULL_RTX, false,
831 OPTAB_LIB_WIDEN);
832 int pos_neg = get_range_pos_neg (arg0);
833 if (pos_neg == 2)
834 /* If ARG0 is known to be always negative, this is always overflow. */
835 emit_jump (do_error);
836 else if (pos_neg == 3)
837 /* If ARG0 is not known to be always positive, check at runtime. */
838 do_compare_rtx_and_jump (op0, const0_rtx, LT, false, mode, NULL_RTX,
839 NULL, do_error, profile_probability::very_unlikely ());
840 do_compare_rtx_and_jump (op1, op0, LEU, true, mode, NULL_RTX, NULL,
841 done_label, profile_probability::very_likely ());
842 goto do_error_label;
845 /* u1 - s2 -> sr */
846 if (code == MINUS_EXPR && uns0_p && !uns1_p && !unsr_p)
848 /* Compute the operation. On RTL level, the addition is always
849 unsigned. */
850 res = expand_binop (mode, sub_optab, op0, op1, NULL_RTX, false,
851 OPTAB_LIB_WIDEN);
852 rtx tem = expand_binop (mode, add_optab, op1, sgn, NULL_RTX, false,
853 OPTAB_LIB_WIDEN);
854 do_compare_rtx_and_jump (op0, tem, LTU, true, mode, NULL_RTX, NULL,
855 done_label, profile_probability::very_likely ());
856 goto do_error_label;
859 /* u1 + u2 -> sr */
860 if (code == PLUS_EXPR && uns0_p && uns1_p && !unsr_p)
862 /* Compute the operation. On RTL level, the addition is always
863 unsigned. */
864 res = expand_binop (mode, add_optab, op0, op1, NULL_RTX, false,
865 OPTAB_LIB_WIDEN);
866 do_compare_rtx_and_jump (res, const0_rtx, LT, false, mode, NULL_RTX,
867 NULL, do_error, profile_probability::very_unlikely ());
868 rtx tem = op1;
869 /* The operation is commutative, so we can pick operand to compare
870 against. For prec <= BITS_PER_WORD, I think preferring REG operand
871 is better over CONST_INT, because the CONST_INT might enlarge the
872 instruction or CSE would need to figure out we'd already loaded it
873 into a register before. For prec > BITS_PER_WORD, I think CONST_INT
874 might be more beneficial, as then the multi-word comparison can be
875 perhaps simplified. */
876 if (prec <= BITS_PER_WORD
877 ? (CONST_SCALAR_INT_P (op1) && REG_P (op0))
878 : CONST_SCALAR_INT_P (op0))
879 tem = op0;
880 do_compare_rtx_and_jump (res, tem, GEU, true, mode, NULL_RTX, NULL,
881 done_label, profile_probability::very_likely ());
882 goto do_error_label;
885 /* s1 +- s2 -> ur */
886 if (!uns0_p && !uns1_p && unsr_p)
888 /* Compute the operation. On RTL level, the addition is always
889 unsigned. */
890 res = expand_binop (mode, code == PLUS_EXPR ? add_optab : sub_optab,
891 op0, op1, NULL_RTX, false, OPTAB_LIB_WIDEN);
892 int pos_neg = get_range_pos_neg (arg1);
893 if (code == PLUS_EXPR)
895 int pos_neg0 = get_range_pos_neg (arg0);
896 if (pos_neg0 != 3 && pos_neg == 3)
898 std::swap (op0, op1);
899 pos_neg = pos_neg0;
902 rtx tem;
903 if (pos_neg != 3)
905 tem = expand_binop (mode, ((pos_neg == 1) ^ (code == MINUS_EXPR))
906 ? and_optab : ior_optab,
907 op0, res, NULL_RTX, false, OPTAB_LIB_WIDEN);
908 do_compare_rtx_and_jump (tem, const0_rtx, GE, false, mode, NULL,
909 NULL, done_label, profile_probability::very_likely ());
911 else
913 rtx_code_label *do_ior_label = gen_label_rtx ();
914 do_compare_rtx_and_jump (op1, const0_rtx,
915 code == MINUS_EXPR ? GE : LT, false, mode,
916 NULL_RTX, NULL, do_ior_label,
917 profile_probability::even ());
918 tem = expand_binop (mode, and_optab, op0, res, NULL_RTX, false,
919 OPTAB_LIB_WIDEN);
920 do_compare_rtx_and_jump (tem, const0_rtx, GE, false, mode, NULL_RTX,
921 NULL, done_label, profile_probability::very_likely ());
922 emit_jump (do_error);
923 emit_label (do_ior_label);
924 tem = expand_binop (mode, ior_optab, op0, res, NULL_RTX, false,
925 OPTAB_LIB_WIDEN);
926 do_compare_rtx_and_jump (tem, const0_rtx, GE, false, mode, NULL_RTX,
927 NULL, done_label, profile_probability::very_likely ());
929 goto do_error_label;
932 /* u1 - u2 -> sr */
933 if (code == MINUS_EXPR && uns0_p && uns1_p && !unsr_p)
935 /* Compute the operation. On RTL level, the addition is always
936 unsigned. */
937 res = expand_binop (mode, sub_optab, op0, op1, NULL_RTX, false,
938 OPTAB_LIB_WIDEN);
939 rtx_code_label *op0_geu_op1 = gen_label_rtx ();
940 do_compare_rtx_and_jump (op0, op1, GEU, true, mode, NULL_RTX, NULL,
941 op0_geu_op1, profile_probability::even ());
942 do_compare_rtx_and_jump (res, const0_rtx, LT, false, mode, NULL_RTX,
943 NULL, done_label, profile_probability::very_likely ());
944 emit_jump (do_error);
945 emit_label (op0_geu_op1);
946 do_compare_rtx_and_jump (res, const0_rtx, GE, false, mode, NULL_RTX,
947 NULL, done_label, profile_probability::very_likely ());
948 goto do_error_label;
951 gcc_assert (!uns0_p && !uns1_p && !unsr_p);
953 /* s1 +- s2 -> sr */
954 do_signed:
956 insn_code icode = optab_handler (code == PLUS_EXPR ? addv4_optab
957 : subv4_optab, mode);
958 if (icode != CODE_FOR_nothing)
960 struct expand_operand ops[4];
961 rtx_insn *last = get_last_insn ();
963 res = gen_reg_rtx (mode);
964 create_output_operand (&ops[0], res, mode);
965 create_input_operand (&ops[1], op0, mode);
966 create_input_operand (&ops[2], op1, mode);
967 create_fixed_operand (&ops[3], do_error);
968 if (maybe_expand_insn (icode, 4, ops))
970 last = get_last_insn ();
971 if (profile_status_for_fn (cfun) != PROFILE_ABSENT
972 && JUMP_P (last)
973 && any_condjump_p (last)
974 && !find_reg_note (last, REG_BR_PROB, 0))
975 add_reg_br_prob_note (last,
976 profile_probability::very_unlikely ());
977 emit_jump (done_label);
978 goto do_error_label;
981 delete_insns_since (last);
984 /* Compute the operation. On RTL level, the addition is always
985 unsigned. */
986 res = expand_binop (mode, code == PLUS_EXPR ? add_optab : sub_optab,
987 op0, op1, NULL_RTX, false, OPTAB_LIB_WIDEN);
989 /* If we can prove that one of the arguments (for MINUS_EXPR only
990 the second operand, as subtraction is not commutative) is always
991 non-negative or always negative, we can do just one comparison
992 and conditional jump. */
993 int pos_neg = get_range_pos_neg (arg1);
994 if (code == PLUS_EXPR)
996 int pos_neg0 = get_range_pos_neg (arg0);
997 if (pos_neg0 != 3 && pos_neg == 3)
999 std::swap (op0, op1);
1000 pos_neg = pos_neg0;
1004 /* Addition overflows if and only if the two operands have the same sign,
1005 and the result has the opposite sign. Subtraction overflows if and
1006 only if the two operands have opposite sign, and the subtrahend has
1007 the same sign as the result. Here 0 is counted as positive. */
1008 if (pos_neg == 3)
1010 /* Compute op0 ^ op1 (operands have opposite sign). */
1011 rtx op_xor = expand_binop (mode, xor_optab, op0, op1, NULL_RTX, false,
1012 OPTAB_LIB_WIDEN);
1014 /* Compute res ^ op1 (result and 2nd operand have opposite sign). */
1015 rtx res_xor = expand_binop (mode, xor_optab, res, op1, NULL_RTX, false,
1016 OPTAB_LIB_WIDEN);
1018 rtx tem;
1019 if (code == PLUS_EXPR)
1021 /* Compute (res ^ op1) & ~(op0 ^ op1). */
1022 tem = expand_unop (mode, one_cmpl_optab, op_xor, NULL_RTX, false);
1023 tem = expand_binop (mode, and_optab, res_xor, tem, NULL_RTX, false,
1024 OPTAB_LIB_WIDEN);
1026 else
1028 /* Compute (op0 ^ op1) & ~(res ^ op1). */
1029 tem = expand_unop (mode, one_cmpl_optab, res_xor, NULL_RTX, false);
1030 tem = expand_binop (mode, and_optab, op_xor, tem, NULL_RTX, false,
1031 OPTAB_LIB_WIDEN);
1034 /* No overflow if the result has bit sign cleared. */
1035 do_compare_rtx_and_jump (tem, const0_rtx, GE, false, mode, NULL_RTX,
1036 NULL, done_label, profile_probability::very_likely ());
1039 /* Compare the result of the operation with the first operand.
1040 No overflow for addition if second operand is positive and result
1041 is larger or second operand is negative and result is smaller.
1042 Likewise for subtraction with sign of second operand flipped. */
1043 else
1044 do_compare_rtx_and_jump (res, op0,
1045 (pos_neg == 1) ^ (code == MINUS_EXPR) ? GE : LE,
1046 false, mode, NULL_RTX, NULL, done_label,
1047 profile_probability::very_likely ());
1050 do_error_label:
1051 emit_label (do_error);
1052 if (is_ubsan)
1054 /* Expand the ubsan builtin call. */
1055 push_temp_slots ();
1056 fn = ubsan_build_overflow_builtin (code, loc, TREE_TYPE (arg0),
1057 arg0, arg1, datap);
1058 expand_normal (fn);
1059 pop_temp_slots ();
1060 do_pending_stack_adjust ();
1062 else if (lhs)
1063 expand_arith_set_overflow (lhs, target);
1065 /* We're done. */
1066 emit_label (done_label);
1068 if (lhs)
1070 if (is_ubsan)
1071 expand_ubsan_result_store (target, res);
1072 else
1074 if (do_xor)
1075 res = expand_binop (mode, add_optab, res, sgn, NULL_RTX, false,
1076 OPTAB_LIB_WIDEN);
1078 expand_arith_overflow_result_store (lhs, target, mode, res);
1083 /* Add negate overflow checking to the statement STMT. */
1085 static void
1086 expand_neg_overflow (location_t loc, tree lhs, tree arg1, bool is_ubsan,
1087 tree *datap)
1089 rtx res, op1;
1090 tree fn;
1091 rtx_code_label *done_label, *do_error;
1092 rtx target = NULL_RTX;
1094 done_label = gen_label_rtx ();
1095 do_error = gen_label_rtx ();
1097 do_pending_stack_adjust ();
1098 op1 = expand_normal (arg1);
1100 machine_mode mode = TYPE_MODE (TREE_TYPE (arg1));
1101 if (lhs)
1103 target = expand_expr (lhs, NULL_RTX, VOIDmode, EXPAND_WRITE);
1104 if (!is_ubsan)
1105 write_complex_part (target, const0_rtx, true);
1108 enum insn_code icode = optab_handler (negv3_optab, mode);
1109 if (icode != CODE_FOR_nothing)
1111 struct expand_operand ops[3];
1112 rtx_insn *last = get_last_insn ();
1114 res = gen_reg_rtx (mode);
1115 create_output_operand (&ops[0], res, mode);
1116 create_input_operand (&ops[1], op1, mode);
1117 create_fixed_operand (&ops[2], do_error);
1118 if (maybe_expand_insn (icode, 3, ops))
1120 last = get_last_insn ();
1121 if (profile_status_for_fn (cfun) != PROFILE_ABSENT
1122 && JUMP_P (last)
1123 && any_condjump_p (last)
1124 && !find_reg_note (last, REG_BR_PROB, 0))
1125 add_reg_br_prob_note (last,
1126 profile_probability::very_unlikely ());
1127 emit_jump (done_label);
1129 else
1131 delete_insns_since (last);
1132 icode = CODE_FOR_nothing;
1136 if (icode == CODE_FOR_nothing)
1138 /* Compute the operation. On RTL level, the addition is always
1139 unsigned. */
1140 res = expand_unop (mode, neg_optab, op1, NULL_RTX, false);
1142 /* Compare the operand with the most negative value. */
1143 rtx minv = expand_normal (TYPE_MIN_VALUE (TREE_TYPE (arg1)));
1144 do_compare_rtx_and_jump (op1, minv, NE, true, mode, NULL_RTX, NULL,
1145 done_label, profile_probability::very_likely ());
1148 emit_label (do_error);
1149 if (is_ubsan)
1151 /* Expand the ubsan builtin call. */
1152 push_temp_slots ();
1153 fn = ubsan_build_overflow_builtin (NEGATE_EXPR, loc, TREE_TYPE (arg1),
1154 arg1, NULL_TREE, datap);
1155 expand_normal (fn);
1156 pop_temp_slots ();
1157 do_pending_stack_adjust ();
1159 else if (lhs)
1160 expand_arith_set_overflow (lhs, target);
1162 /* We're done. */
1163 emit_label (done_label);
1165 if (lhs)
1167 if (is_ubsan)
1168 expand_ubsan_result_store (target, res);
1169 else
1170 expand_arith_overflow_result_store (lhs, target, mode, res);
1174 /* Add mul overflow checking to the statement STMT. */
1176 static void
1177 expand_mul_overflow (location_t loc, tree lhs, tree arg0, tree arg1,
1178 bool unsr_p, bool uns0_p, bool uns1_p, bool is_ubsan,
1179 tree *datap)
1181 rtx res, op0, op1;
1182 tree fn, type;
1183 rtx_code_label *done_label, *do_error;
1184 rtx target = NULL_RTX;
1185 signop sign;
1186 enum insn_code icode;
1188 done_label = gen_label_rtx ();
1189 do_error = gen_label_rtx ();
1191 do_pending_stack_adjust ();
1192 op0 = expand_normal (arg0);
1193 op1 = expand_normal (arg1);
1195 machine_mode mode = TYPE_MODE (TREE_TYPE (arg0));
1196 bool uns = unsr_p;
1197 if (lhs)
1199 target = expand_expr (lhs, NULL_RTX, VOIDmode, EXPAND_WRITE);
1200 if (!is_ubsan)
1201 write_complex_part (target, const0_rtx, true);
1204 if (is_ubsan)
1205 gcc_assert (!unsr_p && !uns0_p && !uns1_p);
1207 /* We assume both operands and result have the same precision
1208 here (GET_MODE_BITSIZE (mode)), S stands for signed type
1209 with that precision, U for unsigned type with that precision,
1210 sgn for unsigned most significant bit in that precision.
1211 s1 is signed first operand, u1 is unsigned first operand,
1212 s2 is signed second operand, u2 is unsigned second operand,
1213 sr is signed result, ur is unsigned result and the following
1214 rules say how to compute result (which is always result of
1215 the operands as if both were unsigned, cast to the right
1216 signedness) and how to compute whether operation overflowed.
1217 main_ovf (false) stands for jump on signed multiplication
1218 overflow or the main algorithm with uns == false.
1219 main_ovf (true) stands for jump on unsigned multiplication
1220 overflow or the main algorithm with uns == true.
1222 s1 * s2 -> sr
1223 res = (S) ((U) s1 * (U) s2)
1224 ovf = main_ovf (false)
1225 u1 * u2 -> ur
1226 res = u1 * u2
1227 ovf = main_ovf (true)
1228 s1 * u2 -> ur
1229 res = (U) s1 * u2
1230 ovf = (s1 < 0 && u2) || main_ovf (true)
1231 u1 * u2 -> sr
1232 res = (S) (u1 * u2)
1233 ovf = res < 0 || main_ovf (true)
1234 s1 * u2 -> sr
1235 res = (S) ((U) s1 * u2)
1236 ovf = (S) u2 >= 0 ? main_ovf (false)
1237 : (s1 != 0 && (s1 != -1 || u2 != (U) res))
1238 s1 * s2 -> ur
1239 t1 = (s1 & s2) < 0 ? (-(U) s1) : ((U) s1)
1240 t2 = (s1 & s2) < 0 ? (-(U) s2) : ((U) s2)
1241 res = t1 * t2
1242 ovf = (s1 ^ s2) < 0 ? (s1 && s2) : main_ovf (true) */
1244 if (uns0_p && !uns1_p)
1246 /* Multiplication is commutative, if operand signedness differs,
1247 canonicalize to the first operand being signed and second
1248 unsigned to simplify following code. */
1249 std::swap (op0, op1);
1250 std::swap (arg0, arg1);
1251 uns0_p = false;
1252 uns1_p = true;
1255 int pos_neg0 = get_range_pos_neg (arg0);
1256 int pos_neg1 = get_range_pos_neg (arg1);
1258 /* s1 * u2 -> ur */
1259 if (!uns0_p && uns1_p && unsr_p)
1261 switch (pos_neg0)
1263 case 1:
1264 /* If s1 is non-negative, just perform normal u1 * u2 -> ur. */
1265 goto do_main;
1266 case 2:
1267 /* If s1 is negative, avoid the main code, just multiply and
1268 signal overflow if op1 is not 0. */
1269 struct separate_ops ops;
1270 ops.code = MULT_EXPR;
1271 ops.type = TREE_TYPE (arg1);
1272 ops.op0 = make_tree (ops.type, op0);
1273 ops.op1 = make_tree (ops.type, op1);
1274 ops.op2 = NULL_TREE;
1275 ops.location = loc;
1276 res = expand_expr_real_2 (&ops, NULL_RTX, mode, EXPAND_NORMAL);
1277 do_compare_rtx_and_jump (op1, const0_rtx, EQ, true, mode, NULL_RTX,
1278 NULL, done_label, profile_probability::very_likely ());
1279 goto do_error_label;
1280 case 3:
1281 rtx_code_label *do_main_label;
1282 do_main_label = gen_label_rtx ();
1283 do_compare_rtx_and_jump (op0, const0_rtx, GE, false, mode, NULL_RTX,
1284 NULL, do_main_label, profile_probability::very_likely ());
1285 do_compare_rtx_and_jump (op1, const0_rtx, EQ, true, mode, NULL_RTX,
1286 NULL, do_main_label, profile_probability::very_likely ());
1287 expand_arith_set_overflow (lhs, target);
1288 emit_label (do_main_label);
1289 goto do_main;
1290 default:
1291 gcc_unreachable ();
1295 /* u1 * u2 -> sr */
1296 if (uns0_p && uns1_p && !unsr_p)
1298 uns = true;
1299 /* Rest of handling of this case after res is computed. */
1300 goto do_main;
1303 /* s1 * u2 -> sr */
1304 if (!uns0_p && uns1_p && !unsr_p)
1306 switch (pos_neg1)
1308 case 1:
1309 goto do_main;
1310 case 2:
1311 /* If (S) u2 is negative (i.e. u2 is larger than maximum of S,
1312 avoid the main code, just multiply and signal overflow
1313 unless 0 * u2 or -1 * ((U) Smin). */
1314 struct separate_ops ops;
1315 ops.code = MULT_EXPR;
1316 ops.type = TREE_TYPE (arg1);
1317 ops.op0 = make_tree (ops.type, op0);
1318 ops.op1 = make_tree (ops.type, op1);
1319 ops.op2 = NULL_TREE;
1320 ops.location = loc;
1321 res = expand_expr_real_2 (&ops, NULL_RTX, mode, EXPAND_NORMAL);
1322 do_compare_rtx_and_jump (op0, const0_rtx, EQ, true, mode, NULL_RTX,
1323 NULL, done_label, profile_probability::very_likely ());
1324 do_compare_rtx_and_jump (op0, constm1_rtx, NE, true, mode, NULL_RTX,
1325 NULL, do_error, profile_probability::very_unlikely ());
1326 int prec;
1327 prec = GET_MODE_PRECISION (mode);
1328 rtx sgn;
1329 sgn = immed_wide_int_const (wi::min_value (prec, SIGNED), mode);
1330 do_compare_rtx_and_jump (op1, sgn, EQ, true, mode, NULL_RTX,
1331 NULL, done_label, profile_probability::very_likely ());
1332 goto do_error_label;
1333 case 3:
1334 /* Rest of handling of this case after res is computed. */
1335 goto do_main;
1336 default:
1337 gcc_unreachable ();
1341 /* s1 * s2 -> ur */
1342 if (!uns0_p && !uns1_p && unsr_p)
1344 rtx tem, tem2;
1345 switch (pos_neg0 | pos_neg1)
1347 case 1: /* Both operands known to be non-negative. */
1348 goto do_main;
1349 case 2: /* Both operands known to be negative. */
1350 op0 = expand_unop (mode, neg_optab, op0, NULL_RTX, false);
1351 op1 = expand_unop (mode, neg_optab, op1, NULL_RTX, false);
1352 /* Avoid looking at arg0/arg1 ranges, as we've changed
1353 the arguments. */
1354 arg0 = error_mark_node;
1355 arg1 = error_mark_node;
1356 goto do_main;
1357 case 3:
1358 if ((pos_neg0 ^ pos_neg1) == 3)
1360 /* If one operand is known to be negative and the other
1361 non-negative, this overflows always, unless the non-negative
1362 one is 0. Just do normal multiply and set overflow
1363 unless one of the operands is 0. */
1364 struct separate_ops ops;
1365 ops.code = MULT_EXPR;
1366 ops.type
1367 = build_nonstandard_integer_type (GET_MODE_PRECISION (mode),
1369 ops.op0 = make_tree (ops.type, op0);
1370 ops.op1 = make_tree (ops.type, op1);
1371 ops.op2 = NULL_TREE;
1372 ops.location = loc;
1373 res = expand_expr_real_2 (&ops, NULL_RTX, mode, EXPAND_NORMAL);
1374 tem = expand_binop (mode, and_optab, op0, op1, NULL_RTX, false,
1375 OPTAB_LIB_WIDEN);
1376 do_compare_rtx_and_jump (tem, const0_rtx, EQ, true, mode,
1377 NULL_RTX, NULL, done_label,
1378 profile_probability::very_likely ());
1379 goto do_error_label;
1381 /* The general case, do all the needed comparisons at runtime. */
1382 rtx_code_label *do_main_label, *after_negate_label;
1383 rtx rop0, rop1;
1384 rop0 = gen_reg_rtx (mode);
1385 rop1 = gen_reg_rtx (mode);
1386 emit_move_insn (rop0, op0);
1387 emit_move_insn (rop1, op1);
1388 op0 = rop0;
1389 op1 = rop1;
1390 do_main_label = gen_label_rtx ();
1391 after_negate_label = gen_label_rtx ();
1392 tem = expand_binop (mode, and_optab, op0, op1, NULL_RTX, false,
1393 OPTAB_LIB_WIDEN);
1394 do_compare_rtx_and_jump (tem, const0_rtx, GE, false, mode, NULL_RTX,
1395 NULL, after_negate_label, profile_probability::very_likely ());
1396 /* Both arguments negative here, negate them and continue with
1397 normal unsigned overflow checking multiplication. */
1398 emit_move_insn (op0, expand_unop (mode, neg_optab, op0,
1399 NULL_RTX, false));
1400 emit_move_insn (op1, expand_unop (mode, neg_optab, op1,
1401 NULL_RTX, false));
1402 /* Avoid looking at arg0/arg1 ranges, as we might have changed
1403 the arguments. */
1404 arg0 = error_mark_node;
1405 arg1 = error_mark_node;
1406 emit_jump (do_main_label);
1407 emit_label (after_negate_label);
1408 tem2 = expand_binop (mode, xor_optab, op0, op1, NULL_RTX, false,
1409 OPTAB_LIB_WIDEN);
1410 do_compare_rtx_and_jump (tem2, const0_rtx, GE, false, mode, NULL_RTX,
1411 NULL, do_main_label, profile_probability::very_likely ());
1412 /* One argument is negative here, the other positive. This
1413 overflows always, unless one of the arguments is 0. But
1414 if e.g. s2 is 0, (U) s1 * 0 doesn't overflow, whatever s1
1415 is, thus we can keep do_main code oring in overflow as is. */
1416 do_compare_rtx_and_jump (tem, const0_rtx, EQ, true, mode, NULL_RTX,
1417 NULL, do_main_label, profile_probability::very_likely ());
1418 expand_arith_set_overflow (lhs, target);
1419 emit_label (do_main_label);
1420 goto do_main;
1421 default:
1422 gcc_unreachable ();
1426 do_main:
1427 type = build_nonstandard_integer_type (GET_MODE_PRECISION (mode), uns);
1428 sign = uns ? UNSIGNED : SIGNED;
1429 icode = optab_handler (uns ? umulv4_optab : mulv4_optab, mode);
1430 if (icode != CODE_FOR_nothing)
1432 struct expand_operand ops[4];
1433 rtx_insn *last = get_last_insn ();
1435 res = gen_reg_rtx (mode);
1436 create_output_operand (&ops[0], res, mode);
1437 create_input_operand (&ops[1], op0, mode);
1438 create_input_operand (&ops[2], op1, mode);
1439 create_fixed_operand (&ops[3], do_error);
1440 if (maybe_expand_insn (icode, 4, ops))
1442 last = get_last_insn ();
1443 if (profile_status_for_fn (cfun) != PROFILE_ABSENT
1444 && JUMP_P (last)
1445 && any_condjump_p (last)
1446 && !find_reg_note (last, REG_BR_PROB, 0))
1447 add_reg_br_prob_note (last,
1448 profile_probability::very_unlikely ());
1449 emit_jump (done_label);
1451 else
1453 delete_insns_since (last);
1454 icode = CODE_FOR_nothing;
1458 if (icode == CODE_FOR_nothing)
1460 struct separate_ops ops;
1461 int prec = GET_MODE_PRECISION (mode);
1462 machine_mode hmode = mode_for_size (prec / 2, MODE_INT, 1);
1463 ops.op0 = make_tree (type, op0);
1464 ops.op1 = make_tree (type, op1);
1465 ops.op2 = NULL_TREE;
1466 ops.location = loc;
1467 if (GET_MODE_2XWIDER_MODE (mode) != VOIDmode
1468 && targetm.scalar_mode_supported_p (GET_MODE_2XWIDER_MODE (mode)))
1470 machine_mode wmode = GET_MODE_2XWIDER_MODE (mode);
1471 ops.code = WIDEN_MULT_EXPR;
1472 ops.type
1473 = build_nonstandard_integer_type (GET_MODE_PRECISION (wmode), uns);
1475 res = expand_expr_real_2 (&ops, NULL_RTX, wmode, EXPAND_NORMAL);
1476 rtx hipart = expand_shift (RSHIFT_EXPR, wmode, res, prec,
1477 NULL_RTX, uns);
1478 hipart = convert_modes (mode, wmode, hipart, uns);
1479 res = convert_modes (mode, wmode, res, uns);
1480 if (uns)
1481 /* For the unsigned multiplication, there was overflow if
1482 HIPART is non-zero. */
1483 do_compare_rtx_and_jump (hipart, const0_rtx, EQ, true, mode,
1484 NULL_RTX, NULL, done_label,
1485 profile_probability::very_likely ());
1486 else
1488 rtx signbit = expand_shift (RSHIFT_EXPR, mode, res, prec - 1,
1489 NULL_RTX, 0);
1490 /* RES is low half of the double width result, HIPART
1491 the high half. There was overflow if
1492 HIPART is different from RES < 0 ? -1 : 0. */
1493 do_compare_rtx_and_jump (signbit, hipart, EQ, true, mode,
1494 NULL_RTX, NULL, done_label,
1495 profile_probability::very_likely ());
1498 else if (hmode != BLKmode && 2 * GET_MODE_PRECISION (hmode) == prec)
1500 rtx_code_label *large_op0 = gen_label_rtx ();
1501 rtx_code_label *small_op0_large_op1 = gen_label_rtx ();
1502 rtx_code_label *one_small_one_large = gen_label_rtx ();
1503 rtx_code_label *both_ops_large = gen_label_rtx ();
1504 rtx_code_label *after_hipart_neg = uns ? NULL : gen_label_rtx ();
1505 rtx_code_label *after_lopart_neg = uns ? NULL : gen_label_rtx ();
1506 rtx_code_label *do_overflow = gen_label_rtx ();
1507 rtx_code_label *hipart_different = uns ? NULL : gen_label_rtx ();
1509 unsigned int hprec = GET_MODE_PRECISION (hmode);
1510 rtx hipart0 = expand_shift (RSHIFT_EXPR, mode, op0, hprec,
1511 NULL_RTX, uns);
1512 hipart0 = convert_modes (hmode, mode, hipart0, uns);
1513 rtx lopart0 = convert_modes (hmode, mode, op0, uns);
1514 rtx signbit0 = const0_rtx;
1515 if (!uns)
1516 signbit0 = expand_shift (RSHIFT_EXPR, hmode, lopart0, hprec - 1,
1517 NULL_RTX, 0);
1518 rtx hipart1 = expand_shift (RSHIFT_EXPR, mode, op1, hprec,
1519 NULL_RTX, uns);
1520 hipart1 = convert_modes (hmode, mode, hipart1, uns);
1521 rtx lopart1 = convert_modes (hmode, mode, op1, uns);
1522 rtx signbit1 = const0_rtx;
1523 if (!uns)
1524 signbit1 = expand_shift (RSHIFT_EXPR, hmode, lopart1, hprec - 1,
1525 NULL_RTX, 0);
1527 res = gen_reg_rtx (mode);
1529 /* True if op0 resp. op1 are known to be in the range of
1530 halfstype. */
1531 bool op0_small_p = false;
1532 bool op1_small_p = false;
1533 /* True if op0 resp. op1 are known to have all zeros or all ones
1534 in the upper half of bits, but are not known to be
1535 op{0,1}_small_p. */
1536 bool op0_medium_p = false;
1537 bool op1_medium_p = false;
1538 /* -1 if op{0,1} is known to be negative, 0 if it is known to be
1539 nonnegative, 1 if unknown. */
1540 int op0_sign = 1;
1541 int op1_sign = 1;
1543 if (pos_neg0 == 1)
1544 op0_sign = 0;
1545 else if (pos_neg0 == 2)
1546 op0_sign = -1;
1547 if (pos_neg1 == 1)
1548 op1_sign = 0;
1549 else if (pos_neg1 == 2)
1550 op1_sign = -1;
1552 unsigned int mprec0 = prec;
1553 if (arg0 != error_mark_node)
1554 mprec0 = get_min_precision (arg0, sign);
1555 if (mprec0 <= hprec)
1556 op0_small_p = true;
1557 else if (!uns && mprec0 <= hprec + 1)
1558 op0_medium_p = true;
1559 unsigned int mprec1 = prec;
1560 if (arg1 != error_mark_node)
1561 mprec1 = get_min_precision (arg1, sign);
1562 if (mprec1 <= hprec)
1563 op1_small_p = true;
1564 else if (!uns && mprec1 <= hprec + 1)
1565 op1_medium_p = true;
1567 int smaller_sign = 1;
1568 int larger_sign = 1;
1569 if (op0_small_p)
1571 smaller_sign = op0_sign;
1572 larger_sign = op1_sign;
1574 else if (op1_small_p)
1576 smaller_sign = op1_sign;
1577 larger_sign = op0_sign;
1579 else if (op0_sign == op1_sign)
1581 smaller_sign = op0_sign;
1582 larger_sign = op0_sign;
1585 if (!op0_small_p)
1586 do_compare_rtx_and_jump (signbit0, hipart0, NE, true, hmode,
1587 NULL_RTX, NULL, large_op0,
1588 profile_probability::unlikely ());
1590 if (!op1_small_p)
1591 do_compare_rtx_and_jump (signbit1, hipart1, NE, true, hmode,
1592 NULL_RTX, NULL, small_op0_large_op1,
1593 profile_probability::unlikely ());
1595 /* If both op0 and op1 are sign (!uns) or zero (uns) extended from
1596 hmode to mode, the multiplication will never overflow. We can
1597 do just one hmode x hmode => mode widening multiplication. */
1598 rtx lopart0s = lopart0, lopart1s = lopart1;
1599 if (GET_CODE (lopart0) == SUBREG)
1601 lopart0s = shallow_copy_rtx (lopart0);
1602 SUBREG_PROMOTED_VAR_P (lopart0s) = 1;
1603 SUBREG_PROMOTED_SET (lopart0s, uns ? SRP_UNSIGNED : SRP_SIGNED);
1605 if (GET_CODE (lopart1) == SUBREG)
1607 lopart1s = shallow_copy_rtx (lopart1);
1608 SUBREG_PROMOTED_VAR_P (lopart1s) = 1;
1609 SUBREG_PROMOTED_SET (lopart1s, uns ? SRP_UNSIGNED : SRP_SIGNED);
1611 tree halfstype = build_nonstandard_integer_type (hprec, uns);
1612 ops.op0 = make_tree (halfstype, lopart0s);
1613 ops.op1 = make_tree (halfstype, lopart1s);
1614 ops.code = WIDEN_MULT_EXPR;
1615 ops.type = type;
1616 rtx thisres
1617 = expand_expr_real_2 (&ops, NULL_RTX, mode, EXPAND_NORMAL);
1618 emit_move_insn (res, thisres);
1619 emit_jump (done_label);
1621 emit_label (small_op0_large_op1);
1623 /* If op0 is sign (!uns) or zero (uns) extended from hmode to mode,
1624 but op1 is not, just swap the arguments and handle it as op1
1625 sign/zero extended, op0 not. */
1626 rtx larger = gen_reg_rtx (mode);
1627 rtx hipart = gen_reg_rtx (hmode);
1628 rtx lopart = gen_reg_rtx (hmode);
1629 emit_move_insn (larger, op1);
1630 emit_move_insn (hipart, hipart1);
1631 emit_move_insn (lopart, lopart0);
1632 emit_jump (one_small_one_large);
1634 emit_label (large_op0);
1636 if (!op1_small_p)
1637 do_compare_rtx_and_jump (signbit1, hipart1, NE, true, hmode,
1638 NULL_RTX, NULL, both_ops_large,
1639 profile_probability::unlikely ());
1641 /* If op1 is sign (!uns) or zero (uns) extended from hmode to mode,
1642 but op0 is not, prepare larger, hipart and lopart pseudos and
1643 handle it together with small_op0_large_op1. */
1644 emit_move_insn (larger, op0);
1645 emit_move_insn (hipart, hipart0);
1646 emit_move_insn (lopart, lopart1);
1648 emit_label (one_small_one_large);
1650 /* lopart is the low part of the operand that is sign extended
1651 to mode, larger is the other operand, hipart is the
1652 high part of larger and lopart0 and lopart1 are the low parts
1653 of both operands.
1654 We perform lopart0 * lopart1 and lopart * hipart widening
1655 multiplications. */
1656 tree halfutype = build_nonstandard_integer_type (hprec, 1);
1657 ops.op0 = make_tree (halfutype, lopart0);
1658 ops.op1 = make_tree (halfutype, lopart1);
1659 rtx lo0xlo1
1660 = expand_expr_real_2 (&ops, NULL_RTX, mode, EXPAND_NORMAL);
1662 ops.op0 = make_tree (halfutype, lopart);
1663 ops.op1 = make_tree (halfutype, hipart);
1664 rtx loxhi = gen_reg_rtx (mode);
1665 rtx tem = expand_expr_real_2 (&ops, NULL_RTX, mode, EXPAND_NORMAL);
1666 emit_move_insn (loxhi, tem);
1668 if (!uns)
1670 /* if (hipart < 0) loxhi -= lopart << (bitsize / 2); */
1671 if (larger_sign == 0)
1672 emit_jump (after_hipart_neg);
1673 else if (larger_sign != -1)
1674 do_compare_rtx_and_jump (hipart, const0_rtx, GE, false, hmode,
1675 NULL_RTX, NULL, after_hipart_neg,
1676 profile_probability::even ());
1678 tem = convert_modes (mode, hmode, lopart, 1);
1679 tem = expand_shift (LSHIFT_EXPR, mode, tem, hprec, NULL_RTX, 1);
1680 tem = expand_simple_binop (mode, MINUS, loxhi, tem, NULL_RTX,
1681 1, OPTAB_DIRECT);
1682 emit_move_insn (loxhi, tem);
1684 emit_label (after_hipart_neg);
1686 /* if (lopart < 0) loxhi -= larger; */
1687 if (smaller_sign == 0)
1688 emit_jump (after_lopart_neg);
1689 else if (smaller_sign != -1)
1690 do_compare_rtx_and_jump (lopart, const0_rtx, GE, false, hmode,
1691 NULL_RTX, NULL, after_lopart_neg,
1692 profile_probability::even ());
1694 tem = expand_simple_binop (mode, MINUS, loxhi, larger, NULL_RTX,
1695 1, OPTAB_DIRECT);
1696 emit_move_insn (loxhi, tem);
1698 emit_label (after_lopart_neg);
1701 /* loxhi += (uns) lo0xlo1 >> (bitsize / 2); */
1702 tem = expand_shift (RSHIFT_EXPR, mode, lo0xlo1, hprec, NULL_RTX, 1);
1703 tem = expand_simple_binop (mode, PLUS, loxhi, tem, NULL_RTX,
1704 1, OPTAB_DIRECT);
1705 emit_move_insn (loxhi, tem);
1707 /* if (loxhi >> (bitsize / 2)
1708 == (hmode) loxhi >> (bitsize / 2 - 1)) (if !uns)
1709 if (loxhi >> (bitsize / 2) == 0 (if uns). */
1710 rtx hipartloxhi = expand_shift (RSHIFT_EXPR, mode, loxhi, hprec,
1711 NULL_RTX, 0);
1712 hipartloxhi = convert_modes (hmode, mode, hipartloxhi, 0);
1713 rtx signbitloxhi = const0_rtx;
1714 if (!uns)
1715 signbitloxhi = expand_shift (RSHIFT_EXPR, hmode,
1716 convert_modes (hmode, mode,
1717 loxhi, 0),
1718 hprec - 1, NULL_RTX, 0);
1720 do_compare_rtx_and_jump (signbitloxhi, hipartloxhi, NE, true, hmode,
1721 NULL_RTX, NULL, do_overflow,
1722 profile_probability::very_unlikely ());
1724 /* res = (loxhi << (bitsize / 2)) | (hmode) lo0xlo1; */
1725 rtx loxhishifted = expand_shift (LSHIFT_EXPR, mode, loxhi, hprec,
1726 NULL_RTX, 1);
1727 tem = convert_modes (mode, hmode,
1728 convert_modes (hmode, mode, lo0xlo1, 1), 1);
1730 tem = expand_simple_binop (mode, IOR, loxhishifted, tem, res,
1731 1, OPTAB_DIRECT);
1732 if (tem != res)
1733 emit_move_insn (res, tem);
1734 emit_jump (done_label);
1736 emit_label (both_ops_large);
1738 /* If both operands are large (not sign (!uns) or zero (uns)
1739 extended from hmode), then perform the full multiplication
1740 which will be the result of the operation.
1741 The only cases which don't overflow are for signed multiplication
1742 some cases where both hipart0 and highpart1 are 0 or -1.
1743 For unsigned multiplication when high parts are both non-zero
1744 this overflows always. */
1745 ops.code = MULT_EXPR;
1746 ops.op0 = make_tree (type, op0);
1747 ops.op1 = make_tree (type, op1);
1748 tem = expand_expr_real_2 (&ops, NULL_RTX, mode, EXPAND_NORMAL);
1749 emit_move_insn (res, tem);
1751 if (!uns)
1753 if (!op0_medium_p)
1755 tem = expand_simple_binop (hmode, PLUS, hipart0, const1_rtx,
1756 NULL_RTX, 1, OPTAB_DIRECT);
1757 do_compare_rtx_and_jump (tem, const1_rtx, GTU, true, hmode,
1758 NULL_RTX, NULL, do_error,
1759 profile_probability::very_unlikely ());
1762 if (!op1_medium_p)
1764 tem = expand_simple_binop (hmode, PLUS, hipart1, const1_rtx,
1765 NULL_RTX, 1, OPTAB_DIRECT);
1766 do_compare_rtx_and_jump (tem, const1_rtx, GTU, true, hmode,
1767 NULL_RTX, NULL, do_error,
1768 profile_probability::very_unlikely ());
1771 /* At this point hipart{0,1} are both in [-1, 0]. If they are
1772 the same, overflow happened if res is negative, if they are
1773 different, overflow happened if res is positive. */
1774 if (op0_sign != 1 && op1_sign != 1 && op0_sign != op1_sign)
1775 emit_jump (hipart_different);
1776 else if (op0_sign == 1 || op1_sign == 1)
1777 do_compare_rtx_and_jump (hipart0, hipart1, NE, true, hmode,
1778 NULL_RTX, NULL, hipart_different,
1779 profile_probability::even ());
1781 do_compare_rtx_and_jump (res, const0_rtx, LT, false, mode,
1782 NULL_RTX, NULL, do_error,
1783 profile_probability::very_unlikely ());
1784 emit_jump (done_label);
1786 emit_label (hipart_different);
1788 do_compare_rtx_and_jump (res, const0_rtx, GE, false, mode,
1789 NULL_RTX, NULL, do_error,
1790 profile_probability::very_unlikely ());
1791 emit_jump (done_label);
1794 emit_label (do_overflow);
1796 /* Overflow, do full multiplication and fallthru into do_error. */
1797 ops.op0 = make_tree (type, op0);
1798 ops.op1 = make_tree (type, op1);
1799 tem = expand_expr_real_2 (&ops, NULL_RTX, mode, EXPAND_NORMAL);
1800 emit_move_insn (res, tem);
1802 else
1804 gcc_assert (!is_ubsan);
1805 ops.code = MULT_EXPR;
1806 ops.type = type;
1807 res = expand_expr_real_2 (&ops, NULL_RTX, mode, EXPAND_NORMAL);
1808 emit_jump (done_label);
1812 do_error_label:
1813 emit_label (do_error);
1814 if (is_ubsan)
1816 /* Expand the ubsan builtin call. */
1817 push_temp_slots ();
1818 fn = ubsan_build_overflow_builtin (MULT_EXPR, loc, TREE_TYPE (arg0),
1819 arg0, arg1, datap);
1820 expand_normal (fn);
1821 pop_temp_slots ();
1822 do_pending_stack_adjust ();
1824 else if (lhs)
1825 expand_arith_set_overflow (lhs, target);
1827 /* We're done. */
1828 emit_label (done_label);
1830 /* u1 * u2 -> sr */
1831 if (uns0_p && uns1_p && !unsr_p)
1833 rtx_code_label *all_done_label = gen_label_rtx ();
1834 do_compare_rtx_and_jump (res, const0_rtx, GE, false, mode, NULL_RTX,
1835 NULL, all_done_label, profile_probability::very_likely ());
1836 expand_arith_set_overflow (lhs, target);
1837 emit_label (all_done_label);
1840 /* s1 * u2 -> sr */
1841 if (!uns0_p && uns1_p && !unsr_p && pos_neg1 == 3)
1843 rtx_code_label *all_done_label = gen_label_rtx ();
1844 rtx_code_label *set_noovf = gen_label_rtx ();
1845 do_compare_rtx_and_jump (op1, const0_rtx, GE, false, mode, NULL_RTX,
1846 NULL, all_done_label, profile_probability::very_likely ());
1847 expand_arith_set_overflow (lhs, target);
1848 do_compare_rtx_and_jump (op0, const0_rtx, EQ, true, mode, NULL_RTX,
1849 NULL, set_noovf, profile_probability::very_likely ());
1850 do_compare_rtx_and_jump (op0, constm1_rtx, NE, true, mode, NULL_RTX,
1851 NULL, all_done_label, profile_probability::very_unlikely ());
1852 do_compare_rtx_and_jump (op1, res, NE, true, mode, NULL_RTX, NULL,
1853 all_done_label, profile_probability::very_unlikely ());
1854 emit_label (set_noovf);
1855 write_complex_part (target, const0_rtx, true);
1856 emit_label (all_done_label);
1859 if (lhs)
1861 if (is_ubsan)
1862 expand_ubsan_result_store (target, res);
1863 else
1864 expand_arith_overflow_result_store (lhs, target, mode, res);
1868 /* Expand UBSAN_CHECK_* internal function if it has vector operands. */
1870 static void
1871 expand_vector_ubsan_overflow (location_t loc, enum tree_code code, tree lhs,
1872 tree arg0, tree arg1)
1874 int cnt = TYPE_VECTOR_SUBPARTS (TREE_TYPE (arg0));
1875 rtx_code_label *loop_lab = NULL;
1876 rtx cntvar = NULL_RTX;
1877 tree cntv = NULL_TREE;
1878 tree eltype = TREE_TYPE (TREE_TYPE (arg0));
1879 tree sz = TYPE_SIZE (eltype);
1880 tree data = NULL_TREE;
1881 tree resv = NULL_TREE;
1882 rtx lhsr = NULL_RTX;
1883 rtx resvr = NULL_RTX;
1885 if (lhs)
1887 optab op;
1888 lhsr = expand_expr (lhs, NULL_RTX, VOIDmode, EXPAND_WRITE);
1889 if (!VECTOR_MODE_P (GET_MODE (lhsr))
1890 || (op = optab_for_tree_code (code, TREE_TYPE (arg0),
1891 optab_default)) == unknown_optab
1892 || (optab_handler (op, TYPE_MODE (TREE_TYPE (arg0)))
1893 == CODE_FOR_nothing))
1895 if (MEM_P (lhsr))
1896 resv = make_tree (TREE_TYPE (lhs), lhsr);
1897 else
1899 resvr = assign_temp (TREE_TYPE (lhs), 1, 1);
1900 resv = make_tree (TREE_TYPE (lhs), resvr);
1904 if (cnt > 4)
1906 do_pending_stack_adjust ();
1907 loop_lab = gen_label_rtx ();
1908 cntvar = gen_reg_rtx (TYPE_MODE (sizetype));
1909 cntv = make_tree (sizetype, cntvar);
1910 emit_move_insn (cntvar, const0_rtx);
1911 emit_label (loop_lab);
1913 if (TREE_CODE (arg0) != VECTOR_CST)
1915 rtx arg0r = expand_normal (arg0);
1916 arg0 = make_tree (TREE_TYPE (arg0), arg0r);
1918 if (TREE_CODE (arg1) != VECTOR_CST)
1920 rtx arg1r = expand_normal (arg1);
1921 arg1 = make_tree (TREE_TYPE (arg1), arg1r);
1923 for (int i = 0; i < (cnt > 4 ? 1 : cnt); i++)
1925 tree op0, op1, res = NULL_TREE;
1926 if (cnt > 4)
1928 tree atype = build_array_type_nelts (eltype, cnt);
1929 op0 = uniform_vector_p (arg0);
1930 if (op0 == NULL_TREE)
1932 op0 = fold_build1_loc (loc, VIEW_CONVERT_EXPR, atype, arg0);
1933 op0 = build4_loc (loc, ARRAY_REF, eltype, op0, cntv,
1934 NULL_TREE, NULL_TREE);
1936 op1 = uniform_vector_p (arg1);
1937 if (op1 == NULL_TREE)
1939 op1 = fold_build1_loc (loc, VIEW_CONVERT_EXPR, atype, arg1);
1940 op1 = build4_loc (loc, ARRAY_REF, eltype, op1, cntv,
1941 NULL_TREE, NULL_TREE);
1943 if (resv)
1945 res = fold_build1_loc (loc, VIEW_CONVERT_EXPR, atype, resv);
1946 res = build4_loc (loc, ARRAY_REF, eltype, res, cntv,
1947 NULL_TREE, NULL_TREE);
1950 else
1952 tree bitpos = bitsize_int (tree_to_uhwi (sz) * i);
1953 op0 = fold_build3_loc (loc, BIT_FIELD_REF, eltype, arg0, sz, bitpos);
1954 op1 = fold_build3_loc (loc, BIT_FIELD_REF, eltype, arg1, sz, bitpos);
1955 if (resv)
1956 res = fold_build3_loc (loc, BIT_FIELD_REF, eltype, resv, sz,
1957 bitpos);
1959 switch (code)
1961 case PLUS_EXPR:
1962 expand_addsub_overflow (loc, PLUS_EXPR, res, op0, op1,
1963 false, false, false, true, &data);
1964 break;
1965 case MINUS_EXPR:
1966 if (cnt > 4 ? integer_zerop (arg0) : integer_zerop (op0))
1967 expand_neg_overflow (loc, res, op1, true, &data);
1968 else
1969 expand_addsub_overflow (loc, MINUS_EXPR, res, op0, op1,
1970 false, false, false, true, &data);
1971 break;
1972 case MULT_EXPR:
1973 expand_mul_overflow (loc, res, op0, op1, false, false, false,
1974 true, &data);
1975 break;
1976 default:
1977 gcc_unreachable ();
1980 if (cnt > 4)
1982 struct separate_ops ops;
1983 ops.code = PLUS_EXPR;
1984 ops.type = TREE_TYPE (cntv);
1985 ops.op0 = cntv;
1986 ops.op1 = build_int_cst (TREE_TYPE (cntv), 1);
1987 ops.op2 = NULL_TREE;
1988 ops.location = loc;
1989 rtx ret = expand_expr_real_2 (&ops, cntvar, TYPE_MODE (sizetype),
1990 EXPAND_NORMAL);
1991 if (ret != cntvar)
1992 emit_move_insn (cntvar, ret);
1993 do_compare_rtx_and_jump (cntvar, GEN_INT (cnt), NE, false,
1994 TYPE_MODE (sizetype), NULL_RTX, NULL, loop_lab,
1995 profile_probability::very_likely ());
1997 if (lhs && resv == NULL_TREE)
1999 struct separate_ops ops;
2000 ops.code = code;
2001 ops.type = TREE_TYPE (arg0);
2002 ops.op0 = arg0;
2003 ops.op1 = arg1;
2004 ops.op2 = NULL_TREE;
2005 ops.location = loc;
2006 rtx ret = expand_expr_real_2 (&ops, lhsr, TYPE_MODE (TREE_TYPE (arg0)),
2007 EXPAND_NORMAL);
2008 if (ret != lhsr)
2009 emit_move_insn (lhsr, ret);
2011 else if (resvr)
2012 emit_move_insn (lhsr, resvr);
2015 /* Expand UBSAN_CHECK_ADD call STMT. */
2017 static void
2018 expand_UBSAN_CHECK_ADD (internal_fn, gcall *stmt)
2020 location_t loc = gimple_location (stmt);
2021 tree lhs = gimple_call_lhs (stmt);
2022 tree arg0 = gimple_call_arg (stmt, 0);
2023 tree arg1 = gimple_call_arg (stmt, 1);
2024 if (VECTOR_TYPE_P (TREE_TYPE (arg0)))
2025 expand_vector_ubsan_overflow (loc, PLUS_EXPR, lhs, arg0, arg1);
2026 else
2027 expand_addsub_overflow (loc, PLUS_EXPR, lhs, arg0, arg1,
2028 false, false, false, true, NULL);
2031 /* Expand UBSAN_CHECK_SUB call STMT. */
2033 static void
2034 expand_UBSAN_CHECK_SUB (internal_fn, gcall *stmt)
2036 location_t loc = gimple_location (stmt);
2037 tree lhs = gimple_call_lhs (stmt);
2038 tree arg0 = gimple_call_arg (stmt, 0);
2039 tree arg1 = gimple_call_arg (stmt, 1);
2040 if (VECTOR_TYPE_P (TREE_TYPE (arg0)))
2041 expand_vector_ubsan_overflow (loc, MINUS_EXPR, lhs, arg0, arg1);
2042 else if (integer_zerop (arg0))
2043 expand_neg_overflow (loc, lhs, arg1, true, NULL);
2044 else
2045 expand_addsub_overflow (loc, MINUS_EXPR, lhs, arg0, arg1,
2046 false, false, false, true, NULL);
2049 /* Expand UBSAN_CHECK_MUL call STMT. */
2051 static void
2052 expand_UBSAN_CHECK_MUL (internal_fn, gcall *stmt)
2054 location_t loc = gimple_location (stmt);
2055 tree lhs = gimple_call_lhs (stmt);
2056 tree arg0 = gimple_call_arg (stmt, 0);
2057 tree arg1 = gimple_call_arg (stmt, 1);
2058 if (VECTOR_TYPE_P (TREE_TYPE (arg0)))
2059 expand_vector_ubsan_overflow (loc, MULT_EXPR, lhs, arg0, arg1);
2060 else
2061 expand_mul_overflow (loc, lhs, arg0, arg1, false, false, false, true,
2062 NULL);
2065 /* Helper function for {ADD,SUB,MUL}_OVERFLOW call stmt expansion. */
2067 static void
2068 expand_arith_overflow (enum tree_code code, gimple *stmt)
2070 tree lhs = gimple_call_lhs (stmt);
2071 if (lhs == NULL_TREE)
2072 return;
2073 tree arg0 = gimple_call_arg (stmt, 0);
2074 tree arg1 = gimple_call_arg (stmt, 1);
2075 tree type = TREE_TYPE (TREE_TYPE (lhs));
2076 int uns0_p = TYPE_UNSIGNED (TREE_TYPE (arg0));
2077 int uns1_p = TYPE_UNSIGNED (TREE_TYPE (arg1));
2078 int unsr_p = TYPE_UNSIGNED (type);
2079 int prec0 = TYPE_PRECISION (TREE_TYPE (arg0));
2080 int prec1 = TYPE_PRECISION (TREE_TYPE (arg1));
2081 int precres = TYPE_PRECISION (type);
2082 location_t loc = gimple_location (stmt);
2083 if (!uns0_p && get_range_pos_neg (arg0) == 1)
2084 uns0_p = true;
2085 if (!uns1_p && get_range_pos_neg (arg1) == 1)
2086 uns1_p = true;
2087 int pr = get_min_precision (arg0, uns0_p ? UNSIGNED : SIGNED);
2088 prec0 = MIN (prec0, pr);
2089 pr = get_min_precision (arg1, uns1_p ? UNSIGNED : SIGNED);
2090 prec1 = MIN (prec1, pr);
2092 /* If uns0_p && uns1_p, precop is minimum needed precision
2093 of unsigned type to hold the exact result, otherwise
2094 precop is minimum needed precision of signed type to
2095 hold the exact result. */
2096 int precop;
2097 if (code == MULT_EXPR)
2098 precop = prec0 + prec1 + (uns0_p != uns1_p);
2099 else
2101 if (uns0_p == uns1_p)
2102 precop = MAX (prec0, prec1) + 1;
2103 else if (uns0_p)
2104 precop = MAX (prec0 + 1, prec1) + 1;
2105 else
2106 precop = MAX (prec0, prec1 + 1) + 1;
2108 int orig_precres = precres;
2112 if ((uns0_p && uns1_p)
2113 ? ((precop + !unsr_p) <= precres
2114 /* u1 - u2 -> ur can overflow, no matter what precision
2115 the result has. */
2116 && (code != MINUS_EXPR || !unsr_p))
2117 : (!unsr_p && precop <= precres))
2119 /* The infinity precision result will always fit into result. */
2120 rtx target = expand_expr (lhs, NULL_RTX, VOIDmode, EXPAND_WRITE);
2121 write_complex_part (target, const0_rtx, true);
2122 machine_mode mode = TYPE_MODE (type);
2123 struct separate_ops ops;
2124 ops.code = code;
2125 ops.type = type;
2126 ops.op0 = fold_convert_loc (loc, type, arg0);
2127 ops.op1 = fold_convert_loc (loc, type, arg1);
2128 ops.op2 = NULL_TREE;
2129 ops.location = loc;
2130 rtx tem = expand_expr_real_2 (&ops, NULL_RTX, mode, EXPAND_NORMAL);
2131 expand_arith_overflow_result_store (lhs, target, mode, tem);
2132 return;
2135 /* For operations with low precision, if target doesn't have them, start
2136 with precres widening right away, otherwise do it only if the most
2137 simple cases can't be used. */
2138 const int min_precision = targetm.min_arithmetic_precision ();
2139 if (orig_precres == precres && precres < min_precision)
2141 else if ((uns0_p && uns1_p && unsr_p && prec0 <= precres
2142 && prec1 <= precres)
2143 || ((!uns0_p || !uns1_p) && !unsr_p
2144 && prec0 + uns0_p <= precres
2145 && prec1 + uns1_p <= precres))
2147 arg0 = fold_convert_loc (loc, type, arg0);
2148 arg1 = fold_convert_loc (loc, type, arg1);
2149 switch (code)
2151 case MINUS_EXPR:
2152 if (integer_zerop (arg0) && !unsr_p)
2154 expand_neg_overflow (loc, lhs, arg1, false, NULL);
2155 return;
2157 /* FALLTHRU */
2158 case PLUS_EXPR:
2159 expand_addsub_overflow (loc, code, lhs, arg0, arg1, unsr_p,
2160 unsr_p, unsr_p, false, NULL);
2161 return;
2162 case MULT_EXPR:
2163 expand_mul_overflow (loc, lhs, arg0, arg1, unsr_p,
2164 unsr_p, unsr_p, false, NULL);
2165 return;
2166 default:
2167 gcc_unreachable ();
2171 /* For sub-word operations, retry with a wider type first. */
2172 if (orig_precres == precres && precop <= BITS_PER_WORD)
2174 int p = MAX (min_precision, precop);
2175 machine_mode m = smallest_mode_for_size (p, MODE_INT);
2176 tree optype = build_nonstandard_integer_type (GET_MODE_PRECISION (m),
2177 uns0_p && uns1_p
2178 && unsr_p);
2179 p = TYPE_PRECISION (optype);
2180 if (p > precres)
2182 precres = p;
2183 unsr_p = TYPE_UNSIGNED (optype);
2184 type = optype;
2185 continue;
2189 if (prec0 <= precres && prec1 <= precres)
2191 tree types[2];
2192 if (unsr_p)
2194 types[0] = build_nonstandard_integer_type (precres, 0);
2195 types[1] = type;
2197 else
2199 types[0] = type;
2200 types[1] = build_nonstandard_integer_type (precres, 1);
2202 arg0 = fold_convert_loc (loc, types[uns0_p], arg0);
2203 arg1 = fold_convert_loc (loc, types[uns1_p], arg1);
2204 if (code != MULT_EXPR)
2205 expand_addsub_overflow (loc, code, lhs, arg0, arg1, unsr_p,
2206 uns0_p, uns1_p, false, NULL);
2207 else
2208 expand_mul_overflow (loc, lhs, arg0, arg1, unsr_p,
2209 uns0_p, uns1_p, false, NULL);
2210 return;
2213 /* Retry with a wider type. */
2214 if (orig_precres == precres)
2216 int p = MAX (prec0, prec1);
2217 machine_mode m = smallest_mode_for_size (p, MODE_INT);
2218 tree optype = build_nonstandard_integer_type (GET_MODE_PRECISION (m),
2219 uns0_p && uns1_p
2220 && unsr_p);
2221 p = TYPE_PRECISION (optype);
2222 if (p > precres)
2224 precres = p;
2225 unsr_p = TYPE_UNSIGNED (optype);
2226 type = optype;
2227 continue;
2231 gcc_unreachable ();
2233 while (1);
2236 /* Expand ADD_OVERFLOW STMT. */
2238 static void
2239 expand_ADD_OVERFLOW (internal_fn, gcall *stmt)
2241 expand_arith_overflow (PLUS_EXPR, stmt);
2244 /* Expand SUB_OVERFLOW STMT. */
2246 static void
2247 expand_SUB_OVERFLOW (internal_fn, gcall *stmt)
2249 expand_arith_overflow (MINUS_EXPR, stmt);
2252 /* Expand MUL_OVERFLOW STMT. */
2254 static void
2255 expand_MUL_OVERFLOW (internal_fn, gcall *stmt)
2257 expand_arith_overflow (MULT_EXPR, stmt);
2260 /* This should get folded in tree-vectorizer.c. */
2262 static void
2263 expand_LOOP_VECTORIZED (internal_fn, gcall *)
2265 gcc_unreachable ();
2268 /* This should get folded in tree-vectorizer.c. */
2270 static void
2271 expand_LOOP_DIST_ALIAS (internal_fn, gcall *)
2273 gcc_unreachable ();
2276 /* Expand MASK_LOAD call STMT using optab OPTAB. */
2278 static void
2279 expand_mask_load_optab_fn (internal_fn, gcall *stmt, convert_optab optab)
2281 struct expand_operand ops[3];
2282 tree type, lhs, rhs, maskt, ptr;
2283 rtx mem, target, mask;
2284 unsigned align;
2286 maskt = gimple_call_arg (stmt, 2);
2287 lhs = gimple_call_lhs (stmt);
2288 if (lhs == NULL_TREE)
2289 return;
2290 type = TREE_TYPE (lhs);
2291 ptr = build_int_cst (TREE_TYPE (gimple_call_arg (stmt, 1)), 0);
2292 align = tree_to_shwi (gimple_call_arg (stmt, 1));
2293 if (TYPE_ALIGN (type) != align)
2294 type = build_aligned_type (type, align);
2295 rhs = fold_build2 (MEM_REF, type, gimple_call_arg (stmt, 0), ptr);
2297 mem = expand_expr (rhs, NULL_RTX, VOIDmode, EXPAND_WRITE);
2298 gcc_assert (MEM_P (mem));
2299 mask = expand_normal (maskt);
2300 target = expand_expr (lhs, NULL_RTX, VOIDmode, EXPAND_WRITE);
2301 create_output_operand (&ops[0], target, TYPE_MODE (type));
2302 create_fixed_operand (&ops[1], mem);
2303 create_input_operand (&ops[2], mask, TYPE_MODE (TREE_TYPE (maskt)));
2304 expand_insn (convert_optab_handler (optab, TYPE_MODE (type),
2305 TYPE_MODE (TREE_TYPE (maskt))),
2306 3, ops);
2309 /* Expand MASK_STORE call STMT using optab OPTAB. */
2311 static void
2312 expand_mask_store_optab_fn (internal_fn, gcall *stmt, convert_optab optab)
2314 struct expand_operand ops[3];
2315 tree type, lhs, rhs, maskt, ptr;
2316 rtx mem, reg, mask;
2317 unsigned align;
2319 maskt = gimple_call_arg (stmt, 2);
2320 rhs = gimple_call_arg (stmt, 3);
2321 type = TREE_TYPE (rhs);
2322 ptr = build_int_cst (TREE_TYPE (gimple_call_arg (stmt, 1)), 0);
2323 align = tree_to_shwi (gimple_call_arg (stmt, 1));
2324 if (TYPE_ALIGN (type) != align)
2325 type = build_aligned_type (type, align);
2326 lhs = fold_build2 (MEM_REF, type, gimple_call_arg (stmt, 0), ptr);
2328 mem = expand_expr (lhs, NULL_RTX, VOIDmode, EXPAND_WRITE);
2329 gcc_assert (MEM_P (mem));
2330 mask = expand_normal (maskt);
2331 reg = expand_normal (rhs);
2332 create_fixed_operand (&ops[0], mem);
2333 create_input_operand (&ops[1], reg, TYPE_MODE (type));
2334 create_input_operand (&ops[2], mask, TYPE_MODE (TREE_TYPE (maskt)));
2335 expand_insn (convert_optab_handler (optab, TYPE_MODE (type),
2336 TYPE_MODE (TREE_TYPE (maskt))),
2337 3, ops);
2340 static void
2341 expand_ABNORMAL_DISPATCHER (internal_fn, gcall *)
2345 static void
2346 expand_BUILTIN_EXPECT (internal_fn, gcall *stmt)
2348 /* When guessing was done, the hints should be already stripped away. */
2349 gcc_assert (!flag_guess_branch_prob || optimize == 0 || seen_error ());
2351 rtx target;
2352 tree lhs = gimple_call_lhs (stmt);
2353 if (lhs)
2354 target = expand_expr (lhs, NULL_RTX, VOIDmode, EXPAND_WRITE);
2355 else
2356 target = const0_rtx;
2357 rtx val = expand_expr (gimple_call_arg (stmt, 0), target, VOIDmode, EXPAND_NORMAL);
2358 if (lhs && val != target)
2359 emit_move_insn (target, val);
2362 /* IFN_VA_ARG is supposed to be expanded at pass_stdarg. So this dummy function
2363 should never be called. */
2365 static void
2366 expand_VA_ARG (internal_fn, gcall *)
2368 gcc_unreachable ();
2371 /* Expand the IFN_UNIQUE function according to its first argument. */
2373 static void
2374 expand_UNIQUE (internal_fn, gcall *stmt)
2376 rtx pattern = NULL_RTX;
2377 enum ifn_unique_kind kind
2378 = (enum ifn_unique_kind) TREE_INT_CST_LOW (gimple_call_arg (stmt, 0));
2380 switch (kind)
2382 default:
2383 gcc_unreachable ();
2385 case IFN_UNIQUE_UNSPEC:
2386 if (targetm.have_unique ())
2387 pattern = targetm.gen_unique ();
2388 break;
2390 case IFN_UNIQUE_OACC_FORK:
2391 case IFN_UNIQUE_OACC_JOIN:
2392 if (targetm.have_oacc_fork () && targetm.have_oacc_join ())
2394 tree lhs = gimple_call_lhs (stmt);
2395 rtx target = const0_rtx;
2397 if (lhs)
2398 target = expand_expr (lhs, NULL_RTX, VOIDmode, EXPAND_WRITE);
2400 rtx data_dep = expand_normal (gimple_call_arg (stmt, 1));
2401 rtx axis = expand_normal (gimple_call_arg (stmt, 2));
2403 if (kind == IFN_UNIQUE_OACC_FORK)
2404 pattern = targetm.gen_oacc_fork (target, data_dep, axis);
2405 else
2406 pattern = targetm.gen_oacc_join (target, data_dep, axis);
2408 else
2409 gcc_unreachable ();
2410 break;
2413 if (pattern)
2414 emit_insn (pattern);
2417 /* The size of an OpenACC compute dimension. */
2419 static void
2420 expand_GOACC_DIM_SIZE (internal_fn, gcall *stmt)
2422 tree lhs = gimple_call_lhs (stmt);
2424 if (!lhs)
2425 return;
2427 rtx target = expand_expr (lhs, NULL_RTX, VOIDmode, EXPAND_WRITE);
2428 if (targetm.have_oacc_dim_size ())
2430 rtx dim = expand_expr (gimple_call_arg (stmt, 0), NULL_RTX,
2431 VOIDmode, EXPAND_NORMAL);
2432 emit_insn (targetm.gen_oacc_dim_size (target, dim));
2434 else
2435 emit_move_insn (target, GEN_INT (1));
2438 /* The position of an OpenACC execution engine along one compute axis. */
2440 static void
2441 expand_GOACC_DIM_POS (internal_fn, gcall *stmt)
2443 tree lhs = gimple_call_lhs (stmt);
2445 if (!lhs)
2446 return;
2448 rtx target = expand_expr (lhs, NULL_RTX, VOIDmode, EXPAND_WRITE);
2449 if (targetm.have_oacc_dim_pos ())
2451 rtx dim = expand_expr (gimple_call_arg (stmt, 0), NULL_RTX,
2452 VOIDmode, EXPAND_NORMAL);
2453 emit_insn (targetm.gen_oacc_dim_pos (target, dim));
2455 else
2456 emit_move_insn (target, const0_rtx);
2459 /* This is expanded by oacc_device_lower pass. */
2461 static void
2462 expand_GOACC_LOOP (internal_fn, gcall *)
2464 gcc_unreachable ();
2467 /* This is expanded by oacc_device_lower pass. */
2469 static void
2470 expand_GOACC_REDUCTION (internal_fn, gcall *)
2472 gcc_unreachable ();
2475 /* This is expanded by oacc_device_lower pass. */
2477 static void
2478 expand_GOACC_TILE (internal_fn, gcall *)
2480 gcc_unreachable ();
2483 /* Set errno to EDOM. */
2485 static void
2486 expand_SET_EDOM (internal_fn, gcall *)
2488 #ifdef TARGET_EDOM
2489 #ifdef GEN_ERRNO_RTX
2490 rtx errno_rtx = GEN_ERRNO_RTX;
2491 #else
2492 rtx errno_rtx = gen_rtx_MEM (word_mode, gen_rtx_SYMBOL_REF (Pmode, "errno"));
2493 #endif
2494 emit_move_insn (errno_rtx,
2495 gen_int_mode (TARGET_EDOM, GET_MODE (errno_rtx)));
2496 #else
2497 gcc_unreachable ();
2498 #endif
2501 /* Expand atomic bit test and set. */
2503 static void
2504 expand_ATOMIC_BIT_TEST_AND_SET (internal_fn, gcall *call)
2506 expand_ifn_atomic_bit_test_and (call);
2509 /* Expand atomic bit test and complement. */
2511 static void
2512 expand_ATOMIC_BIT_TEST_AND_COMPLEMENT (internal_fn, gcall *call)
2514 expand_ifn_atomic_bit_test_and (call);
2517 /* Expand atomic bit test and reset. */
2519 static void
2520 expand_ATOMIC_BIT_TEST_AND_RESET (internal_fn, gcall *call)
2522 expand_ifn_atomic_bit_test_and (call);
2525 /* Expand atomic bit test and set. */
2527 static void
2528 expand_ATOMIC_COMPARE_EXCHANGE (internal_fn, gcall *call)
2530 expand_ifn_atomic_compare_exchange (call);
2533 /* Expand LAUNDER to assignment, lhs = arg0. */
2535 static void
2536 expand_LAUNDER (internal_fn, gcall *call)
2538 tree lhs = gimple_call_lhs (call);
2540 if (!lhs)
2541 return;
2543 expand_assignment (lhs, gimple_call_arg (call, 0), false);
2546 /* Expand DIVMOD() using:
2547 a) optab handler for udivmod/sdivmod if it is available.
2548 b) If optab_handler doesn't exist, generate call to
2549 target-specific divmod libfunc. */
2551 static void
2552 expand_DIVMOD (internal_fn, gcall *call_stmt)
2554 tree lhs = gimple_call_lhs (call_stmt);
2555 tree arg0 = gimple_call_arg (call_stmt, 0);
2556 tree arg1 = gimple_call_arg (call_stmt, 1);
2558 gcc_assert (TREE_CODE (TREE_TYPE (lhs)) == COMPLEX_TYPE);
2559 tree type = TREE_TYPE (TREE_TYPE (lhs));
2560 machine_mode mode = TYPE_MODE (type);
2561 bool unsignedp = TYPE_UNSIGNED (type);
2562 optab tab = (unsignedp) ? udivmod_optab : sdivmod_optab;
2564 rtx op0 = expand_normal (arg0);
2565 rtx op1 = expand_normal (arg1);
2566 rtx target = expand_expr (lhs, NULL_RTX, VOIDmode, EXPAND_WRITE);
2568 rtx quotient, remainder, libfunc;
2570 /* Check if optab_handler exists for divmod_optab for given mode. */
2571 if (optab_handler (tab, mode) != CODE_FOR_nothing)
2573 quotient = gen_reg_rtx (mode);
2574 remainder = gen_reg_rtx (mode);
2575 expand_twoval_binop (tab, op0, op1, quotient, remainder, unsignedp);
2578 /* Generate call to divmod libfunc if it exists. */
2579 else if ((libfunc = optab_libfunc (tab, mode)) != NULL_RTX)
2580 targetm.expand_divmod_libfunc (libfunc, mode, op0, op1,
2581 &quotient, &remainder);
2583 else
2584 gcc_unreachable ();
2586 /* Wrap the return value (quotient, remainder) within COMPLEX_EXPR. */
2587 expand_expr (build2 (COMPLEX_EXPR, TREE_TYPE (lhs),
2588 make_tree (TREE_TYPE (arg0), quotient),
2589 make_tree (TREE_TYPE (arg1), remainder)),
2590 target, VOIDmode, EXPAND_NORMAL);
2593 /* Expand a call to FN using the operands in STMT. FN has a single
2594 output operand and NARGS input operands. */
2596 static void
2597 expand_direct_optab_fn (internal_fn fn, gcall *stmt, direct_optab optab,
2598 unsigned int nargs)
2600 expand_operand *ops = XALLOCAVEC (expand_operand, nargs + 1);
2602 tree_pair types = direct_internal_fn_types (fn, stmt);
2603 insn_code icode = direct_optab_handler (optab, TYPE_MODE (types.first));
2605 tree lhs = gimple_call_lhs (stmt);
2606 tree lhs_type = TREE_TYPE (lhs);
2607 rtx lhs_rtx = expand_expr (lhs, NULL_RTX, VOIDmode, EXPAND_WRITE);
2608 create_output_operand (&ops[0], lhs_rtx, insn_data[icode].operand[0].mode);
2610 for (unsigned int i = 0; i < nargs; ++i)
2612 tree rhs = gimple_call_arg (stmt, i);
2613 tree rhs_type = TREE_TYPE (rhs);
2614 rtx rhs_rtx = expand_normal (rhs);
2615 if (INTEGRAL_TYPE_P (rhs_type))
2616 create_convert_operand_from (&ops[i + 1], rhs_rtx,
2617 TYPE_MODE (rhs_type),
2618 TYPE_UNSIGNED (rhs_type));
2619 else
2620 create_input_operand (&ops[i + 1], rhs_rtx, TYPE_MODE (rhs_type));
2623 expand_insn (icode, nargs + 1, ops);
2624 if (!rtx_equal_p (lhs_rtx, ops[0].value))
2626 /* If the return value has an integral type, convert the instruction
2627 result to that type. This is useful for things that return an
2628 int regardless of the size of the input. If the instruction result
2629 is smaller than required, assume that it is signed.
2631 If the return value has a nonintegral type, its mode must match
2632 the instruction result. */
2633 if (GET_CODE (lhs_rtx) == SUBREG && SUBREG_PROMOTED_VAR_P (lhs_rtx))
2635 /* If this is a scalar in a register that is stored in a wider
2636 mode than the declared mode, compute the result into its
2637 declared mode and then convert to the wider mode. */
2638 gcc_checking_assert (INTEGRAL_TYPE_P (lhs_type));
2639 rtx tmp = convert_to_mode (GET_MODE (lhs_rtx), ops[0].value, 0);
2640 convert_move (SUBREG_REG (lhs_rtx), tmp,
2641 SUBREG_PROMOTED_SIGN (lhs_rtx));
2643 else if (GET_MODE (lhs_rtx) == GET_MODE (ops[0].value))
2644 emit_move_insn (lhs_rtx, ops[0].value);
2645 else
2647 gcc_checking_assert (INTEGRAL_TYPE_P (lhs_type));
2648 convert_move (lhs_rtx, ops[0].value, 0);
2653 /* Expanders for optabs that can use expand_direct_optab_fn. */
2655 #define expand_unary_optab_fn(FN, STMT, OPTAB) \
2656 expand_direct_optab_fn (FN, STMT, OPTAB, 1)
2658 #define expand_binary_optab_fn(FN, STMT, OPTAB) \
2659 expand_direct_optab_fn (FN, STMT, OPTAB, 2)
2661 /* RETURN_TYPE and ARGS are a return type and argument list that are
2662 in principle compatible with FN (which satisfies direct_internal_fn_p).
2663 Return the types that should be used to determine whether the
2664 target supports FN. */
2666 tree_pair
2667 direct_internal_fn_types (internal_fn fn, tree return_type, tree *args)
2669 const direct_internal_fn_info &info = direct_internal_fn (fn);
2670 tree type0 = (info.type0 < 0 ? return_type : TREE_TYPE (args[info.type0]));
2671 tree type1 = (info.type1 < 0 ? return_type : TREE_TYPE (args[info.type1]));
2672 return tree_pair (type0, type1);
2675 /* CALL is a call whose return type and arguments are in principle
2676 compatible with FN (which satisfies direct_internal_fn_p). Return the
2677 types that should be used to determine whether the target supports FN. */
2679 tree_pair
2680 direct_internal_fn_types (internal_fn fn, gcall *call)
2682 const direct_internal_fn_info &info = direct_internal_fn (fn);
2683 tree op0 = (info.type0 < 0
2684 ? gimple_call_lhs (call)
2685 : gimple_call_arg (call, info.type0));
2686 tree op1 = (info.type1 < 0
2687 ? gimple_call_lhs (call)
2688 : gimple_call_arg (call, info.type1));
2689 return tree_pair (TREE_TYPE (op0), TREE_TYPE (op1));
2692 /* Return true if OPTAB is supported for TYPES (whose modes should be
2693 the same) when the optimization type is OPT_TYPE. Used for simple
2694 direct optabs. */
2696 static bool
2697 direct_optab_supported_p (direct_optab optab, tree_pair types,
2698 optimization_type opt_type)
2700 machine_mode mode = TYPE_MODE (types.first);
2701 gcc_checking_assert (mode == TYPE_MODE (types.second));
2702 return direct_optab_handler (optab, mode, opt_type) != CODE_FOR_nothing;
2705 /* Return true if load/store lanes optab OPTAB is supported for
2706 array type TYPES.first when the optimization type is OPT_TYPE. */
2708 static bool
2709 multi_vector_optab_supported_p (convert_optab optab, tree_pair types,
2710 optimization_type opt_type)
2712 gcc_assert (TREE_CODE (types.first) == ARRAY_TYPE);
2713 machine_mode imode = TYPE_MODE (types.first);
2714 machine_mode vmode = TYPE_MODE (TREE_TYPE (types.first));
2715 return (convert_optab_handler (optab, imode, vmode, opt_type)
2716 != CODE_FOR_nothing);
2719 #define direct_unary_optab_supported_p direct_optab_supported_p
2720 #define direct_binary_optab_supported_p direct_optab_supported_p
2721 #define direct_mask_load_optab_supported_p direct_optab_supported_p
2722 #define direct_load_lanes_optab_supported_p multi_vector_optab_supported_p
2723 #define direct_mask_store_optab_supported_p direct_optab_supported_p
2724 #define direct_store_lanes_optab_supported_p multi_vector_optab_supported_p
2726 /* Return true if FN is supported for the types in TYPES when the
2727 optimization type is OPT_TYPE. The types are those associated with
2728 the "type0" and "type1" fields of FN's direct_internal_fn_info
2729 structure. */
2731 bool
2732 direct_internal_fn_supported_p (internal_fn fn, tree_pair types,
2733 optimization_type opt_type)
2735 switch (fn)
2737 #define DEF_INTERNAL_FN(CODE, FLAGS, FNSPEC) \
2738 case IFN_##CODE: break;
2739 #define DEF_INTERNAL_OPTAB_FN(CODE, FLAGS, OPTAB, TYPE) \
2740 case IFN_##CODE: \
2741 return direct_##TYPE##_optab_supported_p (OPTAB##_optab, types, \
2742 opt_type);
2743 #include "internal-fn.def"
2745 case IFN_LAST:
2746 break;
2748 gcc_unreachable ();
2751 /* Return true if FN is supported for type TYPE when the optimization
2752 type is OPT_TYPE. The caller knows that the "type0" and "type1"
2753 fields of FN's direct_internal_fn_info structure are the same. */
2755 bool
2756 direct_internal_fn_supported_p (internal_fn fn, tree type,
2757 optimization_type opt_type)
2759 const direct_internal_fn_info &info = direct_internal_fn (fn);
2760 gcc_checking_assert (info.type0 == info.type1);
2761 return direct_internal_fn_supported_p (fn, tree_pair (type, type), opt_type);
2764 /* Return true if IFN_SET_EDOM is supported. */
2766 bool
2767 set_edom_supported_p (void)
2769 #ifdef TARGET_EDOM
2770 return true;
2771 #else
2772 return false;
2773 #endif
2776 #define DEF_INTERNAL_OPTAB_FN(CODE, FLAGS, OPTAB, TYPE) \
2777 static void \
2778 expand_##CODE (internal_fn fn, gcall *stmt) \
2780 expand_##TYPE##_optab_fn (fn, stmt, OPTAB##_optab); \
2782 #include "internal-fn.def"
2784 /* Routines to expand each internal function, indexed by function number.
2785 Each routine has the prototype:
2787 expand_<NAME> (gcall *stmt)
2789 where STMT is the statement that performs the call. */
2790 static void (*const internal_fn_expanders[]) (internal_fn, gcall *) = {
2791 #define DEF_INTERNAL_FN(CODE, FLAGS, FNSPEC) expand_##CODE,
2792 #include "internal-fn.def"
2796 /* Expand STMT as though it were a call to internal function FN. */
2798 void
2799 expand_internal_call (internal_fn fn, gcall *stmt)
2801 internal_fn_expanders[fn] (fn, stmt);
2804 /* Expand STMT, which is a call to internal function FN. */
2806 void
2807 expand_internal_call (gcall *stmt)
2809 expand_internal_call (gimple_call_internal_fn (stmt), stmt);
2812 void
2813 expand_PHI (internal_fn, gcall *)
2815 gcc_unreachable ();