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