[PR87563][AARCH64-SVE]: Don't keep ifcvt loop when COND_<OP> ifn could not be vectorized.
[platform/upstream/gcc.git] / gcc / internal-fn.c
1 /* Internal functions.
2    Copyright (C) 2011-2018 Free Software Foundation, Inc.
3
4 This file is part of GCC.
5
6 GCC is free software; you can redistribute it and/or modify it under
7 the terms of the GNU General Public License as published by the Free
8 Software Foundation; either version 3, or (at your option) any later
9 version.
10
11 GCC is distributed in the hope that it will be useful, but WITHOUT ANY
12 WARRANTY; without even the implied warranty of MERCHANTABILITY or
13 FITNESS FOR A PARTICULAR PURPOSE.  See the GNU General Public License
14 for more details.
15
16 You should have received a copy of the GNU General Public License
17 along with GCC; see the file COPYING3.  If not see
18 <http://www.gnu.org/licenses/>.  */
19
20 #include "config.h"
21 #include "system.h"
22 #include "coretypes.h"
23 #include "backend.h"
24 #include "target.h"
25 #include "rtl.h"
26 #include "tree.h"
27 #include "gimple.h"
28 #include "predict.h"
29 #include "stringpool.h"
30 #include "tree-vrp.h"
31 #include "tree-ssanames.h"
32 #include "expmed.h"
33 #include "memmodel.h"
34 #include "optabs.h"
35 #include "emit-rtl.h"
36 #include "diagnostic-core.h"
37 #include "fold-const.h"
38 #include "internal-fn.h"
39 #include "stor-layout.h"
40 #include "dojump.h"
41 #include "expr.h"
42 #include "stringpool.h"
43 #include "attribs.h"
44 #include "asan.h"
45 #include "ubsan.h"
46 #include "recog.h"
47 #include "builtins.h"
48 #include "optabs-tree.h"
49 #include "gimple-ssa.h"
50 #include "tree-phinodes.h"
51 #include "ssa-iterators.h"
52
53 /* The names of each internal function, indexed by function number.  */
54 const char *const internal_fn_name_array[] = {
55 #define DEF_INTERNAL_FN(CODE, FLAGS, FNSPEC) #CODE,
56 #include "internal-fn.def"
57   "<invalid-fn>"
58 };
59
60 /* The ECF_* flags of each internal function, indexed by function number.  */
61 const int internal_fn_flags_array[] = {
62 #define DEF_INTERNAL_FN(CODE, FLAGS, FNSPEC) FLAGS,
63 #include "internal-fn.def"
64   0
65 };
66
67 /* Return the internal function called NAME, or IFN_LAST if there's
68    no such function.  */
69
70 internal_fn
71 lookup_internal_fn (const char *name)
72 {
73   typedef hash_map<nofree_string_hash, internal_fn> name_to_fn_map_type;
74   static name_to_fn_map_type *name_to_fn_map;
75
76   if (!name_to_fn_map)
77     {
78       name_to_fn_map = new name_to_fn_map_type (IFN_LAST);
79       for (unsigned int i = 0; i < IFN_LAST; ++i)
80         name_to_fn_map->put (internal_fn_name (internal_fn (i)),
81                              internal_fn (i));
82     }
83   internal_fn *entry = name_to_fn_map->get (name);
84   return entry ? *entry : IFN_LAST;
85 }
86
87 /* Fnspec of each internal function, indexed by function number.  */
88 const_tree internal_fn_fnspec_array[IFN_LAST + 1];
89
90 void
91 init_internal_fns ()
92 {
93 #define DEF_INTERNAL_FN(CODE, FLAGS, FNSPEC) \
94   if (FNSPEC) internal_fn_fnspec_array[IFN_##CODE] = \
95     build_string ((int) sizeof (FNSPEC), FNSPEC ? FNSPEC : "");
96 #include "internal-fn.def"
97   internal_fn_fnspec_array[IFN_LAST] = 0;
98 }
99
100 /* Create static initializers for the information returned by
101    direct_internal_fn.  */
102 #define not_direct { -2, -2, false }
103 #define mask_load_direct { -1, 2, false }
104 #define load_lanes_direct { -1, -1, false }
105 #define mask_load_lanes_direct { -1, -1, false }
106 #define gather_load_direct { -1, -1, false }
107 #define mask_store_direct { 3, 2, false }
108 #define store_lanes_direct { 0, 0, false }
109 #define mask_store_lanes_direct { 0, 0, false }
110 #define scatter_store_direct { 3, 3, false }
111 #define unary_direct { 0, 0, true }
112 #define binary_direct { 0, 0, true }
113 #define ternary_direct { 0, 0, true }
114 #define cond_unary_direct { 1, 1, true }
115 #define cond_binary_direct { 1, 1, true }
116 #define 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           rtx lopart0s = lopart0, lopart1s = lopart1;
1757           if (GET_CODE (lopart0) == SUBREG)
1758             {
1759               lopart0s = shallow_copy_rtx (lopart0);
1760               SUBREG_PROMOTED_VAR_P (lopart0s) = 1;
1761               SUBREG_PROMOTED_SET (lopart0s, uns ? SRP_UNSIGNED : SRP_SIGNED);
1762             }
1763           if (GET_CODE (lopart1) == SUBREG)
1764             {
1765               lopart1s = shallow_copy_rtx (lopart1);
1766               SUBREG_PROMOTED_VAR_P (lopart1s) = 1;
1767               SUBREG_PROMOTED_SET (lopart1s, uns ? SRP_UNSIGNED : SRP_SIGNED);
1768             }
1769           tree halfstype = build_nonstandard_integer_type (hprec, uns);
1770           ops.op0 = make_tree (halfstype, lopart0s);
1771           ops.op1 = make_tree (halfstype, lopart1s);
1772           ops.code = WIDEN_MULT_EXPR;
1773           ops.type = type;
1774           rtx thisres
1775             = expand_expr_real_2 (&ops, NULL_RTX, mode, EXPAND_NORMAL);
1776           emit_move_insn (res, thisres);
1777           emit_jump (done_label);
1778
1779           emit_label (small_op0_large_op1);
1780
1781           /* If op0 is sign (!uns) or zero (uns) extended from hmode to mode,
1782              but op1 is not, just swap the arguments and handle it as op1
1783              sign/zero extended, op0 not.  */
1784           rtx larger = gen_reg_rtx (mode);
1785           rtx hipart = gen_reg_rtx (hmode);
1786           rtx lopart = gen_reg_rtx (hmode);
1787           emit_move_insn (larger, op1);
1788           emit_move_insn (hipart, hipart1);
1789           emit_move_insn (lopart, lopart0);
1790           emit_jump (one_small_one_large);
1791
1792           emit_label (large_op0);
1793
1794           if (!op1_small_p)
1795             do_compare_rtx_and_jump (signbit1, hipart1, NE, true, hmode,
1796                                      NULL_RTX, NULL, both_ops_large,
1797                                      profile_probability::unlikely ());
1798
1799           /* If op1 is sign (!uns) or zero (uns) extended from hmode to mode,
1800              but op0 is not, prepare larger, hipart and lopart pseudos and
1801              handle it together with small_op0_large_op1.  */
1802           emit_move_insn (larger, op0);
1803           emit_move_insn (hipart, hipart0);
1804           emit_move_insn (lopart, lopart1);
1805
1806           emit_label (one_small_one_large);
1807
1808           /* lopart is the low part of the operand that is sign extended
1809              to mode, larger is the other operand, hipart is the
1810              high part of larger and lopart0 and lopart1 are the low parts
1811              of both operands.
1812              We perform lopart0 * lopart1 and lopart * hipart widening
1813              multiplications.  */
1814           tree halfutype = build_nonstandard_integer_type (hprec, 1);
1815           ops.op0 = make_tree (halfutype, lopart0);
1816           ops.op1 = make_tree (halfutype, lopart1);
1817           rtx lo0xlo1
1818             = expand_expr_real_2 (&ops, NULL_RTX, mode, EXPAND_NORMAL);
1819
1820           ops.op0 = make_tree (halfutype, lopart);
1821           ops.op1 = make_tree (halfutype, hipart);
1822           rtx loxhi = gen_reg_rtx (mode);
1823           rtx tem = expand_expr_real_2 (&ops, NULL_RTX, mode, EXPAND_NORMAL);
1824           emit_move_insn (loxhi, tem);
1825
1826           if (!uns)
1827             {
1828               /* if (hipart < 0) loxhi -= lopart << (bitsize / 2);  */
1829               if (larger_sign == 0)
1830                 emit_jump (after_hipart_neg);
1831               else if (larger_sign != -1)
1832                 do_compare_rtx_and_jump (hipart, const0_rtx, GE, false, hmode,
1833                                          NULL_RTX, NULL, after_hipart_neg,
1834                                          profile_probability::even ());
1835
1836               tem = convert_modes (mode, hmode, lopart, 1);
1837               tem = expand_shift (LSHIFT_EXPR, mode, tem, hprec, NULL_RTX, 1);
1838               tem = expand_simple_binop (mode, MINUS, loxhi, tem, NULL_RTX,
1839                                          1, OPTAB_WIDEN);
1840               emit_move_insn (loxhi, tem);
1841
1842               emit_label (after_hipart_neg);
1843
1844               /* if (lopart < 0) loxhi -= larger;  */
1845               if (smaller_sign == 0)
1846                 emit_jump (after_lopart_neg);
1847               else if (smaller_sign != -1)
1848                 do_compare_rtx_and_jump (lopart, const0_rtx, GE, false, hmode,
1849                                          NULL_RTX, NULL, after_lopart_neg,
1850                                          profile_probability::even ());
1851
1852               tem = expand_simple_binop (mode, MINUS, loxhi, larger, NULL_RTX,
1853                                          1, OPTAB_WIDEN);
1854               emit_move_insn (loxhi, tem);
1855
1856               emit_label (after_lopart_neg);
1857             }
1858
1859           /* loxhi += (uns) lo0xlo1 >> (bitsize / 2);  */
1860           tem = expand_shift (RSHIFT_EXPR, mode, lo0xlo1, hprec, NULL_RTX, 1);
1861           tem = expand_simple_binop (mode, PLUS, loxhi, tem, NULL_RTX,
1862                                      1, OPTAB_WIDEN);
1863           emit_move_insn (loxhi, tem);
1864
1865           /* if (loxhi >> (bitsize / 2)
1866                  == (hmode) loxhi >> (bitsize / 2 - 1))  (if !uns)
1867              if (loxhi >> (bitsize / 2) == 0             (if uns).  */
1868           rtx hipartloxhi = expand_shift (RSHIFT_EXPR, mode, loxhi, hprec,
1869                                           NULL_RTX, 0);
1870           hipartloxhi = convert_modes (hmode, mode, hipartloxhi, 0);
1871           rtx signbitloxhi = const0_rtx;
1872           if (!uns)
1873             signbitloxhi = expand_shift (RSHIFT_EXPR, hmode,
1874                                          convert_modes (hmode, mode,
1875                                                         loxhi, 0),
1876                                          hprec - 1, NULL_RTX, 0);
1877
1878           do_compare_rtx_and_jump (signbitloxhi, hipartloxhi, NE, true, hmode,
1879                                    NULL_RTX, NULL, do_overflow,
1880                                    profile_probability::very_unlikely ());
1881
1882           /* res = (loxhi << (bitsize / 2)) | (hmode) lo0xlo1;  */
1883           rtx loxhishifted = expand_shift (LSHIFT_EXPR, mode, loxhi, hprec,
1884                                            NULL_RTX, 1);
1885           tem = convert_modes (mode, hmode,
1886                                convert_modes (hmode, mode, lo0xlo1, 1), 1);
1887
1888           tem = expand_simple_binop (mode, IOR, loxhishifted, tem, res,
1889                                      1, OPTAB_WIDEN);
1890           if (tem != res)
1891             emit_move_insn (res, tem);
1892           emit_jump (done_label);
1893
1894           emit_label (both_ops_large);
1895
1896           /* If both operands are large (not sign (!uns) or zero (uns)
1897              extended from hmode), then perform the full multiplication
1898              which will be the result of the operation.
1899              The only cases which don't overflow are for signed multiplication
1900              some cases where both hipart0 and highpart1 are 0 or -1.
1901              For unsigned multiplication when high parts are both non-zero
1902              this overflows always.  */
1903           ops.code = MULT_EXPR;
1904           ops.op0 = make_tree (type, op0);
1905           ops.op1 = make_tree (type, op1);
1906           tem = expand_expr_real_2 (&ops, NULL_RTX, mode, EXPAND_NORMAL);
1907           emit_move_insn (res, tem);
1908
1909           if (!uns)
1910             {
1911               if (!op0_medium_p)
1912                 {
1913                   tem = expand_simple_binop (hmode, PLUS, hipart0, const1_rtx,
1914                                              NULL_RTX, 1, OPTAB_WIDEN);
1915                   do_compare_rtx_and_jump (tem, const1_rtx, GTU, true, hmode,
1916                                            NULL_RTX, NULL, do_error,
1917                                            profile_probability::very_unlikely ());
1918                 }
1919
1920               if (!op1_medium_p)
1921                 {
1922                   tem = expand_simple_binop (hmode, PLUS, hipart1, const1_rtx,
1923                                              NULL_RTX, 1, OPTAB_WIDEN);
1924                   do_compare_rtx_and_jump (tem, const1_rtx, GTU, true, hmode,
1925                                            NULL_RTX, NULL, do_error,
1926                                            profile_probability::very_unlikely ());
1927                 }
1928
1929               /* At this point hipart{0,1} are both in [-1, 0].  If they are
1930                  the same, overflow happened if res is non-positive, if they
1931                  are different, overflow happened if res is positive.  */
1932               if (op0_sign != 1 && op1_sign != 1 && op0_sign != op1_sign)
1933                 emit_jump (hipart_different);
1934               else if (op0_sign == 1 || op1_sign == 1)
1935                 do_compare_rtx_and_jump (hipart0, hipart1, NE, true, hmode,
1936                                          NULL_RTX, NULL, hipart_different,
1937                                          profile_probability::even ());
1938
1939               do_compare_rtx_and_jump (res, const0_rtx, LE, false, mode,
1940                                        NULL_RTX, NULL, do_error,
1941                                        profile_probability::very_unlikely ());
1942               emit_jump (done_label);
1943
1944               emit_label (hipart_different);
1945
1946               do_compare_rtx_and_jump (res, const0_rtx, GE, false, mode,
1947                                        NULL_RTX, NULL, do_error,
1948                                        profile_probability::very_unlikely ());
1949               emit_jump (done_label);
1950             }
1951
1952           emit_label (do_overflow);
1953
1954           /* Overflow, do full multiplication and fallthru into do_error.  */
1955           ops.op0 = make_tree (type, op0);
1956           ops.op1 = make_tree (type, op1);
1957           tem = expand_expr_real_2 (&ops, NULL_RTX, mode, EXPAND_NORMAL);
1958           emit_move_insn (res, tem);
1959         }
1960       else if (GET_MODE_2XWIDER_MODE (mode).exists (&wmode)
1961                && targetm.scalar_mode_supported_p (wmode))
1962         /* Even emitting a libcall is better than not detecting overflow
1963            at all.  */
1964         goto twoxwider;
1965       else
1966         {
1967           gcc_assert (!is_ubsan);
1968           ops.code = MULT_EXPR;
1969           ops.type = type;
1970           res = expand_expr_real_2 (&ops, NULL_RTX, mode, EXPAND_NORMAL);
1971           emit_jump (done_label);
1972         }
1973     }
1974
1975  do_error_label:
1976   emit_label (do_error);
1977   if (is_ubsan)
1978     {
1979       /* Expand the ubsan builtin call.  */
1980       push_temp_slots ();
1981       fn = ubsan_build_overflow_builtin (MULT_EXPR, loc, TREE_TYPE (arg0),
1982                                          arg0, arg1, datap);
1983       expand_normal (fn);
1984       pop_temp_slots ();
1985       do_pending_stack_adjust ();
1986     }
1987   else if (lhs)
1988     expand_arith_set_overflow (lhs, target);
1989
1990   /* We're done.  */
1991   emit_label (done_label);
1992
1993   /* u1 * u2 -> sr  */
1994   if (uns0_p && uns1_p && !unsr_p)
1995     {
1996       rtx_code_label *all_done_label = gen_label_rtx ();
1997       do_compare_rtx_and_jump (res, const0_rtx, GE, false, mode, NULL_RTX,
1998                                NULL, all_done_label, profile_probability::very_likely ());
1999       expand_arith_set_overflow (lhs, target);
2000       emit_label (all_done_label);
2001     }
2002
2003   /* s1 * u2 -> sr  */
2004   if (!uns0_p && uns1_p && !unsr_p && pos_neg1 == 3)
2005     {
2006       rtx_code_label *all_done_label = gen_label_rtx ();
2007       rtx_code_label *set_noovf = gen_label_rtx ();
2008       do_compare_rtx_and_jump (op1, const0_rtx, GE, false, mode, NULL_RTX,
2009                                NULL, all_done_label, profile_probability::very_likely ());
2010       expand_arith_set_overflow (lhs, target);
2011       do_compare_rtx_and_jump (op0, const0_rtx, EQ, true, mode, NULL_RTX,
2012                                NULL, set_noovf, profile_probability::very_likely ());
2013       do_compare_rtx_and_jump (op0, constm1_rtx, NE, true, mode, NULL_RTX,
2014                                NULL, all_done_label, profile_probability::very_unlikely ());
2015       do_compare_rtx_and_jump (op1, res, NE, true, mode, NULL_RTX, NULL,
2016                                all_done_label, profile_probability::very_unlikely ());
2017       emit_label (set_noovf);
2018       write_complex_part (target, const0_rtx, true);
2019       emit_label (all_done_label);
2020     }
2021
2022   if (lhs)
2023     {
2024       if (is_ubsan)
2025         expand_ubsan_result_store (target, res);
2026       else
2027         expand_arith_overflow_result_store (lhs, target, mode, res);
2028     }
2029 }
2030
2031 /* Expand UBSAN_CHECK_* internal function if it has vector operands.  */
2032
2033 static void
2034 expand_vector_ubsan_overflow (location_t loc, enum tree_code code, tree lhs,
2035                               tree arg0, tree arg1)
2036 {
2037   poly_uint64 cnt = TYPE_VECTOR_SUBPARTS (TREE_TYPE (arg0));
2038   rtx_code_label *loop_lab = NULL;
2039   rtx cntvar = NULL_RTX;
2040   tree cntv = NULL_TREE;
2041   tree eltype = TREE_TYPE (TREE_TYPE (arg0));
2042   tree sz = TYPE_SIZE (eltype);
2043   tree data = NULL_TREE;
2044   tree resv = NULL_TREE;
2045   rtx lhsr = NULL_RTX;
2046   rtx resvr = NULL_RTX;
2047   unsigned HOST_WIDE_INT const_cnt = 0;
2048   bool use_loop_p = (!cnt.is_constant (&const_cnt) || const_cnt > 4);
2049
2050   if (lhs)
2051     {
2052       optab op;
2053       lhsr = expand_expr (lhs, NULL_RTX, VOIDmode, EXPAND_WRITE);
2054       if (!VECTOR_MODE_P (GET_MODE (lhsr))
2055           || (op = optab_for_tree_code (code, TREE_TYPE (arg0),
2056                                         optab_default)) == unknown_optab
2057           || (optab_handler (op, TYPE_MODE (TREE_TYPE (arg0)))
2058               == CODE_FOR_nothing))
2059         {
2060           if (MEM_P (lhsr))
2061             resv = make_tree (TREE_TYPE (lhs), lhsr);
2062           else
2063             {
2064               resvr = assign_temp (TREE_TYPE (lhs), 1, 1);
2065               resv = make_tree (TREE_TYPE (lhs), resvr);
2066             }
2067         }
2068     }
2069   if (use_loop_p)
2070     {
2071       do_pending_stack_adjust ();
2072       loop_lab = gen_label_rtx ();
2073       cntvar = gen_reg_rtx (TYPE_MODE (sizetype));
2074       cntv = make_tree (sizetype, cntvar);
2075       emit_move_insn (cntvar, const0_rtx);
2076       emit_label (loop_lab);
2077     }
2078   if (TREE_CODE (arg0) != VECTOR_CST)
2079     {
2080       rtx arg0r = expand_normal (arg0);
2081       arg0 = make_tree (TREE_TYPE (arg0), arg0r);
2082     }
2083   if (TREE_CODE (arg1) != VECTOR_CST)
2084     {
2085       rtx arg1r = expand_normal (arg1);
2086       arg1 = make_tree (TREE_TYPE (arg1), arg1r);
2087     }
2088   for (unsigned int i = 0; i < (use_loop_p ? 1 : const_cnt); i++)
2089     {
2090       tree op0, op1, res = NULL_TREE;
2091       if (use_loop_p)
2092         {
2093           tree atype = build_array_type_nelts (eltype, cnt);
2094           op0 = uniform_vector_p (arg0);
2095           if (op0 == NULL_TREE)
2096             {
2097               op0 = fold_build1_loc (loc, VIEW_CONVERT_EXPR, atype, arg0);
2098               op0 = build4_loc (loc, ARRAY_REF, eltype, op0, cntv,
2099                                 NULL_TREE, NULL_TREE);
2100             }
2101           op1 = uniform_vector_p (arg1);
2102           if (op1 == NULL_TREE)
2103             {
2104               op1 = fold_build1_loc (loc, VIEW_CONVERT_EXPR, atype, arg1);
2105               op1 = build4_loc (loc, ARRAY_REF, eltype, op1, cntv,
2106                                 NULL_TREE, NULL_TREE);
2107             }
2108           if (resv)
2109             {
2110               res = fold_build1_loc (loc, VIEW_CONVERT_EXPR, atype, resv);
2111               res = build4_loc (loc, ARRAY_REF, eltype, res, cntv,
2112                                 NULL_TREE, NULL_TREE);
2113             }
2114         }
2115       else
2116         {
2117           tree bitpos = bitsize_int (tree_to_uhwi (sz) * i);
2118           op0 = fold_build3_loc (loc, BIT_FIELD_REF, eltype, arg0, sz, bitpos);
2119           op1 = fold_build3_loc (loc, BIT_FIELD_REF, eltype, arg1, sz, bitpos);
2120           if (resv)
2121             res = fold_build3_loc (loc, BIT_FIELD_REF, eltype, resv, sz,
2122                                    bitpos);
2123         }
2124       switch (code)
2125         {
2126         case PLUS_EXPR:
2127           expand_addsub_overflow (loc, PLUS_EXPR, res, op0, op1,
2128                                   false, false, false, true, &data);
2129           break;
2130         case MINUS_EXPR:
2131           if (use_loop_p ? integer_zerop (arg0) : integer_zerop (op0))
2132             expand_neg_overflow (loc, res, op1, true, &data);
2133           else
2134             expand_addsub_overflow (loc, MINUS_EXPR, res, op0, op1,
2135                                     false, false, false, true, &data);
2136           break;
2137         case MULT_EXPR:
2138           expand_mul_overflow (loc, res, op0, op1, false, false, false,
2139                                true, &data);
2140           break;
2141         default:
2142           gcc_unreachable ();
2143         }
2144     }
2145   if (use_loop_p)
2146     {
2147       struct separate_ops ops;
2148       ops.code = PLUS_EXPR;
2149       ops.type = TREE_TYPE (cntv);
2150       ops.op0 = cntv;
2151       ops.op1 = build_int_cst (TREE_TYPE (cntv), 1);
2152       ops.op2 = NULL_TREE;
2153       ops.location = loc;
2154       rtx ret = expand_expr_real_2 (&ops, cntvar, TYPE_MODE (sizetype),
2155                                     EXPAND_NORMAL);
2156       if (ret != cntvar)
2157         emit_move_insn (cntvar, ret);
2158       rtx cntrtx = gen_int_mode (cnt, TYPE_MODE (sizetype));
2159       do_compare_rtx_and_jump (cntvar, cntrtx, NE, false,
2160                                TYPE_MODE (sizetype), NULL_RTX, NULL, loop_lab,
2161                                profile_probability::very_likely ());
2162     }
2163   if (lhs && resv == NULL_TREE)
2164     {
2165       struct separate_ops ops;
2166       ops.code = code;
2167       ops.type = TREE_TYPE (arg0);
2168       ops.op0 = arg0;
2169       ops.op1 = arg1;
2170       ops.op2 = NULL_TREE;
2171       ops.location = loc;
2172       rtx ret = expand_expr_real_2 (&ops, lhsr, TYPE_MODE (TREE_TYPE (arg0)),
2173                                     EXPAND_NORMAL);
2174       if (ret != lhsr)
2175         emit_move_insn (lhsr, ret);
2176     }
2177   else if (resvr)
2178     emit_move_insn (lhsr, resvr);
2179 }
2180
2181 /* Expand UBSAN_CHECK_ADD call STMT.  */
2182
2183 static void
2184 expand_UBSAN_CHECK_ADD (internal_fn, gcall *stmt)
2185 {
2186   location_t loc = gimple_location (stmt);
2187   tree lhs = gimple_call_lhs (stmt);
2188   tree arg0 = gimple_call_arg (stmt, 0);
2189   tree arg1 = gimple_call_arg (stmt, 1);
2190   if (VECTOR_TYPE_P (TREE_TYPE (arg0)))
2191     expand_vector_ubsan_overflow (loc, PLUS_EXPR, lhs, arg0, arg1);
2192   else
2193     expand_addsub_overflow (loc, PLUS_EXPR, lhs, arg0, arg1,
2194                             false, false, false, true, NULL);
2195 }
2196
2197 /* Expand UBSAN_CHECK_SUB call STMT.  */
2198
2199 static void
2200 expand_UBSAN_CHECK_SUB (internal_fn, gcall *stmt)
2201 {
2202   location_t loc = gimple_location (stmt);
2203   tree lhs = gimple_call_lhs (stmt);
2204   tree arg0 = gimple_call_arg (stmt, 0);
2205   tree arg1 = gimple_call_arg (stmt, 1);
2206   if (VECTOR_TYPE_P (TREE_TYPE (arg0)))
2207     expand_vector_ubsan_overflow (loc, MINUS_EXPR, lhs, arg0, arg1);
2208   else if (integer_zerop (arg0))
2209     expand_neg_overflow (loc, lhs, arg1, true, NULL);
2210   else
2211     expand_addsub_overflow (loc, MINUS_EXPR, lhs, arg0, arg1,
2212                             false, false, false, true, NULL);
2213 }
2214
2215 /* Expand UBSAN_CHECK_MUL call STMT.  */
2216
2217 static void
2218 expand_UBSAN_CHECK_MUL (internal_fn, gcall *stmt)
2219 {
2220   location_t loc = gimple_location (stmt);
2221   tree lhs = gimple_call_lhs (stmt);
2222   tree arg0 = gimple_call_arg (stmt, 0);
2223   tree arg1 = gimple_call_arg (stmt, 1);
2224   if (VECTOR_TYPE_P (TREE_TYPE (arg0)))
2225     expand_vector_ubsan_overflow (loc, MULT_EXPR, lhs, arg0, arg1);
2226   else
2227     expand_mul_overflow (loc, lhs, arg0, arg1, false, false, false, true,
2228                          NULL);
2229 }
2230
2231 /* Helper function for {ADD,SUB,MUL}_OVERFLOW call stmt expansion.  */
2232
2233 static void
2234 expand_arith_overflow (enum tree_code code, gimple *stmt)
2235 {
2236   tree lhs = gimple_call_lhs (stmt);
2237   if (lhs == NULL_TREE)
2238     return;
2239   tree arg0 = gimple_call_arg (stmt, 0);
2240   tree arg1 = gimple_call_arg (stmt, 1);
2241   tree type = TREE_TYPE (TREE_TYPE (lhs));
2242   int uns0_p = TYPE_UNSIGNED (TREE_TYPE (arg0));
2243   int uns1_p = TYPE_UNSIGNED (TREE_TYPE (arg1));
2244   int unsr_p = TYPE_UNSIGNED (type);
2245   int prec0 = TYPE_PRECISION (TREE_TYPE (arg0));
2246   int prec1 = TYPE_PRECISION (TREE_TYPE (arg1));
2247   int precres = TYPE_PRECISION (type);
2248   location_t loc = gimple_location (stmt);
2249   if (!uns0_p && get_range_pos_neg (arg0) == 1)
2250     uns0_p = true;
2251   if (!uns1_p && get_range_pos_neg (arg1) == 1)
2252     uns1_p = true;
2253   int pr = get_min_precision (arg0, uns0_p ? UNSIGNED : SIGNED);
2254   prec0 = MIN (prec0, pr);
2255   pr = get_min_precision (arg1, uns1_p ? UNSIGNED : SIGNED);
2256   prec1 = MIN (prec1, pr);
2257
2258   /* If uns0_p && uns1_p, precop is minimum needed precision
2259      of unsigned type to hold the exact result, otherwise
2260      precop is minimum needed precision of signed type to
2261      hold the exact result.  */
2262   int precop;
2263   if (code == MULT_EXPR)
2264     precop = prec0 + prec1 + (uns0_p != uns1_p);
2265   else
2266     {
2267       if (uns0_p == uns1_p)
2268         precop = MAX (prec0, prec1) + 1;
2269       else if (uns0_p)
2270         precop = MAX (prec0 + 1, prec1) + 1;
2271       else
2272         precop = MAX (prec0, prec1 + 1) + 1;
2273     }
2274   int orig_precres = precres;
2275
2276   do
2277     {
2278       if ((uns0_p && uns1_p)
2279           ? ((precop + !unsr_p) <= precres
2280              /* u1 - u2 -> ur can overflow, no matter what precision
2281                 the result has.  */
2282              && (code != MINUS_EXPR || !unsr_p))
2283           : (!unsr_p && precop <= precres))
2284         {
2285           /* The infinity precision result will always fit into result.  */
2286           rtx target = expand_expr (lhs, NULL_RTX, VOIDmode, EXPAND_WRITE);
2287           write_complex_part (target, const0_rtx, true);
2288           scalar_int_mode mode = SCALAR_INT_TYPE_MODE (type);
2289           struct separate_ops ops;
2290           ops.code = code;
2291           ops.type = type;
2292           ops.op0 = fold_convert_loc (loc, type, arg0);
2293           ops.op1 = fold_convert_loc (loc, type, arg1);
2294           ops.op2 = NULL_TREE;
2295           ops.location = loc;
2296           rtx tem = expand_expr_real_2 (&ops, NULL_RTX, mode, EXPAND_NORMAL);
2297           expand_arith_overflow_result_store (lhs, target, mode, tem);
2298           return;
2299         }
2300
2301       /* For operations with low precision, if target doesn't have them, start
2302          with precres widening right away, otherwise do it only if the most
2303          simple cases can't be used.  */
2304       const int min_precision = targetm.min_arithmetic_precision ();
2305       if (orig_precres == precres && precres < min_precision)
2306         ;
2307       else if ((uns0_p && uns1_p && unsr_p && prec0 <= precres
2308                 && prec1 <= precres)
2309           || ((!uns0_p || !uns1_p) && !unsr_p
2310               && prec0 + uns0_p <= precres
2311               && prec1 + uns1_p <= precres))
2312         {
2313           arg0 = fold_convert_loc (loc, type, arg0);
2314           arg1 = fold_convert_loc (loc, type, arg1);
2315           switch (code)
2316             {
2317             case MINUS_EXPR:
2318               if (integer_zerop (arg0) && !unsr_p)
2319                 {
2320                   expand_neg_overflow (loc, lhs, arg1, false, NULL);
2321                   return;
2322                 }
2323               /* FALLTHRU */
2324             case PLUS_EXPR:
2325               expand_addsub_overflow (loc, code, lhs, arg0, arg1, unsr_p,
2326                                       unsr_p, unsr_p, false, NULL);
2327               return;
2328             case MULT_EXPR:
2329               expand_mul_overflow (loc, lhs, arg0, arg1, unsr_p,
2330                                    unsr_p, unsr_p, false, NULL);
2331               return;
2332             default:
2333               gcc_unreachable ();
2334             }
2335         }
2336
2337       /* For sub-word operations, retry with a wider type first.  */
2338       if (orig_precres == precres && precop <= BITS_PER_WORD)
2339         {
2340           int p = MAX (min_precision, precop);
2341           scalar_int_mode m = smallest_int_mode_for_size (p);
2342           tree optype = build_nonstandard_integer_type (GET_MODE_PRECISION (m),
2343                                                         uns0_p && uns1_p
2344                                                         && unsr_p);
2345           p = TYPE_PRECISION (optype);
2346           if (p > precres)
2347             {
2348               precres = p;
2349               unsr_p = TYPE_UNSIGNED (optype);
2350               type = optype;
2351               continue;
2352             }
2353         }
2354
2355       if (prec0 <= precres && prec1 <= precres)
2356         {
2357           tree types[2];
2358           if (unsr_p)
2359             {
2360               types[0] = build_nonstandard_integer_type (precres, 0);
2361               types[1] = type;
2362             }
2363           else
2364             {
2365               types[0] = type;
2366               types[1] = build_nonstandard_integer_type (precres, 1);
2367             }
2368           arg0 = fold_convert_loc (loc, types[uns0_p], arg0);
2369           arg1 = fold_convert_loc (loc, types[uns1_p], arg1);
2370           if (code != MULT_EXPR)
2371             expand_addsub_overflow (loc, code, lhs, arg0, arg1, unsr_p,
2372                                     uns0_p, uns1_p, false, NULL);
2373           else
2374             expand_mul_overflow (loc, lhs, arg0, arg1, unsr_p,
2375                                  uns0_p, uns1_p, false, NULL);
2376           return;
2377         }
2378
2379       /* Retry with a wider type.  */
2380       if (orig_precres == precres)
2381         {
2382           int p = MAX (prec0, prec1);
2383           scalar_int_mode m = smallest_int_mode_for_size (p);
2384           tree optype = build_nonstandard_integer_type (GET_MODE_PRECISION (m),
2385                                                         uns0_p && uns1_p
2386                                                         && unsr_p);
2387           p = TYPE_PRECISION (optype);
2388           if (p > precres)
2389             {
2390               precres = p;
2391               unsr_p = TYPE_UNSIGNED (optype);
2392               type = optype;
2393               continue;
2394             }
2395         }
2396
2397       gcc_unreachable ();
2398     }
2399   while (1);
2400 }
2401
2402 /* Expand ADD_OVERFLOW STMT.  */
2403
2404 static void
2405 expand_ADD_OVERFLOW (internal_fn, gcall *stmt)
2406 {
2407   expand_arith_overflow (PLUS_EXPR, stmt);
2408 }
2409
2410 /* Expand SUB_OVERFLOW STMT.  */
2411
2412 static void
2413 expand_SUB_OVERFLOW (internal_fn, gcall *stmt)
2414 {
2415   expand_arith_overflow (MINUS_EXPR, stmt);
2416 }
2417
2418 /* Expand MUL_OVERFLOW STMT.  */
2419
2420 static void
2421 expand_MUL_OVERFLOW (internal_fn, gcall *stmt)
2422 {
2423   expand_arith_overflow (MULT_EXPR, stmt);
2424 }
2425
2426 /* This should get folded in tree-vectorizer.c.  */
2427
2428 static void
2429 expand_LOOP_VECTORIZED (internal_fn, gcall *)
2430 {
2431   gcc_unreachable ();
2432 }
2433
2434 /* This should get folded in tree-vectorizer.c.  */
2435
2436 static void
2437 expand_LOOP_DIST_ALIAS (internal_fn, gcall *)
2438 {
2439   gcc_unreachable ();
2440 }
2441
2442 /* Return a memory reference of type TYPE for argument INDEX of STMT.
2443    Use argument INDEX + 1 to derive the second (TBAA) operand.  */
2444
2445 static tree
2446 expand_call_mem_ref (tree type, gcall *stmt, int index)
2447 {
2448   tree addr = gimple_call_arg (stmt, index);
2449   tree alias_ptr_type = TREE_TYPE (gimple_call_arg (stmt, index + 1));
2450   unsigned int align = tree_to_shwi (gimple_call_arg (stmt, index + 1));
2451   if (TYPE_ALIGN (type) != align)
2452     type = build_aligned_type (type, align);
2453
2454   tree tmp = addr;
2455   if (TREE_CODE (tmp) == SSA_NAME)
2456     {
2457       gimple *def = SSA_NAME_DEF_STMT (tmp);
2458       if (gimple_assign_single_p (def))
2459         tmp = gimple_assign_rhs1 (def);
2460     }
2461
2462   if (TREE_CODE (tmp) == ADDR_EXPR)
2463     {
2464       tree mem = TREE_OPERAND (tmp, 0);
2465       if (TREE_CODE (mem) == TARGET_MEM_REF
2466           && types_compatible_p (TREE_TYPE (mem), type))
2467         {
2468           tree offset = TMR_OFFSET (mem);
2469           if (type != TREE_TYPE (mem)
2470               || alias_ptr_type != TREE_TYPE (offset)
2471               || !integer_zerop (offset))
2472             {
2473               mem = copy_node (mem);
2474               TMR_OFFSET (mem) = wide_int_to_tree (alias_ptr_type,
2475                                                    wi::to_poly_wide (offset));
2476               TREE_TYPE (mem) = type;
2477             }
2478           return mem;
2479         }
2480     }
2481
2482   return fold_build2 (MEM_REF, type, addr, build_int_cst (alias_ptr_type, 0));
2483 }
2484
2485 /* Expand MASK_LOAD{,_LANES} call STMT using optab OPTAB.  */
2486
2487 static void
2488 expand_mask_load_optab_fn (internal_fn, gcall *stmt, convert_optab optab)
2489 {
2490   struct expand_operand ops[3];
2491   tree type, lhs, rhs, maskt;
2492   rtx mem, target, mask;
2493   insn_code icode;
2494
2495   maskt = gimple_call_arg (stmt, 2);
2496   lhs = gimple_call_lhs (stmt);
2497   if (lhs == NULL_TREE)
2498     return;
2499   type = TREE_TYPE (lhs);
2500   rhs = expand_call_mem_ref (type, stmt, 0);
2501
2502   if (optab == vec_mask_load_lanes_optab)
2503     icode = get_multi_vector_move (type, optab);
2504   else
2505     icode = convert_optab_handler (optab, TYPE_MODE (type),
2506                                    TYPE_MODE (TREE_TYPE (maskt)));
2507
2508   mem = expand_expr (rhs, NULL_RTX, VOIDmode, EXPAND_WRITE);
2509   gcc_assert (MEM_P (mem));
2510   mask = expand_normal (maskt);
2511   target = expand_expr (lhs, NULL_RTX, VOIDmode, EXPAND_WRITE);
2512   create_output_operand (&ops[0], target, TYPE_MODE (type));
2513   create_fixed_operand (&ops[1], mem);
2514   create_input_operand (&ops[2], mask, TYPE_MODE (TREE_TYPE (maskt)));
2515   expand_insn (icode, 3, ops);
2516 }
2517
2518 #define expand_mask_load_lanes_optab_fn expand_mask_load_optab_fn
2519
2520 /* Expand MASK_STORE{,_LANES} call STMT using optab OPTAB.  */
2521
2522 static void
2523 expand_mask_store_optab_fn (internal_fn, gcall *stmt, convert_optab optab)
2524 {
2525   struct expand_operand ops[3];
2526   tree type, lhs, rhs, maskt;
2527   rtx mem, reg, mask;
2528   insn_code icode;
2529
2530   maskt = gimple_call_arg (stmt, 2);
2531   rhs = gimple_call_arg (stmt, 3);
2532   type = TREE_TYPE (rhs);
2533   lhs = expand_call_mem_ref (type, stmt, 0);
2534
2535   if (optab == vec_mask_store_lanes_optab)
2536     icode = get_multi_vector_move (type, optab);
2537   else
2538     icode = convert_optab_handler (optab, TYPE_MODE (type),
2539                                    TYPE_MODE (TREE_TYPE (maskt)));
2540
2541   mem = expand_expr (lhs, NULL_RTX, VOIDmode, EXPAND_WRITE);
2542   gcc_assert (MEM_P (mem));
2543   mask = expand_normal (maskt);
2544   reg = expand_normal (rhs);
2545   create_fixed_operand (&ops[0], mem);
2546   create_input_operand (&ops[1], reg, TYPE_MODE (type));
2547   create_input_operand (&ops[2], mask, TYPE_MODE (TREE_TYPE (maskt)));
2548   expand_insn (icode, 3, ops);
2549 }
2550
2551 #define expand_mask_store_lanes_optab_fn expand_mask_store_optab_fn
2552
2553 static void
2554 expand_ABNORMAL_DISPATCHER (internal_fn, gcall *)
2555 {
2556 }
2557
2558 static void
2559 expand_BUILTIN_EXPECT (internal_fn, gcall *stmt)
2560 {
2561   /* When guessing was done, the hints should be already stripped away.  */
2562   gcc_assert (!flag_guess_branch_prob || optimize == 0 || seen_error ());
2563
2564   rtx target;
2565   tree lhs = gimple_call_lhs (stmt);
2566   if (lhs)
2567     target = expand_expr (lhs, NULL_RTX, VOIDmode, EXPAND_WRITE);
2568   else
2569     target = const0_rtx;
2570   rtx val = expand_expr (gimple_call_arg (stmt, 0), target, VOIDmode, EXPAND_NORMAL);
2571   if (lhs && val != target)
2572     emit_move_insn (target, val);
2573 }
2574
2575 /* IFN_VA_ARG is supposed to be expanded at pass_stdarg.  So this dummy function
2576    should never be called.  */
2577
2578 static void
2579 expand_VA_ARG (internal_fn, gcall *)
2580 {
2581   gcc_unreachable ();
2582 }
2583
2584 /* Expand the IFN_UNIQUE function according to its first argument.  */
2585
2586 static void
2587 expand_UNIQUE (internal_fn, gcall *stmt)
2588 {
2589   rtx pattern = NULL_RTX;
2590   enum ifn_unique_kind kind
2591     = (enum ifn_unique_kind) TREE_INT_CST_LOW (gimple_call_arg (stmt, 0));
2592
2593   switch (kind)
2594     {
2595     default:
2596       gcc_unreachable ();
2597
2598     case IFN_UNIQUE_UNSPEC:
2599       if (targetm.have_unique ())
2600         pattern = targetm.gen_unique ();
2601       break;
2602
2603     case IFN_UNIQUE_OACC_FORK:
2604     case IFN_UNIQUE_OACC_JOIN:
2605       if (targetm.have_oacc_fork () && targetm.have_oacc_join ())
2606         {
2607           tree lhs = gimple_call_lhs (stmt);
2608           rtx target = const0_rtx;
2609
2610           if (lhs)
2611             target = expand_expr (lhs, NULL_RTX, VOIDmode, EXPAND_WRITE);
2612
2613           rtx data_dep = expand_normal (gimple_call_arg (stmt, 1));
2614           rtx axis = expand_normal (gimple_call_arg (stmt, 2));
2615
2616           if (kind == IFN_UNIQUE_OACC_FORK)
2617             pattern = targetm.gen_oacc_fork (target, data_dep, axis);
2618           else
2619             pattern = targetm.gen_oacc_join (target, data_dep, axis);
2620         }
2621       else
2622         gcc_unreachable ();
2623       break;
2624     }
2625
2626   if (pattern)
2627     emit_insn (pattern);
2628 }
2629
2630 /* The size of an OpenACC compute dimension.  */
2631
2632 static void
2633 expand_GOACC_DIM_SIZE (internal_fn, gcall *stmt)
2634 {
2635   tree lhs = gimple_call_lhs (stmt);
2636
2637   if (!lhs)
2638     return;
2639
2640   rtx target = expand_expr (lhs, NULL_RTX, VOIDmode, EXPAND_WRITE);
2641   if (targetm.have_oacc_dim_size ())
2642     {
2643       rtx dim = expand_expr (gimple_call_arg (stmt, 0), NULL_RTX,
2644                              VOIDmode, EXPAND_NORMAL);
2645       emit_insn (targetm.gen_oacc_dim_size (target, dim));
2646     }
2647   else
2648     emit_move_insn (target, GEN_INT (1));
2649 }
2650
2651 /* The position of an OpenACC execution engine along one compute axis.  */
2652
2653 static void
2654 expand_GOACC_DIM_POS (internal_fn, gcall *stmt)
2655 {
2656   tree lhs = gimple_call_lhs (stmt);
2657
2658   if (!lhs)
2659     return;
2660
2661   rtx target = expand_expr (lhs, NULL_RTX, VOIDmode, EXPAND_WRITE);
2662   if (targetm.have_oacc_dim_pos ())
2663     {
2664       rtx dim = expand_expr (gimple_call_arg (stmt, 0), NULL_RTX,
2665                              VOIDmode, EXPAND_NORMAL);
2666       emit_insn (targetm.gen_oacc_dim_pos (target, dim));
2667     }
2668   else
2669     emit_move_insn (target, const0_rtx);
2670 }
2671
2672 /* This is expanded by oacc_device_lower pass.  */
2673
2674 static void
2675 expand_GOACC_LOOP (internal_fn, gcall *)
2676 {
2677   gcc_unreachable ();
2678 }
2679
2680 /* This is expanded by oacc_device_lower pass.  */
2681
2682 static void
2683 expand_GOACC_REDUCTION (internal_fn, gcall *)
2684 {
2685   gcc_unreachable ();
2686 }
2687
2688 /* This is expanded by oacc_device_lower pass.  */
2689
2690 static void
2691 expand_GOACC_TILE (internal_fn, gcall *)
2692 {
2693   gcc_unreachable ();
2694 }
2695
2696 /* Set errno to EDOM.  */
2697
2698 static void
2699 expand_SET_EDOM (internal_fn, gcall *)
2700 {
2701 #ifdef TARGET_EDOM
2702 #ifdef GEN_ERRNO_RTX
2703   rtx errno_rtx = GEN_ERRNO_RTX;
2704 #else
2705   rtx errno_rtx = gen_rtx_MEM (word_mode, gen_rtx_SYMBOL_REF (Pmode, "errno"));
2706 #endif
2707   emit_move_insn (errno_rtx,
2708                   gen_int_mode (TARGET_EDOM, GET_MODE (errno_rtx)));
2709 #else
2710   gcc_unreachable ();
2711 #endif
2712 }
2713
2714 /* Expand atomic bit test and set.  */
2715
2716 static void
2717 expand_ATOMIC_BIT_TEST_AND_SET (internal_fn, gcall *call)
2718 {
2719   expand_ifn_atomic_bit_test_and (call);
2720 }
2721
2722 /* Expand atomic bit test and complement.  */
2723
2724 static void
2725 expand_ATOMIC_BIT_TEST_AND_COMPLEMENT (internal_fn, gcall *call)
2726 {
2727   expand_ifn_atomic_bit_test_and (call);
2728 }
2729
2730 /* Expand atomic bit test and reset.  */
2731
2732 static void
2733 expand_ATOMIC_BIT_TEST_AND_RESET (internal_fn, gcall *call)
2734 {
2735   expand_ifn_atomic_bit_test_and (call);
2736 }
2737
2738 /* Expand atomic bit test and set.  */
2739
2740 static void
2741 expand_ATOMIC_COMPARE_EXCHANGE (internal_fn, gcall *call)
2742 {
2743   expand_ifn_atomic_compare_exchange (call);
2744 }
2745
2746 /* Expand LAUNDER to assignment, lhs = arg0.  */
2747
2748 static void
2749 expand_LAUNDER (internal_fn, gcall *call)
2750 {
2751   tree lhs = gimple_call_lhs (call);
2752
2753   if (!lhs)
2754     return;
2755
2756   expand_assignment (lhs, gimple_call_arg (call, 0), false);
2757 }
2758
2759 /* Expand {MASK_,}SCATTER_STORE{S,U} call CALL using optab OPTAB.  */
2760
2761 static void
2762 expand_scatter_store_optab_fn (internal_fn, gcall *stmt, direct_optab optab)
2763 {
2764   internal_fn ifn = gimple_call_internal_fn (stmt);
2765   int rhs_index = internal_fn_stored_value_index (ifn);
2766   int mask_index = internal_fn_mask_index (ifn);
2767   tree base = gimple_call_arg (stmt, 0);
2768   tree offset = gimple_call_arg (stmt, 1);
2769   tree scale = gimple_call_arg (stmt, 2);
2770   tree rhs = gimple_call_arg (stmt, rhs_index);
2771
2772   rtx base_rtx = expand_normal (base);
2773   rtx offset_rtx = expand_normal (offset);
2774   HOST_WIDE_INT scale_int = tree_to_shwi (scale);
2775   rtx rhs_rtx = expand_normal (rhs);
2776
2777   struct expand_operand ops[6];
2778   int i = 0;
2779   create_address_operand (&ops[i++], base_rtx);
2780   create_input_operand (&ops[i++], offset_rtx, TYPE_MODE (TREE_TYPE (offset)));
2781   create_integer_operand (&ops[i++], TYPE_UNSIGNED (TREE_TYPE (offset)));
2782   create_integer_operand (&ops[i++], scale_int);
2783   create_input_operand (&ops[i++], rhs_rtx, TYPE_MODE (TREE_TYPE (rhs)));
2784   if (mask_index >= 0)
2785     {
2786       tree mask = gimple_call_arg (stmt, mask_index);
2787       rtx mask_rtx = expand_normal (mask);
2788       create_input_operand (&ops[i++], mask_rtx, TYPE_MODE (TREE_TYPE (mask)));
2789     }
2790
2791   insn_code icode = direct_optab_handler (optab, TYPE_MODE (TREE_TYPE (rhs)));
2792   expand_insn (icode, i, ops);
2793 }
2794
2795 /* Expand {MASK_,}GATHER_LOAD call CALL using optab OPTAB.  */
2796
2797 static void
2798 expand_gather_load_optab_fn (internal_fn, gcall *stmt, direct_optab optab)
2799 {
2800   tree lhs = gimple_call_lhs (stmt);
2801   tree base = gimple_call_arg (stmt, 0);
2802   tree offset = gimple_call_arg (stmt, 1);
2803   tree scale = gimple_call_arg (stmt, 2);
2804
2805   rtx lhs_rtx = expand_expr (lhs, NULL_RTX, VOIDmode, EXPAND_WRITE);
2806   rtx base_rtx = expand_normal (base);
2807   rtx offset_rtx = expand_normal (offset);
2808   HOST_WIDE_INT scale_int = tree_to_shwi (scale);
2809
2810   int i = 0;
2811   struct expand_operand ops[6];
2812   create_output_operand (&ops[i++], lhs_rtx, TYPE_MODE (TREE_TYPE (lhs)));
2813   create_address_operand (&ops[i++], base_rtx);
2814   create_input_operand (&ops[i++], offset_rtx, TYPE_MODE (TREE_TYPE (offset)));
2815   create_integer_operand (&ops[i++], TYPE_UNSIGNED (TREE_TYPE (offset)));
2816   create_integer_operand (&ops[i++], scale_int);
2817   if (optab == mask_gather_load_optab)
2818     {
2819       tree mask = gimple_call_arg (stmt, 3);
2820       rtx mask_rtx = expand_normal (mask);
2821       create_input_operand (&ops[i++], mask_rtx, TYPE_MODE (TREE_TYPE (mask)));
2822     }
2823   insn_code icode = direct_optab_handler (optab, TYPE_MODE (TREE_TYPE (lhs)));
2824   expand_insn (icode, i, ops);
2825 }
2826
2827 /* Expand DIVMOD() using:
2828  a) optab handler for udivmod/sdivmod if it is available.
2829  b) If optab_handler doesn't exist, generate call to
2830     target-specific divmod libfunc.  */
2831
2832 static void
2833 expand_DIVMOD (internal_fn, gcall *call_stmt)
2834 {
2835   tree lhs = gimple_call_lhs (call_stmt);
2836   tree arg0 = gimple_call_arg (call_stmt, 0);
2837   tree arg1 = gimple_call_arg (call_stmt, 1);
2838
2839   gcc_assert (TREE_CODE (TREE_TYPE (lhs)) == COMPLEX_TYPE);
2840   tree type = TREE_TYPE (TREE_TYPE (lhs));
2841   machine_mode mode = TYPE_MODE (type);
2842   bool unsignedp = TYPE_UNSIGNED (type);
2843   optab tab = (unsignedp) ? udivmod_optab : sdivmod_optab;
2844
2845   rtx op0 = expand_normal (arg0);
2846   rtx op1 = expand_normal (arg1);
2847   rtx target = expand_expr (lhs, NULL_RTX, VOIDmode, EXPAND_WRITE);
2848
2849   rtx quotient, remainder, libfunc;
2850
2851   /* Check if optab_handler exists for divmod_optab for given mode.  */
2852   if (optab_handler (tab, mode) != CODE_FOR_nothing)
2853     {
2854       quotient = gen_reg_rtx (mode);
2855       remainder = gen_reg_rtx (mode);
2856       expand_twoval_binop (tab, op0, op1, quotient, remainder, unsignedp);
2857     }
2858
2859   /* Generate call to divmod libfunc if it exists.  */
2860   else if ((libfunc = optab_libfunc (tab, mode)) != NULL_RTX)
2861     targetm.expand_divmod_libfunc (libfunc, mode, op0, op1,
2862                                    &quotient, &remainder);
2863
2864   else
2865     gcc_unreachable ();
2866
2867   /* Wrap the return value (quotient, remainder) within COMPLEX_EXPR.  */
2868   expand_expr (build2 (COMPLEX_EXPR, TREE_TYPE (lhs),
2869                        make_tree (TREE_TYPE (arg0), quotient),
2870                        make_tree (TREE_TYPE (arg1), remainder)),
2871                target, VOIDmode, EXPAND_NORMAL);
2872 }
2873
2874 /* Expand a NOP.  */
2875
2876 static void
2877 expand_NOP (internal_fn, gcall *)
2878 {
2879   /* Nothing.  But it shouldn't really prevail.  */
2880 }
2881
2882 /* Expand a call to FN using the operands in STMT.  FN has a single
2883    output operand and NARGS input operands.  */
2884
2885 static void
2886 expand_direct_optab_fn (internal_fn fn, gcall *stmt, direct_optab optab,
2887                         unsigned int nargs)
2888 {
2889   expand_operand *ops = XALLOCAVEC (expand_operand, nargs + 1);
2890
2891   tree_pair types = direct_internal_fn_types (fn, stmt);
2892   insn_code icode = direct_optab_handler (optab, TYPE_MODE (types.first));
2893   gcc_assert (icode != CODE_FOR_nothing);
2894
2895   tree lhs = gimple_call_lhs (stmt);
2896   rtx lhs_rtx = NULL_RTX;
2897   if (lhs)
2898     lhs_rtx = expand_expr (lhs, NULL_RTX, VOIDmode, EXPAND_WRITE);
2899
2900   /* Do not assign directly to a promoted subreg, since there is no
2901      guarantee that the instruction will leave the upper bits of the
2902      register in the state required by SUBREG_PROMOTED_SIGN.  */
2903   rtx dest = lhs_rtx;
2904   if (dest && GET_CODE (dest) == SUBREG && SUBREG_PROMOTED_VAR_P (dest))
2905     dest = NULL_RTX;
2906
2907   create_output_operand (&ops[0], dest, insn_data[icode].operand[0].mode);
2908
2909   for (unsigned int i = 0; i < nargs; ++i)
2910     {
2911       tree rhs = gimple_call_arg (stmt, i);
2912       tree rhs_type = TREE_TYPE (rhs);
2913       rtx rhs_rtx = expand_normal (rhs);
2914       if (INTEGRAL_TYPE_P (rhs_type))
2915         create_convert_operand_from (&ops[i + 1], rhs_rtx,
2916                                      TYPE_MODE (rhs_type),
2917                                      TYPE_UNSIGNED (rhs_type));
2918       else
2919         create_input_operand (&ops[i + 1], rhs_rtx, TYPE_MODE (rhs_type));
2920     }
2921
2922   expand_insn (icode, nargs + 1, ops);
2923   if (lhs_rtx && !rtx_equal_p (lhs_rtx, ops[0].value))
2924     {
2925       /* If the return value has an integral type, convert the instruction
2926          result to that type.  This is useful for things that return an
2927          int regardless of the size of the input.  If the instruction result
2928          is smaller than required, assume that it is signed.
2929
2930          If the return value has a nonintegral type, its mode must match
2931          the instruction result.  */
2932       if (GET_CODE (lhs_rtx) == SUBREG && SUBREG_PROMOTED_VAR_P (lhs_rtx))
2933         {
2934           /* If this is a scalar in a register that is stored in a wider
2935              mode than the declared mode, compute the result into its
2936              declared mode and then convert to the wider mode.  */
2937           gcc_checking_assert (INTEGRAL_TYPE_P (TREE_TYPE (lhs)));
2938           rtx tmp = convert_to_mode (GET_MODE (lhs_rtx), ops[0].value, 0);
2939           convert_move (SUBREG_REG (lhs_rtx), tmp,
2940                         SUBREG_PROMOTED_SIGN (lhs_rtx));
2941         }
2942       else if (GET_MODE (lhs_rtx) == GET_MODE (ops[0].value))
2943         emit_move_insn (lhs_rtx, ops[0].value);
2944       else
2945         {
2946           gcc_checking_assert (INTEGRAL_TYPE_P (TREE_TYPE (lhs)));
2947           convert_move (lhs_rtx, ops[0].value, 0);
2948         }
2949     }
2950 }
2951
2952 /* Expand WHILE_ULT call STMT using optab OPTAB.  */
2953
2954 static void
2955 expand_while_optab_fn (internal_fn, gcall *stmt, convert_optab optab)
2956 {
2957   expand_operand ops[3];
2958   tree rhs_type[2];
2959
2960   tree lhs = gimple_call_lhs (stmt);
2961   tree lhs_type = TREE_TYPE (lhs);
2962   rtx lhs_rtx = expand_expr (lhs, NULL_RTX, VOIDmode, EXPAND_WRITE);
2963   create_output_operand (&ops[0], lhs_rtx, TYPE_MODE (lhs_type));
2964
2965   for (unsigned int i = 0; i < 2; ++i)
2966     {
2967       tree rhs = gimple_call_arg (stmt, i);
2968       rhs_type[i] = TREE_TYPE (rhs);
2969       rtx rhs_rtx = expand_normal (rhs);
2970       create_input_operand (&ops[i + 1], rhs_rtx, TYPE_MODE (rhs_type[i]));
2971     }
2972
2973   insn_code icode = convert_optab_handler (optab, TYPE_MODE (rhs_type[0]),
2974                                            TYPE_MODE (lhs_type));
2975
2976   expand_insn (icode, 3, ops);
2977   if (!rtx_equal_p (lhs_rtx, ops[0].value))
2978     emit_move_insn (lhs_rtx, ops[0].value);
2979 }
2980
2981 /* Expanders for optabs that can use expand_direct_optab_fn.  */
2982
2983 #define expand_unary_optab_fn(FN, STMT, OPTAB) \
2984   expand_direct_optab_fn (FN, STMT, OPTAB, 1)
2985
2986 #define expand_binary_optab_fn(FN, STMT, OPTAB) \
2987   expand_direct_optab_fn (FN, STMT, OPTAB, 2)
2988
2989 #define expand_ternary_optab_fn(FN, STMT, OPTAB) \
2990   expand_direct_optab_fn (FN, STMT, OPTAB, 3)
2991
2992 #define expand_cond_unary_optab_fn(FN, STMT, OPTAB) \
2993   expand_direct_optab_fn (FN, STMT, OPTAB, 3)
2994
2995 #define expand_cond_binary_optab_fn(FN, STMT, OPTAB) \
2996   expand_direct_optab_fn (FN, STMT, OPTAB, 4)
2997
2998 #define expand_cond_ternary_optab_fn(FN, STMT, OPTAB) \
2999   expand_direct_optab_fn (FN, STMT, OPTAB, 5)
3000
3001 #define expand_fold_extract_optab_fn(FN, STMT, OPTAB) \
3002   expand_direct_optab_fn (FN, STMT, OPTAB, 3)
3003
3004 #define expand_fold_left_optab_fn(FN, STMT, OPTAB) \
3005   expand_direct_optab_fn (FN, STMT, OPTAB, 2)
3006
3007 /* RETURN_TYPE and ARGS are a return type and argument list that are
3008    in principle compatible with FN (which satisfies direct_internal_fn_p).
3009    Return the types that should be used to determine whether the
3010    target supports FN.  */
3011
3012 tree_pair
3013 direct_internal_fn_types (internal_fn fn, tree return_type, tree *args)
3014 {
3015   const direct_internal_fn_info &info = direct_internal_fn (fn);
3016   tree type0 = (info.type0 < 0 ? return_type : TREE_TYPE (args[info.type0]));
3017   tree type1 = (info.type1 < 0 ? return_type : TREE_TYPE (args[info.type1]));
3018   return tree_pair (type0, type1);
3019 }
3020
3021 /* CALL is a call whose return type and arguments are in principle
3022    compatible with FN (which satisfies direct_internal_fn_p).  Return the
3023    types that should be used to determine whether the target supports FN.  */
3024
3025 tree_pair
3026 direct_internal_fn_types (internal_fn fn, gcall *call)
3027 {
3028   const direct_internal_fn_info &info = direct_internal_fn (fn);
3029   tree op0 = (info.type0 < 0
3030               ? gimple_call_lhs (call)
3031               : gimple_call_arg (call, info.type0));
3032   tree op1 = (info.type1 < 0
3033               ? gimple_call_lhs (call)
3034               : gimple_call_arg (call, info.type1));
3035   return tree_pair (TREE_TYPE (op0), TREE_TYPE (op1));
3036 }
3037
3038 /* Return true if OPTAB is supported for TYPES (whose modes should be
3039    the same) when the optimization type is OPT_TYPE.  Used for simple
3040    direct optabs.  */
3041
3042 static bool
3043 direct_optab_supported_p (direct_optab optab, tree_pair types,
3044                           optimization_type opt_type)
3045 {
3046   machine_mode mode = TYPE_MODE (types.first);
3047   gcc_checking_assert (mode == TYPE_MODE (types.second));
3048   return direct_optab_handler (optab, mode, opt_type) != CODE_FOR_nothing;
3049 }
3050
3051 /* Return true if OPTAB is supported for TYPES, where the first type
3052    is the destination and the second type is the source.  Used for
3053    convert optabs.  */
3054
3055 static bool
3056 convert_optab_supported_p (convert_optab optab, tree_pair types,
3057                            optimization_type opt_type)
3058 {
3059   return (convert_optab_handler (optab, TYPE_MODE (types.first),
3060                                  TYPE_MODE (types.second), opt_type)
3061           != CODE_FOR_nothing);
3062 }
3063
3064 /* Return true if load/store lanes optab OPTAB is supported for
3065    array type TYPES.first when the optimization type is OPT_TYPE.  */
3066
3067 static bool
3068 multi_vector_optab_supported_p (convert_optab optab, tree_pair types,
3069                                 optimization_type opt_type)
3070 {
3071   gcc_assert (TREE_CODE (types.first) == ARRAY_TYPE);
3072   machine_mode imode = TYPE_MODE (types.first);
3073   machine_mode vmode = TYPE_MODE (TREE_TYPE (types.first));
3074   return (convert_optab_handler (optab, imode, vmode, opt_type)
3075           != CODE_FOR_nothing);
3076 }
3077
3078 #define direct_unary_optab_supported_p direct_optab_supported_p
3079 #define direct_binary_optab_supported_p direct_optab_supported_p
3080 #define direct_ternary_optab_supported_p direct_optab_supported_p
3081 #define direct_cond_unary_optab_supported_p direct_optab_supported_p
3082 #define direct_cond_binary_optab_supported_p direct_optab_supported_p
3083 #define direct_cond_ternary_optab_supported_p direct_optab_supported_p
3084 #define direct_mask_load_optab_supported_p direct_optab_supported_p
3085 #define direct_load_lanes_optab_supported_p multi_vector_optab_supported_p
3086 #define direct_mask_load_lanes_optab_supported_p multi_vector_optab_supported_p
3087 #define direct_gather_load_optab_supported_p direct_optab_supported_p
3088 #define direct_mask_store_optab_supported_p direct_optab_supported_p
3089 #define direct_store_lanes_optab_supported_p multi_vector_optab_supported_p
3090 #define direct_mask_store_lanes_optab_supported_p multi_vector_optab_supported_p
3091 #define direct_scatter_store_optab_supported_p direct_optab_supported_p
3092 #define direct_while_optab_supported_p convert_optab_supported_p
3093 #define direct_fold_extract_optab_supported_p direct_optab_supported_p
3094 #define direct_fold_left_optab_supported_p direct_optab_supported_p
3095
3096 /* Return the optab used by internal function FN.  */
3097
3098 static optab
3099 direct_internal_fn_optab (internal_fn fn, tree_pair types)
3100 {
3101   switch (fn)
3102     {
3103 #define DEF_INTERNAL_FN(CODE, FLAGS, FNSPEC) \
3104     case IFN_##CODE: break;
3105 #define DEF_INTERNAL_OPTAB_FN(CODE, FLAGS, OPTAB, TYPE) \
3106     case IFN_##CODE: return OPTAB##_optab;
3107 #define DEF_INTERNAL_SIGNED_OPTAB_FN(CODE, FLAGS, SELECTOR, SIGNED_OPTAB, \
3108                                      UNSIGNED_OPTAB, TYPE)              \
3109     case IFN_##CODE: return (TYPE_UNSIGNED (types.SELECTOR)             \
3110                              ? UNSIGNED_OPTAB ## _optab                 \
3111                              : SIGNED_OPTAB ## _optab);
3112 #include "internal-fn.def"
3113
3114     case IFN_LAST:
3115       break;
3116     }
3117   gcc_unreachable ();
3118 }
3119
3120 /* Return the optab used by internal function FN.  */
3121
3122 static optab
3123 direct_internal_fn_optab (internal_fn fn)
3124 {
3125   switch (fn)
3126     {
3127 #define DEF_INTERNAL_FN(CODE, FLAGS, FNSPEC) \
3128     case IFN_##CODE: break;
3129 #define DEF_INTERNAL_OPTAB_FN(CODE, FLAGS, OPTAB, TYPE) \
3130     case IFN_##CODE: return OPTAB##_optab;
3131 #include "internal-fn.def"
3132
3133     case IFN_LAST:
3134       break;
3135     }
3136   gcc_unreachable ();
3137 }
3138
3139 /* Return true if FN is supported for the types in TYPES when the
3140    optimization type is OPT_TYPE.  The types are those associated with
3141    the "type0" and "type1" fields of FN's direct_internal_fn_info
3142    structure.  */
3143
3144 bool
3145 direct_internal_fn_supported_p (internal_fn fn, tree_pair types,
3146                                 optimization_type opt_type)
3147 {
3148   switch (fn)
3149     {
3150 #define DEF_INTERNAL_FN(CODE, FLAGS, FNSPEC) \
3151     case IFN_##CODE: break;
3152 #define DEF_INTERNAL_OPTAB_FN(CODE, FLAGS, OPTAB, TYPE) \
3153     case IFN_##CODE: \
3154       return direct_##TYPE##_optab_supported_p (OPTAB##_optab, types, \
3155                                                 opt_type);
3156 #define DEF_INTERNAL_SIGNED_OPTAB_FN(CODE, FLAGS, SELECTOR, SIGNED_OPTAB, \
3157                                      UNSIGNED_OPTAB, TYPE)              \
3158     case IFN_##CODE:                                                    \
3159       {                                                                 \
3160         optab which_optab = (TYPE_UNSIGNED (types.SELECTOR)             \
3161                              ? UNSIGNED_OPTAB ## _optab                 \
3162                              : SIGNED_OPTAB ## _optab);                 \
3163         return direct_##TYPE##_optab_supported_p (which_optab, types,   \
3164                                                   opt_type);            \
3165       }
3166 #include "internal-fn.def"
3167
3168     case IFN_LAST:
3169       break;
3170     }
3171   gcc_unreachable ();
3172 }
3173
3174 /* Return true if FN is supported for type TYPE when the optimization
3175    type is OPT_TYPE.  The caller knows that the "type0" and "type1"
3176    fields of FN's direct_internal_fn_info structure are the same.  */
3177
3178 bool
3179 direct_internal_fn_supported_p (internal_fn fn, tree type,
3180                                 optimization_type opt_type)
3181 {
3182   const direct_internal_fn_info &info = direct_internal_fn (fn);
3183   gcc_checking_assert (info.type0 == info.type1);
3184   return direct_internal_fn_supported_p (fn, tree_pair (type, type), opt_type);
3185 }
3186
3187 /* Return true if the STMT is supported when the optimization type is OPT_TYPE,
3188    given that STMT is a call to a direct internal function.  */
3189
3190 bool
3191 direct_internal_fn_supported_p (gcall *stmt, optimization_type opt_type)
3192 {
3193   internal_fn fn = gimple_call_internal_fn (stmt);
3194   tree_pair types = direct_internal_fn_types (fn, stmt);
3195   return direct_internal_fn_supported_p (fn, types, opt_type);
3196 }
3197
3198 /* If FN is commutative in two consecutive arguments, return the
3199    index of the first, otherwise return -1.  */
3200
3201 int
3202 first_commutative_argument (internal_fn fn)
3203 {
3204   switch (fn)
3205     {
3206     case IFN_FMA:
3207     case IFN_FMS:
3208     case IFN_FNMA:
3209     case IFN_FNMS:
3210     case IFN_AVG_FLOOR:
3211     case IFN_AVG_CEIL:
3212     case IFN_FMIN:
3213     case IFN_FMAX:
3214       return 0;
3215
3216     case IFN_COND_ADD:
3217     case IFN_COND_MUL:
3218     case IFN_COND_MIN:
3219     case IFN_COND_MAX:
3220     case IFN_COND_AND:
3221     case IFN_COND_IOR:
3222     case IFN_COND_XOR:
3223     case IFN_COND_FMA:
3224     case IFN_COND_FMS:
3225     case IFN_COND_FNMA:
3226     case IFN_COND_FNMS:
3227       return 1;
3228
3229     default:
3230       return -1;
3231     }
3232 }
3233
3234 /* Return true if IFN_SET_EDOM is supported.  */
3235
3236 bool
3237 set_edom_supported_p (void)
3238 {
3239 #ifdef TARGET_EDOM
3240   return true;
3241 #else
3242   return false;
3243 #endif
3244 }
3245
3246 #define DEF_INTERNAL_OPTAB_FN(CODE, FLAGS, OPTAB, TYPE) \
3247   static void                                           \
3248   expand_##CODE (internal_fn fn, gcall *stmt)           \
3249   {                                                     \
3250     expand_##TYPE##_optab_fn (fn, stmt, OPTAB##_optab); \
3251   }
3252 #define DEF_INTERNAL_SIGNED_OPTAB_FN(CODE, FLAGS, SELECTOR, SIGNED_OPTAB, \
3253                                      UNSIGNED_OPTAB, TYPE)              \
3254   static void                                                           \
3255   expand_##CODE (internal_fn fn, gcall *stmt)                           \
3256   {                                                                     \
3257     tree_pair types = direct_internal_fn_types (fn, stmt);              \
3258     optab which_optab = direct_internal_fn_optab (fn, types);           \
3259     expand_##TYPE##_optab_fn (fn, stmt, which_optab);                   \
3260   }
3261 #include "internal-fn.def"
3262
3263 /* Routines to expand each internal function, indexed by function number.
3264    Each routine has the prototype:
3265
3266        expand_<NAME> (gcall *stmt)
3267
3268    where STMT is the statement that performs the call. */
3269 static void (*const internal_fn_expanders[]) (internal_fn, gcall *) = {
3270 #define DEF_INTERNAL_FN(CODE, FLAGS, FNSPEC) expand_##CODE,
3271 #include "internal-fn.def"
3272   0
3273 };
3274
3275 /* Invoke T(CODE, IFN) for each conditional function IFN that maps to a
3276    tree code CODE.  */
3277 #define FOR_EACH_CODE_MAPPING(T) \
3278   T (PLUS_EXPR, IFN_COND_ADD) \
3279   T (MINUS_EXPR, IFN_COND_SUB) \
3280   T (MULT_EXPR, IFN_COND_MUL) \
3281   T (TRUNC_DIV_EXPR, IFN_COND_DIV) \
3282   T (TRUNC_MOD_EXPR, IFN_COND_MOD) \
3283   T (RDIV_EXPR, IFN_COND_RDIV) \
3284   T (MIN_EXPR, IFN_COND_MIN) \
3285   T (MAX_EXPR, IFN_COND_MAX) \
3286   T (BIT_AND_EXPR, IFN_COND_AND) \
3287   T (BIT_IOR_EXPR, IFN_COND_IOR) \
3288   T (BIT_XOR_EXPR, IFN_COND_XOR)
3289
3290 /* Return a function that only performs CODE when a certain condition is met
3291    and that uses a given fallback value otherwise.  For example, if CODE is
3292    a binary operation associated with conditional function FN:
3293
3294      LHS = FN (COND, A, B, ELSE)
3295
3296    is equivalent to the C expression:
3297
3298      LHS = COND ? A CODE B : ELSE;
3299
3300    operating elementwise if the operands are vectors.
3301
3302    Return IFN_LAST if no such function exists.  */
3303
3304 internal_fn
3305 get_conditional_internal_fn (tree_code code)
3306 {
3307   switch (code)
3308     {
3309 #define CASE(CODE, IFN) case CODE: return IFN;
3310       FOR_EACH_CODE_MAPPING(CASE)
3311 #undef CASE
3312     default:
3313       return IFN_LAST;
3314     }
3315 }
3316
3317 /* If IFN implements the conditional form of a tree code, return that
3318    tree code, otherwise return ERROR_MARK.  */
3319
3320 tree_code
3321 conditional_internal_fn_code (internal_fn ifn)
3322 {
3323   switch (ifn)
3324     {
3325 #define CASE(CODE, IFN) case IFN: return CODE;
3326       FOR_EACH_CODE_MAPPING(CASE)
3327 #undef CASE
3328     default:
3329       return ERROR_MARK;
3330     }
3331 }
3332
3333 /* Invoke T(IFN) for each internal function IFN that also has an
3334    IFN_COND_* form.  */
3335 #define FOR_EACH_COND_FN_PAIR(T) \
3336   T (FMA) \
3337   T (FMS) \
3338   T (FNMA) \
3339   T (FNMS)
3340
3341 /* Return a function that only performs internal function FN when a
3342    certain condition is met and that uses a given fallback value otherwise.
3343    In other words, the returned function FN' is such that:
3344
3345      LHS = FN' (COND, A1, ... An, ELSE)
3346
3347    is equivalent to the C expression:
3348
3349      LHS = COND ? FN (A1, ..., An) : ELSE;
3350
3351    operating elementwise if the operands are vectors.
3352
3353    Return IFN_LAST if no such function exists.  */
3354
3355 internal_fn
3356 get_conditional_internal_fn (internal_fn fn)
3357 {
3358   switch (fn)
3359     {
3360 #define CASE(NAME) case IFN_##NAME: return IFN_COND_##NAME;
3361       FOR_EACH_COND_FN_PAIR(CASE)
3362 #undef CASE
3363     default:
3364       return IFN_LAST;
3365     }
3366 }
3367
3368 /* If IFN implements the conditional form of an unconditional internal
3369    function, return that unconditional function, otherwise return IFN_LAST.  */
3370
3371 internal_fn
3372 get_unconditional_internal_fn (internal_fn ifn)
3373 {
3374   switch (ifn)
3375     {
3376 #define CASE(NAME) case IFN_COND_##NAME: return IFN_##NAME;
3377       FOR_EACH_COND_FN_PAIR(CASE)
3378 #undef CASE
3379     default:
3380       return IFN_LAST;
3381     }
3382 }
3383
3384 /* Return true if STMT can be interpreted as a conditional tree code
3385    operation of the form:
3386
3387      LHS = COND ? OP (RHS1, ...) : ELSE;
3388
3389    operating elementwise if the operands are vectors.  This includes
3390    the case of an all-true COND, so that the operation always happens.
3391
3392    When returning true, set:
3393
3394    - *COND_OUT to the condition COND, or to NULL_TREE if the condition
3395      is known to be all-true
3396    - *CODE_OUT to the tree code
3397    - OPS[I] to operand I of *CODE_OUT
3398    - *ELSE_OUT to the fallback value ELSE, or to NULL_TREE if the
3399      condition is known to be all true.  */
3400
3401 bool
3402 can_interpret_as_conditional_op_p (gimple *stmt, tree *cond_out,
3403                                    tree_code *code_out,
3404                                    tree (&ops)[3], tree *else_out)
3405 {
3406   if (gassign *assign = dyn_cast <gassign *> (stmt))
3407     {
3408       *cond_out = NULL_TREE;
3409       *code_out = gimple_assign_rhs_code (assign);
3410       ops[0] = gimple_assign_rhs1 (assign);
3411       ops[1] = gimple_assign_rhs2 (assign);
3412       ops[2] = gimple_assign_rhs3 (assign);
3413       *else_out = NULL_TREE;
3414       return true;
3415     }
3416   if (gcall *call = dyn_cast <gcall *> (stmt))
3417     if (gimple_call_internal_p (call))
3418       {
3419         internal_fn ifn = gimple_call_internal_fn (call);
3420         tree_code code = conditional_internal_fn_code (ifn);
3421         if (code != ERROR_MARK)
3422           {
3423             *cond_out = gimple_call_arg (call, 0);
3424             *code_out = code;
3425             unsigned int nops = gimple_call_num_args (call) - 2;
3426             for (unsigned int i = 0; i < 3; ++i)
3427               ops[i] = i < nops ? gimple_call_arg (call, i + 1) : NULL_TREE;
3428             *else_out = gimple_call_arg (call, nops + 1);
3429             if (integer_truep (*cond_out))
3430               {
3431                 *cond_out = NULL_TREE;
3432                 *else_out = NULL_TREE;
3433               }
3434             return true;
3435           }
3436       }
3437   return false;
3438 }
3439
3440 /* Return true if IFN is some form of load from memory.  */
3441
3442 bool
3443 internal_load_fn_p (internal_fn fn)
3444 {
3445   switch (fn)
3446     {
3447     case IFN_MASK_LOAD:
3448     case IFN_LOAD_LANES:
3449     case IFN_MASK_LOAD_LANES:
3450     case IFN_GATHER_LOAD:
3451     case IFN_MASK_GATHER_LOAD:
3452       return true;
3453
3454     default:
3455       return false;
3456     }
3457 }
3458
3459 /* Return true if IFN is some form of store to memory.  */
3460
3461 bool
3462 internal_store_fn_p (internal_fn fn)
3463 {
3464   switch (fn)
3465     {
3466     case IFN_MASK_STORE:
3467     case IFN_STORE_LANES:
3468     case IFN_MASK_STORE_LANES:
3469     case IFN_SCATTER_STORE:
3470     case IFN_MASK_SCATTER_STORE:
3471       return true;
3472
3473     default:
3474       return false;
3475     }
3476 }
3477
3478 /* Return true if IFN is some form of gather load or scatter store.  */
3479
3480 bool
3481 internal_gather_scatter_fn_p (internal_fn fn)
3482 {
3483   switch (fn)
3484     {
3485     case IFN_GATHER_LOAD:
3486     case IFN_MASK_GATHER_LOAD:
3487     case IFN_SCATTER_STORE:
3488     case IFN_MASK_SCATTER_STORE:
3489       return true;
3490
3491     default:
3492       return false;
3493     }
3494 }
3495
3496 /* If FN takes a vector mask argument, return the index of that argument,
3497    otherwise return -1.  */
3498
3499 int
3500 internal_fn_mask_index (internal_fn fn)
3501 {
3502   switch (fn)
3503     {
3504     case IFN_MASK_LOAD:
3505     case IFN_MASK_LOAD_LANES:
3506     case IFN_MASK_STORE:
3507     case IFN_MASK_STORE_LANES:
3508       return 2;
3509
3510     case IFN_MASK_GATHER_LOAD:
3511       return 3;
3512
3513     case IFN_MASK_SCATTER_STORE:
3514       return 4;
3515
3516     default:
3517       return (conditional_internal_fn_code (fn) != ERROR_MARK
3518               || get_unconditional_internal_fn (fn) != IFN_LAST ? 0 : -1);
3519     }
3520 }
3521
3522 /* If FN takes a value that should be stored to memory, return the index
3523    of that argument, otherwise return -1.  */
3524
3525 int
3526 internal_fn_stored_value_index (internal_fn fn)
3527 {
3528   switch (fn)
3529     {
3530     case IFN_MASK_STORE:
3531     case IFN_SCATTER_STORE:
3532     case IFN_MASK_SCATTER_STORE:
3533       return 3;
3534
3535     default:
3536       return -1;
3537     }
3538 }
3539
3540 /* Return true if the target supports gather load or scatter store function
3541    IFN.  For loads, VECTOR_TYPE is the vector type of the load result,
3542    while for stores it is the vector type of the stored data argument.
3543    MEMORY_ELEMENT_TYPE is the type of the memory elements being loaded
3544    or stored.  OFFSET_SIGN is the sign of the offset argument, which is
3545    only relevant when the offset is narrower than an address.  SCALE is
3546    the amount by which the offset should be multiplied *after* it has
3547    been extended to address width.  */
3548
3549 bool
3550 internal_gather_scatter_fn_supported_p (internal_fn ifn, tree vector_type,
3551                                         tree memory_element_type,
3552                                         signop offset_sign, int scale)
3553 {
3554   if (!tree_int_cst_equal (TYPE_SIZE (TREE_TYPE (vector_type)),
3555                            TYPE_SIZE (memory_element_type)))
3556     return false;
3557   optab optab = direct_internal_fn_optab (ifn);
3558   insn_code icode = direct_optab_handler (optab, TYPE_MODE (vector_type));
3559   int output_ops = internal_load_fn_p (ifn) ? 1 : 0;
3560   return (icode != CODE_FOR_nothing
3561           && insn_operand_matches (icode, 2 + output_ops,
3562                                    GEN_INT (offset_sign == UNSIGNED))
3563           && insn_operand_matches (icode, 3 + output_ops,
3564                                    GEN_INT (scale)));
3565 }
3566
3567 /* Expand STMT as though it were a call to internal function FN.  */
3568
3569 void
3570 expand_internal_call (internal_fn fn, gcall *stmt)
3571 {
3572   internal_fn_expanders[fn] (fn, stmt);
3573 }
3574
3575 /* Expand STMT, which is a call to internal function FN.  */
3576
3577 void
3578 expand_internal_call (gcall *stmt)
3579 {
3580   expand_internal_call (gimple_call_internal_fn (stmt), stmt);
3581 }
3582
3583 /* If TYPE is a vector type, return true if IFN is a direct internal
3584    function that is supported for that type.  If TYPE is a scalar type,
3585    return true if IFN is a direct internal function that is supported for
3586    the target's preferred vector version of TYPE.  */
3587
3588 bool
3589 vectorized_internal_fn_supported_p (internal_fn ifn, tree type)
3590 {
3591   scalar_mode smode;
3592   if (!VECTOR_TYPE_P (type) && is_a <scalar_mode> (TYPE_MODE (type), &smode))
3593     {
3594       machine_mode vmode = targetm.vectorize.preferred_simd_mode (smode);
3595       if (VECTOR_MODE_P (vmode))
3596         type = build_vector_type_for_mode (type, vmode);
3597     }
3598
3599   return (VECTOR_MODE_P (TYPE_MODE (type))
3600           && direct_internal_fn_supported_p (ifn, type, OPTIMIZE_FOR_SPEED));
3601 }
3602
3603 void
3604 expand_PHI (internal_fn, gcall *)
3605 {
3606     gcc_unreachable ();
3607 }