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