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