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