Update copyright years.
[platform/upstream/gcc.git] / gcc / internal-fn.c
1 /* Internal functions.
2    Copyright (C) 2011-2016 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-ssanames.h"
31 #include "expmed.h"
32 #include "optabs.h"
33 #include "emit-rtl.h"
34 #include "diagnostic-core.h"
35 #include "fold-const.h"
36 #include "internal-fn.h"
37 #include "stor-layout.h"
38 #include "dojump.h"
39 #include "expr.h"
40 #include "ubsan.h"
41 #include "recog.h"
42
43 /* The names of each internal function, indexed by function number.  */
44 const char *const internal_fn_name_array[] = {
45 #define DEF_INTERNAL_FN(CODE, FLAGS, FNSPEC) #CODE,
46 #include "internal-fn.def"
47   "<invalid-fn>"
48 };
49
50 /* The ECF_* flags of each internal function, indexed by function number.  */
51 const int internal_fn_flags_array[] = {
52 #define DEF_INTERNAL_FN(CODE, FLAGS, FNSPEC) FLAGS,
53 #include "internal-fn.def"
54   0
55 };
56
57 /* Fnspec of each internal function, indexed by function number.  */
58 const_tree internal_fn_fnspec_array[IFN_LAST + 1];
59
60 void
61 init_internal_fns ()
62 {
63 #define DEF_INTERNAL_FN(CODE, FLAGS, FNSPEC) \
64   if (FNSPEC) internal_fn_fnspec_array[IFN_##CODE] = \
65     build_string ((int) sizeof (FNSPEC), FNSPEC ? FNSPEC : "");
66 #include "internal-fn.def"
67   internal_fn_fnspec_array[IFN_LAST] = 0;
68 }
69
70 /* Create static initializers for the information returned by
71    direct_internal_fn.  */
72 #define not_direct { -2, -2, false }
73 #define mask_load_direct { -1, 2, false }
74 #define load_lanes_direct { -1, -1, false }
75 #define mask_store_direct { 3, 2, false }
76 #define store_lanes_direct { 0, 0, false }
77 #define unary_direct { 0, 0, true }
78 #define binary_direct { 0, 0, true }
79
80 const direct_internal_fn_info direct_internal_fn_array[IFN_LAST + 1] = {
81 #define DEF_INTERNAL_FN(CODE, FLAGS, FNSPEC) not_direct,
82 #define DEF_INTERNAL_OPTAB_FN(CODE, FLAGS, OPTAB, TYPE) TYPE##_direct,
83 #include "internal-fn.def"
84   not_direct
85 };
86
87 /* ARRAY_TYPE is an array of vector modes.  Return the associated insn
88    for load-lanes-style optab OPTAB, or CODE_FOR_nothing if none.  */
89
90 static enum insn_code
91 get_multi_vector_move (tree array_type, convert_optab optab)
92 {
93   machine_mode imode;
94   machine_mode vmode;
95
96   gcc_assert (TREE_CODE (array_type) == ARRAY_TYPE);
97   imode = TYPE_MODE (array_type);
98   vmode = TYPE_MODE (TREE_TYPE (array_type));
99
100   return convert_optab_handler (optab, imode, vmode);
101 }
102
103 /* Expand LOAD_LANES call STMT using optab OPTAB.  */
104
105 static void
106 expand_load_lanes_optab_fn (internal_fn, gcall *stmt, convert_optab optab)
107 {
108   struct expand_operand ops[2];
109   tree type, lhs, rhs;
110   rtx target, mem;
111
112   lhs = gimple_call_lhs (stmt);
113   rhs = gimple_call_arg (stmt, 0);
114   type = TREE_TYPE (lhs);
115
116   target = expand_expr (lhs, NULL_RTX, VOIDmode, EXPAND_WRITE);
117   mem = expand_normal (rhs);
118
119   gcc_assert (MEM_P (mem));
120   PUT_MODE (mem, TYPE_MODE (type));
121
122   create_output_operand (&ops[0], target, TYPE_MODE (type));
123   create_fixed_operand (&ops[1], mem);
124   expand_insn (get_multi_vector_move (type, optab), 2, ops);
125 }
126
127 /* Expand STORE_LANES call STMT using optab OPTAB.  */
128
129 static void
130 expand_store_lanes_optab_fn (internal_fn, gcall *stmt, convert_optab optab)
131 {
132   struct expand_operand ops[2];
133   tree type, lhs, rhs;
134   rtx target, reg;
135
136   lhs = gimple_call_lhs (stmt);
137   rhs = gimple_call_arg (stmt, 0);
138   type = TREE_TYPE (rhs);
139
140   target = expand_expr (lhs, NULL_RTX, VOIDmode, EXPAND_WRITE);
141   reg = expand_normal (rhs);
142
143   gcc_assert (MEM_P (target));
144   PUT_MODE (target, TYPE_MODE (type));
145
146   create_fixed_operand (&ops[0], target);
147   create_input_operand (&ops[1], reg, TYPE_MODE (type));
148   expand_insn (get_multi_vector_move (type, optab), 2, ops);
149 }
150
151 static void
152 expand_ANNOTATE (internal_fn, gcall *)
153 {
154   gcc_unreachable ();
155 }
156
157 /* This should get expanded in adjust_simduid_builtins.  */
158
159 static void
160 expand_GOMP_SIMD_LANE (internal_fn, gcall *)
161 {
162   gcc_unreachable ();
163 }
164
165 /* This should get expanded in adjust_simduid_builtins.  */
166
167 static void
168 expand_GOMP_SIMD_VF (internal_fn, gcall *)
169 {
170   gcc_unreachable ();
171 }
172
173 /* This should get expanded in adjust_simduid_builtins.  */
174
175 static void
176 expand_GOMP_SIMD_LAST_LANE (internal_fn, gcall *)
177 {
178   gcc_unreachable ();
179 }
180
181 /* This should get expanded in adjust_simduid_builtins.  */
182
183 static void
184 expand_GOMP_SIMD_ORDERED_START (internal_fn, gcall *)
185 {
186   gcc_unreachable ();
187 }
188
189 /* This should get expanded in adjust_simduid_builtins.  */
190
191 static void
192 expand_GOMP_SIMD_ORDERED_END (internal_fn, gcall *)
193 {
194   gcc_unreachable ();
195 }
196
197 /* This should get expanded in the sanopt pass.  */
198
199 static void
200 expand_UBSAN_NULL (internal_fn, gcall *)
201 {
202   gcc_unreachable ();
203 }
204
205 /* This should get expanded in the sanopt pass.  */
206
207 static void
208 expand_UBSAN_BOUNDS (internal_fn, gcall *)
209 {
210   gcc_unreachable ();
211 }
212
213 /* This should get expanded in the sanopt pass.  */
214
215 static void
216 expand_UBSAN_VPTR (internal_fn, gcall *)
217 {
218   gcc_unreachable ();
219 }
220
221 /* This should get expanded in the sanopt pass.  */
222
223 static void
224 expand_UBSAN_OBJECT_SIZE (internal_fn, gcall *)
225 {
226   gcc_unreachable ();
227 }
228
229 /* This should get expanded in the sanopt pass.  */
230
231 static void
232 expand_ASAN_CHECK (internal_fn, gcall *)
233 {
234   gcc_unreachable ();
235 }
236
237 /* This should get expanded in the tsan pass.  */
238
239 static void
240 expand_TSAN_FUNC_EXIT (internal_fn, gcall *)
241 {
242   gcc_unreachable ();
243 }
244
245 /* Helper function for expand_addsub_overflow.  Return 1
246    if ARG interpreted as signed in its precision is known to be always
247    positive or 2 if ARG is known to be always negative, or 3 if ARG may
248    be positive or negative.  */
249
250 static int
251 get_range_pos_neg (tree arg)
252 {
253   if (arg == error_mark_node)
254     return 3;
255
256   int prec = TYPE_PRECISION (TREE_TYPE (arg));
257   int cnt = 0;
258   if (TREE_CODE (arg) == INTEGER_CST)
259     {
260       wide_int w = wi::sext (arg, prec);
261       if (wi::neg_p (w))
262         return 2;
263       else
264         return 1;
265     }
266   while (CONVERT_EXPR_P (arg)
267          && INTEGRAL_TYPE_P (TREE_TYPE (TREE_OPERAND (arg, 0)))
268          && TYPE_PRECISION (TREE_TYPE (TREE_OPERAND (arg, 0))) <= prec)
269     {
270       arg = TREE_OPERAND (arg, 0);
271       /* Narrower value zero extended into wider type
272          will always result in positive values.  */
273       if (TYPE_UNSIGNED (TREE_TYPE (arg))
274           && TYPE_PRECISION (TREE_TYPE (arg)) < prec)
275         return 1;
276       prec = TYPE_PRECISION (TREE_TYPE (arg));
277       if (++cnt > 30)
278         return 3;
279     }
280
281   if (TREE_CODE (arg) != SSA_NAME)
282     return 3;
283   wide_int arg_min, arg_max;
284   while (get_range_info (arg, &arg_min, &arg_max) != VR_RANGE)
285     {
286       gimple *g = SSA_NAME_DEF_STMT (arg);
287       if (is_gimple_assign (g)
288           && CONVERT_EXPR_CODE_P (gimple_assign_rhs_code (g)))
289         {
290           tree t = gimple_assign_rhs1 (g);
291           if (INTEGRAL_TYPE_P (TREE_TYPE (t))
292               && TYPE_PRECISION (TREE_TYPE (t)) <= prec)
293             {
294               if (TYPE_UNSIGNED (TREE_TYPE (t))
295                   && TYPE_PRECISION (TREE_TYPE (t)) < prec)
296                 return 1;
297               prec = TYPE_PRECISION (TREE_TYPE (t));
298               arg = t;
299               if (++cnt > 30)
300                 return 3;
301               continue;
302             }
303         }
304       return 3;
305     }
306   if (TYPE_UNSIGNED (TREE_TYPE (arg)))
307     {
308       /* For unsigned values, the "positive" range comes
309          below the "negative" range.  */
310       if (!wi::neg_p (wi::sext (arg_max, prec), SIGNED))
311         return 1;
312       if (wi::neg_p (wi::sext (arg_min, prec), SIGNED))
313         return 2;
314     }
315   else
316     {
317       if (!wi::neg_p (wi::sext (arg_min, prec), SIGNED))
318         return 1;
319       if (wi::neg_p (wi::sext (arg_max, prec), SIGNED))
320         return 2;
321     }
322   return 3;
323 }
324
325 /* Return minimum precision needed to represent all values
326    of ARG in SIGNed integral type.  */
327
328 static int
329 get_min_precision (tree arg, signop sign)
330 {
331   int prec = TYPE_PRECISION (TREE_TYPE (arg));
332   int cnt = 0;
333   signop orig_sign = sign;
334   if (TREE_CODE (arg) == INTEGER_CST)
335     {
336       int p;
337       if (TYPE_SIGN (TREE_TYPE (arg)) != sign)
338         {
339           widest_int w = wi::to_widest (arg);
340           w = wi::ext (w, prec, sign);
341           p = wi::min_precision (w, sign);
342         }
343       else
344         p = wi::min_precision (arg, sign);
345       return MIN (p, prec);
346     }
347   while (CONVERT_EXPR_P (arg)
348          && INTEGRAL_TYPE_P (TREE_TYPE (TREE_OPERAND (arg, 0)))
349          && TYPE_PRECISION (TREE_TYPE (TREE_OPERAND (arg, 0))) <= prec)
350     {
351       arg = TREE_OPERAND (arg, 0);
352       if (TYPE_PRECISION (TREE_TYPE (arg)) < prec)
353         {
354           if (TYPE_UNSIGNED (TREE_TYPE (arg)))
355             sign = UNSIGNED;
356           else if (sign == UNSIGNED && get_range_pos_neg (arg) != 1)
357             return prec + (orig_sign != sign);
358           prec = TYPE_PRECISION (TREE_TYPE (arg));
359         }
360       if (++cnt > 30)
361         return prec + (orig_sign != sign);
362     }
363   if (TREE_CODE (arg) != SSA_NAME)
364     return prec + (orig_sign != sign);
365   wide_int arg_min, arg_max;
366   while (get_range_info (arg, &arg_min, &arg_max) != VR_RANGE)
367     {
368       gimple *g = SSA_NAME_DEF_STMT (arg);
369       if (is_gimple_assign (g)
370           && CONVERT_EXPR_CODE_P (gimple_assign_rhs_code (g)))
371         {
372           tree t = gimple_assign_rhs1 (g);
373           if (INTEGRAL_TYPE_P (TREE_TYPE (t))
374               && TYPE_PRECISION (TREE_TYPE (t)) <= prec)
375             {
376               arg = t;
377               if (TYPE_PRECISION (TREE_TYPE (arg)) < prec)
378                 {
379                   if (TYPE_UNSIGNED (TREE_TYPE (arg)))
380                     sign = UNSIGNED;
381                   else if (sign == UNSIGNED && get_range_pos_neg (arg) != 1)
382                     return prec + (orig_sign != sign);
383                   prec = TYPE_PRECISION (TREE_TYPE (arg));
384                 }
385               if (++cnt > 30)
386                 return prec + (orig_sign != sign);
387               continue;
388             }
389         }
390       return prec + (orig_sign != sign);
391     }
392   if (sign == TYPE_SIGN (TREE_TYPE (arg)))
393     {
394       int p1 = wi::min_precision (arg_min, sign);
395       int p2 = wi::min_precision (arg_max, sign);
396       p1 = MAX (p1, p2);
397       prec = MIN (prec, p1);
398     }
399   else if (sign == UNSIGNED && !wi::neg_p (arg_min, SIGNED))
400     {
401       int p = wi::min_precision (arg_max, UNSIGNED);
402       prec = MIN (prec, p);
403     }
404   return prec + (orig_sign != sign);
405 }
406
407 /* Helper for expand_*_overflow.  Store RES into the __real__ part
408    of TARGET.  If RES has larger MODE than __real__ part of TARGET,
409    set the __imag__ part to 1 if RES doesn't fit into it.  */
410
411 static void
412 expand_arith_overflow_result_store (tree lhs, rtx target,
413                                     machine_mode mode, rtx res)
414 {
415   machine_mode tgtmode = GET_MODE_INNER (GET_MODE (target));
416   rtx lres = res;
417   if (tgtmode != mode)
418     {
419       rtx_code_label *done_label = gen_label_rtx ();
420       int uns = TYPE_UNSIGNED (TREE_TYPE (TREE_TYPE (lhs)));
421       lres = convert_modes (tgtmode, mode, res, uns);
422       gcc_assert (GET_MODE_PRECISION (tgtmode) < GET_MODE_PRECISION (mode));
423       do_compare_rtx_and_jump (res, convert_modes (mode, tgtmode, lres, uns),
424                                EQ, true, mode, NULL_RTX, NULL, done_label,
425                                PROB_VERY_LIKELY);
426       write_complex_part (target, const1_rtx, true);
427       emit_label (done_label);
428     }
429   write_complex_part (target, lres, false);
430 }
431
432 /* Helper for expand_*_overflow.  Store RES into TARGET.  */
433
434 static void
435 expand_ubsan_result_store (rtx target, rtx res)
436 {
437   if (GET_CODE (target) == SUBREG && SUBREG_PROMOTED_VAR_P (target))
438     /* If this is a scalar in a register that is stored in a wider mode   
439        than the declared mode, compute the result into its declared mode
440        and then convert to the wider mode.  Our value is the computed
441        expression.  */
442     convert_move (SUBREG_REG (target), res, SUBREG_PROMOTED_SIGN (target));
443   else
444     emit_move_insn (target, res);
445 }
446
447 /* Add sub/add overflow checking to the statement STMT.
448    CODE says whether the operation is +, or -.  */
449
450 static void
451 expand_addsub_overflow (location_t loc, tree_code code, tree lhs,
452                         tree arg0, tree arg1, bool unsr_p, bool uns0_p,
453                         bool uns1_p, bool is_ubsan)
454 {
455   rtx res, target = NULL_RTX;
456   tree fn;
457   rtx_code_label *done_label = gen_label_rtx ();
458   rtx_code_label *do_error = gen_label_rtx ();
459   do_pending_stack_adjust ();
460   rtx op0 = expand_normal (arg0);
461   rtx op1 = expand_normal (arg1);
462   machine_mode mode = TYPE_MODE (TREE_TYPE (arg0));
463   int prec = GET_MODE_PRECISION (mode);
464   rtx sgn = immed_wide_int_const (wi::min_value (prec, SIGNED), mode);
465   bool do_xor = false;
466
467   if (is_ubsan)
468     gcc_assert (!unsr_p && !uns0_p && !uns1_p);
469
470   if (lhs)
471     {
472       target = expand_expr (lhs, NULL_RTX, VOIDmode, EXPAND_WRITE);
473       if (!is_ubsan)
474         write_complex_part (target, const0_rtx, true);
475     }
476
477   /* We assume both operands and result have the same precision
478      here (GET_MODE_BITSIZE (mode)), S stands for signed type
479      with that precision, U for unsigned type with that precision,
480      sgn for unsigned most significant bit in that precision.
481      s1 is signed first operand, u1 is unsigned first operand,
482      s2 is signed second operand, u2 is unsigned second operand,
483      sr is signed result, ur is unsigned result and the following
484      rules say how to compute result (which is always result of
485      the operands as if both were unsigned, cast to the right
486      signedness) and how to compute whether operation overflowed.
487
488      s1 + s2 -> sr
489         res = (S) ((U) s1 + (U) s2)
490         ovf = s2 < 0 ? res > s1 : res < s1 (or jump on overflow)
491      s1 - s2 -> sr
492         res = (S) ((U) s1 - (U) s2)
493         ovf = s2 < 0 ? res < s1 : res > s2 (or jump on overflow)
494      u1 + u2 -> ur
495         res = u1 + u2
496         ovf = res < u1 (or jump on carry, but RTL opts will handle it)
497      u1 - u2 -> ur
498         res = u1 - u2
499         ovf = res > u1 (or jump on carry, but RTL opts will handle it)
500      s1 + u2 -> sr
501         res = (S) ((U) s1 + u2)
502         ovf = ((U) res ^ sgn) < u2
503      s1 + u2 -> ur
504         t1 = (S) (u2 ^ sgn)
505         t2 = s1 + t1
506         res = (U) t2 ^ sgn
507         ovf = t1 < 0 ? t2 > s1 : t2 < s1 (or jump on overflow)
508      s1 - u2 -> sr
509         res = (S) ((U) s1 - u2)
510         ovf = u2 > ((U) s1 ^ sgn)
511      s1 - u2 -> ur
512         res = (U) s1 - u2
513         ovf = s1 < 0 || u2 > (U) s1
514      u1 - s2 -> sr
515         res = u1 - (U) s2
516         ovf = u1 >= ((U) s2 ^ sgn)
517      u1 - s2 -> ur
518         t1 = u1 ^ sgn
519         t2 = t1 - (U) s2
520         res = t2 ^ sgn
521         ovf = s2 < 0 ? (S) t2 < (S) t1 : (S) t2 > (S) t1 (or jump on overflow)
522      s1 + s2 -> ur
523         res = (U) s1 + (U) s2
524         ovf = s2 < 0 ? (s1 | (S) res) < 0) : (s1 & (S) res) < 0)
525      u1 + u2 -> sr
526         res = (S) (u1 + u2)
527         ovf = (U) res < u2 || res < 0
528      u1 - u2 -> sr
529         res = (S) (u1 - u2)
530         ovf = u1 >= u2 ? res < 0 : res >= 0
531      s1 - s2 -> ur
532         res = (U) s1 - (U) s2
533         ovf = s2 >= 0 ? ((s1 | (S) res) < 0) : ((s1 & (S) res) < 0)  */
534
535   if (code == PLUS_EXPR && uns0_p && !uns1_p)
536     {
537       /* PLUS_EXPR is commutative, if operand signedness differs,
538          canonicalize to the first operand being signed and second
539          unsigned to simplify following code.  */
540       std::swap (op0, op1);
541       std::swap (arg0, arg1);
542       uns0_p = false;
543       uns1_p = true;
544     }
545
546   /* u1 +- u2 -> ur  */
547   if (uns0_p && uns1_p && unsr_p)
548     {
549       insn_code icode = optab_handler (code == PLUS_EXPR ? uaddv4_optab
550                                        : usubv4_optab, mode);
551       if (icode != CODE_FOR_nothing)
552         {
553           struct expand_operand ops[4];
554           rtx_insn *last = get_last_insn ();
555
556           res = gen_reg_rtx (mode);
557           create_output_operand (&ops[0], res, mode);
558           create_input_operand (&ops[1], op0, mode);
559           create_input_operand (&ops[2], op1, mode);
560           create_fixed_operand (&ops[3], do_error);
561           if (maybe_expand_insn (icode, 4, ops))
562             {
563               last = get_last_insn ();
564               if (profile_status_for_fn (cfun) != PROFILE_ABSENT
565                   && JUMP_P (last)
566                   && any_condjump_p (last)
567                   && !find_reg_note (last, REG_BR_PROB, 0))
568                 add_int_reg_note (last, REG_BR_PROB, PROB_VERY_UNLIKELY);
569               emit_jump (done_label);
570               goto do_error_label;
571             }
572
573           delete_insns_since (last);
574         }
575
576       /* Compute the operation.  On RTL level, the addition is always
577          unsigned.  */
578       res = expand_binop (mode, code == PLUS_EXPR ? add_optab : sub_optab,
579                           op0, op1, NULL_RTX, false, OPTAB_LIB_WIDEN);
580       rtx tem = op0;
581       /* For PLUS_EXPR, the operation is commutative, so we can pick
582          operand to compare against.  For prec <= BITS_PER_WORD, I think
583          preferring REG operand is better over CONST_INT, because
584          the CONST_INT might enlarge the instruction or CSE would need
585          to figure out we'd already loaded it into a register before.
586          For prec > BITS_PER_WORD, I think CONST_INT might be more beneficial,
587          as then the multi-word comparison can be perhaps simplified.  */
588       if (code == PLUS_EXPR
589           && (prec <= BITS_PER_WORD
590               ? (CONST_SCALAR_INT_P (op0) && REG_P (op1))
591               : CONST_SCALAR_INT_P (op1)))
592         tem = op1;
593       do_compare_rtx_and_jump (res, tem, code == PLUS_EXPR ? GEU : LEU,
594                                true, mode, NULL_RTX, NULL, done_label,
595                                PROB_VERY_LIKELY);
596       goto do_error_label;
597     }
598
599   /* s1 +- u2 -> sr  */
600   if (!uns0_p && uns1_p && !unsr_p)
601     {
602       /* Compute the operation.  On RTL level, the addition is always
603          unsigned.  */
604       res = expand_binop (mode, code == PLUS_EXPR ? add_optab : sub_optab,
605                           op0, op1, NULL_RTX, false, OPTAB_LIB_WIDEN);
606       rtx tem = expand_binop (mode, add_optab,
607                               code == PLUS_EXPR ? res : op0, sgn,
608                               NULL_RTX, false, OPTAB_LIB_WIDEN);
609       do_compare_rtx_and_jump (tem, op1, GEU, true, mode, NULL_RTX, NULL,
610                                done_label, PROB_VERY_LIKELY);
611       goto do_error_label;
612     }
613
614   /* s1 + u2 -> ur  */
615   if (code == PLUS_EXPR && !uns0_p && uns1_p && unsr_p)
616     {
617       op1 = expand_binop (mode, add_optab, op1, sgn, NULL_RTX, false,
618                           OPTAB_LIB_WIDEN);
619       /* As we've changed op1, we have to avoid using the value range
620          for the original argument.  */
621       arg1 = error_mark_node;
622       do_xor = true;
623       goto do_signed;
624     }
625
626   /* u1 - s2 -> ur  */
627   if (code == MINUS_EXPR && uns0_p && !uns1_p && unsr_p)
628     {
629       op0 = expand_binop (mode, add_optab, op0, sgn, NULL_RTX, false,
630                           OPTAB_LIB_WIDEN);
631       /* As we've changed op0, we have to avoid using the value range
632          for the original argument.  */
633       arg0 = error_mark_node;
634       do_xor = true;
635       goto do_signed;
636     }
637
638   /* s1 - u2 -> ur  */
639   if (code == MINUS_EXPR && !uns0_p && uns1_p && unsr_p)
640     {
641       /* Compute the operation.  On RTL level, the addition is always
642          unsigned.  */
643       res = expand_binop (mode, sub_optab, op0, op1, NULL_RTX, false,
644                           OPTAB_LIB_WIDEN);
645       int pos_neg = get_range_pos_neg (arg0);
646       if (pos_neg == 2)
647         /* If ARG0 is known to be always negative, this is always overflow.  */
648         emit_jump (do_error);
649       else if (pos_neg == 3)
650         /* If ARG0 is not known to be always positive, check at runtime.  */
651         do_compare_rtx_and_jump (op0, const0_rtx, LT, false, mode, NULL_RTX,
652                                  NULL, do_error, PROB_VERY_UNLIKELY);
653       do_compare_rtx_and_jump (op1, op0, LEU, true, mode, NULL_RTX, NULL,
654                                done_label, PROB_VERY_LIKELY);
655       goto do_error_label;
656     }
657
658   /* u1 - s2 -> sr  */
659   if (code == MINUS_EXPR && uns0_p && !uns1_p && !unsr_p)
660     {
661       /* Compute the operation.  On RTL level, the addition is always
662          unsigned.  */
663       res = expand_binop (mode, sub_optab, op0, op1, NULL_RTX, false,
664                           OPTAB_LIB_WIDEN);
665       rtx tem = expand_binop (mode, add_optab, op1, sgn, NULL_RTX, false,
666                               OPTAB_LIB_WIDEN);
667       do_compare_rtx_and_jump (op0, tem, LTU, true, mode, NULL_RTX, NULL,
668                                done_label, PROB_VERY_LIKELY);
669       goto do_error_label;
670     }
671
672   /* u1 + u2 -> sr  */
673   if (code == PLUS_EXPR && uns0_p && uns1_p && !unsr_p)
674     {
675       /* Compute the operation.  On RTL level, the addition is always
676          unsigned.  */
677       res = expand_binop (mode, add_optab, op0, op1, NULL_RTX, false,
678                           OPTAB_LIB_WIDEN);
679       do_compare_rtx_and_jump (res, const0_rtx, LT, false, mode, NULL_RTX,
680                                NULL, do_error, PROB_VERY_UNLIKELY);
681       rtx tem = op1;
682       /* The operation is commutative, so we can pick operand to compare
683          against.  For prec <= BITS_PER_WORD, I think preferring REG operand
684          is better over CONST_INT, because the CONST_INT might enlarge the
685          instruction or CSE would need to figure out we'd already loaded it
686          into a register before.  For prec > BITS_PER_WORD, I think CONST_INT
687          might be more beneficial, as then the multi-word comparison can be
688          perhaps simplified.  */
689       if (prec <= BITS_PER_WORD
690           ? (CONST_SCALAR_INT_P (op1) && REG_P (op0))
691           : CONST_SCALAR_INT_P (op0))
692         tem = op0;
693       do_compare_rtx_and_jump (res, tem, GEU, true, mode, NULL_RTX, NULL,
694                                done_label, PROB_VERY_LIKELY);
695       goto do_error_label;
696     }
697
698   /* s1 +- s2 -> ur  */
699   if (!uns0_p && !uns1_p && unsr_p)
700     {
701       /* Compute the operation.  On RTL level, the addition is always
702          unsigned.  */
703       res = expand_binop (mode, code == PLUS_EXPR ? add_optab : sub_optab,
704                           op0, op1, NULL_RTX, false, OPTAB_LIB_WIDEN);
705       int pos_neg = get_range_pos_neg (arg1);
706       if (code == PLUS_EXPR)
707         {
708           int pos_neg0 = get_range_pos_neg (arg0);
709           if (pos_neg0 != 3 && pos_neg == 3)
710             {
711               std::swap (op0, op1);
712               pos_neg = pos_neg0;
713             }
714         }
715       rtx tem;
716       if (pos_neg != 3)
717         {
718           tem = expand_binop (mode, ((pos_neg == 1) ^ (code == MINUS_EXPR))
719                                     ? and_optab : ior_optab,
720                               op0, res, NULL_RTX, false, OPTAB_LIB_WIDEN);
721           do_compare_rtx_and_jump (tem, const0_rtx, GE, false, mode, NULL,
722                                    NULL, done_label, PROB_VERY_LIKELY);
723         }
724       else
725         {
726           rtx_code_label *do_ior_label = gen_label_rtx ();
727           do_compare_rtx_and_jump (op1, const0_rtx,
728                                    code == MINUS_EXPR ? GE : LT, false, mode,
729                                    NULL_RTX, NULL, do_ior_label,
730                                    PROB_EVEN);
731           tem = expand_binop (mode, and_optab, op0, res, NULL_RTX, false,
732                               OPTAB_LIB_WIDEN);
733           do_compare_rtx_and_jump (tem, const0_rtx, GE, false, mode, NULL_RTX,
734                                    NULL, done_label, PROB_VERY_LIKELY);
735           emit_jump (do_error);
736           emit_label (do_ior_label);
737           tem = expand_binop (mode, ior_optab, op0, res, NULL_RTX, false,
738                               OPTAB_LIB_WIDEN);
739           do_compare_rtx_and_jump (tem, const0_rtx, GE, false, mode, NULL_RTX,
740                                    NULL, done_label, PROB_VERY_LIKELY);
741         }
742       goto do_error_label;
743     }
744
745   /* u1 - u2 -> sr  */
746   if (code == MINUS_EXPR && uns0_p && uns1_p && !unsr_p)
747     {
748       /* Compute the operation.  On RTL level, the addition is always
749          unsigned.  */
750       res = expand_binop (mode, sub_optab, op0, op1, NULL_RTX, false,
751                           OPTAB_LIB_WIDEN);
752       rtx_code_label *op0_geu_op1 = gen_label_rtx ();
753       do_compare_rtx_and_jump (op0, op1, GEU, true, mode, NULL_RTX, NULL,
754                                op0_geu_op1, PROB_EVEN);
755       do_compare_rtx_and_jump (res, const0_rtx, LT, false, mode, NULL_RTX,
756                                NULL, done_label, PROB_VERY_LIKELY);
757       emit_jump (do_error);
758       emit_label (op0_geu_op1);
759       do_compare_rtx_and_jump (res, const0_rtx, GE, false, mode, NULL_RTX,
760                                NULL, done_label, PROB_VERY_LIKELY);
761       goto do_error_label;
762     }
763
764   gcc_assert (!uns0_p && !uns1_p && !unsr_p);
765
766   /* s1 +- s2 -> sr  */
767  do_signed:
768   {
769     insn_code icode = optab_handler (code == PLUS_EXPR ? addv4_optab
770                                      : subv4_optab, mode);
771     if (icode != CODE_FOR_nothing)
772       {
773         struct expand_operand ops[4];
774         rtx_insn *last = get_last_insn ();
775
776         res = gen_reg_rtx (mode);
777         create_output_operand (&ops[0], res, mode);
778         create_input_operand (&ops[1], op0, mode);
779         create_input_operand (&ops[2], op1, mode);
780         create_fixed_operand (&ops[3], do_error);
781         if (maybe_expand_insn (icode, 4, ops))
782           {
783             last = get_last_insn ();
784             if (profile_status_for_fn (cfun) != PROFILE_ABSENT
785                 && JUMP_P (last)
786                 && any_condjump_p (last)
787                 && !find_reg_note (last, REG_BR_PROB, 0))
788               add_int_reg_note (last, REG_BR_PROB, PROB_VERY_UNLIKELY);
789             emit_jump (done_label);
790             goto do_error_label;
791           }
792
793         delete_insns_since (last);
794       }
795
796     rtx_code_label *sub_check = gen_label_rtx ();
797     int pos_neg = 3;
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
804     /* If we can prove one of the arguments (for MINUS_EXPR only
805        the second operand, as subtraction is not commutative) is always
806        non-negative or always negative, we can do just one comparison
807        and conditional jump instead of 2 at runtime, 3 present in the
808        emitted code.  If one of the arguments is CONST_INT, all we
809        need is to make sure it is op1, then the first
810        do_compare_rtx_and_jump will be just folded.  Otherwise try
811        to use range info if available.  */
812     if (code == PLUS_EXPR && CONST_INT_P (op0))
813       std::swap (op0, op1);
814     else if (CONST_INT_P (op1))
815       ;
816     else if (code == PLUS_EXPR && TREE_CODE (arg0) == SSA_NAME)
817       {
818         pos_neg = get_range_pos_neg (arg0);
819         if (pos_neg != 3)
820           std::swap (op0, op1);
821       }
822     if (pos_neg == 3 && !CONST_INT_P (op1) && TREE_CODE (arg1) == SSA_NAME)
823       pos_neg = get_range_pos_neg (arg1);
824
825     /* If the op1 is negative, we have to use a different check.  */
826     if (pos_neg == 3)
827       do_compare_rtx_and_jump (op1, const0_rtx, LT, false, mode, NULL_RTX,
828                                NULL, sub_check, PROB_EVEN);
829
830     /* Compare the result of the operation with one of the operands.  */
831     if (pos_neg & 1)
832       do_compare_rtx_and_jump (res, op0, code == PLUS_EXPR ? GE : LE,
833                                false, mode, NULL_RTX, NULL, done_label,
834                                PROB_VERY_LIKELY);
835
836     /* If we get here, we have to print the error.  */
837     if (pos_neg == 3)
838       {
839         emit_jump (do_error);
840         emit_label (sub_check);
841       }
842
843     /* We have k = a + b for b < 0 here.  k <= a must hold.  */
844     if (pos_neg & 2)
845       do_compare_rtx_and_jump (res, op0, code == PLUS_EXPR ? LE : GE,
846                                false, mode, NULL_RTX, NULL, done_label,
847                                PROB_VERY_LIKELY);
848   }
849
850  do_error_label:
851   emit_label (do_error);
852   if (is_ubsan)
853     {
854       /* Expand the ubsan builtin call.  */
855       push_temp_slots ();
856       fn = ubsan_build_overflow_builtin (code, loc, TREE_TYPE (arg0),
857                                          arg0, arg1);
858       expand_normal (fn);
859       pop_temp_slots ();
860       do_pending_stack_adjust ();
861     }
862   else if (lhs)
863     write_complex_part (target, const1_rtx, true);
864
865   /* We're done.  */
866   emit_label (done_label);
867
868   if (lhs)
869     {
870       if (is_ubsan)
871         expand_ubsan_result_store (target, res);
872       else
873         {
874           if (do_xor)
875             res = expand_binop (mode, add_optab, res, sgn, NULL_RTX, false,
876                                 OPTAB_LIB_WIDEN);
877
878           expand_arith_overflow_result_store (lhs, target, mode, res);
879         }
880     }
881 }
882
883 /* Add negate overflow checking to the statement STMT.  */
884
885 static void
886 expand_neg_overflow (location_t loc, tree lhs, tree arg1, bool is_ubsan)
887 {
888   rtx res, op1;
889   tree fn;
890   rtx_code_label *done_label, *do_error;
891   rtx target = NULL_RTX;
892
893   done_label = gen_label_rtx ();
894   do_error = gen_label_rtx ();
895
896   do_pending_stack_adjust ();
897   op1 = expand_normal (arg1);
898
899   machine_mode mode = TYPE_MODE (TREE_TYPE (arg1));
900   if (lhs)
901     {
902       target = expand_expr (lhs, NULL_RTX, VOIDmode, EXPAND_WRITE);
903       if (!is_ubsan)
904         write_complex_part (target, const0_rtx, true);
905     }
906
907   enum insn_code icode = optab_handler (negv3_optab, mode);
908   if (icode != CODE_FOR_nothing)
909     {
910       struct expand_operand ops[3];
911       rtx_insn *last = get_last_insn ();
912
913       res = gen_reg_rtx (mode);
914       create_output_operand (&ops[0], res, mode);
915       create_input_operand (&ops[1], op1, mode);
916       create_fixed_operand (&ops[2], do_error);
917       if (maybe_expand_insn (icode, 3, ops))
918         {
919           last = get_last_insn ();
920           if (profile_status_for_fn (cfun) != PROFILE_ABSENT
921               && JUMP_P (last)
922               && any_condjump_p (last)
923               && !find_reg_note (last, REG_BR_PROB, 0))
924             add_int_reg_note (last, REG_BR_PROB, PROB_VERY_UNLIKELY);
925           emit_jump (done_label);
926         }
927       else
928         {
929           delete_insns_since (last);
930           icode = CODE_FOR_nothing;
931         }
932     }
933
934   if (icode == CODE_FOR_nothing)
935     {
936       /* Compute the operation.  On RTL level, the addition is always
937          unsigned.  */
938       res = expand_unop (mode, neg_optab, op1, NULL_RTX, false);
939
940       /* Compare the operand with the most negative value.  */
941       rtx minv = expand_normal (TYPE_MIN_VALUE (TREE_TYPE (arg1)));
942       do_compare_rtx_and_jump (op1, minv, NE, true, mode, NULL_RTX, NULL,
943                                done_label, PROB_VERY_LIKELY);
944     }
945
946   emit_label (do_error);
947   if (is_ubsan)
948     {
949       /* Expand the ubsan builtin call.  */
950       push_temp_slots ();
951       fn = ubsan_build_overflow_builtin (NEGATE_EXPR, loc, TREE_TYPE (arg1),
952                                          arg1, NULL_TREE);
953       expand_normal (fn);
954       pop_temp_slots ();
955       do_pending_stack_adjust ();
956     }
957   else if (lhs)
958     write_complex_part (target, const1_rtx, true);
959
960   /* We're done.  */
961   emit_label (done_label);
962
963   if (lhs)
964     {
965       if (is_ubsan)
966         expand_ubsan_result_store (target, res);
967       else
968         expand_arith_overflow_result_store (lhs, target, mode, res);
969     }
970 }
971
972 /* Add mul overflow checking to the statement STMT.  */
973
974 static void
975 expand_mul_overflow (location_t loc, tree lhs, tree arg0, tree arg1,
976                      bool unsr_p, bool uns0_p, bool uns1_p, bool is_ubsan)
977 {
978   rtx res, op0, op1;
979   tree fn, type;
980   rtx_code_label *done_label, *do_error;
981   rtx target = NULL_RTX;
982   signop sign;
983   enum insn_code icode;
984
985   done_label = gen_label_rtx ();
986   do_error = gen_label_rtx ();
987
988   do_pending_stack_adjust ();
989   op0 = expand_normal (arg0);
990   op1 = expand_normal (arg1);
991
992   machine_mode mode = TYPE_MODE (TREE_TYPE (arg0));
993   bool uns = unsr_p;
994   if (lhs)
995     {
996       target = expand_expr (lhs, NULL_RTX, VOIDmode, EXPAND_WRITE);
997       if (!is_ubsan)
998         write_complex_part (target, const0_rtx, true);
999     }
1000
1001   if (is_ubsan)
1002     gcc_assert (!unsr_p && !uns0_p && !uns1_p);
1003
1004   /* We assume both operands and result have the same precision
1005      here (GET_MODE_BITSIZE (mode)), S stands for signed type
1006      with that precision, U for unsigned type with that precision,
1007      sgn for unsigned most significant bit in that precision.
1008      s1 is signed first operand, u1 is unsigned first operand,
1009      s2 is signed second operand, u2 is unsigned second operand,
1010      sr is signed result, ur is unsigned result and the following
1011      rules say how to compute result (which is always result of
1012      the operands as if both were unsigned, cast to the right
1013      signedness) and how to compute whether operation overflowed.
1014      main_ovf (false) stands for jump on signed multiplication
1015      overflow or the main algorithm with uns == false.
1016      main_ovf (true) stands for jump on unsigned multiplication
1017      overflow or the main algorithm with uns == true.
1018
1019      s1 * s2 -> sr
1020         res = (S) ((U) s1 * (U) s2)
1021         ovf = main_ovf (false)
1022      u1 * u2 -> ur
1023         res = u1 * u2
1024         ovf = main_ovf (true)
1025      s1 * u2 -> ur
1026         res = (U) s1 * u2
1027         ovf = (s1 < 0 && u2) || main_ovf (true)
1028      u1 * u2 -> sr
1029         res = (S) (u1 * u2)
1030         ovf = res < 0 || main_ovf (true)
1031      s1 * u2 -> sr
1032         res = (S) ((U) s1 * u2)
1033         ovf = (S) u2 >= 0 ? main_ovf (false)
1034                           : (s1 != 0 && (s1 != -1 || u2 != (U) res))
1035      s1 * s2 -> ur
1036         t1 = (s1 & s2) < 0 ? (-(U) s1) : ((U) s1)
1037         t2 = (s1 & s2) < 0 ? (-(U) s2) : ((U) s2)
1038         res = t1 * t2
1039         ovf = (s1 ^ s2) < 0 ? (s1 && s2) : main_ovf (true)  */
1040
1041   if (uns0_p && !uns1_p)
1042     {
1043       /* Multiplication is commutative, if operand signedness differs,
1044          canonicalize to the first operand being signed and second
1045          unsigned to simplify following code.  */
1046       std::swap (op0, op1);
1047       std::swap (arg0, arg1);
1048       uns0_p = false;
1049       uns1_p = true;
1050     }
1051
1052   int pos_neg0 = get_range_pos_neg (arg0);
1053   int pos_neg1 = get_range_pos_neg (arg1);
1054
1055   /* s1 * u2 -> ur  */
1056   if (!uns0_p && uns1_p && unsr_p)
1057     {
1058       switch (pos_neg0)
1059         {
1060         case 1:
1061           /* If s1 is non-negative, just perform normal u1 * u2 -> ur.  */
1062           goto do_main;
1063         case 2:
1064           /* If s1 is negative, avoid the main code, just multiply and
1065              signal overflow if op1 is not 0.  */
1066           struct separate_ops ops;
1067           ops.code = MULT_EXPR;
1068           ops.type = TREE_TYPE (arg1);
1069           ops.op0 = make_tree (ops.type, op0);
1070           ops.op1 = make_tree (ops.type, op1);
1071           ops.op2 = NULL_TREE;
1072           ops.location = loc;
1073           res = expand_expr_real_2 (&ops, NULL_RTX, mode, EXPAND_NORMAL);
1074           do_compare_rtx_and_jump (op1, const0_rtx, EQ, true, mode, NULL_RTX,
1075                                    NULL, done_label, PROB_VERY_LIKELY);
1076           goto do_error_label;
1077         case 3:
1078           rtx_code_label *do_main_label;
1079           do_main_label = gen_label_rtx ();
1080           do_compare_rtx_and_jump (op0, const0_rtx, GE, false, mode, NULL_RTX,
1081                                    NULL, do_main_label, PROB_VERY_LIKELY);
1082           do_compare_rtx_and_jump (op1, const0_rtx, EQ, true, mode, NULL_RTX,
1083                                    NULL, do_main_label, PROB_VERY_LIKELY);
1084           write_complex_part (target, const1_rtx, true);
1085           emit_label (do_main_label);
1086           goto do_main;
1087         default:
1088           gcc_unreachable ();
1089         }
1090     }
1091
1092   /* u1 * u2 -> sr  */
1093   if (uns0_p && uns1_p && !unsr_p)
1094     {
1095       uns = true;
1096       /* Rest of handling of this case after res is computed.  */
1097       goto do_main;
1098     }
1099
1100   /* s1 * u2 -> sr  */
1101   if (!uns0_p && uns1_p && !unsr_p)
1102     {
1103       switch (pos_neg1)
1104         {
1105         case 1:
1106           goto do_main;
1107         case 2:
1108           /* If (S) u2 is negative (i.e. u2 is larger than maximum of S,
1109              avoid the main code, just multiply and signal overflow
1110              unless 0 * u2 or -1 * ((U) Smin).  */
1111           struct separate_ops ops;
1112           ops.code = MULT_EXPR;
1113           ops.type = TREE_TYPE (arg1);
1114           ops.op0 = make_tree (ops.type, op0);
1115           ops.op1 = make_tree (ops.type, op1);
1116           ops.op2 = NULL_TREE;
1117           ops.location = loc;
1118           res = expand_expr_real_2 (&ops, NULL_RTX, mode, EXPAND_NORMAL);
1119           do_compare_rtx_and_jump (op0, const0_rtx, EQ, true, mode, NULL_RTX,
1120                                    NULL, done_label, PROB_VERY_LIKELY);
1121           do_compare_rtx_and_jump (op0, constm1_rtx, NE, true, mode, NULL_RTX,
1122                                    NULL, do_error, PROB_VERY_UNLIKELY);
1123           int prec;
1124           prec = GET_MODE_PRECISION (mode);
1125           rtx sgn;
1126           sgn = immed_wide_int_const (wi::min_value (prec, SIGNED), mode);
1127           do_compare_rtx_and_jump (op1, sgn, EQ, true, mode, NULL_RTX,
1128                                    NULL, done_label, PROB_VERY_LIKELY);
1129           goto do_error_label;
1130         case 3:
1131           /* Rest of handling of this case after res is computed.  */
1132           goto do_main;
1133         default:
1134           gcc_unreachable ();
1135         }
1136     }
1137
1138   /* s1 * s2 -> ur  */
1139   if (!uns0_p && !uns1_p && unsr_p)
1140     {
1141       rtx tem, tem2;
1142       switch (pos_neg0 | pos_neg1)
1143         {
1144         case 1: /* Both operands known to be non-negative.  */
1145           goto do_main;
1146         case 2: /* Both operands known to be negative.  */
1147           op0 = expand_unop (mode, neg_optab, op0, NULL_RTX, false);
1148           op1 = expand_unop (mode, neg_optab, op1, NULL_RTX, false);
1149           /* Avoid looking at arg0/arg1 ranges, as we've changed
1150              the arguments.  */
1151           arg0 = error_mark_node;
1152           arg1 = error_mark_node;
1153           goto do_main;
1154         case 3:
1155           if ((pos_neg0 ^ pos_neg1) == 3)
1156             {
1157               /* If one operand is known to be negative and the other
1158                  non-negative, this overflows always, unless the non-negative
1159                  one is 0.  Just do normal multiply and set overflow
1160                  unless one of the operands is 0.  */
1161               struct separate_ops ops;
1162               ops.code = MULT_EXPR;
1163               ops.type
1164                 = build_nonstandard_integer_type (GET_MODE_PRECISION (mode),
1165                                                   1);
1166               ops.op0 = make_tree (ops.type, op0);
1167               ops.op1 = make_tree (ops.type, op1);
1168               ops.op2 = NULL_TREE;
1169               ops.location = loc;
1170               res = expand_expr_real_2 (&ops, NULL_RTX, mode, EXPAND_NORMAL);
1171               tem = expand_binop (mode, and_optab, op0, op1, NULL_RTX, false,
1172                                   OPTAB_LIB_WIDEN);
1173               do_compare_rtx_and_jump (tem, const0_rtx, EQ, true, mode,
1174                                        NULL_RTX, NULL, done_label,
1175                                        PROB_VERY_LIKELY);
1176               goto do_error_label;
1177             }
1178           /* The general case, do all the needed comparisons at runtime.  */
1179           rtx_code_label *do_main_label, *after_negate_label;
1180           rtx rop0, rop1;
1181           rop0 = gen_reg_rtx (mode);
1182           rop1 = gen_reg_rtx (mode);
1183           emit_move_insn (rop0, op0);
1184           emit_move_insn (rop1, op1);
1185           op0 = rop0;
1186           op1 = rop1;
1187           do_main_label = gen_label_rtx ();
1188           after_negate_label = gen_label_rtx ();
1189           tem = expand_binop (mode, and_optab, op0, op1, NULL_RTX, false,
1190                               OPTAB_LIB_WIDEN);
1191           do_compare_rtx_and_jump (tem, const0_rtx, GE, false, mode, NULL_RTX,
1192                                    NULL, after_negate_label, PROB_VERY_LIKELY);
1193           /* Both arguments negative here, negate them and continue with
1194              normal unsigned overflow checking multiplication.  */
1195           emit_move_insn (op0, expand_unop (mode, neg_optab, op0,
1196                                             NULL_RTX, false));
1197           emit_move_insn (op1, expand_unop (mode, neg_optab, op1,
1198                                             NULL_RTX, false));
1199           /* Avoid looking at arg0/arg1 ranges, as we might have changed
1200              the arguments.  */
1201           arg0 = error_mark_node;
1202           arg1 = error_mark_node;
1203           emit_jump (do_main_label);
1204           emit_label (after_negate_label);
1205           tem2 = expand_binop (mode, xor_optab, op0, op1, NULL_RTX, false,
1206                                OPTAB_LIB_WIDEN);
1207           do_compare_rtx_and_jump (tem2, const0_rtx, GE, false, mode, NULL_RTX,
1208                                    NULL, do_main_label, PROB_VERY_LIKELY);
1209           /* One argument is negative here, the other positive.  This
1210              overflows always, unless one of the arguments is 0.  But
1211              if e.g. s2 is 0, (U) s1 * 0 doesn't overflow, whatever s1
1212              is, thus we can keep do_main code oring in overflow as is.  */
1213           do_compare_rtx_and_jump (tem, const0_rtx, EQ, true, mode, NULL_RTX,
1214                                    NULL, do_main_label, PROB_VERY_LIKELY);
1215           write_complex_part (target, const1_rtx, true);
1216           emit_label (do_main_label);
1217           goto do_main;
1218         default:
1219           gcc_unreachable ();
1220         }
1221     }
1222
1223  do_main:
1224   type = build_nonstandard_integer_type (GET_MODE_PRECISION (mode), uns);
1225   sign = uns ? UNSIGNED : SIGNED;
1226   icode = optab_handler (uns ? umulv4_optab : mulv4_optab, mode);
1227   if (icode != CODE_FOR_nothing)
1228     {
1229       struct expand_operand ops[4];
1230       rtx_insn *last = get_last_insn ();
1231
1232       res = gen_reg_rtx (mode);
1233       create_output_operand (&ops[0], res, mode);
1234       create_input_operand (&ops[1], op0, mode);
1235       create_input_operand (&ops[2], op1, mode);
1236       create_fixed_operand (&ops[3], do_error);
1237       if (maybe_expand_insn (icode, 4, ops))
1238         {
1239           last = get_last_insn ();
1240           if (profile_status_for_fn (cfun) != PROFILE_ABSENT
1241               && JUMP_P (last)
1242               && any_condjump_p (last)
1243               && !find_reg_note (last, REG_BR_PROB, 0))
1244             add_int_reg_note (last, REG_BR_PROB, PROB_VERY_UNLIKELY);
1245           emit_jump (done_label);
1246         }
1247       else
1248         {
1249           delete_insns_since (last);
1250           icode = CODE_FOR_nothing;
1251         }
1252     }
1253
1254   if (icode == CODE_FOR_nothing)
1255     {
1256       struct separate_ops ops;
1257       int prec = GET_MODE_PRECISION (mode);
1258       machine_mode hmode = mode_for_size (prec / 2, MODE_INT, 1);
1259       ops.op0 = make_tree (type, op0);
1260       ops.op1 = make_tree (type, op1);
1261       ops.op2 = NULL_TREE;
1262       ops.location = loc;
1263       if (GET_MODE_2XWIDER_MODE (mode) != VOIDmode
1264           && targetm.scalar_mode_supported_p (GET_MODE_2XWIDER_MODE (mode)))
1265         {
1266           machine_mode wmode = GET_MODE_2XWIDER_MODE (mode);
1267           ops.code = WIDEN_MULT_EXPR;
1268           ops.type
1269             = build_nonstandard_integer_type (GET_MODE_PRECISION (wmode), uns);
1270
1271           res = expand_expr_real_2 (&ops, NULL_RTX, wmode, EXPAND_NORMAL);
1272           rtx hipart = expand_shift (RSHIFT_EXPR, wmode, res, prec,
1273                                      NULL_RTX, uns);
1274           hipart = gen_lowpart (mode, hipart);
1275           res = gen_lowpart (mode, res);
1276           if (uns)
1277             /* For the unsigned multiplication, there was overflow if
1278                HIPART is non-zero.  */
1279             do_compare_rtx_and_jump (hipart, const0_rtx, EQ, true, mode,
1280                                      NULL_RTX, NULL, done_label,
1281                                      PROB_VERY_LIKELY);
1282           else
1283             {
1284               rtx signbit = expand_shift (RSHIFT_EXPR, mode, res, prec - 1,
1285                                           NULL_RTX, 0);
1286               /* RES is low half of the double width result, HIPART
1287                  the high half.  There was overflow if
1288                  HIPART is different from RES < 0 ? -1 : 0.  */
1289               do_compare_rtx_and_jump (signbit, hipart, EQ, true, mode,
1290                                        NULL_RTX, NULL, done_label,
1291                                        PROB_VERY_LIKELY);
1292             }
1293         }
1294       else if (hmode != BLKmode && 2 * GET_MODE_PRECISION (hmode) == prec)
1295         {
1296           rtx_code_label *large_op0 = gen_label_rtx ();
1297           rtx_code_label *small_op0_large_op1 = gen_label_rtx ();
1298           rtx_code_label *one_small_one_large = gen_label_rtx ();
1299           rtx_code_label *both_ops_large = gen_label_rtx ();
1300           rtx_code_label *after_hipart_neg = uns ? NULL : gen_label_rtx ();
1301           rtx_code_label *after_lopart_neg = uns ? NULL : gen_label_rtx ();
1302           rtx_code_label *do_overflow = gen_label_rtx ();
1303           rtx_code_label *hipart_different = uns ? NULL : gen_label_rtx ();
1304
1305           unsigned int hprec = GET_MODE_PRECISION (hmode);
1306           rtx hipart0 = expand_shift (RSHIFT_EXPR, mode, op0, hprec,
1307                                       NULL_RTX, uns);
1308           hipart0 = gen_lowpart (hmode, hipart0);
1309           rtx lopart0 = gen_lowpart (hmode, op0);
1310           rtx signbit0 = const0_rtx;
1311           if (!uns)
1312             signbit0 = expand_shift (RSHIFT_EXPR, hmode, lopart0, hprec - 1,
1313                                      NULL_RTX, 0);
1314           rtx hipart1 = expand_shift (RSHIFT_EXPR, mode, op1, hprec,
1315                                       NULL_RTX, uns);
1316           hipart1 = gen_lowpart (hmode, hipart1);
1317           rtx lopart1 = gen_lowpart (hmode, op1);
1318           rtx signbit1 = const0_rtx;
1319           if (!uns)
1320             signbit1 = expand_shift (RSHIFT_EXPR, hmode, lopart1, hprec - 1,
1321                                      NULL_RTX, 0);
1322
1323           res = gen_reg_rtx (mode);
1324
1325           /* True if op0 resp. op1 are known to be in the range of
1326              halfstype.  */
1327           bool op0_small_p = false;
1328           bool op1_small_p = false;
1329           /* True if op0 resp. op1 are known to have all zeros or all ones
1330              in the upper half of bits, but are not known to be
1331              op{0,1}_small_p.  */
1332           bool op0_medium_p = false;
1333           bool op1_medium_p = false;
1334           /* -1 if op{0,1} is known to be negative, 0 if it is known to be
1335              nonnegative, 1 if unknown.  */
1336           int op0_sign = 1;
1337           int op1_sign = 1;
1338
1339           if (pos_neg0 == 1)
1340             op0_sign = 0;
1341           else if (pos_neg0 == 2)
1342             op0_sign = -1;
1343           if (pos_neg1 == 1)
1344             op1_sign = 0;
1345           else if (pos_neg1 == 2)
1346             op1_sign = -1;
1347
1348           unsigned int mprec0 = prec;
1349           if (arg0 != error_mark_node)
1350             mprec0 = get_min_precision (arg0, sign);
1351           if (mprec0 <= hprec)
1352             op0_small_p = true;
1353           else if (!uns && mprec0 <= hprec + 1)
1354             op0_medium_p = true;
1355           unsigned int mprec1 = prec;
1356           if (arg1 != error_mark_node)
1357             mprec1 = get_min_precision (arg1, sign);
1358           if (mprec1 <= hprec)
1359             op1_small_p = true;
1360           else if (!uns && mprec1 <= hprec + 1)
1361             op1_medium_p = true;
1362
1363           int smaller_sign = 1;
1364           int larger_sign = 1;
1365           if (op0_small_p)
1366             {
1367               smaller_sign = op0_sign;
1368               larger_sign = op1_sign;
1369             }
1370           else if (op1_small_p)
1371             {
1372               smaller_sign = op1_sign;
1373               larger_sign = op0_sign;
1374             }
1375           else if (op0_sign == op1_sign)
1376             {
1377               smaller_sign = op0_sign;
1378               larger_sign = op0_sign;
1379             }
1380
1381           if (!op0_small_p)
1382             do_compare_rtx_and_jump (signbit0, hipart0, NE, true, hmode,
1383                                      NULL_RTX, NULL, large_op0,
1384                                      PROB_UNLIKELY);
1385
1386           if (!op1_small_p)
1387             do_compare_rtx_and_jump (signbit1, hipart1, NE, true, hmode,
1388                                      NULL_RTX, NULL, small_op0_large_op1,
1389                                      PROB_UNLIKELY);
1390
1391           /* If both op0 and op1 are sign (!uns) or zero (uns) extended from
1392              hmode to mode, the multiplication will never overflow.  We can
1393              do just one hmode x hmode => mode widening multiplication.  */
1394           rtx lopart0s = lopart0, lopart1s = lopart1;
1395           if (GET_CODE (lopart0) == SUBREG)
1396             {
1397               lopart0s = shallow_copy_rtx (lopart0);
1398               SUBREG_PROMOTED_VAR_P (lopart0s) = 1;
1399               SUBREG_PROMOTED_SET (lopart0s, uns ? SRP_UNSIGNED : SRP_SIGNED);
1400             }
1401           if (GET_CODE (lopart1) == SUBREG)
1402             {
1403               lopart1s = shallow_copy_rtx (lopart1);
1404               SUBREG_PROMOTED_VAR_P (lopart1s) = 1;
1405               SUBREG_PROMOTED_SET (lopart1s, uns ? SRP_UNSIGNED : SRP_SIGNED);
1406             }
1407           tree halfstype = build_nonstandard_integer_type (hprec, uns);
1408           ops.op0 = make_tree (halfstype, lopart0s);
1409           ops.op1 = make_tree (halfstype, lopart1s);
1410           ops.code = WIDEN_MULT_EXPR;
1411           ops.type = type;
1412           rtx thisres
1413             = expand_expr_real_2 (&ops, NULL_RTX, mode, EXPAND_NORMAL);
1414           emit_move_insn (res, thisres);
1415           emit_jump (done_label);
1416
1417           emit_label (small_op0_large_op1);
1418
1419           /* If op0 is sign (!uns) or zero (uns) extended from hmode to mode,
1420              but op1 is not, just swap the arguments and handle it as op1
1421              sign/zero extended, op0 not.  */
1422           rtx larger = gen_reg_rtx (mode);
1423           rtx hipart = gen_reg_rtx (hmode);
1424           rtx lopart = gen_reg_rtx (hmode);
1425           emit_move_insn (larger, op1);
1426           emit_move_insn (hipart, hipart1);
1427           emit_move_insn (lopart, lopart0);
1428           emit_jump (one_small_one_large);
1429
1430           emit_label (large_op0);
1431
1432           if (!op1_small_p)
1433             do_compare_rtx_and_jump (signbit1, hipart1, NE, true, hmode,
1434                                      NULL_RTX, NULL, both_ops_large,
1435                                      PROB_UNLIKELY);
1436
1437           /* If op1 is sign (!uns) or zero (uns) extended from hmode to mode,
1438              but op0 is not, prepare larger, hipart and lopart pseudos and
1439              handle it together with small_op0_large_op1.  */
1440           emit_move_insn (larger, op0);
1441           emit_move_insn (hipart, hipart0);
1442           emit_move_insn (lopart, lopart1);
1443
1444           emit_label (one_small_one_large);
1445
1446           /* lopart is the low part of the operand that is sign extended
1447              to mode, larger is the other operand, hipart is the
1448              high part of larger and lopart0 and lopart1 are the low parts
1449              of both operands.
1450              We perform lopart0 * lopart1 and lopart * hipart widening
1451              multiplications.  */
1452           tree halfutype = build_nonstandard_integer_type (hprec, 1);
1453           ops.op0 = make_tree (halfutype, lopart0);
1454           ops.op1 = make_tree (halfutype, lopart1);
1455           rtx lo0xlo1
1456             = expand_expr_real_2 (&ops, NULL_RTX, mode, EXPAND_NORMAL);
1457
1458           ops.op0 = make_tree (halfutype, lopart);
1459           ops.op1 = make_tree (halfutype, hipart);
1460           rtx loxhi = gen_reg_rtx (mode);
1461           rtx tem = expand_expr_real_2 (&ops, NULL_RTX, mode, EXPAND_NORMAL);
1462           emit_move_insn (loxhi, tem);
1463
1464           if (!uns)
1465             {
1466               /* if (hipart < 0) loxhi -= lopart << (bitsize / 2);  */
1467               if (larger_sign == 0)
1468                 emit_jump (after_hipart_neg);
1469               else if (larger_sign != -1)
1470                 do_compare_rtx_and_jump (hipart, const0_rtx, GE, false, hmode,
1471                                          NULL_RTX, NULL, after_hipart_neg,
1472                                          PROB_EVEN);
1473
1474               tem = convert_modes (mode, hmode, lopart, 1);
1475               tem = expand_shift (LSHIFT_EXPR, mode, tem, hprec, NULL_RTX, 1);
1476               tem = expand_simple_binop (mode, MINUS, loxhi, tem, NULL_RTX,
1477                                          1, OPTAB_DIRECT);
1478               emit_move_insn (loxhi, tem);
1479
1480               emit_label (after_hipart_neg);
1481
1482               /* if (lopart < 0) loxhi -= larger;  */
1483               if (smaller_sign == 0)
1484                 emit_jump (after_lopart_neg);
1485               else if (smaller_sign != -1)
1486                 do_compare_rtx_and_jump (lopart, const0_rtx, GE, false, hmode,
1487                                          NULL_RTX, NULL, after_lopart_neg,
1488                                          PROB_EVEN);
1489
1490               tem = expand_simple_binop (mode, MINUS, loxhi, larger, NULL_RTX,
1491                                          1, OPTAB_DIRECT);
1492               emit_move_insn (loxhi, tem);
1493
1494               emit_label (after_lopart_neg);
1495             }
1496
1497           /* loxhi += (uns) lo0xlo1 >> (bitsize / 2);  */
1498           tem = expand_shift (RSHIFT_EXPR, mode, lo0xlo1, hprec, NULL_RTX, 1);
1499           tem = expand_simple_binop (mode, PLUS, loxhi, tem, NULL_RTX,
1500                                      1, OPTAB_DIRECT);
1501           emit_move_insn (loxhi, tem);
1502
1503           /* if (loxhi >> (bitsize / 2)
1504                  == (hmode) loxhi >> (bitsize / 2 - 1))  (if !uns)
1505              if (loxhi >> (bitsize / 2) == 0             (if uns).  */
1506           rtx hipartloxhi = expand_shift (RSHIFT_EXPR, mode, loxhi, hprec,
1507                                           NULL_RTX, 0);
1508           hipartloxhi = gen_lowpart (hmode, hipartloxhi);
1509           rtx signbitloxhi = const0_rtx;
1510           if (!uns)
1511             signbitloxhi = expand_shift (RSHIFT_EXPR, hmode,
1512                                          gen_lowpart (hmode, loxhi),
1513                                          hprec - 1, NULL_RTX, 0);
1514
1515           do_compare_rtx_and_jump (signbitloxhi, hipartloxhi, NE, true, hmode,
1516                                    NULL_RTX, NULL, do_overflow,
1517                                    PROB_VERY_UNLIKELY);
1518
1519           /* res = (loxhi << (bitsize / 2)) | (hmode) lo0xlo1;  */
1520           rtx loxhishifted = expand_shift (LSHIFT_EXPR, mode, loxhi, hprec,
1521                                            NULL_RTX, 1);
1522           tem = convert_modes (mode, hmode, gen_lowpart (hmode, lo0xlo1), 1);
1523
1524           tem = expand_simple_binop (mode, IOR, loxhishifted, tem, res,
1525                                      1, OPTAB_DIRECT);
1526           if (tem != res)
1527             emit_move_insn (res, tem);
1528           emit_jump (done_label);
1529
1530           emit_label (both_ops_large);
1531
1532           /* If both operands are large (not sign (!uns) or zero (uns)
1533              extended from hmode), then perform the full multiplication
1534              which will be the result of the operation.
1535              The only cases which don't overflow are for signed multiplication
1536              some cases where both hipart0 and highpart1 are 0 or -1.
1537              For unsigned multiplication when high parts are both non-zero
1538              this overflows always.  */
1539           ops.code = MULT_EXPR;
1540           ops.op0 = make_tree (type, op0);
1541           ops.op1 = make_tree (type, op1);
1542           tem = expand_expr_real_2 (&ops, NULL_RTX, mode, EXPAND_NORMAL);
1543           emit_move_insn (res, tem);
1544
1545           if (!uns)
1546             {
1547               if (!op0_medium_p)
1548                 {
1549                   tem = expand_simple_binop (hmode, PLUS, hipart0, const1_rtx,
1550                                              NULL_RTX, 1, OPTAB_DIRECT);
1551                   do_compare_rtx_and_jump (tem, const1_rtx, GTU, true, hmode,
1552                                            NULL_RTX, NULL, do_error,
1553                                            PROB_VERY_UNLIKELY);
1554                 }
1555
1556               if (!op1_medium_p)
1557                 {
1558                   tem = expand_simple_binop (hmode, PLUS, hipart1, const1_rtx,
1559                                              NULL_RTX, 1, OPTAB_DIRECT);
1560                   do_compare_rtx_and_jump (tem, const1_rtx, GTU, true, hmode,
1561                                            NULL_RTX, NULL, do_error,
1562                                            PROB_VERY_UNLIKELY);
1563                 }
1564
1565               /* At this point hipart{0,1} are both in [-1, 0].  If they are
1566                  the same, overflow happened if res is negative, if they are
1567                  different, overflow happened if res is positive.  */
1568               if (op0_sign != 1 && op1_sign != 1 && op0_sign != op1_sign)
1569                 emit_jump (hipart_different);
1570               else if (op0_sign == 1 || op1_sign == 1)
1571                 do_compare_rtx_and_jump (hipart0, hipart1, NE, true, hmode,
1572                                          NULL_RTX, NULL, hipart_different,
1573                                          PROB_EVEN);
1574
1575               do_compare_rtx_and_jump (res, const0_rtx, LT, false, mode,
1576                                        NULL_RTX, NULL, do_error,
1577                                        PROB_VERY_UNLIKELY);
1578               emit_jump (done_label);
1579
1580               emit_label (hipart_different);
1581
1582               do_compare_rtx_and_jump (res, const0_rtx, GE, false, mode,
1583                                        NULL_RTX, NULL, do_error,
1584                                        PROB_VERY_UNLIKELY);
1585               emit_jump (done_label);
1586             }
1587
1588           emit_label (do_overflow);
1589
1590           /* Overflow, do full multiplication and fallthru into do_error.  */
1591           ops.op0 = make_tree (type, op0);
1592           ops.op1 = make_tree (type, op1);
1593           tem = expand_expr_real_2 (&ops, NULL_RTX, mode, EXPAND_NORMAL);
1594           emit_move_insn (res, tem);
1595         }
1596       else
1597         {
1598           gcc_assert (!is_ubsan);
1599           ops.code = MULT_EXPR;
1600           ops.type = type;
1601           res = expand_expr_real_2 (&ops, NULL_RTX, mode, EXPAND_NORMAL);
1602           emit_jump (done_label);
1603         }
1604     }
1605
1606  do_error_label:
1607   emit_label (do_error);
1608   if (is_ubsan)
1609     {
1610       /* Expand the ubsan builtin call.  */
1611       push_temp_slots ();
1612       fn = ubsan_build_overflow_builtin (MULT_EXPR, loc, TREE_TYPE (arg0),
1613                                          arg0, arg1);
1614       expand_normal (fn);
1615       pop_temp_slots ();
1616       do_pending_stack_adjust ();
1617     }
1618   else if (lhs)
1619     write_complex_part (target, const1_rtx, true);
1620
1621   /* We're done.  */
1622   emit_label (done_label);
1623
1624   /* u1 * u2 -> sr  */
1625   if (uns0_p && uns1_p && !unsr_p)
1626     {
1627       rtx_code_label *all_done_label = gen_label_rtx ();
1628       do_compare_rtx_and_jump (res, const0_rtx, GE, false, mode, NULL_RTX,
1629                                NULL, all_done_label, PROB_VERY_LIKELY);
1630       write_complex_part (target, const1_rtx, true);
1631       emit_label (all_done_label);
1632     }
1633
1634   /* s1 * u2 -> sr  */
1635   if (!uns0_p && uns1_p && !unsr_p && pos_neg1 == 3)
1636     {
1637       rtx_code_label *all_done_label = gen_label_rtx ();
1638       rtx_code_label *set_noovf = gen_label_rtx ();
1639       do_compare_rtx_and_jump (op1, const0_rtx, GE, false, mode, NULL_RTX,
1640                                NULL, all_done_label, PROB_VERY_LIKELY);
1641       write_complex_part (target, const1_rtx, true);
1642       do_compare_rtx_and_jump (op0, const0_rtx, EQ, true, mode, NULL_RTX,
1643                                NULL, set_noovf, PROB_VERY_LIKELY);
1644       do_compare_rtx_and_jump (op0, constm1_rtx, NE, true, mode, NULL_RTX,
1645                                NULL, all_done_label, PROB_VERY_UNLIKELY);
1646       do_compare_rtx_and_jump (op1, res, NE, true, mode, NULL_RTX, NULL,
1647                                all_done_label, PROB_VERY_UNLIKELY);
1648       emit_label (set_noovf);
1649       write_complex_part (target, const0_rtx, true);
1650       emit_label (all_done_label);
1651     }
1652
1653   if (lhs)
1654     {
1655       if (is_ubsan)
1656         expand_ubsan_result_store (target, res);
1657       else
1658         expand_arith_overflow_result_store (lhs, target, mode, res);
1659     }
1660 }
1661
1662 /* Expand UBSAN_CHECK_ADD call STMT.  */
1663
1664 static void
1665 expand_UBSAN_CHECK_ADD (internal_fn, gcall *stmt)
1666 {
1667   location_t loc = gimple_location (stmt);
1668   tree lhs = gimple_call_lhs (stmt);
1669   tree arg0 = gimple_call_arg (stmt, 0);
1670   tree arg1 = gimple_call_arg (stmt, 1);
1671   expand_addsub_overflow (loc, PLUS_EXPR, lhs, arg0, arg1,
1672                           false, false, false, true);
1673 }
1674
1675 /* Expand UBSAN_CHECK_SUB call STMT.  */
1676
1677 static void
1678 expand_UBSAN_CHECK_SUB (internal_fn, gcall *stmt)
1679 {
1680   location_t loc = gimple_location (stmt);
1681   tree lhs = gimple_call_lhs (stmt);
1682   tree arg0 = gimple_call_arg (stmt, 0);
1683   tree arg1 = gimple_call_arg (stmt, 1);
1684   if (integer_zerop (arg0))
1685     expand_neg_overflow (loc, lhs, arg1, true);
1686   else
1687     expand_addsub_overflow (loc, MINUS_EXPR, lhs, arg0, arg1,
1688                             false, false, false, true);
1689 }
1690
1691 /* Expand UBSAN_CHECK_MUL call STMT.  */
1692
1693 static void
1694 expand_UBSAN_CHECK_MUL (internal_fn, gcall *stmt)
1695 {
1696   location_t loc = gimple_location (stmt);
1697   tree lhs = gimple_call_lhs (stmt);
1698   tree arg0 = gimple_call_arg (stmt, 0);
1699   tree arg1 = gimple_call_arg (stmt, 1);
1700   expand_mul_overflow (loc, lhs, arg0, arg1, false, false, false, true);
1701 }
1702
1703 /* Helper function for {ADD,SUB,MUL}_OVERFLOW call stmt expansion.  */
1704
1705 static void
1706 expand_arith_overflow (enum tree_code code, gimple *stmt)
1707 {
1708   tree lhs = gimple_call_lhs (stmt);
1709   if (lhs == NULL_TREE)
1710     return;
1711   tree arg0 = gimple_call_arg (stmt, 0);
1712   tree arg1 = gimple_call_arg (stmt, 1);
1713   tree type = TREE_TYPE (TREE_TYPE (lhs));
1714   int uns0_p = TYPE_UNSIGNED (TREE_TYPE (arg0));
1715   int uns1_p = TYPE_UNSIGNED (TREE_TYPE (arg1));
1716   int unsr_p = TYPE_UNSIGNED (type);
1717   int prec0 = TYPE_PRECISION (TREE_TYPE (arg0));
1718   int prec1 = TYPE_PRECISION (TREE_TYPE (arg1));
1719   int precres = TYPE_PRECISION (type);
1720   location_t loc = gimple_location (stmt);
1721   if (!uns0_p && get_range_pos_neg (arg0) == 1)
1722     uns0_p = true;
1723   if (!uns1_p && get_range_pos_neg (arg1) == 1)
1724     uns1_p = true;
1725   int pr = get_min_precision (arg0, uns0_p ? UNSIGNED : SIGNED);
1726   prec0 = MIN (prec0, pr);
1727   pr = get_min_precision (arg1, uns1_p ? UNSIGNED : SIGNED);
1728   prec1 = MIN (prec1, pr);
1729
1730   /* If uns0_p && uns1_p, precop is minimum needed precision
1731      of unsigned type to hold the exact result, otherwise
1732      precop is minimum needed precision of signed type to
1733      hold the exact result.  */
1734   int precop;
1735   if (code == MULT_EXPR)
1736     precop = prec0 + prec1 + (uns0_p != uns1_p);
1737   else
1738     {
1739       if (uns0_p == uns1_p)
1740         precop = MAX (prec0, prec1) + 1;
1741       else if (uns0_p)
1742         precop = MAX (prec0 + 1, prec1) + 1;
1743       else
1744         precop = MAX (prec0, prec1 + 1) + 1;
1745     }
1746   int orig_precres = precres;
1747
1748   do
1749     {
1750       if ((uns0_p && uns1_p)
1751           ? ((precop + !unsr_p) <= precres
1752              /* u1 - u2 -> ur can overflow, no matter what precision
1753                 the result has.  */
1754              && (code != MINUS_EXPR || !unsr_p))
1755           : (!unsr_p && precop <= precres))
1756         {
1757           /* The infinity precision result will always fit into result.  */
1758           rtx target = expand_expr (lhs, NULL_RTX, VOIDmode, EXPAND_WRITE);
1759           write_complex_part (target, const0_rtx, true);
1760           enum machine_mode mode = TYPE_MODE (type);
1761           struct separate_ops ops;
1762           ops.code = code;
1763           ops.type = type;
1764           ops.op0 = fold_convert_loc (loc, type, arg0);
1765           ops.op1 = fold_convert_loc (loc, type, arg1);
1766           ops.op2 = NULL_TREE;
1767           ops.location = loc;
1768           rtx tem = expand_expr_real_2 (&ops, NULL_RTX, mode, EXPAND_NORMAL);
1769           expand_arith_overflow_result_store (lhs, target, mode, tem);
1770           return;
1771         }
1772
1773       /* For sub-word operations, if target doesn't have them, start
1774          with precres widening right away, otherwise do it only
1775          if the most simple cases can't be used.  */
1776       if (WORD_REGISTER_OPERATIONS
1777           && orig_precres == precres
1778           && precres < BITS_PER_WORD)
1779         ;
1780       else if ((uns0_p && uns1_p && unsr_p && prec0 <= precres
1781                 && prec1 <= precres)
1782           || ((!uns0_p || !uns1_p) && !unsr_p
1783               && prec0 + uns0_p <= precres
1784               && prec1 + uns1_p <= precres))
1785         {
1786           arg0 = fold_convert_loc (loc, type, arg0);
1787           arg1 = fold_convert_loc (loc, type, arg1);
1788           switch (code)
1789             {
1790             case MINUS_EXPR:
1791               if (integer_zerop (arg0) && !unsr_p)
1792                 expand_neg_overflow (loc, lhs, arg1, false);
1793               /* FALLTHRU */
1794             case PLUS_EXPR:
1795               expand_addsub_overflow (loc, code, lhs, arg0, arg1,
1796                                       unsr_p, unsr_p, unsr_p, false);
1797               return;
1798             case MULT_EXPR:
1799               expand_mul_overflow (loc, lhs, arg0, arg1,
1800                                    unsr_p, unsr_p, unsr_p, false);
1801               return;
1802             default:
1803               gcc_unreachable ();
1804             }
1805         }
1806
1807       /* For sub-word operations, retry with a wider type first.  */
1808       if (orig_precres == precres && precop <= BITS_PER_WORD)
1809         {
1810 #if WORD_REGISTER_OPERATIONS
1811           int p = BITS_PER_WORD;
1812 #else
1813           int p = precop;
1814 #endif
1815           enum machine_mode m = smallest_mode_for_size (p, MODE_INT);
1816           tree optype = build_nonstandard_integer_type (GET_MODE_PRECISION (m),
1817                                                         uns0_p && uns1_p
1818                                                         && unsr_p);
1819           p = TYPE_PRECISION (optype);
1820           if (p > precres)
1821             {
1822               precres = p;
1823               unsr_p = TYPE_UNSIGNED (optype);
1824               type = optype;
1825               continue;
1826             }
1827         }
1828
1829       if (prec0 <= precres && prec1 <= precres)
1830         {
1831           tree types[2];
1832           if (unsr_p)
1833             {
1834               types[0] = build_nonstandard_integer_type (precres, 0);
1835               types[1] = type;
1836             }
1837           else
1838             {
1839               types[0] = type;
1840               types[1] = build_nonstandard_integer_type (precres, 1);
1841             }
1842           arg0 = fold_convert_loc (loc, types[uns0_p], arg0);
1843           arg1 = fold_convert_loc (loc, types[uns1_p], arg1);
1844           if (code != MULT_EXPR)
1845             expand_addsub_overflow (loc, code, lhs, arg0, arg1, unsr_p,
1846                                     uns0_p, uns1_p, false);
1847           else
1848             expand_mul_overflow (loc, lhs, arg0, arg1, unsr_p,
1849                                  uns0_p, uns1_p, false);
1850           return;
1851         }
1852
1853       /* Retry with a wider type.  */
1854       if (orig_precres == precres)
1855         {
1856           int p = MAX (prec0, prec1);
1857           enum machine_mode m = smallest_mode_for_size (p, MODE_INT);
1858           tree optype = build_nonstandard_integer_type (GET_MODE_PRECISION (m),
1859                                                         uns0_p && uns1_p
1860                                                         && unsr_p);
1861           p = TYPE_PRECISION (optype);
1862           if (p > precres)
1863             {
1864               precres = p;
1865               unsr_p = TYPE_UNSIGNED (optype);
1866               type = optype;
1867               continue;
1868             }
1869         }
1870
1871       gcc_unreachable ();
1872     }
1873   while (1);
1874 }
1875
1876 /* Expand ADD_OVERFLOW STMT.  */
1877
1878 static void
1879 expand_ADD_OVERFLOW (internal_fn, gcall *stmt)
1880 {
1881   expand_arith_overflow (PLUS_EXPR, stmt);
1882 }
1883
1884 /* Expand SUB_OVERFLOW STMT.  */
1885
1886 static void
1887 expand_SUB_OVERFLOW (internal_fn, gcall *stmt)
1888 {
1889   expand_arith_overflow (MINUS_EXPR, stmt);
1890 }
1891
1892 /* Expand MUL_OVERFLOW STMT.  */
1893
1894 static void
1895 expand_MUL_OVERFLOW (internal_fn, gcall *stmt)
1896 {
1897   expand_arith_overflow (MULT_EXPR, stmt);
1898 }
1899
1900 /* This should get folded in tree-vectorizer.c.  */
1901
1902 static void
1903 expand_LOOP_VECTORIZED (internal_fn, gcall *)
1904 {
1905   gcc_unreachable ();
1906 }
1907
1908 /* Expand MASK_LOAD call STMT using optab OPTAB.  */
1909
1910 static void
1911 expand_mask_load_optab_fn (internal_fn, gcall *stmt, convert_optab optab)
1912 {
1913   struct expand_operand ops[3];
1914   tree type, lhs, rhs, maskt, ptr;
1915   rtx mem, target, mask;
1916   unsigned align;
1917
1918   maskt = gimple_call_arg (stmt, 2);
1919   lhs = gimple_call_lhs (stmt);
1920   if (lhs == NULL_TREE)
1921     return;
1922   type = TREE_TYPE (lhs);
1923   ptr = build_int_cst (TREE_TYPE (gimple_call_arg (stmt, 1)), 0);
1924   align = tree_to_shwi (gimple_call_arg (stmt, 1));
1925   if (TYPE_ALIGN (type) != align)
1926     type = build_aligned_type (type, align);
1927   rhs = fold_build2 (MEM_REF, type, gimple_call_arg (stmt, 0), ptr);
1928
1929   mem = expand_expr (rhs, NULL_RTX, VOIDmode, EXPAND_WRITE);
1930   gcc_assert (MEM_P (mem));
1931   mask = expand_normal (maskt);
1932   target = expand_expr (lhs, NULL_RTX, VOIDmode, EXPAND_WRITE);
1933   create_output_operand (&ops[0], target, TYPE_MODE (type));
1934   create_fixed_operand (&ops[1], mem);
1935   create_input_operand (&ops[2], mask, TYPE_MODE (TREE_TYPE (maskt)));
1936   expand_insn (convert_optab_handler (optab, TYPE_MODE (type),
1937                                       TYPE_MODE (TREE_TYPE (maskt))),
1938                3, ops);
1939 }
1940
1941 /* Expand MASK_STORE call STMT using optab OPTAB.  */
1942
1943 static void
1944 expand_mask_store_optab_fn (internal_fn, gcall *stmt, convert_optab optab)
1945 {
1946   struct expand_operand ops[3];
1947   tree type, lhs, rhs, maskt, ptr;
1948   rtx mem, reg, mask;
1949   unsigned align;
1950
1951   maskt = gimple_call_arg (stmt, 2);
1952   rhs = gimple_call_arg (stmt, 3);
1953   type = TREE_TYPE (rhs);
1954   ptr = build_int_cst (TREE_TYPE (gimple_call_arg (stmt, 1)), 0);
1955   align = tree_to_shwi (gimple_call_arg (stmt, 1));
1956   if (TYPE_ALIGN (type) != align)
1957     type = build_aligned_type (type, align);
1958   lhs = fold_build2 (MEM_REF, type, gimple_call_arg (stmt, 0), ptr);
1959
1960   mem = expand_expr (lhs, NULL_RTX, VOIDmode, EXPAND_WRITE);
1961   gcc_assert (MEM_P (mem));
1962   mask = expand_normal (maskt);
1963   reg = expand_normal (rhs);
1964   create_fixed_operand (&ops[0], mem);
1965   create_input_operand (&ops[1], reg, TYPE_MODE (type));
1966   create_input_operand (&ops[2], mask, TYPE_MODE (TREE_TYPE (maskt)));
1967   expand_insn (convert_optab_handler (optab, TYPE_MODE (type),
1968                                       TYPE_MODE (TREE_TYPE (maskt))),
1969                3, ops);
1970 }
1971
1972 static void
1973 expand_ABNORMAL_DISPATCHER (internal_fn, gcall *)
1974 {
1975 }
1976
1977 static void
1978 expand_BUILTIN_EXPECT (internal_fn, gcall *stmt)
1979 {
1980   /* When guessing was done, the hints should be already stripped away.  */
1981   gcc_assert (!flag_guess_branch_prob || optimize == 0 || seen_error ());
1982
1983   rtx target;
1984   tree lhs = gimple_call_lhs (stmt);
1985   if (lhs)
1986     target = expand_expr (lhs, NULL_RTX, VOIDmode, EXPAND_WRITE);
1987   else
1988     target = const0_rtx;
1989   rtx val = expand_expr (gimple_call_arg (stmt, 0), target, VOIDmode, EXPAND_NORMAL);
1990   if (lhs && val != target)
1991     emit_move_insn (target, val);
1992 }
1993
1994 /* IFN_VA_ARG is supposed to be expanded at pass_stdarg.  So this dummy function
1995    should never be called.  */
1996
1997 static void
1998 expand_VA_ARG (internal_fn, gcall *)
1999 {
2000   gcc_unreachable ();
2001 }
2002
2003 /* Expand the IFN_UNIQUE function according to its first argument.  */
2004
2005 static void
2006 expand_UNIQUE (internal_fn, gcall *stmt)
2007 {
2008   rtx pattern = NULL_RTX;
2009   enum ifn_unique_kind kind
2010     = (enum ifn_unique_kind) TREE_INT_CST_LOW (gimple_call_arg (stmt, 0));
2011
2012   switch (kind)
2013     {
2014     default:
2015       gcc_unreachable ();
2016
2017     case IFN_UNIQUE_UNSPEC:
2018       if (targetm.have_unique ())
2019         pattern = targetm.gen_unique ();
2020       break;
2021
2022     case IFN_UNIQUE_OACC_FORK:
2023     case IFN_UNIQUE_OACC_JOIN:
2024       if (targetm.have_oacc_fork () && targetm.have_oacc_join ())
2025         {
2026           tree lhs = gimple_call_lhs (stmt);
2027           rtx target = const0_rtx;
2028
2029           if (lhs)
2030             target = expand_expr (lhs, NULL_RTX, VOIDmode, EXPAND_WRITE);
2031
2032           rtx data_dep = expand_normal (gimple_call_arg (stmt, 1));
2033           rtx axis = expand_normal (gimple_call_arg (stmt, 2));
2034
2035           if (kind == IFN_UNIQUE_OACC_FORK)
2036             pattern = targetm.gen_oacc_fork (target, data_dep, axis);
2037           else
2038             pattern = targetm.gen_oacc_join (target, data_dep, axis);
2039         }
2040       else
2041         gcc_unreachable ();
2042       break;
2043     }
2044
2045   if (pattern)
2046     emit_insn (pattern);
2047 }
2048
2049 /* The size of an OpenACC compute dimension.  */
2050
2051 static void
2052 expand_GOACC_DIM_SIZE (internal_fn, gcall *stmt)
2053 {
2054   tree lhs = gimple_call_lhs (stmt);
2055
2056   if (!lhs)
2057     return;
2058
2059   rtx target = expand_expr (lhs, NULL_RTX, VOIDmode, EXPAND_WRITE);
2060   if (targetm.have_oacc_dim_size ())
2061     {
2062       rtx dim = expand_expr (gimple_call_arg (stmt, 0), NULL_RTX,
2063                              VOIDmode, EXPAND_NORMAL);
2064       emit_insn (targetm.gen_oacc_dim_size (target, dim));
2065     }
2066   else
2067     emit_move_insn (target, GEN_INT (1));
2068 }
2069
2070 /* The position of an OpenACC execution engine along one compute axis.  */
2071
2072 static void
2073 expand_GOACC_DIM_POS (internal_fn, gcall *stmt)
2074 {
2075   tree lhs = gimple_call_lhs (stmt);
2076
2077   if (!lhs)
2078     return;
2079
2080   rtx target = expand_expr (lhs, NULL_RTX, VOIDmode, EXPAND_WRITE);
2081   if (targetm.have_oacc_dim_pos ())
2082     {
2083       rtx dim = expand_expr (gimple_call_arg (stmt, 0), NULL_RTX,
2084                              VOIDmode, EXPAND_NORMAL);
2085       emit_insn (targetm.gen_oacc_dim_pos (target, dim));
2086     }
2087   else
2088     emit_move_insn (target, const0_rtx);
2089 }
2090
2091 /* This is expanded by oacc_device_lower pass.  */
2092
2093 static void
2094 expand_GOACC_LOOP (internal_fn, gcall *)
2095 {
2096   gcc_unreachable ();
2097 }
2098
2099 /* This is expanded by oacc_device_lower pass.  */
2100
2101 static void
2102 expand_GOACC_REDUCTION (internal_fn, gcall *)
2103 {
2104   gcc_unreachable ();
2105 }
2106
2107 /* Set errno to EDOM.  */
2108
2109 static void
2110 expand_SET_EDOM (internal_fn, gcall *)
2111 {
2112 #ifdef TARGET_EDOM
2113 #ifdef GEN_ERRNO_RTX
2114   rtx errno_rtx = GEN_ERRNO_RTX;
2115 #else
2116   rtx errno_rtx = gen_rtx_MEM (word_mode, gen_rtx_SYMBOL_REF (Pmode, "errno"));
2117 #endif
2118   emit_move_insn (errno_rtx,
2119                   gen_int_mode (TARGET_EDOM, GET_MODE (errno_rtx)));
2120 #else
2121   gcc_unreachable ();
2122 #endif
2123 }
2124
2125 /* Expand a call to FN using the operands in STMT.  FN has a single
2126    output operand and NARGS input operands.  */
2127
2128 static void
2129 expand_direct_optab_fn (internal_fn fn, gcall *stmt, direct_optab optab,
2130                         unsigned int nargs)
2131 {
2132   expand_operand *ops = XALLOCAVEC (expand_operand, nargs + 1);
2133
2134   tree_pair types = direct_internal_fn_types (fn, stmt);
2135   insn_code icode = direct_optab_handler (optab, TYPE_MODE (types.first));
2136
2137   tree lhs = gimple_call_lhs (stmt);
2138   tree lhs_type = TREE_TYPE (lhs);
2139   rtx lhs_rtx = expand_expr (lhs, NULL_RTX, VOIDmode, EXPAND_WRITE);
2140   create_output_operand (&ops[0], lhs_rtx, insn_data[icode].operand[0].mode);
2141
2142   for (unsigned int i = 0; i < nargs; ++i)
2143     {
2144       tree rhs = gimple_call_arg (stmt, i);
2145       tree rhs_type = TREE_TYPE (rhs);
2146       rtx rhs_rtx = expand_normal (rhs);
2147       if (INTEGRAL_TYPE_P (rhs_type))
2148         create_convert_operand_from (&ops[i + 1], rhs_rtx,
2149                                      TYPE_MODE (rhs_type),
2150                                      TYPE_UNSIGNED (rhs_type));
2151       else
2152         create_input_operand (&ops[i + 1], rhs_rtx, TYPE_MODE (rhs_type));
2153     }
2154
2155   expand_insn (icode, nargs + 1, ops);
2156   if (!rtx_equal_p (lhs_rtx, ops[0].value))
2157     {
2158       /* If the return value has an integral type, convert the instruction
2159          result to that type.  This is useful for things that return an
2160          int regardless of the size of the input.  If the instruction result
2161          is smaller than required, assume that it is signed.
2162
2163          If the return value has a nonintegral type, its mode must match
2164          the instruction result.  */
2165       if (GET_CODE (lhs_rtx) == SUBREG && SUBREG_PROMOTED_VAR_P (lhs_rtx))
2166         {
2167           /* If this is a scalar in a register that is stored in a wider
2168              mode than the declared mode, compute the result into its
2169              declared mode and then convert to the wider mode.  */
2170           gcc_checking_assert (INTEGRAL_TYPE_P (lhs_type));
2171           rtx tmp = convert_to_mode (GET_MODE (lhs_rtx), ops[0].value, 0);
2172           convert_move (SUBREG_REG (lhs_rtx), tmp,
2173                         SUBREG_PROMOTED_SIGN (lhs_rtx));
2174         }
2175       else if (GET_MODE (lhs_rtx) == GET_MODE (ops[0].value))
2176         emit_move_insn (lhs_rtx, ops[0].value);
2177       else
2178         {
2179           gcc_checking_assert (INTEGRAL_TYPE_P (lhs_type));
2180           convert_move (lhs_rtx, ops[0].value, 0);
2181         }
2182     }
2183 }
2184
2185 /* Expanders for optabs that can use expand_direct_optab_fn.  */
2186
2187 #define expand_unary_optab_fn(FN, STMT, OPTAB) \
2188   expand_direct_optab_fn (FN, STMT, OPTAB, 1)
2189
2190 #define expand_binary_optab_fn(FN, STMT, OPTAB) \
2191   expand_direct_optab_fn (FN, STMT, OPTAB, 2)
2192
2193 /* RETURN_TYPE and ARGS are a return type and argument list that are
2194    in principle compatible with FN (which satisfies direct_internal_fn_p).
2195    Return the types that should be used to determine whether the
2196    target supports FN.  */
2197
2198 tree_pair
2199 direct_internal_fn_types (internal_fn fn, tree return_type, tree *args)
2200 {
2201   const direct_internal_fn_info &info = direct_internal_fn (fn);
2202   tree type0 = (info.type0 < 0 ? return_type : TREE_TYPE (args[info.type0]));
2203   tree type1 = (info.type1 < 0 ? return_type : TREE_TYPE (args[info.type1]));
2204   return tree_pair (type0, type1);
2205 }
2206
2207 /* CALL is a call whose return type and arguments are in principle
2208    compatible with FN (which satisfies direct_internal_fn_p).  Return the
2209    types that should be used to determine whether the target supports FN.  */
2210
2211 tree_pair
2212 direct_internal_fn_types (internal_fn fn, gcall *call)
2213 {
2214   const direct_internal_fn_info &info = direct_internal_fn (fn);
2215   tree op0 = (info.type0 < 0
2216               ? gimple_call_lhs (call)
2217               : gimple_call_arg (call, info.type0));
2218   tree op1 = (info.type1 < 0
2219               ? gimple_call_lhs (call)
2220               : gimple_call_arg (call, info.type1));
2221   return tree_pair (TREE_TYPE (op0), TREE_TYPE (op1));
2222 }
2223
2224 /* Return true if OPTAB is supported for TYPES (whose modes should be
2225    the same) when the optimization type is OPT_TYPE.  Used for simple
2226    direct optabs.  */
2227
2228 static bool
2229 direct_optab_supported_p (direct_optab optab, tree_pair types,
2230                           optimization_type opt_type)
2231 {
2232   machine_mode mode = TYPE_MODE (types.first);
2233   gcc_checking_assert (mode == TYPE_MODE (types.second));
2234   return direct_optab_handler (optab, mode, opt_type) != CODE_FOR_nothing;
2235 }
2236
2237 /* Return true if load/store lanes optab OPTAB is supported for
2238    array type TYPES.first when the optimization type is OPT_TYPE.  */
2239
2240 static bool
2241 multi_vector_optab_supported_p (convert_optab optab, tree_pair types,
2242                                 optimization_type opt_type)
2243 {
2244   gcc_assert (TREE_CODE (types.first) == ARRAY_TYPE);
2245   machine_mode imode = TYPE_MODE (types.first);
2246   machine_mode vmode = TYPE_MODE (TREE_TYPE (types.first));
2247   return (convert_optab_handler (optab, imode, vmode, opt_type)
2248           != CODE_FOR_nothing);
2249 }
2250
2251 #define direct_unary_optab_supported_p direct_optab_supported_p
2252 #define direct_binary_optab_supported_p direct_optab_supported_p
2253 #define direct_mask_load_optab_supported_p direct_optab_supported_p
2254 #define direct_load_lanes_optab_supported_p multi_vector_optab_supported_p
2255 #define direct_mask_store_optab_supported_p direct_optab_supported_p
2256 #define direct_store_lanes_optab_supported_p multi_vector_optab_supported_p
2257
2258 /* Return true if FN is supported for the types in TYPES when the
2259    optimization type is OPT_TYPE.  The types are those associated with
2260    the "type0" and "type1" fields of FN's direct_internal_fn_info
2261    structure.  */
2262
2263 bool
2264 direct_internal_fn_supported_p (internal_fn fn, tree_pair types,
2265                                 optimization_type opt_type)
2266 {
2267   switch (fn)
2268     {
2269 #define DEF_INTERNAL_FN(CODE, FLAGS, FNSPEC) \
2270     case IFN_##CODE: break;
2271 #define DEF_INTERNAL_OPTAB_FN(CODE, FLAGS, OPTAB, TYPE) \
2272     case IFN_##CODE: \
2273       return direct_##TYPE##_optab_supported_p (OPTAB##_optab, types, \
2274                                                 opt_type);
2275 #include "internal-fn.def"
2276
2277     case IFN_LAST:
2278       break;
2279     }
2280   gcc_unreachable ();
2281 }
2282
2283 /* Return true if FN is supported for type TYPE when the optimization
2284    type is OPT_TYPE.  The caller knows that the "type0" and "type1"
2285    fields of FN's direct_internal_fn_info structure are the same.  */
2286
2287 bool
2288 direct_internal_fn_supported_p (internal_fn fn, tree type,
2289                                 optimization_type opt_type)
2290 {
2291   const direct_internal_fn_info &info = direct_internal_fn (fn);
2292   gcc_checking_assert (info.type0 == info.type1);
2293   return direct_internal_fn_supported_p (fn, tree_pair (type, type), opt_type);
2294 }
2295
2296 /* Return true if IFN_SET_EDOM is supported.  */
2297
2298 bool
2299 set_edom_supported_p (void)
2300 {
2301 #ifdef TARGET_EDOM
2302   return true;
2303 #else
2304   return false;
2305 #endif
2306 }
2307
2308 #define DEF_INTERNAL_OPTAB_FN(CODE, FLAGS, OPTAB, TYPE) \
2309   static void                                           \
2310   expand_##CODE (internal_fn fn, gcall *stmt)           \
2311   {                                                     \
2312     expand_##TYPE##_optab_fn (fn, stmt, OPTAB##_optab); \
2313   }
2314 #include "internal-fn.def"
2315
2316 /* Routines to expand each internal function, indexed by function number.
2317    Each routine has the prototype:
2318
2319        expand_<NAME> (gcall *stmt)
2320
2321    where STMT is the statement that performs the call. */
2322 static void (*const internal_fn_expanders[]) (internal_fn, gcall *) = {
2323 #define DEF_INTERNAL_FN(CODE, FLAGS, FNSPEC) expand_##CODE,
2324 #include "internal-fn.def"
2325   0
2326 };
2327
2328 /* Expand STMT as though it were a call to internal function FN.  */
2329
2330 void
2331 expand_internal_call (internal_fn fn, gcall *stmt)
2332 {
2333   internal_fn_expanders[fn] (fn, stmt);
2334 }
2335
2336 /* Expand STMT, which is a call to internal function FN.  */
2337
2338 void
2339 expand_internal_call (gcall *stmt)
2340 {
2341   expand_internal_call (gimple_call_internal_fn (stmt), stmt);
2342 }