2015-09-25 Vladimir Makarov <vmakarov@redhat.com>
[official-gcc.git] / gcc / internal-fn.c
blob71f811cbfc87b8150b26396a9d1afcad1791f094
1 /* Internal functions.
2 Copyright (C) 2011-2015 Free Software Foundation, Inc.
4 This file is part of GCC.
6 GCC is free software; you can redistribute it and/or modify it under
7 the terms of the GNU General Public License as published by the Free
8 Software Foundation; either version 3, or (at your option) any later
9 version.
11 GCC is distributed in the hope that it will be useful, but WITHOUT ANY
12 WARRANTY; without even the implied warranty of MERCHANTABILITY or
13 FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License
14 for more details.
16 You should have received a copy of the GNU General Public License
17 along with GCC; see the file COPYING3. If not see
18 <http://www.gnu.org/licenses/>. */
20 #include "config.h"
21 #include "system.h"
22 #include "coretypes.h"
23 #include "alias.h"
24 #include "backend.h"
25 #include "predict.h"
26 #include "tree.h"
27 #include "gimple.h"
28 #include "rtl.h"
29 #include "options.h"
30 #include "fold-const.h"
31 #include "internal-fn.h"
32 #include "stor-layout.h"
33 #include "flags.h"
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"
42 #include "expr.h"
43 #include "insn-codes.h"
44 #include "optabs.h"
45 #include "ubsan.h"
46 #include "target.h"
47 #include "stringpool.h"
48 #include "tree-ssanames.h"
49 #include "diagnostic-core.h"
51 /* The names of each internal function, indexed by function number. */
52 const char *const internal_fn_name_array[] = {
53 #define DEF_INTERNAL_FN(CODE, FLAGS, FNSPEC) #CODE,
54 #include "internal-fn.def"
55 #undef DEF_INTERNAL_FN
56 "<invalid-fn>"
59 /* The ECF_* flags of each internal function, indexed by function number. */
60 const int internal_fn_flags_array[] = {
61 #define DEF_INTERNAL_FN(CODE, FLAGS, FNSPEC) FLAGS,
62 #include "internal-fn.def"
63 #undef DEF_INTERNAL_FN
67 /* Fnspec of each internal function, indexed by function number. */
68 const_tree internal_fn_fnspec_array[IFN_LAST + 1];
70 void
71 init_internal_fns ()
73 #define DEF_INTERNAL_FN(CODE, FLAGS, FNSPEC) \
74 if (FNSPEC) internal_fn_fnspec_array[IFN_##CODE] = \
75 build_string ((int) sizeof (FNSPEC), FNSPEC ? FNSPEC : "");
76 #include "internal-fn.def"
77 #undef DEF_INTERNAL_FN
78 internal_fn_fnspec_array[IFN_LAST] = 0;
81 /* ARRAY_TYPE is an array of vector modes. Return the associated insn
82 for load-lanes-style optab OPTAB. The insn must exist. */
84 static enum insn_code
85 get_multi_vector_move (tree array_type, convert_optab optab)
87 enum insn_code icode;
88 machine_mode imode;
89 machine_mode vmode;
91 gcc_assert (TREE_CODE (array_type) == ARRAY_TYPE);
92 imode = TYPE_MODE (array_type);
93 vmode = TYPE_MODE (TREE_TYPE (array_type));
95 icode = convert_optab_handler (optab, imode, vmode);
96 gcc_assert (icode != CODE_FOR_nothing);
97 return icode;
100 /* Expand LOAD_LANES call STMT. */
102 static void
103 expand_LOAD_LANES (gcall *stmt)
105 struct expand_operand ops[2];
106 tree type, lhs, rhs;
107 rtx target, mem;
109 lhs = gimple_call_lhs (stmt);
110 rhs = gimple_call_arg (stmt, 0);
111 type = TREE_TYPE (lhs);
113 target = expand_expr (lhs, NULL_RTX, VOIDmode, EXPAND_WRITE);
114 mem = expand_normal (rhs);
116 gcc_assert (MEM_P (mem));
117 PUT_MODE (mem, TYPE_MODE (type));
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);
124 /* Expand STORE_LANES call STMT. */
126 static void
127 expand_STORE_LANES (gcall *stmt)
129 struct expand_operand ops[2];
130 tree type, lhs, rhs;
131 rtx target, reg;
133 lhs = gimple_call_lhs (stmt);
134 rhs = gimple_call_arg (stmt, 0);
135 type = TREE_TYPE (rhs);
137 target = expand_expr (lhs, NULL_RTX, VOIDmode, EXPAND_WRITE);
138 reg = expand_normal (rhs);
140 gcc_assert (MEM_P (target));
141 PUT_MODE (target, TYPE_MODE (type));
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);
148 static void
149 expand_ANNOTATE (gcall *)
151 gcc_unreachable ();
154 /* This should get expanded in adjust_simduid_builtins. */
156 static void
157 expand_GOMP_SIMD_LANE (gcall *)
159 gcc_unreachable ();
162 /* This should get expanded in adjust_simduid_builtins. */
164 static void
165 expand_GOMP_SIMD_VF (gcall *)
167 gcc_unreachable ();
170 /* This should get expanded in adjust_simduid_builtins. */
172 static void
173 expand_GOMP_SIMD_LAST_LANE (gcall *)
175 gcc_unreachable ();
178 /* This should get expanded in the sanopt pass. */
180 static void
181 expand_UBSAN_NULL (gcall *)
183 gcc_unreachable ();
186 /* This should get expanded in the sanopt pass. */
188 static void
189 expand_UBSAN_BOUNDS (gcall *)
191 gcc_unreachable ();
194 /* This should get expanded in the sanopt pass. */
196 static void
197 expand_UBSAN_VPTR (gcall *)
199 gcc_unreachable ();
202 /* This should get expanded in the sanopt pass. */
204 static void
205 expand_UBSAN_OBJECT_SIZE (gcall *)
207 gcc_unreachable ();
210 /* This should get expanded in the sanopt pass. */
212 static void
213 expand_ASAN_CHECK (gcall *)
215 gcc_unreachable ();
218 /* This should get expanded in the tsan pass. */
220 static void
221 expand_TSAN_FUNC_EXIT (gcall *)
223 gcc_unreachable ();
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. */
231 static int
232 get_range_pos_neg (tree arg)
234 if (arg == error_mark_node)
235 return 3;
237 int prec = TYPE_PRECISION (TREE_TYPE (arg));
238 int cnt = 0;
239 if (TREE_CODE (arg) == INTEGER_CST)
241 wide_int w = wi::sext (arg, prec);
242 if (wi::neg_p (w))
243 return 2;
244 else
245 return 1;
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)
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;
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)
267 gimple *g = SSA_NAME_DEF_STMT (arg);
268 if (is_gimple_assign (g)
269 && CONVERT_EXPR_CODE_P (gimple_assign_rhs_code (g)))
271 tree t = gimple_assign_rhs1 (g);
272 if (INTEGRAL_TYPE_P (TREE_TYPE (t))
273 && TYPE_PRECISION (TREE_TYPE (t)) <= prec)
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;
285 return 3;
287 if (TYPE_UNSIGNED (TREE_TYPE (arg)))
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;
296 else
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;
303 return 3;
306 /* Return minimum precision needed to represent all values
307 of ARG in SIGNed integral type. */
309 static int
310 get_min_precision (tree arg, signop sign)
312 int prec = TYPE_PRECISION (TREE_TYPE (arg));
313 int cnt = 0;
314 signop orig_sign = sign;
315 if (TREE_CODE (arg) == INTEGER_CST)
317 int p;
318 if (TYPE_SIGN (TREE_TYPE (arg)) != sign)
320 widest_int w = wi::to_widest (arg);
321 w = wi::ext (w, prec, sign);
322 p = wi::min_precision (w, sign);
324 else
325 p = wi::min_precision (arg, sign);
326 return MIN (p, prec);
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)
332 arg = TREE_OPERAND (arg, 0);
333 if (TYPE_PRECISION (TREE_TYPE (arg)) < prec)
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));
341 if (++cnt > 30)
342 return prec + (orig_sign != sign);
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)
349 gimple *g = SSA_NAME_DEF_STMT (arg);
350 if (is_gimple_assign (g)
351 && CONVERT_EXPR_CODE_P (gimple_assign_rhs_code (g)))
353 tree t = gimple_assign_rhs1 (g);
354 if (INTEGRAL_TYPE_P (TREE_TYPE (t))
355 && TYPE_PRECISION (TREE_TYPE (t)) <= prec)
357 arg = t;
358 if (TYPE_PRECISION (TREE_TYPE (arg)) < prec)
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));
366 if (++cnt > 30)
367 return prec + (orig_sign != sign);
368 continue;
371 return prec + (orig_sign != sign);
373 if (sign == TYPE_SIGN (TREE_TYPE (arg)))
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);
380 else if (sign == UNSIGNED && !wi::neg_p (arg_min, SIGNED))
382 int p = wi::min_precision (arg_max, UNSIGNED);
383 prec = MIN (prec, p);
385 return prec + (orig_sign != sign);
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. */
392 static void
393 expand_arith_overflow_result_store (tree lhs, rtx target,
394 machine_mode mode, rtx res)
396 machine_mode tgtmode = GET_MODE_INNER (GET_MODE (target));
397 rtx lres = res;
398 if (tgtmode != mode)
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));
404 do_compare_rtx_and_jump (res, convert_modes (mode, tgtmode, lres, uns),
405 EQ, true, mode, NULL_RTX, NULL, done_label,
406 PROB_VERY_LIKELY);
407 write_complex_part (target, const1_rtx, true);
408 emit_label (done_label);
410 write_complex_part (target, lres, false);
413 /* Helper for expand_*_overflow. Store RES into TARGET. */
415 static void
416 expand_ubsan_result_store (rtx target, rtx res)
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);
428 /* Add sub/add overflow checking to the statement STMT.
429 CODE says whether the operation is +, or -. */
431 static void
432 expand_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)
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 ();
440 do_pending_stack_adjust ();
441 rtx op0 = expand_normal (arg0);
442 rtx op1 = expand_normal (arg1);
443 machine_mode mode = TYPE_MODE (TREE_TYPE (arg0));
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;
448 if (is_ubsan)
449 gcc_assert (!unsr_p && !uns0_p && !uns1_p);
451 if (lhs)
453 target = expand_expr (lhs, NULL_RTX, VOIDmode, EXPAND_WRITE);
454 if (!is_ubsan)
455 write_complex_part (target, const0_rtx, true);
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.
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) */
516 if (code == PLUS_EXPR && uns0_p && !uns1_p)
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. */
521 std::swap (op0, op1);
522 std::swap (arg0, arg1);
523 uns0_p = false;
524 uns1_p = true;
527 /* u1 +- u2 -> ur */
528 if (uns0_p && uns1_p && unsr_p)
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;
547 do_compare_rtx_and_jump (res, tem, code == PLUS_EXPR ? GEU : LEU,
548 true, mode, NULL_RTX, NULL, done_label,
549 PROB_VERY_LIKELY);
550 goto do_error_label;
553 /* s1 +- u2 -> sr */
554 if (!uns0_p && uns1_p && !unsr_p)
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);
563 do_compare_rtx_and_jump (tem, op1, GEU, true, mode, NULL_RTX, NULL,
564 done_label, PROB_VERY_LIKELY);
565 goto do_error_label;
568 /* s1 + u2 -> ur */
569 if (code == PLUS_EXPR && !uns0_p && uns1_p && unsr_p)
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;
580 /* u1 - s2 -> ur */
581 if (code == MINUS_EXPR && uns0_p && !uns1_p && unsr_p)
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;
592 /* s1 - u2 -> ur */
593 if (code == MINUS_EXPR && !uns0_p && uns1_p && unsr_p)
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. */
605 do_compare_rtx_and_jump (op0, const0_rtx, LT, false, mode, NULL_RTX,
606 NULL, do_error, PROB_VERY_UNLIKELY);
607 do_compare_rtx_and_jump (op1, op0, LEU, true, mode, NULL_RTX, NULL,
608 done_label, PROB_VERY_LIKELY);
609 goto do_error_label;
612 /* u1 - s2 -> sr */
613 if (code == MINUS_EXPR && uns0_p && !uns1_p && !unsr_p)
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);
621 do_compare_rtx_and_jump (op0, tem, LTU, true, mode, NULL_RTX, NULL,
622 done_label, PROB_VERY_LIKELY);
623 goto do_error_label;
626 /* u1 + u2 -> sr */
627 if (code == PLUS_EXPR && uns0_p && uns1_p && !unsr_p)
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);
633 do_compare_rtx_and_jump (res, const0_rtx, LT, false, mode, NULL_RTX,
634 NULL, do_error, PROB_VERY_UNLIKELY);
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;
647 do_compare_rtx_and_jump (res, tem, GEU, true, mode, NULL_RTX, NULL,
648 done_label, PROB_VERY_LIKELY);
649 goto do_error_label;
652 /* s1 +- s2 -> ur */
653 if (!uns0_p && !uns1_p && unsr_p)
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)
662 int pos_neg0 = get_range_pos_neg (arg0);
663 if (pos_neg0 != 3 && pos_neg == 3)
665 std::swap (op0, op1);
666 pos_neg = pos_neg0;
669 rtx tem;
670 if (pos_neg != 3)
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);
675 do_compare_rtx_and_jump (tem, const0_rtx, GE, false, mode, NULL,
676 NULL, done_label, PROB_VERY_LIKELY);
678 else
680 rtx_code_label *do_ior_label = gen_label_rtx ();
681 do_compare_rtx_and_jump (op1, const0_rtx,
682 code == MINUS_EXPR ? GE : LT, false, mode,
683 NULL_RTX, NULL, do_ior_label,
684 PROB_EVEN);
685 tem = expand_binop (mode, and_optab, op0, res, NULL_RTX, false,
686 OPTAB_LIB_WIDEN);
687 do_compare_rtx_and_jump (tem, const0_rtx, GE, false, mode, NULL_RTX,
688 NULL, done_label, PROB_VERY_LIKELY);
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);
693 do_compare_rtx_and_jump (tem, const0_rtx, GE, false, mode, NULL_RTX,
694 NULL, done_label, PROB_VERY_LIKELY);
696 goto do_error_label;
699 /* u1 - u2 -> sr */
700 if (code == MINUS_EXPR && uns0_p && uns1_p && !unsr_p)
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 ();
707 do_compare_rtx_and_jump (op0, op1, GEU, true, mode, NULL_RTX, NULL,
708 op0_geu_op1, PROB_EVEN);
709 do_compare_rtx_and_jump (res, const0_rtx, LT, false, mode, NULL_RTX,
710 NULL, done_label, PROB_VERY_LIKELY);
711 emit_jump (do_error);
712 emit_label (op0_geu_op1);
713 do_compare_rtx_and_jump (res, const0_rtx, GE, false, mode, NULL_RTX,
714 NULL, done_label, PROB_VERY_LIKELY);
715 goto do_error_label;
718 gcc_assert (!uns0_p && !uns1_p && !unsr_p);
720 /* s1 +- s2 -> sr */
721 do_signed: ;
722 enum insn_code icode;
723 icode = optab_handler (code == PLUS_EXPR ? addv4_optab : subv4_optab, mode);
724 if (icode != CODE_FOR_nothing)
726 struct expand_operand ops[4];
727 rtx_insn *last = get_last_insn ();
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))
736 last = get_last_insn ();
737 if (profile_status_for_fn (cfun) != PROFILE_ABSENT
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);
744 else
746 delete_insns_since (last);
747 icode = CODE_FOR_nothing;
751 if (icode == CODE_FOR_nothing)
753 rtx_code_label *sub_check = gen_label_rtx ();
754 int pos_neg = 3;
756 /* Compute the operation. On RTL level, the addition is always
757 unsigned. */
758 res = expand_binop (mode, code == PLUS_EXPR ? add_optab : sub_optab,
759 op0, op1, NULL_RTX, false, OPTAB_LIB_WIDEN);
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
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
767 do_compare_rtx_and_jump will be just folded. Otherwise try
768 to use range info if available. */
769 if (code == PLUS_EXPR && CONST_INT_P (op0))
770 std::swap (op0, op1);
771 else if (CONST_INT_P (op1))
773 else if (code == PLUS_EXPR && TREE_CODE (arg0) == SSA_NAME)
775 pos_neg = get_range_pos_neg (arg0);
776 if (pos_neg != 3)
777 std::swap (op0, op1);
779 if (pos_neg == 3 && !CONST_INT_P (op1) && TREE_CODE (arg1) == SSA_NAME)
780 pos_neg = get_range_pos_neg (arg1);
782 /* If the op1 is negative, we have to use a different check. */
783 if (pos_neg == 3)
784 do_compare_rtx_and_jump (op1, const0_rtx, LT, false, mode, NULL_RTX,
785 NULL, sub_check, PROB_EVEN);
787 /* Compare the result of the operation with one of the operands. */
788 if (pos_neg & 1)
789 do_compare_rtx_and_jump (res, op0, code == PLUS_EXPR ? GE : LE,
790 false, mode, NULL_RTX, NULL, done_label,
791 PROB_VERY_LIKELY);
793 /* If we get here, we have to print the error. */
794 if (pos_neg == 3)
796 emit_jump (do_error);
798 emit_label (sub_check);
801 /* We have k = a + b for b < 0 here. k <= a must hold. */
802 if (pos_neg & 2)
803 do_compare_rtx_and_jump (res, op0, code == PLUS_EXPR ? LE : GE,
804 false, mode, NULL_RTX, NULL, done_label,
805 PROB_VERY_LIKELY);
808 do_error_label:
809 emit_label (do_error);
810 if (is_ubsan)
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 ();
820 else if (lhs)
821 write_complex_part (target, const1_rtx, true);
823 /* We're done. */
824 emit_label (done_label);
826 if (lhs)
828 if (is_ubsan)
829 expand_ubsan_result_store (target, res);
830 else
832 if (do_xor)
833 res = expand_binop (mode, add_optab, res, sgn, NULL_RTX, false,
834 OPTAB_LIB_WIDEN);
836 expand_arith_overflow_result_store (lhs, target, mode, res);
841 /* Add negate overflow checking to the statement STMT. */
843 static void
844 expand_neg_overflow (location_t loc, tree lhs, tree arg1, bool is_ubsan)
846 rtx res, op1;
847 tree fn;
848 rtx_code_label *done_label, *do_error;
849 rtx target = NULL_RTX;
851 done_label = gen_label_rtx ();
852 do_error = gen_label_rtx ();
854 do_pending_stack_adjust ();
855 op1 = expand_normal (arg1);
857 machine_mode mode = TYPE_MODE (TREE_TYPE (arg1));
858 if (lhs)
860 target = expand_expr (lhs, NULL_RTX, VOIDmode, EXPAND_WRITE);
861 if (!is_ubsan)
862 write_complex_part (target, const0_rtx, true);
865 enum insn_code icode = optab_handler (negv3_optab, mode);
866 if (icode != CODE_FOR_nothing)
868 struct expand_operand ops[3];
869 rtx_insn *last = get_last_insn ();
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))
877 last = get_last_insn ();
878 if (profile_status_for_fn (cfun) != PROFILE_ABSENT
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);
885 else
887 delete_insns_since (last);
888 icode = CODE_FOR_nothing;
892 if (icode == CODE_FOR_nothing)
894 /* Compute the operation. On RTL level, the addition is always
895 unsigned. */
896 res = expand_unop (mode, neg_optab, op1, NULL_RTX, false);
898 /* Compare the operand with the most negative value. */
899 rtx minv = expand_normal (TYPE_MIN_VALUE (TREE_TYPE (arg1)));
900 do_compare_rtx_and_jump (op1, minv, NE, true, mode, NULL_RTX, NULL,
901 done_label, PROB_VERY_LIKELY);
904 emit_label (do_error);
905 if (is_ubsan)
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 ();
915 else if (lhs)
916 write_complex_part (target, const1_rtx, true);
918 /* We're done. */
919 emit_label (done_label);
921 if (lhs)
923 if (is_ubsan)
924 expand_ubsan_result_store (target, res);
925 else
926 expand_arith_overflow_result_store (lhs, target, mode, res);
930 /* Add mul overflow checking to the statement STMT. */
932 static void
933 expand_mul_overflow (location_t loc, tree lhs, tree arg0, tree arg1,
934 bool unsr_p, bool uns0_p, bool uns1_p, bool is_ubsan)
936 rtx res, op0, op1;
937 tree fn, type;
938 rtx_code_label *done_label, *do_error;
939 rtx target = NULL_RTX;
940 signop sign;
941 enum insn_code icode;
943 done_label = gen_label_rtx ();
944 do_error = gen_label_rtx ();
946 do_pending_stack_adjust ();
947 op0 = expand_normal (arg0);
948 op1 = expand_normal (arg1);
950 machine_mode mode = TYPE_MODE (TREE_TYPE (arg0));
951 bool uns = unsr_p;
952 if (lhs)
954 target = expand_expr (lhs, NULL_RTX, VOIDmode, EXPAND_WRITE);
955 if (!is_ubsan)
956 write_complex_part (target, const0_rtx, true);
959 if (is_ubsan)
960 gcc_assert (!unsr_p && !uns0_p && !uns1_p);
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.
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) */
999 if (uns0_p && !uns1_p)
1001 /* Multiplication is commutative, if operand signedness differs,
1002 canonicalize to the first operand being signed and second
1003 unsigned to simplify following code. */
1004 std::swap (op0, op1);
1005 std::swap (arg0, arg1);
1006 uns0_p = false;
1007 uns1_p = true;
1010 int pos_neg0 = get_range_pos_neg (arg0);
1011 int pos_neg1 = get_range_pos_neg (arg1);
1013 /* s1 * u2 -> ur */
1014 if (!uns0_p && uns1_p && unsr_p)
1016 switch (pos_neg0)
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);
1032 do_compare_rtx_and_jump (op1, const0_rtx, EQ, true, mode, NULL_RTX,
1033 NULL, done_label, PROB_VERY_LIKELY);
1034 goto do_error_label;
1035 case 3:
1036 rtx_code_label *do_main_label;
1037 do_main_label = gen_label_rtx ();
1038 do_compare_rtx_and_jump (op0, const0_rtx, GE, false, mode, NULL_RTX,
1039 NULL, do_main_label, PROB_VERY_LIKELY);
1040 do_compare_rtx_and_jump (op1, const0_rtx, EQ, true, mode, NULL_RTX,
1041 NULL, do_main_label, PROB_VERY_LIKELY);
1042 write_complex_part (target, const1_rtx, true);
1043 emit_label (do_main_label);
1044 goto do_main;
1045 default:
1046 gcc_unreachable ();
1050 /* u1 * u2 -> sr */
1051 if (uns0_p && uns1_p && !unsr_p)
1053 uns = true;
1054 /* Rest of handling of this case after res is computed. */
1055 goto do_main;
1058 /* s1 * u2 -> sr */
1059 if (!uns0_p && uns1_p && !unsr_p)
1061 switch (pos_neg1)
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);
1077 do_compare_rtx_and_jump (op0, const0_rtx, EQ, true, mode, NULL_RTX,
1078 NULL, done_label, PROB_VERY_LIKELY);
1079 do_compare_rtx_and_jump (op0, constm1_rtx, NE, true, mode, NULL_RTX,
1080 NULL, do_error, PROB_VERY_UNLIKELY);
1081 int prec;
1082 prec = GET_MODE_PRECISION (mode);
1083 rtx sgn;
1084 sgn = immed_wide_int_const (wi::min_value (prec, SIGNED), mode);
1085 do_compare_rtx_and_jump (op1, sgn, EQ, true, mode, NULL_RTX,
1086 NULL, done_label, PROB_VERY_LIKELY);
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 ();
1096 /* s1 * s2 -> ur */
1097 if (!uns0_p && !uns1_p && unsr_p)
1099 rtx tem, tem2;
1100 switch (pos_neg0 | pos_neg1)
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)
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),
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);
1131 do_compare_rtx_and_jump (tem, const0_rtx, EQ, true, mode,
1132 NULL_RTX, NULL, done_label,
1133 PROB_VERY_LIKELY);
1134 goto do_error_label;
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);
1149 do_compare_rtx_and_jump (tem, const0_rtx, GE, false, mode, NULL_RTX,
1150 NULL, after_negate_label, PROB_VERY_LIKELY);
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);
1165 do_compare_rtx_and_jump (tem2, const0_rtx, GE, false, mode, NULL_RTX,
1166 NULL, do_main_label, PROB_VERY_LIKELY);
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. */
1171 do_compare_rtx_and_jump (tem, const0_rtx, EQ, true, mode, NULL_RTX,
1172 NULL, do_main_label, PROB_VERY_LIKELY);
1173 write_complex_part (target, const1_rtx, true);
1174 emit_label (do_main_label);
1175 goto do_main;
1176 default:
1177 gcc_unreachable ();
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);
1185 if (icode != CODE_FOR_nothing)
1187 struct expand_operand ops[4];
1188 rtx_insn *last = get_last_insn ();
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))
1197 last = get_last_insn ();
1198 if (profile_status_for_fn (cfun) != PROFILE_ABSENT
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);
1205 else
1207 delete_insns_since (last);
1208 icode = CODE_FOR_nothing;
1212 if (icode == CODE_FOR_nothing)
1214 struct separate_ops ops;
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);
1219 ops.op2 = NULL_TREE;
1220 ops.location = loc;
1221 if (GET_MODE_2XWIDER_MODE (mode) != VOIDmode
1222 && targetm.scalar_mode_supported_p (GET_MODE_2XWIDER_MODE (mode)))
1224 machine_mode wmode = GET_MODE_2XWIDER_MODE (mode);
1225 ops.code = WIDEN_MULT_EXPR;
1226 ops.type
1227 = build_nonstandard_integer_type (GET_MODE_PRECISION (wmode), uns);
1229 res = expand_expr_real_2 (&ops, NULL_RTX, wmode, EXPAND_NORMAL);
1230 rtx hipart = expand_shift (RSHIFT_EXPR, wmode, res, prec,
1231 NULL_RTX, uns);
1232 hipart = gen_lowpart (mode, hipart);
1233 res = gen_lowpart (mode, res);
1234 if (uns)
1235 /* For the unsigned multiplication, there was overflow if
1236 HIPART is non-zero. */
1237 do_compare_rtx_and_jump (hipart, const0_rtx, EQ, true, mode,
1238 NULL_RTX, NULL, done_label,
1239 PROB_VERY_LIKELY);
1240 else
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. */
1247 do_compare_rtx_and_jump (signbit, hipart, EQ, true, mode,
1248 NULL_RTX, NULL, done_label,
1249 PROB_VERY_LIKELY);
1252 else if (hmode != BLKmode && 2 * GET_MODE_PRECISION (hmode) == prec)
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 ();
1258 rtx_code_label *after_hipart_neg = uns ? NULL : gen_label_rtx ();
1259 rtx_code_label *after_lopart_neg = uns ? NULL : gen_label_rtx ();
1260 rtx_code_label *do_overflow = gen_label_rtx ();
1261 rtx_code_label *hipart_different = uns ? NULL : gen_label_rtx ();
1263 unsigned int hprec = GET_MODE_PRECISION (hmode);
1264 rtx hipart0 = expand_shift (RSHIFT_EXPR, mode, op0, hprec,
1265 NULL_RTX, uns);
1266 hipart0 = gen_lowpart (hmode, hipart0);
1267 rtx lopart0 = gen_lowpart (hmode, op0);
1268 rtx signbit0 = const0_rtx;
1269 if (!uns)
1270 signbit0 = expand_shift (RSHIFT_EXPR, hmode, lopart0, hprec - 1,
1271 NULL_RTX, 0);
1272 rtx hipart1 = expand_shift (RSHIFT_EXPR, mode, op1, hprec,
1273 NULL_RTX, uns);
1274 hipart1 = gen_lowpart (hmode, hipart1);
1275 rtx lopart1 = gen_lowpart (hmode, op1);
1276 rtx signbit1 = const0_rtx;
1277 if (!uns)
1278 signbit1 = expand_shift (RSHIFT_EXPR, hmode, lopart1, hprec - 1,
1279 NULL_RTX, 0);
1281 res = gen_reg_rtx (mode);
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;
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;
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;
1321 int smaller_sign = 1;
1322 int larger_sign = 1;
1323 if (op0_small_p)
1325 smaller_sign = op0_sign;
1326 larger_sign = op1_sign;
1328 else if (op1_small_p)
1330 smaller_sign = op1_sign;
1331 larger_sign = op0_sign;
1333 else if (op0_sign == op1_sign)
1335 smaller_sign = op0_sign;
1336 larger_sign = op0_sign;
1339 if (!op0_small_p)
1340 do_compare_rtx_and_jump (signbit0, hipart0, NE, true, hmode,
1341 NULL_RTX, NULL, large_op0,
1342 PROB_UNLIKELY);
1344 if (!op1_small_p)
1345 do_compare_rtx_and_jump (signbit1, hipart1, NE, true, hmode,
1346 NULL_RTX, NULL, small_op0_large_op1,
1347 PROB_UNLIKELY);
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;
1353 if (GET_CODE (lopart0) == SUBREG)
1355 lopart0s = shallow_copy_rtx (lopart0);
1356 SUBREG_PROMOTED_VAR_P (lopart0s) = 1;
1357 SUBREG_PROMOTED_SET (lopart0s, uns ? SRP_UNSIGNED : SRP_SIGNED);
1359 if (GET_CODE (lopart1) == SUBREG)
1361 lopart1s = shallow_copy_rtx (lopart1);
1362 SUBREG_PROMOTED_VAR_P (lopart1s) = 1;
1363 SUBREG_PROMOTED_SET (lopart1s, uns ? SRP_UNSIGNED : SRP_SIGNED);
1365 tree halfstype = build_nonstandard_integer_type (hprec, uns);
1366 ops.op0 = make_tree (halfstype, lopart0s);
1367 ops.op1 = make_tree (halfstype, lopart1s);
1368 ops.code = WIDEN_MULT_EXPR;
1369 ops.type = type;
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);
1375 emit_label (small_op0_large_op1);
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. */
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);
1388 emit_label (large_op0);
1390 if (!op1_small_p)
1391 do_compare_rtx_and_jump (signbit1, hipart1, NE, true, hmode,
1392 NULL_RTX, NULL, both_ops_large,
1393 PROB_UNLIKELY);
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. */
1398 emit_move_insn (larger, op0);
1399 emit_move_insn (hipart, hipart0);
1400 emit_move_insn (lopart, lopart1);
1402 emit_label (one_small_one_large);
1404 /* lopart is the low part of the operand that is sign extended
1405 to mode, larger is the other operand, hipart is the
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);
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);
1422 if (!uns)
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)
1428 do_compare_rtx_and_jump (hipart, const0_rtx, GE, false, hmode,
1429 NULL_RTX, NULL, after_hipart_neg,
1430 PROB_EVEN);
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);
1438 emit_label (after_hipart_neg);
1440 /* if (lopart < 0) loxhi -= larger; */
1441 if (smaller_sign == 0)
1442 emit_jump (after_lopart_neg);
1443 else if (smaller_sign != -1)
1444 do_compare_rtx_and_jump (lopart, const0_rtx, GE, false, hmode,
1445 NULL_RTX, NULL, after_lopart_neg,
1446 PROB_EVEN);
1448 tem = expand_simple_binop (mode, MINUS, loxhi, larger, NULL_RTX,
1449 1, OPTAB_DIRECT);
1450 emit_move_insn (loxhi, tem);
1452 emit_label (after_lopart_neg);
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);
1461 /* if (loxhi >> (bitsize / 2)
1462 == (hmode) loxhi >> (bitsize / 2 - 1)) (if !uns)
1463 if (loxhi >> (bitsize / 2) == 0 (if uns). */
1464 rtx hipartloxhi = expand_shift (RSHIFT_EXPR, mode, loxhi, hprec,
1465 NULL_RTX, 0);
1466 hipartloxhi = gen_lowpart (hmode, hipartloxhi);
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);
1473 do_compare_rtx_and_jump (signbitloxhi, hipartloxhi, NE, true, hmode,
1474 NULL_RTX, NULL, do_overflow,
1475 PROB_VERY_UNLIKELY);
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);
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);
1488 emit_label (both_ops_large);
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. */
1497 ops.code = MULT_EXPR;
1498 ops.op0 = make_tree (type, op0);
1499 ops.op1 = make_tree (type, op1);
1500 tem = expand_expr_real_2 (&ops, NULL_RTX, mode, EXPAND_NORMAL);
1501 emit_move_insn (res, tem);
1503 if (!uns)
1505 if (!op0_medium_p)
1507 tem = expand_simple_binop (hmode, PLUS, hipart0, const1_rtx,
1508 NULL_RTX, 1, OPTAB_DIRECT);
1509 do_compare_rtx_and_jump (tem, const1_rtx, GTU, true, hmode,
1510 NULL_RTX, NULL, do_error,
1511 PROB_VERY_UNLIKELY);
1514 if (!op1_medium_p)
1516 tem = expand_simple_binop (hmode, PLUS, hipart1, const1_rtx,
1517 NULL_RTX, 1, OPTAB_DIRECT);
1518 do_compare_rtx_and_jump (tem, const1_rtx, GTU, true, hmode,
1519 NULL_RTX, NULL, do_error,
1520 PROB_VERY_UNLIKELY);
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)
1529 do_compare_rtx_and_jump (hipart0, hipart1, NE, true, hmode,
1530 NULL_RTX, NULL, hipart_different,
1531 PROB_EVEN);
1533 do_compare_rtx_and_jump (res, const0_rtx, LT, false, mode,
1534 NULL_RTX, NULL, do_error,
1535 PROB_VERY_UNLIKELY);
1536 emit_jump (done_label);
1538 emit_label (hipart_different);
1540 do_compare_rtx_and_jump (res, const0_rtx, GE, false, mode,
1541 NULL_RTX, NULL, do_error,
1542 PROB_VERY_UNLIKELY);
1543 emit_jump (done_label);
1546 emit_label (do_overflow);
1548 /* Overflow, do full multiplication and fallthru into do_error. */
1549 ops.op0 = make_tree (type, op0);
1550 ops.op1 = make_tree (type, op1);
1551 tem = expand_expr_real_2 (&ops, NULL_RTX, mode, EXPAND_NORMAL);
1552 emit_move_insn (res, tem);
1554 else
1556 gcc_assert (!is_ubsan);
1557 ops.code = MULT_EXPR;
1558 ops.type = type;
1559 res = expand_expr_real_2 (&ops, NULL_RTX, mode, EXPAND_NORMAL);
1560 emit_jump (done_label);
1564 do_error_label:
1565 emit_label (do_error);
1566 if (is_ubsan)
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 ();
1576 else if (lhs)
1577 write_complex_part (target, const1_rtx, true);
1579 /* We're done. */
1580 emit_label (done_label);
1582 /* u1 * u2 -> sr */
1583 if (uns0_p && uns1_p && !unsr_p)
1585 rtx_code_label *all_done_label = gen_label_rtx ();
1586 do_compare_rtx_and_jump (res, const0_rtx, GE, false, mode, NULL_RTX,
1587 NULL, all_done_label, PROB_VERY_LIKELY);
1588 write_complex_part (target, const1_rtx, true);
1589 emit_label (all_done_label);
1592 /* s1 * u2 -> sr */
1593 if (!uns0_p && uns1_p && !unsr_p && pos_neg1 == 3)
1595 rtx_code_label *all_done_label = gen_label_rtx ();
1596 rtx_code_label *set_noovf = gen_label_rtx ();
1597 do_compare_rtx_and_jump (op1, const0_rtx, GE, false, mode, NULL_RTX,
1598 NULL, all_done_label, PROB_VERY_LIKELY);
1599 write_complex_part (target, const1_rtx, true);
1600 do_compare_rtx_and_jump (op0, const0_rtx, EQ, true, mode, NULL_RTX,
1601 NULL, set_noovf, PROB_VERY_LIKELY);
1602 do_compare_rtx_and_jump (op0, constm1_rtx, NE, true, mode, NULL_RTX,
1603 NULL, all_done_label, PROB_VERY_UNLIKELY);
1604 do_compare_rtx_and_jump (op1, res, NE, true, mode, NULL_RTX, NULL,
1605 all_done_label, PROB_VERY_UNLIKELY);
1606 emit_label (set_noovf);
1607 write_complex_part (target, const0_rtx, true);
1608 emit_label (all_done_label);
1611 if (lhs)
1613 if (is_ubsan)
1614 expand_ubsan_result_store (target, res);
1615 else
1616 expand_arith_overflow_result_store (lhs, target, mode, res);
1620 /* Expand UBSAN_CHECK_ADD call STMT. */
1622 static void
1623 expand_UBSAN_CHECK_ADD (gcall *stmt)
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);
1633 /* Expand UBSAN_CHECK_SUB call STMT. */
1635 static void
1636 expand_UBSAN_CHECK_SUB (gcall *stmt)
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);
1644 else
1645 expand_addsub_overflow (loc, MINUS_EXPR, lhs, arg0, arg1,
1646 false, false, false, true);
1649 /* Expand UBSAN_CHECK_MUL call STMT. */
1651 static void
1652 expand_UBSAN_CHECK_MUL (gcall *stmt)
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);
1661 /* Helper function for {ADD,SUB,MUL}_OVERFLOW call stmt expansion. */
1663 static void
1664 expand_arith_overflow (enum tree_code code, gimple *stmt)
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);
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
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;
1704 int orig_precres = precres;
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))
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;
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. */
1734 if (WORD_REGISTER_OPERATIONS
1735 && orig_precres == precres
1736 && precres < BITS_PER_WORD)
1738 else if ((uns0_p && uns1_p && unsr_p && prec0 <= precres
1739 && prec1 <= precres)
1740 || ((!uns0_p || !uns1_p) && !unsr_p
1741 && prec0 + uns0_p <= precres
1742 && prec1 + uns1_p <= precres))
1744 arg0 = fold_convert_loc (loc, type, arg0);
1745 arg1 = fold_convert_loc (loc, type, arg1);
1746 switch (code)
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 ();
1765 /* For sub-word operations, retry with a wider type first. */
1766 if (orig_precres == precres && precop <= BITS_PER_WORD)
1768 #if WORD_REGISTER_OPERATIONS
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)
1780 precres = p;
1781 unsr_p = TYPE_UNSIGNED (optype);
1782 type = optype;
1783 continue;
1787 if (prec0 <= precres && prec1 <= precres)
1789 tree types[2];
1790 if (unsr_p)
1792 types[0] = build_nonstandard_integer_type (precres, 0);
1793 types[1] = type;
1795 else
1797 types[0] = type;
1798 types[1] = build_nonstandard_integer_type (precres, 1);
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;
1811 /* Retry with a wider type. */
1812 if (orig_precres == precres)
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)
1822 precres = p;
1823 unsr_p = TYPE_UNSIGNED (optype);
1824 type = optype;
1825 continue;
1829 gcc_unreachable ();
1831 while (1);
1834 /* Expand ADD_OVERFLOW STMT. */
1836 static void
1837 expand_ADD_OVERFLOW (gcall *stmt)
1839 expand_arith_overflow (PLUS_EXPR, stmt);
1842 /* Expand SUB_OVERFLOW STMT. */
1844 static void
1845 expand_SUB_OVERFLOW (gcall *stmt)
1847 expand_arith_overflow (MINUS_EXPR, stmt);
1850 /* Expand MUL_OVERFLOW STMT. */
1852 static void
1853 expand_MUL_OVERFLOW (gcall *stmt)
1855 expand_arith_overflow (MULT_EXPR, stmt);
1858 /* This should get folded in tree-vectorizer.c. */
1860 static void
1861 expand_LOOP_VECTORIZED (gcall *)
1863 gcc_unreachable ();
1866 static void
1867 expand_MASK_LOAD (gcall *stmt)
1869 struct expand_operand ops[3];
1870 tree type, lhs, rhs, maskt;
1871 rtx mem, target, mask;
1873 maskt = gimple_call_arg (stmt, 2);
1874 lhs = gimple_call_lhs (stmt);
1875 if (lhs == NULL_TREE)
1876 return;
1877 type = TREE_TYPE (lhs);
1878 rhs = fold_build2 (MEM_REF, type, gimple_call_arg (stmt, 0),
1879 gimple_call_arg (stmt, 1));
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);
1891 static void
1892 expand_MASK_STORE (gcall *stmt)
1894 struct expand_operand ops[3];
1895 tree type, lhs, rhs, maskt;
1896 rtx mem, reg, mask;
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));
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);
1914 static void
1915 expand_ABNORMAL_DISPATCHER (gcall *)
1919 static void
1920 expand_BUILTIN_EXPECT (gcall *stmt)
1922 /* When guessing was done, the hints should be already stripped away. */
1923 gcc_assert (!flag_guess_branch_prob || optimize == 0 || seen_error ());
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);
1936 /* IFN_VA_ARG is supposed to be expanded at pass_stdarg. So this dummy function
1937 should never be called. */
1939 static void
1940 expand_VA_ARG (gcall *stmt ATTRIBUTE_UNUSED)
1942 gcc_unreachable ();
1945 /* Routines to expand each internal function, indexed by function number.
1946 Each routine has the prototype:
1948 expand_<NAME> (gcall *stmt)
1950 where STMT is the statement that performs the call. */
1951 static void (*const internal_fn_expanders[]) (gcall *) = {
1952 #define DEF_INTERNAL_FN(CODE, FLAGS, FNSPEC) expand_##CODE,
1953 #include "internal-fn.def"
1954 #undef DEF_INTERNAL_FN
1958 /* Expand STMT, which is a call to internal function FN. */
1960 void
1961 expand_internal_call (gcall *stmt)
1963 internal_fn_expanders[(int) gimple_call_internal_fn (stmt)] (stmt);