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