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