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