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