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