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