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