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
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
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/>. */
22 #include "coretypes.h"
29 #include "stringpool.h"
31 #include "tree-ssanames.h"
36 #include "diagnostic-core.h"
37 #include "fold-const.h"
38 #include "internal-fn.h"
39 #include "stor-layout.h"
42 #include "stringpool.h"
48 #include "optabs-tree.h"
49 #include "gimple-ssa.h"
50 #include "tree-phinodes.h"
51 #include "ssa-iterators.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"
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
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
;
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
)),
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];
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"
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
)
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. */
158 expand_load_lanes_optab_fn (internal_fn
, gcall
*stmt
, convert_optab optab
)
160 class expand_operand ops
[2];
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. */
184 expand_store_lanes_optab_fn (internal_fn
, gcall
*stmt
, convert_optab optab
)
186 class expand_operand ops
[2];
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
);
206 expand_ANNOTATE (internal_fn
, gcall
*)
211 /* This should get expanded in omp_device_lower pass. */
214 expand_GOMP_USE_SIMT (internal_fn
, gcall
*)
219 /* This should get expanded in omp_device_lower pass. */
222 expand_GOMP_SIMT_ENTER (internal_fn
, gcall
*)
227 /* Allocate per-lane storage and begin non-uniform execution region. */
230 expand_GOMP_SIMT_ENTER_ALLOC (internal_fn
, gcall
*stmt
)
233 tree lhs
= gimple_call_lhs (stmt
);
235 target
= expand_expr (lhs
, NULL_RTX
, VOIDmode
, EXPAND_WRITE
);
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. */
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. */
265 expand_GOMP_SIMT_LANE (internal_fn
, gcall
*stmt
)
267 tree lhs
= gimple_call_lhs (stmt
);
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. */
279 expand_GOMP_SIMT_VF (internal_fn
, gcall
*)
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. */
289 expand_GOMP_SIMT_LAST_LANE (internal_fn
, gcall
*stmt
)
291 tree lhs
= gimple_call_lhs (stmt
);
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". */
308 expand_GOMP_SIMT_ORDERED_PRED (internal_fn
, gcall
*stmt
)
310 tree lhs
= gimple_call_lhs (stmt
);
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. */
328 expand_GOMP_SIMT_VOTE_ANY (internal_fn
, gcall
*stmt
)
330 tree lhs
= gimple_call_lhs (stmt
);
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. */
348 expand_GOMP_SIMT_XCHG_BFLY (internal_fn
, gcall
*stmt
)
350 tree lhs
= gimple_call_lhs (stmt
);
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. */
369 expand_GOMP_SIMT_XCHG_IDX (internal_fn
, gcall
*stmt
)
371 tree lhs
= gimple_call_lhs (stmt
);
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. */
390 expand_GOMP_SIMD_LANE (internal_fn
, gcall
*)
395 /* This should get expanded in adjust_simduid_builtins. */
398 expand_GOMP_SIMD_VF (internal_fn
, gcall
*)
403 /* This should get expanded in adjust_simduid_builtins. */
406 expand_GOMP_SIMD_LAST_LANE (internal_fn
, gcall
*)
411 /* This should get expanded in adjust_simduid_builtins. */
414 expand_GOMP_SIMD_ORDERED_START (internal_fn
, gcall
*)
419 /* This should get expanded in adjust_simduid_builtins. */
422 expand_GOMP_SIMD_ORDERED_END (internal_fn
, gcall
*)
427 /* This should get expanded in the sanopt pass. */
430 expand_UBSAN_NULL (internal_fn
, gcall
*)
435 /* This should get expanded in the sanopt pass. */
438 expand_UBSAN_BOUNDS (internal_fn
, gcall
*)
443 /* This should get expanded in the sanopt pass. */
446 expand_UBSAN_VPTR (internal_fn
, gcall
*)
451 /* This should get expanded in the sanopt pass. */
454 expand_UBSAN_PTR (internal_fn
, gcall
*)
459 /* This should get expanded in the sanopt pass. */
462 expand_UBSAN_OBJECT_SIZE (internal_fn
, gcall
*)
467 /* This should get expanded in the sanopt pass. */
470 expand_HWASAN_CHECK (internal_fn
, gcall
*)
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
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
,
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,
490 emit_library_call_value (func
, NULL_RTX
, LCT_NORMAL
, VOIDmode
,
491 virtual_stack_dynamic_rtx
, Pmode
,
492 HWASAN_STACK_BACKGROUND
, QImode
,
496 /* For hwasan stack tagging:
497 Return a tag to be used for a dynamic allocation. */
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,
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. */
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. */
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. */
575 expand_ASAN_CHECK (internal_fn
, gcall
*)
580 /* This should get expanded in the sanopt pass. */
583 expand_ASAN_MARK (internal_fn
, gcall
*)
588 /* This should get expanded in the sanopt pass. */
591 expand_ASAN_POISON (internal_fn
, gcall
*)
596 /* This should get expanded in the sanopt pass. */
599 expand_ASAN_POISON_USE (internal_fn
, gcall
*)
604 /* This should get expanded in the tsan pass. */
607 expand_TSAN_FUNC_EXIT (internal_fn
, gcall
*)
612 /* This should get expanded in the lower pass. */
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. */
625 get_min_precision (tree arg
, signop sign
)
627 int prec
= TYPE_PRECISION (TREE_TYPE (arg
));
629 signop orig_sign
= sign
;
630 if (TREE_CODE (arg
) == INTEGER_CST
)
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
);
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
)))
652 else if (sign
== UNSIGNED
&& get_range_pos_neg (arg
) != 1)
653 return prec
+ (orig_sign
!= sign
);
654 prec
= TYPE_PRECISION (TREE_TYPE (arg
));
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
);
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
)
683 if (TYPE_PRECISION (TREE_TYPE (arg
)) < prec
)
685 if (TYPE_UNSIGNED (TREE_TYPE (arg
)))
687 else if (sign
== UNSIGNED
&& get_range_pos_neg (arg
) != 1)
688 return prec
+ (orig_sign
!= sign
);
689 prec
= TYPE_PRECISION (TREE_TYPE (arg
));
692 return prec
+ (orig_sign
!= sign
);
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
);
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). */
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);
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. */
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
)));
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
);
754 rtx_code_label
*done_label
= gen_label_rtx ();
755 int uns
= TYPE_UNSIGNED (TREE_TYPE (TREE_TYPE (lhs
)));
760 = immed_wide_int_const (wi::shifted_mask (0, prec
, false, tgtprec
),
762 lres
= expand_simple_binop (tgtmode
, AND
, res
, mask
, NULL_RTX
,
763 true, OPTAB_LIB_WIDEN
);
767 lres
= expand_shift (LSHIFT_EXPR
, tgtmode
, res
, tgtprec
- prec
,
769 lres
= expand_shift (RSHIFT_EXPR
, tgtmode
, lres
, tgtprec
- prec
,
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. */
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
791 convert_move (SUBREG_REG (target
), res
, SUBREG_PROMOTED_SIGN (target
));
793 emit_move_insn (target
, res
);
796 /* Add sub/add overflow checking to the statement STMT.
797 CODE says whether the operation is +, or -. */
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
;
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
);
817 gcc_assert (!unsr_p
&& !uns0_p
&& !uns1_p
);
821 target
= expand_expr (lhs
, NULL_RTX
, VOIDmode
, EXPAND_WRITE
);
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.
838 res = (S) ((U) s1 + (U) s2)
839 ovf = s2 < 0 ? res > s1 : res < s1 (or jump on overflow)
841 res = (S) ((U) s1 - (U) s2)
842 ovf = s2 < 0 ? res < s1 : res > s2 (or jump on overflow)
845 ovf = res < u1 (or jump on carry, but RTL opts will handle it)
848 ovf = res > u1 (or jump on carry, but RTL opts will handle it)
850 res = (S) ((U) s1 + u2)
851 ovf = ((U) res ^ sgn) < u2
856 ovf = t1 < 0 ? t2 > s1 : t2 < s1 (or jump on overflow)
858 res = (S) ((U) s1 - u2)
859 ovf = u2 > ((U) s1 ^ sgn)
862 ovf = s1 < 0 || u2 > (U) s1
865 ovf = u1 >= ((U) s2 ^ sgn)
870 ovf = s2 < 0 ? (S) t2 < (S) t1 : (S) t2 > (S) t1 (or jump on overflow)
872 res = (U) s1 + (U) s2
873 ovf = s2 < 0 ? (s1 | (S) res) < 0) : (s1 & (S) res) < 0)
876 ovf = (U) res < u2 || res < 0
879 ovf = u1 >= u2 ? res < 0 : res >= 0
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
);
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
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
);
923 delete_insns_since (last
);
926 /* Compute the operation. On RTL level, the addition is always
928 res
= expand_binop (mode
, code
== PLUS_EXPR
? add_optab
: sub_optab
,
929 op0
, op1
, NULL_RTX
, false, OPTAB_LIB_WIDEN
);
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
)))
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 ());
950 if (!uns0_p
&& uns1_p
&& !unsr_p
)
952 /* Compute the operation. On RTL level, the addition is always
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 ());
965 if (code
== PLUS_EXPR
&& !uns0_p
&& uns1_p
&& unsr_p
)
967 op1
= expand_binop (mode
, add_optab
, op1
, sgn
, NULL_RTX
, false,
969 /* As we've changed op1, we have to avoid using the value range
970 for the original argument. */
971 arg1
= error_mark_node
;
977 if (code
== MINUS_EXPR
&& uns0_p
&& !uns1_p
&& unsr_p
)
979 op0
= expand_binop (mode
, add_optab
, op0
, sgn
, NULL_RTX
, false,
981 /* As we've changed op0, we have to avoid using the value range
982 for the original argument. */
983 arg0
= error_mark_node
;
989 if (code
== MINUS_EXPR
&& !uns0_p
&& uns1_p
&& unsr_p
)
991 /* Compute the operation. On RTL level, the addition is always
993 res
= expand_binop (mode
, sub_optab
, op0
, op1
, NULL_RTX
, false,
995 int pos_neg
= get_range_pos_neg (arg0
);
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
;
1009 if (code
== MINUS_EXPR
&& uns0_p
&& !uns1_p
&& !unsr_p
)
1011 /* Compute the operation. On RTL level, the addition is always
1013 res
= expand_binop (mode
, sub_optab
, op0
, op1
, NULL_RTX
, false,
1015 rtx tem
= expand_binop (mode
, add_optab
, op1
, sgn
, NULL_RTX
, false,
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
;
1023 if (code
== PLUS_EXPR
&& uns0_p
&& uns1_p
&& !unsr_p
)
1025 /* Compute the operation. On RTL level, the addition is always
1027 res
= expand_binop (mode
, add_optab
, op0
, op1
, NULL_RTX
, false,
1029 do_compare_rtx_and_jump (res
, const0_rtx
, LT
, false, mode
, NULL_RTX
,
1030 NULL
, do_error
, profile_probability::very_unlikely ());
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
))
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
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
);
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 ());
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,
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,
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
;
1096 if (code
== MINUS_EXPR
&& uns0_p
&& uns1_p
&& !unsr_p
)
1098 /* Compute the operation. On RTL level, the addition is always
1100 res
= expand_binop (mode
, sub_optab
, op0
, op1
, NULL_RTX
, false,
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 */
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
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
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
);
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. */
1173 /* Compute op0 ^ op1 (operands have opposite sign). */
1174 rtx op_xor
= expand_binop (mode
, xor_optab
, op0
, op1
, NULL_RTX
, false,
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,
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,
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,
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. */
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 ());
1214 emit_label (do_error
);
1217 /* Expand the ubsan builtin call. */
1219 fn
= ubsan_build_overflow_builtin (code
, loc
, TREE_TYPE (arg0
),
1223 do_pending_stack_adjust ();
1226 expand_arith_set_overflow (lhs
, target
);
1229 emit_label (done_label
);
1234 expand_ubsan_result_store (target
, res
);
1238 res
= expand_binop (mode
, add_optab
, res
, sgn
, NULL_RTX
, false,
1241 expand_arith_overflow_result_store (lhs
, target
, mode
, res
);
1246 /* Add negate overflow checking to the statement STMT. */
1249 expand_neg_overflow (location_t loc
, tree lhs
, tree arg1
, bool is_ubsan
,
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
));
1266 target
= expand_expr (lhs
, NULL_RTX
, VOIDmode
, EXPAND_WRITE
);
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
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
);
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
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
);
1314 /* Expand the ubsan builtin call. */
1316 fn
= ubsan_build_overflow_builtin (NEGATE_EXPR
, loc
, TREE_TYPE (arg1
),
1317 arg1
, NULL_TREE
, datap
);
1320 do_pending_stack_adjust ();
1323 expand_arith_set_overflow (lhs
, target
);
1326 emit_label (done_label
);
1331 expand_ubsan_result_store (target
, res
);
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. */
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
)
1348 if (find_widening_optab_handler (smul_widen_optab
, wmode
, mode
)
1349 != CODE_FOR_nothing
)
1352 rtx_insn
*last
= get_last_insn ();
1353 if (CONSTANT_P (op0
))
1354 op0
= convert_modes (wmode
, mode
, op0
, uns
);
1356 op0
= gen_raw_REG (wmode
, LAST_VIRTUAL_REGISTER
+ 1);
1357 if (CONSTANT_P (op1
))
1358 op1
= convert_modes (wmode
, mode
, op1
, uns
);
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. */
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
,
1375 rtx_code_label
*done_label
, *do_error
;
1376 rtx target
= NULL_RTX
;
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
));
1391 target
= expand_expr (lhs
, NULL_RTX
, VOIDmode
, EXPAND_WRITE
);
1393 write_complex_part (target
, const0_rtx
, true);
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.
1415 res = (S) ((U) s1 * (U) s2)
1416 ovf = main_ovf (false)
1419 ovf = main_ovf (true)
1422 ovf = (s1 < 0 && u2) || main_ovf (true)
1425 ovf = res < 0 || main_ovf (true)
1427 res = (S) ((U) s1 * u2)
1428 ovf = (S) u2 >= 0 ? main_ovf (false)
1429 : (s1 != 0 && (s1 != -1 || u2 != (U) res))
1431 t1 = (s1 & s2) < 0 ? (-(U) s1) : ((U) s1)
1432 t2 = (s1 & s2) < 0 ? (-(U) s2) : ((U) s2)
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
);
1447 int pos_neg0
= get_range_pos_neg (arg0
);
1448 int pos_neg1
= get_range_pos_neg (arg1
);
1451 if (!uns0_p
&& uns1_p
&& unsr_p
)
1456 /* If s1 is non-negative, just perform normal u1 * u2 -> ur. */
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
;
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
;
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
1488 ovf = (S) res < 0 */
1489 struct separate_ops ops
;
1490 ops
.code
= MULT_EXPR
;
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
;
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
);
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. */
1531 /* Rest of handling of this case after res is computed. */
1536 if (!uns0_p
&& uns1_p
&& !unsr_p
)
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
;
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 ());
1559 prec
= GET_MODE_PRECISION (mode
);
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
;
1566 /* Rest of handling of this case after res is computed. */
1574 if (!uns0_p
&& !uns1_p
&& unsr_p
)
1577 switch (pos_neg0
| pos_neg1
)
1579 case 1: /* Both operands known to be non-negative. */
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
1586 arg0
= error_mark_node
;
1587 arg1
= error_mark_node
;
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
;
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
;
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
1626 ovf = (S) res < 0 */
1627 struct separate_ops ops
;
1628 ops
.code
= MULT_EXPR
;
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
;
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
;
1645 rop0
= gen_reg_rtx (mode
);
1646 rop1
= gen_reg_rtx (mode
);
1647 emit_move_insn (rop0
, op0
);
1648 emit_move_insn (rop1
, op1
);
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,
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
,
1661 emit_move_insn (op1
, expand_unop (mode
, neg_optab
, op1
,
1663 /* Avoid looking at arg0/arg1 ranges, as we might have changed
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,
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. */
1679 do_compare_rtx_and_jump (op0
, const0_rtx
, EQ
, true, mode
, NULL_RTX
,
1680 NULL
, do_main_label
,
1681 profile_probability::very_unlikely ());
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
);
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
);
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. */
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
);
1732 upper
= expand_shift (RSHIFT_EXPR
, mode
, opn0
,
1733 GET_MODE_PRECISION (mode
) - cnt
,
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
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
);
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
;
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. */
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
)
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
))
1801 ops
.code
= WIDEN_MULT_EXPR
;
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
,
1808 hipart
= convert_modes (mode
, wmode
, hipart
, uns
);
1809 res
= convert_modes (mode
, wmode
, res
, 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 ());
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,
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)
1834 ops
.code
= MULT_HIGHPART_EXPR
;
1837 rtx hipart
= expand_expr_real_2 (&ops
, NULL_RTX
, mode
,
1839 ops
.code
= MULT_EXPR
;
1840 res
= expand_expr_real_2 (&ops
, NULL_RTX
, mode
, EXPAND_NORMAL
);
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 ());
1849 rtx signbit
= expand_shift (RSHIFT_EXPR
, mode
, res
, prec
- 1,
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
,
1875 hipart0
= convert_modes (hmode
, mode
, hipart0
, uns
);
1876 rtx lopart0
= convert_modes (hmode
, mode
, op0
, uns
);
1877 rtx signbit0
= const0_rtx
;
1879 signbit0
= expand_shift (RSHIFT_EXPR
, hmode
, lopart0
, hprec
- 1,
1881 rtx hipart1
= expand_shift (RSHIFT_EXPR
, mode
, op1
, hprec
,
1883 hipart1
= convert_modes (hmode
, mode
, hipart1
, uns
);
1884 rtx lopart1
= convert_modes (hmode
, mode
, op1
, uns
);
1885 rtx signbit1
= const0_rtx
;
1887 signbit1
= expand_shift (RSHIFT_EXPR
, hmode
, lopart1
, hprec
- 1,
1890 res
= gen_reg_rtx (mode
);
1892 /* True if op0 resp. op1 are known to be in the range of
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
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. */
1908 else if (pos_neg0
== 2)
1912 else if (pos_neg1
== 2)
1915 unsigned int mprec0
= prec
;
1916 if (arg0
!= error_mark_node
)
1917 mprec0
= get_min_precision (arg0
, sign
);
1918 if (mprec0
<= hprec
)
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
)
1927 else if (!uns
&& mprec1
<= hprec
+ 1)
1928 op1_medium_p
= true;
1930 int smaller_sign
= 1;
1931 int larger_sign
= 1;
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
;
1949 do_compare_rtx_and_jump (signbit0
, hipart0
, NE
, true, hmode
,
1950 NULL_RTX
, NULL
, large_op0
,
1951 profile_probability::unlikely ());
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
;
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
);
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
2004 We perform lopart0 * lopart1 and lopart * hipart widening
2006 tree halfutype
= build_nonstandard_integer_type (hprec
, 1);
2007 ops
.op0
= make_tree (halfutype
, lopart0
);
2008 ops
.op1
= make_tree (halfutype
, lopart1
);
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
);
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
,
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
,
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
,
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
,
2062 hipartloxhi
= convert_modes (hmode
, mode
, hipartloxhi
, 0);
2063 rtx signbitloxhi
= const0_rtx
;
2065 signbitloxhi
= expand_shift (RSHIFT_EXPR
, hmode
,
2066 convert_modes (hmode
, mode
,
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
,
2077 tem
= convert_modes (mode
, hmode
,
2078 convert_modes (hmode
, mode
, lo0xlo1
, 1), 1);
2080 tem
= expand_simple_binop (mode
, IOR
, loxhishifted
, 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
);
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 ());
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
2159 gcc_assert (!is_ubsan
);
2160 ops
.code
= MULT_EXPR
;
2162 res
= expand_expr_real_2 (&ops
, NULL_RTX
, mode
, EXPAND_NORMAL
);
2163 emit_jump (done_label
);
2168 emit_label (do_error
);
2171 /* Expand the ubsan builtin call. */
2173 fn
= ubsan_build_overflow_builtin (MULT_EXPR
, loc
, TREE_TYPE (arg0
),
2177 do_pending_stack_adjust ();
2180 expand_arith_set_overflow (lhs
, target
);
2183 emit_label (done_label
);
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
);
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
);
2217 expand_ubsan_result_store (target
, res
);
2219 expand_arith_overflow_result_store (lhs
, target
, mode
, res
);
2223 /* Expand UBSAN_CHECK_* internal function if it has vector operands. */
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);
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
))
2253 resv
= make_tree (TREE_TYPE (lhs
), lhsr
);
2256 resvr
= assign_temp (TREE_TYPE (lhs
), 1, 1);
2257 resv
= make_tree (TREE_TYPE (lhs
), resvr
);
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
;
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
);
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
);
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
);
2313 res
= fold_build3_loc (loc
, BIT_FIELD_REF
, eltype
, resv
, sz
,
2319 expand_addsub_overflow (loc
, PLUS_EXPR
, res
, op0
, op1
,
2320 false, false, false, true, &data
);
2323 if (use_loop_p
? integer_zerop (arg0
) : integer_zerop (op0
))
2324 expand_neg_overflow (loc
, res
, op1
, true, &data
);
2326 expand_addsub_overflow (loc
, MINUS_EXPR
, res
, op0
, op1
,
2327 false, false, false, true, &data
);
2330 expand_mul_overflow (loc
, res
, op0
, op1
, false, false, false,
2339 struct separate_ops ops
;
2340 ops
.code
= PLUS_EXPR
;
2341 ops
.type
= TREE_TYPE (cntv
);
2343 ops
.op1
= build_int_cst (TREE_TYPE (cntv
), 1);
2344 ops
.op2
= NULL_TREE
;
2346 rtx ret
= expand_expr_real_2 (&ops
, cntvar
, TYPE_MODE (sizetype
),
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
;
2359 ops
.type
= TREE_TYPE (arg0
);
2362 ops
.op2
= NULL_TREE
;
2364 rtx ret
= expand_expr_real_2 (&ops
, lhsr
, TYPE_MODE (TREE_TYPE (arg0
)),
2367 emit_move_insn (lhsr
, ret
);
2370 emit_move_insn (lhsr
, resvr
);
2373 /* Expand UBSAN_CHECK_ADD call STMT. */
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
);
2385 expand_addsub_overflow (loc
, PLUS_EXPR
, lhs
, arg0
, arg1
,
2386 false, false, false, true, NULL
);
2389 /* Expand UBSAN_CHECK_SUB call STMT. */
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
);
2403 expand_addsub_overflow (loc
, MINUS_EXPR
, lhs
, arg0
, arg1
,
2404 false, false, false, true, NULL
);
2407 /* Expand UBSAN_CHECK_MUL call STMT. */
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
);
2419 expand_mul_overflow (loc
, lhs
, arg0
, arg1
, false, false, false, true,
2423 /* Helper function for {ADD,SUB,MUL}_OVERFLOW call stmt expansion. */
2426 expand_arith_overflow (enum tree_code code
, gimple
*stmt
)
2428 tree lhs
= gimple_call_lhs (stmt
);
2429 if (lhs
== NULL_TREE
)
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)
2443 if (!uns1_p
&& get_range_pos_neg (arg1
) == 1)
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. */
2455 if (code
== MULT_EXPR
)
2456 precop
= prec0
+ prec1
+ (uns0_p
!= uns1_p
);
2459 if (uns0_p
== uns1_p
)
2460 precop
= MAX (prec0
, prec1
) + 1;
2462 precop
= MAX (prec0
+ 1, prec1
) + 1;
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
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
;
2484 ops
.op0
= fold_convert_loc (loc
, type
, arg0
);
2485 ops
.op1
= fold_convert_loc (loc
, type
, arg1
);
2486 ops
.op2
= NULL_TREE
;
2488 rtx tem
= expand_expr_real_2 (&ops
, NULL_RTX
, mode
, EXPAND_NORMAL
);
2489 expand_arith_overflow_result_store (lhs
, target
, mode
, tem
);
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
);
2510 if (integer_zerop (arg0
) && !unsr_p
)
2512 expand_neg_overflow (loc
, lhs
, arg1
, false, NULL
);
2517 expand_addsub_overflow (loc
, code
, lhs
, arg0
, arg1
, unsr_p
,
2518 unsr_p
, unsr_p
, false, NULL
);
2521 expand_mul_overflow (loc
, lhs
, arg0
, arg1
, unsr_p
,
2522 unsr_p
, unsr_p
, false, NULL
);
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
),
2537 p
= TYPE_PRECISION (optype
);
2541 unsr_p
= TYPE_UNSIGNED (optype
);
2547 if (prec0
<= precres
&& prec1
<= precres
)
2552 types
[0] = build_nonstandard_integer_type (precres
, 0);
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
);
2566 expand_mul_overflow (loc
, lhs
, arg0
, arg1
, unsr_p
,
2567 uns0_p
, uns1_p
, false, NULL
);
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
),
2579 p
= TYPE_PRECISION (optype
);
2583 unsr_p
= TYPE_UNSIGNED (optype
);
2594 /* Expand ADD_OVERFLOW STMT. */
2597 expand_ADD_OVERFLOW (internal_fn
, gcall
*stmt
)
2599 expand_arith_overflow (PLUS_EXPR
, stmt
);
2602 /* Expand SUB_OVERFLOW STMT. */
2605 expand_SUB_OVERFLOW (internal_fn
, gcall
*stmt
)
2607 expand_arith_overflow (MINUS_EXPR
, stmt
);
2610 /* Expand MUL_OVERFLOW STMT. */
2613 expand_MUL_OVERFLOW (internal_fn
, gcall
*stmt
)
2615 expand_arith_overflow (MULT_EXPR
, stmt
);
2618 /* This should get folded in tree-vectorizer.c. */
2621 expand_LOOP_VECTORIZED (internal_fn
, gcall
*)
2626 /* This should get folded in tree-vectorizer.c. */
2629 expand_LOOP_DIST_ALIAS (internal_fn
, gcall
*)
2634 /* Return a memory reference of type TYPE for argument INDEX of STMT.
2635 Use argument INDEX + 1 to derive the second (TBAA) operand. */
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
);
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
;
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. */
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
;
2687 maskt
= gimple_call_arg (stmt
, 2);
2688 lhs
= gimple_call_lhs (stmt
);
2689 if (lhs
== NULL_TREE
)
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
));
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
)));
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. */
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
;
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
));
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
)));
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. */
2767 expand_vec_cond_optab_fn (internal_fn
, gcall
*stmt
, convert_optab optab
)
2769 class expand_operand ops
[6];
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
);
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. */
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. */
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
)),
2871 if (maybe_expand_insn (icode
, 3, ops
))
2873 emit_move_insn (target
, temp
);
2881 expand_ABNORMAL_DISPATCHER (internal_fn
, gcall
*)
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 ());
2892 tree lhs
= gimple_call_lhs (stmt
);
2894 target
= expand_expr (lhs
, NULL_RTX
, VOIDmode
, EXPAND_WRITE
);
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. */
2906 expand_VA_ARG (internal_fn
, gcall
*)
2911 /* IFN_VEC_CONVERT is supposed to be expanded at pass_lower_vector. So this
2912 dummy function should never be called. */
2915 expand_VEC_CONVERT (internal_fn
, gcall
*)
2920 /* Expand the IFN_UNIQUE function according to its first argument. */
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));
2934 case IFN_UNIQUE_UNSPEC
:
2935 if (targetm
.have_unique ())
2936 pattern
= targetm
.gen_unique ();
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
;
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
);
2955 pattern
= targetm
.gen_oacc_join (target
, data_dep
, axis
);
2963 emit_insn (pattern
);
2966 /* The size of an OpenACC compute dimension. */
2969 expand_GOACC_DIM_SIZE (internal_fn
, gcall
*stmt
)
2971 tree lhs
= gimple_call_lhs (stmt
);
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
));
2984 emit_move_insn (target
, GEN_INT (1));
2987 /* The position of an OpenACC execution engine along one compute axis. */
2990 expand_GOACC_DIM_POS (internal_fn
, gcall
*stmt
)
2992 tree lhs
= gimple_call_lhs (stmt
);
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
));
3005 emit_move_insn (target
, const0_rtx
);
3008 /* This is expanded by oacc_device_lower pass. */
3011 expand_GOACC_LOOP (internal_fn
, gcall
*)
3016 /* This is expanded by oacc_device_lower pass. */
3019 expand_GOACC_REDUCTION (internal_fn
, gcall
*)
3024 /* This is expanded by oacc_device_lower pass. */
3027 expand_GOACC_TILE (internal_fn
, gcall
*)
3032 /* Set errno to EDOM. */
3035 expand_SET_EDOM (internal_fn
, gcall
*)
3038 #ifdef GEN_ERRNO_RTX
3039 rtx errno_rtx
= GEN_ERRNO_RTX
;
3041 rtx errno_rtx
= gen_rtx_MEM (word_mode
, gen_rtx_SYMBOL_REF (Pmode
, "errno"));
3043 emit_move_insn (errno_rtx
,
3044 gen_int_mode (TARGET_EDOM
, GET_MODE (errno_rtx
)));
3050 /* Expand atomic bit test and set. */
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. */
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. */
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. */
3077 expand_ATOMIC_COMPARE_EXCHANGE (internal_fn
, gcall
*call
)
3079 expand_ifn_atomic_compare_exchange (call
);
3082 /* Expand LAUNDER to assignment, lhs = arg0. */
3085 expand_LAUNDER (internal_fn
, gcall
*call
)
3087 tree lhs
= gimple_call_lhs (call
);
3092 expand_assignment (lhs
, gimple_call_arg (call
, 0), false);
3095 /* Expand {MASK_,}SCATTER_STORE{S,U} call CALL using optab OPTAB. */
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];
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. */
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
);
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. */
3171 contains_call_div_mod (rtx_insn
*insn
)
3173 subrtx_iterator::array_type array
;
3174 for (; insn
; insn
= NEXT_INSN (insn
))
3177 else if (INSN_P (insn
))
3178 FOR_EACH_SUBRTX (iter
, array
, PATTERN (insn
), NONCONST
)
3179 switch (GET_CODE (*iter
))
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. */
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
3225 scalar_int_mode int_mode
;
3226 if (remainder
== NULL_RTX
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
),
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
),
3259 delete_insns_since (last
);
3262 if (remainder
== NULL_RTX
)
3264 struct separate_ops ops
;
3265 ops
.code
= TRUNC_DIV_EXPR
;
3267 ops
.op0
= make_tree (ops
.type
, op0
);
3269 ops
.op2
= NULL_TREE
;
3270 ops
.location
= gimple_location (call_stmt
);
3272 quotient
= expand_expr_real_2 (&ops
, NULL_RTX
, mode
, EXPAND_NORMAL
);
3273 if (contains_call_div_mod (get_insns ()))
3274 quotient
= NULL_RTX
;
3277 ops
.code
= TRUNC_MOD_EXPR
;
3278 remainder
= expand_expr_real_2 (&ops
, NULL_RTX
, mode
,
3280 if (contains_call_div_mod (get_insns ()))
3281 remainder
= NULL_RTX
;
3284 insns
= get_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 "ient
, &remainder
);
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
);
3318 expand_NOP (internal_fn
, gcall
*)
3320 /* Nothing. But it shouldn't really prevail. */
3323 /* Coroutines, all should have been processed at this stage. */
3326 expand_CO_FRAME (internal_fn
, gcall
*)
3332 expand_CO_YIELD (internal_fn
, gcall
*)
3338 expand_CO_SUSPN (internal_fn
, gcall
*)
3344 expand_CO_ACTOR (internal_fn
, gcall
*)
3349 /* Expand a call to FN using the operands in STMT. FN has a single
3350 output operand and NARGS input operands. */
3353 expand_direct_optab_fn (internal_fn fn
, gcall
*stmt
, direct_optab optab
,
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
;
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. */
3371 if (dest
&& GET_CODE (dest
) == SUBREG
&& SUBREG_PROMOTED_VAR_P (dest
))
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
));
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
);
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. */
3422 expand_while_optab_fn (internal_fn
, gcall
*stmt
, convert_optab optab
)
3424 expand_operand ops
[3];
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. */
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. */
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
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
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. */
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. */
3579 direct_internal_fn_optab (internal_fn fn
, tree_pair types
)
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"
3600 /* Return the optab used by internal function FN. */
3603 direct_internal_fn_optab (internal_fn 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"
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
3625 direct_internal_fn_supported_p (internal_fn fn
, tree_pair types
,
3626 optimization_type opt_type
)
3630 #define DEF_INTERNAL_FN(CODE, FLAGS, FNSPEC) \
3631 case IFN_##CODE: break;
3632 #define DEF_INTERNAL_OPTAB_FN(CODE, FLAGS, OPTAB, TYPE) \
3634 return direct_##TYPE##_optab_supported_p (OPTAB##_optab, types, \
3636 #define DEF_INTERNAL_SIGNED_OPTAB_FN(CODE, FLAGS, SELECTOR, SIGNED_OPTAB, \
3637 UNSIGNED_OPTAB, TYPE) \
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, \
3646 #include "internal-fn.def"
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. */
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. */
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
)
3716 /* Return true if IFN_SET_EDOM is supported. */
3719 set_edom_supported_p (void)
3728 #define DEF_INTERNAL_OPTAB_FN(CODE, FLAGS, OPTAB, TYPE) \
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) \
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
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. */
3789 get_conditional_internal_fn (tree_code code
)
3793 #define CASE(CODE, IFN) case CODE: return IFN;
3794 FOR_EACH_CODE_MAPPING(CASE
)
3801 /* If IFN implements the conditional form of a tree code, return that
3802 tree code, otherwise return ERROR_MARK. */
3805 conditional_internal_fn_code (internal_fn ifn
)
3809 #define CASE(CODE, IFN) case IFN: return CODE;
3810 FOR_EACH_CODE_MAPPING(CASE
)
3817 /* Invoke T(IFN) for each internal function IFN that also has an
3819 #define FOR_EACH_COND_FN_PAIR(T) \
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. */
3840 get_conditional_internal_fn (internal_fn fn
)
3844 #define CASE(NAME) case IFN_##NAME: return IFN_COND_##NAME;
3845 FOR_EACH_COND_FN_PAIR(CASE
)
3852 /* If IFN implements the conditional form of an unconditional internal
3853 function, return that unconditional function, otherwise return IFN_LAST. */
3856 get_unconditional_internal_fn (internal_fn ifn
)
3860 #define CASE(NAME) case IFN_COND_##NAME: return IFN_##NAME;
3861 FOR_EACH_COND_FN_PAIR(CASE
)
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. */
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
;
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);
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
;
3924 /* Return true if IFN is some form of load from memory. */
3927 internal_load_fn_p (internal_fn fn
)
3932 case IFN_LOAD_LANES
:
3933 case IFN_MASK_LOAD_LANES
:
3934 case IFN_GATHER_LOAD
:
3935 case IFN_MASK_GATHER_LOAD
:
3944 /* Return true if IFN is some form of store to memory. */
3947 internal_store_fn_p (internal_fn 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
:
3964 /* Return true if IFN is some form of gather load or scatter store. */
3967 internal_gather_scatter_fn_p (internal_fn fn
)
3971 case IFN_GATHER_LOAD
:
3972 case IFN_MASK_GATHER_LOAD
:
3973 case IFN_SCATTER_STORE
:
3974 case IFN_MASK_SCATTER_STORE
:
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
)
3991 case IFN_MASK_LOAD_LANES
:
3992 case IFN_MASK_STORE
:
3993 case IFN_MASK_STORE_LANES
:
3996 case IFN_MASK_GATHER_LOAD
:
3997 case IFN_MASK_SCATTER_STORE
:
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
)
4014 case IFN_MASK_STORE
:
4015 case IFN_MASK_STORE_LANES
:
4016 case IFN_SCATTER_STORE
:
4017 case IFN_MASK_SCATTER_STORE
:
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. */
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
)))
4043 if (maybe_ne (TYPE_VECTOR_SUBPARTS (vector_type
),
4044 TYPE_VECTOR_SUBPARTS (offset_vector_type
)))
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. */
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
)
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. */
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. */
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. */
4096 vectorized_internal_fn_supported_p (internal_fn ifn
, tree type
)
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
));
4111 expand_PHI (internal_fn
, gcall
*)