]> git.ipfire.org Git - thirdparty/gcc.git/blame - gcc/internal-fn.c
Fix double word typos.
[thirdparty/gcc.git] / gcc / internal-fn.c
CommitLineData
25583c4f 1/* Internal functions.
5624e564 2 Copyright (C) 2011-2015 Free Software Foundation, Inc.
25583c4f
RS
3
4This file is part of GCC.
5
6GCC is free software; you can redistribute it and/or modify it under
7the terms of the GNU General Public License as published by the Free
8Software Foundation; either version 3, or (at your option) any later
9version.
10
11GCC is distributed in the hope that it will be useful, but WITHOUT ANY
12WARRANTY; without even the implied warranty of MERCHANTABILITY or
13FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License
14for more details.
15
16You should have received a copy of the GNU General Public License
17along 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"
40e23961 23#include "alias.h"
c7131fb2 24#include "backend.h"
9fdcd34e 25#include "predict.h"
25583c4f 26#include "tree.h"
c7131fb2
AM
27#include "gimple.h"
28#include "rtl.h"
29#include "options.h"
40e23961 30#include "fold-const.h"
0e37a2f3 31#include "internal-fn.h"
d8a2d370 32#include "stor-layout.h"
36566b39 33#include "flags.h"
36566b39
PK
34#include "insn-config.h"
35#include "expmed.h"
36#include "dojump.h"
37#include "explow.h"
38#include "calls.h"
39#include "emit-rtl.h"
40#include "varasm.h"
41#include "stmt.h"
25583c4f 42#include "expr.h"
b0710fe1 43#include "insn-codes.h"
25583c4f 44#include "optabs.h"
31e071ae
MP
45#include "ubsan.h"
46#include "target.h"
97286431
JJ
47#include "stringpool.h"
48#include "tree-ssanames.h"
ed9c79e1 49#include "diagnostic-core.h"
25583c4f
RS
50
51/* The names of each internal function, indexed by function number. */
52const char *const internal_fn_name_array[] = {
b78475cf 53#define DEF_INTERNAL_FN(CODE, FLAGS, FNSPEC) #CODE,
25583c4f
RS
54#include "internal-fn.def"
55#undef DEF_INTERNAL_FN
56 "<invalid-fn>"
57};
58
59/* The ECF_* flags of each internal function, indexed by function number. */
60const int internal_fn_flags_array[] = {
b78475cf 61#define DEF_INTERNAL_FN(CODE, FLAGS, FNSPEC) FLAGS,
25583c4f
RS
62#include "internal-fn.def"
63#undef DEF_INTERNAL_FN
64 0
65};
66
b78475cf
YG
67/* Fnspec of each internal function, indexed by function number. */
68const_tree internal_fn_fnspec_array[IFN_LAST + 1];
69
70void
71init_internal_fns ()
72{
73#define DEF_INTERNAL_FN(CODE, FLAGS, FNSPEC) \
74 if (FNSPEC) internal_fn_fnspec_array[IFN_##CODE] = \
63a4184f 75 build_string ((int) sizeof (FNSPEC), FNSPEC ? FNSPEC : "");
b78475cf
YG
76#include "internal-fn.def"
77#undef DEF_INTERNAL_FN
78 internal_fn_fnspec_array[IFN_LAST] = 0;
79}
80
272c6793
RS
81/* ARRAY_TYPE is an array of vector modes. Return the associated insn
82 for load-lanes-style optab OPTAB. The insn must exist. */
83
84static enum insn_code
85get_multi_vector_move (tree array_type, convert_optab optab)
86{
87 enum insn_code icode;
ef4bddc2
RS
88 machine_mode imode;
89 machine_mode vmode;
272c6793
RS
90
91 gcc_assert (TREE_CODE (array_type) == ARRAY_TYPE);
92 imode = TYPE_MODE (array_type);
93 vmode = TYPE_MODE (TREE_TYPE (array_type));
94
95 icode = convert_optab_handler (optab, imode, vmode);
96 gcc_assert (icode != CODE_FOR_nothing);
97 return icode;
98}
99
100/* Expand LOAD_LANES call STMT. */
101
102static void
538dd0b7 103expand_LOAD_LANES (gcall *stmt)
272c6793
RS
104{
105 struct expand_operand ops[2];
106 tree type, lhs, rhs;
107 rtx target, mem;
108
109 lhs = gimple_call_lhs (stmt);
110 rhs = gimple_call_arg (stmt, 0);
111 type = TREE_TYPE (lhs);
112
113 target = expand_expr (lhs, NULL_RTX, VOIDmode, EXPAND_WRITE);
114 mem = expand_normal (rhs);
115
116 gcc_assert (MEM_P (mem));
117 PUT_MODE (mem, TYPE_MODE (type));
118
119 create_output_operand (&ops[0], target, TYPE_MODE (type));
120 create_fixed_operand (&ops[1], mem);
121 expand_insn (get_multi_vector_move (type, vec_load_lanes_optab), 2, ops);
122}
123
124/* Expand STORE_LANES call STMT. */
125
126static void
538dd0b7 127expand_STORE_LANES (gcall *stmt)
272c6793
RS
128{
129 struct expand_operand ops[2];
130 tree type, lhs, rhs;
131 rtx target, reg;
132
133 lhs = gimple_call_lhs (stmt);
134 rhs = gimple_call_arg (stmt, 0);
135 type = TREE_TYPE (rhs);
136
137 target = expand_expr (lhs, NULL_RTX, VOIDmode, EXPAND_WRITE);
138 reg = expand_normal (rhs);
139
140 gcc_assert (MEM_P (target));
141 PUT_MODE (target, TYPE_MODE (type));
142
143 create_fixed_operand (&ops[0], target);
144 create_input_operand (&ops[1], reg, TYPE_MODE (type));
145 expand_insn (get_multi_vector_move (type, vec_store_lanes_optab), 2, ops);
146}
147
8170608b 148static void
35228ac7 149expand_ANNOTATE (gcall *)
8170608b
TB
150{
151 gcc_unreachable ();
152}
153
74bf76ed
JJ
154/* This should get expanded in adjust_simduid_builtins. */
155
156static void
35228ac7 157expand_GOMP_SIMD_LANE (gcall *)
74bf76ed
JJ
158{
159 gcc_unreachable ();
160}
161
162/* This should get expanded in adjust_simduid_builtins. */
163
164static void
35228ac7 165expand_GOMP_SIMD_VF (gcall *)
74bf76ed
JJ
166{
167 gcc_unreachable ();
168}
169
170/* This should get expanded in adjust_simduid_builtins. */
171
172static void
35228ac7 173expand_GOMP_SIMD_LAST_LANE (gcall *)
74bf76ed
JJ
174{
175 gcc_unreachable ();
176}
177
b9a55b13
MP
178/* This should get expanded in the sanopt pass. */
179
180static void
35228ac7 181expand_UBSAN_NULL (gcall *)
b9a55b13
MP
182{
183 gcc_unreachable ();
184}
185
0e37a2f3
MP
186/* This should get expanded in the sanopt pass. */
187
188static void
35228ac7 189expand_UBSAN_BOUNDS (gcall *)
0e82f089
MP
190{
191 gcc_unreachable ();
192}
193
194/* This should get expanded in the sanopt pass. */
195
196static void
35228ac7 197expand_UBSAN_VPTR (gcall *)
0e37a2f3
MP
198{
199 gcc_unreachable ();
200}
201
c62ccb9a
YG
202/* This should get expanded in the sanopt pass. */
203
204static void
35228ac7
JJ
205expand_UBSAN_OBJECT_SIZE (gcall *)
206{
207 gcc_unreachable ();
208}
209
210/* This should get expanded in the sanopt pass. */
211
212static void
213expand_ASAN_CHECK (gcall *)
c62ccb9a
YG
214{
215 gcc_unreachable ();
216}
217
fca4adf2
JJ
218/* This should get expanded in the tsan pass. */
219
220static void
221expand_TSAN_FUNC_EXIT (gcall *)
222{
223 gcc_unreachable ();
224}
225
1304953e
JJ
226/* Helper function for expand_addsub_overflow. Return 1
227 if ARG interpreted as signed in its precision is known to be always
228 positive or 2 if ARG is known to be always negative, or 3 if ARG may
229 be positive or negative. */
230
231static int
232get_range_pos_neg (tree arg)
233{
234 if (arg == error_mark_node)
235 return 3;
236
237 int prec = TYPE_PRECISION (TREE_TYPE (arg));
238 int cnt = 0;
239 if (TREE_CODE (arg) == INTEGER_CST)
240 {
241 wide_int w = wi::sext (arg, prec);
242 if (wi::neg_p (w))
243 return 2;
244 else
245 return 1;
246 }
247 while (CONVERT_EXPR_P (arg)
248 && INTEGRAL_TYPE_P (TREE_TYPE (TREE_OPERAND (arg, 0)))
249 && TYPE_PRECISION (TREE_TYPE (TREE_OPERAND (arg, 0))) <= prec)
250 {
251 arg = TREE_OPERAND (arg, 0);
252 /* Narrower value zero extended into wider type
253 will always result in positive values. */
254 if (TYPE_UNSIGNED (TREE_TYPE (arg))
255 && TYPE_PRECISION (TREE_TYPE (arg)) < prec)
256 return 1;
257 prec = TYPE_PRECISION (TREE_TYPE (arg));
258 if (++cnt > 30)
259 return 3;
260 }
261
262 if (TREE_CODE (arg) != SSA_NAME)
263 return 3;
264 wide_int arg_min, arg_max;
265 while (get_range_info (arg, &arg_min, &arg_max) != VR_RANGE)
266 {
267 gimple g = SSA_NAME_DEF_STMT (arg);
268 if (is_gimple_assign (g)
269 && CONVERT_EXPR_CODE_P (gimple_assign_rhs_code (g)))
270 {
271 tree t = gimple_assign_rhs1 (g);
272 if (INTEGRAL_TYPE_P (TREE_TYPE (t))
273 && TYPE_PRECISION (TREE_TYPE (t)) <= prec)
274 {
275 if (TYPE_UNSIGNED (TREE_TYPE (t))
276 && TYPE_PRECISION (TREE_TYPE (t)) < prec)
277 return 1;
278 prec = TYPE_PRECISION (TREE_TYPE (t));
279 arg = t;
280 if (++cnt > 30)
281 return 3;
282 continue;
283 }
284 }
285 return 3;
286 }
287 if (TYPE_UNSIGNED (TREE_TYPE (arg)))
288 {
289 /* For unsigned values, the "positive" range comes
290 below the "negative" range. */
291 if (!wi::neg_p (wi::sext (arg_max, prec), SIGNED))
292 return 1;
293 if (wi::neg_p (wi::sext (arg_min, prec), SIGNED))
294 return 2;
295 }
296 else
297 {
298 if (!wi::neg_p (wi::sext (arg_min, prec), SIGNED))
299 return 1;
300 if (wi::neg_p (wi::sext (arg_max, prec), SIGNED))
301 return 2;
302 }
303 return 3;
304}
305
306/* Return minimum precision needed to represent all values
307 of ARG in SIGNed integral type. */
308
309static int
310get_min_precision (tree arg, signop sign)
311{
312 int prec = TYPE_PRECISION (TREE_TYPE (arg));
313 int cnt = 0;
314 signop orig_sign = sign;
315 if (TREE_CODE (arg) == INTEGER_CST)
316 {
317 int p;
318 if (TYPE_SIGN (TREE_TYPE (arg)) != sign)
319 {
320 widest_int w = wi::to_widest (arg);
321 w = wi::ext (w, prec, sign);
322 p = wi::min_precision (w, sign);
323 }
324 else
325 p = wi::min_precision (arg, sign);
326 return MIN (p, prec);
327 }
328 while (CONVERT_EXPR_P (arg)
329 && INTEGRAL_TYPE_P (TREE_TYPE (TREE_OPERAND (arg, 0)))
330 && TYPE_PRECISION (TREE_TYPE (TREE_OPERAND (arg, 0))) <= prec)
331 {
332 arg = TREE_OPERAND (arg, 0);
333 if (TYPE_PRECISION (TREE_TYPE (arg)) < prec)
334 {
335 if (TYPE_UNSIGNED (TREE_TYPE (arg)))
336 sign = UNSIGNED;
337 else if (sign == UNSIGNED && get_range_pos_neg (arg) != 1)
338 return prec + (orig_sign != sign);
339 prec = TYPE_PRECISION (TREE_TYPE (arg));
340 }
341 if (++cnt > 30)
342 return prec + (orig_sign != sign);
343 }
344 if (TREE_CODE (arg) != SSA_NAME)
345 return prec + (orig_sign != sign);
346 wide_int arg_min, arg_max;
347 while (get_range_info (arg, &arg_min, &arg_max) != VR_RANGE)
348 {
349 gimple g = SSA_NAME_DEF_STMT (arg);
350 if (is_gimple_assign (g)
351 && CONVERT_EXPR_CODE_P (gimple_assign_rhs_code (g)))
352 {
353 tree t = gimple_assign_rhs1 (g);
354 if (INTEGRAL_TYPE_P (TREE_TYPE (t))
355 && TYPE_PRECISION (TREE_TYPE (t)) <= prec)
356 {
357 arg = t;
358 if (TYPE_PRECISION (TREE_TYPE (arg)) < prec)
359 {
360 if (TYPE_UNSIGNED (TREE_TYPE (arg)))
361 sign = UNSIGNED;
362 else if (sign == UNSIGNED && get_range_pos_neg (arg) != 1)
363 return prec + (orig_sign != sign);
364 prec = TYPE_PRECISION (TREE_TYPE (arg));
365 }
366 if (++cnt > 30)
367 return prec + (orig_sign != sign);
368 continue;
369 }
370 }
371 return prec + (orig_sign != sign);
372 }
373 if (sign == TYPE_SIGN (TREE_TYPE (arg)))
374 {
375 int p1 = wi::min_precision (arg_min, sign);
376 int p2 = wi::min_precision (arg_max, sign);
377 p1 = MAX (p1, p2);
378 prec = MIN (prec, p1);
379 }
380 else if (sign == UNSIGNED && !wi::neg_p (arg_min, SIGNED))
381 {
c1ee2e62 382 int p = wi::min_precision (arg_max, UNSIGNED);
1304953e
JJ
383 prec = MIN (prec, p);
384 }
385 return prec + (orig_sign != sign);
386}
387
388/* Helper for expand_*_overflow. Store RES into the __real__ part
389 of TARGET. If RES has larger MODE than __real__ part of TARGET,
390 set the __imag__ part to 1 if RES doesn't fit into it. */
391
392static void
393expand_arith_overflow_result_store (tree lhs, rtx target,
394 machine_mode mode, rtx res)
395{
396 machine_mode tgtmode = GET_MODE_INNER (GET_MODE (target));
397 rtx lres = res;
398 if (tgtmode != mode)
399 {
400 rtx_code_label *done_label = gen_label_rtx ();
401 int uns = TYPE_UNSIGNED (TREE_TYPE (TREE_TYPE (lhs)));
402 lres = convert_modes (tgtmode, mode, res, uns);
403 gcc_assert (GET_MODE_PRECISION (tgtmode) < GET_MODE_PRECISION (mode));
92344ed0 404 do_compare_rtx_and_jump (res, convert_modes (mode, tgtmode, lres, uns),
1476d1bd 405 EQ, true, mode, NULL_RTX, NULL, done_label,
1304953e
JJ
406 PROB_VERY_LIKELY);
407 write_complex_part (target, const1_rtx, true);
408 emit_label (done_label);
409 }
410 write_complex_part (target, lres, false);
411}
412
5620052d
JJ
413/* Helper for expand_*_overflow. Store RES into TARGET. */
414
415static void
416expand_ubsan_result_store (rtx target, rtx res)
417{
418 if (GET_CODE (target) == SUBREG && SUBREG_PROMOTED_VAR_P (target))
419 /* If this is a scalar in a register that is stored in a wider mode
420 than the declared mode, compute the result into its declared mode
421 and then convert to the wider mode. Our value is the computed
422 expression. */
423 convert_move (SUBREG_REG (target), res, SUBREG_PROMOTED_SIGN (target));
424 else
425 emit_move_insn (target, res);
426}
427
31e071ae
MP
428/* Add sub/add overflow checking to the statement STMT.
429 CODE says whether the operation is +, or -. */
430
1304953e
JJ
431static void
432expand_addsub_overflow (location_t loc, tree_code code, tree lhs,
433 tree arg0, tree arg1, bool unsr_p, bool uns0_p,
434 bool uns1_p, bool is_ubsan)
31e071ae 435{
1304953e
JJ
436 rtx res, target = NULL_RTX;
437 tree fn;
438 rtx_code_label *done_label = gen_label_rtx ();
439 rtx_code_label *do_error = gen_label_rtx ();
31e071ae 440 do_pending_stack_adjust ();
1304953e
JJ
441 rtx op0 = expand_normal (arg0);
442 rtx op1 = expand_normal (arg1);
ef4bddc2 443 machine_mode mode = TYPE_MODE (TREE_TYPE (arg0));
1304953e
JJ
444 int prec = GET_MODE_PRECISION (mode);
445 rtx sgn = immed_wide_int_const (wi::min_value (prec, SIGNED), mode);
446 bool do_xor = false;
447
448 if (is_ubsan)
449 gcc_assert (!unsr_p && !uns0_p && !uns1_p);
450
31e071ae 451 if (lhs)
1304953e
JJ
452 {
453 target = expand_expr (lhs, NULL_RTX, VOIDmode, EXPAND_WRITE);
454 if (!is_ubsan)
455 write_complex_part (target, const0_rtx, true);
456 }
457
458 /* We assume both operands and result have the same precision
459 here (GET_MODE_BITSIZE (mode)), S stands for signed type
460 with that precision, U for unsigned type with that precision,
461 sgn for unsigned most significant bit in that precision.
462 s1 is signed first operand, u1 is unsigned first operand,
463 s2 is signed second operand, u2 is unsigned second operand,
464 sr is signed result, ur is unsigned result and the following
465 rules say how to compute result (which is always result of
466 the operands as if both were unsigned, cast to the right
467 signedness) and how to compute whether operation overflowed.
468
469 s1 + s2 -> sr
470 res = (S) ((U) s1 + (U) s2)
471 ovf = s2 < 0 ? res > s1 : res < s1 (or jump on overflow)
472 s1 - s2 -> sr
473 res = (S) ((U) s1 - (U) s2)
474 ovf = s2 < 0 ? res < s1 : res > s2 (or jump on overflow)
475 u1 + u2 -> ur
476 res = u1 + u2
477 ovf = res < u1 (or jump on carry, but RTL opts will handle it)
478 u1 - u2 -> ur
479 res = u1 - u2
480 ovf = res > u1 (or jump on carry, but RTL opts will handle it)
481 s1 + u2 -> sr
482 res = (S) ((U) s1 + u2)
483 ovf = ((U) res ^ sgn) < u2
484 s1 + u2 -> ur
485 t1 = (S) (u2 ^ sgn)
486 t2 = s1 + t1
487 res = (U) t2 ^ sgn
488 ovf = t1 < 0 ? t2 > s1 : t2 < s1 (or jump on overflow)
489 s1 - u2 -> sr
490 res = (S) ((U) s1 - u2)
491 ovf = u2 > ((U) s1 ^ sgn)
492 s1 - u2 -> ur
493 res = (U) s1 - u2
494 ovf = s1 < 0 || u2 > (U) s1
495 u1 - s2 -> sr
496 res = u1 - (U) s2
497 ovf = u1 >= ((U) s2 ^ sgn)
498 u1 - s2 -> ur
499 t1 = u1 ^ sgn
500 t2 = t1 - (U) s2
501 res = t2 ^ sgn
502 ovf = s2 < 0 ? (S) t2 < (S) t1 : (S) t2 > (S) t1 (or jump on overflow)
503 s1 + s2 -> ur
504 res = (U) s1 + (U) s2
505 ovf = s2 < 0 ? (s1 | (S) res) < 0) : (s1 & (S) res) < 0)
506 u1 + u2 -> sr
507 res = (S) (u1 + u2)
508 ovf = (U) res < u2 || res < 0
509 u1 - u2 -> sr
510 res = (S) (u1 - u2)
511 ovf = u1 >= u2 ? res < 0 : res >= 0
512 s1 - s2 -> ur
513 res = (U) s1 - (U) s2
514 ovf = s2 >= 0 ? ((s1 | (S) res) < 0) : ((s1 & (S) res) < 0) */
515
516 if (code == PLUS_EXPR && uns0_p && !uns1_p)
517 {
518 /* PLUS_EXPR is commutative, if operand signedness differs,
519 canonicalize to the first operand being signed and second
520 unsigned to simplify following code. */
6b4db501
MM
521 std::swap (op0, op1);
522 std::swap (arg0, arg1);
523 uns0_p = false;
524 uns1_p = true;
1304953e
JJ
525 }
526
527 /* u1 +- u2 -> ur */
528 if (uns0_p && uns1_p && unsr_p)
529 {
530 /* Compute the operation. On RTL level, the addition is always
531 unsigned. */
532 res = expand_binop (mode, code == PLUS_EXPR ? add_optab : sub_optab,
533 op0, op1, NULL_RTX, false, OPTAB_LIB_WIDEN);
534 rtx tem = op0;
535 /* For PLUS_EXPR, the operation is commutative, so we can pick
536 operand to compare against. For prec <= BITS_PER_WORD, I think
537 preferring REG operand is better over CONST_INT, because
538 the CONST_INT might enlarge the instruction or CSE would need
539 to figure out we'd already loaded it into a register before.
540 For prec > BITS_PER_WORD, I think CONST_INT might be more beneficial,
541 as then the multi-word comparison can be perhaps simplified. */
542 if (code == PLUS_EXPR
543 && (prec <= BITS_PER_WORD
544 ? (CONST_SCALAR_INT_P (op0) && REG_P (op1))
545 : CONST_SCALAR_INT_P (op1)))
546 tem = op1;
92344ed0 547 do_compare_rtx_and_jump (res, tem, code == PLUS_EXPR ? GEU : LEU,
1476d1bd 548 true, mode, NULL_RTX, NULL, done_label,
1304953e
JJ
549 PROB_VERY_LIKELY);
550 goto do_error_label;
551 }
552
553 /* s1 +- u2 -> sr */
554 if (!uns0_p && uns1_p && !unsr_p)
555 {
556 /* Compute the operation. On RTL level, the addition is always
557 unsigned. */
558 res = expand_binop (mode, code == PLUS_EXPR ? add_optab : sub_optab,
559 op0, op1, NULL_RTX, false, OPTAB_LIB_WIDEN);
560 rtx tem = expand_binop (mode, add_optab,
561 code == PLUS_EXPR ? res : op0, sgn,
562 NULL_RTX, false, OPTAB_LIB_WIDEN);
1476d1bd 563 do_compare_rtx_and_jump (tem, op1, GEU, true, mode, NULL_RTX, NULL,
1304953e
JJ
564 done_label, PROB_VERY_LIKELY);
565 goto do_error_label;
566 }
567
568 /* s1 + u2 -> ur */
569 if (code == PLUS_EXPR && !uns0_p && uns1_p && unsr_p)
570 {
571 op1 = expand_binop (mode, add_optab, op1, sgn, NULL_RTX, false,
572 OPTAB_LIB_WIDEN);
573 /* As we've changed op1, we have to avoid using the value range
574 for the original argument. */
575 arg1 = error_mark_node;
576 do_xor = true;
577 goto do_signed;
578 }
579
580 /* u1 - s2 -> ur */
581 if (code == MINUS_EXPR && uns0_p && !uns1_p && unsr_p)
582 {
583 op0 = expand_binop (mode, add_optab, op0, sgn, NULL_RTX, false,
584 OPTAB_LIB_WIDEN);
585 /* As we've changed op0, we have to avoid using the value range
586 for the original argument. */
587 arg0 = error_mark_node;
588 do_xor = true;
589 goto do_signed;
590 }
591
592 /* s1 - u2 -> ur */
593 if (code == MINUS_EXPR && !uns0_p && uns1_p && unsr_p)
594 {
595 /* Compute the operation. On RTL level, the addition is always
596 unsigned. */
597 res = expand_binop (mode, sub_optab, op0, op1, NULL_RTX, false,
598 OPTAB_LIB_WIDEN);
599 int pos_neg = get_range_pos_neg (arg0);
600 if (pos_neg == 2)
601 /* If ARG0 is known to be always negative, this is always overflow. */
602 emit_jump (do_error);
603 else if (pos_neg == 3)
604 /* If ARG0 is not known to be always positive, check at runtime. */
92344ed0 605 do_compare_rtx_and_jump (op0, const0_rtx, LT, false, mode, NULL_RTX,
1476d1bd
MM
606 NULL, do_error, PROB_VERY_UNLIKELY);
607 do_compare_rtx_and_jump (op1, op0, LEU, true, mode, NULL_RTX, NULL,
1304953e
JJ
608 done_label, PROB_VERY_LIKELY);
609 goto do_error_label;
610 }
611
612 /* u1 - s2 -> sr */
613 if (code == MINUS_EXPR && uns0_p && !uns1_p && !unsr_p)
614 {
615 /* Compute the operation. On RTL level, the addition is always
616 unsigned. */
617 res = expand_binop (mode, sub_optab, op0, op1, NULL_RTX, false,
618 OPTAB_LIB_WIDEN);
619 rtx tem = expand_binop (mode, add_optab, op1, sgn, NULL_RTX, false,
620 OPTAB_LIB_WIDEN);
1476d1bd 621 do_compare_rtx_and_jump (op0, tem, LTU, true, mode, NULL_RTX, NULL,
1304953e
JJ
622 done_label, PROB_VERY_LIKELY);
623 goto do_error_label;
624 }
625
626 /* u1 + u2 -> sr */
627 if (code == PLUS_EXPR && uns0_p && uns1_p && !unsr_p)
628 {
629 /* Compute the operation. On RTL level, the addition is always
630 unsigned. */
631 res = expand_binop (mode, add_optab, op0, op1, NULL_RTX, false,
632 OPTAB_LIB_WIDEN);
92344ed0 633 do_compare_rtx_and_jump (res, const0_rtx, LT, false, mode, NULL_RTX,
1476d1bd 634 NULL, do_error, PROB_VERY_UNLIKELY);
1304953e
JJ
635 rtx tem = op1;
636 /* The operation is commutative, so we can pick operand to compare
637 against. For prec <= BITS_PER_WORD, I think preferring REG operand
638 is better over CONST_INT, because the CONST_INT might enlarge the
639 instruction or CSE would need to figure out we'd already loaded it
640 into a register before. For prec > BITS_PER_WORD, I think CONST_INT
641 might be more beneficial, as then the multi-word comparison can be
642 perhaps simplified. */
643 if (prec <= BITS_PER_WORD
644 ? (CONST_SCALAR_INT_P (op1) && REG_P (op0))
645 : CONST_SCALAR_INT_P (op0))
646 tem = op0;
1476d1bd 647 do_compare_rtx_and_jump (res, tem, GEU, true, mode, NULL_RTX, NULL,
1304953e
JJ
648 done_label, PROB_VERY_LIKELY);
649 goto do_error_label;
650 }
651
652 /* s1 +- s2 -> ur */
653 if (!uns0_p && !uns1_p && unsr_p)
654 {
655 /* Compute the operation. On RTL level, the addition is always
656 unsigned. */
657 res = expand_binop (mode, code == PLUS_EXPR ? add_optab : sub_optab,
658 op0, op1, NULL_RTX, false, OPTAB_LIB_WIDEN);
659 int pos_neg = get_range_pos_neg (arg1);
660 if (code == PLUS_EXPR)
661 {
662 int pos_neg0 = get_range_pos_neg (arg0);
663 if (pos_neg0 != 3 && pos_neg == 3)
664 {
6b4db501 665 std::swap (op0, op1);
1304953e
JJ
666 pos_neg = pos_neg0;
667 }
668 }
669 rtx tem;
670 if (pos_neg != 3)
671 {
672 tem = expand_binop (mode, ((pos_neg == 1) ^ (code == MINUS_EXPR))
673 ? and_optab : ior_optab,
674 op0, res, NULL_RTX, false, OPTAB_LIB_WIDEN);
1476d1bd
MM
675 do_compare_rtx_and_jump (tem, const0_rtx, GE, false, mode, NULL,
676 NULL, done_label, PROB_VERY_LIKELY);
1304953e
JJ
677 }
678 else
679 {
680 rtx_code_label *do_ior_label = gen_label_rtx ();
92344ed0
JJ
681 do_compare_rtx_and_jump (op1, const0_rtx,
682 code == MINUS_EXPR ? GE : LT, false, mode,
1476d1bd 683 NULL_RTX, NULL, do_ior_label,
92344ed0 684 PROB_EVEN);
1304953e
JJ
685 tem = expand_binop (mode, and_optab, op0, res, NULL_RTX, false,
686 OPTAB_LIB_WIDEN);
92344ed0 687 do_compare_rtx_and_jump (tem, const0_rtx, GE, false, mode, NULL_RTX,
1476d1bd 688 NULL, done_label, PROB_VERY_LIKELY);
1304953e
JJ
689 emit_jump (do_error);
690 emit_label (do_ior_label);
691 tem = expand_binop (mode, ior_optab, op0, res, NULL_RTX, false,
692 OPTAB_LIB_WIDEN);
92344ed0 693 do_compare_rtx_and_jump (tem, const0_rtx, GE, false, mode, NULL_RTX,
1476d1bd 694 NULL, done_label, PROB_VERY_LIKELY);
1304953e
JJ
695 }
696 goto do_error_label;
697 }
698
699 /* u1 - u2 -> sr */
700 if (code == MINUS_EXPR && uns0_p && uns1_p && !unsr_p)
701 {
702 /* Compute the operation. On RTL level, the addition is always
703 unsigned. */
704 res = expand_binop (mode, sub_optab, op0, op1, NULL_RTX, false,
705 OPTAB_LIB_WIDEN);
706 rtx_code_label *op0_geu_op1 = gen_label_rtx ();
1476d1bd 707 do_compare_rtx_and_jump (op0, op1, GEU, true, mode, NULL_RTX, NULL,
1304953e 708 op0_geu_op1, PROB_EVEN);
92344ed0 709 do_compare_rtx_and_jump (res, const0_rtx, LT, false, mode, NULL_RTX,
1476d1bd 710 NULL, done_label, PROB_VERY_LIKELY);
1304953e
JJ
711 emit_jump (do_error);
712 emit_label (op0_geu_op1);
92344ed0 713 do_compare_rtx_and_jump (res, const0_rtx, GE, false, mode, NULL_RTX,
1476d1bd 714 NULL, done_label, PROB_VERY_LIKELY);
1304953e
JJ
715 goto do_error_label;
716 }
31e071ae 717
1304953e
JJ
718 gcc_assert (!uns0_p && !uns1_p && !unsr_p);
719
720 /* s1 +- s2 -> sr */
721 do_signed: ;
722 enum insn_code icode;
723 icode = optab_handler (code == PLUS_EXPR ? addv4_optab : subv4_optab, mode);
31e071ae
MP
724 if (icode != CODE_FOR_nothing)
725 {
726 struct expand_operand ops[4];
da664544 727 rtx_insn *last = get_last_insn ();
31e071ae
MP
728
729 res = gen_reg_rtx (mode);
730 create_output_operand (&ops[0], res, mode);
731 create_input_operand (&ops[1], op0, mode);
732 create_input_operand (&ops[2], op1, mode);
733 create_fixed_operand (&ops[3], do_error);
734 if (maybe_expand_insn (icode, 4, ops))
735 {
736 last = get_last_insn ();
0a6a6ac9 737 if (profile_status_for_fn (cfun) != PROFILE_ABSENT
31e071ae
MP
738 && JUMP_P (last)
739 && any_condjump_p (last)
740 && !find_reg_note (last, REG_BR_PROB, 0))
741 add_int_reg_note (last, REG_BR_PROB, PROB_VERY_UNLIKELY);
742 emit_jump (done_label);
743 }
744 else
745 {
746 delete_insns_since (last);
747 icode = CODE_FOR_nothing;
748 }
749 }
750
751 if (icode == CODE_FOR_nothing)
752 {
da664544 753 rtx_code_label *sub_check = gen_label_rtx ();
97286431 754 int pos_neg = 3;
31e071ae
MP
755
756 /* Compute the operation. On RTL level, the addition is always
757 unsigned. */
7ddf4d5a
MP
758 res = expand_binop (mode, code == PLUS_EXPR ? add_optab : sub_optab,
759 op0, op1, NULL_RTX, false, OPTAB_LIB_WIDEN);
31e071ae 760
f451d3a8
JJ
761 /* If we can prove one of the arguments (for MINUS_EXPR only
762 the second operand, as subtraction is not commutative) is always
763 non-negative or always negative, we can do just one comparison
764 and conditional jump instead of 2 at runtime, 3 present in the
97286431
JJ
765 emitted code. If one of the arguments is CONST_INT, all we
766 need is to make sure it is op1, then the first
92344ed0 767 do_compare_rtx_and_jump will be just folded. Otherwise try
97286431 768 to use range info if available. */
f451d3a8 769 if (code == PLUS_EXPR && CONST_INT_P (op0))
6b4db501 770 std::swap (op0, op1);
97286431
JJ
771 else if (CONST_INT_P (op1))
772 ;
f451d3a8 773 else if (code == PLUS_EXPR && TREE_CODE (arg0) == SSA_NAME)
97286431 774 {
1304953e 775 pos_neg = get_range_pos_neg (arg0);
97286431 776 if (pos_neg != 3)
6b4db501 777 std::swap (op0, op1);
97286431
JJ
778 }
779 if (pos_neg == 3 && !CONST_INT_P (op1) && TREE_CODE (arg1) == SSA_NAME)
1304953e 780 pos_neg = get_range_pos_neg (arg1);
97286431 781
31e071ae 782 /* If the op1 is negative, we have to use a different check. */
97286431 783 if (pos_neg == 3)
92344ed0 784 do_compare_rtx_and_jump (op1, const0_rtx, LT, false, mode, NULL_RTX,
1476d1bd 785 NULL, sub_check, PROB_EVEN);
31e071ae 786
7ddf4d5a 787 /* Compare the result of the operation with one of the operands. */
97286431 788 if (pos_neg & 1)
92344ed0 789 do_compare_rtx_and_jump (res, op0, code == PLUS_EXPR ? GE : LE,
1476d1bd 790 false, mode, NULL_RTX, NULL, done_label,
97286431
JJ
791 PROB_VERY_LIKELY);
792
31e071ae 793 /* If we get here, we have to print the error. */
97286431
JJ
794 if (pos_neg == 3)
795 {
796 emit_jump (do_error);
797
798 emit_label (sub_check);
799 }
31e071ae 800
31e071ae 801 /* We have k = a + b for b < 0 here. k <= a must hold. */
97286431 802 if (pos_neg & 2)
92344ed0 803 do_compare_rtx_and_jump (res, op0, code == PLUS_EXPR ? LE : GE,
1476d1bd 804 false, mode, NULL_RTX, NULL, done_label,
97286431 805 PROB_VERY_LIKELY);
31e071ae
MP
806 }
807
1304953e 808 do_error_label:
1769415d 809 emit_label (do_error);
1304953e
JJ
810 if (is_ubsan)
811 {
812 /* Expand the ubsan builtin call. */
813 push_temp_slots ();
814 fn = ubsan_build_overflow_builtin (code, loc, TREE_TYPE (arg0),
815 arg0, arg1);
816 expand_normal (fn);
817 pop_temp_slots ();
818 do_pending_stack_adjust ();
819 }
820 else if (lhs)
821 write_complex_part (target, const1_rtx, true);
31e071ae 822
1769415d
MP
823 /* We're done. */
824 emit_label (done_label);
31e071ae
MP
825
826 if (lhs)
1304953e
JJ
827 {
828 if (is_ubsan)
5620052d 829 expand_ubsan_result_store (target, res);
1304953e
JJ
830 else
831 {
832 if (do_xor)
833 res = expand_binop (mode, add_optab, res, sgn, NULL_RTX, false,
834 OPTAB_LIB_WIDEN);
835
836 expand_arith_overflow_result_store (lhs, target, mode, res);
837 }
838 }
31e071ae
MP
839}
840
841/* Add negate overflow checking to the statement STMT. */
842
1304953e
JJ
843static void
844expand_neg_overflow (location_t loc, tree lhs, tree arg1, bool is_ubsan)
31e071ae
MP
845{
846 rtx res, op1;
1304953e 847 tree fn;
da664544
DM
848 rtx_code_label *done_label, *do_error;
849 rtx target = NULL_RTX;
31e071ae 850
31e071ae
MP
851 done_label = gen_label_rtx ();
852 do_error = gen_label_rtx ();
31e071ae
MP
853
854 do_pending_stack_adjust ();
855 op1 = expand_normal (arg1);
856
ef4bddc2 857 machine_mode mode = TYPE_MODE (TREE_TYPE (arg1));
31e071ae 858 if (lhs)
1304953e
JJ
859 {
860 target = expand_expr (lhs, NULL_RTX, VOIDmode, EXPAND_WRITE);
861 if (!is_ubsan)
862 write_complex_part (target, const0_rtx, true);
863 }
31e071ae
MP
864
865 enum insn_code icode = optab_handler (negv3_optab, mode);
866 if (icode != CODE_FOR_nothing)
867 {
868 struct expand_operand ops[3];
da664544 869 rtx_insn *last = get_last_insn ();
31e071ae
MP
870
871 res = gen_reg_rtx (mode);
872 create_output_operand (&ops[0], res, mode);
873 create_input_operand (&ops[1], op1, mode);
874 create_fixed_operand (&ops[2], do_error);
875 if (maybe_expand_insn (icode, 3, ops))
876 {
877 last = get_last_insn ();
0a6a6ac9 878 if (profile_status_for_fn (cfun) != PROFILE_ABSENT
31e071ae
MP
879 && JUMP_P (last)
880 && any_condjump_p (last)
881 && !find_reg_note (last, REG_BR_PROB, 0))
882 add_int_reg_note (last, REG_BR_PROB, PROB_VERY_UNLIKELY);
883 emit_jump (done_label);
884 }
885 else
886 {
887 delete_insns_since (last);
888 icode = CODE_FOR_nothing;
889 }
890 }
891
892 if (icode == CODE_FOR_nothing)
893 {
894 /* Compute the operation. On RTL level, the addition is always
895 unsigned. */
896 res = expand_unop (mode, neg_optab, op1, NULL_RTX, false);
897
898 /* Compare the operand with the most negative value. */
899 rtx minv = expand_normal (TYPE_MIN_VALUE (TREE_TYPE (arg1)));
1476d1bd 900 do_compare_rtx_and_jump (op1, minv, NE, true, mode, NULL_RTX, NULL,
31e071ae
MP
901 done_label, PROB_VERY_LIKELY);
902 }
903
904 emit_label (do_error);
1304953e
JJ
905 if (is_ubsan)
906 {
907 /* Expand the ubsan builtin call. */
908 push_temp_slots ();
909 fn = ubsan_build_overflow_builtin (NEGATE_EXPR, loc, TREE_TYPE (arg1),
910 arg1, NULL_TREE);
911 expand_normal (fn);
912 pop_temp_slots ();
913 do_pending_stack_adjust ();
914 }
915 else if (lhs)
916 write_complex_part (target, const1_rtx, true);
31e071ae
MP
917
918 /* We're done. */
919 emit_label (done_label);
920
921 if (lhs)
1304953e
JJ
922 {
923 if (is_ubsan)
5620052d 924 expand_ubsan_result_store (target, res);
1304953e
JJ
925 else
926 expand_arith_overflow_result_store (lhs, target, mode, res);
927 }
31e071ae
MP
928}
929
930/* Add mul overflow checking to the statement STMT. */
931
1304953e
JJ
932static void
933expand_mul_overflow (location_t loc, tree lhs, tree arg0, tree arg1,
934 bool unsr_p, bool uns0_p, bool uns1_p, bool is_ubsan)
31e071ae
MP
935{
936 rtx res, op0, op1;
1304953e 937 tree fn, type;
da664544
DM
938 rtx_code_label *done_label, *do_error;
939 rtx target = NULL_RTX;
1304953e
JJ
940 signop sign;
941 enum insn_code icode;
31e071ae 942
31e071ae
MP
943 done_label = gen_label_rtx ();
944 do_error = gen_label_rtx ();
31e071ae
MP
945
946 do_pending_stack_adjust ();
947 op0 = expand_normal (arg0);
948 op1 = expand_normal (arg1);
949
ef4bddc2 950 machine_mode mode = TYPE_MODE (TREE_TYPE (arg0));
1304953e 951 bool uns = unsr_p;
31e071ae 952 if (lhs)
1304953e
JJ
953 {
954 target = expand_expr (lhs, NULL_RTX, VOIDmode, EXPAND_WRITE);
955 if (!is_ubsan)
956 write_complex_part (target, const0_rtx, true);
957 }
958
959 if (is_ubsan)
960 gcc_assert (!unsr_p && !uns0_p && !uns1_p);
961
962 /* We assume both operands and result have the same precision
963 here (GET_MODE_BITSIZE (mode)), S stands for signed type
964 with that precision, U for unsigned type with that precision,
965 sgn for unsigned most significant bit in that precision.
966 s1 is signed first operand, u1 is unsigned first operand,
967 s2 is signed second operand, u2 is unsigned second operand,
968 sr is signed result, ur is unsigned result and the following
969 rules say how to compute result (which is always result of
970 the operands as if both were unsigned, cast to the right
971 signedness) and how to compute whether operation overflowed.
972 main_ovf (false) stands for jump on signed multiplication
973 overflow or the main algorithm with uns == false.
974 main_ovf (true) stands for jump on unsigned multiplication
975 overflow or the main algorithm with uns == true.
976
977 s1 * s2 -> sr
978 res = (S) ((U) s1 * (U) s2)
979 ovf = main_ovf (false)
980 u1 * u2 -> ur
981 res = u1 * u2
982 ovf = main_ovf (true)
983 s1 * u2 -> ur
984 res = (U) s1 * u2
985 ovf = (s1 < 0 && u2) || main_ovf (true)
986 u1 * u2 -> sr
987 res = (S) (u1 * u2)
988 ovf = res < 0 || main_ovf (true)
989 s1 * u2 -> sr
990 res = (S) ((U) s1 * u2)
991 ovf = (S) u2 >= 0 ? main_ovf (false)
992 : (s1 != 0 && (s1 != -1 || u2 != (U) res))
993 s1 * s2 -> ur
994 t1 = (s1 & s2) < 0 ? (-(U) s1) : ((U) s1)
995 t2 = (s1 & s2) < 0 ? (-(U) s2) : ((U) s2)
996 res = t1 * t2
997 ovf = (s1 ^ s2) < 0 ? (s1 && s2) : main_ovf (true) */
998
999 if (uns0_p && !uns1_p)
1000 {
1001 /* Multiplication is commutative, if operand signedness differs,
1002 canonicalize to the first operand being signed and second
1003 unsigned to simplify following code. */
6b4db501
MM
1004 std::swap (op0, op1);
1005 std::swap (arg0, arg1);
1006 uns0_p = false;
1007 uns1_p = true;
1304953e
JJ
1008 }
1009
1010 int pos_neg0 = get_range_pos_neg (arg0);
1011 int pos_neg1 = get_range_pos_neg (arg1);
1012
1013 /* s1 * u2 -> ur */
1014 if (!uns0_p && uns1_p && unsr_p)
1015 {
1016 switch (pos_neg0)
1017 {
1018 case 1:
1019 /* If s1 is non-negative, just perform normal u1 * u2 -> ur. */
1020 goto do_main;
1021 case 2:
1022 /* If s1 is negative, avoid the main code, just multiply and
1023 signal overflow if op1 is not 0. */
1024 struct separate_ops ops;
1025 ops.code = MULT_EXPR;
1026 ops.type = TREE_TYPE (arg1);
1027 ops.op0 = make_tree (ops.type, op0);
1028 ops.op1 = make_tree (ops.type, op1);
1029 ops.op2 = NULL_TREE;
1030 ops.location = loc;
1031 res = expand_expr_real_2 (&ops, NULL_RTX, mode, EXPAND_NORMAL);
92344ed0 1032 do_compare_rtx_and_jump (op1, const0_rtx, EQ, true, mode, NULL_RTX,
1476d1bd 1033 NULL, done_label, PROB_VERY_LIKELY);
1304953e
JJ
1034 goto do_error_label;
1035 case 3:
1036 rtx_code_label *do_main_label;
1037 do_main_label = gen_label_rtx ();
92344ed0 1038 do_compare_rtx_and_jump (op0, const0_rtx, GE, false, mode, NULL_RTX,
1476d1bd 1039 NULL, do_main_label, PROB_VERY_LIKELY);
92344ed0 1040 do_compare_rtx_and_jump (op1, const0_rtx, EQ, true, mode, NULL_RTX,
1476d1bd 1041 NULL, do_main_label, PROB_VERY_LIKELY);
1304953e
JJ
1042 write_complex_part (target, const1_rtx, true);
1043 emit_label (do_main_label);
1044 goto do_main;
1045 default:
1046 gcc_unreachable ();
1047 }
1048 }
1049
1050 /* u1 * u2 -> sr */
1051 if (uns0_p && uns1_p && !unsr_p)
1052 {
1053 uns = true;
1054 /* Rest of handling of this case after res is computed. */
1055 goto do_main;
1056 }
1057
1058 /* s1 * u2 -> sr */
1059 if (!uns0_p && uns1_p && !unsr_p)
1060 {
1061 switch (pos_neg1)
1062 {
1063 case 1:
1064 goto do_main;
1065 case 2:
1066 /* If (S) u2 is negative (i.e. u2 is larger than maximum of S,
1067 avoid the main code, just multiply and signal overflow
1068 unless 0 * u2 or -1 * ((U) Smin). */
1069 struct separate_ops ops;
1070 ops.code = MULT_EXPR;
1071 ops.type = TREE_TYPE (arg1);
1072 ops.op0 = make_tree (ops.type, op0);
1073 ops.op1 = make_tree (ops.type, op1);
1074 ops.op2 = NULL_TREE;
1075 ops.location = loc;
1076 res = expand_expr_real_2 (&ops, NULL_RTX, mode, EXPAND_NORMAL);
92344ed0 1077 do_compare_rtx_and_jump (op0, const0_rtx, EQ, true, mode, NULL_RTX,
1476d1bd 1078 NULL, done_label, PROB_VERY_LIKELY);
92344ed0 1079 do_compare_rtx_and_jump (op0, constm1_rtx, NE, true, mode, NULL_RTX,
1476d1bd 1080 NULL, do_error, PROB_VERY_UNLIKELY);
1304953e
JJ
1081 int prec;
1082 prec = GET_MODE_PRECISION (mode);
1083 rtx sgn;
1084 sgn = immed_wide_int_const (wi::min_value (prec, SIGNED), mode);
92344ed0 1085 do_compare_rtx_and_jump (op1, sgn, EQ, true, mode, NULL_RTX,
1476d1bd 1086 NULL, done_label, PROB_VERY_LIKELY);
1304953e
JJ
1087 goto do_error_label;
1088 case 3:
1089 /* Rest of handling of this case after res is computed. */
1090 goto do_main;
1091 default:
1092 gcc_unreachable ();
1093 }
1094 }
31e071ae 1095
1304953e
JJ
1096 /* s1 * s2 -> ur */
1097 if (!uns0_p && !uns1_p && unsr_p)
1098 {
1099 rtx tem, tem2;
1100 switch (pos_neg0 | pos_neg1)
1101 {
1102 case 1: /* Both operands known to be non-negative. */
1103 goto do_main;
1104 case 2: /* Both operands known to be negative. */
1105 op0 = expand_unop (mode, neg_optab, op0, NULL_RTX, false);
1106 op1 = expand_unop (mode, neg_optab, op1, NULL_RTX, false);
1107 /* Avoid looking at arg0/arg1 ranges, as we've changed
1108 the arguments. */
1109 arg0 = error_mark_node;
1110 arg1 = error_mark_node;
1111 goto do_main;
1112 case 3:
1113 if ((pos_neg0 ^ pos_neg1) == 3)
1114 {
1115 /* If one operand is known to be negative and the other
1116 non-negative, this overflows always, unless the non-negative
1117 one is 0. Just do normal multiply and set overflow
1118 unless one of the operands is 0. */
1119 struct separate_ops ops;
1120 ops.code = MULT_EXPR;
1121 ops.type
1122 = build_nonstandard_integer_type (GET_MODE_PRECISION (mode),
1123 1);
1124 ops.op0 = make_tree (ops.type, op0);
1125 ops.op1 = make_tree (ops.type, op1);
1126 ops.op2 = NULL_TREE;
1127 ops.location = loc;
1128 res = expand_expr_real_2 (&ops, NULL_RTX, mode, EXPAND_NORMAL);
1129 tem = expand_binop (mode, and_optab, op0, op1, NULL_RTX, false,
1130 OPTAB_LIB_WIDEN);
92344ed0 1131 do_compare_rtx_and_jump (tem, const0_rtx, EQ, true, mode,
1476d1bd 1132 NULL_RTX, NULL, done_label,
92344ed0 1133 PROB_VERY_LIKELY);
1304953e
JJ
1134 goto do_error_label;
1135 }
1136 /* The general case, do all the needed comparisons at runtime. */
1137 rtx_code_label *do_main_label, *after_negate_label;
1138 rtx rop0, rop1;
1139 rop0 = gen_reg_rtx (mode);
1140 rop1 = gen_reg_rtx (mode);
1141 emit_move_insn (rop0, op0);
1142 emit_move_insn (rop1, op1);
1143 op0 = rop0;
1144 op1 = rop1;
1145 do_main_label = gen_label_rtx ();
1146 after_negate_label = gen_label_rtx ();
1147 tem = expand_binop (mode, and_optab, op0, op1, NULL_RTX, false,
1148 OPTAB_LIB_WIDEN);
92344ed0 1149 do_compare_rtx_and_jump (tem, const0_rtx, GE, false, mode, NULL_RTX,
1476d1bd 1150 NULL, after_negate_label, PROB_VERY_LIKELY);
1304953e
JJ
1151 /* Both arguments negative here, negate them and continue with
1152 normal unsigned overflow checking multiplication. */
1153 emit_move_insn (op0, expand_unop (mode, neg_optab, op0,
1154 NULL_RTX, false));
1155 emit_move_insn (op1, expand_unop (mode, neg_optab, op1,
1156 NULL_RTX, false));
1157 /* Avoid looking at arg0/arg1 ranges, as we might have changed
1158 the arguments. */
1159 arg0 = error_mark_node;
1160 arg1 = error_mark_node;
1161 emit_jump (do_main_label);
1162 emit_label (after_negate_label);
1163 tem2 = expand_binop (mode, xor_optab, op0, op1, NULL_RTX, false,
1164 OPTAB_LIB_WIDEN);
92344ed0 1165 do_compare_rtx_and_jump (tem2, const0_rtx, GE, false, mode, NULL_RTX,
1476d1bd 1166 NULL, do_main_label, PROB_VERY_LIKELY);
1304953e
JJ
1167 /* One argument is negative here, the other positive. This
1168 overflows always, unless one of the arguments is 0. But
1169 if e.g. s2 is 0, (U) s1 * 0 doesn't overflow, whatever s1
1170 is, thus we can keep do_main code oring in overflow as is. */
92344ed0 1171 do_compare_rtx_and_jump (tem, const0_rtx, EQ, true, mode, NULL_RTX,
1476d1bd 1172 NULL, do_main_label, PROB_VERY_LIKELY);
1304953e
JJ
1173 write_complex_part (target, const1_rtx, true);
1174 emit_label (do_main_label);
1175 goto do_main;
1176 default:
1177 gcc_unreachable ();
1178 }
1179 }
1180
1181 do_main:
1182 type = build_nonstandard_integer_type (GET_MODE_PRECISION (mode), uns);
1183 sign = uns ? UNSIGNED : SIGNED;
1184 icode = optab_handler (uns ? umulv4_optab : mulv4_optab, mode);
31e071ae
MP
1185 if (icode != CODE_FOR_nothing)
1186 {
1187 struct expand_operand ops[4];
da664544 1188 rtx_insn *last = get_last_insn ();
31e071ae
MP
1189
1190 res = gen_reg_rtx (mode);
1191 create_output_operand (&ops[0], res, mode);
1192 create_input_operand (&ops[1], op0, mode);
1193 create_input_operand (&ops[2], op1, mode);
1194 create_fixed_operand (&ops[3], do_error);
1195 if (maybe_expand_insn (icode, 4, ops))
1196 {
1197 last = get_last_insn ();
0a6a6ac9 1198 if (profile_status_for_fn (cfun) != PROFILE_ABSENT
31e071ae
MP
1199 && JUMP_P (last)
1200 && any_condjump_p (last)
1201 && !find_reg_note (last, REG_BR_PROB, 0))
1202 add_int_reg_note (last, REG_BR_PROB, PROB_VERY_UNLIKELY);
1203 emit_jump (done_label);
1204 }
1205 else
1206 {
1207 delete_insns_since (last);
1208 icode = CODE_FOR_nothing;
1209 }
1210 }
1211
1212 if (icode == CODE_FOR_nothing)
1213 {
1214 struct separate_ops ops;
1304953e
JJ
1215 int prec = GET_MODE_PRECISION (mode);
1216 machine_mode hmode = mode_for_size (prec / 2, MODE_INT, 1);
1217 ops.op0 = make_tree (type, op0);
1218 ops.op1 = make_tree (type, op1);
31e071ae 1219 ops.op2 = NULL_TREE;
1304953e 1220 ops.location = loc;
31e071ae
MP
1221 if (GET_MODE_2XWIDER_MODE (mode) != VOIDmode
1222 && targetm.scalar_mode_supported_p (GET_MODE_2XWIDER_MODE (mode)))
1223 {
ef4bddc2 1224 machine_mode wmode = GET_MODE_2XWIDER_MODE (mode);
31e071ae
MP
1225 ops.code = WIDEN_MULT_EXPR;
1226 ops.type
1304953e 1227 = build_nonstandard_integer_type (GET_MODE_PRECISION (wmode), uns);
31e071ae
MP
1228
1229 res = expand_expr_real_2 (&ops, NULL_RTX, wmode, EXPAND_NORMAL);
1304953e
JJ
1230 rtx hipart = expand_shift (RSHIFT_EXPR, wmode, res, prec,
1231 NULL_RTX, uns);
31e071ae
MP
1232 hipart = gen_lowpart (mode, hipart);
1233 res = gen_lowpart (mode, res);
1304953e
JJ
1234 if (uns)
1235 /* For the unsigned multiplication, there was overflow if
1236 HIPART is non-zero. */
92344ed0 1237 do_compare_rtx_and_jump (hipart, const0_rtx, EQ, true, mode,
1476d1bd 1238 NULL_RTX, NULL, done_label,
92344ed0 1239 PROB_VERY_LIKELY);
1304953e
JJ
1240 else
1241 {
1242 rtx signbit = expand_shift (RSHIFT_EXPR, mode, res, prec - 1,
1243 NULL_RTX, 0);
1244 /* RES is low half of the double width result, HIPART
1245 the high half. There was overflow if
1246 HIPART is different from RES < 0 ? -1 : 0. */
92344ed0 1247 do_compare_rtx_and_jump (signbit, hipart, EQ, true, mode,
1476d1bd 1248 NULL_RTX, NULL, done_label,
92344ed0 1249 PROB_VERY_LIKELY);
1304953e 1250 }
31e071ae 1251 }
1304953e 1252 else if (hmode != BLKmode && 2 * GET_MODE_PRECISION (hmode) == prec)
d5fa9cc9 1253 {
da664544
DM
1254 rtx_code_label *large_op0 = gen_label_rtx ();
1255 rtx_code_label *small_op0_large_op1 = gen_label_rtx ();
1256 rtx_code_label *one_small_one_large = gen_label_rtx ();
1257 rtx_code_label *both_ops_large = gen_label_rtx ();
1304953e
JJ
1258 rtx_code_label *after_hipart_neg = uns ? NULL : gen_label_rtx ();
1259 rtx_code_label *after_lopart_neg = uns ? NULL : gen_label_rtx ();
da664544 1260 rtx_code_label *do_overflow = gen_label_rtx ();
1304953e 1261 rtx_code_label *hipart_different = uns ? NULL : gen_label_rtx ();
d5fa9cc9 1262
807e902e 1263 unsigned int hprec = GET_MODE_PRECISION (hmode);
d5fa9cc9 1264 rtx hipart0 = expand_shift (RSHIFT_EXPR, mode, op0, hprec,
1304953e 1265 NULL_RTX, uns);
d5fa9cc9
JJ
1266 hipart0 = gen_lowpart (hmode, hipart0);
1267 rtx lopart0 = gen_lowpart (hmode, op0);
1304953e
JJ
1268 rtx signbit0 = const0_rtx;
1269 if (!uns)
1270 signbit0 = expand_shift (RSHIFT_EXPR, hmode, lopart0, hprec - 1,
1271 NULL_RTX, 0);
d5fa9cc9 1272 rtx hipart1 = expand_shift (RSHIFT_EXPR, mode, op1, hprec,
1304953e 1273 NULL_RTX, uns);
d5fa9cc9
JJ
1274 hipart1 = gen_lowpart (hmode, hipart1);
1275 rtx lopart1 = gen_lowpart (hmode, op1);
1304953e
JJ
1276 rtx signbit1 = const0_rtx;
1277 if (!uns)
1278 signbit1 = expand_shift (RSHIFT_EXPR, hmode, lopart1, hprec - 1,
1279 NULL_RTX, 0);
d5fa9cc9
JJ
1280
1281 res = gen_reg_rtx (mode);
1282
1283 /* True if op0 resp. op1 are known to be in the range of
1284 halfstype. */
1285 bool op0_small_p = false;
1286 bool op1_small_p = false;
1287 /* True if op0 resp. op1 are known to have all zeros or all ones
1288 in the upper half of bits, but are not known to be
1289 op{0,1}_small_p. */
1290 bool op0_medium_p = false;
1291 bool op1_medium_p = false;
1292 /* -1 if op{0,1} is known to be negative, 0 if it is known to be
1293 nonnegative, 1 if unknown. */
1294 int op0_sign = 1;
1295 int op1_sign = 1;
1296
1304953e
JJ
1297 if (pos_neg0 == 1)
1298 op0_sign = 0;
1299 else if (pos_neg0 == 2)
1300 op0_sign = -1;
1301 if (pos_neg1 == 1)
1302 op1_sign = 0;
1303 else if (pos_neg1 == 2)
1304 op1_sign = -1;
1305
1306 unsigned int mprec0 = prec;
1307 if (arg0 != error_mark_node)
1308 mprec0 = get_min_precision (arg0, sign);
1309 if (mprec0 <= hprec)
1310 op0_small_p = true;
1311 else if (!uns && mprec0 <= hprec + 1)
1312 op0_medium_p = true;
1313 unsigned int mprec1 = prec;
1314 if (arg1 != error_mark_node)
1315 mprec1 = get_min_precision (arg1, sign);
1316 if (mprec1 <= hprec)
1317 op1_small_p = true;
1318 else if (!uns && mprec1 <= hprec + 1)
1319 op1_medium_p = true;
d5fa9cc9
JJ
1320
1321 int smaller_sign = 1;
1322 int larger_sign = 1;
1323 if (op0_small_p)
1324 {
1325 smaller_sign = op0_sign;
1326 larger_sign = op1_sign;
1327 }
1328 else if (op1_small_p)
1329 {
1330 smaller_sign = op1_sign;
1331 larger_sign = op0_sign;
1332 }
1333 else if (op0_sign == op1_sign)
1334 {
1335 smaller_sign = op0_sign;
1336 larger_sign = op0_sign;
1337 }
1338
1339 if (!op0_small_p)
92344ed0 1340 do_compare_rtx_and_jump (signbit0, hipart0, NE, true, hmode,
1476d1bd 1341 NULL_RTX, NULL, large_op0,
92344ed0 1342 PROB_UNLIKELY);
d5fa9cc9
JJ
1343
1344 if (!op1_small_p)
92344ed0 1345 do_compare_rtx_and_jump (signbit1, hipart1, NE, true, hmode,
1476d1bd 1346 NULL_RTX, NULL, small_op0_large_op1,
d5fa9cc9
JJ
1347 PROB_UNLIKELY);
1348
1304953e
JJ
1349 /* If both op0 and op1 are sign (!uns) or zero (uns) extended from
1350 hmode to mode, the multiplication will never overflow. We can
1351 do just one hmode x hmode => mode widening multiplication. */
1352 rtx lopart0s = lopart0, lopart1s = lopart1;
d5fa9cc9
JJ
1353 if (GET_CODE (lopart0) == SUBREG)
1354 {
1304953e
JJ
1355 lopart0s = shallow_copy_rtx (lopart0);
1356 SUBREG_PROMOTED_VAR_P (lopart0s) = 1;
1357 SUBREG_PROMOTED_SET (lopart0s, uns ? SRP_UNSIGNED : SRP_SIGNED);
d5fa9cc9
JJ
1358 }
1359 if (GET_CODE (lopart1) == SUBREG)
1360 {
1304953e
JJ
1361 lopart1s = shallow_copy_rtx (lopart1);
1362 SUBREG_PROMOTED_VAR_P (lopart1s) = 1;
1363 SUBREG_PROMOTED_SET (lopart1s, uns ? SRP_UNSIGNED : SRP_SIGNED);
d5fa9cc9 1364 }
1304953e
JJ
1365 tree halfstype = build_nonstandard_integer_type (hprec, uns);
1366 ops.op0 = make_tree (halfstype, lopart0s);
1367 ops.op1 = make_tree (halfstype, lopart1s);
d5fa9cc9 1368 ops.code = WIDEN_MULT_EXPR;
1304953e 1369 ops.type = type;
d5fa9cc9
JJ
1370 rtx thisres
1371 = expand_expr_real_2 (&ops, NULL_RTX, mode, EXPAND_NORMAL);
1372 emit_move_insn (res, thisres);
1373 emit_jump (done_label);
1374
1375 emit_label (small_op0_large_op1);
1376
1304953e
JJ
1377 /* If op0 is sign (!uns) or zero (uns) extended from hmode to mode,
1378 but op1 is not, just swap the arguments and handle it as op1
1379 sign/zero extended, op0 not. */
d5fa9cc9
JJ
1380 rtx larger = gen_reg_rtx (mode);
1381 rtx hipart = gen_reg_rtx (hmode);
1382 rtx lopart = gen_reg_rtx (hmode);
1383 emit_move_insn (larger, op1);
1384 emit_move_insn (hipart, hipart1);
1385 emit_move_insn (lopart, lopart0);
1386 emit_jump (one_small_one_large);
1387
1388 emit_label (large_op0);
1389
1390 if (!op1_small_p)
92344ed0 1391 do_compare_rtx_and_jump (signbit1, hipart1, NE, true, hmode,
1476d1bd 1392 NULL_RTX, NULL, both_ops_large,
92344ed0 1393 PROB_UNLIKELY);
d5fa9cc9 1394
1304953e
JJ
1395 /* If op1 is sign (!uns) or zero (uns) extended from hmode to mode,
1396 but op0 is not, prepare larger, hipart and lopart pseudos and
1397 handle it together with small_op0_large_op1. */
d5fa9cc9
JJ
1398 emit_move_insn (larger, op0);
1399 emit_move_insn (hipart, hipart0);
1400 emit_move_insn (lopart, lopart1);
1401
1402 emit_label (one_small_one_large);
1403
1404 /* lopart is the low part of the operand that is sign extended
026c3cfd 1405 to mode, larger is the other operand, hipart is the
d5fa9cc9
JJ
1406 high part of larger and lopart0 and lopart1 are the low parts
1407 of both operands.
1408 We perform lopart0 * lopart1 and lopart * hipart widening
1409 multiplications. */
1410 tree halfutype = build_nonstandard_integer_type (hprec, 1);
1411 ops.op0 = make_tree (halfutype, lopart0);
1412 ops.op1 = make_tree (halfutype, lopart1);
1413 rtx lo0xlo1
1414 = expand_expr_real_2 (&ops, NULL_RTX, mode, EXPAND_NORMAL);
1415
1416 ops.op0 = make_tree (halfutype, lopart);
1417 ops.op1 = make_tree (halfutype, hipart);
1418 rtx loxhi = gen_reg_rtx (mode);
1419 rtx tem = expand_expr_real_2 (&ops, NULL_RTX, mode, EXPAND_NORMAL);
1420 emit_move_insn (loxhi, tem);
1421
1304953e
JJ
1422 if (!uns)
1423 {
1424 /* if (hipart < 0) loxhi -= lopart << (bitsize / 2); */
1425 if (larger_sign == 0)
1426 emit_jump (after_hipart_neg);
1427 else if (larger_sign != -1)
92344ed0 1428 do_compare_rtx_and_jump (hipart, const0_rtx, GE, false, hmode,
1476d1bd 1429 NULL_RTX, NULL, after_hipart_neg,
1304953e
JJ
1430 PROB_EVEN);
1431
1432 tem = convert_modes (mode, hmode, lopart, 1);
1433 tem = expand_shift (LSHIFT_EXPR, mode, tem, hprec, NULL_RTX, 1);
1434 tem = expand_simple_binop (mode, MINUS, loxhi, tem, NULL_RTX,
1435 1, OPTAB_DIRECT);
1436 emit_move_insn (loxhi, tem);
1437
1438 emit_label (after_hipart_neg);
1439
1440 /* if (lopart < 0) loxhi -= larger; */
1441 if (smaller_sign == 0)
1442 emit_jump (after_lopart_neg);
1443 else if (smaller_sign != -1)
92344ed0 1444 do_compare_rtx_and_jump (lopart, const0_rtx, GE, false, hmode,
1476d1bd 1445 NULL_RTX, NULL, after_lopart_neg,
1304953e
JJ
1446 PROB_EVEN);
1447
1448 tem = expand_simple_binop (mode, MINUS, loxhi, larger, NULL_RTX,
1449 1, OPTAB_DIRECT);
1450 emit_move_insn (loxhi, tem);
1451
1452 emit_label (after_lopart_neg);
1453 }
d5fa9cc9
JJ
1454
1455 /* loxhi += (uns) lo0xlo1 >> (bitsize / 2); */
1456 tem = expand_shift (RSHIFT_EXPR, mode, lo0xlo1, hprec, NULL_RTX, 1);
1457 tem = expand_simple_binop (mode, PLUS, loxhi, tem, NULL_RTX,
1458 1, OPTAB_DIRECT);
1459 emit_move_insn (loxhi, tem);
1460
1461 /* if (loxhi >> (bitsize / 2)
1304953e
JJ
1462 == (hmode) loxhi >> (bitsize / 2 - 1)) (if !uns)
1463 if (loxhi >> (bitsize / 2) == 0 (if uns). */
d5fa9cc9
JJ
1464 rtx hipartloxhi = expand_shift (RSHIFT_EXPR, mode, loxhi, hprec,
1465 NULL_RTX, 0);
1466 hipartloxhi = gen_lowpart (hmode, hipartloxhi);
1304953e
JJ
1467 rtx signbitloxhi = const0_rtx;
1468 if (!uns)
1469 signbitloxhi = expand_shift (RSHIFT_EXPR, hmode,
1470 gen_lowpart (hmode, loxhi),
1471 hprec - 1, NULL_RTX, 0);
d5fa9cc9 1472
92344ed0 1473 do_compare_rtx_and_jump (signbitloxhi, hipartloxhi, NE, true, hmode,
1476d1bd 1474 NULL_RTX, NULL, do_overflow,
d5fa9cc9
JJ
1475 PROB_VERY_UNLIKELY);
1476
1477 /* res = (loxhi << (bitsize / 2)) | (hmode) lo0xlo1; */
1478 rtx loxhishifted = expand_shift (LSHIFT_EXPR, mode, loxhi, hprec,
1479 NULL_RTX, 1);
1480 tem = convert_modes (mode, hmode, gen_lowpart (hmode, lo0xlo1), 1);
1481
1482 tem = expand_simple_binop (mode, IOR, loxhishifted, tem, res,
1483 1, OPTAB_DIRECT);
1484 if (tem != res)
1485 emit_move_insn (res, tem);
1486 emit_jump (done_label);
1487
1488 emit_label (both_ops_large);
1489
1304953e
JJ
1490 /* If both operands are large (not sign (!uns) or zero (uns)
1491 extended from hmode), then perform the full multiplication
1492 which will be the result of the operation.
1493 The only cases which don't overflow are for signed multiplication
1494 some cases where both hipart0 and highpart1 are 0 or -1.
1495 For unsigned multiplication when high parts are both non-zero
1496 this overflows always. */
d5fa9cc9 1497 ops.code = MULT_EXPR;
1304953e
JJ
1498 ops.op0 = make_tree (type, op0);
1499 ops.op1 = make_tree (type, op1);
d5fa9cc9
JJ
1500 tem = expand_expr_real_2 (&ops, NULL_RTX, mode, EXPAND_NORMAL);
1501 emit_move_insn (res, tem);
1502
1304953e 1503 if (!uns)
d5fa9cc9 1504 {
1304953e
JJ
1505 if (!op0_medium_p)
1506 {
1507 tem = expand_simple_binop (hmode, PLUS, hipart0, const1_rtx,
1508 NULL_RTX, 1, OPTAB_DIRECT);
92344ed0 1509 do_compare_rtx_and_jump (tem, const1_rtx, GTU, true, hmode,
1476d1bd 1510 NULL_RTX, NULL, do_error,
1304953e
JJ
1511 PROB_VERY_UNLIKELY);
1512 }
d5fa9cc9 1513
1304953e
JJ
1514 if (!op1_medium_p)
1515 {
1516 tem = expand_simple_binop (hmode, PLUS, hipart1, const1_rtx,
1517 NULL_RTX, 1, OPTAB_DIRECT);
92344ed0 1518 do_compare_rtx_and_jump (tem, const1_rtx, GTU, true, hmode,
1476d1bd 1519 NULL_RTX, NULL, do_error,
1304953e
JJ
1520 PROB_VERY_UNLIKELY);
1521 }
d5fa9cc9 1522
1304953e
JJ
1523 /* At this point hipart{0,1} are both in [-1, 0]. If they are
1524 the same, overflow happened if res is negative, if they are
1525 different, overflow happened if res is positive. */
1526 if (op0_sign != 1 && op1_sign != 1 && op0_sign != op1_sign)
1527 emit_jump (hipart_different);
1528 else if (op0_sign == 1 || op1_sign == 1)
92344ed0 1529 do_compare_rtx_and_jump (hipart0, hipart1, NE, true, hmode,
1476d1bd 1530 NULL_RTX, NULL, hipart_different,
92344ed0 1531 PROB_EVEN);
d5fa9cc9 1532
92344ed0 1533 do_compare_rtx_and_jump (res, const0_rtx, LT, false, mode,
1476d1bd 1534 NULL_RTX, NULL, do_error,
92344ed0 1535 PROB_VERY_UNLIKELY);
1304953e 1536 emit_jump (done_label);
d5fa9cc9 1537
1304953e
JJ
1538 emit_label (hipart_different);
1539
92344ed0 1540 do_compare_rtx_and_jump (res, const0_rtx, GE, false, mode,
1476d1bd 1541 NULL_RTX, NULL, do_error,
92344ed0 1542 PROB_VERY_UNLIKELY);
1304953e
JJ
1543 emit_jump (done_label);
1544 }
d5fa9cc9
JJ
1545
1546 emit_label (do_overflow);
1547
1548 /* Overflow, do full multiplication and fallthru into do_error. */
1304953e
JJ
1549 ops.op0 = make_tree (type, op0);
1550 ops.op1 = make_tree (type, op1);
d5fa9cc9
JJ
1551 tem = expand_expr_real_2 (&ops, NULL_RTX, mode, EXPAND_NORMAL);
1552 emit_move_insn (res, tem);
1553 }
31e071ae
MP
1554 else
1555 {
1304953e 1556 gcc_assert (!is_ubsan);
31e071ae 1557 ops.code = MULT_EXPR;
1304953e 1558 ops.type = type;
31e071ae
MP
1559 res = expand_expr_real_2 (&ops, NULL_RTX, mode, EXPAND_NORMAL);
1560 emit_jump (done_label);
1561 }
1562 }
1563
1304953e 1564 do_error_label:
31e071ae 1565 emit_label (do_error);
1304953e
JJ
1566 if (is_ubsan)
1567 {
1568 /* Expand the ubsan builtin call. */
1569 push_temp_slots ();
1570 fn = ubsan_build_overflow_builtin (MULT_EXPR, loc, TREE_TYPE (arg0),
1571 arg0, arg1);
1572 expand_normal (fn);
1573 pop_temp_slots ();
1574 do_pending_stack_adjust ();
1575 }
1576 else if (lhs)
1577 write_complex_part (target, const1_rtx, true);
31e071ae
MP
1578
1579 /* We're done. */
1580 emit_label (done_label);
1581
1304953e
JJ
1582 /* u1 * u2 -> sr */
1583 if (uns0_p && uns1_p && !unsr_p)
1584 {
1585 rtx_code_label *all_done_label = gen_label_rtx ();
92344ed0 1586 do_compare_rtx_and_jump (res, const0_rtx, GE, false, mode, NULL_RTX,
1476d1bd 1587 NULL, all_done_label, PROB_VERY_LIKELY);
1304953e
JJ
1588 write_complex_part (target, const1_rtx, true);
1589 emit_label (all_done_label);
1590 }
1591
1592 /* s1 * u2 -> sr */
1593 if (!uns0_p && uns1_p && !unsr_p && pos_neg1 == 3)
1594 {
1595 rtx_code_label *all_done_label = gen_label_rtx ();
1596 rtx_code_label *set_noovf = gen_label_rtx ();
92344ed0 1597 do_compare_rtx_and_jump (op1, const0_rtx, GE, false, mode, NULL_RTX,
1476d1bd 1598 NULL, all_done_label, PROB_VERY_LIKELY);
1304953e 1599 write_complex_part (target, const1_rtx, true);
92344ed0 1600 do_compare_rtx_and_jump (op0, const0_rtx, EQ, true, mode, NULL_RTX,
1476d1bd 1601 NULL, set_noovf, PROB_VERY_LIKELY);
92344ed0 1602 do_compare_rtx_and_jump (op0, constm1_rtx, NE, true, mode, NULL_RTX,
1476d1bd
MM
1603 NULL, all_done_label, PROB_VERY_UNLIKELY);
1604 do_compare_rtx_and_jump (op1, res, NE, true, mode, NULL_RTX, NULL,
92344ed0 1605 all_done_label, PROB_VERY_UNLIKELY);
1304953e
JJ
1606 emit_label (set_noovf);
1607 write_complex_part (target, const0_rtx, true);
1608 emit_label (all_done_label);
1609 }
1610
31e071ae 1611 if (lhs)
1304953e
JJ
1612 {
1613 if (is_ubsan)
5620052d 1614 expand_ubsan_result_store (target, res);
1304953e
JJ
1615 else
1616 expand_arith_overflow_result_store (lhs, target, mode, res);
1617 }
31e071ae
MP
1618}
1619
1620/* Expand UBSAN_CHECK_ADD call STMT. */
1621
1622static void
538dd0b7 1623expand_UBSAN_CHECK_ADD (gcall *stmt)
31e071ae 1624{
1304953e
JJ
1625 location_t loc = gimple_location (stmt);
1626 tree lhs = gimple_call_lhs (stmt);
1627 tree arg0 = gimple_call_arg (stmt, 0);
1628 tree arg1 = gimple_call_arg (stmt, 1);
1629 expand_addsub_overflow (loc, PLUS_EXPR, lhs, arg0, arg1,
1630 false, false, false, true);
31e071ae
MP
1631}
1632
1633/* Expand UBSAN_CHECK_SUB call STMT. */
1634
1635static void
538dd0b7 1636expand_UBSAN_CHECK_SUB (gcall *stmt)
31e071ae 1637{
1304953e
JJ
1638 location_t loc = gimple_location (stmt);
1639 tree lhs = gimple_call_lhs (stmt);
1640 tree arg0 = gimple_call_arg (stmt, 0);
1641 tree arg1 = gimple_call_arg (stmt, 1);
1642 if (integer_zerop (arg0))
1643 expand_neg_overflow (loc, lhs, arg1, true);
31e071ae 1644 else
1304953e
JJ
1645 expand_addsub_overflow (loc, MINUS_EXPR, lhs, arg0, arg1,
1646 false, false, false, true);
31e071ae
MP
1647}
1648
1649/* Expand UBSAN_CHECK_MUL call STMT. */
1650
1651static void
538dd0b7 1652expand_UBSAN_CHECK_MUL (gcall *stmt)
31e071ae 1653{
1304953e
JJ
1654 location_t loc = gimple_location (stmt);
1655 tree lhs = gimple_call_lhs (stmt);
1656 tree arg0 = gimple_call_arg (stmt, 0);
1657 tree arg1 = gimple_call_arg (stmt, 1);
1658 expand_mul_overflow (loc, lhs, arg0, arg1, false, false, false, true);
1659}
1660
1661/* Helper function for {ADD,SUB,MUL}_OVERFLOW call stmt expansion. */
1662
1663static void
1664expand_arith_overflow (enum tree_code code, gimple stmt)
1665{
1666 tree lhs = gimple_call_lhs (stmt);
1667 if (lhs == NULL_TREE)
1668 return;
1669 tree arg0 = gimple_call_arg (stmt, 0);
1670 tree arg1 = gimple_call_arg (stmt, 1);
1671 tree type = TREE_TYPE (TREE_TYPE (lhs));
1672 int uns0_p = TYPE_UNSIGNED (TREE_TYPE (arg0));
1673 int uns1_p = TYPE_UNSIGNED (TREE_TYPE (arg1));
1674 int unsr_p = TYPE_UNSIGNED (type);
1675 int prec0 = TYPE_PRECISION (TREE_TYPE (arg0));
1676 int prec1 = TYPE_PRECISION (TREE_TYPE (arg1));
1677 int precres = TYPE_PRECISION (type);
1678 location_t loc = gimple_location (stmt);
1679 if (!uns0_p && get_range_pos_neg (arg0) == 1)
1680 uns0_p = true;
1681 if (!uns1_p && get_range_pos_neg (arg1) == 1)
1682 uns1_p = true;
1683 int pr = get_min_precision (arg0, uns0_p ? UNSIGNED : SIGNED);
1684 prec0 = MIN (prec0, pr);
1685 pr = get_min_precision (arg1, uns1_p ? UNSIGNED : SIGNED);
1686 prec1 = MIN (prec1, pr);
1687
1688 /* If uns0_p && uns1_p, precop is minimum needed precision
1689 of unsigned type to hold the exact result, otherwise
1690 precop is minimum needed precision of signed type to
1691 hold the exact result. */
1692 int precop;
1693 if (code == MULT_EXPR)
1694 precop = prec0 + prec1 + (uns0_p != uns1_p);
1695 else
1696 {
1697 if (uns0_p == uns1_p)
1698 precop = MAX (prec0, prec1) + 1;
1699 else if (uns0_p)
1700 precop = MAX (prec0 + 1, prec1) + 1;
1701 else
1702 precop = MAX (prec0, prec1 + 1) + 1;
1703 }
1704 int orig_precres = precres;
1705
1706 do
1707 {
1708 if ((uns0_p && uns1_p)
1709 ? ((precop + !unsr_p) <= precres
1710 /* u1 - u2 -> ur can overflow, no matter what precision
1711 the result has. */
1712 && (code != MINUS_EXPR || !unsr_p))
1713 : (!unsr_p && precop <= precres))
1714 {
1715 /* The infinity precision result will always fit into result. */
1716 rtx target = expand_expr (lhs, NULL_RTX, VOIDmode, EXPAND_WRITE);
1717 write_complex_part (target, const0_rtx, true);
1718 enum machine_mode mode = TYPE_MODE (type);
1719 struct separate_ops ops;
1720 ops.code = code;
1721 ops.type = type;
1722 ops.op0 = fold_convert_loc (loc, type, arg0);
1723 ops.op1 = fold_convert_loc (loc, type, arg1);
1724 ops.op2 = NULL_TREE;
1725 ops.location = loc;
1726 rtx tem = expand_expr_real_2 (&ops, NULL_RTX, mode, EXPAND_NORMAL);
1727 expand_arith_overflow_result_store (lhs, target, mode, tem);
1728 return;
1729 }
1730
1304953e
JJ
1731 /* For sub-word operations, if target doesn't have them, start
1732 with precres widening right away, otherwise do it only
1733 if the most simple cases can't be used. */
9e11bfef
TS
1734 if (WORD_REGISTER_OPERATIONS
1735 && orig_precres == precres
1736 && precres < BITS_PER_WORD)
1304953e 1737 ;
9e11bfef
TS
1738 else if ((uns0_p && uns1_p && unsr_p && prec0 <= precres
1739 && prec1 <= precres)
1304953e
JJ
1740 || ((!uns0_p || !uns1_p) && !unsr_p
1741 && prec0 + uns0_p <= precres
1742 && prec1 + uns1_p <= precres))
1743 {
1744 arg0 = fold_convert_loc (loc, type, arg0);
1745 arg1 = fold_convert_loc (loc, type, arg1);
1746 switch (code)
1747 {
1748 case MINUS_EXPR:
1749 if (integer_zerop (arg0) && !unsr_p)
1750 expand_neg_overflow (loc, lhs, arg1, false);
1751 /* FALLTHRU */
1752 case PLUS_EXPR:
1753 expand_addsub_overflow (loc, code, lhs, arg0, arg1,
1754 unsr_p, unsr_p, unsr_p, false);
1755 return;
1756 case MULT_EXPR:
1757 expand_mul_overflow (loc, lhs, arg0, arg1,
1758 unsr_p, unsr_p, unsr_p, false);
1759 return;
1760 default:
1761 gcc_unreachable ();
1762 }
1763 }
1764
1765 /* For sub-word operations, retry with a wider type first. */
1766 if (orig_precres == precres && precop <= BITS_PER_WORD)
1767 {
9e11bfef 1768#if WORD_REGISTER_OPERATIONS
1304953e
JJ
1769 int p = BITS_PER_WORD;
1770#else
1771 int p = precop;
1772#endif
1773 enum machine_mode m = smallest_mode_for_size (p, MODE_INT);
1774 tree optype = build_nonstandard_integer_type (GET_MODE_PRECISION (m),
1775 uns0_p && uns1_p
1776 && unsr_p);
1777 p = TYPE_PRECISION (optype);
1778 if (p > precres)
1779 {
1780 precres = p;
1781 unsr_p = TYPE_UNSIGNED (optype);
1782 type = optype;
1783 continue;
1784 }
1785 }
1786
1787 if (prec0 <= precres && prec1 <= precres)
1788 {
1789 tree types[2];
1790 if (unsr_p)
1791 {
1792 types[0] = build_nonstandard_integer_type (precres, 0);
1793 types[1] = type;
1794 }
1795 else
1796 {
1797 types[0] = type;
1798 types[1] = build_nonstandard_integer_type (precres, 1);
1799 }
1800 arg0 = fold_convert_loc (loc, types[uns0_p], arg0);
1801 arg1 = fold_convert_loc (loc, types[uns1_p], arg1);
1802 if (code != MULT_EXPR)
1803 expand_addsub_overflow (loc, code, lhs, arg0, arg1, unsr_p,
1804 uns0_p, uns1_p, false);
1805 else
1806 expand_mul_overflow (loc, lhs, arg0, arg1, unsr_p,
1807 uns0_p, uns1_p, false);
1808 return;
1809 }
1810
1811 /* Retry with a wider type. */
1812 if (orig_precres == precres)
1813 {
1814 int p = MAX (prec0, prec1);
1815 enum machine_mode m = smallest_mode_for_size (p, MODE_INT);
1816 tree optype = build_nonstandard_integer_type (GET_MODE_PRECISION (m),
1817 uns0_p && uns1_p
1818 && unsr_p);
1819 p = TYPE_PRECISION (optype);
1820 if (p > precres)
1821 {
1822 precres = p;
1823 unsr_p = TYPE_UNSIGNED (optype);
1824 type = optype;
1825 continue;
1826 }
1827 }
1828
1829 gcc_unreachable ();
1830 }
1831 while (1);
1832}
1833
1834/* Expand ADD_OVERFLOW STMT. */
1835
1836static void
538dd0b7 1837expand_ADD_OVERFLOW (gcall *stmt)
1304953e
JJ
1838{
1839 expand_arith_overflow (PLUS_EXPR, stmt);
1840}
1841
1842/* Expand SUB_OVERFLOW STMT. */
1843
1844static void
538dd0b7 1845expand_SUB_OVERFLOW (gcall *stmt)
1304953e
JJ
1846{
1847 expand_arith_overflow (MINUS_EXPR, stmt);
1848}
1849
1850/* Expand MUL_OVERFLOW STMT. */
1851
1852static void
538dd0b7 1853expand_MUL_OVERFLOW (gcall *stmt)
1304953e
JJ
1854{
1855 expand_arith_overflow (MULT_EXPR, stmt);
31e071ae
MP
1856}
1857
5ce9450f
JJ
1858/* This should get folded in tree-vectorizer.c. */
1859
1860static void
35228ac7 1861expand_LOOP_VECTORIZED (gcall *)
5ce9450f
JJ
1862{
1863 gcc_unreachable ();
1864}
1865
1866static void
538dd0b7 1867expand_MASK_LOAD (gcall *stmt)
5ce9450f
JJ
1868{
1869 struct expand_operand ops[3];
1870 tree type, lhs, rhs, maskt;
1871 rtx mem, target, mask;
1872
1873 maskt = gimple_call_arg (stmt, 2);
1874 lhs = gimple_call_lhs (stmt);
8e91d222
JJ
1875 if (lhs == NULL_TREE)
1876 return;
5ce9450f
JJ
1877 type = TREE_TYPE (lhs);
1878 rhs = fold_build2 (MEM_REF, type, gimple_call_arg (stmt, 0),
1879 gimple_call_arg (stmt, 1));
1880
1881 mem = expand_expr (rhs, NULL_RTX, VOIDmode, EXPAND_WRITE);
1882 gcc_assert (MEM_P (mem));
1883 mask = expand_normal (maskt);
1884 target = expand_expr (lhs, NULL_RTX, VOIDmode, EXPAND_WRITE);
1885 create_output_operand (&ops[0], target, TYPE_MODE (type));
1886 create_fixed_operand (&ops[1], mem);
1887 create_input_operand (&ops[2], mask, TYPE_MODE (TREE_TYPE (maskt)));
1888 expand_insn (optab_handler (maskload_optab, TYPE_MODE (type)), 3, ops);
1889}
1890
1891static void
538dd0b7 1892expand_MASK_STORE (gcall *stmt)
5ce9450f
JJ
1893{
1894 struct expand_operand ops[3];
1895 tree type, lhs, rhs, maskt;
1896 rtx mem, reg, mask;
1897
1898 maskt = gimple_call_arg (stmt, 2);
1899 rhs = gimple_call_arg (stmt, 3);
1900 type = TREE_TYPE (rhs);
1901 lhs = fold_build2 (MEM_REF, type, gimple_call_arg (stmt, 0),
1902 gimple_call_arg (stmt, 1));
1903
1904 mem = expand_expr (lhs, NULL_RTX, VOIDmode, EXPAND_WRITE);
1905 gcc_assert (MEM_P (mem));
1906 mask = expand_normal (maskt);
1907 reg = expand_normal (rhs);
1908 create_fixed_operand (&ops[0], mem);
1909 create_input_operand (&ops[1], reg, TYPE_MODE (type));
1910 create_input_operand (&ops[2], mask, TYPE_MODE (TREE_TYPE (maskt)));
1911 expand_insn (optab_handler (maskstore_optab, TYPE_MODE (type)), 3, ops);
1912}
1913
09b22f48 1914static void
538dd0b7 1915expand_ABNORMAL_DISPATCHER (gcall *)
09b22f48
JJ
1916{
1917}
1918
ed9c79e1 1919static void
538dd0b7 1920expand_BUILTIN_EXPECT (gcall *stmt)
ed9c79e1
JJ
1921{
1922 /* When guessing was done, the hints should be already stripped away. */
1923 gcc_assert (!flag_guess_branch_prob || optimize == 0 || seen_error ());
1924
1925 rtx target;
1926 tree lhs = gimple_call_lhs (stmt);
1927 if (lhs)
1928 target = expand_expr (lhs, NULL_RTX, VOIDmode, EXPAND_WRITE);
1929 else
1930 target = const0_rtx;
1931 rtx val = expand_expr (gimple_call_arg (stmt, 0), target, VOIDmode, EXPAND_NORMAL);
1932 if (lhs && val != target)
1933 emit_move_insn (target, val);
1934}
1935
f8e89441
TV
1936/* IFN_VA_ARG is supposed to be expanded at pass_stdarg. So this dummy function
1937 should never be called. */
1938
1939static void
1940expand_VA_ARG (gcall *stmt ATTRIBUTE_UNUSED)
1941{
1942 gcc_unreachable ();
1943}
1944
25583c4f
RS
1945/* Routines to expand each internal function, indexed by function number.
1946 Each routine has the prototype:
1947
538dd0b7 1948 expand_<NAME> (gcall *stmt)
25583c4f
RS
1949
1950 where STMT is the statement that performs the call. */
538dd0b7 1951static void (*const internal_fn_expanders[]) (gcall *) = {
b78475cf 1952#define DEF_INTERNAL_FN(CODE, FLAGS, FNSPEC) expand_##CODE,
25583c4f
RS
1953#include "internal-fn.def"
1954#undef DEF_INTERNAL_FN
1955 0
1956};
1957
1958/* Expand STMT, which is a call to internal function FN. */
1959
1960void
538dd0b7 1961expand_internal_call (gcall *stmt)
25583c4f
RS
1962{
1963 internal_fn_expanders[(int) gimple_call_internal_fn (stmt)] (stmt);
1964}