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