LCOV - code coverage report
Current view: top level - gcc - gimple-lower-bitint.cc (source / functions) Coverage Total Hit
Test: gcc.info Lines: 86.4 % 5302 4583
Test Date: 2026-06-20 15:32:29 Functions: 100.0 % 57 57
Legend: Lines:     hit not hit

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

Generated by: LCOV version 2.4-beta

LCOV profile is generated on x86_64 machine using following configure options: configure --disable-bootstrap --enable-coverage=opt --enable-languages=c,c++,fortran,go,jit,lto,rust,m2 --enable-host-shared. GCC test suite is run with the built compiler.