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