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