]> git.ipfire.org Git - thirdparty/gcc.git/blob - gcc/internal-fn.c
re PR target/82274 (__builtin_mul_overflow fails to detect overflow for int64_t when...
[thirdparty/gcc.git] / gcc / internal-fn.c
1 /* Internal functions.
2 Copyright (C) 2011-2017 Free Software Foundation, Inc.
3
4 This file is part of GCC.
5
6 GCC is free software; you can redistribute it and/or modify it under
7 the terms of the GNU General Public License as published by the Free
8 Software Foundation; either version 3, or (at your option) any later
9 version.
10
11 GCC is distributed in the hope that it will be useful, but WITHOUT ANY
12 WARRANTY; without even the implied warranty of MERCHANTABILITY or
13 FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License
14 for more details.
15
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/>. */
19
20 #include "config.h"
21 #include "system.h"
22 #include "coretypes.h"
23 #include "backend.h"
24 #include "target.h"
25 #include "rtl.h"
26 #include "tree.h"
27 #include "gimple.h"
28 #include "predict.h"
29 #include "stringpool.h"
30 #include "tree-vrp.h"
31 #include "tree-ssanames.h"
32 #include "expmed.h"
33 #include "memmodel.h"
34 #include "optabs.h"
35 #include "emit-rtl.h"
36 #include "diagnostic-core.h"
37 #include "fold-const.h"
38 #include "internal-fn.h"
39 #include "stor-layout.h"
40 #include "dojump.h"
41 #include "expr.h"
42 #include "stringpool.h"
43 #include "attribs.h"
44 #include "asan.h"
45 #include "ubsan.h"
46 #include "recog.h"
47 #include "builtins.h"
48 #include "optabs-tree.h"
49
50 /* The names of each internal function, indexed by function number. */
51 const char *const internal_fn_name_array[] = {
52 #define DEF_INTERNAL_FN(CODE, FLAGS, FNSPEC) #CODE,
53 #include "internal-fn.def"
54 "<invalid-fn>"
55 };
56
57 /* The ECF_* flags of each internal function, indexed by function number. */
58 const int internal_fn_flags_array[] = {
59 #define DEF_INTERNAL_FN(CODE, FLAGS, FNSPEC) FLAGS,
60 #include "internal-fn.def"
61 0
62 };
63
64 /* Fnspec of each internal function, indexed by function number. */
65 const_tree internal_fn_fnspec_array[IFN_LAST + 1];
66
67 void
68 init_internal_fns ()
69 {
70 #define DEF_INTERNAL_FN(CODE, FLAGS, FNSPEC) \
71 if (FNSPEC) internal_fn_fnspec_array[IFN_##CODE] = \
72 build_string ((int) sizeof (FNSPEC), FNSPEC ? FNSPEC : "");
73 #include "internal-fn.def"
74 internal_fn_fnspec_array[IFN_LAST] = 0;
75 }
76
77 /* Create static initializers for the information returned by
78 direct_internal_fn. */
79 #define not_direct { -2, -2, false }
80 #define mask_load_direct { -1, 2, false }
81 #define load_lanes_direct { -1, -1, false }
82 #define mask_store_direct { 3, 2, false }
83 #define store_lanes_direct { 0, 0, false }
84 #define unary_direct { 0, 0, true }
85 #define binary_direct { 0, 0, true }
86
87 const direct_internal_fn_info direct_internal_fn_array[IFN_LAST + 1] = {
88 #define DEF_INTERNAL_FN(CODE, FLAGS, FNSPEC) not_direct,
89 #define DEF_INTERNAL_OPTAB_FN(CODE, FLAGS, OPTAB, TYPE) TYPE##_direct,
90 #include "internal-fn.def"
91 not_direct
92 };
93
94 /* ARRAY_TYPE is an array of vector modes. Return the associated insn
95 for load-lanes-style optab OPTAB, or CODE_FOR_nothing if none. */
96
97 static enum insn_code
98 get_multi_vector_move (tree array_type, convert_optab optab)
99 {
100 machine_mode imode;
101 machine_mode vmode;
102
103 gcc_assert (TREE_CODE (array_type) == ARRAY_TYPE);
104 imode = TYPE_MODE (array_type);
105 vmode = TYPE_MODE (TREE_TYPE (array_type));
106
107 return convert_optab_handler (optab, imode, vmode);
108 }
109
110 /* Expand LOAD_LANES call STMT using optab OPTAB. */
111
112 static void
113 expand_load_lanes_optab_fn (internal_fn, gcall *stmt, convert_optab optab)
114 {
115 struct expand_operand ops[2];
116 tree type, lhs, rhs;
117 rtx target, mem;
118
119 lhs = gimple_call_lhs (stmt);
120 rhs = gimple_call_arg (stmt, 0);
121 type = TREE_TYPE (lhs);
122
123 target = expand_expr (lhs, NULL_RTX, VOIDmode, EXPAND_WRITE);
124 mem = expand_normal (rhs);
125
126 gcc_assert (MEM_P (mem));
127 PUT_MODE (mem, TYPE_MODE (type));
128
129 create_output_operand (&ops[0], target, TYPE_MODE (type));
130 create_fixed_operand (&ops[1], mem);
131 expand_insn (get_multi_vector_move (type, optab), 2, ops);
132 }
133
134 /* Expand STORE_LANES call STMT using optab OPTAB. */
135
136 static void
137 expand_store_lanes_optab_fn (internal_fn, gcall *stmt, convert_optab optab)
138 {
139 struct expand_operand ops[2];
140 tree type, lhs, rhs;
141 rtx target, reg;
142
143 lhs = gimple_call_lhs (stmt);
144 rhs = gimple_call_arg (stmt, 0);
145 type = TREE_TYPE (rhs);
146
147 target = expand_expr (lhs, NULL_RTX, VOIDmode, EXPAND_WRITE);
148 reg = expand_normal (rhs);
149
150 gcc_assert (MEM_P (target));
151 PUT_MODE (target, TYPE_MODE (type));
152
153 create_fixed_operand (&ops[0], target);
154 create_input_operand (&ops[1], reg, TYPE_MODE (type));
155 expand_insn (get_multi_vector_move (type, optab), 2, ops);
156 }
157
158 static void
159 expand_ANNOTATE (internal_fn, gcall *)
160 {
161 gcc_unreachable ();
162 }
163
164 /* This should get expanded in omp_device_lower pass. */
165
166 static void
167 expand_GOMP_USE_SIMT (internal_fn, gcall *)
168 {
169 gcc_unreachable ();
170 }
171
172 /* This should get expanded in omp_device_lower pass. */
173
174 static void
175 expand_GOMP_SIMT_ENTER (internal_fn, gcall *)
176 {
177 gcc_unreachable ();
178 }
179
180 /* Allocate per-lane storage and begin non-uniform execution region. */
181
182 static void
183 expand_GOMP_SIMT_ENTER_ALLOC (internal_fn, gcall *stmt)
184 {
185 rtx target;
186 tree lhs = gimple_call_lhs (stmt);
187 if (lhs)
188 target = expand_expr (lhs, NULL_RTX, VOIDmode, EXPAND_WRITE);
189 else
190 target = gen_reg_rtx (Pmode);
191 rtx size = expand_normal (gimple_call_arg (stmt, 0));
192 rtx align = expand_normal (gimple_call_arg (stmt, 1));
193 struct expand_operand ops[3];
194 create_output_operand (&ops[0], target, Pmode);
195 create_input_operand (&ops[1], size, Pmode);
196 create_input_operand (&ops[2], align, Pmode);
197 gcc_assert (targetm.have_omp_simt_enter ());
198 expand_insn (targetm.code_for_omp_simt_enter, 3, ops);
199 }
200
201 /* Deallocate per-lane storage and leave non-uniform execution region. */
202
203 static void
204 expand_GOMP_SIMT_EXIT (internal_fn, gcall *stmt)
205 {
206 gcc_checking_assert (!gimple_call_lhs (stmt));
207 rtx arg = expand_normal (gimple_call_arg (stmt, 0));
208 struct expand_operand ops[1];
209 create_input_operand (&ops[0], arg, Pmode);
210 gcc_assert (targetm.have_omp_simt_exit ());
211 expand_insn (targetm.code_for_omp_simt_exit, 1, ops);
212 }
213
214 /* Lane index on SIMT targets: thread index in the warp on NVPTX. On targets
215 without SIMT execution this should be expanded in omp_device_lower pass. */
216
217 static void
218 expand_GOMP_SIMT_LANE (internal_fn, gcall *stmt)
219 {
220 tree lhs = gimple_call_lhs (stmt);
221 if (!lhs)
222 return;
223
224 rtx target = expand_expr (lhs, NULL_RTX, VOIDmode, EXPAND_WRITE);
225 gcc_assert (targetm.have_omp_simt_lane ());
226 emit_insn (targetm.gen_omp_simt_lane (target));
227 }
228
229 /* This should get expanded in omp_device_lower pass. */
230
231 static void
232 expand_GOMP_SIMT_VF (internal_fn, gcall *)
233 {
234 gcc_unreachable ();
235 }
236
237 /* Lane index of the first SIMT lane that supplies a non-zero argument.
238 This is a SIMT counterpart to GOMP_SIMD_LAST_LANE, used to represent the
239 lane that executed the last iteration for handling OpenMP lastprivate. */
240
241 static void
242 expand_GOMP_SIMT_LAST_LANE (internal_fn, gcall *stmt)
243 {
244 tree lhs = gimple_call_lhs (stmt);
245 if (!lhs)
246 return;
247
248 rtx target = expand_expr (lhs, NULL_RTX, VOIDmode, EXPAND_WRITE);
249 rtx cond = expand_normal (gimple_call_arg (stmt, 0));
250 machine_mode mode = TYPE_MODE (TREE_TYPE (lhs));
251 struct expand_operand ops[2];
252 create_output_operand (&ops[0], target, mode);
253 create_input_operand (&ops[1], cond, mode);
254 gcc_assert (targetm.have_omp_simt_last_lane ());
255 expand_insn (targetm.code_for_omp_simt_last_lane, 2, ops);
256 }
257
258 /* Non-transparent predicate used in SIMT lowering of OpenMP "ordered". */
259
260 static void
261 expand_GOMP_SIMT_ORDERED_PRED (internal_fn, gcall *stmt)
262 {
263 tree lhs = gimple_call_lhs (stmt);
264 if (!lhs)
265 return;
266
267 rtx target = expand_expr (lhs, NULL_RTX, VOIDmode, EXPAND_WRITE);
268 rtx ctr = expand_normal (gimple_call_arg (stmt, 0));
269 machine_mode mode = TYPE_MODE (TREE_TYPE (lhs));
270 struct expand_operand ops[2];
271 create_output_operand (&ops[0], target, mode);
272 create_input_operand (&ops[1], ctr, mode);
273 gcc_assert (targetm.have_omp_simt_ordered ());
274 expand_insn (targetm.code_for_omp_simt_ordered, 2, ops);
275 }
276
277 /* "Or" boolean reduction across SIMT lanes: return non-zero in all lanes if
278 any lane supplies a non-zero argument. */
279
280 static void
281 expand_GOMP_SIMT_VOTE_ANY (internal_fn, gcall *stmt)
282 {
283 tree lhs = gimple_call_lhs (stmt);
284 if (!lhs)
285 return;
286
287 rtx target = expand_expr (lhs, NULL_RTX, VOIDmode, EXPAND_WRITE);
288 rtx cond = expand_normal (gimple_call_arg (stmt, 0));
289 machine_mode mode = TYPE_MODE (TREE_TYPE (lhs));
290 struct expand_operand ops[2];
291 create_output_operand (&ops[0], target, mode);
292 create_input_operand (&ops[1], cond, mode);
293 gcc_assert (targetm.have_omp_simt_vote_any ());
294 expand_insn (targetm.code_for_omp_simt_vote_any, 2, ops);
295 }
296
297 /* Exchange between SIMT lanes with a "butterfly" pattern: source lane index
298 is destination lane index XOR given offset. */
299
300 static void
301 expand_GOMP_SIMT_XCHG_BFLY (internal_fn, gcall *stmt)
302 {
303 tree lhs = gimple_call_lhs (stmt);
304 if (!lhs)
305 return;
306
307 rtx target = expand_expr (lhs, NULL_RTX, VOIDmode, EXPAND_WRITE);
308 rtx src = expand_normal (gimple_call_arg (stmt, 0));
309 rtx idx = expand_normal (gimple_call_arg (stmt, 1));
310 machine_mode mode = TYPE_MODE (TREE_TYPE (lhs));
311 struct expand_operand ops[3];
312 create_output_operand (&ops[0], target, mode);
313 create_input_operand (&ops[1], src, mode);
314 create_input_operand (&ops[2], idx, SImode);
315 gcc_assert (targetm.have_omp_simt_xchg_bfly ());
316 expand_insn (targetm.code_for_omp_simt_xchg_bfly, 3, ops);
317 }
318
319 /* Exchange between SIMT lanes according to given source lane index. */
320
321 static void
322 expand_GOMP_SIMT_XCHG_IDX (internal_fn, gcall *stmt)
323 {
324 tree lhs = gimple_call_lhs (stmt);
325 if (!lhs)
326 return;
327
328 rtx target = expand_expr (lhs, NULL_RTX, VOIDmode, EXPAND_WRITE);
329 rtx src = expand_normal (gimple_call_arg (stmt, 0));
330 rtx idx = expand_normal (gimple_call_arg (stmt, 1));
331 machine_mode mode = TYPE_MODE (TREE_TYPE (lhs));
332 struct expand_operand ops[3];
333 create_output_operand (&ops[0], target, mode);
334 create_input_operand (&ops[1], src, mode);
335 create_input_operand (&ops[2], idx, SImode);
336 gcc_assert (targetm.have_omp_simt_xchg_idx ());
337 expand_insn (targetm.code_for_omp_simt_xchg_idx, 3, ops);
338 }
339
340 /* This should get expanded in adjust_simduid_builtins. */
341
342 static void
343 expand_GOMP_SIMD_LANE (internal_fn, gcall *)
344 {
345 gcc_unreachable ();
346 }
347
348 /* This should get expanded in adjust_simduid_builtins. */
349
350 static void
351 expand_GOMP_SIMD_VF (internal_fn, gcall *)
352 {
353 gcc_unreachable ();
354 }
355
356 /* This should get expanded in adjust_simduid_builtins. */
357
358 static void
359 expand_GOMP_SIMD_LAST_LANE (internal_fn, gcall *)
360 {
361 gcc_unreachable ();
362 }
363
364 /* This should get expanded in adjust_simduid_builtins. */
365
366 static void
367 expand_GOMP_SIMD_ORDERED_START (internal_fn, gcall *)
368 {
369 gcc_unreachable ();
370 }
371
372 /* This should get expanded in adjust_simduid_builtins. */
373
374 static void
375 expand_GOMP_SIMD_ORDERED_END (internal_fn, gcall *)
376 {
377 gcc_unreachable ();
378 }
379
380 /* This should get expanded in the sanopt pass. */
381
382 static void
383 expand_UBSAN_NULL (internal_fn, gcall *)
384 {
385 gcc_unreachable ();
386 }
387
388 /* This should get expanded in the sanopt pass. */
389
390 static void
391 expand_UBSAN_BOUNDS (internal_fn, gcall *)
392 {
393 gcc_unreachable ();
394 }
395
396 /* This should get expanded in the sanopt pass. */
397
398 static void
399 expand_UBSAN_VPTR (internal_fn, gcall *)
400 {
401 gcc_unreachable ();
402 }
403
404 /* This should get expanded in the sanopt pass. */
405
406 static void
407 expand_UBSAN_PTR (internal_fn, gcall *)
408 {
409 gcc_unreachable ();
410 }
411
412 /* This should get expanded in the sanopt pass. */
413
414 static void
415 expand_UBSAN_OBJECT_SIZE (internal_fn, gcall *)
416 {
417 gcc_unreachable ();
418 }
419
420 /* This should get expanded in the sanopt pass. */
421
422 static void
423 expand_ASAN_CHECK (internal_fn, gcall *)
424 {
425 gcc_unreachable ();
426 }
427
428 /* This should get expanded in the sanopt pass. */
429
430 static void
431 expand_ASAN_MARK (internal_fn, gcall *)
432 {
433 gcc_unreachable ();
434 }
435
436 /* This should get expanded in the sanopt pass. */
437
438 static void
439 expand_ASAN_POISON (internal_fn, gcall *)
440 {
441 gcc_unreachable ();
442 }
443
444 /* This should get expanded in the sanopt pass. */
445
446 static void
447 expand_ASAN_POISON_USE (internal_fn, gcall *)
448 {
449 gcc_unreachable ();
450 }
451
452 /* This should get expanded in the tsan pass. */
453
454 static void
455 expand_TSAN_FUNC_EXIT (internal_fn, gcall *)
456 {
457 gcc_unreachable ();
458 }
459
460 /* This should get expanded in the lower pass. */
461
462 static void
463 expand_FALLTHROUGH (internal_fn, gcall *call)
464 {
465 error_at (gimple_location (call),
466 "invalid use of attribute %<fallthrough%>");
467 }
468
469 /* Return minimum precision needed to represent all values
470 of ARG in SIGNed integral type. */
471
472 static int
473 get_min_precision (tree arg, signop sign)
474 {
475 int prec = TYPE_PRECISION (TREE_TYPE (arg));
476 int cnt = 0;
477 signop orig_sign = sign;
478 if (TREE_CODE (arg) == INTEGER_CST)
479 {
480 int p;
481 if (TYPE_SIGN (TREE_TYPE (arg)) != sign)
482 {
483 widest_int w = wi::to_widest (arg);
484 w = wi::ext (w, prec, sign);
485 p = wi::min_precision (w, sign);
486 }
487 else
488 p = wi::min_precision (wi::to_wide (arg), sign);
489 return MIN (p, prec);
490 }
491 while (CONVERT_EXPR_P (arg)
492 && INTEGRAL_TYPE_P (TREE_TYPE (TREE_OPERAND (arg, 0)))
493 && TYPE_PRECISION (TREE_TYPE (TREE_OPERAND (arg, 0))) <= prec)
494 {
495 arg = TREE_OPERAND (arg, 0);
496 if (TYPE_PRECISION (TREE_TYPE (arg)) < prec)
497 {
498 if (TYPE_UNSIGNED (TREE_TYPE (arg)))
499 sign = UNSIGNED;
500 else if (sign == UNSIGNED && get_range_pos_neg (arg) != 1)
501 return prec + (orig_sign != sign);
502 prec = TYPE_PRECISION (TREE_TYPE (arg));
503 }
504 if (++cnt > 30)
505 return prec + (orig_sign != sign);
506 }
507 if (TREE_CODE (arg) != SSA_NAME)
508 return prec + (orig_sign != sign);
509 wide_int arg_min, arg_max;
510 while (get_range_info (arg, &arg_min, &arg_max) != VR_RANGE)
511 {
512 gimple *g = SSA_NAME_DEF_STMT (arg);
513 if (is_gimple_assign (g)
514 && CONVERT_EXPR_CODE_P (gimple_assign_rhs_code (g)))
515 {
516 tree t = gimple_assign_rhs1 (g);
517 if (INTEGRAL_TYPE_P (TREE_TYPE (t))
518 && TYPE_PRECISION (TREE_TYPE (t)) <= prec)
519 {
520 arg = t;
521 if (TYPE_PRECISION (TREE_TYPE (arg)) < prec)
522 {
523 if (TYPE_UNSIGNED (TREE_TYPE (arg)))
524 sign = UNSIGNED;
525 else if (sign == UNSIGNED && get_range_pos_neg (arg) != 1)
526 return prec + (orig_sign != sign);
527 prec = TYPE_PRECISION (TREE_TYPE (arg));
528 }
529 if (++cnt > 30)
530 return prec + (orig_sign != sign);
531 continue;
532 }
533 }
534 return prec + (orig_sign != sign);
535 }
536 if (sign == TYPE_SIGN (TREE_TYPE (arg)))
537 {
538 int p1 = wi::min_precision (arg_min, sign);
539 int p2 = wi::min_precision (arg_max, sign);
540 p1 = MAX (p1, p2);
541 prec = MIN (prec, p1);
542 }
543 else if (sign == UNSIGNED && !wi::neg_p (arg_min, SIGNED))
544 {
545 int p = wi::min_precision (arg_max, UNSIGNED);
546 prec = MIN (prec, p);
547 }
548 return prec + (orig_sign != sign);
549 }
550
551 /* Helper for expand_*_overflow. Set the __imag__ part to true
552 (1 except for signed:1 type, in which case store -1). */
553
554 static void
555 expand_arith_set_overflow (tree lhs, rtx target)
556 {
557 if (TYPE_PRECISION (TREE_TYPE (TREE_TYPE (lhs))) == 1
558 && !TYPE_UNSIGNED (TREE_TYPE (TREE_TYPE (lhs))))
559 write_complex_part (target, constm1_rtx, true);
560 else
561 write_complex_part (target, const1_rtx, true);
562 }
563
564 /* Helper for expand_*_overflow. Store RES into the __real__ part
565 of TARGET. If RES has larger MODE than __real__ part of TARGET,
566 set the __imag__ part to 1 if RES doesn't fit into it. Similarly
567 if LHS has smaller precision than its mode. */
568
569 static void
570 expand_arith_overflow_result_store (tree lhs, rtx target,
571 scalar_int_mode mode, rtx res)
572 {
573 scalar_int_mode tgtmode
574 = as_a <scalar_int_mode> (GET_MODE_INNER (GET_MODE (target)));
575 rtx lres = res;
576 if (tgtmode != mode)
577 {
578 rtx_code_label *done_label = gen_label_rtx ();
579 int uns = TYPE_UNSIGNED (TREE_TYPE (TREE_TYPE (lhs)));
580 lres = convert_modes (tgtmode, mode, res, uns);
581 gcc_assert (GET_MODE_PRECISION (tgtmode) < GET_MODE_PRECISION (mode));
582 do_compare_rtx_and_jump (res, convert_modes (mode, tgtmode, lres, uns),
583 EQ, true, mode, NULL_RTX, NULL, done_label,
584 profile_probability::very_likely ());
585 expand_arith_set_overflow (lhs, target);
586 emit_label (done_label);
587 }
588 int prec = TYPE_PRECISION (TREE_TYPE (TREE_TYPE (lhs)));
589 int tgtprec = GET_MODE_PRECISION (tgtmode);
590 if (prec < tgtprec)
591 {
592 rtx_code_label *done_label = gen_label_rtx ();
593 int uns = TYPE_UNSIGNED (TREE_TYPE (TREE_TYPE (lhs)));
594 res = lres;
595 if (uns)
596 {
597 rtx mask
598 = immed_wide_int_const (wi::shifted_mask (0, prec, false, tgtprec),
599 tgtmode);
600 lres = expand_simple_binop (tgtmode, AND, res, mask, NULL_RTX,
601 true, OPTAB_LIB_WIDEN);
602 }
603 else
604 {
605 lres = expand_shift (LSHIFT_EXPR, tgtmode, res, tgtprec - prec,
606 NULL_RTX, 1);
607 lres = expand_shift (RSHIFT_EXPR, tgtmode, lres, tgtprec - prec,
608 NULL_RTX, 0);
609 }
610 do_compare_rtx_and_jump (res, lres,
611 EQ, true, tgtmode, NULL_RTX, NULL, done_label,
612 profile_probability::very_likely ());
613 expand_arith_set_overflow (lhs, target);
614 emit_label (done_label);
615 }
616 write_complex_part (target, lres, false);
617 }
618
619 /* Helper for expand_*_overflow. Store RES into TARGET. */
620
621 static void
622 expand_ubsan_result_store (rtx target, rtx res)
623 {
624 if (GET_CODE (target) == SUBREG && SUBREG_PROMOTED_VAR_P (target))
625 /* If this is a scalar in a register that is stored in a wider mode
626 than the declared mode, compute the result into its declared mode
627 and then convert to the wider mode. Our value is the computed
628 expression. */
629 convert_move (SUBREG_REG (target), res, SUBREG_PROMOTED_SIGN (target));
630 else
631 emit_move_insn (target, res);
632 }
633
634 /* Add sub/add overflow checking to the statement STMT.
635 CODE says whether the operation is +, or -. */
636
637 static void
638 expand_addsub_overflow (location_t loc, tree_code code, tree lhs,
639 tree arg0, tree arg1, bool unsr_p, bool uns0_p,
640 bool uns1_p, bool is_ubsan, tree *datap)
641 {
642 rtx res, target = NULL_RTX;
643 tree fn;
644 rtx_code_label *done_label = gen_label_rtx ();
645 rtx_code_label *do_error = gen_label_rtx ();
646 do_pending_stack_adjust ();
647 rtx op0 = expand_normal (arg0);
648 rtx op1 = expand_normal (arg1);
649 scalar_int_mode mode = SCALAR_INT_TYPE_MODE (TREE_TYPE (arg0));
650 int prec = GET_MODE_PRECISION (mode);
651 rtx sgn = immed_wide_int_const (wi::min_value (prec, SIGNED), mode);
652 bool do_xor = false;
653
654 if (is_ubsan)
655 gcc_assert (!unsr_p && !uns0_p && !uns1_p);
656
657 if (lhs)
658 {
659 target = expand_expr (lhs, NULL_RTX, VOIDmode, EXPAND_WRITE);
660 if (!is_ubsan)
661 write_complex_part (target, const0_rtx, true);
662 }
663
664 /* We assume both operands and result have the same precision
665 here (GET_MODE_BITSIZE (mode)), S stands for signed type
666 with that precision, U for unsigned type with that precision,
667 sgn for unsigned most significant bit in that precision.
668 s1 is signed first operand, u1 is unsigned first operand,
669 s2 is signed second operand, u2 is unsigned second operand,
670 sr is signed result, ur is unsigned result and the following
671 rules say how to compute result (which is always result of
672 the operands as if both were unsigned, cast to the right
673 signedness) and how to compute whether operation overflowed.
674
675 s1 + s2 -> sr
676 res = (S) ((U) s1 + (U) s2)
677 ovf = s2 < 0 ? res > s1 : res < s1 (or jump on overflow)
678 s1 - s2 -> sr
679 res = (S) ((U) s1 - (U) s2)
680 ovf = s2 < 0 ? res < s1 : res > s2 (or jump on overflow)
681 u1 + u2 -> ur
682 res = u1 + u2
683 ovf = res < u1 (or jump on carry, but RTL opts will handle it)
684 u1 - u2 -> ur
685 res = u1 - u2
686 ovf = res > u1 (or jump on carry, but RTL opts will handle it)
687 s1 + u2 -> sr
688 res = (S) ((U) s1 + u2)
689 ovf = ((U) res ^ sgn) < u2
690 s1 + u2 -> ur
691 t1 = (S) (u2 ^ sgn)
692 t2 = s1 + t1
693 res = (U) t2 ^ sgn
694 ovf = t1 < 0 ? t2 > s1 : t2 < s1 (or jump on overflow)
695 s1 - u2 -> sr
696 res = (S) ((U) s1 - u2)
697 ovf = u2 > ((U) s1 ^ sgn)
698 s1 - u2 -> ur
699 res = (U) s1 - u2
700 ovf = s1 < 0 || u2 > (U) s1
701 u1 - s2 -> sr
702 res = u1 - (U) s2
703 ovf = u1 >= ((U) s2 ^ sgn)
704 u1 - s2 -> ur
705 t1 = u1 ^ sgn
706 t2 = t1 - (U) s2
707 res = t2 ^ sgn
708 ovf = s2 < 0 ? (S) t2 < (S) t1 : (S) t2 > (S) t1 (or jump on overflow)
709 s1 + s2 -> ur
710 res = (U) s1 + (U) s2
711 ovf = s2 < 0 ? (s1 | (S) res) < 0) : (s1 & (S) res) < 0)
712 u1 + u2 -> sr
713 res = (S) (u1 + u2)
714 ovf = (U) res < u2 || res < 0
715 u1 - u2 -> sr
716 res = (S) (u1 - u2)
717 ovf = u1 >= u2 ? res < 0 : res >= 0
718 s1 - s2 -> ur
719 res = (U) s1 - (U) s2
720 ovf = s2 >= 0 ? ((s1 | (S) res) < 0) : ((s1 & (S) res) < 0) */
721
722 if (code == PLUS_EXPR && uns0_p && !uns1_p)
723 {
724 /* PLUS_EXPR is commutative, if operand signedness differs,
725 canonicalize to the first operand being signed and second
726 unsigned to simplify following code. */
727 std::swap (op0, op1);
728 std::swap (arg0, arg1);
729 uns0_p = false;
730 uns1_p = true;
731 }
732
733 /* u1 +- u2 -> ur */
734 if (uns0_p && uns1_p && unsr_p)
735 {
736 insn_code icode = optab_handler (code == PLUS_EXPR ? uaddv4_optab
737 : usubv4_optab, mode);
738 if (icode != CODE_FOR_nothing)
739 {
740 struct expand_operand ops[4];
741 rtx_insn *last = get_last_insn ();
742
743 res = gen_reg_rtx (mode);
744 create_output_operand (&ops[0], res, mode);
745 create_input_operand (&ops[1], op0, mode);
746 create_input_operand (&ops[2], op1, mode);
747 create_fixed_operand (&ops[3], do_error);
748 if (maybe_expand_insn (icode, 4, ops))
749 {
750 last = get_last_insn ();
751 if (profile_status_for_fn (cfun) != PROFILE_ABSENT
752 && JUMP_P (last)
753 && any_condjump_p (last)
754 && !find_reg_note (last, REG_BR_PROB, 0))
755 add_reg_br_prob_note (last,
756 profile_probability::very_unlikely ());
757 emit_jump (done_label);
758 goto do_error_label;
759 }
760
761 delete_insns_since (last);
762 }
763
764 /* Compute the operation. On RTL level, the addition is always
765 unsigned. */
766 res = expand_binop (mode, code == PLUS_EXPR ? add_optab : sub_optab,
767 op0, op1, NULL_RTX, false, OPTAB_LIB_WIDEN);
768 rtx tem = op0;
769 /* For PLUS_EXPR, the operation is commutative, so we can pick
770 operand to compare against. For prec <= BITS_PER_WORD, I think
771 preferring REG operand is better over CONST_INT, because
772 the CONST_INT might enlarge the instruction or CSE would need
773 to figure out we'd already loaded it into a register before.
774 For prec > BITS_PER_WORD, I think CONST_INT might be more beneficial,
775 as then the multi-word comparison can be perhaps simplified. */
776 if (code == PLUS_EXPR
777 && (prec <= BITS_PER_WORD
778 ? (CONST_SCALAR_INT_P (op0) && REG_P (op1))
779 : CONST_SCALAR_INT_P (op1)))
780 tem = op1;
781 do_compare_rtx_and_jump (res, tem, code == PLUS_EXPR ? GEU : LEU,
782 true, mode, NULL_RTX, NULL, done_label,
783 profile_probability::very_likely ());
784 goto do_error_label;
785 }
786
787 /* s1 +- u2 -> sr */
788 if (!uns0_p && uns1_p && !unsr_p)
789 {
790 /* Compute the operation. On RTL level, the addition is always
791 unsigned. */
792 res = expand_binop (mode, code == PLUS_EXPR ? add_optab : sub_optab,
793 op0, op1, NULL_RTX, false, OPTAB_LIB_WIDEN);
794 rtx tem = expand_binop (mode, add_optab,
795 code == PLUS_EXPR ? res : op0, sgn,
796 NULL_RTX, false, OPTAB_LIB_WIDEN);
797 do_compare_rtx_and_jump (tem, op1, GEU, true, mode, NULL_RTX, NULL,
798 done_label, profile_probability::very_likely ());
799 goto do_error_label;
800 }
801
802 /* s1 + u2 -> ur */
803 if (code == PLUS_EXPR && !uns0_p && uns1_p && unsr_p)
804 {
805 op1 = expand_binop (mode, add_optab, op1, sgn, NULL_RTX, false,
806 OPTAB_LIB_WIDEN);
807 /* As we've changed op1, we have to avoid using the value range
808 for the original argument. */
809 arg1 = error_mark_node;
810 do_xor = true;
811 goto do_signed;
812 }
813
814 /* u1 - s2 -> ur */
815 if (code == MINUS_EXPR && uns0_p && !uns1_p && unsr_p)
816 {
817 op0 = expand_binop (mode, add_optab, op0, sgn, NULL_RTX, false,
818 OPTAB_LIB_WIDEN);
819 /* As we've changed op0, we have to avoid using the value range
820 for the original argument. */
821 arg0 = error_mark_node;
822 do_xor = true;
823 goto do_signed;
824 }
825
826 /* s1 - u2 -> ur */
827 if (code == MINUS_EXPR && !uns0_p && uns1_p && unsr_p)
828 {
829 /* Compute the operation. On RTL level, the addition is always
830 unsigned. */
831 res = expand_binop (mode, sub_optab, op0, op1, NULL_RTX, false,
832 OPTAB_LIB_WIDEN);
833 int pos_neg = get_range_pos_neg (arg0);
834 if (pos_neg == 2)
835 /* If ARG0 is known to be always negative, this is always overflow. */
836 emit_jump (do_error);
837 else if (pos_neg == 3)
838 /* If ARG0 is not known to be always positive, check at runtime. */
839 do_compare_rtx_and_jump (op0, const0_rtx, LT, false, mode, NULL_RTX,
840 NULL, do_error, profile_probability::very_unlikely ());
841 do_compare_rtx_and_jump (op1, op0, LEU, true, mode, NULL_RTX, NULL,
842 done_label, profile_probability::very_likely ());
843 goto do_error_label;
844 }
845
846 /* u1 - s2 -> sr */
847 if (code == MINUS_EXPR && uns0_p && !uns1_p && !unsr_p)
848 {
849 /* Compute the operation. On RTL level, the addition is always
850 unsigned. */
851 res = expand_binop (mode, sub_optab, op0, op1, NULL_RTX, false,
852 OPTAB_LIB_WIDEN);
853 rtx tem = expand_binop (mode, add_optab, op1, sgn, NULL_RTX, false,
854 OPTAB_LIB_WIDEN);
855 do_compare_rtx_and_jump (op0, tem, LTU, true, mode, NULL_RTX, NULL,
856 done_label, profile_probability::very_likely ());
857 goto do_error_label;
858 }
859
860 /* u1 + u2 -> sr */
861 if (code == PLUS_EXPR && uns0_p && uns1_p && !unsr_p)
862 {
863 /* Compute the operation. On RTL level, the addition is always
864 unsigned. */
865 res = expand_binop (mode, add_optab, op0, op1, NULL_RTX, false,
866 OPTAB_LIB_WIDEN);
867 do_compare_rtx_and_jump (res, const0_rtx, LT, false, mode, NULL_RTX,
868 NULL, do_error, profile_probability::very_unlikely ());
869 rtx tem = op1;
870 /* The operation is commutative, so we can pick operand to compare
871 against. For prec <= BITS_PER_WORD, I think preferring REG operand
872 is better over CONST_INT, because the CONST_INT might enlarge the
873 instruction or CSE would need to figure out we'd already loaded it
874 into a register before. For prec > BITS_PER_WORD, I think CONST_INT
875 might be more beneficial, as then the multi-word comparison can be
876 perhaps simplified. */
877 if (prec <= BITS_PER_WORD
878 ? (CONST_SCALAR_INT_P (op1) && REG_P (op0))
879 : CONST_SCALAR_INT_P (op0))
880 tem = op0;
881 do_compare_rtx_and_jump (res, tem, GEU, true, mode, NULL_RTX, NULL,
882 done_label, profile_probability::very_likely ());
883 goto do_error_label;
884 }
885
886 /* s1 +- s2 -> ur */
887 if (!uns0_p && !uns1_p && unsr_p)
888 {
889 /* Compute the operation. On RTL level, the addition is always
890 unsigned. */
891 res = expand_binop (mode, code == PLUS_EXPR ? add_optab : sub_optab,
892 op0, op1, NULL_RTX, false, OPTAB_LIB_WIDEN);
893 int pos_neg = get_range_pos_neg (arg1);
894 if (code == PLUS_EXPR)
895 {
896 int pos_neg0 = get_range_pos_neg (arg0);
897 if (pos_neg0 != 3 && pos_neg == 3)
898 {
899 std::swap (op0, op1);
900 pos_neg = pos_neg0;
901 }
902 }
903 rtx tem;
904 if (pos_neg != 3)
905 {
906 tem = expand_binop (mode, ((pos_neg == 1) ^ (code == MINUS_EXPR))
907 ? and_optab : ior_optab,
908 op0, res, NULL_RTX, false, OPTAB_LIB_WIDEN);
909 do_compare_rtx_and_jump (tem, const0_rtx, GE, false, mode, NULL,
910 NULL, done_label, profile_probability::very_likely ());
911 }
912 else
913 {
914 rtx_code_label *do_ior_label = gen_label_rtx ();
915 do_compare_rtx_and_jump (op1, const0_rtx,
916 code == MINUS_EXPR ? GE : LT, false, mode,
917 NULL_RTX, NULL, do_ior_label,
918 profile_probability::even ());
919 tem = expand_binop (mode, and_optab, op0, res, NULL_RTX, false,
920 OPTAB_LIB_WIDEN);
921 do_compare_rtx_and_jump (tem, const0_rtx, GE, false, mode, NULL_RTX,
922 NULL, done_label, profile_probability::very_likely ());
923 emit_jump (do_error);
924 emit_label (do_ior_label);
925 tem = expand_binop (mode, ior_optab, op0, res, NULL_RTX, false,
926 OPTAB_LIB_WIDEN);
927 do_compare_rtx_and_jump (tem, const0_rtx, GE, false, mode, NULL_RTX,
928 NULL, done_label, profile_probability::very_likely ());
929 }
930 goto do_error_label;
931 }
932
933 /* u1 - u2 -> sr */
934 if (code == MINUS_EXPR && uns0_p && uns1_p && !unsr_p)
935 {
936 /* Compute the operation. On RTL level, the addition is always
937 unsigned. */
938 res = expand_binop (mode, sub_optab, op0, op1, NULL_RTX, false,
939 OPTAB_LIB_WIDEN);
940 rtx_code_label *op0_geu_op1 = gen_label_rtx ();
941 do_compare_rtx_and_jump (op0, op1, GEU, true, mode, NULL_RTX, NULL,
942 op0_geu_op1, profile_probability::even ());
943 do_compare_rtx_and_jump (res, const0_rtx, LT, false, mode, NULL_RTX,
944 NULL, done_label, profile_probability::very_likely ());
945 emit_jump (do_error);
946 emit_label (op0_geu_op1);
947 do_compare_rtx_and_jump (res, const0_rtx, GE, false, mode, NULL_RTX,
948 NULL, done_label, profile_probability::very_likely ());
949 goto do_error_label;
950 }
951
952 gcc_assert (!uns0_p && !uns1_p && !unsr_p);
953
954 /* s1 +- s2 -> sr */
955 do_signed:
956 {
957 insn_code icode = optab_handler (code == PLUS_EXPR ? addv4_optab
958 : subv4_optab, mode);
959 if (icode != CODE_FOR_nothing)
960 {
961 struct expand_operand ops[4];
962 rtx_insn *last = get_last_insn ();
963
964 res = gen_reg_rtx (mode);
965 create_output_operand (&ops[0], res, mode);
966 create_input_operand (&ops[1], op0, mode);
967 create_input_operand (&ops[2], op1, mode);
968 create_fixed_operand (&ops[3], do_error);
969 if (maybe_expand_insn (icode, 4, ops))
970 {
971 last = get_last_insn ();
972 if (profile_status_for_fn (cfun) != PROFILE_ABSENT
973 && JUMP_P (last)
974 && any_condjump_p (last)
975 && !find_reg_note (last, REG_BR_PROB, 0))
976 add_reg_br_prob_note (last,
977 profile_probability::very_unlikely ());
978 emit_jump (done_label);
979 goto do_error_label;
980 }
981
982 delete_insns_since (last);
983 }
984
985 /* Compute the operation. On RTL level, the addition is always
986 unsigned. */
987 res = expand_binop (mode, code == PLUS_EXPR ? add_optab : sub_optab,
988 op0, op1, NULL_RTX, false, OPTAB_LIB_WIDEN);
989
990 /* If we can prove that one of the arguments (for MINUS_EXPR only
991 the second operand, as subtraction is not commutative) is always
992 non-negative or always negative, we can do just one comparison
993 and conditional jump. */
994 int pos_neg = get_range_pos_neg (arg1);
995 if (code == PLUS_EXPR)
996 {
997 int pos_neg0 = get_range_pos_neg (arg0);
998 if (pos_neg0 != 3 && pos_neg == 3)
999 {
1000 std::swap (op0, op1);
1001 pos_neg = pos_neg0;
1002 }
1003 }
1004
1005 /* Addition overflows if and only if the two operands have the same sign,
1006 and the result has the opposite sign. Subtraction overflows if and
1007 only if the two operands have opposite sign, and the subtrahend has
1008 the same sign as the result. Here 0 is counted as positive. */
1009 if (pos_neg == 3)
1010 {
1011 /* Compute op0 ^ op1 (operands have opposite sign). */
1012 rtx op_xor = expand_binop (mode, xor_optab, op0, op1, NULL_RTX, false,
1013 OPTAB_LIB_WIDEN);
1014
1015 /* Compute res ^ op1 (result and 2nd operand have opposite sign). */
1016 rtx res_xor = expand_binop (mode, xor_optab, res, op1, NULL_RTX, false,
1017 OPTAB_LIB_WIDEN);
1018
1019 rtx tem;
1020 if (code == PLUS_EXPR)
1021 {
1022 /* Compute (res ^ op1) & ~(op0 ^ op1). */
1023 tem = expand_unop (mode, one_cmpl_optab, op_xor, NULL_RTX, false);
1024 tem = expand_binop (mode, and_optab, res_xor, tem, NULL_RTX, false,
1025 OPTAB_LIB_WIDEN);
1026 }
1027 else
1028 {
1029 /* Compute (op0 ^ op1) & ~(res ^ op1). */
1030 tem = expand_unop (mode, one_cmpl_optab, res_xor, NULL_RTX, false);
1031 tem = expand_binop (mode, and_optab, op_xor, tem, NULL_RTX, false,
1032 OPTAB_LIB_WIDEN);
1033 }
1034
1035 /* No overflow if the result has bit sign cleared. */
1036 do_compare_rtx_and_jump (tem, const0_rtx, GE, false, mode, NULL_RTX,
1037 NULL, done_label, profile_probability::very_likely ());
1038 }
1039
1040 /* Compare the result of the operation with the first operand.
1041 No overflow for addition if second operand is positive and result
1042 is larger or second operand is negative and result is smaller.
1043 Likewise for subtraction with sign of second operand flipped. */
1044 else
1045 do_compare_rtx_and_jump (res, op0,
1046 (pos_neg == 1) ^ (code == MINUS_EXPR) ? GE : LE,
1047 false, mode, NULL_RTX, NULL, done_label,
1048 profile_probability::very_likely ());
1049 }
1050
1051 do_error_label:
1052 emit_label (do_error);
1053 if (is_ubsan)
1054 {
1055 /* Expand the ubsan builtin call. */
1056 push_temp_slots ();
1057 fn = ubsan_build_overflow_builtin (code, loc, TREE_TYPE (arg0),
1058 arg0, arg1, datap);
1059 expand_normal (fn);
1060 pop_temp_slots ();
1061 do_pending_stack_adjust ();
1062 }
1063 else if (lhs)
1064 expand_arith_set_overflow (lhs, target);
1065
1066 /* We're done. */
1067 emit_label (done_label);
1068
1069 if (lhs)
1070 {
1071 if (is_ubsan)
1072 expand_ubsan_result_store (target, res);
1073 else
1074 {
1075 if (do_xor)
1076 res = expand_binop (mode, add_optab, res, sgn, NULL_RTX, false,
1077 OPTAB_LIB_WIDEN);
1078
1079 expand_arith_overflow_result_store (lhs, target, mode, res);
1080 }
1081 }
1082 }
1083
1084 /* Add negate overflow checking to the statement STMT. */
1085
1086 static void
1087 expand_neg_overflow (location_t loc, tree lhs, tree arg1, bool is_ubsan,
1088 tree *datap)
1089 {
1090 rtx res, op1;
1091 tree fn;
1092 rtx_code_label *done_label, *do_error;
1093 rtx target = NULL_RTX;
1094
1095 done_label = gen_label_rtx ();
1096 do_error = gen_label_rtx ();
1097
1098 do_pending_stack_adjust ();
1099 op1 = expand_normal (arg1);
1100
1101 scalar_int_mode mode = SCALAR_INT_TYPE_MODE (TREE_TYPE (arg1));
1102 if (lhs)
1103 {
1104 target = expand_expr (lhs, NULL_RTX, VOIDmode, EXPAND_WRITE);
1105 if (!is_ubsan)
1106 write_complex_part (target, const0_rtx, true);
1107 }
1108
1109 enum insn_code icode = optab_handler (negv3_optab, mode);
1110 if (icode != CODE_FOR_nothing)
1111 {
1112 struct expand_operand ops[3];
1113 rtx_insn *last = get_last_insn ();
1114
1115 res = gen_reg_rtx (mode);
1116 create_output_operand (&ops[0], res, mode);
1117 create_input_operand (&ops[1], op1, mode);
1118 create_fixed_operand (&ops[2], do_error);
1119 if (maybe_expand_insn (icode, 3, ops))
1120 {
1121 last = get_last_insn ();
1122 if (profile_status_for_fn (cfun) != PROFILE_ABSENT
1123 && JUMP_P (last)
1124 && any_condjump_p (last)
1125 && !find_reg_note (last, REG_BR_PROB, 0))
1126 add_reg_br_prob_note (last,
1127 profile_probability::very_unlikely ());
1128 emit_jump (done_label);
1129 }
1130 else
1131 {
1132 delete_insns_since (last);
1133 icode = CODE_FOR_nothing;
1134 }
1135 }
1136
1137 if (icode == CODE_FOR_nothing)
1138 {
1139 /* Compute the operation. On RTL level, the addition is always
1140 unsigned. */
1141 res = expand_unop (mode, neg_optab, op1, NULL_RTX, false);
1142
1143 /* Compare the operand with the most negative value. */
1144 rtx minv = expand_normal (TYPE_MIN_VALUE (TREE_TYPE (arg1)));
1145 do_compare_rtx_and_jump (op1, minv, NE, true, mode, NULL_RTX, NULL,
1146 done_label, profile_probability::very_likely ());
1147 }
1148
1149 emit_label (do_error);
1150 if (is_ubsan)
1151 {
1152 /* Expand the ubsan builtin call. */
1153 push_temp_slots ();
1154 fn = ubsan_build_overflow_builtin (NEGATE_EXPR, loc, TREE_TYPE (arg1),
1155 arg1, NULL_TREE, datap);
1156 expand_normal (fn);
1157 pop_temp_slots ();
1158 do_pending_stack_adjust ();
1159 }
1160 else if (lhs)
1161 expand_arith_set_overflow (lhs, target);
1162
1163 /* We're done. */
1164 emit_label (done_label);
1165
1166 if (lhs)
1167 {
1168 if (is_ubsan)
1169 expand_ubsan_result_store (target, res);
1170 else
1171 expand_arith_overflow_result_store (lhs, target, mode, res);
1172 }
1173 }
1174
1175 /* Add mul overflow checking to the statement STMT. */
1176
1177 static void
1178 expand_mul_overflow (location_t loc, tree lhs, tree arg0, tree arg1,
1179 bool unsr_p, bool uns0_p, bool uns1_p, bool is_ubsan,
1180 tree *datap)
1181 {
1182 rtx res, op0, op1;
1183 tree fn, type;
1184 rtx_code_label *done_label, *do_error;
1185 rtx target = NULL_RTX;
1186 signop sign;
1187 enum insn_code icode;
1188
1189 done_label = gen_label_rtx ();
1190 do_error = gen_label_rtx ();
1191
1192 do_pending_stack_adjust ();
1193 op0 = expand_normal (arg0);
1194 op1 = expand_normal (arg1);
1195
1196 scalar_int_mode mode = SCALAR_INT_TYPE_MODE (TREE_TYPE (arg0));
1197 bool uns = unsr_p;
1198 if (lhs)
1199 {
1200 target = expand_expr (lhs, NULL_RTX, VOIDmode, EXPAND_WRITE);
1201 if (!is_ubsan)
1202 write_complex_part (target, const0_rtx, true);
1203 }
1204
1205 if (is_ubsan)
1206 gcc_assert (!unsr_p && !uns0_p && !uns1_p);
1207
1208 /* We assume both operands and result have the same precision
1209 here (GET_MODE_BITSIZE (mode)), S stands for signed type
1210 with that precision, U for unsigned type with that precision,
1211 sgn for unsigned most significant bit in that precision.
1212 s1 is signed first operand, u1 is unsigned first operand,
1213 s2 is signed second operand, u2 is unsigned second operand,
1214 sr is signed result, ur is unsigned result and the following
1215 rules say how to compute result (which is always result of
1216 the operands as if both were unsigned, cast to the right
1217 signedness) and how to compute whether operation overflowed.
1218 main_ovf (false) stands for jump on signed multiplication
1219 overflow or the main algorithm with uns == false.
1220 main_ovf (true) stands for jump on unsigned multiplication
1221 overflow or the main algorithm with uns == true.
1222
1223 s1 * s2 -> sr
1224 res = (S) ((U) s1 * (U) s2)
1225 ovf = main_ovf (false)
1226 u1 * u2 -> ur
1227 res = u1 * u2
1228 ovf = main_ovf (true)
1229 s1 * u2 -> ur
1230 res = (U) s1 * u2
1231 ovf = (s1 < 0 && u2) || main_ovf (true)
1232 u1 * u2 -> sr
1233 res = (S) (u1 * u2)
1234 ovf = res < 0 || main_ovf (true)
1235 s1 * u2 -> sr
1236 res = (S) ((U) s1 * u2)
1237 ovf = (S) u2 >= 0 ? main_ovf (false)
1238 : (s1 != 0 && (s1 != -1 || u2 != (U) res))
1239 s1 * s2 -> ur
1240 t1 = (s1 & s2) < 0 ? (-(U) s1) : ((U) s1)
1241 t2 = (s1 & s2) < 0 ? (-(U) s2) : ((U) s2)
1242 res = t1 * t2
1243 ovf = (s1 ^ s2) < 0 ? (s1 && s2) : main_ovf (true) */
1244
1245 if (uns0_p && !uns1_p)
1246 {
1247 /* Multiplication is commutative, if operand signedness differs,
1248 canonicalize to the first operand being signed and second
1249 unsigned to simplify following code. */
1250 std::swap (op0, op1);
1251 std::swap (arg0, arg1);
1252 uns0_p = false;
1253 uns1_p = true;
1254 }
1255
1256 int pos_neg0 = get_range_pos_neg (arg0);
1257 int pos_neg1 = get_range_pos_neg (arg1);
1258
1259 /* s1 * u2 -> ur */
1260 if (!uns0_p && uns1_p && unsr_p)
1261 {
1262 switch (pos_neg0)
1263 {
1264 case 1:
1265 /* If s1 is non-negative, just perform normal u1 * u2 -> ur. */
1266 goto do_main;
1267 case 2:
1268 /* If s1 is negative, avoid the main code, just multiply and
1269 signal overflow if op1 is not 0. */
1270 struct separate_ops ops;
1271 ops.code = MULT_EXPR;
1272 ops.type = TREE_TYPE (arg1);
1273 ops.op0 = make_tree (ops.type, op0);
1274 ops.op1 = make_tree (ops.type, op1);
1275 ops.op2 = NULL_TREE;
1276 ops.location = loc;
1277 res = expand_expr_real_2 (&ops, NULL_RTX, mode, EXPAND_NORMAL);
1278 do_compare_rtx_and_jump (op1, const0_rtx, EQ, true, mode, NULL_RTX,
1279 NULL, done_label, profile_probability::very_likely ());
1280 goto do_error_label;
1281 case 3:
1282 rtx_code_label *do_main_label;
1283 do_main_label = gen_label_rtx ();
1284 do_compare_rtx_and_jump (op0, const0_rtx, GE, false, mode, NULL_RTX,
1285 NULL, do_main_label, profile_probability::very_likely ());
1286 do_compare_rtx_and_jump (op1, const0_rtx, EQ, true, mode, NULL_RTX,
1287 NULL, do_main_label, profile_probability::very_likely ());
1288 expand_arith_set_overflow (lhs, target);
1289 emit_label (do_main_label);
1290 goto do_main;
1291 default:
1292 gcc_unreachable ();
1293 }
1294 }
1295
1296 /* u1 * u2 -> sr */
1297 if (uns0_p && uns1_p && !unsr_p)
1298 {
1299 uns = true;
1300 /* Rest of handling of this case after res is computed. */
1301 goto do_main;
1302 }
1303
1304 /* s1 * u2 -> sr */
1305 if (!uns0_p && uns1_p && !unsr_p)
1306 {
1307 switch (pos_neg1)
1308 {
1309 case 1:
1310 goto do_main;
1311 case 2:
1312 /* If (S) u2 is negative (i.e. u2 is larger than maximum of S,
1313 avoid the main code, just multiply and signal overflow
1314 unless 0 * u2 or -1 * ((U) Smin). */
1315 struct separate_ops ops;
1316 ops.code = MULT_EXPR;
1317 ops.type = TREE_TYPE (arg1);
1318 ops.op0 = make_tree (ops.type, op0);
1319 ops.op1 = make_tree (ops.type, op1);
1320 ops.op2 = NULL_TREE;
1321 ops.location = loc;
1322 res = expand_expr_real_2 (&ops, NULL_RTX, mode, EXPAND_NORMAL);
1323 do_compare_rtx_and_jump (op0, const0_rtx, EQ, true, mode, NULL_RTX,
1324 NULL, done_label, profile_probability::very_likely ());
1325 do_compare_rtx_and_jump (op0, constm1_rtx, NE, true, mode, NULL_RTX,
1326 NULL, do_error, profile_probability::very_unlikely ());
1327 int prec;
1328 prec = GET_MODE_PRECISION (mode);
1329 rtx sgn;
1330 sgn = immed_wide_int_const (wi::min_value (prec, SIGNED), mode);
1331 do_compare_rtx_and_jump (op1, sgn, EQ, true, mode, NULL_RTX,
1332 NULL, done_label, profile_probability::very_likely ());
1333 goto do_error_label;
1334 case 3:
1335 /* Rest of handling of this case after res is computed. */
1336 goto do_main;
1337 default:
1338 gcc_unreachable ();
1339 }
1340 }
1341
1342 /* s1 * s2 -> ur */
1343 if (!uns0_p && !uns1_p && unsr_p)
1344 {
1345 rtx tem, tem2;
1346 switch (pos_neg0 | pos_neg1)
1347 {
1348 case 1: /* Both operands known to be non-negative. */
1349 goto do_main;
1350 case 2: /* Both operands known to be negative. */
1351 op0 = expand_unop (mode, neg_optab, op0, NULL_RTX, false);
1352 op1 = expand_unop (mode, neg_optab, op1, NULL_RTX, false);
1353 /* Avoid looking at arg0/arg1 ranges, as we've changed
1354 the arguments. */
1355 arg0 = error_mark_node;
1356 arg1 = error_mark_node;
1357 goto do_main;
1358 case 3:
1359 if ((pos_neg0 ^ pos_neg1) == 3)
1360 {
1361 /* If one operand is known to be negative and the other
1362 non-negative, this overflows always, unless the non-negative
1363 one is 0. Just do normal multiply and set overflow
1364 unless one of the operands is 0. */
1365 struct separate_ops ops;
1366 ops.code = MULT_EXPR;
1367 ops.type
1368 = build_nonstandard_integer_type (GET_MODE_PRECISION (mode),
1369 1);
1370 ops.op0 = make_tree (ops.type, op0);
1371 ops.op1 = make_tree (ops.type, op1);
1372 ops.op2 = NULL_TREE;
1373 ops.location = loc;
1374 res = expand_expr_real_2 (&ops, NULL_RTX, mode, EXPAND_NORMAL);
1375 tem = expand_binop (mode, and_optab, op0, op1, NULL_RTX, false,
1376 OPTAB_LIB_WIDEN);
1377 do_compare_rtx_and_jump (tem, const0_rtx, EQ, true, mode,
1378 NULL_RTX, NULL, done_label,
1379 profile_probability::very_likely ());
1380 goto do_error_label;
1381 }
1382 /* The general case, do all the needed comparisons at runtime. */
1383 rtx_code_label *do_main_label, *after_negate_label;
1384 rtx rop0, rop1;
1385 rop0 = gen_reg_rtx (mode);
1386 rop1 = gen_reg_rtx (mode);
1387 emit_move_insn (rop0, op0);
1388 emit_move_insn (rop1, op1);
1389 op0 = rop0;
1390 op1 = rop1;
1391 do_main_label = gen_label_rtx ();
1392 after_negate_label = gen_label_rtx ();
1393 tem = expand_binop (mode, and_optab, op0, op1, NULL_RTX, false,
1394 OPTAB_LIB_WIDEN);
1395 do_compare_rtx_and_jump (tem, const0_rtx, GE, false, mode, NULL_RTX,
1396 NULL, after_negate_label, profile_probability::very_likely ());
1397 /* Both arguments negative here, negate them and continue with
1398 normal unsigned overflow checking multiplication. */
1399 emit_move_insn (op0, expand_unop (mode, neg_optab, op0,
1400 NULL_RTX, false));
1401 emit_move_insn (op1, expand_unop (mode, neg_optab, op1,
1402 NULL_RTX, false));
1403 /* Avoid looking at arg0/arg1 ranges, as we might have changed
1404 the arguments. */
1405 arg0 = error_mark_node;
1406 arg1 = error_mark_node;
1407 emit_jump (do_main_label);
1408 emit_label (after_negate_label);
1409 tem2 = expand_binop (mode, xor_optab, op0, op1, NULL_RTX, false,
1410 OPTAB_LIB_WIDEN);
1411 do_compare_rtx_and_jump (tem2, const0_rtx, GE, false, mode, NULL_RTX,
1412 NULL, do_main_label, profile_probability::very_likely ());
1413 /* One argument is negative here, the other positive. This
1414 overflows always, unless one of the arguments is 0. But
1415 if e.g. s2 is 0, (U) s1 * 0 doesn't overflow, whatever s1
1416 is, thus we can keep do_main code oring in overflow as is. */
1417 do_compare_rtx_and_jump (tem, const0_rtx, EQ, true, mode, NULL_RTX,
1418 NULL, do_main_label, profile_probability::very_likely ());
1419 expand_arith_set_overflow (lhs, target);
1420 emit_label (do_main_label);
1421 goto do_main;
1422 default:
1423 gcc_unreachable ();
1424 }
1425 }
1426
1427 do_main:
1428 type = build_nonstandard_integer_type (GET_MODE_PRECISION (mode), uns);
1429 sign = uns ? UNSIGNED : SIGNED;
1430 icode = optab_handler (uns ? umulv4_optab : mulv4_optab, mode);
1431 if (icode != CODE_FOR_nothing)
1432 {
1433 struct expand_operand ops[4];
1434 rtx_insn *last = get_last_insn ();
1435
1436 res = gen_reg_rtx (mode);
1437 create_output_operand (&ops[0], res, mode);
1438 create_input_operand (&ops[1], op0, mode);
1439 create_input_operand (&ops[2], op1, mode);
1440 create_fixed_operand (&ops[3], do_error);
1441 if (maybe_expand_insn (icode, 4, ops))
1442 {
1443 last = get_last_insn ();
1444 if (profile_status_for_fn (cfun) != PROFILE_ABSENT
1445 && JUMP_P (last)
1446 && any_condjump_p (last)
1447 && !find_reg_note (last, REG_BR_PROB, 0))
1448 add_reg_br_prob_note (last,
1449 profile_probability::very_unlikely ());
1450 emit_jump (done_label);
1451 }
1452 else
1453 {
1454 delete_insns_since (last);
1455 icode = CODE_FOR_nothing;
1456 }
1457 }
1458
1459 if (icode == CODE_FOR_nothing)
1460 {
1461 struct separate_ops ops;
1462 int prec = GET_MODE_PRECISION (mode);
1463 scalar_int_mode hmode, wmode;
1464 ops.op0 = make_tree (type, op0);
1465 ops.op1 = make_tree (type, op1);
1466 ops.op2 = NULL_TREE;
1467 ops.location = loc;
1468 if (GET_MODE_2XWIDER_MODE (mode).exists (&wmode)
1469 && targetm.scalar_mode_supported_p (wmode))
1470 {
1471 ops.code = WIDEN_MULT_EXPR;
1472 ops.type
1473 = build_nonstandard_integer_type (GET_MODE_PRECISION (wmode), uns);
1474
1475 res = expand_expr_real_2 (&ops, NULL_RTX, wmode, EXPAND_NORMAL);
1476 rtx hipart = expand_shift (RSHIFT_EXPR, wmode, res, prec,
1477 NULL_RTX, uns);
1478 hipart = convert_modes (mode, wmode, hipart, uns);
1479 res = convert_modes (mode, wmode, res, uns);
1480 if (uns)
1481 /* For the unsigned multiplication, there was overflow if
1482 HIPART is non-zero. */
1483 do_compare_rtx_and_jump (hipart, const0_rtx, EQ, true, mode,
1484 NULL_RTX, NULL, done_label,
1485 profile_probability::very_likely ());
1486 else
1487 {
1488 rtx signbit = expand_shift (RSHIFT_EXPR, mode, res, prec - 1,
1489 NULL_RTX, 0);
1490 /* RES is low half of the double width result, HIPART
1491 the high half. There was overflow if
1492 HIPART is different from RES < 0 ? -1 : 0. */
1493 do_compare_rtx_and_jump (signbit, hipart, EQ, true, mode,
1494 NULL_RTX, NULL, done_label,
1495 profile_probability::very_likely ());
1496 }
1497 }
1498 else if (int_mode_for_size (prec / 2, 1).exists (&hmode)
1499 && 2 * GET_MODE_PRECISION (hmode) == prec)
1500 {
1501 rtx_code_label *large_op0 = gen_label_rtx ();
1502 rtx_code_label *small_op0_large_op1 = gen_label_rtx ();
1503 rtx_code_label *one_small_one_large = gen_label_rtx ();
1504 rtx_code_label *both_ops_large = gen_label_rtx ();
1505 rtx_code_label *after_hipart_neg = uns ? NULL : gen_label_rtx ();
1506 rtx_code_label *after_lopart_neg = uns ? NULL : gen_label_rtx ();
1507 rtx_code_label *do_overflow = gen_label_rtx ();
1508 rtx_code_label *hipart_different = uns ? NULL : gen_label_rtx ();
1509
1510 unsigned int hprec = GET_MODE_PRECISION (hmode);
1511 rtx hipart0 = expand_shift (RSHIFT_EXPR, mode, op0, hprec,
1512 NULL_RTX, uns);
1513 hipart0 = convert_modes (hmode, mode, hipart0, uns);
1514 rtx lopart0 = convert_modes (hmode, mode, op0, uns);
1515 rtx signbit0 = const0_rtx;
1516 if (!uns)
1517 signbit0 = expand_shift (RSHIFT_EXPR, hmode, lopart0, hprec - 1,
1518 NULL_RTX, 0);
1519 rtx hipart1 = expand_shift (RSHIFT_EXPR, mode, op1, hprec,
1520 NULL_RTX, uns);
1521 hipart1 = convert_modes (hmode, mode, hipart1, uns);
1522 rtx lopart1 = convert_modes (hmode, mode, op1, uns);
1523 rtx signbit1 = const0_rtx;
1524 if (!uns)
1525 signbit1 = expand_shift (RSHIFT_EXPR, hmode, lopart1, hprec - 1,
1526 NULL_RTX, 0);
1527
1528 res = gen_reg_rtx (mode);
1529
1530 /* True if op0 resp. op1 are known to be in the range of
1531 halfstype. */
1532 bool op0_small_p = false;
1533 bool op1_small_p = false;
1534 /* True if op0 resp. op1 are known to have all zeros or all ones
1535 in the upper half of bits, but are not known to be
1536 op{0,1}_small_p. */
1537 bool op0_medium_p = false;
1538 bool op1_medium_p = false;
1539 /* -1 if op{0,1} is known to be negative, 0 if it is known to be
1540 nonnegative, 1 if unknown. */
1541 int op0_sign = 1;
1542 int op1_sign = 1;
1543
1544 if (pos_neg0 == 1)
1545 op0_sign = 0;
1546 else if (pos_neg0 == 2)
1547 op0_sign = -1;
1548 if (pos_neg1 == 1)
1549 op1_sign = 0;
1550 else if (pos_neg1 == 2)
1551 op1_sign = -1;
1552
1553 unsigned int mprec0 = prec;
1554 if (arg0 != error_mark_node)
1555 mprec0 = get_min_precision (arg0, sign);
1556 if (mprec0 <= hprec)
1557 op0_small_p = true;
1558 else if (!uns && mprec0 <= hprec + 1)
1559 op0_medium_p = true;
1560 unsigned int mprec1 = prec;
1561 if (arg1 != error_mark_node)
1562 mprec1 = get_min_precision (arg1, sign);
1563 if (mprec1 <= hprec)
1564 op1_small_p = true;
1565 else if (!uns && mprec1 <= hprec + 1)
1566 op1_medium_p = true;
1567
1568 int smaller_sign = 1;
1569 int larger_sign = 1;
1570 if (op0_small_p)
1571 {
1572 smaller_sign = op0_sign;
1573 larger_sign = op1_sign;
1574 }
1575 else if (op1_small_p)
1576 {
1577 smaller_sign = op1_sign;
1578 larger_sign = op0_sign;
1579 }
1580 else if (op0_sign == op1_sign)
1581 {
1582 smaller_sign = op0_sign;
1583 larger_sign = op0_sign;
1584 }
1585
1586 if (!op0_small_p)
1587 do_compare_rtx_and_jump (signbit0, hipart0, NE, true, hmode,
1588 NULL_RTX, NULL, large_op0,
1589 profile_probability::unlikely ());
1590
1591 if (!op1_small_p)
1592 do_compare_rtx_and_jump (signbit1, hipart1, NE, true, hmode,
1593 NULL_RTX, NULL, small_op0_large_op1,
1594 profile_probability::unlikely ());
1595
1596 /* If both op0 and op1 are sign (!uns) or zero (uns) extended from
1597 hmode to mode, the multiplication will never overflow. We can
1598 do just one hmode x hmode => mode widening multiplication. */
1599 rtx lopart0s = lopart0, lopart1s = lopart1;
1600 if (GET_CODE (lopart0) == SUBREG)
1601 {
1602 lopart0s = shallow_copy_rtx (lopart0);
1603 SUBREG_PROMOTED_VAR_P (lopart0s) = 1;
1604 SUBREG_PROMOTED_SET (lopart0s, uns ? SRP_UNSIGNED : SRP_SIGNED);
1605 }
1606 if (GET_CODE (lopart1) == SUBREG)
1607 {
1608 lopart1s = shallow_copy_rtx (lopart1);
1609 SUBREG_PROMOTED_VAR_P (lopart1s) = 1;
1610 SUBREG_PROMOTED_SET (lopart1s, uns ? SRP_UNSIGNED : SRP_SIGNED);
1611 }
1612 tree halfstype = build_nonstandard_integer_type (hprec, uns);
1613 ops.op0 = make_tree (halfstype, lopart0s);
1614 ops.op1 = make_tree (halfstype, lopart1s);
1615 ops.code = WIDEN_MULT_EXPR;
1616 ops.type = type;
1617 rtx thisres
1618 = expand_expr_real_2 (&ops, NULL_RTX, mode, EXPAND_NORMAL);
1619 emit_move_insn (res, thisres);
1620 emit_jump (done_label);
1621
1622 emit_label (small_op0_large_op1);
1623
1624 /* If op0 is sign (!uns) or zero (uns) extended from hmode to mode,
1625 but op1 is not, just swap the arguments and handle it as op1
1626 sign/zero extended, op0 not. */
1627 rtx larger = gen_reg_rtx (mode);
1628 rtx hipart = gen_reg_rtx (hmode);
1629 rtx lopart = gen_reg_rtx (hmode);
1630 emit_move_insn (larger, op1);
1631 emit_move_insn (hipart, hipart1);
1632 emit_move_insn (lopart, lopart0);
1633 emit_jump (one_small_one_large);
1634
1635 emit_label (large_op0);
1636
1637 if (!op1_small_p)
1638 do_compare_rtx_and_jump (signbit1, hipart1, NE, true, hmode,
1639 NULL_RTX, NULL, both_ops_large,
1640 profile_probability::unlikely ());
1641
1642 /* If op1 is sign (!uns) or zero (uns) extended from hmode to mode,
1643 but op0 is not, prepare larger, hipart and lopart pseudos and
1644 handle it together with small_op0_large_op1. */
1645 emit_move_insn (larger, op0);
1646 emit_move_insn (hipart, hipart0);
1647 emit_move_insn (lopart, lopart1);
1648
1649 emit_label (one_small_one_large);
1650
1651 /* lopart is the low part of the operand that is sign extended
1652 to mode, larger is the other operand, hipart is the
1653 high part of larger and lopart0 and lopart1 are the low parts
1654 of both operands.
1655 We perform lopart0 * lopart1 and lopart * hipart widening
1656 multiplications. */
1657 tree halfutype = build_nonstandard_integer_type (hprec, 1);
1658 ops.op0 = make_tree (halfutype, lopart0);
1659 ops.op1 = make_tree (halfutype, lopart1);
1660 rtx lo0xlo1
1661 = expand_expr_real_2 (&ops, NULL_RTX, mode, EXPAND_NORMAL);
1662
1663 ops.op0 = make_tree (halfutype, lopart);
1664 ops.op1 = make_tree (halfutype, hipart);
1665 rtx loxhi = gen_reg_rtx (mode);
1666 rtx tem = expand_expr_real_2 (&ops, NULL_RTX, mode, EXPAND_NORMAL);
1667 emit_move_insn (loxhi, tem);
1668
1669 if (!uns)
1670 {
1671 /* if (hipart < 0) loxhi -= lopart << (bitsize / 2); */
1672 if (larger_sign == 0)
1673 emit_jump (after_hipart_neg);
1674 else if (larger_sign != -1)
1675 do_compare_rtx_and_jump (hipart, const0_rtx, GE, false, hmode,
1676 NULL_RTX, NULL, after_hipart_neg,
1677 profile_probability::even ());
1678
1679 tem = convert_modes (mode, hmode, lopart, 1);
1680 tem = expand_shift (LSHIFT_EXPR, mode, tem, hprec, NULL_RTX, 1);
1681 tem = expand_simple_binop (mode, MINUS, loxhi, tem, NULL_RTX,
1682 1, OPTAB_DIRECT);
1683 emit_move_insn (loxhi, tem);
1684
1685 emit_label (after_hipart_neg);
1686
1687 /* if (lopart < 0) loxhi -= larger; */
1688 if (smaller_sign == 0)
1689 emit_jump (after_lopart_neg);
1690 else if (smaller_sign != -1)
1691 do_compare_rtx_and_jump (lopart, const0_rtx, GE, false, hmode,
1692 NULL_RTX, NULL, after_lopart_neg,
1693 profile_probability::even ());
1694
1695 tem = expand_simple_binop (mode, MINUS, loxhi, larger, NULL_RTX,
1696 1, OPTAB_DIRECT);
1697 emit_move_insn (loxhi, tem);
1698
1699 emit_label (after_lopart_neg);
1700 }
1701
1702 /* loxhi += (uns) lo0xlo1 >> (bitsize / 2); */
1703 tem = expand_shift (RSHIFT_EXPR, mode, lo0xlo1, hprec, NULL_RTX, 1);
1704 tem = expand_simple_binop (mode, PLUS, loxhi, tem, NULL_RTX,
1705 1, OPTAB_DIRECT);
1706 emit_move_insn (loxhi, tem);
1707
1708 /* if (loxhi >> (bitsize / 2)
1709 == (hmode) loxhi >> (bitsize / 2 - 1)) (if !uns)
1710 if (loxhi >> (bitsize / 2) == 0 (if uns). */
1711 rtx hipartloxhi = expand_shift (RSHIFT_EXPR, mode, loxhi, hprec,
1712 NULL_RTX, 0);
1713 hipartloxhi = convert_modes (hmode, mode, hipartloxhi, 0);
1714 rtx signbitloxhi = const0_rtx;
1715 if (!uns)
1716 signbitloxhi = expand_shift (RSHIFT_EXPR, hmode,
1717 convert_modes (hmode, mode,
1718 loxhi, 0),
1719 hprec - 1, NULL_RTX, 0);
1720
1721 do_compare_rtx_and_jump (signbitloxhi, hipartloxhi, NE, true, hmode,
1722 NULL_RTX, NULL, do_overflow,
1723 profile_probability::very_unlikely ());
1724
1725 /* res = (loxhi << (bitsize / 2)) | (hmode) lo0xlo1; */
1726 rtx loxhishifted = expand_shift (LSHIFT_EXPR, mode, loxhi, hprec,
1727 NULL_RTX, 1);
1728 tem = convert_modes (mode, hmode,
1729 convert_modes (hmode, mode, lo0xlo1, 1), 1);
1730
1731 tem = expand_simple_binop (mode, IOR, loxhishifted, tem, res,
1732 1, OPTAB_DIRECT);
1733 if (tem != res)
1734 emit_move_insn (res, tem);
1735 emit_jump (done_label);
1736
1737 emit_label (both_ops_large);
1738
1739 /* If both operands are large (not sign (!uns) or zero (uns)
1740 extended from hmode), then perform the full multiplication
1741 which will be the result of the operation.
1742 The only cases which don't overflow are for signed multiplication
1743 some cases where both hipart0 and highpart1 are 0 or -1.
1744 For unsigned multiplication when high parts are both non-zero
1745 this overflows always. */
1746 ops.code = MULT_EXPR;
1747 ops.op0 = make_tree (type, op0);
1748 ops.op1 = make_tree (type, op1);
1749 tem = expand_expr_real_2 (&ops, NULL_RTX, mode, EXPAND_NORMAL);
1750 emit_move_insn (res, tem);
1751
1752 if (!uns)
1753 {
1754 if (!op0_medium_p)
1755 {
1756 tem = expand_simple_binop (hmode, PLUS, hipart0, const1_rtx,
1757 NULL_RTX, 1, OPTAB_DIRECT);
1758 do_compare_rtx_and_jump (tem, const1_rtx, GTU, true, hmode,
1759 NULL_RTX, NULL, do_error,
1760 profile_probability::very_unlikely ());
1761 }
1762
1763 if (!op1_medium_p)
1764 {
1765 tem = expand_simple_binop (hmode, PLUS, hipart1, const1_rtx,
1766 NULL_RTX, 1, OPTAB_DIRECT);
1767 do_compare_rtx_and_jump (tem, const1_rtx, GTU, true, hmode,
1768 NULL_RTX, NULL, do_error,
1769 profile_probability::very_unlikely ());
1770 }
1771
1772 /* At this point hipart{0,1} are both in [-1, 0]. If they are
1773 the same, overflow happened if res is non-positive, if they
1774 are different, overflow happened if res is positive. */
1775 if (op0_sign != 1 && op1_sign != 1 && op0_sign != op1_sign)
1776 emit_jump (hipart_different);
1777 else if (op0_sign == 1 || op1_sign == 1)
1778 do_compare_rtx_and_jump (hipart0, hipart1, NE, true, hmode,
1779 NULL_RTX, NULL, hipart_different,
1780 profile_probability::even ());
1781
1782 do_compare_rtx_and_jump (res, const0_rtx, LE, false, mode,
1783 NULL_RTX, NULL, do_error,
1784 profile_probability::very_unlikely ());
1785 emit_jump (done_label);
1786
1787 emit_label (hipart_different);
1788
1789 do_compare_rtx_and_jump (res, const0_rtx, GE, false, mode,
1790 NULL_RTX, NULL, do_error,
1791 profile_probability::very_unlikely ());
1792 emit_jump (done_label);
1793 }
1794
1795 emit_label (do_overflow);
1796
1797 /* Overflow, do full multiplication and fallthru into do_error. */
1798 ops.op0 = make_tree (type, op0);
1799 ops.op1 = make_tree (type, op1);
1800 tem = expand_expr_real_2 (&ops, NULL_RTX, mode, EXPAND_NORMAL);
1801 emit_move_insn (res, tem);
1802 }
1803 else
1804 {
1805 gcc_assert (!is_ubsan);
1806 ops.code = MULT_EXPR;
1807 ops.type = type;
1808 res = expand_expr_real_2 (&ops, NULL_RTX, mode, EXPAND_NORMAL);
1809 emit_jump (done_label);
1810 }
1811 }
1812
1813 do_error_label:
1814 emit_label (do_error);
1815 if (is_ubsan)
1816 {
1817 /* Expand the ubsan builtin call. */
1818 push_temp_slots ();
1819 fn = ubsan_build_overflow_builtin (MULT_EXPR, loc, TREE_TYPE (arg0),
1820 arg0, arg1, datap);
1821 expand_normal (fn);
1822 pop_temp_slots ();
1823 do_pending_stack_adjust ();
1824 }
1825 else if (lhs)
1826 expand_arith_set_overflow (lhs, target);
1827
1828 /* We're done. */
1829 emit_label (done_label);
1830
1831 /* u1 * u2 -> sr */
1832 if (uns0_p && uns1_p && !unsr_p)
1833 {
1834 rtx_code_label *all_done_label = gen_label_rtx ();
1835 do_compare_rtx_and_jump (res, const0_rtx, GE, false, mode, NULL_RTX,
1836 NULL, all_done_label, profile_probability::very_likely ());
1837 expand_arith_set_overflow (lhs, target);
1838 emit_label (all_done_label);
1839 }
1840
1841 /* s1 * u2 -> sr */
1842 if (!uns0_p && uns1_p && !unsr_p && pos_neg1 == 3)
1843 {
1844 rtx_code_label *all_done_label = gen_label_rtx ();
1845 rtx_code_label *set_noovf = gen_label_rtx ();
1846 do_compare_rtx_and_jump (op1, const0_rtx, GE, false, mode, NULL_RTX,
1847 NULL, all_done_label, profile_probability::very_likely ());
1848 expand_arith_set_overflow (lhs, target);
1849 do_compare_rtx_and_jump (op0, const0_rtx, EQ, true, mode, NULL_RTX,
1850 NULL, set_noovf, profile_probability::very_likely ());
1851 do_compare_rtx_and_jump (op0, constm1_rtx, NE, true, mode, NULL_RTX,
1852 NULL, all_done_label, profile_probability::very_unlikely ());
1853 do_compare_rtx_and_jump (op1, res, NE, true, mode, NULL_RTX, NULL,
1854 all_done_label, profile_probability::very_unlikely ());
1855 emit_label (set_noovf);
1856 write_complex_part (target, const0_rtx, true);
1857 emit_label (all_done_label);
1858 }
1859
1860 if (lhs)
1861 {
1862 if (is_ubsan)
1863 expand_ubsan_result_store (target, res);
1864 else
1865 expand_arith_overflow_result_store (lhs, target, mode, res);
1866 }
1867 }
1868
1869 /* Expand UBSAN_CHECK_* internal function if it has vector operands. */
1870
1871 static void
1872 expand_vector_ubsan_overflow (location_t loc, enum tree_code code, tree lhs,
1873 tree arg0, tree arg1)
1874 {
1875 int cnt = TYPE_VECTOR_SUBPARTS (TREE_TYPE (arg0));
1876 rtx_code_label *loop_lab = NULL;
1877 rtx cntvar = NULL_RTX;
1878 tree cntv = NULL_TREE;
1879 tree eltype = TREE_TYPE (TREE_TYPE (arg0));
1880 tree sz = TYPE_SIZE (eltype);
1881 tree data = NULL_TREE;
1882 tree resv = NULL_TREE;
1883 rtx lhsr = NULL_RTX;
1884 rtx resvr = NULL_RTX;
1885
1886 if (lhs)
1887 {
1888 optab op;
1889 lhsr = expand_expr (lhs, NULL_RTX, VOIDmode, EXPAND_WRITE);
1890 if (!VECTOR_MODE_P (GET_MODE (lhsr))
1891 || (op = optab_for_tree_code (code, TREE_TYPE (arg0),
1892 optab_default)) == unknown_optab
1893 || (optab_handler (op, TYPE_MODE (TREE_TYPE (arg0)))
1894 == CODE_FOR_nothing))
1895 {
1896 if (MEM_P (lhsr))
1897 resv = make_tree (TREE_TYPE (lhs), lhsr);
1898 else
1899 {
1900 resvr = assign_temp (TREE_TYPE (lhs), 1, 1);
1901 resv = make_tree (TREE_TYPE (lhs), resvr);
1902 }
1903 }
1904 }
1905 if (cnt > 4)
1906 {
1907 do_pending_stack_adjust ();
1908 loop_lab = gen_label_rtx ();
1909 cntvar = gen_reg_rtx (TYPE_MODE (sizetype));
1910 cntv = make_tree (sizetype, cntvar);
1911 emit_move_insn (cntvar, const0_rtx);
1912 emit_label (loop_lab);
1913 }
1914 if (TREE_CODE (arg0) != VECTOR_CST)
1915 {
1916 rtx arg0r = expand_normal (arg0);
1917 arg0 = make_tree (TREE_TYPE (arg0), arg0r);
1918 }
1919 if (TREE_CODE (arg1) != VECTOR_CST)
1920 {
1921 rtx arg1r = expand_normal (arg1);
1922 arg1 = make_tree (TREE_TYPE (arg1), arg1r);
1923 }
1924 for (int i = 0; i < (cnt > 4 ? 1 : cnt); i++)
1925 {
1926 tree op0, op1, res = NULL_TREE;
1927 if (cnt > 4)
1928 {
1929 tree atype = build_array_type_nelts (eltype, cnt);
1930 op0 = uniform_vector_p (arg0);
1931 if (op0 == NULL_TREE)
1932 {
1933 op0 = fold_build1_loc (loc, VIEW_CONVERT_EXPR, atype, arg0);
1934 op0 = build4_loc (loc, ARRAY_REF, eltype, op0, cntv,
1935 NULL_TREE, NULL_TREE);
1936 }
1937 op1 = uniform_vector_p (arg1);
1938 if (op1 == NULL_TREE)
1939 {
1940 op1 = fold_build1_loc (loc, VIEW_CONVERT_EXPR, atype, arg1);
1941 op1 = build4_loc (loc, ARRAY_REF, eltype, op1, cntv,
1942 NULL_TREE, NULL_TREE);
1943 }
1944 if (resv)
1945 {
1946 res = fold_build1_loc (loc, VIEW_CONVERT_EXPR, atype, resv);
1947 res = build4_loc (loc, ARRAY_REF, eltype, res, cntv,
1948 NULL_TREE, NULL_TREE);
1949 }
1950 }
1951 else
1952 {
1953 tree bitpos = bitsize_int (tree_to_uhwi (sz) * i);
1954 op0 = fold_build3_loc (loc, BIT_FIELD_REF, eltype, arg0, sz, bitpos);
1955 op1 = fold_build3_loc (loc, BIT_FIELD_REF, eltype, arg1, sz, bitpos);
1956 if (resv)
1957 res = fold_build3_loc (loc, BIT_FIELD_REF, eltype, resv, sz,
1958 bitpos);
1959 }
1960 switch (code)
1961 {
1962 case PLUS_EXPR:
1963 expand_addsub_overflow (loc, PLUS_EXPR, res, op0, op1,
1964 false, false, false, true, &data);
1965 break;
1966 case MINUS_EXPR:
1967 if (cnt > 4 ? integer_zerop (arg0) : integer_zerop (op0))
1968 expand_neg_overflow (loc, res, op1, true, &data);
1969 else
1970 expand_addsub_overflow (loc, MINUS_EXPR, res, op0, op1,
1971 false, false, false, true, &data);
1972 break;
1973 case MULT_EXPR:
1974 expand_mul_overflow (loc, res, op0, op1, false, false, false,
1975 true, &data);
1976 break;
1977 default:
1978 gcc_unreachable ();
1979 }
1980 }
1981 if (cnt > 4)
1982 {
1983 struct separate_ops ops;
1984 ops.code = PLUS_EXPR;
1985 ops.type = TREE_TYPE (cntv);
1986 ops.op0 = cntv;
1987 ops.op1 = build_int_cst (TREE_TYPE (cntv), 1);
1988 ops.op2 = NULL_TREE;
1989 ops.location = loc;
1990 rtx ret = expand_expr_real_2 (&ops, cntvar, TYPE_MODE (sizetype),
1991 EXPAND_NORMAL);
1992 if (ret != cntvar)
1993 emit_move_insn (cntvar, ret);
1994 do_compare_rtx_and_jump (cntvar, GEN_INT (cnt), NE, false,
1995 TYPE_MODE (sizetype), NULL_RTX, NULL, loop_lab,
1996 profile_probability::very_likely ());
1997 }
1998 if (lhs && resv == NULL_TREE)
1999 {
2000 struct separate_ops ops;
2001 ops.code = code;
2002 ops.type = TREE_TYPE (arg0);
2003 ops.op0 = arg0;
2004 ops.op1 = arg1;
2005 ops.op2 = NULL_TREE;
2006 ops.location = loc;
2007 rtx ret = expand_expr_real_2 (&ops, lhsr, TYPE_MODE (TREE_TYPE (arg0)),
2008 EXPAND_NORMAL);
2009 if (ret != lhsr)
2010 emit_move_insn (lhsr, ret);
2011 }
2012 else if (resvr)
2013 emit_move_insn (lhsr, resvr);
2014 }
2015
2016 /* Expand UBSAN_CHECK_ADD call STMT. */
2017
2018 static void
2019 expand_UBSAN_CHECK_ADD (internal_fn, gcall *stmt)
2020 {
2021 location_t loc = gimple_location (stmt);
2022 tree lhs = gimple_call_lhs (stmt);
2023 tree arg0 = gimple_call_arg (stmt, 0);
2024 tree arg1 = gimple_call_arg (stmt, 1);
2025 if (VECTOR_TYPE_P (TREE_TYPE (arg0)))
2026 expand_vector_ubsan_overflow (loc, PLUS_EXPR, lhs, arg0, arg1);
2027 else
2028 expand_addsub_overflow (loc, PLUS_EXPR, lhs, arg0, arg1,
2029 false, false, false, true, NULL);
2030 }
2031
2032 /* Expand UBSAN_CHECK_SUB call STMT. */
2033
2034 static void
2035 expand_UBSAN_CHECK_SUB (internal_fn, gcall *stmt)
2036 {
2037 location_t loc = gimple_location (stmt);
2038 tree lhs = gimple_call_lhs (stmt);
2039 tree arg0 = gimple_call_arg (stmt, 0);
2040 tree arg1 = gimple_call_arg (stmt, 1);
2041 if (VECTOR_TYPE_P (TREE_TYPE (arg0)))
2042 expand_vector_ubsan_overflow (loc, MINUS_EXPR, lhs, arg0, arg1);
2043 else if (integer_zerop (arg0))
2044 expand_neg_overflow (loc, lhs, arg1, true, NULL);
2045 else
2046 expand_addsub_overflow (loc, MINUS_EXPR, lhs, arg0, arg1,
2047 false, false, false, true, NULL);
2048 }
2049
2050 /* Expand UBSAN_CHECK_MUL call STMT. */
2051
2052 static void
2053 expand_UBSAN_CHECK_MUL (internal_fn, gcall *stmt)
2054 {
2055 location_t loc = gimple_location (stmt);
2056 tree lhs = gimple_call_lhs (stmt);
2057 tree arg0 = gimple_call_arg (stmt, 0);
2058 tree arg1 = gimple_call_arg (stmt, 1);
2059 if (VECTOR_TYPE_P (TREE_TYPE (arg0)))
2060 expand_vector_ubsan_overflow (loc, MULT_EXPR, lhs, arg0, arg1);
2061 else
2062 expand_mul_overflow (loc, lhs, arg0, arg1, false, false, false, true,
2063 NULL);
2064 }
2065
2066 /* Helper function for {ADD,SUB,MUL}_OVERFLOW call stmt expansion. */
2067
2068 static void
2069 expand_arith_overflow (enum tree_code code, gimple *stmt)
2070 {
2071 tree lhs = gimple_call_lhs (stmt);
2072 if (lhs == NULL_TREE)
2073 return;
2074 tree arg0 = gimple_call_arg (stmt, 0);
2075 tree arg1 = gimple_call_arg (stmt, 1);
2076 tree type = TREE_TYPE (TREE_TYPE (lhs));
2077 int uns0_p = TYPE_UNSIGNED (TREE_TYPE (arg0));
2078 int uns1_p = TYPE_UNSIGNED (TREE_TYPE (arg1));
2079 int unsr_p = TYPE_UNSIGNED (type);
2080 int prec0 = TYPE_PRECISION (TREE_TYPE (arg0));
2081 int prec1 = TYPE_PRECISION (TREE_TYPE (arg1));
2082 int precres = TYPE_PRECISION (type);
2083 location_t loc = gimple_location (stmt);
2084 if (!uns0_p && get_range_pos_neg (arg0) == 1)
2085 uns0_p = true;
2086 if (!uns1_p && get_range_pos_neg (arg1) == 1)
2087 uns1_p = true;
2088 int pr = get_min_precision (arg0, uns0_p ? UNSIGNED : SIGNED);
2089 prec0 = MIN (prec0, pr);
2090 pr = get_min_precision (arg1, uns1_p ? UNSIGNED : SIGNED);
2091 prec1 = MIN (prec1, pr);
2092
2093 /* If uns0_p && uns1_p, precop is minimum needed precision
2094 of unsigned type to hold the exact result, otherwise
2095 precop is minimum needed precision of signed type to
2096 hold the exact result. */
2097 int precop;
2098 if (code == MULT_EXPR)
2099 precop = prec0 + prec1 + (uns0_p != uns1_p);
2100 else
2101 {
2102 if (uns0_p == uns1_p)
2103 precop = MAX (prec0, prec1) + 1;
2104 else if (uns0_p)
2105 precop = MAX (prec0 + 1, prec1) + 1;
2106 else
2107 precop = MAX (prec0, prec1 + 1) + 1;
2108 }
2109 int orig_precres = precres;
2110
2111 do
2112 {
2113 if ((uns0_p && uns1_p)
2114 ? ((precop + !unsr_p) <= precres
2115 /* u1 - u2 -> ur can overflow, no matter what precision
2116 the result has. */
2117 && (code != MINUS_EXPR || !unsr_p))
2118 : (!unsr_p && precop <= precres))
2119 {
2120 /* The infinity precision result will always fit into result. */
2121 rtx target = expand_expr (lhs, NULL_RTX, VOIDmode, EXPAND_WRITE);
2122 write_complex_part (target, const0_rtx, true);
2123 scalar_int_mode mode = SCALAR_INT_TYPE_MODE (type);
2124 struct separate_ops ops;
2125 ops.code = code;
2126 ops.type = type;
2127 ops.op0 = fold_convert_loc (loc, type, arg0);
2128 ops.op1 = fold_convert_loc (loc, type, arg1);
2129 ops.op2 = NULL_TREE;
2130 ops.location = loc;
2131 rtx tem = expand_expr_real_2 (&ops, NULL_RTX, mode, EXPAND_NORMAL);
2132 expand_arith_overflow_result_store (lhs, target, mode, tem);
2133 return;
2134 }
2135
2136 /* For operations with low precision, if target doesn't have them, start
2137 with precres widening right away, otherwise do it only if the most
2138 simple cases can't be used. */
2139 const int min_precision = targetm.min_arithmetic_precision ();
2140 if (orig_precres == precres && precres < min_precision)
2141 ;
2142 else if ((uns0_p && uns1_p && unsr_p && prec0 <= precres
2143 && prec1 <= precres)
2144 || ((!uns0_p || !uns1_p) && !unsr_p
2145 && prec0 + uns0_p <= precres
2146 && prec1 + uns1_p <= precres))
2147 {
2148 arg0 = fold_convert_loc (loc, type, arg0);
2149 arg1 = fold_convert_loc (loc, type, arg1);
2150 switch (code)
2151 {
2152 case MINUS_EXPR:
2153 if (integer_zerop (arg0) && !unsr_p)
2154 {
2155 expand_neg_overflow (loc, lhs, arg1, false, NULL);
2156 return;
2157 }
2158 /* FALLTHRU */
2159 case PLUS_EXPR:
2160 expand_addsub_overflow (loc, code, lhs, arg0, arg1, unsr_p,
2161 unsr_p, unsr_p, false, NULL);
2162 return;
2163 case MULT_EXPR:
2164 expand_mul_overflow (loc, lhs, arg0, arg1, unsr_p,
2165 unsr_p, unsr_p, false, NULL);
2166 return;
2167 default:
2168 gcc_unreachable ();
2169 }
2170 }
2171
2172 /* For sub-word operations, retry with a wider type first. */
2173 if (orig_precres == precres && precop <= BITS_PER_WORD)
2174 {
2175 int p = MAX (min_precision, precop);
2176 scalar_int_mode m = smallest_int_mode_for_size (p);
2177 tree optype = build_nonstandard_integer_type (GET_MODE_PRECISION (m),
2178 uns0_p && uns1_p
2179 && unsr_p);
2180 p = TYPE_PRECISION (optype);
2181 if (p > precres)
2182 {
2183 precres = p;
2184 unsr_p = TYPE_UNSIGNED (optype);
2185 type = optype;
2186 continue;
2187 }
2188 }
2189
2190 if (prec0 <= precres && prec1 <= precres)
2191 {
2192 tree types[2];
2193 if (unsr_p)
2194 {
2195 types[0] = build_nonstandard_integer_type (precres, 0);
2196 types[1] = type;
2197 }
2198 else
2199 {
2200 types[0] = type;
2201 types[1] = build_nonstandard_integer_type (precres, 1);
2202 }
2203 arg0 = fold_convert_loc (loc, types[uns0_p], arg0);
2204 arg1 = fold_convert_loc (loc, types[uns1_p], arg1);
2205 if (code != MULT_EXPR)
2206 expand_addsub_overflow (loc, code, lhs, arg0, arg1, unsr_p,
2207 uns0_p, uns1_p, false, NULL);
2208 else
2209 expand_mul_overflow (loc, lhs, arg0, arg1, unsr_p,
2210 uns0_p, uns1_p, false, NULL);
2211 return;
2212 }
2213
2214 /* Retry with a wider type. */
2215 if (orig_precres == precres)
2216 {
2217 int p = MAX (prec0, prec1);
2218 scalar_int_mode m = smallest_int_mode_for_size (p);
2219 tree optype = build_nonstandard_integer_type (GET_MODE_PRECISION (m),
2220 uns0_p && uns1_p
2221 && unsr_p);
2222 p = TYPE_PRECISION (optype);
2223 if (p > precres)
2224 {
2225 precres = p;
2226 unsr_p = TYPE_UNSIGNED (optype);
2227 type = optype;
2228 continue;
2229 }
2230 }
2231
2232 gcc_unreachable ();
2233 }
2234 while (1);
2235 }
2236
2237 /* Expand ADD_OVERFLOW STMT. */
2238
2239 static void
2240 expand_ADD_OVERFLOW (internal_fn, gcall *stmt)
2241 {
2242 expand_arith_overflow (PLUS_EXPR, stmt);
2243 }
2244
2245 /* Expand SUB_OVERFLOW STMT. */
2246
2247 static void
2248 expand_SUB_OVERFLOW (internal_fn, gcall *stmt)
2249 {
2250 expand_arith_overflow (MINUS_EXPR, stmt);
2251 }
2252
2253 /* Expand MUL_OVERFLOW STMT. */
2254
2255 static void
2256 expand_MUL_OVERFLOW (internal_fn, gcall *stmt)
2257 {
2258 expand_arith_overflow (MULT_EXPR, stmt);
2259 }
2260
2261 /* This should get folded in tree-vectorizer.c. */
2262
2263 static void
2264 expand_LOOP_VECTORIZED (internal_fn, gcall *)
2265 {
2266 gcc_unreachable ();
2267 }
2268
2269 /* This should get folded in tree-vectorizer.c. */
2270
2271 static void
2272 expand_LOOP_DIST_ALIAS (internal_fn, gcall *)
2273 {
2274 gcc_unreachable ();
2275 }
2276
2277 /* Expand MASK_LOAD call STMT using optab OPTAB. */
2278
2279 static void
2280 expand_mask_load_optab_fn (internal_fn, gcall *stmt, convert_optab optab)
2281 {
2282 struct expand_operand ops[3];
2283 tree type, lhs, rhs, maskt, ptr;
2284 rtx mem, target, mask;
2285 unsigned align;
2286
2287 maskt = gimple_call_arg (stmt, 2);
2288 lhs = gimple_call_lhs (stmt);
2289 if (lhs == NULL_TREE)
2290 return;
2291 type = TREE_TYPE (lhs);
2292 ptr = build_int_cst (TREE_TYPE (gimple_call_arg (stmt, 1)), 0);
2293 align = tree_to_shwi (gimple_call_arg (stmt, 1));
2294 if (TYPE_ALIGN (type) != align)
2295 type = build_aligned_type (type, align);
2296 rhs = fold_build2 (MEM_REF, type, gimple_call_arg (stmt, 0), ptr);
2297
2298 mem = expand_expr (rhs, NULL_RTX, VOIDmode, EXPAND_WRITE);
2299 gcc_assert (MEM_P (mem));
2300 mask = expand_normal (maskt);
2301 target = expand_expr (lhs, NULL_RTX, VOIDmode, EXPAND_WRITE);
2302 create_output_operand (&ops[0], target, TYPE_MODE (type));
2303 create_fixed_operand (&ops[1], mem);
2304 create_input_operand (&ops[2], mask, TYPE_MODE (TREE_TYPE (maskt)));
2305 expand_insn (convert_optab_handler (optab, TYPE_MODE (type),
2306 TYPE_MODE (TREE_TYPE (maskt))),
2307 3, ops);
2308 }
2309
2310 /* Expand MASK_STORE call STMT using optab OPTAB. */
2311
2312 static void
2313 expand_mask_store_optab_fn (internal_fn, gcall *stmt, convert_optab optab)
2314 {
2315 struct expand_operand ops[3];
2316 tree type, lhs, rhs, maskt, ptr;
2317 rtx mem, reg, mask;
2318 unsigned align;
2319
2320 maskt = gimple_call_arg (stmt, 2);
2321 rhs = gimple_call_arg (stmt, 3);
2322 type = TREE_TYPE (rhs);
2323 ptr = build_int_cst (TREE_TYPE (gimple_call_arg (stmt, 1)), 0);
2324 align = tree_to_shwi (gimple_call_arg (stmt, 1));
2325 if (TYPE_ALIGN (type) != align)
2326 type = build_aligned_type (type, align);
2327 lhs = fold_build2 (MEM_REF, type, gimple_call_arg (stmt, 0), ptr);
2328
2329 mem = expand_expr (lhs, NULL_RTX, VOIDmode, EXPAND_WRITE);
2330 gcc_assert (MEM_P (mem));
2331 mask = expand_normal (maskt);
2332 reg = expand_normal (rhs);
2333 create_fixed_operand (&ops[0], mem);
2334 create_input_operand (&ops[1], reg, TYPE_MODE (type));
2335 create_input_operand (&ops[2], mask, TYPE_MODE (TREE_TYPE (maskt)));
2336 expand_insn (convert_optab_handler (optab, TYPE_MODE (type),
2337 TYPE_MODE (TREE_TYPE (maskt))),
2338 3, ops);
2339 }
2340
2341 static void
2342 expand_ABNORMAL_DISPATCHER (internal_fn, gcall *)
2343 {
2344 }
2345
2346 static void
2347 expand_BUILTIN_EXPECT (internal_fn, gcall *stmt)
2348 {
2349 /* When guessing was done, the hints should be already stripped away. */
2350 gcc_assert (!flag_guess_branch_prob || optimize == 0 || seen_error ());
2351
2352 rtx target;
2353 tree lhs = gimple_call_lhs (stmt);
2354 if (lhs)
2355 target = expand_expr (lhs, NULL_RTX, VOIDmode, EXPAND_WRITE);
2356 else
2357 target = const0_rtx;
2358 rtx val = expand_expr (gimple_call_arg (stmt, 0), target, VOIDmode, EXPAND_NORMAL);
2359 if (lhs && val != target)
2360 emit_move_insn (target, val);
2361 }
2362
2363 /* IFN_VA_ARG is supposed to be expanded at pass_stdarg. So this dummy function
2364 should never be called. */
2365
2366 static void
2367 expand_VA_ARG (internal_fn, gcall *)
2368 {
2369 gcc_unreachable ();
2370 }
2371
2372 /* Expand the IFN_UNIQUE function according to its first argument. */
2373
2374 static void
2375 expand_UNIQUE (internal_fn, gcall *stmt)
2376 {
2377 rtx pattern = NULL_RTX;
2378 enum ifn_unique_kind kind
2379 = (enum ifn_unique_kind) TREE_INT_CST_LOW (gimple_call_arg (stmt, 0));
2380
2381 switch (kind)
2382 {
2383 default:
2384 gcc_unreachable ();
2385
2386 case IFN_UNIQUE_UNSPEC:
2387 if (targetm.have_unique ())
2388 pattern = targetm.gen_unique ();
2389 break;
2390
2391 case IFN_UNIQUE_OACC_FORK:
2392 case IFN_UNIQUE_OACC_JOIN:
2393 if (targetm.have_oacc_fork () && targetm.have_oacc_join ())
2394 {
2395 tree lhs = gimple_call_lhs (stmt);
2396 rtx target = const0_rtx;
2397
2398 if (lhs)
2399 target = expand_expr (lhs, NULL_RTX, VOIDmode, EXPAND_WRITE);
2400
2401 rtx data_dep = expand_normal (gimple_call_arg (stmt, 1));
2402 rtx axis = expand_normal (gimple_call_arg (stmt, 2));
2403
2404 if (kind == IFN_UNIQUE_OACC_FORK)
2405 pattern = targetm.gen_oacc_fork (target, data_dep, axis);
2406 else
2407 pattern = targetm.gen_oacc_join (target, data_dep, axis);
2408 }
2409 else
2410 gcc_unreachable ();
2411 break;
2412 }
2413
2414 if (pattern)
2415 emit_insn (pattern);
2416 }
2417
2418 /* The size of an OpenACC compute dimension. */
2419
2420 static void
2421 expand_GOACC_DIM_SIZE (internal_fn, gcall *stmt)
2422 {
2423 tree lhs = gimple_call_lhs (stmt);
2424
2425 if (!lhs)
2426 return;
2427
2428 rtx target = expand_expr (lhs, NULL_RTX, VOIDmode, EXPAND_WRITE);
2429 if (targetm.have_oacc_dim_size ())
2430 {
2431 rtx dim = expand_expr (gimple_call_arg (stmt, 0), NULL_RTX,
2432 VOIDmode, EXPAND_NORMAL);
2433 emit_insn (targetm.gen_oacc_dim_size (target, dim));
2434 }
2435 else
2436 emit_move_insn (target, GEN_INT (1));
2437 }
2438
2439 /* The position of an OpenACC execution engine along one compute axis. */
2440
2441 static void
2442 expand_GOACC_DIM_POS (internal_fn, gcall *stmt)
2443 {
2444 tree lhs = gimple_call_lhs (stmt);
2445
2446 if (!lhs)
2447 return;
2448
2449 rtx target = expand_expr (lhs, NULL_RTX, VOIDmode, EXPAND_WRITE);
2450 if (targetm.have_oacc_dim_pos ())
2451 {
2452 rtx dim = expand_expr (gimple_call_arg (stmt, 0), NULL_RTX,
2453 VOIDmode, EXPAND_NORMAL);
2454 emit_insn (targetm.gen_oacc_dim_pos (target, dim));
2455 }
2456 else
2457 emit_move_insn (target, const0_rtx);
2458 }
2459
2460 /* This is expanded by oacc_device_lower pass. */
2461
2462 static void
2463 expand_GOACC_LOOP (internal_fn, gcall *)
2464 {
2465 gcc_unreachable ();
2466 }
2467
2468 /* This is expanded by oacc_device_lower pass. */
2469
2470 static void
2471 expand_GOACC_REDUCTION (internal_fn, gcall *)
2472 {
2473 gcc_unreachable ();
2474 }
2475
2476 /* This is expanded by oacc_device_lower pass. */
2477
2478 static void
2479 expand_GOACC_TILE (internal_fn, gcall *)
2480 {
2481 gcc_unreachable ();
2482 }
2483
2484 /* Set errno to EDOM. */
2485
2486 static void
2487 expand_SET_EDOM (internal_fn, gcall *)
2488 {
2489 #ifdef TARGET_EDOM
2490 #ifdef GEN_ERRNO_RTX
2491 rtx errno_rtx = GEN_ERRNO_RTX;
2492 #else
2493 rtx errno_rtx = gen_rtx_MEM (word_mode, gen_rtx_SYMBOL_REF (Pmode, "errno"));
2494 #endif
2495 emit_move_insn (errno_rtx,
2496 gen_int_mode (TARGET_EDOM, GET_MODE (errno_rtx)));
2497 #else
2498 gcc_unreachable ();
2499 #endif
2500 }
2501
2502 /* Expand atomic bit test and set. */
2503
2504 static void
2505 expand_ATOMIC_BIT_TEST_AND_SET (internal_fn, gcall *call)
2506 {
2507 expand_ifn_atomic_bit_test_and (call);
2508 }
2509
2510 /* Expand atomic bit test and complement. */
2511
2512 static void
2513 expand_ATOMIC_BIT_TEST_AND_COMPLEMENT (internal_fn, gcall *call)
2514 {
2515 expand_ifn_atomic_bit_test_and (call);
2516 }
2517
2518 /* Expand atomic bit test and reset. */
2519
2520 static void
2521 expand_ATOMIC_BIT_TEST_AND_RESET (internal_fn, gcall *call)
2522 {
2523 expand_ifn_atomic_bit_test_and (call);
2524 }
2525
2526 /* Expand atomic bit test and set. */
2527
2528 static void
2529 expand_ATOMIC_COMPARE_EXCHANGE (internal_fn, gcall *call)
2530 {
2531 expand_ifn_atomic_compare_exchange (call);
2532 }
2533
2534 /* Expand LAUNDER to assignment, lhs = arg0. */
2535
2536 static void
2537 expand_LAUNDER (internal_fn, gcall *call)
2538 {
2539 tree lhs = gimple_call_lhs (call);
2540
2541 if (!lhs)
2542 return;
2543
2544 expand_assignment (lhs, gimple_call_arg (call, 0), false);
2545 }
2546
2547 /* Expand DIVMOD() using:
2548 a) optab handler for udivmod/sdivmod if it is available.
2549 b) If optab_handler doesn't exist, generate call to
2550 target-specific divmod libfunc. */
2551
2552 static void
2553 expand_DIVMOD (internal_fn, gcall *call_stmt)
2554 {
2555 tree lhs = gimple_call_lhs (call_stmt);
2556 tree arg0 = gimple_call_arg (call_stmt, 0);
2557 tree arg1 = gimple_call_arg (call_stmt, 1);
2558
2559 gcc_assert (TREE_CODE (TREE_TYPE (lhs)) == COMPLEX_TYPE);
2560 tree type = TREE_TYPE (TREE_TYPE (lhs));
2561 machine_mode mode = TYPE_MODE (type);
2562 bool unsignedp = TYPE_UNSIGNED (type);
2563 optab tab = (unsignedp) ? udivmod_optab : sdivmod_optab;
2564
2565 rtx op0 = expand_normal (arg0);
2566 rtx op1 = expand_normal (arg1);
2567 rtx target = expand_expr (lhs, NULL_RTX, VOIDmode, EXPAND_WRITE);
2568
2569 rtx quotient, remainder, libfunc;
2570
2571 /* Check if optab_handler exists for divmod_optab for given mode. */
2572 if (optab_handler (tab, mode) != CODE_FOR_nothing)
2573 {
2574 quotient = gen_reg_rtx (mode);
2575 remainder = gen_reg_rtx (mode);
2576 expand_twoval_binop (tab, op0, op1, quotient, remainder, unsignedp);
2577 }
2578
2579 /* Generate call to divmod libfunc if it exists. */
2580 else if ((libfunc = optab_libfunc (tab, mode)) != NULL_RTX)
2581 targetm.expand_divmod_libfunc (libfunc, mode, op0, op1,
2582 &quotient, &remainder);
2583
2584 else
2585 gcc_unreachable ();
2586
2587 /* Wrap the return value (quotient, remainder) within COMPLEX_EXPR. */
2588 expand_expr (build2 (COMPLEX_EXPR, TREE_TYPE (lhs),
2589 make_tree (TREE_TYPE (arg0), quotient),
2590 make_tree (TREE_TYPE (arg1), remainder)),
2591 target, VOIDmode, EXPAND_NORMAL);
2592 }
2593
2594 /* Expand a call to FN using the operands in STMT. FN has a single
2595 output operand and NARGS input operands. */
2596
2597 static void
2598 expand_direct_optab_fn (internal_fn fn, gcall *stmt, direct_optab optab,
2599 unsigned int nargs)
2600 {
2601 expand_operand *ops = XALLOCAVEC (expand_operand, nargs + 1);
2602
2603 tree_pair types = direct_internal_fn_types (fn, stmt);
2604 insn_code icode = direct_optab_handler (optab, TYPE_MODE (types.first));
2605
2606 tree lhs = gimple_call_lhs (stmt);
2607 tree lhs_type = TREE_TYPE (lhs);
2608 rtx lhs_rtx = expand_expr (lhs, NULL_RTX, VOIDmode, EXPAND_WRITE);
2609 create_output_operand (&ops[0], lhs_rtx, insn_data[icode].operand[0].mode);
2610
2611 for (unsigned int i = 0; i < nargs; ++i)
2612 {
2613 tree rhs = gimple_call_arg (stmt, i);
2614 tree rhs_type = TREE_TYPE (rhs);
2615 rtx rhs_rtx = expand_normal (rhs);
2616 if (INTEGRAL_TYPE_P (rhs_type))
2617 create_convert_operand_from (&ops[i + 1], rhs_rtx,
2618 TYPE_MODE (rhs_type),
2619 TYPE_UNSIGNED (rhs_type));
2620 else
2621 create_input_operand (&ops[i + 1], rhs_rtx, TYPE_MODE (rhs_type));
2622 }
2623
2624 expand_insn (icode, nargs + 1, ops);
2625 if (!rtx_equal_p (lhs_rtx, ops[0].value))
2626 {
2627 /* If the return value has an integral type, convert the instruction
2628 result to that type. This is useful for things that return an
2629 int regardless of the size of the input. If the instruction result
2630 is smaller than required, assume that it is signed.
2631
2632 If the return value has a nonintegral type, its mode must match
2633 the instruction result. */
2634 if (GET_CODE (lhs_rtx) == SUBREG && SUBREG_PROMOTED_VAR_P (lhs_rtx))
2635 {
2636 /* If this is a scalar in a register that is stored in a wider
2637 mode than the declared mode, compute the result into its
2638 declared mode and then convert to the wider mode. */
2639 gcc_checking_assert (INTEGRAL_TYPE_P (lhs_type));
2640 rtx tmp = convert_to_mode (GET_MODE (lhs_rtx), ops[0].value, 0);
2641 convert_move (SUBREG_REG (lhs_rtx), tmp,
2642 SUBREG_PROMOTED_SIGN (lhs_rtx));
2643 }
2644 else if (GET_MODE (lhs_rtx) == GET_MODE (ops[0].value))
2645 emit_move_insn (lhs_rtx, ops[0].value);
2646 else
2647 {
2648 gcc_checking_assert (INTEGRAL_TYPE_P (lhs_type));
2649 convert_move (lhs_rtx, ops[0].value, 0);
2650 }
2651 }
2652 }
2653
2654 /* Expanders for optabs that can use expand_direct_optab_fn. */
2655
2656 #define expand_unary_optab_fn(FN, STMT, OPTAB) \
2657 expand_direct_optab_fn (FN, STMT, OPTAB, 1)
2658
2659 #define expand_binary_optab_fn(FN, STMT, OPTAB) \
2660 expand_direct_optab_fn (FN, STMT, OPTAB, 2)
2661
2662 /* RETURN_TYPE and ARGS are a return type and argument list that are
2663 in principle compatible with FN (which satisfies direct_internal_fn_p).
2664 Return the types that should be used to determine whether the
2665 target supports FN. */
2666
2667 tree_pair
2668 direct_internal_fn_types (internal_fn fn, tree return_type, tree *args)
2669 {
2670 const direct_internal_fn_info &info = direct_internal_fn (fn);
2671 tree type0 = (info.type0 < 0 ? return_type : TREE_TYPE (args[info.type0]));
2672 tree type1 = (info.type1 < 0 ? return_type : TREE_TYPE (args[info.type1]));
2673 return tree_pair (type0, type1);
2674 }
2675
2676 /* CALL is a call whose return type and arguments are in principle
2677 compatible with FN (which satisfies direct_internal_fn_p). Return the
2678 types that should be used to determine whether the target supports FN. */
2679
2680 tree_pair
2681 direct_internal_fn_types (internal_fn fn, gcall *call)
2682 {
2683 const direct_internal_fn_info &info = direct_internal_fn (fn);
2684 tree op0 = (info.type0 < 0
2685 ? gimple_call_lhs (call)
2686 : gimple_call_arg (call, info.type0));
2687 tree op1 = (info.type1 < 0
2688 ? gimple_call_lhs (call)
2689 : gimple_call_arg (call, info.type1));
2690 return tree_pair (TREE_TYPE (op0), TREE_TYPE (op1));
2691 }
2692
2693 /* Return true if OPTAB is supported for TYPES (whose modes should be
2694 the same) when the optimization type is OPT_TYPE. Used for simple
2695 direct optabs. */
2696
2697 static bool
2698 direct_optab_supported_p (direct_optab optab, tree_pair types,
2699 optimization_type opt_type)
2700 {
2701 machine_mode mode = TYPE_MODE (types.first);
2702 gcc_checking_assert (mode == TYPE_MODE (types.second));
2703 return direct_optab_handler (optab, mode, opt_type) != CODE_FOR_nothing;
2704 }
2705
2706 /* Return true if load/store lanes optab OPTAB is supported for
2707 array type TYPES.first when the optimization type is OPT_TYPE. */
2708
2709 static bool
2710 multi_vector_optab_supported_p (convert_optab optab, tree_pair types,
2711 optimization_type opt_type)
2712 {
2713 gcc_assert (TREE_CODE (types.first) == ARRAY_TYPE);
2714 machine_mode imode = TYPE_MODE (types.first);
2715 machine_mode vmode = TYPE_MODE (TREE_TYPE (types.first));
2716 return (convert_optab_handler (optab, imode, vmode, opt_type)
2717 != CODE_FOR_nothing);
2718 }
2719
2720 #define direct_unary_optab_supported_p direct_optab_supported_p
2721 #define direct_binary_optab_supported_p direct_optab_supported_p
2722 #define direct_mask_load_optab_supported_p direct_optab_supported_p
2723 #define direct_load_lanes_optab_supported_p multi_vector_optab_supported_p
2724 #define direct_mask_store_optab_supported_p direct_optab_supported_p
2725 #define direct_store_lanes_optab_supported_p multi_vector_optab_supported_p
2726
2727 /* Return true if FN is supported for the types in TYPES when the
2728 optimization type is OPT_TYPE. The types are those associated with
2729 the "type0" and "type1" fields of FN's direct_internal_fn_info
2730 structure. */
2731
2732 bool
2733 direct_internal_fn_supported_p (internal_fn fn, tree_pair types,
2734 optimization_type opt_type)
2735 {
2736 switch (fn)
2737 {
2738 #define DEF_INTERNAL_FN(CODE, FLAGS, FNSPEC) \
2739 case IFN_##CODE: break;
2740 #define DEF_INTERNAL_OPTAB_FN(CODE, FLAGS, OPTAB, TYPE) \
2741 case IFN_##CODE: \
2742 return direct_##TYPE##_optab_supported_p (OPTAB##_optab, types, \
2743 opt_type);
2744 #include "internal-fn.def"
2745
2746 case IFN_LAST:
2747 break;
2748 }
2749 gcc_unreachable ();
2750 }
2751
2752 /* Return true if FN is supported for type TYPE when the optimization
2753 type is OPT_TYPE. The caller knows that the "type0" and "type1"
2754 fields of FN's direct_internal_fn_info structure are the same. */
2755
2756 bool
2757 direct_internal_fn_supported_p (internal_fn fn, tree type,
2758 optimization_type opt_type)
2759 {
2760 const direct_internal_fn_info &info = direct_internal_fn (fn);
2761 gcc_checking_assert (info.type0 == info.type1);
2762 return direct_internal_fn_supported_p (fn, tree_pair (type, type), opt_type);
2763 }
2764
2765 /* Return true if IFN_SET_EDOM is supported. */
2766
2767 bool
2768 set_edom_supported_p (void)
2769 {
2770 #ifdef TARGET_EDOM
2771 return true;
2772 #else
2773 return false;
2774 #endif
2775 }
2776
2777 #define DEF_INTERNAL_OPTAB_FN(CODE, FLAGS, OPTAB, TYPE) \
2778 static void \
2779 expand_##CODE (internal_fn fn, gcall *stmt) \
2780 { \
2781 expand_##TYPE##_optab_fn (fn, stmt, OPTAB##_optab); \
2782 }
2783 #include "internal-fn.def"
2784
2785 /* Routines to expand each internal function, indexed by function number.
2786 Each routine has the prototype:
2787
2788 expand_<NAME> (gcall *stmt)
2789
2790 where STMT is the statement that performs the call. */
2791 static void (*const internal_fn_expanders[]) (internal_fn, gcall *) = {
2792 #define DEF_INTERNAL_FN(CODE, FLAGS, FNSPEC) expand_##CODE,
2793 #include "internal-fn.def"
2794 0
2795 };
2796
2797 /* Expand STMT as though it were a call to internal function FN. */
2798
2799 void
2800 expand_internal_call (internal_fn fn, gcall *stmt)
2801 {
2802 internal_fn_expanders[fn] (fn, stmt);
2803 }
2804
2805 /* Expand STMT, which is a call to internal function FN. */
2806
2807 void
2808 expand_internal_call (gcall *stmt)
2809 {
2810 expand_internal_call (gimple_call_internal_fn (stmt), stmt);
2811 }
2812
2813 void
2814 expand_PHI (internal_fn, gcall *)
2815 {
2816 gcc_unreachable ();
2817 }