2 Copyright (C) 2011-2023 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"
54 #include "gimple-range.h"
56 /* For lang_hooks.types.type_for_mode. */
57 #include "langhooks.h"
59 /* The names of each internal function, indexed by function number. */
60 const char *const internal_fn_name_array
[] = {
61 #define DEF_INTERNAL_FN(CODE, FLAGS, FNSPEC) #CODE,
62 #include "internal-fn.def"
66 /* The ECF_* flags of each internal function, indexed by function number. */
67 const int internal_fn_flags_array
[] = {
68 #define DEF_INTERNAL_FN(CODE, FLAGS, FNSPEC) FLAGS,
69 #include "internal-fn.def"
73 /* Return the internal function called NAME, or IFN_LAST if there's
77 lookup_internal_fn (const char *name
)
79 typedef hash_map
<nofree_string_hash
, internal_fn
> name_to_fn_map_type
;
80 static name_to_fn_map_type
*name_to_fn_map
;
84 name_to_fn_map
= new name_to_fn_map_type (IFN_LAST
);
85 for (unsigned int i
= 0; i
< IFN_LAST
; ++i
)
86 name_to_fn_map
->put (internal_fn_name (internal_fn (i
)),
89 internal_fn
*entry
= name_to_fn_map
->get (name
);
90 return entry
? *entry
: IFN_LAST
;
93 /* Fnspec of each internal function, indexed by function number. */
94 const_tree internal_fn_fnspec_array
[IFN_LAST
+ 1];
99 #define DEF_INTERNAL_FN(CODE, FLAGS, FNSPEC) \
100 if (FNSPEC) internal_fn_fnspec_array[IFN_##CODE] = \
101 build_string ((int) sizeof (FNSPEC) - 1, FNSPEC ? FNSPEC : "");
102 #include "internal-fn.def"
103 internal_fn_fnspec_array
[IFN_LAST
] = 0;
106 /* Create static initializers for the information returned by
107 direct_internal_fn. */
108 #define not_direct { -2, -2, false }
109 #define mask_load_direct { -1, 2, false }
110 #define load_lanes_direct { -1, -1, false }
111 #define mask_load_lanes_direct { -1, -1, false }
112 #define gather_load_direct { 3, 1, false }
113 #define len_load_direct { -1, -1, false }
114 #define mask_store_direct { 3, 2, false }
115 #define store_lanes_direct { 0, 0, false }
116 #define mask_store_lanes_direct { 0, 0, false }
117 #define vec_cond_mask_direct { 1, 0, false }
118 #define vec_cond_direct { 2, 0, false }
119 #define scatter_store_direct { 3, 1, false }
120 #define len_store_direct { 3, 3, false }
121 #define vec_set_direct { 3, 3, false }
122 #define unary_direct { 0, 0, true }
123 #define unary_convert_direct { -1, 0, true }
124 #define binary_direct { 0, 0, true }
125 #define ternary_direct { 0, 0, true }
126 #define cond_unary_direct { 1, 1, true }
127 #define cond_binary_direct { 1, 1, true }
128 #define cond_ternary_direct { 1, 1, true }
129 #define while_direct { 0, 2, false }
130 #define fold_extract_direct { 2, 2, false }
131 #define fold_left_direct { 1, 1, false }
132 #define mask_fold_left_direct { 1, 1, false }
133 #define check_ptrs_direct { 0, 0, false }
135 const direct_internal_fn_info direct_internal_fn_array
[IFN_LAST
+ 1] = {
136 #define DEF_INTERNAL_FN(CODE, FLAGS, FNSPEC) not_direct,
137 #define DEF_INTERNAL_OPTAB_FN(CODE, FLAGS, OPTAB, TYPE) TYPE##_direct,
138 #define DEF_INTERNAL_SIGNED_OPTAB_FN(CODE, FLAGS, SELECTOR, SIGNED_OPTAB, \
139 UNSIGNED_OPTAB, TYPE) TYPE##_direct,
140 #include "internal-fn.def"
144 /* Expand STMT using instruction ICODE. The instruction has NOUTPUTS
145 output operands and NINPUTS input operands, where NOUTPUTS is either
146 0 or 1. The output operand (if any) comes first, followed by the
147 NINPUTS input operands. */
150 expand_fn_using_insn (gcall
*stmt
, insn_code icode
, unsigned int noutputs
,
151 unsigned int ninputs
)
153 gcc_assert (icode
!= CODE_FOR_nothing
);
155 expand_operand
*ops
= XALLOCAVEC (expand_operand
, noutputs
+ ninputs
);
156 unsigned int opno
= 0;
157 rtx lhs_rtx
= NULL_RTX
;
158 tree lhs
= gimple_call_lhs (stmt
);
162 gcc_assert (noutputs
== 1);
164 lhs_rtx
= expand_expr (lhs
, NULL_RTX
, VOIDmode
, EXPAND_WRITE
);
166 /* Do not assign directly to a promoted subreg, since there is no
167 guarantee that the instruction will leave the upper bits of the
168 register in the state required by SUBREG_PROMOTED_SIGN. */
170 if (dest
&& GET_CODE (dest
) == SUBREG
&& SUBREG_PROMOTED_VAR_P (dest
))
172 create_output_operand (&ops
[opno
], dest
,
173 insn_data
[icode
].operand
[opno
].mode
);
179 for (unsigned int i
= 0; i
< ninputs
; ++i
)
181 tree rhs
= gimple_call_arg (stmt
, i
);
182 tree rhs_type
= TREE_TYPE (rhs
);
183 rtx rhs_rtx
= expand_normal (rhs
);
184 if (INTEGRAL_TYPE_P (rhs_type
))
185 create_convert_operand_from (&ops
[opno
], rhs_rtx
,
186 TYPE_MODE (rhs_type
),
187 TYPE_UNSIGNED (rhs_type
));
189 create_input_operand (&ops
[opno
], rhs_rtx
, TYPE_MODE (rhs_type
));
193 gcc_assert (opno
== noutputs
+ ninputs
);
194 expand_insn (icode
, opno
, ops
);
195 if (lhs_rtx
&& !rtx_equal_p (lhs_rtx
, ops
[0].value
))
197 /* If the return value has an integral type, convert the instruction
198 result to that type. This is useful for things that return an
199 int regardless of the size of the input. If the instruction result
200 is smaller than required, assume that it is signed.
202 If the return value has a nonintegral type, its mode must match
203 the instruction result. */
204 if (GET_CODE (lhs_rtx
) == SUBREG
&& SUBREG_PROMOTED_VAR_P (lhs_rtx
))
206 /* If this is a scalar in a register that is stored in a wider
207 mode than the declared mode, compute the result into its
208 declared mode and then convert to the wider mode. */
209 gcc_checking_assert (INTEGRAL_TYPE_P (TREE_TYPE (lhs
)));
210 rtx tmp
= convert_to_mode (GET_MODE (lhs_rtx
), ops
[0].value
, 0);
211 convert_move (SUBREG_REG (lhs_rtx
), tmp
,
212 SUBREG_PROMOTED_SIGN (lhs_rtx
));
214 else if (GET_MODE (lhs_rtx
) == GET_MODE (ops
[0].value
))
215 emit_move_insn (lhs_rtx
, ops
[0].value
);
218 gcc_checking_assert (INTEGRAL_TYPE_P (TREE_TYPE (lhs
)));
219 convert_move (lhs_rtx
, ops
[0].value
, 0);
224 /* ARRAY_TYPE is an array of vector modes. Return the associated insn
225 for load-lanes-style optab OPTAB, or CODE_FOR_nothing if none. */
227 static enum insn_code
228 get_multi_vector_move (tree array_type
, convert_optab optab
)
233 gcc_assert (TREE_CODE (array_type
) == ARRAY_TYPE
);
234 imode
= TYPE_MODE (array_type
);
235 vmode
= TYPE_MODE (TREE_TYPE (array_type
));
237 return convert_optab_handler (optab
, imode
, vmode
);
240 /* Expand LOAD_LANES call STMT using optab OPTAB. */
243 expand_load_lanes_optab_fn (internal_fn
, gcall
*stmt
, convert_optab optab
)
245 class expand_operand ops
[2];
249 lhs
= gimple_call_lhs (stmt
);
250 rhs
= gimple_call_arg (stmt
, 0);
251 type
= TREE_TYPE (lhs
);
253 target
= expand_expr (lhs
, NULL_RTX
, VOIDmode
, EXPAND_WRITE
);
254 mem
= expand_normal (rhs
);
256 gcc_assert (MEM_P (mem
));
257 PUT_MODE (mem
, TYPE_MODE (type
));
259 create_output_operand (&ops
[0], target
, TYPE_MODE (type
));
260 create_fixed_operand (&ops
[1], mem
);
261 expand_insn (get_multi_vector_move (type
, optab
), 2, ops
);
262 if (!rtx_equal_p (target
, ops
[0].value
))
263 emit_move_insn (target
, ops
[0].value
);
266 /* Expand STORE_LANES call STMT using optab OPTAB. */
269 expand_store_lanes_optab_fn (internal_fn
, gcall
*stmt
, convert_optab optab
)
271 class expand_operand ops
[2];
275 lhs
= gimple_call_lhs (stmt
);
276 rhs
= gimple_call_arg (stmt
, 0);
277 type
= TREE_TYPE (rhs
);
279 target
= expand_expr (lhs
, NULL_RTX
, VOIDmode
, EXPAND_WRITE
);
280 reg
= expand_normal (rhs
);
282 gcc_assert (MEM_P (target
));
283 PUT_MODE (target
, TYPE_MODE (type
));
285 create_fixed_operand (&ops
[0], target
);
286 create_input_operand (&ops
[1], reg
, TYPE_MODE (type
));
287 expand_insn (get_multi_vector_move (type
, optab
), 2, ops
);
291 expand_ANNOTATE (internal_fn
, gcall
*)
296 /* This should get expanded in omp_device_lower pass. */
299 expand_GOMP_USE_SIMT (internal_fn
, gcall
*)
304 /* This should get expanded in omp_device_lower pass. */
307 expand_GOMP_SIMT_ENTER (internal_fn
, gcall
*)
312 /* Allocate per-lane storage and begin non-uniform execution region. */
315 expand_GOMP_SIMT_ENTER_ALLOC (internal_fn
, gcall
*stmt
)
318 tree lhs
= gimple_call_lhs (stmt
);
320 target
= expand_expr (lhs
, NULL_RTX
, VOIDmode
, EXPAND_WRITE
);
322 target
= gen_reg_rtx (Pmode
);
323 rtx size
= expand_normal (gimple_call_arg (stmt
, 0));
324 rtx align
= expand_normal (gimple_call_arg (stmt
, 1));
325 class expand_operand ops
[3];
326 create_output_operand (&ops
[0], target
, Pmode
);
327 create_input_operand (&ops
[1], size
, Pmode
);
328 create_input_operand (&ops
[2], align
, Pmode
);
329 gcc_assert (targetm
.have_omp_simt_enter ());
330 expand_insn (targetm
.code_for_omp_simt_enter
, 3, ops
);
331 if (!rtx_equal_p (target
, ops
[0].value
))
332 emit_move_insn (target
, ops
[0].value
);
335 /* Deallocate per-lane storage and leave non-uniform execution region. */
338 expand_GOMP_SIMT_EXIT (internal_fn
, gcall
*stmt
)
340 gcc_checking_assert (!gimple_call_lhs (stmt
));
341 rtx arg
= expand_normal (gimple_call_arg (stmt
, 0));
342 class expand_operand ops
[1];
343 create_input_operand (&ops
[0], arg
, Pmode
);
344 gcc_assert (targetm
.have_omp_simt_exit ());
345 expand_insn (targetm
.code_for_omp_simt_exit
, 1, ops
);
348 /* Lane index on SIMT targets: thread index in the warp on NVPTX. On targets
349 without SIMT execution this should be expanded in omp_device_lower pass. */
352 expand_GOMP_SIMT_LANE (internal_fn
, gcall
*stmt
)
354 tree lhs
= gimple_call_lhs (stmt
);
358 rtx target
= expand_expr (lhs
, NULL_RTX
, VOIDmode
, EXPAND_WRITE
);
359 gcc_assert (targetm
.have_omp_simt_lane ());
360 emit_insn (targetm
.gen_omp_simt_lane (target
));
363 /* This should get expanded in omp_device_lower pass. */
366 expand_GOMP_SIMT_VF (internal_fn
, gcall
*)
371 /* This should get expanded in omp_device_lower pass. */
374 expand_GOMP_TARGET_REV (internal_fn
, gcall
*)
379 /* Lane index of the first SIMT lane that supplies a non-zero argument.
380 This is a SIMT counterpart to GOMP_SIMD_LAST_LANE, used to represent the
381 lane that executed the last iteration for handling OpenMP lastprivate. */
384 expand_GOMP_SIMT_LAST_LANE (internal_fn
, gcall
*stmt
)
386 tree lhs
= gimple_call_lhs (stmt
);
390 rtx target
= expand_expr (lhs
, NULL_RTX
, VOIDmode
, EXPAND_WRITE
);
391 rtx cond
= expand_normal (gimple_call_arg (stmt
, 0));
392 machine_mode mode
= TYPE_MODE (TREE_TYPE (lhs
));
393 class expand_operand ops
[2];
394 create_output_operand (&ops
[0], target
, mode
);
395 create_input_operand (&ops
[1], cond
, mode
);
396 gcc_assert (targetm
.have_omp_simt_last_lane ());
397 expand_insn (targetm
.code_for_omp_simt_last_lane
, 2, ops
);
398 if (!rtx_equal_p (target
, ops
[0].value
))
399 emit_move_insn (target
, ops
[0].value
);
402 /* Non-transparent predicate used in SIMT lowering of OpenMP "ordered". */
405 expand_GOMP_SIMT_ORDERED_PRED (internal_fn
, gcall
*stmt
)
407 tree lhs
= gimple_call_lhs (stmt
);
411 rtx target
= expand_expr (lhs
, NULL_RTX
, VOIDmode
, EXPAND_WRITE
);
412 rtx ctr
= expand_normal (gimple_call_arg (stmt
, 0));
413 machine_mode mode
= TYPE_MODE (TREE_TYPE (lhs
));
414 class expand_operand ops
[2];
415 create_output_operand (&ops
[0], target
, mode
);
416 create_input_operand (&ops
[1], ctr
, mode
);
417 gcc_assert (targetm
.have_omp_simt_ordered ());
418 expand_insn (targetm
.code_for_omp_simt_ordered
, 2, ops
);
419 if (!rtx_equal_p (target
, ops
[0].value
))
420 emit_move_insn (target
, ops
[0].value
);
423 /* "Or" boolean reduction across SIMT lanes: return non-zero in all lanes if
424 any lane supplies a non-zero argument. */
427 expand_GOMP_SIMT_VOTE_ANY (internal_fn
, gcall
*stmt
)
429 tree lhs
= gimple_call_lhs (stmt
);
433 rtx target
= expand_expr (lhs
, NULL_RTX
, VOIDmode
, EXPAND_WRITE
);
434 rtx cond
= expand_normal (gimple_call_arg (stmt
, 0));
435 machine_mode mode
= TYPE_MODE (TREE_TYPE (lhs
));
436 class expand_operand ops
[2];
437 create_output_operand (&ops
[0], target
, mode
);
438 create_input_operand (&ops
[1], cond
, mode
);
439 gcc_assert (targetm
.have_omp_simt_vote_any ());
440 expand_insn (targetm
.code_for_omp_simt_vote_any
, 2, ops
);
441 if (!rtx_equal_p (target
, ops
[0].value
))
442 emit_move_insn (target
, ops
[0].value
);
445 /* Exchange between SIMT lanes with a "butterfly" pattern: source lane index
446 is destination lane index XOR given offset. */
449 expand_GOMP_SIMT_XCHG_BFLY (internal_fn
, gcall
*stmt
)
451 tree lhs
= gimple_call_lhs (stmt
);
455 rtx target
= expand_expr (lhs
, NULL_RTX
, VOIDmode
, EXPAND_WRITE
);
456 rtx src
= expand_normal (gimple_call_arg (stmt
, 0));
457 rtx idx
= expand_normal (gimple_call_arg (stmt
, 1));
458 machine_mode mode
= TYPE_MODE (TREE_TYPE (lhs
));
459 class expand_operand ops
[3];
460 create_output_operand (&ops
[0], target
, mode
);
461 create_input_operand (&ops
[1], src
, mode
);
462 create_input_operand (&ops
[2], idx
, SImode
);
463 gcc_assert (targetm
.have_omp_simt_xchg_bfly ());
464 expand_insn (targetm
.code_for_omp_simt_xchg_bfly
, 3, ops
);
465 if (!rtx_equal_p (target
, ops
[0].value
))
466 emit_move_insn (target
, ops
[0].value
);
469 /* Exchange between SIMT lanes according to given source lane index. */
472 expand_GOMP_SIMT_XCHG_IDX (internal_fn
, gcall
*stmt
)
474 tree lhs
= gimple_call_lhs (stmt
);
478 rtx target
= expand_expr (lhs
, NULL_RTX
, VOIDmode
, EXPAND_WRITE
);
479 rtx src
= expand_normal (gimple_call_arg (stmt
, 0));
480 rtx idx
= expand_normal (gimple_call_arg (stmt
, 1));
481 machine_mode mode
= TYPE_MODE (TREE_TYPE (lhs
));
482 class expand_operand ops
[3];
483 create_output_operand (&ops
[0], target
, mode
);
484 create_input_operand (&ops
[1], src
, mode
);
485 create_input_operand (&ops
[2], idx
, SImode
);
486 gcc_assert (targetm
.have_omp_simt_xchg_idx ());
487 expand_insn (targetm
.code_for_omp_simt_xchg_idx
, 3, ops
);
488 if (!rtx_equal_p (target
, ops
[0].value
))
489 emit_move_insn (target
, ops
[0].value
);
492 /* This should get expanded in adjust_simduid_builtins. */
495 expand_GOMP_SIMD_LANE (internal_fn
, gcall
*)
500 /* This should get expanded in adjust_simduid_builtins. */
503 expand_GOMP_SIMD_VF (internal_fn
, gcall
*)
508 /* This should get expanded in adjust_simduid_builtins. */
511 expand_GOMP_SIMD_LAST_LANE (internal_fn
, gcall
*)
516 /* This should get expanded in adjust_simduid_builtins. */
519 expand_GOMP_SIMD_ORDERED_START (internal_fn
, gcall
*)
524 /* This should get expanded in adjust_simduid_builtins. */
527 expand_GOMP_SIMD_ORDERED_END (internal_fn
, gcall
*)
532 /* This should get expanded in the sanopt pass. */
535 expand_UBSAN_NULL (internal_fn
, gcall
*)
540 /* This should get expanded in the sanopt pass. */
543 expand_UBSAN_BOUNDS (internal_fn
, gcall
*)
548 /* This should get expanded in the sanopt pass. */
551 expand_UBSAN_VPTR (internal_fn
, gcall
*)
556 /* This should get expanded in the sanopt pass. */
559 expand_UBSAN_PTR (internal_fn
, gcall
*)
564 /* This should get expanded in the sanopt pass. */
567 expand_UBSAN_OBJECT_SIZE (internal_fn
, gcall
*)
572 /* This should get expanded in the sanopt pass. */
575 expand_HWASAN_CHECK (internal_fn
, gcall
*)
580 /* For hwasan stack tagging:
581 Clear tags on the dynamically allocated space.
582 For use after an object dynamically allocated on the stack goes out of
585 expand_HWASAN_ALLOCA_UNPOISON (internal_fn
, gcall
*gc
)
587 gcc_assert (Pmode
== ptr_mode
);
588 tree restored_position
= gimple_call_arg (gc
, 0);
589 rtx restored_rtx
= expand_expr (restored_position
, NULL_RTX
, VOIDmode
,
591 rtx func
= init_one_libfunc ("__hwasan_tag_memory");
592 rtx off
= expand_simple_binop (Pmode
, MINUS
, restored_rtx
,
593 stack_pointer_rtx
, NULL_RTX
, 0,
595 emit_library_call_value (func
, NULL_RTX
, LCT_NORMAL
, VOIDmode
,
596 virtual_stack_dynamic_rtx
, Pmode
,
597 HWASAN_STACK_BACKGROUND
, QImode
,
601 /* For hwasan stack tagging:
602 Return a tag to be used for a dynamic allocation. */
604 expand_HWASAN_CHOOSE_TAG (internal_fn
, gcall
*gc
)
606 tree tag
= gimple_call_lhs (gc
);
607 rtx target
= expand_expr (tag
, NULL_RTX
, VOIDmode
, EXPAND_NORMAL
);
608 machine_mode mode
= GET_MODE (target
);
609 gcc_assert (mode
== QImode
);
611 rtx base_tag
= targetm
.memtag
.extract_tag (hwasan_frame_base (), NULL_RTX
);
612 gcc_assert (base_tag
);
613 rtx tag_offset
= gen_int_mode (hwasan_current_frame_tag (), QImode
);
614 rtx chosen_tag
= expand_simple_binop (QImode
, PLUS
, base_tag
, tag_offset
,
615 target
, /* unsignedp = */1,
617 chosen_tag
= hwasan_truncate_to_tag_size (chosen_tag
, target
);
619 /* Really need to put the tag into the `target` RTX. */
620 if (chosen_tag
!= target
)
622 rtx temp
= chosen_tag
;
623 gcc_assert (GET_MODE (chosen_tag
) == mode
);
624 emit_move_insn (target
, temp
);
627 hwasan_increment_frame_tag ();
630 /* For hwasan stack tagging:
631 Tag a region of space in the shadow stack according to the base pointer of
632 an object on the stack. N.b. the length provided in the internal call is
633 required to be aligned to HWASAN_TAG_GRANULE_SIZE. */
635 expand_HWASAN_MARK (internal_fn
, gcall
*gc
)
637 gcc_assert (ptr_mode
== Pmode
);
638 HOST_WIDE_INT flag
= tree_to_shwi (gimple_call_arg (gc
, 0));
639 bool is_poison
= ((asan_mark_flags
)flag
) == ASAN_MARK_POISON
;
641 tree base
= gimple_call_arg (gc
, 1);
642 gcc_checking_assert (TREE_CODE (base
) == ADDR_EXPR
);
643 rtx base_rtx
= expand_normal (base
);
645 rtx tag
= is_poison
? HWASAN_STACK_BACKGROUND
646 : targetm
.memtag
.extract_tag (base_rtx
, NULL_RTX
);
647 rtx address
= targetm
.memtag
.untagged_pointer (base_rtx
, NULL_RTX
);
649 tree len
= gimple_call_arg (gc
, 2);
650 rtx r_len
= expand_normal (len
);
652 rtx func
= init_one_libfunc ("__hwasan_tag_memory");
653 emit_library_call (func
, LCT_NORMAL
, VOIDmode
, address
, Pmode
,
654 tag
, QImode
, r_len
, Pmode
);
657 /* For hwasan stack tagging:
658 Store a tag into a pointer. */
660 expand_HWASAN_SET_TAG (internal_fn
, gcall
*gc
)
662 gcc_assert (ptr_mode
== Pmode
);
663 tree g_target
= gimple_call_lhs (gc
);
664 tree g_ptr
= gimple_call_arg (gc
, 0);
665 tree g_tag
= gimple_call_arg (gc
, 1);
667 rtx ptr
= expand_normal (g_ptr
);
668 rtx tag
= expand_expr (g_tag
, NULL_RTX
, QImode
, EXPAND_NORMAL
);
669 rtx target
= expand_normal (g_target
);
671 rtx untagged
= targetm
.memtag
.untagged_pointer (ptr
, target
);
672 rtx tagged_value
= targetm
.memtag
.set_tag (untagged
, tag
, target
);
673 if (tagged_value
!= target
)
674 emit_move_insn (target
, tagged_value
);
677 /* This should get expanded in the sanopt pass. */
680 expand_ASAN_CHECK (internal_fn
, gcall
*)
685 /* This should get expanded in the sanopt pass. */
688 expand_ASAN_MARK (internal_fn
, gcall
*)
693 /* This should get expanded in the sanopt pass. */
696 expand_ASAN_POISON (internal_fn
, gcall
*)
701 /* This should get expanded in the sanopt pass. */
704 expand_ASAN_POISON_USE (internal_fn
, gcall
*)
709 /* This should get expanded in the tsan pass. */
712 expand_TSAN_FUNC_EXIT (internal_fn
, gcall
*)
717 /* This should get expanded in the lower pass. */
720 expand_FALLTHROUGH (internal_fn
, gcall
*call
)
722 error_at (gimple_location (call
),
723 "invalid use of attribute %<fallthrough%>");
726 /* Return minimum precision needed to represent all values
727 of ARG in SIGNed integral type. */
730 get_min_precision (tree arg
, signop sign
)
732 int prec
= TYPE_PRECISION (TREE_TYPE (arg
));
734 signop orig_sign
= sign
;
735 if (TREE_CODE (arg
) == INTEGER_CST
)
738 if (TYPE_SIGN (TREE_TYPE (arg
)) != sign
)
740 widest_int w
= wi::to_widest (arg
);
741 w
= wi::ext (w
, prec
, sign
);
742 p
= wi::min_precision (w
, sign
);
745 p
= wi::min_precision (wi::to_wide (arg
), sign
);
746 return MIN (p
, prec
);
748 while (CONVERT_EXPR_P (arg
)
749 && INTEGRAL_TYPE_P (TREE_TYPE (TREE_OPERAND (arg
, 0)))
750 && TYPE_PRECISION (TREE_TYPE (TREE_OPERAND (arg
, 0))) <= prec
)
752 arg
= TREE_OPERAND (arg
, 0);
753 if (TYPE_PRECISION (TREE_TYPE (arg
)) < prec
)
755 if (TYPE_UNSIGNED (TREE_TYPE (arg
)))
757 else if (sign
== UNSIGNED
&& get_range_pos_neg (arg
) != 1)
758 return prec
+ (orig_sign
!= sign
);
759 prec
= TYPE_PRECISION (TREE_TYPE (arg
));
762 return prec
+ (orig_sign
!= sign
);
764 if (CONVERT_EXPR_P (arg
)
765 && INTEGRAL_TYPE_P (TREE_TYPE (TREE_OPERAND (arg
, 0)))
766 && TYPE_PRECISION (TREE_TYPE (TREE_OPERAND (arg
, 0))) > prec
)
768 /* We have e.g. (unsigned short) y_2 where int y_2 = (int) x_1(D);
769 If y_2's min precision is smaller than prec, return that. */
770 int oprec
= get_min_precision (TREE_OPERAND (arg
, 0), sign
);
772 return oprec
+ (orig_sign
!= sign
);
774 if (TREE_CODE (arg
) != SSA_NAME
)
775 return prec
+ (orig_sign
!= sign
);
777 while (!get_global_range_query ()->range_of_expr (r
, arg
)
778 || r
.kind () != VR_RANGE
)
780 gimple
*g
= SSA_NAME_DEF_STMT (arg
);
781 if (is_gimple_assign (g
)
782 && CONVERT_EXPR_CODE_P (gimple_assign_rhs_code (g
)))
784 tree t
= gimple_assign_rhs1 (g
);
785 if (INTEGRAL_TYPE_P (TREE_TYPE (t
))
786 && TYPE_PRECISION (TREE_TYPE (t
)) <= prec
)
789 if (TYPE_PRECISION (TREE_TYPE (arg
)) < prec
)
791 if (TYPE_UNSIGNED (TREE_TYPE (arg
)))
793 else if (sign
== UNSIGNED
&& get_range_pos_neg (arg
) != 1)
794 return prec
+ (orig_sign
!= sign
);
795 prec
= TYPE_PRECISION (TREE_TYPE (arg
));
798 return prec
+ (orig_sign
!= sign
);
802 return prec
+ (orig_sign
!= sign
);
804 if (sign
== TYPE_SIGN (TREE_TYPE (arg
)))
806 int p1
= wi::min_precision (r
.lower_bound (), sign
);
807 int p2
= wi::min_precision (r
.upper_bound (), sign
);
809 prec
= MIN (prec
, p1
);
811 else if (sign
== UNSIGNED
&& !wi::neg_p (r
.lower_bound (), SIGNED
))
813 int p
= wi::min_precision (r
.upper_bound (), UNSIGNED
);
814 prec
= MIN (prec
, p
);
816 return prec
+ (orig_sign
!= sign
);
819 /* Helper for expand_*_overflow. Set the __imag__ part to true
820 (1 except for signed:1 type, in which case store -1). */
823 expand_arith_set_overflow (tree lhs
, rtx target
)
825 if (TYPE_PRECISION (TREE_TYPE (TREE_TYPE (lhs
))) == 1
826 && !TYPE_UNSIGNED (TREE_TYPE (TREE_TYPE (lhs
))))
827 write_complex_part (target
, constm1_rtx
, true, false);
829 write_complex_part (target
, const1_rtx
, true, false);
832 /* Helper for expand_*_overflow. Store RES into the __real__ part
833 of TARGET. If RES has larger MODE than __real__ part of TARGET,
834 set the __imag__ part to 1 if RES doesn't fit into it. Similarly
835 if LHS has smaller precision than its mode. */
838 expand_arith_overflow_result_store (tree lhs
, rtx target
,
839 scalar_int_mode mode
, rtx res
)
841 scalar_int_mode tgtmode
842 = as_a
<scalar_int_mode
> (GET_MODE_INNER (GET_MODE (target
)));
846 rtx_code_label
*done_label
= gen_label_rtx ();
847 int uns
= TYPE_UNSIGNED (TREE_TYPE (TREE_TYPE (lhs
)));
848 lres
= convert_modes (tgtmode
, mode
, res
, uns
);
849 gcc_assert (GET_MODE_PRECISION (tgtmode
) < GET_MODE_PRECISION (mode
));
850 do_compare_rtx_and_jump (res
, convert_modes (mode
, tgtmode
, lres
, uns
),
851 EQ
, true, mode
, NULL_RTX
, NULL
, done_label
,
852 profile_probability::very_likely ());
853 expand_arith_set_overflow (lhs
, target
);
854 emit_label (done_label
);
856 int prec
= TYPE_PRECISION (TREE_TYPE (TREE_TYPE (lhs
)));
857 int tgtprec
= GET_MODE_PRECISION (tgtmode
);
860 rtx_code_label
*done_label
= gen_label_rtx ();
861 int uns
= TYPE_UNSIGNED (TREE_TYPE (TREE_TYPE (lhs
)));
866 = immed_wide_int_const (wi::shifted_mask (0, prec
, false, tgtprec
),
868 lres
= expand_simple_binop (tgtmode
, AND
, res
, mask
, NULL_RTX
,
869 true, OPTAB_LIB_WIDEN
);
873 lres
= expand_shift (LSHIFT_EXPR
, tgtmode
, res
, tgtprec
- prec
,
875 lres
= expand_shift (RSHIFT_EXPR
, tgtmode
, lres
, tgtprec
- prec
,
878 do_compare_rtx_and_jump (res
, lres
,
879 EQ
, true, tgtmode
, NULL_RTX
, NULL
, done_label
,
880 profile_probability::very_likely ());
881 expand_arith_set_overflow (lhs
, target
);
882 emit_label (done_label
);
884 write_complex_part (target
, lres
, false, false);
887 /* Helper for expand_*_overflow. Store RES into TARGET. */
890 expand_ubsan_result_store (rtx target
, rtx res
)
892 if (GET_CODE (target
) == SUBREG
&& SUBREG_PROMOTED_VAR_P (target
))
893 /* If this is a scalar in a register that is stored in a wider mode
894 than the declared mode, compute the result into its declared mode
895 and then convert to the wider mode. Our value is the computed
897 convert_move (SUBREG_REG (target
), res
, SUBREG_PROMOTED_SIGN (target
));
899 emit_move_insn (target
, res
);
902 /* Add sub/add overflow checking to the statement STMT.
903 CODE says whether the operation is +, or -. */
906 expand_addsub_overflow (location_t loc
, tree_code code
, tree lhs
,
907 tree arg0
, tree arg1
, bool unsr_p
, bool uns0_p
,
908 bool uns1_p
, bool is_ubsan
, tree
*datap
)
910 rtx res
, target
= NULL_RTX
;
912 rtx_code_label
*done_label
= gen_label_rtx ();
913 rtx_code_label
*do_error
= gen_label_rtx ();
914 do_pending_stack_adjust ();
915 rtx op0
= expand_normal (arg0
);
916 rtx op1
= expand_normal (arg1
);
917 scalar_int_mode mode
= SCALAR_INT_TYPE_MODE (TREE_TYPE (arg0
));
918 int prec
= GET_MODE_PRECISION (mode
);
919 rtx sgn
= immed_wide_int_const (wi::min_value (prec
, SIGNED
), mode
);
923 gcc_assert (!unsr_p
&& !uns0_p
&& !uns1_p
);
927 target
= expand_expr (lhs
, NULL_RTX
, VOIDmode
, EXPAND_WRITE
);
929 write_complex_part (target
, const0_rtx
, true, false);
932 /* We assume both operands and result have the same precision
933 here (GET_MODE_BITSIZE (mode)), S stands for signed type
934 with that precision, U for unsigned type with that precision,
935 sgn for unsigned most significant bit in that precision.
936 s1 is signed first operand, u1 is unsigned first operand,
937 s2 is signed second operand, u2 is unsigned second operand,
938 sr is signed result, ur is unsigned result and the following
939 rules say how to compute result (which is always result of
940 the operands as if both were unsigned, cast to the right
941 signedness) and how to compute whether operation overflowed.
944 res = (S) ((U) s1 + (U) s2)
945 ovf = s2 < 0 ? res > s1 : res < s1 (or jump on overflow)
947 res = (S) ((U) s1 - (U) s2)
948 ovf = s2 < 0 ? res < s1 : res > s2 (or jump on overflow)
951 ovf = res < u1 (or jump on carry, but RTL opts will handle it)
954 ovf = res > u1 (or jump on carry, but RTL opts will handle it)
956 res = (S) ((U) s1 + u2)
957 ovf = ((U) res ^ sgn) < u2
962 ovf = t1 < 0 ? t2 > s1 : t2 < s1 (or jump on overflow)
964 res = (S) ((U) s1 - u2)
965 ovf = u2 > ((U) s1 ^ sgn)
968 ovf = s1 < 0 || u2 > (U) s1
971 ovf = u1 >= ((U) s2 ^ sgn)
976 ovf = s2 < 0 ? (S) t2 < (S) t1 : (S) t2 > (S) t1 (or jump on overflow)
978 res = (U) s1 + (U) s2
979 ovf = s2 < 0 ? (s1 | (S) res) < 0) : (s1 & (S) res) < 0)
982 ovf = (U) res < u2 || res < 0
985 ovf = u1 >= u2 ? res < 0 : res >= 0
987 res = (U) s1 - (U) s2
988 ovf = s2 >= 0 ? ((s1 | (S) res) < 0) : ((s1 & (S) res) < 0) */
990 if (code
== PLUS_EXPR
&& uns0_p
&& !uns1_p
)
992 /* PLUS_EXPR is commutative, if operand signedness differs,
993 canonicalize to the first operand being signed and second
994 unsigned to simplify following code. */
995 std::swap (op0
, op1
);
996 std::swap (arg0
, arg1
);
1001 /* u1 +- u2 -> ur */
1002 if (uns0_p
&& uns1_p
&& unsr_p
)
1004 insn_code icode
= optab_handler (code
== PLUS_EXPR
? uaddv4_optab
1005 : usubv4_optab
, mode
);
1006 if (icode
!= CODE_FOR_nothing
)
1008 class expand_operand ops
[4];
1009 rtx_insn
*last
= get_last_insn ();
1011 res
= gen_reg_rtx (mode
);
1012 create_output_operand (&ops
[0], res
, mode
);
1013 create_input_operand (&ops
[1], op0
, mode
);
1014 create_input_operand (&ops
[2], op1
, mode
);
1015 create_fixed_operand (&ops
[3], do_error
);
1016 if (maybe_expand_insn (icode
, 4, ops
))
1018 last
= get_last_insn ();
1019 if (profile_status_for_fn (cfun
) != PROFILE_ABSENT
1021 && any_condjump_p (last
)
1022 && !find_reg_note (last
, REG_BR_PROB
, 0))
1023 add_reg_br_prob_note (last
,
1024 profile_probability::very_unlikely ());
1025 emit_jump (done_label
);
1026 goto do_error_label
;
1029 delete_insns_since (last
);
1032 /* Compute the operation. On RTL level, the addition is always
1034 res
= expand_binop (mode
, code
== PLUS_EXPR
? add_optab
: sub_optab
,
1035 op0
, op1
, NULL_RTX
, false, OPTAB_LIB_WIDEN
);
1037 /* For PLUS_EXPR, the operation is commutative, so we can pick
1038 operand to compare against. For prec <= BITS_PER_WORD, I think
1039 preferring REG operand is better over CONST_INT, because
1040 the CONST_INT might enlarge the instruction or CSE would need
1041 to figure out we'd already loaded it into a register before.
1042 For prec > BITS_PER_WORD, I think CONST_INT might be more beneficial,
1043 as then the multi-word comparison can be perhaps simplified. */
1044 if (code
== PLUS_EXPR
1045 && (prec
<= BITS_PER_WORD
1046 ? (CONST_SCALAR_INT_P (op0
) && REG_P (op1
))
1047 : CONST_SCALAR_INT_P (op1
)))
1049 do_compare_rtx_and_jump (res
, tem
, code
== PLUS_EXPR
? GEU
: LEU
,
1050 true, mode
, NULL_RTX
, NULL
, done_label
,
1051 profile_probability::very_likely ());
1052 goto do_error_label
;
1055 /* s1 +- u2 -> sr */
1056 if (!uns0_p
&& uns1_p
&& !unsr_p
)
1058 /* Compute the operation. On RTL level, the addition is always
1060 res
= expand_binop (mode
, code
== PLUS_EXPR
? add_optab
: sub_optab
,
1061 op0
, op1
, NULL_RTX
, false, OPTAB_LIB_WIDEN
);
1062 rtx tem
= expand_binop (mode
, add_optab
,
1063 code
== PLUS_EXPR
? res
: op0
, sgn
,
1064 NULL_RTX
, false, OPTAB_LIB_WIDEN
);
1065 do_compare_rtx_and_jump (tem
, op1
, GEU
, true, mode
, NULL_RTX
, NULL
,
1066 done_label
, profile_probability::very_likely ());
1067 goto do_error_label
;
1071 if (code
== PLUS_EXPR
&& !uns0_p
&& uns1_p
&& unsr_p
)
1073 op1
= expand_binop (mode
, add_optab
, op1
, sgn
, NULL_RTX
, false,
1075 /* As we've changed op1, we have to avoid using the value range
1076 for the original argument. */
1077 arg1
= error_mark_node
;
1083 if (code
== MINUS_EXPR
&& uns0_p
&& !uns1_p
&& unsr_p
)
1085 op0
= expand_binop (mode
, add_optab
, op0
, sgn
, NULL_RTX
, false,
1087 /* As we've changed op0, we have to avoid using the value range
1088 for the original argument. */
1089 arg0
= error_mark_node
;
1095 if (code
== MINUS_EXPR
&& !uns0_p
&& uns1_p
&& unsr_p
)
1097 /* Compute the operation. On RTL level, the addition is always
1099 res
= expand_binop (mode
, sub_optab
, op0
, op1
, NULL_RTX
, false,
1101 int pos_neg
= get_range_pos_neg (arg0
);
1103 /* If ARG0 is known to be always negative, this is always overflow. */
1104 emit_jump (do_error
);
1105 else if (pos_neg
== 3)
1106 /* If ARG0 is not known to be always positive, check at runtime. */
1107 do_compare_rtx_and_jump (op0
, const0_rtx
, LT
, false, mode
, NULL_RTX
,
1108 NULL
, do_error
, profile_probability::very_unlikely ());
1109 do_compare_rtx_and_jump (op1
, op0
, LEU
, true, mode
, NULL_RTX
, NULL
,
1110 done_label
, profile_probability::very_likely ());
1111 goto do_error_label
;
1115 if (code
== MINUS_EXPR
&& uns0_p
&& !uns1_p
&& !unsr_p
)
1117 /* Compute the operation. On RTL level, the addition is always
1119 res
= expand_binop (mode
, sub_optab
, op0
, op1
, NULL_RTX
, false,
1121 rtx tem
= expand_binop (mode
, add_optab
, op1
, sgn
, NULL_RTX
, false,
1123 do_compare_rtx_and_jump (op0
, tem
, LTU
, true, mode
, NULL_RTX
, NULL
,
1124 done_label
, profile_probability::very_likely ());
1125 goto do_error_label
;
1129 if (code
== PLUS_EXPR
&& uns0_p
&& uns1_p
&& !unsr_p
)
1131 /* Compute the operation. On RTL level, the addition is always
1133 res
= expand_binop (mode
, add_optab
, op0
, op1
, NULL_RTX
, false,
1135 do_compare_rtx_and_jump (res
, const0_rtx
, LT
, false, mode
, NULL_RTX
,
1136 NULL
, do_error
, profile_probability::very_unlikely ());
1138 /* The operation is commutative, so we can pick operand to compare
1139 against. For prec <= BITS_PER_WORD, I think preferring REG operand
1140 is better over CONST_INT, because the CONST_INT might enlarge the
1141 instruction or CSE would need to figure out we'd already loaded it
1142 into a register before. For prec > BITS_PER_WORD, I think CONST_INT
1143 might be more beneficial, as then the multi-word comparison can be
1144 perhaps simplified. */
1145 if (prec
<= BITS_PER_WORD
1146 ? (CONST_SCALAR_INT_P (op1
) && REG_P (op0
))
1147 : CONST_SCALAR_INT_P (op0
))
1149 do_compare_rtx_and_jump (res
, tem
, GEU
, true, mode
, NULL_RTX
, NULL
,
1150 done_label
, profile_probability::very_likely ());
1151 goto do_error_label
;
1154 /* s1 +- s2 -> ur */
1155 if (!uns0_p
&& !uns1_p
&& unsr_p
)
1157 /* Compute the operation. On RTL level, the addition is always
1159 res
= expand_binop (mode
, code
== PLUS_EXPR
? add_optab
: sub_optab
,
1160 op0
, op1
, NULL_RTX
, false, OPTAB_LIB_WIDEN
);
1161 int pos_neg
= get_range_pos_neg (arg1
);
1162 if (code
== PLUS_EXPR
)
1164 int pos_neg0
= get_range_pos_neg (arg0
);
1165 if (pos_neg0
!= 3 && pos_neg
== 3)
1167 std::swap (op0
, op1
);
1174 tem
= expand_binop (mode
, ((pos_neg
== 1) ^ (code
== MINUS_EXPR
))
1175 ? and_optab
: ior_optab
,
1176 op0
, res
, NULL_RTX
, false, OPTAB_LIB_WIDEN
);
1177 do_compare_rtx_and_jump (tem
, const0_rtx
, GE
, false, mode
, NULL
,
1178 NULL
, done_label
, profile_probability::very_likely ());
1182 rtx_code_label
*do_ior_label
= gen_label_rtx ();
1183 do_compare_rtx_and_jump (op1
, const0_rtx
,
1184 code
== MINUS_EXPR
? GE
: LT
, false, mode
,
1185 NULL_RTX
, NULL
, do_ior_label
,
1186 profile_probability::even ());
1187 tem
= expand_binop (mode
, and_optab
, op0
, res
, NULL_RTX
, false,
1189 do_compare_rtx_and_jump (tem
, const0_rtx
, GE
, false, mode
, NULL_RTX
,
1190 NULL
, done_label
, profile_probability::very_likely ());
1191 emit_jump (do_error
);
1192 emit_label (do_ior_label
);
1193 tem
= expand_binop (mode
, ior_optab
, op0
, res
, NULL_RTX
, false,
1195 do_compare_rtx_and_jump (tem
, const0_rtx
, GE
, false, mode
, NULL_RTX
,
1196 NULL
, done_label
, profile_probability::very_likely ());
1198 goto do_error_label
;
1202 if (code
== MINUS_EXPR
&& uns0_p
&& uns1_p
&& !unsr_p
)
1204 /* Compute the operation. On RTL level, the addition is always
1206 res
= expand_binop (mode
, sub_optab
, op0
, op1
, NULL_RTX
, false,
1208 rtx_code_label
*op0_geu_op1
= gen_label_rtx ();
1209 do_compare_rtx_and_jump (op0
, op1
, GEU
, true, mode
, NULL_RTX
, NULL
,
1210 op0_geu_op1
, profile_probability::even ());
1211 do_compare_rtx_and_jump (res
, const0_rtx
, LT
, false, mode
, NULL_RTX
,
1212 NULL
, done_label
, profile_probability::very_likely ());
1213 emit_jump (do_error
);
1214 emit_label (op0_geu_op1
);
1215 do_compare_rtx_and_jump (res
, const0_rtx
, GE
, false, mode
, NULL_RTX
,
1216 NULL
, done_label
, profile_probability::very_likely ());
1217 goto do_error_label
;
1220 gcc_assert (!uns0_p
&& !uns1_p
&& !unsr_p
);
1222 /* s1 +- s2 -> sr */
1225 insn_code icode
= optab_handler (code
== PLUS_EXPR
? addv4_optab
1226 : subv4_optab
, mode
);
1227 if (icode
!= CODE_FOR_nothing
)
1229 class expand_operand ops
[4];
1230 rtx_insn
*last
= get_last_insn ();
1232 res
= gen_reg_rtx (mode
);
1233 create_output_operand (&ops
[0], res
, mode
);
1234 create_input_operand (&ops
[1], op0
, mode
);
1235 create_input_operand (&ops
[2], op1
, mode
);
1236 create_fixed_operand (&ops
[3], do_error
);
1237 if (maybe_expand_insn (icode
, 4, ops
))
1239 last
= get_last_insn ();
1240 if (profile_status_for_fn (cfun
) != PROFILE_ABSENT
1242 && any_condjump_p (last
)
1243 && !find_reg_note (last
, REG_BR_PROB
, 0))
1244 add_reg_br_prob_note (last
,
1245 profile_probability::very_unlikely ());
1246 emit_jump (done_label
);
1247 goto do_error_label
;
1250 delete_insns_since (last
);
1253 /* Compute the operation. On RTL level, the addition is always
1255 res
= expand_binop (mode
, code
== PLUS_EXPR
? add_optab
: sub_optab
,
1256 op0
, op1
, NULL_RTX
, false, OPTAB_LIB_WIDEN
);
1258 /* If we can prove that one of the arguments (for MINUS_EXPR only
1259 the second operand, as subtraction is not commutative) is always
1260 non-negative or always negative, we can do just one comparison
1261 and conditional jump. */
1262 int pos_neg
= get_range_pos_neg (arg1
);
1263 if (code
== PLUS_EXPR
)
1265 int pos_neg0
= get_range_pos_neg (arg0
);
1266 if (pos_neg0
!= 3 && pos_neg
== 3)
1268 std::swap (op0
, op1
);
1273 /* Addition overflows if and only if the two operands have the same sign,
1274 and the result has the opposite sign. Subtraction overflows if and
1275 only if the two operands have opposite sign, and the subtrahend has
1276 the same sign as the result. Here 0 is counted as positive. */
1279 /* Compute op0 ^ op1 (operands have opposite sign). */
1280 rtx op_xor
= expand_binop (mode
, xor_optab
, op0
, op1
, NULL_RTX
, false,
1283 /* Compute res ^ op1 (result and 2nd operand have opposite sign). */
1284 rtx res_xor
= expand_binop (mode
, xor_optab
, res
, op1
, NULL_RTX
, false,
1288 if (code
== PLUS_EXPR
)
1290 /* Compute (res ^ op1) & ~(op0 ^ op1). */
1291 tem
= expand_unop (mode
, one_cmpl_optab
, op_xor
, NULL_RTX
, false);
1292 tem
= expand_binop (mode
, and_optab
, res_xor
, tem
, NULL_RTX
, false,
1297 /* Compute (op0 ^ op1) & ~(res ^ op1). */
1298 tem
= expand_unop (mode
, one_cmpl_optab
, res_xor
, NULL_RTX
, false);
1299 tem
= expand_binop (mode
, and_optab
, op_xor
, tem
, NULL_RTX
, false,
1303 /* No overflow if the result has bit sign cleared. */
1304 do_compare_rtx_and_jump (tem
, const0_rtx
, GE
, false, mode
, NULL_RTX
,
1305 NULL
, done_label
, profile_probability::very_likely ());
1308 /* Compare the result of the operation with the first operand.
1309 No overflow for addition if second operand is positive and result
1310 is larger or second operand is negative and result is smaller.
1311 Likewise for subtraction with sign of second operand flipped. */
1313 do_compare_rtx_and_jump (res
, op0
,
1314 (pos_neg
== 1) ^ (code
== MINUS_EXPR
) ? GE
: LE
,
1315 false, mode
, NULL_RTX
, NULL
, done_label
,
1316 profile_probability::very_likely ());
1320 emit_label (do_error
);
1323 /* Expand the ubsan builtin call. */
1325 fn
= ubsan_build_overflow_builtin (code
, loc
, TREE_TYPE (arg0
),
1329 do_pending_stack_adjust ();
1332 expand_arith_set_overflow (lhs
, target
);
1335 emit_label (done_label
);
1340 expand_ubsan_result_store (target
, res
);
1344 res
= expand_binop (mode
, add_optab
, res
, sgn
, NULL_RTX
, false,
1347 expand_arith_overflow_result_store (lhs
, target
, mode
, res
);
1352 /* Add negate overflow checking to the statement STMT. */
1355 expand_neg_overflow (location_t loc
, tree lhs
, tree arg1
, bool is_ubsan
,
1360 rtx_code_label
*done_label
, *do_error
;
1361 rtx target
= NULL_RTX
;
1363 done_label
= gen_label_rtx ();
1364 do_error
= gen_label_rtx ();
1366 do_pending_stack_adjust ();
1367 op1
= expand_normal (arg1
);
1369 scalar_int_mode mode
= SCALAR_INT_TYPE_MODE (TREE_TYPE (arg1
));
1372 target
= expand_expr (lhs
, NULL_RTX
, VOIDmode
, EXPAND_WRITE
);
1374 write_complex_part (target
, const0_rtx
, true, false);
1377 enum insn_code icode
= optab_handler (negv3_optab
, mode
);
1378 if (icode
!= CODE_FOR_nothing
)
1380 class expand_operand ops
[3];
1381 rtx_insn
*last
= get_last_insn ();
1383 res
= gen_reg_rtx (mode
);
1384 create_output_operand (&ops
[0], res
, mode
);
1385 create_input_operand (&ops
[1], op1
, mode
);
1386 create_fixed_operand (&ops
[2], do_error
);
1387 if (maybe_expand_insn (icode
, 3, ops
))
1389 last
= get_last_insn ();
1390 if (profile_status_for_fn (cfun
) != PROFILE_ABSENT
1392 && any_condjump_p (last
)
1393 && !find_reg_note (last
, REG_BR_PROB
, 0))
1394 add_reg_br_prob_note (last
,
1395 profile_probability::very_unlikely ());
1396 emit_jump (done_label
);
1400 delete_insns_since (last
);
1401 icode
= CODE_FOR_nothing
;
1405 if (icode
== CODE_FOR_nothing
)
1407 /* Compute the operation. On RTL level, the addition is always
1409 res
= expand_unop (mode
, neg_optab
, op1
, NULL_RTX
, false);
1411 /* Compare the operand with the most negative value. */
1412 rtx minv
= expand_normal (TYPE_MIN_VALUE (TREE_TYPE (arg1
)));
1413 do_compare_rtx_and_jump (op1
, minv
, NE
, true, mode
, NULL_RTX
, NULL
,
1414 done_label
, profile_probability::very_likely ());
1417 emit_label (do_error
);
1420 /* Expand the ubsan builtin call. */
1422 fn
= ubsan_build_overflow_builtin (NEGATE_EXPR
, loc
, TREE_TYPE (arg1
),
1423 arg1
, NULL_TREE
, datap
);
1426 do_pending_stack_adjust ();
1429 expand_arith_set_overflow (lhs
, target
);
1432 emit_label (done_label
);
1437 expand_ubsan_result_store (target
, res
);
1439 expand_arith_overflow_result_store (lhs
, target
, mode
, res
);
1443 /* Return true if UNS WIDEN_MULT_EXPR with result mode WMODE and operand
1444 mode MODE can be expanded without using a libcall. */
1447 can_widen_mult_without_libcall (scalar_int_mode wmode
, scalar_int_mode mode
,
1448 rtx op0
, rtx op1
, bool uns
)
1450 if (find_widening_optab_handler (umul_widen_optab
, wmode
, mode
)
1451 != CODE_FOR_nothing
)
1454 if (find_widening_optab_handler (smul_widen_optab
, wmode
, mode
)
1455 != CODE_FOR_nothing
)
1458 rtx_insn
*last
= get_last_insn ();
1459 if (CONSTANT_P (op0
))
1460 op0
= convert_modes (wmode
, mode
, op0
, uns
);
1462 op0
= gen_raw_REG (wmode
, LAST_VIRTUAL_REGISTER
+ 1);
1463 if (CONSTANT_P (op1
))
1464 op1
= convert_modes (wmode
, mode
, op1
, uns
);
1466 op1
= gen_raw_REG (wmode
, LAST_VIRTUAL_REGISTER
+ 2);
1467 rtx ret
= expand_mult (wmode
, op0
, op1
, NULL_RTX
, uns
, true);
1468 delete_insns_since (last
);
1469 return ret
!= NULL_RTX
;
1472 /* Add mul overflow checking to the statement STMT. */
1475 expand_mul_overflow (location_t loc
, tree lhs
, tree arg0
, tree arg1
,
1476 bool unsr_p
, bool uns0_p
, bool uns1_p
, bool is_ubsan
,
1481 rtx_code_label
*done_label
, *do_error
;
1482 rtx target
= NULL_RTX
;
1484 enum insn_code icode
;
1486 done_label
= gen_label_rtx ();
1487 do_error
= gen_label_rtx ();
1489 do_pending_stack_adjust ();
1490 op0
= expand_normal (arg0
);
1491 op1
= expand_normal (arg1
);
1493 scalar_int_mode mode
= SCALAR_INT_TYPE_MODE (TREE_TYPE (arg0
));
1497 target
= expand_expr (lhs
, NULL_RTX
, VOIDmode
, EXPAND_WRITE
);
1499 write_complex_part (target
, const0_rtx
, true, false);
1503 gcc_assert (!unsr_p
&& !uns0_p
&& !uns1_p
);
1505 /* We assume both operands and result have the same precision
1506 here (GET_MODE_BITSIZE (mode)), S stands for signed type
1507 with that precision, U for unsigned type with that precision,
1508 sgn for unsigned most significant bit in that precision.
1509 s1 is signed first operand, u1 is unsigned first operand,
1510 s2 is signed second operand, u2 is unsigned second operand,
1511 sr is signed result, ur is unsigned result and the following
1512 rules say how to compute result (which is always result of
1513 the operands as if both were unsigned, cast to the right
1514 signedness) and how to compute whether operation overflowed.
1515 main_ovf (false) stands for jump on signed multiplication
1516 overflow or the main algorithm with uns == false.
1517 main_ovf (true) stands for jump on unsigned multiplication
1518 overflow or the main algorithm with uns == true.
1521 res = (S) ((U) s1 * (U) s2)
1522 ovf = main_ovf (false)
1525 ovf = main_ovf (true)
1528 ovf = (s1 < 0 && u2) || main_ovf (true)
1531 ovf = res < 0 || main_ovf (true)
1533 res = (S) ((U) s1 * u2)
1534 ovf = (S) u2 >= 0 ? main_ovf (false)
1535 : (s1 != 0 && (s1 != -1 || u2 != (U) res))
1537 t1 = (s1 & s2) < 0 ? (-(U) s1) : ((U) s1)
1538 t2 = (s1 & s2) < 0 ? (-(U) s2) : ((U) s2)
1540 ovf = (s1 ^ s2) < 0 ? (s1 && s2) : main_ovf (true) */
1542 if (uns0_p
&& !uns1_p
)
1544 /* Multiplication is commutative, if operand signedness differs,
1545 canonicalize to the first operand being signed and second
1546 unsigned to simplify following code. */
1547 std::swap (op0
, op1
);
1548 std::swap (arg0
, arg1
);
1553 int pos_neg0
= get_range_pos_neg (arg0
);
1554 int pos_neg1
= get_range_pos_neg (arg1
);
1557 if (!uns0_p
&& uns1_p
&& unsr_p
)
1562 /* If s1 is non-negative, just perform normal u1 * u2 -> ur. */
1565 /* If s1 is negative, avoid the main code, just multiply and
1566 signal overflow if op1 is not 0. */
1567 struct separate_ops ops
;
1568 ops
.code
= MULT_EXPR
;
1569 ops
.type
= TREE_TYPE (arg1
);
1570 ops
.op0
= make_tree (ops
.type
, op0
);
1571 ops
.op1
= make_tree (ops
.type
, op1
);
1572 ops
.op2
= NULL_TREE
;
1574 res
= expand_expr_real_2 (&ops
, NULL_RTX
, mode
, EXPAND_NORMAL
);
1575 do_compare_rtx_and_jump (op1
, const0_rtx
, EQ
, true, mode
, NULL_RTX
,
1576 NULL
, done_label
, profile_probability::very_likely ());
1577 goto do_error_label
;
1579 if (get_min_precision (arg1
, UNSIGNED
)
1580 + get_min_precision (arg0
, SIGNED
) <= GET_MODE_PRECISION (mode
))
1582 /* If the first operand is sign extended from narrower type, the
1583 second operand is zero extended from narrower type and
1584 the sum of the two precisions is smaller or equal to the
1585 result precision: if the first argument is at runtime
1586 non-negative, maximum result will be 0x7e81 or 0x7f..fe80..01
1587 and there will be no overflow, if the first argument is
1588 negative and the second argument zero, the result will be
1589 0 and there will be no overflow, if the first argument is
1590 negative and the second argument positive, the result when
1591 treated as signed will be negative (minimum -0x7f80 or
1592 -0x7f..f80..0) there will be always overflow. So, do
1594 ovf = (S) res < 0 */
1595 struct separate_ops ops
;
1596 ops
.code
= MULT_EXPR
;
1598 = build_nonstandard_integer_type (GET_MODE_PRECISION (mode
),
1600 ops
.op0
= make_tree (ops
.type
, op0
);
1601 ops
.op1
= make_tree (ops
.type
, op1
);
1602 ops
.op2
= NULL_TREE
;
1604 res
= expand_expr_real_2 (&ops
, NULL_RTX
, mode
, EXPAND_NORMAL
);
1605 do_compare_rtx_and_jump (res
, const0_rtx
, GE
, false,
1606 mode
, NULL_RTX
, NULL
, done_label
,
1607 profile_probability::very_likely ());
1608 goto do_error_label
;
1610 rtx_code_label
*do_main_label
;
1611 do_main_label
= gen_label_rtx ();
1612 do_compare_rtx_and_jump (op0
, const0_rtx
, GE
, false, mode
, NULL_RTX
,
1613 NULL
, do_main_label
, profile_probability::very_likely ());
1614 do_compare_rtx_and_jump (op1
, const0_rtx
, EQ
, true, mode
, NULL_RTX
,
1615 NULL
, do_main_label
, profile_probability::very_likely ());
1616 expand_arith_set_overflow (lhs
, target
);
1617 emit_label (do_main_label
);
1625 if (uns0_p
&& uns1_p
&& !unsr_p
)
1627 if ((pos_neg0
| pos_neg1
) == 1)
1629 /* If both arguments are zero extended from narrower types,
1630 the MSB will be clear on both and so we can pretend it is
1631 a normal s1 * s2 -> sr multiplication. */
1637 /* Rest of handling of this case after res is computed. */
1642 if (!uns0_p
&& uns1_p
&& !unsr_p
)
1649 /* If (S) u2 is negative (i.e. u2 is larger than maximum of S,
1650 avoid the main code, just multiply and signal overflow
1651 unless 0 * u2 or -1 * ((U) Smin). */
1652 struct separate_ops ops
;
1653 ops
.code
= MULT_EXPR
;
1654 ops
.type
= TREE_TYPE (arg1
);
1655 ops
.op0
= make_tree (ops
.type
, op0
);
1656 ops
.op1
= make_tree (ops
.type
, op1
);
1657 ops
.op2
= NULL_TREE
;
1659 res
= expand_expr_real_2 (&ops
, NULL_RTX
, mode
, EXPAND_NORMAL
);
1660 do_compare_rtx_and_jump (op0
, const0_rtx
, EQ
, true, mode
, NULL_RTX
,
1661 NULL
, done_label
, profile_probability::very_likely ());
1662 do_compare_rtx_and_jump (op0
, constm1_rtx
, NE
, true, mode
, NULL_RTX
,
1663 NULL
, do_error
, profile_probability::very_unlikely ());
1665 prec
= GET_MODE_PRECISION (mode
);
1667 sgn
= immed_wide_int_const (wi::min_value (prec
, SIGNED
), mode
);
1668 do_compare_rtx_and_jump (op1
, sgn
, EQ
, true, mode
, NULL_RTX
,
1669 NULL
, done_label
, profile_probability::very_likely ());
1670 goto do_error_label
;
1672 /* Rest of handling of this case after res is computed. */
1680 if (!uns0_p
&& !uns1_p
&& unsr_p
)
1683 switch (pos_neg0
| pos_neg1
)
1685 case 1: /* Both operands known to be non-negative. */
1687 case 2: /* Both operands known to be negative. */
1688 op0
= expand_unop (mode
, neg_optab
, op0
, NULL_RTX
, false);
1689 op1
= expand_unop (mode
, neg_optab
, op1
, NULL_RTX
, false);
1690 /* Avoid looking at arg0/arg1 ranges, as we've changed
1692 arg0
= error_mark_node
;
1693 arg1
= error_mark_node
;
1696 if ((pos_neg0
^ pos_neg1
) == 3)
1698 /* If one operand is known to be negative and the other
1699 non-negative, this overflows always, unless the non-negative
1700 one is 0. Just do normal multiply and set overflow
1701 unless one of the operands is 0. */
1702 struct separate_ops ops
;
1703 ops
.code
= MULT_EXPR
;
1705 = build_nonstandard_integer_type (GET_MODE_PRECISION (mode
),
1707 ops
.op0
= make_tree (ops
.type
, op0
);
1708 ops
.op1
= make_tree (ops
.type
, op1
);
1709 ops
.op2
= NULL_TREE
;
1711 res
= expand_expr_real_2 (&ops
, NULL_RTX
, mode
, EXPAND_NORMAL
);
1712 do_compare_rtx_and_jump (pos_neg0
== 1 ? op0
: op1
, const0_rtx
, EQ
,
1713 true, mode
, NULL_RTX
, NULL
, done_label
,
1714 profile_probability::very_likely ());
1715 goto do_error_label
;
1717 if (get_min_precision (arg0
, SIGNED
)
1718 + get_min_precision (arg1
, SIGNED
) <= GET_MODE_PRECISION (mode
))
1720 /* If both operands are sign extended from narrower types and
1721 the sum of the two precisions is smaller or equal to the
1722 result precision: if both arguments are at runtime
1723 non-negative, maximum result will be 0x3f01 or 0x3f..f0..01
1724 and there will be no overflow, if both arguments are negative,
1725 maximum result will be 0x40..00 and there will be no overflow
1726 either, if one argument is positive and the other argument
1727 negative, the result when treated as signed will be negative
1728 and there will be always overflow, and if one argument is
1729 zero and the other negative the result will be zero and no
1732 ovf = (S) res < 0 */
1733 struct separate_ops ops
;
1734 ops
.code
= MULT_EXPR
;
1736 = build_nonstandard_integer_type (GET_MODE_PRECISION (mode
),
1738 ops
.op0
= make_tree (ops
.type
, op0
);
1739 ops
.op1
= make_tree (ops
.type
, op1
);
1740 ops
.op2
= NULL_TREE
;
1742 res
= expand_expr_real_2 (&ops
, NULL_RTX
, mode
, EXPAND_NORMAL
);
1743 do_compare_rtx_and_jump (res
, const0_rtx
, GE
, false,
1744 mode
, NULL_RTX
, NULL
, done_label
,
1745 profile_probability::very_likely ());
1746 goto do_error_label
;
1748 /* The general case, do all the needed comparisons at runtime. */
1749 rtx_code_label
*do_main_label
, *after_negate_label
;
1751 rop0
= gen_reg_rtx (mode
);
1752 rop1
= gen_reg_rtx (mode
);
1753 emit_move_insn (rop0
, op0
);
1754 emit_move_insn (rop1
, op1
);
1757 do_main_label
= gen_label_rtx ();
1758 after_negate_label
= gen_label_rtx ();
1759 tem
= expand_binop (mode
, and_optab
, op0
, op1
, NULL_RTX
, false,
1761 do_compare_rtx_and_jump (tem
, const0_rtx
, GE
, false, mode
, NULL_RTX
,
1762 NULL
, after_negate_label
, profile_probability::very_likely ());
1763 /* Both arguments negative here, negate them and continue with
1764 normal unsigned overflow checking multiplication. */
1765 emit_move_insn (op0
, expand_unop (mode
, neg_optab
, op0
,
1767 emit_move_insn (op1
, expand_unop (mode
, neg_optab
, op1
,
1769 /* Avoid looking at arg0/arg1 ranges, as we might have changed
1771 arg0
= error_mark_node
;
1772 arg1
= error_mark_node
;
1773 emit_jump (do_main_label
);
1774 emit_label (after_negate_label
);
1775 tem
= expand_binop (mode
, xor_optab
, op0
, op1
, NULL_RTX
, false,
1777 do_compare_rtx_and_jump (tem
, const0_rtx
, GE
, false, mode
, NULL_RTX
,
1778 NULL
, do_main_label
,
1779 profile_probability::very_likely ());
1780 /* One argument is negative here, the other positive. This
1781 overflows always, unless one of the arguments is 0. But
1782 if e.g. s2 is 0, (U) s1 * 0 doesn't overflow, whatever s1
1783 is, thus we can keep do_main code oring in overflow as is. */
1785 do_compare_rtx_and_jump (op0
, const0_rtx
, EQ
, true, mode
, NULL_RTX
,
1786 NULL
, do_main_label
,
1787 profile_probability::very_unlikely ());
1789 do_compare_rtx_and_jump (op1
, const0_rtx
, EQ
, true, mode
, NULL_RTX
,
1790 NULL
, do_main_label
,
1791 profile_probability::very_unlikely ());
1792 expand_arith_set_overflow (lhs
, target
);
1793 emit_label (do_main_label
);
1801 type
= build_nonstandard_integer_type (GET_MODE_PRECISION (mode
), uns
);
1802 sign
= uns
? UNSIGNED
: SIGNED
;
1803 icode
= optab_handler (uns
? umulv4_optab
: mulv4_optab
, mode
);
1805 && (integer_pow2p (arg0
) || integer_pow2p (arg1
))
1806 && (optimize_insn_for_speed_p () || icode
== CODE_FOR_nothing
))
1808 /* Optimize unsigned multiplication by power of 2 constant
1809 using 2 shifts, one for result, one to extract the shifted
1810 out bits to see if they are all zero.
1811 Don't do this if optimizing for size and we have umulv4_optab,
1812 in that case assume multiplication will be shorter.
1813 This is heuristics based on the single target that provides
1814 umulv4 right now (i?86/x86_64), if further targets add it, this
1815 might need to be revisited.
1816 Cases where both operands are constant should be folded already
1817 during GIMPLE, and cases where one operand is constant but not
1818 power of 2 are questionable, either the WIDEN_MULT_EXPR case
1819 below can be done without multiplication, just by shifts and adds,
1820 or we'd need to divide the result (and hope it actually doesn't
1821 really divide nor multiply) and compare the result of the division
1822 with the original operand. */
1827 if (integer_pow2p (arg0
))
1829 std::swap (opn0
, opn1
);
1830 std::swap (argn0
, argn1
);
1832 int cnt
= tree_log2 (argn1
);
1833 if (cnt
>= 0 && cnt
< GET_MODE_PRECISION (mode
))
1835 rtx upper
= const0_rtx
;
1836 res
= expand_shift (LSHIFT_EXPR
, mode
, opn0
, cnt
, NULL_RTX
, uns
);
1838 upper
= expand_shift (RSHIFT_EXPR
, mode
, opn0
,
1839 GET_MODE_PRECISION (mode
) - cnt
,
1841 do_compare_rtx_and_jump (upper
, const0_rtx
, EQ
, true, mode
,
1842 NULL_RTX
, NULL
, done_label
,
1843 profile_probability::very_likely ());
1844 goto do_error_label
;
1847 if (icode
!= CODE_FOR_nothing
)
1849 class expand_operand ops
[4];
1850 rtx_insn
*last
= get_last_insn ();
1852 res
= gen_reg_rtx (mode
);
1853 create_output_operand (&ops
[0], res
, mode
);
1854 create_input_operand (&ops
[1], op0
, mode
);
1855 create_input_operand (&ops
[2], op1
, mode
);
1856 create_fixed_operand (&ops
[3], do_error
);
1857 if (maybe_expand_insn (icode
, 4, ops
))
1859 last
= get_last_insn ();
1860 if (profile_status_for_fn (cfun
) != PROFILE_ABSENT
1862 && any_condjump_p (last
)
1863 && !find_reg_note (last
, REG_BR_PROB
, 0))
1864 add_reg_br_prob_note (last
,
1865 profile_probability::very_unlikely ());
1866 emit_jump (done_label
);
1870 delete_insns_since (last
);
1871 icode
= CODE_FOR_nothing
;
1875 if (icode
== CODE_FOR_nothing
)
1877 struct separate_ops ops
;
1878 int prec
= GET_MODE_PRECISION (mode
);
1879 scalar_int_mode hmode
, wmode
;
1880 ops
.op0
= make_tree (type
, op0
);
1881 ops
.op1
= make_tree (type
, op1
);
1882 ops
.op2
= NULL_TREE
;
1885 /* Optimize unsigned overflow check where we don't use the
1886 multiplication result, just whether overflow happened.
1887 If we can do MULT_HIGHPART_EXPR, that followed by
1888 comparison of the result against zero is cheapest.
1889 We'll still compute res, but it should be DCEd later. */
1895 && !(uns0_p
&& uns1_p
&& !unsr_p
)
1896 && can_mult_highpart_p (mode
, uns
) == 1
1897 && single_imm_use (lhs
, &use
, &use_stmt
)
1898 && is_gimple_assign (use_stmt
)
1899 && gimple_assign_rhs_code (use_stmt
) == IMAGPART_EXPR
)
1902 if (GET_MODE_2XWIDER_MODE (mode
).exists (&wmode
)
1903 && targetm
.scalar_mode_supported_p (wmode
)
1904 && can_widen_mult_without_libcall (wmode
, mode
, op0
, op1
, uns
))
1907 ops
.code
= WIDEN_MULT_EXPR
;
1909 = build_nonstandard_integer_type (GET_MODE_PRECISION (wmode
), uns
);
1911 res
= expand_expr_real_2 (&ops
, NULL_RTX
, wmode
, EXPAND_NORMAL
);
1912 rtx hipart
= expand_shift (RSHIFT_EXPR
, wmode
, res
, prec
,
1914 hipart
= convert_modes (mode
, wmode
, hipart
, uns
);
1915 res
= convert_modes (mode
, wmode
, res
, uns
);
1917 /* For the unsigned multiplication, there was overflow if
1918 HIPART is non-zero. */
1919 do_compare_rtx_and_jump (hipart
, const0_rtx
, EQ
, true, mode
,
1920 NULL_RTX
, NULL
, done_label
,
1921 profile_probability::very_likely ());
1924 /* RES is used more than once, place it in a pseudo. */
1925 res
= force_reg (mode
, res
);
1927 rtx signbit
= expand_shift (RSHIFT_EXPR
, mode
, res
, prec
- 1,
1929 /* RES is low half of the double width result, HIPART
1930 the high half. There was overflow if
1931 HIPART is different from RES < 0 ? -1 : 0. */
1932 do_compare_rtx_and_jump (signbit
, hipart
, EQ
, true, mode
,
1933 NULL_RTX
, NULL
, done_label
,
1934 profile_probability::very_likely ());
1937 else if (can_mult_highpart_p (mode
, uns
) == 1)
1940 ops
.code
= MULT_HIGHPART_EXPR
;
1943 rtx hipart
= expand_expr_real_2 (&ops
, NULL_RTX
, mode
,
1945 ops
.code
= MULT_EXPR
;
1946 res
= expand_expr_real_2 (&ops
, NULL_RTX
, mode
, EXPAND_NORMAL
);
1948 /* For the unsigned multiplication, there was overflow if
1949 HIPART is non-zero. */
1950 do_compare_rtx_and_jump (hipart
, const0_rtx
, EQ
, true, mode
,
1951 NULL_RTX
, NULL
, done_label
,
1952 profile_probability::very_likely ());
1955 rtx signbit
= expand_shift (RSHIFT_EXPR
, mode
, res
, prec
- 1,
1957 /* RES is low half of the double width result, HIPART
1958 the high half. There was overflow if
1959 HIPART is different from RES < 0 ? -1 : 0. */
1960 do_compare_rtx_and_jump (signbit
, hipart
, EQ
, true, mode
,
1961 NULL_RTX
, NULL
, done_label
,
1962 profile_probability::very_likely ());
1966 else if (int_mode_for_size (prec
/ 2, 1).exists (&hmode
)
1967 && 2 * GET_MODE_PRECISION (hmode
) == prec
)
1969 rtx_code_label
*large_op0
= gen_label_rtx ();
1970 rtx_code_label
*small_op0_large_op1
= gen_label_rtx ();
1971 rtx_code_label
*one_small_one_large
= gen_label_rtx ();
1972 rtx_code_label
*both_ops_large
= gen_label_rtx ();
1973 rtx_code_label
*after_hipart_neg
= uns
? NULL
: gen_label_rtx ();
1974 rtx_code_label
*after_lopart_neg
= uns
? NULL
: gen_label_rtx ();
1975 rtx_code_label
*do_overflow
= gen_label_rtx ();
1976 rtx_code_label
*hipart_different
= uns
? NULL
: gen_label_rtx ();
1978 unsigned int hprec
= GET_MODE_PRECISION (hmode
);
1979 rtx hipart0
= expand_shift (RSHIFT_EXPR
, mode
, op0
, hprec
,
1981 hipart0
= convert_modes (hmode
, mode
, hipart0
, uns
);
1982 rtx lopart0
= convert_modes (hmode
, mode
, op0
, uns
);
1983 rtx signbit0
= const0_rtx
;
1985 signbit0
= expand_shift (RSHIFT_EXPR
, hmode
, lopart0
, hprec
- 1,
1987 rtx hipart1
= expand_shift (RSHIFT_EXPR
, mode
, op1
, hprec
,
1989 hipart1
= convert_modes (hmode
, mode
, hipart1
, uns
);
1990 rtx lopart1
= convert_modes (hmode
, mode
, op1
, uns
);
1991 rtx signbit1
= const0_rtx
;
1993 signbit1
= expand_shift (RSHIFT_EXPR
, hmode
, lopart1
, hprec
- 1,
1996 res
= gen_reg_rtx (mode
);
1998 /* True if op0 resp. op1 are known to be in the range of
2000 bool op0_small_p
= false;
2001 bool op1_small_p
= false;
2002 /* True if op0 resp. op1 are known to have all zeros or all ones
2003 in the upper half of bits, but are not known to be
2005 bool op0_medium_p
= false;
2006 bool op1_medium_p
= false;
2007 /* -1 if op{0,1} is known to be negative, 0 if it is known to be
2008 nonnegative, 1 if unknown. */
2014 else if (pos_neg0
== 2)
2018 else if (pos_neg1
== 2)
2021 unsigned int mprec0
= prec
;
2022 if (arg0
!= error_mark_node
)
2023 mprec0
= get_min_precision (arg0
, sign
);
2024 if (mprec0
<= hprec
)
2026 else if (!uns
&& mprec0
<= hprec
+ 1)
2027 op0_medium_p
= true;
2028 unsigned int mprec1
= prec
;
2029 if (arg1
!= error_mark_node
)
2030 mprec1
= get_min_precision (arg1
, sign
);
2031 if (mprec1
<= hprec
)
2033 else if (!uns
&& mprec1
<= hprec
+ 1)
2034 op1_medium_p
= true;
2036 int smaller_sign
= 1;
2037 int larger_sign
= 1;
2040 smaller_sign
= op0_sign
;
2041 larger_sign
= op1_sign
;
2043 else if (op1_small_p
)
2045 smaller_sign
= op1_sign
;
2046 larger_sign
= op0_sign
;
2048 else if (op0_sign
== op1_sign
)
2050 smaller_sign
= op0_sign
;
2051 larger_sign
= op0_sign
;
2055 do_compare_rtx_and_jump (signbit0
, hipart0
, NE
, true, hmode
,
2056 NULL_RTX
, NULL
, large_op0
,
2057 profile_probability::unlikely ());
2060 do_compare_rtx_and_jump (signbit1
, hipart1
, NE
, true, hmode
,
2061 NULL_RTX
, NULL
, small_op0_large_op1
,
2062 profile_probability::unlikely ());
2064 /* If both op0 and op1 are sign (!uns) or zero (uns) extended from
2065 hmode to mode, the multiplication will never overflow. We can
2066 do just one hmode x hmode => mode widening multiplication. */
2067 tree halfstype
= build_nonstandard_integer_type (hprec
, uns
);
2068 ops
.op0
= make_tree (halfstype
, lopart0
);
2069 ops
.op1
= make_tree (halfstype
, lopart1
);
2070 ops
.code
= WIDEN_MULT_EXPR
;
2073 = expand_expr_real_2 (&ops
, NULL_RTX
, mode
, EXPAND_NORMAL
);
2074 emit_move_insn (res
, thisres
);
2075 emit_jump (done_label
);
2077 emit_label (small_op0_large_op1
);
2079 /* If op0 is sign (!uns) or zero (uns) extended from hmode to mode,
2080 but op1 is not, just swap the arguments and handle it as op1
2081 sign/zero extended, op0 not. */
2082 rtx larger
= gen_reg_rtx (mode
);
2083 rtx hipart
= gen_reg_rtx (hmode
);
2084 rtx lopart
= gen_reg_rtx (hmode
);
2085 emit_move_insn (larger
, op1
);
2086 emit_move_insn (hipart
, hipart1
);
2087 emit_move_insn (lopart
, lopart0
);
2088 emit_jump (one_small_one_large
);
2090 emit_label (large_op0
);
2093 do_compare_rtx_and_jump (signbit1
, hipart1
, NE
, true, hmode
,
2094 NULL_RTX
, NULL
, both_ops_large
,
2095 profile_probability::unlikely ());
2097 /* If op1 is sign (!uns) or zero (uns) extended from hmode to mode,
2098 but op0 is not, prepare larger, hipart and lopart pseudos and
2099 handle it together with small_op0_large_op1. */
2100 emit_move_insn (larger
, op0
);
2101 emit_move_insn (hipart
, hipart0
);
2102 emit_move_insn (lopart
, lopart1
);
2104 emit_label (one_small_one_large
);
2106 /* lopart is the low part of the operand that is sign extended
2107 to mode, larger is the other operand, hipart is the
2108 high part of larger and lopart0 and lopart1 are the low parts
2110 We perform lopart0 * lopart1 and lopart * hipart widening
2112 tree halfutype
= build_nonstandard_integer_type (hprec
, 1);
2113 ops
.op0
= make_tree (halfutype
, lopart0
);
2114 ops
.op1
= make_tree (halfutype
, lopart1
);
2116 = expand_expr_real_2 (&ops
, NULL_RTX
, mode
, EXPAND_NORMAL
);
2118 ops
.op0
= make_tree (halfutype
, lopart
);
2119 ops
.op1
= make_tree (halfutype
, hipart
);
2120 rtx loxhi
= gen_reg_rtx (mode
);
2121 rtx tem
= expand_expr_real_2 (&ops
, NULL_RTX
, mode
, EXPAND_NORMAL
);
2122 emit_move_insn (loxhi
, tem
);
2126 /* if (hipart < 0) loxhi -= lopart << (bitsize / 2); */
2127 if (larger_sign
== 0)
2128 emit_jump (after_hipart_neg
);
2129 else if (larger_sign
!= -1)
2130 do_compare_rtx_and_jump (hipart
, const0_rtx
, GE
, false, hmode
,
2131 NULL_RTX
, NULL
, after_hipart_neg
,
2132 profile_probability::even ());
2134 tem
= convert_modes (mode
, hmode
, lopart
, 1);
2135 tem
= expand_shift (LSHIFT_EXPR
, mode
, tem
, hprec
, NULL_RTX
, 1);
2136 tem
= expand_simple_binop (mode
, MINUS
, loxhi
, tem
, NULL_RTX
,
2138 emit_move_insn (loxhi
, tem
);
2140 emit_label (after_hipart_neg
);
2142 /* if (lopart < 0) loxhi -= larger; */
2143 if (smaller_sign
== 0)
2144 emit_jump (after_lopart_neg
);
2145 else if (smaller_sign
!= -1)
2146 do_compare_rtx_and_jump (lopart
, const0_rtx
, GE
, false, hmode
,
2147 NULL_RTX
, NULL
, after_lopart_neg
,
2148 profile_probability::even ());
2150 tem
= expand_simple_binop (mode
, MINUS
, loxhi
, larger
, NULL_RTX
,
2152 emit_move_insn (loxhi
, tem
);
2154 emit_label (after_lopart_neg
);
2157 /* loxhi += (uns) lo0xlo1 >> (bitsize / 2); */
2158 tem
= expand_shift (RSHIFT_EXPR
, mode
, lo0xlo1
, hprec
, NULL_RTX
, 1);
2159 tem
= expand_simple_binop (mode
, PLUS
, loxhi
, tem
, NULL_RTX
,
2161 emit_move_insn (loxhi
, tem
);
2163 /* if (loxhi >> (bitsize / 2)
2164 == (hmode) loxhi >> (bitsize / 2 - 1)) (if !uns)
2165 if (loxhi >> (bitsize / 2) == 0 (if uns). */
2166 rtx hipartloxhi
= expand_shift (RSHIFT_EXPR
, mode
, loxhi
, hprec
,
2168 hipartloxhi
= convert_modes (hmode
, mode
, hipartloxhi
, 0);
2169 rtx signbitloxhi
= const0_rtx
;
2171 signbitloxhi
= expand_shift (RSHIFT_EXPR
, hmode
,
2172 convert_modes (hmode
, mode
,
2174 hprec
- 1, NULL_RTX
, 0);
2176 do_compare_rtx_and_jump (signbitloxhi
, hipartloxhi
, NE
, true, hmode
,
2177 NULL_RTX
, NULL
, do_overflow
,
2178 profile_probability::very_unlikely ());
2180 /* res = (loxhi << (bitsize / 2)) | (hmode) lo0xlo1; */
2181 rtx loxhishifted
= expand_shift (LSHIFT_EXPR
, mode
, loxhi
, hprec
,
2183 tem
= convert_modes (mode
, hmode
,
2184 convert_modes (hmode
, mode
, lo0xlo1
, 1), 1);
2186 tem
= expand_simple_binop (mode
, IOR
, loxhishifted
, tem
, res
,
2189 emit_move_insn (res
, tem
);
2190 emit_jump (done_label
);
2192 emit_label (both_ops_large
);
2194 /* If both operands are large (not sign (!uns) or zero (uns)
2195 extended from hmode), then perform the full multiplication
2196 which will be the result of the operation.
2197 The only cases which don't overflow are for signed multiplication
2198 some cases where both hipart0 and highpart1 are 0 or -1.
2199 For unsigned multiplication when high parts are both non-zero
2200 this overflows always. */
2201 ops
.code
= MULT_EXPR
;
2202 ops
.op0
= make_tree (type
, op0
);
2203 ops
.op1
= make_tree (type
, op1
);
2204 tem
= expand_expr_real_2 (&ops
, NULL_RTX
, mode
, EXPAND_NORMAL
);
2205 emit_move_insn (res
, tem
);
2211 tem
= expand_simple_binop (hmode
, PLUS
, hipart0
, const1_rtx
,
2212 NULL_RTX
, 1, OPTAB_WIDEN
);
2213 do_compare_rtx_and_jump (tem
, const1_rtx
, GTU
, true, hmode
,
2214 NULL_RTX
, NULL
, do_error
,
2215 profile_probability::very_unlikely ());
2220 tem
= expand_simple_binop (hmode
, PLUS
, hipart1
, const1_rtx
,
2221 NULL_RTX
, 1, OPTAB_WIDEN
);
2222 do_compare_rtx_and_jump (tem
, const1_rtx
, GTU
, true, hmode
,
2223 NULL_RTX
, NULL
, do_error
,
2224 profile_probability::very_unlikely ());
2227 /* At this point hipart{0,1} are both in [-1, 0]. If they are
2228 the same, overflow happened if res is non-positive, if they
2229 are different, overflow happened if res is positive. */
2230 if (op0_sign
!= 1 && op1_sign
!= 1 && op0_sign
!= op1_sign
)
2231 emit_jump (hipart_different
);
2232 else if (op0_sign
== 1 || op1_sign
== 1)
2233 do_compare_rtx_and_jump (hipart0
, hipart1
, NE
, true, hmode
,
2234 NULL_RTX
, NULL
, hipart_different
,
2235 profile_probability::even ());
2237 do_compare_rtx_and_jump (res
, const0_rtx
, LE
, false, mode
,
2238 NULL_RTX
, NULL
, do_error
,
2239 profile_probability::very_unlikely ());
2240 emit_jump (done_label
);
2242 emit_label (hipart_different
);
2244 do_compare_rtx_and_jump (res
, const0_rtx
, GE
, false, mode
,
2245 NULL_RTX
, NULL
, do_error
,
2246 profile_probability::very_unlikely ());
2247 emit_jump (done_label
);
2250 emit_label (do_overflow
);
2252 /* Overflow, do full multiplication and fallthru into do_error. */
2253 ops
.op0
= make_tree (type
, op0
);
2254 ops
.op1
= make_tree (type
, op1
);
2255 tem
= expand_expr_real_2 (&ops
, NULL_RTX
, mode
, EXPAND_NORMAL
);
2256 emit_move_insn (res
, tem
);
2258 else if (GET_MODE_2XWIDER_MODE (mode
).exists (&wmode
)
2259 && targetm
.scalar_mode_supported_p (wmode
))
2260 /* Even emitting a libcall is better than not detecting overflow
2265 gcc_assert (!is_ubsan
);
2266 ops
.code
= MULT_EXPR
;
2268 res
= expand_expr_real_2 (&ops
, NULL_RTX
, mode
, EXPAND_NORMAL
);
2269 emit_jump (done_label
);
2274 emit_label (do_error
);
2277 /* Expand the ubsan builtin call. */
2279 fn
= ubsan_build_overflow_builtin (MULT_EXPR
, loc
, TREE_TYPE (arg0
),
2283 do_pending_stack_adjust ();
2286 expand_arith_set_overflow (lhs
, target
);
2289 emit_label (done_label
);
2292 if (uns0_p
&& uns1_p
&& !unsr_p
)
2294 rtx_code_label
*all_done_label
= gen_label_rtx ();
2295 do_compare_rtx_and_jump (res
, const0_rtx
, GE
, false, mode
, NULL_RTX
,
2296 NULL
, all_done_label
, profile_probability::very_likely ());
2297 expand_arith_set_overflow (lhs
, target
);
2298 emit_label (all_done_label
);
2302 if (!uns0_p
&& uns1_p
&& !unsr_p
&& pos_neg1
== 3)
2304 rtx_code_label
*all_done_label
= gen_label_rtx ();
2305 rtx_code_label
*set_noovf
= gen_label_rtx ();
2306 do_compare_rtx_and_jump (op1
, const0_rtx
, GE
, false, mode
, NULL_RTX
,
2307 NULL
, all_done_label
, profile_probability::very_likely ());
2308 expand_arith_set_overflow (lhs
, target
);
2309 do_compare_rtx_and_jump (op0
, const0_rtx
, EQ
, true, mode
, NULL_RTX
,
2310 NULL
, set_noovf
, profile_probability::very_likely ());
2311 do_compare_rtx_and_jump (op0
, constm1_rtx
, NE
, true, mode
, NULL_RTX
,
2312 NULL
, all_done_label
, profile_probability::very_unlikely ());
2313 do_compare_rtx_and_jump (op1
, res
, NE
, true, mode
, NULL_RTX
, NULL
,
2314 all_done_label
, profile_probability::very_unlikely ());
2315 emit_label (set_noovf
);
2316 write_complex_part (target
, const0_rtx
, true, false);
2317 emit_label (all_done_label
);
2323 expand_ubsan_result_store (target
, res
);
2325 expand_arith_overflow_result_store (lhs
, target
, mode
, res
);
2329 /* Expand UBSAN_CHECK_* internal function if it has vector operands. */
2332 expand_vector_ubsan_overflow (location_t loc
, enum tree_code code
, tree lhs
,
2333 tree arg0
, tree arg1
)
2335 poly_uint64 cnt
= TYPE_VECTOR_SUBPARTS (TREE_TYPE (arg0
));
2336 rtx_code_label
*loop_lab
= NULL
;
2337 rtx cntvar
= NULL_RTX
;
2338 tree cntv
= NULL_TREE
;
2339 tree eltype
= TREE_TYPE (TREE_TYPE (arg0
));
2340 tree sz
= TYPE_SIZE (eltype
);
2341 tree data
= NULL_TREE
;
2342 tree resv
= NULL_TREE
;
2343 rtx lhsr
= NULL_RTX
;
2344 rtx resvr
= NULL_RTX
;
2345 unsigned HOST_WIDE_INT const_cnt
= 0;
2346 bool use_loop_p
= (!cnt
.is_constant (&const_cnt
) || const_cnt
> 4);
2351 lhsr
= expand_expr (lhs
, NULL_RTX
, VOIDmode
, EXPAND_WRITE
);
2352 if (!VECTOR_MODE_P (GET_MODE (lhsr
))
2353 || (op
= optab_for_tree_code (code
, TREE_TYPE (arg0
),
2354 optab_default
)) == unknown_optab
2355 || (optab_handler (op
, TYPE_MODE (TREE_TYPE (arg0
)))
2356 == CODE_FOR_nothing
))
2359 resv
= make_tree (TREE_TYPE (lhs
), lhsr
);
2362 resvr
= assign_temp (TREE_TYPE (lhs
), 1, 1);
2363 resv
= make_tree (TREE_TYPE (lhs
), resvr
);
2369 do_pending_stack_adjust ();
2370 loop_lab
= gen_label_rtx ();
2371 cntvar
= gen_reg_rtx (TYPE_MODE (sizetype
));
2372 cntv
= make_tree (sizetype
, cntvar
);
2373 emit_move_insn (cntvar
, const0_rtx
);
2374 emit_label (loop_lab
);
2376 if (TREE_CODE (arg0
) != VECTOR_CST
)
2378 rtx arg0r
= expand_normal (arg0
);
2379 arg0
= make_tree (TREE_TYPE (arg0
), arg0r
);
2381 if (TREE_CODE (arg1
) != VECTOR_CST
)
2383 rtx arg1r
= expand_normal (arg1
);
2384 arg1
= make_tree (TREE_TYPE (arg1
), arg1r
);
2386 for (unsigned int i
= 0; i
< (use_loop_p
? 1 : const_cnt
); i
++)
2388 tree op0
, op1
, res
= NULL_TREE
;
2391 tree atype
= build_array_type_nelts (eltype
, cnt
);
2392 op0
= uniform_vector_p (arg0
);
2393 if (op0
== NULL_TREE
)
2395 op0
= fold_build1_loc (loc
, VIEW_CONVERT_EXPR
, atype
, arg0
);
2396 op0
= build4_loc (loc
, ARRAY_REF
, eltype
, op0
, cntv
,
2397 NULL_TREE
, NULL_TREE
);
2399 op1
= uniform_vector_p (arg1
);
2400 if (op1
== NULL_TREE
)
2402 op1
= fold_build1_loc (loc
, VIEW_CONVERT_EXPR
, atype
, arg1
);
2403 op1
= build4_loc (loc
, ARRAY_REF
, eltype
, op1
, cntv
,
2404 NULL_TREE
, NULL_TREE
);
2408 res
= fold_build1_loc (loc
, VIEW_CONVERT_EXPR
, atype
, resv
);
2409 res
= build4_loc (loc
, ARRAY_REF
, eltype
, res
, cntv
,
2410 NULL_TREE
, NULL_TREE
);
2415 tree bitpos
= bitsize_int (tree_to_uhwi (sz
) * i
);
2416 op0
= fold_build3_loc (loc
, BIT_FIELD_REF
, eltype
, arg0
, sz
, bitpos
);
2417 op1
= fold_build3_loc (loc
, BIT_FIELD_REF
, eltype
, arg1
, sz
, bitpos
);
2419 res
= fold_build3_loc (loc
, BIT_FIELD_REF
, eltype
, resv
, sz
,
2425 expand_addsub_overflow (loc
, PLUS_EXPR
, res
, op0
, op1
,
2426 false, false, false, true, &data
);
2429 if (use_loop_p
? integer_zerop (arg0
) : integer_zerop (op0
))
2430 expand_neg_overflow (loc
, res
, op1
, true, &data
);
2432 expand_addsub_overflow (loc
, MINUS_EXPR
, res
, op0
, op1
,
2433 false, false, false, true, &data
);
2436 expand_mul_overflow (loc
, res
, op0
, op1
, false, false, false,
2445 struct separate_ops ops
;
2446 ops
.code
= PLUS_EXPR
;
2447 ops
.type
= TREE_TYPE (cntv
);
2449 ops
.op1
= build_int_cst (TREE_TYPE (cntv
), 1);
2450 ops
.op2
= NULL_TREE
;
2452 rtx ret
= expand_expr_real_2 (&ops
, cntvar
, TYPE_MODE (sizetype
),
2455 emit_move_insn (cntvar
, ret
);
2456 rtx cntrtx
= gen_int_mode (cnt
, TYPE_MODE (sizetype
));
2457 do_compare_rtx_and_jump (cntvar
, cntrtx
, NE
, false,
2458 TYPE_MODE (sizetype
), NULL_RTX
, NULL
, loop_lab
,
2459 profile_probability::very_likely ());
2461 if (lhs
&& resv
== NULL_TREE
)
2463 struct separate_ops ops
;
2465 ops
.type
= TREE_TYPE (arg0
);
2468 ops
.op2
= NULL_TREE
;
2470 rtx ret
= expand_expr_real_2 (&ops
, lhsr
, TYPE_MODE (TREE_TYPE (arg0
)),
2473 emit_move_insn (lhsr
, ret
);
2476 emit_move_insn (lhsr
, resvr
);
2479 /* Expand UBSAN_CHECK_ADD call STMT. */
2482 expand_UBSAN_CHECK_ADD (internal_fn
, gcall
*stmt
)
2484 location_t loc
= gimple_location (stmt
);
2485 tree lhs
= gimple_call_lhs (stmt
);
2486 tree arg0
= gimple_call_arg (stmt
, 0);
2487 tree arg1
= gimple_call_arg (stmt
, 1);
2488 if (VECTOR_TYPE_P (TREE_TYPE (arg0
)))
2489 expand_vector_ubsan_overflow (loc
, PLUS_EXPR
, lhs
, arg0
, arg1
);
2491 expand_addsub_overflow (loc
, PLUS_EXPR
, lhs
, arg0
, arg1
,
2492 false, false, false, true, NULL
);
2495 /* Expand UBSAN_CHECK_SUB call STMT. */
2498 expand_UBSAN_CHECK_SUB (internal_fn
, gcall
*stmt
)
2500 location_t loc
= gimple_location (stmt
);
2501 tree lhs
= gimple_call_lhs (stmt
);
2502 tree arg0
= gimple_call_arg (stmt
, 0);
2503 tree arg1
= gimple_call_arg (stmt
, 1);
2504 if (VECTOR_TYPE_P (TREE_TYPE (arg0
)))
2505 expand_vector_ubsan_overflow (loc
, MINUS_EXPR
, lhs
, arg0
, arg1
);
2506 else if (integer_zerop (arg0
))
2507 expand_neg_overflow (loc
, lhs
, arg1
, true, NULL
);
2509 expand_addsub_overflow (loc
, MINUS_EXPR
, lhs
, arg0
, arg1
,
2510 false, false, false, true, NULL
);
2513 /* Expand UBSAN_CHECK_MUL call STMT. */
2516 expand_UBSAN_CHECK_MUL (internal_fn
, gcall
*stmt
)
2518 location_t loc
= gimple_location (stmt
);
2519 tree lhs
= gimple_call_lhs (stmt
);
2520 tree arg0
= gimple_call_arg (stmt
, 0);
2521 tree arg1
= gimple_call_arg (stmt
, 1);
2522 if (VECTOR_TYPE_P (TREE_TYPE (arg0
)))
2523 expand_vector_ubsan_overflow (loc
, MULT_EXPR
, lhs
, arg0
, arg1
);
2525 expand_mul_overflow (loc
, lhs
, arg0
, arg1
, false, false, false, true,
2529 /* Helper function for {ADD,SUB,MUL}_OVERFLOW call stmt expansion. */
2532 expand_arith_overflow (enum tree_code code
, gimple
*stmt
)
2534 tree lhs
= gimple_call_lhs (stmt
);
2535 if (lhs
== NULL_TREE
)
2537 tree arg0
= gimple_call_arg (stmt
, 0);
2538 tree arg1
= gimple_call_arg (stmt
, 1);
2539 tree type
= TREE_TYPE (TREE_TYPE (lhs
));
2540 int uns0_p
= TYPE_UNSIGNED (TREE_TYPE (arg0
));
2541 int uns1_p
= TYPE_UNSIGNED (TREE_TYPE (arg1
));
2542 int unsr_p
= TYPE_UNSIGNED (type
);
2543 int prec0
= TYPE_PRECISION (TREE_TYPE (arg0
));
2544 int prec1
= TYPE_PRECISION (TREE_TYPE (arg1
));
2545 int precres
= TYPE_PRECISION (type
);
2546 location_t loc
= gimple_location (stmt
);
2547 if (!uns0_p
&& get_range_pos_neg (arg0
) == 1)
2549 if (!uns1_p
&& get_range_pos_neg (arg1
) == 1)
2551 int pr
= get_min_precision (arg0
, uns0_p
? UNSIGNED
: SIGNED
);
2552 prec0
= MIN (prec0
, pr
);
2553 pr
= get_min_precision (arg1
, uns1_p
? UNSIGNED
: SIGNED
);
2554 prec1
= MIN (prec1
, pr
);
2556 /* If uns0_p && uns1_p, precop is minimum needed precision
2557 of unsigned type to hold the exact result, otherwise
2558 precop is minimum needed precision of signed type to
2559 hold the exact result. */
2561 if (code
== MULT_EXPR
)
2562 precop
= prec0
+ prec1
+ (uns0_p
!= uns1_p
);
2565 if (uns0_p
== uns1_p
)
2566 precop
= MAX (prec0
, prec1
) + 1;
2568 precop
= MAX (prec0
+ 1, prec1
) + 1;
2570 precop
= MAX (prec0
, prec1
+ 1) + 1;
2572 int orig_precres
= precres
;
2576 if ((uns0_p
&& uns1_p
)
2577 ? ((precop
+ !unsr_p
) <= precres
2578 /* u1 - u2 -> ur can overflow, no matter what precision
2580 && (code
!= MINUS_EXPR
|| !unsr_p
))
2581 : (!unsr_p
&& precop
<= precres
))
2583 /* The infinity precision result will always fit into result. */
2584 rtx target
= expand_expr (lhs
, NULL_RTX
, VOIDmode
, EXPAND_WRITE
);
2585 write_complex_part (target
, const0_rtx
, true, false);
2586 scalar_int_mode mode
= SCALAR_INT_TYPE_MODE (type
);
2587 struct separate_ops ops
;
2590 ops
.op0
= fold_convert_loc (loc
, type
, arg0
);
2591 ops
.op1
= fold_convert_loc (loc
, type
, arg1
);
2592 ops
.op2
= NULL_TREE
;
2594 rtx tem
= expand_expr_real_2 (&ops
, NULL_RTX
, mode
, EXPAND_NORMAL
);
2595 expand_arith_overflow_result_store (lhs
, target
, mode
, tem
);
2599 /* For operations with low precision, if target doesn't have them, start
2600 with precres widening right away, otherwise do it only if the most
2601 simple cases can't be used. */
2602 const int min_precision
= targetm
.min_arithmetic_precision ();
2603 if (orig_precres
== precres
&& precres
< min_precision
)
2605 else if ((uns0_p
&& uns1_p
&& unsr_p
&& prec0
<= precres
2606 && prec1
<= precres
)
2607 || ((!uns0_p
|| !uns1_p
) && !unsr_p
2608 && prec0
+ uns0_p
<= precres
2609 && prec1
+ uns1_p
<= precres
))
2611 arg0
= fold_convert_loc (loc
, type
, arg0
);
2612 arg1
= fold_convert_loc (loc
, type
, arg1
);
2616 if (integer_zerop (arg0
) && !unsr_p
)
2618 expand_neg_overflow (loc
, lhs
, arg1
, false, NULL
);
2623 expand_addsub_overflow (loc
, code
, lhs
, arg0
, arg1
, unsr_p
,
2624 unsr_p
, unsr_p
, false, NULL
);
2627 expand_mul_overflow (loc
, lhs
, arg0
, arg1
, unsr_p
,
2628 unsr_p
, unsr_p
, false, NULL
);
2635 /* For sub-word operations, retry with a wider type first. */
2636 if (orig_precres
== precres
&& precop
<= BITS_PER_WORD
)
2638 int p
= MAX (min_precision
, precop
);
2639 scalar_int_mode m
= smallest_int_mode_for_size (p
);
2640 tree optype
= build_nonstandard_integer_type (GET_MODE_PRECISION (m
),
2643 p
= TYPE_PRECISION (optype
);
2647 unsr_p
= TYPE_UNSIGNED (optype
);
2653 if (prec0
<= precres
&& prec1
<= precres
)
2658 types
[0] = build_nonstandard_integer_type (precres
, 0);
2664 types
[1] = build_nonstandard_integer_type (precres
, 1);
2666 arg0
= fold_convert_loc (loc
, types
[uns0_p
], arg0
);
2667 arg1
= fold_convert_loc (loc
, types
[uns1_p
], arg1
);
2668 if (code
!= MULT_EXPR
)
2669 expand_addsub_overflow (loc
, code
, lhs
, arg0
, arg1
, unsr_p
,
2670 uns0_p
, uns1_p
, false, NULL
);
2672 expand_mul_overflow (loc
, lhs
, arg0
, arg1
, unsr_p
,
2673 uns0_p
, uns1_p
, false, NULL
);
2677 /* Retry with a wider type. */
2678 if (orig_precres
== precres
)
2680 int p
= MAX (prec0
, prec1
);
2681 scalar_int_mode m
= smallest_int_mode_for_size (p
);
2682 tree optype
= build_nonstandard_integer_type (GET_MODE_PRECISION (m
),
2685 p
= TYPE_PRECISION (optype
);
2689 unsr_p
= TYPE_UNSIGNED (optype
);
2700 /* Expand ADD_OVERFLOW STMT. */
2703 expand_ADD_OVERFLOW (internal_fn
, gcall
*stmt
)
2705 expand_arith_overflow (PLUS_EXPR
, stmt
);
2708 /* Expand SUB_OVERFLOW STMT. */
2711 expand_SUB_OVERFLOW (internal_fn
, gcall
*stmt
)
2713 expand_arith_overflow (MINUS_EXPR
, stmt
);
2716 /* Expand MUL_OVERFLOW STMT. */
2719 expand_MUL_OVERFLOW (internal_fn
, gcall
*stmt
)
2721 expand_arith_overflow (MULT_EXPR
, stmt
);
2724 /* This should get folded in tree-vectorizer.cc. */
2727 expand_LOOP_VECTORIZED (internal_fn
, gcall
*)
2732 /* This should get folded in tree-vectorizer.cc. */
2735 expand_LOOP_DIST_ALIAS (internal_fn
, gcall
*)
2740 /* Return a memory reference of type TYPE for argument INDEX of STMT.
2741 Use argument INDEX + 1 to derive the second (TBAA) operand. */
2744 expand_call_mem_ref (tree type
, gcall
*stmt
, int index
)
2746 tree addr
= gimple_call_arg (stmt
, index
);
2747 tree alias_ptr_type
= TREE_TYPE (gimple_call_arg (stmt
, index
+ 1));
2748 unsigned int align
= tree_to_shwi (gimple_call_arg (stmt
, index
+ 1));
2749 if (TYPE_ALIGN (type
) != align
)
2750 type
= build_aligned_type (type
, align
);
2753 if (TREE_CODE (tmp
) == SSA_NAME
)
2755 gimple
*def
= SSA_NAME_DEF_STMT (tmp
);
2756 if (gimple_assign_single_p (def
))
2757 tmp
= gimple_assign_rhs1 (def
);
2760 if (TREE_CODE (tmp
) == ADDR_EXPR
)
2762 tree mem
= TREE_OPERAND (tmp
, 0);
2763 if (TREE_CODE (mem
) == TARGET_MEM_REF
2764 && types_compatible_p (TREE_TYPE (mem
), type
))
2766 tree offset
= TMR_OFFSET (mem
);
2767 if (type
!= TREE_TYPE (mem
)
2768 || alias_ptr_type
!= TREE_TYPE (offset
)
2769 || !integer_zerop (offset
))
2771 mem
= copy_node (mem
);
2772 TMR_OFFSET (mem
) = wide_int_to_tree (alias_ptr_type
,
2773 wi::to_poly_wide (offset
));
2774 TREE_TYPE (mem
) = type
;
2780 return fold_build2 (MEM_REF
, type
, addr
, build_int_cst (alias_ptr_type
, 0));
2783 /* Expand MASK_LOAD{,_LANES} or LEN_LOAD call STMT using optab OPTAB. */
2786 expand_partial_load_optab_fn (internal_fn
, gcall
*stmt
, convert_optab optab
)
2788 class expand_operand ops
[4];
2789 tree type
, lhs
, rhs
, maskt
, biast
;
2790 rtx mem
, target
, mask
, bias
;
2793 maskt
= gimple_call_arg (stmt
, 2);
2794 lhs
= gimple_call_lhs (stmt
);
2795 if (lhs
== NULL_TREE
)
2797 type
= TREE_TYPE (lhs
);
2798 rhs
= expand_call_mem_ref (type
, stmt
, 0);
2800 if (optab
== vec_mask_load_lanes_optab
)
2801 icode
= get_multi_vector_move (type
, optab
);
2802 else if (optab
== len_load_optab
)
2803 icode
= direct_optab_handler (optab
, TYPE_MODE (type
));
2805 icode
= convert_optab_handler (optab
, TYPE_MODE (type
),
2806 TYPE_MODE (TREE_TYPE (maskt
)));
2808 mem
= expand_expr (rhs
, NULL_RTX
, VOIDmode
, EXPAND_WRITE
);
2809 gcc_assert (MEM_P (mem
));
2810 mask
= expand_normal (maskt
);
2811 target
= expand_expr (lhs
, NULL_RTX
, VOIDmode
, EXPAND_WRITE
);
2812 create_output_operand (&ops
[0], target
, TYPE_MODE (type
));
2813 create_fixed_operand (&ops
[1], mem
);
2814 if (optab
== len_load_optab
)
2816 create_convert_operand_from (&ops
[2], mask
, TYPE_MODE (TREE_TYPE (maskt
)),
2817 TYPE_UNSIGNED (TREE_TYPE (maskt
)));
2818 biast
= gimple_call_arg (stmt
, 3);
2819 bias
= expand_normal (biast
);
2820 create_input_operand (&ops
[3], bias
, QImode
);
2821 expand_insn (icode
, 4, ops
);
2825 create_input_operand (&ops
[2], mask
, TYPE_MODE (TREE_TYPE (maskt
)));
2826 expand_insn (icode
, 3, ops
);
2829 if (!rtx_equal_p (target
, ops
[0].value
))
2830 emit_move_insn (target
, ops
[0].value
);
2833 #define expand_mask_load_optab_fn expand_partial_load_optab_fn
2834 #define expand_mask_load_lanes_optab_fn expand_mask_load_optab_fn
2835 #define expand_len_load_optab_fn expand_partial_load_optab_fn
2837 /* Expand MASK_STORE{,_LANES} or LEN_STORE call STMT using optab OPTAB. */
2840 expand_partial_store_optab_fn (internal_fn
, gcall
*stmt
, convert_optab optab
)
2842 class expand_operand ops
[4];
2843 tree type
, lhs
, rhs
, maskt
, biast
;
2844 rtx mem
, reg
, mask
, bias
;
2847 maskt
= gimple_call_arg (stmt
, 2);
2848 rhs
= gimple_call_arg (stmt
, 3);
2849 type
= TREE_TYPE (rhs
);
2850 lhs
= expand_call_mem_ref (type
, stmt
, 0);
2852 if (optab
== vec_mask_store_lanes_optab
)
2853 icode
= get_multi_vector_move (type
, optab
);
2854 else if (optab
== len_store_optab
)
2855 icode
= direct_optab_handler (optab
, TYPE_MODE (type
));
2857 icode
= convert_optab_handler (optab
, TYPE_MODE (type
),
2858 TYPE_MODE (TREE_TYPE (maskt
)));
2860 mem
= expand_expr (lhs
, NULL_RTX
, VOIDmode
, EXPAND_WRITE
);
2861 gcc_assert (MEM_P (mem
));
2862 mask
= expand_normal (maskt
);
2863 reg
= expand_normal (rhs
);
2864 create_fixed_operand (&ops
[0], mem
);
2865 create_input_operand (&ops
[1], reg
, TYPE_MODE (type
));
2866 if (optab
== len_store_optab
)
2868 create_convert_operand_from (&ops
[2], mask
, TYPE_MODE (TREE_TYPE (maskt
)),
2869 TYPE_UNSIGNED (TREE_TYPE (maskt
)));
2870 biast
= gimple_call_arg (stmt
, 4);
2871 bias
= expand_normal (biast
);
2872 create_input_operand (&ops
[3], bias
, QImode
);
2873 expand_insn (icode
, 4, ops
);
2877 create_input_operand (&ops
[2], mask
, TYPE_MODE (TREE_TYPE (maskt
)));
2878 expand_insn (icode
, 3, ops
);
2882 #define expand_mask_store_optab_fn expand_partial_store_optab_fn
2883 #define expand_mask_store_lanes_optab_fn expand_mask_store_optab_fn
2884 #define expand_len_store_optab_fn expand_partial_store_optab_fn
2886 /* Expand VCOND, VCONDU and VCONDEQ optab internal functions.
2887 The expansion of STMT happens based on OPTAB table associated. */
2890 expand_vec_cond_optab_fn (internal_fn
, gcall
*stmt
, convert_optab optab
)
2892 class expand_operand ops
[6];
2894 tree lhs
= gimple_call_lhs (stmt
);
2895 tree op0a
= gimple_call_arg (stmt
, 0);
2896 tree op0b
= gimple_call_arg (stmt
, 1);
2897 tree op1
= gimple_call_arg (stmt
, 2);
2898 tree op2
= gimple_call_arg (stmt
, 3);
2899 enum tree_code tcode
= (tree_code
) int_cst_value (gimple_call_arg (stmt
, 4));
2901 tree vec_cond_type
= TREE_TYPE (lhs
);
2902 tree op_mode
= TREE_TYPE (op0a
);
2903 bool unsignedp
= TYPE_UNSIGNED (op_mode
);
2905 machine_mode mode
= TYPE_MODE (vec_cond_type
);
2906 machine_mode cmp_op_mode
= TYPE_MODE (op_mode
);
2908 icode
= convert_optab_handler (optab
, mode
, cmp_op_mode
);
2910 = vector_compare_rtx (VOIDmode
, tcode
, op0a
, op0b
, unsignedp
, icode
, 4);
2911 rtx rtx_op1
= expand_normal (op1
);
2912 rtx rtx_op2
= expand_normal (op2
);
2914 rtx target
= expand_expr (lhs
, NULL_RTX
, VOIDmode
, EXPAND_WRITE
);
2915 create_output_operand (&ops
[0], target
, mode
);
2916 create_input_operand (&ops
[1], rtx_op1
, mode
);
2917 create_input_operand (&ops
[2], rtx_op2
, mode
);
2918 create_fixed_operand (&ops
[3], comparison
);
2919 create_fixed_operand (&ops
[4], XEXP (comparison
, 0));
2920 create_fixed_operand (&ops
[5], XEXP (comparison
, 1));
2921 expand_insn (icode
, 6, ops
);
2922 if (!rtx_equal_p (ops
[0].value
, target
))
2923 emit_move_insn (target
, ops
[0].value
);
2926 /* Expand VCOND_MASK optab internal function.
2927 The expansion of STMT happens based on OPTAB table associated. */
2930 expand_vec_cond_mask_optab_fn (internal_fn
, gcall
*stmt
, convert_optab optab
)
2932 class expand_operand ops
[4];
2934 tree lhs
= gimple_call_lhs (stmt
);
2935 tree op0
= gimple_call_arg (stmt
, 0);
2936 tree op1
= gimple_call_arg (stmt
, 1);
2937 tree op2
= gimple_call_arg (stmt
, 2);
2938 tree vec_cond_type
= TREE_TYPE (lhs
);
2940 machine_mode mode
= TYPE_MODE (vec_cond_type
);
2941 machine_mode mask_mode
= TYPE_MODE (TREE_TYPE (op0
));
2942 enum insn_code icode
= convert_optab_handler (optab
, mode
, mask_mode
);
2943 rtx mask
, rtx_op1
, rtx_op2
;
2945 gcc_assert (icode
!= CODE_FOR_nothing
);
2947 mask
= expand_normal (op0
);
2948 rtx_op1
= expand_normal (op1
);
2949 rtx_op2
= expand_normal (op2
);
2951 mask
= force_reg (mask_mode
, mask
);
2952 rtx_op1
= force_reg (mode
, rtx_op1
);
2954 rtx target
= expand_expr (lhs
, NULL_RTX
, VOIDmode
, EXPAND_WRITE
);
2955 create_output_operand (&ops
[0], target
, mode
);
2956 create_input_operand (&ops
[1], rtx_op1
, mode
);
2957 create_input_operand (&ops
[2], rtx_op2
, mode
);
2958 create_input_operand (&ops
[3], mask
, mask_mode
);
2959 expand_insn (icode
, 4, ops
);
2960 if (!rtx_equal_p (ops
[0].value
, target
))
2961 emit_move_insn (target
, ops
[0].value
);
2964 /* Expand VEC_SET internal functions. */
2967 expand_vec_set_optab_fn (internal_fn
, gcall
*stmt
, convert_optab optab
)
2969 tree lhs
= gimple_call_lhs (stmt
);
2970 tree op0
= gimple_call_arg (stmt
, 0);
2971 tree op1
= gimple_call_arg (stmt
, 1);
2972 tree op2
= gimple_call_arg (stmt
, 2);
2973 rtx target
= expand_expr (lhs
, NULL_RTX
, VOIDmode
, EXPAND_WRITE
);
2974 rtx src
= expand_normal (op0
);
2976 machine_mode outermode
= TYPE_MODE (TREE_TYPE (op0
));
2977 scalar_mode innermode
= GET_MODE_INNER (outermode
);
2979 rtx value
= expand_normal (op1
);
2980 rtx pos
= expand_normal (op2
);
2982 class expand_operand ops
[3];
2983 enum insn_code icode
= optab_handler (optab
, outermode
);
2985 if (icode
!= CODE_FOR_nothing
)
2987 rtx temp
= gen_reg_rtx (outermode
);
2988 emit_move_insn (temp
, src
);
2990 create_fixed_operand (&ops
[0], temp
);
2991 create_input_operand (&ops
[1], value
, innermode
);
2992 create_convert_operand_from (&ops
[2], pos
, TYPE_MODE (TREE_TYPE (op2
)),
2994 if (maybe_expand_insn (icode
, 3, ops
))
2996 emit_move_insn (target
, temp
);
3004 expand_ABNORMAL_DISPATCHER (internal_fn
, gcall
*)
3009 expand_BUILTIN_EXPECT (internal_fn
, gcall
*stmt
)
3011 /* When guessing was done, the hints should be already stripped away. */
3012 gcc_assert (!flag_guess_branch_prob
|| optimize
== 0 || seen_error ());
3015 tree lhs
= gimple_call_lhs (stmt
);
3017 target
= expand_expr (lhs
, NULL_RTX
, VOIDmode
, EXPAND_WRITE
);
3019 target
= const0_rtx
;
3020 rtx val
= expand_expr (gimple_call_arg (stmt
, 0), target
, VOIDmode
, EXPAND_NORMAL
);
3021 if (lhs
&& val
!= target
)
3022 emit_move_insn (target
, val
);
3025 /* IFN_VA_ARG is supposed to be expanded at pass_stdarg. So this dummy function
3026 should never be called. */
3029 expand_VA_ARG (internal_fn
, gcall
*)
3034 /* IFN_VEC_CONVERT is supposed to be expanded at pass_lower_vector. So this
3035 dummy function should never be called. */
3038 expand_VEC_CONVERT (internal_fn
, gcall
*)
3043 /* Expand IFN_RAWMEMCHAR internal function. */
3046 expand_RAWMEMCHR (internal_fn
, gcall
*stmt
)
3048 expand_operand ops
[3];
3050 tree lhs
= gimple_call_lhs (stmt
);
3053 machine_mode lhs_mode
= TYPE_MODE (TREE_TYPE (lhs
));
3054 rtx lhs_rtx
= expand_expr (lhs
, NULL_RTX
, VOIDmode
, EXPAND_WRITE
);
3055 create_output_operand (&ops
[0], lhs_rtx
, lhs_mode
);
3057 tree mem
= gimple_call_arg (stmt
, 0);
3058 rtx mem_rtx
= get_memory_rtx (mem
, NULL
);
3059 create_fixed_operand (&ops
[1], mem_rtx
);
3061 tree pattern
= gimple_call_arg (stmt
, 1);
3062 machine_mode mode
= TYPE_MODE (TREE_TYPE (pattern
));
3063 rtx pattern_rtx
= expand_normal (pattern
);
3064 create_input_operand (&ops
[2], pattern_rtx
, mode
);
3066 insn_code icode
= direct_optab_handler (rawmemchr_optab
, mode
);
3068 expand_insn (icode
, 3, ops
);
3069 if (!rtx_equal_p (lhs_rtx
, ops
[0].value
))
3070 emit_move_insn (lhs_rtx
, ops
[0].value
);
3073 /* Expand the IFN_UNIQUE function according to its first argument. */
3076 expand_UNIQUE (internal_fn
, gcall
*stmt
)
3078 rtx pattern
= NULL_RTX
;
3079 enum ifn_unique_kind kind
3080 = (enum ifn_unique_kind
) TREE_INT_CST_LOW (gimple_call_arg (stmt
, 0));
3087 case IFN_UNIQUE_UNSPEC
:
3088 if (targetm
.have_unique ())
3089 pattern
= targetm
.gen_unique ();
3092 case IFN_UNIQUE_OACC_FORK
:
3093 case IFN_UNIQUE_OACC_JOIN
:
3094 if (targetm
.have_oacc_fork () && targetm
.have_oacc_join ())
3096 tree lhs
= gimple_call_lhs (stmt
);
3097 rtx target
= const0_rtx
;
3100 target
= expand_expr (lhs
, NULL_RTX
, VOIDmode
, EXPAND_WRITE
);
3102 rtx data_dep
= expand_normal (gimple_call_arg (stmt
, 1));
3103 rtx axis
= expand_normal (gimple_call_arg (stmt
, 2));
3105 if (kind
== IFN_UNIQUE_OACC_FORK
)
3106 pattern
= targetm
.gen_oacc_fork (target
, data_dep
, axis
);
3108 pattern
= targetm
.gen_oacc_join (target
, data_dep
, axis
);
3116 emit_insn (pattern
);
3119 /* Expand the IFN_DEFERRED_INIT function:
3120 LHS = DEFERRED_INIT (SIZE of the DECL, INIT_TYPE, NAME of the DECL);
3122 Initialize the LHS with zero/pattern according to its second argument
3124 if INIT_TYPE is AUTO_INIT_ZERO, use zeroes to initialize;
3125 if INIT_TYPE is AUTO_INIT_PATTERN, use 0xFE byte-repeatable pattern
3127 The LHS variable is initialized including paddings.
3128 The reasons to choose 0xFE for pattern initialization are:
3129 1. It is a non-canonical virtual address on x86_64, and at the
3130 high end of the i386 kernel address space.
3131 2. It is a very large float value (-1.694739530317379e+38).
3132 3. It is also an unusual number for integers. */
3133 #define INIT_PATTERN_VALUE 0xFE
3135 expand_DEFERRED_INIT (internal_fn
, gcall
*stmt
)
3137 tree lhs
= gimple_call_lhs (stmt
);
3138 tree var_size
= gimple_call_arg (stmt
, 0);
3139 enum auto_init_type init_type
3140 = (enum auto_init_type
) TREE_INT_CST_LOW (gimple_call_arg (stmt
, 1));
3141 bool reg_lhs
= true;
3143 tree var_type
= TREE_TYPE (lhs
);
3144 gcc_assert (init_type
> AUTO_INIT_UNINITIALIZED
);
3146 if (TREE_CODE (lhs
) == SSA_NAME
)
3150 tree lhs_base
= lhs
;
3151 while (handled_component_p (lhs_base
))
3152 lhs_base
= TREE_OPERAND (lhs_base
, 0);
3153 reg_lhs
= (mem_ref_refers_to_non_mem_p (lhs_base
)
3154 || non_mem_decl_p (lhs_base
));
3155 /* If this expands to a register and the underlying decl is wrapped in
3156 a MEM_REF that just serves as an access type change expose the decl
3157 if it is of correct size. This avoids a situation as in PR103271
3158 if the target does not support a direct move to the registers mode. */
3160 && TREE_CODE (lhs_base
) == MEM_REF
3161 && TREE_CODE (TREE_OPERAND (lhs_base
, 0)) == ADDR_EXPR
3162 && DECL_P (TREE_OPERAND (TREE_OPERAND (lhs_base
, 0), 0))
3163 && integer_zerop (TREE_OPERAND (lhs_base
, 1))
3164 && tree_fits_uhwi_p (var_size
)
3165 && tree_int_cst_equal
3167 DECL_SIZE_UNIT (TREE_OPERAND (TREE_OPERAND (lhs_base
, 0), 0))))
3169 lhs
= TREE_OPERAND (TREE_OPERAND (lhs_base
, 0), 0);
3170 var_type
= TREE_TYPE (lhs
);
3176 /* If the variable is not in register, expand to a memset
3177 to initialize it. */
3178 mark_addressable (lhs
);
3179 tree var_addr
= build_fold_addr_expr (lhs
);
3181 tree value
= (init_type
== AUTO_INIT_PATTERN
)
3182 ? build_int_cst (integer_type_node
,
3184 : integer_zero_node
;
3185 tree m_call
= build_call_expr (builtin_decl_implicit (BUILT_IN_MEMSET
),
3186 3, var_addr
, value
, var_size
);
3187 /* Expand this memset call. */
3188 expand_builtin_memset (m_call
, NULL_RTX
, TYPE_MODE (var_type
));
3192 /* If this variable is in a register use expand_assignment.
3193 For boolean scalars force zero-init. */
3195 scalar_int_mode var_mode
;
3196 if (TREE_CODE (TREE_TYPE (lhs
)) != BOOLEAN_TYPE
3197 && tree_fits_uhwi_p (var_size
)
3198 && (init_type
== AUTO_INIT_PATTERN
3199 || !is_gimple_reg_type (var_type
))
3200 && int_mode_for_size (tree_to_uhwi (var_size
) * BITS_PER_UNIT
,
3201 0).exists (&var_mode
)
3202 && have_insn_for (SET
, var_mode
))
3204 unsigned HOST_WIDE_INT total_bytes
= tree_to_uhwi (var_size
);
3205 unsigned char *buf
= XALLOCAVEC (unsigned char, total_bytes
);
3206 memset (buf
, (init_type
== AUTO_INIT_PATTERN
3207 ? INIT_PATTERN_VALUE
: 0), total_bytes
);
3208 tree itype
= build_nonstandard_integer_type
3209 (total_bytes
* BITS_PER_UNIT
, 1);
3210 wide_int w
= wi::from_buffer (buf
, total_bytes
);
3211 init
= wide_int_to_tree (itype
, w
);
3212 /* Pun the LHS to make sure its type has constant size
3213 unless it is an SSA name where that's already known. */
3214 if (TREE_CODE (lhs
) != SSA_NAME
)
3215 lhs
= build1 (VIEW_CONVERT_EXPR
, itype
, lhs
);
3217 init
= fold_build1 (VIEW_CONVERT_EXPR
, TREE_TYPE (lhs
), init
);
3220 /* Use zero-init also for variable-length sizes. */
3221 init
= build_zero_cst (var_type
);
3223 expand_assignment (lhs
, init
, false);
3227 /* The size of an OpenACC compute dimension. */
3230 expand_GOACC_DIM_SIZE (internal_fn
, gcall
*stmt
)
3232 tree lhs
= gimple_call_lhs (stmt
);
3237 rtx target
= expand_expr (lhs
, NULL_RTX
, VOIDmode
, EXPAND_WRITE
);
3238 if (targetm
.have_oacc_dim_size ())
3240 rtx dim
= expand_expr (gimple_call_arg (stmt
, 0), NULL_RTX
,
3241 VOIDmode
, EXPAND_NORMAL
);
3242 emit_insn (targetm
.gen_oacc_dim_size (target
, dim
));
3245 emit_move_insn (target
, GEN_INT (1));
3248 /* The position of an OpenACC execution engine along one compute axis. */
3251 expand_GOACC_DIM_POS (internal_fn
, gcall
*stmt
)
3253 tree lhs
= gimple_call_lhs (stmt
);
3258 rtx target
= expand_expr (lhs
, NULL_RTX
, VOIDmode
, EXPAND_WRITE
);
3259 if (targetm
.have_oacc_dim_pos ())
3261 rtx dim
= expand_expr (gimple_call_arg (stmt
, 0), NULL_RTX
,
3262 VOIDmode
, EXPAND_NORMAL
);
3263 emit_insn (targetm
.gen_oacc_dim_pos (target
, dim
));
3266 emit_move_insn (target
, const0_rtx
);
3269 /* This is expanded by oacc_device_lower pass. */
3272 expand_GOACC_LOOP (internal_fn
, gcall
*)
3277 /* This is expanded by oacc_device_lower pass. */
3280 expand_GOACC_REDUCTION (internal_fn
, gcall
*)
3285 /* This is expanded by oacc_device_lower pass. */
3288 expand_GOACC_TILE (internal_fn
, gcall
*)
3293 /* Set errno to EDOM. */
3296 expand_SET_EDOM (internal_fn
, gcall
*)
3299 #ifdef GEN_ERRNO_RTX
3300 rtx errno_rtx
= GEN_ERRNO_RTX
;
3302 rtx errno_rtx
= gen_rtx_MEM (word_mode
, gen_rtx_SYMBOL_REF (Pmode
, "errno"));
3304 emit_move_insn (errno_rtx
,
3305 gen_int_mode (TARGET_EDOM
, GET_MODE (errno_rtx
)));
3311 /* Expand atomic bit test and set. */
3314 expand_ATOMIC_BIT_TEST_AND_SET (internal_fn
, gcall
*call
)
3316 expand_ifn_atomic_bit_test_and (call
);
3319 /* Expand atomic bit test and complement. */
3322 expand_ATOMIC_BIT_TEST_AND_COMPLEMENT (internal_fn
, gcall
*call
)
3324 expand_ifn_atomic_bit_test_and (call
);
3327 /* Expand atomic bit test and reset. */
3330 expand_ATOMIC_BIT_TEST_AND_RESET (internal_fn
, gcall
*call
)
3332 expand_ifn_atomic_bit_test_and (call
);
3335 /* Expand atomic bit test and set. */
3338 expand_ATOMIC_COMPARE_EXCHANGE (internal_fn
, gcall
*call
)
3340 expand_ifn_atomic_compare_exchange (call
);
3343 /* Expand atomic add fetch and cmp with 0. */
3346 expand_ATOMIC_ADD_FETCH_CMP_0 (internal_fn
, gcall
*call
)
3348 expand_ifn_atomic_op_fetch_cmp_0 (call
);
3351 /* Expand atomic sub fetch and cmp with 0. */
3354 expand_ATOMIC_SUB_FETCH_CMP_0 (internal_fn
, gcall
*call
)
3356 expand_ifn_atomic_op_fetch_cmp_0 (call
);
3359 /* Expand atomic and fetch and cmp with 0. */
3362 expand_ATOMIC_AND_FETCH_CMP_0 (internal_fn
, gcall
*call
)
3364 expand_ifn_atomic_op_fetch_cmp_0 (call
);
3367 /* Expand atomic or fetch and cmp with 0. */
3370 expand_ATOMIC_OR_FETCH_CMP_0 (internal_fn
, gcall
*call
)
3372 expand_ifn_atomic_op_fetch_cmp_0 (call
);
3375 /* Expand atomic xor fetch and cmp with 0. */
3378 expand_ATOMIC_XOR_FETCH_CMP_0 (internal_fn
, gcall
*call
)
3380 expand_ifn_atomic_op_fetch_cmp_0 (call
);
3383 /* Expand LAUNDER to assignment, lhs = arg0. */
3386 expand_LAUNDER (internal_fn
, gcall
*call
)
3388 tree lhs
= gimple_call_lhs (call
);
3393 expand_assignment (lhs
, gimple_call_arg (call
, 0), false);
3396 /* Expand {MASK_,}SCATTER_STORE{S,U} call CALL using optab OPTAB. */
3399 expand_scatter_store_optab_fn (internal_fn
, gcall
*stmt
, direct_optab optab
)
3401 internal_fn ifn
= gimple_call_internal_fn (stmt
);
3402 int rhs_index
= internal_fn_stored_value_index (ifn
);
3403 int mask_index
= internal_fn_mask_index (ifn
);
3404 tree base
= gimple_call_arg (stmt
, 0);
3405 tree offset
= gimple_call_arg (stmt
, 1);
3406 tree scale
= gimple_call_arg (stmt
, 2);
3407 tree rhs
= gimple_call_arg (stmt
, rhs_index
);
3409 rtx base_rtx
= expand_normal (base
);
3410 rtx offset_rtx
= expand_normal (offset
);
3411 HOST_WIDE_INT scale_int
= tree_to_shwi (scale
);
3412 rtx rhs_rtx
= expand_normal (rhs
);
3414 class expand_operand ops
[6];
3416 create_address_operand (&ops
[i
++], base_rtx
);
3417 create_input_operand (&ops
[i
++], offset_rtx
, TYPE_MODE (TREE_TYPE (offset
)));
3418 create_integer_operand (&ops
[i
++], TYPE_UNSIGNED (TREE_TYPE (offset
)));
3419 create_integer_operand (&ops
[i
++], scale_int
);
3420 create_input_operand (&ops
[i
++], rhs_rtx
, TYPE_MODE (TREE_TYPE (rhs
)));
3421 if (mask_index
>= 0)
3423 tree mask
= gimple_call_arg (stmt
, mask_index
);
3424 rtx mask_rtx
= expand_normal (mask
);
3425 create_input_operand (&ops
[i
++], mask_rtx
, TYPE_MODE (TREE_TYPE (mask
)));
3428 insn_code icode
= convert_optab_handler (optab
, TYPE_MODE (TREE_TYPE (rhs
)),
3429 TYPE_MODE (TREE_TYPE (offset
)));
3430 expand_insn (icode
, i
, ops
);
3433 /* Expand {MASK_,}GATHER_LOAD call CALL using optab OPTAB. */
3436 expand_gather_load_optab_fn (internal_fn
, gcall
*stmt
, direct_optab optab
)
3438 tree lhs
= gimple_call_lhs (stmt
);
3439 tree base
= gimple_call_arg (stmt
, 0);
3440 tree offset
= gimple_call_arg (stmt
, 1);
3441 tree scale
= gimple_call_arg (stmt
, 2);
3443 rtx lhs_rtx
= expand_expr (lhs
, NULL_RTX
, VOIDmode
, EXPAND_WRITE
);
3444 rtx base_rtx
= expand_normal (base
);
3445 rtx offset_rtx
= expand_normal (offset
);
3446 HOST_WIDE_INT scale_int
= tree_to_shwi (scale
);
3449 class expand_operand ops
[6];
3450 create_output_operand (&ops
[i
++], lhs_rtx
, TYPE_MODE (TREE_TYPE (lhs
)));
3451 create_address_operand (&ops
[i
++], base_rtx
);
3452 create_input_operand (&ops
[i
++], offset_rtx
, TYPE_MODE (TREE_TYPE (offset
)));
3453 create_integer_operand (&ops
[i
++], TYPE_UNSIGNED (TREE_TYPE (offset
)));
3454 create_integer_operand (&ops
[i
++], scale_int
);
3455 if (optab
== mask_gather_load_optab
)
3457 tree mask
= gimple_call_arg (stmt
, 4);
3458 rtx mask_rtx
= expand_normal (mask
);
3459 create_input_operand (&ops
[i
++], mask_rtx
, TYPE_MODE (TREE_TYPE (mask
)));
3461 insn_code icode
= convert_optab_handler (optab
, TYPE_MODE (TREE_TYPE (lhs
)),
3462 TYPE_MODE (TREE_TYPE (offset
)));
3463 expand_insn (icode
, i
, ops
);
3464 if (!rtx_equal_p (lhs_rtx
, ops
[0].value
))
3465 emit_move_insn (lhs_rtx
, ops
[0].value
);
3468 /* Helper for expand_DIVMOD. Return true if the sequence starting with
3469 INSN contains any call insns or insns with {,U}{DIV,MOD} rtxes. */
3472 contains_call_div_mod (rtx_insn
*insn
)
3474 subrtx_iterator::array_type array
;
3475 for (; insn
; insn
= NEXT_INSN (insn
))
3478 else if (INSN_P (insn
))
3479 FOR_EACH_SUBRTX (iter
, array
, PATTERN (insn
), NONCONST
)
3480 switch (GET_CODE (*iter
))
3494 /* Expand DIVMOD() using:
3495 a) optab handler for udivmod/sdivmod if it is available.
3496 b) If optab_handler doesn't exist, generate call to
3497 target-specific divmod libfunc. */
3500 expand_DIVMOD (internal_fn
, gcall
*call_stmt
)
3502 tree lhs
= gimple_call_lhs (call_stmt
);
3503 tree arg0
= gimple_call_arg (call_stmt
, 0);
3504 tree arg1
= gimple_call_arg (call_stmt
, 1);
3506 gcc_assert (TREE_CODE (TREE_TYPE (lhs
)) == COMPLEX_TYPE
);
3507 tree type
= TREE_TYPE (TREE_TYPE (lhs
));
3508 machine_mode mode
= TYPE_MODE (type
);
3509 bool unsignedp
= TYPE_UNSIGNED (type
);
3510 optab tab
= (unsignedp
) ? udivmod_optab
: sdivmod_optab
;
3512 rtx op0
= expand_normal (arg0
);
3513 rtx op1
= expand_normal (arg1
);
3514 rtx target
= expand_expr (lhs
, NULL_RTX
, VOIDmode
, EXPAND_WRITE
);
3516 rtx quotient
= NULL_RTX
, remainder
= NULL_RTX
;
3517 rtx_insn
*insns
= NULL
;
3519 if (TREE_CODE (arg1
) == INTEGER_CST
)
3521 /* For DIVMOD by integral constants, there could be efficient code
3522 expanded inline e.g. using shifts and plus/minus. Try to expand
3523 the division and modulo and if it emits any library calls or any
3524 {,U}{DIV,MOD} rtxes throw it away and use a divmod optab or
3526 scalar_int_mode int_mode
;
3527 if (remainder
== NULL_RTX
3529 && CONST_INT_P (op1
)
3530 && !pow2p_hwi (INTVAL (op1
))
3531 && is_int_mode (TYPE_MODE (type
), &int_mode
)
3532 && GET_MODE_SIZE (int_mode
) == 2 * UNITS_PER_WORD
3533 && optab_handler (and_optab
, word_mode
) != CODE_FOR_nothing
3534 && optab_handler (add_optab
, word_mode
) != CODE_FOR_nothing
3535 && optimize_insn_for_speed_p ())
3537 rtx_insn
*last
= get_last_insn ();
3538 remainder
= NULL_RTX
;
3539 quotient
= expand_doubleword_divmod (int_mode
, op0
, op1
, &remainder
,
3540 TYPE_UNSIGNED (type
));
3541 if (quotient
!= NULL_RTX
)
3543 if (optab_handler (mov_optab
, int_mode
) != CODE_FOR_nothing
)
3545 rtx_insn
*move
= emit_move_insn (quotient
, quotient
);
3546 set_dst_reg_note (move
, REG_EQUAL
,
3547 gen_rtx_fmt_ee (TYPE_UNSIGNED (type
)
3548 ? UDIV
: DIV
, int_mode
,
3549 copy_rtx (op0
), op1
),
3551 move
= emit_move_insn (remainder
, remainder
);
3552 set_dst_reg_note (move
, REG_EQUAL
,
3553 gen_rtx_fmt_ee (TYPE_UNSIGNED (type
)
3554 ? UMOD
: MOD
, int_mode
,
3555 copy_rtx (op0
), op1
),
3560 delete_insns_since (last
);
3563 if (remainder
== NULL_RTX
)
3565 struct separate_ops ops
;
3566 ops
.code
= TRUNC_DIV_EXPR
;
3568 ops
.op0
= make_tree (ops
.type
, op0
);
3570 ops
.op2
= NULL_TREE
;
3571 ops
.location
= gimple_location (call_stmt
);
3573 quotient
= expand_expr_real_2 (&ops
, NULL_RTX
, mode
, EXPAND_NORMAL
);
3574 if (contains_call_div_mod (get_insns ()))
3575 quotient
= NULL_RTX
;
3578 ops
.code
= TRUNC_MOD_EXPR
;
3579 remainder
= expand_expr_real_2 (&ops
, NULL_RTX
, mode
,
3581 if (contains_call_div_mod (get_insns ()))
3582 remainder
= NULL_RTX
;
3585 insns
= get_insns ();
3593 /* Check if optab_handler exists for divmod_optab for given mode. */
3594 else if (optab_handler (tab
, mode
) != CODE_FOR_nothing
)
3596 quotient
= gen_reg_rtx (mode
);
3597 remainder
= gen_reg_rtx (mode
);
3598 expand_twoval_binop (tab
, op0
, op1
, quotient
, remainder
, unsignedp
);
3601 /* Generate call to divmod libfunc if it exists. */
3602 else if (rtx libfunc
= optab_libfunc (tab
, mode
))
3603 targetm
.expand_divmod_libfunc (libfunc
, mode
, op0
, op1
,
3604 "ient
, &remainder
);
3609 /* Wrap the return value (quotient, remainder) within COMPLEX_EXPR. */
3610 expand_expr (build2 (COMPLEX_EXPR
, TREE_TYPE (lhs
),
3611 make_tree (TREE_TYPE (arg0
), quotient
),
3612 make_tree (TREE_TYPE (arg1
), remainder
)),
3613 target
, VOIDmode
, EXPAND_NORMAL
);
3619 expand_NOP (internal_fn
, gcall
*)
3621 /* Nothing. But it shouldn't really prevail. */
3624 /* Coroutines, all should have been processed at this stage. */
3627 expand_CO_FRAME (internal_fn
, gcall
*)
3633 expand_CO_YIELD (internal_fn
, gcall
*)
3639 expand_CO_SUSPN (internal_fn
, gcall
*)
3645 expand_CO_ACTOR (internal_fn
, gcall
*)
3650 /* Expand a call to FN using the operands in STMT. FN has a single
3651 output operand and NARGS input operands. */
3654 expand_direct_optab_fn (internal_fn fn
, gcall
*stmt
, direct_optab optab
,
3657 tree_pair types
= direct_internal_fn_types (fn
, stmt
);
3658 insn_code icode
= direct_optab_handler (optab
, TYPE_MODE (types
.first
));
3659 expand_fn_using_insn (stmt
, icode
, 1, nargs
);
3662 /* Expand WHILE_ULT call STMT using optab OPTAB. */
3665 expand_while_optab_fn (internal_fn
, gcall
*stmt
, convert_optab optab
)
3667 expand_operand ops
[4];
3670 tree lhs
= gimple_call_lhs (stmt
);
3671 tree lhs_type
= TREE_TYPE (lhs
);
3672 rtx lhs_rtx
= expand_expr (lhs
, NULL_RTX
, VOIDmode
, EXPAND_WRITE
);
3673 create_output_operand (&ops
[0], lhs_rtx
, TYPE_MODE (lhs_type
));
3675 for (unsigned int i
= 0; i
< 2; ++i
)
3677 tree rhs
= gimple_call_arg (stmt
, i
);
3678 rhs_type
[i
] = TREE_TYPE (rhs
);
3679 rtx rhs_rtx
= expand_normal (rhs
);
3680 create_input_operand (&ops
[i
+ 1], rhs_rtx
, TYPE_MODE (rhs_type
[i
]));
3684 if (!VECTOR_MODE_P (TYPE_MODE (lhs_type
)))
3686 /* When the mask is an integer mode the exact vector length may not
3687 be clear to the backend, so we pass it in operand[3].
3688 Use the vector in arg2 for the most reliable intended size. */
3689 tree type
= TREE_TYPE (gimple_call_arg (stmt
, 2));
3690 create_integer_operand (&ops
[3], TYPE_VECTOR_SUBPARTS (type
));
3694 /* The mask has a vector type so the length operand is unnecessary. */
3697 insn_code icode
= convert_optab_handler (optab
, TYPE_MODE (rhs_type
[0]),
3698 TYPE_MODE (lhs_type
));
3700 expand_insn (icode
, opcnt
, ops
);
3701 if (!rtx_equal_p (lhs_rtx
, ops
[0].value
))
3702 emit_move_insn (lhs_rtx
, ops
[0].value
);
3705 /* Expand a call to a convert-like optab using the operands in STMT.
3706 FN has a single output operand and NARGS input operands. */
3709 expand_convert_optab_fn (internal_fn fn
, gcall
*stmt
, convert_optab optab
,
3712 tree_pair types
= direct_internal_fn_types (fn
, stmt
);
3713 insn_code icode
= convert_optab_handler (optab
, TYPE_MODE (types
.first
),
3714 TYPE_MODE (types
.second
));
3715 expand_fn_using_insn (stmt
, icode
, 1, nargs
);
3718 /* Expanders for optabs that can use expand_direct_optab_fn. */
3720 #define expand_unary_optab_fn(FN, STMT, OPTAB) \
3721 expand_direct_optab_fn (FN, STMT, OPTAB, 1)
3723 #define expand_binary_optab_fn(FN, STMT, OPTAB) \
3724 expand_direct_optab_fn (FN, STMT, OPTAB, 2)
3726 #define expand_ternary_optab_fn(FN, STMT, OPTAB) \
3727 expand_direct_optab_fn (FN, STMT, OPTAB, 3)
3729 #define expand_cond_unary_optab_fn(FN, STMT, OPTAB) \
3730 expand_direct_optab_fn (FN, STMT, OPTAB, 3)
3732 #define expand_cond_binary_optab_fn(FN, STMT, OPTAB) \
3733 expand_direct_optab_fn (FN, STMT, OPTAB, 4)
3735 #define expand_cond_ternary_optab_fn(FN, STMT, OPTAB) \
3736 expand_direct_optab_fn (FN, STMT, OPTAB, 5)
3738 #define expand_fold_extract_optab_fn(FN, STMT, OPTAB) \
3739 expand_direct_optab_fn (FN, STMT, OPTAB, 3)
3741 #define expand_fold_left_optab_fn(FN, STMT, OPTAB) \
3742 expand_direct_optab_fn (FN, STMT, OPTAB, 2)
3744 #define expand_mask_fold_left_optab_fn(FN, STMT, OPTAB) \
3745 expand_direct_optab_fn (FN, STMT, OPTAB, 3)
3747 #define expand_check_ptrs_optab_fn(FN, STMT, OPTAB) \
3748 expand_direct_optab_fn (FN, STMT, OPTAB, 4)
3750 /* Expanders for optabs that can use expand_convert_optab_fn. */
3752 #define expand_unary_convert_optab_fn(FN, STMT, OPTAB) \
3753 expand_convert_optab_fn (FN, STMT, OPTAB, 1)
3755 /* RETURN_TYPE and ARGS are a return type and argument list that are
3756 in principle compatible with FN (which satisfies direct_internal_fn_p).
3757 Return the types that should be used to determine whether the
3758 target supports FN. */
3761 direct_internal_fn_types (internal_fn fn
, tree return_type
, tree
*args
)
3763 const direct_internal_fn_info
&info
= direct_internal_fn (fn
);
3764 tree type0
= (info
.type0
< 0 ? return_type
: TREE_TYPE (args
[info
.type0
]));
3765 tree type1
= (info
.type1
< 0 ? return_type
: TREE_TYPE (args
[info
.type1
]));
3766 return tree_pair (type0
, type1
);
3769 /* CALL is a call whose return type and arguments are in principle
3770 compatible with FN (which satisfies direct_internal_fn_p). Return the
3771 types that should be used to determine whether the target supports FN. */
3774 direct_internal_fn_types (internal_fn fn
, gcall
*call
)
3776 const direct_internal_fn_info
&info
= direct_internal_fn (fn
);
3777 tree op0
= (info
.type0
< 0
3778 ? gimple_call_lhs (call
)
3779 : gimple_call_arg (call
, info
.type0
));
3780 tree op1
= (info
.type1
< 0
3781 ? gimple_call_lhs (call
)
3782 : gimple_call_arg (call
, info
.type1
));
3783 return tree_pair (TREE_TYPE (op0
), TREE_TYPE (op1
));
3786 /* Return true if OPTAB is supported for TYPES (whose modes should be
3787 the same) when the optimization type is OPT_TYPE. Used for simple
3791 direct_optab_supported_p (direct_optab optab
, tree_pair types
,
3792 optimization_type opt_type
)
3794 machine_mode mode
= TYPE_MODE (types
.first
);
3795 gcc_checking_assert (mode
== TYPE_MODE (types
.second
));
3796 return direct_optab_handler (optab
, mode
, opt_type
) != CODE_FOR_nothing
;
3799 /* Return true if OPTAB is supported for TYPES, where the first type
3800 is the destination and the second type is the source. Used for
3804 convert_optab_supported_p (convert_optab optab
, tree_pair types
,
3805 optimization_type opt_type
)
3807 return (convert_optab_handler (optab
, TYPE_MODE (types
.first
),
3808 TYPE_MODE (types
.second
), opt_type
)
3809 != CODE_FOR_nothing
);
3812 /* Return true if load/store lanes optab OPTAB is supported for
3813 array type TYPES.first when the optimization type is OPT_TYPE. */
3816 multi_vector_optab_supported_p (convert_optab optab
, tree_pair types
,
3817 optimization_type opt_type
)
3819 gcc_assert (TREE_CODE (types
.first
) == ARRAY_TYPE
);
3820 machine_mode imode
= TYPE_MODE (types
.first
);
3821 machine_mode vmode
= TYPE_MODE (TREE_TYPE (types
.first
));
3822 return (convert_optab_handler (optab
, imode
, vmode
, opt_type
)
3823 != CODE_FOR_nothing
);
3826 #define direct_unary_optab_supported_p direct_optab_supported_p
3827 #define direct_unary_convert_optab_supported_p convert_optab_supported_p
3828 #define direct_binary_optab_supported_p direct_optab_supported_p
3829 #define direct_ternary_optab_supported_p direct_optab_supported_p
3830 #define direct_cond_unary_optab_supported_p direct_optab_supported_p
3831 #define direct_cond_binary_optab_supported_p direct_optab_supported_p
3832 #define direct_cond_ternary_optab_supported_p direct_optab_supported_p
3833 #define direct_mask_load_optab_supported_p convert_optab_supported_p
3834 #define direct_load_lanes_optab_supported_p multi_vector_optab_supported_p
3835 #define direct_mask_load_lanes_optab_supported_p multi_vector_optab_supported_p
3836 #define direct_gather_load_optab_supported_p convert_optab_supported_p
3837 #define direct_len_load_optab_supported_p direct_optab_supported_p
3838 #define direct_mask_store_optab_supported_p convert_optab_supported_p
3839 #define direct_store_lanes_optab_supported_p multi_vector_optab_supported_p
3840 #define direct_mask_store_lanes_optab_supported_p multi_vector_optab_supported_p
3841 #define direct_vec_cond_mask_optab_supported_p convert_optab_supported_p
3842 #define direct_vec_cond_optab_supported_p convert_optab_supported_p
3843 #define direct_scatter_store_optab_supported_p convert_optab_supported_p
3844 #define direct_len_store_optab_supported_p direct_optab_supported_p
3845 #define direct_while_optab_supported_p convert_optab_supported_p
3846 #define direct_fold_extract_optab_supported_p direct_optab_supported_p
3847 #define direct_fold_left_optab_supported_p direct_optab_supported_p
3848 #define direct_mask_fold_left_optab_supported_p direct_optab_supported_p
3849 #define direct_check_ptrs_optab_supported_p direct_optab_supported_p
3850 #define direct_vec_set_optab_supported_p direct_optab_supported_p
3852 /* Return the optab used by internal function FN. */
3855 direct_internal_fn_optab (internal_fn fn
, tree_pair types
)
3859 #define DEF_INTERNAL_FN(CODE, FLAGS, FNSPEC) \
3860 case IFN_##CODE: break;
3861 #define DEF_INTERNAL_OPTAB_FN(CODE, FLAGS, OPTAB, TYPE) \
3862 case IFN_##CODE: return OPTAB##_optab;
3863 #define DEF_INTERNAL_SIGNED_OPTAB_FN(CODE, FLAGS, SELECTOR, SIGNED_OPTAB, \
3864 UNSIGNED_OPTAB, TYPE) \
3865 case IFN_##CODE: return (TYPE_UNSIGNED (types.SELECTOR) \
3866 ? UNSIGNED_OPTAB ## _optab \
3867 : SIGNED_OPTAB ## _optab);
3868 #include "internal-fn.def"
3876 /* Return the optab used by internal function FN. */
3879 direct_internal_fn_optab (internal_fn fn
)
3883 #define DEF_INTERNAL_FN(CODE, FLAGS, FNSPEC) \
3884 case IFN_##CODE: break;
3885 #define DEF_INTERNAL_OPTAB_FN(CODE, FLAGS, OPTAB, TYPE) \
3886 case IFN_##CODE: return OPTAB##_optab;
3887 #include "internal-fn.def"
3895 /* Return true if FN is supported for the types in TYPES when the
3896 optimization type is OPT_TYPE. The types are those associated with
3897 the "type0" and "type1" fields of FN's direct_internal_fn_info
3901 direct_internal_fn_supported_p (internal_fn fn
, tree_pair types
,
3902 optimization_type opt_type
)
3906 #define DEF_INTERNAL_FN(CODE, FLAGS, FNSPEC) \
3907 case IFN_##CODE: break;
3908 #define DEF_INTERNAL_OPTAB_FN(CODE, FLAGS, OPTAB, TYPE) \
3910 return direct_##TYPE##_optab_supported_p (OPTAB##_optab, types, \
3912 #define DEF_INTERNAL_SIGNED_OPTAB_FN(CODE, FLAGS, SELECTOR, SIGNED_OPTAB, \
3913 UNSIGNED_OPTAB, TYPE) \
3916 optab which_optab = (TYPE_UNSIGNED (types.SELECTOR) \
3917 ? UNSIGNED_OPTAB ## _optab \
3918 : SIGNED_OPTAB ## _optab); \
3919 return direct_##TYPE##_optab_supported_p (which_optab, types, \
3922 #include "internal-fn.def"
3930 /* Return true if FN is supported for type TYPE when the optimization
3931 type is OPT_TYPE. The caller knows that the "type0" and "type1"
3932 fields of FN's direct_internal_fn_info structure are the same. */
3935 direct_internal_fn_supported_p (internal_fn fn
, tree type
,
3936 optimization_type opt_type
)
3938 const direct_internal_fn_info
&info
= direct_internal_fn (fn
);
3939 gcc_checking_assert (info
.type0
== info
.type1
);
3940 return direct_internal_fn_supported_p (fn
, tree_pair (type
, type
), opt_type
);
3943 /* Return true if the STMT is supported when the optimization type is OPT_TYPE,
3944 given that STMT is a call to a direct internal function. */
3947 direct_internal_fn_supported_p (gcall
*stmt
, optimization_type opt_type
)
3949 internal_fn fn
= gimple_call_internal_fn (stmt
);
3950 tree_pair types
= direct_internal_fn_types (fn
, stmt
);
3951 return direct_internal_fn_supported_p (fn
, types
, opt_type
);
3954 /* Return true if FN is a binary operation and if FN is commutative. */
3957 commutative_binary_fn_p (internal_fn fn
)
3968 case IFN_COMPLEX_MUL
:
3969 case IFN_UBSAN_CHECK_ADD
:
3970 case IFN_UBSAN_CHECK_MUL
:
3971 case IFN_ADD_OVERFLOW
:
3972 case IFN_MUL_OVERFLOW
:
3980 /* Return true if FN is a ternary operation and if its first two arguments
3984 commutative_ternary_fn_p (internal_fn fn
)
3999 /* Return true if FN is an associative binary operation. */
4002 associative_binary_fn_p (internal_fn fn
)
4015 /* If FN is commutative in two consecutive arguments, return the
4016 index of the first, otherwise return -1. */
4019 first_commutative_argument (internal_fn fn
)
4039 if (commutative_binary_fn_p (fn
)
4040 || commutative_ternary_fn_p (fn
))
4046 /* Return true if IFN_SET_EDOM is supported. */
4049 set_edom_supported_p (void)
4058 #define DEF_INTERNAL_OPTAB_FN(CODE, FLAGS, OPTAB, TYPE) \
4060 expand_##CODE (internal_fn fn, gcall *stmt) \
4062 expand_##TYPE##_optab_fn (fn, stmt, OPTAB##_optab); \
4064 #define DEF_INTERNAL_SIGNED_OPTAB_FN(CODE, FLAGS, SELECTOR, SIGNED_OPTAB, \
4065 UNSIGNED_OPTAB, TYPE) \
4067 expand_##CODE (internal_fn fn, gcall *stmt) \
4069 tree_pair types = direct_internal_fn_types (fn, stmt); \
4070 optab which_optab = direct_internal_fn_optab (fn, types); \
4071 expand_##TYPE##_optab_fn (fn, stmt, which_optab); \
4073 #include "internal-fn.def"
4075 /* Routines to expand each internal function, indexed by function number.
4076 Each routine has the prototype:
4078 expand_<NAME> (gcall *stmt)
4080 where STMT is the statement that performs the call. */
4081 static void (*const internal_fn_expanders
[]) (internal_fn
, gcall
*) = {
4082 #define DEF_INTERNAL_FN(CODE, FLAGS, FNSPEC) expand_##CODE,
4083 #include "internal-fn.def"
4087 /* Invoke T(CODE, IFN) for each conditional function IFN that maps to a
4089 #define FOR_EACH_CODE_MAPPING(T) \
4090 T (PLUS_EXPR, IFN_COND_ADD) \
4091 T (MINUS_EXPR, IFN_COND_SUB) \
4092 T (MULT_EXPR, IFN_COND_MUL) \
4093 T (TRUNC_DIV_EXPR, IFN_COND_DIV) \
4094 T (TRUNC_MOD_EXPR, IFN_COND_MOD) \
4095 T (RDIV_EXPR, IFN_COND_RDIV) \
4096 T (MIN_EXPR, IFN_COND_MIN) \
4097 T (MAX_EXPR, IFN_COND_MAX) \
4098 T (BIT_AND_EXPR, IFN_COND_AND) \
4099 T (BIT_IOR_EXPR, IFN_COND_IOR) \
4100 T (BIT_XOR_EXPR, IFN_COND_XOR) \
4101 T (LSHIFT_EXPR, IFN_COND_SHL) \
4102 T (RSHIFT_EXPR, IFN_COND_SHR) \
4103 T (NEGATE_EXPR, IFN_COND_NEG)
4105 /* Return a function that only performs CODE when a certain condition is met
4106 and that uses a given fallback value otherwise. For example, if CODE is
4107 a binary operation associated with conditional function FN:
4109 LHS = FN (COND, A, B, ELSE)
4111 is equivalent to the C expression:
4113 LHS = COND ? A CODE B : ELSE;
4115 operating elementwise if the operands are vectors.
4117 Return IFN_LAST if no such function exists. */
4120 get_conditional_internal_fn (tree_code code
)
4124 #define CASE(CODE, IFN) case CODE: return IFN;
4125 FOR_EACH_CODE_MAPPING(CASE
)
4132 /* If IFN implements the conditional form of a tree code, return that
4133 tree code, otherwise return ERROR_MARK. */
4136 conditional_internal_fn_code (internal_fn ifn
)
4140 #define CASE(CODE, IFN) case IFN: return CODE;
4141 FOR_EACH_CODE_MAPPING(CASE
)
4148 /* Invoke T(IFN) for each internal function IFN that also has an
4150 #define FOR_EACH_COND_FN_PAIR(T) \
4158 /* Return a function that only performs internal function FN when a
4159 certain condition is met and that uses a given fallback value otherwise.
4160 In other words, the returned function FN' is such that:
4162 LHS = FN' (COND, A1, ... An, ELSE)
4164 is equivalent to the C expression:
4166 LHS = COND ? FN (A1, ..., An) : ELSE;
4168 operating elementwise if the operands are vectors.
4170 Return IFN_LAST if no such function exists. */
4173 get_conditional_internal_fn (internal_fn fn
)
4177 #define CASE(NAME) case IFN_##NAME: return IFN_COND_##NAME;
4178 FOR_EACH_COND_FN_PAIR(CASE
)
4185 /* If IFN implements the conditional form of an unconditional internal
4186 function, return that unconditional function, otherwise return IFN_LAST. */
4189 get_unconditional_internal_fn (internal_fn ifn
)
4193 #define CASE(NAME) case IFN_COND_##NAME: return IFN_##NAME;
4194 FOR_EACH_COND_FN_PAIR(CASE
)
4201 /* Return true if STMT can be interpreted as a conditional tree code
4202 operation of the form:
4204 LHS = COND ? OP (RHS1, ...) : ELSE;
4206 operating elementwise if the operands are vectors. This includes
4207 the case of an all-true COND, so that the operation always happens.
4209 When returning true, set:
4211 - *COND_OUT to the condition COND, or to NULL_TREE if the condition
4212 is known to be all-true
4213 - *CODE_OUT to the tree code
4214 - OPS[I] to operand I of *CODE_OUT
4215 - *ELSE_OUT to the fallback value ELSE, or to NULL_TREE if the
4216 condition is known to be all true. */
4219 can_interpret_as_conditional_op_p (gimple
*stmt
, tree
*cond_out
,
4220 tree_code
*code_out
,
4221 tree (&ops
)[3], tree
*else_out
)
4223 if (gassign
*assign
= dyn_cast
<gassign
*> (stmt
))
4225 *cond_out
= NULL_TREE
;
4226 *code_out
= gimple_assign_rhs_code (assign
);
4227 ops
[0] = gimple_assign_rhs1 (assign
);
4228 ops
[1] = gimple_assign_rhs2 (assign
);
4229 ops
[2] = gimple_assign_rhs3 (assign
);
4230 *else_out
= NULL_TREE
;
4233 if (gcall
*call
= dyn_cast
<gcall
*> (stmt
))
4234 if (gimple_call_internal_p (call
))
4236 internal_fn ifn
= gimple_call_internal_fn (call
);
4237 tree_code code
= conditional_internal_fn_code (ifn
);
4238 if (code
!= ERROR_MARK
)
4240 *cond_out
= gimple_call_arg (call
, 0);
4242 unsigned int nops
= gimple_call_num_args (call
) - 2;
4243 for (unsigned int i
= 0; i
< 3; ++i
)
4244 ops
[i
] = i
< nops
? gimple_call_arg (call
, i
+ 1) : NULL_TREE
;
4245 *else_out
= gimple_call_arg (call
, nops
+ 1);
4246 if (integer_truep (*cond_out
))
4248 *cond_out
= NULL_TREE
;
4249 *else_out
= NULL_TREE
;
4257 /* Return true if IFN is some form of load from memory. */
4260 internal_load_fn_p (internal_fn fn
)
4265 case IFN_LOAD_LANES
:
4266 case IFN_MASK_LOAD_LANES
:
4267 case IFN_GATHER_LOAD
:
4268 case IFN_MASK_GATHER_LOAD
:
4277 /* Return true if IFN is some form of store to memory. */
4280 internal_store_fn_p (internal_fn fn
)
4284 case IFN_MASK_STORE
:
4285 case IFN_STORE_LANES
:
4286 case IFN_MASK_STORE_LANES
:
4287 case IFN_SCATTER_STORE
:
4288 case IFN_MASK_SCATTER_STORE
:
4297 /* Return true if IFN is some form of gather load or scatter store. */
4300 internal_gather_scatter_fn_p (internal_fn fn
)
4304 case IFN_GATHER_LOAD
:
4305 case IFN_MASK_GATHER_LOAD
:
4306 case IFN_SCATTER_STORE
:
4307 case IFN_MASK_SCATTER_STORE
:
4315 /* If FN takes a vector mask argument, return the index of that argument,
4316 otherwise return -1. */
4319 internal_fn_mask_index (internal_fn fn
)
4324 case IFN_MASK_LOAD_LANES
:
4325 case IFN_MASK_STORE
:
4326 case IFN_MASK_STORE_LANES
:
4329 case IFN_MASK_GATHER_LOAD
:
4330 case IFN_MASK_SCATTER_STORE
:
4334 return (conditional_internal_fn_code (fn
) != ERROR_MARK
4335 || get_unconditional_internal_fn (fn
) != IFN_LAST
? 0 : -1);
4339 /* If FN takes a value that should be stored to memory, return the index
4340 of that argument, otherwise return -1. */
4343 internal_fn_stored_value_index (internal_fn fn
)
4347 case IFN_MASK_STORE
:
4348 case IFN_MASK_STORE_LANES
:
4349 case IFN_SCATTER_STORE
:
4350 case IFN_MASK_SCATTER_STORE
:
4359 /* Return true if the target supports gather load or scatter store function
4360 IFN. For loads, VECTOR_TYPE is the vector type of the load result,
4361 while for stores it is the vector type of the stored data argument.
4362 MEMORY_ELEMENT_TYPE is the type of the memory elements being loaded
4363 or stored. OFFSET_VECTOR_TYPE is the vector type that holds the
4364 offset from the shared base address of each loaded or stored element.
4365 SCALE is the amount by which these offsets should be multiplied
4366 *after* they have been extended to address width. */
4369 internal_gather_scatter_fn_supported_p (internal_fn ifn
, tree vector_type
,
4370 tree memory_element_type
,
4371 tree offset_vector_type
, int scale
)
4373 if (!tree_int_cst_equal (TYPE_SIZE (TREE_TYPE (vector_type
)),
4374 TYPE_SIZE (memory_element_type
)))
4376 if (maybe_ne (TYPE_VECTOR_SUBPARTS (vector_type
),
4377 TYPE_VECTOR_SUBPARTS (offset_vector_type
)))
4379 optab optab
= direct_internal_fn_optab (ifn
);
4380 insn_code icode
= convert_optab_handler (optab
, TYPE_MODE (vector_type
),
4381 TYPE_MODE (offset_vector_type
));
4382 int output_ops
= internal_load_fn_p (ifn
) ? 1 : 0;
4383 bool unsigned_p
= TYPE_UNSIGNED (TREE_TYPE (offset_vector_type
));
4384 return (icode
!= CODE_FOR_nothing
4385 && insn_operand_matches (icode
, 2 + output_ops
, GEN_INT (unsigned_p
))
4386 && insn_operand_matches (icode
, 3 + output_ops
, GEN_INT (scale
)));
4389 /* Return true if the target supports IFN_CHECK_{RAW,WAR}_PTRS function IFN
4390 for pointers of type TYPE when the accesses have LENGTH bytes and their
4391 common byte alignment is ALIGN. */
4394 internal_check_ptrs_fn_supported_p (internal_fn ifn
, tree type
,
4395 poly_uint64 length
, unsigned int align
)
4397 machine_mode mode
= TYPE_MODE (type
);
4398 optab optab
= direct_internal_fn_optab (ifn
);
4399 insn_code icode
= direct_optab_handler (optab
, mode
);
4400 if (icode
== CODE_FOR_nothing
)
4402 rtx length_rtx
= immed_wide_int_const (length
, mode
);
4403 return (insn_operand_matches (icode
, 3, length_rtx
)
4404 && insn_operand_matches (icode
, 4, GEN_INT (align
)));
4407 /* Return the supported bias for IFN which is either IFN_LEN_LOAD
4408 or IFN_LEN_STORE. For now we only support the biases of 0 and -1
4409 (in case 0 is not an allowable length for len_load or len_store).
4410 If none of the biases match what the backend provides, return
4411 VECT_PARTIAL_BIAS_UNSUPPORTED. */
4414 internal_len_load_store_bias (internal_fn ifn
, machine_mode mode
)
4416 optab optab
= direct_internal_fn_optab (ifn
);
4417 insn_code icode
= direct_optab_handler (optab
, mode
);
4419 if (icode
!= CODE_FOR_nothing
)
4421 /* For now we only support biases of 0 or -1. Try both of them. */
4422 if (insn_operand_matches (icode
, 3, GEN_INT (0)))
4424 if (insn_operand_matches (icode
, 3, GEN_INT (-1)))
4428 return VECT_PARTIAL_BIAS_UNSUPPORTED
;
4431 /* Expand STMT as though it were a call to internal function FN. */
4434 expand_internal_call (internal_fn fn
, gcall
*stmt
)
4436 internal_fn_expanders
[fn
] (fn
, stmt
);
4439 /* Expand STMT, which is a call to internal function FN. */
4442 expand_internal_call (gcall
*stmt
)
4444 expand_internal_call (gimple_call_internal_fn (stmt
), stmt
);
4447 /* If TYPE is a vector type, return true if IFN is a direct internal
4448 function that is supported for that type. If TYPE is a scalar type,
4449 return true if IFN is a direct internal function that is supported for
4450 the target's preferred vector version of TYPE. */
4453 vectorized_internal_fn_supported_p (internal_fn ifn
, tree type
)
4455 if (VECTOR_MODE_P (TYPE_MODE (type
)))
4456 return direct_internal_fn_supported_p (ifn
, type
, OPTIMIZE_FOR_SPEED
);
4459 if (VECTOR_TYPE_P (type
)
4460 || !is_a
<scalar_mode
> (TYPE_MODE (type
), &smode
))
4463 machine_mode vmode
= targetm
.vectorize
.preferred_simd_mode (smode
);
4464 if (VECTOR_MODE_P (vmode
))
4466 tree vectype
= build_vector_type_for_mode (type
, vmode
);
4467 if (direct_internal_fn_supported_p (ifn
, vectype
, OPTIMIZE_FOR_SPEED
))
4471 auto_vector_modes vector_modes
;
4472 targetm
.vectorize
.autovectorize_vector_modes (&vector_modes
, true);
4473 for (machine_mode base_mode
: vector_modes
)
4474 if (related_vector_mode (base_mode
, smode
).exists (&vmode
))
4476 tree vectype
= build_vector_type_for_mode (type
, vmode
);
4477 if (direct_internal_fn_supported_p (ifn
, vectype
, OPTIMIZE_FOR_SPEED
))
4485 expand_SHUFFLEVECTOR (internal_fn
, gcall
*)
4491 expand_PHI (internal_fn
, gcall
*)
4497 expand_SPACESHIP (internal_fn
, gcall
*stmt
)
4499 tree lhs
= gimple_call_lhs (stmt
);
4500 tree rhs1
= gimple_call_arg (stmt
, 0);
4501 tree rhs2
= gimple_call_arg (stmt
, 1);
4502 tree type
= TREE_TYPE (rhs1
);
4504 do_pending_stack_adjust ();
4506 rtx target
= expand_expr (lhs
, NULL_RTX
, VOIDmode
, EXPAND_WRITE
);
4507 rtx op1
= expand_normal (rhs1
);
4508 rtx op2
= expand_normal (rhs2
);
4510 class expand_operand ops
[3];
4511 create_output_operand (&ops
[0], target
, TYPE_MODE (TREE_TYPE (lhs
)));
4512 create_input_operand (&ops
[1], op1
, TYPE_MODE (type
));
4513 create_input_operand (&ops
[2], op2
, TYPE_MODE (type
));
4514 insn_code icode
= optab_handler (spaceship_optab
, TYPE_MODE (type
));
4515 expand_insn (icode
, 3, ops
);
4516 if (!rtx_equal_p (target
, ops
[0].value
))
4517 emit_move_insn (target
, ops
[0].value
);
4521 expand_ASSUME (internal_fn
, gcall
*)
4526 expand_MASK_CALL (internal_fn
, gcall
*)
4528 /* This IFN should only exist between ifcvt and vect passes. */