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