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