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