Line data Source code
1 : /* Lower _BitInt(N) operations to scalar operations.
2 : Copyright (C) 2023-2026 Free Software Foundation, Inc.
3 : Contributed by Jakub Jelinek <jakub@redhat.com>.
4 :
5 : This file is part of GCC.
6 :
7 : GCC is free software; you can redistribute it and/or modify it
8 : under the terms of the GNU General Public License as published by the
9 : Free Software Foundation; either version 3, or (at your option) any
10 : later version.
11 :
12 : GCC is distributed in the hope that it will be useful, but WITHOUT
13 : ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
14 : FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License
15 : for more details.
16 :
17 : You should have received a copy of the GNU General Public License
18 : along with GCC; see the file COPYING3. If not see
19 : <http://www.gnu.org/licenses/>. */
20 :
21 : #include "config.h"
22 : #include "system.h"
23 : #include "coretypes.h"
24 : #include "backend.h"
25 : #include "rtl.h"
26 : #include "tree.h"
27 : #include "gimple.h"
28 : #include "cfghooks.h"
29 : #include "tree-pass.h"
30 : #include "ssa.h"
31 : #include "fold-const.h"
32 : #include "gimplify.h"
33 : #include "gimple-iterator.h"
34 : #include "tree-cfg.h"
35 : #include "tree-dfa.h"
36 : #include "cfgloop.h"
37 : #include "cfganal.h"
38 : #include "target.h"
39 : #include "tree-ssa-live.h"
40 : #include "tree-ssa-coalesce.h"
41 : #include "domwalk.h"
42 : #include "memmodel.h"
43 : #include "optabs.h"
44 : #include "varasm.h"
45 : #include "gimple-range.h"
46 : #include "value-range.h"
47 : #include "langhooks.h"
48 : #include "gimplify-me.h"
49 : #include "diagnostic-core.h"
50 : #include "tree-eh.h"
51 : #include "tree-pretty-print.h"
52 : #include "alloc-pool.h"
53 : #include "tree-into-ssa.h"
54 : #include "tree-cfgcleanup.h"
55 : #include "tree-switch-conversion.h"
56 : #include "ubsan.h"
57 : #include "stor-layout.h"
58 : #include "gimple-lower-bitint.h"
59 : #include "attribs.h"
60 : #include "asan.h"
61 :
62 : /* Split BITINT_TYPE precisions in 4 categories. Small _BitInt, where
63 : target hook says it is a single limb, middle _BitInt which per ABI
64 : does not, but there is some INTEGER_TYPE in which arithmetics can be
65 : performed (operations on such _BitInt are lowered to casts to that
66 : arithmetic type and cast back; e.g. on x86_64 limb is DImode, but
67 : target supports TImode, so _BitInt(65) to _BitInt(128) are middle
68 : ones), large _BitInt which should by straight line code and
69 : finally huge _BitInt which should be handled by loops over the limbs. */
70 :
71 : enum bitint_prec_kind {
72 : bitint_prec_small,
73 : bitint_prec_middle,
74 : bitint_prec_large,
75 : bitint_prec_huge
76 : };
77 :
78 : /* Caches to speed up bitint_precision_kind. */
79 :
80 : static int small_max_prec, mid_min_prec, large_min_prec, huge_min_prec;
81 : static int limb_prec, abi_limb_prec;
82 : static bool bitint_big_endian;
83 : static enum bitint_ext bitint_extended;
84 :
85 : /* Categorize _BitInt(PREC) as small, middle, large or huge. */
86 :
87 : static bitint_prec_kind
88 489455 : bitint_precision_kind (int prec)
89 : {
90 489455 : if (prec <= small_max_prec)
91 : return bitint_prec_small;
92 470970 : if (huge_min_prec && prec >= huge_min_prec)
93 : return bitint_prec_huge;
94 265647 : if (large_min_prec && prec >= large_min_prec)
95 : return bitint_prec_large;
96 52838 : if (mid_min_prec && prec >= mid_min_prec)
97 : return bitint_prec_middle;
98 :
99 10091 : struct bitint_info info;
100 10091 : bool ok = targetm.c.bitint_type_info (prec, &info);
101 10091 : gcc_assert (ok);
102 10091 : scalar_int_mode limb_mode = as_a <scalar_int_mode> (info.limb_mode);
103 10091 : if (prec <= GET_MODE_PRECISION (limb_mode))
104 : {
105 2626 : small_max_prec = prec;
106 2626 : return bitint_prec_small;
107 : }
108 7465 : bitint_big_endian = info.big_endian;
109 7465 : bitint_extended = info.extended;
110 7465 : if (info.limb_mode == info.abi_limb_mode && bitint_extended == bitint_ext_full)
111 0 : bitint_extended = bitint_ext_partial;
112 7465 : if (!large_min_prec
113 14833 : && GET_MODE_PRECISION (limb_mode) <= MAX_FIXED_MODE_SIZE)
114 14736 : large_min_prec = MAX_FIXED_MODE_SIZE + 1;
115 7465 : if (!limb_prec)
116 7368 : limb_prec = GET_MODE_PRECISION (limb_mode);
117 7465 : if (!abi_limb_prec)
118 7368 : abi_limb_prec
119 7368 : = GET_MODE_PRECISION (as_a <scalar_int_mode> (info.abi_limb_mode));
120 : /* For bitint_ext_full with different limb_mode from abi_limb_mode we
121 : currently only support only abi_limb_mode twice the precision of
122 : limb_mode, and don't support big endian in that case either. */
123 7465 : gcc_assert (bitint_extended != bitint_ext_full
124 : || (abi_limb_prec == 2 * limb_prec
125 : && !bitint_big_endian));
126 7465 : if (!huge_min_prec)
127 : {
128 14736 : if (4 * limb_prec >= MAX_FIXED_MODE_SIZE)
129 7368 : huge_min_prec = 4 * limb_prec;
130 : else
131 0 : huge_min_prec = MAX_FIXED_MODE_SIZE + 1;
132 : }
133 14930 : if (prec <= MAX_FIXED_MODE_SIZE)
134 : {
135 1625 : if (!mid_min_prec || prec < mid_min_prec)
136 1625 : mid_min_prec = prec;
137 : return bitint_prec_middle;
138 : }
139 5840 : if (huge_min_prec && prec >= huge_min_prec)
140 2361 : return bitint_prec_huge;
141 : return bitint_prec_large;
142 : }
143 :
144 : /* Same for a TYPE. */
145 :
146 : static bitint_prec_kind
147 483989 : bitint_precision_kind (tree type)
148 : {
149 483989 : return bitint_precision_kind (TYPE_PRECISION (type));
150 : }
151 :
152 : /* Return minimum precision needed to describe INTEGER_CST
153 : CST. All bits above that precision up to precision of
154 : TREE_TYPE (CST) are cleared if EXT is set to 0, or set
155 : if EXT is set to -1. */
156 :
157 : static unsigned
158 5399 : bitint_min_cst_precision (tree cst, int &ext)
159 : {
160 5399 : ext = tree_int_cst_sgn (cst) < 0 ? -1 : 0;
161 5399 : wide_int w = wi::to_wide (cst);
162 5399 : unsigned min_prec = wi::min_precision (w, TYPE_SIGN (TREE_TYPE (cst)));
163 : /* For signed values, we don't need to count the sign bit,
164 : we'll use constant 0 or -1 for the upper bits. */
165 5399 : if (!TYPE_UNSIGNED (TREE_TYPE (cst)))
166 3281 : --min_prec;
167 : else
168 : {
169 : /* For unsigned values, also try signed min_precision
170 : in case the constant has lots of most significant bits set. */
171 2118 : unsigned min_prec2 = wi::min_precision (w, SIGNED) - 1;
172 2118 : if (min_prec2 < min_prec)
173 : {
174 1002 : ext = -1;
175 1002 : return min_prec2;
176 : }
177 : }
178 : return min_prec;
179 5399 : }
180 :
181 : namespace {
182 :
183 : /* If OP is middle _BitInt, cast it to corresponding INTEGER_TYPE
184 : cached in TYPE and return it. */
185 :
186 : tree
187 7859 : maybe_cast_middle_bitint (gimple_stmt_iterator *gsi, tree op, tree &type)
188 : {
189 7859 : if (op == NULL_TREE
190 7826 : || !BITINT_TYPE_P (TREE_TYPE (op))
191 14803 : || bitint_precision_kind (TREE_TYPE (op)) != bitint_prec_middle)
192 : return op;
193 :
194 6927 : int prec = TYPE_PRECISION (TREE_TYPE (op));
195 6927 : int uns = TYPE_UNSIGNED (TREE_TYPE (op));
196 6927 : if (type == NULL_TREE
197 2557 : || TYPE_PRECISION (type) != prec
198 9484 : || TYPE_UNSIGNED (type) != uns)
199 4370 : type = build_nonstandard_integer_type (prec, uns);
200 :
201 6927 : if (TREE_CODE (op) != SSA_NAME)
202 : {
203 2365 : tree nop = fold_convert (type, op);
204 2365 : if (is_gimple_val (nop))
205 : return nop;
206 : }
207 :
208 4562 : tree nop = make_ssa_name (type);
209 4562 : gimple *g = gimple_build_assign (nop, NOP_EXPR, op);
210 4562 : gsi_insert_before (gsi, g, GSI_SAME_STMT);
211 4562 : return nop;
212 : }
213 :
214 : /* Return true if STMT can be handled in a loop from least to most
215 : significant limb together with its dependencies. */
216 :
217 : bool
218 48100 : mergeable_op (gimple *stmt)
219 : {
220 48100 : if (!is_gimple_assign (stmt))
221 : return false;
222 39375 : switch (gimple_assign_rhs_code (stmt))
223 : {
224 : case PLUS_EXPR:
225 : case MINUS_EXPR:
226 : case NEGATE_EXPR:
227 : case BIT_AND_EXPR:
228 : case BIT_IOR_EXPR:
229 : case BIT_XOR_EXPR:
230 : case BIT_NOT_EXPR:
231 : case SSA_NAME:
232 : case INTEGER_CST:
233 : case BIT_FIELD_REF:
234 : return true;
235 410 : case LSHIFT_EXPR:
236 410 : {
237 410 : tree cnt = gimple_assign_rhs2 (stmt);
238 410 : if (tree_fits_uhwi_p (cnt)
239 198 : && tree_to_uhwi (cnt) < (unsigned HOST_WIDE_INT) limb_prec)
240 : return true;
241 : }
242 : break;
243 6341 : CASE_CONVERT:
244 6341 : case VIEW_CONVERT_EXPR:
245 6341 : {
246 6341 : tree lhs_type = TREE_TYPE (gimple_assign_lhs (stmt));
247 6341 : tree rhs_type = TREE_TYPE (gimple_assign_rhs1 (stmt));
248 6341 : if (TREE_CODE (gimple_assign_rhs1 (stmt)) == SSA_NAME
249 6299 : && BITINT_TYPE_P (lhs_type)
250 3724 : && BITINT_TYPE_P (rhs_type)
251 3369 : && bitint_precision_kind (lhs_type) >= bitint_prec_large
252 3333 : && bitint_precision_kind (rhs_type) >= bitint_prec_large
253 9513 : && (CEIL (TYPE_PRECISION (lhs_type), limb_prec)
254 3172 : == CEIL (TYPE_PRECISION (rhs_type), limb_prec)))
255 : {
256 2198 : if (TYPE_PRECISION (rhs_type) >= TYPE_PRECISION (lhs_type))
257 : return true;
258 183 : if ((unsigned) TYPE_PRECISION (lhs_type) % (2 * limb_prec) != 0)
259 : return true;
260 17 : if (bitint_precision_kind (lhs_type) == bitint_prec_large)
261 : return true;
262 : }
263 : break;
264 : }
265 : default:
266 : break;
267 : }
268 : return false;
269 : }
270 :
271 : /* Return non-zero if stmt is .{ADD,SUB,MUL}_OVERFLOW call with
272 : _Complex large/huge _BitInt lhs which has at most two immediate uses,
273 : at most one use in REALPART_EXPR stmt in the same bb and exactly one
274 : IMAGPART_EXPR use in the same bb with a single use which casts it to
275 : non-BITINT_TYPE integral type. If there is a REALPART_EXPR use,
276 : return 2. Such cases (most common uses of those builtins) can be
277 : optimized by marking their lhs and lhs of IMAGPART_EXPR and maybe lhs
278 : of REALPART_EXPR as not needed to be backed up by a stack variable.
279 : For .UBSAN_CHECK_{ADD,SUB,MUL} return 3. */
280 :
281 : int
282 21481 : optimizable_arith_overflow (gimple *stmt)
283 : {
284 21481 : bool is_ubsan = false;
285 21481 : if (!is_gimple_call (stmt) || !gimple_call_internal_p (stmt))
286 : return false;
287 5236 : switch (gimple_call_internal_fn (stmt))
288 : {
289 : case IFN_ADD_OVERFLOW:
290 : case IFN_SUB_OVERFLOW:
291 : case IFN_MUL_OVERFLOW:
292 : break;
293 63 : case IFN_UBSAN_CHECK_ADD:
294 63 : case IFN_UBSAN_CHECK_SUB:
295 63 : case IFN_UBSAN_CHECK_MUL:
296 63 : is_ubsan = true;
297 63 : break;
298 : default:
299 : return 0;
300 : }
301 5210 : tree lhs = gimple_call_lhs (stmt);
302 5210 : if (!lhs)
303 : return 0;
304 5210 : if (SSA_NAME_OCCURS_IN_ABNORMAL_PHI (lhs))
305 : return 0;
306 5195 : tree type = is_ubsan ? TREE_TYPE (lhs) : TREE_TYPE (TREE_TYPE (lhs));
307 0 : if (!BITINT_TYPE_P (type)
308 5195 : || bitint_precision_kind (type) < bitint_prec_large)
309 : return 0;
310 :
311 5195 : if (is_ubsan)
312 : {
313 48 : use_operand_p use_p;
314 48 : gimple *use_stmt;
315 48 : if (!single_imm_use (lhs, &use_p, &use_stmt)
316 48 : || gimple_bb (use_stmt) != gimple_bb (stmt)
317 48 : || !gimple_store_p (use_stmt)
318 48 : || !is_gimple_assign (use_stmt)
319 48 : || gimple_has_volatile_ops (use_stmt)
320 96 : || stmt_ends_bb_p (use_stmt))
321 0 : return 0;
322 : return 3;
323 : }
324 :
325 5147 : imm_use_iterator ui;
326 5147 : use_operand_p use_p;
327 5147 : int seen = 0;
328 5147 : gimple *realpart = NULL, *cast = NULL;
329 14740 : FOR_EACH_IMM_USE_FAST (use_p, ui, lhs)
330 : {
331 9807 : gimple *g = USE_STMT (use_p);
332 9807 : if (is_gimple_debug (g))
333 0 : continue;
334 9807 : if (!is_gimple_assign (g) || gimple_bb (g) != gimple_bb (stmt))
335 : return 0;
336 9807 : if (gimple_assign_rhs_code (g) == REALPART_EXPR)
337 : {
338 4660 : if ((seen & 1) != 0)
339 : return 0;
340 4660 : seen |= 1;
341 4660 : realpart = g;
342 : }
343 5147 : else if (gimple_assign_rhs_code (g) == IMAGPART_EXPR)
344 : {
345 5147 : if ((seen & 2) != 0)
346 214 : return 0;
347 5147 : seen |= 2;
348 :
349 5147 : use_operand_p use2_p;
350 5147 : gimple *use_stmt;
351 5147 : tree lhs2 = gimple_assign_lhs (g);
352 5147 : if (SSA_NAME_OCCURS_IN_ABNORMAL_PHI (lhs2))
353 : return 0;
354 5147 : if (!single_imm_use (lhs2, &use2_p, &use_stmt)
355 5147 : || gimple_bb (use_stmt) != gimple_bb (stmt)
356 10294 : || !gimple_assign_cast_p (use_stmt))
357 : return 0;
358 :
359 4937 : lhs2 = gimple_assign_lhs (use_stmt);
360 9874 : if (!INTEGRAL_TYPE_P (TREE_TYPE (lhs2))
361 9874 : || BITINT_TYPE_P (TREE_TYPE (lhs2)))
362 : return 0;
363 4933 : cast = use_stmt;
364 : }
365 : else
366 : return 0;
367 214 : }
368 4933 : if ((seen & 2) == 0)
369 : return 0;
370 4933 : if (seen == 3)
371 : {
372 : /* Punt if the cast stmt appears before realpart stmt, because
373 : if both appear, the lowering wants to emit all the code
374 : at the location of realpart stmt. */
375 4660 : gimple_stmt_iterator gsi = gsi_for_stmt (realpart);
376 4660 : unsigned int cnt = 0;
377 4663 : do
378 : {
379 4663 : gsi_prev_nondebug (&gsi);
380 4663 : if (gsi_end_p (gsi) || gsi_stmt (gsi) == cast)
381 : return 0;
382 4660 : if (gsi_stmt (gsi) == stmt)
383 : return 2;
384 : /* If realpart is too far from stmt, punt as well.
385 : Usually it will appear right after it. */
386 3 : if (++cnt == 32)
387 : return 0;
388 : }
389 : while (1);
390 : }
391 : return 1;
392 : }
393 :
394 : /* If STMT is some kind of comparison (GIMPLE_COND, comparison assignment)
395 : comparing large/huge _BitInt types, return the comparison code and if
396 : non-NULL fill in the comparison operands to *POP1 and *POP2. */
397 :
398 : tree_code
399 36031 : comparison_op (gimple *stmt, tree *pop1, tree *pop2)
400 : {
401 36031 : tree op1 = NULL_TREE, op2 = NULL_TREE;
402 36031 : tree_code code = ERROR_MARK;
403 36031 : if (gimple_code (stmt) == GIMPLE_COND)
404 : {
405 6554 : code = gimple_cond_code (stmt);
406 6554 : op1 = gimple_cond_lhs (stmt);
407 6554 : op2 = gimple_cond_rhs (stmt);
408 : }
409 29477 : else if (is_gimple_assign (stmt))
410 : {
411 29450 : code = gimple_assign_rhs_code (stmt);
412 29450 : op1 = gimple_assign_rhs1 (stmt);
413 29450 : if (TREE_CODE_CLASS (code) == tcc_comparison
414 29450 : || TREE_CODE_CLASS (code) == tcc_binary)
415 2214 : op2 = gimple_assign_rhs2 (stmt);
416 : }
417 36031 : if (TREE_CODE_CLASS (code) != tcc_comparison)
418 : return ERROR_MARK;
419 7336 : tree type = TREE_TYPE (op1);
420 10 : if (!BITINT_TYPE_P (type)
421 7346 : || bitint_precision_kind (type) < bitint_prec_large)
422 : return ERROR_MARK;
423 7336 : if (pop1)
424 : {
425 7274 : *pop1 = op1;
426 7274 : *pop2 = op2;
427 : }
428 : return code;
429 : }
430 :
431 : /* Class used during large/huge _BitInt lowering containing all the
432 : state for the methods. */
433 :
434 : struct bitint_large_huge
435 : {
436 7366 : bitint_large_huge ()
437 7366 : : m_names (NULL), m_loads (NULL), m_preserved (NULL),
438 7366 : m_single_use_names (NULL), m_map (NULL), m_vars (NULL),
439 7366 : m_limb_type (NULL_TREE), m_data (vNULL),
440 7366 : m_returns_twice_calls (vNULL) {}
441 :
442 : ~bitint_large_huge ();
443 :
444 : void insert_before (gimple *);
445 : tree limb_access_type (tree, tree);
446 : tree limb_access (tree, tree, tree, bool, bool = false);
447 : tree build_bit_field_ref (tree, tree, unsigned HOST_WIDE_INT,
448 : unsigned HOST_WIDE_INT);
449 : void if_then (gimple *, profile_probability, edge &, edge &);
450 : void if_then_else (gimple *, profile_probability, edge &, edge &);
451 : void if_then_if_then_else (gimple *g, gimple *,
452 : profile_probability, profile_probability,
453 : edge &, edge &, edge &);
454 : tree handle_operand (tree, tree);
455 : tree prepare_data_in_out (tree, tree, tree *, tree = NULL_TREE);
456 : tree add_cast (tree, tree);
457 : tree handle_plus_minus (tree_code, tree, tree, tree);
458 : tree handle_lshift (tree, tree, tree);
459 : tree handle_cast (tree, tree, tree);
460 : tree handle_bit_field_ref (tree, tree);
461 : tree handle_load (gimple *, tree);
462 : tree handle_stmt (gimple *, tree);
463 : tree handle_operand_addr (tree, gimple *, int *, int *);
464 : tree create_loop (tree, tree *);
465 : tree lower_mergeable_stmt (gimple *, tree_code &, tree, tree);
466 : tree lower_comparison_stmt (gimple *, tree_code &, tree, tree);
467 : void lower_shift_stmt (tree, gimple *);
468 : void lower_muldiv_stmt (tree, gimple *);
469 : void lower_float_conv_stmt (tree, gimple *);
470 : tree arith_overflow_extract_bits (unsigned int, unsigned int, tree,
471 : unsigned int, bool);
472 : void finish_arith_overflow (tree, tree, tree, tree, tree, tree, gimple *,
473 : unsigned, tree_code);
474 : void lower_addsub_overflow (tree, gimple *);
475 : void lower_mul_overflow (tree, gimple *);
476 : void lower_cplxpart_stmt (tree, gimple *);
477 : void lower_complexexpr_stmt (gimple *);
478 : void lower_bit_query (gimple *);
479 : void lower_bswap_bitreverse (tree, gimple *);
480 : void lower_call (tree, gimple *);
481 : void lower_asm (gimple *);
482 : void lower_stmt (gimple *);
483 :
484 : /* Bitmap of large/huge _BitInt SSA_NAMEs except those can be
485 : merged with their uses. */
486 : bitmap m_names;
487 : /* Subset of those for lhs of load statements. These will be
488 : cleared in m_names if the loads will be mergeable with all
489 : their uses. */
490 : bitmap m_loads;
491 : /* Bitmap of large/huge _BitInt SSA_NAMEs that should survive
492 : to later passes (arguments or return values of calls). */
493 : bitmap m_preserved;
494 : /* Subset of m_names which have a single use. As the lowering
495 : can replace various original statements with their lowered
496 : form even before it is done iterating over all basic blocks,
497 : testing has_single_use for the purpose of emitting clobbers
498 : doesn't work properly. */
499 : bitmap m_single_use_names;
500 : /* Used for coalescing/partitioning of large/huge _BitInt SSA_NAMEs
501 : set in m_names. */
502 : var_map m_map;
503 : /* Mapping of the partitions to corresponding decls. */
504 : tree *m_vars;
505 : /* Unsigned integer type with limb precision. */
506 : tree m_limb_type;
507 : /* Its TYPE_SIZE_UNIT. */
508 : unsigned HOST_WIDE_INT m_limb_size;
509 : /* Location of a gimple stmt which is being currently lowered. */
510 : location_t m_loc;
511 : /* Current stmt iterator where code is being lowered currently. */
512 : gimple_stmt_iterator m_gsi;
513 : /* Statement after which any clobbers should be added if non-NULL. */
514 : gimple *m_after_stmt;
515 : /* Set when creating loops to the loop header bb and its preheader. */
516 : basic_block m_bb, m_preheader_bb;
517 : /* Stmt iterator after which initialization statements should be emitted. */
518 : gimple_stmt_iterator m_init_gsi;
519 : /* Decl into which a mergeable statement stores result. */
520 : tree m_lhs;
521 : /* handle_operand/handle_stmt can be invoked in various ways.
522 :
523 : lower_mergeable_stmt for large _BitInt calls those with constant
524 : idx only, expanding to straight line code, for huge _BitInt
525 : emits a loop from least significant limb upwards, where each loop
526 : iteration handles 2 limbs, plus there can be up to one full limb
527 : and one partial limb processed after the loop, where handle_operand
528 : and/or handle_stmt are called with constant idx. m_upwards_2limb
529 : is set for this case, false otherwise. m_upwards is true if it
530 : is either large or huge _BitInt handled by lower_mergeable_stmt,
531 : i.e. indexes always increase.
532 :
533 : Another way is used by lower_comparison_stmt, which walks limbs
534 : from most significant to least significant, partial limb if any
535 : processed first with constant idx and then loop processing a single
536 : limb per iteration with non-constant idx.
537 :
538 : Another way is used in lower_shift_stmt, where for LSHIFT_EXPR
539 : destination limbs are processed from most significant to least
540 : significant or for RSHIFT_EXPR the other way around, in loops or
541 : straight line code, but idx usually is non-constant (so from
542 : handle_operand/handle_stmt POV random access). The LSHIFT_EXPR
543 : handling there can access even partial limbs using non-constant
544 : idx (then m_var_msb should be true, for all the other cases
545 : including lower_mergeable_stmt/lower_comparison_stmt that is
546 : not the case and so m_var_msb should be false.
547 :
548 : m_first should be set the first time handle_operand/handle_stmt
549 : is called and clear when it is called for some other limb with
550 : the same argument. If the lowering of an operand (e.g. INTEGER_CST)
551 : or statement (e.g. +/-/<< with < limb_prec constant) needs some
552 : state between the different calls, when m_first is true it should
553 : push some trees to m_data vector and also make sure m_data_cnt is
554 : incremented by how many trees were pushed, and when m_first is
555 : false, it can use the m_data[m_data_cnt] etc. data or update them,
556 : just needs to bump m_data_cnt by the same amount as when it was
557 : called with m_first set. The toplevel calls to
558 : handle_operand/handle_stmt should set m_data_cnt to 0 and truncate
559 : m_data vector when setting m_first to true.
560 :
561 : m_cast_conditional and m_bitfld_load are used when handling a
562 : bit-field load inside of a widening cast. handle_cast sometimes
563 : needs to do runtime comparisons and handle_operand only conditionally
564 : or even in two separate conditional blocks for one idx (once with
565 : constant index after comparing the runtime one for equality with the
566 : constant). In these cases, m_cast_conditional is set to true and
567 : the bit-field load then communicates its m_data_cnt to handle_cast
568 : using m_bitfld_load. */
569 : bool m_first;
570 : bool m_var_msb;
571 : unsigned m_upwards_2limb;
572 : bool m_upwards;
573 : bool m_cast_conditional;
574 : unsigned m_bitfld_load;
575 : vec<tree> m_data;
576 : unsigned int m_data_cnt;
577 : vec<gimple *> m_returns_twice_calls;
578 : };
579 :
580 7366 : bitint_large_huge::~bitint_large_huge ()
581 : {
582 7366 : BITMAP_FREE (m_names);
583 7366 : BITMAP_FREE (m_loads);
584 7366 : BITMAP_FREE (m_preserved);
585 7366 : BITMAP_FREE (m_single_use_names);
586 7366 : if (m_map)
587 5691 : delete_var_map (m_map);
588 7366 : XDELETEVEC (m_vars);
589 7366 : m_data.release ();
590 7366 : m_returns_twice_calls.release ();
591 7366 : }
592 :
593 : /* Insert gimple statement G before current location
594 : and set its gimple_location. */
595 :
596 : void
597 364137 : bitint_large_huge::insert_before (gimple *g)
598 : {
599 364137 : gimple_set_location (g, m_loc);
600 364137 : gsi_insert_before (&m_gsi, g, GSI_SAME_STMT);
601 364137 : }
602 :
603 : /* Return type for accessing limb IDX of BITINT_TYPE TYPE.
604 : This is normally m_limb_type, except for a partial most
605 : significant limb if any. */
606 :
607 : tree
608 130868 : bitint_large_huge::limb_access_type (tree type, tree idx)
609 : {
610 130868 : if (type == NULL_TREE)
611 5913 : return m_limb_type;
612 124955 : unsigned HOST_WIDE_INT i = tree_to_uhwi (idx);
613 124955 : unsigned int prec = TYPE_PRECISION (type);
614 124955 : gcc_assert (i * limb_prec < prec
615 : || (bitint_extended == bitint_ext_full
616 : && abi_limb_prec > limb_prec
617 : && i * limb_prec
618 : < CEIL (prec, abi_limb_prec) * abi_limb_prec));
619 249910 : if (bitint_big_endian
620 124955 : ? (i != 0 || (prec % limb_prec) == 0)
621 124955 : : (i + 1) * limb_prec <= prec)
622 81548 : return m_limb_type;
623 : else
624 86814 : return build_nonstandard_integer_type (prec % limb_prec,
625 43407 : TYPE_UNSIGNED (type));
626 : }
627 :
628 : /* Return a tree how to access limb IDX of VAR corresponding to BITINT_TYPE
629 : TYPE. If WRITE_P is true, it will be a store, otherwise a read. */
630 :
631 : tree
632 156189 : bitint_large_huge::limb_access (tree type, tree var, tree idx, bool write_p,
633 : bool abi_load_p)
634 : {
635 156189 : tree atype = (tree_fits_uhwi_p (idx)
636 156189 : ? limb_access_type (type, idx) : m_limb_type);
637 :
638 156189 : tree ltype = (bitint_extended && abi_load_p) ? atype : m_limb_type;
639 :
640 156189 : addr_space_t as = TYPE_ADDR_SPACE (TREE_TYPE (var));
641 156189 : tree ret;
642 156189 : if (DECL_P (var) && tree_fits_uhwi_p (idx))
643 : {
644 96025 : if (as != TYPE_ADDR_SPACE (ltype))
645 0 : ltype = build_qualified_type (ltype, TYPE_QUALS (ltype)
646 0 : | ENCODE_QUAL_ADDR_SPACE (as));
647 96025 : tree ptype = build_pointer_type (strip_array_types (TREE_TYPE (var)));
648 96025 : unsigned HOST_WIDE_INT off = tree_to_uhwi (idx) * m_limb_size;
649 96025 : if (bitint_big_endian)
650 0 : off += m_limb_size - tree_to_uhwi (TYPE_SIZE_UNIT (ltype));
651 96025 : ret = build2 (MEM_REF, ltype,
652 : build_fold_addr_expr (var),
653 96025 : build_int_cst (ptype, off));
654 96025 : TREE_THIS_VOLATILE (ret) = TREE_THIS_VOLATILE (var);
655 96025 : TREE_SIDE_EFFECTS (ret) = TREE_SIDE_EFFECTS (var);
656 96025 : }
657 60164 : else if (TREE_CODE (var) == MEM_REF && tree_fits_uhwi_p (idx))
658 : {
659 4316 : if (as != TYPE_ADDR_SPACE (ltype))
660 0 : ltype = build_qualified_type (ltype, TYPE_QUALS (ltype)
661 0 : | ENCODE_QUAL_ADDR_SPACE (as));
662 4316 : unsigned HOST_WIDE_INT off = tree_to_uhwi (idx) * m_limb_size;
663 4316 : if (bitint_big_endian)
664 0 : off += m_limb_size - tree_to_uhwi (TYPE_SIZE_UNIT (ltype));
665 4316 : ret
666 8632 : = build2 (MEM_REF, ltype, unshare_expr (TREE_OPERAND (var, 0)),
667 8632 : size_binop (PLUS_EXPR, TREE_OPERAND (var, 1),
668 : build_int_cst (TREE_TYPE (TREE_OPERAND (var, 1)),
669 : off)));
670 4316 : TREE_THIS_VOLATILE (ret) = TREE_THIS_VOLATILE (var);
671 4316 : TREE_SIDE_EFFECTS (ret) = TREE_SIDE_EFFECTS (var);
672 4316 : TREE_THIS_NOTRAP (ret) = TREE_THIS_NOTRAP (var);
673 4316 : }
674 : else
675 : {
676 55848 : ltype = m_limb_type;
677 55848 : if (as != TYPE_ADDR_SPACE (ltype))
678 17 : ltype = build_qualified_type (ltype, TYPE_QUALS (ltype)
679 17 : | ENCODE_QUAL_ADDR_SPACE (as));
680 55848 : var = unshare_expr (var);
681 55848 : if (TREE_CODE (TREE_TYPE (var)) != ARRAY_TYPE
682 83858 : || !useless_type_conversion_p (m_limb_type,
683 28010 : TREE_TYPE (TREE_TYPE (var))))
684 : {
685 28780 : unsigned HOST_WIDE_INT nelts
686 28780 : = CEIL (tree_to_uhwi (TYPE_SIZE (TREE_TYPE (var))), limb_prec);
687 28780 : tree atype = build_array_type_nelts (ltype, nelts);
688 28780 : var = build1 (VIEW_CONVERT_EXPR, atype, var);
689 : }
690 55848 : ret = build4 (ARRAY_REF, ltype, var, idx, NULL_TREE, NULL_TREE);
691 : }
692 156189 : if (!write_p && !useless_type_conversion_p (atype, ltype))
693 : {
694 19040 : gimple *g = gimple_build_assign (make_ssa_name (m_limb_type), ret);
695 19040 : insert_before (g);
696 19040 : ret = gimple_assign_lhs (g);
697 19040 : ret = build1 (NOP_EXPR, atype, ret);
698 : }
699 156189 : return ret;
700 : }
701 :
702 : /* Build a BIT_FIELD_REF to access BITSIZE bits with FTYPE type at
703 : offset BITPOS inside of OBJ. */
704 :
705 : tree
706 273 : bitint_large_huge::build_bit_field_ref (tree ftype, tree obj,
707 : unsigned HOST_WIDE_INT bitsize,
708 : unsigned HOST_WIDE_INT bitpos)
709 : {
710 546 : if (INTEGRAL_TYPE_P (TREE_TYPE (obj))
711 282 : && !type_has_mode_precision_p (TREE_TYPE (obj)))
712 : {
713 9 : unsigned HOST_WIDE_INT nelts
714 9 : = CEIL (tree_to_uhwi (TYPE_SIZE (TREE_TYPE (obj))), limb_prec);
715 9 : tree ltype = m_limb_type;
716 9 : addr_space_t as = TYPE_ADDR_SPACE (TREE_TYPE (obj));
717 9 : if (as != TYPE_ADDR_SPACE (ltype))
718 0 : ltype = build_qualified_type (ltype, TYPE_QUALS (ltype)
719 0 : | ENCODE_QUAL_ADDR_SPACE (as));
720 9 : tree atype = build_array_type_nelts (ltype, nelts);
721 9 : obj = build1 (VIEW_CONVERT_EXPR, atype, obj);
722 : }
723 273 : return build3 (BIT_FIELD_REF, ftype, obj, bitsize_int (bitsize),
724 273 : bitsize_int (bitpos));
725 : }
726 :
727 : /* Emit a half diamond,
728 : if (COND)
729 : |\
730 : | \
731 : | \
732 : | new_bb1
733 : | /
734 : | /
735 : |/
736 : or if (COND) new_bb1;
737 : PROB is the probability that the condition is true.
738 : Updates m_gsi to start of new_bb1.
739 : Sets EDGE_TRUE to edge from new_bb1 to successor and
740 : EDGE_FALSE to the EDGE_FALSE_VALUE edge from if (COND) bb. */
741 :
742 : void
743 4318 : bitint_large_huge::if_then (gimple *cond, profile_probability prob,
744 : edge &edge_true, edge &edge_false)
745 : {
746 4318 : insert_before (cond);
747 4318 : edge e1 = split_block (gsi_bb (m_gsi), cond);
748 4318 : edge e2 = split_block (e1->dest, (gimple *) NULL);
749 4318 : edge e3 = make_edge (e1->src, e2->dest, EDGE_FALSE_VALUE);
750 4318 : e1->flags = EDGE_TRUE_VALUE;
751 4318 : e1->probability = prob;
752 4318 : e3->probability = prob.invert ();
753 4318 : set_immediate_dominator (CDI_DOMINATORS, e2->dest, e1->src);
754 4318 : edge_true = e2;
755 4318 : edge_false = e3;
756 4318 : m_gsi = gsi_after_labels (e1->dest);
757 4318 : }
758 :
759 : /* Emit a full diamond,
760 : if (COND)
761 : /\
762 : / \
763 : / \
764 : new_bb1 new_bb2
765 : \ /
766 : \ /
767 : \/
768 : or if (COND) new_bb2; else new_bb1;
769 : PROB is the probability that the condition is true.
770 : Updates m_gsi to start of new_bb2.
771 : Sets EDGE_TRUE to edge from new_bb1 to successor and
772 : EDGE_FALSE to the EDGE_FALSE_VALUE edge from if (COND) bb. */
773 :
774 : void
775 112 : bitint_large_huge::if_then_else (gimple *cond, profile_probability prob,
776 : edge &edge_true, edge &edge_false)
777 : {
778 112 : insert_before (cond);
779 112 : edge e1 = split_block (gsi_bb (m_gsi), cond);
780 112 : edge e2 = split_block (e1->dest, (gimple *) NULL);
781 112 : basic_block bb = create_empty_bb (e1->dest);
782 112 : add_bb_to_loop (bb, e1->dest->loop_father);
783 112 : edge e3 = make_edge (e1->src, bb, EDGE_TRUE_VALUE);
784 112 : e1->flags = EDGE_FALSE_VALUE;
785 112 : e3->probability = prob;
786 112 : e1->probability = prob.invert ();
787 112 : bb->count = e1->src->count.apply_probability (prob);
788 112 : set_immediate_dominator (CDI_DOMINATORS, bb, e1->src);
789 112 : set_immediate_dominator (CDI_DOMINATORS, e2->dest, e1->src);
790 112 : edge_true = make_single_succ_edge (bb, e2->dest, EDGE_FALLTHRU);
791 112 : edge_false = e2;
792 112 : m_gsi = gsi_after_labels (bb);
793 112 : }
794 :
795 : /* Emit a half diamond with full diamond in it
796 : if (COND1)
797 : |\
798 : | \
799 : | \
800 : | if (COND2)
801 : | / \
802 : | / \
803 : |new_bb1 new_bb2
804 : | | /
805 : \ | /
806 : \ | /
807 : \ | /
808 : \|/
809 : or if (COND1) { if (COND2) new_bb2; else new_bb1; }
810 : PROB1 is the probability that the condition 1 is true.
811 : PROB2 is the probability that the condition 2 is true.
812 : Updates m_gsi to start of new_bb1.
813 : Sets EDGE_TRUE_TRUE to edge from new_bb2 to successor,
814 : EDGE_TRUE_FALSE to edge from new_bb1 to successor and
815 : EDGE_FALSE to the EDGE_FALSE_VALUE edge from if (COND1) bb.
816 : If COND2 is NULL, this is equivalent to
817 : if_then (COND1, PROB1, EDGE_TRUE_FALSE, EDGE_FALSE);
818 : EDGE_TRUE_TRUE = NULL; */
819 :
820 : void
821 2098 : bitint_large_huge::if_then_if_then_else (gimple *cond1, gimple *cond2,
822 : profile_probability prob1,
823 : profile_probability prob2,
824 : edge &edge_true_true,
825 : edge &edge_true_false,
826 : edge &edge_false)
827 : {
828 2098 : edge e2, e3, e4 = NULL;
829 2098 : if_then (cond1, prob1, e2, e3);
830 2098 : if (cond2 == NULL)
831 : {
832 1257 : edge_true_true = NULL;
833 1257 : edge_true_false = e2;
834 1257 : edge_false = e3;
835 1257 : return;
836 : }
837 841 : insert_before (cond2);
838 841 : e2 = split_block (gsi_bb (m_gsi), cond2);
839 841 : basic_block bb = create_empty_bb (e2->dest);
840 841 : add_bb_to_loop (bb, e2->dest->loop_father);
841 841 : e4 = make_edge (e2->src, bb, EDGE_TRUE_VALUE);
842 841 : set_immediate_dominator (CDI_DOMINATORS, bb, e2->src);
843 841 : e4->probability = prob2;
844 841 : e2->flags = EDGE_FALSE_VALUE;
845 841 : e2->probability = prob2.invert ();
846 841 : bb->count = e2->src->count.apply_probability (prob2);
847 841 : e4 = make_single_succ_edge (bb, e3->dest, EDGE_FALLTHRU);
848 841 : e2 = find_edge (e2->dest, e3->dest);
849 841 : edge_true_true = e4;
850 841 : edge_true_false = e2;
851 841 : edge_false = e3;
852 841 : m_gsi = gsi_after_labels (e2->src);
853 : }
854 :
855 : /* Emit code to access limb IDX from OP. */
856 :
857 : tree
858 111511 : bitint_large_huge::handle_operand (tree op, tree idx)
859 : {
860 111511 : switch (TREE_CODE (op))
861 : {
862 77073 : case SSA_NAME:
863 77073 : if (m_names == NULL
864 77073 : || !bitmap_bit_p (m_names, SSA_NAME_VERSION (op)))
865 : {
866 14521 : if (SSA_NAME_IS_DEFAULT_DEF (op))
867 : {
868 47 : if (m_first)
869 : {
870 16 : tree v = create_tmp_reg (m_limb_type);
871 16 : if (SSA_NAME_VAR (op) && VAR_P (SSA_NAME_VAR (op)))
872 : {
873 16 : DECL_NAME (v) = DECL_NAME (SSA_NAME_VAR (op));
874 16 : DECL_SOURCE_LOCATION (v)
875 16 : = DECL_SOURCE_LOCATION (SSA_NAME_VAR (op));
876 : }
877 16 : v = get_or_create_ssa_default_def (cfun, v);
878 16 : m_data.safe_push (v);
879 : }
880 47 : tree ret = m_data[m_data_cnt];
881 47 : m_data_cnt++;
882 47 : if (tree_fits_uhwi_p (idx))
883 : {
884 45 : tree type = limb_access_type (TREE_TYPE (op), idx);
885 45 : ret = add_cast (type, ret);
886 : }
887 : return ret;
888 : }
889 14474 : location_t loc_save = m_loc;
890 14474 : m_loc = gimple_location (SSA_NAME_DEF_STMT (op));
891 14474 : tree ret = handle_stmt (SSA_NAME_DEF_STMT (op), idx);
892 14474 : m_loc = loc_save;
893 14474 : return ret;
894 : }
895 62552 : int p;
896 62552 : gimple *g;
897 62552 : tree t;
898 62552 : p = var_to_partition (m_map, op);
899 62552 : gcc_assert (m_vars[p] != NULL_TREE);
900 62552 : t = limb_access (TREE_TYPE (op), m_vars[p], idx, false);
901 62552 : g = gimple_build_assign (make_ssa_name (TREE_TYPE (t)), t);
902 62552 : insert_before (g);
903 62552 : t = gimple_assign_lhs (g);
904 62552 : if (m_first
905 22645 : && m_single_use_names
906 21773 : && m_vars[p] != m_lhs
907 21673 : && m_after_stmt
908 71318 : && bitmap_bit_p (m_single_use_names, SSA_NAME_VERSION (op)))
909 : {
910 8450 : tree clobber = build_clobber (TREE_TYPE (m_vars[p]),
911 : CLOBBER_STORAGE_END);
912 8450 : g = gimple_build_assign (m_vars[p], clobber);
913 8450 : gimple_stmt_iterator gsi = gsi_for_stmt (m_after_stmt);
914 8450 : gsi_insert_after (&gsi, g, GSI_SAME_STMT);
915 : }
916 : return t;
917 34438 : case INTEGER_CST:
918 34438 : if (tree_fits_uhwi_p (idx))
919 : {
920 23839 : tree c, type = limb_access_type (TREE_TYPE (op), idx);
921 23839 : unsigned HOST_WIDE_INT i = tree_to_uhwi (idx);
922 23839 : if (m_first)
923 : {
924 6214 : m_data.safe_push (NULL_TREE);
925 6214 : m_data.safe_push (NULL_TREE);
926 : }
927 23839 : if (bitint_big_endian)
928 0 : i = CEIL (TYPE_PRECISION (TREE_TYPE (op)), limb_prec) - 1 - i;
929 23839 : if (limb_prec != HOST_BITS_PER_WIDE_INT)
930 : {
931 0 : wide_int w = wi::rshift (wi::to_wide (op), i * limb_prec,
932 0 : TYPE_SIGN (TREE_TYPE (op)));
933 0 : c = wide_int_to_tree (type,
934 0 : wide_int::from (w, TYPE_PRECISION (type),
935 : UNSIGNED));
936 0 : }
937 23839 : else if (i >= TREE_INT_CST_EXT_NUNITS (op))
938 7511 : c = build_int_cst (type,
939 13334 : tree_int_cst_sgn (op) < 0 ? -1 : 0);
940 : else
941 16328 : c = build_int_cst (type, TREE_INT_CST_ELT (op, i));
942 23839 : m_data_cnt += 2;
943 23839 : return c;
944 : }
945 10599 : if (m_first
946 10599 : || (m_data[m_data_cnt] == NULL_TREE
947 159 : && m_data[m_data_cnt + 1] == NULL_TREE))
948 : {
949 5345 : unsigned int prec = TYPE_PRECISION (TREE_TYPE (op));
950 5345 : unsigned int rem = prec % ((m_upwards_2limb ? 2 : 1) * limb_prec);
951 5345 : int ext;
952 5345 : unsigned min_prec = bitint_min_cst_precision (op, ext);
953 5345 : if (m_first)
954 : {
955 5186 : m_data.safe_push (NULL_TREE);
956 5186 : m_data.safe_push (NULL_TREE);
957 : }
958 5345 : if (integer_zerop (op))
959 : {
960 837 : tree c = build_zero_cst (m_limb_type);
961 837 : m_data[m_data_cnt] = c;
962 837 : m_data[m_data_cnt + 1] = c;
963 : }
964 4508 : else if (integer_all_onesp (op))
965 : {
966 679 : tree c = build_all_ones_cst (m_limb_type);
967 679 : m_data[m_data_cnt] = c;
968 679 : m_data[m_data_cnt + 1] = c;
969 : }
970 3829 : else if (m_upwards_2limb && min_prec <= (unsigned) limb_prec)
971 : {
972 : /* Single limb constant. Use a phi with that limb from
973 : the preheader edge and 0 or -1 constant from the other edge
974 : and for the second limb in the loop. */
975 895 : tree out;
976 895 : gcc_assert (m_first);
977 895 : m_data.pop ();
978 895 : m_data.pop ();
979 895 : prepare_data_in_out (fold_convert (m_limb_type, op), idx, &out,
980 895 : build_int_cst (m_limb_type, ext));
981 895 : }
982 2934 : else if (min_prec > prec - rem - 2 * limb_prec)
983 : {
984 : /* Constant which has enough significant bits that it isn't
985 : worth trying to save .rodata space by extending from smaller
986 : number. */
987 2415 : tree type;
988 2415 : if (m_var_msb)
989 25 : type = TREE_TYPE (op);
990 : else
991 : /* If we have a guarantee the most significant partial limb
992 : (if any) will be only accessed through handle_operand
993 : with INTEGER_CST idx, we don't need to include the partial
994 : limb in .rodata. */
995 2390 : type = build_bitint_type (prec - rem, 1);
996 2415 : tree c = tree_output_constant_def (fold_convert (type, op));
997 2415 : m_data[m_data_cnt] = c;
998 2415 : m_data[m_data_cnt + 1] = NULL_TREE;
999 : }
1000 519 : else if (m_upwards_2limb)
1001 : {
1002 : /* Constant with smaller number of bits. Trade conditional
1003 : code for .rodata space by extending from smaller number. */
1004 444 : min_prec = CEIL (min_prec, 2 * limb_prec) * (2 * limb_prec);
1005 444 : tree type = build_bitint_type (min_prec, 1);
1006 444 : tree c = tree_output_constant_def (fold_convert (type, op));
1007 444 : tree ridx = idx;
1008 444 : if (bitint_big_endian)
1009 : {
1010 0 : ridx = make_ssa_name (sizetype);
1011 0 : g = gimple_build_assign (ridx, PLUS_EXPR, idx,
1012 0 : size_int (min_prec / limb_prec
1013 : - ((HOST_WIDE_INT)
1014 : CEIL (prec,
1015 : limb_prec))));
1016 0 : insert_before (g);
1017 : }
1018 444 : tree ridx2 = make_ssa_name (sizetype);
1019 444 : g = gimple_build_assign (ridx2, PLUS_EXPR, ridx,
1020 : bitint_big_endian
1021 0 : ? size_int (-1) : size_one_node);
1022 444 : insert_before (g);
1023 444 : if (bitint_big_endian)
1024 0 : g = gimple_build_cond (GE_EXPR, idx,
1025 0 : size_int (CEIL (prec, limb_prec)
1026 : - min_prec / limb_prec),
1027 : NULL_TREE, NULL_TREE);
1028 : else
1029 444 : g = gimple_build_cond (LT_EXPR, idx,
1030 444 : size_int (min_prec / limb_prec),
1031 : NULL_TREE, NULL_TREE);
1032 444 : edge edge_true, edge_false;
1033 888 : if_then (g, (min_prec >= (prec - rem) / 2
1034 312 : ? profile_probability::likely ()
1035 132 : : profile_probability::unlikely ()),
1036 : edge_true, edge_false);
1037 444 : tree c1 = limb_access (TREE_TYPE (op), c, ridx, false);
1038 444 : g = gimple_build_assign (make_ssa_name (TREE_TYPE (c1)), c1);
1039 444 : insert_before (g);
1040 444 : c1 = gimple_assign_lhs (g);
1041 444 : tree c2 = limb_access (TREE_TYPE (op), c, ridx2, false);
1042 444 : g = gimple_build_assign (make_ssa_name (TREE_TYPE (c2)), c2);
1043 444 : insert_before (g);
1044 444 : c2 = gimple_assign_lhs (g);
1045 444 : tree c3 = build_int_cst (m_limb_type, ext);
1046 444 : m_gsi = gsi_after_labels (edge_true->dest);
1047 444 : m_data[m_data_cnt] = make_ssa_name (m_limb_type);
1048 444 : m_data[m_data_cnt + 1] = make_ssa_name (m_limb_type);
1049 444 : gphi *phi = create_phi_node (m_data[m_data_cnt],
1050 : edge_true->dest);
1051 444 : add_phi_arg (phi, c1, edge_true, UNKNOWN_LOCATION);
1052 444 : add_phi_arg (phi, c3, edge_false, UNKNOWN_LOCATION);
1053 444 : phi = create_phi_node (m_data[m_data_cnt + 1], edge_true->dest);
1054 444 : add_phi_arg (phi, c2, edge_true, UNKNOWN_LOCATION);
1055 444 : add_phi_arg (phi, c3, edge_false, UNKNOWN_LOCATION);
1056 : }
1057 : else
1058 : {
1059 : /* Constant with smaller number of bits. Trade conditional
1060 : code for .rodata space by extending from smaller number.
1061 : Version for loops with random access to the limbs or
1062 : downwards loops. */
1063 75 : min_prec = CEIL (min_prec, limb_prec) * limb_prec;
1064 75 : tree c;
1065 75 : if (min_prec <= (unsigned) limb_prec)
1066 21 : c = fold_convert (m_limb_type, op);
1067 : else
1068 : {
1069 54 : tree type = build_bitint_type (min_prec, 1);
1070 54 : c = tree_output_constant_def (fold_convert (type, op));
1071 : }
1072 75 : m_data[m_data_cnt] = c;
1073 75 : m_data[m_data_cnt + 1] = integer_type_node;
1074 : }
1075 5345 : t = m_data[m_data_cnt];
1076 : }
1077 : else
1078 5254 : t = m_data[m_data_cnt + 1];
1079 10599 : if (m_data[m_data_cnt + 1] == NULL_TREE)
1080 : {
1081 4774 : tree ridx = idx;
1082 4774 : unsigned int prec = TYPE_PRECISION (TREE_TYPE (op));
1083 4774 : tree c = m_data[m_data_cnt];
1084 4774 : unsigned int min_prec = TYPE_PRECISION (TREE_TYPE (c));
1085 4774 : if (bitint_big_endian
1086 0 : && CEIL (min_prec, limb_prec) != CEIL (prec, limb_prec))
1087 : {
1088 0 : ridx = make_ssa_name (sizetype);
1089 0 : g = gimple_build_assign (ridx, PLUS_EXPR, idx,
1090 0 : size_int (CEIL (min_prec, limb_prec)
1091 : - ((HOST_WIDE_INT)
1092 : CEIL (prec, limb_prec))));
1093 0 : insert_before (g);
1094 : }
1095 4774 : t = limb_access (TREE_TYPE (op), c, ridx, false);
1096 4774 : g = gimple_build_assign (make_ssa_name (TREE_TYPE (t)), t);
1097 4774 : insert_before (g);
1098 4774 : t = gimple_assign_lhs (g);
1099 : }
1100 5825 : else if (m_data[m_data_cnt + 1] == integer_type_node)
1101 : {
1102 115 : unsigned int prec = TYPE_PRECISION (TREE_TYPE (op));
1103 115 : unsigned rem = prec % ((m_upwards_2limb ? 2 : 1) * limb_prec);
1104 115 : int ext = wi::neg_p (wi::to_wide (op)) ? -1 : 0;
1105 115 : tree c = m_data[m_data_cnt];
1106 115 : unsigned min_prec = TYPE_PRECISION (TREE_TYPE (c));
1107 115 : if (bitint_big_endian)
1108 0 : g = gimple_build_cond (GE_EXPR, idx,
1109 0 : size_int (CEIL (prec, limb_prec)
1110 : - min_prec / limb_prec),
1111 : NULL_TREE, NULL_TREE);
1112 : else
1113 115 : g = gimple_build_cond (LT_EXPR, idx,
1114 115 : size_int (min_prec / limb_prec),
1115 : NULL_TREE, NULL_TREE);
1116 115 : edge edge_true, edge_false;
1117 230 : if_then (g, (min_prec >= (prec - rem) / 2
1118 29 : ? profile_probability::likely ()
1119 86 : : profile_probability::unlikely ()),
1120 : edge_true, edge_false);
1121 115 : if (min_prec > (unsigned) limb_prec)
1122 : {
1123 70 : tree ridx = idx;
1124 70 : if (bitint_big_endian)
1125 : {
1126 0 : ridx = make_ssa_name (sizetype);
1127 0 : g = gimple_build_assign (ridx, PLUS_EXPR, idx,
1128 0 : size_int (min_prec / limb_prec
1129 : - ((HOST_WIDE_INT)
1130 : CEIL (prec,
1131 : limb_prec))));
1132 0 : insert_before (g);
1133 : }
1134 70 : c = limb_access (TREE_TYPE (op), c, ridx, false);
1135 70 : g = gimple_build_assign (make_ssa_name (TREE_TYPE (c)), c);
1136 70 : insert_before (g);
1137 70 : c = gimple_assign_lhs (g);
1138 : }
1139 115 : tree c2 = build_int_cst (m_limb_type, ext);
1140 115 : m_gsi = gsi_after_labels (edge_true->dest);
1141 115 : t = make_ssa_name (m_limb_type);
1142 115 : gphi *phi = create_phi_node (t, edge_true->dest);
1143 115 : add_phi_arg (phi, c, edge_true, UNKNOWN_LOCATION);
1144 115 : add_phi_arg (phi, c2, edge_false, UNKNOWN_LOCATION);
1145 : }
1146 10599 : m_data_cnt += 2;
1147 10599 : return t;
1148 0 : default:
1149 0 : gcc_unreachable ();
1150 : }
1151 : }
1152 :
1153 : /* Helper method, add a PHI node with VAL from preheader edge if
1154 : inside of a loop and m_first. Keep state in a pair of m_data
1155 : elements. If VAL_OUT is non-NULL, use that as PHI argument from
1156 : the latch edge, otherwise create a new SSA_NAME for it and let
1157 : caller initialize it. */
1158 :
1159 : tree
1160 15859 : bitint_large_huge::prepare_data_in_out (tree val, tree idx, tree *data_out,
1161 : tree val_out)
1162 : {
1163 15859 : if (!m_first)
1164 : {
1165 9430 : *data_out = tree_fits_uhwi_p (idx) ? NULL_TREE : m_data[m_data_cnt + 1];
1166 9430 : return m_data[m_data_cnt];
1167 : }
1168 :
1169 6429 : *data_out = NULL_TREE;
1170 6429 : if (tree_fits_uhwi_p (idx))
1171 : {
1172 2006 : m_data.safe_push (val);
1173 2006 : m_data.safe_push (NULL_TREE);
1174 2006 : return val;
1175 : }
1176 :
1177 4423 : tree in = make_ssa_name (TREE_TYPE (val));
1178 4423 : gphi *phi = create_phi_node (in, m_bb);
1179 4423 : edge e1 = find_edge (m_preheader_bb, m_bb);
1180 4423 : edge e2 = EDGE_PRED (m_bb, 0);
1181 4423 : if (e1 == e2)
1182 4423 : e2 = EDGE_PRED (m_bb, 1);
1183 4423 : add_phi_arg (phi, val, e1, UNKNOWN_LOCATION);
1184 4423 : tree out = val_out ? val_out : make_ssa_name (TREE_TYPE (val));
1185 4423 : add_phi_arg (phi, out, e2, UNKNOWN_LOCATION);
1186 4423 : m_data.safe_push (in);
1187 4423 : m_data.safe_push (out);
1188 4423 : return in;
1189 : }
1190 :
1191 : /* Return VAL cast to TYPE. If VAL is INTEGER_CST, just
1192 : convert it without emitting any code, otherwise emit
1193 : the conversion statement before the current location. */
1194 :
1195 : tree
1196 38746 : bitint_large_huge::add_cast (tree type, tree val)
1197 : {
1198 38746 : if (TREE_CODE (val) == INTEGER_CST)
1199 4577 : return fold_convert (type, val);
1200 :
1201 34169 : tree lhs = make_ssa_name (type);
1202 34169 : gimple *g = gimple_build_assign (lhs, NOP_EXPR, val);
1203 34169 : insert_before (g);
1204 34169 : return lhs;
1205 : }
1206 :
1207 : /* Helper of handle_stmt method, handle PLUS_EXPR or MINUS_EXPR. */
1208 :
1209 : tree
1210 13360 : bitint_large_huge::handle_plus_minus (tree_code code, tree rhs1, tree rhs2,
1211 : tree idx)
1212 : {
1213 13360 : tree lhs, data_out, ctype;
1214 13360 : tree rhs1_type = TREE_TYPE (rhs1);
1215 13360 : gimple *g;
1216 13360 : tree data_in = prepare_data_in_out (build_zero_cst (m_limb_type), idx,
1217 : &data_out);
1218 :
1219 19146 : if (optab_handler (code == PLUS_EXPR ? uaddc5_optab : usubc5_optab,
1220 13360 : TYPE_MODE (m_limb_type)) != CODE_FOR_nothing)
1221 : {
1222 13360 : ctype = build_complex_type (m_limb_type);
1223 13360 : if (!types_compatible_p (rhs1_type, m_limb_type))
1224 : {
1225 1073 : if (!TYPE_UNSIGNED (rhs1_type))
1226 : {
1227 360 : tree type = unsigned_type_for (rhs1_type);
1228 360 : rhs1 = add_cast (type, rhs1);
1229 360 : rhs2 = add_cast (type, rhs2);
1230 : }
1231 1073 : rhs1 = add_cast (m_limb_type, rhs1);
1232 1073 : rhs2 = add_cast (m_limb_type, rhs2);
1233 : }
1234 13360 : lhs = make_ssa_name (ctype);
1235 19146 : g = gimple_build_call_internal (code == PLUS_EXPR
1236 : ? IFN_UADDC : IFN_USUBC,
1237 : 3, rhs1, rhs2, data_in);
1238 13360 : gimple_call_set_lhs (g, lhs);
1239 13360 : insert_before (g);
1240 13360 : if (data_out == NULL_TREE)
1241 11141 : data_out = make_ssa_name (m_limb_type);
1242 13360 : g = gimple_build_assign (data_out, IMAGPART_EXPR,
1243 : build1 (IMAGPART_EXPR, m_limb_type, lhs));
1244 13360 : insert_before (g);
1245 : }
1246 0 : else if (types_compatible_p (rhs1_type, m_limb_type))
1247 : {
1248 0 : ctype = build_complex_type (m_limb_type);
1249 0 : lhs = make_ssa_name (ctype);
1250 0 : g = gimple_build_call_internal (code == PLUS_EXPR
1251 : ? IFN_ADD_OVERFLOW : IFN_SUB_OVERFLOW,
1252 : 2, rhs1, rhs2);
1253 0 : gimple_call_set_lhs (g, lhs);
1254 0 : insert_before (g);
1255 0 : if (data_out == NULL_TREE)
1256 0 : data_out = make_ssa_name (m_limb_type);
1257 0 : if (!integer_zerop (data_in))
1258 : {
1259 0 : rhs1 = make_ssa_name (m_limb_type);
1260 0 : g = gimple_build_assign (rhs1, REALPART_EXPR,
1261 : build1 (REALPART_EXPR, m_limb_type, lhs));
1262 0 : insert_before (g);
1263 0 : rhs2 = make_ssa_name (m_limb_type);
1264 0 : g = gimple_build_assign (rhs2, IMAGPART_EXPR,
1265 : build1 (IMAGPART_EXPR, m_limb_type, lhs));
1266 0 : insert_before (g);
1267 0 : lhs = make_ssa_name (ctype);
1268 0 : g = gimple_build_call_internal (code == PLUS_EXPR
1269 : ? IFN_ADD_OVERFLOW
1270 : : IFN_SUB_OVERFLOW,
1271 : 2, rhs1, data_in);
1272 0 : gimple_call_set_lhs (g, lhs);
1273 0 : insert_before (g);
1274 0 : data_in = make_ssa_name (m_limb_type);
1275 0 : g = gimple_build_assign (data_in, IMAGPART_EXPR,
1276 : build1 (IMAGPART_EXPR, m_limb_type, lhs));
1277 0 : insert_before (g);
1278 0 : g = gimple_build_assign (data_out, PLUS_EXPR, rhs2, data_in);
1279 0 : insert_before (g);
1280 : }
1281 : else
1282 : {
1283 0 : g = gimple_build_assign (data_out, IMAGPART_EXPR,
1284 : build1 (IMAGPART_EXPR, m_limb_type, lhs));
1285 0 : insert_before (g);
1286 : }
1287 : }
1288 : else
1289 : {
1290 : /* Always perform the two additions or subtractions in
1291 : unsigned type, avoid introducing a temporary UB. While
1292 : the end result of the 2 additions or 2 subtractions in
1293 : a valid program should not overflow, temporarily it can.
1294 : See PR126503. */
1295 0 : tree utype = unsigned_type_for (rhs1_type);
1296 0 : tree in = add_cast (utype, data_in);
1297 0 : lhs = make_ssa_name (utype);
1298 0 : if (utype != rhs1_type)
1299 : {
1300 0 : rhs1 = add_cast (utype, rhs1);
1301 0 : rhs2 = add_cast (utype, rhs2);
1302 : }
1303 0 : g = gimple_build_assign (lhs, code, rhs1, rhs2);
1304 0 : insert_before (g);
1305 0 : rhs1 = make_ssa_name (utype);
1306 0 : g = gimple_build_assign (rhs1, code, lhs, in);
1307 0 : insert_before (g);
1308 0 : m_data[m_data_cnt] = NULL_TREE;
1309 0 : m_data_cnt += 2;
1310 0 : return utype != rhs1_type ? add_cast (rhs1_type, rhs1) : rhs1;
1311 : }
1312 13360 : rhs1 = make_ssa_name (m_limb_type);
1313 13360 : g = gimple_build_assign (rhs1, REALPART_EXPR,
1314 : build1 (REALPART_EXPR, m_limb_type, lhs));
1315 13360 : insert_before (g);
1316 13360 : if (!types_compatible_p (rhs1_type, m_limb_type))
1317 1073 : rhs1 = add_cast (rhs1_type, rhs1);
1318 13360 : m_data[m_data_cnt] = data_out;
1319 13360 : m_data_cnt += 2;
1320 13360 : return rhs1;
1321 : }
1322 :
1323 : /* Helper function for handle_stmt method, handle LSHIFT_EXPR by
1324 : count in [0, limb_prec - 1] range. */
1325 :
1326 : tree
1327 152 : bitint_large_huge::handle_lshift (tree rhs1, tree rhs2, tree idx)
1328 : {
1329 152 : unsigned HOST_WIDE_INT cnt = tree_to_uhwi (rhs2);
1330 152 : gcc_checking_assert (cnt < (unsigned) limb_prec);
1331 152 : if (cnt == 0)
1332 : return rhs1;
1333 :
1334 152 : tree lhs, data_out, rhs1_type = TREE_TYPE (rhs1);
1335 152 : gimple *g;
1336 152 : tree data_in = prepare_data_in_out (build_zero_cst (m_limb_type), idx,
1337 : &data_out);
1338 :
1339 152 : if (!integer_zerop (data_in))
1340 : {
1341 136 : lhs = make_ssa_name (m_limb_type);
1342 136 : g = gimple_build_assign (lhs, RSHIFT_EXPR, data_in,
1343 : build_int_cst (unsigned_type_node,
1344 136 : limb_prec - cnt));
1345 136 : insert_before (g);
1346 136 : if (!types_compatible_p (rhs1_type, m_limb_type))
1347 35 : lhs = add_cast (rhs1_type, lhs);
1348 : data_in = lhs;
1349 : }
1350 152 : if (types_compatible_p (rhs1_type, m_limb_type))
1351 : {
1352 117 : if (data_out == NULL_TREE)
1353 82 : data_out = make_ssa_name (m_limb_type);
1354 117 : g = gimple_build_assign (data_out, rhs1);
1355 117 : insert_before (g);
1356 : }
1357 152 : if (cnt < (unsigned) TYPE_PRECISION (rhs1_type))
1358 : {
1359 137 : lhs = make_ssa_name (rhs1_type);
1360 137 : g = gimple_build_assign (lhs, LSHIFT_EXPR, rhs1, rhs2);
1361 137 : insert_before (g);
1362 137 : if (!integer_zerop (data_in))
1363 : {
1364 121 : rhs1 = lhs;
1365 121 : lhs = make_ssa_name (rhs1_type);
1366 121 : g = gimple_build_assign (lhs, BIT_IOR_EXPR, rhs1, data_in);
1367 121 : insert_before (g);
1368 : }
1369 : }
1370 : else
1371 : lhs = data_in;
1372 152 : m_data[m_data_cnt] = data_out;
1373 152 : m_data_cnt += 2;
1374 152 : return lhs;
1375 : }
1376 :
1377 : /* Helper function for handle_stmt method, handle an integral
1378 : to integral conversion. */
1379 :
1380 : tree
1381 7561 : bitint_large_huge::handle_cast (tree lhs_type, tree rhs1, tree idx)
1382 : {
1383 7561 : tree rhs_type = TREE_TYPE (rhs1);
1384 7561 : gimple *g;
1385 7561 : if ((TREE_CODE (rhs1) == SSA_NAME || TREE_CODE (rhs1) == INTEGER_CST)
1386 7561 : && BITINT_TYPE_P (lhs_type)
1387 7561 : && BITINT_TYPE_P (rhs_type)
1388 6568 : && bitint_precision_kind (lhs_type) >= bitint_prec_large
1389 14129 : && bitint_precision_kind (rhs_type) >= bitint_prec_large)
1390 : {
1391 5929 : if (TYPE_PRECISION (rhs_type) >= TYPE_PRECISION (lhs_type)
1392 : /* If lhs has bigger precision than rhs, we can use
1393 : the simple case only if there is a guarantee that
1394 : the most significant limb is handled in straight
1395 : line code. If m_var_msb (on left shifts) or
1396 : if m_upwards_2limb * limb_prec is equal to
1397 : lhs precision or if not m_upwards_2limb and lhs_type
1398 : has precision which is multiple of limb_prec that is
1399 : not the case. */
1400 5929 : || (!m_var_msb
1401 1524 : && (CEIL (TYPE_PRECISION (lhs_type), limb_prec)
1402 1524 : == CEIL (TYPE_PRECISION (rhs_type), limb_prec))
1403 370 : && ((!m_upwards_2limb
1404 182 : && (TYPE_PRECISION (lhs_type) % limb_prec != 0))
1405 267 : || (m_upwards_2limb
1406 376 : && (m_upwards_2limb * limb_prec
1407 188 : < TYPE_PRECISION (lhs_type))))))
1408 : {
1409 4670 : tree ridx = idx;
1410 4670 : if (bitint_big_endian
1411 4670 : && (CEIL (TYPE_PRECISION (lhs_type), limb_prec)
1412 0 : != CEIL (TYPE_PRECISION (rhs_type), limb_prec)))
1413 : {
1414 0 : HOST_WIDE_INT diff = CEIL (TYPE_PRECISION (rhs_type), limb_prec);
1415 0 : diff -= CEIL (TYPE_PRECISION (lhs_type), limb_prec);
1416 0 : if (tree_fits_uhwi_p (idx))
1417 0 : ridx = size_int (tree_to_uhwi (idx) + diff);
1418 : else
1419 : {
1420 0 : tree t = make_ssa_name (sizetype);
1421 0 : g = gimple_build_assign (t, PLUS_EXPR, idx, size_int (diff));
1422 0 : insert_before (g);
1423 0 : ridx = t;
1424 : }
1425 : }
1426 4670 : rhs1 = handle_operand (rhs1, ridx);
1427 4670 : if (tree_fits_uhwi_p (idx))
1428 : {
1429 2389 : tree type = limb_access_type (lhs_type, idx);
1430 2389 : if (!types_compatible_p (type, TREE_TYPE (rhs1)))
1431 1250 : rhs1 = add_cast (type, rhs1);
1432 : }
1433 : return rhs1;
1434 : }
1435 1259 : tree t;
1436 : /* Indexes lower than this don't need any special processing. */
1437 1259 : unsigned low = ((unsigned) TYPE_PRECISION (rhs_type)
1438 1259 : - !TYPE_UNSIGNED (rhs_type)) / limb_prec;
1439 : /* Indexes >= than this always contain an extension. */
1440 1259 : unsigned high = CEIL ((unsigned) TYPE_PRECISION (rhs_type), limb_prec);
1441 1259 : unsigned lcnt = CEIL ((unsigned) TYPE_PRECISION (lhs_type), limb_prec);
1442 1259 : unsigned lowe = bitint_big_endian ? lcnt - 1 - low : low;
1443 1259 : bool save_first = m_first;
1444 1259 : if (m_first)
1445 : {
1446 414 : m_data.safe_push (NULL_TREE);
1447 414 : m_data.safe_push (NULL_TREE);
1448 414 : m_data.safe_push (NULL_TREE);
1449 414 : if (TYPE_UNSIGNED (rhs_type))
1450 : /* No need to keep state between iterations. */
1451 : ;
1452 193 : else if (m_upwards && !m_upwards_2limb)
1453 : /* We need to keep state between iterations, but
1454 : not within any loop, everything is straight line
1455 : code with only increasing indexes. */
1456 : ;
1457 153 : else if (!m_upwards_2limb)
1458 : {
1459 3 : unsigned save_data_cnt = m_data_cnt;
1460 3 : gimple_stmt_iterator save_gsi = m_gsi;
1461 3 : m_gsi = m_init_gsi;
1462 3 : if (gsi_end_p (m_gsi))
1463 0 : m_gsi = gsi_after_labels (gsi_bb (m_gsi));
1464 : else
1465 3 : gsi_next (&m_gsi);
1466 3 : m_data_cnt = save_data_cnt + 3;
1467 3 : t = handle_operand (rhs1, size_int (bitint_big_endian
1468 : ? high - 1 - low : low));
1469 3 : m_first = false;
1470 3 : m_data[save_data_cnt + 2]
1471 3 : = build_int_cst (integer_type_node, m_data_cnt);
1472 3 : m_data_cnt = save_data_cnt;
1473 3 : t = add_cast (signed_type_for (m_limb_type), t);
1474 3 : tree lpm1 = build_int_cst (unsigned_type_node, limb_prec - 1);
1475 3 : tree n = make_ssa_name (TREE_TYPE (t));
1476 3 : g = gimple_build_assign (n, RSHIFT_EXPR, t, lpm1);
1477 3 : insert_before (g);
1478 3 : m_data[save_data_cnt + 1] = add_cast (m_limb_type, n);
1479 3 : m_init_gsi = m_gsi;
1480 3 : if (gsi_end_p (m_init_gsi))
1481 0 : m_init_gsi = gsi_last_bb (gsi_bb (m_init_gsi));
1482 : else
1483 3 : gsi_prev (&m_init_gsi);
1484 3 : m_gsi = save_gsi;
1485 : }
1486 150 : else if (m_upwards_2limb * limb_prec < TYPE_PRECISION (rhs_type))
1487 : /* We need to keep state between iterations, but
1488 : fortunately not within the loop, only afterwards. */
1489 : ;
1490 : else
1491 : {
1492 146 : tree out;
1493 146 : m_data.truncate (m_data_cnt);
1494 146 : prepare_data_in_out (build_zero_cst (m_limb_type), idx, &out);
1495 146 : m_data.safe_push (NULL_TREE);
1496 : }
1497 : }
1498 :
1499 1259 : unsigned save_data_cnt = m_data_cnt;
1500 1259 : m_data_cnt += 3;
1501 1259 : if (!tree_fits_uhwi_p (idx))
1502 : {
1503 688 : if (m_upwards_2limb
1504 668 : && low >= m_upwards_2limb - m_first)
1505 : {
1506 158 : if (bitint_big_endian
1507 158 : && (CEIL (TYPE_PRECISION (lhs_type), limb_prec)
1508 0 : != CEIL (TYPE_PRECISION (rhs_type), limb_prec)))
1509 : {
1510 0 : HOST_WIDE_INT diff
1511 0 : = CEIL (TYPE_PRECISION (rhs_type), limb_prec);
1512 0 : diff -= CEIL (TYPE_PRECISION (lhs_type), limb_prec);
1513 0 : tree t = make_ssa_name (sizetype);
1514 0 : g = gimple_build_assign (t, PLUS_EXPR, idx, size_int (diff));
1515 0 : insert_before (g);
1516 0 : idx = t;
1517 : }
1518 158 : rhs1 = handle_operand (rhs1, idx);
1519 158 : if (m_first)
1520 131 : m_data[save_data_cnt + 2]
1521 262 : = build_int_cst (integer_type_node, m_data_cnt);
1522 158 : m_first = save_first;
1523 158 : return rhs1;
1524 : }
1525 1326 : bool single_comparison
1526 530 : = low == high || (m_upwards_2limb && (low & 1) == m_first);
1527 266 : tree idxc = idx;
1528 266 : if (!single_comparison
1529 266 : && m_upwards_2limb
1530 246 : && !m_first
1531 112 : && low + 1 == m_upwards_2limb)
1532 : /* In this case we know that idx <= low always,
1533 : so effectively we just needs a single comparison,
1534 : idx < low or idx == low, but we'd need to emit different
1535 : code for the 2 branches than single_comparison normally
1536 : emits. So, instead of special-casing that, emit a
1537 : low <= low comparison which cfg cleanup will clean up
1538 : at the end of the pass. */
1539 89 : idxc = size_int (lowe);
1540 530 : if (bitint_big_endian)
1541 0 : g = gimple_build_cond (single_comparison ? GT_EXPR : GE_EXPR,
1542 0 : idxc, size_int (lowe),
1543 : NULL_TREE, NULL_TREE);
1544 : else
1545 796 : g = gimple_build_cond (single_comparison ? LT_EXPR : LE_EXPR,
1546 530 : idxc, size_int (low), NULL_TREE, NULL_TREE);
1547 530 : edge edge_true_true, edge_true_false, edge_false;
1548 796 : if_then_if_then_else (g, (single_comparison ? NULL
1549 266 : : gimple_build_cond (EQ_EXPR, idx,
1550 266 : size_int (lowe),
1551 : NULL_TREE,
1552 : NULL_TREE)),
1553 : profile_probability::likely (),
1554 : profile_probability::unlikely (),
1555 : edge_true_true, edge_true_false, edge_false);
1556 530 : bool save_cast_conditional = m_cast_conditional;
1557 530 : m_cast_conditional = true;
1558 530 : m_bitfld_load = 0;
1559 530 : tree t1 = idx, t2 = NULL_TREE;
1560 530 : if (bitint_big_endian
1561 530 : && (CEIL (TYPE_PRECISION (lhs_type), limb_prec)
1562 0 : != CEIL (TYPE_PRECISION (rhs_type), limb_prec)))
1563 : {
1564 0 : HOST_WIDE_INT diff = CEIL (TYPE_PRECISION (rhs_type), limb_prec);
1565 0 : diff -= CEIL (TYPE_PRECISION (lhs_type), limb_prec);
1566 0 : t1 = make_ssa_name (sizetype);
1567 0 : g = gimple_build_assign (t1, PLUS_EXPR, idx, size_int (diff));
1568 0 : insert_before (g);
1569 : }
1570 530 : t1 = handle_operand (rhs1, t1);
1571 530 : if (m_first)
1572 208 : m_data[save_data_cnt + 2]
1573 416 : = build_int_cst (integer_type_node, m_data_cnt);
1574 530 : tree ext = NULL_TREE;
1575 530 : tree bitfld = NULL_TREE;
1576 530 : if (!single_comparison)
1577 : {
1578 266 : m_gsi = gsi_after_labels (edge_true_true->src);
1579 266 : m_first = false;
1580 266 : m_data_cnt = save_data_cnt + 3;
1581 266 : if (m_bitfld_load)
1582 : {
1583 4 : bitfld = m_data[m_bitfld_load];
1584 4 : m_data[m_bitfld_load] = m_data[m_bitfld_load + 2];
1585 4 : m_bitfld_load = 0;
1586 : }
1587 266 : t2 = handle_operand (rhs1, size_int (bitint_big_endian
1588 : ? high - 1 - low : low));
1589 266 : if (!useless_type_conversion_p (m_limb_type, TREE_TYPE (t2)))
1590 221 : t2 = add_cast (m_limb_type, t2);
1591 266 : if (!TYPE_UNSIGNED (rhs_type) && m_upwards_2limb)
1592 : {
1593 146 : ext = add_cast (signed_type_for (m_limb_type), t2);
1594 292 : tree lpm1 = build_int_cst (unsigned_type_node,
1595 146 : limb_prec - 1);
1596 146 : tree n = make_ssa_name (TREE_TYPE (ext));
1597 146 : g = gimple_build_assign (n, RSHIFT_EXPR, ext, lpm1);
1598 146 : insert_before (g);
1599 146 : ext = add_cast (m_limb_type, n);
1600 : }
1601 : }
1602 530 : tree t3;
1603 530 : if (TYPE_UNSIGNED (rhs_type))
1604 278 : t3 = build_zero_cst (m_limb_type);
1605 252 : else if (m_upwards_2limb && (save_first || ext != NULL_TREE))
1606 168 : t3 = m_data[save_data_cnt];
1607 : else
1608 84 : t3 = m_data[save_data_cnt + 1];
1609 530 : m_gsi = gsi_after_labels (edge_true_false->dest);
1610 530 : t = make_ssa_name (m_limb_type);
1611 530 : gphi *phi = create_phi_node (t, edge_true_false->dest);
1612 530 : add_phi_arg (phi, t1, edge_true_false, UNKNOWN_LOCATION);
1613 530 : add_phi_arg (phi, t3, edge_false, UNKNOWN_LOCATION);
1614 530 : if (edge_true_true)
1615 266 : add_phi_arg (phi, t2, edge_true_true, UNKNOWN_LOCATION);
1616 530 : if (ext)
1617 : {
1618 146 : tree t4 = make_ssa_name (m_limb_type);
1619 146 : phi = create_phi_node (t4, edge_true_false->dest);
1620 146 : add_phi_arg (phi, build_zero_cst (m_limb_type), edge_true_false,
1621 : UNKNOWN_LOCATION);
1622 146 : add_phi_arg (phi, m_data[save_data_cnt], edge_false,
1623 : UNKNOWN_LOCATION);
1624 146 : add_phi_arg (phi, ext, edge_true_true, UNKNOWN_LOCATION);
1625 146 : if (!save_cast_conditional)
1626 : {
1627 136 : g = gimple_build_assign (m_data[save_data_cnt + 1], t4);
1628 136 : insert_before (g);
1629 : }
1630 : else
1631 10 : for (basic_block bb = gsi_bb (m_gsi);;)
1632 : {
1633 10 : edge e1 = single_succ_edge (bb);
1634 10 : edge e2 = find_edge (e1->dest, m_bb), e3;
1635 10 : tree t5 = (e2 ? m_data[save_data_cnt + 1]
1636 10 : : make_ssa_name (m_limb_type));
1637 10 : phi = create_phi_node (t5, e1->dest);
1638 10 : edge_iterator ei;
1639 30 : FOR_EACH_EDGE (e3, ei, e1->dest->preds)
1640 30 : add_phi_arg (phi, (e3 == e1 ? t4
1641 10 : : build_zero_cst (m_limb_type)),
1642 : e3, UNKNOWN_LOCATION);
1643 10 : if (e2)
1644 : break;
1645 0 : t4 = t5;
1646 0 : bb = e1->dest;
1647 0 : }
1648 : }
1649 530 : if (m_bitfld_load)
1650 : {
1651 8 : tree t4;
1652 8 : if (!save_first && !save_cast_conditional)
1653 2 : t4 = m_data[m_bitfld_load + 1];
1654 : else
1655 6 : t4 = make_ssa_name (m_limb_type);
1656 8 : phi = create_phi_node (t4, edge_true_false->dest);
1657 12 : add_phi_arg (phi,
1658 4 : edge_true_true ? bitfld : m_data[m_bitfld_load],
1659 : edge_true_false, UNKNOWN_LOCATION);
1660 8 : add_phi_arg (phi, m_data[m_bitfld_load + 2],
1661 : edge_false, UNKNOWN_LOCATION);
1662 8 : if (edge_true_true)
1663 4 : add_phi_arg (phi, m_data[m_bitfld_load], edge_true_true,
1664 : UNKNOWN_LOCATION);
1665 8 : if (save_cast_conditional)
1666 4 : for (basic_block bb = gsi_bb (m_gsi);;)
1667 : {
1668 4 : edge e1 = single_succ_edge (bb);
1669 4 : edge e2 = find_edge (e1->dest, m_bb), e3;
1670 4 : tree t5 = ((e2 && !save_first) ? m_data[m_bitfld_load + 1]
1671 4 : : make_ssa_name (m_limb_type));
1672 4 : phi = create_phi_node (t5, e1->dest);
1673 4 : edge_iterator ei;
1674 14 : FOR_EACH_EDGE (e3, ei, e1->dest->preds)
1675 16 : add_phi_arg (phi, (e3 == e1 ? t4
1676 6 : : build_zero_cst (m_limb_type)),
1677 : e3, UNKNOWN_LOCATION);
1678 4 : t4 = t5;
1679 4 : if (e2)
1680 : break;
1681 0 : bb = e1->dest;
1682 0 : }
1683 8 : m_data[m_bitfld_load] = t4;
1684 8 : m_data[m_bitfld_load + 2] = t4;
1685 8 : m_bitfld_load = 0;
1686 : }
1687 530 : m_cast_conditional = save_cast_conditional;
1688 530 : m_first = save_first;
1689 530 : return t;
1690 : }
1691 : else
1692 : {
1693 571 : unsigned tidx = tree_to_uhwi (idx);
1694 571 : if (bitint_big_endian)
1695 0 : tidx = lcnt - 1 - tidx;
1696 571 : if (tidx < low)
1697 : {
1698 152 : t = handle_operand (rhs1, (bitint_big_endian
1699 0 : ? size_int (high - 1 - tidx) : idx));
1700 152 : if (m_first)
1701 71 : m_data[save_data_cnt + 2]
1702 142 : = build_int_cst (integer_type_node, m_data_cnt);
1703 : }
1704 419 : else if (tidx < high)
1705 : {
1706 68 : t = handle_operand (rhs1, size_int (bitint_big_endian
1707 : ? high - 1 - low : low));
1708 68 : if (m_first)
1709 1 : m_data[save_data_cnt + 2]
1710 2 : = build_int_cst (integer_type_node, m_data_cnt);
1711 68 : if (!useless_type_conversion_p (m_limb_type, TREE_TYPE (t)))
1712 60 : t = add_cast (m_limb_type, t);
1713 68 : tree ext = NULL_TREE;
1714 68 : if (!TYPE_UNSIGNED (rhs_type) && m_upwards)
1715 : {
1716 44 : ext = add_cast (signed_type_for (m_limb_type), t);
1717 88 : tree lpm1 = build_int_cst (unsigned_type_node,
1718 44 : limb_prec - 1);
1719 44 : tree n = make_ssa_name (TREE_TYPE (ext));
1720 44 : g = gimple_build_assign (n, RSHIFT_EXPR, ext, lpm1);
1721 44 : insert_before (g);
1722 44 : ext = add_cast (m_limb_type, n);
1723 44 : m_data[save_data_cnt + 1] = ext;
1724 : }
1725 : }
1726 : else
1727 : {
1728 351 : if (TYPE_UNSIGNED (rhs_type) && m_first)
1729 : {
1730 0 : handle_operand (rhs1, (bitint_big_endian
1731 0 : ? size_int (high - 1)
1732 : : size_zero_node));
1733 0 : m_data[save_data_cnt + 2]
1734 0 : = build_int_cst (integer_type_node, m_data_cnt);
1735 : }
1736 : else
1737 351 : m_data_cnt = tree_to_uhwi (m_data[save_data_cnt + 2]);
1738 351 : if (TYPE_UNSIGNED (rhs_type))
1739 184 : t = build_zero_cst (m_limb_type);
1740 167 : else if (m_bb
1741 16 : && m_data[save_data_cnt]
1742 180 : && ((tidx & 1) == 0 || tidx != low + 1))
1743 : t = m_data[save_data_cnt];
1744 : else
1745 161 : t = m_data[save_data_cnt + 1];
1746 : }
1747 571 : tree type = limb_access_type (lhs_type, idx);
1748 571 : if (!useless_type_conversion_p (type, m_limb_type))
1749 292 : t = add_cast (type, t);
1750 571 : m_first = save_first;
1751 571 : return t;
1752 : }
1753 : }
1754 0 : else if (BITINT_TYPE_P (lhs_type)
1755 1632 : && bitint_precision_kind (lhs_type) >= bitint_prec_large
1756 3264 : && INTEGRAL_TYPE_P (rhs_type))
1757 : {
1758 : /* Add support for 3 or more limbs filled in from normal integral
1759 : type if this assert fails. If no target chooses limb mode smaller
1760 : than half of largest supported normal integral type, this will not
1761 : be needed. */
1762 1632 : gcc_assert (TYPE_PRECISION (rhs_type) <= 2 * limb_prec);
1763 1632 : tree r1 = NULL_TREE, r2 = NULL_TREE, rext = NULL_TREE;
1764 1632 : if (m_first)
1765 : {
1766 594 : gimple_stmt_iterator save_gsi = m_gsi;
1767 594 : m_gsi = m_init_gsi;
1768 594 : if (gsi_end_p (m_gsi))
1769 58 : m_gsi = gsi_after_labels (gsi_bb (m_gsi));
1770 : else
1771 536 : gsi_next (&m_gsi);
1772 375 : if (BITINT_TYPE_P (rhs_type)
1773 594 : && bitint_precision_kind (rhs_type) == bitint_prec_middle)
1774 : {
1775 63 : tree type = NULL_TREE;
1776 63 : rhs1 = maybe_cast_middle_bitint (&m_gsi, rhs1, type);
1777 63 : rhs_type = TREE_TYPE (rhs1);
1778 : }
1779 594 : r1 = rhs1;
1780 594 : if (!useless_type_conversion_p (m_limb_type, TREE_TYPE (rhs1)))
1781 526 : r1 = add_cast (m_limb_type, rhs1);
1782 594 : if (TYPE_PRECISION (rhs_type) > limb_prec)
1783 : {
1784 109 : g = gimple_build_assign (make_ssa_name (rhs_type),
1785 : RSHIFT_EXPR, rhs1,
1786 : build_int_cst (unsigned_type_node,
1787 109 : limb_prec));
1788 109 : insert_before (g);
1789 109 : r2 = add_cast (m_limb_type, gimple_assign_lhs (g));
1790 : }
1791 594 : if (TYPE_UNSIGNED (rhs_type))
1792 287 : rext = build_zero_cst (m_limb_type);
1793 : else
1794 : {
1795 307 : rext = add_cast (signed_type_for (m_limb_type), r2 ? r2 : r1);
1796 307 : g = gimple_build_assign (make_ssa_name (TREE_TYPE (rext)),
1797 : RSHIFT_EXPR, rext,
1798 : build_int_cst (unsigned_type_node,
1799 307 : limb_prec - 1));
1800 307 : insert_before (g);
1801 307 : rext = add_cast (m_limb_type, gimple_assign_lhs (g));
1802 : }
1803 594 : m_init_gsi = m_gsi;
1804 594 : if (gsi_end_p (m_init_gsi))
1805 598 : m_init_gsi = gsi_last_bb (gsi_bb (m_init_gsi));
1806 : else
1807 295 : gsi_prev (&m_init_gsi);
1808 594 : m_gsi = save_gsi;
1809 : }
1810 1632 : tree t;
1811 1632 : if (m_upwards_2limb)
1812 : {
1813 776 : if (m_first)
1814 : {
1815 297 : tree out1, out2;
1816 297 : prepare_data_in_out (r1, idx, &out1, rext);
1817 297 : if (TYPE_PRECISION (rhs_type) > limb_prec)
1818 : {
1819 70 : prepare_data_in_out (r2, idx, &out2, rext);
1820 70 : m_data.pop ();
1821 70 : t = m_data.pop ();
1822 70 : m_data[m_data_cnt + 1] = t;
1823 : }
1824 : else
1825 227 : m_data[m_data_cnt + 1] = rext;
1826 297 : m_data.safe_push (rext);
1827 297 : t = m_data[m_data_cnt];
1828 : }
1829 479 : else if (!tree_fits_uhwi_p (idx))
1830 297 : t = m_data[m_data_cnt + 1];
1831 : else
1832 : {
1833 182 : tree type = limb_access_type (lhs_type, idx);
1834 182 : t = m_data[m_data_cnt + 2];
1835 182 : if (!useless_type_conversion_p (type, m_limb_type))
1836 153 : t = add_cast (type, t);
1837 : }
1838 776 : m_data_cnt += 3;
1839 776 : return t;
1840 : }
1841 856 : else if (m_first)
1842 : {
1843 297 : m_data.safe_push (r1);
1844 297 : m_data.safe_push (r2);
1845 297 : m_data.safe_push (rext);
1846 : }
1847 856 : unsigned lcnt = CEIL ((unsigned) TYPE_PRECISION (lhs_type), limb_prec);
1848 856 : if (tree_fits_uhwi_p (idx))
1849 : {
1850 812 : tree type = limb_access_type (lhs_type, idx);
1851 812 : if (bitint_big_endian
1852 812 : ? tree_to_uhwi (idx) == lcnt - 1 : integer_zerop (idx))
1853 269 : t = m_data[m_data_cnt];
1854 543 : else if (TYPE_PRECISION (rhs_type) > limb_prec
1855 543 : && (bitint_big_endian
1856 72 : ? tree_to_uhwi (idx) == lcnt - 2
1857 72 : : integer_onep (idx)))
1858 33 : t = m_data[m_data_cnt + 1];
1859 : else
1860 510 : t = m_data[m_data_cnt + 2];
1861 812 : if (!useless_type_conversion_p (type, m_limb_type))
1862 250 : t = add_cast (type, t);
1863 812 : m_data_cnt += 3;
1864 812 : return t;
1865 : }
1866 44 : g = gimple_build_cond (NE_EXPR, idx,
1867 : bitint_big_endian
1868 0 : ? size_int (lcnt - 1) : size_zero_node,
1869 : NULL_TREE, NULL_TREE);
1870 44 : edge e2, e3, e4 = NULL;
1871 44 : if_then (g, profile_probability::likely (), e2, e3);
1872 44 : if (m_data[m_data_cnt + 1])
1873 : {
1874 14 : g = gimple_build_cond (EQ_EXPR, idx,
1875 : bitint_big_endian
1876 0 : ? size_int (lcnt - 2) : size_one_node,
1877 : NULL_TREE, NULL_TREE);
1878 14 : insert_before (g);
1879 14 : edge e5 = split_block (gsi_bb (m_gsi), g);
1880 14 : e4 = make_edge (e5->src, e2->dest, EDGE_TRUE_VALUE);
1881 14 : e2 = find_edge (e5->dest, e2->dest);
1882 14 : e4->probability = profile_probability::unlikely ();
1883 14 : e5->flags = EDGE_FALSE_VALUE;
1884 14 : e5->probability = e4->probability.invert ();
1885 : }
1886 44 : m_gsi = gsi_after_labels (e2->dest);
1887 44 : t = make_ssa_name (m_limb_type);
1888 44 : gphi *phi = create_phi_node (t, e2->dest);
1889 44 : add_phi_arg (phi, m_data[m_data_cnt + 2], e2, UNKNOWN_LOCATION);
1890 44 : add_phi_arg (phi, m_data[m_data_cnt], e3, UNKNOWN_LOCATION);
1891 44 : if (e4)
1892 14 : add_phi_arg (phi, m_data[m_data_cnt + 1], e4, UNKNOWN_LOCATION);
1893 44 : m_data_cnt += 3;
1894 44 : return t;
1895 : }
1896 : return NULL_TREE;
1897 : }
1898 :
1899 : /* Helper function for handle_stmt method, handle a BIT_FIELD_REF. */
1900 :
1901 : tree
1902 23 : bitint_large_huge::handle_bit_field_ref (tree op, tree idx)
1903 : {
1904 23 : if (tree_fits_uhwi_p (idx))
1905 : {
1906 13 : if (m_first)
1907 4 : m_data.safe_push (NULL);
1908 13 : ++m_data_cnt;
1909 13 : unsigned HOST_WIDE_INT sz = tree_to_uhwi (TYPE_SIZE (m_limb_type));
1910 13 : unsigned i = tree_to_uhwi (idx);
1911 13 : if (bitint_big_endian)
1912 0 : i = CEIL (TYPE_PRECISION (TREE_TYPE (op)), limb_prec) - 1 - i;
1913 26 : tree bfr = build3 (BIT_FIELD_REF, m_limb_type,
1914 13 : TREE_OPERAND (op, 0),
1915 13 : TYPE_SIZE (m_limb_type),
1916 13 : size_binop (PLUS_EXPR, TREE_OPERAND (op, 2),
1917 : bitsize_int (i * sz)));
1918 13 : tree r = make_ssa_name (m_limb_type);
1919 13 : gimple *g = gimple_build_assign (r, bfr);
1920 13 : insert_before (g);
1921 13 : tree type = limb_access_type (TREE_TYPE (op), idx);
1922 13 : if (!useless_type_conversion_p (type, m_limb_type))
1923 0 : r = add_cast (type, r);
1924 : return r;
1925 : }
1926 10 : tree var;
1927 10 : if (m_first)
1928 : {
1929 5 : unsigned HOST_WIDE_INT sz = tree_to_uhwi (TYPE_SIZE (TREE_TYPE (op)));
1930 5 : machine_mode mode;
1931 5 : tree type, bfr;
1932 5 : if (bitwise_mode_for_size (sz).exists (&mode)
1933 0 : && known_eq (GET_MODE_BITSIZE (mode), sz))
1934 0 : type = bitwise_type_for_mode (mode);
1935 : else
1936 : {
1937 5 : mode = VOIDmode;
1938 5 : type = TYPE_MAIN_VARIANT (TREE_TYPE (TREE_OPERAND (op, 0)));
1939 : }
1940 5 : if (TYPE_ALIGN (type) < TYPE_ALIGN (TREE_TYPE (op)))
1941 0 : type = build_aligned_type (type, TYPE_ALIGN (TREE_TYPE (op)));
1942 5 : var = create_tmp_var (type);
1943 5 : TREE_ADDRESSABLE (var) = 1;
1944 5 : gimple *g;
1945 5 : if (mode != VOIDmode)
1946 : {
1947 0 : bfr = build3 (BIT_FIELD_REF, type, TREE_OPERAND (op, 0),
1948 0 : TYPE_SIZE (type), TREE_OPERAND (op, 2));
1949 0 : g = gimple_build_assign (make_ssa_name (type),
1950 : BIT_FIELD_REF, bfr);
1951 0 : gimple_set_location (g, m_loc);
1952 0 : gsi_insert_after (&m_init_gsi, g, GSI_NEW_STMT);
1953 0 : bfr = gimple_assign_lhs (g);
1954 : }
1955 : else
1956 5 : bfr = TREE_OPERAND (op, 0);
1957 5 : g = gimple_build_assign (var, bfr);
1958 5 : gimple_set_location (g, m_loc);
1959 5 : gsi_insert_after (&m_init_gsi, g, GSI_NEW_STMT);
1960 5 : if (mode == VOIDmode)
1961 : {
1962 5 : unsigned HOST_WIDE_INT nelts
1963 5 : = CEIL (tree_to_uhwi (TYPE_SIZE (TREE_TYPE (op))), limb_prec);
1964 5 : tree atype = build_array_type_nelts (m_limb_type, nelts);
1965 5 : var = build2 (MEM_REF, atype, build_fold_addr_expr (var),
1966 : build_int_cst (build_pointer_type (type),
1967 5 : tree_to_uhwi (TREE_OPERAND (op, 2))
1968 5 : / BITS_PER_UNIT));
1969 : }
1970 5 : m_data.safe_push (var);
1971 : }
1972 : else
1973 5 : var = unshare_expr (m_data[m_data_cnt]);
1974 10 : ++m_data_cnt;
1975 10 : var = limb_access (TREE_TYPE (op), var, idx, false);
1976 10 : tree r = make_ssa_name (m_limb_type);
1977 10 : gimple *g = gimple_build_assign (r, var);
1978 10 : insert_before (g);
1979 10 : return r;
1980 : }
1981 :
1982 : /* Add a new EH edge from SRC to EH_EDGE->dest, where EH_EDGE
1983 : is an older EH edge, and except for virtual PHIs duplicate the
1984 : PHI argument from the EH_EDGE to the new EH edge. */
1985 :
1986 : static void
1987 20 : add_eh_edge (basic_block src, edge eh_edge)
1988 : {
1989 20 : edge e = make_edge (src, eh_edge->dest, EDGE_EH);
1990 20 : e->probability = profile_probability::very_unlikely ();
1991 20 : for (gphi_iterator gsi = gsi_start_phis (eh_edge->dest);
1992 27 : !gsi_end_p (gsi); gsi_next (&gsi))
1993 : {
1994 7 : gphi *phi = gsi.phi ();
1995 7 : tree lhs = gimple_phi_result (phi);
1996 14 : if (virtual_operand_p (lhs))
1997 4 : continue;
1998 3 : const phi_arg_d *arg = gimple_phi_arg (phi, eh_edge->dest_idx);
1999 3 : add_phi_arg (phi, arg->def, e, arg->locus);
2000 : }
2001 20 : }
2002 :
2003 : /* Helper function for handle_stmt method, handle a load from memory. */
2004 :
2005 : tree
2006 21362 : bitint_large_huge::handle_load (gimple *stmt, tree idx)
2007 : {
2008 21362 : tree rhs1 = gimple_assign_rhs1 (stmt);
2009 21362 : tree rhs_type = TREE_TYPE (rhs1);
2010 21362 : bool eh = stmt_ends_bb_p (stmt);
2011 21362 : bool load_bitfield_p = false;
2012 21362 : edge eh_edge = NULL;
2013 21362 : gimple *g;
2014 :
2015 21362 : if (TREE_CODE (rhs1) == BIT_FIELD_REF
2016 21362 : && integer_zerop (TREE_OPERAND (rhs1, 2)))
2017 2 : rhs1 = TREE_OPERAND (rhs1, 0);
2018 :
2019 21362 : if (eh)
2020 : {
2021 10 : edge_iterator ei;
2022 10 : basic_block bb = gimple_bb (stmt);
2023 :
2024 10 : FOR_EACH_EDGE (eh_edge, ei, bb->succs)
2025 10 : if (eh_edge->flags & EDGE_EH)
2026 : break;
2027 : }
2028 :
2029 21362 : if (TREE_CODE (rhs1) == COMPONENT_REF
2030 21362 : && DECL_BIT_FIELD_TYPE (TREE_OPERAND (rhs1, 1)))
2031 : {
2032 1225 : tree fld = TREE_OPERAND (rhs1, 1);
2033 : /* For little-endian, we can allow as inputs bit-fields
2034 : which start at a limb boundary. */
2035 1225 : gcc_assert (tree_fits_uhwi_p (DECL_FIELD_BIT_OFFSET (fld)));
2036 1225 : if (!bitint_big_endian
2037 1225 : && DECL_OFFSET_ALIGN (fld) >= TYPE_ALIGN (TREE_TYPE (rhs1))
2038 2450 : && (tree_to_uhwi (DECL_FIELD_BIT_OFFSET (fld)) % limb_prec) == 0)
2039 : {
2040 739 : load_bitfield_p = true;
2041 751 : goto normal_load;
2042 : }
2043 : /* Even if DECL_FIELD_BIT_OFFSET (fld) is a multiple of BITS_PER_UNIT,
2044 : handle it normally for now. */
2045 486 : if (!bitint_big_endian
2046 486 : && (tree_to_uhwi (DECL_FIELD_BIT_OFFSET (fld)) % BITS_PER_UNIT) == 0)
2047 : {
2048 12 : load_bitfield_p = true;
2049 12 : goto normal_load;
2050 : }
2051 474 : tree repr = DECL_BIT_FIELD_REPRESENTATIVE (fld);
2052 474 : poly_int64 bitoffset;
2053 474 : poly_uint64 field_offset, repr_offset;
2054 474 : bool var_field_off = false;
2055 474 : if (poly_int_tree_p (DECL_FIELD_OFFSET (fld), &field_offset)
2056 948 : && poly_int_tree_p (DECL_FIELD_OFFSET (repr), &repr_offset))
2057 474 : bitoffset = (field_offset - repr_offset) * BITS_PER_UNIT;
2058 : else
2059 : {
2060 : bitoffset = 0;
2061 : var_field_off = true;
2062 : }
2063 474 : bitoffset += (tree_to_uhwi (DECL_FIELD_BIT_OFFSET (fld))
2064 474 : - tree_to_uhwi (DECL_FIELD_BIT_OFFSET (repr)));
2065 948 : tree nrhs1 = build3 (COMPONENT_REF, TREE_TYPE (repr),
2066 474 : TREE_OPERAND (rhs1, 0), repr,
2067 0 : var_field_off ? TREE_OPERAND (rhs1, 2) : NULL_TREE);
2068 474 : HOST_WIDE_INT bo = bitoffset.to_constant ();
2069 474 : unsigned bo_idx = (unsigned HOST_WIDE_INT) bo / limb_prec;
2070 474 : unsigned bo_bit = (unsigned HOST_WIDE_INT) bo % limb_prec;
2071 474 : unsigned bo_last = 0;
2072 474 : unsigned bo_shift = bo_bit;
2073 474 : unsigned nelts = CEIL (TYPE_PRECISION (rhs_type), limb_prec);
2074 474 : if (bitint_big_endian)
2075 : {
2076 0 : bo_last = CEIL (TYPE_PRECISION (rhs_type) + bo_bit, limb_prec) - 1;
2077 0 : bo_shift = (TYPE_PRECISION (rhs_type) + bo_bit) % limb_prec;
2078 0 : if (bo_shift)
2079 0 : bo_shift = limb_prec - bo_shift;
2080 : }
2081 474 : if (m_first)
2082 : {
2083 141 : if (m_upwards && bo_shift)
2084 : {
2085 138 : gimple_stmt_iterator save_gsi = m_gsi;
2086 138 : m_gsi = m_init_gsi;
2087 138 : if (gsi_end_p (m_gsi))
2088 57 : m_gsi = gsi_after_labels (gsi_bb (m_gsi));
2089 : else
2090 81 : gsi_next (&m_gsi);
2091 138 : tree t = limb_access (NULL_TREE, nrhs1,
2092 138 : size_int (bo_idx + bo_last), true);
2093 138 : tree iv = make_ssa_name (m_limb_type);
2094 138 : g = gimple_build_assign (iv, t);
2095 138 : insert_before (g);
2096 138 : if (eh)
2097 : {
2098 2 : maybe_duplicate_eh_stmt (g, stmt);
2099 2 : if (eh_edge)
2100 : {
2101 2 : edge e = split_block (gsi_bb (m_gsi), g);
2102 2 : add_eh_edge (e->src, eh_edge);
2103 2 : m_gsi = gsi_after_labels (e->dest);
2104 2 : if (gsi_bb (save_gsi) == e->src)
2105 : {
2106 1 : if (gsi_end_p (save_gsi))
2107 0 : save_gsi = gsi_end_bb (e->dest);
2108 : else
2109 1 : save_gsi = gsi_for_stmt (gsi_stmt (save_gsi));
2110 : }
2111 2 : if (m_preheader_bb == e->src)
2112 1 : m_preheader_bb = e->dest;
2113 : }
2114 : }
2115 138 : m_init_gsi = m_gsi;
2116 138 : if (gsi_end_p (m_init_gsi))
2117 222 : m_init_gsi = gsi_last_bb (gsi_bb (m_init_gsi));
2118 : else
2119 28 : gsi_prev (&m_init_gsi);
2120 138 : m_gsi = save_gsi;
2121 138 : tree out;
2122 138 : prepare_data_in_out (iv, idx, &out);
2123 138 : out = m_data[m_data_cnt];
2124 138 : m_data.safe_push (out);
2125 138 : }
2126 : else
2127 : {
2128 3 : m_data.safe_push (NULL_TREE);
2129 3 : m_data.safe_push (NULL_TREE);
2130 3 : m_data.safe_push (NULL_TREE);
2131 : }
2132 : }
2133 :
2134 474 : tree nidx0 = NULL_TREE, nidx1 = NULL_TREE;
2135 474 : tree iv = m_data[m_data_cnt];
2136 474 : if (m_cast_conditional && iv)
2137 : {
2138 12 : gcc_assert (!m_bitfld_load);
2139 12 : m_bitfld_load = m_data_cnt;
2140 : }
2141 474 : if (tree_fits_uhwi_p (idx))
2142 : {
2143 272 : unsigned prec = TYPE_PRECISION (rhs_type);
2144 272 : unsigned HOST_WIDE_INT i = tree_to_uhwi (idx);
2145 272 : if (bitint_big_endian)
2146 0 : i = nelts - 1 - i;
2147 272 : gcc_assert (i * limb_prec < prec);
2148 272 : if (bo_shift)
2149 272 : nidx1 = size_int (bo_idx + (bitint_big_endian
2150 : ? bo_last - i - 1 : i + 1));
2151 272 : if ((i + 1) * limb_prec > prec)
2152 : {
2153 100 : prec %= limb_prec;
2154 100 : if (prec + bo_bit <= (unsigned) limb_prec)
2155 272 : nidx1 = NULL_TREE;
2156 : }
2157 272 : if (!iv)
2158 4 : nidx0 = size_int (bo_idx + (bitint_big_endian ? bo_last - i : i));
2159 : }
2160 : else
2161 : {
2162 202 : HOST_WIDE_INT adj = bo_idx;
2163 202 : if (bitint_big_endian)
2164 0 : adj += (HOST_WIDE_INT) bo_last + 1 - nelts;
2165 202 : if (!iv)
2166 : {
2167 4 : if (adj == 0)
2168 : nidx0 = idx;
2169 : else
2170 : {
2171 0 : nidx0 = make_ssa_name (sizetype);
2172 0 : g = gimple_build_assign (nidx0, PLUS_EXPR, idx,
2173 0 : size_int (adj));
2174 0 : insert_before (g);
2175 : }
2176 : }
2177 202 : if (bo_shift)
2178 : {
2179 202 : if (bitint_big_endian && adj == 1)
2180 : nidx1 = idx;
2181 : else
2182 : {
2183 202 : nidx1 = make_ssa_name (sizetype);
2184 202 : g = gimple_build_assign (nidx1, PLUS_EXPR, idx,
2185 404 : size_int (adj + (bitint_big_endian
2186 : ? -1 : 1)));
2187 202 : insert_before (g);
2188 : }
2189 : }
2190 : }
2191 :
2192 680 : tree iv2 = NULL_TREE;
2193 206 : if (nidx0)
2194 : {
2195 8 : tree t = limb_access (NULL_TREE, nrhs1, nidx0, true);
2196 8 : iv = make_ssa_name (m_limb_type);
2197 8 : g = gimple_build_assign (iv, t);
2198 8 : insert_before (g);
2199 8 : if (eh)
2200 : {
2201 0 : maybe_duplicate_eh_stmt (g, stmt);
2202 0 : if (eh_edge)
2203 : {
2204 0 : edge e = split_block (gsi_bb (m_gsi), g);
2205 0 : m_gsi = gsi_after_labels (e->dest);
2206 0 : add_eh_edge (e->src, eh_edge);
2207 : }
2208 : }
2209 : }
2210 474 : if (nidx1)
2211 : {
2212 385 : bool conditional = m_var_msb && !tree_fits_uhwi_p (idx);
2213 385 : unsigned prec = TYPE_PRECISION (rhs_type);
2214 385 : if (conditional)
2215 : {
2216 3 : if ((prec % limb_prec) == 0
2217 3 : || ((prec % limb_prec) + bo_bit > (unsigned) limb_prec))
2218 382 : conditional = false;
2219 : }
2220 385 : edge edge_true = NULL, edge_false = NULL;
2221 385 : if (conditional)
2222 : {
2223 6 : g = gimple_build_cond (NE_EXPR, idx,
2224 : bitint_big_endian
2225 : ? size_zero_node
2226 3 : : size_int (prec / limb_prec),
2227 : NULL_TREE, NULL_TREE);
2228 3 : if_then (g, profile_probability::likely (),
2229 : edge_true, edge_false);
2230 : }
2231 385 : tree t = limb_access (NULL_TREE, nrhs1, nidx1, true);
2232 385 : if (m_upwards_2limb
2233 283 : && !m_first
2234 184 : && !m_bitfld_load
2235 178 : && !tree_fits_uhwi_p (idx))
2236 95 : iv2 = m_data[m_data_cnt + 1];
2237 : else
2238 290 : iv2 = make_ssa_name (m_limb_type);
2239 385 : g = gimple_build_assign (iv2, t);
2240 385 : insert_before (g);
2241 385 : if (eh)
2242 : {
2243 5 : maybe_duplicate_eh_stmt (g, stmt);
2244 5 : if (eh_edge)
2245 : {
2246 5 : edge e = split_block (gsi_bb (m_gsi), g);
2247 5 : m_gsi = gsi_after_labels (e->dest);
2248 5 : add_eh_edge (e->src, eh_edge);
2249 : }
2250 : }
2251 385 : if (conditional)
2252 : {
2253 3 : tree iv3 = make_ssa_name (m_limb_type);
2254 3 : if (eh)
2255 0 : edge_true = find_edge (gsi_bb (m_gsi), edge_false->dest);
2256 3 : gphi *phi = create_phi_node (iv3, edge_true->dest);
2257 3 : add_phi_arg (phi, iv2, edge_true, UNKNOWN_LOCATION);
2258 3 : add_phi_arg (phi, build_zero_cst (m_limb_type),
2259 : edge_false, UNKNOWN_LOCATION);
2260 3 : m_gsi = gsi_after_labels (edge_true->dest);
2261 3 : iv2 = iv3;
2262 : }
2263 : }
2264 474 : if (bo_shift)
2265 : {
2266 474 : g = gimple_build_assign (make_ssa_name (m_limb_type), RSHIFT_EXPR,
2267 : iv, build_int_cst (unsigned_type_node,
2268 474 : bo_shift));
2269 474 : insert_before (g);
2270 474 : iv = gimple_assign_lhs (g);
2271 : }
2272 474 : if (iv2)
2273 : {
2274 385 : g = gimple_build_assign (make_ssa_name (m_limb_type), LSHIFT_EXPR,
2275 : iv2, build_int_cst (unsigned_type_node,
2276 385 : limb_prec - bo_shift));
2277 385 : insert_before (g);
2278 385 : g = gimple_build_assign (make_ssa_name (m_limb_type), BIT_IOR_EXPR,
2279 : gimple_assign_lhs (g), iv);
2280 385 : insert_before (g);
2281 385 : iv = gimple_assign_lhs (g);
2282 385 : if (m_data[m_data_cnt])
2283 379 : m_data[m_data_cnt] = iv2;
2284 : }
2285 474 : if (tree_fits_uhwi_p (idx))
2286 : {
2287 272 : tree atype = limb_access_type (rhs_type, idx);
2288 272 : if (!useless_type_conversion_p (atype, TREE_TYPE (iv)))
2289 100 : iv = add_cast (atype, iv);
2290 : }
2291 474 : m_data_cnt += 3;
2292 474 : return iv;
2293 : }
2294 :
2295 20888 : normal_load:
2296 : /* Use write_p = true for loads with EH edges to make
2297 : sure limb_access doesn't add a cast as separate
2298 : statement after it. */
2299 20888 : rhs1 = limb_access (rhs_type, rhs1, idx, eh, !load_bitfield_p);
2300 20888 : tree ret = make_ssa_name (TREE_TYPE (rhs1));
2301 20888 : g = gimple_build_assign (ret, rhs1);
2302 20888 : insert_before (g);
2303 20888 : if (eh)
2304 : {
2305 3 : maybe_duplicate_eh_stmt (g, stmt);
2306 3 : if (eh_edge)
2307 : {
2308 3 : edge e = split_block (gsi_bb (m_gsi), g);
2309 3 : m_gsi = gsi_after_labels (e->dest);
2310 3 : add_eh_edge (e->src, eh_edge);
2311 : }
2312 3 : if (tree_fits_uhwi_p (idx))
2313 : {
2314 1 : tree atype = limb_access_type (rhs_type, idx);
2315 1 : if (!useless_type_conversion_p (atype, TREE_TYPE (rhs1)))
2316 1 : ret = add_cast (atype, ret);
2317 : }
2318 : }
2319 : return ret;
2320 : }
2321 :
2322 : /* Return a limb IDX from a mergeable statement STMT. */
2323 :
2324 : tree
2325 39200 : bitint_large_huge::handle_stmt (gimple *stmt, tree idx)
2326 : {
2327 39200 : tree lhs, rhs1, rhs2 = NULL_TREE;
2328 39200 : gimple *g;
2329 39200 : switch (gimple_code (stmt))
2330 : {
2331 39200 : case GIMPLE_ASSIGN:
2332 39200 : if (gimple_assign_load_p (stmt))
2333 21362 : return handle_load (stmt, idx);
2334 17838 : switch (gimple_assign_rhs_code (stmt))
2335 : {
2336 990 : case BIT_AND_EXPR:
2337 990 : case BIT_IOR_EXPR:
2338 990 : case BIT_XOR_EXPR:
2339 990 : rhs2 = handle_operand (gimple_assign_rhs2 (stmt), idx);
2340 : /* FALLTHRU */
2341 1410 : case BIT_NOT_EXPR:
2342 1410 : rhs1 = handle_operand (gimple_assign_rhs1 (stmt), idx);
2343 1410 : lhs = make_ssa_name (TREE_TYPE (rhs1));
2344 1410 : g = gimple_build_assign (lhs, gimple_assign_rhs_code (stmt),
2345 : rhs1, rhs2);
2346 1410 : insert_before (g);
2347 1410 : return lhs;
2348 4026 : case PLUS_EXPR:
2349 4026 : case MINUS_EXPR:
2350 4026 : rhs1 = handle_operand (gimple_assign_rhs1 (stmt), idx);
2351 4026 : rhs2 = handle_operand (gimple_assign_rhs2 (stmt), idx);
2352 4026 : return handle_plus_minus (gimple_assign_rhs_code (stmt),
2353 4026 : rhs1, rhs2, idx);
2354 163 : case NEGATE_EXPR:
2355 163 : rhs2 = handle_operand (gimple_assign_rhs1 (stmt), idx);
2356 163 : rhs1 = build_zero_cst (TREE_TYPE (rhs2));
2357 163 : return handle_plus_minus (MINUS_EXPR, rhs1, rhs2, idx);
2358 152 : case LSHIFT_EXPR:
2359 152 : return handle_lshift (handle_operand (gimple_assign_rhs1 (stmt),
2360 : idx),
2361 152 : gimple_assign_rhs2 (stmt), idx);
2362 5087 : case SSA_NAME:
2363 5087 : case PAREN_EXPR:
2364 5087 : case INTEGER_CST:
2365 5087 : return handle_operand (gimple_assign_rhs1 (stmt), idx);
2366 6969 : CASE_CONVERT:
2367 6969 : return handle_cast (TREE_TYPE (gimple_assign_lhs (stmt)),
2368 6969 : gimple_assign_rhs1 (stmt), idx);
2369 8 : case VIEW_CONVERT_EXPR:
2370 8 : return handle_cast (TREE_TYPE (gimple_assign_lhs (stmt)),
2371 8 : TREE_OPERAND (gimple_assign_rhs1 (stmt), 0),
2372 8 : idx);
2373 23 : case BIT_FIELD_REF:
2374 23 : return handle_bit_field_ref (gimple_assign_rhs1 (stmt), idx);
2375 : default:
2376 : break;
2377 : }
2378 : break;
2379 : default:
2380 : break;
2381 : }
2382 0 : gcc_unreachable ();
2383 : }
2384 :
2385 : /* Return minimum precision of OP at STMT.
2386 : Positive value is minimum precision above which all bits
2387 : are zero, negative means all bits above negation of the
2388 : value are copies of the sign bit. */
2389 :
2390 : static int
2391 8446 : range_to_prec (tree op, gimple *stmt)
2392 : {
2393 8446 : int_range_max r;
2394 8446 : wide_int w;
2395 8446 : tree type = TREE_TYPE (op);
2396 8446 : unsigned int prec = TYPE_PRECISION (type);
2397 :
2398 8446 : if (!optimize
2399 7510 : || !get_range_query (cfun)->range_of_expr (r, op, stmt)
2400 12201 : || r.undefined_p ())
2401 : {
2402 4692 : if (TYPE_UNSIGNED (type))
2403 1902 : return prec;
2404 : else
2405 2790 : return MIN ((int) -prec, -2);
2406 : }
2407 :
2408 3754 : if (!TYPE_UNSIGNED (TREE_TYPE (op)))
2409 : {
2410 2339 : w = r.lower_bound ();
2411 2339 : if (wi::neg_p (w))
2412 : {
2413 1934 : int min_prec1 = wi::min_precision (w, SIGNED);
2414 1934 : w = r.upper_bound ();
2415 1934 : int min_prec2 = wi::min_precision (w, SIGNED);
2416 1934 : int min_prec = MAX (min_prec1, min_prec2);
2417 1934 : return MIN (-min_prec, -2);
2418 : }
2419 : }
2420 :
2421 1820 : w = r.upper_bound ();
2422 1820 : int min_prec = wi::min_precision (w, UNSIGNED);
2423 1820 : return MAX (min_prec, 1);
2424 8446 : }
2425 :
2426 : /* Return address of the first limb of OP and write into *PREC
2427 : its precision. If positive, the operand is zero extended
2428 : from that precision, if it is negative, the operand is sign-extended
2429 : from -*PREC. If PREC_STORED is NULL, it is the toplevel call,
2430 : otherwise *PREC_STORED is prec from the innermost call without
2431 : range optimizations (0 for uninitialized SSA_NAME). */
2432 :
2433 : tree
2434 3864 : bitint_large_huge::handle_operand_addr (tree op, gimple *stmt,
2435 : int *prec_stored, int *prec)
2436 : {
2437 3864 : wide_int w;
2438 3864 : location_t loc_save = m_loc;
2439 3864 : tree ret = NULL_TREE;
2440 3864 : int precs = 0;
2441 3899 : if ((!BITINT_TYPE_P (TREE_TYPE (op))
2442 3835 : || bitint_precision_kind (TREE_TYPE (op)) < bitint_prec_large)
2443 3988 : && TREE_CODE (op) != INTEGER_CST)
2444 : {
2445 124 : do_int:
2446 124 : *prec = range_to_prec (op, stmt);
2447 124 : bitint_prec_kind kind = bitint_prec_small;
2448 124 : gcc_assert (INTEGRAL_TYPE_P (TREE_TYPE (op)));
2449 124 : if (BITINT_TYPE_P (TREE_TYPE (op)))
2450 104 : kind = bitint_precision_kind (TREE_TYPE (op));
2451 104 : if (kind == bitint_prec_middle)
2452 : {
2453 12 : tree type = NULL_TREE;
2454 12 : op = maybe_cast_middle_bitint (&m_gsi, op, type);
2455 : }
2456 124 : tree op_type = TREE_TYPE (op);
2457 124 : unsigned HOST_WIDE_INT nelts
2458 124 : = CEIL (TYPE_PRECISION (op_type), limb_prec);
2459 : /* Add support for 3 or more limbs filled in from normal
2460 : integral type if this assert fails. If no target chooses
2461 : limb mode smaller than half of largest supported normal
2462 : integral type, this will not be needed. */
2463 124 : gcc_assert (nelts <= 2);
2464 124 : precs = (TYPE_UNSIGNED (op_type)
2465 124 : ? TYPE_PRECISION (op_type) : -TYPE_PRECISION (op_type));
2466 124 : if (*prec <= limb_prec && *prec >= -limb_prec)
2467 : {
2468 111 : nelts = 1;
2469 111 : if (TYPE_UNSIGNED (op_type))
2470 : {
2471 26 : if (precs > limb_prec)
2472 124 : precs = limb_prec;
2473 : }
2474 85 : else if (precs < -limb_prec)
2475 124 : precs = -limb_prec;
2476 : }
2477 124 : if (prec_stored)
2478 0 : *prec_stored = precs;
2479 124 : tree atype = build_array_type_nelts (m_limb_type, nelts);
2480 124 : tree var = create_tmp_var (atype);
2481 124 : tree t1 = op;
2482 124 : if (!useless_type_conversion_p (m_limb_type, op_type))
2483 124 : t1 = add_cast (m_limb_type, t1);
2484 124 : tree v = build4 (ARRAY_REF, m_limb_type, var,
2485 0 : bitint_big_endian && nelts > 1
2486 : ? size_one_node : size_zero_node,
2487 : NULL_TREE, NULL_TREE);
2488 124 : gimple *g = gimple_build_assign (v, t1);
2489 124 : insert_before (g);
2490 124 : if (nelts > 1)
2491 : {
2492 13 : tree lp = build_int_cst (unsigned_type_node, limb_prec);
2493 13 : g = gimple_build_assign (make_ssa_name (op_type),
2494 : RSHIFT_EXPR, op, lp);
2495 13 : insert_before (g);
2496 13 : tree t2 = gimple_assign_lhs (g);
2497 13 : t2 = add_cast (m_limb_type, t2);
2498 13 : v = build4 (ARRAY_REF, m_limb_type, var,
2499 : bitint_big_endian ? size_zero_node : size_one_node,
2500 : NULL_TREE, NULL_TREE);
2501 13 : g = gimple_build_assign (v, t2);
2502 13 : insert_before (g);
2503 : }
2504 124 : ret = build_fold_addr_expr (var);
2505 124 : if (!stmt_ends_bb_p (gsi_stmt (m_gsi)))
2506 : {
2507 123 : tree clobber = build_clobber (atype, CLOBBER_STORAGE_END);
2508 123 : g = gimple_build_assign (var, clobber);
2509 123 : gsi_insert_after (&m_gsi, g, GSI_SAME_STMT);
2510 : }
2511 124 : m_loc = loc_save;
2512 124 : goto do_ret;
2513 : }
2514 3788 : switch (TREE_CODE (op))
2515 : {
2516 2922 : case SSA_NAME:
2517 2922 : if (m_names == NULL
2518 2922 : || !bitmap_bit_p (m_names, SSA_NAME_VERSION (op)))
2519 : {
2520 102 : gimple *g = SSA_NAME_DEF_STMT (op);
2521 102 : m_loc = gimple_location (g);
2522 102 : if (gimple_assign_load_p (g))
2523 : {
2524 36 : *prec = range_to_prec (op, NULL);
2525 36 : precs = (TYPE_UNSIGNED (TREE_TYPE (op))
2526 36 : ? TYPE_PRECISION (TREE_TYPE (op))
2527 25 : : -TYPE_PRECISION (TREE_TYPE (op)));
2528 36 : if (prec_stored)
2529 6 : *prec_stored = precs;
2530 36 : ret = build_fold_addr_expr (gimple_assign_rhs1 (g));
2531 36 : ret = force_gimple_operand_gsi (&m_gsi, ret, true,
2532 : NULL_TREE, true, GSI_SAME_STMT);
2533 : }
2534 66 : else if (gimple_code (g) == GIMPLE_NOP)
2535 : {
2536 2 : *prec = TYPE_UNSIGNED (TREE_TYPE (op)) ? limb_prec : -limb_prec;
2537 2 : precs = *prec;
2538 2 : if (prec_stored)
2539 1 : *prec_stored = 0;
2540 2 : tree var = create_tmp_var (m_limb_type);
2541 2 : TREE_ADDRESSABLE (var) = 1;
2542 2 : ret = build_fold_addr_expr (var);
2543 2 : if (!stmt_ends_bb_p (gsi_stmt (m_gsi)))
2544 : {
2545 2 : tree clobber = build_clobber (m_limb_type,
2546 : CLOBBER_STORAGE_END);
2547 2 : g = gimple_build_assign (var, clobber);
2548 2 : gsi_insert_after (&m_gsi, g, GSI_SAME_STMT);
2549 : }
2550 : }
2551 : else
2552 : {
2553 64 : gcc_assert (gimple_assign_cast_p (g));
2554 64 : tree rhs1 = gimple_assign_rhs1 (g);
2555 64 : bitint_prec_kind kind = bitint_prec_small;
2556 64 : if (TREE_CODE (rhs1) == VIEW_CONVERT_EXPR)
2557 1 : rhs1 = TREE_OPERAND (rhs1, 0);
2558 64 : gcc_assert (INTEGRAL_TYPE_P (TREE_TYPE (rhs1)));
2559 64 : if (BITINT_TYPE_P (TREE_TYPE (rhs1)))
2560 49 : kind = bitint_precision_kind (TREE_TYPE (rhs1));
2561 49 : if (kind >= bitint_prec_large)
2562 : {
2563 16 : tree lhs_type = TREE_TYPE (op);
2564 16 : tree rhs_type = TREE_TYPE (rhs1);
2565 16 : int prec_stored_val = 0;
2566 16 : ret = handle_operand_addr (rhs1, g, &prec_stored_val, prec);
2567 16 : precs = prec_stored_val;
2568 16 : if (prec_stored)
2569 0 : *prec_stored = prec_stored_val;
2570 16 : if (precs == 0)
2571 : {
2572 1 : gcc_assert (*prec == limb_prec || *prec == -limb_prec);
2573 : precs = *prec;
2574 : }
2575 16 : if (TYPE_PRECISION (lhs_type) > TYPE_PRECISION (rhs_type))
2576 : {
2577 4 : if (TYPE_UNSIGNED (lhs_type)
2578 4 : && !TYPE_UNSIGNED (rhs_type))
2579 1 : gcc_assert (*prec >= 0 || prec_stored == NULL);
2580 : }
2581 : else
2582 : {
2583 12 : if (prec_stored_val == 0)
2584 : /* Non-widening cast of uninitialized value. */;
2585 11 : else if (*prec > 0 && *prec < TYPE_PRECISION (lhs_type))
2586 : ;
2587 11 : else if (TYPE_UNSIGNED (lhs_type))
2588 : {
2589 8 : gcc_assert (*prec > 0
2590 : || prec_stored_val > 0
2591 : || (-prec_stored_val
2592 : >= TYPE_PRECISION (lhs_type)));
2593 8 : *prec = TYPE_PRECISION (lhs_type);
2594 : }
2595 3 : else if (*prec < 0 && -*prec < TYPE_PRECISION (lhs_type))
2596 : ;
2597 : else
2598 3 : *prec = -TYPE_PRECISION (lhs_type);
2599 : }
2600 : }
2601 : else
2602 : {
2603 48 : op = rhs1;
2604 48 : stmt = g;
2605 48 : goto do_int;
2606 : }
2607 : }
2608 54 : m_loc = loc_save;
2609 54 : goto do_ret;
2610 : }
2611 : else
2612 : {
2613 2820 : int p = var_to_partition (m_map, op);
2614 2820 : gcc_assert (m_vars[p] != NULL_TREE);
2615 2820 : *prec = range_to_prec (op, stmt);
2616 2820 : precs = (TYPE_UNSIGNED (TREE_TYPE (op))
2617 2820 : ? TYPE_PRECISION (TREE_TYPE (op))
2618 1669 : : -TYPE_PRECISION (TREE_TYPE (op)));
2619 2820 : if (prec_stored)
2620 9 : *prec_stored = precs;
2621 2820 : ret = build_fold_addr_expr (m_vars[p]);
2622 2820 : goto do_ret;
2623 : }
2624 866 : case INTEGER_CST:
2625 866 : unsigned int min_prec, mp;
2626 866 : tree type;
2627 866 : w = wi::to_wide (op);
2628 866 : if (tree_int_cst_sgn (op) >= 0)
2629 : {
2630 651 : min_prec = wi::min_precision (w, UNSIGNED);
2631 651 : *prec = MAX (min_prec, 1);
2632 : }
2633 : else
2634 : {
2635 215 : min_prec = wi::min_precision (w, SIGNED);
2636 215 : *prec = MIN ((int) -min_prec, -2);
2637 : }
2638 866 : mp = CEIL (min_prec, limb_prec) * limb_prec;
2639 866 : if (mp == 0)
2640 : mp = 1;
2641 866 : if (mp >= (unsigned) TYPE_PRECISION (TREE_TYPE (op))
2642 866 : && (BITINT_TYPE_P (TREE_TYPE (op))
2643 24 : || TYPE_PRECISION (TREE_TYPE (op)) <= limb_prec))
2644 316 : type = TREE_TYPE (op);
2645 : else
2646 550 : type = build_bitint_type (mp, 1);
2647 20 : if (!BITINT_TYPE_P (type)
2648 866 : || bitint_precision_kind (type) == bitint_prec_small)
2649 : {
2650 587 : if (TYPE_PRECISION (type) <= limb_prec)
2651 587 : type = m_limb_type;
2652 : else
2653 : {
2654 0 : while (bitint_precision_kind (mp) == bitint_prec_small)
2655 0 : mp += limb_prec;
2656 : /* This case is for targets which e.g. have 64-bit
2657 : limb but categorize up to 128-bits _BitInts as
2658 : small. We could use type of m_limb_type[2] and
2659 : similar instead to save space. */
2660 0 : type = build_bitint_type (mp, 1);
2661 : }
2662 : }
2663 866 : if (tree_int_cst_sgn (op) >= 0)
2664 651 : precs = MAX (TYPE_PRECISION (type), 1);
2665 : else
2666 215 : precs = MIN ((int) -TYPE_PRECISION (type), -2);
2667 866 : if (prec_stored)
2668 0 : *prec_stored = precs;
2669 866 : op = tree_output_constant_def (fold_convert (type, op));
2670 866 : ret = build_fold_addr_expr (op);
2671 866 : goto do_ret;
2672 0 : default:
2673 0 : gcc_unreachable ();
2674 : }
2675 3864 : do_ret:
2676 3864 : if (bitint_big_endian && prec_stored == NULL)
2677 : {
2678 0 : int p1 = *prec < 0 ? -*prec : *prec;
2679 0 : int p2 = precs < 0 ? -precs : precs;
2680 0 : int c1 = CEIL (p1, limb_prec);
2681 0 : int c2 = CEIL (p2, limb_prec);
2682 0 : gcc_assert (c1 <= c2);
2683 0 : if (c1 != c2)
2684 : {
2685 0 : gimple *g
2686 0 : = gimple_build_assign (make_ssa_name (TREE_TYPE (ret)),
2687 : POINTER_PLUS_EXPR, ret,
2688 0 : size_int ((c2 - c1) * m_limb_size));
2689 0 : insert_before (g);
2690 0 : ret = gimple_assign_lhs (g);
2691 : }
2692 : }
2693 3864 : return ret;
2694 3864 : }
2695 :
2696 : /* Helper function, create a loop before the current location,
2697 : start with sizetype INIT value from the preheader edge. Return
2698 : a PHI result and set *IDX_NEXT to SSA_NAME it creates and uses
2699 : from the latch edge. */
2700 :
2701 : tree
2702 14674 : bitint_large_huge::create_loop (tree init, tree *idx_next)
2703 : {
2704 14674 : if (!gsi_end_p (m_gsi))
2705 15776 : gsi_prev (&m_gsi);
2706 : else
2707 4336 : m_gsi = gsi_last_bb (gsi_bb (m_gsi));
2708 14674 : edge e1 = split_block (gsi_bb (m_gsi), gsi_stmt (m_gsi));
2709 14674 : edge e2 = split_block (e1->dest, (gimple *) NULL);
2710 14674 : edge e3 = make_edge (e1->dest, e1->dest, EDGE_TRUE_VALUE);
2711 14674 : e3->probability = profile_probability::very_unlikely ();
2712 14674 : e2->flags = EDGE_FALSE_VALUE;
2713 14674 : e2->probability = e3->probability.invert ();
2714 14674 : tree idx = make_ssa_name (sizetype);
2715 14674 : gphi *phi = create_phi_node (idx, e1->dest);
2716 14674 : add_phi_arg (phi, init, e1, UNKNOWN_LOCATION);
2717 14674 : *idx_next = make_ssa_name (sizetype);
2718 14674 : add_phi_arg (phi, *idx_next, e3, UNKNOWN_LOCATION);
2719 14674 : m_gsi = gsi_after_labels (e1->dest);
2720 14674 : m_bb = e1->dest;
2721 14674 : m_preheader_bb = e1->src;
2722 14674 : class loop *loop = alloc_loop ();
2723 14674 : loop->header = e1->dest;
2724 14674 : add_loop (loop, e1->src->loop_father);
2725 14674 : return idx;
2726 : }
2727 :
2728 : /* Lower large/huge _BitInt statement mergeable or similar STMT which can be
2729 : lowered using iteration from the least significant limb up to the most
2730 : significant limb. For large _BitInt it is emitted as straight line code
2731 : before current location, for huge _BitInt as a loop handling two limbs
2732 : at once, followed by handling up to limbs in straight line code (at most
2733 : one full and one partial limb). It can also handle EQ_EXPR/NE_EXPR
2734 : comparisons, in that case CMP_CODE should be the comparison code and
2735 : CMP_OP1/CMP_OP2 the comparison operands. */
2736 :
2737 : tree
2738 23385 : bitint_large_huge::lower_mergeable_stmt (gimple *stmt, tree_code &cmp_code,
2739 : tree cmp_op1, tree cmp_op2)
2740 : {
2741 23385 : bool eq_p = cmp_code != ERROR_MARK;
2742 23385 : tree type;
2743 23385 : if (eq_p)
2744 6552 : type = TREE_TYPE (cmp_op1);
2745 : else
2746 16833 : type = TREE_TYPE (gimple_assign_lhs (stmt));
2747 23385 : gcc_assert (BITINT_TYPE_P (type));
2748 23385 : bitint_prec_kind kind = bitint_precision_kind (type);
2749 23385 : gcc_assert (kind >= bitint_prec_large);
2750 23385 : gimple *g;
2751 23385 : tree lhs = gimple_get_lhs (stmt);
2752 23385 : tree rhs1, lhs_type = lhs ? TREE_TYPE (lhs) : NULL_TREE;
2753 17273 : if (lhs
2754 17273 : && TREE_CODE (lhs) == SSA_NAME
2755 8749 : && BITINT_TYPE_P (TREE_TYPE (lhs))
2756 8309 : && bitint_precision_kind (TREE_TYPE (lhs)) >= bitint_prec_large)
2757 : {
2758 8309 : int p = var_to_partition (m_map, lhs);
2759 8309 : gcc_assert (m_vars[p] != NULL_TREE);
2760 8309 : m_lhs = lhs = m_vars[p];
2761 : }
2762 23385 : unsigned cnt, rem = 0, end = 0, prec = TYPE_PRECISION (type);
2763 23385 : bool sext = false;
2764 23385 : tree ext = NULL_TREE, store_operand = NULL_TREE;
2765 23385 : bool eh = false;
2766 23385 : basic_block eh_pad = NULL;
2767 23385 : tree nlhs = NULL_TREE;
2768 23385 : unsigned HOST_WIDE_INT bo_idx = 0;
2769 23385 : unsigned HOST_WIDE_INT bo_bit = 0;
2770 23385 : unsigned bo_shift = 0;
2771 23385 : unsigned bo_last = 0;
2772 23385 : bool bo_be_p = false;
2773 23385 : tree bf_cur = NULL_TREE, bf_next = NULL_TREE;
2774 23385 : if (gimple_store_p (stmt))
2775 : {
2776 8524 : store_operand = gimple_assign_rhs1 (stmt);
2777 8524 : eh = stmt_ends_bb_p (stmt);
2778 8524 : if (eh)
2779 : {
2780 2 : edge e;
2781 2 : edge_iterator ei;
2782 2 : basic_block bb = gimple_bb (stmt);
2783 :
2784 2 : FOR_EACH_EDGE (e, ei, bb->succs)
2785 2 : if (e->flags & EDGE_EH)
2786 : {
2787 2 : eh_pad = e->dest;
2788 2 : break;
2789 : }
2790 : }
2791 8524 : if (TREE_CODE (lhs) == COMPONENT_REF
2792 8524 : && DECL_BIT_FIELD_TYPE (TREE_OPERAND (lhs, 1)))
2793 : {
2794 162 : tree fld = TREE_OPERAND (lhs, 1);
2795 162 : gcc_assert (tree_fits_uhwi_p (DECL_FIELD_BIT_OFFSET (fld)));
2796 162 : tree repr = DECL_BIT_FIELD_REPRESENTATIVE (fld);
2797 162 : poly_int64 bitoffset;
2798 162 : poly_uint64 field_offset, repr_offset;
2799 162 : if (!bitint_big_endian
2800 162 : && (tree_to_uhwi (DECL_FIELD_BIT_OFFSET (fld))
2801 162 : % BITS_PER_UNIT) == 0)
2802 : nlhs = lhs;
2803 : else
2804 : {
2805 143 : bool var_field_off = false;
2806 143 : if (poly_int_tree_p (DECL_FIELD_OFFSET (fld), &field_offset)
2807 286 : && poly_int_tree_p (DECL_FIELD_OFFSET (repr), &repr_offset))
2808 143 : bitoffset = (field_offset - repr_offset) * BITS_PER_UNIT;
2809 : else
2810 : {
2811 : bitoffset = 0;
2812 : var_field_off = true;
2813 : }
2814 143 : bitoffset += (tree_to_uhwi (DECL_FIELD_BIT_OFFSET (fld))
2815 143 : - tree_to_uhwi (DECL_FIELD_BIT_OFFSET (repr)));
2816 286 : nlhs = build3 (COMPONENT_REF, TREE_TYPE (repr),
2817 143 : TREE_OPERAND (lhs, 0), repr,
2818 : var_field_off
2819 0 : ? TREE_OPERAND (lhs, 2) : NULL_TREE);
2820 143 : HOST_WIDE_INT bo = bitoffset.to_constant ();
2821 143 : bo_idx = (unsigned HOST_WIDE_INT) bo / limb_prec;
2822 143 : bo_bit = (unsigned HOST_WIDE_INT) bo % limb_prec;
2823 143 : bo_shift = bo_bit;
2824 143 : if (bitint_big_endian)
2825 : {
2826 0 : bo_last = CEIL (prec + bo_bit, limb_prec) - 1;
2827 0 : bo_shift = (prec + bo_bit) % limb_prec;
2828 0 : bo_be_p = true;
2829 0 : if (bo_shift)
2830 0 : bo_shift = limb_prec - bo_shift;
2831 : }
2832 : }
2833 : }
2834 : }
2835 8524 : if ((store_operand
2836 8524 : && TREE_CODE (store_operand) == SSA_NAME
2837 7546 : && (m_names == NULL
2838 7516 : || !bitmap_bit_p (m_names, SSA_NAME_VERSION (store_operand)))
2839 1156 : && gimple_assign_cast_p (SSA_NAME_DEF_STMT (store_operand)))
2840 31353 : || gimple_assign_cast_p (stmt))
2841 : {
2842 2159 : rhs1 = gimple_assign_rhs1 (store_operand
2843 556 : ? SSA_NAME_DEF_STMT (store_operand)
2844 : : stmt);
2845 1603 : if (TREE_CODE (rhs1) == VIEW_CONVERT_EXPR)
2846 2 : rhs1 = TREE_OPERAND (rhs1, 0);
2847 : /* Optimize mergeable ops ending with widening cast to _BitInt
2848 : (or followed by store). We can lower just the limbs of the
2849 : cast operand and widen afterwards. */
2850 1603 : if (TREE_CODE (rhs1) == SSA_NAME
2851 1603 : && (m_names == NULL
2852 1597 : || !bitmap_bit_p (m_names, SSA_NAME_VERSION (rhs1)))
2853 619 : && BITINT_TYPE_P (TREE_TYPE (rhs1))
2854 480 : && bitint_precision_kind (TREE_TYPE (rhs1)) >= bitint_prec_large
2855 2034 : && (CEIL ((unsigned) TYPE_PRECISION (TREE_TYPE (rhs1)),
2856 431 : limb_prec) < CEIL (prec, limb_prec)
2857 306 : || (kind == bitint_prec_huge
2858 262 : && TYPE_PRECISION (TREE_TYPE (rhs1)) < prec)))
2859 : {
2860 131 : store_operand = rhs1;
2861 131 : prec = TYPE_PRECISION (TREE_TYPE (rhs1));
2862 131 : kind = bitint_precision_kind (TREE_TYPE (rhs1));
2863 131 : if (!TYPE_UNSIGNED (TREE_TYPE (rhs1)))
2864 54 : sext = true;
2865 : }
2866 : }
2867 23385 : tree idx = NULL_TREE, idx_first = NULL_TREE, idx_next = NULL_TREE;
2868 23385 : if (kind == bitint_prec_large)
2869 12207 : cnt = CEIL (prec, limb_prec);
2870 : else
2871 : {
2872 11178 : rem = (prec % (2 * limb_prec));
2873 11178 : end = (prec - rem) / limb_prec;
2874 11178 : cnt = 2 + CEIL (rem, limb_prec);
2875 11178 : idx = idx_first = create_loop (bitint_big_endian
2876 11178 : ? size_int (cnt - 2 + end - 1)
2877 : : size_zero_node, &idx_next);
2878 : }
2879 :
2880 23385 : basic_block edge_bb = NULL;
2881 23385 : if (eq_p)
2882 : {
2883 6552 : gimple_stmt_iterator gsi = gsi_for_stmt (stmt);
2884 6552 : gsi_prev (&gsi);
2885 6552 : edge e = split_block (gsi_bb (gsi), gsi_stmt (gsi));
2886 6552 : edge_bb = e->src;
2887 6552 : if (kind == bitint_prec_large)
2888 7186 : m_gsi = gsi_end_bb (edge_bb);
2889 : }
2890 : else
2891 16833 : m_after_stmt = stmt;
2892 23385 : if (kind != bitint_prec_large)
2893 11178 : m_upwards_2limb = end;
2894 23385 : m_upwards = true;
2895 :
2896 23385 : bool separate_ext
2897 23385 : = (prec != (unsigned) TYPE_PRECISION (type)
2898 23385 : && (CEIL ((unsigned) TYPE_PRECISION (type), limb_prec)
2899 131 : > CEIL (prec, limb_prec)));
2900 23385 : bool zero_ms_limb = false;
2901 23385 : if (bitint_extended == bitint_ext_full
2902 0 : && !eq_p
2903 0 : && !nlhs
2904 0 : && abi_limb_prec > limb_prec
2905 23385 : && ((CEIL ((unsigned) TYPE_PRECISION (type), abi_limb_prec)
2906 0 : * abi_limb_prec / limb_prec)
2907 0 : > CEIL ((unsigned) TYPE_PRECISION (type), limb_prec)))
2908 : {
2909 0 : if (prec == (unsigned) TYPE_PRECISION (type))
2910 : {
2911 0 : sext = !TYPE_UNSIGNED (type);
2912 0 : separate_ext = true;
2913 : }
2914 0 : else if (TYPE_UNSIGNED (type) && sext)
2915 : zero_ms_limb = true;
2916 : else
2917 : separate_ext = true;
2918 : }
2919 23510 : unsigned dst_idx_off = 0;
2920 23385 : if (separate_ext && bitint_big_endian)
2921 0 : dst_idx_off = (CEIL ((unsigned) TYPE_PRECISION (type), limb_prec)
2922 0 : - CEIL (prec, limb_prec));
2923 :
2924 93759 : for (unsigned i = 0; i < cnt; i++)
2925 : {
2926 70374 : m_data_cnt = 0;
2927 70374 : if (kind == bitint_prec_large)
2928 37235 : idx = size_int (bitint_big_endian ? cnt - 1 - i : i);
2929 33139 : else if (i >= 2)
2930 10783 : idx = size_int (bitint_big_endian ? cnt - 1 - i : end + (i > 2));
2931 70374 : if (eq_p)
2932 : {
2933 19845 : rhs1 = handle_operand (cmp_op1, idx);
2934 19845 : tree rhs2 = handle_operand (cmp_op2, idx);
2935 19845 : g = gimple_build_cond (NE_EXPR, rhs1, rhs2, NULL_TREE, NULL_TREE);
2936 19845 : insert_before (g);
2937 19845 : edge e1 = split_block (gsi_bb (m_gsi), g);
2938 19845 : e1->flags = EDGE_FALSE_VALUE;
2939 19845 : edge e2 = make_edge (e1->src, gimple_bb (stmt), EDGE_TRUE_VALUE);
2940 19845 : e1->probability = profile_probability::unlikely ();
2941 19845 : e2->probability = e1->probability.invert ();
2942 19845 : if (i == 0)
2943 6552 : set_immediate_dominator (CDI_DOMINATORS, e2->dest, e2->src);
2944 19845 : m_gsi = gsi_after_labels (e1->dest);
2945 : }
2946 : else
2947 : {
2948 50529 : if (store_operand)
2949 25803 : rhs1 = handle_operand (store_operand, idx);
2950 : else
2951 24726 : rhs1 = handle_stmt (stmt, idx);
2952 50529 : if (!useless_type_conversion_p (m_limb_type, TREE_TYPE (rhs1)))
2953 12056 : rhs1 = add_cast (m_limb_type, rhs1);
2954 50529 : if (sext && i == cnt - 1)
2955 50529 : ext = rhs1;
2956 50529 : tree nidx = idx;
2957 50529 : HOST_WIDE_INT adj = bo_idx;
2958 50529 : if (bo_be_p)
2959 0 : adj += bo_last - (CEIL (prec, limb_prec) - 1);
2960 : else
2961 50529 : adj += dst_idx_off;
2962 50529 : if (adj)
2963 : {
2964 220 : if (tree_fits_uhwi_p (idx))
2965 116 : nidx = size_int (tree_to_uhwi (idx) + adj);
2966 : else
2967 : {
2968 104 : nidx = make_ssa_name (sizetype);
2969 104 : g = gimple_build_assign (nidx, PLUS_EXPR, idx,
2970 104 : size_int (adj));
2971 104 : insert_before (g);
2972 : }
2973 : }
2974 50529 : bool done = false;
2975 50529 : basic_block new_bb = NULL;
2976 : /* Handle stores into bit-fields. */
2977 50529 : if (bo_shift)
2978 : {
2979 455 : if (i == 0)
2980 : {
2981 143 : edge e2 = NULL;
2982 143 : if (kind != bitint_prec_large)
2983 : {
2984 112 : prepare_data_in_out (build_zero_cst (m_limb_type),
2985 : idx, &bf_next);
2986 112 : bf_next = m_data.pop ();
2987 112 : bf_cur = m_data.pop ();
2988 112 : g = gimple_build_cond (EQ_EXPR, idx,
2989 : bitint_big_endian
2990 0 : ? size_int (CEIL (prec,
2991 : limb_prec) - 1)
2992 : : size_zero_node,
2993 : NULL_TREE, NULL_TREE);
2994 112 : edge edge_true;
2995 112 : if_then_else (g, profile_probability::unlikely (),
2996 : edge_true, e2);
2997 112 : new_bb = e2->dest;
2998 : }
2999 143 : tree ftype
3000 143 : = build_nonstandard_integer_type (limb_prec - bo_shift, 1);
3001 286 : tree bfr = build_bit_field_ref (ftype, unshare_expr (nlhs),
3002 143 : limb_prec - bo_shift,
3003 : bitint_big_endian
3004 0 : ? (bo_idx + bo_last)
3005 0 : * limb_prec
3006 143 : : bo_idx * limb_prec
3007 : + bo_bit);
3008 143 : tree t = add_cast (ftype, rhs1);
3009 143 : g = gimple_build_assign (bfr, t);
3010 143 : insert_before (g);
3011 143 : if (eh)
3012 : {
3013 0 : maybe_duplicate_eh_stmt (g, stmt);
3014 0 : if (eh_pad)
3015 : {
3016 0 : edge e = split_block (gsi_bb (m_gsi), g);
3017 0 : m_gsi = gsi_after_labels (e->dest);
3018 0 : add_eh_edge (e->src,
3019 : find_edge (gimple_bb (stmt), eh_pad));
3020 : }
3021 : }
3022 143 : if (kind == bitint_prec_large)
3023 : {
3024 : bf_cur = rhs1;
3025 : done = true;
3026 : }
3027 112 : else if (e2)
3028 112 : m_gsi = gsi_after_labels (e2->src);
3029 : }
3030 112 : if (!done)
3031 : {
3032 424 : tree t1 = make_ssa_name (m_limb_type);
3033 424 : tree t2 = make_ssa_name (m_limb_type);
3034 424 : tree t3 = make_ssa_name (m_limb_type);
3035 424 : g = gimple_build_assign (t1, RSHIFT_EXPR, bf_cur,
3036 : build_int_cst (unsigned_type_node,
3037 424 : limb_prec
3038 424 : - bo_shift));
3039 424 : insert_before (g);
3040 424 : g = gimple_build_assign (t2, LSHIFT_EXPR, rhs1,
3041 : build_int_cst (unsigned_type_node,
3042 424 : bo_shift));
3043 424 : insert_before (g);
3044 424 : bf_cur = rhs1;
3045 424 : g = gimple_build_assign (t3, BIT_IOR_EXPR, t1, t2);
3046 424 : insert_before (g);
3047 424 : rhs1 = t3;
3048 424 : if (bf_next && i == 1)
3049 : {
3050 112 : g = gimple_build_assign (bf_next, bf_cur);
3051 112 : insert_before (g);
3052 : }
3053 : }
3054 : }
3055 31 : if (!done)
3056 : {
3057 : /* Handle bit-field access to partial last limb if needed. */
3058 50498 : if (nlhs
3059 480 : && i == cnt - 1
3060 162 : && !separate_ext
3061 138 : && tree_fits_uhwi_p (idx))
3062 : {
3063 123 : unsigned int tprec = TYPE_PRECISION (type);
3064 123 : unsigned int rprec = (tprec - 1) % limb_prec + 1;
3065 123 : if (rprec + bo_shift < (unsigned) limb_prec)
3066 : {
3067 46 : tree ftype
3068 46 : = build_nonstandard_integer_type (rprec + bo_shift, 1);
3069 46 : tree bfr
3070 92 : = build_bit_field_ref (ftype, unshare_expr (nlhs),
3071 : rprec + bo_shift,
3072 : bitint_big_endian
3073 0 : ? bo_idx * limb_prec + bo_bit
3074 46 : : (bo_idx + tprec / limb_prec)
3075 46 : * limb_prec);
3076 46 : tree t = add_cast (ftype, rhs1);
3077 46 : g = gimple_build_assign (bfr, t);
3078 46 : done = true;
3079 46 : bf_cur = NULL_TREE;
3080 : }
3081 77 : else if (rprec + bo_shift == (unsigned) limb_prec)
3082 50452 : bf_cur = NULL_TREE;
3083 : }
3084 : /* Otherwise, stores to any other lhs. */
3085 46 : if (!done)
3086 : {
3087 50886 : tree l = limb_access (nlhs ? NULL_TREE : lhs_type,
3088 : nlhs ? nlhs : lhs, nidx, true);
3089 50452 : g = gimple_build_assign (l, rhs1);
3090 : }
3091 50498 : insert_before (g);
3092 50498 : if (eh)
3093 : {
3094 6 : maybe_duplicate_eh_stmt (g, stmt);
3095 6 : if (eh_pad)
3096 : {
3097 6 : edge e = split_block (gsi_bb (m_gsi), g);
3098 6 : m_gsi = gsi_after_labels (e->dest);
3099 6 : add_eh_edge (e->src,
3100 : find_edge (gimple_bb (stmt), eh_pad));
3101 : }
3102 : }
3103 50498 : if (new_bb)
3104 112 : m_gsi = gsi_after_labels (new_bb);
3105 : }
3106 : }
3107 70374 : m_first = false;
3108 70374 : if (kind == bitint_prec_huge && i <= 1)
3109 : {
3110 22356 : if (i == 0)
3111 : {
3112 11178 : idx = make_ssa_name (sizetype);
3113 11178 : g = gimple_build_assign (idx, PLUS_EXPR, idx_first,
3114 : bitint_big_endian
3115 0 : ? size_int (-1) : size_one_node);
3116 11178 : insert_before (g);
3117 : }
3118 : else
3119 : {
3120 11178 : g = gimple_build_assign (idx_next, PLUS_EXPR, idx_first,
3121 22356 : size_int (bitint_big_endian ? -2 : 2));
3122 11178 : insert_before (g);
3123 11178 : if (bitint_big_endian)
3124 0 : g = gimple_build_cond (NE_EXPR, idx_first, size_int (cnt - 1),
3125 : NULL_TREE, NULL_TREE);
3126 : else
3127 11178 : g = gimple_build_cond (NE_EXPR, idx_next, size_int (end),
3128 : NULL_TREE, NULL_TREE);
3129 11178 : insert_before (g);
3130 11178 : if (eq_p)
3131 2959 : m_gsi = gsi_after_labels (edge_bb);
3132 : else
3133 8219 : m_gsi = gsi_for_stmt (stmt);
3134 11178 : m_bb = NULL;
3135 : }
3136 : }
3137 : }
3138 :
3139 23385 : if (separate_ext)
3140 : {
3141 125 : if (sext)
3142 : {
3143 51 : ext = add_cast (signed_type_for (m_limb_type), ext);
3144 102 : tree lpm1 = build_int_cst (unsigned_type_node,
3145 51 : limb_prec - 1);
3146 51 : tree n = make_ssa_name (TREE_TYPE (ext));
3147 51 : g = gimple_build_assign (n, RSHIFT_EXPR, ext, lpm1);
3148 51 : insert_before (g);
3149 51 : ext = add_cast (m_limb_type, n);
3150 : }
3151 : else
3152 74 : ext = build_zero_cst (m_limb_type);
3153 125 : kind = bitint_precision_kind (type);
3154 125 : unsigned start = CEIL (prec, limb_prec);
3155 125 : prec = TYPE_PRECISION (type);
3156 125 : if (bitint_extended == bitint_ext_full
3157 0 : && !nlhs
3158 0 : && !zero_ms_limb
3159 0 : && abi_limb_prec > limb_prec)
3160 : {
3161 0 : prec = CEIL (prec, abi_limb_prec) * abi_limb_prec;
3162 0 : kind = bitint_precision_kind (prec);
3163 : }
3164 125 : unsigned total = CEIL (prec, limb_prec);
3165 125 : idx = idx_first = idx_next = NULL_TREE;
3166 125 : if (prec <= (start + 2 + (bo_shift != 0)) * limb_prec)
3167 : kind = bitint_prec_large;
3168 80 : if (kind == bitint_prec_large)
3169 45 : cnt = total - start;
3170 : else
3171 : {
3172 80 : rem = prec % limb_prec;
3173 80 : end = (prec - rem) / limb_prec;
3174 152 : cnt = (bo_shift != 0) + 1 + (rem != 0);
3175 : }
3176 125 : if (bitint_big_endian && bo_shift != 0 && (prec % limb_prec) == 0)
3177 0 : ++total;
3178 321 : for (unsigned i = 0; i < cnt; i++)
3179 : {
3180 196 : if (kind == bitint_prec_large || (i == 0 && bo_shift != 0))
3181 62 : idx = size_int (bo_idx
3182 : + (bitint_big_endian
3183 : ? total - 1 - start - i : start + i));
3184 134 : else if (i == cnt - 1 && rem != 0)
3185 108 : idx = size_int (bo_idx + (bitint_big_endian ? 0 : end));
3186 80 : else if (i == (bo_shift != 0))
3187 80 : idx = create_loop (size_int (bo_idx
3188 : + (bitint_big_endian
3189 : ? total - 1 - start - i
3190 : : start + i)), &idx_next);
3191 196 : rhs1 = ext;
3192 196 : if (bf_cur != NULL_TREE && bf_cur != ext)
3193 : {
3194 20 : tree t1 = make_ssa_name (m_limb_type);
3195 20 : g = gimple_build_assign (t1, RSHIFT_EXPR, bf_cur,
3196 : build_int_cst (unsigned_type_node,
3197 20 : limb_prec - bo_shift));
3198 20 : insert_before (g);
3199 20 : if (integer_zerop (ext))
3200 : rhs1 = t1;
3201 : else
3202 : {
3203 10 : tree t2 = make_ssa_name (m_limb_type);
3204 10 : rhs1 = make_ssa_name (m_limb_type);
3205 10 : g = gimple_build_assign (t2, LSHIFT_EXPR, ext,
3206 : build_int_cst (unsigned_type_node,
3207 10 : bo_shift));
3208 10 : insert_before (g);
3209 10 : g = gimple_build_assign (rhs1, BIT_IOR_EXPR, t1, t2);
3210 10 : insert_before (g);
3211 : }
3212 : bf_cur = ext;
3213 : }
3214 196 : bool done = false;
3215 : /* Handle bit-field access to partial last limb if needed. */
3216 196 : if (nlhs && i == cnt - 1)
3217 : {
3218 24 : unsigned int tprec = TYPE_PRECISION (type);
3219 24 : unsigned int rprec = (tprec - 1) % limb_prec + 1;
3220 24 : if (rprec + bo_shift < (unsigned) limb_prec)
3221 : {
3222 12 : tree ftype
3223 12 : = build_nonstandard_integer_type (rprec + bo_shift, 1);
3224 12 : tree bfr
3225 24 : = build_bit_field_ref (ftype, unshare_expr (nlhs),
3226 : rprec + bo_shift,
3227 : bitint_big_endian
3228 0 : ? bo_idx * limb_prec + bo_bit
3229 12 : : (bo_idx + tprec / limb_prec)
3230 12 : * limb_prec);
3231 12 : tree t = add_cast (ftype, rhs1);
3232 12 : g = gimple_build_assign (bfr, t);
3233 12 : done = true;
3234 12 : bf_cur = NULL_TREE;
3235 : }
3236 12 : else if (rprec + bo_shift == (unsigned) limb_prec)
3237 : bf_cur = NULL_TREE;
3238 : }
3239 : /* Otherwise, stores to any other lhs. */
3240 12 : if (!done)
3241 : {
3242 214 : tree l = limb_access (nlhs ? NULL_TREE : lhs_type,
3243 : nlhs ? nlhs : lhs, idx, true);
3244 :
3245 184 : if (bitint_extended
3246 0 : && sext
3247 0 : && TYPE_UNSIGNED (lhs_type)
3248 0 : && tree_fits_uhwi_p (idx)
3249 184 : && !nlhs)
3250 : {
3251 0 : rhs1 = add_cast (limb_access_type (lhs_type, idx), rhs1);
3252 0 : rhs1 = add_cast (TREE_TYPE (l), rhs1);
3253 : }
3254 :
3255 184 : g = gimple_build_assign (l, rhs1);
3256 : }
3257 196 : insert_before (g);
3258 196 : if (eh)
3259 : {
3260 0 : maybe_duplicate_eh_stmt (g, stmt);
3261 0 : if (eh_pad)
3262 : {
3263 0 : edge e = split_block (gsi_bb (m_gsi), g);
3264 0 : m_gsi = gsi_after_labels (e->dest);
3265 0 : add_eh_edge (e->src, find_edge (gimple_bb (stmt), eh_pad));
3266 : }
3267 : }
3268 196 : if (kind == bitint_prec_huge && i == (bo_shift != 0))
3269 : {
3270 80 : g = gimple_build_assign (idx_next, PLUS_EXPR, idx,
3271 : bitint_big_endian
3272 0 : ? size_int (-1) : size_one_node);
3273 80 : insert_before (g);
3274 : /* For big-endian, if bo_idx + total - 1 - end is all ones, then
3275 : compare idx (which is equal to idx_next + 1) against 0
3276 : instead. */
3277 80 : if (bitint_big_endian && bo_idx + total - end == 0)
3278 0 : g = gimple_build_cond (NE_EXPR, idx, size_zero_node,
3279 : NULL_TREE, NULL_TREE);
3280 : else
3281 80 : g = gimple_build_cond (NE_EXPR, idx_next,
3282 80 : size_int (bo_idx
3283 : + (bitint_big_endian
3284 : ? total - 1 - end
3285 : : end)),
3286 : NULL_TREE, NULL_TREE);
3287 80 : insert_before (g);
3288 80 : m_gsi = gsi_for_stmt (stmt);
3289 80 : m_bb = NULL;
3290 : }
3291 : }
3292 : }
3293 23385 : if (bf_cur != NULL_TREE)
3294 : {
3295 72 : unsigned int tprec = TYPE_PRECISION (type);
3296 72 : unsigned int rprec = (tprec + bo_shift) % limb_prec;
3297 72 : tree ftype = build_nonstandard_integer_type (rprec, 1);
3298 144 : tree bfr = build_bit_field_ref (ftype, unshare_expr (nlhs),
3299 : rprec,
3300 : bitint_big_endian
3301 0 : ? bo_idx * limb_prec + bo_bit
3302 72 : : (bo_idx + (tprec + bo_bit) / limb_prec)
3303 : * limb_prec);
3304 72 : rhs1 = bf_cur;
3305 72 : if (bf_cur != ext)
3306 : {
3307 64 : rhs1 = make_ssa_name (TREE_TYPE (rhs1));
3308 64 : g = gimple_build_assign (rhs1, RSHIFT_EXPR, bf_cur,
3309 : build_int_cst (unsigned_type_node,
3310 64 : limb_prec - bo_shift));
3311 64 : insert_before (g);
3312 : }
3313 72 : rhs1 = add_cast (ftype, rhs1);
3314 72 : g = gimple_build_assign (bfr, rhs1);
3315 72 : insert_before (g);
3316 72 : if (eh)
3317 : {
3318 0 : maybe_duplicate_eh_stmt (g, stmt);
3319 0 : if (eh_pad)
3320 : {
3321 0 : edge e = split_block (gsi_bb (m_gsi), g);
3322 0 : m_gsi = gsi_after_labels (e->dest);
3323 0 : add_eh_edge (e->src, find_edge (gimple_bb (stmt), eh_pad));
3324 : }
3325 : }
3326 : }
3327 23385 : if (zero_ms_limb)
3328 : {
3329 0 : tree p2 = build_int_cst (sizetype,
3330 0 : CEIL ((unsigned) TYPE_PRECISION (type),
3331 : abi_limb_prec)
3332 0 : * abi_limb_prec / limb_prec - 1);
3333 0 : tree l = limb_access (lhs_type, lhs, p2, true);
3334 0 : g = gimple_build_assign (l, build_zero_cst (m_limb_type));
3335 0 : insert_before (g);
3336 0 : if (eh)
3337 : {
3338 0 : maybe_duplicate_eh_stmt (g, stmt);
3339 0 : if (eh_pad)
3340 : {
3341 0 : edge e = split_block (gsi_bb (m_gsi), g);
3342 0 : m_gsi = gsi_after_labels (e->dest);
3343 0 : add_eh_edge (e->src, find_edge (gimple_bb (stmt), eh_pad));
3344 : }
3345 : }
3346 : }
3347 :
3348 23385 : if (gimple_store_p (stmt))
3349 : {
3350 8524 : unlink_stmt_vdef (stmt);
3351 17048 : release_ssa_name (gimple_vdef (stmt));
3352 8524 : gsi_remove (&m_gsi, true);
3353 : }
3354 23385 : if (eq_p)
3355 : {
3356 6552 : lhs = make_ssa_name (boolean_type_node);
3357 6552 : basic_block bb = gimple_bb (stmt);
3358 6552 : gphi *phi = create_phi_node (lhs, bb);
3359 6552 : edge e = find_edge (gsi_bb (m_gsi), bb);
3360 6552 : unsigned int n = EDGE_COUNT (bb->preds);
3361 32949 : for (unsigned int i = 0; i < n; i++)
3362 : {
3363 26397 : edge e2 = EDGE_PRED (bb, i);
3364 26397 : add_phi_arg (phi, e == e2 ? boolean_true_node : boolean_false_node,
3365 : e2, UNKNOWN_LOCATION);
3366 : }
3367 6552 : cmp_code = cmp_code == EQ_EXPR ? NE_EXPR : EQ_EXPR;
3368 6552 : return lhs;
3369 : }
3370 : else
3371 : return NULL_TREE;
3372 : }
3373 :
3374 : /* Handle a large/huge _BitInt comparison statement STMT other than
3375 : EQ_EXPR/NE_EXPR. CMP_CODE, CMP_OP1 and CMP_OP2 meaning is like in
3376 : lower_mergeable_stmt. The {GT,GE,LT,LE}_EXPR comparisons are
3377 : lowered by iteration from the most significant limb downwards to
3378 : the least significant one, for large _BitInt in straight line code,
3379 : otherwise with most significant limb handled in
3380 : straight line code followed by a loop handling one limb at a time.
3381 : Comparisons with unsigned huge _BitInt with precisions which are
3382 : multiples of limb precision can use just the loop and don't need to
3383 : handle most significant limb before the loop. The loop or straight
3384 : line code jumps to final basic block if a particular pair of limbs
3385 : is not equal. */
3386 :
3387 : tree
3388 722 : bitint_large_huge::lower_comparison_stmt (gimple *stmt, tree_code &cmp_code,
3389 : tree cmp_op1, tree cmp_op2)
3390 : {
3391 722 : tree type = TREE_TYPE (cmp_op1);
3392 722 : gcc_assert (BITINT_TYPE_P (type));
3393 722 : bitint_prec_kind kind = bitint_precision_kind (type);
3394 722 : gcc_assert (kind >= bitint_prec_large);
3395 722 : gimple *g;
3396 722 : if (!TYPE_UNSIGNED (type)
3397 441 : && integer_zerop (cmp_op2)
3398 750 : && (cmp_code == GE_EXPR || cmp_code == LT_EXPR))
3399 : {
3400 28 : unsigned end = CEIL ((unsigned) TYPE_PRECISION (type), limb_prec) - 1;
3401 56 : tree idx = size_int (bitint_big_endian ? 0 : end);
3402 28 : m_data_cnt = 0;
3403 28 : tree rhs1 = handle_operand (cmp_op1, idx);
3404 28 : if (TYPE_UNSIGNED (TREE_TYPE (rhs1)))
3405 : {
3406 24 : tree stype = signed_type_for (TREE_TYPE (rhs1));
3407 24 : rhs1 = add_cast (stype, rhs1);
3408 : }
3409 28 : tree lhs = make_ssa_name (boolean_type_node);
3410 28 : g = gimple_build_assign (lhs, cmp_code, rhs1,
3411 28 : build_zero_cst (TREE_TYPE (rhs1)));
3412 28 : insert_before (g);
3413 28 : cmp_code = NE_EXPR;
3414 28 : return lhs;
3415 : }
3416 :
3417 694 : unsigned cnt, rem = 0, end = 0;
3418 694 : tree idx = NULL_TREE, idx_next = NULL_TREE;
3419 694 : if (kind == bitint_prec_large)
3420 377 : cnt = CEIL ((unsigned) TYPE_PRECISION (type), limb_prec);
3421 : else
3422 : {
3423 317 : rem = ((unsigned) TYPE_PRECISION (type) % limb_prec);
3424 317 : if (rem == 0 && !TYPE_UNSIGNED (type))
3425 : rem = limb_prec;
3426 317 : end = ((unsigned) TYPE_PRECISION (type) - rem) / limb_prec;
3427 317 : cnt = 1 + (rem != 0);
3428 : }
3429 :
3430 694 : basic_block edge_bb = NULL;
3431 694 : gimple_stmt_iterator gsi = gsi_for_stmt (stmt);
3432 694 : gsi_prev (&gsi);
3433 694 : edge e = split_block (gsi_bb (gsi), gsi_stmt (gsi));
3434 694 : edge_bb = e->src;
3435 694 : m_gsi = gsi_end_bb (edge_bb);
3436 :
3437 694 : edge *edges = XALLOCAVEC (edge, cnt * 2);
3438 2519 : for (unsigned i = 0; i < cnt; i++)
3439 : {
3440 1825 : m_data_cnt = 0;
3441 1825 : if (kind == bitint_prec_large)
3442 1246 : idx = size_int (bitint_big_endian ? i : cnt - i - 1);
3443 579 : else if (i == cnt - 1)
3444 317 : idx = create_loop (size_int (bitint_big_endian ? cnt - 1 : end - 1),
3445 : &idx_next);
3446 : else
3447 524 : idx = size_int (bitint_big_endian ? 0 : end);
3448 1825 : tree rhs1 = handle_operand (cmp_op1, idx);
3449 1825 : tree rhs2 = handle_operand (cmp_op2, idx);
3450 1825 : if (i == 0
3451 694 : && !TYPE_UNSIGNED (type)
3452 2238 : && TYPE_UNSIGNED (TREE_TYPE (rhs1)))
3453 : {
3454 112 : tree stype = signed_type_for (TREE_TYPE (rhs1));
3455 112 : rhs1 = add_cast (stype, rhs1);
3456 112 : rhs2 = add_cast (stype, rhs2);
3457 : }
3458 1825 : g = gimple_build_cond (GT_EXPR, rhs1, rhs2, NULL_TREE, NULL_TREE);
3459 1825 : insert_before (g);
3460 1825 : edge e1 = split_block (gsi_bb (m_gsi), g);
3461 1825 : e1->flags = EDGE_FALSE_VALUE;
3462 1825 : edge e2 = make_edge (e1->src, gimple_bb (stmt), EDGE_TRUE_VALUE);
3463 1825 : e1->probability = profile_probability::likely ();
3464 1825 : e2->probability = e1->probability.invert ();
3465 1825 : if (i == 0)
3466 694 : set_immediate_dominator (CDI_DOMINATORS, e2->dest, e2->src);
3467 1825 : m_gsi = gsi_after_labels (e1->dest);
3468 1825 : edges[2 * i] = e2;
3469 1825 : g = gimple_build_cond (LT_EXPR, rhs1, rhs2, NULL_TREE, NULL_TREE);
3470 1825 : insert_before (g);
3471 1825 : e1 = split_block (gsi_bb (m_gsi), g);
3472 1825 : e1->flags = EDGE_FALSE_VALUE;
3473 1825 : e2 = make_edge (e1->src, gimple_bb (stmt), EDGE_TRUE_VALUE);
3474 1825 : e1->probability = profile_probability::unlikely ();
3475 1825 : e2->probability = e1->probability.invert ();
3476 1825 : m_gsi = gsi_after_labels (e1->dest);
3477 1825 : edges[2 * i + 1] = e2;
3478 1825 : m_first = false;
3479 1825 : if (kind == bitint_prec_huge && i == cnt - 1)
3480 : {
3481 634 : g = gimple_build_assign (idx_next, PLUS_EXPR, idx,
3482 : bitint_big_endian ? size_one_node
3483 317 : : size_int (-1));
3484 317 : insert_before (g);
3485 317 : g = gimple_build_cond (NE_EXPR, idx,
3486 : bitint_big_endian
3487 0 : ? size_int (end - 1 + (cnt != 1))
3488 : : size_zero_node,
3489 : NULL_TREE, NULL_TREE);
3490 317 : insert_before (g);
3491 317 : edge true_edge, false_edge;
3492 317 : extract_true_false_edges_from_block (gsi_bb (m_gsi),
3493 : &true_edge, &false_edge);
3494 317 : m_gsi = gsi_after_labels (false_edge->dest);
3495 317 : m_bb = NULL;
3496 : }
3497 : }
3498 :
3499 694 : tree lhs = make_ssa_name (boolean_type_node);
3500 694 : basic_block bb = gimple_bb (stmt);
3501 694 : gphi *phi = create_phi_node (lhs, bb);
3502 5038 : for (unsigned int i = 0; i < cnt * 2; i++)
3503 : {
3504 3650 : tree val = ((cmp_code == GT_EXPR || cmp_code == GE_EXPR)
3505 3650 : ^ (i & 1)) ? boolean_true_node : boolean_false_node;
3506 3650 : add_phi_arg (phi, val, edges[i], UNKNOWN_LOCATION);
3507 : }
3508 694 : add_phi_arg (phi, (cmp_code == GE_EXPR || cmp_code == LE_EXPR)
3509 : ? boolean_true_node : boolean_false_node,
3510 : find_edge (gsi_bb (m_gsi), bb), UNKNOWN_LOCATION);
3511 694 : cmp_code = NE_EXPR;
3512 694 : return lhs;
3513 : }
3514 :
3515 : /* Lower large/huge _BitInt left and right shift except for left
3516 : shift by < limb_prec constant. */
3517 :
3518 : void
3519 584 : bitint_large_huge::lower_shift_stmt (tree obj, gimple *stmt)
3520 : {
3521 584 : tree rhs1 = gimple_assign_rhs1 (stmt);
3522 584 : tree lhs = gimple_assign_lhs (stmt);
3523 584 : tree_code rhs_code = gimple_assign_rhs_code (stmt);
3524 584 : tree type = TREE_TYPE (rhs1);
3525 584 : gimple *final_stmt = gsi_stmt (m_gsi);
3526 584 : gcc_assert (BITINT_TYPE_P (type)
3527 : && bitint_precision_kind (type) >= bitint_prec_large);
3528 584 : int prec = TYPE_PRECISION (type);
3529 584 : tree n = gimple_assign_rhs2 (stmt), n1, n2, n3, n4;
3530 584 : gimple *g;
3531 584 : if (obj == NULL_TREE)
3532 : {
3533 465 : int part = var_to_partition (m_map, lhs);
3534 465 : gcc_assert (m_vars[part] != NULL_TREE);
3535 : obj = m_vars[part];
3536 : }
3537 : /* Preparation code common for both left and right shifts.
3538 : unsigned n1 = n % limb_prec;
3539 : size_t n2 = n / limb_prec;
3540 : size_t n3 = n1 != 0;
3541 : unsigned n4 = (limb_prec - n1) % limb_prec;
3542 : (for power of 2 limb_prec n4 can be -n1 & limb_prec). */
3543 584 : if (TREE_CODE (n) == INTEGER_CST)
3544 : {
3545 249 : tree lp = build_int_cst (TREE_TYPE (n), limb_prec);
3546 249 : n1 = int_const_binop (TRUNC_MOD_EXPR, n, lp);
3547 249 : n2 = fold_convert (sizetype, int_const_binop (TRUNC_DIV_EXPR, n, lp));
3548 249 : n3 = size_int (!integer_zerop (n1));
3549 249 : n4 = int_const_binop (TRUNC_MOD_EXPR,
3550 249 : int_const_binop (MINUS_EXPR, lp, n1), lp);
3551 : }
3552 : else
3553 : {
3554 335 : n1 = make_ssa_name (TREE_TYPE (n));
3555 335 : n2 = make_ssa_name (sizetype);
3556 335 : n3 = make_ssa_name (sizetype);
3557 335 : n4 = make_ssa_name (TREE_TYPE (n));
3558 335 : if (pow2p_hwi (limb_prec))
3559 : {
3560 335 : tree lpm1 = build_int_cst (TREE_TYPE (n), limb_prec - 1);
3561 335 : g = gimple_build_assign (n1, BIT_AND_EXPR, n, lpm1);
3562 335 : insert_before (g);
3563 989 : g = gimple_build_assign (useless_type_conversion_p (sizetype,
3564 335 : TREE_TYPE (n))
3565 319 : ? n2 : make_ssa_name (TREE_TYPE (n)),
3566 : RSHIFT_EXPR, n,
3567 335 : build_int_cst (TREE_TYPE (n),
3568 670 : exact_log2 (limb_prec)));
3569 335 : insert_before (g);
3570 335 : if (gimple_assign_lhs (g) != n2)
3571 : {
3572 319 : g = gimple_build_assign (n2, NOP_EXPR, gimple_assign_lhs (g));
3573 319 : insert_before (g);
3574 : }
3575 335 : g = gimple_build_assign (make_ssa_name (TREE_TYPE (n)),
3576 : NEGATE_EXPR, n1);
3577 335 : insert_before (g);
3578 335 : g = gimple_build_assign (n4, BIT_AND_EXPR, gimple_assign_lhs (g),
3579 : lpm1);
3580 335 : insert_before (g);
3581 : }
3582 : else
3583 : {
3584 0 : tree lp = build_int_cst (TREE_TYPE (n), limb_prec);
3585 0 : g = gimple_build_assign (n1, TRUNC_MOD_EXPR, n, lp);
3586 0 : insert_before (g);
3587 0 : g = gimple_build_assign (useless_type_conversion_p (sizetype,
3588 0 : TREE_TYPE (n))
3589 0 : ? n2 : make_ssa_name (TREE_TYPE (n)),
3590 : TRUNC_DIV_EXPR, n, lp);
3591 0 : insert_before (g);
3592 0 : if (gimple_assign_lhs (g) != n2)
3593 : {
3594 0 : g = gimple_build_assign (n2, NOP_EXPR, gimple_assign_lhs (g));
3595 0 : insert_before (g);
3596 : }
3597 0 : g = gimple_build_assign (make_ssa_name (TREE_TYPE (n)),
3598 : MINUS_EXPR, lp, n1);
3599 0 : insert_before (g);
3600 0 : g = gimple_build_assign (n4, TRUNC_MOD_EXPR, gimple_assign_lhs (g),
3601 : lp);
3602 0 : insert_before (g);
3603 : }
3604 335 : g = gimple_build_assign (make_ssa_name (boolean_type_node), NE_EXPR, n1,
3605 335 : build_zero_cst (TREE_TYPE (n)));
3606 335 : insert_before (g);
3607 335 : g = gimple_build_assign (n3, NOP_EXPR, gimple_assign_lhs (g));
3608 335 : insert_before (g);
3609 : }
3610 1168 : tree p = build_int_cst (sizetype,
3611 584 : prec / limb_prec - (prec % limb_prec == 0));
3612 584 : if (rhs_code == RSHIFT_EXPR)
3613 : {
3614 : /* Lower
3615 : dst = src >> n;
3616 : as
3617 : unsigned n1 = n % limb_prec;
3618 : size_t n2 = n / limb_prec;
3619 : size_t n3 = n1 != 0;
3620 : unsigned n4 = (limb_prec - n1) % limb_prec;
3621 : size_t idx;
3622 : size_t p = prec / limb_prec - (prec % limb_prec == 0);
3623 : int signed_p = (typeof (src) -1) < 0;
3624 : for (idx = n2; idx < ((!signed_p && (prec % limb_prec == 0))
3625 : ? p : p - n3); ++idx)
3626 : dst[idx - n2] = (src[idx] >> n1) | (src[idx + n3] << n4);
3627 : limb_type ext;
3628 : if (prec % limb_prec == 0)
3629 : ext = src[p];
3630 : else if (signed_p)
3631 : ext = ((signed limb_type) (src[p] << (limb_prec
3632 : - (prec % limb_prec))))
3633 : >> (limb_prec - (prec % limb_prec));
3634 : else
3635 : ext = src[p] & (((limb_type) 1 << (prec % limb_prec)) - 1);
3636 : if (!signed_p && (prec % limb_prec == 0))
3637 : ;
3638 : else if (idx < prec / 64)
3639 : {
3640 : dst[idx - n2] = (src[idx] >> n1) | (ext << n4);
3641 : ++idx;
3642 : }
3643 : idx -= n2;
3644 : if (signed_p)
3645 : {
3646 : dst[idx] = ((signed limb_type) ext) >> n1;
3647 : ext = ((signed limb_type) ext) >> (limb_prec - 1);
3648 : }
3649 : else
3650 : {
3651 : dst[idx] = ext >> n1;
3652 : ext = 0;
3653 : }
3654 : for (++idx; idx <= p; ++idx)
3655 : dst[idx] = ext; */
3656 387 : tree pmn3;
3657 387 : if (TYPE_UNSIGNED (type) && prec % limb_prec == 0)
3658 100 : pmn3 = bitint_big_endian ? size_zero_node : p;
3659 287 : else if (bitint_big_endian)
3660 : pmn3 = n3;
3661 287 : else if (TREE_CODE (n3) == INTEGER_CST)
3662 114 : pmn3 = int_const_binop (MINUS_EXPR, p, n3);
3663 : else
3664 : {
3665 173 : pmn3 = make_ssa_name (sizetype);
3666 173 : g = gimple_build_assign (pmn3, MINUS_EXPR, p, n3);
3667 173 : insert_before (g);
3668 : }
3669 387 : tree pmn2 = NULL_TREE;
3670 387 : if (bitint_big_endian)
3671 : {
3672 0 : if (TREE_CODE (n2) == INTEGER_CST)
3673 0 : pmn2 = int_const_binop (MINUS_EXPR, p, n2);
3674 : else
3675 : {
3676 0 : pmn2 = make_ssa_name (sizetype);
3677 0 : g = gimple_build_assign (pmn2, MINUS_EXPR, p, n2);
3678 0 : insert_before (g);
3679 : }
3680 0 : g = gimple_build_cond (GT_EXPR, pmn2, pmn3, NULL_TREE, NULL_TREE);
3681 : }
3682 : else
3683 387 : g = gimple_build_cond (LT_EXPR, n2, pmn3, NULL_TREE, NULL_TREE);
3684 387 : edge edge_true, edge_false;
3685 387 : if_then (g, profile_probability::likely (), edge_true, edge_false);
3686 387 : tree idx_next;
3687 774 : tree idx = create_loop (bitint_big_endian ? pmn2 : n2, &idx_next);
3688 387 : tree idxmn2 = make_ssa_name (sizetype);
3689 387 : tree idxpn3 = make_ssa_name (sizetype);
3690 774 : g = gimple_build_assign (idxmn2,
3691 : bitint_big_endian ? PLUS_EXPR : MINUS_EXPR,
3692 : idx, n2);
3693 387 : insert_before (g);
3694 774 : g = gimple_build_assign (idxpn3,
3695 : bitint_big_endian ? MINUS_EXPR : PLUS_EXPR,
3696 : idx, n3);
3697 387 : insert_before (g);
3698 387 : m_data_cnt = 0;
3699 387 : tree t1 = handle_operand (rhs1, idx);
3700 387 : m_first = false;
3701 387 : g = gimple_build_assign (make_ssa_name (m_limb_type),
3702 : RSHIFT_EXPR, t1, n1);
3703 387 : insert_before (g);
3704 387 : t1 = gimple_assign_lhs (g);
3705 387 : if (!integer_zerop (n3))
3706 : {
3707 299 : m_data_cnt = 0;
3708 299 : tree t2 = handle_operand (rhs1, idxpn3);
3709 299 : g = gimple_build_assign (make_ssa_name (m_limb_type),
3710 : LSHIFT_EXPR, t2, n4);
3711 299 : insert_before (g);
3712 299 : t2 = gimple_assign_lhs (g);
3713 299 : g = gimple_build_assign (make_ssa_name (m_limb_type),
3714 : BIT_IOR_EXPR, t1, t2);
3715 299 : insert_before (g);
3716 299 : t1 = gimple_assign_lhs (g);
3717 : }
3718 387 : tree l = limb_access (TREE_TYPE (lhs), obj, idxmn2, true);
3719 387 : g = gimple_build_assign (l, t1);
3720 387 : insert_before (g);
3721 387 : g = gimple_build_assign (idx_next, PLUS_EXPR, idx,
3722 0 : bitint_big_endian ? size_int (-1)
3723 : : size_one_node);
3724 387 : insert_before (g);
3725 774 : g = gimple_build_cond (bitint_big_endian ? GT_EXPR : LT_EXPR,
3726 : idx_next, pmn3, NULL_TREE, NULL_TREE);
3727 387 : insert_before (g);
3728 387 : idx = make_ssa_name (sizetype);
3729 387 : m_gsi = gsi_for_stmt (final_stmt);
3730 387 : gphi *phi = create_phi_node (idx, gsi_bb (m_gsi));
3731 387 : edge_false = find_edge (edge_false->src, gsi_bb (m_gsi));
3732 387 : edge_true = EDGE_PRED (gsi_bb (m_gsi),
3733 : EDGE_PRED (gsi_bb (m_gsi), 0) == edge_false);
3734 774 : add_phi_arg (phi, bitint_big_endian ? pmn2 : n2, edge_false,
3735 : UNKNOWN_LOCATION);
3736 387 : add_phi_arg (phi, idx_next, edge_true, UNKNOWN_LOCATION);
3737 387 : m_data_cnt = 0;
3738 387 : tree ms = handle_operand (rhs1, bitint_big_endian ? size_zero_node : p);
3739 387 : tree ext = ms;
3740 387 : if (!types_compatible_p (TREE_TYPE (ms), m_limb_type))
3741 230 : ext = add_cast (m_limb_type, ms);
3742 587 : if (!(TYPE_UNSIGNED (type) && prec % limb_prec == 0)
3743 487 : && !integer_zerop (n3))
3744 : {
3745 249 : if (bitint_big_endian)
3746 0 : g = gimple_build_cond (GT_EXPR, idx, size_zero_node,
3747 : NULL_TREE, NULL_TREE);
3748 : else
3749 249 : g = gimple_build_cond (LT_EXPR, idx, p, NULL_TREE, NULL_TREE);
3750 249 : if_then (g, profile_probability::likely (), edge_true, edge_false);
3751 249 : m_data_cnt = 0;
3752 249 : t1 = handle_operand (rhs1, idx);
3753 249 : g = gimple_build_assign (make_ssa_name (m_limb_type),
3754 : RSHIFT_EXPR, t1, n1);
3755 249 : insert_before (g);
3756 249 : t1 = gimple_assign_lhs (g);
3757 249 : g = gimple_build_assign (make_ssa_name (m_limb_type),
3758 : LSHIFT_EXPR, ext, n4);
3759 249 : insert_before (g);
3760 249 : tree t2 = gimple_assign_lhs (g);
3761 249 : g = gimple_build_assign (make_ssa_name (m_limb_type),
3762 : BIT_IOR_EXPR, t1, t2);
3763 249 : insert_before (g);
3764 249 : t1 = gimple_assign_lhs (g);
3765 249 : idxmn2 = make_ssa_name (sizetype);
3766 498 : g = gimple_build_assign (idxmn2, bitint_big_endian
3767 : ? PLUS_EXPR : MINUS_EXPR, idx, n2);
3768 249 : insert_before (g);
3769 249 : l = limb_access (TREE_TYPE (lhs), obj, idxmn2, true);
3770 249 : g = gimple_build_assign (l, t1);
3771 249 : insert_before (g);
3772 249 : idx_next = make_ssa_name (sizetype);
3773 249 : g = gimple_build_assign (idx_next, PLUS_EXPR, idx,
3774 : bitint_big_endian
3775 0 : ? size_int (-1) : size_one_node);
3776 249 : insert_before (g);
3777 249 : m_gsi = gsi_for_stmt (final_stmt);
3778 249 : tree nidx = make_ssa_name (sizetype);
3779 249 : phi = create_phi_node (nidx, gsi_bb (m_gsi));
3780 249 : edge_false = find_edge (edge_false->src, gsi_bb (m_gsi));
3781 249 : edge_true = EDGE_PRED (gsi_bb (m_gsi),
3782 : EDGE_PRED (gsi_bb (m_gsi), 0) == edge_false);
3783 249 : add_phi_arg (phi, idx, edge_false, UNKNOWN_LOCATION);
3784 249 : add_phi_arg (phi, idx_next, edge_true, UNKNOWN_LOCATION);
3785 249 : idx = nidx;
3786 : }
3787 774 : g = gimple_build_assign (make_ssa_name (sizetype),
3788 : bitint_big_endian ? PLUS_EXPR : MINUS_EXPR,
3789 : idx, n2);
3790 387 : insert_before (g);
3791 387 : idx = gimple_assign_lhs (g);
3792 387 : tree sext = ext;
3793 387 : if (!TYPE_UNSIGNED (type))
3794 187 : sext = add_cast (signed_type_for (m_limb_type), ext);
3795 387 : g = gimple_build_assign (make_ssa_name (TREE_TYPE (sext)),
3796 : RSHIFT_EXPR, sext, n1);
3797 387 : insert_before (g);
3798 387 : t1 = gimple_assign_lhs (g);
3799 387 : if (!TYPE_UNSIGNED (type))
3800 : {
3801 187 : t1 = add_cast (m_limb_type, t1);
3802 187 : g = gimple_build_assign (make_ssa_name (TREE_TYPE (sext)),
3803 : RSHIFT_EXPR, sext,
3804 187 : build_int_cst (TREE_TYPE (n),
3805 187 : limb_prec - 1));
3806 187 : insert_before (g);
3807 187 : ext = add_cast (m_limb_type, gimple_assign_lhs (g));
3808 : }
3809 : else
3810 200 : ext = build_zero_cst (m_limb_type);
3811 387 : l = limb_access (TREE_TYPE (lhs), obj, idx, true);
3812 387 : g = gimple_build_assign (l, t1);
3813 387 : insert_before (g);
3814 387 : g = gimple_build_assign (make_ssa_name (sizetype), PLUS_EXPR, idx,
3815 : bitint_big_endian
3816 0 : ? size_int (-1) : size_one_node);
3817 387 : insert_before (g);
3818 387 : tree p2 = p;
3819 387 : if (bitint_big_endian)
3820 : {
3821 0 : tree new_idx = gimple_assign_lhs (g);
3822 0 : g = gimple_build_cond (NE_EXPR, idx, size_zero_node,
3823 : NULL_TREE, NULL_TREE);
3824 0 : idx = new_idx;
3825 : }
3826 : else
3827 : {
3828 387 : if (bitint_extended == bitint_ext_full
3829 0 : && abi_limb_prec > limb_prec)
3830 0 : p2 = build_int_cst (sizetype,
3831 0 : CEIL (prec, abi_limb_prec)
3832 0 : * abi_limb_prec / limb_prec - 1);
3833 387 : idx = gimple_assign_lhs (g);
3834 387 : g = gimple_build_cond (LE_EXPR, idx, p2, NULL_TREE, NULL_TREE);
3835 : }
3836 387 : if_then (g, profile_probability::likely (), edge_true, edge_false);
3837 387 : idx = create_loop (idx, &idx_next);
3838 387 : l = limb_access (TREE_TYPE (lhs), obj, idx, true);
3839 387 : g = gimple_build_assign (l, ext);
3840 387 : insert_before (g);
3841 387 : g = gimple_build_assign (idx_next, PLUS_EXPR, idx,
3842 : bitint_big_endian
3843 0 : ? size_int (-1) : size_one_node);
3844 387 : insert_before (g);
3845 387 : if (bitint_big_endian)
3846 0 : g = gimple_build_cond (NE_EXPR, idx, size_zero_node,
3847 : NULL_TREE, NULL_TREE);
3848 : else
3849 387 : g = gimple_build_cond (LE_EXPR, idx_next, p2, NULL_TREE, NULL_TREE);
3850 387 : insert_before (g);
3851 : }
3852 : else
3853 : {
3854 : /* Lower
3855 : dst = src << n;
3856 : as
3857 : unsigned n1 = n % limb_prec;
3858 : size_t n2 = n / limb_prec;
3859 : size_t n3 = n1 != 0;
3860 : unsigned n4 = (limb_prec - n1) % limb_prec;
3861 : size_t idx;
3862 : size_t p = prec / limb_prec - (prec % limb_prec == 0);
3863 : for (idx = p; (ssize_t) idx >= (ssize_t) (n2 + n3); --idx)
3864 : dst[idx] = (src[idx - n2] << n1) | (src[idx - n2 - n3] >> n4);
3865 : if (n1)
3866 : {
3867 : dst[idx] = src[idx - n2] << n1;
3868 : --idx;
3869 : }
3870 : for (; (ssize_t) idx >= 0; --idx)
3871 : dst[idx] = 0; */
3872 197 : tree n2pn3;
3873 197 : if (TREE_CODE (n2) == INTEGER_CST && TREE_CODE (n3) == INTEGER_CST)
3874 71 : n2pn3 = int_const_binop (PLUS_EXPR, n2, n3);
3875 : else
3876 : {
3877 126 : n2pn3 = make_ssa_name (sizetype);
3878 126 : g = gimple_build_assign (n2pn3, PLUS_EXPR, n2, n3);
3879 126 : insert_before (g);
3880 : }
3881 197 : if (bitint_big_endian)
3882 : {
3883 0 : if (TREE_CODE (n2pn3) == INTEGER_CST)
3884 0 : n2pn3 = int_const_binop (MINUS_EXPR, p, n2pn3);
3885 : else
3886 : {
3887 0 : g = gimple_build_assign (make_ssa_name (sizetype),
3888 : MINUS_EXPR, p, n2pn3);
3889 0 : insert_before (g);
3890 0 : n2pn3 = gimple_assign_lhs (g);
3891 : }
3892 : }
3893 : /* For LSHIFT_EXPR, we can use handle_operand with non-INTEGER_CST
3894 : idx even to access the most significant partial limb. */
3895 197 : m_var_msb = true;
3896 197 : if (integer_zerop (n3))
3897 : /* For n3 == 0 p >= n2 + n3 is always true for all valid shift
3898 : counts. Emit if (true) condition that can be optimized later. */
3899 45 : g = gimple_build_cond (NE_EXPR, boolean_true_node, boolean_false_node,
3900 : NULL_TREE, NULL_TREE);
3901 152 : else if (bitint_big_endian)
3902 0 : g = gimple_build_cond (NE_EXPR, n2pn3, size_int (-1), NULL_TREE,
3903 : NULL_TREE);
3904 : else
3905 152 : g = gimple_build_cond (LE_EXPR, n2pn3, p, NULL_TREE, NULL_TREE);
3906 197 : edge edge_true, edge_false;
3907 197 : if_then (g, profile_probability::likely (), edge_true, edge_false);
3908 197 : tree idx_next;
3909 197 : tree idx = create_loop (bitint_big_endian ? size_zero_node : p,
3910 : &idx_next);
3911 197 : tree idxmn2 = make_ssa_name (sizetype);
3912 197 : tree idxmn2mn3 = make_ssa_name (sizetype);
3913 394 : g = gimple_build_assign (idxmn2,
3914 : bitint_big_endian ? PLUS_EXPR : MINUS_EXPR,
3915 : idx, n2);
3916 197 : insert_before (g);
3917 394 : g = gimple_build_assign (idxmn2mn3,
3918 : bitint_big_endian ? PLUS_EXPR : MINUS_EXPR,
3919 : idxmn2, n3);
3920 197 : insert_before (g);
3921 197 : m_data_cnt = 0;
3922 197 : tree t1 = handle_operand (rhs1, idxmn2);
3923 197 : m_first = false;
3924 197 : g = gimple_build_assign (make_ssa_name (m_limb_type),
3925 : LSHIFT_EXPR, t1, n1);
3926 197 : insert_before (g);
3927 197 : t1 = gimple_assign_lhs (g);
3928 197 : if (!integer_zerop (n3))
3929 : {
3930 152 : m_data_cnt = 0;
3931 152 : tree t2 = handle_operand (rhs1, idxmn2mn3);
3932 152 : g = gimple_build_assign (make_ssa_name (m_limb_type),
3933 : RSHIFT_EXPR, t2, n4);
3934 152 : insert_before (g);
3935 152 : t2 = gimple_assign_lhs (g);
3936 152 : g = gimple_build_assign (make_ssa_name (m_limb_type),
3937 : BIT_IOR_EXPR, t1, t2);
3938 152 : insert_before (g);
3939 152 : t1 = gimple_assign_lhs (g);
3940 : }
3941 197 : tree l = limb_access (TREE_TYPE (lhs), obj, idx, true);
3942 197 : g = gimple_build_assign (l, t1);
3943 197 : insert_before (g);
3944 394 : g = gimple_build_assign (idx_next, PLUS_EXPR, idx,
3945 : bitint_big_endian
3946 197 : ? size_one_node : size_int (-1));
3947 197 : insert_before (g);
3948 197 : tree sn2pn3 = add_cast (ssizetype, n2pn3);
3949 394 : g = gimple_build_cond (bitint_big_endian ? LE_EXPR : GE_EXPR,
3950 : add_cast (ssizetype, idx_next), sn2pn3,
3951 : NULL_TREE, NULL_TREE);
3952 197 : insert_before (g);
3953 197 : idx = make_ssa_name (sizetype);
3954 197 : m_gsi = gsi_for_stmt (final_stmt);
3955 197 : gphi *phi = create_phi_node (idx, gsi_bb (m_gsi));
3956 197 : edge_false = find_edge (edge_false->src, gsi_bb (m_gsi));
3957 197 : edge_true = EDGE_PRED (gsi_bb (m_gsi),
3958 : EDGE_PRED (gsi_bb (m_gsi), 0) == edge_false);
3959 197 : add_phi_arg (phi, bitint_big_endian ? size_zero_node : p,
3960 : edge_false, UNKNOWN_LOCATION);
3961 197 : add_phi_arg (phi, idx_next, edge_true, UNKNOWN_LOCATION);
3962 197 : m_data_cnt = 0;
3963 197 : if (!integer_zerop (n3))
3964 : {
3965 152 : g = gimple_build_cond (NE_EXPR, n3, size_zero_node,
3966 : NULL_TREE, NULL_TREE);
3967 152 : if_then (g, profile_probability::likely (), edge_true, edge_false);
3968 152 : idxmn2 = make_ssa_name (sizetype);
3969 304 : g = gimple_build_assign (idxmn2,
3970 : bitint_big_endian ? PLUS_EXPR : MINUS_EXPR,
3971 : idx, n2);
3972 152 : insert_before (g);
3973 152 : m_data_cnt = 0;
3974 152 : t1 = handle_operand (rhs1, idxmn2);
3975 152 : g = gimple_build_assign (make_ssa_name (m_limb_type),
3976 : LSHIFT_EXPR, t1, n1);
3977 152 : insert_before (g);
3978 152 : t1 = gimple_assign_lhs (g);
3979 152 : l = limb_access (TREE_TYPE (lhs), obj, idx, true);
3980 152 : g = gimple_build_assign (l, t1);
3981 152 : insert_before (g);
3982 152 : idx_next = make_ssa_name (sizetype);
3983 304 : g = gimple_build_assign (idx_next, PLUS_EXPR, idx,
3984 : bitint_big_endian
3985 152 : ? size_one_node : size_int (-1));
3986 152 : insert_before (g);
3987 152 : m_gsi = gsi_for_stmt (final_stmt);
3988 152 : tree nidx = make_ssa_name (sizetype);
3989 152 : phi = create_phi_node (nidx, gsi_bb (m_gsi));
3990 152 : edge_false = find_edge (edge_false->src, gsi_bb (m_gsi));
3991 152 : edge_true = EDGE_PRED (gsi_bb (m_gsi),
3992 : EDGE_PRED (gsi_bb (m_gsi), 0) == edge_false);
3993 152 : add_phi_arg (phi, idx, edge_false, UNKNOWN_LOCATION);
3994 152 : add_phi_arg (phi, idx_next, edge_true, UNKNOWN_LOCATION);
3995 152 : idx = nidx;
3996 : }
3997 197 : if (bitint_big_endian)
3998 0 : g = gimple_build_cond (LE_EXPR, idx, p, NULL_TREE, NULL_TREE);
3999 : else
4000 197 : g = gimple_build_cond (GE_EXPR, add_cast (ssizetype, idx),
4001 : ssize_int (0), NULL_TREE, NULL_TREE);
4002 197 : if_then (g, profile_probability::likely (), edge_true, edge_false);
4003 197 : idx = create_loop (idx, &idx_next);
4004 197 : l = limb_access (TREE_TYPE (lhs), obj, idx, true);
4005 197 : g = gimple_build_assign (l, build_zero_cst (m_limb_type));
4006 197 : insert_before (g);
4007 394 : g = gimple_build_assign (idx_next, PLUS_EXPR, idx,
4008 : bitint_big_endian
4009 197 : ? size_one_node : size_int (-1));
4010 197 : insert_before (g);
4011 197 : if (bitint_big_endian)
4012 0 : g = gimple_build_cond (LE_EXPR, idx_next, p, NULL_TREE, NULL_TREE);
4013 : else
4014 197 : g = gimple_build_cond (GE_EXPR, add_cast (ssizetype, idx_next),
4015 : ssize_int (0), NULL_TREE, NULL_TREE);
4016 197 : insert_before (g);
4017 197 : if (bitint_extended && prec % limb_prec != 0)
4018 : {
4019 : /* The most significant limb has been updated either in the
4020 : loop or in the if after it. To simplify the code, just
4021 : read it back from memory and extend. */
4022 0 : m_gsi = gsi_after_labels (edge_false->dest);
4023 0 : idx = bitint_big_endian ? size_zero_node : p;
4024 0 : tree l = limb_access (TREE_TYPE (lhs), obj, idx, true);
4025 0 : tree type = limb_access_type (TREE_TYPE (lhs), idx);
4026 0 : tree v = make_ssa_name (m_limb_type);
4027 0 : g = gimple_build_assign (v, l);
4028 0 : insert_before (g);
4029 0 : v = add_cast (type, v);
4030 0 : l = limb_access (TREE_TYPE (lhs), obj, idx, true);
4031 0 : v = add_cast (m_limb_type, v);
4032 0 : g = gimple_build_assign (l, v);
4033 0 : insert_before (g);
4034 0 : if (bitint_extended == bitint_ext_full
4035 0 : && abi_limb_prec > limb_prec
4036 0 : && (CEIL (prec, abi_limb_prec) * abi_limb_prec
4037 0 : > CEIL (prec, limb_prec) * limb_prec))
4038 : {
4039 0 : tree p2 = build_int_cst (sizetype,
4040 : CEIL (prec, abi_limb_prec)
4041 0 : * abi_limb_prec / limb_prec - 1);
4042 0 : if (TYPE_UNSIGNED (TREE_TYPE (lhs)))
4043 0 : v = build_zero_cst (m_limb_type);
4044 : else
4045 : {
4046 0 : v = add_cast (signed_type_for (m_limb_type), v);
4047 0 : g = gimple_build_assign (make_ssa_name (TREE_TYPE (v)),
4048 : RSHIFT_EXPR, v,
4049 : build_int_cst (unsigned_type_node,
4050 0 : limb_prec - 1));
4051 0 : insert_before (g);
4052 0 : v = add_cast (m_limb_type, gimple_assign_lhs (g));
4053 : }
4054 0 : l = limb_access (TREE_TYPE (lhs), obj, p2, true);
4055 0 : g = gimple_build_assign (l, v);
4056 0 : insert_before (g);
4057 : }
4058 : }
4059 197 : else if (bitint_extended == bitint_ext_full
4060 0 : && abi_limb_prec > limb_prec
4061 0 : && (CEIL (prec, abi_limb_prec) * abi_limb_prec
4062 0 : > CEIL (prec, limb_prec) * limb_prec))
4063 : {
4064 0 : m_gsi = gsi_after_labels (edge_false->dest);
4065 0 : tree p2 = build_int_cst (sizetype,
4066 : CEIL (prec, abi_limb_prec)
4067 0 : * abi_limb_prec / limb_prec - 1);
4068 0 : tree v;
4069 0 : if (TYPE_UNSIGNED (TREE_TYPE (lhs)))
4070 0 : v = build_zero_cst (m_limb_type);
4071 : else
4072 : {
4073 0 : tree l = limb_access (TREE_TYPE (lhs), obj, p, true);
4074 0 : v = make_ssa_name (m_limb_type);
4075 0 : g = gimple_build_assign (v, l);
4076 0 : insert_before (g);
4077 0 : v = add_cast (signed_type_for (m_limb_type), v);
4078 0 : g = gimple_build_assign (make_ssa_name (TREE_TYPE (v)),
4079 : RSHIFT_EXPR, v,
4080 : build_int_cst (unsigned_type_node,
4081 0 : limb_prec - 1));
4082 0 : insert_before (g);
4083 0 : v = add_cast (m_limb_type, gimple_assign_lhs (g));
4084 : }
4085 0 : tree l = limb_access (TREE_TYPE (lhs), obj, p2, true);
4086 0 : g = gimple_build_assign (l, v);
4087 0 : insert_before (g);
4088 : }
4089 : }
4090 584 : }
4091 :
4092 : /* Lower large/huge _BitInt multiplication or division. */
4093 :
4094 : void
4095 371 : bitint_large_huge::lower_muldiv_stmt (tree obj, gimple *stmt)
4096 : {
4097 371 : tree rhs1 = gimple_assign_rhs1 (stmt);
4098 371 : tree rhs2 = gimple_assign_rhs2 (stmt);
4099 371 : tree lhs = gimple_assign_lhs (stmt);
4100 371 : tree_code rhs_code = gimple_assign_rhs_code (stmt);
4101 371 : tree type = TREE_TYPE (rhs1);
4102 371 : gcc_assert (BITINT_TYPE_P (type)
4103 : && bitint_precision_kind (type) >= bitint_prec_large);
4104 371 : int prec = TYPE_PRECISION (type), prec1, prec2;
4105 371 : bool ext_ms_limb = false;
4106 371 : bool do_ext = false;
4107 371 : rhs1 = handle_operand_addr (rhs1, stmt, NULL, &prec1);
4108 371 : rhs2 = handle_operand_addr (rhs2, stmt, NULL, &prec2);
4109 371 : if (obj == NULL_TREE)
4110 : {
4111 166 : int part = var_to_partition (m_map, lhs);
4112 166 : gcc_assert (m_vars[part] != NULL_TREE);
4113 166 : obj = m_vars[part];
4114 166 : lhs = build_fold_addr_expr (obj);
4115 : }
4116 : else
4117 : {
4118 205 : lhs = build_fold_addr_expr (obj);
4119 205 : lhs = force_gimple_operand_gsi (&m_gsi, lhs, true,
4120 : NULL_TREE, true, GSI_SAME_STMT);
4121 : }
4122 371 : if (bitint_extended && TYPE_OVERFLOW_WRAPS (type))
4123 : {
4124 0 : if (rhs_code == MULT_EXPR)
4125 : do_ext = true;
4126 : /* For signed division with -fwrapv, minimum negative / -1 needs
4127 : is minimum negative and the padding bits above it should be all
4128 : set. */
4129 0 : else if (!TYPE_UNSIGNED (type)
4130 0 : && (rhs_code == TRUNC_DIV_EXPR || rhs_code == EXACT_DIV_EXPR))
4131 371 : do_ext = true;
4132 : }
4133 371 : if (bitint_extended == bitint_ext_full
4134 0 : && abi_limb_prec > limb_prec
4135 0 : && (CEIL (prec, abi_limb_prec) * abi_limb_prec
4136 0 : > CEIL (prec, limb_prec) * limb_prec))
4137 : {
4138 : /* unsigned multiplication needs to wrap around, so we can't
4139 : increase prec. Similarly for -fwrapv. */
4140 0 : if (do_ext)
4141 : ext_ms_limb = true;
4142 : else
4143 0 : prec = CEIL (prec, abi_limb_prec) * abi_limb_prec;
4144 : }
4145 371 : tree sitype = lang_hooks.types.type_for_mode (SImode, 0);
4146 371 : gimple *g;
4147 371 : switch (rhs_code)
4148 : {
4149 208 : case MULT_EXPR:
4150 208 : g = gimple_build_call_internal (IFN_MULBITINT, 6,
4151 208 : lhs, build_int_cst (sitype, prec),
4152 208 : rhs1, build_int_cst (sitype, prec1),
4153 208 : rhs2, build_int_cst (sitype, prec2));
4154 208 : insert_before (g);
4155 208 : break;
4156 103 : case TRUNC_DIV_EXPR:
4157 103 : case EXACT_DIV_EXPR:
4158 103 : g = gimple_build_call_internal (IFN_DIVMODBITINT, 8,
4159 103 : lhs, build_int_cst (sitype, prec),
4160 : null_pointer_node,
4161 : build_int_cst (sitype, 0),
4162 103 : rhs1, build_int_cst (sitype, prec1),
4163 103 : rhs2, build_int_cst (sitype, prec2));
4164 103 : if (!stmt_ends_bb_p (stmt))
4165 102 : gimple_call_set_nothrow (as_a <gcall *> (g), true);
4166 103 : insert_before (g);
4167 103 : break;
4168 60 : case TRUNC_MOD_EXPR:
4169 60 : g = gimple_build_call_internal (IFN_DIVMODBITINT, 8, null_pointer_node,
4170 : build_int_cst (sitype, 0),
4171 60 : lhs, build_int_cst (sitype, prec),
4172 60 : rhs1, build_int_cst (sitype, prec1),
4173 60 : rhs2, build_int_cst (sitype, prec2));
4174 60 : if (!stmt_ends_bb_p (stmt))
4175 57 : gimple_call_set_nothrow (as_a <gcall *> (g), true);
4176 60 : insert_before (g);
4177 60 : break;
4178 0 : default:
4179 0 : gcc_unreachable ();
4180 : }
4181 371 : if (stmt_ends_bb_p (stmt))
4182 : {
4183 4 : maybe_duplicate_eh_stmt (g, stmt);
4184 4 : edge e1;
4185 4 : edge_iterator ei;
4186 4 : basic_block bb = gimple_bb (stmt);
4187 :
4188 4 : FOR_EACH_EDGE (e1, ei, bb->succs)
4189 4 : if (e1->flags & EDGE_EH)
4190 : break;
4191 4 : if (e1)
4192 : {
4193 4 : edge e2 = split_block (gsi_bb (m_gsi), g);
4194 4 : m_gsi = gsi_after_labels (e2->dest);
4195 4 : add_eh_edge (e2->src, e1);
4196 : }
4197 : }
4198 371 : if (do_ext
4199 371 : && ((prec % limb_prec) != 0 || (ext_ms_limb && !TYPE_UNSIGNED (type))))
4200 : {
4201 : /* Unsigned multiplication wraps, but libgcc function will return the
4202 : bits beyond prec within the top limb as another limb of the full
4203 : multiplication. So, clear the padding bits here. */
4204 0 : tree idx = size_int (bitint_big_endian ? 0 : prec / limb_prec);
4205 0 : tree l = limb_access (type, obj, idx, true);
4206 0 : tree ctype = limb_access_type (type, idx);
4207 0 : tree v = make_ssa_name (m_limb_type);
4208 0 : g = gimple_build_assign (v, l);
4209 0 : insert_before (g);
4210 0 : tree v2 = v;
4211 0 : if ((prec % limb_prec) != 0)
4212 : {
4213 0 : v = add_cast (ctype, v);
4214 0 : l = limb_access (type, obj, idx, true);
4215 0 : v = add_cast (m_limb_type, v);
4216 0 : v2 = v;
4217 0 : g = gimple_build_assign (l, v);
4218 0 : insert_before (g);
4219 : }
4220 0 : if (ext_ms_limb && !TYPE_UNSIGNED (type))
4221 : {
4222 0 : v2 = add_cast (signed_type_for (m_limb_type), v2);
4223 0 : tree lpm1 = build_int_cst (unsigned_type_node, limb_prec - 1);
4224 0 : v = make_ssa_name (TREE_TYPE (v2));
4225 0 : g = gimple_build_assign (v, RSHIFT_EXPR, v2, lpm1);
4226 0 : insert_before (g);
4227 0 : unsigned int i
4228 0 : = CEIL (prec, abi_limb_prec) * abi_limb_prec / limb_prec;
4229 0 : v = add_cast (m_limb_type, v);
4230 0 : g = gimple_build_assign (limb_access (type, obj, size_int (i - 1),
4231 : true), v);
4232 0 : insert_before (g);
4233 0 : ext_ms_limb = false;
4234 : }
4235 : }
4236 371 : if (ext_ms_limb)
4237 : {
4238 0 : unsigned int i = CEIL (prec, abi_limb_prec) * abi_limb_prec / limb_prec;
4239 0 : g = gimple_build_assign (limb_access (type, obj, size_int (i - 1), true),
4240 : build_zero_cst (m_limb_type));
4241 0 : insert_before (g);
4242 : }
4243 371 : }
4244 :
4245 : /* Lower large/huge _BitInt conversion to/from floating point. */
4246 :
4247 : void
4248 327 : bitint_large_huge::lower_float_conv_stmt (tree obj, gimple *stmt)
4249 : {
4250 327 : tree rhs1 = gimple_assign_rhs1 (stmt);
4251 327 : tree lhs = gimple_assign_lhs (stmt);
4252 327 : tree_code rhs_code = gimple_assign_rhs_code (stmt);
4253 327 : tree sitype = lang_hooks.types.type_for_mode (SImode, 0);
4254 327 : gimple *g;
4255 327 : if (rhs_code == FIX_TRUNC_EXPR)
4256 : {
4257 179 : tree type = TREE_TYPE (lhs);
4258 179 : int prec = TYPE_PRECISION (type);
4259 179 : bool extend_ms_limb = false;
4260 179 : if (bitint_extended == bitint_ext_full
4261 0 : && abi_limb_prec > limb_prec
4262 0 : && (CEIL (prec, abi_limb_prec) * abi_limb_prec
4263 0 : > CEIL (prec, limb_prec) * limb_prec))
4264 179 : extend_ms_limb = true;
4265 179 : if (!TYPE_UNSIGNED (type))
4266 93 : prec = -prec;
4267 179 : if (obj == NULL_TREE)
4268 : {
4269 135 : int part = var_to_partition (m_map, lhs);
4270 135 : gcc_assert (m_vars[part] != NULL_TREE);
4271 135 : obj = m_vars[part];
4272 135 : lhs = build_fold_addr_expr (obj);
4273 : }
4274 : else
4275 : {
4276 44 : lhs = build_fold_addr_expr (obj);
4277 44 : lhs = force_gimple_operand_gsi (&m_gsi, lhs, true,
4278 : NULL_TREE, true, GSI_SAME_STMT);
4279 : }
4280 179 : scalar_mode from_mode
4281 179 : = as_a <scalar_mode> (TYPE_MODE (TREE_TYPE (rhs1)));
4282 : #ifdef HAVE_SFmode
4283 : /* IEEE single is a full superset of both IEEE half and
4284 : bfloat formats, convert to float first and then to _BitInt
4285 : to avoid the need of another 2 library routines. */
4286 179 : if ((REAL_MODE_FORMAT (from_mode) == &arm_bfloat_half_format
4287 179 : || REAL_MODE_FORMAT (from_mode) == &ieee_half_format)
4288 191 : && REAL_MODE_FORMAT (SFmode) == &ieee_single_format)
4289 : {
4290 12 : tree type = lang_hooks.types.type_for_mode (SFmode, 0);
4291 12 : if (type)
4292 12 : rhs1 = add_cast (type, rhs1);
4293 : }
4294 : #endif
4295 179 : g = gimple_build_call_internal (IFN_FLOATTOBITINT, 3,
4296 179 : lhs, build_int_cst (sitype, prec),
4297 : rhs1);
4298 179 : insert_before (g);
4299 179 : if (extend_ms_limb)
4300 : {
4301 0 : unsigned int i
4302 0 : = (CEIL (prec < 0 ? -prec : prec, abi_limb_prec)
4303 0 : * abi_limb_prec / limb_prec);
4304 0 : tree val;
4305 0 : if (prec < 0)
4306 : {
4307 0 : g = gimple_build_assign (make_ssa_name (m_limb_type),
4308 : limb_access (type, obj,
4309 0 : size_int (i - 2),
4310 : true));
4311 0 : insert_before (g);
4312 0 : val = add_cast (signed_type_for (m_limb_type),
4313 : gimple_assign_lhs (g));
4314 0 : g = gimple_build_assign (make_ssa_name (TREE_TYPE (val)),
4315 : RSHIFT_EXPR, val,
4316 : build_int_cst (unsigned_type_node,
4317 0 : limb_prec - 1));
4318 0 : insert_before (g);
4319 0 : val = add_cast (m_limb_type, gimple_assign_lhs (g));
4320 : }
4321 : else
4322 0 : val = build_zero_cst (m_limb_type);
4323 0 : g = gimple_build_assign (limb_access (type, obj, size_int (i - 1),
4324 : true), val);
4325 0 : insert_before (g);
4326 : }
4327 : }
4328 : else
4329 : {
4330 148 : int prec;
4331 148 : rhs1 = handle_operand_addr (rhs1, stmt, NULL, &prec);
4332 148 : g = gimple_build_call_internal (IFN_BITINTTOFLOAT, 2,
4333 148 : rhs1, build_int_cst (sitype, prec));
4334 148 : gimple_call_set_lhs (g, lhs);
4335 148 : if (!stmt_ends_bb_p (stmt))
4336 147 : gimple_call_set_nothrow (as_a <gcall *> (g), true);
4337 148 : gsi_replace (&m_gsi, g, true);
4338 : }
4339 327 : }
4340 :
4341 : /* Helper method for lower_addsub_overflow and lower_mul_overflow.
4342 : If check_zero is true, caller wants to check if all bits in [start, end)
4343 : are zero, otherwise if bits in [start, end) are either all zero or
4344 : all ones. L is the limb with index LIMB, START and END are measured
4345 : in bits. */
4346 :
4347 : tree
4348 6453 : bitint_large_huge::arith_overflow_extract_bits (unsigned int start,
4349 : unsigned int end, tree l,
4350 : unsigned int limb,
4351 : bool check_zero)
4352 : {
4353 6453 : unsigned startlimb = start / limb_prec;
4354 6453 : unsigned endlimb = (end - 1) / limb_prec;
4355 6453 : gimple *g;
4356 :
4357 6453 : if ((start % limb_prec) == 0 && (end % limb_prec) == 0)
4358 : return l;
4359 6184 : if (startlimb == endlimb && limb == startlimb)
4360 : {
4361 2039 : if (check_zero)
4362 : {
4363 1486 : wide_int w = wi::shifted_mask (start % limb_prec,
4364 1486 : end - start, false, limb_prec);
4365 2972 : g = gimple_build_assign (make_ssa_name (m_limb_type),
4366 : BIT_AND_EXPR, l,
4367 1486 : wide_int_to_tree (m_limb_type, w));
4368 1486 : insert_before (g);
4369 1486 : return gimple_assign_lhs (g);
4370 1486 : }
4371 553 : unsigned int shift = start % limb_prec;
4372 553 : if ((end % limb_prec) != 0)
4373 : {
4374 336 : unsigned int lshift = (-end) % limb_prec;
4375 336 : shift += lshift;
4376 336 : g = gimple_build_assign (make_ssa_name (m_limb_type),
4377 : LSHIFT_EXPR, l,
4378 : build_int_cst (unsigned_type_node,
4379 336 : lshift));
4380 336 : insert_before (g);
4381 336 : l = gimple_assign_lhs (g);
4382 : }
4383 553 : l = add_cast (signed_type_for (m_limb_type), l);
4384 553 : g = gimple_build_assign (make_ssa_name (TREE_TYPE (l)),
4385 : RSHIFT_EXPR, l,
4386 553 : build_int_cst (unsigned_type_node, shift));
4387 553 : insert_before (g);
4388 553 : return add_cast (m_limb_type, gimple_assign_lhs (g));
4389 : }
4390 4145 : else if (limb == startlimb)
4391 : {
4392 1990 : if ((start % limb_prec) == 0)
4393 : return l;
4394 1876 : if (!check_zero)
4395 950 : l = add_cast (signed_type_for (m_limb_type), l);
4396 1876 : g = gimple_build_assign (make_ssa_name (TREE_TYPE (l)),
4397 : RSHIFT_EXPR, l,
4398 : build_int_cst (unsigned_type_node,
4399 1876 : start % limb_prec));
4400 1876 : insert_before (g);
4401 1876 : l = gimple_assign_lhs (g);
4402 1876 : if (!check_zero)
4403 950 : l = add_cast (m_limb_type, l);
4404 : return l;
4405 : }
4406 2155 : else if (limb == endlimb)
4407 : {
4408 1704 : if ((end % limb_prec) == 0)
4409 : return l;
4410 1687 : if (check_zero)
4411 : {
4412 880 : wide_int w = wi::mask (end % limb_prec, false, limb_prec);
4413 1760 : g = gimple_build_assign (make_ssa_name (m_limb_type),
4414 : BIT_AND_EXPR, l,
4415 880 : wide_int_to_tree (m_limb_type, w));
4416 880 : insert_before (g);
4417 880 : return gimple_assign_lhs (g);
4418 880 : }
4419 807 : unsigned int shift = (-end) % limb_prec;
4420 807 : g = gimple_build_assign (make_ssa_name (m_limb_type),
4421 : LSHIFT_EXPR, l,
4422 807 : build_int_cst (unsigned_type_node, shift));
4423 807 : insert_before (g);
4424 807 : l = add_cast (signed_type_for (m_limb_type), gimple_assign_lhs (g));
4425 807 : g = gimple_build_assign (make_ssa_name (TREE_TYPE (l)),
4426 : RSHIFT_EXPR, l,
4427 807 : build_int_cst (unsigned_type_node, shift));
4428 807 : insert_before (g);
4429 807 : return add_cast (m_limb_type, gimple_assign_lhs (g));
4430 : }
4431 : return l;
4432 : }
4433 :
4434 : /* Helper method for lower_addsub_overflow and lower_mul_overflow. Store
4435 : result including overflow flag into the right locations. */
4436 :
4437 : void
4438 4212 : bitint_large_huge::finish_arith_overflow (tree var, tree obj, tree type,
4439 : tree ovf, tree lhs, tree orig_obj,
4440 : gimple *stmt, unsigned nelts,
4441 : tree_code code)
4442 : {
4443 4212 : gimple *g;
4444 :
4445 4212 : if (obj == NULL_TREE
4446 4212 : && (!BITINT_TYPE_P (type)
4447 231 : || bitint_precision_kind (type) < bitint_prec_large))
4448 : {
4449 : /* Add support for 3 or more limbs filled in from normal integral
4450 : type if this assert fails. If no target chooses limb mode smaller
4451 : than half of largest supported normal integral type, this will not
4452 : be needed. */
4453 250 : gcc_assert (TYPE_PRECISION (type) <= 2 * limb_prec);
4454 250 : tree lhs_type = type;
4455 110 : if (BITINT_TYPE_P (type)
4456 250 : && bitint_precision_kind (type) == bitint_prec_middle)
4457 46 : lhs_type = build_nonstandard_integer_type (TYPE_PRECISION (type),
4458 46 : TYPE_UNSIGNED (type));
4459 250 : tree r1 = limb_access (NULL_TREE, var,
4460 : bitint_big_endian
4461 0 : ? size_int (nelts - 1) : size_zero_node, true);
4462 250 : g = gimple_build_assign (make_ssa_name (m_limb_type), r1);
4463 250 : insert_before (g);
4464 250 : r1 = gimple_assign_lhs (g);
4465 250 : if (!useless_type_conversion_p (lhs_type, TREE_TYPE (r1)))
4466 250 : r1 = add_cast (lhs_type, r1);
4467 250 : if (TYPE_PRECISION (lhs_type) > limb_prec)
4468 : {
4469 90 : tree r2 = limb_access (NULL_TREE, var,
4470 : bitint_big_endian
4471 0 : ? size_int (nelts - 2) : size_one_node, true);
4472 90 : g = gimple_build_assign (make_ssa_name (m_limb_type), r2);
4473 90 : insert_before (g);
4474 90 : r2 = gimple_assign_lhs (g);
4475 90 : r2 = add_cast (lhs_type, r2);
4476 90 : g = gimple_build_assign (make_ssa_name (lhs_type), LSHIFT_EXPR, r2,
4477 : build_int_cst (unsigned_type_node,
4478 90 : limb_prec));
4479 90 : insert_before (g);
4480 90 : g = gimple_build_assign (make_ssa_name (lhs_type), BIT_IOR_EXPR, r1,
4481 : gimple_assign_lhs (g));
4482 90 : insert_before (g);
4483 90 : r1 = gimple_assign_lhs (g);
4484 : }
4485 250 : if (lhs_type != type)
4486 46 : r1 = add_cast (type, r1);
4487 250 : ovf = add_cast (lhs_type, ovf);
4488 250 : if (lhs_type != type)
4489 46 : ovf = add_cast (type, ovf);
4490 250 : g = gimple_build_assign (lhs, COMPLEX_EXPR, r1, ovf);
4491 250 : m_gsi = gsi_for_stmt (stmt);
4492 250 : gsi_replace (&m_gsi, g, true);
4493 : }
4494 : else
4495 : {
4496 3962 : unsigned HOST_WIDE_INT obj_nelts = 0;
4497 3962 : tree atype = NULL_TREE;
4498 3962 : if (obj)
4499 : {
4500 3871 : obj_nelts = tree_to_uhwi (TYPE_SIZE (TREE_TYPE (obj))) / limb_prec;
4501 3871 : if (orig_obj == NULL_TREE)
4502 2277 : obj_nelts >>= 1;
4503 3871 : atype = build_array_type_nelts (m_limb_type, obj_nelts);
4504 : }
4505 3962 : if (bitint_extended && (var || obj))
4506 : {
4507 0 : unsigned prec = TYPE_PRECISION (type);
4508 0 : unsigned prec_limbs = CEIL (prec, limb_prec);
4509 0 : bool ext_ms_limb
4510 : = (bitint_extended == bitint_ext_full
4511 0 : && abi_limb_prec > limb_prec
4512 0 : && (CEIL (prec, abi_limb_prec) * abi_limb_prec
4513 0 : > CEIL (prec, limb_prec) * limb_prec));
4514 : /* For .{ADD,SUB}_OVERFLOW the partial limb if any is
4515 : already extended in lower_addsub_overflow. */
4516 0 : if ((code == MULT_EXPR && (prec % limb_prec) != 0)
4517 0 : || (ext_ms_limb && !TYPE_UNSIGNED (type)))
4518 : {
4519 0 : tree plm1idx = size_int (bitint_big_endian
4520 : ? nelts - obj_nelts : prec_limbs - 1);
4521 0 : tree plm1type
4522 0 : = limb_access_type (type, bitint_big_endian
4523 : ? size_zero_node : plm1idx);
4524 0 : tree l = limb_access (bitint_big_endian ? NULL_TREE : type,
4525 : var ? var : obj, plm1idx, true);
4526 0 : tree rhs = make_ssa_name (TREE_TYPE (l));
4527 0 : g = gimple_build_assign (rhs, l);
4528 0 : insert_before (g);
4529 0 : if (code == MULT_EXPR && (prec % limb_prec) != 0)
4530 : {
4531 0 : if (!useless_type_conversion_p (plm1type, TREE_TYPE (rhs)))
4532 0 : rhs = add_cast (plm1type, rhs);
4533 0 : if (!useless_type_conversion_p (TREE_TYPE (l),
4534 0 : TREE_TYPE (rhs)))
4535 0 : rhs = add_cast (TREE_TYPE (l), rhs);
4536 0 : l = limb_access (bitint_big_endian ? NULL_TREE : type,
4537 : var ? var : obj, plm1idx, true);
4538 0 : g = gimple_build_assign (l, rhs);
4539 0 : insert_before (g);
4540 : }
4541 0 : if (ext_ms_limb && !TYPE_UNSIGNED (type))
4542 : {
4543 0 : rhs = add_cast (signed_type_for (m_limb_type), rhs);
4544 0 : tree lpm1 = build_int_cst (unsigned_type_node,
4545 0 : limb_prec - 1);
4546 0 : tree v = make_ssa_name (TREE_TYPE (rhs));
4547 0 : g = gimple_build_assign (v, RSHIFT_EXPR, rhs, lpm1);
4548 0 : insert_before (g);
4549 0 : unsigned int i
4550 0 : = CEIL (prec, abi_limb_prec) * abi_limb_prec / limb_prec;
4551 0 : v = add_cast (m_limb_type, v);
4552 0 : g = gimple_build_assign (limb_access (type, var ? var : obj,
4553 0 : size_int (i - 1),
4554 : true), v);
4555 0 : insert_before (g);
4556 0 : ext_ms_limb = false;
4557 : }
4558 : }
4559 0 : if (ext_ms_limb)
4560 : {
4561 0 : unsigned int i
4562 0 : = CEIL (prec, abi_limb_prec) * abi_limb_prec / limb_prec;
4563 0 : g = gimple_build_assign (limb_access (type, var ? var : obj,
4564 0 : size_int (i - 1), true),
4565 : build_zero_cst (m_limb_type));
4566 0 : insert_before (g);
4567 : }
4568 : }
4569 3962 : if (var && obj)
4570 : {
4571 519 : tree v1, v2;
4572 519 : tree off;
4573 519 : if (orig_obj == NULL_TREE)
4574 : {
4575 32 : off = build_zero_cst (build_pointer_type (TREE_TYPE (obj)));
4576 32 : v1 = build2 (MEM_REF, atype,
4577 : build_fold_addr_expr (unshare_expr (obj)), off);
4578 : }
4579 487 : else if (!useless_type_conversion_p (atype, TREE_TYPE (obj)))
4580 9 : v1 = build1 (VIEW_CONVERT_EXPR, atype, unshare_expr (obj));
4581 : else
4582 478 : v1 = unshare_expr (obj);
4583 519 : off = build_int_cst (build_pointer_type (TREE_TYPE (var)),
4584 : bitint_big_endian
4585 519 : ? (nelts - obj_nelts) * m_limb_size : 0);
4586 519 : v2 = build2 (MEM_REF, atype, build_fold_addr_expr (var), off);
4587 519 : g = gimple_build_assign (v1, v2);
4588 519 : insert_before (g);
4589 : }
4590 3443 : else if (obj && bitint_big_endian && nelts != obj_nelts)
4591 : {
4592 0 : gcc_assert (nelts > obj_nelts);
4593 0 : tree fn = builtin_decl_implicit (BUILT_IN_MEMMOVE);
4594 0 : tree off = build_int_cst (build_pointer_type (TREE_TYPE (obj)),
4595 0 : (nelts - obj_nelts) * m_limb_size);
4596 0 : tree src = build2 (MEM_REF, atype,
4597 : build_fold_addr_expr (unshare_expr (obj)), off);
4598 0 : g = gimple_build_call (fn, 3,
4599 : build_fold_addr_expr (unshare_expr (obj)),
4600 : build_fold_addr_expr (src),
4601 : build_int_cst (size_type_node,
4602 0 : obj_nelts * m_limb_size));
4603 0 : insert_before (g);
4604 : }
4605 3962 : if (orig_obj == NULL_TREE && obj)
4606 : {
4607 2277 : ovf = add_cast (m_limb_type, ovf);
4608 2277 : tree l = limb_access (NULL_TREE, obj,
4609 2277 : size_int (bitint_big_endian
4610 : ? obj_nelts * 2 - 1 : obj_nelts),
4611 : true);
4612 2277 : g = gimple_build_assign (l, ovf);
4613 2277 : insert_before (g);
4614 2277 : if (obj_nelts > 1)
4615 : {
4616 2277 : atype = build_array_type_nelts (m_limb_type, obj_nelts - 1);
4617 2277 : tree off = build_int_cst (build_pointer_type (TREE_TYPE (obj)),
4618 2277 : (obj_nelts + !bitint_big_endian)
4619 2277 : * m_limb_size);
4620 2277 : tree v1 = build2 (MEM_REF, atype,
4621 : build_fold_addr_expr (unshare_expr (obj)),
4622 : off);
4623 2277 : g = gimple_build_assign (v1, build_zero_cst (atype));
4624 2277 : insert_before (g);
4625 : }
4626 : }
4627 1685 : else if (TREE_CODE (TREE_TYPE (lhs)) == COMPLEX_TYPE)
4628 : {
4629 1640 : imm_use_iterator ui;
4630 1640 : use_operand_p use_p;
4631 1640 : FOR_EACH_IMM_USE_FAST (use_p, ui, lhs)
4632 : {
4633 1640 : g = USE_STMT (use_p);
4634 1640 : if (!is_gimple_assign (g)
4635 1640 : || gimple_assign_rhs_code (g) != IMAGPART_EXPR)
4636 0 : continue;
4637 1640 : tree lhs2 = gimple_assign_lhs (g);
4638 1640 : gimple *use_stmt;
4639 1640 : single_imm_use (lhs2, &use_p, &use_stmt);
4640 1640 : lhs2 = gimple_assign_lhs (use_stmt);
4641 1640 : gimple_stmt_iterator gsi = gsi_for_stmt (use_stmt);
4642 1640 : if (useless_type_conversion_p (TREE_TYPE (lhs2), TREE_TYPE (ovf)))
4643 1619 : g = gimple_build_assign (lhs2, ovf);
4644 : else
4645 21 : g = gimple_build_assign (lhs2, NOP_EXPR, ovf);
4646 1640 : gsi_replace (&gsi, g, true);
4647 1640 : if (gsi_stmt (m_gsi) == use_stmt)
4648 91 : m_gsi = gsi_for_stmt (g);
4649 1640 : break;
4650 1640 : }
4651 : }
4652 45 : else if (ovf != boolean_false_node)
4653 : {
4654 45 : g = gimple_build_cond (NE_EXPR, ovf, boolean_false_node,
4655 : NULL_TREE, NULL_TREE);
4656 45 : edge edge_true, edge_false;
4657 45 : if_then (g, profile_probability::very_unlikely (),
4658 : edge_true, edge_false);
4659 45 : tree zero = build_zero_cst (TREE_TYPE (lhs));
4660 45 : tree fn = ubsan_build_overflow_builtin (code, m_loc,
4661 45 : TREE_TYPE (lhs),
4662 : zero, zero, NULL);
4663 45 : force_gimple_operand_gsi (&m_gsi, fn, true, NULL_TREE,
4664 : true, GSI_SAME_STMT);
4665 45 : m_gsi = gsi_after_labels (edge_true->dest);
4666 : }
4667 : }
4668 4212 : if (var)
4669 : {
4670 781 : tree clobber = build_clobber (TREE_TYPE (var), CLOBBER_STORAGE_END);
4671 781 : g = gimple_build_assign (var, clobber);
4672 781 : gsi_insert_after (&m_gsi, g, GSI_SAME_STMT);
4673 : }
4674 4212 : }
4675 :
4676 : /* Helper function for lower_addsub_overflow and lower_mul_overflow.
4677 : Given precisions of result TYPE (PREC), argument 0 precision PREC0,
4678 : argument 1 precision PREC1 and minimum precision for the result
4679 : PREC2, compute *START, *END, *CHECK_ZERO and return OVF. */
4680 :
4681 : static tree
4682 4212 : arith_overflow (tree_code code, tree type, int prec, int prec0, int prec1,
4683 : int prec2, unsigned *start, unsigned *end, bool *check_zero)
4684 : {
4685 4212 : *start = 0;
4686 4212 : *end = 0;
4687 4212 : *check_zero = true;
4688 : /* Ignore this special rule for subtraction, even if both
4689 : prec0 >= 0 and prec1 >= 0, their subtraction can be negative
4690 : in infinite precision. */
4691 4212 : if (code != MINUS_EXPR && prec0 >= 0 && prec1 >= 0)
4692 : {
4693 : /* Result in [0, prec2) is unsigned, if prec > prec2,
4694 : all bits above it will be zero. */
4695 681 : if ((prec - !TYPE_UNSIGNED (type)) >= prec2)
4696 0 : return boolean_false_node;
4697 : else
4698 : {
4699 : /* ovf if any of bits in [start, end) is non-zero. */
4700 681 : *start = prec - !TYPE_UNSIGNED (type);
4701 681 : *end = prec2;
4702 : }
4703 : }
4704 3531 : else if (TYPE_UNSIGNED (type))
4705 : {
4706 : /* If result in [0, prec2) is signed and if prec > prec2,
4707 : all bits above it will be sign bit copies. */
4708 1950 : if (prec >= prec2)
4709 : {
4710 : /* ovf if bit prec - 1 is non-zero. */
4711 184 : *start = prec - 1;
4712 184 : *end = prec;
4713 : }
4714 : else
4715 : {
4716 : /* ovf if any of bits in [start, end) is non-zero. */
4717 1766 : *start = prec;
4718 1766 : *end = prec2;
4719 : }
4720 : }
4721 1581 : else if (prec >= prec2)
4722 2 : return boolean_false_node;
4723 : else
4724 : {
4725 : /* ovf if [start, end) bits aren't all zeros or all ones. */
4726 1579 : *start = prec - 1;
4727 1579 : *end = prec2;
4728 1579 : *check_zero = false;
4729 : }
4730 : return NULL_TREE;
4731 : }
4732 :
4733 : /* Lower a .{ADD,SUB}_OVERFLOW call with at least one large/huge _BitInt
4734 : argument or return type _Complex large/huge _BitInt. */
4735 :
4736 : void
4737 2733 : bitint_large_huge::lower_addsub_overflow (tree obj, gimple *stmt)
4738 : {
4739 2733 : tree arg0 = gimple_call_arg (stmt, 0);
4740 2733 : tree arg1 = gimple_call_arg (stmt, 1);
4741 2733 : tree lhs = gimple_call_lhs (stmt);
4742 2733 : gimple *g;
4743 :
4744 2733 : if (!lhs)
4745 : {
4746 0 : gimple_stmt_iterator gsi = gsi_for_stmt (stmt);
4747 0 : gsi_remove (&gsi, true);
4748 0 : return;
4749 : }
4750 2733 : gimple *final_stmt = gsi_stmt (m_gsi);
4751 2733 : tree type = TREE_TYPE (lhs);
4752 2733 : if (TREE_CODE (type) == COMPLEX_TYPE)
4753 2703 : type = TREE_TYPE (type);
4754 2733 : int prec = TYPE_PRECISION (type);
4755 2733 : int prec0 = range_to_prec (arg0, stmt);
4756 2733 : int prec1 = range_to_prec (arg1, stmt);
4757 : /* If PREC0 >= 0 && PREC1 >= 0 and CODE is not MINUS_EXPR, PREC2 is
4758 : the minimum unsigned precision of any possible operation's
4759 : result, otherwise it is minimum signed precision.
4760 : Some examples:
4761 : If PREC0 or PREC1 is 8, it means that argument is [0, 0xff],
4762 : if PREC0 or PREC1 is 10, it means that argument is [0, 0x3ff],
4763 : if PREC0 or PREC1 is -8, it means that argument is [-0x80, 0x7f],
4764 : if PREC0 or PREC1 is -10, it means that argument is [-0x200, 0x1ff].
4765 : PREC0 CODE PREC1 RESULT PREC2 SIGNED vs. UNSIGNED
4766 : 8 + 8 [0, 0x1fe] 9 UNSIGNED
4767 : 8 + 10 [0, 0x4fe] 11 UNSIGNED
4768 : -8 + -8 [-0x100, 0xfe] 9 SIGNED
4769 : -8 + -10 [-0x280, 0x27e] 11 SIGNED
4770 : 8 + -8 [-0x80, 0x17e] 10 SIGNED
4771 : 8 + -10 [-0x200, 0x2fe] 11 SIGNED
4772 : 10 + -8 [-0x80, 0x47e] 12 SIGNED
4773 : 8 - 8 [-0xff, 0xff] 9 SIGNED
4774 : 8 - 10 [-0x3ff, 0xff] 11 SIGNED
4775 : 10 - 8 [-0xff, 0x3ff] 11 SIGNED
4776 : -8 - -8 [-0xff, 0xff] 9 SIGNED
4777 : -8 - -10 [-0x27f, 0x27f] 11 SIGNED
4778 : -10 - -8 [-0x27f, 0x27f] 11 SIGNED
4779 : 8 - -8 [-0x7f, 0x17f] 10 SIGNED
4780 : 8 - -10 [-0x1ff, 0x2ff] 11 SIGNED
4781 : 10 - -8 [-0x7f, 0x47f] 12 SIGNED
4782 : -8 - 8 [-0x17f, 0x7f] 10 SIGNED
4783 : -8 - 10 [-0x47f, 0x7f] 12 SIGNED
4784 : -10 - 8 [-0x2ff, 0x1ff] 11 SIGNED */
4785 2733 : int prec2 = MAX (prec0 < 0 ? -prec0 : prec0,
4786 : prec1 < 0 ? -prec1 : prec1);
4787 : /* If operands are either both signed or both unsigned,
4788 : we need just one additional bit. */
4789 3777 : prec2 = (((prec0 < 0) == (prec1 < 0)
4790 : /* If one operand is signed and one unsigned and
4791 : the signed one has larger precision, we need
4792 : just one extra bit, otherwise two. */
4793 707 : || (prec0 < 0 ? (prec2 == -prec0 && prec2 != prec1)
4794 337 : : (prec2 == -prec1 && prec2 != prec0)))
4795 2733 : ? prec2 + 1 : prec2 + 2);
4796 2733 : int prec3 = MAX (prec0 < 0 ? -prec0 : prec0,
4797 : prec1 < 0 ? -prec1 : prec1);
4798 2733 : prec3 = MAX (prec3, prec);
4799 2733 : tree var = NULL_TREE;
4800 2733 : tree orig_obj = obj;
4801 2733 : if (obj == NULL_TREE
4802 1753 : && BITINT_TYPE_P (type)
4803 1652 : && bitint_precision_kind (type) >= bitint_prec_large
4804 1536 : && m_names
4805 4245 : && bitmap_bit_p (m_names, SSA_NAME_VERSION (lhs)))
4806 : {
4807 1457 : int part = var_to_partition (m_map, lhs);
4808 1457 : gcc_assert (m_vars[part] != NULL_TREE);
4809 1457 : obj = m_vars[part];
4810 1457 : if (TREE_TYPE (lhs) == type)
4811 14 : orig_obj = obj;
4812 : }
4813 101 : if (!BITINT_TYPE_P (type)
4814 2733 : || bitint_precision_kind (type) < bitint_prec_large)
4815 : {
4816 217 : unsigned HOST_WIDE_INT nelts = CEIL (prec, limb_prec);
4817 217 : tree atype = build_array_type_nelts (m_limb_type, nelts);
4818 217 : var = create_tmp_var (atype);
4819 : }
4820 :
4821 2733 : enum tree_code code;
4822 2733 : switch (gimple_call_internal_fn (stmt))
4823 : {
4824 : case IFN_ADD_OVERFLOW:
4825 : case IFN_UBSAN_CHECK_ADD:
4826 : code = PLUS_EXPR;
4827 : break;
4828 1399 : case IFN_SUB_OVERFLOW:
4829 1399 : case IFN_UBSAN_CHECK_SUB:
4830 1399 : code = MINUS_EXPR;
4831 1399 : break;
4832 0 : default:
4833 0 : gcc_unreachable ();
4834 : }
4835 2733 : unsigned start, end;
4836 2733 : bool check_zero;
4837 2733 : tree ovf = arith_overflow (code, type, prec, prec0, prec1, prec2,
4838 : &start, &end, &check_zero);
4839 :
4840 2733 : unsigned startlimb, endlimb;
4841 2733 : if (ovf)
4842 : {
4843 : startlimb = ~0U;
4844 : endlimb = ~0U;
4845 : }
4846 : else
4847 : {
4848 2733 : startlimb = start / limb_prec;
4849 2733 : endlimb = (end - 1) / limb_prec;
4850 : }
4851 :
4852 2733 : int prec4 = ovf != NULL_TREE ? prec : prec3;
4853 2733 : bitint_prec_kind kind = bitint_precision_kind (prec4);
4854 2733 : unsigned cnt, rem = 0, fin = 0, nelts;
4855 2733 : tree idx = NULL_TREE, idx_first = NULL_TREE, idx_next = NULL_TREE;
4856 5466 : bool last_ovf = (ovf == NULL_TREE
4857 2733 : && CEIL (prec2, limb_prec) > CEIL (prec3, limb_prec));
4858 2733 : if (kind != bitint_prec_huge)
4859 1539 : nelts = cnt = CEIL (prec4, limb_prec) + last_ovf;
4860 : else
4861 : {
4862 1194 : rem = prec4 % (2 * limb_prec);
4863 1194 : fin = (prec4 - rem) / limb_prec;
4864 1194 : cnt = 2 + CEIL (rem, limb_prec) + last_ovf;
4865 1194 : nelts = fin + cnt - 2;
4866 1194 : idx = idx_first = create_loop (bitint_big_endian
4867 1194 : ? size_int (nelts - 1) : size_zero_node,
4868 : &idx_next);
4869 : }
4870 :
4871 2733 : if (kind == bitint_prec_huge)
4872 1194 : m_upwards_2limb = fin;
4873 2733 : m_upwards = true;
4874 :
4875 2733 : tree type0 = TREE_TYPE (arg0);
4876 2733 : tree type1 = TREE_TYPE (arg1);
4877 2733 : int prec5 = prec3;
4878 2733 : if (bitint_precision_kind (prec5) < bitint_prec_large)
4879 10 : prec5 = MAX (TYPE_PRECISION (type0), TYPE_PRECISION (type1));
4880 2733 : if (TYPE_PRECISION (type0) < prec5)
4881 : {
4882 146 : type0 = build_bitint_type (prec5, TYPE_UNSIGNED (type0));
4883 146 : if (TREE_CODE (arg0) == INTEGER_CST)
4884 27 : arg0 = fold_convert (type0, arg0);
4885 : }
4886 2733 : if (TYPE_PRECISION (type1) < prec5)
4887 : {
4888 156 : type1 = build_bitint_type (prec5, TYPE_UNSIGNED (type1));
4889 156 : if (TREE_CODE (arg1) == INTEGER_CST)
4890 76 : arg1 = fold_convert (type1, arg1);
4891 : }
4892 2733 : unsigned int data_cnt = 0;
4893 2733 : tree last_rhs1 = NULL_TREE, last_rhs2 = NULL_TREE;
4894 2733 : tree cmp = build_zero_cst (m_limb_type);
4895 2733 : unsigned prec_limbs = CEIL ((unsigned) prec, limb_prec);
4896 2733 : tree ovf_out = NULL_TREE, cmp_out = NULL_TREE;
4897 11904 : for (unsigned i = 0; i < cnt; i++)
4898 : {
4899 9171 : m_data_cnt = 0;
4900 9171 : tree rhs1, rhs2;
4901 9171 : if (kind != bitint_prec_huge)
4902 5303 : idx = size_int (bitint_big_endian ? nelts - 1 - i : i);
4903 3868 : else if (i >= 2)
4904 1480 : idx = size_int (bitint_big_endian ? nelts + 1 - fin - i : fin + i - 2);
4905 9171 : if (!last_ovf || i < cnt - 1)
4906 : {
4907 8225 : tree idx0 = idx, idx1 = idx;
4908 8225 : if (bitint_big_endian
4909 8225 : && CEIL ((unsigned) TYPE_PRECISION (type0), limb_prec) != nelts)
4910 : {
4911 0 : HOST_WIDE_INT diff
4912 0 : = ((HOST_WIDE_INT) CEIL (TYPE_PRECISION (type0), limb_prec)
4913 0 : - (HOST_WIDE_INT) nelts);
4914 0 : if (tree_fits_uhwi_p (idx))
4915 0 : idx0 = size_int (tree_to_uhwi (idx) + diff);
4916 : else
4917 : {
4918 0 : idx0 = make_ssa_name (sizetype);
4919 0 : g = gimple_build_assign (idx0, PLUS_EXPR, idx,
4920 0 : size_int (diff));
4921 0 : insert_before (g);
4922 : }
4923 : }
4924 8225 : if (type0 != TREE_TYPE (arg0))
4925 334 : rhs1 = handle_cast (type0, arg0, idx0);
4926 : else
4927 7891 : rhs1 = handle_operand (arg0, idx0);
4928 8225 : if (bitint_big_endian
4929 8225 : && CEIL ((unsigned) TYPE_PRECISION (type1), limb_prec) != nelts)
4930 : {
4931 0 : HOST_WIDE_INT diff
4932 0 : = ((HOST_WIDE_INT) CEIL (TYPE_PRECISION (type1), limb_prec)
4933 0 : - (HOST_WIDE_INT) nelts);
4934 0 : if (tree_fits_uhwi_p (idx))
4935 0 : idx1 = size_int (tree_to_uhwi (idx) + diff);
4936 : else
4937 : {
4938 0 : idx1 = make_ssa_name (sizetype);
4939 0 : g = gimple_build_assign (idx1, PLUS_EXPR, idx,
4940 0 : size_int (diff));
4941 0 : insert_before (g);
4942 : }
4943 : }
4944 8225 : if (type1 != TREE_TYPE (arg1))
4945 250 : rhs2 = handle_cast (type1, arg1, idx1);
4946 : else
4947 7975 : rhs2 = handle_operand (arg1, idx1);
4948 8225 : if (i == 0)
4949 2733 : data_cnt = m_data_cnt;
4950 8225 : if (!useless_type_conversion_p (m_limb_type, TREE_TYPE (rhs1)))
4951 1983 : rhs1 = add_cast (m_limb_type, rhs1);
4952 8225 : if (!useless_type_conversion_p (m_limb_type, TREE_TYPE (rhs2)))
4953 1983 : rhs2 = add_cast (m_limb_type, rhs2);
4954 : last_rhs1 = rhs1;
4955 : last_rhs2 = rhs2;
4956 : }
4957 : else
4958 : {
4959 946 : m_data_cnt = data_cnt;
4960 946 : if (TYPE_UNSIGNED (type0) || prec0 >= 0)
4961 421 : rhs1 = build_zero_cst (m_limb_type);
4962 : else
4963 : {
4964 525 : rhs1 = add_cast (signed_type_for (m_limb_type), last_rhs1);
4965 525 : if (TREE_CODE (rhs1) == INTEGER_CST)
4966 52 : rhs1 = build_int_cst (m_limb_type,
4967 74 : tree_int_cst_sgn (rhs1) < 0 ? -1 : 0);
4968 : else
4969 : {
4970 946 : tree lpm1 = build_int_cst (unsigned_type_node,
4971 473 : limb_prec - 1);
4972 473 : g = gimple_build_assign (make_ssa_name (TREE_TYPE (rhs1)),
4973 : RSHIFT_EXPR, rhs1, lpm1);
4974 473 : insert_before (g);
4975 473 : rhs1 = add_cast (m_limb_type, gimple_assign_lhs (g));
4976 : }
4977 : }
4978 946 : if (TYPE_UNSIGNED (type1) || prec1 >= 0)
4979 543 : rhs2 = build_zero_cst (m_limb_type);
4980 : else
4981 : {
4982 403 : rhs2 = add_cast (signed_type_for (m_limb_type), last_rhs2);
4983 403 : if (TREE_CODE (rhs2) == INTEGER_CST)
4984 114 : rhs2 = build_int_cst (m_limb_type,
4985 153 : tree_int_cst_sgn (rhs2) < 0 ? -1 : 0);
4986 : else
4987 : {
4988 578 : tree lpm1 = build_int_cst (unsigned_type_node,
4989 289 : limb_prec - 1);
4990 289 : g = gimple_build_assign (make_ssa_name (TREE_TYPE (rhs2)),
4991 : RSHIFT_EXPR, rhs2, lpm1);
4992 289 : insert_before (g);
4993 289 : rhs2 = add_cast (m_limb_type, gimple_assign_lhs (g));
4994 : }
4995 : }
4996 : }
4997 9171 : tree rhs = handle_plus_minus (code, rhs1, rhs2, idx);
4998 9171 : if (ovf != boolean_false_node)
4999 : {
5000 9171 : if (tree_fits_uhwi_p (idx))
5001 : {
5002 6783 : unsigned limb = tree_to_uhwi (idx);
5003 6783 : if (bitint_big_endian)
5004 0 : limb = nelts - 1 - limb;
5005 6783 : if (limb >= startlimb && limb <= endlimb)
5006 : {
5007 3370 : tree l = arith_overflow_extract_bits (start, end, rhs,
5008 : limb, check_zero);
5009 3370 : tree this_ovf = make_ssa_name (boolean_type_node);
5010 3370 : if (ovf == NULL_TREE && !check_zero)
5011 : {
5012 907 : cmp = l;
5013 907 : g = gimple_build_assign (make_ssa_name (m_limb_type),
5014 : PLUS_EXPR, l,
5015 : build_int_cst (m_limb_type, 1));
5016 907 : insert_before (g);
5017 907 : g = gimple_build_assign (this_ovf, GT_EXPR,
5018 : gimple_assign_lhs (g),
5019 : build_int_cst (m_limb_type, 1));
5020 : }
5021 : else
5022 2463 : g = gimple_build_assign (this_ovf, NE_EXPR, l, cmp);
5023 3370 : insert_before (g);
5024 3370 : if (ovf == NULL_TREE)
5025 : ovf = this_ovf;
5026 : else
5027 : {
5028 1064 : tree b = make_ssa_name (boolean_type_node);
5029 1064 : g = gimple_build_assign (b, BIT_IOR_EXPR, ovf, this_ovf);
5030 1064 : insert_before (g);
5031 1064 : ovf = b;
5032 : }
5033 : }
5034 : }
5035 2388 : else if (startlimb < fin)
5036 : {
5037 854 : if (m_first && startlimb + 2 < fin)
5038 : {
5039 324 : tree data_out;
5040 324 : ovf = prepare_data_in_out (boolean_false_node, idx, &data_out);
5041 324 : ovf_out = m_data.pop ();
5042 324 : m_data.pop ();
5043 324 : if (!check_zero)
5044 : {
5045 169 : cmp = prepare_data_in_out (cmp, idx, &data_out);
5046 169 : cmp_out = m_data.pop ();
5047 169 : m_data.pop ();
5048 : }
5049 : }
5050 854 : if (i != 0 || startlimb != fin - 1)
5051 : {
5052 839 : tree_code cmp_code;
5053 839 : bool single_comparison
5054 839 : = (startlimb + 2 >= fin || (startlimb & 1) != (i & 1));
5055 : if (!single_comparison)
5056 : cmp_code = GE_EXPR;
5057 515 : else if ((startlimb & 1) == (i & 1))
5058 : cmp_code = EQ_EXPR;
5059 : else
5060 412 : cmp_code = GT_EXPR;
5061 839 : if (bitint_big_endian)
5062 0 : g = gimple_build_cond (swap_tree_comparison (cmp_code),
5063 0 : idx, size_int (nelts - 1
5064 : - startlimb),
5065 : NULL_TREE, NULL_TREE);
5066 : else
5067 839 : g = gimple_build_cond (cmp_code, idx, size_int (startlimb),
5068 : NULL_TREE, NULL_TREE);
5069 839 : edge edge_true_true, edge_true_false, edge_false;
5070 839 : gimple *g2 = NULL;
5071 839 : if (!single_comparison)
5072 324 : g2 = gimple_build_cond (NE_EXPR, idx,
5073 324 : size_int (bitint_big_endian
5074 : ? nelts - 1 - startlimb
5075 : : startlimb),
5076 : NULL_TREE, NULL_TREE);
5077 839 : if_then_if_then_else (g, g2, profile_probability::likely (),
5078 : profile_probability::likely (),
5079 : edge_true_true, edge_true_false,
5080 : edge_false);
5081 839 : unsigned tidx = startlimb + (cmp_code == GT_EXPR);
5082 839 : tree l = arith_overflow_extract_bits (start, end, rhs, tidx,
5083 : check_zero);
5084 839 : tree this_ovf = make_ssa_name (boolean_type_node);
5085 839 : if (cmp_code != GT_EXPR && !check_zero)
5086 : {
5087 173 : g = gimple_build_assign (make_ssa_name (m_limb_type),
5088 : PLUS_EXPR, l,
5089 : build_int_cst (m_limb_type, 1));
5090 173 : insert_before (g);
5091 173 : g = gimple_build_assign (this_ovf, GT_EXPR,
5092 : gimple_assign_lhs (g),
5093 : build_int_cst (m_limb_type, 1));
5094 : }
5095 : else
5096 666 : g = gimple_build_assign (this_ovf, NE_EXPR, l, cmp);
5097 839 : insert_before (g);
5098 839 : if (cmp_code == GT_EXPR)
5099 : {
5100 412 : tree t = make_ssa_name (boolean_type_node);
5101 412 : g = gimple_build_assign (t, BIT_IOR_EXPR, ovf, this_ovf);
5102 412 : insert_before (g);
5103 412 : this_ovf = t;
5104 : }
5105 839 : tree this_ovf2 = NULL_TREE;
5106 839 : if (!single_comparison)
5107 : {
5108 324 : m_gsi = gsi_after_labels (edge_true_true->src);
5109 324 : tree t = make_ssa_name (boolean_type_node);
5110 324 : g = gimple_build_assign (t, NE_EXPR, rhs, cmp);
5111 324 : insert_before (g);
5112 324 : this_ovf2 = make_ssa_name (boolean_type_node);
5113 324 : g = gimple_build_assign (this_ovf2, BIT_IOR_EXPR,
5114 : ovf, t);
5115 324 : insert_before (g);
5116 : }
5117 839 : m_gsi = gsi_after_labels (edge_true_false->dest);
5118 839 : tree t;
5119 839 : if (i == 1 && ovf_out)
5120 : t = ovf_out;
5121 : else
5122 515 : t = make_ssa_name (boolean_type_node);
5123 839 : gphi *phi = create_phi_node (t, edge_true_false->dest);
5124 839 : add_phi_arg (phi, this_ovf, edge_true_false,
5125 : UNKNOWN_LOCATION);
5126 839 : add_phi_arg (phi, ovf ? ovf
5127 : : boolean_false_node, edge_false,
5128 : UNKNOWN_LOCATION);
5129 839 : if (edge_true_true)
5130 324 : add_phi_arg (phi, this_ovf2, edge_true_true,
5131 : UNKNOWN_LOCATION);
5132 839 : ovf = t;
5133 839 : if (!check_zero && cmp_code != GT_EXPR)
5134 : {
5135 173 : t = cmp_out ? cmp_out : make_ssa_name (m_limb_type);
5136 173 : phi = create_phi_node (t, edge_true_false->dest);
5137 173 : add_phi_arg (phi, l, edge_true_false, UNKNOWN_LOCATION);
5138 173 : add_phi_arg (phi, cmp, edge_false, UNKNOWN_LOCATION);
5139 173 : if (edge_true_true)
5140 169 : add_phi_arg (phi, cmp, edge_true_true,
5141 : UNKNOWN_LOCATION);
5142 : cmp = t;
5143 : }
5144 : }
5145 : }
5146 : }
5147 :
5148 9171 : if (var || obj)
5149 : {
5150 8943 : if (tree_fits_uhwi_p (idx)
5151 6673 : && (bitint_big_endian
5152 6673 : ? nelts - 1 - tree_to_uhwi (idx)
5153 6673 : : tree_to_uhwi (idx)) >= prec_limbs)
5154 : ;
5155 7555 : else if (!tree_fits_uhwi_p (idx)
5156 2270 : && (unsigned) prec < (fin - (i == 0)) * limb_prec)
5157 : {
5158 1458 : bool single_comparison
5159 729 : = (((unsigned) prec % limb_prec) == 0
5160 571 : || prec_limbs + 1 >= fin
5161 1231 : || (prec_limbs & 1) == (i & 1));
5162 729 : if (bitint_big_endian)
5163 0 : g = gimple_build_cond (GE_EXPR, idx,
5164 0 : size_int (nelts - prec_limbs),
5165 : NULL_TREE, NULL_TREE);
5166 : else
5167 729 : g = gimple_build_cond (LE_EXPR, idx, size_int (prec_limbs - 1),
5168 : NULL_TREE, NULL_TREE);
5169 729 : gimple *g2 = NULL;
5170 729 : if (!single_comparison)
5171 251 : g2 = gimple_build_cond (EQ_EXPR, idx,
5172 251 : size_int (bitint_big_endian
5173 : ? nelts - prec_limbs
5174 : : prec_limbs - 1),
5175 : NULL_TREE, NULL_TREE);
5176 729 : edge edge_true_true, edge_true_false, edge_false;
5177 729 : if_then_if_then_else (g, g2, profile_probability::likely (),
5178 : profile_probability::unlikely (),
5179 : edge_true_true, edge_true_false,
5180 : edge_false);
5181 729 : tree idxl = idx;
5182 729 : if (bitint_big_endian && prec_limbs != nelts)
5183 : {
5184 0 : HOST_WIDE_INT diff = ((HOST_WIDE_INT) prec_limbs
5185 0 : - (HOST_WIDE_INT) nelts);
5186 0 : if (tree_fits_uhwi_p (idx))
5187 0 : idxl = size_int (tree_to_uhwi (idx) + diff);
5188 : else
5189 : {
5190 0 : idxl = make_ssa_name (sizetype);
5191 0 : g = gimple_build_assign (idxl, PLUS_EXPR, idx,
5192 0 : size_int (diff));
5193 0 : insert_before (g);
5194 : }
5195 : }
5196 1082 : tree l = limb_access (type, var ? var : obj, idxl, true);
5197 729 : g = gimple_build_assign (l, rhs);
5198 729 : insert_before (g);
5199 729 : if (!single_comparison)
5200 : {
5201 251 : m_gsi = gsi_after_labels (edge_true_true->src);
5202 251 : tree plm1idx = size_int (bitint_big_endian
5203 : ? 0 : prec_limbs - 1);
5204 251 : tree plm1type = limb_access_type (type, plm1idx);
5205 251 : l = limb_access (type, var ? var : obj, plm1idx, true);
5206 251 : if (!useless_type_conversion_p (plm1type, TREE_TYPE (rhs)))
5207 251 : rhs = add_cast (plm1type, rhs);
5208 251 : if (!useless_type_conversion_p (TREE_TYPE (l),
5209 251 : TREE_TYPE (rhs)))
5210 251 : rhs = add_cast (TREE_TYPE (l), rhs);
5211 251 : g = gimple_build_assign (l, rhs);
5212 251 : insert_before (g);
5213 : }
5214 729 : m_gsi = gsi_after_labels (edge_true_false->dest);
5215 729 : }
5216 : else
5217 : {
5218 6826 : tree idxl = idx;
5219 6826 : if (bitint_big_endian && prec_limbs != nelts)
5220 : {
5221 0 : HOST_WIDE_INT diff = ((HOST_WIDE_INT) prec_limbs
5222 0 : - (HOST_WIDE_INT) nelts);
5223 0 : if (tree_fits_uhwi_p (idx))
5224 0 : idxl = size_int (tree_to_uhwi (idx) + diff);
5225 : else
5226 : {
5227 0 : idxl = make_ssa_name (sizetype);
5228 0 : g = gimple_build_assign (idxl, PLUS_EXPR, idx,
5229 0 : size_int (diff));
5230 0 : insert_before (g);
5231 : }
5232 : }
5233 13623 : tree l = limb_access (type, var ? var : obj, idxl, true);
5234 6826 : if (bitint_extended && tree_fits_uhwi_p (idxl))
5235 : {
5236 0 : tree atype = limb_access_type (type, idxl);
5237 0 : if (!useless_type_conversion_p (atype, TREE_TYPE (rhs)))
5238 0 : rhs = add_cast (atype, rhs);
5239 : }
5240 6826 : if (!useless_type_conversion_p (TREE_TYPE (l), TREE_TYPE (rhs)))
5241 0 : rhs = add_cast (TREE_TYPE (l), rhs);
5242 6826 : g = gimple_build_assign (l, rhs);
5243 6826 : insert_before (g);
5244 : }
5245 : }
5246 9171 : m_first = false;
5247 9171 : if (kind == bitint_prec_huge && i <= 1)
5248 : {
5249 2388 : if (i == 0)
5250 : {
5251 1194 : idx = make_ssa_name (sizetype);
5252 1194 : g = gimple_build_assign (idx, PLUS_EXPR, idx_first,
5253 : bitint_big_endian
5254 0 : ? size_int (-1) : size_one_node);
5255 1194 : insert_before (g);
5256 : }
5257 : else
5258 : {
5259 1194 : g = gimple_build_assign (idx_next, PLUS_EXPR, idx_first,
5260 2388 : size_int (bitint_big_endian ? -2 : 2));
5261 1194 : insert_before (g);
5262 1194 : if (bitint_big_endian)
5263 0 : g = gimple_build_cond (NE_EXPR, idx_first,
5264 0 : size_int (nelts + 1 - fin),
5265 : NULL_TREE, NULL_TREE);
5266 : else
5267 1194 : g = gimple_build_cond (NE_EXPR, idx_next, size_int (fin),
5268 : NULL_TREE, NULL_TREE);
5269 1194 : insert_before (g);
5270 1194 : m_gsi = gsi_for_stmt (final_stmt);
5271 1194 : m_bb = NULL;
5272 : }
5273 : }
5274 : }
5275 :
5276 2733 : finish_arith_overflow (var, obj, type, ovf, lhs, orig_obj, stmt,
5277 : prec_limbs, code);
5278 : }
5279 :
5280 : /* Lower a .MUL_OVERFLOW call with at least one large/huge _BitInt
5281 : argument or return type _Complex large/huge _BitInt. */
5282 :
5283 : void
5284 1479 : bitint_large_huge::lower_mul_overflow (tree obj, gimple *stmt)
5285 : {
5286 1479 : tree arg0 = gimple_call_arg (stmt, 0);
5287 1479 : tree arg1 = gimple_call_arg (stmt, 1);
5288 1479 : tree lhs = gimple_call_lhs (stmt);
5289 1479 : if (!lhs)
5290 : {
5291 0 : gimple_stmt_iterator gsi = gsi_for_stmt (stmt);
5292 0 : gsi_remove (&gsi, true);
5293 0 : return;
5294 : }
5295 1479 : gimple *final_stmt = gsi_stmt (m_gsi);
5296 1479 : tree type = TREE_TYPE (lhs);
5297 1479 : if (TREE_CODE (type) == COMPLEX_TYPE)
5298 1464 : type = TREE_TYPE (type);
5299 1479 : int prec = TYPE_PRECISION (type), prec0, prec1;
5300 1479 : arg0 = handle_operand_addr (arg0, stmt, NULL, &prec0);
5301 1479 : arg1 = handle_operand_addr (arg1, stmt, NULL, &prec1);
5302 1479 : int prec2 = ((prec0 < 0 ? -prec0 : prec0)
5303 1479 : + (prec1 < 0 ? -prec1 : prec1));
5304 1479 : if (prec0 == 1 || prec1 == 1)
5305 35 : --prec2;
5306 1479 : tree var = NULL_TREE;
5307 1479 : tree orig_obj = obj;
5308 1479 : bool force_var = false;
5309 1479 : if (obj == NULL_TREE
5310 886 : && BITINT_TYPE_P (type)
5311 877 : && bitint_precision_kind (type) >= bitint_prec_large
5312 853 : && m_names
5313 2320 : && bitmap_bit_p (m_names, SSA_NAME_VERSION (lhs)))
5314 : {
5315 841 : int part = var_to_partition (m_map, lhs);
5316 841 : gcc_assert (m_vars[part] != NULL_TREE);
5317 841 : obj = m_vars[part];
5318 841 : if (TREE_TYPE (lhs) == type)
5319 7 : orig_obj = obj;
5320 : }
5321 638 : else if (obj != NULL_TREE && DECL_P (obj))
5322 : {
5323 1755 : for (int i = 0; i < 2; ++i)
5324 : {
5325 1170 : tree arg = i ? arg1 : arg0;
5326 1170 : if (TREE_CODE (arg) == ADDR_EXPR)
5327 1170 : arg = TREE_OPERAND (arg, 0);
5328 1170 : if (get_base_address (arg) == obj)
5329 : {
5330 : force_var = true;
5331 : break;
5332 : }
5333 : }
5334 : }
5335 1479 : if (obj == NULL_TREE
5336 1479 : || force_var
5337 1434 : || !BITINT_TYPE_P (type)
5338 1434 : || bitint_precision_kind (type) < bitint_prec_large
5339 3747 : || prec2 > (CEIL (prec, limb_prec) * limb_prec * (orig_obj ? 1 : 2)))
5340 : {
5341 564 : unsigned HOST_WIDE_INT nelts = CEIL (MAX (prec, prec2), limb_prec);
5342 564 : tree atype = build_array_type_nelts (m_limb_type, nelts);
5343 564 : var = create_tmp_var (atype);
5344 : }
5345 1479 : tree addr = build_fold_addr_expr (var ? var : obj);
5346 1479 : addr = force_gimple_operand_gsi (&m_gsi, addr, true,
5347 : NULL_TREE, true, GSI_SAME_STMT);
5348 1479 : tree sitype = lang_hooks.types.type_for_mode (SImode, 0);
5349 1479 : gimple *g
5350 1479 : = gimple_build_call_internal (IFN_MULBITINT, 6,
5351 : addr, build_int_cst (sitype,
5352 1479 : MAX (prec2, prec)),
5353 1479 : arg0, build_int_cst (sitype, prec0),
5354 1479 : arg1, build_int_cst (sitype, prec1));
5355 1479 : insert_before (g);
5356 :
5357 1479 : unsigned start, end;
5358 1479 : bool check_zero;
5359 1479 : tree ovf = arith_overflow (MULT_EXPR, type, prec, prec0, prec1, prec2,
5360 : &start, &end, &check_zero);
5361 1479 : if (ovf == NULL_TREE)
5362 : {
5363 1477 : unsigned startlimb = start / limb_prec;
5364 1477 : unsigned endlimb = (end - 1) / limb_prec;
5365 1477 : unsigned nelts = CEIL (MAX (prec, prec2), limb_prec);
5366 1477 : unsigned cnt;
5367 1477 : bool use_loop = false;
5368 1477 : if (startlimb == endlimb)
5369 : cnt = 1;
5370 1190 : else if (startlimb + 1 == endlimb)
5371 : cnt = 2;
5372 1013 : else if ((end % limb_prec) == 0)
5373 : {
5374 : cnt = 2;
5375 : use_loop = true;
5376 : }
5377 : else
5378 : {
5379 767 : cnt = 3;
5380 767 : use_loop = startlimb + 2 < endlimb;
5381 : }
5382 767 : if (cnt == 1)
5383 : {
5384 507 : tree l = limb_access (NULL_TREE, var ? var : obj,
5385 287 : size_int (bitint_big_endian
5386 : ? nelts - 1 - startlimb
5387 : : startlimb), true);
5388 287 : g = gimple_build_assign (make_ssa_name (m_limb_type), l);
5389 287 : insert_before (g);
5390 287 : l = arith_overflow_extract_bits (start, end, gimple_assign_lhs (g),
5391 : startlimb, check_zero);
5392 287 : ovf = make_ssa_name (boolean_type_node);
5393 287 : if (check_zero)
5394 247 : g = gimple_build_assign (ovf, NE_EXPR, l,
5395 : build_zero_cst (m_limb_type));
5396 : else
5397 : {
5398 40 : g = gimple_build_assign (make_ssa_name (m_limb_type),
5399 : PLUS_EXPR, l,
5400 : build_int_cst (m_limb_type, 1));
5401 40 : insert_before (g);
5402 40 : g = gimple_build_assign (ovf, GT_EXPR, gimple_assign_lhs (g),
5403 : build_int_cst (m_limb_type, 1));
5404 : }
5405 287 : insert_before (g);
5406 : }
5407 : else
5408 : {
5409 1190 : basic_block edge_bb = NULL;
5410 1190 : gimple_stmt_iterator gsi = m_gsi;
5411 1190 : gsi_prev (&gsi);
5412 1190 : edge e = split_block (gsi_bb (gsi), gsi_stmt (gsi));
5413 1190 : edge_bb = e->src;
5414 1190 : m_gsi = gsi_end_bb (edge_bb);
5415 :
5416 1190 : tree cmp = build_zero_cst (m_limb_type);
5417 5527 : for (unsigned i = 0; i < cnt; i++)
5418 : {
5419 3147 : tree idx, idx_next = NULL_TREE;
5420 3147 : if (i == 0)
5421 1190 : idx = size_int (bitint_big_endian
5422 : ? nelts - 1 - startlimb : startlimb);
5423 1957 : else if (i == 2)
5424 767 : idx = size_int (bitint_big_endian
5425 : ? nelts - 1 - endlimb : endlimb);
5426 1190 : else if (use_loop)
5427 665 : idx = create_loop (size_int (bitint_big_endian
5428 : ? nelts - startlimb - 2
5429 : : startlimb + 1), &idx_next);
5430 : else
5431 525 : idx = size_int (bitint_big_endian
5432 : ? nelts - startlimb - 2 : startlimb + 1);
5433 4988 : tree l = limb_access (NULL_TREE, var ? var : obj, idx, true);
5434 3147 : g = gimple_build_assign (make_ssa_name (m_limb_type), l);
5435 3147 : insert_before (g);
5436 3147 : l = gimple_assign_lhs (g);
5437 3147 : if (i == 0 || i == 2)
5438 2724 : l = arith_overflow_extract_bits (start, end, l,
5439 : i == 0 ? startlimb : endlimb,
5440 : check_zero);
5441 1957 : if (i == 0 && !check_zero)
5442 : {
5443 459 : cmp = l;
5444 459 : g = gimple_build_assign (make_ssa_name (m_limb_type),
5445 : PLUS_EXPR, l,
5446 : build_int_cst (m_limb_type, 1));
5447 459 : insert_before (g);
5448 459 : g = gimple_build_cond (GT_EXPR, gimple_assign_lhs (g),
5449 : build_int_cst (m_limb_type, 1),
5450 : NULL_TREE, NULL_TREE);
5451 : }
5452 : else
5453 2688 : g = gimple_build_cond (NE_EXPR, l, cmp, NULL_TREE, NULL_TREE);
5454 3147 : insert_before (g);
5455 3147 : edge e1 = split_block (gsi_bb (m_gsi), g);
5456 3147 : e1->flags = EDGE_FALSE_VALUE;
5457 3147 : edge e2 = make_edge (e1->src, gimple_bb (final_stmt),
5458 : EDGE_TRUE_VALUE);
5459 3147 : e1->probability = profile_probability::likely ();
5460 3147 : e2->probability = e1->probability.invert ();
5461 3147 : if (i == 0)
5462 1190 : set_immediate_dominator (CDI_DOMINATORS, e2->dest, e2->src);
5463 3147 : m_gsi = gsi_after_labels (e1->dest);
5464 3147 : if (i == 1 && use_loop)
5465 : {
5466 665 : g = gimple_build_assign (idx_next, PLUS_EXPR, idx,
5467 : bitint_big_endian
5468 0 : ? size_int (-1) : size_one_node);
5469 665 : insert_before (g);
5470 665 : if (bitint_big_endian)
5471 0 : g = gimple_build_cond (NE_EXPR, idx,
5472 0 : size_int (nelts - endlimb
5473 : - (cnt == 2)),
5474 : NULL_TREE, NULL_TREE);
5475 : else
5476 665 : g = gimple_build_cond (NE_EXPR, idx_next,
5477 665 : size_int (endlimb + (cnt == 2)),
5478 : NULL_TREE, NULL_TREE);
5479 665 : insert_before (g);
5480 665 : edge true_edge, false_edge;
5481 665 : extract_true_false_edges_from_block (gsi_bb (m_gsi),
5482 : &true_edge,
5483 : &false_edge);
5484 665 : m_gsi = gsi_after_labels (false_edge->dest);
5485 665 : m_bb = NULL;
5486 : }
5487 : }
5488 :
5489 1190 : ovf = make_ssa_name (boolean_type_node);
5490 1190 : basic_block bb = gimple_bb (final_stmt);
5491 1190 : gphi *phi = create_phi_node (ovf, bb);
5492 1190 : edge e1 = find_edge (gsi_bb (m_gsi), bb);
5493 1190 : edge_iterator ei;
5494 5527 : FOR_EACH_EDGE (e, ei, bb->preds)
5495 : {
5496 4337 : tree val = e == e1 ? boolean_false_node : boolean_true_node;
5497 4337 : add_phi_arg (phi, val, e, UNKNOWN_LOCATION);
5498 : }
5499 1190 : m_gsi = gsi_for_stmt (final_stmt);
5500 : }
5501 : }
5502 :
5503 1479 : finish_arith_overflow (var, obj, type, ovf, lhs, orig_obj, stmt,
5504 1479 : CEIL (MAX (prec, prec2), limb_prec), MULT_EXPR);
5505 : }
5506 :
5507 : /* Lower REALPART_EXPR or IMAGPART_EXPR stmt extracting part of result from
5508 : .{ADD,SUB,MUL}_OVERFLOW call. */
5509 :
5510 : void
5511 6002 : bitint_large_huge::lower_cplxpart_stmt (tree obj, gimple *stmt)
5512 : {
5513 6002 : tree rhs1 = gimple_assign_rhs1 (stmt);
5514 6002 : rhs1 = TREE_OPERAND (rhs1, 0);
5515 6002 : if (obj == NULL_TREE)
5516 : {
5517 5929 : int part = var_to_partition (m_map, gimple_assign_lhs (stmt));
5518 5929 : gcc_assert (m_vars[part] != NULL_TREE);
5519 : obj = m_vars[part];
5520 : }
5521 6002 : if (TREE_CODE (rhs1) == SSA_NAME
5522 6002 : && (m_names == NULL
5523 6001 : || !bitmap_bit_p (m_names, SSA_NAME_VERSION (rhs1))))
5524 : {
5525 1549 : lower_call (obj, SSA_NAME_DEF_STMT (rhs1));
5526 1549 : return;
5527 : }
5528 4453 : int part = var_to_partition (m_map, rhs1);
5529 4453 : gcc_assert (m_vars[part] != NULL_TREE);
5530 4453 : tree var = m_vars[part];
5531 4453 : unsigned HOST_WIDE_INT nelts
5532 4453 : = tree_to_uhwi (TYPE_SIZE (TREE_TYPE (obj))) / limb_prec;
5533 4453 : tree atype = build_array_type_nelts (m_limb_type, nelts);
5534 4453 : if (!useless_type_conversion_p (atype, TREE_TYPE (obj)))
5535 102 : obj = build1 (VIEW_CONVERT_EXPR, atype, obj);
5536 4453 : tree off = build_int_cst (build_pointer_type (TREE_TYPE (var)),
5537 4453 : gimple_assign_rhs_code (stmt) == REALPART_EXPR
5538 4453 : ? 0 : nelts * m_limb_size);
5539 4453 : tree v2 = build2 (MEM_REF, atype, build_fold_addr_expr (var), off);
5540 4453 : gimple *g = gimple_build_assign (obj, v2);
5541 4453 : insert_before (g);
5542 : }
5543 :
5544 : /* Lower COMPLEX_EXPR stmt. */
5545 :
5546 : void
5547 18 : bitint_large_huge::lower_complexexpr_stmt (gimple *stmt)
5548 : {
5549 18 : tree lhs = gimple_assign_lhs (stmt);
5550 18 : tree rhs1 = gimple_assign_rhs1 (stmt);
5551 18 : tree rhs2 = gimple_assign_rhs2 (stmt);
5552 18 : int part = var_to_partition (m_map, lhs);
5553 18 : gcc_assert (m_vars[part] != NULL_TREE);
5554 18 : lhs = m_vars[part];
5555 18 : unsigned HOST_WIDE_INT nelts
5556 18 : = tree_to_uhwi (TYPE_SIZE (TREE_TYPE (rhs1))) / limb_prec;
5557 18 : tree atype = build_array_type_nelts (m_limb_type, nelts);
5558 18 : tree zero = build_zero_cst (build_pointer_type (TREE_TYPE (lhs)));
5559 18 : tree v1 = build2 (MEM_REF, atype, build_fold_addr_expr (lhs), zero);
5560 18 : tree v2;
5561 18 : if (TREE_CODE (rhs1) == SSA_NAME)
5562 : {
5563 18 : part = var_to_partition (m_map, rhs1);
5564 18 : gcc_assert (m_vars[part] != NULL_TREE);
5565 : v2 = m_vars[part];
5566 : }
5567 0 : else if (integer_zerop (rhs1))
5568 0 : v2 = build_zero_cst (atype);
5569 : else
5570 0 : v2 = tree_output_constant_def (rhs1);
5571 18 : if (!useless_type_conversion_p (atype, TREE_TYPE (v2)))
5572 18 : v2 = build1 (VIEW_CONVERT_EXPR, atype, v2);
5573 18 : gimple *g = gimple_build_assign (v1, v2);
5574 18 : insert_before (g);
5575 18 : tree off = fold_convert (build_pointer_type (TREE_TYPE (lhs)),
5576 : TYPE_SIZE_UNIT (atype));
5577 18 : v1 = build2 (MEM_REF, atype, build_fold_addr_expr (lhs), off);
5578 18 : if (TREE_CODE (rhs2) == SSA_NAME)
5579 : {
5580 0 : part = var_to_partition (m_map, rhs2);
5581 0 : gcc_assert (m_vars[part] != NULL_TREE);
5582 : v2 = m_vars[part];
5583 : }
5584 18 : else if (integer_zerop (rhs2))
5585 18 : v2 = build_zero_cst (atype);
5586 : else
5587 0 : v2 = tree_output_constant_def (rhs2);
5588 18 : if (!useless_type_conversion_p (atype, TREE_TYPE (v2)))
5589 0 : v2 = build1 (VIEW_CONVERT_EXPR, atype, v2);
5590 18 : g = gimple_build_assign (v1, v2);
5591 18 : insert_before (g);
5592 18 : }
5593 :
5594 : /* Lower a .{CLZ,CTZ,CLRSB,FFS,PARITY,POPCOUNT} call with one large/huge _BitInt
5595 : argument. */
5596 :
5597 : void
5598 101 : bitint_large_huge::lower_bit_query (gimple *stmt)
5599 : {
5600 101 : tree arg0 = gimple_call_arg (stmt, 0);
5601 101 : tree arg1 = (gimple_call_num_args (stmt) == 2
5602 101 : ? gimple_call_arg (stmt, 1) : NULL_TREE);
5603 101 : tree lhs = gimple_call_lhs (stmt);
5604 101 : gimple *g;
5605 :
5606 101 : if (!lhs)
5607 : {
5608 0 : gimple_stmt_iterator gsi = gsi_for_stmt (stmt);
5609 0 : gsi_remove (&gsi, true);
5610 0 : return;
5611 : }
5612 101 : tree type = TREE_TYPE (arg0);
5613 101 : gcc_assert (BITINT_TYPE_P (type));
5614 101 : bitint_prec_kind kind = bitint_precision_kind (type);
5615 101 : gcc_assert (kind >= bitint_prec_large);
5616 101 : enum internal_fn ifn = gimple_call_internal_fn (stmt);
5617 101 : enum built_in_function fcode = END_BUILTINS;
5618 101 : gcc_assert (TYPE_PRECISION (unsigned_type_node) == limb_prec
5619 : || TYPE_PRECISION (long_unsigned_type_node) == limb_prec
5620 : || TYPE_PRECISION (long_long_unsigned_type_node) == limb_prec);
5621 101 : switch (ifn)
5622 : {
5623 26 : case IFN_CLZ:
5624 26 : if (TYPE_PRECISION (unsigned_type_node) == limb_prec)
5625 : fcode = BUILT_IN_CLZ;
5626 26 : else if (TYPE_PRECISION (long_unsigned_type_node) == limb_prec)
5627 : fcode = BUILT_IN_CLZL;
5628 : else
5629 0 : fcode = BUILT_IN_CLZLL;
5630 : break;
5631 11 : case IFN_FFS:
5632 : /* .FFS (X) is .CTZ (X, -1) + 1, though under the hood
5633 : we don't add the addend at the end. */
5634 11 : arg1 = integer_zero_node;
5635 : /* FALLTHRU */
5636 39 : case IFN_CTZ:
5637 39 : if (TYPE_PRECISION (unsigned_type_node) == limb_prec)
5638 : fcode = BUILT_IN_CTZ;
5639 39 : else if (TYPE_PRECISION (long_unsigned_type_node) == limb_prec)
5640 : fcode = BUILT_IN_CTZL;
5641 : else
5642 0 : fcode = BUILT_IN_CTZLL;
5643 39 : m_upwards = true;
5644 39 : break;
5645 9 : case IFN_CLRSB:
5646 9 : if (TYPE_PRECISION (unsigned_type_node) == limb_prec)
5647 : fcode = BUILT_IN_CLRSB;
5648 9 : else if (TYPE_PRECISION (long_unsigned_type_node) == limb_prec)
5649 : fcode = BUILT_IN_CLRSBL;
5650 : else
5651 0 : fcode = BUILT_IN_CLRSBLL;
5652 : break;
5653 16 : case IFN_PARITY:
5654 16 : if (TYPE_PRECISION (unsigned_type_node) == limb_prec)
5655 : fcode = BUILT_IN_PARITY;
5656 16 : else if (TYPE_PRECISION (long_unsigned_type_node) == limb_prec)
5657 : fcode = BUILT_IN_PARITYL;
5658 : else
5659 0 : fcode = BUILT_IN_PARITYLL;
5660 16 : m_upwards = true;
5661 16 : break;
5662 11 : case IFN_POPCOUNT:
5663 11 : if (TYPE_PRECISION (unsigned_type_node) == limb_prec)
5664 : fcode = BUILT_IN_POPCOUNT;
5665 11 : else if (TYPE_PRECISION (long_unsigned_type_node) == limb_prec)
5666 : fcode = BUILT_IN_POPCOUNTL;
5667 : else
5668 0 : fcode = BUILT_IN_POPCOUNTLL;
5669 11 : m_upwards = true;
5670 11 : break;
5671 0 : default:
5672 0 : gcc_unreachable ();
5673 : }
5674 101 : tree fndecl = builtin_decl_explicit (fcode), res = NULL_TREE;
5675 101 : unsigned cnt = 0, rem = 0, end = 0, prec = TYPE_PRECISION (type);
5676 101 : unsigned nelts = CEIL (prec, limb_prec);
5677 101 : struct bq_details { edge e; tree val, addend; } *bqp = NULL;
5678 101 : basic_block edge_bb = NULL;
5679 101 : if (m_upwards)
5680 : {
5681 66 : tree idx = NULL_TREE, idx_first = NULL_TREE, idx_next = NULL_TREE;
5682 66 : if (kind == bitint_prec_large)
5683 : cnt = nelts;
5684 : else
5685 : {
5686 39 : rem = (prec % (2 * limb_prec));
5687 39 : end = (prec - rem) / limb_prec;
5688 39 : cnt = 2 + CEIL (rem, limb_prec);
5689 39 : idx = idx_first = create_loop (bitint_big_endian
5690 39 : ? size_int (nelts - 1)
5691 : : size_zero_node, &idx_next);
5692 : }
5693 :
5694 66 : if (ifn == IFN_CTZ || ifn == IFN_FFS)
5695 : {
5696 39 : gimple_stmt_iterator gsi = gsi_for_stmt (stmt);
5697 39 : gsi_prev (&gsi);
5698 39 : edge e = split_block (gsi_bb (gsi), gsi_stmt (gsi));
5699 39 : edge_bb = e->src;
5700 39 : if (kind == bitint_prec_large)
5701 32 : m_gsi = gsi_end_bb (edge_bb);
5702 39 : bqp = XALLOCAVEC (struct bq_details, cnt);
5703 : }
5704 : else
5705 27 : m_after_stmt = stmt;
5706 66 : if (kind != bitint_prec_large)
5707 39 : m_upwards_2limb = end;
5708 :
5709 244 : for (unsigned i = 0; i < cnt; i++)
5710 : {
5711 178 : m_data_cnt = 0;
5712 178 : if (kind == bitint_prec_large)
5713 83 : idx = size_int (bitint_big_endian ? nelts - 1 - i : i);
5714 95 : else if (i >= 2)
5715 17 : idx = size_int (bitint_big_endian
5716 : ? nelts - 1 - end - (i > 2) : end + (i > 2));
5717 :
5718 178 : tree rhs1 = handle_operand (arg0, idx);
5719 178 : if (!useless_type_conversion_p (m_limb_type, TREE_TYPE (rhs1)))
5720 : {
5721 32 : if (!TYPE_UNSIGNED (TREE_TYPE (rhs1)))
5722 5 : rhs1 = add_cast (unsigned_type_for (TREE_TYPE (rhs1)), rhs1);
5723 32 : rhs1 = add_cast (m_limb_type, rhs1);
5724 : }
5725 :
5726 178 : tree in, out, tem;
5727 178 : if (ifn == IFN_PARITY)
5728 43 : in = prepare_data_in_out (build_zero_cst (m_limb_type), idx, &out);
5729 135 : else if (ifn == IFN_FFS)
5730 29 : in = prepare_data_in_out (integer_one_node, idx, &out);
5731 : else
5732 106 : in = prepare_data_in_out (integer_zero_node, idx, &out);
5733 :
5734 178 : switch (ifn)
5735 : {
5736 104 : case IFN_CTZ:
5737 104 : case IFN_FFS:
5738 104 : g = gimple_build_cond (NE_EXPR, rhs1,
5739 : build_zero_cst (m_limb_type),
5740 : NULL_TREE, NULL_TREE);
5741 104 : insert_before (g);
5742 104 : edge e1, e2;
5743 104 : e1 = split_block (gsi_bb (m_gsi), g);
5744 104 : e1->flags = EDGE_FALSE_VALUE;
5745 104 : e2 = make_edge (e1->src, gimple_bb (stmt), EDGE_TRUE_VALUE);
5746 104 : e1->probability = profile_probability::unlikely ();
5747 104 : e2->probability = e1->probability.invert ();
5748 104 : if (i == 0)
5749 39 : set_immediate_dominator (CDI_DOMINATORS, e2->dest, e2->src);
5750 104 : m_gsi = gsi_after_labels (e1->dest);
5751 104 : bqp[i].e = e2;
5752 104 : bqp[i].val = rhs1;
5753 104 : if (tree_fits_uhwi_p (idx))
5754 58 : bqp[i].addend
5755 58 : = build_int_cst (integer_type_node,
5756 : (bitint_big_endian
5757 58 : ? nelts - 1 - tree_to_uhwi (idx)
5758 58 : : tree_to_uhwi (idx)) * limb_prec
5759 58 : + (ifn == IFN_FFS));
5760 : else
5761 : {
5762 46 : bqp[i].addend = in;
5763 46 : if (i == 1)
5764 23 : res = out;
5765 : else
5766 23 : res = make_ssa_name (integer_type_node);
5767 46 : g = gimple_build_assign (res, PLUS_EXPR, in,
5768 : build_int_cst (integer_type_node,
5769 46 : limb_prec));
5770 46 : insert_before (g);
5771 46 : m_data[m_data_cnt] = res;
5772 : }
5773 : break;
5774 43 : case IFN_PARITY:
5775 43 : if (!integer_zerop (in))
5776 : {
5777 37 : if (kind == bitint_prec_huge && i == 1)
5778 10 : res = out;
5779 : else
5780 27 : res = make_ssa_name (m_limb_type);
5781 37 : g = gimple_build_assign (res, BIT_XOR_EXPR, in, rhs1);
5782 37 : insert_before (g);
5783 : }
5784 : else
5785 : res = rhs1;
5786 43 : m_data[m_data_cnt] = res;
5787 43 : break;
5788 31 : case IFN_POPCOUNT:
5789 31 : g = gimple_build_call (fndecl, 1, rhs1);
5790 31 : tem = make_ssa_name (integer_type_node);
5791 31 : gimple_call_set_lhs (g, tem);
5792 31 : insert_before (g);
5793 31 : if (!integer_zerop (in))
5794 : {
5795 26 : if (kind == bitint_prec_huge && i == 1)
5796 6 : res = out;
5797 : else
5798 20 : res = make_ssa_name (integer_type_node);
5799 26 : g = gimple_build_assign (res, PLUS_EXPR, in, tem);
5800 26 : insert_before (g);
5801 : }
5802 : else
5803 : res = tem;
5804 31 : m_data[m_data_cnt] = res;
5805 31 : break;
5806 0 : default:
5807 0 : gcc_unreachable ();
5808 : }
5809 :
5810 178 : m_first = false;
5811 178 : if (kind == bitint_prec_huge && i <= 1)
5812 : {
5813 78 : if (i == 0)
5814 : {
5815 39 : idx = make_ssa_name (sizetype);
5816 39 : g = gimple_build_assign (idx, PLUS_EXPR, idx_first,
5817 : bitint_big_endian
5818 0 : ? size_int (-1) : size_one_node);
5819 39 : insert_before (g);
5820 : }
5821 : else
5822 : {
5823 39 : g = gimple_build_assign (idx_next, PLUS_EXPR, idx_first,
5824 78 : size_int (bitint_big_endian
5825 : ? -2 : 2));
5826 39 : insert_before (g);
5827 39 : if (bitint_big_endian)
5828 0 : g = gimple_build_cond (NE_EXPR, idx_first,
5829 0 : size_int (cnt - 1),
5830 : NULL_TREE, NULL_TREE);
5831 : else
5832 39 : g = gimple_build_cond (NE_EXPR, idx_next, size_int (end),
5833 : NULL_TREE, NULL_TREE);
5834 39 : insert_before (g);
5835 39 : if (ifn == IFN_CTZ || ifn == IFN_FFS)
5836 23 : m_gsi = gsi_after_labels (edge_bb);
5837 : else
5838 16 : m_gsi = gsi_for_stmt (stmt);
5839 39 : m_bb = NULL;
5840 : }
5841 : }
5842 : }
5843 : }
5844 : else
5845 : {
5846 35 : tree idx = NULL_TREE, idx_next = NULL_TREE, first = NULL_TREE;
5847 35 : int sub_one = 0;
5848 35 : if (kind == bitint_prec_large)
5849 : cnt = nelts;
5850 : else
5851 : {
5852 18 : rem = prec % limb_prec;
5853 18 : if (rem == 0 && (!TYPE_UNSIGNED (type) || ifn == IFN_CLRSB))
5854 : rem = limb_prec;
5855 18 : end = (prec - rem) / limb_prec;
5856 18 : cnt = 1 + (rem != 0);
5857 18 : if (ifn == IFN_CLRSB)
5858 5 : sub_one = 1;
5859 : }
5860 :
5861 35 : gimple_stmt_iterator gsi = gsi_for_stmt (stmt);
5862 35 : gsi_prev (&gsi);
5863 35 : edge e = split_block (gsi_bb (gsi), gsi_stmt (gsi));
5864 35 : edge_bb = e->src;
5865 35 : m_gsi = gsi_end_bb (edge_bb);
5866 :
5867 35 : if (ifn == IFN_CLZ)
5868 26 : bqp = XALLOCAVEC (struct bq_details, cnt);
5869 : else
5870 : {
5871 9 : gsi = gsi_for_stmt (stmt);
5872 9 : gsi_prev (&gsi);
5873 9 : e = split_block (gsi_bb (gsi), gsi_stmt (gsi));
5874 9 : edge_bb = e->src;
5875 9 : bqp = XALLOCAVEC (struct bq_details, 2 * cnt);
5876 : }
5877 :
5878 116 : for (unsigned i = 0; i < cnt; i++)
5879 : {
5880 81 : m_data_cnt = 0;
5881 81 : if (kind == bitint_prec_large)
5882 51 : idx = size_int (bitint_big_endian ? i : cnt - i - 1);
5883 30 : else if (i == cnt - 1)
5884 18 : idx = create_loop (size_int (bitint_big_endian ? i : end - 1),
5885 : &idx_next);
5886 : else
5887 12 : idx = bitint_big_endian ? size_zero_node : size_int (end);
5888 :
5889 81 : tree rhs1 = handle_operand (arg0, idx);
5890 81 : if (!useless_type_conversion_p (m_limb_type, TREE_TYPE (rhs1)))
5891 : {
5892 19 : if (ifn == IFN_CLZ && !TYPE_UNSIGNED (TREE_TYPE (rhs1)))
5893 0 : rhs1 = add_cast (unsigned_type_for (TREE_TYPE (rhs1)), rhs1);
5894 19 : else if (ifn == IFN_CLRSB && TYPE_UNSIGNED (TREE_TYPE (rhs1)))
5895 0 : rhs1 = add_cast (signed_type_for (TREE_TYPE (rhs1)), rhs1);
5896 19 : rhs1 = add_cast (m_limb_type, rhs1);
5897 : }
5898 :
5899 81 : if (ifn == IFN_CLZ)
5900 : {
5901 59 : g = gimple_build_cond (NE_EXPR, rhs1,
5902 : build_zero_cst (m_limb_type),
5903 : NULL_TREE, NULL_TREE);
5904 59 : insert_before (g);
5905 59 : edge e1 = split_block (gsi_bb (m_gsi), g);
5906 59 : e1->flags = EDGE_FALSE_VALUE;
5907 59 : edge e2 = make_edge (e1->src, gimple_bb (stmt), EDGE_TRUE_VALUE);
5908 59 : e1->probability = profile_probability::unlikely ();
5909 59 : e2->probability = e1->probability.invert ();
5910 59 : if (i == 0)
5911 26 : set_immediate_dominator (CDI_DOMINATORS, e2->dest, e2->src);
5912 59 : m_gsi = gsi_after_labels (e1->dest);
5913 59 : bqp[i].e = e2;
5914 59 : bqp[i].val = rhs1;
5915 : }
5916 : else
5917 : {
5918 22 : if (i == 0)
5919 : {
5920 9 : first = rhs1;
5921 9 : g = gimple_build_assign (make_ssa_name (m_limb_type),
5922 : PLUS_EXPR, rhs1,
5923 : build_int_cst (m_limb_type, 1));
5924 9 : insert_before (g);
5925 9 : g = gimple_build_cond (GT_EXPR, gimple_assign_lhs (g),
5926 : build_int_cst (m_limb_type, 1),
5927 : NULL_TREE, NULL_TREE);
5928 9 : insert_before (g);
5929 : }
5930 : else
5931 : {
5932 13 : g = gimple_build_assign (make_ssa_name (m_limb_type),
5933 : BIT_XOR_EXPR, rhs1, first);
5934 13 : insert_before (g);
5935 13 : tree stype = signed_type_for (m_limb_type);
5936 13 : g = gimple_build_cond (LT_EXPR,
5937 : add_cast (stype,
5938 : gimple_assign_lhs (g)),
5939 : build_zero_cst (stype),
5940 : NULL_TREE, NULL_TREE);
5941 13 : insert_before (g);
5942 13 : edge e1 = split_block (gsi_bb (m_gsi), g);
5943 13 : e1->flags = EDGE_FALSE_VALUE;
5944 13 : edge e2 = make_edge (e1->src, gimple_bb (stmt),
5945 : EDGE_TRUE_VALUE);
5946 13 : e1->probability = profile_probability::unlikely ();
5947 13 : e2->probability = e1->probability.invert ();
5948 13 : if (i == 1)
5949 9 : set_immediate_dominator (CDI_DOMINATORS, e2->dest,
5950 : e2->src);
5951 13 : m_gsi = gsi_after_labels (e1->dest);
5952 13 : bqp[2 * i].e = e2;
5953 13 : g = gimple_build_cond (NE_EXPR, rhs1, first,
5954 : NULL_TREE, NULL_TREE);
5955 13 : insert_before (g);
5956 : }
5957 22 : edge e1 = split_block (gsi_bb (m_gsi), g);
5958 22 : e1->flags = EDGE_FALSE_VALUE;
5959 22 : edge e2 = make_edge (e1->src, edge_bb, EDGE_TRUE_VALUE);
5960 22 : e1->probability = profile_probability::unlikely ();
5961 22 : e2->probability = e1->probability.invert ();
5962 22 : if (i == 0)
5963 9 : set_immediate_dominator (CDI_DOMINATORS, e2->dest, e2->src);
5964 22 : m_gsi = gsi_after_labels (e1->dest);
5965 22 : bqp[2 * i + 1].e = e2;
5966 22 : bqp[i].val = rhs1;
5967 : }
5968 81 : if (tree_fits_uhwi_p (idx))
5969 126 : bqp[i].addend
5970 63 : = build_int_cst (integer_type_node,
5971 63 : (int) prec
5972 63 : - (((int) (bitint_big_endian
5973 0 : ? nelts - 1 - tree_to_uhwi (idx)
5974 63 : : tree_to_uhwi (idx)) + 1)
5975 63 : * limb_prec) - sub_one);
5976 : else
5977 : {
5978 18 : tree in, out;
5979 18 : in = build_int_cst (integer_type_node, rem - sub_one);
5980 18 : m_first = true;
5981 18 : in = prepare_data_in_out (in, idx, &out);
5982 18 : out = m_data[m_data_cnt + 1];
5983 18 : bqp[i].addend = in;
5984 18 : g = gimple_build_assign (out, PLUS_EXPR, in,
5985 : build_int_cst (integer_type_node,
5986 18 : limb_prec));
5987 18 : insert_before (g);
5988 18 : m_data[m_data_cnt] = out;
5989 : }
5990 :
5991 81 : m_first = false;
5992 81 : if (kind == bitint_prec_huge && i == cnt - 1)
5993 : {
5994 36 : g = gimple_build_assign (idx_next, PLUS_EXPR, idx,
5995 : bitint_big_endian
5996 18 : ? size_one_node : size_int (-1));
5997 18 : insert_before (g);
5998 18 : g = gimple_build_cond (NE_EXPR, idx,
5999 : bitint_big_endian
6000 0 : ? size_int (nelts - 1) : size_zero_node,
6001 : NULL_TREE, NULL_TREE);
6002 18 : insert_before (g);
6003 18 : edge true_edge, false_edge;
6004 18 : extract_true_false_edges_from_block (gsi_bb (m_gsi),
6005 : &true_edge, &false_edge);
6006 18 : m_gsi = gsi_after_labels (false_edge->dest);
6007 18 : m_bb = NULL;
6008 : }
6009 : }
6010 : }
6011 101 : switch (ifn)
6012 : {
6013 65 : case IFN_CLZ:
6014 65 : case IFN_CTZ:
6015 65 : case IFN_FFS:
6016 65 : gphi *phi1, *phi2, *phi3;
6017 65 : basic_block bb;
6018 65 : bb = gsi_bb (m_gsi);
6019 65 : remove_edge (find_edge (bb, gimple_bb (stmt)));
6020 65 : phi1 = create_phi_node (make_ssa_name (m_limb_type),
6021 : gimple_bb (stmt));
6022 65 : phi2 = create_phi_node (make_ssa_name (integer_type_node),
6023 : gimple_bb (stmt));
6024 293 : for (unsigned i = 0; i < cnt; i++)
6025 : {
6026 163 : add_phi_arg (phi1, bqp[i].val, bqp[i].e, UNKNOWN_LOCATION);
6027 163 : add_phi_arg (phi2, bqp[i].addend, bqp[i].e, UNKNOWN_LOCATION);
6028 : }
6029 65 : if (arg1 == NULL_TREE)
6030 : {
6031 35 : g = gimple_build_builtin_unreachable (m_loc);
6032 35 : insert_before (g);
6033 : }
6034 65 : m_gsi = gsi_for_stmt (stmt);
6035 65 : g = gimple_build_call (fndecl, 1, gimple_phi_result (phi1));
6036 65 : gimple_call_set_lhs (g, make_ssa_name (integer_type_node));
6037 65 : insert_before (g);
6038 65 : if (arg1 == NULL_TREE)
6039 35 : g = gimple_build_assign (lhs, PLUS_EXPR,
6040 : gimple_phi_result (phi2),
6041 : gimple_call_lhs (g));
6042 : else
6043 : {
6044 30 : g = gimple_build_assign (make_ssa_name (integer_type_node),
6045 : PLUS_EXPR, gimple_phi_result (phi2),
6046 : gimple_call_lhs (g));
6047 30 : insert_before (g);
6048 30 : edge e1 = split_block (gimple_bb (stmt), g);
6049 30 : edge e2 = make_edge (bb, e1->dest, EDGE_FALLTHRU);
6050 30 : e2->probability = profile_probability::always ();
6051 30 : set_immediate_dominator (CDI_DOMINATORS, e1->dest,
6052 : get_immediate_dominator (CDI_DOMINATORS,
6053 : e1->src));
6054 30 : phi3 = create_phi_node (make_ssa_name (integer_type_node), e1->dest);
6055 30 : add_phi_arg (phi3, gimple_assign_lhs (g), e1, UNKNOWN_LOCATION);
6056 30 : add_phi_arg (phi3, arg1, e2, UNKNOWN_LOCATION);
6057 30 : m_gsi = gsi_for_stmt (stmt);
6058 30 : g = gimple_build_assign (lhs, gimple_phi_result (phi3));
6059 : }
6060 65 : gsi_replace (&m_gsi, g, true);
6061 65 : break;
6062 9 : case IFN_CLRSB:
6063 9 : bb = gsi_bb (m_gsi);
6064 9 : remove_edge (find_edge (bb, edge_bb));
6065 9 : edge e;
6066 9 : e = make_edge (bb, gimple_bb (stmt), EDGE_FALLTHRU);
6067 9 : e->probability = profile_probability::always ();
6068 9 : set_immediate_dominator (CDI_DOMINATORS, gimple_bb (stmt),
6069 : get_immediate_dominator (CDI_DOMINATORS,
6070 : edge_bb));
6071 9 : phi1 = create_phi_node (make_ssa_name (m_limb_type),
6072 : edge_bb);
6073 9 : phi2 = create_phi_node (make_ssa_name (integer_type_node),
6074 : edge_bb);
6075 9 : phi3 = create_phi_node (make_ssa_name (integer_type_node),
6076 : gimple_bb (stmt));
6077 40 : for (unsigned i = 0; i < cnt; i++)
6078 : {
6079 22 : add_phi_arg (phi1, bqp[i].val, bqp[2 * i + 1].e, UNKNOWN_LOCATION);
6080 22 : add_phi_arg (phi2, bqp[i].addend, bqp[2 * i + 1].e,
6081 : UNKNOWN_LOCATION);
6082 22 : tree a = bqp[i].addend;
6083 22 : if (i && kind == bitint_prec_large)
6084 8 : a = int_const_binop (PLUS_EXPR, a, integer_minus_one_node);
6085 22 : if (i)
6086 13 : add_phi_arg (phi3, a, bqp[2 * i].e, UNKNOWN_LOCATION);
6087 : }
6088 9 : add_phi_arg (phi3, build_int_cst (integer_type_node, prec - 1), e,
6089 : UNKNOWN_LOCATION);
6090 9 : m_gsi = gsi_after_labels (edge_bb);
6091 9 : g = gimple_build_call (fndecl, 1,
6092 : add_cast (signed_type_for (m_limb_type),
6093 : gimple_phi_result (phi1)));
6094 9 : gimple_call_set_lhs (g, make_ssa_name (integer_type_node));
6095 9 : insert_before (g);
6096 9 : g = gimple_build_assign (make_ssa_name (integer_type_node),
6097 : PLUS_EXPR, gimple_call_lhs (g),
6098 : gimple_phi_result (phi2));
6099 9 : insert_before (g);
6100 9 : if (kind != bitint_prec_large)
6101 : {
6102 5 : g = gimple_build_assign (make_ssa_name (integer_type_node),
6103 : PLUS_EXPR, gimple_assign_lhs (g),
6104 : integer_one_node);
6105 5 : insert_before (g);
6106 : }
6107 9 : add_phi_arg (phi3, gimple_assign_lhs (g),
6108 : find_edge (edge_bb, gimple_bb (stmt)), UNKNOWN_LOCATION);
6109 9 : m_gsi = gsi_for_stmt (stmt);
6110 9 : g = gimple_build_assign (lhs, gimple_phi_result (phi3));
6111 9 : gsi_replace (&m_gsi, g, true);
6112 9 : break;
6113 16 : case IFN_PARITY:
6114 16 : g = gimple_build_call (fndecl, 1, res);
6115 16 : gimple_call_set_lhs (g, lhs);
6116 16 : gsi_replace (&m_gsi, g, true);
6117 16 : break;
6118 11 : case IFN_POPCOUNT:
6119 11 : g = gimple_build_assign (lhs, res);
6120 11 : gsi_replace (&m_gsi, g, true);
6121 11 : break;
6122 0 : default:
6123 0 : gcc_unreachable ();
6124 : }
6125 : }
6126 :
6127 : /* Lower a .{BSWAP,BITREVERSE} call with one large/huge _BitInt argument. */
6128 :
6129 : void
6130 15 : bitint_large_huge::lower_bswap_bitreverse (tree obj, gimple *stmt)
6131 : {
6132 15 : tree arg = gimple_call_arg (stmt, 0);
6133 15 : tree lhs = gimple_call_lhs (stmt);
6134 15 : gimple *g;
6135 :
6136 15 : if (!lhs)
6137 : {
6138 0 : gimple_stmt_iterator gsi = gsi_for_stmt (stmt);
6139 0 : gsi_remove (&gsi, true);
6140 0 : return;
6141 : }
6142 15 : tree type = TREE_TYPE (arg);
6143 15 : gcc_assert (BITINT_TYPE_P (type));
6144 15 : bitint_prec_kind kind = bitint_precision_kind (type);
6145 15 : gcc_assert (kind >= bitint_prec_large);
6146 15 : if (!obj)
6147 : {
6148 2 : int part = var_to_partition (m_map, lhs);
6149 2 : gcc_assert (m_vars[part] != NULL_TREE);
6150 : obj = m_vars[part];
6151 : }
6152 15 : enum internal_fn ifn = gimple_call_internal_fn (stmt);
6153 15 : enum built_in_function bcode = END_BUILTINS;
6154 15 : switch (limb_prec)
6155 : {
6156 0 : case 16:
6157 0 : bcode = ifn == IFN_BSWAP ? BUILT_IN_BSWAP16 : BUILT_IN_BITREVERSE16;
6158 : break;
6159 0 : case 32:
6160 0 : bcode = ifn == IFN_BSWAP ? BUILT_IN_BSWAP32 : BUILT_IN_BITREVERSE32;
6161 : break;
6162 15 : case 64:
6163 15 : bcode = ifn == IFN_BSWAP ? BUILT_IN_BSWAP64 : BUILT_IN_BITREVERSE64;
6164 : break;
6165 0 : case 128:
6166 0 : bcode = ifn == IFN_BSWAP ? BUILT_IN_BSWAP128 : BUILT_IN_BITREVERSE128;
6167 : break;
6168 0 : default:
6169 0 : gcc_unreachable ();
6170 : }
6171 15 : tree fndecl = builtin_decl_explicit (bcode);
6172 15 : unsigned prec = TYPE_PRECISION (type);
6173 30 : tree p = build_int_cst (sizetype,
6174 15 : prec / limb_prec - (prec % limb_prec == 0));
6175 : /* For IFN .BSWAP or .BITREVERSE and
6176 : FN corresponding __builtin_bswapN or __builtin_bitreverseN where N
6177 : is limb_prec, lower
6178 : dst = IFN (src);
6179 : as
6180 : size_t p = prec / limb_prec - (prec % limb_prec == 0);
6181 : if constexpr ((prec % limb_prec) == 0)
6182 : {
6183 : for (idx = 0; idx <= p; ++idx)
6184 : dst[p - idx] = FN (src[idx]);
6185 : }
6186 : else
6187 : {
6188 : unsigned n1 = prec % limb_prec;
6189 : unsigned n2 = limb_prec - n1;
6190 : dst[p] = FN (src[0]) >> n2;
6191 : for (idx = p - 1; (ssize_t) idx >= 0; --idx)
6192 : dst[idx] = FN ((src[p - idx] << n2) | (src[p - idx - 1] >> n1));
6193 : } */
6194 15 : if (prec % limb_prec == 0)
6195 : {
6196 3 : tree idx_next;
6197 3 : tree idx = create_loop (size_zero_node, &idx_next);
6198 3 : tree pmidx = make_ssa_name (sizetype);
6199 3 : g = gimple_build_assign (pmidx, MINUS_EXPR, p, idx);
6200 3 : insert_before (g);
6201 3 : m_data_cnt = 0;
6202 3 : tree t = handle_operand (arg, idx);
6203 3 : m_first = false;
6204 3 : g = gimple_build_call (fndecl, 1, t);
6205 3 : t = make_ssa_name (m_limb_type);
6206 3 : gimple_call_set_lhs (g, t);
6207 3 : insert_before (g);
6208 3 : tree l = limb_access (TREE_TYPE (lhs), obj, pmidx, true);
6209 3 : g = gimple_build_assign (l, t);
6210 3 : insert_before (g);
6211 3 : g = gimple_build_assign (idx_next, PLUS_EXPR, idx, size_one_node);
6212 3 : insert_before (g);
6213 3 : g = gimple_build_cond (LE_EXPR, idx_next, p, NULL_TREE, NULL_TREE);
6214 3 : insert_before (g);
6215 : }
6216 : else
6217 : {
6218 12 : tree n1 = build_int_cst (unsigned_type_node, prec % limb_prec);
6219 24 : tree n2 = build_int_cst (unsigned_type_node,
6220 12 : limb_prec - (prec % limb_prec));
6221 12 : m_data_cnt = 0;
6222 12 : tree t = handle_operand (arg, bitint_big_endian ? p : size_zero_node);
6223 12 : m_first = false;
6224 : /* Nothing is needed to bswap 8 bits or bitreverse 1 bit, so just
6225 : mask off higher bits in that case. */
6226 19 : if ((prec % limb_prec) != (ifn == IFN_BSWAP ? 8 : 1))
6227 : {
6228 8 : g = gimple_build_call (fndecl, 1, t);
6229 8 : t = make_ssa_name (m_limb_type);
6230 8 : gimple_call_set_lhs (g, t);
6231 8 : insert_before (g);
6232 8 : g = gimple_build_assign (make_ssa_name (m_limb_type), RSHIFT_EXPR,
6233 : t, n2);
6234 : }
6235 : else
6236 4 : g = gimple_build_assign (make_ssa_name (m_limb_type), BIT_AND_EXPR,
6237 : t, build_int_cst (m_limb_type,
6238 : ifn == IFN_BSWAP
6239 6 : ? 0xff : 1));
6240 12 : insert_before (g);
6241 12 : t = gimple_assign_lhs (g);
6242 12 : tree l = limb_access (TREE_TYPE (lhs), obj,
6243 : bitint_big_endian ? size_zero_node : p, true);
6244 12 : g = gimple_build_assign (l, t);
6245 12 : insert_before (g);
6246 12 : tree pm1 = build_int_cst (sizetype, prec / limb_prec - 1);
6247 12 : tree idx_next;
6248 12 : tree idx = create_loop (pm1, &idx_next);
6249 12 : tree pmidx = make_ssa_name (sizetype);
6250 12 : g = gimple_build_assign (pmidx, MINUS_EXPR, p, idx);
6251 12 : insert_before (g);
6252 12 : m_data_cnt = 0;
6253 24 : t = handle_operand (arg, bitint_big_endian ? idx : pmidx);
6254 12 : m_data_cnt = 0;
6255 12 : g = gimple_build_assign (make_ssa_name (m_limb_type), LSHIFT_EXPR,
6256 : t, n2);
6257 12 : insert_before (g);
6258 12 : t = gimple_assign_lhs (g);
6259 12 : tree t2 = make_ssa_name (sizetype);
6260 12 : if (bitint_big_endian)
6261 0 : g = gimple_build_assign (t2, PLUS_EXPR, idx, size_one_node);
6262 : else
6263 12 : g = gimple_build_assign (t2, PLUS_EXPR, pmidx, size_int (-1));
6264 12 : insert_before (g);
6265 12 : t2 = handle_operand (arg, t2);
6266 12 : g = gimple_build_assign (make_ssa_name (m_limb_type), RSHIFT_EXPR,
6267 : t2, n1);
6268 12 : insert_before (g);
6269 12 : t2 = gimple_assign_lhs (g);
6270 12 : g = gimple_build_assign (make_ssa_name (m_limb_type), BIT_IOR_EXPR,
6271 : t, t2);
6272 12 : insert_before (g);
6273 12 : t = gimple_assign_lhs (g);
6274 12 : g = gimple_build_call (fndecl, 1, t);
6275 12 : t = make_ssa_name (m_limb_type);
6276 12 : gimple_call_set_lhs (g, t);
6277 12 : insert_before (g);
6278 24 : l = limb_access (TREE_TYPE (lhs), obj,
6279 : bitint_big_endian ? pmidx : idx, true);
6280 12 : g = gimple_build_assign (l, t);
6281 12 : insert_before (g);
6282 12 : g = gimple_build_assign (idx_next, PLUS_EXPR, idx, size_int (-1));
6283 12 : insert_before (g);
6284 12 : g = gimple_build_cond (NE_EXPR, idx, size_zero_node, NULL_TREE,
6285 : NULL_TREE);
6286 12 : insert_before (g);
6287 : }
6288 15 : gimple_stmt_iterator gsi = gsi_for_stmt (stmt);
6289 15 : if (bitint_extended == bitint_ext_full
6290 0 : && abi_limb_prec > limb_prec
6291 0 : && (CEIL (prec, abi_limb_prec) * abi_limb_prec
6292 0 : > CEIL (prec, limb_prec) * limb_prec))
6293 : {
6294 0 : m_gsi = gsi;
6295 0 : tree p2 = build_int_cst (sizetype,
6296 : CEIL (prec, abi_limb_prec)
6297 0 : * abi_limb_prec / limb_prec - 1);
6298 0 : tree l = limb_access (TREE_TYPE (lhs), obj, p2, true);
6299 0 : g = gimple_build_assign (l, build_zero_cst (m_limb_type));
6300 0 : insert_before (g);
6301 : }
6302 : }
6303 :
6304 : /* Lower a call statement with one or more large/huge _BitInt
6305 : arguments or large/huge _BitInt return value. */
6306 :
6307 : void
6308 8857 : bitint_large_huge::lower_call (tree obj, gimple *stmt)
6309 : {
6310 8857 : gimple_stmt_iterator gsi = gsi_for_stmt (stmt);
6311 8857 : unsigned int nargs = gimple_call_num_args (stmt);
6312 8857 : if (gimple_call_internal_p (stmt))
6313 4328 : switch (gimple_call_internal_fn (stmt))
6314 : {
6315 2733 : case IFN_ADD_OVERFLOW:
6316 2733 : case IFN_SUB_OVERFLOW:
6317 2733 : case IFN_UBSAN_CHECK_ADD:
6318 2733 : case IFN_UBSAN_CHECK_SUB:
6319 2733 : lower_addsub_overflow (obj, stmt);
6320 7061 : return;
6321 1479 : case IFN_MUL_OVERFLOW:
6322 1479 : case IFN_UBSAN_CHECK_MUL:
6323 1479 : lower_mul_overflow (obj, stmt);
6324 1479 : return;
6325 101 : case IFN_CLZ:
6326 101 : case IFN_CTZ:
6327 101 : case IFN_CLRSB:
6328 101 : case IFN_FFS:
6329 101 : case IFN_PARITY:
6330 101 : case IFN_POPCOUNT:
6331 101 : lower_bit_query (stmt);
6332 101 : return;
6333 15 : case IFN_BSWAP:
6334 15 : case IFN_BITREVERSE:
6335 15 : lower_bswap_bitreverse (obj, stmt);
6336 15 : return;
6337 : default:
6338 : break;
6339 : }
6340 4529 : bool returns_twice = (gimple_call_flags (stmt) & ECF_RETURNS_TWICE) != 0;
6341 10202 : for (unsigned int i = 0; i < nargs; ++i)
6342 : {
6343 5673 : tree arg = gimple_call_arg (stmt, i);
6344 9003 : if (TREE_CODE (arg) != SSA_NAME
6345 2440 : || !BITINT_TYPE_P (TREE_TYPE (arg))
6346 8051 : || bitint_precision_kind (TREE_TYPE (arg)) <= bitint_prec_middle)
6347 3330 : continue;
6348 2343 : if (SSA_NAME_IS_DEFAULT_DEF (arg)
6349 2343 : && (!SSA_NAME_VAR (arg) || VAR_P (SSA_NAME_VAR (arg))))
6350 : {
6351 1 : tree var = create_tmp_reg (TREE_TYPE (arg));
6352 1 : arg = get_or_create_ssa_default_def (cfun, var);
6353 : }
6354 : else
6355 : {
6356 2342 : int p = var_to_partition (m_map, arg);
6357 2342 : tree v = m_vars[p];
6358 2342 : gcc_assert (v != NULL_TREE);
6359 2342 : if (!types_compatible_p (TREE_TYPE (arg), TREE_TYPE (v)))
6360 2322 : v = build1 (VIEW_CONVERT_EXPR, TREE_TYPE (arg), v);
6361 2342 : arg = make_ssa_name (TREE_TYPE (arg));
6362 2342 : gimple *g = gimple_build_assign (arg, v);
6363 2342 : gsi_insert_before (&gsi, g, GSI_SAME_STMT);
6364 2342 : if (returns_twice && bb_has_abnormal_pred (gimple_bb (stmt)))
6365 : {
6366 11 : m_returns_twice_calls.safe_push (stmt);
6367 11 : returns_twice = false;
6368 : }
6369 : }
6370 2343 : gimple_call_set_arg (stmt, i, arg);
6371 2343 : if (m_preserved == NULL)
6372 412 : m_preserved = BITMAP_ALLOC (NULL);
6373 2343 : bitmap_set_bit (m_preserved, SSA_NAME_VERSION (arg));
6374 : }
6375 4529 : tree lhs = gimple_call_lhs (stmt);
6376 4529 : if (lhs
6377 4398 : && TREE_CODE (lhs) == SSA_NAME
6378 4398 : && BITINT_TYPE_P (TREE_TYPE (lhs))
6379 8849 : && bitint_precision_kind (TREE_TYPE (lhs)) >= bitint_prec_large)
6380 : {
6381 4294 : int p = var_to_partition (m_map, lhs);
6382 4294 : tree v = m_vars[p];
6383 4294 : gcc_assert (v != NULL_TREE);
6384 4294 : if (!types_compatible_p (TREE_TYPE (lhs), TREE_TYPE (v)))
6385 4294 : v = build1 (VIEW_CONVERT_EXPR, TREE_TYPE (lhs), v);
6386 4294 : gimple_call_set_lhs (stmt, v);
6387 4294 : SSA_NAME_DEF_STMT (lhs) = gimple_build_nop ();
6388 : }
6389 4529 : update_stmt (stmt);
6390 : }
6391 :
6392 : /* Lower __asm STMT which involves large/huge _BitInt values. */
6393 :
6394 : void
6395 3 : bitint_large_huge::lower_asm (gimple *stmt)
6396 : {
6397 3 : gasm *g = as_a <gasm *> (stmt);
6398 3 : unsigned noutputs = gimple_asm_noutputs (g);
6399 3 : unsigned ninputs = gimple_asm_ninputs (g);
6400 :
6401 5 : for (unsigned i = 0; i < noutputs; ++i)
6402 : {
6403 2 : tree t = gimple_asm_output_op (g, i);
6404 2 : tree s = TREE_VALUE (t);
6405 2 : if (TREE_CODE (s) == SSA_NAME
6406 1 : && BITINT_TYPE_P (TREE_TYPE (s))
6407 3 : && bitint_precision_kind (TREE_TYPE (s)) >= bitint_prec_large)
6408 : {
6409 1 : int part = var_to_partition (m_map, s);
6410 1 : gcc_assert (m_vars[part] != NULL_TREE);
6411 1 : TREE_VALUE (t) = m_vars[part];
6412 : }
6413 : }
6414 8 : for (unsigned i = 0; i < ninputs; ++i)
6415 : {
6416 5 : tree t = gimple_asm_input_op (g, i);
6417 5 : tree s = TREE_VALUE (t);
6418 5 : if (TREE_CODE (s) == SSA_NAME
6419 4 : && BITINT_TYPE_P (TREE_TYPE (s))
6420 9 : && bitint_precision_kind (TREE_TYPE (s)) >= bitint_prec_large)
6421 : {
6422 4 : if (SSA_NAME_IS_DEFAULT_DEF (s)
6423 4 : && (!SSA_NAME_VAR (s) || VAR_P (SSA_NAME_VAR (s))))
6424 : {
6425 1 : TREE_VALUE (t) = create_tmp_var (TREE_TYPE (s), "bitint");
6426 1 : mark_addressable (TREE_VALUE (t));
6427 : }
6428 : else
6429 : {
6430 3 : int part = var_to_partition (m_map, s);
6431 3 : gcc_assert (m_vars[part] != NULL_TREE);
6432 3 : TREE_VALUE (t) = m_vars[part];
6433 : }
6434 : }
6435 : }
6436 3 : update_stmt (stmt);
6437 3 : }
6438 :
6439 : /* Lower statement STMT which involves large/huge _BitInt values
6440 : into code accessing individual limbs. */
6441 :
6442 : void
6443 42903 : bitint_large_huge::lower_stmt (gimple *stmt)
6444 : {
6445 42903 : m_first = true;
6446 42903 : m_lhs = NULL_TREE;
6447 42903 : m_data.truncate (0);
6448 42903 : m_data_cnt = 0;
6449 42903 : m_gsi = gsi_for_stmt (stmt);
6450 42903 : m_after_stmt = NULL;
6451 42903 : m_bb = NULL;
6452 42903 : m_init_gsi = m_gsi;
6453 42903 : gsi_prev (&m_init_gsi);
6454 42903 : m_preheader_bb = NULL;
6455 42903 : m_upwards_2limb = 0;
6456 42903 : m_upwards = false;
6457 42903 : m_var_msb = false;
6458 42903 : m_cast_conditional = false;
6459 42903 : m_bitfld_load = 0;
6460 42903 : m_loc = gimple_location (stmt);
6461 42903 : if (is_gimple_call (stmt))
6462 : {
6463 7180 : lower_call (NULL_TREE, stmt);
6464 7180 : return;
6465 : }
6466 35723 : if (gimple_code (stmt) == GIMPLE_ASM)
6467 : {
6468 3 : lower_asm (stmt);
6469 3 : return;
6470 : }
6471 35720 : tree lhs = NULL_TREE, cmp_op1 = NULL_TREE, cmp_op2 = NULL_TREE;
6472 35720 : tree_code cmp_code = comparison_op (stmt, &cmp_op1, &cmp_op2);
6473 35720 : bool eq_p = (cmp_code == EQ_EXPR || cmp_code == NE_EXPR);
6474 35720 : bool mergeable_cast_p = false;
6475 35720 : bool final_cast_p = false;
6476 35720 : if (gimple_assign_cast_p (stmt))
6477 : {
6478 5449 : lhs = gimple_assign_lhs (stmt);
6479 5449 : tree rhs1 = gimple_assign_rhs1 (stmt);
6480 5449 : if (TREE_CODE (rhs1) == VIEW_CONVERT_EXPR)
6481 46 : rhs1 = TREE_OPERAND (rhs1, 0);
6482 9670 : if (BITINT_TYPE_P (TREE_TYPE (lhs))
6483 1228 : && bitint_precision_kind (TREE_TYPE (lhs)) >= bitint_prec_large
6484 6641 : && INTEGRAL_TYPE_P (TREE_TYPE (rhs1)))
6485 : mergeable_cast_p = true;
6486 4547 : else if (BITINT_TYPE_P (TREE_TYPE (rhs1))
6487 4257 : && bitint_precision_kind (TREE_TYPE (rhs1)) >= bitint_prec_large
6488 8659 : && (INTEGRAL_TYPE_P (TREE_TYPE (lhs))
6489 36 : || POINTER_TYPE_P (TREE_TYPE (lhs))
6490 35 : || gimple_assign_rhs_code (stmt) == VIEW_CONVERT_EXPR))
6491 : {
6492 4257 : final_cast_p = true;
6493 4257 : if (((TREE_CODE (TREE_TYPE (lhs)) == INTEGER_TYPE
6494 572 : && TYPE_PRECISION (TREE_TYPE (lhs)) > MAX_FIXED_MODE_SIZE)
6495 4257 : || (!INTEGRAL_TYPE_P (TREE_TYPE (lhs))
6496 36 : && !POINTER_TYPE_P (TREE_TYPE (lhs))))
6497 4292 : && gimple_assign_rhs_code (stmt) == VIEW_CONVERT_EXPR)
6498 : {
6499 : /* Handle VIEW_CONVERT_EXPRs to not generally supported
6500 : huge INTEGER_TYPEs like uint256_t or uint512_t. These
6501 : are usually emitted from memcpy folding and backends
6502 : support moves with them but that is usually it.
6503 : Similarly handle VCEs to vector/complex types etc. */
6504 35 : gcc_assert (TREE_CODE (rhs1) == SSA_NAME);
6505 35 : if (SSA_NAME_IS_DEFAULT_DEF (rhs1)
6506 35 : && (!SSA_NAME_VAR (rhs1) || VAR_P (SSA_NAME_VAR (rhs1))))
6507 : {
6508 0 : tree var = create_tmp_reg (TREE_TYPE (lhs));
6509 0 : rhs1 = get_or_create_ssa_default_def (cfun, var);
6510 0 : gimple_assign_set_rhs1 (stmt, rhs1);
6511 0 : gimple_assign_set_rhs_code (stmt, SSA_NAME);
6512 : }
6513 35 : else if (m_names == NULL
6514 35 : || !bitmap_bit_p (m_names, SSA_NAME_VERSION (rhs1)))
6515 : {
6516 0 : gimple *g = SSA_NAME_DEF_STMT (rhs1);
6517 0 : gcc_assert (gimple_assign_load_p (g));
6518 0 : tree mem = gimple_assign_rhs1 (g);
6519 0 : tree ltype = TREE_TYPE (lhs);
6520 0 : addr_space_t as = TYPE_ADDR_SPACE (TREE_TYPE (mem));
6521 0 : if (as != TYPE_ADDR_SPACE (ltype))
6522 0 : ltype
6523 0 : = build_qualified_type (ltype,
6524 0 : TYPE_QUALS (ltype)
6525 0 : | ENCODE_QUAL_ADDR_SPACE (as));
6526 0 : rhs1 = build1 (VIEW_CONVERT_EXPR, ltype, unshare_expr (mem));
6527 0 : gimple_assign_set_rhs1 (stmt, rhs1);
6528 : }
6529 : else
6530 : {
6531 35 : int part = var_to_partition (m_map, rhs1);
6532 35 : gcc_assert (m_vars[part] != NULL_TREE);
6533 35 : rhs1 = build1 (VIEW_CONVERT_EXPR, TREE_TYPE (lhs),
6534 : m_vars[part]);
6535 35 : gimple_assign_set_rhs1 (stmt, rhs1);
6536 : }
6537 35 : update_stmt (stmt);
6538 35 : return;
6539 : }
6540 4222 : if (TREE_CODE (rhs1) == SSA_NAME
6541 4222 : && (m_names == NULL
6542 4185 : || !bitmap_bit_p (m_names, SSA_NAME_VERSION (rhs1))))
6543 : {
6544 1723 : gimple *g = SSA_NAME_DEF_STMT (rhs1);
6545 1723 : if (is_gimple_assign (g)
6546 1723 : && gimple_assign_rhs_code (g) == IMAGPART_EXPR)
6547 : {
6548 1640 : tree rhs2 = TREE_OPERAND (gimple_assign_rhs1 (g), 0);
6549 1640 : if (TREE_CODE (rhs2) == SSA_NAME
6550 1640 : && (m_names == NULL
6551 1603 : || !bitmap_bit_p (m_names, SSA_NAME_VERSION (rhs2))))
6552 : {
6553 1640 : g = SSA_NAME_DEF_STMT (rhs2);
6554 1640 : int ovf = optimizable_arith_overflow (g);
6555 1640 : if (ovf == 2)
6556 : /* If .{ADD,SUB,MUL}_OVERFLOW has both REALPART_EXPR
6557 : and IMAGPART_EXPR uses, where the latter is cast to
6558 : non-_BitInt, it will be optimized when handling
6559 : the REALPART_EXPR. */
6560 : return;
6561 91 : if (ovf == 1)
6562 : {
6563 91 : lower_call (NULL_TREE, g);
6564 91 : return;
6565 : }
6566 : }
6567 : }
6568 : }
6569 : }
6570 145 : else if (BITINT_TYPE_P (TREE_TYPE (lhs))
6571 145 : && bitint_precision_kind (TREE_TYPE (lhs)) >= bitint_prec_large
6572 145 : && !INTEGRAL_TYPE_P (TREE_TYPE (rhs1))
6573 145 : && !POINTER_TYPE_P (TREE_TYPE (rhs1))
6574 290 : && gimple_assign_rhs_code (stmt) == VIEW_CONVERT_EXPR)
6575 : {
6576 10 : int part = var_to_partition (m_map, lhs);
6577 10 : gcc_assert (m_vars[part] != NULL_TREE);
6578 10 : lhs = build1 (VIEW_CONVERT_EXPR, TREE_TYPE (rhs1), m_vars[part]);
6579 10 : insert_before (gimple_build_assign (lhs, rhs1));
6580 10 : return;
6581 : }
6582 : }
6583 34035 : if (gimple_store_p (stmt))
6584 : {
6585 9009 : tree rhs1 = gimple_assign_rhs1 (stmt);
6586 9009 : if (TREE_CODE (rhs1) == SSA_NAME
6587 9009 : && (m_names == NULL
6588 7949 : || !bitmap_bit_p (m_names, SSA_NAME_VERSION (rhs1))))
6589 : {
6590 1641 : gimple *g = SSA_NAME_DEF_STMT (rhs1);
6591 1641 : m_loc = gimple_location (g);
6592 1641 : lhs = gimple_assign_lhs (stmt);
6593 1641 : if (is_gimple_assign (g) && !mergeable_op (g))
6594 645 : switch (gimple_assign_rhs_code (g))
6595 : {
6596 119 : case LSHIFT_EXPR:
6597 119 : case RSHIFT_EXPR:
6598 119 : lower_shift_stmt (lhs, g);
6599 478 : handled:
6600 478 : m_gsi = gsi_for_stmt (stmt);
6601 478 : unlink_stmt_vdef (stmt);
6602 956 : release_ssa_name (gimple_vdef (stmt));
6603 478 : gsi_remove (&m_gsi, true);
6604 478 : return;
6605 205 : case MULT_EXPR:
6606 205 : case TRUNC_DIV_EXPR:
6607 205 : case EXACT_DIV_EXPR:
6608 205 : case TRUNC_MOD_EXPR:
6609 205 : lower_muldiv_stmt (lhs, g);
6610 205 : goto handled;
6611 44 : case FIX_TRUNC_EXPR:
6612 44 : lower_float_conv_stmt (lhs, g);
6613 44 : goto handled;
6614 73 : case REALPART_EXPR:
6615 73 : case IMAGPART_EXPR:
6616 73 : lower_cplxpart_stmt (lhs, g);
6617 73 : goto handled;
6618 8 : case VIEW_CONVERT_EXPR:
6619 8 : {
6620 8 : tree rhs1 = gimple_assign_rhs1 (g);
6621 8 : rhs1 = TREE_OPERAND (rhs1, 0);
6622 8 : if (!INTEGRAL_TYPE_P (TREE_TYPE (rhs1))
6623 7 : && !POINTER_TYPE_P (TREE_TYPE (rhs1)))
6624 : {
6625 7 : tree ltype = TREE_TYPE (rhs1);
6626 7 : addr_space_t as = TYPE_ADDR_SPACE (TREE_TYPE (lhs));
6627 7 : ltype
6628 14 : = build_qualified_type (ltype,
6629 7 : TYPE_QUALS (TREE_TYPE (lhs))
6630 7 : | ENCODE_QUAL_ADDR_SPACE (as));
6631 7 : lhs = build1 (VIEW_CONVERT_EXPR, ltype, lhs);
6632 7 : gimple_assign_set_lhs (stmt, lhs);
6633 7 : gimple_assign_set_rhs1 (stmt, rhs1);
6634 7 : gimple_assign_set_rhs_code (stmt, TREE_CODE (rhs1));
6635 7 : update_stmt (stmt);
6636 7 : return;
6637 : }
6638 : }
6639 : break;
6640 : default:
6641 : break;
6642 : }
6643 996 : else if (optimizable_arith_overflow (g) == 3)
6644 : {
6645 24 : lower_call (lhs, g);
6646 24 : goto handled;
6647 : }
6648 972 : else if (is_gimple_call (g) && gimple_call_internal_p (g))
6649 13 : switch (gimple_call_internal_fn (g))
6650 : {
6651 13 : case IFN_BSWAP:
6652 13 : case IFN_BITREVERSE:
6653 13 : lower_call (lhs, g);
6654 13 : goto handled;
6655 : default:
6656 : break;
6657 : }
6658 :
6659 1156 : m_loc = gimple_location (stmt);
6660 : }
6661 : }
6662 33550 : if (mergeable_op (stmt)
6663 22114 : || gimple_store_p (stmt)
6664 22114 : || gimple_assign_load_p (stmt)
6665 : || eq_p
6666 17300 : || mergeable_cast_p
6667 43717 : || (is_gimple_assign (stmt)
6668 9779 : && gimple_assign_rhs_code (stmt) == PAREN_EXPR))
6669 : {
6670 23385 : lhs = lower_mergeable_stmt (stmt, cmp_code, cmp_op1, cmp_op2);
6671 23385 : if (!eq_p)
6672 : return;
6673 : }
6674 10165 : else if (cmp_code != ERROR_MARK)
6675 722 : lhs = lower_comparison_stmt (stmt, cmp_code, cmp_op1, cmp_op2);
6676 16717 : if (cmp_code != ERROR_MARK)
6677 : {
6678 7274 : if (gimple_code (stmt) == GIMPLE_COND)
6679 : {
6680 6500 : gcond *cstmt = as_a <gcond *> (stmt);
6681 6500 : gimple_cond_set_lhs (cstmt, lhs);
6682 6500 : gimple_cond_set_rhs (cstmt, boolean_false_node);
6683 6500 : gimple_cond_set_code (cstmt, cmp_code);
6684 6500 : update_stmt (stmt);
6685 6500 : return;
6686 : }
6687 774 : if (gimple_assign_rhs_code (stmt) == COND_EXPR)
6688 : {
6689 0 : tree cond = build2 (cmp_code, boolean_type_node, lhs,
6690 : boolean_false_node);
6691 0 : gimple_assign_set_rhs1 (stmt, cond);
6692 0 : lhs = gimple_assign_lhs (stmt);
6693 0 : gcc_assert (!BITINT_TYPE_P (TREE_TYPE (lhs))
6694 : || (bitint_precision_kind (TREE_TYPE (lhs))
6695 : <= bitint_prec_middle));
6696 0 : update_stmt (stmt);
6697 0 : return;
6698 : }
6699 774 : gimple_assign_set_rhs1 (stmt, lhs);
6700 774 : gimple_assign_set_rhs2 (stmt, boolean_false_node);
6701 774 : gimple_assign_set_rhs_code (stmt, cmp_code);
6702 774 : update_stmt (stmt);
6703 774 : return;
6704 : }
6705 9443 : if (final_cast_p)
6706 : {
6707 2582 : tree lhs_type = TREE_TYPE (lhs);
6708 : /* Add support for 3 or more limbs filled in from normal integral
6709 : type if this assert fails. If no target chooses limb mode smaller
6710 : than half of largest supported normal integral type, this will not
6711 : be needed. */
6712 2582 : gcc_assert (TYPE_PRECISION (lhs_type) <= 2 * limb_prec);
6713 2582 : gimple *g;
6714 2546 : if ((BITINT_TYPE_P (lhs_type)
6715 36 : && bitint_precision_kind (lhs_type) == bitint_prec_middle)
6716 5149 : || POINTER_TYPE_P (lhs_type))
6717 16 : lhs_type = build_nonstandard_integer_type (TYPE_PRECISION (lhs_type),
6718 16 : TYPE_UNSIGNED (lhs_type));
6719 2582 : m_data_cnt = 0;
6720 2582 : tree rhs1 = gimple_assign_rhs1 (stmt);
6721 2582 : unsigned int prec = TYPE_PRECISION (TREE_TYPE (rhs1));
6722 2582 : unsigned int cnt = CEIL (prec, limb_prec);
6723 2582 : tree r1 = handle_operand (rhs1, size_int (bitint_big_endian
6724 : ? cnt - 1 : 0));
6725 2582 : if (!useless_type_conversion_p (lhs_type, TREE_TYPE (r1)))
6726 2473 : r1 = add_cast (lhs_type, r1);
6727 2582 : if (TYPE_PRECISION (lhs_type) > limb_prec)
6728 : {
6729 70 : m_data_cnt = 0;
6730 70 : m_first = false;
6731 70 : tree r2 = handle_operand (rhs1, size_int (bitint_big_endian
6732 : ? cnt - 2 : 1));
6733 70 : r2 = add_cast (lhs_type, r2);
6734 70 : g = gimple_build_assign (make_ssa_name (lhs_type), LSHIFT_EXPR, r2,
6735 : build_int_cst (unsigned_type_node,
6736 70 : limb_prec));
6737 70 : insert_before (g);
6738 70 : g = gimple_build_assign (make_ssa_name (lhs_type), BIT_IOR_EXPR, r1,
6739 : gimple_assign_lhs (g));
6740 70 : insert_before (g);
6741 70 : r1 = gimple_assign_lhs (g);
6742 : }
6743 2582 : if (lhs_type != TREE_TYPE (lhs))
6744 16 : g = gimple_build_assign (lhs, NOP_EXPR, r1);
6745 : else
6746 2566 : g = gimple_build_assign (lhs, r1);
6747 2582 : gsi_replace (&m_gsi, g, true);
6748 2582 : return;
6749 : }
6750 6861 : if (is_gimple_assign (stmt))
6751 6861 : switch (gimple_assign_rhs_code (stmt))
6752 : {
6753 465 : case LSHIFT_EXPR:
6754 465 : case RSHIFT_EXPR:
6755 465 : lower_shift_stmt (NULL_TREE, stmt);
6756 465 : return;
6757 166 : case MULT_EXPR:
6758 166 : case TRUNC_DIV_EXPR:
6759 166 : case EXACT_DIV_EXPR:
6760 166 : case TRUNC_MOD_EXPR:
6761 166 : lower_muldiv_stmt (NULL_TREE, stmt);
6762 166 : return;
6763 283 : case FIX_TRUNC_EXPR:
6764 283 : case FLOAT_EXPR:
6765 283 : lower_float_conv_stmt (NULL_TREE, stmt);
6766 283 : return;
6767 5929 : case REALPART_EXPR:
6768 5929 : case IMAGPART_EXPR:
6769 5929 : lower_cplxpart_stmt (NULL_TREE, stmt);
6770 5929 : return;
6771 18 : case COMPLEX_EXPR:
6772 18 : lower_complexexpr_stmt (stmt);
6773 18 : return;
6774 : default:
6775 : break;
6776 : }
6777 0 : gcc_unreachable ();
6778 : }
6779 :
6780 : /* Helper for walk_non_aliased_vuses. Determine if we arrived at
6781 : the desired memory state. */
6782 :
6783 : void *
6784 2190 : vuse_eq (ao_ref *, tree vuse1, void *data)
6785 : {
6786 2190 : tree vuse2 = (tree) data;
6787 2190 : if (vuse1 == vuse2)
6788 820 : return data;
6789 :
6790 : return NULL;
6791 : }
6792 :
6793 : /* Return true if STMT uses a library function and needs to take
6794 : address of its inputs. We need to avoid bit-fields in those
6795 : cases. Similarly, we need to avoid overlap between destination
6796 : and source limb arrays. */
6797 :
6798 : bool
6799 15105 : stmt_needs_operand_addr (gimple *stmt)
6800 : {
6801 15105 : if (is_gimple_assign (stmt))
6802 10298 : switch (gimple_assign_rhs_code (stmt))
6803 : {
6804 585 : case MULT_EXPR:
6805 585 : case TRUNC_DIV_EXPR:
6806 585 : case EXACT_DIV_EXPR:
6807 585 : case TRUNC_MOD_EXPR:
6808 585 : case FLOAT_EXPR:
6809 585 : return true;
6810 : default:
6811 : break;
6812 : }
6813 4807 : else if (is_gimple_call (stmt) && gimple_call_internal_p (stmt))
6814 46 : switch (gimple_call_internal_fn (stmt))
6815 : {
6816 17 : case IFN_MUL_OVERFLOW:
6817 17 : case IFN_UBSAN_CHECK_MUL:
6818 17 : return true;
6819 : /* These two actually don't take address, but reshuffle
6820 : all bytes or bits, so need similar treatment. */
6821 4 : case IFN_BSWAP:
6822 4 : case IFN_BITREVERSE:
6823 4 : return true;
6824 : default:
6825 : break;
6826 : }
6827 : return false;
6828 : }
6829 :
6830 : /* Dominator walker used to discover which large/huge _BitInt
6831 : loads could be sunk into all their uses. */
6832 :
6833 630 : class bitint_dom_walker : public dom_walker
6834 : {
6835 : public:
6836 315 : bitint_dom_walker (bitmap names, bitmap loads)
6837 630 : : dom_walker (CDI_DOMINATORS), m_names (names), m_loads (loads) {}
6838 :
6839 : edge before_dom_children (basic_block) final override;
6840 :
6841 : private:
6842 : bitmap m_names, m_loads;
6843 : };
6844 :
6845 : edge
6846 4518 : bitint_dom_walker::before_dom_children (basic_block bb)
6847 : {
6848 4518 : gphi *phi = get_virtual_phi (bb);
6849 4518 : tree vop;
6850 4518 : if (phi)
6851 794 : vop = gimple_phi_result (phi);
6852 3724 : else if (bb == ENTRY_BLOCK_PTR_FOR_FN (cfun))
6853 : vop = NULL_TREE;
6854 : else
6855 3409 : vop = (tree) get_immediate_dominator (CDI_DOMINATORS, bb)->aux;
6856 :
6857 4518 : auto_vec<tree, 16> worklist;
6858 9036 : for (gimple_stmt_iterator gsi = gsi_start_bb (bb);
6859 20012 : !gsi_end_p (gsi); gsi_next (&gsi))
6860 : {
6861 15494 : gimple *stmt = gsi_stmt (gsi);
6862 15494 : if (is_gimple_debug (stmt))
6863 2769 : continue;
6864 :
6865 15542 : if (!vop && gimple_vuse (stmt))
6866 : vop = gimple_vuse (stmt);
6867 :
6868 15105 : tree cvop = vop;
6869 28350 : if (gimple_vdef (stmt))
6870 : vop = gimple_vdef (stmt);
6871 :
6872 15105 : tree lhs = gimple_get_lhs (stmt);
6873 17485 : if (lhs
6874 10971 : && TREE_CODE (lhs) == SSA_NAME
6875 8748 : && BITINT_TYPE_P (TREE_TYPE (lhs))
6876 5871 : && bitint_precision_kind (TREE_TYPE (lhs)) >= bitint_prec_large
6877 20828 : && !bitmap_bit_p (m_names, SSA_NAME_VERSION (lhs)))
6878 : /* If lhs of stmt is large/huge _BitInt SSA_NAME not in m_names,
6879 : it means it will be handled in a loop or straight line code
6880 : at the location of its (ultimate) immediate use, so for
6881 : vop checking purposes check these only at the ultimate
6882 : immediate use. */
6883 2380 : continue;
6884 :
6885 12725 : ssa_op_iter oi;
6886 12725 : use_operand_p use_p;
6887 21573 : FOR_EACH_SSA_USE_OPERAND (use_p, stmt, oi, SSA_OP_USE)
6888 : {
6889 8848 : tree s = USE_FROM_PTR (use_p);
6890 14272 : if (BITINT_TYPE_P (TREE_TYPE (s))
6891 8848 : && bitint_precision_kind (TREE_TYPE (s)) >= bitint_prec_large)
6892 3269 : worklist.safe_push (s);
6893 : }
6894 :
6895 12725 : bool needs_operand_addr = stmt_needs_operand_addr (stmt);
6896 31559 : while (worklist.length () > 0)
6897 : {
6898 6109 : tree s = worklist.pop ();
6899 :
6900 6109 : if (!bitmap_bit_p (m_names, SSA_NAME_VERSION (s)))
6901 : {
6902 2380 : gimple *g = SSA_NAME_DEF_STMT (s);
6903 2380 : needs_operand_addr |= stmt_needs_operand_addr (g);
6904 5459 : FOR_EACH_SSA_USE_OPERAND (use_p, g, oi, SSA_OP_USE)
6905 : {
6906 3079 : tree s2 = USE_FROM_PTR (use_p);
6907 3269 : if (BITINT_TYPE_P (TREE_TYPE (s2))
6908 3079 : && (bitint_precision_kind (TREE_TYPE (s2))
6909 : >= bitint_prec_large))
6910 2840 : worklist.safe_push (s2);
6911 : }
6912 3100 : continue;
6913 2380 : }
6914 3729 : if (!SSA_NAME_OCCURS_IN_ABNORMAL_PHI (s)
6915 3729 : && gimple_assign_cast_p (SSA_NAME_DEF_STMT (s)))
6916 : {
6917 226 : tree rhs = gimple_assign_rhs1 (SSA_NAME_DEF_STMT (s));
6918 396 : if (TREE_CODE (rhs) == SSA_NAME
6919 226 : && bitmap_bit_p (m_loads, SSA_NAME_VERSION (rhs)))
6920 : s = rhs;
6921 : else
6922 170 : continue;
6923 : }
6924 3503 : else if (!bitmap_bit_p (m_loads, SSA_NAME_VERSION (s)))
6925 548 : continue;
6926 :
6927 3011 : gimple *g = SSA_NAME_DEF_STMT (s);
6928 3011 : tree rhs1 = gimple_assign_rhs1 (g);
6929 3011 : if (needs_operand_addr
6930 218 : && TREE_CODE (rhs1) == COMPONENT_REF
6931 3028 : && DECL_BIT_FIELD_TYPE (TREE_OPERAND (rhs1, 1)))
6932 : {
6933 4 : tree fld = TREE_OPERAND (rhs1, 1);
6934 : /* For little-endian, we can allow as inputs bit-fields
6935 : which start at a limb boundary. */
6936 6 : if (!bitint_big_endian
6937 4 : && DECL_OFFSET_ALIGN (fld) >= TYPE_ALIGN (TREE_TYPE (rhs1))
6938 4 : && tree_fits_uhwi_p (DECL_FIELD_BIT_OFFSET (fld))
6939 4 : && (tree_to_uhwi (DECL_FIELD_BIT_OFFSET (fld))
6940 4 : % limb_prec) == 0)
6941 : ;
6942 : else
6943 : {
6944 2 : bitmap_clear_bit (m_loads, SSA_NAME_VERSION (s));
6945 2 : continue;
6946 : }
6947 : }
6948 :
6949 3009 : ao_ref ref;
6950 3009 : ao_ref_init (&ref, rhs1);
6951 3009 : tree lvop = gimple_vuse (g);
6952 3009 : unsigned limit = 64;
6953 3009 : tree vuse = cvop;
6954 3009 : if (vop != cvop
6955 1338 : && is_gimple_assign (stmt)
6956 1336 : && gimple_store_p (stmt)
6957 4345 : && (needs_operand_addr
6958 1143 : || !operand_equal_p (lhs, gimple_assign_rhs1 (g), 0)))
6959 : vuse = vop;
6960 3009 : if (vuse != lvop
6961 3009 : && walk_non_aliased_vuses (&ref, vuse, false, vuse_eq,
6962 : NULL, NULL, NULL, limit, lvop) == NULL)
6963 532 : bitmap_clear_bit (m_loads, SSA_NAME_VERSION (s));
6964 : }
6965 : }
6966 :
6967 4518 : bb->aux = (void *) vop;
6968 4518 : return NULL;
6969 4518 : }
6970 :
6971 : }
6972 :
6973 : /* Replacement for normal processing of STMT in tree-ssa-coalesce.cc
6974 : build_ssa_conflict_graph.
6975 : The differences are:
6976 : 1) don't process assignments with large/huge _BitInt lhs not in NAMES
6977 : 2) for large/huge _BitInt multiplication/division/modulo process def
6978 : only after processing uses rather than before to make uses conflict
6979 : with the definition
6980 : 3) for large/huge _BitInt uses not in NAMES mark the uses of their
6981 : SSA_NAME_DEF_STMT (recursively), because those uses will be sunk into
6982 : the final statement. */
6983 :
6984 : void
6985 84261 : build_bitint_stmt_ssa_conflicts (gimple *stmt, live_track *live,
6986 : ssa_conflicts *graph, bitmap names,
6987 : void (*def) (live_track *, tree,
6988 : ssa_conflicts *),
6989 : void (*use) (live_track *, tree),
6990 : void (*clear) (live_track *, tree))
6991 : {
6992 84261 : bool muldiv_p = false;
6993 84261 : tree lhs = NULL_TREE;
6994 84261 : if (is_gimple_assign (stmt))
6995 : {
6996 46265 : lhs = gimple_assign_lhs (stmt);
6997 46265 : if (TREE_CODE (lhs) == SSA_NAME)
6998 : {
6999 33443 : tree type = TREE_TYPE (lhs);
7000 33443 : if (TREE_CODE (type) == COMPLEX_TYPE)
7001 63 : type = TREE_TYPE (type);
7002 12866 : if (BITINT_TYPE_P (type)
7003 33448 : && bitint_precision_kind (type) >= bitint_prec_large)
7004 : {
7005 19964 : if (!bitmap_bit_p (names, SSA_NAME_VERSION (lhs)))
7006 4899 : return;
7007 :
7008 : /* A copy between 2 partitions does not introduce an interference
7009 : by itself. If they did, you would never be able to coalesce
7010 : two things which are copied. If the two variables really do
7011 : conflict, they will conflict elsewhere in the program.
7012 :
7013 : This is handled by simply removing the SRC of the copy from
7014 : the live list, and processing the stmt normally.
7015 :
7016 : Don't do this if lhs is not in names though, in such cases
7017 : it is actually used at some point later in the basic
7018 : block. */
7019 15065 : if (gimple_assign_copy_p (stmt))
7020 : {
7021 1686 : tree rhs1 = gimple_assign_rhs1 (stmt);
7022 1686 : if (TREE_CODE (rhs1) == SSA_NAME)
7023 45 : clear (live, rhs1);
7024 : }
7025 :
7026 15065 : switch (gimple_assign_rhs_code (stmt))
7027 : {
7028 166 : case MULT_EXPR:
7029 166 : case TRUNC_DIV_EXPR:
7030 166 : case EXACT_DIV_EXPR:
7031 166 : case TRUNC_MOD_EXPR:
7032 166 : muldiv_p = true;
7033 : default:
7034 : break;
7035 : }
7036 : }
7037 : }
7038 : }
7039 37996 : else if (is_gimple_call (stmt) && gimple_call_internal_p (stmt))
7040 4301 : switch (gimple_call_internal_fn (stmt))
7041 : {
7042 2699 : case IFN_ADD_OVERFLOW:
7043 2699 : case IFN_SUB_OVERFLOW:
7044 2699 : case IFN_UBSAN_CHECK_ADD:
7045 2699 : case IFN_UBSAN_CHECK_SUB:
7046 2699 : if (bitint_big_endian)
7047 : {
7048 0 : lhs = gimple_call_lhs (stmt);
7049 0 : if (lhs)
7050 79362 : muldiv_p = true;
7051 : }
7052 : break;
7053 1478 : case IFN_MUL_OVERFLOW:
7054 1478 : case IFN_UBSAN_CHECK_MUL:
7055 1478 : case IFN_BSWAP:
7056 1478 : case IFN_BITREVERSE:
7057 1478 : lhs = gimple_call_lhs (stmt);
7058 1478 : if (lhs)
7059 79362 : muldiv_p = true;
7060 : break;
7061 : default:
7062 : break;
7063 : }
7064 :
7065 158724 : auto_vec<tree, 16> worklist;
7066 79362 : ssa_op_iter iter;
7067 79362 : tree var;
7068 : /* On little-endian, mergeable ops process limbs from 0 up so except
7069 : for multiplication/division/modulo there is no risk in using the
7070 : same underlying variable for lhs and some operand, even when casts
7071 : are involved, the lhs limb is stored only after processing the source
7072 : limbs with the same index.
7073 : For multiplication/division/modulo, the libgcc library function requires
7074 : no aliasing between result and sources.
7075 : On big-endian, even mergeable ops limb processing can be problematic
7076 : though, because it can apply various index corrections e.g. when there
7077 : is a cast from operand with different number of limbs. So, make the
7078 : lhs conflict with all the operands which are (for now virtually) used on
7079 : the current stmt if there is any mismatch in the number of limbs between
7080 : operands and the lhs. */
7081 79362 : if (bitint_big_endian && lhs && !muldiv_p)
7082 : {
7083 0 : tree ltype = TREE_TYPE (lhs);
7084 0 : if (TREE_CODE (ltype) == COMPLEX_TYPE)
7085 : muldiv_p = true;
7086 0 : else if (TREE_CODE (lhs) == SSA_NAME
7087 0 : && BITINT_TYPE_P (ltype)
7088 0 : && bitint_precision_kind (ltype) >= bitint_prec_large)
7089 : {
7090 0 : unsigned lnelts = CEIL (TYPE_PRECISION (ltype), limb_prec);
7091 0 : FOR_EACH_SSA_TREE_OPERAND (var, stmt, iter, SSA_OP_USE)
7092 : {
7093 0 : tree type = TREE_TYPE (var);
7094 0 : if (TREE_CODE (type) == COMPLEX_TYPE)
7095 0 : type = TREE_TYPE (type);
7096 0 : if (BITINT_TYPE_P (type)
7097 0 : && bitint_precision_kind (type) >= bitint_prec_large)
7098 : {
7099 0 : if (bitmap_bit_p (names, SSA_NAME_VERSION (var)))
7100 : {
7101 0 : unsigned nelts = CEIL (TYPE_PRECISION (type), limb_prec);
7102 0 : if (TREE_CODE (TREE_TYPE (var)) == COMPLEX_TYPE
7103 0 : || lnelts != nelts)
7104 : {
7105 0 : muldiv_p = true;
7106 : break;
7107 : }
7108 : }
7109 : else
7110 0 : worklist.safe_push (var);
7111 : }
7112 : }
7113 :
7114 0 : while (!muldiv_p && worklist.length () > 0)
7115 : {
7116 0 : tree s = worklist.pop ();
7117 0 : FOR_EACH_SSA_TREE_OPERAND (var, SSA_NAME_DEF_STMT (s), iter,
7118 : SSA_OP_USE)
7119 : {
7120 0 : tree type = TREE_TYPE (var);
7121 0 : if (TREE_CODE (type) == COMPLEX_TYPE)
7122 0 : type = TREE_TYPE (type);
7123 0 : if (BITINT_TYPE_P (type)
7124 0 : && bitint_precision_kind (type) >= bitint_prec_large)
7125 : {
7126 0 : if (bitmap_bit_p (names, SSA_NAME_VERSION (var)))
7127 : {
7128 0 : unsigned nelts = CEIL (TYPE_PRECISION (type),
7129 : limb_prec);
7130 0 : if (TREE_CODE (TREE_TYPE (var)) == COMPLEX_TYPE
7131 0 : || lnelts != nelts)
7132 : {
7133 : muldiv_p = true;
7134 : break;
7135 : }
7136 : }
7137 : else
7138 0 : worklist.safe_push (var);
7139 : }
7140 : }
7141 : }
7142 0 : worklist.truncate (0);
7143 : }
7144 : }
7145 :
7146 79362 : if (!muldiv_p)
7147 : {
7148 : /* For stmts with more than one SSA_NAME definition pretend all the
7149 : SSA_NAME outputs but the first one are live at this point, so
7150 : that conflicts are added in between all those even when they are
7151 : actually not really live after the asm, because expansion might
7152 : copy those into pseudos after the asm and if multiple outputs
7153 : share the same partition, it might overwrite those that should
7154 : be live. E.g.
7155 : asm volatile (".." : "=r" (a) : "=r" (b) : "0" (a), "1" (a));
7156 : return a;
7157 : See PR70593. */
7158 77718 : bool first = true;
7159 113747 : FOR_EACH_SSA_TREE_OPERAND (var, stmt, iter, SSA_OP_DEF)
7160 36029 : if (first)
7161 : first = false;
7162 : else
7163 0 : use (live, var);
7164 :
7165 113747 : FOR_EACH_SSA_TREE_OPERAND (var, stmt, iter, SSA_OP_DEF)
7166 36029 : def (live, var, graph);
7167 : }
7168 :
7169 135299 : FOR_EACH_SSA_TREE_OPERAND (var, stmt, iter, SSA_OP_USE)
7170 : {
7171 55937 : tree type = TREE_TYPE (var);
7172 55937 : if (TREE_CODE (type) == COMPLEX_TYPE)
7173 6313 : type = TREE_TYPE (type);
7174 18881 : if (BITINT_TYPE_P (type)
7175 55954 : && bitint_precision_kind (type) >= bitint_prec_large)
7176 : {
7177 36074 : if (bitmap_bit_p (names, SSA_NAME_VERSION (var)))
7178 30974 : use (live, var);
7179 : else
7180 5100 : worklist.safe_push (var);
7181 : }
7182 : }
7183 :
7184 87462 : while (worklist.length () > 0)
7185 : {
7186 8100 : tree s = worklist.pop ();
7187 16940 : FOR_EACH_SSA_TREE_OPERAND (var, SSA_NAME_DEF_STMT (s), iter, SSA_OP_USE)
7188 : {
7189 8840 : tree type = TREE_TYPE (var);
7190 8840 : if (TREE_CODE (type) == COMPLEX_TYPE)
7191 1675 : type = TREE_TYPE (type);
7192 536 : if (BITINT_TYPE_P (type)
7193 8845 : && bitint_precision_kind (type) >= bitint_prec_large)
7194 : {
7195 8174 : if (bitmap_bit_p (names, SSA_NAME_VERSION (var)))
7196 5174 : use (live, var);
7197 : else
7198 3000 : worklist.safe_push (var);
7199 : }
7200 : }
7201 : }
7202 :
7203 79362 : if (muldiv_p)
7204 1644 : def (live, lhs, graph);
7205 : }
7206 :
7207 : /* If STMT is .{ADD,SUB,MUL}_OVERFLOW with INTEGER_CST arguments,
7208 : return the largest bitint_prec_kind of them, otherwise return
7209 : bitint_prec_small. */
7210 :
7211 : static bitint_prec_kind
7212 209983 : arith_overflow_arg_kind (gimple *stmt)
7213 : {
7214 209983 : bitint_prec_kind ret = bitint_prec_small;
7215 209983 : if (is_gimple_call (stmt) && gimple_call_internal_p (stmt))
7216 88685 : switch (gimple_call_internal_fn (stmt))
7217 : {
7218 : case IFN_ADD_OVERFLOW:
7219 : case IFN_SUB_OVERFLOW:
7220 : case IFN_MUL_OVERFLOW:
7221 225087 : for (int i = 0; i < 2; ++i)
7222 : {
7223 150058 : tree a = gimple_call_arg (stmt, i);
7224 150058 : if (TREE_CODE (a) == INTEGER_CST
7225 150058 : && BITINT_TYPE_P (TREE_TYPE (a)))
7226 : {
7227 5930 : bitint_prec_kind kind = bitint_precision_kind (TREE_TYPE (a));
7228 150058 : ret = MAX (ret, kind);
7229 : }
7230 : }
7231 : break;
7232 : default:
7233 : break;
7234 : }
7235 209983 : return ret;
7236 : }
7237 :
7238 : /* Entry point for _BitInt(N) operation lowering during optimization. */
7239 :
7240 : static unsigned int
7241 1512279 : gimple_lower_bitint (void)
7242 : {
7243 1512279 : small_max_prec = mid_min_prec = large_min_prec = huge_min_prec = 0;
7244 1512279 : limb_prec = abi_limb_prec = 0;
7245 1512279 : bitint_big_endian = false;
7246 :
7247 1512279 : unsigned int i;
7248 64946096 : for (i = 0; i < num_ssa_names; ++i)
7249 : {
7250 63441183 : tree s = ssa_name (i);
7251 63441183 : if (s == NULL)
7252 13616584 : continue;
7253 49824599 : tree type = TREE_TYPE (s);
7254 49824599 : if (TREE_CODE (type) == COMPLEX_TYPE)
7255 : {
7256 199303 : if (arith_overflow_arg_kind (SSA_NAME_DEF_STMT (s))
7257 : != bitint_prec_small)
7258 : break;
7259 199190 : type = TREE_TYPE (type);
7260 : }
7261 49807601 : if (BITINT_TYPE_P (type)
7262 49824493 : && bitint_precision_kind (type) != bitint_prec_small)
7263 : break;
7264 : /* We need to also rewrite stores of large/huge _BitInt INTEGER_CSTs
7265 : into memory. Such functions could have no large/huge SSA_NAMEs. */
7266 49817301 : if (SSA_NAME_IS_VIRTUAL_OPERAND (s))
7267 : {
7268 21793558 : gimple *g = SSA_NAME_DEF_STMT (s);
7269 21793558 : if (is_gimple_assign (g) && gimple_store_p (g))
7270 : {
7271 11065231 : tree t = gimple_assign_rhs1 (g);
7272 22127966 : if (BITINT_TYPE_P (TREE_TYPE (t))
7273 11065231 : && (bitint_precision_kind (TREE_TYPE (t))
7274 : >= bitint_prec_large))
7275 : break;
7276 : }
7277 : }
7278 : /* Similarly, e.g. with -frounding-math casts from _BitInt INTEGER_CSTs
7279 : to floating point types need to be rewritten. */
7280 28023743 : else if (SCALAR_FLOAT_TYPE_P (type))
7281 : {
7282 2327287 : gimple *g = SSA_NAME_DEF_STMT (s);
7283 2327287 : if (is_gimple_assign (g) && gimple_assign_rhs_code (g) == FLOAT_EXPR)
7284 : {
7285 128466 : tree t = gimple_assign_rhs1 (g);
7286 128466 : if (TREE_CODE (t) == INTEGER_CST
7287 110 : && BITINT_TYPE_P (TREE_TYPE (t))
7288 128467 : && (bitint_precision_kind (TREE_TYPE (t))
7289 : != bitint_prec_small))
7290 : break;
7291 : }
7292 : }
7293 : }
7294 3024558 : if (i == num_ssa_names)
7295 : return 0;
7296 :
7297 7366 : basic_block bb;
7298 7366 : auto_vec<gimple *, 4> switch_statements;
7299 46241 : FOR_EACH_BB_FN (bb, cfun)
7300 : {
7301 115858 : if (gswitch *swtch = safe_dyn_cast <gswitch *> (*gsi_last_bb (bb)))
7302 : {
7303 24 : tree idx = gimple_switch_index (swtch);
7304 32 : if (!BITINT_TYPE_P (TREE_TYPE (idx))
7305 24 : || bitint_precision_kind (TREE_TYPE (idx)) < bitint_prec_large)
7306 13 : continue;
7307 :
7308 11 : if (optimize)
7309 6 : group_case_labels_stmt (swtch);
7310 11 : if (gimple_switch_num_labels (swtch) == 1)
7311 : {
7312 0 : single_succ_edge (bb)->flags |= EDGE_FALLTHRU;
7313 0 : gimple_stmt_iterator gsi = gsi_for_stmt (swtch);
7314 0 : gsi_remove (&gsi, true);
7315 : }
7316 : else
7317 11 : switch_statements.safe_push (swtch);
7318 : }
7319 : }
7320 :
7321 7366 : if (!switch_statements.is_empty ())
7322 : {
7323 11 : bool expanded = false;
7324 11 : gimple *stmt;
7325 11 : unsigned int j;
7326 11 : i = 0;
7327 22 : FOR_EACH_VEC_ELT (switch_statements, j, stmt)
7328 : {
7329 11 : gswitch *swtch = as_a<gswitch *> (stmt);
7330 11 : tree_switch_conversion::switch_decision_tree dt (swtch);
7331 11 : expanded |= dt.analyze_switch_statement ();
7332 11 : }
7333 :
7334 11 : if (expanded)
7335 : {
7336 11 : free_dominance_info (CDI_DOMINATORS);
7337 11 : free_dominance_info (CDI_POST_DOMINATORS);
7338 11 : mark_virtual_operands_for_renaming (cfun);
7339 11 : cleanup_tree_cfg (TODO_update_ssa);
7340 : }
7341 : }
7342 :
7343 7366 : if (flag_sanitize & (SANITIZE_ADDRESS | SANITIZE_HWADDRESS))
7344 : {
7345 14 : hash_map<tree, tree> shadow_vars_mapping;
7346 14 : bool need_commit_edge_insert = false;
7347 14 : bool any_asan_poison = false;
7348 129 : for (unsigned j = 0; j < num_ssa_names; ++j)
7349 : {
7350 115 : tree s = ssa_name (j);
7351 115 : if (s == NULL)
7352 31 : continue;
7353 84 : tree type = TREE_TYPE (s);
7354 37 : if (BITINT_TYPE_P (type)
7355 47 : && gimple_call_internal_p (SSA_NAME_DEF_STMT (s),
7356 : IFN_ASAN_POISON)
7357 112 : && bitint_precision_kind (type) >= bitint_prec_large)
7358 : {
7359 28 : any_asan_poison = true;
7360 28 : gimple_stmt_iterator gsi = gsi_for_stmt (SSA_NAME_DEF_STMT (s));
7361 28 : asan_expand_poison_ifn (&gsi, &need_commit_edge_insert,
7362 : shadow_vars_mapping);
7363 : }
7364 : }
7365 14 : if (any_asan_poison)
7366 : {
7367 14 : if (need_commit_edge_insert)
7368 0 : gsi_commit_edge_inserts ();
7369 14 : i = 0;
7370 14 : free_dominance_info (CDI_DOMINATORS);
7371 14 : free_dominance_info (CDI_POST_DOMINATORS);
7372 14 : mark_virtual_operands_for_renaming (cfun);
7373 14 : cleanup_tree_cfg (TODO_update_ssa);
7374 : }
7375 14 : }
7376 :
7377 7366 : struct bitint_large_huge large_huge;
7378 7366 : bool has_large_huge_parm_result = false;
7379 7366 : bool has_large_huge = false;
7380 7366 : unsigned int ret = 0, first_large_huge = ~0U;
7381 7366 : bool edge_insertions = false;
7382 126841 : for (; i < num_ssa_names; ++i)
7383 : {
7384 119475 : tree s = ssa_name (i);
7385 119475 : if (s == NULL)
7386 2811 : continue;
7387 116664 : tree type = TREE_TYPE (s);
7388 116664 : if (TREE_CODE (type) == COMPLEX_TYPE)
7389 : {
7390 5355 : if (arith_overflow_arg_kind (SSA_NAME_DEF_STMT (s))
7391 : >= bitint_prec_large)
7392 1958 : has_large_huge = true;
7393 5355 : type = TREE_TYPE (type);
7394 : }
7395 70409 : if (BITINT_TYPE_P (type)
7396 116690 : && bitint_precision_kind (type) >= bitint_prec_large)
7397 : {
7398 36169 : if (first_large_huge == ~0U)
7399 5814 : first_large_huge = i;
7400 36169 : gimple *stmt = SSA_NAME_DEF_STMT (s), *g;
7401 36169 : gimple_stmt_iterator gsi;
7402 36169 : tree_code rhs_code;
7403 : /* Unoptimize certain constructs to simpler alternatives to
7404 : avoid having to lower all of them. */
7405 36169 : if (is_gimple_assign (stmt) && gimple_bb (stmt))
7406 22279 : switch (rhs_code = gimple_assign_rhs_code (stmt))
7407 : {
7408 : default:
7409 : break;
7410 371 : case MULT_EXPR:
7411 371 : case TRUNC_DIV_EXPR:
7412 371 : case EXACT_DIV_EXPR:
7413 371 : case TRUNC_MOD_EXPR:
7414 371 : if (SSA_NAME_OCCURS_IN_ABNORMAL_PHI (s))
7415 : {
7416 2 : location_t loc = gimple_location (stmt);
7417 2 : gsi = gsi_for_stmt (stmt);
7418 2 : tree rhs1 = gimple_assign_rhs1 (stmt);
7419 2 : tree rhs2 = gimple_assign_rhs2 (stmt);
7420 : /* For multiplication and division with (ab)
7421 : lhs and one or both operands force the operands
7422 : into new SSA_NAMEs to avoid coalescing failures. */
7423 2 : if (TREE_CODE (rhs1) == SSA_NAME
7424 2 : && SSA_NAME_OCCURS_IN_ABNORMAL_PHI (rhs1))
7425 : {
7426 2 : first_large_huge = 0;
7427 2 : tree t = make_ssa_name (TREE_TYPE (rhs1));
7428 2 : g = gimple_build_assign (t, SSA_NAME, rhs1);
7429 2 : gsi_insert_before (&gsi, g, GSI_SAME_STMT);
7430 2 : gimple_set_location (g, loc);
7431 2 : gimple_assign_set_rhs1 (stmt, t);
7432 2 : if (rhs1 == rhs2)
7433 : {
7434 0 : gimple_assign_set_rhs2 (stmt, t);
7435 0 : rhs2 = t;
7436 : }
7437 2 : update_stmt (stmt);
7438 : }
7439 2 : if (TREE_CODE (rhs2) == SSA_NAME
7440 2 : && SSA_NAME_OCCURS_IN_ABNORMAL_PHI (rhs2))
7441 : {
7442 0 : first_large_huge = 0;
7443 0 : tree t = make_ssa_name (TREE_TYPE (rhs2));
7444 0 : g = gimple_build_assign (t, SSA_NAME, rhs2);
7445 0 : gsi_insert_before (&gsi, g, GSI_SAME_STMT);
7446 0 : gimple_set_location (g, loc);
7447 0 : gimple_assign_set_rhs2 (stmt, t);
7448 0 : update_stmt (stmt);
7449 : }
7450 : }
7451 : break;
7452 3 : case LROTATE_EXPR:
7453 3 : case RROTATE_EXPR:
7454 3 : {
7455 3 : first_large_huge = 0;
7456 3 : location_t loc = gimple_location (stmt);
7457 3 : gsi = gsi_for_stmt (stmt);
7458 3 : tree rhs1 = gimple_assign_rhs1 (stmt);
7459 3 : tree type = TREE_TYPE (rhs1);
7460 3 : tree n = gimple_assign_rhs2 (stmt), m;
7461 3 : tree p = build_int_cst (TREE_TYPE (n),
7462 3 : TYPE_PRECISION (type));
7463 3 : if (TREE_CODE (n) == INTEGER_CST)
7464 : {
7465 0 : if (integer_zerop (n))
7466 : m = n;
7467 : else
7468 0 : m = fold_build2 (MINUS_EXPR, TREE_TYPE (n), p, n);
7469 : }
7470 : else
7471 : {
7472 3 : tree tem = make_ssa_name (TREE_TYPE (n));
7473 3 : g = gimple_build_assign (tem, MINUS_EXPR, p, n);
7474 3 : gsi_insert_before (&gsi, g, GSI_SAME_STMT);
7475 3 : gimple_set_location (g, loc);
7476 3 : m = make_ssa_name (TREE_TYPE (n));
7477 3 : g = gimple_build_assign (m, TRUNC_MOD_EXPR, tem, p);
7478 3 : gsi_insert_before (&gsi, g, GSI_SAME_STMT);
7479 3 : gimple_set_location (g, loc);
7480 : }
7481 3 : if (!TYPE_UNSIGNED (type))
7482 : {
7483 0 : tree utype = build_bitint_type (TYPE_PRECISION (type),
7484 : 1);
7485 0 : if (TREE_CODE (rhs1) == INTEGER_CST)
7486 0 : rhs1 = fold_convert (utype, rhs1);
7487 : else
7488 : {
7489 0 : tree t = make_ssa_name (type);
7490 0 : g = gimple_build_assign (t, NOP_EXPR, rhs1);
7491 0 : gsi_insert_before (&gsi, g, GSI_SAME_STMT);
7492 0 : gimple_set_location (g, loc);
7493 : }
7494 : }
7495 4 : g = gimple_build_assign (make_ssa_name (TREE_TYPE (rhs1)),
7496 : rhs_code == LROTATE_EXPR
7497 : ? LSHIFT_EXPR : RSHIFT_EXPR,
7498 : rhs1, n);
7499 3 : gsi_insert_before (&gsi, g, GSI_SAME_STMT);
7500 3 : gimple_set_location (g, loc);
7501 3 : tree op1 = gimple_assign_lhs (g);
7502 4 : g = gimple_build_assign (make_ssa_name (TREE_TYPE (rhs1)),
7503 : rhs_code == LROTATE_EXPR
7504 : ? RSHIFT_EXPR : LSHIFT_EXPR,
7505 : rhs1, m);
7506 3 : gsi_insert_before (&gsi, g, GSI_SAME_STMT);
7507 3 : gimple_set_location (g, loc);
7508 3 : tree op2 = gimple_assign_lhs (g);
7509 3 : tree lhs = gimple_assign_lhs (stmt);
7510 3 : if (!TYPE_UNSIGNED (type))
7511 : {
7512 0 : g = gimple_build_assign (make_ssa_name (TREE_TYPE (op1)),
7513 : BIT_IOR_EXPR, op1, op2);
7514 0 : gsi_insert_before (&gsi, g, GSI_SAME_STMT);
7515 0 : gimple_set_location (g, loc);
7516 0 : g = gimple_build_assign (lhs, NOP_EXPR,
7517 : gimple_assign_lhs (g));
7518 : }
7519 : else
7520 3 : g = gimple_build_assign (lhs, BIT_IOR_EXPR, op1, op2);
7521 3 : gsi_replace (&gsi, g, true);
7522 3 : gimple_set_location (g, loc);
7523 : }
7524 3 : break;
7525 17 : case ABS_EXPR:
7526 17 : case ABSU_EXPR:
7527 17 : case MIN_EXPR:
7528 17 : case MAX_EXPR:
7529 17 : case COND_EXPR:
7530 17 : first_large_huge = 0;
7531 17 : gsi = gsi_for_stmt (stmt);
7532 17 : tree lhs = gimple_assign_lhs (stmt);
7533 17 : tree rhs1 = gimple_assign_rhs1 (stmt), rhs2 = NULL_TREE;
7534 17 : location_t loc = gimple_location (stmt);
7535 17 : if (rhs_code == ABS_EXPR)
7536 4 : g = gimple_build_cond (LT_EXPR, rhs1,
7537 4 : build_zero_cst (TREE_TYPE (rhs1)),
7538 : NULL_TREE, NULL_TREE);
7539 13 : else if (rhs_code == ABSU_EXPR)
7540 : {
7541 4 : rhs2 = make_ssa_name (TREE_TYPE (lhs));
7542 4 : g = gimple_build_assign (rhs2, NOP_EXPR, rhs1);
7543 4 : gsi_insert_before (&gsi, g, GSI_SAME_STMT);
7544 4 : gimple_set_location (g, loc);
7545 4 : g = gimple_build_cond (LT_EXPR, rhs1,
7546 4 : build_zero_cst (TREE_TYPE (rhs1)),
7547 : NULL_TREE, NULL_TREE);
7548 4 : rhs1 = rhs2;
7549 : }
7550 9 : else if (rhs_code == MIN_EXPR || rhs_code == MAX_EXPR)
7551 : {
7552 9 : rhs2 = gimple_assign_rhs2 (stmt);
7553 9 : if (TREE_CODE (rhs1) == INTEGER_CST)
7554 0 : std::swap (rhs1, rhs2);
7555 9 : g = gimple_build_cond (LT_EXPR, rhs1, rhs2,
7556 : NULL_TREE, NULL_TREE);
7557 9 : if (rhs_code == MAX_EXPR)
7558 5 : std::swap (rhs1, rhs2);
7559 : }
7560 : else
7561 : {
7562 0 : g = gimple_build_cond (NE_EXPR, rhs1,
7563 0 : build_zero_cst (TREE_TYPE (rhs1)),
7564 : NULL_TREE, NULL_TREE);
7565 0 : rhs1 = gimple_assign_rhs2 (stmt);
7566 0 : rhs2 = gimple_assign_rhs3 (stmt);
7567 : }
7568 17 : gsi_insert_before (&gsi, g, GSI_SAME_STMT);
7569 17 : gimple_set_location (g, loc);
7570 17 : edge e1 = split_block (gsi_bb (gsi), g);
7571 17 : edge e2 = split_block (e1->dest, (gimple *) NULL);
7572 17 : edge e3 = make_edge (e1->src, e2->dest, EDGE_FALSE_VALUE);
7573 17 : e3->probability = profile_probability::even ();
7574 17 : e1->flags = EDGE_TRUE_VALUE;
7575 17 : e1->probability = e3->probability.invert ();
7576 17 : if (dom_info_available_p (CDI_DOMINATORS))
7577 9 : set_immediate_dominator (CDI_DOMINATORS, e2->dest, e1->src);
7578 17 : if (rhs_code == ABS_EXPR || rhs_code == ABSU_EXPR)
7579 : {
7580 8 : gsi = gsi_after_labels (e1->dest);
7581 8 : g = gimple_build_assign (make_ssa_name (TREE_TYPE (rhs1)),
7582 : NEGATE_EXPR, rhs1);
7583 8 : gsi_insert_before (&gsi, g, GSI_SAME_STMT);
7584 8 : gimple_set_location (g, loc);
7585 8 : rhs2 = gimple_assign_lhs (g);
7586 8 : std::swap (rhs1, rhs2);
7587 : }
7588 17 : gsi = gsi_for_stmt (stmt);
7589 17 : gsi_remove (&gsi, true);
7590 17 : gphi *phi = create_phi_node (lhs, e2->dest);
7591 17 : add_phi_arg (phi, rhs1, e2, UNKNOWN_LOCATION);
7592 17 : add_phi_arg (phi, rhs2, e3, UNKNOWN_LOCATION);
7593 17 : break;
7594 : }
7595 13890 : else if (SSA_NAME_OCCURS_IN_ABNORMAL_PHI (s)
7596 76 : && is_gimple_call (stmt)
7597 13910 : && gimple_call_internal_p (stmt))
7598 20 : switch (gimple_call_internal_fn (stmt))
7599 : {
7600 12 : case IFN_UBSAN_CHECK_ADD:
7601 12 : case IFN_UBSAN_CHECK_SUB:
7602 12 : if (!bitint_big_endian)
7603 : break;
7604 : /* FALLTHRU */
7605 : case IFN_UBSAN_CHECK_MUL:
7606 : case IFN_BSWAP:
7607 : case IFN_BITREVERSE:
7608 22 : for (unsigned i = 0; i < gimple_call_num_args (stmt); ++i)
7609 : {
7610 14 : location_t loc = gimple_location (stmt);
7611 14 : gsi = gsi_for_stmt (stmt);
7612 : /* Similar case to multiplication/division with (ab)
7613 : above for internal functions which set muldiv_p. */
7614 14 : tree arg = gimple_call_arg (stmt, i);
7615 14 : if (TREE_CODE (arg) == SSA_NAME
7616 14 : && SSA_NAME_OCCURS_IN_ABNORMAL_PHI (arg))
7617 : {
7618 8 : first_large_huge = 0;
7619 8 : tree t = make_ssa_name (TREE_TYPE (arg));
7620 8 : g = gimple_build_assign (t, SSA_NAME, arg);
7621 8 : gsi_insert_before (&gsi, g, GSI_SAME_STMT);
7622 8 : gimple_set_location (g, loc);
7623 8 : gimple_call_set_arg (stmt, i, t);
7624 8 : if (i == 0
7625 8 : && gimple_call_num_args (stmt) >= 2
7626 14 : && gimple_call_arg (stmt, 1) == arg)
7627 0 : gimple_call_set_arg (stmt, 1, t);
7628 8 : update_stmt (stmt);
7629 : }
7630 : }
7631 : break;
7632 : default:
7633 : break;
7634 : }
7635 : }
7636 : /* We need to also rewrite stores of large/huge _BitInt INTEGER_CSTs
7637 : into memory. Such functions could have no large/huge SSA_NAMEs. */
7638 80495 : else if (SSA_NAME_IS_VIRTUAL_OPERAND (s))
7639 : {
7640 51244 : gimple *g = SSA_NAME_DEF_STMT (s);
7641 51244 : if (is_gimple_assign (g) && gimple_store_p (g))
7642 : {
7643 16396 : tree t = gimple_assign_rhs1 (g);
7644 18579 : if (BITINT_TYPE_P (TREE_TYPE (t))
7645 16396 : && (bitint_precision_kind (TREE_TYPE (t))
7646 : >= bitint_prec_large))
7647 : has_large_huge = true;
7648 : }
7649 : }
7650 : /* Similarly, e.g. with -frounding-math casts from _BitInt INTEGER_CSTs
7651 : to floating point types need to be rewritten. */
7652 29251 : else if (SCALAR_FLOAT_TYPE_P (type))
7653 : {
7654 694 : gimple *g = SSA_NAME_DEF_STMT (s);
7655 694 : if (is_gimple_assign (g) && gimple_assign_rhs_code (g) == FLOAT_EXPR)
7656 : {
7657 187 : tree t = gimple_assign_rhs1 (g);
7658 187 : if (TREE_CODE (t) == INTEGER_CST
7659 1 : && BITINT_TYPE_P (TREE_TYPE (t))
7660 188 : && (bitint_precision_kind (TREE_TYPE (t))
7661 : >= bitint_prec_large))
7662 : has_large_huge = true;
7663 : }
7664 : }
7665 : }
7666 103229 : for (i = first_large_huge; i < num_ssa_names; ++i)
7667 : {
7668 95863 : tree s = ssa_name (i);
7669 95863 : if (s == NULL)
7670 2465 : continue;
7671 93398 : tree type = TREE_TYPE (s);
7672 93398 : if (TREE_CODE (type) == COMPLEX_TYPE)
7673 4124 : type = TREE_TYPE (type);
7674 56591 : if (BITINT_TYPE_P (type)
7675 93422 : && bitint_precision_kind (type) >= bitint_prec_large)
7676 : {
7677 36169 : use_operand_p use_p;
7678 36169 : gimple *use_stmt;
7679 36169 : has_large_huge = true;
7680 37833 : if (optimize
7681 53220 : && optimizable_arith_overflow (SSA_NAME_DEF_STMT (s)))
7682 6577 : continue;
7683 : /* Ignore large/huge _BitInt SSA_NAMEs which have single use in
7684 : the same bb and could be handled in the same loop with the
7685 : immediate use. */
7686 34505 : if (optimize
7687 15387 : && !SSA_NAME_OCCURS_IN_ABNORMAL_PHI (s)
7688 15320 : && single_imm_use (s, &use_p, &use_stmt)
7689 49212 : && gimple_bb (SSA_NAME_DEF_STMT (s)) == gimple_bb (use_stmt))
7690 : {
7691 10345 : if (mergeable_op (SSA_NAME_DEF_STMT (s)))
7692 : {
7693 2222 : if (mergeable_op (use_stmt))
7694 1911 : continue;
7695 311 : tree_code cmp_code = comparison_op (use_stmt, NULL, NULL);
7696 311 : if (cmp_code == EQ_EXPR || cmp_code == NE_EXPR)
7697 26 : continue;
7698 285 : if (gimple_assign_cast_p (use_stmt))
7699 : {
7700 130 : tree lhs = gimple_assign_lhs (use_stmt);
7701 260 : if (INTEGRAL_TYPE_P (TREE_TYPE (lhs))
7702 : /* Don't merge with VIEW_CONVERT_EXPRs to
7703 : huge INTEGER_TYPEs used sometimes in memcpy
7704 : expansion. */
7705 248 : && (TREE_CODE (TREE_TYPE (lhs)) != INTEGER_TYPE
7706 6 : || (TYPE_PRECISION (TREE_TYPE (lhs))
7707 12 : <= MAX_FIXED_MODE_SIZE)))
7708 118 : continue;
7709 : }
7710 155 : else if (gimple_store_p (use_stmt)
7711 0 : && is_gimple_assign (use_stmt)
7712 0 : && !gimple_has_volatile_ops (use_stmt)
7713 155 : && !stmt_ends_bb_p (use_stmt))
7714 0 : continue;
7715 : }
7716 8290 : if (gimple_assign_cast_p (SSA_NAME_DEF_STMT (s)))
7717 : {
7718 864 : tree rhs1 = gimple_assign_rhs1 (SSA_NAME_DEF_STMT (s));
7719 864 : if (TREE_CODE (rhs1) == VIEW_CONVERT_EXPR)
7720 : {
7721 20 : rhs1 = TREE_OPERAND (rhs1, 0);
7722 20 : if (!INTEGRAL_TYPE_P (TREE_TYPE (rhs1))
7723 16 : && !POINTER_TYPE_P (TREE_TYPE (rhs1))
7724 16 : && gimple_store_p (use_stmt))
7725 7 : continue;
7726 : }
7727 1714 : if (INTEGRAL_TYPE_P (TREE_TYPE (rhs1))
7728 766 : && ((is_gimple_assign (use_stmt)
7729 719 : && (gimple_assign_rhs_code (use_stmt)
7730 : != COMPLEX_EXPR))
7731 47 : || gimple_code (use_stmt) == GIMPLE_COND)
7732 756 : && (!gimple_store_p (use_stmt)
7733 132 : || (is_gimple_assign (use_stmt)
7734 132 : && !gimple_has_volatile_ops (use_stmt)
7735 132 : && !stmt_ends_bb_p (use_stmt)))
7736 1613 : && (TREE_CODE (rhs1) != SSA_NAME
7737 756 : || !SSA_NAME_OCCURS_IN_ABNORMAL_PHI (rhs1)))
7738 : {
7739 756 : if (is_gimple_assign (use_stmt))
7740 719 : switch (gimple_assign_rhs_code (use_stmt))
7741 : {
7742 54 : case TRUNC_DIV_EXPR:
7743 54 : case EXACT_DIV_EXPR:
7744 54 : case TRUNC_MOD_EXPR:
7745 54 : case FLOAT_EXPR:
7746 : /* For division, modulo and casts to floating
7747 : point, avoid representing unsigned operands
7748 : using negative prec if they were sign-extended
7749 : from narrower precision. */
7750 54 : if (TYPE_UNSIGNED (TREE_TYPE (s))
7751 28 : && !TYPE_UNSIGNED (TREE_TYPE (rhs1))
7752 63 : && (TYPE_PRECISION (TREE_TYPE (s))
7753 9 : > TYPE_PRECISION (TREE_TYPE (rhs1))))
7754 8 : goto force_name;
7755 : /* FALLTHRU */
7756 113 : case MULT_EXPR:
7757 128 : if (!BITINT_TYPE_P (TREE_TYPE (rhs1))
7758 113 : || (bitint_precision_kind (TREE_TYPE (rhs1))
7759 : < bitint_prec_large))
7760 48 : continue;
7761 : /* Uses which use handle_operand_addr can't
7762 : deal with nested casts. */
7763 65 : if (TREE_CODE (rhs1) == SSA_NAME
7764 65 : && gimple_assign_cast_p
7765 65 : (SSA_NAME_DEF_STMT (rhs1))
7766 43 : && has_single_use (rhs1)
7767 108 : && (gimple_bb (SSA_NAME_DEF_STMT (rhs1))
7768 43 : == gimple_bb (SSA_NAME_DEF_STMT (s))))
7769 43 : goto force_name;
7770 : break;
7771 0 : case VIEW_CONVERT_EXPR:
7772 0 : {
7773 0 : tree lhs = gimple_assign_lhs (use_stmt);
7774 : /* Don't merge with VIEW_CONVERT_EXPRs to
7775 : non-integral types. */
7776 0 : if (!INTEGRAL_TYPE_P (TREE_TYPE (lhs)))
7777 0 : goto force_name;
7778 : /* Don't merge with VIEW_CONVERT_EXPRs to
7779 : huge INTEGER_TYPEs used sometimes in memcpy
7780 : expansion. */
7781 0 : if (TREE_CODE (TREE_TYPE (lhs)) == INTEGER_TYPE
7782 0 : && (TYPE_PRECISION (TREE_TYPE (lhs))
7783 0 : > MAX_FIXED_MODE_SIZE))
7784 0 : goto force_name;
7785 : }
7786 : break;
7787 : default:
7788 : break;
7789 : }
7790 834 : if (!BITINT_TYPE_P (TREE_TYPE (rhs1))
7791 657 : || (bitint_precision_kind (TREE_TYPE (rhs1))
7792 : < bitint_prec_large))
7793 239 : continue;
7794 418 : if ((TYPE_PRECISION (TREE_TYPE (rhs1))
7795 418 : >= TYPE_PRECISION (TREE_TYPE (s)))
7796 418 : && mergeable_op (use_stmt))
7797 60 : continue;
7798 : /* Prevent merging a widening non-mergeable cast
7799 : on result of some narrower mergeable op
7800 : together with later mergeable operations. E.g.
7801 : result of _BitInt(223) addition shouldn't be
7802 : sign-extended to _BitInt(513) and have another
7803 : _BitInt(513) added to it, as handle_plus_minus
7804 : with its PHI node handling inside of handle_cast
7805 : will not work correctly. An exception is if
7806 : use_stmt is a store, this is handled directly
7807 : in lower_mergeable_stmt. */
7808 709 : if (TREE_CODE (rhs1) != SSA_NAME
7809 358 : || !has_single_use (rhs1)
7810 272 : || (gimple_bb (SSA_NAME_DEF_STMT (rhs1))
7811 272 : != gimple_bb (SSA_NAME_DEF_STMT (s)))
7812 216 : || !mergeable_op (SSA_NAME_DEF_STMT (rhs1))
7813 445 : || gimple_store_p (use_stmt))
7814 351 : continue;
7815 7 : if ((TYPE_PRECISION (TREE_TYPE (rhs1))
7816 7 : < TYPE_PRECISION (TREE_TYPE (s)))
7817 9 : && gimple_assign_cast_p (SSA_NAME_DEF_STMT (rhs1)))
7818 : {
7819 : /* Another exception is if the widening cast is
7820 : from mergeable same precision cast from something
7821 : not mergeable. */
7822 0 : tree rhs2
7823 0 : = gimple_assign_rhs1 (SSA_NAME_DEF_STMT (rhs1));
7824 0 : if (BITINT_TYPE_P (TREE_TYPE (rhs2))
7825 0 : && (TYPE_PRECISION (TREE_TYPE (rhs1))
7826 0 : == TYPE_PRECISION (TREE_TYPE (rhs2))))
7827 : {
7828 0 : if (TREE_CODE (rhs2) != SSA_NAME
7829 0 : || !has_single_use (rhs2)
7830 0 : || (gimple_bb (SSA_NAME_DEF_STMT (rhs2))
7831 0 : != gimple_bb (SSA_NAME_DEF_STMT (s)))
7832 0 : || !mergeable_op (SSA_NAME_DEF_STMT (rhs2)))
7833 0 : continue;
7834 : }
7835 : }
7836 : }
7837 : }
7838 7534 : if (is_gimple_assign (SSA_NAME_DEF_STMT (s)))
7839 5424 : switch (gimple_assign_rhs_code (SSA_NAME_DEF_STMT (s)))
7840 : {
7841 1794 : case REALPART_EXPR:
7842 1794 : case IMAGPART_EXPR:
7843 1794 : {
7844 1794 : gimple *ds = SSA_NAME_DEF_STMT (s);
7845 1794 : tree rhs1 = gimple_assign_rhs1 (ds);
7846 1794 : rhs1 = TREE_OPERAND (rhs1, 0);
7847 1794 : if (TREE_CODE (rhs1) == SSA_NAME)
7848 : {
7849 1794 : gimple *g = SSA_NAME_DEF_STMT (rhs1);
7850 1794 : if (optimizable_arith_overflow (g))
7851 : {
7852 1650 : if (gimple_assign_rhs_code (ds) == IMAGPART_EXPR)
7853 1640 : continue;
7854 10 : if (gimple_store_p (use_stmt))
7855 : {
7856 : /* Punt if the cast use of IMAGPART_EXPR stmt
7857 : appears before the store use_stmt, because
7858 : optimizable arith overflow can't be
7859 : lowered at the store location in that case.
7860 : See PR121828. */
7861 10 : gimple_stmt_iterator gsi
7862 10 : = gsi_for_stmt (use_stmt);
7863 10 : unsigned int cnt = 0;
7864 12 : do
7865 : {
7866 12 : gsi_prev_nondebug (&gsi);
7867 12 : if (gsi_end_p (gsi))
7868 : break;
7869 12 : gimple *g2 = gsi_stmt (gsi);
7870 12 : if (g2 == ds)
7871 : break;
7872 3 : if (++cnt == 64)
7873 : break;
7874 3 : if (!gimple_assign_cast_p (g2))
7875 2 : continue;
7876 1 : tree rhs2 = gimple_assign_rhs1 (g2);
7877 1 : if (TREE_CODE (rhs2) != SSA_NAME)
7878 0 : continue;
7879 1 : gimple *g3 = SSA_NAME_DEF_STMT (rhs2);
7880 1 : if (!is_gimple_assign (g3))
7881 0 : continue;
7882 1 : if (gimple_assign_rhs_code (g3)
7883 : != IMAGPART_EXPR)
7884 0 : continue;
7885 1 : rhs2 = gimple_assign_rhs1 (g3);
7886 1 : rhs2 = TREE_OPERAND (rhs2, 0);
7887 1 : if (rhs2 != rhs1)
7888 0 : continue;
7889 : cnt = 64;
7890 : break;
7891 : }
7892 : while (1);
7893 10 : if (cnt == 64)
7894 : break;
7895 : }
7896 : }
7897 : }
7898 : }
7899 : /* FALLTHRU */
7900 844 : case LSHIFT_EXPR:
7901 844 : case RSHIFT_EXPR:
7902 844 : case MULT_EXPR:
7903 844 : case TRUNC_DIV_EXPR:
7904 844 : case EXACT_DIV_EXPR:
7905 844 : case TRUNC_MOD_EXPR:
7906 844 : case FIX_TRUNC_EXPR:
7907 844 : if (gimple_store_p (use_stmt)
7908 444 : && is_gimple_assign (use_stmt)
7909 444 : && !gimple_has_volatile_ops (use_stmt)
7910 1288 : && !stmt_ends_bb_p (use_stmt))
7911 : {
7912 444 : tree lhs = gimple_assign_lhs (use_stmt);
7913 : /* As multiply/division passes address of the lhs
7914 : to library function and that assumes it can extend
7915 : it to whole number of limbs, avoid merging those
7916 : with bit-field stores. Don't allow it for
7917 : shifts etc. either, so that the bit-field store
7918 : handling doesn't have to be done everywhere. */
7919 444 : if (TREE_CODE (lhs) == COMPONENT_REF
7920 444 : && DECL_BIT_FIELD_TYPE (TREE_OPERAND (lhs, 1)))
7921 : break;
7922 441 : continue;
7923 441 : }
7924 : break;
7925 : default:
7926 : break;
7927 : }
7928 2110 : else if (is_gimple_call (SSA_NAME_DEF_STMT (s))
7929 2110 : && gimple_call_internal_p (SSA_NAME_DEF_STMT (s)))
7930 15 : switch (gimple_call_internal_fn (SSA_NAME_DEF_STMT (s)))
7931 : {
7932 13 : case IFN_BSWAP:
7933 13 : case IFN_BITREVERSE:
7934 13 : if (gimple_store_p (use_stmt)
7935 13 : && is_gimple_assign (use_stmt)
7936 13 : && !gimple_has_volatile_ops (use_stmt)
7937 26 : && !stmt_ends_bb_p (use_stmt))
7938 : {
7939 13 : tree lhs = gimple_assign_lhs (use_stmt);
7940 13 : if (TREE_CODE (lhs) == COMPONENT_REF
7941 13 : && DECL_BIT_FIELD_TYPE (TREE_OPERAND (lhs, 1)))
7942 : break;
7943 13 : continue;
7944 13 : }
7945 : break;
7946 : default:
7947 : break;
7948 : }
7949 : }
7950 :
7951 : /* Also ignore uninitialized uses. */
7952 29600 : if (SSA_NAME_IS_DEFAULT_DEF (s)
7953 29600 : && (!SSA_NAME_VAR (s) || VAR_P (SSA_NAME_VAR (s))))
7954 59 : continue;
7955 :
7956 29592 : force_name:
7957 29592 : if (!large_huge.m_names)
7958 5691 : large_huge.m_names = BITMAP_ALLOC (NULL);
7959 29592 : bitmap_set_bit (large_huge.m_names, SSA_NAME_VERSION (s));
7960 29592 : if (has_single_use (s))
7961 : {
7962 : tree s2 = s;
7963 : /* The coalescing hook special cases SSA_NAME copies.
7964 : Make sure not to mark in m_single_use_names single
7965 : use SSA_NAMEs copied from non-single use SSA_NAMEs. */
7966 25889 : while (gimple_assign_copy_p (SSA_NAME_DEF_STMT (s2)))
7967 : {
7968 938 : s2 = gimple_assign_rhs1 (SSA_NAME_DEF_STMT (s2));
7969 938 : if (TREE_CODE (s2) != SSA_NAME)
7970 : break;
7971 41 : if (!has_single_use (s2))
7972 : {
7973 : s2 = NULL_TREE;
7974 : break;
7975 : }
7976 : }
7977 25876 : if (s2)
7978 : {
7979 25848 : if (!large_huge.m_single_use_names)
7980 5577 : large_huge.m_single_use_names = BITMAP_ALLOC (NULL);
7981 25848 : bitmap_set_bit (large_huge.m_single_use_names,
7982 25848 : SSA_NAME_VERSION (s));
7983 : }
7984 : }
7985 29592 : if (SSA_NAME_VAR (s)
7986 7370 : && ((TREE_CODE (SSA_NAME_VAR (s)) == PARM_DECL
7987 5420 : && SSA_NAME_IS_DEFAULT_DEF (s))
7988 1987 : || TREE_CODE (SSA_NAME_VAR (s)) == RESULT_DECL))
7989 : has_large_huge_parm_result = true;
7990 29592 : if (optimize
7991 10474 : && !SSA_NAME_OCCURS_IN_ABNORMAL_PHI (s)
7992 10407 : && gimple_assign_load_p (SSA_NAME_DEF_STMT (s))
7993 6074 : && !gimple_has_volatile_ops (SSA_NAME_DEF_STMT (s))
7994 32580 : && !stmt_ends_bb_p (SSA_NAME_DEF_STMT (s)))
7995 : {
7996 2988 : use_operand_p use_p;
7997 2988 : imm_use_iterator iter;
7998 2988 : bool optimizable_load = true;
7999 6041 : FOR_EACH_IMM_USE_FAST (use_p, iter, s)
8000 : {
8001 3151 : gimple *use_stmt = USE_STMT (use_p);
8002 3151 : if (is_gimple_debug (use_stmt))
8003 0 : continue;
8004 3151 : if (is_gimple_call (use_stmt)
8005 3151 : && gimple_call_internal_p (use_stmt))
8006 66 : switch (gimple_call_internal_fn (use_stmt))
8007 : {
8008 10 : case IFN_CLZ:
8009 10 : case IFN_CTZ:
8010 10 : case IFN_CLRSB:
8011 10 : case IFN_FFS:
8012 10 : case IFN_PARITY:
8013 10 : case IFN_POPCOUNT:
8014 10 : case IFN_BSWAP:
8015 10 : case IFN_BITREVERSE:
8016 10 : continue;
8017 : default:
8018 : break;
8019 : }
8020 3141 : if (gimple_code (use_stmt) == GIMPLE_PHI
8021 : || is_gimple_call (use_stmt)
8022 : || gimple_code (use_stmt) == GIMPLE_ASM
8023 : || (is_gimple_assign (use_stmt)
8024 1907 : && (gimple_assign_rhs_code (use_stmt)
8025 : == COMPLEX_EXPR)))
8026 : {
8027 : optimizable_load = false;
8028 : break;
8029 : }
8030 2988 : }
8031 :
8032 2988 : ssa_op_iter oi;
8033 4037 : FOR_EACH_SSA_USE_OPERAND (use_p, SSA_NAME_DEF_STMT (s),
8034 : oi, SSA_OP_USE)
8035 : {
8036 1049 : tree s2 = USE_FROM_PTR (use_p);
8037 1049 : if (SSA_NAME_OCCURS_IN_ABNORMAL_PHI (s2))
8038 : {
8039 : optimizable_load = false;
8040 : break;
8041 : }
8042 : }
8043 :
8044 2988 : if (optimizable_load && !stmt_ends_bb_p (SSA_NAME_DEF_STMT (s)))
8045 : {
8046 2890 : if (!large_huge.m_loads)
8047 315 : large_huge.m_loads = BITMAP_ALLOC (NULL);
8048 2890 : bitmap_set_bit (large_huge.m_loads, SSA_NAME_VERSION (s));
8049 : }
8050 : }
8051 : }
8052 : /* We need to also rewrite stores of large/huge _BitInt INTEGER_CSTs
8053 : into memory. Such functions could have no large/huge SSA_NAMEs. */
8054 57229 : else if (SSA_NAME_IS_VIRTUAL_OPERAND (s))
8055 : {
8056 40419 : gimple *g = SSA_NAME_DEF_STMT (s);
8057 40419 : if (is_gimple_assign (g) && gimple_store_p (g))
8058 : {
8059 13741 : tree t = gimple_assign_rhs1 (g);
8060 15620 : if (BITINT_TYPE_P (TREE_TYPE (t))
8061 13741 : && bitint_precision_kind (TREE_TYPE (t)) >= bitint_prec_large)
8062 : has_large_huge = true;
8063 : }
8064 : }
8065 : }
8066 :
8067 7366 : if (large_huge.m_names || has_large_huge)
8068 : {
8069 5889 : ret = TODO_update_ssa_only_virtuals | TODO_cleanup_cfg;
8070 5889 : calculate_dominance_info (CDI_DOMINATORS);
8071 5889 : if (optimize)
8072 3105 : enable_ranger (cfun);
8073 5889 : if (large_huge.m_loads)
8074 : {
8075 315 : basic_block entry = ENTRY_BLOCK_PTR_FOR_FN (cfun);
8076 315 : entry->aux = NULL;
8077 630 : bitint_dom_walker (large_huge.m_names,
8078 315 : large_huge.m_loads).walk (entry);
8079 315 : bitmap_and_compl_into (large_huge.m_names, large_huge.m_loads);
8080 315 : clear_aux_for_blocks ();
8081 315 : BITMAP_FREE (large_huge.m_loads);
8082 : }
8083 5889 : large_huge.m_limb_type = build_nonstandard_integer_type (limb_prec, 1);
8084 5889 : large_huge.m_limb_size
8085 5889 : = tree_to_uhwi (TYPE_SIZE_UNIT (large_huge.m_limb_type));
8086 : }
8087 7366 : if (large_huge.m_names)
8088 : {
8089 5691 : large_huge.m_map
8090 11382 : = init_var_map (num_ssa_names, NULL, large_huge.m_names);
8091 5691 : coalesce_ssa_name (large_huge.m_map);
8092 5691 : partition_view_normal (large_huge.m_map);
8093 5691 : if (dump_file && (dump_flags & TDF_DETAILS))
8094 : {
8095 0 : fprintf (dump_file, "After Coalescing:\n");
8096 0 : dump_var_map (dump_file, large_huge.m_map);
8097 : }
8098 5691 : large_huge.m_vars
8099 5691 : = XCNEWVEC (tree, num_var_partitions (large_huge.m_map));
8100 5691 : bitmap_iterator bi;
8101 5691 : if (has_large_huge_parm_result)
8102 19742 : EXECUTE_IF_SET_IN_BITMAP (large_huge.m_names, 0, i, bi)
8103 : {
8104 15530 : tree s = ssa_name (i);
8105 15530 : if (SSA_NAME_VAR (s)
8106 6224 : && ((TREE_CODE (SSA_NAME_VAR (s)) == PARM_DECL
8107 5420 : && SSA_NAME_IS_DEFAULT_DEF (s))
8108 841 : || TREE_CODE (SSA_NAME_VAR (s)) == RESULT_DECL))
8109 : {
8110 5383 : int p = var_to_partition (large_huge.m_map, s);
8111 5383 : if (large_huge.m_vars[p] == NULL_TREE)
8112 : {
8113 5383 : large_huge.m_vars[p] = SSA_NAME_VAR (s);
8114 5383 : mark_addressable (SSA_NAME_VAR (s));
8115 : }
8116 : }
8117 : }
8118 5691 : tree atype = NULL_TREE;
8119 5691 : if (dump_file && (dump_flags & TDF_DETAILS))
8120 0 : fprintf (dump_file, "Mapping SSA_NAMEs to decls:\n");
8121 32927 : EXECUTE_IF_SET_IN_BITMAP (large_huge.m_names, 0, i, bi)
8122 : {
8123 27236 : tree s = ssa_name (i);
8124 27236 : int p = var_to_partition (large_huge.m_map, s);
8125 27236 : if (large_huge.m_vars[p] == NULL_TREE)
8126 : {
8127 18927 : if (atype == NULL_TREE
8128 33060 : || !tree_int_cst_equal (TYPE_SIZE (atype),
8129 14133 : TYPE_SIZE (TREE_TYPE (s))))
8130 : {
8131 7771 : unsigned HOST_WIDE_INT nelts
8132 7771 : = tree_to_uhwi (TYPE_SIZE (TREE_TYPE (s))) / limb_prec;
8133 7771 : atype = build_array_type_nelts (large_huge.m_limb_type,
8134 7771 : nelts);
8135 : }
8136 18927 : large_huge.m_vars[p] = create_tmp_var (atype, "bitint");
8137 18927 : mark_addressable (large_huge.m_vars[p]);
8138 : }
8139 27236 : if (dump_file && (dump_flags & TDF_DETAILS))
8140 : {
8141 0 : print_generic_expr (dump_file, s, TDF_SLIM);
8142 0 : fprintf (dump_file, " -> ");
8143 0 : print_generic_expr (dump_file, large_huge.m_vars[p], TDF_SLIM);
8144 0 : fprintf (dump_file, "\n");
8145 : }
8146 : }
8147 : }
8148 :
8149 46528 : FOR_EACH_BB_REVERSE_FN (bb, cfun)
8150 : {
8151 39162 : gimple_stmt_iterator prev;
8152 198150 : for (gimple_stmt_iterator gsi = gsi_last_bb (bb); !gsi_end_p (gsi);
8153 119826 : gsi = prev)
8154 : {
8155 119826 : prev = gsi;
8156 119826 : gsi_prev (&prev);
8157 119826 : ssa_op_iter iter;
8158 119826 : gimple *stmt = gsi_stmt (gsi);
8159 119826 : if (is_gimple_debug (stmt))
8160 76923 : continue;
8161 114843 : bitint_prec_kind kind = bitint_prec_small;
8162 114843 : tree t;
8163 345555 : FOR_EACH_SSA_TREE_OPERAND (t, stmt, iter, SSA_OP_ALL_OPERANDS)
8164 230712 : if (BITINT_TYPE_P (TREE_TYPE (t)))
8165 : {
8166 79432 : bitint_prec_kind this_kind
8167 79432 : = bitint_precision_kind (TREE_TYPE (t));
8168 230930 : kind = MAX (kind, this_kind);
8169 : }
8170 114843 : if (is_gimple_assign (stmt) && gimple_store_p (stmt))
8171 : {
8172 16418 : t = gimple_assign_rhs1 (stmt);
8173 16418 : if (BITINT_TYPE_P (TREE_TYPE (t)))
8174 : {
8175 14217 : bitint_prec_kind this_kind
8176 14217 : = bitint_precision_kind (TREE_TYPE (t));
8177 14217 : kind = MAX (kind, this_kind);
8178 : }
8179 : }
8180 114843 : if (is_gimple_assign (stmt)
8181 114843 : && gimple_assign_rhs_code (stmt) == FLOAT_EXPR)
8182 : {
8183 189 : t = gimple_assign_rhs1 (stmt);
8184 218 : if (BITINT_TYPE_P (TREE_TYPE (t))
8185 191 : && TREE_CODE (t) == INTEGER_CST)
8186 : {
8187 1 : bitint_prec_kind this_kind
8188 1 : = bitint_precision_kind (TREE_TYPE (t));
8189 1 : kind = MAX (kind, this_kind);
8190 : }
8191 : }
8192 114843 : if (is_gimple_call (stmt))
8193 : {
8194 25873 : t = gimple_call_lhs (stmt);
8195 25873 : if (t && TREE_CODE (TREE_TYPE (t)) == COMPLEX_TYPE)
8196 : {
8197 5325 : bitint_prec_kind this_kind = arith_overflow_arg_kind (stmt);
8198 5325 : kind = MAX (kind, this_kind);
8199 5325 : if (BITINT_TYPE_P (TREE_TYPE (TREE_TYPE (t))))
8200 : {
8201 5200 : this_kind
8202 5200 : = bitint_precision_kind (TREE_TYPE (TREE_TYPE (t)));
8203 5200 : kind = MAX (kind, this_kind);
8204 : }
8205 : }
8206 : }
8207 114521 : if (kind == bitint_prec_small)
8208 45199 : continue;
8209 69644 : switch (gimple_code (stmt))
8210 : {
8211 11139 : case GIMPLE_CALL:
8212 : /* For now. We'll need to handle some internal functions and
8213 : perhaps some builtins. */
8214 11139 : if (kind == bitint_prec_middle)
8215 2282 : continue;
8216 : break;
8217 4 : case GIMPLE_ASM:
8218 4 : if (kind == bitint_prec_middle)
8219 1 : continue;
8220 : break;
8221 1125 : case GIMPLE_RETURN:
8222 1125 : continue;
8223 48746 : case GIMPLE_ASSIGN:
8224 48746 : if (gimple_clobber_p (stmt))
8225 3511 : continue;
8226 45235 : if (kind >= bitint_prec_large)
8227 : break;
8228 8818 : if (gimple_assign_single_p (stmt))
8229 : /* No need to lower copies, loads or stores. */
8230 5809 : continue;
8231 3009 : if (gimple_assign_cast_p (stmt))
8232 : {
8233 2432 : tree lhs = gimple_assign_lhs (stmt);
8234 2432 : tree rhs = gimple_assign_rhs1 (stmt);
8235 4864 : if (INTEGRAL_TYPE_P (TREE_TYPE (lhs))
8236 2432 : && INTEGRAL_TYPE_P (TREE_TYPE (rhs))
8237 4858 : && (TYPE_PRECISION (TREE_TYPE (lhs))
8238 2426 : == TYPE_PRECISION (TREE_TYPE (rhs))))
8239 : /* No need to lower casts to same precision. */
8240 35 : continue;
8241 : }
8242 : break;
8243 : default:
8244 : break;
8245 1125 : }
8246 :
8247 11604 : if (kind == bitint_prec_middle)
8248 : {
8249 5104 : tree type = NULL_TREE;
8250 : /* Middle _BitInt(N) is rewritten to casts to INTEGER_TYPEs
8251 : with the same precision and back. */
8252 5104 : unsigned int nops = gimple_num_ops (stmt);
8253 17082 : for (unsigned int i = is_gimple_assign (stmt) ? 1 : 0;
8254 17082 : i < nops; ++i)
8255 11978 : if (tree op = gimple_op (stmt, i))
8256 : {
8257 7728 : tree nop = maybe_cast_middle_bitint (&gsi, op, type);
8258 7728 : if (nop != op)
8259 6829 : gimple_set_op (stmt, i, nop);
8260 899 : else if (COMPARISON_CLASS_P (op))
8261 : {
8262 0 : TREE_OPERAND (op, 0)
8263 0 : = maybe_cast_middle_bitint (&gsi,
8264 0 : TREE_OPERAND (op, 0),
8265 : type);
8266 0 : TREE_OPERAND (op, 1)
8267 0 : = maybe_cast_middle_bitint (&gsi,
8268 0 : TREE_OPERAND (op, 1),
8269 : type);
8270 : }
8271 899 : else if (TREE_CODE (op) == CASE_LABEL_EXPR)
8272 : {
8273 28 : CASE_LOW (op)
8274 28 : = maybe_cast_middle_bitint (&gsi, CASE_LOW (op),
8275 : type);
8276 56 : CASE_HIGH (op)
8277 56 : = maybe_cast_middle_bitint (&gsi, CASE_HIGH (op),
8278 : type);
8279 : }
8280 : }
8281 5104 : if (tree lhs = gimple_get_lhs (stmt))
8282 4538 : if (BITINT_TYPE_P (TREE_TYPE (lhs))
8283 2974 : && (bitint_precision_kind (TREE_TYPE (lhs))
8284 : == bitint_prec_middle))
8285 : {
8286 1399 : int prec = TYPE_PRECISION (TREE_TYPE (lhs));
8287 1399 : int uns = TYPE_UNSIGNED (TREE_TYPE (lhs));
8288 1399 : type = build_nonstandard_integer_type (prec, uns);
8289 1399 : tree lhs2 = make_ssa_name (type);
8290 1399 : gimple_set_lhs (stmt, lhs2);
8291 1399 : gimple *g = gimple_build_assign (lhs, NOP_EXPR, lhs2);
8292 1399 : if (stmt_ends_bb_p (stmt))
8293 : {
8294 4 : edge e = find_fallthru_edge (gsi_bb (gsi)->succs);
8295 4 : gsi_insert_on_edge (e, g);
8296 4 : edge_insertions = true;
8297 : }
8298 : else
8299 1395 : gsi_insert_after (&gsi, g, GSI_SAME_STMT);
8300 : }
8301 5104 : update_stmt (stmt);
8302 5104 : continue;
8303 5104 : }
8304 :
8305 51777 : if (tree lhs = gimple_get_lhs (stmt))
8306 45143 : if (TREE_CODE (lhs) == SSA_NAME)
8307 : {
8308 36134 : tree type = TREE_TYPE (lhs);
8309 36134 : if (TREE_CODE (type) == COMPLEX_TYPE)
8310 4197 : type = TREE_TYPE (type);
8311 5444 : if (BITINT_TYPE_P (type)
8312 30702 : && bitint_precision_kind (type) >= bitint_prec_large
8313 66634 : && (large_huge.m_names == NULL
8314 30295 : || !bitmap_bit_p (large_huge.m_names,
8315 30295 : SSA_NAME_VERSION (lhs))))
8316 8874 : continue;
8317 : }
8318 :
8319 42903 : large_huge.lower_stmt (stmt);
8320 : }
8321 :
8322 39162 : tree atype = NULL_TREE;
8323 47817 : for (gphi_iterator gsi = gsi_start_phis (bb); !gsi_end_p (gsi);
8324 8655 : gsi_next (&gsi))
8325 : {
8326 8655 : gphi *phi = gsi.phi ();
8327 8655 : tree lhs = gimple_phi_result (phi);
8328 17070 : if (!BITINT_TYPE_P (TREE_TYPE (lhs))
8329 8655 : || bitint_precision_kind (TREE_TYPE (lhs)) < bitint_prec_large)
8330 8462 : continue;
8331 193 : int p1 = var_to_partition (large_huge.m_map, lhs);
8332 193 : gcc_assert (large_huge.m_vars[p1] != NULL_TREE);
8333 : tree v1 = large_huge.m_vars[p1];
8334 694 : for (unsigned i = 0; i < gimple_phi_num_args (phi); ++i)
8335 : {
8336 501 : tree arg = gimple_phi_arg_def (phi, i);
8337 501 : edge e = gimple_phi_arg_edge (phi, i);
8338 501 : gimple *g;
8339 501 : switch (TREE_CODE (arg))
8340 : {
8341 99 : case INTEGER_CST:
8342 99 : if (integer_zerop (arg) && VAR_P (v1))
8343 : {
8344 45 : tree zero = build_zero_cst (TREE_TYPE (v1));
8345 45 : g = gimple_build_assign (v1, zero);
8346 45 : gsi_insert_on_edge (e, g);
8347 45 : edge_insertions = true;
8348 162 : break;
8349 : }
8350 54 : int ext;
8351 54 : unsigned int min_prec, prec, rem;
8352 54 : tree c;
8353 54 : prec = TYPE_PRECISION (TREE_TYPE (arg));
8354 54 : rem = prec % (2 * limb_prec);
8355 54 : min_prec = bitint_min_cst_precision (arg, ext);
8356 54 : if (min_prec > prec - rem - 2 * limb_prec
8357 12 : && min_prec > (unsigned) limb_prec)
8358 : /* Constant which has enough significant bits that it
8359 : isn't worth trying to save .rodata space by extending
8360 : from smaller number. */
8361 : min_prec = prec;
8362 : else
8363 : {
8364 45 : min_prec = CEIL (min_prec, limb_prec) * limb_prec;
8365 45 : if (min_prec > (unsigned) limb_prec
8366 3 : && abi_limb_prec > limb_prec)
8367 : {
8368 : /* For targets with ABI limb precision higher than
8369 : limb precision round to ABI limb precision,
8370 : otherwise c can contain padding bits. */
8371 0 : min_prec
8372 0 : = CEIL (min_prec, abi_limb_prec) * abi_limb_prec;
8373 0 : if (min_prec > prec - rem - 2 * limb_prec)
8374 9 : min_prec = prec;
8375 : }
8376 : }
8377 54 : if (min_prec == 0)
8378 : c = NULL_TREE;
8379 51 : else if (min_prec == prec)
8380 9 : c = tree_output_constant_def (arg);
8381 42 : else if (min_prec == (unsigned) limb_prec)
8382 39 : c = fold_convert (large_huge.m_limb_type, arg);
8383 : else
8384 : {
8385 3 : tree ctype = build_bitint_type (min_prec, 1);
8386 3 : c = tree_output_constant_def (fold_convert (ctype, arg));
8387 : }
8388 51 : if (c)
8389 : {
8390 51 : if (VAR_P (v1) && min_prec == prec)
8391 : {
8392 8 : tree v2 = build1 (VIEW_CONVERT_EXPR,
8393 8 : TREE_TYPE (v1), c);
8394 8 : g = gimple_build_assign (v1, v2);
8395 8 : gsi_insert_on_edge (e, g);
8396 8 : edge_insertions = true;
8397 8 : break;
8398 : }
8399 43 : if (TREE_CODE (TREE_TYPE (c)) == INTEGER_TYPE)
8400 : {
8401 39 : if (bitint_big_endian)
8402 : {
8403 0 : tree ptype = build_pointer_type (TREE_TYPE (v1));
8404 0 : tree sz1 = TYPE_SIZE_UNIT (TREE_TYPE (v1));
8405 0 : tree sz2 = TYPE_SIZE_UNIT (TREE_TYPE (c));
8406 0 : tree off = build_int_cst (ptype,
8407 0 : tree_to_uhwi (sz1)
8408 0 : - tree_to_uhwi (sz2));
8409 0 : tree vd = build2 (MEM_REF, TREE_TYPE (c),
8410 : build_fold_addr_expr (v1),
8411 : off);
8412 0 : g = gimple_build_assign (vd, c);
8413 : }
8414 : else
8415 39 : g = gimple_build_assign (build1 (VIEW_CONVERT_EXPR,
8416 39 : TREE_TYPE (c),
8417 : v1), c);
8418 : }
8419 : else
8420 : {
8421 4 : unsigned HOST_WIDE_INT nelts
8422 4 : = tree_to_uhwi (TYPE_SIZE (TREE_TYPE (c)))
8423 4 : / limb_prec;
8424 4 : tree vtype
8425 8 : = build_array_type_nelts (large_huge.m_limb_type,
8426 4 : nelts);
8427 4 : tree vd;
8428 4 : if (bitint_big_endian)
8429 : {
8430 0 : tree ptype = build_pointer_type (TREE_TYPE (v1));
8431 0 : tree sz1 = TYPE_SIZE_UNIT (TREE_TYPE (v1));
8432 0 : tree sz2 = TYPE_SIZE_UNIT (vtype);
8433 0 : tree off = build_int_cst (ptype,
8434 0 : tree_to_uhwi (sz1)
8435 0 : - tree_to_uhwi (sz2));
8436 0 : vd = build2 (MEM_REF, vtype,
8437 : build_fold_addr_expr (v1), off);
8438 : }
8439 : else
8440 4 : vd = build1 (VIEW_CONVERT_EXPR, vtype, v1);
8441 4 : g = gimple_build_assign (vd,
8442 : build1 (VIEW_CONVERT_EXPR,
8443 : vtype, c));
8444 : }
8445 43 : gsi_insert_on_edge (e, g);
8446 43 : if (min_prec == prec)
8447 : {
8448 : edge_insertions = true;
8449 : break;
8450 : }
8451 : }
8452 45 : if (ext == 0)
8453 : {
8454 39 : unsigned HOST_WIDE_INT nelts
8455 39 : = (tree_to_uhwi (TYPE_SIZE (TREE_TYPE (v1)))
8456 39 : - min_prec) / limb_prec;
8457 39 : tree vtype
8458 78 : = build_array_type_nelts (large_huge.m_limb_type,
8459 39 : nelts);
8460 39 : tree ptype = build_pointer_type (TREE_TYPE (v1));
8461 39 : tree off;
8462 39 : if (c && !bitint_big_endian)
8463 38 : off = fold_convert (ptype,
8464 : TYPE_SIZE_UNIT (TREE_TYPE (c)));
8465 : else
8466 1 : off = build_zero_cst (ptype);
8467 39 : tree vd = build2 (MEM_REF, vtype,
8468 : build_fold_addr_expr (v1), off);
8469 39 : g = gimple_build_assign (vd, build_zero_cst (vtype));
8470 : }
8471 : else
8472 : {
8473 6 : tree vd = v1;
8474 6 : if (c && !bitint_big_endian)
8475 : {
8476 4 : tree ptype = build_pointer_type (TREE_TYPE (v1));
8477 4 : tree off
8478 4 : = fold_convert (ptype,
8479 : TYPE_SIZE_UNIT (TREE_TYPE (c)));
8480 4 : vd = build2 (MEM_REF, large_huge.m_limb_type,
8481 : build_fold_addr_expr (v1), off);
8482 : }
8483 6 : vd = build_fold_addr_expr (vd);
8484 6 : unsigned HOST_WIDE_INT nbytes
8485 6 : = tree_to_uhwi (TYPE_SIZE_UNIT (TREE_TYPE (v1)));
8486 6 : if (c)
8487 4 : nbytes
8488 4 : -= tree_to_uhwi (TYPE_SIZE_UNIT (TREE_TYPE (c)));
8489 6 : tree fn = builtin_decl_implicit (BUILT_IN_MEMSET);
8490 6 : g = gimple_build_call (fn, 3, vd,
8491 : integer_minus_one_node,
8492 : build_int_cst (sizetype,
8493 6 : nbytes));
8494 : }
8495 45 : gsi_insert_on_edge (e, g);
8496 45 : edge_insertions = true;
8497 45 : break;
8498 0 : default:
8499 0 : gcc_unreachable ();
8500 402 : case SSA_NAME:
8501 402 : if (gimple_code (SSA_NAME_DEF_STMT (arg)) == GIMPLE_NOP)
8502 : {
8503 9 : if (large_huge.m_names == NULL
8504 18 : || !bitmap_bit_p (large_huge.m_names,
8505 9 : SSA_NAME_VERSION (arg)))
8506 384 : continue;
8507 : }
8508 402 : int p2 = var_to_partition (large_huge.m_map, arg);
8509 402 : if (p1 == p2)
8510 384 : continue;
8511 18 : gcc_assert (large_huge.m_vars[p2] != NULL_TREE);
8512 18 : tree v2 = large_huge.m_vars[p2];
8513 18 : if (VAR_P (v1) && VAR_P (v2))
8514 18 : g = gimple_build_assign (v1, v2);
8515 0 : else if (VAR_P (v1))
8516 0 : g = gimple_build_assign (v1, build1 (VIEW_CONVERT_EXPR,
8517 0 : TREE_TYPE (v1), v2));
8518 0 : else if (VAR_P (v2))
8519 0 : g = gimple_build_assign (build1 (VIEW_CONVERT_EXPR,
8520 0 : TREE_TYPE (v2), v1), v2);
8521 : else
8522 : {
8523 0 : if (atype == NULL_TREE
8524 0 : || !tree_int_cst_equal (TYPE_SIZE (atype),
8525 0 : TYPE_SIZE (TREE_TYPE (lhs))))
8526 : {
8527 0 : unsigned HOST_WIDE_INT nelts
8528 0 : = tree_to_uhwi (TYPE_SIZE (TREE_TYPE (lhs)))
8529 0 : / limb_prec;
8530 0 : atype
8531 0 : = build_array_type_nelts (large_huge.m_limb_type,
8532 0 : nelts);
8533 : }
8534 0 : g = gimple_build_assign (build1 (VIEW_CONVERT_EXPR,
8535 : atype, v1),
8536 : build1 (VIEW_CONVERT_EXPR,
8537 : atype, v2));
8538 : }
8539 18 : gsi_insert_on_edge (e, g);
8540 18 : edge_insertions = true;
8541 18 : break;
8542 : }
8543 : }
8544 : }
8545 : }
8546 :
8547 7366 : if (large_huge.m_names || has_large_huge)
8548 : {
8549 5889 : gimple *nop = NULL;
8550 387033 : for (i = 0; i < num_ssa_names; ++i)
8551 : {
8552 381144 : tree s = ssa_name (i);
8553 381144 : if (s == NULL_TREE)
8554 15539 : continue;
8555 365605 : tree type = TREE_TYPE (s);
8556 365605 : if (TREE_CODE (type) == COMPLEX_TYPE)
8557 17612 : type = TREE_TYPE (type);
8558 325695 : if (BITINT_TYPE_P (type)
8559 365632 : && bitint_precision_kind (type) >= bitint_prec_large)
8560 : {
8561 40855 : if (large_huge.m_preserved
8562 45353 : && bitmap_bit_p (large_huge.m_preserved,
8563 6841 : SSA_NAME_VERSION (s)))
8564 2343 : continue;
8565 36169 : gimple *g = SSA_NAME_DEF_STMT (s);
8566 36169 : if (gimple_code (g) == GIMPLE_NOP)
8567 : {
8568 9736 : if (SSA_NAME_VAR (s))
8569 5452 : set_ssa_default_def (cfun, SSA_NAME_VAR (s), NULL_TREE);
8570 9736 : release_ssa_name (s);
8571 9736 : continue;
8572 : }
8573 26433 : if (gimple_bb (g) == NULL)
8574 : {
8575 0 : release_ssa_name (s);
8576 0 : continue;
8577 : }
8578 26433 : if (gimple_code (g) != GIMPLE_ASM)
8579 : {
8580 26432 : gimple_stmt_iterator gsi = gsi_for_stmt (g);
8581 26432 : bool save_vta = flag_var_tracking_assignments;
8582 26432 : flag_var_tracking_assignments = false;
8583 26432 : gsi_remove (&gsi, true);
8584 26432 : flag_var_tracking_assignments = save_vta;
8585 : }
8586 26433 : if (nop == NULL)
8587 4920 : nop = gimple_build_nop ();
8588 26433 : SSA_NAME_DEF_STMT (s) = nop;
8589 26433 : release_ssa_name (s);
8590 : }
8591 : }
8592 5889 : if (optimize)
8593 3105 : disable_ranger (cfun);
8594 : }
8595 :
8596 7366 : if (edge_insertions)
8597 56 : gsi_commit_edge_inserts ();
8598 :
8599 : /* Fix up arguments of ECF_RETURNS_TWICE calls. Those were temporarily
8600 : inserted before the call, but that is invalid IL, so move them to the
8601 : right place and add corresponding PHIs. */
8602 7366 : if (!large_huge.m_returns_twice_calls.is_empty ())
8603 : {
8604 9 : auto_vec<gimple *, 16> arg_stmts;
8605 29 : while (!large_huge.m_returns_twice_calls.is_empty ())
8606 : {
8607 11 : gimple *stmt = large_huge.m_returns_twice_calls.pop ();
8608 11 : gimple_stmt_iterator gsi = gsi_after_labels (gimple_bb (stmt));
8609 36 : while (gsi_stmt (gsi) != stmt)
8610 : {
8611 25 : if (is_gimple_debug (gsi_stmt (gsi)))
8612 2 : gsi_next (&gsi);
8613 : else
8614 : {
8615 23 : arg_stmts.safe_push (gsi_stmt (gsi));
8616 23 : gsi_remove (&gsi, false);
8617 : }
8618 : }
8619 11 : gimple *g;
8620 11 : basic_block bb = NULL;
8621 11 : edge e = NULL, ead = NULL;
8622 34 : FOR_EACH_VEC_ELT (arg_stmts, i, g)
8623 : {
8624 23 : gsi_safe_insert_before (&gsi, g);
8625 23 : if (i == 0)
8626 : {
8627 11 : bb = gimple_bb (stmt);
8628 11 : gcc_checking_assert (EDGE_COUNT (bb->preds) == 2);
8629 11 : e = EDGE_PRED (bb, 0);
8630 11 : ead = EDGE_PRED (bb, 1);
8631 11 : if ((ead->flags & EDGE_ABNORMAL) == 0)
8632 0 : std::swap (e, ead);
8633 11 : gcc_checking_assert ((e->flags & EDGE_ABNORMAL) == 0
8634 : && (ead->flags & EDGE_ABNORMAL));
8635 : }
8636 23 : tree lhs = gimple_assign_lhs (g);
8637 23 : tree arg = lhs;
8638 23 : gphi *phi = create_phi_node (copy_ssa_name (arg), bb);
8639 23 : add_phi_arg (phi, arg, e, UNKNOWN_LOCATION);
8640 23 : tree var = create_tmp_reg (TREE_TYPE (arg));
8641 23 : suppress_warning (var, OPT_Wuninitialized);
8642 23 : arg = get_or_create_ssa_default_def (cfun, var);
8643 23 : SSA_NAME_OCCURS_IN_ABNORMAL_PHI (arg) = 1;
8644 23 : add_phi_arg (phi, arg, ead, UNKNOWN_LOCATION);
8645 23 : arg = gimple_phi_result (phi);
8646 23 : SSA_NAME_OCCURS_IN_ABNORMAL_PHI (arg) = 1;
8647 23 : imm_use_iterator iter;
8648 23 : gimple *use_stmt;
8649 69 : FOR_EACH_IMM_USE_STMT (use_stmt, iter, lhs)
8650 : {
8651 46 : if (use_stmt == phi)
8652 23 : continue;
8653 23 : gcc_checking_assert (use_stmt == stmt);
8654 23 : use_operand_p use_p;
8655 46 : FOR_EACH_IMM_USE_ON_STMT (use_p, iter)
8656 23 : SET_USE (use_p, arg);
8657 23 : }
8658 : }
8659 11 : update_stmt (stmt);
8660 11 : arg_stmts.truncate (0);
8661 : }
8662 9 : }
8663 :
8664 7366 : return ret;
8665 7366 : }
8666 :
8667 : namespace {
8668 :
8669 : const pass_data pass_data_lower_bitint =
8670 : {
8671 : GIMPLE_PASS, /* type */
8672 : "bitintlower", /* name */
8673 : OPTGROUP_NONE, /* optinfo_flags */
8674 : TV_NONE, /* tv_id */
8675 : PROP_ssa, /* properties_required */
8676 : PROP_gimple_lbitint, /* properties_provided */
8677 : 0, /* properties_destroyed */
8678 : 0, /* todo_flags_start */
8679 : 0, /* todo_flags_finish */
8680 : };
8681 :
8682 : class pass_lower_bitint : public gimple_opt_pass
8683 : {
8684 : public:
8685 589174 : pass_lower_bitint (gcc::context *ctxt)
8686 1178348 : : gimple_opt_pass (pass_data_lower_bitint, ctxt)
8687 : {}
8688 :
8689 : /* opt_pass methods: */
8690 294587 : opt_pass * clone () final override { return new pass_lower_bitint (m_ctxt); }
8691 1064832 : unsigned int execute (function *) final override
8692 : {
8693 1064832 : return gimple_lower_bitint ();
8694 : }
8695 :
8696 : }; // class pass_lower_bitint
8697 :
8698 : } // anon namespace
8699 :
8700 : gimple_opt_pass *
8701 294587 : make_pass_lower_bitint (gcc::context *ctxt)
8702 : {
8703 294587 : return new pass_lower_bitint (ctxt);
8704 : }
8705 :
8706 :
8707 : namespace {
8708 :
8709 : const pass_data pass_data_lower_bitint_O0 =
8710 : {
8711 : GIMPLE_PASS, /* type */
8712 : "bitintlower0", /* name */
8713 : OPTGROUP_NONE, /* optinfo_flags */
8714 : TV_NONE, /* tv_id */
8715 : PROP_cfg, /* properties_required */
8716 : PROP_gimple_lbitint, /* properties_provided */
8717 : 0, /* properties_destroyed */
8718 : 0, /* todo_flags_start */
8719 : 0, /* todo_flags_finish */
8720 : };
8721 :
8722 : class pass_lower_bitint_O0 : public gimple_opt_pass
8723 : {
8724 : public:
8725 294587 : pass_lower_bitint_O0 (gcc::context *ctxt)
8726 589174 : : gimple_opt_pass (pass_data_lower_bitint_O0, ctxt)
8727 : {}
8728 :
8729 : /* opt_pass methods: */
8730 1512174 : bool gate (function *fun) final override
8731 : {
8732 : /* With errors, normal optimization passes are not run. If we don't
8733 : lower bitint operations at all, rtl expansion will abort. */
8734 1512174 : return !(fun->curr_properties & PROP_gimple_lbitint);
8735 : }
8736 :
8737 447447 : unsigned int execute (function *) final override
8738 : {
8739 447447 : return gimple_lower_bitint ();
8740 : }
8741 :
8742 : }; // class pass_lower_bitint_O0
8743 :
8744 : } // anon namespace
8745 :
8746 : gimple_opt_pass *
8747 294587 : make_pass_lower_bitint_O0 (gcc::context *ctxt)
8748 : {
8749 294587 : return new pass_lower_bitint_O0 (ctxt);
8750 : }
|