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