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