dojump.c (do_jump_by_parts_greater_rtx): Invert probability when swapping the arms...
[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     /* Compute the operation.  On RTL level, the addition is always
851        unsigned.  */
852     res = expand_binop (mode, code == PLUS_EXPR ? add_optab : sub_optab,
853                         op0, op1, NULL_RTX, false, OPTAB_LIB_WIDEN);
854
855     /* If we can prove that one of the arguments (for MINUS_EXPR only
856        the second operand, as subtraction is not commutative) is always
857        non-negative or always negative, we can do just one comparison
858        and conditional jump.  */
859     int pos_neg = get_range_pos_neg (arg1);
860     if (code == PLUS_EXPR)
861       {
862         int pos_neg0 = get_range_pos_neg (arg0);
863         if (pos_neg0 != 3 && pos_neg == 3)
864           {
865             std::swap (op0, op1);
866             pos_neg = pos_neg0;
867           }
868       }
869
870     /* Addition overflows if and only if the two operands have the same sign,
871        and the result has the opposite sign.  Subtraction overflows if and
872        only if the two operands have opposite sign, and the subtrahend has
873        the same sign as the result.  Here 0 is counted as positive.  */
874     if (pos_neg == 3)
875       {
876         /* Compute op0 ^ op1 (operands have opposite sign).  */
877         rtx op_xor = expand_binop (mode, xor_optab, op0, op1, NULL_RTX, false,
878                                    OPTAB_LIB_WIDEN);
879
880         /* Compute res ^ op1 (result and 2nd operand have opposite sign).  */
881         rtx res_xor = expand_binop (mode, xor_optab, res, op1, NULL_RTX, false,
882                                     OPTAB_LIB_WIDEN);
883
884         rtx tem;
885         if (code == PLUS_EXPR)
886           {
887             /* Compute (res ^ op1) & ~(op0 ^ op1).  */
888             tem = expand_unop (mode, one_cmpl_optab, op_xor, NULL_RTX, false);
889             tem = expand_binop (mode, and_optab, res_xor, tem, NULL_RTX, false,
890                                 OPTAB_LIB_WIDEN);
891           }
892         else
893           {
894             /* Compute (op0 ^ op1) & ~(res ^ op1).  */
895             tem = expand_unop (mode, one_cmpl_optab, res_xor, NULL_RTX, false);
896             tem = expand_binop (mode, and_optab, op_xor, tem, NULL_RTX, false,
897                                 OPTAB_LIB_WIDEN);
898           }
899
900         /* No overflow if the result has bit sign cleared.  */
901         do_compare_rtx_and_jump (tem, const0_rtx, GE, false, mode, NULL_RTX,
902                                  NULL, done_label, PROB_VERY_LIKELY);
903       }
904
905     /* Compare the result of the operation with the first operand.
906        No overflow for addition if second operand is positive and result
907        is larger or second operand is negative and result is smaller.
908        Likewise for subtraction with sign of second operand flipped.  */
909     else
910       do_compare_rtx_and_jump (res, op0,
911                                (pos_neg == 1) ^ (code == MINUS_EXPR) ? GE : LE,
912                                false, mode, NULL_RTX, NULL, done_label,
913                                PROB_VERY_LIKELY);
914   }
915
916  do_error_label:
917   emit_label (do_error);
918   if (is_ubsan)
919     {
920       /* Expand the ubsan builtin call.  */
921       push_temp_slots ();
922       fn = ubsan_build_overflow_builtin (code, loc, TREE_TYPE (arg0),
923                                          arg0, arg1);
924       expand_normal (fn);
925       pop_temp_slots ();
926       do_pending_stack_adjust ();
927     }
928   else if (lhs)
929     expand_arith_set_overflow (lhs, target);
930
931   /* We're done.  */
932   emit_label (done_label);
933
934   if (lhs)
935     {
936       if (is_ubsan)
937         expand_ubsan_result_store (target, res);
938       else
939         {
940           if (do_xor)
941             res = expand_binop (mode, add_optab, res, sgn, NULL_RTX, false,
942                                 OPTAB_LIB_WIDEN);
943
944           expand_arith_overflow_result_store (lhs, target, mode, res);
945         }
946     }
947 }
948
949 /* Add negate overflow checking to the statement STMT.  */
950
951 static void
952 expand_neg_overflow (location_t loc, tree lhs, tree arg1, bool is_ubsan)
953 {
954   rtx res, op1;
955   tree fn;
956   rtx_code_label *done_label, *do_error;
957   rtx target = NULL_RTX;
958
959   done_label = gen_label_rtx ();
960   do_error = gen_label_rtx ();
961
962   do_pending_stack_adjust ();
963   op1 = expand_normal (arg1);
964
965   machine_mode mode = TYPE_MODE (TREE_TYPE (arg1));
966   if (lhs)
967     {
968       target = expand_expr (lhs, NULL_RTX, VOIDmode, EXPAND_WRITE);
969       if (!is_ubsan)
970         write_complex_part (target, const0_rtx, true);
971     }
972
973   enum insn_code icode = optab_handler (negv3_optab, mode);
974   if (icode != CODE_FOR_nothing)
975     {
976       struct expand_operand ops[3];
977       rtx_insn *last = get_last_insn ();
978
979       res = gen_reg_rtx (mode);
980       create_output_operand (&ops[0], res, mode);
981       create_input_operand (&ops[1], op1, mode);
982       create_fixed_operand (&ops[2], do_error);
983       if (maybe_expand_insn (icode, 3, ops))
984         {
985           last = get_last_insn ();
986           if (profile_status_for_fn (cfun) != PROFILE_ABSENT
987               && JUMP_P (last)
988               && any_condjump_p (last)
989               && !find_reg_note (last, REG_BR_PROB, 0))
990             add_int_reg_note (last, REG_BR_PROB, PROB_VERY_UNLIKELY);
991           emit_jump (done_label);
992         }
993       else
994         {
995           delete_insns_since (last);
996           icode = CODE_FOR_nothing;
997         }
998     }
999
1000   if (icode == CODE_FOR_nothing)
1001     {
1002       /* Compute the operation.  On RTL level, the addition is always
1003          unsigned.  */
1004       res = expand_unop (mode, neg_optab, op1, NULL_RTX, false);
1005
1006       /* Compare the operand with the most negative value.  */
1007       rtx minv = expand_normal (TYPE_MIN_VALUE (TREE_TYPE (arg1)));
1008       do_compare_rtx_and_jump (op1, minv, NE, true, mode, NULL_RTX, NULL,
1009                                done_label, PROB_VERY_LIKELY);
1010     }
1011
1012   emit_label (do_error);
1013   if (is_ubsan)
1014     {
1015       /* Expand the ubsan builtin call.  */
1016       push_temp_slots ();
1017       fn = ubsan_build_overflow_builtin (NEGATE_EXPR, loc, TREE_TYPE (arg1),
1018                                          arg1, NULL_TREE);
1019       expand_normal (fn);
1020       pop_temp_slots ();
1021       do_pending_stack_adjust ();
1022     }
1023   else if (lhs)
1024     expand_arith_set_overflow (lhs, target);
1025
1026   /* We're done.  */
1027   emit_label (done_label);
1028
1029   if (lhs)
1030     {
1031       if (is_ubsan)
1032         expand_ubsan_result_store (target, res);
1033       else
1034         expand_arith_overflow_result_store (lhs, target, mode, res);
1035     }
1036 }
1037
1038 /* Add mul overflow checking to the statement STMT.  */
1039
1040 static void
1041 expand_mul_overflow (location_t loc, tree lhs, tree arg0, tree arg1,
1042                      bool unsr_p, bool uns0_p, bool uns1_p, bool is_ubsan)
1043 {
1044   rtx res, op0, op1;
1045   tree fn, type;
1046   rtx_code_label *done_label, *do_error;
1047   rtx target = NULL_RTX;
1048   signop sign;
1049   enum insn_code icode;
1050
1051   done_label = gen_label_rtx ();
1052   do_error = gen_label_rtx ();
1053
1054   do_pending_stack_adjust ();
1055   op0 = expand_normal (arg0);
1056   op1 = expand_normal (arg1);
1057
1058   machine_mode mode = TYPE_MODE (TREE_TYPE (arg0));
1059   bool uns = unsr_p;
1060   if (lhs)
1061     {
1062       target = expand_expr (lhs, NULL_RTX, VOIDmode, EXPAND_WRITE);
1063       if (!is_ubsan)
1064         write_complex_part (target, const0_rtx, true);
1065     }
1066
1067   if (is_ubsan)
1068     gcc_assert (!unsr_p && !uns0_p && !uns1_p);
1069
1070   /* We assume both operands and result have the same precision
1071      here (GET_MODE_BITSIZE (mode)), S stands for signed type
1072      with that precision, U for unsigned type with that precision,
1073      sgn for unsigned most significant bit in that precision.
1074      s1 is signed first operand, u1 is unsigned first operand,
1075      s2 is signed second operand, u2 is unsigned second operand,
1076      sr is signed result, ur is unsigned result and the following
1077      rules say how to compute result (which is always result of
1078      the operands as if both were unsigned, cast to the right
1079      signedness) and how to compute whether operation overflowed.
1080      main_ovf (false) stands for jump on signed multiplication
1081      overflow or the main algorithm with uns == false.
1082      main_ovf (true) stands for jump on unsigned multiplication
1083      overflow or the main algorithm with uns == true.
1084
1085      s1 * s2 -> sr
1086         res = (S) ((U) s1 * (U) s2)
1087         ovf = main_ovf (false)
1088      u1 * u2 -> ur
1089         res = u1 * u2
1090         ovf = main_ovf (true)
1091      s1 * u2 -> ur
1092         res = (U) s1 * u2
1093         ovf = (s1 < 0 && u2) || main_ovf (true)
1094      u1 * u2 -> sr
1095         res = (S) (u1 * u2)
1096         ovf = res < 0 || main_ovf (true)
1097      s1 * u2 -> sr
1098         res = (S) ((U) s1 * u2)
1099         ovf = (S) u2 >= 0 ? main_ovf (false)
1100                           : (s1 != 0 && (s1 != -1 || u2 != (U) res))
1101      s1 * s2 -> ur
1102         t1 = (s1 & s2) < 0 ? (-(U) s1) : ((U) s1)
1103         t2 = (s1 & s2) < 0 ? (-(U) s2) : ((U) s2)
1104         res = t1 * t2
1105         ovf = (s1 ^ s2) < 0 ? (s1 && s2) : main_ovf (true)  */
1106
1107   if (uns0_p && !uns1_p)
1108     {
1109       /* Multiplication is commutative, if operand signedness differs,
1110          canonicalize to the first operand being signed and second
1111          unsigned to simplify following code.  */
1112       std::swap (op0, op1);
1113       std::swap (arg0, arg1);
1114       uns0_p = false;
1115       uns1_p = true;
1116     }
1117
1118   int pos_neg0 = get_range_pos_neg (arg0);
1119   int pos_neg1 = get_range_pos_neg (arg1);
1120
1121   /* s1 * u2 -> ur  */
1122   if (!uns0_p && uns1_p && unsr_p)
1123     {
1124       switch (pos_neg0)
1125         {
1126         case 1:
1127           /* If s1 is non-negative, just perform normal u1 * u2 -> ur.  */
1128           goto do_main;
1129         case 2:
1130           /* If s1 is negative, avoid the main code, just multiply and
1131              signal overflow if op1 is not 0.  */
1132           struct separate_ops ops;
1133           ops.code = MULT_EXPR;
1134           ops.type = TREE_TYPE (arg1);
1135           ops.op0 = make_tree (ops.type, op0);
1136           ops.op1 = make_tree (ops.type, op1);
1137           ops.op2 = NULL_TREE;
1138           ops.location = loc;
1139           res = expand_expr_real_2 (&ops, NULL_RTX, mode, EXPAND_NORMAL);
1140           do_compare_rtx_and_jump (op1, const0_rtx, EQ, true, mode, NULL_RTX,
1141                                    NULL, done_label, PROB_VERY_LIKELY);
1142           goto do_error_label;
1143         case 3:
1144           rtx_code_label *do_main_label;
1145           do_main_label = gen_label_rtx ();
1146           do_compare_rtx_and_jump (op0, const0_rtx, GE, false, mode, NULL_RTX,
1147                                    NULL, do_main_label, PROB_VERY_LIKELY);
1148           do_compare_rtx_and_jump (op1, const0_rtx, EQ, true, mode, NULL_RTX,
1149                                    NULL, do_main_label, PROB_VERY_LIKELY);
1150           expand_arith_set_overflow (lhs, target);
1151           emit_label (do_main_label);
1152           goto do_main;
1153         default:
1154           gcc_unreachable ();
1155         }
1156     }
1157
1158   /* u1 * u2 -> sr  */
1159   if (uns0_p && uns1_p && !unsr_p)
1160     {
1161       uns = true;
1162       /* Rest of handling of this case after res is computed.  */
1163       goto do_main;
1164     }
1165
1166   /* s1 * u2 -> sr  */
1167   if (!uns0_p && uns1_p && !unsr_p)
1168     {
1169       switch (pos_neg1)
1170         {
1171         case 1:
1172           goto do_main;
1173         case 2:
1174           /* If (S) u2 is negative (i.e. u2 is larger than maximum of S,
1175              avoid the main code, just multiply and signal overflow
1176              unless 0 * u2 or -1 * ((U) Smin).  */
1177           struct separate_ops ops;
1178           ops.code = MULT_EXPR;
1179           ops.type = TREE_TYPE (arg1);
1180           ops.op0 = make_tree (ops.type, op0);
1181           ops.op1 = make_tree (ops.type, op1);
1182           ops.op2 = NULL_TREE;
1183           ops.location = loc;
1184           res = expand_expr_real_2 (&ops, NULL_RTX, mode, EXPAND_NORMAL);
1185           do_compare_rtx_and_jump (op0, const0_rtx, EQ, true, mode, NULL_RTX,
1186                                    NULL, done_label, PROB_VERY_LIKELY);
1187           do_compare_rtx_and_jump (op0, constm1_rtx, NE, true, mode, NULL_RTX,
1188                                    NULL, do_error, PROB_VERY_UNLIKELY);
1189           int prec;
1190           prec = GET_MODE_PRECISION (mode);
1191           rtx sgn;
1192           sgn = immed_wide_int_const (wi::min_value (prec, SIGNED), mode);
1193           do_compare_rtx_and_jump (op1, sgn, EQ, true, mode, NULL_RTX,
1194                                    NULL, done_label, PROB_VERY_LIKELY);
1195           goto do_error_label;
1196         case 3:
1197           /* Rest of handling of this case after res is computed.  */
1198           goto do_main;
1199         default:
1200           gcc_unreachable ();
1201         }
1202     }
1203
1204   /* s1 * s2 -> ur  */
1205   if (!uns0_p && !uns1_p && unsr_p)
1206     {
1207       rtx tem, tem2;
1208       switch (pos_neg0 | pos_neg1)
1209         {
1210         case 1: /* Both operands known to be non-negative.  */
1211           goto do_main;
1212         case 2: /* Both operands known to be negative.  */
1213           op0 = expand_unop (mode, neg_optab, op0, NULL_RTX, false);
1214           op1 = expand_unop (mode, neg_optab, op1, NULL_RTX, false);
1215           /* Avoid looking at arg0/arg1 ranges, as we've changed
1216              the arguments.  */
1217           arg0 = error_mark_node;
1218           arg1 = error_mark_node;
1219           goto do_main;
1220         case 3:
1221           if ((pos_neg0 ^ pos_neg1) == 3)
1222             {
1223               /* If one operand is known to be negative and the other
1224                  non-negative, this overflows always, unless the non-negative
1225                  one is 0.  Just do normal multiply and set overflow
1226                  unless one of the operands is 0.  */
1227               struct separate_ops ops;
1228               ops.code = MULT_EXPR;
1229               ops.type
1230                 = build_nonstandard_integer_type (GET_MODE_PRECISION (mode),
1231                                                   1);
1232               ops.op0 = make_tree (ops.type, op0);
1233               ops.op1 = make_tree (ops.type, op1);
1234               ops.op2 = NULL_TREE;
1235               ops.location = loc;
1236               res = expand_expr_real_2 (&ops, NULL_RTX, mode, EXPAND_NORMAL);
1237               tem = expand_binop (mode, and_optab, op0, op1, NULL_RTX, false,
1238                                   OPTAB_LIB_WIDEN);
1239               do_compare_rtx_and_jump (tem, const0_rtx, EQ, true, mode,
1240                                        NULL_RTX, NULL, done_label,
1241                                        PROB_VERY_LIKELY);
1242               goto do_error_label;
1243             }
1244           /* The general case, do all the needed comparisons at runtime.  */
1245           rtx_code_label *do_main_label, *after_negate_label;
1246           rtx rop0, rop1;
1247           rop0 = gen_reg_rtx (mode);
1248           rop1 = gen_reg_rtx (mode);
1249           emit_move_insn (rop0, op0);
1250           emit_move_insn (rop1, op1);
1251           op0 = rop0;
1252           op1 = rop1;
1253           do_main_label = gen_label_rtx ();
1254           after_negate_label = gen_label_rtx ();
1255           tem = expand_binop (mode, and_optab, op0, op1, NULL_RTX, false,
1256                               OPTAB_LIB_WIDEN);
1257           do_compare_rtx_and_jump (tem, const0_rtx, GE, false, mode, NULL_RTX,
1258                                    NULL, after_negate_label, PROB_VERY_LIKELY);
1259           /* Both arguments negative here, negate them and continue with
1260              normal unsigned overflow checking multiplication.  */
1261           emit_move_insn (op0, expand_unop (mode, neg_optab, op0,
1262                                             NULL_RTX, false));
1263           emit_move_insn (op1, expand_unop (mode, neg_optab, op1,
1264                                             NULL_RTX, false));
1265           /* Avoid looking at arg0/arg1 ranges, as we might have changed
1266              the arguments.  */
1267           arg0 = error_mark_node;
1268           arg1 = error_mark_node;
1269           emit_jump (do_main_label);
1270           emit_label (after_negate_label);
1271           tem2 = expand_binop (mode, xor_optab, op0, op1, NULL_RTX, false,
1272                                OPTAB_LIB_WIDEN);
1273           do_compare_rtx_and_jump (tem2, const0_rtx, GE, false, mode, NULL_RTX,
1274                                    NULL, do_main_label, PROB_VERY_LIKELY);
1275           /* One argument is negative here, the other positive.  This
1276              overflows always, unless one of the arguments is 0.  But
1277              if e.g. s2 is 0, (U) s1 * 0 doesn't overflow, whatever s1
1278              is, thus we can keep do_main code oring in overflow as is.  */
1279           do_compare_rtx_and_jump (tem, const0_rtx, EQ, true, mode, NULL_RTX,
1280                                    NULL, do_main_label, PROB_VERY_LIKELY);
1281           expand_arith_set_overflow (lhs, target);
1282           emit_label (do_main_label);
1283           goto do_main;
1284         default:
1285           gcc_unreachable ();
1286         }
1287     }
1288
1289  do_main:
1290   type = build_nonstandard_integer_type (GET_MODE_PRECISION (mode), uns);
1291   sign = uns ? UNSIGNED : SIGNED;
1292   icode = optab_handler (uns ? umulv4_optab : mulv4_optab, mode);
1293   if (icode != CODE_FOR_nothing)
1294     {
1295       struct expand_operand ops[4];
1296       rtx_insn *last = get_last_insn ();
1297
1298       res = gen_reg_rtx (mode);
1299       create_output_operand (&ops[0], res, mode);
1300       create_input_operand (&ops[1], op0, mode);
1301       create_input_operand (&ops[2], op1, mode);
1302       create_fixed_operand (&ops[3], do_error);
1303       if (maybe_expand_insn (icode, 4, ops))
1304         {
1305           last = get_last_insn ();
1306           if (profile_status_for_fn (cfun) != PROFILE_ABSENT
1307               && JUMP_P (last)
1308               && any_condjump_p (last)
1309               && !find_reg_note (last, REG_BR_PROB, 0))
1310             add_int_reg_note (last, REG_BR_PROB, PROB_VERY_UNLIKELY);
1311           emit_jump (done_label);
1312         }
1313       else
1314         {
1315           delete_insns_since (last);
1316           icode = CODE_FOR_nothing;
1317         }
1318     }
1319
1320   if (icode == CODE_FOR_nothing)
1321     {
1322       struct separate_ops ops;
1323       int prec = GET_MODE_PRECISION (mode);
1324       machine_mode hmode = mode_for_size (prec / 2, MODE_INT, 1);
1325       ops.op0 = make_tree (type, op0);
1326       ops.op1 = make_tree (type, op1);
1327       ops.op2 = NULL_TREE;
1328       ops.location = loc;
1329       if (GET_MODE_2XWIDER_MODE (mode) != VOIDmode
1330           && targetm.scalar_mode_supported_p (GET_MODE_2XWIDER_MODE (mode)))
1331         {
1332           machine_mode wmode = GET_MODE_2XWIDER_MODE (mode);
1333           ops.code = WIDEN_MULT_EXPR;
1334           ops.type
1335             = build_nonstandard_integer_type (GET_MODE_PRECISION (wmode), uns);
1336
1337           res = expand_expr_real_2 (&ops, NULL_RTX, wmode, EXPAND_NORMAL);
1338           rtx hipart = expand_shift (RSHIFT_EXPR, wmode, res, prec,
1339                                      NULL_RTX, uns);
1340           hipart = gen_lowpart (mode, hipart);
1341           res = gen_lowpart (mode, res);
1342           if (uns)
1343             /* For the unsigned multiplication, there was overflow if
1344                HIPART is non-zero.  */
1345             do_compare_rtx_and_jump (hipart, const0_rtx, EQ, true, mode,
1346                                      NULL_RTX, NULL, done_label,
1347                                      PROB_VERY_LIKELY);
1348           else
1349             {
1350               rtx signbit = expand_shift (RSHIFT_EXPR, mode, res, prec - 1,
1351                                           NULL_RTX, 0);
1352               /* RES is low half of the double width result, HIPART
1353                  the high half.  There was overflow if
1354                  HIPART is different from RES < 0 ? -1 : 0.  */
1355               do_compare_rtx_and_jump (signbit, hipart, EQ, true, mode,
1356                                        NULL_RTX, NULL, done_label,
1357                                        PROB_VERY_LIKELY);
1358             }
1359         }
1360       else if (hmode != BLKmode && 2 * GET_MODE_PRECISION (hmode) == prec)
1361         {
1362           rtx_code_label *large_op0 = gen_label_rtx ();
1363           rtx_code_label *small_op0_large_op1 = gen_label_rtx ();
1364           rtx_code_label *one_small_one_large = gen_label_rtx ();
1365           rtx_code_label *both_ops_large = gen_label_rtx ();
1366           rtx_code_label *after_hipart_neg = uns ? NULL : gen_label_rtx ();
1367           rtx_code_label *after_lopart_neg = uns ? NULL : gen_label_rtx ();
1368           rtx_code_label *do_overflow = gen_label_rtx ();
1369           rtx_code_label *hipart_different = uns ? NULL : gen_label_rtx ();
1370
1371           unsigned int hprec = GET_MODE_PRECISION (hmode);
1372           rtx hipart0 = expand_shift (RSHIFT_EXPR, mode, op0, hprec,
1373                                       NULL_RTX, uns);
1374           hipart0 = gen_lowpart (hmode, hipart0);
1375           rtx lopart0 = gen_lowpart (hmode, op0);
1376           rtx signbit0 = const0_rtx;
1377           if (!uns)
1378             signbit0 = expand_shift (RSHIFT_EXPR, hmode, lopart0, hprec - 1,
1379                                      NULL_RTX, 0);
1380           rtx hipart1 = expand_shift (RSHIFT_EXPR, mode, op1, hprec,
1381                                       NULL_RTX, uns);
1382           hipart1 = gen_lowpart (hmode, hipart1);
1383           rtx lopart1 = gen_lowpart (hmode, op1);
1384           rtx signbit1 = const0_rtx;
1385           if (!uns)
1386             signbit1 = expand_shift (RSHIFT_EXPR, hmode, lopart1, hprec - 1,
1387                                      NULL_RTX, 0);
1388
1389           res = gen_reg_rtx (mode);
1390
1391           /* True if op0 resp. op1 are known to be in the range of
1392              halfstype.  */
1393           bool op0_small_p = false;
1394           bool op1_small_p = false;
1395           /* True if op0 resp. op1 are known to have all zeros or all ones
1396              in the upper half of bits, but are not known to be
1397              op{0,1}_small_p.  */
1398           bool op0_medium_p = false;
1399           bool op1_medium_p = false;
1400           /* -1 if op{0,1} is known to be negative, 0 if it is known to be
1401              nonnegative, 1 if unknown.  */
1402           int op0_sign = 1;
1403           int op1_sign = 1;
1404
1405           if (pos_neg0 == 1)
1406             op0_sign = 0;
1407           else if (pos_neg0 == 2)
1408             op0_sign = -1;
1409           if (pos_neg1 == 1)
1410             op1_sign = 0;
1411           else if (pos_neg1 == 2)
1412             op1_sign = -1;
1413
1414           unsigned int mprec0 = prec;
1415           if (arg0 != error_mark_node)
1416             mprec0 = get_min_precision (arg0, sign);
1417           if (mprec0 <= hprec)
1418             op0_small_p = true;
1419           else if (!uns && mprec0 <= hprec + 1)
1420             op0_medium_p = true;
1421           unsigned int mprec1 = prec;
1422           if (arg1 != error_mark_node)
1423             mprec1 = get_min_precision (arg1, sign);
1424           if (mprec1 <= hprec)
1425             op1_small_p = true;
1426           else if (!uns && mprec1 <= hprec + 1)
1427             op1_medium_p = true;
1428
1429           int smaller_sign = 1;
1430           int larger_sign = 1;
1431           if (op0_small_p)
1432             {
1433               smaller_sign = op0_sign;
1434               larger_sign = op1_sign;
1435             }
1436           else if (op1_small_p)
1437             {
1438               smaller_sign = op1_sign;
1439               larger_sign = op0_sign;
1440             }
1441           else if (op0_sign == op1_sign)
1442             {
1443               smaller_sign = op0_sign;
1444               larger_sign = op0_sign;
1445             }
1446
1447           if (!op0_small_p)
1448             do_compare_rtx_and_jump (signbit0, hipart0, NE, true, hmode,
1449                                      NULL_RTX, NULL, large_op0,
1450                                      PROB_UNLIKELY);
1451
1452           if (!op1_small_p)
1453             do_compare_rtx_and_jump (signbit1, hipart1, NE, true, hmode,
1454                                      NULL_RTX, NULL, small_op0_large_op1,
1455                                      PROB_UNLIKELY);
1456
1457           /* If both op0 and op1 are sign (!uns) or zero (uns) extended from
1458              hmode to mode, the multiplication will never overflow.  We can
1459              do just one hmode x hmode => mode widening multiplication.  */
1460           rtx lopart0s = lopart0, lopart1s = lopart1;
1461           if (GET_CODE (lopart0) == SUBREG)
1462             {
1463               lopart0s = shallow_copy_rtx (lopart0);
1464               SUBREG_PROMOTED_VAR_P (lopart0s) = 1;
1465               SUBREG_PROMOTED_SET (lopart0s, uns ? SRP_UNSIGNED : SRP_SIGNED);
1466             }
1467           if (GET_CODE (lopart1) == SUBREG)
1468             {
1469               lopart1s = shallow_copy_rtx (lopart1);
1470               SUBREG_PROMOTED_VAR_P (lopart1s) = 1;
1471               SUBREG_PROMOTED_SET (lopart1s, uns ? SRP_UNSIGNED : SRP_SIGNED);
1472             }
1473           tree halfstype = build_nonstandard_integer_type (hprec, uns);
1474           ops.op0 = make_tree (halfstype, lopart0s);
1475           ops.op1 = make_tree (halfstype, lopart1s);
1476           ops.code = WIDEN_MULT_EXPR;
1477           ops.type = type;
1478           rtx thisres
1479             = expand_expr_real_2 (&ops, NULL_RTX, mode, EXPAND_NORMAL);
1480           emit_move_insn (res, thisres);
1481           emit_jump (done_label);
1482
1483           emit_label (small_op0_large_op1);
1484
1485           /* If op0 is sign (!uns) or zero (uns) extended from hmode to mode,
1486              but op1 is not, just swap the arguments and handle it as op1
1487              sign/zero extended, op0 not.  */
1488           rtx larger = gen_reg_rtx (mode);
1489           rtx hipart = gen_reg_rtx (hmode);
1490           rtx lopart = gen_reg_rtx (hmode);
1491           emit_move_insn (larger, op1);
1492           emit_move_insn (hipart, hipart1);
1493           emit_move_insn (lopart, lopart0);
1494           emit_jump (one_small_one_large);
1495
1496           emit_label (large_op0);
1497
1498           if (!op1_small_p)
1499             do_compare_rtx_and_jump (signbit1, hipart1, NE, true, hmode,
1500                                      NULL_RTX, NULL, both_ops_large,
1501                                      PROB_UNLIKELY);
1502
1503           /* If op1 is sign (!uns) or zero (uns) extended from hmode to mode,
1504              but op0 is not, prepare larger, hipart and lopart pseudos and
1505              handle it together with small_op0_large_op1.  */
1506           emit_move_insn (larger, op0);
1507           emit_move_insn (hipart, hipart0);
1508           emit_move_insn (lopart, lopart1);
1509
1510           emit_label (one_small_one_large);
1511
1512           /* lopart is the low part of the operand that is sign extended
1513              to mode, larger is the other operand, hipart is the
1514              high part of larger and lopart0 and lopart1 are the low parts
1515              of both operands.
1516              We perform lopart0 * lopart1 and lopart * hipart widening
1517              multiplications.  */
1518           tree halfutype = build_nonstandard_integer_type (hprec, 1);
1519           ops.op0 = make_tree (halfutype, lopart0);
1520           ops.op1 = make_tree (halfutype, lopart1);
1521           rtx lo0xlo1
1522             = expand_expr_real_2 (&ops, NULL_RTX, mode, EXPAND_NORMAL);
1523
1524           ops.op0 = make_tree (halfutype, lopart);
1525           ops.op1 = make_tree (halfutype, hipart);
1526           rtx loxhi = gen_reg_rtx (mode);
1527           rtx tem = expand_expr_real_2 (&ops, NULL_RTX, mode, EXPAND_NORMAL);
1528           emit_move_insn (loxhi, tem);
1529
1530           if (!uns)
1531             {
1532               /* if (hipart < 0) loxhi -= lopart << (bitsize / 2);  */
1533               if (larger_sign == 0)
1534                 emit_jump (after_hipart_neg);
1535               else if (larger_sign != -1)
1536                 do_compare_rtx_and_jump (hipart, const0_rtx, GE, false, hmode,
1537                                          NULL_RTX, NULL, after_hipart_neg,
1538                                          PROB_EVEN);
1539
1540               tem = convert_modes (mode, hmode, lopart, 1);
1541               tem = expand_shift (LSHIFT_EXPR, mode, tem, hprec, NULL_RTX, 1);
1542               tem = expand_simple_binop (mode, MINUS, loxhi, tem, NULL_RTX,
1543                                          1, OPTAB_DIRECT);
1544               emit_move_insn (loxhi, tem);
1545
1546               emit_label (after_hipart_neg);
1547
1548               /* if (lopart < 0) loxhi -= larger;  */
1549               if (smaller_sign == 0)
1550                 emit_jump (after_lopart_neg);
1551               else if (smaller_sign != -1)
1552                 do_compare_rtx_and_jump (lopart, const0_rtx, GE, false, hmode,
1553                                          NULL_RTX, NULL, after_lopart_neg,
1554                                          PROB_EVEN);
1555
1556               tem = expand_simple_binop (mode, MINUS, loxhi, larger, NULL_RTX,
1557                                          1, OPTAB_DIRECT);
1558               emit_move_insn (loxhi, tem);
1559
1560               emit_label (after_lopart_neg);
1561             }
1562
1563           /* loxhi += (uns) lo0xlo1 >> (bitsize / 2);  */
1564           tem = expand_shift (RSHIFT_EXPR, mode, lo0xlo1, hprec, NULL_RTX, 1);
1565           tem = expand_simple_binop (mode, PLUS, loxhi, tem, NULL_RTX,
1566                                      1, OPTAB_DIRECT);
1567           emit_move_insn (loxhi, tem);
1568
1569           /* if (loxhi >> (bitsize / 2)
1570                  == (hmode) loxhi >> (bitsize / 2 - 1))  (if !uns)
1571              if (loxhi >> (bitsize / 2) == 0             (if uns).  */
1572           rtx hipartloxhi = expand_shift (RSHIFT_EXPR, mode, loxhi, hprec,
1573                                           NULL_RTX, 0);
1574           hipartloxhi = gen_lowpart (hmode, hipartloxhi);
1575           rtx signbitloxhi = const0_rtx;
1576           if (!uns)
1577             signbitloxhi = expand_shift (RSHIFT_EXPR, hmode,
1578                                          gen_lowpart (hmode, loxhi),
1579                                          hprec - 1, NULL_RTX, 0);
1580
1581           do_compare_rtx_and_jump (signbitloxhi, hipartloxhi, NE, true, hmode,
1582                                    NULL_RTX, NULL, do_overflow,
1583                                    PROB_VERY_UNLIKELY);
1584
1585           /* res = (loxhi << (bitsize / 2)) | (hmode) lo0xlo1;  */
1586           rtx loxhishifted = expand_shift (LSHIFT_EXPR, mode, loxhi, hprec,
1587                                            NULL_RTX, 1);
1588           tem = convert_modes (mode, hmode, gen_lowpart (hmode, lo0xlo1), 1);
1589
1590           tem = expand_simple_binop (mode, IOR, loxhishifted, tem, res,
1591                                      1, OPTAB_DIRECT);
1592           if (tem != res)
1593             emit_move_insn (res, tem);
1594           emit_jump (done_label);
1595
1596           emit_label (both_ops_large);
1597
1598           /* If both operands are large (not sign (!uns) or zero (uns)
1599              extended from hmode), then perform the full multiplication
1600              which will be the result of the operation.
1601              The only cases which don't overflow are for signed multiplication
1602              some cases where both hipart0 and highpart1 are 0 or -1.
1603              For unsigned multiplication when high parts are both non-zero
1604              this overflows always.  */
1605           ops.code = MULT_EXPR;
1606           ops.op0 = make_tree (type, op0);
1607           ops.op1 = make_tree (type, op1);
1608           tem = expand_expr_real_2 (&ops, NULL_RTX, mode, EXPAND_NORMAL);
1609           emit_move_insn (res, tem);
1610
1611           if (!uns)
1612             {
1613               if (!op0_medium_p)
1614                 {
1615                   tem = expand_simple_binop (hmode, PLUS, hipart0, const1_rtx,
1616                                              NULL_RTX, 1, OPTAB_DIRECT);
1617                   do_compare_rtx_and_jump (tem, const1_rtx, GTU, true, hmode,
1618                                            NULL_RTX, NULL, do_error,
1619                                            PROB_VERY_UNLIKELY);
1620                 }
1621
1622               if (!op1_medium_p)
1623                 {
1624                   tem = expand_simple_binop (hmode, PLUS, hipart1, const1_rtx,
1625                                              NULL_RTX, 1, OPTAB_DIRECT);
1626                   do_compare_rtx_and_jump (tem, const1_rtx, GTU, true, hmode,
1627                                            NULL_RTX, NULL, do_error,
1628                                            PROB_VERY_UNLIKELY);
1629                 }
1630
1631               /* At this point hipart{0,1} are both in [-1, 0].  If they are
1632                  the same, overflow happened if res is negative, if they are
1633                  different, overflow happened if res is positive.  */
1634               if (op0_sign != 1 && op1_sign != 1 && op0_sign != op1_sign)
1635                 emit_jump (hipart_different);
1636               else if (op0_sign == 1 || op1_sign == 1)
1637                 do_compare_rtx_and_jump (hipart0, hipart1, NE, true, hmode,
1638                                          NULL_RTX, NULL, hipart_different,
1639                                          PROB_EVEN);
1640
1641               do_compare_rtx_and_jump (res, const0_rtx, LT, false, mode,
1642                                        NULL_RTX, NULL, do_error,
1643                                        PROB_VERY_UNLIKELY);
1644               emit_jump (done_label);
1645
1646               emit_label (hipart_different);
1647
1648               do_compare_rtx_and_jump (res, const0_rtx, GE, false, mode,
1649                                        NULL_RTX, NULL, do_error,
1650                                        PROB_VERY_UNLIKELY);
1651               emit_jump (done_label);
1652             }
1653
1654           emit_label (do_overflow);
1655
1656           /* Overflow, do full multiplication and fallthru into do_error.  */
1657           ops.op0 = make_tree (type, op0);
1658           ops.op1 = make_tree (type, op1);
1659           tem = expand_expr_real_2 (&ops, NULL_RTX, mode, EXPAND_NORMAL);
1660           emit_move_insn (res, tem);
1661         }
1662       else
1663         {
1664           gcc_assert (!is_ubsan);
1665           ops.code = MULT_EXPR;
1666           ops.type = type;
1667           res = expand_expr_real_2 (&ops, NULL_RTX, mode, EXPAND_NORMAL);
1668           emit_jump (done_label);
1669         }
1670     }
1671
1672  do_error_label:
1673   emit_label (do_error);
1674   if (is_ubsan)
1675     {
1676       /* Expand the ubsan builtin call.  */
1677       push_temp_slots ();
1678       fn = ubsan_build_overflow_builtin (MULT_EXPR, loc, TREE_TYPE (arg0),
1679                                          arg0, arg1);
1680       expand_normal (fn);
1681       pop_temp_slots ();
1682       do_pending_stack_adjust ();
1683     }
1684   else if (lhs)
1685     expand_arith_set_overflow (lhs, target);
1686
1687   /* We're done.  */
1688   emit_label (done_label);
1689
1690   /* u1 * u2 -> sr  */
1691   if (uns0_p && uns1_p && !unsr_p)
1692     {
1693       rtx_code_label *all_done_label = gen_label_rtx ();
1694       do_compare_rtx_and_jump (res, const0_rtx, GE, false, mode, NULL_RTX,
1695                                NULL, all_done_label, PROB_VERY_LIKELY);
1696       expand_arith_set_overflow (lhs, target);
1697       emit_label (all_done_label);
1698     }
1699
1700   /* s1 * u2 -> sr  */
1701   if (!uns0_p && uns1_p && !unsr_p && pos_neg1 == 3)
1702     {
1703       rtx_code_label *all_done_label = gen_label_rtx ();
1704       rtx_code_label *set_noovf = gen_label_rtx ();
1705       do_compare_rtx_and_jump (op1, const0_rtx, GE, false, mode, NULL_RTX,
1706                                NULL, all_done_label, PROB_VERY_LIKELY);
1707       expand_arith_set_overflow (lhs, target);
1708       do_compare_rtx_and_jump (op0, const0_rtx, EQ, true, mode, NULL_RTX,
1709                                NULL, set_noovf, PROB_VERY_LIKELY);
1710       do_compare_rtx_and_jump (op0, constm1_rtx, NE, true, mode, NULL_RTX,
1711                                NULL, all_done_label, PROB_VERY_UNLIKELY);
1712       do_compare_rtx_and_jump (op1, res, NE, true, mode, NULL_RTX, NULL,
1713                                all_done_label, PROB_VERY_UNLIKELY);
1714       emit_label (set_noovf);
1715       write_complex_part (target, const0_rtx, true);
1716       emit_label (all_done_label);
1717     }
1718
1719   if (lhs)
1720     {
1721       if (is_ubsan)
1722         expand_ubsan_result_store (target, res);
1723       else
1724         expand_arith_overflow_result_store (lhs, target, mode, res);
1725     }
1726 }
1727
1728 /* Expand UBSAN_CHECK_ADD call STMT.  */
1729
1730 static void
1731 expand_UBSAN_CHECK_ADD (internal_fn, gcall *stmt)
1732 {
1733   location_t loc = gimple_location (stmt);
1734   tree lhs = gimple_call_lhs (stmt);
1735   tree arg0 = gimple_call_arg (stmt, 0);
1736   tree arg1 = gimple_call_arg (stmt, 1);
1737   expand_addsub_overflow (loc, PLUS_EXPR, lhs, arg0, arg1,
1738                           false, false, false, true);
1739 }
1740
1741 /* Expand UBSAN_CHECK_SUB call STMT.  */
1742
1743 static void
1744 expand_UBSAN_CHECK_SUB (internal_fn, gcall *stmt)
1745 {
1746   location_t loc = gimple_location (stmt);
1747   tree lhs = gimple_call_lhs (stmt);
1748   tree arg0 = gimple_call_arg (stmt, 0);
1749   tree arg1 = gimple_call_arg (stmt, 1);
1750   if (integer_zerop (arg0))
1751     expand_neg_overflow (loc, lhs, arg1, true);
1752   else
1753     expand_addsub_overflow (loc, MINUS_EXPR, lhs, arg0, arg1,
1754                             false, false, false, true);
1755 }
1756
1757 /* Expand UBSAN_CHECK_MUL call STMT.  */
1758
1759 static void
1760 expand_UBSAN_CHECK_MUL (internal_fn, gcall *stmt)
1761 {
1762   location_t loc = gimple_location (stmt);
1763   tree lhs = gimple_call_lhs (stmt);
1764   tree arg0 = gimple_call_arg (stmt, 0);
1765   tree arg1 = gimple_call_arg (stmt, 1);
1766   expand_mul_overflow (loc, lhs, arg0, arg1, false, false, false, true);
1767 }
1768
1769 /* Helper function for {ADD,SUB,MUL}_OVERFLOW call stmt expansion.  */
1770
1771 static void
1772 expand_arith_overflow (enum tree_code code, gimple *stmt)
1773 {
1774   tree lhs = gimple_call_lhs (stmt);
1775   if (lhs == NULL_TREE)
1776     return;
1777   tree arg0 = gimple_call_arg (stmt, 0);
1778   tree arg1 = gimple_call_arg (stmt, 1);
1779   tree type = TREE_TYPE (TREE_TYPE (lhs));
1780   int uns0_p = TYPE_UNSIGNED (TREE_TYPE (arg0));
1781   int uns1_p = TYPE_UNSIGNED (TREE_TYPE (arg1));
1782   int unsr_p = TYPE_UNSIGNED (type);
1783   int prec0 = TYPE_PRECISION (TREE_TYPE (arg0));
1784   int prec1 = TYPE_PRECISION (TREE_TYPE (arg1));
1785   int precres = TYPE_PRECISION (type);
1786   location_t loc = gimple_location (stmt);
1787   if (!uns0_p && get_range_pos_neg (arg0) == 1)
1788     uns0_p = true;
1789   if (!uns1_p && get_range_pos_neg (arg1) == 1)
1790     uns1_p = true;
1791   int pr = get_min_precision (arg0, uns0_p ? UNSIGNED : SIGNED);
1792   prec0 = MIN (prec0, pr);
1793   pr = get_min_precision (arg1, uns1_p ? UNSIGNED : SIGNED);
1794   prec1 = MIN (prec1, pr);
1795
1796   /* If uns0_p && uns1_p, precop is minimum needed precision
1797      of unsigned type to hold the exact result, otherwise
1798      precop is minimum needed precision of signed type to
1799      hold the exact result.  */
1800   int precop;
1801   if (code == MULT_EXPR)
1802     precop = prec0 + prec1 + (uns0_p != uns1_p);
1803   else
1804     {
1805       if (uns0_p == uns1_p)
1806         precop = MAX (prec0, prec1) + 1;
1807       else if (uns0_p)
1808         precop = MAX (prec0 + 1, prec1) + 1;
1809       else
1810         precop = MAX (prec0, prec1 + 1) + 1;
1811     }
1812   int orig_precres = precres;
1813
1814   do
1815     {
1816       if ((uns0_p && uns1_p)
1817           ? ((precop + !unsr_p) <= precres
1818              /* u1 - u2 -> ur can overflow, no matter what precision
1819                 the result has.  */
1820              && (code != MINUS_EXPR || !unsr_p))
1821           : (!unsr_p && precop <= precres))
1822         {
1823           /* The infinity precision result will always fit into result.  */
1824           rtx target = expand_expr (lhs, NULL_RTX, VOIDmode, EXPAND_WRITE);
1825           write_complex_part (target, const0_rtx, true);
1826           enum machine_mode mode = TYPE_MODE (type);
1827           struct separate_ops ops;
1828           ops.code = code;
1829           ops.type = type;
1830           ops.op0 = fold_convert_loc (loc, type, arg0);
1831           ops.op1 = fold_convert_loc (loc, type, arg1);
1832           ops.op2 = NULL_TREE;
1833           ops.location = loc;
1834           rtx tem = expand_expr_real_2 (&ops, NULL_RTX, mode, EXPAND_NORMAL);
1835           expand_arith_overflow_result_store (lhs, target, mode, tem);
1836           return;
1837         }
1838
1839       /* For sub-word operations, if target doesn't have them, start
1840          with precres widening right away, otherwise do it only
1841          if the most simple cases can't be used.  */
1842       if (WORD_REGISTER_OPERATIONS
1843           && orig_precres == precres
1844           && precres < BITS_PER_WORD)
1845         ;
1846       else if ((uns0_p && uns1_p && unsr_p && prec0 <= precres
1847                 && prec1 <= precres)
1848           || ((!uns0_p || !uns1_p) && !unsr_p
1849               && prec0 + uns0_p <= precres
1850               && prec1 + uns1_p <= precres))
1851         {
1852           arg0 = fold_convert_loc (loc, type, arg0);
1853           arg1 = fold_convert_loc (loc, type, arg1);
1854           switch (code)
1855             {
1856             case MINUS_EXPR:
1857               if (integer_zerop (arg0) && !unsr_p)
1858                 {
1859                   expand_neg_overflow (loc, lhs, arg1, false);
1860                   return;
1861                 }
1862               /* FALLTHRU */
1863             case PLUS_EXPR:
1864               expand_addsub_overflow (loc, code, lhs, arg0, arg1,
1865                                       unsr_p, unsr_p, unsr_p, false);
1866               return;
1867             case MULT_EXPR:
1868               expand_mul_overflow (loc, lhs, arg0, arg1,
1869                                    unsr_p, unsr_p, unsr_p, false);
1870               return;
1871             default:
1872               gcc_unreachable ();
1873             }
1874         }
1875
1876       /* For sub-word operations, retry with a wider type first.  */
1877       if (orig_precres == precres && precop <= BITS_PER_WORD)
1878         {
1879           int p = WORD_REGISTER_OPERATIONS ? BITS_PER_WORD : precop;
1880           enum machine_mode m = smallest_mode_for_size (p, MODE_INT);
1881           tree optype = build_nonstandard_integer_type (GET_MODE_PRECISION (m),
1882                                                         uns0_p && uns1_p
1883                                                         && unsr_p);
1884           p = TYPE_PRECISION (optype);
1885           if (p > precres)
1886             {
1887               precres = p;
1888               unsr_p = TYPE_UNSIGNED (optype);
1889               type = optype;
1890               continue;
1891             }
1892         }
1893
1894       if (prec0 <= precres && prec1 <= precres)
1895         {
1896           tree types[2];
1897           if (unsr_p)
1898             {
1899               types[0] = build_nonstandard_integer_type (precres, 0);
1900               types[1] = type;
1901             }
1902           else
1903             {
1904               types[0] = type;
1905               types[1] = build_nonstandard_integer_type (precres, 1);
1906             }
1907           arg0 = fold_convert_loc (loc, types[uns0_p], arg0);
1908           arg1 = fold_convert_loc (loc, types[uns1_p], arg1);
1909           if (code != MULT_EXPR)
1910             expand_addsub_overflow (loc, code, lhs, arg0, arg1, unsr_p,
1911                                     uns0_p, uns1_p, false);
1912           else
1913             expand_mul_overflow (loc, lhs, arg0, arg1, unsr_p,
1914                                  uns0_p, uns1_p, false);
1915           return;
1916         }
1917
1918       /* Retry with a wider type.  */
1919       if (orig_precres == precres)
1920         {
1921           int p = MAX (prec0, prec1);
1922           enum machine_mode m = smallest_mode_for_size (p, MODE_INT);
1923           tree optype = build_nonstandard_integer_type (GET_MODE_PRECISION (m),
1924                                                         uns0_p && uns1_p
1925                                                         && unsr_p);
1926           p = TYPE_PRECISION (optype);
1927           if (p > precres)
1928             {
1929               precres = p;
1930               unsr_p = TYPE_UNSIGNED (optype);
1931               type = optype;
1932               continue;
1933             }
1934         }
1935
1936       gcc_unreachable ();
1937     }
1938   while (1);
1939 }
1940
1941 /* Expand ADD_OVERFLOW STMT.  */
1942
1943 static void
1944 expand_ADD_OVERFLOW (internal_fn, gcall *stmt)
1945 {
1946   expand_arith_overflow (PLUS_EXPR, stmt);
1947 }
1948
1949 /* Expand SUB_OVERFLOW STMT.  */
1950
1951 static void
1952 expand_SUB_OVERFLOW (internal_fn, gcall *stmt)
1953 {
1954   expand_arith_overflow (MINUS_EXPR, stmt);
1955 }
1956
1957 /* Expand MUL_OVERFLOW STMT.  */
1958
1959 static void
1960 expand_MUL_OVERFLOW (internal_fn, gcall *stmt)
1961 {
1962   expand_arith_overflow (MULT_EXPR, stmt);
1963 }
1964
1965 /* This should get folded in tree-vectorizer.c.  */
1966
1967 static void
1968 expand_LOOP_VECTORIZED (internal_fn, gcall *)
1969 {
1970   gcc_unreachable ();
1971 }
1972
1973 /* Expand MASK_LOAD call STMT using optab OPTAB.  */
1974
1975 static void
1976 expand_mask_load_optab_fn (internal_fn, gcall *stmt, convert_optab optab)
1977 {
1978   struct expand_operand ops[3];
1979   tree type, lhs, rhs, maskt, ptr;
1980   rtx mem, target, mask;
1981   unsigned align;
1982
1983   maskt = gimple_call_arg (stmt, 2);
1984   lhs = gimple_call_lhs (stmt);
1985   if (lhs == NULL_TREE)
1986     return;
1987   type = TREE_TYPE (lhs);
1988   ptr = build_int_cst (TREE_TYPE (gimple_call_arg (stmt, 1)), 0);
1989   align = tree_to_shwi (gimple_call_arg (stmt, 1));
1990   if (TYPE_ALIGN (type) != align)
1991     type = build_aligned_type (type, align);
1992   rhs = fold_build2 (MEM_REF, type, gimple_call_arg (stmt, 0), ptr);
1993
1994   mem = expand_expr (rhs, NULL_RTX, VOIDmode, EXPAND_WRITE);
1995   gcc_assert (MEM_P (mem));
1996   mask = expand_normal (maskt);
1997   target = expand_expr (lhs, NULL_RTX, VOIDmode, EXPAND_WRITE);
1998   create_output_operand (&ops[0], target, TYPE_MODE (type));
1999   create_fixed_operand (&ops[1], mem);
2000   create_input_operand (&ops[2], mask, TYPE_MODE (TREE_TYPE (maskt)));
2001   expand_insn (convert_optab_handler (optab, TYPE_MODE (type),
2002                                       TYPE_MODE (TREE_TYPE (maskt))),
2003                3, ops);
2004 }
2005
2006 /* Expand MASK_STORE call STMT using optab OPTAB.  */
2007
2008 static void
2009 expand_mask_store_optab_fn (internal_fn, gcall *stmt, convert_optab optab)
2010 {
2011   struct expand_operand ops[3];
2012   tree type, lhs, rhs, maskt, ptr;
2013   rtx mem, reg, mask;
2014   unsigned align;
2015
2016   maskt = gimple_call_arg (stmt, 2);
2017   rhs = gimple_call_arg (stmt, 3);
2018   type = TREE_TYPE (rhs);
2019   ptr = build_int_cst (TREE_TYPE (gimple_call_arg (stmt, 1)), 0);
2020   align = tree_to_shwi (gimple_call_arg (stmt, 1));
2021   if (TYPE_ALIGN (type) != align)
2022     type = build_aligned_type (type, align);
2023   lhs = fold_build2 (MEM_REF, type, gimple_call_arg (stmt, 0), ptr);
2024
2025   mem = expand_expr (lhs, NULL_RTX, VOIDmode, EXPAND_WRITE);
2026   gcc_assert (MEM_P (mem));
2027   mask = expand_normal (maskt);
2028   reg = expand_normal (rhs);
2029   create_fixed_operand (&ops[0], mem);
2030   create_input_operand (&ops[1], reg, TYPE_MODE (type));
2031   create_input_operand (&ops[2], mask, TYPE_MODE (TREE_TYPE (maskt)));
2032   expand_insn (convert_optab_handler (optab, TYPE_MODE (type),
2033                                       TYPE_MODE (TREE_TYPE (maskt))),
2034                3, ops);
2035 }
2036
2037 static void
2038 expand_ABNORMAL_DISPATCHER (internal_fn, gcall *)
2039 {
2040 }
2041
2042 static void
2043 expand_BUILTIN_EXPECT (internal_fn, gcall *stmt)
2044 {
2045   /* When guessing was done, the hints should be already stripped away.  */
2046   gcc_assert (!flag_guess_branch_prob || optimize == 0 || seen_error ());
2047
2048   rtx target;
2049   tree lhs = gimple_call_lhs (stmt);
2050   if (lhs)
2051     target = expand_expr (lhs, NULL_RTX, VOIDmode, EXPAND_WRITE);
2052   else
2053     target = const0_rtx;
2054   rtx val = expand_expr (gimple_call_arg (stmt, 0), target, VOIDmode, EXPAND_NORMAL);
2055   if (lhs && val != target)
2056     emit_move_insn (target, val);
2057 }
2058
2059 /* IFN_VA_ARG is supposed to be expanded at pass_stdarg.  So this dummy function
2060    should never be called.  */
2061
2062 static void
2063 expand_VA_ARG (internal_fn, gcall *)
2064 {
2065   gcc_unreachable ();
2066 }
2067
2068 /* Expand the IFN_UNIQUE function according to its first argument.  */
2069
2070 static void
2071 expand_UNIQUE (internal_fn, gcall *stmt)
2072 {
2073   rtx pattern = NULL_RTX;
2074   enum ifn_unique_kind kind
2075     = (enum ifn_unique_kind) TREE_INT_CST_LOW (gimple_call_arg (stmt, 0));
2076
2077   switch (kind)
2078     {
2079     default:
2080       gcc_unreachable ();
2081
2082     case IFN_UNIQUE_UNSPEC:
2083       if (targetm.have_unique ())
2084         pattern = targetm.gen_unique ();
2085       break;
2086
2087     case IFN_UNIQUE_OACC_FORK:
2088     case IFN_UNIQUE_OACC_JOIN:
2089       if (targetm.have_oacc_fork () && targetm.have_oacc_join ())
2090         {
2091           tree lhs = gimple_call_lhs (stmt);
2092           rtx target = const0_rtx;
2093
2094           if (lhs)
2095             target = expand_expr (lhs, NULL_RTX, VOIDmode, EXPAND_WRITE);
2096
2097           rtx data_dep = expand_normal (gimple_call_arg (stmt, 1));
2098           rtx axis = expand_normal (gimple_call_arg (stmt, 2));
2099
2100           if (kind == IFN_UNIQUE_OACC_FORK)
2101             pattern = targetm.gen_oacc_fork (target, data_dep, axis);
2102           else
2103             pattern = targetm.gen_oacc_join (target, data_dep, axis);
2104         }
2105       else
2106         gcc_unreachable ();
2107       break;
2108     }
2109
2110   if (pattern)
2111     emit_insn (pattern);
2112 }
2113
2114 /* The size of an OpenACC compute dimension.  */
2115
2116 static void
2117 expand_GOACC_DIM_SIZE (internal_fn, gcall *stmt)
2118 {
2119   tree lhs = gimple_call_lhs (stmt);
2120
2121   if (!lhs)
2122     return;
2123
2124   rtx target = expand_expr (lhs, NULL_RTX, VOIDmode, EXPAND_WRITE);
2125   if (targetm.have_oacc_dim_size ())
2126     {
2127       rtx dim = expand_expr (gimple_call_arg (stmt, 0), NULL_RTX,
2128                              VOIDmode, EXPAND_NORMAL);
2129       emit_insn (targetm.gen_oacc_dim_size (target, dim));
2130     }
2131   else
2132     emit_move_insn (target, GEN_INT (1));
2133 }
2134
2135 /* The position of an OpenACC execution engine along one compute axis.  */
2136
2137 static void
2138 expand_GOACC_DIM_POS (internal_fn, gcall *stmt)
2139 {
2140   tree lhs = gimple_call_lhs (stmt);
2141
2142   if (!lhs)
2143     return;
2144
2145   rtx target = expand_expr (lhs, NULL_RTX, VOIDmode, EXPAND_WRITE);
2146   if (targetm.have_oacc_dim_pos ())
2147     {
2148       rtx dim = expand_expr (gimple_call_arg (stmt, 0), NULL_RTX,
2149                              VOIDmode, EXPAND_NORMAL);
2150       emit_insn (targetm.gen_oacc_dim_pos (target, dim));
2151     }
2152   else
2153     emit_move_insn (target, const0_rtx);
2154 }
2155
2156 /* This is expanded by oacc_device_lower pass.  */
2157
2158 static void
2159 expand_GOACC_LOOP (internal_fn, gcall *)
2160 {
2161   gcc_unreachable ();
2162 }
2163
2164 /* This is expanded by oacc_device_lower pass.  */
2165
2166 static void
2167 expand_GOACC_REDUCTION (internal_fn, gcall *)
2168 {
2169   gcc_unreachable ();
2170 }
2171
2172 /* Set errno to EDOM.  */
2173
2174 static void
2175 expand_SET_EDOM (internal_fn, gcall *)
2176 {
2177 #ifdef TARGET_EDOM
2178 #ifdef GEN_ERRNO_RTX
2179   rtx errno_rtx = GEN_ERRNO_RTX;
2180 #else
2181   rtx errno_rtx = gen_rtx_MEM (word_mode, gen_rtx_SYMBOL_REF (Pmode, "errno"));
2182 #endif
2183   emit_move_insn (errno_rtx,
2184                   gen_int_mode (TARGET_EDOM, GET_MODE (errno_rtx)));
2185 #else
2186   gcc_unreachable ();
2187 #endif
2188 }
2189
2190 /* Expand atomic bit test and set.  */
2191
2192 static void
2193 expand_ATOMIC_BIT_TEST_AND_SET (internal_fn, gcall *call)
2194 {
2195   expand_ifn_atomic_bit_test_and (call);
2196 }
2197
2198 /* Expand atomic bit test and complement.  */
2199
2200 static void
2201 expand_ATOMIC_BIT_TEST_AND_COMPLEMENT (internal_fn, gcall *call)
2202 {
2203   expand_ifn_atomic_bit_test_and (call);
2204 }
2205
2206 /* Expand atomic bit test and reset.  */
2207
2208 static void
2209 expand_ATOMIC_BIT_TEST_AND_RESET (internal_fn, gcall *call)
2210 {
2211   expand_ifn_atomic_bit_test_and (call);
2212 }
2213
2214 /* Expand atomic bit test and set.  */
2215
2216 static void
2217 expand_ATOMIC_COMPARE_EXCHANGE (internal_fn, gcall *call)
2218 {
2219   expand_ifn_atomic_compare_exchange (call);
2220 }
2221
2222 /* Expand LAUNDER to assignment, lhs = arg0.  */
2223
2224 static void
2225 expand_LAUNDER (internal_fn, gcall *call)
2226 {
2227   tree lhs = gimple_call_lhs (call);
2228
2229   if (!lhs)
2230     return;
2231
2232   expand_assignment (lhs, gimple_call_arg (call, 0), false);
2233 }
2234
2235 /* Expand a call to FN using the operands in STMT.  FN has a single
2236    output operand and NARGS input operands.  */
2237
2238 static void
2239 expand_direct_optab_fn (internal_fn fn, gcall *stmt, direct_optab optab,
2240                         unsigned int nargs)
2241 {
2242   expand_operand *ops = XALLOCAVEC (expand_operand, nargs + 1);
2243
2244   tree_pair types = direct_internal_fn_types (fn, stmt);
2245   insn_code icode = direct_optab_handler (optab, TYPE_MODE (types.first));
2246
2247   tree lhs = gimple_call_lhs (stmt);
2248   tree lhs_type = TREE_TYPE (lhs);
2249   rtx lhs_rtx = expand_expr (lhs, NULL_RTX, VOIDmode, EXPAND_WRITE);
2250   create_output_operand (&ops[0], lhs_rtx, insn_data[icode].operand[0].mode);
2251
2252   for (unsigned int i = 0; i < nargs; ++i)
2253     {
2254       tree rhs = gimple_call_arg (stmt, i);
2255       tree rhs_type = TREE_TYPE (rhs);
2256       rtx rhs_rtx = expand_normal (rhs);
2257       if (INTEGRAL_TYPE_P (rhs_type))
2258         create_convert_operand_from (&ops[i + 1], rhs_rtx,
2259                                      TYPE_MODE (rhs_type),
2260                                      TYPE_UNSIGNED (rhs_type));
2261       else
2262         create_input_operand (&ops[i + 1], rhs_rtx, TYPE_MODE (rhs_type));
2263     }
2264
2265   expand_insn (icode, nargs + 1, ops);
2266   if (!rtx_equal_p (lhs_rtx, ops[0].value))
2267     {
2268       /* If the return value has an integral type, convert the instruction
2269          result to that type.  This is useful for things that return an
2270          int regardless of the size of the input.  If the instruction result
2271          is smaller than required, assume that it is signed.
2272
2273          If the return value has a nonintegral type, its mode must match
2274          the instruction result.  */
2275       if (GET_CODE (lhs_rtx) == SUBREG && SUBREG_PROMOTED_VAR_P (lhs_rtx))
2276         {
2277           /* If this is a scalar in a register that is stored in a wider
2278              mode than the declared mode, compute the result into its
2279              declared mode and then convert to the wider mode.  */
2280           gcc_checking_assert (INTEGRAL_TYPE_P (lhs_type));
2281           rtx tmp = convert_to_mode (GET_MODE (lhs_rtx), ops[0].value, 0);
2282           convert_move (SUBREG_REG (lhs_rtx), tmp,
2283                         SUBREG_PROMOTED_SIGN (lhs_rtx));
2284         }
2285       else if (GET_MODE (lhs_rtx) == GET_MODE (ops[0].value))
2286         emit_move_insn (lhs_rtx, ops[0].value);
2287       else
2288         {
2289           gcc_checking_assert (INTEGRAL_TYPE_P (lhs_type));
2290           convert_move (lhs_rtx, ops[0].value, 0);
2291         }
2292     }
2293 }
2294
2295 /* Expanders for optabs that can use expand_direct_optab_fn.  */
2296
2297 #define expand_unary_optab_fn(FN, STMT, OPTAB) \
2298   expand_direct_optab_fn (FN, STMT, OPTAB, 1)
2299
2300 #define expand_binary_optab_fn(FN, STMT, OPTAB) \
2301   expand_direct_optab_fn (FN, STMT, OPTAB, 2)
2302
2303 /* RETURN_TYPE and ARGS are a return type and argument list that are
2304    in principle compatible with FN (which satisfies direct_internal_fn_p).
2305    Return the types that should be used to determine whether the
2306    target supports FN.  */
2307
2308 tree_pair
2309 direct_internal_fn_types (internal_fn fn, tree return_type, tree *args)
2310 {
2311   const direct_internal_fn_info &info = direct_internal_fn (fn);
2312   tree type0 = (info.type0 < 0 ? return_type : TREE_TYPE (args[info.type0]));
2313   tree type1 = (info.type1 < 0 ? return_type : TREE_TYPE (args[info.type1]));
2314   return tree_pair (type0, type1);
2315 }
2316
2317 /* CALL is a call whose return type and arguments are in principle
2318    compatible with FN (which satisfies direct_internal_fn_p).  Return the
2319    types that should be used to determine whether the target supports FN.  */
2320
2321 tree_pair
2322 direct_internal_fn_types (internal_fn fn, gcall *call)
2323 {
2324   const direct_internal_fn_info &info = direct_internal_fn (fn);
2325   tree op0 = (info.type0 < 0
2326               ? gimple_call_lhs (call)
2327               : gimple_call_arg (call, info.type0));
2328   tree op1 = (info.type1 < 0
2329               ? gimple_call_lhs (call)
2330               : gimple_call_arg (call, info.type1));
2331   return tree_pair (TREE_TYPE (op0), TREE_TYPE (op1));
2332 }
2333
2334 /* Return true if OPTAB is supported for TYPES (whose modes should be
2335    the same) when the optimization type is OPT_TYPE.  Used for simple
2336    direct optabs.  */
2337
2338 static bool
2339 direct_optab_supported_p (direct_optab optab, tree_pair types,
2340                           optimization_type opt_type)
2341 {
2342   machine_mode mode = TYPE_MODE (types.first);
2343   gcc_checking_assert (mode == TYPE_MODE (types.second));
2344   return direct_optab_handler (optab, mode, opt_type) != CODE_FOR_nothing;
2345 }
2346
2347 /* Return true if load/store lanes optab OPTAB is supported for
2348    array type TYPES.first when the optimization type is OPT_TYPE.  */
2349
2350 static bool
2351 multi_vector_optab_supported_p (convert_optab optab, tree_pair types,
2352                                 optimization_type opt_type)
2353 {
2354   gcc_assert (TREE_CODE (types.first) == ARRAY_TYPE);
2355   machine_mode imode = TYPE_MODE (types.first);
2356   machine_mode vmode = TYPE_MODE (TREE_TYPE (types.first));
2357   return (convert_optab_handler (optab, imode, vmode, opt_type)
2358           != CODE_FOR_nothing);
2359 }
2360
2361 #define direct_unary_optab_supported_p direct_optab_supported_p
2362 #define direct_binary_optab_supported_p direct_optab_supported_p
2363 #define direct_mask_load_optab_supported_p direct_optab_supported_p
2364 #define direct_load_lanes_optab_supported_p multi_vector_optab_supported_p
2365 #define direct_mask_store_optab_supported_p direct_optab_supported_p
2366 #define direct_store_lanes_optab_supported_p multi_vector_optab_supported_p
2367
2368 /* Return true if FN is supported for the types in TYPES when the
2369    optimization type is OPT_TYPE.  The types are those associated with
2370    the "type0" and "type1" fields of FN's direct_internal_fn_info
2371    structure.  */
2372
2373 bool
2374 direct_internal_fn_supported_p (internal_fn fn, tree_pair types,
2375                                 optimization_type opt_type)
2376 {
2377   switch (fn)
2378     {
2379 #define DEF_INTERNAL_FN(CODE, FLAGS, FNSPEC) \
2380     case IFN_##CODE: break;
2381 #define DEF_INTERNAL_OPTAB_FN(CODE, FLAGS, OPTAB, TYPE) \
2382     case IFN_##CODE: \
2383       return direct_##TYPE##_optab_supported_p (OPTAB##_optab, types, \
2384                                                 opt_type);
2385 #include "internal-fn.def"
2386
2387     case IFN_LAST:
2388       break;
2389     }
2390   gcc_unreachable ();
2391 }
2392
2393 /* Return true if FN is supported for type TYPE when the optimization
2394    type is OPT_TYPE.  The caller knows that the "type0" and "type1"
2395    fields of FN's direct_internal_fn_info structure are the same.  */
2396
2397 bool
2398 direct_internal_fn_supported_p (internal_fn fn, tree type,
2399                                 optimization_type opt_type)
2400 {
2401   const direct_internal_fn_info &info = direct_internal_fn (fn);
2402   gcc_checking_assert (info.type0 == info.type1);
2403   return direct_internal_fn_supported_p (fn, tree_pair (type, type), opt_type);
2404 }
2405
2406 /* Return true if IFN_SET_EDOM is supported.  */
2407
2408 bool
2409 set_edom_supported_p (void)
2410 {
2411 #ifdef TARGET_EDOM
2412   return true;
2413 #else
2414   return false;
2415 #endif
2416 }
2417
2418 #define DEF_INTERNAL_OPTAB_FN(CODE, FLAGS, OPTAB, TYPE) \
2419   static void                                           \
2420   expand_##CODE (internal_fn fn, gcall *stmt)           \
2421   {                                                     \
2422     expand_##TYPE##_optab_fn (fn, stmt, OPTAB##_optab); \
2423   }
2424 #include "internal-fn.def"
2425
2426 /* Routines to expand each internal function, indexed by function number.
2427    Each routine has the prototype:
2428
2429        expand_<NAME> (gcall *stmt)
2430
2431    where STMT is the statement that performs the call. */
2432 static void (*const internal_fn_expanders[]) (internal_fn, gcall *) = {
2433 #define DEF_INTERNAL_FN(CODE, FLAGS, FNSPEC) expand_##CODE,
2434 #include "internal-fn.def"
2435   0
2436 };
2437
2438 /* Expand STMT as though it were a call to internal function FN.  */
2439
2440 void
2441 expand_internal_call (internal_fn fn, gcall *stmt)
2442 {
2443   internal_fn_expanders[fn] (fn, stmt);
2444 }
2445
2446 /* Expand STMT, which is a call to internal function FN.  */
2447
2448 void
2449 expand_internal_call (gcall *stmt)
2450 {
2451   expand_internal_call (gimple_call_internal_fn (stmt), stmt);
2452 }