Avoid no-stack-protector-attr fails on hppa*-*-*.
[official-gcc.git] / gcc / internal-fn.c
blobdd7173126fbb99be398cb0c760ab5ebc1a576335
1 /* Internal functions.
2 Copyright (C) 2011-2021 Free Software Foundation, Inc.
4 This file is part of GCC.
6 GCC is free software; you can redistribute it and/or modify it under
7 the terms of the GNU General Public License as published by the Free
8 Software Foundation; either version 3, or (at your option) any later
9 version.
11 GCC is distributed in the hope that it will be useful, but WITHOUT ANY
12 WARRANTY; without even the implied warranty of MERCHANTABILITY or
13 FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License
14 for more details.
16 You should have received a copy of the GNU General Public License
17 along with GCC; see the file COPYING3. If not see
18 <http://www.gnu.org/licenses/>. */
20 #include "config.h"
21 #include "system.h"
22 #include "coretypes.h"
23 #include "backend.h"
24 #include "target.h"
25 #include "rtl.h"
26 #include "tree.h"
27 #include "gimple.h"
28 #include "predict.h"
29 #include "stringpool.h"
30 #include "tree-vrp.h"
31 #include "tree-ssanames.h"
32 #include "expmed.h"
33 #include "memmodel.h"
34 #include "optabs.h"
35 #include "emit-rtl.h"
36 #include "diagnostic-core.h"
37 #include "fold-const.h"
38 #include "internal-fn.h"
39 #include "stor-layout.h"
40 #include "dojump.h"
41 #include "expr.h"
42 #include "stringpool.h"
43 #include "attribs.h"
44 #include "asan.h"
45 #include "ubsan.h"
46 #include "recog.h"
47 #include "builtins.h"
48 #include "optabs-tree.h"
49 #include "gimple-ssa.h"
50 #include "tree-phinodes.h"
51 #include "ssa-iterators.h"
52 #include "explow.h"
53 #include "rtl-iter.h"
55 /* The names of each internal function, indexed by function number. */
56 const char *const internal_fn_name_array[] = {
57 #define DEF_INTERNAL_FN(CODE, FLAGS, FNSPEC) #CODE,
58 #include "internal-fn.def"
59 "<invalid-fn>"
62 /* The ECF_* flags of each internal function, indexed by function number. */
63 const int internal_fn_flags_array[] = {
64 #define DEF_INTERNAL_FN(CODE, FLAGS, FNSPEC) FLAGS,
65 #include "internal-fn.def"
69 /* Return the internal function called NAME, or IFN_LAST if there's
70 no such function. */
72 internal_fn
73 lookup_internal_fn (const char *name)
75 typedef hash_map<nofree_string_hash, internal_fn> name_to_fn_map_type;
76 static name_to_fn_map_type *name_to_fn_map;
78 if (!name_to_fn_map)
80 name_to_fn_map = new name_to_fn_map_type (IFN_LAST);
81 for (unsigned int i = 0; i < IFN_LAST; ++i)
82 name_to_fn_map->put (internal_fn_name (internal_fn (i)),
83 internal_fn (i));
85 internal_fn *entry = name_to_fn_map->get (name);
86 return entry ? *entry : IFN_LAST;
89 /* Fnspec of each internal function, indexed by function number. */
90 const_tree internal_fn_fnspec_array[IFN_LAST + 1];
92 void
93 init_internal_fns ()
95 #define DEF_INTERNAL_FN(CODE, FLAGS, FNSPEC) \
96 if (FNSPEC) internal_fn_fnspec_array[IFN_##CODE] = \
97 build_string ((int) sizeof (FNSPEC) - 1, FNSPEC ? FNSPEC : "");
98 #include "internal-fn.def"
99 internal_fn_fnspec_array[IFN_LAST] = 0;
102 /* Create static initializers for the information returned by
103 direct_internal_fn. */
104 #define not_direct { -2, -2, false }
105 #define mask_load_direct { -1, 2, false }
106 #define load_lanes_direct { -1, -1, false }
107 #define mask_load_lanes_direct { -1, -1, false }
108 #define gather_load_direct { 3, 1, false }
109 #define len_load_direct { -1, -1, false }
110 #define mask_store_direct { 3, 2, false }
111 #define store_lanes_direct { 0, 0, false }
112 #define mask_store_lanes_direct { 0, 0, false }
113 #define vec_cond_mask_direct { 1, 0, false }
114 #define vec_cond_direct { 2, 0, false }
115 #define scatter_store_direct { 3, 1, false }
116 #define len_store_direct { 3, 3, false }
117 #define vec_set_direct { 3, 3, false }
118 #define unary_direct { 0, 0, true }
119 #define binary_direct { 0, 0, true }
120 #define ternary_direct { 0, 0, true }
121 #define cond_unary_direct { 1, 1, true }
122 #define cond_binary_direct { 1, 1, true }
123 #define cond_ternary_direct { 1, 1, true }
124 #define while_direct { 0, 2, false }
125 #define fold_extract_direct { 2, 2, false }
126 #define fold_left_direct { 1, 1, false }
127 #define mask_fold_left_direct { 1, 1, false }
128 #define check_ptrs_direct { 0, 0, false }
130 const direct_internal_fn_info direct_internal_fn_array[IFN_LAST + 1] = {
131 #define DEF_INTERNAL_FN(CODE, FLAGS, FNSPEC) not_direct,
132 #define DEF_INTERNAL_OPTAB_FN(CODE, FLAGS, OPTAB, TYPE) TYPE##_direct,
133 #define DEF_INTERNAL_SIGNED_OPTAB_FN(CODE, FLAGS, SELECTOR, SIGNED_OPTAB, \
134 UNSIGNED_OPTAB, TYPE) TYPE##_direct,
135 #include "internal-fn.def"
136 not_direct
139 /* ARRAY_TYPE is an array of vector modes. Return the associated insn
140 for load-lanes-style optab OPTAB, or CODE_FOR_nothing if none. */
142 static enum insn_code
143 get_multi_vector_move (tree array_type, convert_optab optab)
145 machine_mode imode;
146 machine_mode vmode;
148 gcc_assert (TREE_CODE (array_type) == ARRAY_TYPE);
149 imode = TYPE_MODE (array_type);
150 vmode = TYPE_MODE (TREE_TYPE (array_type));
152 return convert_optab_handler (optab, imode, vmode);
155 /* Expand LOAD_LANES call STMT using optab OPTAB. */
157 static void
158 expand_load_lanes_optab_fn (internal_fn, gcall *stmt, convert_optab optab)
160 class expand_operand ops[2];
161 tree type, lhs, rhs;
162 rtx target, mem;
164 lhs = gimple_call_lhs (stmt);
165 rhs = gimple_call_arg (stmt, 0);
166 type = TREE_TYPE (lhs);
168 target = expand_expr (lhs, NULL_RTX, VOIDmode, EXPAND_WRITE);
169 mem = expand_normal (rhs);
171 gcc_assert (MEM_P (mem));
172 PUT_MODE (mem, TYPE_MODE (type));
174 create_output_operand (&ops[0], target, TYPE_MODE (type));
175 create_fixed_operand (&ops[1], mem);
176 expand_insn (get_multi_vector_move (type, optab), 2, ops);
177 if (!rtx_equal_p (target, ops[0].value))
178 emit_move_insn (target, ops[0].value);
181 /* Expand STORE_LANES call STMT using optab OPTAB. */
183 static void
184 expand_store_lanes_optab_fn (internal_fn, gcall *stmt, convert_optab optab)
186 class expand_operand ops[2];
187 tree type, lhs, rhs;
188 rtx target, reg;
190 lhs = gimple_call_lhs (stmt);
191 rhs = gimple_call_arg (stmt, 0);
192 type = TREE_TYPE (rhs);
194 target = expand_expr (lhs, NULL_RTX, VOIDmode, EXPAND_WRITE);
195 reg = expand_normal (rhs);
197 gcc_assert (MEM_P (target));
198 PUT_MODE (target, TYPE_MODE (type));
200 create_fixed_operand (&ops[0], target);
201 create_input_operand (&ops[1], reg, TYPE_MODE (type));
202 expand_insn (get_multi_vector_move (type, optab), 2, ops);
205 static void
206 expand_ANNOTATE (internal_fn, gcall *)
208 gcc_unreachable ();
211 /* This should get expanded in omp_device_lower pass. */
213 static void
214 expand_GOMP_USE_SIMT (internal_fn, gcall *)
216 gcc_unreachable ();
219 /* This should get expanded in omp_device_lower pass. */
221 static void
222 expand_GOMP_SIMT_ENTER (internal_fn, gcall *)
224 gcc_unreachable ();
227 /* Allocate per-lane storage and begin non-uniform execution region. */
229 static void
230 expand_GOMP_SIMT_ENTER_ALLOC (internal_fn, gcall *stmt)
232 rtx target;
233 tree lhs = gimple_call_lhs (stmt);
234 if (lhs)
235 target = expand_expr (lhs, NULL_RTX, VOIDmode, EXPAND_WRITE);
236 else
237 target = gen_reg_rtx (Pmode);
238 rtx size = expand_normal (gimple_call_arg (stmt, 0));
239 rtx align = expand_normal (gimple_call_arg (stmt, 1));
240 class expand_operand ops[3];
241 create_output_operand (&ops[0], target, Pmode);
242 create_input_operand (&ops[1], size, Pmode);
243 create_input_operand (&ops[2], align, Pmode);
244 gcc_assert (targetm.have_omp_simt_enter ());
245 expand_insn (targetm.code_for_omp_simt_enter, 3, ops);
248 /* Deallocate per-lane storage and leave non-uniform execution region. */
250 static void
251 expand_GOMP_SIMT_EXIT (internal_fn, gcall *stmt)
253 gcc_checking_assert (!gimple_call_lhs (stmt));
254 rtx arg = expand_normal (gimple_call_arg (stmt, 0));
255 class expand_operand ops[1];
256 create_input_operand (&ops[0], arg, Pmode);
257 gcc_assert (targetm.have_omp_simt_exit ());
258 expand_insn (targetm.code_for_omp_simt_exit, 1, ops);
261 /* Lane index on SIMT targets: thread index in the warp on NVPTX. On targets
262 without SIMT execution this should be expanded in omp_device_lower pass. */
264 static void
265 expand_GOMP_SIMT_LANE (internal_fn, gcall *stmt)
267 tree lhs = gimple_call_lhs (stmt);
268 if (!lhs)
269 return;
271 rtx target = expand_expr (lhs, NULL_RTX, VOIDmode, EXPAND_WRITE);
272 gcc_assert (targetm.have_omp_simt_lane ());
273 emit_insn (targetm.gen_omp_simt_lane (target));
276 /* This should get expanded in omp_device_lower pass. */
278 static void
279 expand_GOMP_SIMT_VF (internal_fn, gcall *)
281 gcc_unreachable ();
284 /* Lane index of the first SIMT lane that supplies a non-zero argument.
285 This is a SIMT counterpart to GOMP_SIMD_LAST_LANE, used to represent the
286 lane that executed the last iteration for handling OpenMP lastprivate. */
288 static void
289 expand_GOMP_SIMT_LAST_LANE (internal_fn, gcall *stmt)
291 tree lhs = gimple_call_lhs (stmt);
292 if (!lhs)
293 return;
295 rtx target = expand_expr (lhs, NULL_RTX, VOIDmode, EXPAND_WRITE);
296 rtx cond = expand_normal (gimple_call_arg (stmt, 0));
297 machine_mode mode = TYPE_MODE (TREE_TYPE (lhs));
298 class expand_operand ops[2];
299 create_output_operand (&ops[0], target, mode);
300 create_input_operand (&ops[1], cond, mode);
301 gcc_assert (targetm.have_omp_simt_last_lane ());
302 expand_insn (targetm.code_for_omp_simt_last_lane, 2, ops);
305 /* Non-transparent predicate used in SIMT lowering of OpenMP "ordered". */
307 static void
308 expand_GOMP_SIMT_ORDERED_PRED (internal_fn, gcall *stmt)
310 tree lhs = gimple_call_lhs (stmt);
311 if (!lhs)
312 return;
314 rtx target = expand_expr (lhs, NULL_RTX, VOIDmode, EXPAND_WRITE);
315 rtx ctr = expand_normal (gimple_call_arg (stmt, 0));
316 machine_mode mode = TYPE_MODE (TREE_TYPE (lhs));
317 class expand_operand ops[2];
318 create_output_operand (&ops[0], target, mode);
319 create_input_operand (&ops[1], ctr, mode);
320 gcc_assert (targetm.have_omp_simt_ordered ());
321 expand_insn (targetm.code_for_omp_simt_ordered, 2, ops);
324 /* "Or" boolean reduction across SIMT lanes: return non-zero in all lanes if
325 any lane supplies a non-zero argument. */
327 static void
328 expand_GOMP_SIMT_VOTE_ANY (internal_fn, gcall *stmt)
330 tree lhs = gimple_call_lhs (stmt);
331 if (!lhs)
332 return;
334 rtx target = expand_expr (lhs, NULL_RTX, VOIDmode, EXPAND_WRITE);
335 rtx cond = expand_normal (gimple_call_arg (stmt, 0));
336 machine_mode mode = TYPE_MODE (TREE_TYPE (lhs));
337 class expand_operand ops[2];
338 create_output_operand (&ops[0], target, mode);
339 create_input_operand (&ops[1], cond, mode);
340 gcc_assert (targetm.have_omp_simt_vote_any ());
341 expand_insn (targetm.code_for_omp_simt_vote_any, 2, ops);
344 /* Exchange between SIMT lanes with a "butterfly" pattern: source lane index
345 is destination lane index XOR given offset. */
347 static void
348 expand_GOMP_SIMT_XCHG_BFLY (internal_fn, gcall *stmt)
350 tree lhs = gimple_call_lhs (stmt);
351 if (!lhs)
352 return;
354 rtx target = expand_expr (lhs, NULL_RTX, VOIDmode, EXPAND_WRITE);
355 rtx src = expand_normal (gimple_call_arg (stmt, 0));
356 rtx idx = expand_normal (gimple_call_arg (stmt, 1));
357 machine_mode mode = TYPE_MODE (TREE_TYPE (lhs));
358 class expand_operand ops[3];
359 create_output_operand (&ops[0], target, mode);
360 create_input_operand (&ops[1], src, mode);
361 create_input_operand (&ops[2], idx, SImode);
362 gcc_assert (targetm.have_omp_simt_xchg_bfly ());
363 expand_insn (targetm.code_for_omp_simt_xchg_bfly, 3, ops);
366 /* Exchange between SIMT lanes according to given source lane index. */
368 static void
369 expand_GOMP_SIMT_XCHG_IDX (internal_fn, gcall *stmt)
371 tree lhs = gimple_call_lhs (stmt);
372 if (!lhs)
373 return;
375 rtx target = expand_expr (lhs, NULL_RTX, VOIDmode, EXPAND_WRITE);
376 rtx src = expand_normal (gimple_call_arg (stmt, 0));
377 rtx idx = expand_normal (gimple_call_arg (stmt, 1));
378 machine_mode mode = TYPE_MODE (TREE_TYPE (lhs));
379 class expand_operand ops[3];
380 create_output_operand (&ops[0], target, mode);
381 create_input_operand (&ops[1], src, mode);
382 create_input_operand (&ops[2], idx, SImode);
383 gcc_assert (targetm.have_omp_simt_xchg_idx ());
384 expand_insn (targetm.code_for_omp_simt_xchg_idx, 3, ops);
387 /* This should get expanded in adjust_simduid_builtins. */
389 static void
390 expand_GOMP_SIMD_LANE (internal_fn, gcall *)
392 gcc_unreachable ();
395 /* This should get expanded in adjust_simduid_builtins. */
397 static void
398 expand_GOMP_SIMD_VF (internal_fn, gcall *)
400 gcc_unreachable ();
403 /* This should get expanded in adjust_simduid_builtins. */
405 static void
406 expand_GOMP_SIMD_LAST_LANE (internal_fn, gcall *)
408 gcc_unreachable ();
411 /* This should get expanded in adjust_simduid_builtins. */
413 static void
414 expand_GOMP_SIMD_ORDERED_START (internal_fn, gcall *)
416 gcc_unreachable ();
419 /* This should get expanded in adjust_simduid_builtins. */
421 static void
422 expand_GOMP_SIMD_ORDERED_END (internal_fn, gcall *)
424 gcc_unreachable ();
427 /* This should get expanded in the sanopt pass. */
429 static void
430 expand_UBSAN_NULL (internal_fn, gcall *)
432 gcc_unreachable ();
435 /* This should get expanded in the sanopt pass. */
437 static void
438 expand_UBSAN_BOUNDS (internal_fn, gcall *)
440 gcc_unreachable ();
443 /* This should get expanded in the sanopt pass. */
445 static void
446 expand_UBSAN_VPTR (internal_fn, gcall *)
448 gcc_unreachable ();
451 /* This should get expanded in the sanopt pass. */
453 static void
454 expand_UBSAN_PTR (internal_fn, gcall *)
456 gcc_unreachable ();
459 /* This should get expanded in the sanopt pass. */
461 static void
462 expand_UBSAN_OBJECT_SIZE (internal_fn, gcall *)
464 gcc_unreachable ();
467 /* This should get expanded in the sanopt pass. */
469 static void
470 expand_HWASAN_CHECK (internal_fn, gcall *)
472 gcc_unreachable ();
475 /* For hwasan stack tagging:
476 Clear tags on the dynamically allocated space.
477 For use after an object dynamically allocated on the stack goes out of
478 scope. */
479 static void
480 expand_HWASAN_ALLOCA_UNPOISON (internal_fn, gcall *gc)
482 gcc_assert (Pmode == ptr_mode);
483 tree restored_position = gimple_call_arg (gc, 0);
484 rtx restored_rtx = expand_expr (restored_position, NULL_RTX, VOIDmode,
485 EXPAND_NORMAL);
486 rtx func = init_one_libfunc ("__hwasan_tag_memory");
487 rtx off = expand_simple_binop (Pmode, MINUS, restored_rtx,
488 stack_pointer_rtx, NULL_RTX, 0,
489 OPTAB_WIDEN);
490 emit_library_call_value (func, NULL_RTX, LCT_NORMAL, VOIDmode,
491 virtual_stack_dynamic_rtx, Pmode,
492 HWASAN_STACK_BACKGROUND, QImode,
493 off, Pmode);
496 /* For hwasan stack tagging:
497 Return a tag to be used for a dynamic allocation. */
498 static void
499 expand_HWASAN_CHOOSE_TAG (internal_fn, gcall *gc)
501 tree tag = gimple_call_lhs (gc);
502 rtx target = expand_expr (tag, NULL_RTX, VOIDmode, EXPAND_NORMAL);
503 machine_mode mode = GET_MODE (target);
504 gcc_assert (mode == QImode);
506 rtx base_tag = targetm.memtag.extract_tag (hwasan_frame_base (), NULL_RTX);
507 gcc_assert (base_tag);
508 rtx tag_offset = gen_int_mode (hwasan_current_frame_tag (), QImode);
509 rtx chosen_tag = expand_simple_binop (QImode, PLUS, base_tag, tag_offset,
510 target, /* unsignedp = */1,
511 OPTAB_WIDEN);
512 chosen_tag = hwasan_truncate_to_tag_size (chosen_tag, target);
514 /* Really need to put the tag into the `target` RTX. */
515 if (chosen_tag != target)
517 rtx temp = chosen_tag;
518 gcc_assert (GET_MODE (chosen_tag) == mode);
519 emit_move_insn (target, temp);
522 hwasan_increment_frame_tag ();
525 /* For hwasan stack tagging:
526 Tag a region of space in the shadow stack according to the base pointer of
527 an object on the stack. N.b. the length provided in the internal call is
528 required to be aligned to HWASAN_TAG_GRANULE_SIZE. */
529 static void
530 expand_HWASAN_MARK (internal_fn, gcall *gc)
532 gcc_assert (ptr_mode == Pmode);
533 HOST_WIDE_INT flag = tree_to_shwi (gimple_call_arg (gc, 0));
534 bool is_poison = ((asan_mark_flags)flag) == ASAN_MARK_POISON;
536 tree base = gimple_call_arg (gc, 1);
537 gcc_checking_assert (TREE_CODE (base) == ADDR_EXPR);
538 rtx base_rtx = expand_normal (base);
540 rtx tag = is_poison ? HWASAN_STACK_BACKGROUND
541 : targetm.memtag.extract_tag (base_rtx, NULL_RTX);
542 rtx address = targetm.memtag.untagged_pointer (base_rtx, NULL_RTX);
544 tree len = gimple_call_arg (gc, 2);
545 rtx r_len = expand_normal (len);
547 rtx func = init_one_libfunc ("__hwasan_tag_memory");
548 emit_library_call (func, LCT_NORMAL, VOIDmode, address, Pmode,
549 tag, QImode, r_len, Pmode);
552 /* For hwasan stack tagging:
553 Store a tag into a pointer. */
554 static void
555 expand_HWASAN_SET_TAG (internal_fn, gcall *gc)
557 gcc_assert (ptr_mode == Pmode);
558 tree g_target = gimple_call_lhs (gc);
559 tree g_ptr = gimple_call_arg (gc, 0);
560 tree g_tag = gimple_call_arg (gc, 1);
562 rtx ptr = expand_normal (g_ptr);
563 rtx tag = expand_expr (g_tag, NULL_RTX, QImode, EXPAND_NORMAL);
564 rtx target = expand_normal (g_target);
566 rtx untagged = targetm.memtag.untagged_pointer (ptr, target);
567 rtx tagged_value = targetm.memtag.set_tag (untagged, tag, target);
568 if (tagged_value != target)
569 emit_move_insn (target, tagged_value);
572 /* This should get expanded in the sanopt pass. */
574 static void
575 expand_ASAN_CHECK (internal_fn, gcall *)
577 gcc_unreachable ();
580 /* This should get expanded in the sanopt pass. */
582 static void
583 expand_ASAN_MARK (internal_fn, gcall *)
585 gcc_unreachable ();
588 /* This should get expanded in the sanopt pass. */
590 static void
591 expand_ASAN_POISON (internal_fn, gcall *)
593 gcc_unreachable ();
596 /* This should get expanded in the sanopt pass. */
598 static void
599 expand_ASAN_POISON_USE (internal_fn, gcall *)
601 gcc_unreachable ();
604 /* This should get expanded in the tsan pass. */
606 static void
607 expand_TSAN_FUNC_EXIT (internal_fn, gcall *)
609 gcc_unreachable ();
612 /* This should get expanded in the lower pass. */
614 static void
615 expand_FALLTHROUGH (internal_fn, gcall *call)
617 error_at (gimple_location (call),
618 "invalid use of attribute %<fallthrough%>");
621 /* Return minimum precision needed to represent all values
622 of ARG in SIGNed integral type. */
624 static int
625 get_min_precision (tree arg, signop sign)
627 int prec = TYPE_PRECISION (TREE_TYPE (arg));
628 int cnt = 0;
629 signop orig_sign = sign;
630 if (TREE_CODE (arg) == INTEGER_CST)
632 int p;
633 if (TYPE_SIGN (TREE_TYPE (arg)) != sign)
635 widest_int w = wi::to_widest (arg);
636 w = wi::ext (w, prec, sign);
637 p = wi::min_precision (w, sign);
639 else
640 p = wi::min_precision (wi::to_wide (arg), sign);
641 return MIN (p, prec);
643 while (CONVERT_EXPR_P (arg)
644 && INTEGRAL_TYPE_P (TREE_TYPE (TREE_OPERAND (arg, 0)))
645 && TYPE_PRECISION (TREE_TYPE (TREE_OPERAND (arg, 0))) <= prec)
647 arg = TREE_OPERAND (arg, 0);
648 if (TYPE_PRECISION (TREE_TYPE (arg)) < prec)
650 if (TYPE_UNSIGNED (TREE_TYPE (arg)))
651 sign = UNSIGNED;
652 else if (sign == UNSIGNED && get_range_pos_neg (arg) != 1)
653 return prec + (orig_sign != sign);
654 prec = TYPE_PRECISION (TREE_TYPE (arg));
656 if (++cnt > 30)
657 return prec + (orig_sign != sign);
659 if (CONVERT_EXPR_P (arg)
660 && INTEGRAL_TYPE_P (TREE_TYPE (TREE_OPERAND (arg, 0)))
661 && TYPE_PRECISION (TREE_TYPE (TREE_OPERAND (arg, 0))) > prec)
663 /* We have e.g. (unsigned short) y_2 where int y_2 = (int) x_1(D);
664 If y_2's min precision is smaller than prec, return that. */
665 int oprec = get_min_precision (TREE_OPERAND (arg, 0), sign);
666 if (oprec < prec)
667 return oprec + (orig_sign != sign);
669 if (TREE_CODE (arg) != SSA_NAME)
670 return prec + (orig_sign != sign);
671 wide_int arg_min, arg_max;
672 while (get_range_info (arg, &arg_min, &arg_max) != VR_RANGE)
674 gimple *g = SSA_NAME_DEF_STMT (arg);
675 if (is_gimple_assign (g)
676 && CONVERT_EXPR_CODE_P (gimple_assign_rhs_code (g)))
678 tree t = gimple_assign_rhs1 (g);
679 if (INTEGRAL_TYPE_P (TREE_TYPE (t))
680 && TYPE_PRECISION (TREE_TYPE (t)) <= prec)
682 arg = t;
683 if (TYPE_PRECISION (TREE_TYPE (arg)) < prec)
685 if (TYPE_UNSIGNED (TREE_TYPE (arg)))
686 sign = UNSIGNED;
687 else if (sign == UNSIGNED && get_range_pos_neg (arg) != 1)
688 return prec + (orig_sign != sign);
689 prec = TYPE_PRECISION (TREE_TYPE (arg));
691 if (++cnt > 30)
692 return prec + (orig_sign != sign);
693 continue;
696 return prec + (orig_sign != sign);
698 if (sign == TYPE_SIGN (TREE_TYPE (arg)))
700 int p1 = wi::min_precision (arg_min, sign);
701 int p2 = wi::min_precision (arg_max, sign);
702 p1 = MAX (p1, p2);
703 prec = MIN (prec, p1);
705 else if (sign == UNSIGNED && !wi::neg_p (arg_min, SIGNED))
707 int p = wi::min_precision (arg_max, UNSIGNED);
708 prec = MIN (prec, p);
710 return prec + (orig_sign != sign);
713 /* Helper for expand_*_overflow. Set the __imag__ part to true
714 (1 except for signed:1 type, in which case store -1). */
716 static void
717 expand_arith_set_overflow (tree lhs, rtx target)
719 if (TYPE_PRECISION (TREE_TYPE (TREE_TYPE (lhs))) == 1
720 && !TYPE_UNSIGNED (TREE_TYPE (TREE_TYPE (lhs))))
721 write_complex_part (target, constm1_rtx, true);
722 else
723 write_complex_part (target, const1_rtx, true);
726 /* Helper for expand_*_overflow. Store RES into the __real__ part
727 of TARGET. If RES has larger MODE than __real__ part of TARGET,
728 set the __imag__ part to 1 if RES doesn't fit into it. Similarly
729 if LHS has smaller precision than its mode. */
731 static void
732 expand_arith_overflow_result_store (tree lhs, rtx target,
733 scalar_int_mode mode, rtx res)
735 scalar_int_mode tgtmode
736 = as_a <scalar_int_mode> (GET_MODE_INNER (GET_MODE (target)));
737 rtx lres = res;
738 if (tgtmode != mode)
740 rtx_code_label *done_label = gen_label_rtx ();
741 int uns = TYPE_UNSIGNED (TREE_TYPE (TREE_TYPE (lhs)));
742 lres = convert_modes (tgtmode, mode, res, uns);
743 gcc_assert (GET_MODE_PRECISION (tgtmode) < GET_MODE_PRECISION (mode));
744 do_compare_rtx_and_jump (res, convert_modes (mode, tgtmode, lres, uns),
745 EQ, true, mode, NULL_RTX, NULL, done_label,
746 profile_probability::very_likely ());
747 expand_arith_set_overflow (lhs, target);
748 emit_label (done_label);
750 int prec = TYPE_PRECISION (TREE_TYPE (TREE_TYPE (lhs)));
751 int tgtprec = GET_MODE_PRECISION (tgtmode);
752 if (prec < tgtprec)
754 rtx_code_label *done_label = gen_label_rtx ();
755 int uns = TYPE_UNSIGNED (TREE_TYPE (TREE_TYPE (lhs)));
756 res = lres;
757 if (uns)
759 rtx mask
760 = immed_wide_int_const (wi::shifted_mask (0, prec, false, tgtprec),
761 tgtmode);
762 lres = expand_simple_binop (tgtmode, AND, res, mask, NULL_RTX,
763 true, OPTAB_LIB_WIDEN);
765 else
767 lres = expand_shift (LSHIFT_EXPR, tgtmode, res, tgtprec - prec,
768 NULL_RTX, 1);
769 lres = expand_shift (RSHIFT_EXPR, tgtmode, lres, tgtprec - prec,
770 NULL_RTX, 0);
772 do_compare_rtx_and_jump (res, lres,
773 EQ, true, tgtmode, NULL_RTX, NULL, done_label,
774 profile_probability::very_likely ());
775 expand_arith_set_overflow (lhs, target);
776 emit_label (done_label);
778 write_complex_part (target, lres, false);
781 /* Helper for expand_*_overflow. Store RES into TARGET. */
783 static void
784 expand_ubsan_result_store (rtx target, rtx res)
786 if (GET_CODE (target) == SUBREG && SUBREG_PROMOTED_VAR_P (target))
787 /* If this is a scalar in a register that is stored in a wider mode
788 than the declared mode, compute the result into its declared mode
789 and then convert to the wider mode. Our value is the computed
790 expression. */
791 convert_move (SUBREG_REG (target), res, SUBREG_PROMOTED_SIGN (target));
792 else
793 emit_move_insn (target, res);
796 /* Add sub/add overflow checking to the statement STMT.
797 CODE says whether the operation is +, or -. */
799 void
800 expand_addsub_overflow (location_t loc, tree_code code, tree lhs,
801 tree arg0, tree arg1, bool unsr_p, bool uns0_p,
802 bool uns1_p, bool is_ubsan, tree *datap)
804 rtx res, target = NULL_RTX;
805 tree fn;
806 rtx_code_label *done_label = gen_label_rtx ();
807 rtx_code_label *do_error = gen_label_rtx ();
808 do_pending_stack_adjust ();
809 rtx op0 = expand_normal (arg0);
810 rtx op1 = expand_normal (arg1);
811 scalar_int_mode mode = SCALAR_INT_TYPE_MODE (TREE_TYPE (arg0));
812 int prec = GET_MODE_PRECISION (mode);
813 rtx sgn = immed_wide_int_const (wi::min_value (prec, SIGNED), mode);
814 bool do_xor = false;
816 if (is_ubsan)
817 gcc_assert (!unsr_p && !uns0_p && !uns1_p);
819 if (lhs)
821 target = expand_expr (lhs, NULL_RTX, VOIDmode, EXPAND_WRITE);
822 if (!is_ubsan)
823 write_complex_part (target, const0_rtx, true);
826 /* We assume both operands and result have the same precision
827 here (GET_MODE_BITSIZE (mode)), S stands for signed type
828 with that precision, U for unsigned type with that precision,
829 sgn for unsigned most significant bit in that precision.
830 s1 is signed first operand, u1 is unsigned first operand,
831 s2 is signed second operand, u2 is unsigned second operand,
832 sr is signed result, ur is unsigned result and the following
833 rules say how to compute result (which is always result of
834 the operands as if both were unsigned, cast to the right
835 signedness) and how to compute whether operation overflowed.
837 s1 + s2 -> sr
838 res = (S) ((U) s1 + (U) s2)
839 ovf = s2 < 0 ? res > s1 : res < s1 (or jump on overflow)
840 s1 - s2 -> sr
841 res = (S) ((U) s1 - (U) s2)
842 ovf = s2 < 0 ? res < s1 : res > s2 (or jump on overflow)
843 u1 + u2 -> ur
844 res = u1 + u2
845 ovf = res < u1 (or jump on carry, but RTL opts will handle it)
846 u1 - u2 -> ur
847 res = u1 - u2
848 ovf = res > u1 (or jump on carry, but RTL opts will handle it)
849 s1 + u2 -> sr
850 res = (S) ((U) s1 + u2)
851 ovf = ((U) res ^ sgn) < u2
852 s1 + u2 -> ur
853 t1 = (S) (u2 ^ sgn)
854 t2 = s1 + t1
855 res = (U) t2 ^ sgn
856 ovf = t1 < 0 ? t2 > s1 : t2 < s1 (or jump on overflow)
857 s1 - u2 -> sr
858 res = (S) ((U) s1 - u2)
859 ovf = u2 > ((U) s1 ^ sgn)
860 s1 - u2 -> ur
861 res = (U) s1 - u2
862 ovf = s1 < 0 || u2 > (U) s1
863 u1 - s2 -> sr
864 res = u1 - (U) s2
865 ovf = u1 >= ((U) s2 ^ sgn)
866 u1 - s2 -> ur
867 t1 = u1 ^ sgn
868 t2 = t1 - (U) s2
869 res = t2 ^ sgn
870 ovf = s2 < 0 ? (S) t2 < (S) t1 : (S) t2 > (S) t1 (or jump on overflow)
871 s1 + s2 -> ur
872 res = (U) s1 + (U) s2
873 ovf = s2 < 0 ? (s1 | (S) res) < 0) : (s1 & (S) res) < 0)
874 u1 + u2 -> sr
875 res = (S) (u1 + u2)
876 ovf = (U) res < u2 || res < 0
877 u1 - u2 -> sr
878 res = (S) (u1 - u2)
879 ovf = u1 >= u2 ? res < 0 : res >= 0
880 s1 - s2 -> ur
881 res = (U) s1 - (U) s2
882 ovf = s2 >= 0 ? ((s1 | (S) res) < 0) : ((s1 & (S) res) < 0) */
884 if (code == PLUS_EXPR && uns0_p && !uns1_p)
886 /* PLUS_EXPR is commutative, if operand signedness differs,
887 canonicalize to the first operand being signed and second
888 unsigned to simplify following code. */
889 std::swap (op0, op1);
890 std::swap (arg0, arg1);
891 uns0_p = false;
892 uns1_p = true;
895 /* u1 +- u2 -> ur */
896 if (uns0_p && uns1_p && unsr_p)
898 insn_code icode = optab_handler (code == PLUS_EXPR ? uaddv4_optab
899 : usubv4_optab, mode);
900 if (icode != CODE_FOR_nothing)
902 class expand_operand ops[4];
903 rtx_insn *last = get_last_insn ();
905 res = gen_reg_rtx (mode);
906 create_output_operand (&ops[0], res, mode);
907 create_input_operand (&ops[1], op0, mode);
908 create_input_operand (&ops[2], op1, mode);
909 create_fixed_operand (&ops[3], do_error);
910 if (maybe_expand_insn (icode, 4, ops))
912 last = get_last_insn ();
913 if (profile_status_for_fn (cfun) != PROFILE_ABSENT
914 && JUMP_P (last)
915 && any_condjump_p (last)
916 && !find_reg_note (last, REG_BR_PROB, 0))
917 add_reg_br_prob_note (last,
918 profile_probability::very_unlikely ());
919 emit_jump (done_label);
920 goto do_error_label;
923 delete_insns_since (last);
926 /* Compute the operation. On RTL level, the addition is always
927 unsigned. */
928 res = expand_binop (mode, code == PLUS_EXPR ? add_optab : sub_optab,
929 op0, op1, NULL_RTX, false, OPTAB_LIB_WIDEN);
930 rtx tem = op0;
931 /* For PLUS_EXPR, the operation is commutative, so we can pick
932 operand to compare against. For prec <= BITS_PER_WORD, I think
933 preferring REG operand is better over CONST_INT, because
934 the CONST_INT might enlarge the instruction or CSE would need
935 to figure out we'd already loaded it into a register before.
936 For prec > BITS_PER_WORD, I think CONST_INT might be more beneficial,
937 as then the multi-word comparison can be perhaps simplified. */
938 if (code == PLUS_EXPR
939 && (prec <= BITS_PER_WORD
940 ? (CONST_SCALAR_INT_P (op0) && REG_P (op1))
941 : CONST_SCALAR_INT_P (op1)))
942 tem = op1;
943 do_compare_rtx_and_jump (res, tem, code == PLUS_EXPR ? GEU : LEU,
944 true, mode, NULL_RTX, NULL, done_label,
945 profile_probability::very_likely ());
946 goto do_error_label;
949 /* s1 +- u2 -> sr */
950 if (!uns0_p && uns1_p && !unsr_p)
952 /* Compute the operation. On RTL level, the addition is always
953 unsigned. */
954 res = expand_binop (mode, code == PLUS_EXPR ? add_optab : sub_optab,
955 op0, op1, NULL_RTX, false, OPTAB_LIB_WIDEN);
956 rtx tem = expand_binop (mode, add_optab,
957 code == PLUS_EXPR ? res : op0, sgn,
958 NULL_RTX, false, OPTAB_LIB_WIDEN);
959 do_compare_rtx_and_jump (tem, op1, GEU, true, mode, NULL_RTX, NULL,
960 done_label, profile_probability::very_likely ());
961 goto do_error_label;
964 /* s1 + u2 -> ur */
965 if (code == PLUS_EXPR && !uns0_p && uns1_p && unsr_p)
967 op1 = expand_binop (mode, add_optab, op1, sgn, NULL_RTX, false,
968 OPTAB_LIB_WIDEN);
969 /* As we've changed op1, we have to avoid using the value range
970 for the original argument. */
971 arg1 = error_mark_node;
972 do_xor = true;
973 goto do_signed;
976 /* u1 - s2 -> ur */
977 if (code == MINUS_EXPR && uns0_p && !uns1_p && unsr_p)
979 op0 = expand_binop (mode, add_optab, op0, sgn, NULL_RTX, false,
980 OPTAB_LIB_WIDEN);
981 /* As we've changed op0, we have to avoid using the value range
982 for the original argument. */
983 arg0 = error_mark_node;
984 do_xor = true;
985 goto do_signed;
988 /* s1 - u2 -> ur */
989 if (code == MINUS_EXPR && !uns0_p && uns1_p && unsr_p)
991 /* Compute the operation. On RTL level, the addition is always
992 unsigned. */
993 res = expand_binop (mode, sub_optab, op0, op1, NULL_RTX, false,
994 OPTAB_LIB_WIDEN);
995 int pos_neg = get_range_pos_neg (arg0);
996 if (pos_neg == 2)
997 /* If ARG0 is known to be always negative, this is always overflow. */
998 emit_jump (do_error);
999 else if (pos_neg == 3)
1000 /* If ARG0 is not known to be always positive, check at runtime. */
1001 do_compare_rtx_and_jump (op0, const0_rtx, LT, false, mode, NULL_RTX,
1002 NULL, do_error, profile_probability::very_unlikely ());
1003 do_compare_rtx_and_jump (op1, op0, LEU, true, mode, NULL_RTX, NULL,
1004 done_label, profile_probability::very_likely ());
1005 goto do_error_label;
1008 /* u1 - s2 -> sr */
1009 if (code == MINUS_EXPR && uns0_p && !uns1_p && !unsr_p)
1011 /* Compute the operation. On RTL level, the addition is always
1012 unsigned. */
1013 res = expand_binop (mode, sub_optab, op0, op1, NULL_RTX, false,
1014 OPTAB_LIB_WIDEN);
1015 rtx tem = expand_binop (mode, add_optab, op1, sgn, NULL_RTX, false,
1016 OPTAB_LIB_WIDEN);
1017 do_compare_rtx_and_jump (op0, tem, LTU, true, mode, NULL_RTX, NULL,
1018 done_label, profile_probability::very_likely ());
1019 goto do_error_label;
1022 /* u1 + u2 -> sr */
1023 if (code == PLUS_EXPR && uns0_p && uns1_p && !unsr_p)
1025 /* Compute the operation. On RTL level, the addition is always
1026 unsigned. */
1027 res = expand_binop (mode, add_optab, op0, op1, NULL_RTX, false,
1028 OPTAB_LIB_WIDEN);
1029 do_compare_rtx_and_jump (res, const0_rtx, LT, false, mode, NULL_RTX,
1030 NULL, do_error, profile_probability::very_unlikely ());
1031 rtx tem = op1;
1032 /* The operation is commutative, so we can pick operand to compare
1033 against. For prec <= BITS_PER_WORD, I think preferring REG operand
1034 is better over CONST_INT, because the CONST_INT might enlarge the
1035 instruction or CSE would need to figure out we'd already loaded it
1036 into a register before. For prec > BITS_PER_WORD, I think CONST_INT
1037 might be more beneficial, as then the multi-word comparison can be
1038 perhaps simplified. */
1039 if (prec <= BITS_PER_WORD
1040 ? (CONST_SCALAR_INT_P (op1) && REG_P (op0))
1041 : CONST_SCALAR_INT_P (op0))
1042 tem = op0;
1043 do_compare_rtx_and_jump (res, tem, GEU, true, mode, NULL_RTX, NULL,
1044 done_label, profile_probability::very_likely ());
1045 goto do_error_label;
1048 /* s1 +- s2 -> ur */
1049 if (!uns0_p && !uns1_p && unsr_p)
1051 /* Compute the operation. On RTL level, the addition is always
1052 unsigned. */
1053 res = expand_binop (mode, code == PLUS_EXPR ? add_optab : sub_optab,
1054 op0, op1, NULL_RTX, false, OPTAB_LIB_WIDEN);
1055 int pos_neg = get_range_pos_neg (arg1);
1056 if (code == PLUS_EXPR)
1058 int pos_neg0 = get_range_pos_neg (arg0);
1059 if (pos_neg0 != 3 && pos_neg == 3)
1061 std::swap (op0, op1);
1062 pos_neg = pos_neg0;
1065 rtx tem;
1066 if (pos_neg != 3)
1068 tem = expand_binop (mode, ((pos_neg == 1) ^ (code == MINUS_EXPR))
1069 ? and_optab : ior_optab,
1070 op0, res, NULL_RTX, false, OPTAB_LIB_WIDEN);
1071 do_compare_rtx_and_jump (tem, const0_rtx, GE, false, mode, NULL,
1072 NULL, done_label, profile_probability::very_likely ());
1074 else
1076 rtx_code_label *do_ior_label = gen_label_rtx ();
1077 do_compare_rtx_and_jump (op1, const0_rtx,
1078 code == MINUS_EXPR ? GE : LT, false, mode,
1079 NULL_RTX, NULL, do_ior_label,
1080 profile_probability::even ());
1081 tem = expand_binop (mode, and_optab, op0, res, NULL_RTX, false,
1082 OPTAB_LIB_WIDEN);
1083 do_compare_rtx_and_jump (tem, const0_rtx, GE, false, mode, NULL_RTX,
1084 NULL, done_label, profile_probability::very_likely ());
1085 emit_jump (do_error);
1086 emit_label (do_ior_label);
1087 tem = expand_binop (mode, ior_optab, op0, res, NULL_RTX, false,
1088 OPTAB_LIB_WIDEN);
1089 do_compare_rtx_and_jump (tem, const0_rtx, GE, false, mode, NULL_RTX,
1090 NULL, done_label, profile_probability::very_likely ());
1092 goto do_error_label;
1095 /* u1 - u2 -> sr */
1096 if (code == MINUS_EXPR && uns0_p && uns1_p && !unsr_p)
1098 /* Compute the operation. On RTL level, the addition is always
1099 unsigned. */
1100 res = expand_binop (mode, sub_optab, op0, op1, NULL_RTX, false,
1101 OPTAB_LIB_WIDEN);
1102 rtx_code_label *op0_geu_op1 = gen_label_rtx ();
1103 do_compare_rtx_and_jump (op0, op1, GEU, true, mode, NULL_RTX, NULL,
1104 op0_geu_op1, profile_probability::even ());
1105 do_compare_rtx_and_jump (res, const0_rtx, LT, false, mode, NULL_RTX,
1106 NULL, done_label, profile_probability::very_likely ());
1107 emit_jump (do_error);
1108 emit_label (op0_geu_op1);
1109 do_compare_rtx_and_jump (res, const0_rtx, GE, false, mode, NULL_RTX,
1110 NULL, done_label, profile_probability::very_likely ());
1111 goto do_error_label;
1114 gcc_assert (!uns0_p && !uns1_p && !unsr_p);
1116 /* s1 +- s2 -> sr */
1117 do_signed:
1119 insn_code icode = optab_handler (code == PLUS_EXPR ? addv4_optab
1120 : subv4_optab, mode);
1121 if (icode != CODE_FOR_nothing)
1123 class expand_operand ops[4];
1124 rtx_insn *last = get_last_insn ();
1126 res = gen_reg_rtx (mode);
1127 create_output_operand (&ops[0], res, mode);
1128 create_input_operand (&ops[1], op0, mode);
1129 create_input_operand (&ops[2], op1, mode);
1130 create_fixed_operand (&ops[3], do_error);
1131 if (maybe_expand_insn (icode, 4, ops))
1133 last = get_last_insn ();
1134 if (profile_status_for_fn (cfun) != PROFILE_ABSENT
1135 && JUMP_P (last)
1136 && any_condjump_p (last)
1137 && !find_reg_note (last, REG_BR_PROB, 0))
1138 add_reg_br_prob_note (last,
1139 profile_probability::very_unlikely ());
1140 emit_jump (done_label);
1141 goto do_error_label;
1144 delete_insns_since (last);
1147 /* Compute the operation. On RTL level, the addition is always
1148 unsigned. */
1149 res = expand_binop (mode, code == PLUS_EXPR ? add_optab : sub_optab,
1150 op0, op1, NULL_RTX, false, OPTAB_LIB_WIDEN);
1152 /* If we can prove that one of the arguments (for MINUS_EXPR only
1153 the second operand, as subtraction is not commutative) is always
1154 non-negative or always negative, we can do just one comparison
1155 and conditional jump. */
1156 int pos_neg = get_range_pos_neg (arg1);
1157 if (code == PLUS_EXPR)
1159 int pos_neg0 = get_range_pos_neg (arg0);
1160 if (pos_neg0 != 3 && pos_neg == 3)
1162 std::swap (op0, op1);
1163 pos_neg = pos_neg0;
1167 /* Addition overflows if and only if the two operands have the same sign,
1168 and the result has the opposite sign. Subtraction overflows if and
1169 only if the two operands have opposite sign, and the subtrahend has
1170 the same sign as the result. Here 0 is counted as positive. */
1171 if (pos_neg == 3)
1173 /* Compute op0 ^ op1 (operands have opposite sign). */
1174 rtx op_xor = expand_binop (mode, xor_optab, op0, op1, NULL_RTX, false,
1175 OPTAB_LIB_WIDEN);
1177 /* Compute res ^ op1 (result and 2nd operand have opposite sign). */
1178 rtx res_xor = expand_binop (mode, xor_optab, res, op1, NULL_RTX, false,
1179 OPTAB_LIB_WIDEN);
1181 rtx tem;
1182 if (code == PLUS_EXPR)
1184 /* Compute (res ^ op1) & ~(op0 ^ op1). */
1185 tem = expand_unop (mode, one_cmpl_optab, op_xor, NULL_RTX, false);
1186 tem = expand_binop (mode, and_optab, res_xor, tem, NULL_RTX, false,
1187 OPTAB_LIB_WIDEN);
1189 else
1191 /* Compute (op0 ^ op1) & ~(res ^ op1). */
1192 tem = expand_unop (mode, one_cmpl_optab, res_xor, NULL_RTX, false);
1193 tem = expand_binop (mode, and_optab, op_xor, tem, NULL_RTX, false,
1194 OPTAB_LIB_WIDEN);
1197 /* No overflow if the result has bit sign cleared. */
1198 do_compare_rtx_and_jump (tem, const0_rtx, GE, false, mode, NULL_RTX,
1199 NULL, done_label, profile_probability::very_likely ());
1202 /* Compare the result of the operation with the first operand.
1203 No overflow for addition if second operand is positive and result
1204 is larger or second operand is negative and result is smaller.
1205 Likewise for subtraction with sign of second operand flipped. */
1206 else
1207 do_compare_rtx_and_jump (res, op0,
1208 (pos_neg == 1) ^ (code == MINUS_EXPR) ? GE : LE,
1209 false, mode, NULL_RTX, NULL, done_label,
1210 profile_probability::very_likely ());
1213 do_error_label:
1214 emit_label (do_error);
1215 if (is_ubsan)
1217 /* Expand the ubsan builtin call. */
1218 push_temp_slots ();
1219 fn = ubsan_build_overflow_builtin (code, loc, TREE_TYPE (arg0),
1220 arg0, arg1, datap);
1221 expand_normal (fn);
1222 pop_temp_slots ();
1223 do_pending_stack_adjust ();
1225 else if (lhs)
1226 expand_arith_set_overflow (lhs, target);
1228 /* We're done. */
1229 emit_label (done_label);
1231 if (lhs)
1233 if (is_ubsan)
1234 expand_ubsan_result_store (target, res);
1235 else
1237 if (do_xor)
1238 res = expand_binop (mode, add_optab, res, sgn, NULL_RTX, false,
1239 OPTAB_LIB_WIDEN);
1241 expand_arith_overflow_result_store (lhs, target, mode, res);
1246 /* Add negate overflow checking to the statement STMT. */
1248 static void
1249 expand_neg_overflow (location_t loc, tree lhs, tree arg1, bool is_ubsan,
1250 tree *datap)
1252 rtx res, op1;
1253 tree fn;
1254 rtx_code_label *done_label, *do_error;
1255 rtx target = NULL_RTX;
1257 done_label = gen_label_rtx ();
1258 do_error = gen_label_rtx ();
1260 do_pending_stack_adjust ();
1261 op1 = expand_normal (arg1);
1263 scalar_int_mode mode = SCALAR_INT_TYPE_MODE (TREE_TYPE (arg1));
1264 if (lhs)
1266 target = expand_expr (lhs, NULL_RTX, VOIDmode, EXPAND_WRITE);
1267 if (!is_ubsan)
1268 write_complex_part (target, const0_rtx, true);
1271 enum insn_code icode = optab_handler (negv3_optab, mode);
1272 if (icode != CODE_FOR_nothing)
1274 class expand_operand ops[3];
1275 rtx_insn *last = get_last_insn ();
1277 res = gen_reg_rtx (mode);
1278 create_output_operand (&ops[0], res, mode);
1279 create_input_operand (&ops[1], op1, mode);
1280 create_fixed_operand (&ops[2], do_error);
1281 if (maybe_expand_insn (icode, 3, ops))
1283 last = get_last_insn ();
1284 if (profile_status_for_fn (cfun) != PROFILE_ABSENT
1285 && JUMP_P (last)
1286 && any_condjump_p (last)
1287 && !find_reg_note (last, REG_BR_PROB, 0))
1288 add_reg_br_prob_note (last,
1289 profile_probability::very_unlikely ());
1290 emit_jump (done_label);
1292 else
1294 delete_insns_since (last);
1295 icode = CODE_FOR_nothing;
1299 if (icode == CODE_FOR_nothing)
1301 /* Compute the operation. On RTL level, the addition is always
1302 unsigned. */
1303 res = expand_unop (mode, neg_optab, op1, NULL_RTX, false);
1305 /* Compare the operand with the most negative value. */
1306 rtx minv = expand_normal (TYPE_MIN_VALUE (TREE_TYPE (arg1)));
1307 do_compare_rtx_and_jump (op1, minv, NE, true, mode, NULL_RTX, NULL,
1308 done_label, profile_probability::very_likely ());
1311 emit_label (do_error);
1312 if (is_ubsan)
1314 /* Expand the ubsan builtin call. */
1315 push_temp_slots ();
1316 fn = ubsan_build_overflow_builtin (NEGATE_EXPR, loc, TREE_TYPE (arg1),
1317 arg1, NULL_TREE, datap);
1318 expand_normal (fn);
1319 pop_temp_slots ();
1320 do_pending_stack_adjust ();
1322 else if (lhs)
1323 expand_arith_set_overflow (lhs, target);
1325 /* We're done. */
1326 emit_label (done_label);
1328 if (lhs)
1330 if (is_ubsan)
1331 expand_ubsan_result_store (target, res);
1332 else
1333 expand_arith_overflow_result_store (lhs, target, mode, res);
1337 /* Return true if UNS WIDEN_MULT_EXPR with result mode WMODE and operand
1338 mode MODE can be expanded without using a libcall. */
1340 static bool
1341 can_widen_mult_without_libcall (scalar_int_mode wmode, scalar_int_mode mode,
1342 rtx op0, rtx op1, bool uns)
1344 if (find_widening_optab_handler (umul_widen_optab, wmode, mode)
1345 != CODE_FOR_nothing)
1346 return true;
1348 if (find_widening_optab_handler (smul_widen_optab, wmode, mode)
1349 != CODE_FOR_nothing)
1350 return true;
1352 rtx_insn *last = get_last_insn ();
1353 if (CONSTANT_P (op0))
1354 op0 = convert_modes (wmode, mode, op0, uns);
1355 else
1356 op0 = gen_raw_REG (wmode, LAST_VIRTUAL_REGISTER + 1);
1357 if (CONSTANT_P (op1))
1358 op1 = convert_modes (wmode, mode, op1, uns);
1359 else
1360 op1 = gen_raw_REG (wmode, LAST_VIRTUAL_REGISTER + 2);
1361 rtx ret = expand_mult (wmode, op0, op1, NULL_RTX, uns, true);
1362 delete_insns_since (last);
1363 return ret != NULL_RTX;
1366 /* Add mul overflow checking to the statement STMT. */
1368 static void
1369 expand_mul_overflow (location_t loc, tree lhs, tree arg0, tree arg1,
1370 bool unsr_p, bool uns0_p, bool uns1_p, bool is_ubsan,
1371 tree *datap)
1373 rtx res, op0, op1;
1374 tree fn, type;
1375 rtx_code_label *done_label, *do_error;
1376 rtx target = NULL_RTX;
1377 signop sign;
1378 enum insn_code icode;
1380 done_label = gen_label_rtx ();
1381 do_error = gen_label_rtx ();
1383 do_pending_stack_adjust ();
1384 op0 = expand_normal (arg0);
1385 op1 = expand_normal (arg1);
1387 scalar_int_mode mode = SCALAR_INT_TYPE_MODE (TREE_TYPE (arg0));
1388 bool uns = unsr_p;
1389 if (lhs)
1391 target = expand_expr (lhs, NULL_RTX, VOIDmode, EXPAND_WRITE);
1392 if (!is_ubsan)
1393 write_complex_part (target, const0_rtx, true);
1396 if (is_ubsan)
1397 gcc_assert (!unsr_p && !uns0_p && !uns1_p);
1399 /* We assume both operands and result have the same precision
1400 here (GET_MODE_BITSIZE (mode)), S stands for signed type
1401 with that precision, U for unsigned type with that precision,
1402 sgn for unsigned most significant bit in that precision.
1403 s1 is signed first operand, u1 is unsigned first operand,
1404 s2 is signed second operand, u2 is unsigned second operand,
1405 sr is signed result, ur is unsigned result and the following
1406 rules say how to compute result (which is always result of
1407 the operands as if both were unsigned, cast to the right
1408 signedness) and how to compute whether operation overflowed.
1409 main_ovf (false) stands for jump on signed multiplication
1410 overflow or the main algorithm with uns == false.
1411 main_ovf (true) stands for jump on unsigned multiplication
1412 overflow or the main algorithm with uns == true.
1414 s1 * s2 -> sr
1415 res = (S) ((U) s1 * (U) s2)
1416 ovf = main_ovf (false)
1417 u1 * u2 -> ur
1418 res = u1 * u2
1419 ovf = main_ovf (true)
1420 s1 * u2 -> ur
1421 res = (U) s1 * u2
1422 ovf = (s1 < 0 && u2) || main_ovf (true)
1423 u1 * u2 -> sr
1424 res = (S) (u1 * u2)
1425 ovf = res < 0 || main_ovf (true)
1426 s1 * u2 -> sr
1427 res = (S) ((U) s1 * u2)
1428 ovf = (S) u2 >= 0 ? main_ovf (false)
1429 : (s1 != 0 && (s1 != -1 || u2 != (U) res))
1430 s1 * s2 -> ur
1431 t1 = (s1 & s2) < 0 ? (-(U) s1) : ((U) s1)
1432 t2 = (s1 & s2) < 0 ? (-(U) s2) : ((U) s2)
1433 res = t1 * t2
1434 ovf = (s1 ^ s2) < 0 ? (s1 && s2) : main_ovf (true) */
1436 if (uns0_p && !uns1_p)
1438 /* Multiplication is commutative, if operand signedness differs,
1439 canonicalize to the first operand being signed and second
1440 unsigned to simplify following code. */
1441 std::swap (op0, op1);
1442 std::swap (arg0, arg1);
1443 uns0_p = false;
1444 uns1_p = true;
1447 int pos_neg0 = get_range_pos_neg (arg0);
1448 int pos_neg1 = get_range_pos_neg (arg1);
1450 /* s1 * u2 -> ur */
1451 if (!uns0_p && uns1_p && unsr_p)
1453 switch (pos_neg0)
1455 case 1:
1456 /* If s1 is non-negative, just perform normal u1 * u2 -> ur. */
1457 goto do_main;
1458 case 2:
1459 /* If s1 is negative, avoid the main code, just multiply and
1460 signal overflow if op1 is not 0. */
1461 struct separate_ops ops;
1462 ops.code = MULT_EXPR;
1463 ops.type = TREE_TYPE (arg1);
1464 ops.op0 = make_tree (ops.type, op0);
1465 ops.op1 = make_tree (ops.type, op1);
1466 ops.op2 = NULL_TREE;
1467 ops.location = loc;
1468 res = expand_expr_real_2 (&ops, NULL_RTX, mode, EXPAND_NORMAL);
1469 do_compare_rtx_and_jump (op1, const0_rtx, EQ, true, mode, NULL_RTX,
1470 NULL, done_label, profile_probability::very_likely ());
1471 goto do_error_label;
1472 case 3:
1473 if (get_min_precision (arg1, UNSIGNED)
1474 + get_min_precision (arg0, SIGNED) <= GET_MODE_PRECISION (mode))
1476 /* If the first operand is sign extended from narrower type, the
1477 second operand is zero extended from narrower type and
1478 the sum of the two precisions is smaller or equal to the
1479 result precision: if the first argument is at runtime
1480 non-negative, maximum result will be 0x7e81 or 0x7f..fe80..01
1481 and there will be no overflow, if the first argument is
1482 negative and the second argument zero, the result will be
1483 0 and there will be no overflow, if the first argument is
1484 negative and the second argument positive, the result when
1485 treated as signed will be negative (minimum -0x7f80 or
1486 -0x7f..f80..0) there there will be always overflow. So, do
1487 res = (U) (s1 * u2)
1488 ovf = (S) res < 0 */
1489 struct separate_ops ops;
1490 ops.code = MULT_EXPR;
1491 ops.type
1492 = build_nonstandard_integer_type (GET_MODE_PRECISION (mode),
1494 ops.op0 = make_tree (ops.type, op0);
1495 ops.op1 = make_tree (ops.type, op1);
1496 ops.op2 = NULL_TREE;
1497 ops.location = loc;
1498 res = expand_expr_real_2 (&ops, NULL_RTX, mode, EXPAND_NORMAL);
1499 do_compare_rtx_and_jump (res, const0_rtx, GE, false,
1500 mode, NULL_RTX, NULL, done_label,
1501 profile_probability::very_likely ());
1502 goto do_error_label;
1504 rtx_code_label *do_main_label;
1505 do_main_label = gen_label_rtx ();
1506 do_compare_rtx_and_jump (op0, const0_rtx, GE, false, mode, NULL_RTX,
1507 NULL, do_main_label, profile_probability::very_likely ());
1508 do_compare_rtx_and_jump (op1, const0_rtx, EQ, true, mode, NULL_RTX,
1509 NULL, do_main_label, profile_probability::very_likely ());
1510 expand_arith_set_overflow (lhs, target);
1511 emit_label (do_main_label);
1512 goto do_main;
1513 default:
1514 gcc_unreachable ();
1518 /* u1 * u2 -> sr */
1519 if (uns0_p && uns1_p && !unsr_p)
1521 if ((pos_neg0 | pos_neg1) == 1)
1523 /* If both arguments are zero extended from narrower types,
1524 the MSB will be clear on both and so we can pretend it is
1525 a normal s1 * s2 -> sr multiplication. */
1526 uns0_p = false;
1527 uns1_p = false;
1529 else
1530 uns = true;
1531 /* Rest of handling of this case after res is computed. */
1532 goto do_main;
1535 /* s1 * u2 -> sr */
1536 if (!uns0_p && uns1_p && !unsr_p)
1538 switch (pos_neg1)
1540 case 1:
1541 goto do_main;
1542 case 2:
1543 /* If (S) u2 is negative (i.e. u2 is larger than maximum of S,
1544 avoid the main code, just multiply and signal overflow
1545 unless 0 * u2 or -1 * ((U) Smin). */
1546 struct separate_ops ops;
1547 ops.code = MULT_EXPR;
1548 ops.type = TREE_TYPE (arg1);
1549 ops.op0 = make_tree (ops.type, op0);
1550 ops.op1 = make_tree (ops.type, op1);
1551 ops.op2 = NULL_TREE;
1552 ops.location = loc;
1553 res = expand_expr_real_2 (&ops, NULL_RTX, mode, EXPAND_NORMAL);
1554 do_compare_rtx_and_jump (op0, const0_rtx, EQ, true, mode, NULL_RTX,
1555 NULL, done_label, profile_probability::very_likely ());
1556 do_compare_rtx_and_jump (op0, constm1_rtx, NE, true, mode, NULL_RTX,
1557 NULL, do_error, profile_probability::very_unlikely ());
1558 int prec;
1559 prec = GET_MODE_PRECISION (mode);
1560 rtx sgn;
1561 sgn = immed_wide_int_const (wi::min_value (prec, SIGNED), mode);
1562 do_compare_rtx_and_jump (op1, sgn, EQ, true, mode, NULL_RTX,
1563 NULL, done_label, profile_probability::very_likely ());
1564 goto do_error_label;
1565 case 3:
1566 /* Rest of handling of this case after res is computed. */
1567 goto do_main;
1568 default:
1569 gcc_unreachable ();
1573 /* s1 * s2 -> ur */
1574 if (!uns0_p && !uns1_p && unsr_p)
1576 rtx tem;
1577 switch (pos_neg0 | pos_neg1)
1579 case 1: /* Both operands known to be non-negative. */
1580 goto do_main;
1581 case 2: /* Both operands known to be negative. */
1582 op0 = expand_unop (mode, neg_optab, op0, NULL_RTX, false);
1583 op1 = expand_unop (mode, neg_optab, op1, NULL_RTX, false);
1584 /* Avoid looking at arg0/arg1 ranges, as we've changed
1585 the arguments. */
1586 arg0 = error_mark_node;
1587 arg1 = error_mark_node;
1588 goto do_main;
1589 case 3:
1590 if ((pos_neg0 ^ pos_neg1) == 3)
1592 /* If one operand is known to be negative and the other
1593 non-negative, this overflows always, unless the non-negative
1594 one is 0. Just do normal multiply and set overflow
1595 unless one of the operands is 0. */
1596 struct separate_ops ops;
1597 ops.code = MULT_EXPR;
1598 ops.type
1599 = build_nonstandard_integer_type (GET_MODE_PRECISION (mode),
1601 ops.op0 = make_tree (ops.type, op0);
1602 ops.op1 = make_tree (ops.type, op1);
1603 ops.op2 = NULL_TREE;
1604 ops.location = loc;
1605 res = expand_expr_real_2 (&ops, NULL_RTX, mode, EXPAND_NORMAL);
1606 do_compare_rtx_and_jump (pos_neg0 == 1 ? op0 : op1, const0_rtx, EQ,
1607 true, mode, NULL_RTX, NULL, done_label,
1608 profile_probability::very_likely ());
1609 goto do_error_label;
1611 if (get_min_precision (arg0, SIGNED)
1612 + get_min_precision (arg1, SIGNED) <= GET_MODE_PRECISION (mode))
1614 /* If both operands are sign extended from narrower types and
1615 the sum of the two precisions is smaller or equal to the
1616 result precision: if both arguments are at runtime
1617 non-negative, maximum result will be 0x3f01 or 0x3f..f0..01
1618 and there will be no overflow, if both arguments are negative,
1619 maximum result will be 0x40..00 and there will be no overflow
1620 either, if one argument is positive and the other argument
1621 negative, the result when treated as signed will be negative
1622 and there will be always overflow, and if one argument is
1623 zero and the other negative the result will be zero and no
1624 overflow. So, do
1625 res = (U) (s1 * s2)
1626 ovf = (S) res < 0 */
1627 struct separate_ops ops;
1628 ops.code = MULT_EXPR;
1629 ops.type
1630 = build_nonstandard_integer_type (GET_MODE_PRECISION (mode),
1632 ops.op0 = make_tree (ops.type, op0);
1633 ops.op1 = make_tree (ops.type, op1);
1634 ops.op2 = NULL_TREE;
1635 ops.location = loc;
1636 res = expand_expr_real_2 (&ops, NULL_RTX, mode, EXPAND_NORMAL);
1637 do_compare_rtx_and_jump (res, const0_rtx, GE, false,
1638 mode, NULL_RTX, NULL, done_label,
1639 profile_probability::very_likely ());
1640 goto do_error_label;
1642 /* The general case, do all the needed comparisons at runtime. */
1643 rtx_code_label *do_main_label, *after_negate_label;
1644 rtx rop0, rop1;
1645 rop0 = gen_reg_rtx (mode);
1646 rop1 = gen_reg_rtx (mode);
1647 emit_move_insn (rop0, op0);
1648 emit_move_insn (rop1, op1);
1649 op0 = rop0;
1650 op1 = rop1;
1651 do_main_label = gen_label_rtx ();
1652 after_negate_label = gen_label_rtx ();
1653 tem = expand_binop (mode, and_optab, op0, op1, NULL_RTX, false,
1654 OPTAB_LIB_WIDEN);
1655 do_compare_rtx_and_jump (tem, const0_rtx, GE, false, mode, NULL_RTX,
1656 NULL, after_negate_label, profile_probability::very_likely ());
1657 /* Both arguments negative here, negate them and continue with
1658 normal unsigned overflow checking multiplication. */
1659 emit_move_insn (op0, expand_unop (mode, neg_optab, op0,
1660 NULL_RTX, false));
1661 emit_move_insn (op1, expand_unop (mode, neg_optab, op1,
1662 NULL_RTX, false));
1663 /* Avoid looking at arg0/arg1 ranges, as we might have changed
1664 the arguments. */
1665 arg0 = error_mark_node;
1666 arg1 = error_mark_node;
1667 emit_jump (do_main_label);
1668 emit_label (after_negate_label);
1669 tem = expand_binop (mode, xor_optab, op0, op1, NULL_RTX, false,
1670 OPTAB_LIB_WIDEN);
1671 do_compare_rtx_and_jump (tem, const0_rtx, GE, false, mode, NULL_RTX,
1672 NULL, do_main_label,
1673 profile_probability::very_likely ());
1674 /* One argument is negative here, the other positive. This
1675 overflows always, unless one of the arguments is 0. But
1676 if e.g. s2 is 0, (U) s1 * 0 doesn't overflow, whatever s1
1677 is, thus we can keep do_main code oring in overflow as is. */
1678 if (pos_neg0 != 2)
1679 do_compare_rtx_and_jump (op0, const0_rtx, EQ, true, mode, NULL_RTX,
1680 NULL, do_main_label,
1681 profile_probability::very_unlikely ());
1682 if (pos_neg1 != 2)
1683 do_compare_rtx_and_jump (op1, const0_rtx, EQ, true, mode, NULL_RTX,
1684 NULL, do_main_label,
1685 profile_probability::very_unlikely ());
1686 expand_arith_set_overflow (lhs, target);
1687 emit_label (do_main_label);
1688 goto do_main;
1689 default:
1690 gcc_unreachable ();
1694 do_main:
1695 type = build_nonstandard_integer_type (GET_MODE_PRECISION (mode), uns);
1696 sign = uns ? UNSIGNED : SIGNED;
1697 icode = optab_handler (uns ? umulv4_optab : mulv4_optab, mode);
1698 if (uns
1699 && (integer_pow2p (arg0) || integer_pow2p (arg1))
1700 && (optimize_insn_for_speed_p () || icode == CODE_FOR_nothing))
1702 /* Optimize unsigned multiplication by power of 2 constant
1703 using 2 shifts, one for result, one to extract the shifted
1704 out bits to see if they are all zero.
1705 Don't do this if optimizing for size and we have umulv4_optab,
1706 in that case assume multiplication will be shorter.
1707 This is heuristics based on the single target that provides
1708 umulv4 right now (i?86/x86_64), if further targets add it, this
1709 might need to be revisited.
1710 Cases where both operands are constant should be folded already
1711 during GIMPLE, and cases where one operand is constant but not
1712 power of 2 are questionable, either the WIDEN_MULT_EXPR case
1713 below can be done without multiplication, just by shifts and adds,
1714 or we'd need to divide the result (and hope it actually doesn't
1715 really divide nor multiply) and compare the result of the division
1716 with the original operand. */
1717 rtx opn0 = op0;
1718 rtx opn1 = op1;
1719 tree argn0 = arg0;
1720 tree argn1 = arg1;
1721 if (integer_pow2p (arg0))
1723 std::swap (opn0, opn1);
1724 std::swap (argn0, argn1);
1726 int cnt = tree_log2 (argn1);
1727 if (cnt >= 0 && cnt < GET_MODE_PRECISION (mode))
1729 rtx upper = const0_rtx;
1730 res = expand_shift (LSHIFT_EXPR, mode, opn0, cnt, NULL_RTX, uns);
1731 if (cnt != 0)
1732 upper = expand_shift (RSHIFT_EXPR, mode, opn0,
1733 GET_MODE_PRECISION (mode) - cnt,
1734 NULL_RTX, uns);
1735 do_compare_rtx_and_jump (upper, const0_rtx, EQ, true, mode,
1736 NULL_RTX, NULL, done_label,
1737 profile_probability::very_likely ());
1738 goto do_error_label;
1741 if (icode != CODE_FOR_nothing)
1743 class expand_operand ops[4];
1744 rtx_insn *last = get_last_insn ();
1746 res = gen_reg_rtx (mode);
1747 create_output_operand (&ops[0], res, mode);
1748 create_input_operand (&ops[1], op0, mode);
1749 create_input_operand (&ops[2], op1, mode);
1750 create_fixed_operand (&ops[3], do_error);
1751 if (maybe_expand_insn (icode, 4, ops))
1753 last = get_last_insn ();
1754 if (profile_status_for_fn (cfun) != PROFILE_ABSENT
1755 && JUMP_P (last)
1756 && any_condjump_p (last)
1757 && !find_reg_note (last, REG_BR_PROB, 0))
1758 add_reg_br_prob_note (last,
1759 profile_probability::very_unlikely ());
1760 emit_jump (done_label);
1762 else
1764 delete_insns_since (last);
1765 icode = CODE_FOR_nothing;
1769 if (icode == CODE_FOR_nothing)
1771 struct separate_ops ops;
1772 int prec = GET_MODE_PRECISION (mode);
1773 scalar_int_mode hmode, wmode;
1774 ops.op0 = make_tree (type, op0);
1775 ops.op1 = make_tree (type, op1);
1776 ops.op2 = NULL_TREE;
1777 ops.location = loc;
1779 /* Optimize unsigned overflow check where we don't use the
1780 multiplication result, just whether overflow happened.
1781 If we can do MULT_HIGHPART_EXPR, that followed by
1782 comparison of the result against zero is cheapest.
1783 We'll still compute res, but it should be DCEd later. */
1784 use_operand_p use;
1785 gimple *use_stmt;
1786 if (!is_ubsan
1787 && lhs
1788 && uns
1789 && !(uns0_p && uns1_p && !unsr_p)
1790 && can_mult_highpart_p (mode, uns) == 1
1791 && single_imm_use (lhs, &use, &use_stmt)
1792 && is_gimple_assign (use_stmt)
1793 && gimple_assign_rhs_code (use_stmt) == IMAGPART_EXPR)
1794 goto highpart;
1796 if (GET_MODE_2XWIDER_MODE (mode).exists (&wmode)
1797 && targetm.scalar_mode_supported_p (wmode)
1798 && can_widen_mult_without_libcall (wmode, mode, op0, op1, uns))
1800 twoxwider:
1801 ops.code = WIDEN_MULT_EXPR;
1802 ops.type
1803 = build_nonstandard_integer_type (GET_MODE_PRECISION (wmode), uns);
1805 res = expand_expr_real_2 (&ops, NULL_RTX, wmode, EXPAND_NORMAL);
1806 rtx hipart = expand_shift (RSHIFT_EXPR, wmode, res, prec,
1807 NULL_RTX, uns);
1808 hipart = convert_modes (mode, wmode, hipart, uns);
1809 res = convert_modes (mode, wmode, res, uns);
1810 if (uns)
1811 /* For the unsigned multiplication, there was overflow if
1812 HIPART is non-zero. */
1813 do_compare_rtx_and_jump (hipart, const0_rtx, EQ, true, mode,
1814 NULL_RTX, NULL, done_label,
1815 profile_probability::very_likely ());
1816 else
1818 /* RES is used more than once, place it in a pseudo. */
1819 res = force_reg (mode, res);
1821 rtx signbit = expand_shift (RSHIFT_EXPR, mode, res, prec - 1,
1822 NULL_RTX, 0);
1823 /* RES is low half of the double width result, HIPART
1824 the high half. There was overflow if
1825 HIPART is different from RES < 0 ? -1 : 0. */
1826 do_compare_rtx_and_jump (signbit, hipart, EQ, true, mode,
1827 NULL_RTX, NULL, done_label,
1828 profile_probability::very_likely ());
1831 else if (can_mult_highpart_p (mode, uns) == 1)
1833 highpart:
1834 ops.code = MULT_HIGHPART_EXPR;
1835 ops.type = type;
1837 rtx hipart = expand_expr_real_2 (&ops, NULL_RTX, mode,
1838 EXPAND_NORMAL);
1839 ops.code = MULT_EXPR;
1840 res = expand_expr_real_2 (&ops, NULL_RTX, mode, EXPAND_NORMAL);
1841 if (uns)
1842 /* For the unsigned multiplication, there was overflow if
1843 HIPART is non-zero. */
1844 do_compare_rtx_and_jump (hipart, const0_rtx, EQ, true, mode,
1845 NULL_RTX, NULL, done_label,
1846 profile_probability::very_likely ());
1847 else
1849 rtx signbit = expand_shift (RSHIFT_EXPR, mode, res, prec - 1,
1850 NULL_RTX, 0);
1851 /* RES is low half of the double width result, HIPART
1852 the high half. There was overflow if
1853 HIPART is different from RES < 0 ? -1 : 0. */
1854 do_compare_rtx_and_jump (signbit, hipart, EQ, true, mode,
1855 NULL_RTX, NULL, done_label,
1856 profile_probability::very_likely ());
1860 else if (int_mode_for_size (prec / 2, 1).exists (&hmode)
1861 && 2 * GET_MODE_PRECISION (hmode) == prec)
1863 rtx_code_label *large_op0 = gen_label_rtx ();
1864 rtx_code_label *small_op0_large_op1 = gen_label_rtx ();
1865 rtx_code_label *one_small_one_large = gen_label_rtx ();
1866 rtx_code_label *both_ops_large = gen_label_rtx ();
1867 rtx_code_label *after_hipart_neg = uns ? NULL : gen_label_rtx ();
1868 rtx_code_label *after_lopart_neg = uns ? NULL : gen_label_rtx ();
1869 rtx_code_label *do_overflow = gen_label_rtx ();
1870 rtx_code_label *hipart_different = uns ? NULL : gen_label_rtx ();
1872 unsigned int hprec = GET_MODE_PRECISION (hmode);
1873 rtx hipart0 = expand_shift (RSHIFT_EXPR, mode, op0, hprec,
1874 NULL_RTX, uns);
1875 hipart0 = convert_modes (hmode, mode, hipart0, uns);
1876 rtx lopart0 = convert_modes (hmode, mode, op0, uns);
1877 rtx signbit0 = const0_rtx;
1878 if (!uns)
1879 signbit0 = expand_shift (RSHIFT_EXPR, hmode, lopart0, hprec - 1,
1880 NULL_RTX, 0);
1881 rtx hipart1 = expand_shift (RSHIFT_EXPR, mode, op1, hprec,
1882 NULL_RTX, uns);
1883 hipart1 = convert_modes (hmode, mode, hipart1, uns);
1884 rtx lopart1 = convert_modes (hmode, mode, op1, uns);
1885 rtx signbit1 = const0_rtx;
1886 if (!uns)
1887 signbit1 = expand_shift (RSHIFT_EXPR, hmode, lopart1, hprec - 1,
1888 NULL_RTX, 0);
1890 res = gen_reg_rtx (mode);
1892 /* True if op0 resp. op1 are known to be in the range of
1893 halfstype. */
1894 bool op0_small_p = false;
1895 bool op1_small_p = false;
1896 /* True if op0 resp. op1 are known to have all zeros or all ones
1897 in the upper half of bits, but are not known to be
1898 op{0,1}_small_p. */
1899 bool op0_medium_p = false;
1900 bool op1_medium_p = false;
1901 /* -1 if op{0,1} is known to be negative, 0 if it is known to be
1902 nonnegative, 1 if unknown. */
1903 int op0_sign = 1;
1904 int op1_sign = 1;
1906 if (pos_neg0 == 1)
1907 op0_sign = 0;
1908 else if (pos_neg0 == 2)
1909 op0_sign = -1;
1910 if (pos_neg1 == 1)
1911 op1_sign = 0;
1912 else if (pos_neg1 == 2)
1913 op1_sign = -1;
1915 unsigned int mprec0 = prec;
1916 if (arg0 != error_mark_node)
1917 mprec0 = get_min_precision (arg0, sign);
1918 if (mprec0 <= hprec)
1919 op0_small_p = true;
1920 else if (!uns && mprec0 <= hprec + 1)
1921 op0_medium_p = true;
1922 unsigned int mprec1 = prec;
1923 if (arg1 != error_mark_node)
1924 mprec1 = get_min_precision (arg1, sign);
1925 if (mprec1 <= hprec)
1926 op1_small_p = true;
1927 else if (!uns && mprec1 <= hprec + 1)
1928 op1_medium_p = true;
1930 int smaller_sign = 1;
1931 int larger_sign = 1;
1932 if (op0_small_p)
1934 smaller_sign = op0_sign;
1935 larger_sign = op1_sign;
1937 else if (op1_small_p)
1939 smaller_sign = op1_sign;
1940 larger_sign = op0_sign;
1942 else if (op0_sign == op1_sign)
1944 smaller_sign = op0_sign;
1945 larger_sign = op0_sign;
1948 if (!op0_small_p)
1949 do_compare_rtx_and_jump (signbit0, hipart0, NE, true, hmode,
1950 NULL_RTX, NULL, large_op0,
1951 profile_probability::unlikely ());
1953 if (!op1_small_p)
1954 do_compare_rtx_and_jump (signbit1, hipart1, NE, true, hmode,
1955 NULL_RTX, NULL, small_op0_large_op1,
1956 profile_probability::unlikely ());
1958 /* If both op0 and op1 are sign (!uns) or zero (uns) extended from
1959 hmode to mode, the multiplication will never overflow. We can
1960 do just one hmode x hmode => mode widening multiplication. */
1961 tree halfstype = build_nonstandard_integer_type (hprec, uns);
1962 ops.op0 = make_tree (halfstype, lopart0);
1963 ops.op1 = make_tree (halfstype, lopart1);
1964 ops.code = WIDEN_MULT_EXPR;
1965 ops.type = type;
1966 rtx thisres
1967 = expand_expr_real_2 (&ops, NULL_RTX, mode, EXPAND_NORMAL);
1968 emit_move_insn (res, thisres);
1969 emit_jump (done_label);
1971 emit_label (small_op0_large_op1);
1973 /* If op0 is sign (!uns) or zero (uns) extended from hmode to mode,
1974 but op1 is not, just swap the arguments and handle it as op1
1975 sign/zero extended, op0 not. */
1976 rtx larger = gen_reg_rtx (mode);
1977 rtx hipart = gen_reg_rtx (hmode);
1978 rtx lopart = gen_reg_rtx (hmode);
1979 emit_move_insn (larger, op1);
1980 emit_move_insn (hipart, hipart1);
1981 emit_move_insn (lopart, lopart0);
1982 emit_jump (one_small_one_large);
1984 emit_label (large_op0);
1986 if (!op1_small_p)
1987 do_compare_rtx_and_jump (signbit1, hipart1, NE, true, hmode,
1988 NULL_RTX, NULL, both_ops_large,
1989 profile_probability::unlikely ());
1991 /* If op1 is sign (!uns) or zero (uns) extended from hmode to mode,
1992 but op0 is not, prepare larger, hipart and lopart pseudos and
1993 handle it together with small_op0_large_op1. */
1994 emit_move_insn (larger, op0);
1995 emit_move_insn (hipart, hipart0);
1996 emit_move_insn (lopart, lopart1);
1998 emit_label (one_small_one_large);
2000 /* lopart is the low part of the operand that is sign extended
2001 to mode, larger is the other operand, hipart is the
2002 high part of larger and lopart0 and lopart1 are the low parts
2003 of both operands.
2004 We perform lopart0 * lopart1 and lopart * hipart widening
2005 multiplications. */
2006 tree halfutype = build_nonstandard_integer_type (hprec, 1);
2007 ops.op0 = make_tree (halfutype, lopart0);
2008 ops.op1 = make_tree (halfutype, lopart1);
2009 rtx lo0xlo1
2010 = expand_expr_real_2 (&ops, NULL_RTX, mode, EXPAND_NORMAL);
2012 ops.op0 = make_tree (halfutype, lopart);
2013 ops.op1 = make_tree (halfutype, hipart);
2014 rtx loxhi = gen_reg_rtx (mode);
2015 rtx tem = expand_expr_real_2 (&ops, NULL_RTX, mode, EXPAND_NORMAL);
2016 emit_move_insn (loxhi, tem);
2018 if (!uns)
2020 /* if (hipart < 0) loxhi -= lopart << (bitsize / 2); */
2021 if (larger_sign == 0)
2022 emit_jump (after_hipart_neg);
2023 else if (larger_sign != -1)
2024 do_compare_rtx_and_jump (hipart, const0_rtx, GE, false, hmode,
2025 NULL_RTX, NULL, after_hipart_neg,
2026 profile_probability::even ());
2028 tem = convert_modes (mode, hmode, lopart, 1);
2029 tem = expand_shift (LSHIFT_EXPR, mode, tem, hprec, NULL_RTX, 1);
2030 tem = expand_simple_binop (mode, MINUS, loxhi, tem, NULL_RTX,
2031 1, OPTAB_WIDEN);
2032 emit_move_insn (loxhi, tem);
2034 emit_label (after_hipart_neg);
2036 /* if (lopart < 0) loxhi -= larger; */
2037 if (smaller_sign == 0)
2038 emit_jump (after_lopart_neg);
2039 else if (smaller_sign != -1)
2040 do_compare_rtx_and_jump (lopart, const0_rtx, GE, false, hmode,
2041 NULL_RTX, NULL, after_lopart_neg,
2042 profile_probability::even ());
2044 tem = expand_simple_binop (mode, MINUS, loxhi, larger, NULL_RTX,
2045 1, OPTAB_WIDEN);
2046 emit_move_insn (loxhi, tem);
2048 emit_label (after_lopart_neg);
2051 /* loxhi += (uns) lo0xlo1 >> (bitsize / 2); */
2052 tem = expand_shift (RSHIFT_EXPR, mode, lo0xlo1, hprec, NULL_RTX, 1);
2053 tem = expand_simple_binop (mode, PLUS, loxhi, tem, NULL_RTX,
2054 1, OPTAB_WIDEN);
2055 emit_move_insn (loxhi, tem);
2057 /* if (loxhi >> (bitsize / 2)
2058 == (hmode) loxhi >> (bitsize / 2 - 1)) (if !uns)
2059 if (loxhi >> (bitsize / 2) == 0 (if uns). */
2060 rtx hipartloxhi = expand_shift (RSHIFT_EXPR, mode, loxhi, hprec,
2061 NULL_RTX, 0);
2062 hipartloxhi = convert_modes (hmode, mode, hipartloxhi, 0);
2063 rtx signbitloxhi = const0_rtx;
2064 if (!uns)
2065 signbitloxhi = expand_shift (RSHIFT_EXPR, hmode,
2066 convert_modes (hmode, mode,
2067 loxhi, 0),
2068 hprec - 1, NULL_RTX, 0);
2070 do_compare_rtx_and_jump (signbitloxhi, hipartloxhi, NE, true, hmode,
2071 NULL_RTX, NULL, do_overflow,
2072 profile_probability::very_unlikely ());
2074 /* res = (loxhi << (bitsize / 2)) | (hmode) lo0xlo1; */
2075 rtx loxhishifted = expand_shift (LSHIFT_EXPR, mode, loxhi, hprec,
2076 NULL_RTX, 1);
2077 tem = convert_modes (mode, hmode,
2078 convert_modes (hmode, mode, lo0xlo1, 1), 1);
2080 tem = expand_simple_binop (mode, IOR, loxhishifted, tem, res,
2081 1, OPTAB_WIDEN);
2082 if (tem != res)
2083 emit_move_insn (res, tem);
2084 emit_jump (done_label);
2086 emit_label (both_ops_large);
2088 /* If both operands are large (not sign (!uns) or zero (uns)
2089 extended from hmode), then perform the full multiplication
2090 which will be the result of the operation.
2091 The only cases which don't overflow are for signed multiplication
2092 some cases where both hipart0 and highpart1 are 0 or -1.
2093 For unsigned multiplication when high parts are both non-zero
2094 this overflows always. */
2095 ops.code = MULT_EXPR;
2096 ops.op0 = make_tree (type, op0);
2097 ops.op1 = make_tree (type, op1);
2098 tem = expand_expr_real_2 (&ops, NULL_RTX, mode, EXPAND_NORMAL);
2099 emit_move_insn (res, tem);
2101 if (!uns)
2103 if (!op0_medium_p)
2105 tem = expand_simple_binop (hmode, PLUS, hipart0, const1_rtx,
2106 NULL_RTX, 1, OPTAB_WIDEN);
2107 do_compare_rtx_and_jump (tem, const1_rtx, GTU, true, hmode,
2108 NULL_RTX, NULL, do_error,
2109 profile_probability::very_unlikely ());
2112 if (!op1_medium_p)
2114 tem = expand_simple_binop (hmode, PLUS, hipart1, const1_rtx,
2115 NULL_RTX, 1, OPTAB_WIDEN);
2116 do_compare_rtx_and_jump (tem, const1_rtx, GTU, true, hmode,
2117 NULL_RTX, NULL, do_error,
2118 profile_probability::very_unlikely ());
2121 /* At this point hipart{0,1} are both in [-1, 0]. If they are
2122 the same, overflow happened if res is non-positive, if they
2123 are different, overflow happened if res is positive. */
2124 if (op0_sign != 1 && op1_sign != 1 && op0_sign != op1_sign)
2125 emit_jump (hipart_different);
2126 else if (op0_sign == 1 || op1_sign == 1)
2127 do_compare_rtx_and_jump (hipart0, hipart1, NE, true, hmode,
2128 NULL_RTX, NULL, hipart_different,
2129 profile_probability::even ());
2131 do_compare_rtx_and_jump (res, const0_rtx, LE, false, mode,
2132 NULL_RTX, NULL, do_error,
2133 profile_probability::very_unlikely ());
2134 emit_jump (done_label);
2136 emit_label (hipart_different);
2138 do_compare_rtx_and_jump (res, const0_rtx, GE, false, mode,
2139 NULL_RTX, NULL, do_error,
2140 profile_probability::very_unlikely ());
2141 emit_jump (done_label);
2144 emit_label (do_overflow);
2146 /* Overflow, do full multiplication and fallthru into do_error. */
2147 ops.op0 = make_tree (type, op0);
2148 ops.op1 = make_tree (type, op1);
2149 tem = expand_expr_real_2 (&ops, NULL_RTX, mode, EXPAND_NORMAL);
2150 emit_move_insn (res, tem);
2152 else if (GET_MODE_2XWIDER_MODE (mode).exists (&wmode)
2153 && targetm.scalar_mode_supported_p (wmode))
2154 /* Even emitting a libcall is better than not detecting overflow
2155 at all. */
2156 goto twoxwider;
2157 else
2159 gcc_assert (!is_ubsan);
2160 ops.code = MULT_EXPR;
2161 ops.type = type;
2162 res = expand_expr_real_2 (&ops, NULL_RTX, mode, EXPAND_NORMAL);
2163 emit_jump (done_label);
2167 do_error_label:
2168 emit_label (do_error);
2169 if (is_ubsan)
2171 /* Expand the ubsan builtin call. */
2172 push_temp_slots ();
2173 fn = ubsan_build_overflow_builtin (MULT_EXPR, loc, TREE_TYPE (arg0),
2174 arg0, arg1, datap);
2175 expand_normal (fn);
2176 pop_temp_slots ();
2177 do_pending_stack_adjust ();
2179 else if (lhs)
2180 expand_arith_set_overflow (lhs, target);
2182 /* We're done. */
2183 emit_label (done_label);
2185 /* u1 * u2 -> sr */
2186 if (uns0_p && uns1_p && !unsr_p)
2188 rtx_code_label *all_done_label = gen_label_rtx ();
2189 do_compare_rtx_and_jump (res, const0_rtx, GE, false, mode, NULL_RTX,
2190 NULL, all_done_label, profile_probability::very_likely ());
2191 expand_arith_set_overflow (lhs, target);
2192 emit_label (all_done_label);
2195 /* s1 * u2 -> sr */
2196 if (!uns0_p && uns1_p && !unsr_p && pos_neg1 == 3)
2198 rtx_code_label *all_done_label = gen_label_rtx ();
2199 rtx_code_label *set_noovf = gen_label_rtx ();
2200 do_compare_rtx_and_jump (op1, const0_rtx, GE, false, mode, NULL_RTX,
2201 NULL, all_done_label, profile_probability::very_likely ());
2202 expand_arith_set_overflow (lhs, target);
2203 do_compare_rtx_and_jump (op0, const0_rtx, EQ, true, mode, NULL_RTX,
2204 NULL, set_noovf, profile_probability::very_likely ());
2205 do_compare_rtx_and_jump (op0, constm1_rtx, NE, true, mode, NULL_RTX,
2206 NULL, all_done_label, profile_probability::very_unlikely ());
2207 do_compare_rtx_and_jump (op1, res, NE, true, mode, NULL_RTX, NULL,
2208 all_done_label, profile_probability::very_unlikely ());
2209 emit_label (set_noovf);
2210 write_complex_part (target, const0_rtx, true);
2211 emit_label (all_done_label);
2214 if (lhs)
2216 if (is_ubsan)
2217 expand_ubsan_result_store (target, res);
2218 else
2219 expand_arith_overflow_result_store (lhs, target, mode, res);
2223 /* Expand UBSAN_CHECK_* internal function if it has vector operands. */
2225 static void
2226 expand_vector_ubsan_overflow (location_t loc, enum tree_code code, tree lhs,
2227 tree arg0, tree arg1)
2229 poly_uint64 cnt = TYPE_VECTOR_SUBPARTS (TREE_TYPE (arg0));
2230 rtx_code_label *loop_lab = NULL;
2231 rtx cntvar = NULL_RTX;
2232 tree cntv = NULL_TREE;
2233 tree eltype = TREE_TYPE (TREE_TYPE (arg0));
2234 tree sz = TYPE_SIZE (eltype);
2235 tree data = NULL_TREE;
2236 tree resv = NULL_TREE;
2237 rtx lhsr = NULL_RTX;
2238 rtx resvr = NULL_RTX;
2239 unsigned HOST_WIDE_INT const_cnt = 0;
2240 bool use_loop_p = (!cnt.is_constant (&const_cnt) || const_cnt > 4);
2242 if (lhs)
2244 optab op;
2245 lhsr = expand_expr (lhs, NULL_RTX, VOIDmode, EXPAND_WRITE);
2246 if (!VECTOR_MODE_P (GET_MODE (lhsr))
2247 || (op = optab_for_tree_code (code, TREE_TYPE (arg0),
2248 optab_default)) == unknown_optab
2249 || (optab_handler (op, TYPE_MODE (TREE_TYPE (arg0)))
2250 == CODE_FOR_nothing))
2252 if (MEM_P (lhsr))
2253 resv = make_tree (TREE_TYPE (lhs), lhsr);
2254 else
2256 resvr = assign_temp (TREE_TYPE (lhs), 1, 1);
2257 resv = make_tree (TREE_TYPE (lhs), resvr);
2261 if (use_loop_p)
2263 do_pending_stack_adjust ();
2264 loop_lab = gen_label_rtx ();
2265 cntvar = gen_reg_rtx (TYPE_MODE (sizetype));
2266 cntv = make_tree (sizetype, cntvar);
2267 emit_move_insn (cntvar, const0_rtx);
2268 emit_label (loop_lab);
2270 if (TREE_CODE (arg0) != VECTOR_CST)
2272 rtx arg0r = expand_normal (arg0);
2273 arg0 = make_tree (TREE_TYPE (arg0), arg0r);
2275 if (TREE_CODE (arg1) != VECTOR_CST)
2277 rtx arg1r = expand_normal (arg1);
2278 arg1 = make_tree (TREE_TYPE (arg1), arg1r);
2280 for (unsigned int i = 0; i < (use_loop_p ? 1 : const_cnt); i++)
2282 tree op0, op1, res = NULL_TREE;
2283 if (use_loop_p)
2285 tree atype = build_array_type_nelts (eltype, cnt);
2286 op0 = uniform_vector_p (arg0);
2287 if (op0 == NULL_TREE)
2289 op0 = fold_build1_loc (loc, VIEW_CONVERT_EXPR, atype, arg0);
2290 op0 = build4_loc (loc, ARRAY_REF, eltype, op0, cntv,
2291 NULL_TREE, NULL_TREE);
2293 op1 = uniform_vector_p (arg1);
2294 if (op1 == NULL_TREE)
2296 op1 = fold_build1_loc (loc, VIEW_CONVERT_EXPR, atype, arg1);
2297 op1 = build4_loc (loc, ARRAY_REF, eltype, op1, cntv,
2298 NULL_TREE, NULL_TREE);
2300 if (resv)
2302 res = fold_build1_loc (loc, VIEW_CONVERT_EXPR, atype, resv);
2303 res = build4_loc (loc, ARRAY_REF, eltype, res, cntv,
2304 NULL_TREE, NULL_TREE);
2307 else
2309 tree bitpos = bitsize_int (tree_to_uhwi (sz) * i);
2310 op0 = fold_build3_loc (loc, BIT_FIELD_REF, eltype, arg0, sz, bitpos);
2311 op1 = fold_build3_loc (loc, BIT_FIELD_REF, eltype, arg1, sz, bitpos);
2312 if (resv)
2313 res = fold_build3_loc (loc, BIT_FIELD_REF, eltype, resv, sz,
2314 bitpos);
2316 switch (code)
2318 case PLUS_EXPR:
2319 expand_addsub_overflow (loc, PLUS_EXPR, res, op0, op1,
2320 false, false, false, true, &data);
2321 break;
2322 case MINUS_EXPR:
2323 if (use_loop_p ? integer_zerop (arg0) : integer_zerop (op0))
2324 expand_neg_overflow (loc, res, op1, true, &data);
2325 else
2326 expand_addsub_overflow (loc, MINUS_EXPR, res, op0, op1,
2327 false, false, false, true, &data);
2328 break;
2329 case MULT_EXPR:
2330 expand_mul_overflow (loc, res, op0, op1, false, false, false,
2331 true, &data);
2332 break;
2333 default:
2334 gcc_unreachable ();
2337 if (use_loop_p)
2339 struct separate_ops ops;
2340 ops.code = PLUS_EXPR;
2341 ops.type = TREE_TYPE (cntv);
2342 ops.op0 = cntv;
2343 ops.op1 = build_int_cst (TREE_TYPE (cntv), 1);
2344 ops.op2 = NULL_TREE;
2345 ops.location = loc;
2346 rtx ret = expand_expr_real_2 (&ops, cntvar, TYPE_MODE (sizetype),
2347 EXPAND_NORMAL);
2348 if (ret != cntvar)
2349 emit_move_insn (cntvar, ret);
2350 rtx cntrtx = gen_int_mode (cnt, TYPE_MODE (sizetype));
2351 do_compare_rtx_and_jump (cntvar, cntrtx, NE, false,
2352 TYPE_MODE (sizetype), NULL_RTX, NULL, loop_lab,
2353 profile_probability::very_likely ());
2355 if (lhs && resv == NULL_TREE)
2357 struct separate_ops ops;
2358 ops.code = code;
2359 ops.type = TREE_TYPE (arg0);
2360 ops.op0 = arg0;
2361 ops.op1 = arg1;
2362 ops.op2 = NULL_TREE;
2363 ops.location = loc;
2364 rtx ret = expand_expr_real_2 (&ops, lhsr, TYPE_MODE (TREE_TYPE (arg0)),
2365 EXPAND_NORMAL);
2366 if (ret != lhsr)
2367 emit_move_insn (lhsr, ret);
2369 else if (resvr)
2370 emit_move_insn (lhsr, resvr);
2373 /* Expand UBSAN_CHECK_ADD call STMT. */
2375 static void
2376 expand_UBSAN_CHECK_ADD (internal_fn, gcall *stmt)
2378 location_t loc = gimple_location (stmt);
2379 tree lhs = gimple_call_lhs (stmt);
2380 tree arg0 = gimple_call_arg (stmt, 0);
2381 tree arg1 = gimple_call_arg (stmt, 1);
2382 if (VECTOR_TYPE_P (TREE_TYPE (arg0)))
2383 expand_vector_ubsan_overflow (loc, PLUS_EXPR, lhs, arg0, arg1);
2384 else
2385 expand_addsub_overflow (loc, PLUS_EXPR, lhs, arg0, arg1,
2386 false, false, false, true, NULL);
2389 /* Expand UBSAN_CHECK_SUB call STMT. */
2391 static void
2392 expand_UBSAN_CHECK_SUB (internal_fn, gcall *stmt)
2394 location_t loc = gimple_location (stmt);
2395 tree lhs = gimple_call_lhs (stmt);
2396 tree arg0 = gimple_call_arg (stmt, 0);
2397 tree arg1 = gimple_call_arg (stmt, 1);
2398 if (VECTOR_TYPE_P (TREE_TYPE (arg0)))
2399 expand_vector_ubsan_overflow (loc, MINUS_EXPR, lhs, arg0, arg1);
2400 else if (integer_zerop (arg0))
2401 expand_neg_overflow (loc, lhs, arg1, true, NULL);
2402 else
2403 expand_addsub_overflow (loc, MINUS_EXPR, lhs, arg0, arg1,
2404 false, false, false, true, NULL);
2407 /* Expand UBSAN_CHECK_MUL call STMT. */
2409 static void
2410 expand_UBSAN_CHECK_MUL (internal_fn, gcall *stmt)
2412 location_t loc = gimple_location (stmt);
2413 tree lhs = gimple_call_lhs (stmt);
2414 tree arg0 = gimple_call_arg (stmt, 0);
2415 tree arg1 = gimple_call_arg (stmt, 1);
2416 if (VECTOR_TYPE_P (TREE_TYPE (arg0)))
2417 expand_vector_ubsan_overflow (loc, MULT_EXPR, lhs, arg0, arg1);
2418 else
2419 expand_mul_overflow (loc, lhs, arg0, arg1, false, false, false, true,
2420 NULL);
2423 /* Helper function for {ADD,SUB,MUL}_OVERFLOW call stmt expansion. */
2425 static void
2426 expand_arith_overflow (enum tree_code code, gimple *stmt)
2428 tree lhs = gimple_call_lhs (stmt);
2429 if (lhs == NULL_TREE)
2430 return;
2431 tree arg0 = gimple_call_arg (stmt, 0);
2432 tree arg1 = gimple_call_arg (stmt, 1);
2433 tree type = TREE_TYPE (TREE_TYPE (lhs));
2434 int uns0_p = TYPE_UNSIGNED (TREE_TYPE (arg0));
2435 int uns1_p = TYPE_UNSIGNED (TREE_TYPE (arg1));
2436 int unsr_p = TYPE_UNSIGNED (type);
2437 int prec0 = TYPE_PRECISION (TREE_TYPE (arg0));
2438 int prec1 = TYPE_PRECISION (TREE_TYPE (arg1));
2439 int precres = TYPE_PRECISION (type);
2440 location_t loc = gimple_location (stmt);
2441 if (!uns0_p && get_range_pos_neg (arg0) == 1)
2442 uns0_p = true;
2443 if (!uns1_p && get_range_pos_neg (arg1) == 1)
2444 uns1_p = true;
2445 int pr = get_min_precision (arg0, uns0_p ? UNSIGNED : SIGNED);
2446 prec0 = MIN (prec0, pr);
2447 pr = get_min_precision (arg1, uns1_p ? UNSIGNED : SIGNED);
2448 prec1 = MIN (prec1, pr);
2450 /* If uns0_p && uns1_p, precop is minimum needed precision
2451 of unsigned type to hold the exact result, otherwise
2452 precop is minimum needed precision of signed type to
2453 hold the exact result. */
2454 int precop;
2455 if (code == MULT_EXPR)
2456 precop = prec0 + prec1 + (uns0_p != uns1_p);
2457 else
2459 if (uns0_p == uns1_p)
2460 precop = MAX (prec0, prec1) + 1;
2461 else if (uns0_p)
2462 precop = MAX (prec0 + 1, prec1) + 1;
2463 else
2464 precop = MAX (prec0, prec1 + 1) + 1;
2466 int orig_precres = precres;
2470 if ((uns0_p && uns1_p)
2471 ? ((precop + !unsr_p) <= precres
2472 /* u1 - u2 -> ur can overflow, no matter what precision
2473 the result has. */
2474 && (code != MINUS_EXPR || !unsr_p))
2475 : (!unsr_p && precop <= precres))
2477 /* The infinity precision result will always fit into result. */
2478 rtx target = expand_expr (lhs, NULL_RTX, VOIDmode, EXPAND_WRITE);
2479 write_complex_part (target, const0_rtx, true);
2480 scalar_int_mode mode = SCALAR_INT_TYPE_MODE (type);
2481 struct separate_ops ops;
2482 ops.code = code;
2483 ops.type = type;
2484 ops.op0 = fold_convert_loc (loc, type, arg0);
2485 ops.op1 = fold_convert_loc (loc, type, arg1);
2486 ops.op2 = NULL_TREE;
2487 ops.location = loc;
2488 rtx tem = expand_expr_real_2 (&ops, NULL_RTX, mode, EXPAND_NORMAL);
2489 expand_arith_overflow_result_store (lhs, target, mode, tem);
2490 return;
2493 /* For operations with low precision, if target doesn't have them, start
2494 with precres widening right away, otherwise do it only if the most
2495 simple cases can't be used. */
2496 const int min_precision = targetm.min_arithmetic_precision ();
2497 if (orig_precres == precres && precres < min_precision)
2499 else if ((uns0_p && uns1_p && unsr_p && prec0 <= precres
2500 && prec1 <= precres)
2501 || ((!uns0_p || !uns1_p) && !unsr_p
2502 && prec0 + uns0_p <= precres
2503 && prec1 + uns1_p <= precres))
2505 arg0 = fold_convert_loc (loc, type, arg0);
2506 arg1 = fold_convert_loc (loc, type, arg1);
2507 switch (code)
2509 case MINUS_EXPR:
2510 if (integer_zerop (arg0) && !unsr_p)
2512 expand_neg_overflow (loc, lhs, arg1, false, NULL);
2513 return;
2515 /* FALLTHRU */
2516 case PLUS_EXPR:
2517 expand_addsub_overflow (loc, code, lhs, arg0, arg1, unsr_p,
2518 unsr_p, unsr_p, false, NULL);
2519 return;
2520 case MULT_EXPR:
2521 expand_mul_overflow (loc, lhs, arg0, arg1, unsr_p,
2522 unsr_p, unsr_p, false, NULL);
2523 return;
2524 default:
2525 gcc_unreachable ();
2529 /* For sub-word operations, retry with a wider type first. */
2530 if (orig_precres == precres && precop <= BITS_PER_WORD)
2532 int p = MAX (min_precision, precop);
2533 scalar_int_mode m = smallest_int_mode_for_size (p);
2534 tree optype = build_nonstandard_integer_type (GET_MODE_PRECISION (m),
2535 uns0_p && uns1_p
2536 && unsr_p);
2537 p = TYPE_PRECISION (optype);
2538 if (p > precres)
2540 precres = p;
2541 unsr_p = TYPE_UNSIGNED (optype);
2542 type = optype;
2543 continue;
2547 if (prec0 <= precres && prec1 <= precres)
2549 tree types[2];
2550 if (unsr_p)
2552 types[0] = build_nonstandard_integer_type (precres, 0);
2553 types[1] = type;
2555 else
2557 types[0] = type;
2558 types[1] = build_nonstandard_integer_type (precres, 1);
2560 arg0 = fold_convert_loc (loc, types[uns0_p], arg0);
2561 arg1 = fold_convert_loc (loc, types[uns1_p], arg1);
2562 if (code != MULT_EXPR)
2563 expand_addsub_overflow (loc, code, lhs, arg0, arg1, unsr_p,
2564 uns0_p, uns1_p, false, NULL);
2565 else
2566 expand_mul_overflow (loc, lhs, arg0, arg1, unsr_p,
2567 uns0_p, uns1_p, false, NULL);
2568 return;
2571 /* Retry with a wider type. */
2572 if (orig_precres == precres)
2574 int p = MAX (prec0, prec1);
2575 scalar_int_mode m = smallest_int_mode_for_size (p);
2576 tree optype = build_nonstandard_integer_type (GET_MODE_PRECISION (m),
2577 uns0_p && uns1_p
2578 && unsr_p);
2579 p = TYPE_PRECISION (optype);
2580 if (p > precres)
2582 precres = p;
2583 unsr_p = TYPE_UNSIGNED (optype);
2584 type = optype;
2585 continue;
2589 gcc_unreachable ();
2591 while (1);
2594 /* Expand ADD_OVERFLOW STMT. */
2596 static void
2597 expand_ADD_OVERFLOW (internal_fn, gcall *stmt)
2599 expand_arith_overflow (PLUS_EXPR, stmt);
2602 /* Expand SUB_OVERFLOW STMT. */
2604 static void
2605 expand_SUB_OVERFLOW (internal_fn, gcall *stmt)
2607 expand_arith_overflow (MINUS_EXPR, stmt);
2610 /* Expand MUL_OVERFLOW STMT. */
2612 static void
2613 expand_MUL_OVERFLOW (internal_fn, gcall *stmt)
2615 expand_arith_overflow (MULT_EXPR, stmt);
2618 /* This should get folded in tree-vectorizer.c. */
2620 static void
2621 expand_LOOP_VECTORIZED (internal_fn, gcall *)
2623 gcc_unreachable ();
2626 /* This should get folded in tree-vectorizer.c. */
2628 static void
2629 expand_LOOP_DIST_ALIAS (internal_fn, gcall *)
2631 gcc_unreachable ();
2634 /* Return a memory reference of type TYPE for argument INDEX of STMT.
2635 Use argument INDEX + 1 to derive the second (TBAA) operand. */
2637 static tree
2638 expand_call_mem_ref (tree type, gcall *stmt, int index)
2640 tree addr = gimple_call_arg (stmt, index);
2641 tree alias_ptr_type = TREE_TYPE (gimple_call_arg (stmt, index + 1));
2642 unsigned int align = tree_to_shwi (gimple_call_arg (stmt, index + 1));
2643 if (TYPE_ALIGN (type) != align)
2644 type = build_aligned_type (type, align);
2646 tree tmp = addr;
2647 if (TREE_CODE (tmp) == SSA_NAME)
2649 gimple *def = SSA_NAME_DEF_STMT (tmp);
2650 if (gimple_assign_single_p (def))
2651 tmp = gimple_assign_rhs1 (def);
2654 if (TREE_CODE (tmp) == ADDR_EXPR)
2656 tree mem = TREE_OPERAND (tmp, 0);
2657 if (TREE_CODE (mem) == TARGET_MEM_REF
2658 && types_compatible_p (TREE_TYPE (mem), type))
2660 tree offset = TMR_OFFSET (mem);
2661 if (type != TREE_TYPE (mem)
2662 || alias_ptr_type != TREE_TYPE (offset)
2663 || !integer_zerop (offset))
2665 mem = copy_node (mem);
2666 TMR_OFFSET (mem) = wide_int_to_tree (alias_ptr_type,
2667 wi::to_poly_wide (offset));
2668 TREE_TYPE (mem) = type;
2670 return mem;
2674 return fold_build2 (MEM_REF, type, addr, build_int_cst (alias_ptr_type, 0));
2677 /* Expand MASK_LOAD{,_LANES} or LEN_LOAD call STMT using optab OPTAB. */
2679 static void
2680 expand_partial_load_optab_fn (internal_fn, gcall *stmt, convert_optab optab)
2682 class expand_operand ops[3];
2683 tree type, lhs, rhs, maskt;
2684 rtx mem, target, mask;
2685 insn_code icode;
2687 maskt = gimple_call_arg (stmt, 2);
2688 lhs = gimple_call_lhs (stmt);
2689 if (lhs == NULL_TREE)
2690 return;
2691 type = TREE_TYPE (lhs);
2692 rhs = expand_call_mem_ref (type, stmt, 0);
2694 if (optab == vec_mask_load_lanes_optab)
2695 icode = get_multi_vector_move (type, optab);
2696 else if (optab == len_load_optab)
2697 icode = direct_optab_handler (optab, TYPE_MODE (type));
2698 else
2699 icode = convert_optab_handler (optab, TYPE_MODE (type),
2700 TYPE_MODE (TREE_TYPE (maskt)));
2702 mem = expand_expr (rhs, NULL_RTX, VOIDmode, EXPAND_WRITE);
2703 gcc_assert (MEM_P (mem));
2704 mask = expand_normal (maskt);
2705 target = expand_expr (lhs, NULL_RTX, VOIDmode, EXPAND_WRITE);
2706 create_output_operand (&ops[0], target, TYPE_MODE (type));
2707 create_fixed_operand (&ops[1], mem);
2708 if (optab == len_load_optab)
2709 create_convert_operand_from (&ops[2], mask, TYPE_MODE (TREE_TYPE (maskt)),
2710 TYPE_UNSIGNED (TREE_TYPE (maskt)));
2711 else
2712 create_input_operand (&ops[2], mask, TYPE_MODE (TREE_TYPE (maskt)));
2713 expand_insn (icode, 3, ops);
2714 if (!rtx_equal_p (target, ops[0].value))
2715 emit_move_insn (target, ops[0].value);
2718 #define expand_mask_load_optab_fn expand_partial_load_optab_fn
2719 #define expand_mask_load_lanes_optab_fn expand_mask_load_optab_fn
2720 #define expand_len_load_optab_fn expand_partial_load_optab_fn
2722 /* Expand MASK_STORE{,_LANES} or LEN_STORE call STMT using optab OPTAB. */
2724 static void
2725 expand_partial_store_optab_fn (internal_fn, gcall *stmt, convert_optab optab)
2727 class expand_operand ops[3];
2728 tree type, lhs, rhs, maskt;
2729 rtx mem, reg, mask;
2730 insn_code icode;
2732 maskt = gimple_call_arg (stmt, 2);
2733 rhs = gimple_call_arg (stmt, 3);
2734 type = TREE_TYPE (rhs);
2735 lhs = expand_call_mem_ref (type, stmt, 0);
2737 if (optab == vec_mask_store_lanes_optab)
2738 icode = get_multi_vector_move (type, optab);
2739 else if (optab == len_store_optab)
2740 icode = direct_optab_handler (optab, TYPE_MODE (type));
2741 else
2742 icode = convert_optab_handler (optab, TYPE_MODE (type),
2743 TYPE_MODE (TREE_TYPE (maskt)));
2745 mem = expand_expr (lhs, NULL_RTX, VOIDmode, EXPAND_WRITE);
2746 gcc_assert (MEM_P (mem));
2747 mask = expand_normal (maskt);
2748 reg = expand_normal (rhs);
2749 create_fixed_operand (&ops[0], mem);
2750 create_input_operand (&ops[1], reg, TYPE_MODE (type));
2751 if (optab == len_store_optab)
2752 create_convert_operand_from (&ops[2], mask, TYPE_MODE (TREE_TYPE (maskt)),
2753 TYPE_UNSIGNED (TREE_TYPE (maskt)));
2754 else
2755 create_input_operand (&ops[2], mask, TYPE_MODE (TREE_TYPE (maskt)));
2756 expand_insn (icode, 3, ops);
2759 #define expand_mask_store_optab_fn expand_partial_store_optab_fn
2760 #define expand_mask_store_lanes_optab_fn expand_mask_store_optab_fn
2761 #define expand_len_store_optab_fn expand_partial_store_optab_fn
2763 /* Expand VCOND, VCONDU and VCONDEQ optab internal functions.
2764 The expansion of STMT happens based on OPTAB table associated. */
2766 static void
2767 expand_vec_cond_optab_fn (internal_fn, gcall *stmt, convert_optab optab)
2769 class expand_operand ops[6];
2770 insn_code icode;
2771 tree lhs = gimple_call_lhs (stmt);
2772 tree op0a = gimple_call_arg (stmt, 0);
2773 tree op0b = gimple_call_arg (stmt, 1);
2774 tree op1 = gimple_call_arg (stmt, 2);
2775 tree op2 = gimple_call_arg (stmt, 3);
2776 enum tree_code tcode = (tree_code) int_cst_value (gimple_call_arg (stmt, 4));
2778 tree vec_cond_type = TREE_TYPE (lhs);
2779 tree op_mode = TREE_TYPE (op0a);
2780 bool unsignedp = TYPE_UNSIGNED (op_mode);
2782 machine_mode mode = TYPE_MODE (vec_cond_type);
2783 machine_mode cmp_op_mode = TYPE_MODE (op_mode);
2785 icode = convert_optab_handler (optab, mode, cmp_op_mode);
2786 rtx comparison
2787 = vector_compare_rtx (VOIDmode, tcode, op0a, op0b, unsignedp, icode, 4);
2788 rtx rtx_op1 = expand_normal (op1);
2789 rtx rtx_op2 = expand_normal (op2);
2791 rtx target = expand_expr (lhs, NULL_RTX, VOIDmode, EXPAND_WRITE);
2792 create_output_operand (&ops[0], target, mode);
2793 create_input_operand (&ops[1], rtx_op1, mode);
2794 create_input_operand (&ops[2], rtx_op2, mode);
2795 create_fixed_operand (&ops[3], comparison);
2796 create_fixed_operand (&ops[4], XEXP (comparison, 0));
2797 create_fixed_operand (&ops[5], XEXP (comparison, 1));
2798 expand_insn (icode, 6, ops);
2799 if (!rtx_equal_p (ops[0].value, target))
2800 emit_move_insn (target, ops[0].value);
2803 /* Expand VCOND_MASK optab internal function.
2804 The expansion of STMT happens based on OPTAB table associated. */
2806 static void
2807 expand_vec_cond_mask_optab_fn (internal_fn, gcall *stmt, convert_optab optab)
2809 class expand_operand ops[4];
2811 tree lhs = gimple_call_lhs (stmt);
2812 tree op0 = gimple_call_arg (stmt, 0);
2813 tree op1 = gimple_call_arg (stmt, 1);
2814 tree op2 = gimple_call_arg (stmt, 2);
2815 tree vec_cond_type = TREE_TYPE (lhs);
2817 machine_mode mode = TYPE_MODE (vec_cond_type);
2818 machine_mode mask_mode = TYPE_MODE (TREE_TYPE (op0));
2819 enum insn_code icode = convert_optab_handler (optab, mode, mask_mode);
2820 rtx mask, rtx_op1, rtx_op2;
2822 gcc_assert (icode != CODE_FOR_nothing);
2824 mask = expand_normal (op0);
2825 rtx_op1 = expand_normal (op1);
2826 rtx_op2 = expand_normal (op2);
2828 mask = force_reg (mask_mode, mask);
2829 rtx_op1 = force_reg (mode, rtx_op1);
2831 rtx target = expand_expr (lhs, NULL_RTX, VOIDmode, EXPAND_WRITE);
2832 create_output_operand (&ops[0], target, mode);
2833 create_input_operand (&ops[1], rtx_op1, mode);
2834 create_input_operand (&ops[2], rtx_op2, mode);
2835 create_input_operand (&ops[3], mask, mask_mode);
2836 expand_insn (icode, 4, ops);
2837 if (!rtx_equal_p (ops[0].value, target))
2838 emit_move_insn (target, ops[0].value);
2841 /* Expand VEC_SET internal functions. */
2843 static void
2844 expand_vec_set_optab_fn (internal_fn, gcall *stmt, convert_optab optab)
2846 tree lhs = gimple_call_lhs (stmt);
2847 tree op0 = gimple_call_arg (stmt, 0);
2848 tree op1 = gimple_call_arg (stmt, 1);
2849 tree op2 = gimple_call_arg (stmt, 2);
2850 rtx target = expand_expr (lhs, NULL_RTX, VOIDmode, EXPAND_WRITE);
2851 rtx src = expand_normal (op0);
2853 machine_mode outermode = TYPE_MODE (TREE_TYPE (op0));
2854 scalar_mode innermode = GET_MODE_INNER (outermode);
2856 rtx value = expand_normal (op1);
2857 rtx pos = expand_normal (op2);
2859 class expand_operand ops[3];
2860 enum insn_code icode = optab_handler (optab, outermode);
2862 if (icode != CODE_FOR_nothing)
2864 rtx temp = gen_reg_rtx (outermode);
2865 emit_move_insn (temp, src);
2867 create_fixed_operand (&ops[0], temp);
2868 create_input_operand (&ops[1], value, innermode);
2869 create_convert_operand_from (&ops[2], pos, TYPE_MODE (TREE_TYPE (op2)),
2870 true);
2871 if (maybe_expand_insn (icode, 3, ops))
2873 emit_move_insn (target, temp);
2874 return;
2877 gcc_unreachable ();
2880 static void
2881 expand_ABNORMAL_DISPATCHER (internal_fn, gcall *)
2885 static void
2886 expand_BUILTIN_EXPECT (internal_fn, gcall *stmt)
2888 /* When guessing was done, the hints should be already stripped away. */
2889 gcc_assert (!flag_guess_branch_prob || optimize == 0 || seen_error ());
2891 rtx target;
2892 tree lhs = gimple_call_lhs (stmt);
2893 if (lhs)
2894 target = expand_expr (lhs, NULL_RTX, VOIDmode, EXPAND_WRITE);
2895 else
2896 target = const0_rtx;
2897 rtx val = expand_expr (gimple_call_arg (stmt, 0), target, VOIDmode, EXPAND_NORMAL);
2898 if (lhs && val != target)
2899 emit_move_insn (target, val);
2902 /* IFN_VA_ARG is supposed to be expanded at pass_stdarg. So this dummy function
2903 should never be called. */
2905 static void
2906 expand_VA_ARG (internal_fn, gcall *)
2908 gcc_unreachable ();
2911 /* IFN_VEC_CONVERT is supposed to be expanded at pass_lower_vector. So this
2912 dummy function should never be called. */
2914 static void
2915 expand_VEC_CONVERT (internal_fn, gcall *)
2917 gcc_unreachable ();
2920 /* Expand the IFN_UNIQUE function according to its first argument. */
2922 static void
2923 expand_UNIQUE (internal_fn, gcall *stmt)
2925 rtx pattern = NULL_RTX;
2926 enum ifn_unique_kind kind
2927 = (enum ifn_unique_kind) TREE_INT_CST_LOW (gimple_call_arg (stmt, 0));
2929 switch (kind)
2931 default:
2932 gcc_unreachable ();
2934 case IFN_UNIQUE_UNSPEC:
2935 if (targetm.have_unique ())
2936 pattern = targetm.gen_unique ();
2937 break;
2939 case IFN_UNIQUE_OACC_FORK:
2940 case IFN_UNIQUE_OACC_JOIN:
2941 if (targetm.have_oacc_fork () && targetm.have_oacc_join ())
2943 tree lhs = gimple_call_lhs (stmt);
2944 rtx target = const0_rtx;
2946 if (lhs)
2947 target = expand_expr (lhs, NULL_RTX, VOIDmode, EXPAND_WRITE);
2949 rtx data_dep = expand_normal (gimple_call_arg (stmt, 1));
2950 rtx axis = expand_normal (gimple_call_arg (stmt, 2));
2952 if (kind == IFN_UNIQUE_OACC_FORK)
2953 pattern = targetm.gen_oacc_fork (target, data_dep, axis);
2954 else
2955 pattern = targetm.gen_oacc_join (target, data_dep, axis);
2957 else
2958 gcc_unreachable ();
2959 break;
2962 if (pattern)
2963 emit_insn (pattern);
2966 /* The size of an OpenACC compute dimension. */
2968 static void
2969 expand_GOACC_DIM_SIZE (internal_fn, gcall *stmt)
2971 tree lhs = gimple_call_lhs (stmt);
2973 if (!lhs)
2974 return;
2976 rtx target = expand_expr (lhs, NULL_RTX, VOIDmode, EXPAND_WRITE);
2977 if (targetm.have_oacc_dim_size ())
2979 rtx dim = expand_expr (gimple_call_arg (stmt, 0), NULL_RTX,
2980 VOIDmode, EXPAND_NORMAL);
2981 emit_insn (targetm.gen_oacc_dim_size (target, dim));
2983 else
2984 emit_move_insn (target, GEN_INT (1));
2987 /* The position of an OpenACC execution engine along one compute axis. */
2989 static void
2990 expand_GOACC_DIM_POS (internal_fn, gcall *stmt)
2992 tree lhs = gimple_call_lhs (stmt);
2994 if (!lhs)
2995 return;
2997 rtx target = expand_expr (lhs, NULL_RTX, VOIDmode, EXPAND_WRITE);
2998 if (targetm.have_oacc_dim_pos ())
3000 rtx dim = expand_expr (gimple_call_arg (stmt, 0), NULL_RTX,
3001 VOIDmode, EXPAND_NORMAL);
3002 emit_insn (targetm.gen_oacc_dim_pos (target, dim));
3004 else
3005 emit_move_insn (target, const0_rtx);
3008 /* This is expanded by oacc_device_lower pass. */
3010 static void
3011 expand_GOACC_LOOP (internal_fn, gcall *)
3013 gcc_unreachable ();
3016 /* This is expanded by oacc_device_lower pass. */
3018 static void
3019 expand_GOACC_REDUCTION (internal_fn, gcall *)
3021 gcc_unreachable ();
3024 /* This is expanded by oacc_device_lower pass. */
3026 static void
3027 expand_GOACC_TILE (internal_fn, gcall *)
3029 gcc_unreachable ();
3032 /* Set errno to EDOM. */
3034 static void
3035 expand_SET_EDOM (internal_fn, gcall *)
3037 #ifdef TARGET_EDOM
3038 #ifdef GEN_ERRNO_RTX
3039 rtx errno_rtx = GEN_ERRNO_RTX;
3040 #else
3041 rtx errno_rtx = gen_rtx_MEM (word_mode, gen_rtx_SYMBOL_REF (Pmode, "errno"));
3042 #endif
3043 emit_move_insn (errno_rtx,
3044 gen_int_mode (TARGET_EDOM, GET_MODE (errno_rtx)));
3045 #else
3046 gcc_unreachable ();
3047 #endif
3050 /* Expand atomic bit test and set. */
3052 static void
3053 expand_ATOMIC_BIT_TEST_AND_SET (internal_fn, gcall *call)
3055 expand_ifn_atomic_bit_test_and (call);
3058 /* Expand atomic bit test and complement. */
3060 static void
3061 expand_ATOMIC_BIT_TEST_AND_COMPLEMENT (internal_fn, gcall *call)
3063 expand_ifn_atomic_bit_test_and (call);
3066 /* Expand atomic bit test and reset. */
3068 static void
3069 expand_ATOMIC_BIT_TEST_AND_RESET (internal_fn, gcall *call)
3071 expand_ifn_atomic_bit_test_and (call);
3074 /* Expand atomic bit test and set. */
3076 static void
3077 expand_ATOMIC_COMPARE_EXCHANGE (internal_fn, gcall *call)
3079 expand_ifn_atomic_compare_exchange (call);
3082 /* Expand LAUNDER to assignment, lhs = arg0. */
3084 static void
3085 expand_LAUNDER (internal_fn, gcall *call)
3087 tree lhs = gimple_call_lhs (call);
3089 if (!lhs)
3090 return;
3092 expand_assignment (lhs, gimple_call_arg (call, 0), false);
3095 /* Expand {MASK_,}SCATTER_STORE{S,U} call CALL using optab OPTAB. */
3097 static void
3098 expand_scatter_store_optab_fn (internal_fn, gcall *stmt, direct_optab optab)
3100 internal_fn ifn = gimple_call_internal_fn (stmt);
3101 int rhs_index = internal_fn_stored_value_index (ifn);
3102 int mask_index = internal_fn_mask_index (ifn);
3103 tree base = gimple_call_arg (stmt, 0);
3104 tree offset = gimple_call_arg (stmt, 1);
3105 tree scale = gimple_call_arg (stmt, 2);
3106 tree rhs = gimple_call_arg (stmt, rhs_index);
3108 rtx base_rtx = expand_normal (base);
3109 rtx offset_rtx = expand_normal (offset);
3110 HOST_WIDE_INT scale_int = tree_to_shwi (scale);
3111 rtx rhs_rtx = expand_normal (rhs);
3113 class expand_operand ops[6];
3114 int i = 0;
3115 create_address_operand (&ops[i++], base_rtx);
3116 create_input_operand (&ops[i++], offset_rtx, TYPE_MODE (TREE_TYPE (offset)));
3117 create_integer_operand (&ops[i++], TYPE_UNSIGNED (TREE_TYPE (offset)));
3118 create_integer_operand (&ops[i++], scale_int);
3119 create_input_operand (&ops[i++], rhs_rtx, TYPE_MODE (TREE_TYPE (rhs)));
3120 if (mask_index >= 0)
3122 tree mask = gimple_call_arg (stmt, mask_index);
3123 rtx mask_rtx = expand_normal (mask);
3124 create_input_operand (&ops[i++], mask_rtx, TYPE_MODE (TREE_TYPE (mask)));
3127 insn_code icode = convert_optab_handler (optab, TYPE_MODE (TREE_TYPE (rhs)),
3128 TYPE_MODE (TREE_TYPE (offset)));
3129 expand_insn (icode, i, ops);
3132 /* Expand {MASK_,}GATHER_LOAD call CALL using optab OPTAB. */
3134 static void
3135 expand_gather_load_optab_fn (internal_fn, gcall *stmt, direct_optab optab)
3137 tree lhs = gimple_call_lhs (stmt);
3138 tree base = gimple_call_arg (stmt, 0);
3139 tree offset = gimple_call_arg (stmt, 1);
3140 tree scale = gimple_call_arg (stmt, 2);
3142 rtx lhs_rtx = expand_expr (lhs, NULL_RTX, VOIDmode, EXPAND_WRITE);
3143 rtx base_rtx = expand_normal (base);
3144 rtx offset_rtx = expand_normal (offset);
3145 HOST_WIDE_INT scale_int = tree_to_shwi (scale);
3147 int i = 0;
3148 class expand_operand ops[6];
3149 create_output_operand (&ops[i++], lhs_rtx, TYPE_MODE (TREE_TYPE (lhs)));
3150 create_address_operand (&ops[i++], base_rtx);
3151 create_input_operand (&ops[i++], offset_rtx, TYPE_MODE (TREE_TYPE (offset)));
3152 create_integer_operand (&ops[i++], TYPE_UNSIGNED (TREE_TYPE (offset)));
3153 create_integer_operand (&ops[i++], scale_int);
3154 if (optab == mask_gather_load_optab)
3156 tree mask = gimple_call_arg (stmt, 4);
3157 rtx mask_rtx = expand_normal (mask);
3158 create_input_operand (&ops[i++], mask_rtx, TYPE_MODE (TREE_TYPE (mask)));
3160 insn_code icode = convert_optab_handler (optab, TYPE_MODE (TREE_TYPE (lhs)),
3161 TYPE_MODE (TREE_TYPE (offset)));
3162 expand_insn (icode, i, ops);
3163 if (!rtx_equal_p (lhs_rtx, ops[0].value))
3164 emit_move_insn (lhs_rtx, ops[0].value);
3167 /* Helper for expand_DIVMOD. Return true if the sequence starting with
3168 INSN contains any call insns or insns with {,U}{DIV,MOD} rtxes. */
3170 static bool
3171 contains_call_div_mod (rtx_insn *insn)
3173 subrtx_iterator::array_type array;
3174 for (; insn; insn = NEXT_INSN (insn))
3175 if (CALL_P (insn))
3176 return true;
3177 else if (INSN_P (insn))
3178 FOR_EACH_SUBRTX (iter, array, PATTERN (insn), NONCONST)
3179 switch (GET_CODE (*iter))
3181 case CALL:
3182 case DIV:
3183 case UDIV:
3184 case MOD:
3185 case UMOD:
3186 return true;
3187 default:
3188 break;
3190 return false;
3193 /* Expand DIVMOD() using:
3194 a) optab handler for udivmod/sdivmod if it is available.
3195 b) If optab_handler doesn't exist, generate call to
3196 target-specific divmod libfunc. */
3198 static void
3199 expand_DIVMOD (internal_fn, gcall *call_stmt)
3201 tree lhs = gimple_call_lhs (call_stmt);
3202 tree arg0 = gimple_call_arg (call_stmt, 0);
3203 tree arg1 = gimple_call_arg (call_stmt, 1);
3205 gcc_assert (TREE_CODE (TREE_TYPE (lhs)) == COMPLEX_TYPE);
3206 tree type = TREE_TYPE (TREE_TYPE (lhs));
3207 machine_mode mode = TYPE_MODE (type);
3208 bool unsignedp = TYPE_UNSIGNED (type);
3209 optab tab = (unsignedp) ? udivmod_optab : sdivmod_optab;
3211 rtx op0 = expand_normal (arg0);
3212 rtx op1 = expand_normal (arg1);
3213 rtx target = expand_expr (lhs, NULL_RTX, VOIDmode, EXPAND_WRITE);
3215 rtx quotient = NULL_RTX, remainder = NULL_RTX;
3216 rtx_insn *insns = NULL;
3218 if (TREE_CODE (arg1) == INTEGER_CST)
3220 /* For DIVMOD by integral constants, there could be efficient code
3221 expanded inline e.g. using shifts and plus/minus. Try to expand
3222 the division and modulo and if it emits any library calls or any
3223 {,U}{DIV,MOD} rtxes throw it away and use a divmod optab or
3224 divmod libcall. */
3225 scalar_int_mode int_mode;
3226 if (remainder == NULL_RTX
3227 && optimize
3228 && CONST_INT_P (op1)
3229 && !pow2p_hwi (INTVAL (op1))
3230 && is_int_mode (TYPE_MODE (type), &int_mode)
3231 && GET_MODE_SIZE (int_mode) == 2 * UNITS_PER_WORD
3232 && optab_handler (and_optab, word_mode) != CODE_FOR_nothing
3233 && optab_handler (add_optab, word_mode) != CODE_FOR_nothing
3234 && optimize_insn_for_speed_p ())
3236 rtx_insn *last = get_last_insn ();
3237 remainder = NULL_RTX;
3238 quotient = expand_doubleword_divmod (int_mode, op0, op1, &remainder,
3239 TYPE_UNSIGNED (type));
3240 if (quotient != NULL_RTX)
3242 if (optab_handler (mov_optab, int_mode) != CODE_FOR_nothing)
3244 rtx_insn *move = emit_move_insn (quotient, quotient);
3245 set_dst_reg_note (move, REG_EQUAL,
3246 gen_rtx_fmt_ee (TYPE_UNSIGNED (type)
3247 ? UDIV : DIV, int_mode,
3248 copy_rtx (op0), op1),
3249 quotient);
3250 move = emit_move_insn (remainder, remainder);
3251 set_dst_reg_note (move, REG_EQUAL,
3252 gen_rtx_fmt_ee (TYPE_UNSIGNED (type)
3253 ? UMOD : MOD, int_mode,
3254 copy_rtx (op0), op1),
3255 quotient);
3258 else
3259 delete_insns_since (last);
3262 if (remainder == NULL_RTX)
3264 struct separate_ops ops;
3265 ops.code = TRUNC_DIV_EXPR;
3266 ops.type = type;
3267 ops.op0 = make_tree (ops.type, op0);
3268 ops.op1 = arg1;
3269 ops.op2 = NULL_TREE;
3270 ops.location = gimple_location (call_stmt);
3271 start_sequence ();
3272 quotient = expand_expr_real_2 (&ops, NULL_RTX, mode, EXPAND_NORMAL);
3273 if (contains_call_div_mod (get_insns ()))
3274 quotient = NULL_RTX;
3275 else
3277 ops.code = TRUNC_MOD_EXPR;
3278 remainder = expand_expr_real_2 (&ops, NULL_RTX, mode,
3279 EXPAND_NORMAL);
3280 if (contains_call_div_mod (get_insns ()))
3281 remainder = NULL_RTX;
3283 if (remainder)
3284 insns = get_insns ();
3285 end_sequence ();
3289 if (remainder)
3290 emit_insn (insns);
3292 /* Check if optab_handler exists for divmod_optab for given mode. */
3293 else if (optab_handler (tab, mode) != CODE_FOR_nothing)
3295 quotient = gen_reg_rtx (mode);
3296 remainder = gen_reg_rtx (mode);
3297 expand_twoval_binop (tab, op0, op1, quotient, remainder, unsignedp);
3300 /* Generate call to divmod libfunc if it exists. */
3301 else if (rtx libfunc = optab_libfunc (tab, mode))
3302 targetm.expand_divmod_libfunc (libfunc, mode, op0, op1,
3303 &quotient, &remainder);
3305 else
3306 gcc_unreachable ();
3308 /* Wrap the return value (quotient, remainder) within COMPLEX_EXPR. */
3309 expand_expr (build2 (COMPLEX_EXPR, TREE_TYPE (lhs),
3310 make_tree (TREE_TYPE (arg0), quotient),
3311 make_tree (TREE_TYPE (arg1), remainder)),
3312 target, VOIDmode, EXPAND_NORMAL);
3315 /* Expand a NOP. */
3317 static void
3318 expand_NOP (internal_fn, gcall *)
3320 /* Nothing. But it shouldn't really prevail. */
3323 /* Coroutines, all should have been processed at this stage. */
3325 static void
3326 expand_CO_FRAME (internal_fn, gcall *)
3328 gcc_unreachable ();
3331 static void
3332 expand_CO_YIELD (internal_fn, gcall *)
3334 gcc_unreachable ();
3337 static void
3338 expand_CO_SUSPN (internal_fn, gcall *)
3340 gcc_unreachable ();
3343 static void
3344 expand_CO_ACTOR (internal_fn, gcall *)
3346 gcc_unreachable ();
3349 /* Expand a call to FN using the operands in STMT. FN has a single
3350 output operand and NARGS input operands. */
3352 static void
3353 expand_direct_optab_fn (internal_fn fn, gcall *stmt, direct_optab optab,
3354 unsigned int nargs)
3356 expand_operand *ops = XALLOCAVEC (expand_operand, nargs + 1);
3358 tree_pair types = direct_internal_fn_types (fn, stmt);
3359 insn_code icode = direct_optab_handler (optab, TYPE_MODE (types.first));
3360 gcc_assert (icode != CODE_FOR_nothing);
3362 tree lhs = gimple_call_lhs (stmt);
3363 rtx lhs_rtx = NULL_RTX;
3364 if (lhs)
3365 lhs_rtx = expand_expr (lhs, NULL_RTX, VOIDmode, EXPAND_WRITE);
3367 /* Do not assign directly to a promoted subreg, since there is no
3368 guarantee that the instruction will leave the upper bits of the
3369 register in the state required by SUBREG_PROMOTED_SIGN. */
3370 rtx dest = lhs_rtx;
3371 if (dest && GET_CODE (dest) == SUBREG && SUBREG_PROMOTED_VAR_P (dest))
3372 dest = NULL_RTX;
3374 create_output_operand (&ops[0], dest, insn_data[icode].operand[0].mode);
3376 for (unsigned int i = 0; i < nargs; ++i)
3378 tree rhs = gimple_call_arg (stmt, i);
3379 tree rhs_type = TREE_TYPE (rhs);
3380 rtx rhs_rtx = expand_normal (rhs);
3381 if (INTEGRAL_TYPE_P (rhs_type))
3382 create_convert_operand_from (&ops[i + 1], rhs_rtx,
3383 TYPE_MODE (rhs_type),
3384 TYPE_UNSIGNED (rhs_type));
3385 else
3386 create_input_operand (&ops[i + 1], rhs_rtx, TYPE_MODE (rhs_type));
3389 expand_insn (icode, nargs + 1, ops);
3390 if (lhs_rtx && !rtx_equal_p (lhs_rtx, ops[0].value))
3392 /* If the return value has an integral type, convert the instruction
3393 result to that type. This is useful for things that return an
3394 int regardless of the size of the input. If the instruction result
3395 is smaller than required, assume that it is signed.
3397 If the return value has a nonintegral type, its mode must match
3398 the instruction result. */
3399 if (GET_CODE (lhs_rtx) == SUBREG && SUBREG_PROMOTED_VAR_P (lhs_rtx))
3401 /* If this is a scalar in a register that is stored in a wider
3402 mode than the declared mode, compute the result into its
3403 declared mode and then convert to the wider mode. */
3404 gcc_checking_assert (INTEGRAL_TYPE_P (TREE_TYPE (lhs)));
3405 rtx tmp = convert_to_mode (GET_MODE (lhs_rtx), ops[0].value, 0);
3406 convert_move (SUBREG_REG (lhs_rtx), tmp,
3407 SUBREG_PROMOTED_SIGN (lhs_rtx));
3409 else if (GET_MODE (lhs_rtx) == GET_MODE (ops[0].value))
3410 emit_move_insn (lhs_rtx, ops[0].value);
3411 else
3413 gcc_checking_assert (INTEGRAL_TYPE_P (TREE_TYPE (lhs)));
3414 convert_move (lhs_rtx, ops[0].value, 0);
3419 /* Expand WHILE_ULT call STMT using optab OPTAB. */
3421 static void
3422 expand_while_optab_fn (internal_fn, gcall *stmt, convert_optab optab)
3424 expand_operand ops[3];
3425 tree rhs_type[2];
3427 tree lhs = gimple_call_lhs (stmt);
3428 tree lhs_type = TREE_TYPE (lhs);
3429 rtx lhs_rtx = expand_expr (lhs, NULL_RTX, VOIDmode, EXPAND_WRITE);
3430 create_output_operand (&ops[0], lhs_rtx, TYPE_MODE (lhs_type));
3432 for (unsigned int i = 0; i < 2; ++i)
3434 tree rhs = gimple_call_arg (stmt, i);
3435 rhs_type[i] = TREE_TYPE (rhs);
3436 rtx rhs_rtx = expand_normal (rhs);
3437 create_input_operand (&ops[i + 1], rhs_rtx, TYPE_MODE (rhs_type[i]));
3440 insn_code icode = convert_optab_handler (optab, TYPE_MODE (rhs_type[0]),
3441 TYPE_MODE (lhs_type));
3443 expand_insn (icode, 3, ops);
3444 if (!rtx_equal_p (lhs_rtx, ops[0].value))
3445 emit_move_insn (lhs_rtx, ops[0].value);
3448 /* Expanders for optabs that can use expand_direct_optab_fn. */
3450 #define expand_unary_optab_fn(FN, STMT, OPTAB) \
3451 expand_direct_optab_fn (FN, STMT, OPTAB, 1)
3453 #define expand_binary_optab_fn(FN, STMT, OPTAB) \
3454 expand_direct_optab_fn (FN, STMT, OPTAB, 2)
3456 #define expand_ternary_optab_fn(FN, STMT, OPTAB) \
3457 expand_direct_optab_fn (FN, STMT, OPTAB, 3)
3459 #define expand_cond_unary_optab_fn(FN, STMT, OPTAB) \
3460 expand_direct_optab_fn (FN, STMT, OPTAB, 3)
3462 #define expand_cond_binary_optab_fn(FN, STMT, OPTAB) \
3463 expand_direct_optab_fn (FN, STMT, OPTAB, 4)
3465 #define expand_cond_ternary_optab_fn(FN, STMT, OPTAB) \
3466 expand_direct_optab_fn (FN, STMT, OPTAB, 5)
3468 #define expand_fold_extract_optab_fn(FN, STMT, OPTAB) \
3469 expand_direct_optab_fn (FN, STMT, OPTAB, 3)
3471 #define expand_fold_left_optab_fn(FN, STMT, OPTAB) \
3472 expand_direct_optab_fn (FN, STMT, OPTAB, 2)
3474 #define expand_mask_fold_left_optab_fn(FN, STMT, OPTAB) \
3475 expand_direct_optab_fn (FN, STMT, OPTAB, 3)
3477 #define expand_check_ptrs_optab_fn(FN, STMT, OPTAB) \
3478 expand_direct_optab_fn (FN, STMT, OPTAB, 4)
3480 /* RETURN_TYPE and ARGS are a return type and argument list that are
3481 in principle compatible with FN (which satisfies direct_internal_fn_p).
3482 Return the types that should be used to determine whether the
3483 target supports FN. */
3485 tree_pair
3486 direct_internal_fn_types (internal_fn fn, tree return_type, tree *args)
3488 const direct_internal_fn_info &info = direct_internal_fn (fn);
3489 tree type0 = (info.type0 < 0 ? return_type : TREE_TYPE (args[info.type0]));
3490 tree type1 = (info.type1 < 0 ? return_type : TREE_TYPE (args[info.type1]));
3491 return tree_pair (type0, type1);
3494 /* CALL is a call whose return type and arguments are in principle
3495 compatible with FN (which satisfies direct_internal_fn_p). Return the
3496 types that should be used to determine whether the target supports FN. */
3498 tree_pair
3499 direct_internal_fn_types (internal_fn fn, gcall *call)
3501 const direct_internal_fn_info &info = direct_internal_fn (fn);
3502 tree op0 = (info.type0 < 0
3503 ? gimple_call_lhs (call)
3504 : gimple_call_arg (call, info.type0));
3505 tree op1 = (info.type1 < 0
3506 ? gimple_call_lhs (call)
3507 : gimple_call_arg (call, info.type1));
3508 return tree_pair (TREE_TYPE (op0), TREE_TYPE (op1));
3511 /* Return true if OPTAB is supported for TYPES (whose modes should be
3512 the same) when the optimization type is OPT_TYPE. Used for simple
3513 direct optabs. */
3515 static bool
3516 direct_optab_supported_p (direct_optab optab, tree_pair types,
3517 optimization_type opt_type)
3519 machine_mode mode = TYPE_MODE (types.first);
3520 gcc_checking_assert (mode == TYPE_MODE (types.second));
3521 return direct_optab_handler (optab, mode, opt_type) != CODE_FOR_nothing;
3524 /* Return true if OPTAB is supported for TYPES, where the first type
3525 is the destination and the second type is the source. Used for
3526 convert optabs. */
3528 static bool
3529 convert_optab_supported_p (convert_optab optab, tree_pair types,
3530 optimization_type opt_type)
3532 return (convert_optab_handler (optab, TYPE_MODE (types.first),
3533 TYPE_MODE (types.second), opt_type)
3534 != CODE_FOR_nothing);
3537 /* Return true if load/store lanes optab OPTAB is supported for
3538 array type TYPES.first when the optimization type is OPT_TYPE. */
3540 static bool
3541 multi_vector_optab_supported_p (convert_optab optab, tree_pair types,
3542 optimization_type opt_type)
3544 gcc_assert (TREE_CODE (types.first) == ARRAY_TYPE);
3545 machine_mode imode = TYPE_MODE (types.first);
3546 machine_mode vmode = TYPE_MODE (TREE_TYPE (types.first));
3547 return (convert_optab_handler (optab, imode, vmode, opt_type)
3548 != CODE_FOR_nothing);
3551 #define direct_unary_optab_supported_p direct_optab_supported_p
3552 #define direct_binary_optab_supported_p direct_optab_supported_p
3553 #define direct_ternary_optab_supported_p direct_optab_supported_p
3554 #define direct_cond_unary_optab_supported_p direct_optab_supported_p
3555 #define direct_cond_binary_optab_supported_p direct_optab_supported_p
3556 #define direct_cond_ternary_optab_supported_p direct_optab_supported_p
3557 #define direct_mask_load_optab_supported_p convert_optab_supported_p
3558 #define direct_load_lanes_optab_supported_p multi_vector_optab_supported_p
3559 #define direct_mask_load_lanes_optab_supported_p multi_vector_optab_supported_p
3560 #define direct_gather_load_optab_supported_p convert_optab_supported_p
3561 #define direct_len_load_optab_supported_p direct_optab_supported_p
3562 #define direct_mask_store_optab_supported_p convert_optab_supported_p
3563 #define direct_store_lanes_optab_supported_p multi_vector_optab_supported_p
3564 #define direct_mask_store_lanes_optab_supported_p multi_vector_optab_supported_p
3565 #define direct_vec_cond_mask_optab_supported_p convert_optab_supported_p
3566 #define direct_vec_cond_optab_supported_p convert_optab_supported_p
3567 #define direct_scatter_store_optab_supported_p convert_optab_supported_p
3568 #define direct_len_store_optab_supported_p direct_optab_supported_p
3569 #define direct_while_optab_supported_p convert_optab_supported_p
3570 #define direct_fold_extract_optab_supported_p direct_optab_supported_p
3571 #define direct_fold_left_optab_supported_p direct_optab_supported_p
3572 #define direct_mask_fold_left_optab_supported_p direct_optab_supported_p
3573 #define direct_check_ptrs_optab_supported_p direct_optab_supported_p
3574 #define direct_vec_set_optab_supported_p direct_optab_supported_p
3576 /* Return the optab used by internal function FN. */
3578 static optab
3579 direct_internal_fn_optab (internal_fn fn, tree_pair types)
3581 switch (fn)
3583 #define DEF_INTERNAL_FN(CODE, FLAGS, FNSPEC) \
3584 case IFN_##CODE: break;
3585 #define DEF_INTERNAL_OPTAB_FN(CODE, FLAGS, OPTAB, TYPE) \
3586 case IFN_##CODE: return OPTAB##_optab;
3587 #define DEF_INTERNAL_SIGNED_OPTAB_FN(CODE, FLAGS, SELECTOR, SIGNED_OPTAB, \
3588 UNSIGNED_OPTAB, TYPE) \
3589 case IFN_##CODE: return (TYPE_UNSIGNED (types.SELECTOR) \
3590 ? UNSIGNED_OPTAB ## _optab \
3591 : SIGNED_OPTAB ## _optab);
3592 #include "internal-fn.def"
3594 case IFN_LAST:
3595 break;
3597 gcc_unreachable ();
3600 /* Return the optab used by internal function FN. */
3602 static optab
3603 direct_internal_fn_optab (internal_fn fn)
3605 switch (fn)
3607 #define DEF_INTERNAL_FN(CODE, FLAGS, FNSPEC) \
3608 case IFN_##CODE: break;
3609 #define DEF_INTERNAL_OPTAB_FN(CODE, FLAGS, OPTAB, TYPE) \
3610 case IFN_##CODE: return OPTAB##_optab;
3611 #include "internal-fn.def"
3613 case IFN_LAST:
3614 break;
3616 gcc_unreachable ();
3619 /* Return true if FN is supported for the types in TYPES when the
3620 optimization type is OPT_TYPE. The types are those associated with
3621 the "type0" and "type1" fields of FN's direct_internal_fn_info
3622 structure. */
3624 bool
3625 direct_internal_fn_supported_p (internal_fn fn, tree_pair types,
3626 optimization_type opt_type)
3628 switch (fn)
3630 #define DEF_INTERNAL_FN(CODE, FLAGS, FNSPEC) \
3631 case IFN_##CODE: break;
3632 #define DEF_INTERNAL_OPTAB_FN(CODE, FLAGS, OPTAB, TYPE) \
3633 case IFN_##CODE: \
3634 return direct_##TYPE##_optab_supported_p (OPTAB##_optab, types, \
3635 opt_type);
3636 #define DEF_INTERNAL_SIGNED_OPTAB_FN(CODE, FLAGS, SELECTOR, SIGNED_OPTAB, \
3637 UNSIGNED_OPTAB, TYPE) \
3638 case IFN_##CODE: \
3640 optab which_optab = (TYPE_UNSIGNED (types.SELECTOR) \
3641 ? UNSIGNED_OPTAB ## _optab \
3642 : SIGNED_OPTAB ## _optab); \
3643 return direct_##TYPE##_optab_supported_p (which_optab, types, \
3644 opt_type); \
3646 #include "internal-fn.def"
3648 case IFN_LAST:
3649 break;
3651 gcc_unreachable ();
3654 /* Return true if FN is supported for type TYPE when the optimization
3655 type is OPT_TYPE. The caller knows that the "type0" and "type1"
3656 fields of FN's direct_internal_fn_info structure are the same. */
3658 bool
3659 direct_internal_fn_supported_p (internal_fn fn, tree type,
3660 optimization_type opt_type)
3662 const direct_internal_fn_info &info = direct_internal_fn (fn);
3663 gcc_checking_assert (info.type0 == info.type1);
3664 return direct_internal_fn_supported_p (fn, tree_pair (type, type), opt_type);
3667 /* Return true if the STMT is supported when the optimization type is OPT_TYPE,
3668 given that STMT is a call to a direct internal function. */
3670 bool
3671 direct_internal_fn_supported_p (gcall *stmt, optimization_type opt_type)
3673 internal_fn fn = gimple_call_internal_fn (stmt);
3674 tree_pair types = direct_internal_fn_types (fn, stmt);
3675 return direct_internal_fn_supported_p (fn, types, opt_type);
3678 /* If FN is commutative in two consecutive arguments, return the
3679 index of the first, otherwise return -1. */
3682 first_commutative_argument (internal_fn fn)
3684 switch (fn)
3686 case IFN_FMA:
3687 case IFN_FMS:
3688 case IFN_FNMA:
3689 case IFN_FNMS:
3690 case IFN_AVG_FLOOR:
3691 case IFN_AVG_CEIL:
3692 case IFN_MULHS:
3693 case IFN_MULHRS:
3694 case IFN_FMIN:
3695 case IFN_FMAX:
3696 return 0;
3698 case IFN_COND_ADD:
3699 case IFN_COND_MUL:
3700 case IFN_COND_MIN:
3701 case IFN_COND_MAX:
3702 case IFN_COND_AND:
3703 case IFN_COND_IOR:
3704 case IFN_COND_XOR:
3705 case IFN_COND_FMA:
3706 case IFN_COND_FMS:
3707 case IFN_COND_FNMA:
3708 case IFN_COND_FNMS:
3709 return 1;
3711 default:
3712 return -1;
3716 /* Return true if IFN_SET_EDOM is supported. */
3718 bool
3719 set_edom_supported_p (void)
3721 #ifdef TARGET_EDOM
3722 return true;
3723 #else
3724 return false;
3725 #endif
3728 #define DEF_INTERNAL_OPTAB_FN(CODE, FLAGS, OPTAB, TYPE) \
3729 static void \
3730 expand_##CODE (internal_fn fn, gcall *stmt) \
3732 expand_##TYPE##_optab_fn (fn, stmt, OPTAB##_optab); \
3734 #define DEF_INTERNAL_SIGNED_OPTAB_FN(CODE, FLAGS, SELECTOR, SIGNED_OPTAB, \
3735 UNSIGNED_OPTAB, TYPE) \
3736 static void \
3737 expand_##CODE (internal_fn fn, gcall *stmt) \
3739 tree_pair types = direct_internal_fn_types (fn, stmt); \
3740 optab which_optab = direct_internal_fn_optab (fn, types); \
3741 expand_##TYPE##_optab_fn (fn, stmt, which_optab); \
3743 #include "internal-fn.def"
3745 /* Routines to expand each internal function, indexed by function number.
3746 Each routine has the prototype:
3748 expand_<NAME> (gcall *stmt)
3750 where STMT is the statement that performs the call. */
3751 static void (*const internal_fn_expanders[]) (internal_fn, gcall *) = {
3752 #define DEF_INTERNAL_FN(CODE, FLAGS, FNSPEC) expand_##CODE,
3753 #include "internal-fn.def"
3757 /* Invoke T(CODE, IFN) for each conditional function IFN that maps to a
3758 tree code CODE. */
3759 #define FOR_EACH_CODE_MAPPING(T) \
3760 T (PLUS_EXPR, IFN_COND_ADD) \
3761 T (MINUS_EXPR, IFN_COND_SUB) \
3762 T (MULT_EXPR, IFN_COND_MUL) \
3763 T (TRUNC_DIV_EXPR, IFN_COND_DIV) \
3764 T (TRUNC_MOD_EXPR, IFN_COND_MOD) \
3765 T (RDIV_EXPR, IFN_COND_RDIV) \
3766 T (MIN_EXPR, IFN_COND_MIN) \
3767 T (MAX_EXPR, IFN_COND_MAX) \
3768 T (BIT_AND_EXPR, IFN_COND_AND) \
3769 T (BIT_IOR_EXPR, IFN_COND_IOR) \
3770 T (BIT_XOR_EXPR, IFN_COND_XOR) \
3771 T (LSHIFT_EXPR, IFN_COND_SHL) \
3772 T (RSHIFT_EXPR, IFN_COND_SHR)
3774 /* Return a function that only performs CODE when a certain condition is met
3775 and that uses a given fallback value otherwise. For example, if CODE is
3776 a binary operation associated with conditional function FN:
3778 LHS = FN (COND, A, B, ELSE)
3780 is equivalent to the C expression:
3782 LHS = COND ? A CODE B : ELSE;
3784 operating elementwise if the operands are vectors.
3786 Return IFN_LAST if no such function exists. */
3788 internal_fn
3789 get_conditional_internal_fn (tree_code code)
3791 switch (code)
3793 #define CASE(CODE, IFN) case CODE: return IFN;
3794 FOR_EACH_CODE_MAPPING(CASE)
3795 #undef CASE
3796 default:
3797 return IFN_LAST;
3801 /* If IFN implements the conditional form of a tree code, return that
3802 tree code, otherwise return ERROR_MARK. */
3804 tree_code
3805 conditional_internal_fn_code (internal_fn ifn)
3807 switch (ifn)
3809 #define CASE(CODE, IFN) case IFN: return CODE;
3810 FOR_EACH_CODE_MAPPING(CASE)
3811 #undef CASE
3812 default:
3813 return ERROR_MARK;
3817 /* Invoke T(IFN) for each internal function IFN that also has an
3818 IFN_COND_* form. */
3819 #define FOR_EACH_COND_FN_PAIR(T) \
3820 T (FMA) \
3821 T (FMS) \
3822 T (FNMA) \
3823 T (FNMS)
3825 /* Return a function that only performs internal function FN when a
3826 certain condition is met and that uses a given fallback value otherwise.
3827 In other words, the returned function FN' is such that:
3829 LHS = FN' (COND, A1, ... An, ELSE)
3831 is equivalent to the C expression:
3833 LHS = COND ? FN (A1, ..., An) : ELSE;
3835 operating elementwise if the operands are vectors.
3837 Return IFN_LAST if no such function exists. */
3839 internal_fn
3840 get_conditional_internal_fn (internal_fn fn)
3842 switch (fn)
3844 #define CASE(NAME) case IFN_##NAME: return IFN_COND_##NAME;
3845 FOR_EACH_COND_FN_PAIR(CASE)
3846 #undef CASE
3847 default:
3848 return IFN_LAST;
3852 /* If IFN implements the conditional form of an unconditional internal
3853 function, return that unconditional function, otherwise return IFN_LAST. */
3855 internal_fn
3856 get_unconditional_internal_fn (internal_fn ifn)
3858 switch (ifn)
3860 #define CASE(NAME) case IFN_COND_##NAME: return IFN_##NAME;
3861 FOR_EACH_COND_FN_PAIR(CASE)
3862 #undef CASE
3863 default:
3864 return IFN_LAST;
3868 /* Return true if STMT can be interpreted as a conditional tree code
3869 operation of the form:
3871 LHS = COND ? OP (RHS1, ...) : ELSE;
3873 operating elementwise if the operands are vectors. This includes
3874 the case of an all-true COND, so that the operation always happens.
3876 When returning true, set:
3878 - *COND_OUT to the condition COND, or to NULL_TREE if the condition
3879 is known to be all-true
3880 - *CODE_OUT to the tree code
3881 - OPS[I] to operand I of *CODE_OUT
3882 - *ELSE_OUT to the fallback value ELSE, or to NULL_TREE if the
3883 condition is known to be all true. */
3885 bool
3886 can_interpret_as_conditional_op_p (gimple *stmt, tree *cond_out,
3887 tree_code *code_out,
3888 tree (&ops)[3], tree *else_out)
3890 if (gassign *assign = dyn_cast <gassign *> (stmt))
3892 *cond_out = NULL_TREE;
3893 *code_out = gimple_assign_rhs_code (assign);
3894 ops[0] = gimple_assign_rhs1 (assign);
3895 ops[1] = gimple_assign_rhs2 (assign);
3896 ops[2] = gimple_assign_rhs3 (assign);
3897 *else_out = NULL_TREE;
3898 return true;
3900 if (gcall *call = dyn_cast <gcall *> (stmt))
3901 if (gimple_call_internal_p (call))
3903 internal_fn ifn = gimple_call_internal_fn (call);
3904 tree_code code = conditional_internal_fn_code (ifn);
3905 if (code != ERROR_MARK)
3907 *cond_out = gimple_call_arg (call, 0);
3908 *code_out = code;
3909 unsigned int nops = gimple_call_num_args (call) - 2;
3910 for (unsigned int i = 0; i < 3; ++i)
3911 ops[i] = i < nops ? gimple_call_arg (call, i + 1) : NULL_TREE;
3912 *else_out = gimple_call_arg (call, nops + 1);
3913 if (integer_truep (*cond_out))
3915 *cond_out = NULL_TREE;
3916 *else_out = NULL_TREE;
3918 return true;
3921 return false;
3924 /* Return true if IFN is some form of load from memory. */
3926 bool
3927 internal_load_fn_p (internal_fn fn)
3929 switch (fn)
3931 case IFN_MASK_LOAD:
3932 case IFN_LOAD_LANES:
3933 case IFN_MASK_LOAD_LANES:
3934 case IFN_GATHER_LOAD:
3935 case IFN_MASK_GATHER_LOAD:
3936 case IFN_LEN_LOAD:
3937 return true;
3939 default:
3940 return false;
3944 /* Return true if IFN is some form of store to memory. */
3946 bool
3947 internal_store_fn_p (internal_fn fn)
3949 switch (fn)
3951 case IFN_MASK_STORE:
3952 case IFN_STORE_LANES:
3953 case IFN_MASK_STORE_LANES:
3954 case IFN_SCATTER_STORE:
3955 case IFN_MASK_SCATTER_STORE:
3956 case IFN_LEN_STORE:
3957 return true;
3959 default:
3960 return false;
3964 /* Return true if IFN is some form of gather load or scatter store. */
3966 bool
3967 internal_gather_scatter_fn_p (internal_fn fn)
3969 switch (fn)
3971 case IFN_GATHER_LOAD:
3972 case IFN_MASK_GATHER_LOAD:
3973 case IFN_SCATTER_STORE:
3974 case IFN_MASK_SCATTER_STORE:
3975 return true;
3977 default:
3978 return false;
3982 /* If FN takes a vector mask argument, return the index of that argument,
3983 otherwise return -1. */
3986 internal_fn_mask_index (internal_fn fn)
3988 switch (fn)
3990 case IFN_MASK_LOAD:
3991 case IFN_MASK_LOAD_LANES:
3992 case IFN_MASK_STORE:
3993 case IFN_MASK_STORE_LANES:
3994 return 2;
3996 case IFN_MASK_GATHER_LOAD:
3997 case IFN_MASK_SCATTER_STORE:
3998 return 4;
4000 default:
4001 return (conditional_internal_fn_code (fn) != ERROR_MARK
4002 || get_unconditional_internal_fn (fn) != IFN_LAST ? 0 : -1);
4006 /* If FN takes a value that should be stored to memory, return the index
4007 of that argument, otherwise return -1. */
4010 internal_fn_stored_value_index (internal_fn fn)
4012 switch (fn)
4014 case IFN_MASK_STORE:
4015 case IFN_MASK_STORE_LANES:
4016 case IFN_SCATTER_STORE:
4017 case IFN_MASK_SCATTER_STORE:
4018 case IFN_LEN_STORE:
4019 return 3;
4021 default:
4022 return -1;
4026 /* Return true if the target supports gather load or scatter store function
4027 IFN. For loads, VECTOR_TYPE is the vector type of the load result,
4028 while for stores it is the vector type of the stored data argument.
4029 MEMORY_ELEMENT_TYPE is the type of the memory elements being loaded
4030 or stored. OFFSET_VECTOR_TYPE is the vector type that holds the
4031 offset from the shared base address of each loaded or stored element.
4032 SCALE is the amount by which these offsets should be multiplied
4033 *after* they have been extended to address width. */
4035 bool
4036 internal_gather_scatter_fn_supported_p (internal_fn ifn, tree vector_type,
4037 tree memory_element_type,
4038 tree offset_vector_type, int scale)
4040 if (!tree_int_cst_equal (TYPE_SIZE (TREE_TYPE (vector_type)),
4041 TYPE_SIZE (memory_element_type)))
4042 return false;
4043 if (maybe_ne (TYPE_VECTOR_SUBPARTS (vector_type),
4044 TYPE_VECTOR_SUBPARTS (offset_vector_type)))
4045 return false;
4046 optab optab = direct_internal_fn_optab (ifn);
4047 insn_code icode = convert_optab_handler (optab, TYPE_MODE (vector_type),
4048 TYPE_MODE (offset_vector_type));
4049 int output_ops = internal_load_fn_p (ifn) ? 1 : 0;
4050 bool unsigned_p = TYPE_UNSIGNED (TREE_TYPE (offset_vector_type));
4051 return (icode != CODE_FOR_nothing
4052 && insn_operand_matches (icode, 2 + output_ops, GEN_INT (unsigned_p))
4053 && insn_operand_matches (icode, 3 + output_ops, GEN_INT (scale)));
4056 /* Return true if the target supports IFN_CHECK_{RAW,WAR}_PTRS function IFN
4057 for pointers of type TYPE when the accesses have LENGTH bytes and their
4058 common byte alignment is ALIGN. */
4060 bool
4061 internal_check_ptrs_fn_supported_p (internal_fn ifn, tree type,
4062 poly_uint64 length, unsigned int align)
4064 machine_mode mode = TYPE_MODE (type);
4065 optab optab = direct_internal_fn_optab (ifn);
4066 insn_code icode = direct_optab_handler (optab, mode);
4067 if (icode == CODE_FOR_nothing)
4068 return false;
4069 rtx length_rtx = immed_wide_int_const (length, mode);
4070 return (insn_operand_matches (icode, 3, length_rtx)
4071 && insn_operand_matches (icode, 4, GEN_INT (align)));
4074 /* Expand STMT as though it were a call to internal function FN. */
4076 void
4077 expand_internal_call (internal_fn fn, gcall *stmt)
4079 internal_fn_expanders[fn] (fn, stmt);
4082 /* Expand STMT, which is a call to internal function FN. */
4084 void
4085 expand_internal_call (gcall *stmt)
4087 expand_internal_call (gimple_call_internal_fn (stmt), stmt);
4090 /* If TYPE is a vector type, return true if IFN is a direct internal
4091 function that is supported for that type. If TYPE is a scalar type,
4092 return true if IFN is a direct internal function that is supported for
4093 the target's preferred vector version of TYPE. */
4095 bool
4096 vectorized_internal_fn_supported_p (internal_fn ifn, tree type)
4098 scalar_mode smode;
4099 if (!VECTOR_TYPE_P (type) && is_a <scalar_mode> (TYPE_MODE (type), &smode))
4101 machine_mode vmode = targetm.vectorize.preferred_simd_mode (smode);
4102 if (VECTOR_MODE_P (vmode))
4103 type = build_vector_type_for_mode (type, vmode);
4106 return (VECTOR_MODE_P (TYPE_MODE (type))
4107 && direct_internal_fn_supported_p (ifn, type, OPTIMIZE_FOR_SPEED));
4110 void
4111 expand_PHI (internal_fn, gcall *)
4113 gcc_unreachable ();